Passed
Push — master ( c92847...6eec4e )
by Nicolaas
08:25
created

PruneAllVersionedRecords::setLimit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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