-
-
-==== Image Links ====
-
-You can also use an image to link to another internal or external page by combining the syntax for links and [[#images_and_other_files|images]] (see below) like this:
-
- [[http://php.net|{{wiki:dokuwiki-128.png}}]]
-
-[[http://php.net|{{wiki:dokuwiki-128.png}}]]
-
-Please note: The image formatting is the only formatting syntax accepted in link names.
-
-The whole [[#images_and_other_files|image]] and [[#links|link]] syntax is supported (including image resizing, internal and external images and URLs and interwiki links).
-
-===== Footnotes =====
-
-You can add footnotes ((This is a footnote)) by using double parentheses.
-
- You can add footnotes ((This is a footnote)) by using double parentheses.
-
-===== Sectioning =====
-
-You can use up to five different levels of headlines to structure your content. If you have more than three headlines, a table of contents is generated automatically -- this can be disabled by including the string ''~~NOTOC~~ '' in the document.
-
-==== Headline Level 3 ====
-=== Headline Level 4 ===
-== Headline Level 5 ==
-
- ==== Headline Level 3 ====
- === Headline Level 4 ===
- == Headline Level 5 ==
-
-By using four or more dashes, you can make a horizontal line:
-
-----
-
-===== Media Files =====
-
-You can include external and internal [[doku>images|images, videos and audio files]] with curly brackets. Optionally you can specify the size of them.
-
-Real size: {{wiki:dokuwiki-128.png}}
-
-Resize to given width: {{wiki:dokuwiki-128.png?50}}
-
-Resize to given width and height((when the aspect ratio of the given width and height doesn't match that of the image, it will be cropped to the new ratio before resizing)): {{wiki:dokuwiki-128.png?200x50}}
-
-Resized external image: Â Â Â Â Â {{https://secure.php.net/images/php.gif?200x50}}
-
- Real size: {{wiki:dokuwiki-128.png}}
- Resize to given width: {{wiki:dokuwiki-128.png?50}}
- Resize to given width and height: {{wiki:dokuwiki-128.png?200x50}}
- Resized external image: Â Â Â Â Â {{https://secure.php.net/images/php.gif?200x50}}
-
-
-By using left or right whitespaces you can choose the alignment.
-
-{{ wiki:dokuwiki-128.png}}
-
-{{wiki:dokuwiki-128.png }}
-
-{{ wiki:dokuwiki-128.png }}
-
- {{ wiki:dokuwiki-128.png}}
- {{wiki:dokuwiki-128.png }}
- {{ wiki:dokuwiki-128.png }}
-
-Of course, you can add a title (displayed as a tooltip by most browsers), too.
-
-{{ wiki:dokuwiki-128.png |This is the caption}}
-
- {{ wiki:dokuwiki-128.png |This is the caption}}
-
-For linking an image to another page see [[#Image Links]] above.
-
-==== Supported Media Formats ====
-
-DokuWiki can embed the following media formats directly.
-
-| Image | ''gif'', ''jpg'', ''png'' |
-| Video | ''webm'', ''ogv'', ''mp4'' |
-| Audio | ''ogg'', ''mp3'', ''wav'' |
-| Flash | ''swf'' |
-
-If you specify a filename that is not a supported media format, then it will be displayed as a link instead.
-
-By adding ''?linkonly'' you provide a link to the media without displaying it inline
-
- {{wiki:dokuwiki-128.png?linkonly}}
-
-{{wiki:dokuwiki-128.png?linkonly}} This is just a link to the image.
-
-==== Fallback Formats ====
-
-Unfortunately not all browsers understand all video and audio formats. To mitigate the problem, you can upload your file in different formats for maximum browser compatibility.
-
-For example consider this embedded mp4 video:
-
- {{video.mp4|A funny video}}
-
-When you upload a ''video.webm'' and ''video.ogv'' next to the referenced ''video.mp4'', DokuWiki will automatically add them as alternatives so that one of the three files is understood by your browser.
-
-Additionally DokuWiki supports a "poster" image which will be shown before the video has started. That image needs to have the same filename as the video and be either a jpg or png file. In the example above a ''video.jpg'' file would work.
-
-===== Lists =====
-
-Dokuwiki supports ordered and unordered lists. To create a list item, indent your text by two spaces and use a ''*'' for unordered lists or a ''-'' for ordered ones.
-
- * This is a list
- * The second item
- * You may have different levels
- * Another item
-
- - The same list but ordered
- - Another item
- - Just use indention for deeper levels
- - That's it
-
-
- * This is a list
- * The second item
- * You may have different levels
- * Another item
-
- - The same list but ordered
- - Another item
- - Just use indention for deeper levels
- - That's it
-
-
-Also take a look at the [[doku>faq:lists|FAQ on list items]].
-
-===== Text Conversions =====
-
-DokuWiki can convert certain pre-defined characters or strings into images or other text or HTML.
-
-The text to image conversion is mainly done for smileys. And the text to HTML conversion is used for typography replacements, but can be configured to use other HTML as well.
-
-==== Text to Image Conversions ====
-
-DokuWiki converts commonly used [[wp>emoticon]]s to their graphical equivalents. Those [[doku>Smileys]] and other images can be configured and extended. Here is an overview of Smileys included in DokuWiki:
-
- * 8-) %% 8-) %%
- * 8-O %% 8-O %%
- * :-( %% :-( %%
- * :-) %% :-) %%
- * =) %% =) %%
- * :-/ %% :-/ %%
- * :-\ %% :-\ %%
- * :-? %% :-? %%
- * :-D %% :-D %%
- * :-P %% :-P %%
- * :-O %% :-O %%
- * :-X %% :-X %%
- * :-| %% :-| %%
- * ;-) %% ;-) %%
- * ^_^ %% ^_^ %%
- * m( %% m( %%
- * :?: %% :?: %%
- * :!: %% :!: %%
- * LOL %% LOL %%
- * FIXME %% FIXME %%
- * DELETEME %% DELETEME %%
-
-==== Text to HTML Conversions ====
-
-Typography: [[DokuWiki]] can convert simple text characters to their typographically correct entities. Here is an example of recognized characters.
-
--> <- <-> => <= <=> >> << -- --- 640x480 (c) (tm) (r)
-"He thought 'It's a man's world'..."
-
-
--> <- <-> => <= <=> >> << -- --- 640x480 (c) (tm) (r)
-"He thought 'It's a man's world'..."
-
-
-The same can be done to produce any kind of HTML, it just needs to be added to the [[doku>entities|pattern file]].
-
-There are three exceptions which do not come from that pattern file: multiplication entity (640x480), 'single' and "double quotes". They can be turned off through a [[doku>config:typography|config option]].
-
-===== Quoting =====
-
-Some times you want to mark some text to show it's a reply or comment. You can use the following syntax:
-
-
-I think we should do it
-
-> No we shouldn't
-
->> Well, I say we should
-
-> Really?
-
->> Yes!
-
->>> Then lets do it!
-
-
-I think we should do it
-
-> No we shouldn't
-
->> Well, I say we should
-
-> Really?
-
->> Yes!
-
->>> Then lets do it!
-
-===== Tables =====
-
-DokuWiki supports a simple syntax to create tables.
-
-^ Heading 1 ^ Heading 2 ^ Heading 3 ^
-| Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
-| Row 2 Col 1 | some colspan (note the double pipe) ||
-| Row 3 Col 1 | Row 3 Col 2 | Row 3 Col 3 |
-
-Table rows have to start and end with a ''|'' for normal rows or a ''^'' for headers.
-
- ^ Heading 1 ^ Heading 2 ^ Heading 3 ^
- | Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
- | Row 2 Col 1 | some colspan (note the double pipe) ||
- | Row 3 Col 1 | Row 3 Col 2 | Row 3 Col 3 |
-
-To connect cells horizontally, just make the next cell completely empty as shown above. Be sure to have always the same amount of cell separators!
-
-Vertical tableheaders are possible, too.
-
-| ^ Heading 1 ^ Heading 2 ^
-^ Heading 3 | Row 1 Col 2 | Row 1 Col 3 |
-^ Heading 4 | no colspan this time | |
-^ Heading 5 | Row 2 Col 2 | Row 2 Col 3 |
-
-As you can see, it's the cell separator before a cell which decides about the formatting:
-
- | ^ Heading 1 ^ Heading 2 ^
- ^ Heading 3 | Row 1 Col 2 | Row 1 Col 3 |
- ^ Heading 4 | no colspan this time | |
- ^ Heading 5 | Row 2 Col 2 | Row 2 Col 3 |
-
-You can have rowspans (vertically connected cells) by adding ''%%:::%%'' into the cells below the one to which they should connect.
-
-^ Heading 1 ^ Heading 2 ^ Heading 3 ^
-| Row 1 Col 1 | this cell spans vertically | Row 1 Col 3 |
-| Row 2 Col 1 | ::: | Row 2 Col 3 |
-| Row 3 Col 1 | ::: | Row 2 Col 3 |
-
-Apart from the rowspan syntax those cells should not contain anything else.
-
- ^ Heading 1 ^ Heading 2 ^ Heading 3 ^
- | Row 1 Col 1 | this cell spans vertically | Row 1 Col 3 |
- | Row 2 Col 1 | ::: | Row 2 Col 3 |
- | Row 3 Col 1 | ::: | Row 2 Col 3 |
-
-You can align the table contents, too. Just add at least two whitespaces at the opposite end of your text: Add two spaces on the left to align right, two spaces on the right to align left and two spaces at least at both ends for centered text.
-
-^ Table with alignment ^^^
-| right| center |left |
-|left | right| center |
-| xxxxxxxxxxxx | xxxxxxxxxxxx | xxxxxxxxxxxx |
-
-This is how it looks in the source:
-
- ^ Table with alignment ^^^
- | right| center |left |
- |left | right| center |
- | xxxxxxxxxxxx | xxxxxxxxxxxx | xxxxxxxxxxxx |
-
-Note: Vertical alignment is not supported.
-
-===== No Formatting =====
-
-If you need to display text exactly like it is typed (without any formatting), enclose the area either with ''%%%%'' tags or even simpler, with double percent signs ''%% ''.
-
-
-This is some text which contains addresses like this: http://www.splitbrain.org and **formatting**, but nothing is done with it.
-
-The same is true for %%//__this__ text// with a smiley ;-)%%.
-
-
- This is some text which contains addresses like this: http://www.splitbrain.org and **formatting**, but nothing is done with it.
-
- The same is true for %%//__this__ text// with a smiley ;-)%%.
-
-===== Code Blocks =====
-
-You can include code blocks into your documents by either indenting them by at least two spaces (like used for the previous examples) or by using the tags ''%%%%'' or ''%%%%''.
-
- This is text is indented by two spaces.
-
-
-This is preformatted code all spaces are preserved: like <-this
-
-
-
-This is pretty much the same, but you could use it to show that you quoted a file.
-
-
-Those blocks were created by this source:
-
- This is text is indented by two spaces.
-
-
- This is preformatted code all spaces are preserved: like <-this
-
-
-
- This is pretty much the same, but you could use it to show that you quoted a file.
-
-
-==== Syntax Highlighting ====
-
-[[wiki:DokuWiki]] can highlight sourcecode, which makes it easier to read. It uses the [[http://qbnz.com/highlighter/|GeSHi]] Generic Syntax Highlighter -- so any language supported by GeSHi is supported. The syntax uses the same code and file blocks described in the previous section, but this time the name of the language syntax to be highlighted is included inside the tag, e.g. ''
'' or '' ''.
-
-
-/**
- * The HelloWorldApp class implements an application that
- * simply displays "Hello World!" to the standard output.
- */
-class HelloWorldApp {
- public static void main(String[] args) {
- System.out.println("Hello World!"); //Display the string.
- }
-}
-
-
-The following language strings are currently recognized: //4cs 6502acme 6502kickass 6502tasm 68000devpac abap actionscript3 actionscript ada aimms algol68 apache applescript apt_sources arm asm asp asymptote autoconf autohotkey autoit avisynth awk bascomavr bash basic4gl batch bf biblatex bibtex blitzbasic bnf boo caddcl cadlisp ceylon cfdg cfm chaiscript chapel cil c_loadrunner clojure c_mac cmake cobol coffeescript c cpp cpp-qt cpp-winapi csharp css cuesheet c_winapi dart dcl dcpu16 dcs delphi diff div dos dot d ecmascript eiffel email epc e erlang euphoria ezt f1 falcon fo fortran freebasic freeswitch fsharp gambas gdb genero genie gettext glsl gml gnuplot go groovy gwbasic haskell haxe hicest hq9plus html html4strict html5 icon idl ini inno intercal io ispfpanel java5 java javascript jcl j jquery julia kixtart klonec klonecpp kotlin latex lb ldif lisp llvm locobasic logtalk lolcode lotusformulas lotusscript lscript lsl2 lua m68k magiksf make mapbasic mathematica matlab mercury metapost mirc mk-61 mmix modula2 modula3 mpasm mxml mysql nagios netrexx newlisp nginx nimrod nsis oberon2 objc objeck ocaml-brief ocaml octave oobas oorexx oracle11 oracle8 oxygene oz parasail parigp pascal pcre perl6 perl per pf phix php-brief php pic16 pike pixelbender pli plsql postgresql postscript povray powerbuilder powershell proftpd progress prolog properties providex purebasic pycon pys60 python qbasic qml q racket rails rbs rebol reg rexx robots roff rpmspec rsplus ruby rust sas sass scala scheme scilab scl sdlbasic smalltalk smarty spark sparql sql sshconfig standardml stonescript swift systemverilog tclegg tcl teraterm texgraph text thinbasic tsql twig typoscript unicon upc urbi uscript vala vbnet vb vbscript vedit verilog vhdl vim visualfoxpro visualprolog whitespace whois winbatch wolfram xbasic xml xojo xorg_conf xpp yaml z80 zxbasic//
-
-There are additional [[doku>syntax_highlighting|advanced options]] available for syntax highlighting, such as highlighting lines or adding line numbers.
-
-==== Downloadable Code Blocks ====
-
-When you use the ''%%%%'' or ''%%%%'' syntax as above, you might want to make the shown code available for download as well. You can do this by specifying a file name after language code like this:
-
-
-
-
-
-
-
-
-
-
-
-If you don't want any highlighting but want a downloadable file, specify a dash (''-'') as the language code: ''%%%%''.
-
-===== RSS/ATOM Feed Aggregation =====
-[[DokuWiki]] can integrate data from external XML feeds. For parsing the XML feeds, [[http://simplepie.org/|SimplePie]] is used. All formats understood by SimplePie can be used in DokuWiki as well. You can influence the rendering by multiple additional space separated parameters:
-
-^ Parameter ^ Description ^
-| any number | will be used as maximum number items to show, defaults to 8 |
-| reverse | display the last items in the feed first |
-| author | show item authors names |
-| date | show item dates |
-| description| show the item description. All HTML tags will be stripped |
-| nosort | do not sort the items in the feed |
-| //n//[dhm] | refresh period, where d=days, h=hours, m=minutes. (e.g. 12h = 12 hours). |
-
-The refresh period defaults to 4 hours. Any value below 10 minutes will be treated as 10 minutes. [[wiki:DokuWiki]] will generally try to supply a cached version of a page, obviously this is inappropriate when the page contains dynamic external content. The parameter tells [[wiki:DokuWiki]] to re-render the page if it is more than //refresh period// since the page was last rendered.
-
-By default the feed will be sorted by date, newest items first. You can sort it by oldest first using the ''reverse'' parameter, or display the feed as is with ''nosort''.
-
-**Example:**
-
- {{rss>http://slashdot.org/index.rss 5 author date 1h }}
-
-{{rss>http://slashdot.org/index.rss 5 author date 1h }}
-
-
-===== Control Macros =====
-
-Some syntax influences how DokuWiki renders a page without creating any output it self. The following control macros are availble:
-
-^ Macro ^ Description |
-| %%~~NOTOC~~%% | If this macro is found on the page, no table of contents will be created |
-| %%~~NOCACHE~~%% | DokuWiki caches all output by default. Sometimes this might not be wanted (eg. when the %%%% syntax above is used), adding this macro will force DokuWiki to rerender a page on every call |
-
-===== Syntax Plugins =====
-
-DokuWiki's syntax can be extended by [[doku>plugins|Plugins]]. How the installed plugins are used is described on their appropriate description pages. The following syntax plugins are available in this particular DokuWiki installation:
-
-~~INFO:syntaxplugins~~
diff --git a/snippets/dokuwiki-2023-04-04/data/pages/wiki/welcome.txt b/snippets/dokuwiki-2023-04-04/data/pages/wiki/welcome.txt
deleted file mode 100644
index 10caa7c..0000000
--- a/snippets/dokuwiki-2023-04-04/data/pages/wiki/welcome.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-====== Welcome to your new DokuWiki ======
-
-Congratulations, your wiki is now up and running. Here are a few more tips to get you started.
-
-Enjoy your work with DokuWiki,\\
--- the developers
-
-===== Create your first pages =====
-
-Your wiki needs to have a start page. As long as it doesn't exist, this link will be red: [[:start]].
-
-Go on, follow that link and create the page. If you need help with using the syntax you can always refer to the [[wiki:syntax|syntax page]].
-
-You might also want to use a sidebar. To create it, just edit the [[:sidebar]] page. Everything in that page will be shown in a margin column on the side. Read our [[doku>faq:sidebar|FAQ on sidebars]] to learn more.
-
-Please be aware that not all templates support sidebars.
-
-===== Customize your Wiki =====
-
-Once you're comfortable with creating and editing pages you might want to have a look at the [[this>doku.php?do=admin&page=config|configuration settings]] (be sure to login as superuser first).
-
-You may also want to see what [[doku>plugins|plugins]] and [[doku>templates|templates]] are available at DokuWiki.org to extend the functionality and looks of your DokuWiki installation.
-
-===== Join the Community =====
-
-DokuWiki is an Open Source project that thrives through user contributions. A good way to stay informed on what's going on and to get useful tips in using DokuWiki is subscribing to the [[doku>newsletter]].
-
-The [[https://forum.dokuwiki.org|DokuWiki User Forum]] is an excellent way to get in contact with other DokuWiki users and is just one of the many ways to get [[doku>faq:support|support]].
-
-Of course we'd be more than happy to have you [[doku>teams:getting_involved|getting involved]] with DokuWiki.
diff --git a/snippets/dokuwiki-2023-04-04/data/tmp/_dummy b/snippets/dokuwiki-2023-04-04/data/tmp/_dummy
deleted file mode 100644
index e492265..0000000
--- a/snippets/dokuwiki-2023-04-04/data/tmp/_dummy
+++ /dev/null
@@ -1 +0,0 @@
-You can safely delete this file.
\ No newline at end of file
diff --git a/snippets/dokuwiki-2023-04-04/doku.php b/snippets/dokuwiki-2023-04-04/doku.php
deleted file mode 100644
index 21332d0..0000000
--- a/snippets/dokuwiki-2023-04-04/doku.php
+++ /dev/null
@@ -1,131 +0,0 @@
-
- *
- * @global Input $INPUT
- */
-
-// update message version - always use a string to avoid localized floats!
-use dokuwiki\Extension\Event;
-
-$updateVersion = "54";
-
-// xdebug_start_profiling();
-
-if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__).'/');
-
-// define all DokuWiki globals here (needed within test requests but also helps to keep track)
-global $ACT, $INPUT, $QUERY, $ID, $REV, $DATE_AT, $IDX,
- $DATE, $RANGE, $HIGH, $TEXT, $PRE, $SUF, $SUM, $INFO, $JSINFO;
-
-
-if(isset($_SERVER['HTTP_X_DOKUWIKI_DO'])) {
- $ACT = trim(strtolower($_SERVER['HTTP_X_DOKUWIKI_DO']));
-} elseif(!empty($_REQUEST['idx'])) {
- $ACT = 'index';
-} elseif(isset($_REQUEST['do'])) {
- $ACT = $_REQUEST['do'];
-} else {
- $ACT = 'show';
-}
-
-// load and initialize the core system
-require_once(DOKU_INC.'inc/init.php');
-
-//import variables
-$INPUT->set('id', str_replace("\xC2\xAD", '', $INPUT->str('id'))); //soft-hyphen
-$QUERY = trim($INPUT->str('q'));
-$ID = getID();
-
-$REV = $INPUT->int('rev');
-$DATE_AT = $INPUT->str('at');
-$IDX = $INPUT->str('idx');
-$DATE = $INPUT->int('date');
-$RANGE = $INPUT->str('range');
-$HIGH = $INPUT->param('s');
-if(empty($HIGH)) $HIGH = getGoogleQuery();
-
-if($INPUT->post->has('wikitext')) {
- $TEXT = cleanText($INPUT->post->str('wikitext'));
-}
-$PRE = cleanText(substr($INPUT->post->str('prefix'), 0, -1));
-$SUF = cleanText($INPUT->post->str('suffix'));
-$SUM = $INPUT->post->str('summary');
-
-
-//parse DATE_AT
-if($DATE_AT) {
- $date_parse = strtotime($DATE_AT);
- if($date_parse) {
- $DATE_AT = $date_parse;
- } else { // check for UNIX Timestamp
- $date_parse = @date('Ymd',$DATE_AT);
- if(!$date_parse || $date_parse === '19700101') {
- msg(sprintf($lang['unable_to_parse_date'], hsc($DATE_AT)));
- $DATE_AT = null;
- }
- }
-}
-
-//check for existing $REV related to $DATE_AT
-if($DATE_AT) {
- $pagelog = new \dokuwiki\ChangeLog\PageChangeLog($ID);
- $rev_t = $pagelog->getLastRevisionAt($DATE_AT);
- if($rev_t === '') { //current revision
- $REV = null;
- $DATE_AT = null;
- } else if ($rev_t === false) { //page did not exist
- $rev_n = $pagelog->getRelativeRevision($DATE_AT,+1);
- msg(
- sprintf(
- $lang['page_nonexist_rev'],
- dformat($DATE_AT),
- wl($ID, array('rev' => $rev_n)),
- dformat($rev_n)
- )
- );
- $REV = $DATE_AT; //will result in a page not exists message
- } else {
- $REV = $rev_t;
- }
-}
-
-//make infos about the selected page available
-$INFO = pageinfo();
-
-// handle debugging
-if($conf['allowdebug'] && $ACT == 'debug') {
- html_debug();
- exit;
-}
-
-//send 404 for missing pages if configured or ID has special meaning to bots
-if(!$INFO['exists'] &&
- ($conf['send404'] || preg_match('/^(robots\.txt|sitemap\.xml(\.gz)?|favicon\.ico|crossdomain\.xml)$/', $ID)) &&
- ($ACT == 'show' || (!is_array($ACT) && substr($ACT, 0, 7) == 'export_'))
-) {
- header('HTTP/1.0 404 Not Found');
-}
-
-//prepare breadcrumbs (initialize a static var)
-if($conf['breadcrumbs']) breadcrumbs();
-
-// check upstream
-checkUpdateMessages();
-
-$tmp = array(); // No event data
-Event::createAndTrigger('DOKUWIKI_STARTED', $tmp);
-
-//close session
-session_write_close();
-
-//do the work (picks up what to do from global env)
-act_dispatch();
-
-$tmp = array(); // No event data
-Event::createAndTrigger('DOKUWIKI_DONE', $tmp);
-
-// xdebug_dump_function_profile(1);
diff --git a/snippets/dokuwiki-2023-04-04/feed.php b/snippets/dokuwiki-2023-04-04/feed.php
deleted file mode 100644
index a389f14..0000000
--- a/snippets/dokuwiki-2023-04-04/feed.php
+++ /dev/null
@@ -1,546 +0,0 @@
-
- *
- * @global array $conf
- * @global Input $INPUT
- */
-
-use dokuwiki\Cache\Cache;
-use dokuwiki\ChangeLog\MediaChangeLog;
-use dokuwiki\ChangeLog\PageChangeLog;
-use dokuwiki\Extension\AuthPlugin;
-use dokuwiki\Extension\Event;
-
-if (!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/');
-require_once(DOKU_INC . 'inc/init.php');
-
-//close session
-session_write_close();
-
-//feed disabled?
-if (!actionOK('rss')) {
- http_status(404);
- echo 'RSS feed is disabled. ';
- exit;
-}
-
-// get params
-$opt = rss_parseOptions();
-
-// the feed is dynamic - we need a cache for each combo
-// (but most people just use the default feed so it's still effective)
-$key = join('', array_values($opt)) . '$' . $INPUT->server->str('REMOTE_USER')
- . '$' . $INPUT->server->str('HTTP_HOST') . $INPUT->server->str('SERVER_PORT');
-$cache = new Cache($key, '.feed');
-
-// prepare cache depends
-$depends['files'] = getConfigFiles('main');
-$depends['age'] = $conf['rss_update'];
-$depends['purge'] = $INPUT->bool('purge');
-
-// check cacheage and deliver if nothing has changed since last
-// time or the update interval has not passed, also handles conditional requests
-header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
-header('Pragma: public');
-header('Content-Type: application/xml; charset=utf-8');
-header('X-Robots-Tag: noindex');
-if ($cache->useCache($depends)) {
- http_conditionalRequest($cache->getTime());
- if ($conf['allowdebug']) header("X-CacheUsed: $cache->cache");
- print $cache->retrieveCache();
- exit;
-} else {
- http_conditionalRequest(time());
-}
-
-// create new feed
-$rss = new UniversalFeedCreator();
-$rss->title = $conf['title'] . (($opt['namespace']) ? ' ' . $opt['namespace'] : '');
-$rss->link = DOKU_URL;
-$rss->syndicationURL = DOKU_URL . 'feed.php';
-$rss->cssStyleSheet = DOKU_URL . 'lib/exe/css.php?s=feed';
-
-$image = new FeedImage();
-$image->title = $conf['title'];
-$image->url = tpl_getMediaFile([':wiki:favicon.ico', ':favicon.ico', 'images/favicon.ico'], true);
-$image->link = DOKU_URL;
-$rss->image = $image;
-
-$data = null;
-$modes = [
- 'list' => 'rssListNamespace',
- 'search' => 'rssSearch',
- 'recent' => 'rssRecentChanges'
-];
-
-if (isset($modes[$opt['feed_mode']])) {
- $data = $modes[$opt['feed_mode']]($opt);
-} else {
- $eventData = [
- 'opt' => &$opt,
- 'data' => &$data,
- ];
- $event = new Event('FEED_MODE_UNKNOWN', $eventData);
- if ($event->advise_before(true)) {
- echo sprintf('Unknown feed mode %s ', hsc($opt['feed_mode']));
- exit;
- }
- $event->advise_after();
-}
-
-rss_buildItems($rss, $data, $opt);
-$feed = $rss->createFeed($opt['feed_type']);
-
-// save cachefile
-$cache->storeCache($feed);
-
-// finally deliver
-print $feed;
-
-// ---------------------------------------------------------------- //
-
-/**
- * Get URL parameters and config options and return an initialized option array
- *
- * @author Andreas Gohr
- */
-function rss_parseOptions()
-{
- global $conf;
- global $INPUT;
-
- $opt = [];
-
- foreach (
- [
- // Basic feed properties
- // Plugins may probably want to add new values to these
- // properties for implementing own feeds
-
- // One of: list, search, recent
- 'feed_mode' => ['str', 'mode', 'recent'],
- // One of: diff, page, rev, current
- 'link_to' => ['str', 'linkto', $conf['rss_linkto']],
- // One of: abstract, diff, htmldiff, html
- 'item_content' => ['str', 'content', $conf['rss_content']],
-
- // Special feed properties
- // These are only used by certain feed_modes
-
- // String, used for feed title, in list and rc mode
- 'namespace' => ['str', 'ns', null],
- // Positive integer, only used in rc mode
- 'items' => ['int', 'num', $conf['recent']],
- // Boolean, only used in rc mode
- 'show_minor' => ['bool', 'minor', false],
- // Boolean, only used in rc mode
- 'only_new' => ['bool', 'onlynewpages', false],
- // String, only used in list mode
- 'sort' => ['str', 'sort', 'natural'],
- // String, only used in search mode
- 'search_query' => ['str', 'q', null],
- // One of: pages, media, both
- 'content_type' => ['str', 'view', $conf['rss_media']]
-
- ] as $name => $val
- ) {
- $opt[$name] = $INPUT->{$val[0]}($val[1], $val[2], true);
- }
-
- $opt['items'] = max(0, (int) $opt['items']);
- $opt['show_minor'] = (bool) $opt['show_minor'];
- $opt['only_new'] = (bool) $opt['only_new'];
- $opt['sort'] = valid_input_set('sort', ['default' => 'natural', 'date'], $opt);
-
- $opt['guardmail'] = ($conf['mailguard'] != '' && $conf['mailguard'] != 'none');
-
- $type = $INPUT->valid(
- 'type',
- ['rss', 'rss2', 'atom', 'atom1', 'rss1'],
- $conf['rss_type']
- );
- switch ($type) {
- case 'rss':
- $opt['feed_type'] = 'RSS0.91';
- $opt['mime_type'] = 'text/xml';
- break;
- case 'rss2':
- $opt['feed_type'] = 'RSS2.0';
- $opt['mime_type'] = 'text/xml';
- break;
- case 'atom':
- $opt['feed_type'] = 'ATOM0.3';
- $opt['mime_type'] = 'application/xml';
- break;
- case 'atom1':
- $opt['feed_type'] = 'ATOM1.0';
- $opt['mime_type'] = 'application/atom+xml';
- break;
- default:
- $opt['feed_type'] = 'RSS1.0';
- $opt['mime_type'] = 'application/xml';
- }
-
- $eventData = [
- 'opt' => &$opt,
- ];
- Event::createAndTrigger('FEED_OPTS_POSTPROCESS', $eventData);
- return $opt;
-}
-
-/**
- * Add recent changed pages to a feed object
- *
- * @param FeedCreator $rss the FeedCreator Object
- * @param array $data the items to add
- * @param array $opt the feed options
- * @author Andreas Gohr
- */
-function rss_buildItems(&$rss, &$data, $opt)
-{
- global $conf;
- global $lang;
- /* @var AuthPlugin $auth */
- global $auth;
-
- $eventData = [
- 'rss' => &$rss,
- 'data' => &$data,
- 'opt' => &$opt,
- ];
- $event = new Event('FEED_DATA_PROCESS', $eventData);
- if ($event->advise_before(false)) {
- foreach ($data as $ditem) {
- if (!is_array($ditem)) {
- // not an array? then only a list of IDs was given
- $ditem = ['id' => $ditem];
- }
-
- $item = new FeedItem();
- $id = $ditem['id'];
- if (empty($ditem['media'])) {
- $meta = p_get_metadata($id);
- } else {
- $meta = [];
- }
-
- // add date
- if (isset($ditem['date'])) {
- $date = $ditem['date'];
- } elseif ($ditem['media']) {
- $date = @filemtime(mediaFN($id));
- } elseif (file_exists(wikiFN($id))) {
- $date = @filemtime(wikiFN($id));
- } elseif ($meta['date']['modified']) {
- $date = $meta['date']['modified'];
- } else {
- $date = 0;
- }
- if ($date) $item->date = date('r', $date);
-
- // add title
- if ($conf['useheading'] && $meta['title'] ?? '') {
- $item->title = $meta['title'];
- } else {
- $item->title = $ditem['id'];
- }
- if ($conf['rss_show_summary'] && !empty($ditem['sum'])) {
- $item->title .= ' - ' . strip_tags($ditem['sum']);
- }
-
- // add item link
- switch ($opt['link_to']) {
- case 'page':
- if (isset($ditem['media'])) {
- $item->link = media_managerURL(
- [
- 'image' => $id,
- 'ns' => getNS($id),
- 'rev' => $date
- ],
- '&',
- true
- );
- } else {
- $item->link = wl($id, 'rev=' . $date, true, '&');
- }
- break;
- case 'rev':
- if ($ditem['media']) {
- $item->link = media_managerURL(
- [
- 'image' => $id,
- 'ns' => getNS($id),
- 'rev' => $date,
- 'tab_details' => 'history'
- ],
- '&',
- true
- );
- } else {
- $item->link = wl($id, 'do=revisions&rev=' . $date, true, '&');
- }
- break;
- case 'current':
- if ($ditem['media']) {
- $item->link = media_managerURL(
- [
- 'image' => $id,
- 'ns' => getNS($id)
- ],
- '&',
- true
- );
- } else {
- $item->link = wl($id, '', true, '&');
- }
- break;
- case 'diff':
- default:
- if ($ditem['media']) {
- $item->link = media_managerURL(
- [
- 'image' => $id,
- 'ns' => getNS($id),
- 'rev' => $date,
- 'tab_details' => 'history',
- 'mediado' => 'diff'
- ],
- '&',
- true
- );
- } else {
- $item->link = wl($id, 'rev=' . $date . '&do=diff', true, '&');
- }
- }
-
- // add item content
- switch ($opt['item_content']) {
- case 'diff':
- case 'htmldiff':
- if ($ditem['media']) {
- $medialog = new MediaChangeLog($id);
- $revs = $medialog->getRevisions(0, 1);
- $rev = $revs[0];
- $src_r = '';
- $src_l = '';
-
- if ($size = media_image_preview_size($id, '', new JpegMeta(mediaFN($id)), 300)) {
- $more = 'w=' . $size[0] . '&h=' . $size[1] . '&t=' . @filemtime(mediaFN($id));
- $src_r = ml($id, $more, true, '&', true);
- }
- if ($rev && $size = media_image_preview_size($id, $rev, new JpegMeta(mediaFN($id, $rev)),
- 300)) {
- $more = 'rev=' . $rev . '&w=' . $size[0] . '&h=' . $size[1];
- $src_l = ml($id, $more, true, '&', true);
- }
- $content = '';
- if ($src_r) {
- $content = '';
- $content .= '' . $rev . ' ';
- $content .= '' . $lang['current'] . ' ';
- $content .= '
';
- $content .= '
';
- $content .= '
';
- }
- } else {
- require_once(DOKU_INC . 'inc/DifferenceEngine.php');
- $pagelog = new PageChangeLog($id);
- $revs = $pagelog->getRevisions(0, 1);
- $rev = $revs[0];
-
- if ($rev) {
- $df = new Diff(
- explode("\n", rawWiki($id, $rev)),
- explode("\n", rawWiki($id, ''))
- );
- } else {
- $df = new Diff(
- [''],
- explode("\n", rawWiki($id, ''))
- );
- }
-
- if ($opt['item_content'] == 'htmldiff') {
- // note: no need to escape diff output, TableDiffFormatter provides 'safe' html
- $tdf = new TableDiffFormatter();
- $content = '';
- $content .= '' . $rev . ' ';
- $content .= '' . $lang['current'] . ' ';
- $content .= $tdf->format($df);
- $content .= '
';
- } else {
- // note: diff output must be escaped, UnifiedDiffFormatter provides plain text
- $udf = new UnifiedDiffFormatter();
- $content = "\n" . hsc($udf->format($df)) . "\n
";
- }
- }
- break;
- case 'html':
- if ($ditem['media']) {
- if ($size = media_image_preview_size($id, '', new JpegMeta(mediaFN($id)))) {
- $more = 'w=' . $size[0] . '&h=' . $size[1] . '&t=' . @filemtime(mediaFN($id));
- $src = ml($id, $more, true, '&', true);
- $content = '
';
- } else {
- $content = '';
- }
- } else {
- if (@filemtime(wikiFN($id)) === $date) {
- $content = p_wiki_xhtml($id, '', false);
- } else {
- $content = p_wiki_xhtml($id, $date, false);
- }
- // no TOC in feeds
- $content = preg_replace('/().*()/s', '', $content);
-
- // add alignment for images
- $content = preg_replace('/(
';
- } else {
- $content = '';
- }
- } else {
- $content = $meta['description']['abstract'];
- }
- }
- $item->description = $content; //FIXME a plugin hook here could be senseful
-
- // add user
- # FIXME should the user be pulled from metadata as well?
- $user = @$ditem['user']; // the @ spares time repeating lookup
- if (blank($user)) {
- $item->author = 'Anonymous';
- $item->authorEmail = 'anonymous@undisclosed.example.com';
- } else {
- $item->author = $user;
- $item->authorEmail = $user . '@undisclosed.example.com';
-
- // get real user name if configured
- if ($conf['useacl'] && $auth) {
- $userInfo = $auth->getUserData($user);
- if ($userInfo) {
- switch ($conf['showuseras']) {
- case 'username':
- case 'username_link':
- $item->author = $userInfo['name'];
- break;
- default:
- $item->author = $user;
- break;
- }
- } else {
- $item->author = $user;
- }
- }
- }
-
- // add category
- if (isset($meta['subject'])) {
- $item->category = $meta['subject'];
- } else {
- $cat = getNS($id);
- if ($cat) $item->category = $cat;
- }
-
- // finally add the item to the feed object, after handing it to registered plugins
- $evdata = [
- 'item' => &$item,
- 'opt' => &$opt,
- 'ditem' => &$ditem,
- 'rss' => &$rss
- ];
- $evt = new Event('FEED_ITEM_ADD', $evdata);
- if ($evt->advise_before()) {
- $rss->addItem($item);
- }
- $evt->advise_after(); // for completeness
- }
- }
- $event->advise_after();
-}
-
-/**
- * Add recent changed pages to the feed object
- *
- * @author Andreas Gohr
- */
-function rssRecentChanges($opt)
-{
- global $conf;
- $flags = 0;
- if (!$conf['rss_show_deleted']) $flags += RECENTS_SKIP_DELETED;
- if (!$opt['show_minor']) $flags += RECENTS_SKIP_MINORS;
- if ($opt['only_new']) $flags += RECENTS_ONLY_CREATION;
- if ($opt['content_type'] == 'media' && $conf['mediarevisions']) $flags += RECENTS_MEDIA_CHANGES;
- if ($opt['content_type'] == 'both' && $conf['mediarevisions']) $flags += RECENTS_MEDIA_PAGES_MIXED;
-
- $recents = getRecents(0, $opt['items'], $opt['namespace'], $flags);
- return $recents;
-}
-
-/**
- * Add all pages of a namespace to the feed object
- *
- * @author Andreas Gohr
- */
-function rssListNamespace($opt)
-{
- require_once(DOKU_INC . 'inc/search.php');
- global $conf;
-
- $ns = ':' . cleanID($opt['namespace']);
- $ns = utf8_encodeFN(str_replace(':', '/', $ns));
-
- $data = [];
- $search_opts = [
- 'depth' => 1,
- 'pagesonly' => true,
- 'listfiles' => true
- ];
- search($data, $conf['datadir'], 'search_universal', $search_opts, $ns, $lvl = 1, $opt['sort']);
-
- return $data;
-}
-
-/**
- * Add the result of a full text search to the feed object
- *
- * @author Andreas Gohr
- */
-function rssSearch($opt)
-{
- if (!$opt['search_query'] || !actionOK('search')) return [];
-
- require_once(DOKU_INC . 'inc/fulltext.php');
- $data = ft_pageSearch($opt['search_query'], $poswords);
- $data = array_keys($data);
-
- return $data;
-}
-
-//Setup VIM: ex: et ts=4 :
diff --git a/snippets/dokuwiki-2023-04-04/inc/.htaccess b/snippets/dokuwiki-2023-04-04/inc/.htaccess
deleted file mode 100644
index 6ba7d91..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/.htaccess
+++ /dev/null
@@ -1,8 +0,0 @@
-## no access to the inc directory
-
- Require all denied
-
-
- Order allow,deny
- Deny from all
-
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/AbstractAclAction.php b/snippets/dokuwiki-2023-04-04/inc/Action/AbstractAclAction.php
deleted file mode 100644
index 871edb0..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/AbstractAclAction.php
+++ /dev/null
@@ -1,25 +0,0 @@
-actionname = $actionname;
- } else {
- // http://stackoverflow.com/a/27457689/172068
- $this->actionname = strtolower(substr(strrchr(get_class($this), '\\'), 1));
- }
- }
-
- /**
- * Return the minimum permission needed
- *
- * This needs to return one of the AUTH_* constants. It will be checked against
- * the current user and page after checkPermissions() ran through. If it fails,
- * the user will be shown the Denied action.
- *
- * @return int
- */
- abstract public function minimumPermission();
-
- /**
- * Check conditions are met to run this action
- *
- * @throws ActionException
- * @return void
- */
- public function checkPreconditions() {
- }
-
- /**
- * Process data
- *
- * This runs before any output is sent to the browser.
- *
- * Throw an Exception if a different action should be run after this step.
- *
- * @throws ActionException
- * @return void
- */
- public function preProcess() {
- }
-
- /**
- * Output whatever content is wanted within tpl_content();
- *
- * @fixme we may want to return a Ui class here
- * @throws FatalException
- */
- public function tplContent() {
- throw new FatalException('No content for Action ' . $this->actionname);
- }
-
- /**
- * Returns the name of this action
- *
- * This is usually the lowercased class name, but may differ for some actions.
- * eg. the export_ modes or for the Plugin action.
- *
- * @return string
- */
- public function getActionName() {
- return $this->actionname;
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/AbstractAliasAction.php b/snippets/dokuwiki-2023-04-04/inc/Action/AbstractAliasAction.php
deleted file mode 100644
index 771664a..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/AbstractAliasAction.php
+++ /dev/null
@@ -1,31 +0,0 @@
-server->str('REMOTE_USER') === '') {
- throw new ActionUserRequiredException();
- }
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Admin.php b/snippets/dokuwiki-2023-04-04/inc/Action/Admin.php
deleted file mode 100644
index 7a884b5..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Admin.php
+++ /dev/null
@@ -1,42 +0,0 @@
-str('page', '', true) != '') {
- /** @var AdminPlugin $plugin */
- if($plugin = plugin_getRequestAdminPlugin()) { // FIXME this method does also permission checking
- if(!$plugin->isAccessibleByCurrentUser()) {
- throw new ActionException('denied');
- }
- $plugin->handle();
- }
- }
- }
-
- /** @inheritDoc */
- public function tplContent() {
- tpl_admin();
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Backlink.php b/snippets/dokuwiki-2023-04-04/inc/Action/Backlink.php
deleted file mode 100644
index 5c51014..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Backlink.php
+++ /dev/null
@@ -1,28 +0,0 @@
-show();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Cancel.php b/snippets/dokuwiki-2023-04-04/inc/Action/Cancel.php
deleted file mode 100644
index d7505e4..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Cancel.php
+++ /dev/null
@@ -1,28 +0,0 @@
- redirect -> show
- throw new ActionAbort('draftdel');
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Check.php b/snippets/dokuwiki-2023-04-04/inc/Action/Check.php
deleted file mode 100644
index 36ae8e8..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Check.php
+++ /dev/null
@@ -1,26 +0,0 @@
-show();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Denied.php b/snippets/dokuwiki-2023-04-04/inc/Action/Denied.php
deleted file mode 100644
index ab2f0d8..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Denied.php
+++ /dev/null
@@ -1,52 +0,0 @@
-showBanner();
-
- $data = null;
- $event = new Event('ACTION_DENIED_TPLCONTENT', $data);
- if ($event->advise_before()) {
- global $INPUT;
- if (empty($INPUT->server->str('REMOTE_USER')) && actionOK('login')) {
- (new Ui\Login)->show();
- }
- }
- $event->advise_after();
- }
-
- /**
- * Display error on denied pages
- *
- * @author Andreas Gohr
- *
- * @return void
- */
- public function showBanner()
- {
- // print intro
- print p_locale_xhtml('denied');
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Diff.php b/snippets/dokuwiki-2023-04-04/inc/Action/Diff.php
deleted file mode 100644
index 31024b6..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Diff.php
+++ /dev/null
@@ -1,41 +0,0 @@
-str('difftype');
- if (!empty($difftype)) {
- set_doku_pref('difftype', $difftype);
- }
- }
-
- /** @inheritdoc */
- public function tplContent()
- {
- global $INFO;
- (new Ui\PageDiff($INFO['id']))->preference('showIntro', true)->show();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Draft.php b/snippets/dokuwiki-2023-04-04/inc/Action/Draft.php
deleted file mode 100644
index 0c33dab..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Draft.php
+++ /dev/null
@@ -1,43 +0,0 @@
-show();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Draftdel.php b/snippets/dokuwiki-2023-04-04/inc/Action/Draftdel.php
deleted file mode 100644
index 1fb7966..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Draftdel.php
+++ /dev/null
@@ -1,38 +0,0 @@
-isDraftAvailable() && checkSecurityToken()) {
- $draft->deleteDraft();
- }
-
- throw new ActionAbort('redirect');
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Edit.php b/snippets/dokuwiki-2023-04-04/inc/Action/Edit.php
deleted file mode 100644
index 417fdb0..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Edit.php
+++ /dev/null
@@ -1,96 +0,0 @@
-show();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Exception/ActionAbort.php b/snippets/dokuwiki-2023-04-04/inc/Action/Exception/ActionAbort.php
deleted file mode 100644
index 9c188bb..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Exception/ActionAbort.php
+++ /dev/null
@@ -1,20 +0,0 @@
-server->str('REQUEST_METHOD')) == 'post') {
- $newaction = 'redirect';
- } else {
- $newaction = 'show';
- }
- }
-
- $this->newaction = $newaction;
- }
-
- /**
- * Returns the action to use next
- *
- * @return string
- */
- public function getNewAction() {
- return $this->newaction;
- }
-
- /**
- * Should this Exception's message be shown to the user?
- *
- * @param null|bool $set when null is given, the current setting is not changed
- * @return bool
- */
- public function displayToUser($set = null) {
- if(!is_null($set)) $this->displayToUser = $set;
- return $set;
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Exception/ActionUserRequiredException.php b/snippets/dokuwiki-2023-04-04/inc/Action/Exception/ActionUserRequiredException.php
deleted file mode 100644
index aab06cc..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Exception/ActionUserRequiredException.php
+++ /dev/null
@@ -1,17 +0,0 @@
-
- * @author Michael Klier
- * @inheritdoc
- */
- public function preProcess() {
- global $ID;
- global $REV;
- global $conf;
- global $lang;
-
- $pre = '';
- $post = '';
- $headers = array();
-
- // search engines: never cache exported docs! (Google only currently)
- $headers['X-Robots-Tag'] = 'noindex';
-
- $mode = substr($this->actionname, 7);
- switch($mode) {
- case 'raw':
- $headers['Content-Type'] = 'text/plain; charset=utf-8';
- $headers['Content-Disposition'] = 'attachment; filename=' . noNS($ID) . '.txt';
- $output = rawWiki($ID, $REV);
- break;
- case 'xhtml':
- $pre .= '' . DOKU_LF;
- $pre .= '' . DOKU_LF;
- $pre .= '' . DOKU_LF;
- $pre .= ' ' . DOKU_LF; // FIXME improve wrapper
- $pre .= ' ' . $ID . ' ' . DOKU_LF;
-
- // get metaheaders
- ob_start();
- tpl_metaheaders();
- $pre .= ob_get_clean();
-
- $pre .= '' . DOKU_LF;
- $pre .= '' . DOKU_LF;
- $pre .= '' . DOKU_LF;
-
- // get toc
- $pre .= tpl_toc(true);
-
- $headers['Content-Type'] = 'text/html; charset=utf-8';
- $output = p_wiki_xhtml($ID, $REV, false);
-
- $post .= '' . DOKU_LF;
- $post .= '' . DOKU_LF;
- $post .= '' . DOKU_LF;
- break;
- case 'xhtmlbody':
- $headers['Content-Type'] = 'text/html; charset=utf-8';
- $output = p_wiki_xhtml($ID, $REV, false);
- break;
- default:
- $output = p_cached_output(wikiFN($ID, $REV), $mode, $ID);
- $headers = p_get_metadata($ID, "format $mode");
- break;
- }
-
- // prepare event data
- $data = array();
- $data['id'] = $ID;
- $data['mode'] = $mode;
- $data['headers'] = $headers;
- $data['output'] =& $output;
-
- Event::createAndTrigger('ACTION_EXPORT_POSTPROCESS', $data);
-
- if(!empty($data['output'])) {
- if(is_array($data['headers'])) foreach($data['headers'] as $key => $val) {
- header("$key: $val");
- }
- print $pre . $data['output'] . $post;
- exit;
- }
-
- throw new ActionAbort();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Index.php b/snippets/dokuwiki-2023-04-04/inc/Action/Index.php
deleted file mode 100644
index 17ef6b7..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Index.php
+++ /dev/null
@@ -1,29 +0,0 @@
-show();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Locked.php b/snippets/dokuwiki-2023-04-04/inc/Action/Locked.php
deleted file mode 100644
index bb84373..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Locked.php
+++ /dev/null
@@ -1,56 +0,0 @@
-showBanner();
- (new Ui\Editor)->show();
- }
-
- /**
- * Display error on locked pages
- *
- * @author Andreas Gohr
- *
- * @return void
- */
- public function showBanner()
- {
- global $ID;
- global $conf;
- global $lang;
- global $INFO;
-
- $locktime = filemtime(wikiLockFN($ID));
- $expire = dformat($locktime + $conf['locktime']);
- $min = round(($conf['locktime'] - (time() - $locktime) )/60);
-
- // print intro
- print p_locale_xhtml('locked');
-
- print '';
- print '- '.$lang['lockedby'].' '.editorinfo($INFO['locked']).'
';
- print '- '.$lang['lockexpire'].' '.$expire.' ('.$min.' min)
';
- print '
'.DOKU_LF;
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Login.php b/snippets/dokuwiki-2023-04-04/inc/Action/Login.php
deleted file mode 100644
index 6b553f3..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Login.php
+++ /dev/null
@@ -1,40 +0,0 @@
-server->has('REMOTE_USER')) {
- // nothing to do
- throw new ActionException();
- }
- }
-
- /** @inheritdoc */
- public function tplContent()
- {
- (new Ui\Login)->show();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Logout.php b/snippets/dokuwiki-2023-04-04/inc/Action/Logout.php
deleted file mode 100644
index d9aead5..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Logout.php
+++ /dev/null
@@ -1,53 +0,0 @@
-canDo('logout')) throw new ActionDisabledException();
- }
-
- /** @inheritdoc */
- public function preProcess() {
- global $ID;
- global $INPUT;
-
- if (!checkSecurityToken()) throw new ActionException();
-
- // when logging out during an edit session, unlock the page
- $lockedby = checklock($ID);
- if($lockedby == $INPUT->server->str('REMOTE_USER')) {
- unlock($ID);
- }
-
- // do the logout stuff and redirect to login
- auth_logoff();
- send_redirect(wl($ID, array('do' => 'login'), true, '&'));
-
- // should never be reached
- throw new ActionException('login');
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Media.php b/snippets/dokuwiki-2023-04-04/inc/Action/Media.php
deleted file mode 100644
index 77a2a6f..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Media.php
+++ /dev/null
@@ -1,24 +0,0 @@
-actionname);
- if($evt->advise_before()) {
- msg('Failed to handle action: ' . hsc($this->actionname), -1);
- }
- $evt->advise_after();
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Preview.php b/snippets/dokuwiki-2023-04-04/inc/Action/Preview.php
deleted file mode 100644
index dfe5afa..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Preview.php
+++ /dev/null
@@ -1,47 +0,0 @@
-savedraft();
- parent::preProcess();
- }
-
- /** @inheritdoc */
- public function tplContent()
- {
- global $TEXT;
- (new Ui\Editor)->show();
- (new Ui\PageView($TEXT))->show();
- }
-
- /**
- * Saves a draft on preview
- */
- protected function savedraft()
- {
- global $ID, $INFO;
- $draft = new \dokuwiki\Draft($ID, $INFO['client']);
- if (!$draft->saveDraft()) {
- $errors = $draft->getErrors();
- foreach ($errors as $error) {
- msg(hsc($error), -1);
- }
- }
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Profile.php b/snippets/dokuwiki-2023-04-04/inc/Action/Profile.php
deleted file mode 100644
index 0ffcb26..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Profile.php
+++ /dev/null
@@ -1,51 +0,0 @@
-canDo('Profile')) throw new ActionDisabledException();
- }
-
- /** @inheritdoc */
- public function preProcess()
- {
- global $lang;
- if (updateprofile()) {
- msg($lang['profchanged'], 1);
- throw new ActionAbort('show');
- }
- }
-
- /** @inheritdoc */
- public function tplContent()
- {
- (new Ui\UserProfile)->show();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/ProfileDelete.php b/snippets/dokuwiki-2023-04-04/inc/Action/ProfileDelete.php
deleted file mode 100644
index d8e4340..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/ProfileDelete.php
+++ /dev/null
@@ -1,43 +0,0 @@
-canDo('delUser')) throw new ActionDisabledException();
- }
-
- /** @inheritdoc */
- public function preProcess() {
- global $lang;
- if(auth_deleteprofile()) {
- msg($lang['profdeleted'], 1);
- throw new ActionAbort('show');
- } else {
- throw new ActionAbort('profile');
- }
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Recent.php b/snippets/dokuwiki-2023-04-04/inc/Action/Recent.php
deleted file mode 100644
index 203c91d..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Recent.php
+++ /dev/null
@@ -1,45 +0,0 @@
-str('show_changes');
- if (!empty($show_changes)) {
- set_doku_pref('show_changes', $show_changes);
- $this->showType = $show_changes;
- } else {
- $this->showType = get_doku_pref('show_changes', 'both');
- }
- }
-
- /** @inheritdoc */
- public function tplContent()
- {
- global $INPUT;
- (new Ui\Recent($INPUT->extract('first')->int('first'), $this->showType))->show();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Recover.php b/snippets/dokuwiki-2023-04-04/inc/Action/Recover.php
deleted file mode 100644
index c0e7446..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Recover.php
+++ /dev/null
@@ -1,24 +0,0 @@
- $ID,
- 'preact' => $ACT
- );
- //get section name when coming from section edit
- if($INPUT->has('hid')) {
- // Use explicitly transmitted header id
- $opts['fragment'] = $INPUT->str('hid');
- } else if($PRE && preg_match('/^\s*==+([^=\n]+)/', $TEXT, $match)) {
- // Fallback to old mechanism
- $check = false; //Byref
- $opts['fragment'] = sectionID($match[0], $check);
- }
-
- // execute the redirect
- Event::createAndTrigger('ACTION_SHOW_REDIRECT', $opts, array($this, 'redirect'));
-
- // should never be reached
- throw new ActionAbort('show');
- }
-
- /**
- * Execute the redirect
- *
- * Default action for ACTION_SHOW_REDIRECT
- *
- * @param array $opts id and fragment for the redirect and the preact
- */
- public function redirect($opts) {
- $go = wl($opts['id'], '', true, '&');
- if(isset($opts['fragment'])) $go .= '#' . $opts['fragment'];
-
- //show it
- send_redirect($go);
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Register.php b/snippets/dokuwiki-2023-04-04/inc/Action/Register.php
deleted file mode 100644
index 4c3da19..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Register.php
+++ /dev/null
@@ -1,51 +0,0 @@
-canDo('addUser')) throw new ActionDisabledException();
- }
-
- /** @inheritdoc */
- public function preProcess()
- {
- if (register()) { // FIXME could be moved from auth to here
- throw new ActionAbort('login');
- }
- }
-
- /** @inheritdoc */
- public function tplContent()
- {
- (new Ui\UserRegister)->show();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Resendpwd.php b/snippets/dokuwiki-2023-04-04/inc/Action/Resendpwd.php
deleted file mode 100644
index 5af02a9..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Resendpwd.php
+++ /dev/null
@@ -1,185 +0,0 @@
-canDo('modPass')) throw new ActionDisabledException();
- }
-
- /** @inheritdoc */
- public function preProcess()
- {
- if ($this->resendpwd()) {
- throw new ActionAbort('login');
- }
- }
-
- /** @inheritdoc */
- public function tplContent()
- {
- (new Ui\UserResendPwd)->show();
- }
-
- /**
- * Send a new password
- *
- * This function handles both phases of the password reset:
- *
- * - handling the first request of password reset
- * - validating the password reset auth token
- *
- * @author Benoit Chesneau
- * @author Chris Smith
- * @author Andreas Gohr
- * @fixme this should be split up into multiple methods
- * @return bool true on success, false on any error
- */
- protected function resendpwd()
- {
- global $lang;
- global $conf;
- /* @var AuthPlugin $auth */
- global $auth;
- global $INPUT;
-
- if (!actionOK('resendpwd')) {
- msg($lang['resendna'], -1);
- return false;
- }
-
- $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth'));
-
- if ($token) {
- // we're in token phase - get user info from token
-
- $tfile = $conf['cachedir'] .'/'. $token[0] .'/'. $token . '.pwauth';
- if (!file_exists($tfile)) {
- msg($lang['resendpwdbadauth'], -1);
- $INPUT->remove('pwauth');
- return false;
- }
- // token is only valid for 3 days
- if ((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) {
- msg($lang['resendpwdbadauth'], -1);
- $INPUT->remove('pwauth');
- @unlink($tfile);
- return false;
- }
-
- $user = io_readfile($tfile);
- $userinfo = $auth->getUserData($user, $requireGroups = false);
- if (!$userinfo['mail']) {
- msg($lang['resendpwdnouser'], -1);
- return false;
- }
-
- if (!$conf['autopasswd']) { // we let the user choose a password
- $pass = $INPUT->str('pass');
-
- // password given correctly?
- if (!$pass) return false;
- if ($pass != $INPUT->str('passchk')) {
- msg($lang['regbadpass'], -1);
- return false;
- }
-
- // change it
- if (!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
- msg($lang['proffail'], -1);
- return false;
- }
-
- } else { // autogenerate the password and send by mail
-
- $pass = auth_pwgen($user);
- if (!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
- msg($lang['proffail'], -1);
- return false;
- }
-
- if (auth_sendPassword($user, $pass)) {
- msg($lang['resendpwdsuccess'], 1);
- } else {
- msg($lang['regmailfail'], -1);
- }
- }
-
- @unlink($tfile);
- return true;
-
- } else {
- // we're in request phase
-
- if (!$INPUT->post->bool('save')) return false;
-
- if (!$INPUT->post->str('login')) {
- msg($lang['resendpwdmissing'], -1);
- return false;
- } else {
- $user = trim($auth->cleanUser($INPUT->post->str('login')));
- }
-
- $userinfo = $auth->getUserData($user, $requireGroups = false);
- if (!$userinfo['mail']) {
- msg($lang['resendpwdnouser'], -1);
- return false;
- }
-
- // generate auth token
- $token = md5(auth_randombytes(16)); // random secret
- $tfile = $conf['cachedir'] .'/'. $token[0] .'/'. $token .'.pwauth';
- $url = wl('', array('do' => 'resendpwd', 'pwauth' => $token), true, '&');
-
- io_saveFile($tfile, $user);
-
- $text = rawLocale('pwconfirm');
- $trep = array(
- 'FULLNAME' => $userinfo['name'],
- 'LOGIN' => $user,
- 'CONFIRM' => $url
- );
-
- $mail = new \Mailer();
- $mail->to($userinfo['name'] .' <'. $userinfo['mail'] .'>');
- $mail->subject($lang['regpwmail']);
- $mail->setBody($text, $trep);
- if ($mail->send()) {
- msg($lang['resendpwdconfirm'], 1);
- } else {
- msg($lang['regmailfail'], -1);
- }
- return true;
- }
- // never reached
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Revert.php b/snippets/dokuwiki-2023-04-04/inc/Action/Revert.php
deleted file mode 100644
index b7ee753..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Revert.php
+++ /dev/null
@@ -1,63 +0,0 @@
- redirect -> show
- throw new ActionAbort('draftdel');
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Revisions.php b/snippets/dokuwiki-2023-04-04/inc/Action/Revisions.php
deleted file mode 100644
index 511a0dc..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Revisions.php
+++ /dev/null
@@ -1,28 +0,0 @@
-show($INPUT->int('first', -1));
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Save.php b/snippets/dokuwiki-2023-04-04/inc/Action/Save.php
deleted file mode 100644
index a577e37..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Save.php
+++ /dev/null
@@ -1,63 +0,0 @@
- $DATE
- ) {
- throw new ActionException('conflict');
- }
-
- //save it
- saveWikiText($ID, con($PRE, $TEXT, $SUF, true), $SUM, $INPUT->bool('minor')); //use pretty mode for con
- //unlock it
- unlock($ID);
-
- // continue with draftdel -> redirect -> show
- throw new ActionAbort('draftdel');
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Search.php b/snippets/dokuwiki-2023-04-04/inc/Action/Search.php
deleted file mode 100644
index 88bd0ba..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Search.php
+++ /dev/null
@@ -1,135 +0,0 @@
-has('q')) {
- parse_str($INPUT->server->str('QUERY_STRING'), $urlParts);
- $urlParts['q'] = $urlParts['id'];
- unset($urlParts['id']);
- $url = wl($ID, $urlParts, true, '&');
- send_redirect($url);
- }
-
- if ($s === '') throw new ActionAbort();
- $this->adjustGlobalQuery();
- }
-
- /** @inheritdoc */
- public function tplContent()
- {
- $this->execute();
-
- $search = new \dokuwiki\Ui\Search($this->pageLookupResults, $this->fullTextResults, $this->highlight);
- $search->show();
- }
-
-
- /**
- * run the search
- */
- protected function execute()
- {
- global $INPUT, $QUERY;
- $after = $INPUT->str('min');
- $before = $INPUT->str('max');
- $this->pageLookupResults = ft_pageLookup($QUERY, true, useHeading('navigation'), $after, $before);
- $this->fullTextResults = ft_pageSearch($QUERY, $highlight, $INPUT->str('srt'), $after, $before);
- $this->highlight = $highlight;
- }
-
- /**
- * Adjust the global query accordingly to the config search_nslimit and search_fragment
- *
- * This will only do something if the search didn't originate from the form on the searchpage itself
- */
- protected function adjustGlobalQuery()
- {
- global $conf, $INPUT, $QUERY, $ID;
-
- if ($INPUT->bool('sf')) {
- return;
- }
-
- $Indexer = idx_get_indexer();
- $parsedQuery = ft_queryParser($Indexer, $QUERY);
-
- if (empty($parsedQuery['ns']) && empty($parsedQuery['notns'])) {
- if ($conf['search_nslimit'] > 0) {
- if (getNS($ID) !== false) {
- $nsParts = explode(':', getNS($ID));
- $ns = implode(':', array_slice($nsParts, 0, $conf['search_nslimit']));
- $QUERY .= " @$ns";
- }
- }
- }
-
- if ($conf['search_fragment'] !== 'exact') {
- if (empty(array_diff($parsedQuery['words'], $parsedQuery['and']))) {
- if (strpos($QUERY, '*') === false) {
- $queryParts = explode(' ', $QUERY);
- $queryParts = array_map(function ($part) {
- if (strpos($part, '@') === 0) {
- return $part;
- }
- if (strpos($part, 'ns:') === 0) {
- return $part;
- }
- if (strpos($part, '^') === 0) {
- return $part;
- }
- if (strpos($part, '-ns:') === 0) {
- return $part;
- }
-
- global $conf;
-
- if ($conf['search_fragment'] === 'starts_with') {
- return $part . '*';
- }
- if ($conf['search_fragment'] === 'ends_with') {
- return '*' . $part;
- }
-
- return '*' . $part . '*';
-
- }, $queryParts);
- $QUERY = implode(' ', $queryParts);
- }
- }
- }
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Show.php b/snippets/dokuwiki-2023-04-04/inc/Action/Show.php
deleted file mode 100644
index 14da7fd..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Show.php
+++ /dev/null
@@ -1,40 +0,0 @@
-show();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Sitemap.php b/snippets/dokuwiki-2023-04-04/inc/Action/Sitemap.php
deleted file mode 100644
index eba9c28..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Sitemap.php
+++ /dev/null
@@ -1,67 +0,0 @@
-
- * @throws FatalException
- * @inheritdoc
- */
- public function preProcess() {
- global $conf;
-
- if($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) {
- throw new FatalException('Sitemap generation is disabled', 404);
- }
-
- $sitemap = Mapper::getFilePath();
- if(Mapper::sitemapIsCompressed()) {
- $mime = 'application/x-gzip';
- } else {
- $mime = 'application/xml; charset=utf-8';
- }
-
- // Check if sitemap file exists, otherwise create it
- if(!is_readable($sitemap)) {
- Mapper::generate();
- }
-
- if(is_readable($sitemap)) {
- // Send headers
- header('Content-Type: ' . $mime);
- header('Content-Disposition: attachment; filename=' . PhpString::basename($sitemap));
-
- http_conditionalRequest(filemtime($sitemap));
-
- // Send file
- //use x-sendfile header to pass the delivery to compatible webservers
- http_sendfile($sitemap);
-
- readfile($sitemap);
- exit;
- }
-
- throw new FatalException('Could not read the sitemap file - bad permissions?');
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Source.php b/snippets/dokuwiki-2023-04-04/inc/Action/Source.php
deleted file mode 100644
index 92b3855..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Source.php
+++ /dev/null
@@ -1,41 +0,0 @@
-show();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Action/Subscribe.php b/snippets/dokuwiki-2023-04-04/inc/Action/Subscribe.php
deleted file mode 100644
index 5aa3cf1..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Action/Subscribe.php
+++ /dev/null
@@ -1,176 +0,0 @@
-handleSubscribeData();
- } catch (ActionAbort $e) {
- throw $e;
- } catch (Exception $e) {
- msg($e->getMessage(), -1);
- }
- }
-
- /** @inheritdoc */
- public function tplContent()
- {
- (new Ui\Subscribe)->show();
- }
-
- /**
- * Handle page 'subscribe'
- *
- * @author Adrian Lang
- * @throws Exception if (un)subscribing fails
- * @throws ActionAbort when (un)subscribing worked
- */
- protected function handleSubscribeData()
- {
- global $lang;
- global $INFO;
- global $INPUT;
-
- // get and preprocess data.
- $params = array();
- foreach (array('target', 'style', 'action') as $param) {
- if ($INPUT->has("sub_$param")) {
- $params[$param] = $INPUT->str("sub_$param");
- }
- }
-
- // any action given? if not just return and show the subscription page
- if (empty($params['action']) || !checkSecurityToken()) return;
-
- // Handle POST data, may throw exception.
- Event::createAndTrigger('ACTION_HANDLE_SUBSCRIBE', $params, array($this, 'handlePostData'));
-
- $target = $params['target'];
- $style = $params['style'];
- $action = $params['action'];
-
- // Perform action.
- $subManager = new SubscriberManager();
- if ($action === 'unsubscribe') {
- $ok = $subManager->remove($target, $INPUT->server->str('REMOTE_USER'), $style);
- } else {
- $ok = $subManager->add($target, $INPUT->server->str('REMOTE_USER'), $style);
- }
-
- if ($ok) {
- msg(
- sprintf(
- $lang["subscr_{$action}_success"], hsc($INFO['userinfo']['name']),
- prettyprint_id($target)
- ), 1
- );
- throw new ActionAbort('redirect');
- }
-
- throw new Exception(
- sprintf(
- $lang["subscr_{$action}_error"],
- hsc($INFO['userinfo']['name']),
- prettyprint_id($target)
- )
- );
- }
-
- /**
- * Validate POST data
- *
- * Validates POST data for a subscribe or unsubscribe request. This is the
- * default action for the event ACTION_HANDLE_SUBSCRIBE.
- *
- * @author Adrian Lang
- *
- * @param array &$params the parameters: target, style and action
- * @throws Exception
- */
- public function handlePostData(&$params)
- {
- global $INFO;
- global $lang;
- global $INPUT;
-
- // Get and validate parameters.
- if (!isset($params['target'])) {
- throw new Exception('no subscription target given');
- }
- $target = $params['target'];
- $valid_styles = array('every', 'digest');
- if (substr($target, -1, 1) === ':') {
- // Allow “list†subscribe style since the target is a namespace.
- $valid_styles[] = 'list';
- }
- $style = valid_input_set(
- 'style', $valid_styles, $params,
- 'invalid subscription style given'
- );
- $action = valid_input_set(
- 'action', array('subscribe', 'unsubscribe'),
- $params, 'invalid subscription action given'
- );
-
- // Check other conditions.
- if ($action === 'subscribe') {
- if ($INFO['userinfo']['mail'] === '') {
- throw new Exception($lang['subscr_subscribe_noaddress']);
- }
- } elseif ($action === 'unsubscribe') {
- $is = false;
- foreach ($INFO['subscribed'] as $subscr) {
- if ($subscr['target'] === $target) {
- $is = true;
- }
- }
- if ($is === false) {
- throw new Exception(
- sprintf(
- $lang['subscr_not_subscribed'],
- $INPUT->server->str('REMOTE_USER'),
- prettyprint_id($target)
- )
- );
- }
- // subscription_set deletes a subscription if style = null.
- $style = null;
- }
-
- $params = compact('target', 'style', 'action');
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/ActionRouter.php b/snippets/dokuwiki-2023-04-04/inc/ActionRouter.php
deleted file mode 100644
index 300a56c..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/ActionRouter.php
+++ /dev/null
@@ -1,229 +0,0 @@
-disabled = explode(',', $conf['disableactions']);
- $this->disabled = array_map('trim', $this->disabled);
- $this->transitions = 0;
-
- $ACT = act_clean($ACT);
- $this->setupAction($ACT);
- $ACT = $this->action->getActionName();
- }
-
- /**
- * Get the singleton instance
- *
- * @param bool $reinit
- * @return ActionRouter
- */
- public static function getInstance($reinit = false) {
- if((self::$instance === null) || $reinit) {
- self::$instance = new ActionRouter();
- }
- return self::$instance;
- }
-
- /**
- * Setup the given action
- *
- * Instantiates the right class, runs permission checks and pre-processing and
- * sets $action
- *
- * @param string $actionname this is passed as a reference to $ACT, for plugin backward compatibility
- * @triggers ACTION_ACT_PREPROCESS
- */
- protected function setupAction(&$actionname) {
- $presetup = $actionname;
-
- try {
- // give plugins an opportunity to process the actionname
- $evt = new Extension\Event('ACTION_ACT_PREPROCESS', $actionname);
- if ($evt->advise_before()) {
- $this->action = $this->loadAction($actionname);
- $this->checkAction($this->action);
- $this->action->preProcess();
- } else {
- // event said the action should be kept, assume action plugin will handle it later
- $this->action = new Plugin($actionname);
- }
- $evt->advise_after();
-
- } catch(ActionException $e) {
- // we should have gotten a new action
- $actionname = $e->getNewAction();
-
- // this one should trigger a user message
- if(is_a($e, ActionDisabledException::class)) {
- msg('Action disabled: ' . hsc($presetup), -1);
- }
-
- // some actions may request the display of a message
- if($e->displayToUser()) {
- msg(hsc($e->getMessage()), -1);
- }
-
- // do setup for new action
- $this->transitionAction($presetup, $actionname);
-
- } catch(NoActionException $e) {
- msg('Action unknown: ' . hsc($actionname), -1);
- $actionname = 'show';
- $this->transitionAction($presetup, $actionname);
- } catch(\Exception $e) {
- $this->handleFatalException($e);
- }
- }
-
- /**
- * Transitions from one action to another
- *
- * Basically just calls setupAction() again but does some checks before.
- *
- * @param string $from current action name
- * @param string $to new action name
- * @param null|ActionException $e any previous exception that caused the transition
- */
- protected function transitionAction($from, $to, $e = null) {
- $this->transitions++;
-
- // no infinite recursion
- if($from == $to) {
- $this->handleFatalException(new FatalException('Infinite loop in actions', 500, $e));
- }
-
- // larger loops will be caught here
- if($this->transitions >= self::MAX_TRANSITIONS) {
- $this->handleFatalException(new FatalException('Maximum action transitions reached', 500, $e));
- }
-
- // do the recursion
- $this->setupAction($to);
- }
-
- /**
- * Aborts all processing with a message
- *
- * When a FataException instanc is passed, the code is treated as Status code
- *
- * @param \Exception|FatalException $e
- * @throws FatalException during unit testing
- */
- protected function handleFatalException(\Exception $e) {
- if(is_a($e, FatalException::class)) {
- http_status($e->getCode());
- } else {
- http_status(500);
- }
- if(defined('DOKU_UNITTEST')) {
- throw $e;
- }
- ErrorHandler::logException($e);
- $msg = 'Something unforeseen has happened: ' . $e->getMessage();
- nice_die(hsc($msg));
- }
-
- /**
- * Load the given action
- *
- * This translates the given name to a class name by uppercasing the first letter.
- * Underscores translate to camelcase names. For actions with underscores, the different
- * parts are removed beginning from the end until a matching class is found. The instatiated
- * Action will always have the full original action set as Name
- *
- * Example: 'export_raw' -> ExportRaw then 'export' -> 'Export'
- *
- * @param $actionname
- * @return AbstractAction
- * @throws NoActionException
- */
- public function loadAction($actionname) {
- $actionname = strtolower($actionname); // FIXME is this needed here? should we run a cleanup somewhere else?
- $parts = explode('_', $actionname);
- while(!empty($parts)) {
- $load = join('_', $parts);
- $class = 'dokuwiki\\Action\\' . str_replace('_', '', ucwords($load, '_'));
- if(class_exists($class)) {
- return new $class($actionname);
- }
- array_pop($parts);
- }
-
- throw new NoActionException();
- }
-
- /**
- * Execute all the checks to see if this action can be executed
- *
- * @param AbstractAction $action
- * @throws ActionDisabledException
- * @throws ActionException
- */
- public function checkAction(AbstractAction $action) {
- global $INFO;
- global $ID;
-
- if(in_array($action->getActionName(), $this->disabled)) {
- throw new ActionDisabledException();
- }
-
- $action->checkPreconditions();
-
- if(isset($INFO)) {
- $perm = $INFO['perm'];
- } else {
- $perm = auth_quickaclcheck($ID);
- }
-
- if($perm < $action->minimumPermission()) {
- throw new ActionException('denied');
- }
- }
-
- /**
- * Returns the action handling the current request
- *
- * @return AbstractAction
- */
- public function getAction() {
- return $this->action;
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Ajax.php b/snippets/dokuwiki-2023-04-04/inc/Ajax.php
deleted file mode 100644
index fd6abb5..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Ajax.php
+++ /dev/null
@@ -1,448 +0,0 @@
-$callfn();
- } else {
- $evt = new Extension\Event('AJAX_CALL_UNKNOWN', $call);
- if($evt->advise_before()) {
- print "AJAX call '" . hsc($call) . "' unknown!\n";
- } else {
- $evt->advise_after();
- unset($evt);
- }
- }
- }
-
- /**
- * Searches for matching pagenames
- *
- * @author Andreas Gohr
- */
- protected function callQsearch() {
- global $lang;
- global $INPUT;
-
- $maxnumbersuggestions = 50;
-
- $query = $INPUT->post->str('q');
- if(empty($query)) $query = $INPUT->get->str('q');
- if(empty($query)) return;
-
- $query = urldecode($query);
-
- $data = ft_pageLookup($query, true, useHeading('navigation'));
-
- if(!count($data)) return;
-
- print '' . $lang['quickhits'] . '';
- print '';
- $counter = 0;
- foreach($data as $id => $title) {
- if(useHeading('navigation')) {
- $name = $title;
- } else {
- $ns = getNS($id);
- if($ns) {
- $name = noNS($id) . ' (' . $ns . ')';
- } else {
- $name = $id;
- }
- }
- echo '- ' . html_wikilink(':' . $id, $name) . '
';
-
- $counter++;
- if($counter > $maxnumbersuggestions) {
- echo '- ...
';
- break;
- }
- }
- print '
';
- }
-
- /**
- * Support OpenSearch suggestions
- *
- * @link http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0
- * @author Mike Frysinger
- */
- protected function callSuggestions() {
- global $INPUT;
-
- $query = cleanID($INPUT->post->str('q'));
- if(empty($query)) $query = cleanID($INPUT->get->str('q'));
- if(empty($query)) return;
-
- $data = ft_pageLookup($query);
- if(!count($data)) return;
- $data = array_keys($data);
-
- // limit results to 15 hits
- $data = array_slice($data, 0, 15);
- $data = array_map('trim', $data);
- $data = array_map('noNS', $data);
- $data = array_unique($data);
- Sort::sort($data);
-
- /* now construct a json */
- $suggestions = array(
- $query, // the original query
- $data, // some suggestions
- array(), // no description
- array() // no urls
- );
-
- header('Content-Type: application/x-suggestions+json');
- print json_encode($suggestions);
- }
-
- /**
- * Refresh a page lock and save draft
- *
- * Andreas Gohr
- */
- protected function callLock() {
- global $ID;
- global $INFO;
- global $INPUT;
-
- $ID = cleanID($INPUT->post->str('id'));
- if(empty($ID)) return;
-
- $INFO = pageinfo();
-
- $response = [
- 'errors' => [],
- 'lock' => '0',
- 'draft' => '',
- ];
- if(!$INFO['writable']) {
- $response['errors'][] = 'Permission to write this page has been denied.';
- echo json_encode($response);
- return;
- }
-
- if(!checklock($ID)) {
- lock($ID);
- $response['lock'] = '1';
- }
-
- $draft = new Draft($ID, $INFO['client']);
- if ($draft->saveDraft()) {
- $response['draft'] = $draft->getDraftMessage();
- } else {
- $response['errors'] = array_merge($response['errors'], $draft->getErrors());
- }
- echo json_encode($response);
- }
-
- /**
- * Delete a draft
- *
- * @author Andreas Gohr
- */
- protected function callDraftdel() {
- global $INPUT;
- $id = cleanID($INPUT->str('id'));
- if(empty($id)) return;
-
- $client = $INPUT->server->str('REMOTE_USER');
- if(!$client) $client = clientIP(true);
-
- $draft = new Draft($id, $client);
- if ($draft->isDraftAvailable() && checkSecurityToken()) {
- $draft->deleteDraft();
- }
- }
-
- /**
- * Return subnamespaces for the Mediamanager
- *
- * @author Andreas Gohr
- */
- protected function callMedians() {
- global $conf;
- global $INPUT;
-
- // wanted namespace
- $ns = cleanID($INPUT->post->str('ns'));
- $dir = utf8_encodeFN(str_replace(':', '/', $ns));
-
- $lvl = count(explode(':', $ns));
-
- $data = array();
- search($data, $conf['mediadir'], 'search_index', array('nofiles' => true), $dir);
- foreach(array_keys($data) as $item) {
- $data[$item]['level'] = $lvl + 1;
- }
- echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li');
- }
-
- /**
- * Return list of files for the Mediamanager
- *
- * @author Andreas Gohr
- */
- protected function callMedialist() {
- global $NS;
- global $INPUT;
-
- $NS = cleanID($INPUT->post->str('ns'));
- $sort = $INPUT->post->bool('recent') ? 'date' : 'natural';
- if($INPUT->post->str('do') == 'media') {
- tpl_mediaFileList();
- } else {
- tpl_mediaContent(true, $sort);
- }
- }
-
- /**
- * Return the content of the right column
- * (image details) for the Mediamanager
- *
- * @author Kate Arzamastseva
- */
- protected function callMediadetails() {
- global $IMG, $JUMPTO, $REV, $fullscreen, $INPUT;
- $fullscreen = true;
- require_once(DOKU_INC . 'lib/exe/mediamanager.php');
-
- $image = '';
- if($INPUT->has('image')) $image = cleanID($INPUT->str('image'));
- if(isset($IMG)) $image = $IMG;
- if(isset($JUMPTO)) $image = $JUMPTO;
- $rev = false;
- if(isset($REV) && !$JUMPTO) $rev = $REV;
-
- html_msgarea();
- tpl_mediaFileDetails($image, $rev);
- }
-
- /**
- * Returns image diff representation for mediamanager
- *
- * @author Kate Arzamastseva
- */
- protected function callMediadiff() {
- global $INPUT;
-
- $image = '';
- if($INPUT->has('image')) $image = cleanID($INPUT->str('image'));
- (new Ui\MediaDiff($image))->preference('fromAjax', true)->show();
- }
-
- /**
- * Manages file uploads
- *
- * @author Kate Arzamastseva
- */
- protected function callMediaupload() {
- global $NS, $MSG, $INPUT;
-
- $id = '';
- if(isset($_FILES['qqfile']['tmp_name'])) {
- $id = $INPUT->post->str('mediaid', $_FILES['qqfile']['name']);
- } elseif($INPUT->get->has('qqfile')) {
- $id = $INPUT->get->str('qqfile');
- }
-
- $id = cleanID($id);
-
- $NS = $INPUT->str('ns');
- $ns = $NS . ':' . getNS($id);
-
- $AUTH = auth_quickaclcheck("$ns:*");
- if($AUTH >= AUTH_UPLOAD) {
- io_createNamespace("$ns:xxx", 'media');
- }
-
- if(isset($_FILES['qqfile']['error']) && $_FILES['qqfile']['error']) unset($_FILES['qqfile']);
-
- $res = false;
- if(isset($_FILES['qqfile']['tmp_name'])) $res = media_upload($NS, $AUTH, $_FILES['qqfile']);
- if($INPUT->get->has('qqfile')) $res = media_upload_xhr($NS, $AUTH);
-
- if($res) {
- $result = array(
- 'success' => true,
- 'link' => media_managerURL(array('ns' => $ns, 'image' => $NS . ':' . $id), '&'),
- 'id' => $NS . ':' . $id,
- 'ns' => $NS
- );
- } else {
- $error = '';
- if(isset($MSG)) {
- foreach($MSG as $msg) {
- $error .= $msg['msg'];
- }
- }
- $result = array(
- 'error' => $error,
- 'ns' => $NS
- );
- }
-
- header('Content-Type: application/json');
- echo json_encode($result);
- }
-
- /**
- * Return sub index for index view
- *
- * @author Andreas Gohr
- */
- protected function callIndex() {
- global $conf;
- global $INPUT;
-
- // wanted namespace
- $ns = cleanID($INPUT->post->str('idx'));
- $dir = utf8_encodeFN(str_replace(':', '/', $ns));
-
- $lvl = count(explode(':', $ns));
-
- $data = array();
- search($data, $conf['datadir'], 'search_index', array('ns' => $ns), $dir);
- foreach (array_keys($data) as $item) {
- $data[$item]['level'] = $lvl + 1;
- }
- $idx = new Ui\Index;
- echo html_buildlist($data, 'idx', [$idx,'formatListItem'], [$idx,'tagListItem']);
- }
-
- /**
- * List matching namespaces and pages for the link wizard
- *
- * @author Andreas Gohr
- */
- protected function callLinkwiz() {
- global $conf;
- global $lang;
- global $INPUT;
-
- $q = ltrim(trim($INPUT->post->str('q')), ':');
- $id = noNS($q);
- $ns = getNS($q);
-
- $ns = cleanID($ns);
- $id = cleanID($id);
-
- $nsd = utf8_encodeFN(str_replace(':', '/', $ns));
-
- $data = array();
- if($q !== '' && $ns === '') {
-
- // use index to lookup matching pages
- $pages = ft_pageLookup($id, true);
-
- // If 'useheading' option is 'always' or 'content',
- // search page titles with original query as well.
- if ($conf['useheading'] == '1' || $conf['useheading'] == 'content') {
- $pages = array_merge($pages, ft_pageLookup($q, true, true));
- asort($pages, SORT_STRING);
- }
-
- // result contains matches in pages and namespaces
- // we now extract the matching namespaces to show
- // them seperately
- $dirs = array();
-
- foreach($pages as $pid => $title) {
- if(strpos(getNS($pid), $id) !== false) {
- // match was in the namespace
- $dirs[getNS($pid)] = 1; // assoc array avoids dupes
- } else {
- // it is a matching page, add it to the result
- $data[] = array(
- 'id' => $pid,
- 'title' => $title,
- 'type' => 'f',
- );
- }
- unset($pages[$pid]);
- }
- foreach($dirs as $dir => $junk) {
- $data[] = array(
- 'id' => $dir,
- 'type' => 'd',
- );
- }
-
- } else {
-
- $opts = array(
- 'depth' => 1,
- 'listfiles' => true,
- 'listdirs' => true,
- 'pagesonly' => true,
- 'firsthead' => true,
- 'sneakyacl' => $conf['sneaky_index'],
- );
- if($id) $opts['filematch'] = '^.*\/' . $id;
- if($id) $opts['dirmatch'] = '^.*\/' . $id;
- search($data, $conf['datadir'], 'search_universal', $opts, $nsd);
-
- // add back to upper
- if($ns) {
- array_unshift(
- $data, array(
- 'id' => getNS($ns),
- 'type' => 'u',
- )
- );
- }
- }
-
- // fixme sort results in a useful way ?
-
- if(!count($data)) {
- echo $lang['nothingfound'];
- exit;
- }
-
- // output the found data
- $even = 1;
- foreach($data as $item) {
- $even *= -1; //zebra
-
- if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id'] !== '') $item['id'] .= ':';
- $link = wl($item['id']);
-
- echo '';
-
- if($item['type'] == 'u') {
- $name = $lang['upperns'];
- } else {
- $name = hsc($item['id']);
- }
-
- echo '' . $name . '';
-
- if(!blank($item['title'])) {
- echo '' . hsc($item['title']) . '';
- }
- echo '';
- }
-
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Cache/Cache.php b/snippets/dokuwiki-2023-04-04/inc/Cache/Cache.php
deleted file mode 100644
index af82e6b..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Cache/Cache.php
+++ /dev/null
@@ -1,240 +0,0 @@
-key = $key;
- $this->ext = $ext;
- $this->cache = getCacheName($key, $ext);
-
- /**
- * @deprecated since 2019-02-02 use the respective getters instead!
- */
- $this->deprecatePublicProperty('_event');
- $this->deprecatePublicProperty('_time');
- $this->deprecatePublicProperty('_nocache');
- }
-
- public function getTime()
- {
- return $this->_time;
- }
-
- public function getEvent()
- {
- return $this->_event;
- }
-
- public function setEvent($event)
- {
- $this->_event = $event;
- }
-
- /**
- * public method to determine whether the cache can be used
- *
- * to assist in centralisation of event triggering and calculation of cache statistics,
- * don't override this function override makeDefaultCacheDecision()
- *
- * @param array $depends array of cache dependencies, support dependecies:
- * 'age' => max age of the cache in seconds
- * 'files' => cache must be younger than mtime of each file
- * (nb. dependency passes if file doesn't exist)
- *
- * @return bool true if cache can be used, false otherwise
- */
- public function useCache($depends = array())
- {
- $this->depends = $depends;
- $this->addDependencies();
-
- if ($this->getEvent()) {
- return $this->stats(
- Event::createAndTrigger(
- $this->getEvent(),
- $this,
- array($this, 'makeDefaultCacheDecision')
- )
- );
- }
-
- return $this->stats($this->makeDefaultCacheDecision());
- }
-
- /**
- * internal method containing cache use decision logic
- *
- * this function processes the following keys in the depends array
- * purge - force a purge on any non empty value
- * age - expire cache if older than age (seconds)
- * files - expire cache if any file in this array was updated more recently than the cache
- *
- * Note that this function needs to be public as it is used as callback for the event handler
- *
- * can be overridden
- *
- * @internal This method may only be called by the event handler! Call \dokuwiki\Cache\Cache::useCache instead!
- *
- * @return bool see useCache()
- */
- public function makeDefaultCacheDecision()
- {
- if ($this->_nocache) {
- return false;
- } // caching turned off
- if (!empty($this->depends['purge'])) {
- return false;
- } // purge requested?
- if (!($this->_time = @filemtime($this->cache))) {
- return false;
- } // cache exists?
-
- // cache too old?
- if (!empty($this->depends['age']) && ((time() - $this->_time) > $this->depends['age'])) {
- return false;
- }
-
- if (!empty($this->depends['files'])) {
- foreach ($this->depends['files'] as $file) {
- if ($this->_time <= @filemtime($file)) {
- return false;
- } // cache older than files it depends on?
- }
- }
-
- return true;
- }
-
- /**
- * add dependencies to the depends array
- *
- * this method should only add dependencies,
- * it should not remove any existing dependencies and
- * it should only overwrite a dependency when the new value is more stringent than the old
- */
- protected function addDependencies()
- {
- global $INPUT;
- if ($INPUT->has('purge')) {
- $this->depends['purge'] = true;
- } // purge requested
- }
-
- /**
- * retrieve the cached data
- *
- * @param bool $clean true to clean line endings, false to leave line endings alone
- * @return string cache contents
- */
- public function retrieveCache($clean = true)
- {
- return io_readFile($this->cache, $clean);
- }
-
- /**
- * cache $data
- *
- * @param string $data the data to be cached
- * @return bool true on success, false otherwise
- */
- public function storeCache($data)
- {
- if ($this->_nocache) {
- return false;
- }
-
- return io_saveFile($this->cache, $data);
- }
-
- /**
- * remove any cached data associated with this cache instance
- */
- public function removeCache()
- {
- @unlink($this->cache);
- }
-
- /**
- * Record cache hits statistics.
- * (Only when debugging allowed, to reduce overhead.)
- *
- * @param bool $success result of this cache use attempt
- * @return bool pass-thru $success value
- */
- protected function stats($success)
- {
- global $conf;
- static $stats = null;
- static $file;
-
- if (!$conf['allowdebug']) {
- return $success;
- }
-
- if (is_null($stats)) {
- $file = $conf['cachedir'] . '/cache_stats.txt';
- $lines = explode("\n", io_readFile($file));
-
- foreach ($lines as $line) {
- $i = strpos($line, ',');
- $stats[substr($line, 0, $i)] = $line;
- }
- }
-
- if (isset($stats[$this->ext])) {
- list($ext, $count, $hits) = explode(',', $stats[$this->ext]);
- } else {
- $ext = $this->ext;
- $count = 0;
- $hits = 0;
- }
-
- $count++;
- if ($success) {
- $hits++;
- }
- $stats[$this->ext] = "$ext,$count,$hits";
-
- io_saveFile($file, join("\n", $stats));
-
- return $success;
- }
-
- /**
- * @return bool
- */
- public function isNoCache()
- {
- return $this->_nocache;
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Cache/CacheImageMod.php b/snippets/dokuwiki-2023-04-04/inc/Cache/CacheImageMod.php
deleted file mode 100644
index 5883f78..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Cache/CacheImageMod.php
+++ /dev/null
@@ -1,56 +0,0 @@
-file = $file;
-
- $this->setEvent('IMAGEMOD_CACHE_USE');
- parent::__construct($file, $fullext);
- }
-
- /** @inheritdoc */
- public function makeDefaultCacheDecision()
- {
- if (!file_exists($this->file)) {
- return false;
- }
- return parent::makeDefaultCacheDecision();
- }
-
- /**
- * Caching depends on the source and the wiki config
- * @inheritdoc
- */
- protected function addDependencies()
- {
- parent::addDependencies();
-
- $this->depends['files'] = array_merge(
- [$this->file],
- getConfigFiles('main')
- );
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Cache/CacheInstructions.php b/snippets/dokuwiki-2023-04-04/inc/Cache/CacheInstructions.php
deleted file mode 100644
index acd02ab..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Cache/CacheInstructions.php
+++ /dev/null
@@ -1,46 +0,0 @@
-cache, false);
- return !empty($contents) ? unserialize($contents) : array();
- }
-
- /**
- * cache $instructions
- *
- * @param array $instructions the instruction to be cached
- * @return bool true on success, false otherwise
- */
- public function storeCache($instructions)
- {
- if ($this->_nocache) {
- return false;
- }
-
- return io_saveFile($this->cache, serialize($instructions));
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Cache/CacheParser.php b/snippets/dokuwiki-2023-04-04/inc/Cache/CacheParser.php
deleted file mode 100644
index 4d8550d..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Cache/CacheParser.php
+++ /dev/null
@@ -1,66 +0,0 @@
-page = $id;
- }
- $this->file = $file;
- $this->mode = $mode;
-
- $this->setEvent('PARSER_CACHE_USE');
- parent::__construct($file . $INPUT->server->str('HTTP_HOST') . $INPUT->server->str('SERVER_PORT'), '.' . $mode);
- }
-
- /**
- * method contains cache use decision logic
- *
- * @return bool see useCache()
- */
- public function makeDefaultCacheDecision()
- {
-
- if (!file_exists($this->file)) {
- return false;
- } // source exists?
- return parent::makeDefaultCacheDecision();
- }
-
- protected function addDependencies()
- {
-
- // parser cache file dependencies ...
- $files = array(
- $this->file, // ... source
- DOKU_INC . 'inc/Parsing/Parser.php', // ... parser
- DOKU_INC . 'inc/parser/handler.php', // ... handler
- );
- $files = array_merge($files, getConfigFiles('main')); // ... wiki settings
-
- $this->depends['files'] = !empty($this->depends['files']) ?
- array_merge($files, $this->depends['files']) :
- $files;
- parent::addDependencies();
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Cache/CacheRenderer.php b/snippets/dokuwiki-2023-04-04/inc/Cache/CacheRenderer.php
deleted file mode 100644
index e8a28c3..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Cache/CacheRenderer.php
+++ /dev/null
@@ -1,94 +0,0 @@
-page)) {
- return true;
- }
-
- // meta cache older than file it depends on?
- if ($this->_time < @filemtime(metaFN($this->page, '.meta'))) {
- return false;
- }
-
- // check current link existence is consistent with cache version
- // first check the purgefile
- // - if the cache is more recent than the purgefile we know no links can have been updated
- if ($this->_time >= @filemtime($conf['cachedir'] . '/purgefile')) {
- return true;
- }
-
- // for wiki pages, check metadata dependencies
- $metadata = p_get_metadata($this->page);
-
- if (!isset($metadata['relation']['references']) ||
- empty($metadata['relation']['references'])) {
- return true;
- }
-
- foreach ($metadata['relation']['references'] as $id => $exists) {
- if ($exists != page_exists($id, '', false)) {
- return false;
- }
- }
-
- return true;
- }
-
- protected function addDependencies()
- {
- global $conf;
-
- // default renderer cache file 'age' is dependent on 'cachetime' setting, two special values:
- // -1 : do not cache (should not be overridden)
- // 0 : cache never expires (can be overridden) - no need to set depends['age']
- if ($conf['cachetime'] == -1) {
- $this->_nocache = true;
- return;
- } elseif ($conf['cachetime'] > 0) {
- $this->depends['age'] = isset($this->depends['age']) ?
- min($this->depends['age'], $conf['cachetime']) : $conf['cachetime'];
- }
-
- // renderer cache file dependencies ...
- $files = array(
- DOKU_INC . 'inc/parser/' . $this->mode . '.php', // ... the renderer
- );
-
- // page implies metadata and possibly some other dependencies
- if (isset($this->page)) {
-
- // for xhtml this will render the metadata if needed
- $valid = p_get_metadata($this->page, 'date valid');
- if (!empty($valid['age'])) {
- $this->depends['age'] = isset($this->depends['age']) ?
- min($this->depends['age'], $valid['age']) : $valid['age'];
- }
- }
-
- $this->depends['files'] = !empty($this->depends['files']) ?
- array_merge($files, $this->depends['files']) :
- $files;
-
- parent::addDependencies();
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/ChangeLog/ChangeLog.php b/snippets/dokuwiki-2023-04-04/inc/ChangeLog/ChangeLog.php
deleted file mode 100644
index b64c24e..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/ChangeLog/ChangeLog.php
+++ /dev/null
@@ -1,678 +0,0 @@
-cache =& $cache_revinfo;
- if (!isset($this->cache[$id])) {
- $this->cache[$id] = array();
- }
-
- $this->id = $id;
- $this->setChunkSize($chunk_size);
- }
-
- /**
- * Returns path to current page/media
- *
- * @return string path to file
- */
- abstract protected function getFilename();
-
- /**
- * Check whether given revision is the current page
- *
- * @param int $rev timestamp of current page
- * @return bool true if $rev is current revision, otherwise false
- */
- public function isCurrentRevision($rev)
- {
- return $rev == $this->currentRevision();
- }
-
- /**
- * Checks if the revision is last revision
- *
- * @param int $rev revision timestamp
- * @return bool true if $rev is last revision, otherwise false
- */
- public function isLastRevision($rev = null)
- {
- return $rev === $this->lastRevision();
- }
-
- /**
- * Return the current revision identifier
- *
- * The "current" revision means current version of the page or media file. It is either
- * identical with or newer than the "last" revision, that depends on whether the file
- * has modified, created or deleted outside of DokuWiki.
- * The value of identifier can be determined by timestamp as far as the file exists,
- * otherwise it must be assigned larger than any other revisions to keep them sortable.
- *
- * @return int|false revision timestamp
- */
- public function currentRevision()
- {
- if (!isset($this->currentRevision)) {
- // set ChangeLog::currentRevision property
- $this->getCurrentRevisionInfo();
- }
- return $this->currentRevision;
- }
-
- /**
- * Return the last revision identifier, date value of the last entry of the changelog
- *
- * @return int|false revision timestamp
- */
- public function lastRevision()
- {
- $revs = $this->getRevisions(-1, 1);
- return empty($revs) ? false : $revs[0];
- }
-
- /**
- * Save revision info to the cache pool
- *
- * @param array $info Revision info structure
- * @return bool
- */
- protected function cacheRevisionInfo($info)
- {
- if (!is_array($info)) return false;
- //$this->cache[$this->id][$info['date']] ??= $info; // since php 7.4
- $this->cache[$this->id][$info['date']] = $this->cache[$this->id][$info['date']] ?? $info;
- return true;
- }
-
- /**
- * Get the changelog information for a specific revision (timestamp)
- *
- * Adjacent changelog lines are optimistically parsed and cached to speed up
- * consecutive calls to getRevisionInfo. For large changelog files, only the chunk
- * containing the requested changelog line is read.
- *
- * @param int $rev revision timestamp
- * @param bool $retrieveCurrentRevInfo allows to skip for getting other revision info in the
- * getCurrentRevisionInfo() where $currentRevision is not yet determined
- * @return bool|array false or array with entries:
- * - date: unix timestamp
- * - ip: IPv4 address (127.0.0.1)
- * - type: log line type
- * - id: page id
- * - user: user name
- * - sum: edit summary (or action reason)
- * - extra: extra data (varies by line type)
- * - sizechange: change of filesize
- *
- * @author Ben Coburn
- * @author Kate Arzamastseva
- */
- public function getRevisionInfo($rev, $retrieveCurrentRevInfo = true)
- {
- $rev = max(0, $rev);
- if (!$rev) return false;
-
- //ensure the external edits are cached as well
- if (!isset($this->currentRevision) && $retrieveCurrentRevInfo) {
- $this->getCurrentRevisionInfo();
- }
-
- // check if it's already in the memory cache
- if (isset($this->cache[$this->id]) && isset($this->cache[$this->id][$rev])) {
- return $this->cache[$this->id][$rev];
- }
-
- //read lines from changelog
- list($fp, $lines) = $this->readloglines($rev);
- if ($fp) {
- fclose($fp);
- }
- if (empty($lines)) return false;
-
- // parse and cache changelog lines
- foreach ($lines as $value) {
- $info = $this->parseLogLine($value);
- $this->cacheRevisionInfo($info);
- }
- if (!isset($this->cache[$this->id][$rev])) {
- return false;
- }
- return $this->cache[$this->id][$rev];
- }
-
- /**
- * Return a list of page revisions numbers
- *
- * Does not guarantee that the revision exists in the attic,
- * only that a line with the date exists in the changelog.
- * By default the current revision is skipped.
- *
- * The current revision is automatically skipped when the page exists.
- * See $INFO['meta']['last_change'] for the current revision.
- * A negative $first let read the current revision too.
- *
- * For efficiency, the log lines are parsed and cached for later
- * calls to getRevisionInfo. Large changelog files are read
- * backwards in chunks until the requested number of changelog
- * lines are received.
- *
- * @param int $first skip the first n changelog lines
- * @param int $num number of revisions to return
- * @return array with the revision timestamps
- *
- * @author Ben Coburn
- * @author Kate Arzamastseva
- */
- public function getRevisions($first, $num)
- {
- $revs = array();
- $lines = array();
- $count = 0;
-
- $logfile = $this->getChangelogFilename();
- if (!file_exists($logfile)) return $revs;
-
- $num = max($num, 0);
- if ($num == 0) {
- return $revs;
- }
-
- if ($first < 0) {
- $first = 0;
- } else {
- $fileLastMod = $this->getFilename();
- if (file_exists($fileLastMod) && $this->isLastRevision(filemtime($fileLastMod))) {
- // skip last revision if the page exists
- $first = max($first + 1, 0);
- }
- }
-
- if (filesize($logfile) < $this->chunk_size || $this->chunk_size == 0) {
- // read whole file
- $lines = file($logfile);
- if ($lines === false) {
- return $revs;
- }
- } else {
- // read chunks backwards
- $fp = fopen($logfile, 'rb'); // "file pointer"
- if ($fp === false) {
- return $revs;
- }
- fseek($fp, 0, SEEK_END);
- $tail = ftell($fp);
-
- // chunk backwards
- $finger = max($tail - $this->chunk_size, 0);
- while ($count < $num + $first) {
- $nl = $this->getNewlinepointer($fp, $finger);
-
- // was the chunk big enough? if not, take another bite
- if ($nl > 0 && $tail <= $nl) {
- $finger = max($finger - $this->chunk_size, 0);
- continue;
- } else {
- $finger = $nl;
- }
-
- // read chunk
- $chunk = '';
- $read_size = max($tail - $finger, 0); // found chunk size
- $got = 0;
- while ($got < $read_size && !feof($fp)) {
- $tmp = @fread($fp, max(min($this->chunk_size, $read_size - $got), 0));
- if ($tmp === false) {
- break;
- } //error state
- $got += strlen($tmp);
- $chunk .= $tmp;
- }
- $tmp = explode("\n", $chunk);
- array_pop($tmp); // remove trailing newline
-
- // combine with previous chunk
- $count += count($tmp);
- $lines = array_merge($tmp, $lines);
-
- // next chunk
- if ($finger == 0) {
- break;
- } else { // already read all the lines
- $tail = $finger;
- $finger = max($tail - $this->chunk_size, 0);
- }
- }
- fclose($fp);
- }
-
- // skip parsing extra lines
- $num = max(min(count($lines) - $first, $num), 0);
- if ($first > 0 && $num > 0) {
- $lines = array_slice($lines, max(count($lines) - $first - $num, 0), $num);
- } elseif ($first > 0 && $num == 0) {
- $lines = array_slice($lines, 0, max(count($lines) - $first, 0));
- } elseif ($first == 0 && $num > 0) {
- $lines = array_slice($lines, max(count($lines) - $num, 0));
- }
-
- // handle lines in reverse order
- for ($i = count($lines) - 1; $i >= 0; $i--) {
- $info = $this->parseLogLine($lines[$i]);
- if ($this->cacheRevisionInfo($info)) {
- $revs[] = $info['date'];
- }
- }
-
- return $revs;
- }
-
- /**
- * Get the nth revision left or right-hand side for a specific page id and revision (timestamp)
- *
- * For large changelog files, only the chunk containing the
- * reference revision $rev is read and sometimes a next chunk.
- *
- * Adjacent changelog lines are optimistically parsed and cached to speed up
- * consecutive calls to getRevisionInfo.
- *
- * @param int $rev revision timestamp used as start date
- * (doesn't need to be exact revision number)
- * @param int $direction give position of returned revision with respect to $rev;
- positive=next, negative=prev
- * @return bool|int
- * timestamp of the requested revision
- * otherwise false
- */
- public function getRelativeRevision($rev, $direction)
- {
- $rev = max($rev, 0);
- $direction = (int)$direction;
-
- //no direction given or last rev, so no follow-up
- if (!$direction || ($direction > 0 && $this->isCurrentRevision($rev))) {
- return false;
- }
-
- //get lines from changelog
- list($fp, $lines, $head, $tail, $eof) = $this->readloglines($rev);
- if (empty($lines)) return false;
-
- // look for revisions later/earlier than $rev, when founded count till the wanted revision is reached
- // also parse and cache changelog lines for getRevisionInfo().
- $revCounter = 0;
- $relativeRev = false;
- $checkOtherChunk = true; //always runs once
- while (!$relativeRev && $checkOtherChunk) {
- $info = array();
- //parse in normal or reverse order
- $count = count($lines);
- if ($direction > 0) {
- $start = 0;
- $step = 1;
- } else {
- $start = $count - 1;
- $step = -1;
- }
- for ($i = $start; $i >= 0 && $i < $count; $i = $i + $step) {
- $info = $this->parseLogLine($lines[$i]);
- if ($this->cacheRevisionInfo($info)) {
- //look for revs older/earlier then reference $rev and select $direction-th one
- if (($direction > 0 && $info['date'] > $rev) || ($direction < 0 && $info['date'] < $rev)) {
- $revCounter++;
- if ($revCounter == abs($direction)) {
- $relativeRev = $info['date'];
- }
- }
- }
- }
-
- //true when $rev is found, but not the wanted follow-up.
- $checkOtherChunk = $fp
- && ($info['date'] == $rev || ($revCounter > 0 && !$relativeRev))
- && !(($tail == $eof && $direction > 0) || ($head == 0 && $direction < 0));
-
- if ($checkOtherChunk) {
- list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, $direction);
-
- if (empty($lines)) break;
- }
- }
- if ($fp) {
- fclose($fp);
- }
-
- return $relativeRev;
- }
-
- /**
- * Returns revisions around rev1 and rev2
- * When available it returns $max entries for each revision
- *
- * @param int $rev1 oldest revision timestamp
- * @param int $rev2 newest revision timestamp (0 looks up last revision)
- * @param int $max maximum number of revisions returned
- * @return array with two arrays with revisions surrounding rev1 respectively rev2
- */
- public function getRevisionsAround($rev1, $rev2, $max = 50)
- {
- $max = intval(abs($max) / 2) * 2 + 1;
- $rev1 = max($rev1, 0);
- $rev2 = max($rev2, 0);
-
- if ($rev2) {
- if ($rev2 < $rev1) {
- $rev = $rev2;
- $rev2 = $rev1;
- $rev1 = $rev;
- }
- } else {
- //empty right side means a removed page. Look up last revision.
- $rev2 = $this->currentRevision();
- }
- //collect revisions around rev2
- list($revs2, $allRevs, $fp, $lines, $head, $tail) = $this->retrieveRevisionsAround($rev2, $max);
-
- if (empty($revs2)) return array(array(), array());
-
- //collect revisions around rev1
- $index = array_search($rev1, $allRevs);
- if ($index === false) {
- //no overlapping revisions
- list($revs1, , , , ,) = $this->retrieveRevisionsAround($rev1, $max);
- if (empty($revs1)) $revs1 = array();
- } else {
- //revisions overlaps, reuse revisions around rev2
- $lastRev = array_pop($allRevs); //keep last entry that could be external edit
- $revs1 = $allRevs;
- while ($head > 0) {
- for ($i = count($lines) - 1; $i >= 0; $i--) {
- $info = $this->parseLogLine($lines[$i]);
- if ($this->cacheRevisionInfo($info)) {
- $revs1[] = $info['date'];
- $index++;
-
- if ($index > intval($max / 2)) break 2;
- }
- }
-
- list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, -1);
- }
- sort($revs1);
- $revs1[] = $lastRev; //push back last entry
-
- //return wanted selection
- $revs1 = array_slice($revs1, max($index - intval($max / 2), 0), $max);
- }
-
- return array(array_reverse($revs1), array_reverse($revs2));
- }
-
- /**
- * Return an existing revision for a specific date which is
- * the current one or younger or equal then the date
- *
- * @param number $date_at timestamp
- * @return string revision ('' for current)
- */
- public function getLastRevisionAt($date_at)
- {
- $fileLastMod = $this->getFilename();
- //requested date_at(timestamp) younger or equal then modified_time($this->id) => load current
- if (file_exists($fileLastMod) && $date_at >= @filemtime($fileLastMod)) {
- return '';
- } else {
- if ($rev = $this->getRelativeRevision($date_at + 1, -1)) { //+1 to get also the requested date revision
- return $rev;
- } else {
- return false;
- }
- }
- }
-
- /**
- * Collect the $max revisions near to the timestamp $rev
- *
- * Ideally, half of retrieved timestamps are older than $rev, another half are newer.
- * The returned array $requestedRevs may not contain the reference timestamp $rev
- * when it does not match any revision value recorded in changelog.
- *
- * @param int $rev revision timestamp
- * @param int $max maximum number of revisions to be returned
- * @return bool|array
- * return array with entries:
- * - $requestedRevs: array of with $max revision timestamps
- * - $revs: all parsed revision timestamps
- * - $fp: file pointer only defined for chuck reading, needs closing.
- * - $lines: non-parsed changelog lines before the parsed revisions
- * - $head: position of first read changelog line
- * - $lastTail: position of end of last read changelog line
- * otherwise false
- */
- protected function retrieveRevisionsAround($rev, $max)
- {
- $revs = array();
- $afterCount = $beforeCount = 0;
-
- //get lines from changelog
- list($fp, $lines, $startHead, $startTail, $eof) = $this->readloglines($rev);
- if (empty($lines)) return false;
-
- //parse changelog lines in chunk, and read forward more chunks until $max/2 is reached
- $head = $startHead;
- $tail = $startTail;
- while (count($lines) > 0) {
- foreach ($lines as $line) {
- $info = $this->parseLogLine($line);
- if ($this->cacheRevisionInfo($info)) {
- $revs[] = $info['date'];
- if ($info['date'] >= $rev) {
- //count revs after reference $rev
- $afterCount++;
- if ($afterCount == 1) $beforeCount = count($revs);
- }
- //enough revs after reference $rev?
- if ($afterCount > intval($max / 2)) break 2;
- }
- }
- //retrieve next chunk
- list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, 1);
- }
- $lastTail = $tail;
-
- // add a possible revision of external edit, create or deletion
- if ($lastTail == $eof && $afterCount <= intval($max / 2) &&
- count($revs) && !$this->isCurrentRevision($revs[count($revs)-1])
- ) {
- $revs[] = $this->currentRevision;
- $afterCount++;
- }
-
- if ($afterCount == 0) {
- //given timestamp $rev is newer than the most recent line in chunk
- return false; //FIXME: or proceed to collect older revisions?
- }
-
- //read more chunks backward until $max/2 is reached and total number of revs is equal to $max
- $lines = array();
- $i = 0;
- if ($afterCount > 0) {
- $head = $startHead;
- $tail = $startTail;
- while ($head > 0) {
- list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, -1);
-
- for ($i = count($lines) - 1; $i >= 0; $i--) {
- $info = $this->parseLogLine($lines[$i]);
- if ($this->cacheRevisionInfo($info)) {
- $revs[] = $info['date'];
- $beforeCount++;
- //enough revs before reference $rev?
- if ($beforeCount > max(intval($max / 2), $max - $afterCount)) break 2;
- }
- }
- }
- }
- //keep only non-parsed lines
- $lines = array_slice($lines, 0, $i);
-
- sort($revs);
-
- //trunk desired selection
- $requestedRevs = array_slice($revs, -$max, $max);
-
- return array($requestedRevs, $revs, $fp, $lines, $head, $lastTail);
- }
-
- /**
- * Get the current revision information, considering external edit, create or deletion
- *
- * When the file has not modified since its last revision, the information of the last
- * change that had already recorded in the changelog is returned as current change info.
- * Otherwise, the change information since the last revision caused outside DokuWiki
- * should be returned, which is referred as "external revision".
- *
- * The change date of the file can be determined by timestamp as far as the file exists,
- * however this is not possible when the file has already deleted outside of DokuWiki.
- * In such case we assign 1 sec before current time() for the external deletion.
- * As a result, the value of current revision identifier may change each time because:
- * 1) the file has again modified outside of DokuWiki, or
- * 2) the value is essentially volatile for deleted but once existed files.
- *
- * @return bool|array false when page had never existed or array with entries:
- * - date: revision identifier (timestamp or last revision +1)
- * - ip: IPv4 address (127.0.0.1)
- * - type: log line type
- * - id: id of page or media
- * - user: user name
- * - sum: edit summary (or action reason)
- * - extra: extra data (varies by line type)
- * - sizechange: change of filesize
- * - timestamp: unix timestamp or false (key set only for external edit occurred)
- *
- * @author Satoshi Sahara
- */
- public function getCurrentRevisionInfo()
- {
- global $lang;
-
- if (isset($this->currentRevision)) return $this->getRevisionInfo($this->currentRevision);
-
- // get revision id from the item file timestamp and changelog
- $fileLastMod = $this->getFilename();
- $fileRev = @filemtime($fileLastMod); // false when the file not exist
- $lastRev = $this->lastRevision(); // false when no changelog
-
- if (!$fileRev && !$lastRev) { // has never existed
- $this->currentRevision = false;
- return false;
- } elseif ($fileRev === $lastRev) { // not external edit
- $this->currentRevision = $lastRev;
- return $this->getRevisionInfo($lastRev);
- }
-
- if (!$fileRev && $lastRev) { // item file does not exist
- // check consistency against changelog
- $revInfo = $this->getRevisionInfo($lastRev, false);
- if ($revInfo['type'] == DOKU_CHANGE_TYPE_DELETE) {
- $this->currentRevision = $lastRev;
- return $revInfo;
- }
-
- // externally deleted, set revision date as late as possible
- $revInfo = [
- 'date' => max($lastRev +1, time() -1), // 1 sec before now or new page save
- 'ip' => '127.0.0.1',
- 'type' => DOKU_CHANGE_TYPE_DELETE,
- 'id' => $this->id,
- 'user' => '',
- 'sum' => $lang['deleted'].' - '.$lang['external_edit'].' ('.$lang['unknowndate'].')',
- 'extra' => '',
- 'sizechange' => -io_getSizeFile($this->getFilename($lastRev)),
- 'timestamp' => false,
- ];
-
- } else { // item file exists, with timestamp $fileRev
- // here, file timestamp $fileRev is different with last revision timestamp $lastRev in changelog
- $isJustCreated = $lastRev === false || (
- $fileRev > $lastRev &&
- $this->getRevisionInfo($lastRev, false)['type'] == DOKU_CHANGE_TYPE_DELETE
- );
- $filesize_new = filesize($this->getFilename());
- $filesize_old = $isJustCreated ? 0 : io_getSizeFile($this->getFilename($lastRev));
- $sizechange = $filesize_new - $filesize_old;
-
- if ($isJustCreated) {
- $timestamp = $fileRev;
- $sum = $lang['created'].' - '.$lang['external_edit'];
- } elseif ($fileRev > $lastRev) {
- $timestamp = $fileRev;
- $sum = $lang['external_edit'];
- } else {
- // $fileRev is older than $lastRev, that is erroneous/incorrect occurrence.
- $msg = "Warning: current file modification time is older than last revision date";
- $details = 'File revision: '.$fileRev.' '.dformat($fileRev, "%Y-%m-%d %H:%M:%S")."\n"
- .'Last revision: '.$lastRev.' '.dformat($lastRev, "%Y-%m-%d %H:%M:%S");
- Logger::error($msg, $details, $this->getFilename());
- $timestamp = false;
- $sum = $lang['external_edit'].' ('.$lang['unknowndate'].')';
- }
-
- // externally created or edited
- $revInfo = [
- 'date' => $timestamp ?: $lastRev +1,
- 'ip' => '127.0.0.1',
- 'type' => $isJustCreated ? DOKU_CHANGE_TYPE_CREATE : DOKU_CHANGE_TYPE_EDIT,
- 'id' => $this->id,
- 'user' => '',
- 'sum' => $sum,
- 'extra' => '',
- 'sizechange' => $sizechange,
- 'timestamp' => $timestamp,
- ];
- }
-
- // cache current revision information of external edition
- $this->currentRevision = $revInfo['date'];
- $this->cache[$this->id][$this->currentRevision] = $revInfo;
- return $this->getRevisionInfo($this->currentRevision);
- }
-
- /**
- * Mechanism to trace no-actual external current revision
- * @param int $rev
- */
- public function traceCurrentRevision($rev)
- {
- if ($rev > $this->lastRevision()) {
- $rev = $this->currentRevision();
- }
- return $rev;
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/ChangeLog/ChangeLogTrait.php b/snippets/dokuwiki-2023-04-04/inc/ChangeLog/ChangeLogTrait.php
deleted file mode 100644
index fce593f..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/ChangeLog/ChangeLogTrait.php
+++ /dev/null
@@ -1,269 +0,0 @@
-
- *
- * @param string $line changelog line
- * @return array|bool parsed line or false
- */
- public static function parseLogLine($line)
- {
- $info = explode("\t", rtrim($line, "\n"));
- if ($info !== false && count($info) > 1) {
- return [
- 'date' => (int)$info[0], // unix timestamp
- 'ip' => $info[1], // IPv4 address (127.0.0.1)
- 'type' => $info[2], // log line type
- 'id' => $info[3], // page id
- 'user' => $info[4], // user name
- 'sum' => $info[5], // edit summary (or action reason)
- 'extra' => $info[6], // extra data (varies by line type)
- 'sizechange' => (isset($info[7]) && $info[7] !== '') ? (int)$info[7] : null, //
- ];
- } else {
- return false;
- }
- }
-
- /**
- * Build a changelog line from it's components
- *
- * @param array $info Revision info structure
- * @param int $timestamp log line date (optional)
- * @return string changelog line
- */
- public static function buildLogLine(array &$info, $timestamp = null)
- {
- $strip = ["\t", "\n"];
- $entry = array(
- 'date' => $timestamp ?? $info['date'],
- 'ip' => $info['ip'],
- 'type' => str_replace($strip, '', $info['type']),
- 'id' => $info['id'],
- 'user' => $info['user'],
- 'sum' => PhpString::substr(str_replace($strip, '', $info['sum']), 0, 255),
- 'extra' => str_replace($strip, '', $info['extra']),
- 'sizechange' => $info['sizechange'],
- );
- $info = $entry;
- return implode("\t", $entry) ."\n";
- }
-
- /**
- * Returns path to changelog
- *
- * @return string path to file
- */
- abstract protected function getChangelogFilename();
-
- /**
- * Checks if the ID has old revisions
- * @return boolean
- */
- public function hasRevisions()
- {
- $logfile = $this->getChangelogFilename();
- return file_exists($logfile);
- }
-
-
- /** @var int */
- protected $chunk_size;
-
- /**
- * Set chunk size for file reading
- * Chunk size zero let read whole file at once
- *
- * @param int $chunk_size maximum block size read from file
- */
- public function setChunkSize($chunk_size)
- {
- if (!is_numeric($chunk_size)) $chunk_size = 0;
-
- $this->chunk_size = (int)max($chunk_size, 0);
- }
-
- /**
- * Returns lines from changelog.
- * If file larger than $chunk_size, only chunk is read that could contain $rev.
- *
- * When reference timestamp $rev is outside time range of changelog, readloglines() will return
- * lines in first or last chunk, but they obviously does not contain $rev.
- *
- * @param int $rev revision timestamp
- * @return array|false
- * if success returns array(fp, array(changeloglines), $head, $tail, $eof)
- * where fp only defined for chuck reading, needs closing.
- * otherwise false
- */
- protected function readloglines($rev)
- {
- $file = $this->getChangelogFilename();
-
- if (!file_exists($file)) {
- return false;
- }
-
- $fp = null;
- $head = 0;
- $tail = 0;
- $eof = 0;
-
- if (filesize($file) < $this->chunk_size || $this->chunk_size == 0) {
- // read whole file
- $lines = file($file);
- if ($lines === false) {
- return false;
- }
- } else {
- // read by chunk
- $fp = fopen($file, 'rb'); // "file pointer"
- if ($fp === false) {
- return false;
- }
- fseek($fp, 0, SEEK_END);
- $eof = ftell($fp);
- $tail = $eof;
-
- // find chunk
- while ($tail - $head > $this->chunk_size) {
- $finger = $head + intval(($tail - $head) / 2);
- $finger = $this->getNewlinepointer($fp, $finger);
- $tmp = fgets($fp);
- if ($finger == $head || $finger == $tail) {
- break;
- }
- $info = $this->parseLogLine($tmp);
- $finger_rev = $info['date'];
-
- if ($finger_rev > $rev) {
- $tail = $finger;
- } else {
- $head = $finger;
- }
- }
-
- if ($tail - $head < 1) {
- // could not find chunk, assume requested rev is missing
- fclose($fp);
- return false;
- }
-
- $lines = $this->readChunk($fp, $head, $tail);
- }
- return array(
- $fp,
- $lines,
- $head,
- $tail,
- $eof,
- );
- }
-
- /**
- * Read chunk and return array with lines of given chunk.
- * Has no check if $head and $tail are really at a new line
- *
- * @param resource $fp resource file pointer
- * @param int $head start point chunk
- * @param int $tail end point chunk
- * @return array lines read from chunk
- */
- protected function readChunk($fp, $head, $tail)
- {
- $chunk = '';
- $chunk_size = max($tail - $head, 0); // found chunk size
- $got = 0;
- fseek($fp, $head);
- while ($got < $chunk_size && !feof($fp)) {
- $tmp = @fread($fp, max(min($this->chunk_size, $chunk_size - $got), 0));
- if ($tmp === false) { //error state
- break;
- }
- $got += strlen($tmp);
- $chunk .= $tmp;
- }
- $lines = explode("\n", $chunk);
- array_pop($lines); // remove trailing newline
- return $lines;
- }
-
- /**
- * Set pointer to first new line after $finger and return its position
- *
- * @param resource $fp file pointer
- * @param int $finger a pointer
- * @return int pointer
- */
- protected function getNewlinepointer($fp, $finger)
- {
- fseek($fp, $finger);
- $nl = $finger;
- if ($finger > 0) {
- fgets($fp); // slip the finger forward to a new line
- $nl = ftell($fp);
- }
- return $nl;
- }
-
- /**
- * Returns the next lines of the changelog of the chunk before head or after tail
- *
- * @param resource $fp file pointer
- * @param int $head position head of last chunk
- * @param int $tail position tail of last chunk
- * @param int $direction positive forward, negative backward
- * @return array with entries:
- * - $lines: changelog lines of read chunk
- * - $head: head of chunk
- * - $tail: tail of chunk
- */
- protected function readAdjacentChunk($fp, $head, $tail, $direction)
- {
- if (!$fp) return array(array(), $head, $tail);
-
- if ($direction > 0) {
- //read forward
- $head = $tail;
- $tail = $head + intval($this->chunk_size * (2 / 3));
- $tail = $this->getNewlinepointer($fp, $tail);
- } else {
- //read backward
- $tail = $head;
- $head = max($tail - $this->chunk_size, 0);
- while (true) {
- $nl = $this->getNewlinepointer($fp, $head);
- // was the chunk big enough? if not, take another bite
- if ($nl > 0 && $tail <= $nl) {
- $head = max($head - $this->chunk_size, 0);
- } else {
- $head = $nl;
- break;
- }
- }
- }
-
- //load next chunk
- $lines = $this->readChunk($fp, $head, $tail);
- return array($lines, $head, $tail);
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/ChangeLog/MediaChangeLog.php b/snippets/dokuwiki-2023-04-04/inc/ChangeLog/MediaChangeLog.php
deleted file mode 100644
index 81279dc..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/ChangeLog/MediaChangeLog.php
+++ /dev/null
@@ -1,60 +0,0 @@
-id, '.changes');
- }
-
- /**
- * Returns path to current page/media
- *
- * @param string|int $rev empty string or revision timestamp
- * @return string path to file
- */
- protected function getFilename($rev = '')
- {
- return mediaFN($this->id, $rev);
- }
-
-
-
- /**
- * Adds an entry to the changelog
- *
- * @param array $info Revision info structure of a media file
- * @param int $timestamp log line date (optional)
- * @return array revision info of added log line
- *
- * @see also addMediaLogEntry() in inc/changelog.php file
- */
- public function addLogEntry(array $info, $timestamp = null)
- {
- global $conf;
-
- if (isset($timestamp)) unset($this->cache[$this->id][$info['date']]);
-
- // add changelog lines
- $logline = $this->buildLogLine($info, $timestamp);
- io_saveFile(mediaMetaFN($this->id,'.changes'), $logline, $append = true);
- io_saveFile($conf['media_changelog'], $logline, $append = true); //global changelog cache
-
- // update cache
- $this->currentRevision = $info['date'];
- $this->cache[$this->id][$this->currentRevision] = $info;
- return $info;
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/ChangeLog/PageChangeLog.php b/snippets/dokuwiki-2023-04-04/inc/ChangeLog/PageChangeLog.php
deleted file mode 100644
index 6399d6a..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/ChangeLog/PageChangeLog.php
+++ /dev/null
@@ -1,60 +0,0 @@
-id, '.changes');
- }
-
- /**
- * Returns path to current page/media
- *
- * @param string|int $rev empty string or revision timestamp
- * @return string path to file
- */
- protected function getFilename($rev = '')
- {
- return wikiFN($this->id, $rev);
- }
-
-
-
- /**
- * Adds an entry to the changelog
- *
- * @param array $info Revision info structure of a page
- * @param int $timestamp log line date (optional)
- * @return array revision info of added log line
- *
- * @see also addLogEntry() in inc/changelog.php file
- */
- public function addLogEntry(array $info, $timestamp = null)
- {
- global $conf;
-
- if (isset($timestamp)) unset($this->cache[$this->id][$info['date']]);
-
- // add changelog lines
- $logline = $this->buildLogLine($info, $timestamp);
- io_saveFile(metaFN($this->id,'.changes'), $logline, true);
- io_saveFile($conf['changelog'], $logline, true); //global changelog cache
-
- // update cache
- $this->currentRevision = $info['date'];
- $this->cache[$this->id][$this->currentRevision] = $info;
- return $info;
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/ChangeLog/RevisionInfo.php b/snippets/dokuwiki-2023-04-04/inc/ChangeLog/RevisionInfo.php
deleted file mode 100644
index 40e2651..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/ChangeLog/RevisionInfo.php
+++ /dev/null
@@ -1,396 +0,0 @@
- 'page',
- 'date' => false,
- ];
- }
- $this->info = $info;
- }
-
- /**
- * Set or return whether this revision is current page or media file
- *
- * This method does not check exactly whether the revision is current or not. Instead,
- * set value of associated "current" key for internal use. Some UI element like diff
- * link button depend on relation to current page or media file. A changelog line does
- * not indicate whether it corresponds to current page or media file.
- *
- * @param bool $value true if the revision is current, otherwise false
- * @return bool
- */
- public function isCurrent($value = null)
- {
- return (bool) $this->val('current', $value);
- }
-
- /**
- * Return or set a value of associated key of revision information
- * but does not allow to change values of existing keys
- *
- * @param string $key
- * @param mixed $value
- * @return string|null
- */
- public function val($key, $value = null)
- {
- if (isset($value) && !array_key_exists($key, $this->info)) {
- // setter, only for new keys
- $this->info[$key] = $value;
- }
- if (array_key_exists($key, $this->info)) {
- // getter
- return $this->info[$key];
- }
- return null;
- }
-
- /**
- * Set extra key-value to the revision information
- * but does not allow to change values of existing keys
- * @param array $info
- * @return void
- */
- public function append(array $info)
- {
- foreach ($info as $key => $value) {
- $this->val($key, $value);
- }
- }
-
-
- /**
- * file icon of the page or media file
- * used in [Ui\recent]
- *
- * @return string
- */
- public function showFileIcon()
- {
- $id = $this->val('id');
- switch ($this->val('mode')) {
- case 'media': // media file revision
- return media_printicon($id);
- case 'page': // page revision
- return '
';
- }
- }
-
- /**
- * edit date and time of the page or media file
- * used in [Ui\recent, Ui\Revisions]
- *
- * @param bool $checkTimestamp enable timestamp check, alter formatted string when timestamp is false
- * @return string
- */
- public function showEditDate($checkTimestamp = false)
- {
- $formatted = dformat($this->val('date'));
- if ($checkTimestamp && $this->val('timestamp') === false) {
- // exact date is unknown for externally deleted file
- // when unknown, alter formatted string "YYYY-mm-DD HH:MM" to "____-__-__ __:__"
- $formatted = preg_replace('/[0-9a-zA-Z]/','_', $formatted);
- }
- return ''. $formatted .'';
- }
-
- /**
- * edit summary
- * used in [Ui\recent, Ui\Revisions]
- *
- * @return string
- */
- public function showEditSummary()
- {
- return ''.' – '. hsc($this->val('sum')).'';
- }
-
- /**
- * editor of the page or media file
- * used in [Ui\recent, Ui\Revisions]
- *
- * @return string
- */
- public function showEditor()
- {
- if ($this->val('user')) {
- $html = ''. editorinfo($this->val('user')) .'';
- if (auth_ismanager()) $html .= ' ('. $this->val('ip') .')';
- } else {
- $html = ''. $this->val('ip') .'';
- }
- return ''. $html. '';
- }
-
- /**
- * name of the page or media file
- * used in [Ui\recent, Ui\Revisions]
- *
- * @return string
- */
- public function showFileName()
- {
- $id = $this->val('id');
- $rev = $this->isCurrent() ? '' : $this->val('date');
-
- switch ($this->val('mode')) {
- case 'media': // media file revision
- $params = ['tab_details'=> 'view', 'ns'=> getNS($id), 'image'=> $id];
- if ($rev) $params += ['rev'=> $rev];
- $href = media_managerURL($params, '&');
- $display_name = $id;
- $exists = file_exists(mediaFN($id, $rev));
- break;
- case 'page': // page revision
- $params = $rev ? ['rev'=> $rev] : [];
- $href = wl($id, $params, false, '&');
- $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id;
- if (!$display_name) $display_name = $id;
- $exists = page_exists($id, $rev);
- }
-
- if($exists) {
- $class = 'wikilink1';
- } else {
- if($this->isCurrent()) {
- //show only not-existing link for current page, which allows for directly create a new page/upload
- $class = 'wikilink2';
- } else {
- //revision is not in attic
- return $display_name;
- }
- }
- if ($this->val('type') == DOKU_CHANGE_TYPE_DELETE) {
- $class = 'wikilink2';
- }
- return ''.$display_name.'';
- }
-
- /**
- * Revision Title for PageDiff table headline
- *
- * @return string
- */
- public function showRevisionTitle()
- {
- global $lang;
-
- if (!$this->val('date')) return '—';
-
- $id = $this->val('id');
- $rev = $this->isCurrent() ? '' : $this->val('date');
- $params = ($rev) ? ['rev'=> $rev] : [];
-
- // revision info may have timestamp key when external edits occurred
- $date = ($this->val('timestamp') === false)
- ? $lang['unknowndate']
- : dformat($this->val('date'));
-
-
- switch ($this->val('mode')) {
- case 'media': // media file revision
- $href = ml($id, $params, false, '&');
- $exists = file_exists(mediaFN($id, $rev));
- break;
- case 'page': // page revision
- $href = wl($id, $params, false, '&');
- $exists = page_exists($id, $rev);
- }
- if($exists) {
- $class = 'wikilink1';
- } else {
- if($this->isCurrent()) {
- //show only not-existing link for current page, which allows for directly create a new page/upload
- $class = 'wikilink2';
- } else {
- //revision is not in attic
- return $id.' ['.$date.']';
- }
- }
- if ($this->val('type') == DOKU_CHANGE_TYPE_DELETE) {
- $class = 'wikilink2';
- }
- return ''.$id.' ['.$date.']'.'';
- }
-
- /**
- * diff link icon in recent changes list, to compare (this) current revision with previous one
- * all items in "recent changes" are current revision of the page or media
- *
- * @return string
- */
- public function showIconCompareWithPrevious()
- {
- global $lang;
- $id = $this->val('id');
-
- $href = '';
- switch ($this->val('mode')) {
- case 'media': // media file revision
- // unlike page, media file does not copied to media_attic when uploaded.
- // diff icon will not be shown when external edit occurred
- // because no attic file to be compared with current.
- $revs = (new MediaChangeLog($id))->getRevisions(0, 1);
- $showLink = (count($revs) && file_exists(mediaFN($id,$revs[0])) && file_exists(mediaFN($id)));
- if ($showLink) {
- $param = ['tab_details'=>'history', 'mediado'=>'diff', 'ns'=> getNS($id), 'image'=> $id];
- $href = media_managerURL($param, '&');
- }
- break;
- case 'page': // page revision
- // when a page just created anyway, it is natural to expect no older revisions
- // even if it had once existed but deleted before. Simply ignore to check changelog.
- if ($this->val('type') !== DOKU_CHANGE_TYPE_CREATE) {
- $href = wl($id, ['do'=>'diff'], false, '&');
- }
- }
-
- if ($href) {
- return ''
- .'
'
- .'';
- } else {
- return '
';
- }
- }
-
- /**
- * diff link icon in revisions list, compare this revision with current one
- * the icon does not displayed for the current revision
- *
- * @return string
- */
- public function showIconCompareWithCurrent()
- {
- global $lang;
- $id = $this->val('id');
- $rev = $this->isCurrent() ? '' : $this->val('date');
-
- $href = '';
- switch ($this->val('mode')) {
- case 'media': // media file revision
- if (!$this->isCurrent() && file_exists(mediaFN($id, $rev))) {
- $param = ['mediado'=>'diff', 'image'=> $id, 'rev'=> $rev];
- $href = media_managerURL($param, '&');
- }
- break;
- case 'page': // page revision
- if (!$this->isCurrent()) {
- $href = wl($id, ['rev'=> $rev, 'do'=>'diff'], false, '&');
- }
- }
-
- if ($href) {
- return ''
- .'
'
- .'';
- } else {
- return '
';
- }
- }
-
- /**
- * icon for revision action
- * used in [Ui\recent]
- *
- * @return string
- */
- public function showIconRevisions()
- {
- global $lang;
-
- if (!actionOK('revisions')) {
- return '';
- }
-
- $id = $this->val('id');
- switch ($this->val('mode')) {
- case 'media': // media file revision
- $param = ['tab_details'=>'history', 'ns'=> getNS($id), 'image'=> $id];
- $href = media_managerURL($param, '&');
- break;
- case 'page': // page revision
- $href = wl($id, ['do'=>'revisions'], false, '&');
- }
- return ''
- . '
'
- . '';
- }
-
- /**
- * size change
- * used in [Ui\recent, Ui\Revisions]
- *
- * @return string
- */
- public function showSizeChange()
- {
- $class = 'sizechange';
- $value = filesize_h(abs($this->val('sizechange')));
- if ($this->val('sizechange') > 0) {
- $class .= ' positive';
- $value = '+' . $value;
- } elseif ($this->val('sizechange') < 0) {
- $class .= ' negative';
- $value = '-' . $value;
- } else {
- $value = '±' . $value;
- }
- return ''.$value.'';
- }
-
- /**
- * current indicator, used in revision list
- * not used in Ui\Recent because recent files are always current one
- *
- * @return string
- */
- public function showCurrentIndicator()
- {
- global $lang;
- return $this->isCurrent() ? '('.$lang['current'].')' : '';
- }
-
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Debug/DebugHelper.php b/snippets/dokuwiki-2023-04-04/inc/Debug/DebugHelper.php
deleted file mode 100644
index f78b881..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Debug/DebugHelper.php
+++ /dev/null
@@ -1,175 +0,0 @@
-isLogging() &&
- ($EVENT_HANDLER === null || !$EVENT_HANDLER->hasHandlerForEvent('INFO_DEPRECATION_LOG'))
- ) {
- // avoid any work if no one cares
- return false;
- }
- return true;
- }
-
- /**
- * Log accesses to deprecated fucntions to the debug log
- *
- * @param string $alternative (optional) The function or method that should be used instead
- * @param int $callerOffset (optional) How far the deprecated method is removed from this one
- * @param string $thing (optional) The deprecated thing, defaults to the calling method
- * @triggers \dokuwiki\Debug::INFO_DEPRECATION_LOG_EVENT
- */
- public static function dbgDeprecatedFunction($alternative = '', $callerOffset = 1, $thing = '')
- {
- if (!self::isEnabled()) return;
-
- $backtrace = debug_backtrace();
- for ($i = 0; $i < $callerOffset; $i += 1) {
- if(count($backtrace) > 1) array_shift($backtrace);
- }
-
- list($self, $call) = $backtrace;
-
- if (!$thing) {
- $thing = trim(
- (!empty($self['class']) ? ($self['class'] . '::') : '') .
- $self['function'] . '()', ':');
- }
-
- self::triggerDeprecationEvent(
- $backtrace,
- $alternative,
- $thing,
- trim(
- (!empty($call['class']) ? ($call['class'] . '::') : '') .
- $call['function'] . '()', ':'),
- $self['file'] ?? $call['file'] ?? '',
- $self['line'] ?? $call['line'] ?? 0
- );
- }
-
- /**
- * This marks logs a deprecation warning for a property that should no longer be used
- *
- * This is usually called withing a magic getter or setter.
- * For logging deprecated functions or methods see dbgDeprecatedFunction()
- *
- * @param string $class The class with the deprecated property
- * @param string $propertyName The name of the deprecated property
- *
- * @triggers \dokuwiki\Debug::INFO_DEPRECATION_LOG_EVENT
- */
- public static function dbgDeprecatedProperty($class, $propertyName)
- {
- if (!self::isEnabled()) return;
-
- $backtrace = debug_backtrace();
- array_shift($backtrace);
- $call = $backtrace[1];
- $caller = trim($call['class'] . '::' . $call['function'] . '()', ':');
- $qualifiedName = $class . '::$' . $propertyName;
- self::triggerDeprecationEvent(
- $backtrace,
- '',
- $qualifiedName,
- $caller,
- $backtrace[0]['file'],
- $backtrace[0]['line']
- );
- }
-
- /**
- * Trigger a custom deprecation event
- *
- * Usually dbgDeprecatedFunction() or dbgDeprecatedProperty() should be used instead.
- * This method is intended only for those situation where they are not applicable.
- *
- * @param string $alternative
- * @param string $deprecatedThing
- * @param string $caller
- * @param string $file
- * @param int $line
- * @param int $callerOffset How many lines should be removed from the beginning of the backtrace
- */
- public static function dbgCustomDeprecationEvent(
- $alternative,
- $deprecatedThing,
- $caller,
- $file,
- $line,
- $callerOffset = 1
- )
- {
- if (!self::isEnabled()) return;
-
- $backtrace = array_slice(debug_backtrace(), $callerOffset);
-
- self::triggerDeprecationEvent(
- $backtrace,
- $alternative,
- $deprecatedThing,
- $caller,
- $file,
- $line
- );
-
- }
-
- /**
- * @param array $backtrace
- * @param string $alternative
- * @param string $deprecatedThing
- * @param string $caller
- * @param string $file
- * @param int $line
- */
- private static function triggerDeprecationEvent(
- array $backtrace,
- $alternative,
- $deprecatedThing,
- $caller,
- $file,
- $line
- )
- {
- $data = [
- 'trace' => $backtrace,
- 'alternative' => $alternative,
- 'called' => $deprecatedThing,
- 'caller' => $caller,
- 'file' => $file,
- 'line' => $line,
- ];
- $event = new Doku_Event(self::INFO_DEPRECATION_LOG_EVENT, $data);
- if ($event->advise_before()) {
- $msg = $event->data['called'] . ' is deprecated. It was called from ';
- $msg .= $event->data['caller'] . ' in ' . $event->data['file'] . ':' . $event->data['line'];
- if ($event->data['alternative']) {
- $msg .= ' ' . $event->data['alternative'] . ' should be used instead!';
- }
- Logger::getInstance(Logger::LOG_DEPRECATED)->log($msg);
- }
- $event->advise_after();
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Debug/PropertyDeprecationHelper.php b/snippets/dokuwiki-2023-04-04/inc/Debug/PropertyDeprecationHelper.php
deleted file mode 100644
index 6289d5b..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Debug/PropertyDeprecationHelper.php
+++ /dev/null
@@ -1,134 +0,0 @@
-deprecatePublicProperty( 'bar', '1.21', __CLASS__ );
- * }
- * }
- *
- * $foo = new Foo;
- * $foo->bar; // works but logs a warning
- *
- * Cannot be used with classes that have their own __get/__set methods.
- *
- */
-trait PropertyDeprecationHelper
-{
-
- /**
- * List of deprecated properties, in => format
- * where is the the name of the class defining the property
- *
- * E.g. [ '_event' => '\dokuwiki\Cache\Cache' ]
- * @var string[]
- */
- protected $deprecatedPublicProperties = [];
-
- /**
- * Mark a property as deprecated. Only use this for properties that used to be public and only
- * call it in the constructor.
- *
- * @param string $property The name of the property.
- * @param null $class name of the class defining the property
- * @see DebugHelper::dbgDeprecatedProperty
- */
- protected function deprecatePublicProperty(
- $property,
- $class = null
- ) {
- $this->deprecatedPublicProperties[$property] = $class ?: get_class();
- }
-
- public function __get($name)
- {
- if (isset($this->deprecatedPublicProperties[$name])) {
- $class = $this->deprecatedPublicProperties[$name];
- DebugHelper::dbgDeprecatedProperty($class, $name);
- return $this->$name;
- }
-
- $qualifiedName = get_class() . '::$' . $name;
- if ($this->deprecationHelperGetPropertyOwner($name)) {
- // Someone tried to access a normal non-public property. Try to behave like PHP would.
- trigger_error("Cannot access non-public property $qualifiedName", E_USER_ERROR);
- } else {
- // Non-existing property. Try to behave like PHP would.
- trigger_error("Undefined property: $qualifiedName", E_USER_NOTICE);
- }
- return null;
- }
-
- public function __set($name, $value)
- {
- if (isset($this->deprecatedPublicProperties[$name])) {
- $class = $this->deprecatedPublicProperties[$name];
- DebugHelper::dbgDeprecatedProperty($class, $name);
- $this->$name = $value;
- return;
- }
-
- $qualifiedName = get_class() . '::$' . $name;
- if ($this->deprecationHelperGetPropertyOwner($name)) {
- // Someone tried to access a normal non-public property. Try to behave like PHP would.
- trigger_error("Cannot access non-public property $qualifiedName", E_USER_ERROR);
- } else {
- // Non-existing property. Try to behave like PHP would.
- $this->$name = $value;
- }
- }
-
- /**
- * Like property_exists but also check for non-visible private properties and returns which
- * class in the inheritance chain declared the property.
- * @param string $property
- * @return string|bool Best guess for the class in which the property is defined.
- */
- private function deprecationHelperGetPropertyOwner($property)
- {
- // Easy branch: check for protected property / private property of the current class.
- if (property_exists($this, $property)) {
- // The class name is not necessarily correct here but getting the correct class
- // name would be expensive, this will work most of the time and getting it
- // wrong is not a big deal.
- return __CLASS__;
- }
- // property_exists() returns false when the property does exist but is private (and not
- // defined by the current class, for some value of "current" that differs slightly
- // between engines).
- // Since PHP triggers an error on public access of non-public properties but happily
- // allows public access to undefined properties, we need to detect this case as well.
- // Reflection is slow so use array cast hack to check for that:
- $obfuscatedProps = array_keys((array)$this);
- $obfuscatedPropTail = "\0$property";
- foreach ($obfuscatedProps as $obfuscatedProp) {
- // private props are in the form \0\0
- if (strpos($obfuscatedProp, $obfuscatedPropTail, 1) !== false) {
- $classname = substr($obfuscatedProp, 1, -strlen($obfuscatedPropTail));
- if ($classname === '*') {
- // sanity; this shouldn't be possible as protected properties were handled earlier
- $classname = __CLASS__;
- }
- return $classname;
- }
- }
- return false;
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/DifferenceEngine.php b/snippets/dokuwiki-2023-04-04/inc/DifferenceEngine.php
deleted file mode 100644
index 70877a4..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/DifferenceEngine.php
+++ /dev/null
@@ -1,1544 +0,0 @@
-
- * @license You may copy this code freely under the conditions of the GPL.
- */
-define('USE_ASSERTS', function_exists('assert'));
-
-class _DiffOp {
- var $type;
- var $orig;
- var $closing;
-
- /**
- * @return _DiffOp
- */
- function reverse() {
- trigger_error("pure virtual", E_USER_ERROR);
- }
-
- function norig() {
- return $this->orig ? count($this->orig) : 0;
- }
-
- function nclosing() {
- return $this->closing ? count($this->closing) : 0;
- }
-}
-
-class _DiffOp_Copy extends _DiffOp {
- var $type = 'copy';
-
- function __construct($orig, $closing = false) {
- if (!is_array($closing))
- $closing = $orig;
- $this->orig = $orig;
- $this->closing = $closing;
- }
-
- function reverse() {
- return new _DiffOp_Copy($this->closing, $this->orig);
- }
-}
-
-class _DiffOp_Delete extends _DiffOp {
- var $type = 'delete';
-
- function __construct($lines) {
- $this->orig = $lines;
- $this->closing = false;
- }
-
- function reverse() {
- return new _DiffOp_Add($this->orig);
- }
-}
-
-class _DiffOp_Add extends _DiffOp {
- var $type = 'add';
-
- function __construct($lines) {
- $this->closing = $lines;
- $this->orig = false;
- }
-
- function reverse() {
- return new _DiffOp_Delete($this->closing);
- }
-}
-
-class _DiffOp_Change extends _DiffOp {
- var $type = 'change';
-
- function __construct($orig, $closing) {
- $this->orig = $orig;
- $this->closing = $closing;
- }
-
- function reverse() {
- return new _DiffOp_Change($this->closing, $this->orig);
- }
-}
-
-
-/**
- * Class used internally by Diff to actually compute the diffs.
- *
- * The algorithm used here is mostly lifted from the perl module
- * Algorithm::Diff (version 1.06) by Ned Konz, which is available at:
- * http://www.perl.com/CPAN/authors/id/N/NE/NEDKONZ/Algorithm-Diff-1.06.zip
- *
- * More ideas are taken from:
- * http://www.ics.uci.edu/~eppstein/161/960229.html
- *
- * Some ideas are (and a bit of code) are from from analyze.c, from GNU
- * diffutils-2.7, which can be found at:
- * ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz
- *
- * closingly, some ideas (subdivision by NCHUNKS > 2, and some optimizations)
- * are my own.
- *
- * @author Geoffrey T. Dairiki
- * @access private
- */
-class _DiffEngine {
-
- var $xchanged = array();
- var $ychanged = array();
- var $xv = array();
- var $yv = array();
- var $xind = array();
- var $yind = array();
- var $seq;
- var $in_seq;
- var $lcs;
-
- /**
- * @param array $from_lines
- * @param array $to_lines
- * @return _DiffOp[]
- */
- function diff($from_lines, $to_lines) {
- $n_from = count($from_lines);
- $n_to = count($to_lines);
-
- $this->xchanged = $this->ychanged = array();
- $this->xv = $this->yv = array();
- $this->xind = $this->yind = array();
- unset($this->seq);
- unset($this->in_seq);
- unset($this->lcs);
-
- // Skip leading common lines.
- for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++) {
- if ($from_lines[$skip] != $to_lines[$skip])
- break;
- $this->xchanged[$skip] = $this->ychanged[$skip] = false;
- }
- // Skip trailing common lines.
- $xi = $n_from;
- $yi = $n_to;
- for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++) {
- if ($from_lines[$xi] != $to_lines[$yi])
- break;
- $this->xchanged[$xi] = $this->ychanged[$yi] = false;
- }
-
- // Ignore lines which do not exist in both files.
- for ($xi = $skip; $xi < $n_from - $endskip; $xi++)
- $xhash[$from_lines[$xi]] = 1;
- for ($yi = $skip; $yi < $n_to - $endskip; $yi++) {
- $line = $to_lines[$yi];
- if (($this->ychanged[$yi] = empty($xhash[$line])))
- continue;
- $yhash[$line] = 1;
- $this->yv[] = $line;
- $this->yind[] = $yi;
- }
- for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
- $line = $from_lines[$xi];
- if (($this->xchanged[$xi] = empty($yhash[$line])))
- continue;
- $this->xv[] = $line;
- $this->xind[] = $xi;
- }
-
- // Find the LCS.
- $this->_compareseq(0, count($this->xv), 0, count($this->yv));
-
- // Merge edits when possible
- $this->_shift_boundaries($from_lines, $this->xchanged, $this->ychanged);
- $this->_shift_boundaries($to_lines, $this->ychanged, $this->xchanged);
-
- // Compute the edit operations.
- $edits = array();
- $xi = $yi = 0;
- while ($xi < $n_from || $yi < $n_to) {
- USE_ASSERTS && assert($yi < $n_to || $this->xchanged[$xi]);
- USE_ASSERTS && assert($xi < $n_from || $this->ychanged[$yi]);
-
- // Skip matching "snake".
- $copy = array();
- while ($xi < $n_from && $yi < $n_to && !$this->xchanged[$xi] && !$this->ychanged[$yi]) {
- $copy[] = $from_lines[$xi++];
- ++$yi;
- }
- if ($copy)
- $edits[] = new _DiffOp_Copy($copy);
-
- // Find deletes & adds.
- $delete = array();
- while ($xi < $n_from && $this->xchanged[$xi])
- $delete[] = $from_lines[$xi++];
-
- $add = array();
- while ($yi < $n_to && $this->ychanged[$yi])
- $add[] = $to_lines[$yi++];
-
- if ($delete && $add)
- $edits[] = new _DiffOp_Change($delete, $add);
- elseif ($delete)
- $edits[] = new _DiffOp_Delete($delete);
- elseif ($add)
- $edits[] = new _DiffOp_Add($add);
- }
- return $edits;
- }
-
-
- /**
- * Divide the Largest Common Subsequence (LCS) of the sequences
- * [XOFF, XLIM) and [YOFF, YLIM) into NCHUNKS approximately equally
- * sized segments.
- *
- * Returns (LCS, PTS). LCS is the length of the LCS. PTS is an
- * array of NCHUNKS+1 (X, Y) indexes giving the diving points between
- * sub sequences. The first sub-sequence is contained in [X0, X1),
- * [Y0, Y1), the second in [X1, X2), [Y1, Y2) and so on. Note
- * that (X0, Y0) == (XOFF, YOFF) and
- * (X[NCHUNKS], Y[NCHUNKS]) == (XLIM, YLIM).
- *
- * This function assumes that the first lines of the specified portions
- * of the two files do not match, and likewise that the last lines do not
- * match. The caller must trim matching lines from the beginning and end
- * of the portions it is going to specify.
- *
- * @param integer $xoff
- * @param integer $xlim
- * @param integer $yoff
- * @param integer $ylim
- * @param integer $nchunks
- *
- * @return array
- */
- function _diag($xoff, $xlim, $yoff, $ylim, $nchunks) {
- $flip = false;
-
- if ($xlim - $xoff > $ylim - $yoff) {
- // Things seems faster (I'm not sure I understand why)
- // when the shortest sequence in X.
- $flip = true;
- list ($xoff, $xlim, $yoff, $ylim) = array($yoff, $ylim, $xoff, $xlim);
- }
-
- if ($flip)
- for ($i = $ylim - 1; $i >= $yoff; $i--)
- $ymatches[$this->xv[$i]][] = $i;
- else
- for ($i = $ylim - 1; $i >= $yoff; $i--)
- $ymatches[$this->yv[$i]][] = $i;
-
- $this->lcs = 0;
- $this->seq[0]= $yoff - 1;
- $this->in_seq = array();
- $ymids[0] = array();
-
- $numer = $xlim - $xoff + $nchunks - 1;
- $x = $xoff;
- for ($chunk = 0; $chunk < $nchunks; $chunk++) {
- if ($chunk > 0)
- for ($i = 0; $i <= $this->lcs; $i++)
- $ymids[$i][$chunk-1] = $this->seq[$i];
-
- $x1 = $xoff + (int)(($numer + ($xlim-$xoff)*$chunk) / $nchunks);
- for ( ; $x < $x1; $x++) {
- $line = $flip ? $this->yv[$x] : $this->xv[$x];
- if (empty($ymatches[$line]))
- continue;
- $matches = $ymatches[$line];
- $switch = false;
- foreach ($matches as $y) {
- if ($switch && $y > $this->seq[$k-1]) {
- USE_ASSERTS && assert($y < $this->seq[$k]);
- // Optimization: this is a common case:
- // next match is just replacing previous match.
- $this->in_seq[$this->seq[$k]] = false;
- $this->seq[$k] = $y;
- $this->in_seq[$y] = 1;
- }
- else if (empty($this->in_seq[$y])) {
- $k = $this->_lcs_pos($y);
- USE_ASSERTS && assert($k > 0);
- $ymids[$k] = $ymids[$k-1];
- $switch = true;
- }
- }
- }
- }
-
- $seps[] = $flip ? array($yoff, $xoff) : array($xoff, $yoff);
- $ymid = $ymids[$this->lcs];
- for ($n = 0; $n < $nchunks - 1; $n++) {
- $x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $n) / $nchunks);
- $y1 = $ymid[$n] + 1;
- $seps[] = $flip ? array($y1, $x1) : array($x1, $y1);
- }
- $seps[] = $flip ? array($ylim, $xlim) : array($xlim, $ylim);
-
- return array($this->lcs, $seps);
- }
-
- function _lcs_pos($ypos) {
- $end = $this->lcs;
- if ($end == 0 || $ypos > $this->seq[$end]) {
- $this->seq[++$this->lcs] = $ypos;
- $this->in_seq[$ypos] = 1;
- return $this->lcs;
- }
-
- $beg = 1;
- while ($beg < $end) {
- $mid = (int)(($beg + $end) / 2);
- if ($ypos > $this->seq[$mid])
- $beg = $mid + 1;
- else
- $end = $mid;
- }
-
- USE_ASSERTS && assert($ypos != $this->seq[$end]);
-
- $this->in_seq[$this->seq[$end]] = false;
- $this->seq[$end] = $ypos;
- $this->in_seq[$ypos] = 1;
- return $end;
- }
-
- /**
- * Find LCS of two sequences.
- *
- * The results are recorded in the vectors $this->{x,y}changed[], by
- * storing a 1 in the element for each line that is an insertion
- * or deletion (ie. is not in the LCS).
- *
- * The subsequence of file 0 is [XOFF, XLIM) and likewise for file 1.
- *
- * Note that XLIM, YLIM are exclusive bounds.
- * All line numbers are origin-0 and discarded lines are not counted.
- *
- * @param integer $xoff
- * @param integer $xlim
- * @param integer $yoff
- * @param integer $ylim
- */
- function _compareseq($xoff, $xlim, $yoff, $ylim) {
- // Slide down the bottom initial diagonal.
- while ($xoff < $xlim && $yoff < $ylim && $this->xv[$xoff] == $this->yv[$yoff]) {
- ++$xoff;
- ++$yoff;
- }
-
- // Slide up the top initial diagonal.
- while ($xlim > $xoff && $ylim > $yoff && $this->xv[$xlim - 1] == $this->yv[$ylim - 1]) {
- --$xlim;
- --$ylim;
- }
-
- if ($xoff == $xlim || $yoff == $ylim)
- $lcs = 0;
- else {
- // This is ad hoc but seems to work well.
- //$nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5);
- //$nchunks = max(2,min(8,(int)$nchunks));
- $nchunks = min(7, $xlim - $xoff, $ylim - $yoff) + 1;
- list ($lcs, $seps)
- = $this->_diag($xoff,$xlim,$yoff, $ylim,$nchunks);
- }
-
- if ($lcs == 0) {
- // X and Y sequences have no common subsequence:
- // mark all changed.
- while ($yoff < $ylim)
- $this->ychanged[$this->yind[$yoff++]] = 1;
- while ($xoff < $xlim)
- $this->xchanged[$this->xind[$xoff++]] = 1;
- }
- else {
- // Use the partitions to split this problem into subproblems.
- reset($seps);
- $pt1 = $seps[0];
- while ($pt2 = next($seps)) {
- $this->_compareseq ($pt1[0], $pt2[0], $pt1[1], $pt2[1]);
- $pt1 = $pt2;
- }
- }
- }
-
- /**
- * Adjust inserts/deletes of identical lines to join changes
- * as much as possible.
- *
- * We do something when a run of changed lines include a
- * line at one end and has an excluded, identical line at the other.
- * We are free to choose which identical line is included.
- * `compareseq' usually chooses the one at the beginning,
- * but usually it is cleaner to consider the following identical line
- * to be the "change".
- *
- * This is extracted verbatim from analyze.c (GNU diffutils-2.7).
- *
- * @param array $lines
- * @param array $changed
- * @param array $other_changed
- */
- function _shift_boundaries($lines, &$changed, $other_changed) {
- $i = 0;
- $j = 0;
-
- USE_ASSERTS && assert(count($lines) == count($changed));
- $len = count($lines);
- $other_len = count($other_changed);
-
- while (1) {
- /*
- * Scan forwards to find beginning of another run of changes.
- * Also keep track of the corresponding point in the other file.
- *
- * Throughout this code, $i and $j are adjusted together so that
- * the first $i elements of $changed and the first $j elements
- * of $other_changed both contain the same number of zeros
- * (unchanged lines).
- * Furthermore, $j is always kept so that $j == $other_len or
- * $other_changed[$j] == false.
- */
- while ($j < $other_len && $other_changed[$j])
- $j++;
-
- while ($i < $len && ! $changed[$i]) {
- USE_ASSERTS && assert($j < $other_len && ! $other_changed[$j]);
- $i++;
- $j++;
- while ($j < $other_len && $other_changed[$j])
- $j++;
- }
-
- if ($i == $len)
- break;
-
- $start = $i;
-
- // Find the end of this run of changes.
- while (++$i < $len && $changed[$i])
- continue;
-
- do {
- /*
- * Record the length of this run of changes, so that
- * we can later determine whether the run has grown.
- */
- $runlength = $i - $start;
-
- /*
- * Move the changed region back, so long as the
- * previous unchanged line matches the last changed one.
- * This merges with previous changed regions.
- */
- while ($start > 0 && $lines[$start - 1] == $lines[$i - 1]) {
- $changed[--$start] = 1;
- $changed[--$i] = false;
- while ($start > 0 && $changed[$start - 1])
- $start--;
- USE_ASSERTS && assert($j > 0);
- while ($other_changed[--$j])
- continue;
- USE_ASSERTS && assert($j >= 0 && !$other_changed[$j]);
- }
-
- /*
- * Set CORRESPONDING to the end of the changed run, at the last
- * point where it corresponds to a changed run in the other file.
- * CORRESPONDING == LEN means no such point has been found.
- */
- $corresponding = $j < $other_len ? $i : $len;
-
- /*
- * Move the changed region forward, so long as the
- * first changed line matches the following unchanged one.
- * This merges with following changed regions.
- * Do this second, so that if there are no merges,
- * the changed region is moved forward as far as possible.
- */
- while ($i < $len && $lines[$start] == $lines[$i]) {
- $changed[$start++] = false;
- $changed[$i++] = 1;
- while ($i < $len && $changed[$i])
- $i++;
-
- USE_ASSERTS && assert($j < $other_len && ! $other_changed[$j]);
- $j++;
- if ($j < $other_len && $other_changed[$j]) {
- $corresponding = $i;
- while ($j < $other_len && $other_changed[$j])
- $j++;
- }
- }
- } while ($runlength != $i - $start);
-
- /*
- * If possible, move the fully-merged run of changes
- * back to a corresponding run in the other file.
- */
- while ($corresponding < $i) {
- $changed[--$start] = 1;
- $changed[--$i] = 0;
- USE_ASSERTS && assert($j > 0);
- while ($other_changed[--$j])
- continue;
- USE_ASSERTS && assert($j >= 0 && !$other_changed[$j]);
- }
- }
- }
-}
-
-/**
- * Class representing a 'diff' between two sequences of strings.
- */
-class Diff {
-
- var $edits;
-
- /**
- * Constructor.
- * Computes diff between sequences of strings.
- *
- * @param array $from_lines An array of strings.
- * (Typically these are lines from a file.)
- * @param array $to_lines An array of strings.
- */
- function __construct($from_lines, $to_lines) {
- $eng = new _DiffEngine;
- $this->edits = $eng->diff($from_lines, $to_lines);
- //$this->_check($from_lines, $to_lines);
- }
-
- /**
- * Compute reversed Diff.
- *
- * SYNOPSIS:
- *
- * $diff = new Diff($lines1, $lines2);
- * $rev = $diff->reverse();
- *
- * @return Diff A Diff object representing the inverse of the
- * original diff.
- */
- function reverse() {
- $rev = $this;
- $rev->edits = array();
- foreach ($this->edits as $edit) {
- $rev->edits[] = $edit->reverse();
- }
- return $rev;
- }
-
- /**
- * Check for empty diff.
- *
- * @return bool True iff two sequences were identical.
- */
- function isEmpty() {
- foreach ($this->edits as $edit) {
- if ($edit->type != 'copy')
- return false;
- }
- return true;
- }
-
- /**
- * Compute the length of the Longest Common Subsequence (LCS).
- *
- * This is mostly for diagnostic purposed.
- *
- * @return int The length of the LCS.
- */
- function lcs() {
- $lcs = 0;
- foreach ($this->edits as $edit) {
- if ($edit->type == 'copy')
- $lcs += count($edit->orig);
- }
- return $lcs;
- }
-
- /**
- * Get the original set of lines.
- *
- * This reconstructs the $from_lines parameter passed to the
- * constructor.
- *
- * @return array The original sequence of strings.
- */
- function orig() {
- $lines = array();
-
- foreach ($this->edits as $edit) {
- if ($edit->orig)
- array_splice($lines, count($lines), 0, $edit->orig);
- }
- return $lines;
- }
-
- /**
- * Get the closing set of lines.
- *
- * This reconstructs the $to_lines parameter passed to the
- * constructor.
- *
- * @return array The sequence of strings.
- */
- function closing() {
- $lines = array();
-
- foreach ($this->edits as $edit) {
- if ($edit->closing)
- array_splice($lines, count($lines), 0, $edit->closing);
- }
- return $lines;
- }
-
- /**
- * Check a Diff for validity.
- *
- * This is here only for debugging purposes.
- *
- * @param mixed $from_lines
- * @param mixed $to_lines
- */
- function _check($from_lines, $to_lines) {
- if (serialize($from_lines) != serialize($this->orig()))
- trigger_error("Reconstructed original doesn't match", E_USER_ERROR);
- if (serialize($to_lines) != serialize($this->closing()))
- trigger_error("Reconstructed closing doesn't match", E_USER_ERROR);
-
- $rev = $this->reverse();
- if (serialize($to_lines) != serialize($rev->orig()))
- trigger_error("Reversed original doesn't match", E_USER_ERROR);
- if (serialize($from_lines) != serialize($rev->closing()))
- trigger_error("Reversed closing doesn't match", E_USER_ERROR);
-
- $prevtype = 'none';
- foreach ($this->edits as $edit) {
- if ($prevtype == $edit->type)
- trigger_error("Edit sequence is non-optimal", E_USER_ERROR);
- $prevtype = $edit->type;
- }
-
- $lcs = $this->lcs();
- trigger_error("Diff okay: LCS = $lcs", E_USER_NOTICE);
- }
-}
-
-/**
- * FIXME: bad name.
- */
-class MappedDiff extends Diff {
- /**
- * Constructor.
- *
- * Computes diff between sequences of strings.
- *
- * This can be used to compute things like
- * case-insensitve diffs, or diffs which ignore
- * changes in white-space.
- *
- * @param string[] $from_lines An array of strings.
- * (Typically these are lines from a file.)
- *
- * @param string[] $to_lines An array of strings.
- *
- * @param string[] $mapped_from_lines This array should
- * have the same size number of elements as $from_lines.
- * The elements in $mapped_from_lines and
- * $mapped_to_lines are what is actually compared
- * when computing the diff.
- *
- * @param string[] $mapped_to_lines This array should
- * have the same number of elements as $to_lines.
- */
- function __construct($from_lines, $to_lines, $mapped_from_lines, $mapped_to_lines) {
-
- assert(count($from_lines) == count($mapped_from_lines));
- assert(count($to_lines) == count($mapped_to_lines));
-
- parent::__construct($mapped_from_lines, $mapped_to_lines);
-
- $xi = $yi = 0;
- $ecnt = count($this->edits);
- for ($i = 0; $i < $ecnt; $i++) {
- $orig = &$this->edits[$i]->orig;
- if (is_array($orig)) {
- $orig = array_slice($from_lines, $xi, count($orig));
- $xi += count($orig);
- }
-
- $closing = &$this->edits[$i]->closing;
- if (is_array($closing)) {
- $closing = array_slice($to_lines, $yi, count($closing));
- $yi += count($closing);
- }
- }
- }
-}
-
-/**
- * A class to format Diffs
- *
- * This class formats the diff in classic diff format.
- * It is intended that this class be customized via inheritance,
- * to obtain fancier outputs.
- */
-class DiffFormatter {
- /**
- * Number of leading context "lines" to preserve.
- *
- * This should be left at zero for this class, but subclasses
- * may want to set this to other values.
- */
- var $leading_context_lines = 0;
-
- /**
- * Number of trailing context "lines" to preserve.
- *
- * This should be left at zero for this class, but subclasses
- * may want to set this to other values.
- */
- var $trailing_context_lines = 0;
-
- /**
- * Format a diff.
- *
- * @param Diff $diff A Diff object.
- * @return string The formatted output.
- */
- function format($diff) {
-
- $xi = $yi = 1;
- $x0 = $y0 = 0;
- $block = false;
- $context = array();
-
- $nlead = $this->leading_context_lines;
- $ntrail = $this->trailing_context_lines;
-
- $this->_start_diff();
-
- foreach ($diff->edits as $edit) {
- if ($edit->type == 'copy') {
- if (is_array($block)) {
- if (count($edit->orig) <= $nlead + $ntrail) {
- $block[] = $edit;
- }
- else{
- if ($ntrail) {
- $context = array_slice($edit->orig, 0, $ntrail);
- $block[] = new _DiffOp_Copy($context);
- }
- $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block);
- $block = false;
- }
- }
- $context = $edit->orig;
- }
- else {
- if (! is_array($block)) {
- $context = array_slice($context, count($context) - $nlead);
- $x0 = $xi - count($context);
- $y0 = $yi - count($context);
- $block = array();
- if ($context)
- $block[] = new _DiffOp_Copy($context);
- }
- $block[] = $edit;
- }
-
- if ($edit->orig)
- $xi += count($edit->orig);
- if ($edit->closing)
- $yi += count($edit->closing);
- }
-
- if (is_array($block))
- $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block);
-
- return $this->_end_diff();
- }
-
- /**
- * @param int $xbeg
- * @param int $xlen
- * @param int $ybeg
- * @param int $ylen
- * @param array $edits
- */
- function _block($xbeg, $xlen, $ybeg, $ylen, &$edits) {
- $this->_start_block($this->_block_header($xbeg, $xlen, $ybeg, $ylen));
- foreach ($edits as $edit) {
- if ($edit->type == 'copy')
- $this->_context($edit->orig);
- elseif ($edit->type == 'add')
- $this->_added($edit->closing);
- elseif ($edit->type == 'delete')
- $this->_deleted($edit->orig);
- elseif ($edit->type == 'change')
- $this->_changed($edit->orig, $edit->closing);
- else
- trigger_error("Unknown edit type", E_USER_ERROR);
- }
- $this->_end_block();
- }
-
- function _start_diff() {
- ob_start();
- }
-
- function _end_diff() {
- $val = ob_get_contents();
- ob_end_clean();
- return $val;
- }
-
- /**
- * @param int $xbeg
- * @param int $xlen
- * @param int $ybeg
- * @param int $ylen
- * @return string
- */
- function _block_header($xbeg, $xlen, $ybeg, $ylen) {
- if ($xlen > 1)
- $xbeg .= "," . ($xbeg + $xlen - 1);
- if ($ylen > 1)
- $ybeg .= "," . ($ybeg + $ylen - 1);
-
- return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
- }
-
- /**
- * @param string $header
- */
- function _start_block($header) {
- echo $header;
- }
-
- function _end_block() {
- }
-
- function _lines($lines, $prefix = ' ') {
- foreach ($lines as $line)
- echo "$prefix ".$this->_escape($line)."\n";
- }
-
- function _context($lines) {
- $this->_lines($lines);
- }
-
- function _added($lines) {
- $this->_lines($lines, ">");
- }
- function _deleted($lines) {
- $this->_lines($lines, "<");
- }
-
- function _changed($orig, $closing) {
- $this->_deleted($orig);
- echo "---\n";
- $this->_added($closing);
- }
-
- /**
- * Escape string
- *
- * Override this method within other formatters if escaping required.
- * Base class requires $str to be returned WITHOUT escaping.
- *
- * @param $str string Text string to escape
- * @return string The escaped string.
- */
- function _escape($str){
- return $str;
- }
-}
-
-/**
- * Utilityclass for styling HTML formatted diffs
- *
- * Depends on global var $DIFF_INLINESTYLES, if true some minimal predefined
- * inline styles are used. Useful for HTML mails and RSS feeds
- *
- * @author Andreas Gohr
- */
-class HTMLDiff {
- /**
- * Holds the style names and basic CSS
- */
- static public $styles = array(
- 'diff-addedline' => 'background-color: #ddffdd;',
- 'diff-deletedline' => 'background-color: #ffdddd;',
- 'diff-context' => 'background-color: #f5f5f5;',
- 'diff-mark' => 'color: #ff0000;',
- );
-
- /**
- * Return a class or style parameter
- *
- * @param string $classname
- *
- * @return string
- */
- static function css($classname){
- global $DIFF_INLINESTYLES;
-
- if($DIFF_INLINESTYLES){
- if(!isset(self::$styles[$classname])) return '';
- return 'style="'.self::$styles[$classname].'"';
- }else{
- return 'class="'.$classname.'"';
- }
- }
-}
-
-/**
- * Additions by Axel Boldt follow, partly taken from diff.php, phpwiki-1.3.3
- *
- */
-
-define('NBSP', "\xC2\xA0"); // utf-8 non-breaking space.
-
-class _HWLDF_WordAccumulator {
-
- function __construct() {
- $this->_lines = array();
- $this->_line = '';
- $this->_group = '';
- $this->_tag = '';
- }
-
- function _flushGroup($new_tag) {
- if ($this->_group !== '') {
- if ($this->_tag == 'mark')
- $this->_line .= ''.$this->_escape($this->_group).'';
- elseif ($this->_tag == 'add')
- $this->_line .= ''.$this->_escape($this->_group).'';
- elseif ($this->_tag == 'del')
- $this->_line .= ''.$this->_escape($this->_group).'';
- else
- $this->_line .= $this->_escape($this->_group);
- }
- $this->_group = '';
- $this->_tag = $new_tag;
- }
-
- /**
- * @param string $new_tag
- */
- function _flushLine($new_tag) {
- $this->_flushGroup($new_tag);
- if ($this->_line != '')
- $this->_lines[] = $this->_line;
- $this->_line = '';
- }
-
- function addWords($words, $tag = '') {
- if ($tag != $this->_tag)
- $this->_flushGroup($tag);
-
- foreach ($words as $word) {
- // new-line should only come as first char of word.
- if ($word == '')
- continue;
- if ($word[0] == "\n") {
- $this->_group .= NBSP;
- $this->_flushLine($tag);
- $word = substr($word, 1);
- }
- assert(!strstr($word, "\n"));
- $this->_group .= $word;
- }
- }
-
- function getLines() {
- $this->_flushLine('~done');
- return $this->_lines;
- }
-
- function _escape($str){
- return hsc($str);
- }
-}
-
-class WordLevelDiff extends MappedDiff {
-
- function __construct($orig_lines, $closing_lines) {
- list ($orig_words, $orig_stripped) = $this->_split($orig_lines);
- list ($closing_words, $closing_stripped) = $this->_split($closing_lines);
-
- parent::__construct($orig_words, $closing_words, $orig_stripped, $closing_stripped);
- }
-
- function _split($lines) {
- if (!preg_match_all('/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xsu',
- implode("\n", $lines), $m)) {
- return array(array(''), array(''));
- }
- return array($m[0], $m[1]);
- }
-
- function orig() {
- $orig = new _HWLDF_WordAccumulator;
-
- foreach ($this->edits as $edit) {
- if ($edit->type == 'copy')
- $orig->addWords($edit->orig);
- elseif ($edit->orig)
- $orig->addWords($edit->orig, 'mark');
- }
- return $orig->getLines();
- }
-
- function closing() {
- $closing = new _HWLDF_WordAccumulator;
-
- foreach ($this->edits as $edit) {
- if ($edit->type == 'copy')
- $closing->addWords($edit->closing);
- elseif ($edit->closing)
- $closing->addWords($edit->closing, 'mark');
- }
- return $closing->getLines();
- }
-}
-
-class InlineWordLevelDiff extends MappedDiff {
-
- function __construct($orig_lines, $closing_lines) {
- list ($orig_words, $orig_stripped) = $this->_split($orig_lines);
- list ($closing_words, $closing_stripped) = $this->_split($closing_lines);
-
- parent::__construct($orig_words, $closing_words, $orig_stripped, $closing_stripped);
- }
-
- function _split($lines) {
- if (!preg_match_all('/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xsu',
- implode("\n", $lines), $m)) {
- return array(array(''), array(''));
- }
- return array($m[0], $m[1]);
- }
-
- function inline() {
- $orig = new _HWLDF_WordAccumulator;
- foreach ($this->edits as $edit) {
- if ($edit->type == 'copy')
- $orig->addWords($edit->closing);
- elseif ($edit->type == 'change'){
- $orig->addWords($edit->orig, 'del');
- $orig->addWords($edit->closing, 'add');
- } elseif ($edit->type == 'delete')
- $orig->addWords($edit->orig, 'del');
- elseif ($edit->type == 'add')
- $orig->addWords($edit->closing, 'add');
- elseif ($edit->orig)
- $orig->addWords($edit->orig, 'del');
- }
- return $orig->getLines();
- }
-}
-
-/**
- * "Unified" diff formatter.
- *
- * This class formats the diff in classic "unified diff" format.
- *
- * NOTE: output is plain text and unsafe for use in HTML without escaping.
- */
-class UnifiedDiffFormatter extends DiffFormatter {
-
- function __construct($context_lines = 4) {
- $this->leading_context_lines = $context_lines;
- $this->trailing_context_lines = $context_lines;
- }
-
- function _block_header($xbeg, $xlen, $ybeg, $ylen) {
- if ($xlen != 1)
- $xbeg .= "," . $xlen;
- if ($ylen != 1)
- $ybeg .= "," . $ylen;
- return "@@ -$xbeg +$ybeg @@\n";
- }
-
- function _added($lines) {
- $this->_lines($lines, "+");
- }
- function _deleted($lines) {
- $this->_lines($lines, "-");
- }
- function _changed($orig, $final) {
- $this->_deleted($orig);
- $this->_added($final);
- }
-}
-
-/**
- * Wikipedia Table style diff formatter.
- *
- */
-class TableDiffFormatter extends DiffFormatter {
- var $colspan = 2;
-
- function __construct() {
- $this->leading_context_lines = 2;
- $this->trailing_context_lines = 2;
- }
-
- /**
- * @param Diff $diff
- * @return string
- */
- function format($diff) {
- // Preserve whitespaces by converting some to non-breaking spaces.
- // Do not convert all of them to allow word-wrap.
- $val = parent::format($diff);
- $val = str_replace(' ',' ', $val);
- $val = preg_replace('/ (?=<)|(?<=[ >]) /', ' ', $val);
- return $val;
- }
-
- function _pre($text){
- $text = htmlspecialchars($text);
- return $text;
- }
-
- function _block_header($xbeg, $xlen, $ybeg, $ylen) {
- global $lang;
- $l1 = $lang['line'].' '.$xbeg;
- $l2 = $lang['line'].' '.$ybeg;
- $r = ''.$l1.": \n".
- ''.$l2.": \n".
- " \n";
- return $r;
- }
-
- function _start_block($header) {
- print($header);
- }
-
- function _end_block() {
- }
-
- function _lines($lines, $prefix=' ', $color="white") {
- }
-
- function addedLine($line,$escaped=false) {
- if (!$escaped){
- $line = $this->_escape($line);
- }
- return '+ '.
- '' . $line.' ';
- }
-
- function deletedLine($line,$escaped=false) {
- if (!$escaped){
- $line = $this->_escape($line);
- }
- return '- '.
- '' . $line.' ';
- }
-
- function emptyLine() {
- return ' ';
- }
-
- function contextLine($line) {
- return ' '.
- ''.$this->_escape($line).' ';
- }
-
- function _added($lines) {
- $this->_addedLines($lines,false);
- }
-
- function _addedLines($lines,$escaped=false){
- foreach ($lines as $line) {
- print('' . $this->emptyLine() . $this->addedLine($line,$escaped) . " \n");
- }
- }
-
- function _deleted($lines) {
- foreach ($lines as $line) {
- print('' . $this->deletedLine($line) . $this->emptyLine() . " \n");
- }
- }
-
- function _context($lines) {
- foreach ($lines as $line) {
- print('' . $this->contextLine($line) . $this->contextLine($line) . " \n");
- }
- }
-
- function _changed($orig, $closing) {
- $diff = new WordLevelDiff($orig, $closing); // this escapes the diff data
- $del = $diff->orig();
- $add = $diff->closing();
-
- while ($line = array_shift($del)) {
- $aline = array_shift($add);
- print('' . $this->deletedLine($line,true) . $this->addedLine($aline,true) . " \n");
- }
- $this->_addedLines($add,true); # If any leftovers
- }
-
- function _escape($str) {
- return hsc($str);
- }
-}
-
-/**
- * Inline style diff formatter.
- *
- */
-class InlineDiffFormatter extends DiffFormatter {
- var $colspan = 2;
-
- function __construct() {
- $this->leading_context_lines = 2;
- $this->trailing_context_lines = 2;
- }
-
- /**
- * @param Diff $diff
- * @return string
- */
- function format($diff) {
- // Preserve whitespaces by converting some to non-breaking spaces.
- // Do not convert all of them to allow word-wrap.
- $val = parent::format($diff);
- $val = str_replace(' ',' ', $val);
- $val = preg_replace('/ (?=<)|(?<=[ >]) /', ' ', $val);
- return $val;
- }
-
- function _pre($text){
- $text = htmlspecialchars($text);
- return $text;
- }
-
- function _block_header($xbeg, $xlen, $ybeg, $ylen) {
- global $lang;
- if ($xlen != 1)
- $xbeg .= "," . $xlen;
- if ($ylen != 1)
- $ybeg .= "," . $ylen;
- $r = '@@ '.$lang['line']." -$xbeg +$ybeg @@";
- $r .= ' '.$lang['deleted'].'';
- $r .= ' '.$lang['created'].'';
- $r .= " \n";
- return $r;
- }
-
- function _start_block($header) {
- print($header."\n");
- }
-
- function _end_block() {
- }
-
- function _lines($lines, $prefix=' ', $color="white") {
- }
-
- function _added($lines) {
- foreach ($lines as $line) {
- print(' '. $this->_escape($line) . " \n");
- }
- }
-
- function _deleted($lines) {
- foreach ($lines as $line) {
- print(' ' . $this->_escape($line) . " \n");
- }
- }
-
- function _context($lines) {
- foreach ($lines as $line) {
- print(' '. $this->_escape($line) ." \n");
- }
- }
-
- function _changed($orig, $closing) {
- $diff = new InlineWordLevelDiff($orig, $closing); // this escapes the diff data
- $add = $diff->inline();
-
- foreach ($add as $line)
- print(' '.$line." \n");
- }
-
- function _escape($str) {
- return hsc($str);
- }
-}
-
-/**
- * A class for computing three way diffs.
- *
- * @author Geoffrey T. Dairiki
- */
-class Diff3 extends Diff {
-
- /**
- * Conflict counter.
- *
- * @var integer
- */
- var $_conflictingBlocks = 0;
-
- /**
- * Computes diff between 3 sequences of strings.
- *
- * @param array $orig The original lines to use.
- * @param array $final1 The first version to compare to.
- * @param array $final2 The second version to compare to.
- */
- function __construct($orig, $final1, $final2) {
- $engine = new _DiffEngine();
-
- $this->_edits = $this->_diff3($engine->diff($orig, $final1),
- $engine->diff($orig, $final2));
- }
-
- /**
- * Returns the merged lines
- *
- * @param string $label1 label for first version
- * @param string $label2 label for second version
- * @param string $label3 separator between versions
- * @return array lines of the merged text
- */
- function mergedOutput($label1='<<<<<<<',$label2='>>>>>>>',$label3='=======') {
- $lines = array();
- foreach ($this->_edits as $edit) {
- if ($edit->isConflict()) {
- /* FIXME: this should probably be moved somewhere else. */
- $lines = array_merge($lines,
- array($label1),
- $edit->final1,
- array($label3),
- $edit->final2,
- array($label2));
- $this->_conflictingBlocks++;
- } else {
- $lines = array_merge($lines, $edit->merged());
- }
- }
-
- return $lines;
- }
-
- /**
- * @access private
- *
- * @param array $edits1
- * @param array $edits2
- *
- * @return array
- */
- function _diff3($edits1, $edits2) {
- $edits = array();
- $bb = new _Diff3_BlockBuilder();
-
- $e1 = current($edits1);
- $e2 = current($edits2);
- while ($e1 || $e2) {
- if ($e1 && $e2 && is_a($e1, '_DiffOp_copy') && is_a($e2, '_DiffOp_copy')) {
- /* We have copy blocks from both diffs. This is the (only)
- * time we want to emit a diff3 copy block. Flush current
- * diff3 diff block, if any. */
- if ($edit = $bb->finish()) {
- $edits[] = $edit;
- }
-
- $ncopy = min($e1->norig(), $e2->norig());
- assert($ncopy > 0);
- $edits[] = new _Diff3_Op_copy(array_slice($e1->orig, 0, $ncopy));
-
- if ($e1->norig() > $ncopy) {
- array_splice($e1->orig, 0, $ncopy);
- array_splice($e1->closing, 0, $ncopy);
- } else {
- $e1 = next($edits1);
- }
-
- if ($e2->norig() > $ncopy) {
- array_splice($e2->orig, 0, $ncopy);
- array_splice($e2->closing, 0, $ncopy);
- } else {
- $e2 = next($edits2);
- }
- } else {
- if ($e1 && $e2) {
- if ($e1->orig && $e2->orig) {
- $norig = min($e1->norig(), $e2->norig());
- $orig = array_splice($e1->orig, 0, $norig);
- array_splice($e2->orig, 0, $norig);
- $bb->input($orig);
- }
-
- if (is_a($e1, '_DiffOp_copy')) {
- $bb->out1(array_splice($e1->closing, 0, $norig));
- }
-
- if (is_a($e2, '_DiffOp_copy')) {
- $bb->out2(array_splice($e2->closing, 0, $norig));
- }
- }
-
- if ($e1 && ! $e1->orig) {
- $bb->out1($e1->closing);
- $e1 = next($edits1);
- }
- if ($e2 && ! $e2->orig) {
- $bb->out2($e2->closing);
- $e2 = next($edits2);
- }
- }
- }
-
- if ($edit = $bb->finish()) {
- $edits[] = $edit;
- }
-
- return $edits;
- }
-}
-
-/**
- * @author Geoffrey T. Dairiki
- *
- * @access private
- */
-class _Diff3_Op {
-
- function __construct($orig = false, $final1 = false, $final2 = false) {
- $this->orig = $orig ? $orig : array();
- $this->final1 = $final1 ? $final1 : array();
- $this->final2 = $final2 ? $final2 : array();
- }
-
- function merged() {
- if (!isset($this->_merged)) {
- if ($this->final1 === $this->final2) {
- $this->_merged = &$this->final1;
- } elseif ($this->final1 === $this->orig) {
- $this->_merged = &$this->final2;
- } elseif ($this->final2 === $this->orig) {
- $this->_merged = &$this->final1;
- } else {
- $this->_merged = false;
- }
- }
-
- return $this->_merged;
- }
-
- function isConflict() {
- return $this->merged() === false;
- }
-
-}
-
-/**
- * @author Geoffrey T. Dairiki
- *
- * @access private
- */
-class _Diff3_Op_copy extends _Diff3_Op {
-
- function __construct($lines = false) {
- $this->orig = $lines ? $lines : array();
- $this->final1 = &$this->orig;
- $this->final2 = &$this->orig;
- }
-
- function merged() {
- return $this->orig;
- }
-
- function isConflict() {
- return false;
- }
-}
-
-/**
- * @author Geoffrey T. Dairiki
- *
- * @access private
- */
-class _Diff3_BlockBuilder {
-
- function __construct() {
- $this->_init();
- }
-
- function input($lines) {
- if ($lines) {
- $this->_append($this->orig, $lines);
- }
- }
-
- function out1($lines) {
- if ($lines) {
- $this->_append($this->final1, $lines);
- }
- }
-
- function out2($lines) {
- if ($lines) {
- $this->_append($this->final2, $lines);
- }
- }
-
- function isEmpty() {
- return !$this->orig && !$this->final1 && !$this->final2;
- }
-
- function finish() {
- if ($this->isEmpty()) {
- return false;
- } else {
- $edit = new _Diff3_Op($this->orig, $this->final1, $this->final2);
- $this->_init();
- return $edit;
- }
- }
-
- function _init() {
- $this->orig = $this->final1 = $this->final2 = array();
- }
-
- function _append(&$array, $lines) {
- array_splice($array, sizeof($array), 0, $lines);
- }
-}
-
-//Setup VIM: ex: et ts=4 :
diff --git a/snippets/dokuwiki-2023-04-04/inc/Draft.php b/snippets/dokuwiki-2023-04-04/inc/Draft.php
deleted file mode 100644
index ea94310..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Draft.php
+++ /dev/null
@@ -1,165 +0,0 @@
-id = $ID;
- $this->client = $client;
- $this->cname = getCacheName("$client\n$ID", '.draft');
- if(file_exists($this->cname) && file_exists(wikiFN($ID))) {
- if (filemtime($this->cname) < filemtime(wikiFN($ID))) {
- // remove stale draft
- $this->deleteDraft();
- }
- }
- }
-
- /**
- * Get the filename for this draft (whether or not it exists)
- *
- * @return string
- */
- public function getDraftFilename()
- {
- return $this->cname;
- }
-
- /**
- * Checks if this draft exists on the filesystem
- *
- * @return bool
- */
- public function isDraftAvailable()
- {
- return file_exists($this->cname);
- }
-
- /**
- * Save a draft of a current edit session
- *
- * The draft will not be saved if
- * - drafts are deactivated in the config
- * - or the editarea is empty and there are no event handlers registered
- * - or the event is prevented
- *
- * @triggers DRAFT_SAVE
- *
- * @return bool whether has the draft been saved
- */
- public function saveDraft()
- {
- global $INPUT, $INFO, $EVENT_HANDLER, $conf;
- if (!$conf['usedraft']) {
- return false;
- }
- if (!$INPUT->post->has('wikitext') &&
- !$EVENT_HANDLER->hasHandlerForEvent('DRAFT_SAVE')) {
- return false;
- }
- $draft = [
- 'id' => $this->id,
- 'prefix' => substr($INPUT->post->str('prefix'), 0, -1),
- 'text' => $INPUT->post->str('wikitext'),
- 'suffix' => $INPUT->post->str('suffix'),
- 'date' => $INPUT->post->int('date'),
- 'client' => $this->client,
- 'cname' => $this->cname,
- 'errors' => [],
- ];
- $event = new Extension\Event('DRAFT_SAVE', $draft);
- if ($event->advise_before()) {
- $draft['hasBeenSaved'] = io_saveFile($draft['cname'], serialize($draft));
- if ($draft['hasBeenSaved']) {
- $INFO['draft'] = $draft['cname'];
- }
- } else {
- $draft['hasBeenSaved'] = false;
- }
- $event->advise_after();
-
- $this->errors = $draft['errors'];
-
- return $draft['hasBeenSaved'];
- }
-
- /**
- * Get the text from the draft file
- *
- * @throws \RuntimeException if the draft file doesn't exist
- *
- * @return string
- */
- public function getDraftText()
- {
- if (!file_exists($this->cname)) {
- throw new \RuntimeException(
- "Draft for page $this->id and user $this->client doesn't exist at $this->cname."
- );
- }
- $draft = unserialize(io_readFile($this->cname,false));
- return cleanText(con($draft['prefix'],$draft['text'],$draft['suffix'],true));
- }
-
- /**
- * Remove the draft from the filesystem
- *
- * Also sets $INFO['draft'] to null
- */
- public function deleteDraft()
- {
- global $INFO;
- @unlink($this->cname);
- $INFO['draft'] = null;
- }
-
- /**
- * Get a formatted message stating when the draft was saved
- *
- * @return string
- */
- public function getDraftMessage()
- {
- global $lang;
- return $lang['draftdate'] . ' ' . dformat(filemtime($this->cname));
- }
-
- /**
- * Retrieve the errors that occured when saving the draft
- *
- * @return array
- */
- public function getErrors()
- {
- return $this->errors;
- }
-
- /**
- * Get the timestamp when this draft was saved
- *
- * @return int
- */
- public function getDraftDate()
- {
- return filemtime($this->cname);
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/ErrorHandler.php b/snippets/dokuwiki-2023-04-04/inc/ErrorHandler.php
deleted file mode 100644
index a14cbc4..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/ErrorHandler.php
+++ /dev/null
@@ -1,205 +0,0 @@
- 'E_ERROR',
- 2 => 'E_WARNING',
- 4 => 'E_PARSE',
- 8 => 'E_NOTICE',
- 16 => 'E_CORE_ERROR',
- 32 => 'E_CORE_WARNING',
- 64 => 'E_COMPILE_ERROR',
- 128 => 'E_COMPILE_WARNING',
- 256 => 'E_USER_ERROR',
- 512 => 'E_USER_WARNING',
- 1024 => 'E_USER_NOTICE',
- 2048 => 'E_STRICT',
- 4096 => 'E_RECOVERABLE_ERROR',
- 8192 => 'E_DEPRECATED',
- 16384 => 'E_USER_DEPRECATED',
- ];
-
- /**
- * Register the default error handling
- */
- public static function register()
- {
- if (!defined('DOKU_UNITTEST')) {
- set_exception_handler([ErrorHandler::class, 'fatalException']);
- register_shutdown_function([ErrorHandler::class, 'fatalShutdown']);
- set_error_handler(
- [ErrorHandler::class, 'errorHandler'],
- E_WARNING|E_USER_ERROR|E_USER_WARNING|E_RECOVERABLE_ERROR
- );
- }
- }
-
- /**
- * Default Exception handler to show a nice user message before dieing
- *
- * The exception is logged to the error log
- *
- * @param \Throwable $e
- */
- public static function fatalException($e)
- {
- $plugin = self::guessPlugin($e);
- $title = hsc(get_class($e) . ': ' . $e->getMessage());
- $msg = 'An unforeseen error has occured. This is most likely a bug somewhere.';
- if ($plugin) $msg .= ' It might be a problem in the ' . $plugin . ' plugin.';
- $logged = self::logException($e)
- ? 'More info has been written to the DokuWiki error log.'
- : $e->getFile() . ':' . $e->getLine();
-
- echo <<
-
-$title
-
-
- $title
- $msg
- $logged
-
-
-
-EOT;
- }
-
- /**
- * Convenience method to display an error message for the given Exception
- *
- * @param \Throwable $e
- * @param string $intro
- */
- public static function showExceptionMsg($e, $intro = 'Error!')
- {
- $msg = hsc($intro) . '
' . hsc(get_class($e) . ': ' . $e->getMessage());
- if (self::logException($e)) $msg .= '
More info is available in the error log.';
- msg($msg, -1);
- }
-
- /**
- * Last resort to handle fatal errors that still can't be caught
- */
- public static function fatalShutdown()
- {
- $error = error_get_last();
- // Check if it's a core/fatal error, otherwise it's a normal shutdown
- if (
- $error !== null &&
- in_array(
- $error['type'],
- [
- E_ERROR,
- E_CORE_ERROR,
- E_COMPILE_ERROR,
- ]
- )
- ) {
- self::fatalException(
- new FatalException($error['message'], 0, $error['type'], $error['file'], $error['line'])
- );
- }
- }
-
- /**
- * Log the given exception to the error log
- *
- * @param \Throwable $e
- * @return bool false if the logging failed
- */
- public static function logException($e)
- {
- if (is_a($e, \ErrorException::class)) {
- $prefix = self::ERRORCODES[$e->getSeverity()];
- } else {
- $prefix = get_class($e);
- }
-
- return Logger::getInstance()->log(
- $prefix . ': ' . $e->getMessage(),
- $e->getTraceAsString(),
- $e->getFile(),
- $e->getLine()
- );
- }
-
- /**
- * Error handler to log non-exception errors
- *
- * @param int $errno
- * @param string $errstr
- * @param string $errfile
- * @param int $errline
- * @return bool
- */
- public static function errorHandler($errno, $errstr, $errfile, $errline)
- {
- global $conf;
-
- // ignore supressed warnings
- if (!(error_reporting() & $errno)) return false;
-
- $ex = new \ErrorException(
- $errstr,
- 0,
- $errno,
- $errfile,
- $errline
- );
- self::logException($ex);
-
- if($ex->getSeverity() === E_WARNING && $conf['hidewarnings']) {
- return true;
- }
-
- return false;
- }
-
- /**
- * Checks the the stacktrace for plugin files
- *
- * @param \Throwable $e
- * @return false|string
- */
- protected static function guessPlugin($e)
- {
- if (preg_match('/lib\/plugins\/(\w+)\//', str_replace('\\', '/', $e->getFile()), $match)) {
- return $match[1];
- }
-
- foreach ($e->getTrace() as $line) {
- if (
- isset($line['class']) &&
- preg_match('/\w+?_plugin_(\w+)/', $line['class'], $match)
- ) {
- return $match[1];
- }
-
- if (
- isset($line['file']) &&
- preg_match('/lib\/plugins\/(\w+)\//', str_replace('\\', '/', $line['file']), $match)
- ) {
- return $match[1];
- }
- }
-
- return false;
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Exception/FatalException.php b/snippets/dokuwiki-2023-04-04/inc/Exception/FatalException.php
deleted file mode 100644
index f52cc66..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Exception/FatalException.php
+++ /dev/null
@@ -1,11 +0,0 @@
-
- */
-abstract class ActionPlugin extends Plugin
-{
-
- /**
- * Registers a callback function for a given event
- *
- * @param \Doku_Event_Handler $controller
- */
- abstract public function register(\Doku_Event_Handler $controller);
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Extension/AdminPlugin.php b/snippets/dokuwiki-2023-04-04/inc/Extension/AdminPlugin.php
deleted file mode 100644
index 7900a1e..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Extension/AdminPlugin.php
+++ /dev/null
@@ -1,123 +0,0 @@
-
- */
-abstract class AdminPlugin extends Plugin
-{
-
- /**
- * Return the text that is displayed at the main admin menu
- * (Default localized language string 'menu' is returned, override this function for setting another name)
- *
- * @param string $language language code
- * @return string menu string
- */
- public function getMenuText($language)
- {
- $menutext = $this->getLang('menu');
- if (!$menutext) {
- $info = $this->getInfo();
- $menutext = $info['name'] . ' ...';
- }
- return $menutext;
- }
-
- /**
- * Return the path to the icon being displayed in the main admin menu.
- * By default it tries to find an 'admin.svg' file in the plugin directory.
- * (Override this function for setting another image)
- *
- * Important: you have to return a single path, monochrome SVG icon! It has to be
- * under 2 Kilobytes!
- *
- * We recommend icons from https://materialdesignicons.com/ or to use a matching
- * style.
- *
- * @return string full path to the icon file
- */
- public function getMenuIcon()
- {
- $plugin = $this->getPluginName();
- return DOKU_PLUGIN . $plugin . '/admin.svg';
- }
-
- /**
- * Determine position in list in admin window
- * Lower values are sorted up
- *
- * @return int
- */
- public function getMenuSort()
- {
- return 1000;
- }
-
- /**
- * Carry out required processing
- */
- public function handle()
- {
- // some plugins might not need this
- }
-
- /**
- * Output html of the admin page
- */
- abstract public function html();
-
- /**
- * Checks if access should be granted to this admin plugin
- *
- * @return bool true if the current user may access this admin plugin
- */
- public function isAccessibleByCurrentUser() {
- $data = [];
- $data['instance'] = $this;
- $data['hasAccess'] = false;
-
- $event = new Event('ADMINPLUGIN_ACCESS_CHECK', $data);
- if($event->advise_before()) {
- if ($this->forAdminOnly()) {
- $data['hasAccess'] = auth_isadmin();
- } else {
- $data['hasAccess'] = auth_ismanager();
- }
- }
- $event->advise_after();
-
- return $data['hasAccess'];
- }
-
- /**
- * Return true for access only by admins (config:superuser) or false if managers are allowed as well
- *
- * @return bool
- */
- public function forAdminOnly()
- {
- return true;
- }
-
- /**
- * Return array with ToC items. Items can be created with the html_mktocitem()
- *
- * @see html_mktocitem()
- * @see tpl_toc()
- *
- * @return array
- */
- public function getTOC()
- {
- return array();
- }
-
-}
-
diff --git a/snippets/dokuwiki-2023-04-04/inc/Extension/AuthPlugin.php b/snippets/dokuwiki-2023-04-04/inc/Extension/AuthPlugin.php
deleted file mode 100644
index 4b75fba..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Extension/AuthPlugin.php
+++ /dev/null
@@ -1,461 +0,0 @@
-
- * @author Jan Schumann
- */
-abstract class AuthPlugin extends Plugin
-{
- public $success = true;
-
- /**
- * Possible things an auth backend module may be able to
- * do. The things a backend can do need to be set to true
- * in the constructor.
- */
- protected $cando = array(
- 'addUser' => false, // can Users be created?
- 'delUser' => false, // can Users be deleted?
- 'modLogin' => false, // can login names be changed?
- 'modPass' => false, // can passwords be changed?
- 'modName' => false, // can real names be changed?
- 'modMail' => false, // can emails be changed?
- 'modGroups' => false, // can groups be changed?
- 'getUsers' => false, // can a (filtered) list of users be retrieved?
- 'getUserCount' => false, // can the number of users be retrieved?
- 'getGroups' => false, // can a list of available groups be retrieved?
- 'external' => false, // does the module do external auth checking?
- 'logout' => true, // can the user logout again? (eg. not possible with HTTP auth)
- );
-
- /**
- * Constructor.
- *
- * Carry out sanity checks to ensure the object is
- * able to operate. Set capabilities in $this->cando
- * array here
- *
- * For future compatibility, sub classes should always include a call
- * to parent::__constructor() in their constructors!
- *
- * Set $this->success to false if checks fail
- *
- * @author Christopher Smith
- */
- public function __construct()
- {
- // the base class constructor does nothing, derived class
- // constructors do the real work
- }
-
- /**
- * Available Capabilities. [ DO NOT OVERRIDE ]
- *
- * For introspection/debugging
- *
- * @author Christopher Smith
- * @return array
- */
- public function getCapabilities()
- {
- return array_keys($this->cando);
- }
-
- /**
- * Capability check. [ DO NOT OVERRIDE ]
- *
- * Checks the capabilities set in the $this->cando array and
- * some pseudo capabilities (shortcutting access to multiple
- * ones)
- *
- * ususal capabilities start with lowercase letter
- * shortcut capabilities start with uppercase letter
- *
- * @author Andreas Gohr
- * @param string $cap the capability to check
- * @return bool
- */
- public function canDo($cap)
- {
- switch ($cap) {
- case 'Profile':
- // can at least one of the user's properties be changed?
- return ($this->cando['modPass'] ||
- $this->cando['modName'] ||
- $this->cando['modMail']);
- break;
- case 'UserMod':
- // can at least anything be changed?
- return ($this->cando['modPass'] ||
- $this->cando['modName'] ||
- $this->cando['modMail'] ||
- $this->cando['modLogin'] ||
- $this->cando['modGroups'] ||
- $this->cando['modMail']);
- break;
- default:
- // print a helping message for developers
- if (!isset($this->cando[$cap])) {
- msg("Check for unknown capability '$cap' - Do you use an outdated Plugin?", -1);
- }
- return $this->cando[$cap];
- }
- }
-
- /**
- * Trigger the AUTH_USERDATA_CHANGE event and call the modification function. [ DO NOT OVERRIDE ]
- *
- * You should use this function instead of calling createUser, modifyUser or
- * deleteUsers directly. The event handlers can prevent the modification, for
- * example for enforcing a user name schema.
- *
- * @author Gabriel Birke
- * @param string $type Modification type ('create', 'modify', 'delete')
- * @param array $params Parameters for the createUser, modifyUser or deleteUsers method.
- * The content of this array depends on the modification type
- * @return bool|null|int Result from the modification function or false if an event handler has canceled the action
- */
- public function triggerUserMod($type, $params)
- {
- $validTypes = array(
- 'create' => 'createUser',
- 'modify' => 'modifyUser',
- 'delete' => 'deleteUsers',
- );
- if (empty($validTypes[$type])) {
- return false;
- }
-
- $result = false;
- $eventdata = array('type' => $type, 'params' => $params, 'modification_result' => null);
- $evt = new Event('AUTH_USER_CHANGE', $eventdata);
- if ($evt->advise_before(true)) {
- $result = call_user_func_array(array($this, $validTypes[$type]), $evt->data['params']);
- $evt->data['modification_result'] = $result;
- }
- $evt->advise_after();
- unset($evt);
- return $result;
- }
-
- /**
- * Log off the current user [ OPTIONAL ]
- *
- * Is run in addition to the ususal logoff method. Should
- * only be needed when trustExternal is implemented.
- *
- * @see auth_logoff()
- * @author Andreas Gohr
- */
- public function logOff()
- {
- }
-
- /**
- * Do all authentication [ OPTIONAL ]
- *
- * Set $this->cando['external'] = true when implemented
- *
- * If this function is implemented it will be used to
- * authenticate a user - all other DokuWiki internals
- * will not be used for authenticating (except this
- * function returns null, in which case, DokuWiki will
- * still run auth_login as a fallback, which may call
- * checkPass()). If this function is not returning null,
- * implementing checkPass() is not needed here anymore.
- *
- * The function can be used to authenticate against third
- * party cookies or Apache auth mechanisms and replaces
- * the auth_login() function
- *
- * The function will be called with or without a set
- * username. If the Username is given it was called
- * from the login form and the given credentials might
- * need to be checked. If no username was given it
- * the function needs to check if the user is logged in
- * by other means (cookie, environment).
- *
- * The function needs to set some globals needed by
- * DokuWiki like auth_login() does.
- *
- * @see auth_login()
- * @author Andreas Gohr
- *
- * @param string $user Username
- * @param string $pass Cleartext Password
- * @param bool $sticky Cookie should not expire
- * @return bool true on successful auth,
- * null on unknown result (fallback to checkPass)
- */
- public function trustExternal($user, $pass, $sticky = false)
- {
- /* some example:
-
- global $USERINFO;
- global $conf;
- $sticky ? $sticky = true : $sticky = false; //sanity check
-
- // do the checking here
-
- // set the globals if authed
- $USERINFO['name'] = 'FIXME';
- $USERINFO['mail'] = 'FIXME';
- $USERINFO['grps'] = array('FIXME');
- $_SERVER['REMOTE_USER'] = $user;
- $_SESSION[DOKU_COOKIE]['auth']['user'] = $user;
- $_SESSION[DOKU_COOKIE]['auth']['pass'] = $pass;
- $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
- return true;
-
- */
- }
-
- /**
- * Check user+password [ MUST BE OVERRIDDEN ]
- *
- * Checks if the given user exists and the given
- * plaintext password is correct
- *
- * May be ommited if trustExternal is used.
- *
- * @author Andreas Gohr
- * @param string $user the user name
- * @param string $pass the clear text password
- * @return bool
- */
- public function checkPass($user, $pass)
- {
- msg("no valid authorisation system in use", -1);
- return false;
- }
-
- /**
- * Return user info [ MUST BE OVERRIDDEN ]
- *
- * Returns info about the given user needs to contain
- * at least these fields:
- *
- * name string full name of the user
- * mail string email address of the user
- * grps array list of groups the user is in
- *
- * @author Andreas Gohr
- * @param string $user the user name
- * @param bool $requireGroups whether or not the returned data must include groups
- * @return false|array containing user data or false
- */
- public function getUserData($user, $requireGroups = true)
- {
- if (!$this->cando['external']) msg("no valid authorisation system in use", -1);
- return false;
- }
-
- /**
- * Create a new User [implement only where required/possible]
- *
- * Returns false if the user already exists, null when an error
- * occurred and true if everything went well.
- *
- * The new user HAS TO be added to the default group by this
- * function!
- *
- * Set addUser capability when implemented
- *
- * @author Andreas Gohr
- * @param string $user
- * @param string $pass
- * @param string $name
- * @param string $mail
- * @param null|array $grps
- * @return bool|null
- */
- public function createUser($user, $pass, $name, $mail, $grps = null)
- {
- msg("authorisation method does not allow creation of new users", -1);
- return null;
- }
-
- /**
- * Modify user data [implement only where required/possible]
- *
- * Set the mod* capabilities according to the implemented features
- *
- * @author Chris Smith
- * @param string $user nick of the user to be changed
- * @param array $changes array of field/value pairs to be changed (password will be clear text)
- * @return bool
- */
- public function modifyUser($user, $changes)
- {
- msg("authorisation method does not allow modifying of user data", -1);
- return false;
- }
-
- /**
- * Delete one or more users [implement only where required/possible]
- *
- * Set delUser capability when implemented
- *
- * @author Chris Smith
- * @param array $users
- * @return int number of users deleted
- */
- public function deleteUsers($users)
- {
- msg("authorisation method does not allow deleting of users", -1);
- return 0;
- }
-
- /**
- * Return a count of the number of user which meet $filter criteria
- * [should be implemented whenever retrieveUsers is implemented]
- *
- * Set getUserCount capability when implemented
- *
- * @author Chris Smith
- * @param array $filter array of field/pattern pairs, empty array for no filter
- * @return int
- */
- public function getUserCount($filter = array())
- {
- msg("authorisation method does not provide user counts", -1);
- return 0;
- }
-
- /**
- * Bulk retrieval of user data [implement only where required/possible]
- *
- * Set getUsers capability when implemented
- *
- * @author Chris Smith
- * @param int $start index of first user to be returned
- * @param int $limit max number of users to be returned, 0 for unlimited
- * @param array $filter array of field/pattern pairs, null for no filter
- * @return array list of userinfo (refer getUserData for internal userinfo details)
- */
- public function retrieveUsers($start = 0, $limit = 0, $filter = null)
- {
- msg("authorisation method does not support mass retrieval of user data", -1);
- return array();
- }
-
- /**
- * Define a group [implement only where required/possible]
- *
- * Set addGroup capability when implemented
- *
- * @author Chris Smith
- * @param string $group
- * @return bool
- */
- public function addGroup($group)
- {
- msg("authorisation method does not support independent group creation", -1);
- return false;
- }
-
- /**
- * Retrieve groups [implement only where required/possible]
- *
- * Set getGroups capability when implemented
- *
- * @author Chris Smith
- * @param int $start
- * @param int $limit
- * @return array
- */
- public function retrieveGroups($start = 0, $limit = 0)
- {
- msg("authorisation method does not support group list retrieval", -1);
- return array();
- }
-
- /**
- * Return case sensitivity of the backend [OPTIONAL]
- *
- * When your backend is caseinsensitive (eg. you can login with USER and
- * user) then you need to overwrite this method and return false
- *
- * @return bool
- */
- public function isCaseSensitive()
- {
- return true;
- }
-
- /**
- * Sanitize a given username [OPTIONAL]
- *
- * This function is applied to any user name that is given to
- * the backend and should also be applied to any user name within
- * the backend before returning it somewhere.
- *
- * This should be used to enforce username restrictions.
- *
- * @author Andreas Gohr
- * @param string $user username
- * @return string the cleaned username
- */
- public function cleanUser($user)
- {
- return $user;
- }
-
- /**
- * Sanitize a given groupname [OPTIONAL]
- *
- * This function is applied to any groupname that is given to
- * the backend and should also be applied to any groupname within
- * the backend before returning it somewhere.
- *
- * This should be used to enforce groupname restrictions.
- *
- * Groupnames are to be passed without a leading '@' here.
- *
- * @author Andreas Gohr
- * @param string $group groupname
- * @return string the cleaned groupname
- */
- public function cleanGroup($group)
- {
- return $group;
- }
-
- /**
- * Check Session Cache validity [implement only where required/possible]
- *
- * DokuWiki caches user info in the user's session for the timespan defined
- * in $conf['auth_security_timeout'].
- *
- * This makes sure slow authentication backends do not slow down DokuWiki.
- * This also means that changes to the user database will not be reflected
- * on currently logged in users.
- *
- * To accommodate for this, the user manager plugin will touch a reference
- * file whenever a change is submitted. This function compares the filetime
- * of this reference file with the time stored in the session.
- *
- * This reference file mechanism does not reflect changes done directly in
- * the backend's database through other means than the user manager plugin.
- *
- * Fast backends might want to return always false, to force rechecks on
- * each page load. Others might want to use their own checking here. If
- * unsure, do not override.
- *
- * @param string $user - The username
- * @author Andreas Gohr
- * @return bool
- */
- public function useSessionCache($user)
- {
- global $conf;
- return ($_SESSION[DOKU_COOKIE]['auth']['time'] >= @filemtime($conf['cachedir'] . '/sessionpurge'));
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Extension/CLIPlugin.php b/snippets/dokuwiki-2023-04-04/inc/Extension/CLIPlugin.php
deleted file mode 100644
index 8637ccf..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Extension/CLIPlugin.php
+++ /dev/null
@@ -1,13 +0,0 @@
-name = $name;
- $this->data =& $data;
- }
-
- /**
- * @return string
- */
- public function __toString()
- {
- return $this->name;
- }
-
- /**
- * advise all registered BEFORE handlers of this event
- *
- * if these methods are used by functions outside of this object, they must
- * properly handle correct processing of any default action and issue an
- * advise_after() signal. e.g.
- * $evt = new dokuwiki\Plugin\Doku_Event(name, data);
- * if ($evt->advise_before(canPreventDefault) {
- * // default action code block
- * }
- * $evt->advise_after();
- * unset($evt);
- *
- * @param bool $enablePreventDefault
- * @return bool results of processing the event, usually $this->runDefault
- */
- public function advise_before($enablePreventDefault = true)
- {
- global $EVENT_HANDLER;
-
- $this->canPreventDefault = $enablePreventDefault;
- if ($EVENT_HANDLER !== null) {
- $EVENT_HANDLER->process_event($this, 'BEFORE');
- } else {
- Logger::getInstance(Logger::LOG_DEBUG)
- ->log($this->name . ':BEFORE event triggered before event system was initialized');
- }
-
- return (!$enablePreventDefault || $this->runDefault);
- }
-
- /**
- * advise all registered AFTER handlers of this event
- *
- * @param bool $enablePreventDefault
- * @see advise_before() for details
- */
- public function advise_after()
- {
- global $EVENT_HANDLER;
-
- $this->mayContinue = true;
-
- if ($EVENT_HANDLER !== null) {
- $EVENT_HANDLER->process_event($this, 'AFTER');
- } else {
- Logger::getInstance(Logger::LOG_DEBUG)->
- log($this->name . ':AFTER event triggered before event system was initialized');
- }
- }
-
- /**
- * trigger
- *
- * - advise all registered (_BEFORE) handlers that this event is about to take place
- * - carry out the default action using $this->data based on $enablePrevent and
- * $this->_default, all of which may have been modified by the event handlers.
- * - advise all registered (_AFTER) handlers that the event has taken place
- *
- * @param null|callable $action
- * @param bool $enablePrevent
- * @return mixed $event->results
- * the value set by any _before or handlers if the default action is prevented
- * or the results of the default action (as modified by _after handlers)
- * or NULL no action took place and no handler modified the value
- */
- public function trigger($action = null, $enablePrevent = true)
- {
-
- if (!is_callable($action)) {
- $enablePrevent = false;
- if ($action !== null) {
- trigger_error(
- 'The default action of ' . $this .
- ' is not null but also not callable. Maybe the method is not public?',
- E_USER_WARNING
- );
- }
- }
-
- if ($this->advise_before($enablePrevent) && is_callable($action)) {
- $this->result = call_user_func_array($action, [&$this->data]);
- }
-
- $this->advise_after();
-
- return $this->result;
- }
-
- /**
- * stopPropagation
- *
- * stop any further processing of the event by event handlers
- * this function does not prevent the default action taking place
- */
- public function stopPropagation()
- {
- $this->mayContinue = false;
- }
-
- /**
- * may the event propagate to the next handler?
- *
- * @return bool
- */
- public function mayPropagate()
- {
- return $this->mayContinue;
- }
-
- /**
- * preventDefault
- *
- * prevent the default action taking place
- */
- public function preventDefault()
- {
- $this->runDefault = false;
- }
-
- /**
- * should the default action be executed?
- *
- * @return bool
- */
- public function mayRunDefault()
- {
- return $this->runDefault;
- }
-
- /**
- * Convenience method to trigger an event
- *
- * Creates, triggers and destroys an event in one go
- *
- * @param string $name name for the event
- * @param mixed $data event data
- * @param callable $action (optional, default=NULL) default action, a php callback function
- * @param bool $canPreventDefault (optional, default=true) can hooks prevent the default action
- *
- * @return mixed the event results value after all event processing is complete
- * by default this is the return value of the default action however
- * it can be set or modified by event handler hooks
- */
- static public function createAndTrigger($name, &$data, $action = null, $canPreventDefault = true)
- {
- $evt = new Event($name, $data);
- return $evt->trigger($action, $canPreventDefault);
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Extension/EventHandler.php b/snippets/dokuwiki-2023-04-04/inc/Extension/EventHandler.php
deleted file mode 100644
index 33ae5e1..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Extension/EventHandler.php
+++ /dev/null
@@ -1,119 +0,0 @@
-register($this);
- }
- }
-
- /**
- * register_hook
- *
- * register a hook for an event
- *
- * @param string $event name used by the event
- * @param string $advise BEFORE|AFTER
- * @param object $obj scope for the method be executed on, NULL for global function or callable
- * @param string|callable $method event handler function
- * @param mixed $param data passed to the event handler
- * @param int $seq sequence number for ordering hook execution (ascending)
- */
- public function register_hook($event, $advise, $obj, $method, $param = null, $seq = 0)
- {
- $seq = (int)$seq;
- $doSort = !isset($this->hooks[$event . '_' . $advise][$seq]);
- $this->hooks[$event . '_' . $advise][$seq][] = array($obj, $method, $param);
-
- if ($doSort) {
- ksort($this->hooks[$event . '_' . $advise]);
- }
- }
-
- /**
- * process the before/after event
- *
- * @param Event $event
- * @param string $advise BEFORE or AFTER
- */
- public function process_event($event, $advise = '')
- {
-
- $evt_name = $event->name . ($advise ? '_' . $advise : '_BEFORE');
-
- if (!empty($this->hooks[$evt_name])) {
- foreach ($this->hooks[$evt_name] as $sequenced_hooks) {
- foreach ($sequenced_hooks as $hook) {
- list($obj, $method, $param) = $hook;
-
- if ($obj === null) {
- $method($event, $param);
- } else {
- $obj->$method($event, $param);
- }
-
- if (!$event->mayPropagate()) return;
- }
- }
- }
- }
-
- /**
- * Check if an event has any registered handlers
- *
- * When $advise is empty, both BEFORE and AFTER events will be considered,
- * otherwise only the given advisory is checked
- *
- * @param string $name Name of the event
- * @param string $advise BEFORE, AFTER or empty
- * @return bool
- */
- public function hasHandlerForEvent($name, $advise = '')
- {
- if ($advise) {
- return isset($this->hooks[$name . '_' . $advise]);
- }
-
- return isset($this->hooks[$name . '_BEFORE']) || isset($this->hooks[$name . '_AFTER']);
- }
-
- /**
- * Get all hooks and their currently registered handlers
- *
- * The handlers are sorted by sequence, then by register time
- *
- * @return array
- */
- public function getEventHandlers()
- {
- return $this->hooks;
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Extension/Plugin.php b/snippets/dokuwiki-2023-04-04/inc/Extension/Plugin.php
deleted file mode 100644
index 03637fe..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Extension/Plugin.php
+++ /dev/null
@@ -1,13 +0,0 @@
-
- */
-class PluginController
-{
- /** @var array the types of plugins DokuWiki supports */
- const PLUGIN_TYPES = ['auth', 'admin', 'syntax', 'action', 'renderer', 'helper', 'remote', 'cli'];
-
- protected $listByType = [];
- /** @var array all installed plugins and their enabled state [plugin=>enabled] */
- protected $masterList = [];
- protected $pluginCascade = ['default' => [], 'local' => [], 'protected' => []];
- protected $lastLocalConfigFile = '';
-
- /**
- * Populates the master list of plugins
- */
- public function __construct()
- {
- $this->loadConfig();
- $this->populateMasterList();
- }
-
- /**
- * Returns a list of available plugins of given type
- *
- * @param $type string, plugin_type name;
- * the type of plugin to return,
- * use empty string for all types
- * @param $all bool;
- * false to only return enabled plugins,
- * true to return both enabled and disabled plugins
- *
- * @return array of
- * - plugin names when $type = ''
- * - or plugin component names when a $type is given
- *
- * @author Andreas Gohr
- */
- public function getList($type = '', $all = false)
- {
-
- // request the complete list
- if (!$type) {
- return $all ? array_keys($this->masterList) : array_keys(array_filter($this->masterList));
- }
-
- if (!isset($this->listByType[$type]['enabled'])) {
- $this->listByType[$type]['enabled'] = $this->getListByType($type, true);
- }
- if ($all && !isset($this->listByType[$type]['disabled'])) {
- $this->listByType[$type]['disabled'] = $this->getListByType($type, false);
- }
-
- return $all
- ? array_merge($this->listByType[$type]['enabled'], $this->listByType[$type]['disabled'])
- : $this->listByType[$type]['enabled'];
- }
-
- /**
- * Loads the given plugin and creates an object of it
- *
- * @param $type string type of plugin to load
- * @param $name string name of the plugin to load
- * @param $new bool true to return a new instance of the plugin, false to use an already loaded instance
- * @param $disabled bool true to load even disabled plugins
- * @return PluginInterface|null the plugin object or null on failure
- * @author Andreas Gohr
- *
- */
- public function load($type, $name, $new = false, $disabled = false)
- {
-
- //we keep all loaded plugins available in global scope for reuse
- global $DOKU_PLUGINS;
-
- list($plugin, /* $component */) = $this->splitName($name);
-
- // check if disabled
- if (!$disabled && !$this->isEnabled($plugin)) {
- return null;
- }
-
- $class = $type . '_plugin_' . $name;
-
- try {
- //plugin already loaded?
- if (!empty($DOKU_PLUGINS[$type][$name])) {
- if ($new || !$DOKU_PLUGINS[$type][$name]->isSingleton()) {
-
- return class_exists($class, true) ? new $class : null;
- }
-
- return $DOKU_PLUGINS[$type][$name];
- }
-
- //construct class and instantiate
- if (!class_exists($class, true)) {
- # the plugin might be in the wrong directory
- $inf = confToHash(DOKU_PLUGIN . "$plugin/plugin.info.txt");
- if ($inf['base'] && $inf['base'] != $plugin) {
- msg(
- sprintf(
- "Plugin installed incorrectly. Rename plugin directory '%s' to '%s'.",
- hsc($plugin),
- hsc(
- $inf['base']
- )
- ), -1
- );
- } elseif (preg_match('/^' . DOKU_PLUGIN_NAME_REGEX . '$/', $plugin) !== 1) {
- msg(
- sprintf(
- "Plugin name '%s' is not a valid plugin name, only the characters a-z ".
- "and 0-9 are allowed. " .
- 'Maybe the plugin has been installed in the wrong directory?', hsc($plugin)
- ), -1
- );
- }
- return null;
- }
- $DOKU_PLUGINS[$type][$name] = new $class;
-
- } catch (\Throwable $e) {
- ErrorHandler::showExceptionMsg($e, sprintf('Failed to load plugin %s', $plugin));
- return null;
- }
-
- return $DOKU_PLUGINS[$type][$name];
- }
-
- /**
- * Whether plugin is disabled
- *
- * @param string $plugin name of plugin
- * @return bool true disabled, false enabled
- * @deprecated in favor of the more sensible isEnabled where the return value matches the enabled state
- */
- public function isDisabled($plugin)
- {
- dbg_deprecated('isEnabled()');
- return !$this->isEnabled($plugin);
- }
-
- /**
- * Check whether plugin is disabled
- *
- * @param string $plugin name of plugin
- * @return bool true enabled, false disabled
- */
- public function isEnabled($plugin)
- {
- return !empty($this->masterList[$plugin]);
- }
-
- /**
- * Disable the plugin
- *
- * @param string $plugin name of plugin
- * @return bool true saving succeed, false saving failed
- */
- public function disable($plugin)
- {
- if (array_key_exists($plugin, $this->pluginCascade['protected'])) return false;
- $this->masterList[$plugin] = 0;
- return $this->saveList();
- }
-
- /**
- * Enable the plugin
- *
- * @param string $plugin name of plugin
- * @return bool true saving succeed, false saving failed
- */
- public function enable($plugin)
- {
- if (array_key_exists($plugin, $this->pluginCascade['protected'])) return false;
- $this->masterList[$plugin] = 1;
- return $this->saveList();
- }
-
- /**
- * Returns cascade of the config files
- *
- * @return array with arrays of plugin configs
- */
- public function getCascade()
- {
- return $this->pluginCascade;
- }
-
- /**
- * Read all installed plugins and their current enabled state
- */
- protected function populateMasterList()
- {
- if ($dh = @opendir(DOKU_PLUGIN)) {
- $all_plugins = array();
- while (false !== ($plugin = readdir($dh))) {
- if ($plugin[0] === '.') continue; // skip hidden entries
- if (is_file(DOKU_PLUGIN . $plugin)) continue; // skip files, we're only interested in directories
-
- if (array_key_exists($plugin, $this->masterList) && $this->masterList[$plugin] == 0) {
- $all_plugins[$plugin] = 0;
-
- } elseif (array_key_exists($plugin, $this->masterList) && $this->masterList[$plugin] == 1) {
- $all_plugins[$plugin] = 1;
- } else {
- $all_plugins[$plugin] = 1;
- }
- }
- $this->masterList = $all_plugins;
- if (!file_exists($this->lastLocalConfigFile)) {
- $this->saveList(true);
- }
- }
- }
-
- /**
- * Includes the plugin config $files
- * and returns the entries of the $plugins array set in these files
- *
- * @param array $files list of files to include, latter overrides previous
- * @return array with entries of the $plugins arrays of the included files
- */
- protected function checkRequire($files)
- {
- $plugins = array();
- foreach ($files as $file) {
- if (file_exists($file)) {
- include_once($file);
- }
- }
- return $plugins;
- }
-
- /**
- * Save the current list of plugins
- *
- * @param bool $forceSave ;
- * false to save only when config changed
- * true to always save
- * @return bool true saving succeed, false saving failed
- */
- protected function saveList($forceSave = false)
- {
- global $conf;
-
- if (empty($this->masterList)) return false;
-
- // Rebuild list of local settings
- $local_plugins = $this->rebuildLocal();
- if ($local_plugins != $this->pluginCascade['local'] || $forceSave) {
- $file = $this->lastLocalConfigFile;
- $out = " $value) {
- $out .= "\$plugins['$plugin'] = $value;\n";
- }
- // backup current file (remove any existing backup)
- if (file_exists($file)) {
- $backup = $file . '.bak';
- if (file_exists($backup)) @unlink($backup);
- if (!@copy($file, $backup)) return false;
- if ($conf['fperm']) chmod($backup, $conf['fperm']);
- }
- //check if can open for writing, else restore
- return io_saveFile($file, $out);
- }
- return false;
- }
-
- /**
- * Rebuild the set of local plugins
- *
- * @return array array of plugins to be saved in end($config_cascade['plugins']['local'])
- */
- protected function rebuildLocal()
- {
- //assign to local variable to avoid overwriting
- $backup = $this->masterList;
- //Can't do anything about protected one so rule them out completely
- $local_default = array_diff_key($backup, $this->pluginCascade['protected']);
- //Diff between local+default and default
- //gives us the ones we need to check and save
- $diffed_ones = array_diff_key($local_default, $this->pluginCascade['default']);
- //The ones which we are sure of (list of 0s not in default)
- $sure_plugins = array_filter($diffed_ones, array($this, 'negate'));
- //the ones in need of diff
- $conflicts = array_diff_key($local_default, $diffed_ones);
- //The final list
- return array_merge($sure_plugins, array_diff_assoc($conflicts, $this->pluginCascade['default']));
- }
-
- /**
- * Build the list of plugins and cascade
- *
- */
- protected function loadConfig()
- {
- global $config_cascade;
- foreach (array('default', 'protected') as $type) {
- if (array_key_exists($type, $config_cascade['plugins'])) {
- $this->pluginCascade[$type] = $this->checkRequire($config_cascade['plugins'][$type]);
- }
- }
- $local = $config_cascade['plugins']['local'];
- $this->lastLocalConfigFile = array_pop($local);
- $this->pluginCascade['local'] = $this->checkRequire(array($this->lastLocalConfigFile));
- if (is_array($local)) {
- $this->pluginCascade['default'] = array_merge(
- $this->pluginCascade['default'],
- $this->checkRequire($local)
- );
- }
- $this->masterList = array_merge(
- $this->pluginCascade['default'],
- $this->pluginCascade['local'],
- $this->pluginCascade['protected']
- );
- }
-
- /**
- * Returns a list of available plugin components of given type
- *
- * @param string $type plugin_type name; the type of plugin to return,
- * @param bool $enabled true to return enabled plugins,
- * false to return disabled plugins
- * @return array of plugin components of requested type
- */
- protected function getListByType($type, $enabled)
- {
- $master_list = $enabled
- ? array_keys(array_filter($this->masterList))
- : array_keys(array_filter($this->masterList, array($this, 'negate')));
- $plugins = array();
-
- foreach ($master_list as $plugin) {
-
- if (file_exists(DOKU_PLUGIN . "$plugin/$type.php")) {
- $plugins[] = $plugin;
- continue;
- }
-
- $typedir = DOKU_PLUGIN . "$plugin/$type/";
- if (is_dir($typedir)) {
- if ($dp = opendir($typedir)) {
- while (false !== ($component = readdir($dp))) {
- if (strpos($component, '.') === 0 || strtolower(substr($component, -4)) !== '.php') continue;
- if (is_file($typedir . $component)) {
- $plugins[] = $plugin . '_' . substr($component, 0, -4);
- }
- }
- closedir($dp);
- }
- }
-
- }//foreach
-
- return $plugins;
- }
-
- /**
- * Split name in a plugin name and a component name
- *
- * @param string $name
- * @return array with
- * - plugin name
- * - and component name when available, otherwise empty string
- */
- protected function splitName($name)
- {
- if (!isset($this->masterList[$name])) {
- return sexplode('_', $name, 2, '');
- }
-
- return array($name, '');
- }
-
- /**
- * Returns inverse boolean value of the input
- *
- * @param mixed $input
- * @return bool inversed boolean value of input
- */
- protected function negate($input)
- {
- return !(bool)$input;
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Extension/PluginInterface.php b/snippets/dokuwiki-2023-04-04/inc/Extension/PluginInterface.php
deleted file mode 100644
index f2dbe86..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Extension/PluginInterface.php
+++ /dev/null
@@ -1,162 +0,0 @@
-
- */
-interface PluginInterface
-{
- /**
- * General Info
- *
- * Needs to return a associative array with the following values:
- *
- * base - the plugin's base name (eg. the directory it needs to be installed in)
- * author - Author of the plugin
- * email - Email address to contact the author
- * date - Last modified date of the plugin in YYYY-MM-DD format
- * name - Name of the plugin
- * desc - Short description of the plugin (Text only)
- * url - Website with more information on the plugin (eg. syntax description)
- */
- public function getInfo();
-
- /**
- * The type of the plugin inferred from the class name
- *
- * @return string plugin type
- */
- public function getPluginType();
-
- /**
- * The name of the plugin inferred from the class name
- *
- * @return string plugin name
- */
- public function getPluginName();
-
- /**
- * The component part of the plugin inferred from the class name
- *
- * @return string component name
- */
- public function getPluginComponent();
-
- /**
- * Access plugin language strings
- *
- * to try to minimise unnecessary loading of the strings when the plugin doesn't require them
- * e.g. when info plugin is querying plugins for information about themselves.
- *
- * @param string $id id of the string to be retrieved
- * @return string in appropriate language or english if not available
- */
- public function getLang($id);
-
- /**
- * retrieve a language dependent file and pass to xhtml renderer for display
- * plugin equivalent of p_locale_xhtml()
- *
- * @param string $id id of language dependent wiki page
- * @return string parsed contents of the wiki page in xhtml format
- */
- public function locale_xhtml($id);
-
- /**
- * Prepends appropriate path for a language dependent filename
- * plugin equivalent of localFN()
- *
- * @param string $id id of localization file
- * @param string $ext The file extension (usually txt)
- * @return string wiki text
- */
- public function localFN($id, $ext = 'txt');
-
- /**
- * Reads all the plugins language dependent strings into $this->lang
- * this function is automatically called by getLang()
- *
- * @todo this could be made protected and be moved to the trait only
- */
- public function setupLocale();
-
- /**
- * use this function to access plugin configuration variables
- *
- * @param string $setting the setting to access
- * @param mixed $notset what to return if the setting is not available
- * @return mixed
- */
- public function getConf($setting, $notset = false);
-
- /**
- * merges the plugin's default settings with any local settings
- * this function is automatically called through getConf()
- *
- * @todo this could be made protected and be moved to the trait only
- */
- public function loadConfig();
-
- /**
- * Loads a given helper plugin (if enabled)
- *
- * @author Esther Brunner
- *
- * @param string $name name of plugin to load
- * @param bool $msg if a message should be displayed in case the plugin is not available
- * @return PluginInterface|null helper plugin object
- */
- public function loadHelper($name, $msg = true);
-
- /**
- * email
- * standardised function to generate an email link according to obfuscation settings
- *
- * @param string $email
- * @param string $name
- * @param string $class
- * @param string $more
- * @return string html
- */
- public function email($email, $name = '', $class = '', $more = '');
-
- /**
- * external_link
- * standardised function to generate an external link according to conf settings
- *
- * @param string $link
- * @param string $title
- * @param string $class
- * @param string $target
- * @param string $more
- * @return string
- */
- public function external_link($link, $title = '', $class = '', $target = '', $more = '');
-
- /**
- * output text string through the parser, allows dokuwiki markup to be used
- * very ineffecient for small pieces of data - try not to use
- *
- * @param string $text wiki markup to parse
- * @param string $format output format
- * @return null|string
- */
- public function render_text($text, $format = 'xhtml');
-
- /**
- * Allow the plugin to prevent DokuWiki from reusing an instance
- *
- * @return bool false if the plugin has to be instantiated
- */
- public function isSingleton();
-}
-
-
-
diff --git a/snippets/dokuwiki-2023-04-04/inc/Extension/PluginTrait.php b/snippets/dokuwiki-2023-04-04/inc/Extension/PluginTrait.php
deleted file mode 100644
index 7f399df..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Extension/PluginTrait.php
+++ /dev/null
@@ -1,256 +0,0 @@
-getLang()
- protected $configloaded = false; // set to true by loadConfig() after loading plugin configuration variables
- protected $conf = array(); // array to hold plugin settings, best accessed via ->getConf()
-
- /**
- * @see PluginInterface::getInfo()
- */
- public function getInfo()
- {
- $parts = explode('_', get_class($this));
- $info = DOKU_PLUGIN . '/' . $parts[2] . '/plugin.info.txt';
- if (file_exists($info)) return confToHash($info);
-
- msg(
- 'getInfo() not implemented in ' . get_class($this) . ' and ' . $info . ' not found.
' .
- 'Verify you\'re running the latest version of the plugin. If the problem persists, send a ' .
- 'bug report to the author of the ' . $parts[2] . ' plugin.', -1
- );
- return array(
- 'date' => '0000-00-00',
- 'name' => $parts[2] . ' plugin',
- );
- }
-
- /**
- * @see PluginInterface::isSingleton()
- */
- public function isSingleton()
- {
- return true;
- }
-
- /**
- * @see PluginInterface::loadHelper()
- */
- public function loadHelper($name, $msg = true)
- {
- $obj = plugin_load('helper', $name);
- if (is_null($obj) && $msg) msg("Helper plugin $name is not available or invalid.", -1);
- return $obj;
- }
-
- // region introspection methods
-
- /**
- * @see PluginInterface::getPluginType()
- */
- public function getPluginType()
- {
- list($t) = explode('_', get_class($this), 2);
- return $t;
- }
-
- /**
- * @see PluginInterface::getPluginName()
- */
- public function getPluginName()
- {
- list(/* $t */, /* $p */, $n) = sexplode('_', get_class($this), 4, '');
- return $n;
- }
-
- /**
- * @see PluginInterface::getPluginComponent()
- */
- public function getPluginComponent()
- {
- list(/* $t */, /* $p */, /* $n */, $c) = sexplode('_', get_class($this), 4, '');
- return $c;
- }
-
- // endregion
- // region localization methods
-
- /**
- * @see PluginInterface::getLang()
- */
- public function getLang($id)
- {
- if (!$this->localised) $this->setupLocale();
-
- return (isset($this->lang[$id]) ? $this->lang[$id] : '');
- }
-
- /**
- * @see PluginInterface::locale_xhtml()
- */
- public function locale_xhtml($id)
- {
- return p_cached_output($this->localFN($id));
- }
-
- /**
- * @see PluginInterface::localFN()
- */
- public function localFN($id, $ext = 'txt')
- {
- global $conf;
- $plugin = $this->getPluginName();
- $file = DOKU_CONF . 'plugin_lang/' . $plugin . '/' . $conf['lang'] . '/' . $id . '.' . $ext;
- if (!file_exists($file)) {
- $file = DOKU_PLUGIN . $plugin . '/lang/' . $conf['lang'] . '/' . $id . '.' . $ext;
- if (!file_exists($file)) {
- //fall back to english
- $file = DOKU_PLUGIN . $plugin . '/lang/en/' . $id . '.' . $ext;
- }
- }
- return $file;
- }
-
- /**
- * @see PluginInterface::setupLocale()
- */
- public function setupLocale()
- {
- if ($this->localised) return;
-
- global $conf, $config_cascade; // definitely don't invoke "global $lang"
- $path = DOKU_PLUGIN . $this->getPluginName() . '/lang/';
-
- $lang = array();
-
- // don't include once, in case several plugin components require the same language file
- @include($path . 'en/lang.php');
- foreach ($config_cascade['lang']['plugin'] as $config_file) {
- if (file_exists($config_file . $this->getPluginName() . '/en/lang.php')) {
- include($config_file . $this->getPluginName() . '/en/lang.php');
- }
- }
-
- if ($conf['lang'] != 'en') {
- @include($path . $conf['lang'] . '/lang.php');
- foreach ($config_cascade['lang']['plugin'] as $config_file) {
- if (file_exists($config_file . $this->getPluginName() . '/' . $conf['lang'] . '/lang.php')) {
- include($config_file . $this->getPluginName() . '/' . $conf['lang'] . '/lang.php');
- }
- }
- }
-
- $this->lang = $lang;
- $this->localised = true;
- }
-
- // endregion
- // region configuration methods
-
- /**
- * @see PluginInterface::getConf()
- */
- public function getConf($setting, $notset = false)
- {
-
- if (!$this->configloaded) {
- $this->loadConfig();
- }
-
- if (isset($this->conf[$setting])) {
- return $this->conf[$setting];
- } else {
- return $notset;
- }
- }
-
- /**
- * @see PluginInterface::loadConfig()
- */
- public function loadConfig()
- {
- global $conf;
-
- $defaults = $this->readDefaultSettings();
- $plugin = $this->getPluginName();
-
- foreach ($defaults as $key => $value) {
- if (isset($conf['plugin'][$plugin][$key])) continue;
- $conf['plugin'][$plugin][$key] = $value;
- }
-
- $this->configloaded = true;
- $this->conf =& $conf['plugin'][$plugin];
- }
-
- /**
- * read the plugin's default configuration settings from conf/default.php
- * this function is automatically called through getConf()
- *
- * @return array setting => value
- */
- protected function readDefaultSettings()
- {
-
- $path = DOKU_PLUGIN . $this->getPluginName() . '/conf/';
- $conf = array();
-
- if (file_exists($path . 'default.php')) {
- include($path . 'default.php');
- }
-
- return $conf;
- }
-
- // endregion
- // region output methods
-
- /**
- * @see PluginInterface::email()
- */
- public function email($email, $name = '', $class = '', $more = '')
- {
- if (!$email) return $name;
- $email = obfuscate($email);
- if (!$name) $name = $email;
- $class = "class='" . ($class ? $class : 'mail') . "'";
- return "$name";
- }
-
- /**
- * @see PluginInterface::external_link()
- */
- public function external_link($link, $title = '', $class = '', $target = '', $more = '')
- {
- global $conf;
-
- $link = htmlentities($link);
- if (!$title) $title = $link;
- if (!$target) $target = $conf['target']['extern'];
- if ($conf['relnofollow']) $more .= ' rel="nofollow"';
-
- if ($class) $class = " class='$class'";
- if ($target) $target = " target='$target'";
- if ($more) $more = " " . trim($more);
-
- return "$title";
- }
-
- /**
- * @see PluginInterface::render_text()
- */
- public function render_text($text, $format = 'xhtml')
- {
- return p_render($format, p_get_instructions($text), $info);
- }
-
- // endregion
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Extension/RemotePlugin.php b/snippets/dokuwiki-2023-04-04/inc/Extension/RemotePlugin.php
deleted file mode 100644
index 33bca98..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Extension/RemotePlugin.php
+++ /dev/null
@@ -1,122 +0,0 @@
-api = new Api();
- }
-
- /**
- * Get all available methods with remote access.
- *
- * By default it exports all public methods of a remote plugin. Methods beginning
- * with an underscore are skipped.
- *
- * @return array Information about all provided methods. {@see dokuwiki\Remote\RemoteAPI}.
- * @throws ReflectionException
- */
- public function _getMethods()
- {
- $result = array();
-
- $reflection = new \ReflectionClass($this);
- foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
- // skip parent methods, only methods further down are exported
- $declaredin = $method->getDeclaringClass()->name;
- if ($declaredin === 'dokuwiki\Extension\Plugin' || $declaredin === 'dokuwiki\Extension\RemotePlugin') {
- continue;
- }
- $method_name = $method->name;
- if (strpos($method_name, '_') === 0) {
- continue;
- }
-
- // strip asterisks
- $doc = $method->getDocComment();
- $doc = preg_replace(
- array('/^[ \t]*\/\*+[ \t]*/m', '/[ \t]*\*+[ \t]*/m', '/\*+\/\s*$/m', '/\s*\/\s*$/m'),
- array('', '', '', ''),
- $doc
- );
-
- // prepare data
- $data = array();
- $data['name'] = $method_name;
- $data['public'] = 0;
- $data['doc'] = $doc;
- $data['args'] = array();
-
- // get parameter type from doc block type hint
- foreach ($method->getParameters() as $parameter) {
- $name = $parameter->name;
- $type = 'string'; // we default to string
- if (preg_match('/^@param[ \t]+([\w|\[\]]+)[ \t]\$' . $name . '/m', $doc, $m)) {
- $type = $this->cleanTypeHint($m[1]);
- }
- $data['args'][] = $type;
- }
-
- // get return type from doc block type hint
- if (preg_match('/^@return[ \t]+([\w|\[\]]+)/m', $doc, $m)) {
- $data['return'] = $this->cleanTypeHint($m[1]);
- } else {
- $data['return'] = 'string';
- }
-
- // add to result
- $result[$method_name] = $data;
- }
-
- return $result;
- }
-
- /**
- * Matches the given type hint against the valid options for the remote API
- *
- * @param string $hint
- * @return string
- */
- protected function cleanTypeHint($hint)
- {
- $types = explode('|', $hint);
- foreach ($types as $t) {
- if (substr($t, -2) === '[]') {
- return 'array';
- }
- if ($t === 'boolean') {
- return 'bool';
- }
- if (in_array($t, array('array', 'string', 'int', 'double', 'bool', 'null', 'date', 'file'))) {
- return $t;
- }
- }
- return 'string';
- }
-
- /**
- * @return Api
- */
- protected function getApi()
- {
- return $this->api;
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Extension/SyntaxPlugin.php b/snippets/dokuwiki-2023-04-04/inc/Extension/SyntaxPlugin.php
deleted file mode 100644
index ea8f51b..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Extension/SyntaxPlugin.php
+++ /dev/null
@@ -1,132 +0,0 @@
-
- */
-abstract class SyntaxPlugin extends \dokuwiki\Parsing\ParserMode\Plugin
-{
- use PluginTrait;
-
- protected $allowedModesSetup = false;
-
- /**
- * Syntax Type
- *
- * Needs to return one of the mode types defined in $PARSER_MODES in Parser.php
- *
- * @return string
- */
- abstract public function getType();
-
- /**
- * Allowed Mode Types
- *
- * Defines the mode types for other dokuwiki markup that maybe nested within the
- * plugin's own markup. Needs to return an array of one or more of the mode types
- * defined in $PARSER_MODES in Parser.php
- *
- * @return array
- */
- public function getAllowedTypes()
- {
- return array();
- }
-
- /**
- * Paragraph Type
- *
- * Defines how this syntax is handled regarding paragraphs. This is important
- * for correct XHTML nesting. Should return one of the following:
- *
- * 'normal' - The plugin can be used inside paragraphs
- * 'block' - Open paragraphs need to be closed before plugin output
- * 'stack' - Special case. Plugin wraps other paragraphs.
- *
- * @see Doku_Handler_Block
- *
- * @return string
- */
- public function getPType()
- {
- return 'normal';
- }
-
- /**
- * Handler to prepare matched data for the rendering process
- *
- * This function can only pass data to render() via its return value - render()
- * may be not be run during the object's current life.
- *
- * Usually you should only need the $match param.
- *
- * @param string $match The text matched by the patterns
- * @param int $state The lexer state for the match
- * @param int $pos The character position of the matched text
- * @param Doku_Handler $handler The Doku_Handler object
- * @return bool|array Return an array with all data you want to use in render, false don't add an instruction
- */
- abstract public function handle($match, $state, $pos, Doku_Handler $handler);
-
- /**
- * Handles the actual output creation.
- *
- * The function must not assume any other of the classes methods have been run
- * during the object's current life. The only reliable data it receives are its
- * parameters.
- *
- * The function should always check for the given output format and return false
- * when a format isn't supported.
- *
- * $renderer contains a reference to the renderer object which is
- * currently handling the rendering. You need to use it for writing
- * the output. How this is done depends on the renderer used (specified
- * by $format
- *
- * The contents of the $data array depends on what the handler() function above
- * created
- *
- * @param string $format output format being rendered
- * @param Doku_Renderer $renderer the current renderer object
- * @param array $data data created by handler()
- * @return boolean rendered correctly? (however, returned value is not used at the moment)
- */
- abstract public function render($format, Doku_Renderer $renderer, $data);
-
- /**
- * There should be no need to override this function
- *
- * @param string $mode
- * @return bool
- */
- public function accepts($mode)
- {
-
- if (!$this->allowedModesSetup) {
- global $PARSER_MODES;
-
- $allowedModeTypes = $this->getAllowedTypes();
- foreach ($allowedModeTypes as $mt) {
- $this->allowedModes = array_merge($this->allowedModes, $PARSER_MODES[$mt]);
- }
-
- $idx = array_search(substr(get_class($this), 7), (array)$this->allowedModes);
- if ($idx !== false) {
- unset($this->allowedModes[$idx]);
- }
- $this->allowedModesSetup = true;
- }
-
- return parent::accepts($mode);
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/FeedParser.php b/snippets/dokuwiki-2023-04-04/inc/FeedParser.php
deleted file mode 100644
index 028f113..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/FeedParser.php
+++ /dev/null
@@ -1,31 +0,0 @@
-enable_cache(false);
- $this->registry->register(File::class, FeedParserFile::class);
- }
-
- /**
- * Backward compatibility for older plugins
- *
- * phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
- * @param string $url
- */
- public function feed_url($url){
- $this->set_feed_url($url);
- }
-}
-
-
diff --git a/snippets/dokuwiki-2023-04-04/inc/FeedParserFile.php b/snippets/dokuwiki-2023-04-04/inc/FeedParserFile.php
deleted file mode 100644
index b056530..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/FeedParserFile.php
+++ /dev/null
@@ -1,62 +0,0 @@
-http = new DokuHTTPClient();
- $this->success = $this->http->sendRequest($url);
-
- $this->headers = $this->http->resp_headers;
- $this->body = $this->http->resp_body;
- $this->error = $this->http->error;
-
- $this->method = \SimplePie\SimplePie::FILE_SOURCE_REMOTE | \SimplePie\SimplePie::FILE_SOURCE_FSOCKOPEN;
-
- return $this->success;
- }
-
- /** @inheritdoc */
- public function headers()
- {
- return $this->headers;
- }
-
- /** @inheritdoc */
- public function body()
- {
- return $this->body;
- }
-
- /** @inheritdoc */
- public function close()
- {
- return true;
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/File/MediaFile.php b/snippets/dokuwiki-2023-04-04/inc/File/MediaFile.php
deleted file mode 100644
index d45822a..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/File/MediaFile.php
+++ /dev/null
@@ -1,166 +0,0 @@
-id = $id; //FIXME should it be cleaned?
- $this->path = mediaFN($id, $rev);
-
- list($this->ext, $this->mime, $this->downloadable) = mimetype($this->path, false);
- }
-
- /** @return string */
- public function getId()
- {
- return $this->id;
- }
-
- /** @return string */
- public function getPath()
- {
- return $this->path;
- }
-
- /**
- * The ID without namespace, used for display purposes
- *
- * @return string
- */
- public function getDisplayName()
- {
- return noNS($this->id);
- }
-
- /** @return string */
- public function getMime()
- {
- if (!$this->mime) return 'application/octet-stream';
- return $this->mime;
- }
-
- /** @return string */
- public function getExtension()
- {
- return (string)$this->ext;
- }
-
- /**
- * Similar to the extesion but does some clean up
- *
- * @return string
- */
- public function getIcoClass()
- {
- $ext = $this->getExtension();
- if ($ext === '') $ext = 'file';
- return preg_replace('/[^_\-a-z0-9]+/i', '_', $ext);
- }
-
- /**
- * Should this file be downloaded instead being displayed inline?
- *
- * @return bool
- */
- public function isDownloadable()
- {
- return $this->downloadable;
- }
-
- /** @return int */
- public function getFileSize()
- {
- return filesize($this->path);
- }
-
- /** @return int */
- public function getLastModified()
- {
- return filemtime($this->path);
- }
-
- /** @return bool */
- public function isWritable()
- {
- return is_writable($this->path);
- }
-
- /** @return bool */
- public function isImage()
- {
- return (substr($this->mime, 0, 6) === 'image/');
- }
-
- /**
- * initializes width and height for images when requested
- */
- protected function initSizes()
- {
- $this->width = 0;
- $this->height = 0;
- if (!$this->isImage()) return;
- $info = getimagesize($this->path);
- if ($info === false) return;
- list($this->width, $this->height) = $info;
- }
-
- /**
- * Returns the width if this is a supported image, 0 otherwise
- *
- * @return int
- */
- public function getWidth()
- {
- if ($this->width === null) $this->initSizes();
- return $this->width;
- }
-
- /**
- * Returns the height if this is a supported image, 0 otherwise
- *
- * @return int
- */
- public function getHeight()
- {
- if ($this->height === null) $this->initSizes();
- return $this->height;
- }
-
- /**
- * Returns the permissions the current user has on the file
- *
- * @todo doing this for each file within a namespace is a waste, we need to cache this somehow
- * @return int
- */
- public function userPermission()
- {
- return auth_quickaclcheck(getNS($this->id).':*');
- }
-
- /** @return JpegMeta */
- public function getMeta()
- {
- if($this->meta === null) $this->meta = new JpegMeta($this->path);
- return $this->meta;
- }
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/File/MediaResolver.php b/snippets/dokuwiki-2023-04-04/inc/File/MediaResolver.php
deleted file mode 100644
index 098584e..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/File/MediaResolver.php
+++ /dev/null
@@ -1,15 +0,0 @@
-id = $id;
- $this->changelog = new PageChangeLog($this->id);
- }
-
- /** @return string */
- public function getId()
- {
- return $this->id;
- }
-
- /** @return string */
- public function getPath($rev = '')
- {
- return wikiFN($this->id, $rev);
- }
-
- /**
- * Get raw WikiText of the page, considering change type at revision date
- * similar to function rawWiki($id, $rev = '')
- *
- * @param int|false $rev timestamp when a revision of wikitext is desired
- * @return string
- */
- public function rawWikiText($rev = null)
- {
- if ($rev !== null) {
- $revInfo = $rev ? $this->changelog->getRevisionInfo($rev) : false;
- return (!$revInfo || $revInfo['type'] == DOKU_CHANGE_TYPE_DELETE)
- ? '' // attic stores complete last page version for a deleted page
- : io_readWikiPage($this->getPath($rev), $this->id, $rev); // retrieve from attic
- } else {
- return io_readWikiPage($this->getPath(), $this->id, '');
- }
- }
-
- /**
- * Saves a wikitext by calling io_writeWikiPage.
- * Also directs changelog and attic updates.
- *
- * @author Andreas Gohr
- * @author Ben Coburn
- *
- * @param string $text wikitext being saved
- * @param string $summary summary of text update
- * @param bool $minor mark this saved version as minor update
- * @return array|void data of event COMMON_WIKIPAGE_SAVE
- */
- public function saveWikiText($text, $summary, $minor = false)
- {
- /* Note to developers:
- This code is subtle and delicate. Test the behavior of
- the attic and changelog with dokuwiki and external edits
- after any changes. External edits change the wiki page
- directly without using php or dokuwiki.
- */
- global $conf;
- global $lang;
- global $REV;
- /* @var Input $INPUT */
- global $INPUT;
-
- // prevent recursive call
- if (isset($this->data)) return;
-
- $pagefile = $this->getPath();
- $currentRevision = @filemtime($pagefile); // int or false
- $currentContent = $this->rawWikiText();
- $currentSize = file_exists($pagefile) ? filesize($pagefile) : 0;
-
- // prepare data for event COMMON_WIKIPAGE_SAVE
- $data = array(
- 'id' => $this->id, // should not be altered by any handlers
- 'file' => $pagefile, // same above
- 'changeType' => null, // set prior to event, and confirm later
- 'revertFrom' => $REV,
- 'oldRevision' => $currentRevision,
- 'oldContent' => $currentContent,
- 'newRevision' => 0, // only available in the after hook
- 'newContent' => $text,
- 'summary' => $summary,
- 'contentChanged' => ($text != $currentContent), // confirm later
- 'changeInfo' => '', // automatically determined by revertFrom
- 'sizechange' => strlen($text) - strlen($currentContent), // TBD
- );
-
- // determine tentatively change type and relevant elements of event data
- if ($data['revertFrom']) {
- // new text may differ from exact revert revision
- $data['changeType'] = DOKU_CHANGE_TYPE_REVERT;
- $data['changeInfo'] = $REV;
- } elseif (trim($data['newContent']) == '') {
- // empty or whitespace only content deletes
- $data['changeType'] = DOKU_CHANGE_TYPE_DELETE;
- } elseif (!file_exists($pagefile)) {
- $data['changeType'] = DOKU_CHANGE_TYPE_CREATE;
- } else {
- // minor edits allowable only for logged in users
- $is_minor_change = ($minor && $conf['useacl'] && $INPUT->server->str('REMOTE_USER'));
- $data['changeType'] = $is_minor_change
- ? DOKU_CHANGE_TYPE_MINOR_EDIT
- : DOKU_CHANGE_TYPE_EDIT;
- }
-
- $this->data = $data;
- $data['page'] = $this; // allow event handlers to use this class methods
-
- $event = new Event('COMMON_WIKIPAGE_SAVE', $data);
- if (!$event->advise_before()) return;
-
- // if the content has not been changed, no save happens (plugins may override this)
- if (!$data['contentChanged']) return;
-
- // Check whether the pagefile has modified during $event->advise_before()
- clearstatcache();
- $fileRev = @filemtime($pagefile);
- if ($fileRev === $currentRevision) {
- // pagefile has not touched by plugin's event handler
- // add a potential external edit entry to changelog and store it into attic
- $this->detectExternalEdit();
- $filesize_old = $currentSize;
- } else {
- // pagefile has modified by plugin's event handler, confirm sizechange
- $filesize_old = (
- $data['changeType'] == DOKU_CHANGE_TYPE_CREATE || (
- $data['changeType'] == DOKU_CHANGE_TYPE_REVERT && !file_exists($pagefile))
- ) ? 0 : filesize($pagefile);
- }
-
- // make change to the current file
- if ($data['changeType'] == DOKU_CHANGE_TYPE_DELETE) {
- // nothing to do when the file has already deleted
- if (!file_exists($pagefile)) return;
- // autoset summary on deletion
- if (blank($data['summary'])) {
- $data['summary'] = $lang['deleted'];
- }
- // send "update" event with empty data, so plugins can react to page deletion
- $ioData = array([$pagefile, '', false], getNS($this->id), noNS($this->id), false);
- Event::createAndTrigger('IO_WIKIPAGE_WRITE', $ioData);
- // pre-save deleted revision
- @touch($pagefile);
- clearstatcache();
- $data['newRevision'] = $this->saveOldRevision();
- // remove empty file
- @unlink($pagefile);
- $filesize_new = 0;
- // don't remove old meta info as it should be saved, plugins can use
- // IO_WIKIPAGE_WRITE for removing their metadata...
- // purge non-persistant meta data
- p_purge_metadata($this->id);
- // remove empty namespaces
- io_sweepNS($this->id, 'datadir');
- io_sweepNS($this->id, 'mediadir');
- } else {
- // save file (namespace dir is created in io_writeWikiPage)
- io_writeWikiPage($pagefile, $data['newContent'], $this->id);
- // pre-save the revision, to keep the attic in sync
- $data['newRevision'] = $this->saveOldRevision();
- $filesize_new = filesize($pagefile);
- }
- $data['sizechange'] = $filesize_new - $filesize_old;
-
- $event->advise_after();
-
- unset($data['page']);
-
- // adds an entry to the changelog and saves the metadata for the page
- $logEntry = $this->changelog->addLogEntry([
- 'date' => $data['newRevision'],
- 'ip' => clientIP(true),
- 'type' => $data['changeType'],
- 'id' => $this->id,
- 'user' => $INPUT->server->str('REMOTE_USER'),
- 'sum' => $data['summary'],
- 'extra' => $data['changeInfo'],
- 'sizechange' => $data['sizechange'],
- ]);
- // update metadata
- $this->updateMetadata($logEntry);
-
- // update the purgefile (timestamp of the last time anything within the wiki was changed)
- io_saveFile($conf['cachedir'].'/purgefile', time());
-
- return $data;
- }
-
- /**
- * Checks if the current page version is newer than the last entry in the page's changelog.
- * If so, we assume it has been an external edit and we create an attic copy and add a proper
- * changelog line.
- *
- * This check is only executed when the page is about to be saved again from the wiki,
- * triggered in @see saveWikiText()
- */
- public function detectExternalEdit()
- {
- $revInfo = $this->changelog->getCurrentRevisionInfo();
-
- // only interested in external revision
- if (empty($revInfo) || !array_key_exists('timestamp', $revInfo)) return;
-
- if ($revInfo['type'] != DOKU_CHANGE_TYPE_DELETE && !$revInfo['timestamp']) {
- // file is older than last revision, that is erroneous/incorrect occurence.
- // try to change file modification time
- $fileLastMod = $this->getPath();
- $wrong_timestamp = filemtime($fileLastMod);
- if (touch($fileLastMod, $revInfo['date'])) {
- clearstatcache();
- $msg = "PageFile($this->id)::detectExternalEdit(): timestamp successfully modified";
- $details = '('.$wrong_timestamp.' -> '.$revInfo['date'].')';
- Logger::error($msg, $details, $fileLastMod);
- } else {
- // runtime error
- $msg = "PageFile($this->id)::detectExternalEdit(): page file should be newer than last revision "
- .'('.filemtime($fileLastMod).' < '. $this->changelog->lastRevision() .')';
- throw new RuntimeException($msg);
- }
- }
-
- // keep at least 1 sec before new page save
- if ($revInfo['date'] == time()) sleep(1); // wait a tick
-
- // store externally edited file to the attic folder
- $this->saveOldRevision();
- // add a changelog entry for externally edited file
- $this->changelog->addLogEntry($revInfo);
- // remove soon to be stale instructions
- $cache = new CacheInstructions($this->id, $this->getPath());
- $cache->removeCache();
- }
-
- /**
- * Moves the current version to the attic and returns its revision date
- *
- * @author Andreas Gohr
- *
- * @return int|string revision timestamp
- */
- public function saveOldRevision()
- {
- $oldfile = $this->getPath();
- if (!file_exists($oldfile)) return '';
- $date = filemtime($oldfile);
- $newfile = $this->getPath($date);
- io_writeWikiPage($newfile, $this->rawWikiText(), $this->id, $date);
- return $date;
- }
-
- /**
- * Update metadata of changed page
- *
- * @param array $logEntry changelog entry
- */
- public function updateMetadata(array $logEntry)
- {
- global $INFO;
-
- list(
- 'date' => $date,
- 'type' => $changeType,
- 'user' => $user,
- ) = $logEntry;
-
- $wasRemoved = ($changeType === DOKU_CHANGE_TYPE_DELETE);
- $wasCreated = ($changeType === DOKU_CHANGE_TYPE_CREATE);
- $wasReverted = ($changeType === DOKU_CHANGE_TYPE_REVERT);
- $wasMinorEdit = ($changeType === DOKU_CHANGE_TYPE_MINOR_EDIT);
-
- $createdDate = @filectime($this->getPath());
-
- if ($wasRemoved) return;
-
- $oldmeta = p_read_metadata($this->id)['persistent'];
- $meta = array();
-
- if ($wasCreated &&
- (empty($oldmeta['date']['created']) || $oldmeta['date']['created'] === $createdDate)
- ) {
- // newly created
- $meta['date']['created'] = $createdDate;
- if ($user) {
- $meta['creator'] = $INFO['userinfo']['name'] ?? null;
- $meta['user'] = $user;
- }
- } elseif (($wasCreated || $wasReverted) && !empty($oldmeta['date']['created'])) {
- // re-created / restored
- $meta['date']['created'] = $oldmeta['date']['created'];
- $meta['date']['modified'] = $createdDate; // use the files ctime here
- $meta['creator'] = $oldmeta['creator'] ?? null;
- if ($user) {
- $meta['contributor'][$user] = $INFO['userinfo']['name'] ?? null;
- }
- } elseif (!$wasMinorEdit) { // non-minor modification
- $meta['date']['modified'] = $date;
- if ($user) {
- $meta['contributor'][$user] = $INFO['userinfo']['name'] ?? null;
- }
- }
- $meta['last_change'] = $logEntry;
- p_set_metadata($this->id, $meta);
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/File/PageResolver.php b/snippets/dokuwiki-2023-04-04/inc/File/PageResolver.php
deleted file mode 100644
index 1c10ea6..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/File/PageResolver.php
+++ /dev/null
@@ -1,99 +0,0 @@
-resolveStartPage($id, $rev, $isDateAt);
- if ($conf['autoplural']) {
- $id = $this->resolveAutoPlural($id, $rev, $isDateAt);
- }
- } else {
- $id = $this->contextID;
- }
-
- $id = cleanID($id); // FIXME always? or support parameter
- // readd hash if any
- if ($hash !== '') $id .= "#$hash";
- return $id;
- }
-
- /**
- * IDs ending in :
- *
- * @param string $id
- * @param string|int|false $rev
- * @param bool $isDateAt
- * @return string
- */
- protected function resolveStartPage($id, $rev, $isDateAt)
- {
- global $conf;
-
- if ($id[-1] !== ':') return $id;
-
- if (page_exists($id . $conf['start'], $rev, true, $isDateAt)) {
- // start page inside namespace
- return $id . $conf['start'];
- } elseif (page_exists($id . noNS(cleanID($id)), $rev, true, $isDateAt)) {
- // page named like the NS inside the NS
- return $id . noNS(cleanID($id));
- } elseif (page_exists(substr($id, 0, -1), $rev, true, $isDateAt)) {
- // page named like the NS outside the NS
- return substr($id, 0, -1);
- }
-
- // fall back to default start page
- return $id . $conf['start'];
- }
-
- /**
- * Try alternative plural/singular form
- *
- * @param string $id
- * @param int $rev
- * @param bool $isDateAt
- * @return string
- */
- protected function resolveAutoPlural($id, $rev, $isDateAt)
- {
- if (page_exists($id, $rev, $isDateAt)) return $id;
-
- if ($id[-1] === 's') {
- $try = substr($id, 0, -1);
- } else {
- $try = $id . 's';
- }
-
- if (page_exists($try, $rev, true, $isDateAt)) {
- return $try;
- }
- return $id;
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/File/Resolver.php b/snippets/dokuwiki-2023-04-04/inc/File/Resolver.php
deleted file mode 100644
index e3734cf..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/File/Resolver.php
+++ /dev/null
@@ -1,106 +0,0 @@
-contextID = $contextID;
- $this->contextNS = (string)getNS($contextID);
- }
-
- /**
- * Resolves a given ID to be absolute
- *
- * @param string $id The ID to resolve
- * @param string|int|false $rev The revision time to use when resolving
- * @param bool $isDateAt Is the given revision only a datetime hint not an exact revision?
- * @return string
- */
- public function resolveId($id, $rev = '', $isDateAt = false)
- {
- global $conf;
-
- // some pre cleaning for useslash:
- if ($conf['useslash']) $id = str_replace('/', ':', $id);
- // on some systems, semicolons might be used instead of colons:
- $id = str_replace(';', ':', $id);
-
- $id = $this->resolvePrefix($id);
- return $this->resolveRelatives($id);
- }
-
- /**
- * Handle IDs starting with . or ~ and prepend the proper prefix
- *
- * @param string $id
- * @return string
- */
- protected function resolvePrefix($id)
- {
- if($id === '') return $id;
-
- // relative to current page (makes the current page a start page)
- if ($id[0] === '~') {
- $id = $this->contextID . ':' . substr($id, 1);
- }
-
- // relative to current namespace
- if ($id[0] === '.') {
- // normalize initial dots without a colon
- $id = preg_replace('/^((\.+:)*)(\.+)(?=[^:\.])/', '\1\3:', $id);
- $id = $this->contextNS . ':' . $id;
- }
-
- // auto-relative, because there is a context namespace but no namespace in the ID
- if ($this->contextID !== '' && strpos($id, ':') === false) {
- $id = $this->contextNS . ':' . $id;
- }
-
- return $id;
- }
-
- /**
- * Handle . and .. within IDs
- *
- * @param string $id
- * @return string
- */
- protected function resolveRelatives($id)
- {
- if ($id === '') return '';
- $trail = ($id[-1] === ':') ? ':' : ''; // keep trailing colon
-
- $result = [];
- $parts = explode(':', $id);
-
- foreach ($parts as $dir) {
- if ($dir === '.') continue;
- if ($dir === '') continue;
- if ($dir === '..') {
- array_pop($result);
- continue;
- }
- array_push($result, $dir);
- }
-
- $id = implode(':', $result);
- $id .= $trail;
-
- return $id;
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Form/ButtonElement.php b/snippets/dokuwiki-2023-04-04/inc/Form/ButtonElement.php
deleted file mode 100644
index 3e110c6..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Form/ButtonElement.php
+++ /dev/null
@@ -1,37 +0,0 @@
- $name, 'value' => 1));
- $this->content = $content;
- }
-
- /**
- * The HTML representation of this element
- *
- * @return string
- */
- public function toHTML()
- {
- return '';
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Form/CheckableElement.php b/snippets/dokuwiki-2023-04-04/inc/Form/CheckableElement.php
deleted file mode 100644
index d70672b..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Form/CheckableElement.php
+++ /dev/null
@@ -1,83 +0,0 @@
-attr('value', 1);
- }
-
- /**
- * Handles the useInput flag and sets the checked attribute accordingly
- */
- protected function prefillInput()
- {
- global $INPUT;
- list($name, $key) = $this->getInputName();
- $myvalue = $this->val();
-
- if (!$INPUT->has($name)) return;
-
- if ($key === null) {
- // no key - single value
- $value = $INPUT->str($name);
- if ($value == $myvalue) {
- $this->attr('checked', 'checked');
- } else {
- $this->rmattr('checked');
- }
- } else {
- // we have an array, there might be several values in it
- $input = $INPUT->arr($name);
- if (isset($input[$key])) {
- $this->rmattr('checked');
-
- // values seem to be in another sub array
- if (is_array($input[$key])) {
- $input = $input[$key];
- }
-
- foreach ($input as $value) {
- if ($value == $myvalue) {
- $this->attr('checked', 'checked');
- }
- }
- }
- }
- }
-
- /**
- * The HTML representation of this element wrapped in a label
- * Note: allow HTML tags in label text
- *
- * @return string
- */
- public function toHTML()
- {
- if ($this->label) {
- return '';
- } else {
- return $this->mainElementHTML();
- }
- }
-
-}
diff --git a/snippets/dokuwiki-2023-04-04/inc/Form/DropdownElement.php b/snippets/dokuwiki-2023-04-04/inc/Form/DropdownElement.php
deleted file mode 100644
index e5628cf..0000000
--- a/snippets/dokuwiki-2023-04-04/inc/Form/DropdownElement.php
+++ /dev/null
@@ -1,202 +0,0 @@
-rmattr('type');
- $this->optGroups[''] = new OptGroup(null, $options);
- $this->val('');
- }
-
- /**
- * Add an `