Passed
Push — sheepy/elevation-configuration ( f8fadb...77a4b0 )
by Marco
07:42
created

ClearDirtyClassesTask   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Test Coverage

Coverage 96.15%

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 30
c 5
b 0
f 0
dl 0
loc 90
ccs 25
cts 26
cp 0.9615
rs 10
wmc 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A run() 0 24 4
A getDirtyClasses() 0 14 4
A createDeleteList() 0 6 2
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\DataObject;
28
use SilverStripe\ORM\ValidationException;
29
30
/**
31
 * Class ClearDirtyClasses Clear out classes that were not succesfully updated or deleted in Solr.
32
 *
33
 * Any classes that failed to index properly or be removed properly need to be cleaned out regularly
34
 * This task takes care of doing this. It can be run directly via /dev/tasks, or via a queued job
35
 *
36
 * @package Firesphere\SolrSearch\Tasks
37
 */
38
class ClearDirtyClassesTask extends BuildTask
39
{
40
    use LoggerTrait;
41
    /**
42
     * @var string URLSegment
43
     */
44
    private static $segment = 'SolrClearDirtyClasses';
45
    /**
46
     * @var string Title
47
     */
48
    protected $title = 'Fix broken items in the Solr cores';
49
    /**
50
     * @var string Description
51
     */
52
    protected $description = 'Clear out classes that are marked as dirty on Solr.';
53
54
    /**
55
     * Clean up Dirty Classes in the index
56
     *
57
     * When there are dirty classes to update or delete, the run will attempt to clean up.
58
     * Dirty classes happen when changes to classes are not successfully updated in Solr
59
     *
60
     * @param HTTPRequest $request
61
     * @return void
62
     * @throws GuzzleException
63
     * @throws ReflectionException
64
     * @throws ValidationException
65
     */
66 2
    public function run($request)
67
    {
68
        /** @var DataList|DirtyClass $dirtyObjectList */
69 2
        $dirtyObjectList = DirtyClass::get();
70
        /** @var SolrCoreService $service */
71 2
        $service = new SolrCoreService();
72 2
        foreach ($dirtyObjectList as $dirtyObject) {
73 2
            $dirtyClasses = $this->getDirtyClasses($dirtyObject);
74 2
            if (!$dirtyClasses->count()) {
75 2
                continue;
76
            }
77
            try {
78 2
                $service->updateItems($dirtyClasses, $dirtyObject->Type);
79 2
                $dirtyObject->delete();
80
            } catch (Exception $exception) {
81
                // @codeCoverageIgnoreStart
82
                $this->getLogger()->error($exception->getMessage());
83
                continue;
84
                // @codeCoverageIgnoreEnd
85
            }
86
        }
87
        /** @var SolrLogger $solrLogger */
88 2
        $solrLogger = new SolrLogger();
89 2
        $solrLogger->saveSolrLog('Index');
90 2
    }
91
92
    /**
93
     * Get the objects that need to be deleted or updated as a list
94
     *
95
     * @param DataObject $dirtyObject
96
     * @return ArrayList|DataList
97
     */
98 2
    private function getDirtyClasses($dirtyObject)
99
    {
100
        /** @var string|DataObject $dirtyClass */
101 2
        $dirtyClass = $dirtyObject->Class;
102 2
        $ids = json_decode($dirtyObject->IDs, true);
103 2
        $dirtyClasses = ArrayList::create();
104 2
        if ($dirtyObject->Type === SolrCoreService::UPDATE_TYPE && count($ids)) {
105 2
            $dirtyClasses = $dirtyClass::get()->byIDs($ids);
106
        }
107 2
        if ($dirtyObject->Type === SolrCoreService::DELETE_TYPE) {
108 2
            $this->createDeleteList($ids, $dirtyClass, $dirtyClasses);
109
        }
110
111 2
        return $dirtyClasses;
112
    }
113
114
    /**
115
     * Create an ArrayList of the dirty items to be deleted from Solr
116
     * Uses the given class name to generate stub objects
117
     *
118
     * @param array $items
119
     * @param string $dirtyClass
120
     * @param ArrayList $dirtyClasses
121
     */
122 2
    protected 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 2
    }
130
}
131