aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNicolas LÅ“uillet <nicolas@loeuillet.org>2014-07-11 17:06:51 +0200
committerNicolas LÅ“uillet <nicolas@loeuillet.org>2014-07-11 17:06:51 +0200
commitb3cda72e93fff3a4c3476e9e7e78ef2b2a3f02b9 (patch)
treefb23b73225da5bc3a4466a51915586f60dde802c
parent3602405ec0dbc576fce09ff9e865ba2404622080 (diff)
downloadwallabag-b3cda72e93fff3a4c3476e9e7e78ef2b2a3f02b9.tar.gz
wallabag-b3cda72e93fff3a4c3476e9e7e78ef2b2a3f02b9.tar.zst
wallabag-b3cda72e93fff3a4c3476e9e7e78ef2b2a3f02b9.zip
PicoFarad framework for routing
-rw-r--r--inc/3rdparty/PicoFarad/Request.php78
-rw-r--r--inc/3rdparty/PicoFarad/Response.php156
-rw-r--r--inc/3rdparty/PicoFarad/Router.php157
-rw-r--r--inc/3rdparty/PicoFarad/Session.php57
-rw-r--r--inc/3rdparty/PicoFarad/Template.php36
-rwxr-xr-xinc/poche/Database.class.php138
-rw-r--r--inc/poche/Routing.class.php8
-rwxr-xr-xinc/poche/global.inc.php19
-rwxr-xr-xindex.php60
9 files changed, 646 insertions, 63 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
3namespace PicoFarad\Request;
4
5
6function param($name, $default_value = null)
7{
8 return isset($_GET[$name]) ? $_GET[$name] : $default_value;
9}
10
11
12function int_param($name, $default_value = 0)
13{
14 return isset($_GET[$name]) && ctype_digit($_GET[$name]) ? (int) $_GET[$name] : $default_value;
15}
16
17
18function value($name)
19{
20 $values = values();
21 return isset($values[$name]) ? $values[$name] : null;
22}
23
24
25function 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
42function body()
43{
44 return file_get_contents('php://input');
45}
46
47
48function 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
58function 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
72function 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
3namespace PicoFarad\Response;
4
5
6function force_download($filename)
7{
8 header('Content-Disposition: attachment; filename="'.$filename.'"');
9}
10
11
12function content_type($mimetype)
13{
14 header('Content-Type: '.$mimetype);
15}
16
17
18function 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
31function redirect($url)
32{
33 header('Location: '.$url);
34 exit;
35}
36
37
38function 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
49function 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
60function 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
71function 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
82function 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
93function 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
105function 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
135function nosniff()
136{
137 header('X-Content-Type-Options: nosniff');
138}
139
140
141function xss()
142{
143 header('X-XSS-Protection: 1; mode=block');
144}
145
146
147function hsts()
148{
149 header('Strict-Transport-Security: max-age=31536000');
150}
151
152
153function 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
3namespace PicoFarad\Router;
4
5// Load controllers: bootstrap('controllers', 'controller1', 'controller2')
6function 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
17function 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
30function 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
43function 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
55function 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
63function 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
71function notfound(\Closure $callback)
72{
73 before('notfound');
74 before_action('notfound');
75 $callback();
76}
77
78// Match a request like this one: GET /myhandler
79function get($url, \Closure $callback)
80{
81 find_route('GET', $url, $callback);
82}
83
84// Match a request like this one: POST /myhandler
85function post($url, \Closure $callback)
86{
87 find_route('POST', $url, $callback);
88}
89
90// Match a request like this one: PUT /myhandler
91function put($url, \Closure $callback)
92{
93 find_route('PUT', $url, $callback);
94}
95
96// Match a request like this one: DELETE /myhandler
97function 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
103function 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
126function 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
3namespace PicoFarad\Session;
4
5const SESSION_LIFETIME = 2678400;
6
7
8function 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
42function close()
43{
44 session_destroy();
45}
46
47
48function flash($message)
49{
50 $_SESSION['flash_message'] = $message;
51}
52
53
54function 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
3namespace PicoFarad\Template;
4
5const PATH = 'templates/';
6
7// Template\load('template_name', ['bla' => 'value']);
8function 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
33function 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}
diff --git a/inc/poche/Database.class.php b/inc/poche/Database.class.php
index 9c1c0286..8d74f2ff 100755
--- a/inc/poche/Database.class.php
+++ b/inc/poche/Database.class.php
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11class Database { 11class Database {
12
12 var $handle; 13 var $handle;
13 private $order = array( 14 private $order = array(
14 'ia' => 'ORDER BY entries.id', 15 'ia' => 'ORDER BY entries.id',
@@ -42,11 +43,13 @@ class Database {
42 Tools::logm('storage type ' . STORAGE); 43 Tools::logm('storage type ' . STORAGE);
43 } 44 }
44 45
45 private function getHandle() { 46 private function getHandle()
47 {
46 return $this->handle; 48 return $this->handle;
47 } 49 }
48 50
49 private function _checkTags() { 51 private function _checkTags()
52 {
50 53
51 if (STORAGE == 'sqlite') { 54 if (STORAGE == 'sqlite') {
52 $sql = ' 55 $sql = '
@@ -110,7 +113,8 @@ class Database {
110 $query = $this->executeQuery($sql, array()); 113 $query = $this->executeQuery($sql, array());
111 } 114 }
112 115
113 public function install($login, $password) { 116 public function install($login, $password)
117 {
114 $sql = 'INSERT INTO users ( username, password, name, email) VALUES (?, ?, ?, ?)'; 118 $sql = 'INSERT INTO users ( username, password, name, email) VALUES (?, ?, ?, ?)';
115 $params = array($login, $password, $login, ' '); 119 $params = array($login, $password, $login, ' ');
116 $query = $this->executeQuery($sql, $params); 120 $query = $this->executeQuery($sql, $params);
@@ -137,7 +141,8 @@ class Database {
137 return TRUE; 141 return TRUE;
138 } 142 }
139 143
140 public function getConfigUser($id) { 144 public function getConfigUser($id)
145 {
141 $sql = "SELECT * FROM users_config WHERE user_id = ?"; 146 $sql = "SELECT * FROM users_config WHERE user_id = ?";
142 $query = $this->executeQuery($sql, array($id)); 147 $query = $this->executeQuery($sql, array($id));
143 $result = $query->fetchAll(); 148 $result = $query->fetchAll();
@@ -150,7 +155,8 @@ class Database {
150 return $user_config; 155 return $user_config;
151 } 156 }
152 157
153 public function userExists($username) { 158 public function userExists($username)
159 {
154 $sql = "SELECT * FROM users WHERE username=?"; 160 $sql = "SELECT * FROM users WHERE username=?";
155 $query = $this->executeQuery($sql, array($username)); 161 $query = $this->executeQuery($sql, array($username));
156 $login = $query->fetchAll(); 162 $login = $query->fetchAll();
@@ -161,7 +167,8 @@ class Database {
161 } 167 }
162 } 168 }
163 169
164 public function login($username, $password, $isauthenticated=false) { 170 public function login($username, $password, $isauthenticated = FALSE)
171 {
165 if ($isauthenticated) { 172 if ($isauthenticated) {
166 $sql = "SELECT * FROM users WHERE username=?"; 173 $sql = "SELECT * FROM users WHERE username=?";
167 $query = $this->executeQuery($sql, array($username)); 174 $query = $this->executeQuery($sql, array($username));
@@ -191,7 +198,8 @@ class Database {
191 $query = $this->executeQuery($sql_update, $params_update); 198 $query = $this->executeQuery($sql_update, $params_update);
192 } 199 }
193 200
194 public function updateUserConfig($userId, $key, $value) { 201 public function updateUserConfig($userId, $key, $value)
202 {
195 $config = $this->getConfigUser($userId); 203 $config = $this->getConfigUser($userId);
196 204
197 if (! isset($config[$key])) { 205 if (! isset($config[$key])) {
@@ -205,7 +213,8 @@ class Database {
205 $query = $this->executeQuery($sql, $params); 213 $query = $this->executeQuery($sql, $params);
206 } 214 }
207 215
208 private function executeQuery($sql, $params) { 216 private function executeQuery($sql, $params)
217 {
209 try 218 try
210 { 219 {
211 $query = $this->getHandle()->prepare($sql); 220 $query = $this->getHandle()->prepare($sql);
@@ -219,28 +228,32 @@ class Database {
219 } 228 }
220 } 229 }
221 230
222 public function listUsers($username=null) { 231 public function listUsers($username = NULL)
232 {
223 $sql = 'SELECT count(*) FROM users'.( $username ? ' WHERE username=?' : ''); 233 $sql = 'SELECT count(*) FROM users'.( $username ? ' WHERE username=?' : '');
224 $query = $this->executeQuery($sql, ( $username ? array($username) : array())); 234 $query = $this->executeQuery($sql, ( $username ? array($username) : array()));
225 list($count) = $query->fetch(); 235 list($count) = $query->fetch();
226 return $count; 236 return $count;
227 } 237 }
228 238
229 public function getUserPassword($userID) { 239 public function getUserPassword($userID)
240 {
230 $sql = "SELECT * FROM users WHERE id=?"; 241 $sql = "SELECT * FROM users WHERE id=?";
231 $query = $this->executeQuery($sql, array($userID)); 242 $query = $this->executeQuery($sql, array($userID));
232 $password = $query->fetchAll(); 243 $password = $query->fetchAll();
233 return isset($password[0]['password']) ? $password[0]['password'] : null; 244 return isset($password[0]['password']) ? $password[0]['password'] : null;
234 } 245 }
235 246
236 public function deleteUserConfig($userID) { 247 public function deleteUserConfig($userID)
248 {
237 $sql_action = 'DELETE from users_config WHERE user_id=?'; 249 $sql_action = 'DELETE from users_config WHERE user_id=?';
238 $params_action = array($userID); 250 $params_action = array($userID);
239 $query = $this->executeQuery($sql_action, $params_action); 251 $query = $this->executeQuery($sql_action, $params_action);
240 return $query; 252 return $query;
241 } 253 }
242 254
243 public function deleteTagsEntriesAndEntries($userID) { 255 public function deleteTagsEntriesAndEntries($userID)
256 {
244 $entries = $this->retrieveAll($userID); 257 $entries = $this->retrieveAll($userID);
245 foreach($entries as $entryid) { 258 foreach($entries as $entryid) {
246 $tags = $this->retrieveTagsByEntry($entryid); 259 $tags = $this->retrieveTagsByEntry($entryid);
@@ -251,20 +264,23 @@ class Database {
251 } 264 }
252 } 265 }
253 266
254 public function deleteUser($userID) { 267 public function deleteUser($userID)
268 {
255 $sql_action = 'DELETE from users WHERE id=?'; 269 $sql_action = 'DELETE from users WHERE id=?';
256 $params_action = array($userID); 270 $params_action = array($userID);
257 $query = $this->executeQuery($sql_action, $params_action); 271 $query = $this->executeQuery($sql_action, $params_action);
258 } 272 }
259 273
260 public function updateContentAndTitle($id, $title, $body, $user_id) { 274 public function updateContentAndTitle($id, $title, $body, $user_id)
275 {
261 $sql_action = 'UPDATE entries SET content = ?, title = ? WHERE id=? AND user_id=?'; 276 $sql_action = 'UPDATE entries SET content = ?, title = ? WHERE id=? AND user_id=?';
262 $params_action = array($body, $title, $id, $user_id); 277 $params_action = array($body, $title, $id, $user_id);
263 $query = $this->executeQuery($sql_action, $params_action); 278 $query = $this->executeQuery($sql_action, $params_action);
264 return $query; 279 return $query;
265 } 280 }
266 281
267 public function retrieveUnfetchedEntries($user_id, $limit) { 282 public function retrieveUnfetchedEntries($user_id, $limit)
283 {
268 284
269 $sql_limit = "LIMIT 0,".$limit; 285 $sql_limit = "LIMIT 0,".$limit;
270 if (STORAGE == 'postgres') { 286 if (STORAGE == 'postgres') {
@@ -278,7 +294,8 @@ class Database {
278 return $entries; 294 return $entries;
279 } 295 }
280 296
281 public function retrieveUnfetchedEntriesCount($user_id) { 297 public function retrieveUnfetchedEntriesCount($user_id)
298 {
282 $sql = "SELECT count(*) FROM entries WHERE (content = '' OR content IS NULL) AND title LIKE 'Untitled - Import%' AND user_id=?"; 299 $sql = "SELECT count(*) FROM entries WHERE (content = '' OR content IS NULL) AND title LIKE 'Untitled - Import%' AND user_id=?";
283 $query = $this->executeQuery($sql, array($user_id)); 300 $query = $this->executeQuery($sql, array($user_id));
284 list($count) = $query->fetch(); 301 list($count) = $query->fetch();
@@ -286,7 +303,8 @@ class Database {
286 return $count; 303 return $count;
287 } 304 }
288 305
289 public function retrieveAll($user_id) { 306 public function retrieveAll($user_id)
307 {
290 $sql = "SELECT * FROM entries WHERE user_id=? ORDER BY id"; 308 $sql = "SELECT * FROM entries WHERE user_id=? ORDER BY id";
291 $query = $this->executeQuery($sql, array($user_id)); 309 $query = $this->executeQuery($sql, array($user_id));
292 $entries = $query->fetchAll(); 310 $entries = $query->fetchAll();
@@ -294,7 +312,8 @@ class Database {
294 return $entries; 312 return $entries;
295 } 313 }
296 314
297 public function retrieveOneById($id, $user_id) { 315 public function retrieveOneById($id, $user_id)
316 {
298 $entry = NULL; 317 $entry = NULL;
299 $sql = "SELECT * FROM entries WHERE id=? AND user_id=?"; 318 $sql = "SELECT * FROM entries WHERE id=? AND user_id=?";
300 $params = array(intval($id), $user_id); 319 $params = array(intval($id), $user_id);
@@ -304,7 +323,8 @@ class Database {
304 return isset($entry[0]) ? $entry[0] : null; 323 return isset($entry[0]) ? $entry[0] : null;
305 } 324 }
306 325
307 public function retrieveOneByURL($url, $user_id) { 326 public function retrieveOneByURL($url, $user_id)
327 {
308 $entry = NULL; 328 $entry = NULL;
309 $sql = "SELECT * FROM entries WHERE url=? AND user_id=?"; 329 $sql = "SELECT * FROM entries WHERE url=? AND user_id=?";
310 $params = array($url, $user_id); 330 $params = array($url, $user_id);
@@ -314,13 +334,15 @@ class Database {
314 return isset($entry[0]) ? $entry[0] : null; 334 return isset($entry[0]) ? $entry[0] : null;
315 } 335 }
316 336
317 public function reassignTags($old_entry_id, $new_entry_id) { 337 public function reassignTags($old_entry_id, $new_entry_id)
338 {
318 $sql = "UPDATE tags_entries SET entry_id=? WHERE entry_id=?"; 339 $sql = "UPDATE tags_entries SET entry_id=? WHERE entry_id=?";
319 $params = array($new_entry_id, $old_entry_id); 340 $params = array($new_entry_id, $old_entry_id);
320 $query = $this->executeQuery($sql, $params); 341 $query = $this->executeQuery($sql, $params);
321 } 342 }
322 343
323 public function getEntriesByView($view, $user_id, $limit = '', $tag_id = 0) { 344 public function getEntriesByView($view, $user_id, $limit = '', $tag_id = 0)
345 {
324 switch ($view) { 346 switch ($view) {
325 case 'archive': 347 case 'archive':
326 $sql = "SELECT * FROM entries WHERE user_id=? AND is_read=? "; 348 $sql = "SELECT * FROM entries WHERE user_id=? AND is_read=? ";
@@ -348,9 +370,10 @@ class Database {
348 $entries = $query->fetchAll(); 370 $entries = $query->fetchAll();
349 371
350 return $entries; 372 return $entries;
351 } 373 }
352 374
353 public function getEntriesByViewCount($view, $user_id, $tag_id = 0) { 375 public function getEntriesByViewCount($view, $user_id, $tag_id = 0)
376 {
354 switch ($view) { 377 switch ($view) {
355 case 'archive': 378 case 'archive':
356 $sql = "SELECT count(*) FROM entries WHERE user_id=? AND is_read=? "; 379 $sql = "SELECT count(*) FROM entries WHERE user_id=? AND is_read=? ";
@@ -378,7 +401,8 @@ class Database {
378 return $count; 401 return $count;
379 } 402 }
380 403
381 public function updateContent($id, $content, $user_id) { 404 public function updateContent($id, $content, $user_id)
405 {
382 $sql_action = 'UPDATE entries SET content = ? WHERE id=? AND user_id=?'; 406 $sql_action = 'UPDATE entries SET content = ? WHERE id=? AND user_id=?';
383 $params_action = array($content, $id, $user_id); 407 $params_action = array($content, $id, $user_id);
384 $query = $this->executeQuery($sql_action, $params_action); 408 $query = $this->executeQuery($sql_action, $params_action);
@@ -393,7 +417,8 @@ class Database {
393 * @param integer $user_id 417 * @param integer $user_id
394 * @return integer $id of inserted record 418 * @return integer $id of inserted record
395 */ 419 */
396 public function add($url, $title, $content, $user_id, $isFavorite=0, $isRead=0) { 420 public function add($url, $title, $content, $user_id, $isFavorite=0, $isRead=0)
421 {
397 $sql_action = 'INSERT INTO entries ( url, title, content, user_id, is_fav, is_read ) VALUES (?, ?, ?, ?, ?, ?)'; 422 $sql_action = 'INSERT INTO entries ( url, title, content, user_id, is_fav, is_read ) VALUES (?, ?, ?, ?, ?, ?)';
398 $params_action = array($url, $title, $content, $user_id, $isFavorite, $isRead); 423 $params_action = array($url, $title, $content, $user_id, $isFavorite, $isRead);
399 424
@@ -406,36 +431,42 @@ class Database {
406 return $id; 431 return $id;
407 } 432 }
408 433
409 public function deleteById($id, $user_id) { 434 public function deleteById($id, $user_id)
435 {
410 $sql_action = "DELETE FROM entries WHERE id=? AND user_id=?"; 436 $sql_action = "DELETE FROM entries WHERE id=? AND user_id=?";
411 $params_action = array($id, $user_id); 437 $params_action = array($id, $user_id);
412 $query = $this->executeQuery($sql_action, $params_action); 438 $query = $this->executeQuery($sql_action, $params_action);
413 return $query; 439 return $query;
414 } 440 }
415 441
416 public function favoriteById($id, $user_id) { 442 public function favoriteById($id, $user_id)
443 {
417 $sql_action = "UPDATE entries SET is_fav=NOT is_fav WHERE id=? AND user_id=?"; 444 $sql_action = "UPDATE entries SET is_fav=NOT is_fav WHERE id=? AND user_id=?";
418 $params_action = array($id, $user_id); 445 $params_action = array($id, $user_id);
419 $query = $this->executeQuery($sql_action, $params_action); 446 $query = $this->executeQuery($sql_action, $params_action);
420 } 447 }
421 448
422 public function archiveById($id, $user_id) { 449 public function archiveById($id, $user_id)
450 {
423 $sql_action = "UPDATE entries SET is_read=NOT is_read WHERE id=? AND user_id=?"; 451 $sql_action = "UPDATE entries SET is_read=NOT is_read WHERE id=? AND user_id=?";
424 $params_action = array($id, $user_id); 452 $params_action = array($id, $user_id);
425 $query = $this->executeQuery($sql_action, $params_action); 453 $query = $this->executeQuery($sql_action, $params_action);
426 } 454 }
427 455
428 public function archiveAll($user_id) { 456 public function archiveAll($user_id)
457 {
429 $sql_action = "UPDATE entries SET is_read=? WHERE user_id=? AND is_read=?"; 458 $sql_action = "UPDATE entries SET is_read=? WHERE user_id=? AND is_read=?";
430 $params_action = array($user_id, 1, 0); 459 $params_action = array($user_id, 1, 0);
431 $query = $this->executeQuery($sql_action, $params_action); 460 $query = $this->executeQuery($sql_action, $params_action);
432 } 461 }
433 462
434 public function getLastId($column = '') { 463 public function getLastId($column = '')
464 {
435 return $this->getHandle()->lastInsertId($column); 465 return $this->getHandle()->lastInsertId($column);
436 } 466 }
437 467
438 public function search($term, $user_id, $limit = '') { 468 public function search($term, $user_id, $limit = '')
469 {
439 $search = '%'.$term.'%'; 470 $search = '%'.$term.'%';
440 $sql_action = "SELECT * FROM entries WHERE user_id=? AND (content LIKE ? OR title LIKE ? OR url LIKE ?) "; //searches in content, title and URL 471 $sql_action = "SELECT * FROM entries WHERE user_id=? AND (content LIKE ? OR title LIKE ? OR url LIKE ?) "; //searches in content, title and URL
441 $sql_action .= $this->getEntriesOrder().' ' . $limit; 472 $sql_action .= $this->getEntriesOrder().' ' . $limit;
@@ -444,7 +475,8 @@ class Database {
444 return $query->fetchAll(); 475 return $query->fetchAll();
445 } 476 }
446 477
447 public function retrieveAllTags($user_id, $term = null) { 478 public function retrieveAllTags($user_id, $term = NULL)
479 {
448 $sql = "SELECT DISTINCT tags.*, count(entries.id) AS entriescount FROM tags 480 $sql = "SELECT DISTINCT tags.*, count(entries.id) AS entriescount FROM tags
449 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id 481 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id
450 LEFT JOIN entries ON tags_entries.entry_id=entries.id 482 LEFT JOIN entries ON tags_entries.entry_id=entries.id
@@ -458,7 +490,8 @@ class Database {
458 return $tags; 490 return $tags;
459 } 491 }
460 492
461 public function retrieveTag($id, $user_id) { 493 public function retrieveTag($id, $user_id)
494 {
462 $tag = NULL; 495 $tag = NULL;
463 $sql = "SELECT DISTINCT tags.* FROM tags 496 $sql = "SELECT DISTINCT tags.* FROM tags
464 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id 497 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id
@@ -468,10 +501,11 @@ class Database {
468 $query = $this->executeQuery($sql, $params); 501 $query = $this->executeQuery($sql, $params);
469 $tag = $query->fetchAll(); 502 $tag = $query->fetchAll();
470 503
471 return isset($tag[0]) ? $tag[0] : null; 504 return isset($tag[0]) ? $tag[0] : NULL;
472 } 505 }
473 506
474 public function retrieveEntriesByTag($tag_id, $user_id) { 507 public function retrieveEntriesByTag($tag_id, $user_id)
508 {
475 $sql = 509 $sql =
476 "SELECT entries.* FROM entries 510 "SELECT entries.* FROM entries
477 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id 511 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id
@@ -482,7 +516,8 @@ class Database {
482 return $entries; 516 return $entries;
483 } 517 }
484 518
485 public function retrieveTagsByEntry($entry_id) { 519 public function retrieveTagsByEntry($entry_id)
520 {
486 $sql = 521 $sql =
487 "SELECT tags.* FROM tags 522 "SELECT tags.* FROM tags
488 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id 523 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id
@@ -493,14 +528,16 @@ class Database {
493 return $tags; 528 return $tags;
494 } 529 }
495 530
496 public function removeTagForEntry($entry_id, $tag_id) { 531 public function removeTagForEntry($entry_id, $tag_id)
532 {
497 $sql_action = "DELETE FROM tags_entries WHERE tag_id=? AND entry_id=?"; 533 $sql_action = "DELETE FROM tags_entries WHERE tag_id=? AND entry_id=?";
498 $params_action = array($tag_id, $entry_id); 534 $params_action = array($tag_id, $entry_id);
499 $query = $this->executeQuery($sql_action, $params_action); 535 $query = $this->executeQuery($sql_action, $params_action);
500 return $query; 536 return $query;
501 } 537 }
502 538
503 public function cleanUnusedTag($tag_id) { 539 public function cleanUnusedTag($tag_id)
540 {
504 $sql_action = "SELECT tags.* FROM tags JOIN tags_entries ON tags_entries.tag_id=tags.id WHERE tags.id=?"; 541 $sql_action = "SELECT tags.* FROM tags JOIN tags_entries ON tags_entries.tag_id=tags.id WHERE tags.id=?";
505 $query = $this->executeQuery($sql_action,array($tag_id)); 542 $query = $this->executeQuery($sql_action,array($tag_id));
506 $tagstokeep = $query->fetchAll(); 543 $tagstokeep = $query->fetchAll();
@@ -519,7 +556,8 @@ class Database {
519 556
520 } 557 }
521 558
522 public function retrieveTagByValue($value) { 559 public function retrieveTagByValue($value)
560 {
523 $tag = NULL; 561 $tag = NULL;
524 $sql = "SELECT * FROM tags WHERE value=?"; 562 $sql = "SELECT * FROM tags WHERE value=?";
525 $params = array($value); 563 $params = array($value);
@@ -529,27 +567,29 @@ class Database {
529 return isset($tag[0]) ? $tag[0] : null; 567 return isset($tag[0]) ? $tag[0] : null;
530 } 568 }
531 569
532 public function createTag($value) { 570 public function createTag($value)
571 {
533 $sql_action = 'INSERT INTO tags ( value ) VALUES (?)'; 572 $sql_action = 'INSERT INTO tags ( value ) VALUES (?)';
534 $params_action = array($value); 573 $params_action = array($value);
535 $query = $this->executeQuery($sql_action, $params_action); 574 $query = $this->executeQuery($sql_action, $params_action);
536 return $query; 575 return $query;
537 } 576 }
538 577
539 public function setTagToEntry($tag_id, $entry_id) { 578 public function setTagToEntry($tag_id, $entry_id)
579 {
540 $sql_action = 'INSERT INTO tags_entries ( tag_id, entry_id ) VALUES (?, ?)'; 580 $sql_action = 'INSERT INTO tags_entries ( tag_id, entry_id ) VALUES (?, ?)';
541 $params_action = array($tag_id, $entry_id); 581 $params_action = array($tag_id, $entry_id);
542 $query = $this->executeQuery($sql_action, $params_action); 582 $query = $this->executeQuery($sql_action, $params_action);
543 return $query; 583 return $query;
544 } 584 }
545 585
546 private function getEntriesOrder() { 586 private function getEntriesOrder()
547 if (isset($_SESSION['sort']) and array_key_exists($_SESSION['sort'], $this->order)) { 587 {
548 return $this->order[$_SESSION['sort']]; 588 if (isset($_SESSION['sort']) and array_key_exists($_SESSION['sort'], $this->order)) {
549 } 589 return $this->order[$_SESSION['sort']];
550 else {
551 return $this->order['default'];
552 }
553 } 590 }
554 591 else {
592 return $this->order['default'];
593 }
594 }
555} 595}
diff --git a/inc/poche/Routing.class.php b/inc/poche/Routing.class.php
index 7e259c24..6e2c046b 100644
--- a/inc/poche/Routing.class.php
+++ b/inc/poche/Routing.class.php
@@ -11,8 +11,8 @@
11class Routing 11class Routing
12{ 12{
13 protected $wallabag; 13 protected $wallabag;
14 protected $referer; 14 public $referer;
15 protected $view; 15 public $view;
16 protected $action; 16 protected $action;
17 protected $id; 17 protected $id;
18 protected $url; 18 protected $url;
@@ -55,7 +55,7 @@ class Routing
55 # because messages can be added in $poche->action(), we have to add this entry now (we can add it before) 55 # because messages can be added in $poche->action(), we have to add this entry now (we can add it before)
56 $this->vars = array_merge($this->vars, array('messages' => $this->wallabag->messages->display('all', FALSE))); 56 $this->vars = array_merge($this->vars, array('messages' => $this->wallabag->messages->display('all', FALSE)));
57 57
58 $this->_render($this->file, $this->vars); 58 $this->render($this->file, $this->vars);
59 } 59 }
60 60
61 private function _defineTplInformation() 61 private function _defineTplInformation()
@@ -142,7 +142,7 @@ class Routing
142 } 142 }
143 } 143 }
144 144
145 private function _render($file, $vars) 145 public function render($file, $vars)
146 { 146 {
147 echo $this->wallabag->tpl->render($file, $vars); 147 echo $this->wallabag->tpl->render($file, $vars);
148 } 148 }
diff --git a/inc/poche/global.inc.php b/inc/poche/global.inc.php
index 2c22c014..9d710b6c 100755
--- a/inc/poche/global.inc.php
+++ b/inc/poche/global.inc.php
@@ -40,6 +40,12 @@ require_once INCLUDES . '/3rdparty/libraries/PHPePub/Logger.php';
40require_once INCLUDES . '/3rdparty/libraries/PHPePub/EPub.php'; 40require_once INCLUDES . '/3rdparty/libraries/PHPePub/EPub.php';
41require_once INCLUDES . '/3rdparty/libraries/PHPePub/EPubChapterSplitter.php'; 41require_once INCLUDES . '/3rdparty/libraries/PHPePub/EPubChapterSplitter.php';
42 42
43require_once INCLUDES . '/3rdparty/PicoFarad/Request.php';
44require_once INCLUDES . '/3rdparty/PicoFarad/Response.php';
45require_once INCLUDES . '/3rdparty/PicoFarad/Router.php';
46require_once INCLUDES . '/3rdparty/PicoFarad/Session.php';
47require_once INCLUDES . '/3rdparty/PicoFarad/Template.php';
48
43# system configuration; database credentials et caetera 49# system configuration; database credentials et caetera
44require_once INCLUDES . '/poche/config.inc.php'; 50require_once INCLUDES . '/poche/config.inc.php';
45require_once INCLUDES . '/poche/config.inc.default.php'; 51require_once INCLUDES . '/poche/config.inc.default.php';
@@ -50,4 +56,15 @@ if (DOWNLOAD_PICTURES) {
50 56
51if (!ini_get('date.timezone') || !@date_default_timezone_set(ini_get('date.timezone'))) { 57if (!ini_get('date.timezone') || !@date_default_timezone_set(ini_get('date.timezone'))) {
52 date_default_timezone_set('UTC'); 58 date_default_timezone_set('UTC');
53} \ No newline at end of file 59}
60
61if (defined('ERROR_REPORTING')) {
62 error_reporting(ERROR_REPORTING);
63}
64
65// Start session
66Session::$sessionName = 'wallabag';
67Session::init();
68
69// Let's rock !
70$wallabag = new Poche();
diff --git a/index.php b/index.php
index 825e9d5a..6f190518 100755
--- a/index.php
+++ b/index.php
@@ -12,14 +12,56 @@ define ('POCHE', '1.8.0');
12require 'check_setup.php'; 12require 'check_setup.php';
13require_once 'inc/poche/global.inc.php'; 13require_once 'inc/poche/global.inc.php';
14 14
15if (defined('ERROR_REPORTING')) {
16 error_reporting(ERROR_REPORTING);
17}
18 15
19// Start session 16use PicoFarad\Router;
20Session::$sessionName = 'wallabag'; 17use PicoFarad\Response;
21Session::init(); 18use PicoFarad\Request;
19use PicoFarad\Session;
22 20
23// Let's rock ! 21// Called before each action
24$wallabag = new Poche(); 22Router\before(function($action) {
25$wallabag->run(); 23
24 // Open a session only for the specified directory
25 Session\open(dirname($_SERVER['PHP_SELF']));
26
27 // HTTP secure headers
28 Response\csp();
29 Response\xframe();
30 Response\xss();
31 Response\nosniff();
32});
33
34// Show help
35Router\get_action('unread', function() use ($wallabag) {
36 $view = 'home';
37 $id = 0;
38
39 $tpl_vars = array(
40 'referer' => $wallabag->routing->referer,
41 'view' => $wallabag->routing->view,
42 'poche_url' => Tools::getPocheUrl(),
43 'title' => _('wallabag, a read it later open source system'),
44 'token' => \Session::getToken(),
45 'theme' => $wallabag->tpl->getTheme(),
46 'entries' => '',
47 'page_links' => '',
48 'nb_results' => '',
49 'listmode' => (isset($_COOKIE['listmode']) ? true : false),
50 );
51
52 $count = $wallabag->store->getEntriesByViewCount($view, $wallabag->user->getId(), $id);
53
54 if ($count > 0) {
55 $wallabag->pagination->set_total($count);
56 $page_links = str_replace(array('previous', 'next'), array(_('previous'), _('next')),
57 $wallabag->pagination->page_links('?view=' . $view . '&sort=' . $_SESSION['sort'] . (($id)?'&id='.$id:'') . '&' ));
58 $tpl_vars['entries'] = $wallabag->store->getEntriesByView($view, $wallabag->user->getId(), $wallabag->pagination->get_limit(), $id);
59 $tpl_vars['page_links'] = $page_links;
60 $tpl_vars['nb_results'] = $count;
61 }
62
63 $wallabag->routing->render('home.twig', $tpl_vars);
64
65 Tools::logm('display ' . $view . ' view');
66
67});