Skip to content

Commit

Permalink
Added new fileName manipulation callbacks and settings.
Browse files Browse the repository at this point in the history
  • Loading branch information
webtechnick committed Apr 17, 2010
1 parent 7e6e770 commit 9d935c3
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 19 deletions.
68 changes: 64 additions & 4 deletions config/file_upload_settings.php
Expand Up @@ -26,7 +26,10 @@ class FileUploadSettings {
*/
var $defaults = array(
/**
* Component Setting Only.
* Component and Behavior Setting.
*
* If using the behavior, and a fileNameFunction setting is detected
* the fileModel setup here will be used by default.
*
* fileModel is the name of the model used if we want to
* keep records of uploads in a database.
Expand Down Expand Up @@ -67,6 +70,8 @@ class FileUploadSettings {
'allowedTypes' => array('image/jpeg','image/gif','image/png','image/pjpeg','image/x-png'),

/**
* Component and Behavior Setting.
*
* Max file size in bytes
* @var mixed false ignore maxFileSize (php.ini limit). int bytes of max file size
*/
Expand All @@ -76,6 +81,7 @@ class FileUploadSettings {
* Component and Behavior Setting.
*
* fields are the fields relating to the database columns
* @var array of fields related to database columns.
*/
'fields' => array('name'=>'name','type'=>'type','size'=>'size'),

Expand All @@ -86,20 +92,74 @@ class FileUploadSettings {
* along with just the Uploaded data. By default this is turned off.
* Turning this feature on will require you to have your model associations
* set correctly in your Upload model.
* @var boolean
* - if true: a saveAll() will be executed.
* - if false: a save() will be executed (default)
*/
'massSave' => false,

/**
* Component Setting Only.
*
* automatic determines if the process of all files will be called automatically upon detection.
* if true: files are processed as soon as they come in
* if false: when a file is ready hasFile is set to true
* it is then up to the calling application to call processAllFiles()
* whenever it wants. this allows params to be changed per uploaded file
* (save every file in a different folder for instance)
* @var boolean
* - if true: files are processed as soon as they come in (default)
* - if false: when a file is ready hasFile is set to true
*/
'automatic' => true,

/**
* Behavior Setting Only.
*
* required determines and checks if a file was sent to the server.
* @var boolean
* - if true: a file is required to be uploaded to save relative records
* - if false: related records will saved even if there is no uploaded file (default)
*/
'required' => false,

/**
* Component and Behavior Setting.
*
* unique will decide if uploaded files can overwrite other files of the same name
* if true: uploaded files will never overwrite other files of the same name (default)
* if false: uploaded files can overwrite files of the same name.
*/
'unique' => true,

/**
* Behavior Setting Only.
*
* Define a model or function callback for the filename.
* You can define this function within your attaching model
* or as a stand-alone function somewhere in your app.
*
* The function will take in the current fileName to be saved to the
* database and allow the user to return the desired fileName defined
* by the function
*
* Note: be sure to return the fileName or the file will not be saved
*
* Model callback example:
* 'fileNameFunction' => 'sanitizeFileName'
*
* Example defined in your model:
* function sanitizeFileName($fileName){
* //Logic for sanitizing your filename
* return 'prefix_' . $fileName;
* }
*
* You can also set a standard PHP string parsing like sha1, or md5 for your filenames.
*
* Example of using basic PHP string parsing function:
* 'fileNameFunction' => 'sha1'
* 'fileNameFunction' => 'md5'
* 'fileNameFunction' => 'crc32'
*/
'automatic' => true
'fileNameFunction' => false
);

}
Expand Down
21 changes: 17 additions & 4 deletions models/behaviors/file_upload.php
Expand Up @@ -3,16 +3,25 @@
* Behavior for file uploads
*
* Example Usage:
* var $actsAs = array(
*
* @example
* var $actsAs = array('FileUpload.FileUpload');
*
* @example
* var $actsAs = array(
* 'FileUpload.FileUpload' => array(
* 'uploadDir' => 'files',
* 'fields' => array('name' => 'file_name', 'type' => 'file_type', 'size' => 'file_size'),
* 'allowedTypes' => array('application/pdf'),
* 'requilred' => false,
* 'required' => false,
* 'unique' => false //filenames will overwrite existing files of the same name. (default true)
* 'fileNameFunction' => 'sha1' //execute the Sha1 function on a filename before saving it (default false)
* )
* )
*
* @version: 4.3.0
*
* @note: Please review the plugins/file_upload/config/file_upload_settings.php file for details on each setting.
* @version: since 4.4.0
* @author: Nick Baker
* @link: http://www.webtechnick.com
*/
Expand All @@ -25,6 +34,9 @@ class FileUploadBehavior extends ModelBehavior {
*/
var $Uploader = null;

/**
* Setup the behavior
*/
function setUp(&$Model, $options = array()){
$FileUploadSettings = new FileUploadSettings;
if(!is_array($options)){
Expand All @@ -34,6 +46,7 @@ function setUp(&$Model, $options = array()){

$uploader_settings = $this->options;
$uploader_settings['uploadDir'] = WWW_ROOT . $uploader_settings['uploadDir'];
$uploader_settings['fileModel'] = $Model->alias;
$this->Uploader = new Uploader($uploader_settings);
}

Expand Down Expand Up @@ -95,7 +108,7 @@ function beforeDelete(&$Model, $cascade){
$data = $Model->read();

$this->Uploader->removeFile($data[$Model->alias][$this->options['fields']['name']]);
return true;
return $Model->beforeDelete($cascade);
}

}
Expand Down
14 changes: 11 additions & 3 deletions readme.txt
Expand Up @@ -15,6 +15,7 @@ BLOG ARTICLE:
http://www.webtechnick.com/blogs/view/221/CakePHP_File_Upload_Plugin

CHANGELOG:
4.4.0: Added new fileName maniupluation callbacks and settings.
4.3.0: Added a new 'maxFileSize' validation key.
4.2.0: Added a new 'required' key in Behavior settings that would produce a validation error if a file wasn't uploaded.
4.1.2: Fixed a regression, passing in custom settings to the helper now changes those settings.
Expand Down Expand Up @@ -50,7 +51,7 @@ model will move the file to its specified area (webroot/files). All the file up
automatically, including multiple file uploads and associations.


===================== BEHAVIOR CONFIGURATION ==========================
===================== BEHAVIOR CONFIGURATION (RECOMMENDED) ==========================
Simply attach the FileUpload.FileUpload behavior to the model of your choice.

<?php
Expand All @@ -72,12 +73,16 @@ class Upload extends AppModel {
'fields' => array('name' => 'file_name', 'type' => 'file_type', 'size' => 'file_size'),
'allowedTypes' => array('application/pdf'),
'required' => false, //default is false, if true a validation error would occur if a file wsan't uploaded.
'maxFileSize' => '10000' //bytes OR false to turn off maxFileSize (default false)
'maxFileSize' => '10000', //bytes OR false to turn off maxFileSize (default false)
'unique' => false //filenames will overwrite existing files of the same name. (default true)
'fileNameFunction' => 'sha1' //execute the Sha1 function on a filename before saving it (default false)
)
);
}
?>

NOTE: Please review the FileUpload/config/file_upload_settings.php for details on each setting.

Now with your upload model set, you'll be able to upload files and save to your database even through associations in other models.
Example:

Expand All @@ -93,8 +98,11 @@ Assuming an Application->hasMany->Uploads you could do the following:
The Behavior method is by far the easiet and most flexible way to get up and rolling with file uploads.


===================== COMPONENT CONFIGURATION ==========================
===================== COMPONENT CONFIGURATION (NOT RECOMMENDED) ==========================
The second options is to use the Component + Helper method.

NOTE: This not the recommended way. I do not recommend using the comopnent unless you do *not* require a model.

Including with this plugin is another method that requires a component. The advantage of using a
component is a model is not required for file uploading. If you do not need a database, and you
simply want to upload data to your server quickly and easily simply skip to the WITHOUT MODEL CONFIGURATION
Expand Down
62 changes: 54 additions & 8 deletions vendors/uploader.php
Expand Up @@ -3,7 +3,7 @@
* Uploader class handles a single file to be uploaded to the file system
*
* @author: Nick Baker
* @verion: 4.3.0
* @version: since 4.4.0
* @link: http://www.webtechnick.com
*/
class Uploader {
Expand Down Expand Up @@ -59,6 +59,56 @@ function __construct($options = array()){
$this->options = array_merge($this->options, $options);
}

/**
* Preform requested callbacks on the filename.
*
* @var string chosen filename
* @return string of resulting filename
* @access private
*/
function __handleFileNameCallback($fileName){
if($this->options['fileNameFunction']){
if($this->options['fileModel']){
$Model = ClassRegistry::init($this->options['fileModel']);
if(method_exists($Model, $this->options['fileNameFunction'])){
$fileName = $Model->{$this->options['fileNameFunction']}($fileName);
}
elseif(function_exists($this->options['fileNameFunction'])){
$fileName = call_user_func($this->options['fileNameFunction'], $fileName);
}
}
else {
if(function_exists($this->options['fileNameFunction'])){
$fileName = call_user_func($this->options['fileNameFunction'], $fileName);
}
}

if(!$fileName){
$this->_error('No filename resulting after parsing. Function: ' . $this->options['fileNameFunction']);
}
}
return $fileName;
}

/**
* Preform requested target patch checks depending on the unique setting
*
* @var string chosen filename target_path
* @return string of resulting target_path
* @access private
*/
function __handleUnique($target_path){
if($this->options['unique']){
$temp_path = substr($target_path, 0, strlen($target_path) - strlen($this->_ext())); //temp path without the ext
$i=1;
while(file_exists($target_path)){
$target_path = $temp_path . "-" . $i . $this->_ext();
$i++;
}
}
return $target_path;
}

/**
* processFile will take a file, or use the current file given to it
* and attempt to save the file to the file system.
Expand All @@ -78,13 +128,9 @@ function processFile($file = null){

//make sure the file doesn't already exist, if it does, add an itteration to it
$up_dir = $this->options['uploadDir'];
$target_path = $up_dir . DS . $this->file['name'];
$temp_path = substr($target_path, 0, strlen($target_path) - strlen($this->_ext())); //temp path without the ext
$i=1;
while(file_exists($target_path)){
$target_path = $temp_path . "-" . $i . $this->_ext();
$i++;
}
$fileName = $this->__handleFileNameCallback($this->file['name']);
$target_path = $up_dir . DS . $fileName;
$target_path = $this->__handleUnique($target_path);

//now move the file.
if(move_uploaded_file($this->file['tmp_name'], $target_path)){
Expand Down

0 comments on commit 9d935c3

Please sign in to comment.