Incorrect variable name used for parameter.
[moodle-linuxchix.git] / mod / wiki / ewiki / ewiki.php
blob0119e948b7f470fccf8d59b0b02cad6a57fad859
1 <script language="PHP"> @define("EWIKI_VERSION", "R1.01d");
3 /*
5 ErfurtWiki - an embedable, fast and user-friendly wiki engine
6 ¯¯¯¯¯¯¯¯¯¯
7 This is Public Domain (no license, no warranty); but feel free
8 to redistribute it under GPL or anything else you like.
10 http://erfurtwiki.sourceforge.net/
11 Mario Salzer <mario*erphesfurt·de> and many others(tm)
14 Use it from inside yoursite.php like that:
15 <html><body>...
16 <?php
17 include("ewiki.php");
18 echo ewiki_page();
23 #-- you could also establish a mysql connection in here, of course:
24 // mysql_connect(":/var/run/mysqld/mysqld.sock", "user", "pw")
25 // and mysql_query("USE mydatabase");
28 #-------------------------------------------------------- config ---
30 #-- I'm sorry for that, but all the @ annoy me
31 error_reporting(0x0000377 & error_reporting());
32 # error_reporting(E_ALL^E_NOTICE);
34 #-- the position of your ewiki-wrapper script
35 define("EWIKI_SCRIPT", "?id="); # relative/absolute to docroot
36 # define("EWIKI_SCRIPT_URL", "http://...?id="); # absolute URL
38 #-- change to your needs (site lang)
39 define("EWIKI_NAME", "ErfurtWiki");
40 define("EWIKI_PAGE_INDEX", "ErfurtWiki");
41 define("EWIKI_PAGE_NEWEST", "NewestPages");
42 define("EWIKI_PAGE_SEARCH", "SearchPages");
43 define("EWIKI_PAGE_HITS", "MostVisitedPages");
44 define("EWIKI_PAGE_VERSIONS", "MostOftenChangedPages");
45 define("EWIKI_PAGE_UPDATES", "UpdatedPages");
47 #-- default settings are good settings - most often ;)
48 #- look & feel
49 define("EWIKI_PRINT_TITLE", 1); # <h2>WikiPageName</h2> on top
50 define("EWIKI_SPLIT_TITLE", 0); # <h2>Wiki Page Name</h2>
51 define("EWIKI_CONTROL_LINE", 1); # EditThisPage-link at bottom
52 define("EWIKI_LIST_LIMIT", 20); # listing limit
53 #- behaviour
54 define("EWIKI_AUTO_EDIT", 1); # edit box for non-existent pages
55 define("EWIKI_EDIT_REDIRECT", 1); # redirect after edit save
56 define("EWIKI_DEFAULT_ACTION", "view"); # (keep!)
57 define("EWIKI_CASE_INSENSITIVE", 1); # wikilink case sensitivity
58 define("EWIKI_HIT_COUNTING", 1);
59 define("UNIX_MILLENNIUM", 1000000000);
60 #- rendering
61 define("EWIKI_ALLOW_HTML", 0); # often a very bad idea
62 define("EWIKI_HTML_CHARS", 1); # allows for &#200;
63 define("EWIKI_ESCAPE_AT", 1); # "@" -> "&#x40;"
64 #- http/urls
65 define("EWIKI_HTTP_HEADERS", 1); # most often a good thing
66 define("EWIKI_NO_CACHE", 1); # browser+proxy shall not cache
67 define("EWIKI_URLENCODE", 1); # disable when _USE_PATH_INFO
68 define("EWIKI_URLDECODE", 1);
69 define("EWIKI_USE_PATH_INFO", 1 &&!strstr($_SERVER["SERVER_SOFTWARE"],"Apache"));
70 define("EWIKI_USE_ACTION_PARAM", 1);
71 define("EWIKI_ACTION_SEP_CHAR", "/");
72 define("EWIKI_UP_PAGENUM", "n"); # _UP_ means "url parameter"
73 define("EWIKI_UP_PAGEEND", "e");
74 define("EWIKI_UP_BINARY", "binary");
75 define("EWIKI_UP_UPLOAD", "upload");
76 #- other stuff
77 define("EWIKI_DEFAULT_LANG", "en");
78 define("EWIKI_CHARSET", "ISO-8859-1");
79 #- user permissions
80 define("EWIKI_PROTECTED_MODE", 0); # disable funcs + require auth
81 define("EWIKI_PROTECTED_MODE_HIDING", 0); # hides disallowed actions
82 define("EWIKI_AUTH_DEFAULT_RING", 3); # 0=root 1=priv 2=user 3=view
83 define("EWIKI_AUTO_LOGIN", 1); # [auth_query] on startup
85 #-- allowed WikiPageNameCharacters
87 #### BEGIN MOODLE CHANGES - to remove auto-camelcase linking.
88 global $moodle_disable_camel_case;
89 if ($moodle_disable_camel_case) {
90 define("EWIKI_CHARS_L", "");
91 define("EWIKI_CHARS_U", "");
93 else {
94 #### END MOODLE CHANGES
96 define("EWIKI_CHARS_L", "a-z_µ¤$\337-\377");
97 define("EWIKI_CHARS_U", "A-Z0-9\300-\336");
99 #### BEGIN MOODLE CHANGES
101 #### END MOODLE CHANGES
103 define("EWIKI_CHARS", EWIKI_CHARS_L.EWIKI_CHARS_U);
105 #-- database
106 define("EWIKI_DB_TABLE_NAME", "ewiki"); # MySQL / ADOdb
107 define("EWIKI_DBFILES_DIRECTORY", "/tmp"); # see "db_flat_files.php"
108 define("EWIKI_DBA", "/tmp/ewiki.dba"); # see "db_dba.php"
109 define("EWIKI_DBQUERY_BUFFER", 512*1024); # 512K
110 define("EWIKI_INIT_PAGES", "./init-pages"); # for initialization
112 define("EWIKI_DB_F_TEXT", 1<<0);
113 define("EWIKI_DB_F_BINARY", 1<<1);
114 define("EWIKI_DB_F_DISABLED", 1<<2);
115 define("EWIKI_DB_F_HTML", 1<<3);
116 define("EWIKI_DB_F_READONLY", 1<<4);
117 define("EWIKI_DB_F_WRITEABLE", 1<<5);
118 define("EWIKI_DB_F_APPENDONLY", 1<<6); #nyi
119 define("EWIKI_DB_F_SYSTEM", 1<<7);
120 define("EWIKI_DB_F_PART", 1<<8);
121 define("EWIKI_DB_F_TYPE", EWIKI_DB_F_TEXT | EWIKI_DB_F_BINARY | EWIKI_DB_F_DISABLED | EWIKI_DB_F_SYSTEM | EWIKI_DB_F_PART);
122 define("EWIKI_DB_F_ACCESS", EWIKI_DB_F_READONLY | EWIKI_DB_F_WRITEABLE | EWIKI_DB_F_APPENDONLY);
123 define("EWIKI_DB_F_COPYMASK", EWIKI_DB_F_TYPE | EWIKI_DB_F_ACCESS);
125 define("EWIKI_DBFILES_NLR", '\\n');
126 define("EWIKI_DBFILES_ENCODE", 0 || (DIRECTORY_SEPARATOR != "/"));
127 define("EWIKI_DBFILES_GZLEVEL", "2");
129 #-- internal
130 define("EWIKI_ADDPARAMDELIM", (strstr(EWIKI_SCRIPT,"?") ? "&" : "?"));
132 #-- binary content (images)
133 define("EWIKI_SCRIPT_BINARY", /*"/binary.php?binary="*/ ltrim(strtok(" ".EWIKI_SCRIPT,"?"))."?".EWIKI_UP_BINARY."=" );
134 define("EWIKI_CACHE_IMAGES", 1 &&!headers_sent());
135 define("EWIKI_IMAGE_MAXSIZE", 64 *1024);
136 define("EWIKI_IMAGE_MAXWIDTH", 3072);
137 define("EWIKI_IMAGE_MAXHEIGHT", 2048);
138 define("EWIKI_IMAGE_MAXALLOC", 1<<19);
139 define("EWIKI_IMAGE_RESIZE", 1);
140 define("EWIKI_IMAGE_ACCEPT", "image/jpeg,image/png,image/gif,application/x-shockwave-flash");
141 define("EWIKI_IDF_INTERNAL", "internal://");
142 define("EWIKI_ACCEPT_BINARY", 0); # for arbitrary binary data files
144 #-- misc
145 define("EWIKI_TMP", $_SERVER["TEMP"] ? $_SERVER["TEMP"] : "/tmp");
146 define("EWIKI_LOGLEVEL", -1); # 0=error 1=warn 2=info 3=debug
147 define("EWIKI_LOGFILE", "/tmp/ewiki.log");
149 #-- plugins (tasks mapped to function names)
150 $ewiki_plugins["database"][] = "ewiki_database_mysql";
151 $ewiki_plugins["edit_preview"][] = "ewiki_page_edit_preview";
152 $ewiki_plugins["render"][] = "ewiki_format";
153 $ewiki_plugins["init"][-5] = "ewiki_localization";
154 $ewiki_plugins["init"][-1] = "ewiki_binary";
155 $ewiki_plugins["handler"][-105] = "ewiki_eventually_initialize";
156 $ewiki_plugins["handler"][] = "ewiki_intermap_walking";
157 $ewiki_plugins["view_append"][-1] = "ewiki_control_links";
158 $ewiki_plugins["view_final"][-1] = "ewiki_add_title";
159 $ewiki_plugins["page_final"][] = "ewiki_http_headers";
160 $ewiki_plugins["page_final"][99115115] = "ewiki_page_css_container";
161 $ewiki_plugins["edit_form_final"][] = "ewiki_page_edit_form_final_imgupload";
162 $ewiki_plugins["format_block"]["pre"][] = "ewiki_format_pre";
163 $ewiki_plugins["format_block"]["code"][] = "ewiki_format_pre";
164 $ewiki_plugins["format_block"]["htm"][] = "ewiki_format_html";
165 $ewiki_plugins["format_block"]["html"][] = "ewiki_format_html";
166 $ewiki_plugins["format_block"]["comment"][] = "ewiki_format_comment";
169 #-- internal pages
170 $ewiki_plugins["page"][EWIKI_PAGE_NEWEST] = "ewiki_page_newest";
171 $ewiki_plugins["page"][EWIKI_PAGE_SEARCH] = "ewiki_page_search";
172 if (EWIKI_HIT_COUNTING) $ewiki_plugins["page"][EWIKI_PAGE_HITS] = "ewiki_page_hits";
173 $ewiki_plugins["page"][EWIKI_PAGE_VERSIONS] = "ewiki_page_versions";
174 $ewiki_plugins["page"][EWIKI_PAGE_UPDATES] = "ewiki_page_updates";
176 #-- page actions
177 $ewiki_plugins["action"]["edit"] = "ewiki_page_edit";
178 $ewiki_plugins["action_always"]["links"] = "ewiki_page_links";
179 $ewiki_plugins["action"]["info"] = "ewiki_page_info";
180 $ewiki_plugins["action"]["view"] = "ewiki_page_view";
182 #-- helper vars ---------------------------------------------------
183 $ewiki_config["idf"]["url"] = array("http://", "mailto:", "internal://", "ftp://", "https://", "irc://", "telnet://", "news://", "chrome://", "file://", "gopher://", "httpz://");
184 $ewiki_config["idf"]["img"] = array(".jpeg", ".png", ".jpg", ".gif", ".j2k");
185 $ewiki_config["idf"]["obj"] = array(".swf", ".svg");
187 #-- entitle actions
188 $ewiki_config["action_links"]["view"] = @array_merge(array(
189 "edit" => "EDITTHISPAGE", # ewiki_t() is called on these
190 "links" => "BACKLINKS",
191 "info" => "PAGEHISTORY",
192 "like" => "LIKEPAGES",
193 ), @$ewiki_config["action_links"]["view"]
195 $ewiki_config["action_links"]["info"] = @array_merge(array(
196 "view" => "browse",
197 "edit" => "fetchback",
198 ), @$ewiki_config["action_links"]["info"]
201 #-- variable configuration settings (go into '$ewiki_config')
202 $ewiki_config_DEFAULTSTMP = array(
203 "edit_thank_you" => 1,
204 "edit_box_size" => "70x15",
205 "print_title" => EWIKI_PRINT_TITLE,
206 "split_title" => EWIKI_SPLIT_TITLE,
207 "control_line" => EWIKI_CONTROL_LINE,
208 "list_limit" => EWIKI_LIST_LIMIT,
209 "script" => EWIKI_SCRIPT,
210 "script_url" => (defined("EWIKI_SCRIPT_URL")?EWIKI_SCRIPT_URL:NULL),
211 "script_binary" => EWIKI_SCRIPT_BINARY,
212 #-- heart of the wiki -- don't try to read this! ;)
214 "wiki_pre_scan_regex" => '/
215 (?<![~!])
216 ((?:(?:\w+:)*['.EWIKI_CHARS_U.']+['.EWIKI_CHARS_L.']+){2,}[\w\d]*)
217 |\^([-'.EWIKI_CHARS_L.EWIKI_CHARS_U.']{3,})
218 |\[ (?:"[^\]\"]+" | \s+ | [^:\]#]+\|)* ([^\|\"\[\]\#]+) (?:\s+ | "[^\]\"]+")* [\]\#]
219 |(\w{3,9}:\/\/[^?#\s\[\]\'\"\)\,<]+) /x',
221 "wiki_link_regex" => "\007 [!~]?(
222 \#?\[[^<>\[\]\n]+\] |
223 \^[-".EWIKI_CHARS_U.EWIKI_CHARS_L."]{3,} |
224 \b([\w]{3,}:)*([".EWIKI_CHARS_U."]+[".EWIKI_CHARS_L."]+){2,}\#?[\w\d]* |
225 ([a-z]{2,9}://|mailto:)[^\s\[\]\'\"\)\,<]+ |
226 \w[-_.+\w]+@(\w[-_\w]+[.])+\w{2,} ) \007x",
228 #-- rendering ruleset
229 "wm_indent" => '<div style="margin-left:15px;" class="indent">',
230 "wm_table_defaults" => 'cellpadding="2" border="1" cellspacing="0"',
231 "wm_whole_line" => array(),
232 "htmlentities" => array(
233 "&" => "&amp;",
234 ">" => "&gt;",
235 "<" => "&lt;",
237 "wm_source" => array(
238 "%%%" => "<br />",
239 "\t" => " ",
240 "\n;:" => "\n ", # workaround, replaces the old ;:
242 "wm_list" => array(
243 "-" => array('ul type="square"', "", "li"),
244 "*" => array('ul type="circle"', "", "li"),
245 "#" => array("ol", "", "li"),
246 ":" => array("dl", "dt", "dd"),
247 #<out># ";" => array("dl", "dt", "dd"),
249 "wm_style" => array(
250 "'''''" => array("<b><i>", "</i></b>"),
251 "'''" => array("<b>", "</b>"),
252 "___" => array("<i><b>", "</b></i>"),
253 "''" => array("<em>", "</em>"),
254 "__" => array("<strong>", "</strong>"),
255 "^^" => array("<sup>", "</sup>"),
256 "==" => array("<tt>", "</tt>"),
257 #<off># "***" => array("<b><i>", "</i></b>"),
258 #<off># "###" => array("<big><b>", "</b></big>"),
259 "**" => array("<b>", "</b>"),
260 "##" => array("<big>", "</big>"),
261 "µµ" => array("<small>", "</small>"),
263 "wm_start_end" => array(
265 #-- rendering plugins
266 "format_block" => array(
267 "html" => array("&lt;html&gt;", "&lt;/html&gt;", "html", 0x0000),
268 "htm" => array("&lt;htm&gt;", "&lt;/htm&gt;", "html", 0x0003),
269 "code" => array("&lt;code&gt;", "&lt;/code&gt;", false, 0x0000),
270 "pre" => array("&lt;pre&gt;", "&lt;/pre&gt;", false, 0x003F),
271 "comment" => array("\n&lt;!--", "--&gt;", false, 0x0030),
272 # "verbatim" => array("&lt;verbatim&gt;", "&lt;/verbatim&gt;", false, 0x0000),
274 "format_params" => array(
275 "scan_links" => 1,
276 "html" => EWIKI_ALLOW_HTML,
277 "mpi" => 1,
280 foreach ($ewiki_config_DEFAULTSTMP as $set => $val) {
281 if (!isset($ewiki_config[$set])) {
282 $ewiki_config[$set] = $val;
284 elseif (is_array($val)) foreach ($val as $vali=>$valv) {
285 if (is_int($vali)) {
286 $ewiki_config[$set][] = $valv;
288 elseif (!isset($ewiki_config[$set][$vali])) {
289 $ewiki_config[$set][$vali] = $valv;
293 $ewiki_config_DEFAULTSTMP = $valv = $vali = $val = NULL;
295 #-- init stuff, autostarted parts
296 ksort($ewiki_plugins["init"]);
297 if ($pf_a = $ewiki_plugins["init"]) foreach ($pf_a as $pf) {
298 // Binary Handling starts here
299 #### MOODLE CHANGE TO BE COMPATIBLE WITH PHP 4.1
300 #if(headers_sent($file,$line)) {
301 # error("Headers already sent: $file:$line");
302 if(headers_sent()) {
303 error("Headers already sent.");
305 $pf($GLOBALS);
307 unset($ewiki_plugins["init"]);
309 #-- text (never remove the "C" or "en" sections!)
311 $ewiki_t["C"] = @array_merge(@$ewiki_t["C"], array(
312 "DATE" => "%a, %d %b %G %T %Z",
313 "EDIT_TEXTAREA_RESIZE_JS" => '<a href="javascript:ewiki_enlarge()" style="text-decoration:none">+</a><script type="text/javascript"><!--'."\n".'function ewiki_enlarge() {var ta=document.getElementById("ewiki_content");ta.style.width=((ta.cols*=1.1)*10).toString()+"px";ta.style.height=((ta.rows*=1.1)*30).toString()+"px";}'."\n".'//--></script>',
316 $ewiki_t["en"] = @array_merge(@$ewiki_t["en"], array(
317 "EDITTHISPAGE" => "EditThisPage",
318 "APPENDTOPAGE" => "Add to",
319 "BACKLINKS" => "BackLinks",
320 "PAGESLINKINGTO" => "Pages linking to \$title",
321 "PAGEHISTORY" => "PageInfo",
322 "INFOABOUTPAGE" => "Information about page",
323 "LIKEPAGES" => "Pages like this",
324 "NEWESTPAGES" => "Newest Pages",
325 "LASTCHANGED" => "last changed on %c",
326 "DOESNOTEXIST" => "This page does not yet exist, please click on EditThisPage if you'd like to create it.",
327 "DISABLEDPAGE" => "This page is currently not available.",
328 "ERRVERSIONSAVE" => "Sorry, while you edited this page someone else
329 did already save a changed version. Please go back to the
330 previous screen and copy your changes to your computers
331 clipboard to insert it again after you reload the edit
332 screen.",
333 "ERRORSAVING" => "An error occoured while saving your changes. Please try again.",
334 "THANKSFORCONTRIBUTION" => "Thank you for your contribution!",
335 "CANNOTCHANGEPAGE" => "This page cannot be changed.",
336 "OLDVERCOMEBACK" => "Make this old version come back to replace the current one",
337 "PREVIEW" => "Preview",
338 "SAVE" => "Save",
339 "CANCEL_EDIT" => "CancelEditing",
340 "UPLOAD_PICTURE_BUTTON" => "upload picture &gt;&gt;&gt;",
341 "EDIT_FORM_1" => "<a href=\"".EWIKI_SCRIPT."GoodStyle\">GoodStyle</a> is to
342 write what comes to your mind. Don't care about how it
343 looks too much now. You can add <a href=\"".EWIKI_SCRIPT."WikiMarkup\">WikiMarkup</a>
344 also later if you think it is necessary.<br />",
345 "EDIT_FORM_2" => "<br />Please do not write things, which may make other
346 people angry. And please keep in mind that you are not all that
347 anonymous in the internet (find out more about your computers
348 '<a href=\"http://google.com/search?q=my+computers+IP+address\">IP address</a>' at Google).",
349 "BIN_IMGTOOLARGE" => "Image file is too large!",
350 "BIN_NOIMG" => "This is no image file (inacceptable file format)!",
351 "FORBIDDEN" => "You are not authorized to access this page.",
354 $ewiki_t["es"] = @array_merge(@$ewiki_t["es"], array(
355 "EDITTHISPAGE" => "EditarEstaPágina",
356 "BACKLINKS" => "EnlacesInversos",
357 "PAGESLINKINGTO" => "Páginas enlazando \$title",
358 "PAGEHISTORY" => "InfoPágina",
359 "INFOABOUTPAGE" => "Información sobre la página",
360 "LIKEPAGES" => "Páginas como esta",
361 "NEWESTPAGES" => "Páginas más nuevas",
362 "LASTCHANGED" => "última modificación %d/%m/%Y a las %H:%M",
363 "DOESNOTEXIST" => "Esta página aún no existe, por favor eliga EditarEstaPágina si desea crearla.",
364 "DISABLEDPAGE" => "Esta página no está disponible en este momento.",
365 "ERRVERSIONSAVE" => "Disculpe, mientras editaba esta página alguién más
366 salvó una versión modificada. Por favor regrese a
367 a la pantalla anterior y copie sus cambios a su computador
368 para insertalos nuevamente después de que cargue
369 la pantalla de edición.",
370 "ERRORSAVING" => "Ocurrió un error mientras se salvavan sus cambios. Por favor intente de nuevo.",
371 "THANKSFORCONTRIBUTION" => "Gracias por su contribución!",
372 "CANNOTCHANGEPAGE" => "Esta página no puede ser modificada.",
373 "OLDVERCOMEBACK" => "Hacer que esta versión antigua regrese a remplazar la actual",
374 "PREVIEW" => "Previsualizar",
375 "SAVE" => "Salvar",
376 "CANCEL_EDIT" => "CancelarEdición",
377 "UPLOAD_PICTURE_BUTTON" => "subir gráfica &gt;&gt;&gt;",
378 "EDIT_FORM_1" => "<a href=\"".EWIKI_SCRIPT."BuenEstilo\">BuenEstilo</a> es
379 escribir lo que viene a su mente. No se preocupe mucho
380 por la apariencia. También puede agregar <a href=\"".EWIKI_SCRIPT."ReglasDeMarcadoWiki\">ReglasDeMarcadoWiki</a>
381 más adelante si piensa que es necesario.<br />",
382 "EDIT_FORM_2" => "<br />Por favor no escriba cosas, que puedan
383 enfadar a otras personas. Y por favor tenga en mente que
384 usted no es del todo anónimo en Internet
385 (encuentre más sobre
386 '<a href=\"http://google.com/search?q=my+computers+IP+address\">IP address</a>' de su computador con Google).",
387 "BIN_IMGTOOLARGE" => "¡La gráfica es demasiado grande!",
388 "BIN_NOIMG" => "¡No es un archivo con una gráfica (formato de archivo inaceptable)!",
389 "FORBIDDEN" => "No está autorizado para acceder a esta página.",
392 $ewiki_t["de"] = @array_merge(@$ewiki_t["de"], array(
393 "EDITTHISPAGE" => "DieseSeiteÄndern",
394 "APPENDTOPAGE" => "Ergänze",
395 "BACKLINKS" => "ZurückLinks",
396 "PAGESLINKINGTO" => "Verweise zur Seite \$title",
397 "PAGEHISTORY" => "SeitenInfo",
398 "INFOABOUTPAGE" => "Informationen über Seite",
399 "LIKEPAGES" => "Ähnliche Seiten",
400 "NEWESTPAGES" => "Neueste Seiten",
401 "LASTCHANGED" => "zuletzt geändert am %d.%m.%Y um %H:%M",
402 "DISABLEDPAGE" => "Diese Seite kann momentan nicht angezeigt werden.",
403 "ERRVERSIONSAVE" => "Entschuldige, aber während Du an der Seite
404 gearbeitet hast, hat bereits jemand anders eine geänderte
405 Fassung gespeichert. Damit nichts verloren geht, browse bitte
406 zurück und speichere Deine Änderungen in der Zwischenablage
407 (Bearbeiten->Kopieren) um sie dann wieder an der richtigen
408 Stelle einzufügen, nachdem du die EditBoxSeite nocheinmal
409 geladen hast.<br />
410 Vielen Dank für Deine Mühe.",
411 "ERRORSAVING" => "Beim Abspeichern ist ein Fehler aufgetreten. Bitte versuche es erneut.",
412 "THANKSFORCONTRIBUTION" => "Vielen Dank für Deinen Beitrag!",
413 "CANNOTCHANGEPAGE" => "Diese Seite kann nicht geändert werden.",
414 "OLDVERCOMEBACK" => "Diese alte Version der Seite wieder zur Aktuellen machen",
415 "PREVIEW" => "Vorschau",
416 "SAVE" => "Speichern",
417 "CANCEL_EDIT" => "ÄnderungenVerwerfen",
418 "UPLOAD_PICTURE_BUTTON" => "Bild hochladen &gt;&gt;&gt;",
419 "EDIT_FORM_1" => "<a href=\"".EWIKI_SCRIPT."GuterStil\">GuterStil</a> ist es,
420 ganz einfach das zu schreiben, was einem gerade in den
421 Sinn kommt. Du solltest dich jetzt noch nicht so sehr
422 darum kümmern, wie die Seite aussieht. Du kannst später
423 immernoch zurückkommen und den Text mit <a href=\"".EWIKI_SCRIPT."FormatierungsRegeln\">WikiTextFormatierungsRegeln</a>
424 aufputschen.<br />",
425 "EDIT_FORM_2" => "<br />Bitte schreib keine Dinge, die andere Leute
426 verärgern könnten. Und bedenke auch, daß es schnell auf
427 dich zurückfallen kann wenn du verschiedene andere Dinge sagst (mehr Informationen zur
428 '<a href=\"http://google.de/search?q=computer+IP+adresse\">IP Adresse</a>'
429 deines Computers findest du bei Google).",
432 #-- InterWiki:Links
433 $ewiki_config["interwiki"] = @array_merge(
434 @$ewiki_config["interwiki"],
435 array(
436 "javascript" => "", # this actually protects from javascript: links
437 "url" => "",
438 # "self" => "this",
439 "this" => EWIKI_SCRIPT, # better was absolute _URL to ewiki wrapper
440 "jump" => "",
441 "ErfurtWiki" => "http://erfurtwiki.sourceforge.net/?id=",
442 "InterWiki" => "InterWikiSearch",
443 "InterWikiSearch" => "http://sunir.org/apps/meta.pl?",
444 "Wiki" => "WardsWiki",
445 "WardsWiki" => "http://www.c2.com/cgi/wiki?",
446 "WikiFind" => "http://c2.com/cgi/wiki?FindPage&amp;value=",
447 "WikiPedia" => "http://www.wikipedia.com/wiki.cgi?",
448 "MeatBall" => "MeatballWiki",
449 "MeatballWiki" => "http://www.usemod.com/cgi-bin/mb.pl?",
450 "UseMod" => "http://www.usemod.com/cgi-bin/wiki.pl?",
451 "PhpWiki" => "http://phpwiki.sourceforge.net/phpwiki/index.php3?",
452 "LinuxWiki" => "http://linuxwiki.de/",
453 "OpenWiki" => "http://openwiki.com/?",
454 "Tavi" => "http://andstuff.org/tavi/",
455 "TWiki" => "http://twiki.sourceforge.net/cgi-bin/view/",
456 "MoinMoin" => "http://www.purl.net/wiki/moin/",
457 "Google" => "http://google.com/search?q=",
458 "ISBN" => "http://www.amazon.com/exec/obidos/ISBN=",
459 "icq" => "http://www.icq.com/",
466 #-------------------------------------------------------------------- main ---
468 /* this is the main function, which you should preferrably call to
469 integrate the ewiki into your web site; it chains to most other
470 parts and plugins (including the edit box);
471 if you do not supply the requested pages "$id" we will fetch it
472 from the pre-defined possible URL parameters.
474 function ewiki_page($id=false) {
476 global $ewiki_links, $ewiki_plugins, $ewiki_ring, $ewiki_t, $ewiki_errmsg;
477 #-- output var
478 $o = "";
480 #-- selected page
481 if (!isset($_REQUEST)) {
482 $_REQUEST = @array_merge($_GET, $_POST);
484 if (!strlen($id)) {
485 $id = ewiki_id();
487 $id = format_string($id,true);
488 #-- page action
489 $action = EWIKI_DEFAULT_ACTION;
490 if ($delim = strpos($id, EWIKI_ACTION_SEP_CHAR)) {
491 $action = substr($id, 0, $delim);
492 $id = substr($id, $delim + 1);
494 elseif (EWIKI_USE_ACTION_PARAM && isset($_REQUEST["action"])) {
495 $action = $_REQUEST["action"];
497 $GLOBALS["ewiki_id"] = $id;
498 $GLOBALS["ewiki_title"] = ewiki_split_title($id);
499 $GLOBALS["ewiki_action"] = $action;
501 #-- fetch from db
502 $dquery = array(
503 "id" => $id
505 if (!isset($_REQUEST["content"]) && ($dquery["version"] = @$_REQUEST["version"])) {
506 $dquery["forced_version"] = $dquery["version"];
508 $data = @array_merge($dquery, ewiki_database("GET", $dquery));
510 #-- stop here if page is not marked as _TEXT,
511 # perform authentication then, and let only administrators proceed
512 if (!empty($data["flags"]) && (($data["flags"] & EWIKI_DB_F_TYPE) != EWIKI_DB_F_TEXT)) {
513 if (($data["flags"] & EWIKI_DB_F_BINARY) && ($pf = $ewiki_plugins["handler_binary"][0])) {
514 return($pf($id, $data, $action)); //_BINARY entries handled separately
516 elseif (!EWIKI_PROTECTED_MODE || !ewiki_auth($id, $data, $action, 0, 1) && ($ewiki_ring!=0)) {
517 return(ewiki_t("DISABLEDPAGE"));
521 #-- pre-check if actions exist
522 $pf_page = ewiki_array($ewiki_plugins["page"], $id);
524 #-- edit <form> for non-existent pages
525 if (($action==EWIKI_DEFAULT_ACTION) && empty($data["content"]) && empty($pf_page)) {
526 if (EWIKI_AUTO_EDIT) {
527 $action = "edit";
529 else {
530 $data["content"] = ewiki_t("DOESNOTEXIST");
533 #-- more initialization
534 if ($pf_a = @$ewiki_plugins["page_init"]) {
535 ksort($pf_a);
536 foreach ($pf_a as $pf) {
537 $o .= $pf($id, $data, $action);
539 unset($ewiki_plugins["page_init"]);
541 $pf_page = ewiki_array($ewiki_plugins["page"], $id);
543 #-- require auth
544 if (EWIKI_PROTECTED_MODE) {
545 if (!ewiki_auth($id, $data, $action, $ring=false, $force=EWIKI_AUTO_LOGIN)) {
546 return($o.=$ewiki_errmsg);
550 #-- handlers
551 $handler_o = "";
552 if ($pf_a = @$ewiki_plugins["handler"]) {
553 ksort($pf_a);
554 foreach ($pf_a as $pf) {
555 if ($handler_o = $pf($id, $data, $action)) { break; }
558 #-- finished by handler
559 if ($handler_o) {
560 $o .= $handler_o;
562 #-- actions that also work for static and internal pages
563 elseif (($pf = @$ewiki_plugins["action_always"][$action]) && function_exists($pf)) {
564 $o .= $pf($id, $data, $action);
566 #-- internal pages
567 elseif ($pf_page && function_exists($pf_page)) {
568 $o .= $pf_page($id, $data, $action);
570 #-- page actions
571 else {
572 $pf = @$ewiki_plugins["action"][$action];
574 #-- fallback to "view" action
575 if (empty($pf) || !function_exists($pf)) {
577 $pf = "ewiki_page_view";
578 $action = "view"; // we could also allow different (this is a
579 // catch-all) view variants, but this would lead to some problems
582 $o .= $pf($id, $data, $action);
585 #-- error instead of page?
586 if (empty($o) && $ewiki_errmsg) {
587 $o = $ewiki_errmsg;
590 #-- html post processing
591 if ($pf_a = $ewiki_plugins["page_final"]) {
592 ksort($pf_a);
593 foreach ($pf_a as $pf) {
594 $pf($o, $id, $data, $action);
598 (EWIKI_ESCAPE_AT) && ($o = str_replace("@", "&#x40;", $o));
600 return($o);
605 #-- HTTP meta headers
606 function ewiki_http_headers(&$o, $id, &$data, $action) {
607 global $ewiki_t;
608 if (EWIKI_HTTP_HEADERS && !headers_sent()) {
609 if (!empty($data)) {
610 if ($uu = @$data["id"]) @header('Content-Disposition: inline; filename="' . urlencode($uu) . '.html"');
611 if ($uu = @$data["version"]) @header('Content-Version: ' . $uu);
612 if ($uu = @$data["lastmodified"]) @header('Last-Modified: ' . gmstrftime($ewiki_t["C"]["DATE"], $uu));
614 if (EWIKI_NO_CACHE) {
615 header('Expires: ' . gmstrftime($ewiki_t["C"]["DATE"], UNIX_MILLENNIUM));
616 header('Pragma: no-cache');
617 header('Cache-Control: no-cache, private, must-revalidate');
618 # change to "C-C: cache, must-revalidate" ??
619 # private only for authenticated users / _PROT_MODE
621 #-- ETag
622 if ($data["version"] && ($etag=ewiki_etag($data)) || ($etag=md5($o))) {
623 $weak = "W/" . urlencode($id) . "." . $data["version"];
624 header("ETag: \"$etag\""); ###, \"$weak\"");
628 function ewiki_etag(&$data) {
629 return( urlencode($data["id"]) . ":" . dechex($data["version"]) . ":ewiki:" .
630 dechex(crc32($data["content"]) & 0x7FFFBFFF) );
635 #-- encloses whole page output with a descriptive <div>
636 function ewiki_page_css_container(&$o, &$id, &$data, &$action) {
637 $o = "<div class=\"wiki $action "
638 . strtr($id, ' ./ --_!"§$%&()=?²³{[]}`+#*;:,<>| @µöäüÖÄÜߤ^°«»\'\\',
639 '- -----------------------------------------------')
640 . "\">\n"
641 . $o . "\n</div>\n";
646 function ewiki_split_title ($id='', $split=EWIKI_SPLIT_TITLE, $entities=1) {
647 strlen($id) or ($id = $GLOBALS["ewiki_id"]);
648 if ($split) {
649 $id = preg_replace("/([".EWIKI_CHARS_L."])([".EWIKI_CHARS_U."]+)/", "$1 $2", $id);
651 return($entities ? htmlentities($id) : $id);
656 function ewiki_add_title(&$html, $id, &$data, $action, $go_action="links") {
657 $html = ewiki_make_title($id, '', 1, $action, $go_action) . $html;
661 function ewiki_make_title($id='', $title='', $class=3, $action="view", $go_action="links", $may_split=1) {
663 global $ewiki_config, $ewiki_plugins, $ewiki_title, $ewiki_id;
665 #-- advanced handler
666 if ($pf = @$ewiki_plugins["make_title"][0]) {
667 return($pf($title, $class, $action, $go_action, $may_split));
669 #-- disabled
670 elseif (!$ewiki_config["print_title"]) {
671 return("");
674 #-- get id
675 if (empty($id)) {
676 $id = $ewiki_id;
679 #-- get title
680 if (!strlen($title)) {
681 $title = $ewiki_title; // already in &html; format
683 elseif ($ewiki_config["split_title"] && $may_split) {
684 $title = ewiki_split_title($title, $ewiki_config["split_title"], 0&($title!=$ewiki_title));
686 else {
687 $title = htmlentities($title);
690 #-- title mangling
691 if ($pf_a = @$ewiki_plugins["title_transform"]) {
692 foreach ($pf_a as $pf) { $pf($id, $title, $go_action); }
695 #-- clickable link or simple headline
696 if ($class <= $ewiki_config["print_title"]) {
697 if ($uu = @$ewiki_config["link_title_action"][$action]) {
698 $go_action = $uu;
700 if ($uu = @$ewiki_config["link_title_url"]) {
701 $href = $uu;
702 unset($ewiki_config["link_title_url"]);
704 else {
705 $href = ewiki_script($go_action, $id);
707 $o = '<a href="' . $href . '">' . ($title) . '</a>';
709 else {
710 $o = $title;
713 return('<h2 class="page title">' . $o . '</h2>'."\n");
719 function ewiki_page_view($id, &$data, $action, $all=1) {
721 global $ewiki_plugins, $ewiki_config;
722 $o = "";
724 #-- render requested wiki page <-- goal !!!
725 $render_args = array(
726 "scan_links" => 1,
727 "html" => (EWIKI_ALLOW_HTML||(@$data["flags"]&EWIKI_DB_F_HTML)),
729 $o .= $ewiki_plugins["render"][0] ($data["content"], $render_args);
730 if (!$all) {
731 return($o);
733 #### MOODLE CHANGE
734 /// Add Moodle filters to text porion of wiki.
735 global $moodle_format; // from wiki/view.php
736 $o = format_text($o, $moodle_format);
737 $o.= "<br /><br />";
739 #-- control line + other per-page info stuff
740 if ($pf_a = $ewiki_plugins["view_append"]) {
741 ksort($pf_a);
742 foreach ($pf_a as $n => $pf) { $o .= $pf($id, $data, $action); }
744 if ($pf_a = $ewiki_plugins["view_final"]) {
745 ksort($pf_a);
746 foreach ($pf_a as $n => $pf) { $pf($o, $id, $data, $action); }
749 if (!empty($_REQUEST["thankyou"]) && $ewiki_config["edit_thank_you"]) {
750 $o = ewiki_t("THANKSFORCONTRIBUTION") . $o;
754 if (EWIKI_HIT_COUNTING) {
755 ewiki_database("HIT", $data);
758 return($o);
764 #-------------------------------------------------------------------- util ---
767 /* retrieves "$id/$action" string from URL / QueryString / PathInfo,
768 change this in conjunction with ewiki_script() to customize your URLs
769 further whenever desired
771 function ewiki_id() {
772 ($id = @$_REQUEST["id"]) or
773 ($id = @$_REQUEST["name"]) or
774 ($id = @$_REQUEST["page"]) or
775 ($id = @$_REQUEST["file"]) or
776 (EWIKI_USE_PATH_INFO) and ($id = ltrim(@$_SERVER["PATH_INFO"], "/")) or
777 (!isset($_REQUEST["id"])) and ($id = trim(strtok($_SERVER["QUERY_STRING"], "&")));
778 if (!strlen($id) || ($id=="id=")) {
779 $id = EWIKI_PAGE_INDEX;
781 (EWIKI_URLDECODE) && ($id = urldecode($id));
782 return($id);
788 /* replaces EWIKI_SCRIPT, works more sophisticated, and
789 bypasses various design flaws
790 - if only the first parameter is used (old style), it can contain
791 a complete "action/WikiPage" - but this is ambigutious
792 - else $asid is the action, and $id contains the WikiPageName
793 - $ewiki_config["script"] will now be used in favour of the constant
794 - needs more work on _BINARY, should be a separate function
796 ## MOODLE-CHANGE: $asid="", Knows the devil why....
797 function ewiki_script($asid="", $id=false, $params="", $bin=0, $html=1, $script=NULL) {
798 global $ewiki_config, $ewiki_plugins;
800 #-- get base script url from config vars
801 if (empty($script)) {
802 $script = &$ewiki_config[!$bin?"script":"script_binary"];
806 #-- separate $action and $id for old style requests
807 if ($id === false) {
808 if (strpos($asid, EWIKI_ACTION_SEP_CHAR) !== false) {
809 $asid = strtok($asid, EWIKI_ACTION_SEP_CHAR);
810 $id = strtok("\000");
812 else {
813 $id = $asid;
814 $asid = "";
818 #-- prepare params
819 if (is_array($params)) {
820 $uu = $params;
821 $params = "";
822 if ($uu) foreach ($uu as $k=>$v) {
823 $params .= (strlen($params)?"&":"") . rawurlencode($k) . "=" . rawurlencode($v);
826 #-- action= parameter
827 if (EWIKI_USE_ACTION_PARAM >= 2) {
828 $params = "action=$asid" . (strlen($params)?"&":"") . $params;
829 $asid = "";
832 #-- workaround slashes in $id
833 if (empty($asid) && (strpos($id, EWIKI_ACTION_SEP_CHAR) !== false) && !$bin) {
834 $asid = "view";
836 /*paranoia*/ $asid = trim($asid, EWIKI_ACTION_SEP_CHAR);
838 #-- make url
839 if (EWIKI_URLENCODE) {
840 $id = urlencode($id);
841 $asid = urlencode($asid);
843 else {
844 # only urlencode &, %, ? for example
846 $url = $script;
847 if ($asid) {
848 $id = $asid . EWIKI_ACTION_SEP_CHAR . $id; #= "action/PageName"
850 if (strpos($url, "%s") !== false) {
851 $url = str_replace("%s", $id, $url);
853 else {
854 $url .= $id;
857 #-- add url params
858 if (strlen($params)) {
859 $url .= (strpos($url,"?")!==false ? "&":"?") . $params;
862 #-- fin
863 if ($html) {
864 //Don't replace & if it's part of encoded character (bug 2209)
865 $url = preg_replace("/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,5};)/","&amp;", $url);
866 } else {
867 //This is going to be used in some header or meta redirect, so It cannot use &amp; (bug 2620)
868 $url = preg_replace('/&amp;/', '&', $url);
870 return($url);
874 /* this ewiki_script() wrapper is used to generate URLs to binary
875 content in the ewiki database
877 function ewiki_script_binary($asid, $id=false, $params=array(), $upload=0) {
879 $upload |= is_string($params) && strlen($params) || count($params);
881 #-- generate URL directly to the plainly saved data file,
882 # see also plugins/binary_store
884 if (defined("EWIKI_DB_STORE_URL") && !$upload) {
885 $url = EWIKI_DB_STORE_URL . rawurlencode($id);
888 #-- else get standard URL (thru ewiki.php) from ewiki_script()
889 else {
890 $url = ewiki_script($asid, $id, $params, "_BINARY=1");
893 return($url);
897 /* this function returns the absolute ewiki_script url, if EWIKI_SCRIPT_URL
898 is set, else it guesses the value
900 function ewiki_script_url() {
902 global $ewiki_action, $ewiki_id, $ewiki_config;
904 $scr_template = $ewiki_config["script"];
905 $scr_current = ewiki_script($ewiki_action, $ewiki_id);
906 $req_uri = $_SERVER["REQUEST_URI"];
908 if ($url = $ewiki_config["script_url"]) {
909 return($url);
911 elseif (strpos($req_uri, $scr_current) !== false) {
912 $url = str_replace($req_uri, $scr_current, $scr_template);
914 elseif (strpos($req_uri, "?") && (strpos($scr_template, "?") !== false)) {
915 $url = substr($req_uri, 0, strpos($req_uri, "?"))
916 . substr($scr_template, strpos($scr_template, "?"));
918 elseif (strpos($req_uri, $sn = $_SERVER["SCRIPT_NAME"])) {
919 $url = $sn . "?id=";
921 else {
922 return(NULL); #-- could not guess it
925 #$url = "http://" . $_SERVER["SERVER_NAME"] . $url;
926 return($url);
932 #------------------------------------------------------------ page plugins ---
936 function ewiki_page_links($id, &$data, $action) {
937 $o = ewiki_make_title($id, ewiki_t("PAGESLINKINGTO", array("title"=>$id)), 1, $action, "", "_MAY_SPLIT=1");
938 if ($pages = ewiki_get_backlinks($id)) {
939 $o .= ewiki_list_pages($pages);
940 } else {
941 $o .= ewiki_t("This page isn't linked from anywhere else.");
943 return($o);
946 function ewiki_get_backlinks($id) {
947 $result = ewiki_database("SEARCH", array("refs" => $id));
948 $pages = array();
949 while ($row = $result->get(0, 0x0020)) {
950 if ( strpos($row["refs"], "\n$id\n") !== false) {
951 $pages[] = $row["id"];
954 return($pages);
957 function ewiki_get_links($id) {
958 if ($data = ewiki_database("GET", array("id"=>$id))) {
959 $refs = explode("\n", trim($data["refs"]));
960 $r = array();
961 foreach (ewiki_database("FIND", $refs) as $id=>$exists) {
962 if ($exists) {
963 $r[] = $id;
966 return($r);
971 function ewiki_list_pages($pages=array(), $limit=EWIKI_LIST_LIMIT,
972 $value_as_title=0, $pf_list=false)
974 global $ewiki_plugins;
975 $o = "";
977 $is_num = !empty($pages[0]);
978 $lines = array();
979 $n = 0;
981 foreach ($pages as $id=>$add_text) {
983 $title = $id;
984 $params = "";
986 if (is_array($add_text)) {
987 list($id, $params, $title, $add_text) = $add_text;
989 elseif ($is_num) {
990 $id = $title = $add_text;
991 $add_text = "";
993 elseif ($value_as_title) {
994 $title = $add_text;
995 $add_text = "";
998 $lines[] = '<a href="' . ewiki_script("", $id, $params) . '">' . htmlentities($title) . '</a> ' . $add_text;
1000 if (($limit > 0) && ($n++ >= $limit)) {
1001 break;
1005 if ($pf_a = @$ewiki_plugins["list_transform"])
1006 foreach ($pf_a as $pf_transform) {
1007 $pf_transform($lines);
1010 if (($pf_list) || ($pf_list = @$ewiki_plugins["list_pages"][0])) {
1011 $o = $pf_list($lines);
1013 elseif($lines) {
1014 $o = "&middot; " . implode("<br />\n&middot; ", $lines) . "<br />\n";
1017 return($o);
1023 function ewiki_page_ordered_list($orderby="created", $asc=0, $print, $title) {
1025 $o = ewiki_make_title("", $title, 2, ".list", "links", 0);
1027 $sorted = array();
1028 $result = ewiki_database("GETALL", array($orderby));
1030 while ($row = $result->get()) {
1031 $row = ewiki_database("GET", array(
1032 "id" => $row["id"],
1033 ($asc >= 0 ? "version" : "uu") => 1 // version 1 is most accurate for {hits}
1035 #-- text page?
1036 if (EWIKI_DB_F_TEXT == ($row["flags"] & EWIKI_DB_F_TYPE)) {
1037 #-- viewing allowed?
1038 if (!EWIKI_PROTECTED_MODE || !EWIKI_PROTECTED_MODE_HIDING || ewiki_auth($row["id"], $row, "view")) {
1039 $sorted[$row["id"]] = $row[$orderby];
1044 if ($asc != 0) { arsort($sorted); }
1045 else { asort($sorted); }
1047 foreach ($sorted as $name => $value) {
1048 if (empty($value)) { $value = "0"; }
1049 ##### BEGIN MOODLE ADDITION #####
1050 #$sorted[$name] = strftime(str_replace('%n', $value, $print), $value);
1051 if($print=="LASTCHANGED") {
1052 $value=strftime("%c",$value);
1054 $sorted[$name] = get_string(strtolower($print),"wiki",$value);
1055 ##### BEGIN MOODLE ADDITION #####
1057 $o .= ewiki_list_pages($sorted);
1059 return($o);
1064 function ewiki_page_newest($id=0, $data=0) {
1065 return( ewiki_page_ordered_list("created", 1, "LASTCHANGED", ewiki_t("NEWESTPAGES")) );
1068 function ewiki_page_updates($id=0, $data=0) {
1069 return( ewiki_page_ordered_list("lastmodified", -1, "LASTCHANGED", EWIKI_PAGE_UPDATES) );
1072 function ewiki_page_hits($id=0, $data=0) {
1073 ##### BEGIN MOODLE ADDITION #####
1074 return( ewiki_page_ordered_list("hits", 1, "hits", EWIKI_PAGE_HITS) );
1077 function ewiki_page_versions($id=0, $data=0) {
1078 return( ewiki_page_ordered_list("version", -1, "changes", EWIKI_PAGE_VERSIONS) );
1079 ##### END MOODLE ADDITION #####
1088 function ewiki_page_search($id, &$data, $action) {
1090 $o = ewiki_make_title($id, $id, 2, $action);
1092 if (! ($q = @$_REQUEST["q"])) {
1094 $o .= '<form action="' . ewiki_script("", $id) . '" method="post">';
1095 $o .= '<input name="q" size="30" /><br /><br />';
1096 $o .= '<input type="submit" value="'.$id.'" />';
1097 $o .= '</form>';
1099 else {
1100 $found = array();
1102 $q = preg_replace('/\s*[^\w]+\s*/', ' ', $q);
1103 foreach (explode(" ", $q) as $search) {
1105 if (empty($search)) { continue; }
1107 $result = ewiki_database("SEARCH", array("content" => $search));
1109 while ($row = $result->get()) {
1111 #-- show this entry in page listings?
1112 if (EWIKI_PROTECTED_MODE && EWIKI_PROTECTED_MODE_HIDING && !ewiki_auth($row["id"], $row, "view")) {
1113 continue;
1116 $found[] = $row["id"];
1120 $o .= ewiki_list_pages($found);
1123 return($o);
1133 function ewiki_page_info($id, &$data, $action) {
1135 global $ewiki_plugins, $ewiki_config, $ewiki_links;
1136 global $CFG, $course; // MOODLE HACK
1138 $o = ewiki_make_title($id, ewiki_t("INFOABOUTPAGE")." '{$id}'", 2, $action,"", "_MAY_SPLIT=1");
1140 $flagnames = array(
1141 "TEXT", "BIN", "DISABLED", "HTML", "READONLY", "WRITEABLE",
1142 "APPENDONLY", "SYSTEM",
1144 $show = array(
1145 "version", "author", "userid", "created",
1146 "lastmodified", "refs",
1147 "flags", "meta", "content"
1150 #-- versions to show
1151 $v_start = $data["version"];
1152 if ( ($uu=@$_REQUEST[EWIKI_UP_PAGENUM]) && ($uu<=$v_start) ) {
1153 $v_start = $uu;
1155 $v_end = $v_start - $ewiki_config["list_limit"];
1156 if ( ($uu=@$_REQUEST[EWIKI_UP_PAGEEND]) && ($uu<=$v_start) ) {
1157 $v_end = $uu;
1159 $v_end = max($v_end, 1);
1161 #-- go
1162 # the very ($first) entry is rendered more verbosely than the others
1163 for ($v=$v_start,$first=1; ($v>=$v_end); $v--,$first=0) {
1165 $current = ewiki_database("GET", array("id"=>$id, "version"=>$v));
1167 if (!strlen(trim($current["id"])) || !$current["version"] || !strlen(trim($current["content"]))) {
1168 continue;
1171 $o .= '<table class="version-info" cellpadding="2" cellspacing="1">' . "\n";
1173 #-- additional info-actions
1174 $commands = '';
1175 foreach ($ewiki_config["action_links"]["info"] as $action=>$title)
1176 if (@$ewiki_plugins["action"][$action] || @$ewiki_plugins["action_always"][$action]) {
1177 ##### BEGIN MOODLE ADDITION #####
1178 if ($commands) {
1179 $commands .= '&nbsp;&nbsp;';
1181 $commands .= '<a href="' .
1182 ewiki_script($action, $id, array("version"=>$current["version"])) .
1183 '">' . get_string($title,"wiki") . '</a>';
1184 ##### END MOODLE ADDITION #####
1187 #-- print page database entry
1188 foreach($show as $i) {
1190 $value = @$current[$i];
1192 #-- show database {fields} differently
1193 if ($i == "meta") {
1194 continue; // MOODLE DOESN'T USE IT
1195 $str = "";
1196 if ($first && $value) { foreach ($value as $n=>$d) {
1197 $str .= htmlentities("$n: $d") . "<br />\n";
1199 $value = $str;
1201 elseif ($value >= UNIX_MILLENNIUM) { #-- {lastmodified}, {created}
1202 #### BEGIN MOODLE CHANGE
1203 $value=userdate($value);
1204 #$value = strftime("%c", $value);
1205 #### END MOODLE CHANGE
1207 elseif ($i == "content") {
1208 continue; // MOODLE DOESN'T CARE
1209 $value = strlen(trim($value)) . " bytes";
1210 $i = "content size";
1212 elseif ($first && ($i == "refs") && !(EWIKI_PROTECTED_MODE && (EWIKI_PROTECTED_MODE_HIDING>=2))) {
1213 $a = explode("\n", trim($value));
1214 $ewiki_links = ewiki_database("FIND", $a);
1215 ewiki_merge_links($ewiki_links);
1216 foreach ($a as $n=>$link) {
1217 $a[$n] = ewiki_link_regex_callback(array("$link"), "force_noimg");
1219 $value = trim(implode(", ", $a));
1220 if (!$value) {
1221 continue;
1224 elseif (strpos($value, "\n") !== false) { #-- also for {refs}
1225 $value = str_replace("\n", ", ", trim($value));
1226 if (!$value) {
1227 continue;
1230 elseif ($i == "version") {
1231 $value = '<a href="' .
1232 ewiki_script("", $id, array("version"=>$value)) . '">' .
1233 $value . '</a> '."($commands)";
1235 elseif ($i == "flags") {
1236 continue; // MOODLE DOESN'T USE IT
1237 $fstr = "";
1238 for ($n = 0; $n < 32; $n++) {
1239 if ($value & (1 << $n)) {
1240 if (! ($s=$flagnames[$n])) { $s = "UU$n"; }
1241 $fstr .= $s . " ";
1244 $value = $fstr;
1246 elseif ($i == "author") {
1247 continue;
1248 $ewiki_links=1;
1249 $value = preg_replace_callback("/((\w+:)?([".EWIKI_CHARS_U."]+[".EWIKI_CHARS_L."]+){2,}[\w\d]*)/", "ewiki_link_regex_callback", $value);
1251 elseif ($i == "userid") {
1252 $i = 'author';
1253 if ($user = get_record('user', 'id', $value)) {
1254 if (!isset($course->id)) {
1255 $course->id = 1;
1257 $picture = print_user_picture($user->id, $course->id, $user->picture, false, true, true);
1258 $value = $picture." <a href=\"$CFG->wwwroot/user/view.php?id=$user->id&amp;course=$course->id\">".fullname($user)."</a>";
1259 } else {
1260 continue;
1261 //$value = @$current['author'];
1265 ##### BEGIN MOODLE ADDITION #####
1266 $o .= '<tr class="page-'.$i.'"><td valign="top" align="right" nowrap="nowrap"><b>' .ewiki_t($i). ':</b></td>' .
1267 '<td>' . $value . "</td></tr>\n";
1268 ##### END MOODLE ADDITION #####
1272 $o .= "</table><br /><br />\n";
1275 #-- page result split
1276 if ($v >= 1) {
1277 $o .= "<br />\n show " . ewiki_chunked_page($this, $id, -1, $v+1, 1) . "\n <br />";
1280 return($o);
1286 function ewiki_chunked_page($action, $id, $dir=-1, $start=10, $end=1, $limit=0, $overlap=0.25, $collapse_last=0.67) {
1288 global $ewiki_config;
1290 if (empty($limit)) {
1291 $limit = $ewiki_config["list_limit"];
1293 if ($overlap < 1) {
1294 $overlap = (int) ($limit * $overlap);
1297 $p = "";
1298 $n = $start;
1300 while ($n) {
1302 $n -= $dir * $overlap;
1304 $e = $n + $dir * ($limit + $overlap);
1306 if ($dir<0) {
1307 $e = max(1, $e);
1308 if ($e <= $collapse_last * $limit) {
1309 $e = 1;
1312 else {
1313 $e = min($end, $e);
1314 if ($e >= $collapse_last * $limit) {
1315 $e = $end;
1319 $o .= ($o?" &middot; ":"")
1320 . '<a href="'.ewiki_script($action, $id, array(EWIKI_UP_PAGENUM=>$n, EWIKI_UP_PAGEEND=>$e))
1321 . '">'. "$n-$e" . '</a>';
1323 if (($n=$e) <= $end) {
1324 $n = false;
1328 return('<div class="chunked-result">'. $o .'</div>');
1336 function ewiki_page_edit($id, $data, $action) {
1338 global $ewiki_links, $ewiki_author, $ewiki_plugins, $ewiki_ring, $ewiki_errmsg;
1340 $hidden_postdata = array();
1342 #-- previous version come back
1343 if (@$data["forced_version"]) {
1345 $current = ewiki_database("GET", array("id"=>$id));
1346 $data["version"] = $current["version"];
1347 unset($current);
1349 unset($_REQUEST["content"]);
1350 unset($_REQUEST["version"]);
1353 #-- edit hacks
1354 if ($pf_a = @$ewiki_plugins["edit_hook"]) foreach ($pf_a as $pf) {
1355 if ($output = $pf($id, $data, $hidden_postdata)) {
1356 return($output);
1360 #-- permission checks
1361 if (isset($ewiki_ring)) {
1362 $ring = $ewiki_ring;
1363 } else {
1364 $ring = 3;
1366 $flags = @$data["flags"];
1367 if (!($flags & EWIKI_DB_F_WRITEABLE)) {
1369 #-- perform auth
1370 $edit_ring = (EWIKI_PROTECTED_MODE>=2) ? (2) : (NULL);
1371 if (EWIKI_PROTECTED_MODE && !ewiki_auth($id, $data, $action, $edit_ring, "FORCE")) {
1372 return($ewiki_errmsg);
1375 #-- flag checking
1376 if (($flags & EWIKI_DB_F_READONLY) and ($ring >= 2)) {
1377 return(ewiki_t("CANNOTCHANGEPAGE"));
1379 if (($flags) and (($flags & EWIKI_DB_F_TYPE) != EWIKI_DB_F_TEXT) and ($ring >= 1)) {
1380 return(ewiki_t("CANNOTCHANGEPAGE"));
1384 #-- "Edit Me"
1385 $o = ewiki_make_title($id, ewiki_t("EDITTHISPAGE").(" '{$id}'"), 2, $action, "", "_MAY_SPLIT=1");
1387 #-- preview
1388 if (isset($_REQUEST["preview"])) {
1389 $o .= $ewiki_plugins["edit_preview"][0]($data);
1392 #-- save
1393 if (isset($_REQUEST["save"])) {
1395 #-- normalize to UNIX newlines
1396 $_REQUEST["content"] = str_replace("\015\012", "\012", $_REQUEST["content"]);
1397 $_REQUEST["content"] = str_replace("\015", "\012", $_REQUEST["content"]);
1399 #-- check for concurrent version saving
1400 $error = 0;
1401 if ((@$data["version"] >= 1) && ($data["version"] != @$_REQUEST["version"]) || (@$_REQUEST["version"] < 1)) {
1403 $pf = $ewiki_plugins["edit_patch"][0];
1405 if (!$pf || !$pf($id, $data)) {
1406 $error = 1;
1407 $o .= ewiki_t("ERRVERSIONSAVE") . "<br /><br />";
1411 if (!$error) {
1413 #-- new pages` flags
1414 if (! ($set_flags = @$data["flags"] & EWIKI_DB_F_COPYMASK)) {
1415 $set_flags = 1;
1417 if (EWIKI_ALLOW_HTML) {
1418 $set_flags |= EWIKI_DB_F_HTML;
1421 #-- mk db entry
1422 $save = array(
1423 "id" => $id,
1424 "version" => @$data["version"] + 1,
1425 "flags" => $set_flags,
1426 "content" => $_REQUEST["content"],
1427 "created" => ($uu=@$data["created"]) ? $uu : time(),
1428 "meta" => ($uu=@$data["meta"]) ? $uu : "",
1429 "hits" => ($uu=@$data["hits"]) ? $uu : "0",
1431 ewiki_data_update($save);
1433 #-- edit storage hooks
1434 if ($pf_a = @$ewiki_plugins["edit_save"]) {
1435 foreach ($pf_a as $pf) {
1436 $pf($save, $data);
1440 #-- save
1441 if (!$save || !ewiki_database("WRITE", $save)) {
1443 $o .= $ewiki_errmsg ? $ewiki_errmsg : ewiki_t("ERRORSAVING");
1446 else {
1447 #-- prevent double saving, when ewiki_page() is re-called
1448 $_REQUEST = $_GET = $_POST = array();
1450 $o = ewiki_t("THANKSFORCONTRIBUTION") . "<br /><br />";
1451 $o .= ewiki_page($id);
1453 if (EWIKI_EDIT_REDIRECT) {
1454 $url = ewiki_script("", $id, "thankyou=1", 0, 0, EWIKI_HTTP_HEADERS?ewiki_script_url():0);
1456 if (EWIKI_HTTP_HEADERS && !headers_sent()) {
1457 header("Status: 303 Redirect for GET");
1458 header("Location: $url");
1459 #header("URI: $url");
1460 #header("Refresh: 0; URL=$url");
1462 else {
1463 $o .= '<meta http-equiv="Refresh" content="0; URL='.htmlentities($url).'">';
1471 //@REWORK
1472 // header("Reload-Location: " . ewiki_script("", $id, "", 0, 0, ewiki_script_url()) );
1475 else {
1476 #-- Edit <form>
1477 $o .= ewiki_page_edit_form($id, $data, $hidden_postdata);
1479 #-- additional forms
1480 if ($pf_a = $ewiki_plugins["edit_form_final"]) foreach ($pf_a as $pf) {
1481 $pf($o, $id, $data, $action);
1485 return($o);
1489 function ewiki_data_update(&$data, $author="") {
1490 global $USER, $ewiki_links;
1492 #-- add backlinks entry
1493 ewiki_scan_wikiwords($data["content"], $ewiki_links, "_STRIP_EMAIL=1");
1494 $data["refs"] = "\n\n".implode("\n", array_keys($ewiki_links))."\n\n";
1495 $data["lastmodified"] = time();
1496 $data["author"] = ewiki_author($author);
1497 if (isset($USER->id)) {
1498 $data["userid"] = $USER->id;
1504 #-- edit <textarea>
1505 function ewiki_page_edit_form(&$id, &$data, &$hidden_postdata) {
1506 global $ewiki_plugins, $ewiki_config;
1508 $o='';
1510 #-- previously edited, or db fetched content
1511 if (@$_REQUEST["content"] || @$_REQUEST["version"]) {
1512 $data = array(
1513 "version" => &$_REQUEST["version"],
1514 "content" => &$_REQUEST["content"]
1517 else {
1518 if (empty($data["version"])) {
1519 $data["version"] = 1;
1521 @$data["content"] .= "";
1524 #-- normalize to DOS newlines
1525 $data["content"] = str_replace("\015\012", "\012", $data["content"]);
1526 $data["content"] = str_replace("\015", "\012", $data["content"]);
1527 $data["content"] = str_replace("\012", "\015\012", $data["content"]);
1529 $hidden_postdata["version"] = &$data["version"];
1531 #-- edit textarea/form
1532 $o .= ewiki_t("EDIT_FORM_1")
1533 . '<form method="post" enctype="multipart/form-data" action="'
1534 . ewiki_script("edit", $id) . '" name="ewiki"'
1535 . ' accept-charset="'.EWIKI_CHARSET.'">' . "\n";
1537 #-- additional POST vars
1538 foreach ($hidden_postdata as $name => $value) {
1539 $o .= '<input type="hidden" name="'.$name.'" value="'.$value.'" />'."\n";
1542 if (EWIKI_CHARSET=="UTF-8") {
1543 $data["content"] = utf8_encode($data["content"]);
1545 ($cols = strtok($ewiki_config["edit_box_size"], "x*/,;:")) && ($rows = strtok("x, ")) || ($cols=70) && ($rows=15);
1546 global $ewiki_use_editor, $ewiki_editor_content;
1547 $ewiki_editor_content=1;
1548 if($ewiki_use_editor) {
1549 ob_start();
1550 $usehtmleditor = can_use_html_editor();
1551 echo '<table><tr><td>';
1552 print_textarea($usehtmleditor, $rows, $cols, 680, 400, "content", ewiki_format($data["content"]));
1553 echo '</td></tr></table>';
1554 if ($usehtmleditor) {
1555 use_html_editor("content");
1557 $o .= ob_get_contents();
1558 ob_end_clean();
1559 } else {
1560 ##### END MOODLE ADDITION #####
1562 $o .= '<textarea wrap="soft" id="ewiki_content" name="content" rows="'.$rows.'" cols="'.$cols.'">'
1563 . htmlentities($data["content"]) . "</textarea>"
1564 . $GLOBALS["ewiki_t"]["C"]["EDIT_TEXTAREA_RESIZE_JS"];
1566 ##### BEGIN MOODLE ADDITION #####
1568 ##### END MOODLE ADDITION #####
1570 #-- more <input> elements before the submit button
1571 if ($pf_a = $ewiki_plugins["edit_form_insert"]) foreach ($pf_a as $pf) {
1572 $o .= $pf($id, $data, $action);
1575 ##### BEGIN MOODLE ADDITION (Cancel Editing into Button) #####
1576 $o .= "\n<br />\n"
1577 . '<input type="submit" name="save" value="'. ewiki_t("SAVE") . '" />'."\n"
1578 . '<input type="submit" name="preview" value="'. ewiki_t("PREVIEW") . '" />' . "\n"
1579 . '<input type="submit" name="canceledit" value="'. ewiki_t("CANCEL_EDIT") . '" />' . "\n";
1580 # . ' &nbsp; <a href="'. ewiki_script("", $id) . '">' . ewiki_t("CANCEL_EDIT") . '</a>';
1581 ##### END MOODLE ADDITION #####
1583 #-- additional form elements
1584 if ($pf_a = $ewiki_plugins["edit_form_append"]) foreach ($pf_a as $pf) {
1585 $o .= $pf($id, $data, $action);
1588 $o .= "\n</form>\n";
1589 // . ewiki_t("EDIT_FORM_2"); // MOODLE DELETION
1591 return('<div align="center" class="edit-box">'. $o .'</div>');
1596 #-- pic upload form
1597 function ewiki_page_edit_form_final_imgupload(&$o, &$id, &$data, &$action) {
1598 if (EWIKI_SCRIPT_BINARY && EWIKI_UP_UPLOAD && EWIKI_IMAGE_MAXSIZE) {
1599 $o .= "\n<br />\n". '<div class="image-upload">'
1600 . '<form action='
1601 . '"'. ewiki_script_binary("", EWIKI_IDF_INTERNAL, "", "_UPLOAD=1") .'"'
1602 . ' method="post" enctype="multipart/form-data" target="_upload">'
1603 . '<input type="hidden" name="MAX_FILE_SIZE" value="'.EWIKI_IMAGE_MAXSIZE.'" />'
1604 . '<input type="file" name="'.EWIKI_UP_UPLOAD.'"'
1605 . (defined("EWIKI_IMAGE_ACCEPT") ? ' accept="'.EWIKI_IMAGE_ACCEPT.'" />' : " />")
1606 . '<input type="hidden" name="'.EWIKI_UP_BINARY.'" value="'.EWIKI_IDF_INTERNAL.'" />'
1607 . '&nbsp;&nbsp;&nbsp;'
1608 . '<input type="submit" value="'.ewiki_t("UPLOAD_PICTURE_BUTTON").'" />'
1609 . '</form></div>'. "\n";
1614 function ewiki_page_edit_preview(&$data) {
1615 #### BEGIN MOODLE CHANGES
1616 global $moodle_format;
1617 $preview_text=$GLOBALS["ewiki_plugins"]["render"][0]($_REQUEST["content"], 1, EWIKI_ALLOW_HTML || (@$data["flags"]&EWIKI_DB_F_HTML));
1618 return( '<div class="preview">'
1619 . "<hr noshade>"
1620 . "<div align=\"right\">" . ewiki_t("PREVIEW") . "</div><hr noshade><br />\n"
1621 . format_text($preview_text, $moodle_format)
1622 . "<br /><br /><hr noshade><br />"
1623 . "</div>"
1625 #### END MOODLE CHANGES
1629 function ewiki_control_links($id, &$data, $action) {
1631 global $ewiki_plugins, $ewiki_ring, $ewiki_config;
1632 $action_links = & $ewiki_config["action_links"][$action];
1634 #-- disabled
1635 if (!$ewiki_config["control_line"]) {
1636 return("");
1639 $o = "\n"
1640 . '<div align="right" class="action-links control-links">'
1641 . "\n<br />\n"
1642 . "<hr noshade>" . "\n";
1644 if (@$data["forced_version"]) {
1646 $o .= '<form action="' . ewiki_script("edit", $id) . '" method="post">' .
1647 '<input type="hidden" name="edit" value="old" />' .
1648 '<input type="hidden" name="version" value="'.$data["forced_version"].'" />' .
1649 '<input type="submit" value="' . ewiki_t("OLDVERCOMEBACK") . '" /></form> ';
1651 else {
1652 foreach ($action_links as $action => $title)
1653 if (!empty($ewiki_plugins["action"][$action]) || !empty($ewiki_plugins["action_always"][$action]) || strpos($action, ":/"))
1655 if (EWIKI_PROTECTED_MODE && EWIKI_PROTECTED_MODE_HIDING && !ewiki_auth($id, $data, $action)) { continue; }
1657 $o .= '<a href="'
1658 . (strpos($action, ":/") ? $action : ewiki_script($action, $id))
1659 . '">' . ewiki_t($title) . '</a> &middot; ';
1663 if ($data["lastmodified"] >= UNIX_MILLENNIUM) {
1664 $o .= '<small>' . strftime(ewiki_t("LASTCHANGED"), @$data["lastmodified"]) . '</small>';
1667 $o .= "</div>\n";
1669 return($o);
1676 # ============================================================= rendering ===
1682 ######## ### ### ######### ### ### ### #######
1683 ######## #### ### ######### ### #### ### #######
1684 ### ##### ### ### ##### ### ###
1685 ###### ######### ### #### ### ######### ######
1686 ###### ######### ### #### ### ######### ######
1687 ### ### ##### ### ### ### ### ##### ###
1688 ######## ### #### ######### ### ### #### #######
1689 ######## ### ### ######### ### ### ### #######
1693 The _format() function transforms $wiki_source pages into <html> strings,
1694 also calls various markup and helper plugins during the transformation
1695 process. The $params array can activate various features and extensions.
1696 only accepts UNIX newlines!
1698 function ewiki_format (
1699 $wiki_source,
1700 $params = array()
1703 global $ewiki_links, $ewiki_plugins, $ewiki_config;
1705 #-- state vars
1706 $params = @array_merge($ewiki_config["format_params"], $params);
1707 $s = array(
1708 "in" => 0, # current input $iii[] block array index
1709 "para" => "",
1710 "line" => "",
1711 "post" => "", # string to append after current line/paragraph
1712 "line_i" => 0,
1713 "lines" => array(),
1714 "list" => "", # lists
1715 "tbl" => 0, # open table?
1716 "indent" => 0, # indentation
1717 "close" => array(),
1719 #-- aliases
1720 $in = &$s["in"];
1721 $line = &$s["line"];
1722 $lines = &$s["lines"];
1723 $para = &$s["para"];
1724 $post = &$s["post"];
1725 $list = &$s["list"];
1727 #-- input and output arrays
1728 if ($wiki_source[0] == "<") { # also prepend an empty line
1729 $wiki_source = "\n" . $wiki_source; # for faster strpos() searchs
1731 $iii = array(
1732 0 => array(
1733 0 => $wiki_source."\n", # body + empty line
1734 1 => 0x0FFF, # flags (0x1=WikiMarkup, 0x2=WikiLinks, 0x100=BlockPlugins)
1735 2 => "core", # block plugin name
1738 $ooo = array(
1740 unset($wiki_source);
1742 #-- plugins
1743 $pf_tbl = @$ewiki_plugins["format_table"][0];
1744 $pf_line = @$ewiki_plugins["format_line"];
1746 #-- wikimarkup (wm)
1747 $htmlentities = $ewiki_config["htmlentities"];
1748 $wm_indent = &$ewiki_config["wm_indent"];
1749 $wm_table_defaults = &$ewiki_config["wm_table_defaults"];
1750 $wm_source = &$ewiki_config["wm_source"];
1751 $wm_list = &$ewiki_config["wm_list"];
1752 $wm_list_chars = implode("", array_keys($wm_list));
1753 $wm_style = &$ewiki_config["wm_style"];
1754 $wm_start_end = &$ewiki_config["wm_start_end"];
1756 #-- eleminate html
1757 $iii[0][0] = strtr($iii[0][0], $htmlentities);
1758 unset($htmlentities["&"]);
1760 #-- pre-processing plugins (working on wiki source)
1761 if ($pf_source = $ewiki_plugins["format_source"]) {
1762 foreach ($pf_source as $pf) $pf(&$iii[0][0]);
1765 #-- simple markup
1766 $iii[0][0] = strtr($iii[0][0], $wm_source);
1768 #-- separate input into blocks ------------------------------------------
1769 foreach ($ewiki_config["format_block"] as $btype => $binfo) {
1771 #-- disabled block plugin?
1772 if ($binfo[2] && !$params[$binfo[2]]) {
1773 continue;
1776 #-- traverse $iii[]
1777 $in = -1;
1778 while ((++$in) < count($iii)) {
1780 #-- search fragment delimeters
1781 if ($iii[$in][1] & 0x0100)
1782 while (
1783 ($c = & $iii[$in][0]) &&
1784 (($l = strpos($c, $binfo[0])) !== false) &&
1785 ($r = strpos($c, $binfo[1], $l)) )
1787 $l_len = strlen($binfo[0]);
1788 $r_len = strlen($binfo[1]);
1790 $repl = array();
1791 // pre-text
1792 if (($l > 0) && trim($text = substr($c, 0, $l))) {
1793 $repl[] = array($text, 0xFFFF, "core");
1795 // the extracted part
1796 if (trim($text = substr($c, $l+$l_len, $r-$l-$r_len))) {
1797 $repl[] = array($text, $binfo[3], "$btype");
1799 // rest
1800 if (($r+$r_len < strlen($c)) && trim($text = substr($c, $r+$r_len))) {
1801 $repl[] = array($text, 0xFFFF, "core");
1803 array_splice($iii, $in, 1, $repl);
1805 $in += 1;
1810 #-- run format_block plugins
1811 $in = -1;
1812 while ((++$in) < count($iii)) {
1813 if (($btype = $iii[$in][2]) && ($pf_a = $ewiki_plugins["format_block"][$btype])) {
1814 $c = &$iii[$in][0];
1815 foreach ($pf_a as $pf) {
1816 # current buffer $c and pointer $in into $iii[] and state $s
1817 $pf($c, $in, $iii, $s, $btype);
1822 #-- wiki markup ------------------------------------------------------
1823 $para = "";
1824 $in = -1;
1825 while ((++$in) < count($iii)) {
1826 #-- wikimarkup
1827 if ($iii[$in][1] & 0x0001) {
1829 #-- input $lines buffer, and output buffer $ooo array
1830 $lines = explode("\n", $iii[$in][0]);
1831 $ooo[$in] = array(
1832 0 => "",
1833 1 => $iii[$in][1]
1835 $out = &$ooo[$in][0];
1836 $s["block"] = ($iii[$in][2] != "core"); # disables indentation & paragraphs
1838 #-- walk through wiki source lines
1839 $line_max = count($lines);
1840 foreach ($lines as $s["line_i"]=>$line) {
1841 #echo "line={$s[line_i]}:$line\n";
1843 #-- empty lines separate paragraphs
1844 if (!strlen($line)) {
1845 ewiki_format_close_para($ooo, $s);
1846 ewiki_format_close_tags($ooo, $s);
1847 if (!$s["block"]) {
1848 $out .= "\n";
1851 #-- horiz bar
1852 if (!strncmp($line, "----", 4)) {
1853 $out .= "<hr noshade>\n";
1854 continue;
1856 #-- html comment
1857 #if (!strncmp($line, "&lt;!--", 7)) {
1858 # $out .= "<!-- " . htmlentities(str_replace("--", "__", substr($line, 7))) . " -->\n";
1859 # continue;
1862 ($c0 = $line[0])
1863 or ($c0 = "\000");
1865 #-- tables
1866 ### MOODLE CHANGE: TRIM
1867 if (($c0 == "|") && ($line[strlen(trim($line))-1] == "|")) {
1868 if (!$s["tbl"]) {
1869 ewiki_format_close_para($ooo, $s);
1870 ewiki_format_close_tags($ooo, $s);
1871 $s["list"] = "";
1873 $line = substr($line, 1, -1);
1874 if ($pf_tbl) {
1875 $pf_tbl($line, $ooo, $s);
1877 else {
1878 if (!$s["tbl"]) {
1879 $out .= "<table " . $wm_table_defaults . ">\n";
1880 $s["close"][] = "\n</table>";
1882 $line = "<tr>\n<td>" . str_replace("|", "</td>\n<td>", $line) . "</td>\n</tr>";
1884 $s["tbl"] = 1;
1885 $para = false;
1887 elseif ($s["tbl"]) {
1888 $s["tbl"] = 0;
1892 #-- headlines
1893 if (($c0 == "!") && ($excl = strspn($line, "!"))) {
1894 if ($excl > 3) {
1895 $excl = 3;
1897 $line = substr($line, $excl);
1898 $excl = 5 - $excl;
1899 $line = "<h$excl>" . $line . "</h$excl>";
1900 if ($para) {
1901 ewiki_format_close_para($ooo, $s);
1903 ewiki_format_close_tags($ooo, $s);
1904 $para = false;
1907 #-- whole-line markup
1908 # ???
1911 #-- indentation (space/tab markup)
1912 $n_indent = 0;
1913 if (!$list && (!$s["block"]) && ($n_indent = strspn($line, " "))) {
1914 $n_indent = (int) ($n_indent / 2.65);
1915 while ($n_indent > $s["indent"]) {
1916 $out .= $wm_indent;
1917 $s["indent"]++;
1920 while ($n_indent < $s["indent"]) {
1921 $out .= "</div>\n";
1922 $s["indent"]--;
1926 #-- text style triggers
1927 foreach ($wm_style as $find=>$replace) {
1928 $find_len = strlen($find);
1929 $loop = 20;
1930 while(($loop--) && (($l = strpos($line, $find)) !== false) && ($r = strpos($line, $find, $l + $find_len))) {
1931 $line = substr($line, 0, $l) . $replace[0] .
1932 substr($line, $l + strlen($find), $r - $l - $find_len) .
1933 $replace[1] . substr($line, $r + $find_len);
1938 #-- list markup
1939 if (isset($wm_list[$c0])) {
1940 if (!$list) {
1941 ewiki_format_close_para($ooo, $s);
1942 ewiki_format_close_tags($ooo, $s);
1944 $new_len = strspn($line, $wm_list_chars);
1945 $new_list = substr($line, 0, $new_len);
1946 $old_len = strlen($list);
1947 $lchar = $new_list[$new_len-1];
1948 list($lopen, $ltag1, $ltag2) = $wm_list[$lchar];
1950 #-- cut line
1951 $line = substr($line, $new_len);
1952 $lspace = "";
1953 $linsert = "";
1954 if ($ltag1) {
1955 $linsert = "<$ltag1>" . strtok($line, $lchar) . "</$ltag1> ";
1956 $line = strtok("\000");
1959 #-- add another <li>st entry
1960 if ($new_len == $old_len) {
1961 $lspace = str_repeat(" ", $new_len);
1962 $out .= "</$ltag2>\n" . $lspace . $linsert . "<$ltag2>";
1964 #-- add list
1965 elseif ($new_len > $old_len) {
1966 while ($new_len > ($old_len=strlen($list))) {
1967 $lchar = $new_list[$old_len];
1968 $list .= $lchar;
1969 list($lopen, $ltag1, $ltag2) = $wm_list[$lchar];
1970 $lclose = strtok($lopen, " ");
1971 $lspace = str_repeat(" ", $new_len);
1973 $out .= "\n$lspace<$lopen>\n" . "$lspace". $linsert . "<$ltag2>";
1974 $s["close"][] = "$lspace</$lclose>";
1975 $s["close"][] = "$lspace</$ltag2>";
1978 #-- close lists
1979 else {
1980 while ($new_len < ($old_len=strlen($list))) {
1981 $remove = $old_len-$new_len;
1982 ewiki_format_close_tags($ooo, $s, 2*$remove);
1983 $list = substr($list, 0, -$remove);
1985 if ($new_len) {
1986 $lspace = str_repeat(" ", $new_len);
1987 $out .= "$lspace</$ltag2>\n" . $lspace . $linsert . "<$ltag2>";
1991 $list = $new_list;
1992 $para = false;
1994 elseif ($list) {
1995 if ($c0 == " ") {
1996 $para = false;
1998 else {
1999 ewiki_format_close_tags($ooo, $s);
2000 $list = "";
2005 #-- start-end markup
2006 foreach ($wm_start_end as $d) {
2007 $len0 = strlen($d[0]);
2008 $loop = 20;
2009 while(($loop--) && (($l = strpos($line, $d[0])) !== false) && ($r = strpos($line, $d[1], $l + $len0))) {
2010 $len1 = strlen($d[1]);
2011 $line = substr($line, 0, $l) . $d[2] .
2012 substr($line, $l + $len0, $r - $l - $len0) .
2013 $replace[1] . substr($line, $r + $len1);
2017 #-- call wiki source formatting plugins that work on current line
2018 if ($pf_line) {
2019 foreach ($pf_line as $pf) $pf($out, $line, $post);
2024 #-- add formatted line to page-output
2025 $line .= $post;
2026 if ($para === false) {
2027 $out .= $line;
2028 $para = "";
2030 else {
2031 $para .= $line . "\n";
2036 #-- last block, or next not WikiSource?
2037 if (!isset($iii[$in+1]) || !($iii[$in+1][1] & 0x0011)) {
2038 ewiki_format_close_para($ooo, $s);
2039 ewiki_format_close_tags($ooo, $s);
2042 #-- copy as is into output buffer
2043 else {
2044 $ooo[$in] = $iii[$in];
2046 $iii[$in] = array();
2049 #-- wiki linking ------------------------------------------------------
2050 $scan_src = "";
2051 for ($in=0; $in<count($ooo); $in++) {
2052 if (EWIKI_HTML_CHARS && ($ooo[$in][1] & 0x0004)) { # html character entities
2053 $ooo[$in][0] = str_replace("&amp;#", "&#", $ooo[$in][0]);
2055 if ($ooo[$in][1] & 0x0022) {
2056 #-- join together multiple WikiSource blocks
2057 while (isset($ooo[$in+1]) && ($ooo[$in][1] & 0x0002) && ($ooo[$in+1][1] & 0x0002)) {
2058 $ooo[$in] = array(
2059 0 => $ooo[$in][0] . "\n" . $ooo[$in+1][0],
2060 1 => $ooo[$in][1] | $ooo[$in+1][1],
2062 array_splice($ooo, $in+1, 1);
2065 $scan_src .= $ooo[$in][0];
2069 #-- pre-scan
2070 if (1+$params["scan_links"]) {
2071 ewiki_scan_wikiwords($scan_src, $ewiki_links);
2073 if ($pf_linkprep = $ewiki_plugins["format_prepare_linking"]) {
2074 foreach ($pf_linkprep as $pf) $pf($scan_src);
2076 $scan_src = NULL;
2078 #-- finally the link-detection-regex
2079 for ($in=0; $in<count($ooo); $in++) {
2080 if ($ooo[$in][1] & 0x0002) {
2081 ##### BEGIN MOODLE ADDITION #####
2082 # No WikiLinks in Editor
2083 #################################
2084 global $ewiki_use_editor, $ewiki_editor_content;
2085 if(!($ewiki_use_editor && $ewiki_editor_content)) {
2086 ##### END MOODLE ADDITION #####
2087 ewiki_render_wiki_links($ooo[$in][0]);
2088 ##### BEGIN MOODLE ADDITION #####
2090 ##### END MOODLE ADDITION #####
2094 #-- fin: combine all blocks into html string ----------------------------
2095 $html = "";
2096 for ($in=0; $in<count($ooo); $in++) {
2097 $html .= $ooo[$in][0] . "\n";
2098 $ooo[$in] = 0;
2100 #-- call post processing plugins
2101 if ($pf_final = $ewiki_plugins["format_final"]) {
2102 foreach ($pf_final as $pf) $pf($html);
2104 return($html);
2109 function ewiki_format_close_para(&$ooo, &$s) {
2110 $out = &$ooo[$s["in"]][0];
2111 #-- output text block
2112 if (trim($s["para"])) {
2113 if (!$s["block"]) {
2114 #### MOODLE CHANGES
2115 global $ewiki_use_editor;
2116 if(!$ewiki_use_editor) {
2117 $s["para"] = "\n<p>\n" . ltrim($s["para"], "\n") . "</p>\n";
2119 #### MOODLE CHANGES
2121 #-- paragraph formation plugins
2122 if ($pf_a = $GLOBALS["ewiki_plugins"]["format_para"]) {
2123 foreach ($pf_a as $pf) {
2124 $pf($s["para"], $ooo, $s);
2127 $out .= $s["para"];
2128 $s["para"] = "";
2130 #-- indentation
2131 while ($s["indent"]) {
2132 $out .= "</div>";
2133 $s["indent"]--;
2138 function ewiki_format_close_tags(&$ooo, &$s, $count=100) {
2139 $out = &$ooo[$s["in"]][0];
2140 if (!is_array($s) || !is_array($s["close"])) {
2141 die("\$s is garbaged == $s!!");
2143 while (($count--) && ($add = array_pop($s["close"]))) {
2144 $out .= $add . "\n";
2149 function ewiki_format_pre(&$str, &$in, &$iii, &$s, $btype) {
2150 $str = "<pre class=\"markup $btype\">" . $str . "</pre>";
2154 function ewiki_format_html(&$str, &$in, &$iii, &$s) {
2155 $he = array_reverse($GLOBALS["ewiki_config"]["htmlentities"]);
2156 $str = strtr($str, array_flip($he));
2157 $str = "<span class=\"markup html\">" . $str . "\n</span>\n";
2161 function ewiki_format_comment(&$str, &$in, &$iii, &$s, $btype) {
2162 $str = "<!-- " . str_replace("--", "¯¯", $str) . " -->";
2168 /* unclean pre-scanning for WikiWords in a page,
2169 pre-query to the db */
2170 function ewiki_scan_wikiwords(&$wiki_source, &$ewiki_links, $se=0) {
2172 global $ewiki_config;
2174 #-- find matches
2175 preg_match_all($ewiki_config["wiki_pre_scan_regex"], $wiki_source, $uu);
2176 $uu = @array_merge($uu[1], $uu[2], $uu[3], $uu[4], (array)@$uu[5]);
2178 #-- clean up list, trim() spaces (allows more unclean regex) - page id unification
2179 foreach ($uu as $i=>$id) {
2180 $uu[$i] = trim($id);
2182 unset($uu[""]);
2183 $uu = array_unique($uu);
2185 #-- query db
2186 $ewiki_links = ewiki_database("FIND", $uu);
2188 #-- strip email adresses
2189 if ($se) {
2190 foreach ($ewiki_links as $c=>$uu) {
2191 if (strpos($c, "@") && (strpos($c, ".") || strpos($c, ":"))) {
2192 unset($ewiki_links[$c]);
2201 /* regex on page content,
2202 handled by callback (see below)
2204 function ewiki_render_wiki_links(&$o) {
2206 global $ewiki_links, $ewiki_config, $ewiki_plugins;
2208 #-- merge with dynamic pages list
2209 ewiki_merge_links($ewiki_links);
2211 #-- replace WikiWords
2212 $link_regex = &$ewiki_config["wiki_link_regex"];
2213 $o = preg_replace_callback($link_regex, "ewiki_link_regex_callback", $o);
2215 #-- cleanup
2216 unset($ewiki_links);
2221 combines with page plugin list,
2222 and makes all case-insensitive
2224 function ewiki_merge_links(&$ewiki_links) {
2225 global $ewiki_plugins;
2226 if ($ewiki_links !== true) {
2227 foreach ($ewiki_plugins["page"] as $page=>$uu) {
2228 $ewiki_links[$page] = 1;
2230 $ewiki_links = ewiki_array($ewiki_links);
2237 /* link rendering (p)regex callback
2238 (ooutch, this is a complicated one)
2240 function ewiki_link_regex_callback($uu, $force_noimg=0) {
2241 #print "<pre>"; print_r($uu); print "</pre>";
2242 global $ewiki_links, $ewiki_plugins, $ewiki_config, $ewiki_id;
2244 $str = trim($uu[0]);
2245 $type = array();
2246 $states = array();
2248 #-- link bracket '[' escaped with '!' or '~'
2249 if (($str[0] == "!") || ($str[0] == "~")) {
2250 return(substr($str, 1));
2252 if ($str[0] == "#") {
2253 $states["define"] = 1;
2254 $str = substr($str, 1);
2256 if ($str[0] == "[") {
2257 $states["brackets"] = 1;
2258 $str = substr($str, 1, -1);
2261 #-- explicit title given via [ title | WikiLink ]
2262 $href = $title = strtok($str, "|");
2263 if ($uu = strtok("|")) {
2264 $href = $uu;
2265 $states["titled"] = 1;
2267 #-- title and href swapped: swap back
2268 if (strpos("://", $title) || strpos($title, ":") && !strpos($href, ":")) {
2269 $uu = $title; $title = $href; $href = $uu;
2272 #-- new entitling scheme [ url "title" ]
2273 if ((($l=strpos($str, '"')) < ($r=strrpos($str, '"'))) && ($l!==false) ) {
2274 $title = substr($str, $l + 1, $r - $l - 1);
2275 $href = substr($str, 0, $l) . substr($str, $r + 1);
2276 $states["titled"] = 1;
2279 #-- strip spaces
2280 $spaces_l = ($href[0]==" ") ?1:0;
2281 $spaces_r = ($href[strlen($href)-1]==" ") ?1:0;
2282 $title = ltrim(trim($title), "^");
2283 $href = ltrim(trim($href), "^");
2285 #-- strip_htmlentities()
2286 if (1&& (strpos($href, "&")!==false) && strpos($href, ";")) {
2287 foreach (array("&lt;"=>"<", "&gt;"=>">", "&amp;"=>"&") as $f=>$t) {
2288 $href = str_replace($f, $t, $href);
2292 #-- anchors
2293 $href2 = "";
2294 if (($p = strrpos($href, "#")) && ($p) && ($href[$p-1] != "&")) {
2295 $href2 = trim(substr($href, $p));
2296 $href = trim(substr($href, 0, $p));
2298 elseif ($p === 0) {
2299 $states["define"] = 1;
2301 if ($href == ".") {
2302 $href = $ewiki_id;
2305 #-- for case-insensitivines
2306 $href_i = EWIKI_CASE_INSENSITIVE ? strtolower($href) : ($href);
2308 #-- injected URLs
2309 if (strpos($inj_url = $ewiki_links[$href_i], "://")) {
2310 if ($href==$title) { $href = $inj_url; }
2313 #-- interwiki links
2314 if (strpos($href, ":") && ($uu = ewiki_interwiki($href, $type))) {
2315 $href = $uu;
2316 $str = "<a href=\"$href$href2\">$title</a>";
2318 #-- action:WikiLinks
2319 elseif ($ewiki_plugins["action"][$a=strtolower(strtok($href, ":"))]) {
2320 $type = array($a, "action", "wikipage");
2321 $str = '<a href="' . ewiki_script($a, strtok("\000")) . '">' . $title . '</a>';
2323 #-- page anchor definitions, if ($href[0]=="#")
2324 elseif (@$states["define"]) {
2325 $type = array("anchor");
2326 if ($title==$href) { $title="&nbsp;"; }
2327 $str = '<a name="' . htmlentities(ltrim($href, "#")) . '">' . ltrim($title, "#") . '</a>';
2329 #-- inner page anchor jumps
2330 elseif (strlen($href2) && ($href==$ewiki_id) || ($href[0]=="#") && ($href2=&$href)) {
2331 $type = array("jump");
2332 $str = '<a href="' . htmlentities($href2) . '">' . $title . '</a>';
2334 #-- ordinary internal WikiLinks
2335 elseif (($ewiki_links === true) || @$ewiki_links[$href_i]) {
2336 $type = array("wikipage");
2337 $str = '<a href="' . ewiki_script("", $href) . htmlentities($href2)
2338 . '">' . $title . '</a>';
2340 #-- guess for mail@addresses, convert to URI if
2341 elseif (strpos($href, "@") && !strpos($href, ":")) {
2342 $type = array("email");
2343 $href = "mailto:" . $href;
2345 #-- not found fallback
2346 else {
2347 $str = "";
2348 #-- a plugin may take care
2349 if ($pf_a = $ewiki_plugins["link_notfound"]) {
2350 foreach ($pf_a as $pf) {
2351 if ($str = $pf($title, $href, $href2, $type)) {
2352 break;
2356 #-- (QuestionMarkLink to edit/ action)
2357 if (!$str) {
2358 $type = array("notfound");
2359 $str = '<span class="NotFound"><b>' . $title . '</b><a href="' .
2360 ewiki_script("", $href) . '">?</a></span>';
2364 #-- convert standard URLs
2365 foreach ($ewiki_config["idf"]["url"] as $find)
2366 if (strpos($href, $find)===0) {
2367 $type[-2] = "url";
2368 $type[-1] = strtok($find, ":");
2370 #-- URL plugins
2371 if ($pf_a = $ewiki_plugins["link_url"]) foreach ($pf_a as $pf) {
2372 if ($str = $pf($href, $title)) { break 2; }
2374 $meta = @$ewiki_links[$href];
2376 #-- check for image files
2377 $ext = substr($href, strrpos($href,"."));
2378 $nocache = strpos($ext, "no");
2379 $ext = strtok($ext, "?&#");
2380 $obj = in_array($ext, $ewiki_config["idf"]["obj"]);
2381 $img = $obj || in_array($ext, $ewiki_config["idf"]["img"]);
2383 #-- internal:// references (binary files)
2384 if (EWIKI_SCRIPT_BINARY && ((strpos($href, EWIKI_IDF_INTERNAL)===0) ||
2385 EWIKI_IMAGE_MAXSIZE && EWIKI_CACHE_IMAGES && $img && !$nocache) )
2387 $type = array("binary");
2388 $href = ewiki_script_binary("", $href);
2391 #-- output html reference
2392 if (!$img || $force_noimg || !$states["brackets"] || (strpos($href, EWIKI_IDF_INTERNAL) === 0)) {
2393 $str = '<a href="' . $href . '">' . $title . '</a>';
2395 #-- img tag
2396 else {
2397 if (is_string($meta)) {
2398 $meta = unserialize($meta);
2400 $type = array("image");
2401 #-- uploaded images size
2402 $x = $meta["width"];
2403 $y = $meta["height"];
2404 if ($p = strpos('?', $href)) { #-- width/height given in url
2405 parse_str(str_replace("&amp;", "&", substr($href, $p)), $meta);
2406 ($uu = $meta["x"] . $meta["width"]) and ($x = $uu);
2407 ($uu = $meta["y"] . $meta["height"]) and ($y = $uu);
2408 if ($scale = $meta["r"] . $meta["scale"]) {
2409 ($p = strpos($scale, "%")) and ($scale = strpos($scale, 0, $p) / 100);
2410 $x *= $scale; $y *= $scale;
2413 $align = array('', ' align="right"', ' align="left"', ' align="center"');
2414 $align = $align[$spaces_l + 2*$spaces_r];
2415 $str = ($obj ? '<embed width="70%"' : '<img') . ' src="' . $href . '"' .
2416 ' alt="' . ($title) . '"' .
2417 (@$states["titled"] ? ' title="' . ($title) . '"' : '').
2418 ($x && $y ? " width=\"$x\" height=\"$y\"" : "") .
2419 $align . " />" . ($obj ? "</embed>" : "");
2420 # htmlentities($title)
2423 break;
2426 #-- icon/transform plugins
2427 ksort($type);
2428 if ($pf_a = @$ewiki_plugins["link_final"]) {
2429 foreach ($pf_a as $pf) { $pf($str, $type, $href, $title); }
2432 return($str);
2437 Returns URL if it encounters an InterWiki:Link or workalike.
2439 function ewiki_interwiki($href, &$type) {
2440 global $ewiki_config, $ewiki_plugins;
2442 if (strpos($href, ":") and !strpos($href, "//")
2443 and ($p1 = strtok($href, ":"))) {
2445 $page = strtok("\000");
2447 if (($p1 = ewiki_array($ewiki_config["interwiki"], $p1)) !== NULL) {
2448 $type = array("interwiki", $uu);
2449 while ($p1_alias = $ewiki_config["interwiki"][$p1]) {
2450 $type[] = $p1;
2451 $p1 = $p1_alias;
2453 if (!strpos($p1, "%s")) {
2454 $p1 .= "%s";
2456 $href = str_replace("%s", $page, $p1);
2457 return($href);
2459 elseif ($pf = $ewiki_plugins["intermap"][$p1]) {
2460 return($pf($p1, $page));
2467 implements FeatureWiki:InterMapWalking
2469 function ewiki_intermap_walking($id, &$data, $action) {
2470 if (empty($data["version"]) && ($href = ewiki_interwiki($id, $uu))) {
2471 header("Location: $href");
2472 return("<a href=\"$href\">$href</a>");
2478 # =========================================================================
2482 ##### ## ## ## ## ##### ## ##
2483 ###### ## ### ## #### ###### ## ##
2484 ## ## ## ### ## ###### ## ## ## ##
2485 ##### ## #### ## ## ## ###### ######
2486 ##### ## ####### ###### #### ####
2487 ## ### ## ## #### ###### ##### ##
2488 ## ### ## ## ### ## ## ## ### ##
2489 ###### ## ## ### ## ## ## ## ##
2490 ###### ## ## ## ## ## ## ## ##
2495 /* fetch & store
2497 function ewiki_binary($break=0) {
2498 global $ewiki_plugins;
2499 global $USER; // MOODLE
2501 #-- reject calls
2502 if (!strlen($id = @$_REQUEST[EWIKI_UP_BINARY]) || !EWIKI_IDF_INTERNAL) {
2503 return(false);
2505 if (headers_sent()) die("ewiki-binary configuration error");
2507 #-- upload requests
2508 $upload_file = @$_FILES[EWIKI_UP_UPLOAD];
2509 $add_meta = array();
2510 if ($orig_name = @$upload_file["name"]) {
2511 $add_meta["Content-Location"] = urlencode($orig_name);
2512 $add_meta["Content-Disposition"] = 'inline; filename="'.urlencode(basename("remote://$orig_name")).'"';
2515 #-- what are we doing here?
2516 if (($id == EWIKI_IDF_INTERNAL) && ($upload_file)) {
2517 $do = "upload";
2519 else {
2520 $data = ewiki_database("GET", array("id" => $id));
2521 $flags = @$data["flags"];
2522 if (EWIKI_DB_F_BINARY == ($flags & EWIKI_DB_F_TYPE)) {
2523 $do = "get";
2525 elseif (empty($data["version"]) and EWIKI_CACHE_IMAGES) {
2526 $do = "cache";
2528 else {
2529 $do = "nop";
2534 #-- auth only happens when enforced with _PROTECTED_MODE_XXL setting
2535 # (authentication for inline images in violation of the WWW spirit)
2536 if ((EWIKI_PROTECTED_MODE>=5) && !ewiki_auth($id, $data, "binary-{$do}")) {
2537 return($_REQUEST["id"]="view/BinaryPermissionError");
2540 #-- upload an image
2541 if ($do == "upload"){
2543 $id = ewiki_binary_save_image($upload_file["tmp_name"], "", $return=0, $add_meta);
2544 @unlink($upload_file["tmp_name"]);
2545 ($title = trim($orig_name, "/")) && ($title = preg_replace("/[^-._\w\d]+/", "_", substr(substr($orig_name, strrpos($title, "/")), 0, 20)))
2546 && ($title = '"'.$title.'"') || ($title="");
2548 if ($id) {
2549 echo<<<EOF
2550 <html><head><title>File/Picture Upload</title><script language="JavaScript" type="text/javascript"><!--
2551 opener.document.forms["ewiki"].elements["content"].value += "\\nUPLOADED PICTURE: [$id$title]\\n";
2552 window.setTimeout("self.close()", 5000);
2553 //--></script></head><body bgcolor="#440707" text="#FFFFFF">Your uploaded file was saved as<br /><big><b>
2554 [$id]
2555 </b></big>.<br /><br /><noscript>Please copy this &uarr; into the text input box:<br />select/mark it with your mouse, press [Ctrl]+[Insert], go back<br />to the previous screen and paste it into the textbox by pressing<br />[Shift]+[Insert] inside there.</noscript></body></html>
2556 EOF;
2560 #-- request for contents from the db
2561 elseif ($do == "get") {
2562 #### CHANGED FOR MOODLE
2563 if (EWIKI_HIT_COUNTING) {
2564 $tmp["id"]=$id;
2565 ewiki_database("HIT", $tmp);
2567 #### CHANGED FOR MOODLE
2569 #-- send http_headers from meta
2570 if (is_array($data["meta"])) {
2571 foreach ($data["meta"] as $hdr=>$val) {
2572 if (($hdr[0] >= "A") && ($hdr[0] <= "Z")) {
2573 header("$hdr: $val");
2578 #-- fetch from binary store
2579 if ($pf_a = $ewiki_plugins["binary_get"]) {
2580 #### CHANGED FOR MOODLE
2581 foreach ($pf_a as $pf) { $pf($id, $data["meta"]); }
2583 #### END CHANGED FOR MOODLE
2586 #-- else fpassthru
2587 echo $data["content"];
2590 #-- fetch & cache requested URL,
2591 elseif ($do == "cache") {
2593 #-- check for standard protocol names, to prevent us from serving
2594 # evil requests for '/etc/passwd.jpeg' or '../.htaccess.gif'
2595 if (preg_match('@^\w?(http|ftp|https|ftps|sftp)\w?://@', $id)) {
2597 #-- generate local copy
2598 $filename = tempnam(EWIKI_TMP, "ewiki.local.temp.");
2599 if (($i = fopen($id, "rb")) && ($o = fopen($filename, "wb"))) {
2601 while (!feof($i)) {
2602 fwrite($o, fread($i, 65536));
2605 fclose($i);
2606 fclose($o);
2608 $add_meta = array(
2609 "Content-Location" => urlencode($id),
2610 "Content-Disposition" => 'inline; filename="'.urlencode(basename($id)).'"'
2613 $result = ewiki_binary_save_image($filename, $id, "RETURN", $add_meta);
2617 #-- deliver
2618 if ($result && !$break) {
2619 ewiki_binary($break=1);
2621 #-- mark URL as unavailable
2622 else {
2623 $data = array(
2624 "id" => $id,
2625 "version" => 1,
2626 "flags" => EWIKI_DB_F_DISABLED,
2627 "lastmodified" => time(),
2628 "created" => time(),
2629 "author" => ewiki_author("ewiki_binary_cache"),
2630 "userid" => $USER->id,
2631 "content" => "",
2632 "meta" => array("Status"=>"404 Absent"),
2634 ewiki_database("WRITE", $data);
2635 header("Location: $id");
2636 ewiki_log("imgcache: did not find '$id', and marked it now in database as DISABLED", 2);
2641 #-- "we don't sell this!"
2642 else {
2643 if (strpos($id, EWIKI_IDF_INTERNAL) === false) {
2644 header("Status: 301 Located SomeWhere Else");
2645 header("Location: $id");
2647 else {
2648 header("Status: 404 Absent");
2649 header("X-Broken-URI: $id");
2653 // you should not remove this one, it is really a good idea to use it!
2654 die();
2662 function ewiki_binary_save_image($filename, $id="", $return=0,
2663 $add_meta=array(), $accept_all=EWIKI_ACCEPT_BINARY, $care_for_images=1)
2665 global $ewiki_plugins;
2666 global $USER; // MOODLE
2668 #-- break on empty files
2669 if (!filesize($filename)) {
2670 return(false);
2673 #-- check for image type and size
2674 $mime_types = array(
2675 "application/octet-stream",
2676 "image/gif",
2677 "image/jpeg",
2678 "image/png",
2679 "application/x-shockwave-flash"
2681 $ext_types = array(
2682 "bin", "gif", "jpeg", "png", "swf"
2684 list($width, $height, $mime_i, $uu) = getimagesize($filename);
2685 (!$mime_i) && ($mime_i=0) || ($mime = $mime_types[$mime_i]);
2687 #-- images expected
2688 if ($care_for_images) {
2690 #-- mime type
2691 if (!$mime_i && !$accept_all || !filesize($filename)) {
2692 ewiki_die(ewiki_t("BIN_NOIMG"), $return);
2693 return;
2696 #-- resize image
2697 if (strpos($mime,"image/")!==false) {
2698 if ($pf_a = $ewiki_plugins["image_resize"]) {
2699 foreach ($pf_a as $pf) {
2700 if (EWIKI_IMAGE_RESIZE && (filesize($filename) > EWIKI_IMAGE_MAXSIZE)) {
2701 $pf($filename, $mime, $return);
2702 clearstatcache();
2703 }}}}
2705 #-- reject image if too large
2706 if (strlen($content) > EWIKI_IMAGE_MAXSIZE) {
2707 ewiki_die(ewiki_t("BIN_IMGTOOLARGE"), $return);
2708 return;
2711 #-- again check mime type and image sizes
2712 list($width, $height, $mime_i, $uu) = getimagesize($filename);
2713 (!$mime_i) && ($mime_i=0) || ($mime = $mime_types[$mime_i]);
2716 ($ext = $ext_types[$mime_i]) or ($ext = $ext_types[0]);
2718 #-- binary files
2719 if ((!$mime_i) && ($pf = $ewiki_plugins["mime_magic"][0])) {
2720 if ($tmp = $pf($content)) {
2721 $mime = $tmp;
2724 if (!strlen($mime)) {
2725 $mime = $mime_types[0];
2728 #-- store size of binary file
2729 $add_meta["size"] = filesize($filename);
2730 $content = "";
2732 #-- handler for (large/) binary content?
2733 if ($pf_a = $ewiki_plugins["binary_store"]) {
2734 foreach ($pf_a as $pf) {
2735 $pf($filename, $id, $add_meta, $ext);
2739 #-- read file into memory (2MB), to store it into the database
2740 if ($filename) {
2741 $f = fopen($filename, "rb");
2742 $content = fread($f, 1<<21);
2743 fclose($f);
2746 #-- generate db file name
2747 if (empty($id)) {
2748 $md5sum = md5($content);
2749 $id = EWIKI_IDF_INTERNAL . $md5sum . ".$ext";
2750 ewiki_log("generated md5sum '$md5sum' from file content");
2753 #-- prepare meta data
2754 $meta = @array_merge(array(
2755 "class" => $mime_i ? "image" : "file",
2756 "Content-Type" => $mime,
2757 "Pragma" => "cache",
2758 ), $add_meta);
2759 if ($mime_i) {
2760 $meta["width"] = $width;
2761 $meta["height"] = $height;
2764 #-- database entry
2765 $data = array(
2766 "id" => $id,
2767 "version" => "1",
2768 "author" => ewiki_author(),
2769 "userid" => $USER->id,
2770 "flags" => EWIKI_DB_F_BINARY | EWIKI_DB_F_READONLY,
2771 "created" => time(),
2772 "lastmodified" => time(),
2773 "meta" => &$meta,
2774 "content" => &$content,
2777 #-- write if not exist
2778 $exists = ewiki_database("FIND", array($id));
2779 if (! $exists[$id] ) {
2780 $result = ewiki_database("WRITE", $data);
2781 ewiki_log("saving of '$id': " . ($result ? "ok" : "error"));
2783 else {
2784 ewiki_log("binary_save_image: '$id' was already in the database", 2);
2787 return($id);
2793 # =========================================================================
2796 #### #### #### ######## ########
2797 ##### ##### #### ########## ##########
2798 ###### ###### #### #### ### #### ###
2799 ############# #### ####
2800 ############# #### ######## ####
2801 #### ### #### #### ######## ####
2802 #### # #### #### #### ####
2803 #### #### #### ### #### #### ###
2804 #### #### #### ######### ##########
2805 #### #### #### ####### ########
2809 /* yes! it is not neccessary to annoy users with country flags, if the
2810 http already provides means to determine preferred languages!
2812 function ewiki_localization() {
2814 global $ewiki_t, $ewiki_plugins;
2816 $deflangs = ','.@$_ENV["LANGUAGE"] . ','.@$_ENV["LANG"]
2817 . ",".EWIKI_DEFAULT_LANG . ",en,C";
2819 foreach (explode(",", @$_SERVER["HTTP_ACCEPT_LANGUAGE"].$deflangs) as $l) {
2821 $l = strtok($l, ";");
2822 $l = strtok($l, "-"); $l = strtok($l, "_"); $l = strtok($l, ".");
2823 $l = trim($l);
2825 $ewiki_t["languages"][] = strtolower($l);
2832 /* poor mans gettext, $repl is an array of string replacements to get
2833 applied to the fetched text chunk,
2834 "$const" is either an entry from $ewiki_t[] or a larger text block
2835 containing _{text} replacement braces of the form "_{...}"
2837 function ewiki_t($const, $repl=array(), $pref_langs=array()) {
2838 ##### BEGIN MOODLE ADDITION #####
2839 $replacechars=array("." => "",
2840 "," => "",
2841 "!" => "",
2842 ";" => "",
2843 ":" => "",
2844 "'" => "",
2845 '"' => "",
2846 "-" => "",
2847 "_" => "",
2848 " " => "",
2849 "+" => "");
2851 $translation=get_string(strtolower(strtr($const,$replacechars)),"wiki",$repl);
2852 return $translation;
2853 ##### END MOODLE ADDITION #####
2855 /* global $ewiki_t;
2857 #-- use default language wishes
2858 if (empty($pref_langs)) {
2859 $pref_langs = $ewiki_t["languages"];
2862 #-- large text snippet replaceing
2863 if (strpos($const, "_{") !== false) {
2864 while ( (($l=strpos($const,"_{")) || ($l===0)) && ($r=strpos($const,"}",$l)) ) {
2865 $const = substr($const, 0, $l)
2866 . ewiki_t(substr($const, $l+2, $r-$l-2))
2867 . substr($const,$r+1);
2871 #-- just one string
2872 else foreach ($pref_langs as $l) {
2874 if (is_string($r = @$ewiki_t[$l][$const]) || ($r = @$ewiki_t[$l][strtoupper($const)])) {
2876 foreach ($repl as $key=>$value) {
2877 if ($key[0] != '$') {
2878 $key = '$'.$key;
2880 $r = str_replace($key, $value, $r);
2882 return($r);
2887 return($const);*/
2895 function ewiki_log($msg, $error_type=3) {
2897 if ((EWIKI_LOGLEVEL >= 0) && ($error_type <= EWIKI_LOGLEVEL)) {
2899 $msg = time() . " - " .
2900 getremoteaddr() . ":" . $_SERVER["REMOTE_PORT"] . " - " .
2901 $_SERVER["REQUEST_METHOD"] . " " . $_SERVER["REQUEST_URI"] . " - " .
2902 strtr($msg, "\n\r\000\377\t\f", "\r\r\r\r\t\f") . "\n";
2903 error_log($msg, 3, EWIKI_LOGFILE);
2910 function ewiki_die($msg, $return=0) {
2911 ewiki_log($msg, 1);
2912 if ($return) {
2913 return($GLOBALS["ewiki_error"] = $msg);
2915 else {
2916 die($msg);
2922 function ewiki_array_hash(&$a) {
2923 return(count($a) . ":" . implode(":", array_keys(array_slice($a, 0, 3))));
2928 /* provides an case-insensitive in_array replacement to search a page name
2929 in a list of others;
2930 the supplied $array WILL be lowercased afterwards, unless $dn was set
2932 function ewiki_in_array($value, &$array, $dn=0, $ci=EWIKI_CASE_INSENSITIVE) {
2934 static $as = array();
2936 #-- work around pass-by-reference
2937 if ($dn && $ci) { $dest = array(); }
2938 else { $dest = &$array; }
2940 #-- make everything lowercase
2941 if ($ci) {
2942 $value = strtolower($value);
2943 if (empty($as[ewiki_array_hash($array)])) { // prevent working on the
2944 foreach ($array as $i=>$v) { // same array multiple times
2945 $dest[$i] = strtolower($v);
2947 $as[ewiki_array_hash($dest)] = 1;
2951 #-- search in values
2952 return(in_array($value, $dest));
2957 /* case-insensitively retrieves an entry from an $array,
2958 or returns the given $array lowercased if $key was obmitted
2960 function ewiki_array($array, $key=false, $am=1, $ci=EWIKI_CASE_INSENSITIVE) {
2962 #-- make everything lowercase
2963 if ($ci) {
2964 $key = strtolower($key);
2966 $r = array();
2967 foreach ($array as $i=>$v) {
2968 $i = strtolower($i);
2969 if (!$am || empty($r[$i])) {
2970 $r[$i] = $v;
2972 else {
2973 $r[$i] .= $v; //RET: doubling for images`meta won't happen
2974 } // but should be "+" here for integers
2976 $array = &$r;
2979 #-- search in values
2980 if ($key) {
2981 return(@$array[$key]);
2983 else {
2984 return($array);
2993 function ewiki_author($defstr="") {
2995 $author = @$GLOBALS["ewiki_author"];
2996 ($ip = getremoteaddr()) or ($ip = "127.0.0.0");
2997 ($port = $_SERVER["REMOTE_PORT"]) or ($port = "null");
2998 $hostname = gethostbyaddr($ip);
2999 $remote = (($ip != $hostname) ? $hostname . " " : "")
3000 . $ip . ":" . $port;
3002 (empty($author)) && (
3003 ($author = $defstr) ||
3004 ($author = $_SERVER["HTTP_FROM"]) || // RFC2068 sect 14.22
3005 ($author = $_SERVER["PHP_AUTH_USER"])
3008 (empty($author))
3009 && ($author = $remote)
3010 || ($author = addslashes($author) . " (" . $remote . ")" );
3012 return($author);
3019 /* Returns a value of (true) if the currently logged in user (this must
3020 be handled by one of the plugin backends) is authenticated to do the
3021 current $action, or to view the current $id page.
3022 - alternatively just checks current authentication $ring permission level
3023 - errors are returned via the global $ewiki_errmsg
3025 function ewiki_auth($id, &$data, $action, $ring=false, $request_auth=0) {
3027 global $ewiki_plugins, $ewiki_ring, $ewiki_author, $ewiki_errmsg;
3028 $ok = true;
3029 $ewiki_errmsg="";
3031 #echo "_a($id,dat,$action,$ring,$request_auth)<br />\n";
3033 if (EWIKI_PROTECTED_MODE) {
3035 #-- set required vars
3036 if (!isset($ewiki_ring)) {
3037 $ewiki_ring = (int)EWIKI_AUTH_DEFAULT_RING;
3039 if ($ring===false) {
3040 $ring = NULL;
3043 #-- plugins to call
3044 $pf_login = @$ewiki_plugins["auth_query"][0];
3045 $pf_perm = $ewiki_plugins["auth_perm"][0];
3047 #-- nobody is currently logged in, so try to fetch username,
3048 # the login <form> is not yet enforced
3049 if ($pf_login && empty($ewiki_auth_user)) {
3050 $pf_login($data, 0);
3053 #-- check permission for current request (page/action/ring)
3054 if ($pf_perm) {
3056 #-- via _auth handler
3057 $ok = $pf_perm($id, $data, $action, $ring, $request_auth);
3059 #-- if it failed, we really depend on the login <form>,
3060 # and then recall the _perm plugin
3061 if ($pf_login && (($request_auth >= 2) || !$ok && $request_auth && (empty($ewiki_auth_user) || EWIKI_AUTO_LOGIN) && empty($ewiki_errmsg))) {
3062 //@FIXME: complicated if() - strip empty(errmsg) ??
3063 $pf_login($data, $request_auth);
3064 $ok = $pf_perm($id, $data, $action, $ring, $request_auth=0);
3067 else {
3068 $ok = !isset($ring) || isset($ring) && ($ewiki_ring <= $ring);
3071 #-- return error string
3072 if (!$ok && empty($ewiki_errmsg)) {
3073 $ewiki_errmsg = ewiki_t("FORBIDDEN");
3077 return($ok);
3082 Queries all registered ["auth_userdb"] plugins for the given
3083 username, and compares password to against "db" value, sets
3084 $ewiki_ring and returns(true) if valid.
3086 function ewiki_auth_user($username, $password) {
3087 global $ewiki_ring, $ewiki_errmsg, $ewiki_auth_user, $ewiki_plugins, $ewiki_author;
3089 if (empty($username)) {
3090 return(false);
3092 if (($password[0] == "$") || (strlen($password) > 12)) {
3093 ewiki_log("_auth_userdb: password was transmitted in encoded form, or is just too long (login attemp for user '$username')", 2);
3094 return(false);
3097 if ($pf_u = $ewiki_plugins["auth_userdb"])
3098 foreach ($pf_u as $pf) {
3100 if (function_exists($pf) && ($entry = $pf($username, $password))) {
3102 #-- get and compare password
3103 if ($entry = (array) $entry) {
3104 $enc_pw = $entry[0];
3106 $success = false
3107 || ($enc_pw == substr($password, 0, 12))
3108 || ($enc_pw == md5($password))
3109 || ($enc_pw == crypt($password, substr($enc_pw, 0, 2)))
3110 || function_exists("sha1") && ($enc_pw == sha1($password));
3111 $success &= $enc_pw != "*";
3113 #-- return if it matches
3114 if ($success) {
3115 if (isset($entry[1])) {
3116 $ewiki_ring = (int)($entry[1]);
3117 } else {
3118 $ewiki_ring = 2; //(EWIKI_AUTH_DEFAULT_RING - 1);
3120 if (empty($ewiki_author)) {
3121 ($ewiki_author = $entry[2]) or
3122 ($ewiki_author = $username);
3124 return($success && ($ewiki_auth_user=$username));
3129 if ($username || $password) {
3130 ewiki_log("_auth_userdb: wrong password supplied for user '$username', not verified against any userdb", 3);
3131 $ewiki_errmsg = "wrong username and/or password";
3132 # ewiki_auth($uu, $uu, $uu, $uu, 2);
3134 return(false);
3141 /* reads all files from "./init-pages/" into the database,
3142 when ewiki is run for the very first time and the FrontPage
3143 does not yet exist in the database
3145 function ewiki_eventually_initialize(&$id, &$data, &$action) {
3147 global $USER;
3149 #-- initialize database only if frontpage missing
3150 if (($id==EWIKI_PAGE_INDEX) && ($action=="edit") && empty($data["version"])) {
3152 ewiki_database("INIT", array());
3153 #### BEGIN MOODLE CHANGE
3154 $path=EWIKI_INIT_PAGES;
3155 if (!empty($path)) {
3156 if ($dh = @opendir($path=EWIKI_INIT_PAGES)) {
3157 while ($filename = readdir($dh)) {
3158 if (preg_match('/^(['.EWIKI_CHARS_U.']+['.EWIKI_CHARS_L.']+\w*)+/', $filename)) {
3159 $found = ewiki_database("FIND", array($filename));
3160 if (! $found[$filename]) {
3161 $content = implode("", file("$path/$filename"));
3162 ewiki_scan_wikiwords($content, $ewiki_links, "_STRIP_EMAIL=1");
3163 $refs = "\n\n" . implode("\n", array_keys($ewiki_links)) . "\n\n";
3164 $save = array(
3165 "id" => "$filename",
3166 "version" => "1",
3167 "flags" => "1",
3168 "content" => $content,
3169 "author" => ewiki_author("ewiki_initialize"),
3170 "userid" => $USER->id,
3171 "refs" => $refs,
3172 "lastmodified" => filemtime("$path/$filename"),
3173 "created" => filectime("$path/$filename") // (not exact)
3175 ewiki_database("WRITE", $save);
3179 closedir($dh);
3181 else {
3182 echo "<b>ewiki error</b>: could not read from directory ". realpath($path) ."<br />\n";
3185 #### END MOODLE CHANGE
3187 #-- try to view/ that newly inserted page
3188 if ($data = ewiki_database("GET", array("id"=>$id))) {
3189 $action = "view";
3197 #---------------------------------------------------------------------------
3201 ######## ### ######## ### ######## ### ###### ########
3202 ######## ### ######## ### ######## ### ###### ########
3203 ## ## ## ## ## ## ## ## ## ## ## ## ## ##
3204 ## ## ## ## ## ## ## ## ## ## ## ## ## ##
3205 ## ## ## ## ## ## ## ## ## ## ## ## ##
3206 ## ## ## ## ## ## ## ## ## ## ## ## ##
3207 ## ## ## ## ## ## ## ######## ## ## ###### ######
3208 ## ## ## ## ## ## ## ######## ## ## ###### ######
3209 ## ## ######### ## ######### ## ## ######### ## ##
3210 ## ## ######### ## ######### ## ## ######### ## ##
3211 ## ## ## ## ## ## ## ## ## ## ## ## ## ##
3212 ## ## ## ## ## ## ## ## ## ## ## ## ## ##
3213 ######## ## ## ## ## ## ######## ## ## ###### ########
3214 ######## ## ## ## ## ## ######## ## ## ###### ########
3219 /* wrapper
3221 function ewiki_database($action, $args, $sw1=0, $sw2=0, $pf=false) {
3223 #-- normalize (fetch bad parameters)
3224 if (($action=="GET") && !is_array($args) && is_string($args)) {
3225 $args = array("id" => $args);
3228 #-- treat special
3229 switch ($action) {
3231 case "GETALL":
3232 $args = array_unique(@array_merge($args, array("flags", "version")));
3233 $args = array_diff($args, array("id"));
3234 break;
3236 case "SEARCH":
3237 # unset($args["version"]);
3238 # unset($args["flags"]);
3239 break;
3241 default:
3242 break;
3245 #-- handle {meta} sub array as needed
3246 if (is_array(@$args["meta"])) {
3247 $args["meta"] = serialize($args["meta"]);
3250 #-- database plugin
3251 if (($pf) || ($pf = @$GLOBALS["ewiki_plugins"]["database"][0])) {
3252 $r = $pf($action, $args, $sw1, $sw2);
3254 else {
3255 ewiki_log("DB layer: no backend!", 0);
3256 $r = false;
3259 #-- database layer generation 2 abstraction
3260 if (is_array($r) && (($action=="SEARCH") || ($action=="GETALL"))) {
3261 $z = new ewiki_dbquery_result(array_keys($args));
3262 foreach ($r as $id=>$row) {
3263 $z->add($row);
3265 $r = $z;
3268 #-- extract {meta} sub array
3269 if (is_array($r) && !is_array(@$r["meta"]) && strlen(@$r["meta"])) {
3270 $r["meta"] = unserialize($r["meta"]);
3273 return($r);
3278 /* returned for SEARCH and GETALL queries, as those operations are
3279 otherwise too memory exhaustive
3281 class ewiki_dbquery_result {
3283 var $keys = array();
3284 var $entries = array();
3285 var $buffer = EWIKI_DBQUERY_BUFFER;
3286 var $size = 0;
3288 function ewiki_dbquery_result($keys) {
3289 $keys = @array_merge($keys, array(-50=>"id", "version", "flags"));
3290 $this->keys = array_unique($keys);
3293 function add($row) {
3294 if (is_array($row)) {
3295 if ($this->buffer) {
3296 $this->size += strlen(serialize($row));
3297 $this->buffer = $this->size <= EWIKI_DBQUERY_BUFFER;
3299 else {
3300 $row = $row["id"];
3303 $this->entries[] = $row;
3306 function get($all=0, $flags=0x00) {
3307 $row = array();
3309 $prot_hide = ($flags&0x0020) && EWIKI_PROTECTED_MODE && EWIKI_PROTECTED_MODE_HIDING;
3310 do {
3311 if (count($this->entries)) {
3313 #-- fetch very first entry from $entries list
3314 $r = array_shift($this->entries);
3316 #-- finish if buffered entry
3317 if (is_array($r) && !$all) {
3318 $row = $r;
3320 #-- else refetch complete entry from database
3321 else {
3322 if (is_array($r)) {
3323 $r = $r["id"];
3325 $r = ewiki_database("GET", array("id"=>$r));
3326 if (!$all) {
3327 foreach ($this->keys as $key) {
3328 $row[$key] = $r[$key];
3330 } else {
3331 $row = $r;
3334 unset($r);
3336 else {
3337 return(NULL); // no more entries
3340 #-- expand {meta} field
3341 if (is_array($row) && is_string(@$row["meta"])) {
3342 $row["meta"] = unserialize($row["meta"]);
3345 #-- drop unwanted results
3346 if ($prot_hide && !ewiki_auth($row["id"], $row, $ewiki_action)) {
3347 $row = array();
3349 } while ($prot_hide && empty($row));
3351 return($row);
3354 function count() {
3355 return(count($this->entries));
3361 /* MySQL database backend
3362 (default)
3363 Note: this is of course an abuse of the relational database scheme,
3364 but neccessary for real db independence and abstraction
3366 function ewiki_database_mysql($action, &$args, $sw1, $sw2) {
3368 #-- reconnect to the database (if multiple are used)
3369 #<off># mysql_ping($GLOBALS["db"]);
3371 #-- result array
3372 $r = array();
3374 switch($action) {
3376 /* Returns database entry as array for the page whose name was given
3377 with the "id" key in the $args array, usually fetches the latest
3378 version of a page, unless a specific "version" was requested in
3379 the $args array.
3381 case "GET":
3382 $id = "'" . mysql_escape_string($args["id"]) . "'";
3383 ($version = 0 + @$args["version"]) and ($version = "AND (version=$version)") or ($version="");
3384 $result = mysql_query("SELECT * FROM " . EWIKI_DB_TABLE_NAME
3385 . " WHERE (pagename=$id) $version ORDER BY version DESC LIMIT 1"
3387 if ($result && ($r = mysql_fetch_array($result, MYSQL_ASSOC))) {
3388 $r["id"] = $r["pagename"];
3389 unset($r["pagename"]);
3391 if (strlen($r["meta"])) {
3392 $r["meta"] = @unserialize($r["meta"]);
3394 break;
3398 /* Increases the hit counter for the page name given in $args array
3399 with "id" index key.
3401 case "HIT":
3402 mysql_query("UPDATE " . EWIKI_DB_TABLE_NAME . " SET hits=(hits+1) WHERE pagename='" . mysql_escape_string($args["id"]) . "'");
3403 break;
3407 /* Stores the $data array into the database, while not overwriting
3408 existing entries (using WRITE); returns 0 on failure and 1 if
3409 saved correctly.
3411 case "OVERWRITE": // fall-through
3412 $COMMAND = "REPLACE";
3414 case "WRITE":
3415 $args["pagename"] = $args["id"];
3416 unset($args["id"]);
3418 if (is_array($args["meta"])) {
3419 $args["meta"] = serialize($args["meta"]);
3422 $sql1 = $sql2 = "";
3423 foreach ($args as $index => $value) {
3424 if (is_int($index)) {
3425 continue;
3427 $a = ($sql1 ? ', ' : '');
3428 $sql1 .= $a . $index;
3429 $sql2 .= $a . "'" . mysql_escape_string($value) . "'";
3432 strlen(@$COMMAND) || ($COMMAND = "INSERT");
3434 $result = mysql_query("$COMMAND INTO " . EWIKI_DB_TABLE_NAME .
3435 " (" . $sql1 . ") VALUES (" . $sql2 . ")"
3438 return($result && mysql_affected_rows() ?1:0);
3439 break;
3443 /* Checks for existence of the WikiPages whose names are given in
3444 the $args array. Returns an array with the specified WikiPageNames
3445 associated with values of "0" or "1" (stating if the page exists
3446 in the database). For images/binary db entries returns the "meta"
3447 field instead of an "1".
3449 case "FIND":
3450 $sql = "";
3451 foreach (array_values($args) as $id) if (strlen($id)) {
3452 $r[$id] = 0;
3453 $sql .= ($sql ? " OR " : "") .
3454 "(pagename='" . mysql_escape_string($id) . "')";
3456 $result = mysql_query($sql = "SELECT pagename AS id, meta FROM " .
3457 EWIKI_DB_TABLE_NAME . " WHERE $sql "
3459 while ($result && ($row = mysql_fetch_row($result))) {
3460 $r[$row[0]] = strpos($row[1], 's:5:"image"') ? $row[1] : 1;
3462 break;
3466 /* Returns an array of __all__ pages, where each entry is made up
3467 of the fields from the database requested with the $args array,
3468 e.g. array("flags","meta","lastmodified");
3470 case "GETALL":
3471 $result = mysql_query("SELECT pagename AS id, ".
3472 implode(", ", $args) .
3473 " FROM ". EWIKI_DB_TABLE_NAME .
3474 " GROUP BY id, version DESC"
3476 $r = new ewiki_dbquery_result($args);
3477 $drop = "";
3478 while ($result && ($row = mysql_fetch_array($result, MYSQL_ASSOC))) {
3479 $i = EWIKI_CASE_INSENSITIVE ? strtolower($row["id"]) : $row["id"];
3480 if ($i != $drop) {
3481 $drop = $i;
3482 $r->add($row);
3485 break;
3489 /* Returns array of database entries (also arrays), where the one
3490 specified column matches the specified content string, for example
3491 $args = array("content" => "text...piece")
3492 is not guaranteed to only search/return the latest version of a page
3494 case "SEARCH":
3495 $field = implode("", array_keys($args));
3496 $content = strtolower(implode("", $args));
3497 if ($field == "id") { $field = "pagename"; }
3499 $result = mysql_query("SELECT pagename AS id, version, flags" .
3500 (EWIKI_DBQUERY_BUFFER && ($field!="pagename") ? ", $field" : "") .
3501 " FROM " . EWIKI_DB_TABLE_NAME .
3502 " WHERE LOCATE('" . mysql_escape_string($content) . "', LCASE($field)) " .
3503 " GROUP BY id, version DESC"
3505 $r = new ewiki_dbquery_result(array("id","version",$field));
3506 $drop = "";
3507 while ($result && ($row = mysql_fetch_array($result, MYSQL_ASSOC))) {
3508 $i = EWIKI_CASE_INSENSITIVE ? strtolower($row["id"]) : $row["id"];
3509 if ($i != $drop) {
3510 $drop = $i;
3511 $r->add($row);
3514 break;
3518 case "DELETE":
3519 $id = mysql_escape_string($args["id"]);
3520 $version = $args["version"];
3521 mysql_query("DELETE FROM " . EWIKI_DB_TABLE_NAME ."
3522 WHERE pagename='$id' AND version=$version");
3523 break;
3527 case "INIT":
3528 mysql_query("CREATE TABLE " . EWIKI_DB_TABLE_NAME ."
3529 (pagename VARCHAR(160) NOT NULL,
3530 version INTEGER UNSIGNED NOT NULL DEFAULT 0,
3531 flags INTEGER UNSIGNED DEFAULT 0,
3532 content MEDIUMTEXT,
3533 author VARCHAR(100) DEFAULT 'ewiki',
3534 userid INTEGER UNSIGNED DEFAULT 0,
3535 created INTEGER UNSIGNED DEFAULT ".time().",
3536 lastmodified INTEGER UNSIGNED DEFAULT 0,
3537 refs MEDIUMTEXT,
3538 meta MEDIUMTEXT,
3539 hits INTEGER UNSIGNED DEFAULT 0,
3540 PRIMARY KEY id (pagename, version) )
3542 echo mysql_error();
3543 break;
3545 default:
3548 return($r);
3553 </script>