It's better when it's simple

User Tools

Site Tools


developer changelog

Refactoring 2021

This page lists changes from August 2020 to July 2022, included in the “Igor” release. For older changes see refactor2020, for newer refactor2022.

Welcome to add more notes/examples/etc on this page, to make updating of plugins and templates easy! Please share all remarks and possible improvements. See forum topic. Thank you very much! Klap-in

How to find deprecated code

A lot of code has been marked as deprecated. Which means it will be removed in future releases of DokuWiki. While this does (normally) not cause plugins to malfunction now, it may lead to nasty surprises after future updates.

Plugin/template authors can easily check if they use any deprecated functions, classes or methods:

Since the Igor 2022 release:

  • logging of deprecated messages is default enabled, otherwise you need to uncheck deprecated in the dontlog configuration setting
  • use the plugin
  • check LogViewer (or data/log/deprecated/<date>.log).

Up to the Hogfather 2020 release:

  • enable the allowdebug setting in the Configuration Manager
  • use the plugin
  • Check logs for any information about deprecated calls caused by the plugin in data/cache/debug.log .

Big improvements

New additions/improvements are:


413313a155 Deprecated dbglog() → dbglog()

Logger::debug("message", "details");
    $header, $msg

See Logger Class for all the options.

Refactored UI elements using Form\Form class

Only new events with dokuwiki\Form\Form from DokuWiki

DokuWiki used before this release Doku_Form at a lot of places. The old Doku_Form triggered a HTML_*FORM_OUTPUT event, when it was outputted by html_form(). The DokuWiki core code is updated to use the new forms, therefore the old events are not triggered anymore. The new style Form triggers a FORM_*_OUTPUT event when its HTML-representation is generated by toHTML() method.

Further, the old event HTML_EDIT_FORMSELECTION is not triggered anymore. Instead, the DokuWiki core code has changed to triggers the new EDIT_FORM_ADDTEXTAREA event that provides a dokuwiki/Form/Form in the $data['form'] and the event handler will complete the editor form.

:!: To enable your actions again, the new event handlers have to be implemented as well. The new events pass the new dokuwiki\Form\Form object as the event data. The old event handlers can be kept temporary for backward compatibility. But the old events handlers will not be used anymore in the new release.

See for the description of the events:

Changes to the dokuwiki\Form\Form class. An optional argument is added to toHTML() to make code simple without a separate event trigger.

- Event::createAndTrigger('FORM_SEARCH_OUTPUT', $searchForm);
- return $searchForm->toHTML();
+ return $searchForm->toHTML('Search');

UI elements implemented as class methods

Implemented by PR 3198 and 3361

Action Router calls Action::tplContent(), which calls Ui::show() that returns the actual HTML to output.

Deprecated functions: html_login, html_edit, html_edit_form, html_show, html_locked, html_index, html_backlinks, html_diff, html_conflict, html_register

Deprecated and only used in DokuWiki: html_denied, html_showrev, html_draft, html_revisions, html_recent, html_updateprofile, html_resendpwd, html_diff_head, html_diff_navigation, html_diff_navigationlink

Removed functions: html_minoredit.

// inc/html.php
- html_login($svg)
+ (new dokuwiki\Ui\Login($svg))->show()
- html_denied() 
+ (new dokuwiki\Action\Denied())->showBanner()
- html_edit()
+ (new dokuwiki\Ui\Editor)->show()
-    html_edit_form($data)
+    (new dokuwiki\Ui\Editor)->addTextarea($data)
-    html_minoredit()
+    // obsoleted: integrated into dokuwiki\Ui\Editor::show()  
- html_showrev()
+ (new dokuwiki\Ui\PageView)->showrev()
- html_show($txt)
+ (new dokuwiki\Ui\PageView($txt))->show()
- html_draft()
+ (new Ui\PageDraft)->show()
- html_locked()
+ (new dokuwiki\Action\Locked())->showBanner()
- html_revisions($first = 0, false);
+ global $INFO;
+ (new dokuwiki\Ui\PageRevisions($INFO['id']))->show($first);
- html_revisions($first = 0, $media_id);
+ (new dokuwiki\Ui\MediaRevisions($media_id))->show($first);
- html_recent($first, $show_changes)
+ (new dokuwiki\Ui\Recent($first, $show_changes))->show()
- html_index($ns)
+ (new dokuwiki\Ui\Index($ns))->show()
-    html_list_index($item)
+    (new dokuwiki\Ui\Index)->formatListItem($item)
-    html_li_index($item)
+    (new dokuwiki\Ui\Index)->tagListItem($item)
     // or as callbacks
-    html_buildlist($data, 'idx', 'html_list_index', 'html_li_index');
+    $idx = new dokuwiki\Ui\Index();
+    html_buildlist($data, 'idx', [$idx,'formatListItem'], [$idx,'tagListItem']);
     // for more examples see end of this section
- html_backlinks() {
+ (new dokuwiki\Ui\Backlinks)->show();
- html_diff($text, $intro, $type)
+ global $INFO;
+ (new dokuwiki\Ui\PageDiff($INFO['id']))->compareWith($text)->preference([
+     'showIntro' => $intro,
+     'difftype'  => $type,
+ ])->show();
-    html_diff_head($l_rev, $r_rev, $id = null, $media = false, $inline = false)
+    // changed to protected method; dokuwiki\Ui\PageDiff()::builddiffHead()
-    html_diff_navigation($pagelog, $type, $l_rev, $r_rev)
+    // changed to protected methods/internal code
-    html_diff_navigationlink($difftype, $linktype, $lrev, $rrev = null)
+    // changed to protected methods/internal code
-    $html = html_insert_softbreaks($diffhtml)
+    $html = (new dokuwiki\Ui\PageDiff())->insertSoftbreaks($diffhtml);
- html_conflict($text, $summary)
+ (new dokuwiki\Ui\PageConflict($text, $summary))->show()
- html_register()
+ (new dokuwiki\Ui\UserRegister)->show()
- html_updateprofile()
+ (new dokuwiki\Ui\UserProfile)->show()
- html_resendpwd()
+ (new dokuwiki\Ui\UserResendPwd)->show()

Removed: MEDIA_DIFF event was not used (did not had description page too).

Deprecated functions: media_diff()

Deprecated functions only internally used: _media_file_diff(), media_file_diff(), media_image_diff()

- $NS = getNS($image);
- $auth = auth_quickaclcheck("$NS:*");
- media_diff($image, $NS, $auth, true);
+ (new dokuwiki\Ui\MediaDiff($image))->preference('fromAjax', true)->show();
- media_diff($image, $NS, $auth);
+ (new dokuwiki\Ui\MediaDiff($image))->show();
-     _media_file_diff($data)
+     // this callback if removed with the MEDIA_DIFF event, now part of \dokuwiki\Ui\MediaDiff::show()
-     media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax)
+     // changed to protected dokuwiki\Ui\MediaDiff::showFileDiff()
-     media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $type)
+     // changed to protected dokuwiki\Ui\MediaDiff::showImageDiff()

Deprecated functions: tpl_subscribe()

// inc/template.php
- tpl_subscribe()
+ (new \dokuwiki\Ui\Subscribe)->show()

Small callbacks changed to annonymous functions

Removed functions: html_hilight_callback, which was used by html_hilight().

// html_hilight_callback() is integrated into html_hilight() 
- $html = @preg_replace_callback("/((<[^>]*)|$regex)/ui",'html_hilight_callback',$html);
+ $html = @preg_replace_callback("/((<[^>]*)|$regex)/ui", function ($match) {
+     $hlight = unslash($match[0]);
+     if (!isset($match[2])) {
+         $hlight = '<span class="search_hit">'.$hlight.'</span>';
+     }
+     return $hlight;
+ }, $html);

Removed function: html_softbreak_callback, which was used by html_insert_softbreaks().

// html_softbreak_callback() is integrated into Ui\Diff::insertSoftbreaks()
- return preg_replace_callback('/<[^>]*>|[^<> ]{12,}/','html_softbreak_callback',$diffhtml);
+ return preg_replace_callback('/<[^>]*>|[^<> ]{12,}/', function ($match) {
+   ...
+ }, $diffhtml);

Changed usage of html_buildlist(), of which 4th argument callable html_li_default has deprecated.

- function html_buildlist($data, $class, $func, $lifunc = 'html_li_default', $forcewrapper = false){
+ function html_buildlist($data, $class, $func, $lifunc = null, $forcewrapper = false) {
+   ...
+   // set callback function to build the <li> tag, formerly defined as html_li_default()
+   if (!is_callable($lifunc)) {
+      $lifunc = function ($item) {
+          return '<li class="level'.$item['level'].'">';
+      };
+   }
+   ....
+ }
  // Example if you want to use own 'html_li_default' function/method in your plugin ...
+     protected function myLiFunc($item) { ... }
+     $html = html_buildlist($data, $class, $func, [$this, 'myLiFunc']);
  // if you want to use callbacks in Ui\Index class:
+     $idx = new dokuwiki\Ui\Index;
+     $html = html_buildlist($data, $class, [$idx,'formatListItem'], [$idx,'tagListItem'])

Other changed functions

Changed function: html_sizechange

- html_sizechange($sizechange, $form) // where $form is the old Doku_Form
+ $html = html_sizechange($sizechange)

Sort with collator

Improved language support Since 3115, sort all alphabetical sorts with a language dependent collator, when 'intl' PHP-extension is available. If not available fall back to php's builtin function.

Alphabetical comparisons and sorts should be changed the following way to improve language support:

Old New
sort() Sort::sort()
ksort() Sort::ksort()
Sort::asortFN() for filenames
for reverse order arsort()/krsort()/etc use array_reverse() after the sort functions above
- $strcmp = strcasecmp($a['prompt'], $b['prompt']);
+ $strcmp = Sort::strcmp($a['prompt'], $b['prompt']);
- $strcmp = strcmp ($a,$b);
+ $strcmp = Sort::strcmp($a,$b);
- strnatcmp(utf8_encodeFN($data[$pos]['id']), utf8_encodeFN($tmp_ns)) > 0
+ Sort::strcmp($data[$pos]['id'], $tmp_ns) > 0
- sort($subs);
+ Sort::sort($subs);
- ksort($this->result);
+ Sort::ksort($this->result);
- asort($usersArray); 
+ Sort::asort($usersArray); 
- natsort($files);
+ Sort::asortFN($files);
- krsort($this->result);
+ Sort::ksort($this->result);
+ $this->result = array_reverse(this->result, true); 

Resizing and cropping

Deprecated Since the use of Slika, some internal functions are not needed anymore.

Old New
Use general functions media_crop_image() and media_crop_image(), or see how these use the Slika library.

PageFile Refactor

Implemented in PR 3361


Old New
addLogEntry() see \dokuwiki\File\Pagefile::saveWikiText() and the deprecated function
detectExternalEdit() \dokuwiki\File\PageFile::detectExternalEdit()


+ use dokuwiki\File\PageFile;
- detectExternalEdit($id) 
+ (new PageFile($id))->detectExternalEdit();
- saveOldRevision($id) {
+ new PageFile($id))->saveOldRevision();

From GIF to SVG smileys

The following images are removed and replaced by a SVG variant.

lib/images/smileys/icon_cool.gif      -> cool.svg
lib/images/smileys/icon_eek.gif       -> eek.svg
lib/images/smileys/icon_eek.gif       -> eek.svg
lib/images/smileys/icon_sad.gif       -> sad.svg
lib/images/smileys/icon_smile.gif     -> smile.svg
lib/images/smileys/icon_smile2.gif    -> smile2.svg
lib/images/smileys/icon_doubt.gif     -> doubt.svg
lib/images/smileys/icon_doubt2.gif    -> doubt2.svg
lib/images/smileys/icon_confused.gif  -> confused.svg
lib/images/smileys/icon_biggrin.gif   -> biggrin.svg
lib/images/smileys/icon_razz.gif      -> razz.svg
lib/images/smileys/icon_surprised.gif -> surprised.svg
lib/images/smileys/icon_surprised.gif -> surprised.svg
lib/images/smileys/icon_silenced.gif  -> silenced.svg
lib/images/smileys/icon_silenced.gif  -> silenced.svg
lib/images/smileys/icon_neutral.gif   -> neutral.svg
lib/images/smileys/icon_wink.gif      -> wink.svg
lib/images/smileys/facepalm.gif       -> facepalm.svg
lib/images/smileys/icon_fun.gif       -> fun.svg
lib/images/smileys/icon_question.gif  -> question.svg
lib/images/smileys/icon_exclaim.gif   -> exclaim.svg
lib/images/smileys/icon_lol.gif       -> lol.svg
lib/images/smileys/fixme.gif          -> fixme.svg
lib/images/smileys/delete.gif         -> delete.svg

Point of attention is to set the desired size of the svg.

hsc() instead of htmlspecialchars()

Due to PHP8.1 changes, the use of htmlspecialchars() is changed. 3574:

- htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
+ htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8');

Better to use hsc() instead of htmlspecialchars(), [and in the xhtml parser $this→_xmlEntities()? FIXME is this right?]

- $url .= htmlspecialchars($val);
+ $url .= hsc($val);

Refactoring of id resolving

3272 and 3630 refactor page and media resolving, introduce ~ shortcut to reference the current page as namespace. Handle hashes in page_exists().

Added media_exists()

Old (deprecated) New
resolve_id() use one of resolve functions below
resolve_mediaid() MediaResolver($context)::resolveId()

Page resolve:

- $cns = getNS($page['id']);
- $exists = false; //updated by resolve function
- $mid = 'relativeid'; //relative id, updated by resolve function
- resolve_pageid($cns, $mid, $exists);
- if(!$exists) {
-     ..
+ use dokuwiki\File\PageResolver;
+ $resolver = new PageResolver($page['id']);
+ $mid = $resolver->resolveId('relativeid');
+ if(!page_exists($mid)) {
+     ..

Media resolve:

- $contextns = getNS($contextid);
- $exists = false; //updated by resolve function
- $mediaid = 'relativemediaid'; //relative id, updated by resolve function
- resolve_mediaid($contextns, $mediaid, $exists);
- if(!$exists) {
-     ..
+ use dokuwiki\File\MediaResolver;
+ $resolver = new MediaResolver($contextid);
+ $mediaid = $resolver->resolveId($mediaid);
+ $exists = media_exists($mediaid);

As one liners:

- resolve_mediaid(getNS($ID), $src, $exists, $this->date_at, true);
+ use dokuwiki\File\MediaResolver;
+ $src = (new MediaResolver($ID))->resolveId($src,$this->date_at,true);
+ $exists = media_exists($src);
- resolve_pageid(getNS($ID), $id, $exists, $this->date_at, true);
+ use dokuwiki\File\PageResolver;        
+ $id = (new PageResolver($ID))->resolveId($id, $this->date_at, true);
+ $exists = page_exists($id, $this->date_at, false, true);

IXR moved

Moved IXR XML RPC to composer dependency 3534

Old (removed) New
IXR_Client functionality splitted: dokuwiki\Remote\IXR\Client
IXR_ClientMulticall IXR\Client\ClientMulticall
n.a. IXR\Client\ClientSSL
IXR_Server IXR\Server\Server
IXR_IntrospectionServer IXR\Server\IntrospectionServer
IXR_Request IXR\Request\Request
IXR_Message IXR\Message\Message
IXR_Error IXR\Message\Error
n.a. IXR\Exception\ClientException
n.a. IXR\Exception\ServerException
IXR_Date IXR\DataType\Date
IXR_Base64 IXR\DataType\Base64
IXR_Value IXR\DataType\Value

This class no longer inherits from HTTPClient, but from the original IXR Client. Therefore, enabling debugging is changed:

  $url = 'http://localhost/devel/dokuwiki/lib/exe/xmlrpc.php';
- $client = new IXR_Client($url);
- $client->debug = true; // enable for debugging
+ use dokuwiki\Remote\IXR\Client;
+ $client = new Client($url);
+ $http = $client->getHttpClient();
+ $http->debug = true; // enable for debugging

Changed signature header() in xhtml renderer

XHTML renderers implementing the header() method, need an extra optional parameter (otherwise error in PHP8) 3618.

- public function header($text, $level, $pos) {
+ public function header($text, $level, $pos, $returnonly = false)

FIXME dokuwiki\Exception\FatalException: Declaration of renderer_plugin_text::finishSectionEdit($end = null) must be compatible with Doku_Renderer_xhtml::finishSectionEdit($end = null, $hid = null)

devel/releases/refactor2021.txt · Last modified: 2023-10-15 13:10 by Klap-in

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki