Schutz vor unbedachtem Löschen von Bildern und Dateien

Fragen zur Implementierung und/oder Anpassung von ConPresso 4 werden in diesem Forum diskutiert.
Antworten
Benutzeravatar
MarkusR
Handbuchversteher
Beiträge: 7361
Registriert: 01.01.1970 01:00
Hat sich bedankt: 111 Mal
Danksagung erhalten: 933 Mal
Kontaktdaten:

Schutz vor unbedachtem Löschen von Bildern und Dateien

Beitrag von MarkusR »

Leider habe ich es jetzt schon mehrfach beobachtet, daß Bilder oder Dateien von "Usern" gelöscht wurden, obwohl sie noch im Frontend genutzt wurden.

Da war die in 3.4.x vorhandene Anzeige der Dateibenutzung doch sehr hilfreich.

Daß diese aus Performancegründen und wegen unvollständiger Auswertung entfernt wurde ist zwar sinnvoll, stellt Redakteure aber vor die unlösbare Aufgabe immer zu wissen, ob eine Datei oder ein Bild noch gebraucht wird.

Als kleinen Versuch habe ich jetzt mal das letzte Javascript-Confirm entfernt und durch die ansonsten konsequent eingesetzte (wenn auch manchmal nervende) Sicherheitsabfrage ersetzt und dabei analysiert, ob und wo eine Datei noch benötigt wird.
Ist aber erst mal nur ein Versuch.

Ist das in Euren Augen hilfreich?

(Soll auch kein Modul sondern nur eine kleine Modifikation werden...)
Dateianhänge
manage_files.png
Ciao Markus
ConPresso-Module

Kein Support per PN!!! Für Fragen und Diskussionen ist das Forum da!

Succi recentis officinalis
Hochwertige Kräutersäfte und -Öle
Benutzeravatar
Mr. Magpie
ConPresso-Profi
Beiträge: 1004
Registriert: 01.01.1970 01:00
Wohnort: Wuppertal
Hat sich bedankt: 274 Mal
Danksagung erhalten: 59 Mal

Beitrag von Mr. Magpie »

Grundsätzlich finde ich das schon ziemlich sinnvoll.

Aber die Sicherheitsabfragen nerven schon sehr, wenn man im Begriff ist, mehrere bis viele Dateien zu löschen. Daher wünschte ich mir zusätzlich die Möglichkeit, mehrere Dateien per Checkboxen zum Löschen markieren zu können.
Günther Ludwig
Benutzeravatar
MarkusR
Handbuchversteher
Beiträge: 7361
Registriert: 01.01.1970 01:00
Hat sich bedankt: 111 Mal
Danksagung erhalten: 933 Mal
Kontaktdaten:

Beitrag von MarkusR »

Geht auch, ist aber natürlich nicht mehr ressourcenschonend... :wink:
Dateianhänge
manage_files_ext.png
Ciao Markus
ConPresso-Module

Kein Support per PN!!! Für Fragen und Diskussionen ist das Forum da!

Succi recentis officinalis
Hochwertige Kräutersäfte und -Öle
Benutzeravatar
Mr. Magpie
ConPresso-Profi
Beiträge: 1004
Registriert: 01.01.1970 01:00
Wohnort: Wuppertal
Hat sich bedankt: 274 Mal
Danksagung erhalten: 59 Mal

Beitrag von Mr. Magpie »

Darf ich's testen? (lechz)
Günther Ludwig
Benutzeravatar
MarkusR
Handbuchversteher
Beiträge: 7361
Registriert: 01.01.1970 01:00
Hat sich bedankt: 111 Mal
Danksagung erhalten: 933 Mal
Kontaktdaten:

Beitrag von MarkusR »

Ja, aber noch etwas Geduld.

Ein paar Dinge muß ich noch bereinigen und dann alles in eine 4.0.9 einbauen.
Entwickelt habe ich es nämlich auf einer 4.0.4...
Ciao Markus
ConPresso-Module

Kein Support per PN!!! Für Fragen und Diskussionen ist das Forum da!

Succi recentis officinalis
Hochwertige Kräutersäfte und -Öle
Benutzeravatar
MarkusR
Handbuchversteher
Beiträge: 7361
Registriert: 01.01.1970 01:00
Hat sich bedankt: 111 Mal
Danksagung erhalten: 933 Mal
Kontaktdaten:

Beitrag von MarkusR »

Here we go...

für bisher unmodifizierte Installationen gibt es die drei Dateien als Archiv, für alle "Bastler" hier der Code mit Anleitung:

=== OPEN / ÖFFNE ===
_include/tab_files.php

=== FIND / FINDE ===

Code: Alles auswählen

echo '<table class="ruler" style="width: 100%;"><thead>';
=== INSERT BEFORE / DAVOR EINFÜGEN ===

Code: Alles auswählen

// start part 1 of 3 enhanced delete by m.roesel ***********************************************
echo '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
echo '<input type="hidden" name="action" value="del">';
// end part 1 of 3 enhanced delete by m.roesel ***********************************************
=== FIND / FINDE ===

Code: Alles auswählen

         .'" onClick="return confirm(\''.$q.'\')">'
         .'<img src="'.SKIN_URL.'pic_del.gif" class="pic_" '
            .'alt="'.  ($show_only_images ? ___('delete image') : ___('delete file')).'" '
            .'title="'.($show_only_images ? ___('delete image') : ___('delete file')).'" />'
         .'</a>');  
=== REPLACE WITH / ERSETZEN MIT ===

Code: Alles auswählen

// start part 2 of 3 enhanced delete by m.roesel ***********************************************
         .'" >'
         .'<img src="'.SKIN_URL.'pic_del.gif" class="pic_" '
            .'alt="'.  ($show_only_images ? ___('delete image') : ___('delete file')).'" '
            .'title="'.($show_only_images ? ___('delete image') : ___('delete file')).'" />'
         .'</a>');  
    echo '<input type="checkbox" name="files[]" value="'.htmlspecialchars($db->v('id')).'#CPO#'.htmlspecialchars($db->v('datei')).'">';
// end part 2 of 3 enhanced delete by m.roesel ***********************************************
=== FIND / FINDE ===

Code: Alles auswählen

echo '</tbody></table>';
=== REPLACE WITH / ERSETZEN MIT ===

Code: Alles auswählen

// start part 3 of 3 enhanced delete by m.roesel ***********************************************
echo '<tr><td></td><td><button type="submit" /><img align="absmiddle" src="'.SKIN_URL.'pic_del.gif" />'.__('selected').'</button></td><td></td><td></td></tr>';
echo '</tbody></table>';
echo '</form>';
// end part 3 of 3 enhanced delete by m.roesel ***********************************************

=== OPEN / ÖFFNE ===
_includesite/i_manage_files.php

=== FIND / FINDE ===

Code: Alles auswählen

case 'del':
    $db = new DB;
    $db->query("SELECT datei, format FROM ".CPO_DATA." "
              ."WHERE id='".$_GET['id']."'");
    while ($db->next_record()) {
        $datei = $db->v('datei');
        $format = $db->v('format');
    }

    $query_del = "DELETE FROM ".CPO_DATA." "
                ."WHERE id='".$_GET['id']."'";
    DEBUG(1, $query_del, __FILE__, __LINE__);
    $db->query($query_del); 

    @unlink (CPO_BASEDIR.'_data/'.$_GET['file']);

    switch ($format) {
    case 1:
        $message[] = sprintf(___('The file %s was successfully deleted.'), '<em>'.htmlspecialchars($datei).'</em>');
        break;
    case 2:
        $message[] = sprintf(___('The image %s was successfully deleted.'), '<em>'.htmlspecialchars($datei).'</em>');
        break;
    }
    
    logaction('delete file', $_GET['file']);
    $_GET['id'] = '';

    break;
=== REPLACE WITH / ERSETZEN MIT ===

Code: Alles auswählen

// start part 1 of 1 enhanced delete by m.roesel ***********************************************
case 'del':
	$db = new DB;
	$articles = array();
	// fetch all articles and states
	$db->query("SELECT nr, titel, artikel_archiv, freigabe, pub_datum, verfallsdatum FROM ".CPO_NEWS);
	while ($db->next_record()) {
		$nr = $db->v('nr');
		$articleData[$nr]['title'] = $db->v('titel');
		$articleData[$nr]['state'] = __('online');
		$articleData[$nr]['color'] = 'red';
		if ($db->v('pub_datum') >= date('Y-m-d H:i:s')) {
			$articleData[$nr]['state'] = 'not published yet';
			$articleData[$nr]['color'] = 'red';
		}
		if ($db->v('verfallsdatum') <= date('Y-m-d H:i:s')) {
			$articleData[$nr]['state'] = __('expired'); 
			$articleData[$nr]['color'] = 'red';
		}
		if ($db->v('artikel_archiv') == 5) {
			$articleData[$nr]['state'] = __('old article version');
			$articleData[$nr]['color'] = 'green';
		}
		if ($db->v('artikel_archiv') == 9) {
			$articleData[$nr]['state'] = __('deleted article'); 
			$articleData[$nr]['color'] = 'green';
		}
	}
	$multimode = false;

	if (isset($_GET['id']) && isset($_GET['file'])) {
		$query4files = ($show_only_images) ? "SELECT article_id FROM ".CPO_CONTENT_IMAGES." WHERE image_id=".$_GET['id'] : "SELECT article_id FROM ".CPO_CONTENT_FILES." WHERE file_id=".$_GET['id'];
		$query4articles = "SELECT article_id FROM ".CPO_CONTENT_HTML." WHERE html like '%".$_GET['file']."%'";
		$fileNameColonString = htmlspecialchars($_GET['file']);
		$givenFileIDs[] = $_GET['id'];
	} elseif (isset($_POST['files'])) {
		$multimode = (count($_POST['files']) > 1) ? true : false ;
		foreach($_POST['files'] AS $givenFile)  {
			$givenFileInfo=explode('#CPO#',$givenFile);
			$givenFiles[$givenFileInfo[0]]=$givenFileInfo[1];
			$givenFileIDs[]=$givenFileInfo[0];
			$givenFileNames[]=$givenFileInfo[1];
			$message .= '['.$givenFileInfo[0].'] '.$givenFileInfo[1].'<br />';
		}
		$fileIdString = implode(',',$givenFileIDs);
		$fileNameString = implode("%' OR  html like '%",$givenFileNames);
		$fileNameColonString = implode(", ",$givenFileNames);
		$query4files = ($show_only_images) ? "SELECT article_id FROM ".CPO_CONTENT_IMAGES." WHERE image_id IN (".$fileIdString.")" : "SELECT article_id FROM ".CPO_CONTENT_FILES." WHERE file_id IN (".$fileIdString.")";
		$query4articles = "SELECT article_id FROM ".CPO_CONTENT_HTML." WHERE html like '%".$fileNameString."%'";
	} else break;
	// messages
    switch ($show_only_images) {
    case true:
		$m_stilused = ($multimode) ? __('The images are still used in the following article(s).') : __('The image is still used in the following article(s).');
		$m_unused = ($multimode) ? __('The images %s seem to be unused.') : __('The image %s seems to be unused.');
		$m_confirm = ($multimode) ? __('Are you sure you want to delete the images %s?') : __('Are you sure you want to delete the image %s?');
        break;
    case false:
		$m_stilused = ($multimode) ? __('The files are still used in the following article(s).') : __('The file is still used in the following article(s).');
		$m_unused = ($multimode) ? __('The files %s seem to be unused.') : __('The file %s seems to be unused.');
		$m_confirm = ($multimode) ? __('Are you sure you want to delete the files %s?') : __('Are you sure you want to delete the file %s?');
        break;
    }

	$db->query($query4files);
	while ($db->next_record()) $articles[$db->v('article_id')] = $db->v('article_id');
	$db->query($query4articles);
	while ($db->next_record()) $articles[$db->v('article_id')] = $db->v('article_id');
	if (count($articles) > 0 )   {
		$message = '<span style="color:red">'. $m_stilused  .'</span><br />';
		foreach ($articles AS $articleID)  {
			$message .= '['.$articleID.'] <span style="color:'.$articleData[$articleID]['color'].'">'.$articleData[$articleID]['title'].' - '.__('Status').': '.$articleData[$articleID]['state'].'</span><br />';
		}
	} else {
		$message = '<span style="color:green">' . sprintf( $m_unused , '<em>' . $fileNameColonString . '</em>') . '</span><br />';
	}
	
	$message .=  sprintf( $m_confirm, '<em>'.$fileNameColonString.'</em>');
	$message .= '<br /><br />';
	$message .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'">';
	$message .= '<input type="hidden" name="action" value="reallydelete">';
	foreach ($givenFileIDs AS $hiddenfileID)$message .= '<input type="hidden" name="id[]" value="'.$hiddenfileID.'" />';
	$message .= '<input type="submit" name="yes" value="'.___('Yes, delete').'" />&nbsp;';
	$message .= '<input type="submit" name="no" value="'.___('No, do not delete').'" />';
	$message .= '</form>';
	include(CPO_BASEDIR.'_include/message.php');
	break;
case 'reallydelete':
    $db = new DB;
	$idString=implode(',',$_POST['id']);
    $db->query("SELECT datei FROM ".CPO_DATA." "
              ."WHERE id IN (".$idString.")");
    while ($db->next_record()) {
        $datei[] = $db->v('datei');
    }
	$nameString= implode(', ',$datei);
	if (isset($_POST['no'])) {
		$message[] = __('Aborted by user. No file was deleted.');
		break;
	}

	$query_del = "DELETE FROM ".CPO_DATA." "
                ."WHERE id IN (".$idString.")";
    DEBUG(1, $query_del, __FILE__, __LINE__);
    $db->query($query_del); 

    foreach ($datei AS $dateiName) @unlink (CPO_BASEDIR.'_data/'.$dateiName);

    switch ($show_only_images) {
    case true:
        $message[] = sprintf(__('The image(s) %s was successfully deleted.'), '<em>'.$nameString.'</em>');
        break;
    case false:
		$message[] = sprintf(__('The file(s) %s was successfully deleted.'), '<em>'.$nameString.'</em>');
        break;
    }
    
    logaction('delete files', $nameString);
    $_POST['id'] = '';

    break;
// end part 1 of 1 enhanced delete by m.roesel ***********************************************
und wer noch in den Genuß deutscher Texte kommen will macht noch folgendes:

=== OPEN / ÖFFNE ===
_include/lang/deutsch/common.inc.php

=== FIND / FINDE ===

Code: Alles auswählen

'' => '');
=== INSERT BEFORE / DAVOR EINFÜGEN ===

Code: Alles auswählen

// start part 1 of 1 enhanced delete by m.roesel ***********************************************
'The images are still used in the following article(s).'
=> 'Die Bilder werden derzeit in folgendem Artikel benutzt.',
'The image is still used in the following article(s).'
=> 'Das Bild wird derzeit in folgendem Artikel benutzt.',
'The images %s seem to be unused.'
=> 'Die Bilder %s scheinen derzeit nicht benutzt zu werden.',
'The image %s seems to be unused.'
=> 'Das Bild %s scheint derzeit nicht benutzt zu werden.',
'Are you sure you want to delete the images %s?'
=> 'Sind Sie sicher, daß Sie die Bilder %s löschen wollen?',
'Are you sure you want to delete the image %s?'
=> 'Sind Sie sicher, daß Sie das Bild %s löschen wollen?',
'The files are still used in the following article(s).'
=> 'Die Dateien werden derzeit in folgendem Artikel benutzt.',
'The file is still used in the following article(s).'
=> 'Die Datei wird derzeit in folgendem Artikel benutzt.',
'The files %s seem to be unused.'
=> 'Die Dateien %s scheinen derzeit nicht benutzt zu werden.',
'The file %s seems to be unused.'
=> 'Die Datei %s scheint derzeit nicht benutzt zu werden.',
'Are you sure you want to delete the files %s?'
=> 'Sind Sie sicher, daß Sie die Dateien %s löschen wollen?',
'Are you sure you want to delete the file %s?'
=> 'Sind Sie sicher, daß Sie die Datei %s löschen wollen?',
'selected'
=> 'ausgewählte',
'The image(s) %s was successfully deleted.'
=> 'Das bzw. die Bilder %s wurden erfolgreich gelöscht.',
'The file(s) %s was successfully deleted.'
=> 'Die Datei(en) %s wurden erfolgreich gelöscht.',
'online'
=> 'online',
'not published yet'
=> 'noch nicht veröffentlicht',
'expired'
=> 'verfallen',
'old article version'
=> 'veraltete Artikelversion',
'deleted article'
=> 'gelöschte Artikelversion',
'Aborted by user. No file was deleted.'
=> 'Abbruch durch Benutzer. Keine Datei wurde gelöscht.',
// end part 1 of 1 enhanced delete by m.roesel ***********************************************
Dateianhänge
enhanced_delete.zip
(36.15 KiB) 683-mal heruntergeladen
Zuletzt geändert von MarkusR am 30.11.2012 13:06, insgesamt 1-mal geändert.
Ciao Markus
ConPresso-Module

Kein Support per PN!!! Für Fragen und Diskussionen ist das Forum da!

Succi recentis officinalis
Hochwertige Kräutersäfte und -Öle
Benutzeravatar
MarkusR
Handbuchversteher
Beiträge: 7361
Registriert: 01.01.1970 01:00
Hat sich bedankt: 111 Mal
Danksagung erhalten: 933 Mal
Kontaktdaten:

Beitrag von MarkusR »

Hat hier jemand ein Feedback dazu???
Ciao Markus
ConPresso-Module

Kein Support per PN!!! Für Fragen und Diskussionen ist das Forum da!

Succi recentis officinalis
Hochwertige Kräutersäfte und -Öle
Benutzeravatar
Mr. Magpie
ConPresso-Profi
Beiträge: 1004
Registriert: 01.01.1970 01:00
Wohnort: Wuppertal
Hat sich bedankt: 274 Mal
Danksagung erhalten: 59 Mal

Beitrag von Mr. Magpie »

Sorry, ich komme zurzeit nicht zum Testen - zuviel Arbeit um die Ohren
Günther Ludwig
Benutzeravatar
hscha
ConPresso-Experte
Beiträge: 714
Registriert: 22.02.2006 22:00
Wohnort: Berlin
Hat sich bedankt: 216 Mal
Danksagung erhalten: 26 Mal
Kontaktdaten:

erfolgreicher Test

Beitrag von hscha »

Hallo Markus,

ich hab's auf drei Webseiten eingebaut und es funktioniert gut. Das einzige, was mir aufgefallen ist: Hat man mehrere Dateien zum Löschen abgehakt, so verschwinden die Häkchen, wenn man auf den Löschen-Button klickt, während oben die Analyse der Löschaktion als Meldung angezeigt wird (siehe Screenshots).

Ich finde es aber nicht dramatisch (vielleicht ist es ja auch so gedacht...).

ConPresso hat durch deine Arbeit einen großen Sprung nach vorn gemacht!!!

Grüße aus Berlin von
Horst
Dateianhänge
Während die Meldung oben erscheint, verschwinden die Häkchen
Während die Meldung oben erscheint, verschwinden die Häkchen
Mehrere Dateien gleichzeitig zum Löschen markieren zu können, ist ein tolles Feature!
Mehrere Dateien gleichzeitig zum Löschen markieren zu können, ist ein tolles Feature!
Benutzeravatar
MarkusR
Handbuchversteher
Beiträge: 7361
Registriert: 01.01.1970 01:00
Hat sich bedankt: 111 Mal
Danksagung erhalten: 933 Mal
Kontaktdaten:

Beitrag von MarkusR »

Das ist normal so... alternativ könnte man die Auflistung unten verschwinden lassen, um sich nicht verwirren zu lassen.
Ich finde es aber auch so ok...

Meine Abbildung oben war ja eine Fotomontage, um beide Stadien im Bild zu haben. Erst unten auswählen, dann oben bestätigen...

Danke fürs Feedback!
Ciao Markus
ConPresso-Module

Kein Support per PN!!! Für Fragen und Diskussionen ist das Forum da!

Succi recentis officinalis
Hochwertige Kräutersäfte und -Öle
Benutzeravatar
Mr. Magpie
ConPresso-Profi
Beiträge: 1004
Registriert: 01.01.1970 01:00
Wohnort: Wuppertal
Hat sich bedankt: 274 Mal
Danksagung erhalten: 59 Mal

Beitrag von Mr. Magpie »

Mir ist erst jetzt noch was aufgefallen: Klickt man den Button, um ausgewählte Bilder zu löschen, hat aber gar nichts ausgewählt, kommt es zu recht hässlichen Fehlermeldungen.
Günther Ludwig
Benutzeravatar
MarkusR
Handbuchversteher
Beiträge: 7361
Registriert: 01.01.1970 01:00
Hat sich bedankt: 111 Mal
Danksagung erhalten: 933 Mal
Kontaktdaten:

Beitrag von MarkusR »

Strafe muß eben sein!!!!


Ansonsten in i_manage_files.php

diesen Teil suchen

Code: Alles auswählen

   } 
   // messages 
und ersetzen durch

Code: Alles auswählen

   } else break;
   // messages 
edit: habe es oben im Code nachgetragen!
Ciao Markus
ConPresso-Module

Kein Support per PN!!! Für Fragen und Diskussionen ist das Forum da!

Succi recentis officinalis
Hochwertige Kräutersäfte und -Öle
Benutzeravatar
MarkusR
Handbuchversteher
Beiträge: 7361
Registriert: 01.01.1970 01:00
Hat sich bedankt: 111 Mal
Danksagung erhalten: 933 Mal
Kontaktdaten:

Beitrag von MarkusR »

Ciao Markus
ConPresso-Module

Kein Support per PN!!! Für Fragen und Diskussionen ist das Forum da!

Succi recentis officinalis
Hochwertige Kräutersäfte und -Öle
Antworten