Index: branches/FileBackend/phase3/includes/filerepo/file/File.php |
— | — | @@ -1584,7 +1584,7 @@ |
1585 | 1585 | wfDeprecated( __METHOD__, '1.19' ); |
1586 | 1586 | |
1587 | 1587 | $fsFile = new FSFile( $path ); |
1588 | | - return $fsFile->sha1Base36(); |
| 1588 | + return $fsFile->getSha1Base36(); |
1589 | 1589 | } |
1590 | 1590 | |
1591 | 1591 | /** |
Index: branches/FileBackend/phase3/includes/filerepo/file/FSFile.php |
— | — | @@ -114,7 +114,7 @@ |
115 | 115 | $info = $this->extractImageSizeInfo( $gis ) + $info; |
116 | 116 | } |
117 | 117 | } |
118 | | - $info['sha1'] = $this->sha1Base36(); |
| 118 | + $info['sha1'] = $this->getSha1Base36(); |
119 | 119 | |
120 | 120 | wfDebug(__METHOD__.": $this->path loaded, {$info['size']} bytes, {$info['mime']}.\n"); |
121 | 121 | } else { |
— | — | @@ -165,7 +165,7 @@ |
166 | 166 | * |
167 | 167 | * @return false|string False on failure |
168 | 168 | */ |
169 | | - public function sha1Base36() { |
| 169 | + public function getSha1Base36() { |
170 | 170 | wfProfileIn( __METHOD__ ); |
171 | 171 | |
172 | 172 | wfSuppressWarnings(); |
— | — | @@ -206,6 +206,6 @@ |
207 | 207 | */ |
208 | 208 | static function getSha1Base36FromPath( $path ) { |
209 | 209 | $fsFile = new self( $path ); |
210 | | - return $fsFile->sha1Base36(); |
| 210 | + return $fsFile->getSha1Base36(); |
211 | 211 | } |
212 | 212 | } |
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileBackendMultiWrite.php |
— | — | @@ -16,8 +16,6 @@ |
17 | 17 | * that has the file. Special cases are listed below: |
18 | 18 | * a) getFileTimestamp() will always check only the master backend to |
19 | 19 | * avoid confusing and inconsistent results. |
20 | | - * b) getFileHash() will always check only the master backend to keep |
21 | | - * the result format consistent. |
22 | 20 | * |
23 | 21 | * All write operations are performed on all backends. |
24 | 22 | * If an operation fails on one backend it will be rolled back from the others. |
— | — | @@ -62,106 +60,87 @@ |
63 | 61 | } |
64 | 62 | |
65 | 63 | final public function doOperations( array $ops ) { |
66 | | - $status = Status::newGood( array() ); |
| 64 | + $status = Status::newGood(); |
67 | 65 | |
68 | 66 | $performOps = array(); // list of FileOp objects |
69 | | - $batchSize = count( $ops ); // each backend has this many ops |
70 | | - $filesToLock = array(); // storage paths to lock |
| 67 | + $filesLockEx = $filesLockSh = array(); // storage paths to lock |
71 | 68 | // Build up a list of FileOps. The list will have all the ops |
72 | 69 | // for one backend, then all the ops for the next, and so on. |
73 | 70 | // These batches of ops are all part of a continuous array. |
74 | 71 | // Also build up a list of files to lock... |
75 | 72 | foreach ( $this->fileBackends as $index => $backend ) { |
76 | | - $performOps = array_merge( $performOps, $backend->getOperations( $ops ) ); |
| 73 | + $backendOps = $this->substOpPaths( $ops, $backend ); |
| 74 | + $performOps = array_merge( $performOps, $backend->getOperations( $backendOps ) ); |
77 | 75 | if ( $index == 0 ) { |
78 | | - // Set $filesToLock from the first batch so we don't try to set all |
| 76 | + // Set "files to lock" from the first batch so we don't try to set all |
79 | 77 | // locks two or three times over (depending on the number of backends). |
80 | 78 | // A lock on one storage path is a lock on all the backends. |
81 | 79 | foreach ( $performOps as $index => $fileOp ) { |
82 | | - $filesToLock = array_merge( $filesToLock, $fileOp->storagePathsUsed() ); |
| 80 | + $filesLockSh = array_merge( $filesLockSh, $fileOp->storagePathsRead() ); |
| 81 | + $filesLockEx = array_merge( $filesLockEx, $fileOp->storagePathsChanged() ); |
83 | 82 | } |
| 83 | + // Lock the paths under the proxy backend's name |
| 84 | + $this->unsubstPaths( $filesLockSh ); |
| 85 | + $this->unsubstPaths( $filesLockEx ); |
84 | 86 | } |
85 | 87 | } |
86 | 88 | |
87 | 89 | // Try to lock those files for the scope of this function... |
88 | | - $scopedLock = $this->getScopedFileLocks( $filesToLock, LockManager::LOCK_EX, $status ); |
| 90 | + $scopeLockS = $this->getScopedFileLocks( $filesLockSh, LockManager::LOCK_UW, $status ); |
| 91 | + $scopeLockE = $this->getScopedFileLocks( $filesLockEx, LockManager::LOCK_EX, $status ); |
89 | 92 | if ( !$status->isOK() ) { |
90 | 93 | return $status; // abort |
91 | 94 | } |
92 | 95 | |
93 | | - $failedOps = array(); // failed ops with 'ignoreErrors' |
94 | | - $predicates = FileOp::newPredicates(); // effects of previous ops |
95 | | - // Do pre-checks for each operation; abort on failure... |
96 | | - foreach ( $performOps as $index => $fileOp ) { |
97 | | - if ( $index > 0 && ( $index % $batchSize ) == 0 ) { |
98 | | - // We are starting the op batch for another backend |
99 | | - // which is not effected by the other op batches. |
100 | | - $predicates = FileOp::newPredicates(); |
101 | | - } |
102 | | - $status->merge( $fileOp->precheck( $predicates ) ); |
103 | | - if ( !$status->isOK() ) { // operation failed? |
104 | | - if ( $fileOp->getParam( 'ignoreErrors' ) ) { |
105 | | - $failedOps[$index] = 1; // remember not to call attempt()/finish() |
106 | | - ++$status->failCount; |
107 | | - $status->success[$index] = false; |
108 | | - } else { |
109 | | - return $status; |
110 | | - } |
111 | | - } |
112 | | - } |
| 96 | + // Actually attempt the operation batch... |
| 97 | + $status->merge( $this->attemptOperations( $performOps ) ); |
113 | 98 | |
114 | | - // Attempt each operation; abort on failure... |
115 | | - foreach ( $performOps as $index => $fileOp ) { |
116 | | - if ( isset( $failedOps[$index] ) ) { |
117 | | - continue; // nothing to do |
118 | | - } |
119 | | - $status->merge( $fileOp->attempt() ); |
120 | | - if ( !$status->isOK() ) { // operation failed? |
121 | | - if ( $fileOp->getParam( 'ignoreErrors' ) ) { |
122 | | - $failedOps[$index] = 1; // remember not to call finish() |
123 | | - ++$status->failCount; |
124 | | - $status->success[$index] = false; |
125 | | - } else { |
126 | | - // Revert everything done so far and abort. |
127 | | - // Do this by reverting each previous operation in reverse order. |
128 | | - $pos = $index - 1; // last one failed; no need to revert() |
129 | | - while ( $pos >= 0 ) { |
130 | | - if ( !isset( $failedOps[$pos] ) ) { |
131 | | - $status->merge( $performOps[$pos]->revert() ); |
132 | | - } |
133 | | - $pos--; |
134 | | - } |
135 | | - return $status; |
| 99 | + return $status; |
| 100 | + } |
| 101 | + |
| 102 | + /** |
| 103 | + * Substitute the backend name in storage path parameters |
| 104 | + * for a set of operations with a that of a given backend. |
| 105 | + * |
| 106 | + * @param $ops Array List of file operation arrays |
| 107 | + * @param $backend FileBackend |
| 108 | + * @return Array |
| 109 | + */ |
| 110 | + protected function substOpPaths( array $ops, FileBackend $backend ) { |
| 111 | + $newOps = array(); // operations |
| 112 | + foreach ( $ops as $op ) { |
| 113 | + $newOp = $op; // operation |
| 114 | + foreach ( array( 'src', 'srcs', 'dst' ) as $par ) { |
| 115 | + if ( isset( $newOp[$par] ) ) { |
| 116 | + $newOp[$par] = preg_replace( |
| 117 | + '!^mwstore://' . preg_quote( $this->name ) . '/!', |
| 118 | + 'mwstore://' . $backend->getName() . '/', |
| 119 | + $newOp[$par] |
| 120 | + ); |
136 | 121 | } |
137 | 122 | } |
| 123 | + $newOps[] = $newOp; |
138 | 124 | } |
| 125 | + return $newOps; |
| 126 | + } |
139 | 127 | |
140 | | - // Finish each operation... |
141 | | - foreach ( $performOps as $index => $fileOp ) { |
142 | | - if ( isset( $failedOps[$index] ) ) { |
143 | | - continue; // nothing to do |
144 | | - } |
145 | | - $subStatus = $fileOp->finish(); |
146 | | - if ( $subStatus->isOK() ) { |
147 | | - ++$status->successCount; |
148 | | - $status->success[$index] = true; |
149 | | - } else { |
150 | | - ++$status->failCount; |
151 | | - $status->success[$index] = false; |
152 | | - } |
153 | | - $status->merge( $subStatus ); |
| 128 | + /** |
| 129 | + * Replace the backend part of storage paths with this backend's name |
| 130 | + * |
| 131 | + * @param &$paths Array |
| 132 | + * @return void |
| 133 | + */ |
| 134 | + protected function unsubstPaths( array &$paths ) { |
| 135 | + foreach ( $paths as &$path ) { |
| 136 | + $path = preg_replace( '!^mwstore://([^/]+)!', "mwstore://{$this->name}", $path ); |
154 | 137 | } |
155 | | - |
156 | | - // Make sure status is OK, despite any finish() fatals |
157 | | - $status->setResult( true, $status->value ); |
158 | | - |
159 | | - return $status; |
160 | 138 | } |
161 | 139 | |
162 | 140 | function prepare( array $params ) { |
163 | 141 | $status = Status::newGood(); |
164 | 142 | foreach ( $this->backends as $backend ) { |
165 | | - $status->merge( $backend->prepare( $params ) ); |
| 143 | + $realParams = $this->substOpPaths( $params, $backend ); |
| 144 | + $status->merge( $backend->prepare( $realParams ) ); |
166 | 145 | } |
167 | 146 | return $status; |
168 | 147 | } |
— | — | @@ -169,7 +148,8 @@ |
170 | 149 | function secure( array $params ) { |
171 | 150 | $status = Status::newGood(); |
172 | 151 | foreach ( $this->backends as $backend ) { |
173 | | - $status->merge( $backend->secure( $params ) ); |
| 152 | + $realParams = $this->substOpPaths( $params, $backend ); |
| 153 | + $status->merge( $backend->secure( $realParams ) ); |
174 | 154 | } |
175 | 155 | return $status; |
176 | 156 | } |
— | — | @@ -177,7 +157,8 @@ |
178 | 158 | function clean( array $params ) { |
179 | 159 | $status = Status::newGood(); |
180 | 160 | foreach ( $this->backends as $backend ) { |
181 | | - $status->merge( $backend->clean( $params ) ); |
| 161 | + $realParams = $this->substOpPaths( $params, $backend ); |
| 162 | + $status->merge( $backend->clean( $realParams ) ); |
182 | 163 | } |
183 | 164 | return $status; |
184 | 165 | } |
— | — | @@ -185,7 +166,8 @@ |
186 | 167 | function fileExists( array $params ) { |
187 | 168 | # Hit all backends in case of failed operations (out of sync) |
188 | 169 | foreach ( $this->backends as $backend ) { |
189 | | - if ( $backend->fileExists( $params ) ) { |
| 170 | + $realParams = $this->substOpPaths( $params, $backend ); |
| 171 | + if ( $backend->fileExists( $realParams ) ) { |
190 | 172 | return true; |
191 | 173 | } |
192 | 174 | } |
— | — | @@ -194,13 +176,15 @@ |
195 | 177 | |
196 | 178 | function getFileTimestamp( array $params ) { |
197 | 179 | // Skip non-master for consistent timestamps |
198 | | - return $this->backends[$this->masterIndex]->getFileTimestamp( $params ); |
| 180 | + $realParams = $this->substOpPaths( $params, $backend ); |
| 181 | + return $this->backends[$this->masterIndex]->getFileTimestamp( $realParams ); |
199 | 182 | } |
200 | 183 | |
201 | 184 | function getSha1Base36(array $params) { |
202 | 185 | # Hit all backends in case of failed operations (out of sync) |
203 | 186 | foreach ( $this->backends as $backend ) { |
204 | | - $hash = $backend->getSha1Base36( $params ); |
| 187 | + $realParams = $this->substOpPaths( $params, $backend ); |
| 188 | + $hash = $backend->getSha1Base36( $realParams ); |
205 | 189 | if ( $hash !== false ) { |
206 | 190 | return $hash; |
207 | 191 | } |
— | — | @@ -211,7 +195,8 @@ |
212 | 196 | function getFileProps( array $params ) { |
213 | 197 | # Hit all backends in case of failed operations (out of sync) |
214 | 198 | foreach ( $this->backends as $backend ) { |
215 | | - $props = $backend->getFileProps( $params ); |
| 199 | + $realParams = $this->substOpPaths( $params, $backend ); |
| 200 | + $props = $backend->getFileProps( $realParams ); |
216 | 201 | if ( $props !== null ) { |
217 | 202 | return $props; |
218 | 203 | } |
— | — | @@ -222,7 +207,8 @@ |
223 | 208 | function streamFile( array $params ) { |
224 | 209 | $status = Status::newGood(); |
225 | 210 | foreach ( $this->backends as $backend ) { |
226 | | - $subStatus = $backend->streamFile( $params ); |
| 211 | + $realParams = $this->substOpPaths( $params, $backend ); |
| 212 | + $subStatus = $backend->streamFile( $realParams ); |
227 | 213 | $status->merge( $subStatus ); |
228 | 214 | if ( $subStatus->isOK() ) { |
229 | 215 | // Pass isOK() despite fatals from other backends |
— | — | @@ -242,7 +228,8 @@ |
243 | 229 | function getLocalReference( array $params ) { |
244 | 230 | # Hit all backends in case of failed operations (out of sync) |
245 | 231 | foreach ( $this->backends as $backend ) { |
246 | | - $fsFile = $backend->getLocalReference( $params ); |
| 232 | + $realParams = $this->substOpPaths( $params, $backend ); |
| 233 | + $fsFile = $backend->getLocalReference( $realParams ); |
247 | 234 | if ( $fsFile ) { |
248 | 235 | return $fsFile; |
249 | 236 | } |
— | — | @@ -253,7 +240,8 @@ |
254 | 241 | function getLocalCopy( array $params ) { |
255 | 242 | # Hit all backends in case of failed operations (out of sync) |
256 | 243 | foreach ( $this->backends as $backend ) { |
257 | | - $tmpFile = $backend->getLocalCopy( $params ); |
| 244 | + $realParams = $this->substOpPaths( $params, $backend ); |
| 245 | + $tmpFile = $backend->getLocalCopy( $realParams ); |
258 | 246 | if ( $tmpFile ) { |
259 | 247 | return $tmpFile; |
260 | 248 | } |
— | — | @@ -264,7 +252,8 @@ |
265 | 253 | function getFileList( array $params ) { |
266 | 254 | foreach ( $this->backends as $index => $backend ) { |
267 | 255 | # Get results from the first backend |
268 | | - return $backend->getFileList( $params ); |
| 256 | + $realParams = $this->substOpPaths( $params, $backend ); |
| 257 | + return $backend->getFileList( $realParams ); |
269 | 258 | } |
270 | 259 | return array(); // sanity |
271 | 260 | } |
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileOp.php |
— | — | @@ -64,6 +64,14 @@ |
65 | 65 | } |
66 | 66 | |
67 | 67 | /** |
| 68 | + * Check if this operation failed precheck() or attempt() |
| 69 | + * @return type |
| 70 | + */ |
| 71 | + final public function failed() { |
| 72 | + return $this->failed; |
| 73 | + } |
| 74 | + |
| 75 | + /** |
68 | 76 | * Get a new empty predicates array for precheck() |
69 | 77 | * |
70 | 78 | * @return Array |
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php |
— | — | @@ -150,6 +150,77 @@ |
151 | 151 | } |
152 | 152 | |
153 | 153 | /** |
| 154 | + * Attempt a series of file operations. |
| 155 | + * Callers are responsible for handling file locking. |
| 156 | + * |
| 157 | + * @param $performOps Array List of FileOp operations |
| 158 | + * @return Status |
| 159 | + */ |
| 160 | + protected function attemptOperations( array $performOps ) { |
| 161 | + $status = Status::newGood(); |
| 162 | + |
| 163 | + $predicates = FileOp::newPredicates(); // account for previous op in prechecks |
| 164 | + // Do pre-checks for each operation; abort on failure... |
| 165 | + foreach ( $performOps as $index => $fileOp ) { |
| 166 | + $status->merge( $fileOp->precheck( $predicates ) ); |
| 167 | + if ( !$status->isOK() ) { // operation failed? |
| 168 | + if ( $fileOp->getParam( 'ignoreErrors' ) ) { |
| 169 | + ++$status->failCount; |
| 170 | + $status->success[$index] = false; |
| 171 | + } else { |
| 172 | + return $status; |
| 173 | + } |
| 174 | + } |
| 175 | + } |
| 176 | + |
| 177 | + // Attempt each operation; abort on failure... |
| 178 | + foreach ( $performOps as $index => $fileOp ) { |
| 179 | + if ( $fileOp->failed() ) { |
| 180 | + continue; // nothing to do |
| 181 | + } |
| 182 | + $status->merge( $fileOp->attempt() ); |
| 183 | + if ( !$status->isOK() ) { // operation failed? |
| 184 | + if ( $fileOp->getParam( 'ignoreErrors' ) ) { |
| 185 | + ++$status->failCount; |
| 186 | + $status->success[$index] = false; |
| 187 | + } else { |
| 188 | + // Revert everything done so far and abort. |
| 189 | + // Do this by reverting each previous operation in reverse order. |
| 190 | + $pos = $index - 1; // last one failed; no need to revert() |
| 191 | + while ( $pos >= 0 ) { |
| 192 | + if ( !$performOps[$pos]->failed() ) { |
| 193 | + $status->merge( $performOps[$pos]->revert() ); |
| 194 | + } |
| 195 | + $pos--; |
| 196 | + } |
| 197 | + return $status; |
| 198 | + } |
| 199 | + } |
| 200 | + } |
| 201 | + |
| 202 | + // Finish each operation... |
| 203 | + foreach ( $performOps as $index => $fileOp ) { |
| 204 | + if ( $fileOp->failed() ) { |
| 205 | + continue; // nothing to do |
| 206 | + } |
| 207 | + $subStatus = $fileOp->finish(); |
| 208 | + if ( $subStatus->isOK() ) { |
| 209 | + ++$status->successCount; |
| 210 | + $status->success[$index] = true; |
| 211 | + } else { |
| 212 | + ++$status->failCount; |
| 213 | + $status->success[$index] = false; |
| 214 | + } |
| 215 | + $status->merge( $subStatus ); |
| 216 | + } |
| 217 | + |
| 218 | + // Make sure status is OK, despite any finish() fatals |
| 219 | + $status->setResult( true, $status->value ); |
| 220 | + |
| 221 | + return $status; |
| 222 | + } |
| 223 | + |
| 224 | + /** |
154 | 225 | * Prepare a storage path for usage. This will create containers |
155 | 226 | * that don't yet exist or, on FS backends, create parent directories. |
156 | 227 | * |
— | — | @@ -461,7 +532,7 @@ |
462 | 533 | if ( !$fsFile ) { |
463 | 534 | return false; |
464 | 535 | } else { |
465 | | - return $fsFile->sha1Base36(); |
| 536 | + return $fsFile->getSha1Base36(); |
466 | 537 | } |
467 | 538 | } |
468 | 539 | |
— | — | @@ -549,84 +620,28 @@ |
550 | 621 | } |
551 | 622 | |
552 | 623 | final public function doOperations( array $ops ) { |
553 | | - $status = Status::newGood( array() ); |
| 624 | + $status = Status::newGood(); |
554 | 625 | |
555 | 626 | // Build up a list of FileOps... |
556 | 627 | $performOps = $this->getOperations( $ops ); |
557 | 628 | |
558 | 629 | // Build up a list of files to lock... |
559 | | - $filesToLock = array(); |
| 630 | + $filesLockEx = $filesLockSh = array(); |
560 | 631 | foreach ( $performOps as $index => $fileOp ) { |
561 | | - $filesToLock = array_merge( $filesToLock, $fileOp->storagePathsUsed() ); |
| 632 | + $filesLockSh = array_merge( $filesLockSh, $fileOp->storagePathsRead() ); |
| 633 | + $filesLockEx = array_merge( $filesLockEx, $fileOp->storagePathsChanged() ); |
562 | 634 | } |
563 | 635 | |
564 | 636 | // Try to lock those files for the scope of this function... |
565 | | - $scopedLock = $this->getScopedFileLocks( $filesToLock, LockManager::LOCK_EX, $status ); |
| 637 | + $scopeLockS = $this->getScopedFileLocks( $filesLockSh, LockManager::LOCK_UW, $status ); |
| 638 | + $scopeLockE = $this->getScopedFileLocks( $filesLockEx, LockManager::LOCK_EX, $status ); |
566 | 639 | if ( !$status->isOK() ) { |
567 | 640 | return $status; // abort |
568 | 641 | } |
569 | 642 | |
570 | | - $failedOps = array(); // failed ops with 'ignoreErrors' |
571 | | - $predicates = FileOp::newPredicates(); // account for previous op in prechecks |
572 | | - // Do pre-checks for each operation; abort on failure... |
573 | | - foreach ( $performOps as $index => $fileOp ) { |
574 | | - $status->merge( $fileOp->precheck( $predicates ) ); |
575 | | - if ( !$status->isOK() ) { // operation failed? |
576 | | - if ( $fileOp->getParam( 'ignoreErrors' ) ) { |
577 | | - $failedOps[$index] = 1; // remember not to call attempt()/finish() |
578 | | - ++$status->failCount; |
579 | | - $status->success[$index] = false; |
580 | | - } else { |
581 | | - return $status; |
582 | | - } |
583 | | - } |
584 | | - } |
| 643 | + // Actually attempt the operation batch... |
| 644 | + $status->merge( $this->attemptOperations( $performOps ) ); |
585 | 645 | |
586 | | - // Attempt each operation; abort on failure... |
587 | | - foreach ( $performOps as $index => $fileOp ) { |
588 | | - if ( isset( $failedOps[$index] ) ) { |
589 | | - continue; // nothing to do |
590 | | - } |
591 | | - $status->merge( $fileOp->attempt() ); |
592 | | - if ( !$status->isOK() ) { // operation failed? |
593 | | - if ( $fileOp->getParam( 'ignoreErrors' ) ) { |
594 | | - $failedOps[$index] = 1; // remember not to call finish() |
595 | | - ++$status->failCount; |
596 | | - $status->success[$index] = false; |
597 | | - } else { |
598 | | - // Revert everything done so far and abort. |
599 | | - // Do this by reverting each previous operation in reverse order. |
600 | | - $pos = $index - 1; // last one failed; no need to revert() |
601 | | - while ( $pos >= 0 ) { |
602 | | - if ( !isset( $failedOps[$pos] ) ) { |
603 | | - $status->merge( $performOps[$pos]->revert() ); |
604 | | - } |
605 | | - $pos--; |
606 | | - } |
607 | | - return $status; |
608 | | - } |
609 | | - } |
610 | | - } |
611 | | - |
612 | | - // Finish each operation... |
613 | | - foreach ( $performOps as $index => $fileOp ) { |
614 | | - if ( isset( $failedOps[$index] ) ) { |
615 | | - continue; // nothing to do |
616 | | - } |
617 | | - $subStatus = $fileOp->finish(); |
618 | | - if ( $subStatus->isOK() ) { |
619 | | - ++$status->successCount; |
620 | | - $status->success[$index] = true; |
621 | | - } else { |
622 | | - ++$status->failCount; |
623 | | - $status->success[$index] = false; |
624 | | - } |
625 | | - $status->merge( $subStatus ); |
626 | | - } |
627 | | - |
628 | | - // Make sure status is OK, despite any finish() fatals |
629 | | - $status->setResult( true, $status->value ); |
630 | | - |
631 | 646 | return $status; |
632 | 647 | } |
633 | 648 | |
Index: branches/FileBackend/phase3/includes/filerepo/FileRepo.php |
— | — | @@ -1200,7 +1200,7 @@ |
1201 | 1201 | if ( !$tmpFile ) { |
1202 | 1202 | return false; |
1203 | 1203 | } |
1204 | | - return $tmpFile->sha1Base36(); |
| 1204 | + return $tmpFile->getSha1Base36(); |
1205 | 1205 | } |
1206 | 1206 | |
1207 | 1207 | /** |