/
SearchUpdateProcessor.php
146 lines (130 loc) · 4.22 KB
/
SearchUpdateProcessor.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
abstract class SearchUpdateProcessor
{
/**
* List of dirty records to process in format
*
* array(
* '$BaseClass' => array(
* '$State Key' => array(
* 'state' => array(
* 'key1' => 'value',
* 'key2' => 'value'
* ),
* 'ids' => array(
* '*id*' => array(
* '*Index Name 1*',
* '*Index Name 2*'
* )
* )
* )
* )
* )
*
* @var array
*/
protected $dirty;
public function __construct()
{
$this->dirty = array();
}
public function addDirtyIDs($class, $statefulids, $index)
{
$base = ClassInfo::baseDataClass($class);
$forclass = isset($this->dirty[$base]) ? $this->dirty[$base] : array();
foreach ($statefulids as $statefulid) {
$id = $statefulid['id'];
$state = $statefulid['state'];
$statekey = serialize($state);
if (!isset($forclass[$statekey])) {
$forclass[$statekey] = array('state' => $state, 'ids' => array($id => array($index)));
} elseif (!isset($forclass[$statekey]['ids'][$id])) {
$forclass[$statekey]['ids'][$id] = array($index);
} elseif (array_search($index, $forclass[$statekey]['ids'][$id]) === false) {
$forclass[$statekey]['ids'][$id][] = $index;
// dirty count stays the same
}
}
$this->dirty[$base] = $forclass;
}
/**
* Generates the list of indexes to process for the dirty items
*
* @return array
*/
protected function prepareIndexes()
{
$originalState = SearchVariant::current_state();
$dirtyIndexes = array();
$dirty = $this->getSource();
$indexes = FullTextSearch::get_indexes();
foreach ($dirty as $base => $statefulids) {
if (!$statefulids) {
continue;
}
foreach ($statefulids as $statefulid) {
$state = $statefulid['state'];
$ids = $statefulid['ids'];
SearchVariant::activate_state($state);
// Ensure that indexes for all new / updated objects are included
$objs = DataObject::get($base)->byIDs(array_keys($ids));
foreach ($objs as $obj) {
foreach ($ids[$obj->ID] as $index) {
if (!$indexes[$index]->variantStateExcluded($state)) {
$indexes[$index]->add($obj);
$dirtyIndexes[$index] = $indexes[$index];
}
}
unset($ids[$obj->ID]);
}
// Generate list of records that do not exist and should be removed
foreach ($ids as $id => $fromindexes) {
foreach ($fromindexes as $index) {
if (!$indexes[$index]->variantStateExcluded($state)) {
$indexes[$index]->delete($base, $id, $state);
$dirtyIndexes[$index] = $indexes[$index];
}
}
}
}
}
SearchVariant::activate_state($originalState);
return $dirtyIndexes;
}
/**
* Commits the specified index to the Solr service
*
* @param SolrIndex $index Index object
* @return bool Flag indicating success
*/
protected function commitIndex($index)
{
return $index->commit() !== false;
}
/**
* Gets the record data source to process
*
* @return array
*/
protected function getSource()
{
return $this->dirty;
}
/**
* Process all indexes, returning true if successful
*
* @return bool Flag indicating success
*/
public function process()
{
// Generate and commit all instances
$indexes = $this->prepareIndexes();
foreach ($indexes as $index) {
if (!$this->commitIndex($index)) {
return false;
}
}
return true;
}
abstract public function triggerProcessing();
}