aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMaryana Rozhankivska <mariroz@mr.lviv.ua>2014-04-02 20:55:19 +0300
committerMaryana Rozhankivska <mariroz@mr.lviv.ua>2014-04-02 20:55:19 +0300
commit182faf2696b38502d4784efc3f84f2f00290343f (patch)
tree619e725c1820773dcd8bb1fe9cbd07c0c325e865
parent22db488d21bc23dc28fc2d60574803525fe53b53 (diff)
downloadwallabag-182faf2696b38502d4784efc3f84f2f00290343f.tar.gz
wallabag-182faf2696b38502d4784efc3f84f2f00290343f.tar.zst
wallabag-182faf2696b38502d4784efc3f84f2f00290343f.zip
import without cron
-rwxr-xr-x[-rw-r--r--]inc/3rdparty/libraries/feedwriter/FeedWriter.php168
-rwxr-xr-xinc/poche/Database.class.php82
-rwxr-xr-xinc/poche/Poche.class.php292
-rwxr-xr-xinc/poche/Tools.class.php8
-rwxr-xr-xinc/poche/config.inc.php.new14
-rwxr-xr-x[-rw-r--r--]index.php5
-rwxr-xr-xthemes/default/_import.twig15
-rwxr-xr-x[-rw-r--r--]themes/default/config.twig25
-rwxr-xr-xthemes/default/home.twig5
9 files changed, 352 insertions, 262 deletions
diff --git a/inc/3rdparty/libraries/feedwriter/FeedWriter.php b/inc/3rdparty/libraries/feedwriter/FeedWriter.php
index adb2526c..5d16e765 100644..100755
--- a/inc/3rdparty/libraries/feedwriter/FeedWriter.php
+++ b/inc/3rdparty/libraries/feedwriter/FeedWriter.php
@@ -9,9 +9,9 @@ define('JSONP', 3, true);
9 * Genarate RSS2 or JSON (original: RSS 1.0, RSS2.0 and ATOM Feed) 9 * Genarate RSS2 or JSON (original: RSS 1.0, RSS2.0 and ATOM Feed)
10 * 10 *
11 * Modified for FiveFilters.org's Full-Text RSS project 11 * Modified for FiveFilters.org's Full-Text RSS project
12 * to allow for inclusion of hubs, JSON output. 12 * to allow for inclusion of hubs, JSON output.
13 * Stripped RSS1 and ATOM support. 13 * Stripped RSS1 and ATOM support.
14 * 14 *
15 * @package UnivarselFeedWriter 15 * @package UnivarselFeedWriter
16 * @author Anis uddin Ahmad <anisniit@gmail.com> 16 * @author Anis uddin Ahmad <anisniit@gmail.com>
17 * @link http://www.ajaxray.com/projects/rss 17 * @link http://www.ajaxray.com/projects/rss
@@ -26,32 +26,32 @@ define('JSONP', 3, true);
26 private $CDATAEncoding = array(); // The tag names which have to encoded as CDATA 26 private $CDATAEncoding = array(); // The tag names which have to encoded as CDATA
27 private $xsl = null; // stylesheet to render RSS (used by Chrome) 27 private $xsl = null; // stylesheet to render RSS (used by Chrome)
28 private $json = null; // JSON object 28 private $json = null; // JSON object
29 29
30 private $version = null; 30 private $version = null;
31 31
32 /** 32 /**
33 * Constructor 33 * Constructor
34 * 34 *
35 * @param constant the version constant (RSS2 or JSON). 35 * @param constant the version constant (RSS2 or JSON).
36 */ 36 */
37 function __construct($version = RSS2) 37 function __construct($version = RSS2)
38 { 38 {
39 $this->version = $version; 39 $this->version = $version;
40 40
41 // Setting default value for assential channel elements 41 // Setting default value for assential channel elements
42 $this->channels['title'] = $version . ' Feed'; 42 $this->channels['title'] = $version . ' Feed';
43 $this->channels['link'] = 'http://www.ajaxray.com/blog'; 43 $this->channels['link'] = 'http://www.ajaxray.com/blog';
44 44
45 //Tag names to encode in CDATA 45 //Tag names to encode in CDATA
46 $this->CDATAEncoding = array('description', 'content:encoded', 'content', 'subtitle', 'summary'); 46 $this->CDATAEncoding = array('description', 'content:encoded', 'content', 'subtitle', 'summary');
47 } 47 }
48 48
49 public function setFormat($format) { 49 public function setFormat($format) {
50 $this->version = $format; 50 $this->version = $format;
51 } 51 }
52 52
53 // Start # public functions --------------------------------------------- 53 // Start # public functions ---------------------------------------------
54 54
55 /** 55 /**
56 * Set a channel element 56 * Set a channel element
57 * @access public 57 * @access public
@@ -63,11 +63,11 @@ define('JSONP', 3, true);
63 { 63 {
64 $this->channels[$elementName] = $content ; 64 $this->channels[$elementName] = $content ;
65 } 65 }
66 66
67 /** 67 /**
68 * Set multiple channel elements from an array. Array elements 68 * Set multiple channel elements from an array. Array elements
69 * should be 'channelName' => 'channelContent' format. 69 * should be 'channelName' => 'channelContent' format.
70 * 70 *
71 * @access public 71 * @access public
72 * @param array array of channels 72 * @param array array of channels
73 * @return void 73 * @return void
@@ -75,30 +75,30 @@ define('JSONP', 3, true);
75 public function setChannelElementsFromArray($elementArray) 75 public function setChannelElementsFromArray($elementArray)
76 { 76 {
77 if(! is_array($elementArray)) return; 77 if(! is_array($elementArray)) return;
78 foreach ($elementArray as $elementName => $content) 78 foreach ($elementArray as $elementName => $content)
79 { 79 {
80 $this->setChannelElement($elementName, $content); 80 $this->setChannelElement($elementName, $content);
81 } 81 }
82 } 82 }
83 83
84 /** 84 /**
85 * Genarate the actual RSS/JSON file 85 * Genarate the actual RSS/JSON file
86 * 86 *
87 * @access public 87 * @access public
88 * @return void 88 * @return void
89 */ 89 */
90 public function genarateFeed() 90 public function genarateFeed()
91 { 91 {
92 if ($this->version == RSS2) { 92 if ($this->version == RSS2) {
93 header('Content-type: text/xml; charset=UTF-8'); 93// header('Content-type: text/xml; charset=UTF-8');
94 // this line prevents Chrome 20 from prompting download 94 // this line prevents Chrome 20 from prompting download
95 // used by Google: https://news.google.com/news/feeds?ned=us&topic=b&output=rss 95 // used by Google: https://news.google.com/news/feeds?ned=us&topic=b&output=rss
96 header('X-content-type-options: nosniff'); 96// header('X-content-type-options: nosniff');
97 } elseif ($this->version == JSON) { 97 } elseif ($this->version == JSON) {
98 header('Content-type: application/json; charset=UTF-8'); 98// header('Content-type: application/json; charset=UTF-8');
99 $this->json = new stdClass(); 99 $this->json = new stdClass();
100 } elseif ($this->version == JSONP) { 100 } elseif ($this->version == JSONP) {
101 header('Content-type: application/javascript; charset=UTF-8'); 101// header('Content-type: application/javascript; charset=UTF-8');
102 $this->json = new stdClass(); 102 $this->json = new stdClass();
103 } 103 }
104 $this->printHead(); 104 $this->printHead();
@@ -109,10 +109,10 @@ define('JSONP', 3, true);
109 echo json_encode($this->json); 109 echo json_encode($this->json);
110 } 110 }
111 } 111 }
112 112
113 /** 113 /**
114 * Create a new FeedItem. 114 * Create a new FeedItem.
115 * 115 *
116 * @access public 116 * @access public
117 * @return object instance of FeedItem class 117 * @return object instance of FeedItem class
118 */ 118 */
@@ -121,24 +121,24 @@ define('JSONP', 3, true);
121 $Item = new FeedItem($this->version); 121 $Item = new FeedItem($this->version);
122 return $Item; 122 return $Item;
123 } 123 }
124 124
125 /** 125 /**
126 * Add a FeedItem to the main class 126 * Add a FeedItem to the main class
127 * 127 *
128 * @access public 128 * @access public
129 * @param object instance of FeedItem class 129 * @param object instance of FeedItem class
130 * @return void 130 * @return void
131 */ 131 */
132 public function addItem($feedItem) 132 public function addItem($feedItem)
133 { 133 {
134 $this->items[] = $feedItem; 134 $this->items[] = $feedItem;
135 } 135 }
136 136
137 // Wrapper functions ------------------------------------------------------------------- 137 // Wrapper functions -------------------------------------------------------------------
138 138
139 /** 139 /**
140 * Set the 'title' channel element 140 * Set the 'title' channel element
141 * 141 *
142 * @access public 142 * @access public
143 * @param srting value of 'title' channel tag 143 * @param srting value of 'title' channel tag
144 * @return void 144 * @return void
@@ -147,59 +147,59 @@ define('JSONP', 3, true);
147 { 147 {
148 $this->setChannelElement('title', $title); 148 $this->setChannelElement('title', $title);
149 } 149 }
150 150
151 /** 151 /**
152 * Add a hub to the channel element 152 * Add a hub to the channel element
153 * 153 *
154 * @access public 154 * @access public
155 * @param string URL 155 * @param string URL
156 * @return void 156 * @return void
157 */ 157 */
158 public function addHub($hub) 158 public function addHub($hub)
159 { 159 {
160 $this->hubs[] = $hub; 160 $this->hubs[] = $hub;
161 } 161 }
162 162
163 /** 163 /**
164 * Set XSL URL 164 * Set XSL URL
165 * 165 *
166 * @access public 166 * @access public
167 * @param string URL 167 * @param string URL
168 * @return void 168 * @return void
169 */ 169 */
170 public function setXsl($xsl) 170 public function setXsl($xsl)
171 { 171 {
172 $this->xsl = $xsl; 172 $this->xsl = $xsl;
173 } 173 }
174 174
175 /** 175 /**
176 * Set self URL 176 * Set self URL
177 * 177 *
178 * @access public 178 * @access public
179 * @param string URL 179 * @param string URL
180 * @return void 180 * @return void
181 */ 181 */
182 public function setSelf($self) 182 public function setSelf($self)
183 { 183 {
184 $this->self = $self; 184 $this->self = $self;
185 } 185 }
186 186
187 /** 187 /**
188 * Set the 'description' channel element 188 * Set the 'description' channel element
189 * 189 *
190 * @access public 190 * @access public
191 * @param srting value of 'description' channel tag 191 * @param srting value of 'description' channel tag
192 * @return void 192 * @return void
193 */ 193 */
194 public function setDescription($desciption) 194 public function setDescription($desciption)
195 { 195 {
196 $tag = ($this->version == ATOM)? 'subtitle' : 'description'; 196 $tag = ($this->version == ATOM)? 'subtitle' : 'description';
197 $this->setChannelElement($tag, $desciption); 197 $this->setChannelElement($tag, $desciption);
198 } 198 }
199 199
200 /** 200 /**
201 * Set the 'link' channel element 201 * Set the 'link' channel element
202 * 202 *
203 * @access public 203 * @access public
204 * @param srting value of 'link' channel tag 204 * @param srting value of 'link' channel tag
205 * @return void 205 * @return void
@@ -208,10 +208,10 @@ define('JSONP', 3, true);
208 { 208 {
209 $this->setChannelElement('link', $link); 209 $this->setChannelElement('link', $link);
210 } 210 }
211 211
212 /** 212 /**
213 * Set the 'image' channel element 213 * Set the 'image' channel element
214 * 214 *
215 * @access public 215 * @access public
216 * @param srting title of image 216 * @param srting title of image
217 * @param srting link url of the imahe 217 * @param srting link url of the imahe
@@ -222,14 +222,14 @@ define('JSONP', 3, true);
222 { 222 {
223 $this->setChannelElement('image', array('title'=>$title, 'link'=>$link, 'url'=>$url)); 223 $this->setChannelElement('image', array('title'=>$title, 'link'=>$link, 'url'=>$url));
224 } 224 }
225 225
226 // End # public functions ---------------------------------------------- 226 // End # public functions ----------------------------------------------
227 227
228 // Start # private functions ---------------------------------------------- 228 // Start # private functions ----------------------------------------------
229 229
230 /** 230 /**
231 * Prints the xml and rss namespace 231 * Prints the xml and rss namespace
232 * 232 *
233 * @access private 233 * @access private
234 * @return void 234 * @return void
235 */ 235 */
@@ -247,10 +247,10 @@ define('JSONP', 3, true);
247 $this->json->rss = array('@attributes' => array('version' => '2.0')); 247 $this->json->rss = array('@attributes' => array('version' => '2.0'));
248 } 248 }
249 } 249 }
250 250
251 /** 251 /**
252 * Closes the open tags at the end of file 252 * Closes the open tags at the end of file
253 * 253 *
254 * @access private 254 * @access private
255 * @return void 255 * @return void
256 */ 256 */
@@ -258,14 +258,14 @@ define('JSONP', 3, true);
258 { 258 {
259 if ($this->version == RSS2) 259 if ($this->version == RSS2)
260 { 260 {
261 echo '</channel>',PHP_EOL,'</rss>'; 261 echo '</channel>',PHP_EOL,'</rss>';
262 } 262 }
263 // do nothing for JSON 263 // do nothing for JSON
264 } 264 }
265 265
266 /** 266 /**
267 * Creates a single node as xml format 267 * Creates a single node as xml format
268 * 268 *
269 * @access private 269 * @access private
270 * @param string name of the tag 270 * @param string name of the tag
271 * @param mixed tag value as string or array of nested tags in 'tagName' => 'tagValue' format 271 * @param mixed tag value as string or array of nested tags in 'tagName' => 'tagValue' format
@@ -273,22 +273,22 @@ define('JSONP', 3, true);
273 * @return string formatted xml tag 273 * @return string formatted xml tag
274 */ 274 */
275 private function makeNode($tagName, $tagContent, $attributes = null) 275 private function makeNode($tagName, $tagContent, $attributes = null)
276 { 276 {
277 if ($this->version == RSS2) 277 if ($this->version == RSS2)
278 { 278 {
279 $nodeText = ''; 279 $nodeText = '';
280 $attrText = ''; 280 $attrText = '';
281 if (is_array($attributes)) 281 if (is_array($attributes))
282 { 282 {
283 foreach ($attributes as $key => $value) 283 foreach ($attributes as $key => $value)
284 { 284 {
285 $attrText .= " $key=\"$value\" "; 285 $attrText .= " $key=\"$value\" ";
286 } 286 }
287 } 287 }
288 $nodeText .= "<{$tagName}{$attrText}>"; 288 $nodeText .= "<{$tagName}{$attrText}>";
289 if (is_array($tagContent)) 289 if (is_array($tagContent))
290 { 290 {
291 foreach ($tagContent as $key => $value) 291 foreach ($tagContent as $key => $value)
292 { 292 {
293 $nodeText .= $this->makeNode($key, $value); 293 $nodeText .= $this->makeNode($key, $value);
294 } 294 }
@@ -297,7 +297,7 @@ define('JSONP', 3, true);
297 { 297 {
298 //$nodeText .= (in_array($tagName, $this->CDATAEncoding))? $tagContent : htmlentities($tagContent); 298 //$nodeText .= (in_array($tagName, $this->CDATAEncoding))? $tagContent : htmlentities($tagContent);
299 $nodeText .= htmlspecialchars($tagContent); 299 $nodeText .= htmlspecialchars($tagContent);
300 } 300 }
301 //$nodeText .= (in_array($tagName, $this->CDATAEncoding))? "]]></$tagName>" : "</$tagName>"; 301 //$nodeText .= (in_array($tagName, $this->CDATAEncoding))? "]]></$tagName>" : "</$tagName>";
302 $nodeText .= "</$tagName>"; 302 $nodeText .= "</$tagName>";
303 return $nodeText . PHP_EOL; 303 return $nodeText . PHP_EOL;
@@ -321,7 +321,7 @@ define('JSONP', 3, true);
321 } 321 }
322 return ''; // should not get here 322 return ''; // should not get here
323 } 323 }
324 324
325 private function json_keys(array $array) { 325 private function json_keys(array $array) {
326 $new = array(); 326 $new = array();
327 foreach ($array as $key => $val) { 327 foreach ($array as $key => $val) {
@@ -334,7 +334,7 @@ define('JSONP', 3, true);
334 } 334 }
335 return $new; 335 return $new;
336 } 336 }
337 337
338 /** 338 /**
339 * @desc Print channels 339 * @desc Print channels
340 * @access private 340 * @access private
@@ -344,7 +344,7 @@ define('JSONP', 3, true);
344 { 344 {
345 //Start channel tag 345 //Start channel tag
346 if ($this->version == RSS2) { 346 if ($this->version == RSS2) {
347 echo '<channel>' . PHP_EOL; 347 echo '<channel>' . PHP_EOL;
348 // add hubs 348 // add hubs
349 foreach ($this->hubs as $hub) { 349 foreach ($this->hubs as $hub) {
350 //echo $this->makeNode('link', '', array('rel'=>'hub', 'href'=>$hub, 'xmlns'=>'http://www.w3.org/2005/Atom')); 350 //echo $this->makeNode('link', '', array('rel'=>'hub', 'href'=>$hub, 'xmlns'=>'http://www.w3.org/2005/Atom'));
@@ -356,7 +356,7 @@ define('JSONP', 3, true);
356 echo '<link rel="self" href="'.htmlspecialchars($this->self).'" xmlns="http://www.w3.org/2005/Atom" />' . PHP_EOL; 356 echo '<link rel="self" href="'.htmlspecialchars($this->self).'" xmlns="http://www.w3.org/2005/Atom" />' . PHP_EOL;
357 } 357 }
358 //Print Items of channel 358 //Print Items of channel
359 foreach ($this->channels as $key => $value) 359 foreach ($this->channels as $key => $value)
360 { 360 {
361 echo $this->makeNode($key, $value); 361 echo $this->makeNode($key, $value);
362 } 362 }
@@ -364,26 +364,26 @@ define('JSONP', 3, true);
364 $this->json->rss['channel'] = (object)$this->json_keys($this->channels); 364 $this->json->rss['channel'] = (object)$this->json_keys($this->channels);
365 } 365 }
366 } 366 }
367 367
368 /** 368 /**
369 * Prints formatted feed items 369 * Prints formatted feed items
370 * 370 *
371 * @access private 371 * @access private
372 * @return void 372 * @return void
373 */ 373 */
374 private function printItems() 374 private function printItems()
375 { 375 {
376 foreach ($this->items as $item) { 376 foreach ($this->items as $item) {
377 $itemElements = $item->getElements(); 377 $itemElements = $item->getElements();
378 378
379 echo $this->startItem(); 379 echo $this->startItem();
380 380
381 if ($this->version == JSON || $this->version == JSONP) { 381 if ($this->version == JSON || $this->version == JSONP) {
382 $json_item = array(); 382 $json_item = array();
383 } 383 }
384 384
385 foreach ($itemElements as $thisElement) { 385 foreach ($itemElements as $thisElement) {
386 foreach ($thisElement as $instance) { 386 foreach ($thisElement as $instance) {
387 if ($this->version == RSS2) { 387 if ($this->version == RSS2) {
388 echo $this->makeNode($instance['name'], $instance['content'], $instance['attributes']); 388 echo $this->makeNode($instance['name'], $instance['content'], $instance['attributes']);
389 } elseif ($this->version == JSON || $this->version == JSONP) { 389 } elseif ($this->version == JSON || $this->version == JSONP) {
@@ -406,10 +406,10 @@ define('JSONP', 3, true);
406 } 406 }
407 } 407 }
408 } 408 }
409 409
410 /** 410 /**
411 * Make the starting tag of channels 411 * Make the starting tag of channels
412 * 412 *
413 * @access private 413 * @access private
414 * @return void 414 * @return void
415 */ 415 */
@@ -417,14 +417,14 @@ define('JSONP', 3, true);
417 { 417 {
418 if ($this->version == RSS2) 418 if ($this->version == RSS2)
419 { 419 {
420 echo '<item>' . PHP_EOL; 420 echo '<item>' . PHP_EOL;
421 } 421 }
422 // nothing for JSON 422 // nothing for JSON
423 } 423 }
424 424
425 /** 425 /**
426 * Closes feed item tag 426 * Closes feed item tag
427 * 427 *
428 * @access private 428 * @access private
429 * @return void 429 * @return void
430 */ 430 */
@@ -432,10 +432,10 @@ define('JSONP', 3, true);
432 { 432 {
433 if ($this->version == RSS2) 433 if ($this->version == RSS2)
434 { 434 {
435 echo '</item>' . PHP_EOL; 435 echo '</item>' . PHP_EOL;
436 } 436 }
437 // nothing for JSON 437 // nothing for JSON
438 } 438 }
439 439
440 // End # private functions ---------------------------------------------- 440 // End # private functions ----------------------------------------------
441 } \ No newline at end of file 441 } \ No newline at end of file
diff --git a/inc/poche/Database.class.php b/inc/poche/Database.class.php
index 6f5c9ac0..9adb1644 100755
--- a/inc/poche/Database.class.php
+++ b/inc/poche/Database.class.php
@@ -18,7 +18,7 @@ class Database {
18 'default' => 'ORDER BY entries.id' 18 'default' => 'ORDER BY entries.id'
19 ); 19 );
20 20
21 function __construct() 21 function __construct()
22 { 22 {
23 switch (STORAGE) { 23 switch (STORAGE) {
24 case 'sqlite': 24 case 'sqlite':
@@ -27,11 +27,11 @@ class Database {
27 break; 27 break;
28 case 'mysql': 28 case 'mysql':
29 $db_path = 'mysql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB; 29 $db_path = 'mysql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB;
30 $this->handle = new PDO($db_path, STORAGE_USER, STORAGE_PASSWORD); 30 $this->handle = new PDO($db_path, STORAGE_USER, STORAGE_PASSWORD);
31 break; 31 break;
32 case 'postgres': 32 case 'postgres':
33 $db_path = 'pgsql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB; 33 $db_path = 'pgsql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB;
34 $this->handle = new PDO($db_path, STORAGE_USER, STORAGE_PASSWORD); 34 $this->handle = new PDO($db_path, STORAGE_USER, STORAGE_PASSWORD);
35 break; 35 break;
36 } 36 }
37 37
@@ -51,7 +51,7 @@ class Database {
51 } 51 }
52 $hasAdmin = count($query->fetchAll()); 52 $hasAdmin = count($query->fetchAll());
53 53
54 if ($hasAdmin == 0) 54 if ($hasAdmin == 0)
55 return false; 55 return false;
56 56
57 return true; 57 return true;
@@ -140,7 +140,7 @@ class Database {
140 $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)'; 140 $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)';
141 $params = array($id_user, 'language', LANG); 141 $params = array($id_user, 'language', LANG);
142 $query = $this->executeQuery($sql, $params); 142 $query = $this->executeQuery($sql, $params);
143 143
144 $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)'; 144 $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)';
145 $params = array($id_user, 'theme', DEFAULT_THEME); 145 $params = array($id_user, 'theme', DEFAULT_THEME);
146 $query = $this->executeQuery($sql, $params); 146 $query = $this->executeQuery($sql, $params);
@@ -153,7 +153,7 @@ class Database {
153 $query = $this->executeQuery($sql, array($id)); 153 $query = $this->executeQuery($sql, array($id));
154 $result = $query->fetchAll(); 154 $result = $query->fetchAll();
155 $user_config = array(); 155 $user_config = array();
156 156
157 foreach ($result as $key => $value) { 157 foreach ($result as $key => $value) {
158 $user_config[$value['name']] = $value['value']; 158 $user_config[$value['name']] = $value['value'];
159 } 159 }
@@ -201,10 +201,10 @@ class Database {
201 $params_update = array($password, $userId); 201 $params_update = array($password, $userId);
202 $query = $this->executeQuery($sql_update, $params_update); 202 $query = $this->executeQuery($sql_update, $params_update);
203 } 203 }
204 204
205 public function updateUserConfig($userId, $key, $value) { 205 public function updateUserConfig($userId, $key, $value) {
206 $config = $this->getConfigUser($userId); 206 $config = $this->getConfigUser($userId);
207 207
208 if (! isset($config[$key])) { 208 if (! isset($config[$key])) {
209 $sql = "INSERT INTO users_config (value, user_id, name) VALUES (?, ?, ?)"; 209 $sql = "INSERT INTO users_config (value, user_id, name) VALUES (?, ?, ?)";
210 } 210 }
@@ -252,8 +252,16 @@ class Database {
252 return $entries; 252 return $entries;
253 } 253 }
254 254
255 public function retrieveUnfetchedEntriesCount($user_id) {
256 $sql = "SELECT count(*) FROM entries WHERE (content = '' OR content IS NULL) AND user_id=?";
257 $query = $this->executeQuery($sql, array($user_id));
258 list($count) = $query->fetch();
259
260 return $count;
261 }
262
255 public function retrieveAll($user_id) { 263 public function retrieveAll($user_id) {
256 $sql = "SELECT * FROM entries WHERE content <> '' AND user_id=? ORDER BY id"; 264 $sql = "SELECT * FROM entries WHERE user_id=? ORDER BY id";
257 $query = $this->executeQuery($sql, array($user_id)); 265 $query = $this->executeQuery($sql, array($user_id));
258 $entries = $query->fetchAll(); 266 $entries = $query->fetchAll();
259 267
@@ -272,7 +280,7 @@ class Database {
272 280
273 public function retrieveOneByURL($url, $user_id) { 281 public function retrieveOneByURL($url, $user_id) {
274 $entry = NULL; 282 $entry = NULL;
275 $sql = "SELECT * FROM entries WHERE content <> '' AND url=? AND user_id=?"; 283 $sql = "SELECT * FROM entries WHERE url=? AND user_id=?";
276 $params = array($url, $user_id); 284 $params = array($url, $user_id);
277 $query = $this->executeQuery($sql, $params); 285 $query = $this->executeQuery($sql, $params);
278 $entry = $query->fetchAll(); 286 $entry = $query->fetchAll();
@@ -289,22 +297,21 @@ class Database {
289 public function getEntriesByView($view, $user_id, $limit = '', $tag_id = 0) { 297 public function getEntriesByView($view, $user_id, $limit = '', $tag_id = 0) {
290 switch ($view) { 298 switch ($view) {
291 case 'archive': 299 case 'archive':
292 $sql = "SELECT * FROM entries WHERE content <> '' AND user_id=? AND is_read=? "; 300 $sql = "SELECT * FROM entries WHERE user_id=? AND is_read=? ";
293 $params = array($user_id, 1); 301 $params = array($user_id, 1);
294 break; 302 break;
295 case 'fav' : 303 case 'fav' :
296 $sql = "SELECT * FROM entries WHERE content <> '' AND user_id=? AND is_fav=? "; 304 $sql = "SELECT * FROM entries WHERE user_id=? AND is_fav=? ";
297 $params = array($user_id, 1); 305 $params = array($user_id, 1);
298 break; 306 break;
299 case 'tag' : 307 case 'tag' :
300 $sql = "SELECT entries.* FROM entries 308 $sql = "SELECT entries.* FROM entries
301 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id 309 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id
302 WHERE entries.content <> '' AND 310 WHERE entries.user_id=? AND tags_entries.tag_id = ? ";
303 entries.user_id=? AND tags_entries.tag_id = ? ";
304 $params = array($user_id, $tag_id); 311 $params = array($user_id, $tag_id);
305 break; 312 break;
306 default: 313 default:
307 $sql = "SELECT * FROM entries WHERE content <> '' AND user_id=? AND is_read=? "; 314 $sql = "SELECT * FROM entries WHERE user_id=? AND is_read=? ";
308 $params = array($user_id, 0); 315 $params = array($user_id, 0);
309 break; 316 break;
310 } 317 }
@@ -320,22 +327,21 @@ class Database {
320 public function getEntriesByViewCount($view, $user_id, $tag_id = 0) { 327 public function getEntriesByViewCount($view, $user_id, $tag_id = 0) {
321 switch ($view) { 328 switch ($view) {
322 case 'archive': 329 case 'archive':
323 $sql = "SELECT count(*) FROM entries WHERE content <> '' AND user_id=? AND is_read=? "; 330 $sql = "SELECT count(*) FROM entries WHERE user_id=? AND is_read=? ";
324 $params = array($user_id, 1); 331 $params = array($user_id, 1);
325 break; 332 break;
326 case 'fav' : 333 case 'fav' :
327 $sql = "SELECT count(*) FROM entries WHERE content <> '' AND user_id=? AND is_fav=? "; 334 $sql = "SELECT count(*) FROM entries WHERE user_id=? AND is_fav=? ";
328 $params = array($user_id, 1); 335 $params = array($user_id, 1);
329 break; 336 break;
330 case 'tag' : 337 case 'tag' :
331 $sql = "SELECT count(*) FROM entries 338 $sql = "SELECT count(*) FROM entries
332 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id 339 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id
333 WHERE entries.content <> '' AND 340 WHERE entries.user_id=? AND tags_entries.tag_id = ? ";
334 entries.user_id=? AND tags_entries.tag_id = ? ";
335 $params = array($user_id, $tag_id); 341 $params = array($user_id, $tag_id);
336 break; 342 break;
337 default: 343 default:
338 $sql = "SELECT count(*) FROM entries WHERE content <> '' AND user_id=? AND is_read=? "; 344 $sql = "SELECT count(*) FROM entries WHERE user_id=? AND is_read=? ";
339 $params = array($user_id, 0); 345 $params = array($user_id, 0);
340 break; 346 break;
341 } 347 }
@@ -353,11 +359,24 @@ class Database {
353 return $query; 359 return $query;
354 } 360 }
355 361
356 public function add($url, $title, $content, $user_id) { 362 /**
357 $sql_action = 'INSERT INTO entries ( url, title, content, user_id ) VALUES (?, ?, ?, ?)'; 363 *
358 $params_action = array($url, $title, $content, $user_id); 364 * @param string $url
359 $query = $this->executeQuery($sql_action, $params_action); 365 * @param string $title
360 return $query; 366 * @param string $content
367 * @param integer $user_id
368 * @return integer $id of inserted record
369 */
370 public function add($url, $title, $content, $user_id, $isFavorite=0, $isRead=0) {
371 $sql_action = 'INSERT INTO entries ( url, title, content, user_id, is_fav, is_read ) VALUES (?, ?, ?, ?, ?, ?)';
372 $params_action = array($url, $title, $content, $user_id, $isFavorite, $isRead);
373 if ( !$this->executeQuery($sql_action, $params_action) ) {
374 $id = null;
375 }
376 else {
377 $id = intval($this->getLastId( (STORAGE == 'postgres') ? 'users_id_seq' : '' ));
378 }
379 return $id;
361 } 380 }
362 381
363 public function deleteById($id, $user_id) { 382 public function deleteById($id, $user_id) {
@@ -388,7 +407,7 @@ class Database {
388 public function getLastId($column = '') { 407 public function getLastId($column = '') {
389 return $this->getHandle()->lastInsertId($column); 408 return $this->getHandle()->lastInsertId($column);
390 } 409 }
391 410
392 public function search($term){ 411 public function search($term){
393 $search = '%'.$term.'%'; 412 $search = '%'.$term.'%';
394 $query = $this->getHandle()->prepare("SELECT * FROM entries WHERE content LIKE ? OR title LIKE ? OR url LIKE ?"); //searches in content, title and URL 413 $query = $this->getHandle()->prepare("SELECT * FROM entries WHERE content LIKE ? OR title LIKE ? OR url LIKE ?"); //searches in content, title and URL
@@ -401,7 +420,7 @@ class Database {
401 $sql = "SELECT DISTINCT tags.*, count(entries.id) AS entriescount FROM tags 420 $sql = "SELECT DISTINCT tags.*, count(entries.id) AS entriescount FROM tags
402 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id 421 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id
403 LEFT JOIN entries ON tags_entries.entry_id=entries.id 422 LEFT JOIN entries ON tags_entries.entry_id=entries.id
404 WHERE entries.content <> '' AND entries.user_id=? 423 WHERE entries.user_id=?
405 ". (($term) ? "AND lower(tags.value) LIKE ?" : '') ." 424 ". (($term) ? "AND lower(tags.value) LIKE ?" : '') ."
406 GROUP BY tags.id, tags.value 425 GROUP BY tags.id, tags.value
407 ORDER BY tags.value"; 426 ORDER BY tags.value";
@@ -416,7 +435,7 @@ class Database {
416 $sql = "SELECT DISTINCT tags.* FROM tags 435 $sql = "SELECT DISTINCT tags.* FROM tags
417 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id 436 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id
418 LEFT JOIN entries ON tags_entries.entry_id=entries.id 437 LEFT JOIN entries ON tags_entries.entry_id=entries.id
419 WHERE entries.content <> '' AND tags.id=? AND entries.user_id=?"; 438 WHERE tags.id=? AND entries.user_id=?";
420 $params = array(intval($id), $user_id); 439 $params = array(intval($id), $user_id);
421 $query = $this->executeQuery($sql, $params); 440 $query = $this->executeQuery($sql, $params);
422 $tag = $query->fetchAll(); 441 $tag = $query->fetchAll();
@@ -425,11 +444,10 @@ class Database {
425 } 444 }
426 445
427 public function retrieveEntriesByTag($tag_id, $user_id) { 446 public function retrieveEntriesByTag($tag_id, $user_id) {
428 $sql = 447 $sql =
429 "SELECT entries.* FROM entries 448 "SELECT entries.* FROM entries
430 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id 449 LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id
431 WHERE entries.content <> '' AND 450 WHERE tags_entries.tag_id = ? AND entries.user_id=?";
432 tags_entries.tag_id = ? AND entries.user_id=?";
433 $query = $this->executeQuery($sql, array($tag_id, $user_id)); 451 $query = $this->executeQuery($sql, array($tag_id, $user_id));
434 $entries = $query->fetchAll(); 452 $entries = $query->fetchAll();
435 453
@@ -437,7 +455,7 @@ class Database {
437 } 455 }
438 456
439 public function retrieveTagsByEntry($entry_id) { 457 public function retrieveTagsByEntry($entry_id) {
440 $sql = 458 $sql =
441 "SELECT tags.* FROM tags 459 "SELECT tags.* FROM tags
442 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id 460 LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id
443 WHERE tags_entries.entry_id = ?"; 461 WHERE tags_entries.entry_id = ?";
diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php
index 7d9faed1..d1b0c945 100755
--- a/inc/poche/Poche.class.php
+++ b/inc/poche/Poche.class.php
@@ -18,7 +18,7 @@ class Poche
18 public $tpl; 18 public $tpl;
19 public $messages; 19 public $messages;
20 public $pagination; 20 public $pagination;
21 21
22 private $currentTheme = ''; 22 private $currentTheme = '';
23 private $currentLanguage = ''; 23 private $currentLanguage = '';
24 private $notInstalledMessage = array(); 24 private $notInstalledMessage = array();
@@ -42,11 +42,11 @@ class Poche
42 if ($this->configFileIsAvailable()) { 42 if ($this->configFileIsAvailable()) {
43 $this->init(); 43 $this->init();
44 } 44 }
45 45
46 if ($this->themeIsInstalled()) { 46 if ($this->themeIsInstalled()) {
47 $this->initTpl(); 47 $this->initTpl();
48 } 48 }
49 49
50 if ($this->systemIsInstalled()) { 50 if ($this->systemIsInstalled()) {
51 $this->store = new Database(); 51 $this->store = new Database();
52 $this->messages = new Messages(); 52 $this->messages = new Messages();
@@ -57,8 +57,8 @@ class Poche
57 $this->store->checkTags(); 57 $this->store->checkTags();
58 } 58 }
59 } 59 }
60 60
61 private function init() 61 private function init()
62 { 62 {
63 Tools::initPhp(); 63 Tools::initPhp();
64 64
@@ -74,28 +74,28 @@ class Poche
74 $language = $this->user->getConfigValue('language'); 74 $language = $this->user->getConfigValue('language');
75 putenv('LC_ALL=' . $language); 75 putenv('LC_ALL=' . $language);
76 setlocale(LC_ALL, $language); 76 setlocale(LC_ALL, $language);
77 bindtextdomain($language, LOCALE); 77 bindtextdomain($language, LOCALE);
78 textdomain($language); 78 textdomain($language);
79 79
80 # Pagination 80 # Pagination
81 $this->pagination = new Paginator($this->user->getConfigValue('pager'), 'p'); 81 $this->pagination = new Paginator($this->user->getConfigValue('pager'), 'p');
82 82
83 # Set up theme 83 # Set up theme
84 $themeDirectory = $this->user->getConfigValue('theme'); 84 $themeDirectory = $this->user->getConfigValue('theme');
85 85
86 if ($themeDirectory === false) { 86 if ($themeDirectory === false) {
87 $themeDirectory = DEFAULT_THEME; 87 $themeDirectory = DEFAULT_THEME;
88 } 88 }
89 89
90 $this->currentTheme = $themeDirectory; 90 $this->currentTheme = $themeDirectory;
91 91
92 # Set up language 92 # Set up language
93 $languageDirectory = $this->user->getConfigValue('language'); 93 $languageDirectory = $this->user->getConfigValue('language');
94 94
95 if ($languageDirectory === false) { 95 if ($languageDirectory === false) {
96 $languageDirectory = DEFAULT_THEME; 96 $languageDirectory = DEFAULT_THEME;
97 } 97 }
98 98
99 $this->currentLanguage = $languageDirectory; 99 $this->currentLanguage = $languageDirectory;
100 } 100 }
101 101
@@ -108,7 +108,7 @@ class Poche
108 108
109 return true; 109 return true;
110 } 110 }
111 111
112 public function themeIsInstalled() { 112 public function themeIsInstalled() {
113 $passTheme = TRUE; 113 $passTheme = TRUE;
114 # Twig is an absolute requirement for Poche to function. Abort immediately if the Composer installer hasn't been run yet 114 # Twig is an absolute requirement for Poche to function. Abort immediately if the Composer installer hasn't been run yet
@@ -123,27 +123,27 @@ class Poche
123 self::$canRenderTemplates = false; 123 self::$canRenderTemplates = false;
124 124
125 $passTheme = FALSE; 125 $passTheme = FALSE;
126 } 126 }
127 127
128 # Check if the selected theme and its requirements are present 128 # Check if the selected theme and its requirements are present
129 $theme = $this->getTheme(); 129 $theme = $this->getTheme();
130 130
131 if ($theme != '' && ! is_dir(THEME . '/' . $theme)) { 131 if ($theme != '' && ! is_dir(THEME . '/' . $theme)) {
132 $this->notInstalledMessage[] = 'The currently selected theme (' . $theme . ') does not seem to be properly installed (Missing directory: ' . THEME . '/' . $theme . ')'; 132 $this->notInstalledMessage[] = 'The currently selected theme (' . $theme . ') does not seem to be properly installed (Missing directory: ' . THEME . '/' . $theme . ')';
133 133
134 self::$canRenderTemplates = false; 134 self::$canRenderTemplates = false;
135 135
136 $passTheme = FALSE; 136 $passTheme = FALSE;
137 } 137 }
138 138
139 $themeInfo = $this->getThemeInfo($theme); 139 $themeInfo = $this->getThemeInfo($theme);
140 if (isset($themeInfo['requirements']) && is_array($themeInfo['requirements'])) { 140 if (isset($themeInfo['requirements']) && is_array($themeInfo['requirements'])) {
141 foreach ($themeInfo['requirements'] as $requiredTheme) { 141 foreach ($themeInfo['requirements'] as $requiredTheme) {
142 if (! is_dir(THEME . '/' . $requiredTheme)) { 142 if (! is_dir(THEME . '/' . $requiredTheme)) {
143 $this->notInstalledMessage[] = 'The required "' . $requiredTheme . '" theme is missing for the current theme (' . $theme . ')'; 143 $this->notInstalledMessage[] = 'The required "' . $requiredTheme . '" theme is missing for the current theme (' . $theme . ')';
144 144
145 self::$canRenderTemplates = false; 145 self::$canRenderTemplates = false;
146 146
147 $passTheme = FALSE; 147 $passTheme = FALSE;
148 } 148 }
149 } 149 }
@@ -153,21 +153,21 @@ class Poche
153 return FALSE; 153 return FALSE;
154 } 154 }
155 155
156 156
157 return true; 157 return true;
158 } 158 }
159 159
160 /** 160 /**
161 * all checks before installation. 161 * all checks before installation.
162 * @todo move HTML to template 162 * @todo move HTML to template
163 * @return boolean 163 * @return boolean
164 */ 164 */
165 public function systemIsInstalled() 165 public function systemIsInstalled()
166 { 166 {
167 $msg = TRUE; 167 $msg = TRUE;
168 168
169 $configSalt = defined('SALT') ? constant('SALT') : ''; 169 $configSalt = defined('SALT') ? constant('SALT') : '';
170 170
171 if (empty($configSalt)) { 171 if (empty($configSalt)) {
172 $this->notInstalledMessage[] = 'You have not yet filled in the SALT value in the config.inc.php file.'; 172 $this->notInstalledMessage[] = 'You have not yet filled in the SALT value in the config.inc.php file.';
173 $msg = FALSE; 173 $msg = FALSE;
@@ -193,7 +193,7 @@ class Poche
193 193
194 return true; 194 return true;
195 } 195 }
196 196
197 public function getNotInstalledMessage() { 197 public function getNotInstalledMessage() {
198 return $this->notInstalledMessage; 198 return $this->notInstalledMessage;
199 } 199 }
@@ -202,7 +202,7 @@ class Poche
202 { 202 {
203 $loaderChain = new Twig_Loader_Chain(); 203 $loaderChain = new Twig_Loader_Chain();
204 $theme = $this->getTheme(); 204 $theme = $this->getTheme();
205 205
206 # add the current theme as first to the loader chain so Twig will look there first for overridden template files 206 # add the current theme as first to the loader chain so Twig will look there first for overridden template files
207 try { 207 try {
208 $loaderChain->addLoader(new Twig_Loader_Filesystem(THEME . '/' . $theme)); 208 $loaderChain->addLoader(new Twig_Loader_Filesystem(THEME . '/' . $theme));
@@ -210,7 +210,7 @@ class Poche
210 # @todo isInstalled() should catch this, inject Twig later 210 # @todo isInstalled() should catch this, inject Twig later
211 die('The currently selected theme (' . $theme . ') does not seem to be properly installed (' . THEME . '/' . $theme .' is missing)'); 211 die('The currently selected theme (' . $theme . ') does not seem to be properly installed (' . THEME . '/' . $theme .' is missing)');
212 } 212 }
213 213
214 # add all required themes to the loader chain 214 # add all required themes to the loader chain
215 $themeInfo = $this->getThemeInfo($theme); 215 $themeInfo = $this->getThemeInfo($theme);
216 if (isset($themeInfo['requirements']) && is_array($themeInfo['requirements'])) { 216 if (isset($themeInfo['requirements']) && is_array($themeInfo['requirements'])) {
@@ -223,16 +223,16 @@ class Poche
223 } 223 }
224 } 224 }
225 } 225 }
226 226
227 if (DEBUG_POCHE) { 227 if (DEBUG_POCHE) {
228 $twigParams = array(); 228 $twigParams = array();
229 } else { 229 } else {
230 $twigParams = array('cache' => CACHE); 230 $twigParams = array('cache' => CACHE);
231 } 231 }
232 232
233 $this->tpl = new Twig_Environment($loaderChain, $twigParams); 233 $this->tpl = new Twig_Environment($loaderChain, $twigParams);
234 $this->tpl->addExtension(new Twig_Extensions_Extension_I18n()); 234 $this->tpl->addExtension(new Twig_Extensions_Extension_I18n());
235 235
236 # filter to display domain name of an url 236 # filter to display domain name of an url
237 $filter = new Twig_SimpleFilter('getDomain', 'Tools::getDomain'); 237 $filter = new Twig_SimpleFilter('getDomain', 'Tools::getDomain');
238 $this->tpl->addFilter($filter); 238 $this->tpl->addFilter($filter);
@@ -251,7 +251,7 @@ class Poche
251 'poche_url' => Tools::getPocheUrl() 251 'poche_url' => Tools::getPocheUrl()
252 )); 252 ));
253 if (isset($_GET['install'])) { 253 if (isset($_GET['install'])) {
254 if (($_POST['password'] == $_POST['password_repeat']) 254 if (($_POST['password'] == $_POST['password_repeat'])
255 && $_POST['password'] != "" && $_POST['login'] != "") { 255 && $_POST['password'] != "" && $_POST['login'] != "") {
256 # let's rock, install poche baby ! 256 # let's rock, install poche baby !
257 if ($this->store->install($_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login']))) 257 if ($this->store->install($_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login'])))
@@ -268,7 +268,7 @@ class Poche
268 } 268 }
269 exit(); 269 exit();
270 } 270 }
271 271
272 public function getTheme() { 272 public function getTheme() {
273 return $this->currentTheme; 273 return $this->currentTheme;
274 } 274 }
@@ -293,7 +293,7 @@ class Poche
293 if (is_file($themeIniFile) && is_readable($themeIniFile)) { 293 if (is_file($themeIniFile) && is_readable($themeIniFile)) {
294 $themeInfo = parse_ini_file($themeIniFile); 294 $themeInfo = parse_ini_file($themeIniFile);
295 } 295 }
296 296
297 if ($themeInfo === false) { 297 if ($themeInfo === false) {
298 $themeInfo = array(); 298 $themeInfo = array();
299 } 299 }
@@ -304,7 +304,7 @@ class Poche
304 304
305 return $themeInfo; 305 return $themeInfo;
306 } 306 }
307 307
308 public function getInstalledThemes() { 308 public function getInstalledThemes() {
309 $handle = opendir(THEME); 309 $handle = opendir(THEME);
310 $themes = array(); 310 $themes = array();
@@ -331,28 +331,28 @@ class Poche
331 public function getInstalledLanguages() { 331 public function getInstalledLanguages() {
332 $handle = opendir(LOCALE); 332 $handle = opendir(LOCALE);
333 $languages = array(); 333 $languages = array();
334 334
335 while (($language = readdir($handle)) !== false) { 335 while (($language = readdir($handle)) !== false) {
336 # Languages are stored in a directory, so all directory names are languages 336 # Languages are stored in a directory, so all directory names are languages
337 # @todo move language installation data to database 337 # @todo move language installation data to database
338 if (! is_dir(LOCALE . '/' . $language) || in_array($language, array('..', '.', 'tools'))) { 338 if (! is_dir(LOCALE . '/' . $language) || in_array($language, array('..', '.', 'tools'))) {
339 continue; 339 continue;
340 } 340 }
341 341
342 $current = false; 342 $current = false;
343 343
344 if ($language === $this->getLanguage()) { 344 if ($language === $this->getLanguage()) {
345 $current = true; 345 $current = true;
346 } 346 }
347 347
348 $languages[] = array('name' => (isset($this->language_names[$language]) ? $this->language_names[$language] : $language), 'value' => $language, 'current' => $current); 348 $languages[] = array('name' => (isset($this->language_names[$language]) ? $this->language_names[$language] : $language), 'value' => $language, 'current' => $current);
349 } 349 }
350 350
351 return $languages; 351 return $languages;
352 } 352 }
353 353
354 public function getDefaultConfig() 354 public function getDefaultConfig()
355 { 355 {
356 return array( 356 return array(
357 'pager' => PAGINATION, 357 'pager' => PAGINATION,
358 'language' => LANG, 358 'language' => LANG,
@@ -385,19 +385,15 @@ class Poche
385 $body = ''; 385 $body = '';
386 } 386 }
387 387
388 //search for possible duplicate if not in import mode 388 //search for possible duplicate
389 $duplicate = NULL; 389 $duplicate = NULL;
390 if (!$import) { 390 if (!$import) {
391 $duplicate = $this->store->retrieveOneByURL($url->getUrl(), $this->user->getId()); 391 $duplicate = $this->store->retrieveOneByURL($url->getUrl(), $this->user->getId());
392 } 392 }
393 393
394 if ($this->store->add($url->getUrl(), $title, $body, $this->user->getId())) { 394 $last_id = $this->store->add($url->getUrl(), $title, $body, $this->user->getId());
395 if ( $last_id && !$import ) {
395 Tools::logm('add link ' . $url->getUrl()); 396 Tools::logm('add link ' . $url->getUrl());
396 $sequence = '';
397 if (STORAGE == 'postgres') {
398 $sequence = 'entries_id_seq';
399 }
400 $last_id = $this->store->getLastId($sequence);
401 if (DOWNLOAD_PICTURES) { 397 if (DOWNLOAD_PICTURES) {
402 $content = filtre_picture($body, $url->getUrl(), $last_id); 398 $content = filtre_picture($body, $url->getUrl(), $last_id);
403 Tools::logm('updating content article'); 399 Tools::logm('updating content article');
@@ -417,9 +413,7 @@ class Poche
417 } 413 }
418 } 414 }
419 415
420 if (!$import) { 416 $this->messages->add('s', _('the link has been added successfully'));
421 $this->messages->add('s', _('the link has been added successfully'));
422 }
423 } 417 }
424 else { 418 else {
425 if (!$import) { 419 if (!$import) {
@@ -603,7 +597,7 @@ class Poche
603 'tags' => $tags, 597 'tags' => $tags,
604 ); 598 );
605 break; 599 break;
606 600
607 case 'search': 601 case 'search':
608 if (isset($_GET['search'])){ 602 if (isset($_GET['search'])){
609 $search = $_GET['search']; 603 $search = $_GET['search'];
@@ -647,7 +641,7 @@ class Poche
647 'nb_results' => '', 641 'nb_results' => '',
648 'listmode' => (isset($_COOKIE['listmode']) ? true : false), 642 'listmode' => (isset($_COOKIE['listmode']) ? true : false),
649 ); 643 );
650 644
651 //if id is given - we retrive entries by tag: id is tag id 645 //if id is given - we retrive entries by tag: id is tag id
652 if ($id) { 646 if ($id) {
653 $tpl_vars['tag'] = $this->store->retrieveTag($id, $this->user->getId()); 647 $tpl_vars['tag'] = $this->store->retrieveTag($id, $this->user->getId());
@@ -672,8 +666,8 @@ class Poche
672 } 666 }
673 667
674 /** 668 /**
675 * update the password of the current user. 669 * update the password of the current user.
676 * if MODE_DEMO is TRUE, the password can't be updated. 670 * if MODE_DEMO is TRUE, the password can't be updated.
677 * @todo add the return value 671 * @todo add the return value
678 * @todo set the new password in function header like this updatePassword($newPassword) 672 * @todo set the new password in function header like this updatePassword($newPassword)
679 * @return boolean 673 * @return boolean
@@ -701,44 +695,44 @@ class Poche
701 } 695 }
702 } 696 }
703 } 697 }
704 698
705 public function updateTheme() 699 public function updateTheme()
706 { 700 {
707 # no data 701 # no data
708 if (empty($_POST['theme'])) { 702 if (empty($_POST['theme'])) {
709 } 703 }
710 704
711 # we are not going to change it to the current theme... 705 # we are not going to change it to the current theme...
712 if ($_POST['theme'] == $this->getTheme()) { 706 if ($_POST['theme'] == $this->getTheme()) {
713 $this->messages->add('w', _('still using the "' . $this->getTheme() . '" theme!')); 707 $this->messages->add('w', _('still using the "' . $this->getTheme() . '" theme!'));
714 Tools::redirect('?view=config'); 708 Tools::redirect('?view=config');
715 } 709 }
716 710
717 $themes = $this->getInstalledThemes(); 711 $themes = $this->getInstalledThemes();
718 $actualTheme = false; 712 $actualTheme = false;
719 713
720 foreach (array_keys($themes) as $theme) { 714 foreach (array_keys($themes) as $theme) {
721 if ($theme == $_POST['theme']) { 715 if ($theme == $_POST['theme']) {
722 $actualTheme = true; 716 $actualTheme = true;
723 break; 717 break;
724 } 718 }
725 } 719 }
726 720
727 if (! $actualTheme) { 721 if (! $actualTheme) {
728 $this->messages->add('e', _('that theme does not seem to be installed')); 722 $this->messages->add('e', _('that theme does not seem to be installed'));
729 Tools::redirect('?view=config'); 723 Tools::redirect('?view=config');
730 } 724 }
731 725
732 $this->store->updateUserConfig($this->user->getId(), 'theme', $_POST['theme']); 726 $this->store->updateUserConfig($this->user->getId(), 'theme', $_POST['theme']);
733 $this->messages->add('s', _('you have changed your theme preferences')); 727 $this->messages->add('s', _('you have changed your theme preferences'));
734 728
735 $currentConfig = $_SESSION['poche_user']->config; 729 $currentConfig = $_SESSION['poche_user']->config;
736 $currentConfig['theme'] = $_POST['theme']; 730 $currentConfig['theme'] = $_POST['theme'];
737 731
738 $_SESSION['poche_user']->setConfig($currentConfig); 732 $_SESSION['poche_user']->setConfig($currentConfig);
739 733
740 $this->emptyCache(); 734 $this->emptyCache();
741 735
742 Tools::redirect('?view=config'); 736 Tools::redirect('?view=config');
743 } 737 }
744 738
@@ -747,40 +741,40 @@ class Poche
747 # no data 741 # no data
748 if (empty($_POST['language'])) { 742 if (empty($_POST['language'])) {
749 } 743 }
750 744
751 # we are not going to change it to the current language... 745 # we are not going to change it to the current language...
752 if ($_POST['language'] == $this->getLanguage()) { 746 if ($_POST['language'] == $this->getLanguage()) {
753 $this->messages->add('w', _('still using the "' . $this->getLanguage() . '" language!')); 747 $this->messages->add('w', _('still using the "' . $this->getLanguage() . '" language!'));
754 Tools::redirect('?view=config'); 748 Tools::redirect('?view=config');
755 } 749 }
756 750
757 $languages = $this->getInstalledLanguages(); 751 $languages = $this->getInstalledLanguages();
758 $actualLanguage = false; 752 $actualLanguage = false;
759 753
760 foreach ($languages as $language) { 754 foreach ($languages as $language) {
761 if ($language['value'] == $_POST['language']) { 755 if ($language['value'] == $_POST['language']) {
762 $actualLanguage = true; 756 $actualLanguage = true;
763 break; 757 break;
764 } 758 }
765 } 759 }
766 760
767 if (! $actualLanguage) { 761 if (! $actualLanguage) {
768 $this->messages->add('e', _('that language does not seem to be installed')); 762 $this->messages->add('e', _('that language does not seem to be installed'));
769 Tools::redirect('?view=config'); 763 Tools::redirect('?view=config');
770 } 764 }
771 765
772 $this->store->updateUserConfig($this->user->getId(), 'language', $_POST['language']); 766 $this->store->updateUserConfig($this->user->getId(), 'language', $_POST['language']);
773 $this->messages->add('s', _('you have changed your language preferences')); 767 $this->messages->add('s', _('you have changed your language preferences'));
774 768
775 $currentConfig = $_SESSION['poche_user']->config; 769 $currentConfig = $_SESSION['poche_user']->config;
776 $currentConfig['language'] = $_POST['language']; 770 $currentConfig['language'] = $_POST['language'];
777 771
778 $_SESSION['poche_user']->setConfig($currentConfig); 772 $_SESSION['poche_user']->setConfig($currentConfig);
779 773
780 $this->emptyCache(); 774 $this->emptyCache();
781 775
782 Tools::redirect('?view=config'); 776 Tools::redirect('?view=config');
783 } 777 }
784 /** 778 /**
785 * get credentials from differents sources 779 * get credentials from differents sources
786 * it redirects the user to the $referer link 780 * it redirects the user to the $referer link
@@ -835,7 +829,7 @@ class Poche
835 /** 829 /**
836 * log out the poche user. It cleans the session. 830 * log out the poche user. It cleans the session.
837 * @todo add the return value 831 * @todo add the return value
838 * @return boolean 832 * @return boolean
839 */ 833 */
840 public function logout() 834 public function logout()
841 { 835 {
@@ -891,7 +885,7 @@ class Poche
891 * import from Pocket. poche needs a ./ril_export.html file 885 * import from Pocket. poche needs a ./ril_export.html file
892 * @todo add the return value 886 * @todo add the return value
893 * @param string $targetFile the file used for importing 887 * @param string $targetFile the file used for importing
894 * @return boolean 888 * @return boolean
895 */ 889 */
896 private function importFromPocket($targetFile) 890 private function importFromPocket($targetFile)
897 { 891 {
@@ -922,7 +916,7 @@ class Poche
922 $this->action('add_tag',$url,$last_id,true,false,$tags); 916 $this->action('add_tag',$url,$last_id,true,false,$tags);
923 } 917 }
924 } 918 }
925 919
926 # the second <ul> is for read links 920 # the second <ul> is for read links
927 $read = 1; 921 $read = 1;
928 } 922 }
@@ -937,7 +931,7 @@ class Poche
937 * import from Readability. poche needs a ./readability file 931 * import from Readability. poche needs a ./readability file
938 * @todo add the return value 932 * @todo add the return value
939 * @param string $targetFile the file used for importing 933 * @param string $targetFile the file used for importing
940 * @return boolean 934 * @return boolean
941 */ 935 */
942 private function importFromReadability($targetFile) 936 private function importFromReadability($targetFile)
943 { 937 {
@@ -994,7 +988,7 @@ class Poche
994 /** 988 /**
995 * import from Poche exported file 989 * import from Poche exported file
996 * @param string $targetFile the file used for importing 990 * @param string $targetFile the file used for importing
997 * @return boolean 991 * @return boolean
998 */ 992 */
999 private function importFromPoche($targetFile) 993 private function importFromPoche($targetFile)
1000 { 994 {
@@ -1014,12 +1008,12 @@ class Poche
1014 $url = new Url(base64_encode($value['url'])); 1008 $url = new Url(base64_encode($value['url']));
1015 $favorite = ($value['is_fav'] == -1); 1009 $favorite = ($value['is_fav'] == -1);
1016 $archive = ($value['is_read'] == -1); 1010 $archive = ($value['is_read'] == -1);
1017 1011
1018 # we can add the url 1012 # we can add the url
1019 if (!is_null($url) && $url->isCorrect()) { 1013 if (!is_null($url) && $url->isCorrect()) {
1020 1014
1021 $this->action('add', $url, 0, TRUE); 1015 $this->action('add', $url, 0, TRUE);
1022 1016
1023 $count++; 1017 $count++;
1024 if ($favorite) { 1018 if ($favorite) {
1025 $last_id = $this->store->getLastId($sequence); 1019 $last_id = $this->store->getLastId($sequence);
@@ -1030,7 +1024,7 @@ class Poche
1030 $this->action('toggle_archive', $url, $last_id, TRUE); 1024 $this->action('toggle_archive', $url, $last_id, TRUE);
1031 } 1025 }
1032 } 1026 }
1033 1027
1034 } 1028 }
1035 1029
1036 unlink($targetFile); 1030 unlink($targetFile);
@@ -1041,37 +1035,115 @@ class Poche
1041 1035
1042 /** 1036 /**
1043 * import datas into your poche 1037 * import datas into your poche
1044 * @param string $from name of the service to import : pocket, instapaper or readability 1038 * @return boolean
1045 * @todo add the return value
1046 * @return boolean
1047 */ 1039 */
1048 public function import($from) 1040 public function import() {
1049 { 1041
1050 $providers = array( 1042 if ( isset($_FILES['file']) ) {
1051 'pocket' => 'importFromPocket', 1043 // assume, that file is in json format
1052 'readability' => 'importFromReadability', 1044 $str_data = file_get_contents($_FILES['file']['tmp_name']);
1053 'instapaper' => 'importFromInstapaper', 1045 $data = json_decode($str_data, true);
1054 'poche' => 'importFromPoche', 1046
1055 ); 1047 if ( $data === null ) {
1056 1048 //not json - assume html
1057 if (! isset($providers[$from])) { 1049 $html = new simple_html_dom();
1058 $this->messages->add('e', _('Unknown import provider.')); 1050 $html->load_file($_FILES['file']['tmp_name']);
1059 Tools::redirect(); 1051 $data = array();
1052 $read = 0;
1053 foreach (array('ol','ul') as $list) {
1054 foreach ($html->find($list) as $ul) {
1055 foreach ($ul->find('li') as $li) {
1056 $tmpEntry = array();
1057 $a = $li->find('a');
1058 $tmpEntry['url'] = $a[0]->href;
1059 $tmpEntry['tags'] = $a[0]->tags;
1060 $tmpEntry['is_read'] = $read;
1061 if ($tmpEntry['url']) {
1062 $data[] = $tmpEntry;
1063 }
1064 }
1065 # the second <ol/ul> is for read links
1066 $read = ((sizeof($data) && $read)?0:1);
1067 }
1068 }
1060 } 1069 }
1061 1070
1062 $targetFile = CACHE . '/' . constant(strtoupper($from) . '_FILE'); 1071 $i = 0; //counter for articles inserted
1063 1072 foreach ($data as $record) {
1064 if (! file_exists($targetFile)) { 1073 //echo '<pre>';
1065 $this->messages->add('e', _('Could not find required "' . $targetFile . '" import file.')); 1074 //var_dump($record);
1066 Tools::redirect(); 1075 // foreach ($record as $key=>$val) {
1076 // echo "\n=================\n$i: $key: $val\n";
1077 // }
1078 // exit;
1079
1080 $url = trim($record['url']);
1081 if ( $url ) {
1082 $title = (isset($record['title']) ? $record['title'] : _('Untitled - Import - ').'</a> <a href="./?import">'._('click to finish import').'</a><a>');
1083 $body = (isset($record['content']) ? $record['content'] : '');
1084 $isRead = (isset($record['is_read']) ? intval($record['is_read']) : 0);
1085 $isFavorite = (isset($record['is_fav']) ? intval($record['is_fav']) : 0);
1086 //insert new record
1087 $id = $this->store->add($url, $title, $body, $this->user->getId(), $isFavorite, $isRead);
1088 if ( $id ) {
1089 //increment no of records inserted
1090 $i++;
1091 if ( isset($record['tags']) && trim($record['tags']) ) {
1092 //@TODO: set tags
1093
1094 }
1095 }
1096 }
1097 }
1098
1099 if ( $i > 0 ) {
1100 $this->messages->add('s', _('Articles inserted: ').$i._('. Please note, that some may be marked as "read".'));
1101 }
1102 }
1103 //file parsing finished here
1104
1105 //now download article contents if any
1106
1107 //check if we need to download any content
1108 $recordsDownloadRequired = $this->store->retrieveUnfetchedEntriesCount($this->user->getId());
1109 if ( $recordsDownloadRequired == 0 ) {
1110 //nothing to download
1111 $this->messages->add('s', _('Import finished.'));
1112 Tools::redirect();
1113 }
1114 else {
1115 //if just inserted - don't download anything, download will start in next reload
1116 if ( !isset($_FILES['file']) ) {
1117 //download next batch
1118 $items = $this->store->retrieveUnfetchedEntries($this->user->getId(), IMPORT_LIMIT);
1119
1120 $config = HTMLPurifier_Config::createDefault();
1121 $config->set('Cache.SerializerPath', CACHE);
1122 $purifier = new HTMLPurifier($config);
1123
1124 foreach ($items as $item) {
1125 $url = new Url(base64_encode($item['url']));
1126 $content = Tools::getPageContent($url);
1127
1128 $title = (($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled'));
1129 $body = (($content['rss']['channel']['item']['description'] != '') ? $content['rss']['channel']['item']['description'] : _('Undefined'));
1130
1131 //clean content to prevent xss attack
1132 $title = $purifier->purify($title);
1133 $body = $purifier->purify($body);
1134
1135 $this->store->updateContentAndTitle($item['id'], $title, $body, $this->user->getId());
1136 }
1137
1067 } 1138 }
1068 1139 }
1069 $this->$providers[$from]($targetFile); 1140
1141 return array('includeImport'=>true, 'import'=>array('recordsDownloadRequired'=>$recordsDownloadRequired, 'recordsUnderDownload'=> IMPORT_LIMIT, 'delay'=> IMPORT_DELAY * 1000) );
1070 } 1142 }
1071 1143
1072 public function uploadFile() { 1144 public function uploadFile() {
1073 if(isset($_FILES['file'])) 1145 if (isset($_FILES['file']))
1074 { 1146 {
1075 $dir = CACHE . '/'; 1147 $dir = CACHE . '/';
1076 $file = basename($_FILES['file']['name']); 1148 $file = basename($_FILES['file']['name']);
1077 if(move_uploaded_file($_FILES['file']['tmp_name'], $dir . $file)) { 1149 if(move_uploaded_file($_FILES['file']['tmp_name'], $dir . $file)) {
@@ -1081,7 +1153,7 @@ class Poche
1081 $this->messages->add('e', _('Error while importing file. Do you have access to upload it?')); 1153 $this->messages->add('e', _('Error while importing file. Do you have access to upload it?'));
1082 } 1154 }
1083 } 1155 }
1084 1156
1085 Tools::redirect('?view=config'); 1157 Tools::redirect('?view=config');
1086 } 1158 }
1087 1159
@@ -1093,7 +1165,7 @@ class Poche
1093 { 1165 {
1094 $filename = "wallabag-export-".$this->user->getId()."-".date("Y-m-d").".json"; 1166 $filename = "wallabag-export-".$this->user->getId()."-".date("Y-m-d").".json";
1095 header('Content-Disposition: attachment; filename='.$filename); 1167 header('Content-Disposition: attachment; filename='.$filename);
1096 1168
1097 $entries = $this->store->retrieveAll($this->user->getId()); 1169 $entries = $this->store->retrieveAll($this->user->getId());
1098 echo $this->tpl->render('export.twig', array( 1170 echo $this->tpl->render('export.twig', array(
1099 'export' => Tools::renderJson($entries), 1171 'export' => Tools::renderJson($entries),
diff --git a/inc/poche/Tools.class.php b/inc/poche/Tools.class.php
index ad451fc6..a130e94b 100755
--- a/inc/poche/Tools.class.php
+++ b/inc/poche/Tools.class.php
@@ -7,7 +7,7 @@
7 * @copyright 2013 7 * @copyright 2013
8 * @license http://www.wtfpl.net/ see COPYING file 8 * @license http://www.wtfpl.net/ see COPYING file
9 */ 9 */
10 10
11class Tools 11class Tools
12{ 12{
13 public static function initPhp() 13 public static function initPhp()
@@ -42,7 +42,7 @@ class Tools
42 && (strtolower($_SERVER['HTTPS']) == 'on')) 42 && (strtolower($_SERVER['HTTPS']) == 'on'))
43 || (isset($_SERVER["SERVER_PORT"]) 43 || (isset($_SERVER["SERVER_PORT"])
44 && $_SERVER["SERVER_PORT"] == '443') // HTTPS detection. 44 && $_SERVER["SERVER_PORT"] == '443') // HTTPS detection.
45 || (isset($_SERVER["SERVER_PORT"]) //Custom HTTPS port detection 45 || (isset($_SERVER["SERVER_PORT"]) //Custom HTTPS port detection
46 && $_SERVER["SERVER_PORT"] == SSL_PORT) 46 && $_SERVER["SERVER_PORT"] == SSL_PORT)
47 || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) 47 || (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])
48 && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'); 48 && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https');
@@ -148,7 +148,7 @@ class Tools
148 ); 148 );
149 149
150 # only download page lesser than 4MB 150 # only download page lesser than 4MB
151 $data = @file_get_contents($url, false, $context, -1, 4000000); 151 $data = @file_get_contents($url, false, $context, -1, 4000000);
152 152
153 if (isset($http_response_header) and isset($http_response_header[0])) { 153 if (isset($http_response_header) and isset($http_response_header[0])) {
154 $httpcodeOK = isset($http_response_header) and isset($http_response_header[0]) and ((strpos($http_response_header[0], '200 OK') !== FALSE) or (strpos($http_response_header[0], '301 Moved Permanently') !== FALSE)); 154 $httpcodeOK = isset($http_response_header) and isset($http_response_header[0]) and ((strpos($http_response_header[0], '200 OK') !== FALSE) or (strpos($http_response_header[0], '301 Moved Permanently') !== FALSE));
@@ -200,7 +200,7 @@ class Tools
200 } 200 }
201 } 201 }
202 202
203 public static function encodeString($string) 203 public static function encodeString($string)
204 { 204 {
205 return sha1($string . SALT); 205 return sha1($string . SALT);
206 } 206 }
diff --git a/inc/poche/config.inc.php.new b/inc/poche/config.inc.php.new
index 8d52497b..83b3c4c0 100755
--- a/inc/poche/config.inc.php.new
+++ b/inc/poche/config.inc.php.new
@@ -52,12 +52,8 @@ define ('CACHE', ROOT . '/cache');
52 52
53define ('PAGINATION', '10'); 53define ('PAGINATION', '10');
54 54
55define ('POCKET_FILE', '/ril_export.html'); 55//limit for download of articles during import
56define ('READABILITY_FILE', '/readability'); 56define ('IMPORT_LIMIT', 5);
57define ('INSTAPAPER_FILE', '/instapaper-export.html'); 57//delay between downloads (in sec)
58define ('POCHE_FILE', '/poche-export'); 58define ('IMPORT_DELAY', 5);
59 59
60define ('IMPORT_POCKET_FILE', ROOT . POCKET_FILE);
61define ('IMPORT_READABILITY_FILE', ROOT . READABILITY_FILE);
62define ('IMPORT_INSTAPAPER_FILE', ROOT . INSTAPAPER_FILE);
63define ('IMPORT_POCHE_FILE', ROOT . POCHE_FILE); \ No newline at end of file
diff --git a/index.php b/index.php
index fb13f38d..8b578832 100644..100755
--- a/index.php
+++ b/index.php
@@ -40,7 +40,7 @@ $tpl_vars = array(
40 40
41if (! empty($notInstalledMessage)) { 41if (! empty($notInstalledMessage)) {
42 if (! Poche::$canRenderTemplates || ! Poche::$configFileAvailable) { 42 if (! Poche::$canRenderTemplates || ! Poche::$configFileAvailable) {
43 # We cannot use Twig to display the error message 43 # We cannot use Twig to display the error message
44 echo '<h1>Errors</h1><ol>'; 44 echo '<h1>Errors</h1><ol>';
45 foreach ($notInstalledMessage as $message) { 45 foreach ($notInstalledMessage as $message) {
46 echo '<li>' . $message . '</li>'; 46 echo '<li>' . $message . '</li>';
@@ -67,7 +67,8 @@ if (isset($_GET['login'])) {
67 # Update password 67 # Update password
68 $poche->updatePassword(); 68 $poche->updatePassword();
69} elseif (isset($_GET['import'])) { 69} elseif (isset($_GET['import'])) {
70 $import = $poche->import($_GET['from']); 70 $import = $poche->import();
71 $tpl_vars = array_merge($tpl_vars, $import);
71} elseif (isset($_GET['download'])) { 72} elseif (isset($_GET['download'])) {
72 Tools::download_db(); 73 Tools::download_db();
73} elseif (isset($_GET['empty-cache'])) { 74} elseif (isset($_GET['empty-cache'])) {
diff --git a/themes/default/_import.twig b/themes/default/_import.twig
new file mode 100755
index 00000000..926696c1
--- /dev/null
+++ b/themes/default/_import.twig
@@ -0,0 +1,15 @@
1<script type="text/javascript">
2<!--
3 $(document).ready(function() {
4 $("body").css("cursor", "wait");
5
6 setTimeout(function(){
7 window.location = '/?import';
8 }, {{ import.delay }} );
9 });
10//-->
11</script>
12<div class="messages warning">
13 <p>{% trans "Download required for " %} {{ import.recordsDownloadRequired }} {% trans "records" %}.</p>
14 <p>{% trans "Downloading next " %} {{ import.recordsUnderDownload }} {% trans "articles, please wait" %}...</p>
15</div>
diff --git a/themes/default/config.twig b/themes/default/config.twig
index 5d20e0ea..7ccd0b36 100644..100755
--- a/themes/default/config.twig
+++ b/themes/default/config.twig
@@ -104,36 +104,19 @@
104 {% endif %} 104 {% endif %}
105 105
106 <h2>{% trans "Import" %}</h2> 106 <h2>{% trans "Import" %}</h2>
107 <p>{% trans "Importing from other services can be quite long, and webservers default configuration often prevents long scripts execution time, so it must be done in multiple parts." %}</p> 107 <p>{% trans "You can import your Pocket, Readability, Instapaper, Wallabag or any data in appropriate json or html format." %}</p>
108 <p>1. {% trans "First, select the export file on your computer and upload it." %}</p> 108 <p>{% trans "Please select export file on your computer:" %}</p>
109 <form method="post" action="?uploadfile" name="uploadfile" enctype="multipart/form-data"> 109 <form method="post" action="?import" name="uploadfile" enctype="multipart/form-data">
110 <fieldset class="w500p"> 110 <fieldset class="w500p">
111 <div class="row"> 111 <div class="row">
112 <label class="col w150p" for="file">{% trans "File:" %}</label> 112 <label class="col w150p" for="file">{% trans "File:" %}</label>
113 <input class="col" type="file" id="file" name="file" tabindex="4"> 113 <input class="col" type="file" id="file" name="file" tabindex="4">
114 </div> 114 </div>
115 <div class="row mts txtcenter"> 115 <div class="row mts txtcenter">
116 <button class="bouton" type="submit" tabindex="4">{% trans "Upload" %}</button> 116 <button class="bouton" type="submit" tabindex="4">{% trans "Import" %}</button>
117 </div> 117 </div>
118 </fieldset> 118 </fieldset>
119 <input type="hidden" name="MAX_FILE_SIZE" value="1048576">
120 <input type="hidden" name="returnurl" value="{{ referer }}">
121 </form> 119 </form>
122 <p>2. {% trans "Then, click on the right link below." %}</p>
123 <ul>
124 <li><a href="./?import&amp;from=pocket">{% trans "Import from Pocket" %}</a> {{ '(after uploaded %s file)'|trans|format(constant('POCKET_FILE')) }}</li>
125 <li><a href="./?import&amp;from=readability">{% trans "Import from Readability" %}</a> {{ '(after uploaded %s file)'|trans|format(constant('READABILITY_FILE')) }}</li>
126 <li><a href="./?import&amp;from=instapaper">{% trans "Import from Instapaper" %}</a> {{ '(after uploaded %s file)'|trans|format(constant('INSTAPAPER_FILE')) }}</li>
127 <li><a href="./?import&amp;from=poche">{% trans "Import from wallabag" %}</a> {{ '(after uploaded %s file)'|trans|format(constant('POCHE_FILE')) }}</li>
128 </ul>
129
130 {% if token == '' %}
131 <p>{% trans "3. Your feed token is currently empty and must first be generated to fetch content. Click <a href='?feed&amp;action=generate'>here to generate it</a>." %}</p>
132 {% else %}
133 <p>3. {% trans "Finally, you have to fetch content for imported items." %} <a href="cron.php?limit=10&amp;user-id={{ user_id }}&amp;token={{token}}" target="_blank">{% trans "Click here" %}</a> {% trans "to fetch content for 10 articles" %}.</p>
134 <p>{% trans "If you have console access to your server, you can also create a cron task:" %}</p>
135 <pre><code>0 */4 * * * cd /path/to/wallabag && php cron.php --limit=10 --user-id={{user_id}} --token={{token}} >/dev/null 2>&1</code></pre>
136 {% endif %}
137 120
138 <h2>{% trans "Export your wallabag data" %}</h2> 121 <h2>{% trans "Export your wallabag data" %}</h2>
139 {% if constant('STORAGE') == 'sqlite' %} 122 {% if constant('STORAGE') == 'sqlite' %}
diff --git a/themes/default/home.twig b/themes/default/home.twig
index b6185df1..e06d65ab 100755
--- a/themes/default/home.twig
+++ b/themes/default/home.twig
@@ -16,6 +16,11 @@
16{% include '_sorting.twig' %} 16{% include '_sorting.twig' %}
17{% endblock %} 17{% endblock %}
18{% block content %} 18{% block content %}
19
20 {% if includeImport %}
21 {% include '_import.twig' %}
22 {% endif %}
23
19 {% if tag %} 24 {% if tag %}
20 <h3>{% trans "Tag" %}: <b>{{ tag.value }}</b></h3> 25 <h3>{% trans "Tag" %}: <b>{{ tag.value }}</b></h3>
21 {% endif %} 26 {% endif %}