X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=index.php;h=a31cbeab68106756d929b056d71b3b1377bf17db;hb=af290059d10319e76d1e7d78b592cab99c26d91a;hp=a42c844a8bac754d1e4fccf3118cb75f1460d5f3;hpb=03340c18ead651ef9e11f883745695f2edafbae3;p=github%2Fshaarli%2FShaarli.git diff --git a/index.php b/index.php index a42c844a..a31cbeab 100644 --- a/index.php +++ b/index.php @@ -300,210 +300,6 @@ if (!isset($_SESSION['tokens'])) { $_SESSION['tokens']=array(); // Token are attached to the session. } -/** - * Daily RSS feed: 1 RSS entry per day giving all the bookmarks on that day. - * Gives the last 7 days (which have bookmarks). - * This RSS feed cannot be filtered. - * - * @param BookmarkServiceInterface $bookmarkService - * @param ConfigManager $conf Configuration Manager instance - * @param LoginManager $loginManager LoginManager instance - */ -function showDailyRSS($bookmarkService, $conf, $loginManager) -{ - // Cache system - $query = $_SERVER['QUERY_STRING']; - $cache = new CachedPage( - $conf->get('config.PAGE_CACHE'), - page_url($_SERVER), - startsWith($query, 'do=dailyrss') && !$loginManager->isLoggedIn() - ); - $cached = $cache->cachedVersion(); - if (!empty($cached)) { - echo $cached; - exit; - } - - /* Some Shaarlies may have very few bookmarks, so we need to look - back in time until we have enough days ($nb_of_days). - */ - $nb_of_days = 7; // We take 7 days. - $today = date('Ymd'); - $days = array(); - - foreach ($bookmarkService->search() as $bookmark) { - $day = $bookmark->getCreated()->format('Ymd'); // Extract day (without time) - if (strcmp($day, $today) < 0) { - if (empty($days[$day])) { - $days[$day] = array(); - } - $days[$day][] = $bookmark; - } - - if (count($days) > $nb_of_days) { - break; // Have we collected enough days? - } - } - - // Build the RSS feed. - header('Content-Type: application/rss+xml; charset=utf-8'); - $pageaddr = escape(index_url($_SERVER)); - echo ''; - echo ''; - echo 'Daily - '. $conf->get('general.title') . ''; - echo ''. $pageaddr .''; - echo 'Daily shared bookmarks'; - echo 'en-en'; - echo ''. $pageaddr .''. PHP_EOL; - - $factory = new FormatterFactory($conf, $loginManager->isLoggedIn()); - $formatter = $factory->getFormatter(); - $formatter->addContextData('index_url', index_url($_SERVER)); - // For each day. - /** @var Bookmark[] $bookmarks */ - foreach ($days as $day => $bookmarks) { - $formattedBookmarks = []; - $dayDate = DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, $day.'_000000'); - $absurl = escape(index_url($_SERVER).'?do=daily&day='.$day); // Absolute URL of the corresponding "Daily" page. - - // We pre-format some fields for proper output. - foreach ($bookmarks as $key => $bookmark) { - $formattedBookmarks[$key] = $formatter->format($bookmark); - // This page is a bit specific, we need raw description to calculate the length - $formattedBookmarks[$key]['formatedDescription'] = $formattedBookmarks[$key]['description']; - $formattedBookmarks[$key]['description'] = $bookmark->getDescription(); - - if ($bookmark->isNote()) { - $link['url'] = index_url($_SERVER) . $bookmark->getUrl(); // make permalink URL absolute - } - } - - // Then build the HTML for this day: - $tpl = new RainTPL(); - $tpl->assign('title', $conf->get('general.title')); - $tpl->assign('daydate', $dayDate->getTimestamp()); - $tpl->assign('absurl', $absurl); - $tpl->assign('links', $formattedBookmarks); - $tpl->assign('rssdate', escape($dayDate->format(DateTime::RSS))); - $tpl->assign('hide_timestamps', $conf->get('privacy.hide_timestamps', false)); - $tpl->assign('index_url', $pageaddr); - $html = $tpl->draw('dailyrss', true); - - echo $html . PHP_EOL; - } - echo ''; - - $cache->cache(ob_get_contents()); - ob_end_flush(); - exit; -} - -/** - * Show the 'Daily' page. - * - * @param PageBuilder $pageBuilder Template engine wrapper. - * @param BookmarkServiceInterface $bookmarkService instance. - * @param ConfigManager $conf Configuration Manager instance. - * @param PluginManager $pluginManager Plugin Manager instance. - * @param LoginManager $loginManager Login Manager instance - */ -function showDaily($pageBuilder, $bookmarkService, $conf, $pluginManager, $loginManager) -{ - if (isset($_GET['day'])) { - $day = $_GET['day']; - if ($day === date('Ymd', strtotime('now'))) { - $pageBuilder->assign('dayDesc', t('Today')); - } elseif ($day === date('Ymd', strtotime('-1 days'))) { - $pageBuilder->assign('dayDesc', t('Yesterday')); - } - } else { - $day = date('Ymd', strtotime('now')); // Today, in format YYYYMMDD. - $pageBuilder->assign('dayDesc', t('Today')); - } - - $days = $bookmarkService->days(); - $i = array_search($day, $days); - if ($i === false && count($days)) { - // no bookmarks for day, but at least one day with bookmarks - $i = count($days) - 1; - $day = $days[$i]; - } - $previousday = ''; - $nextday = ''; - - if ($i !== false) { - if ($i >= 1) { - $previousday = $days[$i - 1]; - } - if ($i < count($days) - 1) { - $nextday = $days[$i + 1]; - } - } - try { - $linksToDisplay = $bookmarkService->filterDay($day); - } catch (Exception $exc) { - error_log($exc); - $linksToDisplay = []; - } - - $factory = new FormatterFactory($conf, $loginManager->isLoggedIn()); - $formatter = $factory->getFormatter(); - // We pre-format some fields for proper output. - foreach ($linksToDisplay as $key => $bookmark) { - $linksToDisplay[$key] = $formatter->format($bookmark); - // This page is a bit specific, we need raw description to calculate the length - $linksToDisplay[$key]['formatedDescription'] = $linksToDisplay[$key]['description']; - $linksToDisplay[$key]['description'] = $bookmark->getDescription(); - } - - $dayDate = DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, $day.'_000000'); - $data = array( - 'pagetitle' => $conf->get('general.title') .' - '. format_date($dayDate, false), - 'linksToDisplay' => $linksToDisplay, - 'day' => $dayDate->getTimestamp(), - 'dayDate' => $dayDate, - 'previousday' => $previousday, - 'nextday' => $nextday, - ); - - /* Hook is called before column construction so that plugins don't have - to deal with columns. */ - $pluginManager->executeHooks('render_daily', $data, array('loggedin' => $loginManager->isLoggedIn())); - - /* We need to spread the articles on 3 columns. - I did not want to use a JavaScript lib like http://masonry.desandro.com/ - so I manually spread entries with a simple method: I roughly evaluate the - height of a div according to title and description length. - */ - $columns = array(array(), array(), array()); // Entries to display, for each column. - $fill = array(0, 0, 0); // Rough estimate of columns fill. - foreach ($data['linksToDisplay'] as $key => $bookmark) { - // Roughly estimate length of entry (by counting characters) - // Title: 30 chars = 1 line. 1 line is 30 pixels height. - // Description: 836 characters gives roughly 342 pixel height. - // This is not perfect, but it's usually OK. - $length = strlen($bookmark['title']) + (342 * strlen($bookmark['description'])) / 836; - if (! empty($bookmark['thumbnail'])) { - $length += 100; // 1 thumbnails roughly takes 100 pixels height. - } - // Then put in column which is the less filled: - $smallest = min($fill); // find smallest value in array. - $index = array_search($smallest, $fill); // find index of this smallest value. - array_push($columns[$index], $bookmark); // Put entry in this column. - $fill[$index] += $length; - } - - $data['cols'] = $columns; - - foreach ($data as $key => $value) { - $pageBuilder->assign($key, $value); - } - - $pageBuilder->assign('pagetitle', t('Daily') .' - '. $conf->get('general.title', 'Shaarli')); - $pageBuilder->renderPage('daily'); - exit; -} - /** * Renders the linklist * @@ -530,7 +326,7 @@ function showLinkList($PAGE, $linkDb, $conf, $pluginManager, $loginManager) */ function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionManager, $loginManager) { - $pageCacheManager = new PageCacheManager($conf->get('resource.page_cache')); + $pageCacheManager = new PageCacheManager($conf->get('resource.page_cache'), $loginManager->isLoggedIn()); $updater = new Updater( UpdaterUtils::read_updates_file($conf->get('resource.updates')), $bookmarkService, @@ -616,275 +412,64 @@ function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionM // -------- Tag cloud if ($targetPage == Router::$PAGE_TAGCLOUD) { - $visibility = ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : ''; - $filteringTags = isset($_GET['searchtags']) ? explode(' ', $_GET['searchtags']) : []; - $tags = $bookmarkService->bookmarksCountPerTag($filteringTags, $visibility); - - // We sort tags alphabetically, then choose a font size according to count. - // First, find max value. - $maxcount = 0; - foreach ($tags as $value) { - $maxcount = max($maxcount, $value); - } - - alphabetical_sort($tags, false, true); - - $logMaxCount = $maxcount > 1 ? log($maxcount, 30) : 1; - $tagList = array(); - foreach ($tags as $key => $value) { - if (in_array($key, $filteringTags)) { - continue; - } - // Tag font size scaling: - // default 15 and 30 logarithm bases affect scaling, - // 2.2 and 0.8 are arbitrary font sizes in em. - $size = log($value, 15) / $logMaxCount * 2.2 + 0.8; - $tagList[$key] = array( - 'count' => $value, - 'size' => number_format($size, 2, '.', ''), - ); - } - - $searchTags = implode(' ', escape($filteringTags)); - $data = array( - 'search_tags' => $searchTags, - 'tags' => $tagList, - ); - $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => $loginManager->isLoggedIn())); - - foreach ($data as $key => $value) { - $PAGE->assign($key, $value); - } - - $searchTags = ! empty($searchTags) ? $searchTags .' - ' : ''; - $PAGE->assign('pagetitle', $searchTags. t('Tag cloud') .' - '. $conf->get('general.title', 'Shaarli')); - $PAGE->renderPage('tag.cloud'); + header('Location: ./tag-cloud'); exit; } // -------- Tag list if ($targetPage == Router::$PAGE_TAGLIST) { - $visibility = ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : ''; - $filteringTags = isset($_GET['searchtags']) ? explode(' ', $_GET['searchtags']) : []; - $tags = $bookmarkService->bookmarksCountPerTag($filteringTags, $visibility); - foreach ($filteringTags as $tag) { - if (array_key_exists($tag, $tags)) { - unset($tags[$tag]); - } - } - - if (! empty($_GET['sort']) && $_GET['sort'] === 'alpha') { - alphabetical_sort($tags, false, true); - } - - $searchTags = implode(' ', escape($filteringTags)); - $data = [ - 'search_tags' => $searchTags, - 'tags' => $tags, - ]; - $pluginManager->executeHooks('render_taglist', $data, ['loggedin' => $loginManager->isLoggedIn()]); - - foreach ($data as $key => $value) { - $PAGE->assign($key, $value); - } - - $searchTags = ! empty($searchTags) ? $searchTags .' - ' : ''; - $PAGE->assign('pagetitle', $searchTags . t('Tag list') .' - '. $conf->get('general.title', 'Shaarli')); - $PAGE->renderPage('tag.list'); + header('Location: ./tag-list'); exit; } // Daily page. if ($targetPage == Router::$PAGE_DAILY) { - showDaily($PAGE, $bookmarkService, $conf, $pluginManager, $loginManager); + $dayParam = !empty($_GET['day']) ? '?day=' . escape($_GET['day']) : ''; + header('Location: ./daily'. $dayParam); + exit; } // ATOM and RSS feed. if ($targetPage == Router::$PAGE_FEED_ATOM || $targetPage == Router::$PAGE_FEED_RSS) { $feedType = $targetPage == Router::$PAGE_FEED_RSS ? FeedBuilder::$FEED_RSS : FeedBuilder::$FEED_ATOM; - header('Content-Type: application/'. $feedType .'+xml; charset=utf-8'); - - // Cache system - $query = $_SERVER['QUERY_STRING']; - $cache = new CachedPage( - $conf->get('resource.page_cache'), - page_url($_SERVER), - startsWith($query, 'do='. $targetPage) && !$loginManager->isLoggedIn() - ); - $cached = $cache->cachedVersion(); - if (!empty($cached)) { - echo $cached; - exit; - } - $factory = new FormatterFactory($conf, $loginManager->isLoggedIn()); - // Generate data. - $feedGenerator = new FeedBuilder( - $bookmarkService, - $factory->getFormatter(), - $feedType, - $_SERVER, - $_GET, - $loginManager->isLoggedIn() - ); - $feedGenerator->setLocale(strtolower(setlocale(LC_COLLATE, 0))); - $feedGenerator->setHideDates($conf->get('privacy.hide_timestamps') && !$loginManager->isLoggedIn()); - $feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$conf->get('feed.rss_permalinks')); - $data = $feedGenerator->buildData(); - - // Process plugin hook. - $pluginManager->executeHooks('render_feed', $data, array( - 'loggedin' => $loginManager->isLoggedIn(), - 'target' => $targetPage, - )); - - // Render the template. - $PAGE->assignAll($data); - $PAGE->renderPage('feed.'. $feedType); - $cache->cache(ob_get_contents()); - ob_end_flush(); + header('Location: ./feed-'. $feedType .'?'. http_build_query($_GET)); exit; } // Display opensearch plugin (XML) if ($targetPage == Router::$PAGE_OPENSEARCH) { - header('Content-Type: application/xml; charset=utf-8'); - $PAGE->assign('serverurl', index_url($_SERVER)); - $PAGE->renderPage('opensearch'); + header('Location: ./open-search'); exit; } // -------- User clicks on a tag in a link: The tag is added to the list of searched tags (searchtags=...) if (isset($_GET['addtag'])) { - // Get previous URL (http_referer) and add the tag to the searchtags parameters in query. - if (empty($_SERVER['HTTP_REFERER'])) { - // In case browser does not send HTTP_REFERER - header('Location: ?searchtags='.urlencode($_GET['addtag'])); - exit; - } - parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); - - // Prevent redirection loop - if (isset($params['addtag'])) { - unset($params['addtag']); - } - - // Check if this tag is already in the search query and ignore it if it is. - // Each tag is always separated by a space - if (isset($params['searchtags'])) { - $current_tags = explode(' ', $params['searchtags']); - } else { - $current_tags = array(); - } - $addtag = true; - foreach ($current_tags as $value) { - if ($value === $_GET['addtag']) { - $addtag = false; - break; - } - } - // Append the tag if necessary - if (empty($params['searchtags'])) { - $params['searchtags'] = trim($_GET['addtag']); - } elseif ($addtag) { - $params['searchtags'] = trim($params['searchtags']).' '.trim($_GET['addtag']); - } - - // We also remove page (keeping the same page has no sense, since the - // results are different) - unset($params['page']); - - header('Location: ?'.http_build_query($params)); + header('Location: ./add-tag/'. $_GET['addtag']); exit; } // -------- User clicks on a tag in result count: Remove the tag from the list of searched tags (searchtags=...) if (isset($_GET['removetag'])) { - // Get previous URL (http_referer) and remove the tag from the searchtags parameters in query. - if (empty($_SERVER['HTTP_REFERER'])) { - header('Location: ?'); - exit; - } - - // In case browser does not send HTTP_REFERER - parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); - - // Prevent redirection loop - if (isset($params['removetag'])) { - unset($params['removetag']); - } - - if (isset($params['searchtags'])) { - $tags = explode(' ', $params['searchtags']); - // Remove value from array $tags. - $tags = array_diff($tags, array($_GET['removetag'])); - $params['searchtags'] = implode(' ', $tags); - - if (empty($params['searchtags'])) { - unset($params['searchtags']); - } - - // We also remove page (keeping the same page has no sense, since - // the results are different) - unset($params['page']); - } - header('Location: ?'.http_build_query($params)); + header('Location: ./remove-tag/'. $_GET['removetag']); exit; } // -------- User wants to change the number of bookmarks per page (linksperpage=...) if (isset($_GET['linksperpage'])) { - if (is_numeric($_GET['linksperpage'])) { - $_SESSION['LINKS_PER_PAGE']=abs(intval($_GET['linksperpage'])); - } - - if (! empty($_SERVER['HTTP_REFERER'])) { - $location = generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('linksperpage')); - } else { - $location = '?'; - } - header('Location: '. $location); + header('Location: ./links-per-page?nb='. $_GET['linksperpage']); exit; } // -------- User wants to see only private bookmarks (toggle) if (isset($_GET['visibility'])) { - if ($_GET['visibility'] === 'private') { - // Visibility not set or not already private, set private, otherwise reset it - if (empty($_SESSION['visibility']) || $_SESSION['visibility'] !== 'private') { - // See only private bookmarks - $_SESSION['visibility'] = 'private'; - } else { - unset($_SESSION['visibility']); - } - } elseif ($_GET['visibility'] === 'public') { - if (empty($_SESSION['visibility']) || $_SESSION['visibility'] !== 'public') { - // See only public bookmarks - $_SESSION['visibility'] = 'public'; - } else { - unset($_SESSION['visibility']); - } - } - - if (! empty($_SERVER['HTTP_REFERER'])) { - $location = generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('visibility')); - } else { - $location = '?'; - } - header('Location: '. $location); + header('Location: ./visibility/'. $_GET['visibility']); exit; } // -------- User wants to see only untagged bookmarks (toggle) if (isset($_GET['untaggedonly'])) { - $_SESSION['untaggedonly'] = empty($_SESSION['untaggedonly']); - - if (! empty($_SERVER['HTTP_REFERER'])) { - $location = generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('untaggedonly')); - } else { - $location = '?'; - } - header('Location: '. $location); + header('Location: ./untagged-only'); exit; } @@ -894,7 +479,7 @@ function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionM // Show login screen, then redirect to ?post=... if (isset($_GET['post'])) { header( // Redirect to login page, then back to post link. - 'Location: /login?post='.urlencode($_GET['post']). + 'Location: ./login?post='.urlencode($_GET['post']). (!empty($_GET['title'])?'&title='.urlencode($_GET['title']):''). (!empty($_GET['description'])?'&description='.urlencode($_GET['description']):''). (!empty($_GET['tags'])?'&tags='.urlencode($_GET['tags']):''). @@ -905,7 +490,7 @@ function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionM showLinkList($PAGE, $bookmarkService, $conf, $pluginManager, $loginManager); if (isset($_GET['edit_link'])) { - header('Location: /login?edit_link='. escape($_GET['edit_link'])); + header('Location: ./login?edit_link='. escape($_GET['edit_link'])); exit; } @@ -1887,7 +1472,7 @@ try { $linkDb = new BookmarkFileService($conf, $history, $loginManager->isLoggedIn()); if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) { - showDailyRSS($linkDb, $conf, $loginManager); + header('Location: ./daily-rss'); exit; } @@ -1916,7 +1501,29 @@ $app->group('', function () { $this->get('/login', '\Shaarli\Front\Controller\LoginController:index')->setName('login'); $this->get('/logout', '\Shaarli\Front\Controller\LogoutController:index')->setName('logout'); $this->get('/picture-wall', '\Shaarli\Front\Controller\PictureWallController:index')->setName('picwall'); + $this->get('/tag-cloud', '\Shaarli\Front\Controller\TagCloudController:cloud')->setName('tagcloud'); + $this->get('/tag-list', '\Shaarli\Front\Controller\TagCloudController:list')->setName('taglist'); + $this->get('/daily', '\Shaarli\Front\Controller\DailyController:index')->setName('daily'); + $this->get('/daily-rss', '\Shaarli\Front\Controller\DailyController:rss')->setName('dailyrss'); + $this->get('/feed-atom', '\Shaarli\Front\Controller\FeedController:atom')->setName('feedatom'); + $this->get('/feed-rss', '\Shaarli\Front\Controller\FeedController:rss')->setName('feedrss'); + $this->get('/open-search', '\Shaarli\Front\Controller\OpenSearchController:index')->setName('opensearch'); + $this->get('/add-tag/{newTag}', '\Shaarli\Front\Controller\TagController:addTag')->setName('add-tag'); + $this->get('/remove-tag/{tag}', '\Shaarli\Front\Controller\TagController:removeTag')->setName('remove-tag'); + + $this + ->get('/links-per-page', '\Shaarli\Front\Controller\SessionFilterController:linksPerPage') + ->setName('filter-links-per-page') + ; + $this + ->get('/visibility/{visibility}', '\Shaarli\Front\Controller\SessionFilterController:visibility') + ->setName('visibility') + ; + $this + ->get('/untagged-only', '\Shaarli\Front\Controller\SessionFilterController:untaggedOnly') + ->setName('untagged-only') + ; })->add('\Shaarli\Front\ShaarliMiddleware'); $response = $app->run(true);