diff options
author | ArthurHoaro <arthur@hoa.ro> | 2020-01-18 10:01:06 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-18 10:01:06 +0100 |
commit | 3fb29fdda04ca86e04422d49b86cf646d53c4f9d (patch) | |
tree | adf8512f93f5559ba87d0c9931969ae4ebea7133 /index.php | |
parent | 796c4c57d085ae4589b53dfe8369ae9ba30ffdaf (diff) | |
parent | e26e2060f5470ce8bf4c5973284bae07b8af170a (diff) | |
download | Shaarli-3fb29fdda04ca86e04422d49b86cf646d53c4f9d.tar.gz Shaarli-3fb29fdda04ca86e04422d49b86cf646d53c4f9d.tar.zst Shaarli-3fb29fdda04ca86e04422d49b86cf646d53c4f9d.zip |
Store bookmarks as PHP objects and add a service layer to retriā¦ (#1307)
Store bookmarks as PHP objects and add a service layer to retrieve them
Diffstat (limited to 'index.php')
-rw-r--r-- | index.php | 555 |
1 files changed, 278 insertions, 277 deletions
@@ -35,9 +35,6 @@ ini_set('upload_max_filesize', '16M'); | |||
35 | 35 | ||
36 | // See all error except warnings | 36 | // See all error except warnings |
37 | error_reporting(E_ALL^E_WARNING); | 37 | error_reporting(E_ALL^E_WARNING); |
38 | // See all errors (for debugging only) | ||
39 | //error_reporting(-1); | ||
40 | |||
41 | 38 | ||
42 | // 3rd-party libraries | 39 | // 3rd-party libraries |
43 | if (! file_exists(__DIR__ . '/vendor/autoload.php')) { | 40 | if (! file_exists(__DIR__ . '/vendor/autoload.php')) { |
@@ -65,11 +62,15 @@ require_once 'application/TimeZone.php'; | |||
65 | require_once 'application/Utils.php'; | 62 | require_once 'application/Utils.php'; |
66 | 63 | ||
67 | use \Shaarli\ApplicationUtils; | 64 | use \Shaarli\ApplicationUtils; |
68 | use \Shaarli\Bookmark\Exception\LinkNotFoundException; | 65 | use Shaarli\Bookmark\BookmarkServiceInterface; |
69 | use \Shaarli\Bookmark\LinkDB; | 66 | use \Shaarli\Bookmark\Exception\BookmarkNotFoundException; |
67 | use Shaarli\Bookmark\Bookmark; | ||
68 | use Shaarli\Bookmark\BookmarkFilter; | ||
69 | use Shaarli\Bookmark\BookmarkFileService; | ||
70 | use \Shaarli\Config\ConfigManager; | 70 | use \Shaarli\Config\ConfigManager; |
71 | use \Shaarli\Feed\CachedPage; | 71 | use \Shaarli\Feed\CachedPage; |
72 | use \Shaarli\Feed\FeedBuilder; | 72 | use \Shaarli\Feed\FeedBuilder; |
73 | use Shaarli\Formatter\FormatterFactory; | ||
73 | use \Shaarli\History; | 74 | use \Shaarli\History; |
74 | use \Shaarli\Languages; | 75 | use \Shaarli\Languages; |
75 | use \Shaarli\Netscape\NetscapeBookmarkUtils; | 76 | use \Shaarli\Netscape\NetscapeBookmarkUtils; |
@@ -81,6 +82,7 @@ use \Shaarli\Security\LoginManager; | |||
81 | use \Shaarli\Security\SessionManager; | 82 | use \Shaarli\Security\SessionManager; |
82 | use \Shaarli\Thumbnailer; | 83 | use \Shaarli\Thumbnailer; |
83 | use \Shaarli\Updater\Updater; | 84 | use \Shaarli\Updater\Updater; |
85 | use \Shaarli\Updater\UpdaterUtils; | ||
84 | 86 | ||
85 | // Ensure the PHP version is supported | 87 | // Ensure the PHP version is supported |
86 | try { | 88 | try { |
@@ -122,6 +124,17 @@ if (isset($_COOKIE['shaarli']) && !SessionManager::checkId($_COOKIE['shaarli'])) | |||
122 | } | 124 | } |
123 | 125 | ||
124 | $conf = new ConfigManager(); | 126 | $conf = new ConfigManager(); |
127 | |||
128 | // In dev mode, throw exception on any warning | ||
129 | if ($conf->get('dev.debug', false)) { | ||
130 | // See all errors (for debugging only) | ||
131 | error_reporting(-1); | ||
132 | |||
133 | set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) { | ||
134 | throw new ErrorException($errstr, 0, $errno, $errfile, $errline); | ||
135 | }); | ||
136 | } | ||
137 | |||
125 | $sessionManager = new SessionManager($_SESSION, $conf); | 138 | $sessionManager = new SessionManager($_SESSION, $conf); |
126 | $loginManager = new LoginManager($conf, $sessionManager); | 139 | $loginManager = new LoginManager($conf, $sessionManager); |
127 | $loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']); | 140 | $loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']); |
@@ -140,7 +153,7 @@ if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { | |||
140 | new Languages(setlocale(LC_MESSAGES, 0), $conf); | 153 | new Languages(setlocale(LC_MESSAGES, 0), $conf); |
141 | 154 | ||
142 | $conf->setEmpty('general.timezone', date_default_timezone_get()); | 155 | $conf->setEmpty('general.timezone', date_default_timezone_get()); |
143 | $conf->setEmpty('general.title', t('Shared links on '). escape(index_url($_SERVER))); | 156 | $conf->setEmpty('general.title', t('Shared bookmarks on '). escape(index_url($_SERVER))); |
144 | RainTPL::$tpl_dir = $conf->get('resource.raintpl_tpl').'/'.$conf->get('resource.theme').'/'; // template directory | 157 | RainTPL::$tpl_dir = $conf->get('resource.raintpl_tpl').'/'.$conf->get('resource.theme').'/'; // template directory |
145 | RainTPL::$cache_dir = $conf->get('resource.raintpl_tmp'); // cache directory | 158 | RainTPL::$cache_dir = $conf->get('resource.raintpl_tmp'); // cache directory |
146 | 159 | ||
@@ -283,14 +296,15 @@ if (!isset($_SESSION['tokens'])) { | |||
283 | } | 296 | } |
284 | 297 | ||
285 | /** | 298 | /** |
286 | * Daily RSS feed: 1 RSS entry per day giving all the links on that day. | 299 | * Daily RSS feed: 1 RSS entry per day giving all the bookmarks on that day. |
287 | * Gives the last 7 days (which have links). | 300 | * Gives the last 7 days (which have bookmarks). |
288 | * This RSS feed cannot be filtered. | 301 | * This RSS feed cannot be filtered. |
289 | * | 302 | * |
290 | * @param ConfigManager $conf Configuration Manager instance | 303 | * @param BookmarkServiceInterface $bookmarkService |
291 | * @param LoginManager $loginManager LoginManager instance | 304 | * @param ConfigManager $conf Configuration Manager instance |
305 | * @param LoginManager $loginManager LoginManager instance | ||
292 | */ | 306 | */ |
293 | function showDailyRSS($conf, $loginManager) | 307 | function showDailyRSS($bookmarkService, $conf, $loginManager) |
294 | { | 308 | { |
295 | // Cache system | 309 | // Cache system |
296 | $query = $_SERVER['QUERY_STRING']; | 310 | $query = $_SERVER['QUERY_STRING']; |
@@ -305,28 +319,20 @@ function showDailyRSS($conf, $loginManager) | |||
305 | exit; | 319 | exit; |
306 | } | 320 | } |
307 | 321 | ||
308 | // If cached was not found (or not usable), then read the database and build the response: | 322 | /* Some Shaarlies may have very few bookmarks, so we need to look |
309 | // Read links from database (and filter private links if used it not logged in). | ||
310 | $LINKSDB = new LinkDB( | ||
311 | $conf->get('resource.datastore'), | ||
312 | $loginManager->isLoggedIn(), | ||
313 | $conf->get('privacy.hide_public_links') | ||
314 | ); | ||
315 | |||
316 | /* Some Shaarlies may have very few links, so we need to look | ||
317 | back in time until we have enough days ($nb_of_days). | 323 | back in time until we have enough days ($nb_of_days). |
318 | */ | 324 | */ |
319 | $nb_of_days = 7; // We take 7 days. | 325 | $nb_of_days = 7; // We take 7 days. |
320 | $today = date('Ymd'); | 326 | $today = date('Ymd'); |
321 | $days = array(); | 327 | $days = array(); |
322 | 328 | ||
323 | foreach ($LINKSDB as $link) { | 329 | foreach ($bookmarkService->search() as $bookmark) { |
324 | $day = $link['created']->format('Ymd'); // Extract day (without time) | 330 | $day = $bookmark->getCreated()->format('Ymd'); // Extract day (without time) |
325 | if (strcmp($day, $today) < 0) { | 331 | if (strcmp($day, $today) < 0) { |
326 | if (empty($days[$day])) { | 332 | if (empty($days[$day])) { |
327 | $days[$day] = array(); | 333 | $days[$day] = array(); |
328 | } | 334 | } |
329 | $days[$day][] = $link; | 335 | $days[$day][] = $bookmark; |
330 | } | 336 | } |
331 | 337 | ||
332 | if (count($days) > $nb_of_days) { | 338 | if (count($days) > $nb_of_days) { |
@@ -341,30 +347,38 @@ function showDailyRSS($conf, $loginManager) | |||
341 | echo '<channel>'; | 347 | echo '<channel>'; |
342 | echo '<title>Daily - '. $conf->get('general.title') . '</title>'; | 348 | echo '<title>Daily - '. $conf->get('general.title') . '</title>'; |
343 | echo '<link>'. $pageaddr .'</link>'; | 349 | echo '<link>'. $pageaddr .'</link>'; |
344 | echo '<description>Daily shared links</description>'; | 350 | echo '<description>Daily shared bookmarks</description>'; |
345 | echo '<language>en-en</language>'; | 351 | echo '<language>en-en</language>'; |
346 | echo '<copyright>'. $pageaddr .'</copyright>'. PHP_EOL; | 352 | echo '<copyright>'. $pageaddr .'</copyright>'. PHP_EOL; |
347 | 353 | ||
354 | $factory = new FormatterFactory($conf); | ||
355 | $formatter = $factory->getFormatter(); | ||
356 | $formatter->addContextData('index_url', index_url($_SERVER)); | ||
348 | // For each day. | 357 | // For each day. |
349 | foreach ($days as $day => $links) { | 358 | /** @var Bookmark[] $bookmarks */ |
350 | $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000'); | 359 | foreach ($days as $day => $bookmarks) { |
360 | $formattedBookmarks = []; | ||
361 | $dayDate = DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, $day.'_000000'); | ||
351 | $absurl = escape(index_url($_SERVER).'?do=daily&day='.$day); // Absolute URL of the corresponding "Daily" page. | 362 | $absurl = escape(index_url($_SERVER).'?do=daily&day='.$day); // Absolute URL of the corresponding "Daily" page. |
352 | 363 | ||
353 | // We pre-format some fields for proper output. | 364 | // We pre-format some fields for proper output. |
354 | foreach ($links as &$link) { | 365 | foreach ($bookmarks as $key => $bookmark) { |
355 | $link['formatedDescription'] = format_description($link['description']); | 366 | $formattedBookmarks[$key] = $formatter->format($bookmark); |
356 | $link['timestamp'] = $link['created']->getTimestamp(); | 367 | // This page is a bit specific, we need raw description to calculate the length |
357 | if (is_note($link['url'])) { | 368 | $formattedBookmarks[$key]['formatedDescription'] = $formattedBookmarks[$key]['description']; |
358 | $link['url'] = index_url($_SERVER) . $link['url']; // make permalink URL absolute | 369 | $formattedBookmarks[$key]['description'] = $bookmark->getDescription(); |
370 | |||
371 | if ($bookmark->isNote()) { | ||
372 | $link['url'] = index_url($_SERVER) . $bookmark->getUrl(); // make permalink URL absolute | ||
359 | } | 373 | } |
360 | } | 374 | } |
361 | 375 | ||
362 | // Then build the HTML for this day: | 376 | // Then build the HTML for this day: |
363 | $tpl = new RainTPL; | 377 | $tpl = new RainTPL(); |
364 | $tpl->assign('title', $conf->get('general.title')); | 378 | $tpl->assign('title', $conf->get('general.title')); |
365 | $tpl->assign('daydate', $dayDate->getTimestamp()); | 379 | $tpl->assign('daydate', $dayDate->getTimestamp()); |
366 | $tpl->assign('absurl', $absurl); | 380 | $tpl->assign('absurl', $absurl); |
367 | $tpl->assign('links', $links); | 381 | $tpl->assign('links', $formattedBookmarks); |
368 | $tpl->assign('rssdate', escape($dayDate->format(DateTime::RSS))); | 382 | $tpl->assign('rssdate', escape($dayDate->format(DateTime::RSS))); |
369 | $tpl->assign('hide_timestamps', $conf->get('privacy.hide_timestamps', false)); | 383 | $tpl->assign('hide_timestamps', $conf->get('privacy.hide_timestamps', false)); |
370 | $tpl->assign('index_url', $pageaddr); | 384 | $tpl->assign('index_url', $pageaddr); |
@@ -382,13 +396,13 @@ function showDailyRSS($conf, $loginManager) | |||
382 | /** | 396 | /** |
383 | * Show the 'Daily' page. | 397 | * Show the 'Daily' page. |
384 | * | 398 | * |
385 | * @param PageBuilder $pageBuilder Template engine wrapper. | 399 | * @param PageBuilder $pageBuilder Template engine wrapper. |
386 | * @param LinkDB $LINKSDB LinkDB instance. | 400 | * @param BookmarkServiceInterface $bookmarkService instance. |
387 | * @param ConfigManager $conf Configuration Manager instance. | 401 | * @param ConfigManager $conf Configuration Manager instance. |
388 | * @param PluginManager $pluginManager Plugin Manager instance. | 402 | * @param PluginManager $pluginManager Plugin Manager instance. |
389 | * @param LoginManager $loginManager Login Manager instance | 403 | * @param LoginManager $loginManager Login Manager instance |
390 | */ | 404 | */ |
391 | function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager, $loginManager) | 405 | function showDaily($pageBuilder, $bookmarkService, $conf, $pluginManager, $loginManager) |
392 | { | 406 | { |
393 | if (isset($_GET['day'])) { | 407 | if (isset($_GET['day'])) { |
394 | $day = $_GET['day']; | 408 | $day = $_GET['day']; |
@@ -402,10 +416,10 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager, $loginManager) | |||
402 | $pageBuilder->assign('dayDesc', t('Today')); | 416 | $pageBuilder->assign('dayDesc', t('Today')); |
403 | } | 417 | } |
404 | 418 | ||
405 | $days = $LINKSDB->days(); | 419 | $days = $bookmarkService->days(); |
406 | $i = array_search($day, $days); | 420 | $i = array_search($day, $days); |
407 | if ($i === false && count($days)) { | 421 | if ($i === false && count($days)) { |
408 | // no links for day, but at least one day with links | 422 | // no bookmarks for day, but at least one day with bookmarks |
409 | $i = count($days) - 1; | 423 | $i = count($days) - 1; |
410 | $day = $days[$i]; | 424 | $day = $days[$i]; |
411 | } | 425 | } |
@@ -414,29 +428,30 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager, $loginManager) | |||
414 | 428 | ||
415 | if ($i !== false) { | 429 | if ($i !== false) { |
416 | if ($i >= 1) { | 430 | if ($i >= 1) { |
417 | $previousday=$days[$i - 1]; | 431 | $previousday = $days[$i - 1]; |
418 | } | 432 | } |
419 | if ($i < count($days) - 1) { | 433 | if ($i < count($days) - 1) { |
420 | $nextday = $days[$i + 1]; | 434 | $nextday = $days[$i + 1]; |
421 | } | 435 | } |
422 | } | 436 | } |
423 | try { | 437 | try { |
424 | $linksToDisplay = $LINKSDB->filterDay($day); | 438 | $linksToDisplay = $bookmarkService->filterDay($day); |
425 | } catch (Exception $exc) { | 439 | } catch (Exception $exc) { |
426 | error_log($exc); | 440 | error_log($exc); |
427 | $linksToDisplay = array(); | 441 | $linksToDisplay = []; |
428 | } | 442 | } |
429 | 443 | ||
444 | $factory = new FormatterFactory($conf); | ||
445 | $formatter = $factory->getFormatter(); | ||
430 | // We pre-format some fields for proper output. | 446 | // We pre-format some fields for proper output. |
431 | foreach ($linksToDisplay as $key => $link) { | 447 | foreach ($linksToDisplay as $key => $bookmark) { |
432 | $taglist = explode(' ', $link['tags']); | 448 | $linksToDisplay[$key] = $formatter->format($bookmark); |
433 | uasort($taglist, 'strcasecmp'); | 449 | // This page is a bit specific, we need raw description to calculate the length |
434 | $linksToDisplay[$key]['taglist']=$taglist; | 450 | $linksToDisplay[$key]['formatedDescription'] = $linksToDisplay[$key]['description']; |
435 | $linksToDisplay[$key]['formatedDescription'] = format_description($link['description']); | 451 | $linksToDisplay[$key]['description'] = $bookmark->getDescription(); |
436 | $linksToDisplay[$key]['timestamp'] = $link['created']->getTimestamp(); | ||
437 | } | 452 | } |
438 | 453 | ||
439 | $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000'); | 454 | $dayDate = DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, $day.'_000000'); |
440 | $data = array( | 455 | $data = array( |
441 | 'pagetitle' => $conf->get('general.title') .' - '. format_date($dayDate, false), | 456 | 'pagetitle' => $conf->get('general.title') .' - '. format_date($dayDate, false), |
442 | 'linksToDisplay' => $linksToDisplay, | 457 | 'linksToDisplay' => $linksToDisplay, |
@@ -457,19 +472,19 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager, $loginManager) | |||
457 | */ | 472 | */ |
458 | $columns = array(array(), array(), array()); // Entries to display, for each column. | 473 | $columns = array(array(), array(), array()); // Entries to display, for each column. |
459 | $fill = array(0, 0, 0); // Rough estimate of columns fill. | 474 | $fill = array(0, 0, 0); // Rough estimate of columns fill. |
460 | foreach ($data['linksToDisplay'] as $key => $link) { | 475 | foreach ($data['linksToDisplay'] as $key => $bookmark) { |
461 | // Roughly estimate length of entry (by counting characters) | 476 | // Roughly estimate length of entry (by counting characters) |
462 | // Title: 30 chars = 1 line. 1 line is 30 pixels height. | 477 | // Title: 30 chars = 1 line. 1 line is 30 pixels height. |
463 | // Description: 836 characters gives roughly 342 pixel height. | 478 | // Description: 836 characters gives roughly 342 pixel height. |
464 | // This is not perfect, but it's usually OK. | 479 | // This is not perfect, but it's usually OK. |
465 | $length = strlen($link['title']) + (342 * strlen($link['description'])) / 836; | 480 | $length = strlen($bookmark['title']) + (342 * strlen($bookmark['description'])) / 836; |
466 | if (! empty($link['thumbnail'])) { | 481 | if (! empty($bookmark['thumbnail'])) { |
467 | $length += 100; // 1 thumbnails roughly takes 100 pixels height. | 482 | $length += 100; // 1 thumbnails roughly takes 100 pixels height. |
468 | } | 483 | } |
469 | // Then put in column which is the less filled: | 484 | // Then put in column which is the less filled: |
470 | $smallest = min($fill); // find smallest value in array. | 485 | $smallest = min($fill); // find smallest value in array. |
471 | $index = array_search($smallest, $fill); // find index of this smallest value. | 486 | $index = array_search($smallest, $fill); // find index of this smallest value. |
472 | array_push($columns[$index], $link); // Put entry in this column. | 487 | array_push($columns[$index], $bookmark); // Put entry in this column. |
473 | $fill[$index] += $length; | 488 | $fill[$index] += $length; |
474 | } | 489 | } |
475 | 490 | ||
@@ -487,40 +502,39 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager, $loginManager) | |||
487 | /** | 502 | /** |
488 | * Renders the linklist | 503 | * Renders the linklist |
489 | * | 504 | * |
490 | * @param pageBuilder $PAGE pageBuilder instance. | 505 | * @param pageBuilder $PAGE pageBuilder instance. |
491 | * @param LinkDB $LINKSDB LinkDB instance. | 506 | * @param BookmarkServiceInterface $linkDb instance. |
492 | * @param ConfigManager $conf Configuration Manager instance. | 507 | * @param ConfigManager $conf Configuration Manager instance. |
493 | * @param PluginManager $pluginManager Plugin Manager instance. | 508 | * @param PluginManager $pluginManager Plugin Manager instance. |
494 | */ | 509 | */ |
495 | function showLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) | 510 | function showLinkList($PAGE, $linkDb, $conf, $pluginManager, $loginManager) |
496 | { | 511 | { |
497 | buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager); | 512 | buildLinkList($PAGE, $linkDb, $conf, $pluginManager, $loginManager); |
498 | $PAGE->renderPage('linklist'); | 513 | $PAGE->renderPage('linklist'); |
499 | } | 514 | } |
500 | 515 | ||
501 | /** | 516 | /** |
502 | * Render HTML page (according to URL parameters and user rights) | 517 | * Render HTML page (according to URL parameters and user rights) |
503 | * | 518 | * |
504 | * @param ConfigManager $conf Configuration Manager instance. | 519 | * @param ConfigManager $conf Configuration Manager instance. |
505 | * @param PluginManager $pluginManager Plugin Manager instance, | 520 | * @param PluginManager $pluginManager Plugin Manager instance, |
506 | * @param LinkDB $LINKSDB | 521 | * @param BookmarkServiceInterface $bookmarkService |
507 | * @param History $history instance | 522 | * @param History $history instance |
508 | * @param SessionManager $sessionManager SessionManager instance | 523 | * @param SessionManager $sessionManager SessionManager instance |
509 | * @param LoginManager $loginManager LoginManager instance | 524 | * @param LoginManager $loginManager LoginManager instance |
510 | */ | 525 | */ |
511 | function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $loginManager) | 526 | function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionManager, $loginManager) |
512 | { | 527 | { |
513 | $updater = new Updater( | 528 | $updater = new Updater( |
514 | read_updates_file($conf->get('resource.updates')), | 529 | UpdaterUtils::read_updates_file($conf->get('resource.updates')), |
515 | $LINKSDB, | 530 | $bookmarkService, |
516 | $conf, | 531 | $conf, |
517 | $loginManager->isLoggedIn(), | 532 | $loginManager->isLoggedIn() |
518 | $_SESSION | ||
519 | ); | 533 | ); |
520 | try { | 534 | try { |
521 | $newUpdates = $updater->update(); | 535 | $newUpdates = $updater->update(); |
522 | if (! empty($newUpdates)) { | 536 | if (! empty($newUpdates)) { |
523 | write_updates_file( | 537 | UpdaterUtils::write_updates_file( |
524 | $conf->get('resource.updates'), | 538 | $conf->get('resource.updates'), |
525 | $updater->getDoneUpdates() | 539 | $updater->getDoneUpdates() |
526 | ); | 540 | ); |
@@ -529,9 +543,9 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
529 | die($e->getMessage()); | 543 | die($e->getMessage()); |
530 | } | 544 | } |
531 | 545 | ||
532 | $PAGE = new PageBuilder($conf, $_SESSION, $LINKSDB, $sessionManager->generateToken(), $loginManager->isLoggedIn()); | 546 | $PAGE = new PageBuilder($conf, $_SESSION, $bookmarkService, $sessionManager->generateToken(), $loginManager->isLoggedIn()); |
533 | $PAGE->assign('linkcount', count($LINKSDB)); | 547 | $PAGE->assign('linkcount', $bookmarkService->count(BookmarkFilter::$ALL)); |
534 | $PAGE->assign('privateLinkcount', count_private($LINKSDB)); | 548 | $PAGE->assign('privateLinkcount', $bookmarkService->count(BookmarkFilter::$PRIVATE)); |
535 | $PAGE->assign('plugin_errors', $pluginManager->getErrors()); | 549 | $PAGE->assign('plugin_errors', $pluginManager->getErrors()); |
536 | 550 | ||
537 | // Determine which page will be rendered. | 551 | // Determine which page will be rendered. |
@@ -611,27 +625,28 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
611 | } | 625 | } |
612 | 626 | ||
613 | // Optionally filter the results: | 627 | // Optionally filter the results: |
614 | $links = $LINKSDB->filterSearch($_GET); | 628 | $links = $bookmarkService->search($_GET); |
615 | $linksToDisplay = array(); | 629 | $linksToDisplay = []; |
616 | 630 | ||
617 | // Get only links which have a thumbnail. | 631 | // Get only bookmarks which have a thumbnail. |
618 | // Note: we do not retrieve thumbnails here, the request is too heavy. | 632 | // Note: we do not retrieve thumbnails here, the request is too heavy. |
633 | $factory = new FormatterFactory($conf); | ||
634 | $formatter = $factory->getFormatter(); | ||
619 | foreach ($links as $key => $link) { | 635 | foreach ($links as $key => $link) { |
620 | if (isset($link['thumbnail']) && $link['thumbnail'] !== false) { | 636 | if ($link->getThumbnail() !== false) { |
621 | $linksToDisplay[] = $link; // Add to array. | 637 | $linksToDisplay[] = $formatter->format($link); |
622 | } | 638 | } |
623 | } | 639 | } |
624 | 640 | ||
625 | $data = array( | 641 | $data = [ |
626 | 'linksToDisplay' => $linksToDisplay, | 642 | 'linksToDisplay' => $linksToDisplay, |
627 | ); | 643 | ]; |
628 | $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => $loginManager->isLoggedIn())); | 644 | $pluginManager->executeHooks('render_picwall', $data, ['loggedin' => $loginManager->isLoggedIn()]); |
629 | 645 | ||
630 | foreach ($data as $key => $value) { | 646 | foreach ($data as $key => $value) { |
631 | $PAGE->assign($key, $value); | 647 | $PAGE->assign($key, $value); |
632 | } | 648 | } |
633 | 649 | ||
634 | |||
635 | $PAGE->renderPage('picwall'); | 650 | $PAGE->renderPage('picwall'); |
636 | exit; | 651 | exit; |
637 | } | 652 | } |
@@ -640,7 +655,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
640 | if ($targetPage == Router::$PAGE_TAGCLOUD) { | 655 | if ($targetPage == Router::$PAGE_TAGCLOUD) { |
641 | $visibility = ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : ''; | 656 | $visibility = ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : ''; |
642 | $filteringTags = isset($_GET['searchtags']) ? explode(' ', $_GET['searchtags']) : []; | 657 | $filteringTags = isset($_GET['searchtags']) ? explode(' ', $_GET['searchtags']) : []; |
643 | $tags = $LINKSDB->linksCountPerTag($filteringTags, $visibility); | 658 | $tags = $bookmarkService->bookmarksCountPerTag($filteringTags, $visibility); |
644 | 659 | ||
645 | // We sort tags alphabetically, then choose a font size according to count. | 660 | // We sort tags alphabetically, then choose a font size according to count. |
646 | // First, find max value. | 661 | // First, find max value. |
@@ -687,7 +702,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
687 | if ($targetPage == Router::$PAGE_TAGLIST) { | 702 | if ($targetPage == Router::$PAGE_TAGLIST) { |
688 | $visibility = ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : ''; | 703 | $visibility = ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : ''; |
689 | $filteringTags = isset($_GET['searchtags']) ? explode(' ', $_GET['searchtags']) : []; | 704 | $filteringTags = isset($_GET['searchtags']) ? explode(' ', $_GET['searchtags']) : []; |
690 | $tags = $LINKSDB->linksCountPerTag($filteringTags, $visibility); | 705 | $tags = $bookmarkService->bookmarksCountPerTag($filteringTags, $visibility); |
691 | foreach ($filteringTags as $tag) { | 706 | foreach ($filteringTags as $tag) { |
692 | if (array_key_exists($tag, $tags)) { | 707 | if (array_key_exists($tag, $tags)) { |
693 | unset($tags[$tag]); | 708 | unset($tags[$tag]); |
@@ -717,7 +732,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
717 | 732 | ||
718 | // Daily page. | 733 | // Daily page. |
719 | if ($targetPage == Router::$PAGE_DAILY) { | 734 | if ($targetPage == Router::$PAGE_DAILY) { |
720 | showDaily($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager); | 735 | showDaily($PAGE, $bookmarkService, $conf, $pluginManager, $loginManager); |
721 | } | 736 | } |
722 | 737 | ||
723 | // ATOM and RSS feed. | 738 | // ATOM and RSS feed. |
@@ -738,8 +753,16 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
738 | exit; | 753 | exit; |
739 | } | 754 | } |
740 | 755 | ||
756 | $factory = new FormatterFactory($conf); | ||
741 | // Generate data. | 757 | // Generate data. |
742 | $feedGenerator = new FeedBuilder($LINKSDB, $feedType, $_SERVER, $_GET, $loginManager->isLoggedIn()); | 758 | $feedGenerator = new FeedBuilder( |
759 | $bookmarkService, | ||
760 | $factory->getFormatter(), | ||
761 | $feedType, | ||
762 | $_SERVER, | ||
763 | $_GET, | ||
764 | $loginManager->isLoggedIn() | ||
765 | ); | ||
743 | $feedGenerator->setLocale(strtolower(setlocale(LC_COLLATE, 0))); | 766 | $feedGenerator->setLocale(strtolower(setlocale(LC_COLLATE, 0))); |
744 | $feedGenerator->setHideDates($conf->get('privacy.hide_timestamps') && !$loginManager->isLoggedIn()); | 767 | $feedGenerator->setHideDates($conf->get('privacy.hide_timestamps') && !$loginManager->isLoggedIn()); |
745 | $feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$conf->get('feed.rss_permalinks')); | 768 | $feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$conf->get('feed.rss_permalinks')); |
@@ -845,7 +868,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
845 | exit; | 868 | exit; |
846 | } | 869 | } |
847 | 870 | ||
848 | // -------- User wants to change the number of links per page (linksperpage=...) | 871 | // -------- User wants to change the number of bookmarks per page (linksperpage=...) |
849 | if (isset($_GET['linksperpage'])) { | 872 | if (isset($_GET['linksperpage'])) { |
850 | if (is_numeric($_GET['linksperpage'])) { | 873 | if (is_numeric($_GET['linksperpage'])) { |
851 | $_SESSION['LINKS_PER_PAGE']=abs(intval($_GET['linksperpage'])); | 874 | $_SESSION['LINKS_PER_PAGE']=abs(intval($_GET['linksperpage'])); |
@@ -860,19 +883,19 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
860 | exit; | 883 | exit; |
861 | } | 884 | } |
862 | 885 | ||
863 | // -------- User wants to see only private links (toggle) | 886 | // -------- User wants to see only private bookmarks (toggle) |
864 | if (isset($_GET['visibility'])) { | 887 | if (isset($_GET['visibility'])) { |
865 | if ($_GET['visibility'] === 'private') { | 888 | if ($_GET['visibility'] === 'private') { |
866 | // Visibility not set or not already private, set private, otherwise reset it | 889 | // Visibility not set or not already private, set private, otherwise reset it |
867 | if (empty($_SESSION['visibility']) || $_SESSION['visibility'] !== 'private') { | 890 | if (empty($_SESSION['visibility']) || $_SESSION['visibility'] !== 'private') { |
868 | // See only private links | 891 | // See only private bookmarks |
869 | $_SESSION['visibility'] = 'private'; | 892 | $_SESSION['visibility'] = 'private'; |
870 | } else { | 893 | } else { |
871 | unset($_SESSION['visibility']); | 894 | unset($_SESSION['visibility']); |
872 | } | 895 | } |
873 | } elseif ($_GET['visibility'] === 'public') { | 896 | } elseif ($_GET['visibility'] === 'public') { |
874 | if (empty($_SESSION['visibility']) || $_SESSION['visibility'] !== 'public') { | 897 | if (empty($_SESSION['visibility']) || $_SESSION['visibility'] !== 'public') { |
875 | // See only public links | 898 | // See only public bookmarks |
876 | $_SESSION['visibility'] = 'public'; | 899 | $_SESSION['visibility'] = 'public'; |
877 | } else { | 900 | } else { |
878 | unset($_SESSION['visibility']); | 901 | unset($_SESSION['visibility']); |
@@ -888,7 +911,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
888 | exit; | 911 | exit; |
889 | } | 912 | } |
890 | 913 | ||
891 | // -------- User wants to see only untagged links (toggle) | 914 | // -------- User wants to see only untagged bookmarks (toggle) |
892 | if (isset($_GET['untaggedonly'])) { | 915 | if (isset($_GET['untaggedonly'])) { |
893 | $_SESSION['untaggedonly'] = empty($_SESSION['untaggedonly']); | 916 | $_SESSION['untaggedonly'] = empty($_SESSION['untaggedonly']); |
894 | 917 | ||
@@ -916,7 +939,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
916 | exit; | 939 | exit; |
917 | } | 940 | } |
918 | 941 | ||
919 | showLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager); | 942 | showLinkList($PAGE, $bookmarkService, $conf, $pluginManager, $loginManager); |
920 | if (isset($_GET['edit_link'])) { | 943 | if (isset($_GET['edit_link'])) { |
921 | header('Location: ?do=login&edit_link='. escape($_GET['edit_link'])); | 944 | header('Location: ?do=login&edit_link='. escape($_GET['edit_link'])); |
922 | exit; | 945 | exit; |
@@ -1022,7 +1045,11 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1022 | $conf->set('privacy.hide_public_links', !empty($_POST['hidePublicLinks'])); | 1045 | $conf->set('privacy.hide_public_links', !empty($_POST['hidePublicLinks'])); |
1023 | $conf->set('api.enabled', !empty($_POST['enableApi'])); | 1046 | $conf->set('api.enabled', !empty($_POST['enableApi'])); |
1024 | $conf->set('api.secret', escape($_POST['apiSecret'])); | 1047 | $conf->set('api.secret', escape($_POST['apiSecret'])); |
1025 | $conf->set('translation.language', escape($_POST['language'])); | 1048 | $conf->set('formatter', escape($_POST['formatter'])); |
1049 | |||
1050 | if (! empty($_POST['language'])) { | ||
1051 | $conf->set('translation.language', escape($_POST['language'])); | ||
1052 | } | ||
1026 | 1053 | ||
1027 | $thumbnailsMode = extension_loaded('gd') ? $_POST['enableThumbnails'] : Thumbnailer::MODE_NONE; | 1054 | $thumbnailsMode = extension_loaded('gd') ? $_POST['enableThumbnails'] : Thumbnailer::MODE_NONE; |
1028 | if ($thumbnailsMode !== Thumbnailer::MODE_NONE | 1055 | if ($thumbnailsMode !== Thumbnailer::MODE_NONE |
@@ -1056,6 +1083,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1056 | $PAGE->assign('title', $conf->get('general.title')); | 1083 | $PAGE->assign('title', $conf->get('general.title')); |
1057 | $PAGE->assign('theme', $conf->get('resource.theme')); | 1084 | $PAGE->assign('theme', $conf->get('resource.theme')); |
1058 | $PAGE->assign('theme_available', ThemeUtils::getThemes($conf->get('resource.raintpl_tpl'))); | 1085 | $PAGE->assign('theme_available', ThemeUtils::getThemes($conf->get('resource.raintpl_tpl'))); |
1086 | $PAGE->assign('formatter_available', ['default', 'markdown']); | ||
1059 | list($continents, $cities) = generateTimeZoneData( | 1087 | list($continents, $cities) = generateTimeZoneData( |
1060 | timezone_identifiers_list(), | 1088 | timezone_identifiers_list(), |
1061 | $conf->get('general.timezone') | 1089 | $conf->get('general.timezone') |
@@ -1093,17 +1121,25 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1093 | } | 1121 | } |
1094 | 1122 | ||
1095 | $toTag = isset($_POST['totag']) ? escape($_POST['totag']) : null; | 1123 | $toTag = isset($_POST['totag']) ? escape($_POST['totag']) : null; |
1096 | $alteredLinks = $LINKSDB->renameTag(escape($_POST['fromtag']), $toTag); | 1124 | $fromTag = escape($_POST['fromtag']); |
1097 | $LINKSDB->save($conf->get('resource.page_cache')); | 1125 | $count = 0; |
1098 | foreach ($alteredLinks as $link) { | 1126 | $bookmarks = $bookmarkService->search(['searchtags' => $fromTag], BookmarkFilter::$ALL, true); |
1099 | $history->updateLink($link); | 1127 | foreach ($bookmarks as $bookmark) { |
1128 | if ($toTag) { | ||
1129 | $bookmark->renameTag($fromTag, $toTag); | ||
1130 | } else { | ||
1131 | $bookmark->deleteTag($fromTag); | ||
1132 | } | ||
1133 | $bookmarkService->set($bookmark, false); | ||
1134 | $history->updateLink($bookmark); | ||
1135 | $count++; | ||
1100 | } | 1136 | } |
1137 | $bookmarkService->save(); | ||
1101 | $delete = empty($_POST['totag']); | 1138 | $delete = empty($_POST['totag']); |
1102 | $redirect = $delete ? 'do=changetag' : 'searchtags='. urlencode(escape($_POST['totag'])); | 1139 | $redirect = $delete ? 'do=changetag' : 'searchtags='. urlencode(escape($_POST['totag'])); |
1103 | $count = count($alteredLinks); | ||
1104 | $alert = $delete | 1140 | $alert = $delete |
1105 | ? sprintf(t('The tag was removed from %d link.', 'The tag was removed from %d links.', $count), $count) | 1141 | ? sprintf(t('The tag was removed from %d link.', 'The tag was removed from %d bookmarks.', $count), $count) |
1106 | : sprintf(t('The tag was renamed in %d link.', 'The tag was renamed in %d links.', $count), $count); | 1142 | : sprintf(t('The tag was renamed in %d link.', 'The tag was renamed in %d bookmarks.', $count), $count); |
1107 | echo '<script>alert("'. $alert .'");document.location=\'?'. $redirect .'\';</script>'; | 1143 | echo '<script>alert("'. $alert .'");document.location=\'?'. $redirect .'\';</script>'; |
1108 | exit; | 1144 | exit; |
1109 | } | 1145 | } |
@@ -1123,69 +1159,37 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1123 | } | 1159 | } |
1124 | 1160 | ||
1125 | // lf_id should only be present if the link exists. | 1161 | // lf_id should only be present if the link exists. |
1126 | $id = isset($_POST['lf_id']) ? intval(escape($_POST['lf_id'])) : $LINKSDB->getNextId(); | 1162 | $id = isset($_POST['lf_id']) ? intval(escape($_POST['lf_id'])) : null; |
1127 | $link['id'] = $id; | 1163 | if ($id && $bookmarkService->exists($id)) { |
1128 | // Linkdate is kept here to: | ||
1129 | // - use the same permalink for notes as they're displayed when creating them | ||
1130 | // - let users hack creation date of their posts | ||
1131 | // See: https://shaarli.readthedocs.io/en/master/guides/various-hacks/#changing-the-timestamp-for-a-shaare | ||
1132 | $linkdate = escape($_POST['lf_linkdate']); | ||
1133 | $link['created'] = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $linkdate); | ||
1134 | if (isset($LINKSDB[$id])) { | ||
1135 | // Edit | 1164 | // Edit |
1136 | $link['updated'] = new DateTime(); | 1165 | $bookmark = $bookmarkService->get($id); |
1137 | $link['shorturl'] = $LINKSDB[$id]['shorturl']; | ||
1138 | $link['sticky'] = isset($LINKSDB[$id]['sticky']) ? $LINKSDB[$id]['sticky'] : false; | ||
1139 | $new = false; | ||
1140 | } else { | 1166 | } else { |
1141 | // New link | 1167 | // New link |
1142 | $link['updated'] = null; | 1168 | $bookmark = new Bookmark(); |
1143 | $link['shorturl'] = link_small_hash($link['created'], $id); | ||
1144 | $link['sticky'] = false; | ||
1145 | $new = true; | ||
1146 | } | ||
1147 | |||
1148 | // Remove multiple spaces. | ||
1149 | $tags = trim(preg_replace('/\s\s+/', ' ', $_POST['lf_tags'])); | ||
1150 | // Remove first '-' char in tags. | ||
1151 | $tags = preg_replace('/(^| )\-/', '$1', $tags); | ||
1152 | // Remove duplicates. | ||
1153 | $tags = implode(' ', array_unique(explode(' ', $tags))); | ||
1154 | |||
1155 | if (empty(trim($_POST['lf_url']))) { | ||
1156 | $_POST['lf_url'] = '?' . smallHash($linkdate . $id); | ||
1157 | } | 1169 | } |
1158 | $url = whitelist_protocols(trim($_POST['lf_url']), $conf->get('security.allowed_protocols')); | ||
1159 | 1170 | ||
1160 | $link = array_merge($link, [ | 1171 | $bookmark->setTitle($_POST['lf_title']); |
1161 | 'title' => trim($_POST['lf_title']), | 1172 | $bookmark->setDescription($_POST['lf_description']); |
1162 | 'url' => $url, | 1173 | $bookmark->setUrl($_POST['lf_url'], $conf->get('security.allowed_protocols')); |
1163 | 'description' => $_POST['lf_description'], | 1174 | $bookmark->setPrivate(isset($_POST['lf_private'])); |
1164 | 'private' => (isset($_POST['lf_private']) ? 1 : 0), | 1175 | $bookmark->setTagsString($_POST['lf_tags']); |
1165 | 'tags' => str_replace(',', ' ', $tags), | ||
1166 | ]); | ||
1167 | |||
1168 | // If title is empty, use the URL as title. | ||
1169 | if ($link['title'] == '') { | ||
1170 | $link['title'] = $link['url']; | ||
1171 | } | ||
1172 | 1176 | ||
1173 | if ($conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE | 1177 | if ($conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE |
1174 | && ! is_note($link['url']) | 1178 | && ! $bookmark->isNote() |
1175 | ) { | 1179 | ) { |
1176 | $thumbnailer = new Thumbnailer($conf); | 1180 | $thumbnailer = new Thumbnailer($conf); |
1177 | $link['thumbnail'] = $thumbnailer->get($url); | 1181 | $bookmark->setThumbnail($thumbnailer->get($bookmark->getUrl())); |
1178 | } | 1182 | } |
1183 | $bookmarkService->addOrSet($bookmark, false); | ||
1179 | 1184 | ||
1180 | $pluginManager->executeHooks('save_link', $link); | 1185 | // To preserve backward compatibility with 3rd parties, plugins still use arrays |
1186 | $factory = new FormatterFactory($conf); | ||
1187 | $formatter = $factory->getFormatter('raw'); | ||
1188 | $data = $formatter->format($bookmark); | ||
1189 | $pluginManager->executeHooks('save_link', $data); | ||
1181 | 1190 | ||
1182 | $LINKSDB[$id] = $link; | 1191 | $bookmark->fromArray($data); |
1183 | $LINKSDB->save($conf->get('resource.page_cache')); | 1192 | $bookmarkService->set($bookmark); |
1184 | if ($new) { | ||
1185 | $history->addLink($link); | ||
1186 | } else { | ||
1187 | $history->updateLink($link); | ||
1188 | } | ||
1189 | 1193 | ||
1190 | // If we are called from the bookmarklet, we must close the popup: | 1194 | // If we are called from the bookmarklet, we must close the popup: |
1191 | if (isset($_GET['source']) && ($_GET['source']=='bookmarklet' || $_GET['source']=='firefoxsocialapi')) { | 1195 | if (isset($_GET['source']) && ($_GET['source']=='bookmarklet' || $_GET['source']=='firefoxsocialapi')) { |
@@ -1196,32 +1200,12 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1196 | $returnurl = !empty($_POST['returnurl']) ? $_POST['returnurl'] : '?'; | 1200 | $returnurl = !empty($_POST['returnurl']) ? $_POST['returnurl'] : '?'; |
1197 | $location = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); | 1201 | $location = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); |
1198 | // Scroll to the link which has been edited. | 1202 | // Scroll to the link which has been edited. |
1199 | $location .= '#' . $link['shorturl']; | 1203 | $location .= '#' . $bookmark->getShortUrl(); |
1200 | // After saving the link, redirect to the page the user was on. | 1204 | // After saving the link, redirect to the page the user was on. |
1201 | header('Location: '. $location); | 1205 | header('Location: '. $location); |
1202 | exit; | 1206 | exit; |
1203 | } | 1207 | } |
1204 | 1208 | ||
1205 | // -------- User clicked the "Cancel" button when editing a link. | ||
1206 | if (isset($_POST['cancel_edit'])) { | ||
1207 | $id = isset($_POST['lf_id']) ? (int) escape($_POST['lf_id']) : false; | ||
1208 | if (! isset($LINKSDB[$id])) { | ||
1209 | header('Location: ?'); | ||
1210 | } | ||
1211 | // If we are called from the bookmarklet, we must close the popup: | ||
1212 | if (isset($_GET['source']) && ($_GET['source']=='bookmarklet' || $_GET['source']=='firefoxsocialapi')) { | ||
1213 | echo '<script>self.close();</script>'; | ||
1214 | exit; | ||
1215 | } | ||
1216 | $link = $LINKSDB[$id]; | ||
1217 | $returnurl = ( isset($_POST['returnurl']) ? $_POST['returnurl'] : '?' ); | ||
1218 | // Scroll to the link which has been edited. | ||
1219 | $returnurl .= '#'. $link['shorturl']; | ||
1220 | $returnurl = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); | ||
1221 | header('Location: '.$returnurl); // After canceling, redirect to the page the user was on. | ||
1222 | exit; | ||
1223 | } | ||
1224 | |||
1225 | // -------- User clicked the "Delete" button when editing a link: Delete link from database. | 1209 | // -------- User clicked the "Delete" button when editing a link: Delete link from database. |
1226 | if ($targetPage == Router::$PAGE_DELETELINK) { | 1210 | if ($targetPage == Router::$PAGE_DELETELINK) { |
1227 | if (! $sessionManager->checkToken($_GET['token'])) { | 1211 | if (! $sessionManager->checkToken($_GET['token'])) { |
@@ -1231,23 +1215,31 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1231 | $ids = trim($_GET['lf_linkdate']); | 1215 | $ids = trim($_GET['lf_linkdate']); |
1232 | if (strpos($ids, ' ') !== false) { | 1216 | if (strpos($ids, ' ') !== false) { |
1233 | // multiple, space-separated ids provided | 1217 | // multiple, space-separated ids provided |
1234 | $ids = array_values(array_filter(preg_split('/\s+/', escape($ids)))); | 1218 | $ids = array_values(array_filter( |
1219 | preg_split('/\s+/', escape($ids)), | ||
1220 | function ($item) { | ||
1221 | return $item !== ''; | ||
1222 | } | ||
1223 | )); | ||
1235 | } else { | 1224 | } else { |
1236 | // only a single id provided | 1225 | // only a single id provided |
1226 | $shortUrl = $bookmarkService->get($ids)->getShortUrl(); | ||
1237 | $ids = [$ids]; | 1227 | $ids = [$ids]; |
1238 | } | 1228 | } |
1239 | // assert at least one id is given | 1229 | // assert at least one id is given |
1240 | if (!count($ids)) { | 1230 | if (!count($ids)) { |
1241 | die('no id provided'); | 1231 | die('no id provided'); |
1242 | } | 1232 | } |
1233 | $factory = new FormatterFactory($conf); | ||
1234 | $formatter = $factory->getFormatter('raw'); | ||
1243 | foreach ($ids as $id) { | 1235 | foreach ($ids as $id) { |
1244 | $id = (int) escape($id); | 1236 | $id = (int) escape($id); |
1245 | $link = $LINKSDB[$id]; | 1237 | $bookmark = $bookmarkService->get($id); |
1246 | $pluginManager->executeHooks('delete_link', $link); | 1238 | $data = $formatter->format($bookmark); |
1247 | $history->deleteLink($link); | 1239 | $pluginManager->executeHooks('delete_link', $data); |
1248 | unset($LINKSDB[$id]); | 1240 | $bookmarkService->remove($bookmark, false); |
1249 | } | 1241 | } |
1250 | $LINKSDB->save($conf->get('resource.page_cache')); // save to disk | 1242 | $bookmarkService->save(); |
1251 | 1243 | ||
1252 | // If we are called from the bookmarklet, we must close the popup: | 1244 | // If we are called from the bookmarklet, we must close the popup: |
1253 | if (isset($_GET['source']) && ($_GET['source']=='bookmarklet' || $_GET['source']=='firefoxsocialapi')) { | 1245 | if (isset($_GET['source']) && ($_GET['source']=='bookmarklet' || $_GET['source']=='firefoxsocialapi')) { |
@@ -1261,7 +1253,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1261 | $location = generateLocation( | 1253 | $location = generateLocation( |
1262 | $_SERVER['HTTP_REFERER'], | 1254 | $_SERVER['HTTP_REFERER'], |
1263 | $_SERVER['HTTP_HOST'], | 1255 | $_SERVER['HTTP_HOST'], |
1264 | ['delete_link', 'edit_link', $link['shorturl']] | 1256 | ['delete_link', 'edit_link', ! empty($shortUrl) ? $shortUrl : null] |
1265 | ); | 1257 | ); |
1266 | } | 1258 | } |
1267 | 1259 | ||
@@ -1294,14 +1286,21 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1294 | } else { | 1286 | } else { |
1295 | $private = $_GET['newVisibility'] === 'private'; | 1287 | $private = $_GET['newVisibility'] === 'private'; |
1296 | } | 1288 | } |
1289 | $factory = new FormatterFactory($conf); | ||
1290 | $formatter = $factory->getFormatter('raw'); | ||
1297 | foreach ($ids as $id) { | 1291 | foreach ($ids as $id) { |
1298 | $id = (int) escape($id); | 1292 | $id = (int) escape($id); |
1299 | $link = $LINKSDB[$id]; | 1293 | $bookmark = $bookmarkService->get($id); |
1300 | $link['private'] = $private; | 1294 | $bookmark->setPrivate($private); |
1301 | $pluginManager->executeHooks('save_link', $link); | 1295 | |
1302 | $LINKSDB[$id] = $link; | 1296 | // To preserve backward compatibility with 3rd parties, plugins still use arrays |
1297 | $data = $formatter->format($bookmark); | ||
1298 | $pluginManager->executeHooks('save_link', $data); | ||
1299 | $bookmark->fromArray($data); | ||
1300 | |||
1301 | $bookmarkService->set($bookmark); | ||
1303 | } | 1302 | } |
1304 | $LINKSDB->save($conf->get('resource.page_cache')); // save to disk | 1303 | $bookmarkService->save(); |
1305 | 1304 | ||
1306 | $location = '?'; | 1305 | $location = '?'; |
1307 | if (isset($_SERVER['HTTP_REFERER'])) { | 1306 | if (isset($_SERVER['HTTP_REFERER'])) { |
@@ -1317,17 +1316,22 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1317 | // -------- User clicked the "EDIT" button on a link: Display link edit form. | 1316 | // -------- User clicked the "EDIT" button on a link: Display link edit form. |
1318 | if (isset($_GET['edit_link'])) { | 1317 | if (isset($_GET['edit_link'])) { |
1319 | $id = (int) escape($_GET['edit_link']); | 1318 | $id = (int) escape($_GET['edit_link']); |
1320 | $link = $LINKSDB[$id]; // Read database | 1319 | try { |
1321 | if (!$link) { | 1320 | $link = $bookmarkService->get($id); // Read database |
1321 | } catch (BookmarkNotFoundException $e) { | ||
1322 | // Link not found in database. | ||
1322 | header('Location: ?'); | 1323 | header('Location: ?'); |
1323 | exit; | 1324 | exit; |
1324 | } // Link not found in database. | 1325 | } |
1325 | $link['linkdate'] = $link['created']->format(LinkDB::LINK_DATE_FORMAT); | 1326 | |
1327 | $factory = new FormatterFactory($conf); | ||
1328 | $formatter = $factory->getFormatter('raw'); | ||
1329 | $formattedLink = $formatter->format($link); | ||
1326 | $data = array( | 1330 | $data = array( |
1327 | 'link' => $link, | 1331 | 'link' => $formattedLink, |
1328 | 'link_is_new' => false, | 1332 | 'link_is_new' => false, |
1329 | 'http_referer' => (isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''), | 1333 | 'http_referer' => (isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''), |
1330 | 'tags' => $LINKSDB->linksCountPerTag(), | 1334 | 'tags' => $bookmarkService->bookmarksCountPerTag(), |
1331 | ); | 1335 | ); |
1332 | $pluginManager->executeHooks('render_editlink', $data); | 1336 | $pluginManager->executeHooks('render_editlink', $data); |
1333 | 1337 | ||
@@ -1346,10 +1350,9 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1346 | 1350 | ||
1347 | $link_is_new = false; | 1351 | $link_is_new = false; |
1348 | // Check if URL is not already in database (in this case, we will edit the existing link) | 1352 | // Check if URL is not already in database (in this case, we will edit the existing link) |
1349 | $link = $LINKSDB->getLinkFromUrl($url); | 1353 | $bookmark = $bookmarkService->findByUrl($url); |
1350 | if (! $link) { | 1354 | if (! $bookmark) { |
1351 | $link_is_new = true; | 1355 | $link_is_new = true; |
1352 | $linkdate = strval(date(LinkDB::LINK_DATE_FORMAT)); | ||
1353 | // Get title if it was provided in URL (by the bookmarklet). | 1356 | // Get title if it was provided in URL (by the bookmarklet). |
1354 | $title = empty($_GET['title']) ? '' : escape($_GET['title']); | 1357 | $title = empty($_GET['title']) ? '' : escape($_GET['title']); |
1355 | // Get description if it was provided in URL (by the bookmarklet). [Bronco added that] | 1358 | // Get description if it was provided in URL (by the bookmarklet). [Bronco added that] |
@@ -1375,32 +1378,32 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1375 | } | 1378 | } |
1376 | 1379 | ||
1377 | if ($url == '') { | 1380 | if ($url == '') { |
1378 | $url = '?' . smallHash($linkdate . $LINKSDB->getNextId()); | ||
1379 | $title = $conf->get('general.default_note_title', t('Note: ')); | 1381 | $title = $conf->get('general.default_note_title', t('Note: ')); |
1380 | } | 1382 | } |
1381 | $url = escape($url); | 1383 | $url = escape($url); |
1382 | $title = escape($title); | 1384 | $title = escape($title); |
1383 | 1385 | ||
1384 | $link = array( | 1386 | $link = [ |
1385 | 'linkdate' => $linkdate, | ||
1386 | 'title' => $title, | 1387 | 'title' => $title, |
1387 | 'url' => $url, | 1388 | 'url' => $url, |
1388 | 'description' => $description, | 1389 | 'description' => $description, |
1389 | 'tags' => $tags, | 1390 | 'tags' => $tags, |
1390 | 'private' => $private, | 1391 | 'private' => $private, |
1391 | ); | 1392 | ]; |
1392 | } else { | 1393 | } else { |
1393 | $link['linkdate'] = $link['created']->format(LinkDB::LINK_DATE_FORMAT); | 1394 | $factory = new FormatterFactory($conf); |
1395 | $formatter = $factory->getFormatter('raw'); | ||
1396 | $link = $formatter->format($bookmark); | ||
1394 | } | 1397 | } |
1395 | 1398 | ||
1396 | $data = array( | 1399 | $data = [ |
1397 | 'link' => $link, | 1400 | 'link' => $link, |
1398 | 'link_is_new' => $link_is_new, | 1401 | 'link_is_new' => $link_is_new, |
1399 | 'http_referer' => (isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''), | 1402 | 'http_referer' => (isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''), |
1400 | 'source' => (isset($_GET['source']) ? $_GET['source'] : ''), | 1403 | 'source' => (isset($_GET['source']) ? $_GET['source'] : ''), |
1401 | 'tags' => $LINKSDB->linksCountPerTag(), | 1404 | 'tags' => $bookmarkService->bookmarksCountPerTag(), |
1402 | 'default_private_links' => $conf->get('privacy.default_private_links', false), | 1405 | 'default_private_links' => $conf->get('privacy.default_private_links', false), |
1403 | ); | 1406 | ]; |
1404 | $pluginManager->executeHooks('render_editlink', $data); | 1407 | $pluginManager->executeHooks('render_editlink', $data); |
1405 | 1408 | ||
1406 | foreach ($data as $key => $value) { | 1409 | foreach ($data as $key => $value) { |
@@ -1413,7 +1416,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1413 | } | 1416 | } |
1414 | 1417 | ||
1415 | if ($targetPage == Router::$PAGE_PINLINK) { | 1418 | if ($targetPage == Router::$PAGE_PINLINK) { |
1416 | if (! isset($_GET['id']) || empty($LINKSDB[$_GET['id']])) { | 1419 | if (! isset($_GET['id']) || !$bookmarkService->exists($_GET['id'])) { |
1417 | // FIXME! Use a proper error system. | 1420 | // FIXME! Use a proper error system. |
1418 | $msg = t('Invalid link ID provided'); | 1421 | $msg = t('Invalid link ID provided'); |
1419 | echo '<script>alert("'. $msg .'");document.location=\''. index_url($_SERVER) .'\';</script>'; | 1422 | echo '<script>alert("'. $msg .'");document.location=\''. index_url($_SERVER) .'\';</script>'; |
@@ -1423,16 +1426,15 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1423 | die('Wrong token.'); | 1426 | die('Wrong token.'); |
1424 | } | 1427 | } |
1425 | 1428 | ||
1426 | $link = $LINKSDB[$_GET['id']]; | 1429 | $link = $bookmarkService->get($_GET['id']); |
1427 | $link['sticky'] = ! $link['sticky']; | 1430 | $link->setSticky(! $link->isSticky()); |
1428 | $LINKSDB[(int) $_GET['id']] = $link; | 1431 | $bookmarkService->set($link); |
1429 | $LINKSDB->save($conf->get('resource.page_cache')); | ||
1430 | header('Location: '.index_url($_SERVER)); | 1432 | header('Location: '.index_url($_SERVER)); |
1431 | exit; | 1433 | exit; |
1432 | } | 1434 | } |
1433 | 1435 | ||
1434 | if ($targetPage == Router::$PAGE_EXPORT) { | 1436 | if ($targetPage == Router::$PAGE_EXPORT) { |
1435 | // Export links as a Netscape Bookmarks file | 1437 | // Export bookmarks as a Netscape Bookmarks file |
1436 | 1438 | ||
1437 | if (empty($_GET['selection'])) { | 1439 | if (empty($_GET['selection'])) { |
1438 | $PAGE->assign('pagetitle', t('Export') .' - '. $conf->get('general.title', 'Shaarli')); | 1440 | $PAGE->assign('pagetitle', t('Export') .' - '. $conf->get('general.title', 'Shaarli')); |
@@ -1449,10 +1451,13 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1449 | } | 1451 | } |
1450 | 1452 | ||
1451 | try { | 1453 | try { |
1454 | $factory = new FormatterFactory($conf); | ||
1455 | $formatter = $factory->getFormatter('raw'); | ||
1452 | $PAGE->assign( | 1456 | $PAGE->assign( |
1453 | 'links', | 1457 | 'links', |
1454 | NetscapeBookmarkUtils::filterAndFormat( | 1458 | NetscapeBookmarkUtils::filterAndFormat( |
1455 | $LINKSDB, | 1459 | $bookmarkService, |
1460 | $formatter, | ||
1456 | $selection, | 1461 | $selection, |
1457 | $prependNoteUrl, | 1462 | $prependNoteUrl, |
1458 | index_url($_SERVER) | 1463 | index_url($_SERVER) |
@@ -1467,7 +1472,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1467 | header('Content-Type: text/html; charset=utf-8'); | 1472 | header('Content-Type: text/html; charset=utf-8'); |
1468 | header( | 1473 | header( |
1469 | 'Content-disposition: attachment; filename=bookmarks_' | 1474 | 'Content-disposition: attachment; filename=bookmarks_' |
1470 | .$selection.'_'.$now->format(LinkDB::LINK_DATE_FORMAT).'.html' | 1475 | .$selection.'_'.$now->format(Bookmark::LINK_DATE_FORMAT).'.html' |
1471 | ); | 1476 | ); |
1472 | $PAGE->assign('date', $now->format(DateTime::RFC822)); | 1477 | $PAGE->assign('date', $now->format(DateTime::RFC822)); |
1473 | $PAGE->assign('eol', PHP_EOL); | 1478 | $PAGE->assign('eol', PHP_EOL); |
@@ -1521,7 +1526,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1521 | $status = NetscapeBookmarkUtils::import( | 1526 | $status = NetscapeBookmarkUtils::import( |
1522 | $_POST, | 1527 | $_POST, |
1523 | $_FILES, | 1528 | $_FILES, |
1524 | $LINKSDB, | 1529 | $bookmarkService, |
1525 | $conf, | 1530 | $conf, |
1526 | $history | 1531 | $history |
1527 | ); | 1532 | ); |
@@ -1592,19 +1597,19 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1592 | // Get a fresh token | 1597 | // Get a fresh token |
1593 | if ($targetPage == Router::$GET_TOKEN) { | 1598 | if ($targetPage == Router::$GET_TOKEN) { |
1594 | header('Content-Type:text/plain'); | 1599 | header('Content-Type:text/plain'); |
1595 | echo $sessionManager->generateToken($conf); | 1600 | echo $sessionManager->generateToken(); |
1596 | exit; | 1601 | exit; |
1597 | } | 1602 | } |
1598 | 1603 | ||
1599 | // -------- Thumbnails Update | 1604 | // -------- Thumbnails Update |
1600 | if ($targetPage == Router::$PAGE_THUMBS_UPDATE) { | 1605 | if ($targetPage == Router::$PAGE_THUMBS_UPDATE) { |
1601 | $ids = []; | 1606 | $ids = []; |
1602 | foreach ($LINKSDB as $link) { | 1607 | foreach ($bookmarkService->search() as $bookmark) { |
1603 | // A note or not HTTP(S) | 1608 | // A note or not HTTP(S) |
1604 | if (is_note($link['url']) || ! startsWith(strtolower($link['url']), 'http')) { | 1609 | if ($bookmark->isNote() || ! startsWith(strtolower($bookmark->getUrl()), 'http')) { |
1605 | continue; | 1610 | continue; |
1606 | } | 1611 | } |
1607 | $ids[] = $link['id']; | 1612 | $ids[] = $bookmark->getId(); |
1608 | } | 1613 | } |
1609 | $PAGE->assign('ids', $ids); | 1614 | $PAGE->assign('ids', $ids); |
1610 | $PAGE->assign('pagetitle', t('Thumbnails update') .' - '. $conf->get('general.title', 'Shaarli')); | 1615 | $PAGE->assign('pagetitle', t('Thumbnails update') .' - '. $conf->get('general.title', 'Shaarli')); |
@@ -1619,37 +1624,40 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1619 | exit; | 1624 | exit; |
1620 | } | 1625 | } |
1621 | $id = (int) $_POST['id']; | 1626 | $id = (int) $_POST['id']; |
1622 | if (empty($LINKSDB[$id])) { | 1627 | if (! $bookmarkService->exists($id)) { |
1623 | http_response_code(404); | 1628 | http_response_code(404); |
1624 | exit; | 1629 | exit; |
1625 | } | 1630 | } |
1626 | $thumbnailer = new Thumbnailer($conf); | 1631 | $thumbnailer = new Thumbnailer($conf); |
1627 | $link = $LINKSDB[$id]; | 1632 | $bookmark = $bookmarkService->get($id); |
1628 | $link['thumbnail'] = $thumbnailer->get($link['url']); | 1633 | $bookmark->setThumbnail($thumbnailer->get($bookmark->getUrl())); |
1629 | $LINKSDB[$id] = $link; | 1634 | $bookmarkService->set($bookmark); |
1630 | $LINKSDB->save($conf->get('resource.page_cache')); | ||
1631 | 1635 | ||
1632 | echo json_encode($link); | 1636 | $factory = new FormatterFactory($conf); |
1637 | echo json_encode($factory->getFormatter('raw')->format($bookmark)); | ||
1633 | exit; | 1638 | exit; |
1634 | } | 1639 | } |
1635 | 1640 | ||
1636 | // -------- Otherwise, simply display search form and links: | 1641 | // -------- Otherwise, simply display search form and bookmarks: |
1637 | showLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager); | 1642 | showLinkList($PAGE, $bookmarkService, $conf, $pluginManager, $loginManager); |
1638 | exit; | 1643 | exit; |
1639 | } | 1644 | } |
1640 | 1645 | ||
1641 | /** | 1646 | /** |
1642 | * Template for the list of links (<div id="linklist">) | 1647 | * Template for the list of bookmarks (<div id="linklist">) |
1643 | * This function fills all the necessary fields in the $PAGE for the template 'linklist.html' | 1648 | * This function fills all the necessary fields in the $PAGE for the template 'linklist.html' |
1644 | * | 1649 | * |
1645 | * @param pageBuilder $PAGE pageBuilder instance. | 1650 | * @param pageBuilder $PAGE pageBuilder instance. |
1646 | * @param LinkDB $LINKSDB LinkDB instance. | 1651 | * @param BookmarkServiceInterface $linkDb LinkDB instance. |
1647 | * @param ConfigManager $conf Configuration Manager instance. | 1652 | * @param ConfigManager $conf Configuration Manager instance. |
1648 | * @param PluginManager $pluginManager Plugin Manager instance. | 1653 | * @param PluginManager $pluginManager Plugin Manager instance. |
1649 | * @param LoginManager $loginManager LoginManager instance | 1654 | * @param LoginManager $loginManager LoginManager instance |
1650 | */ | 1655 | */ |
1651 | function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) | 1656 | function buildLinkList($PAGE, $linkDb, $conf, $pluginManager, $loginManager) |
1652 | { | 1657 | { |
1658 | $factory = new FormatterFactory($conf); | ||
1659 | $formatter = $factory->getFormatter(); | ||
1660 | |||
1653 | // Used in templates | 1661 | // Used in templates |
1654 | if (isset($_GET['searchtags'])) { | 1662 | if (isset($_GET['searchtags'])) { |
1655 | if (! empty($_GET['searchtags'])) { | 1663 | if (! empty($_GET['searchtags'])) { |
@@ -1666,19 +1674,19 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) | |||
1666 | if (! empty($_SERVER['QUERY_STRING']) | 1674 | if (! empty($_SERVER['QUERY_STRING']) |
1667 | && preg_match('/^[a-zA-Z0-9-_@]{6}($|&|#)/', $_SERVER['QUERY_STRING'])) { | 1675 | && preg_match('/^[a-zA-Z0-9-_@]{6}($|&|#)/', $_SERVER['QUERY_STRING'])) { |
1668 | try { | 1676 | try { |
1669 | $linksToDisplay = $LINKSDB->filterHash($_SERVER['QUERY_STRING']); | 1677 | $linksToDisplay = $linkDb->findByHash($_SERVER['QUERY_STRING']); |
1670 | } catch (LinkNotFoundException $e) { | 1678 | } catch (BookmarkNotFoundException $e) { |
1671 | $PAGE->render404($e->getMessage()); | 1679 | $PAGE->render404($e->getMessage()); |
1672 | exit; | 1680 | exit; |
1673 | } | 1681 | } |
1674 | } else { | 1682 | } else { |
1675 | // Filter links according search parameters. | 1683 | // Filter bookmarks according search parameters. |
1676 | $visibility = ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : ''; | 1684 | $visibility = ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : ''; |
1677 | $request = [ | 1685 | $request = [ |
1678 | 'searchtags' => $searchtags, | 1686 | 'searchtags' => $searchtags, |
1679 | 'searchterm' => $searchterm, | 1687 | 'searchterm' => $searchterm, |
1680 | ]; | 1688 | ]; |
1681 | $linksToDisplay = $LINKSDB->filterSearch($request, false, $visibility, !empty($_SESSION['untaggedonly'])); | 1689 | $linksToDisplay = $linkDb->search($request, $visibility, false, !empty($_SESSION['untaggedonly'])); |
1682 | } | 1690 | } |
1683 | 1691 | ||
1684 | // ---- Handle paging. | 1692 | // ---- Handle paging. |
@@ -1704,36 +1712,26 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) | |||
1704 | 1712 | ||
1705 | $linkDisp = array(); | 1713 | $linkDisp = array(); |
1706 | while ($i<$end && $i<count($keys)) { | 1714 | while ($i<$end && $i<count($keys)) { |
1707 | $link = $linksToDisplay[$keys[$i]]; | 1715 | $link = $formatter->format($linksToDisplay[$keys[$i]]); |
1708 | $link['description'] = format_description($link['description']); | ||
1709 | $classLi = ($i % 2) != 0 ? '' : 'publicLinkHightLight'; | ||
1710 | $link['class'] = $link['private'] == 0 ? $classLi : 'private'; | ||
1711 | $link['timestamp'] = $link['created']->getTimestamp(); | ||
1712 | if (! empty($link['updated'])) { | ||
1713 | $link['updated_timestamp'] = $link['updated']->getTimestamp(); | ||
1714 | } else { | ||
1715 | $link['updated_timestamp'] = ''; | ||
1716 | } | ||
1717 | $taglist = preg_split('/\s+/', $link['tags'], -1, PREG_SPLIT_NO_EMPTY); | ||
1718 | uasort($taglist, 'strcasecmp'); | ||
1719 | $link['taglist'] = $taglist; | ||
1720 | 1716 | ||
1721 | // Logged in, thumbnails enabled, not a note, | 1717 | // Logged in, thumbnails enabled, not a note, |
1722 | // and (never retrieved yet or no valid cache file) | 1718 | // and (never retrieved yet or no valid cache file) |
1723 | if ($loginManager->isLoggedIn() && $thumbnailsEnabled && $link['url'][0] != '?' | 1719 | if ($loginManager->isLoggedIn() |
1724 | && (! isset($link['thumbnail']) || ($link['thumbnail'] !== false && ! is_file($link['thumbnail']))) | 1720 | && $thumbnailsEnabled |
1721 | && !$linksToDisplay[$keys[$i]]->isNote() | ||
1722 | && $linksToDisplay[$keys[$i]]->getThumbnail() !== false | ||
1723 | && ! is_file($linksToDisplay[$keys[$i]]->getThumbnail()) | ||
1725 | ) { | 1724 | ) { |
1726 | $elem = $LINKSDB[$keys[$i]]; | 1725 | $linksToDisplay[$keys[$i]]->setThumbnail($thumbnailer->get($link['url'])); |
1727 | $elem['thumbnail'] = $thumbnailer->get($link['url']); | 1726 | $linkDb->set($linksToDisplay[$keys[$i]], false); |
1728 | $LINKSDB[$keys[$i]] = $elem; | ||
1729 | $updateDB = true; | 1727 | $updateDB = true; |
1730 | $link['thumbnail'] = $elem['thumbnail']; | 1728 | $link['thumbnail'] = $linksToDisplay[$keys[$i]]->getThumbnail(); |
1731 | } | 1729 | } |
1732 | 1730 | ||
1733 | // Check for both signs of a note: starting with ? and 7 chars long. | 1731 | // Check for both signs of a note: starting with ? and 7 chars long. |
1734 | if ($link['url'][0] === '?' && strlen($link['url']) === 7) { | 1732 | // if ($link['url'][0] === '?' && strlen($link['url']) === 7) { |
1735 | $link['url'] = index_url($_SERVER) . $link['url']; | 1733 | // $link['url'] = index_url($_SERVER) . $link['url']; |
1736 | } | 1734 | // } |
1737 | 1735 | ||
1738 | $linkDisp[$keys[$i]] = $link; | 1736 | $linkDisp[$keys[$i]] = $link; |
1739 | $i++; | 1737 | $i++; |
@@ -1741,7 +1739,7 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) | |||
1741 | 1739 | ||
1742 | // If we retrieved new thumbnails, we update the database. | 1740 | // If we retrieved new thumbnails, we update the database. |
1743 | if (!empty($updateDB)) { | 1741 | if (!empty($updateDB)) { |
1744 | $LINKSDB->save($conf->get('resource.page_cache')); | 1742 | $linkDb->save(); |
1745 | } | 1743 | } |
1746 | 1744 | ||
1747 | // Compute paging navigation | 1745 | // Compute paging navigation |
@@ -1771,7 +1769,7 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) | |||
1771 | 1769 | ||
1772 | // If there is only a single link, we change on-the-fly the title of the page. | 1770 | // If there is only a single link, we change on-the-fly the title of the page. |
1773 | if (count($linksToDisplay) == 1) { | 1771 | if (count($linksToDisplay) == 1) { |
1774 | $data['pagetitle'] = $linksToDisplay[$keys[0]]['title'] .' - '. $conf->get('general.title'); | 1772 | $data['pagetitle'] = $linksToDisplay[$keys[0]]->getTitle() .' - '. $conf->get('general.title'); |
1775 | } elseif (! empty($searchterm) || ! empty($searchtags)) { | 1773 | } elseif (! empty($searchterm) || ! empty($searchtags)) { |
1776 | $data['pagetitle'] = t('Search: '); | 1774 | $data['pagetitle'] = t('Search: '); |
1777 | $data['pagetitle'] .= ! empty($searchterm) ? $searchterm .' ' : ''; | 1775 | $data['pagetitle'] .= ! empty($searchterm) ? $searchterm .' ' : ''; |
@@ -1856,7 +1854,7 @@ function install($conf, $sessionManager, $loginManager) | |||
1856 | if (!empty($_POST['title'])) { | 1854 | if (!empty($_POST['title'])) { |
1857 | $conf->set('general.title', escape($_POST['title'])); | 1855 | $conf->set('general.title', escape($_POST['title'])); |
1858 | } else { | 1856 | } else { |
1859 | $conf->set('general.title', 'Shared links on '.escape(index_url($_SERVER))); | 1857 | $conf->set('general.title', 'Shared bookmarks on '.escape(index_url($_SERVER))); |
1860 | } | 1858 | } |
1861 | $conf->set('translation.language', escape($_POST['language'])); | 1859 | $conf->set('translation.language', escape($_POST['language'])); |
1862 | $conf->set('updates.check_updates', !empty($_POST['updateCheck'])); | 1860 | $conf->set('updates.check_updates', !empty($_POST['updateCheck'])); |
@@ -1881,9 +1879,16 @@ function install($conf, $sessionManager, $loginManager) | |||
1881 | echo '<script>alert("'. $e->getMessage() .'");document.location=\'?\';</script>'; | 1879 | echo '<script>alert("'. $e->getMessage() .'");document.location=\'?\';</script>'; |
1882 | exit; | 1880 | exit; |
1883 | } | 1881 | } |
1882 | |||
1883 | $history = new History($conf->get('resource.history')); | ||
1884 | $bookmarkService = new BookmarkFileService($conf, $history, true); | ||
1885 | if ($bookmarkService->count() === 0) { | ||
1886 | $bookmarkService->initialize(); | ||
1887 | } | ||
1888 | |||
1884 | echo '<script>alert(' | 1889 | echo '<script>alert(' |
1885 | .'"Shaarli is now configured. ' | 1890 | .'"Shaarli is now configured. ' |
1886 | .'Please enter your login/password and start shaaring your links!"' | 1891 | .'Please enter your login/password and start shaaring your bookmarks!"' |
1887 | .');document.location=\'?do=login\';</script>'; | 1892 | .');document.location=\'?do=login\';</script>'; |
1888 | exit; | 1893 | exit; |
1889 | } | 1894 | } |
@@ -1897,11 +1902,6 @@ function install($conf, $sessionManager, $loginManager) | |||
1897 | exit; | 1902 | exit; |
1898 | } | 1903 | } |
1899 | 1904 | ||
1900 | if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) { | ||
1901 | showDailyRSS($conf, $loginManager); | ||
1902 | exit; | ||
1903 | } | ||
1904 | |||
1905 | if (!isset($_SESSION['LINKS_PER_PAGE'])) { | 1905 | if (!isset($_SESSION['LINKS_PER_PAGE'])) { |
1906 | $_SESSION['LINKS_PER_PAGE'] = $conf->get('general.links_per_page', 20); | 1906 | $_SESSION['LINKS_PER_PAGE'] = $conf->get('general.links_per_page', 20); |
1907 | } | 1907 | } |
@@ -1912,11 +1912,12 @@ try { | |||
1912 | die($e->getMessage()); | 1912 | die($e->getMessage()); |
1913 | } | 1913 | } |
1914 | 1914 | ||
1915 | $linkDb = new LinkDB( | 1915 | $linkDb = new BookmarkFileService($conf, $history, $loginManager->isLoggedIn()); |
1916 | $conf->get('resource.datastore'), | 1916 | |
1917 | $loginManager->isLoggedIn(), | 1917 | if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) { |
1918 | $conf->get('privacy.hide_public_links') | 1918 | showDailyRSS($linkDb, $conf, $loginManager); |
1919 | ); | 1919 | exit; |
1920 | } | ||
1920 | 1921 | ||
1921 | $container = new \Slim\Container(); | 1922 | $container = new \Slim\Container(); |
1922 | $container['conf'] = $conf; | 1923 | $container['conf'] = $conf; |
@@ -1927,11 +1928,11 @@ $app = new \Slim\App($container); | |||
1927 | // REST API routes | 1928 | // REST API routes |
1928 | $app->group('/api/v1', function () { | 1929 | $app->group('/api/v1', function () { |
1929 | $this->get('/info', '\Shaarli\Api\Controllers\Info:getInfo')->setName('getInfo'); | 1930 | $this->get('/info', '\Shaarli\Api\Controllers\Info:getInfo')->setName('getInfo'); |
1930 | $this->get('/links', '\Shaarli\Api\Controllers\Links:getLinks')->setName('getLinks'); | 1931 | $this->get('/bookmarks', '\Shaarli\Api\Controllers\Links:getLinks')->setName('getLinks'); |
1931 | $this->get('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:getLink')->setName('getLink'); | 1932 | $this->get('/bookmarks/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:getLink')->setName('getLink'); |
1932 | $this->post('/links', '\Shaarli\Api\Controllers\Links:postLink')->setName('postLink'); | 1933 | $this->post('/bookmarks', '\Shaarli\Api\Controllers\Links:postLink')->setName('postLink'); |
1933 | $this->put('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:putLink')->setName('putLink'); | 1934 | $this->put('/bookmarks/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:putLink')->setName('putLink'); |
1934 | $this->delete('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:deleteLink')->setName('deleteLink'); | 1935 | $this->delete('/bookmarks/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:deleteLink')->setName('deleteLink'); |
1935 | 1936 | ||
1936 | $this->get('/tags', '\Shaarli\Api\Controllers\Tags:getTags')->setName('getTags'); | 1937 | $this->get('/tags', '\Shaarli\Api\Controllers\Tags:getTags')->setName('getTags'); |
1937 | $this->get('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:getTag')->setName('getTag'); | 1938 | $this->get('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:getTag')->setName('getTag'); |