26use Wikimedia\AtEase\AtEase;
27use Wikimedia\Timestamp\ConvertibleTimestamp;
54 if ( $dst ===
null ) {
55 $status->fatal(
'backend-fail-invalidpath',
$params[
'dst'] );
60 $this->files[$dst] = [
62 'mtime' => ConvertibleTimestamp::convert( TS_MW, time() )
72 if ( $dst ===
null ) {
73 $status->fatal(
'backend-fail-invalidpath',
$params[
'dst'] );
78 AtEase::suppressWarnings();
79 $data = file_get_contents(
$params[
'src'] );
80 AtEase::restoreWarnings();
81 if ( $data ===
false ) {
82 $status->fatal(
'backend-fail-store',
$params[
'src'],
$params[
'dst'] );
87 $this->files[$dst] = [
89 'mtime' => ConvertibleTimestamp::convert( TS_MW, time() )
99 if ( $src ===
null ) {
100 $status->fatal(
'backend-fail-invalidpath',
$params[
'src'] );
106 if ( $dst ===
null ) {
107 $status->fatal(
'backend-fail-invalidpath',
$params[
'dst'] );
112 if ( !isset( $this->files[$src] ) ) {
113 if ( empty(
$params[
'ignoreMissingSource'] ) ) {
114 $status->fatal(
'backend-fail-copy',
$params[
'src'],
$params[
'dst'] );
120 $this->files[$dst] = [
121 'data' => $this->files[$src][
'data'],
122 'mtime' => ConvertibleTimestamp::convert( TS_MW, time() )
132 if ( $src ===
null ) {
133 $status->fatal(
'backend-fail-invalidpath',
$params[
'src'] );
139 if ( $dst ===
null ) {
140 $status->fatal(
'backend-fail-invalidpath',
$params[
'dst'] );
145 if ( !isset( $this->files[$src] ) ) {
146 if ( empty(
$params[
'ignoreMissingSource'] ) ) {
147 $status->fatal(
'backend-fail-move',
$params[
'src'],
$params[
'dst'] );
153 $this->files[$dst] = $this->files[$src];
154 unset( $this->files[$src] );
155 $this->files[$dst][
'mtime'] = ConvertibleTimestamp::convert( TS_MW, time() );
164 if ( $src ===
null ) {
165 $status->fatal(
'backend-fail-invalidpath',
$params[
'src'] );
170 if ( !isset( $this->files[$src] ) ) {
171 if ( empty(
$params[
'ignoreMissingSource'] ) ) {
172 $status->fatal(
'backend-fail-delete',
$params[
'src'] );
178 unset( $this->files[$src] );
185 if ( $src ===
null ) {
186 return self::RES_ERROR;
189 if ( isset( $this->files[$src] ) ) {
191 'mtime' => $this->files[$src][
'mtime'],
192 'size' => strlen( $this->files[$src][
'data'] ),
196 return self::RES_ABSENT;
201 foreach (
$params[
'srcs'] as $srcPath ) {
203 if ( $src ===
null ) {
204 $fsFile = self::RES_ERROR;
205 } elseif ( !isset( $this->files[$src] ) ) {
206 $fsFile = self::RES_ABSENT;
210 $fsFile = $this->tmpFileFactory->newTempFSFile(
'localcopy_', $ext );
212 $bytes = file_put_contents( $fsFile->getPath(), $this->files[$src][
'data'] );
213 if ( $bytes !== strlen( $this->files[$src][
'data'] ) ) {
214 $fsFile = self::RES_ERROR;
218 $tmpFiles[$srcPath] = $fsFile;
225 $prefix = rtrim(
"$container/$dir",
'/' ) .
'/';
226 foreach ( $this->files as
$path => $data ) {
227 if ( strpos(
$path, $prefix ) === 0 ) {
237 $prefix = rtrim(
"$container/$dir",
'/' ) .
'/';
238 $prefixLen = strlen( $prefix );
239 foreach ( $this->files as
$path => $data ) {
240 if ( strpos(
$path, $prefix ) === 0 ) {
241 $relPath = substr(
$path, $prefixLen );
242 if ( $relPath ===
false ) {
244 } elseif ( strpos( $relPath,
'/' ) ===
false ) {
247 $parts = array_slice( explode(
'/', $relPath ), 0, -1 );
248 if ( !empty(
$params[
'topOnly'] ) ) {
249 $dirs[$parts[0]] = 1;
252 foreach ( $parts as $part ) {
253 $dir = ( $current ===
'' ) ? $part :
"$current/$part";
261 return array_keys( $dirs );
266 $prefix = rtrim(
"$container/$dir",
'/' ) .
'/';
267 $prefixLen = strlen( $prefix );
268 foreach ( $this->files as
$path => $data ) {
269 if ( strpos(
$path, $prefix ) === 0 ) {
270 $relPath = substr(
$path, $prefixLen );
271 if ( $relPath ===
false ) {
273 } elseif ( !empty(
$params[
'topOnly'] ) && strpos( $relPath,
'/' ) !==
false ) {
295 if ( $relPath ===
null ) {
299 return ( $relPath !==
'' ) ?
"$fullCont/$relPath" : $fullCont;
304class_alias( MemoryFileBackend::class,
'MemoryFileBackend' );
array $params
The job parameters.