Passed
Push — master ( ba1efb...f2c93c )
by Marco
06:01
created

ClearDirtyClassesTask::run()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 3
eloc 12
c 3
b 0
f 0
nc 4
nop 1
dl 0
loc 21
ccs 10
cts 10
cp 1
crap 3
rs 9.8666
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
            try {
75 2
                $service->updateItems($dirtyClasses, $dirtyObject->Type);
76 2
                $dirtyObject->delete();
77 2
            } catch (Exception $exception) {
78
                // @codeCoverageIgnoreStart
79
                $this->getLogger()->error($exception->getMessage());
80
                continue;
81
                // @codeCoverageIgnoreEnd
82
            }
83
        }
84
        /** @var SolrLogger $solrLogger */
85 2
        $solrLogger = new SolrLogger();
86 2
        $solrLogger->saveSolrLog('Index');
87 2
    }
88
89
    /**
90
     * Get the objects that need to be deleted or updated as a list
91
     *
92
     * @param DirtyClass $dirtyObject
93
     * @return ArrayList|DataList
94
     */
95 2
    private function getDirtyClasses($dirtyObject)
96
    {
97
        /** @var string $dirtyClass */
98 2
        $dirtyClass = $dirtyObject->Class;
99 2
        $ids = json_decode($dirtyObject->IDs, true);
100 2
        $dirtyClasses = ArrayList::create();
101 2
        if ($dirtyObject->Type === SolrCoreService::UPDATE_TYPE && count($ids)) {
102 2
            $dirtyClasses = $dirtyClass::get()->byIDs($ids);
103
        }
104 2
        if ($dirtyObject->Type === SolrCoreService::DELETE_TYPE) {
105 2
            $this->createDeleteList($ids, $dirtyClass, $dirtyClasses);
106
        }
107
108 2
        return $dirtyClasses;
109
    }
110
111
    /**
112
     * Create an ArrayList of the dirty items to be deleted from Solr
113
     * Uses the given class name to generate stub objects
114
     *
115
     * @param array $items
116
     * @param string $dirtyClass
117
     * @param ArrayList $dirtyClasses
118
     */
119 2
    private function createDeleteList($items, $dirtyClass, &$dirtyClasses)
120
    {
121
        /** @var ArrayList $deletions */
122 2
        foreach ($items as $item) {
123 2
            $dirtyItem = $dirtyClass::create(['ClassName' => $dirtyClass, 'ID' => $item]);
124 2
            $dirtyClasses->push($dirtyItem);
125
        }
126 2
    }
127
}
128