Passed
Pull Request — master (#213)
by Simon
06:50 queued 04:29
created

ClearDirtyClassesTask::getDirtyClasses()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.0218

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 14
ccs 8
cts 9
cp 0.8889
crap 4.0218
rs 10
1
<?php
2
/**
3
 * Class ClearDirtyClasses|Firesphere\SolrSearch\Tasks\ClearDirtyClasses Clear out classes that were not
4
 * succesfully updated or deleted in Solr.
5
 *
6
 * Any classes that failed to index properly or be removed properly need to be cleaned out regularly
7
 * This task takes care of doing this. It can be run directly via /dev/tasks, or via a queued job
8
 *
9
 * @package Firesphere\SolrSearch\Tasks
10
 * @author Simon `Firesphere` Erkelens; Marco `Sheepy` Hermo
11
 * @copyright Copyright (c) 2018 - now() Firesphere & Sheepy
12
 */
13
14
namespace Firesphere\SolrSearch\Tasks;
15
16
use Exception;
17
use Firesphere\SolrSearch\Helpers\SolrLogger;
18
use Firesphere\SolrSearch\Models\DirtyClass;
19
use Firesphere\SolrSearch\Services\SolrCoreService;
20
use Firesphere\SolrSearch\Traits\LoggerTrait;
21
use GuzzleHttp\Exception\GuzzleException;
22
use ReflectionException;
23
use SilverStripe\Control\HTTPRequest;
24
use SilverStripe\Dev\BuildTask;
25
use SilverStripe\ORM\ArrayList;
26
use SilverStripe\ORM\DataList;
27
use SilverStripe\ORM\ValidationException;
28
29
/**
30
 * Class ClearDirtyClasses Clear out classes that were not succesfully updated or deleted in Solr.
31
 *
32
 * Any classes that failed to index properly or be removed properly need to be cleaned out regularly
33
 * This task takes care of doing this. It can be run directly via /dev/tasks, or via a queued job
34
 *
35
 * @package Firesphere\SolrSearch\Tasks
36
 */
37
class ClearDirtyClassesTask extends BuildTask
38
{
39
    use LoggerTrait;
40
    /**
41
     * @var string URLSegment
42
     */
43
    private static $segment = 'SolrClearDirtyClasses';
44
    /**
45
     * @var string Title
46
     */
47
    protected $title = 'Fix broken items in the Solr cores';
48
    /**
49
     * @var string Description
50
     */
51
    protected $description = 'Clear out classes that are marked as dirty on Solr.';
52
53
    /**
54
     * Clean up Dirty Classes in the index
55
     *
56
     * When there are dirty classes to update or delete, the run will attempt to clean up.
57
     * Dirty classes happen when changes to classes are not successfully updated in Solr
58
     *
59
     * @param HTTPRequest $request
60
     * @return void
61
     * @throws GuzzleException
62
     * @throws ReflectionException
63
     * @throws ValidationException
64
     */
65 2
    public function run($request)
66
    {
67
        /** @var DataList|DirtyClass $dirtyObjectList */
68 2
        $dirtyObjectList = DirtyClass::get();
69
        /** @var SolrCoreService $service */
70 2
        $service = new SolrCoreService();
71 2
        foreach ($dirtyObjectList as $dirtyObject) {
72 2
            $dirtyClasses = $this->getDirtyClasses($dirtyObject);
73 2
            if (!$dirtyClasses->count()) {
74 2
                continue;
75
            }
76
            try {
77 2
                $service->updateItems($dirtyClasses, $dirtyObject->Type);
78 2
                $dirtyObject->delete();
79
            } catch (Exception $exception) {
80
                // @codeCoverageIgnoreStart
81
                $this->getLogger()->error($exception->getMessage());
82
                continue;
83
                // @codeCoverageIgnoreEnd
84
            }
85
        }
86
        /** @var SolrLogger $solrLogger */
87 2
        $solrLogger = new SolrLogger();
88 2
        $solrLogger->saveSolrLog('Index');
89 2
    }
90
91
    /**
92
     * Get the objects that need to be deleted or updated as a list
93
     *
94
     * @param DirtyClass $dirtyObject
95
     * @return ArrayList|DataList
96
     */
97 2
    private function getDirtyClasses($dirtyObject)
98
    {
99
        /** @var string $dirtyClass */
100 2
        $dirtyClass = $dirtyObject->Class;
101 2
        $ids = json_decode($dirtyObject->IDs, true);
102 2
        $dirtyClasses = ArrayList::create();
103 2
        if ($dirtyObject->Type === SolrCoreService::UPDATE_TYPE && count($ids)) {
104 2
            return $dirtyClass::get()->byIDs($ids);
105
        }
106 2
        if ($dirtyObject->Type === SolrCoreService::DELETE_TYPE) {
107 2
            return $this->createDeleteList($ids, $dirtyClass, $dirtyClasses);
108
        }
109
110
        return $dirtyClasses;
111
    }
112
113
    /**
114
     * Create an ArrayList of the dirty items to be deleted from Solr
115
     * Uses the given class name to generate stub objects
116
     *
117
     * @param array $items
118
     * @param string $dirtyClass
119
     * @param ArrayList $dirtyClasses
120
     * @return ArrayList
121
     */
122 2
    private function createDeleteList($items, $dirtyClass, $dirtyClasses)
123
    {
124
        /** @var ArrayList $deletions */
125 2
        foreach ($items as $item) {
126 2
            $dirtyItem = $dirtyClass::create(['ClassName' => $dirtyClass, 'ID' => $item]);
127 2
            $dirtyClasses->push($dirtyItem);
128
        }
129
130 2
        return $dirtyClasses;
131
    }
132
}
133