summaryrefslogtreecommitdiff
path: root/inc
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2006-03-11 21:01:48 +0100
committerAndreas Gohr <andi@splitbrain.org>2006-03-11 21:01:48 +0100
commitee4c4a1b5a5840c1b9d2d8c74b3f4298dd52928b (patch)
treeec7011afc97d0159819e8b334709fe0680cab9b1 /inc
parent6d8affe6a4c62d13d1cd6051c23ab305145f9db6 (diff)
downloadrpg-ee4c4a1b5a5840c1b9d2d8c74b3f4298dd52928b.tar.gz
rpg-ee4c4a1b5a5840c1b9d2d8c74b3f4298dd52928b.tar.bz2
Automatic draft saving
DokuWiki now automatically creates a draft file of the currently edited page. In case of an editing interuption (eg. Browsercrash) the draftfile can be continued later. darcs-hash:20060311200148-7ad00-919337a51e001136178d175a1755cd26122e9726.gz
Diffstat (limited to 'inc')
-rw-r--r--inc/actions.php77
-rw-r--r--inc/common.php14
-rw-r--r--inc/html.php47
-rw-r--r--inc/io.php3
-rw-r--r--inc/lang/en/lang.php10
-rw-r--r--inc/template.php14
6 files changed, 142 insertions, 23 deletions
diff --git a/inc/actions.php b/inc/actions.php
index e92e366d0..963be86a9 100644
--- a/inc/actions.php
+++ b/inc/actions.php
@@ -62,6 +62,14 @@ function act_dispatch(){
if($ACT == 'save')
$ACT = act_save($ACT);
+ //draft deletion
+ if($ACT == 'draftdel')
+ $ACT = act_draftdel($ACT);
+
+ //draft saving on preview
+ if($ACT == 'preview')
+ $ACT = act_draftsave($ACT);
+
//edit
if(($ACT == 'edit' || $ACT == 'preview') && $INFO['editable']){
$ACT = act_edit($ACT);
@@ -116,10 +124,18 @@ function act_clean($act){
global $lang;
global $conf;
+ // check if the action was given as array key
+ if(is_array($act)){
+ list($act) = array_keys($act);
+ }
+
//handle localized buttons
- if($act == $lang['btn_save']) $act = 'save';
- if($act == $lang['btn_preview']) $act = 'preview';
- if($act == $lang['btn_cancel']) $act = 'show';
+ if($act == $lang['btn_save']) $act = 'save';
+ if($act == $lang['btn_preview']) $act = 'preview';
+ if($act == $lang['btn_cancel']) $act = 'show';
+ if($act == $lang['btn_recover']) $act = 'recover';
+ if($act == $lang['btn_draftdel']) $act = 'draftdel';
+
//remove all bad chars
$act = strtolower($act);
@@ -136,12 +152,12 @@ function act_clean($act){
return 'show';
}
- if(array_search($act,array('login','logout','register','save','edit',
- 'preview','search','show','check','index','revisions',
- 'diff','recent','backlink','admin','subscribe',
- 'unsubscribe','profile','resendpwd',)) === false
- && substr($act,0,7) != 'export_' ) {
- msg('Unknown command: '.htmlspecialchars($act),-1);
+ if(!in_array($act,array('login','logout','register','save','edit','draft',
+ 'preview','search','show','check','index','revisions',
+ 'diff','recent','backlink','admin','subscribe',
+ 'unsubscribe','profile','resendpwd','recover',
+ 'draftdel',)) && substr($act,0,7) != 'export_' ) {
+ msg('Command unknown: '.htmlspecialchars($act),-1);
return 'show';
}
return $act;
@@ -156,7 +172,7 @@ function act_permcheck($act){
global $INFO;
global $conf;
- if(in_array($act,array('save','preview','edit'))){
+ if(in_array($act,array('save','preview','edit','recover'))){
if($INFO['exists']){
if($act == 'edit'){
//the edit function will check again and do a source show
@@ -187,6 +203,43 @@ function act_permcheck($act){
}
/**
+ * Handle 'draftdel'
+ *
+ * Deletes the draft for the current page and user
+ */
+function act_draftdel($act){
+ global $INFO;
+ @unlink($INFO['draft']);
+ $INFO['draft'] = null;
+ return 'show';
+}
+
+/**
+ * Saves a draft on preview
+ *
+ * @todo this currently duplicates code from ajax.php :-/
+ */
+function act_draftsave($act){
+ global $INFO;
+ global $ID;
+ global $conf;
+ if($conf['usedraft'] && $_POST['wikitext']){
+ $draft = array('id' => $ID,
+ 'prefix' => $_POST['prefix'],
+ 'text' => $_POST['wikitext'],
+ 'suffix' => $_POST['suffix'],
+ 'date' => $_POST['date'],
+ 'client' => $INFO['client'],
+ );
+ $cname = getCacheName($draft['client'].$ID,'.draft');
+ if(io_saveFile($cname,serialize($draft))){
+ $INFO['draft'] = $cname;
+ }
+ }
+ return $act;
+}
+
+/**
* Handle 'save'
*
* Checks for spam and conflicts and saves the page.
@@ -215,6 +268,9 @@ function act_save($act){
//unlock it
unlock($ID);
+ //delete draft
+ act_draftdel($act);
+
//show it
session_write_close();
header("Location: ".wl($ID,'',true));
@@ -259,6 +315,7 @@ function act_auth($act){
*/
function act_edit($act){
global $ID;
+ global $INFO;
//check if locked by anyone - if not lock for my self
$lockedby = checklock($ID);
diff --git a/inc/common.php b/inc/common.php
index ffb78f432..a2facee90 100644
--- a/inc/common.php
+++ b/inc/common.php
@@ -36,14 +36,17 @@ function pageinfo(){
$info['userinfo'] = $USERINFO;
$info['perm'] = auth_quickaclcheck($ID);
$info['subscribed'] = is_subscribed($ID,$_SERVER['REMOTE_USER']);
+ $info['client'] = $_SERVER['REMOTE_USER'];
// if some outside auth were used only REMOTE_USER is set
if(!$info['userinfo']['name']){
$info['userinfo']['name'] = $_SERVER['REMOTE_USER'];
}
+
}else{
$info['perm'] = auth_aclcheck($ID,'',null);
$info['subscribed'] = false;
+ $info['client'] = clientIP(true);
}
$info['namespace'] = getNS($ID);
@@ -86,6 +89,17 @@ function pageinfo(){
$info['editor'] = $revinfo['ip'];
}
+ // draft
+ $draft = getCacheName($info['client'].$ID,'.draft');
+ if(@file_exists($draft)){
+ if(@filemtime($draft) < @filemtime(wikiFN($ID))){
+ // remove stale draft
+ @unlink($draft);
+ }else{
+ $info['draft'] = $draft;
+ }
+ }
+
return $info;
}
diff --git a/inc/html.php b/inc/html.php
index c0ce8527f..0cc52fbd1 100644
--- a/inc/html.php
+++ b/inc/html.php
@@ -98,7 +98,7 @@ function html_login(){
}
/**
- * shows the edit/source/show button dependent on current mode
+ * shows the edit/source/show/draft button dependent on current mode
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
@@ -110,10 +110,14 @@ function html_editbutton(){
if($ACT == 'show' || $ACT == 'search'){
if($INFO['writable']){
- if($INFO['exists']){
- $r = html_btn('edit',$ID,'e',array('do' => 'edit','rev' => $REV),'post');
+ if($INFO['draft']){
+ $r = html_btn('draft',$ID,'e',array('do' => 'draft'),'post');
}else{
- $r = html_btn('create',$ID,'e',array('do' => 'edit','rev' => $REV),'post');
+ if($INFO['exists']){
+ $r = html_btn('edit',$ID,'e',array('do' => 'edit','rev' => $REV),'post');
+ }else{
+ $r = html_btn('create',$ID,'e',array('do' => 'edit','rev' => $REV),'post');
+ }
}
}else{
$r = html_btn('source',$ID,'v',array('do' => 'edit','rev' => $REV),'post');
@@ -287,6 +291,36 @@ function html_show($txt=''){
}
/**
+ * ask the user about how to handle an exisiting draft
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_draft(){
+ global $INFO;
+ global $ID;
+ global $lang;
+ global $conf;
+ $draft = unserialize(io_readFile($INFO['draft'],false));
+ $text = cleanText(con($draft['prefix'],$draft['text'],$draft['suffix'],true));
+
+ echo p_locale_xhtml('draft');
+ ?>
+ <form id="dw__editform" method="post" action="<?php echo script()?>"
+ accept-charset="<?php echo $lang['encoding']?>"><div class="no">
+ <input type="hidden" name="id" value="<?php echo $ID?>" />
+ <input type="hidden" name="date" value="<?php echo $draft['date']?>" /></div>
+ <textarea name="wikitext" id="wiki__text" readonly="readonly" cols="80" rows="10" class="edit"><?php echo "\n".formText($text)?></textarea>
+
+ <div id="draft__status"><?php echo $lang['draftdate'].' '.date($conf['dformat'],filemtime($INFO['draft']))?></div>
+
+ <input class="button" type="submit" name="do" value="<?php echo $lang['btn_recover']?>" tabindex="1" />
+ <input class="button" type="submit" name="do" value="<?php echo $lang['btn_draftdel']?>" tabindex="2" />
+ <input class="button" type="submit" name="do" value="<?php echo $lang['btn_cancel']?>" tabindex="3" />
+ </form>
+ <?php
+}
+
+/**
* Highlights searchqueries in HTML code
*
* @author Andreas Gohr <andi@splitbrain.org>
@@ -999,6 +1033,7 @@ function html_edit($text=null,$include='edit'){ //FIXME: include needed?
<div style="width:99%;">
<form id="dw__editform" method="post" action="<?php echo script()?>" accept-charset="<?php echo $lang['encoding']?>"><div class="no">
<div class="toolbar">
+ <div id="draft__status"><?php if($INFO['draft']) echo $lang['draftdate'].' '.date($conf['dformat']);?></div>
<div id="tool__bar"></div>
<input type="hidden" name="id" value="<?php echo $ID?>" />
<input type="hidden" name="rev" value="<?php echo $REV?>" />
@@ -1012,8 +1047,8 @@ function html_edit($text=null,$include='edit'){ //FIXME: include needed?
textChanged = <?php ($pr) ? print 'true' : print 'false' ?>;
</script>
<span id="spell__action"></span>
- <?php } ?>
<div id="spell__suggest"></div>
+ <?php } ?>
</div>
<div id="spell__result"></div>
@@ -1025,7 +1060,7 @@ function html_edit($text=null,$include='edit'){ //FIXME: include needed?
<div class="editButtons">
<input class="button" id="edbtn__save" type="submit" name="do" value="<?php echo $lang['btn_save']?>" accesskey="s" title="[ALT+S]" tabindex="4" />
<input class="button" id="edbtn__preview" type="submit" name="do" value="<?php echo $lang['btn_preview']?>" accesskey="p" title="[ALT+P]" tabindex="5" />
- <input class="button" type="submit" name="do" value="<?php echo $lang['btn_cancel']?>" tabindex="5" />
+ <input class="button" type="submit" name="do[draftdel]" value="<?php echo $lang['btn_cancel']?>" tabindex="5" />
</div>
<?php } ?>
<?php if($wr){ ?>
diff --git a/inc/io.php b/inc/io.php
index 1d458ace9..ae1a3611c 100644
--- a/inc/io.php
+++ b/inc/io.php
@@ -33,6 +33,9 @@ function io_sweepNS($id,$basedir='datadir'){
*
* Uses gzip if extension is .gz
*
+ * If you want to use the returned value in unserialize
+ * be sure to set $clean to false!
+ *
* @author Andreas Gohr <andi@splitbrain.org>
*/
function io_readFile($file,$clean=true){
diff --git a/inc/lang/en/lang.php b/inc/lang/en/lang.php
index 1a4308125..c1aa6bd6c 100644
--- a/inc/lang/en/lang.php
+++ b/inc/lang/en/lang.php
@@ -36,9 +36,12 @@ $lang['btn_backlink'] = "Backlinks";
$lang['btn_backtomedia'] = 'Back to Mediafile Selection';
$lang['btn_subscribe'] = 'Subscribe Changes';
$lang['btn_unsubscribe'] = 'Unsubscribe Changes';
-$lang['btn_profile'] = 'Update Profile';
-$lang['btn_reset'] = 'Reset';
-$lang['btn_resendpwd'] = 'Send new password';
+$lang['btn_profile'] = 'Update Profile';
+$lang['btn_reset'] = 'Reset';
+$lang['btn_resendpwd'] = 'Send new password';
+$lang['btn_draft'] = 'Edit draft';
+$lang['btn_recover'] = 'Recover draft';
+$lang['btn_draftdel'] = 'Delete draft';
$lang['loggedinas'] = 'Logged in as';
$lang['user'] = 'Username';
@@ -53,6 +56,7 @@ $lang['register'] = 'Register';
$lang['profile'] = 'User Profile';
$lang['badlogin'] = 'Sorry, username or password was wrong.';
$lang['minoredit'] = 'Minor Changes';
+$lang['draftdate'] = 'Draft autosaved on'; // full dformat date will be added
$lang['regmissing'] = 'Sorry, you must fill in all fields.';
$lang['reguexists'] = 'Sorry, a user with this login already exists.';
diff --git a/inc/template.php b/inc/template.php
index 091cd2e56..a74067f8b 100644
--- a/inc/template.php
+++ b/inc/template.php
@@ -53,8 +53,8 @@ function template($tpl){
* (defined by the global $ACT var) by calling the appropriate
* outputfunction(s) from html.php
*
- * Everything that doesn't use the default template isn't
- * handled by this function. ACL stuff is not done either.
+ * Everything that doesn't use the main template file isn't
+ * handled by this function. ACL stuff is not done here either.
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
@@ -74,9 +74,15 @@ function tpl_content(){
html_edit($TEXT);
html_show($TEXT);
break;
+ case 'recover':
+ html_edit($TEXT);
+ break;
case 'edit':
html_edit();
break;
+ case 'draft':
+ html_draft();
+ break;
case 'wordblock':
html_edit($TEXT,'wordblock');
break;
@@ -203,7 +209,7 @@ function tpl_metaheaders($alt=true){
ptln('<link rel="stylesheet" media="print" type="text/css" href="'.DOKU_BASE.'lib/exe/css.php?print=1" />',$it);
// load javascript
- $js_edit = ($ACT=='edit' || $ACT=='preview') ? 1 : 0;
+ $js_edit = ($ACT=='edit' || $ACT=='preview' || $ACT=='recover') ? 1 : 0;
$js_write = ($INFO['writable']) ? 1 : 0;
if($js_edit && $js_write){
ptln('<script type="text/javascript" charset="utf-8">',$it);
@@ -283,7 +289,7 @@ function tpl_getparent($ID){
*
* Available Buttons are
*
- * edit - edit/create/show button
+ * edit - edit/create/show/draft button
* history - old revisions
* recent - recent changes
* login - login/logout button - if ACL enabled