X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=index.php;h=58ae2ddb780a9315755df398c77eaa5773b0e712;hb=a19c24edc1057bd411821f9e3e7d1d309d38b1bb;hp=953f1085e958c280eff4119d1690952bf81a6f4c;hpb=787faa42f3a2bcbf83a7853f23f3667a6febf9da;p=github%2Fshaarli%2FShaarli.git
diff --git a/index.php b/index.php
index 953f1085..58ae2ddb 100644
--- a/index.php
+++ b/index.php
@@ -121,7 +121,32 @@ if (isset($_COOKIE['shaarli']) && !SessionManager::checkId($_COOKIE['shaarli']))
$_COOKIE['shaarli'] = session_id();
}
-$conf = new ConfigManager();
+$folderBase = getenv("BASE");
+
+if (getenv("USERSPACE")) {
+ if (isset($_GET["do"]) && $_GET["do"] == "login") {
+ header("Location: $folderBase/?do=login");
+ exit;
+ }
+ $userspace = preg_replace("/[^-_A-Za-z0-9]/", '', getenv("USERSPACE"));
+} else if (isset($_SESSION["username"]) && $_SESSION["username"]) {
+ header("Location: " . $folderBase . "/" . $_SESSION["username"] . "?");
+ exit;
+} else if (!isset($_GET["do"]) || $_GET["do"] != "login") {
+ header("Location: $folderBase/?do=login");
+ exit;
+}
+
+if (!isset($userspace) && isset($_POST["login"])) {
+ $userspace = preg_replace("/[^-_A-Za-z0-9]/", '', $_POST["login"]);
+ error_log("debugImmae: setting userspace from POST: " . $userspace);
+}
+
+if (isset($userspace)) {
+ $conf = new ConfigManager(null, $userspace);
+} else {
+ $conf = new ConfigManager();
+}
$sessionManager = new SessionManager($_SESSION, $conf);
$loginManager = new LoginManager($GLOBALS, $conf, $sessionManager);
$loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']);
@@ -175,7 +200,7 @@ if (! is_file($conf->getConfigFileExt())) {
}
// Display the installation form if no existing config is found
- install($conf, $sessionManager, $loginManager);
+ install($conf, $sessionManager, $loginManager, $userspace);
}
$loginManager->checkLoginState($_COOKIE, $clientIpId);
@@ -205,6 +230,7 @@ if (isset($_POST['login'])) {
&& $loginManager->checkCredentials($_SERVER['REMOTE_ADDR'], $clientIpId, $_POST['login'], $_POST['password'])
) {
$loginManager->handleSuccessfulLogin($_SERVER);
+ $userspace = $_POST['login'];
$cookiedir = '';
if (dirname($_SERVER['SCRIPT_NAME']) != '/') {
@@ -241,25 +267,25 @@ if (isset($_POST['login'])) {
$uri .= '&'.$param.'='.urlencode($_GET[$param]);
}
}
- header('Location: '. $uri);
+ header('Location: '. $userspace . $uri);
exit;
}
if (isset($_GET['edit_link'])) {
- header('Location: ?edit_link='. escape($_GET['edit_link']));
+ header('Location: ' . $userspace . '?edit_link='. escape($_GET['edit_link']));
exit;
}
if (isset($_POST['returnurl'])) {
// Prevent loops over login screen.
if (strpos($_POST['returnurl'], 'do=login') === false) {
- header('Location: '. generateLocation($_POST['returnurl'], $_SERVER['HTTP_HOST']));
+ header('Location: ' . generateLocation($_POST['returnurl'], $_SERVER['HTTP_HOST']));
exit;
}
}
- header('Location: ?'); exit;
+ header('Location: '. $userspace . '?'); exit;
} else {
- $loginManager->handleFailedLogin($_SERVER);
+ $errorReason = $loginManager->handleFailedLogin($_SERVER);
$redir = '&username='. urlencode($_POST['login']);
if (isset($_GET['post'])) {
$redir .= '&post=' . urlencode($_GET['post']);
@@ -270,7 +296,7 @@ if (isset($_POST['login'])) {
}
}
// Redirect to login screen.
- echo '';
+ echo '';
exit;
}
}
@@ -356,7 +382,6 @@ function showDailyRSS($conf, $loginManager) {
$conf->get('redirector.url'),
$conf->get('redirector.encode_url')
);
- $link['thumbnail'] = thumbnail($conf, $link['url']);
$link['timestamp'] = $link['created']->getTimestamp();
if (startsWith($link['url'], '?')) {
$link['url'] = index_url($_SERVER) . $link['url']; // make permalink URL absolute
@@ -371,6 +396,7 @@ function showDailyRSS($conf, $loginManager) {
$tpl->assign('links', $links);
$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;
@@ -433,7 +459,6 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager, $loginManager)
$conf->get('redirector.url'),
$conf->get('redirector.encode_url')
);
- $linksToDisplay[$key]['thumbnail'] = thumbnail($conf, $link['url']);
$linksToDisplay[$key]['timestamp'] = $link['created']->getTimestamp();
}
@@ -514,7 +539,8 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
read_updates_file($conf->get('resource.updates')),
$LINKSDB,
$conf,
- $loginManager->isLoggedIn()
+ $loginManager->isLoggedIn(),
+ $_SESSION
);
try {
$newUpdates = $updater->update();
@@ -529,7 +555,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
die($e->getMessage());
}
- $PAGE = new PageBuilder($conf, $LINKSDB, $sessionManager->generateToken(), $loginManager->isLoggedIn());
+ $PAGE = new PageBuilder($conf, $_SESSION, $LINKSDB, $sessionManager->generateToken(), $loginManager->isLoggedIn());
$PAGE->assign('linkcount', count($LINKSDB));
$PAGE->assign('privateLinkcount', count_private($LINKSDB));
$PAGE->assign('plugin_errors', $pluginManager->getErrors());
@@ -602,7 +628,9 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
// -------- Picture wall
if ($targetPage == Router::$PAGE_PICWALL)
{
- if (! $conf->get('thumbnails.enabled')) {
+ $PAGE->assign('pagetitle', t('Picture wall') .' - '. $conf->get('general.title', 'Shaarli'));
+ if (! $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) === Thumbnailer::MODE_NONE) {
+ $PAGE->assign('linksToDisplay', []);
$PAGE->renderPage('picwall');
exit;
}
@@ -611,38 +639,13 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
$links = $LINKSDB->filterSearch($_GET);
$linksToDisplay = array();
- $thumbnailer = new Thumbnailer($conf);
-
-
- $newThumbnailsCpt = 0;
// Get only links which have a thumbnail.
+ // Note: we do not retrieve thumbnails here, the request is too heavy.
foreach($links as $key => $link)
{
- // Not a note,
- // and (never retrieved yet or no valid cache file)
- if ($link['url'][0] != '?'
- && (! isset($link['thumbnail']) || ($link['thumbnail'] !== false && ! is_file($link['thumbnail'])))
- ) {
- $item = $LINKSDB[$key];
- $item['thumbnail'] = $thumbnailer->get($link['url']);
- $LINKSDB[$key] = $item;
- $newThumbnailsCpt++;
- }
-
if (isset($link['thumbnail']) && $link['thumbnail'] !== false) {
$linksToDisplay[] = $link; // Add to array.
}
-
- // If we retrieved new thumbnails, we update the database every 20 links.
- // Downloading everything the first time may take a very long time
- if ($newThumbnailsCpt == 20) {
- $LINKSDB->save($conf->get('resource.page_cache'));
- $newThumbnailsCpt = 0;
- }
- }
-
- if ($newThumbnailsCpt > 0) {
- $LINKSDB->save($conf->get('resource.page_cache'));
}
$data = array(
@@ -654,7 +657,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
$PAGE->assign($key, $value);
}
- $PAGE->assign('pagetitle', t('Picture wall') .' - '. $conf->get('general.title', 'Shaarli'));
+
$PAGE->renderPage('picwall');
exit;
}
@@ -1036,7 +1039,16 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
$conf->set('api.enabled', !empty($_POST['enableApi']));
$conf->set('api.secret', escape($_POST['apiSecret']));
$conf->set('translation.language', escape($_POST['language']));
- $conf->set('thumbnails.enabled', extension_loaded('gd') && !empty($_POST['enableThumbnails']));
+
+ $thumbnailsMode = extension_loaded('gd') ? $_POST['enableThumbnails'] : Thumbnailer::MODE_NONE;
+ if ($thumbnailsMode !== Thumbnailer::MODE_NONE
+ && $thumbnailsMode !== $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE)
+ ) {
+ $_SESSION['warnings'][] = t(
+ 'You have enabled or changed thumbnails mode. Please synchronize them.'
+ );
+ }
+ $conf->set('thumbnails.mode', $thumbnailsMode);
try {
$conf->write($loginManager->isLoggedIn());
@@ -1077,6 +1089,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
$PAGE->assign('languages', Languages::getAvailableLanguages());
$PAGE->assign('language', $conf->get('translation.language'));
$PAGE->assign('gd_enabled', extension_loaded('gd'));
+ $PAGE->assign('thumbnails_mode', $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE));
$PAGE->assign('pagetitle', t('Configure') .' - '. $conf->get('general.title', 'Shaarli'));
$PAGE->renderPage('configure');
exit;
@@ -1133,7 +1146,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
// Linkdate is kept here to:
// - use the same permalink for notes as they're displayed when creating them
// - let users hack creation date of their posts
- // See: https://shaarli.readthedocs.io/en/master/Various-hacks/#changing-the-timestamp-for-a-shaare
+ // See: https://shaarli.readthedocs.io/en/master/guides/various-hacks/#changing-the-timestamp-for-a-shaare
$linkdate = escape($_POST['lf_linkdate']);
if (isset($LINKSDB[$id])) {
// Edit
@@ -1178,7 +1191,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
$link['title'] = $link['url'];
}
- if ($conf->get('thumbnails.enabled')) {
+ if ($conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE) {
$thumbnailer = new Thumbnailer($conf);
$link['thumbnail'] = $thumbnailer->get($url);
}
@@ -1521,6 +1534,43 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
exit;
}
+ // -------- Thumbnails Update
+ if ($targetPage == Router::$PAGE_THUMBS_UPDATE) {
+ $ids = [];
+ foreach ($LINKSDB as $link) {
+ // A note or not HTTP(S)
+ if ($link['url'][0] === '?' || ! startsWith(strtolower($link['url']), 'http')) {
+ continue;
+ }
+ $ids[] = $link['id'];
+ }
+ $PAGE->assign('ids', $ids);
+ $PAGE->assign('pagetitle', t('Thumbnails update') .' - '. $conf->get('general.title', 'Shaarli'));
+ $PAGE->renderPage('thumbnails');
+ exit;
+ }
+
+ // -------- Single Thumbnail Update
+ if ($targetPage == Router::$AJAX_THUMB_UPDATE) {
+ if (! isset($_POST['id']) || ! ctype_digit($_POST['id'])) {
+ http_response_code(400);
+ exit;
+ }
+ $id = (int) $_POST['id'];
+ if (empty($LINKSDB[$id])) {
+ http_response_code(404);
+ exit;
+ }
+ $thumbnailer = new Thumbnailer($conf);
+ $link = $LINKSDB[$id];
+ $link['thumbnail'] = $thumbnailer->get($link['url']);
+ $LINKSDB[$id] = $link;
+ $LINKSDB->save($conf->get('resource.page_cache'));
+
+ echo json_encode($link);
+ exit;
+ }
+
// -------- Otherwise, simply display search form and links:
showLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager);
exit;
@@ -1585,7 +1635,8 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
$i = ($page-1) * $_SESSION['LINKS_PER_PAGE'];
$end = $i + $_SESSION['LINKS_PER_PAGE'];
- if ($conf->get('thumbnails.enabled')) {
+ $thumbnailsEnabled = $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE;
+ if ($thumbnailsEnabled) {
$thumbnailer = new Thumbnailer($conf);
}
@@ -1610,9 +1661,9 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
uasort($taglist, 'strcasecmp');
$link['taglist'] = $taglist;
- // Thumbnails enabled, not a note,
+ // Logged in, thumbnails enabled, not a note,
// and (never retrieved yet or no valid cache file)
- if ($conf->get('thumbnails.enabled') && $link['url'][0] != '?'
+ if ($loginManager->isLoggedIn() && $thumbnailsEnabled && $link['url'][0] != '?'
&& (! isset($link['thumbnail']) || ($link['thumbnail'] !== false && ! is_file($link['thumbnail'])))
) {
$elem = $LINKSDB[$keys[$i]];
@@ -1694,7 +1745,7 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
* @param SessionManager $sessionManager SessionManager instance
* @param LoginManager $loginManager LoginManager instance
*/
-function install($conf, $sessionManager, $loginManager) {
+function install($conf, $sessionManager, $loginManager, $userspace) {
// On free.fr host, make sure the /sessions directory exists, otherwise login will not work.
if (endsWith($_SERVER['HTTP_HOST'],'.free.fr') && !is_dir($_SERVER['DOCUMENT_ROOT'].'/sessions')) mkdir($_SERVER['DOCUMENT_ROOT'].'/sessions',0705);
@@ -1730,7 +1781,7 @@ function install($conf, $sessionManager, $loginManager) {
}
- if (!empty($_POST['setlogin']) && !empty($_POST['setpassword']))
+ if (true)
{
$tz = 'UTC';
if (!empty($_POST['continent']) && !empty($_POST['city'])
@@ -1739,15 +1790,15 @@ function install($conf, $sessionManager, $loginManager) {
$tz = $_POST['continent'].'/'.$_POST['city'];
}
$conf->set('general.timezone', $tz);
- $login = $_POST['setlogin'];
- $conf->set('credentials.login', $login);
+ $conf->set('credentials.login', $userspace);
$salt = sha1(uniqid('', true) .'_'. mt_rand());
$conf->set('credentials.salt', $salt);
- $conf->set('credentials.hash', sha1($_POST['setpassword'] . $login . $salt));
+ $hash = sha1(uniqid('', true) .'_'. mt_rand());
+ $conf->set('credentials.hash', $hash);
if (!empty($_POST['title'])) {
$conf->set('general.title', escape($_POST['title']));
} else {
- $conf->set('general.title', 'Shared links on '.escape(index_url($_SERVER)));
+ $conf->set('general.title', ucwords(str_replace("_", " ", $userspace)));
}
$conf->set('translation.language', escape($_POST['language']));
$conf->set('updates.check_updates', !empty($_POST['updateCheck']));
@@ -1777,7 +1828,7 @@ function install($conf, $sessionManager, $loginManager) {
exit;
}
- $PAGE = new PageBuilder($conf, null, $sessionManager->generateToken());
+ $PAGE = new PageBuilder($conf, $_SESSION, null, $sessionManager->generateToken());
list($continents, $cities) = generateTimeZoneData(timezone_identifiers_list(), date_default_timezone_get());
$PAGE->assign('continents', $continents);
$PAGE->assign('cities', $cities);
@@ -1786,7 +1837,11 @@ function install($conf, $sessionManager, $loginManager) {
exit;
}
-if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) { showDailyRSS($conf); exit; }
+if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) {
+ showDailyRSS($conf, $loginManager);
+ exit;
+}
+
if (!isset($_SESSION['LINKS_PER_PAGE'])) {
$_SESSION['LINKS_PER_PAGE'] = $conf->get('general.links_per_page', 20);
}
@@ -1812,20 +1867,31 @@ $container['history'] = $history;
$app = new \Slim\App($container);
// REST API routes
-$app->group('/api/v1', function() {
+if (isset($userspace)) {
+ $mountpoint = '/' . $userspace . '/api/v1';
+} else {
+ $mountpoint = '/api/v1';
+}
+$app->group($mountpoint, function() {
$this->get('/info', '\Shaarli\Api\Controllers\Info:getInfo')->setName('getInfo');
$this->get('/links', '\Shaarli\Api\Controllers\Links:getLinks')->setName('getLinks');
$this->get('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:getLink')->setName('getLink');
$this->post('/links', '\Shaarli\Api\Controllers\Links:postLink')->setName('postLink');
$this->put('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:putLink')->setName('putLink');
$this->delete('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:deleteLink')->setName('deleteLink');
+
+ $this->get('/tags', '\Shaarli\Api\Controllers\Tags:getTags')->setName('getTags');
+ $this->get('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:getTag')->setName('getTag');
+ $this->put('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:putTag')->setName('putTag');
+ $this->delete('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:deleteTag')->setName('deleteTag');
+
$this->get('/history', '\Shaarli\Api\Controllers\History:getHistory')->setName('getHistory');
})->add('\Shaarli\Api\ApiMiddleware');
$response = $app->run(true);
// Hack to make Slim and Shaarli router work together:
// If a Slim route isn't found and NOT API call, we call renderPage().
-if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], '/api/v1') === false) {
+if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], $mountpoint) === false) {
// We use UTF-8 for proper international characters handling.
header('Content-Type: text/html; charset=utf-8');
renderPage($conf, $pluginManager, $linkDb, $history, $sessionManager, $loginManager);