Completed
Push — master ( f7252d...955fe9 )
by André
19:56 queued 06:52
created

Indexer::indexLocations()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 4
nop 2
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the eZ Publish Kernel package.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Publish\Core\Search\Elasticsearch\Content;
10
11
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
12
use eZ\Publish\Core\Search\Common\Indexer as SearchIndexer;
13
use eZ\Publish\Core\Search\Elasticsearch\Content\Handler as SearchHandler;
14
use PDO;
15
use RuntimeException;
16
use Symfony\Component\Console\Helper\ProgressBar;
17
use Symfony\Component\Console\Output\OutputInterface;
18
19
class Indexer extends SearchIndexer
20
{
21
    /**
22
     * @var \eZ\Publish\Core\Search\Elasticsearch\Content\Handler
23
     */
24
    protected $searchHandler;
25
26
    /**
27
     * Create search engine index.
28
     *
29
     * @param \Symfony\Component\Console\Output\OutputInterface $output
30
     * @param int $iterationCount
31
     * @param bool $commit commit changes after each iteration
32
     */
33
    public function createSearchIndex(OutputInterface $output, $iterationCount, $commit)
34
    {
35
        $output->writeln('Creating Elasticsearch Search Engine Index...');
36
37
        if (!$this->searchHandler instanceof SearchHandler) {
38
            throw new RuntimeException(sprintf('Expected to find an instance of %s, but found %s', SearchHandler::class, get_class($this->searchHandler)));
39
        }
40
41
        $stmt = $this->getContentDbFieldsStmt(['count(id)']);
42
        $totalCount = intval($stmt->fetchColumn());
43
        $stmt = $this->getContentDbFieldsStmt(['id', 'current_version']);
44
        $this->searchHandler->purgeIndex();
45
        /** @var \Symfony\Component\Console\Helper\ProgressBar $progress */
46
        $progress = new ProgressBar($output);
47
        $progress->start($totalCount);
48
        $i = 0;
49
        do {
50
            $contentObjects = [];
51
            for ($k = 0; $k <= $iterationCount; ++$k) {
52
                if (!$row = $stmt->fetch(PDO::FETCH_ASSOC)) {
53
                    break;
54
                }
55
                try {
56
                    $contentObjects[] = $this->persistenceHandler->contentHandler()->load(
57
                        $row['id'],
58
                        $row['current_version']
59
                    );
60
                } catch (NotFoundException $e) {
61
                    $this->logWarning($progress, "Could not load current version of Content with id ${row['id']}, so skipped for indexing. Full exception: " . $e->getMessage());
62
                }
63
            }
64
            foreach ($contentObjects as $contentObject) {
65
                try {
66
                    $this->searchHandler->indexContent($contentObject);
67
                    // Skip location indexing if search engine does not use it, or if content does not have locations
68
                    if (empty($contentObject->versionInfo->contentInfo->mainLocationId)) {
69
                        continue;
70
                    }
71
                    $this->indexLocations($contentObject->versionInfo->contentInfo->id, $progress);
72
                } catch (NotFoundException $e) {
73
                    $this->logWarning($progress, 'Content with id ' . $contentObject->versionInfo->id . ' has missing data, so skipped for indexing. Full exception: ' . $e->getMessage());
74
                }
75
            }
76
            if ($commit) {
77
                $this->searchHandler->flush();
78
            }
79
            $progress->advance($k);
80
        } while (($i += $iterationCount) < $totalCount);
81
        $progress->finish();
82
        $output->writeln('');
83
84
        $output->writeln('Finished creating Elasticsearch Search Engine Index');
85
    }
86
87
    /**
88
     * Index Locations of the given Content Object.
89
     *
90
     * @param int $contentId Content Object Id
91
     * @param \Symfony\Component\Console\Helper\ProgressBar $progress
92
     */
93
    private function indexLocations($contentId, ProgressBar $progress)
94
    {
95
        $locationIds = $this->getContentLocationIds($contentId);
96
        foreach ($locationIds as $locationId) {
97
            try {
98
                $location = $this->persistenceHandler->locationHandler()->load($locationId);
99
                $this->searchHandler->indexLocation($location);
100
            } catch (NotFoundException $e) {
101
                $this->logWarning($progress, "Could not load Location with id $locationId, so skipped for indexing. Full exception: " . $e->getMessage());
102
            }
103
        }
104
    }
105
}
106