ILIAS  trunk Revision v11.0_alpha-1761-g6dbbfa7b760
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
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)
 
 uploadSizeLimit ()
 
 register (PreProcessor $preProcessor)
 
 process ()
 
 getResults ()
 
 hasUploads ()
 
 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)
 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.

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

349  : array
350  {
351  $recursiveIterator = new RecursiveIteratorIterator(
353  $uploadedFiles,
354  RecursiveArrayIterator::CHILD_ARRAYS_ONLY
355  ),
356  RecursiveIteratorIterator::LEAVES_ONLY
357  );
358 
359  return iterator_to_array($recursiveIterator, false);
360  }
+ Here is the caller graph for this function:

◆ getResults()

ILIAS\FileUpload\FileUploadImpl::getResults ( )

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

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.

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

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  }
+ 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.

References ILIAS\FileUpload\FileUploadImpl\$processed.

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

◆ hasUploads()

ILIAS\FileUpload\FileUploadImpl::hasUploads ( )

Implements ILIAS\FileUpload\FileUpload.

Definition at line 337 of file FileUploadImpl.php.

References ILIAS\FileUpload\FileUploadImpl\flattenUploadedFiles().

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)
+ Here is the call graph for this function:

◆ moveFilesTo()

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

Implements ILIAS\FileUpload\FileUpload.

Definition at line 126 of file FileUploadImpl.php.

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

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  }
regenerateUploadResultWithCopyError(UploadResult $result, string $errorReason)
Creates a clone of the given result and set the status to rejected with the passed error message...
$location
Definition: buildRTE.php:22
selectFilesystem(int $location)
Selects the correct filesystem by the given Location constant.
$path
Definition: ltiservices.php:29
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
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
+ 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.

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

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  }
regenerateUploadResultWithCopyError(UploadResult $result, string $errorReason)
Creates a clone of the given result and set the status to rejected with the passed error message...
$location
Definition: buildRTE.php:22
selectFilesystem(int $location)
Selects the correct filesystem by the given Location constant.
$path
Definition: ltiservices.php:29
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
+ Here is the call graph for this function:

◆ process()

ILIAS\FileUpload\FileUploadImpl::process ( )

Implements ILIAS\FileUpload\FileUpload.

Definition at line 247 of file FileUploadImpl.php.

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

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  }
flattenUploadedFiles(array $uploadedFiles)
rejectFailedUpload(Metadata $metadata)
Reject a failed upload with the given metadata.
hardRemoveUpload(string $identifier, ProcessingStatus $status)
This is the very last thing we can do if a preprocessor DENIEs an upload.
static ofPsr7Stream(StreamInterface $stream)
Create a FileStream from a Psr7 compliant stream.
Definition: Streams.php:113
+ 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.

References ILIAS\FileUpload\DTO\ProcessingStatus\REJECTED.

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

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  }
+ 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.

References $path.

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

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  }
$path
Definition: ltiservices.php:29
+ Here is the caller graph for this function:

◆ register()

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

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.

References ILIAS\FileUpload\DTO\ProcessingStatus\REJECTED.

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

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  }
+ 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

Definition at line 210 of file FileUploadImpl.php.

References 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().

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 STORAGE
The filesystem outside of the ilias web root.
Definition: Location.php:43
$location
Definition: buildRTE.php:22
static filesystems()
Returns the loaded filesystems.
const CUSTOMIZING
The filesystem within the web root where all the skins and plugins are saved.
Definition: Location.php:48
const TEMPORARY
The ILIAS temporary directory.
Definition: Location.php:53
const WEB
The filesystem within the ilias web root.
Definition: Location.php:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ uploadSizeLimit()

ILIAS\FileUpload\FileUploadImpl::uploadSizeLimit ( )

Implements ILIAS\FileUpload\FileUpload.

Definition at line 225 of file FileUploadImpl.php.

References ilFileUtils\getPhpUploadSizeLimitInBytes().

225  : int
226  {
228  }
static 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

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

Definition at line 53 of file FileUploadImpl.php.

◆ $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: