Passed
Push — master ( aef744...57a6a5 )
by Nicolaas
02:03
created

PruneAllVersionedRecords::run()   B

Complexity

Conditions 6
Paths 20

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
cc 6
eloc 20
c 7
b 0
f 0
nc 20
nop 1
dl 0
loc 32
rs 8.9777
1
<?php
2
3
namespace Sunnysideup\VersionPruner\Api;
4
5
use SilverStripe\Core\ClassInfo;
6
use SilverStripe\Core\Config\Config;
7
use SilverStripe\Dev\BuildTask;
8
use SilverStripe\ORM\DataList;
9
use SilverStripe\ORM\DataObject;
10
use SilverStripe\ORM\DB;
11
use SilverStripe\Versioned\Versioned;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Versioned\Versioned was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
13
class PruneAllVersionedRecords extends BuildTask
14
{
15
    /**
16
     * @var int
17
     */
18
    protected const MAX_ITEMS_PER_CLASS = 500;
19
20
    /**
21
     * @var string
22
     */
23
    protected $title = 'Prune all versioned records';
24
25
    protected $description = 'Go through all dataobjects that are versioned and prune them as per schema provided.';
26
    protected $limit = self::MAX_ITEMS_PER_CLASS;
27
28
    protected $verbose = false;
29
30
    protected $dryRun = false;
31
32
    /**
33
     * @var string
34
     */
35
    private static $segment = 'prune-all-versioned-records';
36
37
    /**
38
     * Prune all published DataObjects which are published according to config.
39
     *
40
     * @param mixed $request
41
     */
42
    public function run($request)
43
    {
44
        $classes = $this->getAllVersionedDataClasses();
45
        if($request->requestVar('verbose')) {
46
            $this->verbose = $request->requestVar('verbose');
47
        }
48
        if($request->requestVar('dry')) {
49
            $this->dryRun = $request->requestVar('dry');
50
        }
51
        DB::alteration_message('Pruning all DataObjects with a maximum of ' . self::MAX_ITEMS_PER_CLASS . ' per class.');
52
        $totalTotalDeleted = 0;
53
        $runObject = RunForOneObject::inst()
54
            ->setVerbose($this->verbose)
55
            ->setDryRun($this->dryRun);
56
        foreach ($classes as $className) {
57
            DB::alteration_message('... Looking at ' . $className);
58
            $objects = $this->getObjectsPerClassName($className);
59
            $totalDeleted = 0;
60
61
            foreach ($objects as $object) {
62
                // check if stages are present
63
                // DB::alteration_message('... ... Checking #ID: ' . $object->ID);
64
                $totalDeleted += $runObject->deleteSuperfluousVersions($object, false);
65
            }
66
67
            if ($totalDeleted > 0) {
68
                DB::alteration_message('... ... Deleted ' . $totalDeleted . ' records');
69
                $totalTotalDeleted += $totalDeleted;
70
            }
71
        }
72
73
        DB::alteration_message('Completed, pruned ' . $totalTotalDeleted . ' records');
74
    }
75
76
    protected function getObjectsPerClassName(string $className): DataList
77
    {
78
        return Versioned::get_by_stage($className, Versioned::DRAFT)
79
            ->sort(DB::get_conn()->random() . ' ASC')
80
            ->limit(self::MAX_ITEMS_PER_CLASS)
81
        ;
82
    }
83
84
    /**
85
     * Get all versioned database classes.
86
     */
87
    private function getAllVersionedDataClasses(): array
88
    {
89
        $allClasses = ClassInfo::subclassesFor(DataObject::class);
90
        $versionedClasses = [];
91
        foreach ($allClasses as $className) {
92
            if (DataObject::has_extension($className, Versioned::class)) {
93
                $ancestors = ClassInfo::ancestry($className);
94
                foreach ($ancestors as $classNameInner) {
95
                    if (DataObject::has_extension($classNameInner, Versioned::class)) {
96
                        $versionedClasses[$classNameInner] = $classNameInner;
97
98
                        continue 2;
99
                    }
100
                }
101
102
                $versionedClasses[$className] = $className;
103
            }
104
        }
105
106
        return $versionedClasses;
107
    }
108
}
109