RulesLoaderCommand::execute()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3.0052

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 11
c 2
b 0
f 0
nc 3
nop 2
dl 0
loc 16
ccs 11
cts 12
cp 0.9167
crap 3.0052
rs 9.9
1
<?php
2
3
namespace Obblm\Core\Command;
4
5
use Obblm\Core\Entity\Rule;
6
use Doctrine\ORM\EntityManagerInterface;
7
use Obblm\Core\Helper\CoreTranslation;
8
use Obblm\Core\Helper\Rule\Config\ConfigResolver;
9
use Obblm\Core\Helper\Rule\Config\RuleConfigResolver;
10
use Symfony\Component\Console\Command\Command;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Symfony\Component\Console\Style\SymfonyStyle;
14
use Symfony\Component\Finder\Finder;
15
use Symfony\Component\Finder\SplFileInfo;
16
use Symfony\Component\OptionsResolver\Exception\InvalidArgumentException;
17
use Symfony\Component\Yaml\Yaml;
18
19
class RulesLoaderCommand extends Command
20
{
21
    /** @var string */
22
    protected static $defaultName = 'obblm:rules:load';
23
    /** @var string */
24
    protected $rulesDirectory = 'datas/rules';
25
    /** @var EntityManagerInterface */
26
    private $em;
27
    /** @var SymfonyStyle */
28
    private $io;
29
30 1
    public function __construct(EntityManagerInterface $em)
31
    {
32 1
        $this->em = $em;
33 1
        $this->rulesDirectory = dirname(__DIR__) . '/Resources/datas/rules';
34 1
        parent::__construct();
35 1
    }
36
37 1
    protected function configure():void
38
    {
39 1
        $this->setDescription('Loads Blood Bowl core rules.')
40 1
            ->setHelp('This command will add core Blood Bowl rules to the database.');
41 1
    }
42
43 1
    protected function execute(InputInterface $input, OutputInterface $output)
44
    {
45 1
        $this->io = new SymfonyStyle($input, $output);
46 1
        $finder = new Finder();
47 1
        $this->io->title("Importing pre fetched rules from " . $this->rulesDirectory);
48 1
        $finder->directories()->ignoreDotFiles(true)->depth(0)->in($this->rulesDirectory);
49 1
        if ($finder->hasResults()) {
50 1
            foreach ($finder as $ruleDirectory) {
51 1
                $this->parseRule($ruleDirectory);
52
            }
53 1
            $this->em->flush();
54 1
            $this->io->success('All rules have been created or updated.');
55 1
            return 0;
56
        }
57
58
        return 1;
59
    }
60
61 1
    protected function parseRule(SplFileInfo $ruleDirectory):void
62
    {
63 1
        $rules = [];
64 1
        $key = $ruleDirectory->getFilename();
65
66 1
        $directory = str_replace(dirname(__DIR__), '', $ruleDirectory->getPathname());
67
68 1
        $this->io->block("Importing {$key} rules form {$directory}");
69 1
        $finder = new Finder();
70 1
        $finder->files()->ignoreDotFiles(true)->name(['*.yaml', '*.yml'])->in($ruleDirectory->getPathname());
71 1
        if ($finder->hasResults()) {
72 1
            $this->io->progressStart($finder->count());
73 1
            foreach ($finder as $file) {
74 1
                $content = Yaml::parseFile($file->getPathname());
75 1
                $rules = array_merge_recursive($rules, $content);
76 1
                $this->io->progressAdvance(1);
77
            }
78 1
            if (!isset($rules['rules'][$key])) {
79
                $this->io->error("The rules.{$key} rule does not exist in {$ruleDirectory->getPathname()} directory.");
80
            }
81 1
            $ruleArray = $rules['rules'][$key];
82
83
            try {
84 1
                $treeResolver = new ConfigResolver(new RuleConfigResolver());
85 1
                $ruleArray = $treeResolver->resolve($ruleArray);
86
87
                /** @var Rule|null $rule */
88 1
                $rule = $this->em->getRepository(Rule::class)->findOneBy(['ruleKey' => $key]);
89 1
                if (!$rule) {
90 1
                    $rule = (new Rule())
91 1
                        ->setRuleKey($key)
92 1
                        ->setReadOnly(true);
93
                }
94 1
                ksort($ruleArray['rosters']);
95 1
                $rule->setName(CoreTranslation::getRuleTitle($key))
96 1
                    ->setRuleDirectory($directory)
97 1
                    ->setPostBb2020($ruleArray['post_bb_2020'] ?? false)
98 1
                    ->setTemplate($ruleArray['template'] ?? 'base')
99 1
                    ->setRule($ruleArray);
100 1
                $this->em->persist($rule);
101 1
                $this->io->progressFinish();
102
            } catch (InvalidArgumentException $e) {
103
                $this->io->progressFinish();
104
                $this->io->error("The rule.{$key} is not valid, resolver said :\n{$e->getMessage()}");
105
            }
106 1
            return;
107
        }
108
        $this->io->warning("There is no rule files in {$ruleDirectory->getPathname()} directory.");
109
        return;
110
    }
111
}
112