Passed
Push — master ( 68b778...1b1614 )
by Thierry
07:15 queued 04:29
created

FileUpload::__construct()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 6
c 3
b 0
f 0
dl 0
loc 12
rs 10
cc 3
nc 3
nop 1
1
<?php
2
3
/**
4
 * FileUpload.php - This class implements file upload with Ajax.
5
 *
6
 * @package jaxon-core
0 ignored issues
show
Coding Style introduced by
Package name "jaxon-core" is not valid; consider "Jaxoncore" instead
Loading history...
7
 * @author Thierry Feuzeu <[email protected]>
8
 * @copyright 2017 Thierry Feuzeu <[email protected]>
9
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
10
 * @link https://github.com/jaxon-php/jaxon-core
11
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
12
13
namespace Jaxon\Request\Plugin;
14
15
use Jaxon\Jaxon;
16
use Jaxon\Plugin\Request as RequestPlugin;
17
use Jaxon\Request\Support\UploadedFile;
18
use Jaxon\Request\Support\FileUpload as Support;
19
use Jaxon\Response\UploadResponse;
20
use Exception;
21
use Closure;
22
23
class FileUpload extends RequestPlugin
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class FileUpload
Loading history...
24
{
25
    use \Jaxon\Features\Config;
26
    use \Jaxon\Features\Validator;
27
    use \Jaxon\Features\Translator;
28
29
    /**
30
     * The uploaded files copied in the user dir
31
     *
32
     * @var array
33
     */
34
    protected $aUserFiles = [];
35
36
    /**
37
     * The name of file containing upload data
38
     *
39
     * @var string
40
     */
41
    protected $sTempFile = '';
42
43
    /**
44
     * The subdir where uploaded files are stored
45
     *
46
     * @var string
47
     */
48
    protected $sUploadSubdir = '';
49
50
    /**
51
     * Is the current request an HTTP upload
52
     *
53
     * @var boolean
54
     */
55
    protected $bRequestIsHttpUpload = false;
56
57
    /**
58
     * HTTP file upload support
59
     *
60
     * @var Support
61
     */
62
    protected $xSupport = null;
63
64
    /**
65
     * The constructor
66
     *
67
     * @param Support       $xSupport       HTTP file upload support
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 7 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 7 found
Loading history...
68
     */
69
    public function __construct(Support $xSupport)
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines before function; 1 found
Loading history...
70
    {
71
        $this->xSupport = $xSupport;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
72
        $this->sUploadSubdir = uniqid() . DIRECTORY_SEPARATOR;
73
74
        if(array_key_exists('jxnupl', $_POST))
75
        {
76
            $this->sTempFile = $_POST['jxnupl'];
77
        }
78
        elseif(array_key_exists('jxnupl', $_GET))
79
        {
80
            $this->sTempFile = $_GET['jxnupl'];
81
        }
82
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
83
84
    /**
85
     * @inheritDoc
86
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
87
    public function getName()
88
    {
89
        return Jaxon::FILE_UPLOAD;
90
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
91
92
    /**
93
     * Set the uploaded file name sanitizer
94
     *
95
     * @param Closure       $cSanitizer            The closure
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 7 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 12 found
Loading history...
96
     *
97
     * @return void
98
     */
99
    public function sanitizer(Closure $cSanitizer)
100
    {
101
        $this->xSupport->setNameSanitizer($cSanitizer);
102
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
103
104
    /**
105
     * Get the uploaded files
106
     *
107
     * @return array
108
     */
109
    public function files()
110
    {
111
        return $this->aUserFiles;
112
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
113
114
    /**
115
     * Make sure the upload dir exists and is writable
116
     *
117
     * @param string        $sUploadDir             The filename
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 4 spaces after parameter name; 13 found
Loading history...
118
     * @param string        $sUploadSubDir          The filename
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 10 found
Loading history...
119
     *
120
     * @return string
121
     */
122
    private function _makeUploadDir($sUploadDir, $sUploadSubDir)
123
    {
124
        $sUploadDir = rtrim(trim($sUploadDir), '/\\') . DIRECTORY_SEPARATOR;
125
        // Verify that the upload dir exists and is writable
126
        if(!is_writable($sUploadDir))
127
        {
128
            throw new \Jaxon\Exception\Error($this->trans('errors.upload.access'));
129
        }
130
        $sUploadDir .= $sUploadSubDir;
131
        if(!file_exists($sUploadDir) && !@mkdir($sUploadDir))
132
        {
133
            throw new \Jaxon\Exception\Error($this->trans('errors.upload.access'));
134
        }
135
        return $sUploadDir;
136
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
137
138
    /**
139
     * Get the path to the upload dir
140
     *
141
     * @param string        $sFieldId               The filename
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 15 found
Loading history...
142
     *
143
     * @return string
144
     */
145
    protected function getUploadDir($sFieldId)
146
    {
147
        // Default upload dir
148
        $sDefaultUploadDir = $this->getOption('upload.default.dir');
149
        $sUploadDir = $this->getOption('upload.files.' . $sFieldId . '.dir', $sDefaultUploadDir);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
150
151
        return $this->_makeUploadDir($sUploadDir, $this->sUploadSubdir);
152
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
153
154
    /**
155
     * Get the path to the upload temp dir
156
     *
157
     * @return string
158
     */
159
    protected function getUploadTempDir()
160
    {
161
        // Default upload dir
162
        $sUploadDir = $this->getOption('upload.default.dir');
163
164
        return $this->_makeUploadDir($sUploadDir, 'tmp' . DIRECTORY_SEPARATOR);
165
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
166
167
    /**
168
     * Get the path to the upload temp file
169
     *
170
     * @return string
171
     */
172
    protected function getUploadTempFile()
173
    {
174
        $sUploadDir = $this->getOption('upload.default.dir');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
175
        $sUploadDir = rtrim(trim($sUploadDir), '/\\') . DIRECTORY_SEPARATOR;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
176
        $sUploadDir .= 'tmp' . DIRECTORY_SEPARATOR;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
177
        $sUploadTempFile = $sUploadDir . $this->sTempFile . '.json';
178
        if(!is_readable($sUploadTempFile))
179
        {
180
            throw new \Jaxon\Exception\Error($this->trans('errors.upload.access'));
181
        }
182
        return $sUploadTempFile;
183
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
184
185
    /**
186
     * Read uploaded files info from HTTP request data
187
     *
188
     * @return void
189
     */
190
    protected function readFromHttpData()
191
    {
192
        // Check validity of the uploaded files
193
        $aTempFiles = $this->xSupport->getUploadedFiles();
194
195
        // Copy the uploaded files from the temp dir to the user dir
196
        foreach($aTempFiles as $sVarName => $aFiles)
197
        {
198
            $this->aUserFiles[$sVarName] = [];
199
            // Get the path to the upload dir
200
            $sUploadDir = $this->getUploadDir($sVarName);
201
202
            foreach($aFiles as $aFile)
203
            {
204
                // Set the user file data
205
                $xUploadedFile = UploadedFile::fromHttpData($sUploadDir, $aFile);
206
                // All's right, move the file to the user dir.
207
                move_uploaded_file($aFile["tmp_name"], $xUploadedFile->path());
208
                $this->aUserFiles[$sVarName][] = $xUploadedFile;
209
            }
210
        }
211
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
212
213
    /**
214
     * Save uploaded files info to a temp file
215
     *
216
     * @return void
217
     */
218
    protected function saveToTempFile()
219
    {
220
        // Convert uploaded file to an array
221
        $aFiles = [];
222
        foreach($this->aUserFiles as $sVarName => $aUserFiles)
223
        {
224
            $aFiles[$sVarName] = [];
225
            foreach($aUserFiles as $aUserFile)
226
            {
227
                $aFiles[$sVarName][] = $aUserFile->toTempData();
228
            }
229
        }
230
        // Save upload data in a temp file
231
        $sUploadDir = $this->getUploadTempDir();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
232
        $this->sTempFile = uniqid();
233
        file_put_contents($sUploadDir . $this->sTempFile . '.json', json_encode($aFiles));
234
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
235
236
    /**
237
     * Read uploaded files info from a temp file
238
     *
239
     * @return void
240
     */
241
    protected function readFromTempFile()
242
    {
243
        // Upload temp file
244
        $sUploadTempFile = $this->getUploadTempFile();
245
        $aFiles = json_decode(file_get_contents($sUploadTempFile), true);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
246
        foreach($aFiles as $sVarName => $aUserFiles)
247
        {
248
            $this->aUserFiles[$sVarName] = [];
249
            foreach($aUserFiles as $aUserFile)
250
            {
251
                $this->aUserFiles[$sVarName][] = UploadedFile::fromTempData($aUserFile);
252
            }
253
        }
254
        unlink($sUploadTempFile);
255
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
256
257
    /**
258
     * Inform this plugin that other plugin can process the current request
259
     *
260
     * @return void
261
     */
262
    public function noRequestPluginFound()
263
    {
264
        if(count($_FILES) > 0)
265
        {
266
            $this->bRequestIsHttpUpload = true;
267
        }
268
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
269
270
    /**
271
     * @inheritDoc
272
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
273
    public function canProcessRequest()
274
    {
275
        return (count($_FILES) > 0 || ($this->sTempFile));
276
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
277
278
    /**
279
     * Process the uploaded files in the HTTP request
280
     *
281
     * @return boolean
282
     */
283
    public function processRequest()
284
    {
285
        if(!$this->canProcessRequest())
286
        {
287
            return false;
288
        }
289
290
        if(count($_FILES) > 0)
291
        {
292
            // Ajax or Http request with upload
293
            $this->readFromHttpData();
294
295
            if($this->bRequestIsHttpUpload)
296
            {
297
                // Process an HTTP upload request
298
                // This requires to set the response to be returned.
299
                $xResponse = new UploadResponse();
300
                try
301
                {
302
                    $this->saveToTempFile();
303
                    $xResponse->setUploadedFile($this->sTempFile);
304
                }
305
                catch(Exception $e)
306
                {
307
                    $xResponse->setErrorMessage($e->getMessage());
308
                }
309
                jaxon()->di()->getResponseManager()->append($xResponse);
310
            }
311
        }
312
        elseif(($this->sTempFile))
313
        {
314
            // Ajax request following and HTTP upload
315
            $this->readFromTempFile();
316
        }
317
318
        return true;
319
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 0 found
Loading history...
320
}
321