Completed
Push — master ( 344722...0256b9 )
by Timo
20:25 queued 20:17
created

Item::setRecord()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
namespace ApacheSolrForTypo3\Solr\IndexQueue;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2009-2015 Ingo Renner <[email protected]>
8
 *  All rights reserved
9
 *
10
 *  This script is part of the TYPO3 project. The TYPO3 project is
11
 *  free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  The GNU General Public License can be found at
17
 *  http://www.gnu.org/copyleft/gpl.html.
18
 *
19
 *  This script is distributed in the hope that it will be useful,
20
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 *  GNU General Public License for more details.
23
 *
24
 *  This copyright notice MUST APPEAR in all copies of the script!
25
 ***************************************************************/
26
27
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\IndexQueueIndexingPropertyRepository;
28
use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository;
29
use ApacheSolrForTypo3\Solr\Site;
30
use TYPO3\CMS\Backend\Utility\BackendUtility;
31
use TYPO3\CMS\Core\Utility\GeneralUtility;
32
33
/**
34
 * Representation of an index queue item, carrying meta data and the record to be
35
 * indexed.
36
 *
37
 * @author Ingo Renner <[email protected]>
38
 */
39
class Item
40
{
41
42
    /**
43
     * The item's uid in the index queue (tx_solr_indexqueue_item.uid)
44
     *
45
     * @var int
46
     */
47
    protected $indexQueueUid;
48
49
    /**
50
     * The root page uid of the tree the item is located in (tx_solr_indexqueue_item.root)
51
     *
52
     * @var int
53
     */
54
    protected $rootPageUid;
55
56
    /**
57
     * The record's type, usually a table name, but could also be a file type (tx_solr_indexqueue_item.item_type)
58
     *
59
     * @var string
60
     */
61
    protected $type;
62
63
    /**
64
     * The name of the indexing configuration that should be used when indexing (tx_solr_indexqueue_item.indexing_configuration)
65
     * the item.
66
     *
67
     * @var string
68
     */
69
    protected $indexingConfigurationName;
70
71
    /**
72
     * The unix timestamp when the record was last changed (tx_solr_indexqueue_item.changed)
73
     *
74
     * @var int
75
     */
76
    protected $changed;
77
78
    /**
79
     * Indexing properties to provide additional information for the item's
80
     * indexer / how to index the item.
81
     *
82
     * @var array
83
     */
84
    protected $indexingProperties = [];
85
86
    /**
87
     * Flag for lazy loading indexing properties.
88
     *
89
     * @var bool
90
     */
91
    protected $indexingPropertiesLoaded = false;
92
93
    /**
94
     * Flag, whether indexing properties exits for this item.
95
     *
96
     * @var bool
97
     */
98
    protected $hasIndexingProperties = false;
99
100
    /**
101
     * The record's uid.
102
     *
103
     * @var int
104
     */
105
    protected $recordUid = 0;
106
107
    /**
108
     * The record itself
109
     *
110
     * @var array
111
     */
112
    protected $record;
113
114
    /**
115
     * Moint point identifier.
116
     *
117
     * @var string
118
     */
119
    protected $mountPointIdentifier;
120
121
    /**
122
     * @var string
123
     */
124
    protected $errors = '';
125
126
    /**
127
     * @var IndexQueueIndexingPropertyRepository
128
     */
129
    protected $indexQueueIndexingPropertyRepository;
130
131 64
    /**
132
     * Constructor, takes item meta data information and resolves that to the full record.
133
     *
134
     * @param array $itemMetaData Metadata describing the item to index using the index queue. Is expected to contain a record from table tx_solr_indexqueue_item
135 64
     * @param array $fullRecord Optional full record for the item. If provided, can save some SQL queries.
136 64
     * @param IndexQueueIndexingPropertyRepository|null $indexQueueIndexingPropertyRepository
137 64
     */
138 64
    public function __construct(array $itemMetaData, array $fullRecord = [], IndexQueueIndexingPropertyRepository $indexQueueIndexingPropertyRepository = null)
139 64
    {
140 64
        $this->indexQueueUid = $itemMetaData['uid'];
141 64
        $this->rootPageUid = $itemMetaData['root'];
142
        $this->type = $itemMetaData['item_type'];
143 64
        $this->recordUid = $itemMetaData['item_uid'];
144 64
        $this->mountPointIdentifier = (string) empty($itemMetaData['pages_mountidentifier']) ? '' : $itemMetaData['pages_mountidentifier'];
145
        $this->changed = $itemMetaData['changed'];
146 64
        $this->errors = (string) empty($itemMetaData['errors']) ? '' : $itemMetaData['errors'];
147 34
148
        $this->indexingConfigurationName = $itemMetaData['indexing_configuration'];
149 64
        $this->hasIndexingProperties = (boolean)$itemMetaData['has_indexing_properties'];
150
151
        if (!empty($fullRecord)) {
152
            $this->record = $fullRecord;
153
        }
154 8
        $this->indexQueueIndexingPropertyRepository = isset($indexQueueIndexingPropertyRepository) ? $indexQueueIndexingPropertyRepository : GeneralUtility::makeInstance(IndexQueueIndexingPropertyRepository::class);
155
    }
156 8
157
    /**
158
     * Getter for Index Queue UID
159
     *
160
     * @return integer
161
     */
162
    public function getIndexQueueUid()
163
    {
164 27
        return $this->indexQueueUid;
165
    }
166 27
167
    /**
168
     * Gets the item's root page ID (uid)
169
     *
170
     * @return int root page ID
171
     */
172
    public function getRootPageUid()
173
    {
174 21
        return $this->rootPageUid;
175
    }
176 21
177
    /**
178
     * Returns mount point identifier
179
     *
180
     * @return string
181
     */
182
    public function getMountPointIdentifier()
183
    {
184
        return $this->mountPointIdentifier;
185
    }
186
187
    /**
188
     * @param integer $uid
189
     */
190 5
    public function setRootPageUid($uid)
191
    {
192 5
        $this->rootPageUid = intval($uid);
193
    }
194
195
    /**
196
     * @return string
197
     */
198
    public function getErrors()
199
    {
200 27
        return $this->errors;
201
    }
202 27
203 27
    /**
204
     * Gets the site the item belongs to.
205
     *
206 23
     * @return Site Site instance the item belongs to.
207
     */
208 23
    public function getSite()
209
    {
210
        $siteRepository = GeneralUtility::makeInstance(SiteRepository::class);
211
        return $siteRepository->getSiteByRootPageId($this->rootPageUid);
212
    }
213
214
    public function getType()
215
    {
216 32
        return $this->type;
217
    }
218 32
219
    public function setType($type)
220
    {
221
        $this->type = $type;
222
    }
223
224
    public function getIndexingConfigurationName()
225
    {
226
        return $this->indexingConfigurationName;
227
    }
228
229
    public function setIndexingConfigurationName($indexingConfigurationName)
230
    {
231
        $this->indexingConfigurationName = $indexingConfigurationName;
232
    }
233
234
    public function getChanged()
235
    {
236 5
        return $this->changed;
237
    }
238 5
239
    public function setChanged($changed)
240 5
    {
241
        $this->changed = intval($changed);
242
    }
243
244
    public function getRecordUid()
245
    {
246
        $this->getRecord();
247
248
        return $this->record['uid'];
249
    }
250 20
251
    /**
252 20
     * Gets the item's full record.
253 1
     *
254 1
     * Uses lazy loading.
255 1
     *
256 1
     * @return array The item's DB record.
257 1
     */
258 1
    public function getRecord()
259
    {
260
        if (empty($this->record)) {
261
            $this->record = (array)BackendUtility::getRecord(
262 20
                $this->type,
263
                $this->recordUid,
264
                '*',
265
                '',
266
                false
267
            );
268
        }
269
270
        return $this->record;
271
    }
272
273 17
    public function setRecord(array $record)
274
    {
275 17
        $this->record = $record;
276
    }
277 17
278
    /**
279
     * @return int
280
     */
281
    public function getRecordPageId()
282
    {
283
        $this->getRecord();
284 7
285
        return $this->record['pid'];
286 7
    }
287
288 7
    /**
289 7
     * Stores the indexing properties.
290
     *
291
     */
292 7
    public function storeIndexingProperties()
293 7
    {
294
        $this->indexQueueIndexingPropertyRepository->removeByRootPidAndIndexQueueUid(intval($this->rootPageUid), intval($this->indexQueueUid));
295
296
        if ($this->hasIndexingProperties()) {
297
            $this->writeIndexingProperties();
298
        }
299
300 7
        $this->updateHasIndexingPropertiesFlag();
301
    }
302 7
303 7
    public function hasIndexingProperties()
304 7
    {
305 7
        return $this->hasIndexingProperties;
306
    }
307
308 7
    /**
309
     * Writes all indexing properties.
310
     */
311
    protected function writeIndexingProperties()
312
    {
313
        $properties = [];
314 7
        foreach ($this->indexingProperties as $propertyKey => $propertyValue) {
315
            $properties[] = [
316 7
                'root' => $this->rootPageUid,
317
                'item_id' => $this->indexQueueUid,
318 7
                'property_key' => $propertyKey,
319
                'property_value' => $propertyValue
320
            ];
321
        }
322
        if (empty($properties)) {
323
            return;
324
        }
325
        $this->indexQueueIndexingPropertyRepository->bulkInsert($properties);
326 7
    }
327
328 7
    /**
329 7
     * Updates the "has_indexing_properties" flag in the Index Queue.
330 7
     */
331 7
    protected function updateHasIndexingPropertiesFlag()
332 7
    {
333 7
        $hasIndexingProperties = '0';
334 7
        if ($this->hasIndexingProperties()) {
335
            $hasIndexingProperties = '1';
336
        }
337
338 7
        $GLOBALS['TYPO3_DB']->exec_UPDATEquery(
339 7
            'tx_solr_indexqueue_item',
340 7
            'uid = ' . intval($this->indexQueueUid),
341
            ['has_indexing_properties' => $hasIndexingProperties]
342
        );
343
344 7
        if ($GLOBALS['TYPO3_DB']->sql_error()) {
345
            throw new \RuntimeException(
346
                'Could not update has_indexing_properties flag in Index Queue for item ' . $this->indexQueueUid,
347
                1323802610
348
            );
349
        }
350 7
    }
351
352
    /**
353
     * @param string $key
354
     * @return bool
355
     */
356
    public function hasIndexingProperty($key)
357 7
    {
358
        $this->loadIndexingProperties();
359 7
360 7
        return array_key_exists($key, $this->indexingProperties);
361 7
    }
362
363
    /**
364 7
     * Loads the indexing properties for the item - if not already loaded.
365 7
     */
366 7
    public function loadIndexingProperties()
367 7
    {
368
        if (!$this->indexingPropertiesLoaded) {
369
            $indexingProperties = $this->indexQueueIndexingPropertyRepository->findAllByIndexQueueUid(intval($this->indexQueueUid));
370 7
371
            if (!empty($indexingProperties)) {
372
                foreach ($indexingProperties as $indexingProperty) {
373
                    $this->indexingProperties[$indexingProperty['property_key']] = $indexingProperty['property_value'];
374
                }
375
            }
376 7
377
            $this->indexingPropertiesLoaded = true;
378
        }
379
    }
380
381
    /**
382 1
     * Sets an indexing property for the item.
383
     *
384 1
     * @param string $key Indexing property name
385
     * @param string|int|float $value Indexing property value
386 1
     * @throws \InvalidArgumentException when $value is not string, integer or float
387
     */
388
    public function setIndexingProperty($key, $value)
389
    {
390
391
        // make sure to not interfere with existing indexing properties
392
        $this->loadIndexingProperties();
393 8
394
        $key = (string)$key; // Scalar typehints now!
395 8
396 8
        if (!is_string($value) && !is_int($value) && !is_float($value)) {
397 8
            throw new \InvalidArgumentException(
398 8
                'Cannot set indexing property "' . $key
399 8
                . '", its value must be string, integer or float, '
400
                . 'type given was "' . gettype($value) . '"',
401
                1323173209
402 8
            );
403
        }
404
405
        $this->indexingProperties[$key] = $value;
406
        $this->hasIndexingProperties = true;
407
    }
408 8
409
    /**
410 8
     * Gets a specific indexing property by its name/key.
411
     *
412
     * @param string $key Indexing property name/key.
413
     * @throws \InvalidArgumentException when the given $key does not exist.
414
     * @return string
415
     */
416
    public function getIndexingProperty($key)
417
    {
418
        $this->loadIndexingProperties();
419 7
420
        if (!array_key_exists($key, $this->indexingProperties)) {
421
            throw new \InvalidArgumentException(
422
                'No indexing property "' . $key . '".',
423 7
                1323174143
424
            );
425 7
        }
426
427 7
        return $this->indexingProperties[$key];
428
    }
429
430
    /**
431
     * Gets all indexing properties set for this item.
432
     *
433
     * @return array Array of indexing properties.
434
     */
435
    public function getIndexingProperties()
436 7
    {
437 7
        $this->loadIndexingProperties();
438 7
439
        return $this->indexingProperties;
440
    }
441
442
    /**
443
     * Gets the names/keys of the item's indexing properties.
444
     *
445
     * @return array Array of indexing property names/keys
446
     */
447
    public function getIndexingPropertyKeys()
448
    {
449
        $this->loadIndexingProperties();
450
451
        return array_keys($this->indexingProperties);
452
    }
453
}
454