aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc/md/dev/Plugin-system.md14
-rw-r--r--plugins/archiveorg/archiveorg.php6
-rw-r--r--plugins/isso/isso.php2
-rw-r--r--plugins/qrcode/qrcode.php4
-rw-r--r--tests/plugins/PluginArchiveorgTest.php37
-rw-r--r--tests/plugins/PluginIssoTest.php23
-rw-r--r--tpl/vintage/linklist.paging.html2
7 files changed, 61 insertions, 27 deletions
diff --git a/doc/md/dev/Plugin-system.md b/doc/md/dev/Plugin-system.md
index a87bd0cf..c29774de 100644
--- a/doc/md/dev/Plugin-system.md
+++ b/doc/md/dev/Plugin-system.md
@@ -139,6 +139,20 @@ Each file contain two keys:
139 139
140> Note: In PHP, `parse_ini_file()` seems to want strings to be between by quotes `"` in the ini file. 140> Note: In PHP, `parse_ini_file()` seems to want strings to be between by quotes `"` in the ini file.
141 141
142### Understanding relative paths
143
144Because Shaarli is a self-hosted tool, an instance can either be installed at the root directory, or under a subfolder.
145This means that you can *never* use absolute paths (eg `/plugins/mything/file.png`).
146
147If a file needs to be included in server end, use simple relative path:
148`PluginManager::$PLUGINS_PATH . '/mything/template.html'`.
149
150If it needs to be included in front end side (e.g. an image),
151the relative path must be prefixed with special data `_BASE_PATH_`:
152`($data['_BASE_PATH_'] ?? '') . '/' . PluginManager::$PLUGINS_PATH . '/mything/picture.png`.
153
154Note that special placeholders for CSS and JS files (respectively `css_files` and `js_files`) are already prefixed
155with the base path in template files.
142 156
143### It's not working! 157### It's not working!
144 158
diff --git a/plugins/archiveorg/archiveorg.php b/plugins/archiveorg/archiveorg.php
index f26e6129..922b5966 100644
--- a/plugins/archiveorg/archiveorg.php
+++ b/plugins/archiveorg/archiveorg.php
@@ -20,10 +20,12 @@ function hook_archiveorg_render_linklist($data)
20 $path = ($data['_BASE_PATH_'] ?? '') . '/' . PluginManager::$PLUGINS_PATH; 20 $path = ($data['_BASE_PATH_'] ?? '') . '/' . PluginManager::$PLUGINS_PATH;
21 21
22 foreach ($data['links'] as &$value) { 22 foreach ($data['links'] as &$value) {
23 if ($value['private'] && preg_match('/^\?[a-zA-Z0-9-_@]{6}($|&|#)/', $value['real_url'])) { 23 $isNote = startsWith($value['real_url'], '/shaare/');
24 if ($value['private'] && $isNote) {
24 continue; 25 continue;
25 } 26 }
26 $archive = sprintf($archive_html, $value['url'], $path, t('View on archive.org')); 27 $url = $isNote ? rtrim(index_url($_SERVER), '/') . $value['real_url'] : $value['real_url'];
28 $archive = sprintf($archive_html, $url, $path, t('View on archive.org'));
27 $value['link_plugin'][] = $archive; 29 $value['link_plugin'][] = $archive;
28 } 30 }
29 31
diff --git a/plugins/isso/isso.php b/plugins/isso/isso.php
index 16edd9a6..79e7380b 100644
--- a/plugins/isso/isso.php
+++ b/plugins/isso/isso.php
@@ -49,7 +49,7 @@ function hook_isso_render_linklist($data, $conf)
49 $isso = sprintf($issoHtml, $issoUrl, $issoUrl, $link['id'], $link['id']); 49 $isso = sprintf($issoHtml, $issoUrl, $issoUrl, $link['id'], $link['id']);
50 $data['plugin_end_zone'][] = $isso; 50 $data['plugin_end_zone'][] = $isso;
51 } else { 51 } else {
52 $button = '<span><a href="?%s#isso-thread">'; 52 $button = '<span><a href="'. ($data['_BASE_PATH_'] ?? '') . '/shaare/%s#isso-thread">';
53 // For the default theme we use a FontAwesome icon which is better than an image 53 // For the default theme we use a FontAwesome icon which is better than an image
54 if ($conf->get('resource.theme') === 'default') { 54 if ($conf->get('resource.theme') === 'default') {
55 $button .= '<i class="linklist-plugin-icon fa fa-comment"></i>'; 55 $button .= '<i class="linklist-plugin-icon fa fa-comment"></i>';
diff --git a/plugins/qrcode/qrcode.php b/plugins/qrcode/qrcode.php
index 56ae47b3..95499e39 100644
--- a/plugins/qrcode/qrcode.php
+++ b/plugins/qrcode/qrcode.php
@@ -42,7 +42,7 @@ function hook_qrcode_render_linklist($data)
42function hook_qrcode_render_footer($data) 42function hook_qrcode_render_footer($data)
43{ 43{
44 if ($data['_PAGE_'] == TemplatePage::LINKLIST) { 44 if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
45 $data['js_files'][] = ($data['_BASE_PATH_'] ?? '') . '/' . PluginManager::$PLUGINS_PATH . '/qrcode/shaarli-qrcode.js'; 45 $data['js_files'][] = PluginManager::$PLUGINS_PATH . '/qrcode/shaarli-qrcode.js';
46 } 46 }
47 47
48 return $data; 48 return $data;
@@ -58,7 +58,7 @@ function hook_qrcode_render_footer($data)
58function hook_qrcode_render_includes($data) 58function hook_qrcode_render_includes($data)
59{ 59{
60 if ($data['_PAGE_'] == TemplatePage::LINKLIST) { 60 if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
61 $data['css_files'][] = ($data['_BASE_PATH_'] ?? '') . '/' . PluginManager::$PLUGINS_PATH . '/qrcode/qrcode.css'; 61 $data['css_files'][] = PluginManager::$PLUGINS_PATH . '/qrcode/qrcode.css';
62 } 62 }
63 63
64 return $data; 64 return $data;
diff --git a/tests/plugins/PluginArchiveorgTest.php b/tests/plugins/PluginArchiveorgTest.php
index b9a67adb..9c19752c 100644
--- a/tests/plugins/PluginArchiveorgTest.php
+++ b/tests/plugins/PluginArchiveorgTest.php
@@ -1,10 +1,12 @@
1<?php 1<?php
2
2namespace Shaarli\Plugin\Archiveorg; 3namespace Shaarli\Plugin\Archiveorg;
3 4
4/** 5/**
5 * PluginArchiveorgTest.php 6 * PluginArchiveorgTest.php
6 */ 7 */
7 8
9use PHPUnit\Framework\TestCase;
8use Shaarli\Plugin\PluginManager; 10use Shaarli\Plugin\PluginManager;
9 11
10require_once 'plugins/archiveorg/archiveorg.php'; 12require_once 'plugins/archiveorg/archiveorg.php';
@@ -13,20 +15,35 @@ require_once 'plugins/archiveorg/archiveorg.php';
13 * Class PluginArchiveorgTest 15 * Class PluginArchiveorgTest
14 * Unit test for the archiveorg plugin 16 * Unit test for the archiveorg plugin
15 */ 17 */
16class PluginArchiveorgTest extends \PHPUnit\Framework\TestCase 18class PluginArchiveorgTest extends TestCase
17{ 19{
20 protected $savedScriptName;
21
18 /** 22 /**
19 * Reset plugin path 23 * Reset plugin path
20 */ 24 */
21 public function setUp() 25 public function setUp(): void
22 { 26 {
23 PluginManager::$PLUGINS_PATH = 'plugins'; 27 PluginManager::$PLUGINS_PATH = 'plugins';
28
29 // plugins manipulate global vars
30 $_SERVER['SERVER_PORT'] = '80';
31 $_SERVER['SERVER_NAME'] = 'shaarli.shaarli';
32 $this->savedScriptName = $_SERVER['SCRIPT_NAME'] ?? null;
33 $_SERVER['SCRIPT_NAME'] = '/index.php';
34 }
35
36 public function tearDown(): void
37 {
38 unset($_SERVER['SERVER_PORT']);
39 unset($_SERVER['SERVER_NAME']);
40 $_SERVER['SCRIPT_NAME'] = $this->savedScriptName;
24 } 41 }
25 42
26 /** 43 /**
27 * Test render_linklist hook on external bookmarks. 44 * Test render_linklist hook on external bookmarks.
28 */ 45 */
29 public function testArchiveorgLinklistOnExternalLinks() 46 public function testArchiveorgLinklistOnExternalLinks(): void
30 { 47 {
31 $str = 'http://randomstr.com/test'; 48 $str = 'http://randomstr.com/test';
32 49
@@ -56,16 +73,16 @@ class PluginArchiveorgTest extends \PHPUnit\Framework\TestCase
56 /** 73 /**
57 * Test render_linklist hook on internal bookmarks. 74 * Test render_linklist hook on internal bookmarks.
58 */ 75 */
59 public function testArchiveorgLinklistOnInternalLinks() 76 public function testArchiveorgLinklistOnInternalLinks(): void
60 { 77 {
61 $internalLink1 = 'http://shaarli.shaarli/?qvMAqg'; 78 $internalLink1 = 'http://shaarli.shaarli/shaare/qvMAqg';
62 $internalLinkRealURL1 = '?qvMAqg'; 79 $internalLinkRealURL1 = '/shaare/qvMAqg';
63 80
64 $internalLink2 = 'http://shaarli.shaarli/?2_7zww'; 81 $internalLink2 = 'http://shaarli.shaarli/shaare/2_7zww';
65 $internalLinkRealURL2 = '?2_7zww'; 82 $internalLinkRealURL2 = '/shaare/2_7zww';
66 83
67 $internalLink3 = 'http://shaarli.shaarli/?z7u-_Q'; 84 $internalLink3 = 'http://shaarli.shaarli/shaare/z7u-_Q';
68 $internalLinkRealURL3 = '?z7u-_Q'; 85 $internalLinkRealURL3 = '/shaare/z7u-_Q';
69 86
70 $data = array( 87 $data = array(
71 'title' => $internalLink1, 88 'title' => $internalLink1,
diff --git a/tests/plugins/PluginIssoTest.php b/tests/plugins/PluginIssoTest.php
index 99477205..2bbb93d2 100644
--- a/tests/plugins/PluginIssoTest.php
+++ b/tests/plugins/PluginIssoTest.php
@@ -2,6 +2,7 @@
2namespace Shaarli\Plugin\Isso; 2namespace Shaarli\Plugin\Isso;
3 3
4use DateTime; 4use DateTime;
5use PHPUnit\Framework\TestCase;
5use Shaarli\Bookmark\Bookmark; 6use Shaarli\Bookmark\Bookmark;
6use Shaarli\Config\ConfigManager; 7use Shaarli\Config\ConfigManager;
7use Shaarli\Plugin\PluginManager; 8use Shaarli\Plugin\PluginManager;
@@ -13,12 +14,12 @@ require_once 'plugins/isso/isso.php';
13 * 14 *
14 * Test the Isso plugin (comment system). 15 * Test the Isso plugin (comment system).
15 */ 16 */
16class PluginIssoTest extends \PHPUnit\Framework\TestCase 17class PluginIssoTest extends TestCase
17{ 18{
18 /** 19 /**
19 * Reset plugin path 20 * Reset plugin path
20 */ 21 */
21 public function setUp() 22 public function setUp(): void
22 { 23 {
23 PluginManager::$PLUGINS_PATH = 'plugins'; 24 PluginManager::$PLUGINS_PATH = 'plugins';
24 } 25 }
@@ -26,7 +27,7 @@ class PluginIssoTest extends \PHPUnit\Framework\TestCase
26 /** 27 /**
27 * Test Isso init without errors. 28 * Test Isso init without errors.
28 */ 29 */
29 public function testIssoInitNoError() 30 public function testIssoInitNoError(): void
30 { 31 {
31 $conf = new ConfigManager(''); 32 $conf = new ConfigManager('');
32 $conf->set('plugins.ISSO_SERVER', 'value'); 33 $conf->set('plugins.ISSO_SERVER', 'value');
@@ -37,7 +38,7 @@ class PluginIssoTest extends \PHPUnit\Framework\TestCase
37 /** 38 /**
38 * Test Isso init with errors. 39 * Test Isso init with errors.
39 */ 40 */
40 public function testIssoInitError() 41 public function testIssoInitError(): void
41 { 42 {
42 $conf = new ConfigManager(''); 43 $conf = new ConfigManager('');
43 $errors = isso_init($conf); 44 $errors = isso_init($conf);
@@ -47,7 +48,7 @@ class PluginIssoTest extends \PHPUnit\Framework\TestCase
47 /** 48 /**
48 * Test render_linklist hook with valid settings to display the comment form. 49 * Test render_linklist hook with valid settings to display the comment form.
49 */ 50 */
50 public function testIssoDisplayed() 51 public function testIssoDisplayed(): void
51 { 52 {
52 $conf = new ConfigManager(''); 53 $conf = new ConfigManager('');
53 $conf->set('plugins.ISSO_SERVER', 'value'); 54 $conf->set('plugins.ISSO_SERVER', 'value');
@@ -87,7 +88,7 @@ class PluginIssoTest extends \PHPUnit\Framework\TestCase
87 /** 88 /**
88 * Test isso plugin when multiple bookmarks are displayed (shouldn't be displayed). 89 * Test isso plugin when multiple bookmarks are displayed (shouldn't be displayed).
89 */ 90 */
90 public function testIssoMultipleLinks() 91 public function testIssoMultipleLinks(): void
91 { 92 {
92 $conf = new ConfigManager(''); 93 $conf = new ConfigManager('');
93 $conf->set('plugins.ISSO_SERVER', 'value'); 94 $conf->set('plugins.ISSO_SERVER', 'value');
@@ -115,14 +116,14 @@ class PluginIssoTest extends \PHPUnit\Framework\TestCase
115 116
116 $processed = hook_isso_render_linklist($data, $conf); 117 $processed = hook_isso_render_linklist($data, $conf);
117 // link_plugin should be added for the icon 118 // link_plugin should be added for the icon
118 $this->assertContains('<a href="?'. $short1 .'#isso-thread">', $processed['links'][0]['link_plugin'][0]); 119 $this->assertContains('<a href="/shaare/'. $short1 .'#isso-thread">', $processed['links'][0]['link_plugin'][0]);
119 $this->assertContains('<a href="?'. $short2 .'#isso-thread">', $processed['links'][1]['link_plugin'][0]); 120 $this->assertContains('<a href="/shaare/'. $short2 .'#isso-thread">', $processed['links'][1]['link_plugin'][0]);
120 } 121 }
121 122
122 /** 123 /**
123 * Test isso plugin when using search (shouldn't be displayed). 124 * Test isso plugin when using search (shouldn't be displayed).
124 */ 125 */
125 public function testIssoNotDisplayedWhenSearch() 126 public function testIssoNotDisplayedWhenSearch(): void
126 { 127 {
127 $conf = new ConfigManager(''); 128 $conf = new ConfigManager('');
128 $conf->set('plugins.ISSO_SERVER', 'value'); 129 $conf->set('plugins.ISSO_SERVER', 'value');
@@ -145,13 +146,13 @@ class PluginIssoTest extends \PHPUnit\Framework\TestCase
145 $processed = hook_isso_render_linklist($data, $conf); 146 $processed = hook_isso_render_linklist($data, $conf);
146 147
147 // link_plugin should be added for the icon 148 // link_plugin should be added for the icon
148 $this->assertContains('<a href="?'. $short1 .'#isso-thread">', $processed['links'][0]['link_plugin'][0]); 149 $this->assertContains('<a href="/shaare/'. $short1 .'#isso-thread">', $processed['links'][0]['link_plugin'][0]);
149 } 150 }
150 151
151 /** 152 /**
152 * Test isso plugin without server configuration (shouldn't be displayed). 153 * Test isso plugin without server configuration (shouldn't be displayed).
153 */ 154 */
154 public function testIssoWithoutConf() 155 public function testIssoWithoutConf(): void
155 { 156 {
156 $data = 'abc'; 157 $data = 'abc';
157 $conf = new ConfigManager(''); 158 $conf = new ConfigManager('');
diff --git a/tpl/vintage/linklist.paging.html b/tpl/vintage/linklist.paging.html
index b9396df6..79daf16c 100644
--- a/tpl/vintage/linklist.paging.html
+++ b/tpl/vintage/linklist.paging.html
@@ -32,6 +32,6 @@
32 </form> 32 </form>
33 </div> 33 </div>
34 {if="$previous_page_url"} <a href="{$previous_page_url}" class="paging_older">&#x25C4;Older</a> {/if} 34 {if="$previous_page_url"} <a href="{$previous_page_url}" class="paging_older">&#x25C4;Older</a> {/if}
35 <div class="paging_current">page {$page_current} / {$page_max} </div> 35 {if="$page_max>1"}<div class="paging_current">page {$page_current} / {$page_max} </div>{/if}
36 {if="$next_page_url"} <a href="{$next_page_url}" class="paging_newer">Newer&#x25BA;</a> {/if} 36 {if="$next_page_url"} <a href="{$next_page_url}" class="paging_newer">Newer&#x25BA;</a> {/if}
37</div> 37</div>