sftp.class.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <?php
  2. /**
  3. * Classe sftp
  4. *
  5. * Cette classe gère les interactions avec un serveur SFTP, y compris la connexion,
  6. * l'envoi, la suppression et la récupération de fichiers.
  7. */
  8. class sftp
  9. {
  10. /**
  11. * @var mixed Ressource d'authentification ou identifiants pour la connexion SFTP.
  12. */
  13. private static $authent;
  14. /**
  15. * @var mixed Ressource ou objet de connexion SFTP.
  16. */
  17. private static $connexion;
  18. /**
  19. * @var mixed Données à envoyer via la connexion SFTP.
  20. */
  21. private static $dataSend;
  22. /**
  23. * Établit une connexion à l'hôte SFTP via le protocole SSH2.
  24. *
  25. * Modifie temporairement le délai d'attente par défaut du socket selon le nombre de secondes spécifié,
  26. * puis tente de se connecter. Restaure le délai d'attente initial après la tentative de connexion.
  27. * Retourne TRUE si la connexion réussit, FALSE sinon.
  28. *
  29. * @param int $_sec Nombre de secondes à définir pour le délai d'attente du socket (par défaut : 2).
  30. * @return bool TRUE si la connexion est réussie, FALSE en cas d'échec.
  31. */
  32. private static function connectHost(int $_sec = 2)
  33. {
  34. $originalConnectionTimeout = ini_get('default_socket_timeout');
  35. ini_set('default_socket_timeout', $_sec);
  36. if (self::$authent = @ssh2_connect(SFTP_HOST, 22)) {
  37. ini_set('default_socket_timeout', $originalConnectionTimeout);
  38. return TRUE;
  39. } else {
  40. return FALSE;
  41. }
  42. }
  43. /**
  44. * Authentifie l'utilisateur auprès de l'hôte SFTP.
  45. *
  46. * @return bool Vrai si l'authentification est réussie, faux sinon.
  47. */
  48. private static function authentHost()
  49. {
  50. return (@ssh2_auth_password(self::$authent, SFTP_USER, SFTP_PASS)) ? TRUE : FALSE;
  51. }
  52. /**
  53. * Initialise la connexion SFTP.
  54. *
  55. * @return bool Vrai si l'initialisation est réussie, faux sinon.
  56. */
  57. private static function initializeHost()
  58. {
  59. return (self::$connexion = @ssh2_sftp(self::$authent)) ? TRUE : FALSE;
  60. }
  61. /**
  62. * Vérifie si un fichier existe localement.
  63. *
  64. * @param string $_file Chemin du fichier à vérifier.
  65. * @return bool Vrai si le fichier existe, faux sinon.
  66. */
  67. private static function fileExist(?string $_file = NULL)
  68. {
  69. return (file_exists($_file)) ? TRUE : FALSE;
  70. }
  71. /**
  72. * Lit le contenu d'un fichier local.
  73. *
  74. * @param string $_file Chemin du fichier à lire.
  75. * @return bool Vrai si le contenu est lu avec succès, faux sinon.
  76. */
  77. private static function fileGetContents(?string $_file = NULL)
  78. {
  79. return (self::$dataSend = @file_get_contents($_file)) ? TRUE : FALSE;
  80. }
  81. /**
  82. * Accède à l'hôte SFTP en établissant une connexion complète.
  83. *
  84. * @param bool $_showAlert Affiche des alertes en cas d'erreur (par défaut TRUE).
  85. * @return bool Vrai si l'accès est réussi, faux sinon.
  86. */
  87. private static function accessHost(bool $_showAlert = TRUE)
  88. {
  89. if (!self::connectHost()) {
  90. ($_showAlert == TRUE) ? alert::recError("Erreur de connection au serveur distant") : NULL;
  91. return FALSE;
  92. }
  93. if (!self::authentHost()) {
  94. ($_showAlert == TRUE) ? alert::recError("Erreur d'authentification au serveur distant") : NULL;
  95. return FALSE;
  96. }
  97. if (!self::initializeHost()) {
  98. ($_showAlert == TRUE) ? alert::recError("Erreur d'initialisation au serveur distant") : NULL;
  99. return FALSE;
  100. }
  101. ($_showAlert == TRUE) ? alert::recSuccess("Accès au serveur distant") : NULL;
  102. return TRUE;
  103. }
  104. /**
  105. * Teste l'accès à l'hôte SFTP sans afficher d'alertes.
  106. *
  107. * @return bool Vrai si l'accès est réussi, faux sinon.
  108. */
  109. public static function testAccessHost()
  110. {
  111. return (self::accessHost(FALSE)) ? TRUE : FALSE;
  112. }
  113. /**
  114. * Envoie un fichier au serveur distant.
  115. *
  116. * @param string $_file Nom du fichier à envoyer.
  117. * @return bool Vrai si le fichier est envoyé avec succès, faux sinon.
  118. */
  119. private static function sendFile(string $_file)
  120. {
  121. self::accessHost();
  122. $stream = @fopen("ssh2.sftp://" . self::$authent . SFTP_REMOTE . $_file, "w");
  123. if ($stream == FALSE){
  124. alert::recError("Impossible d'écrire sur le serveur distant");
  125. return FALSE;
  126. }
  127. $data = @file_get_contents(SFTP_LOCAL . $_file);
  128. if ($data == FALSE){
  129. alert::recError("Impossible d'extraire les données du fichier local");
  130. return FALSE;
  131. }
  132. if (@fwrite($stream, $data) === false) {
  133. alert::recError($_file . " n'a pas pu être transféré au serveur distant");
  134. return FALSE;
  135. } else {
  136. alert::recSuccess($_file . " a été trasféré avec succès");
  137. return TRUE;
  138. }
  139. @fclose($stream);
  140. }
  141. /**
  142. * Supprime un fichier du serveur distant.
  143. *
  144. * @param string $_file Nom du fichier à supprimer.
  145. * @return bool Vrai si le fichier est supprimé avec succès, faux sinon.
  146. */
  147. public static function deleteFileToRemote(string $_file)
  148. {
  149. db::query("UPDATE " . DB_T_EXCEL . " SET createForSFTP = NULL WHERE id = :id");
  150. db::bind(':id', salaries::lastExcel());
  151. try {
  152. db::execute();
  153. alert::recSuccess($_file . " a été supprimé du serveur local.");
  154. return TRUE;
  155. } catch (Exception $e) {
  156. alert::recError($_file . " n'a pas pu être supprimé");
  157. return FALSE;
  158. }
  159. }
  160. /**
  161. * Envoie un fichier local au serveur distant.
  162. *
  163. * @param string|null $_file Nom du fichier à envoyer.
  164. * @return bool Vrai si le fichier est envoyé avec succès, faux sinon.
  165. */
  166. public static function sendFileToRemote(?string $_file = NULL)
  167. {
  168. if ($_file == NULL) {
  169. alert::recError("Le fichier à envoyé n'a pas été défini");
  170. return FALSE;
  171. } elseif (!self::fileExist(SFTP_LOCAL . $_file)) {
  172. alert::recError($_file . " n'est pas présent sur le serveur");
  173. return FALSE;
  174. } else {
  175. return self::sendFile($_file);
  176. }
  177. }
  178. /**
  179. * Scanne les fichiers présents dans le dossier distant.
  180. *
  181. * @return array Liste des fichiers dans le dossier distant.
  182. */
  183. public static function scanFolderRemote()
  184. {
  185. self::accessHost(FALSE);
  186. $realpath = @ssh2_sftp_realpath(self::$connexion, SFTP_REMOTE);
  187. $dir = "ssh2.sftp://" . self::$connexion . $realpath;
  188. $tempArray = array();
  189. if (is_dir($dir)) {
  190. if ($dh = opendir($dir)) {
  191. while (($file = readdir($dh)) !== false) {
  192. $tempFile = NULL;
  193. $realpath = @ssh2_sftp_realpath(self::$connexion, $file);
  194. $filetype = filetype($dir . $realpath);
  195. $size = sprintf("%.2f", filesize($dir . $realpath));
  196. if ($filetype != "dir") {
  197. $infos = @ssh2_sftp_stat(self::$connexion, SFTP_REMOTE.$file);
  198. $tempFile["file"] = $file;
  199. $tempFile["size"] = core::formatFileSize($infos["size"], 2);
  200. $tempFile["date"] = core::dateFromTimestamp($infos["atime"]);
  201. $tempArray[] = $tempFile;
  202. }
  203. }
  204. closedir($dh);
  205. }
  206. }
  207. return $tempArray;
  208. }
  209. /**
  210. * Scanne les fichiers présents dans le dossier local.
  211. *
  212. * @return array Liste des fichiers dans le dossier local.
  213. */
  214. public static function scanFolderLocal()
  215. {
  216. $tempArray = array();
  217. if ($scandir = scandir(SFTP_LOCAL)) {
  218. foreach ($scandir as $file) {
  219. $tempFile = NULL;
  220. if (is_file(SFTP_LOCAL . $file) === TRUE and $file != "index.html") {
  221. $tempFile["file"] = $file;
  222. $tempFile["size"] = core::formatFileSize(filesize(SFTP_LOCAL . $file), 2);
  223. $tempFile["date"] = core::dateFromTimestamp(filemtime(SFTP_LOCAL . $file));
  224. $tempArray[] = $tempFile;
  225. }
  226. }
  227. }
  228. return $tempArray;
  229. }
  230. /**
  231. * Supprime un fichier du serveur distant.
  232. *
  233. * @param string $_file Nom du fichier à supprimer.
  234. * @return bool Vrai si le fichier est supprimé avec succès, faux sinon.
  235. */
  236. public static function deleteFormRemote(string $_file)
  237. {
  238. self::accessHost(FALSE);
  239. if (@ssh2_sftp_unlink(self::$connexion, SFTP_REMOTE . $_file)) {
  240. alert::recSuccess($_file . " a été supprimé du serveur distant.");
  241. return TRUE;
  242. } else {
  243. alert::recError($_file . " n'a pas été supprimé du serveur distant");
  244. return FALSE;
  245. }
  246. }
  247. /**
  248. * Télécharge un fichier du serveur distant vers le serveur local.
  249. *
  250. * @param string $_file Nom du fichier à télécharger.
  251. */
  252. public static function downloadFormRemote(string $_file)
  253. {
  254. self::accessHost(FALSE);
  255. //ssh2_scp_recv(self::$authent, SFTP_REMOTE.$_file, SFTP_LOCAL.$_file);
  256. $stream = @fopen("ssh2.sftp://" . self::$authent . SFTP_REMOTE . $_file, 'r');
  257. $contents = stream_get_contents($stream);
  258. file_put_contents(DIR_TEMP . $_file, $contents);
  259. @fclose($stream);
  260. }
  261. }