Server : Apache System : Linux webd348.cluster026.gra.hosting.ovh.net 5.15.148-ovh-vps-grsec-zfs-classid #1 SMP Thu Feb 8 09:41:04 UTC 2024 x86_64 User : hednacluml ( 122243) PHP Version : 8.3.9 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl Directory : /home/hednacluml/jobs/plugins-dist/dump/inc/ |
<?php /***************************************************************************\ * SPIP, Système de publication pour l'internet * * * * Copyright © avec tendresse depuis 2001 * * Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribué sous licence GNU/GPL. * \***************************************************************************/ /** * API permettant la manipulation des sauvegardes * * @package SPIP\Dump\API */ if (!defined('_ECRIRE_INC_VERSION')) { return; } /** * Répertoire de sauvegarde * * Crée et retourne le chemin du répertoire de sauvegarde * * @see _DIR_DUMP * * @return string */ function dump_repertoire() { $repertoire = _DIR_DUMP; if ( !@file_exists($repertoire) and !$repertoire = sous_repertoire(_DIR_DUMP, '', false, true) ) { $repertoire = preg_replace(',' . _DIR_TMP . ',', '', _DIR_DUMP); $repertoire = sous_repertoire(_DIR_TMP, $repertoire); } return $repertoire; } /** * Nom du fichier de sauvegarde * * la fourniture de l'extension permet de vérifier que le nom n'existe pas déjà. * * @param string $dir Chemin de stockage du fichier * @param string $extension Extension du fichier de sauvegarde * @return string */ function dump_nom_fichier($dir, $extension = 'sqlite') { include_spip('inc/texte'); $site = 'spip'; if (isset($GLOBALS['meta']['nom_site'])) { $site = typo($GLOBALS['meta']['nom_site']); // extraire_multi $site = couper(translitteration(trim($site)), 30, ''); $site = preg_replace([',\W,is', ',_(?=_),', ',_$,'], ['_', '', ''], $site); } $site .= '_' . date('Ymd'); $nom = $site; $cpt = 0; while (file_exists($dir . $nom . ".$extension")) { $nom = $site . sprintf('_%03d', ++$cpt); } return $nom . ".$extension"; } /** * Détermine le type de serveur de sauvegarde, * sqlite2 ou sqlite3 * * @return string */ function dump_type_serveur() { // chercher si sqlite2 ou 3 est disponible include_spip('req/sqlite3'); if (function_exists('spip_versions_sqlite3') and spip_versions_sqlite3()) { return 'sqlite3'; } if (function_exists('spip_versions_sqlite3')) { spip_log( "ERREUR sqlite3 n'est pas correctement installé : " . "extension_loaded('pdo')=" . extension_loaded('pdo') . " extension_loaded('pdo_sqlite')=" . extension_loaded('pdo_sqlite'), _LOG_ERREUR ); } return ''; } /** * Conteneur pour les arguments de la connexion * * Si on passe $args, les arguments de la connexion sont memorisés. * Renvoie toujours les derniers arguments memorisés. * * @staticvar array $connect_args Pour stocker le premier conteneur * @param array $args * @return array */ function dump_serveur($args = null) { static $connect_args = null; if ($args) { $connect_args = $args; } return $connect_args; } function dump_connect_args($archive) { if (!$type_serveur = dump_type_serveur()) { return null; } return [dirname($archive), '', '', '', basename($archive, '.sqlite'), $type_serveur, 'spip']; } /** * Initialiser un dump * * @param string $status_file Fichier contenant les informations serialisees sur le statut de l'export * @param string $archive Nom de l'archive (stockee dans le fichier de statut) * @param array $tables Liste des tables a exporter (autocaculee par defaut) * @param array $where Condition sur l'export * @param string $action Pour differencier la sauvegarde de l'import * @return bool/string */ function dump_init($status_file, $archive, $tables = null, $where = [], $action = 'sauvegarde') { $status = []; $status_file = _DIR_TMP . basename($status_file) . '.txt'; if ( lire_fichier($status_file, $status) and $status = unserialize($status) and $status['etape'] !== 'fini' and filemtime($status_file) >= time() - 120 ) { // si le fichier status est trop vieux c'est un abandon return _T('dump:erreur_' . $action . '_deja_en_cours'); } if (!$type_serveur = dump_type_serveur()) { return _T('dump:erreur_sqlite_indisponible'); } if (!$tables) { [$tables, ] = base_liste_table_for_dump(lister_tables_noexport()); } $status = ['tables' => $tables, 'where' => $where, 'archive' => $archive]; $status['connect'] = dump_connect_args($archive); dump_serveur($status['connect']); if (!spip_connect('dump')) { return _T('dump:erreur_creation_base_sqlite'); } // la constante sert a verifier qu'on utilise bien le connect/dump du plugin, // et pas une base externe homonyme if (!defined('_DUMP_SERVEUR_OK')) { return _T('erreur_connect_dump', ['dump' => 'dump']); } $status['etape'] = 'init'; if (!ecrire_fichier($status_file, serialize($status))) { return _T('dump:avis_probleme_ecriture_fichier', ['fichier' => $status_file]); } return true; } /** * Afficher l'avancement de la copie * * @staticvar int $etape Nombre de fois ou on est passe dans cette foncion * @param <type> $courant Flag pour indiquer si c'est la table sur laquelle on travaille actuellement * @param <type> $total Nombre total de tables * @param <type> $table Nom de la table */ function dump_afficher_progres($courant, $total, $table) { static $etape = 1; if (unique($table)) { if ($total < 0 or !is_numeric($total)) { echo '<br /><strong>' . $etape . '. ' . "</strong>$table "; } else { echo '<br /><strong>' . $etape . '. ' . "$table</strong> " . ($courant ? " <i>($courant)</i> " : ''); } $etape++; } if (is_numeric($total) and $total >= 0) { echo '. '; } else { echo '(' . (-intval($total)) . ')'; } flush(); } /** * Écrire le js pour relancer la procédure de dump * * @param string $redirect URL de la prochaine etape du dump * @return string Code HTML de redirection */ function dump_relance($redirect) { // si Javascript est dispo, anticiper le Time-out return "<script language=\"JavaScript\" type=\"text/javascript\">window.setTimeout('location.href=\"$redirect\";',300);</script>\n"; } /** * Marquer la procédure de dump comme finie * * @param string $status_file * Fichier qui mémorise les infos utiles concernant la sauvegarde en cours * @param string $action * Type d'action supplémentaire à réaliser : * * - restaurer : supprimer la structure qui était stockée dans le dump * - 'auvegarder : stocker dans le dump la structure de la base source */ function dump_end($status_file, $action = '') { $status = []; $status_file = _DIR_TMP . basename($status_file) . '.txt'; if ( !lire_fichier($status_file, $status) or !$status = unserialize($status) ) { return; } switch ($action) { case 'restaurer': // supprimer la structure qui etait stockee dans le dump sql_delete('spip_meta', "nom='dump_structure_temp'"); break; case 'sauvegarder': // stocker dans le dump la structure de la base source $structure = []; foreach ($status['tables_copiees'] as $t => $n) { $structure[$t] = sql_showtable($t, true); } dump_serveur($status['connect']); spip_connect('dump'); // si spip_meta n'a pas ete backup elle n'est pas dans le dump, il faut la creer pour y stocker cette meta if (!sql_showtable('spip_meta', true, 'dump')) { $desc = sql_showtable('spip_meta', true); sql_create('spip_meta', $desc['field'], $desc['key'], false, false, 'dump'); } sql_delete('spip_meta', "nom='dump_structure_temp'", 'dump'); #enlever une vieille structure deja la, au cas ou sql_insertq( 'spip_meta', ['nom' => 'dump_structure_temp', 'valeur' => serialize($structure), 'impt' => 'non'], [], 'dump' ); break; } $status['etape'] = 'fini'; ecrire_fichier($status_file, serialize($status)); } /** * Lister les fichiers de sauvegarde existant dans un repertoire * trie par nom, date ou taille * * @param string $dir Repertoire de sauvegarde * @param string $tri Tri pour recuperer les fichiers * @param string $extension Extension des fichiers de sauvegarde * @param int $limit Nombre max de fichiers listes * @return array */ function dump_lister_sauvegardes($dir, $tri = 'nom', $extension = 'sqlite', $limit = 100) { $liste_dump = preg_files($dir, '\.' . $extension . '$', $limit, false); $n = strlen($dir); $tn = $tl = $tt = $td = []; foreach ($liste_dump as $fichier) { $d = filemtime($fichier); $t = filesize($fichier); $fichier = substr($fichier, $n); $tl[] = ['fichier' => $fichier, 'taille' => $t, 'date' => $d]; $td[] = $d; $tt[] = $t; $tn[] = $fichier; } if ($tri == 'taille') { array_multisort($tt, SORT_ASC, $tl); } elseif ($tri == 'date') { array_multisort($td, SORT_ASC, $tl); } else { array_multisort($tn, SORT_ASC, $tl); } return $tl; } /** * Extraire le statut contenu dans un fichier * * @param $status_file Nom du fichier stocke dans _DIR_TMP * @return array|string */ function dump_lire_status($status_file) { $status = null; if (!$status_file) { return ''; } $status_file = _DIR_TMP . basename($status_file) . '.txt'; if ( !lire_fichier($status_file, $status) or !$status = unserialize($status) ) { return ''; } return $status; } /** * Verifier qu'un sauvegarde est finie * * @param $status_file Nom du fichier stocke dans _DIR_TMP * @return string Chaine non vide s'il reste des choses a faire */ function dump_verifie_sauvegarde_finie($status_file) { if ( !$status_file or !$status = dump_lire_status($status_file) or $status['etape'] !== 'fini' ) { return ''; } return ' '; } /** * Recuperer le nom du fichier d'archivage qui est memorise dans le fichier de statut * * @param $status_file Nom du fichier stocke dans _DIR_TMP * @return string Nom ou chaine vide si on a un probleme */ function dump_nom_sauvegarde($status_file) { if ( !$status = dump_lire_status($status_file) or !file_exists($f = $status['archive'] . '.sqlite') ) { return ''; } return $f; } /** * Recuperer la taille du fichier de sauvegarde * * @param $status_file Nom du fichier stocke dans _DIR_TMP * @return string/int Taille ou Chaine vide en cas de probleme */ function dump_taille_sauvegarde($status_file) { if ( !$f = dump_nom_sauvegarde($status_file) or !$s = filesize($f) ) { return ''; } return $s; } /** * Recuperer la date de derniere modification du fichier de sauvegarde * * @param $status_file Nom du fichier stocke dans _DIR_TMP * @return string/int Date ou Chaine vide en cas de probleme */ function dump_date_sauvegarde($status_file) { if ( !$f = dump_nom_sauvegarde($status_file) or !$d = filemtime($f) ) { return ''; } return date('Y-m-d', $d); }