First Local Commit - After Clean up.

Signed-off-by: Rick Hays <rhays@haysgang.com>
This commit is contained in:
2019-12-02 14:54:38 -06:00
commit 10412ab7f6
486 changed files with 123242 additions and 0 deletions

View File

@@ -0,0 +1,325 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014-2019 British Columbia Institute of Technology
* Copyright (c) 2019 CodeIgniter Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author CodeIgniter Dev Team
* @copyright 2019 CodeIgniter Foundation
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 4.0.0
* @filesource
*/
namespace CodeIgniter\HTTP\Files;
/**
* Class FileCollection
*
* Provides easy access to uploaded files for a request.
*
* @package CodeIgniter\HTTP\Files
*/
class FileCollection
{
/**
* An array of UploadedFile instances for any files
* uploaded as part of this request.
* Populated the first time either files(), file(), or hasFile()
* is called.
*
* @var array|null
*/
protected $files;
//--------------------------------------------------------------------
/**
* Returns an array of all uploaded files that were found.
* Each element in the array will be an instance of UploadedFile.
* The key of each element will be the client filename.
*
* @return array|null
*/
public function all()
{
$this->populateFiles();
return $this->files;
}
//--------------------------------------------------------------------
/**
* Attempts to get a single file from the collection of uploaded files.
*
* @param string $name
*
* @return UploadedFile|null
*/
public function getFile(string $name)
{
$this->populateFiles();
if ($this->hasFile($name))
{
if (strpos($name, '.') !== false)
{
$name = explode('.', $name);
$uploadedFile = $this->getValueDotNotationSyntax($name, $this->files);
return ($uploadedFile instanceof UploadedFile) ?
$uploadedFile : null;
}
if (array_key_exists($name, $this->files))
{
$uploadedFile = $this->files[$name];
return ($uploadedFile instanceof UploadedFile) ?
$uploadedFile : null;
}
}
return null;
}
//--------------------------------------------------------------------
/**
* Verify if a file exist in the collection of uploaded files and is have been uploaded with multiple option.
*
* @param string $name
*
* @return array|null
*/
public function getFileMultiple(string $name)
{
$this->populateFiles();
if ($this->hasFile($name))
{
if (strpos($name, '.') !== false)
{
$name = explode('.', $name);
$uploadedFile = $this->getValueDotNotationSyntax($name, $this->files);
return (is_array($uploadedFile) && ($uploadedFile[0] instanceof UploadedFile)) ?
$uploadedFile : null;
}
if (array_key_exists($name, $this->files))
{
$uploadedFile = $this->files[$name];
return (is_array($uploadedFile) && ($uploadedFile[0] instanceof UploadedFile)) ?
$uploadedFile : null;
}
}
return null;
}
//--------------------------------------------------------------------
/**
* Checks whether an uploaded file with name $fileID exists in
* this request.
*
* @param string $fileID The name of the uploaded file (from the input)
*
* @return boolean
*/
public function hasFile(string $fileID): bool
{
$this->populateFiles();
if (strpos($fileID, '.') !== false)
{
$segments = explode('.', $fileID);
$el = $this->files;
foreach ($segments as $segment)
{
if (! array_key_exists($segment, $el))
{
return false;
}
$el = $el[$segment];
}
return true;
}
return isset($this->files[$fileID]);
}
//--------------------------------------------------------------------
/**
* Taking information from the $_FILES array, it creates an instance
* of UploadedFile for each one, saving the results to this->files.
*
* Called by files(), file(), and hasFile()
*/
protected function populateFiles()
{
if (is_array($this->files))
{
return;
}
$this->files = [];
if (empty($_FILES))
{
return;
}
$files = $this->fixFilesArray($_FILES);
foreach ($files as $name => $file)
{
$this->files[$name] = $this->createFileObject($file);
}
}
//--------------------------------------------------------------------
/**
* Given a file array, will create UploadedFile instances. Will
* loop over an array and create objects for each.
*
* @param array $array
*
* @return array|UploadedFile
*/
protected function createFileObject(array $array)
{
if (! isset($array['name']))
{
$output = [];
foreach ($array as $key => $values)
{
if (! is_array($values))
{
continue;
}
$output[$key] = $this->createFileObject($values);
}
return $output;
}
return new UploadedFile(
$array['tmp_name'] ?? null, $array['name'] ?? null, $array['type'] ?? null, $array['size'] ?? null, $array['error'] ?? null
);
}
//--------------------------------------------------------------------
/**
* Reformats the odd $_FILES array into something much more like
* we would expect, with each object having its own array.
*
* Thanks to Jack Sleight on the PHP Manual page for the basis
* of this method.
*
* @see http://php.net/manual/en/reserved.variables.files.php#118294
*
* @param array $data
*
* @return array
*/
protected function fixFilesArray(array $data): array
{
$output = [];
foreach ($data as $name => $array)
{
foreach ($array as $field => $value)
{
$pointer = &$output[$name];
if (! is_array($value))
{
$pointer[$field] = $value;
continue;
}
$stack = [&$pointer];
$iterator = new \RecursiveIteratorIterator(
new \RecursiveArrayIterator($value), \RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $key => $val)
{
array_splice($stack, $iterator->getDepth() + 1);
$pointer = &$stack[count($stack) - 1];
$pointer = &$pointer[$key];
$stack[] = &$pointer;
if (! $iterator->hasChildren())
{
$pointer[$field] = $val;
}
}
}
}
return $output;
}
//--------------------------------------------------------------------
/**
* 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(array $index, array $value)
{
if (is_array($index) && ! empty($index))
{
$current_index = array_shift($index);
}
if (is_array($index) && $index && is_array($value[$current_index]) && $value[$current_index])
{
return $this->getValueDotNotationSyntax($index, $value[$current_index]);
}
return (isset($value[$current_index])) ? $value[$current_index] : null;
}
}

View File

@@ -0,0 +1,413 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014-2019 British Columbia Institute of Technology
* Copyright (c) 2019 CodeIgniter Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author CodeIgniter Dev Team
* @copyright 2019 CodeIgniter Foundation
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 4.0.0
* @filesource
*/
namespace CodeIgniter\HTTP\Files;
use CodeIgniter\Files\File;
use CodeIgniter\HTTP\Exceptions\HTTPException;
use Config\Mimes;
use Exception;
/**
* Value object representing a single file uploaded through an
* HTTP request. Used by the IncomingRequest class to
* provide files.
*
* Typically, implementors will extend the SplFileInfo class.
*
* @package CodeIgniter\HTTP
*/
class UploadedFile extends File implements UploadedFileInterface
{
/**
* The path to the temporary file.
*
* @var string
*/
protected $path;
/**
* The original filename as provided by the client.
*
* @var string
*/
protected $originalName;
/**
* The filename given to a file during a move.
*
* @var string
*/
protected $name;
/**
* The type of file as provided by PHP
*
* @var string
*/
protected $originalMimeType;
/**
* The error constant of the upload
* (one of PHP's UPLOADERRXXX constants)
*
* @var integer
*/
protected $error;
/**
* Whether the file has been moved already or not.
*
* @var boolean
*/
protected $hasMoved = false;
//--------------------------------------------------------------------
/**
* Accepts the file information as would be filled in from the $_FILES array.
*
* @param string $path The temporary location of the uploaded file.
* @param string $originalName The client-provided filename.
* @param string $mimeType The type of file as provided by PHP
* @param integer $size The size of the file, in bytes
* @param integer $error The error constant of the upload (one of PHP's UPLOADERRXXX constants)
*/
public function __construct(string $path, string $originalName, string $mimeType = null, int $size = null, int $error = null)
{
$this->path = $path;
$this->name = $originalName;
$this->originalName = $originalName;
$this->originalMimeType = $mimeType;
$this->size = $size;
$this->error = $error;
parent::__construct($path, false);
}
//--------------------------------------------------------------------
/**
* Move the uploaded file to a new location.
*
* $targetPath may be an absolute path, or a relative path. If it is a
* relative path, resolution should be the same as used by PHP's rename()
* function.
*
* The original file MUST be removed on completion.
*
* If this method is called more than once, any subsequent calls MUST raise
* an exception.
*
* When used in an SAPI environment where $_FILES is populated, when writing
* files via moveTo(), is_uploaded_file() and move_uploaded_file() SHOULD be
* used to ensure permissions and upload status are verified correctly.
*
* If you wish to move to a stream, use getStream(), as SAPI operations
* cannot guarantee writing to stream destinations.
*
* @see http://php.net/is_uploaded_file
* @see http://php.net/move_uploaded_file
*
* @param string $targetPath Path to which to move the uploaded file.
* @param string $name the name to rename the file to.
* @param boolean $overwrite State for indicating whether to overwrite the previously generated file with the same
* name or not.
*
* @return boolean
*
* @throws \InvalidArgumentException if the $path specified is invalid.
* @throws \RuntimeException on any error during the move operation.
* @throws \RuntimeException on the second or subsequent call to the method.
*/
public function move(string $targetPath, string $name = null, bool $overwrite = false)
{
$targetPath = $this->setPath($targetPath); //set the target path
if ($this->hasMoved)
{
throw HTTPException::forAlreadyMoved();
}
if (! $this->isValid())
{
throw HTTPException::forInvalidFile();
}
$targetPath = rtrim($targetPath, '/') . '/';
$name = is_null($name) ? $this->getName() : $name;
$destination = $overwrite ? $targetPath . $name : $this->getDestination($targetPath . $name);
try
{
move_uploaded_file($this->path, $destination);
}
catch (Exception $e)
{
$error = error_get_last();
throw HTTPException::forMoveFailed(basename($this->path), $targetPath, strip_tags($error['message']));
}
@chmod($targetPath, 0777 & ~umask());
// Success, so store our new information
$this->path = $targetPath;
$this->name = basename($destination);
$this->hasMoved = true;
return true;
}
/**
* create file target path if
* the set path does not exist
*
* @param string $path
*
* @return string The path set or created.
*/
protected function setPath(string $path): string
{
if (! is_dir($path))
{
mkdir($path, 0777, true);
//create the index.html file
if (! is_file($path . 'index.html'))
{
$file = fopen($path . 'index.html', 'x+');
fclose($file);
}
}
return $path;
}
//--------------------------------------------------------------------
/**
* Returns whether the file has been moved or not. If it has,
* the move() method will not work and certain properties, like
* the tempName, will no longer be available.
*
* @return boolean
*/
public function hasMoved(): bool
{
return $this->hasMoved;
}
//--------------------------------------------------------------------
/**
* Retrieve the error associated with the uploaded file.
*
* The return value MUST be one of PHP's UPLOAD_ERR_XXX constants.
*
* If the file was uploaded successfully, this method MUST return
* UPLOAD_ERR_OK.
*
* Implementations SHOULD return the value stored in the "error" key of
* the file in the $_FILES array.
*
* @see http://php.net/manual/en/features.file-upload.errors.php
* @return integer One of PHP's UPLOAD_ERR_XXX constants.
*/
public function getError(): int
{
if (is_null($this->error))
{
return UPLOAD_ERR_OK;
}
return $this->error;
}
//--------------------------------------------------------------------
/**
* Get error string
*
* @return string
*/
public function getErrorString(): string
{
$errors = [
UPLOAD_ERR_OK => lang('HTTP.uploadErrOk'),
UPLOAD_ERR_INI_SIZE => lang('HTTP.uploadErrIniSize'),
UPLOAD_ERR_FORM_SIZE => lang('HTTP.uploadErrFormSize'),
UPLOAD_ERR_PARTIAL => lang('HTTP.uploadErrPartial'),
UPLOAD_ERR_NO_FILE => lang('HTTP.uploadErrNoFile'),
UPLOAD_ERR_CANT_WRITE => lang('HTTP.uploadErrCantWrite'),
UPLOAD_ERR_NO_TMP_DIR => lang('HTTP.uploadErrNoTmpDir'),
UPLOAD_ERR_EXTENSION => lang('HTTP.uploadErrExtension'),
];
$error = is_null($this->error) ? UPLOAD_ERR_OK : $this->error;
return sprintf($errors[$error] ?? lang('HTTP.uploadErrUnknown'), $this->getName());
}
//--------------------------------------------------------------------
/**
* Returns the mime type as provided by the client.
* This is NOT a trusted value.
* For a trusted version, use getMimeType() instead.
*
* @return string The media type sent by the client or null if none was provided.
*/
public function getClientMimeType(): string
{
return $this->originalMimeType;
}
//--------------------------------------------------------------------
/**
* Retrieve the filename. This will typically be the filename sent
* by the client, and should not be trusted. If the file has been
* moved, this will return the final name of the moved file.
*
* @return string The filename sent by the client or null if none was provided.
*/
public function getName(): string
{
return $this->name;
}
//--------------------------------------------------------------------
/**
* Returns the name of the file as provided by the client during upload.
*
* @return string
*/
public function getClientName(): string
{
return $this->originalName;
}
//--------------------------------------------------------------------
/**
* Gets the temporary filename where the file was uploaded to.
*
* @return string
*/
public function getTempName(): string
{
return $this->path;
}
//--------------------------------------------------------------------
/**
* Overrides SPLFileInfo's to work with uploaded files, since
* the temp file that's been uploaded doesn't have an extension.
*
* Is simply an alias for guessExtension for a safer method
* than simply relying on the provided extension.
* Additionally it will return clientExtension in case if there are
* other extensions with the same mime type.
*/
public function getExtension(): string
{
return $this->guessExtension();
}
/**
* Attempts to determine the best file extension.
*
* @return string|null
*/
public function guessExtension(): string
{
return Mimes::guessExtensionFromType($this->getClientMimeType(), $this->getClientExtension()) ?? $this->getClientExtension();
}
//--------------------------------------------------------------------
/**
* Returns the original file extension, based on the file name that
* was uploaded. This is NOT a trusted source.
* For a trusted version, use guessExtension() instead.
*
* @return string
*/
public function getClientExtension(): string
{
return pathinfo($this->originalName, PATHINFO_EXTENSION) ?? '';
}
//--------------------------------------------------------------------
/**
* Returns whether the file was uploaded successfully, based on whether
* it was uploaded via HTTP and has no errors.
*
* @return boolean
*/
public function isValid(): bool
{
return is_uploaded_file($this->path) && $this->error === UPLOAD_ERR_OK;
}
/**
* Save the uploaded file to a new location.
*
* By default, upload files are saved in writable/uploads directory. The YYYYMMDD folder
* and random file name will be created.
*
* @param string $folderName the folder name to writable/uploads directory.
* @param string $fileName the name to rename the file to.
* @return string file full path
*/
public function store(string $folderName = null, string $fileName = null): string
{
$folderName = rtrim($folderName ?? date('Ymd'), '/') . '/' ;
$fileName = $fileName ?? $this->getRandomName();
// Move the uploaded file to a new location.
return ($this->move(WRITEPATH . 'uploads/' . $folderName, $fileName)) ?
$folderName . $this->name : null;
}
//--------------------------------------------------------------------
}

View File

@@ -0,0 +1,203 @@
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014-2019 British Columbia Institute of Technology
* Copyright (c) 2019 CodeIgniter Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author CodeIgniter Dev Team
* @copyright 2019 CodeIgniter Foundation
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 4.0.0
* @filesource
*/
namespace CodeIgniter\HTTP\Files;
/**
* Value object representing a single file uploaded through an
* HTTP request. Used by the IncomingRequest class to
* provide files.
*
* Typically, implementors will extend the SplFileInfo class.
*
* @package CodeIgniter\HTTP
*/
interface UploadedFileInterface
{
/**
* Accepts the file information as would be filled in from the $_FILES array.
*
* @param string $path The temporary location of the uploaded file.
* @param string $originalName The client-provided filename.
* @param string $mimeType The type of file as provided by PHP
* @param integer $size The size of the file, in bytes
* @param integer $error The error constant of the upload (one of PHP's UPLOADERRXXX constants)
*/
public function __construct(string $path, string $originalName, string $mimeType = null, int $size = null, int $error = null);
//--------------------------------------------------------------------
/**
* Move the uploaded file to a new location.
*
* $targetPath may be an absolute path, or a relative path. If it is a
* relative path, resolution should be the same as used by PHP's rename()
* function.
*
* The original file MUST be removed on completion.
*
* If this method is called more than once, any subsequent calls MUST raise
* an exception.
*
* When used in an SAPI environment where $_FILES is populated, when writing
* files via moveTo(), is_uploaded_file() and move_uploaded_file() SHOULD be
* used to ensure permissions and upload status are verified correctly.
*
* If you wish to move to a stream, use getStream(), as SAPI operations
* cannot guarantee writing to stream destinations.
*
* @see http://php.net/is_uploaded_file
* @see http://php.net/move_uploaded_file
*
* @param string $targetPath Path to which to move the uploaded file.
* @param string $name the name to rename the file to.
*
* @throws \InvalidArgumentException if the $path specified is invalid.
* @throws \RuntimeException on any error during the move operation.
* @throws \RuntimeException on the second or subsequent call to the method.
*/
public function move(string $targetPath, string $name = null);
//--------------------------------------------------------------------
/**
* Returns whether the file has been moved or not. If it has,
* the move() method will not work and certain properties, like
* the tempName, will no longer be available.
*
* @return boolean
*/
public function hasMoved(): bool;
//--------------------------------------------------------------------
/**
* Retrieve the error associated with the uploaded file.
*
* The return value MUST be one of PHP's UPLOAD_ERR_XXX constants.
*
* If the file was uploaded successfully, this method MUST return
* UPLOAD_ERR_OK.
*
* Implementations SHOULD return the value stored in the "error" key of
* the file in the $_FILES array.
*
* @see http://php.net/manual/en/features.file-upload.errors.php
* @return integer One of PHP's UPLOAD_ERR_XXX constants.
*/
public function getError(): int;
//--------------------------------------------------------------------
/**
* Retrieve the filename sent by the client.
*
* Do not trust the value returned by this method. A client could send
* a malicious filename with the intention to corrupt or hack your
* application.
*
* Implementations SHOULD return the value stored in the "name" key of
* the file in the $_FILES array.
*
* @return string|null The filename sent by the client or null if none
* was provided.
*/
public function getName(): string;
//--------------------------------------------------------------------
/**
* Gets the temporary filename where the file was uploaded to.
*
* @return string
*/
public function getTempName(): string;
//--------------------------------------------------------------------
/**
* Returns the original file extension, based on the file name that
* was uploaded. This is NOT a trusted source.
* For a trusted version, use guessExtension() instead.
*
* @return string|null
*/
public function getClientExtension(): string;
//--------------------------------------------------------------------
/**
* Returns the mime type as provided by the client.
* This is NOT a trusted value.
* For a trusted version, use getMimeType() instead.
*
* @return string|null
*/
public function getClientMimeType(): string;
//--------------------------------------------------------------------
/**
* Returns whether the file was uploaded successfully, based on whether
* it was uploaded via HTTP and has no errors.
*
* @return boolean
*/
public function isValid(): bool;
//--------------------------------------------------------------------
/**
* Returns the destination path for the move operation where overwriting is not expected.
*
* First, it checks whether the delimiter is present in the filename, if it is, then it checks whether the
* last element is an integer as there may be cases that the delimiter may be present in the filename.
* For the all other cases, it appends an integer starting from zero before the file's extension.
*
* @param string $destination
* @param string $delimiter
* @param integer $i
*
* @return string
*/
public function getDestination(string $destination, string $delimiter = '_', int $i = 0): string;
//--------------------------------------------------------------------
}