InstallCommand   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 498
Duplicated Lines 0 %

Test Coverage

Coverage 32.67%

Importance

Changes 0
Metric Value
wmc 35
c 0
b 0
f 0
dl 0
loc 498
rs 9
ccs 66
cts 202
cp 0.3267

14 Methods

Rating   Name   Duplication   Size   Complexity  
A installDummyData() 0 16 1
B createTextnodes() 0 90 5
B createUsers() 0 26 1
A execute() 0 15 3
B createTopics() 0 38 5
A __construct() 0 12 1
B createHitches() 0 31 4
A purgeDB() 0 15 2
A configure() 0 16 1
B installUsers() 0 29 5
A createLicensees() 0 18 3
A cleanImageDirectories() 0 5 2
A installAdminUser() 0 16 1
A installDefaultUsers() 0 4 1
1
<?php
2
/* Copyright (C) 2015-2017 Michael Giesler, Stephan Kreutzer
3
 *
4
 * This file is part of Dembelo.
5
 *
6
 * Dembelo is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Affero General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * Dembelo is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU Affero General Public License 3 for more details.
15
 *
16
 * You should have received a copy of the GNU Affero General Public License 3
17
 * along with Dembelo. If not, see <http://www.gnu.org/licenses/>.
18
 */
19
namespace DembeloMain\Command;
20
21
use Apoutchika\LoremIpsumBundle\Services\LoremIpsum;
22
use DembeloMain\Document\Licensee;
23
use DembeloMain\Document\Textnode;
24
use DembeloMain\Document\TextnodeHitch;
25
use DembeloMain\Model\Repository\LicenseeRepositoryInterface;
26
use DembeloMain\Model\Repository\TextNodeRepositoryInterface;
27
use DembeloMain\Model\Repository\TopicRepositoryInterface;
28
use DembeloMain\Model\Repository\UserRepositoryInterface;
29
use Symfony\Component\Console\Command\Command;
30
use Symfony\Component\Console\Input\InputInterface;
31
use Symfony\Component\Console\Output\OutputInterface;
32
use DembeloMain\Document\User;
33
use DembeloMain\Document\Topic;
34
use Doctrine\Bundle\MongoDBBundle\ManagerRegistry;
35
use Symfony\Component\Console\Input\InputOption;
36
use DembeloMain\Document\Readpath;
37
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
38
39
/**
40
 * Class InstallCommand
41
 */
42
class InstallCommand extends Command
43
{
44
    /**
45
     * @var string
46
     */
47
    protected static $defaultName = 'dembelo:install';
48
49
    /**
50
     * @var ManagerRegistry
51
     */
52
    private $mongo;
53
54
    /**
55
     * @var array
56
     */
57
    private $dummyData = [];
58
59
    /**
60
     * @var string
61
     */
62
    private $topicImageDirectory;
63
64
    /**
65
     * @var TopicRepositoryInterface
66
     */
67
    private $topicRepository;
68
69
    /**
70
     * @var TextNodeRepositoryInterface
71
     */
72
    private $textNodeRepository;
73
74
    /**
75
     * @var LicenseeRepositoryInterface
76
     */
77
    private $licenseeRepository;
78
79
    /**
80
     * @var string
81
     */
82
    private $topicDummyImageDirectory;
83
84
    /**
85
     * @var LoremIpsum
86
     */
87
    private $loremIpsum;
88
89
    /**
90
     * @var UserRepositoryInterface
91
     */
92
    private $userRepository;
93
94
    /**
95
     * @var UserPasswordEncoderInterface
96
     */
97
    private $passwordEncoder;
98
99
    /**
100
     * InstallCommand constructor.
101
     *
102
     * @param ManagerRegistry              $mongo
103
     * @param TopicRepositoryInterface     $topicRepository
104
     * @param TextNodeRepositoryInterface  $textNodeRepository
105
     * @param LicenseeRepositoryInterface  $licenseeRepository
106
     * @param UserRepositoryInterface      $userRepository
107
     * @param LoremIpsum                   $loremIpsum
108
     * @param UserPasswordEncoderInterface $passwordEncoder
109
     * @param string                       $topicDummyImageDirectory
110
     * @param string                       $topicImageDirectory
111
     */
112 1
    public function __construct(ManagerRegistry $mongo, TopicRepositoryInterface $topicRepository, TextNodeRepositoryInterface $textNodeRepository, LicenseeRepositoryInterface $licenseeRepository, UserRepositoryInterface $userRepository, LoremIpsum $loremIpsum, UserPasswordEncoderInterface $passwordEncoder, string $topicDummyImageDirectory, string $topicImageDirectory)
113
    {
114 1
        $this->mongo = $mongo;
115 1
        $this->topicImageDirectory = $topicImageDirectory;
116 1
        $this->topicRepository = $topicRepository;
117 1
        $this->textNodeRepository = $textNodeRepository;
118 1
        $this->licenseeRepository = $licenseeRepository;
119 1
        $this->topicDummyImageDirectory = $topicDummyImageDirectory;
120 1
        $this->loremIpsum = $loremIpsum;
121 1
        $this->userRepository = $userRepository;
122 1
        $this->passwordEncoder = $passwordEncoder;
123 1
        parent::__construct();
124 1
    }
125
126
    /**
127
     * @return void
128
     *
129
     * @throws \Symfony\Component\Console\Exception\InvalidArgumentException
130
     */
131 1
    protected function configure(): void
132
    {
133
        $this
134 1
            ->setName('dembelo:install')
135 1
            ->setDescription('Installation Routine')
136 1
            ->addOption(
137 1
                'purge-db',
138 1
                null,
139 1
                InputOption::VALUE_NONE,
140 1
                'deletes all content from DB before installation'
141
            )
142 1
            ->addOption(
143 1
                'with-dummy-data',
144 1
                null,
145 1
                InputOption::VALUE_NONE,
146 1
                'installs some dummy data to play with'
147
            );
148 1
    }
149
150
    /**
151
     * @param InputInterface  $input
152
     * @param OutputInterface $output
153
     *
154
     * @return int|null|void
155
     *
156
     * @throws \Exception
157
     */
158 1
    protected function execute(InputInterface $input, OutputInterface $output)
159
    {
160 1
        if ($input->getOption('purge-db')) {
161
            $this->purgeDB();
162
            $output->writeln('<info>Database cleared</info>');
163
            $this->cleanImageDirectories();
164
            $output->writeln('<info>Directories cleared</info>');
165
        }
166
167 1
        $this->installDefaultUsers($output);
168 1
        $output->writeln('<info>Default users installed</info>');
169
170 1
        if ($input->getOption('with-dummy-data')) {
171
            $this->installDummyData($output);
172
            $output->writeln('<info>Dummy data installed</info>');
173
        }
174 1
    }
175
176
    /**
177
     * @return void
178
     */
179
    protected function purgeDB(): void
180
    {
181
        $collectionClasses = [
182
            Licensee::class,
183
            Readpath::class,
184
            Textnode::class,
185
            Topic::class,
186
            User::class,
187
        ];
188
189
        $dm = $this->mongo->getManager();
190
191
        foreach ($collectionClasses as $collectionClass) {
192
            $collection = $dm->getDocumentCollection($collectionClass);
193
            $collection->remove([]);
194
        }
195
    }
196
197
    /**
198
     * @param OutputInterface $output
199
     *
200
     * @return void
201
     *
202
     * @throws \Exception
203
     */
204 1
    protected function installDefaultUsers(OutputInterface $output): void
205
    {
206 1
        $this->installAdminUser();
207 1
        $output->writeln('admin user installed');
208 1
    }
209
210
    /**
211
     * @return void
212
     *
213
     * @throws \Exception
214
     */
215 1
    protected function installAdminUser(): void
216
    {
217
        $users = [
218
            [
219 1
                'email' => '[email protected]',
220 1
                'password' => 'dembelo',
221
                'roles' => ['ROLE_ADMIN'],
222 1
                'gender' => 'm',
223 1
                'status' => 1,
224 1
                'source' => '',
225 1
                'reason' => '',
226 1
                'metadata' => ['created' => time(), 'updated' => time()],
227
            ],
228
        ];
229
230 1
        $this->installUsers($users);
231 1
    }
232
233
    /**
234
     * @param OutputInterface $output
235
     *
236
     * @return void
237
     *
238
     * @throws \Exception
239
     */
240
    protected function installDummyData(OutputInterface $output): void
241
    {
242
        $this->createLicensees();
243
        $output->writeln('Licensees installed...');
244
245
        $this->createUsers();
246
        $output->writeln('Users installed...');
247
248
        $this->createTopics();
249
        $output->writeln('Topics installed...');
250
251
        $this->createTextnodes();
252
        $output->writeln('Textnodes installed...');
253
254
        $this->createHitches();
255
        $output->writeln('Hitches installed...');
256
    }
257
258
    /**
259
     * @return void
260
     */
261
    private function createLicensees(): void
262
    {
263
        $licensees = [
264
            ['name' => 'Lizenznehmer 1'],
265
            ['name' => 'Lizenznehmer 2'],
266
        ];
267
268
        $this->dummyData['licensees'] = [];
269
270
        foreach ($licensees as $licenseeData) {
271
            $licensee = $this->licenseeRepository->findOneByName($licenseeData['name']);
272
273
            if (null === $licensee) {
274
                $licensee = new Licensee();
275
                $licensee->setName($licenseeData['name']);
276
                $this->licenseeRepository->save($licensee);
277
            }
278
            $this->dummyData['licensees'][] = $licensee;
279
        }
280
    }
281
282
    /**
283
     * @return void
284
     *
285
     * @throws \Exception
286
     */
287
    private function createUsers(): void
288
    {
289
        $users = [
290
            [
291
                'email' => '[email protected]',
292
                'password' => 'dembelo',
293
                'roles' => ['ROLE_USER'],
294
                'gender' => 'm',
295
                'status' => 1,
296
                'source' => '',
297
                'reason' => '',
298
                'metadata' => ['created' => time(), 'updated' => time()],
299
            ],
300
            [
301
                'email' => '[email protected]',
302
                'password' => 'dembelo',
303
                'roles' => ['ROLE_LICENSEE'],
304
                'gender' => 'm',
305
                'status' => 1,
306
                'source' => '',
307
                'reason' => '',
308
                'metadata' => ['created' => time(), 'updated' => time()],
309
            ],
310
        ];
311
312
        $this->installUsers($users);
313
    }
314
315
    /**
316
     * @param array $users
317
     *
318
     * @return void
319
     *
320
     * @throws \Exception
321
     */
322 1
    private function installUsers(array $users): void
323
    {
324 1
        if (!isset($this->dummyData['users'])) {
325 1
            $this->dummyData['users'] = array();
326
        }
327
328 1
        foreach ($users as $userData) {
329 1
            $user = $this->userRepository->findOneBy(['email' => $userData['email']]);
330
331 1
            if (null === $user) {
332 1
                $user = new User();
333 1
                $user->setEmail($userData['email']);
334 1
                $password = $this->passwordEncoder->encodePassword($user, $userData['password']);
335 1
                $user->setPassword($password);
336 1
                $user->setRoles($userData['roles']);
337 1
                $user->setGender($userData['gender']);
338 1
                $user->setSource($userData['source']);
339 1
                $user->setReason($userData['reason']);
340 1
                $user->setStatus($userData['status']);
341 1
                $user->setMetadata($userData['metadata']);
342
343 1
                if (\in_array('ROLE_LICENSEE', $userData['roles'], true)) {
344
                    $user->setLicenseeId($this->dummyData['licensees'][0]->getId());
345
                }
346
347 1
                $this->userRepository->save($user);
348
            }
349
350 1
            $this->dummyData['users'][] = $user;
351
        }
352 1
    }
353
354
    /**
355
     * @return void
356
     *
357
     * @throws \RuntimeException
358
     */
359
    private function createTopics(): void
360
    {
361
        $this->dummyData['topics'] = [];
362
363
        $topicData = [
364
            ['name' => 'Themenfeld 2', 'status' => Topic::STATUS_ACTIVE],
365
            ['name' => 'Themenfeld 3', 'status' => Topic::STATUS_ACTIVE],
366
            ['name' => 'Themenfeld 4', 'status' => Topic::STATUS_ACTIVE],
367
            ['name' => 'Themenfeld 5', 'status' => Topic::STATUS_ACTIVE],
368
            ['name' => 'Themenfeld 6', 'status' => Topic::STATUS_ACTIVE],
369
            ['name' => 'Themenfeld 7', 'status' => Topic::STATUS_ACTIVE],
370
            ['name' => 'Themenfeld 8', 'status' => Topic::STATUS_ACTIVE],
371
            ['name' => 'Themenfeld 9', 'status' => Topic::STATUS_ACTIVE],
372
        ];
373
374
        $imagesSrcFolder = $this->topicDummyImageDirectory;
375
        $imagesTargetFolder = $this->topicImageDirectory;
376
377
        $sortKey = 1;
378
        foreach ($topicData as $topicDatum) {
379
            $topic = $this->topicRepository->findOneByName($topicDatum['name']);
380
            if (null === $topic) {
381
                $imagename = 'bg0'.$sortKey.'.jpg';
382
                $topic = new Topic();
383
                $topic->setName($topicDatum['name']);
384
                $topic->setStatus($topicDatum['status']);
385
                $topic->setSortKey($sortKey);
386
                $topic->setOriginalImageName($imagename);
387
                $topic->setImageFilename($imagename);
388
                $this->topicRepository->save($topic);
389
                $topicFolder = $imagesTargetFolder.'/'.$topic->getId().'/';
390
                if (!mkdir($topicFolder) && !is_dir($topicFolder)) {
391
                    throw new \RuntimeException(sprintf('Directory "%s" was not created', $topicFolder));
392
                }
393
                copy($imagesSrcFolder.$imagename, $topicFolder.'/'.$imagename);
394
                ++$sortKey;
395
            }
396
            $this->dummyData['topics'][] = $topic;
397
        }
398
    }
399
400
    /**
401
     * @return void
402
     */
403
    private function createTextnodes(): void
404
    {
405
        $loremIpsumLength = 3500;
406
407
        $allAccessNodes = $this->textNodeRepository->findBy(['access' => true]);
408
        if (count($allAccessNodes) >= 7) {
409
            return;
410
        }
411
412
        $textnodeData = [
413
            [
414
                'topic' => $this->dummyData['topics'][0],
415
                'text' => $this->loremIpsum->getWords($loremIpsumLength),
416
                'access' => true,
417
                'licensee' => $this->dummyData['licensees'][0],
418
                'metadata' => [
419
                    'Titel' => 'Titel 1',
420
                    'Autor' => 'Autor 1',
421
                    'Verlag' => 'Verlag 1',
422
                ],
423
            ],
424
            [
425
                'text' => $this->loremIpsum->getWords($loremIpsumLength),
426
                'access' => false,
427
                'licensee' => $this->dummyData['licensees'][0],
428
                'metadata' => [
429
                    'Titel' => 'Titel 2',
430
                    'Autor' => 'Autor 2',
431
                    'Verlag' => 'Verlag 2',
432
                ],
433
            ],
434
            [
435
                'text' => $this->loremIpsum->getWords($loremIpsumLength),
436
                'access' => false,
437
                'licensee' => $this->dummyData['licensees'][0],
438
                'metadata' => [
439
                    'Titel' => 'Titel 3',
440
                    'Autor' => 'Autor 3',
441
                    'Verlag' => 'Verlag 3',
442
                ],
443
            ],
444
            [
445
                'topic' => $this->dummyData['topics'][1],
446
                'text' => $this->loremIpsum->getWords($loremIpsumLength),
447
                'access' => true,
448
                'licensee' => $this->dummyData['licensees'][0],
449
                'metadata' => [
450
                    'Titel' => 'Titel 4',
451
                    'Autor' => 'Autor 4',
452
                    'Verlag' => 'Verlag 4',
453
                ],
454
            ],
455
            [
456
                'text' => $this->loremIpsum->getWords($loremIpsumLength),
457
                'access' => false,
458
                'licensee' => $this->dummyData['licensees'][0],
459
                'metadata' => [
460
                    'Titel' => 'Titel 5',
461
                    'Autor' => 'Autor 5',
462
                    'Verlag' => 'Verlag 5',
463
                ],
464
            ],
465
            [
466
                'text' => $this->loremIpsum->getWords($loremIpsumLength),
467
                'access' => false,
468
                'licensee' => $this->dummyData['licensees'][0],
469
                'metadata' => [
470
                    'Titel' => 'Titel 6',
471
                    'Autor' => 'Autor 6',
472
                    'Verlag' => 'Verlag 6',
473
                ],
474
            ],
475
        ];
476
477
        foreach ($textnodeData as $textnodeDatum) {
478
            $textnode = new Textnode();
479
            $textnode->setStatus(Textnode::STATUS_ACTIVE);
480
            if (isset($textnodeDatum['topic'])) {
481
                $textnode->setTopicId($textnodeDatum['topic']->getId());
482
            }
483
            if (isset($textnodeDatum['licensee'])) {
484
                $textnode->setLicenseeId($textnodeDatum['licensee']->getId());
485
            }
486
            $textnode->setCreated(date('Y-m-d H:i:s'));
487
            $textnode->setText($textnodeDatum['text']);
488
            $textnode->setAccess($textnodeDatum['access']);
489
            $textnode->setMetadata($textnodeDatum['metadata']);
490
            $this->textNodeRepository->save($textnode);
491
492
            $this->dummyData['textnodes'][] = $textnode;
493
        }
494
    }
495
496
    /**
497
     * @return void
498
     */
499
    private function createHitches(): void
500
    {
501
        if (isset($this->dummyData['textnodes']) !== true) {
502
            return;
503
        }
504
505
        /* @var $dummyTextnodes Textnode[] */
506
        $dummyTextnodes = $this->dummyData['textnodes'];
507
508
        if (count($dummyTextnodes) < 3) {
509
            return;
510
        }
511
512
        if ($dummyTextnodes[0]->getChildHitchCount() >= 2) {
0 ignored issues
show
Bug introduced by
The method getChildHitchCount() does not exist on DembeloMain\Document\Textnode. Did you maybe mean getChildHitches()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

512
        if ($dummyTextnodes[0]->/** @scrutinizer ignore-call */ getChildHitchCount() >= 2) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
513
            return;
514
        }
515
516
        $hitch = [];
517
        $hitch['textnodeId'] = $dummyTextnodes[1]->getId();
518
        $hitch['description'] = 'Mehr Lorem.';
519
        $hitch['status'] = TextnodeHitch::STATUS_ACTIVE;
520
        $dummyTextnodes[0]->appendHitch($hitch);
0 ignored issues
show
Bug introduced by
The method appendHitch() does not exist on DembeloMain\Document\Textnode. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

520
        $dummyTextnodes[0]->/** @scrutinizer ignore-call */ 
521
                            appendHitch($hitch);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
521
        $this->textNodeRepository->save($this->dummyData['textnodes'][0]);
522
523
        $hitch = [];
524
        $hitch['textnodeId'] = $dummyTextnodes[2]->getId();
525
        $hitch['description'] = 'Mehr Ipsum.';
526
        $hitch['status'] = TextnodeHitch::STATUS_ACTIVE;
527
        $dummyTextnodes[0]->appendHitch($hitch);
528
529
        $this->textNodeRepository->save($dummyTextnodes[0]);
530
    }
531
532
    /**
533
     * @return void
534
     */
535
    private function cleanImageDirectories(): void
536
    {
537
        $topicImageDirectory = $this->topicImageDirectory.'/';
538
        if (is_dir($topicImageDirectory)) {
539
            shell_exec('rm -r '.$topicImageDirectory.'*');
540
        }
541
    }
542
}
543