Completed
Branch v1.x-dev (5736e4)
by Benjamin
04:09
created

AbstractInducementRuleTrait::getInducements()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
namespace Obblm\Core\Helper\Rule\Traits;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\Common\Collections\Criteria;
7
use Doctrine\Common\Collections\Expr\CompositeExpression;
8
use Doctrine\Common\Collections\Expr\Expression;
9
use Obblm\Core\Contracts\InducementInterface;
10
use Obblm\Core\Entity\Team;
11
use Obblm\Core\Exception\InvalidArgumentException;
12
use Obblm\Core\Exception\NotFoundRuleKeyExcepion;
13
use Obblm\Core\Helper\CoreTranslation;
14
use Obblm\Core\Helper\Rule\Inducement\Inducement;
15
16
/*********************
17
 * INDUCEMENT METHODS
18
 ********************/
19
trait AbstractInducementRuleTrait
20
{
21
    abstract public function getInducementTable():ArrayCollection;
22
23 1
    private function getInducementExpression($options):CompositeExpression
24
    {
25 1
        $expressions = [];
26 1
        if (isset($options['type'])) {
27
            // Criteria by inducement type
28 1
            $expressions['type'] = $this->getTypeExpression($options);
29
        }
30 1
        if (isset($options['cost_limit'])) {
31
            // Criteria by cost limit
32
            $expressions['cost'] = $this->getBudgetExpression($options);
33
        }
34 1
        if (isset($options['roster'])) {
35
            // Criteria by roster
36
            $expressions['roster'] = $this->getRosterExpression($options);
37
        }
38 1
        return new CompositeExpression(CompositeExpression::TYPE_AND, $expressions);
39
    }
40
41 1
    private function getTypeExpression($options):Expression
42
    {
43 1
        if (isset($options['type'])) {
44
            // Criteria by inducement type
45 1
            if (is_array($options['type'])) {
46
                $types = [];
47
                foreach ($options['type'] as $type) {
48
                    if (is_string($type)) {
49
                        $inducementType = $this->getInducementType($type);
0 ignored issues
show
Bug introduced by
The method getInducementType() does not exist on Obblm\Core\Helper\Rule\T...ractInducementRuleTrait. Did you maybe mean getInducementTable()? ( Ignorable by Annotation )

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

49
                        /** @scrutinizer ignore-call */ 
50
                        $inducementType = $this->getInducementType($type);

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...
50
                        $types[] = Criteria::expr()->eq('type', $inducementType);
51
                    }
52
                }
53
                return new CompositeExpression(CompositeExpression::TYPE_OR, $types);
54 1
            } elseif (is_string($options['type'])) {
55 1
                $inducementType = $this->getInducementType($options['type']);
56 1
                return Criteria::expr()->eq('type', $inducementType);
57
            }
58
            throw new InvalidArgumentException('"type" option is not an array or a string');
59
        }
60
        throw new InvalidArgumentException('"type" option must be defined');
61
    }
62
63
    private function getRosterExpression($options):Expression
64
    {
65
        if (isset($options['roster']) && is_string($options['roster'])) {
66
            // Criteria by roster
67
            return Criteria::expr()->orX(
68
                Criteria::expr()->memberOf('rosters', $options['roster']),
69
                Criteria::expr()->eq('rosters', [])
70
            );
71
        }
72
        throw new InvalidArgumentException('"roster" option must be defined');
73
    }
74
75
    private function getBudgetExpression($options):Expression
76
    {
77
        if (isset($options['cost_limit']) && is_int($options['cost_limit'])) {
78
            // Criteria by cost limit
79
            return Criteria::expr()->lte('value', $options['cost_limit']);
80
        }
81
        throw new InvalidArgumentException('"cost_limit" option must be defined');
82
    }
83
84 1
    public function getInducements():ArrayCollection
85
    {
86 1
        $criteria = Criteria::create()
87 1
            ->where($this->getInducementExpression(['type' => 'inducements']));
88 1
        return $this->getInducementTable()->matching($criteria);
89
    }
90
91 1
    public function getStarPlayers():ArrayCollection
92
    {
93 1
        $criteria = Criteria::create()
94 1
            ->where($this->getInducementExpression(['type' => 'star_players']));
95 1
        return $this->getInducementTable()->matching($criteria);
96
    }
97
98
    public function getInducementsFor(Team $team, ?int $budget = null):ArrayCollection
99
    {
100
        $criteria = Criteria::create();
101
        $expr = [
102
            'type' => [
103
                'inducements',
104
                'star_players'
105
            ],
106
            'roster' => $team->getRoster()
107
        ];
108
        if ($budget !== null) {
109
            $expr['cost_limit'] = $budget;
110
        }
111
        $criteria->where(Criteria::expr()->andX(
112
            $this->getInducementExpression($expr)
113
        ));
114
        $availableInducements = $this->getInducementTable()->matching($criteria);
115
        return $availableInducements->toArray();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $availableInducements->toArray() returns the type array which is incompatible with the type-hinted return Doctrine\Common\Collections\ArrayCollection.
Loading history...
116
    }
117
118
    public function getInducementsByTeamOptions(array $options):array
119
    {
120
        $inducements = [];
121
        $ruleKey = $this->getAttachedRule()->getRuleKey();
0 ignored issues
show
Bug introduced by
It seems like getAttachedRule() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

121
        $ruleKey = $this->/** @scrutinizer ignore-call */ getAttachedRule()->getRuleKey();
Loading history...
122
        $availableInducements = $this->rule['inducements'];
123
124
        foreach ($availableInducements as $key => $value) {
125
            if ($key !== 'star_players') {
126
                if ($options[$key]) {
127
                    $inducement = [
128
                        'type' => $this->getInducementType('inducements'),
129
                        'key' => join(CoreTranslation::TRANSLATION_GLUE, [$ruleKey, 'inducements', $key]),
130
                        'translation_domain' => $this->getAttachedRule()->getRuleKey(),
131
                        'translation_key' => CoreTranslation::getInducementName($ruleKey, $key),
132
                        'max' => $value['max'] ?? 0,
133
                        'value' => ($options[$key] === 'discount') ? $value['discounted_cost'] : $value['cost'],
134
                    ];
135
                    $inducements[] = new Inducement($inducement);
136
                }
137
            }
138
        }
139
        return $inducements;
140
    }
141
142
    public function getMaxStarPlayers():int
143
    {
144
        return $this->rule['inducements']['star_players']['max'];
145
    }
146
147
    public function getStarPlayer(string $key):InducementInterface
148
    {
149
        if (!$this->getStarPlayers()->containsKey($key)) {
150
            throw new NotFoundRuleKeyExcepion($key);
151
        }
152
        return $this->getStarPlayers()->get($key);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getStarPlayers()->get($key) could return the type null which is incompatible with the type-hinted return Obblm\Core\Contracts\InducementInterface. Consider adding an additional type-check to rule them out.
Loading history...
153
    }
154
155
    public function getAvailableStarPlayers(Team $team):array
156
    {
157
        $criteria = Criteria::create();
158
        $criteria->where(Criteria::expr()->andX(
159
            $this->getInducementExpression([
160
                'type' => 'star_players',
161
                'roster' => $team->getRoster()
162
            ])
163
        ));
164
        return $this->getInducementTable()->matching($criteria)->toArray();
165
    }
166
}
167