├── Contract.php
├── Contract
├── Exception.php
├── Term.php
└── Term
│ ├── Abstract.php
│ └── ProxyCollection.php
├── Examples
├── Array_Notation.php
├── Controller.php
├── Filter.php
├── Find.php
├── Image_Resize.php
└── Model.php
├── LICENSE
├── Overview.txt
└── README.md
/Contract.php:
--------------------------------------------------------------------------------
1 | reflection['class'] = new ReflectionClass($object['class']);
28 | $this->reflection['method'] = $this->reflection['class']->getMethod($object['function']);
29 | $this->reflection['parameters'] = $this->reflection['method']->getParameters();
30 | $this->name = $this->reflection['class']->name . '/' . $this->reflection['method']->name;
31 |
32 | foreach ($this->reflection['parameters'] as $p => $parameter){
33 |
34 | $termName = $parameter->name;
35 | $termData = (isset($object['args'][$p])) ? $object['args'][$p] : (($parameter->isDefaultValueAvailable()) ? $parameter->getDefaultValue() : null);
36 |
37 | $this->terms[$termName] = new Contract_Term($termName, $termData, $this);
38 |
39 | }
40 |
41 | }
42 |
43 | if (!is_null($termsData)) $this->terms($termsData);
44 | if (!is_null($metAction)) switch ($metAction){
45 |
46 | case self::MET_OR_THROW: $this->metOrThrow(); break;
47 | default: $this->metOrThrow(); break;
48 |
49 | }
50 |
51 | }
52 |
53 | public function data($term){
54 |
55 | return $this->getData($term);
56 |
57 | }
58 |
59 | public function debug($print = true){
60 |
61 | $debug = array();
62 |
63 | $terms = $this->getTerms();
64 | foreach ($terms as $term){
65 |
66 | $termName = $term->getName();
67 | $debug[$termName] = $term->debug(false);
68 |
69 | }
70 |
71 | if ($print) print_r($debug);
72 |
73 | return $debug;
74 |
75 | }
76 |
77 | public static function factory(array $termsData = null, $metAction = null){
78 |
79 | $contract = new self($termsData, $metAction, Contract::FROM_FACTORY);
80 | return $contract;
81 |
82 | }
83 |
84 | public function find($termName){
85 |
86 | $terms = explode('/', $termName);
87 | $current = $this;
88 |
89 | foreach ($terms as $term){
90 |
91 | $term = $current->getTerm($term, false);
92 | if ($term instanceof Contract_Term_Abstract) $current = $term;
93 | else {
94 |
95 | throw new Contract_Exception('Could not find: ' . $termName);
96 |
97 | }
98 |
99 | }
100 |
101 | return $current;
102 |
103 | }
104 |
105 | public function getData($term){
106 |
107 | return $this->getTerm($term)->data();
108 |
109 | }
110 |
111 | public function getMets(){
112 |
113 | $mets = array();
114 |
115 | $terms = $this->getTerms();
116 | foreach ($terms as $term){
117 |
118 | $termMets = $term->getMets();
119 | $mets = array_merge($mets, $termMets);
120 |
121 | }
122 |
123 | return $mets;
124 |
125 | }
126 |
127 | public function getName(){
128 |
129 | return $this->name;
130 |
131 | }
132 |
133 | public function getTerm($name, $find = true, $data = null){
134 |
135 | if ($find && is_null($data)) $term = $this->find($name);
136 | else $term = $this->terms[$name];
137 |
138 | if (!$term instanceof Contract_Term_Abstract) $term = $this->terms[$name] = new Contract_Term($name, $data, $this);
139 |
140 | return $term;
141 |
142 | }
143 |
144 | public function getTerms(){
145 |
146 | return $this->terms;
147 |
148 | }
149 |
150 | public function met(){
151 |
152 | $mets = $this->getMets();
153 |
154 | foreach ($mets as $met) if ($met['met'] !== true){
155 |
156 | if ($met['predicate'] != 'Allowed') return false;
157 |
158 | }
159 |
160 | return true;
161 |
162 | }
163 |
164 | public function metOrThrow(){
165 |
166 | $mets = $this->getMets();
167 |
168 | foreach ($mets as $met) if ($met['met'] !== true){
169 |
170 | if ($met['predicate'] != 'Allowed'){
171 |
172 | throw new Contract_Exception('Contract term `' . $met['term'] . '` did not meet its requirement for ' . $met['predicate'] . '.', $met['name']);
173 |
174 | }
175 |
176 | }
177 |
178 | return true;
179 |
180 | }
181 |
182 | public function term($name, $data = null){
183 |
184 | $term = $this->getTerm($name, true, $data);
185 | return $term;
186 |
187 | }
188 |
189 | public function terms(array $termsData){
190 |
191 | foreach ($termsData as $termName => $termConfig){
192 |
193 | $name = $termName;
194 | $data = null;
195 | $definition = $termConfig;
196 |
197 | if (is_array($termConfig)){
198 |
199 | if (array_key_exists('data', $termConfig)) $data = $termConfig['data'];
200 | if (array_key_exists('definition', $termConfig)) $definition = $termConfig['definition'];
201 |
202 | }
203 |
204 | $term = $this->getTerm($name, true, $data);
205 |
206 | if (is_array($definition)){
207 |
208 | foreach ($definition as $definitionName => $definitionValue){
209 |
210 | if (method_exists($term, $definitionName)){
211 |
212 | switch ($definitionName){
213 |
214 | case 'element':
215 |
216 | if (is_array($definitionValue)){
217 |
218 | foreach ($definitionValue as $elementName => $elementConfig){
219 |
220 | $element = $term->element($elementName);
221 |
222 | if (is_array($elementConfig)){
223 |
224 | foreach ($elementConfig as $elementDefinitionName => $elementDefinitionValue){
225 |
226 | if (method_exists($element, $elementDefinitionName)){
227 |
228 | if (!is_array($elementDefinitionValue) || in_array($elementDefinitionName, array('allowed', 'alone', 'in'))) $elementDefinitionValue = array($elementDefinitionValue);
229 | call_user_func_array(array($element, $elementDefinitionName), $elementDefinitionValue);
230 |
231 |
232 | }
233 | else if (method_exists($element, $elementDefinitionValue)){
234 |
235 | call_user_func_array(array($element, $elementDefinitionValue), array());
236 |
237 | }
238 |
239 | }
240 |
241 | }
242 | else {
243 |
244 | if (method_exists($element, $elementConfig)){
245 |
246 | call_user_func_array(array($element, $elementConfig), array());
247 |
248 | }
249 |
250 | }
251 |
252 | }
253 |
254 | }
255 |
256 | break;
257 |
258 | case 'elements':
259 |
260 | throw new Exception('Contract_Term::elements() is not supported when creating terms via array notation.');
261 |
262 | break;
263 |
264 | default:
265 |
266 | if (!is_array($definitionValue) || in_array($definitionName, array('allowed', 'alone', 'in'))) $definitionValue = array($definitionValue);
267 | call_user_func_array(array($term, $definitionName), $definitionValue);
268 |
269 | break;
270 |
271 | }
272 |
273 | }
274 | else if (method_exists($term, $definitionValue)){
275 |
276 | call_user_func_array(array($term, $definitionValue), array());
277 |
278 | }
279 |
280 | }
281 |
282 | }
283 | else {
284 |
285 | if (method_exists($term, $definition)){
286 |
287 | call_user_func_array(array($term, $definition), array());
288 |
289 | }
290 |
291 | }
292 |
293 | }
294 |
295 | return $this;
296 |
297 | }
298 |
299 | public function __toString(){
300 |
301 | $string = '[contract' . (!empty($this->name) ? ':' . $this->name : '') . "]\n";
302 |
303 | $terms = $this->getTerms();
304 | foreach ($terms as $term) $string .= $term;
305 |
306 | return $string;
307 |
308 | }
309 |
310 | }
311 |
312 | ?>
--------------------------------------------------------------------------------
/Contract/Exception.php:
--------------------------------------------------------------------------------
1 | term = $term;
11 |
12 | }
13 |
14 | public function __get($name){
15 |
16 | $property = null;
17 |
18 | if ($name == 'term') $property = $this->term;
19 |
20 | return $property;
21 |
22 | }
23 |
24 | }
25 |
26 | ?>
27 |
--------------------------------------------------------------------------------
/Contract/Term.php:
--------------------------------------------------------------------------------
1 | setName($name);
67 | $this->setData($data);
68 | $this->setParent($parent);
69 | $this->setChildren();
70 |
71 | }
72 |
73 | public function allowed($keys, $propagate = false){ if ($keys == '*'){ foreach ($this->children as $key => $term){ $this->dataAllowable[] = $key; if ($propagate) $term->allowed('*', $propagate); } } else { if (is_array($keys)) $this->dataAllowable = $keys; else $this->dataAllowable[] = $keys; } return $this; }
74 | public function alone(array $exceptions = null){ $this->meetAlone = (!is_null($exceptions)) ? $exceptions : true; return $this; }
75 | public function alpha(){ $this->meetAlpha = true; return $this; }
76 | public function alphaNumeric(){ $this->meetAlphaNumeric = true; return $this; }
77 | public function alphaDash(){ $this->meetAlphaDash = true; return $this; }
78 | public function alphaUnderscore(){ $this->meetAlphaUnderscore = true; return $this; }
79 | public function arraylist($all = false){ $this->meetArraylist = ($all) ? 'all' : 'one'; return $this; }
80 | public function base64(){ $this->meetBase64 = true; return $this; }
81 | public function between($value, $value2){ $this->meetBetween = array($value, $value2); return $this; }
82 | public function boolean($strict = true){ $this->meetBoolean = ($strict) ? 'strict' : 'loose'; return $this; }
83 | public function count($value = null, $value2 = null){ $this->meetCount = (!is_null($value) || !is_null($value2)) ? array($value, $value2) : false; return $this; }
84 | public function date(){ $this->meetDate = true; return $this; }
85 | public function datetime(){ $this->meetDatetime = true; return $this; }
86 | public function decimal(){ $this->meetDecimal = true; return $this; }
87 | public function earlier($timestamp = null){ $this->meetEarlier = (!is_null($timestamp)) ? strtotime($timestamp) : time(); return $this; }
88 | public function email(){ $this->meetEmail = true; return $this; }
89 | public function equals($value){ $this->meetEquals = $value; return $this; }
90 | public function file(){ $this->meetFile = true; return $this; }
91 | public function greaterThan($value){ $this->meetGreaterThan = $value; return $this; }
92 | public function id(){ $this->meetId = true; return $this; }
93 | public function in(array $values){ $this->meetIn = $values; return $this; }
94 | public function integer(){ $this->meetInteger = true; return $this; }
95 | public function ip(){ $this->meetIp = true; return $this; }
96 | public function later($timestamp = null){ $this->meetLater = (!is_null($timestamp)) ? strtotime($timestamp) : time(); return $this; }
97 | public function length($value = null, $value2 = null){ $this->meetLength = (!is_null($value) || !is_null($value2)) ? array($value, $value2) : false; return $this; }
98 | public function lessThan($value){ $this->meetLessThan = $value; return $this; }
99 | public function many(){ $this->meetMany = true; return $this; }
100 | public function natural(){ $this->meetNatural = true; return $this; }
101 | public function naturalPositive(){ $this->meetNaturalPositive = true; return $this; }
102 | public function none(){ $this->meetNone = true; return $this; }
103 | public function not($value){ $this->meetNot = $value; return $this; }
104 | public function null(){ $this->meetNull = true; return $this; }
105 | public function numeric(){ $this->meetNumeric = true; return $this; }
106 | public function object($type = null){ $this->meetObject = (!is_null($type)) ? $type : true; return $this; }
107 | public function one(){ $this->meetOne = true; return $this; }
108 | public function optional($optional = true){ $this->meetOptional = $optional; return $this; }
109 | public function phone($strict = false){ $this->meetPhone = ($strict) ? 'strict' : 'loose'; return $this; }
110 | public function required($required = true){ $this->meetRequired = $required; return $this; }
111 | public function row($all = false){ $this->meetRow = ($all) ? 'all' : 'one'; return $this; }
112 | public function string(){ $this->meetString = true; return $this; }
113 | public function time(){ $this->meetTime = true; return $this; }
114 | public function url(){ $this->meetUrl = true; return $this; }
115 | public function withData(){ $this->meetWithData = true; return $this; }
116 |
117 | public function data($type = null){
118 |
119 | return $this->getData($type);
120 |
121 | }
122 |
123 | public function debug($print = true){
124 |
125 | $mets = $this->getMets();
126 |
127 | foreach ($mets as $m => $met) if ($met['met'] === true) unset($mets[$m]);
128 |
129 | if ($print) print_r($mets);
130 |
131 | return $mets;
132 |
133 | }
134 |
135 | public function element($name){
136 |
137 | if (!in_array($name, $this->dataAllowable)) $this->dataAllowable[] = $name;
138 | if (!isset($this->children[$name])) $this->children[$name] = new Site_Contract_Term($name, '', $this);
139 |
140 | return $this->getTerm($name);
141 |
142 | }
143 |
144 | public function elements(){
145 |
146 | require_once('Term/ProxyCollection.php');
147 | return new Contract_Term_ProxyCollection($this);
148 |
149 | }
150 |
151 | public function end($recursion = false){
152 |
153 | return $this->parent();
154 |
155 | }
156 |
157 | public function find($termName){
158 |
159 | $terms = explode('/', $termName);
160 | $current = $this;
161 |
162 | foreach ($terms as $term){
163 |
164 | $term = $current->getTerm($term, false);
165 | if ($term instanceof Contract_Term_Abstract) $current = $term;
166 | else {
167 |
168 | require_once('Exception.php');
169 | throw new Contract_Exception('Could not find: ' . $termName);
170 |
171 | }
172 |
173 | }
174 |
175 | return $current;
176 |
177 | }
178 |
179 | public function getData($type = null){
180 |
181 | switch ($type){
182 | case self::DATA_ALLOWABLE: return $this->dataAllowable;
183 | case self::DATA_MET: return $this->getMetData(false);
184 | case self::DATA_ORIGINAL: return $this->data;
185 | default: return $this->getMetData();
186 | }
187 |
188 | }
189 |
190 | public function getFullName(){
191 |
192 | if (is_null($this->fullName)){
193 |
194 | $fullName = $this->getName();
195 | if ($this->parent && $this->parent instanceof Contract_Term) $fullName = $this->parent->getFullName() . '/' . $fullName;
196 | $this->fullName = $fullName;
197 |
198 | }
199 |
200 | return $this->fullName;
201 |
202 | }
203 |
204 | public function getMetData($rescan = false){
205 |
206 | if ($this->scanned && !$rescan) return $this->dataMet;
207 |
208 | $dataMet = $this->getData(self::DATA_ORIGINAL);
209 | $mets = $this->getMets();
210 |
211 | foreach ($dataMet as $key => $value){
212 |
213 | $keyFullName = $this->element($key)->getFullName();
214 |
215 | foreach ($mets as $metFullName => $met){
216 |
217 | $metFullName = implode('/', array_slice(explode('/', $metFullName), 0, -1));
218 | if (strpos($metFullName, $keyFullName) === 0){
219 |
220 | if ($met['met'] === false){
221 |
222 | if ($met['predicate'] == 'Allowed') eval('unset($dataMet[' . implode('][', array_slice(explode('/', $metFullName), 1)) . ']);');
223 | else unset($dataMet[$key]);
224 |
225 | }
226 |
227 | }
228 |
229 | }
230 |
231 | }
232 |
233 | $this->dataMet = $dataMet;
234 | $this->scanned = true;
235 |
236 | return $this->dataMet;
237 |
238 | }
239 |
240 | public function getMets(){
241 |
242 | $mets = array();
243 |
244 | if ($this->meetOptional == true && empty($this->data)) return $mets;
245 |
246 | $properties = get_object_vars($this);
247 | foreach ($properties as $propertyName => $propertyValue) if (substr($propertyName, 0, 4) == 'meet' && $propertyValue !== false){
248 |
249 | $condition = substr($propertyName, 4);
250 | $method = 'met' . $condition;
251 | $methodMets = $this->$method();
252 | $mets = array_merge($mets, $methodMets);
253 |
254 | }
255 |
256 | foreach ($this->children as $childName => $childTerm){
257 |
258 | $childMets = $childTerm->getMets();
259 | $mets = array_merge($mets, $childMets);
260 |
261 | }
262 |
263 | return $mets;
264 |
265 | }
266 |
267 | public function getName(){
268 |
269 | return $this->name;
270 |
271 | }
272 |
273 | protected function getParent($recursion = false){
274 |
275 | if ($recursion && $this->parent instanceof Contract_Term){
276 |
277 | if (is_string($recursion) && $recursion == $this->parent->getName()) return $this->parent;
278 | if (is_int($recursion)) $recursion--;
279 | $parent = $this->parent->getParent($recursion);
280 |
281 | }
282 | else $parent = $this->parent;
283 |
284 | return $parent;
285 |
286 | }
287 |
288 | protected function getPredicateFullName($predicateName){
289 |
290 | $fullName = $this->getFullName();
291 | $predicateFullName = $fullName . '/' . $predicateName;
292 | return $predicateFullName;
293 |
294 | }
295 |
296 | public function getTerm($name, $find = true){
297 |
298 | if ($find) $term = $this->find($name);
299 | else $term = $this->children[$name];
300 | return $term;
301 |
302 | }
303 |
304 | public function met(){
305 |
306 | $mets = $this->getMets();
307 |
308 | foreach ($mets as $met) if ($met['met'] !== true){
309 |
310 | if ($met['predicate'] != 'Allowed') return false;
311 |
312 | }
313 |
314 | return true;
315 |
316 | }
317 |
318 | public function metOrThrow(){
319 |
320 | $mets = $this->getMets();
321 |
322 | foreach ($mets as $met) if ($met['met'] !== true){
323 |
324 | if ($met['predicate'] != 'Allowed'){
325 |
326 | require_once('Exception.php');
327 | throw new Contract_Exception('Contract term `' . $met['term'] . '` did not meet its requirement for ' . $met['predicate'] . '.', $met['name']);
328 |
329 | }
330 |
331 | }
332 |
333 | return true;
334 |
335 | }
336 |
337 | protected function metAllowed(){ return $this->scanOne('Allowed'); }
338 | protected function metAlone(){ return $this->scanAll('Alone'); }
339 | protected function metAlpha(){ return $this->scanAll('Alpha'); }
340 | protected function metAlphaNumeric(){ return $this->scanAll('AlphaNumeric'); }
341 | protected function metAlphaDash(){ return $this->scanAll('AlphaDash'); }
342 | protected function metAlphaUnderscore(){ return $this->scanAll('AlphaUnderscore'); }
343 | protected function metArraylist(){ switch($this->meetArraylist){ case 'all': return $this->scanAll('Arraylist'); break; case 'one': return $this->scanOne('Arraylist'); break; } }
344 | protected function metBase64(){ return $this->scanAll('Base64'); }
345 | protected function metBetween(){ return $this->scanAll('Between'); }
346 | protected function metBoolean(){ return $this->scanAll('Boolean'); }
347 | protected function metCount(){ return $this->scanOne('Count'); }
348 | protected function metDate(){ return $this->scanAll('Date'); }
349 | protected function metDatetime(){ return $this->scanAll('Datetime'); }
350 | protected function metDecimal(){ return $this->scanAll('Decimal'); }
351 | protected function metEarlier(){ return $this->scanAll('Earlier'); }
352 | protected function metEmail(){ return $this->scanAll('Email'); }
353 | protected function metEquals(){ return $this->scanAll('Equals'); }
354 | protected function metFile(){ return $this->scanAll('File'); }
355 | protected function metGreaterThan(){ return $this->scanAll('GreaterThan'); }
356 | protected function metId(){ return $this->scanAll('Id'); }
357 | protected function metIn(){ return $this->scanAll('In'); }
358 | protected function metInteger(){ return $this->scanAll('Integer'); }
359 | protected function metIp(){ return $this->scanAll('Ip'); }
360 | protected function metLater(){ return $this->scanAll('Later'); }
361 | protected function metLength(){ return $this->scanAll('Length'); }
362 | protected function metLessThan(){ return $this->scanAll('LessThan'); }
363 | protected function metMany(){ return $this->scanOne('Many'); }
364 | protected function metNatural(){ return $this->scanAll('Natural'); }
365 | protected function metNaturalPositive(){ return $this->scanAll('NaturalPositive'); }
366 | protected function metNone(){ return $this->scanOne('None'); }
367 | protected function metNot(){ return $this->scanAll('Not'); }
368 | protected function metNull(){ return $this->scanAll('Null'); }
369 | protected function metNumeric(){ return $this->scanAll('Numeric'); }
370 | protected function metObject(){ return $this->scanAll('Object'); }
371 | protected function metOne(){ return $this->scanOne('One'); }
372 | protected function metOptional(){ return $this->scanOne('Optional'); }
373 | protected function metPhone(){ return $this->scanAll('Phone'); }
374 | protected function metRequired(){ return $this->scanOne('Required'); }
375 | protected function metRow(){ switch($this->meetRow){ case 'all': return $this->scanAll('Row'); break; case 'one': return $this->scanOne('Row'); break; } }
376 | protected function metString(){ return $this->scanAll('String'); }
377 | protected function metTime(){ return $this->scanAll('Time'); }
378 | protected function metUrl(){ return $this->scanAll('Url'); }
379 | protected function metWithData(){ return $this->scanOne('WithData'); }
380 |
381 | public function parent($recursion = false){
382 |
383 | return $this->getParent($recursion);
384 |
385 | }
386 |
387 | protected function predicateAllowed($value, $key){ if (is_null($this->parent) || !($this->parent instanceof self)) return false; return in_array($this->getName(), $this->parent->data(self::DATA_ALLOWABLE)); }
388 | protected function predicateAlone($value){ if (is_null($this->parent) || !($this->parent instanceof self)) return true; $parentData = $this->parent->getData(self::DATA_ORIGINAL); if (!is_array($parentData)) return true; if ($this->meetAlone === true) return (count($parentData) == 1 && array_key_exists($this->getName(), $parentData)); $parentDataAlone = array_diff_key($parentData, array_flip($this->meetAlone)); return (count($parentDataAlone) == 1 && array_key_exists($this->getName(), $parentDataAlone)); }
389 | protected function predicateAlpha($value){ return (bool) preg_match('/[a-zA-Z]+/', $value); }
390 | protected function predicateAlphaNumeric($value){ return (bool) preg_match('/[a-zA-Z0-9]+/', $value); }
391 | protected function predicateAlphaDash($value){ return (bool) preg_match('/[a-zA-Z0-9-]+/', $value); }
392 | protected function predicateAlphaUnderscore($value){ return (bool) preg_match('/[a-z0-9_]+/', $value); }
393 | protected function predicateArraylist($value){ return is_array($value); }
394 | protected function predicateBase64($value){ return (bool) !preg_match('/[^a-zA-Z0-9\/\+=]/', $value); }
395 | protected function predicateBetween($value){ return $value >= $this->meetBetween[0] && $value <= $this->meetBetween[1]; }
396 | protected function predicateBoolean($value){ return ($this->meetBoolean == 'strict') ? is_bool($value) : is_bool($value) || $value === 0 || $value === 1 || $value === '0' || $value === '1'; }
397 | protected function predicateCount($value){ $count = count($value); if (!is_null($this->meetCount[0]) && !is_null($this->meetCount[1])){ if (is_numeric($this->meetCount[0]) && is_numeric($this->meetCount[1])) return ($count >= $this->meetCount[0] && $count <= $this->meetCount[1]); if (is_numeric($this->meetCount[0])) return $count >= $this->meetCount[0]; else return $count <= $this->meetCount[1]; } else if (!is_null($this->meetCount[0])) return $count == $this->meetCount[0]; return false; }
398 | protected function predicateDate($value){ return (bool) preg_match('/^(((\d{4})(-)(0[13578]|10|12)(-)(0[1-9]|[12][0-9]|3[01]))|((\d{4})(-)(0[469]|1??1)(-)([0][1-9]|[12][0-9]|30))|((\d{4})(-)(02)(-)(0[1-9]|1[0-9]|2[0-8]))|(([02468]??[048]00)(-)(02)(-)(29))|(([13579][26]00)(-)(02)(-)(29))|(([0-9][0-9][0][48])(-)(0??2)(-)(29))|(([0-9][0-9][2468][048])(-)(02)(-)(29))|(([0-9][0-9][13579][26])(-)(02??)(-)(29)))$/', $value); }
399 | protected function predicateDatetime($value){ return (bool) preg_match('/^(((\d{4})(-)(0[13578]|10|12)(-)(0[1-9]|[12][0-9]|3[01]))|((\d{4})(-)(0[469]|1??1)(-)([0][1-9]|[12][0-9]|30))|((\d{4})(-)(02)(-)(0[1-9]|1[0-9]|2[0-8]))|(([02468]??[048]00)(-)(02)(-)(29))|(([13579][26]00)(-)(02)(-)(29))|(([0-9][0-9][0][48])(-)(0??2)(-)(29))|(([0-9][0-9][2468][048])(-)(02)(-)(29))|(([0-9][0-9][13579][26])(-)(02??)(-)(29)))(\s([0-1][0-9]|2[0-4]):([0-5][0-9]):([0-5][0-9]))$/', $value); }
400 | protected function predicateDecimal($value){ return filter_var($value, FILTER_VALIDATE_FLOAT) !== false; }
401 | protected function predicateEarlier($value){ return strtotime($value) < $this->meetEarlier; }
402 | protected function predicateEmail($value){ return filter_var($value, FILTER_VALIDATE_EMAIL) !== false; }
403 | protected function predicateEquals($value){ return $value == $this->meetEquals; }
404 | protected function predicateFile($value){ return is_file($value); }
405 | protected function predicateGreaterThan($value){ return $value > $this->meetGreaterThan; }
406 | protected function predicateId($value){ return (bool) preg_match('/^[0-9]+$/', $value) && $value > 0; }
407 | protected function predicateIn($value){ return in_array($value, $this->meetIn); }
408 | protected function predicateInteger($value){ return filter_var($value, FILTER_VALIDATE_INT) !== false; }
409 | protected function predicateIp($value){ return filter_var($value, FILTER_VALIDATE_IP) !== false; }
410 | protected function predicateLater($value){ return strtotime($value) > $this->meetLater; }
411 | protected function predicateLength($value){ $length = strlen($value); if (!is_null($this->meetLength[0]) && !is_null($this->meetLength[1])){ if ($this->meetLength[0] !== false && $this->meetLength[1] !== false) return ($length >= $this->meetLength[0] && $length <= $this->meetLength[1]); if ($this->meetLength[0] !== false) return $length >= $this->meetLength[0]; return $length <= $this->meetLength[1]; } else if (!is_null($this->meetLength[0])) return $length == $this->meetLength[0]; return false; }
412 | protected function predicateLessThan($value){ return $value < $this->meetLessThan; }
413 | protected function predicateMany($value){ return count($value) > 1; }
414 | protected function predicateNatural($value){ return (bool) preg_match('/^[0-9]+$/', $value); }
415 | protected function predicateNaturalPositive($value){ return (bool) preg_match('/^[0-9]+$/', $value) && $value > 0; }
416 | protected function predicateNone($value){ return empty($this->data); }
417 | protected function predicateNot($value){ return (is_array($this->meetNot)) ? !in_array($value, $this->meetNot) : $value != $this->meetNot; }
418 | protected function predicateNull($value){ return is_null($value); }
419 | protected function predicateNumeric($value){ return is_numeric($value); }
420 | protected function predicateObject($value){ return ($this->meetObject === true) ? is_object($value) : is_object($value) && $value instanceof $this->meetObject; }
421 | protected function predicateOne($value){ return count($value) == 1; }
422 | protected function predicateOptional($value){ return true; }
423 | protected function predicatePhone($value){ if ($this->meetPhone == 'strict') return (bool) preg_match('/^\([0-9]{3}\)\s?[0-9]{3}-[0-9]{4}$/', $value); else return (strlen(preg_replace('/[^0-9]/', '', $value)) >= 10); }
424 | protected function predicateRequired($value){ if (is_array($this->data)){ if (is_array($this->meetRequired)) foreach ($this->meetRequired as $required) if (empty($this->data[$required])) return false; return !empty($this->data); } return (trim($this->data) != ''); }
425 | protected function predicateRow($value){ return (isset($value['id']) && preg_match('/^[0-9]+$/', $value['id']) && $value['id'] > 0); }
426 | protected function predicateString($value){ return is_string($value); }
427 | protected function predicateTime($value){ return (bool) preg_match('/^(([0-1][0-9]|2[0-4]):([0-5][0-9]):([0-5][0-9]))$/', $value); }
428 | protected function predicateURL($value){ return filter_var($value, FILTER_VALIDATE_URL) !== false; }
429 | protected function predicateWithData($value){ $data = $this->data(self::DATA_ORIGINAL); return !empty($data); }
430 |
431 | protected function scanAll($predicate){
432 |
433 | $mets = array();
434 | $predicateMethod = 'predicate' . $predicate;
435 | $predicateFullName = $this->getPredicateFullName($predicate);
436 |
437 | if (!is_array($this->data)){
438 |
439 | $value = $this->data;
440 | $met = call_user_func_array(array($this, $predicateMethod), array($value, $this->getName()));
441 | $mets[$predicateFullName] = array('term' => $this->getFullName(), 'name' => $this->getName(), 'value' => $value, 'predicate' => $predicate, 'met' => $met);
442 |
443 | }
444 | else foreach ($this->data as $key => $value){
445 |
446 | $met = call_user_func_array(array($this, $predicateMethod), array($value, $key));
447 | $mets[$predicateFullName] = array('term' => $this->getFullName(), 'name' => $key, 'value' => $value, 'predicate' => $predicate, 'met' => $met);
448 |
449 | }
450 |
451 | return $mets;
452 |
453 | }
454 |
455 | protected function scanOne($predicate){
456 |
457 | $mets = array();
458 | $predicateMethod = 'predicate' . $predicate;
459 | $predicateFullName = $this->getPredicateFullName($predicate);
460 |
461 | $value = $this->data;
462 | $met = call_user_func_array(array($this, $predicateMethod), array($value, $this->getName()));
463 | $mets[$predicateFullName] = array('term' => $this->getFullName(), 'name' => $this->getName(), 'value' => $value, 'predicate' => $predicate, 'met' => $met);
464 |
465 | return $mets;
466 |
467 | }
468 |
469 | protected function setChildren(){
470 |
471 | if (is_array($this->data)) foreach ($this->data as $name => $data) $this->children[$name] = new Contract_Term($name, $data, $this);
472 |
473 | }
474 |
475 | protected function setData($data = null){
476 |
477 | $this->data = $data;
478 |
479 | }
480 |
481 | protected function setName($name){
482 |
483 | if (is_null($this->name)) $this->name = $name;
484 |
485 | }
486 |
487 | protected function setParent($parent){
488 |
489 | if ($parent instanceof Contract || $parent instanceof Contract_Term) $this->parent = $parent;
490 |
491 | }
492 |
493 |
494 | public function __toString(){
495 |
496 | $string = '[term:' . $this->getFullName() . "]\n";
497 | $vars = get_object_vars($this);
498 | foreach ($vars as $key => $value) if (substr($key, 0, 4) == 'meet' && $value !== false) $string .= "\t" . $key . "\n";
499 | foreach ($this->children as $term) $string .= $term;
500 | return $string;
501 |
502 | }
503 |
504 | }
505 |
506 | ?>
507 |
--------------------------------------------------------------------------------
/Contract/Term/Abstract.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Contract/Term/ProxyCollection.php:
--------------------------------------------------------------------------------
1 | parent = $parent;
12 | $parentData = $parent->getData(Contract_Term::DATA_ORIGINAL);
13 | if (!is_array($parentData)) throw new Exception('Array expected for parent data.');
14 |
15 | }
16 |
17 | public function __call($method, $arguments){
18 |
19 | if (is_null($this->returnTerms)){
20 |
21 | if ($method == 'end') return $this->parent;
22 |
23 | $parentData = $this->parent->data(Contract_Term::DATA_ORIGINAL);
24 | $returnTerms = array();
25 |
26 | foreach ($parentData as $key => $value){
27 |
28 | $parentTerm = $this->parent->element($key);
29 | $returnTerms[] = call_user_func_array(array($parentTerm, $method), $arguments);
30 |
31 | }
32 |
33 | if ($method == 'element') $this->returnTerms = $returnTerms;
34 |
35 | }
36 | else {
37 |
38 | if ($method == 'end') $this->returnTerms = null;
39 | else foreach ($this->returnTerms as $returnTerm) call_user_func_array(array($returnTerm, $method), $arguments);
40 |
41 | }
42 |
43 | return $this;
44 |
45 | }
46 |
47 | }
48 |
49 | ?>
--------------------------------------------------------------------------------
/Examples/Array_Notation.php:
--------------------------------------------------------------------------------
1 | test();
5 |
6 | class Array_Notation {
7 |
8 | public function test(){
9 |
10 | $this->testA('2053', 'John Smith');
11 | $this->testB();
12 |
13 | }
14 |
15 | /* Validating Class Method Parameters In Array Notation */
16 | public function testA($userId, $userName){
17 |
18 | $contract = new Contract(array(
19 | 'userId' => 'id',
20 | 'userName' => array('optional', 'alphaNumeric', 'length' => array(8,12))
21 | ));
22 | $contract->metOrThrow();
23 |
24 | }
25 |
26 |
27 | /* Validating Local Variables In Array Notation */
28 | public function testB(){
29 |
30 | $testValue1 = 100;
31 | $testValue2 = 'red';
32 | $testValue3 = array('name' => 'John Smith', 'age' => 30);
33 |
34 | $contract = new Contract(array(
35 | 'test1' => array('data' => $testValue1, 'definition' => 'integer'),
36 | 'test2' => array('data' => $testValue2, 'definition' => array('length' => 3, 'in' => array('red', 'green', 'blue'))),
37 | 'test3' => array('data' => $testValue3, 'definition' => array('arraylist', 'element' => array('age' => array('integer', 'lessThan' => 29), 'name' => array('alpha', 'in' => array('John Doe', 'Jane Smith')))))
38 | ));
39 | $contract->metOrThrow();
40 |
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/Examples/Controller.php:
--------------------------------------------------------------------------------
1 | term('userEmail', $loginUserEmail)->email()->metOrThrow();
19 | $contract->term('userPass', $loginUserPass)->alphaNumeric()->length(8,16)->metOrThrow();
20 | $contract->term('userIp', $loginUserPass)->ip()->metOrThrow();
21 | $contract->term('dateTime', $loginDateTime)->datetime()->metOrThrow();
22 |
23 | /* Get User For Login */
24 | $user = $userModel->getUser($userEmail, $userPass);
25 | $contract->term('user', $user)->arraylist()
26 | ->element('id')->id()->end()
27 | ->element('active')->equals(1)->end()
28 | ->metOrThrow();
29 | $loginUserId = $user['id'];
30 |
31 | /* Proceed Safely to Model for Storage of User Login */
32 | $logged = $userModel->login($loginUserId, $loginUserIp, $loginDateTime);
33 | $contract->term('userLogged', $logged)->boolean()->equals(TRUE)->metOrThrow();
34 |
35 | }
36 | catch (Contract_Exception $e){
37 |
38 | /* Collect error messages from contract exception */
39 | $messages = array();
40 | switch ($e->term){
41 |
42 | case 'userEmail': $messages[] = 'Please enter an email address.'; break;
43 | case 'userPass': $messages[] = 'Please enter a password.'; break;
44 | case 'userIp': $messages[] = 'Please enter a valid ip address.'; break;
45 | case 'dateTime': $messages[] = 'Please enter a valid date time.'; break;
46 | case 'user': $messages[] = 'Please enter a valid user.'; break;
47 | case 'userLogged': $messages[] = 'Sorry. You could not be logged in.'; break;
48 | default: $messages[] = 'We do not get it either!'; break;
49 |
50 | }
51 |
52 | }
53 |
54 | }
55 |
56 | }
57 |
58 | }
59 |
60 | ?>
61 |
--------------------------------------------------------------------------------
/Examples/Filter.php:
--------------------------------------------------------------------------------
1 | test();
5 |
6 | class User_Filter {
7 |
8 | public function test(){
9 |
10 | $usersData = self::getUsersData();
11 |
12 | $usersDataFilteredByStateCT = $this->filterByState($usersData, 'CT');
13 | print_r($usersDataFilteredByStateCT);
14 |
15 | $usersDataFilteredByHasMultipleOptions = $this->filterByHasMultipleOptions($usersData);
16 | print_r($usersDataFilteredByHasMultipleOptions);
17 |
18 | $usersDataFilteredByValidUser = $this->filterByValidUser($usersData);
19 | print_r($usersDataFilteredByValidUser);
20 |
21 | }
22 |
23 | public function filterByHasMultipleOptions($usersData){
24 |
25 | /* Before filtering the data, establish the agreement for the method parameters. */
26 | $contract = new Contract();
27 | $contract->term('usersData')->arraylist();
28 | $contract->metOrThrow();
29 |
30 | /* Users data must be an array of elements, each element an array itself, with an options array that has two or more elements. */
31 | $contract->term('usersData')->elements()
32 | ->arraylist()
33 | ->allowed('*')
34 | ->element('options')->arraylist()->count(2, '*');
35 |
36 | $filteredData = $contract->term('usersData')->data();
37 |
38 | return $filteredData;
39 |
40 | }
41 |
42 | public function filterByState($usersData, $state){
43 |
44 | /* Before filtering the data, establish the agreement for the method parameters. */
45 | $contract = new Contract();
46 | $contract->term('usersData')->arraylist();
47 | $contract->term('state')->length(2)->in(self::getStates(true));
48 | $contract->metOrThrow();
49 |
50 | /* Users data must be an array of elements, each element an array itself, with a state element equaling $state.
51 | Allowed fields to be returned are name, address, city, state, and zip. */
52 | $contract->term('usersData')->elements()
53 | ->arraylist()
54 | ->allowed(array('name', 'address', 'city', 'state', 'zip'))
55 | ->element('state')->equals($state)->end();
56 |
57 | $filteredData = $contract->term('usersData')->data();
58 |
59 | return $filteredData;
60 |
61 | }
62 |
63 | public function filterByValidUser($usersData){
64 |
65 | /* Before filtering the data, establish the agreement for the method parameters. */
66 | $contract = new Contract();
67 | $contract->term('usersData')->arraylist();
68 | $contract->metOrThrow();
69 |
70 | /* Users data must be an array of elements, each element an array itself, with an id, name, registered date, and active boolean true.
71 | Allowed fields to be returned are the defined elements: id, name, registered, active. */
72 | $contract->term('usersData')->elements()
73 | ->arraylist()
74 | ->element('id')->id()->end()
75 | ->element('name')->optional()->alpha()->end()
76 | ->element('registered')->datetime()->end()
77 | ->element('active')->boolean()->equals(true)->end();
78 |
79 | $filteredData = $contract->term('usersData')->data();
80 |
81 | return $filteredData;
82 |
83 | }
84 |
85 | public static function getStates($abbreviationIsKey = false){
86 |
87 | $states = array(
88 | 'AL' => 'Alabama',
89 | 'AK' => 'Alaska',
90 | 'AZ' => 'Arizona',
91 | 'AR' => 'Arkansas',
92 | 'CA' => 'California',
93 | 'CO' => 'Colorado',
94 | 'CT' => 'Connecticut',
95 | 'DE' => 'Delaware',
96 | 'DC' => 'District Of Columbia',
97 | 'FL' => 'Florida',
98 | 'GA' => 'Georgia',
99 | 'HI' => 'Hawaii',
100 | 'ID' => 'Idaho',
101 | 'IL' => 'Illinois',
102 | 'IN' => 'Indiana',
103 | 'IA' => 'Iowa',
104 | 'KS' => 'Kansas',
105 | 'KY' => 'Kentucky',
106 | 'LA' => 'Louisiana',
107 | 'ME' => 'Maine',
108 | 'MD' => 'Maryland',
109 | 'MA' => 'Massachusetts',
110 | 'MI' => 'Michigan',
111 | 'MN' => 'Minnesota',
112 | 'MS' => 'Mississippi',
113 | 'MO' => 'Missouri',
114 | 'MT' => 'Montana',
115 | 'NE' => 'Nebraska',
116 | 'NV' => 'Nevada',
117 | 'NH' => 'New Hampshire',
118 | 'NJ' => 'New Jersey',
119 | 'NM' => 'New Mexico',
120 | 'NY' => 'New York',
121 | 'NC' => 'North Carolina',
122 | 'ND' => 'North Dakota',
123 | 'OH' => 'Ohio',
124 | 'OK' => 'Oklahoma',
125 | 'OR' => 'Oregon',
126 | 'PA' => 'Pennsylvania',
127 | 'RI' => 'Rhode Island',
128 | 'SC' => 'South Carolina',
129 | 'SD' => 'South Dakota',
130 | 'TN' => 'Tennessee',
131 | 'TX' => 'Texas',
132 | 'UT' => 'Utah',
133 | 'VT' => 'Vermont',
134 | 'VA' => 'Virginia',
135 | 'WA' => 'Washington',
136 | 'WV' => 'West Virginia',
137 | 'WI' => 'Wisconsin',
138 | 'WY' => 'Wyoming'
139 | );
140 |
141 | if ($abbreviationIsKey) $states = array_flip($states);
142 |
143 | return $states;
144 |
145 | }
146 |
147 | public static function getUsersData(){
148 |
149 | $usersData = array(
150 | array(
151 | 'id' => 1,
152 | 'name' => 'John Smith',
153 | 'address' => '123 Main Street',
154 | 'city' => 'Hartford',
155 | 'state' => 'CT',
156 | 'zip' => '34678',
157 | 'options' => array(
158 | 'remember' => true,
159 | 'duration_length' => 2,
160 | 'duration_unit' => 'week'
161 | ),
162 | 'logged' => '2014-02-06 12:00:00',
163 | 'registered' => '2012-01-01 12:00:00',
164 | 'active' => true
165 | ),
166 | array(
167 | 'id' => 2,
168 | 'name' => 'Jane Smith',
169 | 'address' => '345 Main Street',
170 | 'city' => 'Boston',
171 | 'state' => 'MA',
172 | 'zip' => '01243',
173 | 'options' => array(
174 | 'remember' => false
175 | ),
176 | 'logged' => '2014-03-01 12:00:00',
177 | 'registered' => '2012-07-01 12:00:00',
178 | 'active' => true
179 | ),
180 | array(
181 | 'id' => null,
182 | 'name' => 'Paul Smith',
183 | 'address' => '768 First Street',
184 | 'city' => 'Providence',
185 | 'state' => 'RI',
186 | 'zip' => '03654',
187 | 'options' => array(
188 | 'remember' => null
189 | ),
190 | 'logged' => null,
191 | 'registered' => '2012-05-01 12:00:00',
192 | 'active' => false
193 | )
194 | );
195 |
196 | return $usersData;
197 |
198 | }
199 |
200 | }
201 |
202 | ?>
203 |
--------------------------------------------------------------------------------
/Examples/Find.php:
--------------------------------------------------------------------------------
1 | array(
9 | 'inner' => array(
10 | 'number' => 1,
11 | 'letter' => 'A'
12 | ),
13 | 'inner2' => array(
14 | 'email' => 'user@email.com'
15 | ),
16 | )
17 | );
18 |
19 | /* Run the tests */
20 | $this->children($data);
21 | $this->parents($data);
22 |
23 | }
24 |
25 | /* Direct access for defining child terms found anywhere in multi-dimensional arrays */
26 | public function children($data){
27 |
28 | $contract = new Contract();
29 | $contract->term('data/outer/inner')->arraylist()
30 | ->element('number')->integer()->end()
31 | ->element('letter')->alpha()->end();
32 | $contract->metOrThrow();
33 |
34 | }
35 |
36 | /* Direct access for defining parent terms from anywhere in multi-dimensional arrays */
37 | public function parents($data){
38 |
39 | $contract = new Contract();
40 | $contract->term('data')->arraylist()
41 | ->element('outer')->arraylist()
42 | ->element('inner')->arraylist()
43 | ->element('number')->integer()->parent()
44 | ->element('letter')->alpha()->parent('outer') /* Direct access to 'outer' element */
45 | ->element('inner2')->arraylist()
46 | ->element('email')->email()->parent(TRUE) /* Direct access to the contract super object */
47 | ->metOrThrow();
48 |
49 | }
50 |
51 | }
52 |
53 | ?>
54 |
--------------------------------------------------------------------------------
/Examples/Image_Resize.php:
--------------------------------------------------------------------------------
1 | array(
9 | 'style' => array(
10 | 'top' => 0,
11 | 'left' => 0,
12 | 'width' => 0,
13 | 'height' => 0
14 | ),
15 | 'thumb' => array(
16 | 'style' => array(
17 | 'top' => 0,
18 | 'left' => 0,
19 | 'width' => 0,
20 | 'height' => 0
21 | )
22 | )
23 | )
24 | );
25 |
26 | try {
27 |
28 | /* The versatility in checking multi-dimensional arrays is profoundly intuitive! */
29 | $contract = new Site_Contract();
30 | $contract->term('fileData', $fileData)->arraylist()
31 | ->element('options')->arraylist()
32 | ->element('style')->arraylist()
33 | ->element('top')->natural()->end()
34 | ->element('left')->natural()->end()
35 | ->end()
36 | ->element('thumb')->arraylist()
37 | ->element('style')->arraylist()
38 | ->element('top')->natural()->end()
39 | ->element('left')->natural()->end()
40 | ->end();
41 | $contract->metOrThrow();
42 |
43 |
44 | }
45 | catch(Exception $exception){
46 |
47 | echo $exception->term;
48 |
49 | }
50 |
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/Examples/Model.php:
--------------------------------------------------------------------------------
1 | term('userId')->id();
10 | $contract->term('userData')->arraylist()
11 | ->element('type')->in(array('member','administrator'))->end()
12 | ->element('username')->alphaNumeric()->length(8, 16)->end()
13 | ->element('name')->required()->end()
14 | ->element('address')->required()->end()
15 | ->element('city')->required()->end()
16 | ->element('state')->length(2)->end()
17 | ->element('zip')->length(5,10)->end()
18 | ->element('country')->required()->end()
19 | ->element('email')->email()->end()
20 | ->element('phone')->phone()->end()
21 | ->element('fax')->optional()->phone()->end()
22 | ->element('photo')->optional()->file()->end()
23 | ->element('website')->optional()->url()->end()
24 | ->element('registered')->datetime()->end()
25 | ->element('active')->boolean()->end();
26 | $contract->metOrThrow();
27 |
28 | /* Follow w/ Basic MySQL Query */
29 | $rows = array();
30 |
31 | /* $select = "SELECT * FROM user WHERE id = {$userId}";
32 | while($row = mysql_query($select)) $rows[] = $row; */
33 |
34 | return $rows;
35 |
36 | }
37 |
38 | }
39 |
40 | ?>
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
11 | class Model { 12 | 13 | public function getFoos($barId, $includeBaz = false, $limit = 0, $offset = 0){ 14 | 15 | $contract = new Contract(); 16 | $contract->term('barId')->id()->end() 17 | ->term('includeBaz')->boolean()->end() 18 | ->term('limit')->natural()->end() 19 | ->term('offset')->natural()->end() 20 | ->metOrThrow(); 21 | 22 | /* Continue with peace of mind ... */ 23 | 24 | } 25 | 26 | } 27 |28 | 29 | Example of Array Notation for Defining Contract Terms 30 | ----------------------------------------------------------- 31 | 32 |
33 | class UserModel { 34 | 35 | public function getUser($userId, $userName){ 36 | 37 | $contract = new Contract(array( 38 | 'userId' => 'id', 39 | 'userName' => array('optional', 'alphaNumeric', 'length' => array(8,12)) 40 | )); 41 | $contract->metOrThrow(); 42 | 43 | /* Now, get the user ... */ 44 | 45 | } 46 | 47 | } 48 |49 | 50 | In PHP > 5.4, you can take advantage of this additional short coding for defining contract terms via array notation: 51 | ------------------------------------------------------------------------------------------------------------------- 52 | 53 |
54 | $contract = new Contract([ 55 | 'number1' => 'integer', 56 | 'number2' => ['integer', 'between' => [1, 50]], 57 | 'number3' => ['optional', 'integer', 'lessThan' => 15] 58 | ]); 59 | $contract->metOrThrow(); 60 |61 | 62 | Example of Checking The Contract During Initialization: 63 | ------------------------------------------------------------------------------------------------------------------- 64 | 65 |
66 | $contract = new Contract(array( 67 | 'userId' => 'id', 68 | 'userData' => array('arraylist', 'element' => array('name' => 'alpha', 'address' => 'required')) 69 | ), Contract::MET_OR_THROW); 70 |71 | 72 | Documentation of PHP-Contract Functionality 73 | ------------------------------------------- 74 | (For detailed usage examples, see https://github.com/axiom82/PHP-Contract/tree/master/Examples, and for more information, see https://github.com/axiom82/PHP-Contract/wiki) 75 | 76 | 77 |
78 | 79 | class MyClass { 80 | 81 | public function myMethod($arg){ 82 | 83 | $contract = new Contract(); 84 | 85 | /* Defining Terms For Method Arguments and Local Variables in Method Scope ... 86 | Note: arguments are already created as terms for you, local variables must be created manually (see below) */ 87 | 88 | $contract->term('arg')->allowed($array); /* The term may be an array containing the specified fields (other fields filtered out, see data();) */ 89 | $contract->term('arg')->alone(); /* The term must be alone, having no siblings */ 90 | $contract->term('arg')->alpha(); /* The term must be an alphabetical string */ 91 | $contract->term('arg')->alphaNumeric(); /* The term must be an alplanumeric string */ 92 | $contract->term('arg')->alphaDash(); /* The term must be an alphanumeric allowing dashes */ 93 | $contract->term('arg')->alphaUnderscore(); /* The term must be an alphanumeric allowing unscores */ 94 | $contract->term('arg')->arraylist(); /* The term must be an array */ 95 | $contract->term('arg')->base64(); /* The term must be a base64 string */ 96 | $contract->term('arg')->between($value, $value2); /* The term must be between the range of the two values */ 97 | $contract->term('arg')->boolean(); /* The term must be a boolean */ 98 | $contract->term('arg')->count($value); /* The term must be the count of the value (for arrays) */ 99 | $contract->term('arg')->decimal(); /* The term must be a decimal */ 100 | $contract->term('arg')->earlier($value); /* The term must be earlier than the value */ 101 | $contract->term('arg')->email(); /* The term must be an email address */ 102 | $contract->term('arg')->equals($value); /* The term must match the value */ 103 | $contract->term('arg')->greaterThan($value); /* The term must be greater than the value */ 104 | $contract->term('arg')->id(); /* The term must be an id (a natural positive number) */ 105 | $contract->term('arg')->in($value); /* The term must be in the values of the array */ 106 | $contract->term('arg')->integer(); /* The term must be an integer */ 107 | $contract->term('arg')->ip(); /* The term must be an ip address */ 108 | $contract->term('arg')->later($value); /* The term must be later than the value */ 109 | $contract->term('arg')->length($value); /* The term must be the length of the value */ 110 | $contract->term('arg')->lessThan($value); /* The term must be less than the value */ 111 | $contract->term('arg')->many(); /* The term must be an array with more than one element */ 112 | $contract->term('arg')->natural(); /* The term must be a natural number */ 113 | $contract->term('arg')->naturalPositive(); /* The term must be a natural positive number */ 114 | $contract->term('arg')->none(); /* The term must be an empty value or values */ 115 | $contract->term('arg')->not($value); /* The term must not be equal to the value or values */ 116 | $contract->term('arg')->null(); /* The term must be null */ 117 | $contract->term('arg')->numeric(); /* The term must be numeric */ 118 | $contract->term('arg')->object($value); /* The term must be an object that is an instance of the value */ 119 | $contract->term('arg')->one(); /* The term must be an array with one and only one element */ 120 | $contract->term('arg')->optional(); /* The term is not required */ 121 | $contract->term('arg')->phone(); /* The term must be a phone number */ 122 | $contract->term('arg')->required(); /* The term must be non-empty */ 123 | $contract->term('arg')->required($values); /* The term must be an array with the specific fields */ 124 | $contract->term('arg')->string(); /* The term must be a string */ 125 | $contract->term('arg')->url(); /* The term must be URL */ 126 | $contract->term('arg')->withData(); /* The term, after the contract filters out invalid data, 127 | must have one or more valid values */ 128 | 129 | /* Defining Terms for Local Variables in Method Scope */ 130 | $contract->term('id', $idVar)->id(); 131 | $contract->term('email', $emailVar)->email(); 132 | $contract->term('password', $passVar)->alphaNumeric()->length(8, 16); 133 | 134 | /* Validation */ 135 | $met = $contract->term('arg')->met(); /* The contract term has a met() method that checks to see if 136 | the term met its own rules, it does so and then returns a 137 | boolean for success or failure */ 138 | if (!$met) return false; /* You may choose to return false when the term has not been met */ 139 | 140 | $met = $contract->met(); /* The contract checks all of its child terms through its met() method, 141 | which calls each contract term's met() method, 142 | and collects the results */ 143 | $contract->metOrThrow(); /* Most useful I think. Equivalent to met(), however, throws an exception 144 | halting the program unless caught. Terms also have their own individual 145 | metOrThrow() method, in case you want to test line by line per term. */ 146 | 147 | /* Post Validation, Obtaining Filtered Data */ 148 | $argData = $contract->term('arg')->data(); /* Returns the term's value(s) as per the contract. 149 | Indeed, the contract presents through its data() method 150 | only the data that meets the contract term rules. If 151 | allowed() is used (see above), data() will return the 152 | allowed value(s) from the original value(s) in the 153 | argument */ 154 | 155 | $argData = $contract->data('arg'); /* This is equivalent in functionality to the line above, however, 156 | this method is cleaner in appearance. The contract proxies to 157 | the term and gets the data via the term's data() method. */ 158 | 159 | /* Debugging: "Which term(s) did not meet the contract?" */ 160 | $contract->debug(); 161 | 162 | /* Or, return the array into your own variable */ 163 | $debug = $contract->debug(true); 164 | 165 | /* Print and review the full definition of the contract */ 166 | echo $contract; /* Prints a clean and readable text describing the contract and its terms */ 167 | 168 | } 169 | 170 | } 171 |172 | --------------------------------------------------------------------------------