diff --git a/system/HTTP/Files/FileCollection.php b/system/HTTP/Files/FileCollection.php index 87f31ee511ea..7b117f4f8e02 100644 --- a/system/HTTP/Files/FileCollection.php +++ b/system/HTTP/Files/FileCollection.php @@ -182,7 +182,8 @@ protected function createFileObject(array $array) $array['name'] ?? null, $array['type'] ?? null, $array['size'] ?? null, - $array['error'] ?? null + $array['error'] ?? null, + $array['full_path'] ?? null ); } diff --git a/system/HTTP/Files/UploadedFile.php b/system/HTTP/Files/UploadedFile.php index a9e81cd97ee1..70ece748d834 100644 --- a/system/HTTP/Files/UploadedFile.php +++ b/system/HTTP/Files/UploadedFile.php @@ -34,6 +34,13 @@ class UploadedFile extends File implements UploadedFileInterface */ protected $path; + /** + * The webkit relative path of the file. + * + * @var string + */ + protected $clientPath; + /** * The original filename as provided by the client. * @@ -78,8 +85,9 @@ class UploadedFile extends File implements UploadedFileInterface * @param string $mimeType The type of file as provided by PHP * @param int $size The size of the file, in bytes * @param int $error The error constant of the upload (one of PHP's UPLOADERRXXX constants) + * @param string $clientPath The webkit relative path of the uploaded file. */ - public function __construct(string $path, string $originalName, ?string $mimeType = null, ?int $size = null, ?int $error = null) + public function __construct(string $path, string $originalName, ?string $mimeType = null, ?int $size = null, ?int $error = null, ?string $clientPath = null) { $this->path = $path; $this->name = $originalName; @@ -87,6 +95,7 @@ public function __construct(string $path, string $originalName, ?string $mimeTyp $this->originalMimeType = $mimeType; $this->size = $size; $this->error = $error; + $this->clientPath = $clientPath; parent::__construct($path, false); } @@ -267,6 +276,15 @@ public function getClientName(): string return $this->originalName; } + /** + * (PHP 8.1+) + * Returns the webkit relative path of the uploaded file on directory uploads. + */ + public function getClientPath(): ?string + { + return $this->clientPath; + } + /** * Gets the temporary filename where the file was uploaded to. */ diff --git a/system/HTTP/Files/UploadedFileInterface.php b/system/HTTP/Files/UploadedFileInterface.php index 37c18554a106..075c4190a381 100644 --- a/system/HTTP/Files/UploadedFileInterface.php +++ b/system/HTTP/Files/UploadedFileInterface.php @@ -31,8 +31,9 @@ interface UploadedFileInterface * @param string $mimeType The type of file as provided by PHP * @param int $size The size of the file, in bytes * @param int $error The error constant of the upload (one of PHP's UPLOADERRXXX constants) + * @param string $clientPath The webkit relative path of the uploaded file. */ - public function __construct(string $path, string $originalName, ?string $mimeType = null, ?int $size = null, ?int $error = null); + public function __construct(string $path, string $originalName, ?string $mimeType = null, ?int $size = null, ?int $error = null, ?string $clientPath = null); /** * Move the uploaded file to a new location. @@ -109,6 +110,12 @@ public function getName(): string; */ public function getTempName(): string; + /** + * (PHP 8.1+) + * Returns the webkit relative path of the uploaded file on directory uploads. + */ + public function getClientPath(): ?string; + /** * Returns the original file extension, based on the file name that * was uploaded. This is NOT a trusted source. diff --git a/tests/system/HTTP/Files/FileCollectionTest.php b/tests/system/HTTP/Files/FileCollectionTest.php index c9d2c0123acf..7c087e07d18a 100644 --- a/tests/system/HTTP/Files/FileCollectionTest.php +++ b/tests/system/HTTP/Files/FileCollectionTest.php @@ -453,6 +453,41 @@ public function testErrorWithNoError() $this->assertSame(UPLOAD_ERR_OK, $file->getError()); } + public function testClientPathReturnsValidFullPath() + { + $_FILES = [ + 'userfile' => [ + 'name' => 'someFile.txt', + 'type' => 'text/plain', + 'size' => '124', + 'tmp_name' => '/tmp/myTempFile.txt', + 'full_path' => 'someDir/someFile.txt', + ], + ]; + + $collection = new FileCollection(); + $file = $collection->getFile('userfile'); + + $this->assertSame('someDir/someFile.txt', $file->getClientPath()); + } + + public function testClientPathReturnsNullWhenFullPathIsNull() + { + $_FILES = [ + 'userfile' => [ + 'name' => 'someFile.txt', + 'type' => 'text/plain', + 'size' => '124', + 'tmp_name' => '/tmp/myTempFile.txt', + ], + ]; + + $collection = new FileCollection(); + $file = $collection->getFile('userfile'); + + $this->assertNull($file->getClientPath()); + } + public function testFileReturnsValidSingleFile() { $_FILES = [ diff --git a/user_guide_src/source/changelogs/v4.4.0.rst b/user_guide_src/source/changelogs/v4.4.0.rst index f0d803b7e36e..c79e9fb56571 100644 --- a/user_guide_src/source/changelogs/v4.4.0.rst +++ b/user_guide_src/source/changelogs/v4.4.0.rst @@ -89,6 +89,9 @@ Libraries the actual validated data. See :ref:`validation-getting-validated-data` for details. - **Images:** The option ``$quality`` can now be used to compress WebP images. +- **Uploaded Files:** Added ``UploadedFiles::getClientPath()`` method that returns + the value of the `full_path` index of the file if it was uploaded via directory upload. + Helpers and Functions ===================== diff --git a/user_guide_src/source/libraries/uploaded_files.rst b/user_guide_src/source/libraries/uploaded_files.rst index b91b34ecd718..6a981100696b 100644 --- a/user_guide_src/source/libraries/uploaded_files.rst +++ b/user_guide_src/source/libraries/uploaded_files.rst @@ -304,6 +304,16 @@ version, use ``getMimeType()`` instead: .. literalinclude:: uploaded_files/015.php +getClientPath() +--------------- + +.. versionadded:: 4.4.0 + +Returns the `webkit relative path `_ of the uploaded file when the client has uploaded files via directory upload. +In PHP versions below 8.1, this returns ``null`` + +.. literalinclude:: uploaded_files/023.php + Moving Files ============ diff --git a/user_guide_src/source/libraries/uploaded_files/023.php b/user_guide_src/source/libraries/uploaded_files/023.php new file mode 100644 index 000000000000..f8accc9087b1 --- /dev/null +++ b/user_guide_src/source/libraries/uploaded_files/023.php @@ -0,0 +1,4 @@ +getClientPath(); +echo $clientPath; // dir/file.txt, or dir/sub_dir/file.txt