Completed
Push — master ( cc2765...340ff8 )
by Richard
08:19
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 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
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 license 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\Except;
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 Variable
38
     */
39
    private $subject;
40
41
    /**
42
     * @var Schema
43
     */
44
    private $schema;
45
46
    /**
47
     * @var array
48
     */
49
    private $arguments;
50
51
    /**
52
     * @param string $mode
53
     */
54 77
    public function __construct($mode, Variable $subject, Schema $schema, array $arguments) {
55 77
        assert('in_array($mode, self::$modes)');
56 77
        assert('$schema->arguments_are_valid($arguments)');
57 77
        $this->mode = $mode;
58 77
        $this->subject = $subject;
59 77
        $this->schema = $schema;
60 77
        $this->arguments = $arguments;
61 77
    }
62
63
    /**
64
     * @return string
65
     */
66 66
    public function mode() {
67 66
        return $this->mode;
68
    }
69
70
    /**
71
     * Definition of the entities this rule was defined for.
72
     *
73
     * @return  Variable
74
     */
75 69
    public function subject() {
76 69
        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 51
    public function checked_on() {
89 51
        if ($this->mode() == self::MODE_ONLY_CAN) {
90
            return new Except
91 12
                ( new Everything("EVERYTHING")
92 12
                , $this->subject()
93 12
                );
94
        }
95 39
        return $this->subject();
96
    }
97
98
    /**
99
     * Get all variables referenced by the rule.
100
     *
101
     * @return  Vars\Variable[]
102
     */
103 18
    public function variables() {
104 18
        $vars = array($this->subject());
105 18
        foreach ($this->arguments as $argument) {
106 18
            if ($argument instanceof Variable) {
107 16
                $vars[] = $argument;
108 16
            }
109 18
        }
110 18
        return $vars;
111
    }
112
113
    /**
114
     * Get the schema that was used for the rule.
115
     *
116
     * @return Schema
117
     */
118 18
    public function schema() {
119 18
        return $this->schema;
120
    }
121
122
    /**
123
     * Pretty print the rule.
124
     *
125
     * @return string
126
     */
127 15
    public function pprint() {
128 15
        $name = $this->subject()->name();
129 15
        switch ($this->mode()) {
130 15
            case self::MODE_CANNOT:
131 15
                return "$name cannot ".$this->schema()->pprint($this);
132
            case self::MODE_MUST:
133
                return "$name must ".$this->schema()->pprint($this);
134
            case self::MODE_ONLY_CAN:
135
                return "only $name can ".$this->schema()->pprint($this);
136
            default:
137
                throw new \Exception("Unknown rule mode '".$this->mode()."'");
138
        }
139
    }
140
141
    /**
142
     * Compile the rule to SQL.
143
     *
144
     * @param   Query       $query
145
     * @return Statement
146
     */
147 49
    public function compile(Query $query) {
148 49
        return $this->schema->compile($query, $this);
149
    }
150
151
    /**
152
     * Turn a query result into a violation.
153
     *
154
     * @param   array   $row
155
     * @return  \Lechimp\Dicto\Analysis\Violation
156
     */
157 2
    public function to_violation(array $row) {
158 2
        return $this->schema->to_violation($this, $row);
159
    }
160
161
    /**
162
     * Get the argument at the index.
163
     *
164
     * @throws  \OutOfRangeException
165
     * @param   int     $index
166
     * @return  mixed 
167
     */
168 61
    public function argument($index) {
169 61
        if ($index < 0 || $index >= count($this->arguments)) {
170
            throw new \OutOfRangeException("'$index' out of range.");
171
        }
172 61
        return $this->arguments[$index];
173
    }
174
175
    /**
176
     * Get all arguments.
177
     *
178
     * @return array
179
     */
180 3
    public function arguments() {
181 3
        return $this->arguments;
182
    }
183
}
184
185