getMetadata('uri'); if (!is_string($file)) { throw new InvalidArgumentException('No URI associated with the stream.'); } $this->file = $file; $this->stream = $fileNameOrStream; } elseif (is_string($fileNameOrStream)) { $this->file = $fileNameOrStream; } else { throw new InvalidArgumentException( 'Please provide a string (full path to the uploaded file) or an instance of StreamInterface.' ); } $this->name = $name; $this->type = $type; $this->size = $size; $this->error = $error; $this->sapi = $sapi; } /** * {@inheritdoc} */ public function getStream() { if ($this->moved) { throw new RuntimeException(sprintf('Uploaded file %s has already been moved', $this->name)); } if (!$this->stream) { $this->stream = (new StreamFactory())->createStreamFromFile($this->file); } return $this->stream; } /** * {@inheritdoc} */ public function moveTo($targetPath): void { if ($this->moved) { throw new RuntimeException('Uploaded file already moved'); } $targetIsStream = strpos($targetPath, '://') > 0; if (!$targetIsStream && !is_writable(dirname($targetPath))) { throw new InvalidArgumentException('Upload target path is not writable'); } if ($targetIsStream) { if (!copy($this->file, $targetPath)) { throw new RuntimeException(sprintf('Error moving uploaded file %s to %s', $this->name, $targetPath)); } if (!unlink($this->file)) { throw new RuntimeException(sprintf('Error removing uploaded file %s', $this->name)); } } elseif ($this->sapi) { if (!is_uploaded_file($this->file)) { throw new RuntimeException(sprintf('%s is not a valid uploaded file', $this->file)); } if (!move_uploaded_file($this->file, $targetPath)) { throw new RuntimeException(sprintf('Error moving uploaded file %s to %s', $this->name, $targetPath)); } } else { if (!rename($this->file, $targetPath)) { throw new RuntimeException(sprintf('Error moving uploaded file %s to %s', $this->name, $targetPath)); } } $this->moved = true; } /** * {@inheritdoc} */ public function getError(): int { return $this->error; } /** * {@inheritdoc} */ public function getClientFilename(): ?string { return $this->name; } /** * {@inheritdoc} */ public function getClientMediaType(): ?string { return $this->type; } /** * {@inheritdoc} */ public function getSize(): ?int { return $this->size; } /** * Returns the client-provided full path to the file * * @internal This method is not part of the PSR-7 standard * * @return string */ public function getFilePath(): string { return $this->file; } /** * Create a normalized tree of UploadedFile instances from the Environment. * * @internal This method is not part of the PSR-7 standard. * * @param array $globals The global server variables. * * @return array A normalized tree of UploadedFile instances or null if none are provided. */ public static function createFromGlobals(array $globals): array { if (isset($globals['slim.files']) && is_array($globals['slim.files'])) { return $globals['slim.files']; } if (!empty($_FILES)) { return static::parseUploadedFiles($_FILES); } return []; } /** * Parse a non-normalized, i.e. $_FILES superglobal, tree of uploaded file data. * * @internal This method is not part of the PSR-7 standard. * * @param array $uploadedFiles The non-normalized tree of uploaded file data. * * @return array A normalized tree of UploadedFile instances. */ private static function parseUploadedFiles(array $uploadedFiles): array { $parsed = []; foreach ($uploadedFiles as $field => $uploadedFile) { if (!isset($uploadedFile['error'])) { if (is_array($uploadedFile)) { $parsed[$field] = static::parseUploadedFiles($uploadedFile); } continue; } $parsed[$field] = []; if (!is_array($uploadedFile['error'])) { $parsed[$field] = new static( $uploadedFile['tmp_name'], isset($uploadedFile['name']) ? $uploadedFile['name'] : null, isset($uploadedFile['type']) ? $uploadedFile['type'] : null, isset($uploadedFile['size']) ? $uploadedFile['size'] : null, $uploadedFile['error'], true ); } else { $subArray = []; foreach ($uploadedFile['error'] as $fileIdx => $error) { // Normalize sub array and re-parse to move the input's key name up a level $subArray[$fileIdx]['name'] = $uploadedFile['name'][$fileIdx]; $subArray[$fileIdx]['type'] = $uploadedFile['type'][$fileIdx]; $subArray[$fileIdx]['tmp_name'] = $uploadedFile['tmp_name'][$fileIdx]; $subArray[$fileIdx]['error'] = $uploadedFile['error'][$fileIdx]; $subArray[$fileIdx]['size'] = $uploadedFile['size'][$fileIdx]; $parsed[$field] = static::parseUploadedFiles($subArray); } } } return $parsed; } }