Test Failed
Push — master ( ff69f6...dcdcb3 )
by Chauncey
10:36
created

ConditionalizableTrait::resolveConditionalLogic()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.6026
c 0
b 0
f 0
cc 7
nc 6
nop 1
1
<?php
2
3
namespace Charcoal\Ui;
4
5
use InvalidArgumentException;
6
7
// From 'charcoal-view'
8
use Charcoal\View\ViewableInterface;
9
use Charcoal\View\ViewInterface;
10
11
/**
12
 * Provides an entity with a condition.
13
 *
14
 * Implementation of {@see \Charcoal\Ui\ConditionalizableInterface}
15
 */
16
trait ConditionalizableTrait
17
{
18
    /**
19
     * Condition needed to render the entity.
20
     *
21
     * @var string|boolean
22
     */
23
    private $condition;
24
25
    /**
26
     * rendered condition.
27
     *
28
     * @var string|boolean
29
     */
30
    private $resolvedCondition;
31
32
    /**
33
     * @return boolean
34
     */
35
    public function resolvedCondition()
36
    {
37
        if (!isset($this->resolvedCondition)) {
38
            if (!isset($this->condition)) {
39
                $this->resolvedCondition = true;
40
            } else {
41
                $this->resolvedCondition = $this->parseConditionalLogic(
42
                    $this->condition()
43
                );
44
            }
45
        }
46
47
        return $this->resolvedCondition;
48
    }
49
50
    /**
51
     * @return boolean|string
52
     */
53
    public function condition()
54
    {
55
        return $this->condition;
56
    }
57
58
    /**
59
     * @param boolean|string $condition A condition to evaluate.
60
     * @throws InvalidArgumentException If the condition is not a string nor boolean.
61
     * @return self
62
     */
63
    public function setCondition($condition)
64
    {
65
        if (!is_bool($condition) && !is_string($condition)) {
66
            throw new InvalidArgumentException(
67
                'Condition must be a string or boolean'
68
            );
69
        }
70
71
        unset($this->resolvedCondition);
72
        $this->condition = $condition;
73
        return $this;
74
    }
75
76
    /**
77
     * Resolve the conditional logic.
78
     *
79
     * @param  mixed $condition The condition.
80
     * @return boolean|null
81
     */
82
    final protected function parseConditionalLogic($condition)
83
    {
84
        if ($condition === null) {
85
            return null;
86
        }
87
88
        if (is_bool($condition)) {
89
            return $condition;
90
        }
91
92
        $not = false;
93
        if (is_string($condition)) {
94
            $not = ($condition[0] === '!');
95
            if ($not) {
96
                $condition = ltrim($condition, '!');
97
            }
98
        }
99
100
        $result = $this->resolveConditionalLogic($condition);
101
102
        return (($not === true) ? !$result : $result);
103
    }
104
105
    /**
106
     * Parse the widget's conditional logic.
107
     *
108
     * @param  callable|string $condition The callable or renderable condition.
109
     * @return boolean
110
     */
111
    protected function resolveConditionalLogic($condition)
112
    {
113
        if (is_callable([ $this, $condition ])) {
114
            return !!$this->{$condition}();
115
        }
116
117
        if (is_callable($condition)) {
118
            return !!$condition();
119
        }
120
121
        if (is_callable([ $this, 'form' ])) {
122
            $form = $this->form();
0 ignored issues
show
Bug introduced by
It seems like form() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
123
124
            if (is_callable([ $form, 'obj' ])) {
125
                $obj = $form->obj();
126
127
                if (($obj instanceof ViewableInterface) && ($obj->view() instanceof ViewInterface)) {
128
                    return !!$obj->renderTemplate($condition);
129
                }
130
            }
131
        }
132
133
        return !!$condition;
134
    }
135
}
136