Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Validator
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 6
240
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 validate
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
30
 __getState
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 __getRule
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 __getDescriptions
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 __getValidatorFlags
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2namespace USDLRegex;
3
4/**
5 * Validation class.
6 */
7class Validator {
8    /**
9     * Map of states and their rules
10     * @var array
11     */
12    public $rules = array();
13
14    /**
15     * Flag for adding verbosity to output
16     * @var boolean
17     */
18    public $verbose         = FALSE;
19
20    /**
21     * Flag for making regex comparisons case insensitive. e.g. the `i` flag
22     * @var boolean
23     */
24    public $caseInsensitive = FALSE;
25
26    function __construct($options = array()) {
27        $defaults = array(
28            'rules'           => json_decode(file_get_contents(__DIR__.'/../regex.json'), TRUE),
29            'verbose'         => FALSE,
30            'caseInsensitive' => FALSE,
31        );
32
33        $options = array_merge($defaults, $options);
34
35        $this->rules           = $options['rules'];
36        $this->verbose         = $options['verbose'];
37        $this->caseInsensitive = $options['caseInsensitive'];
38    }
39
40    /**
41     * Takes the passed state to lookup the regex rules, and tries to match
42     * in the provided string.
43     *
44     * @param  String $state     2 letter abbreviation of the state
45     * @param  String $dlString  string representatino of the driver license number
46     *
47     * @return Bool              TRUE/FALSE if the number is valid
48     */
49    public function validate($state, $dlString) {
50        $rule       = $this->__getRule($state);
51        $regexFlags = $this->__getValidatorFlags();
52
53        if ($this->verbose === TRUE) {
54            echo "Validating $dlString using rule $rule\n";
55        }
56
57        $isValid = (bool)preg_match("/$rule/$regexFlags", $dlString);
58
59        if ($isValid === FALSE && $this->verbose === TRUE) {
60            echo "Didn't match against the following criteria:\n";
61            foreach ($this->__getDescriptions($state) as $description) {
62                echo "  $description\n";
63            }
64        }
65
66        return $isValid;
67    }
68
69    /**
70     * Finds and returns the registered state definition.
71     *
72     * @param  String $key State to lookup rules for
73     *
74     * @return Array       Array of Rule and Descriptions
75     *
76     * @throws USDLRegex\ValueException         No State key was provided
77     * @throws USDLRegex\StateNotFoundException Passed state doesn't exist in key
78     */
79    private function __getState($key=NULL) {
80        if ($key === NULL) {
81            throw new ValueException('Must provide a key to get a rule');
82        }
83
84        $key = strtoupper($key);
85
86        if (!array_key_exists($key, $this->rules)) {
87            throw new StateNotFoundException("State '$key' not found in rule set");
88        }
89
90        return $this->rules[$key];
91    }
92
93    /**
94     * Finds and returns the validation rule for the state.
95     *
96     * @param  String $key State to lookup rules for
97     *
98     * @return String      String representation of regex
99     *
100     * @throws USDLRegex\RuleFormatException 'rule' key doesn't exist for the passed
101     *                                       state.
102     */
103    private function __getRule($key=NULL) {
104        $state = $this->__getState($key);
105
106        if (!array_key_exists('rule', $state)) {
107            throw new RuleFormatException("Malformed rules JSON: State '$key' does not have a 'rule' key.");
108        }
109
110        return $state['rule'];
111    }
112
113    /**
114     * Finds and returns the list of friendly descriptions for the state rule regex.
115     *
116     * @param  String $key State to lookup rules for
117     *
118     * @return Array       Array of strings with friendly regex rules
119     *
120     * @throws USDLRegex\RuleFormatException 'description' key doesn't exist for the
121     *                                       passed state.
122     */
123    private function __getDescriptions($key=NULL) {
124        $state = $this->__getState($key);
125
126        if (!array_key_exists('description', $state)) {
127            throw new RuleFormatException("Malformed rules JSON: State '$key' does not have a 'description' key.");
128        }
129
130        return $state['description'];
131    }
132
133    /**
134     * Compiles a list of regex directives to be used while validating.
135     *
136     * @return String string of regex directives
137     */
138    private function __getValidatorFlags() {
139        $validatorFlags = '';
140
141        if ($this->caseInsensitive === TRUE) {
142            $validatorFlags .= 'i';
143        }
144
145        return $validatorFlags;
146    }
147}