Completed
Pull Request — master (#1093)
by Oleg
08:41
created

Resetter::switchIndexAlias()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
ccs 6
cts 6
cp 1
rs 9.6666
cc 2
eloc 5
nc 2
nop 2
crap 2
1
<?php
2
3
namespace FOS\ElasticaBundle\Index;
4
5
use Elastica\Index;
6
use Elastica\Exception\ResponseException;
7
use Elastica\Type\Mapping;
8
use FOS\ElasticaBundle\Configuration\ConfigManager;
9
use FOS\ElasticaBundle\Event\IndexResetEvent;
10
use FOS\ElasticaBundle\Event\TypeResetEvent;
11
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
12
13
/**
14
 * Deletes and recreates indexes.
15
 */
16
class Resetter
17
{
18
    /**
19
     * @var AliasProcessor
20
     */
21
    private $aliasProcessor;
22
23
    /***
24
     * @var ConfigManager
25
     */
26
    private $configManager;
27
28
    /**
29
     * @var EventDispatcherInterface
30
     */
31
    private $dispatcher;
32
33
    /**
34
     * @var IndexManager
35
     */
36
    private $indexManager;
37
38
    /**
39
     * @var MappingBuilder
40
     */
41
    private $mappingBuilder;
42
43
    /**
44
     * @param ConfigManager            $configManager
45
     * @param IndexManager             $indexManager
46
     * @param AliasProcessor           $aliasProcessor
47
     * @param MappingBuilder           $mappingBuilder
48
     * @param EventDispatcherInterface $eventDispatcher
49
     */
50 15
    public function __construct(
51
        ConfigManager $configManager,
52
        IndexManager $indexManager,
53
        AliasProcessor $aliasProcessor,
54
        MappingBuilder $mappingBuilder,
55
        EventDispatcherInterface $eventDispatcher
56
    ) {
57 15
        $this->aliasProcessor = $aliasProcessor;
58 15
        $this->configManager = $configManager;
59 15
        $this->dispatcher = $eventDispatcher;
60 15
        $this->indexManager = $indexManager;
61 15
        $this->mappingBuilder = $mappingBuilder;
62 15
    }
63
64
    /**
65
     * Deletes and recreates all indexes.
66
     *
67
     * @param bool $populating
68
     * @param bool $force
69
     */
70 1
    public function resetAllIndexes($populating = false, $force = false)
71
    {
72 1
        foreach ($this->configManager->getIndexNames() as $name) {
73 1
            $this->resetIndex($name, $populating, $force);
74
        }
75 1
    }
76
77
    /**
78
     * Deletes and recreates the named index. If populating, creates a new index
79
     * with a randomised name for an alias to be set after population.
80
     *
81
     * @param string $indexName
82
     * @param bool   $populating
83
     * @param bool   $force      If index exists with same name as alias, remove it
84
     *
85
     * @throws \InvalidArgumentException if no index exists for the given name
86
     */
87 8
    public function resetIndex($indexName, $populating = false, $force = false)
88
    {
89 8
        $indexConfig = $this->configManager->getIndexConfiguration($indexName);
90 7
        $index = $this->indexManager->getIndex($indexName);
91
92 7
        $event = new IndexResetEvent($indexName, $populating, $force);
93 7
        $this->dispatcher->dispatch(IndexResetEvent::PRE_INDEX_RESET, $event);
94
95 7
        if ($indexConfig->isUseAlias()) {
96 1
            $this->aliasProcessor->setRootName($indexConfig, $index);
97
        }
98
99 7
        $mapping = $this->mappingBuilder->buildIndexMapping($indexConfig);
100 7
        $index->create($mapping, true);
101
102 7
        if (!$populating and $indexConfig->isUseAlias()) {
103 1
            $this->aliasProcessor->switchIndexAlias($indexConfig, $index, $force);
104
        }
105
106 7
        $this->dispatcher->dispatch(IndexResetEvent::POST_INDEX_RESET, $event);
107 7
    }
108
109
    /**
110
     * Deletes and recreates a mapping type for the named index.
111
     *
112
     * @param string $indexName
113
     * @param string $typeName
114
     *
115
     * @throws \InvalidArgumentException if no index or type mapping exists for the given names
116
     * @throws ResponseException
117
     */
118 5
    public function resetIndexType($indexName, $typeName)
119
    {
120 5
        $typeConfig = $this->configManager->getTypeConfiguration($indexName, $typeName);
121 4
        $index = $this->indexManager->getIndex($indexName);
122 4
        $type = $index->getType($typeName);
123
124 4
        $indexConfig = $this->configManager->getIndexConfiguration($indexName);
125 4
        $settings = $indexConfig->getSettings();
126
127 4
        $event = new TypeResetEvent($indexName, $typeName);
128 4
        $this->dispatcher->dispatch(TypeResetEvent::PRE_TYPE_RESET, $event);
129
130
        try {
131 4
            $type->delete();
132
        } catch (ResponseException $e) {
133
            if (strpos($e->getMessage(), 'TypeMissingException') === false) {
134
                throw $e;
135
            }
136
        }
137
138 4
        if (!empty($settings)) {
139 2
            $index->close();
140 2
            $index->setSettings($settings);
141 2
            $index->open();
142
        }
143
144 4
        $mapping = new Mapping();
145 4
        foreach ($this->mappingBuilder->buildTypeMapping($typeConfig) as $name => $field) {
0 ignored issues
show
Bug introduced by
The expression $this->mappingBuilder->b...ypeMapping($typeConfig) of type object<stdClass>|array<s...ynamic_templates":"?"}> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
146 2
            $mapping->setParam($name, $field);
147
        }
148
149 4
        $type->setMapping($mapping);
150
151 4
        $this->dispatcher->dispatch(TypeResetEvent::POST_TYPE_RESET, $event);
152 4
    }
153
154
    /**
155
     * A command run when a population has finished.
156
     *
157
     * @param string $indexName
158
     *
159
     * @deprecated
160
     */
161
    public function postPopulate($indexName)
162
    {
163
        $this->switchIndexAlias($indexName);
164
    }
165
166
    /**
167
     * Switching aliases
168
     *
169
     * @param string $indexName
170
     * @param bool   $delete Delete or close index
171
     *
172
     * @throws \FOS\ElasticaBundle\Exception\AliasIsIndexException
173
     */
174 2
    public function switchIndexAlias($indexName, $delete = true)
175
    {
176 2
        $indexConfig = $this->configManager->getIndexConfiguration($indexName);
177
178 2
        if ($indexConfig->isUseAlias()) {
179 1
            $index = $this->indexManager->getIndex($indexName);
180 1
            $this->aliasProcessor->switchIndexAlias($indexConfig, $index, false, $delete);
181
        }
182 2
    }
183
}
184