Passed
Pull Request — master (#133)
by
unknown
02:02
created

SiteTreePublishingEngine::setQueueService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\StaticPublishQueue\Extension\Engine;
4
5
use SilverStripe\CMS\Model\SiteTreeExtension;
6
use SilverStripe\Core\Environment;
7
use SilverStripe\Core\Injector\Injector;
8
use SilverStripe\Core\Resettable;
9
use SilverStripe\StaticPublishQueue\Contract\StaticPublishingTrigger;
10
use SilverStripe\StaticPublishQueue\Extension\Publishable\PublishableSiteTree;
11
use SilverStripe\StaticPublishQueue\Job\DeleteStaticCacheJob;
12
use SilverStripe\StaticPublishQueue\Job\GenerateStaticCacheJob;
13
use Symbiote\QueuedJobs\Services\QueuedJobService;
14
15
/**
16
 * This extension couples to the StaticallyPublishable and StaticPublishingTrigger implementations
17
 * on the SiteTree objects and makes sure the actual change to SiteTree is triggered/enqueued.
18
 *
19
 * Provides the following information as a context to StaticPublishingTrigger:
20
 * * action - name of the executed action: publish or unpublish
21
 *
22
 * @see PublishableSiteTree
23
 */
24
class SiteTreePublishingEngine extends SiteTreeExtension implements Resettable
25
{
26
    /**
27
     * Queued job service injection property
28
     * used for unit tests only
29
     *
30
     * @var QueuedJobService|null
31
     */
32
    protected static $queueService = null;
33
34
    /**
35
     * Queues the urls to be flushed into the queue.
36
     *
37
     * @var array
38
     */
39
    private $toUpdate = [];
40
41
    /**
42
     * Queues the urls to be deleted as part of a next flush operation.
43
     *
44
     * @var array
45
     */
46
    private $toDelete = [];
47
48
    public static function reset(): void
49
    {
50
        static::$queueService = null;
51
    }
52
53
    /**
54
     * @param QueuedJobService $service
55
     */
56
    public static function setQueueService(QueuedJobService $service): void
57
    {
58
        static::$queueService = $service;
59
    }
60
61
    /**
62
     * @return array
63
     */
64
    public function getToUpdate()
65
    {
66
        return $this->toUpdate;
67
    }
68
69
    /**
70
     * @return array
71
     */
72
    public function getToDelete()
73
    {
74
        return $this->toDelete;
75
    }
76
77
    /**
78
     * @param array $toUpdate
79
     * @return $this
80
     */
81
    public function setToUpdate($toUpdate)
82
    {
83
        $this->toUpdate = $toUpdate;
84
        return $this;
85
    }
86
87
    /**
88
     * @param array $toDelete
89
     * @return $this
90
     */
91
    public function setToDelete($toDelete)
92
    {
93
        $this->toDelete = $toDelete;
94
        return $this;
95
    }
96
97
    /**
98
     * @param \SilverStripe\CMS\Model\SiteTree|null $original
99
     */
100
    public function onAfterPublishRecursive(&$original)
101
    {
102
        // if the site tree has been "reorganised" (ie: the parentID has changed)
103
        // then this is eht equivalent of an unpublish and publish as far as the
104
        // static publisher is concerned
105
        if ($original && (
106
                $original->ParentID !== $this->getOwner()->ParentID
107
                || $original->URLSegment !== $this->getOwner()->URLSegment
108
            )
109
        ) {
110
            $context = [
111
                'action' => 'unpublish',
112
            ];
113
            $original->collectChanges($context);
114
            $original->flushChanges();
115
        }
116
        $context = [
117
            'action' => 'publish',
118
        ];
119
        $this->collectChanges($context);
120
        $this->flushChanges();
121
    }
122
123
    public function onBeforeUnpublish()
124
    {
125
        $context = [
126
            'action' => 'unpublish',
127
        ];
128
        $this->collectChanges($context);
129
    }
130
131
    public function onAfterUnpublish()
132
    {
133
        $this->flushChanges();
134
    }
135
136
    /**
137
     * Collect all changes for the given context.
138
     *
139
     * @param array $context
140
     */
141
    public function collectChanges($context)
142
    {
143
        Environment::increaseMemoryLimitTo();
144
        Environment::increaseTimeLimitTo();
145
146
        if ($this->getOwner()->hasExtension(PublishableSiteTree::class)
147
            || $this->getOwner() instanceof StaticPublishingTrigger
148
        ) {
149
            $toUpdate = $this->getOwner()->objectsToUpdate($context);
150
            $this->setToUpdate($toUpdate);
151
152
            $toDelete = $this->getOwner()->objectsToDelete($context);
153
            $this->setToDelete($toDelete);
154
        }
155
    }
156
157
    /**
158
     * Execute URL deletions, enqueue URL updates.
159
     */
160
    public function flushChanges()
161
    {
162
        $queue = static::$queueService ?? QueuedJobService::singleton();
163
164
        if (!empty($this->toUpdate)) {
165
            foreach ($this->toUpdate as $queueItem) {
166
                $job = Injector::inst()->create(GenerateStaticCacheJob::class);
167
168
                $jobData = new \stdClass();
169
                $urls = $queueItem->urlsToCache();
170
                ksort($urls);
171
                $jobData->URLsToProcess = $urls;
172
173
                $job->setJobData(0, 0, false, $jobData, [
174
                    'Building URLs: ' . var_export(array_keys($jobData->URLsToProcess), true),
175
                ]);
176
177
                $queue->queueJob($job);
178
            }
179
            $this->toUpdate = [];
180
        }
181
182
        if (!empty($this->toDelete)) {
183
            foreach ($this->toDelete as $queueItem) {
184
                $job = Injector::inst()->create(DeleteStaticCacheJob::class);
185
186
                $jobData = new \stdClass();
187
                $urls = $queueItem->urlsToCache();
188
                ksort($urls);
189
                $jobData->URLsToProcess = $urls;
190
191
                $job->setJobData(0, 0, false, $jobData, [
192
                    'Purging URLs: ' . var_export(array_keys($jobData->URLsToProcess), true),
193
                ]);
194
195
                $queue->queueJob($job);
196
            }
197
            $this->toDelete = [];
198
        }
199
    }
200
}
201