diff --git a/appinfo/info.xml b/appinfo/info.xml index 8f696b737b..1991609a5a 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -59,6 +59,7 @@ +t OCA\Deck\Command\ArchiveOldCards OCA\Deck\Command\UserExport OCA\Deck\Command\BoardImport OCA\Deck\Command\TransferOwnership diff --git a/lib/Command/ArchiveOldCards.php b/lib/Command/ArchiveOldCards.php new file mode 100644 index 0000000000..261bef0687 --- /dev/null +++ b/lib/Command/ArchiveOldCards.php @@ -0,0 +1,96 @@ +db = $db; + } + + protected function configure(): void { + $this->setName('deck:cards:archive-old') + ->setDescription('Archive Deck cards older than a specified number of days') + ->addOption( + 'days', + 'd', + InputOption::VALUE_REQUIRED, + 'Number of days of inactivity before archiving', + 60 + ) + ->addOption( + 'dry-run', + null, + InputOption::VALUE_NONE, + 'List cards that would be archived without modifying them' + ); + } + + protected function execute(InputInterface $input, OutputInterface $output): int { + $isDryRun = (bool)$input->getOption('dry-run'); + $days = (int)$input->getOption('days'); + + if ($days <= 0) { + $output->writeln('The --days parameter must be a positive integer.'); + return Command::INVALID; + } + + $cutoffTimestamp = (new DateTime("-{$days} days"))->getTimestamp(); + + $output->writeln("Searching for active cards unchanged for at least {$days} days (before " . date('Y-m-d H:i:s', $cutoffTimestamp) . ")..."); + + $qb = $this->db->getQueryBuilder(); + $qb->select('id', 'title') + ->from('deck_cards') + ->where($qb->expr()->eq('archived', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT))) + ->andWhere($qb->expr()->lt('last_modified', $qb->createNamedParameter($cutoffTimestamp, IQueryBuilder::PARAM_INT))); + + $result = $qb->executeQuery(); + $rows = $result->fetchAll(); + $result->closeCursor(); + + $count = count($rows); + + if ($count === 0) { + $output->writeln('No cards matched the criteria.'); + return Command::SUCCESS; + } + + $now = time(); + + foreach ($rows as $row) { + $cardId = (int)$row['id']; + $cardTitle = $row['title'] ?? 'Untitled'; + + if ($isDryRun) { + $output->writeln("[Dry Run] Would archive card ID {$cardId}: {$cardTitle}"); + continue; + } + + $updateQb = $this->db->getQueryBuilder(); + $updateQb->update('deck_cards') + ->set('archived', $updateQb->createNamedParameter(1, IQueryBuilder::PARAM_INT)) + ->set('last_modified', $updateQb->createNamedParameter($now, IQueryBuilder::PARAM_INT)) + ->where($updateQb->expr()->eq('id', $updateQb->createNamedParameter($cardId, IQueryBuilder::PARAM_INT))) + ->executeStatement(); + + $output->writeln("Archived card ID {$cardId}: {$cardTitle}"); + } + + $output->writeln("Finished. Total cards processed: {$count}"); + + return Command::SUCCESS; + } +}