You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
6.1 KiB

9 years ago
9 years ago
3 months ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
3 months ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
3 months ago
9 years ago
  1. <?php
  2. ## fonctions pour hasher les documents
  3. if (!defined("_ECRIRE_INC_VERSION")) return;
  4. include_spip('inc/sql');
  5. /* pour un fichier d'origine situé dans IMG/{$ext}/xxxx.ext,
  6. * prendre les 3 premiers caractères (a, b, c) du md5(xxxx.ext),
  7. * et déplacer le fichier dans IMG/{$ext}/a/b/c/xxxx.ext
  8. * attention on ignore le IMG/ eventuel dans $doc, et on retourne sans IMG/
  9. * $rev sert a faire l'inverse
  10. * @param string $doc
  11. * @param bool $rev
  12. * @return string
  13. */
  14. function hasher_adresser_document($doc, $rev=false) {
  15. switch ($rev) {
  16. case false:
  17. if (!preg_match(',^(?:IMG/)?([^/]+)/([^/]+\.\1)$,S', $doc, $r))
  18. return false;
  19. $m = md5($r[2]);
  20. return $r[1].'/'.$m[0].'/'.$m[1].'/'.$m[2].'/'.$r[2];
  21. case true:
  22. if (!preg_match(',^(?:IMG/)?([^/]+)/./././([^/]+\.\1)$,S', $doc, $r))
  23. return false;
  24. return $r[1].'/'.$r[2];
  25. }
  26. }
  27. /* Deplacer un fichier et sa reference dans la base de donnees
  28. * avec tous les controles d'erreur
  29. *
  30. * @param int $id_document
  31. * @param bool $rev
  32. * @return bool
  33. */
  34. function hasher_deplacer_document($id_document, $corriger=false, $rev=false) {
  35. // 1. recuperer les donnees du document
  36. // et verifier qu'on peut le hasher
  37. if (!$id_document = intval($id_document)){
  38. spip_log("Erreur hasher_deplacer_document intval $id_document", 'hash');
  39. return false;
  40. }
  41. if (!$t = sql_fetsel('fichier', 'spip_documents', 'id_document='.$id_document)
  42. ) {
  43. spip_log("Erreur hasher_deplacer_document select doc=$id_document ", 'hash');
  44. return false;
  45. }
  46. $src = $t['fichier'];
  47. // savoir si on a IMG/ devant (en SPIP 1.9.2) ou pas (SPIP 2++)
  48. $img = preg_match(',^IMG/,', $src)
  49. ? 'IMG/' : '';
  50. $dir_ref = preg_match(',^IMG/,', $src)
  51. ? _DIR_RACINE : _DIR_IMG;
  52. // On fabrique le nom du fichier dest
  53. if (!$dest = hasher_adresser_document($src, $rev)) {
  54. spip_log("Erreur hasher_adresser_document($src) rev : $rev", 'hash');
  55. return false;
  56. }
  57. // si le src n'existe pas, ciao, enfin presque
  58. if (!file_exists($dir_ref.$src)) {
  59. spip_log("Erreur hasher_deplacer_document id_document $id_document fichier $dir_ref $src n'existe pas", 'hash');
  60. // si le src n'existe pas, on verifie qu'il n'a pas deja ete déplace (ie le dest existe),
  61. // et si oui, on modifie juste le chemin en base...
  62. if($corriger) {
  63. if(file_exists(_DIR_IMG.$dest)){
  64. // on note la destination finale
  65. if (!sql_updateq('spip_documents', ['fichier'=>$img.$dest], ['id_document' => $id_document])) {
  66. spip_log("erreur hasher_deplacer_document update correction $img $dest doc $id_document", 'hash');
  67. return false;
  68. } else {
  69. spip_log("hasher_deplacer_document fichier "._DIR_IMG."$dest existe deja, Table corrigee", 'hash');
  70. return true ;
  71. }
  72. } else {
  73. spip_log("hasher_deplacer_document fichier "._DIR_IMG."$dest n'existe pas", 'hash');
  74. }
  75. }
  76. return false ;
  77. }
  78. // si le dest existe deja, renommer jusqu'a trouver un creneau libre
  79. $i = 0;
  80. while (file_exists(_DIR_IMG.$dest)) {
  81. $i++;
  82. $dest = preg_replace(',(-\d+)?(\.[^.]+)$,', '-'.$i.'\2', $dest);
  83. }
  84. // 2. creer au besoin les sous-repertoires
  85. if (!is_dir(_DIR_IMG.$dir = dirname($dest))
  86. AND !mkdir(_DIR_IMG.$dir, _SPIP_CHMOD, true)) {
  87. spip_log("erreur hasher_deplacer_document mkdir($dir)", 'hash');
  88. return false;
  89. }
  90. // 3. Section critique : il faut modifier dans la base *et* deplacer
  91. // on note les fichiers en cours de deplacement avec un - devant ; si
  92. // ca casse on saura reparer
  93. if (!sql_update('spip_documents', ['fichier'=>'CONCAT("-", fichier)'], 'id_document='.$id_document)) {
  94. spip_log("erreur hasher_deplacer_document update 1", 'hash');
  95. return false;
  96. }
  97. // on deplace
  98. if (!rename($dir_ref.$src, _DIR_IMG.$dest)) {
  99. spip_log("erreur hasher_deplacer_document rename", 'hash');
  100. sql_updateq('spip_documents', ['fichier'=>$src], 'id_document='.$id_document);
  101. return false;
  102. }
  103. // on note la destination finale
  104. if (!sql_updateq('spip_documents', ['fichier'=>$img.$dest], 'id_document='.$id_document)) {
  105. spip_log("erreur hasher_deplacer_document update 2", 'hash');
  106. return false;
  107. }
  108. // 4. Ouf c'est fini et sans erreur
  109. return true;
  110. }
  111. /* Cette fonction prend les n documents non hashés les plus récents,
  112. * et appelle hasher_deplacer_document() sur chacun d'eux. Elle renvoie
  113. * un array() contenant les id_document des documents qu'elle a déplacés.
  114. * @param int $n
  115. * @param bool $rev
  116. * @return array
  117. * @return bool
  118. */
  119. function hasher_deplacer_n_documents($n, $corriger=false, $rev=false) {
  120. $docs = array();
  121. static $dejafait = false;
  122. // Une seule fois par hit (cas de l'insertion de plusieurs docs venant d'un zip)
  123. if ($dejafait) return $docs ;
  124. $dejafait = true;
  125. if (!$n = intval($n)
  126. OR !$s = sql_select(
  127. 'id_document',
  128. 'spip_documents',
  129. "fichier REGEXP '^(IMG/)?[^/]+/". ($rev ? "./././" : "")."[^/]+$' AND distant='non'",
  130. '',
  131. 'date',
  132. $n
  133. )) {
  134. spip_log("erreur hasher_deplacer_n_documents", 'hash');
  135. return false;
  136. }
  137. while ($t = sql_fetch($s)) {
  138. $id_document = $t['id_document'];
  139. if (hasher_deplacer_document($id_document, $corriger, $rev))
  140. $docs[] = $id_document;
  141. }
  142. return $docs;
  143. }
  144. /* Compte les documents hashes et non hashes
  145. * @return array
  146. */
  147. function hasher_compter_documents() {
  148. $non = sql_countsel('spip_documents', "fichier REGEXP '^(IMG/)?[^/]+/"
  149. ."[^/]+$' AND distant='non'");
  150. $oui = sql_countsel('spip_documents', "fichier REGEXP '^(IMG/)?[^/]+/"
  151. . "./././"
  152. ."[^/]+$' AND distant='non'");
  153. return array($oui, $non);
  154. }
  155. /* Pipeline post_edition pour agir apres ajout de nouveaux documents via upload
  156. * @param array $flux
  157. * @return array
  158. */
  159. function hasher_post_edition($flux) {
  160. if ($flux['args']['operation']?? '' == 'ajouter_document'
  161. AND $id = intval($flux['args']['id_objet'])) {
  162. hasher_deplacer_document($id);
  163. hasher_deplacer_n_documents(10);
  164. }
  165. return $flux;
  166. }
  167. function htaccess_est_installe($htaccess){
  168. if (!lire_fichier($htaccess, $contenu)
  169. OR !preg_match(',hash_404,', $contenu)) {
  170. return false ;
  171. } else {
  172. return true ;
  173. }
  174. }