Completed
Push — master ( 31785d...5192f1 )
by Richard
06:45
created

Rule::variables()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
ccs 8
cts 8
cp 1
rs 9.6666
cc 3
eloc 6
nc 3
nop 0
crap 3
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 51
    public function __construct($mode, Variable $subject, Schema $schema, array $arguments) {
54 51
        assert('in_array($mode, self::$modes)');
55 51
        assert('$schema->arguments_are_valid($arguments)');
56 51
        $this->mode = $mode;
57 51
        $this->subject = $subject;
58 51
        $this->schema = $schema;
59 51
        $this->arguments = $arguments;
60 51
    }
61
62
    /**
63
     * @return string
64
     */
65 40
    public function mode() {
66 40
        return $this->mode;
67
    }
68
69
    /**
70
     * Definition of the entities this rule was defined for.
71
     *
72
     * @return  Variable
73
     */
74 43
    public function subject() {
75 43
        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 25
    public function checked_on() {
88 25
        if ($this->mode() == self::MODE_ONLY_CAN) {
89
            return new Except
90 7
                ( new Everything("EVERYTHING")
91 7
                , $this->subject()
92 7
                );
93
        }
94 18
        return $this->subject();
95
    }
96
97
    /**
98
     * Get all variables referenced by the rule.
99
     *
100
     * @return  Vars\Variable[]
101
     */
102 38
    public function variables() {
103 38
        $vars = array($this->subject());
104 38
        foreach ($this->arguments as $argument) {
105 38
            if ($argument instanceof Variable) {
106 30
                $vars[] = $argument;
107 30
            }
108 38
        }
109 38
        return $vars;
110
    }
111
112
    /**
113
     * Get the schema that was used for the rule.
114
     *
115
     * @return Schema
116
     */
117 38
    public function schema() {
118 38
        return $this->schema;
119
    }
120
121
    /**
122
     * Pretty print the rule.
123
     *
124
     * @return string
125
     */
126 35
    public function pprint() {
127 35
        $name = $this->subject()->name();
128 35
        switch ($this->mode()) {
129 35
            case self::MODE_CANNOT:
130 20
                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 23
    public function compile(Index $index) {
147 23
        return $this->schema->compile($index, $this);
148
    }
149
150
    /**
151
     * Get the argument at the index.
152
     *
153
     * @throws  \OutOfRangeException
154
     * @param   int     $index
155
     * @return  mixed 
156
     */
157 35
    public function argument($index) {
158 35
        if ($index < 0 || $index >= count($this->arguments)) {
159
            throw new \OutOfRangeException("'$index' out of range.");
160
        }
161 35
        return $this->arguments[$index];
162
    }
163
164
    /**
165
     * Get all arguments.
166
     *
167
     * @return array
168
     */
169 3
    public function arguments() {
170 3
        return $this->arguments;
171
    }
172
}
173
174