Advertisement
Guest User

Untitled

a guest
Jul 19th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.41 KB | None | 0 0
  1. <?php
  2.  
  3. class FileShardingCommand
  4. extends EConsoleCommand
  5. {
  6. public function actionIndex()
  7. {
  8. static $oldId = null;
  9. while (true)
  10. {
  11. $additionalCond = '';
  12.  
  13. if ($oldId)
  14. {
  15. $additionalCond = " AND id > $oldId";
  16. }
  17.  
  18. $sql = <<<SQL
  19. SELECT * FROM tbl_file WHERE migration_status is null or migration_status = '' $additionalCond;
  20. SQL;
  21. $file = File::model()->findBySql($sql);
  22.  
  23.  
  24. $oldId = $file->id;
  25.  
  26. $this->_log("Took file $file->id");
  27.  
  28. if (!$file)
  29. {
  30. $this->_log('Done.');
  31. exit;
  32. }
  33.  
  34. $this->_log("Took file $file->id");
  35.  
  36.  
  37. $oldFilePath = $file->getPathname();
  38.  
  39. $transaction = \Yii::app()->db->beginTransaction();
  40.  
  41. try
  42. {
  43. $fileName = $this->getFileName($file->id);
  44. $filePath = $this->getFilePath($fileName);
  45.  
  46. if ($newFilePath = $this->saveFile($file, $filePath))
  47. {
  48. $file->prepareUpdateList()
  49. ->setPlainField('migration_status', 'done')
  50. ->setPlainField('spec', $this->makeSpec($newFilePath))
  51. ->apply();
  52.  
  53. $transaction->commit();
  54.  
  55. $this->_log("Saved to: $newFilePath");
  56. }
  57. else
  58. {
  59. $this->_log('Skip file.');
  60. $transaction->commit();
  61. continue;
  62. }
  63.  
  64. if ($tmp = str_replace('.' . pathinfo($oldFilePath)['extension'], '', $oldFilePath))
  65. {
  66. @unlink($tmp);
  67.  
  68. $this->_log("Unlinked tmp file: $tmp");
  69. }
  70.  
  71. unlink($oldFilePath);
  72.  
  73. $this->_log("Unlinked old file: $oldFilePath");
  74. }
  75. catch (Throwable $e)
  76. {
  77. $transaction->rollback();
  78. throw $e;
  79. }
  80. }
  81. }
  82.  
  83. public function makeSpec(string $newFilePath): string
  84. {
  85. return str_replace(\Yii::app()->env->get(\env\files_path), 'file:%files_path%', $newFilePath);
  86. }
  87.  
  88. public function getFileName(int $id): string
  89. {
  90. $id = (string)$id;
  91.  
  92. $idLength = strlen($id);
  93. $fileNameLength = 12;
  94.  
  95. $zeroNum = $fileNameLength - $idLength;
  96.  
  97. if (0 === $zeroNum)
  98. {
  99. return strrev($id);
  100. }
  101.  
  102. return strrev(str_repeat("0", $zeroNum) . $id);
  103. }
  104.  
  105. public function getFilePath(string $fileName): string
  106. {
  107. return \Yii::app()->env->get(\env\files_path) . DIRECTORY_SEPARATOR .
  108. substr($fileName, 0, 3) . DIRECTORY_SEPARATOR .
  109. substr($fileName, 3, 3) . DIRECTORY_SEPARATOR .
  110. substr($fileName, 6, 3) . DIRECTORY_SEPARATOR .
  111. substr($fileName, 9, 3);
  112. }
  113.  
  114.  
  115. /**
  116. * @param File $file
  117. * @param string $newFilePath
  118. * @return bool|string
  119. */
  120. public function saveFile(File $file, string $newFilePath)
  121. {
  122. $oldFilePath = $file->getPathname();
  123.  
  124. if (!file_exists($oldFilePath))
  125. {
  126. $file->prepareUpdateList()
  127. ->setPlainField('migration_status', 'error')
  128. ->apply();
  129.  
  130. return false;
  131. }
  132.  
  133. $oldHash = hash_file('md5', $file->getHandler()->getPathname());
  134.  
  135.  
  136. if (!is_dir($newFilePath) && !mkdir($newFilePath, '0777', true))
  137. {
  138. throw new RuntimeException("не удалось создать создать каталог файл $newFilePath");
  139. }
  140.  
  141. $newFilePath = $newFilePath . DIRECTORY_SEPARATOR . $this->getFileNameToSave($file);
  142.  
  143. if (!copy($oldFilePath, $newFilePath))
  144. {
  145. throw new RuntimeException('не скопировалось');
  146. }
  147.  
  148. if (hash_file('md5', $newFilePath) !== $oldHash)
  149. {
  150. throw new RuntimeException('хэш не совпадает у файла #' . $file->id);
  151. }
  152.  
  153. return $newFilePath;
  154. }
  155.  
  156. public function getFileNameToSave(File $file)
  157. {
  158. $nameArray = explode('/', $file->getPathname());
  159. return array_pop($nameArray);
  160. }
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement