diff --git a/images/del.png b/images/del.png new file mode 100644 index 0000000000000000000000000000000000000000..a3260d718e65db8c0ca981b1ae420c2327510bff Binary files /dev/null and b/images/del.png differ diff --git a/inc/admin_acl.php b/inc/admin_acl.php index 5dc907049b18991194db4fb15e89afee0811cf65..fcf9d9ae387b92814a9bd9580e55caa7166eb499 100644 --- a/inc/admin_acl.php +++ b/inc/admin_acl.php @@ -28,7 +28,7 @@ function admin_acl_handler(){ if($type == '@') $user = '@'.$user; if($user == '@all') $user = '@ALL'; //special group! (now case insensitive) $perm = (int) $perm; - if($perm > AUTH_UPLOAD) $perm = AUTH_UPLOAD; + if($perm > AUTH_DELETE) $perm = AUTH_DELETE; //FIXME sanitize scope!!! //nothing to do? @@ -374,7 +374,7 @@ function admin_acl_html_checkboxes($setperm,$ispage){ static $label = 0; //number labels $ret = ''; - foreach(array(AUTH_READ,AUTH_EDIT,AUTH_CREATE,AUTH_UPLOAD) as $perm){ + foreach(array(AUTH_READ,AUTH_EDIT,AUTH_CREATE,AUTH_UPLOAD,AUTH_DELETE) as $perm){ $label += 1; //general checkbox attributes diff --git a/inc/auth.php b/inc/auth.php index a948a544f6258caa27d8b1dd8ef5b936a33eb66b..a55cfbc5127953353b9af3904b3e662c56436254 100644 --- a/inc/auth.php +++ b/inc/auth.php @@ -23,6 +23,7 @@ define('AUTH_EDIT',2); define('AUTH_CREATE',4); define('AUTH_UPLOAD',8); + define('AUTH_DELETE',16); define('AUTH_ADMIN',255); if($conf['useacl']){ @@ -249,7 +250,7 @@ function auth_aclcheck($id,$user,$groups){ foreach($matches as $match){ $match = preg_replace('/#.*$/','',$match); //ignore comments $acl = preg_split('/\s+/',$match); - if($acl[2] > AUTH_UPLOAD) $acl[2] = AUTH_UPLOAD; //no admins in the ACL! + if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL! if($acl[2] > $perm){ $perm = $acl[2]; } @@ -273,7 +274,7 @@ function auth_aclcheck($id,$user,$groups){ foreach($matches as $match){ $match = preg_replace('/#.*$/','',$match); //ignore comments $acl = preg_split('/\s+/',$match); - if($acl[2] > AUTH_UPLOAD) $acl[2] = AUTH_UPLOAD; //no admins in the ACL! + if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL! if($acl[2] > $perm){ $perm = $acl[2]; } diff --git a/inc/template.php b/inc/template.php index 1f54c5f99a76e0d666232f90488a73084e441ea5..11a1112d0ee7d739f3931e0db4e2237329001bcc 100644 --- a/inc/template.php +++ b/inc/template.php @@ -548,6 +548,7 @@ function tpl_mediafilelist(){ global $conf; global $lang; global $NS; + global $AUTH; $dir = utf8_encodeFN(str_replace(':','/',$NS)); $data = array(); @@ -564,11 +565,27 @@ function tpl_mediafilelist(){ ptln('<a href="javascript:mediaSelect(\''.$item['id'].'\')">'. utf8_decodeFN($item['file']). '</a>',6); + + //prepare deletion button + if($AUTH >= AUTH_DELETE){ + $ask = $lang['del_confirm'].'\\n'; + $ask .= $item['id']; + + $del = '<a href="media.php?delete='.urlencode($item['id']).'" '. + 'onclick="return confirm(\''.$ask.'\')" onkeypress="return confirm(\''.$ask.'\')">'. + '<img src="'.DOKU_BASE.'images/del.png" alt="'.$lang['btn_delete'].'" '. + 'align="bottom" title="'.$lang['btn_delete'].'" /></a>'; + }else{ + $del = ''; + } + + if($item['isimg']){ $w = $item['info'][0]; $h = $item['info'][1]; - ptln('('.$w.'×'.$h.' '.filesize_h($item['size']).')<br />',6); + ptln('('.$w.'×'.$h.' '.filesize_h($item['size']).')',6); + ptln($del.'<br />',6); ptln('<a href="javascript:mediaSelect(\''.$item['id'].'\')">'); if($w>120){ @@ -580,6 +597,7 @@ function tpl_mediafilelist(){ }else{ ptln ('('.filesize_h($item['size']).')',6); + ptln($del,6); } ptln('</li>',4); } @@ -594,6 +612,7 @@ function tpl_mediafilelist(){ function tpl_mediauploadform(){ global $NS; global $UPLOADOK; + global $AUTH; global $lang; if(!$UPLOADOK) return; @@ -606,6 +625,9 @@ function tpl_mediauploadform(){ ptln($lang['txt_filename'].'<br />',4); ptln('<input type="text" name="id" class="edit" />',4); ptln('<input type="submit" class="button" value="'.$lang['btn_upload'].'" accesskey="s" />',4); + if($AUTH >= AUTH_DELETE){ + ptln('<label for="ow" class="simple"><input type="checkbox" name="ow" value="1" id="ow">'.$lang['txt_overwrt'].'</label>',4); + } ptln('</form>',2); } diff --git a/lang/de/lang.php b/lang/de/lang.php index c4f65d8147b03be1051b891b7831b6e6c922279f..bc6ff749a4659e19cb247191f70ab06867d3bb80 100644 --- a/lang/de/lang.php +++ b/lang/de/lang.php @@ -53,8 +53,9 @@ $lang['reqbadpass'] = 'Die beiden eingegeben Passwörter stimmen nicht überein. $lang['regpwmail'] = 'Ihr DokuWiki Passwort'; $lang['reghere'] = 'Sie haben noch keinen Zugang? Hier anmelden'; -$lang['txt_upload'] = 'Datei zum Hochladen auswählen'; +$lang['txt_upload'] = 'Datei zum Hochladen auswählen'; $lang['txt_filename'] = 'Wikinamen eingeben (optional)'; +$lang['txt_overwrt'] = 'Bestehende Datei überschreiben'; $lang['lockedby'] = 'Momentan gesperrt von'; $lang['lockexpire'] = 'Sperre läuft ab am'; $lang['willexpire'] = 'Die Sperre zur Bearbeitung dieser Seite läuft in einer Minute ab.\nUm Bearbeitungskonflikte zu vermeiden, sollten sie sie durch einen Klick auf den Vorschau-Knopf verlängern.'; @@ -69,6 +70,7 @@ $lang['fileupload'] = 'Datei hochladen'; $lang['uploadsucc'] = 'Datei wurde erfolgreich hochgeladen'; $lang['uploadfail'] = 'Hochladen fehlgeschlagen. Keine Berechtigung?'; $lang['uploadwrong'] = 'Hochladen verweigert. Diese Dateiendung ist nicht erlaubt.'; +$lang['uploadexist'] = 'Datei existiert bereits. Keine Änderungen vorgenommen.'; $lang['namespaces'] = 'Namensräume'; $lang['mediafiles'] = 'Vorhandene Dateien in'; @@ -125,6 +127,7 @@ $lang['acl_perm1'] = 'Lesen'; $lang['acl_perm2'] = 'Bearbeiten'; $lang['acl_perm4'] = 'Anlegen'; $lang['acl_perm8'] = 'Hochladen'; +$lang['acl_perm16'] = 'Entfernen'; $lang['acl_new'] = 'Eintrag hinzufügen'; //Setup VIM: ex: et ts=2 enc=utf-8 : diff --git a/lang/en/lang.php b/lang/en/lang.php index 49773b594681158c93cb80d90838f03a8a61f4e6..7d6667429dc935a49ecc75a22481640a16ee0bf9 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -54,6 +54,7 @@ $lang['reghere'] = 'You don\'t have an account yet? Just get one'; $lang['txt_upload'] = 'Select file to upload'; $lang['txt_filename'] = 'Enter wikiname (optional)'; +$lang['txt_overwrt'] = 'Overwrite existing file'; $lang['lockedby'] = 'Currently locked by'; $lang['lockexpire'] = 'Lock expires at'; $lang['willexpire'] = 'Your lock for editing this page is about to expire in a minute.\nTo avoid conflicts use the preview button to reset the locktimer.'; @@ -66,7 +67,8 @@ $lang['mediaselect'] = 'Mediafile Selection'; $lang['fileupload'] = 'Mediafile Upload'; $lang['uploadsucc'] = 'Upload successful'; $lang['uploadfail'] = 'Upload failed. Maybe wrong permissions?'; -$lang['uploadwrong'] = 'Upload denied. This file extension is forbidden'; +$lang['uploadwrong'] = 'Upload denied. This file extension is forbidden!'; +$lang['uploadexist'] = 'File already exists. Nothing done.'; $lang['namespaces'] = 'Namespaces'; $lang['mediafiles'] = 'Available files in'; @@ -123,6 +125,7 @@ $lang['acl_perm1'] = 'Read'; $lang['acl_perm2'] = 'Edit'; $lang['acl_perm4'] = 'Create'; $lang['acl_perm8'] = 'Upload'; +$lang['acl_perm16'] = 'Delete'; $lang['acl_new'] = 'Add new Entry'; //Setup VIM: ex: et ts=2 enc=utf-8 : diff --git a/media.php b/media.php index 3b71f62a326c537203e3b7b5a11d1ec7dd1baae2..3340bae4e95ef8393436c4bae07bd95f718f4b94 100644 --- a/media.php +++ b/media.php @@ -11,11 +11,18 @@ header('Content-Type: text/html; charset='.$lang['encoding']); - $NS = $_REQUEST['ns']; - $NS = cleanID($NS); + //get namespace to display (either direct or from deletion order) + if($_REQUEST['delete']){ + $DEL = cleanID($_REQUEST['delete']); + $NS = getNS($DEL); + }else{ + $NS = $_REQUEST['ns']; + $NS = cleanID($NS); + } //check upload permissions - if(auth_quickaclcheck("$NS:*") >= AUTH_UPLOAD){ + $AUTH = auth_quickaclcheck("$NS:*"); + if($AUTH >= AUTH_UPLOAD){ $UPLOADOK = true; //create the given namespace (just for beautification) $mdir = $conf['mediadir'].'/'.utf8_encodeFN(str_replace(':','/',$NS)); @@ -24,8 +31,14 @@ $UPLOADOK = false; } + //handle deletion + if($DEL && $AUTH >= AUTH_DELETE){ + media_delete($DEL); + } + + //handle upload if($_FILES['upload']['tmp_name'] && $UPLOADOK){ - media_upload($NS); + media_upload($NS,$AUTH); } //start output and load template @@ -37,12 +50,27 @@ /**********************************************/ +/** + * Deletes mediafiles - Auth is not handled here! + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function media_delete($delid){ + $file = mediaFN($delid); + if(@unlink($file)){ + return true; + } + //something went wrong + msg("'$file' couldn't be deleted - check permissions",-1); + return false; +} + /** * Handles Mediafile uploads * * @author Andreas Gohr <andi@splitbrain.org> */ -function media_upload($NS){ +function media_upload($NS,$AUTH){ require_once(DOKU_INC.'inc/confutils.php'); global $lang; global $conf; @@ -65,9 +93,14 @@ function media_upload($NS){ // because a temp file was created already umask($conf['umask']); if(preg_match('/\.('.$regex.')$/i',$fn)){ + //check for overwrite + if(@file_exists($fn) && (!$_POST['ow'] || $AUTH < AUTH_DELETE)){ + msg($lang['uploadexist'],0); + return false; + } // prepare directory io_makeFileDir($fn); - if (move_uploaded_file($file['tmp_name'], $fn)) { + if(move_uploaded_file($file['tmp_name'], $fn)) { // set the correct permission here chmod($fn, 0777 - $conf['umask']); msg($lang['uploadsucc'],1);