StoreFileOp.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <?php
  2. /**
  3. * Helper class for representing operations with transaction support.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. * http://www.gnu.org/copyleft/gpl.html
  19. *
  20. * @file
  21. * @ingroup FileBackend
  22. */
  23. use Wikimedia\AtEase\AtEase;
  24. /**
  25. * Store a file into the backend from a file on the file system.
  26. * Parameters for this operation are outlined in FileBackend::doOperations().
  27. */
  28. class StoreFileOp extends FileOp {
  29. protected function allowedParams() {
  30. return [
  31. [ 'src', 'dst' ],
  32. [ 'overwrite', 'overwriteSame', 'headers' ],
  33. [ 'src', 'dst' ]
  34. ];
  35. }
  36. protected function doPrecheck( array &$predicates ) {
  37. $status = StatusValue::newGood();
  38. // Check if the source file exists in the file system and is not too big
  39. if ( !is_file( $this->params['src'] ) ) {
  40. $status->fatal( 'backend-fail-notexists', $this->params['src'] );
  41. return $status;
  42. }
  43. // Check if the source file is too big
  44. $maxBytes = $this->backend->maxFileSizeInternal();
  45. if ( filesize( $this->params['src'] ) > $maxBytes ) {
  46. $status->fatal( 'backend-fail-maxsize', $this->params['dst'], $maxBytes );
  47. return $status;
  48. }
  49. // Check if an incompatible destination file exists
  50. $status->merge( $this->precheckDestExistence( $predicates ) );
  51. $this->params['dstExists'] = $this->destExists; // see FileBackendStore::setFileCache()
  52. if ( $status->isOK() ) {
  53. // Update file existence predicates
  54. $predicates['exists'][$this->params['dst']] = true;
  55. $predicates['sha1'][$this->params['dst']] = $this->sourceSha1;
  56. }
  57. return $status; // safe to call attempt()
  58. }
  59. protected function doAttempt() {
  60. if ( $this->overwriteSameCase ) {
  61. $status = StatusValue::newGood(); // nothing to do
  62. } else {
  63. // Store the file at the destination
  64. $status = $this->backend->storeInternal( $this->setFlags( $this->params ) );
  65. }
  66. return $status;
  67. }
  68. protected function getSourceSha1Base36() {
  69. AtEase::suppressWarnings();
  70. $hash = sha1_file( $this->params['src'] );
  71. AtEase::restoreWarnings();
  72. if ( $hash !== false ) {
  73. $hash = Wikimedia\base_convert( $hash, 16, 36, 31 );
  74. }
  75. return $hash;
  76. }
  77. public function storagePathsChanged() {
  78. return [ $this->params['dst'] ];
  79. }
  80. }