Passed
Push — master ( 79004c...22fd84 )
by Nicolaas
02:17
created

PruneAllVersionedRecords::setDryRun()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 5
rs 10
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
27
    protected $limit = self::MAX_ITEMS_PER_CLASS;
28
29
    protected $verbose = false;
30
31
    protected $dryRun = false;
32
33
    /**
34
     * @var string
35
     */
36
    private static $segment = 'prune-all-versioned-records';
37
38
    public function setVerbose(?bool $verbose = true): self
39
    {
40
        $this->verbose = $verbose;
41
42
        return $this;
43
    }
44
45
    public function setDryRun(?bool $dryRun = true): self
46
    {
47
        $this->dryRun = $dryRun;
48
49
        return $this;
50
    }
51
52
    public function setLimit(int $limit): self
53
    {
54
        $this->limit = $limit;
55
56
        return $this;
57
    }
58
59
60
    /**
61
     * Prune all published DataObjects which are published according to config.
62
     *
63
     * @param mixed $request
64
     */
65
    public function run($request)
66
    {
67
        $classes = $this->getAllVersionedDataClasses();
68
        if ($request && $request->requestVar('verbose')) {
69
            $this->verbose = $request->requestVar('verbose');
70
        }
71
        if ($request && $request->requestVar('dry')) {
72
            $this->dryRun = $request->requestVar('dry');
73
        }
74
        if ($request && $request->requestVar('limit')) {
75
            $this->limit = $request->requestVar('limit');
76
        }
77
        DB::alteration_message('Pruning all DataObjects with a maximum of ' . self::MAX_ITEMS_PER_CLASS . ' per class.');
78
        $totalTotalDeleted = 0;
79
        $runObject = RunForOneObject::inst()
80
            ->setVerbose($this->verbose)
81
            ->setDryRun($this->dryRun)
82
        ;
83
        DB::alteration_message('settings (set as parameters)');
84
        DB::alteration_message('-------------------- ');
85
        DB::alteration_message('verbose: ' . ($this->verbose ? 'yes' : 'no'), 'created');
86
        DB::alteration_message('dry run: ' . ($this->dryRun ? 'yes' : 'no'), 'created');
87
        DB::alteration_message('limit per class: ' . $this->limit, 'created');
88
        DB::alteration_message('-------------------- ');
89
        foreach ($classes as $className) {
90
            DB::alteration_message('... Looking at ' . $className);
91
            $objects = $this->getObjectsPerClassName($className);
92
            $totalDeleted = 0;
93
94
            foreach ($objects as $object) {
95
                // check if stages are present
96
                // DB::alteration_message('... ... Checking #ID: ' . $object->ID);
97
                $totalDeleted += $runObject->deleteSuperfluousVersions($object, false);
98
            }
99
100
            if ($totalDeleted > 0) {
101
                DB::alteration_message('... ... Deleted ' . $totalDeleted . ' records');
102
                $totalTotalDeleted += $totalDeleted;
103
            }
104
        }
105
106
        DB::alteration_message('Completed, pruned ' . $totalTotalDeleted . ' records');
107
        $array = $runObject->getCountRegister();
108
        foreach ($array as $table => $count) {
109
            DB::alteration_message($table . ' has ' . $count . ' records left.');
110
        }
111
    }
112
113
    protected function getObjectsPerClassName(string $className): DataList
114
    {
115
        return Versioned::get_by_stage($className, Versioned::DRAFT)
116
            ->sort(DB::get_conn()->random() . ' ASC')
117
            ->limit($this->limit)
118
        ;
119
    }
120
121
    /**
122
     * Get all versioned database classes.
123
     */
124
    protected function getAllVersionedDataClasses(): array
125
    {
126
        $allClasses = ClassInfo::subclassesFor(DataObject::class);
127
        $versionedClasses = [];
128
        foreach ($allClasses as $className) {
129
            if (DataObject::has_extension($className, Versioned::class)) {
130
                $ancestors = ClassInfo::ancestry($className);
131
                foreach ($ancestors as $classNameInner) {
132
                    if (DataObject::has_extension($classNameInner, Versioned::class)) {
133
                        $versionedClasses[$classNameInner] = $classNameInner;
134
135
                        continue 2;
136
                    }
137
                }
138
139
                $versionedClasses[$className] = $className;
140
            }
141
        }
142
143
        return $versionedClasses;
144
    }
145
}
146