Skip to content

Commit

Permalink
Insert relative media references when applicable
Browse files Browse the repository at this point in the history
  • Loading branch information
annda committed Oct 21, 2024
1 parent c37d932 commit 5801f51
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 1 deletion.
37 changes: 37 additions & 0 deletions _test/FileTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace dokuwiki\plugin\imgpaste\test;

use DokuWikiTest;

/**
* tests for the imgpaste plugin
*
* @group plugin_imgpaste
* @group plugins
*/
class FileTest extends DokuWikiTest
{

public function provideIds()
{
return [
'no shared ns - absolute / no transformation' => [ 'foo:bar', 'pasted:11223333-4455.png', 'pasted:11223333-4455.png'],
'same top ns - relative' => [ 'foo:bar', 'foo:pasted:20241008-181825.png', '.:pasted:20241008-181825.png'],
'one ns up' => ['foo:v1:bar', 'foo:pasted:11223333-4455.png', '..:pasted:11223333-4455.png'],
'two ns up' => ['foo:bar:v1:baz', 'foo:pasted:11223333-4455.png', '..:..:pasted:11223333-4455.png'],
'page with ns, media ref in root - absolute' => ['a:b', 'c', ':c'],
];
}

/**
* @dataProvider provideIds
* @param string $page
* @param string $media
* @param string $expected
*/
public function testResolveID(string $page, string $media, string $expected)
{
$this->assertSame($expected, \helper_plugin_imgpaste::createRelativeID($page, $media));
}
}
84 changes: 84 additions & 0 deletions _test/GeneralTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

namespace dokuwiki\plugin\imgpaste\test;

use DokuWikiTest;

/**
* General tests for the imgpaste plugin
*
* @group plugin_imgpaste
* @group plugins
*/
class GeneralTest extends DokuWikiTest
{
/**
* Simple test to make sure the plugin.info.txt is in correct format
*/
public function testPluginInfo(): void
{
$file = __DIR__ . '/../plugin.info.txt';
$this->assertFileExists($file);

$info = confToHash($file);

$this->assertArrayHasKey('base', $info);
$this->assertArrayHasKey('author', $info);
$this->assertArrayHasKey('email', $info);
$this->assertArrayHasKey('date', $info);
$this->assertArrayHasKey('name', $info);
$this->assertArrayHasKey('desc', $info);
$this->assertArrayHasKey('url', $info);

$this->assertEquals('imgpaste', $info['base']);
$this->assertRegExp('/^https?:\/\//', $info['url']);
$this->assertTrue(mail_isvalid($info['email']));
$this->assertRegExp('/^\d\d\d\d-\d\d-\d\d$/', $info['date']);
$this->assertTrue(false !== strtotime($info['date']));
}

/**
* Test to ensure that every conf['...'] entry in conf/default.php has a corresponding meta['...'] entry in
* conf/metadata.php.
*/
public function testPluginConf(): void
{
$conf_file = __DIR__ . '/../conf/default.php';
$meta_file = __DIR__ . '/../conf/metadata.php';

if (!file_exists($conf_file) && !file_exists($meta_file)) {
self::markTestSkipped('No config files exist -> skipping test');
}

if (file_exists($conf_file)) {
include($conf_file);
}
if (file_exists($meta_file)) {
include($meta_file);
}

$this->assertEquals(
gettype($conf),
gettype($meta),
'Both ' . DOKU_PLUGIN . 'imgpaste/conf/default.php and ' . DOKU_PLUGIN . 'imgpaste/conf/metadata.php have to exist and contain the same keys.'
);

if ($conf !== null && $meta !== null) {
foreach ($conf as $key => $value) {
$this->assertArrayHasKey(
$key,
$meta,
'Key $meta[\'' . $key . '\'] missing in ' . DOKU_PLUGIN . 'imgpaste/conf/metadata.php'
);
}

foreach ($meta as $key => $value) {
$this->assertArrayHasKey(
$key,
$conf,
'Key $conf[\'' . $key . '\'] missing in ' . DOKU_PLUGIN . 'imgpaste/conf/default.php'
);
}
}
}
}
2 changes: 1 addition & 1 deletion action.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function handleAjaxUpload(Doku_Event $event)
header('Content-Type: application/json');
echo json_encode([
'message' => $lang['uploadsucc'],
'id' => $result,
'id' => \helper_plugin_imgpaste::createRelativeId($INPUT->post->str('id'), $result),
'mime' => $type,
'ext' => $mimetypes[$type],
'url' => ml($result),
Expand Down
74 changes: 74 additions & 0 deletions helper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

use dokuwiki\Extension\Plugin;

/**
* DokuWiki Plugin imgpaste (Helper Component)
*
* @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
* @author Andreas Gohr, Anna Dabrowska <[email protected]>
*/
class helper_plugin_imgpaste extends Plugin
{
/**
* Create a relative ID from a given reference ID and a full ID to link to
*
* PHP rewrite of the original Javascript written by Andreas Gohr
* in /lib/scripts/linkwiz.js
*
* Both IDs are expected to be clean, e.g., the result of a clean ID function.
* No relative paths, leading colons, or similar things are allowed. As long as
* pages have a common prefix, a relative link is constructed.
*
* @param string $ref The ID of a page the link is used on
* @param string $id The ID to link to
* @return string The relative ID
*/
public static function createRelativeID($ref, $id) {
// Split the reference and target IDs into namespaces
$sourceNs = explode(':', $ref);
array_pop($sourceNs); // Remove the page part, keep only the namespace
$targetNs = explode(':', $id);
$targetPage = array_pop($targetNs); // Remove the page part of the target ID
$relativeID = [];

// Find the common prefix length
$commonPrefixLength = 0;
while ($commonPrefixLength < count($sourceNs) &&
$commonPrefixLength < count($targetNs) &&
$sourceNs[$commonPrefixLength] === $targetNs[$commonPrefixLength]) {
$commonPrefixLength++;
}

if (count($sourceNs) > 0) {
if ($commonPrefixLength > 0) {
if ($commonPrefixLength === count($sourceNs) && $commonPrefixLength === count($targetNs)) {
// Both pages are in the same namespace
} elseif ($commonPrefixLength < count($sourceNs)) {
// Add '..' for each missing namespace from common to the target
$relativeID = array_merge(
$relativeID,
array_fill(0, count($sourceNs) - $commonPrefixLength, '..')
);
} else {
// Target is below common prefix, add '.'
$relativeID[] = '.';
}
} elseif (count($targetNs) === 0) {
// Target is in the root namespace, but source is not, make it absolute
$relativeID[] = '';
}

// Add any remaining parts of the target namespace
$relativeID = array_merge($relativeID, array_slice($targetNs, $commonPrefixLength));
} else {
// Source is in the root namespace, just use target as is
$relativeID = $targetNs;
}

// Add the target page to the relative ID
$relativeID[] = $targetPage;

return implode(':', $relativeID);
}
}

0 comments on commit 5801f51

Please sign in to comment.