Skip to content

Commit

Permalink
- Chg: Migrated to 1.8 Richtext API
Browse files Browse the repository at this point in the history
- Chg: Changed HumHub min version to 1.8
  • Loading branch information
buddh4 committed Feb 4, 2021
1 parent 0fe2798 commit 2672d99
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 80 deletions.
9 changes: 7 additions & 2 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Changelog
=========

1.5.0 (February 4, 2021)
------------------------
- Chg: Migrated to 1.8 Richtext API
- Chg: Changed HumHub min version to 1.8

1.4.3 (February 2, 2021)
------------------------
- Enh #153: Confirm on leave unsaved form
Expand All @@ -15,8 +20,8 @@ Changelog
------------------------
- Fix #134: Wiki fixed menu cut if menu higher than window
- Fix: Double escaping of anchors
- Chng: Split js modules into multiple files
- Chng: Added grunt build
- Chg: Split js modules into multiple files
- Chg: Added grunt build
- Enh: Use of minified assets
- Fix: Search index update may throw error

Expand Down
4 changes: 2 additions & 2 deletions module.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"name": "Wiki",
"description": "Collect and share information with your very own Wiki.",
"keywords": ["wiki"],
"version": "1.4.3",
"version": "1.5.0",
"humhub": {
"minVersion": "1.7"
"minVersion": "1.8"
},
"homepage": "https://github.com/humhub/humhub-modules-wiki",
"authors": [
Expand Down
79 changes: 4 additions & 75 deletions widgets/WikiRichText.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,81 +13,10 @@ class WikiRichText extends ProsemirrorRichText
{
public $preset = 'wiki';

public function isCompatibilityMode()
public static function getExtensions()
{
return false;
$result = parent::getExtensions();
$result[] = new WikiRichTextLinkExtension();
return $result;
}

protected function parseOutput()
{
$output = parent::parseOutput();
// WikiLinks have to be parsed before internal links!
$output = $this->parseWikiLinks($output);
$output = $this->parseInternalLinks($output);
return $output;

}

public function parseInternalLinks($output) {
return preg_replace_callback(static::getLinkPattern(), function($match) {
$url = $match[2];

if(empty($url)) {
return $match[0];
}

if(strpos($url, "file-guid-") !== 0 && strpos($url, "file-guid:") !== 0 && $url[0] !== '.' && $url[0] !== '/' && strpos($url, ':') === false) {
$page = WikiPage::findOne(['title' => $match[2]]);
return $this->toWikiLink($match[1], $page);
}

if(!$this->edit) {
if (strpos($url, "file-guid-") === 0) {

$guid = str_replace('file-guid-', '', $url);
$file = File::findOne(['guid' => $guid]);
if ($file !== null) {
return '['.$match[1].']('.$file->getUrl([], true).')';
}
}
}

return $match[0];
}, $output);
}

protected static function getLinkPattern()
{
return '/(?<!\\\\)\[([^\]]*)\]\(([^\)\s]*)(?:\s")?([^\)"]*)?(?:")?\)/is';
}

public function parseWikiLinks($text)
{
// $match[0]: markdown, $match[1]: name, $match[2]: extension(wiki) $match[3]: wikiId
return static::replaceLinkExtension($text, 'wiki', function($match) {
return $this->toWikiLink($match[1], WikiPage::findOne(['id' => $match[3]]), null, $match[4]);
});
}

public function toWikiLink($label, $page, $title = null, $anchor = null)
{
if(!$page) {
// page not found format is [<label>](wiki:#)
return $this->toWikiLink($label, '#');
}

if($page instanceof WikiPage) {
// In edit mode we use wiki:<wikiId> format in rendered richtext we use actual wiki url
$url = $this->edit ? $page->id : Url::toWiki($page);

if($anchor) {
$url .= '#'. urlencode($anchor);
}

return $this->toWikiLink($label, $url, $page->title);
}

return '['.$label.'](wiki:'. $page.' "'.$title.'")';
}

}
123 changes: 123 additions & 0 deletions widgets/WikiRichTextLinkExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php


namespace humhub\modules\wiki\widgets;


use humhub\modules\content\widgets\richtext\extensions\link\LinkParserBlock;
use humhub\modules\content\widgets\richtext\extensions\link\RichTextLinkExtension;
use humhub\modules\content\widgets\richtext\extensions\link\RichTextLinkExtensionMatch;
use humhub\modules\content\widgets\richtext\ProsemirrorRichText;
use humhub\modules\file\models\File;
use humhub\modules\wiki\helpers\Url;
use humhub\modules\wiki\models\WikiPage;

/**
* Wiki link extension uses the following format:
*
* [<text>](wiki:label "url")
* $match[0]: markdown, $match[1]: name, $match[2]: extension(wiki) $match[3]: wikiId
*/
class WikiRichTextLinkExtension extends RichTextLinkExtension
{
public $key = 'wiki';

/**
* @inheritdoc
*/
public function onBeforeOutput(ProsemirrorRichText $richtext, string $output) : string
{
$output = $this->parseWikiLinks($richtext->edit, $output);
return $this->parseInternalLinks($richtext->edit, $output);
}

/**
* @inheritdoc
*/
public function parseWikiLinks(bool $isEdit, string $output)
{
return static::replace($output, function(RichTextLinkExtensionMatch $match) use($isEdit) {
return $this->toWikiLink($isEdit, $match->getText(), WikiPage::findOne(['id' => $match->getExtensionId()]), null, $match->getTitle());
});
}

/**
* Parses for legacy wiki links
* @param bool $isEdit
* @param string $output
* @return string
*/
private function parseInternalLinks(bool $isEdit, string $output)
{
return preg_replace_callback(static::getLinkPattern(), function($match) use($isEdit) {
$url = $match[2];

if(empty($url)) {
return $match[0];
}

if(strpos($url, "file-guid-") !== 0 && strpos($url, "file-guid:") !== 0 && $url[0] !== '.' && $url[0] !== '/' && strpos($url, ':') === false) {
$page = WikiPage::findOne(['title' => $match[2]]);
return $this->toWikiLink($isEdit, $match[1], $page);
}

if(!$isEdit) {
if (strpos($url, "file-guid-") === 0) {
$guid = str_replace('file-guid-', '', $url);
$file = File::findOne(['guid' => $guid]);
if ($file !== null) {
return '['.$match[1].']('.$file->getUrl([], true).')';
}
}
}

return $match[0];
}, $output);
}

/**
* @inheritdoc
*/
private static function getLinkPattern()
{
return '/(?<!\\\\)\[([^\]]*)\]\(([^\)\s]*)(?:\s")?([^\)"]*)?(?:")?\)/is';
}

private function toWikiLink($isEdit, $label, $page, $title = null, $anchor = null)
{
if(!$page) {
// page not found format is [<label>](wiki:#)
return $this->toWikiLink($isEdit, $label, '#');
}

if($page instanceof WikiPage) {
// In edit mode we use wiki:<wikiId> format in rendered richtext we use actual wiki url
$url = $isEdit ? $page->id : Url::toWiki($page);

if($anchor) {
$url .= '#'. urlencode($anchor);
}

return $this->toWikiLink($isEdit, $label, $url, $page->title);
}

return RichTextLinkExtension::buildLink($label,'wiki:'. $page, $title );
}

/**
* @inheritdoc
*/
public function onBeforeConvertLink(LinkParserBlock $linkBlock) : void
{
$wikiId = $this->cutExtensionKeyFromUrl($linkBlock->getUrl());

$page = WikiPage::findOne(['id' => $wikiId]);

if(!$page) {
$linkBlock->setResult('['.$linkBlock->getParsedText().']');
return;
}

$linkBlock->setUrl($page->getUrl());
}
}
3 changes: 2 additions & 1 deletion widgets/views/wallEntry.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<?php

use humhub\libs\Html;
use humhub\modules\wiki\assets\Assets;
use humhub\modules\wiki\helpers\Url;
use humhub\modules\wiki\widgets\WikiRichText;
use humhub\widgets\Button;
use humhub\widgets\Link;

/* @var $wiki \humhub\modules\wiki\models\WikiPage */

\humhub\modules\wiki\assets\Assets::register($this);
Assets::register($this);

$wikiUrl = Url::toWiki($wiki);

Expand Down

0 comments on commit 2672d99

Please sign in to comment.