Completed
Push — master ( f7852e...e666ea )
by Richard
06:08
created

Rule::schema()   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
c 0
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 license along with the code.
9
 */
10
11
namespace Lechimp\Dicto\Rules;
12
13
use Lechimp\Dicto\Analysis\Index;
14
use Lechimp\Dicto\Definition\Definition;
15
use Lechimp\Dicto\Variables\Variable;
16
use Lechimp\Dicto\Variables\Except;
17
use Lechimp\Dicto\Variables\Everything;
18
19
class Rule extends Definition {
20
    const MODE_CANNOT   = "CANNOT";
21
    const MODE_MUST     = "MUST";
22
    const MODE_ONLY_CAN = "ONLY_CAN";
23
24
    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...
25
        ( Rule::MODE_CANNOT
26
        , Rule::MODE_MUST
27
        , Rule::MODE_ONLY_CAN
28
        );
29
30
    /**
31
     * @var string
32
     */
33
    private $mode;
34
35
    /**
36
     * @var Variable
37
     */
38
    private $subject;
39
40
    /**
41
     * @var Schema
42
     */
43
    private $schema;
44
45
    /**
46
     * @var array
47
     */
48
    private $arguments;
49
50
    /**
51
     * @param string $mode
52
     */
53 46
    public function __construct($mode, Variable $subject, Schema $schema, array $arguments) {
54 46
        assert('in_array($mode, self::$modes)');
55 46
        assert('$schema->arguments_are_valid($arguments)');
56 46
        $this->mode = $mode;
57 46
        $this->subject = $subject;
58 46
        $this->schema = $schema;
59 46
        $this->arguments = $arguments;
60 46
    }
61
62
    /**
63
     * @return string
64
     */
65 37
    public function mode() {
66 37
        return $this->mode;
67
    }
68
69
    /**
70
     * Definition of the entities this rule was defined for.
71
     *
72
     * @return  Variable
73
     */
74 40
    public function subject() {
75 40
        return $this->subject;
76
    }
77
78
    /**
79
     * Definition of the entities this rule needs to be checked on.
80
     *
81
     * In the default case the rule needs to be checked on every entity that
82
     * is not subject() if the mode is MODE_ONLY_CAN, as this really says
83
     * something about the other entities.
84
     *
85
     * @return  Variable
86
     */
87 22
    public function checked_on() {
88 22
        if ($this->mode() == self::MODE_ONLY_CAN) {
89
            return new Except
90 7
                ( new Everything("EVERYTHING")
91 7
                , $this->subject()
92 7
                );
93
        }
94 15
        return $this->subject();
95
    }
96
97
    /**
98
     * Get all variables referenced by the rule.
99
     *
100
     * @return  Vars\Variable[]
101
     */
102 35
    public function variables() {
103 35
        $vars = array($this->subject());
104 35
        foreach ($this->arguments as $argument) {
105 35
            if ($argument instanceof Variable) {
106 27
                $vars[] = $argument;
107 27
            }
108 35
        }
109 35
        return $vars;
110
    }
111
112
    /**
113
     * Get the schema that was used for the rule.
114
     *
115
     * @return Schema
116
     */
117 35
    public function schema() {
118 35
        return $this->schema;
119
    }
120
121
    /**
122
     * Pretty print the rule.
123
     *
124
     * @return string
125
     */
126 32
    public function pprint() {
127 32
        $name = $this->subject()->name();
128 32
        switch ($this->mode()) {
129 32
            case self::MODE_CANNOT:
130 17
                return "$name cannot ".$this->schema()->pprint($this);
131 15
            case self::MODE_MUST:
132 9
                return "$name must ".$this->schema()->pprint($this);
133 6
            case self::MODE_ONLY_CAN:
134 6
                return "only $name can ".$this->schema()->pprint($this);
135
            default:
136
                throw new \Exception("Unknown rule mode '".$this->mode()."'");
137
        }
138
    }
139
140
    /**
141
     * Compile the rule to SQL.
142
     *
143
     * @param   Index   $index
144
     * @return  Query
145
     */
146 20
    public function compile(Index $index) {
147 20
        return $this->schema->compile($index, $this);
148
    }
149
150
    /**
151
     * Turn a query result into a violation.
152
     *
153
     * @param   array   $row
154
     * @return  \Lechimp\Dicto\Analysis\Violation
155
     */
156 7
    public function to_violation(array $row) {
157 7
        return $this->schema->to_violation($this, $row);
158
    }
159
160
    /**
161
     * Get the argument at the index.
162
     *
163
     * @throws  \OutOfRangeException
164
     * @param   int     $index
165
     * @return  mixed 
166
     */
167 32
    public function argument($index) {
168 32
        if ($index < 0 || $index >= count($this->arguments)) {
169
            throw new \OutOfRangeException("'$index' out of range.");
170
        }
171 32
        return $this->arguments[$index];
172
    }
173
174
    /**
175
     * Get all arguments.
176
     *
177
     * @return array
178
     */
179 3
    public function arguments() {
180 3
        return $this->arguments;
181
    }
182
}
183
184