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

UrlBundleService::getJobsForUrls()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 27
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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