Sauvegarde des pièces jointes sous leurs noms d'origine

Description: phpBB3 stocke les pièces jointes avec des noms de fichiers aléatoires et sans extension. Mais, un propriétaire du forum peut vouloir sauvegarder tous les fichiers avec leur nom de fichier d'origine. Cet article décrit un script pour le faire.

Catégories: Divers

Lien vers cet article: Tout sélectionner

[url=https://forums.caforum.fr/kb/viewarticle?a=18]Base de connaissance - Sauvegarde des pièces jointes sous leurs noms d'origine[/url]

Le nom de fichier utilisé par phpBB et le nom de fichier d'origine sont stockés dans la table attachments, donc pour récupérer le nom de fichier d'origine, vous pouvez utiliser les données de cette table.

Voici un script qui copie tous les fichiers (à l'exception des vignettes) téléchargés en tant que pièces jointes dans un dossier différent et les renomme avec le nom de fichier d'origine, précédé de l'attachment_id pour éviter les noms de fichiers en double. Les données d'origine dans phpBB ne sont pas modifiées.


Étape 1

Tout d'abord, créez un répertoire appelé filebackup dans le dossier racine de votre forum et définissez son autorisation CHMOD sur 777.

Étape 2

Collez le script suivant dans un éditeur de texte brut, enregistrez-le sous le nom rename.php et placez-le dans le dossier racine de votre forum (où se trouve config.php).

Code: Tout sélectionner

<?php
/**
* This script will copy all attachments from the attachment folder (default
* "files") to a separate directory, replacing the cryptic phpBB filename with the
* original filename, prepended by numeric attach_id to prevent duplicate filenames.
*/

/**
* @ignore
*/
define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);

// Name of script - change if you use a different name for the script
$scriptname = 'rename.php';
// Specify the number of attachments to copy in one run - reduce if you receive a timeout from server
$interval = 100;
// Specify the path for the copies - must have write access (CHMOD 777)
$copypath = 'filebackup';

// read id of last attachement copied
if (isset($config['last_attach_id']))
{
   $last_attach_id = $config['last_attach_id'];
}
else
{
   $last_attach_id = 0;
   set_config('last_attach_id', 0);
}

// count number of attachments to process
$sql = 'SELECT COUNT(attach_id) AS num_attach
    FROM ' . ATTACHMENTS_TABLE . '
WHERE attach_id > ' . (int) $last_attach_id . '
ORDER BY attach_id ASC';
$result = $db->sql_query($sql);
$attachs_count = (int) $db->sql_fetchfield('num_attach');

// Output Information
echo dheader();

// read required information from attachment table
$sql = 'SELECT attach_id, physical_filename, real_filename
    FROM ' . ATTACHMENTS_TABLE . '
WHERE attach_id > ' . (int) $last_attach_id . '
ORDER BY attach_id ASC';
$result = $db->sql_query_limit($sql, $interval);

// how many attachment do we copy in this run?
$actual_num = $db->sql_affectedrows($result);
if ($actual_num == 0)
{
    // nothing to do
    $complete = true;
}
else
{
    $complete = false;
    if ($attachs_count <= $interval)
    {
        // this is the last run
        $complete = true;
    }
    while ($row = $db->sql_fetchrow($result))
    {
        // for each attachment
        //remember id
        $last_attach_id = $row['attach_id'];
        // build source filename including path (we fetch the path from config
        $source = $phpbb_root_path . $config['upload_path'] . '/' . $row['physical_filename'];
        // build destination filename including path
        $destination = $phpbb_root_path . $copypath . '/' . $last_attach_id . "_" . $row['real_filename'];
        // copy the file
        if (copy ($source, $destination))
        {
            // write info to user
            echo sprintf("<tr><td class='succ'>copy succesful:</td><td>%s</td><td>%s</td><td>%s</td></tr>", $last_attach_id, $source, $destination);
        }
        else
        {
            echo sprintf("<tr><td class='error'>copy failed:</span></td><td>%s</td><td>%s</td><td>%s</td></tr>", $last_attach_id, $source, $destination);
        }
    }
    // write last attachment id in config
    set_config('last_attach_id', $last_attach_id);
}
// finished
echo dfooter();

function dheader()
{
    global $attachs_count, $interval;
    if ($interval > $attachs_count)
    {
        $interval = $attachs_count;
    }
    $remain = $attachs_count - $interval;

    return '<html>
    <head>
        <title>copy ' . $interval . ' attachments in this run, ' . $remain . ' remain to copy</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf8">
        <style>
            a:visited {COLOR: #3A4273; TEXT-DECORATION: none}
            a:link {COLOR: #3A4273; TEXT-DECORATION: none}
            a:hover {COLOR: #3A4273; TEXT-DECORATION: underline}
            .error {COLOR: red; ; FONT-WEIGHT: bold}
            .succ {COLOR: green; ; FONT-WEIGHT: bold}
            body, table, td {COLOR: #3A4273; FONT-FAMILY: Tahoma, Verdana, Arial; FONT-SIZE: 12px; LINE-HEIGHT: 20px; scrollbar-base-color: #E3E3EA; scrollbar-arrow-color: #5C5C8D}
            input {COLOR: #085878; FONT-FAMILY: Tahoma, Verdana, Arial; FONT-SIZE: 12px; background-color: #3A4273; color: #FFFFFF; scrollbar-base-color: #E3E3EA; scrollbar-arrow-color: #5C5C8D}
            .install {FONT-FAMILY: Arial, Verdana; FONT-SIZE: 20px; FONT-WEIGHT: bold; COLOR: #000000}
        </style>
    </head>
    <body bgcolor="#3A4273" text="#000000">
        <table width="95%" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" align="center">
            <tr>
                <td>
                    <table width="98%" border="0" cellspacing="0" cellpadding="0" align="center">
                        <tr><th colspan="4">copy ' . $interval . ' attachments in this run, ' . $remain . ' remain to copy</th></tr>
                        <tr>
                            <th>Status</th><th>Attach_ID</th><th>phpBB internal file name</th><th>Copy with original file name</th>
                        </tr>';
}

function dfooter()
{
    global $scriptname, $complete;
    if (!$complete)
    {
        $next_step_link = '<a href="' . $scriptname . '">Click to continue with next step</a>';
    }
    else
    {
        $next_step_link = "<b>Completed</b>";
    }

    return '<tr><td colspan="4" align="center">' . $next_step_link . '</td></tr>
                    </table>
                </td>
            </tr>
        </table><br>
    </body>
</html>';
}

?>

Exécutez le script en accédant à https://www.example.com/[board_root_folder_name]/rename.php.

Le script copie et renomme tous les fichiers (sauf les vignettes) dans le nouveau dossier filebackup. Pour éviter les noms de fichiers en double (peut-être que 2 utilisateurs ont utilisé abc.jpg), l'ID de pièce jointe est ajouté au nom de fichier.

Le script présente une sortie détaillée de tous les fichiers copiés et peut être invoqué plusieurs fois.
Appuyez simplement sur F5 pour redémarrer le script ou suivez le lien en bas de la page après la première exécution.


Étape 3

Une fois terminé, vous pouvez télécharger tous les fichiers du dossier filebackup avec de « vrais » noms.

REMARQUES
  • Si vous obtenez une erreur lors de l'exécution du script, vous pouvez réduire le nombre de fichiers copiés (diminuez simplement la valeur de $interval au début du script).
  • Augmentez $interval si vous avez un grand nombre de pièces jointes - testez simplement la valeur appropriée à vos besoins.
  • Gardez à l'esprit que lorsque vous avez un grand nombre de pièces jointes, vous pouvez rencontrer un délai d'attente php. Essayez de réduire la valeur de $interval comme décrit ci-dessus.
  • Le script définit une valeur dans la base de données lorsqu'il est exécuté, donc si le script est exécuté à nouveau, seules les pièces jointes ajoutées au tableau après sa dernière exécution seront copiées. Si vous devez recopier toutes les pièces jointes, vous pouvez réinitialiser la valeur dans la base de données en exécutant cette requête SQL :

Code: Tout sélectionner

UPDATE phpbb_config SET config_value = 0 WHERE config_name = 'last_attach_id';

Si phpbb_ est le préfixe de votre table.

Traduit depuis phpbb.com