use OCP\Files\NotPermittedException;
use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\IConfig;
+use OCP\IDBConnection;
class MigrateBackgroundImages extends QueuedJob {
public const TIME_SENSITIVE = 0;
+ protected const STAGE_PREPARE = 'prepare';
+ protected const STAGE_EXECUTE = 'execute';
+
private IConfig $config;
private IAppManager $appManager;
private IAppDataFactory $appDataFactory;
private IJobList $jobList;
-
- public function __construct(ITimeFactory $time, IAppDataFactory $appDataFactory, IConfig $config, IAppManager $appManager, IJobList $jobList) {
+ private IDBConnection $dbc;
+
+ public function __construct(
+ ITimeFactory $time,
+ IAppDataFactory $appDataFactory,
+ IConfig $config,
+ IAppManager $appManager,
+ IJobList $jobList,
+ IDBConnection $dbc
+ ) {
parent::__construct($time);
$this->config = $config;
$this->appManager = $appManager;
$this->appDataFactory = $appDataFactory;
$this->jobList = $jobList;
+ $this->dbc = $dbc;
}
protected function run($argument): void {
- if (!$this->appManager->isEnabledForUser('dashboard')) {
- return;
+ if (!isset($argument['stage'])) {
+ // not executed in 25.0.0?!
+ $argument['stage'] = 'prepare';
}
- $dashboardData = $this->appDataFactory->get('dashboard');
+ switch ($argument['stage']) {
+ case self::STAGE_PREPARE:
+ $this->runPreparation();
+ break;
+ case self::STAGE_EXECUTE:
+ $this->runMigration();
+ break;
+ default:
+ break;
+ }
+ }
- $userIds = $this->config->getUsersForUserValue('theming', 'background', 'custom');
+ protected function runPreparation(): void {
+ try {
+ $selector = $this->dbc->getQueryBuilder();
+ $result = $selector->select('userid')
+ ->from('preferences')
+ ->where($selector->expr()->eq('appid', $selector->createNamedParameter('theming')))
+ ->andWhere($selector->expr()->eq('configkey', $selector->createNamedParameter('background')))
+ ->andWhere($selector->expr()->eq('configvalue', $selector->createNamedParameter('custom')))
+ ->executeQuery();
+
+ $userIds = $result->fetchAll(\PDO::FETCH_COLUMN);
+ $this->storeUserIdsToProcess($userIds);
+ } catch (\Throwable $t) {
+ $this->jobList->add(self::class, self::STAGE_PREPARE);
+ throw $t;
+ }
+ $this->jobList->add(self::class, self::STAGE_EXECUTE);
+ }
- $notSoFastMode = \count($userIds) > 5000;
- $reTrigger = false;
- $processed = 0;
+ protected function runMigration(): void {
+ $storedUserIds = $this->config->getAppValue('theming', '25_background_image_migration');
+ if ($storedUserIds === '') {
+ return;
+ }
+ $allUserIds = \json_decode(\gzuncompress($storedUserIds), true);
+ $notSoFastMode = isset($allUserIds[5000]);
+ $dashboardData = $this->appDataFactory->get('dashboard');
+ $userIds = $notSoFastMode ? array_slice($allUserIds, 0, 5000) : $allUserIds;
foreach ($userIds as $userId) {
try {
// precondition
- if ($notSoFastMode) {
- if ($this->config->getUserValue($userId, 'theming', 'background-migrated', '0') === '1') {
- // already migrated
- continue;
- }
- $reTrigger = true;
+ if (!$this->appManager->isEnabledForUser('dashboard', $userId)) {
+ continue;
}
// migration
$file->delete();
} catch (NotFoundException|NotPermittedException $e) {
}
- // capture state
- if ($notSoFastMode) {
- $this->config->setUserValue($userId, 'theming', 'background-migrated', '1');
- $processed++;
- }
- if ($processed > 4999) {
- break;
- }
}
- if ($reTrigger) {
- $this->jobList->add(self::class);
+ if ($notSoFastMode) {
+ $remainingUserIds = array_slice($allUserIds, 5000);
+ $this->storeUserIdsToProcess($remainingUserIds);
+ $this->jobList->add(self::class, ['stage' => self::STAGE_EXECUTE]);
+ } else {
+ $this->config->deleteAppValue('theming', '25_background_image_migration');
}
}
+ protected function storeUserIdsToProcess(array $userIds): void {
+ $storableUserIds = \gzcompress(\json_encode($userIds), 9);
+ $this->config->setAppValue('theming', '25_background_image_migration', $storableUserIds);
+ }
+
/**
* Get the root location for users theming data
*/