ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
ILIAS\FileUpload\FileUploadImpl Class Reference

Class FileUploadImpl. More...

+ Inheritance diagram for ILIAS\FileUpload\FileUploadImpl:
+ Collaboration diagram for ILIAS\FileUpload\FileUploadImpl:

Public Member Functions

 __construct (private PreProcessorManager $processorManager, private Filesystems $filesystems, private GlobalHttpState $globalHttpState)
 FileUploadImpl constructor. More...
 
 moveOneFileTo (UploadResult $uploadResult, string $destination, int $location=Location::STORAGE, string $file_name='', bool $override_existing=false)
 Moves a single File (the attributes, metadata and upload-status of which are contained in UploadResult) to the given destination.The destination is a relative path which refers to the path of the location.
Parameters
UploadResult$uploadResultWhich upload result do you want to move?
string$destinationWhere do you want to move the file?
int$locationLocation::[STORAGE|WEB|CUSTOMIZING]
string$file_nameDo you want to rename the file?
bool$override_existingOverride existing file with same name
More...
 
 moveFilesTo (string $destination, int $location=Location::STORAGE)
 @inheritDoc More...
 
 uploadSizeLimit ()
 @inheritDoc More...
 
 register (PreProcessor $preProcessor)
 @inheritDoc More...
 
 process ()
 @inheritDoc More...
 
 getResults ()
 @inheritDoc More...
 
 hasUploads ()
 @inheritDoc More...
 
 hasBeenProcessed ()
 Return (bool)true if the current upload has already been processed. More...
 
 moveFilesTo (string $destination, int $location=Location::STORAGE)
 Moves all uploaded files to the given destination after the processors had processed the files. More...
 
 moveOneFileTo (UploadResult $uploadResult, string $destination, int $location=Location::STORAGE, string $file_name='', bool $override_existing=false)
 Moves a single File (the attributes, metadata and upload-status of which are contained in UploadResult) to the given destination. More...
 
 uploadSizeLimit ()
 Returns the current upload size limit in bytes. More...
 
 register (PreProcessor $preProcessor)
 Register a new preprocessor instance. More...
 
 process ()
 Invokes all preprocessors for each uploaded file in the sequence they got registered. More...
 
 getResults ()
 Returns the results of the processing and moving operation of the uploaded files. More...
 
 hasUploads ()
 Return (bool)true if one ore more file-uploads are in the current request, (bool)false if not. More...
 
 hasBeenProcessed ()
 Return (bool)true if the current upload has already been processed. More...
 

Protected Member Functions

 flattenUploadedFiles (array $uploadedFiles)
 

Private Member Functions

 hardRemoveUpload (string $identifier, ProcessingStatus $status)
 @description This is the very last thing we can do if a preprocessor DENIEs an upload. More...
 
 regenerateUploadResultWithPath (UploadResult $result, string $path)
 Generate an exact copy of the result with the given path. More...
 
 regenerateUploadResultWithCopyError (UploadResult $result, string $errorReason)
 Creates a clone of the given result and set the status to rejected with the passed error message. More...
 
 selectFilesystem (int $location)
 Selects the correct filesystem by the given Location constant. More...
 
 rejectFailedUpload (Metadata $metadata)
 Reject a failed upload with the given metadata. More...
 

Private Attributes

bool $processed = false
 
bool $moved = false
 
array $uploadResult = []
 
array $rejectedUploadResult = []
 
array $uploadStreams = null
 

Detailed Description

Class FileUploadImpl.

Author
Nicolas Schäfli ns@st.nosp@m.uder.nosp@m.-raim.nosp@m.ann..nosp@m.ch
Since
5.3
Version
1.0.0

Definition at line 46 of file FileUploadImpl.php.

Constructor & Destructor Documentation

◆ __construct()

ILIAS\FileUpload\FileUploadImpl::__construct ( private PreProcessorManager  $processorManager,
private Filesystems  $filesystems,
private GlobalHttpState  $globalHttpState 
)

FileUploadImpl constructor.

Parameters
PreProcessorManager$processorManagerThe processor manager which should be used.
Filesystems$filesystemsThe Filesystems implementation which should be used.
GlobalHttpState$globalHttpStateThe http implementation which should be used to detect the uploaded files.

Definition at line 73 of file FileUploadImpl.php.

74 {
75 }

Member Function Documentation

◆ flattenUploadedFiles()

ILIAS\FileUpload\FileUploadImpl::flattenUploadedFiles ( array  $uploadedFiles)
protected

Definition at line 349 of file FileUploadImpl.php.

349 : array
350 {
351 $recursiveIterator = new RecursiveIteratorIterator(
352 new RecursiveArrayIterator(
353 $uploadedFiles,
354 RecursiveArrayIterator::CHILD_ARRAYS_ONLY
355 ),
356 RecursiveIteratorIterator::LEAVES_ONLY
357 );
358
359 return iterator_to_array($recursiveIterator, false);
360 }

Referenced by ILIAS\FileUpload\FileUploadImpl\hasUploads(), and ILIAS\FileUpload\FileUploadImpl\process().

+ Here is the caller graph for this function:

◆ getResults()

ILIAS\FileUpload\FileUploadImpl::getResults ( )

@inheritDoc

Implements ILIAS\FileUpload\FileUpload.

Definition at line 324 of file FileUploadImpl.php.

324 : array
325 {
326 if ($this->processed) {
327 return array_merge($this->uploadResult, $this->rejectedUploadResult);
328 }
329
330 throw new IllegalStateException('Can not fetch results without processing the uploads.');
331 }

◆ hardRemoveUpload()

ILIAS\FileUpload\FileUploadImpl::hardRemoveUpload ( string  $identifier,
ProcessingStatus  $status 
)
private

@description This is the very last thing we can do if a preprocessor DENIEs an upload.

This is a hard removal, not beautiful, but it works.

Definition at line 81 of file FileUploadImpl.php.

81 : never
82 {
83 // we delete the file from the temporary directory and remove it from the global $_FILES array
84 $file_stream = $this->uploadStreams[$identifier];
85 $uri = $file_stream->getMetadata('uri');
86 $file_stream->close();
87 unlink($uri);
88 unset($this->uploadStreams[$identifier]);
89 unset($_FILES[$identifier]);
90 throw new IllegalStateException($status->getMessage());
91 }

References ILIAS\FileUpload\DTO\ProcessingStatus\getMessage().

Referenced by ILIAS\FileUpload\FileUploadImpl\process().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hasBeenProcessed()

ILIAS\FileUpload\FileUploadImpl::hasBeenProcessed ( )

Return (bool)true if the current upload has already been processed.

Since
5.3

Implements ILIAS\FileUpload\FileUpload.

Definition at line 363 of file FileUploadImpl.php.

363 : bool
364 {
365 return $this->processed;
366 }

References ILIAS\FileUpload\FileUploadImpl\$processed.

◆ hasUploads()

ILIAS\FileUpload\FileUploadImpl::hasUploads ( )

@inheritDoc

Implements ILIAS\FileUpload\FileUpload.

Definition at line 337 of file FileUploadImpl.php.

337 : bool
338 {
339 if ($this->moved) {
340 return false;
341 }
342
343 $uploadedFiles = $this->flattenUploadedFiles($this->globalHttpState->request()->getUploadedFiles());
344
345 return ($uploadedFiles !== []);
346 }
flattenUploadedFiles(array $uploadedFiles)

References ILIAS\FileUpload\FileUploadImpl\flattenUploadedFiles().

+ Here is the call graph for this function:

◆ moveFilesTo()

ILIAS\FileUpload\FileUploadImpl::moveFilesTo ( string  $destination,
int  $location = Location::STORAGE 
)

@inheritDoc

Implements ILIAS\FileUpload\FileUpload.

Definition at line 126 of file FileUploadImpl.php.

126 : void
127 {
128 if (!$this->processed) {
129 throw new \RuntimeException('Can not move unprocessed files.');
130 }
131
132 if ($this->moved) {
133 throw new \RuntimeException('Can not move the files a second time.');
134 }
135
136 $filesystem = $this->selectFilesystem($location);
137 $tempResults = [];
138
139 foreach ($this->uploadResult as $key => $uploadResult) {
140 if ($uploadResult->getStatus()->getCode() === ProcessingStatus::REJECTED) {
141 continue;
142 }
143
144 try {
145 $path = $destination . '/' . $uploadResult->getName();
146 $filesystem->writeStream($path, Streams::ofPsr7Stream($this->uploadStreams[$key]));
147 $tempResults[] = $this->regenerateUploadResultWithPath($uploadResult, $path);
148 } catch (IOException $ex) {
149 $this->regenerateUploadResultWithCopyError($uploadResult, $ex->getMessage());
150 }
151 }
152
153 $this->uploadResult = $tempResults;
154 $this->uploadStreams = null;
155 $this->moved = true;
156 }
$location
Definition: buildRTE.php:22
regenerateUploadResultWithCopyError(UploadResult $result, string $errorReason)
Creates a clone of the given result and set the status to rejected with the passed error message.
selectFilesystem(int $location)
Selects the correct filesystem by the given Location constant.
regenerateUploadResultWithPath(UploadResult $result, string $path)
Generate an exact copy of the result with the given path.
static ofPsr7Stream(StreamInterface $stream)
Create a FileStream from a Psr7 compliant stream.
Definition: Streams.php:113
$path
Definition: ltiservices.php:30

References $location, $path, ILIAS\FileUpload\FileUploadImpl\$uploadResult, ILIAS\Filesystem\Stream\Streams\ofPsr7Stream(), ILIAS\FileUpload\FileUploadImpl\regenerateUploadResultWithCopyError(), ILIAS\FileUpload\FileUploadImpl\regenerateUploadResultWithPath(), ILIAS\FileUpload\DTO\ProcessingStatus\REJECTED, and ILIAS\FileUpload\FileUploadImpl\selectFilesystem().

+ Here is the call graph for this function:

◆ moveOneFileTo()

ILIAS\FileUpload\FileUploadImpl::moveOneFileTo ( UploadResult  $uploadResult,
string  $destination,
int  $location = Location::STORAGE,
string  $file_name = '',
bool  $override_existing = false 
)

Moves a single File (the attributes, metadata and upload-status of which are contained in UploadResult) to the given destination.The destination is a relative path which refers to the path of the location.

Parameters
UploadResult$uploadResultWhich upload result do you want to move?
string$destinationWhere do you want to move the file?
int$locationLocation::[STORAGE|WEB|CUSTOMIZING]
string$file_nameDo you want to rename the file?
bool$override_existingOverride existing file with same name

Implements ILIAS\FileUpload\FileUpload.

Definition at line 96 of file FileUploadImpl.php.

96 : bool
97 {
98 if (!$this->processed) {
99 throw new \RuntimeException('Can not move unprocessed files.');
100 }
101 $filesystem = $this->selectFilesystem($location);
102 $tempResults = [];
103
104 if ($uploadResult->getStatus()->getCode() === ProcessingStatus::REJECTED) {
105 return false;
106 }
107
108 try {
109 $path = rtrim($destination, "/") . '/' . ($file_name === "" ? $uploadResult->getName() : $file_name);
110 if ($override_existing && $filesystem->has($path)) {
111 $filesystem->delete($path);
112 }
113 $filesystem->writeStream($path, Streams::ofPsr7Stream($this->uploadStreams[$uploadResult->getPath()]));
114 $tempResults[] = $this->regenerateUploadResultWithPath($uploadResult, $path);
115 } catch (IOException $ex) {
116 $this->regenerateUploadResultWithCopyError($uploadResult, $ex->getMessage());
117 }
118
119 return true;
120 }

References $location, $path, ILIAS\FileUpload\FileUploadImpl\$uploadResult, ILIAS\Filesystem\Stream\Streams\ofPsr7Stream(), ILIAS\FileUpload\FileUploadImpl\regenerateUploadResultWithCopyError(), ILIAS\FileUpload\FileUploadImpl\regenerateUploadResultWithPath(), ILIAS\FileUpload\DTO\ProcessingStatus\REJECTED, and ILIAS\FileUpload\FileUploadImpl\selectFilesystem().

+ Here is the call graph for this function:

◆ process()

ILIAS\FileUpload\FileUploadImpl::process ( )

@inheritDoc

Implements ILIAS\FileUpload\FileUpload.

Definition at line 247 of file FileUploadImpl.php.

247 : void
248 {
249 if ($this->processed) {
250 throw new IllegalStateException('Can not reprocess the uploaded files.');
251 }
252
253 $uploadedFiles = $this->globalHttpState->request()->getUploadedFiles();
254 $collectFilesFromNestedFields = $this->flattenUploadedFiles($uploadedFiles);
255 foreach ($collectFilesFromNestedFields as $file) {
256 $metadata = new Metadata($file->getClientFilename(), $file->getSize(), $file->getClientMediaType());
257 try {
258 $stream = Streams::ofPsr7Stream($file->getStream());
259 } catch (\RuntimeException) {
260 $this->rejectFailedUpload($metadata);
261 continue;
262 }
263
264 // we take the temporary file name as an identifier as it is the only unique attribute.
265 $identifier = $file->getStream()->getMetadata('uri');
266
267 $identifier = is_array($identifier) ? '' : $identifier;
268
269 $this->uploadStreams[$identifier] = $stream;
270
271 if ($file->getError() === UPLOAD_ERR_OK) {
272 $processingResult = $this->processorManager->process($stream, $metadata);
273
274 // we do discard if the result is a DENIED that there is no further pissibility to process the file.
275 if ($processingResult->getCode() === ProcessingStatus::DENIED) {
276 $this->hardRemoveUpload($identifier, $processingResult);
277 continue;
278 }
279
280 $result = new UploadResult(
281 $metadata->getFilename(),
282 $metadata->getUploadSize(),
283 $metadata->getMimeType(),
284 $metadata->additionalMetaData(),
285 $processingResult,
286 is_string($identifier) ? $identifier : ''
287 );
288 $this->uploadResult[$identifier] = $result;
289 } else {
290 $this->rejectFailedUpload($metadata);
291 }
292 }
293
294 $this->processed = true;
295 }
hardRemoveUpload(string $identifier, ProcessingStatus $status)
@description This is the very last thing we can do if a preprocessor DENIEs an upload.
rejectFailedUpload(Metadata $metadata)
Reject a failed upload with the given metadata.

References ILIAS\FileUpload\DTO\ProcessingStatus\DENIED, ILIAS\FileUpload\FileUploadImpl\flattenUploadedFiles(), ILIAS\FileUpload\FileUploadImpl\hardRemoveUpload(), ILIAS\Filesystem\Stream\Streams\ofPsr7Stream(), and ILIAS\FileUpload\FileUploadImpl\rejectFailedUpload().

+ Here is the call graph for this function:

◆ regenerateUploadResultWithCopyError()

ILIAS\FileUpload\FileUploadImpl::regenerateUploadResultWithCopyError ( UploadResult  $result,
string  $errorReason 
)
private

Creates a clone of the given result and set the status to rejected with the passed error message.

Parameters
UploadResult$resultThe result which should be cloned.
string$errorReasonThe reason why the error occurred.
Returns
UploadResult The newly cloned rejected result.

Definition at line 188 of file FileUploadImpl.php.

188 : UploadResult
189 {
190 return new UploadResult(
191 $result->getName(),
192 $result->getSize(),
193 $result->getMimeType(),
194 $result->getMetaData(),
195 new ProcessingStatus(ProcessingStatus::REJECTED, $errorReason),
196 ''
197 );
198 }

References ILIAS\FileUpload\DTO\UploadResult\getMetaData(), ILIAS\FileUpload\DTO\UploadResult\getMimeType(), ILIAS\FileUpload\DTO\UploadResult\getName(), ILIAS\FileUpload\DTO\UploadResult\getSize(), and ILIAS\FileUpload\DTO\ProcessingStatus\REJECTED.

Referenced by ILIAS\FileUpload\FileUploadImpl\moveFilesTo(), and ILIAS\FileUpload\FileUploadImpl\moveOneFileTo().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ regenerateUploadResultWithPath()

ILIAS\FileUpload\FileUploadImpl::regenerateUploadResultWithPath ( UploadResult  $result,
string  $path 
)
private

Generate an exact copy of the result with the given path.

Parameters
UploadResult$resultThe result which should be cloned.
string$pathThe path which should be set on the result clone.
Returns
UploadResult The cloned result with the given path.

Definition at line 167 of file FileUploadImpl.php.

167 : UploadResult
168 {
169 return new UploadResult(
170 $result->getName(),
171 $result->getSize(),
172 $result->getMimeType(),
173 $result->getMetaData(),
174 $result->getStatus(),
175 $path
176 );
177 }

References $path, ILIAS\FileUpload\DTO\UploadResult\getMetaData(), ILIAS\FileUpload\DTO\UploadResult\getMimeType(), ILIAS\FileUpload\DTO\UploadResult\getName(), ILIAS\FileUpload\DTO\UploadResult\getSize(), and ILIAS\FileUpload\DTO\UploadResult\getStatus().

Referenced by ILIAS\FileUpload\FileUploadImpl\moveFilesTo(), and ILIAS\FileUpload\FileUploadImpl\moveOneFileTo().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ register()

ILIAS\FileUpload\FileUploadImpl::register ( PreProcessor  $preProcessor)

@inheritDoc

Implements ILIAS\FileUpload\FileUpload.

Definition at line 234 of file FileUploadImpl.php.

234 : void
235 {
236 if (!$this->processed) {
237 $this->processorManager->with($preProcessor);
238 } else {
239 throw new IllegalStateException('Can not register processor after the upload was processed.');
240 }
241 }

◆ rejectFailedUpload()

ILIAS\FileUpload\FileUploadImpl::rejectFailedUpload ( Metadata  $metadata)
private

Reject a failed upload with the given metadata.

Parameters
Metadata$metadataThe metadata used to create the rejected result.

Definition at line 303 of file FileUploadImpl.php.

303 : void
304 {
305 //reject failed upload
306 $processingStatus = new ProcessingStatus(ProcessingStatus::REJECTED, 'Upload failed');
307 $extraMetadata = new ImmutableMapWrapper(new EntryLockingStringMap());
308 $result = new UploadResult(
309 $metadata->getFilename(),
310 $metadata->getUploadSize(),
311 $metadata->getMimeType(),
312 $extraMetadata,
313 $processingStatus,
314 ''
315 );
316
317 $this->rejectedUploadResult[] = $result;
318 }

References ILIAS\FileUpload\DTO\Metadata\getFilename(), ILIAS\FileUpload\DTO\Metadata\getMimeType(), ILIAS\FileUpload\DTO\Metadata\getUploadSize(), and ILIAS\FileUpload\DTO\ProcessingStatus\REJECTED.

Referenced by ILIAS\FileUpload\FileUploadImpl\process().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ selectFilesystem()

ILIAS\FileUpload\FileUploadImpl::selectFilesystem ( int  $location)
private

Selects the correct filesystem by the given Location constant.

Parameters
int$locationThe storage location constant defined within the Location interface.
See also
Location
Exceptions

InvalidArgumentException Thrown if the location is not a valid Location constant.

Definition at line 210 of file FileUploadImpl.php.

210 : Filesystem
211 {
212 return match ($location) {
213 Location::CUSTOMIZING => $this->filesystems->customizing(),
214 Location::STORAGE => $this->filesystems->storage(),
215 Location::WEB => $this->filesystems->web(),
216 Location::TEMPORARY => $this->filesystems->temp(),
217 default => throw new \InvalidArgumentException("No filesystem found for location code \"$location\""),
218 };
219 }
const TEMPORARY
The ILIAS temporary directory.
Definition: Location.php:53
const CUSTOMIZING
The filesystem within the web root where all the skins and plugins are saved.
Definition: Location.php:48
const WEB
The filesystem within the ilias web root.
Definition: Location.php:38
const STORAGE
The filesystem outside of the ilias web root.
Definition: Location.php:43
static filesystems()
Returns the loaded filesystems.

References $location, ILIAS\FileUpload\Location\CUSTOMIZING, ILIAS\Filesystem\filesystems(), ILIAS\FileUpload\Location\STORAGE, ILIAS\FileUpload\Location\TEMPORARY, and ILIAS\FileUpload\Location\WEB.

Referenced by ILIAS\FileUpload\FileUploadImpl\moveFilesTo(), and ILIAS\FileUpload\FileUploadImpl\moveOneFileTo().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ uploadSizeLimit()

ILIAS\FileUpload\FileUploadImpl::uploadSizeLimit ( )

@inheritDoc

Implements ILIAS\FileUpload\FileUpload.

Definition at line 225 of file FileUploadImpl.php.

225 : int
226 {
228 }
static getPhpUploadSizeLimitInBytes()

References ilFileUtils\getPhpUploadSizeLimitInBytes().

+ Here is the call graph for this function:

Field Documentation

◆ $moved

bool ILIAS\FileUpload\FileUploadImpl::$moved = false
private

Definition at line 49 of file FileUploadImpl.php.

◆ $processed

bool ILIAS\FileUpload\FileUploadImpl::$processed = false
private

Definition at line 48 of file FileUploadImpl.php.

Referenced by ILIAS\FileUpload\FileUploadImpl\hasBeenProcessed().

◆ $rejectedUploadResult

array ILIAS\FileUpload\FileUploadImpl::$rejectedUploadResult = []
private

Definition at line 57 of file FileUploadImpl.php.

◆ $uploadResult

UploadResult[] ILIAS\FileUpload\FileUploadImpl::$uploadResult = []
private

◆ $uploadStreams

array ILIAS\FileUpload\FileUploadImpl::$uploadStreams = null
private

Definition at line 61 of file FileUploadImpl.php.


The documentation for this class was generated from the following file: