Completed
Push — master ( 9a341d...f10304 )
by Thierry
01:44
created

FileUpload::getUploadedFiles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * FileUpload.php - Jaxon browser event
5
 *
6
 * This class adds server side event handling capabilities to Jaxon
7
 *
8
 * Events can be registered, then event handlers attached.
9
 *
10
 * @package jaxon-core
11
 * @author Jared White
12
 * @author J. Max Wilson
13
 * @author Joseph Woolley
14
 * @author Steffen Konerow
15
 * @author Thierry Feuzeu <[email protected]>
16
 * @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
17
 * @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White  & J. Max Wilson
18
 * @copyright 2016 Thierry Feuzeu <[email protected]>
19
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
20
 * @link https://github.com/jaxon-php/jaxon-core
21
 */
22
23
namespace Jaxon\Request\Plugin;
24
25
use Jaxon\Jaxon;
26
use Jaxon\Plugin\Request as RequestPlugin;
27
28
class FileUpload extends RequestPlugin
29
{
30
    use \Jaxon\Utils\Traits\Validator;
31
    use \Jaxon\Utils\Traits\Translator;
32
33
    /**
34
     * The uploaded files copied in the user dir
35
     *
36
     * @var array
37
     */
38
    protected $aUserFiles;
39
40
    /**
41
     * The uploaded files received in the temp dir
42
     *
43
     * @var array
44
     */
45
    protected $aFiles;
46
47
    public function __construct()
0 ignored issues
show
Coding Style introduced by
__construct uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
48
    {
49
        $this->aUserFiles = [];
50
        $this->aFiles = [];
51
52
        foreach($_FILES as $var => $aFile)
53
        {
54
            $this->aFiles[$var] = [];
55
            if(is_array($aFile['name']))
56
            {
57
                for($i = 0; $i < count($aFile['name']); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
58
                {
59
                    // Copy the file data into the local array
60
                    $this->aFiles[$var][] = [
61
                        'name' => $aFile['name'][$i],
62
                        'type' => $aFile['type'][$i],
63
                        'tmp_name' => $aFile['tmp_name'][$i],
64
                        'error' => $aFile['error'][$i],
65
                        'size' => $aFile['size'][$i],
66
                    ];
67
                }
68
            }
69
            else
70
            {
71
                // Copy the file data into the local array
72
                $this->aFiles[$var][] = [
73
                    'name' => $aFile['name'],
74
                    'type' => $aFile['type'],
75
                    'tmp_name' => $aFile['tmp_name'],
76
                    'error' => $aFile['error'],
77
                    'size' => $aFile['size'],
78
                ];
79
            }
80
        }
81
    }
82
83
    /**
84
     * Return the name of this plugin
85
     *
86
     * @return string
87
     */
88
    public function getName()
89
    {
90
        return 'FileUpload';
91
    }
92
93
    /**
94
     * Get the uploaded files
95
     *
96
     * @return array
97
     */
98
    public function getUploadedFiles()
99
    {
100
        return $this->aUserFiles;
101
    }
102
103
    /**
104
     * Register a browser event
105
     *
106
     * @param array         $aArgs                An array containing the event specification
107
     *
108
     * @return \Jaxon\Request\Request
109
     */
110
    public function register($aArgs)
111
    {
112
        return false;
113
    }
114
115
    /**
116
     * Generate a hash for the registered browser events
117
     *
118
     * @return string
119
     */
120
    public function generateHash()
121
    {
122
        return '';
123
    }
124
125
    /**
126
     * Generate client side javascript code for the registered browser events
127
     *
128
     * @return string
129
     */
130
    public function getScript()
131
    {
132
        return '';
133
    }
134
135
    /**
136
     * Check if this plugin can process the incoming Jaxon request
137
     *
138
     * @return boolean
139
     */
140
    public function canProcessRequest()
141
    {
142
        // This plugin does not process a request all alone.
143
        // It provides complementary feature to other request plugins instead.
144
        return false;
145
    }
146
147
    /**
148
     * Process the uploaded files into the HTTP request
149
     *
150
     * @return boolean
151
     */
152
    public function processRequest()
153
    {
154
        // Default upload dir
155
        $sDefaultUploadDir = $this->getOption('upload.dir');
156
        // Check validity of the uploaded files
157
        foreach($this->aFiles as $var => &$aFiles)
158
        {
159
            $this->aUserFiles[$var] = [];
160
            foreach($aFiles as &$aFile)
161
            {
162
                // Verify upload result
163
                if($aFile['error'] != 0)
164
                {
165
                    throw new \Jaxon\Exception\Error($this->trans('errors.upload.failed', $aFile));
166
                }
167
                // Verify file validity (format, size)
168
                if(!$this->validateUploadedFile($aFile))
169
                {
170
                    throw new \Jaxon\Exception\Error($this->trans('errors.upload.invalid', $aFile));
171
                }
172
                // Verify that the upload dir exists and is writable
173
                $sUploadDir = trim($this->getOption('upload.files.' . $var . '.dir', $sDefaultUploadDir));
174
                $sUploadDir = rtrim($sUploadDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
175
                if(!is_writable($sUploadDir))
176
                {
177
                    throw new \Jaxon\Exception\Error($this->trans('errors.upload.access'));
178
                }
179
                // Set the user file data
180
                $this->aUserFiles[$var][] = [
181
                    'type' => $aFile['type'],
182
                    'name' => $aFile['name'],
183
                    'path' => $sUploadDir . $aFile["name"],
184
                    'size' => $aFile['size'],
185
                ];
186
            }
187
        }
188
        // Copy the uploaded files from the temp dir to the user dir
189
        foreach($this->aFiles as $var => $aFiles)
190
        {
191
            for($i = 0; $i < count($aFiles); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
192
            {
193
                // All's right, move the file to the user dir.
194
                move_uploaded_file($aFiles[$i]["tmp_name"], $this->aUserFiles[$var][$i]["path"]);
195
            }
196
        }
197
        return true;
198
    }
199
}
200