Completed
Push — master ( 333f55...a94ac3 )
by Richard
05:33
created

Rule::arguments()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
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\Rules;
12
13
use Lechimp\Dicto\Definition\Definition;
14
use Lechimp\Dicto\Variables\Variable;
15
use Lechimp\Dicto\Variables\ButNot;
16
use Lechimp\Dicto\Variables\Everything;
17
use Lechimp\Dicto\Analysis\Query;
18
use Doctrine\DBAL\Driver\Statement;
19
20
class Rule extends Definition {
21
    const MODE_CANNOT   = "CANNOT";
22
    const MODE_MUST     = "MUST";
23
    const MODE_ONLY_CAN = "ONLY_CAN";
24
25
    static $modes = array
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $modes.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
26
        ( Rule::MODE_CANNOT
27
        , Rule::MODE_MUST
28
        , Rule::MODE_ONLY_CAN
29
        );
30
31
    /**
32
     * @var string
33
     */
34
    private $mode;
35
36
    /**
37
     * @var Vars\Variable
38
     */
39
    private $subject;
40
41
    /**
42
     * @var R\Schema
43
     */
44
    private $schema;
45
46
    /**
47
     * @var array
48
     */
49
    private $arguments;
50
51
    /**
52
     * @param string $mode
53
     */
54 237
    public function __construct($mode, Variable $subject, Schema $schema, array $arguments) {
55 237
        assert('in_array($mode, self::$modes)');
56 237
        $schema->check_arguments($arguments);
57 236
        $this->mode = $mode;
58 236
        $this->subject = $subject;
0 ignored issues
show
Documentation Bug introduced by
It seems like $subject of type object<Lechimp\Dicto\Variables\Variable> is incompatible with the declared type object<Lechimp\Dicto\Rules\Vars\Variable> of property $subject.

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...
59 236
        $this->schema = $schema;
0 ignored issues
show
Documentation Bug introduced by
It seems like $schema of type object<Lechimp\Dicto\Rules\Schema> is incompatible with the declared type object<Lechimp\Dicto\Rules\R\Schema> of property $schema.

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...
60 236
        $this->arguments = $arguments;
61 236
    }
62
63
    /**
64
     * @return string
65
     */
66 54
    public function mode() {
67 54
        return $this->mode;
68
    }
69
70
    /**
71
     * Definition of the entities this rule was defined for.
72
     *
73
     * @return  Variable
74
     */
75 57
    public function subject() {
76 57
        return $this->subject;
77
    }
78
79
    /**
80
     * Definition of the entities this rule needs to be checked on.
81
     *
82
     * In the default case the rule needs to be checked on every entity that
83
     * is not subject() if the mode is MODE_ONLY_CAN, as this really says
84
     * something about the other entities.
85
     *
86
     * @return  Variable
87
     */
88 50
    public function checked_on() {
89 50
        if ($this->mode() == self::MODE_ONLY_CAN) {
90
            return new ButNot
91 12
                ( "ONLY_CAN_INVERSION"
92 12
                , new Everything("EVERYTHING")
93 12
                , $this->subject()
94 12
                );
95
        }
96 38
        return $this->subject();
97
    }
98
99
    /**
100
     * Get all variables referenced by the rule.
101
     *
102
     * @return  Vars\Variable[]
103
     */
104 5
    public function variables() {
105 5
        $vars = array($this->subject());
106 5
        foreach ($this->arguments as $argument) {
107 5
            if ($argument instanceof Variable) {
108 3
                $vars[] = $argument;
109 3
            }
110 5
        }
111 5
        return $vars;
112
    }
113
114
    /**
115
     * Get the schema that was used for the rule.
116
     *
117
     * @return Schema
118
     */
119 4
    public function schema() {
120 4
        return $this->schema;
121
    }
122
123
    /**
124
     * Pretty print the rule.
125
     *
126
     * @return string
127
     */
128 1
    public function pprint() {
129 1
        $name = $this->subject()->name();
130 1
        switch ($this->mode()) {
131 1
            case self::MODE_CANNOT:
132
                return "$name cannot ".$this->schema()->pprint($this);
133 1
            case self::MODE_MUST:
134 1
                return "$name must ".$this->schema()->pprint($this);
135
            case self::MODE_ONLY_CAN:
136
                return "only $name can ".$this->schema()->pprint($this);
137
            default:
138
                throw new \Exception("Unknown rule mode '".$this->mode()."'");
139
        }
140
    }
141
142
    /**
143
     * Compile the rule to SQL.
144
     *
145
     * @param   Query       $query
146
     * @return Statement
147
     */
148 48
    public function compile(Query $query) {
149 48
        return $this->schema->compile($query, $this);
150
    }
151
152
    /**
153
     * Turn a query result into a violation.
154
     *
155
     * @param   array   $row
156
     * @param   string  $file_source
157
     * @return  \Lechimp\Dicto\Analysis\Violation
158
     */
159 2
    public function to_violation(array $row, array $file_source) {
160 2
        return $this->schema->to_violation($this, $row, $file_source);
161
    }
162
163
    /**
164
     * Get the argument at the index.
165
     *
166
     * @throws  \OutOfRangeException
167
     * @param   int     $index
168
     * @return  mixed 
169
     */
170 49
    public function argument($index) {
171 49
        if ($index < 0 || $index >= count($this->arguments)) {
172
            throw new \OutOfRangeException("'$index' out of range.");
173
        }
174 49
        return $this->arguments[$index];
175
    }
176
177
    /**
178
     * Get all arguments.
179
     *
180
     * @return array
181
     */
182 3
    public function arguments() {
183 3
        return $this->arguments;
184
    }
185
}
186
187