2 @define
("EWIKI_VERSION", "R1.01d");
6 ErfurtWiki - an embedable, fast and user-friendly wiki engine
8 This is Public Domain (no license, no warranty); but feel free
9 to redistribute it under GPL or anything else you like.
11 http://erfurtwiki.sourceforge.net/
12 Mario Salzer <mario*erphesfurt·de> and many others(tm)
15 Use it from inside yoursite.php like that:
24 #-- you could also establish a mysql connection in here, of course:
25 // mysql_connect(":/var/run/mysqld/mysqld.sock", "user", "pw")
26 // and mysql_query("USE mydatabase");
29 #-------------------------------------------------------- config ---
31 #-- I'm sorry for that, but all the @ annoy me
32 error_reporting(0x0000377 & error_reporting());
33 # error_reporting(E_ALL^E_NOTICE);
35 #-- the position of your ewiki-wrapper script
36 define("EWIKI_SCRIPT", "?id="); # relative/absolute to docroot
37 # define("EWIKI_SCRIPT_URL", "http://...?id="); # absolute URL
39 #-- change to your needs (site lang)
40 define("EWIKI_NAME", "ErfurtWiki");
41 define("EWIKI_PAGE_INDEX", "ErfurtWiki");
42 define("EWIKI_PAGE_NEWEST", "NewestPages");
43 define("EWIKI_PAGE_SEARCH", "SearchPages");
44 define("EWIKI_PAGE_HITS", "MostVisitedPages");
45 define("EWIKI_PAGE_VERSIONS", "MostOftenChangedPages");
46 define("EWIKI_PAGE_UPDATES", "UpdatedPages");
48 #-- default settings are good settings - most often ;)
50 define("EWIKI_PRINT_TITLE", 1); # <h2>WikiPageName</h2> on top
51 define("EWIKI_SPLIT_TITLE", 0); # <h2>Wiki Page Name</h2>
52 define("EWIKI_CONTROL_LINE", 1); # EditThisPage-link at bottom
53 define("EWIKI_LIST_LIMIT", 20); # listing limit
55 define("EWIKI_AUTO_EDIT", 1); # edit box for non-existent pages
56 define("EWIKI_EDIT_REDIRECT", 1); # redirect after edit save
57 define("EWIKI_DEFAULT_ACTION", "view"); # (keep!)
58 define("EWIKI_CASE_INSENSITIVE", 1); # wikilink case sensitivity
59 define("EWIKI_HIT_COUNTING", 1);
60 define("UNIX_MILLENNIUM", 1000000000);
62 define("EWIKI_ALLOW_HTML", 0); # often a very bad idea
63 define("EWIKI_HTML_CHARS", 1); # allows for È
64 define("EWIKI_ESCAPE_AT", 1); # "@" -> "@"
66 define("EWIKI_HTTP_HEADERS", 1); # most often a good thing
67 define("EWIKI_NO_CACHE", 1); # browser+proxy shall not cache
68 define("EWIKI_URLENCODE", 1); # disable when _USE_PATH_INFO
69 define("EWIKI_URLDECODE", 1);
70 define("EWIKI_USE_PATH_INFO", 1 &&!strstr($_SERVER["SERVER_SOFTWARE"],"Apache"));
71 define("EWIKI_USE_ACTION_PARAM", 1);
72 define("EWIKI_ACTION_SEP_CHAR", "/");
73 define("EWIKI_UP_PAGENUM", "n"); # _UP_ means "url parameter"
74 define("EWIKI_UP_PAGEEND", "e");
75 define("EWIKI_UP_BINARY", "binary");
76 define("EWIKI_UP_UPLOAD", "upload");
78 define("EWIKI_DEFAULT_LANG", "en");
79 define("EWIKI_CHARSET", "UTF-8");
81 define("EWIKI_PROTECTED_MODE", 0); # disable funcs + require auth
82 define("EWIKI_PROTECTED_MODE_HIDING", 0); # hides disallowed actions
83 define("EWIKI_AUTH_DEFAULT_RING", 3); # 0=root 1=priv 2=user 3=view
84 define("EWIKI_AUTO_LOGIN", 1); # [auth_query] on startup
86 #-- allowed WikiPageNameCharacters
88 #### BEGIN MOODLE CHANGES - to remove auto-camelcase linking.
89 global $moodle_disable_camel_case;
90 if ($moodle_disable_camel_case) {
91 define("EWIKI_CHARS_L", "");
92 define("EWIKI_CHARS_U", "");
95 #### END MOODLE CHANGES
97 define("EWIKI_CHARS_L", "a-z_µ¤$\337-\377");
98 define("EWIKI_CHARS_U", "A-Z0-9\300-\336");
100 #### BEGIN MOODLE CHANGES
102 #### END MOODLE CHANGES
104 define("EWIKI_CHARS", EWIKI_CHARS_L
.EWIKI_CHARS_U
);
107 define("EWIKI_DB_TABLE_NAME", "ewiki"); # MySQL / ADOdb
108 define("EWIKI_DBFILES_DIRECTORY", "/tmp"); # see "db_flat_files.php"
109 define("EWIKI_DBA", "/tmp/ewiki.dba"); # see "db_dba.php"
110 define("EWIKI_DBQUERY_BUFFER", 512*1024); # 512K
111 define("EWIKI_INIT_PAGES", "./init-pages"); # for initialization
113 define("EWIKI_DB_F_TEXT", 1<<0);
114 define("EWIKI_DB_F_BINARY", 1<<1);
115 define("EWIKI_DB_F_DISABLED", 1<<2);
116 define("EWIKI_DB_F_HTML", 1<<3);
117 define("EWIKI_DB_F_READONLY", 1<<4);
118 define("EWIKI_DB_F_WRITEABLE", 1<<5);
119 define("EWIKI_DB_F_APPENDONLY", 1<<6); #nyi
120 define("EWIKI_DB_F_SYSTEM", 1<<7);
121 define("EWIKI_DB_F_PART", 1<<8);
122 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
);
123 define("EWIKI_DB_F_ACCESS", EWIKI_DB_F_READONLY | EWIKI_DB_F_WRITEABLE | EWIKI_DB_F_APPENDONLY
);
124 define("EWIKI_DB_F_COPYMASK", EWIKI_DB_F_TYPE | EWIKI_DB_F_ACCESS
);
126 define("EWIKI_DBFILES_NLR", '\\n');
127 define("EWIKI_DBFILES_ENCODE", 0 ||
(DIRECTORY_SEPARATOR
!= "/"));
128 define("EWIKI_DBFILES_GZLEVEL", "2");
131 define("EWIKI_ADDPARAMDELIM", (strstr(EWIKI_SCRIPT
,"?") ?
"&" : "?"));
133 #-- binary content (images)
134 define("EWIKI_SCRIPT_BINARY", /*"/binary.php?binary="*/ ltrim(strtok(" ".EWIKI_SCRIPT
,"?"))."?".EWIKI_UP_BINARY
."=" );
135 define("EWIKI_CACHE_IMAGES", 1 &&!headers_sent());
136 define("EWIKI_IMAGE_MAXSIZE", 64 *1024);
137 define("EWIKI_IMAGE_MAXWIDTH", 3072);
138 define("EWIKI_IMAGE_MAXHEIGHT", 2048);
139 define("EWIKI_IMAGE_MAXALLOC", 1<<19);
140 define("EWIKI_IMAGE_RESIZE", 1);
141 define("EWIKI_IMAGE_ACCEPT", "image/jpeg,image/png,image/gif,application/x-shockwave-flash");
142 define("EWIKI_IDF_INTERNAL", "internal://");
143 define("EWIKI_ACCEPT_BINARY", 0); # for arbitrary binary data files
146 define("EWIKI_TMP", $_SERVER["TEMP"] ?
$_SERVER["TEMP"] : "/tmp");
147 define("EWIKI_LOGLEVEL", -1); # 0=error 1=warn 2=info 3=debug
148 define("EWIKI_LOGFILE", "/tmp/ewiki.log");
150 #-- plugins (tasks mapped to function names)
151 $ewiki_plugins["database"][] = "ewiki_database_mysql";
152 $ewiki_plugins["edit_preview"][] = "ewiki_page_edit_preview";
153 $ewiki_plugins["render"][] = "ewiki_format";
154 $ewiki_plugins["init"][-5] = "ewiki_localization";
155 $ewiki_plugins["init"][-1] = "ewiki_binary";
156 $ewiki_plugins["handler"][-105] = "ewiki_eventually_initialize";
157 $ewiki_plugins["handler"][] = "ewiki_intermap_walking";
158 $ewiki_plugins["view_append"][-1] = "ewiki_control_links";
159 $ewiki_plugins["view_final"][-1] = "ewiki_add_title";
160 $ewiki_plugins["page_final"][] = "ewiki_http_headers";
161 $ewiki_plugins["page_final"][99115115] = "ewiki_page_css_container";
162 $ewiki_plugins["edit_form_final"][] = "ewiki_page_edit_form_final_imgupload";
163 $ewiki_plugins["format_block"]["pre"][] = "ewiki_format_pre";
164 $ewiki_plugins["format_block"]["code"][] = "ewiki_format_pre";
165 $ewiki_plugins["format_block"]["htm"][] = "ewiki_format_html";
166 $ewiki_plugins["format_block"]["html"][] = "ewiki_format_html";
167 $ewiki_plugins["format_block"]["comment"][] = "ewiki_format_comment";
171 $ewiki_plugins["page"][EWIKI_PAGE_NEWEST
] = "ewiki_page_newest";
172 $ewiki_plugins["page"][EWIKI_PAGE_SEARCH
] = "ewiki_page_search";
173 if (EWIKI_HIT_COUNTING
) $ewiki_plugins["page"][EWIKI_PAGE_HITS
] = "ewiki_page_hits";
174 $ewiki_plugins["page"][EWIKI_PAGE_VERSIONS
] = "ewiki_page_versions";
175 $ewiki_plugins["page"][EWIKI_PAGE_UPDATES
] = "ewiki_page_updates";
178 $ewiki_plugins["action"]["edit"] = "ewiki_page_edit";
179 $ewiki_plugins["action_always"]["links"] = "ewiki_page_links";
180 $ewiki_plugins["action"]["info"] = "ewiki_page_info";
181 $ewiki_plugins["action"]["view"] = "ewiki_page_view";
183 #-- helper vars ---------------------------------------------------
184 $ewiki_config["idf"]["url"] = array("http://", "mailto:", "internal://", "ftp://", "https://", "irc://", "telnet://", "news://", "chrome://", "file://", "gopher://", "httpz://");
185 $ewiki_config["idf"]["img"] = array(".jpeg", ".png", ".jpg", ".gif", ".j2k");
186 $ewiki_config["idf"]["obj"] = array(".swf", ".svg");
189 $ewiki_config["action_links"]["view"] = @array_merge
(array(
190 "edit" => "EDITTHISPAGE", # ewiki_t() is called on these
191 "links" => "BACKLINKS",
192 "info" => "PAGEHISTORY",
193 "like" => "LIKEPAGES",
194 ), @$ewiki_config["action_links"]["view"]
196 $ewiki_config["action_links"]["info"] = @array_merge
(array(
198 "edit" => "fetchback",
199 ), @$ewiki_config["action_links"]["info"]
202 #-- variable configuration settings (go into '$ewiki_config')
203 $ewiki_config_DEFAULTSTMP = array(
204 "edit_thank_you" => 1,
205 "edit_box_size" => "70x15",
206 "print_title" => EWIKI_PRINT_TITLE
,
207 "split_title" => EWIKI_SPLIT_TITLE
,
208 "control_line" => EWIKI_CONTROL_LINE
,
209 "list_limit" => EWIKI_LIST_LIMIT
,
210 "script" => EWIKI_SCRIPT
,
211 "script_url" => (defined("EWIKI_SCRIPT_URL")?EWIKI_SCRIPT_URL
:NULL),
212 "script_binary" => EWIKI_SCRIPT_BINARY
,
213 #-- heart of the wiki -- don't try to read this! ;)
215 "wiki_pre_scan_regex" => '/
217 ((?:(?:\w+:)*['.EWIKI_CHARS_U
.']+['.EWIKI_CHARS_L
.']+){2,}[\w\d]*)
218 |\^([-'.EWIKI_CHARS_L
.EWIKI_CHARS_U
.']{3,})
219 |\[ (?:"[^\]\"]+" | \s+ | [^:\]#]+\|)* ([^\|\"\[\]\#]+) (?:\s+ | "[^\]\"]+")* [\]\#]
220 |(\w{3,9}:\/\/[^?#\s\[\]\'\"\)\,<]+) /x',
222 "wiki_link_regex" => "\007 [!~]?(
223 \#?\[[^<>\[\]\n]+\] |
224 \^[-".EWIKI_CHARS_U
.EWIKI_CHARS_L
."]{3,} |
225 \b([\w]{3,}:)*([".EWIKI_CHARS_U
."]+[".EWIKI_CHARS_L
."]+){2,}\#?[\w\d]* |
226 ([a-z]{2,9}://|mailto:)[^\s\[\]\'\"\)\,<]+ |
227 \w[-_.+\w]+@(\w[-_\w]+[.])+\w{2,} ) \007x",
229 #-- rendering ruleset
231 "wm_table_defaults" => 'cellpadding="2" border="1" cellspacing="0"',
232 "wm_whole_line" => array(),
233 "htmlentities" => array(
238 "wm_source" => array(
241 "\n;:" => "\n ", # workaround, replaces the old ;:
244 "-" => array('ul type="square"', "", "li"),
245 "*" => array('ul type="circle"', "", "li"),
246 "#" => array("ol", "", "li"),
247 ":" => array("dl", "dt", "dd"),
248 #<out># ";" => array("dl", "dt", "dd"),
251 "'''''" => array("<b><i>", "</i></b>"),
252 "'''" => array("<b>", "</b>"),
253 "___" => array("<i><b>", "</b></i>"),
254 "''" => array("<em>", "</em>"),
255 "__" => array("<strong>", "</strong>"),
256 "^^" => array("<sup>", "</sup>"),
257 "==" => array("<tt>", "</tt>"),
258 #<off># "***" => array("<b><i>", "</i></b>"),
259 #<off># "###" => array("<big><b>", "</b></big>"),
260 "**" => array("<b>", "</b>"),
261 "##" => array("<big>", "</big>"),
262 "µµ" => array("<small>", "</small>"),
264 "wm_start_end" => array(
266 #-- rendering plugins
267 "format_block" => array(
268 "html" => array("<html>", "</html>", "html", 0x0000),
269 "htm" => array("<htm>", "</htm>", "html", 0x0003),
270 "code" => array("<code>", "</code>", false, 0x0000),
271 "pre" => array("<pre>", "</pre>", false, 0x003F),
272 "comment" => array("\n<!--", "-->", false, 0x0030),
273 # "verbatim" => array("<verbatim>", "</verbatim>", false, 0x0000),
275 "format_params" => array(
277 "html" => EWIKI_ALLOW_HTML
,
281 foreach ($ewiki_config_DEFAULTSTMP as $set => $val) {
282 if (!isset($ewiki_config[$set])) {
283 $ewiki_config[$set] = $val;
285 elseif (is_array($val)) foreach ($val as $vali=>$valv) {
287 $ewiki_config[$set][] = $valv;
289 elseif (!isset($ewiki_config[$set][$vali])) {
290 $ewiki_config[$set][$vali] = $valv;
294 $ewiki_config_DEFAULTSTMP = $valv = $vali = $val = NULL;
296 #-- init stuff, autostarted parts
297 ksort($ewiki_plugins["init"]);
298 if ($pf_a = $ewiki_plugins["init"]) foreach ($pf_a as $pf) {
299 // Binary Handling starts here
300 #### MOODLE CHANGE TO BE COMPATIBLE WITH PHP 4.1
301 #if(headers_sent($file,$line)) {
302 # error("Headers already sent: $file:$line");
304 error("Headers already sent.");
308 unset($ewiki_plugins["init"]);
310 #-- text (never remove the "C" or "en" sections!)
312 $ewiki_t["C"] = @array_merge
(@$ewiki_t["C"], array(
313 "DATE" => "%a, %d %b %G %T %Z",
314 "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>',
317 $ewiki_t["en"] = @array_merge
(@$ewiki_t["en"], array(
318 "EDITTHISPAGE" => "EditThisPage",
319 "APPENDTOPAGE" => "Add to",
320 "BACKLINKS" => "BackLinks",
321 "PAGESLINKINGTO" => "Pages linking to \$title",
322 "PAGEHISTORY" => "PageInfo",
323 "INFOABOUTPAGE" => "Information about page",
324 "LIKEPAGES" => "Pages like this",
325 "NEWESTPAGES" => "Newest Pages",
326 "LASTCHANGED" => "last changed on %c",
327 "DOESNOTEXIST" => "This page does not yet exist, please click on EditThisPage if you'd like to create it.",
328 "DISABLEDPAGE" => "This page is currently not available.",
329 "ERRVERSIONSAVE" => "Sorry, while you edited this page someone else
330 did already save a changed version. Please go back to the
331 previous screen and copy your changes to your computers
332 clipboard to insert it again after you reload the edit
334 "ERRORSAVING" => "An error occoured while saving your changes. Please try again.",
335 "THANKSFORCONTRIBUTION" => "Thank you for your contribution!",
336 "CANNOTCHANGEPAGE" => "This page cannot be changed.",
337 "OLDVERCOMEBACK" => "Make this old version come back to replace the current one",
338 "PREVIEW" => "Preview",
340 "CANCEL_EDIT" => "CancelEditing",
341 "UPLOAD_PICTURE_BUTTON" => "upload picture >>>",
342 "EDIT_FORM_1" => "<a href=\"".EWIKI_SCRIPT
."GoodStyle\">GoodStyle</a> is to
343 write what comes to your mind. Don't care about how it
344 looks too much now. You can add <a href=\"".EWIKI_SCRIPT
."WikiMarkup\">WikiMarkup</a>
345 also later if you think it is necessary.<br />",
346 "EDIT_FORM_2" => "<br />Please do not write things, which may make other
347 people angry. And please keep in mind that you are not all that
348 anonymous in the internet (find out more about your computers
349 '<a href=\"http://google.com/search?q=my+computers+IP+address\">IP address</a>' at Google).",
350 "BIN_IMGTOOLARGE" => "Image file is too large!",
351 "BIN_NOIMG" => "This is no image file (inacceptable file format)!",
352 "FORBIDDEN" => "You are not authorized to access this page.",
355 $ewiki_t["es"] = @array_merge
(@$ewiki_t["es"], array(
356 "EDITTHISPAGE" => "EditarEstaPágina",
357 "BACKLINKS" => "EnlacesInversos",
358 "PAGESLINKINGTO" => "Páginas enlazando \$title",
359 "PAGEHISTORY" => "InfoPágina",
360 "INFOABOUTPAGE" => "Información sobre la página",
361 "LIKEPAGES" => "Páginas como esta",
362 "NEWESTPAGES" => "Páginas más nuevas",
363 "LASTCHANGED" => "última modificación %d/%m/%Y a las %H:%M",
364 "DOESNOTEXIST" => "Esta página aún no existe, por favor eliga EditarEstaPágina si desea crearla.",
365 "DISABLEDPAGE" => "Esta página no está disponible en este momento.",
366 "ERRVERSIONSAVE" => "Disculpe, mientras editaba esta página alguién más
367 salvó una versión modificada. Por favor regrese a
368 a la pantalla anterior y copie sus cambios a su computador
369 para insertalos nuevamente después de que cargue
370 la pantalla de edición.",
371 "ERRORSAVING" => "Ocurrió un error mientras se salvavan sus cambios. Por favor intente de nuevo.",
372 "THANKSFORCONTRIBUTION" => "Gracias por su contribución!",
373 "CANNOTCHANGEPAGE" => "Esta página no puede ser modificada.",
374 "OLDVERCOMEBACK" => "Hacer que esta versión antigua regrese a remplazar la actual",
375 "PREVIEW" => "Previsualizar",
377 "CANCEL_EDIT" => "CancelarEdición",
378 "UPLOAD_PICTURE_BUTTON" => "subir gráfica >>>",
379 "EDIT_FORM_1" => "<a href=\"".EWIKI_SCRIPT
."BuenEstilo\">BuenEstilo</a> es
380 escribir lo que viene a su mente. No se preocupe mucho
381 por la apariencia. También puede agregar <a href=\"".EWIKI_SCRIPT
."ReglasDeMarcadoWiki\">ReglasDeMarcadoWiki</a>
382 más adelante si piensa que es necesario.<br />",
383 "EDIT_FORM_2" => "<br />Por favor no escriba cosas, que puedan
384 enfadar a otras personas. Y por favor tenga en mente que
385 usted no es del todo anónimo en Internet
387 '<a href=\"http://google.com/search?q=my+computers+IP+address\">IP address</a>' de su computador con Google).",
388 "BIN_IMGTOOLARGE" => "¡La gráfica es demasiado grande!",
389 "BIN_NOIMG" => "¡No es un archivo con una gráfica (formato de archivo inaceptable)!",
390 "FORBIDDEN" => "No está autorizado para acceder a esta página.",
393 $ewiki_t["de"] = @array_merge
(@$ewiki_t["de"], array(
394 "EDITTHISPAGE" => "DieseSeiteÄndern",
395 "APPENDTOPAGE" => "Ergänze",
396 "BACKLINKS" => "ZurückLinks",
397 "PAGESLINKINGTO" => "Verweise zur Seite \$title",
398 "PAGEHISTORY" => "SeitenInfo",
399 "INFOABOUTPAGE" => "Informationen über Seite",
400 "LIKEPAGES" => "Ähnliche Seiten",
401 "NEWESTPAGES" => "Neueste Seiten",
402 "LASTCHANGED" => "zuletzt geändert am %d.%m.%Y um %H:%M",
403 "DISABLEDPAGE" => "Diese Seite kann momentan nicht angezeigt werden.",
404 "ERRVERSIONSAVE" => "Entschuldige, aber während Du an der Seite
405 gearbeitet hast, hat bereits jemand anders eine geänderte
406 Fassung gespeichert. Damit nichts verloren geht, browse bitte
407 zurück und speichere Deine Änderungen in der Zwischenablage
408 (Bearbeiten->Kopieren) um sie dann wieder an der richtigen
409 Stelle einzufügen, nachdem du die EditBoxSeite nocheinmal
411 Vielen Dank für Deine Mühe.",
412 "ERRORSAVING" => "Beim Abspeichern ist ein Fehler aufgetreten. Bitte versuche es erneut.",
413 "THANKSFORCONTRIBUTION" => "Vielen Dank für Deinen Beitrag!",
414 "CANNOTCHANGEPAGE" => "Diese Seite kann nicht geändert werden.",
415 "OLDVERCOMEBACK" => "Diese alte Version der Seite wieder zur Aktuellen machen",
416 "PREVIEW" => "Vorschau",
417 "SAVE" => "Speichern",
418 "CANCEL_EDIT" => "ÄnderungenVerwerfen",
419 "UPLOAD_PICTURE_BUTTON" => "Bild hochladen >>>",
420 "EDIT_FORM_1" => "<a href=\"".EWIKI_SCRIPT
."GuterStil\">GuterStil</a> ist es,
421 ganz einfach das zu schreiben, was einem gerade in den
422 Sinn kommt. Du solltest dich jetzt noch nicht so sehr
423 darum kümmern, wie die Seite aussieht. Du kannst später
424 immernoch zurückkommen und den Text mit <a href=\"".EWIKI_SCRIPT
."FormatierungsRegeln\">WikiTextFormatierungsRegeln</a>
426 "EDIT_FORM_2" => "<br />Bitte schreib keine Dinge, die andere Leute
427 verärgern könnten. Und bedenke auch, daß es schnell auf
428 dich zurückfallen kann wenn du verschiedene andere Dinge sagst (mehr Informationen zur
429 '<a href=\"http://google.de/search?q=computer+IP+adresse\">IP Adresse</a>'
430 deines Computers findest du bei Google).",
434 $ewiki_config["interwiki"] = @array_merge
(
435 @$ewiki_config["interwiki"],
437 "javascript" => "", # this actually protects from javascript: links
440 "this" => EWIKI_SCRIPT
, # better was absolute _URL to ewiki wrapper
442 "ErfurtWiki" => "http://erfurtwiki.sourceforge.net/?id=",
443 "InterWiki" => "InterWikiSearch",
444 "InterWikiSearch" => "http://sunir.org/apps/meta.pl?",
445 "Wiki" => "WardsWiki",
446 "WardsWiki" => "http://www.c2.com/cgi/wiki?",
447 "WikiFind" => "http://c2.com/cgi/wiki?FindPage&value=",
448 "WikiPedia" => "http://www.wikipedia.com/wiki.cgi?",
449 "MeatBall" => "MeatballWiki",
450 "MeatballWiki" => "http://www.usemod.com/cgi-bin/mb.pl?",
451 "UseMod" => "http://www.usemod.com/cgi-bin/wiki.pl?",
452 "PhpWiki" => "http://phpwiki.sourceforge.net/phpwiki/index.php3?",
453 "LinuxWiki" => "http://linuxwiki.de/",
454 "OpenWiki" => "http://openwiki.com/?",
455 "Tavi" => "http://andstuff.org/tavi/",
456 "TWiki" => "http://twiki.sourceforge.net/cgi-bin/view/",
457 "MoinMoin" => "http://www.purl.net/wiki/moin/",
458 "Google" => "http://google.com/search?q=",
459 "ISBN" => "http://www.amazon.com/exec/obidos/ISBN=",
460 "icq" => "http://www.icq.com/",
467 #-------------------------------------------------------------------- main ---
469 /* this is the main function, which you should preferrably call to
470 integrate the ewiki into your web site; it chains to most other
471 parts and plugins (including the edit box);
472 if you do not supply the requested pages "$id" we will fetch it
473 from the pre-defined possible URL parameters.
475 function ewiki_page($id=false) {
477 global $ewiki_links, $ewiki_plugins, $ewiki_ring, $ewiki_t, $ewiki_errmsg;
482 if (!isset($_REQUEST)) {
483 $_REQUEST = @array_merge
($_GET, $_POST);
488 $id = format_string($id,true);
490 $action = EWIKI_DEFAULT_ACTION
;
491 if ($delim = strpos($id, EWIKI_ACTION_SEP_CHAR
)) {
492 $action = substr($id, 0, $delim);
493 $id = substr($id, $delim +
1);
495 elseif (EWIKI_USE_ACTION_PARAM
&& isset($_REQUEST["action"])) {
496 $action = $_REQUEST["action"];
498 $GLOBALS["ewiki_id"] = $id;
499 $GLOBALS["ewiki_title"] = ewiki_split_title($id);
500 $GLOBALS["ewiki_action"] = $action;
506 if (!isset($_REQUEST["content"]) && ($dquery["version"] = @$_REQUEST["version"])) {
507 $dquery["forced_version"] = $dquery["version"];
509 $data = @array_merge
($dquery, ewiki_database("GET", $dquery));
511 #-- stop here if page is not marked as _TEXT,
512 # perform authentication then, and let only administrators proceed
513 if (!empty($data["flags"]) && (($data["flags"] & EWIKI_DB_F_TYPE
) != EWIKI_DB_F_TEXT
)) {
514 if (($data["flags"] & EWIKI_DB_F_BINARY
) && ($pf = $ewiki_plugins["handler_binary"][0])) {
515 return($pf($id, $data, $action)); //_BINARY entries handled separately
517 elseif (!EWIKI_PROTECTED_MODE ||
!ewiki_auth($id, $data, $action, 0, 1) && ($ewiki_ring!=0)) {
518 return(ewiki_t("DISABLEDPAGE"));
522 #-- pre-check if actions exist
523 $pf_page = ewiki_array($ewiki_plugins["page"], $id);
525 #-- edit <form> for non-existent pages
526 if (($action==EWIKI_DEFAULT_ACTION
) && empty($data["content"]) && empty($pf_page)) {
527 if (EWIKI_AUTO_EDIT
) {
531 $data["content"] = ewiki_t("DOESNOTEXIST");
534 #-- more initialization
535 if ($pf_a = @$ewiki_plugins["page_init"]) {
537 foreach ($pf_a as $pf) {
538 $o .= $pf($id, $data, $action);
540 unset($ewiki_plugins["page_init"]);
542 $pf_page = ewiki_array($ewiki_plugins["page"], $id);
545 if (EWIKI_PROTECTED_MODE
) {
546 if (!ewiki_auth($id, $data, $action, $ring=false, $force=EWIKI_AUTO_LOGIN
)) {
547 return($o.=$ewiki_errmsg);
553 if ($pf_a = @$ewiki_plugins["handler"]) {
555 foreach ($pf_a as $pf) {
556 if ($handler_o = $pf($id, $data, $action)) { break; }
559 #-- finished by handler
563 #-- actions that also work for static and internal pages
564 elseif (($pf = @$ewiki_plugins["action_always"][$action]) && function_exists($pf)) {
565 $o .= $pf($id, $data, $action);
568 elseif ($pf_page && function_exists($pf_page)) {
569 $o .= $pf_page($id, $data, $action);
573 $pf = @$ewiki_plugins["action"][$action];
575 #-- fallback to "view" action
576 if (empty($pf) ||
!function_exists($pf)) {
578 $pf = "ewiki_page_view";
579 $action = "view"; // we could also allow different (this is a
580 // catch-all) view variants, but this would lead to some problems
583 $o .= $pf($id, $data, $action);
586 #-- error instead of page?
587 if (empty($o) && $ewiki_errmsg) {
591 #-- html post processing
592 if ($pf_a = $ewiki_plugins["page_final"]) {
594 foreach ($pf_a as $pf) {
595 if ($action == 'edit' and $pf == 'ewiki_html_tag_balancer') {
596 continue; // balancer breaks htmlarea buttons
598 $pf($o, $id, $data, $action);
602 (EWIKI_ESCAPE_AT
) && ($o = str_replace("@", "@", $o));
609 #-- HTTP meta headers
610 function ewiki_http_headers(&$o, $id, &$data, $action) {
612 if (EWIKI_HTTP_HEADERS
&& !headers_sent()) {
614 if ($uu = @$data["id"]) @header
('Content-Disposition: inline; filename="' . urlencode($uu) . '.html"');
615 if ($uu = @$data["version"]) @header
('Content-Version: ' . $uu);
616 if ($uu = @$data["lastmodified"]) @header
('Last-Modified: ' . gmstrftime($ewiki_t["C"]["DATE"], $uu));
618 if (EWIKI_NO_CACHE
) {
619 header('Expires: ' . gmstrftime($ewiki_t["C"]["DATE"], UNIX_MILLENNIUM
));
620 header('Pragma: no-cache');
621 header('Cache-Control: no-cache, private, must-revalidate');
622 # change to "C-C: cache, must-revalidate" ??
623 # private only for authenticated users / _PROT_MODE
626 if ($data["version"] && ($etag=ewiki_etag($data)) ||
($etag=md5($o))) {
627 $weak = "W/" . urlencode($id) . "." . $data["version"];
628 header("ETag: \"$etag\""); ###, \"$weak\"");
632 function ewiki_etag(&$data) {
633 return( urlencode($data["id"]) . ":" . dechex($data["version"]) . ":ewiki:" .
634 dechex(crc32($data["content"]) & 0x7FFFBFFF) );
639 #-- encloses whole page output with a descriptive <div>
640 function ewiki_page_css_container(&$o, &$id, &$data, &$action) {
641 $o = "<div class=\"wiki $action "
642 . strtr($id, ' ./ --_!"§$%&()=?²³{[]}`+#*;:,<>| @µöäüÖÄÜߤ^°«»\'\\',
643 '- -----------------------------------------------')
650 function ewiki_split_title ($id='', $split=EWIKI_SPLIT_TITLE
, $entities=1) {
651 strlen($id) or ($id = $GLOBALS["ewiki_id"]);
653 $id = preg_replace("/([".EWIKI_CHARS_L
."])([".EWIKI_CHARS_U
."]+)/", "$1 $2", $id);
655 return($entities ?
s($id) : $id);
660 function ewiki_add_title(&$html, $id, &$data, $action, $go_action="links") {
661 $html = ewiki_make_title($id, '', 1, $action, $go_action) . $html;
665 function ewiki_make_title($id='', $title='', $class=3, $action="view", $go_action="links", $may_split=1) {
667 global $ewiki_config, $ewiki_plugins, $ewiki_title, $ewiki_id;
670 if ($pf = @$ewiki_plugins["make_title"][0]) {
671 return($pf($title, $class, $action, $go_action, $may_split));
674 elseif (!$ewiki_config["print_title"]) {
684 if (!strlen($title)) {
685 $title = $ewiki_title; // already in &html; format
687 elseif ($ewiki_config["split_title"] && $may_split) {
688 $title = ewiki_split_title($title, $ewiki_config["split_title"], 0&($title!=$ewiki_title));
695 if ($pf_a = @$ewiki_plugins["title_transform"]) {
696 foreach ($pf_a as $pf) { $pf($id, $title, $go_action); }
699 #-- clickable link or simple headline
700 if ($class <= $ewiki_config["print_title"]) {
701 if ($uu = @$ewiki_config["link_title_action"][$action]) {
704 if ($uu = @$ewiki_config["link_title_url"]) {
706 unset($ewiki_config["link_title_url"]);
709 $href = ewiki_script($go_action, $id);
711 $o = '<a href="' . $href . '">' . ($title) . '</a>';
717 return('<h2 class="page title">' . $o . '</h2>'."\n");
723 function ewiki_page_view($id, &$data, $action, $all=1) {
725 global $ewiki_plugins, $ewiki_config;
728 #-- render requested wiki page <-- goal !!!
729 $render_args = array(
731 "html" => (EWIKI_ALLOW_HTML||
(@$data["flags"]&EWIKI_DB_F_HTML
)),
733 $o .= $ewiki_plugins["render"][0] ($data["content"], $render_args);
738 /// Add Moodle filters to text porion of wiki.
739 global $moodle_format; // from wiki/view.php
740 $o = format_text($o, $moodle_format);
743 #-- control line + other per-page info stuff
744 if ($pf_a = $ewiki_plugins["view_append"]) {
746 foreach ($pf_a as $n => $pf) { $o .= $pf($id, $data, $action); }
748 if ($pf_a = $ewiki_plugins["view_final"]) {
750 foreach ($pf_a as $n => $pf) { $pf($o, $id, $data, $action); }
753 if (!empty($_REQUEST["thankyou"]) && $ewiki_config["edit_thank_you"]) {
754 $o = ewiki_t("THANKSFORCONTRIBUTION") . $o;
758 if (EWIKI_HIT_COUNTING
) {
759 ewiki_database("HIT", $data);
768 #-------------------------------------------------------------------- util ---
771 /* retrieves "$id/$action" string from URL / QueryString / PathInfo,
772 change this in conjunction with ewiki_script() to customize your URLs
773 further whenever desired
775 function ewiki_id() {
776 ($id = @$_REQUEST["id"]) or
777 ($id = @$_REQUEST["name"]) or
778 ($id = @$_REQUEST["page"]) or
779 ($id = @$_REQUEST["file"]) or
780 (EWIKI_USE_PATH_INFO
) and ($id = ltrim(@$_SERVER["PATH_INFO"], "/")) or
781 (!isset($_REQUEST["id"])) and ($id = trim(strtok($_SERVER["QUERY_STRING"], "&")));
782 if (!strlen($id) ||
($id=="id=")) {
783 $id = EWIKI_PAGE_INDEX
;
785 (EWIKI_URLDECODE
) && ($id = urldecode($id));
792 /* replaces EWIKI_SCRIPT, works more sophisticated, and
793 bypasses various design flaws
794 - if only the first parameter is used (old style), it can contain
795 a complete "action/WikiPage" - but this is ambigutious
796 - else $asid is the action, and $id contains the WikiPageName
797 - $ewiki_config["script"] will now be used in favour of the constant
798 - needs more work on _BINARY, should be a separate function
800 ## MOODLE-CHANGE: $asid="", Knows the devil why....
801 function ewiki_script($asid="", $id=false, $params="", $bin=0, $html=1, $script=NULL) {
802 global $ewiki_config, $ewiki_plugins;
804 #-- get base script url from config vars
805 if (empty($script)) {
806 $script = &$ewiki_config[!$bin?
"script":"script_binary"];
810 #-- separate $action and $id for old style requests
812 if (strpos($asid, EWIKI_ACTION_SEP_CHAR
) !== false) {
813 $asid = strtok($asid, EWIKI_ACTION_SEP_CHAR
);
814 $id = strtok("\000");
823 if (is_array($params)) {
826 if ($uu) foreach ($uu as $k=>$v) {
827 $params .= (strlen($params)?
"&":"") . rawurlencode($k) . "=" . rawurlencode($v);
830 #-- action= parameter
831 if (EWIKI_USE_ACTION_PARAM
>= 2) {
832 $params = "action=$asid" . (strlen($params)?
"&":"") . $params;
836 #-- workaround slashes in $id
837 if (empty($asid) && (strpos($id, EWIKI_ACTION_SEP_CHAR
) !== false) && !$bin) {
840 /*paranoia*/ $asid = trim($asid, EWIKI_ACTION_SEP_CHAR
);
843 if (EWIKI_URLENCODE
) {
844 $id = urlencode($id);
845 $asid = urlencode($asid);
848 # only urlencode &, %, ? for example
852 $id = $asid . EWIKI_ACTION_SEP_CHAR
. $id; #= "action/PageName"
854 if (strpos($url, "%s") !== false) {
855 $url = str_replace("%s", $id, $url);
862 if (strlen($params)) {
863 $url .= (strpos($url,"?")!==false ?
"&":"?") . $params;
867 //Don't replace & if it's part of encoded character (bug 2209)
868 $url = preg_replace("/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,5};)/","&", $url);
870 //This is going to be used in some header or meta redirect, so It cannot use & (bug 2620)
871 $url = preg_replace('/&/', '&', $url);
877 /* this ewiki_script() wrapper is used to generate URLs to binary
878 content in the ewiki database
880 function ewiki_script_binary($asid, $id=false, $params=array(), $upload=0) {
882 $upload |
= is_string($params) && strlen($params) ||
count($params);
884 #-- generate URL directly to the plainly saved data file,
885 # see also plugins/binary_store
887 if (defined("EWIKI_DB_STORE_URL") && !$upload) {
888 $url = EWIKI_DB_STORE_URL
. rawurlencode($id);
891 #-- else get standard URL (thru ewiki.php) from ewiki_script()
893 $url = ewiki_script($asid, $id, $params, "_BINARY=1");
900 /* this function returns the absolute ewiki_script url, if EWIKI_SCRIPT_URL
901 is set, else it guesses the value
903 function ewiki_script_url() {
905 global $ewiki_action, $ewiki_id, $ewiki_config;
907 $scr_template = $ewiki_config["script"];
908 $scr_current = ewiki_script($ewiki_action, $ewiki_id);
909 $req_uri = $_SERVER["REQUEST_URI"];
911 if ($url = $ewiki_config["script_url"]) {
914 elseif (strpos($req_uri, $scr_current) !== false) {
915 $url = str_replace($req_uri, $scr_current, $scr_template);
917 elseif (strpos($req_uri, "?") && (strpos($scr_template, "?") !== false)) {
918 $url = substr($req_uri, 0, strpos($req_uri, "?"))
919 . substr($scr_template, strpos($scr_template, "?"));
921 elseif (strpos($req_uri, $sn = $_SERVER["SCRIPT_NAME"])) {
925 return(NULL); #-- could not guess it
928 #$url = "http://" . $_SERVER["SERVER_NAME"] . $url;
935 #------------------------------------------------------------ page plugins ---
939 function ewiki_page_links($id, &$data, $action) {
940 $o = ewiki_make_title($id, ewiki_t("PAGESLINKINGTO", array("title"=>$id)), 1, $action, "", "_MAY_SPLIT=1");
941 if ($pages = ewiki_get_backlinks($id)) {
942 $o .= ewiki_list_pages($pages);
944 $o .= ewiki_t("This page isn't linked from anywhere else.");
949 function ewiki_get_backlinks($id) {
950 $result = ewiki_database("SEARCH", array("refs" => $id));
952 while ($row = $result->get(0, 0x0020)) {
953 if ( strpos($row["refs"], "\n$id\n") !== false) {
954 $pages[] = $row["id"];
960 function ewiki_get_links($id) {
961 if ($data = ewiki_database("GET", array("id"=>$id))) {
962 $refs = explode("\n", trim($data["refs"]));
964 foreach (ewiki_database("FIND", $refs) as $id=>$exists) {
974 function ewiki_list_pages($pages=array(), $limit=EWIKI_LIST_LIMIT
,
975 $value_as_title=0, $pf_list=false)
977 global $ewiki_plugins;
980 $is_num = !empty($pages[0]);
984 foreach ($pages as $id=>$add_text) {
989 if (is_array($add_text)) {
990 list($id, $params, $title, $add_text) = $add_text;
993 $id = $title = $add_text;
996 elseif ($value_as_title) {
1001 $lines[] = '<a href="' . ewiki_script("", $id, $params) . '">' . s($title) . '</a> ' . $add_text;
1003 if (($limit > 0) && ($n++
>= $limit)) {
1008 if ($pf_a = @$ewiki_plugins["list_transform"])
1009 foreach ($pf_a as $pf_transform) {
1010 $pf_transform($lines);
1013 if (($pf_list) ||
($pf_list = @$ewiki_plugins["list_pages"][0])) {
1014 $o = $pf_list($lines);
1017 $o = "· " . implode("<br />\n· ", $lines) . "<br />\n";
1026 function ewiki_page_ordered_list($orderby="created", $asc=0, $print, $title) {
1028 $o = ewiki_make_title("", $title, 2, ".list", "links", 0);
1031 $result = ewiki_database("GETALL", array($orderby));
1033 while ($row = $result->get()) {
1034 $row = ewiki_database("GET", array(
1036 ($asc >= 0 ?
"version" : "uu") => 1 // version 1 is most accurate for {hits}
1039 if (EWIKI_DB_F_TEXT
== ($row["flags"] & EWIKI_DB_F_TYPE
)) {
1040 #-- viewing allowed?
1041 if (!EWIKI_PROTECTED_MODE ||
!EWIKI_PROTECTED_MODE_HIDING ||
ewiki_auth($row["id"], $row, "view")) {
1042 $sorted[$row["id"]] = $row[$orderby];
1047 if ($asc != 0) { arsort($sorted); }
1048 else { asort($sorted); }
1050 foreach ($sorted as $name => $value) {
1051 if (empty($value)) { $value = "0"; }
1052 ##### BEGIN MOODLE ADDITION #####
1053 #$sorted[$name] = strftime(str_replace('%n', $value, $print), $value);
1054 if($print=="LASTCHANGED") {
1055 $value=strftime("%c",$value);
1057 $sorted[$name] = get_string(strtolower($print),"wiki",$value);
1058 ##### BEGIN MOODLE ADDITION #####
1060 $o .= ewiki_list_pages($sorted);
1067 function ewiki_page_newest($id=0, $data=0) {
1068 return( ewiki_page_ordered_list("created", 1, "LASTCHANGED", ewiki_t("NEWESTPAGES")) );
1071 function ewiki_page_updates($id=0, $data=0) {
1072 return( ewiki_page_ordered_list("lastmodified", -1, "LASTCHANGED", EWIKI_PAGE_UPDATES
) );
1075 function ewiki_page_hits($id=0, $data=0) {
1076 ##### BEGIN MOODLE ADDITION #####
1077 return( ewiki_page_ordered_list("hits", 1, "hits", EWIKI_PAGE_HITS
) );
1080 function ewiki_page_versions($id=0, $data=0) {
1081 return( ewiki_page_ordered_list("version", -1, "changes", EWIKI_PAGE_VERSIONS
) );
1082 ##### END MOODLE ADDITION #####
1091 function ewiki_page_search($id, &$data, $action) {
1095 $o = ewiki_make_title($id, $id, 2, $action);
1097 if (! ($q = @$_REQUEST["q"])) {
1099 $o .= '<form action="' . ewiki_script("", $id) . '" method="post">';
1100 $o .= '<fieldset class="invisiblefieldset">';
1101 $o .= '<input name="q" size="30" /><br /><br />';
1102 $o .= '<input type="submit" value="'.$id.'" />';
1103 $o .= '</fieldset>';
1109 if ($CFG->unicodedb
) {
1110 $q = preg_replace('/\s*[\W]+\s*/u', ' ', $q);
1112 $q = preg_replace('/\s*[^\w]+\s*/', ' ', $q);
1114 foreach (explode(" ", $q) as $search) {
1116 if (empty($search)) { continue; }
1118 $result = ewiki_database("SEARCH", array("content" => $search));
1120 while ($row = $result->get()) {
1122 #-- show this entry in page listings?
1123 if (EWIKI_PROTECTED_MODE
&& EWIKI_PROTECTED_MODE_HIDING
&& !ewiki_auth($row["id"], $row, "view")) {
1127 $found[] = $row["id"];
1131 $o .= ewiki_list_pages($found);
1144 function ewiki_page_info($id, &$data, $action) {
1146 global $ewiki_plugins, $ewiki_config, $ewiki_links;
1147 global $CFG, $course; // MOODLE HACK
1149 $o = ewiki_make_title($id, ewiki_t("INFOABOUTPAGE")." '{$id}'", 2, $action,"", "_MAY_SPLIT=1");
1152 "TEXT", "BIN", "DISABLED", "HTML", "READONLY", "WRITEABLE",
1153 "APPENDONLY", "SYSTEM",
1156 "version", "author", "userid", "created",
1157 "lastmodified", "refs",
1158 "flags", "meta", "content"
1161 #-- versions to show
1162 $v_start = $data["version"];
1163 if ( ($uu=@$_REQUEST[EWIKI_UP_PAGENUM
]) && ($uu<=$v_start) ) {
1166 $v_end = $v_start - $ewiki_config["list_limit"] +
1;
1167 if ( ($uu=@$_REQUEST[EWIKI_UP_PAGEEND
]) && ($uu<=$v_start) ) {
1170 $v_end = max($v_end, 1);
1173 # the very ($first) entry is rendered more verbosely than the others
1174 for ($v=$v_start,$first=1; ($v>=$v_end); $v--,$first=0) {
1176 $current = ewiki_database("GET", array("id"=>$id, "version"=>$v));
1178 if (!strlen(trim($current["id"])) ||
!$current["version"] ||
!strlen(trim($current["content"]))) {
1182 $o .= '<table class="version-info" cellpadding="2" cellspacing="1">' . "\n";
1184 #-- additional info-actions
1186 foreach ($ewiki_config["action_links"]["info"] as $thisaction=>$title)
1187 if (@$ewiki_plugins["action"][$thisaction] ||
@$ewiki_plugins["action_always"][$thisaction]) {
1188 ##### BEGIN MOODLE ADDITION #####
1190 $commands .= ' ';
1192 $commands .= '<a href="' .
1193 ewiki_script($thisaction, $id, array("version"=>$current["version"])) .
1194 '">' . get_string($title,"wiki") . '</a>';
1195 ##### END MOODLE ADDITION #####
1198 #-- print page database entry
1199 foreach($show as $i) {
1201 $value = @$current[$i];
1203 #-- show database {fields} differently
1205 continue; // MOODLE DOESN'T USE IT
1207 if ($first && $value) { foreach ($value as $n=>$d) {
1208 $str .= s("$n: $d") . "<br />\n";
1212 elseif ($value >= UNIX_MILLENNIUM
) { #-- {lastmodified}, {created}
1213 #### BEGIN MOODLE CHANGE
1214 $value=userdate($value);
1215 #$value = strftime("%c", $value);
1216 #### END MOODLE CHANGE
1218 elseif ($i == "content") {
1219 continue; // MOODLE DOESN'T CARE
1220 $value = strlen(trim($value)) . " bytes";
1221 $i = "content size";
1223 elseif ($first && ($i == "refs") && !(EWIKI_PROTECTED_MODE
&& (EWIKI_PROTECTED_MODE_HIDING
>=2))) {
1224 $a = explode("\n", trim($value));
1225 $ewiki_links = ewiki_database("FIND", $a);
1226 ewiki_merge_links($ewiki_links);
1227 foreach ($a as $n=>$link) {
1228 $a[$n] = ewiki_link_regex_callback(array("$link"), "force_noimg");
1230 $value = trim(implode(", ", $a));
1235 elseif (strpos($value, "\n") !== false) { #-- also for {refs}
1236 $value = str_replace("\n", ", ", trim($value));
1241 elseif ($i == "version") {
1242 $value = '<a href="' .
1243 ewiki_script("", $id, array("version"=>$value)) . '">' .
1244 $value . '</a> '."($commands)";
1246 elseif ($i == "flags") {
1247 continue; // MOODLE DOESN'T USE IT
1249 for ($n = 0; $n < 32; $n++
) {
1250 if ($value & (1 << $n)) {
1251 if (! ($s=$flagnames[$n])) { $s = "UU$n"; }
1257 elseif ($i == "author") {
1260 $value = preg_replace_callback("/((\w+:)?([".EWIKI_CHARS_U
."]+[".EWIKI_CHARS_L
."]+){2,}[\w\d]*)/", "ewiki_link_regex_callback", $value);
1262 elseif ($i == "userid") {
1264 if ($user = get_record('user', 'id', $value)) {
1265 if (!isset($course->id
)) {
1268 $picture = print_user_picture($user->id
, $course->id
, $user->picture
, false, true, true);
1269 $value = $picture." <a href=\"$CFG->wwwroot/user/view.php?id=$user->id&course=$course->id\">".fullname($user)."</a>";
1272 //$value = @$current['author'];
1276 ##### BEGIN MOODLE ADDITION #####
1277 $o .= '<tr class="page-'.$i.'"><td style="vertical-align:top;text-align:right;white-space: nowrap;"><b>' .ewiki_t($i). ':</b></td>' .
1278 '<td>' . $value . "</td></tr>\n";
1279 ##### END MOODLE ADDITION #####
1283 $o .= "</table><br /><br />\n";
1287 #-- page result split
1289 $o .= "<br />\n".get_string('showversions','wiki').' '.ewiki_chunked_page($action, $id, -1, $v, 1, 0, 0) . "\n <br />";
1298 function ewiki_chunked_page($action, $id, $dir=-1, $start=10, $end=1, $limit=0, $overlap=0.25, $collapse_last=0.67) {
1300 global $ewiki_config;
1302 if (empty($limit)) {
1303 $limit = $ewiki_config["list_limit"];
1306 $overlap = (int) ($limit * $overlap);
1314 $n -= $dir * $overlap;
1316 $e = $n +
$dir * ($limit +
$overlap) +
1;
1320 if ($e <= $collapse_last * $limit) {
1326 if ($e >= $collapse_last * $limit) {
1331 $o .= ($o?
" · ":"")
1332 . '<a href="'.ewiki_script($action, $id, array(EWIKI_UP_PAGENUM
=>$n, EWIKI_UP_PAGEEND
=>$e))
1333 . '">'. "$n-$e" . '</a>';
1335 if (($n=$e-1) < $end) {
1340 return('<span class="chunked-result">'. $o .'</span>');
1348 function ewiki_page_edit($id, $data, $action) {
1350 global $ewiki_links, $ewiki_author, $ewiki_plugins, $ewiki_ring, $ewiki_errmsg;
1352 $hidden_postdata = array();
1354 #-- previous version come back
1355 if (@$data["forced_version"]) {
1357 $current = ewiki_database("GET", array("id"=>$id));
1358 $data["version"] = $current["version"];
1361 unset($_REQUEST["content"]);
1362 unset($_REQUEST["version"]);
1366 if ($pf_a = @$ewiki_plugins["edit_hook"]) foreach ($pf_a as $pf) {
1367 if ($output = $pf($id, $data, $hidden_postdata)) {
1372 #-- permission checks
1373 if (isset($ewiki_ring)) {
1374 $ring = $ewiki_ring;
1378 $flags = @$data["flags"];
1379 if (!($flags & EWIKI_DB_F_WRITEABLE
)) {
1382 $edit_ring = (EWIKI_PROTECTED_MODE
>=2) ?
(2) : (NULL);
1383 if (EWIKI_PROTECTED_MODE
&& !ewiki_auth($id, $data, $action, $edit_ring, "FORCE")) {
1384 return($ewiki_errmsg);
1388 if (($flags & EWIKI_DB_F_READONLY
) and ($ring >= 2)) {
1389 return(ewiki_t("CANNOTCHANGEPAGE"));
1391 if (($flags) and (($flags & EWIKI_DB_F_TYPE
) != EWIKI_DB_F_TEXT
) and ($ring >= 1)) {
1392 return(ewiki_t("CANNOTCHANGEPAGE"));
1397 $o = ewiki_make_title($id, ewiki_t("EDITTHISPAGE").(" '{$id}'"), 2, $action, "", "_MAY_SPLIT=1");
1400 if (isset($_REQUEST["preview"])) {
1401 $o .= $ewiki_plugins["edit_preview"][0]($data);
1405 if (isset($_REQUEST["save"])) {
1408 #-- normalize to UNIX newlines
1409 $_REQUEST["content"] = str_replace("\015\012", "\012", $_REQUEST["content"]);
1410 $_REQUEST["content"] = str_replace("\015", "\012", $_REQUEST["content"]);
1412 #-- check for concurrent version saving
1414 if ((@$data["version"] >= 1) && ($data["version"] != @$_REQUEST["version"]) ||
(@$_REQUEST["version"] < 1)) {
1416 $pf = $ewiki_plugins["edit_patch"][0];
1418 if (!$pf ||
!$pf($id, $data)) {
1420 $o .= ewiki_t("ERRVERSIONSAVE") . "<br /><br />";
1426 #-- new pages` flags
1427 if (! ($set_flags = @$data["flags"] & EWIKI_DB_F_COPYMASK
)) {
1430 if (EWIKI_ALLOW_HTML
) {
1431 $set_flags |
= EWIKI_DB_F_HTML
;
1437 "version" => @$data["version"] +
1,
1438 "flags" => $set_flags,
1439 "content" => $_REQUEST["content"],
1440 "created" => ($uu=@$data["created"]) ?
$uu : time(),
1441 "meta" => ($uu=@$data["meta"]) ?
$uu : "",
1442 "hits" => ($uu=@$data["hits"]) ?
$uu : "0",
1444 ewiki_data_update($save);
1446 #-- edit storage hooks
1447 if ($pf_a = @$ewiki_plugins["edit_save"]) {
1448 foreach ($pf_a as $pf) {
1454 if (!$save ||
!ewiki_database("WRITE", $save)) {
1456 $o .= $ewiki_errmsg ?
$ewiki_errmsg : ewiki_t("ERRORSAVING");
1460 #-- prevent double saving, when ewiki_page() is re-called
1461 $_REQUEST = $_GET = $_POST = array();
1463 $o = ewiki_t("THANKSFORCONTRIBUTION") . "<br /><br />";
1464 $o .= ewiki_page($id);
1466 if (EWIKI_EDIT_REDIRECT
) {
1467 $url = ewiki_script("", $id, "thankyou=1", 0, 0, EWIKI_HTTP_HEADERS?
ewiki_script_url():0);
1469 if (EWIKI_HTTP_HEADERS
&& !headers_sent()) {
1470 header("Status: 303 Redirect for GET");
1471 header("Location: $url");
1472 #header("URI: $url");
1473 #header("Refresh: 0; URL=$url");
1476 $o .= '<meta http-equiv="Refresh" content="0; URL='.s($url).'">';
1485 // header("Reload-Location: " . ewiki_script("", $id, "", 0, 0, ewiki_script_url()) );
1490 $o .= ewiki_page_edit_form($id, $data, $hidden_postdata);
1492 #-- additional forms
1493 if ($pf_a = $ewiki_plugins["edit_form_final"]) foreach ($pf_a as $pf) {
1494 $pf($o, $id, $data, $action);
1502 function ewiki_data_update(&$data, $author="") {
1503 global $USER, $ewiki_links;
1505 #-- add backlinks entry
1506 ewiki_scan_wikiwords($data["content"], $ewiki_links, "_STRIP_EMAIL=1");
1507 $data["refs"] = "\n\n".implode("\n", array_keys($ewiki_links))."\n\n";
1508 $data["lastmodified"] = time();
1509 $data["author"] = ewiki_author($author);
1510 if (isset($USER->id
)) {
1511 $data["userid"] = $USER->id
;
1518 function ewiki_page_edit_form(&$id, &$data, &$hidden_postdata) {
1519 global $ewiki_plugins, $ewiki_config, $moodle_format;
1523 #-- previously edited, or db fetched content
1524 if (@$_REQUEST["content"] ||
@$_REQUEST["version"]) {
1526 "version" => &$_REQUEST["version"],
1527 "content" => &$_REQUEST["content"]
1531 if (empty($data["version"])) {
1532 $data["version"] = 1;
1534 @$data["content"] .= "";
1537 #-- normalize to DOS newlines
1538 $data["content"] = str_replace("\015\012", "\012", $data["content"]);
1539 $data["content"] = str_replace("\015", "\012", $data["content"]);
1540 $data["content"] = str_replace("\012", "\015\012", $data["content"]);
1542 $hidden_postdata["version"] = &$data["version"];
1544 #-- edit textarea/form
1545 // deleted name="ewiki", can not find the reference, and it's breaking xhtml
1546 $o .= ewiki_t("EDIT_FORM_1")
1547 . '<form method="post" enctype="multipart/form-data" action="'
1548 . ewiki_script("edit", $id) . '" '
1549 . ' accept-charset="'.EWIKI_CHARSET
.'">' . "\n";
1551 #-- additional POST vars
1552 foreach ($hidden_postdata as $name => $value) {
1553 $o .= '<input type="hidden" name="'.$name.'" value="'.$value.'" />'."\n";
1556 ($cols = strtok($ewiki_config["edit_box_size"], "x*/,;:")) && ($rows = strtok("x, ")) ||
($cols=70) && ($rows=15);
1557 global $ewiki_use_editor, $ewiki_editor_content;
1558 $ewiki_editor_content=1;
1559 if($ewiki_use_editor) {
1561 $usehtmleditor = can_use_html_editor();
1562 echo '<table><tr><td>';
1563 if ($usehtmleditor) { //clean and convert before editing
1564 $options = new object();
1565 $options->smiley
= false;
1566 $options->filter
= false;
1567 $oldtext = format_text(ewiki_format($data["content"]), $moodle_format, $options);
1569 $oldtext = ewiki_format($data["content"]);
1571 print_textarea($usehtmleditor, $rows, $cols, 680, 400, "content", $oldtext);
1572 echo '</td></tr></table>';
1574 if ($usehtmleditor) {
1575 use_html_editor("content");
1577 $o .= ob_get_contents();
1581 ##### END MOODLE ADDITION #####
1583 $o .= '<textarea wrap="soft" id="ewiki_content" name="content" rows="'.$rows.'" cols="'.$cols.'">'
1584 . s($data["content"]) . "</textarea>"
1585 . $GLOBALS["ewiki_t"]["C"]["EDIT_TEXTAREA_RESIZE_JS"];
1587 ##### BEGIN MOODLE ADDITION #####
1589 ##### END MOODLE ADDITION #####
1591 #-- more <input> elements before the submit button
1592 if ($pf_a = $ewiki_plugins["edit_form_insert"]) foreach ($pf_a as $pf) {
1593 $o .= $pf($id, $data, $action);
1596 ##### BEGIN MOODLE ADDITION (Cancel Editing into Button) #####
1598 . '<input type="submit" name="save" value="'. ewiki_t("SAVE") . '" />'."\n"
1599 . '<input type="submit" name="preview" value="'. ewiki_t("PREVIEW") . '" />' . "\n"
1600 . '<input type="submit" name="canceledit" value="'. ewiki_t("CANCEL_EDIT") . '" />' . "\n";
1601 # . ' <a href="'. ewiki_script("", $id) . '">' . ewiki_t("CANCEL_EDIT") . '</a>';
1602 ##### END MOODLE ADDITION #####
1604 #-- additional form elements
1605 if ($pf_a = $ewiki_plugins["edit_form_append"]) foreach ($pf_a as $pf) {
1606 $o .= $pf($id, $data, $action);
1609 $o .= "\n</div></form>\n";
1610 // . ewiki_t("EDIT_FORM_2"); // MOODLE DELETION
1612 return('<div class="edit-box">'. $o .'</div>');
1618 function ewiki_page_edit_form_final_imgupload(&$o, &$id, &$data, &$action) {
1619 if (EWIKI_SCRIPT_BINARY
&& EWIKI_UP_UPLOAD
&& EWIKI_IMAGE_MAXSIZE
) {
1620 $o .= "\n<br />\n". '<div class="image-upload">'
1622 . '"'. ewiki_script_binary("", EWIKI_IDF_INTERNAL
, "", "_UPLOAD=1") .'"'
1623 . ' method="post" enctype="multipart/form-data" target="_upload">'
1624 . '<fieldset class="invisiblefieldset">'
1625 . '<input type="hidden" name="MAX_FILE_SIZE" value="'.EWIKI_IMAGE_MAXSIZE
.'" />'
1626 . '<input type="file" name="'.EWIKI_UP_UPLOAD
.'"'
1627 . (defined("EWIKI_IMAGE_ACCEPT") ?
' accept="'.EWIKI_IMAGE_ACCEPT
.'" />' : " />")
1628 . '<input type="hidden" name="'.EWIKI_UP_BINARY
.'" value="'.EWIKI_IDF_INTERNAL
.'" />'
1629 . ' '
1630 . '<input type="submit" value="'.ewiki_t("UPLOAD_PICTURE_BUTTON").'" />'
1631 . '</fieldset></form></div>'. "\n";
1636 function ewiki_page_edit_preview(&$data) {
1637 #### BEGIN MOODLE CHANGES
1638 global $moodle_format;
1639 $preview_text=$GLOBALS["ewiki_plugins"]["render"][0]($_REQUEST["content"], 1, EWIKI_ALLOW_HTML ||
(@$data["flags"]&EWIKI_DB_F_HTML
));
1640 return( '<div class="preview">'
1642 . "<div align=\"right\">" . ewiki_t("PREVIEW") . "</div><hr noshade><br />\n"
1643 . format_text($preview_text, $moodle_format)
1644 . "<br /><br /><hr noshade><br />"
1647 #### END MOODLE CHANGES
1651 function ewiki_control_links($id, &$data, $action) {
1653 global $ewiki_plugins, $ewiki_ring, $ewiki_config;
1654 $action_links = & $ewiki_config["action_links"][$action];
1657 if (!$ewiki_config["control_line"]) {
1662 . '<div align="right" class="action-links control-links">'
1664 . "<hr noshade>" . "\n";
1666 if (@$data["forced_version"]) {
1668 $o .= '<form action="' . ewiki_script("edit", $id) . '" method="post">' .
1669 '<fieldset class="invisiblefieldset">'.
1670 '<input type="hidden" name="edit" value="old" />' .
1671 '<input type="hidden" name="version" value="'.$data["forced_version"].'" />' .
1672 '<input type="submit" value="' . ewiki_t("OLDVERCOMEBACK") . '" /></form> ';
1675 foreach ($action_links as $action => $title)
1676 if (!empty($ewiki_plugins["action"][$action]) ||
!empty($ewiki_plugins["action_always"][$action]) ||
strpos($action, ":/"))
1678 if (EWIKI_PROTECTED_MODE
&& EWIKI_PROTECTED_MODE_HIDING
&& !ewiki_auth($id, $data, $action)) { continue; }
1681 . (strpos($action, ":/") ?
$action : ewiki_script($action, $id))
1682 . '">' . ewiki_t($title) . '</a> · ';
1686 if ($data["lastmodified"] >= UNIX_MILLENNIUM
) {
1687 $o .= '<small>' . strftime(ewiki_t("LASTCHANGED"), @$data["lastmodified"]) . '</small>';
1699 # ============================================================= rendering ===
1705 ######## ### ### ######### ### ### ### #######
1706 ######## #### ### ######### ### #### ### #######
1707 ### ##### ### ### ##### ### ###
1708 ###### ######### ### #### ### ######### ######
1709 ###### ######### ### #### ### ######### ######
1710 ### ### ##### ### ### ### ### ##### ###
1711 ######## ### #### ######### ### ### #### #######
1712 ######## ### ### ######### ### ### ### #######
1716 The _format() function transforms $wiki_source pages into <html> strings,
1717 also calls various markup and helper plugins during the transformation
1718 process. The $params array can activate various features and extensions.
1719 only accepts UNIX newlines!
1721 function ewiki_format (
1726 global $ewiki_links, $ewiki_plugins, $ewiki_config;
1729 $params = @array_merge
($ewiki_config["format_params"], $params);
1731 "in" => 0, # current input $iii[] block array index
1734 "post" => "", # string to append after current line/paragraph
1737 "list" => "", # lists
1738 "tbl" => 0, # open table?
1739 "indent" => 0, # indentation
1744 $line = &$s["line"];
1745 $lines = &$s["lines"];
1746 $para = &$s["para"];
1747 $post = &$s["post"];
1748 $list = &$s["list"];
1750 #-- input and output arrays
1751 if ($wiki_source[0] == "<") { # also prepend an empty line
1752 $wiki_source = "\n" . $wiki_source; # for faster strpos() searchs
1756 0 => $wiki_source."\n", # body + empty line
1757 1 => 0x0FFF, # flags (0x1=WikiMarkup, 0x2=WikiLinks, 0x100=BlockPlugins)
1758 2 => "core", # block plugin name
1763 unset($wiki_source);
1766 $pf_tbl = @$ewiki_plugins["format_table"][0];
1767 $pf_line = @$ewiki_plugins["format_line"];
1770 $htmlentities = $ewiki_config["htmlentities"];
1771 $wm_indent = &$ewiki_config["wm_indent"];
1772 $wm_table_defaults = &$ewiki_config["wm_table_defaults"];
1773 $wm_source = &$ewiki_config["wm_source"];
1774 $wm_list = &$ewiki_config["wm_list"];
1775 $wm_list_chars = implode("", array_keys($wm_list));
1776 $wm_style = &$ewiki_config["wm_style"];
1777 $wm_start_end = &$ewiki_config["wm_start_end"];
1780 $iii[0][0] = strtr($iii[0][0], $htmlentities);
1781 unset($htmlentities["&"]);
1783 #-- pre-processing plugins (working on wiki source)
1784 if ($pf_source = $ewiki_plugins["format_source"]) {
1785 foreach ($pf_source as $pf) $pf($iii[0][0]);
1789 $iii[0][0] = strtr($iii[0][0], $wm_source);
1791 #-- separate input into blocks ------------------------------------------
1792 foreach ($ewiki_config["format_block"] as $btype => $binfo) {
1794 #-- disabled block plugin?
1795 if ($binfo[2] && !$params[$binfo[2]]) {
1801 while ((++
$in) < count($iii)) {
1803 #-- search fragment delimeters
1804 if ($iii[$in][1] & 0x0100)
1806 ($c = & $iii[$in][0]) &&
1807 (($l = strpos($c, $binfo[0])) !== false) &&
1808 ($r = strpos($c, $binfo[1], $l)) )
1810 $l_len = strlen($binfo[0]);
1811 $r_len = strlen($binfo[1]);
1815 if (($l > 0) && trim($text = substr($c, 0, $l))) {
1816 $repl[] = array($text, 0xFFFF, "core");
1818 // the extracted part
1819 if (trim($text = substr($c, $l+
$l_len, $r-$l-$r_len))) {
1820 $repl[] = array($text, $binfo[3], "$btype");
1823 if (($r+
$r_len < strlen($c)) && trim($text = substr($c, $r+
$r_len))) {
1824 $repl[] = array($text, 0xFFFF, "core");
1826 array_splice($iii, $in, 1, $repl);
1833 #-- run format_block plugins
1835 while ((++
$in) < count($iii)) {
1836 if (($btype = $iii[$in][2]) && ($pf_a = $ewiki_plugins["format_block"][$btype])) {
1838 foreach ($pf_a as $pf) {
1839 # current buffer $c and pointer $in into $iii[] and state $s
1840 $pf($c, $in, $iii, $s, $btype);
1845 #-- wiki markup ------------------------------------------------------
1848 while ((++
$in) < count($iii)) {
1850 if ($iii[$in][1] & 0x0001) {
1852 #-- input $lines buffer, and output buffer $ooo array
1853 $lines = explode("\n", $iii[$in][0]);
1858 $out = &$ooo[$in][0];
1859 $s["block"] = ($iii[$in][2] != "core"); # disables indentation & paragraphs
1861 #-- walk through wiki source lines
1862 $line_max = count($lines);
1863 foreach ($lines as $s["line_i"]=>$line) {
1864 //echo "<pre>line={$s[line_i]}:".htmlspecialchars($line).":".htmlspecialchars($line[0])."</pre>";
1866 #-- empty lines separate paragraphs
1867 if (!strlen($line)) {
1868 ewiki_format_close_para($ooo, $s);
1869 ewiki_format_close_tags($ooo, $s);
1875 if (!strncmp($line, "----", 4)) {
1876 $out .= "<hr noshade>\n";
1880 #if (!strncmp($line, "<!--", 7)) {
1881 # $out .= "<!-- " . htmlentities(str_replace("--", "__", substr($line, 7))) . " -->\n";
1889 ### MOODLE CHANGE: TRIM
1890 if (($c0 == "|") && ($line[strlen(trim($line))-1] == "|")) {
1892 ewiki_format_close_para($ooo, $s);
1893 ewiki_format_close_tags($ooo, $s);
1896 $line = substr($line, 1, -1);
1898 $pf_tbl($line, $ooo, $s);
1902 $out .= "<table " . $wm_table_defaults . ">\n";
1903 $s["close"][] = "\n</table>";
1905 $line = "<tr>\n<td>" . str_replace("|", "</td>\n<td>", $line) . "</td>\n</tr>";
1910 elseif ($s["tbl"]) {
1916 if (($c0 == "!") && ($excl = strspn($line, "!"))) {
1920 $line = substr($line, $excl);
1922 $line = "<h$excl>" . $line . "</h$excl>";
1924 ewiki_format_close_para($ooo, $s);
1926 ewiki_format_close_tags($ooo, $s);
1930 #-- whole-line markup
1934 #-- indentation (space/tab markup)
1936 if (!$list && (!$s["block"]) && ($n_indent = strspn($line, " "))) {
1937 $n_indent = (int) ($n_indent / 2.65);
1938 while ($n_indent > $s["indent"]) {
1943 while ($n_indent < $s["indent"]) {
1949 #-- text style triggers
1950 foreach ($wm_style as $find=>$replace) {
1951 $find_len = strlen($find);
1953 while(($loop--) && (($l = strpos($line, $find)) !== false) && ($r = strpos($line, $find, $l +
$find_len))) {
1954 $line = substr($line, 0, $l) . $replace[0] .
1955 substr($line, $l +
strlen($find), $r - $l - $find_len) .
1956 $replace[1] . substr($line, $r +
$find_len);
1962 if (isset($wm_list[$c0])) {
1964 ewiki_format_close_para($ooo, $s);
1965 ewiki_format_close_tags($ooo, $s);
1967 $new_len = strspn($line, $wm_list_chars);
1968 $new_list = substr($line, 0, $new_len);
1969 $old_len = strlen($list);
1970 $lchar = $new_list[$new_len-1];
1971 list($lopen, $ltag1, $ltag2) = $wm_list[$lchar];
1974 $line = substr($line, $new_len);
1978 $linsert = "<$ltag1>" . strtok($line, $lchar) . "</$ltag1> ";
1979 $line = strtok("\000");
1982 #-- add another <li>st entry
1983 if ($new_len == $old_len) {
1984 $lspace = str_repeat(" ", $new_len);
1985 $out .= "</$ltag2>\n" . $lspace . $linsert . "<$ltag2>";
1988 elseif ($new_len > $old_len) {
1989 while ($new_len > ($old_len=strlen($list))) {
1990 $lchar = $new_list[$old_len];
1992 list($lopen, $ltag1, $ltag2) = $wm_list[$lchar];
1993 $lclose = strtok($lopen, " ");
1994 $lspace = str_repeat(" ", $new_len);
1996 $out .= "\n$lspace<$lopen>\n" . "$lspace". $linsert . "<$ltag2>";
1997 $s["close"][] = "$lspace</$lclose>";
1998 $s["close"][] = "$lspace</$ltag2>";
2003 while ($new_len < ($old_len=strlen($list))) {
2004 $remove = $old_len-$new_len;
2005 ewiki_format_close_tags($ooo, $s, 2*$remove);
2006 $list = substr($list, 0, -$remove);
2009 $lspace = str_repeat(" ", $new_len);
2010 $out .= "$lspace</$ltag2>\n" . $lspace . $linsert . "<$ltag2>";
2022 ewiki_format_close_tags($ooo, $s);
2028 #-- start-end markup
2029 foreach ($wm_start_end as $d) {
2030 $len0 = strlen($d[0]);
2032 while(($loop--) && (($l = strpos($line, $d[0])) !== false) && ($r = strpos($line, $d[1], $l +
$len0))) {
2033 $len1 = strlen($d[1]);
2034 $line = substr($line, 0, $l) . $d[2] .
2035 substr($line, $l +
$len0, $r - $l - $len0) .
2036 $replace[1] . substr($line, $r +
$len1);
2040 #-- call wiki source formatting plugins that work on current line
2042 foreach ($pf_line as $pf) $pf($out, $line, $post);
2047 #-- add formatted line to page-output
2049 if ($para === false) {
2054 $para .= $line . "\n";
2059 #-- last block, or next not WikiSource?
2060 if (!isset($iii[$in+
1]) ||
!($iii[$in+
1][1] & 0x0011)) {
2061 ewiki_format_close_para($ooo, $s);
2062 ewiki_format_close_tags($ooo, $s);
2065 #-- copy as is into output buffer
2067 $ooo[$in] = $iii[$in];
2069 $iii[$in] = array();
2072 #-- wiki linking ------------------------------------------------------
2074 for ($in=0; $in<count($ooo); $in++
) {
2075 if (EWIKI_HTML_CHARS
&& ($ooo[$in][1] & 0x0004)) { # html character entities
2076 $ooo[$in][0] = str_replace("&#", "&#", $ooo[$in][0]);
2078 if ($ooo[$in][1] & 0x0022) {
2079 #-- join together multiple WikiSource blocks
2080 while (isset($ooo[$in+
1]) && ($ooo[$in][1] & 0x0002) && ($ooo[$in+
1][1] & 0x0002)) {
2082 0 => $ooo[$in][0] . "\n" . $ooo[$in+
1][0],
2083 1 => $ooo[$in][1] |
$ooo[$in+
1][1],
2085 array_splice($ooo, $in+
1, 1);
2088 $scan_src .= $ooo[$in][0];
2093 if (1+
$params["scan_links"]) {
2094 ewiki_scan_wikiwords($scan_src, $ewiki_links);
2096 if ($pf_linkprep = $ewiki_plugins["format_prepare_linking"]) {
2097 foreach ($pf_linkprep as $pf) $pf($scan_src);
2101 #-- finally the link-detection-regex
2102 for ($in=0; $in<count($ooo); $in++
) {
2103 if ($ooo[$in][1] & 0x0002) {
2104 ##### BEGIN MOODLE ADDITION #####
2105 # No WikiLinks in Editor
2106 #################################
2107 global $ewiki_use_editor, $ewiki_editor_content;
2108 if(!($ewiki_use_editor && $ewiki_editor_content)) {
2109 ##### END MOODLE ADDITION #####
2110 ewiki_render_wiki_links($ooo[$in][0]);
2111 ##### BEGIN MOODLE ADDITION #####
2113 ##### END MOODLE ADDITION #####
2117 #-- fin: combine all blocks into html string ----------------------------
2119 for ($in=0; $in<count($ooo); $in++
) {
2120 $html .= $ooo[$in][0] . "\n";
2123 #-- call post processing plugins
2124 if ($pf_final = $ewiki_plugins["format_final"]) {
2125 foreach ($pf_final as $pf) $pf($html);
2132 function ewiki_format_close_para(&$ooo, &$s) {
2133 $out = &$ooo[$s["in"]][0];
2134 #-- output text block
2135 if (trim($s["para"])) {
2138 global $ewiki_use_editor;
2139 if(!$ewiki_use_editor) {
2140 $s["para"] = "\n<p>\n" . ltrim($s["para"], "\n") . "</p>\n";
2144 #-- paragraph formation plugins
2145 if ($pf_a = $GLOBALS["ewiki_plugins"]["format_para"]) {
2146 foreach ($pf_a as $pf) {
2147 $pf($s["para"], $ooo, $s);
2154 while ($s["indent"]) {
2161 function ewiki_format_close_tags(&$ooo, &$s, $count=100) {
2162 $out = &$ooo[$s["in"]][0];
2163 if (!is_array($s) ||
!is_array($s["close"])) {
2164 die("\$s is garbaged == $s!!");
2166 while (($count--) && ($add = array_pop($s["close"]))) {
2167 $out .= $add . "\n";
2172 function ewiki_format_pre(&$str, &$in, &$iii, &$s, $btype) {
2173 $str = "<pre class=\"markup $btype\">" . $str . "</pre>";
2177 function ewiki_format_html(&$str, &$in, &$iii, &$s) {
2178 $he = array_reverse($GLOBALS["ewiki_config"]["htmlentities"]);
2179 $str = strtr($str, array_flip($he));
2180 $str = "<span class=\"markup html\">" . $str . "\n</span>\n";
2184 function ewiki_format_comment(&$str, &$in, &$iii, &$s, $btype) {
2185 $str = "<!-- " . str_replace("--", "¯¯", $str) . " -->";
2191 /* unclean pre-scanning for WikiWords in a page,
2192 pre-query to the db */
2193 function ewiki_scan_wikiwords(&$wiki_source, &$ewiki_links, $se=0) {
2195 global $ewiki_config;
2198 preg_match_all($ewiki_config["wiki_pre_scan_regex"], $wiki_source, $uu);
2199 $uu = @array_merge
($uu[1], $uu[2], $uu[3], $uu[4], (array)@$uu[5]);
2201 #-- clean up list, trim() spaces (allows more unclean regex) - page id unification
2202 foreach ($uu as $i=>$id) {
2203 $uu[$i] = trim($id);
2206 $uu = array_unique($uu);
2209 $ewiki_links = ewiki_database("FIND", $uu);
2211 #-- strip email adresses
2213 foreach ($ewiki_links as $c=>$uu) {
2214 if (strpos($c, "@") && (strpos($c, ".") ||
strpos($c, ":"))) {
2215 unset($ewiki_links[$c]);
2224 /* regex on page content,
2225 handled by callback (see below)
2227 function ewiki_render_wiki_links(&$o) {
2229 global $ewiki_links, $ewiki_config, $ewiki_plugins;
2231 #-- merge with dynamic pages list
2232 ewiki_merge_links($ewiki_links);
2234 #-- replace WikiWords
2235 $link_regex = &$ewiki_config["wiki_link_regex"];
2236 $o = preg_replace_callback($link_regex, "ewiki_link_regex_callback", $o);
2239 unset($ewiki_links);
2244 combines with page plugin list,
2245 and makes all case-insensitive
2247 function ewiki_merge_links(&$ewiki_links) {
2248 global $ewiki_plugins;
2249 #### BEGIN MOODLE CHANGES
2250 global $ewiki_link_case;
2251 $ewiki_link_case=array();
2252 #### END MOODLE CHANGES
2253 if ($ewiki_links !== true) {
2254 foreach ($ewiki_plugins["page"] as $page=>$uu) {
2255 $ewiki_links[$page] = 1;
2257 #### BEGIN MOODLE CHANGES
2258 foreach($ewiki_links as $page => $uu) {
2260 $ewiki_link_case[strtolower($page)]=$page;
2263 #### END MOODLE CHANGES
2264 $ewiki_links = ewiki_array($ewiki_links);
2271 /* link rendering (p)regex callback
2272 (ooutch, this is a complicated one)
2274 function ewiki_link_regex_callback($uu, $force_noimg=0) {
2275 #print "<pre>"; print_r($uu); print "</pre>";
2276 global $ewiki_links, $ewiki_plugins, $ewiki_config, $ewiki_id;
2278 $str = trim($uu[0]);
2282 #-- link bracket '[' escaped with '!' or '~'
2283 if (($str[0] == "!") ||
($str[0] == "~")) {
2284 return(substr($str, 1));
2286 if ($str[0] == "#") {
2287 $states["define"] = 1;
2288 $str = substr($str, 1);
2290 if ($str[0] == "[") {
2291 $states["brackets"] = 1;
2292 $str = substr($str, 1, -1);
2295 #-- explicit title given via [ title | WikiLink ]
2296 $href = $title = strtok($str, "|");
2297 if ($uu = strtok("|")) {
2299 $states["titled"] = 1;
2301 #-- title and href swapped: swap back
2302 if (strpos("://", $title) ||
strpos($title, ":") && !strpos($href, ":")) {
2303 $uu = $title; $title = $href; $href = $uu;
2306 #-- new entitling scheme [ url "title" ]
2307 if ((($l=strpos($str, '"')) < ($r=strrpos($str, '"'))) && ($l!==false) ) {
2308 $title = substr($str, $l +
1, $r - $l - 1);
2309 $href = substr($str, 0, $l) . substr($str, $r +
1);
2310 $states["titled"] = 1;
2314 $spaces_l = ($href[0]==" ") ?
1:0;
2315 $spaces_r = ($href[strlen($href)-1]==" ") ?
1:0;
2316 $title = ltrim(trim($title), "^");
2317 $href = ltrim(trim($href), "^");
2319 #-- strip_htmlentities()
2320 if (1&& (strpos($href, "&")!==false) && strpos($href, ";")) {
2321 foreach (array("<"=>"<", ">"=>">", "&"=>"&") as $f=>$t) {
2322 $href = str_replace($f, $t, $href);
2328 if (($p = strrpos($href, "#")) && ($p) && ($href[$p-1] != "&")) {
2329 $href2 = trim(substr($href, $p));
2330 $href = trim(substr($href, 0, $p));
2333 $states["define"] = 1;
2339 #-- for case-insensitivines
2340 $href_i = EWIKI_CASE_INSENSITIVE ?
strtolower($href) : ($href);
2343 if (strpos($inj_url = $ewiki_links[$href_i], "://")) {
2344 if ($href==$title) { $href = $inj_url; }
2348 if (strpos($href, ":") && ($uu = ewiki_interwiki($href, $type))) {
2350 $str = "<a href=\"$href$href2\">$title</a>";
2352 #-- action:WikiLinks
2353 elseif ($ewiki_plugins["action"][$a=strtolower(strtok($href, ":"))]) {
2354 $type = array($a, "action", "wikipage");
2355 $str = '<a href="' . ewiki_script($a, strtok("\000")) . '">' . $title . '</a>';
2357 #-- page anchor definitions, if ($href[0]=="#")
2358 elseif (@$states["define"]) {
2359 $type = array("anchor");
2360 if ($title==$href) { $title=" "; }
2361 $str = '<a name="' . s(ltrim($href, "#")) . '">' . ltrim($title, "#") . '</a>';
2363 #-- inner page anchor jumps
2364 elseif (strlen($href2) && ($href==$ewiki_id) ||
($href[0]=="#") && ($href2=&$href)) {
2365 $type = array("jump");
2366 $str = '<a href="' . s($href2) . '">' . $title . '</a>';
2368 #-- ordinary internal WikiLinks
2369 elseif (($ewiki_links === true) ||
@$ewiki_links[$href_i]) {
2370 $type = array("wikipage");
2371 #### BEGIN MOODLE CHANGES
2372 global $ewiki_link_case;
2373 $href_realcase=array_key_exists($href_i,$ewiki_link_case) ?
$ewiki_link_case[$href_i] : $href;
2374 $str = '<a href="' . ewiki_script("", $href_realcase) . s($href2)
2375 . '">' . $title . '</a>';
2376 #### END MOODLE CHANGES
2378 #-- guess for mail@addresses, convert to URI if
2379 elseif (strpos($href, "@") && !strpos($href, ":")) {
2380 $type = array("email");
2381 $href = "mailto:" . $href;
2383 #-- not found fallback
2386 #-- a plugin may take care
2387 if ($pf_a = $ewiki_plugins["link_notfound"]) {
2388 foreach ($pf_a as $pf) {
2389 if ($str = $pf($title, $href, $href2, $type)) {
2394 #-- (QuestionMarkLink to edit/ action)
2396 $type = array("notfound");
2397 $str = '<span class="NotFound"><b>' . $title . '</b><a href="' .
2398 ewiki_script("", $href) . '">?</a></span>';
2402 #-- convert standard URLs
2403 foreach ($ewiki_config["idf"]["url"] as $find)
2404 if (strpos($href, $find)===0) {
2406 $type[-1] = strtok($find, ":");
2409 if ($pf_a = $ewiki_plugins["link_url"]) foreach ($pf_a as $pf) {
2410 if ($str = $pf($href, $title)) { break 2; }
2412 $meta = @$ewiki_links[$href];
2414 #-- check for image files
2415 $ext = substr($href, strrpos($href,"."));
2416 $nocache = strpos($ext, "no");
2417 $ext = strtok($ext, "?&#");
2418 $obj = in_array($ext, $ewiki_config["idf"]["obj"]);
2419 $img = $obj ||
in_array($ext, $ewiki_config["idf"]["img"]);
2421 #-- internal:// references (binary files)
2422 if (EWIKI_SCRIPT_BINARY
&& ((strpos($href, EWIKI_IDF_INTERNAL
)===0) ||
2423 EWIKI_IMAGE_MAXSIZE
&& EWIKI_CACHE_IMAGES
&& $img && !$nocache) )
2425 $type = array("binary");
2426 $href = ewiki_script_binary("", $href);
2429 #-- output html reference
2430 if (!$img ||
$force_noimg ||
!$states["brackets"] ||
(strpos($href, EWIKI_IDF_INTERNAL
) === 0)) {
2431 $str = '<a href="' . $href . '">' . $title . '</a>';
2435 if (is_string($meta)) {
2436 $meta = unserialize($meta);
2438 $type = array("image");
2439 #-- uploaded images size
2440 $x = $meta["width"];
2441 $y = $meta["height"];
2442 if ($p = strpos('?', $href)) { #-- width/height given in url
2443 parse_str(str_replace("&", "&", substr($href, $p)), $meta);
2444 ($uu = $meta["x"] . $meta["width"]) and ($x = $uu);
2445 ($uu = $meta["y"] . $meta["height"]) and ($y = $uu);
2446 if ($scale = $meta["r"] . $meta["scale"]) {
2447 ($p = strpos($scale, "%")) and ($scale = strpos($scale, 0, $p) / 100);
2448 $x *= $scale; $y *= $scale;
2451 $align = array('', ' align="right"', ' align="left"', ' align="center"');
2452 $align = $align[$spaces_l +
2*$spaces_r];
2453 $str = ($obj ?
'<embed width="70%"' : '<img') . ' src="' . $href . '"' .
2454 ' alt="' . ($title) . '"' .
2455 (@$states["titled"] ?
' title="' . ($title) . '"' : '').
2456 ($x && $y ?
" width=\"$x\" height=\"$y\"" : "") .
2457 $align . " />" . ($obj ?
"</embed>" : "");
2458 # htmlentities($title)
2464 #-- icon/transform plugins
2466 if ($pf_a = @$ewiki_plugins["link_final"]) {
2467 foreach ($pf_a as $pf) { $pf($str, $type, $href, $title); }
2475 Returns URL if it encounters an InterWiki:Link or workalike.
2477 function ewiki_interwiki($href, &$type) {
2478 global $ewiki_config, $ewiki_plugins;
2480 if (strpos($href, ":") and !strpos($href, "//")
2481 and ($p1 = strtok($href, ":"))) {
2483 $page = strtok("\000");
2485 if (($p1 = ewiki_array($ewiki_config["interwiki"], $p1)) !== NULL) {
2486 $type = array("interwiki", $uu);
2487 while ($p1_alias = $ewiki_config["interwiki"][$p1]) {
2491 if (!strpos($p1, "%s")) {
2494 $href = str_replace("%s", $page, $p1);
2497 elseif ($pf = $ewiki_plugins["intermap"][$p1]) {
2498 return($pf($p1, $page));
2505 implements FeatureWiki:InterMapWalking
2507 function ewiki_intermap_walking($id, &$data, $action) {
2508 if (empty($data["version"]) && ($href = ewiki_interwiki($id, $uu))) {
2509 header("Location: $href");
2510 return("<a href=\"$href\">$href</a>");
2516 # =========================================================================
2520 ##### ## ## ## ## ##### ## ##
2521 ###### ## ### ## #### ###### ## ##
2522 ## ## ## ### ## ###### ## ## ## ##
2523 ##### ## #### ## ## ## ###### ######
2524 ##### ## ####### ###### #### ####
2525 ## ### ## ## #### ###### ##### ##
2526 ## ### ## ## ### ## ## ## ### ##
2527 ###### ## ## ### ## ## ## ## ##
2528 ###### ## ## ## ## ## ## ## ##
2535 function ewiki_binary($break=0) {
2536 global $ewiki_plugins;
2537 global $USER; // MOODLE
2540 if (!strlen($id = @$_REQUEST[EWIKI_UP_BINARY
]) ||
!EWIKI_IDF_INTERNAL
) {
2543 if (headers_sent()) die("ewiki-binary configuration error");
2546 $upload_file = @$_FILES[EWIKI_UP_UPLOAD
];
2547 $add_meta = array();
2548 if ($orig_name = @$upload_file["name"]) {
2549 $add_meta["Content-Location"] = urlencode($orig_name);
2550 $add_meta["Content-Disposition"] = 'inline; filename="'.urlencode(basename("remote://$orig_name")).'"';
2553 #-- what are we doing here?
2554 if (($id == EWIKI_IDF_INTERNAL
) && ($upload_file)) {
2558 $data = ewiki_database("GET", array("id" => $id));
2559 $flags = @$data["flags"];
2560 if (EWIKI_DB_F_BINARY
== ($flags & EWIKI_DB_F_TYPE
)) {
2563 elseif (empty($data["version"]) and EWIKI_CACHE_IMAGES
) {
2571 #-- auth only happens when enforced with _PROTECTED_MODE_XXL setting
2572 # (authentication for inline images in violation of the WWW spirit)
2573 if ((EWIKI_PROTECTED_MODE
>=5) && !ewiki_auth($id, $data, "binary-{$do}")) {
2574 return($_REQUEST["id"]="view/BinaryPermissionError");
2578 if ($do == "upload"){
2579 $id = ewiki_binary_save_image($upload_file["tmp_name"], "", $return=0, $add_meta);
2580 @unlink
($upload_file["tmp_name"]);
2581 ($title = trim($orig_name, "/")) && ($title = preg_replace("/[^-._\w\d]+/", "_", substr(substr($orig_name, strrpos($title, "/")), 0, 20)))
2582 && ($title = '"'.$title.'"') ||
($title="");
2586 <html><head><title>File/Picture Upload</title><script type="text/javascript"><!--
2587 opener.document.forms["ewiki"].elements["content"].value += "\\nUPLOADED PICTURE: [$id$title]\\n";
2588 window.setTimeout("self.close()", 5000);
2589 //--></script></head><body bgcolor="#440707" text="#FFFFFF">Your uploaded file was saved as<br /><big><b>
2591 </b></big>.<br /><br /><noscript>Please copy this ↑ 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>
2596 #-- request for contents from the db
2597 elseif ($do == "get") {
2598 #### CHANGED FOR MOODLE
2599 if (EWIKI_HIT_COUNTING
) {
2601 ewiki_database("HIT", $tmp);
2603 #### CHANGED FOR MOODLE
2605 #-- send http_headers from meta
2606 if (is_array($data["meta"])) {
2607 foreach ($data["meta"] as $hdr=>$val) {
2608 if (($hdr[0] >= "A") && ($hdr[0] <= "Z")) {
2609 header("$hdr: $val");
2614 #-- fetch from binary store
2615 if ($pf_a = $ewiki_plugins["binary_get"]) {
2616 #### CHANGED FOR MOODLE
2617 foreach ($pf_a as $pf) { $pf($id, $data["meta"]); }
2619 #### END CHANGED FOR MOODLE
2623 echo $data["content"];
2626 #-- fetch & cache requested URL,
2627 elseif ($do == "cache") {
2629 #-- check for standard protocol names, to prevent us from serving
2630 # evil requests for '/etc/passwd.jpeg' or '../.htaccess.gif'
2631 if (preg_match('@^\w?(http|ftp|https|ftps|sftp)\w?://@', $id)) {
2633 #-- generate local copy
2634 $filename = tempnam(EWIKI_TMP
, "ewiki.local.temp.");
2635 if (($i = fopen($id, "rb")) && ($o = fopen($filename, "wb"))) {
2638 fwrite($o, fread($i, 65536));
2645 "Content-Location" => urlencode($id),
2646 "Content-Disposition" => 'inline; filename="'.urlencode(basename($id)).'"'
2649 $result = ewiki_binary_save_image($filename, $id, "RETURN", $add_meta);
2654 if ($result && !$break) {
2655 ewiki_binary($break=1);
2657 #-- mark URL as unavailable
2662 "flags" => EWIKI_DB_F_DISABLED
,
2663 "lastmodified" => time(),
2664 "created" => time(),
2665 "author" => ewiki_author("ewiki_binary_cache"),
2666 "userid" => $USER->id
,
2668 "meta" => array("Status"=>"404 Absent"),
2670 ewiki_database("WRITE", $data);
2671 header("Location: $id");
2672 ewiki_log("imgcache: did not find '$id', and marked it now in database as DISABLED", 2);
2677 #-- "we don't sell this!"
2679 if (strpos($id, EWIKI_IDF_INTERNAL
) === false) {
2680 header("Status: 301 Located SomeWhere Else");
2681 header("Location: $id");
2684 header("Status: 404 Absent");
2685 header("X-Broken-URI: $id");
2689 // you should not remove this one, it is really a good idea to use it!
2698 function ewiki_binary_save_image($filename, $id="", $return=0,
2699 $add_meta=array(), $accept_all=EWIKI_ACCEPT_BINARY
, $care_for_images=1)
2701 global $ewiki_plugins;
2702 global $USER; // MOODLE
2704 #-- break on empty files
2705 if (!filesize($filename)) {
2709 #-- check for image type and size
2710 $mime_types = array(
2711 "application/octet-stream",
2715 "application/x-shockwave-flash"
2718 "bin", "gif", "jpeg", "png", "swf"
2720 list($width, $height, $mime_i, $uu) = getimagesize($filename);
2721 (!$mime_i) && ($mime_i=0) ||
($mime = $mime_types[$mime_i]);
2724 if ($care_for_images) {
2727 if (!$mime_i && !$accept_all ||
!filesize($filename)) {
2728 ewiki_die(ewiki_t("BIN_NOIMG"), $return);
2733 if (strpos($mime,"image/")!==false) {
2734 if ($pf_a = $ewiki_plugins["image_resize"]) {
2735 foreach ($pf_a as $pf) {
2736 if (EWIKI_IMAGE_RESIZE
&& (filesize($filename) > EWIKI_IMAGE_MAXSIZE
)) {
2737 $pf($filename, $mime, $return);
2741 #-- reject image if too large
2742 if (strlen($content) > EWIKI_IMAGE_MAXSIZE
) {
2743 ewiki_die(ewiki_t("BIN_IMGTOOLARGE"), $return);
2747 #-- again check mime type and image sizes
2748 list($width, $height, $mime_i, $uu) = getimagesize($filename);
2749 (!$mime_i) && ($mime_i=0) ||
($mime = $mime_types[$mime_i]);
2752 ($ext = $ext_types[$mime_i]) or ($ext = $ext_types[0]);
2755 if ((!$mime_i) && ($pf = $ewiki_plugins["mime_magic"][0])) {
2756 if ($tmp = $pf($content)) {
2760 if (!strlen($mime)) {
2761 $mime = $mime_types[0];
2764 #-- store size of binary file
2765 $add_meta["size"] = filesize($filename);
2768 #-- handler for (large/) binary content?
2769 if ($pf_a = $ewiki_plugins["binary_store"]) {
2770 foreach ($pf_a as $pf) {
2771 $pf($filename, $id, $add_meta, $ext);
2775 #-- read file into memory (2MB), to store it into the database
2777 $f = fopen($filename, "rb");
2778 $content = fread($f, 1<<21);
2782 #-- generate db file name
2784 $md5sum = md5($content);
2785 $id = EWIKI_IDF_INTERNAL
. $md5sum . ".$ext";
2786 ewiki_log("generated md5sum '$md5sum' from file content");
2789 #-- prepare meta data
2790 $meta = @array_merge
(array(
2791 "class" => $mime_i ?
"image" : "file",
2792 "Content-Type" => $mime,
2793 "Pragma" => "cache",
2796 $meta["width"] = $width;
2797 $meta["height"] = $height;
2804 "author" => ewiki_author(),
2805 "userid" => $USER->id
,
2806 "flags" => EWIKI_DB_F_BINARY | EWIKI_DB_F_READONLY
,
2807 "created" => time(),
2808 "lastmodified" => time(),
2810 "content" => &$content,
2813 #-- write if not exist
2814 $exists = ewiki_database("FIND", array($id));
2815 if (! $exists[$id] ) {
2816 $result = ewiki_database("WRITE", $data);
2817 ewiki_log("saving of '$id': " . ($result ?
"ok" : "error"));
2820 ewiki_log("binary_save_image: '$id' was already in the database", 2);
2829 # =========================================================================
2832 #### #### #### ######## ########
2833 ##### ##### #### ########## ##########
2834 ###### ###### #### #### ### #### ###
2835 ############# #### ####
2836 ############# #### ######## ####
2837 #### ### #### #### ######## ####
2838 #### # #### #### #### ####
2839 #### #### #### ### #### #### ###
2840 #### #### #### ######### ##########
2841 #### #### #### ####### ########
2845 /* yes! it is not neccessary to annoy users with country flags, if the
2846 http already provides means to determine preferred languages!
2848 function ewiki_localization() {
2850 global $ewiki_t, $ewiki_plugins;
2852 $deflangs = ','.@$_ENV["LANGUAGE"] . ','.@$_ENV["LANG"]
2853 . ",".EWIKI_DEFAULT_LANG
. ",en,C";
2855 foreach (explode(",", @$_SERVER["HTTP_ACCEPT_LANGUAGE"].$deflangs) as $l) {
2857 $l = strtok($l, ";");
2858 $l = strtok($l, "-"); $l = strtok($l, "_"); $l = strtok($l, ".");
2861 $ewiki_t["languages"][] = strtolower($l);
2868 /* poor mans gettext, $repl is an array of string replacements to get
2869 applied to the fetched text chunk,
2870 "$const" is either an entry from $ewiki_t[] or a larger text block
2871 containing _{text} replacement braces of the form "_{...}"
2873 function ewiki_t($const, $repl=array(), $pref_langs=array()) {
2874 ##### BEGIN MOODLE ADDITION #####
2875 $replacechars=array("." => "",
2887 $translation=get_string(strtolower(strtr($const,$replacechars)),"wiki",$repl);
2888 return $translation;
2889 ##### END MOODLE ADDITION #####
2893 #-- use default language wishes
2894 if (empty($pref_langs)) {
2895 $pref_langs = $ewiki_t["languages"];
2898 #-- large text snippet replaceing
2899 if (strpos($const, "_{") !== false) {
2900 while ( (($l=strpos($const,"_{")) || ($l===0)) && ($r=strpos($const,"}",$l)) ) {
2901 $const = substr($const, 0, $l)
2902 . ewiki_t(substr($const, $l+2, $r-$l-2))
2903 . substr($const,$r+1);
2908 else foreach ($pref_langs as $l) {
2910 if (is_string($r = @$ewiki_t[$l][$const]) || ($r = @$ewiki_t[$l][strtoupper($const)])) {
2912 foreach ($repl as $key=>$value) {
2913 if ($key[0] != '$') {
2916 $r = str_replace($key, $value, $r);
2931 function ewiki_log($msg, $error_type=3) {
2933 if ((EWIKI_LOGLEVEL
>= 0) && ($error_type <= EWIKI_LOGLEVEL
)) {
2935 $msg = time() . " - " .
2936 getremoteaddr() . ":" . $_SERVER["REMOTE_PORT"] . " - " .
2937 $_SERVER["REQUEST_METHOD"] . " " . $_SERVER["REQUEST_URI"] . " - " .
2938 strtr($msg, "\n\r\000\377\t\f", "\r\r\r\r\t\f") . "\n";
2939 error_log($msg, 3, EWIKI_LOGFILE
);
2946 function ewiki_die($msg, $return=0) {
2949 return($GLOBALS["ewiki_error"] = $msg);
2958 function ewiki_array_hash(&$a) {
2959 return(count($a) . ":" . implode(":", array_keys(array_slice($a, 0, 3))));
2964 /* provides an case-insensitive in_array replacement to search a page name
2965 in a list of others;
2966 the supplied $array WILL be lowercased afterwards, unless $dn was set
2968 function ewiki_in_array($value, &$array, $dn=0, $ci=EWIKI_CASE_INSENSITIVE
) {
2970 static $as = array();
2972 #-- work around pass-by-reference
2973 if ($dn && $ci) { $dest = array(); }
2974 else { $dest = &$array; }
2976 #-- make everything lowercase
2978 $value = strtolower($value);
2979 if (empty($as[ewiki_array_hash($array)])) { // prevent working on the
2980 foreach ($array as $i=>$v) { // same array multiple times
2981 $dest[$i] = strtolower($v);
2983 $as[ewiki_array_hash($dest)] = 1;
2987 #-- search in values
2988 return(in_array($value, $dest));
2993 /* case-insensitively retrieves an entry from an $array,
2994 or returns the given $array lowercased if $key was obmitted
2996 function ewiki_array($array, $key=false, $am=1, $ci=EWIKI_CASE_INSENSITIVE
) {
2998 #-- make everything lowercase
3000 $key = strtolower($key);
3003 foreach ($array as $i=>$v) {
3004 $i = strtolower($i);
3005 if (!$am ||
empty($r[$i])) {
3009 $r[$i] .= $v; //RET: doubling for images`meta won't happen
3010 } // but should be "+" here for integers
3015 #-- search in values
3017 return(@$array[$key]);
3029 function ewiki_author($defstr="") {
3031 $author = @$GLOBALS["ewiki_author"];
3032 ($ip = getremoteaddr()) or ($ip = "127.0.0.0");
3033 ($port = $_SERVER["REMOTE_PORT"]) or ($port = "null");
3035 $remote = (($ip != $hostname) ?
$hostname . " " : "")
3036 . $ip . ":" . $port;
3038 (empty($author)) && (
3039 ($author = $defstr) ||
3040 ($author = $_SERVER["HTTP_FROM"]) ||
// RFC2068 sect 14.22
3041 ($author = $_SERVER["PHP_AUTH_USER"])
3045 && ($author = $remote)
3046 ||
($author = addslashes($author) . " (" . $remote . ")" );
3055 /* Returns a value of (true) if the currently logged in user (this must
3056 be handled by one of the plugin backends) is authenticated to do the
3057 current $action, or to view the current $id page.
3058 - alternatively just checks current authentication $ring permission level
3059 - errors are returned via the global $ewiki_errmsg
3061 function ewiki_auth($id, &$data, $action, $ring=false, $request_auth=0) {
3063 global $ewiki_plugins, $ewiki_ring, $ewiki_author, $ewiki_errmsg;
3067 #echo "_a($id,dat,$action,$ring,$request_auth)<br />\n";
3069 if (EWIKI_PROTECTED_MODE
) {
3071 #-- set required vars
3072 if (!isset($ewiki_ring)) {
3073 $ewiki_ring = (int)EWIKI_AUTH_DEFAULT_RING
;
3075 if ($ring===false) {
3080 $pf_login = @$ewiki_plugins["auth_query"][0];
3081 $pf_perm = $ewiki_plugins["auth_perm"][0];
3083 #-- nobody is currently logged in, so try to fetch username,
3084 # the login <form> is not yet enforced
3085 if ($pf_login && empty($ewiki_auth_user)) {
3086 $pf_login($data, 0);
3089 #-- check permission for current request (page/action/ring)
3092 #-- via _auth handler
3093 $ok = $pf_perm($id, $data, $action, $ring, $request_auth);
3095 #-- if it failed, we really depend on the login <form>,
3096 # and then recall the _perm plugin
3097 if ($pf_login && (($request_auth >= 2) ||
!$ok && $request_auth && (empty($ewiki_auth_user) || EWIKI_AUTO_LOGIN
) && empty($ewiki_errmsg))) {
3098 //@FIXME: complicated if() - strip empty(errmsg) ??
3099 $pf_login($data, $request_auth);
3100 $ok = $pf_perm($id, $data, $action, $ring, $request_auth=0);
3104 $ok = !isset($ring) ||
isset($ring) && ($ewiki_ring <= $ring);
3107 #-- return error string
3108 if (!$ok && empty($ewiki_errmsg)) {
3109 $ewiki_errmsg = ewiki_t("FORBIDDEN");
3118 Queries all registered ["auth_userdb"] plugins for the given
3119 username, and compares password to against "db" value, sets
3120 $ewiki_ring and returns(true) if valid.
3122 function ewiki_auth_user($username, $password) {
3123 global $ewiki_ring, $ewiki_errmsg, $ewiki_auth_user, $ewiki_plugins, $ewiki_author;
3125 if (empty($username)) {
3128 if (($password[0] == "$") ||
(strlen($password) > 12)) {
3129 ewiki_log("_auth_userdb: password was transmitted in encoded form, or is just too long (login attemp for user '$username')", 2);
3133 if ($pf_u = $ewiki_plugins["auth_userdb"])
3134 foreach ($pf_u as $pf) {
3136 if (function_exists($pf) && ($entry = $pf($username, $password))) {
3138 #-- get and compare password
3139 if ($entry = (array) $entry) {
3140 $enc_pw = $entry[0];
3143 ||
($enc_pw == substr($password, 0, 12))
3144 ||
($enc_pw == md5($password))
3145 ||
($enc_pw == crypt($password, substr($enc_pw, 0, 2)))
3146 ||
function_exists("sha1") && ($enc_pw == sha1($password));
3147 $success &= $enc_pw != "*";
3149 #-- return if it matches
3151 if (isset($entry[1])) {
3152 $ewiki_ring = (int)($entry[1]);
3154 $ewiki_ring = 2; //(EWIKI_AUTH_DEFAULT_RING - 1);
3156 if (empty($ewiki_author)) {
3157 ($ewiki_author = $entry[2]) or
3158 ($ewiki_author = $username);
3160 return($success && ($ewiki_auth_user=$username));
3165 if ($username ||
$password) {
3166 ewiki_log("_auth_userdb: wrong password supplied for user '$username', not verified against any userdb", 3);
3167 $ewiki_errmsg = "wrong username and/or password";
3168 # ewiki_auth($uu, $uu, $uu, $uu, 2);
3177 /* reads all files from "./init-pages/" into the database,
3178 when ewiki is run for the very first time and the FrontPage
3179 does not yet exist in the database
3181 function ewiki_eventually_initialize(&$id, &$data, &$action) {
3185 #-- initialize database only if frontpage missing
3186 if (($id==EWIKI_PAGE_INDEX
) && ($action=="edit") && empty($data["version"])) {
3188 ewiki_database("INIT", array());
3189 #### BEGIN MOODLE CHANGE
3190 $path=EWIKI_INIT_PAGES
;
3191 if (!empty($path)) {
3192 if ($dh = @opendir
($path=EWIKI_INIT_PAGES
)) {
3193 while (false !== ($filename = readdir($dh))) {
3194 #### MOODLE CHANGE TO SOLVE BUG #3830. Original doesn't support dots in names.
3195 //Orig->if (preg_match('/^(['.EWIKI_CHARS_U.']+['.EWIKI_CHARS_L.']+\w*)+/', $filename)) {
3196 if ($filename == clean_filename($filename) && !is_dir($path.'/'.$filename)) {
3197 #### END OF MOODLE CHANGE TO SOLVE BUG #3830. Original doesn't support dots in names.
3198 $found = ewiki_database("FIND", array($filename));
3199 if (! $found[$filename]) {
3200 $content = implode("", file("$path/$filename"));
3201 ewiki_scan_wikiwords($content, $ewiki_links, "_STRIP_EMAIL=1");
3202 $refs = "\n\n" . implode("\n", array_keys($ewiki_links)) . "\n\n";
3204 "id" => "$filename",
3207 "content" => $content,
3208 "author" => ewiki_author("ewiki_initialize"),
3209 "userid" => $USER->id
,
3211 "lastmodified" => filemtime("$path/$filename"),
3212 "created" => filectime("$path/$filename") // (not exact)
3214 ewiki_database("WRITE", $save);
3221 echo "<b>ewiki error</b>: could not read from directory ". realpath($path) ."<br />\n";
3224 #### END MOODLE CHANGE
3226 #-- try to view/ that newly inserted page
3227 if ($data = ewiki_database("GET", array("id"=>$id))) {
3236 #---------------------------------------------------------------------------
3240 ######## ### ######## ### ######## ### ###### ########
3241 ######## ### ######## ### ######## ### ###### ########
3242 ## ## ## ## ## ## ## ## ## ## ## ## ## ##
3243 ## ## ## ## ## ## ## ## ## ## ## ## ## ##
3244 ## ## ## ## ## ## ## ## ## ## ## ## ##
3245 ## ## ## ## ## ## ## ## ## ## ## ## ##
3246 ## ## ## ## ## ## ## ######## ## ## ###### ######
3247 ## ## ## ## ## ## ## ######## ## ## ###### ######
3248 ## ## ######### ## ######### ## ## ######### ## ##
3249 ## ## ######### ## ######### ## ## ######### ## ##
3250 ## ## ## ## ## ## ## ## ## ## ## ## ## ##
3251 ## ## ## ## ## ## ## ## ## ## ## ## ## ##
3252 ######## ## ## ## ## ## ######## ## ## ###### ########
3253 ######## ## ## ## ## ## ######## ## ## ###### ########
3260 function ewiki_database($action, $args, $sw1=0, $sw2=0, $pf=false) {
3262 #-- normalize (fetch bad parameters)
3263 if (($action=="GET") && !is_array($args) && is_string($args)) {
3264 $args = array("id" => $args);
3271 $args = array_unique(@array_merge
($args, array("flags", "version")));
3272 $args = array_diff($args, array("id"));
3276 # unset($args["version"]);
3277 # unset($args["flags"]);
3284 #-- handle {meta} sub array as needed
3285 if (is_array(@$args["meta"])) {
3286 $args["meta"] = serialize($args["meta"]);
3290 if (($pf) ||
($pf = @$GLOBALS["ewiki_plugins"]["database"][0])) {
3291 $r = $pf($action, $args, $sw1, $sw2);
3294 ewiki_log("DB layer: no backend!", 0);
3298 #-- database layer generation 2 abstraction
3299 if (is_array($r) && (($action=="SEARCH") ||
($action=="GETALL"))) {
3300 $z = new ewiki_dbquery_result(array_keys($args));
3301 foreach ($r as $id=>$row) {
3307 #-- extract {meta} sub array
3308 if (is_array($r) && !is_array(@$r["meta"]) && strlen(@$r["meta"])) {
3309 $r["meta"] = unserialize($r["meta"]);
3317 /* returned for SEARCH and GETALL queries, as those operations are
3318 otherwise too memory exhaustive
3320 class ewiki_dbquery_result
{
3322 var $keys = array();
3323 var $entries = array();
3324 var $buffer = EWIKI_DBQUERY_BUFFER
;
3327 function ewiki_dbquery_result($keys) {
3328 $keys = @array_merge
($keys, array(-50=>"id", "version", "flags"));
3329 $this->keys
= array_unique($keys);
3332 function add($row) {
3333 if (is_array($row)) {
3334 if ($this->buffer
) {
3335 $this->size +
= strlen(serialize($row));
3336 $this->buffer
= $this->size
<= EWIKI_DBQUERY_BUFFER
;
3342 $this->entries
[] = $row;
3345 function get($all=0, $flags=0x00) {
3348 $prot_hide = ($flags&0x0020) && EWIKI_PROTECTED_MODE
&& EWIKI_PROTECTED_MODE_HIDING
;
3350 if (count($this->entries
)) {
3352 #-- fetch very first entry from $entries list
3353 $r = array_shift($this->entries
);
3355 #-- finish if buffered entry
3356 if (is_array($r) && !$all) {
3359 #-- else refetch complete entry from database
3364 $r = ewiki_database("GET", array("id"=>$r));
3366 foreach ($this->keys
as $key) {
3367 $row[$key] = $r[$key];
3376 return(NULL); // no more entries
3379 #-- expand {meta} field
3380 if (is_array($row) && is_string(@$row["meta"])) {
3381 $row["meta"] = unserialize($row["meta"]);
3384 #-- drop unwanted results
3385 if ($prot_hide && !ewiki_auth($row["id"], $row, $ewiki_action)) {
3388 } while ($prot_hide && empty($row));
3394 return(count($this->entries
));
3400 /* MySQL database backend
3402 Note: this is of course an abuse of the relational database scheme,
3403 but neccessary for real db independence and abstraction
3405 function ewiki_database_mysql($action, &$args, $sw1, $sw2) {
3407 #-- reconnect to the database (if multiple are used)
3408 #<off># mysql_ping($GLOBALS["db"]);
3415 /* Returns database entry as array for the page whose name was given
3416 with the "id" key in the $args array, usually fetches the latest
3417 version of a page, unless a specific "version" was requested in
3421 $id = "'" . mysql_escape_string($args["id"]) . "'";
3422 ($version = 0 +
@$args["version"]) and ($version = "AND (version=$version)") or ($version="");
3423 $result = mysql_query("SELECT * FROM " . EWIKI_DB_TABLE_NAME
3424 . " WHERE (pagename=$id) $version ORDER BY version DESC LIMIT 1"
3426 if ($result && ($r = mysql_fetch_array($result, MYSQL_ASSOC
))) {
3427 $r["id"] = $r["pagename"];
3428 unset($r["pagename"]);
3430 if (strlen($r["meta"])) {
3431 $r["meta"] = @unserialize
($r["meta"]);
3437 /* Increases the hit counter for the page name given in $args array
3438 with "id" index key.
3441 mysql_query("UPDATE " . EWIKI_DB_TABLE_NAME
. " SET hits=(hits+1) WHERE pagename='" . mysql_escape_string($args["id"]) . "'");
3446 /* Stores the $data array into the database, while not overwriting
3447 existing entries (using WRITE); returns 0 on failure and 1 if
3450 case "OVERWRITE": // fall-through
3451 $COMMAND = "REPLACE";
3454 $args["pagename"] = $args["id"];
3457 if (is_array($args["meta"])) {
3458 $args["meta"] = serialize($args["meta"]);
3462 foreach ($args as $index => $value) {
3463 if (is_int($index)) {
3466 $a = ($sql1 ?
', ' : '');
3467 $sql1 .= $a . $index;
3468 $sql2 .= $a . "'" . mysql_escape_string($value) . "'";
3471 strlen(@$COMMAND) ||
($COMMAND = "INSERT");
3473 $result = mysql_query("$COMMAND INTO " . EWIKI_DB_TABLE_NAME
.
3474 " (" . $sql1 . ") VALUES (" . $sql2 . ")"
3477 return($result && mysql_affected_rows() ?
1:0);
3482 /* Checks for existence of the WikiPages whose names are given in
3483 the $args array. Returns an array with the specified WikiPageNames
3484 associated with values of "0" or "1" (stating if the page exists
3485 in the database). For images/binary db entries returns the "meta"
3486 field instead of an "1".
3490 foreach (array_values($args) as $id) if (strlen($id)) {
3492 $sql .= ($sql ?
" OR " : "") .
3493 "(pagename='" . mysql_escape_string($id) . "')";
3495 $result = mysql_query($sql = "SELECT pagename AS id, meta FROM " .
3496 EWIKI_DB_TABLE_NAME
. " WHERE $sql "
3498 while ($result && ($row = mysql_fetch_row($result))) {
3499 $r[$row[0]] = strpos($row[1], 's:5:"image"') ?
$row[1] : 1;
3505 /* Returns an array of __all__ pages, where each entry is made up
3506 of the fields from the database requested with the $args array,
3507 e.g. array("flags","meta","lastmodified");
3510 $result = mysql_query("SELECT pagename AS id, ".
3511 implode(", ", $args) .
3512 " FROM ". EWIKI_DB_TABLE_NAME
.
3513 " GROUP BY id, version DESC"
3515 $r = new ewiki_dbquery_result($args);
3517 while ($result && ($row = mysql_fetch_array($result, MYSQL_ASSOC
))) {
3518 $i = EWIKI_CASE_INSENSITIVE ?
strtolower($row["id"]) : $row["id"];
3528 /* Returns array of database entries (also arrays), where the one
3529 specified column matches the specified content string, for example
3530 $args = array("content" => "text...piece")
3531 is not guaranteed to only search/return the latest version of a page
3534 $field = implode("", array_keys($args));
3535 $content = strtolower(implode("", $args));
3536 if ($field == "id") { $field = "pagename"; }
3538 $result = mysql_query("SELECT pagename AS id, version, flags" .
3539 (EWIKI_DBQUERY_BUFFER
&& ($field!="pagename") ?
", $field" : "") .
3540 " FROM " . EWIKI_DB_TABLE_NAME
.
3541 " WHERE LOCATE('" . mysql_escape_string($content) . "', LCASE($field)) " .
3542 " GROUP BY id, version DESC"
3544 $r = new ewiki_dbquery_result(array("id","version",$field));
3546 while ($result && ($row = mysql_fetch_array($result, MYSQL_ASSOC
))) {
3547 $i = EWIKI_CASE_INSENSITIVE ?
strtolower($row["id"]) : $row["id"];
3558 $id = mysql_escape_string($args["id"]);
3559 $version = $args["version"];
3560 mysql_query("DELETE FROM " . EWIKI_DB_TABLE_NAME
."
3561 WHERE pagename='$id' AND version=$version");
3567 mysql_query("CREATE TABLE " . EWIKI_DB_TABLE_NAME
."
3568 (pagename VARCHAR(160) NOT NULL,
3569 version INTEGER UNSIGNED NOT NULL DEFAULT 0,
3570 flags INTEGER UNSIGNED DEFAULT 0,
3572 author VARCHAR(100) DEFAULT 'ewiki',
3573 userid INTEGER UNSIGNED DEFAULT 0,
3574 created INTEGER UNSIGNED DEFAULT ".time().",
3575 lastmodified INTEGER UNSIGNED DEFAULT 0,
3578 hits INTEGER UNSIGNED DEFAULT 0,
3579 PRIMARY KEY id (pagename, version) )