cosmocode / edittable

Plugin to provide a custom editor for tables in DokuWiki
https://www.dokuwiki.org/plugin:edittable
32 stars 26 forks source link

hogfather: tableeditor ends in blank field when cell content shows URL #190

Closed bits-fritz closed 4 years ago

bits-fritz commented 4 years ago

After updating from Greebo to Hogfather klicking the "edit table" tab results in a blank field. Tables are untouched.

Reinstalling the plugin didn't help. Even removing /var/www/dokuwiki/lib/plugins/edittable and installing the pluging for new didn't do the trick.

System: debian stretch Server version: Apache/2.4.25 (Debian) PHP 7.0.33-0+deb9u6

dokuwiki-apache2-error.log

Update: It appears that "edittable" doesn't like cell content which shows an URL (or slash in general?)

editing works: | @ | : | [[https://www.dokuwiki.org/|Dokuwiki]] |

editing works not:

| @     | :     | [[https://www.dokuwiki.org/]]  |
| @     | :     | https://www.dokuwiki.org/      |
loganmarchione commented 4 years ago

Same issue, similar error (but on Nginx). Can edit tables, as long as they don't contain a URL.

Ubuntu 20.04 nginx/1.17.10 PHP 7.4.3

2020/06/13 11:09:09 [error] 4448#4448: *1 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Class 'Doku_Parser_Mode_externallink' not found in /var/www/dokuwiki/lib/plugins/edittable/renderer/inverse.php:422
Stack trace:
#0 /var/www/dokuwiki/lib/plugins/edittable/action/editor.php(74): renderer_plugin_edittable_inverse->externallink()
#1 /var/www/dokuwiki/inc/Extension/EventHandler.php(81): action_plugin_edittable_editor->editform()
#2 /var/www/dokuwiki/inc/Extension/Event.php(72): dokuwiki\Extension\EventHandler->process_event()
#3 /var/www/dokuwiki/inc/Extension/Event.php(128): dokuwiki\Extension\Event->advise_before()
#4 /var/www/dokuwiki/inc/Extension/Event.php(195): dokuwiki\Extension\Event->trigger()
#5 /var/www/dokuwiki/inc/html.php(1877): dokuwiki\Extension\Event::createAndTrigger()
#6 /var/www/dokuwiki/inc/Action/Edit.php(88): html_edit()
#7 /var/www/dokuwiki/inc/template.php(99): dokuwiki\Action\Edit->tplContent()
#8 [internal function]: tpl_content_core()
#9 /var/www/dokuwiki/inc/Extension/Event.php(129): call_user_func_array()
#1" while reading response header from upstream, client: 10.10.1.74, server: wiki.internal.my-domain.com, request: "POST /doku.php HTTP/2.0", upstream: "fastcgi://unix:/var/run/php/php7.4-fpm.sock:", host: "wiki.internal.my-domain.com", referrer: "https://wiki.internal.my-domain.com/doku.php?id=it:pc_revisions"
yguel commented 4 years ago

I confirm the bug here. Same system as bits-fritz.

hobgoblinsmaster commented 4 years ago

The class Doku_Parse_Mode_externallink does not exists anymore (it was renamed and namespaced: dokuwiki\Parsing\ParserMode\Externallink). The member patterns is also declared protected and cannot be use directly.

If this can help, this is a very dirty patch (I just copied the part filling patterns array from the original class):

--- inverse.php.old     2019-06-24 14:50:32.000000000 +0200
+++ inverse.php.new     2020-07-02 09:57:20.703708300 +0200
@@ -9,6 +9,7 @@
 if(!defined('DOKU_INC')) die();

 require_once DOKU_INC.'inc/parser/renderer.php';
+require_once DOKU_INC.'inc/confutils.php';

 class renderer_plugin_edittable_inverse extends Doku_Renderer {
     /** @var string will contain the whole document */
@@ -26,6 +27,7 @@
     private $_liststack = array();
     private $quotelvl = 0;
     private $_extlinkparser = null;
+    private $patterns = array();

     function getFormat() {
         return 'wiki';
@@ -418,13 +420,29 @@
          */
         if($name === null) {
             // get the patterns from the parser
-            if(is_null($this->_extlinkparser)) {
+            /*if(is_null($this->_extlinkparser)) {
                 $this->_extlinkparser = new Doku_Parser_Mode_externallink();
                 $this->_extlinkparser->preConnect();
             }

             // check if URL matches pattern
-            foreach($this->_extlinkparser->patterns as $pattern) {
+            foreach($this->_extlinkparser->patterns as $pattern) { */
+           if (count($this->patterns) == 0) {
+               $ltrs = '\w';
+        $gunk = '/\#~:.?+=&%@!\-\[\]';
+        $punc = '.:?\-;,';
+        $host = $ltrs.$punc;
+        $any  = $ltrs.$gunk.$punc;
+
+        $this->schemes = getSchemes();
+        foreach ($this->schemes as $scheme) {
+            $this->patterns[] = '\b(?i)'.$scheme.'(?-i)://['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
+        }
+
+        $this->patterns[] = '(?<=\s)(?i)www?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
+        $this->patterns[] = '(?<=\s)(?i)ftp?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
+               }
+            foreach($this->patterns as $pattern) {
                 if(preg_match("'$pattern'", " $url ")) {
                     $this->doc .= $url; // gotcha!
                     return;
annda commented 4 years ago

The error is caused by links without a title, like [[http://example.com]] or simply http://example.com

Unfortunately at this moment I don't see an easy solution except rolling back some of the changes introduced in 99bd0733da7a111f5e838cd8449a814f084f314a

But when ditching pattern detection we no longer know whether the link is surrounded by link syntax, so we can either blindly add it, or not. Either way, we risk changing the original document from [[http://example.com]] to http://example.com or the other way round. (And we definitely break tests that make sure this does not happen.)

I submitted a draft PR #193 to demonstrate the problem.

An alternative would be to actually duplicate the pattern recognition code, as shown by @hobgoblinsmaster above.

@splitbrain do you have any advice?