diff options
author | Nicolas LÅ“uillet <nicolas@loeuillet.org> | 2014-07-11 17:06:51 +0200 |
---|---|---|
committer | Nicolas LÅ“uillet <nicolas@loeuillet.org> | 2014-07-11 17:06:51 +0200 |
commit | b3cda72e93fff3a4c3476e9e7e78ef2b2a3f02b9 (patch) | |
tree | fb23b73225da5bc3a4466a51915586f60dde802c /inc/3rdparty/PicoFarad | |
parent | 3602405ec0dbc576fce09ff9e865ba2404622080 (diff) | |
download | wallabag-b3cda72e93fff3a4c3476e9e7e78ef2b2a3f02b9.tar.gz wallabag-b3cda72e93fff3a4c3476e9e7e78ef2b2a3f02b9.tar.zst wallabag-b3cda72e93fff3a4c3476e9e7e78ef2b2a3f02b9.zip |
PicoFarad framework for routing
Diffstat (limited to 'inc/3rdparty/PicoFarad')
-rw-r--r-- | inc/3rdparty/PicoFarad/Request.php | 78 | ||||
-rw-r--r-- | inc/3rdparty/PicoFarad/Response.php | 156 | ||||
-rw-r--r-- | inc/3rdparty/PicoFarad/Router.php | 157 | ||||
-rw-r--r-- | inc/3rdparty/PicoFarad/Session.php | 57 | ||||
-rw-r--r-- | inc/3rdparty/PicoFarad/Template.php | 36 |
5 files changed, 484 insertions, 0 deletions
diff --git a/inc/3rdparty/PicoFarad/Request.php b/inc/3rdparty/PicoFarad/Request.php new file mode 100644 index 00000000..46c82bca --- /dev/null +++ b/inc/3rdparty/PicoFarad/Request.php | |||
@@ -0,0 +1,78 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace PicoFarad\Request; | ||
4 | |||
5 | |||
6 | function param($name, $default_value = null) | ||
7 | { | ||
8 | return isset($_GET[$name]) ? $_GET[$name] : $default_value; | ||
9 | } | ||
10 | |||
11 | |||
12 | function int_param($name, $default_value = 0) | ||
13 | { | ||
14 | return isset($_GET[$name]) && ctype_digit($_GET[$name]) ? (int) $_GET[$name] : $default_value; | ||
15 | } | ||
16 | |||
17 | |||
18 | function value($name) | ||
19 | { | ||
20 | $values = values(); | ||
21 | return isset($values[$name]) ? $values[$name] : null; | ||
22 | } | ||
23 | |||
24 | |||
25 | function values() | ||
26 | { | ||
27 | if (! empty($_POST)) { | ||
28 | |||
29 | return $_POST; | ||
30 | } | ||
31 | |||
32 | $result = json_decode(body(), true); | ||
33 | |||
34 | if ($result) { | ||
35 | return $result; | ||
36 | } | ||
37 | |||
38 | return array(); | ||
39 | } | ||
40 | |||
41 | |||
42 | function body() | ||
43 | { | ||
44 | return file_get_contents('php://input'); | ||
45 | } | ||
46 | |||
47 | |||
48 | function file_content($field) | ||
49 | { | ||
50 | if (isset($_FILES[$field])) { | ||
51 | return file_get_contents($_FILES[$field]['tmp_name']); | ||
52 | } | ||
53 | |||
54 | return ''; | ||
55 | } | ||
56 | |||
57 | |||
58 | function file_info($field) | ||
59 | { | ||
60 | if (isset($_FILES[$field])) { | ||
61 | return array( | ||
62 | 'name' => $_FILES[$field]['name'], | ||
63 | 'mimetype' => $_FILES[$field]['type'], | ||
64 | 'size' => $_FILES[$field]['size'], | ||
65 | ); | ||
66 | } | ||
67 | |||
68 | return false; | ||
69 | } | ||
70 | |||
71 | |||
72 | function file_move($field, $destination) | ||
73 | { | ||
74 | if (isset($_FILES[$field]) && ! file_exists($destination)) { | ||
75 | @mkdir(dirname($destination), 0777, true); | ||
76 | move_uploaded_file($_FILES[$field]['tmp_name'], $destination); | ||
77 | } | ||
78 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/PicoFarad/Response.php b/inc/3rdparty/PicoFarad/Response.php new file mode 100644 index 00000000..9114fde0 --- /dev/null +++ b/inc/3rdparty/PicoFarad/Response.php | |||
@@ -0,0 +1,156 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace PicoFarad\Response; | ||
4 | |||
5 | |||
6 | function force_download($filename) | ||
7 | { | ||
8 | header('Content-Disposition: attachment; filename="'.$filename.'"'); | ||
9 | } | ||
10 | |||
11 | |||
12 | function content_type($mimetype) | ||
13 | { | ||
14 | header('Content-Type: '.$mimetype); | ||
15 | } | ||
16 | |||
17 | |||
18 | function status($status_code) | ||
19 | { | ||
20 | $sapi_name = php_sapi_name(); | ||
21 | |||
22 | if (strpos($sapi_name, 'apache') !== false || $sapi_name === 'cli-server') { | ||
23 | header('HTTP/1.0 '.$status_code); | ||
24 | } | ||
25 | else { | ||
26 | header('Status: '.$status_code); | ||
27 | } | ||
28 | } | ||
29 | |||
30 | |||
31 | function redirect($url) | ||
32 | { | ||
33 | header('Location: '.$url); | ||
34 | exit; | ||
35 | } | ||
36 | |||
37 | |||
38 | function json(array $data, $status_code = 200) | ||
39 | { | ||
40 | status($status_code); | ||
41 | |||
42 | header('Content-Type: application/json'); | ||
43 | echo json_encode($data); | ||
44 | |||
45 | exit; | ||
46 | } | ||
47 | |||
48 | |||
49 | function text($data, $status_code = 200) | ||
50 | { | ||
51 | status($status_code); | ||
52 | |||
53 | header('Content-Type: text/plain; charset=utf-8'); | ||
54 | echo $data; | ||
55 | |||
56 | exit; | ||
57 | } | ||
58 | |||
59 | |||
60 | function html($data, $status_code = 200) | ||
61 | { | ||
62 | status($status_code); | ||
63 | |||
64 | header('Content-Type: text/html; charset=utf-8'); | ||
65 | echo $data; | ||
66 | |||
67 | exit; | ||
68 | } | ||
69 | |||
70 | |||
71 | function xml($data, $status_code = 200) | ||
72 | { | ||
73 | status($status_code); | ||
74 | |||
75 | header('Content-Type: text/xml; charset=utf-8'); | ||
76 | echo $data; | ||
77 | |||
78 | exit; | ||
79 | } | ||
80 | |||
81 | |||
82 | function js($data, $status_code = 200) | ||
83 | { | ||
84 | status($status_code); | ||
85 | |||
86 | header('Content-Type: text/javascript; charset=utf-8'); | ||
87 | echo $data; | ||
88 | |||
89 | exit; | ||
90 | } | ||
91 | |||
92 | |||
93 | function binary($data, $status_code = 200) | ||
94 | { | ||
95 | status($status_code); | ||
96 | |||
97 | header('Content-Transfer-Encoding: binary'); | ||
98 | header('Content-Type: application/octet-stream'); | ||
99 | echo $data; | ||
100 | |||
101 | exit; | ||
102 | } | ||
103 | |||
104 | |||
105 | function csp(array $policies = array()) | ||
106 | { | ||
107 | $policies['default-src'] = "'self'"; | ||
108 | $values = ''; | ||
109 | |||
110 | foreach ($policies as $policy => $hosts) { | ||
111 | |||
112 | if (is_array($hosts)) { | ||
113 | |||
114 | $acl = ''; | ||
115 | |||
116 | foreach ($hosts as &$host) { | ||
117 | |||
118 | if ($host === '*' || $host === 'self' || strpos($host, 'http') === 0) { | ||
119 | $acl .= $host.' '; | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | else { | ||
124 | |||
125 | $acl = $hosts; | ||
126 | } | ||
127 | |||
128 | $values .= $policy.' '.trim($acl).'; '; | ||
129 | } | ||
130 | |||
131 | header('Content-Security-Policy: '.$values); | ||
132 | } | ||
133 | |||
134 | |||
135 | function nosniff() | ||
136 | { | ||
137 | header('X-Content-Type-Options: nosniff'); | ||
138 | } | ||
139 | |||
140 | |||
141 | function xss() | ||
142 | { | ||
143 | header('X-XSS-Protection: 1; mode=block'); | ||
144 | } | ||
145 | |||
146 | |||
147 | function hsts() | ||
148 | { | ||
149 | header('Strict-Transport-Security: max-age=31536000'); | ||
150 | } | ||
151 | |||
152 | |||
153 | function xframe($mode = 'DENY', array $urls = array()) | ||
154 | { | ||
155 | header('X-Frame-Options: '.$mode.' '.implode(' ', $urls)); | ||
156 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/PicoFarad/Router.php b/inc/3rdparty/PicoFarad/Router.php new file mode 100644 index 00000000..b62b8e2d --- /dev/null +++ b/inc/3rdparty/PicoFarad/Router.php | |||
@@ -0,0 +1,157 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace PicoFarad\Router; | ||
4 | |||
5 | // Load controllers: bootstrap('controllers', 'controller1', 'controller2') | ||
6 | function bootstrap() | ||
7 | { | ||
8 | $files = \func_get_args(); | ||
9 | $base_path = array_shift($files); | ||
10 | |||
11 | foreach ($files as $file) { | ||
12 | require $base_path.'/'.$file.'.php'; | ||
13 | } | ||
14 | } | ||
15 | |||
16 | // Execute a callback before each action | ||
17 | function before($value = null) | ||
18 | { | ||
19 | static $before_callback = null; | ||
20 | |||
21 | if (is_callable($value)) { | ||
22 | $before_callback = $value; | ||
23 | } | ||
24 | else if (is_callable($before_callback)) { | ||
25 | $before_callback($value); | ||
26 | } | ||
27 | } | ||
28 | |||
29 | // Execute a callback before a specific action | ||
30 | function before_action($name, $value = null) | ||
31 | { | ||
32 | static $callbacks = array(); | ||
33 | |||
34 | if (is_callable($value)) { | ||
35 | $callbacks[$name] = $value; | ||
36 | } | ||
37 | else if (isset($callbacks[$name]) && is_callable($callbacks[$name])) { | ||
38 | $callbacks[$name]($value); | ||
39 | } | ||
40 | } | ||
41 | |||
42 | // Execute an action | ||
43 | function action($name, \Closure $callback) | ||
44 | { | ||
45 | $handler = isset($_GET['action']) ? $_GET['action'] : 'default'; | ||
46 | |||
47 | if ($handler === $name) { | ||
48 | before($name); | ||
49 | before_action($name); | ||
50 | $callback(); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | // Execute an action only for POST requests | ||
55 | function post_action($name, \Closure $callback) | ||
56 | { | ||
57 | if ($_SERVER['REQUEST_METHOD'] === 'POST') { | ||
58 | action($name, $callback); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | // Execute an action only for GET requests | ||
63 | function get_action($name, \Closure $callback) | ||
64 | { | ||
65 | if ($_SERVER['REQUEST_METHOD'] === 'GET') { | ||
66 | action($name, $callback); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | // Run when no action have been executed before | ||
71 | function notfound(\Closure $callback) | ||
72 | { | ||
73 | before('notfound'); | ||
74 | before_action('notfound'); | ||
75 | $callback(); | ||
76 | } | ||
77 | |||
78 | // Match a request like this one: GET /myhandler | ||
79 | function get($url, \Closure $callback) | ||
80 | { | ||
81 | find_route('GET', $url, $callback); | ||
82 | } | ||
83 | |||
84 | // Match a request like this one: POST /myhandler | ||
85 | function post($url, \Closure $callback) | ||
86 | { | ||
87 | find_route('POST', $url, $callback); | ||
88 | } | ||
89 | |||
90 | // Match a request like this one: PUT /myhandler | ||
91 | function put($url, \Closure $callback) | ||
92 | { | ||
93 | find_route('PUT', $url, $callback); | ||
94 | } | ||
95 | |||
96 | // Match a request like this one: DELETE /myhandler | ||
97 | function delete($url, \Closure $callback) | ||
98 | { | ||
99 | find_route('DELETE', $url, $callback); | ||
100 | } | ||
101 | |||
102 | // Define which callback to execute according to the URL and the HTTP verb | ||
103 | function find_route($method, $route, \Closure $callback) | ||
104 | { | ||
105 | if ($_SERVER['REQUEST_METHOD'] === $method) { | ||
106 | |||
107 | if (! empty($_SERVER['QUERY_STRING'])) { | ||
108 | $url = substr($_SERVER['REQUEST_URI'], 0, -(strlen($_SERVER['QUERY_STRING']) + 1)); | ||
109 | } | ||
110 | else { | ||
111 | $url = $_SERVER['REQUEST_URI']; | ||
112 | } | ||
113 | |||
114 | $params = array(); | ||
115 | |||
116 | if (url_match($route, $url, $params)) { | ||
117 | |||
118 | before($route); | ||
119 | \call_user_func_array($callback, $params); | ||
120 | exit; | ||
121 | } | ||
122 | } | ||
123 | } | ||
124 | |||
125 | // Parse url and find matches | ||
126 | function url_match($route_uri, $request_uri, array &$params) | ||
127 | { | ||
128 | if ($request_uri === $route_uri) return true; | ||
129 | if ($route_uri === '/' || $request_uri === '/') return false; | ||
130 | |||
131 | $route_uri = trim($route_uri, '/'); | ||
132 | $request_uri = trim($request_uri, '/'); | ||
133 | |||
134 | $route_items = explode('/', $route_uri); | ||
135 | $request_items = explode('/', $request_uri); | ||
136 | $nb_route_items = count($route_items); | ||
137 | |||
138 | if ($nb_route_items === count($request_items)) { | ||
139 | |||
140 | for ($i = 0; $i < $nb_route_items; ++$i) { | ||
141 | |||
142 | if ($route_items[$i][0] === ':') { | ||
143 | |||
144 | $params[substr($route_items[$i], 1)] = $request_items[$i]; | ||
145 | } | ||
146 | else if ($route_items[$i] !== $request_items[$i]) { | ||
147 | |||
148 | $params = array(); | ||
149 | return false; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | return true; | ||
154 | } | ||
155 | |||
156 | return false; | ||
157 | } | ||
diff --git a/inc/3rdparty/PicoFarad/Session.php b/inc/3rdparty/PicoFarad/Session.php new file mode 100644 index 00000000..ee7b415a --- /dev/null +++ b/inc/3rdparty/PicoFarad/Session.php | |||
@@ -0,0 +1,57 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace PicoFarad\Session; | ||
4 | |||
5 | const SESSION_LIFETIME = 2678400; | ||
6 | |||
7 | |||
8 | function open($base_path = '/', $save_path = '') | ||
9 | { | ||
10 | if ($save_path !== '') session_save_path($save_path); | ||
11 | |||
12 | // HttpOnly and secure flags for session cookie | ||
13 | session_set_cookie_params( | ||
14 | SESSION_LIFETIME, | ||
15 | $base_path ?: '/', | ||
16 | null, | ||
17 | isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on', | ||
18 | true | ||
19 | ); | ||
20 | |||
21 | // Avoid session id in the URL | ||
22 | ini_set('session.use_only_cookies', true); | ||
23 | |||
24 | // Ensure session ID integrity | ||
25 | ini_set('session.entropy_file', '/dev/urandom'); | ||
26 | ini_set('session.entropy_length', '32'); | ||
27 | ini_set('session.hash_bits_per_character', 6); | ||
28 | |||
29 | // Custom session name | ||
30 | session_name('__$'); | ||
31 | |||
32 | session_start(); | ||
33 | |||
34 | // Regenerate the session id to avoid session fixation issue | ||
35 | if (empty($_SESSION['__validated'])) { | ||
36 | session_regenerate_id(true); | ||
37 | $_SESSION['__validated'] = 1; | ||
38 | } | ||
39 | } | ||
40 | |||
41 | |||
42 | function close() | ||
43 | { | ||
44 | session_destroy(); | ||
45 | } | ||
46 | |||
47 | |||
48 | function flash($message) | ||
49 | { | ||
50 | $_SESSION['flash_message'] = $message; | ||
51 | } | ||
52 | |||
53 | |||
54 | function flash_error($message) | ||
55 | { | ||
56 | $_SESSION['flash_error_message'] = $message; | ||
57 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/PicoFarad/Template.php b/inc/3rdparty/PicoFarad/Template.php new file mode 100644 index 00000000..c32be309 --- /dev/null +++ b/inc/3rdparty/PicoFarad/Template.php | |||
@@ -0,0 +1,36 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace PicoFarad\Template; | ||
4 | |||
5 | const PATH = 'templates/'; | ||
6 | |||
7 | // Template\load('template_name', ['bla' => 'value']); | ||
8 | function load() | ||
9 | { | ||
10 | if (func_num_args() < 1 || func_num_args() > 2) { | ||
11 | die('Invalid template arguments'); | ||
12 | } | ||
13 | |||
14 | if (! file_exists(PATH.func_get_arg(0).'.php')) { | ||
15 | die('Unable to load the template: "'.func_get_arg(0).'"'); | ||
16 | } | ||
17 | |||
18 | if (func_num_args() === 2) { | ||
19 | |||
20 | if (! is_array(func_get_arg(1))) { | ||
21 | die('Template variables must be an array'); | ||
22 | } | ||
23 | |||
24 | extract(func_get_arg(1)); | ||
25 | } | ||
26 | |||
27 | ob_start(); | ||
28 | include PATH.func_get_arg(0).'.php'; | ||
29 | return ob_get_clean(); | ||
30 | } | ||
31 | |||
32 | |||
33 | function layout($template_name, array $template_args = array(), $layout_name = 'layout') | ||
34 | { | ||
35 | return load($layout_name, $template_args + array('content_for_layout' => load($template_name, $template_args))); | ||
36 | } | ||