Completed
Pull Request — master (#16)
by Eric
10:34
created

LuceneManager::getIndexes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the Ivory Lucene Search package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ivory\LuceneSearchBundle\Model;
13
14
use ZendSearch\Lucene\Analysis\Analyzer\Analyzer;
15
use ZendSearch\Lucene\Analysis\Analyzer\Common\TextNum\CaseInsensitive;
16
use ZendSearch\Lucene\Index;
17
use ZendSearch\Lucene\Lucene;
18
use ZendSearch\Lucene\Search\QueryParser;
19
use ZendSearch\Lucene\Storage\Directory\Filesystem;
20
21
/**
22
 * @author GeLo <[email protected]>
23
 */
24
class LuceneManager
25
{
26
    const DEFAULT_ANALYZER = CaseInsensitive::class;
27
    const DEFAULT_MAX_BUFFERED_DOCS = 10;
28
    const DEFAULT_MAX_MERGE_DOCS = PHP_INT_MAX;
29
    const DEFAULT_MERGE_FACTOR = 10;
30
    const DEFAULT_PERMISSIONS = 0777;
31
    const DEFAULT_AUTO_OPTIMIZED = false;
32
    const DEFAULT_QUERY_PARSER_ENCODING = '';
33
34
    /**
35
     * @var Index[]
36
     */
37
    private $indexes = [];
38
39
    /**
40
     * @var array
41
     */
42
    private $configs = [];
43
44
    /**
45
     * @return bool
46
     */
47
    public function hasIndexes()
48
    {
49
        return !empty($this->configs);
50
    }
51
52
    /**
53
     * @return string[]
54
     */
55
    public function getIndexes()
56
    {
57
        return array_keys($this->configs);
58
    }
59
60
    /**
61
     * @param string $identifier
62
     *
63
     * @return bool
64
     */
65
    public function hasIndex($identifier)
66
    {
67
        return isset($this->configs[$identifier]);
68
    }
69
70
    /**
71
     * @param string $identifier
72
     *
73
     * @return Index
74
     */
75
    public function getIndex($identifier)
76
    {
77
        $config = $this->getConfig($identifier);
78
        $path = $config['path'];
79
80
        Filesystem::setDefaultFilePermissions($config['permissions']);
81
        QueryParser::setDefaultEncoding($config['query_parser_encoding']);
82
        Analyzer::setDefault(new $config['analyzer']());
83
84
        if (!$this->checkPath($path)) {
85
            $this->indexes[$identifier] = Lucene::create($path);
86
        } else {
87
            $this->indexes[$identifier] = Lucene::open($path);
88
        }
89
90
        $this->indexes[$identifier]->setMaxBufferedDocs($config['max_buffered_docs']);
91
        $this->indexes[$identifier]->setMaxMergeDocs($config['max_merge_docs']);
92
        $this->indexes[$identifier]->setMergeFactor($config['merge_factor']);
93
94
        if ($config['auto_optimized']) {
95
            $this->indexes[$identifier]->optimize();
96
        }
97
98
        return $this->indexes[$identifier];
99
    }
100
101
    /**
102
     * @param array $indexes
103
     *
104
     * @throws \InvalidArgumentException
105
     */
106
    public function setIndexes(array $indexes)
107
    {
108
        foreach ($indexes as $identifier => $index) {
109
            if (!isset($index['path'])) {
110
                throw new \InvalidArgumentException('Each lucene index must have a path value.');
111
            }
112
113
            $this->setIndex(
114
                $identifier,
115
                $index['path'],
116
                isset($index['analyzer']) ? $index['analyzer'] : self::DEFAULT_ANALYZER,
117
                isset($index['max_buffered_docs']) ? $index['max_buffered_docs'] : self::DEFAULT_MAX_BUFFERED_DOCS,
118
                isset($index['max_merge_docs']) ? $index['max_merge_docs'] : self::DEFAULT_MAX_MERGE_DOCS,
119
                isset($index['merge_factor']) ? $index['merge_factor'] : self::DEFAULT_MERGE_FACTOR,
120
                isset($index['permissions']) ? $index['permissions'] : self::DEFAULT_PERMISSIONS,
121
                isset($index['auto_optimized']) ? $index['auto_optimized'] : self::DEFAULT_AUTO_OPTIMIZED,
122
                isset($index['query_parser_encoding']) ? $index['query_parser_encoding'] : self::DEFAULT_QUERY_PARSER_ENCODING
123
            );
124
        }
125
    }
126
127
    /**
128
     * @param string $identifier
129
     * @param string $path
130
     * @param string $analyzer
131
     * @param int    $maxBufferedDocs
132
     * @param int    $maxMergeDocs
133
     * @param int    $mergeFactor
134
     * @param int    $permissions
135
     * @param bool   $autoOptimized
136
     * @param string $queryParserEncoding
137
     */
138
    public function setIndex(
139
        $identifier,
140
        $path,
141
        $analyzer = self::DEFAULT_ANALYZER,
142
        $maxBufferedDocs = self::DEFAULT_MAX_BUFFERED_DOCS,
143
        $maxMergeDocs = self::DEFAULT_MAX_MERGE_DOCS,
144
        $mergeFactor = self::DEFAULT_MERGE_FACTOR,
145
        $permissions = self::DEFAULT_PERMISSIONS,
146
        $autoOptimized = self::DEFAULT_AUTO_OPTIMIZED,
147
        $queryParserEncoding = self::DEFAULT_QUERY_PARSER_ENCODING
148
    ) {
149
        $this->configs[$identifier] = [
150
            'path'                  => $path,
151
            'analyzer'              => $analyzer,
152
            'max_buffered_docs'     => $maxBufferedDocs,
153
            'max_merge_docs'        => $maxMergeDocs,
154
            'merge_factor'          => $mergeFactor,
155
            'permissions'           => $permissions,
156
            'auto_optimized'        => $autoOptimized,
157
            'query_parser_encoding' => $queryParserEncoding,
158
        ];
159
    }
160
161
    /**
162
     * @param string $identifier
163
     * @param bool   $removeDirectory
164
     */
165
    public function removeIndex($identifier, $removeDirectory = false)
166
    {
167
        if ($removeDirectory) {
168
            $this->eraseIndex($identifier);
169
        }
170
171
        unset($this->indexes[$identifier]);
172
        unset($this->configs[$identifier]);
173
    }
174
175
    /**
176
     * @param string $identifier
177
     */
178
    public function eraseIndex($identifier)
179
    {
180
        $directory = $this->getIndex($identifier)->getDirectory();
181
        unset($this->indexes[$identifier]);
182
183
        if (!$directory instanceof Filesystem) {
184
            return;
185
        }
186
187
        foreach ($directory->fileList() as $file) {
188
            $directory->deleteFile($file);
189
        }
190
191
        $config = $this->getConfig($identifier);
192
193
        if (is_dir($config['path'])) {
194
            rmdir($config['path']);
195
        }
196
    }
197
198
    /**
199
     * @param string $identifier
200
     *
201
     * @throws \InvalidArgumentException
202
     *
203
     * @return array
204
     */
205
    private function getConfig($identifier)
206
    {
207
        if (!isset($this->configs[$identifier])) {
208
            throw new \InvalidArgumentException(sprintf('The lucene index "%s" does not exist.', $identifier));
209
        }
210
211
        return $this->configs[$identifier];
212
    }
213
214
    /**
215
     * @param string $path
216
     *
217
     * @return bool
218
     */
219
    private function checkPath($path)
220
    {
221
        return file_exists($path) && is_readable($path) && ($resources = scandir($path)) && (count($resources) > 2);
222
    }
223
}
224