Skip to content

Commit e4023f3

Browse files
authored
Merge pull request #7 from bboure/master
Improve `UploadFromUrl::extendOptions()` and fix PSR-2 codestlye
2 parents 92ce471 + 663c0c2 commit e4023f3

File tree

5 files changed

+130
-77
lines changed

5 files changed

+130
-77
lines changed

src/FileFromUrlValidator.php

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* @link http://github.com/igogo5yo/yii2-upload-from-url
1010
*/
1111
namespace igogo5yo\uploadfromurl;
12+
1213
use Yii;
1314
use igogo5yo\uploadfromurl\UploadFromUrl;
1415
use yii\helpers\FileHelper;
@@ -84,19 +85,40 @@ protected function validateValue($file)
8485
switch ($file->error) {
8586
case UPLOAD_ERR_OK:
8687
if ($this->maxSize !== null && $file->size > $this->maxSize) {
87-
return [$this->tooBig, ['file' => $file->name, 'limit' => $this->getSizeLimit()]];
88+
return [
89+
$this->tooBig,
90+
[
91+
'file' => $file->name,
92+
'limit' => $this->getSizeLimit(),
93+
'formattedLimit' => Yii::$app->formatter->asShortSize($this->getSizeLimit()),
94+
]
95+
];
8896
} elseif ($this->minSize !== null && $file->size < $this->minSize) {
89-
return [$this->tooSmall, ['file' => $file->name, 'limit' => $this->minSize]];
97+
return [
98+
$this->tooSmall,
99+
[
100+
'file' => $value->name,
101+
'limit' => $this->minSize,
102+
'formattedLimit' => Yii::$app->formatter->asShortSize($this->minSize),
103+
],
104+
];
90105
} elseif (!empty($this->extensions) && !$this->validateExtension($file)) {
91106
return [$this->wrongExtension, ['file' => $file->name, 'extensions' => implode(', ', $this->extensions)]];
92-
} elseif (!empty($this->mimeTypes) && !in_array($file->type, $this->mimeTypes, false)) {
107+
} elseif (!empty($this->mimeTypes) && !$this->validateMimeType($file)) {
93108
return [$this->wrongMimeType, ['file' => $file->name, 'mimeTypes' => implode(', ', $this->mimeTypes)]];
94-
} else {
95-
return null;
96109
}
110+
111+
return null;
97112
case UPLOAD_ERR_INI_SIZE:
98113
case UPLOAD_ERR_FORM_SIZE:
99-
return [$this->tooBig, ['file' => $file->name, 'limit' => $this->getSizeLimit()]];
114+
return [
115+
$this->tooBig,
116+
[
117+
'file' => $file->name,
118+
'limit' => $this->getSizeLimit(),
119+
'formattedLimit' => Yii::$app->formatter->asShortSize($this->getSizeLimit()),
120+
]
121+
];
100122
case UPLOAD_ERR_PARTIAL:
101123
Yii::warning('File was only partially uploaded: ' . $file->name, __METHOD__);
102124
break;
@@ -135,4 +157,22 @@ protected function validateExtension($file)
135157
}
136158
return true;
137159
}
160+
161+
private function buildMimeTypeRegexp($mask)
162+
{
163+
return '/^' . str_replace('\*', '.*', preg_quote($mask, '/')) . '$/';
164+
}
165+
166+
protected function validateMimeType($file)
167+
{
168+
foreach ($this->mimeTypes as $mimeType) {
169+
if ($mimeType === $file->type) {
170+
return true;
171+
}
172+
if (strpos($mimeType, '*') !== false && preg_match($this->buildMimeTypeRegexp($mimeType), $file->type)) {
173+
return true;
174+
}
175+
}
176+
return false;
177+
}
138178
}

src/UploadFromUrl.php

Lines changed: 68 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,24 @@
1919
/**
2020
* UploadFileByURL represents the information for an file by url address.
2121
*
22-
* You can call [[initWithModel()]] or [[initWithUrl()]] or [[initWithUrlAndModel()]] with to retrieve the instance of file object,
23-
* and then use [[saveAs()]] to save it on the server.
22+
* You can call [[initWithModel()]] or [[initWithUrl()]] or [[initWithUrlAndModel()]]
23+
* with to retrieve the instance of file object, and then use [[saveAs()]] to save it on the server.
2424
* You may also query other information about the file, including [[name]],
2525
* [[extension]], [[type]], [[size]] etc.
2626
*
27-
*
2827
* @author Skliar Ihor <skliar.ihor@gmail.com>
2928
* @since 1.0
3029
*/
3130
class UploadFromUrl extends Object
3231
{
33-
/**
34-
* @var string the original name of the file being uploaded
35-
*/
36-
public $name;
37-
/**
38-
* @var string the name of the file without extension being uploaded
39-
*/
40-
public $baseName;
32+
/**
33+
* @var string the original name of the file being uploaded
34+
*/
35+
public $name;
36+
/**
37+
* @var string the name of the file without extension being uploaded
38+
*/
39+
public $baseName;
4140
/**
4241
* @var string the MIME-type of the uploaded file (such as "image/gif").
4342
* Since this MIME type is not checked on the server side, do not take this value for granted.
@@ -58,10 +57,10 @@ class UploadFromUrl extends Object
5857
*/
5958
public $extension;
6059

61-
public $url;
62-
public $model;
63-
public $attribute;
64-
public $isWithModel = false;
60+
public $url;
61+
public $model;
62+
public $attribute;
63+
public $isWithModel = false;
6564

6665
/**
6766
* String output.
@@ -74,73 +73,74 @@ public function __toString()
7473
return $this->name;
7574
}
7675

77-
public static function initWithUrl($url)
76+
public static function initWithUrl($url)
7877
{
7978
return self::createInstance([
80-
'url' => $url
81-
]);
79+
'url' => $url
80+
]);
8281
}
8382

84-
public static function initWithModel($model, $attribute)
85-
{
83+
public static function initWithModel($model, $attribute)
84+
{
8685
return self::createInstance([
87-
'url' => $model->{$attribute},
88-
'isWithModel' => true,
89-
'model' => $model,
90-
'attribute' => $attribute,
91-
]);
92-
}
86+
'url' => $model->{$attribute},
87+
'isWithModel' => true,
88+
'model' => $model,
89+
'attribute' => $attribute,
90+
]);
91+
}
9392

94-
public static function initWithUrlAndModel($url, $model, $attribute)
95-
{
93+
public static function initWithUrlAndModel($url, $model, $attribute)
94+
{
9695
return self::createInstance([
97-
'url' => $url,
98-
'isWithModel' => true,
99-
'model' => $model,
100-
'attribute' => $attribute,
101-
]);
102-
}
96+
'url' => $url,
97+
'isWithModel' => true,
98+
'model' => $model,
99+
'attribute' => $attribute,
100+
]);
101+
}
103102

104103
public static function getInstance($model, $attribute)
105104
{
106105
return self::initWithModel($model, $attribute);
107106
}
108107

109-
public function saveAs($file, $saveToModel = false)
110-
{
111-
if ($saveToModel && $this->isWithModel) {
112-
$this->model->{$this->attribute} = $file;
113-
} else if ($this->isWithModel) {
114-
$this->model->{$this->attribute} = null;
115-
}
116-
117-
return copy($this->url, $file);
118-
}
119-
120-
protected static function createInstance($options)
121-
{
122-
$options = self::extendOptions($options);
123-
return new static($options);
124-
}
125-
126-
protected static function extendOptions(array $options)
127-
{
128-
$parsed_url = parse_url($options['url']);
129-
$headers = @get_headers($options['url'], 1);
130-
131-
if (!$parsed_url || !$headers || !preg_match('/^(HTTP)(.*)(200)(.*)/i', $headers[0])) {
132-
$options['error'] = UPLOAD_ERR_NO_FILE;
133-
}
108+
public function saveAs($file, $saveToModel = false)
109+
{
110+
if ($saveToModel && $this->isWithModel) {
111+
$this->model->{$this->attribute} = $file;
112+
} elseif ($this->isWithModel) {
113+
$this->model->{$this->attribute} = null;
114+
}
134115

135-
$fname = explode('/', $parsed_url['path']);
136-
$options['name'] = end($fname);
137-
$options['baseName'] = explode('.', $options['name'], 1);
138-
$ext = explode('.', $options['name']);
139-
$options['extension'] = mb_strtolower(end($ext));
116+
return copy($this->url, $file);
117+
}
140118

141-
$options['size'] = isset($headers['Content-Length']) ? $headers['Content-Length'] : 0;
142-
$options['type'] = isset($headers['Content-Type']) ? $headers['Content-Type'] : FileHelper::getMimeTypeByExtension($options['name']);
119+
protected static function createInstance($options)
120+
{
121+
$options = self::extendOptions($options);
122+
return new static($options);
123+
}
143124

144-
return $options;
145-
}
125+
protected static function extendOptions(array $options)
126+
{
127+
$parsed_url = parse_url($options['url']);
128+
$headers = get_headers($options['url'], 1);
129+
130+
if (!$parsed_url || !$headers || !preg_match('/^(HTTP)(.*)(200)(.*)/i', $headers[0])) {
131+
$options['error'] = UPLOAD_ERR_NO_FILE;
132+
}
133+
134+
$options['name'] = isset($parsed_url['path']) ? pathinfo($parsed_url['path'], PATHINFO_BASENAME) : '';
135+
$options['baseName'] = isset($parsed_url['path']) ? pathinfo($parsed_url['path'], PATHINFO_FILENAME) : '';
136+
$options['extension'] = isset($parsed_url['path'])
137+
? mb_strtolower(pathinfo($parsed_url['path'], PATHINFO_EXTENSION))
138+
: '';
139+
$options['size'] = isset($headers['Content-Length']) ? $headers['Content-Length'] : 0;
140+
$options['type'] = isset($headers['Content-Type'])
141+
? $headers['Content-Type']
142+
: FileHelper::getMimeTypeByExtension($options['name']);
143+
144+
return $options;
145+
}
146146
}

tests/UploadFromUrlTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,16 @@ public function testFour()
7373
$this->assertTrue(!empty($file->name));
7474
$this->assertTrue(!empty($file->extension));
7575
}
76-
}
76+
77+
public function testOptions()
78+
{
79+
$file = UploadFromUrl::initWithUrl(self::FILE_URL);
80+
81+
$this->assertEquals('yii', $file->baseName);
82+
$this->assertEquals('png', $file->extension);
83+
$this->assertEquals('yii.png', $file->name);
84+
// Inthis test, size is non deterministic (Yii could change it's logo any time).
85+
// Making sure it is > 0 is enough
86+
$this->assertGreaterThan(0, $file->size);
87+
}
88+
}

tests/bootstrap.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717
'baseUrl' => '/',
1818
],
1919
],
20-
]);
20+
]);

tests/models/Model.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ class Model extends \yii\base\Model
1515
{
1616
public $image;
1717

18+
1819
public function rules()
1920
{
2021
return [
2122
['image', 'igogo5yo\uploadfromurl\FileFromUrlValidator', 'extensions' => 'csv', 'mimeTypes' => 'text/plain'],
2223
['image', 'safe']
2324
];
2425
}
25-
}
26+
}

0 commit comments

Comments
 (0)