OpenXE/classes/Components/Http/Collection/FilesCollection.php

224 lines
5.4 KiB
PHP
Raw Normal View History

2021-05-21 08:49:41 +02:00
<?php
namespace Xentral\Components\Http\Collection;
use ArrayIterator;
use Iterator;
use Xentral\Components\Http\File\FileUpload;
class FilesCollection implements Iterator
{
/** @var ArrayIterator $iterator */
protected $iterator;
/**
* @param array $files
*/
public function __construct(array $files = [])
{
$files = $this->loadFilesArray($files);
$this->iterator = new ArrayIterator($files);
}
/**
* Returns all file uploads.
*
* @return FileUpload[]
*/
public function all()
{
return $this->iterator->getArrayCopy();
}
/**
* Returns true if there is a file upload entry with this name.
*
* @param string $name
*
* @return bool
*/
public function has($name)
{
return $this->iterator->offsetExists($name);
}
/**
* Get an file upload entry.
*
* @param string $name
* @param mixed|null $default
*
* @return FileUpload|mixed
*/
public function get($name, $default = null)
{
return $this->has($name) ? $this->iterator->offsetGet($name) : $default;
}
/**
* Returns true if all upload files are valid.
*
* @return bool true=all upload files are valid
*/
public function allValid()
{
foreach ($this->all() as $name => $upload) {
if (!$upload->isValid()) {
return false;
}
}
return true;
}
/**
* Returns true if at least one file upload has an error.
*
* @return bool true=there is at least one error
*/
public function hasErrors()
{
foreach ($this->all() as $name => $upload) {
if ($upload->hasError()) {
return true;
}
}
return false;
}
/**
* Return the current element
*
* @return mixed FileUpload Object, null on failure
*/
public function current()
{
return $this->iterator->current();
}
/**
* Move forward to next element
*
* @return void
*/
public function next()
{
$this->iterator->next();
}
/**
* Return the key of the current element
*
* @return mixed on success, or null on failure.
*/
public function key()
{
return $this->iterator->key();
}
/**
* Checks if current position is valid
*
* @return boolean true on success or false on failure.
*/
public function valid()
{
return $this->iterator->valid();
}
/**
* Rewind the Iterator to the first element
*
* @return void Any returned value is ignored.
*/
public function rewind()
{
$this->iterator->rewind();
}
/**
* @param $fileEntries
*
* @return bool true=is alternate Array
*/
protected function isAlternateArray($fileEntries)
{
if (
!isset($fileEntries[array_keys($fileEntries)[0]]['tmp_name'])
|| is_array($fileEntries[array_keys($fileEntries)[0]]['tmp_name'])
) {
return true;
}
return false;
}
/**
* @param array $fileEntries
*
* @return FileUpload[] $files
*/
protected function loadFilesArray($fileEntries)
{
if (empty($fileEntries)) {
return [];
}
if ($this->isAlternateArray($fileEntries)) {
return $this->convertFilesArray($fileEntries);
}
$files = [];
foreach ($fileEntries as $name => $upload) {
if (empty($upload['tmp_name'])) {
continue;
}
if (!is_array($upload['tmp_name'])) {
$files[$name] = FileUpload::fromFilesArray($upload);
continue;
}
}
return $files;
}
/**
* Recursively builds the array with FileUpload instances from alternative array format.
*
* tested up to 3rd level nesting
*
* @param array $files
*
* @return array
*/
protected function convertFilesArray(array $files)
{
$totalUploads = [];
foreach ($files as $name => $file) {
$keys = array_keys($file);
if (count(array_intersect($keys, ['name', 'tmp_name'])) === 2) {
$uploads = [];
foreach ($file['tmp_name'] as $k => $v) {
$upload = [
'tmp_name' => array_key_exists('tmp_name', $file) ? $file['tmp_name'][$k] : null,
'name' => array_key_exists('name', $file) ? $file['name'][$k] : null,
'type' => array_key_exists('type', $file) ? $file['type'][$k] : null,
'size' => array_key_exists('size', $file) ? $file['size'][$k] : null,
'error' => array_key_exists('error', $file) ? $file['error'][$k] : null,
];
if (!empty($upload['tmp_name'])) {
$uploads[$k] = FileUpload::fromFilesArray($upload);
}
}
$totalUploads[$name] = $uploads;
} else {
if (!(isset($file['tmp_name']) && $file['tmp_name'] === '')) {
$totalUploads[$name] = $this->convertFilesArray($file);
}
}
}
return $totalUploads;
}
}