Completed
Push — feature/EVO-8294-fileUpload ( f76403 )
by
unknown
65:32
created

RequestManager   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 7

Importance

Changes 0
Metric Value
wmc 15
lcom 0
cbo 7
dl 0
loc 102
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
C updateFileRequest() 0 46 11
B extractFileFromString() 0 35 4
1
<?php
2
/**
3
 * Handles REQUEST file specific actions
4
 */
5
6
namespace Graviton\FileBundle\Manager;
7
8
use Symfony\Component\HttpFoundation\File\UploadedFile;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\File\File;
11
use Symfony\Component\Filesystem\Filesystem;
12
13
/**
14
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
15
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
16
 * @link     http://swisscom.ch
17
 */
18
class RequestManager
19
{
20
    /**
21
     * Simple RAW http request parser.
22
     * Ideal for PUT requests where PUT is streamed but you still need the data.
23
     *
24
     * @param Request $request Sf data request
25
     * @return Request
26
     */
27
    public function updateFileRequest(Request $request)
28
    {
29
        $input = $request->getContent();
30
        $server = $request->server;
31
        $contentType = $server->get('CONTENT_TYPE', $server->get('HTTP_CONTENT_TYPE'));
32
        $data = [];
33
34
        // grab multipart boundary from content type header
35
        preg_match('/boundary=(.*)$/', $contentType, $matches);
36
37
        // content type is probably regular form-encoded
38
        if (!count($matches)) {
39
            // Check if content is binary, convert to file upload
40
            if ($request->files->count() == 0 && preg_match('~[^\x20-\x7E\t\r\n]~', $input) > 0) {
41
                $file = $this->extractFileFromString($input);
0 ignored issues
show
Bug introduced by
It seems like $input defined by $request->getContent() on line 29 can also be of type resource; however, Graviton\FileBundle\Mana...extractFileFromString() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
42
                $request->files->add([$file]);
43
            }
44
            return $request;
45
        }
46
47
        $contentBlocks = preg_split("/-+$matches[1]/", $input);
48
49
        // determine content blocks usage
50
        foreach ($contentBlocks as $contentBlock) {
51
            if (empty($contentBlock)) {
52
                continue;
53
            }
54
            preg_match('/name=\"(.*?)\"[^"]/i', $contentBlock, $matches);
55
            $name = isset($matches[1]) ? $matches[1] : '';
56
            if ('upload' !== $name) {
57
                preg_match('/name=\"([^\"]*)\"[\n|\r]+([^\n\r].*)?\r$/s', $contentBlock, $matches);
58
                $contentBlock = array_key_exists(2, $matches) ? $matches[2]: $contentBlock;
59
            }
60
            $data[$name] = $contentBlock;
61
        }
62
63
        if (array_key_exists('metadata', $data)) {
64
            $request->request->set('metadata', $data['metadata']);
65
        }
66
        if (array_key_exists('upload', $data)) {
67
            $file = $this->extractFileFromString($data['upload']);
68
            $request->files->add([$file]);
69
        }
70
71
        return $request;
72
    }
73
74
75
    /**
76
     * Extracts file data from request content
77
     * TODO solve direct POST file without form upload from curl
78
     * curl -X POST -d @image.jpg http://localhost:8000/file/ -v
79
     *
80
     * @param string $fileInfoString Information about uploaded files.
81
     *
82
     * @return UploadedFile
83
     */
84
    private function extractFileFromString($fileInfoString)
85
    {
86
        $str = (string) $fileInfoString;
87
        $tmpName = $fileName = date('Y-m-d_H-i-s') . '_' . md5($str);
88
89
        $isBinary = (preg_match('~[^\x20-\x7E\t\r\n]~', $str) > 0);
90
91
        if ($isBinary) {
92
            $fileContent = ltrim($str);
93
        } else {
94
            // Original Name
95
            preg_match('/filename=\"(.*?)\"/i', $str, $matches);
96
            if (array_key_exists(1, $matches)) {
97
                $fileName = preg_replace('/\s+/', '-', $matches[1]);
98
            }
99
            $fileInfo = explode("\r\n\r\n", ltrim($str), 2);
100
            $fileContent = substr($fileInfo[1], 0, -2);
101
        }
102
103
        $dir = ini_get('upload_tmp_dir');
104
        $dir = (empty($dir)) ? sys_get_temp_dir() : $dir;
105
        $tmpFile = $dir . DIRECTORY_SEPARATOR . $tmpName;
106
107
        // create temporary file;
108
        $filesystem = new Filesystem();
109
        $filesystem->dumpFile($tmpFile, $fileContent, 0755);
110
        $file = new File($tmpFile);
111
112
        return new UploadedFile(
113
            $file->getRealPath(),
114
            $fileName,
115
            $file->getMimeType(),
116
            $file->getSize()
117
        );
118
    }
119
}
120