Completed
Push — feature/EVO-5751-text-index-mo... ( 6b6245...40ee25 )
by
unknown
62:21
created

GenerateBuildIndexesCommand::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 1
eloc 7
nc 1
nop 3
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
    public function __construct(
43
        LoaderInterface $definitionLoader,
44
        DocumentManager $documentManager,
45
        $name = null
46
    ) {
47
        parent::__construct($name);
48
49
        $this->definitionLoader = $definitionLoader;
50
        $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
    }
52
53
    /**
54
     * {@inheritDoc}
55
     *
56
     * @return void
57
     */
58
    protected function configure()
59
    {
60
        parent::configure();
61
62
        $this->addOption(
63
            'json',
64
            '',
65
            InputOption::VALUE_OPTIONAL,
66
            'Path to the json definition.'
67
        )
68
            ->setName('graviton:generate:build-indexes')
69
            ->setDescription(
70
                'Generates Mongo-Text Indexes (MongoDB >= 2.6) for collections as defined'
71
            );
72
    }
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
                    $collection->deleteIndex();
102
                    $collection->ensureIndex(
103
                        $textSearchIndexDefinitionFromJson[0],
104
                        $textSearchIndexDefinitionFromJson[1]
105
                    );
106
                    echo "Created index '" . $indexName . "' for Collection '" . $collection->getName() . "'\n";
107
                } else {
108
                    echo "Couldn't create text Index for Collection " . $className
109
                        . ". MongoDB Version =< 2.6 installed: " . $mongoVersion . "\n";
110
                }
111
            }
112
        }
113
    }
114
115
    /**
116
     * @param JsonDefinition $jsonDef the Json-Definition-Object for a Service/Collection
117
     * @return array the Index-Definition-Array
118
     */
119
    private function getTextSearchIndexDefinitionFromJson(JsonDefinition $jsonDef)
120
    {
121
        $index = [];
122
        foreach ($jsonDef->getFields() as $field) {
123
            if (isset($field->getDefAsArray()['searchable']) && $field->getDefAsArray()['searchable'] > 0) {
124
                $index[0][$field->getName()] = 'text';
125
                $index[1]['weights'][$field->getName()] = (int) $field->getDefAsArray()['searchable'];
126
            }
127
        };
128
        if (isset($index[1])) {
129
            $index[1]['name'] = 'search' . $jsonDef->getId();
130
            $index[1]['default_language'] = 'de';
131
            $index[1]['language_override'] = 'language';
132
        }
133
        return $index;
134
    }
135
136
    /**
137
     * Gets the installed MongoDB Version
138
     * @param String $className The Classname of the collection, needed to fetch the right DB connection
139
     * @return String getMongoDBVersion The version of the MongoDB as a string
140
     */
141
    private function getMongoDBVersion($className)
142
    {
143
        $buildInfo = $this->documentManager->getDocumentDatabase($className)->command(['buildinfo' => 1]);
144
        if (isset($buildInfo['version'])) {
145
            return $buildInfo['version'];
146
        } else {
147
            return 'unkown';
148
        }
149
    }
150
}
151