Completed
Push — 4.0 ( 0fc1f3...2aa397 )
by Marco
02:59
created

File   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 191
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 6.75%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 30
c 2
b 0
f 0
lcom 1
cbo 1
dl 0
loc 191
ccs 5
cts 74
cp 0.0675
rs 10

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 2
A getTemporaryName() 0 5 1
A getLocalName() 0 8 2
A getFileName() 0 5 1
A getSlug() 0 5 1
A getContentType() 0 5 1
A getSize() 0 5 1
A getUploadTime() 0 5 1
A getFileData() 0 10 2
A fileIsSaved() 0 9 3
A load() 0 13 3
B save() 0 23 5
A loadFromUploadedFile() 0 21 2
A createSlug() 0 21 3
A fromUploadedFiles() 0 13 2
1
<?php namespace Comodojo\Dispatcher\Request;
2
3
use \Exception;
4
use \Comodojo\Exception\DispatcherException;
5
6
/**
7
 * @package     Comodojo Dispatcher
8
 * @author      Marco Giovinazzi <[email protected]>
9
 * @author      Marco Castiello <[email protected]>
10
 * @license     GPL-3.0+
11
 *
12
 * LICENSE:
13
 *
14
 * This program is free software: you can redistribute it and/or modify
15
 * it under the terms of the GNU Affero General Public License as
16
 * published by the Free Software Foundation, either version 3 of the
17
 * License, or (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public License
25
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26
 */
27
28
class File {
29
30
    private $path  = '';
31
32
    private $slug  = '';
33
34
    private $fname = '';
35
36
    private $tname = '';
37
38
    private $upld  = '';
39
40
    private $ctype = 'text/plain';
41
42
    private $size  = 0;
43
44
    public function __construct($fileControl = null, $repository = '') {
45
46
        $this->path = $repository;
47
48
        if (!is_null($fileControl)) {
49
50
            $this->load($fileControl);
51
52
        }
53
54
    }
55
56
    public function getTemporaryName() {
57
58
        return $this->tname;
59
60
    }
61
62
    public function getLocalName() {
63
64
        if (!empty($this->path))
65
            return $this->path . "/" . $this->slug;
66
        else
67
            return '';
68
69
    }
70
71
    public function getFileName() {
72
73
        return $this->fname;
74
75
    }
76
77
    public function getSlug() {
78
79
        return $this->slug;
80
81
    }
82
83
    public function getContentType() {
84
85
        return $this->ctype;
86
87
    }
88
89
    public function getSize() {
90
91
        return $this->size;
92
93
    }
94
95
    public function getUploadTime() {
96
97
        return $this->upld;
98
99
    }
100
101
    public function getFileData() {
102
103
        $file = $this->getTemporaryName();
104
105
        if (file_exists($file))
106
            return file_get_contents($file);
107
108
        throw new DispatcherException("File does not exists");
109
110
    }
111
112
    public function fileIsSaved() {
113
114
        return (
115
            !empty($this->path) &&
116
            !empty($this->slug) &&
117
            file_exists($this->getLocalName())
118
        );
119
120
    }
121
122
    public function load($slugOrControl) {
0 ignored issues
show
Coding Style introduced by
load 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...
123
124
        if (isset($_FILES) && isset($_FILES[$slugOrControl])) {
125
126
            $this->loadFromUploadedFile($slugOrControl);
127
128
            return $this;
129
130
        }
131
132
        throw new DispatcherException("The requested file has not been uploaded");
133
134
    }
135
136
    public function save($repository = '') {
137
138
        if (!empty($repository)) {
139
140
            $this->path = $repository;
141
142
        }
143
144
        if (!empty($this->path) && file_exists($this->path)) {
145
146
            if (move_uploaded_file($this->getTemporaryName(), $this->getLocalName())) {
147
148
                return $this->fileIsSaved();
149
150
            }
151
152
            throw new DispatcherException("Unable to save file");
153
154
        }
155
156
        throw new DispatcherException("Repository path is not available");
157
158
    }
159
160
    private function loadFromUploadedFile($fileControl) {
0 ignored issues
show
Coding Style introduced by
loadFromUploadedFile 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...
161
162
        if (isset($_FILES[$fileControl])) {
163
164
            $file = $_FILES[$fileControl];
165
166
            $this->tname = $file['tmp_name'];
167
            $this->fname = $file['name'];
168
            $this->ctype = $file['type'];
169
            $this->size  = intval($file['size']);
170
            $this->upld  = filectime($file['tmp_name']);
0 ignored issues
show
Documentation Bug introduced by
The property $upld was declared of type string, but filectime($file['tmp_name']) is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
171
172
            $this->createSlug();
173
174
            return $this;
175
176
        }
177
178
        throw new DispatcherException("File not uploaded");
179
180
    }
181
182
    private function createSlug() {
183
184
        preg_match_all("/[a-z0-9]+/", iconv("UTF-8", "ASCII//TRANSLIT", strtolower(preg_replace('/\..*?$/', '', $this->fname))), $matches);
185
186
        $this->slug  = implode('-', $matches[0]);
187
188
        if (!empty($this->path)) {
189
190
            $files = glob($this->path . "/" . $slug . "*");
0 ignored issues
show
Bug introduced by
The variable $slug does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
191
192
            $count = count ($files);
193
194
            if ($count > 0) {
195
196
                $this->slug .= "-" . $count;
197
198
            }
199
200
        }
201
202
    }
203
204 5
    public static function fromUploadedFiles($repository = '') {
0 ignored issues
show
Coding Style introduced by
fromUploadedFiles 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...
205
206 5
        $files = array();
207
208 5
        foreach ($_FILES as $idx => $data) {
209
210
            $files[] = new File($idx, $repository);
211
212 5
        }
213
214 5
        return $files;
215
216
    }
217
218
}
219