-
Notifications
You must be signed in to change notification settings - Fork 0
/
core.php
210 lines (191 loc) · 6.83 KB
/
core.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
<?php namespace Px;
/*
Part of Plarx | https://github.com/ProgerXP/Plarx
*/
/*-----------------------------------------------------------------------
| HTTP STATUS CODES
|----------------------------------------------------------------------*/
// These constants can be used in DoubleEdge responses, for example:
//
// function get_index($id) {
// if ($model = AModel::find($id)) {
// return $model;
// } else {
// return E_NONE;
// }
// }
define('Px\\E_OK', 200);
define('Px\\E_UNCHANGED', 304);
define('Px\\E_INPUT', 400);
define('Px\\E_UNAUTH', 401);
define('Px\\E_DENIED', 403);
define('Px\\E_NONE', 404);
define('Px\\E_GONE', 410);
define('Px\\E_SERVER', 500);
/*-----------------------------------------------------------------------
| CUSTOM EXCEPTIONS
|----------------------------------------------------------------------*/
// Generic exception, parent for all Plarx exceptions.
class EPlarx extends \Exception { }
// Exception used for JSON-related errors such as string decoding or encoding.
class EJSON extends EPlarx {
//= int json_last_error() result
//= null if unknown
public $jsonError;
//* $code int, null - json_last_error() code, if available.
function __construct($msg, $code = null) {
$this->jsonError = $code;
func_num_args() > 1 and $msg .= " - error code $code.";
parent::__construct($msg);
}
}
// Exception used when a required request variable is missing.
class ENoInput extends EPlarx {
//= str input variable name that wasn't passed
//= null unspecified var name
public $key;
//* $key str, null - name of missing request variable, if available.
function __construct($key = null) {
"$key" === '' or $this->key = $key;
$name = "$key" === '' ? '' : " [$key]";
parent::__construct("No input variable$name given.");
}
}
// Exception used when client is expected to be authorized but it isn't.
class ENoAuth extends EPlarx {
// Reference to controller that has caused this exception.
//
//= object
//= str name like 'bndl::ctl.sub@actn'
public $controller;
//* $controller object, str, null - controller requiring authentication, if available.
function __construct($controller = null) {
$this->controller = $controller;
is_object($controller) and $controller = get_class($controller);
parent::__construct("Controller [$controller] expects an authorized user.");
}
}
// Exception used when an event didn't return expected value or some other conditions
// have not been met.
class EEvent extends EPlarx { }
/*-----------------------------------------------------------------------
| GLOBAL FUNCTIONS
|----------------------------------------------------------------------*/
// function (str $prop)
//
// Creates function ($obj) that returns $obj->$prop or null if $obj isn't an object.
// Useful for array_map(), array_filter() and the likes.
//
//= Closure ($obj)
//
//? array_omit(prop('available'), $goods);
// // removes objects from $goods that have falsy ->$available property
//? array_map(prop('id'), $models);
// // returns array containing each $models' member ID (ignoring non-objects)
//
// function (str $prop, array $array)
//
// Maps $array with the function produced by the first version ($array-less).
//
//= array
//
//? prop('id', $models);
// // identical to array_map(prop('id'), $models);
function prop($prop, array $toMap = null) {
if (func_num_args() > 1) {
return array_map(prop($prop), (array) $toMap);
} else {
return function ($obj) use ($prop) {
return is_object($obj) ? $obj->$prop : null;
};
}
}
// function (str $func)
//
// Creates function ($obj) that returns the result of calling $obj->$func() or
// null if $obj isn't an object.
// Useful for array_map(), array_filter() and the likes.
//
//= Closure ($obj)
//
//? array_filter(func('dirty'), $models);
// // keeps $models' objects which method dirty() returns non-falsy value
//? array_map(func('to_array'), $models);
// // converts each $models' object into array by calling their to_array() method
//
// function (str $func, array $array)
//
// Maps $array with the function produced by the first version ($array-less).
//
//= array
//
//? prop('to_array', $models);
// // identical to array_map(func('to_array'), $models);
function func($func, array $toMap = null) {
if (func_num_args() > 1) {
return array_map(func($func), (array) $toMap);
} else {
return function ($obj) use ($func) {
return is_object($obj) ? $obj->$func() : null;
};
}
}
// The opposite of array_filter(). Preserves array keys.
//
//* $func callable ($item), null - if given removes items from $array to which
// $func($item) returned a non-falsy value; if omitted keeps only falsy members.
//
//? $missingPerms = array_keys(array_omit(array('perm1' => true, 'perm2' => false)));
// //=> array('perm2')
//? array_omit(range(-3, 3), function ($n) { return $n > 1; });
// //=> array(2, 3)
function array_omit($array, $func = null) {
return array_filter($array, function ($value) use ($func) {
return $func ? !call_user_func($func, $value) : !$value;
});
}
// Converts $value to array. Unlike (array) will return empty array on null $value
// and array($value) on object $value. See also arrizeAny().
//
//* $value mixed
//* $key mixed - used when $value is not an array to assign initial member's key.
//
//= array
//
//? arrize(null); //=> array()
//? arrize(array()); //=> array()
//? arrize(array('foo')); //=> array('foo')
//? arrize('foo'); //=> array('foo')
//? arrize('foo', 'bar'); //=> array('bar' => 'foo')
//? arrize(array('foo'), 'bar'); //=> array('foo')
//? arrize(new stdClass); //=> array(new stdClass)
//? arrize(new stdClass, 4444); //=> array(4444 => new stdClass)
//? arrize(function () { }, 1); //=> array(1 => function () { })
function arrize($value, $key = 0) {
return $value === null ? array() : arrizeAny($value, $key);
}
// Converts given value to array. Unlike (array) it doesn't convert objects and
// doesn't cause Fatal Error when given a Closure. Returns array(null) on null $value.
//
// See also arrize().
//
//* $value mixed
//* $key mixed - used when $value is not an array to assign initial member's key.
//
//= array
//
//? arrize(null); //=> array(null)
//? plus all other examples from arrize()
function arrizeAny($value, $key = 0) {
return is_array($value) ? $value : array($key => $value);
}
// Changes array keys by invoking $func as ($keys, $value) and using its return
// value as new key.
//
//? array_set_keys(array('a' => 'b'), function ($k) { return "-$k-"; });
// //=> array('-a-' => 'b')
function array_set_keys(array $array, $func) {
$keys = array();
foreach ($array as $key => &$value) { $keys[] = $func($key, $value); }
return $array ? array_combine($keys, $array) : array();
}