RemoveBrokenProperties.php 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OC\Repair;
  8. use OCP\DB\QueryBuilder\IQueryBuilder;
  9. use OCP\IDBConnection;
  10. use OCP\Migration\IOutput;
  11. use OCP\Migration\IRepairStep;
  12. class RemoveBrokenProperties implements IRepairStep {
  13. /**
  14. * RemoveBrokenProperties constructor.
  15. *
  16. * @param IDBConnection $db
  17. */
  18. public function __construct(
  19. private IDBConnection $db,
  20. ) {
  21. }
  22. /**
  23. * @inheritdoc
  24. */
  25. public function getName() {
  26. return 'Remove broken DAV object properties';
  27. }
  28. /**
  29. * @inheritdoc
  30. */
  31. public function run(IOutput $output) {
  32. // retrieve all object properties
  33. $qb = $this->db->getQueryBuilder();
  34. $qb->select('id', 'propertyvalue')
  35. ->from('properties')
  36. ->where($qb->expr()->eq('valuetype', $qb->createNamedParameter('3', IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT));
  37. $result = $qb->executeQuery();
  38. // find broken object properties
  39. $brokenIds = [];
  40. while ($entry = $result->fetch()) {
  41. if (!empty($entry['propertyvalue'])) {
  42. $object = @unserialize(str_replace('\x00', chr(0), $entry['propertyvalue']));
  43. if ($object === false) {
  44. $brokenIds[] = $entry['id'];
  45. }
  46. } else {
  47. $brokenIds[] = $entry['id'];
  48. }
  49. }
  50. $result->closeCursor();
  51. // delete broken object properties
  52. $qb = $this->db->getQueryBuilder();
  53. $qb->delete('properties')
  54. ->where($qb->expr()->in('id', $qb->createParameter('ids'), IQueryBuilder::PARAM_STR_ARRAY));
  55. foreach (array_chunk($brokenIds, 1000) as $chunkIds) {
  56. $qb->setParameter('ids', $chunkIds, IQueryBuilder::PARAM_STR_ARRAY);
  57. $qb->executeStatement();
  58. }
  59. $total = count($brokenIds);
  60. $output->info("$total broken object properties removed");
  61. }
  62. }