From d971b104edc51ddf3819eded837de97357c3b395 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 29 Jan 2018 13:14:56 +0100 Subject: [PATCH] Do not cache the settings/sections in the database anymore This caused more troubles then it had benefits, especially when an app got disabled or was removed without being disabled. Signed-off-by: Joas Schilling --- .../Version14000Date20180129121024.php | 52 ++ lib/base.php | 18 - lib/composer/composer/autoload_classmap.php | 3 +- lib/composer/composer/autoload_static.php | 3 +- lib/private/Installer.php | 9 - lib/private/Server.php | 2 - lib/private/Settings/Manager.php | 468 ++++++------------ lib/private/Settings/Mapper.php | 217 -------- lib/private/Settings/RemoveOrphaned.php | 92 ---- lib/private/legacy/app.php | 26 +- lib/public/Settings/IManager.php | 52 +- tests/lib/Settings/ManagerTest.php | 106 +--- tests/lib/Settings/MapperTest.php | 139 ------ version.php | 2 +- 14 files changed, 253 insertions(+), 936 deletions(-) create mode 100644 core/Migrations/Version14000Date20180129121024.php delete mode 100644 lib/private/Settings/Mapper.php delete mode 100644 lib/private/Settings/RemoveOrphaned.php delete mode 100644 tests/lib/Settings/MapperTest.php diff --git a/core/Migrations/Version14000Date20180129121024.php b/core/Migrations/Version14000Date20180129121024.php new file mode 100644 index 0000000000..eedd99d014 --- /dev/null +++ b/core/Migrations/Version14000Date20180129121024.php @@ -0,0 +1,52 @@ + + * + * @author Joas Schilling + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +namespace OC\Core\Migrations; + +use OCP\DB\ISchemaWrapper; +use OCP\Migration\SimpleMigrationStep; +use OCP\Migration\IOutput; + +/** + * Delete the admin|personal sections and settings tables + */ +class Version14000Date20180129121024 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + * @since 13.0.0 + */ + public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + $schema->dropTable('admin_sections'); + $schema->dropTable('admin_settings'); + $schema->dropTable('personal_sections'); + $schema->dropTable('personal_settings'); + + return $schema; + } +} diff --git a/lib/base.php b/lib/base.php index 444c0df7e9..b6382a069b 100644 --- a/lib/base.php +++ b/lib/base.php @@ -54,7 +54,6 @@ * */ -use OC\Settings\RemoveOrphaned; use OCP\Share; use OC\Encryption\HookManager; use OC\Files\Filesystem; @@ -721,7 +720,6 @@ class OC { self::registerEncryptionWrapper(); self::registerEncryptionHooks(); self::registerAccountHooks(); - self::registerSettingsHooks(); $settings = new \OC\Settings\Application(); $settings->register(); @@ -833,22 +831,6 @@ class OC { } } - public static function registerSettingsHooks() { - $dispatcher = \OC::$server->getEventDispatcher(); - $dispatcher->addListener(OCP\App\ManagerEvent::EVENT_APP_DISABLE, function($event) { - /** @var \OCP\App\ManagerEvent $event */ - \OC::$server->getSettingsManager()->onAppDisabled($event->getAppID()); - }); - $dispatcher->addListener(OCP\App\ManagerEvent::EVENT_APP_UPDATE, function($event) { - /** @var \OCP\App\ManagerEvent $event */ - $jobList = \OC::$server->getJobList(); - $job = RemoveOrphaned::class; - if(!$jobList->has($job, null)) { - $jobList->add($job); - } - }); - } - private static function registerEncryptionWrapper() { $manager = self::$server->getEncryptionManager(); \OCP\Util::connectHook('OC_Filesystem', 'preSetup', $manager, 'setupStorage'); diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index f29b9334fc..28004d50cf 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -534,6 +534,7 @@ return array( 'OC\\Core\\Migrations\\Version13000Date20170814074715' => $baseDir . '/core/Migrations/Version13000Date20170814074715.php', 'OC\\Core\\Migrations\\Version13000Date20170919121250' => $baseDir . '/core/Migrations/Version13000Date20170919121250.php', 'OC\\Core\\Migrations\\Version13000Date20170926101637' => $baseDir . '/core/Migrations/Version13000Date20170926101637.php', + 'OC\\Core\\Migrations\\Version14000Date20180129121024' => $baseDir . '/core/Migrations/Version14000Date20180129121024.php', 'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php', 'OC\\DB\\AdapterMySQL' => $baseDir . '/lib/private/DB/AdapterMySQL.php', 'OC\\DB\\AdapterOCI8' => $baseDir . '/lib/private/DB/AdapterOCI8.php', @@ -886,12 +887,10 @@ return array( 'OC\\Settings\\Hooks' => $baseDir . '/settings/Hooks.php', 'OC\\Settings\\Mailer\\NewUserMailHelper' => $baseDir . '/settings/Mailer/NewUserMailHelper.php', 'OC\\Settings\\Manager' => $baseDir . '/lib/private/Settings/Manager.php', - 'OC\\Settings\\Mapper' => $baseDir . '/lib/private/Settings/Mapper.php', 'OC\\Settings\\Middleware\\SubadminMiddleware' => $baseDir . '/settings/Middleware/SubadminMiddleware.php', 'OC\\Settings\\Personal\\Additional' => $baseDir . '/lib/private/Settings/Personal/Additional.php', 'OC\\Settings\\Personal\\PersonalInfo' => $baseDir . '/lib/private/Settings/Personal/PersonalInfo.php', 'OC\\Settings\\Personal\\Security' => $baseDir . '/lib/private/Settings/Personal/Security.php', - 'OC\\Settings\\RemoveOrphaned' => $baseDir . '/lib/private/Settings/RemoveOrphaned.php', 'OC\\Settings\\Section' => $baseDir . '/lib/private/Settings/Section.php', 'OC\\Setup' => $baseDir . '/lib/private/Setup.php', 'OC\\Setup\\AbstractDatabase' => $baseDir . '/lib/private/Setup/AbstractDatabase.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index def8abd8c5..f23933fe98 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -564,6 +564,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Core\\Migrations\\Version13000Date20170814074715' => __DIR__ . '/../../..' . '/core/Migrations/Version13000Date20170814074715.php', 'OC\\Core\\Migrations\\Version13000Date20170919121250' => __DIR__ . '/../../..' . '/core/Migrations/Version13000Date20170919121250.php', 'OC\\Core\\Migrations\\Version13000Date20170926101637' => __DIR__ . '/../../..' . '/core/Migrations/Version13000Date20170926101637.php', + 'OC\\Core\\Migrations\\Version14000Date20180129121024' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180129121024.php', 'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php', 'OC\\DB\\AdapterMySQL' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterMySQL.php', 'OC\\DB\\AdapterOCI8' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterOCI8.php', @@ -916,12 +917,10 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Settings\\Hooks' => __DIR__ . '/../../..' . '/settings/Hooks.php', 'OC\\Settings\\Mailer\\NewUserMailHelper' => __DIR__ . '/../../..' . '/settings/Mailer/NewUserMailHelper.php', 'OC\\Settings\\Manager' => __DIR__ . '/../../..' . '/lib/private/Settings/Manager.php', - 'OC\\Settings\\Mapper' => __DIR__ . '/../../..' . '/lib/private/Settings/Mapper.php', 'OC\\Settings\\Middleware\\SubadminMiddleware' => __DIR__ . '/../../..' . '/settings/Middleware/SubadminMiddleware.php', 'OC\\Settings\\Personal\\Additional' => __DIR__ . '/../../..' . '/lib/private/Settings/Personal/Additional.php', 'OC\\Settings\\Personal\\PersonalInfo' => __DIR__ . '/../../..' . '/lib/private/Settings/Personal/PersonalInfo.php', 'OC\\Settings\\Personal\\Security' => __DIR__ . '/../../..' . '/lib/private/Settings/Personal/Security.php', - 'OC\\Settings\\RemoveOrphaned' => __DIR__ . '/../../..' . '/lib/private/Settings/RemoveOrphaned.php', 'OC\\Settings\\Section' => __DIR__ . '/../../..' . '/lib/private/Settings/Section.php', 'OC\\Setup' => __DIR__ . '/../../..' . '/lib/private/Setup.php', 'OC\\Setup\\AbstractDatabase' => __DIR__ . '/../../..' . '/lib/private/Setup/AbstractDatabase.php', diff --git a/lib/private/Installer.php b/lib/private/Installer.php index d150e48fd8..6a78ea329c 100644 --- a/lib/private/Installer.php +++ b/lib/private/Installer.php @@ -144,9 +144,6 @@ class Installer { } \OC_App::setupBackgroundJobs($info['background-jobs']); - if(isset($info['settings']) && is_array($info['settings'])) { - \OC::$server->getSettingsManager()->setupSettings($info['settings']); - } //run appinfo/install.php if(!isset($data['noinstall']) or $data['noinstall']==false) { @@ -605,12 +602,6 @@ class Installer { OC_App::setAppTypes($info['id']); - if(isset($info['settings']) && is_array($info['settings'])) { - // requires that autoloading was registered for the app, - // as happens before running the install.php some lines above - \OC::$server->getSettingsManager()->setupSettings($info['settings']); - } - return $info['id']; } diff --git a/lib/private/Server.php b/lib/private/Server.php index 8799223345..b12b92272f 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -1074,12 +1074,10 @@ class Server extends ServerContainer implements IServerContainer { $c->getUserManager(), $c->getLockingProvider(), $c->getRequest(), - new \OC\Settings\Mapper($c->getDatabaseConnection()), $c->getURLGenerator(), $c->query(AccountManager::class), $c->getGroupManager(), $c->getL10NFactory(), - $c->getThemingDefaults(), $c->getAppManager() ); return $manager; diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index efeedbe6fc..387460852a 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -32,7 +32,6 @@ namespace OC\Settings; use OC\Accounts\AccountManager; use OCP\App\IAppManager; use OCP\AppFramework\QueryException; -use OCP\AutoloadNotAllowedException; use OCP\Encryption\IManager as EncryptionManager; use OCP\IConfig; use OCP\IDBConnection; @@ -54,8 +53,6 @@ class Manager implements IManager { private $log; /** @var IDBConnection */ private $dbc; - /** @var Mapper */ - private $mapper; /** @var IL10N */ private $l; /** @var IConfig */ @@ -76,8 +73,6 @@ class Manager implements IManager { private $groupManager; /** @var IFactory */ private $l10nFactory; - /** @var \OC_Defaults */ - private $defaults; /** @var IAppManager */ private $appManager; @@ -90,12 +85,11 @@ class Manager implements IManager { * @param IUserManager $userManager * @param ILockingProvider $lockingProvider * @param IRequest $request - * @param Mapper $mapper * @param IURLGenerator $url * @param AccountManager $accountManager * @param IGroupManager $groupManager * @param IFactory $l10nFactory - * @param \OC_Defaults $defaults + * @param IAppManager $appManager */ public function __construct( ILogger $log, @@ -106,17 +100,14 @@ class Manager implements IManager { IUserManager $userManager, ILockingProvider $lockingProvider, IRequest $request, - Mapper $mapper, IURLGenerator $url, AccountManager $accountManager, IGroupManager $groupManager, IFactory $l10nFactory, - \OC_Defaults $defaults, IAppManager $appManager ) { $this->log = $log; $this->dbc = $dbc; - $this->mapper = $mapper; $this->l = $l; $this->config = $config; $this->encryptionManager = $encryptionManager; @@ -127,233 +118,112 @@ class Manager implements IManager { $this->accountManager = $accountManager; $this->groupManager = $groupManager; $this->l10nFactory = $l10nFactory; - $this->defaults = $defaults; $this->appManager = $appManager; } - /** - * @inheritdoc - */ - public function setupSettings(array $settings) { - if (!empty($settings[IManager::KEY_ADMIN_SECTION])) { - foreach ($settings[IManager::KEY_ADMIN_SECTION] as $className) { - $this->setupSectionEntry($className, 'admin'); - } - } - if (!empty($settings[IManager::KEY_ADMIN_SETTINGS])) { - foreach ($settings[IManager::KEY_ADMIN_SETTINGS] as $className) { - $this->setupSettingsEntry($className, 'admin'); - } - } + /** @var array */ + protected $sectionClasses = []; - if (!empty($settings[IManager::KEY_PERSONAL_SECTION])) { - foreach ($settings[IManager::KEY_PERSONAL_SECTION] as $className) { - $this->setupSectionEntry($className, 'personal'); - } - } - if (!empty($settings[IManager::KEY_PERSONAL_SETTINGS])) { - foreach ($settings[IManager::KEY_PERSONAL_SETTINGS] as $className) { - $this->setupSettingsEntry($className, 'personal'); - } - } + /** @var array */ + protected $sections = []; + + /** + * @param string $type 'admin' or 'personal' + * @param string $section Class must implement OCP\Settings\ISection + * @return void + */ + public function registerSection(string $type, string $section) { + $this->sectionClasses[$section] = $type; } /** - * attempts to remove an apps section and/or settings entry. A listener is - * added centrally making sure that this method is called ones an app was - * disabled. - * - * @param string $appId - * @since 9.1.0 + * @param string $type 'admin' or 'personal' + * @return ISection[] */ - public function onAppDisabled($appId) { - $appInfo = \OC_App::getAppInfo($appId); // hello static legacy - - if (!empty($appInfo['settings'][IManager::KEY_ADMIN_SECTION])) { - foreach ($appInfo['settings'][IManager::KEY_ADMIN_SECTION] as $className) { - $this->mapper->remove(Mapper::TABLE_ADMIN_SECTIONS, trim($className, '\\')); - } - } - if (!empty($appInfo['settings'][IManager::KEY_ADMIN_SETTINGS])) { - foreach ($appInfo['settings'][IManager::KEY_ADMIN_SETTINGS] as $className) { - $this->mapper->remove(Mapper::TABLE_ADMIN_SETTINGS, trim($className, '\\')); - } + protected function getSections(string $type): array { + if (!isset($this->sections[$type])) { + $this->sections[$type] = []; } - if (!empty($appInfo['settings'][IManager::KEY_PERSONAL_SECTION])) { - foreach ($appInfo['settings'][IManager::KEY_PERSONAL_SECTION] as $className) { - $this->mapper->remove(Mapper::TABLE_PERSONAL_SECTIONS, trim($className, '\\')); + foreach ($this->sectionClasses as $class => $sectionType) { + try { + /** @var ISection $section */ + $section = \OC::$server->query($class); + } catch (QueryException $e) { + $this->log->logException($e, ['level' => Util::INFO]); + continue; } - } - if (!empty($appInfo['settings'][IManager::KEY_PERSONAL_SETTINGS])) { - foreach ($appInfo['settings'][IManager::KEY_PERSONAL_SETTINGS] as $className) { - $this->mapper->remove(Mapper::TABLE_PERSONAL_SETTINGS, trim($className, '\\')); + + if (!$section instanceof ISection) { + $this->log->logException(new \InvalidArgumentException('Invalid settings section registered'), ['level' => Util::INFO]); + continue; } + + $this->sections[$sectionType][$section->getID()] = $section; + + unset($this->sectionClasses[$class]); } + + return $this->sections[$type]; } - public function checkForOrphanedClassNames() { - $tables = [Mapper::TABLE_ADMIN_SECTIONS, Mapper::TABLE_ADMIN_SETTINGS, Mapper::TABLE_PERSONAL_SECTIONS, Mapper::TABLE_PERSONAL_SETTINGS]; - foreach ($tables as $table) { - $classes = $this->mapper->getClasses($table); - foreach ($classes as $className) { - try { - \OC::$server->query($className); - } catch (QueryException $e) { - $this->mapper->remove($table, $className); - } - } - } + /** @var array */ + protected $settingClasses = []; + + /** @var array */ + protected $settings = []; + + /** + * @param string $type 'admin' or 'personal' + * @param string $setting Class must implement OCP\Settings\ISetting + * @return void + */ + public function registerSetting(string $type, string $setting) { + $this->settingClasses[$setting] = $type; } /** - * @param string $sectionClassName - * @param string $type either 'admin' or 'personal' + * @param string $type 'admin' or 'personal' + * @param string $section + * @return ISettings[] */ - private function setupSectionEntry($sectionClassName, $type) { - if (!class_exists($sectionClassName)) { - $this->log->debug('Could not find ' . ucfirst($type) . ' section class ' . $sectionClassName); - return; + protected function getSettings(string $type, string $section): array { + if (!isset($this->settings[$type])) { + $this->settings[$type] = []; } - try { - $section = $this->query($sectionClassName); - } catch (QueryException $e) { - // cancel - return; + if (!isset($this->settings[$type][$section])) { + $this->settings[$type][$section] = []; } - if (!$section instanceof ISection) { - $this->log->error( - ucfirst($type) .' section instance must implement \OCP\ISection. Invalid class: {class}', - ['class' => $sectionClassName] - ); - return; - } - $table = $this->getSectionTableForType($type); - if(!$this->hasSection(get_class($section), $table)) { - $this->addSection($section, $table); - } else { - $this->updateSection($section, $table); - } - } + foreach ($this->settingClasses as $class => $settingsType) { + try { + /** @var ISettings $setting */ + $setting = \OC::$server->query($class); + } catch (QueryException $e) { + $this->log->logException($e, ['level' => Util::INFO]); + continue; + } - private function addSection(ISection $section, $table) { - $this->mapper->add($table, [ - 'id' => $section->getID(), - 'class' => get_class($section), - 'priority' => $section->getPriority(), - ]); - } + if (!$setting instanceof ISettings) { + $this->log->logException(new \InvalidArgumentException('Invalid settings setting registered'), ['level' => Util::INFO]); + continue; + } - private function addSettings(ISettings $settings, $table) { - $this->mapper->add($table, [ - 'class' => get_class($settings), - 'section' => $settings->getSection(), - 'priority' => $settings->getPriority(), - ]); - } + if (!isset($this->settings[$settingsType][$setting->getSection()])) { + $this->settings[$settingsType][$setting->getSection()] = []; + } + $this->settings[$settingsType][$setting->getSection()][] = $setting; - private function updateSettings(ISettings $settings, $table) { - $this->mapper->update( - $table, - 'class', - get_class($settings), - [ - 'section' => $settings->getSection(), - 'priority' => $settings->getPriority(), - ] - ); - } - - private function updateSection(ISection $section, $table) { - $this->mapper->update( - $table, - 'class', - get_class($section), - [ - 'id' => $section->getID(), - 'priority' => $section->getPriority(), - ] - ); - } - - /** - * @param string $className - * @param string $table - * @return bool - */ - private function hasSection($className, $table) { - return $this->mapper->has($table, $className); - } - - /** - * @param string $className - * @return bool - */ - private function hasSettings($className, $table) { - return $this->mapper->has($table, $className); - } - - private function setupSettingsEntry($settingsClassName, $type) { - if (!class_exists($settingsClassName)) { - $this->log->debug('Could not find ' . $type . ' section class ' . $settingsClassName); - return; + unset($this->settingClasses[$class]); } - try { - /** @var ISettings $settings */ - $settings = $this->query($settingsClassName); - } catch (QueryException $e) { - // cancel - return; - } - - if (!$settings instanceof ISettings) { - $this->log->error( - ucfirst($type) . ' section instance must implement \OCP\Settings\ISettings. Invalid class: {class}', - ['class' => $settingsClassName] - ); - return; - } - $table = $this->getSettingsTableForType($type); - if (!$this->hasSettings(get_class($settings), $table)) { - $this->addSettings($settings, $table); - } else { - $this->updateSettings($settings, $table); - } - } - - private function getSectionTableForType($type) { - if($type === 'admin') { - return Mapper::TABLE_ADMIN_SECTIONS; - } else if($type === 'personal') { - return Mapper::TABLE_PERSONAL_SECTIONS; - } - throw new \InvalidArgumentException('"admin" or "personal" expected'); - } - - private function getSettingsTableForType($type) { - if($type === 'admin') { - return Mapper::TABLE_ADMIN_SETTINGS; - } else if($type === 'personal') { - return Mapper::TABLE_PERSONAL_SETTINGS; - } - throw new \InvalidArgumentException('"admin" or "personal" expected'); - } - - private function query($className) { - try { - return \OC::$server->query($className); - } catch (QueryException $e) { - $this->log->logException($e, ['level' => Util::INFO]); - throw $e; - } + return $this->settings[$type][$section]; } /** * @inheritdoc */ - public function getAdminSections() { + public function getAdminSections(): array { // built-in sections $sections = [ 0 => [new Section('server', $this->l->t('Basic settings'), 0, $this->url->imagePath('settings', 'admin.svg'))], @@ -364,17 +234,15 @@ class Manager implements IManager { 99 => [new Section('tips-tricks', $this->l->t('Tips & tricks'), 0, $this->url->imagePath('settings', 'help.svg'))], ]; - $rows = $this->mapper->getAdminSectionsFromDB(); + $appSections = $this->getSections('admin'); - foreach ($rows as $row) { - if (!isset($sections[$row['priority']])) { - $sections[$row['priority']] = []; - } - try { - $sections[$row['priority']][] = $this->query($row['class']); - } catch (QueryException $e) { - // skip + foreach ($appSections as $section) { + /** @var ISection $section */ + if (!isset($sections[$section->getPriority()])) { + $sections[$section->getPriority()] = []; } + + $sections[$section->getPriority()][] = $section; } ksort($sections); @@ -386,39 +254,37 @@ class Manager implements IManager { * @param string $section * @return ISection[] */ - private function getBuiltInAdminSettings($section) { + private function getBuiltInAdminSettings($section): array { $forms = []; - try { - if ($section === 'server') { - /** @var ISettings $form */ - $form = new Admin\Server($this->dbc, $this->request, $this->config, $this->lockingProvider, $this->l); - $forms[$form->getPriority()] = [$form]; - $form = new Admin\ServerDevNotice(); - $forms[$form->getPriority()] = [$form]; - } - if ($section === 'encryption') { - /** @var ISettings $form */ - $form = new Admin\Encryption($this->encryptionManager, $this->userManager); - $forms[$form->getPriority()] = [$form]; - } - if ($section === 'sharing') { - /** @var ISettings $form */ - $form = new Admin\Sharing($this->config); - $forms[$form->getPriority()] = [$form]; - } - if ($section === 'additional') { - /** @var ISettings $form */ - $form = new Admin\Additional($this->config); - $forms[$form->getPriority()] = [$form]; - } - if ($section === 'tips-tricks') { - /** @var ISettings $form */ - $form = new Admin\TipsTricks($this->config); - $forms[$form->getPriority()] = [$form]; - } - } catch (QueryException $e) { - // skip + + if ($section === 'server') { + /** @var ISettings $form */ + $form = new Admin\Server($this->dbc, $this->request, $this->config, $this->lockingProvider, $this->l); + $forms[$form->getPriority()] = [$form]; + $form = new Admin\ServerDevNotice(); + $forms[$form->getPriority()] = [$form]; } + if ($section === 'encryption') { + /** @var ISettings $form */ + $form = new Admin\Encryption($this->encryptionManager, $this->userManager); + $forms[$form->getPriority()] = [$form]; + } + if ($section === 'sharing') { + /** @var ISettings $form */ + $form = new Admin\Sharing($this->config); + $forms[$form->getPriority()] = [$form]; + } + if ($section === 'additional') { + /** @var ISettings $form */ + $form = new Admin\Additional($this->config); + $forms[$form->getPriority()] = [$form]; + } + if ($section === 'tips-tricks') { + /** @var ISettings $form */ + $form = new Admin\TipsTricks($this->config); + $forms[$form->getPriority()] = [$form]; + } + return $forms; } @@ -426,58 +292,48 @@ class Manager implements IManager { * @param string $section * @return ISection[] */ - private function getBuiltInPersonalSettings($section) { + private function getBuiltInPersonalSettings($section): array { $forms = []; - try { - if ($section === 'personal-info') { - /** @var ISettings $form */ - $form = new Personal\PersonalInfo( - $this->config, - $this->userManager, - $this->groupManager, - $this->accountManager, - $this->appManager, - $this->l10nFactory, - $this->l - ); - $forms[$form->getPriority()] = [$form]; - } - if($section === 'security') { - /** @var ISettings $form */ - $form = new Personal\Security(); - $forms[$form->getPriority()] = [$form]; - } - if ($section === 'additional') { - /** @var ISettings $form */ - $form = new Personal\Additional($this->config); - $forms[$form->getPriority()] = [$form]; - } - } catch (QueryException $e) { - // skip + + if ($section === 'personal-info') { + /** @var ISettings $form */ + $form = new Personal\PersonalInfo( + $this->config, + $this->userManager, + $this->groupManager, + $this->accountManager, + $this->appManager, + $this->l10nFactory, + $this->l + ); + $forms[$form->getPriority()] = [$form]; } + if($section === 'security') { + /** @var ISettings $form */ + $form = new Personal\Security(); + $forms[$form->getPriority()] = [$form]; + } + if ($section === 'additional') { + /** @var ISettings $form */ + $form = new Personal\Additional(); + $forms[$form->getPriority()] = [$form]; + } + return $forms; } /** * @inheritdoc */ - public function getAdminSettings($section) { + public function getAdminSettings($section): array { $settings = $this->getBuiltInAdminSettings($section); - $dbRows = $this->mapper->getAdminSettingsFromDB($section); + $appSettings = $this->getSettings('admin', $section); - foreach ($dbRows as $row) { - if (!isset($settings[$row['priority']])) { - $settings[$row['priority']] = []; - } - try { - $settings[$row['priority']][] = $this->query($row['class']); - } catch (QueryException $e) { - // skip - } catch (AutoloadNotAllowedException $e) { - // skip error and remove remnant of disabled app - $this->log->warning('Orphan setting entry will be removed from admin_settings: ' . json_encode($row)); - $this->mapper->remove(Mapper::TABLE_ADMIN_SETTINGS, $row['class']); + foreach ($appSettings as $setting) { + if (!isset($settings[$setting->getPriority()])) { + $settings[$setting->getPriority()] = []; } + $settings[$setting->getPriority()][] = $setting; } ksort($settings); @@ -487,7 +343,7 @@ class Manager implements IManager { /** * @inheritdoc */ - public function getPersonalSections() { + public function getPersonalSections(): array { $sections = [ 0 => [new Section('personal-info', $this->l->t('Personal info'), 0, $this->url->imagePath('core', 'actions/info.svg'))], 5 => [new Section('security', $this->l->t('Security'), 0, $this->url->imagePath('settings', 'password.svg'))], @@ -495,21 +351,19 @@ class Manager implements IManager { ]; $legacyForms = \OC_App::getForms('personal'); - if(count($legacyForms) > 0 && $this->hasLegacyPersonalSettingsToRender($legacyForms)) { + if(!empty($legacyForms) && $this->hasLegacyPersonalSettingsToRender($legacyForms)) { $sections[98] = [new Section('additional', $this->l->t('Additional settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))]; } - $rows = $this->mapper->getPersonalSectionsFromDB(); + $appSections = $this->getSections('personal'); - foreach ($rows as $row) { - if (!isset($sections[$row['priority']])) { - $sections[$row['priority']] = []; - } - try { - $sections[$row['priority']][] = $this->query($row['class']); - } catch (QueryException $e) { - // skip + foreach ($appSections as $section) { + /** @var ISection $section */ + if (!isset($sections[$section->getPriority()])) { + $sections[$section->getPriority()] = []; } + + $sections[$section->getPriority()][] = $section; } ksort($sections); @@ -518,10 +372,10 @@ class Manager implements IManager { } /** - * @param $forms + * @param string[] $forms * @return bool */ - private function hasLegacyPersonalSettingsToRender($forms) { + private function hasLegacyPersonalSettingsToRender(array $forms): bool { foreach ($forms as $form) { if(trim($form) !== '') { return true; @@ -533,19 +387,15 @@ class Manager implements IManager { /** * @inheritdoc */ - public function getPersonalSettings($section) { + public function getPersonalSettings($section): array { $settings = $this->getBuiltInPersonalSettings($section); - $dbRows = $this->mapper->getPersonalSettingsFromDB($section); + $appSettings = $this->getSettings('personal', $section); - foreach ($dbRows as $row) { - if (!isset($settings[$row['priority']])) { - $settings[$row['priority']] = []; - } - try { - $settings[$row['priority']][] = $this->query($row['class']); - } catch (QueryException $e) { - // skip + foreach ($appSettings as $setting) { + if (!isset($settings[$setting->getPriority()])) { + $settings[$setting->getPriority()] = []; } + $settings[$setting->getPriority()][] = $setting; } ksort($settings); diff --git a/lib/private/Settings/Mapper.php b/lib/private/Settings/Mapper.php deleted file mode 100644 index 1c05ea9fe3..0000000000 --- a/lib/private/Settings/Mapper.php +++ /dev/null @@ -1,217 +0,0 @@ - - * - * @author Arthur Schiwon - * @author Lukas Reschke - * @author Robin Appelman - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -namespace OC\Settings; - -use OCP\IDBConnection; - -class Mapper { - const TABLE_ADMIN_SETTINGS = 'admin_settings'; - const TABLE_ADMIN_SECTIONS = 'admin_sections'; - const TABLE_PERSONAL_SETTINGS = 'personal_settings'; - const TABLE_PERSONAL_SECTIONS = 'personal_sections'; - - /** @var IDBConnection */ - private $dbc; - - /** - * @param IDBConnection $dbc - */ - public function __construct(IDBConnection $dbc) { - $this->dbc = $dbc; - } - - /** - * Get the configured admin settings from the database for the provided section - * - * @param string $section - * @return array[] [['class' => string, 'priority' => int], ...] - */ - public function getAdminSettingsFromDB($section) { - return $this->getSettingsFromDB(self::TABLE_ADMIN_SETTINGS, $section); - } - - /** - * Get the configured personal settings from the database for the provided section - * - * @param string $section - * @return array[] [['class' => string, 'priority' => int], ...] - */ - public function getPersonalSettingsFromDB($section) { - return $this->getSettingsFromDB(self::TABLE_PERSONAL_SETTINGS, $section); - } - - /** - * Get the configured settings from the database for the provided table and section - * - * @param $table - * @param $section - * @return array - */ - private function getSettingsFromDB($table, $section) { - $query = $this->dbc->getQueryBuilder(); - $query->select(['class', 'priority']) - ->from($table) - ->where($query->expr()->eq('section', $this->dbc->getQueryBuilder()->createParameter('section'))) - ->setParameter('section', $section); - - $result = $query->execute(); - return $result->fetchAll(); - } - - /** - * Get the configured admin sections from the database - * - * @return array[] [['class' => string, 'priority' => int], ...] - */ - public function getAdminSectionsFromDB() { - return $this->getSectionsFromDB('admin'); - } - - /** - * Get the configured admin sections from the database - * - * @return array[] [['class' => string, 'priority' => int], ...] - */ - public function getPersonalSectionsFromDB() { - return $this->getSectionsFromDB('personal'); - } - - /** - * Get the configured sections from the database by table - * - * @param string $type either 'personal' or 'admin' - * @return array[] [['class' => string, 'priority' => int], ...] - */ - public function getSectionsFromDB($type) { - if($type === 'admin') { - $sectionsTable = self::TABLE_ADMIN_SECTIONS; - $settingsTable = self::TABLE_ADMIN_SETTINGS; - } else if($type === 'personal') { - $sectionsTable = self::TABLE_PERSONAL_SECTIONS; - $settingsTable = self::TABLE_PERSONAL_SETTINGS; - } else { - throw new \InvalidArgumentException('"admin" or "personal" expected'); - } - $query = $this->dbc->getQueryBuilder(); - $query->selectDistinct('s.class') - ->addSelect('s.priority') - ->from($sectionsTable, 's') - ->from($settingsTable, 'f') - ->where($query->expr()->eq('s.id', 'f.section')); - $result = $query->execute(); - return array_map(function ($row) { - $row['priority'] = (int)$row['priority']; - return $row; - }, $result->fetchAll()); - } - - /** - * @param string $table one of the Mapper::TABLE_* constants - * @param array $values - */ - public function add($table, array $values) { - $query = $this->dbc->getQueryBuilder(); - $values = array_map(function ($value) use ($query) { - return $query->createNamedParameter($value); - }, $values); - $query->insert($table)->values($values); - $query->execute(); - } - - /** - * returns the registered classes in the given table - * - * @param string $table one of the Mapper::TABLE_* constants - * @return string[] - */ - public function getClasses($table) { - $q = $this->dbc->getQueryBuilder(); - $resultStatement = $q->select('class') - ->from($table) - ->execute(); - $data = $resultStatement->fetchAll(); - $resultStatement->closeCursor(); - - return array_map(function ($row) { - return $row['class']; - }, $data); - } - - /** - * Check if a class is configured in the database - * - * @param string $table one of the Mapper::TABLE_* constants - * @param string $className - * @return bool - */ - public function has($table, $className) { - $query = $this->dbc->getQueryBuilder(); - $query->select('class') - ->from($table) - ->where($query->expr()->eq('class', $query->createNamedParameter($className))) - ->setMaxResults(1); - - $result = $query->execute(); - $row = $result->fetch(); - $result->closeCursor(); - - return (bool)$row; - } - - /** - * deletes an settings or admin entry from the given table - * - * @param string $table one of the Mapper::TABLE_* constants - * @param string $className - */ - public function remove($table, $className) { - $query = $this->dbc->getQueryBuilder(); - $query->delete($table) - ->where($query->expr()->eq('class', $query->createNamedParameter($className))); - - $query->execute(); - } - - /** - * @param string $table one of the Mapper::TABLE_* constants - * @param string $idCol - * @param string $id - * @param array $values - * @suppress SqlInjectionChecker - */ - public function update($table, $idCol, $id, $values) { - $query = $this->dbc->getQueryBuilder(); - $query->update($table); - foreach ($values as $key => $value) { - $query->set($key, $query->createNamedParameter($value)); - } - $query - ->where($query->expr()->eq($idCol, $query->createParameter($idCol))) - ->setParameter($idCol, $id) - ->execute(); - } - -} diff --git a/lib/private/Settings/RemoveOrphaned.php b/lib/private/Settings/RemoveOrphaned.php deleted file mode 100644 index 790ca06002..0000000000 --- a/lib/private/Settings/RemoveOrphaned.php +++ /dev/null @@ -1,92 +0,0 @@ - - * - * @author Arthur Schiwon - * @author Lukas Reschke - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -namespace OC\Settings; - -use OC\BackgroundJob\JobList; -use OC\BackgroundJob\TimedJob; -use OC\NeedsUpdateException; -use OCP\BackgroundJob\IJobList; -use OCP\ILogger; - -/** - * Class RemoveOrphaned - * - * @package OC\Settings - */ -class RemoveOrphaned extends TimedJob { - - /** @var IJobList */ - private $jobList; - - /** @var ILogger */ - private $logger; - - /** @var Manager */ - private $manager; - - public function __construct(Manager $manager = null) { - if($manager !== null) { - $this->manager = $manager; - } else { - // fix DI for Jobs - $this->manager = \OC::$server->getSettingsManager(); - } - } - - /** - * run the job, then remove it from the job list - * - * @param JobList $jobList - * @param ILogger|null $logger - */ - public function execute($jobList, ILogger $logger = null) { - // add an interval of 15 mins - $this->setInterval(15*60); - - $this->jobList = $jobList; - $this->logger = $logger; - parent::execute($jobList, $logger); - } - - /** - * @param array $argument - * @throws \Exception - * @throws \OC\NeedsUpdateException - */ - protected function run($argument) { - try { - \OC_App::loadApps(); - } catch (NeedsUpdateException $ex) { - // only run when apps are up to date - return; - } - - $this->manager->checkForOrphanedClassNames(); - - // remove the job once executed successfully - $this->jobList->remove($this); - } - -} diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php index ea44ac8a14..f8f49d2211 100644 --- a/lib/private/legacy/app.php +++ b/lib/private/legacy/app.php @@ -176,6 +176,28 @@ class OC_App { \OC::$server->getActivityManager()->registerProvider($provider); } } + + if (!empty($info['settings']['admin'])) { + foreach ($info['settings']['admin'] as $setting) { + \OC::$server->getSettingsManager()->registerSetting('admin', $setting); + } + } + if (!empty($info['settings']['admin-section'])) { + foreach ($info['settings']['admin-section'] as $section) { + \OC::$server->getSettingsManager()->registerSection('admin', $section); + } + } + if (!empty($info['settings']['personal'])) { + foreach ($info['settings']['personal'] as $setting) { + \OC::$server->getSettingsManager()->registerSetting('personal', $setting); + } + } + if (!empty($info['settings']['personal-section'])) { + foreach ($info['settings']['personal-section'] as $section) { + \OC::$server->getSettingsManager()->registerSection('personal', $section); + } + } + if (!empty($info['collaboration']['plugins'])) { // deal with one or many plugin entries $plugins = isset($info['collaboration']['plugins']['plugin']['@value']) ? @@ -1007,7 +1029,6 @@ class OC_App { if(isset($info['settings']) && is_array($info['settings'])) { $appPath = self::getAppPath($app); self::registerAutoloading($app, $appPath); - \OC::$server->getSettingsManager()->setupSettings($info['settings']); } \OC_Hook::emit('OC_App', 'post_enable', array('app' => $app)); @@ -1055,9 +1076,6 @@ class OC_App { include $appPath . '/appinfo/update.php'; } self::setupBackgroundJobs($appData['background-jobs']); - if(isset($appData['settings']) && is_array($appData['settings'])) { - \OC::$server->getSettingsManager()->setupSettings($appData['settings']); - } //set remote/public handlers if (array_key_exists('ocsid', $appData)) { diff --git a/lib/public/Settings/IManager.php b/lib/public/Settings/IManager.php index 1a1a4b8e66..52f12c3a8f 100644 --- a/lib/public/Settings/IManager.php +++ b/lib/public/Settings/IManager.php @@ -49,46 +49,18 @@ interface IManager { const KEY_PERSONAL_SECTION = 'personal-section'; /** - * sets up settings according to data specified by an apps info.xml, within - * the element. - * - * @param array $settings an associative array, allowed keys are as specified - * by the KEY_ constant of this interface. The value - * must always be a class name, implement either - * IAdmin or ISection. I.e. only one section and admin - * setting can be configured per app. - * @since 9.1.0 + * @param string $type 'admin' or 'personal' + * @param string $section Class must implement OCP\Settings\ISection + * @since 14.0.0 */ - public function setupSettings(array $settings); + public function registerSection(string $type, string $section); /** - * attempts to remove an apps section and/or settings entry. A listener is - * added centrally making sure that this method is called ones an app was - * disabled. - * - * What this does not help with is when applications change their settings - * or section classes during their life time. New entries will be added, - * but inactive ones will still reside in the database. - * - * @param string $appId - * @since 9.1.0 + * @param string $type 'admin' or 'personal' + * @param string $setting Class must implement OCP\Settings\ISetting + * @since 14.0.0 */ - public function onAppDisabled($appId); - - /** - * The method should check all registered classes whether they are still - * instantiable and remove them, if not. This method is called by a - * background job once, after one or more apps were updated. - * - * An app`s info.xml can change during an update and make it unknown whether - * a registered class name was changed or not. An old one would just stay - * registered. Another case is if an admin takes a radical approach and - * simply removes an app from the app folder. These unregular checks will - * take care of such situations. - * - * @since 9.1.0 - */ - public function checkForOrphanedClassNames(); + public function registerSetting(string $type, string $setting); /** * returns a list of the admin sections @@ -96,7 +68,7 @@ interface IManager { * @return array array of ISection[] where key is the priority * @since 9.1.0 */ - public function getAdminSections(); + public function getAdminSections(): array; /** * returns a list of the personal sections @@ -104,7 +76,7 @@ interface IManager { * @return array array of ISection[] where key is the priority * @since 13.0.0 */ - public function getPersonalSections(); + public function getPersonalSections(): array; /** * returns a list of the admin settings @@ -113,7 +85,7 @@ interface IManager { * @return array array of IAdmin[] where key is the priority * @since 9.1.0 */ - public function getAdminSettings($section); + public function getAdminSettings($section): array; /** * returns a list of the personal settings @@ -122,5 +94,5 @@ interface IManager { * @return array array of IPersonal[] where key is the priority * @since 13.0.0 */ - public function getPersonalSettings($section); + public function getPersonalSettings($section): array; } diff --git a/tests/lib/Settings/ManagerTest.php b/tests/lib/Settings/ManagerTest.php index be5aad2e41..577abc7915 100644 --- a/tests/lib/Settings/ManagerTest.php +++ b/tests/lib/Settings/ManagerTest.php @@ -62,8 +62,6 @@ class ManagerTest extends TestCase { private $lockingProvider; /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */ private $request; - /** @var Mapper|\PHPUnit_Framework_MockObject_MockObject */ - private $mapper; /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */ private $url; /** @var AccountManager|\PHPUnit_Framework_MockObject_MockObject */ @@ -72,8 +70,6 @@ class ManagerTest extends TestCase { private $groupManager; /** @var IFactory|\PHPUnit_Framework_MockObject_MockObject */ private $l10nFactory; - /** @var \OC_Defaults|\PHPUnit_Framework_MockObject_MockObject */ - private $defaults; /** @var IAppManager */ private $appManager; @@ -88,12 +84,10 @@ class ManagerTest extends TestCase { $this->userManager = $this->createMock(IUserManager::class); $this->lockingProvider = $this->createMock(ILockingProvider::class); $this->request = $this->createMock(IRequest::class); - $this->mapper = $this->createMock(Mapper::class); $this->url = $this->createMock(IURLGenerator::class); $this->accountManager = $this->createMock(AccountManager::class); $this->groupManager = $this->createMock(IGroupManager::class); $this->l10nFactory = $this->createMock(IFactory::class); - $this->defaults = $this->createMock(\OC_Defaults::class); $this->appManager = $this->createMock(IAppManager::class); $this->manager = new Manager( @@ -105,90 +99,21 @@ class ManagerTest extends TestCase { $this->userManager, $this->lockingProvider, $this->request, - $this->mapper, $this->url, $this->accountManager, $this->groupManager, $this->l10nFactory, - $this->defaults, $this->appManager ); } - public function settingsTypeProvider() { - return [ - ['admin', 'admin_settings'], - ['personal', 'personal_settings'], - ]; - } - - /** - * @dataProvider settingsTypeProvider - * @param string $type - * @param string $table - */ - public function testSetupSettingsUpdate($type, $table) { - $className = 'OCA\Files\Settings\Admin'; - - $this->mapper->expects($this->any()) - ->method('has') - ->with($table, $className) - ->will($this->returnValue(true)); - - $this->mapper->expects($this->once()) - ->method('update') - ->with($table, - 'class', - $className, [ - 'section' => 'additional', - 'priority' => 5 - ]); - $this->mapper->expects($this->never()) - ->method('add'); - - $this->manager->setupSettings([ - $type => [$className], - ]); - } - - /** - * @dataProvider settingsTypeProvider - * @param string $type - * @param string $table - */ - public function testSetupSettingsAdd($type, $table) { - $this->mapper->expects($this->any()) - ->method('has') - ->with($table, 'OCA\Files\Settings\Admin') - ->will($this->returnValue(false)); - - $this->mapper->expects($this->once()) - ->method('add') - ->with($table, [ - 'class' => 'OCA\Files\Settings\Admin', - 'section' => 'additional', - 'priority' => 5 - ]); - - $this->mapper->expects($this->never()) - ->method('update'); - - $this->manager->setupSettings([ - $type => ['OCA\Files\Settings\Admin'], - ]); - } - public function testGetAdminSections() { $this->l10n ->expects($this->any()) ->method('t') ->will($this->returnArgument(0)); - $this->mapper->expects($this->once()) - ->method('getAdminSectionsFromDB') - ->will($this->returnValue([ - ['class' => \OCA\WorkflowEngine\Settings\Section::class, 'priority' => 90] - ])); + $this->manager->registerSection('admin', \OCA\WorkflowEngine\Settings\Section::class); $this->url->expects($this->exactly(6)) ->method('imagePath') @@ -205,7 +130,7 @@ class ManagerTest extends TestCase { 5 => [new Section('sharing', 'Sharing', 0, '2')], 10 => [new Section('security', 'Security', 0, '3')], 45 => [new Section('encryption', 'Encryption', 0, '3')], - 90 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], + 55 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], 98 => [new Section('additional', 'Additional settings', 0, '4')], 99 => [new Section('tips-tricks', 'Tips & tricks', 0, '5')], ], $this->manager->getAdminSections()); @@ -217,11 +142,7 @@ class ManagerTest extends TestCase { ->method('t') ->will($this->returnArgument(0)); - $this->mapper->expects($this->once()) - ->method('getPersonalSectionsFromDB') - ->will($this->returnValue([ - ['class' => \OCA\WorkflowEngine\Settings\Section::class, 'priority' => 90] - ])); + $this->manager->registerSection('personal', \OCA\WorkflowEngine\Settings\Section::class); $this->url->expects($this->exactly(3)) ->method('imagePath') @@ -231,11 +152,11 @@ class ManagerTest extends TestCase { ['settings', 'change.svg', '3'], ]); - $this->assertArraySubset([ + $this->assertEquals([ 0 => [new Section('personal-info', 'Personal info', 0, '1')], 5 => [new Section('security', 'Security', 0, '2')], 15 => [new Section('sync-clients', 'Sync clients', 0, '3')], - 90 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], + 55 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], ], $this->manager->getPersonalSections()); } @@ -245,11 +166,6 @@ class ManagerTest extends TestCase { ->method('t') ->will($this->returnArgument(0)); - $this->mapper->expects($this->once()) - ->method('getAdminSectionsFromDB') - ->will($this->returnValue([ - ])); - $this->url->expects($this->exactly(6)) ->method('imagePath') ->willReturnMap([ @@ -276,10 +192,6 @@ class ManagerTest extends TestCase { ->method('t') ->will($this->returnArgument(0)); - $this->mapper->expects($this->once()) - ->method('getPersonalSectionsFromDB') - ->will($this->returnValue([])); - $this->url->expects($this->exactly(3)) ->method('imagePath') ->willReturnMap([ @@ -296,20 +208,12 @@ class ManagerTest extends TestCase { } public function testGetAdminSettings() { - $this->mapper->expects($this->any()) - ->method('getAdminSettingsFromDB') - ->will($this->returnValue([])); - $this->assertEquals([ 0 => [new Sharing($this->config)], ], $this->manager->getAdminSettings('sharing')); } public function testGetPersonalSettings() { - $this->mapper->expects($this->any()) - ->method('getPersonalSettingsFromDB') - ->will($this->returnValue([])); - $this->assertEquals([ 10 => [new Security()], ], $this->manager->getPersonalSettings('security')); diff --git a/tests/lib/Settings/MapperTest.php b/tests/lib/Settings/MapperTest.php deleted file mode 100644 index 6a648acd5f..0000000000 --- a/tests/lib/Settings/MapperTest.php +++ /dev/null @@ -1,139 +0,0 @@ - - * - * @author Robin Appelman - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -namespace Tests\Settings; - -use OC\DB\QueryBuilder\Literal; -use OC\Settings\Mapper; -use Test\TestCase; - -/** - * @group DB - */ -class MapperTest extends TestCase { - const SECTION_PREFIX = 'test_section_'; - - /** @var Mapper */ - private $mapper; - - public function setUp() { - parent::setUp(); - $this->mapper = new Mapper(\OC::$server->getDatabaseConnection()); - } - - public function tearDown() { - parent::tearDown(); - - $db = \OC::$server->getDatabaseConnection(); - $builder = $db->getQueryBuilder(); - - $builder->delete(Mapper::TABLE_ADMIN_SECTIONS) - ->where($builder->expr()->like('id', new Literal(self::SECTION_PREFIX . '%'))); - - $builder->delete(Mapper::TABLE_ADMIN_SETTINGS) - ->where($builder->expr()->like('section', new Literal(self::SECTION_PREFIX . '%'))); - } - - public function testManipulateSettings() { - $this->assertEquals(false, $this->mapper->has(Mapper::TABLE_ADMIN_SETTINGS, '\OC\Dummy')); - $this->assertNotContains('\OC\Dummy', $this->mapper->getClasses(Mapper::TABLE_ADMIN_SETTINGS)); - - $this->mapper->add(Mapper::TABLE_ADMIN_SETTINGS, [ - 'class' => '\OC\Dummy', - 'section' => self::SECTION_PREFIX . '1', - 'priority' => 5 - ]); - - $this->assertEquals(true, $this->mapper->has(Mapper::TABLE_ADMIN_SETTINGS, '\OC\Dummy')); - - $this->assertContains('\OC\Dummy', $this->mapper->getClasses(Mapper::TABLE_ADMIN_SETTINGS)); - - $rows = $this->mapper->getAdminSettingsFromDB(self::SECTION_PREFIX . '1'); - $this->assertEquals([ - ['class' => '\OC\Dummy', 'priority' => 5] - ], $rows); - - $this->mapper->update(Mapper::TABLE_ADMIN_SETTINGS, 'class', '\OC\Dummy', [ - 'section' => self::SECTION_PREFIX . '1', 'priority' => 15 - ]); - - $rows = $this->mapper->getAdminSettingsFromDB(self::SECTION_PREFIX . '1'); - $this->assertEquals([ - ['class' => '\OC\Dummy', 'priority' => 15] - ], $rows); - - $this->mapper->update(Mapper::TABLE_ADMIN_SETTINGS, 'class', '\OC\Dummy', [ - 'section' => self::SECTION_PREFIX . '2', 'priority' => 15 - ]); - - $this->assertEquals([], $this->mapper->getAdminSettingsFromDB(self::SECTION_PREFIX . '1')); - $rows = $this->mapper->getAdminSettingsFromDB(self::SECTION_PREFIX . '2'); - $this->assertEquals([ - ['class' => '\OC\Dummy', 'priority' => 15] - ], $rows); - - $this->mapper->remove(Mapper::TABLE_ADMIN_SETTINGS, '\OC\Dummy'); - - $this->assertEquals(false, $this->mapper->has(Mapper::TABLE_ADMIN_SETTINGS, '\OC\Dummy')); - } - - public function testGetAdminSections() { - $this->assertFalse($this->mapper->has(Mapper::TABLE_ADMIN_SECTIONS, '\OC\Dummy')); - - $this->mapper->add(Mapper::TABLE_ADMIN_SECTIONS, [ - 'id' => self::SECTION_PREFIX . '1', - 'class' => '\OC\Dummy', - 'priority' => 1, - ]); - - $this->assertTrue($this->mapper->has(Mapper::TABLE_ADMIN_SECTIONS, '\OC\Dummy')); - - // until we add a setting for the section it's not returned - $this->assertNotContains([ - 'class' => '\OC\Dummy', - 'priority' => 1, - ], $this->mapper->getAdminSectionsFromDB()); - - $this->mapper->add(Mapper::TABLE_ADMIN_SETTINGS, [ - 'class' => '\OC\Dummy', - 'section' => self::SECTION_PREFIX . '1', - 'priority' => 5 - ]); - - $this->assertContains([ - 'class' => '\OC\Dummy', - 'priority' => 1, - ], $this->mapper->getAdminSectionsFromDB()); - - $this->mapper->remove(Mapper::TABLE_ADMIN_SETTINGS, '\OC\Dummy'); - - $this->assertNotContains([ - 'class' => '\OC\Dummy', - 'priority' => 1, - ], $this->mapper->getAdminSectionsFromDB()); - - $this->mapper->remove(Mapper::TABLE_ADMIN_SECTIONS, '\OC\Dummy'); - - $this->assertFalse($this->mapper->has(Mapper::TABLE_ADMIN_SECTIONS, '\OC\Dummy')); - } -} diff --git a/version.php b/version.php index 04ca2acd0a..9b735f2109 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(14, 0, 0, 0); +$OC_Version = array(14, 0, 0, 1); // The human readable string $OC_VersionString = '14.0.0 alpha';