diff options
-rw-r--r-- | application/FeedBuilder.php | 6 | ||||
-rw-r--r-- | application/LinkFilter.php | 37 | ||||
-rw-r--r-- | application/NetscapeBookmarkUtils.php | 25 | ||||
-rw-r--r-- | application/Updater.php | 6 | ||||
-rw-r--r-- | index.php | 92 | ||||
-rw-r--r-- | plugins/isso/isso.php | 6 | ||||
-rw-r--r-- | tpl/daily.html | 4 | ||||
-rw-r--r-- | tpl/editlink.html | 3 | ||||
-rw-r--r-- | tpl/linklist.html | 6 |
9 files changed, 100 insertions, 85 deletions
diff --git a/application/FeedBuilder.php b/application/FeedBuilder.php index 4036a7cc..bfdf2fd3 100644 --- a/application/FeedBuilder.php +++ b/application/FeedBuilder.php | |||
@@ -143,7 +143,7 @@ class FeedBuilder | |||
143 | */ | 143 | */ |
144 | protected function buildItem($link, $pageaddr) | 144 | protected function buildItem($link, $pageaddr) |
145 | { | 145 | { |
146 | $link['guid'] = $pageaddr .'?'. smallHash($link['linkdate']); | 146 | $link['guid'] = $pageaddr .'?'. smallHash($link['created']->format('Ymd_His')); |
147 | // Check for both signs of a note: starting with ? and 7 chars long. | 147 | // Check for both signs of a note: starting with ? and 7 chars long. |
148 | if ($link['url'][0] === '?' && strlen($link['url']) === 7) { | 148 | if ($link['url'][0] === '?' && strlen($link['url']) === 7) { |
149 | $link['url'] = $pageaddr . $link['url']; | 149 | $link['url'] = $pageaddr . $link['url']; |
@@ -156,12 +156,12 @@ class FeedBuilder | |||
156 | $link['description'] = format_description($link['description'], '', $pageaddr); | 156 | $link['description'] = format_description($link['description'], '', $pageaddr); |
157 | $link['description'] .= PHP_EOL .'<br>— '. $permalink; | 157 | $link['description'] .= PHP_EOL .'<br>— '. $permalink; |
158 | 158 | ||
159 | $pubDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']); | 159 | $pubDate = $link['created']; |
160 | $link['pub_iso_date'] = $this->getIsoDate($pubDate); | 160 | $link['pub_iso_date'] = $this->getIsoDate($pubDate); |
161 | 161 | ||
162 | // atom:entry elements MUST contain exactly one atom:updated element. | 162 | // atom:entry elements MUST contain exactly one atom:updated element. |
163 | if (!empty($link['updated'])) { | 163 | if (!empty($link['updated'])) { |
164 | $upDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['updated']); | 164 | $upDate = $link['updated']; |
165 | $link['up_iso_date'] = $this->getIsoDate($upDate, DateTime::ATOM); | 165 | $link['up_iso_date'] = $this->getIsoDate($upDate, DateTime::ATOM); |
166 | } else { | 166 | } else { |
167 | $link['up_iso_date'] = $this->getIsoDate($pubDate, DateTime::ATOM);; | 167 | $link['up_iso_date'] = $this->getIsoDate($pubDate, DateTime::ATOM);; |
diff --git a/application/LinkFilter.php b/application/LinkFilter.php index d4fe28df..7bab46ba 100644 --- a/application/LinkFilter.php +++ b/application/LinkFilter.php | |||
@@ -33,12 +33,12 @@ class LinkFilter | |||
33 | public static $HASHTAG_CHARS = '\p{Pc}\p{N}\p{L}\p{Mn}'; | 33 | public static $HASHTAG_CHARS = '\p{Pc}\p{N}\p{L}\p{Mn}'; |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * @var array all available links. | 36 | * @var LinkDB all available links. |
37 | */ | 37 | */ |
38 | private $links; | 38 | private $links; |
39 | 39 | ||
40 | /** | 40 | /** |
41 | * @param array $links initialization. | 41 | * @param LinkDB $links initialization. |
42 | */ | 42 | */ |
43 | public function __construct($links) | 43 | public function __construct($links) |
44 | { | 44 | { |
@@ -94,18 +94,16 @@ class LinkFilter | |||
94 | private function noFilter($privateonly = false) | 94 | private function noFilter($privateonly = false) |
95 | { | 95 | { |
96 | if (! $privateonly) { | 96 | if (! $privateonly) { |
97 | krsort($this->links); | ||
98 | return $this->links; | 97 | return $this->links; |
99 | } | 98 | } |
100 | 99 | ||
101 | $out = array(); | 100 | $out = array(); |
102 | foreach ($this->links as $value) { | 101 | foreach ($this->links as $key => $value) { |
103 | if ($value['private']) { | 102 | if ($value['private']) { |
104 | $out[$value['linkdate']] = $value; | 103 | $out[$key] = $value; |
105 | } | 104 | } |
106 | } | 105 | } |
107 | 106 | ||
108 | krsort($out); | ||
109 | return $out; | 107 | return $out; |
110 | } | 108 | } |
111 | 109 | ||
@@ -121,10 +119,10 @@ class LinkFilter | |||
121 | private function filterSmallHash($smallHash) | 119 | private function filterSmallHash($smallHash) |
122 | { | 120 | { |
123 | $filtered = array(); | 121 | $filtered = array(); |
124 | foreach ($this->links as $l) { | 122 | foreach ($this->links as $key => $l) { |
125 | if ($smallHash == smallHash($l['linkdate'])) { | 123 | if ($smallHash == smallHash($l['created']->format('Ymd_His'))) { |
126 | // Yes, this is ugly and slow | 124 | // Yes, this is ugly and slow |
127 | $filtered[$l['linkdate']] = $l; | 125 | $filtered[$key] = $l; |
128 | return $filtered; | 126 | return $filtered; |
129 | } | 127 | } |
130 | } | 128 | } |
@@ -188,7 +186,7 @@ class LinkFilter | |||
188 | $keys = array('title', 'description', 'url', 'tags'); | 186 | $keys = array('title', 'description', 'url', 'tags'); |
189 | 187 | ||
190 | // Iterate over every stored link. | 188 | // Iterate over every stored link. |
191 | foreach ($this->links as $link) { | 189 | foreach ($this->links as $id => $link) { |
192 | 190 | ||
193 | // ignore non private links when 'privatonly' is on. | 191 | // ignore non private links when 'privatonly' is on. |
194 | if (! $link['private'] && $privateonly === true) { | 192 | if (! $link['private'] && $privateonly === true) { |
@@ -222,11 +220,10 @@ class LinkFilter | |||
222 | } | 220 | } |
223 | 221 | ||
224 | if ($found) { | 222 | if ($found) { |
225 | $filtered[$link['linkdate']] = $link; | 223 | $filtered[$id] = $link; |
226 | } | 224 | } |
227 | } | 225 | } |
228 | 226 | ||
229 | krsort($filtered); | ||
230 | return $filtered; | 227 | return $filtered; |
231 | } | 228 | } |
232 | 229 | ||
@@ -256,7 +253,7 @@ class LinkFilter | |||
256 | return $filtered; | 253 | return $filtered; |
257 | } | 254 | } |
258 | 255 | ||
259 | foreach ($this->links as $link) { | 256 | foreach ($this->links as $key => $link) { |
260 | // ignore non private links when 'privatonly' is on. | 257 | // ignore non private links when 'privatonly' is on. |
261 | if (! $link['private'] && $privateonly === true) { | 258 | if (! $link['private'] && $privateonly === true) { |
262 | continue; | 259 | continue; |
@@ -278,10 +275,9 @@ class LinkFilter | |||
278 | } | 275 | } |
279 | 276 | ||
280 | if ($found) { | 277 | if ($found) { |
281 | $filtered[$link['linkdate']] = $link; | 278 | $filtered[$key] = $link; |
282 | } | 279 | } |
283 | } | 280 | } |
284 | krsort($filtered); | ||
285 | return $filtered; | 281 | return $filtered; |
286 | } | 282 | } |
287 | 283 | ||
@@ -304,13 +300,14 @@ class LinkFilter | |||
304 | } | 300 | } |
305 | 301 | ||
306 | $filtered = array(); | 302 | $filtered = array(); |
307 | foreach ($this->links as $l) { | 303 | foreach ($this->links as $key => $l) { |
308 | if (startsWith($l['linkdate'], $day)) { | 304 | if ($l['created']->format('Ymd') == $day) { |
309 | $filtered[$l['linkdate']] = $l; | 305 | $filtered[$key] = $l; |
310 | } | 306 | } |
311 | } | 307 | } |
312 | ksort($filtered); | 308 | |
313 | return $filtered; | 309 | // sort by date ASC |
310 | return array_reverse($filtered, true); | ||
314 | } | 311 | } |
315 | 312 | ||
316 | /** | 313 | /** |
diff --git a/application/NetscapeBookmarkUtils.php b/application/NetscapeBookmarkUtils.php index dd21f05b..8a939adb 100644 --- a/application/NetscapeBookmarkUtils.php +++ b/application/NetscapeBookmarkUtils.php | |||
@@ -38,7 +38,7 @@ class NetscapeBookmarkUtils | |||
38 | if ($link['private'] == 0 && $selection == 'private') { | 38 | if ($link['private'] == 0 && $selection == 'private') { |
39 | continue; | 39 | continue; |
40 | } | 40 | } |
41 | $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']); | 41 | $date = $link['created']; |
42 | $link['timestamp'] = $date->getTimestamp(); | 42 | $link['timestamp'] = $date->getTimestamp(); |
43 | $link['taglist'] = str_replace(' ', ',', $link['tags']); | 43 | $link['taglist'] = str_replace(' ', ',', $link['tags']); |
44 | 44 | ||
@@ -147,7 +147,6 @@ class NetscapeBookmarkUtils | |||
147 | 'url' => $bkm['uri'], | 147 | 'url' => $bkm['uri'], |
148 | 'description' => $bkm['note'], | 148 | 'description' => $bkm['note'], |
149 | 'private' => $private, | 149 | 'private' => $private, |
150 | 'linkdate'=> '', | ||
151 | 'tags' => $bkm['tags'] | 150 | 'tags' => $bkm['tags'] |
152 | ); | 151 | ); |
153 | 152 | ||
@@ -161,25 +160,21 @@ class NetscapeBookmarkUtils | |||
161 | } | 160 | } |
162 | 161 | ||
163 | // Overwrite an existing link, keep its date | 162 | // Overwrite an existing link, keep its date |
164 | $newLink['linkdate'] = $existingLink['linkdate']; | 163 | $newLink['id'] = $existingLink['id']; |
165 | $linkDb[$existingLink['linkdate']] = $newLink; | 164 | $newLink['created'] = $existingLink['created']; |
165 | $newLink['updated'] = new DateTime(); | ||
166 | $linkDb[$existingLink['id']] = $newLink; | ||
166 | $importCount++; | 167 | $importCount++; |
167 | $overwriteCount++; | 168 | $overwriteCount++; |
168 | continue; | 169 | continue; |
169 | } | 170 | } |
170 | 171 | ||
171 | // Add a new link | 172 | // Add a new link - @ used for UNIX timestamps |
172 | $newLinkDate = new DateTime('@'.strval($bkm['time'])); | 173 | $newLinkDate = new DateTime('@'.strval($bkm['time'])); |
173 | while (!empty($linkDb[$newLinkDate->format(LinkDB::LINK_DATE_FORMAT)])) { | 174 | $newLinkDate->setTimezone(new DateTimeZone(date_default_timezone_get())); |
174 | // Ensure the date/time is not already used | 175 | $newLink['created'] = $newLinkDate; |
175 | // - this hack is necessary as the date/time acts as a primary key | 176 | $newLink['id'] = $linkDb->getNextId(); |
176 | // - apply 1 second increments until an unused index is found | 177 | $linkDb[$newLink['id']] = $newLink; |
177 | // See https://github.com/shaarli/Shaarli/issues/351 | ||
178 | $newLinkDate->add(new DateInterval('PT1S')); | ||
179 | } | ||
180 | $linkDbDate = $newLinkDate->format(LinkDB::LINK_DATE_FORMAT); | ||
181 | $newLink['linkdate'] = $linkDbDate; | ||
182 | $linkDb[$linkDbDate] = $newLink; | ||
183 | $importCount++; | 178 | $importCount++; |
184 | } | 179 | } |
185 | 180 | ||
diff --git a/application/Updater.php b/application/Updater.php index 94b63990..16c8c376 100644 --- a/application/Updater.php +++ b/application/Updater.php | |||
@@ -218,7 +218,7 @@ class Updater | |||
218 | 218 | ||
219 | /** | 219 | /** |
220 | * Update the database to use the new ID system, which replaces linkdate primary keys. | 220 | * Update the database to use the new ID system, which replaces linkdate primary keys. |
221 | * Also, creation and update dates are now DateTime objects. | 221 | * Also, creation and update dates are now DateTime objects (done by LinkDB). |
222 | * | 222 | * |
223 | * Since this update is very sensitve (changing the whole database), the datastore will be | 223 | * Since this update is very sensitve (changing the whole database), the datastore will be |
224 | * automatically backed up into the file datastore.<datetime>.php. | 224 | * automatically backed up into the file datastore.<datetime>.php. |
@@ -243,10 +243,6 @@ class Updater | |||
243 | $links = array_reverse($links); | 243 | $links = array_reverse($links); |
244 | $cpt = 0; | 244 | $cpt = 0; |
245 | foreach ($links as $l) { | 245 | foreach ($links as $l) { |
246 | $l['created'] = DateTime::createFromFormat('Ymd_His', $l['linkdate']); | ||
247 | if (! empty($l['updated'])) { | ||
248 | $l['updated'] = DateTime::createFromFormat('Ymd_His', $l['updated']); | ||
249 | } | ||
250 | unset($l['linkdate']); | 246 | unset($l['linkdate']); |
251 | $l['id'] = $cpt; | 247 | $l['id'] = $cpt; |
252 | $this->linkDB[$cpt++] = $l; | 248 | $this->linkDB[$cpt++] = $l; |
@@ -564,24 +564,23 @@ function showDailyRSS($conf) { | |||
564 | ); | 564 | ); |
565 | 565 | ||
566 | /* Some Shaarlies may have very few links, so we need to look | 566 | /* Some Shaarlies may have very few links, so we need to look |
567 | back in time (rsort()) until we have enough days ($nb_of_days). | 567 | back in time until we have enough days ($nb_of_days). |
568 | */ | 568 | */ |
569 | $linkdates = array(); | 569 | $ids = array(); |
570 | foreach ($LINKSDB as $linkdate => $value) { | 570 | foreach ($LINKSDB as $id => $value) { |
571 | $linkdates[] = $linkdate; | 571 | $ids[] = $id; |
572 | } | 572 | } |
573 | rsort($linkdates); | ||
574 | $nb_of_days = 7; // We take 7 days. | 573 | $nb_of_days = 7; // We take 7 days. |
575 | $today = date('Ymd'); | 574 | $today = date('Ymd'); |
576 | $days = array(); | 575 | $days = array(); |
577 | 576 | ||
578 | foreach ($linkdates as $linkdate) { | 577 | foreach ($ids as $id) { |
579 | $day = substr($linkdate, 0, 8); // Extract day (without time) | 578 | $day = $LINKSDB[$id]['created']->format('Ymd'); // Extract day (without time) |
580 | if (strcmp($day,$today) < 0) { | 579 | if (strcmp($day, $today) < 0) { |
581 | if (empty($days[$day])) { | 580 | if (empty($days[$day])) { |
582 | $days[$day] = array(); | 581 | $days[$day] = array(); |
583 | } | 582 | } |
584 | $days[$day][] = $linkdate; | 583 | $days[$day][] = $id; |
585 | } | 584 | } |
586 | 585 | ||
587 | if (count($days) > $nb_of_days) { | 586 | if (count($days) > $nb_of_days) { |
@@ -601,7 +600,7 @@ function showDailyRSS($conf) { | |||
601 | echo '<copyright>'. $pageaddr .'</copyright>'. PHP_EOL; | 600 | echo '<copyright>'. $pageaddr .'</copyright>'. PHP_EOL; |
602 | 601 | ||
603 | // For each day. | 602 | // For each day. |
604 | foreach ($days as $day => $linkdates) { | 603 | foreach ($days as $day => $ids) { |
605 | $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000'); | 604 | $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000'); |
606 | $absurl = escape(index_url($_SERVER).'?do=daily&day='.$day); // Absolute URL of the corresponding "Daily" page. | 605 | $absurl = escape(index_url($_SERVER).'?do=daily&day='.$day); // Absolute URL of the corresponding "Daily" page. |
607 | 606 | ||
@@ -609,16 +608,15 @@ function showDailyRSS($conf) { | |||
609 | $links = array(); | 608 | $links = array(); |
610 | 609 | ||
611 | // We pre-format some fields for proper output. | 610 | // We pre-format some fields for proper output. |
612 | foreach ($linkdates as $linkdate) { | 611 | foreach ($ids as $id) { |
613 | $l = $LINKSDB[$linkdate]; | 612 | $l = $LINKSDB[$id]; |
614 | $l['formatedDescription'] = format_description($l['description'], $conf->get('redirector.url')); | 613 | $l['formatedDescription'] = format_description($l['description'], $conf->get('redirector.url')); |
615 | $l['thumbnail'] = thumbnail($conf, $l['url']); | 614 | $l['thumbnail'] = thumbnail($conf, $l['url']); |
616 | $l_date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $l['linkdate']); | 615 | $l['timestamp'] = $l['created']->getTimestamp(); |
617 | $l['timestamp'] = $l_date->getTimestamp(); | ||
618 | if (startsWith($l['url'], '?')) { | 616 | if (startsWith($l['url'], '?')) { |
619 | $l['url'] = index_url($_SERVER) . $l['url']; // make permalink URL absolute | 617 | $l['url'] = index_url($_SERVER) . $l['url']; // make permalink URL absolute |
620 | } | 618 | } |
621 | $links[$linkdate] = $l; | 619 | $links[$id] = $l; |
622 | } | 620 | } |
623 | 621 | ||
624 | // Then build the HTML for this day: | 622 | // Then build the HTML for this day: |
@@ -677,11 +675,11 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager) | |||
677 | 675 | ||
678 | $taglist = explode(' ',$link['tags']); | 676 | $taglist = explode(' ',$link['tags']); |
679 | uasort($taglist, 'strcasecmp'); | 677 | uasort($taglist, 'strcasecmp'); |
678 | $linksToDisplay[$key]['shorturl'] = smallHash($link['created']->format('Ymd_His')); | ||
680 | $linksToDisplay[$key]['taglist']=$taglist; | 679 | $linksToDisplay[$key]['taglist']=$taglist; |
681 | $linksToDisplay[$key]['formatedDescription'] = format_description($link['description'], $conf->get('redirector.url')); | 680 | $linksToDisplay[$key]['formatedDescription'] = format_description($link['description'], $conf->get('redirector.url')); |
682 | $linksToDisplay[$key]['thumbnail'] = thumbnail($conf, $link['url']); | 681 | $linksToDisplay[$key]['thumbnail'] = thumbnail($conf, $link['url']); |
683 | $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']); | 682 | $linksToDisplay[$key]['timestamp'] = $link['created']->getTimestamp(); |
684 | $linksToDisplay[$key]['timestamp'] = $date->getTimestamp(); | ||
685 | } | 683 | } |
686 | 684 | ||
687 | /* We need to spread the articles on 3 columns. | 685 | /* We need to spread the articles on 3 columns. |
@@ -831,7 +829,7 @@ function renderPage($conf, $pluginManager) | |||
831 | // Get only links which have a thumbnail. | 829 | // Get only links which have a thumbnail. |
832 | foreach($links as $link) | 830 | foreach($links as $link) |
833 | { | 831 | { |
834 | $permalink='?'.escape(smallHash($link['linkdate'])); | 832 | $permalink='?'.escape(smallHash($link['created']->format('Ymd_His'))); |
835 | $thumb=lazyThumbnail($conf, $link['url'],$permalink); | 833 | $thumb=lazyThumbnail($conf, $link['url'],$permalink); |
836 | if ($thumb!='') // Only output links which have a thumbnail. | 834 | if ($thumb!='') // Only output links which have a thumbnail. |
837 | { | 835 | { |
@@ -1245,13 +1243,28 @@ function renderPage($conf, $pluginManager) | |||
1245 | // -------- User clicked the "Save" button when editing a link: Save link to database. | 1243 | // -------- User clicked the "Save" button when editing a link: Save link to database. |
1246 | if (isset($_POST['save_edit'])) | 1244 | if (isset($_POST['save_edit'])) |
1247 | { | 1245 | { |
1248 | $linkdate = $_POST['lf_linkdate']; | ||
1249 | $updated = isset($LINKSDB[$linkdate]) ? strval(date('Ymd_His')) : false; | ||
1250 | |||
1251 | // Go away! | 1246 | // Go away! |
1252 | if (! tokenOk($_POST['token'])) { | 1247 | if (! tokenOk($_POST['token'])) { |
1253 | die('Wrong token.'); | 1248 | die('Wrong token.'); |
1254 | } | 1249 | } |
1250 | |||
1251 | // lf_id should only be present if the link exists. | ||
1252 | $id = !empty($_POST['lf_id']) ? (int) escape($_POST['lf_id']) : $LINKSDB->getNextId(); | ||
1253 | // Linkdate is kept here to: | ||
1254 | // - use the same permalink for notes as they're displayed when creating them | ||
1255 | // - let users hack creation date of their posts | ||
1256 | // See: https://github.com/shaarli/Shaarli/wiki/Datastore-hacks#changing-the-timestamp-for-a-link | ||
1257 | $linkdate = escape($_POST['lf_linkdate']); | ||
1258 | if (isset($LINKSDB[$id])) { | ||
1259 | // Edit | ||
1260 | $created = DateTime::createFromFormat('Ymd_His', $linkdate); | ||
1261 | $updated = new DateTime(); | ||
1262 | } else { | ||
1263 | // New link | ||
1264 | $created = DateTime::createFromFormat('Ymd_His', $linkdate); | ||
1265 | $updated = null; | ||
1266 | } | ||
1267 | |||
1255 | // Remove multiple spaces. | 1268 | // Remove multiple spaces. |
1256 | $tags = trim(preg_replace('/\s\s+/', ' ', $_POST['lf_tags'])); | 1269 | $tags = trim(preg_replace('/\s\s+/', ' ', $_POST['lf_tags'])); |
1257 | // Remove first '-' char in tags. | 1270 | // Remove first '-' char in tags. |
@@ -1268,14 +1281,16 @@ function renderPage($conf, $pluginManager) | |||
1268 | } | 1281 | } |
1269 | 1282 | ||
1270 | $link = array( | 1283 | $link = array( |
1284 | 'id' => $id, | ||
1271 | 'title' => trim($_POST['lf_title']), | 1285 | 'title' => trim($_POST['lf_title']), |
1272 | 'url' => $url, | 1286 | 'url' => $url, |
1273 | 'description' => $_POST['lf_description'], | 1287 | 'description' => $_POST['lf_description'], |
1274 | 'private' => (isset($_POST['lf_private']) ? 1 : 0), | 1288 | 'private' => (isset($_POST['lf_private']) ? 1 : 0), |
1275 | 'linkdate' => $linkdate, | 1289 | 'created' => $created, |
1276 | 'updated' => $updated, | 1290 | 'updated' => $updated, |
1277 | 'tags' => str_replace(',', ' ', $tags) | 1291 | 'tags' => str_replace(',', ' ', $tags) |
1278 | ); | 1292 | ); |
1293 | |||
1279 | // If title is empty, use the URL as title. | 1294 | // If title is empty, use the URL as title. |
1280 | if ($link['title'] == '') { | 1295 | if ($link['title'] == '') { |
1281 | $link['title'] = $link['url']; | 1296 | $link['title'] = $link['url']; |
@@ -1283,7 +1298,7 @@ function renderPage($conf, $pluginManager) | |||
1283 | 1298 | ||
1284 | $pluginManager->executeHooks('save_link', $link); | 1299 | $pluginManager->executeHooks('save_link', $link); |
1285 | 1300 | ||
1286 | $LINKSDB[$linkdate] = $link; | 1301 | $LINKSDB[$id] = $link; |
1287 | $LINKSDB->save($conf->get('resource.page_cache')); | 1302 | $LINKSDB->save($conf->get('resource.page_cache')); |
1288 | pubsubhub($conf); | 1303 | pubsubhub($conf); |
1289 | 1304 | ||
@@ -1296,7 +1311,7 @@ function renderPage($conf, $pluginManager) | |||
1296 | $returnurl = !empty($_POST['returnurl']) ? $_POST['returnurl'] : '?'; | 1311 | $returnurl = !empty($_POST['returnurl']) ? $_POST['returnurl'] : '?'; |
1297 | $location = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); | 1312 | $location = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); |
1298 | // Scroll to the link which has been edited. | 1313 | // Scroll to the link which has been edited. |
1299 | $location .= '#' . smallHash($_POST['lf_linkdate']); | 1314 | $location .= '#' . smallHash($created->format('Ymd_His')); |
1300 | // After saving the link, redirect to the page the user was on. | 1315 | // After saving the link, redirect to the page the user was on. |
1301 | header('Location: '. $location); | 1316 | header('Location: '. $location); |
1302 | exit; | 1317 | exit; |
@@ -1307,8 +1322,10 @@ function renderPage($conf, $pluginManager) | |||
1307 | { | 1322 | { |
1308 | // If we are called from the bookmarklet, we must close the popup: | 1323 | // If we are called from the bookmarklet, we must close the popup: |
1309 | if (isset($_GET['source']) && ($_GET['source']=='bookmarklet' || $_GET['source']=='firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } | 1324 | if (isset($_GET['source']) && ($_GET['source']=='bookmarklet' || $_GET['source']=='firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } |
1325 | $link = $LINKSDB[(int) escape($_POST['lf_id'])]; | ||
1310 | $returnurl = ( isset($_POST['returnurl']) ? $_POST['returnurl'] : '?' ); | 1326 | $returnurl = ( isset($_POST['returnurl']) ? $_POST['returnurl'] : '?' ); |
1311 | $returnurl .= '#'.smallHash($_POST['lf_linkdate']); // Scroll to the link which has been edited. | 1327 | // Scroll to the link which has been edited. |
1328 | $returnurl .= '#'.smallHash($link['created']->format('Ymd_His')); | ||
1312 | $returnurl = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); | 1329 | $returnurl = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); |
1313 | header('Location: '.$returnurl); // After canceling, redirect to the page the user was on. | 1330 | header('Location: '.$returnurl); // After canceling, redirect to the page the user was on. |
1314 | exit; | 1331 | exit; |
@@ -1318,14 +1335,17 @@ function renderPage($conf, $pluginManager) | |||
1318 | if (isset($_POST['delete_link'])) | 1335 | if (isset($_POST['delete_link'])) |
1319 | { | 1336 | { |
1320 | if (!tokenOk($_POST['token'])) die('Wrong token.'); | 1337 | if (!tokenOk($_POST['token'])) die('Wrong token.'); |
1338 | |||
1321 | // We do not need to ask for confirmation: | 1339 | // We do not need to ask for confirmation: |
1322 | // - confirmation is handled by JavaScript | 1340 | // - confirmation is handled by JavaScript |
1323 | // - we are protected from XSRF by the token. | 1341 | // - we are protected from XSRF by the token. |
1324 | $linkdate=$_POST['lf_linkdate']; | ||
1325 | 1342 | ||
1326 | $pluginManager->executeHooks('delete_link', $LINKSDB[$linkdate]); | 1343 | // FIXME! We keep `lf_linkdate` for consistency before a proper API. To be removed. |
1344 | $id = isset($_POST['lf_id']) ? (int) escape($_POST['lf_id']) : (int) escape($_POST['lf_linkdate']); | ||
1327 | 1345 | ||
1328 | unset($LINKSDB[$linkdate]); | 1346 | $pluginManager->executeHooks('delete_link', $LINKSDB[$id]); |
1347 | |||
1348 | unset($LINKSDB[$id]); | ||
1329 | $LINKSDB->save('resource.page_cache'); // save to disk | 1349 | $LINKSDB->save('resource.page_cache'); // save to disk |
1330 | 1350 | ||
1331 | // If we are called from the bookmarklet, we must close the popup: | 1351 | // If we are called from the bookmarklet, we must close the popup: |
@@ -1364,8 +1384,10 @@ function renderPage($conf, $pluginManager) | |||
1364 | // -------- User clicked the "EDIT" button on a link: Display link edit form. | 1384 | // -------- User clicked the "EDIT" button on a link: Display link edit form. |
1365 | if (isset($_GET['edit_link'])) | 1385 | if (isset($_GET['edit_link'])) |
1366 | { | 1386 | { |
1367 | $link = $LINKSDB[$_GET['edit_link']]; // Read database | 1387 | $id = (int) escape($_GET['edit_link']); |
1388 | $link = $LINKSDB[$id]; // Read database | ||
1368 | if (!$link) { header('Location: ?'); exit; } // Link not found in database. | 1389 | if (!$link) { header('Location: ?'); exit; } // Link not found in database. |
1390 | $link['linkdate'] = $link['created']->format('Ymd_His'); | ||
1369 | $data = array( | 1391 | $data = array( |
1370 | 'link' => $link, | 1392 | 'link' => $link, |
1371 | 'link_is_new' => false, | 1393 | 'link_is_new' => false, |
@@ -1389,7 +1411,7 @@ function renderPage($conf, $pluginManager) | |||
1389 | $link_is_new = false; | 1411 | $link_is_new = false; |
1390 | // Check if URL is not already in database (in this case, we will edit the existing link) | 1412 | // Check if URL is not already in database (in this case, we will edit the existing link) |
1391 | $link = $LINKSDB->getLinkFromUrl($url); | 1413 | $link = $LINKSDB->getLinkFromUrl($url); |
1392 | if (!$link) | 1414 | if (! $link) |
1393 | { | 1415 | { |
1394 | $link_is_new = true; | 1416 | $link_is_new = true; |
1395 | $linkdate = strval(date('Ymd_His')); | 1417 | $linkdate = strval(date('Ymd_His')); |
@@ -1430,6 +1452,8 @@ function renderPage($conf, $pluginManager) | |||
1430 | 'tags' => $tags, | 1452 | 'tags' => $tags, |
1431 | 'private' => $private | 1453 | 'private' => $private |
1432 | ); | 1454 | ); |
1455 | } else { | ||
1456 | $link['linkdate'] = $link['created']->format('Ymd_His'); | ||
1433 | } | 1457 | } |
1434 | 1458 | ||
1435 | $data = array( | 1459 | $data = array( |
@@ -1635,18 +1659,16 @@ function buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager) | |||
1635 | $link['description'] = format_description($link['description'], $conf->get('redirector.url')); | 1659 | $link['description'] = format_description($link['description'], $conf->get('redirector.url')); |
1636 | $classLi = ($i % 2) != 0 ? '' : 'publicLinkHightLight'; | 1660 | $classLi = ($i % 2) != 0 ? '' : 'publicLinkHightLight'; |
1637 | $link['class'] = $link['private'] == 0 ? $classLi : 'private'; | 1661 | $link['class'] = $link['private'] == 0 ? $classLi : 'private'; |
1638 | $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']); | 1662 | $link['timestamp'] = $link['created']->getTimestamp(); |
1639 | $link['timestamp'] = $date->getTimestamp(); | ||
1640 | if (! empty($link['updated'])) { | 1663 | if (! empty($link['updated'])) { |
1641 | $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['updated']); | 1664 | $link['updated_timestamp'] = $link['updated']->getTimestamp(); |
1642 | $link['updated_timestamp'] = $date->getTimestamp(); | ||
1643 | } else { | 1665 | } else { |
1644 | $link['updated_timestamp'] = ''; | 1666 | $link['updated_timestamp'] = ''; |
1645 | } | 1667 | } |
1646 | $taglist = explode(' ', $link['tags']); | 1668 | $taglist = explode(' ', $link['tags']); |
1647 | uasort($taglist, 'strcasecmp'); | 1669 | uasort($taglist, 'strcasecmp'); |
1648 | $link['taglist'] = $taglist; | 1670 | $link['taglist'] = $taglist; |
1649 | $link['shorturl'] = smallHash($link['linkdate']); | 1671 | $link['shorturl'] = smallHash($link['created']->format('Ymd_His')); |
1650 | // Check for both signs of a note: starting with ? and 7 chars long. | 1672 | // Check for both signs of a note: starting with ? and 7 chars long. |
1651 | if ($link['url'][0] === '?' && | 1673 | if ($link['url'][0] === '?' && |
1652 | strlen($link['url']) === 7) { | 1674 | strlen($link['url']) === 7) { |
diff --git a/plugins/isso/isso.php b/plugins/isso/isso.php index ffb7cfac..c44f3c09 100644 --- a/plugins/isso/isso.php +++ b/plugins/isso/isso.php | |||
@@ -41,9 +41,11 @@ function hook_isso_render_linklist($data, $conf) | |||
41 | // Only display comments for permalinks. | 41 | // Only display comments for permalinks. |
42 | if (count($data['links']) == 1 && empty($data['search_tags']) && empty($data['search_term'])) { | 42 | if (count($data['links']) == 1 && empty($data['search_tags']) && empty($data['search_term'])) { |
43 | $link = reset($data['links']); | 43 | $link = reset($data['links']); |
44 | $isso_html = file_get_contents(PluginManager::$PLUGINS_PATH . '/isso/isso.html'); | 44 | $issoHtml = file_get_contents(PluginManager::$PLUGINS_PATH . '/isso/isso.html'); |
45 | 45 | ||
46 | $isso = sprintf($isso_html, $issoUrl, $issoUrl, $link['linkdate'], $link['linkdate']); | 46 | // FIXME! KO thread unique si même date |
47 | $linkDate = $link['created']->format('Ymd_His'); | ||
48 | $isso = sprintf($issoHtml, $issoUrl, $issoUrl, $linkDate, $linkDate); | ||
47 | $data['plugin_end_zone'][] = $isso; | 49 | $data['plugin_end_zone'][] = $isso; |
48 | 50 | ||
49 | // Hackish way to include this CSS file only when necessary. | 51 | // Hackish way to include this CSS file only when necessary. |
diff --git a/tpl/daily.html b/tpl/daily.html index b82ad483..eba0af3b 100644 --- a/tpl/daily.html +++ b/tpl/daily.html | |||
@@ -49,13 +49,13 @@ | |||
49 | {$link=$value} | 49 | {$link=$value} |
50 | <div class="dailyEntry"> | 50 | <div class="dailyEntry"> |
51 | <div class="dailyEntryPermalink"> | 51 | <div class="dailyEntryPermalink"> |
52 | <a href="?{$link.linkdate|smallHash}"> | 52 | <a href="?{$value.shorturl}"> |
53 | <img src="../images/squiggle2.png" width="25" height="26" title="permalink" alt="permalink"> | 53 | <img src="../images/squiggle2.png" width="25" height="26" title="permalink" alt="permalink"> |
54 | </a> | 54 | </a> |
55 | </div> | 55 | </div> |
56 | {if="!$hide_timestamps || isLoggedIn()"} | 56 | {if="!$hide_timestamps || isLoggedIn()"} |
57 | <div class="dailyEntryLinkdate"> | 57 | <div class="dailyEntryLinkdate"> |
58 | <a href="?{$link.linkdate|smallHash}">{function="strftime('%c', $link.timestamp)"}</a> | 58 | <a href="?{$value.shorturl}">{function="strftime('%c', $link.timestamp)"}</a> |
59 | </div> | 59 | </div> |
60 | {/if} | 60 | {/if} |
61 | {if="$link.tags"} | 61 | {if="$link.tags"} |
diff --git a/tpl/editlink.html b/tpl/editlink.html index 9e7621db..870cc168 100644 --- a/tpl/editlink.html +++ b/tpl/editlink.html | |||
@@ -16,6 +16,9 @@ | |||
16 | <div id="editlinkform"> | 16 | <div id="editlinkform"> |
17 | <form method="post" name="linkform"> | 17 | <form method="post" name="linkform"> |
18 | <input type="hidden" name="lf_linkdate" value="{$link.linkdate}"> | 18 | <input type="hidden" name="lf_linkdate" value="{$link.linkdate}"> |
19 | {if="isset($link.id)"} | ||
20 | <input type="hidden" name="lf_id" value="{$link.id}"> | ||
21 | {/if} | ||
19 | <label for="lf_url"><i>URL</i></label><br><input type="text" name="lf_url" id="lf_url" value="{$link.url}" class="lf_input"><br> | 22 | <label for="lf_url"><i>URL</i></label><br><input type="text" name="lf_url" id="lf_url" value="{$link.url}" class="lf_input"><br> |
20 | <label for="lf_title"><i>Title</i></label><br><input type="text" name="lf_title" id="lf_title" value="{$link.title}" class="lf_input"><br> | 23 | <label for="lf_title"><i>Title</i></label><br><input type="text" name="lf_title" id="lf_title" value="{$link.title}" class="lf_input"><br> |
21 | <label for="lf_description"><i>Description</i></label><br><textarea name="lf_description" id="lf_description" rows="4" cols="25">{$link.description}</textarea><br> | 24 | <label for="lf_description"><i>Description</i></label><br><textarea name="lf_description" id="lf_description" rows="4" cols="25">{$link.description}</textarea><br> |
diff --git a/tpl/linklist.html b/tpl/linklist.html index ddfd729a..de9586c6 100644 --- a/tpl/linklist.html +++ b/tpl/linklist.html | |||
@@ -71,11 +71,11 @@ | |||
71 | {if="isLoggedIn()"} | 71 | {if="isLoggedIn()"} |
72 | <div class="linkeditbuttons"> | 72 | <div class="linkeditbuttons"> |
73 | <form method="GET" class="buttoneditform"> | 73 | <form method="GET" class="buttoneditform"> |
74 | <input type="hidden" name="edit_link" value="{$value.linkdate}"> | 74 | <input type="hidden" name="edit_link" value="{$value.id}"> |
75 | <input type="image" alt="Edit" src="images/edit_icon.png#" title="Edit" class="button_edit"> | 75 | <input type="image" alt="Edit" src="images/edit_icon.png#" title="Edit" class="button_edit"> |
76 | </form><br> | 76 | </form><br> |
77 | <form method="POST" class="buttoneditform"> | 77 | <form method="POST" class="buttoneditform"> |
78 | <input type="hidden" name="lf_linkdate" value="{$value.linkdate}"> | 78 | <input type="hidden" name="lf_linkdate" value="{$value.id}"> |
79 | <input type="hidden" name="token" value="{$token}"> | 79 | <input type="hidden" name="token" value="{$token}"> |
80 | <input type="hidden" name="delete_link"> | 80 | <input type="hidden" name="delete_link"> |
81 | <input type="image" alt="Delete" src="images/delete_icon.png#" title="Delete" | 81 | <input type="image" alt="Delete" src="images/delete_icon.png#" title="Delete" |
@@ -91,7 +91,7 @@ | |||
91 | {if="!$hide_timestamps || isLoggedIn()"} | 91 | {if="!$hide_timestamps || isLoggedIn()"} |
92 | {$updated=$value.updated_timestamp ? 'Edited: '. strftime('%c', $value.updated_timestamp) : 'Permalink'} | 92 | {$updated=$value.updated_timestamp ? 'Edited: '. strftime('%c', $value.updated_timestamp) : 'Permalink'} |
93 | <span class="linkdate" title="Permalink"> | 93 | <span class="linkdate" title="Permalink"> |
94 | <a href="?{$value.linkdate|smallHash}"> | 94 | <a href="?{$value.shorturl}"> |
95 | <span title="{$updated}"> | 95 | <span title="{$updated}"> |
96 | {function="strftime('%c', $value.timestamp)"} | 96 | {function="strftime('%c', $value.timestamp)"} |
97 | {if="$value.updated_timestamp"}*{/if} | 97 | {if="$value.updated_timestamp"}*{/if} |