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

UrlBundleService::formatUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 6
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace SilverStripe\StaticPublishQueue\Service;
4
5
use SilverStripe\Core\Extensible;
6
use SilverStripe\Core\Injector\Injectable;
7
use SilverStripe\Core\Injector\Injector;
8
use SilverStripe\Core\Resettable;
9
use SilverStripe\ORM\DataObject;
10
use SilverStripe\ORM\ValidationException;
11
use SilverStripe\StaticPublishQueue\Job;
12
use Symbiote\QueuedJobs\Services\QueuedJobService;
13
14
/**
15
 * Class UrlBundleService
16
 *
17
 * This service is responsible for bundling URLs which to static cache jobs
18
 * Several extension points are available to allow further customisation
19
 */
20
class UrlBundleService implements Resettable
21
{
22
    use Extensible;
23
    use Injectable;
24
25
    /**
26
     * @var array
27
     */
28
    protected $urls = [];
29
30
    /**
31
     * Add URLs to this bundle
32
     *
33
     * @param array $urls
34
     * @return $this
35
     */
36
    public function addUrls(array $urls): self
37
    {
38
        foreach ($urls as $url) {
39
            $this->urls[$url] = $url;
40
        }
41
42
        return $this;
43
    }
44
45
    /**
46
     * Package URLs into jobs
47
     *
48
     * @param string $jobClass
49
     * @param string|null $message
50
     * @param DataObject|null $contextModel
51
     * @throws ValidationException
52
     */
53
    public function queueJobsForUrls(string $jobClass, ?string $message = null, ?DataObject $contextModel = null): void
54
    {
55
        $singleton = singleton($jobClass);
56
57
        if (!$singleton instanceof Job) {
58
            return;
59
        }
60
61
        $service = QueuedJobService::singleton();
62
        $urls = $this->getUrls();
63
        $urlsPerJob = $singleton->getUrlsPerJob();
64
        $batches = $urlsPerJob > 0 ? array_chunk($urls, $urlsPerJob) : [$urls];
65
66
        foreach ($batches as $urlBatch) {
67
            $priorityUrls = $this->assignPriorityToUrls($urlBatch);
68
69
            /** @var Job $job */
70
            $job = Injector::inst()->create($jobClass);
71
            $job->hydrate($priorityUrls, $message);
72
73
            // Use this extension point to inject some additional data into the job
74
            $this->extend('updateHydratedJob', $job, $contextModel);
75
76
            $service->queueJob($job);
77
        }
78
    }
79
80
    /**
81
     * Flush in-memory data
82
     */
83
    public function flushData(): void
84
    {
85
        $this->urls = [];
86
    }
87
88
    public static function reset()
89
    {
90
        self::singleton()->flushData();
91
    }
92
93
    /**
94
     * Get URLs for further processing
95
     *
96
     * @return array
97
     */
98
    protected function getUrls(): array
99
    {
100
        $urls = [];
101
102
        foreach ($this->urls as $url) {
103
            $url = $this->formatUrl($url);
104
105
            if (!$url) {
106
                continue;
107
            }
108
109
            $urls[] = $url;
110
        }
111
112
        $urls = array_unique($urls);
113
114
        // Use this extension point to change the order of the URLs if needed
115
        $this->extend('updateGetUrls', $urls);
116
117
        return $urls;
118
    }
119
120
    /**
121
     * Extensibility function which allows to handle custom formatting / encoding needs for URLs
122
     * Returning "falsy" value will make the URL to be skipped
123
     *
124
     * @param string $url
125
     * @return string|null
126
     */
127
    protected function formatUrl(string $url): ?string
128
    {
129
        // Use this extension point to reformat URLs, for example encode special characters
130
        $this->extend('updateFormatUrl', $url);
131
132
        return $url;
133
    }
134
135
    /**
136
     * Add priority data to URLs
137
     *
138
     * @param array $urls
139
     * @return array
140
     */
141
    protected function assignPriorityToUrls(array $urls): array
142
    {
143
        $priority = 0;
144
        $priorityUrls = [];
145
146
        foreach ($urls as $url) {
147
            $priorityUrls[$url] = $priority;
148
            $priority += 1;
149
        }
150
151
        return $priorityUrls;
152
    }
153
}
154