Completed
Push — master ( 389cae...29b40e )
by Richard
06:27
created

RuleDefinitionRT   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 199
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 7

Test Coverage

Coverage 97.18%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 20
c 4
b 0
f 0
lcom 3
cbo 7
dl 0
loc 199
ccs 69
cts 71
cp 0.9718
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 17 1
A configuration() 0 10 3
A ruleset() 0 5 1
A variable() 0 12 2
A only() 0 5 1
A maybe_save_current_var() 0 12 3
A get_current_var_name() 0 4 1
A get_current_var() 0 4 1
A get_var() 0 4 1
A current_var_is() 0 4 1
A throw_on_missing_var() 0 5 2
A add_rule() 0 3 1
A get_schema() 0 7 2
1
<?php
2
/******************************************************************************
3
 * An implementation of dicto (scg.unibe.ch/dicto) in and for PHP.
4
 * 
5
 * Copyright (c) 2016 Richard Klees <[email protected]>
6
 *
7
 * This software is licensed under The MIT License. You should have received 
8
 * a copy of the licence along with the code.
9
 */
10
11
namespace Lechimp\Dicto\Definition;
12
13
use Lechimp\Dicto\Rules\Schema;
14
use Lechimp\Dicto\Rules\Invoke;
15
use Lechimp\Dicto\Rules\DependOn;
16
use Lechimp\Dicto\Rules\ContainText;
17
use Lechimp\Dicto\Rules\Rule;
18
use Lechimp\Dicto\Variables\Variable;
19
20
/**
21
 * Runtime for one rule definition. A rule definition starts with
22
 * Dicto::startDefinition() and ends with Dicto::endDefinition().
23
 * This class provides the functionality that is accessed via the
24
 * Dicto class during the definition.
25
 */
26
class RuleDefinitionRT {
27
    /**
28
     * @var array   $name => $definition
29
     */
30
    private $vars;
31
32
    /**
33
     * ToDo: I think, this is not necessary and current_var is sufficient.
34
     *
35
     * @var string|null
36
     */
37
    private $current_var_name;
38
39
    /**
40
     * @var Variables\Variable|null
41
     */
42
    private $current_var;
43
44
    /**
45
     * @var Rules\Rule[]
46
     */
47
    private $rules;
48
49
    /**
50
     * @var array|null
51
     */
52
    private $config;
53
54
    /**
55
     * @var Schema[]
56
     */
57
    private $known_schemas;
58
59 287
    public function __construct() {
60 287
        $this->vars = array();
61 287
        $this->current_var_name = null;
62 287
        $this->current_var = null;
63 287
        $this->rules = array();
64 287
        $this->config = null;
65
        // TODO: This needs to go somewhere else and must be more dynamic.
66 287
        $d = new DependOn();
67 287
        $i = new Invoke();
68 287
        $c = new ContainText();
69
        // TODO: There need to be checks on the name then as well.
70 287
        $this->known_schemas = array
0 ignored issues
show
Documentation Bug introduced by
It seems like array($d->name() => $d, ...> $i, $c->name() => $c) of type array<string,object<Lech...cto\Rules\ContainText>> is incompatible with the declared type array<integer,object<Lechimp\Dicto\Rules\Schema>> of property $known_schemas.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
71 287
            ( $d->name() => $d
72 287
            , $i->name() => $i
73 287
            , $c->name() => $c
74 287
            );
75 287
    }
76
77
    /**
78
     * Set a configuration to be used with the rules.
79
     *
80
     * @param   array|null  $config
81
     * @return  null|array
82
     */
83 281
    public function configuration(array $config = null) {
84 281
        if ($config === null) {
85 281
            return $this->config;
86
        }
87
88 3
        if ($this->config !== null) {
89
            throw new \RuntimeException("Already set configuration.");
90
        }
91 3
        $this->config = $config;
92 3
    }
93
94
    /**
95
     * Get the rule set that was currently created.
96
     *
97
     * @return  Ruleset
98
     */
99 281
    public function ruleset() {
100 281
        $this->maybe_save_current_var();
101
102 281
        return new Ruleset($this->vars, $this->rules);
103
    }
104
105
    /**
106
     * Define a new variable or reference an already defined variable to define
107
     * a rule.
108
     *
109
     * @throws  \RuntimeException   if previous variable declaration was not finished
110
     * @return  NewVar|RuleVar
111
     */
112 282
    public function variable($name) {
113 282
        $this->maybe_save_current_var();
114
115 282
        if (!array_key_exists($name, $this->vars)) {
116 282
            $this->current_var_name = $name;
117 282
            return new Fluid\NewVar($this);
118
        }
119
        else {
120 151
            $this->throw_on_missing_var($name);
121 151
            return new Fluid\RuleVar($this, $name);
122
        }
123
    }
124
125
    /**
126
     * Define a only-rule.
127
     *
128
     * @return  Fluid\Only
129
     */
130 36
    public function only() {
131 36
        $this->maybe_save_current_var();
132
133 36
        return new Fluid\Only($this);
134
    }
135
136
    /**
137
     * Save the currently defined variable, if there is any.
138
     *
139
     * @throws  \RuntimeException   if previous variable declaration was not finished
140
     */
141 285
    protected function maybe_save_current_var() {
142 285
        if ($this->current_var_name !== null) {
143 280
            if ($this->current_var === null) {
144 1
                throw new \RuntimeException(
145 1
                        "The declaration of ".$this->current_var_name.
146 1
                        " was not finished.");
147
            }
148 279
            $this->vars[$this->current_var_name] = $this->current_var;
149 279
            $this->current_var_name = null;
150 279
            $this->current_var = null;
151 279
        }
152 285
    }
153
154
    /**
155
     * Get the name of the current var.
156
     *
157
     * @return  string
158
     */
159 280
    public function get_current_var_name() {
160 280
        assert('is_string($this->current_var_name)');
161 280
        return $this->current_var_name;
162
    }
163
164
    /**
165
     * Get the name of the current var.
166
     *
167
     * @return  Variables\Variable
168
     */
169 82
    public function get_current_var() {
170 82
        assert('$this->current_var !== null');
171 82
        return $this->current_var;
172
    }
173
174
    /**
175
     * Get an already defined variable.
176
     *
177
     * @param   string  $name
178
     * @return  Variables\Variable
179
     */
180 261
    public function get_var($name) {
181 261
        assert('array_key_exists($name, $this->vars)');
182 261
        return $this->vars[$name];
183
    }
184
185
    /**
186
     * Announce what the current variable is atm.
187
     *
188
     * @param   Variables\Variable  $var
189
     */
190 280
    public function current_var_is(Variable $var) {
191 280
        assert('$this->current_var_name !== null');
192 280
        $this->current_var = $var;
0 ignored issues
show
Documentation Bug introduced by
It seems like $var of type object<Lechimp\Dicto\Variables\Variable> is incompatible with the declared type object<Lechimp\Dicto\Def...ariables\Variable>|null of property $current_var.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
193 280
    }
194
195
    /**
196
     * Throws a RuntimeException on missing variable $var.
197
     */
198 262
    public function throw_on_missing_var($var) {
199 262
        if (!array_key_exists($var, $this->vars)) {
200 1
            throw new \RuntimeException("Missing variable $var");
201
        }
202 261
    }
203
204
    /**
205
     * Add a rule to the set.
206
     */
207 186
    public function add_rule(Rule $rule) {
208 186
        $this->rules[] = $rule;
209 186
    }
210
211
    /**
212
     * Try to get a rule schema by name.
213
     *
214
     * @param   string  $name
215
     * @return  Schema|null
216
     */
217 187
    public function get_schema($name) {
218 187
        assert('is_string($name)');
219 187
        if (array_key_exists($name, $this->known_schemas)) {
220 187
            return $this->known_schemas[$name];
221
        }
222
        return null;
223
    }
224
}
225