aboutsummaryrefslogtreecommitdiffhomepage
path: root/index.php
diff options
context:
space:
mode:
Diffstat (limited to 'index.php')
-rw-r--r--index.php156
1 files changed, 98 insertions, 58 deletions
diff --git a/index.php b/index.php
index 4deed197..1f979d3b 100644
--- a/index.php
+++ b/index.php
@@ -56,31 +56,33 @@ require_once 'inc/rain.tpl.class.php';
56require_once __DIR__ . '/vendor/autoload.php'; 56require_once __DIR__ . '/vendor/autoload.php';
57 57
58// Shaarli library 58// Shaarli library
59require_once 'application/ApplicationUtils.php'; 59require_once 'application/bookmark/LinkUtils.php';
60require_once 'application/Cache.php';
61require_once 'application/CachedPage.php';
62require_once 'application/config/ConfigPlugin.php'; 60require_once 'application/config/ConfigPlugin.php';
63require_once 'application/FeedBuilder.php'; 61require_once 'application/feed/Cache.php';
62require_once 'application/http/HttpUtils.php';
63require_once 'application/http/UrlUtils.php';
64require_once 'application/updater/UpdaterUtils.php';
64require_once 'application/FileUtils.php'; 65require_once 'application/FileUtils.php';
65require_once 'application/History.php';
66require_once 'application/HttpUtils.php';
67require_once 'application/LinkDB.php';
68require_once 'application/LinkFilter.php';
69require_once 'application/LinkUtils.php';
70require_once 'application/NetscapeBookmarkUtils.php';
71require_once 'application/PageBuilder.php';
72require_once 'application/TimeZone.php'; 66require_once 'application/TimeZone.php';
73require_once 'application/Url.php';
74require_once 'application/Utils.php'; 67require_once 'application/Utils.php';
75require_once 'application/PluginManager.php'; 68
76require_once 'application/Router.php'; 69use \Shaarli\ApplicationUtils;
77require_once 'application/Updater.php'; 70use \Shaarli\Bookmark\Exception\LinkNotFoundException;
71use \Shaarli\Bookmark\LinkDB;
78use \Shaarli\Config\ConfigManager; 72use \Shaarli\Config\ConfigManager;
73use \Shaarli\Feed\CachedPage;
74use \Shaarli\Feed\FeedBuilder;
75use \Shaarli\History;
79use \Shaarli\Languages; 76use \Shaarli\Languages;
77use \Shaarli\Netscape\NetscapeBookmarkUtils;
78use \Shaarli\Plugin\PluginManager;
79use \Shaarli\Render\PageBuilder;
80use \Shaarli\Render\ThemeUtils;
81use \Shaarli\Router;
80use \Shaarli\Security\LoginManager; 82use \Shaarli\Security\LoginManager;
81use \Shaarli\Security\SessionManager; 83use \Shaarli\Security\SessionManager;
82use \Shaarli\ThemeUtils;
83use \Shaarli\Thumbnailer; 84use \Shaarli\Thumbnailer;
85use \Shaarli\Updater\Updater;
84 86
85// Ensure the PHP version is supported 87// Ensure the PHP version is supported
86try { 88try {
@@ -123,7 +125,7 @@ if (isset($_COOKIE['shaarli']) && !SessionManager::checkId($_COOKIE['shaarli']))
123 125
124$conf = new ConfigManager(); 126$conf = new ConfigManager();
125$sessionManager = new SessionManager($_SESSION, $conf); 127$sessionManager = new SessionManager($_SESSION, $conf);
126$loginManager = new LoginManager($GLOBALS, $conf, $sessionManager); 128$loginManager = new LoginManager($conf, $sessionManager);
127$loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']); 129$loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']);
128$clientIpId = client_ip_id($_SERVER); 130$clientIpId = client_ip_id($_SERVER);
129 131
@@ -310,9 +312,7 @@ function showDailyRSS($conf, $loginManager)
310 $LINKSDB = new LinkDB( 312 $LINKSDB = new LinkDB(
311 $conf->get('resource.datastore'), 313 $conf->get('resource.datastore'),
312 $loginManager->isLoggedIn(), 314 $loginManager->isLoggedIn(),
313 $conf->get('privacy.hide_public_links'), 315 $conf->get('privacy.hide_public_links')
314 $conf->get('redirector.url'),
315 $conf->get('redirector.encode_url')
316 ); 316 );
317 317
318 /* Some Shaarlies may have very few links, so we need to look 318 /* Some Shaarlies may have very few links, so we need to look
@@ -354,13 +354,9 @@ function showDailyRSS($conf, $loginManager)
354 354
355 // We pre-format some fields for proper output. 355 // We pre-format some fields for proper output.
356 foreach ($links as &$link) { 356 foreach ($links as &$link) {
357 $link['formatedDescription'] = format_description( 357 $link['formatedDescription'] = format_description($link['description']);
358 $link['description'],
359 $conf->get('redirector.url'),
360 $conf->get('redirector.encode_url')
361 );
362 $link['timestamp'] = $link['created']->getTimestamp(); 358 $link['timestamp'] = $link['created']->getTimestamp();
363 if (startsWith($link['url'], '?')) { 359 if (is_note($link['url'])) {
364 $link['url'] = index_url($_SERVER) . $link['url']; // make permalink URL absolute 360 $link['url'] = index_url($_SERVER) . $link['url']; // make permalink URL absolute
365 } 361 }
366 } 362 }
@@ -396,9 +392,16 @@ function showDailyRSS($conf, $loginManager)
396 */ 392 */
397function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager, $loginManager) 393function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager, $loginManager)
398{ 394{
399 $day = date('Ymd', strtotime('-1 day')); // Yesterday, in format YYYYMMDD.
400 if (isset($_GET['day'])) { 395 if (isset($_GET['day'])) {
401 $day = $_GET['day']; 396 $day = $_GET['day'];
397 if ($day === date('Ymd', strtotime('now'))) {
398 $pageBuilder->assign('dayDesc', t('Today'));
399 } elseif ($day === date('Ymd', strtotime('-1 days'))) {
400 $pageBuilder->assign('dayDesc', t('Yesterday'));
401 }
402 } else {
403 $day = date('Ymd', strtotime('now')); // Today, in format YYYYMMDD.
404 $pageBuilder->assign('dayDesc', t('Today'));
402 } 405 }
403 406
404 $days = $LINKSDB->days(); 407 $days = $LINKSDB->days();
@@ -431,11 +434,7 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager, $loginManager)
431 $taglist = explode(' ', $link['tags']); 434 $taglist = explode(' ', $link['tags']);
432 uasort($taglist, 'strcasecmp'); 435 uasort($taglist, 'strcasecmp');
433 $linksToDisplay[$key]['taglist']=$taglist; 436 $linksToDisplay[$key]['taglist']=$taglist;
434 $linksToDisplay[$key]['formatedDescription'] = format_description( 437 $linksToDisplay[$key]['formatedDescription'] = format_description($link['description']);
435 $link['description'],
436 $conf->get('redirector.url'),
437 $conf->get('redirector.encode_url')
438 );
439 $linksToDisplay[$key]['timestamp'] = $link['created']->getTimestamp(); 438 $linksToDisplay[$key]['timestamp'] = $link['created']->getTimestamp();
440 } 439 }
441 440
@@ -1016,6 +1015,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1016 $conf->set('general.timezone', $tz); 1015 $conf->set('general.timezone', $tz);
1017 $conf->set('general.title', escape($_POST['title'])); 1016 $conf->set('general.title', escape($_POST['title']));
1018 $conf->set('general.header_link', escape($_POST['titleLink'])); 1017 $conf->set('general.header_link', escape($_POST['titleLink']));
1018 $conf->set('general.retrieve_description', !empty($_POST['retrieveDescription']));
1019 $conf->set('resource.theme', escape($_POST['theme'])); 1019 $conf->set('resource.theme', escape($_POST['theme']));
1020 $conf->set('security.session_protection_disabled', !empty($_POST['disablesessionprotection'])); 1020 $conf->set('security.session_protection_disabled', !empty($_POST['disablesessionprotection']));
1021 $conf->set('privacy.default_private_links', !empty($_POST['privateLinkByDefault'])); 1021 $conf->set('privacy.default_private_links', !empty($_POST['privateLinkByDefault']));
@@ -1064,6 +1064,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1064 ); 1064 );
1065 $PAGE->assign('continents', $continents); 1065 $PAGE->assign('continents', $continents);
1066 $PAGE->assign('cities', $cities); 1066 $PAGE->assign('cities', $cities);
1067 $PAGE->assign('retrieve_description', $conf->get('general.retrieve_description'));
1067 $PAGE->assign('private_links_default', $conf->get('privacy.default_private_links', false)); 1068 $PAGE->assign('private_links_default', $conf->get('privacy.default_private_links', false));
1068 $PAGE->assign('session_protection_disabled', $conf->get('security.session_protection_disabled', false)); 1069 $PAGE->assign('session_protection_disabled', $conf->get('security.session_protection_disabled', false));
1069 $PAGE->assign('enable_rss_permalinks', $conf->get('feed.rss_permalinks', false)); 1070 $PAGE->assign('enable_rss_permalinks', $conf->get('feed.rss_permalinks', false));
@@ -1072,7 +1073,6 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1072 $PAGE->assign('api_enabled', $conf->get('api.enabled', true)); 1073 $PAGE->assign('api_enabled', $conf->get('api.enabled', true));
1073 $PAGE->assign('api_secret', $conf->get('api.secret')); 1074 $PAGE->assign('api_secret', $conf->get('api.secret'));
1074 $PAGE->assign('languages', Languages::getAvailableLanguages()); 1075 $PAGE->assign('languages', Languages::getAvailableLanguages());
1075 $PAGE->assign('language', $conf->get('translation.language'));
1076 $PAGE->assign('gd_enabled', extension_loaded('gd')); 1076 $PAGE->assign('gd_enabled', extension_loaded('gd'));
1077 $PAGE->assign('thumbnails_mode', $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE)); 1077 $PAGE->assign('thumbnails_mode', $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE));
1078 $PAGE->assign('pagetitle', t('Configure') .' - '. $conf->get('general.title', 'Shaarli')); 1078 $PAGE->assign('pagetitle', t('Configure') .' - '. $conf->get('general.title', 'Shaarli'));
@@ -1126,22 +1126,24 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1126 1126
1127 // lf_id should only be present if the link exists. 1127 // lf_id should only be present if the link exists.
1128 $id = isset($_POST['lf_id']) ? intval(escape($_POST['lf_id'])) : $LINKSDB->getNextId(); 1128 $id = isset($_POST['lf_id']) ? intval(escape($_POST['lf_id'])) : $LINKSDB->getNextId();
1129 $link['id'] = $id;
1129 // Linkdate is kept here to: 1130 // Linkdate is kept here to:
1130 // - use the same permalink for notes as they're displayed when creating them 1131 // - use the same permalink for notes as they're displayed when creating them
1131 // - let users hack creation date of their posts 1132 // - let users hack creation date of their posts
1132 // See: https://shaarli.readthedocs.io/en/master/guides/various-hacks/#changing-the-timestamp-for-a-shaare 1133 // See: https://shaarli.readthedocs.io/en/master/guides/various-hacks/#changing-the-timestamp-for-a-shaare
1133 $linkdate = escape($_POST['lf_linkdate']); 1134 $linkdate = escape($_POST['lf_linkdate']);
1135 $link['created'] = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $linkdate);
1134 if (isset($LINKSDB[$id])) { 1136 if (isset($LINKSDB[$id])) {
1135 // Edit 1137 // Edit
1136 $created = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $linkdate); 1138 $link['updated'] = new DateTime();
1137 $updated = new DateTime(); 1139 $link['shorturl'] = $LINKSDB[$id]['shorturl'];
1138 $shortUrl = $LINKSDB[$id]['shorturl']; 1140 $link['sticky'] = isset($LINKSDB[$id]['sticky']) ? $LINKSDB[$id]['sticky'] : false;
1139 $new = false; 1141 $new = false;
1140 } else { 1142 } else {
1141 // New link 1143 // New link
1142 $created = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $linkdate); 1144 $link['updated'] = null;
1143 $updated = null; 1145 $link['shorturl'] = link_small_hash($link['created'], $id);
1144 $shortUrl = link_small_hash($created, $id); 1146 $link['sticky'] = false;
1145 $new = true; 1147 $new = true;
1146 } 1148 }
1147 1149
@@ -1157,24 +1159,22 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1157 } 1159 }
1158 $url = whitelist_protocols(trim($_POST['lf_url']), $conf->get('security.allowed_protocols')); 1160 $url = whitelist_protocols(trim($_POST['lf_url']), $conf->get('security.allowed_protocols'));
1159 1161
1160 $link = array( 1162 $link = array_merge($link, [
1161 'id' => $id,
1162 'title' => trim($_POST['lf_title']), 1163 'title' => trim($_POST['lf_title']),
1163 'url' => $url, 1164 'url' => $url,
1164 'description' => $_POST['lf_description'], 1165 'description' => $_POST['lf_description'],
1165 'private' => (isset($_POST['lf_private']) ? 1 : 0), 1166 'private' => (isset($_POST['lf_private']) ? 1 : 0),
1166 'created' => $created,
1167 'updated' => $updated,
1168 'tags' => str_replace(',', ' ', $tags), 1167 'tags' => str_replace(',', ' ', $tags),
1169 'shorturl' => $shortUrl, 1168 ]);
1170 );
1171 1169
1172 // If title is empty, use the URL as title. 1170 // If title is empty, use the URL as title.
1173 if ($link['title'] == '') { 1171 if ($link['title'] == '') {
1174 $link['title'] = $link['url']; 1172 $link['title'] = $link['url'];
1175 } 1173 }
1176 1174
1177 if ($conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE) { 1175 if ($conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
1176 && ! is_note($link['url'])
1177 ) {
1178 $thumbnailer = new Thumbnailer($conf); 1178 $thumbnailer = new Thumbnailer($conf);
1179 $link['thumbnail'] = $thumbnailer->get($url); 1179 $link['thumbnail'] = $thumbnailer->get($url);
1180 } 1180 }
@@ -1273,6 +1273,51 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1273 exit; 1273 exit;
1274 } 1274 }
1275 1275
1276 // -------- User clicked either "Set public" or "Set private" bulk operation
1277 if ($targetPage == Router::$PAGE_CHANGE_VISIBILITY) {
1278 if (! $sessionManager->checkToken($_GET['token'])) {
1279 die(t('Wrong token.'));
1280 }
1281
1282 $ids = trim($_GET['ids']);
1283 if (strpos($ids, ' ') !== false) {
1284 // multiple, space-separated ids provided
1285 $ids = array_values(array_filter(preg_split('/\s+/', escape($ids))));
1286 } else {
1287 // only a single id provided
1288 $ids = [$ids];
1289 }
1290
1291 // assert at least one id is given
1292 if (!count($ids)) {
1293 die('no id provided');
1294 }
1295 // assert that the visibility is valid
1296 if (!isset($_GET['newVisibility']) || !in_array($_GET['newVisibility'], ['public', 'private'])) {
1297 die('invalid visibility');
1298 } else {
1299 $private = $_GET['newVisibility'] === 'private';
1300 }
1301 foreach ($ids as $id) {
1302 $id = (int) escape($id);
1303 $link = $LINKSDB[$id];
1304 $link['private'] = $private;
1305 $pluginManager->executeHooks('save_link', $link);
1306 $LINKSDB[$id] = $link;
1307 }
1308 $LINKSDB->save($conf->get('resource.page_cache')); // save to disk
1309
1310 $location = '?';
1311 if (isset($_SERVER['HTTP_REFERER'])) {
1312 $location = generateLocation(
1313 $_SERVER['HTTP_REFERER'],
1314 $_SERVER['HTTP_HOST']
1315 );
1316 }
1317 header('Location: ' . $location); // After deleting the link, redirect to appropriate location
1318 exit;
1319 }
1320
1276 // -------- User clicked the "EDIT" button on a link: Display link edit form. 1321 // -------- User clicked the "EDIT" button on a link: Display link edit form.
1277 if (isset($_GET['edit_link'])) { 1322 if (isset($_GET['edit_link'])) {
1278 $id = (int) escape($_GET['edit_link']); 1323 $id = (int) escape($_GET['edit_link']);
@@ -1319,13 +1364,14 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1319 // If this is an HTTP(S) link, we try go get the page to extract 1364 // If this is an HTTP(S) link, we try go get the page to extract
1320 // the title (otherwise we will to straight to the edit form.) 1365 // the title (otherwise we will to straight to the edit form.)
1321 if (empty($title) && strpos(get_url_scheme($url), 'http') !== false) { 1366 if (empty($title) && strpos(get_url_scheme($url), 'http') !== false) {
1367 $retrieveDescription = $conf->get('general.retrieve_description');
1322 // Short timeout to keep the application responsive 1368 // Short timeout to keep the application responsive
1323 // The callback will fill $charset and $title with data from the downloaded page. 1369 // The callback will fill $charset and $title with data from the downloaded page.
1324 get_http_response( 1370 get_http_response(
1325 $url, 1371 $url,
1326 $conf->get('general.download_timeout', 30), 1372 $conf->get('general.download_timeout', 30),
1327 $conf->get('general.download_max_size', 4194304), 1373 $conf->get('general.download_max_size', 4194304),
1328 get_curl_download_callback($charset, $title) 1374 get_curl_download_callback($charset, $title, $description, $tags, $retrieveDescription)
1329 ); 1375 );
1330 if (! empty($title) && strtolower($charset) != 'utf-8') { 1376 if (! empty($title) && strtolower($charset) != 'utf-8') {
1331 $title = mb_convert_encoding($title, 'utf-8', $charset); 1377 $title = mb_convert_encoding($title, 'utf-8', $charset);
@@ -1519,6 +1565,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1519 if ($targetPage == Router::$PAGE_SAVE_PLUGINSADMIN) { 1565 if ($targetPage == Router::$PAGE_SAVE_PLUGINSADMIN) {
1520 try { 1566 try {
1521 if (isset($_POST['parameters_form'])) { 1567 if (isset($_POST['parameters_form'])) {
1568 $pluginManager->executeHooks('save_plugin_parameters', $_POST);
1522 unset($_POST['parameters_form']); 1569 unset($_POST['parameters_form']);
1523 foreach ($_POST as $param => $value) { 1570 foreach ($_POST as $param => $value) {
1524 $conf->set('plugins.'. $param, escape($value)); 1571 $conf->set('plugins.'. $param, escape($value));
@@ -1558,7 +1605,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1558 $ids = []; 1605 $ids = [];
1559 foreach ($LINKSDB as $link) { 1606 foreach ($LINKSDB as $link) {
1560 // A note or not HTTP(S) 1607 // A note or not HTTP(S)
1561 if ($link['url'][0] === '?' || ! startsWith(strtolower($link['url']), 'http')) { 1608 if (is_note($link['url']) || ! startsWith(strtolower($link['url']), 'http')) {
1562 continue; 1609 continue;
1563 } 1610 }
1564 $ids[] = $link['id']; 1611 $ids[] = $link['id'];
@@ -1662,11 +1709,7 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
1662 $linkDisp = array(); 1709 $linkDisp = array();
1663 while ($i<$end && $i<count($keys)) { 1710 while ($i<$end && $i<count($keys)) {
1664 $link = $linksToDisplay[$keys[$i]]; 1711 $link = $linksToDisplay[$keys[$i]];
1665 $link['description'] = format_description( 1712 $link['description'] = format_description($link['description']);
1666 $link['description'],
1667 $conf->get('redirector.url'),
1668 $conf->get('redirector.encode_url')
1669 );
1670 $classLi = ($i % 2) != 0 ? '' : 'publicLinkHightLight'; 1713 $classLi = ($i % 2) != 0 ? '' : 'publicLinkHightLight';
1671 $link['class'] = $link['private'] == 0 ? $classLi : 'private'; 1714 $link['class'] = $link['private'] == 0 ? $classLi : 'private';
1672 $link['timestamp'] = $link['created']->getTimestamp(); 1715 $link['timestamp'] = $link['created']->getTimestamp();
@@ -1727,7 +1770,6 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
1727 'search_term' => $searchterm, 1770 'search_term' => $searchterm,
1728 'search_tags' => $searchtags, 1771 'search_tags' => $searchtags,
1729 'visibility' => ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : '', 1772 'visibility' => ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : '',
1730 'redirector' => $conf->get('redirector.url'), // Optional redirector URL.
1731 'links' => $linkDisp, 1773 'links' => $linkDisp,
1732 ); 1774 );
1733 1775
@@ -1877,9 +1919,7 @@ try {
1877$linkDb = new LinkDB( 1919$linkDb = new LinkDB(
1878 $conf->get('resource.datastore'), 1920 $conf->get('resource.datastore'),
1879 $loginManager->isLoggedIn(), 1921 $loginManager->isLoggedIn(),
1880 $conf->get('privacy.hide_public_links'), 1922 $conf->get('privacy.hide_public_links')
1881 $conf->get('redirector.url'),
1882 $conf->get('redirector.encode_url')
1883); 1923);
1884 1924
1885$container = new \Slim\Container(); 1925$container = new \Slim\Container();
@@ -1902,7 +1942,7 @@ $app->group('/api/v1', function () {
1902 $this->put('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:putTag')->setName('putTag'); 1942 $this->put('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:putTag')->setName('putTag');
1903 $this->delete('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:deleteTag')->setName('deleteTag'); 1943 $this->delete('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:deleteTag')->setName('deleteTag');
1904 1944
1905 $this->get('/history', '\Shaarli\Api\Controllers\History:getHistory')->setName('getHistory'); 1945 $this->get('/history', '\Shaarli\Api\Controllers\HistoryController:getHistory')->setName('getHistory');
1906})->add('\Shaarli\Api\ApiMiddleware'); 1946})->add('\Shaarli\Api\ApiMiddleware');
1907 1947
1908$response = $app->run(true); 1948$response = $app->run(true);