Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:bcit-ci/CodeIgniter4 into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
lonnieezell committed Jan 10, 2017
2 parents 72d9893 + 064cc20 commit d5ce60f
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 28 deletions.
4 changes: 2 additions & 2 deletions system/Database/BaseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -1350,7 +1350,7 @@ public function getCompiledSelect($reset = true)
* @param string the offset clause
* @param bool If true, returns the generate SQL, otherwise executes the query.
*
* @return CI_DB_result
* @return ResultInterface
*/
public function get($limit = null, $offset = null, $returnSQL = false)
{
Expand Down Expand Up @@ -1470,7 +1470,7 @@ public function countAllResults($reset = true, $test = false)
* @param int $limit
* @param int $offset
*
* @return CI_DB_result
* @return ResultInterface
*/
public function getWhere($where = null, $limit = null, $offset = null)
{
Expand Down
71 changes: 58 additions & 13 deletions system/HTTP/Files/FileCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,39 @@ public function all()
*/
public function getFile(string $name)
{
$this->populateFiles();

$name = strtolower($name);

if (array_key_exists($name, $this->files))
{
return $this->files[$name];
}

return null;
}

//--------------------------------------------------------------------
$this->populateFiles();

$name = strtolower($name);

if ($this->hasFile($name)) {

if (strpos($name, '.') !== false) {
$name = explode('.', $name);
$uploadedFile = $this->getValueDotNotationSyntax($name, $this->files);
if($uploadedFile instanceof \CodeIgniter\HTTP\Files\UploadedFile){
return $uploadedFile;
}

return null;
}

if (array_key_exists($name, $this->files)) {
$uploadedFile = $this->files[$name];
if($uploadedFile instanceof \CodeIgniter\HTTP\Files\UploadedFile){
return $uploadedFile;
}

return null;
}

return null;

}

return null;
}

//--------------------------------------------------------------------

/**
* Checks whether an uploaded file with name $fileID exists in
Expand Down Expand Up @@ -250,4 +270,29 @@ protected function fixFilesArray(array $data): array
}

//--------------------------------------------------------------------

/**
* Navigate through a array looking for a particular index
* @param array $index The index sequence we are navigating down
* @param array $value The portion of the array to process
* @return mixed
*/
protected function getValueDotNotationSyntax($index, $value) {
if(is_array($index) &&
count($index)) {
$current_index = array_shift($index);
}
if(is_array($index) &&
count($index) &&
is_array($value[$current_index]) &&
count($value[$current_index])) {
return $this->getValueDotNotationSyntax($index, $value[$current_index]);
} else {
if(isset($value[$current_index])){
return $value[$current_index];
}else{
return null;
}
}
}
}
2 changes: 1 addition & 1 deletion system/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ public function find($id)
{
$row = $builder->whereIn($this->primaryKey, $id)
->get();
$row = $row->getResult();
$row = $row->getResult($this->tempReturnType);
}
else
{
Expand Down
123 changes: 122 additions & 1 deletion tests/system/HTTP/Files/FileCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ public function testHasFileWithSingleFileNestedName()
$this->assertTrue($collection->hasFile('userfile.foo'));
$this->assertTrue($collection->hasFile('userfile.foo.bar'));
}

//--------------------------------------------------------------------

public function testErrorString()
Expand All @@ -279,6 +279,127 @@ public function testErrorString()
}

//--------------------------------------------------------------------

public function testFileReturnsValidSingleFile() {
$_FILES = [
'userfile' => [
'name' => 'someFile.txt',
'type' => 'text/plain',
'size' => '124',
'tmp_name' => '/tmp/myTempFile.txt',
'error' => 0
]
];

$collection = new FileCollection();
$file = $collection->getFile('userfile');
$this->assertTrue($file instanceof UploadedFile);

$this->assertEquals('someFile.txt', $file->getName());
$this->assertEquals(124, $file->getSize());
}

//--------------------------------------------------------------------

public function testFileNoExistSingleFile() {
$_FILES = [
'userfile' => [
'name' => 'someFile.txt',
'type' => 'text/plain',
'size' => '124',
'tmp_name' => '/tmp/myTempFile.txt',
'error' => 0
]
];

$collection = new FileCollection();
$file = $collection->getFile('fileuser');
$this->AssertNull($file);
}

//--------------------------------------------------------------------

public function testFileReturnValidMultipleFiles() {
$_FILES = [
'userfile' => [
'name' => ['fileA.txt', 'fileB.txt'],
'type' => ['text/plain', 'text/csv'],
'size' => ['124', '248'],
'tmp_name' => ['/tmp/fileA.txt', '/tmp/fileB.txt'],
'error' => 0
]
];

$collection = new FileCollection();

$file_1 = $collection->getFile('userfile.0');
$this->assertTrue($file_1 instanceof UploadedFile);
$this->assertEquals('fileA.txt', $file_1->getName());
$this->assertEquals('/tmp/fileA.txt', $file_1->getTempName());
$this->assertEquals('txt', $file_1->getClientExtension());
$this->assertEquals('text/plain', $file_1->getClientType());
$this->assertEquals(124, $file_1->getSize());

$file_2 = $collection->getFile('userfile.1');
$this->assertTrue($file_2 instanceof UploadedFile);
$this->assertEquals('fileB.txt', $file_2->getName());
$this->assertEquals('/tmp/fileB.txt', $file_2->getTempName());
$this->assertEquals('txt', $file_2->getClientExtension());
$this->assertEquals('text/csv', $file_2->getClientType());
$this->assertEquals(248, $file_2->getSize());
}

//--------------------------------------------------------------------

public function testFileWithMultipleFilesNestedName() {
$_FILES = [
'my-form' => [
'name' => [
'details' => [
'avatars' => ['fileA.txt','fileB.txt']
]
],
'type' => [
'details' => [
'avatars' => ['text/plain','text/plain']
]
],
'size' => [
'details' => [
'avatars' => [125,243]
]
],
'tmp_name' => [
'details' => [
'avatars' => ['/tmp/fileA.txt','/tmp/fileB.txt']
]
],
'error' => [
'details' => [
'avatars' => [0,0]
]
],
]
];

$collection = new FileCollection();

$file_1 = $collection->getFile('my-form.details.avatars.0');
$this->assertTrue($file_1 instanceof UploadedFile);
$this->assertEquals('fileA.txt', $file_1->getName());
$this->assertEquals('/tmp/fileA.txt', $file_1->getTempName());
$this->assertEquals('txt', $file_1->getClientExtension());
$this->assertEquals('text/plain', $file_1->getClientType());
$this->assertEquals(125, $file_1->getSize());

$file_2 = $collection->getFile('my-form.details.avatars.1');
$this->assertTrue($file_2 instanceof UploadedFile);
$this->assertEquals('fileB.txt', $file_2->getName());
$this->assertEquals('/tmp/fileB.txt', $file_2->getTempName());
$this->assertEquals('txt', $file_2->getClientExtension());
$this->assertEquals('text/plain', $file_2->getClientType());
$this->assertEquals(243, $file_2->getSize());
}

/**
* @group move-file
Expand Down
5 changes: 2 additions & 3 deletions user_guide_src/source/database/migration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,12 @@ re-usable, modular code suites.
Usage Example
*************

In this example some simple code is placed in **application/controllers/Migrate.php**
In this example some simple code is placed in **application/Controllers/Migrate.php**
to update the schema::

<?php

class Migrate extends CI_Controller
class Migrate extends \CodeIgniter\Controller
{

public function index()
Expand Down Expand Up @@ -302,4 +302,3 @@ Class Reference

$migration->setPath($path)
->latest();

8 changes: 4 additions & 4 deletions user_guide_src/source/database/query_builder.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1009,8 +1009,8 @@ Class Reference
:param int $limit: The LIMIT clause
:param int $offset: The OFFSET clause
:returns: CI_DB_result instance (method chaining)
:rtype: CI_DB_result
:returns: \CodeIgniter\Database\ResultInterface instance (method chaining)
:rtype: \CodeIgniter\Database\ResultInterface

Compiles and runs SELECT statement based on the already
called Query Builder methods.
Expand All @@ -1020,8 +1020,8 @@ Class Reference
:param string $where: The WHERE clause
:param int $limit: The LIMIT clause
:param int $offset: The OFFSET clause
:returns: CI_DB_result instance (method chaining)
:rtype: CI_DB_result
:returns: \CodeIgniter\Database\ResultInterface instance (method chaining)
:rtype: \CodeIgniter\Database\ResultInterface

Same as ``get()``, but also allows the WHERE to be added directly.

Expand Down
2 changes: 1 addition & 1 deletion user_guide_src/source/helpers/security_helper.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The following functions are available:

Provides protection against directory traversal.

This function is an alias for ``CI_Security::sanitize_filename()``.
This function is an alias for ``\CodeIgniter\Security::sanitize_filename()``.
For more info, please see the :doc:`Security Library <../libraries/security>`
documentation.

Expand Down
54 changes: 51 additions & 3 deletions user_guide_src/source/libraries/uploaded_files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ array directly.
Accessing Files
===============

All Files
----------

When you upload files they can be accessed natively in PHP through the ``$_FILES`` superglobal. This array has some
major shortcomings when working with multiple files uploaded at once, and has potential security flaws many developers
are not aware of. CodeIgniter helps with both of these situations by standardizing your usage of files behind a
Expand Down Expand Up @@ -67,11 +70,56 @@ In this case, the returned array of files would be more like::
]
]

If you just need to access a single file, you can use ``getFile()`` to retrieve the file instance directly::
Single File
----------

If you just need to access a single file, you can use ``getFile()`` to retrieve the file instance directly. This will return an instance of ``CodeIgniter\HTTP\Files\UploadedFile``:

Simplest usage
^^^^^^^^^^

With the simplest usage, a single file might be submitted like::

<input type="file" name="userfile" />

Which would return a simple file instance like::

$file = $this->request->getFile('userfile');

Array notation
^^^^^^^^^^

If you used an array notation for the name, the input would look something like::

<input type="file" name="my-form[details][avatar]" />

For get the file instance::

$file = $this->request->getFile('my-form.details.avatar');


Multiple files
^^^^^^^^^^
If there are multiple files with the same name you can use ``getFile()`` ro retrieve every file individually::

<input type="file" name="images[]" multiple />

In controller::

$file1 = $this->request->getFile('images.0');
$file2 = $this->request->getFile('images.1');

Another example::

Upload an avatar: <input type="file" name="my-form[details][avatars][]" />
Upload an avatar: <input type="file" name="my-form[details][avatars][]" />

In controller::

$file = $this->request->getFile('avatar');
$file1 = $this->request->getFile('my-form.details.avatars.0');
$file2 = $this->request->getFile('my-form.details.avatars.1');

.. note:: This currently only works with simple file names and not with array syntax naming.
.. note:: For multiple files it is recommended to use the function ``getFiles()``

=====================
Working With the File
Expand Down

0 comments on commit d5ce60f

Please sign in to comment.