AddCommand::addPosts()   B
last analyzed

Complexity

Conditions 7
Paths 14

Size

Total Lines 35
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 24
nc 14
nop 1
dl 0
loc 35
rs 8.6026
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Command\Fixture;
6
7
use App\Blog\Entity\Comment;
8
use App\Blog\Entity\Post;
9
use App\Blog\Entity\Tag;
10
use App\Blog\Tag\TagRepository;
11
use App\User\User;
12
use Cycle\ORM\EntityManager;
0 ignored issues
show
Bug introduced by
The type Cycle\ORM\EntityManager 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...
13
use DateTimeImmutable;
14
use Exception;
15
use Faker\Factory;
0 ignored issues
show
Bug introduced by
The type Faker\Factory 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...
16
use Faker\Generator;
0 ignored issues
show
Bug introduced by
The type Faker\Generator 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...
17
use Psr\Log\LoggerInterface;
0 ignored issues
show
Bug introduced by
The type Psr\Log\LoggerInterface 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...
18
use Symfony\Component\Console\Command\Command;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Command\Command 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...
19
use Symfony\Component\Console\Input\InputArgument;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Input\InputArgument 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
use Symfony\Component\Console\Input\InputInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Input\InputInterface 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...
21
use Symfony\Component\Console\Output\OutputInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Output\OutputInterface 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...
22
use Symfony\Component\Console\Style\SymfonyStyle;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Style\SymfonyStyle 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...
23
use Throwable;
24
use Yiisoft\Data\Cycle\Writer\EntityWriter;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Data\Cycle\Writer\EntityWriter 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...
25
use Yiisoft\Yii\Console\ExitCode;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Yii\Console\ExitCode 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...
26
use Yiisoft\Yii\Cycle\Command\CycleDependencyProxy;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Yii\Cycle\Command\CycleDependencyProxy 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...
27
28
final class AddCommand extends Command
29
{
30
    protected static $defaultName = 'fixture/add';
31
32
    private Generator $faker;
33
    /** @var User[] */
34
    private array $users = [];
35
    /** @var Tag[] */
36
    private array $tags = [];
37
38
    private const DEFAULT_COUNT = 10;
39
40
    public function __construct(
41
        private CycleDependencyProxy $promise,
42
        private EntityManager $entityManager,
43
        private readonly LoggerInterface $logger,
44
    ) {
45
        parent::__construct();
46
    }
47
48
    public function configure(): void
49
    {
50
        $this
51
            ->setDescription('Add fixtures')
52
            ->setHelp('This command adds random content')
53
            ->addArgument('count', InputArgument::OPTIONAL, 'Count', self::DEFAULT_COUNT);
54
    }
55
56
    protected function execute(InputInterface $input, OutputInterface $output): int
57
    {
58
        $io = new SymfonyStyle($input, $output);
59
60
        $count = (int) $input->getArgument('count');
61
        // get faker
62
        if (!class_exists(Factory::class)) {
63
            $io->error('Faker should be installed. Run `composer install --dev`');
64
65
            return ExitCode::UNSPECIFIED_ERROR;
66
        }
67
        $this->faker = Factory::create();
68
69
        try {
70
            $this->addUsers($count);
71
            $this->addTags($count);
72
            $this->addPosts($count);
73
74
            $this->saveEntities();
75
        } catch (Throwable $t) {
76
            $io->error($t->getMessage());
77
            $this->logger->error($t->getMessage(), ['exception' => $t]);
78
79
            return $t->getCode() ?: ExitCode::UNSPECIFIED_ERROR;
80
        }
81
        $io->success('Done');
82
83
        return ExitCode::OK;
84
    }
85
86
    private function saveEntities(): void
87
    {
88
        (new EntityWriter($this->entityManager))->write($this->users);
89
    }
90
91
    private function addUsers(int $count): void
92
    {
93
        for ($i = 0; $i < $count; $i++) {
94
            $login = $this->faker->unique()->firstName;
95
            $user = new User($login, $login);
96
            $this->users[] = $user;
97
        }
98
    }
99
100
    private function addTags(int $count): void
101
    {
102
        /** @var TagRepository $tagRepository */
103
        $tagRepository = $this->promise
104
            ->getORM()
105
            ->getRepository(Tag::class);
106
        $this->tags = [];
107
        $tagWords = [];
108
        for ($i = 0, $fails = 0; $i < $count; $i++) {
109
            $word = $this->faker->word();
110
            if (in_array($word, $tagWords, true)) {
111
                $i--;
112
                $fails++;
113
                if ($fails >= $count) {
114
                    break;
115
                }
116
                continue;
117
            }
118
            $tagWords[] = $word;
119
            $tag = $tagRepository->getOrCreate($word);
120
            $this->tags[] = $tag;
121
        }
122
    }
123
124
    private function addPosts(int $count): void
125
    {
126
        if (empty($this->users)) {
127
            throw new Exception('No users');
128
        }
129
        for ($i = 0; $i < $count; $i++) {
130
            /** @var User $postUser */
131
            $postUser = $this->users[array_rand($this->users)];
132
            $post = new Post($this->faker->text(64), $this->faker->realText(random_int(1000, 4000)));
133
            $postUser->addPost($post);
134
            $public = random_int(0, 2) > 0;
135
            $post->setPublic($public);
136
            if ($public) {
137
                $post->setPublishedAt(new DateTimeImmutable(date('r', random_int(strtotime('-2 years'), time()))));
138
            }
139
            // link tags
140
            $postTags = (array) array_rand($this->tags, random_int(1, count($this->tags)));
141
            foreach ($postTags as $tagId) {
142
                $tag = $this->tags[$tagId];
143
                $post->addTag($tag);
144
                // todo: uncomment when issue is resolved https://github.com/cycle/orm/issues/70
145
                // $tag->addPost($post);
146
            }
147
            // add comments
148
            $commentsCount = random_int(0, $count);
149
            for ($j = 0; $j <= $commentsCount; $j++) {
150
                $comment = new Comment($this->faker->realText(random_int(100, 500)));
151
                $commentPublic = random_int(0, 3) > 0;
152
                $comment->setPublic($commentPublic);
153
                if ($commentPublic) {
154
                    $comment->setPublishedAt(new DateTimeImmutable(date('r', random_int(strtotime('-1 years'), time()))));
155
                }
156
                $commentUser = $this->users[array_rand($this->users)];
157
                $commentUser->addComment($comment);
158
                $comment->setPost($post);
159
            }
160
        }
161
    }
162
}
163