--- /dev/null
+ToDo
+Mike:
+ - Group Handling (Mike)
+ > deal with changing group mode on active wikis
+ > handle group mode for teacher wikis
+ - Rating
+ - Commenting
+ - Grading
+
+Michael:
+ - SiteMap
+ - Notify
+
+Unassigned or not ready:
+ - Dump Pages
+ - http://moodle.org/mod/forum/discuss.php?d=7768#36954
+ - Image Thumbnails http://moodle.org/mod/forum/discuss.php?d=8351
+
+
+ewiki Preparation:
+ - Current Version: 1.01d
+ - rm -r example-1.php examples/ tools/ config.php
+ - rm -r fragments/ patches/ php-patches/ spages/
--- /dev/null
+------------------------------------------------------------------------------
+WIKI - MOODLE IMPLEMENTATION
+------------------------------------------------------------------------------
+
+This directory contains the work-in-progress version of the Erfurt Wiki
+integration into Moodle.
+
+THIS IS NOT PRODUCTION SOFTWARE. DO NOT INSTALL THIS ON A PRODUCTION SYSTEM!!
+
+This version has been provided for Moodle developers and testers only. It is a
+work in progress and may undergo significant changes.
+
+If you wish to try it, it can be installed as any module.
+
+Please fully delete any previously installed wiki module.
+
--- /dev/null
+<?PHP // $Id$
+/// Extended by Michael Schneider
+/// This page prints a particular instance of wiki
+
+
+ require_once("../../config.php");
+ require_once("lib.php");
+
+ include_once($CFG->dirroot."/mod/wiki/ewikimoodlelib.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/moodle/moodle_binary_store.php");
+
+ require_login($course->id);
+
+
+ optional_variable($id); // Course Module ID, or
+ optional_variable($wikipage); // Pagename
+ optional_variable($confirm, "");
+ optional_variable($action,""); // Admin Action
+ optional_variable($userid); // User wiki.
+ optional_variable($groupid); // Group wiki.
+
+ if ($id) {
+ if (! $cm = get_record("course_modules", "id", $id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ if (! $course = get_record("course", "id", $cm->course)) {
+ error("Course is misconfigured");
+ }
+
+ if (! $wiki = get_record("wiki", "id", $cm->instance)) {
+ error("Course module is incorrect");
+ }
+
+ } else {
+ if (! $wiki = get_record("wiki", "id", $a)) {
+ error("Course module is incorrect");
+ }
+ if (! $course = get_record("course", "id", $wiki->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("wiki", $wiki->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+ }
+
+ /// Build the ewsiki script constant
+ $ewbase = 'view.php?id='.$id;
+ if (isset($userid)) $ewbase .= '&userid='.$userid;
+ if (isset($groupid)) $ewbase .= '&groupid='.$groupid;
+ $ewscript = $ewbase.'&wikipage=';
+ define("EWIKI_SCRIPT", $ewscript);
+ if($wiki->ewikiacceptbinary) {
+ define("EWIKI_UPLOAD_MAXSIZE", get_max_upload_file_size());
+ define("EWIKI_SCRIPT_BINARY", $ewbase."&binary=");
+ }
+
+
+ /// Add the course module 'groupmode' to the wiki object, for easy access.
+ $wiki->groupmode = $cm->groupmode;
+
+ /// Is an Action given ?
+ if(!$action) {
+ error(get_string("noadministrationaction","wiki"));
+ }
+
+ /// Correct Action ?
+ if(!in_array($action, array("setpageflags", "removepages", "strippages", "checklinks", "revertpages"))) {
+ error("Unknown action '$action'","wiki");
+ }
+
+
+ /// May the User administrate it ?
+ if (($wiki_entry = wiki_get_entry($wiki, $course, $userid, $groupid)) === false || wiki_can_edit_entry($wiki_entry, $wiki, $USER, $course) === false) {
+ error(get_string("notadministratewiki","wiki"));
+ }
+
+ /// The wiki_entry->pagename is set to the specified value of the wiki,
+ /// or the default value in the 'lang' file if the specified value was empty.
+ define("EWIKI_PAGE_INDEX",$wiki_entry->pagename);
+ # The mighty Wiki itself
+ include_once($CFG->dirroot."/mod/wiki/ewiki/ewiki.php");
+
+/// Print the page header
+
+ if ($course->category) {
+ $navigation = "<A HREF=\"../../course/view.php?id=$course->id\">$course->shortname</A> ->";
+ }
+
+ $strwikis = get_string("modulenameplural", "wiki");
+ $strwiki = get_string("modulename", "wiki");
+
+ /// Validate Form
+ if ($form = data_submitted()) {
+ switch($action) {
+ case "revertpages":
+ if(!$form->deleteversions || 0 > $form->deleteversions || $form->deleteversions > 1000) {
+ $focus="form.deleteversions";
+ $err->deleteversions=get_string("deleteversionserror","wiki");
+ }
+ if(!$form->changesfield || 0 > $form->changesfield || $form->changesfield > 100000) {
+ $focus="form.changesfield";
+ $err->changesfield=get_string("changesfielderror","wiki");
+ }
+ if($form->authorfieldpattern=="") {
+ $focus="form.authorfieldpattern";
+ $err->authorfieldpattern=get_string("authorfieldpatternerror","wiki");
+ }
+ break;
+ default: break;
+ }
+ }
+
+ print_header("$course->shortname: $wiki_entry->pagename", "$course->fullname",
+ "$navigation <A HREF=\"index.php?id=$course->id\">$strwikis</A> -> <A HREF=\"view.php?id=$id\">$wiki->name</a> ->".
+ get_string("administration","wiki"),
+ $focus, "", true, update_module_button($cm->id, $course->id, $strwiki),
+ navmenu($course, $cm));
+
+
+ ////////////////////////////////////////////////////////////
+ /// Check if the Form has been submitted and display confirmation
+ ////////////////////////////////////////////////////////////
+ if ($form = data_submitted()) {
+ check_for_restricted_user($USER->username, "$CFG->wwwroot/course/view.php?id=$course->id");
+ /// Moodle Log
+ add_to_log($course->id, "wiki", $action, "admin.php?id=$id");
+ $link="admin.php?action=$action&userid=$userid&groupid=$groupid&id=$id&wikipage=$wikipage";
+ switch($action) {
+ case "removepages":
+ if($form->proceed) {
+ if(!$confirm && $form->pagestodelete) {
+ notice_yesno(get_string("removepagecheck", "wiki")."<br>".join(", ", $form->pagestodelete),
+ $link."&confirm=".urlencode(join(" ",$form->pagestodelete)), $link);
+ print_footer($course);
+ exit;
+ }
+ }
+ break;
+ case "strippages":
+ if($form->proceed) {
+ if(!$confirm && $form->pagestostrip) {
+ $err=array();
+ $strippages=wiki_admin_strip_versions($form->pagestostrip,$form->version, $err);
+
+ $confirm="";
+ foreach($strippages as $cnfid => $cnfver) {
+ $confirm.="&confirm[$cnfid]=".urlencode(join(" ",$cnfver));
+ }
+ if(count($err)==0) {
+ notice_yesno(get_string("strippagecheck", "wiki")."<br>".join(", ", $form->pagestostrip),
+ $link.$confirm, $link);
+ print_footer($course);
+ exit;
+ }
+ }
+ }
+ break;
+ case "checklinks":
+ if($form->proceed) {
+ if(!$confirm && $form->pagetocheck) {
+ $confirm="&confirm=".$form->pagetocheck;
+ notice_yesno(get_string("checklinkscheck", "wiki").$form->pagetocheck,
+ $link.$confirm, $link);
+ print_footer($course);
+ exit;
+ }
+ }
+ break;
+ case "setpageflags":
+ // pageflagstatus is used in setpageflags.html
+ $pageflagstatus=wiki_admin_setpageflags($form->flags);
+ break;
+ case "revertpages":
+ if(!$err) {
+ if(!$confirm) {
+ $confirm="&confirm[changesfield]=".urlencode($form->changesfield).
+ "&confirm[authorfieldpattern]=".urlencode($form->authorfieldpattern).
+ "&confirm[howtooperate]=".urlencode($form->howtooperate).
+ "&confirm[deleteversions]=".urlencode($form->deleteversions);
+ $revertedpages=wiki_admin_revert("", $form->authorfieldpattern, $form->changesfield, $form->howtooperate, $form->deleteversions);
+ if($revertedpages) {
+ notice_yesno(get_string("revertpagescheck", "wiki")."<br>".$revertedpages,
+ $link.$confirm, $link);
+ print_footer($course);
+ exit;
+ } else {
+ $err->remark=get_string("nochangestorevert","wiki");
+ }
+ }
+ }
+ break;
+ default: error("No such Wiki-Admin action: $action");
+ break;
+ }
+ }
+
+ /// Actions which need a confirmation. If confirmed, do the action
+ $redirect="view.php?userid=$userid&groupid=$groupid&id=$id&wikipage=$wikipage";
+ if($confirm && !$err) {
+ switch($action) {
+ case "removepages":
+ $ret=wiki_admin_remove(split(" ",$confirm), $course, $wiki, $userid, $groupid);
+ if(!$ret) {
+ redirect($redirect, get_string("pagesremoved","wiki"), 1);
+ } else {
+ error($ret);
+ }
+ exit;
+ case "strippages":
+ $strippages=array();
+ foreach($confirm as $pageid => $versions) {
+ $strippages[$pageid]=split(" ",$versions);
+ }
+ $ret=wiki_admin_strip($strippages);
+ if(!$ret) {
+ redirect($redirect, get_string("pagesstripped","wiki"), 1);
+ } else {
+ error($ret);
+ }
+ exit;
+ case "checklinks":
+ $ret=wiki_admin_checklinks($confirm);
+ redirect($redirect, get_string("linkschecked","wiki")."<br>".$ret, 5);
+ exit;
+ case "revertpages":
+ $revertedpages=wiki_admin_revert(1, $confirm["authorfieldpattern"], $confirm["changesfield"], $confirm["howtooperate"], $confirm["deleteversions"]);
+ redirect($redirect, get_string("pagesreverted","wiki"), 1);
+ exit;
+ case "setpageflags":
+ # No confirmation needed
+ break;
+ default: error("No such action '$action' with confirmation");
+ }
+ }
+
+
+ /// The top row contains links to other wikis, if applicable.
+ if ($wiki_list = wiki_get_other_wikis($wiki, $USER, $course, $wiki_entry->id)) {
+ if (isset($wiki_list['selected'])) {
+ $selected = $wiki_list['selected'];
+ unset($wiki_list['selected']);
+ }
+ echo '<tr><td colspan="2">';
+
+ echo '<form name="otherwikis" action="'.$CFG->wwwroot.'/mod/wiki/admin.php">';
+ echo '<table border="0" cellpadding="0" cellspacing="0" width="100%"><tr>';
+ echo '<td class="sideblockheading" bgcolor="'.$THEME->cellheading.'"> '
+ .$WIKI_TYPES[$wiki->wtype].' '
+ .get_string('modulename', 'wiki').' for '
+ .wiki_get_owner($wiki_entry).':</td>';
+
+ echo '<td class="sideblockheading" bgcolor="'.$THEME->cellheading.'" align="right">'
+ .get_string('otherwikis', 'wiki').': ';
+ $script = 'self.location=document.otherwikis.wikiselect.options[document.otherwikis.wikiselect.selectedIndex].value';
+
+ /// Add Admin-Action
+ reset($wiki_list);
+ $wiki_admin_list=array();
+ while(list($key,$val)=each($wiki_list)) {
+ $wiki_admin_list[$key."&action=$action"]=$val;
+ }
+ choose_from_menu($wiki_admin_list, "wikiselect", $selected, "choose", $script);
+ echo '</td>';
+ echo '</tr></table>';
+ echo '</form>';
+
+ echo '</td>';
+ echo '</tr>';
+ }
+
+ if ($wiki_entry) {
+
+
+ /// Page Actions
+ echo '<table border="0" width="100%">';
+ echo '<tr>';
+# echo '<tr><td align="center">';
+# $specialpages=array("SearchPages", "PageIndex","NewestPages","MostVisitedPages","MostOftenChangedPages","UpdatedPages","FileDownload","FileUpload","OrphanedPages","WantedPages");
+# wiki_print_page_actions($cm->id, $specialpages, $ewiki_id, $ewiki_action, $wiki->ewikiacceptbinary, $canedit);
+# echo '</td>';
+
+ /// Searchform
+ echo '<td align="center">';
+ wiki_print_search_form($cm->id, $q, $userid, $groupid, false);
+ echo '</td>';
+
+ /// Internal Wikilinks
+
+ /// TODO: DOES NOT WORK !!!!
+ echo '<td align="center">';
+ wiki_print_wikilinks_block($cm->id, $wiki->ewikiacceptbinary);
+ echo '</td>';
+
+ /// Administrative Links
+ echo '<td align="center">';
+ wiki_print_administration_actions($cm->id, $userid, $groupid, $wikipage, $wiki->htmlmode!=2);
+ echo '</td>';
+
+# if($wiki->htmlmode!=2) {
+# echo '<td align="center">';
+# helpbutton('formattingrules', get_string('formattingrules', 'wiki'), 'wiki');
+# echo get_string("formattingrules","wiki");
+# echo '</td>';
+# }
+
+ echo '</tr></table>';
+ }
+
+ // The wiki Contents
+ print_simple_box_start( "center", "100%", "$THEME->cellcontent", "20");
+ // Do the Action
+ # "setpageflags", "removepages", "strippages", "checklinks", "revertpages"
+ print_heading_with_help(get_string($action,"wiki"), $action, "wiki");
+ include $action.".html";
+ print_simple_box_end();
+
+/// Finish the page
+ print_footer($course);
+ exit;
+
+?>
\ No newline at end of file
--- /dev/null
+<?PHP //$Id$
+ //This php script contains all the stuff to backup/restore
+ //wiki mods
+
+ //This is the "graphical" structure of the wiki mod:
+ //
+ // wiki
+ // (CL,pk->id)
+ //
+ // wiki_entries
+ // (pk->id, fk->wikiid)
+ //
+ // wiki_pages
+ // (pk->pagename,version,wiki, fk->wiki)
+ //
+ // Meaning: pk->primary key field of the table
+ // fk->foreign key to link with parent
+ // nt->nested field (recursive data)
+ // CL->course level info
+ // UL->user level info
+ // files->table may have files)
+ //
+ //-----------------------------------------------------------
+
+ //This function executes all the backup procedure about this mod
+ function wiki_backup_mods($bf,$preferences) {
+ global $CFG;
+
+ $status = true;
+
+ ////Iterate over wiki table
+ if ($wikis = get_records ("wiki","course", $preferences->backup_course,"id")) {
+ foreach ($wikis as $wiki) {
+ //Start mod
+ fwrite ($bf,start_tag("MOD",3,true));
+ //Print assignment data
+ fwrite ($bf,full_tag("ID",4,false,$wiki->id));
+ fwrite ($bf,full_tag("MODTYPE",4,false,"wiki"));
+ fwrite ($bf,full_tag("NAME",4,false,$wiki->name));
+ fwrite ($bf,full_tag("SUMMARY",4,false,$wiki->summary));
+ fwrite ($bf,full_tag("PAGENAME",4,false,$wiki->wtype));
+ fwrite ($bf,full_tag("WTYPE",4,false,$wiki->wtype));
+ fwrite ($bf,full_tag("EWIKIPRINTTITLE",4,false,$wiki->ewikiprinttitle));
+ fwrite ($bf,full_tag("HTMLMODE",4,false,$wiki->allowsafehtml));
+ fwrite ($bf,full_tag("EWIKIACCEPTBINARY",4,false,$wiki->ewikiacceptbinary));
+ fwrite ($bf,full_tag("INITIALCONTENT",4,false,$wiki->initialcontent));
+ fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$wiki->timemodified));
+
+ //backup entries and pages
+ if ($preferences->mods["forum"]->userinfo) {
+ $status=backup_wiki_entries($bf,$preferences,$wiki->id, $preferences->mods["wiki"]->userinfo);
+ }
+
+ //End mod
+ fwrite ($bf,end_tag("MOD",3,true));
+ }
+ }
+ //if we've selected to backup users info, then backup files too
+ if ($status) {
+ if ($preferences->mods["wiki"]->userinfo) {
+ $status = backup_wiki_files($bf,$preferences);
+ }
+ }
+ return $status;
+ }
+
+ ////Return an array of info (name,value)
+ function wiki_check_backup_mods($course,$user_data=false,$backup_unique_code) {
+ //First the course data
+ $info[0][0] = get_string("modulenameplural","wiki");
+ $info[0][1] = count_records("wiki", "course", "$course");
+ return $info;
+ }
+
+ //Backup wiki_entries contents (executed from wiki_backup_mods)
+ function backup_wiki_entries ($bf,$preferences,$wiki, $userinfo) {
+
+ global $CFG;
+
+ $status = true;
+
+ $wiki_entries = get_records("wiki_entries","wikiid",$wiki,"id");
+ //If there are entries
+ if ($wiki_entries) {
+ $dumped_entries = 0;
+
+ //Iterate over each entry
+ foreach ($wiki_entries as $wik_ent) {
+ //Start entry
+ //Print submission contents
+ if ($userinfo) {
+ $dumped_entries++;
+ if ($dumped_entries == 1) {
+ //Write start tag
+ $status =fwrite ($bf,start_tag("ENTRIES",4,true));
+ }
+ $status =fwrite ($bf,start_tag("ENTRY",5,true));
+
+ fwrite ($bf,full_tag("ID",6,false,$wik_ent->id));
+ fwrite ($bf,full_tag("GROUPID",6,false,$wik_ent->groupid));
+ fwrite ($bf,full_tag("USERID",6,false,$wik_ent->userid));
+ fwrite ($bf,full_tag("PAGENAME",6,false,$wik_ent->pagename));
+ fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$wik_ent->timemodified));
+
+
+ if ( $userinfo ) {
+ $status = backup_wiki_pages($bf,$preferences,$wik_ent->id);
+ }
+
+ $status =fwrite ($bf,end_tag("ENTRY",5,true));
+ }
+ }
+ if ( $dumped_entries > 0 ) {
+ //Write end tag
+ $status =fwrite ($bf,end_tag("ENTRIES",4,true));
+ }
+ }
+ return $status;
+ }
+ function backup_wiki_pages ($bf,$preferences,$entryid) {
+
+ global $CFG;
+
+ $status = true;
+
+ $pages = get_records("wiki_pages","wiki",$entryid);
+ if ($pages) {
+ $status =fwrite ($bf,start_tag("PAGES",6,true));
+ foreach ($pages as $page) {
+ $status =fwrite ($bf,start_tag("PAGE",7,true));
+
+ fwrite ($bf,full_tag("PAGENAME",8,false,$page->pagename));
+ fwrite ($bf,full_tag("VERSION",8,false,$page->version));
+ fwrite ($bf,full_tag("FLAGS",8,false,$page->flags));
+ fwrite ($bf,full_tag("CONTENT",8,false,$page->content));
+ fwrite ($bf,full_tag("AUTHOR",8,false,$page->author));
+ fwrite ($bf,full_tag("CREATED",8,false,$page->created));
+ fwrite ($bf,full_tag("LASTMODIFIED",8,false,$page->lastmodified));
+ fwrite ($bf,full_tag("REFS",8,false,$page->refs));
+ fwrite ($bf,full_tag("META",8,false,$page->meta));
+ fwrite ($bf,full_tag("HITS",8,false,$page->hits));
+
+ $status =fwrite ($bf,end_tag("PAGE",7,true));
+ }
+ $status =fwrite ($bf,end_tag("PAGES",6,true));
+ }
+ return $status;
+ }
+
+ //Backup wiki binary files
+ function backup_wiki_files($bf,$preferences) {
+
+ global $CFG;
+
+ $status = true;
+
+ //First we check to moddata exists and create it as necessary
+ //in temp/backup/$backup_code dir
+ $status = check_and_create_moddata_dir($preferences->backup_unique_code);
+ //Now copy the forum dir
+ if ($status) {
+ //Only if it exists !! Thanks to Daniel Miksik.
+ if (is_dir($CFG->dataroot."/".$preferences->backup_course."/".$CFG->moddata."/wiki")) {
+ $status = backup_copy_file($CFG->dataroot."/".$preferences->backup_course."/".$CFG->moddata."/wiki",
+ $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/moddata/wiki");
+ }
+ }
+
+ return $status;
+
+ }
+
+?>
--- /dev/null
+<?PHP
+ // Make sure all variables are defined
+
+?>
+<FORM ACTION="admin.php" METHOD="POST" ENCTYPE="multipart/form-data">
+<INPUT TYPE="HIDDEN" NAME="userid" VALUE="<? print $userid; ?>">
+<INPUT TYPE="HIDDEN" NAME="groupid" VALUE="<? print $groupid ?>">
+<INPUT TYPE="HIDDEN" NAME="action" VALUE="<? print $action; ?>">
+<INPUT TYPE="HIDDEN" NAME="id" VALUE="<? print $cm->id ?>">
+<INPUT TYPE="HIDDEN" NAME="wikipage" VALUE="<? print $wikipage?>">
+<?
+ $pagelist=wiki_admin_checklinks_list();
+ choose_from_menu($pagelist, "pagetocheck", $wikipage, "");
+?>
+ <input type="submit" name="proceed" value="<? print get_string("checklinks","wiki"); ?>">
+</center>
\ No newline at end of file
--- /dev/null
+<?PHP
+
+function wiki_upgrade($oldversion) {
+/// This function does anything necessary to upgrade
+/// older versions to match current functionality
+
+ global $CFG;
+
+ if ($oldversion < 2004040200) {
+ execute_sql('ALTER TABLE `'.$CFG->prefix.'wiki` DROP `allowstudentstowiki`');
+ }
+
+ if ($oldversion < 2004040700) {
+ execute_sql('ALTER TABLE `'.$CFG->prefix.'wiki` CHANGE `ewikiallowsafehtml` `htmlmode` TINYINT( 4 ) DEFAULT \'0\' NOT NULL');
+ }
+
+ if ($oldversion < 2004042100) {
+ execute_sql('ALTER TABLE `'.$CFG->prefix.'wiki` ADD `pagename` VARCHAR( 255 ) AFTER `summary`');
+ execute_sql('ALTER TABLE `'.$CFG->prefix.'wiki_entries` CHANGE `name` `pagename` VARCHAR( 255 ) NOT NULL');
+ if ($wikis = get_records('wiki')) {
+ foreach ($wikis as $wiki) {
+ if (empty($wiki->pagename)) {
+ set_field('wiki', 'pagename', $wiki->name, 'id', $wiki->id);
+ }
+ }
+ }
+ }
+
+ if ($oldversion < 2004053100) {
+ execute_sql('ALTER TABLE `'.$CFG->prefix.'wiki` CHANGE `initialcontent` `initialcontent` VARCHAR( 255 ) DEFAULT NULL');
+// Remove obsolete 'initialcontent' values.
+ if ($wikis = get_records('wiki')) {
+ foreach ($wikis as $wiki) {
+ if (!empty($wiki->initialcontent)) {
+ set_field('wiki', 'initialcontent', null, 'id', $wiki->id);
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+?>
--- /dev/null
+# This file contains a complete database schema for all the
+# tables used by this module, written in SQL
+
+# It may also contain INSERT statements for particular data
+# that may be used, especially new entries in the table log_display
+
+
+CREATE TABLE `prefix_wiki` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `course` int(10) unsigned NOT NULL default '0',
+ `name` varchar(255) NOT NULL default '',
+ `summary` text NOT NULL,
+ `pagename` varchar(255) default NULL,
+ `wtype` enum('teacher','group','student') NOT NULL default 'group',
+ `ewikiprinttitle` tinyint(4) NOT NULL default '1',
+ `htmlmode` tinyint(4) NOT NULL default '0',
+ `ewikiacceptbinary` tinyint(4) NOT NULL default '0',
+ `initialcontent` varchar(255) default NULL,
+ `timemodified` int(10) NOT NULL default '0',
+ PRIMARY KEY (`id`)
+) TYPE=MyISAM COMMENT='Main wiki table';
+
+
+
+#
+# Table structure for table `mdl_wiki_entries`
+#
+
+CREATE TABLE `prefix_wiki_entries` (
+ `id` int(10) NOT NULL auto_increment,
+ `wikiid` int(10) NOT NULL default '0',
+ `course` int(10) NOT NULL default '0',
+ `groupid` int(10) NOT NULL default '0',
+ `userid` int(10) NOT NULL default '0',
+ `pagename` varchar(255) NOT NULL default '',
+ `timemodified` int(10) NOT NULL default '0',
+ PRIMARY KEY (`id`)
+) TYPE=MyISAM COMMENT='Holds entries for each wiki start instance.';
+
+
+CREATE TABLE `prefix_wiki_pages` (
+ `pagename` VARCHAR(160) NOT NULL,
+ `version` INTEGER UNSIGNED NOT NULL DEFAULT 0,
+ `flags` INTEGER UNSIGNED DEFAULT 0,
+ `content` MEDIUMTEXT,
+ `author` VARCHAR(100) DEFAULT 'ewiki',
+ `created` INTEGER UNSIGNED DEFAULT 0,
+ `lastmodified` INTEGER UNSIGNED DEFAULT 0,
+ `refs` MEDIUMTEXT,
+ `meta` MEDIUMTEXT,
+ `hits` INTEGER UNSIGNED DEFAULT 0,
+ `wiki` int(10) unsigned NOT NULL,
+ PRIMARY KEY id (pagename, version, wiki)
+) TYPE=MyISAM COMMENT='Holds the Wiki-Pages';
--- /dev/null
+Who worked on ErfurtWiki
+========================
+(please note that all mail addresses are 'beautified')
+
+
+Mario Salzer <mario*erphesfurt·de> [http://mario.erphesfurt.de/]
+
+ - original author, current maintainer
+
+
+Andy Fundinger <andy*burgiss·com> [http://www.burgiss.com/]
+
+ - compatibility fixes for PHP.A/W32, notify: address protection for info/
+ - markup_css_singleat, action_extracttodo
+ - spellcheck2, phplib_auth, title_calendar
+ - navbar, aview_posts
+ - LiveUser authentication / permission framework plugin
+
+
+Carsten Senf <ewiki*csenf·de> (from Erfurt)
+
+ - db_flat_files.php bugfixes for Win32 systems
+ - calendar.php, db_fast_files.php` code
+ - page_since_updates.php
+
+
+Alex Wan <alex*burgiss·com> [http://www.burgiss.com/]
+
+ - LiveUser framework auth plugin,
+ log viewing plugin
+
+
+Jeremy Mikola <jmikola*arsjerm·net> [http://www.burgiss.com/]
+
+ - aview_piclogocntl, the Burgiss Groups` LiveUser framework auth plugin
+
+
+Culley Harrelson <cully*fastmail·fm>
+
+ - fixes for html code generation bugs,
+ various feature requests
+
+
+Hans B. Pufal <hansp*aconit·org> [http://www.aconit.org/]
+
+ - various enhancements, bugfixes
+ - mpi_calendar
+ - mpi_environment
+ - mpi_plugins
+ - mpi_page_flags
+ - markup_complextbl
+
+
+Vladimir Támara <vtamara*users.sourceforge·net>
+
+ - Spanish translation of core messages and
+ the basic init-pages/
+
+
+Frank 'Sigi' Luithle <sigi*fsinfo.cs.uni-sb·de>
+
+ - contributed the wiki_format.inc (reduced rendering core)
+
+
+Beate Paland <bep*web·de> [http://www.paland.tv/]
+
+ - bug notices and many helpful suggestions
+ (constantly demanded for <pre> support)
+ - phpCMS integration, see http://www.paland.tv/...
+
+
+Markus Ackermann <maol*symlink·ch> [http://www.symlink.ch/]
+
+ - bug reports, improvement suggestions
+
+
+Dominik Eckardt <the.oberon*gmx·de>
+
+ - suggested the TAB indentation
+ (while now SPACEs are supported)
+
+
--- /dev/null
+Information on how to install and use ErfurtWiki can be found in the
+README, this file only contains notes for the impatient:
+
+Quick Test Installation
+=======================
+
+- just move this newly extracted directory into your webservers docroot:
+ mv ewiki-R1.00f7 /var/www/wiki
+
+- then edit the "config.php" file, you may need to set the correct
+ parameters to access your MySQL database server (db user name and
+ password, and select a database different from "test")
+
+- just go to http://localhost/wiki/
+ (or whereever you did put the files)
+
+
+Warning
+=======
+
+Simply installing these files unchanged onto a public webserver is a bad
+idea, at least the tools/ subdir should be password-protected!
--- /dev/null
+
+ErfurtWiki - a fast, user-friendly, highly configurable Wiki engine in PHP
+==========================================================================
+
+
+README
+¯¯¯¯¯¯
+This is the documentation for ewiki. I tries to describe nearly everything,
+but therefore has now grown to long to be read at once. However it is often
+sufficient to just read the first few paragraphs to set it up (plugins can be
+activated at any later time). If you have the Wiki running, then you can also
+read this file in hypertext format.
+
+
+ 1 What is this?
+ 1.1 Why "ErfurtWiki"?
+ 1.2 WikiAlternatives
+ 1.3 Authors
+ 1.4 Project pages
+ 1.5 Obtaining support
+ 1.6 License
+ 1.7 Known Bugs
+
+ 2 HowTo
+ 2.1 Integration with yoursite.php
+ 2.1.1 Creating a "config.php"
+ 2.1.2 Generation of a "monsterwiki.php" script
+ 2.1.3 What to do if images don't work
+ 2.2 Supplying the WikiPageName
+ 2.2.1 mod_rewrite or PATH_INFO
+ 2.2.2 use with the 404 trick
+ 2.3 Security considerations
+ 2.3.1 PHP settings (register_globals)
+ 2.3.2 _protected_mode
+ 2.4 simple usage restrictions via wrappers
+ 2.5 PhpWiki compatibility
+ 2.5.1 Transition from another WikiWare
+ 2.6 Idea Collection
+ 2.6.1 Multiple Wikis / InterWiki feature abuse
+
+ 3 Internals
+ 3.1 the ewiki_ functions
+ 3.2 $GLOBALS pollution
+ 3.3 the EWIKI_ constants
+ 3.4 $ewiki_config array
+ 3.5 internal coding explained
+ 3.5.1 how ewiki operates
+ 3.5.2 used variables
+
+ 4 Tweaking
+ 4.1 Using the wiki source transformation only
+ 4.2 Customizing ewiki_format()
+ 4.3 Customization using CSS
+ 4.3.1 user style classes in pages
+ 4.3.2 rendered page content
+ 4.3.3 pages enclosed in style classes
+ 4.3.4 plugin output styling
+
+ 5 Explanations
+ 5.1 Binary and text support
+ 5.1.1 Image uploading
+ 5.1.2 Image caching
+ 5.1.3 Image WikiMarkup
+ 5.1.4 binary_store, direct access
+ 5.1.5 Arbitrary binary content
+ 5.2 $action and $id
+ 5.2.1 ewiki URLs
+
+ 6 Everything in one script
+ 6.1 database plugins
+ 6.1.1 MySQL support
+ 6.1.2 plugins/db/flat_files (IMPORTANT)
+ 6.1.3 plugins/db/fast_files
+ 6.1.4 plugins/db/any
+ 6.1.5 plugins/db/adodb
+ 6.1.6 plugins/db/dba
+ 6.1.7 plugins/db/phpwiki13
+ 6.1.8 plugins/db/binary_store
+ 6.2 core enhancements
+ 6.2.1 plugins/patchsaving
+ 6.2.2 plugins/notify
+ 6.2.3 plugins/jump
+ 6.2.4 plugins/email_protect
+ 6.2.5 plugins/spages (StaticPages)
+ 6.2.6 plugins/pluginloader
+ 6.2.7 plugins/init
+ 6.2.8 plugins/feature/appendonly.php
+ 6.2.9 plugins/feature/imgresize_gd.php
+ 6.2.A plugins/feature/imgresize_magick.php
+ 6.2.B plugins/feature/spellcheck.php
+ 6.3 action/ plugins
+ 6.3.1 plugins/action/diff.php
+ 6.3.2 plugins/action/translation.php
+ 6.3.3 plugins/action/like_pages.php
+ 6.3.4 plugins/action/raw.php
+ 6.4 plugins related to hypertext links
+ 6.4.1 plugins/linking/tcn
+ 6.4.2 plugins/linking/plural
+ 6.4.3 plugins/linking/autolinking
+ 6.4.4 plugins/linking/link_css
+ 6.4.5 plugins/linking/link_icons
+ 6.4.6 plugins/linking/link_target_blank
+ 6.4.7 plugins/linking/linkexcerpts
+ 6.4.8 plugins/linking/linkdatabase
+ 6.4.9 plugins/linking/instanturls
+ 6.4.A plugins/linking/titlefix
+ 6.4.B plugins/interwiki/intermap
+ 6.5 appearance/ tweaks
+ 6.5.1 plugins/appearance/listpages_br
+ 6.5.2 plugins/appearance/listpages_ul
+ 6.5.3 plugins/appearance/listpages_tbl
+ 6.5.4 plugins/appearance/fancy_list_dict
+ 6.5.5 plugins/appearance/title_calendar.php
+ 6.6 page/ plugins
+ 6.6.1 plugins/page/powersearch
+ 6.6.2 plugins/page/pageindex
+ 6.6.3 plugins/page/wordindex
+ 6.6.4 plugins/page/imagegallery
+ 6.6.5 plugins/page/aboutplugins
+ 6.6.6 plugins/page/orphanedpages
+ 6.6.7 plugins/page/wantedpages
+ 6.6.8 plugins/page/since_updates
+ 6.6.9 plugins/page/textupload
+ 6.6.A plugins/page/wikidump
+ 6.6.B plugins/page/interwikimap
+ 6.6.C plugins/page/hitcounter
+ 6.6.D plugins/page/scandisk
+ 6.6.E plugins/page/wikinews
+ 6.6.F plugins/page/wikiuserlogin
+ 6.6.G plugins/page/randompage
+ 6.6.H plugins/page/fortune
+ 6.6.J plugins/page/ewikilog
+ 6.6.J plugins/page/phpinfo
+ 6.6.K plugins/page/README
+ 6.7 markup/ plugins
+ 6.7.1 Other WikiWares markup
+ 6.7.2 plugins/markup/css
+ 6.7.3 plugins/markup/css_singleat
+ 6.7.4 plugins/markup/footnotes
+ 6.7.5 plugins/markup/asciitbl
+ 6.7.6 plugins/markup/complextbl
+ 6.7.7 plugins/markup/htmltbl
+ 6.7.8 plugins/markup/rescuehtml
+ 6.7.9 plugins/markup/rendering_phpwiki12
+ 6.7.A plugins/markup/rendering_null
+ 6.8 mpi
+ 6.8.1 mpi_backlinks
+ 6.8.2 mpi_multimedia
+ 6.8.3 mpi_syndicate
+ 6.8.4 mpi_insert
+ 6.8.5 mpi_localsitemap
+ 6.9 visual extensions
+ 6.9.1 plugins/aview/backlinks
+ 6.9.2 plugins/aview/linktree
+ 6.9.3 plugins/aview/toc
+ 6.9.4 plugins/aview/posts
+ 6.9.5 plugins/aview/threads
+ 6.9.6 plugins/aview/subpages
+ 6.9.7 plugins/aview/downloads
+ 6.9.8 plugins/aview/imgappend
+ 6.9.9 plugins/aview/piclogocntrl
+ 6.9.A plugins/aview/aedit_pageimage
+ 6.9.B plugins/aview/control2
+ 6.9.C plugins/aview/aedit_authorname
+ 6.9.D plugins/aview/aedit_deletebutton.js
+ 6.A page filters
+ 6.A.1 plugins/filter/f_fixhtml
+ 6.A.2 plugins/filter/search_highlight
+ 6.A.3 plugins/filter/fun_chef
+ 6.A.4 plugins/filter/fun_upsidedown
+ 6.A.5 plugins/filter/fun_wella
+ 6.A.6 plugins/filter/fun_screamomatic
+ 6.A.7 plugins/filter/f_msiepng
+ B.9 BloatWiki extensions
+ 6.B.1 plugins/module/calendar
+ 6.B.2 plugins/module/downloads
+ 6.B.3 plugins/module/tour
+ 6.C utility code
+ 6.C.1 plugins/lib/cache
+ 6.C.2 plugins/lib/speed
+ 6.C.3 plugins/lib/mime_magic
+ 6.C.4 plugins/lib/navbar
+ 6.C.5 plugins/lib/protmode
+ 6.C.6 plugins/lib/save_storevars
+ 6.D admin/ plugins
+ 6.D.1 control
+ 6.D.2 SearchAndReplace
+ 6.D.3 SearchCache
+ 6.E other plugins
+ 6.E.1 plugins/debug/
+ 6.E.2 plugins/auth/
+ 6.E.3 plugins/auth-liveuser/
+ 6.F separate "extra" tarball
+
+ 7 More separate files
+ 7.1 Pages in init-pages/
+ 7.2 Additional tools/ (IMPORTANT)
+ 7.2.1 tools/t_flags
+ 7.2.2 tools/t_backup
+ 7.2.3 tools/t_restore
+ 7.2.4 tools/t_remove
+ 7.2.5 tools/t_holes
+ 7.2.6 tools/t_textinsert
+ 7.2.7 tools/t_transfer
+ 7.2.8 tools/t_revert
+ 7.2.9 tools/ewikictl
+ 7.2.A tools/wiki2html
+ 7.2.B tools/mkhuge
+ 7.2.C tools/mkpluginmap
+ 7.2.D tools/mkpageplugin
+ 7.3 examples/
+ 7.3.1 examples/homepage.php
+ 7.4 Nice things in fragments/
+ 7.4.1 strip_wonderful_slashes.php (IMPORTANT)
+ 7.4.2 strike_register_globals.php
+ 7.4.3 404finder.php
+ 7.4.4 htaccess
+ 7.4.5 binary.php
+ 7.5 fragments/funcs/*
+ 7.5.1 fragments/funcs/wiki_format.inc
+ 7.5.2 fragments/funcs/auth.php
+ 7.6 fragments/css/*
+ 7.7 fragments/blocks/*
+ 7.8 fragments/patches/*
+ 7.9 How to deal with tweaked code
+
+ 8 Extension HowTo
+ 8.1 the PlugInterface
+ 8.2 plugin tasks
+ 8.2.1 mpi plugins
+ 8.2.2 authentication/permission plugins
+ 8.3 writing your own plugin
+ 8.4 format_* / rendering plugins
+ 8.4.1 ewiki_format() internals
+ 8.4.2 the format_ plugin hooks
+ 8.4.3 $iii[] and $ooo[] block flags
+
+
+
+
+
+
+
+ -------------------------------------------------------------------- 1 --
+
+
+
+What is this?
+¯¯¯¯¯¯¯¯¯¯¯¯¯
+This is a WikiWikiWeb engine implemented in the PHP web scripting
+language. A WikiWiki is a web site which can be edited by everybody
+who visits it (most commonly without requiring that user to register
+before).
+
+It should allow easy integration into an existing web site (portal
+or homepage / CMS-like software), as it is more a library and does
+not output a full .html page but instead just the formatted wiki
+text for inclusion in your pages` body/content area.
+
+
+
+Why "ErfurtWiki"?
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+My home town (Btw, Erfurt is next to Weimar.de) and really that's
+just a name (you're allowed to rename, extend it and to finally
+ship it GPLifyed). You'll soon see the internal name is "ewiki",
+and it is also sometimes called 'EmbeddableWiki'.
+
+
+If you asked - Why you should I use it?
+
+ - It is contained within a single file. It does not require 20 other
+ files to lie around between your own scripts.
+
+ - It does not impose a pre-defined layout, and you do not need
+ to customize it either as it nicely integrates with your sites`
+ layout.
+
+ - I think it's rather fast. It uses regexs too, but most of the
+ ewiki_format() uses the simple and quick string functions.
+
+ - It got rather featureful, the final release seems near :)
+
+
+
+WikiAlternatives
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+If you don't like ewiki, then try at least one of these:
+
+* PhpWiki has a more complete approach than this WikiWare,
+ get it from http://freshmeat.net/projects/phpwiki,
+ it has support for different database types, features localization
+ and comes with an integrated admin area.
+
+* WakkaWiki by Hendrik Mans is also a very powerful PHP implementation,
+ see http://www.wakkawiki.com/
+
+* Miki is another nice (small) implementation in PHP from Jukka
+ Zitting. Get it from http://miki.sourceforge.net/
+
+* Finally sfWiki - the sourceforge Wiki (therefore can be found on
+ http://sfwiki.sourceforge.net/). Some of its wiki syntax looks
+ a bit weird (other parts were inspiring), but it features complex
+ user authentication.
+
+* coWiki - completely OOP and the source code layout is great; looks
+ very featureful, but is more a CMS than a Wiki (authentication bloat)
+ and has also a little weird markup,
+ but better check it out yourself on http://cowiki.org/
+
+* And of course there are Wikis in other scripting languages (and yes,
+ there is still demand for an implementation in assembler or C !!)
+ http://www.freshmeat.net/search/?q=wiki§ion=projects or just
+ have a look at http://www.google.com/search?q=wiki
+
+* However, the BEST PLACE to look for evil concurrent implementations is
+ http://c2.com/cgi/wiki?WikiEngines
+
+
+
+Authors
+¯¯¯¯¯¯¯
+current maintainer: Mario Salzer <mario*erphesfurt·de> icq95596825 (+Yah,Jab)
+main contributor: Andy Fundinger <andy*burgiss·com> from http://burgiss.com/
+
+For the complete list of authors and contributors please see the CREDITS
+file.
+
+This project is still in an early stage, to improve it further we need
+to know what doesn't work or what could be enhanced. Every mail is a
+contribution (yep, that is not measured in lines of source code).
+
+
+
+Project Pages
+¯¯¯¯¯¯¯¯¯¯¯¯¯
+official freshmeat project page:
+- http://freshmeat.net/projects/ewiki
+
+demo site:
+- http://erfurtwiki.sourceforge.net/
+
+newest versions (unstable development releases):
+- http://erfurtwiki.sourceforge.net/downloads/
+
+mailing list archive
+- http://www.freelists.org/archives/ewiki/
+
+
+
+Obtaining Support
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Getting support for problems with ewiki is possible, but please read this
+README first. The author is thankful for BugReports, and of course would
+like to know were this documentation is not detailed enough and fails to
+explain things clearly.
+However, before you send requests to anyone, please visit following site
+(this is necessary to get FREE support):
+
+http://www.catb.org/~esr/faqs/smart-questions.html
+
+Then please feel free to contact the author or leave notes on the BugReports
+or UserSuggestion pages on our project site.
+Joining our http://erfurtwiki.sourceforge.net/?MailingList would allow you
+to reach a larger audience for your questions (and you can unsubscribe as
+soon as your problems are solved).
+
+
+
+License
+¯¯¯¯¯¯¯
+This "program" is "distributed" as "Public Domain". Public Domain
+is like "FreeWare", but a bit more free ;-> You can think of it
+as the GPL without being bound to the GPL. <note> I didn't want to
+include a LICENSE file larger than the program itself. </note>
+
+As this is a free (beer) piece of software, you cannot make me
+responsible for any BUGS or all the REALLY BAD HARD DISK DAMAGES ;-P
+it may lead to.
+
+Additional note: a few plugins contain GPL code, and therefore must be
+downloaded separately (mime_magic.php, rendering_phpwiki12.php).
+
+
+
+Known Bugs
+¯¯¯¯¯¯¯¯¯¯
+Currently none. But this note is just here to encourage you to visit
+http://erfurtwiki.sourceforge.net/?BugReports
+
+
+
+
+
+ -------------------------------------------------------------------- 2 --
+
+
+
+
+HowTo
+¯¯¯¯¯
+the ewiki script requires:
+
+- Webserver (Apache, Nanoweb, ...)
+- PHP 4.1 or later
+- a SQL database (works faster if you have one)
+- your existing web site layout
+- older PHP's wonderful magic slashes should really be disabled
+
+If you don't have the database, there is an add-on for flat-file
+usage (search this document for "db_flat_files" for notes on how to
+get this running).
+
+
+
+Integration with yoursite.php
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+For the next few paragraphs the "yoursite.php" refers to whatever
+files and/or scripts belong to your already existing website. This
+hypothetical script should at least output the <html><body> tags
+around the output from ewiki. The most simple script to accomplish
+this could look like this (see also example-2.php):
+
+ <HTML>
+ <BODY>
+ <?php
+
+ mysql_connect("localhost", "DB-USER-NAME", "PASSWORD"); #[1]
+ mysql_query("use DATABASE-NAME-HERE");
+
+ define("EWIKI_SCRIPT", "yoursite.php?page="); #[2]
+ error_reporting(0); #[3]
+
+ include("ewiki.php"); #[4]
+
+ echo ewiki_page(); #[5]
+
+ ?>
+ </BODY>
+ </HTML>
+
+[1] The first two commands open a connection to your MySQL database,
+usually one saves the result of mysql_connect() in a variable named
+$db or so, but as PHP does not depend on it if there is only one
+single database connection, it is not used in "ewiki.php" at all.
+
+[2] The define line tells ewiki about the hyperlinks it shall
+create.
+
+[3] The error_reporting(0) is highly encouraged (but something similar
+is already built into the ewiki.php script).
+
+[4] The include("ewiki.php") finally loads the ewiki "library" and sets
+any EWIKI_ constants that have not already been defined here.
+
+[5] The final call to the ewiki_page() function returns the wiki page
+which was requested by the browser. You must prepend it with
+"echo" because the ewiki_page() function just returns a <html> enhanced
+string but does not output that one itself.
+
+
+
+ Creating a "config.php"
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Instead of including the plain "ewiki.php" script as shown in the
+ example above, many people may find it more useful to include()
+ a more customized Wiki yoursite.
+
+ Customization of ewiki takes place, by pre-defining() some of the
+ EWIKI_ configuration settings and loading extension plugins. To
+ not move that work and code into yoursite it is recommended to
+ create some sort of "config.php" script, which then contained the
+ various define() and include() commands.
+ It is sometimes even senseful to establish the database connection
+ (if you use SQL and not the flat_files backend) inside of such a
+ config script, if there wasn't already established in yoursite.
+
+ So such a config.php script could contain:
+ - multiple define() commands, setting ewiki behaviour constants
+ - include() comands to load extension plugins
+ - evtl. some include() and define() for the db_flat_files plugin
+ (if you don't have a SQL database)
+ - and last but not least, the include("ewiki.php") script
+
+ If you then include() such a config.php, you get a fully functional
+ and preconfigured Wiki to include into yoursite. By using this
+ approach, you still could override some of the EWIKI_ settings with
+ additional define() constants right before the include("config.php").
+
+ <?php
+ include("includes/ewiki/myconfig.php");
+ ?>
+ <HTML>
+ <BODY>
+ <?php
+ echo ewiki_page();
+ ?>
+ </BODY>
+ </HTML>
+
+ Note: Please don't get confused by the path names, you of course
+ needed to use a subdirectory specification like "ewiki/" before
+ every filename specified in these include() commands, if this was
+ the dir you put all the ewiki scripts.
+
+
+
+ Generation of a "monsterwiki.php" script
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ ewiki over the time grow larger, and nowadays isn't anymore the
+ single script it once was. The distribution ships with over hundreds
+ of extension plugins. But nevertheless it is still possible to build
+ a single script from it all!
+
+ That being said, the "ewiki.php" script still implements a fully
+ functional Wiki (and just only lacks the advanced features supplied
+ the plugins). - You could still just include() the "ewiki.php"
+ script into yoursite and delete everything else the ewiki tarball
+ contained.
+
+ However, it is also possible to MERGE all wanted plugins and the
+ core script together to built a customized (feature enhanced) Wiki
+ script from it. All you needed to do was:
+
+ /unix/$ cat ewiki.php plugins/*.* > monsterwiki.php
+ C:/dos/ type ewiki.php plugins/*.* > monsterwiki.php
+
+ This way you'd get the "monsterwiki.php" file, which contained the
+ ewiki core script plug all plugins - but of course, you should only
+ copy the ones in, you really need and want (but not "*.*" all as
+ shown in the example above)!
+
+ The UNIX shell script "tools/mkhuge" will do exactly that for you;
+ it accepts a parameter from 0 to 3, which will merge a custom set
+ of useful plugins into the then generated "monsterwiki.php" script.
+
+ If you have built a "monsterwiki.php" script, you can include() this
+ instead of the minimal "ewiki.php" into yoursite to integrate a Wiki.
+
+ Eventually you'd also want to merge some configuration settings into
+ this monsterwiki script, so you wouldn't have to put the define(...)
+ commands into yoursite.php before you include("monsterwiki.php");
+ The define() commands however need to be the very first part merged
+ into that monsterwiki script, so it's best to edit the monsterscript
+ after generation and insert the appropriate settings then at the
+ very beginning.
+ You could also merge a (reduced!) "config.php" into the script,
+ using the above "cat" (or "type" for DOS/Win) method. But beware,
+ that this "config.php" then does not contain any include() command;
+ because else the resulting "monsterwiki.php" script would then try
+ to load the "ewiki.php" core script and plugins which were probably
+ already merged in. Even if you merge such a minimal config script
+ at the start of this monsterwiki script, you still could override
+ some settings (at least establishing the database connection) from
+ within yoursite, if you think it's useful.
+
+ Additional note: You could still include() plugins, if you included()
+ such a monsterwiki script into yoursite, provided that the plugin
+ you try to include() wasn't already merged into that monsterwiki.php
+ script before (else it would crash the PHP interpreter, because
+ loading it twice is once too much).
+
+ StaticPages (read about "spages" plugin) can also be included, if
+ you first convert them into ordinary ["page"] plugins using the
+ 'mkpageplugin' commandline tool.
+
+
+
+ What to do if images don't work
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The first example, as well as the "example-2.php" have problems with
+ binary content, because: the <HTML> is output before the 'ewiki.php'
+ library was loaded and got the chance to output pictures.
+
+ So one should better rewrite the above example yoursite.php script to:
+
+ <?php
+ mysql_connect(":/var/run/mysqld/mysqld.sock", "USER", "PW");
+ mysql_query("use DBNAME");
+
+ define("EWIKI_SCRIPT", "yoursite.php?page=);
+ error_reporting(0);
+
+ include("ewiki.php");
+
+ $content = ewiki_page();
+ ?>
+ <HTML>
+ <HEAD>
+ <TITLE><?php echo $ewiki_title; ?>
+ </HEAD>
+ <BODY>
+ <?php
+ echo $content;
+ ?>
+ </BODY>
+ </HTML>
+
+ Please again, note the initial <?php part before the very first plain
+ HTML output - yoursite.php must really start with it, or else binary
+ content (uploaded images) won't work!
+
+ You could, of course write a "binary.php" besides "yoursite.php", to
+ get around this problem; please see fragments/ for an example.
+
+
+
+Supplying the WikiPageName
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+If you just call ewiki_page() as shown in the first example, it will
+try to get the name of the requested WikiPage either from the
+$_SERVER["PATH_INFO"] variable or from one of the GET-variables '?id='
+or '?name=' or '?page=' or '?file=' (available as $_REQUEST["name"]).
+If yoursite.php however uses another way or another varname to receive
+the WikiPageName you can just give it as first parameter:
+
+ ewiki_page( $id = "WikiPageName" );
+
+example-4.php shows how this can be used to list a second WikiPage
+(the list of newest pages) somewhere else on yoursite.php.
+
+
+
+ mod_rewrite or PATH_INFO
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ If you dedicate a complete directory for your wiki, you should keep
+ in mind, that some of the generated URLs contain slashes (for
+ example "edit/WikiPage"), and will look like subdirectories and thus
+ confuse browsers.
+
+ So you should either set EWIKI_SCRIPT to the absolute directory
+ containing your wiki wrapper script: define(EWIKI_SCRIPT,
+ "http://myserver/wiki/"); or else put a <BASE HREF="..."> into the
+ generated pages. Take this precaution because some of the generated
+ links contain additional slashes (like "edit/ThisPage") and thus may
+ make browsers believe in a changed subdirectory.
+
+ This applies to mod_rewrite usage and if you call your wiki wrapper
+ with the page name as PATH_INFO (like "/wiki/index.php/WikiPage").
+
+ Do not forget to enable EWIKI_USE_PATH_INFO, as it is per default
+ disabled for Apache servers! Also check, if EWIKI_URLENCODE and
+ _URLDECODE suit your needs, else you will find it useful to have URL
+ generation encapsulated in the ewiki_script() function.
+
+
+
+ use with the 404 trick
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Once I implemented a way to run a web server below another one
+ (actually Nanoweb below Apache, for more details see
+ http://nanoweb.si.kz/), because the Apache on one of my providers
+ servers was heavily misconfigured - so I handed work over to a
+ secondary WebServer.
+
+ This trick also works without mod_rewrite support, and is therefore
+ also well suited for cheap WebSpace. Put following into the
+ .htaccess of the dedicated wiki directory:
+
+ #-- handle "not found" pages by ewiki
+ ErrorDocument 404 /wiki/index.php
+ DirectoryIndex 404 index.php
+
+ This will allow the "yoursite.php/ewiki.php" script to catch all
+ missed files, which would usually trigger a 404 error. Inside your
+ ewiki wrapper script, you must then however decode the originally
+ requested URL:
+
+ $url = $_SERVER["REQUEST_URL"]; # Apache often uses this one
+ $url = preg_replace("#^/wiki#", "", $url); # strip wiki subdir name
+ $_SERVER["PATH_INFO"] = $url; # make ewiki see it
+
+ The second step is very important, it strips the name of the
+ dedicated subdirectory from the URL, which cannot be done inside
+ ewiki.php.
+
+ The $url from the above example could also be used as $id
+ parameter to ewiki_page().
+
+ It should be noted, that some Apache implementations are garbaging
+ POST requests in case of a triggered 404 error - but you can simply
+ test this by saving a changed WikiPage.
+
+ See also the "fragments/404finder.php" example on this.
+
+ Do not forget to enable EWIKI_USE_PATH_INFO, as it is per default
+ disabled for Apache servers!
+
+
+
+
+
+
+Security considerations
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ewiki was developed using a PHP5 interpreter, but with limitations of PHP4.3
+in mind. There are huge differences (a rather instable, bug-prone and still
+unfinished language) across the 4.x versions of PHP. The 4.0 series is not
+enough to run ewiki, you'll need at least a PHP 4.1 (4.07) to make it work
+reliable.
+
+One must also know, that there are also differences between the settings of
+providers. Some for example enforce users to run their scripts in so called
+"safe mode" (crippled mode) in place of real server security guidelines.
+Other still use pre-4.3 settings for the PHP interpreter (the Win4 php.ini
+still is outdated). So take care, and adjust settings using .htaccess`
+php_option for Apache servers.
+
+
+
+ PHP settings (register_globals)
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Because ewiki was developed on later PHP versions (at least 4.3), it
+ heavily uses the $_REQUEST array and assumes a deactivated
+ "register_globals" setting in php.ini
+ If this is not the case for your setup / WebServer. or with your
+ provider the ewiki.php script may expose a lot security leaks
+ (because of uninitialized variables).
+
+ ewiki in general does only use a few global variables, but especially
+ the $ewiki_ring variable (which is used for PROTECTED_MODE) can lead
+ to problems, if you use it without an existing authentication
+ concept. The $ewiki_plugins is also a very complex task, and I
+ cannot safely state that it won't be able to produce exploits, if
+ the variable is tweaked externally (pushed into by a client).
+
+ So the best thing you could do is to disable register_globals (this
+ can be done from inside a directories .htaccess file by inserting
+ the line "php_option register_globals off").
+
+ A fragments/ include will be added to strike against variables which
+ got set from outside (this is rather easy for variables used by
+ ewiki, because their names all start with "$ewiki_").
+
+
+
+ The two modes of operation (_protected_mode and _flat_real_mode)
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ While this wiki was originally developed as a real wiki, many people
+ use it for different things now, like private HomePages, easy CMS on
+ commercial web sites.
+
+ This fact lead to the support of a restricted operation mode, now
+ known as the _PROTECTED_MODE. It is often used to require people to
+ log in before they can edit pages or upload things. In this README
+ this mode of operation will often be referred to also as the
+ 'crippled mode'. It is completely optional, and doesn't have any
+ impact on speed, when left disabled.
+
+ Btw, the standard ewiki operation mode is
+ now known as the _FLAT_REAL_MODE.
+
+ If you'd like to use authentication, you'll probably want to chain
+ some plugins which enable you to use the user database from
+ yoursite.php, so you do not need a separate .htaccess or an
+ additional relational database for passwords. Please see the section
+ on auth plugins.
+
+ See also the EWIKI_PROTECTED_MODE configuration constant and the
+ separate "plugins/auth/README.auth" file for further and more
+ detailed informations on this feature.
+
+
+
+simple usage restrictions via wrappers
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+The easiest way to cripple a Wiki setup to be browseable-only for the larger
+public, and to allow only a small subset of users to edit pages is to write
+two wrapper scripts around the ewiki.php library.
+
+One of the wrapper scripts should include and use ewiki as described in the
+"Integration with yoursite.php" paragraph. You may want to move this wrapper
+script into a password protected subdirectory (say "/wikiadmin/index.php").
+
+Another wrapper script should then be provided for the users that are only
+allowed to view pages. To disallow editing you'll just have to enrich it
+with commands like:
+
+ unset($ewiki_plugins["action"]["edit"]); # disables editing
+ unset($ewiki_plugins["action"]["info"]); # no info/ action
+ unset($ewiki_plugins["page"]["SearchPages"]); # no search function
+ unset($ewiki_plugins["action"]["view"]); # kill wiki completely
+
+This code must occur after you have 'included("ewiki.php");' the library,
+but before you call the 'ewiki_page();' function, so the unwanted actions
+and pages really do not get activated.
+
+So far the basic approach. If you however have real user authentication
+code behind the scenes you probably don't want to maintain two different
+wrapper scripts. You'll then just put the functionality stripping code
+from above into an if-clause in "yoursite.php" like:
+
+ if (! $user_is_logged_in) {
+ unset($ewiki_plugins["action"]); # (do it less destructive ;)
+ }
+
+Note: this is again an example, DO NOT copy&paste examples and assume
+they'll work for you!
+
+
+
+PhpWiki compatibility
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+The MySQL database table is partially compatible to PhpWiki versions 1.2.x,
+but not with the current PhpWiki 1.3.x versions. There is however now the
+db_phpwiki13 plugin which allows to access those (rw).
+
+
+
+ Transition from another WikiWare
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ If you choosed ewiki to replace an already existing wiki script on
+ your site, you should first think about, that the syntax/WikiMarkup
+ isn't equal across all Wikis. There are a few markup extension
+ plugins, that may help you around this, but beware that transition
+ with a larger collection of WikiPages won't be very easy.
+
+ The best way to import the old WikiPages to ewiki, is to first
+ export it using the tools of the previous WikiWare. You can then
+ just put the produced text/plain PageSource into "init-pages/",
+ because all files found therein (note, that there shouldn't be any
+ file name extension like .txt) are feed directly into the ewiki
+ database, when ewiki is run for the very first time (when the
+ EWIKI_PAGE_INDEX is not found in the db).
+
+ There is a "plugins/db_phpwiki13.php" which may be useful in first
+ trying ewiki, but it is not recommended to use it for daily work.
+ Speaking of PhpWiki you could also use the "tools/t_convertdb.php"
+ to import (and markup convert) all pages from PhpWiki to the ewiki
+ database format.
+
+
+
+
+
+
+ -------------------------------------------------------------------- 3 --
+
+
+
+
+Internals
+¯¯¯¯¯¯¯¯¯
+The MySQL database table structure is to a certain degree compatible
+with that of the well known »PHPWiki« v1.2.x (you only need to change
+EWIKI_DB_TABLE_NAME to "wiki" to use it). This is the MySQL statement
+which creates our database table (you can find it at the bottom of the
+"ewiki.php" script):
+ CREATE TABLE ewiki (
+ pagename VARCHAR(160) NOT NULL,
+ version INTEGER UNSIGNED NOT NULL DEFAULT 0,
+ flags INTEGER UNSIGNED DEFAULT 0,
+ content MEDIUMTEXT,
+ author VARCHAR(100) DEFAULT 'ewiki',
+ created INTEGER UNSIGNED DEFAULT 0,
+ lastmodified INTEGER UNSIGNED DEFAULT 0,
+ refs MEDIUMTEXT,
+ meta MEDIUMTEXT,
+ hits INTEGER UNSIGNED DEFAULT 0,
+ PRIMARY KEY id (pagename, version)
+ )
+
+I didn't like the column name {pagename} but as I've seen this was
+the only difference I renamed it, therefore now the ewiki_database()
+function translates it from "pagename" to "id" and vice versa most of
+the time - else this would be really slim and nice code :)
+
+The columns {version} holds the different saved page versions. Other
+Wikis require a secondary "backup" or "history" table for old versions,
+but as I couldn't imagine what this is for, there is just one table
+in ewiki; and it seems this is really enough. The first {version} of
+a wiki page is always numbered 1. An existing page {version} will
+never get overwritten => very secure MySQL usage.
+
+For what's in the {flags}, see the README section about constants. The
+{content} of course holds the wiki pages source. The {created} and
+{lastmodified} should be clear too.
+
+{refs} contains a "\n" separated list of referenced WikiPages. The
+code to generate that list is rather unclean, so it often contains
+GhostPages. However this does not hurt ewiki and the few functions
+that utilize {refs}, so there is currently no need to slow it down
+by fixing this.
+
+{meta} can hold additional informations, which allows to extend ewiki
+without requiring to ALTER and convert the ewiki database table. It
+currently holds some mime headers for binary content and some other
+useful informations for images and uploaded files.
+
+{hits} should have gone into {meta} really. But having it separate
+allows us to use the very fast mysql UPDATE function.
+
+Note, that the ewiki database table can hold other things than wiki
+pages - binary content (images) for example, depending on the setting
+of the {flags} field.
+
+And last comment about this, the one-table-concept also made it really easy
+to implement the flat file based "database backend".
+
+
+
+ewiki_ functions
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Some of the core functions of ewiki.php can be used separate from the
+others and some of them were designed to be replaced by different
+implementations.
+Btw, all the functions, constants and variables start with "ewiki_"
+to make it easier to mix it into other projects (reduces function name
+conflicts and similar problems, that usually arise if you join two
+or more scripts into one program).
+
+
+ ewiki_page($id)
+ ---------------
+ This is the main function which fetches the selected WikiPage
+ (or the one given with $id) via ewiki_database to transform
+ with ewiki_format().
+ If the requested page does not exist it returns the edit
+ screen.
+ It also includes some virtual pages (InfoAboutThisPage,
+ NewestPages, SearchPage, ReferencesToThisPage, ...).
+
+
+ ewiki_page_...()
+ ----------------
+ These functions were separated out from the main ewiki_page()
+ to make it more readable.
+ Most of them contain code to generate the few special/internal
+ WikiPages (Search, Newest, Info, and the Edit <FORM>, ...)
+
+
+ ewiki_control_links($id, $data)
+ -------------------------------
+ Prints the line with the EditThisPage and PageInfo, ... links.
+
+
+ ewiki_format($wiki_source, $params)
+ ----------------------------------------------------------
+ This returns the formatted (HTML) output for the given WikiSource
+ (with all the WikiMarkup in it).
+
+ The second param is an array with various config overrides. An entry
+ of "scan_links"=>1 for example tells ewiki_format to lookup the
+ referenced WikiPages in the database (see ewiki_scan_wikiwords) for
+ filling up $ewiki_links. Another $params entry is "html"=>0, which
+ controls interpetation of the <html>...</html> page content blocks.
+
+
+ ewiki_render_wiki_links(&$o)
+ ----------------------------
+ Transforms WikiLinks and square brackets in a page into html links.
+
+
+ ewiki_scan_wikiwords(&$wiki_source, &$ewiki_links)
+ --------------------------------------------------
+ work with regex on the wiki source text, to find valid WikiWords,
+ the $ewiki_links will be filled with informations if the found page
+ names exist in the DB.
+
+
+ ewiki_link_regex_callback()
+ ---------------------------
+ Called from ewiki_format(). To separate the ewiki_format() from
+ the database this function will utilize the global $ewiki_links
+ (generated on demand by ewiki_format) to output either a normal
+ link or a question-mark after the WikiPageName to signal a
+ non-existent page.
+
+
+ ewiki_script()
+ --------------
+ Builds the complete URL needed to access the given resource. This
+ function replaces/enhances the static EWIKI_SCRIPT constant and
+ unifies the generated URLs (less bugs). It also helps around
+ various design flaws (like nice looking URL strings), that made
+ some parts of ewiki a bit weird and unreliable in the past. Btw,
+ now the base URL is stored in $ewiki_config["script"].
+
+
+ ewiki_script_binary()
+ ---------------------
+ Is just a ewiki_script() wrapper, but can additionally distinguish
+ between binary download and upload URLs, which could be utilized by
+ (database external) plain file storages (see plugins/binary_store).
+
+
+ ewiki_binary()
+ --------------
+ Gets called automatically for requests with the ?binary= trailer
+ which is used to reference cached and uploaded images (or not
+ yet cached ones).
+
+
+ ewiki_author()
+ --------------
+ returns a string with REMOTE_ADDR and the $ewiki_author or a default
+ string incorporated
+
+
+ ewiki_auth()
+ ------------
+ Is a simple interface to a probably large collection of plugins,
+ which should to actual user and permission management. Support for
+ this in the core is however still sporadic.
+
+
+ ewiki_auth_user()
+ -----------------
+ Queries all registered user databases, and is usually itself called
+ from within an auth_method/auth_query plugin.
+
+
+ ewiki_t()
+ ---------
+ Fetches a text string from the $ewiki_t[] array and additionally adds
+ some text pieces into it (given as second param). It can retrieve
+ translations for registered abbreviations, or searches for complete
+ text fragment replacements. It also understands _{...} to recursively
+ translate a text snippet inside of larger text blocks.
+ This is probably a bit slower and less readable than the previous usage
+ of EWIKI_T_ constants, but it saves some memory and allows to extend
+ translations or additional text constants (of plugins) a lot more
+ easier (previously one had to edit inside a function, which is almost
+ impossible to do from outside / per configuration).
+
+
+ ewiki_make_title()
+ ------------------
+ Returns a string enclosing (the generated) page title (as link) into
+ the html title markup "<h2>". The $class parameter actually tells from
+ which plugin sort it was called, and this decides if a link will be
+ generated or the title will be unclickable plain text (the setting in
+ $ewiki_config["print_title"] is used to determine that). $go_action tells
+ which action to link the title to.
+
+
+ ewiki_chunked_page(...)
+ -----------------------
+ Is a helper function to split large results into multiple click-through
+ pages, and is used by info/ and some search functions/plugins. It only
+ produces the click-through links for inclusion on other dynamic pages,
+ allows overlapping of page chunk ranges.
+
+
+ ewiki_in_array($value, &$array, $dn=0)
+ --------------------------------------
+ Case-insensitive variant of PHPs` in_array(), returns the $value if
+ found. The $array will be all-lowercased afterwards (except when $dn
+ was set).
+
+
+ ewiki_array($array, $index=false, $am=1)
+ ----------------------------------------
+ Returns input-array lowercased (indices), or just the entry for the
+ $index if searched for. The $am decides if multiple entries should be
+ merged together (uppercase+lowercase merging produces overlaps).
+
+
+ ewiki_database($FUNCTION, $args=array() )
+ ------------------------------------------
+ This function is the "database abstraction" in ewiki. It contains
+ ''only'' eight SQL statements which must be replaced if you'd like
+ to use another database server. It is very stupid, and does not know
+ much about its database (keeping it extensible on the other hand),
+ therefore one must be careful when passing database entries to it.
+ The individual "atomic" functions are:
+
+ "GET", $args = array( "id"=>STRING, ["version"=>NUM] )
+ Fetches the newest wiki page incarnation from the database,
+ or alternatively the one given by version.
+
+ "WRITE", $args = array( COLUMN-NAME => VALUE, ... )
+ Saves the contents of the given data array in the database,
+ does _never_ overwrite an existing entry (you must keep track
+ of the {version} yourself).
+
+ "GETALL", $args = array( "COLUMN-1", "COLUMN-2", ... )
+ Fetches an array of all existing pages in the database, but
+ returns it as ewiki_dbquery_result object, which will throw
+ the requested columns on ->get(), where the entries 'id',
+ 'version' and 'flags' are always present.
+
+ "FIND", $args = array( "WikiPage1", "WikiPageName2", ... )
+ Searches the database for the queried page names, returns an
+ array which associates the boolean value (if pages found) with
+ their names
+
+ "SEARCH", $args = array( "COLUMN" => "CONTENT" )
+ Returns only those pages, where the database COLUMN has a content
+ that matches the requested value; the list of pages is returned
+ as ewiki_dbquery_result object, where you can access the
+ individual entries using the ->get() call, which will return the
+ columns 'id', 'version', 'flags' and the scanned COLUMN of course
+ unless you ->get("_ALL=1").
+
+ The following three actions are not required for correct operation,
+ but provide additional functionality for some plugins or tools.
+
+ "HIT", $args = array( "id"=>STRING )
+ Increases the hit counter of the given wiki page by 1,
+ what is not implemented in db_flat_file.
+
+ "OVERWRITE"
+ Is a wrapper to "WRITE" and does replace existing entries.
+
+ "DELETE", $args = array( "id"=>STRING, "version"=>NUM )
+ Removes the specified page (only the given version) from the
+ database; implemented in all database plugins but should be used
+ from within the tools/ only.
+
+ Other functions are usually used internally only, as for example the
+ "ALLFILES" command in dbff or dba/dbm plugins.
+
+
+ ewiki_dbquery_result
+ --------------------
+ Has the member variables $keys and $entries, where the latter
+ contains an array of page names that where triggered by your GETALL
+ or SEARCH request, and the $keys array contains the column names that
+ each subsequent "$result->get()" will return.
+
+ get()
+ Returns the database entry array (see GET above), but only the
+ fields the database query should return (at minimum these are
+ 'id', 'version' and 'flags' and the searched column for SEARCH).
+
+ get("_ALL=1")
+ Instead returns the complete entry.
+
+ count()
+ Returns the number of found database entries.
+
+ add($row)
+ [internal] This is used by the ewiki_database() core functions
+ to initialize the $result object with the found entries.
+
+
+
+$GLOBALS pollution
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+At least the ewiki_page() function produces variables in the
+global namespace. Of course they also were named to not interfere
+with anything from yoursite.php:
+
+ $ewiki_id - Contains the current page name, after ewiki_page()
+ was called.
+
+ $ewiki_action - Contains the $action/ForTheCurrentPage.
+
+ $ewiki_title - Will be set after the first call to ewiki_page(),
+ it is most useful to be printed inside the <TITLE>
+ tags inside <HEAD>. So if you want to use it you
+ should call ewiki_page() very early, but save its
+ output into a variable for later use. This way
+ you can make the current wiki pages` title available
+ (the _title may be different from the pages _id).
+
+ $ewiki_errmsg - Sometimes used to pass error notices back (ewiki_auth
+ does so for example).
+
+ $ewiki_links - Is an array produced by ewiki_format() that associates
+ all found WikiPageNames with a value of 0 or 1,
+ depending on if the referred page exists in the
+ database.
+
+ $ewiki_author - The content of this variable is saved in the author
+ field of newly created wiki pages (it will be filled
+ with IP:PORT if not set from outside). This is only an
+ informational setting, and does not directly correspond
+ to the _PROTECTED_MODE.
+ You should set it, whenever yoursite.php notes a logged in
+ user (so his login gets saved in the wiki pages 'author'
+ column). But you should REALLY NOT SPAM IT with your own
+ name or ad words.
+
+ $ewiki_auth_user - Is set by ewiki_auth_user() whenever it successfully
+ authenticates a user in _PROTECTED_MODE. This variable
+ is then used as reliable state setting, which affects
+ permission granting.
+
+ $ewiki_ring - Holds the permission level ('ring') of the currently
+ authenticated user (or else will be unset). This value
+ tells only about the user, many plugin functions have
+ built-in requirements which will be compared against
+ this value (no value or zero means full permissions).
+ While this is the built-in way to grant permissions
+ and often also suits the needs to do it, the _auth()
+ plugin interface allows to work at a much finer degree
+ of access granting.
+ values: 0=administrator, 1=moderator, 2=editor, 3=guest
+ See also plugins/auth/README.auth for more informations.
+
+ $ewiki_plugins - Is an array which connects task names (say "database"
+ or "image_resize" for example) to function names.
+ You can utilize this if you decide to extend ewiki.
+ There is an own chapter on this.
+
+ $ewiki_config - Imports some configuration settings from older constants,
+ and introduces newer ones, which can then be overridden at
+ runtime. Also holds some work and markup transform data.
+
+ $ewiki_t - Text definitions and translations for all possible
+ messages.
+
+ Things that disappeared again, and which are now part of the $ewiki_config
+ array instead include:
+
+ $ewiki_data - May reappear by setting a _config[] variable.
+
+ $ewiki_interwiki - Was errornously part of _plugins[] for some time.
+
+ $ewiki_script - Was a global var for a short period of time, but now is
+ a subentry in $ewiki_config.
+
+
+
+
+EWIKI_ constants
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+This chapter explains some of the constants and how you can utilize
+them to tweak some of ewiki's behaviour.
+
+The recommended way to change settings is to copy the define() commands
+from "ewiki.php" into "yoursite.php" (see our example "config.php"). This
+is a good idea, because then your settings won't get lost if you upgrade
+to a newer version by overwriting your tweaked "ewiki.php".
+
+ [Note: constants in PHP can be defined() once only, so
+ pre-defining them in "yoursite.php" or a "config.php"
+ script is nearly like a 'configuration']
+
+To define() some of those constants in 'yoursite.php' is especially a good
+thing, because some of them are more used like state variables and it may
+be more senseful to set them depending on informations only available in
+the scripts of yoursite.php (for example if yourscripts provide a way to
+authenticate and login a user you may give him additional rights within
+ewiki by pre-defining one of the following constants).
+
+
+ EWIKI_SCRIPT
+ This is the most important setting. It is used by ewiki.php
+ to generate links to other WikiPages.
+
+ It needs the name of yourscript.php which itself includes
+ ewiki.php.
+ The name of the linked WikiPage is just appended to the string
+ defined here, so you must ensure that it either ends in "/"
+ or "?id=" or "?name=" or "?page=" so it constructs a valid
+ URL after concatenation (or %s replaced) with the WikiPageName.
+
+ If you utilize mod_rewrite on your server, you may wish to
+ make it blank when all requests to http://wiki.example.com/
+ are redirected to the correct script by your WebServer.
+
+ If your wrapper script for example is called 'index.php' then you
+ can just set EWIKI_SCRIPT to "?page=" (which then refers to the
+ index.php of the current directory).
+ You should preferrably set it absolute to the servers DocumentRoot,
+ which gets a requirement if you'd like to give page names and actions
+ via PATH_INFO "/wiki.php/WikiPage" and not as QUERY_STRING "?id=".
+
+ Update: this constant will stay, but the core script now utilizes
+ the ewiki_script() function (which itself additionally respects
+ the $ewiki_config["script"] config variable in favour).
+
+ ewiki_script() introduces use of the "%s" placeholder inside
+ EWIKI_SCRIPT, which will be replaced by pagename and action, when
+ URLs are generated.
+
+ EWIKI_SCRIPT_URL
+ Some parts of ewiki require the absolute URL of the ewiki wrapper
+ script. So in contrast to the (often) short EWIKI_SCRIPT, this
+ constant MUST contain the protocol and server name, like:
+ "http://www.example.com/wiki/index.php?id="
+
+ If you do not set this constant, it will be guessed by the
+ ewiki_script_url() funciton, what often works but may be suboptimal
+ and could also lead to security problems.
+
+
+ EWIKI_DB_TABLE_NAME
+ Sets the name of the MySQL database table name to be created
+ and used to store all WikiPages.
+
+ EWIKI_DBQUERY_BUFFER
+ When set to a value>0 then SQL database buffering will be enabled
+ for SEARCH and GETALL queries. This is mostly like the old (R1.00)
+ behaviour (memory exhaustive), but instead is limited to the size
+ defined by this configuration constant (for example 384K).
+
+ EWIKI_DBFILES_DIRECTORY
+ Defines where db_flat_files puts the database (made up of files).
+ There is a separate paragraph about this,
+
+ EWIKI_DBFILES_ENCODE
+ If set to 1 will generate urlencoded() filenames even on UNIX
+ systems, so the dbff database 'files' get exchangeable across
+ DOS/Win and UNIX filesystems. Not recommended, and will make
+ ewiki run bogus, if you switch it after there already entries
+ in the database.
+ It may however be useful to enable this per default, if you want to
+ "backup" (this is the wrong way) from a Unix server to a Win box via
+ an ordinary FTP program (more professional tools could however handle
+ this more easily).
+
+ EWIKI_INIT_PAGES
+ Names the directory from which the basic pages should be read and
+ then written into the database, when ewiki is run the very first
+ time (or the FrontPage - EWIKI_PAGE_INDEX) is still empty.
+ Btw, you could use the 'ewikictl' utility to export all your Wiki
+ pages into this directory as auto-reinit-backup.
+
+
+ EWIKI_NAME
+ Defines the name of your Wiki. (This is not used currently, but
+ is required, as _PAGE_INDEX is often just set to "FrontPage".)
+
+ EWIKI_PAGE_INDEX
+ This defines the name of the WikiPage which shall be displayed
+ when no value is received within the URL. Often this is called
+ the "FrontPage" of the Wiki.
+
+ The mysql error message "Table 'ewiki' already exists" will appear
+ until you create (and fill) the page specified herein.
+
+ If you'd like to have a wiki without FrontPage, you can set this
+ constant to 0 or "" - you must then however ensure, that the ewiki
+ script is never activated without a page name!
+
+ EWIKI_PAGE_NEWEST
+ This defined the name of the virtual (internally generated) page
+ containing a list of the lately added WikiPages.
+ EWIKI_PAGE_SEARCH
+ Holds the WikiPageName for the search function.
+
+
+ EWIKI_CONTROL_LINE
+ Pre-define this with 0 before including("ewiki.php") if you
+ don't want that "<HR><A HREF>EditThisPage</A> ..." to be shown
+ at the bottom of each page.
+
+ You must then generate the EditThisPage link yourself somewhere
+ else on yoursite.php
+
+ It is often easier to edit the ewiki_control_links() function
+ to match the layout/design of yoursite.php.
+
+ EWIKI_AUTO_EDIT
+ If set to 1 (default) will automatically bring up the edit box
+ for non-existent pages. Else a page in between will appear ("please
+ edit me!") like in PhpWiki.
+
+ EWIKI_LIST_LIMIT
+ Number of pages to show up in search queries (and other generated
+ pages).
+
+
+ EWIKI_PRINT_TITLE
+ If set to 0 will prevent the page title from being shown on many
+ pages (generated and database content ones).
+
+ EWIKI_SPLIT_TITLE
+ If changed to 1 will separate WikiPages titles into its different
+ word parts (only on top of each page).
+
+
+ EWIKI_ALLOW_HTML
+ Usually you do not want that users are able to add <HTML> tags
+ inside the WikiPages as this allows for corruption of your page
+ layout or creation of harmful JavaScript areas.
+
+ This is however one of the few constants which could be set by
+ yoursite.php for logged-in users. If it is set while a user
+ saves a changed page, then the special EWIKI_DB_F_HTML will
+ be set for the newly created version, so <HTML> won't be
+ garbaged by ewiki_format() if another (not logged-in) user
+ requests the WikiPage next time.
+
+ You must start a line with a "|" to actually make the HTML
+ work within a WikiPage.
+
+ If a not logged-in user however re-saves the page this flag
+ won't be set anymore, so you should be careful about that.
+ {{edit ewiki.php and define(_DB_F_HTML with 8+16) to change}}
+
+ EWIKI_RESCUE_HTML
+ Was replaced by "plugins/markup_rescuehtml.php", which now allows
+ for certain 'safe' HTML tags within the wiki source to be used.
+
+ EWIKI_HTML_CHARS
+ If set the rendering function will backconvert html entities which
+ represent non-latin characters, like ႊ or Ԭ
+
+
+ EWIKI_HTTP_HEADERS
+ Allows ewiki to throw HTTP headers, where appropriate. You should keep
+ it enabled, as it allows for things like RedirectionAfterEdit (when
+ a page gets saved), and many other useful things.
+ headers() can often only be sent, if your wiki/yoursite.php is binary
+ safe, or uses PHPs output buffering (less reliable).
+
+ EWIKI_HTTP_HEADERS
+ Instructs browsers not to cache delivered pages at all. This is often
+ a good thing, because otherwise unclever caches will prevent the most
+ recent wikipage version to get seen by users.
+
+
+ EWIKI_CASE_INSENSITIVE
+ Was only recently implemented, but ewiki is fully configurable now in
+ regards to WikiLink case. It is enabled per default, and thus allows
+ referencing any "WikiPage" using strings like "WiKipAgE". This is
+ believed to be more user-friendly than case-dependency.
+ Reverting to "binary" page name matching is not fully complete now (our
+ database scheme was designed for case-insensitivity from the very start
+ and thus the DB code first needs tweaking before links in ewiki really
+ get case-dependent.
+
+
+ EWIKI_ESCAPE_AT
+ Encodes the "@" sign into a html entities, which in the past helped
+ a little bit against address rippers. But please check out the new
+ plugins/email_protect.php, which is more effective against email
+ harvesters.
+
+
+ EWIKI_URLENCODE
+ EWIKI_URLDECODE
+ You shouldn't disable both unless you know, you don't need to encode
+ WikiPageNames (else almost always necessary for sanity and security
+ reasons).
+
+
+ EWIKI_USE_PATH_INFO
+ If you have a broken Webserver (like many Apache versions), you may
+ wish to disable the use of PATH_INFO.
+ If you ever happen to see "Edit page '/wiki/example-1.php'", you
+ probably need to disable it.
+
+
+ EWIKI_USE_ACTION_PARAM
+ Allows the page action command to be given as '&action=...' within
+ an URL (else only "action/WikiPage" allowed).
+ If you set this constant to 2, ewiki will also create such URLs
+ (instead of the usual "edit/PageName" prefix).
+
+ EWIKI_ACTION_SEP_CHAR
+ Defines the character that separates the page name from the action
+ name in generated URLs. Per default this is the slash, but you
+ could use something else (like the ":" colon), which however may
+ have a few drawbacks somewhere else.
+
+
+ EWIKI_DB_F_TEXT
+ This flag is set for every WikiPage inside the database. Usually
+ the only flag set on creation of a new page.
+ Starting from R1.00b previous flags will be copied after applying
+ EWIKI_DB_F_COPYMASK.
+
+ EWIKI_DB_F_BINARY
+ Used for cached/uploaded images. Prevents a page from getting
+ shown.
+
+ EWIKI_DB_F_DISABLED
+ If set will prevent the page from being shown. Not useful.
+ You could more easily unset the TEXT flag to disable page view.
+
+ EWIKI_DB_F_HTML
+ Special flag to allow the current version to include <HTML>
+ tags regardless of the global EWIKI_ALLOW_HTML setting.
+
+ EWIKI_DB_F_READONLY
+ Prevents a new version to be saved, and thus disallows
+ editing of the WikiPage.
+
+ EWIKI_DB_F_WRITEABLE
+ Is the reversal of READONLY but only useful if you crippled
+ ewiki by setting EWIKI_EDIT_AUTHENTICATE, as this flag is only
+ intended to reallow editing of a page if you disallowed it before
+ with _EDIT_AUTH (which denies access to _all_ pages).
+
+ EWIKI_DB_F_APPENDONLY
+ Gets implemented by the plugins/append*.php, and allows to lock
+ a page, in that users can only append to edit (or edit parts of
+ it). See the plugin description for more details.
+
+ EWIKI_DB_F_SYSTEM
+ Is used to mark internally used data holders (usually serialized()
+ variables).
+
+ EWIKI_DB_F_TYPE
+ Used internally to separate TEXT, BINARY, DISABLED and SYSTEM entries.
+
+ EWIKI_DB_F_COPYMASK
+ When a new page is created, the flags of the previous version
+ are ANDed with this value to strip off some unsafe settings.
+ It could be possible to add the _DB_F_HTML setting to here, but
+ this would allow HTML to be used by all users if the READONLY
+ isn't set.
+ Always keep in mind, that flags could be reimported from previous
+ versions as well (I'm usure if this could happen).
+
+
+ EWIKI_PROTECTED_MODE
+ Is an operation mode of ewiki, which activates ewiki_auth() function,
+ that is utilized from many places to require a permission level (from
+ authenticated users). Set this constant to 1 to enable this mode.
+ You'll also need some plugins from plugins/auth/ to make this useful.
+
+ If this constant is set to 2, then you don't need a permission plugin,
+ but can control access to the edit/ function, by setting $ewiki_ring
+ to 2 (to allow) from within yoursite.php scripts. This setting is also
+ sometimes referred to as the "ClassicProtectedMode".
+
+ EWIKI_FLAT_REAL_MODE
+ Not a configuration directive, but the opposite to _PROTECTED_MODE ;)
+
+ EWIKI_AUTH_DEFAULT_RING
+ Is the permission level which is to be set, if no user is logged in
+ currently (defaults to 3 - which means "browsing only").
+
+ EWIKI_AUTO_LOGIN
+ If this is enabled, then ewiki_page() automatically requests for
+ (re-)presenting the login <form> on startup, if current authentication
+ isn't sufficient to go any further. Leave this enabled, it helps around
+ some problems.
+
+ EWIKI_EDIT_AUTHENTICATE
+ EWIKI_ALLOW_OVERWRITE
+ Outdated (were present in older ewiki versions). See
+ 'plugins/auth/auth_perm_old.php' to get them back.
+
+
+ EWIKI_TMP
+ Tells ewiki which directory to use for temporary files. The default
+ value is "/tmp" or whatever the environment variable $TEMP or %TEMP
+ tells (often "C:\\Windoze\\Temp" or "C:\\Trashcan" on DOS systems).
+
+
+ EWIKI_LOGLEVEL
+ Log messages are internally separated into four categories:
+ 0=evil errors, 1=warnings, 2=notices, 3=annoying debug stuff.
+ If you do not want a log at all, just set this constant
+ to -1 or 357. If you set it to 1 for example, you will see
+ error and warning messages in EWIKI_LOGFILE.
+
+
+ EWIKI_SCRIPT_BINARY
+ This requires the REAL absolute address of the ewiki.php
+ library script (but the database must already be opened).
+ Needed for the function for cached/uploaded images.
+ You can set it to almost the same value as EWIKI_SCRIPT if it
+ is ensured that there is yet no output made, and the headers()
+ are not already sent.
+
+ Usually just "?binary=" works fine (if you use the index.php
+ way of including ewiki.php).
+
+ If you don't want ewiki to use image caching and uploading
+ functions you would define this to "" or 0, because this disables
+ the <img href> redirection through ewiki_binary(). You should then
+ also disable the following two constants:
+
+ EWIKI_CACHE_IMAGES
+ Allow caching of images.
+ To disable all the image functions (uploading, caching) set this to 0,
+ as well as EWIKI_SCRIPT_BINARY and:
+
+ EWIKI_IMAGE_MAXSIZE
+ ewiki will scale down images until they get smaller than
+ the absolute size (bytes) given here. This is true for cached
+ and uploaded images.
+ Your database may grow really fast, if you set it too high!
+ (even if .BMP and .XWD files are discarded normally ;-)
+
+ EWIKI_IMAGE_MAXALLOC
+ Maximum size of image while uploading and resizing it (memory
+ limits).
+
+ EWIKI_IMAGE_RESIZE
+ Enables the internal resizing functions.
+
+ EWIKI_IDF_INTERNAL
+ Is used to identify uploaded images and data files. Usually you do
+ not want to change it, especially if there are already uploaded
+ files; however "chrome://" or "file://localhost/tmp/" could be
+ funny alternatives to the default "internal://".
+
+ Note that the renderer relies only on some unique string to detect
+ binary references, but the database functions in fact depend upon
+ "://" to return image sizes on "FIND" calls.
+
+ EWIKI_ACCEPT_BINARY
+ Allows users to upload arbitrary binary files through the image upload
+ function. You should now rather use the downloads plugin, which adds
+ a lot of functionality missing better suited for such purposes.
+ This feature depends on the image upload and cache function.
+
+
+ EWIKI_ADDPARAMDELIM
+ Automatically defined, holds either "?" or "&" depending on what
+ is in EWIKI_SCRIPT. You shouldn't change this unless you know what
+ you are doing.
+
+
+ EWIKI_T_*
+ These were replaced by the $ewiki_t[] array and ewiki_t() function.
+
+
+ EWIKI_CHARS_U
+ EWIKI_CHARS_L
+ Allowed chars in WikiPageNames (uppercase and lowercase chars). Use
+ this to localize your wiki (standard Wikis only allow A-Z, think of
+ that when it comes to InterWiki).
+
+
+ EWIKI_UP_*
+ URL parameters. Changing these may only be necessary, if one is already
+ evaluated within yoursite.php for other purposes (incompatibilities).
+ You could also change these just to make some of the generated URLs
+ look a bit nicer ;)
+
+
+ EWIKI_DEFAULT_LANG
+ This value is used by a few plugins, that must guess the desired
+ language of visitors, or the language of a pages content.
+
+ EWIKI_CHARSET
+ ewiki currently only supports the Latin-1 charset, but UTF-8
+ support is underway. So you should only specify "ISO-8859-1"
+ or "UTF-8" herein (while most other "ISO-8859-*" are believed
+ to work too).
+
+
+ UNIX_MILLENNIUM
+ Ey, don't tell me you're using Windoze ;)
+
+
+ EWIKI_VERSION
+ Is not used at all. It is just placed on top of every ewiki.php to tell
+ you, which version you are running currently.
+ Major releases have a version number like 'R1.00a', while testing and
+ unstable releases have another number appended 'R1.00a7'.
+
+
+See the tools/ subdir for a small utility to change the mentioned flags
+in the ewiki database table.
+
+
+
+$ewiki_config array
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+As it turned out not all configuration settings are as everlasting that
+they can be constants (this mainly applies to "look&feel"-settings). So
+some of the above mentioned EWIKI_ constants can now be overridden by
+settings in the more flexible $ewiki_config[] array.
+
+Usually this array contains index=>value pairs with simple boolean
+meanings, but often there are more complex entries and some of its contents
+are data/behaviour entries (that were previously/falsely in $ewiki_plugins).
+
+You can override settings by just setting $ewiki_config["..."]="...";
+because the entries in ewiki.php are defaults that do not overwrite any
+existing var. So it is really not important if you change things after or
+before the 'ewiki.php' script gets included().
+
+["script"] Replaced EWIKI_SCRIPT, and is used to define the
+ path/URL of the ewiki wrapper script (yoursite.php,
+ which at least included the ewiki.php script and
+ runs the ewiki_page() function).
+
+["script_url"] Should contain an absolute URL to the ewiki wrapper
+ script. (replaces EWIKI_SCRIPT_URL)
+
+["script_binary"] like EWIKI_SCRIPT_BINARY
+
+["print_title"] replaces EWIKI_PRINT_TITLE, but also allows finer
+ grained control:
+ a 1 says that titles should be added at top of pages
+ a 2 states that titles should also link for internal
+ and generated pages
+ a 3 will make linked titles even for pages, that
+ should normally not have them
+
+["split_title"] replaces EWIKI_SPLIT_TITLE, defines if pages` titles
+ WikiWords should be separated by spaces when displayed
+
+["wiki_pre_scan_regex"] Is the regular expression used to separate out links
+ from a pages` content to query the database for
+ existence of all mentioned WikiPages.
+
+["wiki_link_regex"] Is the actual link search regular expression. It is
+ responsible for finding WikiWords and things in square
+ brackets and ordinary http:// or internal:// WWW-links
+ and even email addresses.
+
+["action_links"][$ACTION1][$ACTION2] Holds title for $ACTION2 when shown
+ on a page activated with $ACTION1 (only "view" and
+ "info" get other actions` titles associated currently).
+ This is used for the _control_links() for example to
+ entitle/show action links.
+
+["idf"][$TYPE] Associates arrays with identification (search) strings
+ into classes (we have "url" and "img", "obj" for
+ example associated with proto:// prefixes or filename
+ extension lists).
+
+["interwiki"][$PREFX] Connects other Wikis` script URLs to WikiLinkPrefixes.
+
+
+["format_block"][$BTYPE] Defines "block" types, which are scanned for in
+ WikiPages (using the given search strings), and then
+ handled by specialized ["format_block"] plugins
+ (instead of the core ewiki_format() function code).
+
+["format_params"][] Contains the default $params, the ewiki_format()
+ function will assume, if they weren't overridden
+ by the second paramater given to it.
+
+["wm_..."] WikiMarkup definitions.
+
+["htmlentities"] Used by ewiki_format() to pre-escape <html> in
+ wikipages (later some of the escaped html is
+ often reactivated).
+
+
+
+internal coding explained
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+This section is to explain some of the coding style of ewiki, and how some
+things work. While many parts of ewiki carry good source code comments, it
+is always difficult to quickly understand larger scripts like the ewiki one
+by just reading it.
+
+
+
+ how ewiki operates
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ ewiki_page()
+ - decodes the $id and $action from the GET or POST parameters
+ - tries to load the page from ewiki_database()
+ - if this failed then it calls the database init function
+ - calls some init plugins, calls the _auth() interface
+ - chains to ["page"] plugins which activate for registered $id's
+ - alternatively calls a plugin that was registered for $action
+ - the default however is to render the current page via _page_view()
+ - adds a page title
+ - sends the generated output (view page or plugin output) back to
+ caller (for output into yoursite.php)
+
+ ewiki_page_view()
+ - feeds the current page $data's ["content"] into ewiki_format()
+ - also decodes paramters (html allowed)
+ - returns the gererated html back
+
+ ewiki_format()
+ - beatifies the source code (unifies to plain UNIX newlines)
+ - calls init plugins (wiki source mangling)
+ - splits source into blocks, calls block plugins
+ - then goes through each line of the wiki source to generate html
+ - there is line-start, in-line and complete-markup
+ - afterwards everything went from source into the $ooo-output var
+ - first calls the link pre scan regex (which searches for
+ wikiwords and stores that information into $ewiki_links)
+ - then calls the wiki-link transformation regex function
+ - then calls post plugins and returns generated <html>
+
+ ewiki_render_wiki_links()
+ - searches for all (pre-fetched) $ewiki_links in the
+ ewiki_database ("FIND")
+ - transforms the wikiwords into html-links
+ - with the regex and callback func: returns output back to
+ - ewiki_format()
+
+ ewiki_link_regex_callback()
+ - transform the wiki source snippet returned from the
+ preg_replace() call into a html link string
+ - (complicated)
+
+ ewiki_$page_plugin_*()
+ - page plugins return html output, which usually is hardcoded as
+ strings into them
+ - provide some interactivity
+
+ ewiki_$action_plugins_*()
+ - activate on pages with special registered $action's
+ - provide some interactivity (for page editing for example)
+
+
+
+ used variables
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Variables in ewiki often have similar names, and are also
+ regularily passed by reference from one function to another (so it
+ is in fact the same variable).
+
+ $id - Is often the name of the current page (which is to be shown
+ returned as output. The content of this variable is
+ also available via the global $ewiki_id [[for plugins
+ that do not have the common ($id,$data,$action)
+ interface parameters]].
+
+ $data - Contains the entry fetched with the initial
+ ewiki_database() call. This is an array of the form:
+ array(
+ "id" => "CurrentPageName",
+ "version" => 1, # 1 is the lowest possible
+ "flags" => 1,
+ "created" => 1002056301,
+ "lastmodified" => 1002171711,
+ "hits" => 235,
+ "author" => "localhost (127.0.0.1:4981),
+ "meta" => array("Http-Header"=>"X", "setting"=>"val"),
+ "content" => "wiki source...",
+ )
+
+ $action - The $action with wich the current page was requested
+ (most often "view", but everybody also knows "edit").
+
+ $uu - Short for "unused". Is used as temporary variable, especially
+ with preg_match() and string functions.
+
+ $result - Used for database queries SEARCH and GETALL.
+
+ $row - Holds temporarily fetched entries from the databases
+ (like $data), if page lists are to be generated.
+
+
+
+
+
+ -------------------------------------------------------------------- 4 --
+
+
+
+
+
+Tweaking
+¯¯¯¯¯¯¯¯
+(this part of the README is also just a collection of random notes)
+
+
+
+Just using the wiki source transformation
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+The ewiki_format function was designed to be used independently from the
+ewiki database.
+
+ ewiki_format($wiki_source, 0);
+
+It just needs the "wiki_source" as argument and generates a nicely
+formatted page from it. All you need to take care about is the
+$ewiki_links variable.
+Set the $ewiki_links=true ("true" and not "1" or anything else) to
+enforce ewiki_format() to treat all references as existing.
+
+To separate the ewiki_format() function out of recent ewiki versions,
+you'll also need ewiki_script(), ewiki_link_regex_callback(), ... and
+a lot of constants to take with. It is often much easier to just
+include("ewiki.php") for using ewiki_format(). You then should however
+take care, that the _binary part doesn't get activated by accident. To
+prevent this, just put following before the include() statement:
+
+ unset($_REQUEST["binary"]);
+ include("ewiki.php");
+
+If you need it more quickly, or don't want to load the whole ewiki.php
+file, then just try the fragments/wiki_format.inc, which is a stripped
+down version of an older rendering core function (no WikiLinks, no binary
+stuff). Contributed by Frank Luithle.
+
+
+
+Customizing ewiki_format()
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+There are various markup extension plugins available for ewiki, which
+allow you to use BBCode or the syntax of another WikiWare. But if you
+have a closer look at $ewiki_config (the defaults are in 'ewiki.php'
+around line 200), you'll notice, that you can configure the WikiMarkup
+that is to be used.
+Various "wm_..." entries map our obscure markup to html <tags> (or at
+least fragments of them). So in order to add a feature you could insert
+an own rule there. (But keep in mind, that every new WikiMarkup slows
+down the transformation function.)
+
+Often you want to append an entry to "wm_style", for example:
+
+ $ewiki_config["wm_style"]["==="] = array("<h1>", "</h1>");
+
+Would allow you to write "===SomeText===" in a WikiPage, which then would
+display as an far-too-large headline.
+
+You can also add markup with different 'start' and 'end' characters, using
+the "wm_start_end" entry in $ewiki_config. For example the following would
+render "... ((((some text)))) ..." in a page using the html <kbd> tag:
+
+ $ewiki_config["wm_start_end"][] = array(
+ "((((", "))))", "<kbd>", "</kbd>",
+ );
+
+Please see the section on "ewiki_format() internals" on how to write a
+["format_..."] or markup plugin.
+
+
+
+Customization using CSS
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+There are now some interesting ways to style ewiki output, just read on.
+
+Please note, that it in your stylesheets you just write ".wiki" and
+REALLY NOT ".ewiki" this time.
+
+Also important is, that we discourage use of the underscore in CSS class
+names, because it is simply forbidden there, even if current browsers do
+not complain as loudly as the w3c does. (That's just why you'll now see
+lots of class names with minus dashes instead of underscores.)
+
+
+
+user style classes in pages
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+The plugins/markup_css allows you to use CSS classes and style definitions
+in WikiPages. With the double at @@ followed by a css classname or command
+you start styling a paragraph or parts of the text.
+
+ @@classname at the start of a paragraph will
+ enclose it into a <div class="classname">
+ completely
+
+ But inside of some text, the @@styledef only
+ affects the part until the next @@ everything
+ that comes later won't be enclosed in a <span>
+
+While the css style classes must be defined in your sites` global stylesheet
+to take effect, you could also use direct CSS style commands instead. These
+also must follow the @@ immediately and may not contain spaces. So something
+like @@color:#ff0000; will work, while specifying font names may not always.
+
+
+
+rendered page content
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+If you are not interested in walking around the "ewiki.php" script
+when you want to tune how the output looks, you should try to
+utilize the (few) CSS classes ewiki defines (it does not include
+even one color setting or <font> tag):
+
+<style type="text/css">
+
+ p { font: ... } // almost every part of the generated
+ // wiki pages is inside a <p>...</p>
+
+ em { ... } // you could encolour this, if the browsers
+ strong { ... } // usual italic is not emphasized enough
+
+ .indent // to specify a different space-indentation
+
+</style>
+
+
+
+pages enclosed in style classes
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+The most powerful way to style the content ewiki includes into your site
+is to use the generic style class names which enclose every page that comes
+from ewiki:
+
+ <div class="wiki view ThatPage">
+ ...
+ </div>
+
+This <div> is always the outermost tag around the html content that returns
+from ewiki_page(). It will always contain the class "wiki", after this
+the current page action/ and PageName (the action is usually "view", but
+can be also "edit", "info", "links" or something similar).
+
+Keeping this in mind you can easily style all, a few or even just a single
+page from ewiki in your stylesheet. (We'll explain it here, because the word
+of multiple class names and the cascading way of using CSS is not very
+widespread.)
+
+.wiki { // this affects every page ewiki returns
+ background-color: #ccccff;
+ font-family: "WikiFont";
+ ...
+}
+
+.wiki.view { ... } // only applies to pages that are "view"ed
+.wiki.links { ... } // BackLinks
+.wiki.edit { ... } // when a page gets edited
+
+.wiki.PageIndex { // this rule affects only a __single__ page
+ ... // regardless what the "action/" is now;
+} // useful for "PowerSearch" or "PageIndex"
+
+.wiki.edit.ThisVerySpecialPage { // this css section applies to just one
+ ... // page again, and this time only when
+} // it gets edited
+
+
+
+plugin output styling
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+There often appear special 'pieces' within a rendered page that ewiki
+returns, because not everything in the returned html code belongs to the
+requested pages` content.
+
+For example the current pages` title needs its own css class, like does
+the block of action links ("EditThisPage, PageInfo, ...") below every page,
+so it can be distinguished from the pages` text.
+
+Also note again the use of the '.wiki' selector within the following
+stylesheet guide and ewiki CSS class overview:
+
+
+.wiki h2.page.title { // all titles now have it, while many
+ ... // of them include links as well
+}
+
+.wiki.view .action-links { // "EditThisPage, PageInfo, ..." links
+ ... // are inside such a block, like are two
+} // <hr>'s
+
+.wiki.info .chunked-result { // some generated pages (like the history
+ ... // info/ ones) may need to split their
+} // results; this matches those links
+
+ //-- the edit/ pages are separated into
+ // following blocks:
+.wiki.edit .edit-box { ... }
+.wiki.edit .image-upload { ... }
+.wiki.edit .preview { ... }
+
+ //-- info/ pages contain a history of page versions, each enclosed in
+ // a <table class="version-info">, the <tr>s inside can be selected
+ // separately:
+.wiki.info table.version-info { ... }
+.wiki.info .version-info .action-links { ... }
+.wiki.info .version-info .page-author { ... }
+.wiki.info .page-refs { ... }
+.wiki.info .page-flags { ... }
+
+
+The class naming across most of the extension plugins is not unified, so you
+may often need to look it up here - or inside of the plugins source code.
+This is at least necessary for calendar and navbar, which follow a very
+different naming scheme.
+
+.wiki .download-entry { ... }
+.wiki .download-form { ... }
+.wiki .upload-form { ... }
+
+.wiki .image-append { ... }
+
+
+
+Idea Collection
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Here we'll note some tricks, on how to do this and that. Some of the
+following paragraphs also explain workarounds for currently lacking
+features.
+
+
+
+ Multiple Wikis / InterWiki feature abuse
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Other WikiWare provides means to have multiple namespaces in a wiki,
+ what if fact is contrary to the original Wiki idea suggesting a
+ single flat namespace. ewiki does not support SubWikis or alike, to
+ get multiple Wikis using one ewiki installation you'll need multiple
+ layout and config wrappers (each with its own absolute URL and
+ differen EWIKI_DB_TABLE_NAME or EWIKI_DBFILES_DIRECTORY constants).
+
+ This way you'd get two independent Wikis (with two different SQL
+ database tables, or flat_files directories), and of course links
+ between those two need a special syntax. And the best approach here
+ was to use the InterWiki linking feature.
+
+ To do so, invent to InterWikiAbbreviations for each of your separate
+ Wikis and add it to $ewiki_config["interwiki"] as follows:
+
+ $ewiki_config["interwiki"]["main"] = "/wiki/main/?id=";
+ $ewiki_config["interwiki"]["office"] = "/wiki/office/?id=";
+ $ewiki_config["interwiki"]["tech"] = "http://tech.company.com/?id=";
+ $ewiki_config["interwiki"]["our-www"] = "http://www.company.com/";
+
+ The last one is an example, on how to use the InterWiki feature to
+ generate references to arbitrary web documents, with a simple syntax
+ like "[our-www:/customers/pub/rules.html]" - it's somehow standard to
+ use "company-url:" or "company-www:" as InterWikiAbbreviation for this
+ purpose.
+
+
+
+
+
+
+
+ -------------------------------------------------------------------- 5 --
+
+
+
+
+Explanations
+¯¯¯¯¯¯¯¯¯¯¯¯
+The next few paragraphs shall enlight more detailed how some things are
+handled in ewiki (and why it is that way).
+
+
+
+Binary and Text content
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Because I'd like to keep it small (see also the "Everything in one
+script" paragraph) ewiki also creates just one database table.
+Differently from other Wikis this one has the 'flags' setting for
+each saved page. And as I successfully used this bad trick in earlier
+projects many times to integrate support for hundreds of different
+functions (CMS, links, boards/forums, ...) into a single table; I
+thought it could be funny to have something like this in ewiki too.
+
+While the image thingi seemed senseful to me, other binary data
+cannot be feed into database without helper plugins, because this is
+a Wiki script and not an almighty portal software!
+
+Uploading and caching of images requires the EWIKI_SCRIPT_BINARY
+constant to be set correctly (no output may be made before "ewiki.php"
+is included == "binary safe").
+The ewiki_binary() function handles almost all of this, and gets
+activated automagically (whenever required) as soon as ewiki.php is
+included().
+
+I believe these functions to be rather safe, as there are many sanity checks
+throughout the code to separate between _DB_F_BINARY and _DB_F_TEXT content.
+
+
+
+ Image Uploading
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The currently most important use for the BINARY flag and image
+ functions is to upload images with the small form below every page
+ edit box.
+
+ The upload/caching functions can be disabled fully if
+ EWIKI_SCRIPT_BINARY and EWIKI_CACHE_IMAGES are set empty (or zero).
+
+ URLs starting with "internal://" represent the uploaded files. The
+ string is just a md5() sum generated from the contents of the
+ uploaded file. This way files won't get saved another time if they
+ are uploaded twice. For uploading a JavaScript-capable browser is
+ recommended. It will work without, but then requires the user to
+ copy the [internal://...] text (from one window to another).
+
+ The color of the temporary upload info screen can only be changed
+ inside the ewiki_binary() function, currently.
+
+ Beware that images usually get downscaled if they are larger than
+ specified with EWIKI_IMAGE_MAXSIZE (per default 64K).
+
+
+
+ Images Caching
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Images are usually redirected through EWIKI_SCRIPT_BINARY, and ewiki
+ tries to save them inside the database as with uploaded images. So
+ most of the facts from the previous paragraph apply to this function
+ too.
+
+ You must enable this feature with EWIKI_IMAGE_CACHING, it is shipped
+ disabled currently.
+ Adding a ?nocache to the image URL disables this feature for just one
+ specific image, if _IMAGE_CACHING was otherwise enabled.
+
+ Images are downscaled to fit the maximum defined size in
+ EWIKI_IMAGE_MAXSIZE (bytes) if the PHP libgd extension is available
+ (else dropped and then always redirecting clients which request
+ those image).
+
+
+
+ Image WikiMarkup
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Usually one writes image references using square brackets around the
+ url of an image: [http://www.example.com/pics/image.png] or:
+ [internal://md5md5md5md5md5md5md5md5md5md5md5md5.png]
+
+ This will include (inline) the image into the page, when rendered
+ and viewed. Using the standard square bracket link entitling syntax
+ also image references can be named (non-graphics / alternative
+ text):
+ [http://www.example.com/pics/image.png | This is an example image]
+ [http://.../image.pic "or entitle it using double quotes"]
+
+ Images can also be "aligned" to either side of the screen, thus the
+ remaining text will flow around it. To achieve this include spaces
+ to the left or the right of the image URL:
+
+ * picture to the LEFT: [http://www.example.com/pics/image.png ]
+ * picture to the RIGHT: [ http://www.example.com/pics/image.png]
+ * CENTRED picture: [ http://www.example.com/pics/image.png ]
+
+ Note that you must use __two__ spaces, currently!
+
+ Image rescaling is possible by appending x=... and y=... as query
+ string parameters behind the image URL:
+ [http://www.example.com/pics/image.png?x=160&y=120]
+ The query string parameters "width" and "height" are also accepted.
+
+ If you have an image URL, but you do not want to get that image
+ inlined into the current page, then just leave out the square
+ brackets around.
+
+
+
+ binary_store, direct access
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ While storing the binary data together with text pages in the same
+ database is most often a good thing and suits most sites, there
+ exists also a workaround/hack to keep this binary data in plain
+ files. The advantage is a smaller database and possibly a little
+ speed enhancement (with a large collection of binary things in the
+ db). However the drawback is, that use of plugins/binary_store is
+ only transparent to the main ewiki script, but all admin tools/
+ won't be aware of it.
+
+ If you choose to use the binary_store.php plugin, you can also let
+ ewiki generate URLs directly to the then stored data files if you
+ just set the EWIKI_DB_STORE_URL constant.
+
+ Please see the paragraph on this plugin for more informations on
+ this.
+
+
+
+ Arbitrary Binary Content
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Set the EWIKI_ACCEPT_BINARY constant, if you'd like to allow any
+ binary file to be uploaded and saved in the database using the image
+ upload function. Uploaded files will show up as ordinary (except
+ that "internal://" href prefix) links.
+
+ Please also note the "plugins/download.php", which does a much
+ better job than this constant.
+
+
+
+$action and $id
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Inside of ewiki.php you'll see many occurrences of variables named $id and
+$action. The $id refers to the current page, which usually is a string like
+ThisPage, ThatPage, OrAnotherPage.
+
+Because just having pages wasn't believed to be sufficient enough, there
+is also a way to do something with them. That is what the $action tells.
+The most often used $action is "view" and is automatically assumed when
+no other $action was specified in the current ewiki URL. For non-existent
+pages alternatively the "edit" $action may get used instead.
+
+So the $action now delegates control about a requested page to a subfunc
+or plugin of ewiki, so the stored data of the page can be used for
+something (viewing being again the most common thing to do with it).
+
+"action/ForTheCurrentPage" is how both often looks in conjunction (again:
+if there is no "$action/" then "view/" will be assumed). Here the $action
+appears in front of the page name separated by a slash. A pagename now can
+contain slashes too, because ewiki can figure out, that "view/That/Page"
+separates into the $action being "view" and $id is "That/Page" in this
+example (the "view" gets mandatory in such cases).
+
+
+
+ ewiki URLs
+ ¯¯¯¯¯¯¯¯¯¯
+ "$action/$id" is most commonly appended as "GET parameter" to an
+ ewiki URL, after a string like "?id=" or "?page=" - you've already
+ noticed that!
+
+ There are of course other ways to design the URLs ewiki produces
+ and uses, the PATH_INFO being one of the most favoured alternatives.
+ (we had a paragraph on this earlier, see on top of this README)
+
+ Other Wikis use different URLs too, but you can tweak ewiki easily
+ to a different behaviour, because you have the chance to pass your
+ $action and $id to ewiki_page() from different sources. And because
+ URL generation is encapsulated into the function ewiki_script()
+ you could easily change just a few lines to make them look like you
+ desire.
+
+ The $action can be passed as "?action=" parameter already (this is
+ core support), so URLs could for example look like
+ ".../my/wiki.php?id=ThisPage&action=view" ... or something alike.
+
+
+
+
+
+
+
+ -------------------------------------------------------------------- 6 --
+
+
+
+
+
+
+Everything in one script
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+I think its handy to have one script for one task, and as ewiki is not
+intended to be used as portal script I think it's senseless to have
+always thousands of libs/scripts surrounding it.
+
+However as time went on, it turned out, that it would either slow down
+the core 'library' when everything was included into it, or that there
+couldn't be much further development at some point.
+
+So packaging useful but non-essential extensions into separate files was
+a good decision. Most of the plugin code can however still be inserted
+into or appended to the main "ewiki.php" script easily.
+
+As I realized that it really takes some time to edit the source when
+including non-standard things I decided to add that simple extension
+mechanism. Internally it is represented by the "$ewiki_plugins" array,
+which holds an list of alternative functions for various tasks.
+This allows to just include("a/plugin.php") for additional functionality
+inside ewiki.
+
+ Note: if you're going to use almost all plugins, you should think about
+ merging them altogether into one .php file:
+ cat plugins/*.php > all-plugins.php
+ It is much faster to include() just one big .php script, than it is to
+ let the PHP parser run over twenty small ones (PHP is not interpreted,
+ but memory-compiled).
+
+
+
+database plugins
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+The ewiki.php core script contains a database request function which is
+tailored to a MySQL database. However that function is already prepared
+to chain to another "database abstraction" function if desired.
+
+
+
+ MySQL support
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The first implemented, and still most recommended way to use
+ ewiki is with a MySQL (3.21 or later) database. RDBMS work more
+ reliably and of course much faster than any other of the ewiki
+ database backends.
+
+ As the core ewiki_database() inside ewiki.php already includes
+ the MySQL database calls, there is usually nothing to do, but
+ opening a database connection before ewiki.php is included()
+ from yoursite.php
+ Please look at the top of this README for an example.
+
+ As PHPs mysql_() functions don't require a db resource link to
+ be given anymore, the ewiki_database() function does not pass
+ and thus does not require it too. (If you use more than one MySQL
+ database, you should take care, that ewiki accesses the one you
+ accesses least.)
+
+
+
+ plugins/db_flat_files
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ If you don't have access to a MySQL database, then just include()
+ this plugin to save your wiki pages into simple text files (editable,
+ often called "flat files") inside a dedicated subdirectory. You
+ must set EWIKI_DBFILES_DIRECTORY in the 'ewiki.php' script to the
+ correct dirname. Don't forget, that it must be given either relative
+ to where the ewiki.php script is run from (like "./pages") or
+ absolute to the servers filesystem root (for example
+ "/export/htdocs/user528742/www.example.com/ewiki/pages") but NOT
+ relative to your WebSpaces DocumentRoot!.
+
+ Usually "/tmp" will work, but this one is purged on every boot; and
+ therefore you should create a new sub directory (" mkdir ./pages ")
+ where all files go into. This newly created subdir must be made
+ »world-writeable« using the command "chmod 777 ./pages", because the
+ WebServers user id counts when accessing it.
+
+ Usually you can do both from within your ftp client (the commands
+ are the same if you have a shell account):
+ ftp> cd .../ewiki
+ ftp> mkdir pages
+ ftp> chmod 777 pages
+ ftp> ls
+ -rw----r-- 1 yourname yourname 57024 01. Jan 00:00 ewiki.php
+ -rw----r-- 1 yourname yourname 512 01. Jan 00:00 index.php
+ drwx---r-x 2 yourname yourname 4096 01. Jan 00:00 init-pages
+ drwxrwxrwx 2 yourname yourname 4096 25. Feb 23:59 pages
+ drwx---r-x 2 yourname yourname 4096 01. Jan 00:00 plugins
+ -rw----r-- 1 yourname yourname 33010 01. Jan 00:00 README
+ ftp> quit
+
+ In graphical FTP clients there is usually a menu entry to set
+ "access mode" or "access rights" (sometimes "file permissions") of
+ files and directories equally.
+
+ Again: don't forget to set the EWIKI_DBFILES_DIRECTORY constant to
+ the correct value!
+ If you create a subdirectory for the page files in the same directory
+ the main 'ewiki.php' script resides, you usually want to set the
+ config constant to just "./thesubdirectory" - here you could leave
+ out the "./" (not required as it only refers to the current path).
+ Btw, the slash character will work in directory specifications on
+ windoze systems too (mr. bill once had to introduce a hierarchical
+ filesystem in DOS 2.0, but choosed the bad backslashes, so no one
+ should notice where that idea was borought from).
+
+ The saved pages are in a format usually referred to as
+ "message/http" (like www service request) or "message/rfc822"
+ (internet mail). They usually look like:
+ +-----------------------------------------------
+ | id: WikiPageName\r
+ | version: 1\r
+ | flags: 1\r
+ | author: 127.0.0.1:3054\r
+ | created: 1046532697\r
+ | lastmodified: 1046532697\r
+ | refs: \nErfurtWiki\nNewestPages\n\r
+ | \r
+ | !! WikiSourceContent
+ | <more-text>...
+
+ This file format can be exported by the "backup" tool, so you could
+ easily change from the MySQL database to the flat-files one, if
+ desired. Each page file exists in different versions, where the
+ version number is always appended to the saved pages` file name.
+
+ EWIKI_DBFILES_NLR converts newlines into the string "\n", but just
+ for the values of the metadata. So there shouldn't occur much
+ inconsistency, because the wiki content is saved binary safe in
+ those "flat files".
+
+ Filenames will be heavily converted on Win32 (urlencoded), while on
+ state of the art UNIX/Linux systems only a few characters are
+ replaced (slashes into backslashes) to match filesystem requirements.
+
+ Problems: dbff WikiPageNames are currently not case-insensitive on
+ UNIX-filesystems (while the MySQL-table is).
+ Hits won't get counted; I don't think it is that essential, and it
+ would take too much effort and time (file accesses) to support this.
+
+ Note: You cannot do a "backup" from a Unix server to a Win box by
+ using a plain FTP program, because many characters are allowed in
+ Unix filenames but not on Win partitions. If you really want and
+ need to do so regularily, you could then setup ewiki with
+ EWIKI_DBFILES_ENCODE enabled from the very beginning. - The better
+ aproach was to use 'ewikictl' or 't_backup' or 't_transfer' for the
+ backup task.
+
+
+
+ plugins/db_fast_files
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ NOTE: The db_fast_files has been merged into db_flat_files, so both
+ formats can be read now - at the same time! Updated or new pages will
+ however always be written in the file format determined by
+ EWIKI_DB_FAST_FILES (defaults to 0), edit the "db_flat_files.php"
+ script to change that constant setting, or even add it to your
+ "config.php" so it was always present.
+
+ While "db_flat_files" allows you to edit the WikiPage files (using
+ any simple text editor), the "db_FAST_files" plugin saves the pages
+ in a binary&compressed format (utilizing PHP's serialize function).
+
+ This generally leads to a speed enhancement. Additionally this also
+ allowed the PageHit counting to be activated (which is off in plain
+ flat files).
+
+ So you may wish to use this plugin in favour of the older
+ db_flat_files. And as now both methods are available at the same
+ time, you can switch whenever you want.
+
+ Most of the setup guide from above is true for this one, too.
+
+ An additional configuration constant introduced here is
+ EWIKI_DBFILES_GZLEVEL, which tells the PHP internal zlib how much
+ time to spend on compression of the saved pages. Usually the zlib
+ uses a default of 5, but for speed purposes it is set to 2 here. You
+ can also set the constant to 0 so the files will get saved
+ uncompressed (but still in 'binary' format). A value of 9 will give
+ you the smallest possible files, but this takes a little more CPU
+ cycles (a bit slower).
+
+ This plugin was contributed by Carsten Senf.
+
+
+
+ plugins/db_any
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ If you use a relational SQL database other than MySQL, then you
+ may want to give this plugin a try. It itself provides a wrapper
+ for the PHP database access wrapper libraries ADOdb, PEAR::DB and
+ dbx().
+ These wrappers themselves provide unified access to various SQL
+ databases in contrast to the many highly different db access
+ functions of PHP. Each of these db access wrappers has advantages
+ and disadvantages and so none of them is really widespread and many
+ users of course only jump on one of these trains. Because ewiki now
+ tries to be 'library' it will use whatever database access wrapper
+ you already have running on your site or container CMS, and the
+ highly simplified anydb_*() now tries to make use of it.
+
+ The plugin is based upon the current MySQL database backend, and
+ thus may not be compatible to all proprietary SQL variants other
+ vendors usually enforce.
+
+ Before you can use the db_any plugin you must ensure that you
+ either already have the PHP dbx extension dll loaded or the PEAR::DB
+ or ADOdb include files loaded. db_any will like to see an opened
+ database connection inside of the global '$db' variable. If
+ yoursite.php hasn't already a connection opened when ewiki.php
+ gets included, then you should preferably choose to use the
+ anydb_connect() function to do so (it will choose from PEAR::DB,
+ ADOdb and PHP dbx interfaces).
+ The '$db' connection handle can be shared between your site and
+ ewiki as long as it is a handle for one of the mentioned database
+ access wrapper libraries.
+
+
+
+ plugins/db_adodb
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ obsoleted by plugins/db_any
+
+
+
+ plugins/db_dba
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ including() this plugin enables ewiki to store the WikiPages in the
+ Berkeley DB file given with the EWIKI_DBA constant. Your PHP binary
+ must be compiled with either the "dba" or the "dbm" extension to use
+ this (and the dba extension requires at least one other database
+ type to be enabled).
+
+ The plugin has a built-in list of preferred dba database types, but
+ it respects the filename extension of EWIKI_DBA. For example
+ "wiki.db3" would create a DB3 database file, while "wiki.gdbm"
+ resulted in a GDBM file, if that php extension was available.
+
+ The PHP dba extension can support the db types (if compiled for):
+ .gdbm
+ .ndbm
+ .db2
+ .db3
+ .db4
+ .flatfile
+ .dbm
+
+ If you have the PHP "dbm" extension enabled, wrapper functions will
+ get enabled, so this works even if the "dba" extension is not there.
+
+ The .flatfile is often available even if you haven't compiled your
+ PHP binary for anything else than "dba". This may also often be
+ faster than one of the db_flat_files plugins.
+
+ If EWIKI_DBFILES_GZLEVEL is set to a value from 1 (fast) till 9
+ (very good compression, but slow), the saved pages will get
+ compressed inside the dba database. With 0 this feature gets
+ disabled.
+
+
+
+ plugins/db_phpwiki13
+ --------------------
+ The original ewiki database table structure was compatible with the
+ one used in PhpWiki version 1.2.x, however it turned out that the
+ PhpWiki project has yet not stopped completely and choosed to
+ implement a more relational table structure with version 1.3
+
+ This plugin is only meant for transition __from__ PhpWiki v1.3.x to
+ ewiki, it should NOT be used to connect ewiki with PhpWiki forever.
+
+ Write access is disabled per default, but available. However it is
+ probably not fully compatible with the database abstraction and usage
+ of PhpWiki, so it is likely to corrupt your database if you use it
+ for a longer period of time. This warning is mainly because the
+ 'latestmajor', 'latestminor and 'minor_edit' rows in the PhpWiki
+ database, because such stuff is not used by ewiki at all. ewiki also
+ tries to put some of the pages meta data into places where it could
+ eventually confuse PhpWiki.
+ Write access is however done nearly as safe as within the ewiki
+ database access layer (INSERT statement to not overwrite existing
+ entries).
+
+ Again: this plugin is in no way meant to encourage you to keep your
+ old PhpWiki database! ;>
+ Please see also "tools/ewiki_convertdb.php".
+
+ If you temporarily enable this plugin within the default/example
+ "config.php" or the "tools/ewiki_tools_config.php" you can also
+ utilize the very powerful 'ewikictl' cmdline utility to generate a
+ copy of your PhpWiki database in one of the backup formats suitable
+ for later use with ewiki.
+
+
+
+ plugins/binary_store
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Is a hack into the ewiki core, which will store binary/uploaded
+ files outside of the default ewiki database (as plain files in a
+ data directory).
+
+ Please also see the documentation on top of the plugin file.
+
+ Per default ewiki can store "binary" entries beside ordinary text
+ pages in the database. If you'd like to keep uploaded files/images
+ out of the db, then this plugin/hack will help. It intercepts ewiki
+ and saves uploaded data into a plain data file, and instead creates
+ a "binary symlink" in the database for it (just the binary meta
+ data will get stored, with a hint on where to later access the plain
+ data file).
+
+ This may sometimes be a speed enhancement and reduces size of the
+ database, however it has the drawback that only the main ewiki
+ script can handle this transparently and all admin tools/ fail to
+ deal with the stored plain data files (no backup support and so on).
+
+ By setting the EWIKI_DB_STORE_URL constant correctly (corresponding
+ to your wiki setup and where you store the data files, compare with
+ EWIKI_DB_STORE_DIRECTORY) you can make ewiki create URLs directly
+ to where the stored plain data files reside (they do not contain
+ ewiki database meta data, and thus could be accessed directly by
+ http clients/browsers).
+
+ Please be sure to configure this plugin by setting _DB_STORE_DIRECTORY
+ to something more useful than "/tmp", so your uploaded files will
+ still be there after a reboot.
+
+
+
+core enhancements
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Some really cool features are put into extension plugins, and the most
+important, recommended and most often used ones are listed in this section:
+
+
+
+ plugins/patchsaving
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ If two users concurrently edit a page, then only the first saving
+ attempt will succeed; which the second user is told by the "This
+ page version was already saved" failure message.
+
+ This plugin works around this by passing the contents of the
+ concurrent versions through the 'diff' and 'patch' utilities, which
+ often merges the two different modifications in a new version that
+ can be saved into the database so there is no need for the failure
+ message.
+
+
+
+ plugins/notify
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This plugin enables users to get notified, whenever someone changes
+ a watched page. To enable 'watching' one must just place an email
+ address into the page with following syntax:
+ [notify:mail@example.com]
+
+ This bracket will be invisible, when a page is viewed, so it can be
+ placed anywhere. The notifications will be sent to this address
+ as long as the tag is there.
+
+ If one wishes to receive notification messages in another language,
+ this just needs to be added after a comma or semicolon, like:
+ [notify:pop3@example.net,de]
+ This is often only necessary for the generic TLDs .com .org .net,
+ or where language code and TLD differ.
+
+
+
+ plugins/jump
+ ¯¯¯¯¯¯¯¯¯¯¯¯
+ Introduces magic markup for page redirection (switching to another
+ page). Possible notations are:
+
+ [jump:OtherPage]
+ [goto:SwitchToThere]
+
+ The EWIKI_JUMP_HTTP setting tells this plugin to send a Location:
+ and redirect HTTP status when encountering a page [jump:]. Else
+ this plugin will show up the JumpDestination page without notifying
+ the browser about it.
+
+ It is also possible to perform InterWiki jumps, just be using the
+ common InterWikiMoniker: syntax. [jump:WardsWiki:WelcomeVisitors]
+
+
+
+ plugins/email_protect
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This plugin 'ciphers' all valid email addresses inside a WikiPage
+ for protection against automated spambots. Additionally it
+ throws fake/trap email addresses to spam spammers databases :>
+
+ It ist not integrated into the core script, because some people
+ may prefer to have email addresses visible (intranet usage).
+ However it is HIGHLY RECOMMENDED to enable this plugin. Despite
+ its file size it is rather fast.
+
+
+
+ plugins/spages (StaticPages)
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The "StaticPages"-plugin allows ewiki to access files in a given
+ directory. If these files are in text format, ewiki will parse them
+ as WikiPages. But if you put files with an extension .html, .htm or
+ .php into one of the specified StaticPages` directories they will
+ be returned as is from ewiki_page() - the .php files will of course
+ get executed and their output is returned.
+
+ The basename of the files in the directories to be used by spages
+ will make up the WikiPageName with which the files will be
+ accessible.
+
+ Any given directory (see on top of plugins/spages.php) will be read
+ recursively. So files in a subdirectory will get available as a
+ page with a name like "subdir/FileName". If the name of the
+ subdirectory contains a dot at the end, then the slash will be left
+ out in favour of a dot: resulted in "subdir.FileName" for example.
+
+ PHP scripts in a spages directory however have some restrictions,
+ like not being able to return headers() or to access most global
+ variables without use of the $GLOBALS[] syntax. If you rely on
+ such functionality you should rather write an ordinary page plugin
+ (which in fact is often much easier).
+ From the output of .html and .php scripts only the parts between
+ <body> and </body> will be returned as page content. Any <html>
+ head area will get stripped, as it would lead to completely invalid
+ html code if it was returned as is by ewiki_page() into yoursite.
+
+ To let this plugin load pages from directories, you should either
+ edit the array on top of this plugin file, or define() the
+ EWIKI_SPAGES_DIR (before! including the spages.php script), which
+ then also would be read in.
+ Alternatively you could call the ewiki_init_spages() function
+ yourself to register a directory for processing (after! loading the
+ spages plugin):
+
+ include("plugins/spages.php");
+ ewiki_init_spages("/var/www/wiki/staticpages/");
+
+ You could also use this plugin to inline the ewiki database tools/
+ as virtual pages.
+
+ Btw, it is very easy to make a StaticPage from a ewiki page plugin
+ and vice versa. Please also note the tools/mkpageplugin which can
+ convert anything used as StaticPage into a page plugin for easy
+ including() with other ewiki plugins.
+
+
+
+ plugins/pluginloader
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The pluginloader plugin automatically loads ["action"] and ["page"]
+ plugins, whenever necessary. This allows to skip dozens of
+ include() statements within the config.php (which most always just
+ slow down script startup). It is configured via a static array,
+ which defines which plugins are allowed to be automatically invoked
+ on request.
+ Detailed explanaition is available within this script.
+
+
+
+ plugins/init
+ ¯¯¯¯¯¯¯¯¯¯¯¯
+ Handles database initialization using the distributed standard Wiki
+ files from './init-pages'. Unlike the ewiki-builtin function to
+ perform that task, this plugin first outputs informational notes
+ to the user, prior database initialization.
+ Once you have your SQL or ./files database initialized, you should
+ disable this plugin (it then isn't be required anymore).
+
+
+
+ plugins/feature/appendonly
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This plugin (a family of) implements the actual support for the
+ _DB_F_APPENDONLY page flag. When the flag is set, and this plugin
+ active, then ordinary users can further only append text to the
+ page, and won't be able to edit the earlier written parts of it. So
+ this implements a much softer approach than the _READONLY page
+ flag.
+
+ Also this plugin comes in three flavours, but you can often only
+ load one of them:
+
+ "appendonly" - Really allows just additions to be made to the page,
+ each new separated by a horizontal bar.
+
+ "appendwrite" - Allows to insert a page separator, which protects
+ the upper part from getting edited by ordinary
+ users. Everything below a horizontal bar (denoted
+ by at least 16 minus signs) or a double horizontal
+ bar remains editable by all users.
+ This plugin activates only if the _APPENDONLY and
+ _WRITEABLE flag is set.
+
+ "appendcomments" - stores page additions in an separate database
+ entry marked with _DB_F_PART, but allows this part
+ to get edited as whole (like "appendwrite" plugin).
+
+ The last one is probably not very useful, as it generates some
+ overhead and in fact is a collection of various workarounds to
+ accomplish the desired functionality (so it may prove little
+ lifetime).
+
+
+
+ plugins/feature/imgresize_gd
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Was extracted from the core during the R1.00f development releases.
+ Automatically rescales uploaded images, if they are larger than
+ EWIKI_IMAGE_MAXSIZE.
+ As it uses the gd2 library, there must be support for this in your
+ PHP binary. There are a lot of problems on Win32 systems, and also
+ some Linux binarys (-dev ones) crash constantly if you load this
+ plugin but don't have the libgd activated or available.
+
+
+
+ plugins/feature/imgresize_magick
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Rescales uploaded images via the ImageMagick utility "mogrify",
+ which is usually only available on UNIX systems. It should however
+ be fairly simple to make this plugin work with some other image
+ manipulation tool (at least with Linux).
+
+
+
+ plugins/feature/spellcheck
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Turns the [preview] button below every page edit box into a
+ spellcheck function.
+
+ You need a working 'aspell' or 'ispell' on your system, or the
+ PHP internal aspell functions - as it is rather slow it only shows
+ up the first 20 errors on a page
+
+
+
+action/ plugins
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Action plugins are those, that can be activated ON individual pages. And
+usually are shown as links below a page. The ewiki-builtin EditThisPage,
+BackLinks and PageInfo are ["action"] plugins for example.
+
+
+
+ plugins/action/diff
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Enables to view the differences between two saved page versions
+ (what changes somebody has done to the page), but it is rather
+ stupid and guessworking in how it does so.
+
+
+
+ plugins/action/translation
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This plugin adds a link to the GoogleLanguageTools or AltaVista
+ BabelFish, which then remotely translated the current page into
+ the users preferred language. It has support to detect the lang
+ of the current pages content, to redirect to the right service.
+
+
+
+ plugins/like_pages
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ LikePages is a search feature of WardsWiki, which scans for
+ WikiPages whose name is somewhat similar to the one of the current
+ page (the pagename must be made up of the same WikiWordParts so a
+ page gets listed).
+
+
+
+ plugins/action/raw
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Can be used to download the unrendered Wiki source of a page.
+
+
+
+plugins related to hypertext links
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+The linking/ plugin group deals with how links inside the Wiki will look and
+work. Some of them are would also fall the "core enhancements" group, while
+others are just handy or for link beatification.
+
+
+
+ plugins/linking/tcn
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ ewiki evaluates the Accept-Language HTTP header modern browser
+ send with each request. This plugin now automatically brings up
+ a variant of the current requested page if it finds a match in
+ the database. To make it work, you need to create pages with
+ language suffixes in their names like:
+ ThisPage.es
+ ThisPage
+ ThisPage.de
+ or
+ OtherPage
+ OtherPage*nl
+
+ Note, that there can always be one page in each name group without
+ that suffix. This page then will be assumed to be in the default
+ language set by EWIKI_DEFAULT_LANG.
+
+ If multiple page versions are available, then a list will be
+ printed above the page title to allow users to override the
+ prefered language guess of this plugin.
+
+
+
+ plugins/linking/plural
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This plugin tries to alias plural and singular page names against
+ each other. That is, "WikiPage" will be shown, whenever "WikiPages"
+ was requested (and vice versa).
+
+
+
+ plugins/linking/autolinking
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The autolinking plugin allows to have automatic links inside the
+ Wiki for words which exist in the database, but are no real
+ WikiWords. This is made possible by the companion StaticPage
+ admin plugin "spages/Admin/PrepareAutolinking", which must be
+ invoked from time to time to update the db cache entry, which the
+ autolinking plugin utilizes.
+
+
+
+ plugins/linking/link_css
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Adds CSS classes to the links generated by the Wiki page formatting
+ kernel, which then allow you to colorize (or to otherwise change
+ appearance of links) via a style sheet.
+
+
+
+ plugins/linking/link_icons
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The link_icons plugin prepends icon <img>s before registered link
+ types, like the link_css plugin adds class="..." attributes to the
+ html formatted links in every page.
+
+
+
+ plugins/linking/link_target_blank
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Adds 'target="blank"' to link tags <a>, which will result in most
+ browsers opening pages in a new window.
+
+
+
+ plugins/linking/linkexcerpts
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Adds a short preview text (with <a title="...">) to every link of
+ a page. This however requires multiple additonal database accesses
+ (slower) and could enlarge delivered .html page sizes dramatically.
+
+
+
+ plugins/linking/linkdatabase
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Is a page plugin, which provides a nearly compliant implementation
+ of the page and link structure export function known from the UseMod
+ WikiWare and MeatBall:LinkDatabase. This is useful for contributing
+ to the upcoming InterWikiBatabase and BorgWiki.
+
+
+
+ plugins/linking/instanturls
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to specify URL abbreviations on one or more summary pages.
+ This can be done using a table or a definition list to assign
+ each URL a title, which then can be used on other pages as square
+ bracket reference.
+
+ The 'instanturl_find' plugin in addition allows to use the [find:]
+ moniker to perform partial searches in the list of URL
+ abbreviations, but also in the list of interwiki monikers. As
+ fallback it searches for matching page names or redirects to
+ Google.
+
+
+
+ plugins/linking/titlefix
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to swap [title|PageName] in square brackers [Page|title],
+ because that can easily be detected, if the page already exists.
+
+
+
+ plugins/interwiki/intermap
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This plugin (in fact only a general include) extends the list of
+ known InterWiki: prefixes with a more complete set merged from
+ MoinMoin and PhpWiki's interwiki.map. The links are rather
+ untested to work at the moment.
+
+
+
+
+appearance/ tweaks
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+There are various plugin hooks within ewiki, which allow to mangle text
+strings and data immediately before it would be returned as output.
+
+
+
+ plugins/appearance/listpages_br
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This plugin will produce <br> separated lists (for SearchPages,
+ PageIndex, MostVisitedPages, and so on).
+
+
+
+ plugins/appearance/listpages_ul
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Creates real <ul> lists (WordIndex, CreatedPages, ...) instead of
+ the · ones, ewiki core would usually return.
+
+
+
+ plugins/listpages_tbl
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The listpages_tbl plugin outputs a table instead of the ordinary
+ page lists (PageIndex, UpdatedPages, ...). You need to edit its
+ source to set colours to fit your site layout.
+
+
+
+ plugins/appearance/fancy_list_dict
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The WordIndex and PageIndex plugins (unlike the other page list
+ returning ones like SearchPages and UpdatedPages) can utlize this
+ plugin to output a pretty dictionary like listing of pages.
+
+
+
+ plugins/appearance/title_calendar
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Changes the titles of calendar plugin entries in the database into
+ a more readable format for page lists (PageIndex, PowerSearch,
+ UpdatedPages, and so on).
+
+
+
+page plugins
+¯¯¯¯¯¯¯¯¯¯¯¯
+The page plugins provide additional "generated/internal" pages, which have
+a standard WikiWordPageName and can thus be referenced easily from within
+ordingary WikiPages. But they are of course uneditable (because their
+content is 'hardcoded' as PHP code) and most action/ plugins cannot perform
+any function on them.
+
+With the rise of the StaticPages plugin, the page plugins are almost
+outdated, because all their code could now be extracted into a StaticPage
+file, so their code had to be loaded only on request (instead of including()
+them regardless if they're needed or not, how it currently is done).
+
+
+
+ plugins/page/powersearch
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This plugins provides a (probably) better search function
+ with the default page name "PowerSearch". It tries to guess
+ a value, which tells something about how good a page matches
+ the searched words and orders the found pages list by this
+ (possibly not very useful) value. It prints the top 10 results
+ more verbose.
+
+
+
+ plugins/page/pageindex
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Lists all pages found in the database alphabetically.
+
+
+
+ plugins/page/wordindex
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Lists the word parts of all wiki pages, but requires the
+ powersearch plugin to be present, because the result is redirected
+ to there as usually many of the listed words belong to multiple
+ page names.
+
+
+
+ plugins/page/imagegallery
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Outputs a page containing all cached/uploaded images. The
+ images are currently not rescaled to fit on the page; this
+ work is left to the browser.
+ Needs enhancement.
+
+
+
+ plugins/page/aboutplugins
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Lists all registered plugins (mpi, page, action, task/core). The
+ name refers to the "about:plugins" page present in recent browsers.
+
+
+
+ plugins/page/orphanedpages
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Shows up a list of pages, that exist, but are not linked from any
+ other pages. These is often also called dead pages.
+
+ Note that this plugin does not take into account, if any page
+ can be reached from the frontpage - such a hypertext tree test
+ would require much more work than realized in here.
+
+
+
+ plugins/page/wantedpages
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Returns a list of pages to which QuestionMarkLinks? currently
+ exist.
+
+
+
+ plugins/page/since_updates
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Provides a list of pages with actualization times.
+
+
+
+ plugins/page/textupload
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The virtual TextUpload plugin allows to insert new WikiPages by
+ uploading text files. It can convert from various formats into Wiki
+ content, including some proprietary Office file formats, if one of
+ the possibile filters is avaiable (Unix style file piping).
+ It also can extract multiple files from a Tarball or ZIP archive
+ if the according utilities are available (even on DOS/Win systems).
+
+
+
+ plugins/page/wikidump
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to download a gzipped tarball containing all readily
+ rendered pages as .html files and also images.
+
+
+
+ plugins/page/interwikimap
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Shows up the currently in use InterWikiMap.
+
+
+
+ plugins/page/hitcounter
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Sums up the individual {hits} count of all pages and returns the
+ overall count.
+
+
+
+ plugins/page/scandisk
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Presents an unserious statistic.
+
+
+
+ plugins/page/wikinews
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Returns the most recently added pages in an overview, that
+ incorporates a small fragment from the content of those newly added
+ pages.
+
+
+
+ plugins/page/wikiuserlogin
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to set a free-form username, which then would be stored into
+ the database whenever a page was edited.
+
+
+
+ plugins/page/randompage
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Shows up a randomly choosen page from the database.
+
+
+
+ plugins/page/fortune
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Calls the Unix /usr/games/fortune program and prints out returned
+ content.
+
+
+
+ plugins/page/ewikilog
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to review the content of the 'ewiki.log' file.
+
+
+
+ plugins/page/phpinfo
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Shows the settings of your PHP interpreter.
+
+
+
+ plugins/page/README
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Can parse the distributed README file and make a hypertext
+ presentation from it, for easier reading of the Wiki documentation.
+ It is printed in <pre> text, but with WikiLinking enabled (which
+ however is rarely used in the README file). It additionally
+ presents the README.de and README.auth files.
+
+
+
+ plugins/page/wikiuserlogin
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to post a username (Note: this one does not do any sort of
+ real authentication), which is saved in the http client as cookie,
+ but can afterwards be evaluated as $ewiki_author, so the according
+ field in the database entries contains a bit more than just
+ the IP address when a changed page gets saved.
+
+
+
+markup plugins
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+The ewiki rendering core is rather fast and consolidated, that was the goal.
+However if you ever happen to need more functionality, this can be added
+easily by the use of plugins.
+
+Several are already available to emulate the WikiMarkup of other commonly
+used WikiWare.
+
+
+
+ Other WikiWares markup
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The WikiWorld still lacks a unified markup (and thus also the
+ interchangeablity that made html THE standard it today is), and
+ while ewiki usues nearly MeatBall:WikiMarkupStandard, you may want
+ to reuse existing pages from another Wiki.
+
+ Currently we provide emulation for:
+ * PhpWiki
+ * sfWiki
+ * miki
+ * bbcode (BulletinBoard, not a Wiki)
+
+ But please see the individual files on which (additional) markup
+ they introduce.
+
+ These plugins on occasion only register their markup within
+ $ewiki_config["wm_*"] settings, but often just perfrom
+ pre-conversion of foreign markup by utilizing the ["format_src"]
+ plugin hook (they then pre-convert page content to use ewiki
+ markup rules before the ewiki_format() kernel performs
+ transformation).
+
+
+
+ plugins/markup/css
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ CSS markup allows you to assign visual styles (or semantic CSS
+ class names) to a block of text (paragraph) or to pieces of text.
+ @@ is used to start a styled area. The @@ must be immediately
+ followed by either a CSS class name (without the dot) or with
+ CSS instructions without any whitespaces.
+ The following text (after the @@, the class name and a space) will
+ then be assigned the class until a (possible) next @@ without
+ attached classname or style definition.
+
+ If the @@ occurs at the start of a paragraph it will enclose it
+ in a <div> with the according style assignment, otherwise (in the
+ text) a @@ will become a <span>.
+
+ See also the explanation and examples in this plugins` comments.
+
+
+
+ plugins/markup/css_singleat
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This plugin allows you (like the markup_css plugin) to attach CSS
+ classes to a paragraph of text with just a single @ character:
+
+ @JAVADOCLIKE paragraphs text...
+ ... ... ... .... ... ... ... ...
+
+
+
+ plugins/markup/footnotes
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Introduces the ability to generate footnotes by placing an
+ explanation into double curly brackets {{footnote text}}.
+
+ You should activate this only if you really need it. Sometimes this
+ may be useful, but it is rather bad wiki style; because if someone
+ would like to explain something in more detail he should create a
+ WikiLink to a new page. So this should be used for very short
+ explanations, say incomplete sentences or a book reference and
+ other things where it really seems bloat to create a new page.
+
+ USE THIS RARELY or better not at all!
+ (this is a feature copied from MS` EvilWiki)
+
+
+
+ plugins/markup/asciitbl
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to use ASCII-Art tables as outputed by lynx and other
+ console programs inside of WikiPages, which eases life, when
+ dealing with multiline table cell content.
+
+
+
+ plugins/markup_complextbl
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ ewiki allows you to use tables with the || | characters in the wiki
+ page source. However the html code for the table layout is
+ hardcoded and cannot be changed on a per-page basis.
+ This plugin intercepts the wiki source formation process to allow
+ you to specify html tag attributes inside a table definition like:
+
+ |{ border=0 cellspacing=10} here is | the table | content |
+ | 2nd line | 2nd line |{ rowspan=2} fills two table rows |
+ |{ colspan=2} 3rd line |
+
+ Note, the opening "{" must follow the "|" character immediately.
+
+ This code was provided by Hans B Pufal.
+
+ It may be a security risk to include it per default, as this allows
+ to add SomethingScript references as well.
+
+
+
+ plugins/markup/htmltbl
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Provides a block escape to use the standard html <table> code
+ instead of the limited pipe syntax provided by ewiki. It will parse
+ for <tr> and <td> tags and strip any not registered attributes to
+ defend against harm that could be caused by EvilScript additions.
+
+ The common html <table> syntax then allows easily to include
+ multiline table cell content, which is nearly impossible (to edit)
+ for the "|...|..|" table syntax.
+
+
+
+ plugins/markup_rescuehtml
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to use some 'safe' HTML tags within the WikiPage. This
+ plugin replaces the previous EWIKI_RESCUE_HTML constant.
+
+ Note that those 'safe' HTML tags may also lead to some confusion,
+ especially if you have a wiki about HTML, because then you cannot
+ write text about the <STRONG> tag because it will actually always
+ be interpolated as itself and not as the text string "<STRONG>".
+
+
+
+ plugins/contrib/rendering_phpwiki12
+ -----------------------------------
+ This is the rendering kernel of PhpWiki 1.2 which was made compatible
+ with the ewiki function set.
+ It may be useful to reuse old WikiPages, but anyhow most of its
+ features are supported by the standard ewiki rendering kernel, so
+ this is just a fun and proof-of-concept plugin.
+ ..................................................................
+ : The code of this module is covered by the GPL license, as it :
+ : was copied verbatim from the PhpWiki project. :
+ ··································································
+
+
+
+ plugins/rendering_null
+ ----------------------
+ If someone would like to use ewiki for a personal homepage, but
+ prefers HTML over WikiSyntax, then this rendering core replacement
+ may suit his needs. It allows HTML to be used, but still renders
+ WikiWords into valid hyperlinks (a few other features from the
+ original ewiki_format function are also supported, but you can
+ strip even those).
+
+
+
+mpi
+¯¯¯
+The so called "mpi" plugins can be embedded into pages, and produce their
+output there. They are loaded on demand (only if it appears that they should
+be invoked), but it is possible to include() the individual files regardless
+if they would be used or not.
+
+In order to have the mpi plugins available, you must however first load the
+mpi dispatcher:
+ include("plugins/mpi/mpi.php");
+Which then takes care of the markup and loading of the requested plugins.
+
+The syntax for calling a mpi plugin is (write this inside of a WikiPage,
+when editing it):
+
+ <?plugin PluginName arg="..." arg2=DDD ?>
+
+Where args are often optional or could even be written without the 'argname='
+if only one was required. The name of the mpi plugin is case-insensitive
+here.
+
+It is often possible to invoke mpi plugins like ["page"] plugins, if you
+create a link inside of the page using the syntax <?plugin-link PluginName ?>
+
+
+
+ mpi_backlinks
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Prints a list of BackLinks to the current page (the same as when
+ clicking on the title of a page or on the BackLinks action link).
+ <?plugin BackLinks ?>
+ <?plugin BackLinks page=ForThatPage ?>
+
+
+
+ mpi_multimedia
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to <embed> multimedia files into a page.
+
+
+
+ mpi_syndicate
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Embeds remote RSS feeds (abbrv. for "ReallySimpleSyndication" or
+ "RichSiteSummary") into the current page. It caches the fetched
+ data for quite some time in a pre-parsed _BINARY database entry.
+
+
+
+ mpi_insert
+ ¯¯¯¯¯¯¯¯¯¯
+ Allows to insert another readily rendered WikiPage into the current
+ one, usually inside of a <table border="1">.
+
+
+
+ mpi_localsitemap
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Is a mix of BackLinks and LinkTree features, and prints the tree of
+ pages backreferencing to the current one.
+
+
+
+visual extensions
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+The hook following plugins utilize is called "append-view". It allows to put
+content below a pages contents (after the action links).
+
+
+
+ plugins/aview/backlinks
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Adds the list of BackLinks (references from others to the current
+ page) to the current page below it (this list is also available,
+ when a user clicks on the title of a page).
+
+
+
+ plugins/aview/linktree
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Prints the possible (shortest) paths to the FrontPage (determined
+ by the EWIKI_PAGE_INDEX constant) starting from the current one
+ below. Calculations and database access required by this plugin
+ often means a slowdown up to 2 seconds before the page is readily
+ rendered.
+
+
+
+ plugins/aview/toc
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Analyzes a pages headlines and generates a list of contents box
+ from it, which is inserted as float box on top of it then. Use the
+ following CSS selector to style it:
+
+ .wiki .page-toc {
+ ...
+ }
+
+
+
+ plugins/aview/posts
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to add separate comment pages, which will then always be
+ displayed below the current one, but remain editable as standalone
+ pages. (So the page they are appended to could be marked as
+ _READONLY).
+
+
+
+ plugins/aview/threads
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to group the pages created using the "posts" plugin into
+ threads.
+
+
+
+ plugins/aview/subpages
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Adds the list of pages, which appear to be SubPages of the current
+ one, below it.
+
+
+
+ plugins/aview/downloads
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Shows the uploaded files, which appear to belong to the current
+ page (individual pages can be treated as upload sections).
+
+
+
+ plugins/aview/imgappend
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Prints an image uploading box below every page, which allows to
+ append an image without prior clicking EditThisPage (the image
+ will be automatically appended to the bottom of the page).
+
+
+
+ plugins/aview/piclogocntrl
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This plugin allows users to select a logo graphic which will be
+ made available for use in the site template as
+ $ewiki_config["page_logo"]. Configureable through the internal
+ image list array.
+
+
+
+ plugins/aview/aedit_pageimage
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This plugin allows users to select a page image graphic, and is a
+ mix of the aview/piclogocntrl and page/imagegallery plugins.
+
+
+
+ plugins/aview/control2
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Shows examplarily how to replace the standard "action-links" box,
+ and adds it on top of the page (including the page title).
+
+
+
+ plugins/aview/aedit_authorname
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Adds a text <input> field below the edit/ box, which allows to
+ set the AuthorName which then will get stored, when the page is
+ saved. This name is then also stored client-side as cookie for
+ at least 45 minutes.
+
+ Before using this plugin, you must consider, that it eventually
+ allows to override the correct username that ProtectedMode plugins
+ already provided. And there is no way to prevent users from using
+ faked names (because this plugin cannot check if a username was
+ already 'registered' and thus can't initiate a password query).
+
+
+
+ plugins/aview/aedit_deletebutton.js
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Adds a JavsScript snippet to allow users to quickly mark a page
+ for deleterequest, by inserting the link to "DeleteMe" into the
+ contents, when editing it.
+
+
+
+page filters
+¯¯¯¯¯¯¯¯¯¯¯¯
+A few plugin hooks exist to completely rework generate page output. These
+are often used to insert content into the otherwise readily rendered .html
+pages (some of the above aview plugins do so, too).
+
+
+
+ plugins/filter/f_fixhtml
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Is a minimal tag balancer (a highly simplified HTML tidy) and can
+ work around various html code problems that the ewiki_format()
+ html rendering function has. It is for example specialized to
+ correct broken html that resulted from WikiMarkupAbuse as for
+ example nesting text style attributes like this: __''text__''
+
+
+
+ plugins/filter/search_highlight
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Evaluates the Referer header sent by many browsers to detect if
+ a visitor came from a search engine (even the internal PowerSearch
+ or SearchPages ones) and highlights the searched words in the
+ current pages body (using CSS).
+
+
+
+ plugins/filter/fun_chef
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Borg, Borg, Borg!
+
+
+
+ plugins/filter/fun_upsidedown
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Transforms a pages content using letter transformation to make
+ them readibly from upside down with certain fonts. This however
+ is a bit tricky for html pages and thus will always wrongly
+ intermix sentence order.
+
+
+
+ plugins/filter/fun_wella
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Adds a little CSS to make text swirrling on both sides.
+
+
+
+ plugins/filter/fun_screamomatic
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Detects if someone entered a FULL LINE OF YELLING into a page
+ when editing it, and then sets a persistent cookie. That cookie
+ will result in all pages contents to be converted into uppercase
+ characters.
+
+
+
+ plugins/filter/f_msiepng
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Converts .png <img> references in the WhateverX code required by
+ all current IE versions to display .png images according to the
+ specification (which currently only an IE external plugin can handle
+ correctly).
+
+
+
+BloatWiki extensions
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ewiki slowly evolves into a well-bloated portal software, and some plugins
+already extend it far beyond the scope of an ordinary Wiki.
+
+
+
+ plugins/module/calendar
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The calendar plugin enables you to add an editable calendar to
+ every WikiPage. It is not a fully integral part of ewiki, and needs
+ additional calls from yoursite.php to integrate nicely into your
+ sites layout.
+
+ You even don't need to allow a calendar to be added to every page,
+ you can just include the plugin file and use the _one_ page called
+ "Calendar" or "YearCalendar", where everybody can make additions.
+
+ The coolest about this plugin is, that it nicely integrates into
+ the common WikiNameSpace.
+
+ Just include("plugins/calendar.php"); so it gets available.
+ In yoursite.php integrate it as follows:
+
+ <?php
+ ...
+
+ echo ewiki_page(); // print current pages content, as usual
+
+ ...
+
+ if ( calendar_exists() )
+ {
+ ...
+ echo calendar(); // print calendar for current page
+ }
+ else {
+ ... // else only a link to the cal. page
+ echo "<a href=\"?id=calendar/$ewiki_id\">ShowCalendar</a>";
+ }
+
+ ?>
+
+ The calendar() function call emits the html for the calendar of the
+ currently viewed page (see ewiki_page() call).
+
+ The function calendar_exists() only checks for already existing
+ event entries in the calendar, so the calendar won't show up, if
+ there isn't yet anything inside (so only the "ShowCalendar" link at
+ the bottom of the page will link to the still empty calendar). You
+ can of course leave out this function call or alternatively call
+ it with calendar_exists($always=true) if you want the calendar to
+ appear most of the time / or for all pages.
+
+ Please note the "fragments/calendar.css" file, which illustrates
+ how to tweak layout and look of the generated calendars.
+
+ This plugin was contributed by Carsten Senf (originally
+ implemented for good old PhpWiki).
+
+
+
+ plugins/module/downloads
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ From the very beginning the ewiki core supported uploading image
+ files into the database. As time and discussions went on, there
+ came the idea to allow arbitrary binary files to be inserted too.
+
+ The old EWIKI_ALLOW_BINARY way should now be avoided, because the
+ download plugin adds more functionality and more features, and is
+ easier and more intuitive to use.
+
+ It adds the virtual page FileUpload to insert a file into the
+ database, and the page FileDownload, which lists all available and
+ uploaded binary files from the db.
+
+ Please note, that due to the use of the database interface, the
+ file sizes are usually limited to 1-2M (depending on PHP and MySQL
+ settings), so there may still be some need to reimplement this,
+ using the antique world-writable incoming/ directory method.
+
+ The mime_magic plugin should be used together with this one, and
+ you should change the icon file names (use the ones from the Apache
+ distribution for example).
+
+ (It may also be a good idea to run a secondary database if you
+ use it. Have a look at fragments/binary.php, and set up a
+ secondary ewiki database using it and the db_flat_files plugin.
+ This is useful, because you then can more easily delete uploaded
+ files as they don't get saved into a SQL database.)
+
+ Different download sections can be defined. The "*" merges all
+ allowed sections into one list again, and the "**" section even
+ lists the files attached to pages.
+
+ The page attachment link (to append download functionality to each
+ page) can be revoked by unsetting the $ewiki_plugins["action"]
+ line in the downloads.php file; so only the default sections are
+ accepted (and page names rejected).
+
+ The plugins/downloads_view.php brings up the list of uploaded
+ attachments below each page (if existing). It works rather fast
+ due to an improved database search call, and should therefore be
+ activated whenever you use the per-page attachments feature.
+
+ See also plugins/binary_store.php to keep your SQL database small,
+ but note its limitations.
+
+
+
+ plugins/module/tour
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Provides a shortened view of the current page and all linked ones
+ (even the backlinked ones). This eases navigation and page content
+ "scanning" (getting a quick overview).
+
+
+
+
+utility code
+¯¯¯¯¯¯¯¯¯¯¯¯
+The plugins/lib/ directory contains code and functionality, which often is
+required by some of the other plugins (they depend on it then), but which
+was too specialized to get part of the ewiki.php core script.
+
+Other extensions in the lib/ subdir didn't match in any of the other plugin
+categories.
+
+
+
+ plugins/lib/cache
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This plugin stores readily rendered Wiki page content (already in
+ html format) either into a dedicated directory, or into specially
+ named _BINARY wiki database entries. This then allows to satisfy
+ further requests to a page with the saved content.
+
+ You should set EWIKI_CACHE_DIR to a useful value (a so called
+ "chmod 777" directory, so your webserver process can write into it),
+ or alternatively unset this constant and instead define
+ EWIKI_CACHE_DB so cache entries get stored into the ewiki database.
+ The _CACHE_DB constant is just prepended to the name of the current
+ page to get the name for the database entry for the cache data.
+
+
+
+ plugins/lib/speed
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Evaluates the "conditional HTTP request headers" to tell a client
+ if it could reuse its existing cache entry for a requested page.
+ This is believed to reduce traffic and also speed up some
+ applications. However it is still rather untested and could anyhow
+ lead to some problems (never updating pages for some broken
+ browsers). The evaluated headers include "If-Unmodified-Since:"
+ which corresponds to the "Last-Modified:" answer header ewiki
+ always sends.
+
+ However this will only work, if you disable EWIKI_NOCACHE - but
+ then some browsers will never see updated pages, if they were
+ misconfigured to not refetch pages, once they got into the internal
+ browser cache. (But on the other hand, that is users fault ;)
+
+
+
+ plugins/lib/mime_magic
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Implements the mime_magic feature absent from some (older and
+ misconfigured current) PHP interpreter versions (check your phpinfo
+ and /etc/mime.types).
+
+ This is recommended in conjunction with the downloads plugin to
+ store correct mime type data, for proper use of icons beside
+ download links. Also the correct Content-Type header should always
+ be available, when binary content is delivered.
+ ..................................................................
+ : The data of this plugin is covered by the GNU General Public :
+ : License. :
+ ··································································
+
+
+
+ plugins/lib/navbar
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Provides a configureable menu for the contents of your Wiki for
+ inclusion in your site template, which changes depending on which
+ site area you're currently inside (determined partially by
+ the linktree plugin).
+
+
+
+ plugins/lib/protmode
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Is an extension package (currently in development) with various
+ helper functions for ProtectedMode plugins. Especailly useful in
+ conjunction with the auth-liveuser framework.
+
+
+
+ plugins/lib/save_storevars
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ An example script on how to store additional vars into page entries
+ of the ewiki database (session like).
+
+
+
+admin/ plugins
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Collects plugins for ewiki / database administration. Often these depend
+upon $ewiki_ring==0 (superuser authentication level in EWIKI_PROTECTED_MODE),
+otherwise refuse to work for security reasons (some functions are however
+available to moderators too, ring level 1).
+
+Some of these plugins may be reimplementation of stuff from the tools/
+directory (integrated database tools).
+
+
+
+ control
+ ¯¯¯¯¯¯¯
+ Allows changing per-page settings, and adds a easily accessible
+ "page control" action link below every page.
+
+ You can use this to immediately change per-page flags (_READONLY,
+ _HTML, _DISABLED and so on). Or you can delete a unwanted page as
+ soon as you discover it.
+ It also enables you to edit any entries in the {meta} field of
+ database entries (which sometimes contain HTTP headers, or page
+ "class" settings).
+ And the fourth possible action is to easily rename the page (with
+ letting ewiki adjust all links to it without further intervention).
+
+
+
+ SearchAndReplace
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Is a powerful text/content replacement tool. It features regular
+ expression matching, but can also be used as any other simple string
+ replace-all tool.
+
+
+ SearchCache
+ ¯¯¯¯¯¯¯¯¯¯¯
+ This tool is intended to create 'shadow pages' (or 'ghost pages')
+ for ewiki internal/generated pages (the ["page"] plugins), which
+ usually weren't found by the PageSearch and PowerSearch. This
+ admin plugin just innovocates those page plugins and puts their
+ html output into the database (which then can is found by the
+ search functions, but is never displayed, because the page plugins
+ still have precedence over that faked database content).
+
+
+
+other plugins
+¯¯¯¯¯¯¯¯¯¯¯¯¯
+These plugins actually implement some stuff, one usually should do inside
+of the yoursite.php ewiki wrapper script.
+
+
+
+ plugins/debug/
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Eventually contains debug plugins.
+
+
+
+ plugins/auth/
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Contains various (example and ready to use) plugins for the
+ ewiki_auth() interfaces. This directory contains its own
+ README.auth, which describes the _PROTECTED_MODE, the _auth API and
+ available sample plugins in detail.
+
+
+
+ plugins/auth-liveuser/
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Contains the more advanced authentication and permission plugin
+ bundle for chaining ewiki with the PEAR LiveUser authentication
+ framework. There is detailed documentation within the README in
+ this subdirectory.
+
+
+
+separate "extra" tarball
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+There are a few plugins and extensions, which are not packaged into the
+distributed ewiki tarball for size reasons. You can obtain it from your
+favourite dealer, or from our downloads/ directory as "extra-CVS-*"
+tarball.
+ http://erfurtwiki.sourceforge.net/downloads/
+
+The package currently just contains a minimal spam filter (which after all
+isn't very useful for a Wiki site), but in the future will also provide
+additional example/ layouts and some image/graphics/icons for layout
+beatification purposes.
+
+
+
+
+
+
+
+
+ -------------------------------------------------------------------- 7 --
+
+
+
+
+
+More separate files
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Even if one of the project goals was to have everything in one script,
+there are now some support scripts around it, but those are normally
+only required for setup (init-pages for example). With some others you
+need to take a lot of care before installing on a public WebServer
+(the tools/ for example).
+
+
+
+Pages in init-pages/
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+This directory just contains text-files with the wiki_source of the
+initial pages, which are inserted if you start ewiki.php for the
+first time.
+You can create these files with the tools/ewiki_backup.php script
+or the 'ewikictl' commandline utility.
+
+
+
+Additional tools/
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+This directory holds some (external) add-ons, which are intended to
+supply "admin functions" for the ewiki database.
+It is strongly discouraged to integrate this with ewiki, as it could
+be dangerous to have them always around and usually such stuff just
+complicates things (wiki's should be easy to use).
+
+Per default you will be presented a HTTP Basic AUTH login dialog box
+by your browser if you try to use one of the www tools. This is made
+to prevent other people from doing any harm to the setup.
+In the "tools/t_config.php" script you'll see a link (include) to
+"fragments/funcs/auth.php", which is responsible for this integrated
+security feature. Just insert a username and a password here to start
+using one of the tools/.
+Please keep in mind, that the $passwords array of that ".../auth.php"
+script has nothing to do with the _auth API or EWIKI_PROTECTED_MODE.
+
+Because the www tools (all stuff named "t_*.php") use the "ewiki.php"
+script and the sample "config.php", you eventually need to configure
+these tools separately (they don't need any ewiki plugins, but the
+database ones, if necessary). So if there are problems (for example
+if your ewiki setup is configured with ewiki_auth, which then could
+overlap with the ".../auth.php" script), you may need to edit the www
+tools own "t_config.php" accordingly. (Note: This is not required for
+the default setup.)
+
+If you'd like to integrate the tools/ as virtual pages into ewiki, then
+the StaticPages plugin will help. You then needed to remove the line
+that tries to re-include() your config.php and ewiki.php from the tools/
+"t_config.php" script (else you'll break ewiki).
+To load your tools/ as static pages into the wiki, you then just needed
+a call to ewiki_init_spages() with the "./tools/" directory as parameter.
+
+
+
+ tools/t_flags
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯
+ WikiPages usually have the page flag TEXT assigned. Other possible
+ flags are DISABLED, SYSTEM, BINARY or HTML, READONLY, WRITEABLE.
+ Usually page flags are copied from one page version to the next.
+
+
+
+ tools/t_backup
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Use this to make backup files from the WikiPages. This www script
+ is a wrapper around the ewikictl commandline utility and library,
+ and therefore supports almost the same options.
+
+
+
+ tools/t_restore
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to reinsert the files generated with the backup utility into
+ the database. It is also a www wrapper around ewikictl and thus
+ also supports the "plain", "flat" and "fast" file formats.
+
+
+
+ tools/t_remove
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Use this to delete a page from the database (including all saved
+ versions).
+ You should always prefer to set a page DISABLED with the ewiki_flags
+ tool to hide unwanted content. -- make love() not unlink()
+
+
+
+ tools/t_holes
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯
+ If pages are edited often / regularly you will soon get hundreds of
+ saved page versions. As this slows down (particularly the
+ db_flat_file ones) and enlarges the database content size, you may
+ want to strip old versions.
+
+ This tool suggests you to remove a few page versions. You should
+ however NOT DELETE the page VERSION ONE and the very last (newest)
+ page version (of course).
+ The page version 1 often contains control data, not found in newer
+ versions, when db_flat_files or db_dba is used, so please keep
+ aware of this.
+
+ There were some changes necessary in db_flat_files to support
+ those "version holes", but it currently seems to work stable.
+
+
+ tools/t_textinsert
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Can insert plain text files into the database. This is much the
+ same, what usually happens to the files inside init-pages/
+
+
+
+ tools/t_transfer
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Allows to download all pages in one big "binary" file, and to
+ reinsert it on the same way. This allows for quick moving of
+ the whole database content.
+
+
+
+ tools/t_revert
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Can undo mass changes caused by a script attack (specifically
+ designed to spam or corrupt a Wiki) or someone who put enourmous
+ energy into garbaging multiple pages. The {auther} field always
+ contains at least an IP address to allow easy tracking of such
+ activity, and this plugin just enables you to remove page versions
+ whose {author} field matches a certain string (the attackers IP
+ address).
+
+
+
+ tools/ewikictl
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ ewikictl is a commandline based utility - as opposed to the
+ www/http based scripts mentioned above.
+ UNIX people will find it very useful and handy, while it is
+ believed to work on Win32 systems too.
+
+ It integrates a lot functionality of the web based tools/, some
+ of them less flexible and others more powerful than in the
+ other tools. It, for example, allows to generate database backups
+ automatically and is often easier to use. On the other hand it
+ will be of little use if you don't have a shell account on the
+ WebServer running your wiki (because most times one cannot make
+ remote mysql server connections).
+
+ The most important feature is to make backups using the
+ --backup switch:
+
+ All pages from the database will be saved into backup files
+ in the directory given by --dest (or if not given into
+ './backup-<currentdate>').
+
+ The --format of the backup files can be: plain, fast, flat
+ or xml, meta, xmlmeta, sql, mysql. But remember that only
+ the first three mentioned formats can be reinserted using the
+ ewikictl utility.
+
+ You really should give the --all parameter too, whenever you
+ make a backup, because else only the very last version of each
+ page will get saved (and think of a garbaged last version, this
+ would be a bad idea). So USE --all ALLWAYS!
+
+ Backups can be reread into the database using the
+ --insert switch:
+
+ The --dest or --source parameter says where to search for the
+ save page files, and the --format option again tells the
+ correct backup format (you will get a garbaged database if you
+ get it wrong).
+
+ The --all option is of course necessary again if you gave it
+ when doing the --backup, and ewikictl will complain if it
+ believes the --all option was required.
+
+ You can also use --insert to initially fill a database, or to
+ add just a few new pages, as pages inside the database will
+ never be overwritten by the ones added with --insert.
+
+ The --insert switch also allows to be used to load just one
+ file into the database. --insert <WikiPageFileName>
+
+ Another function is to speed up the database, by creating version
+ --holes:
+
+ If you utilize the db_flat_files and you have hundreds of
+ versions for one page, things may get slow at some point of
+ time, so you may wish to remove some of the unneeded versions.
+ That is what the --holes is for, it strips some of the page
+ versions from the database. Please keep in mind, that the
+ very first version of each page may contain special control
+ data, which is not available in the following ones (this is
+ especially true for db_flat_files).
+
+ Per default the 2nd version of a page until the 10th before
+ the last page version will be removed. You can however specify
+ this range yourself:
+ --holes 2..-10 (default)
+ --holes 5..-5 (5th until 5th before last version)
+
+ Please also keep some versions at the end, as the very last
+ one may contain mangled text (if someone backspaced around).
+
+ The --all option is implied for --holes, but you can and you
+ should combine --holes also with --backup. This special
+ feature will save a backup into the --dest directory ('./holes'
+ per default) before the page version is removed from the
+ database.
+
+ --format
+ The default backup/insert format is the 'plain' one - which
+ means just a pages content will be saved into the files.
+
+ It is however recommended to use the "--format flat" or
+ "--format fast" instead, as both can contain the complete meta
+ data of a page.
+
+ --ls
+ Will print a directory-listing like list of all pages from
+ the database.
+ You can add a pagename as parameter, so only that one will
+ get shown.
+
+ --reset <pagename>
+ --disable <pagename>
+ --enable <pagename>
+ --html <pagename>
+ --readonly <pagename>
+ --writeable <pagename>
+ Will set the according page flags for the given page. You can
+ give the page name also by using the --page or --file or --id
+ switch.
+
+ --chmod <flags>
+ Will set the page flags to the given decimal value. The
+ pagename must be given using --page, --file or --id. This
+ option of course requires knowledge of the flag/option values
+ and their numeric/decimal representations.
+
+ --unlink <filepattern>
+ Can be used to delete a page. You can use the asterisk to
+ remove more than one page, just an '*' would for example delete
+ all pages.
+
+
+ NOTE that you can also use this utility without a shell account on
+ your WebServer, if you create temporary .php wrapper scripts, that
+ contain nothing more than:
+ <pre><?php echo `./tools/ewikictl -ll`; ?></pre>
+
+ Please search google or freshmeat.net for one of those shell faking
+ CGI scripts, to ease this, so can get the most out of ewikictl.
+
+
+
+ tools/wiki2html
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Renders the WikiPages and saves the resulting <HTML> bodies into
+ files. It currently cannot deal with images and binary content
+ correctly.
+
+
+
+ tools/mkhuge
+ ¯¯¯¯¯¯¯¯¯¯¯¯
+ For lazy people - if for some reason your text editor does not
+ allow to enter the correct include() commands for the files from
+ the plugins/ directory you may find this shell script useful to
+ create a monster version of ewiki (plugins and core script merged
+ together into one file).
+ See the paragraph about "monsterwiki.php" for more detailed infos.
+
+
+
+ tools/mkpluginmap
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Is the companion tool for the new ewiki pluginloader extension. It
+ traverses the plugins/ directories and generates a list which
+ allows automatical loading of ["page"] and ["action"] plugins.
+
+ Use the output of this script to replace the list of available
+ plugins inside of the "pluginloader.php" script. But don't forget
+ to disable that extensions, that you wouldn't like to be available.
+
+
+
+ tools/mkpageplugin
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Can convert any StaticPage file (from the spages/ directory) into
+ a standard ewiki page plugin (to get included() like all the others
+ then). It detects automatically the type of the given StaticPage
+ input files - Wiki source (.txt), ready HTML content, or even PHP
+ code.
+ It's intended as help for the unexperienced PHP user, or if you
+ needed to mass convert StaticPage files into plugins. But please
+ note, that including() hundreds of page plugins slows down the PHP
+ interpreter and eats a large amount of memory (and this was the
+ reason for extracting some page plugins into StaticPages).
+
+
+
+examples/
+¯¯¯¯¯¯¯¯¯
+The file "examples-1.php" is the default layout, which you will see, when
+you first run ewiki. The examples/ subdirectories now holds further example
+'ewiki wrappers' or 'layout scripts' (commonly referred to as "yoursite.php"
+scripts in the README).
+
+There is not much further interesting stuff in here. If you can make a
+contribution, just do (however, in the ewiki core tarball, we don't want
+an image or graphics directory).
+
+
+
+ examples/homepage.php
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This is an example on how to use ewiki.php with an authentication
+ frontend. Note that this is not the recommended way to use a wiki
+ (adding authentication can be considered "crippling" a wiki).
+
+ "Authentication" means just a JavaScript based password query
+ dialogue (the password is however checked server-side inside the
+ homepage.src script).
+
+ You should install it preferably as index.php as described on top
+ of the file, the ewiki.php script must be there too. Edit the source
+ and colours to suit your needs. Guess, it needs some images as well.
+
+
+
+Nice things in fragments/
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+This directory holds some files to integrate ewiki.php within some
+other web projects (for example PhpNuke) or some helper and extension
+code, or just other example layouts.
+
+Please have a look at the fragments/README - and as usual into the
+files itself!!
+
+
+
+ strip_wonderful_slashes.php
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ If you have a PHP 4.1 or a provider using the annoying factory-default
+ settings of such a version, you may find this tiny script helpful.
+ It removes the just-for-security-reasons-added-backslashes from the
+ $_REQUEST variables. I wasn't very interested in adding hundreds of
+ stripslashes() calls inside ewiki.php, so this is the workaround for
+ __your__ providers broken php.ini
+
+
+
+ fragments/funcs/wiki_format.inc
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ This php include() file contains just the reduced wiki_format() function,
+ the code to generate internal WikiLinks and the binary data stuff has
+ been removed.
+ It is best suited to allow rendering of WikiSource with other php projects.
+
+ The script was contributed by Frank Luithle.
+
+
+
+ 404finder.php
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Simple example on how to use "ErrorDocumet 404" rediriction to
+ activate the ewiki page search function automatically, which is the
+ poor mans mod_rewrite.
+
+
+
+ htaccess
+ ¯¯¯¯¯¯¯¯
+ To make a Wiki installation look more profession you should try to
+ use your Webservers mod_rewrite module to get nicer looking URLs.
+ This file is an example to be installed as ".htaccess" (Web server
+ per-directory configuration file), which allows to call your ewiki
+ wrapper using URLs like:
+
+ http://www.example.de/wiki/SomePage
+ http://www.example.de/wiki/edit/OneOfThePages
+
+ (For this example, you needed to set EWIKI_SCRIPT to "/wiki/").
+ This example '.htaccess' script shows how to instruct mod_rewrite
+ to catch above URLs and to transform them into ".../index.php?id=Page"
+ again before calling the script.
+
+
+
+ binary.php
+ ¯¯¯¯¯¯¯¯¯¯
+ If your ewiki wrapper script is not binary safe (that is, eventually
+ printing some <html> or text output to stdout before you include()
+ the core ewiki script and called the ewiki_page() function) - then
+ you may need to place a secondary ewiki wrapper besides the one
+ dedicated to pages.
+ The "fragments/binary.php" gives an example and further instructions
+ on this issue.
+
+
+
+ fragments/funcs/auth.php
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Include this script wherever you need authentication. It uses the HTTP
+ Basic Authentication scheme, but the passwords are inside the script
+ in the $passwords array (so no need for .htpasswd setup).
+
+ Note that this script needs to be called before any body output is made
+ (else it would be too late for http header() output).
+
+
+
+ fragments/css/*
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Please understand the *.css as examples that illustrate which style classes
+ are defined inside ewiki.php and its companion plugins.
+
+ Remember, you could insert those files with PHPs` include(), too - if
+ desired (and if a <style> area is currently to be written to stdout).
+
+
+
+ fragments/blocks/*
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Contains small include() scripts to be loaded into "yoursite.php"
+ as "sidebars" and the like for beatification purposes.
+ Oftens these are reduced but useful ["page"] or ["action"] plugins,
+ performing common tasks, like printing the list of newest pages or
+ some sort of menu, or even random page links.
+
+
+
+Other patches/
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+In the patches/ directory some code tweaking tips are collected that are
+either not worth a new plugin or to uncommon and unsafe and unsupported to
+get into fragments/ or plugins/. Please see the README and the files therein
+for more informations.
+
+I often like to refer to that subdir as the "recoding FAQ".
+
+
+
+Updates + How to deal with tweaked code
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+If you ever happen to recode parts of a plugin, WHICH WE STRONGLY ENCOURAGE
+TO DO (to match it better to your needs) - then there is always the risk of
+losing your changes as soon as you upgrade and overwrite everything inside
+of plugins/
+Therefore it is recommended to create a subdirectory like "local/" where
+you copy changed plugins into, then include() them from there instead of
+the distributed default from plugins/. So you won't lose your changes and
+enhancements if you upgrade to a newer version. You of course should then
+check (after updates) if the newer version of a plugin contained
+enhancements you'd like to merge with your cutomized version of the earlier
+plugin incarnation.
+
+For the main "ewiki.php" script, things are of course more difficult, as
+you will probably always overwrite it when you update your installation.
+Best approach is to keep a NOTES file, where you store your patches for
+later reinclusion with newer releases, or even to keep always a second
+copy of your tweaked "ewiki.php". Much better was of course to send your
+changes to the ewiki -dev people so they could merge them into the CVS,
+so everybody could enjoy your ideas.
+
+
+
+
+
+
+ -------------------------------------------------------------------- 8 --
+
+
+
+
+
+
+Extension HowTo
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Best way to extend it is to read the man page on vi or emacs ;-> However
+the tool that made this all possible was joe.
+
+
+
+the PlugInterface
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+The $ewiki_plugins array holds an array of "task names" connected to
+function names (that of course should do something senseful). As an
+example:
+
+ $ewiki_plugins["image_resize"][0] = "ewiki_binary_image_resize_gd";
+
+connects the task name "image_resize" to function already inside ewiki.php,
+and the task "image_resize" will be called for every uploaded or to be
+cached image. The function name here does not say anything about the
+parameters the function will be called with later. You have to look up
+the original function implementation in ewiki.php to see which parameters
+will be passed; so you could write your own task plugin.
+
+The [0] in the example above shows that this is the very first registered
+function for the task "image_resize", there could be others as well. So
+if you write a plugin you should take care to add your function name using
+$ewiki_plugins["task"][] = "my_func" so you won't overwrite a previous
+function name ''registration''.
+There are of course tasks like ["database"] where only one of the plugin
+functions will be called, in this case you should of course overwrite [0].
+
+Two special case "tasks" are ["page"] and ["action"], because they aren't
+counted with numerical indices, but instead carry WikiPageNames or
+other idf strings as array/hash index.
+
+
+
+plugin tasks
+¯¯¯¯¯¯¯¯¯¯¯¯
+Here's a short summary of current PlugInterface "tasks" and (recommended)
+function interface definitions (the "= function (..." lines). A plugin hook
+with [] means there can be multiple, and each one would be tried.
+
+basic
+-----
+
+ ["page"][$PageName] - called for requests to page "$PageName"
+ (like "SearchPage", "NewestPages")
+ = function ( $id, $data, $action )
+
+ ["action"][$ACTION] - called for requests with url "?id=$ACTION/pagename"
+ (core actions are "edit", "links", "info", "view")
+ = function ( $id, &$data, $action )
+
+ ["handler"][] - called from ewiki_page() on start-up, if it returns
+ a string the page was handled and no further
+ processing takes place, the plugins output is used
+ = function ( $id, &$data, $action )
+
+rendering
+---------
+
+ ["render"][0] - alias for ewiki_format() - our "WikiKernel"
+
+ ["format_source"][] - called inside the format function for the wiki
+ source, implement this or the following ones to
+ use complex wiki markup
+ = function ( &$wiki_source )
+
+ ["format_line"][] - generic call from inside wiki format engine
+ for every line, you may need to use static
+ vars inside your plugin function
+ = function ( &$o, &$line, &$post )
+
+ ["format_tbl"][0] - called to handle "wiki|table|markup"
+ (the first and last | are already stripped)
+ = function ( &$o, &$line, &$post, $tbl_open=0 )
+
+ ["format_final"][] - call after wiki source was transformed into html
+ (WikiPageLinks were already interpolated too)
+ = function ( &$html )
+
+ ["format_block"][] - called, with the page fragment extracted using
+ the string patterns of the according
+ $ewiki_config["format_block"] entry
+ = function (&$currbuf, &$in, &$iii, &$s, $btype);
+
+ ["format_para"][] - called, if the $para (text enclosed in <p></p>)
+ is to be written into the output stream $ooo[$in][0]
+ = function (&$para, &$ooo, &$s);
+
+ ["link_url"][] - called to transform wiki source references
+ = function ( $href, $title )
+
+ ["link_final"][] - called from ewiki_link_regex_callback to transform
+ the final <a href>
+ = function ( &$str,, $type, $href, $title )
+
+special tasks
+-------------
+
+ ["database"][0] - only [0] will be called in favour of the ewiki.php
+ internal ewiki_database_mysql()
+ = function ( $action, $args=array() )
+
+ ["image_resize"][] - all [] registered functions will be invoked
+ = function ( &$content, &$mime, $return=0 )
+
+ ["mime_magic"][0] - hooks before save_binary/image to fetch the
+ correct mime type for non-image files; nowadays
+ just an always-available get_content_type()
+ = function ( &$content )
+
+ ["binary_get"][0] - the binary_repository handles large/binary content
+ (to separate it out of the standard sql-database),
+ usually just sending it to stdout
+ = function ( $id, $meta )
+
+page lists
+----------
+
+ ["list_pages"][0] - <li>st generating callback function
+ = function ( $lines )
+
+ ["list_dict"][0] - special variant of the above one (called just for /
+ from within PageIndex and WordIndex listings)
+ = ???
+
+ ["list_transform"][] - works on the given list of links (text transformations)
+ = function ( &$lines )
+
+ ["make_title"][0] - allows to chain a replacement function for
+ ewiki_make_title()
+ = function ($title, $class, $action, $go_action, $may_split)
+
+ ["title_transform"] - changing the currently linked title (called from
+ within _make_title)
+ = function ($id, &$title, &$go_action)
+
+page transform / additions
+--------------------------
+
+ ["view_append"][] - output will be printed below a rendered page
+ = function ( $id, $data, $action )
+
+ ["view_final"][] - can rework the full html of the rendered page
+ = function ( &$html, $id, $data, $action )
+
+ ["view_append"][] - add <html> code at the end of the currently
+ viewed page
+ = function ($id, $data, $action)
+
+ ["view_final"][] - filter hook for final processing of "view/"ed pages
+ = function ($o, $id, $data, $action)
+
+ ["page_final"][] - filter hook for final processing of any
+ shown page (any action: edit/, view/, info/, ...)
+ = function ($o, $id, $data, $action)
+
+edit/ hooks
+-----------
+
+ ["edit_preview"][] - called if edit pages [preview] button pressed
+ = function ( $data )
+
+ ["edit_form_final"][] - add <html>/<form>s to the edit/ page
+ = function (&$o, $id, &$data, $action)
+
+ ["edit_form_append"][] - insert other <input> fields between <textarea>
+ and <submit> button on the edit/ page
+ = function ($id, &$data, $action)
+
+ ["edit_hook"][] - chains into before the edit box is printed
+ (to allow security checks, pre-edit-tweaking, ...)
+ any output terminates the current edit/ attemp
+ = function (&$id, &$data, &$hidden_postdata)
+
+ ["edit_save"][] - immediately called before saving the currently
+ "edit/"ed page into the database, allows last
+ transformations or rejection (unsetting $data)
+ = function (&$data, &$old_data)
+
+ ["edit_patch"][0] - special hook for the patchsaving plugin
+ = function ($id, &$data)
+
+bloat extensions
+----------------
+
+ ["auth_*"][] - plugin tasks used with ewiki_auth()
+ = see the plugins/auth/README.auth
+
+ ["mpi"][...] - markup plugins, see next paragraph
+
+ ["init"][] - run once, when the main script is included()
+
+ ["page_init"][...] - init functions, called when ewiki_page()
+ is called the very first time
+
+aliases and variants
+--------------------
+
+ ["action_always"][$ACTION] - are called with precedence over ["page"]
+ plugins (for example "links" which also
+ works for registered page plugins)
+
+ ["action_binary"][$ACTION] - action/admin plugins which do not care, if
+ the current page actually is binary data
+
+
+Some other entries have been re-extracted into $ewiki_config, because they
+were falsely in $ewiki_plugins. See the paragraph at the start of the README
+on the $ewiki_config array.
+
+This list will probably not stay up-to-date, so please grep the ewiki.php
+script for all occurrences of 'ewiki_plugins["', and you can of course
+invent some new and tell the author how it helped you to implement something
+very different.
+
+
+
+ mpi plugins
+ ¯¯¯¯¯¯¯¯¯¯¯
+ Plugins of the class "mpi" extend the wiki markup with html like
+ calls to dynamic content generating functions. They were taken from
+ the ewiki adaption of Hans B Pufal and are very similar to the
+ plugins found in PhpWiki.
+
+ In order to use them you must first load their generic PlugInterface
+ file using include("plugins/mpi.php");
+
+ Afterwards you could include all the wanted mpi extension modules,
+ using include() again:
+ include("plugins/mpi_calendar.php")
+
+ You can then call those plugins from the wiki markup like:
+ <plugin: calendar>
+ <ewiki: calendar>
+ <mpi: calendar>
+ <?plugin calendar?>
+
+ There are many different plugins available (not all included with
+ this ewiki distribution), and the allowed arguments differ widely
+ (must all be noted inside the < > and are written in arg=value style
+ separated by semicolon):
+
+ <plugin: plugins>
+
+ <plugin: calendar year=2005; month=7;>
+ month_offset=0; start_wday=0;
+ wday_color=#999999; today_color=#ffcccc;
+ wend_color=#bbbbbb;
+
+ <plugin: environment>
+ info=45
+
+ <plugin: insert !WikiPageName>
+ # this includes the referenced WikiPage in a box
+ # into the current one, Note the ! to prevent that
+ # WikiWord from getting rendered (before mpi sees
+ # it)
+
+ <plugin: page_flags>
+ # I strongly discourage this mpi plugin to be
+ # loaded as it allows such easily to spy page
+ # security settings
+
+
+
+
+
+
+ authentication/permission plugins
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The paragraph and descriptions about the _auth interfaces have gone
+ into plugins/auth/README.auth
+
+
+
+writing your own plugin
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Using the list of current plugin tasks, you could (hopefully) write your own
+extension with ease. It is probably most simple to write a dynamic ["page"]
+plugin, so we start with this as example. All you need is a function
+definition like:
+
+ function my_page_plugin($id, $data, $action) {
+ return("This is the returned page <b>content</b>.");
+ }
+
+And then just register it as ["page"] plugin, using your defined function
+name (yes, this does NOT need to start with the usual "ewiki_" prefix!). You
+also need to tell ewiki about the WikiPageName under which your plugin
+should be made available:
+
+ $ewiki_plugins["page"]["MyPagePlugin"] = "my_page_plugin";
+
+That's it. But of course your function should do something more useful, than
+just returning a hardcoded html string - even if this all, what's necessary
+here. The parameters to your ["page"] plugin function you'll often just want
+to ignore, and implement your plugin functionality (hard disk formation e.g.)
+independently from such things.
+
+It is likewise easy to write an ["action"] plugin; but this type of plugin
+should then process some parts of the $data entry and work for nearly any
+page (extracting contents or presenting the current page differently). So
+this kind of plugin could be used to initialize a download for the current
+page or to allow to email it to someone else (beware of the spammers!).
+
+
+
+format_* / rendering plugins
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+It is rather simple to add WikiMarkup using the $ewiki_config["wm_..."]
+settings, but for some tasks you need stronger weapons like rendering
+and markup plugins.
+
+The ewiki_format() function (often blatantly referred to as "rendering
+kernel") recently got rather complicated to add support for the 'block'
+plugins. Therefore we'll first need to discuss the variables structures
+and names used inside of it:
+
+
+
+ ewiki_format() internals
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ When the function receives the input string (WikiSource), it first
+ escapes all html tags using & < > to replace the & < >
+ chars (because HTML is not allowed within Wiki, initially).
+
+ Then it runs optional ["format_source"] plugins on the whole wiki
+ page (still one source string).
+ Afterwards ewiki_format() starts to split that wikisource into
+ fragments meant to get handled by ["format_block"] plugins AND/OR
+ the Wiki -> HTML transformation code inside of it. It creates an
+ array called $iii[] from it - each fragment being an array on its
+ own:
+ $iii[0] = array(
+ 0 => "WikiSource ...",
+ 1 => 0x0FFF,
+ 2 => "core",
+ );
+ Initially we here just have one fragment [0] - and often this
+ remains the only one (if no block plugin activates for the current
+ WikiPage). The 0=> entry contains the body (wiki source) of a
+ fragment, while at the 1=> index you'll find the block flags and 2=>
+ is just the name of the block plugin to handle that fragment.
+
+ If there is some block code, like <htm>...</htm> or <pre>...</pre>
+ in the WikiPage, you'll end up with a larger $iii[] input array:
+ $iii[0] = array("WikiSource...",0xFFFF,"core"),
+ $iii[1] = array("<b>....",0x0002,"html"),
+ $iii[2] = array("text",0x0FFF,""),
+
+ Besides the $iii[] input array, we'll also have an array containing
+ rendering status variables called $s[]. The most important entry
+ there is $s["in"], which is the index into the currently accessed
+ $iii[] wiki page source or block fragment.
+ And ewiki_format() then uses various alias variable names for
+ entries of the status var $s[] array - for example $in and $s["in"]
+ are the same index number.
+
+ After ewiki_format() separated the input source into the block
+ fragments of $iii[], it will then run the actual ["fragment_block"]
+ plugins on it. These can then apply regexs on them, or strip the
+ fragments completely out of $iii[] or transform then into regular
+ wiki source.
+
+ Then the large wiki transform loop comes into action, but only
+ for $iii[] fragments, whose flags (in the $iii[...][1] number)
+ have the bit 0x0001 set. Other blocks/fragments of $iii[] remain
+ untouched.
+ While transforming the $iii[] arrays WikiSource a new fragments
+ array will be created, called $ooo[] - the output array, which has
+ exactly the same layout. And every $iii[$in] directly maps to the
+ $ooo[$in] - same index number! But the later then already contains
+ <html> instead of wiki source.
+
+ Inside of the transformation loop, two other plugin types are
+ activated (besides applying the $ewiki_config["wm_..."] ruleset):
+ the ["format_line"] and ["format_para"] plugin groups.
+
+ After all $iii[] blocks have been transformed into $ooo[], a second
+ loop will check the flags (this time $ooo[...][1]) for the bit 0x0002
+ which tells, if WikiWords should be transformed into html <a href=>
+ links.
+
+ After link conversion (on the selected fragments), all blocks (the
+ content entries $ooo[...][0] of course) of $ooo[] are merged together
+ into one <html> string. After the ["format_final"] plugins run over
+ this, ewiki_format() returns the resulting <html> page.
+
+
+
+ the format_ plugin hooks
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ As denoted above, the ["format_source"] and ["format_final"] plugin
+ hooks are the simplest to work with, as both only get one parameter
+ (passed by reference) containing either the full WikiPage source
+ text or the already fully rendered <html> output.
+
+ The ["format_line"] and ["format_tbl"] hooks are also rather simple,
+ lookup their interface to know which variables you could modify.
+
+ The ["format_para"] and ["format_block"] plugins both recieve
+ either the $iii[] or $ooo[] and status $s[] array variables (plus
+ a few aliases and shortcomings). This makes these hooks look a
+ bit more complicated, but allows great flexibility - a "_block"
+ plugin could for example merge its $iii[] fragment with another
+ one, or replace itself with nothing.
+
+ To write a markup plugin, you should lookup the actual interface in
+ the 'ewiki.php' script or in this README. And don't forget that most
+ parameters are meant to be passed by reference to be useful!
+
+
+
+ $iii[] and $ooo[] block flags
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ The $iii[...][1] and $ooo[...][1] hold the flags (as defined by
+ $ewiki_config["format_block"][...][2]) for each fragment of the
+ WikiPage. The "core" blocks (plain WikiSource) always have the
+ default 0x0FFF assigned.
+
+ Currently used bit values are:
+ 0x0001 - render WikiMarkup
+ 0x0002 - render WikiLinks
+ 0x0004 - international character &#htmlentities; allowed
+ 0x0100 - fragment further (other block plugins can split it)
+
+ pseudo-values (OR checks):
+ 0x0011 - consider to be inline block between WikiSourceBlocks
+ (prevents paragraph breaks between plugin and wiki block)
+ 0x0022 - scan for WikiWords in this paragraph
+
+
--- /dev/null
+
+README.de
+¯¯¯¯¯¯¯¯¯
+Dies ist eine teilweise Übersetzung der README Datei, die weiterhin als
+Referenz verwendet sollte, da hier nur ein paar allgemeine und Setup-
+Informationen enthalten sind.
+
+ 1 Was ist das?
+ 1.1 Warum "ErfurtWiki"?
+ 1.2 WikiAlternativen
+ 1.3 Autor
+ 1.4 ProjektSeiten
+ 1.5 Support bekommen
+ 1.6 Lizens
+
+ 2 Wie jetzt?
+ 2.1 In yoursite.php integrieren
+ 2.2 Den WikiSeitenNamen bestimmen
+ 2.9.1 WikiSprache einstellen (deutsch)
+
+ 3 Im Detail
+ 3.1 die ewiki_ Funktionen
+ 3.2 $GLOBALS Verschmutzung
+ 3.3 die EWIKI_ Konstanten
+ 3.4 $ewiki_config[] array
+
+ 4.1 Nur die WikiQuelltextTransformation einsetzen
+
+ 6.1.2 Ohne MySQL DB verwenden (WICHTIG)
+ 6.1.3 db_fast_files
+ 7.3.3 BöseBäckSläshes \\\\" (WICHTIG)
+
+ 9.5.5 Paßwörter und tools/
+
+
+
+ -------------------------------------------------------------------------
+
+
+
+Was ist das?
+¯¯¯¯¯¯¯¯¯¯¯¯
+Dies ist eine "WikiWikiWeb" Bibliothek, die in der PHP Webskriptsprache
+implementiert ist. Ein WikiWiki ist eine Webseite, die von wirklich jedem
+verändert/ergänzt werden kann, der dort vorbeischaut (ohne vorhergehenden
+Registrierungskram).
+
+Es sollte relativ einfach in bestehende Websites integrierbar sein,
+weil es eben kein komplettes Script sondern vielmehr eine Bibliothek
+ist, die kein fertiges Seitenlayout erzwingt. Stattdessen können die
+erzeugten WikiSeiten als Inhalt in das Layout einer bestehenden Seite
+eingebunden werden.
+
+
+
+Warum "ErfurtWiki"?
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Meine Heimatstadt (Erfurt liegt nahe bei Weimar.de) - und das ist wirklich
+nix weiter als ein Name! Der interne Projektname ist übrigens "ewiki".
+
+
+Warum sollte man ausgerechnet dieses Wiki verwenden wollen?
+
+ - es ist wirklich alles notwendige in einer einzigen Skriptdatei, so
+ daß keine 20 anderen Dateien mit herumliegen müssen, wenn man es
+ in die eigene Site einbindet
+
+ - vordefinierte Layouts werden nicht aufgezwungen, es gibt Beispielseiten
+ aber keine Skins oder Themes aus denen man wählen müßte; das Wiki paßt
+ sich wirklich in eine existierende Seite ein
+
+ - es ist vergleichsweise schnell, reguläre Ausdrücke werden zwar auch hier
+ verwendet, aber nicht so exzessiv wie in anderen Wikis
+ (hauptsächlich einfache und flinke String-Funktionen)
+
+ - der Funktionsumfang ist inzwischen beachtlich :)
+
+
+
+WikiAlternativen
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Es gibt auch noch andere hübsche WikiWare, falls jemand hiermit nicht
+glücklich werden tut:
+
+* PhpWiki ist deutlich vollständiger,
+ siehe http://freshmeat.net/projects/phpwiki,
+ unterstützt versch. Datenbanktypen, Lokalisierung, integrierter
+ Administrationsbereich
+
+* Miki ist eine kleine WikiImplementierung in PHP von Jukka
+ Zitting. http://miki.sourceforge.net/
+
+* http://coWiki.org/ ist tatsächlich mehr ein CMS denn ein Wiki
+
+* Und schließlich: sfWiki - das sourceforge Wiki (daher auch zu finden
+ bei http://sfwiki.sourceforge.net/). Teile der WikiSyntax sieht ein
+ wenig merkwürdig aus, ein paar andere Sachen sind ganz nett; und es
+ unterstützt Benutzerauthentifizierung
+
+* für andere Wikis in anderen Programmiersprachen einfach mal die
+ Suchmaschienen nerven:
+ http://www.freshmeat.net/search/?q=wiki§ion=projects
+ http://www.google.com/search?q=wiki
+
+
+
+Autor
+¯¯¯¯¯
+Mario Salzer <milky*erphesfurt·de>
+ICQ95596825 und Yahoo: icq95596825
+
+Und alle anderen wurden in die Datei CREDITS verbannt ;->
+
+Dies ist ein relativ neues Projekt. Um es zu verbessern, bin ich sehr
+auf Rückmeldungen angewiesen. Jede Mail ist ein wertvoller Beitrag!
+
+
+
+ProjektSeiten
+¯¯¯¯¯¯¯¯¯¯¯¯¯
+freshmeat
+- http://freshmeat.net/ewiki
+
+demo:
+- http://erfurtwiki.sourceforge.net/
+
+neueste Versionen (instabile EnwicklerVersionen):
+- http://erfurtwiki.sourceforge.net/downloads/
+
+
+
+Support bekommen
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Hilfe bei der Installation gibt's natürlich, und selbstverständlich sind
+wir auch dankbar für jeden Hinweis über bestehende Probleme und Fehler
+(bekanntermaßen ist die REAMDE noch nicht ausführlich genug und stellenweise
+überhaupt keine Hilfe).
+Bevor du aber einen BugReport versendest, lies dir bitte folgende Anleitung
+durch (absolut notwendig um KOSTENLOSEN support zu bekommen):
+
+http://www.lugbz.org/documents/smart-questions_de.html
+
+Danach bitte nicht zögern, einen der Autoren zu kontakten oder einfach eine
+Nachricht in BugReports oder UserSuggestion auf unserer ProjektSeite zu
+hinterlassen.
+Wenn du dich auf unserer http://erfurtwiki.sourceforge.net/?MailingList
+anmeldest, hast du die Möglichkeit Hilfe für dein Problem von einer größeren
+Gruppe von Leuten zu bekommen (an- und wieder abmelden geht schnell).
+
+
+
+Lizens
+¯¯¯¯¯¯
+Dieses "Programm" wird als "Public Domain" vertrieben. Public Domain
+ist wie "FreeWare", nur ein bischen mehr frei ;-> Man kann sich das
+vorstellen, wie die GPL ohne an die GPL gebunden zu sein. (Tatsächlich
+wollte ich einfach keine LICENSE Datei mitreinpacken, die größer ist als
+das eigentliche Programm.)
+
+Da dies ein freies (Bier) Stück Software ist, kann mich natürlich
+niemand für irgendwelche Fehler oder all die WIRKLICH SCHLIMMEN
+FESTPLATTEN-SCHÄDEN verantwortlich machen, die bei der Verwendung
+entstehen könnten ;>
+
+
+
+
+ -------------------------------------------------------------------------
+
+
+
+
+Wie jetzt?
+¯¯¯¯¯¯¯¯¯¯
+ewiki benötigt:
+
+- Webserver (Apache, Nanoweb, ...)
+- PHP 4.1 oder neuer
+- nach Mglk. eine MySQL Datenbank (läuft aber auch ohne)
+- deine bereits exitierenden Webseite
+- die wundervollen "magic slashes" in antiken PHP version sollten wirklich
+ abgeschalten sein
+
+Wenn du keine MySQL-Datenbank hast, dann verwende die Erweiterung für
+die Datei-Datenbank.
+
+
+
+In yoursite.php integrieren
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+In den nächsten Abschitten, soll mit dem Begriff "yoursite.php" der
+Teil deiner bestehenden Seite verstanden werden, der das Seitenlayout
+erzeugt (der also zumindest die <html><body> Tags um die Ausgaben von
+ewiki.php bastelt).
+Die schlichteste Lösung findet sich auch noch mal in example-2.php:
+
+ <HTML>
+ <BODY>
+ <?php
+
+ mysql_connect("localhost", "DB-USER-NAME", "PASSWORD");
+ mysql_query("use DATABASE-NAME-HERE");
+
+ define("EWIKI_SCRIPT", "yoursite.php?page=);
+ error_reporting(0);
+
+ include("ewiki.php");
+
+ echo ewiki_page();
+
+ ?>
+ </BODY>
+ </HTML>
+
+Die ersten beiden Befehle öffnen eine Verbindung zur MySQL-Datenbank,
+normalerweise würde man das Ergebnis von mysql_conect() in einer Variable
+wie "$db" ablegen, aber da PHP ohnehin nicht auf deren Verwendung besteht,
+wenn es nur eine DB-Verbindung gibt, wird eine solche Variable in
+"ewiki.php" auch gar nicht verwendet (und der Name dieser Variable wäre
+damit hier egal).
+
+Der Wert in der define() Zeile sagt ewiki wie die Hyperlinks zu den
+referenzierten WikiSeiten lauten müssen, damit ewiki.php auch für die
+nächste angeklickte WikiSeite aufgerufen wird.
+Wenn du nur ein einziges "yoursite.php" Skript hast, wirst du den Wert
+direkt in "ewiki.php" verändern wollen.
+
+Das error_reporting(0) wird sehr empfohlen.
+
+Das include("ewiki.php") lädt endlich die ewiki "Bibliothek" und setzt
+alle bis hierher noch nicht definierten EWIKI_ Konstanten.
+
+Der Aufruf der ewiki_page() Funktion gibt diejenige WikiSeite zurück, die
+vom Browser angefragt wurde. Du mußt hier "echo" davorsetzen, denn sonst
+wird der Text nicht ausgegeben (verpufft im PHP-Nirvana) - ewiki gibt die
+erzeugte Seite nicht selber aus.
+
+
+
+Den WikiSeitenNamen bestimmen
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Wenn du ewiki_page() einfach so aufrufst wie im oberen Beispiel angegeben
+(empfohlen), dann wird es versuchen, den Namen der angefragten Seite selber
+zu ermmitteln ($_SERVER["PATH_INFO"] oder GET-Variablen '?id=' oder '?name='
+oder '?page=' oder '?file=' in $_REQUEST["name"]).
+
+Wenn yoursite.php aber einen anderen Weg benutzt (andere Parameternamen),
+um den WikiSeitenNamen zu übergeben, dann kann man ihn schlicht als ersten
+Parameter angeben:
+
+ ewiki_page( $id = "WikiSeitenNanem" );
+
+
+Example-4.php zeigt das beispielsweise, um die Liste der aktualisierten
+Seiten einzubinden.
+
+
+
+
+
+WikiSprache einstellen (deutsch)
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Ich hab es jetzt schon einige Leute behaupten hören, aber auch beim
+IntranetExplodierer kann man die "bevorzugten Sprachen" irgendwo einstellen.
+Wers nicht findet, kann ja auch gleichmal auf einen aktuellen Browser
+wechseln - das lohnt sich nicht nur wegen der vielen Seiten, die es dann
+plötzlich doch auf Deutsch gibt!
+
+Wer es partou nicht hinbekommt, kann natürlich die deutsche Sprache für
+ewiki erzwingen; hilfreich hierfür ist z.B. die include()-Datei
+"fragments/force_lang_de.php".
+
+Es funktioniert aber auch mit diesem Befehl, der irgendwo in ewiki.php,
+config.php oder yoursite.php eingefügt werden kann (nicht empfohlen):
+
+$_SERVER["HTTP_ACCEPT_LANGUAGE"] = "de; q=1.0, en; q=0.2, eo, nl";
+
+
+
+
+ -------------------------------------------------------------------------
+
+
+
+
+Im Detail
+¯¯¯¯¯¯¯¯¯
+Die MySQL DB Tabellenstruktur ist zu einem gewissen Grad kompatibel mit der
+des allseits bekannten »PHPWiki« (normalerweise reicht es EWIKI_DB_TABLE_NAME
+auf "wiki" zu ändern, um PhpWikis DB weiterzuverwenden).
+Dies ist der MySQL Befehl, der die DB-Tabelle erstellt (beim ersten Start,
+automatisch):
+
+ CREATE TABLE ewiki (
+ pagename VARCHAR(160) NOT NULL,
+ version INTEGER UNSIGNED NOT NULL DEFAULT 0,
+ flags INTEGER UNSIGNED DEFAULT 0,
+ content MEDIUMTEXT,
+ author VARCHAR(100) DEFAULT 'ewiki',
+ created INTEGER UNSIGNED DEFAULT 0,
+ lastmodified INTEGER UNSIGNED DEFAULT 0,
+ refs TEXT,
+ meta TEXT,
+ hits INTEGER UNSIGNED DEFAULT 0,
+ PRIMARY KEY id (pagename, version)
+ )
+
+Den Spaltennamen {pagename} mochte ich eigentlich nicht, aber weil das der
+offensichtlich einzige Unterschied zur PhpWiki-Tabelle war, kam mir die Idee
+mit der Kombatibilität un so hab ich das adaptiert.
+Dummerweise muß nun die ewiki_database() Funktion "pagename" ständig von
+und nach "id" übersetzen.
+
+Die Spalte {version} wird zur Speicherung der verschiedenen abgelegten
+Seitenänderungen verwendet. In anderen Wikis gibt es zu diesem Zweck eine
+Bonus-tabelle wie "backup" oder "history", aber ich hab den Sinn von sowas
+bisher nicht verstanden; und daher gibt es in ewiki nur diese eine Tabelle
+(und das scheint absolut zu reichen)!
+Die erste {version} einer Seite erhält die Nummer 1. Eine bestehende
+Seiten {version} wird niemals überschrieben werden => sehr sicherer MySQL-
+Einsatz.
+
+Mehr über die {flags} in dem entsprechenden Abschnitt in der README. Das
+Feld {content} enthält natürlich den WikiSeitenQuelltext. {created} und
+{lastmodified} enthalten die entsprechenden Zeitangaben im UNIX format.
+
+{refs} enthälte eine "\n" - getrennte Liste von referenzierten WikiSeiten.
+Der Code um diese List zu erzeugen ist etwas unsauber, so daß oftmals
+GeisterSeiten aufgeführt sind. Wieauchimmer, daß beeinträchtigt ewiki
+nicht wirklich, und eine Korrektur wäre Zeit- und Geschwindigkeits-
+verschwendung.
+
+{meta} kann Bonusinfos enth, so daß die Tabellenstruktur nicht bei jeder
+Erweiterung geändert werden muß. Aktuell nur für Binärdaten (Bilder)
+verwendet.
+
+{hits} zählt die Seitenaufrufe, und ist nicht in {meta} integriert, weil
+separat schneller und einfacher zu verwenden.
+
+Die ewiki DB Tabelle kann nicht nur Texteseiten enthalten, sondern auch
+binären Inhalt (vornehmlich Bilder), siehe {flags}.
+
+Das Ein-Tabellen-Konzept hat es übrigens auch recht einfach gemacht, das
+Datei-basierte DB-Backend zu entwickeln. Eine Beispieldatei:
+
+ id: WikiPageName\r
+ version: 1\r
+ flags: 1\r
+ author: 127.0.0.1:3054\r
+ created: 1046532697\r
+ lastmodified: 1046532697\r
+ refs: \nErfurtWiki\nNewestPages\n\r
+ \r
+ !! WikiSourceContent
+ <more-text>...
+
+
+
+
+ewiki_ Funktionen
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Einige der Basis-Funktionen aus ewiki.php können getrennt von den anderen
+verwendet werden, andere sind ausgelegt um durch bessere Implementierungen
+ersetzt zu werden.
+
+
+ ewiki_page($id)
+ ---------------
+ Hauptfunktion, die die angefragte WikiSeite (oder die mit $id
+ angegebene) aus der DB holt, und mit ewiki_format() die fertige
+ HTML-Seite erzeugt.
+ Wenn die angefragte Seite nicht existert, wird eine edit-Box
+ zurückgegeben.
+
+
+ ewiki_page_...()
+ ----------------
+ Die meisten Fkt. mit diesem Prefix wurden aus der Hauptfkt.
+ herausgetrennt, um ewiki übersichtlicher und leichter erweiterbar
+ zu machen.
+ Die meisten enthalten Code um spezielle/interne Seiten zu erzeugen
+ (Suche, Neuest, Info, und das Edit <FORMular>, ...)
+
+
+ ewiki_script()
+ --------------
+ Erzeugt URL aus angegebener Seiten $id und $action, verwendet dazu
+ die EWIKI_SCRIPT-Konstante. Dieser wrapper ermöglicht es auch die
+ eigentlich reservierten Schrägstriche in Seitennamen zu verwenden.
+
+
+ ewiki_control_links($id, $data)
+ -------------------------------
+ Gibt die Zeile mit "DieseSeiteÄndern, SeitenInfo, ... links" aus.
+
+
+ ewiki_format($wiki_source, $scan_links=1, $html_allowed=0)
+ ----------------------------------------------------------
+ Erzeugt die formatierten (HTML) Ausgabe für den übergebenen
+ WikiQuelltext.
+
+ Der zweite Parameter gibt an, ob nach denen im Quelltext referenzierten
+ WikiLinks in der DB nachgesehen werden soll. Wenn dieser Parameter 0
+ ist, dann wird eine bereits vorh. $ewiki_links Array stattdessen
+ verwendet, um zu prüfen ob eine Seite in der DB vorh. ist.
+
+
+ ewiki_link_regex_callback()
+ ---------------------------
+ Aufgerufen aus ewiki_format(). Um ewiki_format() {die eigentliche
+ WikiEngine} weiter von der Datenbank zu trennen, verwendet diese
+ Fkt. das globale array in $ewiki_links, in dem normalerweise vorher
+ schon gefundene WikiSeiten eingetragen wurden (siehe zweiter Param.
+ von ewiki_format) um entweder einen normalen Verweis oder einen
+ Fragezeichen-Link auszugeben (wenn die angegebene Seite noch nicht
+ exisitiert).
+
+
+ ewiki_binary()
+ --------------
+ Wird automatisch aufgerufen, wenn das Skript mit dem ?binary= Anhang
+ aufgerufen wird, um referenzierte / hochgeladene Bilder auszugeben.
+
+
+ ewiki_author()
+ --------------
+ erzeugt einen String, der mit REMOTE_ADDR und $ewiki_author
+ angereichert wurde.
+
+
+ ewiki_database($FUNCTION, $args=array() )
+ ------------------------------------------
+ Diese Funktion ist die "Datenbankabstraktion" in ewiki. Sie enthält
+ ''only'' sechs SQL Kommandos, die ersetzt werden müßtem, wenn du eine
+ andere DB verwenden mußt.
+ Die einzelnen "atomaren" Funktionen sind beschrieben in der
+ orignialen README-Datei.
+
+
+
+
+
+$GLOBALS Verschmutzung
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Zumindest die ewiki_page() Funktion erzeugt einige Variablen im globalen
+Namensraum. Natürlich haben auch diese Namen, die sich mit irgendetwas
+aus yoursite.php überschneiden sollten:
+
+ $ewiki_id - Enthält die DB-$id der aktuellen Seite, ist nicht
+ immer identisch mit $ewiki_title.
+
+ $ewiki_action - Der $action-Parameter, mit dem die Seite angefordert
+ wurde.
+
+ $ewiki_title - Wird nach dem ersten Aufruf von ewiki_page() gestzt,
+ am nützlichsten um in dem <TITLE> Tag ausgegeben
+ zu werden - dafür muß aber ewiki_page() schon im
+ Kopfbereich aufgerufen werden, die Ausgabe gepuffert,
+ damit der Seitentitel noch innerhalb von <HEAD>
+ ausgegeben werden kann.
+
+ $ewiki_script - Eine Kopie von EWIKI_SCRIPT.
+
+ $ewiki_links - Ist ein Arraym daß in ewiki_format() prodiziert wird, und
+ alle gesuchten WikiSeitenNamen mit einem Wert von 0 oder 1
+ assoziiert, je nach dem, ob die Seite existiert oder nicht.
+ Wird diese variable jedoch auf ==true gesetzt (also kein
+ Array), wird angenommen, daß alle WikiSeiten existieren.
+
+ $ewiki_author - Der Inhalt dieser Variable wird in der {author}-Spalte
+ von gespeicherten WikiSeiten abgelegt (zusammen mit
+ IP:PORT).
+ Wenn yoursite.php Benutzer kennt und authentifizieren
+ kann, sollte der Nutzername hier abgelegt werden.
+ Diese Feld sollte aber NICHT ZUGEMÜLLT werden mit
+ irgendwelchen Bonusinfos.
+
+ $ewiki_auth_user - Enthält Namen eines wirklich authentifizierten
+ Benutzers im _PROTECTED_MODE. Nicht notwendig, wird aber
+ u.a. gerne von ewiki_auth() und ewiki_auth_user() zur
+ Vereinfachung verwendet.
+
+ $ewiki_ring - Berechtigungslevel im _PROTECTED_MODE
+ 3 = nur lesen
+ 2 = normaler Benutzer (lesen, editieren, ...)
+ 1 = Moderator (auch Seiten löschen?)
+ 0 = Administrator (darf alles)
+
+ $ewiki_plugins - Dieses array verbindet Aufgabengruppen (z.B. "database"
+ oder "image_resize") mit Funktionsnamen.
+ Dies stellt einen wirklich einfachen und dennoch mächtigen
+ Weg dar, um ewiki zu erweitern.
+ Es gibt ein eigenes Kapitel darüber in der orig. README.
+
+ $ewiki_config - Ersetzt teilweise die EWIKI_ Konstanten.
+
+Folgende gibt's nich mehr (teilweise in $ewiki_config):
+
+ $ewiki_data, $ewiki_interwiki, $ewiki_internal_pages,
+
+
+
+
+
+EWIKI_ Konstanten
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+- - WARNUNG - WARNUNG - WARNUNG - WARNUNG - WARNUNG - WARNUNG - WARNUNG - -
+WARNUNG: Dieser Abschnitt ist grundsätzlich besonders inaktuell! Von daher
+sollte ein Studium des gleichnamigen Abschnitts in der orig. README-Datei
+wirklich vorgezogen werden!! Viele der neu hinzugekommenen Konstanten werden
+hier schlichtweg nicht erwähnt, oder inzwischen sogar __falsch__ beschrieben.
+- - WARNUNG - WARNUNG - WARNUNG - WARNUNG - WARNUNG - WARNUNG - WARNUNG - -
+
+Dieser Abschnitt erklärt einige der Konstanten und wie man sie verwenden
+kann, um ewiki nach der eigenen Pfeife tanzen zu lassen.
+
+Normalerweise solltest diese innherhalb von "ewiki.php" angepaßt werden, einige
+sind jedoch mehr wie Statusvariablen ausgelegt und sollten von "yoursite.php"
+in Abhängigkeit von dort vorhanden Infos gesetzt werden (wenn dort Benutzer
+eingeloggt sind z.B.).
+Dann ist es gut einige der Konstanten vorzudefinieren (einmal def. Konst.
+können nicht wieder geändert werden).
+
+
+ EWIKI_SCRIPT
+ Wichtigste Einstellung. Wird von ewiki.php verwendet, um Links zu
+ anderen WikiSeiten zu erzeugen.
+
+ Es benötigt den Namen von yourscript.php, daß selbst wiederrum
+ ewiki.php geeignet einbindet.
+ Der Name der angefragten WikiSeite wird immer schlicht an den hier
+ definierten TextString angehängt, daher sollter dieser immer in
+ "/" oder "?" oder "?id=" oder "?name=" oder "?page=" enden, damit
+ eine gültige URL dabei herauskommt und der SeitenName von ewiki_page()
+ gefunden wird.
+
+ Wenn auf deinem Server mod_rewrite vorhanden ist und funktioniert,
+ könntest du diese Konst. auch leer lassen, so alle Anfragen zu
+ http://wiki.example.com/ an das richtige Skript übergeben werden.
+ Ansonsten ist es gut, wenn eine URL absolut zum Server-Hauptpfad
+ angegeben ist, also z.B. "/~user/wiki/index.php/", damit Browser
+ keine ungültigen URLs erzeugen, sobald eine $action vor den
+ Seitennamen gesetzt wird (z.B. "edit/DieseSeite").
+
+ Die Konstante wird von ewiki_script() eingesetzt um URLs zu den
+ angegebenen Seiten zu erstellen (wobei einige Fehler abgefangen
+ werden).
+
+ EWIKI_SCRIPT_URL
+ Sollte eine absolute URL enthalten, die ebenfalls zum ewiki-wrapper
+ zeigt, z.B. "http://www.example.com/wiki/?id="
+
+
+ EWIKI_DB_TABLE_NAME
+ Setzt den Namen der MySQL DB Tabelle fest, die erzeugt und verwendet
+ werden soll, um alle WikiSeiten abzulegen.
+
+
+ EWIKI_PAGE_INDEX
+ Definiert den Namen der WikiSeite, die als Startseite angezeigt werden
+ soll.
+ EWIKI_PAGE_NEWEST
+ Name (intern erzeugt) der Seite, die List der zuletzt hinzugefügten
+ Seiten enthält.
+ EWIKI_PAGE_SEARCH
+ Enthält den WikiSeitenNamen für dei SuchFunktion.
+
+
+ EWIKI_CONTROL_LINE
+ Wenn auf 0 gestzt, wird die Zeile unter einer WikiSeite mit
+ "DieseSeiteÄndern, SeitenInfo, ..." nicht angezeigt.
+ In diesem Fall sollte der Edit-Link in yoursite.php erzeugt werden.
+ Besser ist es normalerweise das Aussehen der Ausgabe in
+ ewiki_control_links() selbst zu ändern.
+
+ EWIKI_AUTO_EDIT
+ Bei 1 (voreinstellung) wird automatisch eine Edit-Box für
+ nicht-exisiterende Seiten angezeigt, ansonsten wird eine ZwischenSeite
+ ("Bitte ändere mich!") angezeigt (wie in PhpWiki).
+
+ EWIKI_LIST_LIMIT
+ Maximale Anzahl von Seiten, die in den generierten Listen angezeigt
+ werden sollen (Suche, ...)
+
+ EWIKI_PRINT_TITLE
+ Wenn 0 werden keine SeitenTitel (WikiSeiten und InterneSeiten)
+ angeziegt.
+
+
+ EWIKI_ALLOW_HTML
+ Normalerweise sollte im Wiki keine HTML erlaubt sein - böses JavaScript
+ und <brokenHTML/>, andere Leute nerven.
+
+ Siehe orig. README für mehr Informationen.
+
+
+ EWIKI_RESCUE_HTML
+ Überholt, siehe plugins/markup_rescuehtml.php
+
+
+ EWIKI_DB_F_TEXT
+ Dieses Flag wird für normale WikiSeiten in der DB gesetzt.
+
+ EWIKI_DB_F_BINARY
+ Für binären Inhalt in der DB.
+
+ EWIKI_DB_F_DISABLED
+ DB-Eintrage werden hiermit ausgeknippst.
+
+ EWIKI_DB_F_HTML
+ Erlaubt die Verwendung von HTML im WikiQuelltext, unabhängig von
+ EWIKI_ALLOW_HTML.
+
+ EWIKI_DB_F_READONLY
+ WikiSeite kann nicht verändert werden, so dieses Flag gesetzt ist.
+
+ EWIKI_DB_F_WRITEABLE
+ Umkehrung von READONLY, nur nützlich wenn zuvor alle Seiten mit
+ EWIKI_EDIT_AUTHENTICATE schriebgeschützt wurden.
+
+
+ EWIKI_ALLOW_OVERWRITE
+ Für eingeloggte nutzer kann yoursite.php diese Konst. auf 1 setzen, um
+ auch das Ändern von schreibgeschützten Seiten zu erlauben.
+
+ EWIKI_EDIT_AUTHENTICATE
+ Hiermit kann man ewiki dahingehend kaputt machen, daß alle Seiten
+ schreibgeschützt werden, und nur veränderbar sind, so yoursite.php
+ $ewiki_author setzt.
+
+
+ EWIKI_SCRIPT_BINARY
+ Um binäre Daten ausgeben zu können, muß hier ein wrapper-script
+ angegeben werden, daß ein Datenbank-Verbindung öffnet und keine
+ Textausgaben erzeugt, bevor nicht ewiki.php eingebunden wurde,
+ da sonst nur Datenmüll ausgegeben würde.
+
+ Um alle binary-Funktionalität (Bilder hochladen / cachen) loszuwerden,
+ einfach diese Konstante auf "" setzen, und die folgenden zwei auf 0:
+
+
+ EWIKI_CACHE_IMAGES
+ Bilder zwischenspeichern.
+
+ EWIKI_IMAGE_MAXSIZE
+ Maximale Größe von Bildern die in der DB abgelegt werden sollen.
+
+ EWIKI_IMAGE_RESIZE
+ Bilder herunterskalieren, wenn zu groß.
+
+ EWIKI_IDF_INTERNAL
+ Wird verwendet um hochgeladene Bilder zu identifizieren. Bitte
+ im laufenden Betrieb nicht ändern.
+
+
+ EWIKI_ADDPARAMDELIM
+ Automatisch definiert, enthält entweder "?" oder "&", abhängig von
+ EWIKI_SCRIPT.
+
+
+ EWIKI_T_*
+ überholt, siehe ewiki_t() und $ewiki_t[] in der englischen README
+
+
+ EWIKI_CHARS_U
+ EWIKI_CHARS_L
+ Erlaubte Zeichen in WikiSeitenNamen (große und kleine Letter). Hiermit
+ kann man das wiki lokalisieren; deutsche Umlaute sind schon enthalten.
+
+ UNIX_MILLENNIUM
+ Sehr wichtiges Ereignis ;)
+
+
+Im tools/ Ordner ist ein kleines Script, mit dem man die erwähnten
+SeitenFlags ändern kann.
+
+
+
+$ewiki_config[] array
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Einige der EWIKI_ Konstanten wurden durch Einträge im $ewiki_config[] Array
+ersetzt oder ergänzt (die Konstanten können weiterhin zur Voreinstellung
+verwendet werden). Der Vorteil dieses Arrays ist, daß die Einstellungen auch
+zur Laufzeit geändert werden können.
+
+Für eine komplette und (einigermaßen) aktuelle Übersicht bemühe bitte die
+englischsprachige README.
+
+
+
+
+ -------------------------------------------------------------------------
+
+
+
+
+Nur WikiQuelltextTransformation einsetzen
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Die ewiki_format Funktion war entworfen, um sie auch unabhängig von dem
+restlichen WikiSkript einsetzen zu können.
+Benötigt normalerweise nur den "wiki_source" Parmeter und erzeugt die
+HTML-Seite daraus.
+ ewiki_format($wiki_source, 0);
+
+Alles was man noch anpassen muß ist die $ewiki_links Variable. Setze
+$ewiki_links=true ("true" und nicht "1") so daß ewiki_format() später
+annimmt alle WikiSeiten würden existieren.
+
+Wers eilig hat, kann auch die extrahierte Variante fragments/wiki_format.inc
+verwenden, die Frank Luithle beigesteuert hat.
+
+
+
+
+ -------------------------------------------------------------------------
+
+
+
+
+Ohne MySQL DB verwenden
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Sollte dein Provider keine MySQL Datenbank für dich bereithalten, kannst
+du das plugin "db_flat_files.php" verwenden (einfach include("plugins/...");
+aufrufen um es zu laden).
+
+Alle WikiSeiten werden dann in Textdateien in einem nur dafür
+bereitgestelltem Ordner gespeichert. Stelle hierzu noch die Konstante
+EWIKI_DBFILES_DIRECTORY in der Datei "ewiki.php" passend ein ("/tmp" würde
+jedesmal gelöscht, wenn der Server neu startet).
+Das Verzeichnus muß relativ zum ewiki.php script angegeben werden, oder
+absolut zum Serverhauptverzeichnis, nicht aber relativ zum DocumentRoot
+deines Webspeicherplatzes! In diesem Beispiel wäre "./pages" richtig:
+
+Erstelle ein neues Verzeichnis (via FTP-Programm) und gib dem Webserver
+Schreibzugriff dafür mit dem Befehl " chmod 777 ./pages ".
+ftp> cd .../ewiki
+ftp> mkdir pages
+ftp> chmod 777 pages
+ftp> ls
+-rw----r-- 1 deinname deinname 57024 01. Jan 00:00 ewiki.php
+-rw----r-- 1 deinname deinname 512 01. Jan 00:00 index.php
+drw----r-x 2 deinname deinname 4096 01. Jan 00:00 init-pages
+drwxrwxrwx 2 deinname deinname 4096 25. Feb 23:59 pages
+drw----r-x 5 deinname deinname 4096 01. Jan 00:00 plugins
+-rw----r-- 1 deinname deinname 15826 01. Jan 00:00 README.de
+ftp> quit
+
+Mit einem graphischem FTP-Programm gibt es auch immer die Mglk. die
+"Dateizugriffsrechte" einzustellen.
+
+
+
+db_fast_files
+¯¯¯¯¯¯¯¯¯¯¯¯¯
+Diese neuere Version von db_flat_files, speichert die WikiSeiten
+komprimiert in einem Binär-Format (kann man nicht mehr mit Editor
+ansehen und bearbeiten). Zusätzlich wurde der HitZähler aktiviert.
+
+db_fast_files wurde in db_flat_files integriert, so daß das neue
+Format jetzt nur noch über eine Konstante aktiviert werden muß
+(beide Dateiformate können gleichzeitig in der DB vorhanden sein).
+Für die schnellere Variante aktiviere in "plugins/db_flat_files.php"
+die entsprechende Konstante:
+ define("EWIKI_DB_FAST_FILES", 1);
+(Diese Einstellung könntest du aber auch schon in der "config.php"
+eintragen.)
+
+Zusätzliche Konstante: EWIKI_DBFILES_GZLEVEL sagt wieviel Zeit
+beim Komprimieren verschwendet werden soll:
+0 - keine Komprimierung
+1 - ein ganz klein wenig Kompr.
+2 - Voreinstellung, schnell
+5 - normaler Wert in zlib, gute Komprimierung
+9 - langsam für allerbeste Kompression
+
+Dieses plugin wurde von Carsten Senf beigesteuert.
+
+
+
+
+ --------------------------------------------------------------------------
+
+
+
+
+BöseBäckSläshes
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Wenn auf deinen Seiten pötzlich viele "\" RückwärtsSchrägStriche
+auftauchen liegt das an einer Fehlkonfiguration von PHP. In älteren
+Versionen war leider immer die Option "magic_slashes_gpc" aktiviert
+(siehe auch php.ini).
+
+Bitte am besten deinen WebserverProvider das zu ändern. Wenn du aber bei
+einem der BilligHoster (umsonst wie sourceforge.net oder tripod.com) bist,
+gilt wie immer: einem geschenkten Gaul...
+Dann verwende bitte "fragements/strip_wonderful_slashes.php", um das
+Problem zumindest zu umschiffen, oder ändere deine .htaccess Datei (Apache)
+wie darin beschrieben.
+
+
+
+ --------------------------------------------------------------------------
+
+
+
+Paßwörter und tools/
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+Die tools/ sind gefährlich und daher per Voreinstellung nicht ohne weiteres
+Nutzbar. In der Datei "tools/t_config.php" wird das Script
+"fragmenst/funcs/auth.php" geladen, daß für den Browser-Login-Dialog
+verantwortlich ist. Wenn du also die tools/ verwenden willst, mußt du dort
+zuerst einen Benutzer mit Paßwort eintragen, sonst geht nix.
+
+Um hingegen dein Wiki zu schützen, so daß nur einige wenige Personen die
+Seiten editieren können, ließ dir bitte die Datei "plugins/auth/README.auth"
+durch (leider nur in Englisch). Sie beschreibt den _PROTECTED_MODE und
+stellt die entsprechenden Plugins vor.
+
+
--- /dev/null
+If you updated from R1.01c or earlier, then use the "tools/upgrade-101d"
+to convert the plugin file names in your 'config.php' file.
--- /dev/null
+<script language="PHP"> @define("EWIKI_VERSION", "R1.01d");
+
+/*
+
+ ErfurtWiki - an embedable, fast and user-friendly wiki engine
+ ¯¯¯¯¯¯¯¯¯¯
+ This is Public Domain (no license, no warranty); but feel free
+ to redistribute it under GPL or anything else you like.
+
+ http://erfurtwiki.sourceforge.net/
+ Mario Salzer <mario*erphesfurt·de> and many others(tm)
+
+
+ Use it from inside yoursite.php like that:
+ <html><body>...
+ <?php
+ include("ewiki.php");
+ echo ewiki_page();
+ ?>
+
+*/
+
+#-- you could also establish a mysql connection in here, of course:
+// mysql_connect(":/var/run/mysqld/mysqld.sock", "user", "pw")
+// and mysql_query("USE mydatabase");
+
+
+ #-------------------------------------------------------- config ---
+
+ #-- I'm sorry for that, but all the @ annoy me
+ error_reporting(0x0000377 & error_reporting());
+# error_reporting(E_ALL^E_NOTICE);
+
+ #-- the position of your ewiki-wrapper script
+ define("EWIKI_SCRIPT", "?id="); # relative/absolute to docroot
+# define("EWIKI_SCRIPT_URL", "http://...?id="); # absolute URL
+
+ #-- change to your needs (site lang)
+ define("EWIKI_NAME", "ErfurtWiki");
+ define("EWIKI_PAGE_INDEX", "ErfurtWiki");
+ define("EWIKI_PAGE_NEWEST", "NewestPages");
+ define("EWIKI_PAGE_SEARCH", "SearchPages");
+ define("EWIKI_PAGE_HITS", "MostVisitedPages");
+ define("EWIKI_PAGE_VERSIONS", "MostOftenChangedPages");
+ define("EWIKI_PAGE_UPDATES", "UpdatedPages");
+
+ #-- default settings are good settings - most often ;)
+ #- look & feel
+ define("EWIKI_PRINT_TITLE", 1); # <h2>WikiPageName</h2> on top
+ define("EWIKI_SPLIT_TITLE", 0); # <h2>Wiki Page Name</h2>
+ define("EWIKI_CONTROL_LINE", 1); # EditThisPage-link at bottom
+ define("EWIKI_LIST_LIMIT", 20); # listing limit
+ #- behaviour
+ define("EWIKI_AUTO_EDIT", 1); # edit box for non-existent pages
+ define("EWIKI_EDIT_REDIRECT", 1); # redirect after edit save
+ define("EWIKI_DEFAULT_ACTION", "view"); # (keep!)
+ define("EWIKI_CASE_INSENSITIVE", 1); # wikilink case sensitivity
+ define("EWIKI_HIT_COUNTING", 1);
+ define("UNIX_MILLENNIUM", 1000000000);
+ #- rendering
+ define("EWIKI_ALLOW_HTML", 0); # often a very bad idea
+ define("EWIKI_HTML_CHARS", 1); # allows for È
+ define("EWIKI_ESCAPE_AT", 1); # "@" -> "@"
+ #- http/urls
+ define("EWIKI_HTTP_HEADERS", 1); # most often a good thing
+ define("EWIKI_NO_CACHE", 1); # browser+proxy shall not cache
+ define("EWIKI_URLENCODE", 1); # disable when _USE_PATH_INFO
+ define("EWIKI_URLDECODE", 1);
+ define("EWIKI_USE_PATH_INFO", 1 &&!strstr($_SERVER["SERVER_SOFTWARE"],"Apache"));
+ define("EWIKI_USE_ACTION_PARAM", 1);
+ define("EWIKI_ACTION_SEP_CHAR", "/");
+ define("EWIKI_UP_PAGENUM", "n"); # _UP_ means "url parameter"
+ define("EWIKI_UP_PAGEEND", "e");
+ define("EWIKI_UP_BINARY", "binary");
+ define("EWIKI_UP_UPLOAD", "upload");
+ #- other stuff
+ define("EWIKI_DEFAULT_LANG", "en");
+ define("EWIKI_CHARSET", "ISO-8859-1");
+ #- user permissions
+ define("EWIKI_PROTECTED_MODE", 0); # disable funcs + require auth
+ define("EWIKI_PROTECTED_MODE_HIDING", 0); # hides disallowed actions
+ define("EWIKI_AUTH_DEFAULT_RING", 3); # 0=root 1=priv 2=user 3=view
+ define("EWIKI_AUTO_LOGIN", 1); # [auth_query] on startup
+
+ #-- allowed WikiPageNameCharacters
+ define("EWIKI_CHARS_L", "a-z_µ¤$\337-\377");
+ define("EWIKI_CHARS_U", "A-Z0-9\300-\336");
+ define("EWIKI_CHARS", EWIKI_CHARS_L.EWIKI_CHARS_U);
+
+ #-- database
+ define("EWIKI_DB_TABLE_NAME", "ewiki"); # MySQL / ADOdb
+ define("EWIKI_DBFILES_DIRECTORY", "/tmp"); # see "db_flat_files.php"
+ define("EWIKI_DBA", "/tmp/ewiki.dba"); # see "db_dba.php"
+ define("EWIKI_DBQUERY_BUFFER", 512*1024); # 512K
+ define("EWIKI_INIT_PAGES", "./init-pages"); # for initialization
+
+ define("EWIKI_DB_F_TEXT", 1<<0);
+ define("EWIKI_DB_F_BINARY", 1<<1);
+ define("EWIKI_DB_F_DISABLED", 1<<2);
+ define("EWIKI_DB_F_HTML", 1<<3);
+ define("EWIKI_DB_F_READONLY", 1<<4);
+ define("EWIKI_DB_F_WRITEABLE", 1<<5);
+ define("EWIKI_DB_F_APPENDONLY", 1<<6); #nyi
+ define("EWIKI_DB_F_SYSTEM", 1<<7);
+ define("EWIKI_DB_F_PART", 1<<8);
+ 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);
+ define("EWIKI_DB_F_ACCESS", EWIKI_DB_F_READONLY | EWIKI_DB_F_WRITEABLE | EWIKI_DB_F_APPENDONLY);
+ define("EWIKI_DB_F_COPYMASK", EWIKI_DB_F_TYPE | EWIKI_DB_F_ACCESS);
+
+ define("EWIKI_DBFILES_NLR", '\\n');
+ define("EWIKI_DBFILES_ENCODE", 0 || (DIRECTORY_SEPARATOR != "/"));
+ define("EWIKI_DBFILES_GZLEVEL", "2");
+
+ #-- internal
+ define("EWIKI_ADDPARAMDELIM", (strstr(EWIKI_SCRIPT,"?") ? "&" : "?"));
+
+ #-- binary content (images)
+ define("EWIKI_SCRIPT_BINARY", /*"/binary.php?binary="*/ ltrim(strtok(" ".EWIKI_SCRIPT,"?"))."?".EWIKI_UP_BINARY."=" );
+ define("EWIKI_CACHE_IMAGES", 1 &&!headers_sent());
+ define("EWIKI_IMAGE_MAXSIZE", 64 *1024);
+ define("EWIKI_IMAGE_MAXWIDTH", 3072);
+ define("EWIKI_IMAGE_MAXHEIGHT", 2048);
+ define("EWIKI_IMAGE_MAXALLOC", 1<<19);
+ define("EWIKI_IMAGE_RESIZE", 1);
+ define("EWIKI_IMAGE_ACCEPT", "image/jpeg,image/png,image/gif,application/x-shockwave-flash");
+ define("EWIKI_IDF_INTERNAL", "internal://");
+ define("EWIKI_ACCEPT_BINARY", 0); # for arbitrary binary data files
+
+ #-- misc
+ define("EWIKI_TMP", $_SERVER["TEMP"] ? $_SERVER["TEMP"] : "/tmp");
+ define("EWIKI_LOGLEVEL", -1); # 0=error 1=warn 2=info 3=debug
+ define("EWIKI_LOGFILE", "/tmp/ewiki.log");
+
+ #-- plugins (tasks mapped to function names)
+ $ewiki_plugins["database"][] = "ewiki_database_mysql";
+ $ewiki_plugins["edit_preview"][] = "ewiki_page_edit_preview";
+ $ewiki_plugins["render"][] = "ewiki_format";
+ $ewiki_plugins["init"][-5] = "ewiki_localization";
+ $ewiki_plugins["init"][-1] = "ewiki_binary";
+ $ewiki_plugins["handler"][-105] = "ewiki_eventually_initialize";
+ $ewiki_plugins["handler"][] = "ewiki_intermap_walking";
+ $ewiki_plugins["view_append"][-1] = "ewiki_control_links";
+ $ewiki_plugins["view_final"][-1] = "ewiki_add_title";
+ $ewiki_plugins["page_final"][] = "ewiki_http_headers";
+ $ewiki_plugins["page_final"][99115115] = "ewiki_page_css_container";
+ $ewiki_plugins["edit_form_final"][] = "ewiki_page_edit_form_final_imgupload";
+ $ewiki_plugins["format_block"]["pre"][] = "ewiki_format_pre";
+ $ewiki_plugins["format_block"]["code"][] = "ewiki_format_pre";
+ $ewiki_plugins["format_block"]["htm"][] = "ewiki_format_html";
+ $ewiki_plugins["format_block"]["html"][] = "ewiki_format_html";
+ $ewiki_plugins["format_block"]["comment"][] = "ewiki_format_comment";
+
+
+ #-- internal pages
+ $ewiki_plugins["page"][EWIKI_PAGE_NEWEST] = "ewiki_page_newest";
+ $ewiki_plugins["page"][EWIKI_PAGE_SEARCH] = "ewiki_page_search";
+ if (EWIKI_HIT_COUNTING) $ewiki_plugins["page"][EWIKI_PAGE_HITS] = "ewiki_page_hits";
+ $ewiki_plugins["page"][EWIKI_PAGE_VERSIONS] = "ewiki_page_versions";
+ $ewiki_plugins["page"][EWIKI_PAGE_UPDATES] = "ewiki_page_updates";
+
+ #-- page actions
+ $ewiki_plugins["action"]["edit"] = "ewiki_page_edit";
+ $ewiki_plugins["action_always"]["links"] = "ewiki_page_links";
+ $ewiki_plugins["action"]["info"] = "ewiki_page_info";
+ $ewiki_plugins["action"]["view"] = "ewiki_page_view";
+
+ #-- helper vars ---------------------------------------------------
+ $ewiki_config["idf"]["url"] = array("http://", "mailto:", "internal://", "ftp://", "https://", "irc://", "telnet://", "news://", "chrome://", "file://", "gopher://", "httpz://");
+ $ewiki_config["idf"]["img"] = array(".jpeg", ".png", ".jpg", ".gif", ".j2k");
+ $ewiki_config["idf"]["obj"] = array(".swf", ".svg");
+
+ #-- entitle actions
+ $ewiki_config["action_links"]["view"] = array_merge(array(
+ "edit" => "EDITTHISPAGE", # ewiki_t() is called on these
+ "links" => "BACKLINKS",
+ "info" => "PAGEHISTORY",
+ "like" => "LIKEPAGES",
+ ), @$ewiki_config["action_links"]["view"]
+ );
+ $ewiki_config["action_links"]["info"] = array_merge(array(
+ "view" => "browse",
+ "edit" => "fetchback",
+ ), @$ewiki_config["action_links"]["info"]
+ );
+
+ #-- variable configuration settings (go into '$ewiki_config')
+ $ewiki_config_DEFAULTSTMP = array(
+ "edit_thank_you" => 1,
+ "edit_box_size" => "70x15",
+ "print_title" => EWIKI_PRINT_TITLE,
+ "split_title" => EWIKI_SPLIT_TITLE,
+ "control_line" => EWIKI_CONTROL_LINE,
+ "list_limit" => EWIKI_LIST_LIMIT,
+ "script" => EWIKI_SCRIPT,
+ "script_url" => (defined("EWIKI_SCRIPT_URL")?EWIKI_SCRIPT_URL:NULL),
+ "script_binary" => EWIKI_SCRIPT_BINARY,
+ #-- heart of the wiki -- don't try to read this! ;)
+ "wiki_pre_scan_regex" => '/
+ (?<![~!])
+ ((?:(?:\w+:)*['.EWIKI_CHARS_U.']+['.EWIKI_CHARS_L.']+){2,}[\w\d]*)
+ |\^([-'.EWIKI_CHARS_L.EWIKI_CHARS_U.']{3,})
+ |\[ (?:"[^\]\"]+" | \s+ | [^:\]#]+\|)* ([^\|\"\[\]\#]+) (?:\s+ | "[^\]\"]+")* [\]\#]
+ |(\w{3,9}:\/\/[^?#\s\[\]\'\"\)\,<]+) /x',
+ "wiki_link_regex" => "\007 [!~]?(
+ \#?\[[^<>\[\]\n]+\] |
+ \^[-".EWIKI_CHARS_U.EWIKI_CHARS_L."]{3,} |
+ \b([\w]{3,}:)*([".EWIKI_CHARS_U."]+[".EWIKI_CHARS_L."]+){2,}\#?[\w\d]* |
+ ([a-z]{2,9}://|mailto:)[^\s\[\]\'\"\)\,<]+ |
+ \w[-_.+\w]+@(\w[-_\w]+[.])+\w{2,} ) \007x",
+ #-- rendering ruleset
+ "wm_indent" => '<div style="margin-left:15px;" class="indent">',
+ "wm_table_defaults" => 'cellpadding="2" border="1" cellspacing="0"',
+ "wm_whole_line" => array(),
+ "htmlentities" => array(
+ "&" => "&",
+ ">" => ">",
+ "<" => "<",
+ ),
+ "wm_source" => array(
+ "%%%" => "<br>",
+ "\t" => " ",
+ "\n;:" => "\n ", # workaround, replaces the old ;:
+ ),
+ "wm_list" => array(
+ "-" => array('ul type="square"', "", "li"),
+ "*" => array('ul type="circle"', "", "li"),
+ "#" => array("ol", "", "li"),
+ ":" => array("dl", "dt", "dd"),
+ #<out># ";" => array("dl", "dt", "dd"),
+ ),
+ "wm_style" => array(
+ "'''''" => array("<b><i>", "</i></b>"),
+ "'''" => array("<b>", "</b>"),
+ "___" => array("<i><b>", "</b></i>"),
+ "''" => array("<em>", "</em>"),
+ "__" => array("<strong>", "</strong>"),
+ "^^" => array("<sup>", "</sup>"),
+ "==" => array("<tt>", "</tt>"),
+ #<off># "***" => array("<b><i>", "</i></b>"),
+ #<off># "###" => array("<big><b>", "</b></big>"),
+ "**" => array("<b>", "</b>"),
+ "##" => array("<big>", "</big>"),
+ "µµ" => array("<small>", "</small>"),
+ ),
+ "wm_start_end" => array(
+ ),
+ #-- rendering plugins
+ "format_block" => array(
+ "html" => array("<html>", "</html>", "html", 0x0000),
+ "htm" => array("<htm>", "</htm>", "html", 0x0003),
+ "code" => array("<code>", "</code>", false, 0x0000),
+ "pre" => array("<pre>", "</pre>", false, 0x003F),
+ "comment" => array("\n<!--", "-->", false, 0x0030),
+ # "verbatim" => array("<verbatim>", "</verbatim>", false, 0x0000),
+ ),
+ "format_params" => array(
+ "scan_links" => 1,
+ "html" => EWIKI_ALLOW_HTML,
+ "mpi" => 1,
+ ),
+ );
+ foreach ($ewiki_config_DEFAULTSTMP as $set => $val) {
+ if (!isset($ewiki_config[$set])) {
+ $ewiki_config[$set] = $val;
+ }
+ elseif (is_array($val)) foreach ($val as $vali=>$valv) {
+ if (is_int($vali)) {
+ $ewiki_config[$set][] = $valv;
+ }
+ elseif (!isset($ewiki_config[$set][$vali])) {
+ $ewiki_config[$set][$vali] = $valv;
+ }
+ }
+ }
+ $ewiki_config_DEFAULTSTMP = $valv = $vali = $val = NULL;
+
+ #-- init stuff, autostarted parts
+ ksort($ewiki_plugins["init"]);
+ if ($pf_a = $ewiki_plugins["init"]) foreach ($pf_a as $pf) {
+ $pf($GLOBALS);
+ }
+ unset($ewiki_plugins["init"]);
+
+ #-- text (never remove the "C" or "en" sections!)
+ #
+ $ewiki_t["C"] = array_merge(@$ewiki_t["C"], array(
+ "DATE" => "%a, %d %b %G %T %Z",
+ "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>',
+ ));
+ #
+ $ewiki_t["en"] = array_merge(@$ewiki_t["en"], array(
+ "EDITTHISPAGE" => "EditThisPage",
+ "APPENDTOPAGE" => "Add to",
+ "BACKLINKS" => "BackLinks",
+ "PAGESLINKINGTO" => "Pages linking to \$title",
+ "PAGEHISTORY" => "PageInfo",
+ "INFOABOUTPAGE" => "Information about page",
+ "LIKEPAGES" => "Pages like this",
+ "NEWESTPAGES" => "Newest Pages",
+ "LASTCHANGED" => "last changed on %c",
+ "DOESNOTEXIST" => "This page does not yet exist, please click on EditThisPage if you'd like to create it.",
+ "DISABLEDPAGE" => "This page is currently not available.",
+ "ERRVERSIONSAVE" => "Sorry, while you edited this page someone else
+ did already save a changed version. Please go back to the
+ previous screen and copy your changes to your computers
+ clipboard to insert it again after you reload the edit
+ screen.",
+ "ERRORSAVING" => "An error occoured while saving your changes. Please try again.",
+ "THANKSFORCONTRIBUTION" => "Thank you for your contribution!",
+ "CANNOTCHANGEPAGE" => "This page cannot be changed.",
+ "OLDVERCOMEBACK" => "Make this old version come back to replace the current one",
+ "PREVIEW" => "Preview",
+ "SAVE" => "Save",
+ "CANCEL_EDIT" => "CancelEditing",
+ "UPLOAD_PICTURE_BUTTON" => "upload picture >>>",
+ "EDIT_FORM_1" => "<a href=\"".EWIKI_SCRIPT."GoodStyle\">GoodStyle</a> is to
+ write what comes to your mind. Don't care about how it
+ looks too much now. You can add <a href=\"".EWIKI_SCRIPT."WikiMarkup\">WikiMarkup</a>
+ also later if you think it is necessary.<br>",
+ "EDIT_FORM_2" => "<br>Please do not write things, which may make other
+ people angry. And please keep in mind that you are not all that
+ anonymous in the internet (find out more about your computers
+ '<a href=\"http://google.com/search?q=my+computers+IP+address\">IP address</a>' at Google).",
+ "BIN_IMGTOOLARGE" => "Image file is too large!",
+ "BIN_NOIMG" => "This is no image file (inacceptable file format)!",
+ "FORBIDDEN" => "You are not authorized to access this page.",
+ ));
+ #
+ $ewiki_t["es"] = array_merge(@$ewiki_t["es"], array(
+ "EDITTHISPAGE" => "EditarEstaPágina",
+ "BACKLINKS" => "EnlacesInversos",
+ "PAGESLINKINGTO" => "Páginas enlazando \$title",
+ "PAGEHISTORY" => "InfoPágina",
+ "INFOABOUTPAGE" => "Información sobre la página",
+ "LIKEPAGES" => "Páginas como esta",
+ "NEWESTPAGES" => "Páginas más nuevas",
+ "LASTCHANGED" => "última modificación %d/%m/%Y a las %H:%M",
+ "DOESNOTEXIST" => "Esta página aún no existe, por favor eliga EditarEstaPágina si desea crearla.",
+ "DISABLEDPAGE" => "Esta página no está disponible en este momento.",
+ "ERRVERSIONSAVE" => "Disculpe, mientras editaba esta página alguién más
+ salvó una versión modificada. Por favor regrese a
+ a la pantalla anterior y copie sus cambios a su computador
+ para insertalos nuevamente después de que cargue
+ la pantalla de edición.",
+ "ERRORSAVING" => "Ocurrió un error mientras se salvavan sus cambios. Por favor intente de nuevo.",
+ "THANKSFORCONTRIBUTION" => "Gracias por su contribución!",
+ "CANNOTCHANGEPAGE" => "Esta página no puede ser modificada.",
+ "OLDVERCOMEBACK" => "Hacer que esta versión antigua regrese a remplazar la actual",
+ "PREVIEW" => "Previsualizar",
+ "SAVE" => "Salvar",
+ "CANCEL_EDIT" => "CancelarEdición",
+ "UPLOAD_PICTURE_BUTTON" => "subir gráfica >>>",
+ "EDIT_FORM_1" => "<a href=\"".EWIKI_SCRIPT."BuenEstilo\">BuenEstilo</a> es
+ escribir lo que viene a su mente. No se preocupe mucho
+ por la apariencia. También puede agregar <a href=\"".EWIKI_SCRIPT."ReglasDeMarcadoWiki\">ReglasDeMarcadoWiki</a>
+ más adelante si piensa que es necesario.<br>",
+ "EDIT_FORM_2" => "<br>Por favor no escriba cosas, que puedan
+ enfadar a otras personas. Y por favor tenga en mente que
+ usted no es del todo anónimo en Internet
+ (encuentre más sobre
+ '<a href=\"http://google.com/search?q=my+computers+IP+address\">IP address</a>' de su computador con Google).",
+ "BIN_IMGTOOLARGE" => "¡La gráfica es demasiado grande!",
+ "BIN_NOIMG" => "¡No es un archivo con una gráfica (formato de archivo inaceptable)!",
+ "FORBIDDEN" => "No está autorizado para acceder a esta página.",
+ ));
+ #
+ $ewiki_t["de"] = array_merge(@$ewiki_t["de"], array(
+ "EDITTHISPAGE" => "DieseSeiteÄndern",
+ "APPENDTOPAGE" => "Ergänze",
+ "BACKLINKS" => "ZurückLinks",
+ "PAGESLINKINGTO" => "Verweise zur Seite \$title",
+ "PAGEHISTORY" => "SeitenInfo",
+ "INFOABOUTPAGE" => "Informationen über Seite",
+ "LIKEPAGES" => "Ähnliche Seiten",
+ "NEWESTPAGES" => "Neueste Seiten",
+ "LASTCHANGED" => "zuletzt geändert am %d.%m.%Y um %H:%M",
+ "DISABLEDPAGE" => "Diese Seite kann momentan nicht angezeigt werden.",
+ "ERRVERSIONSAVE" => "Entschuldige, aber während Du an der Seite
+ gearbeitet hast, hat bereits jemand anders eine geänderte
+ Fassung gespeichert. Damit nichts verloren geht, browse bitte
+ zurück und speichere Deine Änderungen in der Zwischenablage
+ (Bearbeiten->Kopieren) um sie dann wieder an der richtigen
+ Stelle einzufügen, nachdem du die EditBoxSeite nocheinmal
+ geladen hast.<br>
+ Vielen Dank für Deine Mühe.",
+ "ERRORSAVING" => "Beim Abspeichern ist ein Fehler aufgetreten. Bitte versuche es erneut.",
+ "THANKSFORCONTRIBUTION" => "Vielen Dank für Deinen Beitrag!",
+ "CANNOTCHANGEPAGE" => "Diese Seite kann nicht geändert werden.",
+ "OLDVERCOMEBACK" => "Diese alte Version der Seite wieder zur Aktuellen machen",
+ "PREVIEW" => "Vorschau",
+ "SAVE" => "Speichern",
+ "CANCEL_EDIT" => "ÄnderungenVerwerfen",
+ "UPLOAD_PICTURE_BUTTON" => "Bild hochladen >>>",
+ "EDIT_FORM_1" => "<a href=\"".EWIKI_SCRIPT."GuterStil\">GuterStil</a> ist es,
+ ganz einfach das zu schreiben, was einem gerade in den
+ Sinn kommt. Du solltest dich jetzt noch nicht so sehr
+ darum kümmern, wie die Seite aussieht. Du kannst später
+ immernoch zurückkommen und den Text mit <a href=\"".EWIKI_SCRIPT."FormatierungsRegeln\">WikiTextFormatierungsRegeln</a>
+ aufputschen.<br>",
+ "EDIT_FORM_2" => "<br>Bitte schreib keine Dinge, die andere Leute
+ verärgern könnten. Und bedenke auch, daß es schnell auf
+ dich zurückfallen kann wenn du verschiedene andere Dinge sagst (mehr Informationen zur
+ '<a href=\"http://google.de/search?q=computer+IP+adresse\">IP Adresse</a>'
+ deines Computers findest du bei Google).",
+ ));
+
+ #-- InterWiki:Links
+ $ewiki_config["interwiki"] = array_merge(
+ @$ewiki_config["interwiki"],
+ array(
+ "javascript" => "", # this actually protects from javascript: links
+ "url" => "",
+# "self" => "this",
+ "this" => EWIKI_SCRIPT, # better was absolute _URL to ewiki wrapper
+ "jump" => "",
+ "ErfurtWiki" => "http://erfurtwiki.sourceforge.net/?id=",
+ "InterWiki" => "InterWikiSearch",
+ "InterWikiSearch" => "http://sunir.org/apps/meta.pl?",
+ "Wiki" => "WardsWiki",
+ "WardsWiki" => "http://www.c2.com/cgi/wiki?",
+ "WikiFind" => "http://c2.com/cgi/wiki?FindPage&value=",
+ "WikiPedia" => "http://www.wikipedia.com/wiki.cgi?",
+ "MeatBall" => "MeatballWiki",
+ "MeatballWiki" => "http://www.usemod.com/cgi-bin/mb.pl?",
+ "UseMod" => "http://www.usemod.com/cgi-bin/wiki.pl?",
+ "PhpWiki" => "http://phpwiki.sourceforge.net/phpwiki/index.php3?",
+ "LinuxWiki" => "http://linuxwiki.de/",
+ "OpenWiki" => "http://openwiki.com/?",
+ "Tavi" => "http://andstuff.org/tavi/",
+ "TWiki" => "http://twiki.sourceforge.net/cgi-bin/view/",
+ "MoinMoin" => "http://www.purl.net/wiki/moin/",
+ "Google" => "http://google.com/search?q=",
+ "ISBN" => "http://www.amazon.com/exec/obidos/ISBN=",
+ "icq" => "http://www.icq.com/",
+ ));
+
+
+
+
+
+#-------------------------------------------------------------------- main ---
+
+/* this is the main function, which you should preferrably call to
+ integrate the ewiki into your web site; it chains to most other
+ parts and plugins (including the edit box);
+ if you do not supply the requested pages "$id" we will fetch it
+ from the pre-defined possible URL parameters.
+*/
+function ewiki_page($id=false) {
+
+ global $ewiki_links, $ewiki_plugins, $ewiki_ring, $ewiki_t, $ewiki_errmsg;
+ #-- output var
+ $o = "";
+
+ #-- selected page
+ if (!isset($_REQUEST)) {
+ $_REQUEST = array_merge($HTTP_GET_VARS, $HTTP_POST_VARS);
+ }
+ if (!strlen($id)) {
+ $id = ewiki_id();
+ }
+
+ #-- page action
+ $action = EWIKI_DEFAULT_ACTION;
+ if ($delim = strpos($id, EWIKI_ACTION_SEP_CHAR)) {
+ $action = substr($id, 0, $delim);
+ $id = substr($id, $delim + 1);
+ }
+ elseif (EWIKI_USE_ACTION_PARAM && isset($_REQUEST["action"])) {
+ $action = $_REQUEST["action"];
+ }
+ $GLOBALS["ewiki_id"] = $id;
+ $GLOBALS["ewiki_title"] = ewiki_split_title($id);
+ $GLOBALS["ewiki_action"] = $action;
+
+ #-- fetch from db
+ $dquery = array(
+ "id" => $id
+ );
+ if (!isset($_REQUEST["content"]) && ($dquery["version"] = @$_REQUEST["version"])) {
+ $dquery["forced_version"] = $dquery["version"];
+ }
+ $data = array_merge($dquery, ewiki_database("GET", $dquery));
+
+ #-- stop here if page is not marked as _TEXT,
+ # perform authentication then, and let only administrators proceed
+ if (!empty($data["flags"]) && (($data["flags"] & EWIKI_DB_F_TYPE) != EWIKI_DB_F_TEXT)) {
+ if (($data["flags"] & EWIKI_DB_F_BINARY) && ($pf = $ewiki_plugins["handler_binary"][0])) {
+ return($pf($id, $data, $action)); //_BINARY entries handled separately
+ }
+ elseif (!EWIKI_PROTECTED_MODE || !ewiki_auth($id, $data, $action, 0, 1) && ($ewiki_ring!=0)) {
+ return(ewiki_t("DISABLEDPAGE"));
+ }
+ }
+
+ #-- pre-check if actions exist
+ $pf_page = ewiki_array($ewiki_plugins["page"], $id);
+
+ #-- edit <form> for non-existent pages
+ if (($action==EWIKI_DEFAULT_ACTION) && empty($data["content"]) && empty($pf_page)) {
+ if (EWIKI_AUTO_EDIT) {
+ $action = "edit";
+ }
+ else {
+ $data["content"] = ewiki_t("DOESNOTEXIST");
+ }
+ }
+ #-- more initialization
+ if ($pf_a = @$ewiki_plugins["page_init"]) {
+ ksort($pf_a);
+ foreach ($pf_a as $pf) {
+ $o .= $pf($id, $data, $action);
+ }
+ unset($ewiki_plugins["page_init"]);
+ }
+ $pf_page = ewiki_array($ewiki_plugins["page"], $id);
+
+ #-- require auth
+ if (EWIKI_PROTECTED_MODE) {
+ if (!ewiki_auth($id, $data, $action, $ring=false, $force=EWIKI_AUTO_LOGIN)) {
+ return($o.=$ewiki_errmsg);
+ }
+ }
+
+ #-- handlers
+ $handler_o = "";
+ if ($pf_a = @$ewiki_plugins["handler"]) {
+ ksort($pf_a);
+ foreach ($pf_a as $pf) {
+ if ($handler_o = $pf($id, $data, $action)) { break; }
+ } }
+
+ #-- finished by handler
+ if ($handler_o) {
+ $o .= $handler_o;
+ }
+ #-- actions that also work for static and internal pages
+ elseif (($pf = @$ewiki_plugins["action_always"][$action]) && function_exists($pf)) {
+ $o .= $pf($id, $data, $action);
+ }
+ #-- internal pages
+ elseif ($pf_page && function_exists($pf_page)) {
+ $o .= $pf_page($id, $data, $action);
+ }
+ #-- page actions
+ else {
+ $pf = @$ewiki_plugins["action"][$action];
+
+ #-- fallback to "view" action
+ if (empty($pf) || !function_exists($pf)) {
+
+ $pf = "ewiki_page_view";
+ $action = "view"; // we could also allow different (this is a
+ // catch-all) view variants, but this would lead to some problems
+ }
+
+ $o .= $pf($id, $data, $action);
+ }
+
+ #-- error instead of page?
+ if (empty($o) && $ewiki_errmsg) {
+ $o = $ewiki_errmsg;
+ }
+
+ #-- html post processing
+ if ($pf_a = $ewiki_plugins["page_final"]) {
+ ksort($pf_a);
+ foreach ($pf_a as $pf) {
+ $pf($o, $id, $data, $action);
+ }
+ }
+ (EWIKI_ESCAPE_AT) && ($o = str_replace("@", "@", $o));
+
+ return($o);
+}
+
+
+
+#-- HTTP meta headers
+function ewiki_http_headers(&$o, $id, &$data, $action) {
+ global $ewiki_t;
+ if (EWIKI_HTTP_HEADERS && !headers_sent()) {
+ if (!empty($data)) {
+ if ($uu = @$data["id"]) @header('Content-Disposition: inline; filename="' . urlencode($uu) . '.html"');
+ if ($uu = @$data["version"]) @header('Content-Version: ' . $uu);
+ if ($uu = @$data["lastmodified"]) @header('Last-Modified: ' . gmstrftime($ewiki_t["C"]["DATE"], $uu));
+ }
+ if (EWIKI_NO_CACHE) {
+ header('Expires: ' . gmstrftime($ewiki_t["C"]["DATE"], UNIX_MILLENNIUM));
+ header('Pragma: no-cache');
+ header('Cache-Control: no-cache, private, must-revalidate');
+ # change to "C-C: cache, must-revalidate" ??
+ # private only for authenticated users / _PROT_MODE
+ }
+ #-- ETag
+ if ($data["version"] && ($etag=ewiki_etag($data)) || ($etag=md5($o))) {
+ $weak = "W/" . urlencode($id) . "." . $data["version"];
+ header("ETag: \"$etag\""); ###, \"$weak\"");
+ }
+ }
+}
+function ewiki_etag(&$data) {
+ return( urlencode($data["id"]) . ":" . dechex($data["version"]) . ":ewiki:" .
+ dechex(crc32($data["content"]) & 0x7FFFBFFF) );
+}
+
+
+
+#-- encloses whole page output with a descriptive <div>
+function ewiki_page_css_container(&$o, &$id, &$data, &$action) {
+ $o = "<div class=\"wiki $action "
+ . strtr($id, ' ./ --_!"§$%&()=?²³{[]}`+#*;:,<>| @µöäüÖÄÜߤ^°«»\'\\',
+ '- -----------------------------------------------')
+ . "\">\n"
+ . $o . "\n</div>\n";
+}
+
+
+
+function ewiki_split_title ($id='', $split=EWIKI_SPLIT_TITLE, $entities=1) {
+ strlen($id) or ($id = $GLOBALS["ewiki_id"]);
+ if ($split) {
+ $id = preg_replace("/([".EWIKI_CHARS_L."])([".EWIKI_CHARS_U."]+)/", "$1 $2", $id);
+ }
+ return($entities ? htmlentities($id) : $id);
+}
+
+
+
+function ewiki_add_title(&$html, $id, &$data, $action, $go_action="links") {
+ $html = ewiki_make_title($id, '', 1, $action, $go_action) . $html;
+}
+
+
+function ewiki_make_title($id='', $title='', $class=3, $action="view", $go_action="links", $may_split=1) {
+
+ global $ewiki_config, $ewiki_plugins, $ewiki_title, $ewiki_id;
+
+ #-- advanced handler
+ if ($pf = @$ewiki_plugins["make_title"][0]) {
+ return($pf($title, $class, $action, $go_action, $may_split));
+ }
+ #-- disabled
+ elseif (!$ewiki_config["print_title"]) {
+ return("");
+ }
+
+ #-- get id
+ if (empty($id)) {
+ $id = $ewiki_id;
+ }
+
+ #-- get title
+ if (!strlen($title)) {
+ $title = $ewiki_title; // already in &html; format
+ }
+ elseif ($ewiki_config["split_title"] && $may_split) {
+ $title = ewiki_split_title($title, $ewiki_config["split_title"], 0&($title!=$ewiki_title));
+ }
+ else {
+ $title = htmlentities($title);
+ }
+
+ #-- title mangling
+ if ($pf_a = @$ewiki_plugins["title_transform"]) {
+ foreach ($pf_a as $pf) { $pf($id, $title, $go_action); }
+ }
+
+ #-- clickable link or simple headline
+ if ($class <= $ewiki_config["print_title"]) {
+ if ($uu = @$ewiki_config["link_title_action"][$action]) {
+ $go_action = $uu;
+ }
+ if ($uu = @$ewiki_config["link_title_url"]) {
+ $href = $uu;
+ unset($ewiki_config["link_title_url"]);
+ }
+ else {
+ $href = ewiki_script($go_action, $id);
+ }
+ $o = '<a href="' . $href . '">' . ($title) . '</a>';
+ }
+ else {
+ $o = $title;
+ }
+
+ return('<h2 class="page title">' . $o . '</h2>'."\n");
+}
+
+
+
+
+function ewiki_page_view($id, &$data, $action, $all=1) {
+
+ global $ewiki_plugins, $ewiki_config;
+ $o = "";
+
+ #-- render requested wiki page <-- goal !!!
+ $render_args = array(
+ "scan_links" => 1,
+ "html" => (EWIKI_ALLOW_HTML||(@$data["flags"]&EWIKI_DB_F_HTML)),
+ );
+ $o .= $ewiki_plugins["render"][0] ($data["content"], $render_args);
+ if (!$all) {
+ return($o);
+ }
+
+ #-- control line + other per-page info stuff
+ if ($pf_a = $ewiki_plugins["view_append"]) {
+ ksort($pf_a);
+ foreach ($pf_a as $n => $pf) { $o .= $pf($id, $data, $action); }
+ }
+ if ($pf_a = $ewiki_plugins["view_final"]) {
+ ksort($pf_a);
+ foreach ($pf_a as $n => $pf) { $pf($o, $id, $data, $action); }
+ }
+
+ if (!empty($_REQUEST["thankyou"]) && $ewiki_config["edit_thank_you"]) {
+ $o = ewiki_t("THANKSFORCONTRIBUTION") . $o;
+ }
+
+
+ if (EWIKI_HIT_COUNTING) {
+ ewiki_database("HIT", $data);
+ }
+
+ return($o);
+}
+
+
+
+
+#-------------------------------------------------------------------- util ---
+
+
+/* retrieves "$id/$action" string from URL / QueryString / PathInfo,
+ change this in conjunction with ewiki_script() to customize your URLs
+ further whenever desired
+*/
+function ewiki_id() {
+ ($id = @$_REQUEST["id"]) or
+ ($id = @$_REQUEST["name"]) or
+ ($id = @$_REQUEST["page"]) or
+ ($id = @$_REQUEST["file"]) or
+ (EWIKI_USE_PATH_INFO) and ($id = ltrim(@$_SERVER["PATH_INFO"], "/")) or
+ (!isset($_REQUEST["id"])) and ($id = trim(strtok($_SERVER["QUERY_STRING"], "&")));
+ if (!strlen($id) || ($id=="id=")) {
+ $id = EWIKI_PAGE_INDEX;
+ }
+ (EWIKI_URLDECODE) && ($id = urldecode($id));
+ return($id);
+}
+
+
+
+
+/* replaces EWIKI_SCRIPT, works more sophisticated, and
+ bypasses various design flaws
+ - if only the first parameter is used (old style), it can contain
+ a complete "action/WikiPage" - but this is ambigutious
+ - else $asid is the action, and $id contains the WikiPageName
+ - $ewiki_config["script"] will now be used in favour of the constant
+ - needs more work on _BINARY, should be a separate function
+*/
+## MOODLE-CHANGE: $asid="", Knows the devil why....
+function ewiki_script($asid="", $id=false, $params="", $bin=0, $html=1, $script=NULL) {
+ global $ewiki_config, $ewiki_plugins;
+
+ #-- get base script url from config vars
+ if (empty($script)) {
+ $script = &$ewiki_config[!$bin?"script":"script_binary"];
+ }
+
+ #-- separate $action and $id for old style requests
+ if ($id === false) {
+ if (strpos($asid, EWIKI_ACTION_SEP_CHAR) !== false) {
+ $asid = strtok($asid, EWIKI_ACTION_SEP_CHAR);
+ $id = strtok("\000");
+ }
+ else {
+ $id = $asid;
+ $asid = "";
+ }
+ }
+
+ #-- prepare params
+ if (is_array($params)) {
+ $uu = $params;
+ $params = "";
+ if ($uu) foreach ($uu as $k=>$v) {
+ $params .= (strlen($params)?"&":"") . rawurlencode($k) . "=" . rawurlencode($v);
+ }
+ }
+ #-- action= parameter
+ if (EWIKI_USE_ACTION_PARAM >= 2) {
+ $params = "action=$asid" . (strlen($params)?"&":"") . $params;
+ $asid = "";
+ }
+
+ #-- workaround slashes in $id
+ if (empty($asid) && (strpos($id, EWIKI_ACTION_SEP_CHAR) !== false) && !$bin) {
+ $asid = "view";
+ }
+ /*paranoia*/ $asid = trim($asid, EWIKI_ACTION_SEP_CHAR);
+
+ #-- make url
+ if (EWIKI_URLENCODE) {
+ $id = urlencode($id);
+ $asid = urlencode($asid);
+ }
+ else {
+ # only urlencode &, %, ? for example
+ }
+ $url = $script;
+ if ($asid) {
+ $id = $asid . EWIKI_ACTION_SEP_CHAR . $id; #= "action/PageName"
+ }
+ if (strpos($url, "%s") !== false) {
+ $url = str_replace("%s", $id, $url);
+ }
+ else {
+ $url .= $id;
+ }
+
+ #-- add url params
+ if (strlen($params)) {
+ $url .= (strpos($url,"?")!==false ? "&":"?") . $params;
+ }
+
+ #-- fin
+ if ($html) {
+ $url = str_replace("&", "&", $url);
+ }
+ return($url);
+}
+
+
+/* this ewiki_script() wrapper is used to generate URLs to binary
+ content in the ewiki database
+*/
+function ewiki_script_binary($asid, $id=false, $params=array(), $upload=0) {
+
+ $upload |= is_string($params) && strlen($params) || count($params);
+
+ #-- generate URL directly to the plainly saved data file,
+ # see also plugins/binary_store
+
+ if (defined("EWIKI_DB_STORE_URL") && !$upload) {
+ $url = EWIKI_DB_STORE_URL . rawurlencode($id);
+ }
+
+ #-- else get standard URL (thru ewiki.php) from ewiki_script()
+ else {
+ $url = ewiki_script($asid, $id, $params, "_BINARY=1");
+ }
+
+ return($url);
+}
+
+
+/* this function returns the absolute ewiki_script url, if EWIKI_SCRIPT_URL
+ is set, else it guesses the value
+*/
+function ewiki_script_url() {
+
+ global $ewiki_action, $ewiki_id, $ewiki_config;
+
+ $scr_template = $ewiki_config["script"];
+ $scr_current = ewiki_script($ewiki_action, $ewiki_id);
+ $req_uri = $_SERVER["REQUEST_URI"];
+
+ if ($url = $ewiki_config["script_url"]) {
+ return($url);
+ }
+ elseif (strpos($req_uri, $scr_current) !== false) {
+ $url = str_replace($req_uri, $scr_current, $scr_template);
+ }
+ elseif (strpos($req_uri, "?") && (strpos($scr_template, "?") !== false)) {
+ $url = substr($req_uri, 0, strpos($req_uri, "?"))
+ . substr($scr_template, strpos($scr_template, "?"));
+ }
+ elseif (strpos($req_uri, $sn = $_SERVER["SCRIPT_NAME"])) {
+ $url = $sn . "?id=";
+ }
+ else {
+ return(NULL); #-- could not guess it
+ }
+
+ $url = "http://" . $_SERVER["SERVER_NAME"] . $url;
+ return($url);
+}
+
+
+
+
+#------------------------------------------------------------ page plugins ---
+
+
+
+function ewiki_page_links($id, &$data, $action) {
+ $o = ewiki_make_title($id, ewiki_t("PAGESLINKINGTO", array("title"=>$id)), 1, $action, "", "_MAY_SPLIT=1");
+ if ($pages = ewiki_get_backlinks($id)) {
+ $o .= ewiki_list_pages($pages);
+ } else {
+ $o .= ewiki_t("This page isn't linked from anywhere else.");
+ }
+ return($o);
+}
+
+function ewiki_get_backlinks($id) {
+ $result = ewiki_database("SEARCH", array("refs" => $id));
+ $pages = array();
+ while ($row = $result->get(0, 0x0020)) {
+ if ( strpos($row["refs"], "\n$id\n") !== false) {
+ $pages[] = $row["id"];
+ }
+ }
+ return($pages);
+}
+
+function ewiki_get_links($id) {
+ if ($data = ewiki_database("GET", array("id"=>$id))) {
+ $refs = explode("\n", trim($data["refs"]));
+ $r = array();
+ foreach (ewiki_database("FIND", $refs) as $id=>$exists) {
+ if ($exists) {
+ $r[] = $id;
+ }
+ }
+ return($r);
+ }
+}
+
+
+function ewiki_list_pages($pages=array(), $limit=EWIKI_LIST_LIMIT,
+ $value_as_title=0, $pf_list=false)
+{
+ global $ewiki_plugins;
+ $o = "";
+
+ $is_num = !empty($pages[0]);
+ $lines = array();
+ $n = 0;
+
+ foreach ($pages as $id=>$add_text) {
+
+ $title = $id;
+ $params = "";
+
+ if (is_array($add_text)) {
+ list($id, $params, $title, $add_text) = $add_text;
+ }
+ elseif ($is_num) {
+ $id = $title = $add_text;
+ $add_text = "";
+ }
+ elseif ($value_as_title) {
+ $title = $add_text;
+ $add_text = "";
+ }
+
+ $lines[] = '<a href="' . ewiki_script("", $id, $params) . '">' . htmlentities($title) . '</a> ' . $add_text;
+
+ if (($limit > 0) && ($n++ >= $limit)) {
+ break;
+ }
+ }
+
+ if ($pf_a = @$ewiki_plugins["list_transform"])
+ foreach ($pf_a as $pf_transform) {
+ $pf_transform($lines);
+ }
+
+ if (($pf_list) || ($pf_list = @$ewiki_plugins["list_pages"][0])) {
+ $o = $pf_list($lines);
+ }
+ elseif($lines) {
+ $o = "· " . implode("<br>\n· ", $lines) . "<br>\n";
+ }
+
+ return($o);
+}
+
+
+
+
+function ewiki_page_ordered_list($orderby="created", $asc=0, $print, $title) {
+
+ $o = ewiki_make_title("", $title, 2, ".list", "links", 0);
+
+ $sorted = array();
+ $result = ewiki_database("GETALL", array($orderby));
+
+ while ($row = $result->get()) {
+ $row = ewiki_database("GET", array(
+ "id" => $row["id"],
+ ($asc >= 0 ? "version" : "uu") => 1 // version 1 is most accurate for {hits}
+ ));
+ #-- text page?
+ if (EWIKI_DB_F_TEXT == ($row["flags"] & EWIKI_DB_F_TYPE)) {
+ #-- viewing allowed?
+ if (!EWIKI_PROTECTED_MODE || !EWIKI_PROTECTED_MODE_HIDING || ewiki_auth($row["id"], $row, "view")) {
+ $sorted[$row["id"]] = $row[$orderby];
+ }
+ }
+ }
+
+ if ($asc != 0) { arsort($sorted); }
+ else { asort($sorted); }
+
+ foreach ($sorted as $name => $value) {
+ if (empty($value)) { $value = "0"; }
+ ##### BEGIN MOODLE ADDITION #####
+ #$sorted[$name] = strftime(str_replace('%n', $value, $print), $value);
+ if($print=="LASTCHANGED") {
+ $value=strftime("%c",$value);
+ }
+ $sorted[$name] = get_string(strtolower($print),"wiki",$value);
+ ##### BEGIN MOODLE ADDITION #####
+ }
+ $o .= ewiki_list_pages($sorted);
+
+ return($o);
+}
+
+
+
+function ewiki_page_newest($id=0, $data=0) {
+ return( ewiki_page_ordered_list("created", 1, "LASTCHANGED", ewiki_t("NEWESTPAGES")) );
+}
+
+function ewiki_page_updates($id=0, $data=0) {
+ return( ewiki_page_ordered_list("lastmodified", -1, "LASTCHANGED", EWIKI_PAGE_UPDATES) );
+}
+
+function ewiki_page_hits($id=0, $data=0) {
+ ##### BEGIN MOODLE ADDITION #####
+ return( ewiki_page_ordered_list("hits", 1, "hits", EWIKI_PAGE_HITS) );
+}
+
+function ewiki_page_versions($id=0, $data=0) {
+ return( ewiki_page_ordered_list("version", -1, "changes", EWIKI_PAGE_VERSIONS) );
+ ##### END MOODLE ADDITION #####
+}
+
+
+
+
+
+
+
+function ewiki_page_search($id, &$data, $action) {
+
+ $o = ewiki_make_title($id, $id, 2, $action);
+
+ if (! ($q = @$_REQUEST["q"])) {
+
+ $o .= '<form action="' . ewiki_script("", $id) . '" method="POST">';
+ $o .= '<input name="q" size="30"><br><br>';
+ $o .= '<input type="submit" value="'.$id.'">';
+ $o .= '</form>';
+ }
+ else {
+ $found = array();
+
+ $q = preg_replace('/\s*[^\w]+\s*/', ' ', $q);
+ foreach (explode(" ", $q) as $search) {
+
+ if (empty($search)) { continue; }
+
+ $result = ewiki_database("SEARCH", array("content" => $search));
+
+ while ($row = $result->get()) {
+
+ #-- show this entry in page listings?
+ if (EWIKI_PROTECTED_MODE && EWIKI_PROTECTED_MODE_HIDING && !ewiki_auth($row["id"], $row, "view")) {
+ continue;
+ }
+
+ $found[] = $row["id"];
+ }
+ }
+
+ $o .= ewiki_list_pages($found);
+ }
+
+ return($o);
+}
+
+
+
+
+
+
+
+
+function ewiki_page_info($id, &$data, $action) {
+
+ global $ewiki_plugins, $ewiki_config, $ewiki_links;
+
+ $o = ewiki_make_title($id, ewiki_t("INFOABOUTPAGE")." '{$id}'", 2, $action,"", "_MAY_SPLIT=1");
+
+ $flagnames = array(
+ "TEXT", "BIN", "DISABLED", "HTML", "READONLY", "WRITEABLE",
+ "APPENDONLY", "SYSTEM",
+ );
+ $show = array(
+ "version", "author", "created",
+ "lastmodified", "refs",
+ "flags", "meta", "content"
+ );
+
+ #-- versions to show
+ $v_start = $data["version"];
+ if ( ($uu=@$_REQUEST[EWIKI_UP_PAGENUM]) && ($uu<=$v_start) ) {
+ $v_start = $uu;
+ }
+ $v_end = $v_start - $ewiki_config["list_limit"];
+ if ( ($uu=@$_REQUEST[EWIKI_UP_PAGEEND]) && ($uu<=$v_start) ) {
+ $v_end = $uu;
+ }
+ $v_end = max($v_end, 1);
+
+ #-- go
+ # the very ($first) entry is rendered more verbosely than the others
+ for ($v=$v_start,$first=1; ($v>=$v_end); $v--,$first=0) {
+
+ $current = ewiki_database("GET", array("id"=>$id, "version"=>$v));
+
+ if (!strlen(trim($current["id"])) || !$current["version"] || !strlen(trim($current["content"]))) {
+ continue;
+ }
+
+ $o .= '<table class="version-info" border="1" cellpadding="2" cellspacing="1">' . "\n";
+
+ #-- additional info-actions
+ $o .= '<tr><td></td><td class="action-links">';
+ foreach ($ewiki_config["action_links"]["info"] as $action=>$title)
+ if (@$ewiki_plugins["action"][$action] || @$ewiki_plugins["action_always"][$action]) {
+ ##### BEGIN MOODLE ADDITION #####
+ $o .= '<a href="' .
+ ewiki_script($action, $id, array("version"=>$current["version"])) .
+ '">' . get_string($title,"wiki") . '</a> ';
+ ##### END MOODLE ADDITION #####
+ }
+ $o .= "</td></tr>\n";
+
+ #-- print page database entry
+ foreach($show as $i) {
+
+ $value = @$current[$i];
+
+ #-- show database {fields} differently
+ if ($i == "meta") {
+ $str = "";
+ if ($first && $value) { foreach ($value as $n=>$d) {
+ $str .= htmlentities("$n: $d") . "<br>\n";
+ } }
+ $value = $str;
+ }
+ elseif ($value >= UNIX_MILLENNIUM) { #-- {lastmodified}, {created}
+ #### BEGIN MOODLE CHANGE
+ $value=userdate($value, $strftimedatetime);
+ #$value = strftime("%c", $value);
+ #### END MOODLE CHANGE
+ }
+ elseif ($i == "content") {
+ $value = strlen(trim($value)) . " bytes";
+ $i = "content size";
+ }
+ elseif ($first && ($i == "refs") && !(EWIKI_PROTECTED_MODE && (EWIKI_PROTECTED_MODE_HIDING>=2))) {
+ $a = explode("\n", trim($value));
+ $ewiki_links = ewiki_database("FIND", $a);
+ ewiki_merge_links($ewiki_links);
+ foreach ($a as $n=>$link) {
+ $a[$n] = ewiki_link_regex_callback(array("$link"), "force_noimg");
+ }
+ $value = implode(", ", $a);
+ }
+ elseif (strpos($value, "\n") !== false) { #-- also for {refs}
+ $value = str_replace("\n", ", ", trim($value));
+ }
+ elseif ($i == "version") {
+ $value = '<a href="' .
+ ewiki_script("", $id, array("version"=>$value)) . '">' .
+ $value . '</a>';
+ }
+ elseif ($i == "flags") {
+ $fstr = "";
+ for ($n = 0; $n < 32; $n++) {
+ if ($value & (1 << $n)) {
+ if (! ($s=$flagnames[$n])) { $s = "UU$n"; }
+ $fstr .= $s . " ";
+ }
+ }
+ $value = $fstr;
+ }
+ elseif ($i == "author") {
+ $ewiki_links=1;
+ $value = preg_replace_callback("/((\w+:)?([".EWIKI_CHARS_U."]+[".EWIKI_CHARS_L."]+){2,}[\w\d]*)/", "ewiki_link_regex_callback", $value);
+ }
+
+ ##### BEGIN MOODLE ADDITION #####
+ $o .= '<tr class="page-'.$i.'"><td valign="top"><b>' .ewiki_t($i). '</b></td>' .
+ '<td>' . $value . "</td></tr>\n";
+ ##### END MOODLE ADDITION #####
+
+ }
+
+ $o .= "</table><br>\n";
+ }
+
+ #-- page result split
+ if ($v >= 1) {
+ $o .= "<br>\n show " . ewiki_chunked_page($this, $id, -1, $v+1, 1) . "\n <br>";
+ }
+
+ return($o);
+}
+
+
+
+
+function ewiki_chunked_page($action, $id, $dir=-1, $start=10, $end=1, $limit=0, $overlap=0.25, $collapse_last=0.67) {
+
+ global $ewiki_config;
+
+ if (empty($limit)) {
+ $limit = $ewiki_config["list_limit"];
+ }
+ if ($overlap < 1) {
+ $overlap = (int) ($limit * $overlap);
+ }
+
+ $p = "";
+ $n = $start;
+
+ while ($n) {
+
+ $n -= $dir * $overlap;
+
+ $e = $n + $dir * ($limit + $overlap);
+
+ if ($dir<0) {
+ $e = max(1, $e);
+ if ($e <= $collapse_last * $limit) {
+ $e = 1;
+ }
+ }
+ else {
+ $e = min($end, $e);
+ if ($e >= $collapse_last * $limit) {
+ $e = $end;
+ }
+ }
+
+ $o .= ($o?" · ":"")
+ . '<a href="'.ewiki_script($action, $id, array(EWIKI_UP_PAGENUM=>$n, EWIKI_UP_PAGEEND=>$e))
+ . '">'. "$n-$e" . '</a>';
+
+ if (($n=$e) <= $end) {
+ $n = false;
+ }
+ }
+
+ return('<div class="chunked-result">'. $o .'</div>');
+}
+
+
+
+
+
+
+function ewiki_page_edit($id, $data, $action) {
+
+ global $ewiki_links, $ewiki_author, $ewiki_plugins, $ewiki_ring, $ewiki_errmsg;
+
+ $hidden_postdata = array();
+
+ #-- previous version come back
+ if (@$data["forced_version"]) {
+
+ $current = ewiki_database("GET", array("id"=>$id));
+ $data["version"] = $current["version"];
+ unset($current);
+
+ unset($_REQUEST["content"]);
+ unset($_REQUEST["version"]);
+ }
+
+ #-- edit hacks
+ if ($pf_a = @$ewiki_plugins["edit_hook"]) foreach ($pf_a as $pf) {
+ if ($output = $pf($id, $data, $hidden_postdata)) {
+ return($output);
+ }
+ }
+
+ #-- permission checks
+ if (isset($ewiki_ring)) {
+ $ring = $ewiki_ring;
+ } else {
+ $ring = 3;
+ }
+ $flags = @$data["flags"];
+ if (!($flags & EWIKI_DB_F_WRITEABLE)) {
+
+ #-- perform auth
+ $edit_ring = (EWIKI_PROTECTED_MODE>=2) ? (2) : (NULL);
+ if (EWIKI_PROTECTED_MODE && !ewiki_auth($id, $data, $action, $edit_ring, "FORCE")) {
+ return($ewiki_errmsg);
+ }
+
+ #-- flag checking
+ if (($flags & EWIKI_DB_F_READONLY) and ($ring >= 2)) {
+ return(ewiki_t("CANNOTCHANGEPAGE"));
+ }
+ if (($flags) and (($flags & EWIKI_DB_F_TYPE) != EWIKI_DB_F_TEXT) and ($ring >= 1)) {
+ return(ewiki_t("CANNOTCHANGEPAGE"));
+ }
+ }
+
+ #-- "Edit Me"
+ $o = ewiki_make_title($id, ewiki_t("EDITTHISPAGE").(" '{$id}'"), 2, $action, "", "_MAY_SPLIT=1");
+
+ #-- preview
+ if (isset($_REQUEST["preview"])) {
+ $o .= $ewiki_plugins["edit_preview"][0]($data);
+ }
+
+ #-- save
+ if (isset($_REQUEST["save"])) {
+
+ #-- normalize to UNIX newlines
+ $_REQUEST["content"] = str_replace("\015\012", "\012", $_REQUEST["content"]);
+ $_REQUEST["content"] = str_replace("\015", "\012", $_REQUEST["content"]);
+
+ #-- check for concurrent version saving
+ $error = 0;
+ if ((@$data["version"] >= 1) && ($data["version"] != @$_REQUEST["version"]) || (@$_REQUEST["version"] < 1)) {
+
+ $pf = $ewiki_plugins["edit_patch"][0];
+
+ if (!$pf || !$pf($id, $data)) {
+ $error = 1;
+ $o .= ewiki_t("ERRVERSIONSAVE") . "<br><br>";
+ }
+
+ }
+ if (!$error) {
+
+ #-- new pages` flags
+ if (! ($set_flags = @$data["flags"] & EWIKI_DB_F_COPYMASK)) {
+ $set_flags = 1;
+ }
+ if (EWIKI_ALLOW_HTML) {
+ $set_flags |= EWIKI_DB_F_HTML;
+ }
+
+ #-- mk db entry
+ $save = array(
+ "id" => $id,
+ "version" => @$data["version"] + 1,
+ "flags" => $set_flags,
+ "content" => $_REQUEST["content"],
+ "created" => ($uu=@$data["created"]) ? $uu : time(),
+ "meta" => ($uu=@$data["meta"]) ? $uu : "",
+ "hits" => ($uu=@$data["hits"]) ? $uu : "0",
+ );
+ ewiki_data_update($save);
+
+ #-- edit storage hooks
+ if ($pf_a = @$ewiki_plugins["edit_save"]) {
+ foreach ($pf_a as $pf) {
+ $pf($save, $data);
+ }
+ }
+
+ #-- save
+ if (!$save || !ewiki_database("WRITE", $save)) {
+
+ $o .= $ewiki_errmsg ? $ewiki_errmsg : ewiki_t("ERRORSAVING");
+
+ }
+ else {
+ #-- prevent double saving, when ewiki_page() is re-called
+ $_REQUEST = $_GET = $_POST = array();
+
+ $o = ewiki_t("THANKSFORCONTRIBUTION") . "<br><br>";
+ $o .= ewiki_page($id);
+
+ if (EWIKI_EDIT_REDIRECT) {
+ $url = ewiki_script("", $id, "thankyou=1", 0, 0, EWIKI_HTTP_HEADERS?ewiki_script_url():0);
+ if (EWIKI_HTTP_HEADERS && !headers_sent()) {
+ header("Status: 303 Redirect for GET");
+ header("Location: $url");
+ #header("URI: $url");
+ #header("Refresh: 0; URL=$url");
+ }
+ else {
+ $o .= '<meta http-equiv="Refresh" content="0; URL='.htmlentities($url).'">';
+ }
+ }
+
+ }
+
+ }
+
+ //@REWORK
+ // header("Reload-Location: " . ewiki_script("", $id, "", 0, 0, ewiki_script_url()) );
+
+ }
+ else {
+ #-- Edit <form>
+ $o .= ewiki_page_edit_form($id, $data, $hidden_postdata);
+
+ #-- additional forms
+ if ($pf_a = $ewiki_plugins["edit_form_final"]) foreach ($pf_a as $pf) {
+ $pf($o, $id, $data, $action);
+ }
+ }
+
+ return($o);
+}
+
+
+function ewiki_data_update(&$data, $author="") {
+ global $ewiki_links;
+
+ #-- add backlinks entry
+ ewiki_scan_wikiwords($data["content"], $ewiki_links, "_STRIP_EMAIL=1");
+ $data["refs"] = "\n\n".implode("\n", array_keys($ewiki_links))."\n\n";
+ $data["lastmodified"] = time();
+ $data["author"] = ewiki_author($author);
+}
+
+
+
+#-- edit <textarea>
+function ewiki_page_edit_form(&$id, &$data, &$hidden_postdata) {
+ global $ewiki_plugins, $ewiki_config;
+ $o="";
+
+ #-- previously edited, or db fetched content
+ if (@$_REQUEST["content"] || @$_REQUEST["version"]) {
+ $data = array(
+ "version" => &$_REQUEST["version"],
+ "content" => &$_REQUEST["content"]
+ );
+ }
+ else {
+ if (empty($data["version"])) {
+ $data["version"] = 1;
+ }
+ @$data["content"] .= "";
+ }
+
+ #-- normalize to DOS newlines
+ $data["content"] = str_replace("\015\012", "\012", $data["content"]);
+ $data["content"] = str_replace("\015", "\012", $data["content"]);
+ $data["content"] = str_replace("\012", "\015\012", $data["content"]);
+
+ $hidden_postdata["version"] = &$data["version"];
+
+ #-- edit textarea/form
+ $o .= ewiki_t("EDIT_FORM_1")
+ . '<form method="POST" enctype="multipart/form-data" action="'
+ . ewiki_script("edit", $id) . '" name="ewiki"'
+ . ' accept-charset="'.EWIKI_CHARSET.'">' . "\n";
+
+ #-- additional POST vars
+ foreach ($hidden_postdata as $name => $value) {
+ $o .= '<input type="hidden" name="'.$name.'" value="'.$value.'">'."\n";
+ }
+
+ if (EWIKI_CHARSET=="UTF-8") {
+ $data["content"] = utf8_encode($data["content"]);
+ }
+ ($cols = strtok($ewiki_config["edit_box_size"], "x*/,;:")) && ($rows = strtok("x, ")) || ($cols=70) && ($rows=15);
+ global $ewiki_use_editor, $ewiki_editor_content;
+ $ewiki_editor_content=1;
+ if($ewiki_use_editor) {
+ ob_start();
+ print_textarea(1, $rows, $cols, 680, 400, "content", ewiki_format($data["content"]));
+ use_html_editor("content");
+ $o .= ob_get_contents();
+ ob_end_clean();
+ } else {
+ ##### END MOODLE ADDITION #####
+
+ $o .= '<textarea wrap="soft" id="ewiki_content" name="content" rows="'.$rows.'" cols="'.$cols.'">'
+ . htmlentities($data["content"]) . "</textarea>"
+ . $GLOBALS["ewiki_t"]["C"]["EDIT_TEXTAREA_RESIZE_JS"];
+
+ ##### BEGIN MOODLE ADDITION #####
+ }
+ ##### END MOODLE ADDITION #####
+
+ #-- more <input> elements before the submit button
+ if ($pf_a = $ewiki_plugins["edit_form_insert"]) foreach ($pf_a as $pf) {
+ $o .= $pf($id, $data, $action);
+ }
+
+ ##### BEGIN MOODLE ADDITION (Cancel Editing into Button) #####
+ $o .= "\n<br>\n"
+ . '<input type="submit" name="save" value="'. ewiki_t("SAVE") . '">'."\n"
+ . '<input type="submit" name="preview" value="'. ewiki_t("PREVIEW") . '">' . "\n"
+ . '<input type="submit" name="canceledit" value="'. ewiki_t("CANCEL_EDIT") . '">' . "\n";
+# . ' <a href="'. ewiki_script("", $id) . '">' . ewiki_t("CANCEL_EDIT") . '</a>';
+ ##### END MOODLE ADDITION #####
+
+ #-- additional form elements
+ if ($pf_a = $ewiki_plugins["edit_form_append"]) foreach ($pf_a as $pf) {
+ $o .= $pf($id, $data, $action);
+ }
+
+ $o .= "\n</form>\n";
+ // . ewiki_t("EDIT_FORM_2"); // MOODLE DELETION
+
+ return('<div class="edit-box">'. $o .'</div>');
+}
+
+
+
+#-- pic upload form
+function ewiki_page_edit_form_final_imgupload(&$o, &$id, &$data, &$action) {
+ if (EWIKI_SCRIPT_BINARY && EWIKI_UP_UPLOAD && EWIKI_IMAGE_MAXSIZE) {
+ $o .= "\n<br>\n". '<div class="image-upload">'
+ . '<form action='
+ . '"'. ewiki_script_binary("", EWIKI_IDF_INTERNAL, "", "_UPLOAD=1") .'"'
+ . ' method="POST" enctype="multipart/form-data" target="_upload">'
+ . '<input type="file" name="'.EWIKI_UP_UPLOAD.'"'
+ . (defined("EWIKI_IMAGE_ACCEPT") ? ' accept="'.EWIKI_IMAGE_ACCEPT.'">' : "")
+ . '<input type="hidden" name="'.EWIKI_UP_BINARY.'" value="'.EWIKI_IDF_INTERNAL.'">'
+ . ' '
+ . '<input type="submit" value="'.ewiki_t("UPLOAD_PICTURE_BUTTON").'">'
+ . '</form></div>'. "\n";
+ }
+}
+
+
+function ewiki_page_edit_preview(&$data) {
+#### BEGIN MOODLE CHANGES
+ global $moodle_format;
+ $preview_text=$GLOBALS["ewiki_plugins"]["render"][0]($_REQUEST["content"], 1, EWIKI_ALLOW_HTML || (@$data["flags"]&EWIKI_DB_F_HTML));
+ return( '<div class="preview">'
+ . "<hr noshade>"
+ . "<div align=\"right\">" . ewiki_t("PREVIEW") . "</div><hr noshade><br>\n"
+ . format_text($preview_text, $moodle_format)
+ . "<hr noshade><br>"
+ . "</div>"
+ );
+#### END MOODLE CHANGES
+}
+
+
+
+
+
+
+
+function ewiki_control_links($id, &$data, $action) {
+
+ global $ewiki_plugins, $ewiki_ring, $ewiki_config;
+ $action_links = & $ewiki_config["action_links"][$action];
+
+ #-- disabled
+ if (!$ewiki_config["control_line"]) {
+ return("");
+ }
+
+ $o = "\n"
+ . '<div align="right" class="action-links control-links">'
+ . "\n<br>\n"
+ . "<hr noshade>" . "\n";
+
+ if (@$data["forced_version"]) {
+
+ $o .= '<form action="' . ewiki_script("edit", $id) . '" method="POST">' .
+ '<input type="hidden" name="edit" value="old">' .
+ '<input type="hidden" name="version" value="'.$data["forced_version"].'">' .
+ '<input type="submit" value="' . ewiki_t("OLDVERCOMEBACK") . '"></form> ';
+ }
+ else {
+ foreach ($action_links as $action => $title)
+ if (!empty($ewiki_plugins["action"][$action]) || !empty($ewiki_plugins["action_always"][$action]) || strpos($action, ":/"))
+ {
+ if (EWIKI_PROTECTED_MODE && EWIKI_PROTECTED_MODE_HIDING && !ewiki_auth($id, $data, $action)) { continue; }
+
+ $o .= '<a href="'
+ . (strpos($action, ":/") ? $action : ewiki_script($action, $id))
+ . '">' . ewiki_t($title) . '</a> · ';
+ }
+ }
+
+ if ($data["lastmodified"] >= UNIX_MILLENNIUM) {
+ $o .= '<small>' . strftime(ewiki_t("LASTCHANGED"), @$data["lastmodified"]) . '</small>';
+ }
+
+ $o .= "</div>\n";
+
+ return($o);
+}
+
+
+
+
+
+# ============================================================= rendering ===
+
+
+
+
+
+######## ### ### ######### ### ### ### #######
+######## #### ### ######### ### #### ### #######
+### ##### ### ### ##### ### ###
+###### ######### ### #### ### ######### ######
+###### ######### ### #### ### ######### ######
+### ### ##### ### ### ### ### ##### ###
+######## ### #### ######### ### ### #### #######
+######## ### ### ######### ### ### ### #######
+
+
+/*
+ The _format() function transforms $wiki_source pages into <html> strings,
+ also calls various markup and helper plugins during the transformation
+ process. The $params array can activate various features and extensions.
+ only accepts UNIX newlines!
+*/
+function ewiki_format (
+ $wiki_source,
+ $params = array()
+ )
+{
+ global $ewiki_links, $ewiki_plugins, $ewiki_config;
+
+ #-- state vars
+ $params = array_merge($ewiki_config["format_params"], $params);
+ $s = array(
+ "in" => 0, # current input $iii[] block array index
+ "para" => "",
+ "line" => "",
+ "post" => "", # string to append after current line/paragraph
+ "line_i" => 0,
+ "lines" => array(),
+ "list" => "", # lists
+ "tbl" => 0, # open table?
+ "indent" => 0, # indentation
+ "close" => array(),
+ );
+ #-- aliases
+ $in = &$s["in"];
+ $line = &$s["line"];
+ $lines = &$s["lines"];
+ $para = &$s["para"];
+ $post = &$s["post"];
+ $list = &$s["list"];
+
+ #-- input and output arrays
+ if ($wiki_source[0] == "<") { # also prepend an empty line
+ $wiki_source = "\n" . $wiki_source; # for faster strpos() searchs
+ }
+ $iii = array(
+ 0 => array(
+ 0 => $wiki_source."\n", # body + empty line
+ 1 => 0x0FFF, # flags (0x1=WikiMarkup, 0x2=WikiLinks, 0x100=BlockPlugins)
+ 2 => "core", # block plugin name
+ )
+ );
+ $ooo = array(
+ );
+ unset($wiki_source);
+
+ #-- plugins
+ $pf_tbl = @$ewiki_plugins["format_table"][0];
+ $pf_line = @$ewiki_plugins["format_line"];
+
+ #-- wikimarkup (wm)
+ $htmlentities = $ewiki_config["htmlentities"];
+ $wm_indent = &$ewiki_config["wm_indent"];
+ $wm_table_defaults = &$ewiki_config["wm_table_defaults"];
+ $wm_source = &$ewiki_config["wm_source"];
+ $wm_list = &$ewiki_config["wm_list"];
+ $wm_list_chars = implode("", array_keys($wm_list));
+ $wm_style = &$ewiki_config["wm_style"];
+ $wm_start_end = &$ewiki_config["wm_start_end"];
+
+ #-- eleminate html
+ $iii[0][0] = strtr($iii[0][0], $htmlentities);
+ unset($htmlentities["&"]);
+
+ #-- pre-processing plugins (working on wiki source)
+ if ($pf_source = $ewiki_plugins["format_source"]) {
+ foreach ($pf_source as $pf) $pf(&$iii[0][0]);
+ }
+
+ #-- simple markup
+ $iii[0][0] = strtr($iii[0][0], $wm_source);
+
+ #-- separate input into blocks ------------------------------------------
+ foreach ($ewiki_config["format_block"] as $btype => $binfo) {
+
+ #-- disabled block plugin?
+ if ($binfo[2] && !$params[$binfo[2]]) {
+ continue;
+ }
+
+ #-- traverse $iii[]
+ $in = -1;
+ while ((++$in) < count($iii)) {
+
+ #-- search fragment delimeters
+ if ($iii[$in][1] & 0x0100)
+ while (
+ ($c = & $iii[$in][0]) &&
+ (($l = strpos($c, $binfo[0])) !== false) &&
+ ($r = strpos($c, $binfo[1], $l)) )
+ {
+ $l_len = strlen($binfo[0]);
+ $r_len = strlen($binfo[1]);
+
+ $repl = array();
+ // pre-text
+ if (($l > 0) && trim($text = substr($c, 0, $l))) {
+ $repl[] = array($text, 0xFFFF, "core");
+ }
+ // the extracted part
+ if (trim($text = substr($c, $l+$l_len, $r-$l-$r_len))) {
+ $repl[] = array($text, $binfo[3], "$btype");
+ }
+ // rest
+ if (($r+$r_len < strlen($c)) && trim($text = substr($c, $r+$r_len))) {
+ $repl[] = array($text, 0xFFFF, "core");
+ }
+ array_splice($iii, $in, 1, $repl);
+
+ $in += 1;
+ }
+ }
+ }
+
+ #-- run format_block plugins
+ $in = -1;
+ while ((++$in) < count($iii)) {
+ if (($btype = $iii[$in][2]) && ($pf_a = $ewiki_plugins["format_block"][$btype])) {
+ $c = &$iii[$in][0];
+ foreach ($pf_a as $pf) {
+ # current buffer $c and pointer $in into $iii[] and state $s
+ $pf($c, $in, $iii, $s, $btype);
+ }
+ }
+ }
+
+ #-- wiki markup ------------------------------------------------------
+ $para = "";
+ $in = -1;
+ while ((++$in) < count($iii)) {
+ #-- wikimarkup
+ if ($iii[$in][1] & 0x0001) {
+
+ #-- input $lines buffer, and output buffer $ooo array
+ $lines = explode("\n", $iii[$in][0]);
+ $ooo[$in] = array(
+ 0 => "",
+ 1 => $iii[$in][1]
+ );
+ $out = &$ooo[$in][0];
+ $s["block"] = ($iii[$in][2] != "core"); # disables indentation & paragraphs
+
+ #-- walk through wiki source lines
+ $line_max = count($lines);
+ foreach ($lines as $s["line_i"]=>$line) {
+#echo "line={$s[line_i]}:$line\n";
+
+ #-- empty lines separate paragraphs
+ if (!strlen($line)) {
+ ewiki_format_close_para($ooo, $s);
+ ewiki_format_close_tags($ooo, $s);
+ if (!$s["block"]) {
+ $out .= "\n";
+ }
+ }
+ #-- horiz bar
+ if (!strncmp($line, "----", 4)) {
+ $out .= "<hr noshade>\n";
+ continue;
+ }
+ #-- html comment
+ #if (!strncmp($line, "<!--", 7)) {
+ # $out .= "<!-- " . htmlentities(str_replace("--", "__", substr($line, 7))) . " -->\n";
+ # continue;
+ #}
+
+ ($c0 = $line[0])
+ or ($c0 = "\000");
+
+ #-- tables
+ ### MOODLE CHANGE: TRIM
+ if (($c0 == "|") && ($line[strlen(trim($line))-1] == "|")) {
+ if (!$s["tbl"]) {
+ ewiki_format_close_para($ooo, $s);
+ ewiki_format_close_tags($ooo, $s);
+ $s["list"] = "";
+ }
+ $line = substr($line, 1, -1);
+ if ($pf_tbl) {
+ $pf_tbl($line, $ooo, $s);
+ }
+ else {
+ if (!$s["tbl"]) {
+ $out .= "<table " . $wm_table_defaults . ">\n";
+ $s["close"][] = "\n</table>";
+ }
+ $line = "<tr>\n<td>" . str_replace("|", "</td>\n<td>", $line) . "</td>\n</tr>";
+ }
+ $s["tbl"] = 1;
+ $para = false;
+ }
+ elseif ($s["tbl"]) {
+ $s["tbl"] = 0;
+ }
+
+
+ #-- headlines
+ if (($c0 == "!") && ($excl = strspn($line, "!"))) {
+ if ($excl > 3) {
+ $excl = 3;
+ }
+ $line = substr($line, $excl);
+ $excl = 5 - $excl;
+ $line = "<h$excl>" . $line . "</h$excl>";
+ if ($para) {
+ ewiki_format_close_para($ooo, $s);
+ }
+ ewiki_format_close_tags($ooo, $s);
+ $para = false;
+ }
+
+ #-- whole-line markup
+ # ???
+
+
+ #-- indentation (space/tab markup)
+ $n_indent = 0;
+ if (!$list && (!$s["block"]) && ($n_indent = strspn($line, " "))) {
+ $n_indent = (int) ($n_indent / 2.65);
+ while ($n_indent > $s["indent"]) {
+ $out .= $wm_indent;
+ $s["indent"]++;
+ }
+ }
+ while ($n_indent < $s["indent"]) {
+ $out .= "</div>\n";
+ $s["indent"]--;
+ }
+
+
+
+ #-- list markup
+ if (isset($wm_list[$c0])) {
+ if (!$list) {
+ ewiki_format_close_para($ooo, $s);
+ ewiki_format_close_tags($ooo, $s);
+ }
+ $new_len = strspn($line, $wm_list_chars);
+ $new_list = substr($line, 0, $new_len);
+ $old_len = strlen($list);
+ $lchar = $new_list[$new_len-1];
+ list($lopen, $ltag1, $ltag2) = $wm_list[$lchar];
+
+ #-- cut line
+ $line = substr($line, $new_len);
+ $lspace = "";
+ $linsert = "";
+ if ($ltag1) {
+ $linsert = "<$ltag1>" . strtok($line, $lchar) . "</$ltag1> ";
+ $line = strtok("\000");
+ }
+
+ #-- add another <li>st entry
+ if ($new_len == $old_len) {
+ $lspace = str_repeat(" ", $new_len);
+ $out .= "</$ltag2>\n" . $lspace . $linsert . "<$ltag2>";
+ }
+ #-- add list
+ elseif ($new_len > $old_len) {
+ while ($new_len > ($old_len=strlen($list))) {
+ $lchar = $new_list[$old_len];
+ $list .= $lchar;
+ list($lopen, $ltag1, $ltag2) = $wm_list[$lchar];
+ $lclose = strtok($lopen, " ");
+ $lspace = str_repeat(" ", $new_len);
+
+ $out .= "\n$lspace<$lopen>\n" . "$lspace". $linsert . "<$ltag2>";
+ $s["close"][] = "$lspace</$lclose>";
+ $s["close"][] = "$lspace</$ltag2>";
+ }
+ }
+ #-- close lists
+ else {
+ while ($new_len < ($old_len=strlen($list))) {
+ $remove = $old_len-$new_len;
+ ewiki_format_close_tags($ooo, $s, 2*$remove);
+ $list = substr($list, 0, -$remove);
+ }
+ if ($new_len) {
+ $lspace = str_repeat(" ", $new_len);
+ $out .= "$lspace</$ltag2>\n" . $lspace . $linsert . "<$ltag2>";
+ }
+ }
+
+ $list = $new_list;
+ $para = false;
+ }
+ elseif ($list) {
+ if ($c0 == " ") {
+ $para = false;
+ }
+ else {
+ ewiki_format_close_tags($ooo, $s);
+ $list = "";
+ }
+ }
+
+
+ #-- text style triggers
+ foreach ($wm_style as $find=>$replace) {
+ $find_len = strlen($find);
+ $loop = 20;
+ while(($loop--) && (($l = strpos($line, $find)) !== false) && ($r = strpos($line, $find, $l + $find_len))) {
+ $line = substr($line, 0, $l) . $replace[0] .
+ substr($line, $l + strlen($find), $r - $l - $find_len) .
+ $replace[1] . substr($line, $r + $find_len);
+ }
+ }
+
+ #-- start-end markup
+ foreach ($wm_start_end as $d) {
+ $len0 = strlen($d[0]);
+ $loop = 20;
+ while(($loop--) && (($l = strpos($line, $d[0])) !== false) && ($r = strpos($line, $d[1], $l + $len0))) {
+ $len1 = strlen($d[1]);
+ $line = substr($line, 0, $l) . $d[2] .
+ substr($line, $l + $len0, $r - $l - $len0) .
+ $replace[1] . substr($line, $r + $len1);
+ }
+ }
+
+ #-- call wiki source formatting plugins that work on current line
+ if ($pf_line) {
+ foreach ($pf_line as $pf) $pf($out, $line, $post);
+ }
+
+
+
+ #-- add formatted line to page-output
+ $line .= $post;
+ if ($para === false) {
+ $out .= $line;
+ $para = "";
+ }
+ else {
+ $para .= $line . "\n";
+ }
+
+ }
+
+ #-- last block, or next not WikiSource?
+ if (!isset($iii[$in+1]) || !($iii[$in+1][1] & 0x0011)) {
+ ewiki_format_close_para($ooo, $s);
+ ewiki_format_close_tags($ooo, $s);
+ }
+ }
+ #-- copy as is into output buffer
+ else {
+ $ooo[$in] = $iii[$in];
+ }
+ $iii[$in] = array();
+ }
+
+ #-- wiki linking ------------------------------------------------------
+ $scan_src = "";
+ for ($in=0; $in<count($ooo); $in++) {
+ if (EWIKI_HTML_CHARS && ($ooo[$in][1] & 0x0004)) { # html character entities
+ $ooo[$in][0] = str_replace("&#", "&#", $ooo[$in][0]);
+ }
+ if ($ooo[$in][1] & 0x0022) {
+ #-- join together multiple WikiSource blocks
+ while (isset($ooo[$in+1]) && ($ooo[$in][1] & 0x0002) && ($ooo[$in+1][1] & 0x0002)) {
+ $ooo[$in] = array(
+ 0 => $ooo[$in][0] . "\n" . $ooo[$in+1][0],
+ 1 => $ooo[$in][1] | $ooo[$in+1][1],
+ );
+ array_splice($ooo, $in+1, 1);
+ }
+ }
+ $scan_src .= $ooo[$in][0];
+ }
+
+
+ #-- pre-scan
+ if (1+$params["scan_links"]) {
+ ewiki_scan_wikiwords($scan_src, $ewiki_links);
+ }
+ if ($pf_linkprep = $ewiki_plugins["format_prepare_linking"]) {
+ foreach ($pf_linkprep as $pf) $pf($scan_src);
+ }
+ $scan_src = NULL;
+
+ #-- finally the link-detection-regex
+ for ($in=0; $in<count($ooo); $in++) {
+ if ($ooo[$in][1] & 0x0002) {
+ ##### BEGIN MOODLE ADDITION #####
+ # No WikiLinks in Editor
+ #################################
+ global $ewiki_use_editor, $ewiki_editor_content;
+ if(!($ewiki_use_editor && $ewiki_editor_content)) {
+ ##### END MOODLE ADDITION #####
+ ewiki_render_wiki_links($ooo[$in][0]);
+ ##### BEGIN MOODLE ADDITION #####
+ }
+ ##### END MOODLE ADDITION #####
+ }
+ }
+
+ #-- fin: combine all blocks into html string ----------------------------
+ $html = "";
+ for ($in=0; $in<count($ooo); $in++) {
+ $html .= $ooo[$in][0] . "\n";
+ $ooo[$in] = 0;
+ }
+ #-- call post processing plugins
+ if ($pf_final = $ewiki_plugins["format_final"]) {
+ foreach ($pf_final as $pf) $pf($html);
+ }
+ return($html);
+}
+
+
+
+function ewiki_format_close_para(&$ooo, &$s) {
+ $out = &$ooo[$s["in"]][0];
+ #-- output text block
+ if (trim($s["para"])) {
+ if (!$s["block"]) {
+ $s["para"] = "\n<p>\n" . ltrim($s["para"], "\n") . "</p>\n";
+ }
+ #-- paragraph formation plugins
+ if ($pf_a = $GLOBALS["ewiki_plugins"]["format_para"]) {
+ foreach ($pf_a as $pf) {
+ $pf($s["para"], $ooo, $s);
+ }
+ }
+ $out .= $s["para"];
+ $s["para"] = "";
+ }
+ #-- indentation
+ while ($s["indent"]) {
+ $out .= "</div>";
+ $s["indent"]--;
+ }
+}
+
+
+function ewiki_format_close_tags(&$ooo, &$s, $count=100) {
+ $out = &$ooo[$s["in"]][0];
+ if (!is_array($s) || !is_array($s["close"])) {
+ die("\$s is garbaged == $s!!");
+ }
+ while (($count--) && ($add = array_pop($s["close"]))) {
+ $out .= $add . "\n";
+ }
+}
+
+
+function ewiki_format_pre(&$str, &$in, &$iii, &$s, $btype) {
+ $str = "<pre class=\"markup $btype\">" . $str . "</pre>";
+}
+
+
+function ewiki_format_html(&$str, &$in, &$iii, &$s) {
+ $he = array_reverse($GLOBALS["ewiki_config"]["htmlentities"]);
+ $str = strtr($str, array_flip($he));
+ $str = "<span class=\"markup html\">" . $str . "\n</span>\n";
+}
+
+
+function ewiki_format_comment(&$str, &$in, &$iii, &$s, $btype) {
+ $str = "<!-- " . str_replace("--", "¯¯", $str) . " -->";
+}
+
+
+
+
+/* unclean pre-scanning for WikiWords in a page,
+ pre-query to the db */
+function ewiki_scan_wikiwords(&$wiki_source, &$ewiki_links, $se=0) {
+
+ global $ewiki_config;
+
+ #-- find matches
+ preg_match_all($ewiki_config["wiki_pre_scan_regex"], $wiki_source, $uu);
+ $uu = array_merge($uu[1], $uu[2], $uu[3], $uu[4], (array)@$uu[5]);
+
+ #-- clean up list, trim() spaces (allows more unclean regex) - page id unification
+ foreach ($uu as $i=>$id) {
+ $uu[$i] = trim($id);
+ }
+ unset($uu[""]);
+ $uu = array_unique($uu);
+
+ #-- query db
+ $ewiki_links = ewiki_database("FIND", $uu);
+
+ #-- strip email adresses
+ if ($se) {
+ foreach ($ewiki_links as $c=>$uu) {
+ if (strpos($c, "@") && (strpos($c, ".") || strpos($c, ":"))) {
+ unset($ewiki_links[$c]);
+ }
+ }
+ }
+
+}
+
+
+
+/* regex on page content,
+ handled by callback (see below)
+*/
+function ewiki_render_wiki_links(&$o) {
+
+ global $ewiki_links, $ewiki_config, $ewiki_plugins;
+
+ #-- merge with dynamic pages list
+ ewiki_merge_links($ewiki_links);
+
+ #-- replace WikiWords
+ $link_regex = &$ewiki_config["wiki_link_regex"];
+ $o = preg_replace_callback($link_regex, "ewiki_link_regex_callback", $o);
+
+ #-- cleanup
+ unset($ewiki_links);
+}
+
+
+/*
+ combines with page plugin list,
+ and makes all case-insensitive
+*/
+function ewiki_merge_links(&$ewiki_links) {
+ global $ewiki_plugins;
+ if ($ewiki_links !== true) {
+ foreach ($ewiki_plugins["page"] as $page=>$uu) {
+ $ewiki_links[$page] = 1;
+ }
+ $ewiki_links = ewiki_array($ewiki_links);
+ }
+}
+
+
+
+
+/* link rendering (p)regex callback
+ (ooutch, this is a complicated one)
+*/
+function ewiki_link_regex_callback($uu, $force_noimg=0) {
+ #print "<pre>"; print_r($uu); print "</pre>";
+ global $ewiki_links, $ewiki_plugins, $ewiki_config, $ewiki_id;
+
+ $str = trim($uu[0]);
+ $type = array();
+ $states = array();
+
+ #-- link bracket '[' escaped with '!' or '~'
+ if (($str[0] == "!") || ($str[0] == "~")) {
+ return(substr($str, 1));
+ }
+ if ($str[0] == "#") {
+ $states["define"] = 1;
+ $str = substr($str, 1);
+ }
+ if ($str[0] == "[") {
+ $states["brackets"] = 1;
+ $str = substr($str, 1, -1);
+ }
+
+ #-- explicit title given via [ title | WikiLink ]
+ $href = $title = strtok($str, "|");
+ if ($uu = strtok("|")) {
+ $href = $uu;
+ $states["titled"] = 1;
+ }
+ #-- title and href swapped: swap back
+ if (strpos("://", $title) || strpos($title, ":") && !strpos($href, ":")) {
+ $uu = $title; $title = $href; $href = $uu;
+ }
+ #-- new entitling scheme [ url "title" ]
+ if ((($l=strpos($str, '"')) < ($r=strrpos($str, '"'))) && ($l!==false) ) {
+ $title = substr($str, $l + 1, $r - $l - 1);
+ $href = substr($str, 0, $l) . substr($str, $r + 1);
+ $states["titled"] = 1;
+ }
+
+ #-- strip spaces
+ $spaces_l = ($href[0]==" ") ?1:0;
+ $spaces_r = ($href[strlen($href)-1]==" ") ?1:0;
+ $title = ltrim(trim($title), "^");
+ $href = ltrim(trim($href), "^");
+
+ #-- strip_htmlentities()
+ if (1&& (strpos($href, "&")!==false) && strpos($href, ";")) {
+ foreach (array("<"=>"<", ">"=>">", "&"=>"&") as $f=>$t) {
+ $href = str_replace($f, $t, $href);
+ }
+ }
+
+ #-- anchors
+ $href2 = "";
+ if (($p = strrpos($href, "#")) && ($p) && ($href[$p-1] != "&")) {
+ $href2 = trim(substr($href, $p));
+ $href = trim(substr($href, 0, $p));
+ }
+ elseif ($p === 0) {
+ $states["define"] = 1;
+ }
+ if ($href == ".") {
+ $href = $ewiki_id;
+ }
+
+
+ #-- for case-insensitivines
+ $href_i = EWIKI_CASE_INSENSITIVE ? strtolower($href) : ($href);
+
+ #-- injected URLs
+ if (strpos($inj_url = $ewiki_links[$href_i], "://")) {
+ if ($href==$title) { $href = $inj_url; }
+ }
+
+ #-- interwiki links
+ if (strpos($href, ":") && ($uu = ewiki_interwiki($href, $type))) {
+ $href = $uu;
+ $str = "<a href=\"$href$href2\">$title</a>";
+ }
+ #-- action:WikiLinks
+ elseif ($ewiki_plugins["action"][$a=strtolower(strtok($href, ":"))]) {
+ $type = array($a, "action", "wikipage");
+ $str = '<a href="' . ewiki_script($a, strtok("\000")) . '">' . $title . '</a>';
+ }
+ #-- page anchor definitions, if ($href[0]=="#")
+ elseif (@$states["define"]) {
+ $type = array("anchor");
+ if ($title==$href) { $title=" "; }
+ $str = '<a name="' . htmlentities(ltrim($href, "#")) . '">' . ltrim($title, "#") . '</a>';
+ }
+ #-- inner page anchor jumps
+ elseif (strlen($href2) && ($href==$ewiki_id) || ($href[0]=="#") && ($href2=&$href)) {
+ $type = array("jump");
+ $str = '<a href="' . htmlentities($href2) . '">' . $title . '</a>';
+ }
+ #-- ordinary internal WikiLinks
+ elseif (($ewiki_links === true) || @$ewiki_links[$href_i]) {
+ $type = array("wikipage");
+ $str = '<a href="' . ewiki_script("", $href) . htmlentities($href2)
+ . '">' . $title . '</a>';
+ }
+ #-- guess for mail@addresses, convert to URI if
+ elseif (strpos($href, "@") && !strpos($href, ":")) {
+ $type = array("email");
+ $href = "mailto:" . $href;
+ }
+ #-- not found fallback
+ else {
+ $str = "";
+ #-- a plugin may take care
+ if ($pf_a = $ewiki_plugins["link_notfound"]) {
+ foreach ($pf_a as $pf) {
+ if ($str = $pf($title, $href, $href2, $type)) {
+ break;
+ } }
+ }
+
+ #-- (QuestionMarkLink to edit/ action)
+ if (!$str) {
+ $type = array("notfound");
+ $str = '<span class="NotFound"><b>' . $title . '</b><a href="' .
+ ewiki_script("", $href) . '">?</a></span>';
+ }
+ }
+
+ #-- convert standard URLs
+ foreach ($ewiki_config["idf"]["url"] as $find)
+ if (strpos($href, $find)===0) {
+ $type[-2] = "url";
+ $type[-1] = strtok($find, ":");
+
+ #-- URL plugins
+ if ($pf_a = $ewiki_plugins["link_url"]) foreach ($pf_a as $pf) {
+ if ($str = $pf($href, $title)) { break 2; }
+ }
+ $meta = @$ewiki_links[$href];
+
+ #-- check for image files
+ $ext = substr($href, strrpos($href,"."));
+ $nocache = strpos($ext, "no");
+ $ext = strtok($ext, "?&#");
+ $obj = in_array($ext, $ewiki_config["idf"]["obj"]);
+ $img = $obj || in_array($ext, $ewiki_config["idf"]["img"]);
+
+ #-- internal:// references (binary files)
+ if (EWIKI_SCRIPT_BINARY && ((strpos($href, EWIKI_IDF_INTERNAL)===0) ||
+ EWIKI_IMAGE_MAXSIZE && EWIKI_CACHE_IMAGES && $img && !$nocache) )
+ {
+ $type = array("binary");
+ $href = ewiki_script_binary("", $href);
+ }
+
+ #-- output html reference
+ if (!$img || $force_noimg || !$states["brackets"] || (strpos($href, EWIKI_IDF_INTERNAL) === 0)) {
+ $str = '<a href="' . $href . '">' . $title . '</a>';
+ }
+ #-- img tag
+ else {
+ if (is_string($meta)) {
+ $meta = unserialize($meta);
+ }
+ $type = array("image");
+ #-- uploaded images size
+ $x = $meta["width"];
+ $y = $meta["height"];
+ if ($p = strpos('?', $href)) { #-- width/height given in url
+ parse_str(str_replace("&", "&", substr($href, $p)), $meta);
+ ($uu = $meta["x"] . $meta["width"]) and ($x = $uu);
+ ($uu = $meta["y"] . $meta["height"]) and ($y = $uu);
+ if ($scale = $meta["r"] . $meta["scale"]) {
+ ($p = strpos($scale, "%")) and ($scale = strpos($scale, 0, $p) / 100);
+ $x *= $scale; $y *= $scale;
+ }
+ }
+ $align = array('', ' align="right"', ' align="left"', ' align="center"');
+ $align = $align[$spaces_l + 2*$spaces_r];
+ $str = ($obj ? '<embed width="70%"' : '<img') . ' src="' . $href . '"' .
+ ' alt="' . ($title) . '"' .
+ (@$states["titled"] ? ' title="' . ($title) . '"' : '').
+ ($x && $y ? " width=\"$x\" height=\"$y\"" : "") .
+ $align . ">" . ($obj ? "</embed>" : "");
+ # htmlentities($title)
+ }
+
+ break;
+ }
+
+ #-- icon/transform plugins
+ ksort($type);
+ if ($pf_a = @$ewiki_plugins["link_final"]) {
+ foreach ($pf_a as $pf) { $pf($str, $type, $href, $title); }
+ }
+
+ return($str);
+}
+
+
+/*
+ Returns URL if it encounters an InterWiki:Link or workalike.
+*/
+function ewiki_interwiki($href, &$type) {
+ global $ewiki_config, $ewiki_plugins;
+
+ if (strpos($href, ":") and !strpos($href, "//")
+ and ($p1 = strtok($href, ":"))) {
+
+ $page = strtok("\000");
+
+ if (($p1 = ewiki_array($ewiki_config["interwiki"], $p1)) !== NULL) {
+ $type = array("interwiki", $uu);
+ while ($p1_alias = $ewiki_config["interwiki"][$p1]) {
+ $type[] = $p1;
+ $p1 = $p1_alias;
+ }
+ if (!strpos($p1, "%s")) {
+ $p1 .= "%s";
+ }
+ $href = str_replace("%s", $page, $p1);
+ return($href);
+ }
+ elseif ($pf = $ewiki_plugins["intermap"][$p1]) {
+ return($pf($p1, $page));
+ }
+ }
+}
+
+
+/*
+ implements FeatureWiki:InterMapWalking
+*/
+function ewiki_intermap_walking($id, &$data, $action) {
+ if (empty($data["version"]) && ($href = ewiki_interwiki($id, $uu))) {
+ header("Location: $href");
+ return("<a href=\"$href\">$href</a>");
+ }
+}
+
+
+
+# =========================================================================
+
+
+
+##### ## ## ## ## ##### ## ##
+###### ## ### ## #### ###### ## ##
+## ## ## ### ## ###### ## ## ## ##
+##### ## #### ## ## ## ###### ######
+##### ## ####### ###### #### ####
+## ### ## ## #### ###### ##### ##
+## ### ## ## ### ## ## ## ### ##
+###### ## ## ### ## ## ## ## ##
+###### ## ## ## ## ## ## ## ##
+
+
+
+
+/* fetch & store
+*/
+function ewiki_binary($break=0) {
+ global $ewiki_plugins;
+
+ #-- reject calls
+ if (!strlen($id = @$_REQUEST[EWIKI_UP_BINARY]) || !EWIKI_IDF_INTERNAL) {
+ return(false);
+ }
+ if (headers_sent()) die("ewiki-binary configuration error");
+
+ #-- upload requests
+ $upload_file = @$_FILES[EWIKI_UP_UPLOAD];
+ $add_meta = array();
+ if ($orig_name = @$upload_file["name"]) {
+ $add_meta["Content-Location"] = urlencode($orig_name);
+ $add_meta["Content-Disposition"] = 'inline; filename="'.urlencode(basename("remote://$orig_name")).'"';
+ }
+
+ #-- what are we doing here?
+ if (($id == EWIKI_IDF_INTERNAL) && ($upload_file)) {
+ $do = "upload";
+ }
+ else {
+ $data = ewiki_database("GET", array("id" => $id));
+ $flags = @$data["flags"];
+ if (EWIKI_DB_F_BINARY == ($flags & EWIKI_DB_F_TYPE)) {
+ $do = "get";
+ }
+ elseif (empty($data["version"]) and EWIKI_CACHE_IMAGES) {
+ $do = "cache";
+ }
+ else {
+ $do = "nop";
+ }
+ }
+
+
+ #-- auth only happens when enforced with _PROTECTED_MODE_XXL setting
+ # (authentication for inline images in violation of the WWW spirit)
+ if ((EWIKI_PROTECTED_MODE>=5) && !ewiki_auth($id, $data, "binary-{$do}")) {
+ return($_REQUEST["id"]="view/BinaryPermissionError");
+ }
+
+ #-- upload an image
+ if ($do == "upload"){
+
+ $id = ewiki_binary_save_image($upload_file["tmp_name"], "", $return=0, $add_meta);
+ @unlink($upload_file["tmp_name"]);
+ ($title = trim($orig_name, "/")) && ($title = preg_replace("/[^-._\w\d]+/", "_", substr(substr($orig_name, strrpos($title, "/")), 0, 20)))
+ && ($title = '"'.$title.'"') || ($title="");
+
+ if ($id) {
+ echo<<<EOF
+<html><head><title>File/Picture Upload</title><script language="JavaScript" type="text/javascript"><!--
+ opener.document.forms["ewiki"].elements["content"].value += "\\nUPLOADED PICTURE: [$id$title]\\n";
+ window.setTimeout("self.close()", 5000);
+//--></script></head><body bgcolor="#440707" text="#FFFFFF">Your uploaded file was saved as<br><big><b>
+[$id]
+</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>
+EOF;
+ }
+ }
+
+ #-- request for contents from the db
+ elseif ($do == "get") {
+#### CHANGED FOR MOODLE
+ if (EWIKI_HIT_COUNTING) {
+ $tmp["id"]=$id;
+ ewiki_database("HIT", $tmp);
+ }
+#### CHANGED FOR MOODLE
+
+ #-- send http_headers from meta
+ if (is_array($data["meta"])) {
+ foreach ($data["meta"] as $hdr=>$val) {
+ if (($hdr[0] >= "A") && ($hdr[0] <= "Z")) {
+ header("$hdr: $val");
+ }
+ }
+ }
+
+ #-- fetch from binary store
+ if ($pf_a = $ewiki_plugins["binary_get"]) {
+#### CHANGED FOR MOODLE
+ foreach ($pf_a as $pf) { $pf($id, $data["meta"]); }
+
+#### END CHANGED FOR MOODLE
+ }
+
+ #-- else fpassthru
+ echo $data["content"];
+ }
+
+ #-- fetch & cache requested URL,
+ elseif ($do == "cache") {
+
+ #-- check for standard protocol names, to prevent us from serving
+ # evil requests for '/etc/passwd.jpeg' or '../.htaccess.gif'
+ if (preg_match('@^\w?(http|ftp|https|ftps|sftp)\w?://@', $id)) {
+
+ #-- generate local copy
+ $filename = tempnam(EWIKI_TMP, "ewiki.local.temp.");
+ if (($i = fopen($id, "rb")) && ($o = fopen($filename, "wb"))) {
+
+ while (!feof($i)) {
+ fwrite($o, fread($i, 65536));
+ }
+
+ fclose($i);
+ fclose($o);
+
+ $add_meta = array(
+ "Content-Location" => urlencode($id),
+ "Content-Disposition" => 'inline; filename="'.urlencode(basename($id)).'"'
+ );
+
+ $result = ewiki_binary_save_image($filename, $id, "RETURN", $add_meta);
+ }
+ }
+
+ #-- deliver
+ if ($result && !$break) {
+ ewiki_binary($break=1);
+ }
+ #-- mark URL as unavailable
+ else {
+ $data = array(
+ "id" => $id,
+ "version" => 1,
+ "flags" => EWIKI_DB_F_DISABLED,
+ "lastmodified" => time(),
+ "created" => time(),
+ "author" => ewiki_author("ewiki_binary_cache"),
+ "content" => "",
+ "meta" => array("Status"=>"404 Absent"),
+ );
+ ewiki_database("WRITE", $data);
+ header("Location: $id");
+ ewiki_log("imgcache: did not find '$id', and marked it now in database as DISABLED", 2);
+ }
+
+ }
+
+ #-- "we don't sell this!"
+ else {
+ if (strpos($id, EWIKI_IDF_INTERNAL) === false) {
+ header("Status: 301 Located SomeWhere Else");
+ header("Location: $id");
+ }
+ else {
+ header("Status: 404 Absent");
+ header("X-Broken-URI: $id");
+ }
+ }
+
+ // you should not remove this one, it is really a good idea to use it!
+ die();
+}
+
+
+
+
+
+
+function ewiki_binary_save_image($filename, $id="", $return=0,
+$add_meta=array(), $accept_all=EWIKI_ACCEPT_BINARY, $care_for_images=1)
+{
+ global $ewiki_plugins;
+
+ #-- break on empty files
+ if (!filesize($filename)) {
+ return(false);
+ }
+
+ #-- check for image type and size
+ $mime_types = array(
+ "application/octet-stream",
+ "image/gif",
+ "image/jpeg",
+ "image/png",
+ "application/x-shockwave-flash"
+ );
+ $ext_types = array(
+ "bin", "gif", "jpeg", "png", "swf"
+ );
+ list($width, $height, $mime_i, $uu) = getimagesize($filename);
+ (!$mime_i) && ($mime_i=0) || ($mime = $mime_types[$mime_i]);
+
+ #-- images expected
+ if ($care_for_images) {
+
+ #-- mime type
+ if (!$mime_i && !$accept_all || !filesize($filename)) {
+ ewiki_die(ewiki_t("BIN_NOIMG"), $return);
+ return;
+ }
+
+ #-- resize image
+ if (strpos($mime,"image/")!==false) {
+ if ($pf_a = $ewiki_plugins["image_resize"]) {
+ foreach ($pf_a as $pf) {
+ if (EWIKI_IMAGE_RESIZE && (filesize($filename) > EWIKI_IMAGE_MAXSIZE)) {
+ $pf($filename, $mime, $return);
+ clearstatcache();
+ }}}}
+
+ #-- reject image if too large
+ if (strlen($content) > EWIKI_IMAGE_MAXSIZE) {
+ ewiki_die(ewiki_t("BIN_IMGTOOLARGE"), $return);
+ return;
+ }
+
+ #-- again check mime type and image sizes
+ list($width, $height, $mime_i, $uu) = getimagesize($filename);
+ (!$mime_i) && ($mime_i=0) || ($mime = $mime_types[$mime_i]);
+
+ }
+ ($ext = $ext_types[$mime_i]) or ($ext = $ext_types[0]);
+
+ #-- binary files
+ if ((!$mime_i) && ($pf = $ewiki_plugins["mime_magic"][0])) {
+ if ($tmp = $pf($content)) {
+ $mime = $tmp;
+ }
+ }
+ if (!strlen($mime)) {
+ $mime = $mime_types[0];
+ }
+
+ #-- store size of binary file
+ $add_meta["size"] = filesize($filename);
+ $content = "";
+
+ #-- handler for (large/) binary content?
+ if ($pf_a = $ewiki_plugins["binary_store"]) {
+ foreach ($pf_a as $pf) {
+ $pf($filename, $id, $add_meta, $ext);
+ }
+ }
+
+ #-- read file into memory (2MB), to store it into the database
+ if ($filename) {
+ $f = fopen($filename, "rb");
+ $content = fread($f, 1<<21);
+ fclose($f);
+ }
+
+ #-- generate db file name
+ if (empty($id)) {
+ $md5sum = md5($content);
+ $id = EWIKI_IDF_INTERNAL . $md5sum . ".$ext";
+ ewiki_log("generated md5sum '$md5sum' from file content");
+ }
+
+ #-- prepare meta data
+ $meta = @array_merge(array(
+ "class" => $mime_i ? "image" : "file",
+ "Content-Type" => $mime,
+ "Pragma" => "cache",
+ ), $add_meta);
+ if ($mime_i) {
+ $meta["width"] = $width;
+ $meta["height"] = $height;
+ }
+
+ #-- database entry
+ $data = array(
+ "id" => $id,
+ "version" => "1",
+ "author" => ewiki_author(),
+ "flags" => EWIKI_DB_F_BINARY | EWIKI_DB_F_READONLY,
+ "created" => time(),
+ "lastmodified" => time(),
+ "meta" => &$meta,
+ "content" => &$content,
+ );
+
+ #-- write if not exist
+ $exists = ewiki_database("FIND", array($id));
+ if (! $exists[$id] ) {
+ $result = ewiki_database("WRITE", $data);
+ ewiki_log("saving of '$id': " . ($result ? "ok" : "error"));
+ }
+ else {
+ ewiki_log("binary_save_image: '$id' was already in the database", 2);
+ }
+
+ return($id);
+}
+
+
+
+
+# =========================================================================
+
+
+#### #### #### ######## ########
+##### ##### #### ########## ##########
+###### ###### #### #### ### #### ###
+############# #### ####
+############# #### ######## ####
+#### ### #### #### ######## ####
+#### # #### #### #### ####
+#### #### #### ### #### #### ###
+#### #### #### ######### ##########
+#### #### #### ####### ########
+
+
+
+/* yes! it is not neccessary to annoy users with country flags, if the
+ http already provides means to determine preferred languages!
+*/
+function ewiki_localization() {
+
+ global $ewiki_t, $ewiki_plugins;
+
+ $deflangs = ','.@$_ENV["LANGUAGE"] . ','.@$_ENV["LANG"]
+ . ",".EWIKI_DEFAULT_LANG . ",en,C";
+
+ foreach (explode(",", @$_SERVER["HTTP_ACCEPT_LANGUAGE"].$deflangs) as $l) {
+
+ $l = strtok($l, ";");
+ $l = strtok($l, "-"); $l = strtok($l, "_"); $l = strtok($l, ".");
+ $l = trim($l);
+
+ $ewiki_t["languages"][] = strtolower($l);
+ }
+}
+
+
+
+
+/* poor mans gettext, $repl is an array of string replacements to get
+ applied to the fetched text chunk,
+ "$const" is either an entry from $ewiki_t[] or a larger text block
+ containing _{text} replacement braces of the form "_{...}"
+*/
+function ewiki_t($const, $repl=array(), $pref_langs=array()) {
+ ##### BEGIN MOODLE ADDITION #####
+ $replacechars=array("." => "",
+ "," => "",
+ "!" => "",
+ ";" => "",
+ ":" => "",
+ "'" => "",
+ '"' => "",
+ "-" => "",
+ "_" => "",
+ " " => "",
+ "+" => "");
+
+ $translation=get_string(strtolower(strtr($const,$replacechars)),"wiki",$repl);
+ return $translation;
+ ##### END MOODLE ADDITION #####
+
+/* global $ewiki_t;
+
+ #-- use default language wishes
+ if (empty($pref_langs)) {
+ $pref_langs = $ewiki_t["languages"];
+ }
+
+ #-- large text snippet replaceing
+ if (strpos($const, "_{") !== false) {
+ while ( (($l=strpos($const,"_{")) || ($l===0)) && ($r=strpos($const,"}",$l)) ) {
+ $const = substr($const, 0, $l)
+ . ewiki_t(substr($const, $l+2, $r-$l-2))
+ . substr($const,$r+1);
+ }
+ }
+
+ #-- just one string
+ else foreach ($pref_langs as $l) {
+
+ if (is_string($r = @$ewiki_t[$l][$const]) || ($r = @$ewiki_t[$l][strtoupper($const)])) {
+
+ foreach ($repl as $key=>$value) {
+ if ($key[0] != '$') {
+ $key = '$'.$key;
+ }
+ $r = str_replace($key, $value, $r);
+ }
+ return($r);
+
+ }
+ }
+
+ return($const);*/
+}
+
+
+
+
+
+
+function ewiki_log($msg, $error_type=3) {
+
+ if ((EWIKI_LOGLEVEL >= 0) && ($error_type <= EWIKI_LOGLEVEL)) {
+
+ $msg = time() . " - " .
+ $_SERVER["REMOTE_ADDR"] . ":" . $_SERVER["REMOTE_PORT"] . " - " .
+ $_SERVER["REQUEST_METHOD"] . " " . $_SERVER["REQUEST_URI"] . " - " .
+ strtr($msg, "\n\r\000\377\t\f", "\r\r\r\r\t\f") . "\n";
+ error_log($msg, 3, EWIKI_LOGFILE);
+ }
+}
+
+
+
+
+function ewiki_die($msg, $return=0) {
+ ewiki_log($msg, 1);
+ if ($return) {
+ return($GLOBALS["ewiki_error"] = $msg);
+ }
+ else {
+ die($msg);
+ }
+}
+
+
+
+function ewiki_array_hash(&$a) {
+ return(count($a) . ":" . implode(":", array_keys(array_slice($a, 0, 3))));
+}
+
+
+
+/* provides an case-insensitive in_array replacement to search a page name
+ in a list of others;
+ the supplied $array WILL be lowercased afterwards, unless $dn was set
+*/
+function ewiki_in_array($value, &$array, $dn=0, $ci=EWIKI_CASE_INSENSITIVE) {
+
+ static $as = array();
+
+ #-- work around pass-by-reference
+ if ($dn && $ci) { $dest = array(); }
+ else { $dest = &$array; }
+
+ #-- make everything lowercase
+ if ($ci) {
+ $value = strtolower($value);
+ if (empty($as[ewiki_array_hash($array)])) { // prevent working on the
+ foreach ($array as $i=>$v) { // same array multiple times
+ $dest[$i] = strtolower($v);
+ }
+ $as[ewiki_array_hash($dest)] = 1;
+ }
+ }
+
+ #-- search in values
+ return(in_array($value, $dest));
+}
+
+
+
+/* case-insensitively retrieves an entry from an $array,
+ or returns the given $array lowercased if $key was obmitted
+*/
+function ewiki_array($array, $key=false, $am=1, $ci=EWIKI_CASE_INSENSITIVE) {
+
+ #-- make everything lowercase
+ if ($ci) {
+ $key = strtolower($key);
+
+ $r = array();
+ foreach ($array as $i=>$v) {
+ $i = strtolower($i);
+ if (!$am || empty($r[$i])) {
+ $r[$i] = $v;
+ }
+ else {
+ $r[$i] .= $v; //RET: doubling for images`meta won't happen
+ } // but should be "+" here for integers
+ }
+ $array = &$r;
+ }
+
+ #-- search in values
+ if ($key) {
+ return(@$array[$key]);
+ }
+ else {
+ return($array);
+ }
+}
+
+
+
+
+
+
+function ewiki_author($defstr="") {
+
+ $author = @$GLOBALS["ewiki_author"];
+ ($ip = &$_SERVER["REMOTE_ADDR"]) or ($ip = "127.0.0.0");
+ ($port = $_SERVER["REMOTE_PORT"]) or ($port = "null");
+ $hostname = gethostbyaddr($ip);
+ $remote = (($ip != $hostname) ? $hostname . " " : "")
+ . $ip . ":" . $port;
+
+ (empty($author)) && (
+ ($author = $defstr) ||
+ ($author = $_SERVER["HTTP_FROM"]) || // RFC2068 sect 14.22
+ ($author = $_SERVER["PHP_AUTH_USER"])
+ );
+
+ (empty($author))
+ && ($author = $remote)
+ || ($author = addslashes($author) . " (" . $remote . ")" );
+
+ return($author);
+}
+
+
+
+
+
+/* Returns a value of (true) if the currently logged in user (this must
+ be handled by one of the plugin backends) is authenticated to do the
+ current $action, or to view the current $id page.
+ - alternatively just checks current authentication $ring permission level
+ - errors are returned via the global $ewiki_errmsg
+*/
+function ewiki_auth($id, &$data, $action, $ring=false, $request_auth=0) {
+
+ global $ewiki_plugins, $ewiki_ring, $ewiki_author, $ewiki_errmsg;
+ $ok = true;
+ $ewiki_errmsg="";
+
+#echo "_a($id,dat,$action,$ring,$request_auth)<br>\n";
+
+ if (EWIKI_PROTECTED_MODE) {
+
+ #-- set required vars
+ if (!isset($ewiki_ring)) {
+ $ewiki_ring = (int)EWIKI_AUTH_DEFAULT_RING;
+ }
+ if ($ring===false) {
+ $ring = NULL;
+ }
+
+ #-- plugins to call
+ $pf_login = @$ewiki_plugins["auth_query"][0];
+ $pf_perm = $ewiki_plugins["auth_perm"][0];
+
+ #-- nobody is currently logged in, so try to fetch username,
+ # the login <form> is not yet enforced
+ if ($pf_login && empty($ewiki_auth_user)) {
+ $pf_login($data, 0);
+ }
+
+ #-- check permission for current request (page/action/ring)
+ if ($pf_perm) {
+
+ #-- via _auth handler
+ $ok = $pf_perm($id, $data, $action, $ring, $request_auth);
+
+ #-- if it failed, we really depend on the login <form>,
+ # and then recall the _perm plugin
+ if ($pf_login && (($request_auth >= 2) || !$ok && $request_auth && (empty($ewiki_auth_user) || EWIKI_AUTO_LOGIN) && empty($ewiki_errmsg))) {
+//@FIXME: complicated if() - strip empty(errmsg) ??
+ $pf_login($data, $request_auth);
+ $ok = $pf_perm($id, $data, $action, $ring, $request_auth=0);
+ }
+ }
+ else {
+ $ok = !isset($ring) || isset($ring) && ($ewiki_ring <= $ring);
+ }
+
+ #-- return error string
+ if (!$ok && empty($ewiki_errmsg)) {
+ $ewiki_errmsg = ewiki_t("FORBIDDEN");
+ }
+ }
+
+ return($ok);
+}
+
+
+/*
+ Queries all registered ["auth_userdb"] plugins for the given
+ username, and compares password to against "db" value, sets
+ $ewiki_ring and returns(true) if valid.
+*/
+function ewiki_auth_user($username, $password) {
+ global $ewiki_ring, $ewiki_errmsg, $ewiki_auth_user, $ewiki_plugins, $ewiki_author;
+
+ if (empty($username)) {
+ return(false);
+ }
+ if (($password[0] == "$") || (strlen($password) > 12)) {
+ ewiki_log("_auth_userdb: password was transmitted in encoded form, or is just too long (login attemp for user '$username')", 2);
+ return(false);
+ }
+
+ if ($pf_u = $ewiki_plugins["auth_userdb"])
+ foreach ($pf_u as $pf) {
+
+ if (function_exists($pf) && ($entry = $pf($username, $password))) {
+
+ #-- get and compare password
+ if ($entry = (array) $entry) {
+ $enc_pw = $entry[0];
+ }
+ $success = false
+ || ($enc_pw == substr($password, 0, 12))
+ || ($enc_pw == md5($password))
+ || ($enc_pw == crypt($password, substr($enc_pw, 0, 2)))
+ || function_exists("sha1") && ($enc_pw == sha1($password));
+ $success &= $enc_pw != "*";
+
+ #-- return if it matches
+ if ($success) {
+ if (isset($entry[1])) {
+ $ewiki_ring = (int)($entry[1]);
+ } else {
+ $ewiki_ring = 2; //(EWIKI_AUTH_DEFAULT_RING - 1);
+ }
+ if (empty($ewiki_author)) {
+ ($ewiki_author = $entry[2]) or
+ ($ewiki_author = $username);
+ }
+ return($success && ($ewiki_auth_user=$username));
+ }
+ }
+ }
+
+ if ($username || $password) {
+ ewiki_log("_auth_userdb: wrong password supplied for user '$username', not verified against any userdb", 3);
+ $ewiki_errmsg = "wrong username and/or password";
+# ewiki_auth($uu, $uu, $uu, $uu, 2);
+ }
+ return(false);
+}
+
+
+
+
+
+/* reads all files from "./init-pages/" into the database,
+ when ewiki is run for the very first time and the FrontPage
+ does not yet exist in the database
+*/
+function ewiki_eventually_initialize(&$id, &$data, &$action) {
+
+ #-- initialize database only if frontpage missing
+ if (($id==EWIKI_PAGE_INDEX) && ($action=="edit") && empty($data["version"])) {
+
+ ewiki_database("INIT", array());
+#### BEGIN MOODLE CHANGE
+ $path=EWIKI_INIT_PAGES;
+ if (!empty($path)) {
+ if ($dh = @opendir($path=EWIKI_INIT_PAGES)) {
+ while ($filename = readdir($dh)) {
+ if (preg_match('/^(['.EWIKI_CHARS_U.']+['.EWIKI_CHARS_L.']+\w*)+/', $filename)) {
+ $found = ewiki_database("FIND", array($filename));
+ if (! $found[$filename]) {
+ $content = implode("", file("$path/$filename"));
+ ewiki_scan_wikiwords($content, $ewiki_links, "_STRIP_EMAIL=1");
+ $refs = "\n\n" . implode("\n", array_keys($ewiki_links)) . "\n\n";
+ $save = array(
+ "id" => "$filename",
+ "version" => "1",
+ "flags" => "1",
+ "content" => $content,
+ "author" => ewiki_author("ewiki_initialize"),
+ "refs" => $refs,
+ "lastmodified" => filemtime("$path/$filename"),
+ "created" => filectime("$path/$filename") // (not exact)
+ );
+ ewiki_database("WRITE", $save);
+ }
+ }
+ }
+ closedir($dh);
+ }
+ else {
+ echo "<b>ewiki error</b>: could not read from directory ". realpath($path) ."<br>\n";
+ }
+ }
+#### END MOODLE CHANGE
+
+ #-- try to view/ that newly inserted page
+ if ($data = ewiki_database("GET", array("id"=>$id))) {
+ $action = "view";
+ }
+ }
+}
+
+
+
+
+#---------------------------------------------------------------------------
+
+
+
+######## ### ######## ### ######## ### ###### ########
+######## ### ######## ### ######## ### ###### ########
+## ## ## ## ## ## ## ## ## ## ## ## ## ##
+## ## ## ## ## ## ## ## ## ## ## ## ## ##
+## ## ## ## ## ## ## ## ## ## ## ## ##
+## ## ## ## ## ## ## ## ## ## ## ## ##
+## ## ## ## ## ## ## ######## ## ## ###### ######
+## ## ## ## ## ## ## ######## ## ## ###### ######
+## ## ######### ## ######### ## ## ######### ## ##
+## ## ######### ## ######### ## ## ######### ## ##
+## ## ## ## ## ## ## ## ## ## ## ## ## ##
+## ## ## ## ## ## ## ## ## ## ## ## ## ##
+######## ## ## ## ## ## ######## ## ## ###### ########
+######## ## ## ## ## ## ######## ## ## ###### ########
+
+
+
+
+/* wrapper
+*/
+function ewiki_database($action, $args, $sw1=0, $sw2=0, $pf=false) {
+
+ #-- normalize (fetch bad parameters)
+ if (($action=="GET") && !is_array($args) && is_string($args)) {
+ $args = array("id" => $args);
+ }
+
+ #-- treat special
+ switch ($action) {
+
+ case "GETALL":
+ $args = array_unique(array_merge($args, array("flags", "version")));
+ $args = array_diff($args, array("id"));
+ break;
+
+ case "SEARCH":
+# unset($args["version"]);
+# unset($args["flags"]);
+ break;
+
+ default:
+ break;
+ }
+
+ #-- handle {meta} sub array as needed
+ if (is_array(@$args["meta"])) {
+ $args["meta"] = serialize($args["meta"]);
+ }
+
+ #-- database plugin
+ if (($pf) || ($pf = @$GLOBALS["ewiki_plugins"]["database"][0])) {
+ $r = $pf($action, $args, $sw1, $sw2);
+ }
+ else {
+ ewiki_log("DB layer: no backend!", 0);
+ $r = false;
+ }
+
+ #-- database layer generation 2 abstraction
+ if (is_array($r) && (($action=="SEARCH") || ($action=="GETALL"))) {
+ $z = new ewiki_dbquery_result(array_keys($args));
+ foreach ($r as $id=>$row) {
+ $z->add($row);
+ }
+ $r = $z;
+ }
+
+ #-- extract {meta} sub array
+ if (is_array($r) && !is_array(@$r["meta"]) && strlen(@$r["meta"])) {
+ $r["meta"] = unserialize($r["meta"]);
+ }
+
+ return($r);
+}
+
+
+
+/* returned for SEARCH and GETALL queries, as those operations are
+ otherwise too memory exhaustive
+*/
+class ewiki_dbquery_result {
+
+ var $keys = array();
+ var $entries = array();
+ var $buffer = EWIKI_DBQUERY_BUFFER;
+ var $size = 0;
+
+ function ewiki_dbquery_result($keys) {
+ $keys = array_merge($keys, array(-50=>"id", "version", "flags"));
+ $this->keys = array_unique($keys);
+ }
+
+ function add($row) {
+ if (is_array($row)) {
+ if ($this->buffer) {
+ $this->size += strlen(serialize($row));
+ $this->buffer = $this->size <= EWIKI_DBQUERY_BUFFER;
+ }
+ else {
+ $row = $row["id"];
+ }
+ }
+ $this->entries[] = $row;
+ }
+
+ function get($all=0, $flags=0x00) {
+ $row = array();
+
+ $prot_hide = ($flags&0x0020) && EWIKI_PROTECTED_MODE && EWIKI_PROTECTED_MODE_HIDING;
+ do {
+ if (count($this->entries)) {
+
+ #-- fetch very first entry from $entries list
+ $r = array_shift($this->entries);
+
+ #-- finish if buffered entry
+ if (is_array($r) && !$all) {
+ $row = $r;
+ }
+ #-- else refetch complete entry from database
+ else {
+ if (is_array($r)) {
+ $r = $r["id"];
+ }
+ $r = ewiki_database("GET", array("id"=>$r));
+ if (!$all) {
+ foreach ($this->keys as $key) {
+ $row[$key] = $r[$key];
+ }
+ } else {
+ $row = $r;
+ }
+ }
+ unset($r);
+ }
+ else {
+ return(NULL); // no more entries
+ }
+
+ #-- expand {meta} field
+ if (is_array($row) && is_string(@$row["meta"])) {
+ $row["meta"] = unserialize($row["meta"]);
+ }
+
+ #-- drop unwanted results
+ if ($prot_hide && !ewiki_auth($row["id"], $row, $ewiki_action)) {
+ $row = array();
+ }
+ } while ($prot_hide && empty($row));
+
+ return($row);
+ }
+
+ function count() {
+ return(count($this->entries));
+ }
+}
+
+
+
+/* MySQL database backend
+ (default)
+ Note: this is of course an abuse of the relational database scheme,
+ but neccessary for real db independence and abstraction
+*/
+function ewiki_database_mysql($action, &$args, $sw1, $sw2) {
+
+ #-- reconnect to the database (if multiple are used)
+ #<off># mysql_ping($GLOBALS["db"]);
+
+ #-- result array
+ $r = array();
+
+ switch($action) {
+
+ /* Returns database entry as array for the page whose name was given
+ with the "id" key in the $args array, usually fetches the latest
+ version of a page, unless a specific "version" was requested in
+ the $args array.
+ */
+ case "GET":
+ $id = "'" . mysql_escape_string($args["id"]) . "'";
+ ($version = 0 + @$args["version"]) and ($version = "AND (version=$version)") or ($version="");
+ $result = mysql_query("SELECT * FROM " . EWIKI_DB_TABLE_NAME
+ . " WHERE (pagename=$id) $version ORDER BY version DESC LIMIT 1"
+ );
+ if ($result && ($r = mysql_fetch_array($result, MYSQL_ASSOC))) {
+ $r["id"] = $r["pagename"];
+ unset($r["pagename"]);
+ }
+ if (strlen($r["meta"])) {
+ $r["meta"] = @unserialize($r["meta"]);
+ }
+ break;
+
+
+
+ /* Increases the hit counter for the page name given in $args array
+ with "id" index key.
+ */
+ case "HIT":
+ mysql_query("UPDATE " . EWIKI_DB_TABLE_NAME . " SET hits=(hits+1) WHERE pagename='" . mysql_escape_string($args["id"]) . "'");
+ break;
+
+
+
+ /* Stores the $data array into the database, while not overwriting
+ existing entries (using WRITE); returns 0 on failure and 1 if
+ saved correctly.
+ */
+ case "OVERWRITE": // fall-through
+ $COMMAND = "REPLACE";
+
+ case "WRITE":
+ $args["pagename"] = $args["id"];
+ unset($args["id"]);
+
+ if (is_array($args["meta"])) {
+ $args["meta"] = serialize($args["meta"]);
+ }
+
+ $sql1 = $sql2 = "";
+ foreach ($args as $index => $value) {
+ if (is_int($index)) {
+ continue;
+ }
+ $a = ($sql1 ? ', ' : '');
+ $sql1 .= $a . $index;
+ $sql2 .= $a . "'" . mysql_escape_string($value) . "'";
+ }
+
+ strlen(@$COMMAND) || ($COMMAND = "INSERT");
+
+ $result = mysql_query("$COMMAND INTO " . EWIKI_DB_TABLE_NAME .
+ " (" . $sql1 . ") VALUES (" . $sql2 . ")"
+ );
+
+ return($result && mysql_affected_rows() ?1:0);
+ break;
+
+
+
+ /* Checks for existence of the WikiPages whose names are given in
+ the $args array. Returns an array with the specified WikiPageNames
+ associated with values of "0" or "1" (stating if the page exists
+ in the database). For images/binary db entries returns the "meta"
+ field instead of an "1".
+ */
+ case "FIND":
+ $sql = "";
+ foreach (array_values($args) as $id) if (strlen($id)) {
+ $r[$id] = 0;
+ $sql .= ($sql ? " OR " : "") .
+ "(pagename='" . mysql_escape_string($id) . "')";
+ }
+ $result = mysql_query($sql = "SELECT pagename AS id, meta FROM " .
+ EWIKI_DB_TABLE_NAME . " WHERE $sql "
+ );
+ while ($result && ($row = mysql_fetch_row($result))) {
+ $r[$row[0]] = strpos($row[1], 's:5:"image"') ? $row[1] : 1;
+ }
+ break;
+
+
+
+ /* Returns an array of __all__ pages, where each entry is made up
+ of the fields from the database requested with the $args array,
+ e.g. array("flags","meta","lastmodified");
+ */
+ case "GETALL":
+ $result = mysql_query("SELECT pagename AS id, ".
+ implode(", ", $args) .
+ " FROM ". EWIKI_DB_TABLE_NAME .
+ " GROUP BY id, version DESC"
+ );
+ $r = new ewiki_dbquery_result($args);
+ $drop = "";
+ while ($result && ($row = mysql_fetch_array($result, MYSQL_ASSOC))) {
+ $i = EWIKI_CASE_INSENSITIVE ? strtolower($row["id"]) : $row["id"];
+ if ($i != $drop) {
+ $drop = $i;
+ $r->add($row);
+ }
+ }
+ break;
+
+
+
+ /* Returns array of database entries (also arrays), where the one
+ specified column matches the specified content string, for example
+ $args = array("content" => "text...piece")
+ is not guaranteed to only search/return the latest version of a page
+ */
+ case "SEARCH":
+ $field = implode("", array_keys($args));
+ $content = strtolower(implode("", $args));
+ if ($field == "id") { $field = "pagename"; }
+
+ $result = mysql_query("SELECT pagename AS id, version, flags" .
+ (EWIKI_DBQUERY_BUFFER && ($field!="pagename") ? ", $field" : "") .
+ " FROM " . EWIKI_DB_TABLE_NAME .
+ " WHERE LOCATE('" . mysql_escape_string($content) . "', LCASE($field)) " .
+ " GROUP BY id, version DESC"
+ );
+ $r = new ewiki_dbquery_result(array("id","version",$field));
+ $drop = "";
+ while ($result && ($row = mysql_fetch_array($result, MYSQL_ASSOC))) {
+ $i = EWIKI_CASE_INSENSITIVE ? strtolower($row["id"]) : $row["id"];
+ if ($i != $drop) {
+ $drop = $i;
+ $r->add($row);
+ }
+ }
+ break;
+
+
+
+ case "DELETE":
+ $id = mysql_escape_string($args["id"]);
+ $version = $args["version"];
+ mysql_query("DELETE FROM " . EWIKI_DB_TABLE_NAME ."
+ WHERE pagename='$id' AND version=$version");
+ break;
+
+
+
+ case "INIT":
+ mysql_query("CREATE TABLE " . EWIKI_DB_TABLE_NAME ."
+ (pagename VARCHAR(160) NOT NULL,
+ version INTEGER UNSIGNED NOT NULL DEFAULT 0,
+ flags INTEGER UNSIGNED DEFAULT 0,
+ content MEDIUMTEXT,
+ author VARCHAR(100) DEFAULT 'ewiki',
+ created INTEGER UNSIGNED DEFAULT ".time().",
+ lastmodified INTEGER UNSIGNED DEFAULT 0,
+ refs MEDIUMTEXT,
+ meta MEDIUMTEXT,
+ hits INTEGER UNSIGNED DEFAULT 0,
+ PRIMARY KEY id (pagename, version) )
+ ");
+ echo mysql_error();
+ break;
+
+ default:
+ }
+
+ return($r);
+}
+
+
+
+</script>
--- /dev/null
+
+ewiki/fragments/
+================
+
+This directory contains various (code) snippets, which may or may not
+be useful for you. You are on your own, when it comes to make them
+work.
+
+
+
+mkhuge
+¯¯¯¯¯¯
+ Is a shell script to merge the core "ewiki.php" with some of the common
+ extension plugins into a "huge-ewiki.php" script - for lazy people ;->
+
+
+
+core.css
+¯¯¯¯¯¯¯¯
+ Is an example (text/css) stylesheet, which shows how to tweak
+ the look of rendered pages using CSS.
+
+ You could copy it into yoursites.css or do something like this in
+ yoursite.php:
+
+ <HTML>
+ <HEAD>
+ <STYLE TYPE="text/css"><!--
+ <?php
+ include("fragments/core.css");
+ ?>
+ //--></STYLE>
+
+
+
+calendar.css
+¯¯¯¯¯¯¯¯¯¯¯¯
+ These stylesheet definitions show all possible CSS classes that
+ are used within the calendar.php plugin. Use like core.css
+
+
+
+binary.php
+¯¯¯¯¯¯¯¯¯¯
+ If yoursite.php is not designed carefully enough or EWIKI_SCRIPT_BINARY
+ cannot be set correctly, you may want to use this wrapper script to
+ allow for uploading and retrieval of binary content (images) via ewiki.
+
+ Copy it to where the main ewiki.php script is, and set the
+ EWIKI_SCRIPT_BINARY constant to the correct absolute position (possibly
+ including http://server.name/) of "binary.php".
+ (this constant must be set on top of ewiki.php)
+
+ You must set the database access params in here, too.
+
+ It may also be useful if you'd like to divide the database into its
+ two parts again - text content and binary content. You could even
+ let it save binary content in a flat file database, while WikiPages
+ remain in a RDBMS.
+
+
+
+
+homepage.src
+¯¯¯¯¯¯¯¯¯¯¯¯
+ Is an __EXAMPLE__ on how to build a crippled Wiki (using authentication)
+ for a private homepage.
+ There is a lot of infos inside the script. And please remember all
+ files labeled with "example" are just examples!!!!!!! (read: I'm rarely
+ interested in bug reports)
+
+
+
+funcs.inc
+¯¯¯¯¯¯¯¯¯
+ Possibly useful pseudo-external helper functions are collected in here.
+
+ function save_newest_pages()
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Reads the recently updated pages list from the database (like
+ "UpdatedPages") and tries to save it in another database table
+ (this example does so in my privately used webcms for speed purposes).
+
+
+
+htaccess
+¯¯¯¯¯¯¯¯
+ Shows how to use mod_rewrite with ewiki.
+
+ * old style: http://www.example.com/wiki.php?page=WikiPage
+ * PATH_INFO: http://www.example.com/WikiPage
+
+ Remember to enable EWIKI_USE_PATH_INFO inside ewiki.php - this was
+ disabled once, because of the many broken Apache implementations (they
+ seem to support that broken CGI/1.1 specification, which was for good
+ reasons and luckily never blessed to become an official RFC).
+
+
+
+strip_wonderful_slashes.php
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Fixes the very bad "magic_quotes_gpc" setting from php.ini for PHP
+ versions prior to 4.3
+
+ Does not hurt a well configured PHP interpreter setup.
+
+
+
+wiki_format.inc
+¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Stripped version of the wiki rendering core for easier inclusion into
+ your own projects.
+
+
--- /dev/null
+<?php
+
+ # http user space authentication layer
+ # ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ # can be used with the tools/, if you don't want to
+ # set up the .htaccess and .htpasswd files
+
+
+ #-- (pw array - I have such one in an external config file)
+ $passwords = array(
+// "user" => "password",
+// "u2" => "password",
+ );
+
+
+
+ #-- fetch user:password
+ if ($uu = trim($_SERVER["HTTP_AUTHORIZATION"])) {
+ strtok($uu, " ");
+ $uu = strtok(" ");
+ $uu = base64_decode($uu);
+ list($_a_u, $_a_p) = explode(":", $uu, 2);
+ }
+ elseif (strlen($_a_u = trim($_SERVER["PHP_AUTH_USER"]))) {
+ $_a_p = trim($_SERVER["PHP_AUTH_PW"]);
+ }
+
+ #-- check password
+ $_success = false;
+ if (strlen($_a_u) && strlen($_a_p) && ($_a_p == @$passwords[$_a_u])) {
+ $_success = $_a_u;
+ }
+
+ #-- request HTTP Basic authentication otherwise
+ if (!$_success) {
+ header('HTTP/1.1 401 Authentication Required');
+ header('Status: 401 Authentication Required');
+ header('WWW-Authenticate: Basic realm="restricted access"');
+ die();
+ }
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+ # if you cannot manage to include() the core "ewiki.php" library
+ # before any plain <HTML> output is made inside "yoursite.php", you
+ # could use such a lib wrapper beside yoursites/index.php
+
+ # it is also useful, if you want to keep binary data in a separate
+ # database, say a db_flat_files one - because you can then set this up
+ # herein without any affect to yoursites/ewiki.php
+
+
+ # remember to define() inside ewiki.php or yoursite.php:
+ define("EWIKI_SCRIPT_BINARY", "binary.php?binary=");
+
+
+ #-- that's all:
+ mysql_connect("localhost", "DBUSER", "DBPASSWORD");
+ mysql_query("use DATABASENAME");
+
+ include("ewiki.php");
+
+?>
\ No newline at end of file
--- /dev/null
+
+/*
+ Include these style definitions into your sites` css, if you'd like
+ to use the calendar plugin.
+*/
+
+
+ table.caltable{
+ background-color: #CDBDAD;
+ }
+ td.calhead {
+ font-family: Verdana, Arial, sans-serif;
+ font-size: 8pt;
+ text-align:center;
+ }
+ th.caldays{
+ color:#BA997A;
+ font-family: Verdana, Arial, sans-serif;
+ font-size: 8pt;
+ text-align:center;
+ }
+ td.calday{
+ font-family: Verdana, Arial, sans-serif;
+ font-size: 8pt;
+ text-align:right;
+ }
+ td.caltoday{
+ background-color:#D7CFC7;
+ font-family: Verdana, Arial, sans-serif;
+ font-size: 8pt;
+ text-align:right;
+ }
+ a.calpg{
+ text-decoration: none;
+ font-weight:600;
+ }
+ a.calhide{
+ text-decoration: none;
+ }
--- /dev/null
+
+/*
+ These example style definitions only show how to tweak look
+ of generated WikiPages.
+*/
+
+
+ body, td {
+ line-height:140%;
+ }
+
+ a {
+ text-decoration:none;
+ }
+
+ a:hover {
+ text-decoration:underline;
+ }
+
+ p {
+ line-height:110%;
+ }
+
+ em {
+ text-decoration:none;
+ font-style:normal;
+ background-color:#cccc22;
+ }
+
+ strong {
+ font-weight:700;
+ }
+
+ .box {
+ background-color:#222266;
+ border:1px #111133 solid;
+ }
+
+ .box hr {
+ display:none;
+ }
+
+ hr {
+ visibility:hidden;
+ }
+
+ form[name=ewiki] {
+ border:2px #ffffff dashed;
+ padding:5px;
+ background-color:#444444;
+ }
+
+ textarea[name=content] {
+ border:2px #000000 dotted;
+ background-color:#B4D3D7;
+ }
+
+ input[name=save], input[name=preview] {
+ border:1px #000000 solid;
+ background-color:#B4D3D7;
+ -moz-border-redius:10px;
+ }
+
--- /dev/null
+#
+# this file contains various useful helper functions, to interfer
+# with the ewiki database from within another site engine
+#
+# may be there is something useful in here for you, too
+#
+
+
+#-- save newest pages
+function save_newest_pages()
+{
+ $sorted = array();
+ foreach (ewiki_database("GETALL", array("lastmodified", "flags", "version")) as $row) {
+ if (($row["flags"] & EWIKI_DB_F_TYPE) == EWIKI_DB_F_TEXT) {
+ $sorted[$row["id"]] = $row["lastmodified"];
+ }
+ }
+ arsort($sorted);
+ $n = 0;
+ $o = "";
+ foreach ($sorted as $id=>$uu) {
+ $o .= '·<a href="/wiki/?id=' . urlencode($id) . '">' .
+ preg_replace('/(\w{15}[a-zäöüß]*)(\w{3,5})/', '$1­$2', $id) . "</a><br>\n";
+ if ($n++ >= 15) break;
+ }
+ $o = addslashes($o);
+
+ mysql_query("UPDATE text_table SET html='$o' WHERE filename='wiki-updated' ")
+ or
+ return($o);
+}
+
+
--- /dev/null
+<?php
+
+
+ #-- This is an example standalone lite-CMS Homepage based on ewiki.php
+
+ # - it requires PHP4.1+
+ # - you should install it as index.php into your dedicated webspace
+ # - copy the ewiki.php there, too
+ # - DON'T upload the tools/ directory, as this requires a lot more
+ # setup to be used securely
+ # - HTML Editors usually allow you to tweak the layout without
+ # garbaging the PHP code inside
+ # - authentication is done using JavaScript+Cookies
+ # - requires a MySQL database, just visit http://freesql.org/ and
+ # get happy (if your provider doesn't provide one)
+ # - there will be no pages initially, you must first create some
+ # - most config options are in the upper area of this file:
+
+ $HOMEPAGE_TITLE = 'MyHomepage';
+ $LOGIN_PASSWORD = 'ewiki';
+ $AUTHOR_NAME = 'your_nickname_here';
+ $MYSQL_HOST = 'localhost';
+ $MYSQL_USER = 'root';
+ $MYSQL_PASSWORD = '';
+ $MYSQL_DATABASE = 'test';
+
+ #-- open database
+ if (!@mysql_ping()) {
+ mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD);
+ mysql_query("use $MYSQL_DATABASE");
+ }
+
+ #-- no errors shown from here
+ error_reporting(0);
+
+ #-- check for password
+ if ($LOGIN_PASSWORD == "password") die("poor");
+ if ($_COOKIE["password"]) {
+ if ($LOGIN_PASSWORD == $_COOKIE["password"]) {
+ $ewiki_author = $AUTHOR_NAME;
+ }
+ else {
+ $page_content == "<h3>password wrong</h3>";
+ }
+ }
+
+ #-- load ewiki
+ define("EWIKI_EDIT_AUTHENTICATE", 1);
+ define("EWIKI_SCRIPT", substr(__FILE__, strrpos(__FILE__, "/") + 1) . "?page=");
+ define("EWIKI_SCRIPT_BINARY", substr(__FILE__, strrpos(__FILE__, "/") + 1) . "?binary=");
+ define("EWIKI_PAGE_INDEX", $HOMEPAGE_TITLE);
+ define("EWIKI_CONTROL_LINE", 0);
+ define("EWIKI_T_CANNOTCHANGEPAGE", "You must first login to change a page.");
+ include("ewiki.php");
+
+ #-- get current page
+ if (empty($page_content)) {
+ $page_content = ewiki_page();
+ }
+
+
+?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+ <HEAD>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+ <title><?php echo($ewiki_title); ?></title>
+ <meta name="GENERATOR" content="ewiki" />
+ <meta name="ROBOTS" content="INDEX,FOLLOW" />
+
+ <style type="text/css">
+ <!--
+ body {
+ background-color:#6666ee;
+ color:#000011;
+ }
+ .menu {
+ background-color:#111166;
+ color:#ffffff;
+ border: 2px solid #000055;
+ padding: 8px;
+ text-align:center;
+ width:120px;
+ }
+ a,a:link { color: #ffff33; text-decoration: none; }
+ a:active { color: #FF6666; }
+ a:visited { color: #660000; }
+ a:hover { font-weight:900; background-color:#ffff00; color:#000000; }
+ .menu a { color:#ffffff; }
+ .menu a:hover { color:#000000; }
+ //-->
+ </style>
+
+ <script language="JavaScript" type="text/javascript">
+ <!--
+
+ function login()
+ {
+ var password = window.prompt("Please enter the administrator password:");
+ window.document.cookie = "password=" + password;
+ window.document.location.reload();
+ }
+
+ function logout()
+ {
+ window.document.cookie = "password=";
+ }
+
+ //-->
+ </script>
+
+</HEAD>
+
+<BODY>
+
+<CENTER>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="10" WIDTH="90%">
+<TR>
+
+<TD WIDTH="120" VALIGN="TOP">
+
+<DIV CLASS="menu">
+
+<h3>Welcome to my Homepage!</h3>
+
+
+ <A HREF=".">Startpage</A> <BR>
+
+ <A HREF="?page=EMailMe">EMailMe</A> <BR>
+
+ <A HREF="?page=MyLinks">MyLinks</A> <BR>
+
+ <BR>
+
+
+<?php
+
+
+ if ($ewiki_author) {
+
+ echo "<A HREF=\"javascript:logout()\">Logout</A><BR>";
+ echo "<A HREF=\"?page=edit/$ewiki_title\">EditThisPage</A><BR>";
+ echo "<A HREF=\"?page=info/$ewiki_title\">PageInfo</A><BR>";
+
+ }
+ else {
+
+ echo "<A HREF=\"?page=links/$ewiki_title\">Links to here</A><BR><BR>";
+
+ echo "<SMALL><A HREF=\"javascript:login()\">EditorLogin</A><BR></SMALL>";
+ }
+
+
+?>
+
+</DIV>
+</TD>
+
+<TD VALIGN="TOP" WIDTH="90%">
+<DIV CLASS="content">
+<?php
+
+
+ echo($page_content);
+
+
+?>
+</TR>
+</TABLE>
+</CENTER>
+
+</BODY>
+</HTML>
\ No newline at end of file
--- /dev/null
+# This is file is to be used with the Apache or Nanoweb webserver.
+#
+# Rename it to .htaccess (or .nwaccess for Nanoweb) in a dedicated
+# directory for your Wiki.
+#
+# It uses the mod_rewrite to look a bit more professionall than
+# the usual GET-vars at the end of our URLs. This is highly
+# recommended as things like "script.php?edit=1&id=page" usually
+# scare search engines and may prevent your Wiki from getting
+# indexed.
+#
+# Please edit ewiki.php and enable EWIKI_USE_PATH_INFO for Apache
+# webservers - the PATH_INFO implementation is very broken for many
+# versions (mostly commercial Unicies and for PHP-CGI variants),
+# because to the Apache Group once choosed to follo that never
+# finished and heavily broken (proposed) CGI/1.1 specification.
+
+#-- enable mod_rewrite (Apache + Nanoweb)
+RewriteEngine On
+
+#-- pass WikiWord-URLs to the wiki wrapper script:
+RewriteRule ^((\w+/)?[A-Z]+[a-z]+\w*[A-Z]+\w+)$ yoursite.php/$1 [L]
+
+#-- or this one, if there is really nothing else in the same directory:
+#RewriteRule ^(.*)$ yoursite.php?id=$1 [L]
--- /dev/null
+#!/bin/sh
+#
+# a shell script, which combines the ewiki.php library and some
+# default plugins into a huger include library
+#
+
+
+HUGE_FILE="huge-ewiki.php"
+CORE_FILE="ewiki.php"
+
+
+#-- current dir
+if [ -e "ewiki.php" ] ; then
+ DWP=.
+else
+ DWP=..
+fi
+
+
+#-- help
+if [ "$1" == "-h" -o "$1" == "--help" ] ; then
+ echo "syntax: mkhuge"
+ echo "combines many of the plugins and the core ewiki.php file into a bigger lib."
+ exit
+fi
+
+
+#-- choose size
+N=$1
+if [ -z "$N" ] ; then
+ N=0
+fi
+if [ "$1" -ge "3" ] ; then
+ PLUGINS="markup_phpwiki.php markup_bbcode.php spellcheck.php $PLUGINS"
+fi
+if [ "$1" -ge "2" ] ; then
+ PLUGINS="more_interwiki.php page_imagegallery.php $PLUGINS"
+fi
+if [ "$1" -ge "1" ] ; then
+ PLUGINS="diff.php page_randompage.php markup_footnotes.php page_wordindex.php $PLUGINS"
+fi
+PLUGINS="strip_wonderful_slashes.php calendar.php email_protect.php like_pages.php page_pageindex.php page_powersearch.php $PLUGINS"
+
+
+#-- proceed
+echo -n "writing: $CORE_FILE"
+cat $DWP/$CORE_FILE > $DWP/$HUGE_FILE
+for ADD in $PLUGINS
+do
+ echo -n "+$ADD"
+ for SUB in plugins fragments ; do
+ if [ -e "$DWP/$SUB/$ADD" ] ; then
+ ADD=$DWP/$SUB/$ADD
+ fi
+ done
+ cat $ADD >> $DWP/$HUGE_FILE
+done
+echo " > $DWP/$HUGE_FILE"
+echo "done."
+
+
--- /dev/null
+<?php
+
+/*
+
+ This is a PHPNuke5.2 module (don't know if it works with v6) to be
+ copied into the modules directory like the filename implies
+ ( phpnuke/modules/Wiki/ ).
+
+ You should copy the "ewiki.php" into the same directory!
+
+ If you want it to initialize the db correctly you must copy the
+ init-pages/ to there as well.
+
+*/
+
+
+#-- stupid legacy code
+if (!eregi("modules.php", $PHP_SELF)) {
+ die ("You can't access this file directly...");
+}
+
+#-- blocks to the left and to the right?
+$index = 0;
+
+#-- HTML,HEAD,TABLESTART
+include("header.php"); #-- or better "mainfile.php" ???
+
+
+#-- Output -----------------------------------------------------------
+OpenTable(); # do we want to know, what this is for?
+
+
+
+
+chdir("modules/Wiki/");
+
+error_reporting(0);
+define("EWIKI_SCRIPT", "modules.php?op=modload&name=Wiki&file=index&wikipage=");
+
+include("ewiki.php");
+($wikipage = $_REQUEST["wikipage"]) or
+($wikipage = $_REQUEST["page"]) or
+($wikipage = EWIKI_PAGE_INDEX);
+echo ewiki_page($wikipage);
+
+chdir("../..");
+
+
+
+
+CloseTable(); # strange function names ;)
+
+
+# /BODY
+include("footer.php");
+
+
+?>
--- /dev/null
+<?php
+
+/*
+
+ this strips all "\" from $_REQUEST and
+ disables the runtime garbaging as well
+
+ just include() it before ewiki.php
+ and everythink should work fine
+
+
+ for Apache+mod_php you should however rather use the
+ [.htaccess] PHP reconfiguration trick:
+ php_flag magic_quotes_gpc off
+ php_flag magic_quotes_runtime off
+
+*/
+
+
+ #-- this is very evil too
+ set_magic_quotes_runtime(0);
+
+
+ #-- strip \'s only if the variables garbaging is really enabled
+ if (get_magic_quotes_gpc()) {
+
+ $superglobals = array(
+ "_REQUEST",
+ "_GET",
+ "_POST",
+ "_COOKIE",
+ "_ENV",
+ "_SERVER"
+ );
+
+ foreach ($superglobals as $AREA) {
+
+ foreach ($GLOBALS[$AREA] as $name => $value) {
+
+ if (!is_array($value)) {
+ $GLOBALS[$AREA][$name] = stripslashes($value);
+ }
+ }
+ }
+
+ }
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/*
+ * Wiki-Engine from "ErfurtWiki", Mario Salzer <milky@erphesfurt.de>
+ * Adapted by Frank Luithle <sigi@fsinfo.cs.uni-sb.de>
+ *
+ * WikiLinks and binary already stripped off -> just the rendering core
+ */
+
+// URL prefixes
+$ewiki_idf_url = array( "http://",
+ "mailto:",
+ "ftp://",
+ "irc://",
+ "telnet://",
+ "news://",
+ "internal://",
+ "chrome://",
+ "file://" );
+
+// allowed wikinames
+//define( "EWIKI_CHARS_L", "a-zäöüß_µ¤$" );
+//define( "EWIKI_CHARS_U", "A-ZÄÖÜ" );
+
+function wiki_format( $wiki_source,
+ $strip_slashes = true,
+ $safe_html_allowed = true,
+ $table_html_allowed = false ) {
+
+ if ( $strip_slashes ) {
+ $wiki_source = stripslashes( $wiki_source );
+ }
+
+ // formatted output
+ $o = "<p>\n";
+
+ // state vars
+ $li_o = "";
+ $tbl_o = 0;
+ $post = "";
+
+ $wm_whole_line = array( "!!!" => "h2",
+ "!!" => "h3",
+ "!" => "h4",
+ " " => "tt",
+ ";:" => 'div style="left-margin:10pt;"' );
+
+ $table_defaults = 'cellpadding="2" border="1" cellspacing="0"';
+
+ // these tags will be preserved if the $safe_html_allowed argument
+ // is set to 'true'
+ $rescue_html = array( "tt", "b", "i", "strong", "em", "s", "kbd", "var",
+ "xmp", "sup", "sub", "pre", "q", "h2", "h3", "h4",
+ "h5", "h6", "cite", "code", "u" );
+
+ $syn_htmlentities = array( "&" => "&",
+ ">" => ">",
+ "<" => "<",
+ "%%%" => "<br>" );
+
+ $wm_list = array( "-" => array('ul type="square"', "", "li"),
+ "*" => array('ul type="circle"', "", "li"),
+ "#" => array("ol", "", "li"),
+ ":" => array("dl", "dt", "dd") );
+
+ $wm_text_style = array( "'''" => array("''__", "__''"),
+ "___" => array("''__", "__''"),
+ "''" => array("<em>", "</em>"),
+ "__" => array("<strong>", "</strong>"),
+ // "^^" => array("<sup>", "</sup>"),
+ // "***" => array("<b><i>", "</i></b>"),
+ // "###" => array("<big><b>", "</b></big>"),
+ "**" => array("<b>", "</b>"),
+ "##" => array("<big>", "</big>"),
+ "µµ" => array("<small>", "</small>") );
+
+ $link_regex = "#(!?\[[^[\]\n]+\])|((?:!?[a-z]{2,6}://|mailto:)[^\s\[\]\'\"\)\,<]+)#";
+
+ #$link_regex = "#(!?\[[^[\]\n]+\])|((?:!?[".EWIKI_CHARS_U."]+[".EWIKI_CHARS_L.
+ # ":]+){2}[\w\d]*)|((?:!?[a-z]{2,6}://|mailto:)[^\s\[\]\'\"\)\,<]+)#";
+
+ // eliminate html
+ foreach ( $syn_htmlentities as $find => $replace ) {
+ $wiki_source = str_replace( $find, $replace, $wiki_source );
+ }
+ array_pop( $syn_htmlentities );
+
+ // unescape allowed html
+ if ( $safe_html_allowed ) {
+ foreach ( $rescue_html as $tag ) {
+ foreach( array( $tag, "/$tag", ( $tag = strtoupper($tag) ), "/$tag" )
+ as $tag ) {
+ $wiki_source = str_replace( '<' . $tag . '>',
+ "<" . $tag . ">",
+ $wiki_source );
+ }
+ }
+ }
+
+ $wiki_source = trim( $wiki_source ) . "\n";
+
+ foreach ( explode( "\n", $wiki_source ) as $line ) {
+ $line = rtrim( $line );
+ $post = "";
+
+ // paragraphs
+ if ( empty($line) ) {
+ $post .= "</p>\n\n<p>";
+ } elseif ( strpos( $line, "----" ) === 0 ) {
+ $o .= "<hr>\n";
+ continue;
+ } elseif ( strpos( $line, "<!--" ) === 0 ) {
+ $o .= "<!-- " . htmlentities( str_replace( "--", "__", substr($line, 7) ) ) . " -->\n";
+ continue;
+ }
+
+ // unescape html markup || tables wiki markup
+ if ( strlen( $line ) && ( $line[0] == "|" ) ) {
+ if ( strlen( $line ) >
+ strlen( trim( $line, "|" ) ) + 1 ) {
+ $line = substr( $line, 1, strlen( $line ) - 2 );
+ if ( !$tbl_o ) {
+ $o .= "<table " . $table_defaults . ">\n";
+ }
+ $line = "<tr>\n<td>" . str_replace("|", "</td>\n<td>", $line) . "</td>\n</tr>";
+ $tbl_o = 1;
+ } elseif ( $table_html_allowed ) {
+ $line = ltrim( substr( $line, 1 ) );
+ foreach ( array_flip( $syn_htmlentities ) as $find => $replace ) {
+ $line = str_replace( $find, $replace, $line );
+ }
+ }
+ } elseif ($tbl_o) {
+ $o .= "</table>\n";
+ $tbl_o = 0;
+ }
+
+ // whole-line wikimarkup
+ foreach ( $wm_whole_line as $find => $replace ) {
+ if ( substr( $line, 0, strlen($find) ) == $find ) {
+ $line = ltrim( substr( $line, strlen($find) ) );
+ $o .= "<$replace>";
+ $post = "</" . strtok( $replace, " " ) . ">" . $post;
+ }
+ }
+
+ // wiki list markup
+ if ( strlen( $li_o ) ||
+ strlen( $line ) && isset( $wm_list[@$line[0]] ) ) {
+ $n = 0;
+ $li = "";
+ // count differences to previous list wikimarkup
+ while ( strlen( $line ) && ( $li0 = $line[0] ) && isset( $wm_list[$li0] ) ) {
+ $li .= $li0;
+ $n++;
+ $line = substr($line, 1);
+ }
+ $line = ltrim($line);
+
+ // fetch list definition
+ if ( strlen( $li ) && ( $last_list_i = $li[strlen($li)-1] ) )
+ list( $list_tag, $list_dt0, $list_entry_tag ) = $wm_list[$last_list_i];
+
+ // output <ul> until new list wikimarkup rule matched
+ while ( strlen($li_o) < strlen($li) ) {
+ $add = $li[ strlen($li_o) ];
+ $o .= "<" . $wm_list[ $add ][ 0 ] . ">\n";
+ $li_o .= $add;
+ }
+
+ // close </ul> lists until "$li_o" == "$li" (list wikimarkup state var)
+ while ( strlen($li_o) > strlen($li) ) {
+ $del = $li_o[ strlen($li_o) - 1 ];
+ $o .= "</" . strtok( $wm_list[$del][0], " " ) . ">\n";
+ $li_o = substr( $li_o, 0, strlen($li_o) - 1 );
+ }
+
+ // more work for <dl> lists
+ if ( !empty($list_dt0) ) {
+ list( $line_dt, $line ) = explode( $last_list_i, $line, 2 );
+ $o .= "<$list_dt0>$line_dt</$list_dt0>";
+ $list_dt0 = $last_list_i = false;
+ }
+
+ // finally enclose current line in <li>...</li>
+ if ( !empty($line) ) {
+ $o .= "<$list_entry_tag>";
+ $post = "</$list_entry_tag>" . $post;
+ }
+
+ $li_o = $li;
+ }
+
+ // link-regex here??
+ // (was formerly, may be faster if applied to the whole formatted
+ // page, but this could also introduce some rendering bugs)
+
+ // text style triggers
+ foreach ( $wm_text_style as $find => $replace ) {
+ $n = strlen( $find );
+ $loop = 20;
+ while( ( $loop-- ) &&
+ ( ($l = strpos($line, $find)) !== false ) &&
+ ( $r = strpos($line, $find, $l + $n) ) ) {
+ $line = substr( $line, 0, $l ) . $replace[0] .
+ substr( $line, $l + strlen($find), $r - $l - $n ) .
+ $replace[1] . substr( $line, $r + $n );
+ }
+ }
+
+ // add formatted line to page-output
+ $o .= $line . $post . "\n";
+
+ }
+
+ // close last line
+ $o .= "</p>\n";
+
+ // finally the link-detection-regex
+ // (impossible to do with simple string arithmetics)
+ $o = preg_replace_callback( $link_regex, "wiki_link_regex_callback", $o );
+
+ return( $o );
+}
+
+
+function wiki_link_regex_callback( $uu ) {
+
+ global $ewiki_idf_url;
+
+ $str = $uu[0];
+
+ // link bracket '[' escaped with '!'
+ if ( $str[0] == "!" ) {
+ return(substr($str, 1));
+ } elseif ( $str[0] == "[" ) {
+ $str = substr( $str, 1, strlen($str) - 2 );
+ }
+
+ // explicit title given via [ foo | bar ]
+ $href = $title = strtok( $str, "|" );
+ if ( $uu = strtok("|") ) {
+ $href = $uu;
+ }
+
+ // title and href swapped: swap back
+ if ( strpos( "://", $title ) ||
+ strpos( $title, ":" ) && !strpos( $href, ":" ) ) {
+ $uu = $title;
+ $title = $href;
+ $href = $uu;
+ }
+
+ $title = trim($title);
+ $href = trim($href);
+
+ /* create _no_ WikiLinks */
+ if ( false ):
+ // interwiki links
+ if ( strpos($href, ":") &&
+ !strpos($href, "//") &&
+ ($p1 = @$ewiki_interwiki[strtok($href, ":")]) ) {
+ while ($p1_alias = @$ewiki_interwiki[$p1]) {
+ $p1 = $p1_alias;
+ }
+ $href = $p1 . strtok("\000");
+ } elseif (($ewiki_links === true) ||
+ @$ewiki_links[$href] ||
+ @$ewiki_internal_pages[$href]) {
+ // ordinary internal WikiLinks
+ $str = '<a href="' . EWIKI_SCRIPT .
+ urlencode($href) . '">' . $title . '</a>';
+ } else {
+ $str = '<b>' . $title . '</b><a href="' .
+ EWIKI_SCRIPT . urlencode($href) /*.EWIKI_ADDPARAMDELIM.'edit'*/ .
+ ' ">?</a>';
+ }
+ endif;
+
+ // convert normal URLs
+ foreach ( $ewiki_idf_url as $find ) {
+ if ( strpos( $href, $find ) === 0 ) {
+ $str = '<a href="' . $href . '">' . $title . '</a>';
+ break;
+ }
+ }
+
+ return($str);
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+ # This plugin protects email addresses from getting seen by spambots,
+ # by the cost of additonal effort for real persons, who really want
+ # to mail someone.
+ #
+ # It is __really safe__ because it protects addresses with an request
+ # <FORM> before the real email address gets shown on a page (it seems
+ # impossible to me, that there are already all that intelligent spambots
+ # available, which can automatically fill out a <form> to access the
+ # following page).
+ # The 'cipher' method is really unimportant, when it comes to tricking
+ # automated harvesters.
+ #
+ # Additionally it generates faked/trap email addresses to annoy the
+ # marketing mafia.
+
+
+ #-- change these from time to time:
+ define("EWIKI_PAGE_EMAIL", "ProtectedEmail");
+ define("EWIKI_UP_ENCEMAIL", "encoded_email");
+ define("EWIKI_UP_NOSPAMBOT", "i_am_no_spambot");
+ define("EWIKI_UP_REQUESTLV", "rl");
+ define("EWIKI_FAKE_EMAIL_LOOP", 5);
+ $ewiki_config["feedbots_tarpits"] = "@spamassassin.taint.org,@123webhosting.org,@e.mailsiphon.com,@heypete.com,@ncifcrf.gov";
+ $ewiki_config["feedbots_badguys"] = "@riaa.com,@whitehouse.gov,@aol.com,@microsoft.com";
+
+ #-- text, translations
+ $ewiki_t["en"]["PROTE0"] = "Protected Email Address";
+ $ewiki_t["en"]["PROTE1"] = "The email address you've clicked on is protected by this form, so it won't get found by <a href=\"http://google.com/search?q=spambots\">spambots</a> (automated search engines, which crawl the net for addresses just for the entertainment of the marketing mafia).";
+ $ewiki_t["en"]["PROTE2"] = "The page you're going to edit contains at least one email address. To protect it we must ensure that no spambot reaches the edit box (with the email address in cleartext).";
+ $ewiki_t["en"]["PROTE4"] = "I'm no spambot, really!";
+ $ewiki_t["en"]["PROTE5"] = "<b>generate more faked email addresses</b>";
+ $ewiki_t["en"]["PROTE6"] = "the email address you've clicked on is:";
+ $ewiki_t["en"]["PROTE7"] = "<b>spammers, please eat these:</b>";
+
+ $ewiki_t["de"]["PROTE0"] = "Geschützte EMail-Adresse";
+ $ewiki_t["de"]["PROTE1"] = "Die EMail-Adresse, die du angeklickt hast, wird durch dieses Formular vor <a href=\"http://google.com/search?q=spambots\">spambots</a> (automatisierte Suchwerkzeuge, die das Netz zur Freude der MarketingMafia nach Adressen abgrasen) beschützt.";
+ $ewiki_t["de"]["PROTE2"] = "Die Seite, die du ändern willst, enthält momentan wenigstens eine EMail-Adresse. Um diese zu schützen müssen wir sicherstellen, daß kein Spambot an die Edit-Box kommt (weil dort die Adresse ja im Klartext steht).";
+ $ewiki_t["de"]["PROTE4"] = "Ich bin wirklich kein Spambot!";
+ $ewiki_t["de"]["PROTE5"] = "<b>noch mehr fingierte Adressen anzeigen</b>";
+ $ewiki_t["de"]["PROTE6"] = "die EMail-Adresse die du angeklickt hast lautet:";
+ $ewiki_t["de"]["PROTE7"] = "<b>Liebe Spammer, bitte freßt das:</b>";
+
+ #-- plugin glue
+ $ewiki_plugins["link_url"][] = "ewiki_email_protect_link";
+ $ewiki_plugins["page"][EWIKI_PAGE_EMAIL] = "ewiki_email_protect_form";
+ $ewiki_plugins["edit_hook"][] = "ewiki_email_protect_edit_hook";
+ $ewiki_plugins["page_final"][] = "ewiki_email_protect_enctext";
+
+
+
+ function ewiki_email_protect_enctext(&$html, $id, $data, $action) {
+
+ $a_secure = array("info", "diff");
+
+ if (in_array($action, $a_secure)) {
+
+ $html = preg_replace('/([-_+\w\d.]+@[-\w\d.]+\.[\w]{2,5})\b/me',
+ '"<a href=\"".ewiki_email_protect_encode("\1",2).
+ "\">".ewiki_email_protect_encode("\1",0)."</a>"',
+ $html);
+ }
+ }
+
+
+ /* ewiki_format() callback function to replace mailto: links with
+ * encoded redirection URLs
+ */
+ function ewiki_email_protect_link(&$href, &$title) {
+
+ if (substr($href, 0, 7) == "mailto:") {
+
+ $href = substr($href, 7);
+
+ $href = ewiki_email_protect_encode($href, 2);
+ $title = ewiki_email_protect_encode($title, 0);
+ }
+ }
+
+
+
+ /* the edit box for every page must be protected as well - else all
+ * mail addresses would still show up in the wikimarkup (cleartext)
+ */
+ function ewiki_email_protect_edit_hook($id, &$data, &$hidden_postdata) {
+
+ $hidden_postdata[EWIKI_UP_NOSPAMBOT] = 1;
+
+ if (empty($_REQUEST[EWIKI_UP_NOSPAMBOT])
+ && strpos($data["content"], "@")
+ && preg_match('/\w\w@([-\w]+\.)+\w\w/', $data["content"]) )
+ {
+ $url = ewiki_script("edit", $id);
+ $o = ewiki_email_protect_form($id, $data, "edit", "PROTE2", $url);
+ return($o);
+ }
+
+ if (!empty($_POST[EWIKI_UP_NOSPAMBOT]) && empty($_COOKIE[EWIKI_UP_NOSPAMBOT]) && EWIKI_HTTP_HEADERS) {
+ setcookie(EWIKI_UP_NOSPAMBOT, "grant_access", time()+7*24*3600, "/");
+ }
+
+ }
+
+
+
+ /* this places a <FORM METHOD="POST"> in between the WikiPage with the
+ * encoded mail address URL and the page with the clearly readable
+ * mailto: string
+ */
+ function ewiki_email_protect_form($id, $data=0, $action=0, $text="PROTE1", $url="") {
+
+ if ($url || ($email = @$_REQUEST[EWIKI_UP_ENCEMAIL])) {
+
+ $html = "<h3>" . ewiki_t("PROTE0") . "</h3>\n";
+
+ if (empty($_REQUEST[EWIKI_UP_NOSPAMBOT])) { #// from GET,POST,COOKIE
+
+ (empty($url)) and ($url = ewiki_script("", EWIKI_PAGE_EMAIL));
+
+ $html .= ewiki_t($text) . "<br><br><br>\n";
+
+ $html .= '<form action="' . $url .
+ '" method="POST" enctype="multipart/form-data" encoding="iso-8859-1">';
+ $html .= '<input type="hidden" name="'.EWIKI_UP_ENCEMAIL.'" value="' . $email . '">';
+ foreach (array_merge($_GET, $_POST) as $var=>$value) {
+ if (($var != "id") && ($var != EWIKI_UP_ENCEMAIL) && ($var != EWIKI_UP_NOSPAMBOT)) {
+ $html .= '<input type="hidden" name="' . htmlentities($var) . '" value="' . htmlentities($value) . '">';
+ }
+ }
+ $html .= '<input type="checkbox" name="'.EWIKI_UP_NOSPAMBOT.'" value="true"> ' . ewiki_t("PROTE4") . '<br><br>';
+ $html .= '<input type="submit" name="go"></form><br><br>';
+
+ if (EWIKI_FAKE_EMAIL_LOOP) {
+ $html .= "\n" . ewiki_t("PROTE7") . "<br>\n";
+ $html .= ewiki_email_protect_feedbots();
+ }
+
+ }
+ else {
+
+ $email = ewiki_email_protect_encode($email, -1);
+
+ $html .= ewiki_t("PROTE6") . "<br>";
+ $html .= '<a href="mailto:' . $email . '">' . $email . '</a>';
+
+ if (EWIKI_HTTP_HEADERS && empty($_COOKIE[EWIKI_UP_NOSPAMBOT])) {
+ setcookie(EWIKI_UP_NOSPAMBOT, "grant_access", time()+7*24*3600, "/");
+ }
+
+ }
+
+ }
+
+ return($html);
+ }
+
+
+
+ /* security really does not depend on how good "encoding" is, because
+ * bots cannot automatically guess that one is actually used
+ */
+ function ewiki_email_protect_encode($string, $func) {
+
+ switch ($func) {
+
+ case 0: // garbage shown email address
+ if (strpos($string, "mailto:") === 0) {
+ $string = substr($string, 7);
+ }
+ while (($rd = strrpos($string, ".")) > strpos($string, "@")) {
+ $string = substr($string, 0, $rd);
+ }
+ $string = strtr($string, "@.-_", "»·±¯");
+ break;
+
+ case 1: // encode
+ $string = str_rot17($string);
+ $string = base64_encode($string);
+ break;
+
+ case -1: // decode
+ $string = base64_decode($string);
+ $string = str_rot17($string);
+ break;
+
+ case 2: // url
+ $string = ewiki_script("", EWIKI_PAGE_EMAIL,
+ array(EWIKI_UP_ENCEMAIL => ewiki_email_protect_encode($string, 1))
+ );
+ break;
+
+ }
+
+ return($string);
+ }
+
+
+
+ /* this is a non-portable string encoding fucntion which ensures, that
+ * encoded strings can only be decoded when requested by the same client
+ * or user in the same dialup session (IP address must match)
+ * feel free to exchange the random garbage string with anything else
+ */
+ function str_rot17($string) {
+ if (!defined("STR_ROT17")) {
+ $i = @$_SERVER["SERVER_SOFTWARE"] .
+ @$_SERVER["HTTP_USER_AGENT"] .
+ @$_SERVER["REMOTE_ADDR"];
+ $i .= 'MxQXF^e-0OKC1\\s{\"?i!8PRoNnljHf65`Eb&A(\':g[D}_|S#~3hG>*9yvdI%<=.urcp/@$ZkqL,TWBw]a;72UzYJ)4mt+ V';
+ $f = "";
+ while (strlen($i)) {
+ if (strpos($f, $i[0]) === false) {
+ $f .= $i[0];
+ }
+ $i = substr($i, 1);
+ }
+ define("STR_ROT17", $f);
+ }
+ return(strtr($string, STR_ROT17, strrev(STR_ROT17)));
+ }
+
+
+
+ /* this function emits some html with random (fake) email addresses
+ * and spambot traps
+ */
+ function ewiki_email_protect_feedbots() {
+
+ global $ewiki_config;
+
+ $html = "";
+ srand(time()/17-1000*microtime());
+
+ #-- spamtraps, and companys/orgs fighting for spammers rights
+ $domains = explode(",",
+ $ewiki_config["feedbots_tarpits"]. "," .$ewiki_config["feedbots_badguys"]
+ );
+ $traps = explode(" ", "blockme@relays.osirusoft.com simon.templar@rfc1149.net james.bond@ada-france.org anton.dvorak@ada.eu.org amandahannah44@hotmail.com usenet@fsck.me.uk meatcan2@beatrice.rutgers.edu heystupid@artsackett.com listme@dsbl.org bill@caradoc.org spamtrap@spambouncer.org spamtrap@woozle.org gfy@spamblocked.com listme@blacklist.woody.ch tarpit@lathi.net");
+ $word_parts = explode(" ", "er an Ma ar on in el en le ll Ca ne ri De Mar Ha Br La Co St Ro ie Sh Mc re or Be li ra Al la al Da Ja il es te Le ha na Ka Ch is Ba nn ey nd He tt ch Ho Ke Ga Pa Wi Do st ma Mi Sa Me he to Car ro et ol ck ic Lo Mo ni ell Gr Bu Bo Ra ia de Jo El am An Re rt at Pe Li Je She Sch ea Sc it se Cha Har Sha Tr as ng rd rr Wa so Ki Ar Bra th Ta ta Wil be Cl ur ee ge ac ay au Fr ns son Ge us nt lo ti ss Cr os Hu We Cor Di ton Ri ke Ste Du No me Go Va Si man Bri ce Lu rn ad da ill Gi Th and rl ry Ros Sta sh To Se ett ley ou Ne ld Bar Ber lin ai Mac Dar Na ve no ul Fa ann Bur ow Ko rs ing Fe Ru Te Ni hi ki yn ly lle Ju Del Su mi Bl di lli Gu ine do Ve Gar ei Hi vi Gra Sto Ti Hol Vi ed ir oo em Bre Man ter Bi Van Bro Col id Fo Po Kr ard ber sa Con ick Cla Mu Bla Pr Ad So om io ho ris un her Wo Chr Her Kat Mil Tre Fra ig Mel od nc yl Ale Jer Mcc Lan lan si Dan Kar Mat Gre ue rg Fi Sp ari Str Mer San Cu rm Mon Win Bel Nor ut ah Pi gh av ci Don ot dr lt ger co Ben Lor Fl Jac Wal Ger tte mo Er ga ert tr ian Cro ff Ver Lin Gil Ken Che Jan nne arr va ers all Cal Cas Hil Han Dor Gl ag we Ed Em ran han Cle im arl wa ug ls ca Ric Par Kel Hen Nic len sk uc ina ste ab err Or Am Mor Fer Rob Luc ob Lar Bea ner pe lm ba ren lla der ec ric Ash Ant Fre rri Den Ham Mic Dem Is As Au che Leo nna rin enn Mal Jam Mad Mcg Wh Ab War Ol ler Whi Es All For ud ord Dea eb nk Woo tin ore art Dr tz Ly Pat Per Kri Min Bet rie Flo rne Joh nni Ce Ty Za ins eli ye rc eo ene ist ev Der Des Val And Can Shi ak Gal Cat Eli May Ea rk nge Fu Qu nie oc um ath oll bi ew Far ich Cra The Ran ani Dav Tra Sal Gri Mos Ang Ter mb Jay les Kir Tu hr oe Tri lia Fin mm aw dy cke itt ale wi eg est ier ze ru sc My lb har ka mer sti br ya Gen Hay a b c d e f g h i j k l m n o p q r s t u v w x y z");
+ $word_delims = explode(" ", "0 1 2 3 3 3 4 5 5 6 7 8 9 - - - - - - - _ _ _ _ _ _ _ . . . . . . .");
+ $n_dom = count($domains)-1;
+ $n_trp = count($traps)-1;
+ $n_wpt = count($word_parts)-1;
+ $n_wdl = count($word_delims)-1;
+
+ for ($n = 1; $n < EWIKI_FAKE_EMAIL_LOOP; $n++) {
+
+ // email name part
+ $m = "";
+ while (strlen($m) < rand(3,17)) {
+ $a = $word_parts[nat_rand($n_wpt)];
+ if (!empty($m)) {
+ $a = strtolower($a);
+ if (rand(1,9)==5) {
+ $m .= $word_delims[rand(0,$n_wdl)];
+ }
+ }
+ $m .= $a;
+ }
+
+ // add domain
+ switch ($dom = $domains[rand(0, $n_dom)]) {
+
+ case "123webhosting.org":
+ $m = strtr(".", "-", $_SERVER["REMOTE_ADDR"])."-".$_SERVER["SERVER_NAME"]."-".time();
+ break;
+
+ default:
+ }
+ $m .= $dom;
+
+ $html .= '<a href="mailto:'.$m.'">'.$m.'</a>'.",\n";
+ }
+
+ $html .= '<a href="mailto:'.$traps[rand(0, $n_trp)].'">'.$traps[rand(0, $n_trp)].'</a>';
+
+ if (($rl = 1 + @$_REQUEST[EWIKI_UP_REQUESTLV]) < EWIKI_FAKE_EMAIL_LOOP) {
+ $html .= ",\n" . '<br><a href="' .
+ ewiki_script("", EWIKI_PAGE_EMAIL,
+ array(
+ EWIKI_UP_ENCEMAIL=>ewiki_email_protect_encode($m, 1),
+ EWIKI_UP_REQUESTLV=>"$rl"
+ )
+ ) . '">' . ewiki_t("PROTE5") . '</a><br>' . "\n";
+ ($rl > 1) && sleep(3);
+ }
+
+ sleep(1);
+ return($html);
+ }
+
+
+
+ function nat_rand($max, $dr=0.5) {
+ $x = $max+1;
+ while ($x > $max) {
+ $x = rand(0, $max * 1000)/100;
+ $x = $x * $dr + $x * $x / 2 * (1-$dr) / $max;
+ }
+ return((int)$x);
+ }
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/*
+ This plugin is used as SetupWizard and initializes the database with
+ the distributed default pages from the ./init-pages directory. It
+ gives some configuration advice, when it thinks this is necessary.
+
+ You need this plugin to run only once (when you first run the Wiki),
+ afterwards you can and should comment out the include() directive which
+ enabled it.
+*/
+
+
+$ewiki_plugins["handler"][-125] = "ewiki_initialization_wizard";
+$ewiki_plugins["page_init"][] = "ewiki_initialization_wizard2";
+
+
+function ewiki_initialization_wizard2($id, &$data, $action) {
+ global $ewiki_plugins;
+
+ #-- disable the default handler
+ unset($ewiki_plugins["handler"][-105]);
+}
+
+function ewiki_initialization_wizard($id, &$data, &$action) {
+
+ global $ewiki_plugins;
+
+ #-- proceed only if frontpage missing or explicetely requested
+ if ((strtolower($id)=="wikisetupwizard") || ($id==EWIKI_PAGE_INDEX) && ($action=="edit") && empty($data["version"]) && !($_REQUEST["abort"])) {
+
+ if ($_REQUEST["abort"]) {
+ }
+
+ #-- first print some what-would-we-do-stats
+ elseif (empty($_REQUEST["init"])) {
+
+ $o = "<h2>WikiSetupWizard</h2>\n";
+ $o .= "You don't have any pages in your Wiki yet, so we should try to read-in the default ones from <tt>init-pages/</tt> now.<br><br>";
+
+ $o .= '<a href="'.ewiki_script("",$id,array("init"=>"now")).'">[InitializeWikiDatabase]</a>';
+ $o .= " ";
+ $o .= '<a href="'.ewiki_script("",$id,array("abort"=>"this")).'">[NoThanks]</a>';
+ $o .= "<br><br>";
+
+ #-- analyze and print settings and misconfigurations
+ $pf_db = $ewiki_plugins["database"][0];
+ $db = substr($pf_db, strrpos($pf_db, "_") + 1);
+ $o .= '<table border="0" width="90%" class="diagnosis">';
+ $o .= '<tr><td>DatabaseBackend</td><td>';
+ $o .= "<b>" . $db . "</b><br>";
+ if ($db == "files") {
+ $o .= "<small>_DBFILES_DIR='</small><tt>" . EWIKI_DBFILES_DIRECTORY . "'</tt>";
+ if (strpos(EWIKI_DBFILES_DIRECTORY, "tmp")) {
+ $o .= "<br><b>Warning</b>: Storing your pages into a temporary directory is not what you want (there they would get deleted randomly), except for testing purposes of course. See the README.";
+ }
+ }
+ else {
+ $o .= "(looks ok)";
+ }
+ $o .= "</td></tr>";
+
+ $o .= '<tr><td>WikiSoftware</td><td>ewiki '.EWIKI_VERSION."</td></tr>";
+ $o .= "</table>";
+
+ #-- more diagnosis
+ if (ini_get("magic_quotes")) {
+ $o.= "<b>Warning</b>: Your PHP interpreter has enabled the ugly and outdated '<i>magic_quotes</i>'. This will lead to problems, so please ask your provider to correct it; or fix it yourself with .htaccess settings as documented in the README. Otherwise don't forget to include() the <tt>fragments/strip_wonderful_slashes.php</tt> (it's ok to proceed for the moment).<br><br>";
+ }
+ if (ini_get("register_globals")) {
+ $o.= "<b>Security warning</b>: The horrible '<i>register_globals</i>' setting is enabled. Without always using <tt>fragments/strike_register_globals.php</tt> or letting your provider fix that, you could get into trouble some day.<br><br>";
+ }
+
+ return('<div class="wiki view WikiSetupWizard">' . $o . '</div>');
+ }
+
+
+ #-- actually initialize the database
+ else {
+ ewiki_database("INIT", array());
+ if ($dh = @opendir($path=EWIKI_INIT_PAGES)) {
+ while ($filename = readdir($dh)) {
+ if (preg_match('/^(['.EWIKI_CHARS_U.']+['.EWIKI_CHARS_L.']+\w*)+/', $filename)) {
+ $found = ewiki_database("FIND", array($filename));
+ if (! $found[$filename]) {
+ $content = implode("", file("$path/$filename"));
+ ewiki_scan_wikiwords($content, $ewiki_links, "_STRIP_EMAIL=1");
+ $refs = "\n\n" . implode("\n", array_keys($ewiki_links)) . "\n\n";
+ $save = array(
+ "id" => "$filename",
+ "version" => "1",
+ "flags" => "1",
+ "content" => $content,
+ "author" => ewiki_author("ewiki_initialize"),
+ "refs" => $refs,
+ "lastmodified" => filemtime("$path/$filename"),
+ "created" => filectime("$path/$filename") // (not exact)
+ );
+ ewiki_database("WRITE", $save);
+ }
+ }
+ }
+ closedir($dh);
+ }
+ else {
+ return("<b>ewiki error</b>: could not read from directory ". realpath($path) ."<br>\n");
+ }
+
+ #-- try to view/ that newly inserted page
+ if ($data = ewiki_database("GET", array("id"=>$id))) {
+ $action = "view";
+ }
+
+ #-- let ewiki_page() proceed as usual
+ return("");
+ }
+ }
+
+}
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/*
+ This plugin adds a page redirection feature. ewiki instantly switches
+ to another page, when one of the following markup snippets is found:
+
+ [jump:AnotherPage]
+ [goto:SwitchToHere]
+ or
+ [jump:WardsWiki:WelcomeVisitors]
+ [jump:Google:ErfurtWiki:MarioSalzer]
+ [jump:http://www.heise.de/]
+
+ One can also use [redirect:] or [location:]. Page switching only occours
+ with the "view" action. Sending a HTTP redirect is the default, but in
+ place redirects are also possible.
+ There exists a loop protection, which limits redirects to 5 (for browsers
+ that cannot detect this themselfes).
+*/
+
+#-- config
+define("EWIKI_JUMP_HTTP", 1); #-- issue a HTTP redirect, or jump in place
+define("EWIKI_UP_REDIRECT_COUNT", "redir");
+
+#-- text
+$ewiki_t["en"]["REDIRECTION_LOOP"] = "<h2>Redirection loop detected<h2>\nOperation stopped, because we're traped in an infinite redirection loop with page \$id.";
+
+#-- plugin glue
+$ewiki_plugins["handler"][] = "ewiki_handler_jump";
+$ewiki_config["interwiki"]["jump"] = "";
+$ewiki_config["interwiki"]["goto"] = "";
+
+
+function ewiki_handler_jump(&$id, &$data, &$action) {
+
+ global $ewiki_config;
+
+ static $redirect_count = 5;
+ $jump_markup = array("jump", "goto", "redirect", "location");
+
+ #-- we only care about "view" action
+ if ($action != "view") {
+ return;
+ }
+
+ #-- escape from loop
+ if (isset($_REQUEST["EWIKI_UP_REDIRECT_COUNT"])) {
+ $redirect_count = $_REQUEST["EWIKI_UP_REDIRECT_COUNT"];
+ }
+ if ($redirect_count-- <= 0) {
+ return(ewiki_t("REDIRECTION_LOOP", array("id"=>$id)));
+ }
+
+ #-- search for [jump:...]
+ if ($links = explode("\n", trim($data["refs"])))
+ foreach ($links as $link) {
+
+ if (strlen($link) && strpos($link, ":")
+ && in_array(strtolower(strtok($link, ":")), $jump_markup)
+ && ($dest = trim(strtok("\n"))) )
+ {
+ $url = "";
+ if (strpos($dest, "://")) {
+ $url = $dest;
+ }
+ else {
+ $url = ewiki_interwiki($dest);
+ }
+
+ #-- Location:
+ if (EWIKI_JUMP_HTTP && EWIKI_HTTP_HEADERS && !headers_sent()) {
+
+ if (empty($url)) {
+ $url = ewiki_script("", $dest,
+ array(EWIKI_UP_REDIRECT_COUNT=>$redirect_count),
+ 0, 0, ewiki_script_url()
+ );
+ }
+ header("Location: $url");
+ die();
+
+ }
+ #-- show page as usual, what will reveal dest URL
+ elseif ($url) {
+ return("");
+ # the rendering kernel will just show up the [jump:]!
+ # (without the jump: of course)
+ }
+ #-- it's simply about another WikiPage
+ else {
+
+ #-- we'll just restart ewiki
+ $data = array();
+ $id = $dest;
+ return(ewiki_page("view/".$id));
+ }
+ }
+ }#-search
+}
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+ require_once("../../config.php");
+ require_once("$CFG->dirroot/files/mimetypes.php");
+
+# this is the upload/download plugin, which allows to put arbitrary binary
+# files into the ewiki database using the provided specialized form, or the
+# standard image upload form below every edit page (if EWIKI_ALLOW_BINARY)
+
+
+#-- settings
+define("EWIKI_UPLOAD_MAXSIZE", 2*1024*1024);
+define("EWIKI_PAGE_UPLOAD", "FileUpload");
+define("EWIKI_PAGE_DOWNLOAD", "FileDownload");
+define("EWIKI_ACTION_ATTACHMENTS", "attachments"); #-- define to 0 to disable
+
+#-- register plugin (main part)
+$ewiki_plugins["page"][EWIKI_PAGE_UPLOAD] = "ewiki_page_fileupload";
+$ewiki_plugins["page"][EWIKI_PAGE_DOWNLOAD] = "ewiki_page_filedownload";
+$ewiki_plugins["action"]["binary"] = "ewiki_binary";
+
+#-- allow per-page downloads
+if (defined("EWIKI_ACTION_ATTACHMENTS") && EWIKI_ACTION_ATTACHMENTS) {
+ $ewiki_plugins["action"][EWIKI_ACTION_ATTACHMENTS] = "ewiki_action_attachments";
+ $ewiki_config["action_links"]["view"][EWIKI_ACTION_ATTACHMENTS] = "Attachments";
+}
+
+
+#-- icons (best given absolute to www root)
+/*$ewiki_binary_icons = array(
+ ".bin" => "/icons/exec.gif",
+ "application/" => "/icons/exec.gif",
+ "application/octet-stream" => "/icons/exec.gif",
+ ".ogg" => "/icons/son.gif",
+ ".jpeg" => "/icons/pic.gif",
+ "text/" => "/icons/txt.gif",
+ ".pdf" => "/icons/txt.gif",
+);*/
+
+
+#-- the upload function __can__ use different sections
+$ewiki_upload_sections = array(
+ "" => "main",
+# "section2" => "section2",
+);
+
+
+#-- text, translations
+$ewiki_t["en"]["UPLOAD0"] = "Use this form to upload an arbitrary binary file into the wiki:<br>";
+$ewiki_t["en"]["UPL_NEWNAM"] = "Save with different filename";
+$ewiki_t["en"]["UPL_INSECT"] = "Upload into section";
+$ewiki_t["en"]["UPL_TOOLARGE"] = "Your upload has been rejected, because that file was too large!";
+$ewiki_t["en"]["UPL_REJSECT"] = 'The given download section "$sect" has been rejected. Please only use the default ones, or tell the WikiAdmin to reenable per-page uploads; else others can\'t find your uploaded files easily.<br><br>';
+$ewiki_t["en"]["UPL_OK"] = "Your file was uploaded correctly, please see <a href=\"\$script".EWIKI_PAGE_DOWNLOAD."\">".EWIKI_PAGE_DOWNLOAD."</a>.<br><br>";
+$ewiki_t["en"]["UPL_ERROR"] = "We're sorry, but something went wrong during the file upload.<br><br>";
+$ewiki_t["en"]["DWNL_SEEUPL"] = 'See also <a href="$script'.EWIKI_PAGE_UPLOAD.'">FileUpload</a>, this page is only about downloading.<br><br>';
+$ewiki_t["en"]["DWNL_NOFILES"] = "No files uploaded yet.<br>\n";
+$ewiki_t["en"]["file"] = "File";
+$ewiki_t["en"]["of"] = "of";
+$ewiki_t["en"]["comment"] = "Comment";
+$ewiki_t["en"]["dwnl_section"] = "download section";
+$ewiki_t["en"]["DWNL_ENTRY_FORMAT"] =
+ '<div class="download"><a href="$url">$icon$title</a><small>$size<br>'.
+ 'uploaded on <b>$time</b>, downloaded <tt>$hits</tt> times<br>'.
+ '(<a href="$url">$id</a>)<br>'.
+ '$section'.'file is of type <tt>$type</tt>'.
+ '$comment'."</small></div><br>\n";
+
+$ewiki_t["de"]["UPLOAD0"] = "Mit diesem Formular kannst du beliebige Dateien in das Wiki abspeichern:<br>";
+$ewiki_t["de"]["UPL_NEWNAM"] = "Mit unterschiedlichem Dateinamen speichern";
+$ewiki_t["de"]["UPL_INSECT"] = "Hochladen in Bereich:";
+$ewiki_t["de"]["UPL_TOOLARGE"] = "Deine Datei wurde nicht aufgenommen, weil sie zu groß war!";
+$ewiki_t["de"]["UPL_REJSECT"] = 'Der angegebene Download-Bereich "$sect" wird nicht verwendet. Bitte verwende einen von den voreingestellten Bereichen, damit Andere die Datei später auch finden können, oder frag den Administrator das Hochladen für beliebige Seiten zu aktivieren.<br><br>';
+$ewiki_t["de"]["UPL_OK"] = "Deine Datei wurde korrekt hochgeladen, sehe einfach auf der <a href=\"\$script".EWIKI_PAGE_DOWNLOAD."\">".EWIKI_PAGE_DOWNLOAD."</a> nach.<br><br>";
+$ewiki_t["de"]["UPL_ERROR"] = "'Tschuldige, aber irgend etwas ist während des Hochladens gründlich schief gelaufen.<br><br>";
+$ewiki_t["de"]["DWNL_SEEUPL"] = 'Siehe auch <a href="$script'.EWIKI_PAGE_UPLOAD.'">DateiHochladen</a>, auf dieser Seite stehen nur die Downloads.<br><br>';
+$ewiki_t["de"]["DWNL_NOFILES"] = "Noch keine Dateien hochgeladen.<br>\n";
+$ewiki_t["de"]["file"] = "Datei";
+$ewiki_t["de"]["of"] = "von";
+$ewiki_t["de"]["comment"] = "Kommentar";
+$ewiki_t["de"]["dwnl_section"] = "Download Bereich";
+$ewiki_t["de"]["DWNL_ENTRY_FORMAT"] =
+ '<div class="download"><a href="$url">$icon$title</a><small>$size<br>'.
+ 'am <b>$time</b> hochgeladen, <tt>$hits</tt> mal abgerufen<br>'.
+ '(<a href="$url">$id</a>)<br>'.
+ '$section'.'Datei ist vom Typ <tt>$type</tt>'.
+ '$comment'."</small></div><br>\n";
+
+
+
+
+function ewiki_page_fileupload($id, $data, $action, $def_sec="") {
+
+ global $ewiki_upload_sections, $ewiki_plugins;
+
+ $o = ewiki_make_title($id, $id, 2);
+
+ $upload_file = $_FILES[EWIKI_UP_UPLOAD];
+ if (empty($upload_file)) {
+
+ $o .= ewiki_t("UPLOAD0");
+
+ $o .= '<div class="upload">'.
+ '<form action="' .
+ ewiki_script( ($action!="view" ? $action : ""), $id).
+ '" method="POST" enctype="multipart/form-data">' .
+ '<b>'.ewiki_t("file").'</b><br><input type="file" name="'.EWIKI_UP_UPLOAD.'"><br><br>' .
+ '<input type="submit" value="' . EWIKI_PAGE_UPLOAD . '"><br><br>';
+
+ $o .= '<b>' . ewiki_t("comment") . '</b><br><textarea name="comment" cols="35" rows="3"></textarea><br><br>';
+
+ if (empty($ewiki_upload_sections[$def_sec])) {
+ $ewiki_upload_sections[$def_sec] = $def_sec;
+ }
+ if (count($ewiki_upload_sections) > 1) {
+ if (empty($def_sec)) {
+ $def_sec = $_REQUEST["section"];
+ }
+ $o .= '<b>'.ewiki_t("UPL_INSECT").'</b><br><select name="section">';
+ foreach ($ewiki_upload_sections as $id => $title) {
+ $o .= '<option value="'.$id.'"' .($id==$def_sec?' selected':''). '>'.$title.'</option>';
+ }
+ $o .= '</select><br><br>';
+ }
+
+ $o .= '<b>'.ewiki_t("UPL_NEWNAM").'</b><br><input type="text" name="new_filename" size="20"><br><br>';
+
+ $o .= '</form></div>';
+
+ }
+ elseif ($upload_file["size"] > EWIKI_UPLOAD_MAXSIZE) {
+
+ $o .= ewiki_t("UPL_TOOLARGE");
+
+ }
+ else {
+
+ $meta = array(
+ "X-Content-Type" => $upload_file["type"],
+ #"X-Content-Length" => $upload_file["size"],
+ );
+ if (($s = $upload_file["name"]) && (strlen($s) >= 3)
+ || ($s = substr(md5(time()+microtime()),0,8) . ".dat"))
+ {
+ if (strlen($uu = trim($_REQUEST["new_filename"])) >= 3) {
+ if ($uu != $s) {
+ $meta["Original-Filename"] = $s;
+ }
+ $s = $uu;
+ }
+ $meta["Content-Location"] = $s;
+ ($p = 0) or
+ ($p = strrpos($s, "/")) and ($p++) or
+ ($p = strrpos($s, '\\')) and ($p++);
+ $meta["Content-Disposition"] = 'attachment; filename="'.urlencode(substr($s, $p)).'"';
+ }
+ if (strlen($sect = $_REQUEST["section"])) {
+ if ($ewiki_upload_sections[$sect]
+ || ($action==EWIKI_ACTION_ATTACHMENTS) && ($data["content"])
+ && strlen($ewiki_plugins["action"][EWIKI_ACTION_ATTACHMENTS])) {
+ $meta["section"] = $sect;
+ }
+ else {
+ $o .= ewiki_t("UPL_REJSECT", array('sect' => $sect));
+
+ return($o);
+ }
+ }
+ if (strlen($s = trim($_REQUEST["comment"]))) {
+ $meta["comment"] = $s;
+ }
+
+ $result = ewiki_binary_save_image($upload_file["tmp_name"], "", "RETURN", $meta, "ACCEPT_ALL", $care_for_images=0);
+
+ if ($result) {
+ $o .= ewiki_t("UPL_OK", array('$script'=>ewiki_script()));
+ }
+ else {
+ $o .= ewiki_t("UPL_ERROR");
+ }
+
+ }
+
+ return($o);
+}
+
+
+
+
+function ewiki_page_filedownload($id, $data, $action, $def_sec="") {
+
+ global $ewiki_binary_icons, $ewiki_upload_sections;
+
+ $o = ewiki_make_title($id, $id, 2);
+#<off># $o .= ewiki_t("DWNL_SEEUPL", '$scr'=>ewiki_script("", ""));
+
+
+ #-- params (section, orderby)
+ ($orderby = $_REQUEST["orderby"]) or ($orderby = "created");
+
+ if ($def_sec) {
+ $section = $def_sec;
+ }
+ else {
+ ($section = $_REQUEST["section"]) or ($section = "");
+ if (count($ewiki_upload_sections) > 1) {
+ $oa = array();
+ $ewiki_upload_sections["*"] = "*";
+ if (empty($ewiki_plugins["action"][EWIKI_ACTION_ATTACHMENTS])) {
+ $ewiki_upload_sections["**"] = "**";
+ }
+ foreach ($ewiki_upload_sections as $sec=>$title) {
+ $oa[] = '<a href="' . ewiki_script("", $id, array(
+ "orderby"=>$orderby, "section" => $sec)) .
+ '">' . $title . "</a>";
+ }
+ $o .= '<div align="center" class="darker">'.implode(" · ", $oa).'</div><br>';
+ }
+ }
+
+
+ #-- collect entries
+ $files = array();
+ $sorted = array();
+ $result = ewiki_database("GETALL", array("flags", "meta", "created", "hits"));
+
+ while ($row = $result->get()) {
+ if (($row["flags"] & EWIKI_DB_F_TYPE) == EWIKI_DB_F_BINARY) {
+
+ $m = &$row["meta"];
+ if(!$section) {
+ $section="**";
+ }
+ if ($m["section"] != $section) {
+ if ($section == "**") {
+ }
+ elseif (($section == "*") && !empty($ewiki_upload_sections[$m["section"]])) {
+ }
+ else {
+ continue;
+ }
+ }
+ else {
+ }
+
+ $files[$row["id"]] = $row;
+ $sorted[$row["id"]] = $row[$orderby];
+ }
+ }
+
+
+ #-- sort
+ arsort($sorted);
+
+
+ #-- slice
+ ($pnum = $_REQUEST[EWIKI_UP_PAGENUM]) or ($pnum = 0);
+ if (count($sorted) > EWIKI_LIST_LIMIT) {
+ $o_nl .= '<div class="lighter">>> ';
+ for ($n=0; $n < (int)(count($sorted) / EWIKI_LIST_LIMIT); $n++) {
+ $o_nl .= '<a href="' . ewiki_script("", $id, array(
+ "orderby"=>$orderby, "section"=>$section, EWIKI_UP_PAGENUM=>$n)) .
+ '">[' . $n . "]</a> ";
+ }
+ $o_nl .= '</div><br>';
+ $o .= $o_nl;
+ }
+ $sorted = array_slice($sorted, $pnum * EWIKI_LIST_LIMIT, EWIKI_LIST_LIMIT);
+
+
+ #-- output
+ if (empty($sorted)) {
+
+ $o .= ewiki_t("DWNL_NOFILES");
+ }
+ else {
+
+ foreach ($sorted as $id=>$uu) {
+ $row = $files[$id];
+ $o .= ewiki_entry_downloads($row, $section[0]=="*");
+ }
+ }
+
+ $o .= $o_nl;
+
+ return($o);
+
+}
+
+
+
+
+function ewiki_entry_downloads($row, $show_section=0) {
+
+ global $ewiki_binary_icons, $ewiki_upload_sections;
+
+ $meta = &$row["meta"];
+
+ $id = $row["id"];
+ $p_title = basename($meta["Content-Location"]);
+ $p_time = strftime("%c", $row["created"]);
+
+
+ $p_hits = ($row["hits"] ? $row["hits"] : "0");
+ $p_size = $meta["size"];
+ $p_size = isset($p_size) ? (", " . ($p_size>=4096 ? round($p_size/1024)."K" : $p_size." bytes")) : "";
+ $p_ct1 = $meta["Content-Type"];
+ $p_ct2 = $meta["X-Content-Type"];
+ if ($p_ct1==$p_ct2) { unset($p_ct2); }
+ if ($p_ct1 && !$p_ct2) { $p_ct = "<tt>$p_ct1</tt>"; }
+ elseif (!$p_ct1 && $p_ct2) { $p_ct = "<tt>$p_ct2</tt>"; }
+ elseif ($p_ct1 && $p_ct2) { $p_ct = "<tt>$p_ct1</tt>, <tt>$p_ct2</tt>"; }
+ else { $p_ct = "<tt>application/octet-stream</tt>"; }
+ $p_section = $ewiki_upload_sections[$meta["section"]];
+ $p_section = $p_section ? $p_section : $meta["section"];
+ $p_comment = strlen($meta["comment"]) ? '<table border="1" cellpadding="2" cellspacing="0"><tr><td class="lighter">'.
+ str_replace('</p>', '', str_replace('<p>', '',
+ ewiki_format($meta["comment"]))) . '</td></tr></table>' : "<br>";
+
+ $p_icon = "";
+ /*foreach ($ewiki_binary_icons as $str => $i) {
+ if (empty($str) || strstr($row["Content-Location"], $str) || strstr($p_ct, $str) || strstr($p_ct2, $str)) {
+ $p_icon = $i;
+ $p_icon_t = $str;
+ }
+ }*/
+
+ /// Moodle Icon Handling
+ global $CFG;
+ $icon = mimeinfo("icon", $id);
+ $p_icon="$CFG->pixpath/f/$icon";
+ $p_icon_t="";
+
+ $info->id = $id;
+ $info->size = $p_size;
+ $info->icon = ($p_icon ? '<img src="'.$p_icon.'" alt="['.$p_icon_t.']" align="left" width="14" height="14" border="0"> ' : '');
+ $info->time = $p_time;
+ $info->hits = $p_hits;
+ $info->section = ($show_section ? ewiki_t('dwnl_section') . ": $p_section<br>" : '');
+ $info->type = $p_ct;
+ $info->url = ewiki_script_binary("", $row["id"]);
+ $info->title = $p_title;
+ $info->comment = $p_comment;
+
+
+ $o .= '<a href="'.$info->url.'">'.$info->icon.$info->title.'</a>'.$info->size.'<br>'.
+ get_string("uploadedon","wiki").": ".$info->time.", ".get_string("downloadtimes","wiki",$info->hits)."<br>".
+ '(<a href="'.$info->url.'">'.$info->id."</a>)<br>".
+ $info->section." ".get_string("fileisoftype","wiki").": ".$info->type.
+ "$info->comment<br><br>";
+
+
+
+ ewiki_t("DWNL_ENTRY_FORMAT", $info);
+
+ return($o);
+}
+
+
+
+#------------------------------------------------------- per-page uploads ---
+
+
+function ewiki_action_attachments($id, $data, $action=EWIKI_ACTION_ATTACHMENTS) {
+
+ if (!empty($_FILES[EWIKI_UP_UPLOAD])) {
+ $o .= ewiki_page_fileupload($id, $data, EWIKI_ACTION_ATTACHMENTS, $id);
+ }
+
+ $o .= ewiki_page_filedownload(ucwords(EWIKI_ACTION_ATTACHMENTS) . " " . ewiki_t("of") . " $id", $data, "view", $id);
+
+ unset($_FILES[EWIKI_UP_UPLOAD]);
+ $o .= ewiki_page_fileupload($id, $data, EWIKI_ACTION_ATTACHMENTS, $id);
+
+ return($o);
+
+}
+
+
+?>
--- /dev/null
+<?php
+
+/*
+ This filter plugin implements minimal html tag balancing, and can also
+ convert ewiki_page() output into (hopefully) valid xhtml. It just works
+ around some markup problems found in ewiki and that may arise from Wiki
+ markup abuse; it however provides no fix for <ul> inside <ul> or even
+ <h2> inside <p> problems (this should rather be fixed in the ewiki_format
+ function). So following code is not meant to fix any possible html file,
+ and it certainly won't make valid html files out of random binary data.
+ So for full html spec conformance you should rather utilize w3c tidy (by
+ using your Webservers "Filter" directive).
+*/
+
+
+define("EWIKI_XHTML", 0);
+$ewiki_plugins["page_final"][] = "ewiki_html_tag_balancer";
+
+
+function ewiki_html_tag_balancer(&$html) {
+
+ #-- vars
+ $html_standalone = array(
+ "img", "br", "hr",
+ "input", "meta", "link",
+ );
+ $html_tags = array(
+ "a", "abbr", "acronym", "address", "applet", "area", "b", "base",
+ "basefont", "bdo", "big", "blockquote", "body", "br", "button",
+ "caption", "center", "cite", "code", "col", "colgroup", "dd", "del",
+ "dfn", "dir", "div", "dl", "dt", "em", "fieldset", "font", "form",
+ "h1", "h2", "h3", "h4", "h5", "h6", "head", "hr", "html", "i",
+ "iframe", "img", "input", "ins", "kbd", "label", "legend", "li",
+ "link", "map", "menu", "meta", "noframes", "noscript", "object", "ol",
+ "optgroup", "option", "p", "param", "pre", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "style", "sub", "sup",
+ "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "title",
+ "tr", "tt", "u", "ul", "var",
+ #-- H2.0 "nextid", "listing", "xmp", "plaintext",
+ #-- H3.2 "frame", "frameset",
+ #-- X1.1 "rb", "rbc", "rp", "rt", "rtc", "ruby",
+ );
+ $close_opened_when = array(
+ "p", "div", "ul", "td", "table", "tr",
+ );
+ if (!EWIKI_XHTML) {
+ $html_tags = array_merge( (array) $html_tags, array(
+ "bgsound", "embed", "layer", "multicol", "nobr", "noembed",
+ ));
+ }
+
+ #-- walk through all tags
+ $tree = array();
+ $len = strlen($html);
+ $done = "";
+ $pos = 0;
+ $loop = 1000;
+ while (($pos < $len) && $loop--) {
+
+ #-- search next tag
+ $l = strpos($html, "<", $pos);
+ $r = strpos($html, ">", $l);
+ if (($l===false) or ($r===false)) {
+ # finish
+ $done .= substr($html, $pos);
+ break;
+ }
+
+ #-- copy plain text part
+ if ($l >= $pos) {
+ $done .= substr($html, $pos, $l-$pos);
+ $pos = $l;
+ }
+
+ #-- analyze current html tag
+ if ($r >= $pos) {
+ $pos = $r + 1;
+ $tag = substr($html, $l + 1, $r - $l - 1);
+
+ #-- split into name and attributes
+ $tname = strtolower(strtok($tag, " \t\n>")); // LOWERCASING not needed here really
+ ($tattr = strtok(">")) && ($tattr = " $tattr");
+
+ // attribute checking could go here
+ // (here we just assume good output from ewiki core)
+ // ...
+
+ #-- html comment
+ if (substr($tname, 0, 3) == "!--") {
+ $r = strpos($html, "-->", $l+4);
+ $pos = $r + 3;
+ $done .= substr($html, $l, $r-$l+3);
+ continue;
+ }
+
+ #-- opening tag?
+ elseif ($tname[0] != "/") {
+
+ #-- standalone tag
+ if (in_array($tname, $html_standalone)) {
+ $tattr = rtrim(rtrim($tattr, "/"));
+ if (EWIKI_XHTML) {
+ $tattr .= " /";
+ }
+ }
+ #-- normal tag
+ else {
+ if (in_array($tname, $html_tags)) {
+ #-- ok
+ }
+ else {
+ #$tattr .= " class=\"$tname\"";
+ #$tname = "div";
+ }
+ array_push($tree, $tname);
+ }
+
+ $tag = "$tname$tattr";
+ }
+ #-- closing tag
+ else {
+ $tname = substr($tname, 1);
+
+ if (!in_array($tname, $html_tags)) {
+ $tname= "div";
+ }
+
+ #-- check if this is allowed
+ if (!$tree) {
+ continue; // ignore closing tag
+ }
+ $last = array_pop($tree);
+ if ($last != $tname) {
+
+ #-- close until last opened block element
+ if (in_array($tname, $close_opened_when)) {
+ do {
+ $done .= "</$last>";
+ }
+ while (($last = array_pop($tree)) && ($last!=$tname));
+ }
+ #-- close last, close current, reopen last
+ else {
+ array_push($tree, $last);
+ $done .= "</$last></$tname><$last>";
+ continue;
+ }
+ }
+ else {
+ #-- all ok
+ }
+
+ #-- readd closing-slash to tag name
+ $tag = "/$tname";
+ }
+
+ $done .= "<$tag>";
+ }
+ }
+
+ #-- close still open tags
+ while ($tree && ($last = array_pop($tree))) {
+ $done .= "</$last>";
+ }
+
+ #-- copy back changes
+ $html = $done;
+
+}
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/*
+ This plugin intercepts some of the binary handling functions to
+ store uploaded files (as is) into a dedicated directory.
+ Because the ewiki database abstraction layer was not designed to
+ hold large files (because it reads records in one chunk), you may need
+ to use this, else large files may break.
+
+ WARNING: this is actually a hack and not a database layer extension,
+ so it will only work with the ewiki.php script itself. The database
+ administration tools are not aware of this agreement and therefor
+ cannot (for example) backup the externally stored data files!
+ If you later choose to disable this extension, the uploaded (and thus
+ externally stored) files then cannot be accessed any longer, of course.
+
+ - You must load this plugin __before__ the main script, because the
+ binary stuff in ewiki.php always engages automatically.
+ - The store directory can be the same as for dbff (filenames differ).
+ - All the administration tools/ are not aware of this hack, so __you__
+ must take care, when it comes to creating backups.
+*/
+
+
+#-- config
+define("EWIKI_DB_STORE_DIRECTORY", "/tmp"); // where to save binary files
+define("EWIKI_DB_STORE_MINSIZE", 0); // send smaller files into db
+define("EWIKI_DB_STORE_MAXSIZE", 32 <<20); // 32MB max per file (but
+ // there is actually no way to upload such large files via HTTP)
+
+# define("EWIKI_DB_STORE_URL", "http://example.com/wiki/files/store/");
+ // allows clients to directly access stored plain data files,
+ // without redirection through ewiki.php, RTFM
+
+
+#-- glue
+$ewiki_plugins["binary_store"][] = "moodle_binary_store_file";
+$ewiki_plugins["binary_get"][] = "moodle_binary_store_get_file";
+
+
+function moodle_binary_get_path($id, $meta, $course, $wiki, $userid, $groupid) {
+ global $CFG;
+ $entry=wiki_get_entry($wiki, $course, $userid, $groupid);
+ if(!$entry) {
+ error("Cannot get entry.");
+ }
+
+ $dir=make_upload_directory("$course->id/$CFG->moddata/wiki/$wiki->id/$entry->id/".$meta["section"]);
+ if(substr($id, 0, strlen(EWIKI_IDF_INTERNAL))!=EWIKI_IDF_INTERNAL) {
+ error("Binary entry does not start with ".EWIKI_IDF_INTERNAL.":::".substr($id, 0, strlen(EWIKI_IDF_INTERNAL)));
+ }
+ $id = substr($id,11);
+ $id = clean_filename($id);
+
+ return "$dir/$id";
+}
+
+
+#-- upload
+function moodle_binary_store_file(&$filename, &$id, &$meta, $ext=".bin") {
+ # READ-Only
+ global $_FILES, $CFG, $course, $wiki, $groupid, $userid, $ewiki_title, $cm;
+ if(!$wiki->ewikiacceptbinary) {
+ error("This wiki does not accept binaries");
+ return 0;
+ }
+
+ $maxbytes = get_max_upload_file_size();
+
+ $entry=wiki_get_entry($wiki, $course, $userid, $groupid);
+ if(!$entry->id) {
+ error("Cannot get entry.");
+ }
+
+ $newfile = $_FILES["upload"];
+ if(!$id) {
+ $newfilename = clean_filename($newfile['name']);
+ $id = EWIKI_IDF_INTERNAL.$newfilename;
+ }
+ $dir=make_upload_directory("$course->id/$CFG->moddata/wiki/$wiki->id/$entry->id/$ewiki_title");
+ if ($maxbytes and $newfile['size'] > $maxbytes) {
+ return 0;
+ }
+ if (! $newfilename) {
+ notify("This file had a weird filename and couldn't be uploaded");
+ } else {
+ if (move_uploaded_file($filename, "$dir/$newfilename")) {
+ chmod("$dir/$newfilename", $CFG->directorypermissions);
+ $meta["binary_store"]=$ewiki_title;
+ $filename="";
+ return true;
+ } else {
+ notify("An error happened while saving the file on the server");
+ return false;
+ }
+ }
+ return false;
+
+
+/* if (($meta["size"] >= EWIKI_DB_STORE_MINSIZE) && ($meta["size"] <= EWIKI_DB_STORE_MAXSIZE)) {
+
+ #-- generate internal://md5sum
+ if (empty($id)) {
+ $md5sum = md5_file($filename);
+ $id = EWIKI_IDF_INTERNAL . $md5sum . ".$ext";
+ ewiki_log("generated md5sum '$md5sum' from file content");
+ }
+
+ #-- move file to dest. location
+ $dbfname = EWIKI_DB_STORE_DIRECTORY."/".rawurlencode($id);
+ if (@rename($filename, $dbfname) || copy($filename, $dbfname) && unlink($filename)) {
+ $filename = "";
+ $meta["binary_store"] = 1;
+ return(true);
+ }
+ else {
+ ewiki_log("file store error with '$dbfname'", 0);
+ }
+ }
+
+ return(false);*/
+}
+
+
+#-- download
+function moodle_binary_store_get_file($id, &$meta) {
+ # READ-Only
+ global $CFG, $cm, $course, $wiki, $groupid, $userid;
+
+ #-- check for file
+ if(!$wiki->ewikiacceptbinary) {
+ error("This wiki does not accept binaries");
+ return 0;
+ }
+
+
+ $filepath=moodle_binary_get_path($id, $meta, $course, $wiki, $userid, $groupid);
+ if (file_exists($filepath)) {
+ readfile($filepath);
+ return(true);
+ } else {
+ return(false);
+ }
+ //$dbfname = EWIKI_DB_STORE_DIRECTORY."/".rawurlencode($id);
+ //if (file_exists($dbfname)) {
+ // readfile($dbfname);
+ // return(true);
+ //}
+ //else {
+ // return(false);
+ //}
+
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/*
+ CSS-highlights the terms used as search patterns. This is done
+ by evaluating the REFERRER and using the QUERY_STRINGs "q="
+ parameter (which is used by Google and ewikis` PowerSearch).
+
+ Highlighting color should be controlled from CSS:
+
+ em.highlight {
+ color: red;
+ }
+
+ em.marker {
+ background: yellow;
+ }
+
+ Using this plugin costs you nearly nothing (not slower), because
+ there most often isn't a "?q=" from a search engine in the referer
+ url.
+*/
+
+
+
+$ewiki_plugins["page_final"][] = "ewiki_moodle_highlight";
+
+
+function ewiki_moodle_highlight(&$o, &$id, &$data, &$action) {
+
+ if (strpos($_SERVER["HTTP_REFERER"], "q=")) {
+
+ #-- PHP versions
+ $stripos = function_exists("stripos") ? "stripos" : "strpos";
+
+ #-- get ?q=...
+ $uu = $_SERVER["HTTP_REFERER"];
+ $uu = substr($uu, strpos($uu, "?"));
+ parse_str($uu, $q);
+ if ($q = $q["q"]) {
+
+ #-- get words out of it
+ $q = preg_replace('/[^-_\d'.EWIKI_CHARS_L.EWIKI_CHARS_U.']+/', " ", $q);
+ $q = array_unique(explode(" ", $q));
+ #-- walk through words
+ foreach ($q as $word) {
+
+ if (empty($word)) {
+ continue;
+ }
+
+ #-- search for word
+ while ($l = $stripos(strtolower($o), strtolower($word), $l)) {
+
+ #-- check for html-tags
+ $t0 = strpos($o, "<", $l);
+ $t1 = strpos($o, ">", $l);
+ if ((!$t0) || ($t0 < $t1)) {
+
+ $repl = '<em class="highlight marker">' . $word . '</em>';
+ $o = substr($o, 0, $l)
+ . $repl
+ . substr($o, 1 + $l + strlen($word)-1);
+
+ $l += strlen($repl);
+ }
+
+ $l++; // advance strpos
+ }
+
+ } // foreach(word)
+
+ }
+
+ } // if(q)
+
+} // func
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/*
+ Can be used to allow preserving of certain "safe" HTML <tags>
+ (as seen in [sfWiki | http://sfwiki.sf.net/].
+ "Safe" tags include Q, S, PRE, TT, H1-H6, KBD, VAR, XMP, B, I
+ but just see (or change) ewiki_format() for more. They are not
+ accepted if written with mixed lowercase and uppercase letters,
+ and they cannot contain any tag attributes.
+
+ RESCUE_HTML was formerly part of the main rendering function, but
+ has now been extracted into this plugin, so one only needs to
+ include it to get simple html tags working.
+*/
+
+
+$ewiki_plugins["format_source"][] = "ewiki_moodle_rescue_html";
+
+
+function ewiki_moodle_rescue_html(&$wiki_source) {
+ $safe_html = EWIKI_RESCUE_HTML;
+ $safe_html += 1;
+
+ $rescue_html = array(
+ "br", "tt", "b", "i", "strong", "em", "s", "kbd", "var", "xmp", "sup", "sub",
+ "pre", "q", "h1", "h2", "h3", "h4", "h5", "h6", "cite", "code", "u",
+ );
+
+
+
+ #-- unescape allowed html
+ if ($safe_html) {
+ /*
+ foreach ($rescue_html as $tag) {
+ foreach(array($tag, "/$tag", ($tag=strtoupper($tag)), "/$tag") as $tag) {
+ $wiki_source = str_replace('<'.$tag.'>', "<".$tag.">", $wiki_source);
+ } }
+ */
+ $regexp='#<(/?('.implode("|",$rescue_html).'))( /)?>#i';
+ $wiki_source = preg_replace($regexp, '<$1>', $wiki_source);
+ }
+
+}
+
+
+?>
--- /dev/null
+<?php
+
+/*
+ This plugin will create a sitemap rooted at the given location
+ Written By: Jeffrey Engleman
+*/
+
+define("EWIKI_PAGE_SITEMAP", "SiteMap");
+define("EWIKI_SITEMAP_DEPTH", 10);
+$ewiki_t["en"]["INVALIDROOT"] = "You are not authorized to access the current root page so no sitemap can be created.";
+$ewiki_t["en"]["SITEMAPFOR"] = "Site map for ";
+$ewiki_t["en"]["VIEWSMFOR"] = "View site map for ";
+$ewiki_plugins["page"][EWIKI_PAGE_SITEMAP]="ewiki_page_sitemap";
+$ewiki_plugins["action"]['sitemap']="ewiki_page_sitemap";
+
+if(!isset($ewiki_config["SiteMap"]["RootList"])){
+ $ewiki_config["SiteMap"]["RootList"]=array(EWIKI_PAGE_INDEX);
+}
+
+/*
+ populates an array with all sites the current user is allowed to access
+ calls the sitemap creation function.
+ returns the sitemap to be displayed.
+*/
+function ewiki_page_sitemap($id=0, $data=0, $action=0){
+ global $ewiki_config;
+
+ //**code hijacked from page_pageindex.php**
+ //creates a list of all of the valid wiki pages in the site
+ $str_null=NULL;
+
+ $a_validpages=ewiki_valid_pages(0,1);
+
+ //**end of hijacked code**
+ //$time_end=getmicrotime();
+
+ //creates the title bar on top of page
+ if($id == EWIKI_PAGE_SITEMAP){
+ $o = ewiki_make_title($id, $id, 2);
+
+ foreach($ewiki_config["SiteMap"]["RootList"] as $root){
+ if(isset($a_validpages[$root])){
+ $valid_root=TRUE;
+ $str_rootid=$root;
+ break;
+ }
+ }
+
+ }else{
+ $o = ewiki_make_title($id, ewiki_t("SITEMAPFOR")." ".$id, 2);
+ if(isset($a_validpages[$id])){
+ $valid_root=TRUE;
+ $str_rootid=$id;
+ }
+ }
+
+ $o .= "<p>".ewiki_t("VIEWSMFOR")." ";
+
+ foreach($ewiki_config["SiteMap"]["RootList"] as $root){
+ if(isset($a_validpages[$root])){
+ $o.='<a href="'.ewiki_script('sitemap/',$root).'">'.$root.'</a> ';
+ }
+ }
+
+ $o.="</p>";
+
+ //checks to see if the user is allowed to view the root page
+ if(!isset($a_validpages[$str_rootid])){
+ $o .= ewiki_t("INVALIDROOT");
+ return $o;
+ }
+
+ //$timesitemap=getmicrotime();
+ $a_sitemap=ewiki_sitemap_create($str_rootid, $a_validpages, EWIKI_SITEMAP_DEPTH);
+
+ $timer=array();
+ $level=-1;
+ $fordump=0;
+ $str_formatted="<ul>\n<li><a href=\"".EWIKI_SCRIPT.$str_rootid."\">".$str_rootid."</a></li>";
+ $fin_level=format_sitemap($a_sitemap, $str_rootid, $str_formatted, $level, $timer, $fordump);
+ $str_formatted.="</ul>".str_pad("", $fin_level*6, "</ul>\n");
+ $o.=$str_formatted;
+
+ //$timesitemap_end=getmicrotime();
+
+ //$o.="GetAll: ".($time_end-$time)."\n";
+ //$o.="SiteMap: ".($timesitemap_end-$timesitemap)."\n";
+ //$o.="Total: ".($timesitemap_end-$time);
+
+
+ return($o);
+
+}
+
+function ewiki_valid_pages($bool_allowimages=0, $virtual_pages=0){
+ //$time=getmicrotime();
+ global $ewiki_plugins;
+ $result = ewiki_database("GETALL", array("flags", "refs", "meta"));
+ while ($row = $result->get()) {
+ if (EWIKI_PROTECTED_MODE && EWIKI_PROTECTED_MODE_HIDING && !ewiki_auth($row["id"], $str_null, "view")) {
+ continue;
+ }
+ if (($row["flags"] & EWIKI_DB_F_TYPE) == EWIKI_DB_F_TEXT || ($bool_allowimages ? $row["meta"]["class"]=="image" : 0)) {
+ $temp_refs=explode("\n",$row["refs"]);
+ foreach($temp_refs as $key => $value) {
+ if(empty($value)) {
+ unset($temp_refs[$key]);
+ }
+ }
+ if($row["meta"]["class"]=="image"){
+ $a_validpages[$row["id"]]=$temp_array=array("refs" => $temp_refs, "type" => "image", "touched" => FALSE);
+ } else {
+ $a_validpages[$row["id"]]=$temp_array=array("refs" => $temp_refs, "type" => "page", "touched" => FALSE);
+ }
+ unset($temp_refs);
+ }
+ }
+
+ if($virtual_pages){
+ #-- include virtual pages to the sitemap.
+ $virtual = array_keys($ewiki_plugins["page"]);
+ foreach($virtual as $vp){
+ if(!EWIKI_PROTECTED_MODE || !EWIKI_PROTECTED_MODE_HIDING || ewiki_auth($vp, $str_null, "view")){
+ $a_validpages[$vp]=array("refs" => array(), "type" => "page", "touched" => FALSE);
+ }
+ }
+ }
+ return $a_validpages;
+}
+
+/*
+ Adds each of the pages in the sitemap to an HTML list. Each site is a clickable link.
+*/
+function format_sitemap($a_sitemap, $str_rootpage, &$str_formatted, &$prevlevel, &$timer, &$fordump){
+
+ //get all children of the root format them and store in $str_formatted array
+ $a_sitemap[$str_rootpage]["child"]= is_array($a_sitemap[$str_rootpage]["child"])?$a_sitemap[$str_rootpage]["child"]:array();
+ if($a_sitemap[$str_rootpage]["child"]){
+ while($str_child = current($a_sitemap[$str_rootpage]["child"])){
+ $str_mark="";
+ if($a_sitemap[$str_rootpage]["level"]>$prevlevel){
+ $str_mark="<ul>\n";
+ }
+ elseif ($a_sitemap[$str_rootpage]["level"]<$prevlevel){
+ //markup length is 6 characters
+ $str_mark=str_pad("", ($prevlevel-$a_sitemap[$str_rootpage]["level"])*6, "</ul>\n");
+ }
+ $prevlevel=$a_sitemap[$str_rootpage]["level"];
+ if($fordump){
+ $str_formatted.=($str_mark."<li><a href=\"".preg_replace(EWIKI_DUMP_FILENAME_REGEX, "", urlencode($str_child)).".html\">".$str_child."</a></li>\n");
+ } else {
+ $str_formatted.=($str_mark."<li><a href=\"".EWIKI_SCRIPT.$str_child."\">".$str_child."</a></li>\n");
+ }
+ array_shift($a_sitemap[$str_rootpage]["child"]);
+ format_sitemap($a_sitemap, $str_child, $str_formatted, $prevlevel, $timer, $fordump);
+ }
+ return ($prevlevel+1);
+ }
+}
+
+
+/*
+ gets all children of the given root and stores them in the $a_children array
+*/
+function ewiki_page_listallchildren($str_root, &$a_children, &$a_sitemap, &$a_validpages, $i_level, $i_maxdepth, $i_flatmap){
+ if(($i_level<$i_maxdepth) && is_array($a_validpages[$str_root]["refs"])){ //controls depth the sitemap will recurse into
+ foreach($a_validpages[$str_root]["refs"] as $str_refs){
+ if($str_refs){ //make sure $str_refs contains a value before doing anything
+ if(isset($a_validpages[$str_refs])){ //test page validity
+ if(!$a_validpages[$str_refs]["touched"]){ //check to see if page already exists
+ if($i_flatmap){
+ $a_sitemap[]=$str_refs;
+ }
+ $a_validpages[$str_refs]["touched"]=TRUE; //mark page as displayed
+ $a_children[$str_refs]="";
+ $a_currchildren[]=$str_refs;
+ }
+ }
+ }
+ }
+ if(!$i_flatmap){
+ if($a_currchildren){
+ $a_sitemap[$str_root]=array("level" => $i_level, "child" => $a_currchildren);
+ } else {
+ $a_sitemap[$str_root]=array("level" => $i_level);
+ }
+ }
+ }
+}
+
+
+/*
+ Creates the sitemap. And sends the data to the format_sitemap function.
+ Returns the HTML formatted sitemap.
+*/
+function ewiki_sitemap_create($str_rootid, $a_validpages, $i_maxdepth, $i_flatmap=0){
+ //map starts out with a depth of 0
+ $i_depth=0;
+ $forcelevel=FALSE;
+
+ //create entry for root in the sitemap array
+ if(!$i_flatmap){
+ $a_sitemap[$str_rootid]=array("parent" => "", "level" => $i_depth, "child" => $str_rootid);
+ } else {
+ $a_sitemap[]=$str_rootid;
+ }
+ //mark the root page as touched
+ $a_validpages[$str_rootid]["touched"]=TRUE;
+ //list all of the children of the root
+ ewiki_page_listallchildren($str_rootid, $a_children, $a_sitemap, $a_validpages, $i_depth, $i_maxdepth, $i_flatmap);
+ $i_depth++;
+
+ if($a_children){
+ end($a_children);
+ $str_nextlevel=key($a_children);
+ reset($a_children);
+
+ while($str_child = key($a_children)){
+ //list all children of the current child
+ ewiki_page_listallchildren($str_child, $a_children, $a_sitemap, $a_validpages, $i_depth, $i_maxdepth, $i_flatmap);
+
+ //if the child is the next level marker...
+ if($str_child==$str_nextlevel){
+ //increment the level counter
+ $i_depth++;
+ //determine which child marks the end of this level
+ end($a_children);
+ $str_nextlevel=key($a_children);
+ //reset the array counter to the beginning of the array
+ reset($a_children);
+ //we are done with this child...get rid of it
+ }
+ array_shift($a_children);
+ }
+ }
+
+ return $a_sitemap;
+}
+?>
--- /dev/null
+<?php
+
+# lists pages, which were referenced
+# but not yet written
+
+
+$ewiki_plugins["page"]["WantedPages"] = "ewiki_page_wantedpages";
+#<off># $ewiki_plugins["page"]["DanglingSymlinks"] = "ewiki_page_wantedpages";
+
+
+function ewiki_page_wantedpages($id, $data, $action) {
+ $wanted=array();
+ #-- collect referenced pages
+ $result = ewiki_database("GETALL", array("refs"));
+ while ($row = $result->get()) {
+ if (EWIKI_PROTECTED_MODE && EWIKI_PROTECTED_MODE_HIDING && !ewiki_auth($row["id"], $uu, "view")) {
+ continue;
+ }
+ $refs .= $row["refs"];
+ }
+
+ #-- build array
+ $refs = array_unique(explode("\n", $refs));
+
+ #-- strip existing pages from array
+ $refs = ewiki_database("FIND", $refs);
+ foreach ($refs as $id=>$exists) {
+ if (EWIKI_PROTECTED_MODE && EWIKI_PROTECTED_MODE_HIDING && !ewiki_auth($row["id"], $uu, "view")) {
+ continue;
+ }
+ if (!$exists && !strstr($id, "://") && strlen(trim($id))) {
+ $wanted[] = $id;
+ }
+ }
+
+ #-- print out
+ $o .= "<ul>";
+ foreach ($wanted as $page) {
+
+ $link = ewiki_link_regex_callback(array($page, $page));
+
+ if (strstr($link, "?</a>")) {
+ $o .= "<li>" . $link . "</li>";
+ }
+
+ }
+ $o .= "<ul>";
+
+ return($o);
+}
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+#
+# The otherwise invisible markup [notify:you@there.net] will trigger a
+# mail, whenever a page is changed. The TLD decides in which language
+# the message will be delivered. One can also append the lang code after
+# a comma or semicolon behind the mail address to set it explicitely:
+# [notify:me@here.org,de] or [notify:you@there.net;eo]
+#
+# Nevertheless English will be used as the default automagically, if
+# nothing else was specified, no need to worry about this.
+#
+# additional features:
+# * diff inclusion
+# * [notify:icq:123456789] - suddenly ICQ.com took the pager service down
+#
+# To include a diff, just set the following constant. Also use it to
+# define the minimum number of changed bytes that are necessary to
+# result in a notification mail. Only use it with Linux/UNIX.
+
+define("EWIKI_NOTIFY_WITH_DIFF", 0); #-- set it to 100 or so
+define("EWIKI_NOTIFY_SENDER",'ewiki');
+
+
+#-- glue
+$ewiki_plugins["edit_hook"][] = "ewiki_notify_edit_hook";
+$ewiki_plugins["format_source"][] = "ewiki_format_remove_notify";
+$ewiki_config["interwiki"]["notify"] = "mailto:";
+
+
+#-- email message text ---------------------------------------------------
+$ewiki_t["en"]["NOTIFY_SUBJECT"] = '"$id" was changed [notify:...]';
+$ewiki_t["en"]["NOTIFY_BODY"] = <<<_END_OF_STRING
+Hi,
+
+A WikiPage has changed and you requested to be notified when this
+happens. The changed page was '\$id' and can be found
+at the following URL:
+\$link
+
+To stop messages like this please strip the [notify:...] with your address
+from the page edit box at \$edit_link
+
+(\$wiki_title on http://\$server/)
+\$server_admin
+_END_OF_STRING;
+
+
+#-- translation.de
+$ewiki_t["de"]["NOTIFY_SUBJECT"] = '"$id" wurde geändert [notify:...]';
+$ewiki_t["de"]["NOTIFY_BODY"] = <<<_END_OF_STRING
+Hi,
+
+Eine WikiSeite hat sich geändert, und du wolltest ja unbedingt wissen,
+wenn das passiert. Die geänderte Seite war '\$id' und
+ist leicht zu finden unter folgender URL:
+\$link
+
+Wenn du diese Benachrichtigungen nicht mehr bekommen willst, solltest du
+deine [notify:...]-Adresse aus der entsprechenden Edit-Box herauslöschen:
+\$edit_link
+
+(\$wiki_title auf http://\$server/)
+\$server_admin
+_END_OF_STRING;
+
+
+#----------------------------------------------------------------------------
+
+
+
+#-- implementatition
+function ewiki_notify_edit_hook($id, $data, &$hidden_postdata) {
+
+ global $ewiki_t, $ewiki_plugins;
+ $ret_err = 0;
+
+ if (!isset($_REQUEST["save"])) {
+ return(false);
+ }
+
+ $mailto = ewiki_notify_links($data["content"], 0);
+
+ if (!count($mailto)) {
+ return(false);
+ }
+
+ #-- generate diff
+ $diff = "";
+ if (EWIKI_NOTIFY_WITH_DIFF && (DIRECTORY_SEPARATOR=="/")) {
+
+ #-- save page versions temporarily as files
+ $fn1 = EWIKI_TMP."/ewiki.tmp.notify.diff.".md5($data["content"]);
+ $fn2 = EWIKI_TMP."/ewiki.tmp.notify.diff.".md5($_REQUEST["content"]);
+ $f = fopen($fn1, "w");
+ fwrite($f, $data["content"]);
+ fclose($f);
+ $f = fopen($fn2, "w");
+ fwrite($f, $_REQUEST["content"]);
+ fclose($f);
+ #-- set mtime of the old one (GNU diff will report it)
+ touch($fn1, $data["lastmodified"]);
+
+ #-- get diff output, rm temp files
+ $diff_exe = "diff";
+ if ($f = popen("$diff_exe --normal --ignore-case --ignore-space-change $fn1 $fn2 2>&1 ", "r")) {
+
+ $diff .= fread($f, 16<<10);
+ pclose($f);
+
+ $diff_failed = !strlen($diff)
+ || (strpos($diff, "Files ") === 0);
+
+ #-- do not [notify:] if changes were minimal
+ if ((!$diff_failed) && (strlen($diff) < EWIKI_NOTIFY_WITH_DIFF)) {
+#echo("WikiNotice: no notify, because too few changes (" .strlen($diff)." byte)\n");
+ $ret_err = 1;
+ }
+
+ $diff = "\n\n-----------------------------------------------------------------------------\n\n"
+ . $diff;
+ }
+ else {
+ $diff = "";
+#echo("WikiWarning: diff failed in notify module\n");
+ }
+
+ unlink($fn1);
+ unlink($fn2);
+
+ if ($ret_err) {
+ return(false);
+ }
+ }
+
+ #-- separate addresses into (TLD) groups
+ $mailto_lang = array(
+ );
+ foreach ($mailto as $m) {
+
+ $lang = "";
+
+ #-- remove lang selection trailer
+ $m = strtok($m, ",");
+ if ($uu = strtok(",")) {
+ $lang = $uu;
+ }
+ $m = strtok($m, ";");
+ if ($uu = strtok(";")) {
+ $lang = $uu;
+ }
+
+ #-- else use TLD as language code
+ if (empty($lang)) {
+ $r = strrpos($m, ".");
+ $lang = substr($m, $r+1);
+ }
+ $lang = trim($lang);
+
+ #-- address mangling
+ $m = trim($m);
+ if (substr($m, 0, 4) == "icq:") {
+ $m = substr($m, 4) . "@pager.icq.com";
+ }
+
+ $mailto_lang[$lang][] = $m;
+ }
+
+ #-- go thru email address groups
+ foreach ($mailto_lang as $lang=>$a_mailto) {
+
+ $pref_langs = array_merge(array(
+ "$lang", "en"
+ ), $ewiki_t["languages"]);
+
+ ($server = $_SERVER["HTTP_HOST"]) or
+ ($server = $_SERVER["SERVER_NAME"]);
+ $s_4 = "http".($_SERVER['HTTPS'] == "on" ? 's':'')."://" . $server . $_SERVER["REQUEST_URI"];
+ $link = str_replace("edit/$id", "$id", $s_4);
+
+ $m_text = ewiki_t("NOTIFY_BODY", array(
+ "id" => $id,
+ "link" => $link,
+ "edit_link" => $s_4,
+ "server_admin" => $_SERVER["SERVER_ADMIN"],
+ "server" => $server,
+ "wiki_title" => EWIKI_PAGE_INDEX,
+ ), $pref_langs);
+ $m_text .= $diff;
+
+ $m_from = EWIKI_NOTIFY_SENDER."@$server";
+ $m_subject = ewiki_t("NOTIFY_SUBJECT", array(
+ "id" => $id,
+ ), $pref_langs);
+
+ $m_to = implode(", ", $a_mailto);
+
+ mail($m_to, $m_subject, $m_text, "From: \"$s_2\" <$m_from>\nX-Mailer: ErfurtWiki/".EWIKI_VERSION);
+
+ }
+}
+
+
+
+function ewiki_notify_links(&$source, $strip=1) {
+ $links = array();
+ $l = 0;
+ if (strlen($source) > 10)
+ while (($l = @strpos($source, "[notify:", $l)) !== false) {
+ $r = strpos($source, "]", $l);
+ $str = substr($source, $l, $r + 1 - $l);
+ if (!strpos("\n", $str)) {
+ $links[] = trim(substr($str, 8, -1));
+ if ($strip) {
+ $source = substr($source, 0, $l) . substr($source, $r + 1);
+ }
+ }
+ $l++;
+ }
+ return($links);
+}
+
+
+
+function ewiki_format_remove_notify(&$source) {
+ ewiki_notify_links($source, 1);
+}
+
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/*
+ This plugin catches concurrent edits of a page, and lets the 'patch'
+ and 'diff' utilities try to merge the different versions. This will
+ often prevent the "This page version was already saved by someone else"
+ failure message.
+ Please use the GNU diff and patch only. Sometimes the unified output
+ format may be superiour; but this depends on the subjects in your Wiki.
+*/
+
+define("EWIKI_BIN_DIFF", "/usr/bin/diff");
+define("EWIKI_BIN_PATCH", "/usr/bin/patch");
+
+if (function_exists("is_executable") && is_executable(EWIKI_BIN_PATCH) && is_executable(EWIKI_BIN_DIFF)) {
+ $ewiki_plugins["edit_patch"][] = "ewiki_edit_patch";
+}
+
+
+function ewiki_edit_patch($id, &$data) {
+
+ $r = false;
+
+ $base = ewiki_database(
+ "GET",
+ array("id"=>$id, "version"=>$_REQUEST["version"])
+ );
+ if (!$base) {
+ return(false);
+ }
+
+ $fn_base = EWIKI_TMP."/ewiki.base.".md5($base["content"]);
+ $fn_requ = EWIKI_TMP."/ewiki..requ.".md5($_REQUEST["content"]);
+ $fn_patch = EWIKI_TMP."/ewiki.patch.".md5($base["content"])."-".md5($_REQUEST["content"]);
+ $fn_curr = EWIKI_TMP."/ewiki.curr.".md5($data["content"]);
+
+ if ($f = fopen($fn_base, "w")) {
+ fwrite($f, $base["content"]);
+ fclose($f);
+ }
+ else {
+ return(false);
+ }
+
+ if ($f = fopen($fn_requ, "w")) {
+ fwrite($f, $_REQUEST["content"]);
+ fclose($f);
+ }
+ else {
+ unlink($fn_base);
+ return(false);
+ }
+
+ if ($f = fopen($fn_curr, "w")) {
+ fwrite($f, $data["content"]);
+ fclose($f);
+ }
+ else {
+ unlink($fn_base);
+ unlink($fn_requ);
+ return(false);
+ }
+
+ exec("diff -c $fn_base $fn_requ > $fn_patch", $output, $retval);
+ if ($retval) {
+
+ exec("patch $fn_curr $fn_patch", $output, $retval);
+ if (!$retval) {
+
+ $_REQUEST["version"] = $curr["version"];
+ $_REQUEST["content"] = implode("", file($fn_curr));
+ $r = true;
+
+ }
+ }
+
+ unlink($fn_base);
+ unlink($fn_requ);
+ unlink($fn_patch);
+ unlink($fn_curr);
+
+ return($r);
+}
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/*
+ dynamic plugin loading
+ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
+ Will load plugins on demand, so they must not be included() one by one
+ together with the core script. This is what commonly the "plugin idea"
+ suggests, and only has minimal disadvantages.
+ - This loader currently only handles "page" and "action" plugins,
+ many other extensions must be activated as before (the other ones
+ are real functionality enhancements and behaviour tweaks, so this
+ approach really made no sense for them).
+ - There is no security risk with this plugin loader extension, because
+ it allows you to set which of the available plugins CAN be loaded
+ on demand (all others must/can be included() as usual elsewhere).
+ - This however requires administration of this plugins` configuration
+ array, but that is not much more effort than maintaining a bunch of
+ include() statements.
+ - Is a small degree faster then including multiple plugin script files
+ one by one. Alternatively you could also merge (cat, mkhuge) all
+ wanted plugins into one script file so you get a speed improvement
+ against multiple include() calls.
+ - Use tools/mkpluginmap to create the initial plugin list.
+*/
+
+
+
+$ewiki_plugins["dl"]["action"] = array(
+ "view" => array("", "", 0),
+ "links" => array("", "", 0),
+ "info" => array("", "", 0),
+# "edit" => array("spellcheck.php", "", 0),
+# "calendar" => array("calendar.php", "ewiki_page_calendar", 0),
+# "addpost" => array("contrib/aview_posts.php", "ewiki_add_post", 0),
+# "imageappend" => array("contrib/aview_imgappend.php", "ewiki_action_image_append", 0),
+# "extodo" => array("contrib/action_extracttodo.php", "ewiki_extract_todo", 0),
+# "addthread" => array("contrib/aview_threads.php", "ewiki_add_thread", 0),
+# "control" => array("admin/control.php", "ewiki_action_control_page", 0),
+# "pdf" => array("pdf.php", "ewiki_send_page_as_pdf", 0),
+ "diff" => array("diff.php", "ewiki_page_stupid_diff", 0),
+# "diff" => array("diff_gnu.php", "ewiki_page_gnu_diff", 0),
+# "binary" => array("downloads.php", "ewiki_binary", 0),
+# "attachments" => array("downloads.php", "ewiki_action_attachments", 0),
+ "like" => array("like_pages.php", "ewiki_page_like", 0),
+# "verdiff" => array("action_verdiff.php", "ewiki_action_verdiff", 0),
+);
+
+$ewiki_plugins["dl"]["page"] = array(
+# "PageCalendar" => array("calendar.php", "ewiki_page_calendar", 0),
+# "PageYearCalendar" => array("calendar.php", "ewiki_page_year_calendar", 0),
+# "WikiNews" => array("contrib/page_wikinews.php", "ewiki_page_wikinews", 0),
+# "WikiDump" => array("contrib/page_wikidump.php", "ewiki_page_wiki_dump_tarball", 0),
+# "README" => array("contrib/page_README.php", "ewiki_page_README", 0),
+# "README.de" => array("contrib/page_README.php", "ewiki_page_README", 0),
+# "plugins/auth/README.auth" => array("contrib/page_README.php", "ewiki_page_README", 0),
+# "Fortune" => array("contrib/page_fortune.php", "ewiki_page_fortune", 0),
+# "ScanDisk" => array("contrib/page_scandisk.php", "ewiki_page_scandisk", 0),
+ "InterWikiMap" => array("contrib/page_interwikimap.php", "ewiki_page_interwikimap", 0),
+# "WikiUserLogin" => array("contrib/page_wikiuserlogin.php", "ewiki_page_wikiuserlogin", 0),
+# "PhpInfo" => array("contrib/page_phpinfo.php", "ewiki_page_phpinfo", 0),
+# "ImageGallery" => array("contrib/page_imagegallery.php", "ewiki_page_image_gallery", 0),
+# "SinceUpdatedPages" => array("contrib/page_since_updates.php", "ewiki_page_since_updates", 0),
+# "TextUpload" => array("contrib/page_textupload.php", "ewiki_page_textupload", 0),
+ "HitCounter" => array("contrib/page_hitcounter.php", "ewiki_page_hitcounter", 0),
+# "SearchCache" => array("admin/page_searchcache.php", "ewiki_cache_generated_pages", 0),
+# "SearchAndReplace" => array("admin/page_searchandreplace.php", "ewiki_page_searchandreplace", 0),
+# "FileUpload" => array("downloads.php", "ewiki_page_fileupload", 0),
+# "FileDownload" => array("downloads.php", "ewiki_page_filedownload", 0),
+ "PowerSearch" => array("page_powersearch.php", "ewiki_page_powersearch", 0),
+# "AboutPlugins" => array("page_aboutplugins.php", "ewiki_page_aboutplugins", 0),
+ "OrphanedPages" => array("page_orphanedpages.php", "ewiki_page_orphanedpages", 0),
+ "PageIndex" => array("page_pageindex.php", "ewiki_page_index", 0),
+ "RandomPage" => array("page_randompage.php", "ewiki_page_random", 0),
+ "WantedPages" => array("page_wantedpages.php", "ewiki_page_wantedpages", 0),
+ "WordIndex" => array("page_wordindex.php", "ewiki_page_wordindex", 0),
+);
+
+
+#-- plugin glue
+$ewiki_plugins["view_init"][] = "ewiki_dynamic_plugin_loader";
+
+
+function ewiki_dynamic_plugin_loader(&$id, &$data, &$action) {
+
+ global $ewiki_plugins, $ewiki_id, $ewiki_title, $ewiki_t,
+ $ewiki_ring, $ewiki_author, $ewiki_config, $ewiki_auth_user,
+ $ewiki_action;
+
+ #-- check for entry
+ if (empty($ewiki_plugins["page"][$id])) {
+ $load = $ewiki_plugins["dl"]["page"][$id];
+ }
+ elseif (empty($ewiki_plugins["action"][$action])) {
+ $load = $ewiki_plugins["dl"]["action"][$action];
+ }
+
+ #-- load plugin
+ if ($load) {
+ if (!is_array($load)) {
+ $load = array($load, "");
+ }
+ if (!($pf=$load[1]) || !function_exists($pf)) {
+ include(dirname(__FILE__)."/".$load[0]);
+ }
+ }
+
+ #-- fake static pages
+ foreach ($ewiki_plugins["dl"]["page"] as $name) {
+ if (empty($ewiki_plugins["page"][$name])) {
+ $ewiki_plugins["page"][$name] = "ewiki_dynamic_plugin_loader";
+ }
+ }
+
+ #-- show action links
+ foreach ($ewiki_plugins["dl"]["action"] as $action=>$uu) {
+ foreach ($ewiki_config["dl"]["action_links"] as $where) {
+ if ($title = $ewiki_config["dl"]["action_links"][$where][$action]) {
+ $ewiki_config["action_links"][$where][$action] = $title;
+ }
+ }
+ }
+
+ return(NULL);
+}
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/*
+ The StaticPages plugin allows you to put some .html or .php files
+ into dedicated directories, which then will get available with their
+ basename as ewiki pages. The files can be in wiki format (.txt or no
+ extension), they can also be in .html format and they may even contain
+ php code (.php).
+
+ Of course it is not possible to provide anything else, than viewing
+ those pages (editing is not possible), but it is of course up to you
+ to add php code to achieve some interactivity.
+ The idea for this plugin was 'borought' from http://geeklog.org/.
+
+ In your static page .php files you cannot do everything you could
+ normally do, there are some restrictions because of the way these static
+ pages are processed. You need to use $GLOBALS to access variables other
+ than the $ewiki_ ones. To return headers() you must append them to the
+ $headers[] or $ewiki_headers[] array.
+
+ If you define("EWIKI_SPAGES_DIR") then this directory will be read
+ initially, but you could also just edit the following list/array of
+ directories, or call ewiki_init_spages() yourself.
+*/
+
+
+#-- specify which dirs to search for page files
+ewiki_init_spages(
+ array(
+ "spages",
+ # "/usr/local/share/wikipages",
+ # "C:/Documents/StaticPages/",
+ )
+);
+if (defined("EWIKI_SPAGES_DIR")) {
+ ewiki_init_spages(EWIKI_SPAGES_DIR);
+}
+
+
+#-- plugin glue
+# - will be added automatically by _init_spages()
+
+
+#-- return page
+function ewiki_spage($id, $data, $action) {
+
+ global $ewiki_spages, $ewiki_plugins;
+
+ $r = "";
+
+ #-- filename from $id
+ $fn = $ewiki_spages[strtolower($id)];
+
+ #-- php file
+ if (strpos($fn, ".php") || strpos($fn, ".htm")) {
+
+ #-- start new ob level
+ ob_start();
+ ob_implicit_flush(0);
+
+ #-- prepare environment
+ global $ewiki_id, $ewiki_title, $ewiki_author, $ewiki_ring,
+ $ewiki_t, $ewiki_config, $ewiki_action, $_EWIKI,
+ $ewiki_auth_user, $ewiki_headers, $headers;
+ $ewiki_headers = array();
+ $headers = &$ewiki_headers;
+
+ #-- execute script
+ include($fn);
+
+ #-- close ob
+ $r = ob_get_contents();
+ ob_end_clean();
+
+ #-- add headers
+ if ($ewiki_headers) {
+ headers(implode("\n", $ewiki_headers));
+ }
+ }
+
+ #-- wiki file
+ else {
+
+ $f = fopen($fn, "rb");
+ $r = fread($f, 256<<10);
+ fclose($f);
+
+ $r = $ewiki_plugins["render"][0]($r);
+ }
+
+ #-- strip <html> and <head> parts (if any)
+ if (($l = strpos(strtolower($r), "<body")) &&
+ ($w = strpos(strtolower($r), "</body")) )
+ {
+ $l = strpos($r, ">", $l+1) + 1;
+ $w = $w - $l;
+ $r = substr($r, $l, $w);
+ }
+
+ #-- return body (means successful handled)
+ return($r);
+
+}
+
+
+
+#-- return page
+#<old># $ewiki_plugins["handler"][] = "ewiki_handler_spages";
+function ewiki_handler_spages($id, $data, $action) {
+
+ global $ewiki_spages;
+
+ #-- compare requested page $id with spages` $id values
+ $i0 = strtolower($id);
+ foreach ($ewiki_spages as $i1 => $fn) {
+ if (strtolower($i1)==$i0) {
+
+ return(ewiki_spage($id));
+
+ }
+ }
+
+}
+
+
+#-- init
+function ewiki_init_spages($dirs, $idprep="") {
+
+ global $ewiki_spages, $ewiki_plugins;
+
+ if (!is_array($dirs)) {
+ $dirs = array($dirs);
+ }
+
+ #-- go through list of directories
+ foreach ($dirs as $dir) {
+
+ if (empty($dir)) {
+ continue;
+ }
+
+ #-- read in one directory
+ $dh = opendir($dir);
+ while ($fn = readdir($dh)) {
+
+ #-- skip over . and ..
+ if ($fn[0] == ".") { continue; }
+
+ #-- be recursive
+ if ($fn && is_dir("$dir/$fn")) {
+ if ($fn != trim($fn, ".")) {
+ $fnadd = trim($fn, ".") . ".";
+ }
+ else {
+ $fnadd = "$fn/";
+ }
+
+ ewiki_init_spages(array("$dir/$fn"), "$idprep$fnadd");
+
+ continue;
+ }
+
+ #-- strip filename extensions
+ $id = str_replace(
+ array(".html", ".htm", ".php", ".txt", ".wiki", ".src"),
+ "",
+ basename($fn)
+ );
+
+ #-- register spage file and as page plugin (one for every spage)
+ $ewiki_spages[strtolower("$idprep$id")] = "$dir/$fn";
+ $ewiki_plugins["page"]["$idprep$id"] = "ewiki_spage";
+
+ }
+ closedir($dh);
+ }
+
+}
+
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* MySQL database backend
+ (Glue between Moodle and ewiki Database)
+
+ Adapted by Michael Schneider
+*/
+
+/// Glue
+$ewiki_plugins["database"][0] = "ewiki_database_moodle";
+
+/// #-- predefine some of the configuration constants
+define("EWIKI_NAME", $wiki_entry->pagename);
+
+define("EWIKI_CONTROL_LINE", 0);
+define("EWIKI_LIST_LIMIT", 25);
+define("EWIKI_DEFAULT_LANG", current_language());
+define("EWIKI_HTML_CHARS", 1);
+define("EWIKI_DB_TABLE_NAME", "wiki_pages");
+
+
+function ewiki_database_moodle($action, &$args, $sw1, $sw2) {
+ global $wiki, $wiki_entry, $CFG;
+ #-- result array
+ $r = array();
+
+ switch($action) {
+
+ /* Returns database entry as array for the page whose name was given
+ with the "id" key in the $args array, usually fetches the latest
+ version of a page, unless a specific "version" was requested in
+ the $args array.
+ */
+ # Ugly, but we need to choose which wiki we are about to change/read
+ case "GET":
+ $id = "'" . mysql_escape_string($args["id"]) . "'";
+ ($version = 0 + @$args["version"]) and ($version = "AND (version=$version)") or ($version="");
+
+
+ # $result = mysql_query("SELECT * FROM " . EWIKI_DB_TABLE_NAME
+ # . " WHERE (pagename=$id) $version ORDER BY version DESC LIMIT 1"
+ #);
+ #if ($result && ($r = mysql_fetch_array($result, MYSQL_ASSOC))) {
+ # $r["id"] = $r["pagename"];
+ # unset($r["pagename"]);
+ #}
+ #if (strlen($r["meta"])) {
+ # $r["meta"] = @unserialize($r["meta"]);
+ #}
+
+ $select="(pagename=$id) AND wiki=".$wiki_entry->id." $version ";
+ $sort="version DESC";
+ $result_obj=get_records_select(EWIKI_DB_TABLE_NAME, $select,$sort,"*",0,1);
+ if($result_obj) {
+ $r=get_object_vars($result_obj[$args["id"]]);
+ $r["id"] = $r["pagename"];
+ unset($r["pagename"]);
+ $r["meta"] = @unserialize($r["meta"]);
+ }
+ break;
+
+
+
+ /* Increases the hit counter for the page name given in $args array
+ with "id" index key.
+ */
+ case "HIT":
+ #mysql_query("UPDATE " . EWIKI_DB_TABLE_NAME . " SET hits=(hits+1) WHERE pagename='" . mysql_escape_string($args["id"]) . "'");
+ # set_field does not work because of the "hits+1" construct
+ #print "DO ".mysql_escape_string($args["id"]); exit;
+ execute_sql("UPDATE " .$CFG->prefix.EWIKI_DB_TABLE_NAME . " SET hits=(hits+1) WHERE pagename='" . mysql_escape_string($args["id"]) . "' and wiki=".$wiki_entry->id, 0);
+ break;
+ /* Stores the $data array into the database, while not overwriting
+ existing entries (using WRITE); returns 0 on failure and 1 if
+ saved correctly.
+ */
+ case "OVERWRITE":
+ $COMMAND = "REPLACE";
+ break;
+
+ case "WRITE":
+ $COMMAND="WRITE";
+ $args["pagename"] = $args["id"];
+ unset($args["id"]);
+
+ if (is_array($args["meta"])) {
+ $args["meta"] = serialize($args["meta"]);
+ }
+
+ #$sql1 = $sql2 = "";
+ #foreach ($args as $index => $value) {
+ # if (is_int($index)) {
+ # continue;
+ # }
+ # $a = ($sql1 ? ', ' : '');
+ # $sql1 .= $a . $index;
+ # $sql2 .= $a . "'" . mysql_escape_string($value) . "'";
+ #}
+
+ #strlen(@$COMMAND) || ($COMMAND = "INSERT");
+
+ foreach ($args as $index => $value) {
+ if (is_int($index)) {
+ continue;
+ }
+ $args[$index] =mysql_escape_string($value);
+ }
+ $args["wiki"]=$wiki_entry->id;
+
+ # Check if Record exists
+ if($COMMAND=="REPLACE") {
+ if(count_records(EWIKI_DB_TABLE_NAME,"wiki", $wiki_entry->id,"pagename",$args["pagename"],"version",$args["version"])) {
+ delete_record(EWIKI_DB_TABLE_NAME,"wiki", $wiki_entry->id,"pagename",$args["pagename"],"version",$args["version"]);
+ }
+ }
+
+ # Write
+ $result=insert_record(EWIKI_DB_TABLE_NAME,$args,false,"pagename");
+
+ #$result = mysql_query("$COMMAND INTO " . EWIKI_DB_TABLE_NAME .
+ # " (" . $sql1 . ") VALUES (" . $sql2 . ")"
+ #);
+ #return($result && mysql_affected_rows() ?1:0);
+
+ return $result;
+ break;
+
+
+
+ /* Checks for existence of the WikiPages whose names are given in
+ the $args array. Returns an array with the specified WikiPageNames
+ associated with values of "0" or "1" (stating if the page exists
+ in the database). For images/binary db entries returns the "meta"
+ field instead of an "1".
+ */
+ case "FIND":
+ $select = "";
+ foreach (array_values($args) as $id) {
+ if (strlen($id)) {
+ $r[$id] = 0;
+ $select .= ($select ? " OR " : "") .
+ "(pagename='" . mysql_escape_string($id) . "')";
+ }
+ }
+ if($select) {
+ $select = "(".$select.") AND wiki=".$wiki_entry->id;
+ $result = get_records_select(EWIKI_DB_TABLE_NAME,$select);
+ #$sql = "SELECT pagename AS id, meta FROM " .
+ # EWIKI_DB_TABLE_NAME . " WHERE $sql "
+ #);
+ #while ($result && ($row = mysql_fetch_row($result))) {
+ # $r[$row[0]] = strpos($row[1], 's:5:"image"') ? $row[1] : 1;
+
+ while(list($key, $val) = @each($result)) {
+ $r[$val->pagename]=strpos($val->meta, 's:5:"image"') ? $val->meta : 1;
+ }
+ }
+ break;
+
+ /* Counts the number of Versions
+ */
+ case "COUNTVERSIONS":
+ $sql= "SELECT pagename AS id, count(*) as versioncount".
+ " FROM ". $CFG->prefix.EWIKI_DB_TABLE_NAME .
+ " WHERE wiki = ".$wiki_entry->id.
+ " GROUP BY id";
+
+ #print "$sql";
+ $result=get_records_sql($sql);
+ while(list($key, $val) = each($result)) {
+ $r[$key]=$val->versioncount;
+ }
+ break;
+
+ /* Returns an array of __all__ pages, where each entry is made up
+ of the fields from the database requested with the $args array,
+ e.g. array("flags","meta","lastmodified");
+ */
+ case "GETALL":
+
+ #$result = mysql_query("SELECT pagename AS id, ".
+ # implode(", ", $args) .
+ # " FROM ". EWIKI_DB_TABLE_NAME .
+ # " GROUP BY id, version DESC"
+ #);
+ $sql= "SELECT pagename AS id, ".
+ implode(", ", $args) .
+ " FROM ". $CFG->prefix.EWIKI_DB_TABLE_NAME .
+ " WHERE wiki = ".$wiki_entry->id.
+ " GROUP BY id, version";
+
+ #print "$sql";
+ $result=get_records_sql($sql);
+ $r = new ewiki_dbquery_result($args);
+
+ $drop = "";
+ #while ($result && ($row = mysql_fetch_array($result, MYSQL_ASSOC))) {
+ # $i = EWIKI_CASE_INSENSITIVE ? strtolower($row["id"]) : $row["id"];
+ # if ($i != $drop) {
+ # $drop = $i;
+ # $r->add($row);
+ # }
+ #}
+ #print "<pre>"; print_r($result); print "</pre>";
+ while(list($key, $val) = each($result)) {
+ $row=get_object_vars($val);
+ $i = EWIKI_CASE_INSENSITIVE ? strtolower($row["id"]) : $row["id"];
+ if ($i != $drop) {
+ $drop = $i;
+ $r->add($row);
+ }
+ }
+
+ break;
+
+
+
+ /* Returns array of database entries (also arrays), where the one
+ specified column matches the specified content string, for example
+ $args = array("content" => "text...piece")
+ is not guaranteed to only search/return the latest version of a page
+ */
+ case "SEARCH":
+ $field = implode("", array_keys($args));
+ $content = strtolower(implode("", $args));
+ if ($field == "id") { $field = "pagename"; }
+
+ #$result = mysql_query("SELECT pagename AS id, version, flags" .
+ # (EWIKI_DBQUERY_BUFFER && ($field!="pagename") ? ", $field" : "") .
+ # " FROM " . EWIKI_DB_TABLE_NAME .
+ # " WHERE LOCATE('" . mysql_escape_string($content) . "', LCASE($field)) " .
+ # " GROUP BY id, version DESC"
+ #);
+ $sql= "SELECT pagename AS id, version, flags" .
+ (EWIKI_DBQUERY_BUFFER && ($field!="pagename") ? ", $field" : "") .
+ " FROM " . $CFG->prefix.EWIKI_DB_TABLE_NAME .
+ " WHERE LOCATE('" . mysql_escape_string($content) . "', LCASE($field)) and wiki=".$wiki_entry->id .
+ " GROUP BY id, version DESC";
+ $result=get_records_sql($sql);
+ $r = new ewiki_dbquery_result(array("id","version",$field));
+ $drop = "";
+ #while ($result && ($row = mysql_fetch_array($result, MYSQL_ASSOC))) {
+ # $i = EWIKI_CASE_INSENSITIVE ? strtolower($row["id"]) : $row["id"];
+ # if ($i != $drop) {
+ # $drop = $i;
+ # $r->add($row);
+ # }
+ #}
+ while(list($key, $val) = @each($result)) {
+ $row=get_object_vars($val);
+ $i = EWIKI_CASE_INSENSITIVE ? strtolower($row["id"]) : $row["id"];
+ if ($i != $drop) {
+ $drop = $i;
+ $r->add($row);
+ }
+ }
+ break;
+
+
+ case "DELETE":
+ $id = mysql_escape_string($args["id"]);
+ $version = $args["version"];
+
+ #mysql_query("DELETE FROM " . EWIKI_DB_TABLE_NAME ."
+ # WHERE pagename='$id' AND version=$version");
+ # print "DELETING wiki:".$wiki_entry->id."Pagename: $id Version: $version <br>\n";
+ delete_records(EWIKI_DB_TABLE_NAME,"wiki", $wiki_entry->id,"pagename",$id,"version",$version);
+
+ break;
+
+
+
+ case "INIT":
+ #mysql_query("CREATE TABLE " . EWIKI_DB_TABLE_NAME ."
+ # (pagename VARCHAR(160) NOT NULL,
+ # version INTEGER UNSIGNED NOT NULL DEFAULT 0,
+ # flags INTEGER UNSIGNED DEFAULT 0,
+ # content MEDIUMTEXT,
+ # author VARCHAR(100) DEFAULT 'ewiki',
+ # created INTEGER UNSIGNED DEFAULT ".time().",
+ # lastmodified INTEGER UNSIGNED DEFAULT 0,
+ # refs MEDIUMTEXT,
+ # meta MEDIUMTEXT,
+ # hits INTEGER UNSIGNED DEFAULT 0,
+ # PRIMARY KEY id (pagename, version) )
+ # ");
+ #echo mysql_error();
+ break;
+
+ default:
+ }
+
+ return($r);
+}
--- /dev/null
+<?PHP // $Id$\r
+ //This function provides automatic linking to\r
+ //wiki pages when its page title is found inside every Moodle text\r
+ //It's based in the glosssary filter by Williams Castillo\r
+ //Modifications by mchurch. Enjoy! :-)\r
+\r
+ require_once($CFG->dirroot.'/mod/wiki/lib.php');\r
+\r
+ $textfilter_function='wiki_page_filter';\r
+\r
+ if (function_exists($textfilter_function)) {\r
+ return;\r
+ }\r
+\r
+ function wiki_page_filter($courseid, $text) {\r
+\r
+ global $CFG;\r
+\r
+ if (empty($courseid)) {\r
+ if ($site = get_site()) {\r
+ $courseid = $site->id;\r
+ }\r
+ }\r
+\r
+ if (!($course = get_record('course', 'id', $courseid))) {\r
+ return $text;\r
+ }\r
+\r
+// Get all wikis for this course.\r
+ $wikis = get_records('wiki', 'course', $courseid);\r
+ if (empty($wikis)) {\r
+ return $text;\r
+ }\r
+\r
+// Walk through each wiki, and get entries.\r
+ foreach ($wikis as $wiki) {\r
+ if ($wiki_entries = wiki_get_entries($wiki)) {\r
+\r
+// Walk through each entry and get the pages.\r
+ foreach ($wiki_entries as $wiki_entry) {\r
+ if ($wiki_pages = get_records('wiki_pages', 'wiki', $wiki_entry->id)) {\r
+\r
+// Walk through each page and filter.\r
+ foreach ($wiki_pages as $wiki_page) {\r
+ $startlink = '<a class="autolink" title="Wiki" href="'\r
+ .$CFG->wwwroot.'/mod/wiki/view.php?wid='.$wiki->id\r
+ .'&userid='.$wiki_entry->userid\r
+ .'&groupid='.$wiki_entry->groupid\r
+ .'&wikipage='.$wiki_page->pagename.'">';\r
+ $text = wiki_link_names($text, $wiki_page->pagename, $startlink, '</a>');\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return $text;\r
+ }\r
+ \r
+ function wiki_link_names($text,$name,$href_tag_begin,$href_tag_end = "</a>") {\r
+\r
+ $list_of_words_cp = strip_tags($name);\r
+\r
+ $list_of_words_cp = trim($list_of_words_cp,'|');\r
+\r
+ $list_of_words_cp = trim($list_of_words_cp);\r
+\r
+ $list_of_words_cp = preg_quote($list_of_words_cp,'/');\r
+\r
+ $invalidprefixs = "([a-zA-Z0-9])";\r
+ $invalidsufixs = "([a-zA-Z0-9])";\r
+\r
+ //Avoid seaching in the string if it's inside invalidprefixs and invalidsufixs\r
+ $words = array();\r
+ $regexp = '/'.$invalidprefixs.'('.$list_of_words_cp.')|('.$list_of_words_cp.')'.$invalidsufixs.'/is';\r
+ preg_match_all($regexp,$text,$list_of_words);\r
+\r
+ foreach (array_unique($list_of_words[0]) as $key=>$value) {\r
+ $words['<*'.$key.'*>'] = $value;\r
+ }\r
+ if (!empty($words)) {\r
+ $text = str_replace($words,array_keys($words),$text);\r
+ }\r
+\r
+ //Now avoid searching inside the <nolink>tag\r
+ $excludes = array();\r
+ preg_match_all('/<nolink>(.+?)<\/nolink>/is',$text,$list_of_excludes);\r
+ foreach (array_unique($list_of_excludes[0]) as $key=>$value) {\r
+ $excludes['<+'.$key.'+>'] = $value;\r
+ }\r
+ if (!empty($excludes)) {\r
+ $text = str_replace($excludes,array_keys($excludes),$text);\r
+ }\r
+\r
+ //Now avoid searching inside links\r
+ $links = array();\r
+ preg_match_all('/<A[\s](.+?)>(.+?)<\/A>/is',$text,$list_of_links);\r
+ foreach (array_unique($list_of_links[0]) as $key=>$value) {\r
+ $links['<@'.$key.'@>'] = $value;\r
+ }\r
+ if (!empty($links)) {\r
+ $text = str_replace($links,array_keys($links),$text);\r
+ }\r
+\r
+ //Now avoid searching inside every tag\r
+ $final = array();\r
+ preg_match_all('/<(.+?)>/is',$text,$list_of_tags);\r
+ foreach (array_unique($list_of_tags[0]) as $key=>$value) {\r
+ $final['<|'.$key.'|>'] = $value;\r
+ }\r
+ if (!empty($final)) {\r
+ $text = str_replace($final,array_keys($final),$text);\r
+ }\r
+\r
+ $text = preg_replace('/('.$list_of_words_cp.')/is', $href_tag_begin.'$1'.$href_tag_end,$text);\r
+\r
+ //Now rebuild excluded areas\r
+ if (!empty($final)) {\r
+ $text = str_replace(array_keys($final),$final,$text);\r
+ }\r
+ if (!empty($links)) {\r
+ $text = str_replace(array_keys($links),$links,$text);\r
+ }\r
+ if (!empty($excludes)) {\r
+ $text = str_replace(array_keys($excludes),$excludes,$text);\r
+ }\r
+ if (!empty($words)) {\r
+ $text = str_replace(array_keys($words),$words,$text);\r
+ }\r
+ return $text;\r
+ }\r
+?>\r
--- /dev/null
+<?PHP // $Id$
+
+/// This page lists all the instances of wiki in a particular course
+/// Replace wiki with the name of your module
+
+ require_once("../../config.php");
+ require_once("lib.php");
+
+ require_variable($id); // course
+
+ if (! $course = get_record("course", "id", $id)) {
+ error("Course ID is incorrect");
+ }
+
+ require_login($course->id);
+
+ add_to_log($course->id, "wiki", "view all", "index.php?id=$course->id", "");
+
+
+/// Get all required strings
+
+ $strwikis = get_string("modulenameplural", "wiki");
+ $strwiki = get_string("modulename", "wiki");
+
+
+/// Print the header
+
+ if ($course->category) {
+ $navigation = "<A HREF=\"../../course/view.php?id=$course->id\">$course->shortname</A> ->";
+ }
+
+ print_header("$course->shortname: $strwikis", "$course->fullname", "$navigation $strwikis", "", "", true, "", navmenu($course));
+
+/// Get all the appropriate data
+
+ if (! $wikis = get_all_instances_in_course("wiki", $course)) {
+ notice("There are no wikis", "../../course/view.php?id=$course->id");
+ die;
+ }
+
+/// Print the list of instances (your module will probably extend this)
+
+ $timenow = time();
+ $strname = get_string('wikiname', 'wiki');
+ $strsummary = get_string('summary');
+ $strtype = get_string('wikitype', 'wiki');
+ $strlastmodified = get_string('lastmodified');
+ $strweek = get_string('week');
+ $strtopic = get_string('topic');
+
+ if ($course->format == "weeks") {
+ $table->head = array ($strweek, $strname, $strsummary, $strtype, $strlastmodified);
+ $table->align = array ('CENTER', 'LEFT', 'LEFT', 'LEFT', 'LEFT');
+ } else if ($course->format == "topics") {
+ $table->head = array ($strtopic, $strname, $strsummary, $strtype, $strlastmodified);
+ $table->align = array ('CENTER', 'LEFT', 'LEFT', 'LEFT', 'LEFT');
+ } else {
+ $table->head = array ($strname, $strsummary, $strtype, $strlastmodified);
+ $table->align = array ('LEFT', 'LEFT', 'LEFT', 'LEFT');
+ }
+
+ foreach ($wikis as $wiki) {
+ if (!$wiki->visible) {
+ //Show dimmed if the mod is hidden
+ $link = '<A class="dimmed" HREF="view.php?id='.$wiki->coursemodule.'">'.$wiki->name.'</A>';
+ } else {
+ //Show normal if the mod is visible
+ $link = '<A HREF="view.php?id='.$wiki->coursemodule.'">'.$wiki->name.'</A>';
+ }
+
+ $timmod = '<span class="smallinfo">'.userdate($wiki->timemodified).'</span>';
+ $summary = '<span class="smallinfo">'.$wiki->summary.'</span>';
+
+ $site = get_site();
+ switch ($wiki->wtype) {
+
+ case 'teacher':
+ $wtype = $site->teacher;
+ break;
+
+ case 'student':
+ $wtype = $site->student;
+ break;
+
+ case 'group':
+ default:
+ $wtype = get_string('group');
+ break;
+ }
+
+ $wtype = '<span class="smallinfo">'.$wtype.'</span>';
+
+ if ($course->format == "weeks" or $course->format == "topics") {
+ $table->data[] = array ($wiki->section, $link, $summary, $wtype, $timmod);
+ } else {
+ $table->data[] = array ($link, $summary, $wtype, $timmod);
+ }
+ }
+
+ echo "<BR>";
+
+ print_table($table);
+
+/// Finish the page
+
+ print_footer($course);
+
+?>
--- /dev/null
+<?PHP // $Id$
+
+/// Library of functions and constants for module wiki
+/// (replace wiki with the name of your module and delete this line)
+
+
+$wiki_CONSTANT = 7; /// for example
+$site = get_site();
+$WIKI_TYPES = array ('teacher' => $site->teacher,
+ 'group' => get_string('groups',"wiki"),
+ 'student' => $site->student );
+define("EWIKI_ESCAPE_AT", 0); # For the algebraic filter
+
+function wiki_add_instance($wiki) {
+/// Given an object containing all the necessary data,
+/// (defined by the form in mod.html) this function
+/// will create a new instance and return the id number
+/// of the new instance.
+
+ $wiki->timemodified = time();
+
+ # May have to add extra stuff in here #
+
+ /// If specified, decode $wiki->initialcontent as the initial page name.
+ /// Make sure its in wiki CamelHumpForm.
+ if (!empty($wiki->initialcontent)) {
+ $wiki->pagename = '';
+ }
+ /// If specified, use $wiki->pagename as the initial page name.
+ /// Make sure its in wiki CamelHumpForm.
+ else if (!empty($wiki->pagename)) {
+ $wiki->pagename = wiki_wiki_name($wiki->pagename);
+ }
+ /// Use the wiki name for the initial page name.
+ else {
+ $wiki->pagename = wiki_wiki_name($wiki->name);
+ }
+ return insert_record("wiki", $wiki);
+}
+
+
+function wiki_update_instance($wiki) {
+/// Given an object containing all the necessary data,
+/// (defined by the form in mod.html) this function
+/// will update an existing instance with new data.
+
+ /// If specified, decode $wiki->initialcontent as the initial page name.
+ /// Make sure its in wiki CamelHumpForm.
+ if (!empty($wiki->initialcontent)) {
+ $wiki->pagename = '';
+ }
+ /// If specified, use $wiki->pagename as the initial page name.
+ /// Make sure its in wiki CamelHumpForm.
+ else if (!empty($wiki->pagename)) {
+ $wiki->pagename = wiki_wiki_name($wiki->pagename);
+ }
+ /// Use the wiki name for the initial page name.
+ else {
+ $wiki->pagename = wiki_wiki_name($wiki->name);
+ }
+
+ $wiki->timemodified = time();
+ $wiki->id = $wiki->instance;
+ return update_record("wiki", $wiki);
+}
+
+/// Delete all Directories recursively
+function wiki_rmdir($basedir) {
+ $handle = @opendir($basedir);
+ if($handle) {
+ while (false!==($folder = readdir($handle))) {
+ if($folder != "." && $folder != ".." && $Folder != "CVS") {
+ wiki_rmdir("$basedir/$folder"); // recursive
+ }
+ }
+ closedir($handle);
+ }
+ @rmdir($basedir);
+}
+
+function wiki_delete_instance($id) {
+/// Given an ID of an instance of this module,
+/// this function will permanently delete the instance
+/// and any data that depends on it.
+ global $CFG;
+
+ if (! $wiki = get_record("wiki", "id", $id)) {
+ return false;
+ }
+
+ $result = true;
+
+ #Delete Files
+### Should probably check regardless of this setting in case its been changed...
+ if($wiki->ewikiacceptbinary) {
+ if ($basedir = $CFG->dataroot."/".$wiki->course."/".$CFG->moddata."/wiki/$id") {
+ if ($files = get_directory_list($basedir)) {
+ foreach ($files as $file) {
+ #if ($file != $exception) {
+ unlink("$basedir/$file");
+ notify("Existing file '$file' has been deleted!");
+ #}
+ }
+ }
+ #if (!$exception) { // Delete directory as well, if empty
+ wiki_rmdir("$basedir");
+ #}
+ }
+ }
+
+ # Delete any dependent records here #
+ if (! delete_records("wiki", "id", $wiki->id)) {
+ $result = false;
+ }
+
+ /// Delete all wiki_entries and wiki_pages.
+ if (($wiki_entries = wiki_get_entries($wiki)) !== false) {
+ foreach ($wiki_entries as $wiki_entry) {
+ if (! delete_records("wiki_pages", "wiki", "$wiki_entry->id")) {
+ $result = false;
+ }
+ if (! delete_records("wiki_entries", "id", "$wiki_entry->id")) {
+ $result = false;
+ }
+ }
+ }
+
+ return $result;
+}
+
+function wiki_user_outline($course, $user, $mod, $wiki) {
+/// Return a small object with summary information about what a
+/// user has done with a given particular instance of this module
+/// Used for user activity reports.
+/// $return->time = the time they did it
+/// $return->info = a short text description
+
+ return $return;
+}
+
+function wiki_user_complete($course, $user, $mod, $wiki) {
+/// Print a detailed representation of what a user has done with
+/// a given particular instance of this module, for user activity reports.
+
+ return true;
+}
+
+function wiki_print_recent_activity($course, $isteacher, $timestart) {
+/// Given a course and a time, this module should find recent activity
+/// that has occurred in wiki activities and print it out.
+/// Return true if there was output, or false is there was none.
+
+ global $CFG;
+
+ return false; // True if anything was printed, otherwise false
+}
+
+function wiki_cron () {
+/// Function to be run periodically according to the moodle cron
+/// This function searches for things that need to be done, such
+/// as sending out mail, toggling flags etc ...
+
+ global $CFG;
+
+ return true;
+}
+
+function wiki_grades($wikiid) {
+/// Must return an array of grades for a given instance of this module,
+/// indexed by user. It also returns a maximum allowed grade.
+
+ $return->grades = NULL;
+ $return->maxgrade = NULL;
+
+ return $return;
+}
+
+function wiki_get_participants($wikiid) {
+//Must return an array of user records (all data) who are participants
+//for a given instance of wiki. Must include every user involved
+//in the instance, independient of his role (student, teacher, admin...)
+//See other modules as example.
+
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+/// Any other wiki functions go here. Each of them must have a name that
+/// starts with wiki_
+
+function wiki_wiki_name($wikiname) {
+/// Return the passed in string in Wiki name format.
+/// Remove any leading and trailing whitespace, capitalize all the words
+/// and then remove any internal whitespace.
+
+ if (wiki_is_wiki_name($wikiname)) {
+ return $wikiname;
+ }
+ else {
+ /// Create uppercase words and remove whitespace.
+ $wikiname = preg_replace("/(\w+)\s/", "$1", ucwords(trim($wikiname)));
+
+ /// Check again - there may only be one word.
+ if (wiki_is_wiki_name($wikiname)) {
+ return $wikiname;
+ }
+ /// If there is only one word, append default wiki name to it.
+ else {
+ return $wikiname.get_string('wikidefaultpagename', 'wiki');
+ }
+ }
+}
+
+function wiki_is_wiki_name($wikiname) {
+/// Check for correct wikiname syntax and return true or false.
+
+ /// If there are spaces between the words, incorrect format.
+ if (preg_match_all('/\w+/', $wikiname, $out) > 1) {
+ return false;
+ }
+ /// If there isn't more than one group of uppercase letters separated by
+ /// lowercase letters or '_', incorrect format.
+ else if (preg_match_all('/[A-Z]+[a-z_]+/', $wikiname, $out) > 1) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+function wiki_page_name(&$wiki) {
+/// Determines the wiki's page name and returns it.
+ if (!empty($wiki->initialcontent)) {
+ $ppos = strrpos($wiki->initialcontent, '/');
+ if ($ppos === false) {
+ $pagename = $wiki->initialcontent;
+ }
+ else {
+ $pagename = substr($wiki->initialcontent, $ppos+1);
+ }
+ }
+ else if (!empty($wiki->pagename)) {
+ $pagename = $wiki->pagename;
+ }
+ else {
+ $pagename = wiki_wiki_name($wiki->name);
+ }
+ return $pagename;
+}
+
+function wiki_content_dir(&$wiki) {
+/// Determines the wiki's default content directory (if there is one).
+ global $CFG;
+
+ if (!empty($wiki->initialcontent)) {
+ $ppos = strrpos($wiki->initialcontent, '/');
+ if ($ppos === false) {
+ $subdir = '';
+ }
+ else {
+ $subdir = substr($wiki->initialcontent, 0, $ppos+1);
+ }
+ $contentdir = $CFG->dataroot.'/'.$wiki->course.'/'.$subdir;
+ }
+ else {
+ $contentdir = false;
+ }
+ return $contentdir;
+}
+
+function wiki_has_entries(&$wiki) {
+/// Returns true if wiki already has wiki entries; otherwise false.
+
+ return record_exists('wiki_entries', 'wikiid', $wiki->id);
+}
+
+function wiki_get_entries(&$wiki, $byindex=NULL) {
+/// Returns an array with all wiki entries indexed by entry id; false if there are none.
+/// If the optional $byindex is specified, returns the entries indexed by that field.
+/// Valid values for $byindex are 'student', 'group'.
+
+ if ($byindex == 'student') {
+ return get_records('wiki_entries', 'wikiid', $wiki->id, '',
+ 'userid,id,wikiid,course,groupid,pagename,timemodified');
+ }
+ else if ($byindex == 'group') {
+ return get_records('wiki_entries', 'wikiid', $wiki->id, '',
+ 'groupid,id,wikiid,course,userid,pagename,timemodified');
+ }
+ else {
+ return get_records('wiki_entries', 'wikiid', $wiki->id);
+ }
+}
+
+function wiki_get_entry(&$wiki, &$course, $userid=0, $groupid=0) {
+/// Returns the wiki entry according to the wiki type.
+/// Optionally, will return wiki entry for $userid student wiki, or
+/// $groupid group or teacher wiki.
+ global $USER;
+
+ switch ($wiki->wtype) {
+ case 'student':
+ /// If a specific user was requested, return it, if allowed.
+ if ($userid and wiki_user_can_access_student_wiki($wiki, $userid, $course)) {
+ $wentry = wiki_get_student_entry($wiki, $userid);
+ }
+
+ /// If there is no entry for this user, check if this user is a teacher.
+ else if (!$wentry = wiki_get_student_entry($wiki, $USER->id)) {
+/* if (isteacher($course->id, $USER->id)) {
+ /// If this user is a teacher, return the first entry.
+ if ($wentries = wiki_get_entries($wiki)) {
+ $wentry = current($wentries);
+ }
+ }*/
+ }
+ break;
+
+ case 'group':
+ /// If there is a groupmode, get the user's group id.
+ $groupmode = groupmode($course, $wiki);
+
+ /// If a specific group was requested, return it, if allowed.
+ if ($groupid and wiki_user_can_access_group_wiki($wiki, $groupid, $course)) {
+ $wentry = wiki_get_group_entry($wiki, $groupid);
+ }
+ else if ($groupmode) {
+ /// If there is no entry for this user, check if this user is a teacher.
+ if (!$wentry = wiki_get_group_entry($wiki, mygroupid($course->id))) {
+/* if (isteacher($course->id, $USER->id)) {
+ /// If this user is a teacher, return the first entry.
+ if ($wentries = wiki_get_entries($wiki)) {
+ $wentry = current($wentries);
+ }
+ } */
+ }
+ }
+ /// If mode is 'nogroups', then groupid is zero.
+ else {
+ $wentry = wiki_get_group_entry($wiki, 0);
+ }
+ break;
+
+ case 'teacher':
+ /// If there is a groupmode, get the user's group id.
+ if (groupmode($course, $wiki)) {
+ $groupid = $groupid ? $groupid : mygroupid($course->id);
+ }
+
+ /// If a specific group was requested, return it, if allowed.
+ if (wiki_user_can_access_teacher_wiki($wiki, $groupid, $course)) {
+ $wentry = wiki_get_teacher_entry($wiki, $groupid);
+ }
+ break;
+ }
+ return $wentry;
+}
+
+function wiki_get_teacher_entry(&$wiki, $groupid=0) {
+/// Returns the wiki entry for the wiki teacher type.
+ return get_record('wiki_entries', 'wikiid', $wiki->id, 'course', $wiki->course, 'groupid', $groupid);
+}
+
+function wiki_get_group_entry(&$wiki, $groupid=null) {
+/// Returns the wiki entry for the given group.
+ return get_record('wiki_entries', 'wikiid', $wiki->id, 'groupid', $groupid);
+}
+
+function wiki_get_student_entry(&$wiki, $userid=null) {
+/// Returns the wiki entry for the given student.
+ global $USER;
+
+ if (is_null($userid)) {
+ $userid = $USER->id;
+ }
+ return get_record('wiki_entries', 'wikiid', $wiki->id, 'userid', $userid);
+}
+
+function wiki_get_other_wikis(&$wiki, &$user, &$course, $currentid=0) {
+ /// Returns a list of other wikis to display, depending on the type, group and user.
+ /// Returns the key containing the currently selected entry as well.
+
+ global $CFG, $ME, $id;
+
+ $wikis = false;
+
+ $groupmode = groupmode($course, $wiki);
+ $mygroupid = mygroupid($course->id);
+ $isteacher = isteacher($course->id, $user->id);
+ $isteacheredit = isteacheredit($course->id, $user->id);
+ $site = get_site();
+
+ switch ($wiki->wtype) {
+
+ case 'student':
+ /// Get all the existing entries for this wiki.
+ $wiki_entries = wiki_get_entries($wiki, 'student');
+ if ($isteacher and ($site->id != $course->id)) {
+
+ /// If the user is an editing teacher, or a non-editing teacher not assigned to a group, show all student
+ /// wikis, regardless of creation.
+ if (($site->id != $course->id) and ($isteacheredit or ($groupmode == NOGROUPS))) {
+
+ if ($students = get_course_students($course->id)) {
+ /// Default pagename is dependent on the wiki settings.
+ $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
+
+ foreach ($students as $student) {
+
+ /// If this student already has an entry, use its pagename.
+ if ($wiki_entries[$student->id]) {
+ $pagename = $wiki_entries[$student->id]->pagename;
+ }
+ else {
+ $pagename = $defpagename;
+ }
+
+ $key = $ME.'?id='.$id.'&userid='.$student->id.'&wikipage='.$pagename;
+ $wikis[$key] = fullname($student).':'.$pagename;
+ }
+ }
+ }
+ else if ($groupmode == SEPARATEGROUPS) {
+ if ($students = get_group_students($mygroupid)) {
+ $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
+ foreach ($students as $student) {
+
+ /// If this student already has an entry, use its pagename.
+ if ($wiki_entries[$student->id]) {
+ $pagename = $wiki_entries[$student->id]->pagename;
+ }
+ else {
+ $pagename = $defpagename;
+ }
+
+ $key = $ME.'?id='.$id.'&userid='.$student->id.'&wikipage='.$pagename;
+ $wikis[$key] = fullname($student).':'.$pagename;
+ }
+ }
+ }
+ else if ($groupmode == VISIBLEGROUPS) {
+ /// Get all students in your group.
+ if ($students = get_group_students($mygroupid)) {
+ $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
+ foreach ($students as $student) {
+ /// If this student already has an entry, use its pagename.
+ if ($wiki_entries[$student->id]) {
+ $pagename = $wiki_entries[$student->id]->pagename;
+ }
+ else {
+ $pagename = $defpagename;
+ }
+ $key = $ME.'?id='.$id.'&userid='.$student->id.'&wikipage='.$pagename;
+ $wikis[$key] = fullname($student).':'.$pagename;
+ }
+ }
+ /// Get all student wikis created, regardless of group.
+ $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
+ .' FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'user u '
+ .' WHERE w.wikiid = '.$wiki->id.' AND u.id = w.userid '
+ .' ORDER BY w.id';
+ $wiki_entries = get_records_sql($sql);
+ $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
+ foreach ($wiki_entries as $wiki_entry) {
+ $key = $ME.'?id='.$id.'&userid='.$wiki_entry->userid.'&wikipage='.$wiki_entry->pagename;
+ $wikis[$key] = fullname($wiki_entry).':'.$wiki_entry->pagename;
+ if ($currentid == $wiki_entry->id) {
+ $wikis['selected'] = $key;
+ }
+ }
+ }
+ }
+ else {
+ /// A user can see other student wikis if they are a member of the same
+ /// group (for separate groups) or there are visible groups, or if this is
+ /// a site-level wiki, and they are an administrator.
+ if (($groupmode == VISIBLEGROUPS) or
+ (($site->id == $course->id) and isadmin())) {
+ $viewall = true;
+ }
+ else if ($groupmode == SEPARATEGROUPS) {
+ $viewall = mygroupid($course->id);
+ }
+ else {
+ $viewall = false;
+ }
+
+ if ($viewall !== false) {
+ $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
+ .' FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'user u '
+ .' WHERE w.wikiid = '.$wiki->id.' AND u.id = w.userid '
+ .' ORDER BY w.id';
+ $wiki_entries = get_records_sql($sql);
+ $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
+ foreach ($wiki_entries as $wiki_entry) {
+ if (($viewall === true) or ismember($viewall, $wiki_entry->userid)) {
+ $key = $ME.'?id='.$id.'&userid='.$wiki_entry->userid.'&wikipage='.$wiki_entry->pagename;
+ $wikis[$key] = fullname($wiki_entry).':'.$wiki_entry->pagename;
+ if ($currentid == $wiki_entry->id) {
+ $wikis['selected'] = $key;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case 'group':
+ /// If the user is an editing teacher, or a non-editing teacher not assigned to a group, show all group
+ /// wikis, regardless of creation.
+
+ /// Get all the existing entries for this wiki.
+ $wiki_entries = wiki_get_entries($wiki, 'group');
+
+ if ($groupmode and ($isteacheredit or ($isteacher and !$mygroupid))) {
+ if ($groups = get_groups($course->id)) {
+ $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
+ foreach ($groups as $group) {
+
+ /// If this group already has an entry, use its pagename.
+ if (isset($wiki_entries[$group->id])) {
+ $pagename = $wiki_entries[$group->id]->pagename;
+ }
+ else {
+ $pagename = $defpagename;
+ }
+
+ $key = $ME.'?id='.$id.'&groupid='.$group->id.'&wikipage='.$pagename;
+ $wikis[$key] = $group->name.':'.$pagename;
+ }
+ }
+ }
+ /// A user can see other group wikis if there are visible groups.
+ else if ($groupmode == VISIBLEGROUPS) {
+ $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
+ .' FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'groups g '
+ .' WHERE w.wikiid = '.$wiki->id.' AND g.id = w.groupid '
+ .' ORDER BY w.groupid';
+ $wiki_entries = get_records_sql($sql);
+ $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
+ foreach ($wiki_entries as $wiki_entry) {
+ $key = $ME.'?id='.$id.'&groupid='.$wiki_entry->groupid.'&wikipage='.$wiki_entry->pagename;
+ $wikis[$key] = $wiki_entry->gname.':'.$wiki_entry->pagename;
+ if ($currentid == $wiki_entry->id) {
+ $wikis['selected'] = $key;
+ }
+ }
+ }
+ break;
+
+ case 'teacher':
+ if ($isteacher) {
+ /// If the user is an editing teacher, or a non-editing teacher not assigned to a group, show all
+ /// teacher wikis, regardless of creation.
+ if ($groupmode and ($isteacheredit or ($isteacher and !$mygroupid))) {
+ if ($groups = get_groups($course->id)) {
+ $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
+
+ foreach ($groups as $group) {
+ /// If this group already has an entry, use its pagename.
+ if ($wiki_entries[$group->id]) {
+ $pagename = $wiki_entries[$group->id]->pagename;
+ }
+ else {
+ $pagename = $defpagename;
+ }
+
+ $key = $ME.'?id='.$id.'&groupid='.$group->id.'&wikipage='.$pagename;
+ $wikis[$key] = $group->name.':'.$pagename;
+ }
+ }
+ }
+ /// A teacher can see all other group teacher wikis.
+ else if ($groupmode) {
+ $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
+ .' FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'groups g '
+ .' WHERE w.wikiid = '.$wiki->id.' AND g.id = w.groupid '
+ .' ORDER BY w.groupid';
+ $wiki_entries = get_records_sql($sql);
+ $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
+ foreach ($wiki_entries as $wiki_entry) {
+ $key = $ME.'?id='.$id.'&groupid='.$wiki_entry->groupid.'&wikipage='.$wiki_entry->pagename;
+ $wikis[$key] = $wiki_entry->gname.':'.$wiki_entry->pagename;
+ if ($currentid == $wiki_entry->id) {
+ $wikis['selected'] = $key;
+ }
+ }
+ }
+ }
+ else {
+ /// A user can see other teacher wikis if they are a teacher, a member of the same
+ /// group (for separate groups) or there are visible groups.
+ if ($groupmode == VISIBLEGROUPS) {
+ $viewall = true;
+ }
+ else if ($groupmode == SEPARATEGROUPS) {
+ $viewall = $mygroupid;
+ }
+ else {
+ $viewall = false;
+ }
+ if ($viewall !== false) {
+ $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
+ .' FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'groups g '
+ .' WHERE w.wikiid = '.$wiki->id.' AND g.id = w.groupid '
+ .' ORDER BY w.groupid';
+ $wiki_entries = get_records_sql($sql);
+ $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
+ foreach ($wiki_entries as $wiki_entry) {
+ if (($viewall === true) or $viewall == $wiki_entry->groupid) {
+ $key = $ME.'?id='.$id.'&groupid='.$wiki_entry->groupid.'&wikipage='.$wiki_entry->pagename;
+ $wikis[$key] = $wiki_entry->gname.':'.$wiki_entry->pagename;
+ if ($currentid == $wiki_entry->id) {
+ $wikis['selected'] = $key;
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ return $wikis;
+}
+
+function wiki_add_entry(&$wiki, &$course, $userid=0, $groupid=0) {
+/// Adds a new wiki entry of the specified type, unless already entered.
+/// No checking is done here. It is assumed that the caller has the correct
+/// privileges to add this entry.
+
+ global $USER;
+
+ /// If this wiki already has a wiki_type entry, return false.
+ if (wiki_get_entry($wiki, $course, $userid, $groupid) !== false) {
+ return false;
+ }
+
+ switch ($wiki->wtype) {
+
+ case 'student':
+ $wiki_entry->wikiid = $wiki->id;
+ $wiki_entry->userid = $userid ? $userid : $USER->id;
+ $wiki_entry->pagename = wiki_page_name($wiki);
+ $wiki_entry->timemodified = time();
+ break;
+
+ case 'group':
+ /// Get the groupmode. It's been added to the wiki object.
+ $groupmode = groupmode($course, $wiki);
+
+ /// If there is a groupmode, get the group id.
+ if ($groupmode) {
+ $groupid = $groupid ? $groupid : mygroupid($course->id);
+ }
+ /// If mode is 'nogroups', then groupid is zero.
+ else {
+ $groupid = 0;
+ }
+ $wiki_entry->wikiid = $wiki->id;
+ $wiki_entry->groupid = $groupid;
+ $wiki_entry->pagename = wiki_page_name($wiki);
+ $wiki_entry->timemodified = time();
+ break;
+
+ case 'teacher':
+ /// Get the groupmode. It's been added to the wiki object.
+ $groupmode = groupmode($course, $wiki);
+
+ /// If there is a groupmode, get the user's group id.
+ if ($groupmode and $groupid == 0) {
+ $groupid = mygroupid($course->id);
+ }
+
+ $wiki_entry->wikiid = $wiki->id;
+ $wiki_entry->course = $wiki->course;
+ $wiki_entry->groupid = $groupid;
+ $wiki_entry->pagename = wiki_page_name($wiki);
+ $wiki_entry->timemodified = time();
+ break;
+ }
+ return insert_record("wiki_entries", $wiki_entry, true);
+}
+
+function wiki_can_add_entry(&$wiki, &$user, &$course, $userid=0, $groupid=0) {
+/// Returns true or false if the user can add a wiki entry for this wiki.
+
+ /// Get the groupmode. It's been added to the wiki object.
+ $groupmode = groupmode($course, $wiki);
+ $mygroupid = mygroupid($course->id);
+ $site = get_site();
+
+ switch ($wiki->wtype) {
+
+ case 'student':
+/// A student can create their own wiki, if they are a member of that course.
+/// A user can create their own wiki at the site level.
+ if ($userid == 0) {
+ return (isstudent($course->id, $user->id) or
+ (($site->id == $course->id) and !empty($user) and !isguest()));
+ }
+/// An editing teacher can create any student wiki, or
+/// a non-editing teacher, if not assigned to a group can create any student wiki, or if assigned to a group can
+/// create any student wiki in their group.
+ else {
+ return ((($userid == $user->id) and isstudent($course->id, $user->id)) or isteacheredit($course->id) or
+ (isteacher($course->id) and (!$groupmode or $mygroupid == 0 or (ismember($mygroupid, $userid)))));
+ }
+ break;
+
+ case 'group':
+ /// If mode is 'nogroups', then all participants can add wikis.
+ if (!$groupmode) {
+ return (isstudent($course->id, $user->id) or isteacher($course->id, $user->id) or
+ (($site->id == $course->id) and !empty($user) and !isguest()));
+ }
+ /// If not requesting a group, must be a member of a group.
+ else if ($groupid == 0) {
+ return ($mygroupid != 0);
+ }
+ /// If requesting a group, must be an editing teacher, a non-editing teacher with no assigned group,
+ /// or a non-editing teacher requesting their group.
+ else {
+ return (isteacheredit($course->id) or
+ (isteacher($course->id) and ($mygroupid == 0 or $mygroupid == $groupid)));
+ }
+ break;
+
+ case 'teacher':
+ /// If mode is 'nogroups', then all teachers can add wikis.
+ if (!$groupmode) {
+ return (isteacher($course->id, $user->id) or (($site->id == $course->id) and isadmin()));
+ }
+ /// If not requesting a group, must be a member of a group.
+ else if ($groupid == 0) {
+ return ($mygroupid != 0 and isteacher($course->id));
+ }
+ /// If there is a group mode, non-editing teachers with an assigned group, can only create wikis
+ /// in their group. Non-editing teachers with no assigned group and editing teachers can create any wiki.
+ else {
+ return (isteacheredit($course->id) or
+ (isteacher($course->id) and ($mygroupid == 0 or $mygroupid == $groupid)));
+ }
+ break;
+ }
+
+ return false;
+}
+
+function wiki_can_edit_entry(&$wiki_entry, &$wiki, &$user, &$course) {
+/// Returns true or false if the user can edit this wiki entry.
+
+ $can_edit = false;
+ $groupmode = groupmode($course, $wiki);
+ $mygroupid = mygroupid($course->id);
+ $site = get_site();
+
+ /// Editing teacher's and admins can edit all wikis, non-editing teachers can edit wikis in their groups,
+ /// or all wikis if group mode is 'no groups' or they don't belong to a group.
+ if (isadmin() or isteacheredit($course->id, $user->id) or
+ ((!$groupmode or $mygroupid == 0) and isteacher($course->id, $user->id))) {
+ $can_edit = true;
+ }
+ else {
+ switch ($wiki->wtype) {
+
+ /// Only a teacher or the owner of a student wiki can edit it.
+ case 'student':
+ $can_edit = (($user->id == $wiki_entry->userid) or
+ ($groupmode and isteacher($course->id, $user->id) and
+ ismember($mygroupid, $wiki_entry->userid)));
+ break;
+
+ case 'group':
+ /// If there is a groupmode, determine the user's group status.
+ if ($groupmode) {
+ /// If the user is a member of the wiki group, they can edit the wiki.
+ $can_edit = ismember($wiki_entry->groupid, $user->id);
+ }
+ /// If mode is 'nogroups', then all participants can edit the wiki.
+ else {
+ $can_edit = (isstudent($course->id, $user->id) or isteacher($course->id, $user->id) or
+ (($site->id == $course->id) and !empty($user) and !isguest()));
+ }
+ break;
+
+ case 'teacher':
+ /// If there is a groupmode, determine the user's group status.
+ if ($groupmode) {
+ /// If the user is a member of the wiki group, they can edit the wiki.
+ $can_edit = (isteacher($course->id, $user->id) and ismember($wiki_entry->groupid, $user->id));
+ }
+ else {
+ $can_edit = (isteacher($course->id, $user->id) or (($site->id == $course->id) and isadmin()));
+ }
+ break;
+ }
+ }
+
+ return $can_edit;
+}
+
+function wiki_user_can_access_student_wiki(&$wiki, $userid, &$course) {
+ global $USER;
+
+ /// Get the groupmode. It's been added to the wiki object.
+ $groupmode = groupmode($course, $wiki);
+ $usersgroup = mygroupid($course->id);
+ $isteacher = isteacher($course->id, $USER->id);
+
+ /// If this user is allowed to access this wiki then return TRUE.
+ /// *** THIS COULD BE A PROBLEM, IF STUDENTS COULD EVER BE PART OF MORE THAN ONE GROUP ***
+ /// A user can access a student wiki, if:
+ /// - it is their wiki,
+ /// - group mode is VISIBLEGROUPS,
+ /// - group mode is SEPARATEGROUPS, and the user is a member of the requested user's group,
+ /// - they are an editing teacher or administrator,
+ /// - they are a non-editing teacher not assigned to a specific group,
+ /// - they are a non-editing teacher and group mode is NOGROUPS.
+ /// - they are an administrator (mostly for site-level wikis).
+ if (($userid and ($USER->id == $userid)) or ($groupmode == VISIBLEGROUPS) or
+ (($groupmode == SEPARATEGROUPS) and ismember($usersgroup, $userid)) or
+ (isteacheredit($course->id, $USER->id)) or
+ (isteacher($course->id, $USER->id) and (!$usersgroup or ($groupmode == NOGROUPS))) or
+ (isadmin())) {
+ $can_access = true;
+ }
+ else {
+ $can_access = false;
+ }
+ return $can_access;
+}
+
+function wiki_user_can_access_group_wiki(&$wiki, $groupid, &$course) {
+ global $USER;
+
+ /// Get the groupmode. It's been added to the wiki object.
+ $groupmode = groupmode($course, $wiki);
+ $usersgroup = mygroupid($course->id);
+ $isteacher = isteacher($course->id, $USER->id);
+
+ /// A user can access a group wiki, if:
+ /// - group mode is NOGROUPS,
+ /// - group mode is VISIBLEGROUPS,
+ /// - group mode is SEPARATEGROUPS, and they are a member of the requested group,
+ /// - they are an editing teacher or administrator,
+ /// - they are a non-editing teacher not assigned to a specific group.
+ if (($groupmode == NOGROUPS) or ($groupmode == VISIBLEGROUPS) or
+ (($groupmode == SEPARATEGROUPS) and ($usersgroup == $groupid)) or
+ (isteacheredit($course->id, $USER->id)) or
+ (isteacher($course->id, $USER->id) and !$usersgroup)) {
+ $can_access = true;
+ }
+ else {
+ $can_access = false;
+ }
+ return $can_access;
+}
+
+function wiki_user_can_access_teacher_wiki(&$wiki, $groupid, &$course) {
+ global $USER;
+
+ /// Get the groupmode. It's been added to the wiki object.
+ $groupmode = groupmode($course, $wiki);
+
+ /// A user can access a teacher wiki, if:
+ /// - group mode is NOGROUPS,
+ /// - group mode is VISIBLEGROUPS,
+ /// - group mode is SEPARATEGROUPS, and they are a member of the requested group,
+ /// - they are a teacher or administrator,
+ if (($groupmode == NOGROUPS) or ($groupmode == VISIBLEGROUPS) or
+ (($groupmode == SEPARATEGROUPS) and (mygroupid($course->id) == $groupid)) or
+ (isteacher($course->id, $USER->id))){
+ $can_access = true;
+ }
+ else {
+ $can_access = false;
+ }
+ return $can_access;
+}
+
+function wiki_get_owner(&$wiki_entry) {
+ if ($wiki_entry->userid > 0) {
+ $user = get_record('user', 'id', $wiki_entry->userid);
+ $owner = fullname($user);
+ }
+ else if ($wiki_entry->groupid > 0) {
+ $group = get_record('groups', 'id', $wiki_entry->groupid);
+ $owner = $group->name;
+ }
+ else if ($wiki_entry->course > 0) {
+ $course = get_record('course', 'id', $wiki_entry->course);
+ $owner = $course->shortname;
+ }
+ else {
+ $owner = '- unknown -';
+ }
+ return $owner;
+}
+
+function wiki_print_search_form($cmid, $search="", $userid, $groupid, $return=false) {
+ global $CFG;
+ # TODO: Add Group and User !!!
+ $output = "<form name=\"search\" action=\"$CFG->wwwroot/mod/wiki/view.php\">";
+ $output .= "<font size=\"-1\">".get_string("search").': ';
+ $output .= "<input name=\"id\" type=\"hidden\" value=\"$cmid\">";
+ $output = $output.($groupid?"<input name=\"groupid\" type=\"hidden\" value=\"$groupid\">":"");
+ $output = $output.($userid?"<input name=\"userid\" type=\"hidden\" value=\"$userid\">":"");
+ $output .= "<input name=\"q\" type=\"text\" size=\"20\" value=\"$search\">".' ';
+ $output .= "<input value=\"".get_string("searchwiki", "wiki")."\" type=\"submit\">";
+ $output .= "</font>";
+ $output .= "<input name=\"wikipage\" type=\"hidden\" value=\"SearchPages\">";
+ $output .= "</form>";
+
+ if ($return) {
+ return $output;
+ }
+ echo $output;
+}
+
+function wiki_print_wikilinks_block($cmid, $binary=false, $return=false) {
+/// Prints a lin-list of special wiki-pages
+ global $CFG, $ewiki_title;
+
+ $links=array();
+
+ $links["PageIndex"]=get_string("pageindex", "wiki");
+ $links["NewestPages"]=get_string("newestpages", "wiki");
+ $links["MostVisitedPages"]=get_string("mostvisitedpages", "wiki");
+ $links["MostOftenChangedPages"]=get_string("mostoftenchangedpages", "wiki");
+ $links["UpdatedPages"]=get_string("updatedpages", "wiki");
+ $links["OrphanedPages"]=get_string("orphanedpages", "wiki");
+ $links["WantedPages"]=get_string("wantedpages", "wiki");
+ if($binary) {
+ $links["FileDownload"]=get_string("filedownload", "wiki");
+ }
+ popup_form(EWIKI_SCRIPT, $links, "wikilinks", "", get_string("choosewikilinks", "wiki"), "", "", $return);
+}
+
+function wiki_print_page_actions($cmid, $specialpages, $wikipage, $action, $binary=false, $canedit=true) {
+/// Displays actions which can be performed on the page
+
+ $page=array();
+
+ // Edit this Page
+ if (in_array($action, array("edit", "links", "info", "attachments"))) {
+ $page["view/$wikipage"]=get_string("viewpage","wiki");
+ }
+ if ($canedit && !in_array($wikipage, $specialpages) && $action != "edit") {
+ $page["edit/$wikipage"]=get_string("editthispage","wiki");
+ }
+ if ($action != "links") {
+ $page["links/$wikipage"]=get_string("backlinks","wiki");
+ }
+ if ($canedit && !in_array($wikipage, $specialpages) && $action!="info") {
+ $page["info/$wikipage"]=get_string("pageinfo","wiki");
+ }
+ if($canedit && $binary && !in_array($wikipage, $specialpages) && $action != "attachments") {
+ $page["attachments/$wikipage"]=get_string("attachments","wiki");
+ }
+
+ popup_form(EWIKI_SCRIPT, $page, "wikiactions", "", get_string("action", "wiki"), "", "", false);
+}
+
+function wiki_print_administration_actions($cmid, $userid, $groupid, $wikipage, $noeditor) {
+/// Displays actions which can be performed on the page
+ global $ME;
+
+
+ /// Create the URL
+ $ewscript = 'admin.php?id='.$cmid;
+ if (isset($userid)) $ewscript .= '&userid='.$userid;
+ if (isset($groupid)) $ewscript .= '&groupid='.$groupid;
+ if (isset($wikipage)) $ewscript .= '&wikipage='.$wikipage;
+ $ewscript.="&action=";
+
+
+ $action=array(
+ "removepages" => get_string("removepages", "wiki"),
+ "strippages" => get_string("strippages", "wiki"),
+ "setpageflags" => get_string("setpageflags", "wiki"),
+ "revertpages" => get_string("revertpages", "wiki"),
+ );
+ // We cannot do certain things if html is used !
+ if($noeditor) {
+ $action["checklinks"]=get_string("checklinks", "wiki");
+ }
+ popup_form($ewscript, $action, "wikiadministration", "", get_string("chooseadministration", "wiki"), "", "", false);
+}
+
+function wiki_admin_get_flagarray() {
+ $ret = array(
+ EWIKI_DB_F_TEXT => get_string("flagtxt","wiki"),
+ EWIKI_DB_F_BINARY => get_string("flagbin","wiki"),
+ EWIKI_DB_F_DISABLED => get_string("flagoff","wiki"),
+ EWIKI_DB_F_HTML => get_string("flaghtm","wiki"),
+ EWIKI_DB_F_READONLY => get_string("flagro","wiki"),
+ EWIKI_DB_F_WRITEABLE => get_string("flagwr","wiki"),
+ );
+
+ return $ret;
+}
+
+///////// Ewiki Administration. Mostly taken from the ewiki/tools folder and changed
+function wiki_admin_setpageflags_list($pageflagstatus) {
+ $FD = wiki_admin_get_flagarray();
+ $table->head = array(get_string("pagename","wiki"), get_string("flags","wiki"));
+ if($pageflagstatus) {
+ $table->head[]=get_string("status","wiki");
+ }
+
+ $result = ewiki_database("GETALL", array("version", "flags"));
+ while ($row = $result->get()) {
+ $id = $row["id"];
+ $data = ewiki_database("GET", $row);
+
+ $cell_pagename="";
+ $cell_flags="";
+ if ($data["flags"] & EWIKI_DB_F_TEXT) {
+ $cell_pagename .= '<A HREF="' . EWIKI_SCRIPT . $id . '">';
+ } else {
+ $cell_pagename .= '<A HREF="' . EWIKI_SCRIPT_BINARY . $id . '">';
+ }
+ $cell_pagename .= htmlentities($id) . '</A> / '.get_string("version","wiki").": ".$row["version"];
+
+ foreach ($FD as $n=>$str) {
+ $cell_flags .='<INPUT TYPE="checkbox" NAME="flags['. rawurlencode($id)
+ . '][' . $n . ']" VALUE="1" '
+ . (($data["flags"] & $n) ? "CHECKED" : "")
+ . '>'.$str. ' ';
+ }
+ if($pageflagstatus) {
+ $table->data[]=array($cell_pagename, $cell_flags, $pageflagstatus[$id]);
+ } else {
+ $table->data[]=array($cell_pagename, $cell_flags);
+ }
+ }
+ return $table;
+}
+
+function wiki_admin_setpageflags($pageflags) {
+ $FD = wiki_admin_get_flagarray();
+
+ $status=array();
+ if($pageflags) {
+ foreach($pageflags as $page=>$fa) {
+
+ $page = rawurldecode($page);
+
+ $flags = 0;
+ $fstr = "";
+ foreach($fa as $num=>$isset) {
+ if ($isset) {
+ $flags += $num;
+ $fstr .= ($fstr?",":""). $FD[$num];
+ }
+ }
+
+ #$status[$page] .= "{$flags}=[{$fstr}]";
+
+ $data = ewiki_database("GET", array("id" => $page));
+
+ if ($data["flags"] != $flags) {
+ $data["flags"] = $flags;
+ $data["author"] = "ewiki-tools, " . ewiki_author();
+ $data["version"]++;
+ ewiki_database("WRITE", $data);
+ $status[$page] = "<b>".get_string("flagsset","wiki")."</b> ".$status[$page];
+ }
+ }
+ }
+ return $status;
+}
+
+
+function wiki_admin_remove_list($listall="") {
+ /// Table header
+ $table->head = array(" ", get_string("pagename","wiki"), get_string("errororreason","wiki"));
+
+ /// Get all pages
+ $result = ewiki_database("GETALL", array("version"));
+ $selected = array();
+
+ /// User wants to see all pages
+ if ($listall) {
+ while ($row = $result->get()) {
+ $selected[$row["id"]] = get_string("listall","wiki")."<br>";
+ }
+ }
+ while ($page = $result->get()) {
+ $id = $page["id"];
+ $page = ewiki_database("GET", array("id"=>$id));
+ $flags = $page["flags"];
+ #print "$id ".strlen(trim(($page["content"])))."<br>";
+
+ if (!strlen(trim(($page["content"]))) && !($flags & EWIKI_DB_F_BINARY)) {
+ @$selected[$id] .= get_string("emptypage","wiki")."<br>";
+ }
+
+ // Check for orphaned pages
+ $result2 = ewiki_database("SEARCH", array("content" => $id));
+ $orphanedpage=true;
+ if ($result2 && $result2->count()) {
+ while ($row = $result2->get()) {
+ $checkcontent = ewiki_database("GET", array("id"=>$row["id"]));
+ $checkcontent = strtolower($checkcontent["content"]);
+
+ if(strpos($checkcontent, strtolower($id)) !== false) {
+ $orphanedpage=false;
+ }
+
+ #echo "rc({$row['id']})==>($id): $check2 <br>";
+ }
+ }
+
+ /// Some more reasons for Deletion...
+ if ($orphanedpage && $id!=EWIKI_PAGE_INDEX &&!($flags & EWIKI_DB_F_BINARY)) {
+ @$selected[$id] .= get_string("orphanedpage","wiki")."<br>";
+ }
+
+ if ($flags & EWIKI_DB_F_DISABLED) {
+ @$selected[$id] .= get_string("disabledpage","wiki")."<br>";
+ }
+
+ if (($flags & 3) == 3) {
+ @$selected[$id] .= get_string("errorbinandtxt","wiki")."<br>";
+ }
+
+ if (!($flags & 3)) {
+ @$selected[$id] .= get_string("errornotype","wiki")."<br>";
+ }
+
+ if ($flags & EWIKI_DB_F_HTML) {
+ @$selected[$id] .= get_string("errorhtml","wiki")."<br>";
+ }
+
+ if (($flags & EWIKI_DB_F_READONLY) && !($flags & EWIKI_DB_F_BINARY)) {
+ @$selected[$id] .= get_string("readonly","wiki")."<br>";
+ }
+
+ if (($flags & EWIKI_DB_F_READONLY) && ($flags & EWIKI_DB_F_WRITEABLE)) {
+ @$selected[$id] .= get_string("errorroandwr","wiki")."<br>";
+ }
+
+ if (strlen($page["content"]) >= 65536) {
+ @$selected[$id] .= get_string("errorsize","wiki")."<br>";
+ }
+
+ if (strpos($page["refs"], "\n".get_string("deletemewikiword","wiki")."\n")!==false) {
+ @$selected[$id] .= get_string("deletemewikiwordfound","wiki",get_string("deletemewikiword","wiki"))."<br>";
+ }
+ }
+
+ foreach ($selected as $id => $reason) {
+ $table_checkbox='<INPUT TYPE="checkbox" VALUE="'.rawurlencode($id).'" NAME="pagestodelete[]">';
+
+ #-- link & id
+ if (strpos($id, EWIKI_IDF_INTERNAL) === false) {
+ $table_page='<A HREF="' . ewiki_script("", $id) . '">';
+ } else {
+ $table_page='<A HREF="' . ewiki_script_binary("", $id) . '">';
+ }
+ $table_page .= htmlentities($id) . '</A>';
+
+ #-- print reason
+ $table_reason=$reason;
+
+ $table->data[]=array($table_checkbox, $table_page, $table_reason);
+ }
+
+ return $table;
+}
+
+/// This function actually removes the pages
+function wiki_admin_remove($pagestodelete, $course, $wiki, $userid, $groupid) {
+ $ret="";
+ foreach ($pagestodelete as $id) {
+
+ $id = rawurldecode($id);
+
+ $data = ewiki_database("GET", array("id"=>$id));
+ for ($version=1; $version<=$data["version"]; $version++) {
+ ewiki_database("DELETE", array("id"=>$id, "version"=>$version));
+ if($data["flags"] & EWIKI_DB_F_BINARY) {
+ $filepath=moodle_binary_get_path($id, $data["meta"], $course, $wiki, $userid, $groupid);
+ @unlink("$filepath");
+ }
+ }
+
+ }
+ return $ret;
+}
+
+function wiki_admin_strip_list($pagestostrip="",$version="",$err="") {
+ /// Table header
+ $table->head = array(" ", get_string("pagename","wiki"), get_string("deleteversions","wiki"));
+
+ $vc=ewiki_database("COUNTVERSIONS", array());
+ $result = ewiki_database("GETALL",array());
+ $i=0;
+ while ($row = $result->get()) {
+ $id = $row["id"];
+ if($vc[$id]>1) {
+ $error="";
+ if($err[$id]) {
+ $error=" ".join(", ",$err[$id]);
+ }
+ $checked="";
+ if($pagestostrip=="" || $pagestostrip[$i]) {
+ $checked=" CHECKED";
+ }
+ if($version=="") {
+ $versiondefault="1-".($row["version"]-1);
+ } else {
+ $versiondefault=$version[$i];
+ }
+ $table->data[]=array('<input type="checkbox" value="'.rawurlencode($id).'" name="pagestostrip['.$i.']" '.$checked.'>',
+ '<A HREF="'.EWIKI_SCRIPT.$id.'">'.htmlentities($id).'</A> / '.get_string("version","wiki").": ".$row["version"],
+ '<input name="version['.$i.']" value="'.$versiondefault.'" size="7">'.$error);
+
+ }
+ $i++;
+ }
+ return $table;
+}
+
+function wiki_admin_strip_versions($pagestostrip, $version, &$err) {
+ $ret=array();
+ foreach ($pagestostrip as $key => $id_ue) {
+
+ $id = rawurldecode($id_ue);
+ if (preg_match('/^(\d+)[-\s._:]+(\d+)$/', trim($version[$key]), $uu)) {
+ $versA = $uu[1];
+ $versZ = $uu[2];
+
+ // Let the last Version in the database
+ $checkdata = ewiki_database("GET", array("id" => $id_ue));
+ if($versZ>=$checkdata["version"]) {
+ $err[$id][] = get_string("versionrangetoobig","wiki");
+ } else {
+ if($versA<=$versZ) {
+ for ($v=$versA; $v<=$versZ; $v++) {
+ $ret[$id][]=$v;
+ }
+ } else {
+ $err[$id][]=get_string("wrongversionrange","wiki",$version[$key]);
+ }
+ }
+ }
+ else {
+ $err[$id][]=get_string("wrongversionrange","wiki",$version[$key]);
+ }
+ }
+ return $ret;
+}
+
+function wiki_admin_strip($pagestostrip) {
+ /// Purges old page-versions
+ foreach($pagestostrip as $id => $versions) {
+ foreach($versions as $version) {
+ ewiki_database("DELETE", array("id"=>$id, "version"=>$version));
+ }
+ }
+}
+
+function wiki_admin_checklinks_list() {
+ $ret=array();
+ $result = ewiki_database("GETALL",array());
+ while ($row = $result->get()) {
+ if(!($row["flags"] & EWIKI_DB_F_BINARY)) {
+ $index=htmlentities($row["id"]);
+ $ret[$index] = $row["id"];
+ }
+ }
+ return $ret;
+}
+
+function wiki_admin_checklinks($pagetocheck) {
+ /// Checks http:// Links
+ $ret="";
+ if($pagetocheck) {
+ $get = ewiki_database("GET", array("id" => $pagetocheck));
+ $content = $get["content"];
+
+ preg_match_all('_(http://[^\s"\'<>#,;]+[^\s"\'<>#,;.])_', $content, $links);
+ $badlinks = array();
+ if(!$links[1]) {
+ $ret = get_string("nolinksfound","wiki")."<br><br>";
+ } else {
+ foreach ($links[1] as $href) {
+ #print "[ $href ]";
+ #$d = @implode("", @file($href));
+ $d="";
+ if($checkfd = @fopen($href, 'r')) {
+ fclose($checkfd);
+ $d="OK";
+ }
+ if (empty($d) || !strlen(trim($d)) || stristr("not found", $d) || stristr("error 404", $d)) {
+ $ret.="[".get_string("linkdead","wiki")."] $href <br>\n";
+ $badlinks[] = $href;
+ } else {
+ $ret.="[".get_string("linkok","wiki")."] $href <br>\n";
+ }
+ }
+ }
+
+ /// Remove old Notices
+ $content = eregi_replace(' µµ__~\['.get_string("offline","wiki").'\]__µµ ','', $content);
+
+ #-- replace dead links
+ foreach ($badlinks as $href) {
+ $content = preg_replace("\377^(.*)($href)\377m", '$1 µµ__~['.get_string("offline","wiki").']__µµ $2', $content);
+ }
+
+ #-- compare against db content
+ if ($content != $get["content"]) {
+ $get["content"] = $content;
+ $get["version"]++;
+ $get["author"] = ewiki_author("ewiki_checklinks");
+ $get["lastmodified"] = time();
+
+ ewiki_database("WRITE", $get);
+ }
+ }
+ return $ret;
+}
+
+function wiki_admin_revert($proceed, $authorfieldpattern, $changesfield, $howtooperate, $deleteversions) {
+ $ret="";
+ #-- params
+ $m_time = $changesfield * 3600;
+ $depth = $deleteversions - 1;
+ $depth = ($depth>0?$depth:0);
+
+ #-- walk through
+ $result = ewiki_database("GETALL", array("id", "author", "lastmodified"));
+ while ($row = $result->get()) {
+ $id = $row["id"];
+ #-- which versions to check
+ $verZ = $row["version"];
+ if ($howtooperate=="lastonly") {
+ $verA = $verZ;
+ }
+ else {
+ $verA = $verZ-$depth;
+ if ($verA <= 0) {
+ $verA = 1;
+ }
+ }
+
+ for ($ver=$verA; $ver<=$verZ; $ver++) {
+ #-- load current $ver database entry
+ if ($verA != $verZ) {
+ $row = ewiki_database("GET", array("id"=>$id, "version"=>$ver));
+ }
+
+ #-- match
+ if (stristr($row["author"], $authorfieldpattern) && ($row["lastmodified"] + $m_time > time())) {
+ $ret .= "$id (".get_string("versionstodelete","wiki").": ";
+ #-- delete multiple versions
+ if ($howtooperate=="allsince") {
+ while ($ver<=$verZ) {
+ $ret .= " $ver";
+ if ($proceed) {
+ ewiki_database("DELETE", array("id"=>$id, "version"=>$ver));
+ }
+ $ver++;
+ }
+ }
+ #-- or just the affected one
+ else {
+ $ret .= " $ver";
+ if ($proceed) {
+ ewiki_database("DELETE", $row);
+ }
+ }
+ $ret .= ")<br>";
+ break;
+ }
+ } #-- for($ver)
+ } #-- while($row)
+ return $ret;
+}
+?>
\ No newline at end of file
--- /dev/null
+<!-- This page defines the form to create or edit an instance of this module -->
+<!-- It is used from /course/mod.php. The whole instance is available as $form. -->
+
+<?php
+ require("$CFG->dirroot/mod/wiki/lib.php");
+
+ if (!isset($form->name)) {
+ $form->name = '';
+ }
+ if (!isset($form->summary)) {
+ $form->summary = '';
+ }
+ if (!isset($form->pagename)) {
+ $form->pagename = '';
+ }
+ if (!isset($form->pagename)) {
+ $form->pagename = '';
+ }
+ if (!isset($form->wtype)) {
+ $form->wtype = 'group';
+ }
+ if (!isset($form->ewikiprinttitle)) {
+ $form->ewikiprinttitle = 1;
+ }
+ if (!isset($form->htmlmode)) {
+ $form->htmlmode = 2 ;
+ }
+ if (!isset($form->ewikiacceptbinary)) {
+ $form->ewikiacceptbinary = 0;
+ }
+ if (!isset($form->initialcontent)) {
+ $form->initialcontent = '';
+ }
+
+ /// If updating an existing wiki, find out if it has entries.
+ if ($form->id) {
+ $wikihasentries = wiki_has_entries($form);
+ }
+?>
+
+<FORM name="form" method="post" action="<?php echo $ME ?>">
+<CENTER>
+<TABLE cellpadding=5>
+<TR valign=top>
+ <TD align=right><P><B><?php print_string('name') ?>:</B></P></TD>
+ <TD>
+ <INPUT type="text" name="name" size=30 value="<?php p($form->name) ?>">
+ </TD>
+</TR>
+<TR valign=top>
+ <TD align=right><P><B><?php print_string('summary') ?>:</B></P></TD>
+ <TD>
+ <?php print_textarea(false, 5, 60, 680, 400, "summary", $form->summary); ?>
+ </TD>
+</TR>
+
+<tr valign=top>
+ <TD align=right><P>
+ <?php helpbutton('wikitype', get_string('wikitype', 'wiki'), 'wiki'); ?>
+ <B><?php print_string('wikitype', "wiki") ?>:</B></P></TD>
+ <TD>
+ <?php
+ if ($wikihasentries) {
+ echo $WIKI_TYPES[$form->wtype];
+ }
+ else {
+ choose_from_menu($WIKI_TYPES, 'wtype', $form->wtype, "");
+ }
+ ?>
+ </TD>
+</tr>
+<TR valign=top>
+ <TD align=right><P><B><?php print_string('ewikiprinttitle', 'wiki') ?>:</B></P></TD>
+ <TD>
+ <select size="1" name="ewikiprinttitle">
+ <option value="1" <?php if ( $form->ewikiprinttitle) { echo 'selected'; }?>><?php print_string('yes') ?></option>
+ <option value="0" <?php if ( !$form->ewikiprinttitle) { echo 'selected'; }?>><?php print_string('no') ?></option>
+ </select>
+ </TD>
+</TR>
+<TR valign=top>
+ <TD align=right><P>
+ <?php helpbutton('htmlmode', get_string('htmlmode', 'wiki'), 'wiki'); ?>
+ <B><?php print_string('htmlmode', 'wiki') ?>:</B></P></TD>
+ <TD>
+ <?php
+ $htmlmodes=array( "0" => get_string("nohtml","wiki") , "1" => get_string("safehtml","wiki"), "2" => get_string("htmlonly","wiki"));
+ choose_from_menu($htmlmodes, "htmlmode", $form->htmlmode, "");
+ ?>
+ </TD>
+</TR>
+<TR valign=top>
+ <TD align=right><P>
+ <?php helpbutton('ewikiacceptbinary', get_string('ewikiacceptbinary', 'wiki'), 'wiki') ?>
+ <B><?php print_string('ewikiacceptbinary', 'wiki') ?>:</B></P></TD>
+ <TD>
+ <select size="1" name="ewikiacceptbinary">
+ <option value="1" <?php if ( $form->ewikiacceptbinary) { echo 'selected'; }?>><?php print_string('yes') ?></option>
+ <option value="0" <?php if ( !$form->ewikiacceptbinary) { echo 'selected'; }?>><?php print_string('no') ?></option>
+ </select>
+ </TD>
+</TR>
+
+<tr valign="top">
+ <td align="right"><b> Optional: </b></td>
+ <td></td>
+</tr>
+
+<TR valign=top>
+ <TD align=right><P>
+ <?php helpbutton('wikiname', get_string('wikiname', 'wiki'), 'wiki'); ?>
+ <B><?php print_string('wikiname', 'wiki') ?>:</B></P></TD>
+ <TD>
+ <?php
+ if ($wikihasentries) {
+ echo $form->pagename;
+ }
+ else {
+ ?>
+ <INPUT type="text" name="pagename" size=30 value="<?php p($form->pagename) ?>"><b> - or - </b>
+ <?php
+ }
+ ?>
+ </TD>
+</TR>
+
+<tr valign="top">
+ <td align="right" nowrap>
+ <?php helpbutton('initialcontent', get_string('initialcontent', 'wiki'), 'wiki'); ?>
+ <B><?php echo get_string("initialcontent", "wiki") ?>:</B></P>
+ </td>
+ <td>
+ <?php
+ if ($wikihasentries) {
+ echo $form->initialcontent;
+ }
+ else {
+ $strchooseafile = get_string("chooseafile", "wiki");
+ echo "<input name=\"initialcontent\" size=\"50\" value=\"$form->initialcontent\"> ";
+ button_to_popup_window ("/mod/wiki/wikifiles.php?id=$course->id",
+ "wikifiles", $strchooseafile, 500, 750, $strchooseafile);
+ }
+ ?>
+ </td>
+</tr>
+
+</TABLE>
+<!-- These hidden variables are always the same -->
+<INPUT type="hidden" name=course value="<?php p($form->course) ?>">
+<INPUT type="hidden" name=coursemodule value="<?php p($form->coursemodule) ?>">
+<INPUT type="hidden" name=section value="<?php p($form->section) ?>">
+<INPUT type="hidden" name=module value="<?php p($form->module) ?>">
+<INPUT type="hidden" name=modulename value="<?php p($form->modulename) ?>">
+<INPUT type="hidden" name=instance value="<?php p($form->instance) ?>">
+<INPUT type="hidden" name=id value="<?php p($form->instance) ?>">
+<INPUT type="hidden" name=mode value="<?php p($form->mode) ?>">
+<INPUT type="submit" value="<?php print_string('savechanges') ?>">
+</CENTER>
+</FORM>
\ No newline at end of file
--- /dev/null
+<?PHP
+ // Make sure all variables are defined
+
+ print get_string("removenotice","wiki")."<br><br>";
+
+
+?>
+<FORM ACTION="admin.php" METHOD="POST" ENCTYPE="multipart/form-data">
+<INPUT TYPE="HIDDEN" NAME="userid" VALUE="<? print $userid; ?>">
+<INPUT TYPE="HIDDEN" NAME="groupid" VALUE="<? print $groupid ?>">
+<INPUT TYPE="HIDDEN" NAME="action" VALUE="<? print $action; ?>">
+<INPUT TYPE="HIDDEN" NAME="id" VALUE="<? print $cm->id ?>">
+<INPUT TYPE="HIDDEN" NAME="wikipage" VALUE="<? print $wikipage?>">
+<?
+ $remove_table=wiki_admin_remove_list($form->listall);
+ print_table($remove_table);
+?>
+<center>
+<?
+ if(!count($remove_table->data)) {
+ print get_string("nocandidatestoremove","wiki",get_string("listall","wiki"))."<br><br>";
+ }
+?>
+<?
+ if($form->listall) {
+ print ' <input type="submit" name="listcandidates" value="'.get_string("listcandidates","wiki").'">'."\n";
+ } else {
+ print ' <input type="submit" name="listall" value="'.get_string("listall","wiki").'">'."\n";
+ }
+?>
+ <input type="submit" name="proceed" value="<? print get_string("removeselectedpages","wiki"); ?>">
+</center>
\ No newline at end of file
--- /dev/null
+<?PHP //$Id$
+ //This php script contains all the stuff to backup/restore
+ //wiki mods
+
+ //This is the "graphical" structure of the wiki mod:
+ //
+ // wiki
+ // (CL,pk->id)
+ //
+ // wiki_entries
+ // (pk->id, fk->wikiid)
+ //
+ // wiki_pages
+ // (pk->pagename,version,wiki, fk->wiki)
+ //
+ // Meaning: pk->primary key field of the table
+ // fk->foreign key to link with parent
+ // nt->nested field (recursive data)
+ // CL->course level info
+ // UL->user level info
+ // files->table may have files)
+ //
+ //-----------------------------------------------------------
+
+ function wiki_restore_mods($mod,$restore) {
+
+ global $CFG;
+
+ $status = true;
+
+ //Get record from backup_ids
+ $data = backup_getid($restore->backup_unique_code,$mod->modtype,$mod->id);
+
+ if ($data) {
+ //Now get completed xmlized object
+ $info = $data->info;
+ //traverse_xmlize($info); //Debug
+ //print_object ($GLOBALS['traverse_array']); //Debug
+ //$GLOBALS['traverse_array']=""; //Debug
+
+ //Now, build the wiki record structure
+ $wiki->course = $restore->course_id;
+ $wiki->name = backup_todb($info['MOD']['#']['NAME']['0']['#']);
+ $wiki->summary = backup_todb($info['MOD']['#']['SUMMARY']['0']['#']);
+ $wiki->pagename = backup_todb($info['MOD']['#']['PAGENAME']['0']['#']);
+ $wiki->wtype = backup_todb($info['MOD']['#']['WTYPE']['0']['#']);
+ $wiki->ewikiprinttitle = backup_todb($info['MOD']['#']['EWIKIPRINTTITLE']['0']['#']);
+ $wiki->ewikiallowsafehtml = backup_todb($info['MOD']['#']['HTMLMODE']['0']['#']);
+ $wiki->ewikiacceptbinary = backup_todb($info['MOD']['#']['EWIKIACCEPTBINARY']['0']['#']);
+ $wiki->initialcontent = backup_todb($info['MOD']['#']['INITIALCONTENT']['0']['#']);
+ $wiki->timemodified = backup_todb($info['MOD']['#']['TIMEMODIFIED']['0']['#']);
+
+
+ //The structure is equal to the db, so insert the wiki
+ $newid = insert_record ("wiki",$wiki);
+
+ //Do some output
+ echo "<ul><li>".get_string("modulename","wiki")." \"".$wiki->name."\"<br>";
+ backup_flush(300);
+
+ if ($newid) {
+ //We have the newid, update backup_ids
+ backup_putid($restore->backup_unique_code,$mod->modtype,
+ $mod->id, $newid);
+ //Restore wiki_entries
+ $status = wiki_entries_restore_mods($mod->id,$newid,$info,$restore);
+ } else {
+ $status = false;
+ }
+
+ //Finalize ul
+ echo "</ul>";
+
+ } else {
+ $status = false;
+ }
+
+ return $status;
+ }
+
+ //This function restores the wiki_entries
+ function wiki_entries_restore_mods($old_wiki_id,$new_wiki_id,$info,$restore) {
+
+ global $CFG;
+
+ $status = true;
+
+ //Get the entries array
+ $entries = $info['MOD']['#']['ENTRIES']['0']['#']['ENTRY'];
+
+ //Iterate over entries
+ for($i = 0; $i < sizeof($entries); $i++) {
+ $ent_info = $entries[$i];
+ //traverse_xmlize($ent_info); //Debug
+ //print_object ($GLOBALS['traverse_array']); //Debug
+ //$GLOBALS['traverse_array']=""; //Debug
+
+ //We'll need this later!!
+ $oldid = backup_todb($ent_info['#']['ID']['0']['#']);
+ $olduserid = backup_todb($ent_info['#']['USERID']['0']['#']);
+ $oldgroupid = backup_todb($ent_info['#']['GROUPID']['0']['#']);
+
+ //Now, build the wiki_ENTRIES record structure
+ $entry->wikiid = $new_wiki_id;
+ $entry->course= $restore->course_id;
+ $entry->userid = backup_todb($ent_info['#']['USERID']['0']['#']);
+ $entry->groupid = backup_todb($ent_info['#']['GROUPID']['0']['#']);
+ $entry->pagename = backup_todb($ent_info['#']['PAGENAME']['0']['#']);
+ $entry->timemodified = backup_todb($ent_info['#']['TIMEMODIFIED']['0']['#']);
+
+ //We have to recode the userid field
+ $user = backup_getid($restore->backup_unique_code,"user",$entry->userid);
+ if ($user) {
+ $entry->userid = $user->new_id;
+ }
+ $group = backup_getid($restore->backup_unique_code,"group",$entry->groupid);
+ if ($group) {
+ $entry->groupid = $group->new_id;
+ }
+ //If userinfo was selected, restore the entry
+ if ($restore->mods['wiki']->userinfo) {
+ //The structure is equal to the db, so insert the wiki_entries
+ $newid = insert_record ("wiki_entries",$entry);
+
+ //Do some output
+ if (($i+1) % 50 == 0) {
+ echo ".";
+ if (($i+1) % 1000 == 0) {
+ echo "<br>";
+ }
+ backup_flush(300);
+ }
+ if ($newid) {
+ //We have the newid, update backup_ids
+ backup_putid($restore->backup_unique_code,"wiki_entries",$oldid,$newid);
+ //Get old wiki id from backup_ids
+ $rec = get_record("backup_ids","backup_code",$restore->backup_unique_code,
+ "table_name","wiki",
+ "new_id",$new_wiki_id);
+ //Now copy moddata associated files
+ $status = wiki_restore_files ($rec->old_id, $new_wiki_id, $oldid, $newid, $restore);
+
+ //Restore wiki_pages
+ $status = wiki_pages_restore_mods($oldid,$newid,$ent_info,$restore);
+ } else {
+ $status = false;
+ }
+ }
+ }
+ return $status;
+ }
+
+ //This function restores the wiki_pages
+ function wiki_pages_restore_mods($old_entry_id,$new_entry_id,$info,$restore) {
+
+ global $CFG;
+
+ $status = true;
+
+ //Get the comments array
+ $pages = $info['#']['PAGES']['0']['#']['PAGE'];
+
+ //Iterate over pages
+ for($i = 0; $i < sizeof($pages); $i++) {
+ $pag_info = $pages[$i];
+ //traverse_xmlize($com_info); //Debug
+ //print_object ($GLOBALS['traverse_array']); //Debug
+ //$GLOBALS['traverse_array']=""; //Debug
+
+ //We'll need this later!!
+ $oldid = backup_todb($pag_info['#']['PAGENAME']['0']['#']."_".$pag_info['#']['VERSION']['0']['#']."_".$pag_info['#']['WIKI']['0']['#']);
+
+ //Now, build the wiki_page record structure
+ $page->wiki = $new_entry_id;
+ $page->pagename = backup_todb($pag_info['#']['PAGENAME']['0']['#']);
+ $page->version = backup_todb($pag_info['#']['VERSION']['0']['#']);
+ $page->flags = backup_todb($pag_info['#']['FLAGS']['0']['#']);
+ $page->content = backup_todb($pag_info['#']['CONTENT']['0']['#']);
+ $page->author = backup_todb($pag_info['#']['AUTHOR']['0']['#']);
+ $page->created = backup_todb($pag_info['#']['CREATED']['0']['#']);
+ $page->lastmodified = backup_todb($pag_info['#']['LASTMODIFIED']['0']['#']);
+ $page->refs = backup_todb($pag_info['#']['REFS']['0']['#']);
+ $page->meta = backup_todb($pag_info['#']['META']['0']['#']);
+ $page->hits = backup_todb($pag_info['#']['HITS']['0']['#']);
+ //The structure is equal to the db, so insert the wiki_comments
+ insert_record ("wiki_pages",$page, false,"pagename");
+#print "<pre>"; print_r($page); print "</pre>";
+ print ($r?"TRUE":"FALSE")."<br>\n";
+ #$newid = insert_record ("wiki_pages",$page);
+ #if($newid) {
+ # $newid = backup_todb($pag_info['#']['PAGENAME']['0']['#']."_".$pag_info['#']['VERSION']['0']['#']."_".$new_entry_id);
+ #}
+ //Do some output
+ if (($i+1) % 50 == 0) {
+ echo ".";
+ if (($i+1) % 1000 == 0) {
+ echo "<br>";
+ }
+ backup_flush(300);
+ }
+ #if ($newid) {
+ # //We have the newid, update backup_ids
+ # backup_putid($restore->backup_unique_code,"wiki_pages",$oldid,$newid);
+ #} else {
+ # $status = false;
+ #}
+ }
+ return $status;
+ }
+
+ function wiki_restore_files ($oldwikiid, $newwikiid, $oldentryid, $newentryid, $restore) {
+
+ global $CFG;
+
+ $status = true;
+ $todo = false;
+ $moddata_path = "";
+ $forum_path = "";
+ $temp_path = "";
+
+ //First, we check to "course_id" exists and create is as necessary
+ //in CFG->dataroot
+ $dest_dir = $CFG->dataroot."/".$restore->course_id;
+ $status = check_dir_exists($dest_dir,true);
+
+ //First, locate course's moddata directory
+ $moddata_path = $CFG->dataroot."/".$restore->course_id."/".$CFG->moddata;
+
+ //Check it exists and create it
+ $status = check_dir_exists($moddata_path,true);
+
+ //Now, locate forum directory
+ if ($status) {
+ $wiki_path = $moddata_path."/wiki";
+ //Check it exists and create it
+ $status = check_dir_exists($wiki_path,true);
+ }
+
+ //Now locate the temp dir we are restoring from
+ if ($status) {
+ $temp_path = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code.
+ "/moddata/wiki/".$oldwikiid."/".$oldentryid;
+ //Check it exists
+ if (is_dir($temp_path)) {
+ $todo = true;
+ }
+ }
+
+ //If todo, we create the neccesary dirs in course moddata/forum
+ if ($status and $todo) {
+ //First this forum id
+ $this_wiki_path = $wiki_path."/".$newwikiid;
+ $status = check_dir_exists($this_wiki_path,true);
+ //Now this post id
+ $entry_wiki_path = $this_wiki_path."/".$newentryid;
+ //And now, copy temp_path to post_forum_path
+ $status = backup_copy_file($temp_path, $entry_wiki_path);
+ }
+
+ return $status;
+ }
+?>
\ No newline at end of file
--- /dev/null
+<?PHP
+ // Make sure all variables are defined
+if (!isset($form->deleteversions)) {
+ $form->deleteversions = 1;
+}
+if (!isset($form->changesfield)) {
+ $form->changesfield = 72;
+}
+
+?>
+<FORM ACTION="admin.php" METHOD="POST" ENCTYPE="multipart/form-data">
+<INPUT TYPE="HIDDEN" NAME="userid" VALUE="<? print $userid; ?>">
+<INPUT TYPE="HIDDEN" NAME="groupid" VALUE="<? print $groupid ?>">
+<INPUT TYPE="HIDDEN" NAME="action" VALUE="<? print $action; ?>">
+<INPUT TYPE="HIDDEN" NAME="id" VALUE="<? print $cm->id ?>">
+<INPUT TYPE="HIDDEN" NAME="wikipage" VALUE="<? print $wikipage?>">
+
+<CENTER>
+<?
+if($err->remark) {
+ formerr($err->remark);
+}
+?>
+<TABLE cellpadding=5>
+<TR valign=top>
+ <TD align=right><P><B><?php print_string('authorfieldpattern','wiki') ?>:</B></P></TD>
+ <TD>
+ <INPUT type="text" name="authorfieldpattern" size=30 value="<?php p($form->authorfieldpattern) ?>">
+<?php
+ helpbutton('revertauthorfieldpattern', get_string('authorfieldpattern', 'wiki'), 'wiki');
+ if (!empty($err->authorfieldpattern)) { formerr($err->authorfieldpattern); }
+?>
+ </TD>
+</TR>
+<TR valign=top>
+ <TD align=right><P><B><?php print_string('changesfield','wiki') ?>:</B></P></TD>
+ <TD>
+ <INPUT type="text" name="changesfield" size=30 value="<?php p($form->changesfield) ?>">
+ <? if (!empty($err->changesfield)) { formerr($err->changesfield); } ?>
+ </TD>
+</TR>
+<TR valign=top>
+ <TD align=right><P><B><?php print_string('howtooperate', 'wiki') ?>:</B></P></TD>
+ <TD>
+ <?php
+ $operations=array( "lastonly" => get_string("revertlastonly","wiki"),
+ "allsince" => get_string("revertallsince","wiki"),
+ "the" => get_string("revertthe","wiki"));
+ choose_from_menu($operations, "howtooperate", $form->howtooperate, "");
+ ?>
+ </TD>
+</TR>
+<TR valign=top>
+ <TD align=right><P><B><?php print_string('deleteversions','wiki') ?>:</B></P></TD>
+ <TD>
+ <INPUT type="text" name="deleteversions" size=2 value="<?php p($form->deleteversions) ?>">
+ <? if (!empty($err->deleteversions)) { formerr($err->deleteversions); } ?>
+ </TD>
+</TR>
+</TABLE>
+ <input type="submit" name="proceed" value="<? print get_string("revertchanges","wiki"); ?>">
+</center>
\ No newline at end of file
--- /dev/null
+<?PHP
+ // Make sure all variables are defined
+
+?>
+<FORM ACTION="admin.php" METHOD="POST" ENCTYPE="multipart/form-data">
+<INPUT TYPE="HIDDEN" NAME="userid" VALUE="<? print $userid; ?>">
+<INPUT TYPE="HIDDEN" NAME="groupid" VALUE="<? print $groupid ?>">
+<INPUT TYPE="HIDDEN" NAME="action" VALUE="<? print $action; ?>">
+<INPUT TYPE="HIDDEN" NAME="id" VALUE="<? print $cm->id ?>">
+<INPUT TYPE="HIDDEN" NAME="wikipage" VALUE="<? print $wikipage?>">
+<?
+ $pageflags_table=wiki_admin_setpageflags_list($pageflagstatus);
+ print_table($pageflags_table);
+?>
+<br>
+<center>
+ <input type="submit" name="proceed" value="<? print get_string("setpageflags","wiki"); ?>">
+</center>
\ No newline at end of file
--- /dev/null
+<?PHP
+ // Make sure all variables are defined
+
+?>
+<FORM ACTION="admin.php" METHOD="POST" ENCTYPE="multipart/form-data">
+<INPUT TYPE="HIDDEN" NAME="userid" VALUE="<? print $userid; ?>">
+<INPUT TYPE="HIDDEN" NAME="groupid" VALUE="<? print $groupid ?>">
+<INPUT TYPE="HIDDEN" NAME="action" VALUE="<? print $action; ?>">
+<INPUT TYPE="HIDDEN" NAME="id" VALUE="<? print $cm->id ?>">
+<INPUT TYPE="HIDDEN" NAME="wikipage" VALUE="<? print $wikipage?>">
+<?
+ $strip_table=wiki_admin_strip_list($form->pagestostrip, $form->version, $err);
+ print_table($strip_table);
+?>
+<center>
+<?
+ if(!count($strip_table->data)) {
+ print get_string("nothingtostrip","wiki")."<br><br>";
+ }
+?>
+ <input type="submit" name="proceed" value="<? print get_string("strippages","wiki"); ?>">
+</center>
\ No newline at end of file
--- /dev/null
+<?php
+ require_once("../../config.php");
+ require_once("$CFG->dirroot/course/lib.php"); // For side-blocks
+ require_once('wiki.class.php');
+
+ echo "Test Harness<br>";
+
+ $wiki = new cWiki(9);
+
+ print_object($wiki);
+?>
\ No newline at end of file
--- /dev/null
+<?PHP // $Id$
+
+/////////////////////////////////////////////////////////////////////////////////
+/// Code fragment to define the version of Wiki
+/// This fragment is called by moodle_needs_upgrading() and /admin/index.php
+/////////////////////////////////////////////////////////////////////////////////
+
+$module->version = 2004053100; // The current module version (Date: YYYYMMDDXX)
+$module->cron = 0; // Period for cron to check this module (secs)
+
+?>
--- /dev/null
+<?PHP // $Id$
+/// Extended by Michael Schneider
+/// This page prints a particular instance of wiki
+
+ require_once("../../config.php");
+ require_once("lib.php");
+# require_once("$CFG->dirroot/course/lib.php"); // For side-blocks
+
+ optional_variable($ewiki_action,""); // Action on Wiki-Page
+ optional_variable($id); // Course Module ID, or
+ optional_variable($wid); // Wiki ID
+ optional_variable($wikipage, false); // Wiki Page Name
+ optional_variable($q,""); // Search Context
+ optional_variable($userid); // User wiki.
+ optional_variable($groupid); // Group wiki.
+ optional_variable($canceledit,""); // Editing has been cancelled
+ if($canceledit) {
+ $wikipage=$ewiki_id;
+ }
+
+ if ($id) {
+ if (! $cm = get_record("course_modules", "id", $id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ if (! $course = get_record("course", "id", $cm->course)) {
+ error("Course is misconfigured");
+ }
+
+ if (! $wiki = get_record("wiki", "id", $cm->instance)) {
+ error("Course module is incorrect");
+ }
+
+ } else {
+ if (! $wiki = get_record("wiki", "id", $wid)) {
+ error("Course module is incorrect");
+ }
+ if (! $course = get_record("course", "id", $wiki->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("wiki", $wiki->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+ $id = $cm->id;
+ $_REQUEST["id"] = $id;
+ }
+
+ if ($course->category or !empty($CFG->forcelogin)) {
+ require_login($course->id);
+ }
+
+ /// Add the course module 'groupmode' to the wiki object, for easy access.
+ $wiki->groupmode = $cm->groupmode;
+
+ /// If the wiki entry doesn't exist, can this user create it?
+
+ if (($wiki_entry = wiki_get_entry($wiki, $course, $userid, $groupid)) === false) {
+
+ if (wiki_can_add_entry($wiki, $USER, $course, $userid, $groupid)) {
+ wiki_add_entry($wiki, $course, $userid, $groupid);
+ if (($wiki_entry = wiki_get_entry($wiki, $course, $userid, $groupid)) === false) {
+ error("Could not add wiki entry.");
+ }
+ }
+ else {
+ $wiki_entry_text = '<div align="center">'.get_string('nowikicreated', 'wiki').'</div>';
+ }
+ }
+
+ /// How shall we display the wiki-page ?
+ $moodle_format=FORMAT_MOODLE;
+
+ ### SAVE ID from Moodle
+ $moodleID=@$_REQUEST["id"];
+ if ($wiki_entry) {
+
+/// The wiki_entry->pagename is set to the specified value of the wiki,
+/// or the default value in the 'lang' file if the specified value was empty.
+ define("EWIKI_PAGE_INDEX",$wiki_entry->pagename);
+
+ $wikipage = ($wikipage === false) ? EWIKI_PAGE_INDEX: $wikipage;
+//////
+
+
+/// ################# EWIKI Part ###########################
+
+/// ### Prevent ewiki getting id as PageID...
+ unset($_REQUEST["id"]);
+ unset($_GET["id"]);
+ unset($_POST["id"]);
+ unset($_POST["id"]);
+ unset($_SERVER["QUERY_STRING"]);
+ unset($HTTP_GET_VARS["id"]);
+ unset($HTTP_POST_VARS["id"]);
+ global $ewiki_title;
+
+/// #-- predefine some of the configuration constants
+ define("EWIKI_NAME", $wiki_entry->pagename);
+
+ /// Search Hilighting
+ if($ewiki_title=="SearchPages") {
+ $qArgument="&q=".urlencode($q);
+ }
+
+ /// Build the ewsiki script constant
+ /// ewbase will also be needed by EWIKI_SCRIPT_BINARY
+ $ewbase = $ME.'?id='.$moodleID;
+ if (isset($userid)) $ewbase .= '&userid='.$userid;
+ if (isset($groupid)) $ewbase .= '&groupid='.$groupid;
+ $ewscript = $ewbase.'&wikipage=';
+ define("EWIKI_SCRIPT", $ewscript);
+
+ /// # Settings for this specific Wiki
+ define("EWIKI_PRINT_TITLE", $wiki->ewikiprinttitle);
+
+ define("EWIKI_INIT_PAGES", wiki_content_dir($wiki));
+
+/// # fix broken PHP setup
+ if (!function_exists("get_magic_quotes_gpc") || get_magic_quotes_gpc()) {
+ include($CFG->dirroot."/mod/wiki/ewiki/fragments/strip_wonderful_slashes.php");
+ }
+ if (ini_get("register_globals")) {
+ # include($CFG->dirroot."/mod/wiki/ewiki/fragments/strike_register_globals.php");
+ }
+
+ # Database Handler
+ include_once($CFG->dirroot."/mod/wiki/ewikimoodlelib.php");
+ # Plugins
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/email_protect.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/patchsaving.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/notify.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/feature/imgresize_gd.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/moodle/moodle_highlight.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/moodle/f_fixhtml.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/aview/backlinks.php");
+ #include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/markup/css.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/markup/footnotes.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/action/diff.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/page/pageindex.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/page/orphanedpages.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/moodle/wantedpages.php");
+
+ # Binary Handling
+ if($wiki->ewikiacceptbinary) {
+ define("EWIKI_UPLOAD_MAXSIZE", get_max_upload_file_size());
+ define("EWIKI_SCRIPT_BINARY", $ewbase."&binary=");
+ define("EWIKI_ALLOW_BINARY",1);
+ define("EWIKI_IMAGE_CACHING",1);
+ #define("EWIKI_AUTOVIEW",1);
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/lib/mime_magic.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/aview/downloads.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/moodle/downloads.php");
+ #include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/db/binary_store.php");
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/moodle/moodle_binary_store.php");
+ } else {
+ define("EWIKI_SCRIPT_BINARY", 0);
+ define("EWIKI_ALLOW_BINARY",0);
+ }
+
+ # The mighty Wiki itself
+ include_once($CFG->dirroot."/mod/wiki/ewiki/ewiki.php");
+
+ # Language-stuff: eWiki gets language from Browser. Lets correct it. Empty arrayelements do no harm
+ $ewiki_t["languages"]=array(current_language(), $course->lang, $CFG->lang,"en","c");
+
+ # Check Access Rights
+ $canedit = wiki_can_edit_entry($wiki_entry, $wiki, $USER, $course);
+ if (!$canedit) {
+ # Protected Mode
+ unset($ewiki_plugins["action"]["edit"]);
+ unset($ewiki_plugins["action"]["info"]);
+ }
+
+ # HTML Handling
+ $ewiki_use_editor=0;
+ if($wiki->htmlmode == 0) {
+ # No HTML
+ $ewiki_config["htmlentities"]=array(); // HTML is managed by moodle
+ $moodle_format=FORMAT_TEXT;
+ }
+ if($wiki->htmlmode == 1) {
+ # Safe HTML
+ include_once($CFG->dirroot."/mod/wiki/ewiki/plugins/moodle/moodle_rescue_html.php");
+ $moodle_format=FORMAT_HTML;
+ }
+ if($wiki->htmlmode == 2) {
+ # HTML Only
+ $moodle_format=FORMAT_HTML;
+ $ewiki_use_editor=1;
+ $ewiki_config["htmlentities"]=array(); // HTML is allowed
+ $ewiki_config["wiki_link_regex"] = "\007 [!~]?(
+ \#?\[[^<>\[\]\n]+\] |
+ \^[-".EWIKI_CHARS_U.EWIKI_CHARS_L."]{3,} |
+ \b([\w]{3,}:)*([".EWIKI_CHARS_U."]+[".EWIKI_CHARS_L."]+){2,}\#?[\w\d]* |
+ \w[-_.+\w]+@(\w[-_\w]+[.])+\w{2,} ) \007x";
+ }
+
+ global $ewiki_author, $USER;
+ $ewiki_author=fullname($USER);
+ $content=ewiki_page($wikipage);
+
+ ### RESTORE ID from Moodle
+ $_REQUEST["id"]=$moodleID;
+ $id=$moodleID;
+/// ################# EWIKI Part ###########################
+ }
+ else {
+ $content = $wiki_entry_text;
+ }
+
+
+/// Moodle Log
+ add_to_log($course->id, "wiki", $ewiki_action, "view.php?id=$cm->id&groupid=$groupid&userid=$userid&wikipage=$wikipage", $wiki->name." ".$ewiki_title);
+
+
+/// Print the page header
+ if ($course->category) {
+ $navigation = "<A HREF=\"../../course/view.php?id=$course->id\">$course->shortname</A> ->";
+ }
+
+ $strwikis = get_string("modulenameplural", "wiki");
+ $strwiki = get_string("modulename", "wiki");
+
+ print_header("$course->shortname: $wiki_entry->pagename", "$course->fullname",
+ "$navigation <A HREF=\"index.php?id=$course->id\">$strwikis</A> -> <A HREF=\"view.php?id=$moodleID\">$wiki->name</a> -> $ewiki_title",
+ "", "", true, update_module_button($cm->id, $course->id, $strwiki),
+ navmenu($course, $cm));
+
+
+ /// Print Page
+
+ /// The top row contains links to other wikis, if applicable.
+ if ($wiki_list = wiki_get_other_wikis($wiki, $USER, $course, $wiki_entry->id)) {
+ $selected="";
+ if (isset($wiki_list['selected'])) {
+ $selected = $wiki_list['selected'];
+ unset($wiki_list['selected']);
+ }
+ echo '<tr><td colspan="2">';
+
+ echo '<form name="otherwikis" action="'.$CFG->wwwroot.'/mod/wiki/view.php">';
+ echo '<table border="0" cellpadding="0" cellspacing="0" width="100%"><tr>';
+ echo '<td class="sideblockheading" bgcolor="'.$THEME->cellheading.'"> '
+ .$WIKI_TYPES[$wiki->wtype].' '
+ .get_string('modulename', 'wiki')." ".get_string('for',"wiki")." "
+ .wiki_get_owner($wiki_entry).':</td>';
+
+ echo '<td class="sideblockheading" bgcolor="'.$THEME->cellheading.'" align="right">'
+ .get_string('otherwikis', 'wiki').': ';
+ $script = 'self.location=document.otherwikis.wikiselect.options[document.otherwikis.wikiselect.selectedIndex].value';
+ choose_from_menu($wiki_list, "wikiselect", $selected, "choose", $script);
+ echo '</td>';
+ echo '</tr></table>';
+ echo '</form>';
+
+ echo '</td>';
+ echo '</tr>';
+ }
+
+ if ($wiki_entry) {
+ $specialpages=array("SearchPages", "PageIndex","NewestPages","MostVisitedPages","MostOftenChangedPages","UpdatedPages","FileDownload","FileUpload","OrphanedPages","WantedPages");
+ /// Page Actions
+ echo '<table border="0" width="100%">';
+ echo '<tr>';
+
+ if ($canedit) {
+ $iconstr="";
+ $editicon= '<img hspace=1 alt="'.get_string("editthispage","wiki").'" height=16 width=16 border=0 src="'.$CFG->pixpath.'/t/edit.gif">';
+ $infoicon= '<img hspace=1 alt="'.get_string("pageinfo","wiki").'" height=16 width=16 border=0 src="'.$CFG->pixpath.'/i/info.gif">';
+ if($ewiki_action!="edit" && !in_array($wikipage, $specialpages)) {
+ $iconstr='<a title="'.get_string("editthispage","wiki").'" href="'.EWIKI_SCRIPT.'&wikipage=edit/'.$ewiki_id.'">'.$editicon."</a>";
+ } else {
+ $iconstr=$editicon;
+ }
+ if($ewiki_action!="info" && !in_array($wikipage, $specialpages)) {
+ $iconstr.='<a title="'.get_string("pageinfo","wiki").'" href="'.EWIKI_SCRIPT.'&wikipage=info/'.$ewiki_id.'">'.$infoicon."</a>";
+ } else {
+ $iconstr.=$infoicon;
+ }
+ echo "<td>$iconstr</td>";
+ }
+
+ echo '<td>';
+ wiki_print_page_actions($cm->id, $specialpages, $ewiki_id, $ewiki_action, $wiki->ewikiacceptbinary, $canedit);
+ echo '</td>';
+
+ /// Searchform
+ echo '<td align="center">';
+ wiki_print_search_form($cm->id, $q, $userid, $groupid, false);
+ echo '</td>';
+
+ /// Internal Wikilinks
+ echo '<td align="center">';
+ wiki_print_wikilinks_block($cm->id, $wiki->ewikiacceptbinary);
+ echo '</td>';
+
+ /// Administrative Links
+ if($canedit) {
+ echo '<td align="center">';
+ wiki_print_administration_actions($cm->id, $userid, $groupid, $ewiki_title, $wiki->htmlmode!=2);
+ echo '</td>';
+ }
+
+ /// Formatting Rules
+ if($wiki->htmlmode!=2) {
+ echo '<td align="center">';
+ helpbutton('wikiusage', get_string('wikiusage', 'wiki'), 'wiki');
+ echo get_string("wikiusage","wiki");
+ echo '</td>';
+ }
+
+ echo '</tr></table>';
+ }
+
+ // The wiki Summary (Closes Bug #1496)
+ if($ewiki_title==$wiki_entry->pagename && !empty($wiki->summary)) {
+ print "<br>";
+ print_simple_box(format_text($wiki->summary, FORMAT_HTML), "center", "100%");
+ print "<br>";
+ }
+
+
+ // The wiki Contents
+ print_simple_box_start( "center", "100%", "$THEME->cellcontent", "20");
+ if($ewiki_action=="edit") {
+ # When editing, the filters shall not interfere the wiki-source
+ print $content;
+ } else {
+ print(format_text($content, $moodle_format));
+ }
+ print_simple_box_end();
+
+/// Finish the page
+ print_footer($course);
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/*
+ This file contains the class definitions used by the wiki module.
+ Include these in your theme file, and modify them to your tastes.
+*/
+
+?>
+<!-- <div> that surrounds entire wiki output -->
+.wiki {
+ background-color: #FFFFFF;
+ padding: 6px;
+}
+
+<!-- action classes that work with the wiki <div> -->
+.view {
+}
+
+.edit {
+}
+
+.info {
+}
+
+.links {
+}
+
+<!-- Defines the <div> tag surrounding the backlinks feature. -->
+.wiki_backlinks {
+ border-top: 2px <?php echo $THEME->borders?> solid;
+}
+
+.indent {
+}
+
+<!-- defines the h2 class for the title -->
+h2.page.title {
+ border-bottom: 2px <?php echo $THEME->borders?> solid;
+}
+
+<!-- Defines the table used for the version information -->
+.version-info {
+}
+
+<!-- Defines the table cell used for the various version actions -->
+.action-links {
+}
+
+<!-- Defines the table cell used for the various version actions -->
+.control-links {
+}
+
+<!-- Defines the table row used for the version version row -->
+.page-version {
+}
+
+<!-- Defines the table row used for the version author row -->
+.page-author {
+}
+
+<!-- Defines the table row used for the version created row -->
+.page-created {
+}
+
+<!-- Defines the table row used for the version lastmodified row -->
+.page-lastmodified {
+}
+
+<!-- Defines the table row used for the version refs row -->
+.page-refs {
+}
+
+<!-- Defines the table row used for the version flags row -->
+.page-flags {
+}
+
+<!-- Defines the table row used for the version meta row -->
+.page-meta {
+}
+
+<!-- Defines the <div> used for the chunked results -->
+.chunked-result {
+}
+
+<!-- Defines the <div> used for the edit box -->
+.edit-box {
+}
+
+<!-- Defines the <div> used for the image upload form -->
+.image-upload {
+}
+
+<!-- Defines the <div> used for the preview page -->
+.preview {
+}
+
+<!-- Defines the <span> used for the search not found -->
+.NotFound {
+}
+
+<!-- Defines the <div> used for the todo list -->
+.ewiki_page_todolist {
+}
+
+<!-- Defines the <table> used for the diff function -->
+.diff {
+}
--- /dev/null
+<?PHP // $Id$
+
+// Manage all uploaded files in a course file area
+
+// This file is a hack to files/index.php that removes
+// the headers and adds some controls so that images
+// can be selected within the Richtext editor.
+
+// All the Moodle-specific stuff is in this top section
+// Configuration and access control occurs here.
+// Must define: USER, basedir, baseweb, html_header and html_footer
+// USER is a persistent variable using sessions
+
+ require("../../config.php");
+ require("../../files/mimetypes.php");
+
+ require_variable($id);
+ optional_variable($file, "");
+ optional_variable($wdir, "");
+ optional_variable($action, "");
+
+ if (! $course = get_record("course", "id", $id) ) {
+ error("That's an invalid course id");
+ }
+
+ require_login($course->id);
+
+ if (! isteacher($course->id) ) {
+ error("Only teachers can edit files");
+ }
+
+ function html_footer() {
+ echo "</td></tr></table></body></html>";
+ }
+
+ function html_header($course, $wdir, $formfield=""){
+
+ global $CFG,$THEME;
+
+ if (! $site = get_site()) {
+ error("Invalid site!");
+ }
+
+ if ($course->id == $site->id) {
+ $strfiles = get_string("sitefiles");
+ } else {
+ $strfiles = get_string("files");
+ }
+
+ if ($wdir == "/") {
+ $fullnav = "$strfiles";
+ } else {
+ $dirs = explode("/", $wdir);
+ $numdirs = count($dirs);
+ $link = "";
+ $navigation = "";
+ for ($i=1; $i<$numdirs; $i++) {
+ $navigation .= " -> ";
+ $link .= "/".urlencode($dirs[$i]);
+ $navigation .= "<a href=\"".$_SERVER['PHP_SELF']."?id=$course->id&wdir=$link\">".$dirs[$i]."</a>";
+ }
+ $fullnav = "<a href=\"".$_SERVER['PHP_SELF']."?id=$course->id&wdir=/\">$strfiles</a> $navigation";
+ }
+
+ print_header();
+ ?>
+ <script language="javascript" type="text/javascript">
+ <!--
+ function set_value(txt) {
+ opener.document.forms['form'].initialcontent.value = txt;
+ window.close();
+ }
+ -->
+ </script>
+ <?php
+
+ echo '<table border="0" cellpadding="3" cellspacing="0" width="100%">';
+ echo '<tr>';
+ echo '<td bgcolor="'.$THEME->cellheading.'" class="navbar">';
+ echo '<font size="2"><b>'."$course->shortname -> $fullnav".'</b></font>';
+ echo '</td>';
+ echo '</tr>';
+ echo '</table>';
+
+ if ($course->id == $site->id) {
+ print_heading(get_string("publicsitefileswarning"), "center", 2);
+ }
+
+ echo "<table border=0 align=center cellspacing=3 cellpadding=3 width=640>";
+ echo "<tr>";
+ echo "<td colspan=\"2\">";
+ }
+
+ if (! $basedir = make_upload_directory("$course->id")) {
+ error("The site administrator needs to fix the file permissions");
+ }
+
+ $baseweb = $CFG->wwwroot;
+
+// End of configuration and access control
+
+
+ $regexp="\\.\\.";
+ if (ereg( $regexp, $file, $regs )| ereg( $regexp, $wdir,$regs )) {
+ $message = "Error: Directories can not contain \"..\"";
+ $wdir = "/";
+ $action = "";
+ }
+
+ if (!$wdir) {
+ $wdir="/";
+ }
+
+
+ switch ($action) {
+
+ case "upload":
+ html_header($course, $wdir);
+
+ if (!empty($_FILES['userfile'])) {
+ $userfile = $_FILES['userfile'];
+ } else {
+ $save = false;
+ }
+ if (!empty($save)) {
+ if (!is_uploaded_file($userfile['tmp_name']) or $userfile['size'] == 0) {
+ notify(get_string("uploadnofilefound"));
+ } else {
+ $userfile_name = clean_filename($userfile['name']);
+ if ($userfile_name) {
+ $newfile = "$basedir$wdir/$userfile_name";
+ if (move_uploaded_file($userfile['tmp_name'], $newfile)) {
+ chmod($newfile, 0666);
+ $a = NULL;
+ $a->file = "$userfile_name (".$userfile['type'].")";
+ $a->directory = $wdir;
+ print_string("uploadedfileto", "", $a);
+ } else {
+ notify(get_string("uploadproblem", "", $userfile_name));
+ }
+ }
+ }
+ displaydir($wdir);
+
+ } else {
+ $upload_max_filesize = get_max_upload_file_size($CFG->maxbytes);
+ $filesize = display_size($upload_max_filesize);
+
+ $struploadafile = get_string("uploadafile");
+ $struploadthisfile = get_string("uploadthisfile");
+ $strmaxsize = get_string("maxsize", "", $filesize);
+ $strcancel = get_string("cancel");
+
+ echo "<P>$struploadafile ($strmaxsize) --> <B>$wdir</B>";
+ echo "<TABLE><TR><TD COLSPAN=2>";
+ echo "<FORM ENCTYPE=\"multipart/form-data\" METHOD=\"post\" ACTION=\"".$_SERVER['PHP_SELF']."\">";
+ echo " <INPUT TYPE=hidden NAME=MAX_FILE_SIZE value=\"$upload_max_filesize\">";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=upload>";
+ echo " <INPUT NAME=\"userfile\" TYPE=\"file\" size=\"60\">";
+ echo " </TD><TR><TD WIDTH=10>";
+ echo " <INPUT TYPE=submit NAME=save VALUE=\"$struploadthisfile\">";
+ echo "</FORM>";
+ echo "</TD><TD WIDTH=100%>";
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=\"get\">";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+ echo " <INPUT TYPE=submit VALUE=\"$strcancel\">";
+ echo "</FORM>";
+ echo "</TD></TR></TABLE>";
+ }
+ html_footer();
+ break;
+
+ case "delete":
+ if (!empty($confirm)) {
+ html_header($course, $wdir);
+ foreach ($USER->filelist as $file) {
+ $fullfile = $basedir.$file;
+ if (! fulldelete($fullfile)) {
+ echo "<BR>Error: Could not delete: $fullfile";
+ }
+ }
+ clearfilelist();
+ displaydir($wdir);
+ html_footer();
+
+ } else {
+ html_header($course, $wdir);
+ if (setfilelist($_POST)) {
+ echo "<p align=center>".get_string("deletecheckwarning").":</p>";
+ print_simple_box_start("center");
+ printfilelist($USER->filelist);
+ print_simple_box_end();
+ echo "<br />";
+ notice_yesno (get_string("deletecheckfiles"),
+ "".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&action=delete&confirm=1",
+ "".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&action=cancel");
+ } else {
+ displaydir($wdir);
+ }
+ html_footer();
+ }
+ break;
+
+ case "move":
+ html_header($course, $wdir);
+ if ($count = setfilelist($_POST)) {
+ $USER->fileop = $action;
+ $USER->filesource = $wdir;
+ echo "<p align=center>";
+ print_string("selectednowmove", "moodle", $count);
+ echo "</p>";
+ }
+ displaydir($wdir);
+ html_footer();
+ break;
+
+ case "paste":
+ html_header($course, $wdir);
+ if (isset($USER->fileop) and $USER->fileop == "move") {
+ foreach ($USER->filelist as $file) {
+ $shortfile = basename($file);
+ $oldfile = $basedir.$file;
+ $newfile = $basedir.$wdir."/".$shortfile;
+ if (!rename($oldfile, $newfile)) {
+ echo "<P>Error: $shortfile not moved";
+ }
+ }
+ }
+ clearfilelist();
+ displaydir($wdir);
+ html_footer();
+ break;
+
+ case "rename":
+ if (!empty($name)) {
+ html_header($course, $wdir);
+ $name = clean_filename($name);
+ if (file_exists($basedir.$wdir."/".$name)) {
+ echo "Error: $name already exists!";
+ } else if (!rename($basedir.$wdir."/".$oldname, $basedir.$wdir."/".$name)) {
+ echo "Error: could not rename $oldname to $name";
+ }
+ displaydir($wdir);
+
+ } else {
+ $strrename = get_string("rename");
+ $strcancel = get_string("cancel");
+ $strrenamefileto = get_string("renamefileto", "moodle", $file);
+ html_header($course, $wdir, "form.name");
+ echo "<P>$strrenamefileto:";
+ echo "<TABLE><TR><TD>";
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=\"post\" NAME=\"form\">";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=rename>";
+ echo " <INPUT TYPE=hidden NAME=oldname VALUE=\"$file\">";
+ echo " <INPUT TYPE=text NAME=name SIZE=35 VALUE=\"$file\">";
+ echo " <INPUT TYPE=submit VALUE=\"$strrename\">";
+ echo "</FORM>";
+ echo "</TD><TD>";
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+ echo " <INPUT TYPE=submit VALUE=\"$strcancel\">";
+ echo "</FORM>";
+ echo "</TD></TR></TABLE>";
+ }
+ html_footer();
+ break;
+
+ case "mkdir":
+ if (!empty($name)) {
+ html_header($course, $wdir);
+ $name = clean_filename($name);
+ if (file_exists("$basedir$wdir/$name")) {
+ echo "Error: $name already exists!";
+ } else if (! make_upload_directory("$course->id/$wdir/$name")) {
+ echo "Error: could not create $name";
+ }
+ displaydir($wdir);
+
+ } else {
+ $strcreate = get_string("create");
+ $strcancel = get_string("cancel");
+ $strcreatefolder = get_string("createfolder", "moodle", $wdir);
+ html_header($course, $wdir, "form.name");
+ echo "<P>$strcreatefolder:";
+ echo "<TABLE><TR><TD>";
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=post NAME=form>";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=mkdir>";
+ echo " <INPUT TYPE=text NAME=name SIZE=35>";
+ echo " <INPUT TYPE=submit VALUE=\"$strcreate\">";
+ echo "</FORM>";
+ echo "</TD><TD>";
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+ echo " <INPUT TYPE=submit VALUE=\"$strcancel\">";
+ echo "</FORM>";
+ echo "</TD></TR></TABLE>";
+ }
+ html_footer();
+ break;
+
+ case "edit":
+ html_header($course, $wdir);
+ if (isset($text)) {
+ $fileptr = fopen($basedir.$file,"w");
+ fputs($fileptr, stripslashes($text));
+ fclose($fileptr);
+ displaydir($wdir);
+
+ } else {
+ $streditfile = get_string("edit", "", "<B>$file</B>");
+ $fileptr = fopen($basedir.$file, "r");
+ $contents = fread($fileptr, filesize($basedir.$file));
+ fclose($fileptr);
+
+ if (mimeinfo("type", $file) == "text/html") {
+ if ($usehtmleditor = can_use_richtext_editor()) {
+ $onsubmit = "onsubmit=\"copyrichtext(document.form.text);\"";
+ } else {
+ $onsubmit = "";
+ }
+ } else {
+ $usehtmleditor = false;
+ $onsubmit = "";
+ }
+
+ print_heading("$streditfile");
+
+ echo "<TABLE><TR><TD COLSPAN=2>";
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=\"post\" NAME=\"form\" $onsubmit>";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
+ echo " <INPUT TYPE=hidden NAME=file VALUE=\"$file\">";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=edit>";
+ print_textarea($usehtmleditor, 25, 80, 680, 400, "text", $contents);
+ echo "</TD></TR><TR><TD>";
+ echo " <INPUT TYPE=submit VALUE=\"".get_string("savechanges")."\">";
+ echo "</FORM>";
+ echo "</TD><TD>";
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+ echo " <INPUT TYPE=submit VALUE=\"".get_string("cancel")."\">";
+ echo "</FORM>";
+ echo "</TD></TR></TABLE>";
+
+ if ($usehtmleditor) {
+ print_richedit_javascript("form", "text", "yes");
+ }
+
+
+ }
+ html_footer();
+ break;
+
+ case "zip":
+ if (!empty($name)) {
+ html_header($course, $wdir);
+ $name = clean_filename($name);
+ if (empty($CFG->zip)) { // Use built-in php-based zip function
+ $files = array();
+ foreach ($USER->filelist as $file) {
+ $files[] = "$basedir/$file";
+ }
+ include_once($CFG->libdir.'/pclzip/pclzip.lib.php');
+ $archive = new PclZip("$basedir/$wdir/$name");
+ if (($list = $archive->create($files,'',"$basedir/$wdir/")) == 0) {
+ error($archive->errorInfo(true));
+ }
+ } else { // Use external zip program
+ $files = "";
+ foreach ($USER->filelist as $file) {
+ $files .= basename($file);
+ $files .= " ";
+ }
+ $command = "cd $basedir/$wdir ; $CFG->zip -r $name $files";
+ Exec($command);
+ }
+ clearfilelist();
+ displaydir($wdir);
+
+ } else {
+ html_header($course, $wdir, "form.name");
+
+ if (setfilelist($_POST)) {
+ echo "<P ALIGN=CENTER>".get_string("youareabouttocreatezip").":</P>";
+ print_simple_box_start("center");
+ printfilelist($USER->filelist);
+ print_simple_box_end();
+ echo "<BR>";
+ echo "<P ALIGN=CENTER>".get_string("whattocallzip");
+ echo "<TABLE><TR><TD>";
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=post NAME=form>";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=zip>";
+ echo " <INPUT TYPE=text NAME=name SIZE=35 VALUE=\"new.zip\">";
+ echo " <INPUT TYPE=submit VALUE=\"".get_string("createziparchive")."\">";
+ echo "</FORM>";
+ echo "</TD><TD>";
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+ echo " <INPUT TYPE=submit VALUE=\"".get_string("cancel")."\">";
+ echo "</FORM>";
+ echo "</TD></TR></TABLE>";
+ } else {
+ displaydir($wdir);
+ clearfilelist();
+ }
+ }
+ html_footer();
+ break;
+
+ case "unzip":
+ html_header($course, $wdir);
+ if (!empty($file)) {
+ $strname = get_string("name");
+ $strsize = get_string("size");
+ $strmodified = get_string("modified");
+ $strstatus = get_string("status");
+ $strok = get_string("ok");
+ $strunpacking = get_string("unpacking", "", $file);
+
+ echo "<P ALIGN=CENTER>$strunpacking:</P>";
+
+ $file = basename($file);
+
+ if (empty($CFG->unzip)) { // Use built-in php-based unzip function
+ include_once($CFG->libdir.'/pclzip/pclzip.lib.php');
+ $archive = new PclZip("$basedir/$wdir/$file");
+ if (!$list = $archive->extract("$basedir/$wdir")) {
+ error($archive->errorInfo(true));
+ } else { // print some output
+ echo "<table cellpadding=\"4\" cellspacing=\"2\" border=\"0\" width=640>";
+ echo "<tr><th align=left>$strname</th>";
+ echo "<th align=right>$strsize</th>";
+ echo "<th align=right>$strmodified</th>";
+ echo "<th align=right>$strstatus</th></tr>";
+ foreach ($list as $item) {
+ echo "<tr>";
+ $item['filename'] = str_replace("$basedir/$wdir/", "", $item['filename']);
+ print_cell("left", $item['filename']);
+ if (! $item['folder']) {
+ print_cell("right", display_size($item['size']));
+ } else {
+ echo "<td> </td>";
+ }
+ $filedate = userdate($item['mtime'], get_string("strftimedatetime"));
+ print_cell("right", $filedate);
+ print_cell("right", $item['status']);
+ echo "</tr>";
+ }
+ echo "</table>";
+ }
+
+ } else { // Use external unzip program
+ print_simple_box_start("center");
+ echo "<PRE>";
+ $command = "cd $basedir/$wdir ; $CFG->unzip -o $file 2>&1";
+ passthru($command);
+ echo "</PRE>";
+ print_simple_box_end();
+ }
+
+ echo "<CENTER><FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+ echo " <INPUT TYPE=submit VALUE=\"$strok\">";
+ echo "</FORM>";
+ echo "</CENTER>";
+ } else {
+ displaydir($wdir);
+ }
+ html_footer();
+ break;
+
+ case "listzip":
+ html_header($course, $wdir);
+ if (!empty($file)) {
+ $strname = get_string("name");
+ $strsize = get_string("size");
+ $strmodified = get_string("modified");
+ $strok = get_string("ok");
+ $strlistfiles = get_string("listfiles", "", $file);
+
+ echo "<P ALIGN=CENTER>$strlistfiles:</P>";
+ $file = basename($file);
+
+ include_once($CFG->libdir.'/pclzip/pclzip.lib.php');
+ $archive = new PclZip("$basedir/$wdir/$file");
+ if (!$list = $archive->listContent("$basedir/$wdir")) {
+ notify($archive->errorInfo(true));
+
+ } else {
+ echo "<table cellpadding=\"4\" cellspacing=\"2\" border=\"0\" width=640>";
+ echo "<tr><th align=left>$strname</th><th align=right>$strsize</th><th align=right>$strmodified</th></tr>";
+ foreach ($list as $item) {
+ echo "<tr>";
+ print_cell("left", $item['filename']);
+ if (! $item['folder']) {
+ print_cell("right", display_size($item['size']));
+ } else {
+ echo "<td> </td>";
+ }
+ $filedate = userdate($item['mtime'], get_string("strftimedatetime"));
+ print_cell("right", $filedate);
+ echo "</tr>";
+ }
+ echo "</table>";
+ }
+ echo "<br><center><form action=\"".$_SERVER['PHP_SELF']."\" method=get>";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+ echo " <INPUT TYPE=submit VALUE=\"$strok\">";
+ echo "</FORM>";
+ echo "</CENTER>";
+ } else {
+ displaydir($wdir);
+ }
+ html_footer();
+ break;
+
+ case "torte":
+ if($_POST)
+ {
+ while(list($key, $val) = each($_POST))
+ {
+ if(ereg("file([0-9]+)", $key, $regs))
+ {
+ $file = $val;
+ }
+ }
+ if(@filetype($CFG->dataroot ."/". $course->id . $file) == "file")
+ {
+ if(mimeinfo("icon", $file) == "image.gif")
+ {
+ $url = $CFG->wwwroot ."/file.php?file=/" .$course->id . $file;
+ runjavascript($url);
+ }
+ else
+ {
+ print "File is not a image!";
+ }
+ }
+ else
+ {
+ print "You cannot insert FOLDER into richtext editor!!!";
+ }
+ }
+ break;
+ case "cancel";
+ clearfilelist();
+
+ default:
+ html_header($course, $wdir);
+ displaydir($wdir);
+ html_footer();
+ break;
+}
+
+
+/// FILE FUNCTIONS ///////////////////////////////////////////////////////////
+
+
+function fulldelete($location) {
+ if (is_dir($location)) {
+ $currdir = opendir($location);
+ while ($file = readdir($currdir)) {
+ if ($file <> ".." && $file <> ".") {
+ $fullfile = $location."/".$file;
+ if (is_dir($fullfile)) {
+ if (!fulldelete($fullfile)) {
+ return false;
+ }
+ } else {
+ if (!unlink($fullfile)) {
+ return false;
+ }
+ }
+ }
+ }
+ closedir($currdir);
+ if (! rmdir($location)) {
+ return false;
+ }
+
+ } else {
+ if (!unlink($location)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+
+function setfilelist($VARS) {
+ global $USER;
+
+ $USER->filelist = array ();
+ $USER->fileop = "";
+
+ $count = 0;
+ foreach ($VARS as $key => $val) {
+ if (substr($key,0,4) == "file") {
+ $count++;
+ $USER->filelist[] = rawurldecode($val);
+ }
+ }
+ return $count;
+}
+
+function clearfilelist() {
+ global $USER;
+
+ $USER->filelist = array ();
+ $USER->fileop = "";
+}
+
+
+function printfilelist($filelist) {
+ global $basedir, $CFG;
+
+ foreach ($filelist as $file) {
+ if (is_dir($basedir.$file)) {
+ echo "<img src=\"$CFG->pixpath/f/folder.gif\" height=16 width=16> $file<br>";
+ $subfilelist = array();
+ $currdir = opendir($basedir.$file);
+ while ($subfile = readdir($currdir)) {
+ if ($subfile <> ".." && $subfile <> ".") {
+ $subfilelist[] = $file."/".$subfile;
+ }
+ }
+ printfilelist($subfilelist);
+
+ } else {
+ $icon = mimeinfo("icon", $file);
+ echo "<img src=\"$CFG->pixpath/f/$icon\" height=16 width=16> $file<br>";
+ }
+ }
+}
+
+
+function print_cell($alignment="center", $text=" ") {
+ echo "<TD ALIGN=\"$alignment\" NOWRAP>";
+ echo "<FONT SIZE=\"-1\" FACE=\"Arial, Helvetica\">";
+ echo "$text";
+ echo "</FONT>";
+ echo "</TD>\n";
+}
+
+function displaydir ($wdir) {
+// $wdir == / or /a or /a/b/c/d etc
+
+ global $basedir;
+ global $id;
+ global $USER, $CFG;
+
+ $fullpath = $basedir.$wdir;
+
+ $directory = opendir($fullpath); // Find all files
+ while ($file = readdir($directory)) {
+ if ($file == "." || $file == "..") {
+ continue;
+ }
+
+ if (is_dir($fullpath."/".$file)) {
+ $dirlist[] = $file;
+ } else {
+ $filelist[] = $file;
+ }
+ }
+ closedir($directory);
+
+ $strname = get_string("name");
+ $strsize = get_string("size");
+ $strmodified = get_string("modified");
+ $straction = get_string("action");
+ $strmakeafolder = get_string("makeafolder");
+ $struploadafile = get_string("uploadafile");
+ $strwithchosenfiles = get_string("withchosenfiles");
+ $strmovetoanotherfolder = get_string("movetoanotherfolder");
+ $strmovefilestohere = get_string("movefilestohere");
+ $strdeletecompletely = get_string("deletecompletely");
+ $strcreateziparchive = get_string("createziparchive");
+ $strrename = get_string("rename");
+ $stredit = get_string("edit");
+ $strunzip = get_string("unzip");
+ $strlist = get_string("list");
+ $strchoose = get_string("choose");
+
+
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=post NAME=dirform>";
+ echo "<TABLE BORDER=0 cellspacing=2 cellpadding=2 width=640>";
+ echo "<TR>";
+ echo "<TH WIDTH=5></TH>";
+ echo "<TH ALIGN=left>$strname</TH>";
+ echo "<TH ALIGN=right>$strsize</TH>";
+ echo "<TH ALIGN=right>$strmodified</TH>";
+ echo "<TH ALIGN=right>$straction</TH>";
+ echo "</TR>\n";
+
+ if ($wdir == "/") {
+ $wdir = "";
+ }
+
+ $count = 0;
+
+ if (!empty($dirlist)) {
+ asort($dirlist);
+ foreach ($dirlist as $dir) {
+
+ $count++;
+
+ $filename = $fullpath."/".$dir;
+ $fileurl = rawurlencode($wdir."/".$dir);
+ $filesafe = rawurlencode($dir);
+ $filedate = userdate(filectime($filename), "%d %b %Y, %I:%M %p");
+
+ echo "<TR>";
+
+ print_cell("center", "<INPUT TYPE=checkbox NAME=\"file$count\" VALUE=\"$fileurl\">");
+ print_cell("left", "<A HREF=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$fileurl\"><IMG SRC=\"$CFG->pixpath/f/folder.gif\" HEIGHT=16 WIDTH=16 BORDER=0 ALT=\"Folder\"></A> <A HREF=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$fileurl\">".htmlspecialchars($dir)."</A>");
+ print_cell("right", "-");
+ print_cell("right", $filedate);
+ print_cell("right", "<A HREF=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$filesafe&action=rename\">$strrename</A>");
+
+ echo "</TR>";
+ }
+ }
+
+
+ if (!empty($filelist)) {
+ asort($filelist);
+ foreach ($filelist as $file) {
+
+ $icon = mimeinfo("icon", $file);
+
+ $count++;
+ $filename = "$fullpath/$file";
+ $fileurl = "$wdir/$file";
+ $filesafe = rawurlencode($file);
+ $fileurlsafe = rawurlencode($fileurl);
+ $filedate = userdate(filectime($filename), "%d %b %Y, %I:%M %p");
+
+ if (substr($fileurl,0,1) == '/') {
+ $selectfile = substr($fileurl,1);
+ } else {
+ $selectfile = $fileurl;
+ }
+ if ($CFG->slasharguments) {
+ $ffurl = "/file.php/$id$fileurl";
+ } else {
+ $ffurl = "/file.php?file=/$id$fileurl";
+ }
+
+ echo "<tr>";
+
+ print_cell("center", "<input type=\"checkbox\" name=\"file$count\" value=\"$fileurl\">");
+
+ echo "<td align=left nowrap>";
+ link_to_popup_window ($ffurl, "display",
+ "<img src=\"$CFG->pixpath/f/$icon\" height=16 width=16 border=0 alt=\"file\">",
+ 480, 640);
+ echo "<font size=\"-1\" face=\"Arial, Helvetica\">";
+ link_to_popup_window ($ffurl, "display", htmlspecialchars($file), 480, 640);
+ echo "</font></td>";
+
+ $file_size = filesize($filename);
+ print_cell("right", display_size($file_size));
+ print_cell("right", $filedate);
+
+ $edittext = "<b><a onMouseDown=\"return set_value('$selectfile')\" href=\"\">$strchoose</a></b> ";
+
+ if ($icon == "text.gif" || $icon == "html.gif") {
+ $edittext .= "<a href=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$fileurl&action=edit\">$stredit</a>";
+ } else if ($icon == "zip.gif") {
+ $edittext .= "<a href=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$fileurl&action=unzip\">$strunzip</a> ";
+ $edittext .= "<a href=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$fileurl&action=listzip\">$strlist</a> ";
+ }
+
+ print_cell("right", "$edittext <A HREF=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$filesafe&action=rename\">$strrename</A>");
+
+ echo "</tr>";
+ }
+ }
+ echo "</table>";
+ echo "<hr width=640 align=center noshade size=1>";
+
+ if (empty($wdir)) {
+ $wdir = "/";
+ }
+
+ echo "<TABLE BORDER=0 cellspacing=2 cellpadding=2 width=640>";
+ echo "<TR><TD>";
+ echo "<INPUT TYPE=hidden NAME=id VALUE=\"$id\">";
+ echo "<INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\"> ";
+ $options = array (
+ "move" => "$strmovetoanotherfolder",
+ "delete" => "$strdeletecompletely",
+ "zip" => "$strcreateziparchive"
+ );
+ if (!empty($count)) {
+ choose_from_menu ($options, "action", "", "$strwithchosenfiles...", "javascript:document.dirform.submit()");
+ }
+
+ echo "</FORM>";
+ echo "<TD ALIGN=center>";
+ if (!empty($USER->fileop) and ($USER->fileop == "move") and ($USER->filesource <> $wdir)) {
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=paste>";
+ echo " <INPUT TYPE=submit VALUE=\"$strmovefilestohere\">";
+ echo "</FORM>";
+ }
+ echo "<TD ALIGN=right>";
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=mkdir>";
+ echo " <INPUT TYPE=submit VALUE=\"$strmakeafolder\">";
+ echo "</FORM>";
+ echo "</TD>";
+ echo "<TD ALIGN=right>";
+ echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+ echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
+ echo " <INPUT TYPE=hidden NAME=action VALUE=upload>";
+ echo " <INPUT TYPE=submit VALUE=\"$struploadafile\">";
+ echo "</FORM>";
+ echo "</TD></TR>";
+ echo "</TABLE>";
+ echo "<HR WIDTH=640 ALIGN=CENTER NOSHADE SIZE=1>";
+
+}
+
+?>