Completed
Push — feature/EVO-5751-text-index-mo... ( 8fecb1...ad25d5 )
by
unknown
62:35
created

GenerateBuildIndexesCommand::execute()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 44
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 44
ccs 0
cts 29
cp 0
rs 6.7272
cc 7
eloc 27
nc 7
nop 2
crap 56
1
<?php
2
/**
3
 * generate MongoDB Fulltext-Search Indexes
4
 */
5
6
namespace Graviton\GeneratorBundle\Command;
7
8
use Doctrine\ODM\MongoDB\DocumentManager;
9
use Graviton\GeneratorBundle\Definition\JsonDefinition;
10
use Graviton\GeneratorBundle\Definition\Loader\LoaderInterface;
11
use Symfony\Component\Console\Command\Command;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Input\InputOption;
14
use Symfony\Component\Console\Output\OutputInterface;
15
16
/**
17
 * Here, we generate all MongoDB Fulltext-Search Indexes
18
 *
19
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
20
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
21
 * @link     http://swisscom.ch
22
 */
23
class GenerateBuildIndexesCommand extends Command
24
{
25
    /**
26
     * @var LoaderInterface
27
     */
28
    private $definitionLoader;
29
30
    /**
31
     * @var documentManager
32
     */
33
    private $documentManager;
34
35
    /**
36
     * GenerateBuildIndexesCommand constructor.
37
     *
38
     * @param LoaderInterface $definitionLoader The definition Loader - loads Definitions from JSON-Files
39
     * @param DocumentManager $documentManager  The Doctrine Document Manager
40
     * @param String          $name             The Name of this Command
0 ignored issues
show
Documentation introduced by
Should the type for parameter $name not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
41
     */
42 2
    public function __construct(
43
        LoaderInterface $definitionLoader,
44
        DocumentManager $documentManager,
45
        $name = null
46
    ) {
47 2
        parent::__construct($name);
48
49 2
        $this->definitionLoader = $definitionLoader;
50 2
        $this->documentManager = $documentManager;
0 ignored issues
show
Documentation Bug introduced by
It seems like $documentManager of type object<Doctrine\ODM\MongoDB\DocumentManager> is incompatible with the declared type object<Graviton\Generato...ommand\documentManager> of property $documentManager.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
51 2
    }
52
53
    /**
54
     * {@inheritDoc}
55
     *
56
     * @return void
57
     */
58 2
    protected function configure()
59
    {
60 2
        parent::configure();
61
62 2
        $this->addOption(
63 2
            'json',
64 2
            '',
65 2
            InputOption::VALUE_OPTIONAL,
66 1
            'Path to the json definition.'
67 1
        )
68 2
            ->setName('graviton:generate:build-indexes')
69 2
            ->setDescription(
70 1
                'Generates Mongo-Text Indexes (MongoDB >= 2.6) for collections as defined'
71 1
            );
72 2
    }
73
74
    /**
75
     * {@inheritDoc}
76
     *
77
     * @param InputInterface  $input  input
78
     * @param OutputInterface $output output
79
     *
80
     * @return void
81
     */
82
    protected function execute(InputInterface $input, OutputInterface $output)
83
    {
84
        $filesToWorkOn = $this->definitionLoader->load($input->getOption('json'));
85
        if (count($filesToWorkOn) < 1) {
86
            throw new \LogicException('Could not find any usable JSON files.');
87
        }
88
89
        /**
90
         * Generate Indexes, if definition is found.
91
         */
92
        foreach ($filesToWorkOn as $jsonDef) {
93
            $textSearchIndexDefinitionFromJson = $this->getTextSearchIndexDefinitionFromJson($jsonDef);
94
            if (count($textSearchIndexDefinitionFromJson)) {
95
                $className = 'GravitonDyn\\' . $jsonDef->getId() . 'Bundle\\Document\\' . $jsonDef->getId();
96
                // Check MongoVersion, unfortunately needs Classname to fetch the right DB Connection
97
                $mongoVersion = $this->getMongoDBVersion($className);
98
                if ((float) $mongoVersion >= 2.6) {
99
                    $indexName = $textSearchIndexDefinitionFromJson[1]['name'];
100
                    $collection = $this->documentManager->getDocumentCollection($className);
101
                    // deleting only the eventual formerly built textindex with given Name
102
                    foreach ($collection->getIndexInfo() as $indexInfo) {
103
                        if ($indexInfo['name']=='search'.$collection->getName()) {
104
                            echo "Deleting Custom Text index ".'search'.$collection->getName()."\n";
105
                            $this->documentManager->getDocumentDatabase($className)->command(
106
                                array(
107
                                    "deleteIndexes" => $collection->getName(),
108
                                    "index" =>'search'.$collection->getName()
109
                                )
110
                            );
111
                            break;
112
                        }
113
                    }
114
                    $collection->ensureIndex(
115
                        $textSearchIndexDefinitionFromJson[0],
116
                        $textSearchIndexDefinitionFromJson[1]
117
                    );
118
                    echo "Created index '" . $indexName . "' for Collection '" . $collection->getName() . "'\n";
119
                } else {
120
                    echo "Couldn't create text Index for Collection " . $className
121
                        . ". MongoDB Version =< 2.6 installed: " . $mongoVersion . "\n";
122
                }
123
            }
124
        }
125
    }
126
127
    /**
128
     * @param JsonDefinition $jsonDef the Json-Definition-Object for a Service/Collection
129
     * @return array the Index-Definition-Array
130
     */
131
    private function getTextSearchIndexDefinitionFromJson(JsonDefinition $jsonDef)
132
    {
133
        $index = [];
134
        foreach ($jsonDef->getFields() as $field) {
135
            if (isset($field->getDefAsArray()['searchable']) && $field->getDefAsArray()['searchable'] > 0) {
136
                $index[0][$field->getName()] = 'text';
137
                $index[1]['weights'][$field->getName()] = (int) $field->getDefAsArray()['searchable'];
138
            }
139
        };
140
        if (isset($index[1])) {
141
            $index[1]['name'] = 'search' . $jsonDef->getId();
142
            $index[1]['default_language'] = 'de';
143
            $index[1]['language_override'] = 'language';
144
        }
145
        return $index;
146
    }
147
148
    /**
149
     * Gets the installed MongoDB Version
150
     * @param String $className The Classname of the collection, needed to fetch the right DB connection
151
     * @return String getMongoDBVersion The version of the MongoDB as a string
152
     */
153
    private function getMongoDBVersion($className)
154
    {
155
        $buildInfo = $this->documentManager->getDocumentDatabase($className)->command(['buildinfo' => 1]);
156
        if (isset($buildInfo['version'])) {
157
            return $buildInfo['version'];
158
        } else {
159
            return 'unkown';
160
        }
161
    }
162
}
163