統計
| ブランチ: | リビジョン:

pictcode / app / Plugin / UploadPack / README.textile @ b3a58ce1

履歴 | 表示 | アノテート | ダウンロード (14.031 KB)

1
h1. UploadPack
2

    
3
"!https://pledgie.com/campaigns/7880.png?skin_name=chrome!(Using it in production? Share some love...)":https://www.pledgie.com/campaigns/7880
4

    
5
UploadPack is a plugin that makes file uploads in CakePHP as easy as possible. It works with almost no configuration, but if you need more flexibility you can easily override default settings.
6

    
7
What's included:
8

    
9
h4. UploadBehavior
10

    
11
Attach it to your model, it will detect any uploaded file and save it to disk. It can even automatically generate thumbnails of uploaded images.
12

    
13
h4. UploadHelper
14

    
15
Use it in your views to display uploaded images or links to files in general.
16

    
17
h2. Installation
18

    
19
# Download this: _http://github.com/szajbus/uploadpack/zipball/master_
20
# Unzip that download.
21
# Copy the resulting folder to _app/plugins_
22
# Rename the folder you just copied to _upload_pack_
23

    
24
h2. Usage
25

    
26
Look at an example.
27

    
28
Scenario: Let users upload their avatars and then display them in two styles - original size and thumbnail.
29

    
30
Solution:
31

    
32
We'll need @User@ model with @avatar_file_name@ field.
33

    
34
<pre><code>CREATE table users (
35
	id int(10) unsigned NOT NULL auto_increment,
36
	login varchar(20) NOT NULL,
37
	avatar_file_name varchar(255)
38
);
39
</code></pre>
40

    
41
Attach @UploadBehavior@ to @User@ model and set it up to handle avatars.
42

    
43
<pre><code><?php
44
	class User extends AppModel {
45
		var $name = 'User';
46
		var $actsAs = array(
47
			'UploadPack.Upload' => array(
48
				'avatar' => array(
49
					'styles' => array(
50
						'thumb' => '80x80'
51
					)
52
				)
53
			)
54
		);
55
	}
56
?>
57
</code></pre>
58

    
59
That's all we need to do with our model. We defined one thumbnail style named 'thumb' which means that uploaded image's thumnbnail of 80x80 pixels size will be generated and saved to disk together with original image.
60

    
61
We didn't touch any other configuration settings so files will be saved as @webroot/upload/:model/:id/:basename_:style.:extension@ (with :keys appropriately substituted at run time). Make sure that @webroot/upload/users@ folder is writeable.
62

    
63
Let's upload a file now. We need to add a file field to a standard "create user" form. Your form must have the right enctype attribute to support file uploads, e.g. @$form->create('Users', array('type' => 'file'));@. Note that we omit the field's @_file_name@ suffix here.
64

    
65
<pre><code><?php echo $form->file('User.avatar') ?></code></pre>
66

    
67
The last thing to do is to handle form-submit in a controller.
68

    
69
<pre><code><?php
70
class UsersController extends AppController {
71
	var $name = 'Users';
72
	var $uses = array('User');
73
	var $helpers = array('Form', 'UploadPack.Upload');
74

    
75
	function create() {
76
		if (!empty($this->data)) {
77
			$this->User->create($this->data);
78
			if ($this->User->save()) {
79
				$this->redirect('/users/show/'.$this->User->id);
80
			}
81
		}
82
	}
83

    
84
	function show($id) {
85
		$this->set('user', $this->User->findById($id));
86
	}
87
}
88
?>
89
</code></pre>
90

    
91
Let's create @users/show.ctp@ view to see the results. Note that we've included UploadHelper in controller's $helpers.
92

    
93
<pre><code>That would be the original file:
94
<?php echo $this->Upload->uploadImage($user, 'User.avatar') ?>
95

    
96
And now it's thumbnail:
97
<?php echo $this->Upload->uploadImage($user, 'User.avatar', array('style' => 'thumb')) ?>
98
</code></pre>
99

    
100
That's how you create new records with uploaded files. Updating existing record would delete a file attached to it from disk.
101

    
102
Could it be any easier? Probably not. Is there more to offer? Yes.
103

    
104
h3. Advanced configuration
105

    
106
h4. You can validate uploaded files
107

    
108
@UploadBehavior@ provides some validation rules for you to use together with standard CakePHP validation mechanism.
109

    
110
Validate attachment's size:
111

    
112
<pre><code>var $validate = array(
113
	'avatar' => array(
114
		'maxSize' => array(
115
			'rule' => array('attachmentMaxSize', 1048576),
116
			'message' => 'Avatar can\'t be larger than 1MB'
117
		),
118
		'minSize' => array(
119
			'rule' => array('attachmentMinSize', 1024),
120
			'message' => 'Avatar can\'t be smaller than 1KB'
121
		)
122
	)
123
);
124
</code></pre>
125

    
126
Validate attachment's content type:
127

    
128
<pre><code>var $validate = array(
129
	'avatar' => array(
130
		'image1 => array(
131
			'rule' => array('attachmentContentType', 'image/jpeg'),
132
			'message' => 'Only jpegs please'
133
		),
134
		'image2' => array(
135
			'rule' => array('attachmentContentType', array('image/jpeg', 'image/gif')),
136
			'message' => 'Only jpegs or gifs please'
137
		),
138
		'image3' => array(
139
			'rule' => array('attachmentContentType', array('document/pdf', '/^image\/.+/')),
140
			'message' => 'Only pdfs or images please'
141
		)
142
	)
143
);
144
</code></pre>
145

    
146
Validate attachment's presence:
147

    
148
<pre><code>var $validate = array(
149
	'avatar' => array(
150
		'rule' => array('attachmentPresence'),
151
		'message' => 'Avatar is required'
152
	)
153
);
154
</code></pre>
155

    
156
Validate image size:
157
<pre><code>var $validate = array(
158
	'avatar' => array(
159
		'minWidth' => array(
160
			'rule' => array('minWidth', '100'),
161
			'message' => 'Photo must be at least 100 pixels wide'
162
		),
163
		'maxWidth' => array(
164
			'rule' => array('maxWidth', '600'),
165
			'message' => 'Photo can\'t be over 600 pixels wide'
166
		),
167
		'minHeight' => array(
168
			'rule' => array('minHeight', '100'),
169
			'message' => 'Photo must be at least 100 pixels wide'
170
		),
171
		'maxHeight' => array(
172
			'rule' => array('maxHeight', '600'),
173
			'message' => 'Photo can\'t be over 600 pixels wide'
174
		)
175
	)
176
);
177
</code></pre>
178

    
179
If you're editing a record that already has avatar attached and you don't supply a new one, record will be valid.
180

    
181
Validate php upload errors:
182
PHP: Error Messages Explained - Manual (http://www.php.net/manual/features.file-upload.errors.php)
183
<pre><code>var $validate = array(
184
	'avatar' => array(
185
		'checkIniSizeError' => array(
186
			'rule' => array('phpUploadError', UPLOAD_ERR_INI_SIZE),
187
			'message' => 'The uploaded file exceeds the upload_max_filesize directive in php.ini'
188
		),
189
		'checkSizesError' => array(
190
			'rule' => array('phpUploadError', array(UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE)),
191
			'message' => 'The uploaded file exceeds the upload_max_filesize directive in php.ini or MAX_FILE_SIZE directive that was specified in the HTML form'
192
		),
193
		'checkAllError' => array(
194
			'rule' => array('phpUploadError'),
195
			'message' => 'Can\'t upload'
196
		)
197
	)
198
);
199
</code></pre>
200

    
201
Validation options:
202

    
203
You can pass additional options to validation rules:
204

    
205
* *allowEmpty* - if set to _false_ will cause validation to fail if the file is not present. This option is not available for _attachmentPresence_ rule.
206

    
207
The example below return true if there is no upload files or jpeg.
208
<pre><code>var $validate = array(
209
	'avatar' => array(
210
		'rule' => array('attachmentContentType', 'image/jpeg'),
211
		'message' => 'Only jpegs please',
212
		'allowEmpty' => true
213
	)
214
);
215
</code></pre>
216

    
217
h4. You can change the path where the files are saved
218

    
219
<pre><code>var $actsAs = array(
220
	'UploadPack.Upload' => array(
221
		'avatar' => array(
222
			'path' => 'your/new/path'
223
		)
224
	)
225
);
226
</code></pre>
227

    
228
The path string can contain special :keys that will be substituted at run time with appropriate values. Here's the list of available @:keys@ with the values they're substituted with.
229

    
230
* *:app* - path to your app dir
231
* *:webroot* - path to your app's webroot dir
232
* *:model* - name of the model tableized with Inflector::tableize (would be 'users' for User model)
233
* *:id* - ID of the record
234
* *:basename* - basename of the uploaded file's original name (would be 'photo' for photo.jpg)
235
* *:extension* - extension of the uploaded file's original name (would be 'jpg' for photo.jpg)
236
* *:style* - name of the thumbnail's style
237
* *:attachment* - pluralized name of the attachment (for example 'avatars')
238
* *:hash* - md5 hash of the original filename + Security.salt
239

    
240
Default value for path is @:webroot/upload/:model/:id/:basename_:style.:extension@.
241

    
242
h4. You can change the url the helper points to when displaying or linking to uploaded files
243

    
244
This setting accepts all the :keys mentioned above and it's default value depends on path setting. For default path it would be defaults @/upload/:model/:id/:basename_:style.:extension@.
245

    
246
You probably won't need to change it too often, though.
247

    
248
h4. You can point to default url if the uploaded file is missing
249

    
250
If uploading an avatar is only a option to your users, you would probably want to have some default image being displayed if no image is uploaded by a user.
251

    
252
<pre><code>var $actsAs = array(
253
	'UploadPack.Upload' => array(
254
		'avatar' => array(
255
			'default_url' => 'path/to/default/image'
256
		)
257
	)
258
);
259
</code></pre>
260

    
261
This setting accepts all the @:keys@ mentioned above, but it's not set by default which results in usual url being returned even it the file does not exist.
262

    
263
h4. You can choose to automatically scale down images that are wider than the <code>maxWidth</code> specified in validation.
264

    
265
<pre><code>var $actsAs = array(
266
	'UploadPack.Upload' => array(
267
		'avatar' => array(
268
			'resizeToMaxWidth' => true
269
		)
270
	)
271
);
272
</code></pre>
273

    
274
h4. JPEG Quality
275

    
276
The jpeg quality can be set with the <code>quality</code> setting.
277

    
278
<pre><code>var $actsAs = array(
279
	'UploadPack.Upload' => array(
280
		'avatar' => array(
281
			'quality' => 95
282
		)
283
	)
284
);
285
</code></pre>
286

    
287
h4. Alpha Channel(PNG, GIF only)
288

    
289
The png and gif can use alpha channel <code>alpha</code> setting.
290

    
291
<pre><code>var $actsAs = array(
292
	'UploadPack.Upload' => array(
293
		'avatar' => array(
294
			'alpha' => true
295
		)
296
	)
297
);
298
</code></pre>
299

    
300
h4. You can choose another field for an external url
301

    
302
<pre><code>var $actsAs = array(
303
	'UploadPack.Upload' => array(
304
		'avatar' => array(
305
			'urlField' => 'gravatar'
306
		)
307
	)
308
);
309
</code></pre>
310

    
311
This way the user can paste an url or choose a file from their filesystem. The url will mimick usual uploading so it will still be validated and resized.
312

    
313
h4. Deleting a file attached to field
314

    
315
<pre><code>$model->data['avatar'] = null;
316
	$model->save();
317
</code></pre>
318

    
319
h3. More on styles
320

    
321
Styles are the definition of thumbnails that will be generated for original image. You can define as many as you want.
322

    
323
<pre><code>var $actsAs = array(
324
	'UploadPack.Upload' => array(
325
		'avatar' => array(
326
			'styles' => array(
327
				'big' => '200x200',
328
				'small' => '120x120',
329
				'thumb' => '80x80'
330
			)
331
		)
332
	)
333
);
334
</code></pre>
335

    
336
Be sure to have @:style@ key included in your path setting to differentiate file names. The original file is also saved and has 'original' as @:style@ value, so you don't need it to define it yourself.
337

    
338
If you want non-image files to be uploaded, define no styles at all. It does not make much sense to generate thumbnails for zip or pdf files.
339

    
340
You can specify any of the following resize modes for your styles:
341

    
342
* *100x80* - resize for best fit into these dimensions, with overlapping edges trimmed if original aspect ratio differs
343
* *[100x80]* - resize to fit these dimensions, with white banding if original aspect ratio differs (Michał's original resize method)
344
* *100w* - maintain original aspect ratio, resize to 100 pixels wide
345
* *80h* - maintain original aspect ratio, resize to 80 pixels high
346
* *80l* - maintain original aspect ratio, resize so that longest side is 80 pixels
347

    
348
h3. More on database table structure
349

    
350
The only database field you need to add to your model's table is @[field]_file_name@. Replace @[field]@ with chosen name (avatar for example).
351

    
352
There are two optional fields you can add: @[field]_content_type@ and @[field]_file_size@. If they're present they will be populated with uploaded file's content type and size in bytes respectively.
353

    
354
Model can have many uploaded files at once. For example define two fields in database table: @avatar_file_name@ and @logo_file_name@. Set up behavior:
355

    
356
<pre><code>var $actsAs = array(
357
	'UploadPack.Upload' => array(
358
		'avatar' => array(),
359
		'logo' => array()
360
		)
361
	)
362
);
363
</code></pre>
364

    
365
h3. Using the helper
366

    
367
There are two methods of UploadHelper you can use:
368

    
369
h4. UploadHelper::uploadUrl($data, $field, $options = array())
370

    
371
Returns url to the uploaded file
372

    
373
* *$data* - record from database (would be @$user@ here)
374
* *$field* - name of a field, like this @Modelname.fieldname@ (would be @User.avatar@ here)
375
* *$options* - url options
376
** *'style'* - name of a thumbnail's style
377
** *'urlize'* - if true returned url is wrapped with @$html->url()@
378

    
379
h4. UploadHelper::uploadImage($data, $field, $options = array(), $htmlOptions = array())
380

    
381
Returns image tag pointing to uploaded file.
382

    
383
* *$data* - record from database (would be @$user@ here)
384
* *$field* - name of a field, like this @Modelname.fieldname@ (would be @User.avatar@ here)
385
* *$options* - url options
386
** *'style'* - name of a thumbnail's style
387
** *'urlize'* - if true returned url is wrapped with @$html->url()@
388
* *$htmlOptions* - array of HTML attributes passed to @$html->image()@
389

    
390
Assuming that you have read a user from database and it's available in @$user@ variable in view.
391

    
392
<pre><code><?php echo $this->Upload->uploadImage($user, 'User.avatar', array('style' => 'thumb')); ?></code></pre>
393

    
394
When you fetch user from database you would usually get:
395

    
396
<pre><code>$user = array(
397
	'User' => array(
398
		'id' => 1,
399
		'avatar_file_name' => 'photo.jpg'
400
	)
401
);
402
</code></pre>
403

    
404
But when the user is fetched as one of many users associated by hasMany association to another model it could be something like:
405

    
406
<pre><code>$data = array(
407
	'User' => array(
408
		0 => array(
409
			'id' => 1,
410
			'avatar_file_name' => 'photo.jpg'
411
		),
412
		1 => array(
413
			'id' => 2,
414
			'avatar_file_name' => 'photo2.jpg'
415
		)
416
	)
417
);
418
</code></pre>
419

    
420
Then you should do:
421

    
422
<pre><code><?php echo $this->Upload->uploadImage($data['User'][0], 'User.avatar', array('style' => 'thumb')) ?></code></pre>
423

    
424
The helper is smart enough to figure out the structure of data you pass to it.
425

    
426
h3. Requirements
427

    
428
UploadPack was developed with CakePHP 1.2 RC3, so it's not guaranteed to work with previous versions. You'll need GD library if you plan to generate image thumbnails. It works OK with 2.0.34 version at least, earlier versions may work too.
429

    
430
h2. Plans for future
431

    
432
There is still something missing in UploadPack, here's what will be added soon:
433

    
434
* file name normalization
435

    
436
The plans for more distant future:
437

    
438
* test coverage
439
* allow uploads to S3
440
* provide a method to regenerate all thumbnails, helpful if you later decide to have different sizes of thumbnails or more styles
441

    
442
I you want to help implementing these features, feel free to submit your patches.
443

    
444
h2. Copyright
445

    
446
Copyright (c) 2008 Michał Szajbe (http://codetunes.com), released under the MIT license.
447

    
448
joe bartlett's (http://jdbartlett.com) tweaks aren't under copyright. Run free, little tweaks!