diff --git a/action.php b/action.php
--- a/action.php
+++ b/action.php
@@ -1,76 +1,94 @@
*/
if(!defined('DOKU_INC')) die();
class action_plugin_linksenhanced extends DokuWiki_Action_Plugin {
function register(Doku_Event_Handler $controller) {
$controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call_unknown');
$controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'add_jsinfo_information');
+ $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handle_parser_cache_use');
}
/**
* Add the language variable to the JSINFO variable
*/
function add_jsinfo_information(Doku_Event $event, $param) {
global $JSINFO;
$JSINFO['plugin']['linksenhanced']['sectok'] = getSecurityToken();
}
function handle_ajax_call_unknown(&$event, $param) {
if($event->data != 'plugin_linksenhanced') return;
$event->preventDefault();
$event->stopPropagation();
global $INPUT;
$action = trim($INPUT->post->str('action'));
$url = trim($INPUT->post->str('url'));
if(!checkSecurityToken())
{
echo "CSRF Attack.";
return;
}
$data = array();
$data['result'] = false;
if($action === 'check')
{
$client = new DokuHTTPClient();
$client->sendRequest($url);
$httpcode = $client->status;
$data['error'] = $client->error;
$data['httpcode'] = $httpcode;
if($httpcode>=200 && $httpcode<300)
$data['result'] = true;
}
else
{
echo "Unknown operation.";
return;
}
// If we are still here, JSON output is requested
//json library of DokuWiki
require_once DOKU_INC . 'inc/JSON.php';
$json = new JSON();
//set content type
header('Content-Type: application/json');
echo $json->encode($data);
}
+
+ function handle_parser_cache_use(&$event, $param) {
+ global $ID;
+ $cache = &$event->data;
+ if(!isset($cache->page)) return;
+
+ $leMeta = p_get_metadata($ID, 'plugin_linksenhanced');
+ if(!$leMeta)
+ return;
+
+ if(isset($leMeta['nocache']) && $leMeta['nocache'] === true)
+ {
+ $event->preventDefault();
+ $event->stopPropagation();
+ $event->result = false;
+ }
+ }
}
diff --git a/plugin.info.txt b/plugin.info.txt
--- a/plugin.info.txt
+++ b/plugin.info.txt
@@ -1,7 +1,7 @@
base linksenhanced
author Andreas Boehler
email dev@aboehler.at
-date 2019-01-25
+date 2019-05-28
name linksenhanced plugin
desc Enhanced Link Syntax
url http://www.aboehler.at
diff --git a/syntax.php b/syntax.php
deleted file mode 100644
--- a/syntax.php
+++ /dev/null
@@ -1,434 +0,0 @@
- FontAwesome Code]]
- * [[render^http://www.dokuwiki.org|//Formatted Output, probably within a paragraph//]]
- *
- * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
- * @author Andreas Böhler
', '', $link[1]));
- }
- if($link[1] === '')
- $link[1] = null;
- }
- else if ( isset($link[1]) && preg_match('/^\{\{[^\}]+\}\}$/',$link[1]) ) {
- // If the title is an image, convert it to an array containing the image details
- $link[1] = Doku_Handler_Parse_Media($link[1]);
- }
- else if(!isset($link[1]))
- {
- $link[1] = null;
- }
-
- $link[0] = trim($link[0]);
-
- //decide which kind of link it is
-
- if ( preg_match('/^[a-zA-Z0-9\.]+>{1}.*$/u',$link[0]) ) {
- $type = 'interwiki';
- }elseif ( preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u',$link[0]) ) {
- $type = 'windowsshare';
- }elseif ( preg_match('#^([a-z0-9\-\.+]+?)://#i',$link[0]) ) {
- $type = 'external';
- }elseif ( preg_match('<'.PREG_PATTERN_VALID_EMAIL.'>',$link[0]) ) {
- $type = 'email';
- }elseif ( preg_match('!^#.+!',$link[0]) ){
- $type = 'local';
- $link[0] = substr($link[0],1);
- }else{
- $type = 'internal';
- }
-
- return array($type, $link, $options);
- }
-
- /**
- * Create output. This is largely based on the internal linking mechanism.
- */
- function render($mode, Doku_Renderer $renderer, $data) {
- if (empty($data)) return false;
- global $conf;
- global $ID;
- global $INFO;
- global $lang;
-
- list($type, $link, $options) = $data;
-
- $url = $link[0];
- $name = $link[1];
-
- if($mode == 'metadata')
- {
- if($type == 'external')
- {
- $schemes = getSchemes();
- list($scheme) = explode('://',$url);
- $scheme = strtolower($scheme);
- if(!in_array($scheme,$schemes)) $url = '';
-
- // is there still an URL?
- if(!$url){
- return true;
- }
-
- $renderer->meta['plugin_linksenhanced']['links'][] = $url;
- }
- return true;
- }
-
- if($mode == 'xhtml') {
- switch($type)
- {
- case 'interwiki':
- $interwiki = explode('>',$link[0],2);
- $wikiName = strtolower($interwiki[0]);
- $wikiUri = $interwiki[1];
- $link = array();
- $link['target'] = $conf['target']['interwiki'];
- $link['pre'] = '';
- $link['suf'] = '';
- $link['more'] = '';
- if($name === null || !$options['render'])
- $link['name'] = $renderer->_getLinkTitle($name, $wikiUri, $isImage);
- else
- $link['name'] = $name;
-
- //get interwiki URL
- $exists = null;
- $url = $renderer->_resolveInterWiki($wikiName, $wikiUri, $exists);
-
- if(!$isImage) {
- $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $wikiName);
- $link['class'] = "interwiki iw_$class";
- } else {
- $link['class'] = 'media';
- }
-
- //do we stay at the same server? Use local target
- if(strpos($url, DOKU_URL) === 0 OR strpos($url, DOKU_BASE) === 0) {
- $link['target'] = $conf['target']['wiki'];
- }
-
- if($options['target'] !== false)
- $link['target'] = $options['target'];
-
- if($exists !== null && !$isImage) {
- if($exists) {
- $link['class'] .= ' wikilink1';
- } else {
- $link['class'] .= ' wikilink2';
- $link['rel'] = 'nofollow';
- }
- }
- if($options['class'] !== false)
- $link['class'] = $options['class'];
-
- $link['url'] = $url;
- $link['title'] = htmlspecialchars($link['url']);
-
- //output formatted
- $renderer->doc .= $renderer->_formatLink($link);
- break;
- case 'windowsshare':
- //simple setup
- $link['target'] = $conf['target']['windows'];
- $link['pre'] = '';
- $link['suf'] = '';
- $link['style'] = '';
-
- if($options['target'] !== false)
- $link['target'] = $options['target'];
-
- if($name === null || !$options['render'])
- $link['name'] = $renderer->_getLinkTitle($name, $url, $isImage);
- else
- $link['name'] = $name;
- if ( !$isImage ) {
- $link['class'] = 'windows';
- } else {
- $link['class'] = 'media';
- }
-
- if($options['class'] !== false)
- $link['class'] = $options['class'];
-
- $link['title'] = $renderer->_xmlEntities($url);
- $url = str_replace('\\','/',$url);
- $url = 'file:///'.$url;
- $link['url'] = $url;
-
- //output formatted
- $renderer->doc .= $renderer->_formatLink($link);
- break;
- case 'external':
- if($name === null || !$options['render'])
- $name = $renderer->_getLinkTitle($name, $url, $isImage);
-
- // url might be an attack vector, only allow registered protocols
- $schemes = getSchemes();
- list($scheme) = explode('://',$url);
- $scheme = strtolower($scheme);
- if(!in_array($scheme,$schemes)) $url = '';
-
- // is there still an URL?
- if(!$url){
- $renderer->doc .= $name;
- return;
- }
-
- // set class
- if ( !$isImage ) {
- $class='urlextern';
- } else {
- $class='media';
- }
-
- if($options['class'] !== false)
- $class = $options['class'];
-
- //prepare for formating
- $link['target'] = $conf['target']['extern'];
- $link['style'] = '';
- $link['pre'] = '';
- $link['suf'] = '';
- $link['more'] = '';
- $link['class'] = $class;
- $link['url'] = $url;
-
- if($options['target'] !== false)
- $link['target'] = $options['target'];
-
- if($options['check'] !== false)
- {
- $link['class'] = 'plugin_linksenhanced_pending';
- }
- $link['name'] = $name;
- $link['title'] = $renderer->_xmlEntities($url);
- if($conf['relnofollow']) $link['more'] .= ' rel="nofollow"';
-
- //output formatted
- $renderer->doc .= $renderer->_formatLink($link);
- break;
- case 'email':
- $link = array();
- $link['target'] = '';
- $link['pre'] = '';
- $link['suf'] = '';
- $link['style'] = '';
- $link['more'] = '';
-
- if($name === null || !$options['render'])
- $name = $renderer->_getLinkTitle($name, '', $isImage);
- if ( !$isImage ) {
- $link['class']='mail';
- } else {
- $link['class']='media';
- }
-
- if($options['class'] !== false)
- $link['class'] = $options['class'];
-
- $url = $renderer->_xmlEntities($url);
- $url = obfuscate($url);
- $title = $url;
-
- if(empty($name)){
- $name = $url;
- }
-
- if($conf['mailguard'] == 'visible') $url = rawurlencode($url);
-
- $link['url'] = 'mailto:'.$url;
- $link['name'] = $name;
- $link['title'] = $title;
-
- //output formatted
- $renderer->doc .= $renderer->_formatLink($link);
- break;
- case 'local':
- if($name === null || !$options['render'])
- $name = $renderer->_getLinkTitle($name, $url, $isImage);
- $url = $renderer->_headerToLink($url);
- $title = $ID.' ↵';
- if($options['class'] !== false)
- $class = $options['class'];
- else
- $class = "wikilink1";
- $renderer->doc .= '';
- $renderer->doc .= $name;
- $renderer->doc .= '';
- break;
- case 'internal':
- $id = $url;
- $params = '';
- $linktype = 'content';
- $parts = explode('?', $id, 2);
- if (count($parts) === 2) {
- $id = $parts[0];
- $params = $parts[1];
- }
-
- // For empty $id we need to know the current $ID
- // We need this check because _simpleTitle needs
- // correct $id and resolve_pageid() use cleanID($id)
- // (some things could be lost)
- if ($id === '') {
- $id = $ID;
- }
-
- // default name is based on $id as given
- $default = $renderer->_simpleTitle($id);
-
- // now first resolve and clean up the $id
- resolve_pageid(getNS($ID),$id,$exists);
-
- if($name === null || !$options['render'])
- $name = $renderer->_getLinkTitle($name, $default, $isImage, $id, $linktype);
- if ( !$isImage ) {
- if ( $exists ) {
- $class='wikilink1';
- } else {
- $class='wikilink2';
- $link['rel']='nofollow';
- }
- } else {
- $class='media';
- }
-
- if($options['class'] !== false)
- $class = $options['class'];
-
- //keep hash anchor
- @list($id,$hash) = explode('#',$id,2);
- if(!empty($hash)) $hash = $renderer->_headerToLink($hash);
-
- //prepare for formating
- $link['target'] = $conf['target']['wiki'];
- $link['style'] = '';
- $link['pre'] = '';
- $link['suf'] = '';
- // highlight link to current page
- if ($id == $INFO['id']) {
- $link['pre'] = '';
- $link['suf'] = '';
- }
- $link['more'] = '';
- $link['class'] = $class;
- $link['url'] = wl($id, $params);
- $link['name'] = $name;
- $link['title'] = $id;
-
- if($options['target'] !== false)
- $link['target'] = $options['target'];
- //add search string
- if($search){
- ($conf['userewrite']) ? $link['url'].='?' : $link['url'].='&';
- if(is_array($search)){
- $search = array_map('rawurlencode',$search);
- $link['url'] .= 's[]='.join('&s[]=',$search);
- }else{
- $link['url'] .= 's='.rawurlencode($search);
- }
- }
-
- //keep hash
- if($hash) $link['url'].='#'.$hash;
-
- //output formatted
- if($returnonly){
- return $renderer->_formatLink($link);
- }else{
- $renderer->doc .= $renderer->_formatLink($link);
- }
- break;
- }
- }
- return false;
- }
-}
diff --git a/syntax/link.php b/syntax/link.php
new file mode 100644
--- /dev/null
+++ b/syntax/link.php
@@ -0,0 +1,438 @@
+ FontAwesome Code]]
+ * [[render^http://www.dokuwiki.org|//Formatted Output, probably within a paragraph//]]
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Böhler
', '', $link[1]));
+ }
+ if($link[1] === '')
+ $link[1] = null;
+ }
+ else if ( isset($link[1]) && preg_match('/^\{\{[^\}]+\}\}$/',$link[1]) ) {
+ // If the title is an image, convert it to an array containing the image details
+ $link[1] = Doku_Handler_Parse_Media($link[1]);
+ }
+ else if(!isset($link[1]))
+ {
+ $link[1] = null;
+ }
+
+ $link[0] = trim($link[0]);
+
+ //decide which kind of link it is
+
+ if ( preg_match('/^[a-zA-Z0-9\.]+>{1}.*$/u',$link[0]) ) {
+ $type = 'interwiki';
+ }elseif ( preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u',$link[0]) ) {
+ $type = 'windowsshare';
+ }elseif ( preg_match('#^([a-z0-9\-\.+]+?)://#i',$link[0]) ) {
+ $type = 'external';
+ }elseif ( preg_match('<'.PREG_PATTERN_VALID_EMAIL.'>',$link[0]) ) {
+ $type = 'email';
+ }elseif ( preg_match('!^#.+!',$link[0]) ){
+ $type = 'local';
+ $link[0] = substr($link[0],1);
+ }else{
+ $type = 'internal';
+ }
+
+ return array($type, $link, $options);
+ }
+
+ /**
+ * Create output. This is largely based on the internal linking mechanism.
+ */
+ function render($mode, Doku_Renderer $renderer, $data) {
+ if (empty($data)) return false;
+ global $conf;
+ global $ID;
+ global $INFO;
+ global $lang;
+
+ list($type, $link, $options) = $data;
+
+ $url = $link[0];
+ $name = $link[1];
+
+ if($mode == 'metadata')
+ {
+ if($type == 'external')
+ {
+ $schemes = getSchemes();
+ list($scheme) = explode('://',$url);
+ $scheme = strtolower($scheme);
+ if(!in_array($scheme,$schemes)) $url = '';
+
+ // is there still an URL?
+ if(!$url){
+ return true;
+ }
+
+ $renderer->meta['plugin_linksenhanced']['links'][] = $url;
+ }
+ return true;
+ }
+
+ if($mode == 'xhtml') {
+ switch($type)
+ {
+ case 'interwiki':
+ $interwiki = explode('>',$link[0],2);
+ $wikiName = strtolower($interwiki[0]);
+ $wikiUri = $interwiki[1];
+ $link = array();
+ $link['target'] = $conf['target']['interwiki'];
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['more'] = '';
+ if($name === null || !$options['render'])
+ $link['name'] = $renderer->_getLinkTitle($name, $wikiUri, $isImage);
+ else
+ $link['name'] = $name;
+
+ //get interwiki URL
+ $exists = null;
+ $url = $renderer->_resolveInterWiki($wikiName, $wikiUri, $exists);
+
+ if(!$isImage) {
+ $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $wikiName);
+ $link['class'] = "interwiki iw_$class";
+ } else {
+ $link['class'] = 'media';
+ }
+
+ //do we stay at the same server? Use local target
+ if(strpos($url, DOKU_URL) === 0 OR strpos($url, DOKU_BASE) === 0) {
+ $link['target'] = $conf['target']['wiki'];
+ }
+
+ if($options['target'] !== false)
+ $link['target'] = $options['target'];
+
+ if($exists !== null && !$isImage) {
+ if($exists) {
+ $link['class'] .= ' wikilink1';
+ } else {
+ $link['class'] .= ' wikilink2';
+ $link['rel'] = 'nofollow';
+ }
+ }
+ if($options['class'] !== false)
+ $link['class'] = $options['class'];
+
+ $link['url'] = $url;
+ $link['title'] = htmlspecialchars($link['url']);
+
+ //output formatted
+ $renderer->doc .= $renderer->_formatLink($link);
+ break;
+ case 'windowsshare':
+ //simple setup
+ $link['target'] = $conf['target']['windows'];
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['style'] = '';
+
+ if($options['target'] !== false)
+ $link['target'] = $options['target'];
+
+ if($name === null || !$options['render'])
+ $link['name'] = $renderer->_getLinkTitle($name, $url, $isImage);
+ else
+ $link['name'] = $name;
+ if ( !$isImage ) {
+ $link['class'] = 'windows';
+ } else {
+ $link['class'] = 'media';
+ }
+
+ if($options['class'] !== false)
+ $link['class'] = $options['class'];
+
+ $link['title'] = $renderer->_xmlEntities($url);
+ $url = str_replace('\\','/',$url);
+ $url = 'file:///'.$url;
+ $link['url'] = $url;
+
+ //output formatted
+ $renderer->doc .= $renderer->_formatLink($link);
+ break;
+ case 'external':
+ if($name === null || !$options['render'])
+ $name = $renderer->_getLinkTitle($name, $url, $isImage);
+
+ // url might be an attack vector, only allow registered protocols
+ $schemes = getSchemes();
+ list($scheme) = explode('://',$url);
+ $scheme = strtolower($scheme);
+ if(!in_array($scheme,$schemes)) $url = '';
+
+ // is there still an URL?
+ if(!$url){
+ $renderer->doc .= $name;
+ return;
+ }
+
+ // set class
+ if ( !$isImage ) {
+ $class='urlextern';
+ } else {
+ $class='media';
+ }
+
+ if($options['class'] !== false)
+ $class = $options['class'];
+
+ //prepare for formating
+ $link['target'] = $conf['target']['extern'];
+ $link['style'] = '';
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['more'] = '';
+ $link['class'] = $class;
+ $link['url'] = $url;
+
+ if($options['target'] !== false)
+ $link['target'] = $options['target'];
+
+ if($options['check'] !== false)
+ {
+ $link['class'] = 'plugin_linksenhanced_pending';
+ }
+ $link['name'] = $name;
+ $link['title'] = $renderer->_xmlEntities($url);
+ if($conf['relnofollow']) $link['more'] .= ' rel="nofollow"';
+
+ //output formatted
+ $renderer->doc .= $renderer->_formatLink($link);
+ break;
+ case 'email':
+ $link = array();
+ $link['target'] = '';
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['style'] = '';
+ $link['more'] = '';
+
+ if($name === null || !$options['render'])
+ $name = $renderer->_getLinkTitle($name, '', $isImage);
+ if ( !$isImage ) {
+ $link['class']='mail';
+ } else {
+ $link['class']='media';
+ }
+
+ if($options['class'] !== false)
+ $link['class'] = $options['class'];
+
+ $url = $renderer->_xmlEntities($url);
+ $url = obfuscate($url);
+ $title = $url;
+
+ if(empty($name)){
+ $name = $url;
+ }
+
+ if($conf['mailguard'] == 'visible') $url = rawurlencode($url);
+
+ $link['url'] = 'mailto:'.$url;
+ $link['name'] = $name;
+ $link['title'] = $title;
+
+ //output formatted
+ $renderer->doc .= $renderer->_formatLink($link);
+ break;
+ case 'local':
+ if($name === null || !$options['render'])
+ $name = $renderer->_getLinkTitle($name, $url, $isImage);
+ $url = $renderer->_headerToLink($url);
+ $title = $ID.' ↵';
+ if($options['class'] !== false)
+ $class = $options['class'];
+ else
+ $class = "wikilink1";
+ $renderer->doc .= '';
+ $renderer->doc .= $name;
+ $renderer->doc .= '';
+ break;
+ case 'internal':
+ $id = $url;
+ $params = '';
+ $linktype = 'content';
+ $parts = explode('?', $id, 2);
+ if (count($parts) === 2) {
+ $id = $parts[0];
+ $params = $parts[1];
+ }
+
+ // For empty $id we need to know the current $ID
+ // We need this check because _simpleTitle needs
+ // correct $id and resolve_pageid() use cleanID($id)
+ // (some things could be lost)
+ if ($id === '') {
+ $id = $ID;
+ }
+
+ // default name is based on $id as given
+ $default = $renderer->_simpleTitle($id);
+
+ // now first resolve and clean up the $id
+ resolve_pageid(getNS($ID),$id,$exists);
+
+ if($name === null || !$options['render'])
+ $name = $renderer->_getLinkTitle($name, $default, $isImage, $id, $linktype);
+ if ( !$isImage ) {
+ if ( $exists ) {
+ $class='wikilink1';
+ } else {
+ $class='wikilink2';
+ $link['rel']='nofollow';
+ }
+ } else {
+ $class='media';
+ }
+
+ if($options['class'] !== false)
+ $class = $options['class'];
+
+ //keep hash anchor
+ @list($id,$hash) = explode('#',$id,2);
+ if(!empty($hash)) $hash = $renderer->_headerToLink($hash);
+
+ //prepare for formating
+ $link['target'] = $conf['target']['wiki'];
+ $link['style'] = '';
+ $link['pre'] = '';
+ $link['suf'] = '';
+ // highlight link to current page
+ if ($id == $INFO['id']) {
+ $link['pre'] = '';
+ $link['suf'] = '';
+ }
+ $link['more'] = '';
+ $link['class'] = $class;
+ $link['url'] = wl($id, $params);
+ $link['name'] = $name;
+ $link['title'] = $id;
+
+ if($options['target'] !== false)
+ $link['target'] = $options['target'];
+ //add search string
+ if($search){
+ ($conf['userewrite']) ? $link['url'].='?' : $link['url'].='&';
+ if(is_array($search)){
+ $search = array_map('rawurlencode',$search);
+ $link['url'] .= 's[]='.join('&s[]=',$search);
+ }else{
+ $link['url'] .= 's='.rawurlencode($search);
+ }
+ }
+
+ //keep hash
+ if($hash) $link['url'].='#'.$hash;
+
+ //output formatted
+ if($returnonly){
+ return $renderer->_formatLink($link);
+ }else{
+ $renderer->doc .= $renderer->_formatLink($link);
+ }
+ break;
+ }
+ }
+ return false;
+ }
+}
diff --git a/syntax/table.php b/syntax/table.php
new file mode 100644
--- /dev/null
+++ b/syntax/table.php
@@ -0,0 +1,132 @@
+ FontAwesome Code]]
+ * [[render^http://www.dokuwiki.org|//Formatted Output, probably within a paragraph//]]
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Böhler Link Overview
';
+ echo '';
+ echo '
';
+ }
+}
';
+
+ foreach($data['links'] as $page => $links)
+ {
+ echo 'Page Link Status '.$page.' ';
+ $first = true;
+ foreach($links as $link)
+ {
+ if(!$first)
+ echo '';
+ else
+ $first = false;
+ echo ' ';
+ }
+ }
+ echo '';
+ echo ''.$link.' ';
+ echo '