Process main page (linklist) through Slim controller
Including a bunch of improvements on the container, and helper used across new controllers.
This commit is contained in:
parent
6132d64748
commit
1a8ac737e5
44 changed files with 1459 additions and 747 deletions
|
@ -71,7 +71,14 @@ class ApiMiddleware
|
|||
$response = $e->getApiResponse();
|
||||
}
|
||||
|
||||
return $response;
|
||||
return $response
|
||||
->withHeader('Access-Control-Allow-Origin', '*')
|
||||
->withHeader(
|
||||
'Access-Control-Allow-Headers',
|
||||
'X-Requested-With, Content-Type, Accept, Origin, Authorization'
|
||||
)
|
||||
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -93,7 +93,7 @@ class BookmarkFileService implements BookmarkServiceInterface
|
|||
throw new Exception('Not authorized');
|
||||
}
|
||||
|
||||
return $bookmark;
|
||||
return $first;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,6 +18,8 @@ use Shaarli\Render\PageCacheManager;
|
|||
use Shaarli\Security\LoginManager;
|
||||
use Shaarli\Security\SessionManager;
|
||||
use Shaarli\Thumbnailer;
|
||||
use Shaarli\Updater\Updater;
|
||||
use Shaarli\Updater\UpdaterUtils;
|
||||
|
||||
/**
|
||||
* Class ContainerBuilder
|
||||
|
@ -128,6 +130,15 @@ class ContainerBuilder
|
|||
return new NetscapeBookmarkUtils($container->bookmarkService, $container->conf, $container->history);
|
||||
};
|
||||
|
||||
$container['updater'] = function (ShaarliContainer $container): Updater {
|
||||
return new Updater(
|
||||
UpdaterUtils::read_updates_file($container->conf->get('resource.updates')),
|
||||
$container->bookmarkService,
|
||||
$container->conf,
|
||||
$container->loginManager->isLoggedIn()
|
||||
);
|
||||
};
|
||||
|
||||
return $container;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,15 +17,17 @@ use Shaarli\Render\PageCacheManager;
|
|||
use Shaarli\Security\LoginManager;
|
||||
use Shaarli\Security\SessionManager;
|
||||
use Shaarli\Thumbnailer;
|
||||
use Shaarli\Updater\Updater;
|
||||
use Slim\Container;
|
||||
|
||||
/**
|
||||
* Extension of Slim container to document the injected objects.
|
||||
*
|
||||
* @property string $basePath Shaarli's instance base path (e.g. `/shaarli/`)
|
||||
* @property string $basePath Shaarli's instance base path (e.g. `/shaarli/`)
|
||||
* @property BookmarkServiceInterface $bookmarkService
|
||||
* @property ConfigManager $conf
|
||||
* @property mixed[] $environment $_SERVER automatically injected by Slim
|
||||
* @property mixed[] $environment $_SERVER automatically injected by Slim
|
||||
* @property callable $errorHandler Overrides default Slim error display
|
||||
* @property FeedBuilder $feedBuilder
|
||||
* @property FormatterFactory $formatterFactory
|
||||
* @property History $history
|
||||
|
@ -37,6 +39,7 @@ use Slim\Container;
|
|||
* @property PluginManager $pluginManager
|
||||
* @property SessionManager $sessionManager
|
||||
* @property Thumbnailer $thumbnailer
|
||||
* @property Updater $updater
|
||||
*/
|
||||
class ShaarliContainer extends Container
|
||||
{
|
||||
|
|
|
@ -25,6 +25,8 @@ class ShaarliMiddleware
|
|||
|
||||
/**
|
||||
* Middleware execution:
|
||||
* - run updates
|
||||
* - if not logged in open shaarli, redirect to login
|
||||
* - execute the controller
|
||||
* - return the response
|
||||
*
|
||||
|
@ -36,27 +38,82 @@ class ShaarliMiddleware
|
|||
*
|
||||
* @return Response response.
|
||||
*/
|
||||
public function __invoke(Request $request, Response $response, callable $next)
|
||||
public function __invoke(Request $request, Response $response, callable $next): Response
|
||||
{
|
||||
$this->container->basePath = rtrim($request->getUri()->getBasePath(), '/');
|
||||
|
||||
try {
|
||||
$response = $next($request, $response);
|
||||
$this->runUpdates();
|
||||
$this->checkOpenShaarli($request, $response, $next);
|
||||
|
||||
return $next($request, $response);
|
||||
} catch (ShaarliFrontException $e) {
|
||||
// Possible functional error
|
||||
$this->container->pageBuilder->reset();
|
||||
$this->container->pageBuilder->assign('message', $e->getMessage());
|
||||
if ($this->container->conf->get('dev.debug', false)) {
|
||||
$this->container->pageBuilder->assign(
|
||||
'stacktrace',
|
||||
nl2br(get_class($this) .': '. $e->getTraceAsString())
|
||||
);
|
||||
}
|
||||
|
||||
$response = $response->withStatus($e->getCode());
|
||||
$response = $response->write($this->container->pageBuilder->render('error'));
|
||||
|
||||
return $response->write($this->container->pageBuilder->render('error'));
|
||||
} catch (UnauthorizedException $e) {
|
||||
return $response->withRedirect($this->container->basePath . '/login');
|
||||
} catch (\Throwable $e) {
|
||||
// Unknown error encountered
|
||||
$this->container->pageBuilder->reset();
|
||||
if ($this->container->conf->get('dev.debug', false)) {
|
||||
$this->container->pageBuilder->assign('message', $e->getMessage());
|
||||
$this->container->pageBuilder->assign(
|
||||
'stacktrace',
|
||||
nl2br(get_class($e) .': '. PHP_EOL . $e->getTraceAsString())
|
||||
);
|
||||
} else {
|
||||
$this->container->pageBuilder->assign('message', t('An unexpected error occurred.'));
|
||||
}
|
||||
|
||||
$response = $response->withStatus(500);
|
||||
|
||||
return $response->write($this->container->pageBuilder->render('error'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the updater for every requests processed while logged in.
|
||||
*/
|
||||
protected function runUpdates(): void
|
||||
{
|
||||
if ($this->container->loginManager->isLoggedIn() !== true) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $response;
|
||||
$newUpdates = $this->container->updater->update();
|
||||
if (!empty($newUpdates)) {
|
||||
$this->container->updater->writeUpdates(
|
||||
$this->container->conf->get('resource.updates'),
|
||||
$this->container->updater->getDoneUpdates()
|
||||
);
|
||||
|
||||
$this->container->pageCacheManager->invalidateCaches();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Access is denied to most pages with `hide_public_links` + `force_login` settings.
|
||||
*/
|
||||
protected function checkOpenShaarli(Request $request, Response $response, callable $next): bool
|
||||
{
|
||||
if (// if the user isn't logged in
|
||||
!$this->container->loginManager->isLoggedIn()
|
||||
// and Shaarli doesn't have public content...
|
||||
&& $this->container->conf->get('privacy.hide_public_links')
|
||||
// and is configured to enforce the login
|
||||
&& $this->container->conf->get('privacy.force_login')
|
||||
// and the current page isn't already the login page
|
||||
// and the user is not requesting a feed (which would lead to a different content-type as expected)
|
||||
&& !in_array($next->getName(), ['login', 'atom', 'rss'], true)
|
||||
) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Shaarli\Front\Controller\Admin;
|
||||
|
||||
use Shaarli\Languages;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Shaarli\Render\ThemeUtils;
|
||||
use Shaarli\Thumbnailer;
|
||||
use Slim\Http\Request;
|
||||
|
@ -52,7 +53,7 @@ class ConfigureController extends ShaarliAdminController
|
|||
$this->assignView('thumbnails_mode', $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE));
|
||||
$this->assignView('pagetitle', t('Configure') .' - '. $this->container->conf->get('general.title', 'Shaarli'));
|
||||
|
||||
return $response->write($this->render('configure'));
|
||||
return $response->write($this->render(TemplatePage::CONFIGURE));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace Shaarli\Front\Controller\Admin;
|
|||
|
||||
use DateTime;
|
||||
use Shaarli\Bookmark\Bookmark;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
|
@ -24,7 +25,7 @@ class ExportController extends ShaarliAdminController
|
|||
{
|
||||
$this->assignView('pagetitle', t('Export') .' - '. $this->container->conf->get('general.title', 'Shaarli'));
|
||||
|
||||
return $response->write($this->render('export'));
|
||||
return $response->write($this->render(TemplatePage::EXPORT));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,6 +75,6 @@ class ExportController extends ShaarliAdminController
|
|||
$this->assignView('eol', PHP_EOL);
|
||||
$this->assignView('selection', $selection);
|
||||
|
||||
return $response->write($this->render('export.bookmarks'));
|
||||
return $response->write($this->render(TemplatePage::NETSCAPE_EXPORT_BOOKMARKS));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Shaarli\Front\Controller\Admin;
|
||||
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
|
@ -39,7 +40,7 @@ class ImportController extends ShaarliAdminController
|
|||
);
|
||||
$this->assignView('pagetitle', t('Import') .' - '. $this->container->conf->get('general.title', 'Shaarli'));
|
||||
|
||||
return $response->write($this->render('import'));
|
||||
return $response->write($this->render(TemplatePage::IMPORT));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Shaarli\Front\Controller\Admin;
|
|||
use Shaarli\Bookmark\Bookmark;
|
||||
use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
|
||||
use Shaarli\Formatter\BookmarkMarkdownFormatter;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Shaarli\Thumbnailer;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
@ -28,7 +29,7 @@ class ManageShaareController extends ShaarliAdminController
|
|||
t('Shaare a new link') .' - '. $this->container->conf->get('general.title', 'Shaarli')
|
||||
);
|
||||
|
||||
return $response->write($this->render('addlink'));
|
||||
return $response->write($this->render(TemplatePage::ADDLINK));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -365,7 +366,7 @@ class ManageShaareController extends ShaarliAdminController
|
|||
$editLabel . t('Shaare') .' - '. $this->container->conf->get('general.title', 'Shaarli')
|
||||
);
|
||||
|
||||
return $response->write($this->render('editlink'));
|
||||
return $response->write($this->render(TemplatePage::EDIT_LINK));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Shaarli\Front\Controller\Admin;
|
||||
|
||||
use Shaarli\Bookmark\BookmarkFilter;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
|
@ -28,7 +29,7 @@ class ManageTagController extends ShaarliAdminController
|
|||
t('Manage tags') .' - '. $this->container->conf->get('general.title', 'Shaarli')
|
||||
);
|
||||
|
||||
return $response->write($this->render('changetag'));
|
||||
return $response->write($this->render(TemplatePage::CHANGE_TAG));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Shaarli\Front\Controller\Admin;
|
|||
use Shaarli\Container\ShaarliContainer;
|
||||
use Shaarli\Front\Exception\OpenShaarliPasswordException;
|
||||
use Shaarli\Front\Exception\ShaarliFrontException;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
use Throwable;
|
||||
|
@ -33,7 +34,7 @@ class PasswordController extends ShaarliAdminController
|
|||
*/
|
||||
public function index(Request $request, Response $response): Response
|
||||
{
|
||||
return $response->write($this->render('changepassword'));
|
||||
return $response->write($this->render(TemplatePage::CHANGE_PASSWORD));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,7 +56,7 @@ class PasswordController extends ShaarliAdminController
|
|||
|
||||
return $response
|
||||
->withStatus(400)
|
||||
->write($this->render('changepassword'))
|
||||
->write($this->render(TemplatePage::CHANGE_PASSWORD))
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -71,7 +72,7 @@ class PasswordController extends ShaarliAdminController
|
|||
|
||||
return $response
|
||||
->withStatus(400)
|
||||
->write($this->render('changepassword'))
|
||||
->write($this->render(TemplatePage::CHANGE_PASSWORD))
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -95,6 +96,6 @@ class PasswordController extends ShaarliAdminController
|
|||
|
||||
$this->saveSuccessMessage(t('Your password has been changed'));
|
||||
|
||||
return $response->write($this->render('changepassword'));
|
||||
return $response->write($this->render(TemplatePage::CHANGE_PASSWORD));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Shaarli\Front\Controller\Admin;
|
||||
|
||||
use Exception;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
|
@ -44,7 +45,7 @@ class PluginsController extends ShaarliAdminController
|
|||
t('Plugin Administration') .' - '. $this->container->conf->get('general.title', 'Shaarli')
|
||||
);
|
||||
|
||||
return $response->write($this->render('pluginsadmin'));
|
||||
return $response->write($this->render(TemplatePage::PLUGINS_ADMIN));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Shaarli\Front\Controller\Admin;
|
||||
|
||||
use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
|
@ -36,7 +37,7 @@ class ThumbnailsController extends ShaarliAdminController
|
|||
t('Thumbnails update') .' - '. $this->container->conf->get('general.title', 'Shaarli')
|
||||
);
|
||||
|
||||
return $response->write($this->render('thumbnails'));
|
||||
return $response->write($this->render(TemplatePage::THUMBNAILS));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,19 +62,4 @@ class ThumbnailsController extends ShaarliAdminController
|
|||
|
||||
return $response->withJson($this->container->formatterFactory->getFormatter('raw')->format($bookmark));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $data Variables passed to the template engine
|
||||
*
|
||||
* @return mixed[] Template data after active plugins render_picwall hook execution.
|
||||
*/
|
||||
protected function executeHooks(array $data): array
|
||||
{
|
||||
$this->container->pluginManager->executeHooks(
|
||||
'render_tools',
|
||||
$data
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Shaarli\Front\Controller\Admin;
|
||||
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
|
@ -29,7 +30,7 @@ class ToolsController extends ShaarliAdminController
|
|||
|
||||
$this->assignView('pagetitle', t('Tools') .' - '. $this->container->conf->get('general.title', 'Shaarli'));
|
||||
|
||||
return $response->write($this->render('tools'));
|
||||
return $response->write($this->render(TemplatePage::TOOLS));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
248
application/front/controller/visitor/BookmarkListController.php
Normal file
248
application/front/controller/visitor/BookmarkListController.php
Normal file
|
@ -0,0 +1,248 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shaarli\Front\Controller\Visitor;
|
||||
|
||||
use Shaarli\Bookmark\Bookmark;
|
||||
use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
|
||||
use Shaarli\Legacy\LegacyController;
|
||||
use Shaarli\Legacy\UnknowLegacyRouteException;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Shaarli\Thumbnailer;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
/**
|
||||
* Class BookmarkListController
|
||||
*
|
||||
* Slim controller used to render the bookmark list, the home page of Shaarli.
|
||||
* It also displays permalinks, and process legacy routes based on GET parameters.
|
||||
*/
|
||||
class BookmarkListController extends ShaarliVisitorController
|
||||
{
|
||||
/**
|
||||
* GET / - Displays the bookmark list, with optional filter parameters.
|
||||
*/
|
||||
public function index(Request $request, Response $response): Response
|
||||
{
|
||||
$legacyResponse = $this->processLegacyController($request, $response);
|
||||
if (null !== $legacyResponse) {
|
||||
return $legacyResponse;
|
||||
}
|
||||
|
||||
$formatter = $this->container->formatterFactory->getFormatter();
|
||||
|
||||
$searchTags = escape(normalize_spaces($request->getParam('searchtags') ?? ''));
|
||||
$searchTerm = escape(normalize_spaces($request->getParam('searchterm') ?? ''));;
|
||||
|
||||
// Filter bookmarks according search parameters.
|
||||
$visibility = $this->container->sessionManager->getSessionParameter('visibility');
|
||||
$search = [
|
||||
'searchtags' => $searchTags,
|
||||
'searchterm' => $searchTerm,
|
||||
];
|
||||
$linksToDisplay = $this->container->bookmarkService->search(
|
||||
$search,
|
||||
$visibility,
|
||||
false,
|
||||
!!$this->container->sessionManager->getSessionParameter('untaggedonly')
|
||||
) ?? [];
|
||||
|
||||
// ---- Handle paging.
|
||||
$keys = [];
|
||||
foreach ($linksToDisplay as $key => $value) {
|
||||
$keys[] = $key;
|
||||
}
|
||||
|
||||
$linksPerPage = $this->container->sessionManager->getSessionParameter('LINKS_PER_PAGE', 20) ?: 20;
|
||||
|
||||
// Select articles according to paging.
|
||||
$pageCount = (int) ceil(count($keys) / $linksPerPage) ?: 1;
|
||||
$page = (int) $request->getParam('page') ?? 1;
|
||||
$page = $page < 1 ? 1 : $page;
|
||||
$page = $page > $pageCount ? $pageCount : $page;
|
||||
|
||||
// Start index.
|
||||
$i = ($page - 1) * $linksPerPage;
|
||||
$end = $i + $linksPerPage;
|
||||
|
||||
$linkDisp = [];
|
||||
$save = false;
|
||||
while ($i < $end && $i < count($keys)) {
|
||||
$save = $this->updateThumbnail($linksToDisplay[$keys[$i]], false) || $save;
|
||||
$link = $formatter->format($linksToDisplay[$keys[$i]]);
|
||||
|
||||
$linkDisp[$keys[$i]] = $link;
|
||||
$i++;
|
||||
}
|
||||
|
||||
if ($save) {
|
||||
$this->container->bookmarkService->save();
|
||||
}
|
||||
|
||||
// Compute paging navigation
|
||||
$searchtagsUrl = $searchTags === '' ? '' : '&searchtags=' . urlencode($searchTags);
|
||||
$searchtermUrl = $searchTerm === '' ? '' : '&searchterm=' . urlencode($searchTerm);
|
||||
|
||||
$previous_page_url = '';
|
||||
if ($i !== count($keys)) {
|
||||
$previous_page_url = '?page=' . ($page + 1) . $searchtermUrl . $searchtagsUrl;
|
||||
}
|
||||
$next_page_url = '';
|
||||
if ($page > 1) {
|
||||
$next_page_url = '?page=' . ($page - 1) . $searchtermUrl . $searchtagsUrl;
|
||||
}
|
||||
|
||||
// Fill all template fields.
|
||||
$data = array_merge(
|
||||
$this->initializeTemplateVars(),
|
||||
[
|
||||
'previous_page_url' => $previous_page_url,
|
||||
'next_page_url' => $next_page_url,
|
||||
'page_current' => $page,
|
||||
'page_max' => $pageCount,
|
||||
'result_count' => count($linksToDisplay),
|
||||
'search_term' => $searchTerm,
|
||||
'search_tags' => $searchTags,
|
||||
'visibility' => $visibility,
|
||||
'links' => $linkDisp,
|
||||
]
|
||||
);
|
||||
|
||||
if (!empty($searchTerm) || !empty($searchTags)) {
|
||||
$data['pagetitle'] = t('Search: ');
|
||||
$data['pagetitle'] .= ! empty($searchTerm) ? $searchTerm . ' ' : '';
|
||||
$bracketWrap = function ($tag) {
|
||||
return '[' . $tag . ']';
|
||||
};
|
||||
$data['pagetitle'] .= ! empty($searchTags)
|
||||
? implode(' ', array_map($bracketWrap, preg_split('/\s+/', $searchTags))) . ' '
|
||||
: '';
|
||||
$data['pagetitle'] .= '- ';
|
||||
}
|
||||
|
||||
$data['pagetitle'] = ($data['pagetitle'] ?? '') . $this->container->conf->get('general.title', 'Shaarli');
|
||||
|
||||
$this->executeHooks($data);
|
||||
$this->assignAllView($data);
|
||||
|
||||
return $response->write($this->render(TemplatePage::LINKLIST));
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /shaare/{hash} - Display a single shaare
|
||||
*/
|
||||
public function permalink(Request $request, Response $response, array $args): Response
|
||||
{
|
||||
try {
|
||||
$bookmark = $this->container->bookmarkService->findByHash($args['hash']);
|
||||
} catch (BookmarkNotFoundException $e) {
|
||||
$this->assignView('error_message', $e->getMessage());
|
||||
|
||||
return $response->write($this->render(TemplatePage::ERROR_404));
|
||||
}
|
||||
|
||||
$this->updateThumbnail($bookmark);
|
||||
|
||||
$data = array_merge(
|
||||
$this->initializeTemplateVars(),
|
||||
[
|
||||
'pagetitle' => $bookmark->getTitle() .' - '. $this->container->conf->get('general.title', 'Shaarli'),
|
||||
'links' => [$this->container->formatterFactory->getFormatter()->format($bookmark)],
|
||||
]
|
||||
);
|
||||
|
||||
$this->executeHooks($data);
|
||||
$this->assignAllView($data);
|
||||
|
||||
return $response->write($this->render(TemplatePage::LINKLIST));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the thumbnail of a single bookmark if necessary.
|
||||
*/
|
||||
protected function updateThumbnail(Bookmark $bookmark, bool $writeDatastore = true): bool
|
||||
{
|
||||
// Logged in, thumbnails enabled, not a note, is HTTP
|
||||
// and (never retrieved yet or no valid cache file)
|
||||
if ($this->container->loginManager->isLoggedIn()
|
||||
&& $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
|
||||
&& false !== $bookmark->getThumbnail()
|
||||
&& !$bookmark->isNote()
|
||||
&& (null === $bookmark->getThumbnail() || !is_file($bookmark->getThumbnail()))
|
||||
&& startsWith(strtolower($bookmark->getUrl()), 'http')
|
||||
) {
|
||||
$bookmark->setThumbnail($this->container->thumbnailer->get($bookmark->getUrl()));
|
||||
$this->container->bookmarkService->set($bookmark, $writeDatastore);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $data Template vars to process in plugins, passed as reference.
|
||||
*/
|
||||
protected function executeHooks(array &$data): void
|
||||
{
|
||||
$this->container->pluginManager->executeHooks(
|
||||
'render_linklist',
|
||||
$data,
|
||||
['loggedin' => $this->container->loginManager->isLoggedIn()]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Default template variables without values.
|
||||
*/
|
||||
protected function initializeTemplateVars(): array
|
||||
{
|
||||
return [
|
||||
'previous_page_url' => '',
|
||||
'next_page_url' => '',
|
||||
'page_max' => '',
|
||||
'search_tags' => '',
|
||||
'result_count' => '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Process legacy routes if necessary. They used query parameters.
|
||||
* If no legacy routes is passed, return null.
|
||||
*/
|
||||
protected function processLegacyController(Request $request, Response $response): ?Response
|
||||
{
|
||||
// Legacy smallhash filter
|
||||
$queryString = $this->container->environment['QUERY_STRING'] ?? null;
|
||||
if (null !== $queryString && 1 === preg_match('/^([a-zA-Z0-9-_@]{6})($|&|#)/', $queryString, $match)) {
|
||||
return $this->redirect($response, '/shaare/' . $match[1]);
|
||||
}
|
||||
|
||||
// Legacy controllers (mostly used for redirections)
|
||||
if (null !== $request->getQueryParam('do')) {
|
||||
$legacyController = new LegacyController($this->container);
|
||||
|
||||
try {
|
||||
return $legacyController->process($request, $response, $request->getQueryParam('do'));
|
||||
} catch (UnknowLegacyRouteException $e) {
|
||||
// We ignore legacy 404
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy GET admin routes
|
||||
$legacyGetRoutes = array_intersect(
|
||||
LegacyController::LEGACY_GET_ROUTES,
|
||||
array_keys($request->getQueryParams() ?? [])
|
||||
);
|
||||
if (1 === count($legacyGetRoutes)) {
|
||||
$legacyController = new LegacyController($this->container);
|
||||
|
||||
return $legacyController->process($request, $response, $legacyGetRoutes[0]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ namespace Shaarli\Front\Controller\Visitor;
|
|||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use Shaarli\Bookmark\Bookmark;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
|
@ -85,7 +86,7 @@ class DailyController extends ShaarliVisitorController
|
|||
t('Daily') .' - '. format_date($dayDate, false) . ' - ' . $mainTitle
|
||||
);
|
||||
|
||||
return $response->write($this->render('daily'));
|
||||
return $response->write($this->render(TemplatePage::DAILY));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -152,7 +153,7 @@ class DailyController extends ShaarliVisitorController
|
|||
$this->assignView('hide_timestamps', $this->container->conf->get('privacy.hide_timestamps', false));
|
||||
$this->assignView('days', $dataPerDay);
|
||||
|
||||
$rssContent = $this->render('dailyrss');
|
||||
$rssContent = $this->render(TemplatePage::DAILY_RSS);
|
||||
|
||||
$cache->cache($rssContent);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Shaarli\Front\Controller\Visitor;
|
||||
|
||||
use Shaarli\Front\Exception\LoginBannedException;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
|
@ -41,6 +42,6 @@ class LoginController extends ShaarliVisitorController
|
|||
->assignView('pagetitle', t('Login') .' - '. $this->container->conf->get('general.title', 'Shaarli'))
|
||||
;
|
||||
|
||||
return $response->write($this->render('loginform'));
|
||||
return $response->write($this->render(TemplatePage::LOGIN));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Shaarli\Front\Controller\Visitor;
|
||||
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
|
@ -21,6 +22,6 @@ class OpenSearchController extends ShaarliVisitorController
|
|||
|
||||
$this->assignView('serverurl', index_url($this->container->environment));
|
||||
|
||||
return $response->write($this->render('opensearch'));
|
||||
return $response->write($this->render(TemplatePage::OPEN_SEARCH));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Shaarli\Front\Controller\Visitor;
|
||||
|
||||
use Shaarli\Front\Exception\ThumbnailsDisabledException;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Shaarli\Thumbnailer;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
@ -46,7 +47,7 @@ class PictureWallController extends ShaarliVisitorController
|
|||
$this->assignView($key, $value);
|
||||
}
|
||||
|
||||
return $response->write($this->render('picwall'));
|
||||
return $response->write($this->render(TemplatePage::PICTURE_WALL));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
130
application/legacy/LegacyController.php
Normal file
130
application/legacy/LegacyController.php
Normal file
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shaarli\Legacy;
|
||||
|
||||
use Shaarli\Feed\FeedBuilder;
|
||||
use Shaarli\Front\Controller\Visitor\ShaarliVisitorController;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
/**
|
||||
* We use this to maintain legacy routes, and redirect requests to the corresponding Slim route.
|
||||
* Only public routes, and both `?addlink` and `?post` were kept here.
|
||||
* Other routes will just display the linklist.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
class LegacyController extends ShaarliVisitorController
|
||||
{
|
||||
/** @var string[] Both `?post` and `?addlink` do not use `?do=` format. */
|
||||
public const LEGACY_GET_ROUTES = [
|
||||
'post',
|
||||
'addlink',
|
||||
];
|
||||
|
||||
/**
|
||||
* This method will call `$action` method, which will redirect to corresponding Slim route.
|
||||
*/
|
||||
public function process(Request $request, Response $response, string $action): Response
|
||||
{
|
||||
if (!method_exists($this, $action)) {
|
||||
throw new UnknowLegacyRouteException();
|
||||
}
|
||||
|
||||
return $this->{$action}($request, $response);
|
||||
}
|
||||
|
||||
/** Legacy route: ?post= */
|
||||
public function post(Request $request, Response $response): Response
|
||||
{
|
||||
$parameters = count($request->getQueryParams()) > 0 ? '?' . http_build_query($request->getQueryParams()) : '';
|
||||
|
||||
if (!$this->container->loginManager->isLoggedIn()) {
|
||||
return $this->redirect($response, '/login' . $parameters);
|
||||
}
|
||||
|
||||
return $this->redirect($response, '/admin/shaare' . $parameters);
|
||||
}
|
||||
|
||||
/** Legacy route: ?addlink= */
|
||||
protected function addlink(Request $request, Response $response): Response
|
||||
{
|
||||
if (!$this->container->loginManager->isLoggedIn()) {
|
||||
return $this->redirect($response, '/login');
|
||||
}
|
||||
|
||||
return $this->redirect($response, '/admin/add-shaare');
|
||||
}
|
||||
|
||||
/** Legacy route: ?do=login */
|
||||
protected function login(Request $request, Response $response): Response
|
||||
{
|
||||
return $this->redirect($response, '/login');
|
||||
}
|
||||
|
||||
/** Legacy route: ?do=logout */
|
||||
protected function logout(Request $request, Response $response): Response
|
||||
{
|
||||
return $this->redirect($response, '/logout');
|
||||
}
|
||||
|
||||
/** Legacy route: ?do=picwall */
|
||||
protected function picwall(Request $request, Response $response): Response
|
||||
{
|
||||
return $this->redirect($response, '/picture-wall');
|
||||
}
|
||||
|
||||
/** Legacy route: ?do=tagcloud */
|
||||
protected function tagcloud(Request $request, Response $response): Response
|
||||
{
|
||||
return $this->redirect($response, '/tags/cloud');
|
||||
}
|
||||
|
||||
/** Legacy route: ?do=taglist */
|
||||
protected function taglist(Request $request, Response $response): Response
|
||||
{
|
||||
return $this->redirect($response, '/tags/list');
|
||||
}
|
||||
|
||||
/** Legacy route: ?do=daily */
|
||||
protected function daily(Request $request, Response $response): Response
|
||||
{
|
||||
$dayParam = !empty($request->getParam('day')) ? '?day=' . escape($request->getParam('day')) : '';
|
||||
|
||||
return $this->redirect($response, '/daily' . $dayParam);
|
||||
}
|
||||
|
||||
/** Legacy route: ?do=rss */
|
||||
protected function rss(Request $request, Response $response): Response
|
||||
{
|
||||
return $this->feed($request, $response, FeedBuilder::$FEED_RSS);
|
||||
}
|
||||
|
||||
/** Legacy route: ?do=atom */
|
||||
protected function atom(Request $request, Response $response): Response
|
||||
{
|
||||
return $this->feed($request, $response, FeedBuilder::$FEED_ATOM);
|
||||
}
|
||||
|
||||
/** Legacy route: ?do=opensearch */
|
||||
protected function opensearch(Request $request, Response $response): Response
|
||||
{
|
||||
return $this->redirect($response, '/open-search');
|
||||
}
|
||||
|
||||
/** Legacy route: ?do=dailyrss */
|
||||
protected function dailyrss(Request $request, Response $response): Response
|
||||
{
|
||||
return $this->redirect($response, '/daily-rss');
|
||||
}
|
||||
|
||||
/** Legacy route: ?do=feed */
|
||||
protected function feed(Request $request, Response $response, string $feedType): Response
|
||||
{
|
||||
$parameters = count($request->getQueryParams()) > 0 ? '?' . http_build_query($request->getQueryParams()) : '';
|
||||
|
||||
return $this->redirect($response, '/feed/' . $feedType . $parameters);
|
||||
}
|
||||
}
|
|
@ -1,12 +1,15 @@
|
|||
<?php
|
||||
namespace Shaarli;
|
||||
|
||||
namespace Shaarli\Legacy;
|
||||
|
||||
/**
|
||||
* Class Router
|
||||
*
|
||||
* (only displayable pages here)
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
class Router
|
||||
class LegacyRouter
|
||||
{
|
||||
public static $AJAX_THUMB_UPDATE = 'ajax_thumb_update';
|
||||
|
9
application/legacy/UnknowLegacyRouteException.php
Normal file
9
application/legacy/UnknowLegacyRouteException.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shaarli\Legacy;
|
||||
|
||||
class UnknowLegacyRouteException extends \Exception
|
||||
{
|
||||
}
|
|
@ -69,6 +69,15 @@ class PageBuilder
|
|||
$this->isLoggedIn = $isLoggedIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset current state of template rendering.
|
||||
* Mostly useful for error handling. We remove everything, and display the error template.
|
||||
*/
|
||||
public function reset(): void
|
||||
{
|
||||
$this->tpl = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize all default tpl tags.
|
||||
*/
|
||||
|
|
33
application/render/TemplatePage.php
Normal file
33
application/render/TemplatePage.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shaarli\Render;
|
||||
|
||||
interface TemplatePage
|
||||
{
|
||||
public const ERROR_404 = '404';
|
||||
public const ADDLINK = 'addlink';
|
||||
public const CHANGE_PASSWORD = 'changepassword';
|
||||
public const CHANGE_TAG = 'changetag';
|
||||
public const CONFIGURE = 'configure';
|
||||
public const DAILY = 'daily';
|
||||
public const DAILY_RSS = 'dailyrss';
|
||||
public const EDIT_LINK = 'editlink';
|
||||
public const ERROR = 'error';
|
||||
public const EXPORT = 'export';
|
||||
public const NETSCAPE_EXPORT_BOOKMARKS = 'export.bookmarks';
|
||||
public const FEED_ATOM = 'feed.atom';
|
||||
public const FEED_RSS = 'feed.rss';
|
||||
public const IMPORT = 'import';
|
||||
public const INSTALL = 'install';
|
||||
public const LINKLIST = 'linklist';
|
||||
public const LOGIN = 'loginform';
|
||||
public const OPEN_SEARCH = 'opensearch';
|
||||
public const PICTURE_WALL = 'picwall';
|
||||
public const PLUGINS_ADMIN = 'pluginsadmin';
|
||||
public const TAG_CLOUD = 'tag.cloud';
|
||||
public const TAG_LIST = 'tag.list';
|
||||
public const THUMBNAILS = 'thumbnails';
|
||||
public const TOOLS = 'tools';
|
||||
}
|
|
@ -21,7 +21,7 @@ class Updater
|
|||
/**
|
||||
* @var BookmarkServiceInterface instance.
|
||||
*/
|
||||
protected $linkServices;
|
||||
protected $bookmarkService;
|
||||
|
||||
/**
|
||||
* @var ConfigManager $conf Configuration Manager instance.
|
||||
|
@ -49,7 +49,7 @@ class Updater
|
|||
public function __construct($doneUpdates, $linkDB, $conf, $isLoggedIn)
|
||||
{
|
||||
$this->doneUpdates = $doneUpdates;
|
||||
$this->linkServices = $linkDB;
|
||||
$this->bookmarkService = $linkDB;
|
||||
$this->conf = $conf;
|
||||
$this->isLoggedIn = $isLoggedIn;
|
||||
|
||||
|
@ -68,7 +68,7 @@ class Updater
|
|||
*/
|
||||
public function update()
|
||||
{
|
||||
$updatesRan = array();
|
||||
$updatesRan = [];
|
||||
|
||||
// If the user isn't logged in, exit without updating.
|
||||
if ($this->isLoggedIn !== true) {
|
||||
|
@ -112,6 +112,16 @@ class Updater
|
|||
return $this->doneUpdates;
|
||||
}
|
||||
|
||||
public function readUpdates(string $updatesFilepath): array
|
||||
{
|
||||
return UpdaterUtils::read_updates_file($updatesFilepath);
|
||||
}
|
||||
|
||||
public function writeUpdates(string $updatesFilepath, array $updates): void
|
||||
{
|
||||
UpdaterUtils::write_updates_file($updatesFilepath, $updates);
|
||||
}
|
||||
|
||||
/**
|
||||
* With the Slim routing system, default header link should be `./` instead of `?`.
|
||||
* Otherwise you can not go back to the home page. Example: `/picture-wall` -> `/picture-wall?` instead of `/`.
|
||||
|
@ -127,4 +137,31 @@ class Updater
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* With the Slim routing system, note bookmarks URL formatted `?abcdef`
|
||||
* should be replaced with `/shaare/abcdef`
|
||||
*/
|
||||
public function updateMethodMigrateExistingNotesUrl(): bool
|
||||
{
|
||||
$updated = false;
|
||||
|
||||
foreach ($this->bookmarkService->search() as $bookmark) {
|
||||
if ($bookmark->isNote()
|
||||
&& startsWith($bookmark->getUrl(), '?')
|
||||
&& 1 === preg_match('/^\?([a-zA-Z0-9-_@]{6})($|&|#)/', $bookmark->getUrl(), $match)
|
||||
) {
|
||||
$updated = true;
|
||||
$bookmark = $bookmark->setUrl('/shaare/' . $match[1]);
|
||||
|
||||
$this->bookmarkService->set($bookmark, false);
|
||||
}
|
||||
}
|
||||
|
||||
if ($updated) {
|
||||
$this->bookmarkService->save();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ If it's still not working, please [open an issue](https://github.com/shaarli/Sha
|
|||
| ------------- |:-------------:|
|
||||
| [render_header](#render_header) | Allow plugin to add content in page headers. |
|
||||
| [render_includes](#render_includes) | Allow plugin to include their own CSS files. |
|
||||
| [render_footer](#render_footer) | Allow plugin to add content in page footer and include their own JS files. |
|
||||
| [render_footer](#render_footer) | Allow plugin to add content in page footer and include their own JS files. |
|
||||
| [render_linklist](#render_linklist) | It allows to add content at the begining and end of the page, after every link displayed and to alter link data. |
|
||||
| [render_editlink](#render_editlink) | Allow to add fields in the form, or display elements. |
|
||||
| [render_tools](#render_tools) | Allow to add content at the end of the page. |
|
||||
|
@ -515,7 +515,7 @@ Otherwise, you can use your own JS as long as this field is send by the form:
|
|||
|
||||
### Placeholder system
|
||||
|
||||
In order to make plugins work with every custom themes, you need to add variable placeholder in your templates.
|
||||
In order to make plugins work with every custom themes, you need to add variable placeholder in your templates.
|
||||
|
||||
It's a RainTPL loop like this:
|
||||
|
||||
|
@ -537,7 +537,7 @@ At the end of the menu:
|
|||
|
||||
At the end of file, before clearing floating blocks:
|
||||
|
||||
{if="!empty($plugin_errors) && isLoggedIn()"}
|
||||
{if="!empty($plugin_errors) && $is_logged_in"}
|
||||
<ul class="errors">
|
||||
{loop="plugin_errors"}
|
||||
<li>{$value}</li>
|
||||
|
|
534
index.php
534
index.php
|
@ -61,30 +61,15 @@ require_once 'application/TimeZone.php';
|
|||
require_once 'application/Utils.php';
|
||||
|
||||
use Shaarli\ApplicationUtils;
|
||||
use Shaarli\Bookmark\Bookmark;
|
||||
use Shaarli\Bookmark\BookmarkFileService;
|
||||
use Shaarli\Bookmark\BookmarkFilter;
|
||||
use Shaarli\Bookmark\BookmarkServiceInterface;
|
||||
use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
|
||||
use Shaarli\Config\ConfigManager;
|
||||
use Shaarli\Container\ContainerBuilder;
|
||||
use Shaarli\Feed\CachedPage;
|
||||
use Shaarli\Feed\FeedBuilder;
|
||||
use Shaarli\Formatter\BookmarkMarkdownFormatter;
|
||||
use Shaarli\Formatter\FormatterFactory;
|
||||
use Shaarli\History;
|
||||
use Shaarli\Languages;
|
||||
use Shaarli\Netscape\NetscapeBookmarkUtils;
|
||||
use Shaarli\Plugin\PluginManager;
|
||||
use Shaarli\Render\PageBuilder;
|
||||
use Shaarli\Render\PageCacheManager;
|
||||
use Shaarli\Render\ThemeUtils;
|
||||
use Shaarli\Router;
|
||||
use Shaarli\Security\LoginManager;
|
||||
use Shaarli\Security\SessionManager;
|
||||
use Shaarli\Thumbnailer;
|
||||
use Shaarli\Updater\Updater;
|
||||
use Shaarli\Updater\UpdaterUtils;
|
||||
use Slim\App;
|
||||
|
||||
// Ensure the PHP version is supported
|
||||
|
@ -196,20 +181,6 @@ if (! is_file($conf->getConfigFileExt())) {
|
|||
|
||||
$loginManager->checkLoginState($_COOKIE, $clientIpId);
|
||||
|
||||
/**
|
||||
* Adapter function to ensure compatibility with third-party templates
|
||||
*
|
||||
* @see https://github.com/shaarli/Shaarli/pull/1086
|
||||
*
|
||||
* @return bool true when the user is logged in, false otherwise
|
||||
*/
|
||||
function isLoggedIn()
|
||||
{
|
||||
global $loginManager;
|
||||
return $loginManager->isLoggedIn();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// Process login form: Check if login/password is correct.
|
||||
if (isset($_POST['login'])) {
|
||||
|
@ -300,473 +271,6 @@ if (!isset($_SESSION['tokens'])) {
|
|||
$_SESSION['tokens']=array(); // Token are attached to the session.
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the linklist
|
||||
*
|
||||
* @param pageBuilder $PAGE pageBuilder instance.
|
||||
* @param BookmarkServiceInterface $linkDb instance.
|
||||
* @param ConfigManager $conf Configuration Manager instance.
|
||||
* @param PluginManager $pluginManager Plugin Manager instance.
|
||||
*/
|
||||
function showLinkList($PAGE, $linkDb, $conf, $pluginManager, $loginManager)
|
||||
{
|
||||
buildLinkList($PAGE, $linkDb, $conf, $pluginManager, $loginManager);
|
||||
$PAGE->renderPage('linklist');
|
||||
}
|
||||
|
||||
/**
|
||||
* Render HTML page (according to URL parameters and user rights)
|
||||
*
|
||||
* @param ConfigManager $conf Configuration Manager instance.
|
||||
* @param PluginManager $pluginManager Plugin Manager instance,
|
||||
* @param BookmarkServiceInterface $bookmarkService
|
||||
* @param History $history instance
|
||||
* @param SessionManager $sessionManager SessionManager instance
|
||||
* @param LoginManager $loginManager LoginManager instance
|
||||
*/
|
||||
function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionManager, $loginManager)
|
||||
{
|
||||
$pageCacheManager = new PageCacheManager($conf->get('resource.page_cache'), $loginManager->isLoggedIn());
|
||||
$updater = new Updater(
|
||||
UpdaterUtils::read_updates_file($conf->get('resource.updates')),
|
||||
$bookmarkService,
|
||||
$conf,
|
||||
$loginManager->isLoggedIn()
|
||||
);
|
||||
try {
|
||||
$newUpdates = $updater->update();
|
||||
if (! empty($newUpdates)) {
|
||||
UpdaterUtils::write_updates_file(
|
||||
$conf->get('resource.updates'),
|
||||
$updater->getDoneUpdates()
|
||||
);
|
||||
|
||||
$pageCacheManager->invalidateCaches();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
die($e->getMessage());
|
||||
}
|
||||
|
||||
$PAGE = new PageBuilder($conf, $_SESSION, $bookmarkService, $sessionManager->generateToken(), $loginManager->isLoggedIn());
|
||||
$PAGE->assign('linkcount', $bookmarkService->count(BookmarkFilter::$ALL));
|
||||
$PAGE->assign('privateLinkcount', $bookmarkService->count(BookmarkFilter::$PRIVATE));
|
||||
$PAGE->assign('plugin_errors', $pluginManager->getErrors());
|
||||
|
||||
// Determine which page will be rendered.
|
||||
$query = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : '';
|
||||
$targetPage = Router::findPage($query, $_GET, $loginManager->isLoggedIn());
|
||||
|
||||
if (// if the user isn't logged in
|
||||
!$loginManager->isLoggedIn() &&
|
||||
// and Shaarli doesn't have public content...
|
||||
$conf->get('privacy.hide_public_links') &&
|
||||
// and is configured to enforce the login
|
||||
$conf->get('privacy.force_login') &&
|
||||
// and the current page isn't already the login page
|
||||
$targetPage !== Router::$PAGE_LOGIN &&
|
||||
// and the user is not requesting a feed (which would lead to a different content-type as expected)
|
||||
$targetPage !== Router::$PAGE_FEED_ATOM &&
|
||||
$targetPage !== Router::$PAGE_FEED_RSS
|
||||
) {
|
||||
// force current page to be the login page
|
||||
$targetPage = Router::$PAGE_LOGIN;
|
||||
}
|
||||
|
||||
// Call plugin hooks for header, footer and includes, specifying which page will be rendered.
|
||||
// Then assign generated data to RainTPL.
|
||||
$common_hooks = array(
|
||||
'includes',
|
||||
'header',
|
||||
'footer',
|
||||
);
|
||||
|
||||
foreach ($common_hooks as $name) {
|
||||
$plugin_data = array();
|
||||
$pluginManager->executeHooks(
|
||||
'render_' . $name,
|
||||
$plugin_data,
|
||||
array(
|
||||
'target' => $targetPage,
|
||||
'loggedin' => $loginManager->isLoggedIn()
|
||||
)
|
||||
);
|
||||
$PAGE->assign('plugins_' . $name, $plugin_data);
|
||||
}
|
||||
|
||||
// -------- Display login form.
|
||||
if ($targetPage == Router::$PAGE_LOGIN) {
|
||||
header('Location: ./login');
|
||||
exit;
|
||||
}
|
||||
// -------- User wants to logout.
|
||||
if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=logout')) {
|
||||
header('Location: ./logout');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- Picture wall
|
||||
if ($targetPage == Router::$PAGE_PICWALL) {
|
||||
header('Location: ./picture-wall');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- Tag cloud
|
||||
if ($targetPage == Router::$PAGE_TAGCLOUD) {
|
||||
header('Location: ./tags/cloud');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- Tag list
|
||||
if ($targetPage == Router::$PAGE_TAGLIST) {
|
||||
header('Location: ./tags/list');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Daily page.
|
||||
if ($targetPage == Router::$PAGE_DAILY) {
|
||||
$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('Location: ./feed/'. $feedType .'?'. http_build_query($_GET));
|
||||
exit;
|
||||
}
|
||||
|
||||
// Display opensearch plugin (XML)
|
||||
if ($targetPage == Router::$PAGE_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'])) {
|
||||
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'])) {
|
||||
header('Location: ./remove-tag/'. $_GET['removetag']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- User wants to change the number of bookmarks per page (linksperpage=...)
|
||||
if (isset($_GET['linksperpage'])) {
|
||||
header('Location: ./links-per-page?nb='. $_GET['linksperpage']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- User wants to see only private bookmarks (toggle)
|
||||
if (isset($_GET['visibility'])) {
|
||||
header('Location: ./visibility/'. $_GET['visibility']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- User wants to see only untagged bookmarks (toggle)
|
||||
if (isset($_GET['untaggedonly'])) {
|
||||
header('Location: ./untagged-only');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- Handle other actions allowed for non-logged in users:
|
||||
if (!$loginManager->isLoggedIn()) {
|
||||
// User tries to post new link but is not logged in:
|
||||
// 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']).
|
||||
(!empty($_GET['title'])?'&title='.urlencode($_GET['title']):'').
|
||||
(!empty($_GET['description'])?'&description='.urlencode($_GET['description']):'').
|
||||
(!empty($_GET['tags'])?'&tags='.urlencode($_GET['tags']):'').
|
||||
(!empty($_GET['source'])?'&source='.urlencode($_GET['source']):'')
|
||||
);
|
||||
exit;
|
||||
}
|
||||
|
||||
showLinkList($PAGE, $bookmarkService, $conf, $pluginManager, $loginManager);
|
||||
if (isset($_GET['edit_link'])) {
|
||||
header('Location: ./login?edit_link='. escape($_GET['edit_link']));
|
||||
exit;
|
||||
}
|
||||
|
||||
exit; // Never remove this one! All operations below are reserved for logged in user.
|
||||
}
|
||||
|
||||
// -------- All other functions are reserved for the registered user:
|
||||
|
||||
// TODO: Remove legacy admin route redirections. We'll only keep public URL.
|
||||
|
||||
// -------- Display the Tools menu if requested (import/export/bookmarklet...)
|
||||
if ($targetPage == Router::$PAGE_TOOLS) {
|
||||
header('Location: ./admin/tools');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- User wants to change his/her password.
|
||||
if ($targetPage == Router::$PAGE_CHANGEPASSWORD) {
|
||||
header('Location: ./admin/password');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- User wants to change configuration
|
||||
if ($targetPage == Router::$PAGE_CONFIGURE) {
|
||||
header('Location: ./admin/configure');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- User wants to rename a tag or delete it
|
||||
if ($targetPage == Router::$PAGE_CHANGETAG) {
|
||||
header('Location: ./admin/tags');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- User wants to add a link without using the bookmarklet: Show form.
|
||||
if ($targetPage == Router::$PAGE_ADDLINK) {
|
||||
header('Location: ./admin/shaare');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- User clicked the "Save" button when editing a link: Save link to database.
|
||||
if (isset($_POST['save_edit'])) {
|
||||
// This route is no longer supported in legacy mode
|
||||
header('Location: ./');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- User clicked the "Delete" button when editing a link: Delete link from database.
|
||||
if ($targetPage == Router::$PAGE_DELETELINK) {
|
||||
$ids = $_GET['lf_linkdate'] ?? '';
|
||||
$token = $_GET['token'] ?? '';
|
||||
|
||||
header('Location: ./admin/shaare/delete?id=' . $ids . '&token=' . $token);
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- User clicked either "Set public" or "Set private" bulk operation
|
||||
if ($targetPage == Router::$PAGE_CHANGE_VISIBILITY) {
|
||||
header('Location: ./admin/shaare/visibility?id=' . $_GET['token']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- User clicked the "EDIT" button on a link: Display link edit form.
|
||||
if (isset($_GET['edit_link'])) {
|
||||
$id = (int) escape($_GET['edit_link']);
|
||||
header('Location: ./admin/shaare/' . $id);
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- User want to post a new link: Display link edit form.
|
||||
if (isset($_GET['post'])) {
|
||||
header('Location: ./admin/shaare?' . http_build_query($_GET));
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($targetPage == Router::$PAGE_PINLINK) {
|
||||
// This route is no longer supported in legacy mode
|
||||
header('Location: ./');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($targetPage == Router::$PAGE_EXPORT) {
|
||||
header('Location: ./admin/export');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($targetPage == Router::$PAGE_IMPORT) {
|
||||
header('Location: ./admin/import');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Plugin administration page
|
||||
if ($targetPage == Router::$PAGE_PLUGINSADMIN) {
|
||||
header('Location: ./admin/plugins');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Plugin administration form action
|
||||
if ($targetPage == Router::$PAGE_SAVE_PLUGINSADMIN) {
|
||||
// This route is no longer supported in legacy mode
|
||||
header('Location: ./admin/plugins');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Get a fresh token
|
||||
if ($targetPage == Router::$GET_TOKEN) {
|
||||
header('Location: ./admin/token');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- Thumbnails Update
|
||||
if ($targetPage == Router::$PAGE_THUMBS_UPDATE) {
|
||||
header('Location: ./admin/thumbnails');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- Single Thumbnail Update
|
||||
if ($targetPage == Router::$AJAX_THUMB_UPDATE) {
|
||||
// This route is no longer supported in legacy mode
|
||||
http_response_code(404);
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------- Otherwise, simply display search form and bookmarks:
|
||||
showLinkList($PAGE, $bookmarkService, $conf, $pluginManager, $loginManager);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template for the list of bookmarks (<div id="linklist">)
|
||||
* This function fills all the necessary fields in the $PAGE for the template 'linklist.html'
|
||||
*
|
||||
* @param pageBuilder $PAGE pageBuilder instance.
|
||||
* @param BookmarkServiceInterface $linkDb LinkDB instance.
|
||||
* @param ConfigManager $conf Configuration Manager instance.
|
||||
* @param PluginManager $pluginManager Plugin Manager instance.
|
||||
* @param LoginManager $loginManager LoginManager instance
|
||||
*/
|
||||
function buildLinkList($PAGE, $linkDb, $conf, $pluginManager, $loginManager)
|
||||
{
|
||||
$factory = new FormatterFactory($conf, $loginManager->isLoggedIn());
|
||||
$formatter = $factory->getFormatter();
|
||||
|
||||
// Used in templates
|
||||
if (isset($_GET['searchtags'])) {
|
||||
if (! empty($_GET['searchtags'])) {
|
||||
$searchtags = escape(normalize_spaces($_GET['searchtags']));
|
||||
} else {
|
||||
$searchtags = false;
|
||||
}
|
||||
} else {
|
||||
$searchtags = '';
|
||||
}
|
||||
$searchterm = !empty($_GET['searchterm']) ? escape(normalize_spaces($_GET['searchterm'])) : '';
|
||||
|
||||
// Smallhash filter
|
||||
if (! empty($_SERVER['QUERY_STRING'])
|
||||
&& preg_match('/^[a-zA-Z0-9-_@]{6}($|&|#)/', $_SERVER['QUERY_STRING'])) {
|
||||
try {
|
||||
$linksToDisplay = $linkDb->findByHash($_SERVER['QUERY_STRING']);
|
||||
} catch (BookmarkNotFoundException $e) {
|
||||
$PAGE->render404($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
// Filter bookmarks according search parameters.
|
||||
$visibility = ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : null;
|
||||
$request = [
|
||||
'searchtags' => $searchtags,
|
||||
'searchterm' => $searchterm,
|
||||
];
|
||||
$linksToDisplay = $linkDb->search($request, $visibility, false, !empty($_SESSION['untaggedonly']));
|
||||
}
|
||||
|
||||
// ---- Handle paging.
|
||||
$keys = array();
|
||||
foreach ($linksToDisplay as $key => $value) {
|
||||
$keys[] = $key;
|
||||
}
|
||||
|
||||
// Select articles according to paging.
|
||||
$pagecount = ceil(count($keys) / $_SESSION['LINKS_PER_PAGE']);
|
||||
$pagecount = $pagecount == 0 ? 1 : $pagecount;
|
||||
$page= empty($_GET['page']) ? 1 : intval($_GET['page']);
|
||||
$page = $page < 1 ? 1 : $page;
|
||||
$page = $page > $pagecount ? $pagecount : $page;
|
||||
// Start index.
|
||||
$i = ($page-1) * $_SESSION['LINKS_PER_PAGE'];
|
||||
$end = $i + $_SESSION['LINKS_PER_PAGE'];
|
||||
|
||||
$thumbnailsEnabled = $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE;
|
||||
if ($thumbnailsEnabled) {
|
||||
$thumbnailer = new Thumbnailer($conf);
|
||||
}
|
||||
|
||||
$linkDisp = array();
|
||||
while ($i<$end && $i<count($keys)) {
|
||||
$link = $formatter->format($linksToDisplay[$keys[$i]]);
|
||||
|
||||
// Logged in, thumbnails enabled, not a note,
|
||||
// and (never retrieved yet or no valid cache file)
|
||||
if ($loginManager->isLoggedIn()
|
||||
&& $thumbnailsEnabled
|
||||
&& !$linksToDisplay[$keys[$i]]->isNote()
|
||||
&& $linksToDisplay[$keys[$i]]->getThumbnail() !== false
|
||||
&& ! is_file($linksToDisplay[$keys[$i]]->getThumbnail())
|
||||
) {
|
||||
$linksToDisplay[$keys[$i]]->setThumbnail($thumbnailer->get($link['url']));
|
||||
$linkDb->set($linksToDisplay[$keys[$i]], false);
|
||||
$updateDB = true;
|
||||
$link['thumbnail'] = $linksToDisplay[$keys[$i]]->getThumbnail();
|
||||
}
|
||||
|
||||
// Check for both signs of a note: starting with ? and 7 chars long.
|
||||
// if ($link['url'][0] === '?' && strlen($link['url']) === 7) {
|
||||
// $link['url'] = index_url($_SERVER) . $link['url'];
|
||||
// }
|
||||
|
||||
$linkDisp[$keys[$i]] = $link;
|
||||
$i++;
|
||||
}
|
||||
|
||||
// If we retrieved new thumbnails, we update the database.
|
||||
if (!empty($updateDB)) {
|
||||
$linkDb->save();
|
||||
}
|
||||
|
||||
// Compute paging navigation
|
||||
$searchtagsUrl = $searchtags === '' ? '' : '&searchtags=' . urlencode($searchtags);
|
||||
$searchtermUrl = empty($searchterm) ? '' : '&searchterm=' . urlencode($searchterm);
|
||||
$previous_page_url = '';
|
||||
if ($i != count($keys)) {
|
||||
$previous_page_url = '?page=' . ($page+1) . $searchtermUrl . $searchtagsUrl;
|
||||
}
|
||||
$next_page_url='';
|
||||
if ($page>1) {
|
||||
$next_page_url = '?page=' . ($page-1) . $searchtermUrl . $searchtagsUrl;
|
||||
}
|
||||
|
||||
// Fill all template fields.
|
||||
$data = array(
|
||||
'previous_page_url' => $previous_page_url,
|
||||
'next_page_url' => $next_page_url,
|
||||
'page_current' => $page,
|
||||
'page_max' => $pagecount,
|
||||
'result_count' => count($linksToDisplay),
|
||||
'search_term' => $searchterm,
|
||||
'search_tags' => $searchtags,
|
||||
'visibility' => ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : '',
|
||||
'links' => $linkDisp,
|
||||
);
|
||||
|
||||
// If there is only a single link, we change on-the-fly the title of the page.
|
||||
if (count($linksToDisplay) == 1) {
|
||||
$data['pagetitle'] = $linksToDisplay[$keys[0]]->getTitle() .' - '. $conf->get('general.title');
|
||||
} elseif (! empty($searchterm) || ! empty($searchtags)) {
|
||||
$data['pagetitle'] = t('Search: ');
|
||||
$data['pagetitle'] .= ! empty($searchterm) ? $searchterm .' ' : '';
|
||||
$bracketWrap = function ($tag) {
|
||||
return '['. $tag .']';
|
||||
};
|
||||
$data['pagetitle'] .= ! empty($searchtags)
|
||||
? implode(' ', array_map($bracketWrap, preg_split('/\s+/', $searchtags))).' '
|
||||
: '';
|
||||
$data['pagetitle'] .= '- '. $conf->get('general.title');
|
||||
}
|
||||
|
||||
$pluginManager->executeHooks('render_linklist', $data, array('loggedin' => $loginManager->isLoggedIn()));
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
$PAGE->assign($key, $value);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation
|
||||
* This function should NEVER be called if the file data/config.php exists.
|
||||
|
@ -882,19 +386,6 @@ if (!isset($_SESSION['LINKS_PER_PAGE'])) {
|
|||
$_SESSION['LINKS_PER_PAGE'] = $conf->get('general.links_per_page', 20);
|
||||
}
|
||||
|
||||
try {
|
||||
$history = new History($conf->get('resource.history'));
|
||||
} catch (Exception $e) {
|
||||
die($e->getMessage());
|
||||
}
|
||||
|
||||
$linkDb = new BookmarkFileService($conf, $history, $loginManager->isLoggedIn());
|
||||
|
||||
if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) {
|
||||
header('Location: ./daily-rss');
|
||||
exit;
|
||||
}
|
||||
|
||||
$containerBuilder = new ContainerBuilder($conf, $sessionManager, $loginManager);
|
||||
$container = $containerBuilder->build();
|
||||
$app = new App($container);
|
||||
|
@ -918,13 +409,15 @@ $app->group('/api/v1', function () {
|
|||
|
||||
$app->group('', function () {
|
||||
/* -- PUBLIC --*/
|
||||
$this->get('/login', '\Shaarli\Front\Controller\Visitor\LoginController:index');
|
||||
$this->get('/', '\Shaarli\Front\Controller\Visitor\BookmarkListController:index');
|
||||
$this->get('/shaare/{hash}', '\Shaarli\Front\Controller\Visitor\BookmarkListController:permalink');
|
||||
$this->get('/login', '\Shaarli\Front\Controller\Visitor\LoginController:index')->setName('login');
|
||||
$this->get('/picture-wall', '\Shaarli\Front\Controller\Visitor\PictureWallController:index');
|
||||
$this->get('/tags/cloud', '\Shaarli\Front\Controller\Visitor\TagCloudController:cloud');
|
||||
$this->get('/tags/list', '\Shaarli\Front\Controller\Visitor\TagCloudController:list');
|
||||
$this->get('/daily', '\Shaarli\Front\Controller\Visitor\DailyController:index');
|
||||
$this->get('/daily-rss', '\Shaarli\Front\Controller\Visitor\DailyController:rss');
|
||||
$this->get('/feed/atom', '\Shaarli\Front\Controller\Visitor\FeedController:atom');
|
||||
$this->get('/daily-rss', '\Shaarli\Front\Controller\Visitor\DailyController:rss')->setName('rss');
|
||||
$this->get('/feed/atom', '\Shaarli\Front\Controller\Visitor\FeedController:atom')->setName('atom');
|
||||
$this->get('/feed/rss', '\Shaarli\Front\Controller\Visitor\FeedController:rss');
|
||||
$this->get('/open-search', '\Shaarli\Front\Controller\Visitor\OpenSearchController:index');
|
||||
|
||||
|
@ -967,19 +460,4 @@ $app->group('', function () {
|
|||
|
||||
$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) {
|
||||
// We use UTF-8 for proper international characters handling.
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
renderPage($conf, $pluginManager, $linkDb, $history, $sessionManager, $loginManager);
|
||||
} else {
|
||||
$response = $response
|
||||
->withHeader('Access-Control-Allow-Origin', '*')
|
||||
->withHeader(
|
||||
'Access-Control-Allow-Headers',
|
||||
'X-Requested-With, Content-Type, Accept, Origin, Authorization'
|
||||
)
|
||||
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
||||
$app->respond($response);
|
||||
}
|
||||
$app->respond($response);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Adds the addlink input on the linklist page.
|
||||
*/
|
||||
|
||||
use Shaarli\Router;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
|
||||
/**
|
||||
* When linklist is displayed, add play videos to header's toolbar.
|
||||
|
@ -16,7 +16,7 @@ use Shaarli\Router;
|
|||
*/
|
||||
function hook_addlink_toolbar_render_header($data)
|
||||
{
|
||||
if ($data['_PAGE_'] == Router::$PAGE_LINKLIST && $data['_LOGGEDIN_'] === true) {
|
||||
if ($data['_PAGE_'] == TemplatePage::LINKLIST && $data['_LOGGEDIN_'] === true) {
|
||||
$form = array(
|
||||
'attr' => array(
|
||||
'method' => 'GET',
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
use Shaarli\Config\ConfigManager;
|
||||
use Shaarli\Plugin\PluginManager;
|
||||
use Shaarli\Router;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
|
||||
/**
|
||||
* In the footer hook, there is a working example of a translation extension for Shaarli.
|
||||
|
@ -74,7 +74,7 @@ function demo_plugin_init($conf)
|
|||
function hook_demo_plugin_render_header($data)
|
||||
{
|
||||
// Only execute when linklist is rendered.
|
||||
if ($data['_PAGE_'] == Router::$PAGE_LINKLIST) {
|
||||
if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
|
||||
// If loggedin
|
||||
if ($data['_LOGGEDIN_'] === true) {
|
||||
/*
|
||||
|
@ -441,9 +441,9 @@ function hook_demo_plugin_delete_link($data)
|
|||
function hook_demo_plugin_render_feed($data)
|
||||
{
|
||||
foreach ($data['links'] as &$link) {
|
||||
if ($data['_PAGE_'] == Router::$PAGE_FEED_ATOM) {
|
||||
if ($data['_PAGE_'] == TemplatePage::FEED_ATOM) {
|
||||
$link['description'] .= ' - ATOM Feed' ;
|
||||
} elseif ($data['_PAGE_'] == Router::$PAGE_FEED_RSS) {
|
||||
} elseif ($data['_PAGE_'] == TemplatePage::FEED_RSS) {
|
||||
$link['description'] .= ' - RSS Feed';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
use Shaarli\Config\ConfigManager;
|
||||
use Shaarli\Plugin\PluginManager;
|
||||
use Shaarli\Router;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
|
||||
/**
|
||||
* Display an error everywhere if the plugin is enabled without configuration.
|
||||
|
@ -76,7 +76,7 @@ function hook_isso_render_linklist($data, $conf)
|
|||
*/
|
||||
function hook_isso_render_includes($data)
|
||||
{
|
||||
if ($data['_PAGE_'] == Router::$PAGE_LINKLIST) {
|
||||
if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
|
||||
$data['css_files'][] = PluginManager::$PLUGINS_PATH . '/isso/isso.css';
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
use Shaarli\Plugin\PluginManager;
|
||||
use Shaarli\Router;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
|
||||
/**
|
||||
* When linklist is displayed, add play videos to header's toolbar.
|
||||
|
@ -18,7 +18,7 @@ use Shaarli\Router;
|
|||
*/
|
||||
function hook_playvideos_render_header($data)
|
||||
{
|
||||
if ($data['_PAGE_'] == Router::$PAGE_LINKLIST) {
|
||||
if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
|
||||
$playvideo = array(
|
||||
'attr' => array(
|
||||
'href' => '#',
|
||||
|
@ -42,7 +42,7 @@ function hook_playvideos_render_header($data)
|
|||
*/
|
||||
function hook_playvideos_render_footer($data)
|
||||
{
|
||||
if ($data['_PAGE_'] == Router::$PAGE_LINKLIST) {
|
||||
if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
|
||||
$data['js_files'][] = PluginManager::$PLUGINS_PATH . '/playvideos/jquery-1.11.2.min.js';
|
||||
$data['js_files'][] = PluginManager::$PLUGINS_PATH . '/playvideos/youtube_playlist.js';
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use pubsubhubbub\publisher\Publisher;
|
|||
use Shaarli\Config\ConfigManager;
|
||||
use Shaarli\Feed\FeedBuilder;
|
||||
use Shaarli\Plugin\PluginManager;
|
||||
use Shaarli\Router;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
|
||||
/**
|
||||
* Plugin init function - set the hub to the default appspot one.
|
||||
|
@ -41,7 +41,7 @@ function pubsubhubbub_init($conf)
|
|||
*/
|
||||
function hook_pubsubhubbub_render_feed($data, $conf)
|
||||
{
|
||||
$feedType = $data['_PAGE_'] == Router::$PAGE_FEED_RSS ? FeedBuilder::$FEED_RSS : FeedBuilder::$FEED_ATOM;
|
||||
$feedType = $data['_PAGE_'] == TemplatePage::FEED_RSS ? FeedBuilder::$FEED_RSS : FeedBuilder::$FEED_ATOM;
|
||||
$template = file_get_contents(PluginManager::$PLUGINS_PATH . '/pubsubhubbub/hub.'. $feedType .'.xml');
|
||||
$data['feed_plugins_header'][] = sprintf($template, $conf->get('plugins.PUBSUBHUB_URL'));
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
use Shaarli\Plugin\PluginManager;
|
||||
use Shaarli\Router;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
|
||||
/**
|
||||
* Add qrcode icon to link_plugin when rendering linklist.
|
||||
|
@ -40,7 +40,7 @@ function hook_qrcode_render_linklist($data)
|
|||
*/
|
||||
function hook_qrcode_render_footer($data)
|
||||
{
|
||||
if ($data['_PAGE_'] == Router::$PAGE_LINKLIST) {
|
||||
if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
|
||||
$data['js_files'][] = PluginManager::$PLUGINS_PATH . '/qrcode/shaarli-qrcode.js';
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ function hook_qrcode_render_footer($data)
|
|||
*/
|
||||
function hook_qrcode_render_includes($data)
|
||||
{
|
||||
if ($data['_PAGE_'] == Router::$PAGE_LINKLIST) {
|
||||
if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
|
||||
$data['css_files'][] = PluginManager::$PLUGINS_PATH . '/qrcode/qrcode.css';
|
||||
}
|
||||
|
||||
|
|
|
@ -892,35 +892,35 @@ class BookmarkFileServiceTest extends TestCase
|
|||
public function testFilterHashValid()
|
||||
{
|
||||
$request = smallHash('20150310_114651');
|
||||
$this->assertEquals(
|
||||
1,
|
||||
count($this->publicLinkDB->findByHash($request))
|
||||
$this->assertSame(
|
||||
$request,
|
||||
$this->publicLinkDB->findByHash($request)->getShortUrl()
|
||||
);
|
||||
$request = smallHash('20150310_114633' . 8);
|
||||
$this->assertEquals(
|
||||
1,
|
||||
count($this->publicLinkDB->findByHash($request))
|
||||
$this->assertSame(
|
||||
$request,
|
||||
$this->publicLinkDB->findByHash($request)->getShortUrl()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test filterHash() with an invalid smallhash.
|
||||
*
|
||||
* @expectedException \Shaarli\Bookmark\Exception\BookmarkNotFoundException
|
||||
*/
|
||||
public function testFilterHashInValid1()
|
||||
{
|
||||
$this->expectException(BookmarkNotFoundException::class);
|
||||
|
||||
$request = 'blabla';
|
||||
$this->publicLinkDB->findByHash($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test filterHash() with an empty smallhash.
|
||||
*
|
||||
* @expectedException \Shaarli\Bookmark\Exception\BookmarkNotFoundException
|
||||
*/
|
||||
public function testFilterHashInValid()
|
||||
{
|
||||
$this->expectException(BookmarkNotFoundException::class);
|
||||
|
||||
$this->publicLinkDB->findByHash('');
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,11 @@ use PHPUnit\Framework\TestCase;
|
|||
use Shaarli\Config\ConfigManager;
|
||||
use Shaarli\Container\ShaarliContainer;
|
||||
use Shaarli\Front\Exception\LoginBannedException;
|
||||
use Shaarli\Front\Exception\UnauthorizedException;
|
||||
use Shaarli\Render\PageBuilder;
|
||||
use Shaarli\Render\PageCacheManager;
|
||||
use Shaarli\Security\LoginManager;
|
||||
use Shaarli\Updater\Updater;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
use Slim\Http\Uri;
|
||||
|
@ -24,9 +28,16 @@ class ShaarliMiddlewareTest extends TestCase
|
|||
public function setUp(): void
|
||||
{
|
||||
$this->container = $this->createMock(ShaarliContainer::class);
|
||||
|
||||
$this->container->conf = $this->createMock(ConfigManager::class);
|
||||
$this->container->loginManager = $this->createMock(LoginManager::class);
|
||||
|
||||
$this->middleware = new ShaarliMiddleware($this->container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test middleware execution with valid controller call
|
||||
*/
|
||||
public function testMiddlewareExecution(): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
|
@ -49,7 +60,10 @@ class ShaarliMiddlewareTest extends TestCase
|
|||
static::assertSame(418, $result->getStatusCode());
|
||||
}
|
||||
|
||||
public function testMiddlewareExecutionWithException(): void
|
||||
/**
|
||||
* Test middleware execution with controller throwing a known front exception
|
||||
*/
|
||||
public function testMiddlewareExecutionWithFrontException(): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getUri')->willReturnCallback(function (): Uri {
|
||||
|
@ -58,7 +72,7 @@ class ShaarliMiddlewareTest extends TestCase
|
|||
|
||||
return $uri;
|
||||
});
|
||||
|
||||
|
||||
$response = new Response();
|
||||
$controller = function (): void {
|
||||
$exception = new LoginBannedException();
|
||||
|
@ -72,9 +86,6 @@ class ShaarliMiddlewareTest extends TestCase
|
|||
});
|
||||
$this->container->pageBuilder = $pageBuilder;
|
||||
|
||||
$conf = $this->createMock(ConfigManager::class);
|
||||
$this->container->conf = $conf;
|
||||
|
||||
/** @var Response $result */
|
||||
$result = $this->middleware->__invoke($request, $response, $controller);
|
||||
|
||||
|
@ -82,4 +93,113 @@ class ShaarliMiddlewareTest extends TestCase
|
|||
static::assertSame(401, $result->getStatusCode());
|
||||
static::assertContains('error', (string) $result->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test middleware execution with controller throwing a not authorized exception
|
||||
*/
|
||||
public function testMiddlewareExecutionWithUnauthorizedException(): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getUri')->willReturnCallback(function (): Uri {
|
||||
$uri = $this->createMock(Uri::class);
|
||||
$uri->method('getBasePath')->willReturn('/subfolder');
|
||||
|
||||
return $uri;
|
||||
});
|
||||
|
||||
$response = new Response();
|
||||
$controller = function (): void {
|
||||
throw new UnauthorizedException();
|
||||
};
|
||||
|
||||
/** @var Response $result */
|
||||
$result = $this->middleware->__invoke($request, $response, $controller);
|
||||
|
||||
static::assertSame(302, $result->getStatusCode());
|
||||
static::assertSame('/subfolder/login', $result->getHeader('location')[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test middleware execution with controller throwing a not authorized exception
|
||||
*/
|
||||
public function testMiddlewareExecutionWithServerExceptionWith(): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getUri')->willReturnCallback(function (): Uri {
|
||||
$uri = $this->createMock(Uri::class);
|
||||
$uri->method('getBasePath')->willReturn('/subfolder');
|
||||
|
||||
return $uri;
|
||||
});
|
||||
|
||||
$response = new Response();
|
||||
$controller = function (): void {
|
||||
throw new \Exception();
|
||||
};
|
||||
|
||||
$parameters = [];
|
||||
$this->container->pageBuilder = $this->createMock(PageBuilder::class);
|
||||
$this->container->pageBuilder->method('render')->willReturnCallback(function (string $message): string {
|
||||
return $message;
|
||||
});
|
||||
$this->container->pageBuilder
|
||||
->method('assign')
|
||||
->willReturnCallback(function (string $key, string $value) use (&$parameters): void {
|
||||
$parameters[$key] = $value;
|
||||
})
|
||||
;
|
||||
|
||||
/** @var Response $result */
|
||||
$result = $this->middleware->__invoke($request, $response, $controller);
|
||||
|
||||
static::assertSame(500, $result->getStatusCode());
|
||||
static::assertContains('error', (string) $result->getBody());
|
||||
static::assertSame('An unexpected error occurred.', $parameters['message']);
|
||||
}
|
||||
|
||||
public function testMiddlewareExecutionWithUpdates(): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getUri')->willReturnCallback(function (): Uri {
|
||||
$uri = $this->createMock(Uri::class);
|
||||
$uri->method('getBasePath')->willReturn('/subfolder');
|
||||
|
||||
return $uri;
|
||||
});
|
||||
|
||||
$response = new Response();
|
||||
$controller = function (Request $request, Response $response): Response {
|
||||
return $response->withStatus(418); // I'm a tea pot
|
||||
};
|
||||
|
||||
$this->container->loginManager = $this->createMock(LoginManager::class);
|
||||
$this->container->loginManager->method('isLoggedIn')->willReturn(true);
|
||||
|
||||
$this->container->conf = $this->createMock(ConfigManager::class);
|
||||
$this->container->conf->method('get')->willReturnCallback(function (string $key): string {
|
||||
return $key;
|
||||
});
|
||||
|
||||
$this->container->pageCacheManager = $this->createMock(PageCacheManager::class);
|
||||
$this->container->pageCacheManager->expects(static::once())->method('invalidateCaches');
|
||||
|
||||
$this->container->updater = $this->createMock(Updater::class);
|
||||
$this->container->updater
|
||||
->expects(static::once())
|
||||
->method('update')
|
||||
->willReturn(['update123'])
|
||||
;
|
||||
$this->container->updater->method('getDoneUpdates')->willReturn($updates = ['update123', 'other']);
|
||||
$this->container->updater
|
||||
->expects(static::once())
|
||||
->method('writeUpdates')
|
||||
->with('resource.updates', $updates)
|
||||
;
|
||||
|
||||
/** @var Response $result */
|
||||
$result = $this->middleware->__invoke($request, $response, $controller);
|
||||
|
||||
static::assertInstanceOf(Response::class, $result);
|
||||
static::assertSame(418, $result->getStatusCode());
|
||||
}
|
||||
}
|
||||
|
|
448
tests/front/controller/visitor/BookmarkListControllerTest.php
Normal file
448
tests/front/controller/visitor/BookmarkListControllerTest.php
Normal file
|
@ -0,0 +1,448 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shaarli\Front\Controller\Visitor;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Shaarli\Bookmark\Bookmark;
|
||||
use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
|
||||
use Shaarli\Config\ConfigManager;
|
||||
use Shaarli\Security\LoginManager;
|
||||
use Shaarli\Thumbnailer;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
class BookmarkListControllerTest extends TestCase
|
||||
{
|
||||
use FrontControllerMockHelper;
|
||||
|
||||
/** @var BookmarkListController */
|
||||
protected $controller;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->createContainer();
|
||||
|
||||
$this->controller = new BookmarkListController($this->container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test rendering list of bookmarks with default parameters (first page).
|
||||
*/
|
||||
public function testIndexDefaultFirstPage(): void
|
||||
{
|
||||
$assignedVariables = [];
|
||||
$this->assignTemplateVars($assignedVariables);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$response = new Response();
|
||||
|
||||
$this->container->bookmarkService
|
||||
->expects(static::once())
|
||||
->method('search')
|
||||
->with(
|
||||
['searchtags' => '', 'searchterm' => ''],
|
||||
null,
|
||||
false,
|
||||
false
|
||||
)
|
||||
->willReturn([
|
||||
(new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'),
|
||||
(new Bookmark())->setId(2)->setUrl('http://url2.tld')->setTitle('Title 2'),
|
||||
(new Bookmark())->setId(3)->setUrl('http://url3.tld')->setTitle('Title 3'),
|
||||
]
|
||||
);
|
||||
|
||||
$this->container->sessionManager
|
||||
->method('getSessionParameter')
|
||||
->willReturnCallback(function (string $parameter, $default = null) {
|
||||
if ('LINKS_PER_PAGE' === $parameter) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return $default;
|
||||
})
|
||||
;
|
||||
|
||||
$result = $this->controller->index($request, $response);
|
||||
|
||||
static::assertSame(200, $result->getStatusCode());
|
||||
static::assertSame('linklist', (string) $result->getBody());
|
||||
|
||||
static::assertSame('Shaarli', $assignedVariables['pagetitle']);
|
||||
static::assertSame('?page=2', $assignedVariables['previous_page_url']);
|
||||
static::assertSame('', $assignedVariables['next_page_url']);
|
||||
static::assertSame(2, $assignedVariables['page_max']);
|
||||
static::assertSame('', $assignedVariables['search_tags']);
|
||||
static::assertSame(3, $assignedVariables['result_count']);
|
||||
static::assertSame(1, $assignedVariables['page_current']);
|
||||
static::assertSame('', $assignedVariables['search_term']);
|
||||
static::assertNull($assignedVariables['visibility']);
|
||||
static::assertCount(2, $assignedVariables['links']);
|
||||
|
||||
$link = $assignedVariables['links'][0];
|
||||
|
||||
static::assertSame(1, $link['id']);
|
||||
static::assertSame('http://url1.tld', $link['url']);
|
||||
static::assertSame('Title 1', $link['title']);
|
||||
|
||||
$link = $assignedVariables['links'][1];
|
||||
|
||||
static::assertSame(2, $link['id']);
|
||||
static::assertSame('http://url2.tld', $link['url']);
|
||||
static::assertSame('Title 2', $link['title']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test rendering list of bookmarks with default parameters (second page).
|
||||
*/
|
||||
public function testIndexDefaultSecondPage(): void
|
||||
{
|
||||
$assignedVariables = [];
|
||||
$this->assignTemplateVars($assignedVariables);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getParam')->willReturnCallback(function (string $key) {
|
||||
if ('page' === $key) {
|
||||
return '2';
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
$response = new Response();
|
||||
|
||||
$this->container->bookmarkService
|
||||
->expects(static::once())
|
||||
->method('search')
|
||||
->with(
|
||||
['searchtags' => '', 'searchterm' => ''],
|
||||
null,
|
||||
false,
|
||||
false
|
||||
)
|
||||
->willReturn([
|
||||
(new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'),
|
||||
(new Bookmark())->setId(2)->setUrl('http://url2.tld')->setTitle('Title 2'),
|
||||
(new Bookmark())->setId(3)->setUrl('http://url3.tld')->setTitle('Title 3'),
|
||||
])
|
||||
;
|
||||
|
||||
$this->container->sessionManager
|
||||
->method('getSessionParameter')
|
||||
->willReturnCallback(function (string $parameter, $default = null) {
|
||||
if ('LINKS_PER_PAGE' === $parameter) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return $default;
|
||||
})
|
||||
;
|
||||
|
||||
$result = $this->controller->index($request, $response);
|
||||
|
||||
static::assertSame(200, $result->getStatusCode());
|
||||
static::assertSame('linklist', (string) $result->getBody());
|
||||
|
||||
static::assertSame('Shaarli', $assignedVariables['pagetitle']);
|
||||
static::assertSame('', $assignedVariables['previous_page_url']);
|
||||
static::assertSame('?page=1', $assignedVariables['next_page_url']);
|
||||
static::assertSame(2, $assignedVariables['page_max']);
|
||||
static::assertSame('', $assignedVariables['search_tags']);
|
||||
static::assertSame(3, $assignedVariables['result_count']);
|
||||
static::assertSame(2, $assignedVariables['page_current']);
|
||||
static::assertSame('', $assignedVariables['search_term']);
|
||||
static::assertNull($assignedVariables['visibility']);
|
||||
static::assertCount(1, $assignedVariables['links']);
|
||||
|
||||
$link = $assignedVariables['links'][2];
|
||||
|
||||
static::assertSame(3, $link['id']);
|
||||
static::assertSame('http://url3.tld', $link['url']);
|
||||
static::assertSame('Title 3', $link['title']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test rendering list of bookmarks with filters.
|
||||
*/
|
||||
public function testIndexDefaultWithFilters(): void
|
||||
{
|
||||
$assignedVariables = [];
|
||||
$this->assignTemplateVars($assignedVariables);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getParam')->willReturnCallback(function (string $key) {
|
||||
if ('searchtags' === $key) {
|
||||
return 'abc def';
|
||||
}
|
||||
if ('searchterm' === $key) {
|
||||
return 'ghi jkl';
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
$response = new Response();
|
||||
|
||||
$this->container->sessionManager
|
||||
->method('getSessionParameter')
|
||||
->willReturnCallback(function (string $key, $default) {
|
||||
if ('LINKS_PER_PAGE' === $key) {
|
||||
return 2;
|
||||
}
|
||||
if ('visibility' === $key) {
|
||||
return 'private';
|
||||
}
|
||||
if ('untaggedonly' === $key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $default;
|
||||
})
|
||||
;
|
||||
|
||||
$this->container->bookmarkService
|
||||
->expects(static::once())
|
||||
->method('search')
|
||||
->with(
|
||||
['searchtags' => 'abc def', 'searchterm' => 'ghi jkl'],
|
||||
'private',
|
||||
false,
|
||||
true
|
||||
)
|
||||
->willReturn([
|
||||
(new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'),
|
||||
(new Bookmark())->setId(2)->setUrl('http://url2.tld')->setTitle('Title 2'),
|
||||
(new Bookmark())->setId(3)->setUrl('http://url3.tld')->setTitle('Title 3'),
|
||||
])
|
||||
;
|
||||
|
||||
$result = $this->controller->index($request, $response);
|
||||
|
||||
static::assertSame(200, $result->getStatusCode());
|
||||
static::assertSame('linklist', (string) $result->getBody());
|
||||
|
||||
static::assertSame('Search: ghi jkl [abc] [def] - Shaarli', $assignedVariables['pagetitle']);
|
||||
static::assertSame('?page=2&searchterm=ghi+jkl&searchtags=abc+def', $assignedVariables['previous_page_url']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test displaying a permalink with valid parameters
|
||||
*/
|
||||
public function testPermalinkValid(): void
|
||||
{
|
||||
$hash = 'abcdef';
|
||||
|
||||
$assignedVariables = [];
|
||||
$this->assignTemplateVars($assignedVariables);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$response = new Response();
|
||||
|
||||
$this->container->bookmarkService
|
||||
->expects(static::once())
|
||||
->method('findByHash')
|
||||
->with($hash)
|
||||
->willReturn((new Bookmark())->setId(123)->setTitle('Title 1')->setUrl('http://url1.tld'))
|
||||
;
|
||||
|
||||
$result = $this->controller->permalink($request, $response, ['hash' => $hash]);
|
||||
|
||||
static::assertSame(200, $result->getStatusCode());
|
||||
static::assertSame('linklist', (string) $result->getBody());
|
||||
|
||||
static::assertSame('Title 1 - Shaarli', $assignedVariables['pagetitle']);
|
||||
static::assertCount(1, $assignedVariables['links']);
|
||||
|
||||
$link = $assignedVariables['links'][0];
|
||||
|
||||
static::assertSame(123, $link['id']);
|
||||
static::assertSame('http://url1.tld', $link['url']);
|
||||
static::assertSame('Title 1', $link['title']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test displaying a permalink with an unknown small hash : renders a 404 template error
|
||||
*/
|
||||
public function testPermalinkNotFound(): void
|
||||
{
|
||||
$hash = 'abcdef';
|
||||
|
||||
$assignedVariables = [];
|
||||
$this->assignTemplateVars($assignedVariables);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$response = new Response();
|
||||
|
||||
$this->container->bookmarkService
|
||||
->expects(static::once())
|
||||
->method('findByHash')
|
||||
->with($hash)
|
||||
->willThrowException(new BookmarkNotFoundException())
|
||||
;
|
||||
|
||||
$result = $this->controller->permalink($request, $response, ['hash' => $hash]);
|
||||
|
||||
static::assertSame(200, $result->getStatusCode());
|
||||
static::assertSame('404', (string) $result->getBody());
|
||||
|
||||
static::assertSame(
|
||||
'The link you are trying to reach does not exist or has been deleted.',
|
||||
$assignedVariables['error_message']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting link list with thumbnail updates.
|
||||
* -> 2 thumbnails update, only 1 datastore write
|
||||
*/
|
||||
public function testThumbnailUpdateFromLinkList(): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
$response = new Response();
|
||||
|
||||
$this->container->loginManager = $this->createMock(LoginManager::class);
|
||||
$this->container->loginManager->method('isLoggedIn')->willReturn(true);
|
||||
|
||||
$this->container->conf = $this->createMock(ConfigManager::class);
|
||||
$this->container->conf
|
||||
->method('get')
|
||||
->willReturnCallback(function (string $key, $default) {
|
||||
return $key === 'thumbnails.mode' ? Thumbnailer::MODE_ALL : $default;
|
||||
})
|
||||
;
|
||||
|
||||
$this->container->thumbnailer = $this->createMock(Thumbnailer::class);
|
||||
$this->container->thumbnailer
|
||||
->expects(static::exactly(2))
|
||||
->method('get')
|
||||
->withConsecutive(['https://url2.tld'], ['https://url4.tld'])
|
||||
;
|
||||
|
||||
$this->container->bookmarkService
|
||||
->expects(static::once())
|
||||
->method('search')
|
||||
->willReturn([
|
||||
(new Bookmark())->setId(1)->setUrl('https://url1.tld')->setTitle('Title 1')->setThumbnail(false),
|
||||
$b1 = (new Bookmark())->setId(2)->setUrl('https://url2.tld')->setTitle('Title 2'),
|
||||
(new Bookmark())->setId(3)->setUrl('https://url3.tld')->setTitle('Title 3')->setThumbnail(false),
|
||||
$b2 = (new Bookmark())->setId(2)->setUrl('https://url4.tld')->setTitle('Title 4'),
|
||||
(new Bookmark())->setId(2)->setUrl('ftp://url5.tld', ['ftp'])->setTitle('Title 5'),
|
||||
])
|
||||
;
|
||||
$this->container->bookmarkService
|
||||
->expects(static::exactly(2))
|
||||
->method('set')
|
||||
->withConsecutive([$b1, false], [$b2, false])
|
||||
;
|
||||
$this->container->bookmarkService->expects(static::once())->method('save');
|
||||
|
||||
$result = $this->controller->index($request, $response);
|
||||
|
||||
static::assertSame(200, $result->getStatusCode());
|
||||
static::assertSame('linklist', (string) $result->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting a permalink with thumbnail update.
|
||||
*/
|
||||
public function testThumbnailUpdateFromPermalink(): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
$response = new Response();
|
||||
|
||||
$this->container->loginManager = $this->createMock(LoginManager::class);
|
||||
$this->container->loginManager->method('isLoggedIn')->willReturn(true);
|
||||
|
||||
$this->container->conf = $this->createMock(ConfigManager::class);
|
||||
$this->container->conf
|
||||
->method('get')
|
||||
->willReturnCallback(function (string $key, $default) {
|
||||
return $key === 'thumbnails.mode' ? Thumbnailer::MODE_ALL : $default;
|
||||
})
|
||||
;
|
||||
|
||||
$this->container->thumbnailer = $this->createMock(Thumbnailer::class);
|
||||
$this->container->thumbnailer->expects(static::once())->method('get')->withConsecutive(['https://url.tld']);
|
||||
|
||||
$this->container->bookmarkService
|
||||
->expects(static::once())
|
||||
->method('findByHash')
|
||||
->willReturn($bookmark = (new Bookmark())->setId(2)->setUrl('https://url.tld')->setTitle('Title 1'))
|
||||
;
|
||||
$this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, true);
|
||||
$this->container->bookmarkService->expects(static::never())->method('save');
|
||||
|
||||
$result = $this->controller->permalink($request, $response, ['hash' => 'abc']);
|
||||
|
||||
static::assertSame(200, $result->getStatusCode());
|
||||
static::assertSame('linklist', (string) $result->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger legacy controller in link list controller: permalink
|
||||
*/
|
||||
public function testLegacyControllerPermalink(): void
|
||||
{
|
||||
$hash = 'abcdef';
|
||||
$this->container->environment['QUERY_STRING'] = $hash;
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$response = new Response();
|
||||
|
||||
$result = $this->controller->index($request, $response);
|
||||
|
||||
static::assertSame(302, $result->getStatusCode());
|
||||
static::assertSame('/subfolder/shaare/' . $hash, $result->getHeader('location')[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger legacy controller in link list controller: ?do= query parameter
|
||||
*/
|
||||
public function testLegacyControllerDoPage(): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParam')->with('do')->willReturn('picwall');
|
||||
$response = new Response();
|
||||
|
||||
$result = $this->controller->index($request, $response);
|
||||
|
||||
static::assertSame(302, $result->getStatusCode());
|
||||
static::assertSame('/subfolder/picture-wall', $result->getHeader('location')[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger legacy controller in link list controller: ?do= query parameter with unknown legacy route
|
||||
*/
|
||||
public function testLegacyControllerUnknownDoPage(): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParam')->with('do')->willReturn('nope');
|
||||
$response = new Response();
|
||||
|
||||
$result = $this->controller->index($request, $response);
|
||||
|
||||
static::assertSame(200, $result->getStatusCode());
|
||||
static::assertSame('linklist', (string) $result->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger legacy controller in link list controller: other GET route (e.g. ?post)
|
||||
*/
|
||||
public function testLegacyControllerGetParameter(): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['post' => $url = 'http://url.tld']);
|
||||
$response = new Response();
|
||||
|
||||
$this->container->loginManager = $this->createMock(LoginManager::class);
|
||||
$this->container->loginManager->method('isLoggedIn')->willReturn(true);
|
||||
|
||||
$result = $this->controller->index($request, $response);
|
||||
|
||||
static::assertSame(302, $result->getStatusCode());
|
||||
static::assertSame(
|
||||
'/subfolder/admin/shaare?post=' . urlencode($url),
|
||||
$result->getHeader('location')[0]
|
||||
);
|
||||
}
|
||||
}
|
99
tests/legacy/LegacyControllerTest.php
Normal file
99
tests/legacy/LegacyControllerTest.php
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shaarli\Legacy;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Shaarli\Front\Controller\Visitor\FrontControllerMockHelper;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
class LegacyControllerTest extends TestCase
|
||||
{
|
||||
use FrontControllerMockHelper;
|
||||
|
||||
/** @var LegacyController */
|
||||
protected $controller;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->createContainer();
|
||||
|
||||
$this->controller = new LegacyController($this->container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProcessProvider
|
||||
*/
|
||||
public function testProcess(string $legacyRoute, array $queryParameters, string $slimRoute, bool $isLoggedIn): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn($queryParameters);
|
||||
$request
|
||||
->method('getParam')
|
||||
->willReturnCallback(function (string $key) use ($queryParameters): ?string {
|
||||
return $queryParameters[$key] ?? null;
|
||||
})
|
||||
;
|
||||
$response = new Response();
|
||||
|
||||
$this->container->loginManager->method('isLoggedIn')->willReturn($isLoggedIn);
|
||||
|
||||
$result = $this->controller->process($request, $response, $legacyRoute);
|
||||
|
||||
static::assertSame('/subfolder' . $slimRoute, $result->getHeader('location')[0]);
|
||||
}
|
||||
|
||||
public function testProcessNotFound(): void
|
||||
{
|
||||
$request = $this->createMock(Request::class);
|
||||
$response = new Response();
|
||||
|
||||
$this->expectException(UnknowLegacyRouteException::class);
|
||||
|
||||
$this->controller->process($request, $response, 'nope');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[] Parameters:
|
||||
* - string legacyRoute
|
||||
* - array queryParameters
|
||||
* - string slimRoute
|
||||
* - bool isLoggedIn
|
||||
*/
|
||||
public function getProcessProvider(): array
|
||||
{
|
||||
return [
|
||||
['post', [], '/admin/shaare', true],
|
||||
['post', [], '/login', false],
|
||||
['post', ['title' => 'test'], '/admin/shaare?title=test', true],
|
||||
['post', ['title' => 'test'], '/login?title=test', false],
|
||||
['addlink', [], '/admin/add-shaare', true],
|
||||
['addlink', [], '/login', false],
|
||||
['login', [], '/login', true],
|
||||
['login', [], '/login', false],
|
||||
['logout', [], '/logout', true],
|
||||
['logout', [], '/logout', false],
|
||||
['picwall', [], '/picture-wall', false],
|
||||
['picwall', [], '/picture-wall', true],
|
||||
['tagcloud', [], '/tags/cloud', false],
|
||||
['tagcloud', [], '/tags/cloud', true],
|
||||
['taglist', [], '/tags/list', false],
|
||||
['taglist', [], '/tags/list', true],
|
||||
['daily', [], '/daily', false],
|
||||
['daily', [], '/daily', true],
|
||||
['daily', ['day' => '123456789', 'discard' => '1'], '/daily?day=123456789', false],
|
||||
['rss', [], '/feed/rss', false],
|
||||
['rss', [], '/feed/rss', true],
|
||||
['rss', ['search' => 'filter123', 'other' => 'param'], '/feed/rss?search=filter123&other=param', false],
|
||||
['atom', [], '/feed/atom', false],
|
||||
['atom', [], '/feed/atom', true],
|
||||
['atom', ['search' => 'filter123', 'other' => 'param'], '/feed/atom?search=filter123&other=param', false],
|
||||
['opensearch', [], '/open-search', false],
|
||||
['opensearch', [], '/open-search', true],
|
||||
['dailyrss', [], '/daily-rss', false],
|
||||
['dailyrss', [], '/daily-rss', true],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
<?php
|
||||
namespace Shaarli;
|
||||
|
||||
namespace Shaarli\Legacy;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Unit tests for Router
|
||||
*/
|
||||
class RouterTest extends \PHPUnit\Framework\TestCase
|
||||
class LegacyRouterTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Test findPage: login page output.
|
||||
|
@ -15,18 +18,18 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageLoginValid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_LOGIN,
|
||||
Router::findPage('do=login', array(), false)
|
||||
LegacyRouter::$PAGE_LOGIN,
|
||||
LegacyRouter::findPage('do=login', array(), false)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_LOGIN,
|
||||
Router::findPage('do=login', array(), 1)
|
||||
LegacyRouter::$PAGE_LOGIN,
|
||||
LegacyRouter::findPage('do=login', array(), 1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_LOGIN,
|
||||
Router::findPage('do=login&stuff', array(), false)
|
||||
LegacyRouter::$PAGE_LOGIN,
|
||||
LegacyRouter::findPage('do=login&stuff', array(), false)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -39,13 +42,13 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageLoginInvalid()
|
||||
{
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_LOGIN,
|
||||
Router::findPage('do=login', array(), true)
|
||||
LegacyRouter::$PAGE_LOGIN,
|
||||
LegacyRouter::findPage('do=login', array(), true)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_LOGIN,
|
||||
Router::findPage('do=other', array(), false)
|
||||
LegacyRouter::$PAGE_LOGIN,
|
||||
LegacyRouter::findPage('do=other', array(), false)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -58,13 +61,13 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPagePicwallValid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_PICWALL,
|
||||
Router::findPage('do=picwall', array(), false)
|
||||
LegacyRouter::$PAGE_PICWALL,
|
||||
LegacyRouter::findPage('do=picwall', array(), false)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_PICWALL,
|
||||
Router::findPage('do=picwall', array(), true)
|
||||
LegacyRouter::$PAGE_PICWALL,
|
||||
LegacyRouter::findPage('do=picwall', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -77,13 +80,13 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPagePicwallInvalid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_PICWALL,
|
||||
Router::findPage('do=picwall&stuff', array(), false)
|
||||
LegacyRouter::$PAGE_PICWALL,
|
||||
LegacyRouter::findPage('do=picwall&stuff', array(), false)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_PICWALL,
|
||||
Router::findPage('do=other', array(), false)
|
||||
LegacyRouter::$PAGE_PICWALL,
|
||||
LegacyRouter::findPage('do=other', array(), false)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -96,18 +99,18 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageTagcloudValid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_TAGCLOUD,
|
||||
Router::findPage('do=tagcloud', array(), false)
|
||||
LegacyRouter::$PAGE_TAGCLOUD,
|
||||
LegacyRouter::findPage('do=tagcloud', array(), false)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_TAGCLOUD,
|
||||
Router::findPage('do=tagcloud', array(), true)
|
||||
LegacyRouter::$PAGE_TAGCLOUD,
|
||||
LegacyRouter::findPage('do=tagcloud', array(), true)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_TAGCLOUD,
|
||||
Router::findPage('do=tagcloud&stuff', array(), false)
|
||||
LegacyRouter::$PAGE_TAGCLOUD,
|
||||
LegacyRouter::findPage('do=tagcloud&stuff', array(), false)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -120,8 +123,8 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageTagcloudInvalid()
|
||||
{
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_TAGCLOUD,
|
||||
Router::findPage('do=other', array(), false)
|
||||
LegacyRouter::$PAGE_TAGCLOUD,
|
||||
LegacyRouter::findPage('do=other', array(), false)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -134,23 +137,23 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageLinklistValid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_LINKLIST,
|
||||
Router::findPage('', array(), true)
|
||||
LegacyRouter::$PAGE_LINKLIST,
|
||||
LegacyRouter::findPage('', array(), true)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_LINKLIST,
|
||||
Router::findPage('whatever', array(), true)
|
||||
LegacyRouter::$PAGE_LINKLIST,
|
||||
LegacyRouter::findPage('whatever', array(), true)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_LINKLIST,
|
||||
Router::findPage('whatever', array(), false)
|
||||
LegacyRouter::$PAGE_LINKLIST,
|
||||
LegacyRouter::findPage('whatever', array(), false)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_LINKLIST,
|
||||
Router::findPage('do=tools', array(), false)
|
||||
LegacyRouter::$PAGE_LINKLIST,
|
||||
LegacyRouter::findPage('do=tools', array(), false)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -163,13 +166,13 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageToolsValid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_TOOLS,
|
||||
Router::findPage('do=tools', array(), true)
|
||||
LegacyRouter::$PAGE_TOOLS,
|
||||
LegacyRouter::findPage('do=tools', array(), true)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_TOOLS,
|
||||
Router::findPage('do=tools&stuff', array(), true)
|
||||
LegacyRouter::$PAGE_TOOLS,
|
||||
LegacyRouter::findPage('do=tools&stuff', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -182,18 +185,18 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageToolsInvalid()
|
||||
{
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_TOOLS,
|
||||
Router::findPage('do=tools', array(), 1)
|
||||
LegacyRouter::$PAGE_TOOLS,
|
||||
LegacyRouter::findPage('do=tools', array(), 1)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_TOOLS,
|
||||
Router::findPage('do=tools', array(), false)
|
||||
LegacyRouter::$PAGE_TOOLS,
|
||||
LegacyRouter::findPage('do=tools', array(), false)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_TOOLS,
|
||||
Router::findPage('do=other', array(), true)
|
||||
LegacyRouter::$PAGE_TOOLS,
|
||||
LegacyRouter::findPage('do=other', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -206,12 +209,12 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageChangepasswdValid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_CHANGEPASSWORD,
|
||||
Router::findPage('do=changepasswd', array(), true)
|
||||
LegacyRouter::$PAGE_CHANGEPASSWORD,
|
||||
LegacyRouter::findPage('do=changepasswd', array(), true)
|
||||
);
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_CHANGEPASSWORD,
|
||||
Router::findPage('do=changepasswd&stuff', array(), true)
|
||||
LegacyRouter::$PAGE_CHANGEPASSWORD,
|
||||
LegacyRouter::findPage('do=changepasswd&stuff', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -224,18 +227,18 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageChangepasswdInvalid()
|
||||
{
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_CHANGEPASSWORD,
|
||||
Router::findPage('do=changepasswd', array(), 1)
|
||||
LegacyRouter::$PAGE_CHANGEPASSWORD,
|
||||
LegacyRouter::findPage('do=changepasswd', array(), 1)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_CHANGEPASSWORD,
|
||||
Router::findPage('do=changepasswd', array(), false)
|
||||
LegacyRouter::$PAGE_CHANGEPASSWORD,
|
||||
LegacyRouter::findPage('do=changepasswd', array(), false)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_CHANGEPASSWORD,
|
||||
Router::findPage('do=other', array(), true)
|
||||
LegacyRouter::$PAGE_CHANGEPASSWORD,
|
||||
LegacyRouter::findPage('do=other', array(), true)
|
||||
);
|
||||
}
|
||||
/**
|
||||
|
@ -247,13 +250,13 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageConfigureValid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_CONFIGURE,
|
||||
Router::findPage('do=configure', array(), true)
|
||||
LegacyRouter::$PAGE_CONFIGURE,
|
||||
LegacyRouter::findPage('do=configure', array(), true)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_CONFIGURE,
|
||||
Router::findPage('do=configure&stuff', array(), true)
|
||||
LegacyRouter::$PAGE_CONFIGURE,
|
||||
LegacyRouter::findPage('do=configure&stuff', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -266,18 +269,18 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageConfigureInvalid()
|
||||
{
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_CONFIGURE,
|
||||
Router::findPage('do=configure', array(), 1)
|
||||
LegacyRouter::$PAGE_CONFIGURE,
|
||||
LegacyRouter::findPage('do=configure', array(), 1)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_CONFIGURE,
|
||||
Router::findPage('do=configure', array(), false)
|
||||
LegacyRouter::$PAGE_CONFIGURE,
|
||||
LegacyRouter::findPage('do=configure', array(), false)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_CONFIGURE,
|
||||
Router::findPage('do=other', array(), true)
|
||||
LegacyRouter::$PAGE_CONFIGURE,
|
||||
LegacyRouter::findPage('do=other', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -290,13 +293,13 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageChangetagValid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_CHANGETAG,
|
||||
Router::findPage('do=changetag', array(), true)
|
||||
LegacyRouter::$PAGE_CHANGETAG,
|
||||
LegacyRouter::findPage('do=changetag', array(), true)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_CHANGETAG,
|
||||
Router::findPage('do=changetag&stuff', array(), true)
|
||||
LegacyRouter::$PAGE_CHANGETAG,
|
||||
LegacyRouter::findPage('do=changetag&stuff', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -309,18 +312,18 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageChangetagInvalid()
|
||||
{
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_CHANGETAG,
|
||||
Router::findPage('do=changetag', array(), 1)
|
||||
LegacyRouter::$PAGE_CHANGETAG,
|
||||
LegacyRouter::findPage('do=changetag', array(), 1)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_CHANGETAG,
|
||||
Router::findPage('do=changetag', array(), false)
|
||||
LegacyRouter::$PAGE_CHANGETAG,
|
||||
LegacyRouter::findPage('do=changetag', array(), false)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_CHANGETAG,
|
||||
Router::findPage('do=other', array(), true)
|
||||
LegacyRouter::$PAGE_CHANGETAG,
|
||||
LegacyRouter::findPage('do=other', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -333,13 +336,13 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageAddlinkValid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_ADDLINK,
|
||||
Router::findPage('do=addlink', array(), true)
|
||||
LegacyRouter::$PAGE_ADDLINK,
|
||||
LegacyRouter::findPage('do=addlink', array(), true)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_ADDLINK,
|
||||
Router::findPage('do=addlink&stuff', array(), true)
|
||||
LegacyRouter::$PAGE_ADDLINK,
|
||||
LegacyRouter::findPage('do=addlink&stuff', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -352,18 +355,18 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageAddlinkInvalid()
|
||||
{
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_ADDLINK,
|
||||
Router::findPage('do=addlink', array(), 1)
|
||||
LegacyRouter::$PAGE_ADDLINK,
|
||||
LegacyRouter::findPage('do=addlink', array(), 1)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_ADDLINK,
|
||||
Router::findPage('do=addlink', array(), false)
|
||||
LegacyRouter::$PAGE_ADDLINK,
|
||||
LegacyRouter::findPage('do=addlink', array(), false)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_ADDLINK,
|
||||
Router::findPage('do=other', array(), true)
|
||||
LegacyRouter::$PAGE_ADDLINK,
|
||||
LegacyRouter::findPage('do=other', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -376,13 +379,13 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageExportValid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_EXPORT,
|
||||
Router::findPage('do=export', array(), true)
|
||||
LegacyRouter::$PAGE_EXPORT,
|
||||
LegacyRouter::findPage('do=export', array(), true)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_EXPORT,
|
||||
Router::findPage('do=export&stuff', array(), true)
|
||||
LegacyRouter::$PAGE_EXPORT,
|
||||
LegacyRouter::findPage('do=export&stuff', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -395,18 +398,18 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageExportInvalid()
|
||||
{
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_EXPORT,
|
||||
Router::findPage('do=export', array(), 1)
|
||||
LegacyRouter::$PAGE_EXPORT,
|
||||
LegacyRouter::findPage('do=export', array(), 1)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_EXPORT,
|
||||
Router::findPage('do=export', array(), false)
|
||||
LegacyRouter::$PAGE_EXPORT,
|
||||
LegacyRouter::findPage('do=export', array(), false)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_EXPORT,
|
||||
Router::findPage('do=other', array(), true)
|
||||
LegacyRouter::$PAGE_EXPORT,
|
||||
LegacyRouter::findPage('do=other', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -419,13 +422,13 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageImportValid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_IMPORT,
|
||||
Router::findPage('do=import', array(), true)
|
||||
LegacyRouter::$PAGE_IMPORT,
|
||||
LegacyRouter::findPage('do=import', array(), true)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_IMPORT,
|
||||
Router::findPage('do=import&stuff', array(), true)
|
||||
LegacyRouter::$PAGE_IMPORT,
|
||||
LegacyRouter::findPage('do=import&stuff', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -438,18 +441,18 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageImportInvalid()
|
||||
{
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_IMPORT,
|
||||
Router::findPage('do=import', array(), 1)
|
||||
LegacyRouter::$PAGE_IMPORT,
|
||||
LegacyRouter::findPage('do=import', array(), 1)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_IMPORT,
|
||||
Router::findPage('do=import', array(), false)
|
||||
LegacyRouter::$PAGE_IMPORT,
|
||||
LegacyRouter::findPage('do=import', array(), false)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_IMPORT,
|
||||
Router::findPage('do=other', array(), true)
|
||||
LegacyRouter::$PAGE_IMPORT,
|
||||
LegacyRouter::findPage('do=other', array(), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -462,24 +465,24 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageEditlinkValid()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_EDITLINK,
|
||||
Router::findPage('whatever', array('edit_link' => 1), true)
|
||||
LegacyRouter::$PAGE_EDITLINK,
|
||||
LegacyRouter::findPage('whatever', array('edit_link' => 1), true)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_EDITLINK,
|
||||
Router::findPage('', array('edit_link' => 1), true)
|
||||
LegacyRouter::$PAGE_EDITLINK,
|
||||
LegacyRouter::findPage('', array('edit_link' => 1), true)
|
||||
);
|
||||
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_EDITLINK,
|
||||
Router::findPage('whatever', array('post' => 1), true)
|
||||
LegacyRouter::$PAGE_EDITLINK,
|
||||
LegacyRouter::findPage('whatever', array('post' => 1), true)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Router::$PAGE_EDITLINK,
|
||||
Router::findPage('whatever', array('post' => 1, 'edit_link' => 1), true)
|
||||
LegacyRouter::$PAGE_EDITLINK,
|
||||
LegacyRouter::findPage('whatever', array('post' => 1, 'edit_link' => 1), true)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -492,18 +495,18 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
public function testFindPageEditlinkInvalid()
|
||||
{
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_EDITLINK,
|
||||
Router::findPage('whatever', array('edit_link' => 1), false)
|
||||
LegacyRouter::$PAGE_EDITLINK,
|
||||
LegacyRouter::findPage('whatever', array('edit_link' => 1), false)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_EDITLINK,
|
||||
Router::findPage('whatever', array('edit_link' => 1), 1)
|
||||
LegacyRouter::$PAGE_EDITLINK,
|
||||
LegacyRouter::findPage('whatever', array('edit_link' => 1), 1)
|
||||
);
|
||||
|
||||
$this->assertNotEquals(
|
||||
Router::$PAGE_EDITLINK,
|
||||
Router::findPage('whatever', array(), true)
|
||||
LegacyRouter::$PAGE_EDITLINK,
|
||||
LegacyRouter::findPage('whatever', array(), true)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
namespace Shaarli\Plugin\Addlink;
|
||||
|
||||
use Shaarli\Plugin\PluginManager;
|
||||
use Shaarli\Router;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
|
||||
require_once 'plugins/addlink_toolbar/addlink_toolbar.php';
|
||||
|
||||
|
@ -26,7 +26,7 @@ class PluginAddlinkTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
$str = 'stuff';
|
||||
$data = array($str => $str);
|
||||
$data['_PAGE_'] = Router::$PAGE_LINKLIST;
|
||||
$data['_PAGE_'] = TemplatePage::LINKLIST;
|
||||
$data['_LOGGEDIN_'] = true;
|
||||
|
||||
$data = hook_addlink_toolbar_render_header($data);
|
||||
|
@ -48,7 +48,7 @@ class PluginAddlinkTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
$str = 'stuff';
|
||||
$data = array($str => $str);
|
||||
$data['_PAGE_'] = Router::$PAGE_LINKLIST;
|
||||
$data['_PAGE_'] = TemplatePage::LINKLIST;
|
||||
$data['_LOGGEDIN_'] = false;
|
||||
|
||||
$data = hook_addlink_toolbar_render_header($data);
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace Shaarli\Plugin\Playvideos;
|
|||
*/
|
||||
|
||||
use Shaarli\Plugin\PluginManager;
|
||||
use Shaarli\Router;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
|
||||
require_once 'plugins/playvideos/playvideos.php';
|
||||
|
||||
|
@ -31,7 +31,7 @@ class PluginPlayvideosTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
$str = 'stuff';
|
||||
$data = array($str => $str);
|
||||
$data['_PAGE_'] = Router::$PAGE_LINKLIST;
|
||||
$data['_PAGE_'] = TemplatePage::LINKLIST;
|
||||
|
||||
$data = hook_playvideos_render_header($data);
|
||||
$this->assertEquals($str, $data[$str]);
|
||||
|
@ -50,7 +50,7 @@ class PluginPlayvideosTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
$str = 'stuff';
|
||||
$data = array($str => $str);
|
||||
$data['_PAGE_'] = Router::$PAGE_LINKLIST;
|
||||
$data['_PAGE_'] = TemplatePage::LINKLIST;
|
||||
|
||||
$data = hook_playvideos_render_footer($data);
|
||||
$this->assertEquals($str, $data[$str]);
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace Shaarli\Plugin\Pubsubhubbub;
|
|||
|
||||
use Shaarli\Config\ConfigManager;
|
||||
use Shaarli\Plugin\PluginManager;
|
||||
use Shaarli\Router;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
|
||||
require_once 'plugins/pubsubhubbub/pubsubhubbub.php';
|
||||
|
||||
|
@ -34,7 +34,7 @@ class PluginPubsubhubbubTest extends \PHPUnit\Framework\TestCase
|
|||
$hub = 'http://domain.hub';
|
||||
$conf = new ConfigManager(self::$configFile);
|
||||
$conf->set('plugins.PUBSUBHUB_URL', $hub);
|
||||
$data['_PAGE_'] = Router::$PAGE_FEED_RSS;
|
||||
$data['_PAGE_'] = TemplatePage::FEED_RSS;
|
||||
|
||||
$data = hook_pubsubhubbub_render_feed($data, $conf);
|
||||
$expected = '<atom:link rel="hub" href="'. $hub .'" />';
|
||||
|
@ -49,7 +49,7 @@ class PluginPubsubhubbubTest extends \PHPUnit\Framework\TestCase
|
|||
$hub = 'http://domain.hub';
|
||||
$conf = new ConfigManager(self::$configFile);
|
||||
$conf->set('plugins.PUBSUBHUB_URL', $hub);
|
||||
$data['_PAGE_'] = Router::$PAGE_FEED_ATOM;
|
||||
$data['_PAGE_'] = TemplatePage::FEED_ATOM;
|
||||
|
||||
$data = hook_pubsubhubbub_render_feed($data, $conf);
|
||||
$expected = '<link rel="hub" href="'. $hub .'" />';
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace Shaarli\Plugin\Qrcode;
|
|||
*/
|
||||
|
||||
use Shaarli\Plugin\PluginManager;
|
||||
use Shaarli\Router;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
|
||||
require_once 'plugins/qrcode/qrcode.php';
|
||||
|
||||
|
@ -57,7 +57,7 @@ class PluginQrcodeTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
$str = 'stuff';
|
||||
$data = array($str => $str);
|
||||
$data['_PAGE_'] = Router::$PAGE_LINKLIST;
|
||||
$data['_PAGE_'] = TemplatePage::LINKLIST;
|
||||
|
||||
$data = hook_qrcode_render_footer($data);
|
||||
$this->assertEquals($str, $data[$str]);
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
namespace Shaarli\Updater;
|
||||
|
||||
use Exception;
|
||||
use Shaarli\Bookmark\BookmarkFileService;
|
||||
use Shaarli\Bookmark\BookmarkServiceInterface;
|
||||
use Shaarli\Config\ConfigManager;
|
||||
use Shaarli\History;
|
||||
|
||||
require_once 'tests/updater/DummyUpdater.php';
|
||||
require_once 'tests/utils/ReferenceLinkDB.php';
|
||||
|
@ -29,6 +32,12 @@ class UpdaterTest extends \PHPUnit\Framework\TestCase
|
|||
*/
|
||||
protected $conf;
|
||||
|
||||
/** @var BookmarkServiceInterface */
|
||||
protected $bookmarkService;
|
||||
|
||||
/** @var Updater */
|
||||
protected $updater;
|
||||
|
||||
/**
|
||||
* Executed before each test.
|
||||
*/
|
||||
|
@ -36,6 +45,8 @@ class UpdaterTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
copy('tests/utils/config/configJson.json.php', self::$configFile .'.json.php');
|
||||
$this->conf = new ConfigManager(self::$configFile);
|
||||
$this->bookmarkService = new BookmarkFileService($this->conf, $this->createMock(History::class), true);
|
||||
$this->updater = new Updater([], $this->bookmarkService, $this->conf, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -167,4 +178,12 @@ class UpdaterTest extends \PHPUnit\Framework\TestCase
|
|||
$updater = new DummyUpdater($updates, array(), $this->conf, true);
|
||||
$updater->update();
|
||||
}
|
||||
|
||||
public function testUpdateMethodRelativeHomeLinkRename(): void
|
||||
{
|
||||
$this->conf->set('general.header_link', '?');
|
||||
$this->updater->updateMethodRelativeHomeLink();
|
||||
|
||||
static::assertSame();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -224,7 +224,7 @@
|
|||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
<a href="{$base_path}/?{$value.shorturl}" title="{$strPermalink}">
|
||||
<a href="{$base_path}/shaare/{$value.shorturl}" title="{$strPermalink}">
|
||||
{if="!$hide_timestamps || $is_logged_in"}
|
||||
{$updated=$value.updated_timestamp ? $strEdited. format_date($value.updated) : $strPermalink}
|
||||
<span class="linkdate" title="{$updated}">
|
||||
|
|
Loading…
Reference in a new issue