Complex classes like Kohana_Upload_File often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Kohana_Upload_File, and based on these observations, apply Extract Interface, too.
1 | <?php defined('SYSPATH') OR die('No direct script access.'); |
||
12 | class Kohana_Upload_File { |
||
13 | |||
14 | protected $_source; |
||
15 | |||
16 | protected $_server; |
||
17 | |||
18 | protected $_path; |
||
19 | |||
20 | protected $_temp; |
||
21 | |||
22 | protected $_filename; |
||
23 | |||
24 | protected $_transformations = array(); |
||
25 | |||
26 | protected $_thumbnails = array(); |
||
27 | |||
28 | protected $_extracted_from_source = FALSE; |
||
29 | |||
30 | |||
31 | 29 | public function __construct($server, $path, $filename = NULL) |
|
32 | { |
||
33 | 29 | $this->server($server); |
|
34 | 29 | $this->_path = $path; |
|
35 | |||
36 | 29 | if ($filename !== NULL) |
|
37 | 29 | { |
|
38 | 1 | $this->_filename = $filename; |
|
39 | 1 | } |
|
40 | 29 | } |
|
41 | |||
42 | /** |
||
43 | * Get / Set the path for the image on the server |
||
44 | * @param string $path |
||
45 | * @return string|Upload_File |
||
46 | */ |
||
47 | 22 | public function path($path = NULL) |
|
48 | { |
||
49 | 22 | if ($path !== NULL) |
|
50 | 22 | { |
|
51 | 19 | $this->_path = $path; |
|
52 | |||
53 | 19 | return $this; |
|
54 | } |
||
55 | |||
56 | 5 | return $this->_path; |
|
57 | } |
||
58 | |||
59 | 2 | public function move_to_server($new_server) |
|
91 | |||
92 | /** |
||
93 | * Get / Set the source. Automatically set the source_type |
||
94 | * |
||
95 | * @param mixed $source |
||
96 | * @return mixed |
||
97 | */ |
||
98 | 24 | public function source($source = NULL) |
|
99 | { |
||
100 | 24 | if ($source !== NULL) |
|
101 | 24 | { |
|
102 | 22 | $this->_source = Upload_Source::factory($source); |
|
103 | |||
104 | 22 | if ($this->_source->type() === Upload_Source::TYPE_TEMP) |
|
105 | 22 | { |
|
106 | 5 | $this->temp()->directory(dirname($source)); |
|
107 | 5 | $this->filename(basename($source)); |
|
108 | 5 | } |
|
109 | |||
110 | 22 | return $this; |
|
111 | } |
||
112 | |||
113 | 20 | return $this->_source; |
|
114 | } |
||
115 | |||
116 | /** |
||
117 | * Get / Set transformations |
||
118 | * @param array $transformations |
||
119 | * @return array|Upload_File |
||
120 | */ |
||
121 | 1 | public function transformations(array $transformations = NULL) |
|
122 | { |
||
123 | 1 | if ($transformations !== NULL) |
|
124 | 1 | { |
|
125 | 1 | $this->_transformations = $transformations; |
|
126 | |||
127 | 1 | return $this; |
|
128 | } |
||
129 | |||
130 | 1 | return $this->_transformations; |
|
131 | } |
||
132 | |||
133 | |||
134 | /** |
||
135 | * Get / Set thumbnails |
||
136 | * @param array $thumbnails |
||
137 | * @return array|Upload_File |
||
138 | */ |
||
139 | 5 | public function thumbnails(array $thumbnails = NULL) |
|
140 | { |
||
141 | 5 | if ($thumbnails !== NULL) |
|
142 | 5 | { |
|
143 | 3 | $this->_thumbnails = $thumbnails; |
|
144 | |||
145 | 3 | return $this; |
|
146 | } |
||
147 | |||
148 | 5 | return $this->_thumbnails; |
|
149 | } |
||
150 | |||
151 | /** |
||
152 | * Get the Upload_Temp object. Create it if it's not already created |
||
153 | * @return Upload_Temp |
||
154 | */ |
||
155 | 24 | public function temp() |
|
156 | { |
||
157 | 24 | if ( ! $this->_temp) |
|
158 | 24 | { |
|
159 | 24 | $this->_temp = Upload_Temp::factory(); |
|
160 | 24 | } |
|
161 | |||
162 | 24 | return $this->_temp; |
|
163 | } |
||
164 | |||
165 | /** |
||
166 | * Get the upload server |
||
167 | * @return Upload_Server |
||
168 | */ |
||
169 | 29 | public function server($server = NULL) |
|
170 | { |
||
171 | 29 | if ($server !== NULL) |
|
172 | 29 | { |
|
173 | 29 | $this->_server = $server; |
|
174 | 29 | return $this; |
|
175 | } |
||
176 | |||
177 | 5 | return Upload_Server::instance($this->_server); |
|
178 | } |
||
179 | |||
180 | /** |
||
181 | * Get / Set the current filename |
||
182 | * @param string $filename |
||
183 | * @return string|Upload_File |
||
184 | */ |
||
185 | 28 | public function filename($filename = NULL) |
|
206 | |||
207 | 2 | public function transform() |
|
208 | { |
||
209 | 2 | if (($this->_transformations OR $this->_thumbnails) AND @ getimagesize($this->file())) |
|
210 | 2 | { |
|
211 | 1 | if ($this->_transformations) |
|
212 | 1 | { |
|
213 | 1 | Upload_Util::transform_image($this->file(), $this->file(), $this->transformations()); |
|
214 | 1 | } |
|
215 | |||
216 | 1 | $this->generate_thumbnails(); |
|
217 | 1 | } |
|
218 | 2 | } |
|
219 | |||
220 | /** |
||
221 | * Save the current source to the temp folder |
||
222 | */ |
||
223 | 15 | public function save_to_temp() |
|
224 | { |
||
225 | 14 | if ( ! $this->source()) |
|
226 | 15 | throw new Kohana_Exception("Cannot move file to temp directory, source does not exist, path :path, filename :filename", array(':path' => $this->path(), ':filename' => $this->filename())); |
|
227 | |||
228 | 14 | if ( ! $this->source()->copied()) |
|
229 | 14 | { |
|
230 | 14 | $this->source()->copy_to($this->temp()->directory_path()); |
|
231 | 14 | $this->filename($this->source()->filename()); |
|
232 | 14 | } |
|
233 | |||
234 | 14 | return $this; |
|
235 | } |
||
236 | |||
237 | /** |
||
238 | * Generate the thumbnails if they are not generated |
||
239 | * |
||
240 | * @return Upload_File $this |
||
241 | */ |
||
242 | 3 | public function generate_thumbnails() |
|
254 | |||
255 | /** |
||
256 | * Save the file by moving it from temporary to the upload server |
||
257 | * Generate the thumbnails if nesessary |
||
258 | * @return Upload_File $this |
||
259 | */ |
||
260 | 2 | public function save() |
|
280 | |||
281 | /** |
||
282 | * Clear temporary files |
||
283 | * @return Upload_File $this |
||
284 | */ |
||
285 | 18 | public function clear() |
|
286 | { |
||
287 | 18 | $this->temp()->clear(); |
|
288 | |||
289 | 18 | return $this; |
|
290 | } |
||
291 | |||
292 | /** |
||
293 | * Delete the current file on the server and clear temporary files |
||
294 | * @return Upload_File $this |
||
295 | */ |
||
296 | 2 | public function delete() |
|
297 | { |
||
298 | 2 | $this->server()->unlink($this->full_path()); |
|
299 | |||
300 | 2 | foreach ($this->thumbnails() as $thumbnail => $transformations) |
|
301 | { |
||
302 | 1 | $this->server()->unlink($this->full_path($thumbnail)); |
|
303 | 2 | } |
|
304 | |||
305 | 2 | $this->clear(); |
|
306 | |||
307 | 2 | return $this; |
|
308 | } |
||
309 | |||
310 | /** |
||
311 | * Get the current filename (temp or server) |
||
312 | * @param string $thumbnail |
||
313 | * @return string |
||
314 | */ |
||
315 | 20 | public function file($thumbnail = NULL) |
|
316 | { |
||
317 | 20 | return $this->location('realpath', $thumbnail); |
|
318 | } |
||
319 | |||
320 | /** |
||
321 | * Get the current url (temp or server) |
||
322 | * @param string $thumbnail |
||
323 | * @param mixed $protocol |
||
324 | * @return string |
||
325 | */ |
||
326 | 1 | public function url($thumbnail = NULL) |
|
327 | { |
||
328 | 1 | return $this->location('url', $thumbnail); |
|
329 | } |
||
330 | |||
331 | /** |
||
332 | * Get the full path with the filename |
||
333 | * @param string $thumbnail |
||
334 | * @return string |
||
335 | */ |
||
336 | 4 | public function full_path($thumbnail = NULL) |
|
337 | { |
||
338 | 4 | return Upload_Util::combine($this->path(), $thumbnail, $this->filename()); |
|
339 | } |
||
340 | |||
341 | 1 | public function temp_source() |
|
342 | { |
||
343 | 1 | if ( ! $this->_source OR ! $this->filename()) |
|
344 | 1 | return NULL; |
|
345 | |||
346 | 1 | return $this->temp()->directory().'/'.$this->filename(); |
|
347 | } |
||
348 | |||
349 | 20 | protected function location($method, $thumbnail = NULL) |
|
370 | |||
371 | /** |
||
372 | * Check if its empty (no filename or source) |
||
373 | * @return boolean |
||
374 | */ |
||
375 | 14 | public function is_empty() |
|
376 | { |
||
377 | 14 | return ! $this->filename(); |
|
378 | } |
||
379 | |||
380 | 2 | public function __toString() |
|
381 | { |
||
382 | 2 | return (string) $this->filename(); |
|
383 | } |
||
384 | } |
||
385 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.