aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNicolas Lœuillet <nicolas@loeuillet.org>2014-04-11 17:22:04 +0200
committerNicolas Lœuillet <nicolas@loeuillet.org>2014-04-11 17:22:04 +0200
commit4a74d9857cdb6116ce24df01b45176b92ad592c0 (patch)
treef8347803fe40f8b27218cbad8ed688c7dbf3a46e
parent0d67b00d5d3b7ce1b76b639dcc65c415a5f13439 (diff)
parent7256e9e139eb07cdae1fbe3009454e6c7d9a8677 (diff)
downloadwallabag-4a74d9857cdb6116ce24df01b45176b92ad592c0.tar.gz
wallabag-4a74d9857cdb6116ce24df01b45176b92ad592c0.tar.zst
wallabag-4a74d9857cdb6116ce24df01b45176b92ad592c0.zip
Merge pull request #634 from wallabag/dev1.6.1b
1.6.1
-rw-r--r--README.md2
-rw-r--r--inc/3rdparty/libraries/feedwriter/FeedItem.php353
-rwxr-xr-xinc/3rdparty/libraries/feedwriter/FeedWriter.php839
-rwxr-xr-xinc/poche/Database.class.php12
-rwxr-xr-xinc/poche/Poche.class.php163
-rwxr-xr-xinc/poche/Tools.class.php4
-rwxr-xr-xindex.php2
-rwxr-xr-x[-rw-r--r--]locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mobin12738 -> 12818 bytes
-rwxr-xr-x[-rw-r--r--]locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po116
-rwxr-xr-xthemes/baggy/_head.twig1
-rw-r--r--themes/baggy/_search-form.twig22
-rwxr-xr-xthemes/baggy/css/main.css16
-rwxr-xr-xthemes/courgette/config.twig10
-rwxr-xr-xthemes/default/_head.twig1
-rw-r--r--themes/default/js/popupForm.js20
-rwxr-xr-xthemes/default/js/saveLink.js2
16 files changed, 814 insertions, 749 deletions
diff --git a/README.md b/README.md
index fe6a06b6..0b54dff4 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ wallabag is a self hostable application allowing you to not miss any content any
4More informations on our website: [wallabag.org](http://wallabag.org) 4More informations on our website: [wallabag.org](http://wallabag.org)
5 5
6## License 6## License
7Copyright © 2010-2013 Nicolas Lœuillet <nicolas@loeuillet.org> 7Copyright © 2010-2014 Nicolas Lœuillet <nicolas@loeuillet.org>
8This work is free. You can redistribute it and/or modify it under the 8This work is free. You can redistribute it and/or modify it under the
9terms of the Do What The Fuck You Want To Public License, Version 2, 9terms of the Do What The Fuck You Want To Public License, Version 2,
10as published by Sam Hocevar. See the COPYING file for more details. 10as published by Sam Hocevar. See the COPYING file for more details.
diff --git a/inc/3rdparty/libraries/feedwriter/FeedItem.php b/inc/3rdparty/libraries/feedwriter/FeedItem.php
index 0eae5e08..3487423f 100644
--- a/inc/3rdparty/libraries/feedwriter/FeedItem.php
+++ b/inc/3rdparty/libraries/feedwriter/FeedItem.php
@@ -10,177 +10,188 @@
10 */ 10 */
11 class FeedItem 11 class FeedItem
12 { 12 {
13 private $elements = array(); //Collection of feed elements 13 private $elements = array(); //Collection of feed elements
14 private $version; 14 private $version;
15 15
16 /** 16 /**
17 * Constructor 17 * Constructor
18 * 18 *
19 * @param contant (RSS1/RSS2/ATOM) RSS2 is default. 19 * @param contant (RSS1/RSS2/ATOM) RSS2 is default.
20 */ 20 */
21 function __construct($version = RSS2) 21 function __construct($version = RSS2)
22 { 22 {
23 $this->version = $version; 23 $this->version = $version;
24 } 24 }
25 25
26 /** 26 /**
27 * Set element (overwrites existing elements with $elementName) 27 * Set element (overwrites existing elements with $elementName)
28 * 28 *
29 * @access public 29 * @access public
30 * @param srting The tag name of an element 30 * @param srting The tag name of an element
31 * @param srting The content of tag 31 * @param srting The content of tag
32 * @param array Attributes(if any) in 'attrName' => 'attrValue' format 32 * @param array Attributes(if any) in 'attrName' => 'attrValue' format
33 * @return void 33 * @return void
34 */ 34 */
35 public function setElement($elementName, $content, $attributes = null) 35 public function setElement($elementName, $content, $attributes = null)
36 { 36 {
37 if (isset($this->elements[$elementName])) { 37 if (isset($this->elements[$elementName])) {
38 unset($this->elements[$elementName]); 38 unset($this->elements[$elementName]);
39 } 39 }
40 $this->addElement($elementName, $content, $attributes); 40 $this->addElement($elementName, $content, $attributes);
41 } 41 }
42 42
43 /** 43 /**
44 * Add an element to elements array 44 * Add an element to elements array
45 * 45 *
46 * @access public 46 * @access public
47 * @param srting The tag name of an element 47 * @param srting The tag name of an element
48 * @param srting The content of tag 48 * @param srting The content of tag
49 * @param array Attributes(if any) in 'attrName' => 'attrValue' format 49 * @param array Attributes(if any) in 'attrName' => 'attrValue' format
50 * @return void 50 * @return void
51 */ 51 */
52 public function addElement($elementName, $content, $attributes = null) 52 public function addElement($elementName, $content, $attributes = null)
53 { 53 {
54 $i = 0; 54 $i = 0;
55 if (isset($this->elements[$elementName])) { 55 if (isset($this->elements[$elementName])) {
56 $i = count($this->elements[$elementName]); 56 $i = count($this->elements[$elementName]);
57 } else { 57 } else {
58 $this->elements[$elementName] = array(); 58 $this->elements[$elementName] = array();
59 } 59 }
60 $this->elements[$elementName][$i]['name'] = $elementName; 60 $this->elements[$elementName][$i]['name'] = $elementName;
61 $this->elements[$elementName][$i]['content'] = $content; 61 $this->elements[$elementName][$i]['content'] = $content;
62 $this->elements[$elementName][$i]['attributes'] = $attributes; 62 $this->elements[$elementName][$i]['attributes'] = $attributes;
63 } 63 }
64 64
65 /** 65 /**
66 * Set multiple feed elements from an array. 66 * Set multiple feed elements from an array.
67 * Elements which have attributes cannot be added by this method 67 * Elements which have attributes cannot be added by this method
68 * 68 *
69 * @access public 69 * @access public
70 * @param array array of elements in 'tagName' => 'tagContent' format. 70 * @param array array of elements in 'tagName' => 'tagContent' format.
71 * @return void 71 * @return void
72 */ 72 */
73 public function addElementArray($elementArray) 73 public function addElementArray($elementArray)
74 { 74 {
75 if(! is_array($elementArray)) return; 75 if(! is_array($elementArray)) return;
76 foreach ($elementArray as $elementName => $content) 76 foreach ($elementArray as $elementName => $content)
77 { 77 {
78 $this->addElement($elementName, $content); 78 $this->addElement($elementName, $content);
79 } 79 }
80 } 80 }
81 81
82 /** 82 /**
83 * Return the collection of elements in this feed item 83 * Return the collection of elements in this feed item
84 * 84 *
85 * @access public 85 * @access public
86 * @return array 86 * @return array
87 */ 87 */
88 public function getElements() 88 public function getElements()
89 { 89 {
90 return $this->elements; 90 return $this->elements;
91 } 91 }
92 92
93 // Wrapper functions ------------------------------------------------------ 93 // Wrapper functions ------------------------------------------------------
94 94
95 /** 95 /**
96 * Set the 'dscription' element of feed item 96 * Set the 'dscription' element of feed item
97 * 97 *
98 * @access public 98 * @access public
99 * @param string The content of 'description' element 99 * @param string The content of 'description' element
100 * @return void 100 * @return void
101 */ 101 */
102 public function setDescription($description) 102 public function setDescription($description)
103 { 103 {
104 $tag = 'description'; 104 $this->setElement('description', $description);
105 $this->setElement($tag, $description); 105 }
106 } 106
107 107 /**
108 /** 108 * @desc Set the 'title' element of feed item
109 * @desc Set the 'title' element of feed item 109 * @access public
110 * @access public 110 * @param string The content of 'title' element
111 * @param string The content of 'title' element 111 * @return void
112 * @return void 112 */
113 */ 113 public function setTitle($title)
114 public function setTitle($title) 114 {
115 { 115 $this->setElement('title', $title);
116 $this->setElement('title', $title); 116 }
117 } 117
118 118 /**
119 /** 119 * Set the 'date' element of feed item
120 * Set the 'date' element of feed item 120 *
121 * 121 * @access public
122 * @access public 122 * @param string The content of 'date' element
123 * @param string The content of 'date' element 123 * @return void
124 * @return void 124 */
125 */ 125 public function setDate($date)
126 public function setDate($date) 126 {
127 { 127 if(! is_numeric($date))
128 if(! is_numeric($date)) 128 {
129 { 129 $date = strtotime($date);
130 $date = strtotime($date); 130 }
131 }
132 131
133 if($this->version == RSS2) 132 if($this->version == RSS2)
134 { 133 {
135 $tag = 'pubDate'; 134 $tag = 'pubDate';
136 $value = date(DATE_RSS, $date); 135 $value = date(DATE_RSS, $date);
137 } 136 }
138 else 137 else
139 { 138 {
140 $tag = 'dc:date'; 139 $tag = 'dc:date';
141 $value = date("Y-m-d", $date); 140 $value = date("Y-m-d", $date);
142 } 141 }
143 142
144 $this->setElement($tag, $value); 143 $this->setElement($tag, $value);
145 } 144 }
146 145
147 /** 146 /**
148 * Set the 'link' element of feed item 147 * Set the 'link' element of feed item
149 * 148 *
150 * @access public 149 * @access public
151 * @param string The content of 'link' element 150 * @param string The content of 'link' element
152 * @return void 151 * @return void
153 */ 152 */
154 public function setLink($link) 153 public function setLink($link)
155 { 154 {
156 if($this->version == RSS2 || $this->version == RSS1) 155 if($this->version == RSS2 || $this->version == RSS1)
157 { 156 {
158 $this->setElement('link', $link); 157 $this->setElement('link', $link);
159 $this->setElement('guid', $link); 158 $this->setElement('guid', $link);
160 } 159 }
161 else 160 else
162 { 161 {
163 $this->setElement('link','',array('href'=>$link)); 162 $this->setElement('link','',array('href'=>$link));
164 $this->setElement('id', FeedWriter::uuid($link,'urn:uuid:')); 163 $this->setElement('id', FeedWriter::uuid($link,'urn:uuid:'));
165 } 164 }
166 165
167 } 166 }
168 167
169 /** 168 /**
170 * Set the 'encloser' element of feed item 169 * Set the 'source' element of feed item
171 * For RSS 2.0 only 170 *
172 * 171 * @access public
173 * @access public 172 * @param string The content of 'source' element
174 * @param string The url attribute of encloser tag 173 * @return void
175 * @param string The length attribute of encloser tag 174 */
176 * @param string The type attribute of encloser tag 175 public function setSource($link)
177 * @return void 176 {
178 */ 177 $this->setElement('source', $link);
179 public function setEncloser($url, $length, $type) 178 }
180 { 179
181 $attributes = array('url'=>$url, 'length'=>$length, 'type'=>$type); 180 /**
182 $this->setElement('enclosure','',$attributes); 181 * Set the 'encloser' element of feed item
183 } 182 * For RSS 2.0 only
184 183 *
184 * @access public
185 * @param string The url attribute of encloser tag
186 * @param string The length attribute of encloser tag
187 * @param string The type attribute of encloser tag
188 * @return void
189 */
190 public function setEncloser($url, $length, $type)
191 {
192 $attributes = array('url'=>$url, 'length'=>$length, 'type'=>$type);
193 $this->setElement('enclosure','',$attributes);
194 }
195
185 } // end of class FeedItem 196 } // end of class FeedItem
186?> 197?> \ No newline at end of file
diff --git a/inc/3rdparty/libraries/feedwriter/FeedWriter.php b/inc/3rdparty/libraries/feedwriter/FeedWriter.php
index 5d16e765..df4c8b4b 100755
--- a/inc/3rdparty/libraries/feedwriter/FeedWriter.php
+++ b/inc/3rdparty/libraries/feedwriter/FeedWriter.php
@@ -18,424 +18,423 @@ define('JSONP', 3, true);
18 */ 18 */
19 class FeedWriter 19 class FeedWriter
20 { 20 {
21 private $self = null; // self URL - http://feed2.w3.org/docs/warning/MissingAtomSelfLink.html 21 private $self = null; // self URL - http://feed2.w3.org/docs/warning/MissingAtomSelfLink.html
22 private $hubs = array(); // PubSubHubbub hubs 22 private $hubs = array(); // PubSubHubbub hubs
23 private $channels = array(); // Collection of channel elements 23 private $channels = array(); // Collection of channel elements
24 private $items = array(); // Collection of items as object of FeedItem class. 24 private $items = array(); // Collection of items as object of FeedItem class.
25 private $data = array(); // Store some other version wise data 25 private $data = array(); // Store some other version wise data
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
58 * @param srting name of the channel tag 58 * @param srting name of the channel tag
59 * @param string content of the channel tag 59 * @param string content of the channel tag
60 * @return void 60 * @return void
61 */ 61 */
62 public function setChannelElement($elementName, $content) 62 public function setChannelElement($elementName, $content)
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
74 */ 74 */
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();
105 $this->printChannels(); 105 $this->printChannels();
106 $this->printItems(); 106 $this->printItems();
107 $this->printTale(); 107 $this->printTale();
108 if ($this->version == JSON || $this->version == JSONP) { 108 if ($this->version == JSON || $this->version == JSONP) {
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 */
119 public function createNewItem() 119 public function createNewItem()
120 { 120 {
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
145 */ 145 */
146 public function setTitle($title) 146 public function setTitle($title)
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($description)
195 { 195 {
196 $tag = ($this->version == ATOM)? 'subtitle' : 'description'; 196 $this->setChannelElement('description', $description);
197 $this->setChannelElement($tag, $desciption); 197 }
198 } 198
199 199 /**
200 /** 200 * Set the 'link' channel element
201 * Set the 'link' channel element 201 *
202 * 202 * @access public
203 * @access public 203 * @param srting value of 'link' channel tag
204 * @param srting value of 'link' channel tag 204 * @return void
205 * @return void 205 */
206 */ 206 public function setLink($link)
207 public function setLink($link) 207 {
208 { 208 $this->setChannelElement('link', $link);
209 $this->setChannelElement('link', $link); 209 }
210 } 210
211 211 /**
212 /** 212 * Set the 'image' channel element
213 * Set the 'image' channel element 213 *
214 * 214 * @access public
215 * @access public 215 * @param srting title of image
216 * @param srting title of image 216 * @param srting link url of the imahe
217 * @param srting link url of the imahe 217 * @param srting path url of the image
218 * @param srting path url of the image 218 * @return void
219 * @return void 219 */
220 */ 220 public function setImage($title, $link, $url)
221 public function setImage($title, $link, $url) 221 {
222 { 222 $this->setChannelElement('image', array('title'=>$title, 'link'=>$link, 'url'=>$url));
223 $this->setChannelElement('image', array('title'=>$title, 'link'=>$link, 'url'=>$url)); 223 }
224 } 224
225 225 // End # public functions ----------------------------------------------
226 // End # public functions ---------------------------------------------- 226
227 227 // Start # private functions ----------------------------------------------
228 // Start # private functions ---------------------------------------------- 228
229 229 /**
230 /** 230 * Prints the xml and rss namespace
231 * Prints the xml and rss namespace 231 *
232 * 232 * @access private
233 * @access private 233 * @return void
234 * @return void 234 */
235 */ 235 private function printHead()
236 private function printHead() 236 {
237 { 237 if ($this->version == RSS2)
238 if ($this->version == RSS2) 238 {
239 { 239 $out = '<?xml version="1.0" encoding="utf-8"?>'."\n";
240 $out = '<?xml version="1.0" encoding="utf-8"?>'."\n"; 240 if ($this->xsl) $out .= '<?xml-stylesheet type="text/xsl" href="'.htmlspecialchars($this->xsl).'"?>' . PHP_EOL;
241 if ($this->xsl) $out .= '<?xml-stylesheet type="text/xsl" href="'.htmlspecialchars($this->xsl).'"?>' . PHP_EOL; 241 $out .= '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">' . PHP_EOL;
242 $out .= '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">' . PHP_EOL; 242 echo $out;
243 echo $out; 243 }
244 } 244 elseif ($this->version == JSON || $this->version == JSONP)
245 elseif ($this->version == JSON || $this->version == JSONP) 245 {
246 { 246 $this->json->rss = array('@attributes' => array('version' => '2.0'));
247 $this->json->rss = array('@attributes' => array('version' => '2.0')); 247 }
248 } 248 }
249 } 249
250 250 /**
251 /** 251 * Closes the open tags at the end of file
252 * Closes the open tags at the end of file 252 *
253 * 253 * @access private
254 * @access private 254 * @return void
255 * @return void 255 */
256 */ 256 private function printTale()
257 private function printTale() 257 {
258 { 258 if ($this->version == RSS2)
259 if ($this->version == RSS2) 259 {
260 { 260 echo '</channel>',PHP_EOL,'</rss>';
261 echo '</channel>',PHP_EOL,'</rss>'; 261 }
262 } 262 // do nothing for JSON
263 // do nothing for JSON 263 }
264 } 264
265 265 /**
266 /** 266 * Creates a single node as xml format
267 * Creates a single node as xml format 267 *
268 * 268 * @access private
269 * @access private 269 * @param string name of the tag
270 * @param string name of the tag 270 * @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 271 * @param array Attributes(if any) in 'attrName' => 'attrValue' format
272 * @param array Attributes(if any) in 'attrName' => 'attrValue' format 272 * @return string formatted xml tag
273 * @return string formatted xml tag 273 */
274 */ 274 private function makeNode($tagName, $tagContent, $attributes = null)
275 private function makeNode($tagName, $tagContent, $attributes = null) 275 {
276 { 276 if ($this->version == RSS2)
277 if ($this->version == RSS2) 277 {
278 { 278 $nodeText = '';
279 $nodeText = ''; 279 $attrText = '';
280 $attrText = ''; 280 if (is_array($attributes))
281 if (is_array($attributes)) 281 {
282 { 282 foreach ($attributes as $key => $value)
283 foreach ($attributes as $key => $value) 283 {
284 { 284 $attrText .= " $key=\"$value\" ";
285 $attrText .= " $key=\"$value\" "; 285 }
286 } 286 }
287 } 287 $nodeText .= "<{$tagName}{$attrText}>";
288 $nodeText .= "<{$tagName}{$attrText}>"; 288 if (is_array($tagContent))
289 if (is_array($tagContent)) 289 {
290 { 290 foreach ($tagContent as $key => $value)
291 foreach ($tagContent as $key => $value) 291 {
292 { 292 $nodeText .= $this->makeNode($key, $value);
293 $nodeText .= $this->makeNode($key, $value); 293 }
294 } 294 }
295 } 295 else
296 else 296 {
297 { 297 //$nodeText .= (in_array($tagName, $this->CDATAEncoding))? $tagContent : htmlentities($tagContent);
298 //$nodeText .= (in_array($tagName, $this->CDATAEncoding))? $tagContent : htmlentities($tagContent); 298 $nodeText .= htmlspecialchars($tagContent);
299 $nodeText .= htmlspecialchars($tagContent); 299 }
300 } 300 //$nodeText .= (in_array($tagName, $this->CDATAEncoding))? "]]></$tagName>" : "</$tagName>";
301 //$nodeText .= (in_array($tagName, $this->CDATAEncoding))? "]]></$tagName>" : "</$tagName>"; 301 $nodeText .= "</$tagName>";
302 $nodeText .= "</$tagName>"; 302 return $nodeText . PHP_EOL;
303 return $nodeText . PHP_EOL; 303 }
304 } 304 elseif ($this->version == JSON || $this->version == JSONP)
305 elseif ($this->version == JSON || $this->version == JSONP) 305 {
306 { 306 $tagName = (string)$tagName;
307 $tagName = (string)$tagName; 307 $tagName = strtr($tagName, ':', '_');
308 $tagName = strtr($tagName, ':', '_'); 308 $node = null;
309 $node = null; 309 if (!$tagContent && is_array($attributes) && count($attributes))
310 if (!$tagContent && is_array($attributes) && count($attributes)) 310 {
311 { 311 $node = array('@attributes' => $this->json_keys($attributes));
312 $node = array('@attributes' => $this->json_keys($attributes)); 312 } else {
313 } else { 313 if (is_array($tagContent)) {
314 if (is_array($tagContent)) { 314 $node = $this->json_keys($tagContent);
315 $node = $this->json_keys($tagContent); 315 } else {
316 } else { 316 $node = $tagContent;
317 $node = $tagContent; 317 }
318 } 318 }
319 } 319 return $node;
320 return $node; 320 }
321 } 321 return ''; // should not get here
322 return ''; // should not get here 322 }
323 } 323
324 324 private function json_keys(array $array) {
325 private function json_keys(array $array) { 325 $new = array();
326 $new = array(); 326 foreach ($array as $key => $val) {
327 foreach ($array as $key => $val) { 327 if (is_string($key)) $key = strtr($key, ':', '_');
328 if (is_string($key)) $key = strtr($key, ':', '_'); 328 if (is_array($val)) {
329 if (is_array($val)) { 329 $new[$key] = $this->json_keys($val);
330 $new[$key] = $this->json_keys($val); 330 } else {
331 } else { 331 $new[$key] = $val;
332 $new[$key] = $val; 332 }
333 } 333 }
334 } 334 return $new;
335 return $new; 335 }
336 } 336
337 337 /**
338 /** 338 * @desc Print channels
339 * @desc Print channels 339 * @access private
340 * @access private 340 * @return void
341 * @return void 341 */
342 */ 342 private function printChannels()
343 private function printChannels() 343 {
344 { 344 //Start channel tag
345 //Start channel tag 345 if ($this->version == RSS2) {
346 if ($this->version == RSS2) { 346 echo '<channel>' . PHP_EOL;
347 echo '<channel>' . PHP_EOL; 347 // add hubs
348 // add hubs 348 foreach ($this->hubs as $hub) {
349 foreach ($this->hubs as $hub) { 349 //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')); 350 echo '<link rel="hub" href="'.htmlspecialchars($hub).'" xmlns="http://www.w3.org/2005/Atom" />' . PHP_EOL;
351 echo '<link rel="hub" href="'.htmlspecialchars($hub).'" xmlns="http://www.w3.org/2005/Atom" />' . PHP_EOL; 351 }
352 } 352 // add self
353 // add self 353 if (isset($this->self)) {
354 if (isset($this->self)) { 354 //echo $this->makeNode('link', '', array('rel'=>'self', 'href'=>$this->self, 'xmlns'=>'http://www.w3.org/2005/Atom'));
355 //echo $this->makeNode('link', '', array('rel'=>'self', 'href'=>$this->self, 'xmlns'=>'http://www.w3.org/2005/Atom')); 355 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; 356 }
357 } 357 //Print Items of channel
358 //Print Items of channel 358 foreach ($this->channels as $key => $value)
359 foreach ($this->channels as $key => $value) 359 {
360 { 360 echo $this->makeNode($key, $value);
361 echo $this->makeNode($key, $value); 361 }
362 } 362 } elseif ($this->version == JSON || $this->version == JSONP) {
363 } elseif ($this->version == JSON || $this->version == JSONP) { 363 $this->json->rss['channel'] = (object)$this->json_keys($this->channels);
364 $this->json->rss['channel'] = (object)$this->json_keys($this->channels); 364 }
365 } 365 }
366 } 366
367 367 /**
368 /** 368 * Prints formatted feed items
369 * Prints formatted feed items 369 *
370 * 370 * @access private
371 * @access private 371 * @return void
372 * @return void 372 */
373 */ 373 private function printItems()
374 private function printItems() 374 {
375 { 375 foreach ($this->items as $item) {
376 foreach ($this->items as $item) { 376 $itemElements = $item->getElements();
377 $itemElements = $item->getElements(); 377
378 378 echo $this->startItem();
379 echo $this->startItem(); 379
380 380 if ($this->version == JSON || $this->version == JSONP) {
381 if ($this->version == JSON || $this->version == JSONP) { 381 $json_item = array();
382 $json_item = array(); 382 }
383 } 383
384 384 foreach ($itemElements as $thisElement) {
385 foreach ($itemElements as $thisElement) { 385 foreach ($thisElement as $instance) {
386 foreach ($thisElement as $instance) { 386 if ($this->version == RSS2) {
387 if ($this->version == RSS2) { 387 echo $this->makeNode($instance['name'], $instance['content'], $instance['attributes']);
388 echo $this->makeNode($instance['name'], $instance['content'], $instance['attributes']); 388 } elseif ($this->version == JSON || $this->version == JSONP) {
389 } elseif ($this->version == JSON || $this->version == JSONP) { 389 $_json_node = $this->makeNode($instance['name'], $instance['content'], $instance['attributes']);
390 $_json_node = $this->makeNode($instance['name'], $instance['content'], $instance['attributes']); 390 if (count($thisElement) > 1) {
391 if (count($thisElement) > 1) { 391 $json_item[strtr($instance['name'], ':', '_')][] = $_json_node;
392 $json_item[strtr($instance['name'], ':', '_')][] = $_json_node; 392 } else {
393 } else { 393 $json_item[strtr($instance['name'], ':', '_')] = $_json_node;
394 $json_item[strtr($instance['name'], ':', '_')] = $_json_node; 394 }
395 } 395 }
396 } 396 }
397 } 397 }
398 } 398 echo $this->endItem();
399 echo $this->endItem(); 399 if ($this->version == JSON || $this->version == JSONP) {
400 if ($this->version == JSON || $this->version == JSONP) { 400 if (count($this->items) > 1) {
401 if (count($this->items) > 1) { 401 $this->json->rss['channel']->item[] = $json_item;
402 $this->json->rss['channel']->item[] = $json_item; 402 } else {
403 } else { 403 $this->json->rss['channel']->item = $json_item;
404 $this->json->rss['channel']->item = $json_item; 404 }
405 } 405 }
406 } 406 }
407 } 407 }
408 } 408
409 409 /**
410 /** 410 * Make the starting tag of channels
411 * Make the starting tag of channels 411 *
412 * 412 * @access private
413 * @access private 413 * @return void
414 * @return void 414 */
415 */ 415 private function startItem()
416 private function startItem() 416 {
417 { 417 if ($this->version == RSS2)
418 if ($this->version == RSS2) 418 {
419 { 419 echo '<item>' . PHP_EOL;
420 echo '<item>' . PHP_EOL; 420 }
421 } 421 // nothing for JSON
422 // nothing for JSON 422 }
423 } 423
424 424 /**
425 /** 425 * Closes feed item tag
426 * Closes feed item tag 426 *
427 * 427 * @access private
428 * @access private 428 * @return void
429 * @return void 429 */
430 */ 430 private function endItem()
431 private function endItem() 431 {
432 { 432 if ($this->version == RSS2)
433 if ($this->version == RSS2) 433 {
434 { 434 echo '</item>' . PHP_EOL;
435 echo '</item>' . PHP_EOL; 435 }
436 } 436 // nothing for JSON
437 // nothing for JSON 437 }
438 } 438
439 439 // End # private functions ----------------------------------------------
440 // End # private functions ----------------------------------------------
441 } \ No newline at end of file 440 } \ No newline at end of file
diff --git a/inc/poche/Database.class.php b/inc/poche/Database.class.php
index 6244df88..036c9d1b 100755
--- a/inc/poche/Database.class.php
+++ b/inc/poche/Database.class.php
@@ -77,7 +77,7 @@ class Database {
77 } 77 }
78 else { 78 else {
79 $sql = ' 79 $sql = '
80 CREATE TABLE tags ( 80 CREATE TABLE IF NOT EXISTS tags (
81 id bigserial primary key, 81 id bigserial primary key,
82 value varchar(255) NOT NULL 82 value varchar(255) NOT NULL
83 ); 83 );
@@ -110,7 +110,7 @@ class Database {
110 } 110 }
111 else { 111 else {
112 $sql = ' 112 $sql = '
113 CREATE TABLE tags_entries ( 113 CREATE TABLE IF NOT EXISTS tags_entries (
114 id bigserial primary key, 114 id bigserial primary key,
115 entry_id integer NOT NULL, 115 entry_id integer NOT NULL,
116 tag_id integer NOT NULL 116 tag_id integer NOT NULL
@@ -245,7 +245,7 @@ class Database {
245 $sql_limit = "LIMIT ".$limit." OFFSET 0"; 245 $sql_limit = "LIMIT ".$limit." OFFSET 0";
246 } 246 }
247 247
248 $sql = "SELECT * FROM entries WHERE (content = '' OR content IS NULL) AND user_id=? ORDER BY id " . $sql_limit; 248 $sql = "SELECT * FROM entries WHERE (content = '' OR content IS NULL) AND title LIKE 'Untitled - Import%' AND user_id=? ORDER BY id " . $sql_limit;
249 $query = $this->executeQuery($sql, array($user_id)); 249 $query = $this->executeQuery($sql, array($user_id));
250 $entries = $query->fetchAll(); 250 $entries = $query->fetchAll();
251 251
@@ -253,7 +253,7 @@ class Database {
253 } 253 }
254 254
255 public function retrieveUnfetchedEntriesCount($user_id) { 255 public function retrieveUnfetchedEntriesCount($user_id) {
256 $sql = "SELECT count(*) FROM entries WHERE (content = '' OR content IS NULL) AND user_id=?"; 256 $sql = "SELECT count(*) FROM entries WHERE (content = '' OR content IS NULL) AND title LIKE 'Untitled - Import%' AND user_id=?";
257 $query = $this->executeQuery($sql, array($user_id)); 257 $query = $this->executeQuery($sql, array($user_id));
258 list($count) = $query->fetch(); 258 list($count) = $query->fetch();
259 259
@@ -374,7 +374,7 @@ class Database {
374 $id = null; 374 $id = null;
375 } 375 }
376 else { 376 else {
377 $id = intval($this->getLastId( (STORAGE == 'postgres') ? 'users_id_seq' : '' )); 377 $id = intval($this->getLastId( (STORAGE == 'postgres') ? 'entries_id_seq' : '') );
378 } 378 }
379 return $id; 379 return $id;
380 } 380 }
@@ -407,7 +407,7 @@ class Database {
407 public function getLastId($column = '') { 407 public function getLastId($column = '') {
408 return $this->getHandle()->lastInsertId($column); 408 return $this->getHandle()->lastInsertId($column);
409 } 409 }
410 410
411 public function search($term, $user_id, $limit = '') { 411 public function search($term, $user_id, $limit = '') {
412 $search = '%'.$term.'%'; 412 $search = '%'.$term.'%';
413 $sql_action = "SELECT * FROM entries WHERE user_id=? AND (content LIKE ? OR title LIKE ? OR url LIKE ?) "; //searches in content, title and URL 413 $sql_action = "SELECT * FROM entries WHERE user_id=? AND (content LIKE ? OR title LIKE ? OR url LIKE ?) "; //searches in content, title and URL
diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php
index a662f695..811895dc 100755
--- a/inc/poche/Poche.class.php
+++ b/inc/poche/Poche.class.php
@@ -373,9 +373,7 @@ class Poche
373 $body = $content['rss']['channel']['item']['description']; 373 $body = $content['rss']['channel']['item']['description'];
374 374
375 // clean content from prevent xss attack 375 // clean content from prevent xss attack
376 $config = HTMLPurifier_Config::createDefault(); 376 $purifier = $this->getPurifier();
377 $config->set('Cache.SerializerPath', CACHE);
378 $purifier = new HTMLPurifier($config);
379 $title = $purifier->purify($title); 377 $title = $purifier->purify($title);
380 $body = $purifier->purify($body); 378 $body = $purifier->purify($body);
381 379
@@ -828,10 +826,12 @@ class Poche
828 define('IMPORT_LIMIT', 5); 826 define('IMPORT_LIMIT', 5);
829 } 827 }
830 if (!defined('IMPORT_DELAY')) { 828 if (!defined('IMPORT_DELAY')) {
831 define('IMPORT_DELAY', 5); 829 define('IMPORT_DELAY', 5);
832 } 830 }
833 831
834 if ( isset($_FILES['file']) ) { 832 if ( isset($_FILES['file']) ) {
833 Tools::logm('Import stated: parsing file');
834
835 // assume, that file is in json format 835 // assume, that file is in json format
836 $str_data = file_get_contents($_FILES['file']['tmp_name']); 836 $str_data = file_get_contents($_FILES['file']['tmp_name']);
837 $data = json_decode($str_data, true); 837 $data = json_decode($str_data, true);
@@ -844,18 +844,18 @@ class Poche
844 $read = 0; 844 $read = 0;
845 foreach (array('ol','ul') as $list) { 845 foreach (array('ol','ul') as $list) {
846 foreach ($html->find($list) as $ul) { 846 foreach ($html->find($list) as $ul) {
847 foreach ($ul->find('li') as $li) { 847 foreach ($ul->find('li') as $li) {
848 $tmpEntry = array(); 848 $tmpEntry = array();
849 $a = $li->find('a'); 849 $a = $li->find('a');
850 $tmpEntry['url'] = $a[0]->href; 850 $tmpEntry['url'] = $a[0]->href;
851 $tmpEntry['tags'] = $a[0]->tags; 851 $tmpEntry['tags'] = $a[0]->tags;
852 $tmpEntry['is_read'] = $read; 852 $tmpEntry['is_read'] = $read;
853 if ($tmpEntry['url']) { 853 if ($tmpEntry['url']) {
854 $data[] = $tmpEntry; 854 $data[] = $tmpEntry;
855 } 855 }
856 } 856 }
857 # the second <ol/ul> is for read links 857 # the second <ol/ul> is for read links
858 $read = ((sizeof($data) && $read)?0:1); 858 $read = ((sizeof($data) && $read)?0:1);
859 } 859 }
860 } 860 }
861 } 861 }
@@ -866,16 +866,16 @@ class Poche
866 $data[] = $record; 866 $data[] = $record;
867 foreach ($record as $record2) { 867 foreach ($record as $record2) {
868 if (is_array($record2)) { 868 if (is_array($record2)) {
869 $data[] = $record2; 869 $data[] = $record2;
870 } 870 }
871 } 871 }
872 } 872 }
873 } 873 }
874 874
875 $i = 0; //counter for articles inserted 875 $urlsInserted = array(); //urls of articles inserted
876 foreach ($data as $record) { 876 foreach ($data as $record) {
877 $url = trim( isset($record['article__url']) ? $record['article__url'] : (isset($record['url']) ? $record['url'] : '') ); 877 $url = trim( isset($record['article__url']) ? $record['article__url'] : (isset($record['url']) ? $record['url'] : '') );
878 if ( $url ) { 878 if ( $url and !in_array($url, $urlsInserted) ) {
879 $title = (isset($record['title']) ? $record['title'] : _('Untitled - Import - ').'</a> <a href="./?import">'._('click to finish import').'</a><a>'); 879 $title = (isset($record['title']) ? $record['title'] : _('Untitled - Import - ').'</a> <a href="./?import">'._('click to finish import').'</a><a>');
880 $body = (isset($record['content']) ? $record['content'] : ''); 880 $body = (isset($record['content']) ? $record['content'] : '');
881 $isRead = (isset($record['is_read']) ? intval($record['is_read']) : (isset($record['archive'])?intval($record['archive']):0)); 881 $isRead = (isset($record['is_read']) ? intval($record['is_read']) : (isset($record['archive'])?intval($record['archive']):0));
@@ -883,19 +883,21 @@ class Poche
883 //insert new record 883 //insert new record
884 $id = $this->store->add($url, $title, $body, $this->user->getId(), $isFavorite, $isRead); 884 $id = $this->store->add($url, $title, $body, $this->user->getId(), $isFavorite, $isRead);
885 if ( $id ) { 885 if ( $id ) {
886 //increment no of records inserted 886 $urlsInserted[] = $url; //add
887 $i++; 887
888 if ( isset($record['tags']) && trim($record['tags']) ) { 888 if ( isset($record['tags']) && trim($record['tags']) ) {
889 //@TODO: set tags 889 //@TODO: set tags
890 890
891 } 891 }
892 } 892 }
893 } 893 }
894 } 894 }
895 895
896 $i = sizeof($urlsInserted);
896 if ( $i > 0 ) { 897 if ( $i > 0 ) {
897 $this->messages->add('s', _('Articles inserted: ').$i._('. Please note, that some may be marked as "read".')); 898 $this->messages->add('s', _('Articles inserted: ').$i._('. Please note, that some may be marked as "read".'));
898 } 899 }
900 Tools::logm('Import of articles finished: '.$i.' articles added (w/o content if not provided).');
899 } 901 }
900 //file parsing finished here 902 //file parsing finished here
901 903
@@ -906,30 +908,32 @@ class Poche
906 if ( $recordsDownloadRequired == 0 ) { 908 if ( $recordsDownloadRequired == 0 ) {
907 //nothing to download 909 //nothing to download
908 $this->messages->add('s', _('Import finished.')); 910 $this->messages->add('s', _('Import finished.'));
911 Tools::logm('Import finished completely');
909 Tools::redirect(); 912 Tools::redirect();
910 } 913 }
911 else { 914 else {
912 //if just inserted - don't download anything, download will start in next reload 915 //if just inserted - don't download anything, download will start in next reload
913 if ( !isset($_FILES['file']) ) { 916 if ( !isset($_FILES['file']) ) {
914 //download next batch 917 //download next batch
918 Tools::logm('Fetching next batch of articles...');
915 $items = $this->store->retrieveUnfetchedEntries($this->user->getId(), IMPORT_LIMIT); 919 $items = $this->store->retrieveUnfetchedEntries($this->user->getId(), IMPORT_LIMIT);
916 920
917 $config = HTMLPurifier_Config::createDefault(); 921 $purifier = $this->getPurifier();
918 $config->set('Cache.SerializerPath', CACHE);
919 $purifier = new HTMLPurifier($config);
920 922
921 foreach ($items as $item) { 923 foreach ($items as $item) {
922 $url = new Url(base64_encode($item['url'])); 924 $url = new Url(base64_encode($item['url']));
923 $content = Tools::getPageContent($url); 925 Tools::logm('Fetching article '.$item['id']);
926 $content = Tools::getPageContent($url);
924 927
925 $title = (($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled')); 928 $title = (($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled'));
926 $body = (($content['rss']['channel']['item']['description'] != '') ? $content['rss']['channel']['item']['description'] : _('Undefined')); 929 $body = (($content['rss']['channel']['item']['description'] != '') ? $content['rss']['channel']['item']['description'] : _('Undefined'));
927 930
928 //clean content to prevent xss attack 931 //clean content to prevent xss attack
929 $title = $purifier->purify($title); 932 $title = $purifier->purify($title);
930 $body = $purifier->purify($body); 933 $body = $purifier->purify($body);
931 934
932 $this->store->updateContentAndTitle($item['id'], $title, $body, $this->user->getId()); 935 $this->store->updateContentAndTitle($item['id'], $title, $body, $this->user->getId());
936 Tools::logm('Article '.$item['id'].' updated.');
933 } 937 }
934 938
935 } 939 }
@@ -942,16 +946,15 @@ class Poche
942 * export poche entries in json 946 * export poche entries in json
943 * @return json all poche entries 947 * @return json all poche entries
944 */ 948 */
945 public function export() 949 public function export() {
946 { 950 $filename = "wallabag-export-".$this->user->getId()."-".date("Y-m-d").".json";
947 $filename = "wallabag-export-".$this->user->getId()."-".date("Y-m-d").".json"; 951 header('Content-Disposition: attachment; filename='.$filename);
948 header('Content-Disposition: attachment; filename='.$filename); 952
949 953 $entries = $this->store->retrieveAll($this->user->getId());
950 $entries = $this->store->retrieveAll($this->user->getId()); 954 echo $this->tpl->render('export.twig', array(
951 echo $this->tpl->render('export.twig', array( 955 'export' => Tools::renderJson($entries),
952 'export' => Tools::renderJson($entries), 956 ));
953 )); 957 Tools::logm('export view');
954 Tools::logm('export view');
955 } 958 }
956 959
957 /** 960 /**
@@ -959,43 +962,42 @@ class Poche
959 * @param string $which 'prod' or 'dev' 962 * @param string $which 'prod' or 'dev'
960 * @return string latest $which version 963 * @return string latest $which version
961 */ 964 */
962 private function getPocheVersion($which = 'prod') 965 private function getPocheVersion($which = 'prod') {
963 { 966 $cache_file = CACHE . '/' . $which;
964 $cache_file = CACHE . '/' . $which; 967 $check_time = time();
965 $check_time = time(); 968
966 969 # checks if the cached version file exists
967 # checks if the cached version file exists 970 if (file_exists($cache_file) && (filemtime($cache_file) > (time() - 86400 ))) {
968 if (file_exists($cache_file) && (filemtime($cache_file) > (time() - 86400 ))) { 971 $version = file_get_contents($cache_file);
969 $version = file_get_contents($cache_file); 972 $check_time = filemtime($cache_file);
970 $check_time = filemtime($cache_file); 973 } else {
971 } else { 974 $version = file_get_contents('http://static.wallabag.org/versions/' . $which);
972 $version = file_get_contents('http://static.wallabag.org/versions/' . $which); 975 file_put_contents($cache_file, $version, LOCK_EX);
973 file_put_contents($cache_file, $version, LOCK_EX); 976 }
974 } 977 return array($version, $check_time);
975 return array($version, $check_time);
976 } 978 }
977 979
978 public function generateToken() 980 public function generateToken()
979 { 981 {
980 if (ini_get('open_basedir') === '') { 982 if (ini_get('open_basedir') === '') {
981 if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { 983 if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
982 echo 'This is a server using Windows!'; 984 echo 'This is a server using Windows!';
983 // alternative to /dev/urandom for Windows 985 // alternative to /dev/urandom for Windows
984 $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20); 986 $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
985 } else { 987 } else {
986 $token = substr(base64_encode(file_get_contents('/dev/urandom', false, null, 0, 20)), 0, 15); 988 $token = substr(base64_encode(file_get_contents('/dev/urandom', false, null, 0, 20)), 0, 15);
987 }
988 }
989 else {
990 $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
991 } 989 }
990 }
991 else {
992 $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
993 }
992 994
993 $token = str_replace('+', '', $token); 995 $token = str_replace('+', '', $token);
994 $this->store->updateUserConfig($this->user->getId(), 'token', $token); 996 $this->store->updateUserConfig($this->user->getId(), 'token', $token);
995 $currentConfig = $_SESSION['poche_user']->config; 997 $currentConfig = $_SESSION['poche_user']->config;
996 $currentConfig['token'] = $token; 998 $currentConfig['token'] = $token;
997 $_SESSION['poche_user']->setConfig($currentConfig); 999 $_SESSION['poche_user']->setConfig($currentConfig);
998 Tools::redirect(); 1000 Tools::redirect();
999 } 1001 }
1000 1002
1001 public function generateFeeds($token, $user_id, $tag_id, $type = 'home') 1003 public function generateFeeds($token, $user_id, $tag_id, $type = 'home')
@@ -1031,6 +1033,7 @@ class Poche
1031 foreach ($entries as $entry) { 1033 foreach ($entries as $entry) {
1032 $newItem = $feed->createNewItem(); 1034 $newItem = $feed->createNewItem();
1033 $newItem->setTitle($entry['title']); 1035 $newItem->setTitle($entry['title']);
1036 $newItem->setSource(Tools::getPocheUrl() . '?view=view&amp;id=' . $entry['id']);
1034 $newItem->setLink($entry['url']); 1037 $newItem->setLink($entry['url']);
1035 $newItem->setDate(time()); 1038 $newItem->setDate(time());
1036 $newItem->setDescription($entry['content']); 1039 $newItem->setDescription($entry['content']);
@@ -1057,4 +1060,16 @@ class Poche
1057 $this->messages->add('s', _('Cache deleted.')); 1060 $this->messages->add('s', _('Cache deleted.'));
1058 Tools::redirect(); 1061 Tools::redirect();
1059 } 1062 }
1063
1064 /**
1065 * return new purifier object with actual config
1066 */
1067 protected function getPurifier() {
1068 $config = HTMLPurifier_Config::createDefault();
1069 $config->set('Cache.SerializerPath', CACHE);
1070 $config->set('HTML.SafeIframe', true);
1071 $config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%'); //allow YouTube and Vimeo$purifier = new HTMLPurifier($config);
1072
1073 return new HTMLPurifier($config);
1074 }
1060} 1075}
diff --git a/inc/poche/Tools.class.php b/inc/poche/Tools.class.php
index a130e94b..7f064020 100755
--- a/inc/poche/Tools.class.php
+++ b/inc/poche/Tools.class.php
@@ -59,8 +59,10 @@ class Tools
59 return $scriptname; 59 return $scriptname;
60 } 60 }
61 61
62 $host = (isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']));
63
62 return 'http' . ($https ? 's' : '') . '://' 64 return 'http' . ($https ? 's' : '') . '://'
63 . $_SERVER["HTTP_HOST"] . $serverport . $scriptname; 65 . $host . $serverport . $scriptname;
64 } 66 }
65 67
66 public static function redirect($url = '') 68 public static function redirect($url = '')
diff --git a/index.php b/index.php
index 7f72b146..deb13d7a 100755
--- a/index.php
+++ b/index.php
@@ -8,7 +8,7 @@
8 * @license http://www.wtfpl.net/ see COPYING file 8 * @license http://www.wtfpl.net/ see COPYING file
9 */ 9 */
10 10
11define ('POCHE', '1.6.0'); 11define ('POCHE', '1.6.1');
12require 'check_setup.php'; 12require 'check_setup.php';
13require_once 'inc/poche/global.inc.php'; 13require_once 'inc/poche/global.inc.php';
14 14
diff --git a/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mo b/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mo
index 600b3281..7bcde861 100644..100755
--- a/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mo
+++ b/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mo
Binary files differ
diff --git a/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po b/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po
index 5053e9e3..bd8dd9b8 100644..100755
--- a/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po
+++ b/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po
@@ -1,26 +1,25 @@
1msgid "" 1msgid ""
2msgstr "" 2msgstr ""
3"Project-Id-Version: \n" 3"Project-Id-Version: wallabag 1.6.0\n"
4"Report-Msgid-Bugs-To: \n" 4"Report-Msgid-Bugs-To: \n"
5"POT-Creation-Date: 2014-02-25 18:33+0300\n" 5"POT-Creation-Date: 2014-02-25 18:33+0300\n"
6"PO-Revision-Date: \n" 6"PO-Revision-Date: \n"
7"Last-Translator: Maryana <mariroz@mr.lviv.ua>\n" 7"Last-Translator: Gilles WITTEZAELE <gilles.wittezaele@laposte.net>\n"
8"Language-Team: \n" 8"Language-Team: \n"
9"Language: \n"
10"MIME-Version: 1.0\n" 9"MIME-Version: 1.0\n"
11"Content-Type: text/plain; charset=UTF-8\n" 10"Content-Type: text/plain; charset=UTF-8\n"
12"Content-Transfer-Encoding: 8bit\n" 11"Content-Transfer-Encoding: 8bit\n"
13"X-Poedit-KeywordsList: _;gettext;gettext_noop\n" 12"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
14"X-Poedit-Basepath: .\n" 13"X-Poedit-SourceCharset: UTF-8\n"
15"X-Poedit-SourceCharset: utf-8\n" 14"X-Generator: Poedit 1.6.4\n"
16"X-Generator: Poedit 1.5.7\n" 15"Plural-Forms: nplurals=2; plural=(n > 1);\n"
17"X-Poedit-SearchPath-0: /home/mariroz/_DEV/web/wallabag/wallabag-master-testing\n" 16"Language: fr_FR\n"
18 17
19msgid "wallabag, a read it later open source system" 18msgid "wallabag, a read it later open source system"
20msgstr "wallabag, un système open source de lecture différé" 19msgstr "wallabag, un système open source de lecture différé"
21 20
22msgid "login failed: user doesn't exist" 21msgid "login failed: user doesn't exist"
23msgstr "identification échouée : l'utilisateur n'existe pas" 22msgstr "échec de l'identification : cet utilisateur n'existe pas"
24 23
25msgid "return home" 24msgid "return home"
26msgstr "retour à l'accueil" 25msgstr "retour à l'accueil"
@@ -32,13 +31,13 @@ msgid "Saving articles"
32msgstr "Sauvegarde des articles" 31msgstr "Sauvegarde des articles"
33 32
34msgid "There are several ways to save an article:" 33msgid "There are several ways to save an article:"
35msgstr "Il y a plusieurs façons de sauver un article :" 34msgstr "Il y a plusieurs façons d'enregistrer un article :"
36 35
37msgid "read the documentation" 36msgid "read the documentation"
38msgstr "lisez la documentation" 37msgstr "lisez la documentation"
39 38
40msgid "download the extension" 39msgid "download the extension"
41msgstr "télécharger l'extension" 40msgstr "téléchargez l'extension"
42 41
43msgid "via F-Droid" 42msgid "via F-Droid"
44msgstr "via F-Droid" 43msgstr "via F-Droid"
@@ -50,7 +49,7 @@ msgid "via Google Play"
50msgstr "via Google PlayStore" 49msgstr "via Google PlayStore"
51 50
52msgid "download the application" 51msgid "download the application"
53msgstr "télécharger l'application" 52msgstr "téléchargez l'application"
54 53
55msgid "By filling this field" 54msgid "By filling this field"
56msgstr "En remplissant ce champ" 55msgstr "En remplissant ce champ"
@@ -85,8 +84,13 @@ msgstr "Une version de développement plus récente est disponible."
85msgid "Feeds" 84msgid "Feeds"
86msgstr "Flux" 85msgstr "Flux"
87 86
88msgid "Your feed token is currently empty and must first be generated to enable feeds. Click <a href='?feed&amp;action=generate'>here to generate it</a>." 87msgid ""
89msgstr "Votre jeton de flux est actuellement vide doit d'abord être généré pour activer les flux. Cliquez <a href='?feed&amp;action=generate'>ici</a> pour le générer." 88"Your feed token is currently empty and must first be generated to enable "
89"feeds. Click <a href='?feed&amp;action=generate'>here to generate it</a>."
90msgstr ""
91"Votre jeton de flux est actuellement vide et doit d'abord être généré pour "
92"activer les flux. Cliquez <a href='?feed&amp;action=generate'>ici</a> pour "
93"le générer."
90 94
91msgid "Unread feed" 95msgid "Unread feed"
92msgstr "Flux des non lus" 96msgstr "Flux des non lus"
@@ -103,8 +107,12 @@ msgstr "Votre jeton :"
103msgid "Your user id:" 107msgid "Your user id:"
104msgstr "Votre ID utilisateur :" 108msgstr "Votre ID utilisateur :"
105 109
106msgid "You can regenerate your token: <a href='?feed&amp;action=generate'>generate!</a>." 110msgid ""
107msgstr "Vous pouvez regénérer votre jeton : <a href='?feed&amp;action=generate'>génération !</a>." 111"You can regenerate your token: <a href='?feed&amp;action=generate'>generate!"
112"</a>."
113msgstr ""
114"Vous pouvez regénérer votre jeton : <a href='?feed&amp;"
115"action=generate'>génération !</a>."
108 116
109msgid "Change your theme" 117msgid "Change your theme"
110msgstr "Changer votre thème" 118msgstr "Changer votre thème"
@@ -136,8 +144,11 @@ msgstr "Répétez votre nouveau mot de passe :"
136msgid "Import" 144msgid "Import"
137msgstr "Importer" 145msgstr "Importer"
138 146
139msgid "Please execute the import script locally as it can take a very long time." 147msgid ""
140msgstr "Merci d'exécuter l'import en local car cela peut prendre du temps." 148"Please execute the import script locally as it can take a very long time."
149msgstr ""
150"Merci d'exécuter le script d'importation en local car cela peut prendre du "
151"temps."
141 152
142msgid "More info in the official documentation:" 153msgid "More info in the official documentation:"
143msgstr "Plus d'infos dans la documentation officielle :" 154msgstr "Plus d'infos dans la documentation officielle :"
@@ -150,13 +161,13 @@ msgid "(you must have a %s file on your server)"
150msgstr "(le fichier %s doit être présent sur le serveur)" 161msgstr "(le fichier %s doit être présent sur le serveur)"
151 162
152msgid "Import from Readability" 163msgid "Import from Readability"
153msgstr "Import depuis Readability" 164msgstr "Importer depuis Readability"
154 165
155msgid "Import from Instapaper" 166msgid "Import from Instapaper"
156msgstr "Import depuis Instapaper" 167msgstr "Importer depuis Instapaper"
157 168
158msgid "Import from wallabag" 169msgid "Import from wallabag"
159msgstr "Import depuis wallabag" 170msgstr "Importer depuis wallabag"
160 171
161msgid "Export your wallabag data" 172msgid "Export your wallabag data"
162msgstr "Exporter vos données de wallabag" 173msgstr "Exporter vos données de wallabag"
@@ -185,8 +196,12 @@ msgstr "retourner à l'article"
185msgid "plop" 196msgid "plop"
186msgstr "plop" 197msgstr "plop"
187 198
188msgid "You can <a href='wallabag_compatibility_test.php'>check your configuration here</a>." 199msgid ""
189msgstr "Vous pouvez vérifier votre configuration <a href='wallabag_compatibility_test.php'>ici</a>." 200"You can <a href='wallabag_compatibility_test.php'>check your configuration "
201"here</a>."
202msgstr ""
203"Vous pouvez vérifier votre configuration <a "
204"href='wallabag_compatibility_test.php'>ici</a>."
190 205
191msgid "favoris" 206msgid "favoris"
192msgstr "favoris" 207msgstr "favoris"
@@ -248,8 +263,14 @@ msgstr "installation"
248msgid "install your wallabag" 263msgid "install your wallabag"
249msgstr "installez votre wallabag" 264msgstr "installez votre wallabag"
250 265
251msgid "wallabag is still not installed. Please fill the below form to install it. Don't hesitate to <a href='http://doc.wallabag.org/'>read the documentation on wallabag website</a>." 266msgid ""
252msgstr "wallabag n'est pas encore installé. Merci de remplir le formulaire suivant pour l'installer. N'hésitez pas à <a href='http://doc.wallabag.org'>lire la documentation sur le site de wallabag</a>." 267"wallabag is still not installed. Please fill the below form to install it. "
268"Don't hesitate to <a href='http://doc.wallabag.org/'>read the documentation "
269"on wallabag website</a>."
270msgstr ""
271"wallabag n'est pas encore installé. Merci de remplir le formulaire suivant "
272"pour l'installer. N'hésitez pas à <a href='http://doc.wallabag.org'>lire la "
273"documentation sur le site de wallabag</a>."
253 274
254msgid "Login" 275msgid "Login"
255msgstr "Nom d'utilisateur" 276msgstr "Nom d'utilisateur"
@@ -267,7 +288,8 @@ msgid "Login to wallabag"
267msgstr "Se connecter à wallabag" 288msgstr "Se connecter à wallabag"
268 289
269msgid "you are in demo mode, some features may be disabled." 290msgid "you are in demo mode, some features may be disabled."
270msgstr "vous êtes en mode démo, certaines fonctionnalités peuvent être désactivées." 291msgstr ""
292"vous êtes en mode démo, certaines fonctionnalités peuvent être désactivées."
271 293
272msgid "Username" 294msgid "Username"
273msgstr "Nom d'utilisateur" 295msgstr "Nom d'utilisateur"
@@ -318,10 +340,10 @@ msgid "tags:"
318msgstr "tags :" 340msgstr "tags :"
319 341
320msgid "Edit tags" 342msgid "Edit tags"
321msgstr "Editer les tags" 343msgstr "Modifier les tags"
322 344
323msgid "save link!" 345msgid "save link!"
324msgstr "sauver le lien !" 346msgstr "enregistrer le lien !"
325 347
326msgid "powered by" 348msgid "powered by"
327msgstr "propulsé par" 349msgstr "propulsé par"
@@ -360,7 +382,7 @@ msgid "tweet"
360msgstr "tweet" 382msgstr "tweet"
361 383
362msgid "email" 384msgid "email"
363msgstr "ee-mail" 385msgstr "e-mail"
364 386
365msgid "this article appears wrong?" 387msgid "this article appears wrong?"
366msgstr "cet article s'affiche mal ?" 388msgstr "cet article s'affiche mal ?"
@@ -369,7 +391,7 @@ msgid "No link available here!"
369msgstr "Aucun lien n'est disponible ici !" 391msgstr "Aucun lien n'est disponible ici !"
370 392
371msgid "Poching a link" 393msgid "Poching a link"
372msgstr "Sauver un lien" 394msgstr "Enregistrer un lien"
373 395
374msgid "by filling this field" 396msgid "by filling this field"
375msgstr "en remplissant ce champ" 397msgstr "en remplissant ce champ"
@@ -396,19 +418,21 @@ msgid "a more recent development version is available."
396msgstr "une version de développement plus récente est disponible." 418msgstr "une version de développement plus récente est disponible."
397 419
398msgid "Please execute the import script locally, it can take a very long time." 420msgid "Please execute the import script locally, it can take a very long time."
399msgstr "Merci d'exécuter l'import en local car cela peut prendre du temps." 421msgstr ""
422"Merci d'exécuter le script d'importation en local car cela peut prendre du "
423"temps."
400 424
401msgid "More infos in the official doc:" 425msgid "More infos in the official doc:"
402msgstr "Plus d'infos dans la documentation officielle :" 426msgstr "Plus d'infos dans la documentation officielle :"
403 427
404msgid "import from Pocket" 428msgid "import from Pocket"
405msgstr "import depuis Pocket" 429msgstr "importation depuis Pocket"
406 430
407msgid "import from Readability" 431msgid "import from Readability"
408msgstr "import depuis Readability" 432msgstr "importation depuis Readability"
409 433
410msgid "import from Instapaper" 434msgid "import from Instapaper"
411msgstr "import depuis Instapaper" 435msgstr "importation depuis Instapaper"
412 436
413msgid "estimated reading time :" 437msgid "estimated reading time :"
414msgstr "temps de lecture estimé :" 438msgstr "temps de lecture estimé :"
@@ -449,8 +473,12 @@ msgstr "en mode démo, vous ne pouvez pas mettre à jour le mot de passe"
449msgid "your password has been updated" 473msgid "your password has been updated"
450msgstr "votre mot de passe a été mis à jour" 474msgstr "votre mot de passe a été mis à jour"
451 475
452msgid "the two fields have to be filled & the password must be the same in the two fields" 476msgid ""
453msgstr "les deux champs doivent être remplis & le mot de passe doit être le même dans les deux" 477"the two fields have to be filled & the password must be the same in the two "
478"fields"
479msgstr ""
480"les deux champs doivent être remplis & le mot de passe doit être le même "
481"dans les deux"
454 482
455msgid "still using the \"" 483msgid "still using the \""
456msgstr "utilise encore \"" 484msgstr "utilise encore \""
@@ -459,7 +487,7 @@ msgid "that theme does not seem to be installed"
459msgstr "ce thème ne semble pas installé" 487msgstr "ce thème ne semble pas installé"
460 488
461msgid "you have changed your theme preferences" 489msgid "you have changed your theme preferences"
462msgstr "vous avez changez vos préférences de thème" 490msgstr "vous avez changé vos préférences de thème"
463 491
464msgid "that language does not seem to be installed" 492msgid "that language does not seem to be installed"
465msgstr "cette langue ne semble pas être installée" 493msgstr "cette langue ne semble pas être installée"
@@ -468,28 +496,28 @@ msgid "you have changed your language preferences"
468msgstr "vous avez changé vos préférences de langue" 496msgstr "vous avez changé vos préférences de langue"
469 497
470msgid "login failed: you have to fill all fields" 498msgid "login failed: you have to fill all fields"
471msgstr "identification échouée : vous devez remplir tous les champs" 499msgstr "échec de l'identification : vous devez remplir tous les champs"
472 500
473msgid "welcome to your wallabag" 501msgid "welcome to your wallabag"
474msgstr "bienvenue dans votre wallabag" 502msgstr "bienvenue dans votre wallabag"
475 503
476msgid "login failed: bad login or password" 504msgid "login failed: bad login or password"
477msgstr "identification échouée : mauvais identifiant ou mot de passe" 505msgstr "échec de l'identification : mauvais identifiant ou mot de passe"
478 506
479msgid "import from instapaper completed" 507msgid "import from instapaper completed"
480msgstr "Import depuis Instapaper complété" 508msgstr "Importation depuis Instapaper complété"
481 509
482msgid "import from pocket completed" 510msgid "import from pocket completed"
483msgstr "Import depuis Pocket complété" 511msgstr "Importation depuis Pocket complété"
484 512
485msgid "import from Readability completed. " 513msgid "import from Readability completed. "
486msgstr "Import depuis Readability complété" 514msgstr "Importation depuis Readability complété"
487 515
488msgid "import from Poche completed. " 516msgid "import from Poche completed. "
489msgstr "Import depuis Pocket complété" 517msgstr "Importation depuis Pocket complété"
490 518
491msgid "Unknown import provider." 519msgid "Unknown import provider."
492msgstr "Fournisseur d'import inconnu." 520msgstr "Format d'importation inconnu."
493 521
494msgid "Incomplete inc/poche/define.inc.php file, please define \"" 522msgid "Incomplete inc/poche/define.inc.php file, please define \""
495msgstr "Fichier inc/poche/define.inc.php incomplet, merci de définir \"" 523msgstr "Fichier inc/poche/define.inc.php incomplet, merci de définir \""
@@ -498,7 +526,7 @@ msgid "Could not find required \""
498msgstr "Ne peut pas trouver \"" 526msgstr "Ne peut pas trouver \""
499 527
500msgid "Uh, there is a problem while generating feeds." 528msgid "Uh, there is a problem while generating feeds."
501msgstr "Ih, il y a un problème lors de la génération des flux." 529msgstr "Hum, il y a un problème lors de la génération des flux."
502 530
503msgid "Cache deleted." 531msgid "Cache deleted."
504msgstr "Cache effacé." 532msgstr "Cache effacé."
diff --git a/themes/baggy/_head.twig b/themes/baggy/_head.twig
index 04898d85..be11673f 100755
--- a/themes/baggy/_head.twig
+++ b/themes/baggy/_head.twig
@@ -12,4 +12,5 @@
12 <script src="{{ poche_url }}themes/{{theme}}/js/jquery.cookie.js"></script> 12 <script src="{{ poche_url }}themes/{{theme}}/js/jquery.cookie.js"></script>
13 <script src="{{ poche_url }}themes/{{theme}}/js/init.js"></script> 13 <script src="{{ poche_url }}themes/{{theme}}/js/init.js"></script>
14 <script src="{{ poche_url }}themes/default/js/saveLink.js"></script> 14 <script src="{{ poche_url }}themes/default/js/saveLink.js"></script>
15 <script src="{{ poche_url }}themes/default/js/popupForm.js"></script>
15 <script src="{{ poche_url }}themes/{{theme}}/js/closeMessage.js"></script> 16 <script src="{{ poche_url }}themes/{{theme}}/js/closeMessage.js"></script>
diff --git a/themes/baggy/_search-form.twig b/themes/baggy/_search-form.twig
index 1fd4154e..b8ac3bfa 100644
--- a/themes/baggy/_search-form.twig
+++ b/themes/baggy/_search-form.twig
@@ -1,21 +1,7 @@
1<div id="search-form" class="messages info"> 1<div id="search-form" class="messages info">
2<form method="get" action="index.php"> 2<form method="get" action="index.php">
3 <input type="hidden" name="view" value="search"></input> 3 <input type="hidden" name="view" value="search"></input>
4 <label><a href="javascript: void(null);" id="search-form-close">X</a>{% trans "Search" %}</label> : <input type="text" name="search" /> 4 <label><a href="javascript: void(null);" id="search-form-close">X</a>{% trans "Search" %}</label> : <input type="text" name="search" />
5 <input id="submit-search" type="submit" value="{% trans "Search" %} !"></input> 5 <input id="submit-search" type="submit" value="{% trans "Search" %} !"></input>
6</form> 6</form>
7</div> 7</div> \ No newline at end of file
8<script type="text/javascript">
9 $(document).ready(function() {
10
11 $("#search-form").hide();
12
13 $("#search").click(function(){
14 $("#search-form").toggle();
15 $("#search").toggleClass("current");
16 $("#search-arrow").toggleClass("arrow-down");
17 });
18
19
20 });
21</script> \ No newline at end of file
diff --git a/themes/baggy/css/main.css b/themes/baggy/css/main.css
index 0dd552de..0991dbed 100755
--- a/themes/baggy/css/main.css
+++ b/themes/baggy/css/main.css
@@ -352,10 +352,10 @@ footer a {
352 letter-spacing:normal; 352 letter-spacing:normal;
353 box-shadow: 0 3px 7px rgba(0,0,0,0.3); 353 box-shadow: 0 3px 7px rgba(0,0,0,0.3);
354 display: inline-block; 354 display: inline-block;
355 width: 32%!important; 355 width: 32%;
356 margin-bottom: 1.5em; 356 margin-bottom: 1.5em;
357 vertical-align: top; 357 vertical-align: top;
358 margin-left: 1.5%!important; 358 margin-left: 1.5%;
359 position: relative; 359 position: relative;
360 overflow: hidden; 360 overflow: hidden;
361 padding: 1.5em 1.5em 3em 1.5em; 361 padding: 1.5em 1.5em 3em 1.5em;
@@ -492,7 +492,7 @@ footer a {
492 } 492 }
493 493
494.entrie:nth-child(3n+1) { 494.entrie:nth-child(3n+1) {
495 margin-left: 0!important; 495 margin-left: 0;
496} 496}
497 497
498.results { 498.results {
@@ -540,7 +540,7 @@ footer a {
540 2.1 = "save a link" popup div related styles 540 2.1 = "save a link" popup div related styles
541 ========================================================================== */ 541 ========================================================================== */
542 542
543#bagit-form { 543#bagit-form, #search-form {
544 background: rgba(0,0,0,0.5); 544 background: rgba(0,0,0,0.5);
545 position: absolute; 545 position: absolute;
546 top: 0; 546 top: 0;
@@ -555,7 +555,7 @@ footer a {
555 border-left: 1px #EEE solid; 555 border-left: 1px #EEE solid;
556} 556}
557 557
558#bagit-form form { 558#bagit-form form, #search-form form {
559 background: #FFF; 559 background: #FFF;
560 position: absolute; 560 position: absolute;
561 top: 0; 561 top: 0;
@@ -568,7 +568,7 @@ footer a {
568 padding: 2em; 568 padding: 2em;
569} 569}
570 570
571a#bagit-form-close { 571a#bagit-form-close, a#search-form-close {
572 background: #000; 572 background: #000;
573 color: #FFF; 573 color: #FFF;
574 padding: 0.2em 0.5em; 574 padding: 0.2em 0.5em;
@@ -577,7 +577,7 @@ a#bagit-form-close {
577 float: right; 577 float: right;
578 font-size: 0.6em; 578 font-size: 0.6em;
579} 579}
580a#bagit-form-close:hover { 580a#bagit-form-close:hover, a#search-form-close:hover {
581 background: #999; 581 background: #999;
582 color: #000; 582 color: #000;
583} 583}
@@ -1028,7 +1028,7 @@ blockquote {
1028 display: none; 1028 display: none;
1029 } 1029 }
1030 1030
1031 #bagit-form { 1031 #bagit-form, #search-form {
1032 left: 0; 1032 left: 0;
1033 } 1033 }
1034} 1034}
diff --git a/themes/courgette/config.twig b/themes/courgette/config.twig
index 5c0aa4b1..6e1a9043 100755
--- a/themes/courgette/config.twig
+++ b/themes/courgette/config.twig
@@ -9,9 +9,11 @@
9 <h2>{% trans "Poching a link" %}</h2> 9 <h2>{% trans "Poching a link" %}</h2>
10 <p>{% trans "There are several ways to save an article:" %} (<a class="special" href="http://doc.wallabag.org" title="{% trans "read the documentation" %}">?</a>)</p> 10 <p>{% trans "There are several ways to save an article:" %} (<a class="special" href="http://doc.wallabag.org" title="{% trans "read the documentation" %}">?</a>)</p>
11 <ul> 11 <ul>
12 <li>firefox: <a href="https://bitbucket.org/jogaulupeau/poche/downloads/poche.xpi" title="download the firefox extension">{% trans "download the extension" %}</a></li> 12 <li>Firefox: <a href="https://addons.mozilla.org/firefox/addon/wallabag/" title="download the firefox extension">{% trans "download the extension" %}</a></li>
13 <li>chrome: <a href="https://bitbucket.org/jogaulupeau/poche/downloads/poche.crx" title="download the chrome extension">{% trans "download the extension" %}</a></li> 13 <li>Chrome: <a href="http://doc.wallabag.org/doku.php?id=users:chrome_extension" title="download the chrome extension">{% trans "download the extension" %}</a></li>
14 <li>android: <a href="https://bitbucket.org/jogaulupeau/poche/downloads/Poche.apk" title="download the application">{% trans "download the application" %}</a></li> 14 <li>Android: <a href="https://f-droid.org/app/fr.gaulupeau.apps.InThePoche" title="download the application">{% trans "via F-Droid" %}</a> {% trans " or " %} <a href="https://play.google.com/store/apps/details?id=fr.gaulupeau.apps.InThePoche" title="download the application">{% trans "via Google Play" %}</a></li>
15 <li>iOS: <a href="https://itunes.apple.com/app/wallabag/id828331015?mt=8" title="download the iOS application">{% trans "download the application" %}</a></li>
16 <li>Windows Phone: <a href="http://www.windowsphone.com/en-us/store/app/wallabag/ff890514-348c-4d0b-9b43-153fff3f7450" title="download the window phone application">{% trans "download the application" %}</a></li>
15 <li> 17 <li>
16 <form method="get" action="index.php"> 18 <form method="get" action="index.php">
17 <label class="addurl" for="plainurl">{% trans "by filling this field" %}:</label> 19 <label class="addurl" for="plainurl">{% trans "by filling this field" %}:</label>
@@ -79,4 +81,4 @@
79 <h2>{% trans "Export your wallabag data" %}</h2> 81 <h2>{% trans "Export your wallabag data" %}</h2>
80 <p><a href="./?export" target="_blank">{% trans "Click here" %}</a> {% trans "to export your wallabag data." %}</p> 82 <p><a href="./?export" target="_blank">{% trans "Click here" %}</a> {% trans "to export your wallabag data." %}</p>
81 </div> 83 </div>
82{% endblock %} \ No newline at end of file 84{% endblock %}
diff --git a/themes/default/_head.twig b/themes/default/_head.twig
index ffbfc22e..8c939e30 100755
--- a/themes/default/_head.twig
+++ b/themes/default/_head.twig
@@ -11,3 +11,4 @@
11 <script src="{{ poche_url }}themes/default/js/autoClose.js"></script> 11 <script src="{{ poche_url }}themes/default/js/autoClose.js"></script>
12 <script src="{{ poche_url }}themes/default/js/closeMessage.js"></script> 12 <script src="{{ poche_url }}themes/default/js/closeMessage.js"></script>
13 <script src="{{ poche_url }}themes/default/js/saveLink.js"></script> 13 <script src="{{ poche_url }}themes/default/js/saveLink.js"></script>
14 <script src="{{ poche_url }}themes/default/js/popupForm.js"></script> \ No newline at end of file
diff --git a/themes/default/js/popupForm.js b/themes/default/js/popupForm.js
new file mode 100644
index 00000000..06be3f0c
--- /dev/null
+++ b/themes/default/js/popupForm.js
@@ -0,0 +1,20 @@
1$(document).ready(function() {
2
3 $("#search-form").hide();
4
5 function closeSearch() {
6 $("#search-form").toggle();
7 $("#search").toggleClass("current");
8 $("#search-arrow").toggleClass("arrow-down");
9 }
10
11 $("#search").click(function(){
12 closeSearch();
13 });
14
15 $("#search-form-close").click(function(){
16 closeSearch();
17 });
18
19
20}); \ No newline at end of file
diff --git a/themes/default/js/saveLink.js b/themes/default/js/saveLink.js
index ccc00d1e..bee453c0 100755
--- a/themes/default/js/saveLink.js
+++ b/themes/default/js/saveLink.js
@@ -75,7 +75,7 @@ $.fn.ready(function() {
75 ========================================================================== */ 75 ========================================================================== */
76 76
77 $(window).keydown(function(e){ 77 $(window).keydown(function(e){
78 if ( ( e.target.tagName.toLowerCase() !== 'input' && e.keyCode == 83 ) || e.keyCode == 27 ) { 78 if ( ( e.target.tagName.toLowerCase() !== 'input' && e.keyCode == 83 ) || (e.keyCode == 27 && $bagitForm.is(':visible') ) ) {
79 $bagit.removeClass("current"); 79 $bagit.removeClass("current");
80 $("#bagit-arrow").removeClass("arrow-down"); 80 $("#bagit-arrow").removeClass("arrow-down");
81 toggleSaveLinkForm(); 81 toggleSaveLinkForm();