New basePath: fix officiel plugin paths and vintage template

This commit is contained in:
ArthurHoaro 2020-07-26 14:43:10 +02:00
parent bc583903ad
commit 9fbc42294e
39 changed files with 169 additions and 244 deletions

View file

@ -1,6 +1,7 @@
<?php
use Shaarli\Config\Exception\PluginConfigOrderException;
use Shaarli\Plugin\PluginManager;
/**
* Plugin configuration helper functions.
@ -19,6 +20,20 @@
*/
function save_plugin_config($formData)
{
// We can only save existing plugins
$directories = str_replace(
PluginManager::$PLUGINS_PATH . '/',
'',
glob(PluginManager::$PLUGINS_PATH . '/*')
);
$formData = array_filter(
$formData,
function ($value, string $key) use ($directories) {
return startsWith($key, 'order') || in_array($key, $directories);
},
ARRAY_FILTER_USE_BOTH
);
// Make sure there are no duplicates in orders.
if (!validate_plugin_order($formData)) {
throw new PluginConfigOrderException();
@ -69,7 +84,7 @@ function validate_plugin_order($formData)
$orders = array();
foreach ($formData as $key => $value) {
// No duplicate order allowed.
if (in_array($value, $orders)) {
if (in_array($value, $orders, true)) {
return false;
}

View file

@ -60,7 +60,7 @@ public function __invoke(Request $request, Response $response, callable $next):
$response = $response->withStatus($e->getCode());
return $response->write($this->container->pageBuilder->render('error'));
return $response->write($this->container->pageBuilder->render('error', $this->container->basePath));
} catch (UnauthorizedException $e) {
$returnUrl = urlencode($this->container->environment['REQUEST_URI']);
@ -80,7 +80,7 @@ public function __invoke(Request $request, Response $response, callable $next):
$response = $response->withStatus(500);
return $response->write($this->container->pageBuilder->render('error'));
return $response->write($this->container->pageBuilder->render('error', $this->container->basePath));
}
}

View file

@ -152,7 +152,7 @@ public function save(Request $request, Response $response): Response
// To preserve backward compatibility with 3rd parties, plugins still use arrays
$formatter = $this->container->formatterFactory->getFormatter('raw');
$data = $formatter->format($bookmark);
$data = $this->executeHooks('save_link', $data);
$this->executePageHooks('save_link', $data);
$bookmark->fromArray($data);
$this->container->bookmarkService->set($bookmark);
@ -211,7 +211,7 @@ public function deleteBookmark(Request $request, Response $response): Response
}
$data = $formatter->format($bookmark);
$this->container->pluginManager->executeHooks('delete_link', $data);
$this->executePageHooks('delete_link', $data);
$this->container->bookmarkService->remove($bookmark, false);
++ $count;
}
@ -283,7 +283,7 @@ public function changeVisibility(Request $request, Response $response): Response
// To preserve backward compatibility with 3rd parties, plugins still use arrays
$data = $formatter->format($bookmark);
$this->container->pluginManager->executeHooks('save_link', $data);
$this->executePageHooks('save_link', $data);
$bookmark->fromArray($data);
$this->container->bookmarkService->set($bookmark, false);
@ -325,7 +325,7 @@ public function pinBookmark(Request $request, Response $response, array $args):
// To preserve backward compatibility with 3rd parties, plugins still use arrays
$data = $formatter->format($bookmark);
$this->container->pluginManager->executeHooks('save_link', $data);
$this->executePageHooks('save_link', $data);
$bookmark->fromArray($data);
$this->container->bookmarkService->set($bookmark);
@ -354,7 +354,7 @@ protected function displayForm(array $link, bool $isNew, Request $request, Respo
'default_private_links' => $this->container->conf->get('privacy.default_private_links', false),
];
$data = $this->executeHooks('render_editlink', $data);
$this->executePageHooks('render_editlink', $data, TemplatePage::EDIT_LINK);
foreach ($data as $key => $value) {
$this->assignView($key, $value);
@ -368,19 +368,4 @@ protected function displayForm(array $link, bool $isNew, Request $request, Respo
return $response->write($this->render(TemplatePage::EDIT_LINK));
}
/**
* @param mixed[] $data Variables passed to the template engine
*
* @return mixed[] Template data after active plugins render_picwall hook execution.
*/
protected function executeHooks(string $hook, array $data): array
{
$this->container->pluginManager->executeHooks(
$hook,
$data
);
return $data;
}
}

View file

@ -58,7 +58,7 @@ public function save(Request $request, Response $response): Response
try {
$parameters = $request->getParams() ?? [];
$this->executeHooks($parameters);
$this->executePageHooks('save_plugin_parameters', $parameters);
if (isset($parameters['parameters_form'])) {
unset($parameters['parameters_form']);
@ -81,19 +81,4 @@ public function save(Request $request, Response $response): Response
return $this->redirect($response, '/admin/plugins');
}
/**
* @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(
'save_plugin_parameters',
$data
);
return $data;
}
}

View file

@ -22,7 +22,7 @@ public function index(Request $request, Response $response): Response
'sslenabled' => is_https($this->container->environment),
];
$data = $this->executeHooks($data);
$this->executePageHooks('render_tools', $data, TemplatePage::TOOLS);
foreach ($data as $key => $value) {
$this->assignView($key, $value);
@ -32,19 +32,4 @@ public function index(Request $request, Response $response): Response
return $response->write($this->render(TemplatePage::TOOLS));
}
/**
* @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;
}
}

View file

@ -124,7 +124,7 @@ public function index(Request $request, Response $response): Response
$data['pagetitle'] = ($data['pagetitle'] ?? '') . $this->container->conf->get('general.title', 'Shaarli');
$this->executeHooks($data);
$this->executePageHooks('render_linklist', $data, TemplatePage::LINKLIST);
$this->assignAllView($data);
return $response->write($this->render(TemplatePage::LINKLIST));
@ -153,7 +153,7 @@ public function permalink(Request $request, Response $response, array $args): Re
]
);
$this->executeHooks($data);
$this->executePageHooks('render_linklist', $data, TemplatePage::LINKLIST);
$this->assignAllView($data);
return $response->write($this->render(TemplatePage::LINKLIST));
@ -182,18 +182,6 @@ protected function updateThumbnail(Bookmark $bookmark, bool $writeDatastore = tr
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.
*/

View file

@ -72,13 +72,11 @@ public function index(Request $request, Response $response): Response
];
// Hooks are called before column construction so that plugins don't have to deal with columns.
$data = $this->executeHooks($data);
$this->executePageHooks('render_daily', $data, TemplatePage::DAILY);
$data['cols'] = $this->calculateColumns($data['linksToDisplay']);
foreach ($data as $key => $value) {
$this->assignView($key, $value);
}
$this->assignAllView($data);
$mainTitle = $this->container->conf->get('general.title', 'Shaarli');
$this->assignView(
@ -190,20 +188,4 @@ protected function calculateColumns(array $links): array
return $columns;
}
/**
* @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_daily',
$data,
['loggedin' => $this->container->loginManager->isLoggedIn()]
);
return $data;
}
}

View file

@ -46,7 +46,7 @@ protected function processRequest(string $feedType, Request $request, Response $
$data = $this->container->feedBuilder->buildData($feedType, $request->getParams());
$data = $this->executeHooks($data, $feedType);
$this->executePageHooks('render_feed', $data, $feedType);
$this->assignAllView($data);
$content = $this->render('feed.'. $feedType);
@ -55,23 +55,4 @@ protected function processRequest(string $feedType, Request $request, Response $
return $response->write($content);
}
/**
* @param mixed[] $data Template data
*
* @return mixed[] Template data after active plugins hook execution.
*/
protected function executeHooks(array $data, string $feedType): array
{
$this->container->pluginManager->executeHooks(
'render_feed',
$data,
[
'loggedin' => $this->container->loginManager->isLoggedIn(),
'target' => $feedType,
]
);
return $data;
}
}

View file

@ -42,30 +42,13 @@ public function index(Request $request, Response $response): Response
}
}
$data = $this->executeHooks($linksToDisplay);
$data = ['linksToDisplay' => $linksToDisplay];
$this->executePageHooks('render_picwall', $data, TemplatePage::PICTURE_WALL);
foreach ($data as $key => $value) {
$this->assignView($key, $value);
}
return $response->write($this->render(TemplatePage::PICTURE_WALL));
}
/**
* @param mixed[] $linksToDisplay List of formatted bookmarks
*
* @return mixed[] Template data after active plugins render_picwall hook execution.
*/
protected function executeHooks(array $linksToDisplay): array
{
$data = [
'linksToDisplay' => $linksToDisplay,
];
$this->container->pluginManager->executeHooks(
'render_picwall',
$data,
['loggedin' => $this->container->loginManager->isLoggedIn()]
);
return $data;
}
}

View file

@ -60,22 +60,9 @@ protected function render(string $template): string
$this->assignView('privateLinkcount', $this->container->bookmarkService->count(BookmarkFilter::$PRIVATE));
$this->assignView('plugin_errors', $this->container->pluginManager->getErrors());
/*
* Define base path (if Shaarli is installed in a domain's subfolder, e.g. `/shaarli`)
* and the asset path (subfolder/tpl/default for default theme).
* These MUST be used to create an internal link or to include an asset in templates.
*/
$this->assignView('base_path', $this->container->basePath);
$this->assignView(
'asset_path',
$this->container->basePath . '/' .
rtrim($this->container->conf->get('resource.raintpl_tpl', 'tpl'), '/') . '/' .
$this->container->conf->get('resource.theme', 'default')
);
$this->executeDefaultHooks($template);
return $this->container->pageBuilder->render($template);
return $this->container->pageBuilder->render($template, $this->container->basePath);
}
/**
@ -97,13 +84,29 @@ protected function executeDefaultHooks(string $template): void
$pluginData,
[
'target' => $template,
'loggedin' => $this->container->loginManager->isLoggedIn()
'loggedin' => $this->container->loginManager->isLoggedIn(),
'basePath' => $this->container->basePath,
]
);
$this->assignView('plugins_' . $name, $pluginData);
}
}
protected function executePageHooks(string $hook, array &$data, string $template = null): void
{
$params = [
'target' => $template,
'loggedin' => $this->container->loginManager->isLoggedIn(),
'basePath' => $this->container->basePath,
];
$this->container->pluginManager->executeHooks(
$hook,
$data,
$params
);
}
/**
* Simple helper which prepend the base path to redirect path.
*

View file

@ -71,10 +71,8 @@ protected function processRequest(string $type, Request $request, Response $resp
'search_tags' => $searchTags,
'tags' => $tags,
];
$data = $this->executeHooks('tag' . $type, $data);
foreach ($data as $key => $value) {
$this->assignView($key, $value);
}
$this->executePageHooks('render_tag' . $type, $data, 'tag.' . $type);
$this->assignAllView($data);
$searchTags = !empty($searchTags) ? $searchTags .' - ' : '';
$this->assignView(
@ -82,7 +80,7 @@ protected function processRequest(string $type, Request $request, Response $resp
$searchTags . t('Tag '. $type) .' - '. $this->container->conf->get('general.title', 'Shaarli')
);
return $response->write($this->render('tag.'. $type));
return $response->write($this->render('tag.' . $type));
}
/**
@ -112,20 +110,4 @@ protected function formatTagsForCloud(array $tags): array
return $tagList;
}
/**
* @param mixed[] $data Template data
*
* @return mixed[] Template data after active plugins hook execution.
*/
protected function executeHooks(string $template, array $data): array
{
$this->container->pluginManager->executeHooks(
'render_'. $template,
$data,
['loggedin' => $this->container->loginManager->isLoggedIn()]
);
return $data;
}
}

View file

@ -108,6 +108,10 @@ public function executeHooks($hook, &$data, $params = array())
$data['_LOGGEDIN_'] = $params['loggedin'];
}
if (isset($params['basePath'])) {
$data['_BASE_PATH_'] = $params['basePath'];
}
foreach ($this->loadedPlugins as $plugin) {
$hookFunction = $this->buildHookName($hook, $plugin);

View file

@ -3,6 +3,7 @@
namespace Shaarli\Render;
use Exception;
use exceptions\MissingBasePathException;
use RainTPL;
use Shaarli\ApplicationUtils;
use Shaarli\Bookmark\BookmarkServiceInterface;
@ -156,7 +157,7 @@ private function initialize()
* Affect variable after controller processing.
* Used for alert messages.
*/
protected function finalize(): void
protected function finalize(string $basePath): void
{
// TODO: use the SessionManager
$messageKeys = [
@ -170,6 +171,14 @@ protected function finalize(): void
unset($_SESSION[$messageKey]);
}
}
$this->assign('base_path', $basePath);
$this->assign(
'asset_path',
$basePath . '/' .
rtrim($this->conf->get('resource.raintpl_tpl', 'tpl'), '/') . '/' .
$this->conf->get('resource.theme', 'default')
);
}
/**
@ -209,23 +218,6 @@ public function assignAll($data)
return true;
}
/**
* Render a specific page (using a template file).
* e.g. $pb->renderPage('picwall');
*
* @param string $page Template filename (without extension).
*/
public function renderPage($page)
{
if ($this->tpl === false) {
$this->initialize();
}
$this->finalize();
$this->tpl->draw($page);
}
/**
* Render a specific page as string (using a template file).
* e.g. $pb->render('picwall');
@ -234,13 +226,13 @@ public function renderPage($page)
*
* @return string Processed template content
*/
public function render(string $page): string
public function render(string $page, string $basePath): string
{
if ($this->tpl === false) {
$this->initialize();
}
$this->finalize();
$this->finalize($basePath);
return $this->tpl->draw($page, true);
}

View file

@ -20,7 +20,7 @@ function hook_addlink_toolbar_render_header($data)
$form = array(
'attr' => array(
'method' => 'GET',
'action' => '',
'action' => $data['_BASE_PATH_'] . '/admin/shaare',
'name' => 'addform',
'class' => 'addform',
),

View file

@ -1,5 +1,5 @@
<span>
<a href="https://web.archive.org/web/%s">
<img class="linklist-plugin-icon" src="plugins/archiveorg/internetarchive.png" title="%s" alt="archive.org" />
<img class="linklist-plugin-icon" src="%s/archiveorg/internetarchive.png" title="%s" alt="archive.org" />
</a>
</span>

View file

@ -17,12 +17,13 @@
function hook_archiveorg_render_linklist($data)
{
$archive_html = file_get_contents(PluginManager::$PLUGINS_PATH . '/archiveorg/archiveorg.html');
$path = ($data['_BASE_PATH_'] ?? '') . '/' . PluginManager::$PLUGINS_PATH;
foreach ($data['links'] as &$value) {
if ($value['private'] && preg_match('/^\?[a-zA-Z0-9-_@]{6}($|&|#)/', $value['real_url'])) {
continue;
}
$archive = sprintf($archive_html, $value['url'], t('View on archive.org'));
$archive = sprintf($archive_html, $value['url'], $path, t('View on archive.org'));
$value['link_plugin'][] = $archive;
}

View file

@ -118,7 +118,7 @@ function hook_demo_plugin_render_header($data)
$form = array(
'attr' => array(
'method' => 'GET',
'action' => '?',
'action' => $data['_BASE_PATH_'] . '/',
'class' => 'addform',
),
'inputs' => array(

View file

@ -1,5 +0,0 @@
<span>
<a href="?%s#isso-thread">
<img class="linklist-plugin-icon" src="plugins/archiveorg/internetarchive.png" title="%s" alt="archive.org" />
</a>
</span>

View file

@ -19,11 +19,12 @@ function hook_qrcode_render_linklist($data)
{
$qrcode_html = file_get_contents(PluginManager::$PLUGINS_PATH . '/qrcode/qrcode.html');
$path = ($data['_BASE_PATH_'] ?? '') . '/' . PluginManager::$PLUGINS_PATH;
foreach ($data['links'] as &$value) {
$qrcode = sprintf(
$qrcode_html,
$value['url'],
PluginManager::$PLUGINS_PATH
$path
);
$value['link_plugin'][] = $qrcode;
}
@ -41,7 +42,7 @@ function hook_qrcode_render_linklist($data)
function hook_qrcode_render_footer($data)
{
if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
$data['js_files'][] = PluginManager::$PLUGINS_PATH . '/qrcode/shaarli-qrcode.js';
$data['js_files'][] = PluginManager::$PLUGINS_PATH . '/qrcode/shaarli-qrcode.js';
}
return $data;

View file

@ -28,14 +28,15 @@
// Show the QR-Code of a permalink (when the QR-Code icon is clicked).
function showQrCode(caller,loading)
{
{
// Dynamic javascript lib loading: We only load qr.js if the QR code icon is clicked:
if (typeof(qr) == 'undefined') // Load qr.js only if not present.
{
if (!loading) // If javascript lib is still loading, do not append script to body.
{
var element = document.createElement("script");
element.src = "plugins/qrcode/qr-1.1.3.min.js";
var basePath = document.querySelector('input[name="js_base_path"]').value;
var element = document.createElement("script");
element.src = basePath + "/plugins/qrcode/qr-1.1.3.min.js";
document.body.appendChild(element);
}
setTimeout(function() { showQrCode(caller,true);}, 200); // Retry in 200 milliseconds.
@ -44,7 +45,7 @@ function showQrCode(caller,loading)
// Remove previous qrcode if present.
removeQrcode();
// Build the div which contains the QR-Code:
var element = document.createElement('div');
element.id = 'permalinkQrcode';
@ -57,11 +58,11 @@ function showQrCode(caller,loading)
// Damn IE
element.setAttribute('onclick', 'this.parentNode.removeChild(this);' );
}
// Build the QR-Code:
var image = qr.image({size: 8,value: caller.dataset.permalink});
if (image)
{
{
element.appendChild(image);
element.innerHTML += "<br>Click to close";
caller.parentNode.appendChild(element);
@ -87,4 +88,4 @@ function removeQrcode()
elem.parentNode.removeChild(elem);
}
return false;
}
}

View file

@ -45,12 +45,14 @@ function hook_wallabag_render_linklist($data, $conf)
$wallabagHtml = file_get_contents(PluginManager::$PLUGINS_PATH . '/wallabag/wallabag.html');
$linkTitle = t('Save to wallabag');
$path = ($data['_BASE_PATH_'] ?? '') . '/' . PluginManager::$PLUGINS_PATH;
foreach ($data['links'] as &$value) {
$wallabag = sprintf(
$wallabagHtml,
$wallabagInstance->getWallabagUrl(),
urlencode($value['url']),
PluginManager::$PLUGINS_PATH,
$path,
$linkTitle
);
$value['link_plugin'][] = $wallabag;

View file

@ -2,6 +2,7 @@
namespace Shaarli\Config;
use Shaarli\Config\Exception\PluginConfigOrderException;
use Shaarli\Plugin\PluginManager;
require_once 'application/config/ConfigPlugin.php';
@ -17,23 +18,30 @@ class ConfigPluginTest extends \PHPUnit\Framework\TestCase
*/
public function testSavePluginConfigValid()
{
$data = array(
$data = [
'order_plugin1' => 2, // no plugin related
'plugin2' => 0, // new - at the end
'plugin3' => 0, // 2nd
'order_plugin3' => 8,
'plugin4' => 0, // 1st
'order_plugin4' => 5,
);
];
$expected = array(
$expected = [
'plugin3',
'plugin4',
'plugin2',
);
];
mkdir($path = __DIR__ . '/folder');
PluginManager::$PLUGINS_PATH = $path;
array_map(function (string $plugin) use ($path) { touch($path . '/' . $plugin); }, $expected);
$out = save_plugin_config($data);
$this->assertEquals($expected, $out);
array_map(function (string $plugin) use ($path) { unlink($path . '/' . $plugin); }, $expected);
rmdir($path);
}
/**

View file

@ -59,8 +59,12 @@ public function testDeleteSingleBookmark(): void
->with('raw')
->willReturnCallback(function () use ($bookmark): BookmarkFormatter {
$formatter = $this->createMock(BookmarkFormatter::class);
$formatter->expects(static::once())->method('format')->with($bookmark);
$formatter
->expects(static::once())
->method('format')
->with($bookmark)
->willReturn(['formatted' => $bookmark])
;
return $formatter;
})
@ -70,7 +74,7 @@ public function testDeleteSingleBookmark(): void
$this->container->pluginManager
->expects(static::once())
->method('executeHooks')
->with('delete_link')
->with('delete_link', ['formatted' => $bookmark])
;
$result = $this->controller->deleteBookmark($request, $response);
@ -129,6 +133,9 @@ public function testDeleteMultipleBookmarks(): void
->withConsecutive(...array_map(function (Bookmark $bookmark): array {
return [$bookmark];
}, $bookmarks))
->willReturnOnConsecutiveCalls(...array_map(function (Bookmark $bookmark): array {
return ['formatted' => $bookmark];
}, $bookmarks))
;
return $formatter;
@ -254,6 +261,9 @@ public function testDeleteMultipleBookmarksOneNotFound(): void
->withConsecutive(...array_map(function (Bookmark $bookmark): array {
return [$bookmark];
}, $bookmarks))
->willReturnOnConsecutiveCalls(...array_map(function (Bookmark $bookmark): array {
return ['formatted' => $bookmark];
}, $bookmarks))
;
return $formatter;
@ -350,7 +360,12 @@ public function testDeleteBookmarkFromBookmarklet(): void
$this->container->formatterFactory
->expects(static::once())
->method('getFormatter')
->willReturn($this->createMock(BookmarkFormatter::class))
->willReturnCallback(function (): BookmarkFormatter {
$formatter = $this->createMock(BookmarkFormatter::class);
$formatter->method('format')->willReturn(['formatted']);
return $formatter;
})
;
$result = $this->controller->deleteBookmark($request, $response);

View file

@ -7,6 +7,7 @@
use PHPUnit\Framework\TestCase;
use Shaarli\Config\ConfigManager;
use Shaarli\Front\Exception\WrongTokenException;
use Shaarli\Plugin\PluginManager;
use Shaarli\Security\SessionManager;
use Slim\Http\Request;
use Slim\Http\Response;
@ -15,6 +16,8 @@ class PluginsControllerTest extends TestCase
{
use FrontAdminControllerMockHelper;
const PLUGIN_NAMES = ['plugin1', 'plugin2', 'plugin3', 'plugin4'];
/** @var PluginsController */
protected $controller;
@ -23,6 +26,17 @@ public function setUp(): void
$this->createContainer();
$this->controller = new PluginsController($this->container);
mkdir($path = __DIR__ . '/folder');
PluginManager::$PLUGINS_PATH = $path;
array_map(function (string $plugin) use ($path) { touch($path . '/' . $plugin); }, static::PLUGIN_NAMES);
}
public function tearDown()
{
$path = __DIR__ . '/folder';
array_map(function (string $plugin) use ($path) { unlink($path . '/' . $plugin); }, static::PLUGIN_NAMES);
rmdir($path);
}
/**

View file

@ -23,7 +23,7 @@ public function setUp(): void
$this->controller = new SessionFilterController($this->container);
}
/**
* Visibility - Default call for private filter while logged in without current value
*/

View file

@ -96,8 +96,6 @@ public function testRender(): void
static::assertSame(10, $this->assignedValues['linkcount']);
static::assertSame(5, $this->assignedValues['privateLinkcount']);
static::assertSame(['error'], $this->assignedValues['plugin_errors']);
static::assertSame('/subfolder', $this->assignedValues['base_path']);
static::assertSame('/subfolder/tpl/default', $this->assignedValues['asset_path']);
static::assertSame('templateName', $this->assignedValues['plugins_includes']['render_includes']['target']);
static::assertTrue($this->assignedValues['plugins_includes']['render_includes']['loggedin']);

View file

@ -28,6 +28,7 @@ public function testAddlinkHeaderLoggedIn()
$data = array($str => $str);
$data['_PAGE_'] = TemplatePage::LINKLIST;
$data['_LOGGEDIN_'] = true;
$data['_BASE_PATH_'] = '/subfolder';
$data = hook_addlink_toolbar_render_header($data);
$this->assertEquals($str, $data[$str]);
@ -36,6 +37,8 @@ public function testAddlinkHeaderLoggedIn()
$data = array($str => $str);
$data['_PAGE_'] = $str;
$data['_LOGGEDIN_'] = true;
$data['_BASE_PATH_'] = '/subfolder';
$data = hook_addlink_toolbar_render_header($data);
$this->assertEquals($str, $data[$str]);
$this->assertArrayNotHasKey('fields_toolbar', $data);
@ -50,6 +53,7 @@ public function testAddlinkHeaderLoggedOut()
$data = array($str => $str);
$data['_PAGE_'] = TemplatePage::LINKLIST;
$data['_LOGGEDIN_'] = false;
$data['_BASE_PATH_'] = '/subfolder';
$data = hook_addlink_toolbar_render_header($data);
$this->assertEquals($str, $data[$str]);

View file

@ -4,7 +4,7 @@
<body onload="document.changepasswordform.oldpassword.focus();">
<div id="pageheader">
{include="page.header"}
<form method="POST" action="#" name="changepasswordform" id="changepasswordform">
<form method="POST" action="{$base_path}/admin/password" name="changepasswordform" id="changepasswordform">
Old password: <input type="password" name="oldpassword">&nbsp; &nbsp;
New password: <input type="password" name="setpassword">
<input type="hidden" name="token" value="{$token}">
@ -12,4 +12,4 @@
</div>
{include="page.footer"}
</body>
</html>
</html>

View file

@ -5,7 +5,7 @@
<body onload="document.changetag.fromtag.focus();">
<div id="pageheader">
{include="page.header"}
<form method="POST" action="" name="changetag" id="changetag">
<form method="POST" action="{$base_path}/admin/tags" name="changetag" id="changetag">
<input type="hidden" name="token" value="{$token}">
<div>
<label for="fromtag">Tag:</label>

View file

@ -4,7 +4,7 @@
<body onload="document.configform.title.focus();">
<div id="pageheader">
{include="page.header"}
<form method="POST" action="#" name="configform" id="configform">
<form method="POST" action="{$base_path}/admin/configure" name="configform" id="configform">
<input type="hidden" name="token" value="{$token}">
<table id="configuration_table">

View file

@ -1,7 +1,6 @@
<!DOCTYPE html>
<html>
<head>{include="includes"}
<link type="text/css" rel="stylesheet" href="inc/awesomplete.css#" />
</head>
<body
{if="$link.title==''"}onload="document.linkform.lf_title.focus();"
@ -10,9 +9,8 @@
<div id="pageheader">
{include="page.header"}
<div id="shaarli_title"><a href="{$titleLink}">{$shaarlititle}</a></div>
{/if}
<div id="editlinkform">
<form method="post" name="linkform">
<form method="post" name="linkform" action="{$base_path}/admin/shaare">
<input type="hidden" name="lf_linkdate" value="{$link.linkdate}">
{if="isset($link.id)"}
<input type="hidden" name="lf_id" value="{$link.id}">

View file

@ -10,6 +10,8 @@
<input type="radio" name="selection" value="all" checked="true"> All<br>
<input type="radio" name="selection" value="private"> Private<br>
<input type="radio" name="selection" value="public"> Public<br>
<input type="hidden" name="token" value="{$token}">
<br>
<input type="checkbox" name="prepend_note_url" id="prepend_note_url">
<label for="prepend_note_url">

View file

@ -6,14 +6,14 @@
<link rel="alternate" type="application/rss+xml" href="{$feedurl}feed/rss?{$searchcrits}#" title="RSS Feed" />
<link rel="alternate" type="application/atom+xml" href="{$feedurl}feed/atom?{$searchcrits}#" title="ATOM Feed" />
<link href="img/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<link type="text/css" rel="stylesheet" href="css/shaarli.min.css" />
<link type="text/css" rel="stylesheet" href="{$asset_path}/css/shaarli.min.css#" />
{if="$formatter==='markdown'"}
<link type="text/css" rel="stylesheet" href="{$asset_path}/css/markdown.min.css?v={$version_hash}#" />
{/if}
{loop="$plugins_includes.css_files"}
<link type="text/css" rel="stylesheet" href="{$value}#"/>
<link type="text/css" rel="stylesheet" href="{$base_path}/{$value}#"/>
{/loop}
{if="is_file('data/user.css')"}<link type="text/css" rel="stylesheet" href="data/user.css#" />{/if}
{if="is_file('data/user.css')"}<link type="text/css" rel="stylesheet" href="{$base_path}/data/user.css#" />{/if}
<link rel="search" type="application/opensearchdescription+xml" href="{$base_path}/open-search#"
title="Shaarli search - {$shaarlititle|htmlspecialchars}" />
{if="! empty($links) && count($links) === 1"}

View file

@ -5,7 +5,7 @@
<div id="install">
<h1>Shaarli</h1>
It looks like it's the first time you run Shaarli. Please configure it:<br>
<form method="POST" action="#" name="installform" id="installform">
<form method="POST" action="{$base_path}/install" name="installform" id="installform">
<table>
<tr><td><b>Login:</b></td><td><input type="text" name="setlogin" size="30"></td></tr>
<tr><td><b>Password:</b></td><td><input type="password" name="setpassword" size="30"></td></tr>

View file

@ -1,7 +1,6 @@
<!DOCTYPE html>
<html>
<head>
<link type="text/css" rel="stylesheet" href="inc/awesomplete.css#" />
{include="includes"}
</head>
<body>
@ -84,7 +83,7 @@
<div class="thumbnail">
<a href="{$value.real_url}">
{ignore}RainTPL hack: put the 2 src on two different line to avoid path replace bug{/ignore}
<img data-src="{$value.thumbnail}#" class="b-lazy"
<img data-src="{$base_path}/{$value.thumbnail}#" class="b-lazy"
src=""
alt="thumbnail" width="{$thumbnails_width}" height="{$thumbnails_height}" />
</a>
@ -93,17 +92,16 @@
<div class="linkcontainer">
{if="$is_logged_in"}
<div class="linkeditbuttons">
<form method="GET" class="buttoneditform">
<input type="hidden" name="edit_link" value="{$value.id}">
<input type="image" alt="Edit" src="{$asset_path}/img/edit_icon.png#" title="Edit" class="button_edit">
</form><br>
<form method="GET" class="buttoneditform">
<input type="hidden" name="lf_linkdate" value="{$value.id}">
<input type="hidden" name="token" value="{$token}">
<input type="hidden" name="delete_link">
<input type="image" alt="Delete" src="{$asset_path}/img/delete_icon.png#" title="Delete"
class="button_delete" onClick="return confirmDeleteLink();">
</form>
<a href="{$base_path}/admin/shaare/{$value.id}" title="Edit" class="button_edit">
<img src="{$asset_path}/img/edit_icon.png#">
</a>
<br>
<a href="{$base_path}/admin/shaare/delete?id={$value.id}&amp;token={$token}" label="Delete"
onClick="return confirmDeleteLink();"
class="button_delete"
>
<img src="{$asset_path}/img/delete_icon.png#">
</a>
</div>
{/if}
<span class="linktitle">
@ -114,7 +112,7 @@
{if="!$hide_timestamps || $is_logged_in"}
{$updated=$value.updated_timestamp ? 'Edited: '. format_date($value.updated) : 'Permalink'}
<span class="linkdate" title="Permalink">
<a href="{$base_path}/?{$value.shorturl}">
<a href="{$base_path}/shaare/{$value.shorturl}">
<span title="{$updated}">
{$value.created|format_date}
{if="$value.updated_timestamp"}*{/if}
@ -123,7 +121,7 @@
</a> -
</span>
{else}
<span class="linkdate" title="Short link here"><a href="{$base_path}/?{$value.shorturl}">permalink</a> - </span>
<span class="linkdate" title="Short link here"><a href="{$base_path}/shaare/{$value.shorturl}">permalink</a> - </span>
{/if}
{loop="$value.link_plugin"}

View file

@ -11,7 +11,7 @@
{include="page.header"}
<div id="headerform">
<form method="post" name="loginform">
<form method="post" name="loginform" action="{$base_path}/login">
<label for="login">Login: <input type="text" id="login" name="login" tabindex="1"
{if="!empty($username)"}value="{$username}"{/if}>
</label>

View file

@ -30,5 +30,7 @@
{/if}
{loop="$plugins_footer.js_files"}
<script src="{$value}#"></script>
<script src="{$base_path}/{$value}#"></script>
{/loop}
<input type="hidden" name="js_base_path" value="{$base_path}" />

View file

@ -86,6 +86,7 @@ <h1>Disabled Plugins</h1>
<input type="submit" value="Save"/>
</div>
</section>
<input type="hidden" name="token" value="{$token}">
</form>
<form action="{$base_path}/admin/plugins" method="POST">
@ -124,6 +125,7 @@ <h2>{function="str_replace('_', ' ', $key)"}</h2>
</div>
</div>
</section>
<input type="hidden" name="token" value="{$token}">
</form>
</div>

View file

@ -23,7 +23,6 @@
<input type="hidden" name="ids" value="{function="implode(',', $ids)"}" />
{include="page.footer"}
<input type="hidden" name="js_base_path" value="{$base_path}" />
<script src="{$asset_path}/js/thumbnails_update.min.js?v={$version_hash}#"></script>
</body>
</html>