New basePath: fix officiel plugin paths and vintage template
This commit is contained in:
parent
bc583903ad
commit
9fbc42294e
39 changed files with 169 additions and 244 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
),
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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>
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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']);
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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">
|
||||
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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
||||
|
|
|
@ -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}">
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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"}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}&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"}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}" />
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue