SiteTreeVersioningTemplate   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 50
c 1
b 0
f 0
dl 0
loc 117
rs 10
wmc 12

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getTitle() 0 3 1
A setKeepVersions() 0 5 1
A getDescription() 0 3 1
A run() 0 4 1
A getItemsToKeep() 0 18 1
A markSuperfluousOnesWithDifferentKeyValues() 0 39 5
A markOlderItemsWithTheSameKeyValues() 0 18 2
1
<?php
2
3
namespace Sunnysideup\VersionPruner\PruningTemplates;
4
5
use Sunnysideup\VersionPruner\PruningTemplatesTemplate;
6
7
class SiteTreeVersioningTemplate extends PruningTemplatesTemplate
8
{
9
    protected $keepVersions = 30;
10
11
    protected $fieldsWithChangesToKeep = [
12
        'URLSegment',
13
        'ParentID',
14
    ];
15
16
    public function setKeepVersions(int $keepVersions): self
17
    {
18
        $this->keepVersions = $keepVersions;
19
20
        return $this;
21
    }
22
23
    public function getTitle(): string
24
    {
25
        return 'SiteTree specific version pruning';
26
    }
27
28
    public function getDescription(): string
29
    {
30
        return 'Delete versions that are older and do not include any changes in ParentID or URLSegment.';
31
    }
32
33
    public function run(?bool $verbose = false)
34
    {
35
        $this->markOlderItemsWithTheSameKeyValues();
36
        $this->markSuperfluousOnesWithDifferentKeyValues();
37
    }
38
39
    /**
40
     * these can be deleted.
41
     */
42
    protected function markOlderItemsWithTheSameKeyValues()
43
    {
44
        $filter = [
45
            '"WasPublished" = ?' => 1,
46
        ];
47
48
        foreach ($this->fieldsWithChangesToKeep as $field) {
49
            $filter['"' . $field . '" = ?'] = $this->object->{$field};
50
        }
51
52
        $query = $this->getBaseQuery($this->fieldsWithChangesToKeep + ['WasPublished'])
53
            ->addWhere($this->normaliseWhere($filter))
54
            ->setLimit($this->normaliseLimit(), $this->normaliseOffset($this->keepVersions))
55
        ;
56
57
        $this->toDelete[$this->getUniqueKey()] += $this->addVersionNumberToArray(
58
            $this->toDelete[$this->getUniqueKey()],
59
            $query->execute()
60
        );
61
    }
62
63
    protected function markSuperfluousOnesWithDifferentKeyValues()
64
    {
65
        $toKeep = $this->getItemsToKeep();
66
        $orFilterKey = '"' . implode('" != ? OR "', $this->fieldsWithChangesToKeep) . '" != ?';
67
        $orFilterValuesArray = [];
68
        foreach ($this->fieldsWithChangesToKeep as $field) {
69
            $orFilterValuesArray[] = $this->object->{$field};
70
        }
71
72
        $results = $this->getBaseQuery($this->fieldsWithChangesToKeep + ['WasPublished'])
73
            ->addWhere(
74
                [
75
                    '"RecordID" = ?' => $this->object->ID,
76
                    '"WasPublished" = ?' => 1,
77
                    '"Version" NOT IN (' . implode(',', ($toKeep + [-1 => 0])) . ')',
78
                    $orFilterKey => $orFilterValuesArray,
79
                ]
80
            )
81
            ->execute()
82
        ;
83
84
        $changedRecords = [];
85
86
        // create a `ParentID - $URLSegment` array to keep only a single
87
        // version of each for URL redirection
88
        foreach ($results as $result) {
89
            $keyArray = [];
90
            foreach ($this->fieldsWithChangesToKeep as $field) {
91
                $keyArray[] = $result[$field];
92
            }
93
94
            $key = implode('_', $keyArray);
95
96
            if (! (in_array($key, $changedRecords, true))) {
97
                //mark the first one, but do not mark it to delete
98
                $changedRecords[] = $key;
99
            } else {
100
                // the first one has been done, so we can delete others...
101
                $this->toDelete[$this->getUniqueKey()][$result['Version']] = $result['Version'];
102
            }
103
        }
104
    }
105
106
    protected function getItemsToKeep(): array
107
    {
108
        // Get the most recent Version IDs of all published pages to ensure
109
        // we leave at least X versions even if a URLSegment or ParentID
110
        // has changed.
111
        $query = $this->getBaseQuery(['WasPublished'])
112
            ->addWhere(
113
                [
114
                    '"RecordID" = ?' => $this->object->ID,
115
                    '"WasPublished" = ?' => 1,
116
                ]
117
            )
118
            ->setLimit($this->keepVersions, 0)
119
        ;
120
121
        return $this->addVersionNumberToArray(
122
            [],
123
            $query->execute()
124
        );
125
    }
126
}
127