Permalink
Browse files

Wiki enhancement: edit locking (uses AJAX)

  • Loading branch information...
sam_marshall
sam_marshall committed Sep 25, 2006
1 parent f775a51 commit 22e846cde22756790e20e1f3f466c743bb9a980c
View
@@ -94,6 +94,7 @@
$string['linkschecked'] = 'Links checked';
$string['listall'] = 'List all';
$string['listcandidates'] = 'List candidates';
+$string['lockcancelled'] = 'Your editing lock has been overridden and somebody else is now editing this page. If you wish to keep your changes, please select and copy them before clicking Cancel; then try to edit again.';
$string['meta'] = 'Meta data';
$string['moduledirectory'] = 'Module Directory';
$string['modulename'] = 'Wiki';
@@ -116,10 +117,13 @@
$string['orphanedpage'] = 'Orphaned page';
$string['orphanedpages'] = 'Orphaned pages';
$string['otherwikis'] = 'Other Wikis';
+$string['overrideinfo'] = 'You can override this user\'s lock, but doing so may cause them to lose their changes! Please take care.';
+$string['overridebutton'] = 'Override lock';
$string['ownerunknown'] = 'unknown';
$string['pageactions'] = 'Page actions';
$string['pageindex'] = 'Page Index';
$string['pageinfo'] = 'Page information';
+$string['pagelocked'] = '<p><strong>This page is being edited by $a->name.</strong> They began editing at $a->since and still have the window open as of $a->seen.</p><p>You need to wait for them to finish before you can edit this page.</p>';
$string['pagename'] = 'Page name';
$string['pagenamechoice'] = '- or -';
$string['pageslinkingto'] = 'Pages linking to this page';
@@ -179,6 +183,7 @@
$string['wantedpages'] = 'Wanted pages';
$string['wiki:participate'] = 'Edit wiki pages';
$string['wiki:manage'] = 'Manage wiki settings';
+$string['wiki:overridelock'] = 'Override locked pages';
$string['wikidefaultpagename'] = 'WikiIndex';
$string['wikiexport'] = 'Export pages';
$string['wikiexportcomment'] = 'Here you can configure the export to your needs.';
View
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This script is called through AJAX. It confirms that a user is still
+ * trying to edit a page that they have locked (they haven't closed
+ * their browser window or something).
+ *
+ * @copyright &copy; 2006 The Open University
+ * @author s.marshall@open.ac.uk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package wiki
+ *//** */
+
+require_once("../../config.php");
+
+header('Content-Type: text/plain');
+
+if(empty($_POST['lockid'])) {
+ print 'noid';
+ exit;
+}
+
+$lockid=(int)$_POST['lockid'];
+if($lock=get_record('wiki_locks','id',$lockid)) {
+ $lock->lockedseen=time();
+ update_record('wiki_locks',$lock);
+ print 'ok';
+} else {
+ print 'cancel'; // Tells user their lock has been cancelled.
+}
+
+?>
View
@@ -36,5 +36,21 @@
'coursecreator' => CAP_PREVENT,
'admin' => CAP_ALLOW
)
+ ),
+
+ 'mod/wiki:overridelock' => array(
+
+ 'riskbitmask' => 0,
+
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_MODULE,
+ 'legacy' => array(
+ 'guest' => CAP_PREVENT,
+ 'student' => CAP_PREVENT,
+ 'teacher' => CAP_ALLOW,
+ 'editingteacher' => CAP_ALLOW,
+ 'coursecreator' => CAP_ALLOW,
+ 'admin' => CAP_ALLOW
+ )
)
);
View
@@ -48,7 +48,7 @@
<INDEX NAME="pagename" UNIQUE="false" FIELDS="pagename" PREVIOUS="userid"/>
</INDEXES>
</TABLE>
- <TABLE NAME="wiki_pages" COMMENT="Holds the Wiki-Pages" PREVIOUS="wiki_entries">
+ <TABLE NAME="wiki_pages" COMMENT="Holds the Wiki-Pages" PREVIOUS="wiki_entries" NEXT="wiki_locks">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="pagename"/>
<FIELD NAME="pagename" TYPE="char" LENGTH="160" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="version"/>
@@ -66,11 +66,37 @@
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for wiki_pages" NEXT="wiki"/>
+ <!-- sam notes: if implemented, this foreign key will break, since the
+ field defaults to 0 not null and will therefore fail to find its
+ referent. -->
<KEY NAME="wiki" TYPE="foreign" FIELDS="wiki" REFTABLE="wiki" REFFIELDS="id" PREVIOUS="primary"/>
</KEYS>
<INDEXES>
<INDEX NAME="pagename-version-wiki" UNIQUE="true" FIELDS="pagename, version, wiki"/>
</INDEXES>
</TABLE>
+ <TABLE NAME="wiki_locks" COMMENT="Stores editing locks on Wiki pages" PREVIOUS="wiki_pages">
+ <FIELDS>
+ <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="wikiid"/>
+ <FIELD NAME="wikiid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="pagename"/>
+ <FIELD NAME="pagename" TYPE="char" LENGTH="160" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="wikiid" NEXT="lockedby"/>
+ <!-- If the page is or was locked, this field holds the userid of the locker -->
+ <FIELD NAME="lockedby" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="pagename" NEXT='lockedsince'/>
+ <!-- Time (seconds since epoch) at which lock began -->
+ <FIELD NAME="lockedsince" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="lockedby" NEXT='lockedseen'/>
+ <!-- Time (seconds since epoch) at which lock was last reconfirmed (we ignore lock if this is >2 mins ago) -->
+ <FIELD NAME="lockedseen" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="lockedsince"/>
+ </FIELDS>
+ <KEYS>
+ <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for wiki_locks" NEXT="wikiid"/>
+ <KEY NAME="wikiid" TYPE="foreign" FIELDS="wikiid" REFTABLE="wiki" REFFIELDS="id" PREVIOUS="primary"/>
+ </KEYS>
+ <INDEXES>
+ <!-- Main index used for retrieving locks -->
+ <INDEX NAME="wikiid-pagename" UNIQUE="false" FIELDS="wikiid,pagename" NEXT="lockedseen"/>
+ <!-- Secondary index used only during cron for deleting expired locks -->
+ <INDEX NAME="lockedseen" UNIQUE="false" FIELDS="lockedseen" PREVIOUS="wikiid-pagename"/>
+ </INDEXES>
+ </TABLE>
</TABLES>
</XMLDB>
View
@@ -160,7 +160,21 @@ function wiki_upgrade($oldversion) {
execute_sql("UPDATE {$CFG->prefix}wiki SET initialcontent='' WHERE initialcontent IS NULL");
table_column('wiki','initialcontent','initialcontent','varchar','255','','','not null');
}
-
+ if ($oldversion < 2006092502) {
+ modify_database("","
+CREATE TABLE prefix_wiki_locks
+(
+ id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ wikiid INT(10) UNSIGNED NOT NULL,
+ pagename VARCHAR(160) NOT NULL DEFAULT '',
+ lockedby INT(10) NOT NULL DEFAULT 0,
+ lockedsince INT(10) NOT NULL DEFAULT 0,
+ lockedseen INT(10) NOT NULL DEFAULT 0,
+ PRIMARY KEY(id),
+ UNIQUE KEY wiki_locks_uk(wikiid,pagename),
+ INDEX wiki_locks_ix(lockedseen)
+);");
+ }
return true;
}
View
@@ -155,6 +155,21 @@ function wiki_upgrade($oldversion) {
modify_database('', 'ALTER TABLE prefix_wiki_pages
ALTER COLUMN refs DROP NOT NULL');
}
+
+ if ($oldversion < 2006092502) {
+ modify_database("","
+CREATE TABLE prefix_wiki_locks
+(
+ id SERIAL PRIMARY KEY,
+ wikiid INTEGER NOT NULL,
+ pagename VARCHAR(160) NOT NULL DEFAULT '',
+ lockedby INTEGER NOT NULL DEFAULT 0,
+ lockedsince INTEGER NOT NULL DEFAULT 0,
+ lockedseen INTEGER NOT NULL DEFAULT 0
+);");
+ modify_database("","CREATE INDEX prefix_wikilock_loc_ix ON prefix_wiki_locks (lockedseen);");
+ modify_database("","CREATE UNIQUE INDEX prefix_wikilock_wikpag_uix ON prefix_wiki_locks (wikiid, pagename);");
+ }
return true;
}
View
@@ -11,6 +11,13 @@
'student' => get_string('defaultcoursestudent') );
define("EWIKI_ESCAPE_AT", 0); # For the algebraic filter
+// How long locks stay around without being confirmed (seconds)
+define(WIKI_LOCK_PERSISTENCE,60);
+
+// How often to confirm that you still want a lock
+define(WIKI_LOCK_RECONFIRM,30);
+
+
/*** Moodle 1.7 compatibility functions *****
*
********************************************/
@@ -135,6 +142,10 @@ function wiki_delete_instance($id) {
}
# Delete any dependent records here #
+ if(!delete_records("wiki_locks","wikiid",$wiki->id)) {
+ $result = false;
+ }
+
if (! delete_records("wiki", "id", $wiki->id)) {
$result = false;
}
@@ -225,9 +236,10 @@ function wiki_cron () {
/// This function searches for things that need to be done, such
/// as sending out mail, toggling flags etc ...
- global $CFG;
+ // Delete expired locks
+ $result=delete_records_select('wiki_locks','lockedseen < '.(time()-WIKI_LOCK_PERSISTENCE));
- return true;
+ return $result;
}
function wiki_grades($wikiid) {
@@ -1550,4 +1562,4 @@ function wiki_get_post_actions() {
}
-?>
+?>
View
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Handles what happens when a user with appropriate permission attempts to
+ * override a wiki page editing lock.
+ *
+ * @copyright &copy; 2006 The Open University
+ * @author s.marshall@open.ac.uk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package package_name
+ *//** */
+
+require_once('../../config.php');
+
+$id=required_param('id',PARAM_INT);
+$page=required_param('page',PARAM_RAW);
+
+if (! $cm = get_coursemodule_from_id('wiki', $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");
+}
+
+if(!confirm_sesskey()) {
+ error("Session key not set");
+}
+if(!data_submitted()) {
+ error("Only POST requests accepted");
+}
+
+require_course_login($course, true, $cm);
+
+$modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
+if(!has_capability('mod/wiki:overridelock', $modcontext)) {
+ error("You do not have the capability to override editing locks");
+}
+
+$actions = explode('/', $page,2);
+if(count($actions)!=2) {
+ error("Unsupported page value");
+}
+$pagename=addslashes($actions[1]);
+if(!delete_records('wiki_locks','pagename',$pagename,'wikiid', $wiki->id)) {
+ error('Unable to delete lock record');
+}
+
+redirect("view.php?id=$id&page=".urlencode($page));
+?>
View
@@ -5,8 +5,8 @@
/// This fragment is called by moodle_needs_upgrading() and /admin/index.php
/////////////////////////////////////////////////////////////////////////////////
-$module->version = 2006091800; // The current module version (Date: YYYYMMDDXX)
+$module->version = 2006092502; // The current module version (Date: YYYYMMDDXX)
$module->requires = 2006080900; // The current module version (Date: YYYYMMDDXX)
-$module->cron = 0; // Period for cron to check this module (secs)
+$module->cron = 3600; // Period for cron to check this module (secs)
?>
Oops, something went wrong.

0 comments on commit 22e846c

Please sign in to comment.