Passed
Push — sheepy/introspection ( 000d40...b6b869 )
by Marco
02:43
created

SolrIndexJob::process()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 31
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 3

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 18
c 4
b 0
f 0
dl 0
loc 31
ccs 18
cts 18
cp 1
rs 9.6666
cc 3
nc 2
nop 0
crap 3
1
<?php
2
3
4
namespace Firesphere\SolrSearch\Jobs;
5
6
use Exception;
7
use Firesphere\SolrSearch\Indexes\BaseIndex;
8
use Firesphere\SolrSearch\Services\SolrCoreService;
9
use Firesphere\SolrSearch\Tasks\SolrIndexTask;
10
use ReflectionException;
11
use SilverStripe\Control\HTTPRequest;
12
use SilverStripe\Core\Injector\Injector;
13
use stdClass;
14
use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
15
use Symbiote\QueuedJobs\Services\QueuedJobService;
16
17
/**
18
 * Class SolrIndexJob
19
 * @package Firesphere\SolrSearch\Jobs
20
 */
21
class SolrIndexJob extends AbstractQueuedJob
22
{
23
24
    /**
25
     * The class that should be indexed.
26
     * If set, the task should run the given class with the given group
27
     * The class should be popped off the array at the end of each subset
28
     * so the next class becomes the class to index.
29
     *
30
     * Rinse and repeat for each class in the index, until this array is empty
31
     *
32
     * @var array
33
     */
34
    protected $classToIndex = [];
35
36
    /**
37
     * The indexes that need to run.
38
     * @var array
39
     */
40
    protected $indexes;
41
42
    /**
43
     * SolrIndexJob constructor.
44
     * @param array $params
45
     */
46 3
    public function __construct($params = [])
47
    {
48 3
        parent::__construct($params);
49
        // Make sure indexes are set on first run, but not again after that :)
50 3
    }
51
52
    /**
53
     * @return string
54
     */
55 2
    public function getTitle()
56
    {
57 2
        return 'Index groups to Solr search';
58
    }
59
60
    /**
61
     * Do some processing yourself!
62
     * @return self
63
     * @throws Exception
64
     */
65 1
    public function process()
66
    {
67 1
        $data = $this->jobData;
68
69 1
        $this->configureRun($data);
70
71 1
        $this->currentStep = $this->currentStep ?: 0;
72 1
        $index = Injector::inst()->get($this->indexes[0]);
73 1
        $this->classToIndex = count($this->classToIndex) ? $this->classToIndex : $index->getClasses();
74
        $indexArgs = [
75 1
            'group' => $this->currentStep,
76 1
            'index' => $this->indexes[0],
77 1
            'class' => $this->classToIndex[0]
78
        ];
79
        /** @var BaseIndex $index */
80
        /** @var SolrIndexTask $task */
81 1
        $task = Injector::inst()->get(SolrIndexTask::class);
82 1
        $request = new HTTPRequest(
83 1
            'GET',
84 1
            '/dev/tasks/SolrIndexTask',
85 1
            $indexArgs
86
        );
87
88 1
        $result = $task->run($request);
89 1
        $this->totalSteps = $result;
90
        // If the result is false, the job should fail too
91
        // Thus, only set to true if the result isn't false :)
92 1
        $this->isComplete = true;
93
94
        /** @var self $this */
95 1
        return $this;
96
    }
97
98
    /**
99
     * @param stdClass|null $data
100
     * @throws ReflectionException
101
     */
102 1
    protected function configureRun($data)
103
    {
104
        // If null gets passed in, it goes a bit wonky with the check for indexes
105 1
        if (!$data) {
106 1
            $data = new stdClass();
107 1
            $data->indexes = null;
108
        }
109 1
        if (!isset($data->indexes) || !count($data->indexes)) { // If indexes are set, don't load them.
110 1
            $this->indexes = (new SolrCoreService())->getValidIndexes();
111
        } else {
112 1
            $this->setIndexes($data->indexes);
113 1
            $this->setClassToIndex($data->classToIndex);
114
        }
115 1
    }
116
117
    /**
118
     * Set up the next job if needed
119
     */
120 1
    public function afterComplete()
121
    {
122 1
        [$currentStep, $totalSteps] = $this->getNextSteps();
123
        // If there are no indexes left to run, let's call it a day
124 1
        if (count($this->indexes)) {
125 1
            $nextJob = new self();
126 1
            $jobData = new stdClass();
127
128 1
            $jobData->classToIndex = $this->getClassToIndex();
129 1
            $jobData->indexes = $this->getIndexes();
130 1
            $nextJob->setJobData($totalSteps, $currentStep, false, $jobData, []);
131
132
            // Add a wee break to let the system recover from this heavy operation
133 1
            Injector::inst()->get(QueuedJobService::class)
134 1
                ->queueJob($nextJob, date('Y-m-d H:i:00', strtotime('+1 minutes')));
135
        }
136 1
        parent::afterComplete();
137 1
    }
138
139
    /**
140
     * @return array
141
     */
142 3
    public function getClassToIndex(): array
143
    {
144 3
        return $this->classToIndex;
145
    }
146
147
    /**
148
     * @param array $classToIndex
149
     * @return SolrIndexJob
150
     */
151 3
    public function setClassToIndex($classToIndex)
152
    {
153 3
        $this->classToIndex = $classToIndex;
154
155 3
        return $this;
156
    }
157
158
    /**
159
     * @return array
160
     */
161 3
    public function getIndexes(): array
162
    {
163 3
        return $this->indexes;
164
    }
165
166
    /**
167
     * @param array $indexes
168
     * @return SolrIndexJob
169
     */
170 3
    public function setIndexes($indexes)
171
    {
172 3
        $this->indexes = $indexes;
173
174 3
        return $this;
175
    }
176
177
    /**
178
     * @return array
179
     */
180 1
    protected function getNextSteps(): array
181
    {
182 1
        $currentStep = $this->currentStep + 1;
183 1
        $totalSteps = $this->totalSteps;
184
        // No more steps to execute on this class, let's go to the next class
185 1
        if ($this->currentStep >= $this->totalSteps) {
186 1
            array_shift($this->classToIndex);
187
            // Reset the current step, a complete new set of data is coming
188 1
            $currentStep = 0;
189 1
            $totalSteps = 1;
190
        }
191
        // If there are no classes left in this index, go to the next index
192 1
        if (!count($this->classToIndex)) {
193 1
            array_shift($this->indexes);
194
            // Reset the current step, a complete new set of data is coming
195 1
            $currentStep = 0;
196 1
            $totalSteps = 1;
197
        }
198
199 1
        return [$currentStep, $totalSteps];
200
    }
201
}
202