Skip to content

Commit 5801f51

Browse files
committed
Insert relative media references when applicable
1 parent c37d932 commit 5801f51

File tree

4 files changed

+196
-1
lines changed

4 files changed

+196
-1
lines changed

_test/FileTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace dokuwiki\plugin\imgpaste\test;
4+
5+
use DokuWikiTest;
6+
7+
/**
8+
* tests for the imgpaste plugin
9+
*
10+
* @group plugin_imgpaste
11+
* @group plugins
12+
*/
13+
class FileTest extends DokuWikiTest
14+
{
15+
16+
public function provideIds()
17+
{
18+
return [
19+
'no shared ns - absolute / no transformation' => [ 'foo:bar', 'pasted:11223333-4455.png', 'pasted:11223333-4455.png'],
20+
'same top ns - relative' => [ 'foo:bar', 'foo:pasted:20241008-181825.png', '.:pasted:20241008-181825.png'],
21+
'one ns up' => ['foo:v1:bar', 'foo:pasted:11223333-4455.png', '..:pasted:11223333-4455.png'],
22+
'two ns up' => ['foo:bar:v1:baz', 'foo:pasted:11223333-4455.png', '..:..:pasted:11223333-4455.png'],
23+
'page with ns, media ref in root - absolute' => ['a:b', 'c', ':c'],
24+
];
25+
}
26+
27+
/**
28+
* @dataProvider provideIds
29+
* @param string $page
30+
* @param string $media
31+
* @param string $expected
32+
*/
33+
public function testResolveID(string $page, string $media, string $expected)
34+
{
35+
$this->assertSame($expected, \helper_plugin_imgpaste::createRelativeID($page, $media));
36+
}
37+
}

_test/GeneralTest.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace dokuwiki\plugin\imgpaste\test;
4+
5+
use DokuWikiTest;
6+
7+
/**
8+
* General tests for the imgpaste plugin
9+
*
10+
* @group plugin_imgpaste
11+
* @group plugins
12+
*/
13+
class GeneralTest extends DokuWikiTest
14+
{
15+
/**
16+
* Simple test to make sure the plugin.info.txt is in correct format
17+
*/
18+
public function testPluginInfo(): void
19+
{
20+
$file = __DIR__ . '/../plugin.info.txt';
21+
$this->assertFileExists($file);
22+
23+
$info = confToHash($file);
24+
25+
$this->assertArrayHasKey('base', $info);
26+
$this->assertArrayHasKey('author', $info);
27+
$this->assertArrayHasKey('email', $info);
28+
$this->assertArrayHasKey('date', $info);
29+
$this->assertArrayHasKey('name', $info);
30+
$this->assertArrayHasKey('desc', $info);
31+
$this->assertArrayHasKey('url', $info);
32+
33+
$this->assertEquals('imgpaste', $info['base']);
34+
$this->assertRegExp('/^https?:\/\//', $info['url']);
35+
$this->assertTrue(mail_isvalid($info['email']));
36+
$this->assertRegExp('/^\d\d\d\d-\d\d-\d\d$/', $info['date']);
37+
$this->assertTrue(false !== strtotime($info['date']));
38+
}
39+
40+
/**
41+
* Test to ensure that every conf['...'] entry in conf/default.php has a corresponding meta['...'] entry in
42+
* conf/metadata.php.
43+
*/
44+
public function testPluginConf(): void
45+
{
46+
$conf_file = __DIR__ . '/../conf/default.php';
47+
$meta_file = __DIR__ . '/../conf/metadata.php';
48+
49+
if (!file_exists($conf_file) && !file_exists($meta_file)) {
50+
self::markTestSkipped('No config files exist -> skipping test');
51+
}
52+
53+
if (file_exists($conf_file)) {
54+
include($conf_file);
55+
}
56+
if (file_exists($meta_file)) {
57+
include($meta_file);
58+
}
59+
60+
$this->assertEquals(
61+
gettype($conf),
62+
gettype($meta),
63+
'Both ' . DOKU_PLUGIN . 'imgpaste/conf/default.php and ' . DOKU_PLUGIN . 'imgpaste/conf/metadata.php have to exist and contain the same keys.'
64+
);
65+
66+
if ($conf !== null && $meta !== null) {
67+
foreach ($conf as $key => $value) {
68+
$this->assertArrayHasKey(
69+
$key,
70+
$meta,
71+
'Key $meta[\'' . $key . '\'] missing in ' . DOKU_PLUGIN . 'imgpaste/conf/metadata.php'
72+
);
73+
}
74+
75+
foreach ($meta as $key => $value) {
76+
$this->assertArrayHasKey(
77+
$key,
78+
$conf,
79+
'Key $conf[\'' . $key . '\'] missing in ' . DOKU_PLUGIN . 'imgpaste/conf/default.php'
80+
);
81+
}
82+
}
83+
}
84+
}

action.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public function handleAjaxUpload(Doku_Event $event)
7878
header('Content-Type: application/json');
7979
echo json_encode([
8080
'message' => $lang['uploadsucc'],
81-
'id' => $result,
81+
'id' => \helper_plugin_imgpaste::createRelativeId($INPUT->post->str('id'), $result),
8282
'mime' => $type,
8383
'ext' => $mimetypes[$type],
8484
'url' => ml($result),

helper.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
use dokuwiki\Extension\Plugin;
4+
5+
/**
6+
* DokuWiki Plugin imgpaste (Helper Component)
7+
*
8+
* @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
9+
* @author Andreas Gohr, Anna Dabrowska <[email protected]>
10+
*/
11+
class helper_plugin_imgpaste extends Plugin
12+
{
13+
/**
14+
* Create a relative ID from a given reference ID and a full ID to link to
15+
*
16+
* PHP rewrite of the original Javascript written by Andreas Gohr
17+
* in /lib/scripts/linkwiz.js
18+
*
19+
* Both IDs are expected to be clean, e.g., the result of a clean ID function.
20+
* No relative paths, leading colons, or similar things are allowed. As long as
21+
* pages have a common prefix, a relative link is constructed.
22+
*
23+
* @param string $ref The ID of a page the link is used on
24+
* @param string $id The ID to link to
25+
* @return string The relative ID
26+
*/
27+
public static function createRelativeID($ref, $id) {
28+
// Split the reference and target IDs into namespaces
29+
$sourceNs = explode(':', $ref);
30+
array_pop($sourceNs); // Remove the page part, keep only the namespace
31+
$targetNs = explode(':', $id);
32+
$targetPage = array_pop($targetNs); // Remove the page part of the target ID
33+
$relativeID = [];
34+
35+
// Find the common prefix length
36+
$commonPrefixLength = 0;
37+
while ($commonPrefixLength < count($sourceNs) &&
38+
$commonPrefixLength < count($targetNs) &&
39+
$sourceNs[$commonPrefixLength] === $targetNs[$commonPrefixLength]) {
40+
$commonPrefixLength++;
41+
}
42+
43+
if (count($sourceNs) > 0) {
44+
if ($commonPrefixLength > 0) {
45+
if ($commonPrefixLength === count($sourceNs) && $commonPrefixLength === count($targetNs)) {
46+
// Both pages are in the same namespace
47+
} elseif ($commonPrefixLength < count($sourceNs)) {
48+
// Add '..' for each missing namespace from common to the target
49+
$relativeID = array_merge(
50+
$relativeID,
51+
array_fill(0, count($sourceNs) - $commonPrefixLength, '..')
52+
);
53+
} else {
54+
// Target is below common prefix, add '.'
55+
$relativeID[] = '.';
56+
}
57+
} elseif (count($targetNs) === 0) {
58+
// Target is in the root namespace, but source is not, make it absolute
59+
$relativeID[] = '';
60+
}
61+
62+
// Add any remaining parts of the target namespace
63+
$relativeID = array_merge($relativeID, array_slice($targetNs, $commonPrefixLength));
64+
} else {
65+
// Source is in the root namespace, just use target as is
66+
$relativeID = $targetNs;
67+
}
68+
69+
// Add the target page to the relative ID
70+
$relativeID[] = $targetPage;
71+
72+
return implode(':', $relativeID);
73+
}
74+
}

0 commit comments

Comments
 (0)