The Upload Plugin is an attempt to sanely upload files using techniques garnered packages such as MeioUpload , UploadPack and PHP documentation.
I will not accept any feature pull requests. They are sometimes of dubious quality and ensuring everything useful gets into the core is difficult at best. Please create a ticket for the functionality you desire and I will either extend this plugin or build it into the core.
If it is a bug-fix, feel free to issue a pull request, but be aware that reviewing your submission will take time and it may not be accepted as-is.
That said, I appreciate any and all feedback, especially on untested code such as this :)
- CakePHP 1.2/1.3
- Imagick/GD PHP Extension (for Thumbnail Creation)
- PHP5 (Not really, but I’m more likely to be able to fix a PHP5 issue than a PHP4 issue)
- Patience
[Manual]
- Download this: http://github.com/josegonzalez/upload/zipball/master
- Unzip that download.
- Copy the resulting folder to
app/plugins
- Rename the folder you just copied to
upload
[GIT Submodule]
In your app directory type:
git submodule add git://github.com/josegonzalez/upload.git plugins/upload
git submodule init
git submodule update
[GIT Clone]
In your plugin directory type
git clone git://github.com/josegonzalez/upload.git upload
CREATE table users (
id int(10) unsigned NOT NULL auto_increment,
username varchar(20) NOT NULL,
photo varchar(255)
);
<?php
class User extends AppModel {
var $name = 'User';
var $actsAs = array(
'Upload.Upload' => array(
'photo'
)
);
}
?>
<?php echo $this->Form->create('User', array('type' => 'file')); ?>
<?php echo $this->Form->input('User.username'); ?>
<?php echo $this->Form->input('User.photo', array('type' => 'file')); ?>
<?php echo $this->Form->end(); ?>
Using the above setup, uploaded files cannot be deleted. To do so, a field must be added to store the directory of the file as follows:
CREATE table users (
`id` int(10) unsigned NOT NULL auto_increment,
`username` varchar(20) NOT NULL,
`photo` varchar(255) DEFAULT NULL,
`photo_dir` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
);
<?php
class User extends AppModel {
var $name = 'User';
var $actsAs = array(
'Upload.Upload' => array(
'photo' => array(
'fields' => array(
'dir' => 'photo_dir'
)
)
)
);
}
?>
<?php echo $this->Form->create('User', array('type' => 'file')); ?>
<?php echo $this->Form->input('User.username'); ?>
<?php echo $this->Form->input('User.photo', array('type' => 'file')); ?>
<?php echo $this->Form->input('User.photo_dir', array('type' => 'hidden')); ?>
<?php echo $this->Form->end(); ?>
Thumbnails are not automatically created. To do so, thumbnail sizes must be defined:
Note: by default thumbnails will be generated by imagick, if you want to use GD you need to set the thumbnailMethod attribute. Example: ‘thumbnailMethod’ => ‘php’.
<?php
class User extends AppModel {
var $name = 'User';
var $actsAs = array(
'Upload.Upload' => array(
'photo' => array(
'fields' => array(
'dir' => 'photo_dir'
),
'thumbsizes' => array(
'xvga' => '1024x768',
'vga' => '640x480',
'thumb' => '80x80'
)
)
)
);
}
?>
Multiple files can also be attached to a single record:
<?php
class User extends AppModel {
var $name = 'User';
var $actsAs = array(
'Upload.Upload' => array(
'resume',
'photo' => array(
'fields' => array(
'dir' => 'profile_dir'
),
'thumbsizes' => array(
'xvga' => '1024x768',
'vga' => '640x480',
'thumb' => '80x80'
)
)
)
);
}
?>
It is now possible to generate a thumbnail for the first page of a PDF file. (Only works with ‘imagick’ thumbnailMethod.)
Please read about the Behavior options for more details as to how to configure this plugin.
pathMethod
: The method to use for file paths. This is appended to thepath
option below- Default: (string)
primaryKey
- Options:
- flat: Does not create a path for each record. Files are moved to the value of the ‘path’ option
- primaryKey: Path based upon the record’s primaryKey is generated. Persists across a record
- random: Random path is generated for each file upload. Does not persist across a record.
- Default: (string)
path
: A path relative to theAPP_PATH
. Should end in{DS}
- Default: (string)
'webroot{DS}files{DS}{model}{DS}{field}{DS}'
- Tokens:
- {DS}: Replaced by a
DIRECTORY_SEPARATOR
- {model}: Replaced by the Model Alias
- {field}: Replaced by the field name
- {DS}: Replaced by a
- Default: (string)
fields
: An array of fields to use when uploading files- Default: (array)
array('dir' => 'dir', 'type' => 'type', 'size' => 'size')
- Options:
- dir: Field to use for storing the directory
- type: Field to use for storing the filetype
- size: Field to use for storing the filesize
- Default: (array)
mimetypes
: Array of mimetypes to use for validation- Default: (array) empty
extensions
: Array of extensions to use for validation- Default: (array) empty
maxSize
: Max filesize in bytes for validation- Default: (int)
2097152
- Default: (int)
minSize
: Minimum filesize in bytes for validation- Default: (int)
8
- Default: (int)
maxHeight
: Maximum image height for validation- Default: (int)
0
- Default: (int)
minHeight
: Minimum image height for validation- Default: (int)
0
- Default: (int)
maxWidth
: Maximum image width for validation- Default: (int)
0
- Default: (int)
minWidth
: Minimum image width for validation- Default: (int)
0
- Default: (int)
deleteOnUpdate
: Whether to delete files when uploading new versions (potentially dangerous due to naming conflicts)- Default: (boolean)
false
- Default: (boolean)
prefixStyle
: Whether to prefix or suffix the style onto thumbnails- Default: (boolean)
true
- Default: (boolean)
thumbnails
: Whether to create thumbnails or not- Default: (boolean)
true
- Default: (boolean)
thumbsizes
: Array of thumbnail sizes, with the style-name mapping to a geometry- Default: (array) empty
thumbnailQuality
: Quality of thumbnails that will be generated, on a scale of 0-100- Default: (int)
75
- Default: (int)
thumbnailMethod
: The method to use for resizing thumbnails- Default: (string)
imagick
- Options:
- imagick: Uses the PHP `imagick` extension to generate thumbnails
- php: Uses the built-in PHP methods (`GD` extension) to generate thumbnails
- Default: (string)
thumbnailType
: Override the type of the generated thumbnail- Default: (mixed)
false
orpng
when the upload is a Media file - Options:
- Any valid image type
- Default: (mixed)
mediaThumbnailType
: Override the type of the generated thumbnail for a non-image media (pdfs
). OverridesthumbnailType
- Default: (mixed)
png
- Options:
- Any valid image type
- Default: (mixed)
saveDir
: Can be used to turn off saving the directory- Default: (boolean)
true
- Note: Because of the way in which the directory is saved, if you are using a
pathMethod
other than flat and you setsaveDir
to false, you may end up in situations where the file is in a location that you cannot predict. This is more of an issue for apathMethod
ofrandom
thanprimaryKey
, but keep this in mind when fiddling with this option
- Default: (boolean)
thumbnailPath
: A path relative to theAPP_PATH
where thumbnails will be saved. Should end in{DS}
. If not set, thumbnails will be saved atpath
.- Default: (boolean)
false
- Tokens:
- {DS}: Replaced by a
DIRECTORY_SEPARATOR
- {model}: Replaced by the Model Alias
- {field}: Replaced by the field name
- {DS}: Replaced by a
- Default: (boolean)
Styles are the definition of thumbnails that will be generated for original image. You can define as many as you want.
<?php
class User extends AppModel {
var $name = 'User';
var $actsAs = array(
'Upload.Upload' => array(
'photo' => array(
'thumbsizes' => array(
'big' => '200x200',
'small' => '120x120'
'thumb' => '80x80'
)
)
)
);
?>
Styles only apply to images of the following types:
- image/bmp
- image/gif
- image/jpeg
- image/pjpeg
- image/png
- image/vnd.microsoft.icon
- image/x-icon
You can specify any of the following resize modes for your styles:
- 100×80 – resize for best fit into these dimensions, with overlapping edges trimmed if original aspect ratio differs
- [100×80] – resize to fit these dimensions, with white banding if original aspect ratio differs
- 100w – maintain original aspect ratio, resize to 100 pixels wide
- 80h – maintain original aspect ratio, resize to 80 pixels high
- 80l – maintain original aspect ratio, resize so that longest side is 80 pixels
By default, no validation rules are attached to the model. One must explicitly attach each rule if needed. Rules not referring to PHP upload errors are configurable but fallback to the behavior configuration.
Check that the file does not exceed the max file size specified by PHP
var $validate = array(
'photo' => array(
'rule' => 'isUnderPhpSizeLimit',
'message' => 'File exceeds upload filesize limit'
)
);
Check that the file does not exceed the max file size specified in the HTML Form
var $validate = array(
'photo' => array(
'rule' => 'isUnderFormSizeLimit',
'message' => 'File exceeds form upload filesize limit'
)
);
Check that the file was completely uploaded
var $validate = array(
'photo' => array(
'rule' => 'isCompletedUpload',
'message' => 'File was not successfully uploaded'
)
);
Check that a file was uploaded
var $validate = array(
'photo' => array(
'rule' => 'isFileUpload',
'message' => 'File was missing from submission'
)
);
Check that the PHP temporary directory is missing
var $validate = array(
'photo' => array(
'rule' => 'tempDirExists',
'message' => 'The system temporary directory is missing'
)
);
Check that the file was successfully written to the server
var $validate = array(
'photo' => array(
'rule' => 'isSuccessfulWrite',
'message' => 'File was unsuccessfully written to the server'
)
);
Check that a PHP extension did not cause an error
var $validate = array(
'photo' => array(
'rule' => 'noPhpExtensionErrors',
'message' => 'File was not uploaded because of a faulty PHP extension'
)
);
Check that the file is of a valid mimetype
var $validate = array(
'photo' => array(
'rule' => array('isValidMimeType', array('valid/mimetypes', 'array/here')),
'message' => 'File is of an invalid mimetype'
)
);
Check that the upload directory is writable
var $validate = array(
'photo' => array(
'rule' => 'isWritable',
'message' => 'File upload directory was not writable'
)
);
Check that the upload directory exists
var $validate = array(
'photo' => array(
'rule' => 'isValidDir',
'message' => 'File upload directory does not exist'
)
);
Check that the file is below the maximum file upload size (checked in bytes)
var $validate = array(
'photo' => array(
'rule' => array('isBelowMaxSize', 1024),
'message' => 'File is larger than the maximum filesize'
)
);
Check that the file is above the minimum file upload size (checked in bytes)
var $validate = array(
'photo' => array(
'rule' => array('isAboveMinSize', 1024),
'message' => 'File is below the mimimum filesize'
)
);
Check that the file has a valid extension
var $validate = array(
'photo' => array(
'rule' => array('isValidExtension', array('ext', 'array', 'here')),
'message' => 'File has an invalid extension'
)
);
Check that the file is above the minimum height requirement (checked in pixels)
var $validate = array(
'photo' => array(
'rule' => array('isAboveMinHeight' 150),
'message' => 'File is below the minimum height'
)
);
Check that the file is below the maximum height requirement (checked in pixels)
var $validate = array(
'photo' => array(
'rule' => array('isBelowMaxHeight', 150),
'message' => 'File is above the maximum height'
)
);
Check that the file is above the minimum width requirement (checked in pixels)
var $validate = array(
'photo' => array(
'rule' => array('isAboveMinWidth', 150),
'message' => 'File is below the minimum width'
)
);
Check that the file is below the maximum width requirement (checked in pixels)
var $validate = array(
'photo' => array(
'rule' => array('isBelowMaxWidth', 150),
'message' => 'File is above the maximum width'
)
);