Completed
Push — master ( 3a917b...8faa80 )
by Alexander
15s queued 12s
created

AddCommand   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 1
Metric Value
wmc 21
eloc 78
c 2
b 1
f 1
dl 0
loc 131
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A saveEntities() 0 7 2
A configure() 0 6 1
A __construct() 0 4 1
A execute() 0 24 4
A addUsers() 0 6 2
A addTags() 0 19 4
B addPosts() 0 38 7
1
<?php
2
3
namespace App\Command\Fixture;
4
5
use App\Blog\Entity\Comment;
6
use App\Blog\Entity\Post;
7
use App\Blog\Entity\Tag;
8
use App\Entity\User;
9
use App\Blog\Tag\TagRepository;
10
use Cycle\ORM\Transaction;
11
use Faker\Factory;
12
use Faker\Generator;
13
use Symfony\Component\Console\Command\Command;
14
use Symfony\Component\Console\Input\InputArgument;
15
use Symfony\Component\Console\Input\InputInterface;
16
use Symfony\Component\Console\Output\OutputInterface;
17
use Symfony\Component\Console\Style\SymfonyStyle;
18
use Yiisoft\Yii\Console\ExitCode;
19
use Yiisoft\Yii\Cycle\Command\CycleDependencyPromise;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Yii\Cycle\Command\CycleDependencyPromise was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
21
class AddCommand extends Command
22
{
23
    protected static $defaultName = 'fixture/add';
24
25
    private CycleDependencyPromise $promise;
26
    private Generator $faker;
27
    /** @var User[] */
28
    private array $users = [];
29
    /** @var Tag[] */
30
    private array $tags = [];
31
32
    private const DEFAULT_COUNT = 10;
33
34
    public function __construct(CycleDependencyPromise $promise)
35
    {
36
        $this->promise = $promise;
37
        parent::__construct();
38
    }
39
40
    public function configure(): void
41
    {
42
        $this
43
            ->setDescription('Add fixtures')
44
            ->setHelp('This command adds random content')
45
            ->addArgument('count', InputArgument::OPTIONAL, 'Count', self::DEFAULT_COUNT);
46
    }
47
48
    protected function execute(InputInterface $input, OutputInterface $output): int
49
    {
50
        $io = new SymfonyStyle($input, $output);
51
52
        $count = (int)$input->getArgument('count');
53
        // get faker
54
        if (!class_exists(Factory::class)) {
55
            $io->error('Faker should be installed. Run `composer install --dev`');
56
            return ExitCode::UNSPECIFIED_ERROR;
57
        }
58
        $this->faker = Factory::create();
59
60
        try {
61
            $this->addUsers($count);
62
            $this->addTags($count);
63
            $this->addPosts($count);
64
65
            $this->saveEntities();
66
        } catch (\Throwable $t) {
67
            $io->error($t->getMessage());
68
            return $t->getCode() ?: ExitCode::UNSPECIFIED_ERROR;
69
        }
70
        $io->success('Done');
71
        return ExitCode::OK;
72
    }
73
74
    private function saveEntities(): void
75
    {
76
        $transaction = new Transaction($this->promise->getORM());
77
        foreach ($this->users as $user) {
78
            $transaction->persist($user);
79
        }
80
        $transaction->run();
81
    }
82
83
    private function addUsers(int $count): void
84
    {
85
        for ($i = 0; $i <= $count; ++$i) {
86
            $login = $this->faker->firstName . rand(0, 9999);
87
            $user = new User($login, $login);
88
            $this->users[] = $user;
89
        }
90
    }
91
92
    private function addTags(int $count): void
93
    {
94
        /** @var TagRepository $tagRepository */
95
        $tagRepository = $this->promise->getORM()->getRepository(Tag::class);
96
        $this->tags = [];
97
        $tagWords = [];
98
        for ($i = 0, $fails = 0; $i <= $count; ++$i) {
99
            $word = $this->faker->word();
100
            if (in_array($word, $tagWords, true)) {
101
                --$i;
102
                ++$fails;
103
                if ($fails >= $count) {
104
                    break;
105
                }
106
                continue;
107
            }
108
            $tagWords[] = $word;
109
            $tag = $tagRepository->getOrCreate($word);
110
            $this->tags[] = $tag;
111
        }
112
    }
113
114
    private function addPosts(int $count): void
115
    {
116
        if (count($this->users) === 0) {
117
            throw new \Exception('No users');
118
        }
119
        for ($i = 0; $i <= $count; ++$i) {
120
            /** @var User $postUser */
121
            $postUser = $this->users[array_rand($this->users)];
122
            $post = new Post($this->faker->text(64), $this->faker->realText(rand(1000, 4000)));
123
            $post->setUser($postUser);
124
            $postUser->addPost($post);
125
            $public = rand(0, 2) > 0;
126
            $post->setPublic($public);
127
            if ($public) {
128
                $post->setPublishedAt(new \DateTimeImmutable(date('r', rand(time(), strtotime('-2 years')))));
129
            }
130
            // link tags
131
            $postTags = (array)array_rand($this->tags, rand(1, count($this->tags)));
132
            foreach ($postTags as $tagId) {
133
                $tag = $this->tags[$tagId];
134
                $post->addTag($tag);
135
                // todo: uncomment when issue is resolved https://github.com/cycle/orm/issues/70
136
                // $tag->addPost($post);
137
            }
138
            // add comments
139
            $commentsCount = rand(0, $count);
140
            for ($j = 0; $j <= $commentsCount; ++$j) {
141
                $comment = new Comment($this->faker->realText(rand(100, 500)));
142
                $commentPublic = rand(0, 3) > 0;
143
                $comment->setPublic($commentPublic);
144
                if ($commentPublic) {
145
                    $comment->setPublishedAt(new \DateTimeImmutable(date('r', rand(time(), strtotime('-1 years')))));
146
                }
147
                $commentUser = $this->users[array_rand($this->users)];
148
                $comment->setUser($commentUser);
149
                $commentUser->addComment($comment);
150
                $post->addComment($comment);
151
                $comment->setPost($post);
152
            }
153
        }
154
    }
155
}
156