MeioUpload Behavior
A behavior to make the file uploads as simple as defining variables.
After about one year trying to make the upload simple in CakePHP, I finally finished an upload behavior based on digital spaghetti's (http://digitalspaghetti.tooum.net/) upload behavior (http://digitalspaghetti.tooum.net/switchboard/blog/2497:Upload_Behavior_for_CakePHP_12) and I am glad to show it for you.
You just have to set the MeioUpload Behavior:
And add the file input in the form:
Here is the link to the snippet with the behavior code:
http://cakeforge.org/snippet/detail.php?type=snippet&id=226
And here id the link to the documentation:
http://www.meiocodigo.com/projects/meioupload
You just have to set the MeioUpload Behavior:
Model Class:
<?php
class MyModel extends AppModel {
var $actsAs = array('MeioUpload' => array(
'filename' => array(
'dir' => 'files/images',
)
);
}
?>
And add the file input in the form:
View Template:
<?php echo $form->create('Produto',array('type' => 'file'));?>
<?php echo $form->input('filename', array('type' => 'file')); ?>
Here is the link to the snippet with the behavior code:
http://cakeforge.org/snippet/detail.php?type=snippet&id=226
And here id the link to the documentation:
http://www.meiocodigo.com/projects/meioupload








I modified MeioUpload Behavior for use it in several model. THis is de code:
array(
* 'filename' => array(
* 'dir' => 'files/images',
* 'create_directory' => false,
* 'allowed_mime' => array('image/jpeg', 'image/pjpeg', 'image/gif', 'image/png'),
* 'allowed_ext' => array('.jpg', '.jpeg', '.png', '.gif'),
* 'thumbsizes' => array(
* 'small' => array('width'=>100, 'height'=>100),
* 'medium' => array('width'=>220, 'height'=>220),
* 'large' => array('width'=>800, 'height'=>600)
* )
* )
* )
* );
* The above code will save the uploaded file's name in the 'filename' field in database,
* it will not overwrite existing files, instead it will create a new filename based on the original
* plus a counter.
* Allowed Mimetypes and extentions should be pretty explanitory.
* For thumbnails, when the file is uploaded, it will create 3 thumbnail sizes and prepend the name
* to the thumbfiles (i.e. image_001.jpg will produced thumb.small.image_001.jpg, thumb.medium.image_001.jpg, etc)
*
* 5) Create your upload view, make sure it's a multipart/form-data form, and the filename field is of type $form->file
* 6) Make sure your directory is at least CHMOD 775, also check your php.ini MAX_FILE_SIZE is enough to support the filesizes you are uploading
*
* Version Details
*
* 1.0.1
* + Fixed a bug in the create folder method
* + Now you can use the $validate var of the model to apply the changes to default validation rules;
* + Changed the my_array_merge function, now it's part of the behavior, name arrayMerge;
* + Allow use of {DS}, {model} and {field} constants in directory name and fields names;
* + Fixed a bug with the replacement of the default names.
*
* 1.0
* + Initial release.
*/
uses('folder');
class MeioUploadBehavior extends ModelBehavior {
/**
* The default options for the behavior
*/
var $default_options = array(
'dir' => '',
'allowed_mime' => array(),
'allowed_ext' => array(),
'create_directory' => true,
'max_size' => 2097152,
'thumbsizes' => array(),
'default' => false,
'fields' => array(
'dir' => 'dir',
'filesize' => 'filesize',
'mimetype' => 'mimetype'
),
'validations' => array(
'FieldName' => array(
'rule' => array('uploadCheckFieldName'),
'check' => true,
'message' => 'Este campo no se ha definido entre los parámetros de MeioUploadBehavior.'
),
'Dir' => array(
'rule' => array('uploadCheckDir'),
'check' => true,
'message' => 'El directorio donde este archivo se coloca no existe o está protegido contra escritura.'
),
'Empty' => array(
'rule' => array('uploadCheckEmpty'),
'check' => true,
'on' => 'create',
'message' => 'El archivo no puede estar vacío'
),
'UploadError' => array(
'rule' => array('uploadCheckUploadError'),
'check' => true,
'message' => 'Hubo problemas al cargar el archivo.'
),
'MaxSize' => array(
'rule' => array('uploadCheckMaxSize'),
'check' => true,
'message' => 'El tamaño máximo de archivo se ha superado.'
),
'InvalidMime' => array(
'rule' => array('uploadCheckInvalidMime'),
'check' => true,
'message' => 'Tipo de archivo inválido.'
),
'InvalidExt' => array(
'rule' => array('uploadCheckInvalidExt'),
'check' => true,
'message' => 'Extensión de archivo inválida.'
)
)
);
var $default_validations = array(
'FieldName' => array(
'rule' => array('uploadCheckFieldName'),
'check' => true,
'message' => ' campo no se ha definido entre los parámetros de MeioUploadBehavior.'
),
'Dir' => array(
'rule' => array('uploadCheckDir'),
'check' => true,
'message' => 'El directorio donde este archivo se coloca no existe o está protegido contra escritura.'
),
'Empty' => array(
'rule' => array('uploadCheckEmpty'),
'check' => true,
'on' => 'create',
'message' => 'El archivo no puede estar vacío'
),
'UploadError' => array(
'rule' => array('uploadCheckUploadError'),
'check' => true,
'message' => 'Hubo problemas al cargar el archivo.'
),
'MaxSize' => array(
'rule' => array('uploadCheckMaxSize'),
'check' => true,
'message' => 'El tamaño máximo de archivo se ha superado.'
),
'InvalidMime' => array(
'rule' => array('uploadCheckInvalidMime'),
'check' => true,
'message' => 'Tipo de archivo inválido.'
),
'InvalidExt' => array(
'rule' => array('uploadCheckInvalidExt'),
'check' => true,
'message' => 'Extensión de archivo inválida.'
)
);
/**
* The message for move error.
*/
var $moveErrorMsg = 'Hubo problemas en la copia de archivo.';
/**
* The array that saves the $options for the behavior
*/
var $__fields = array();
/**
* Patterns of reserved words
*/
var $patterns = array(
"thumb",
"default"
);
/**
* Words to replace the patterns of reserved words
*/
var $replacements = array(
"t_umb",
"d_fault"
);
/**
* Array of files to be removed on the afterSave callback
*/
var $__filesToRemove = array();
/**
* Setup the behavior. It stores a reference to the model, merges the default options with the options for each field, and setup the validation rules.
*
* @author Vinicius Mendes
* @return null
* @param $model Object
* @param $config Array[optional]
*/
function setup(&$model, $config=array()) {
$this->Folder[$model->name] = &new Folder;
$this->__model[$model->name] = $model;
$this->__fields[$model->name] = array();
foreach($config as $field => $options) {
// Check if given field exists
if(!$model->hasField($field)) {
trigger_error('MeioUploadBehavior Error: The field "'.$field.'" doesn\'t exists in the model "'.$model->name.'".', E_USER_WARNING);
}
// Merge given options with defaults
$options = $this->arrayMerge($this->default_options, $options);
// Including the default name to the replacements
if($options['default']){
if(!preg_match('/^.+\..+$/',$options['default'])){
trigger_error('MeioUploadBehavior Error: The default option must be the filename with extension.', E_USER_ERROR);
}
$this->_includeDefaultReplacement($options['default']);
}
// Verifies if the thumbsizes names is alphanumeric
foreach($options['thumbsizes'] as $name => $size){
if(!preg_match('/^[0-9a-zA-Z]+$/',$name)){
trigger_error('MeioUploadBehavior Error: The thumbsizes names must be alphanumeric.', E_USER_ERROR);
}
}
// Process the max_size if it is not numeric
$options['max_size'] = $this->sizeToBytes($options['max_size']);
$this->__fields[$model->name][$field] = $options;
// Generate temporary directory if none provided
if(empty($options['dir'])) {
$this->__fields[$model->name][$field]['dir'] = 'uploads' . DS . $model->name;
// Else replace the tokens of the dir.
} else {
$this->__fields[$model->name][$field]['dir'] = $this->replaceTokens($model, $options['dir'],$field);
}
// Replace tokens in the fields names.
foreach($this->__fields[$model->name][$field]['fields'] as $fieldToken => $fieldName){
$this->__fields[$model->name][$field]['fields'][$fieldToken] = $this->replaceTokens($model, $fieldName,$field);
}
// Check that the given directory does not have a DS on the end
if($options['dir'][strlen($options['dir'])-1] == DS) {
$options['dir'] = substr($options['dir'],0,strlen($options['dir'])-2);
}
}
}
/**
* Merges two arrays recursively
*
* @author Vinicius Mendes
* @return Array
* @param $arr Array
* @param $ins Array
*/
function arrayMerge($arr, $ins) {
if (is_array($arr)) {
if (is_array($ins)) {
foreach ($ins as $k=>$v) {
if (isset($arr[$k])&&is_array($v)&&is_array($arr[$k])) {
$arr[$k] = $this->arrayMerge($arr[$k],$v);
}
else $arr[$k] = $v;
}
}
} elseif (!is_array($arr)&&(strlen($arr)==0||$arr==0)) {
$arr=$ins;
}
return($arr);
}
/**
* Replaces some tokens. {model} to the underscore version of the model name, {field} to the field name, {DS}. / or \ to DS constant value.
*
* @author Vinicius Mendes
* @return String
* @param $string String
* @param $fieldName String
*/
function replaceTokens($model, $string,$fieldName){
return str_replace(array('{model}', '{field}', '{DS}','/','\\'),array(Inflector::underscore($this->__model[$model->name]->name),$fieldName,DS,DS,DS),$string);
}
/**
* Convert a size value to bytes. For example: 2 MB to 2097152.
*
* @author Vinicius Mendes
* @return int
* @param $size String
*/
function sizeToBytes($size){
if(is_numeric($size)) return $size;
if(!preg_match('/^[1-9][0-9]* (kb|mb|gb|tb)$/i', $size)){
trigger_error('MeioUploadBehavior Error: The max_size option format is invalid.', E_USER_ERROR);
return 0;
}
list($size, $unit) = explode(' ',$size);
if(strtolower($unit) == 'kb') return $size*1024;
if(strtolower($unit) == 'mb') return $size*1048576;
if(strtolower($unit) == 'gb') return $size*1073741824;
if(strtolower($unit) == 'tb') return $size*1099511627776;
trigger_error('MeioUploadBehavior Error: The max_size unit is invalid.', E_USER_ERROR);
return 0;
}
/**
* Sets the validation for each field, based on the options.
*
* @author Vinicius Mendes
* @return null
* @param $fieldName String
* @param $options Array
*/
function setupValidation($model, $fieldName, $options){
$options = $this->__fields[$model->name][$fieldName];
if(isset($this->__model[$model->name]->validate[$fieldName])){
if(isset($this->__model[$model->name]->validate[$fieldName]['rule'])){
$this->__model[$model->name]->validate[$fieldName] = array(
'oldValidation' => $this->__model[$model->name]->validates[$fieldName]
);
}
} else {
$this->__model[$model->name]->validate[$fieldName] = array();
}
$this->__model[$model->name]->validate[$fieldName] = $this->arrayMerge($this->default_validations,$this->__model[$model->name]->validate[$fieldName]);
$this->__model[$model->name]->validate[$fieldName] = $this->arrayMerge($options['validations'],$this->__model[$model->name]->validate[$fieldName]);
}
/**
* Checks if the field was declared in the MeioUpload Behavior setup
*
* @author Vinicius Mendes
* @return boolean
* @param $model Object
* @param $data Array
*/
function uploadCheckFieldName(&$model, $data,$other){
foreach($data as $fieldName => $field){
if(!$this->__model[$model->name]->validate[$fieldName]['FieldName']['check']) return true;
if(isset($this->__fields[$model->name][$fieldName])){
return true;
} else {
$this->log('UploadBehavior Error: The field "'.$fieldName.'" wasn\'t declared as part of the UploadBehavior in model "'.$model->name.'".');
return false;
}
}
return true;
}
/**
* Checks if the folder exists or can be created or writable.
*
* @author Vinicius Mendes
* @return boolean
* @param $model Object
* @param $data Array
*/
function uploadCheckDir(&$model, $data){
foreach($data as $fieldName => $field){
if(!$this->__model[$model->name]->validate[$fieldName]['Dir']['check']) return true;
$options = $this->__fields[$model->name][$fieldName];
if(empty($field['remove']) || empty($field['name'])){
// Check if directory exists and create it if required
if(!is_dir($options['dir'])) {
if($options['create_directory']){
if(!$this->Folder[$model->name]->create($options['dir'])) {
trigger_error('UploadBehavior Error: The directory '.$options['dir'].' does not exist and cannot be created.', E_USER_WARNING);
return false;
}
} else {
trigger_error('UploadBehavior Error: The directory'.$options['dir'].' does not exist.', E_USER_WARNING);
return false;
}
}
// Check if directory is writable
if(!is_writable($options['dir'])) {
trigger_error('UploadBehavior Error: The directory '.$options['dir'].' isn\'t writable.', E_USER_WARNING);
return false;
}
}
}
return true;
}
/**
* Checks if the filename is not empty.
*
* @author Vinicius Mendes
* @return boolean
* @param $model Object
* @param $data Array
*/
function uploadCheckEmpty(&$model, $data){
foreach($data as $fieldName => $field){
if(!$this->__model[$model->name]->validate[$fieldName]['Empty']['check']) return true;
if(empty($field['remove'])){
if(!is_array($field) || empty($field['name'])){
return false;
}
}
}
return true;
}
/**
* Checks if ocurred erros in the upload.
*
* @author Vinicius Mendes
* @return boolean
* @param $model Object
* @param $data Array
*/
function uploadCheckUploadError(&$model, $data){
foreach($data as $fieldName => $field){
if(!$this->__model[$model->name]->validate[$fieldName]['UploadError']['check']) return true;
if(!empty($field['name']) && $field['error'] > 0){
return false;
}
}
return true;
}
/**
* Checks if the file isn't bigger then the max file size option.
*
* @author Vinicius Mendes
* @return boolean
* @param $model Object
* @param $data Array
*/
function uploadCheckMaxSize(&$model, $data){
foreach($data as $fieldName => $field){
if(!$this->__model[$model->name]->validate[$fieldName]['MaxSize']['check']) return true;
$options = $this->__fields[$model->name][$fieldName];
if(!empty($field['name']) && $field['size'] > $options['max_size']) {
return false;
}
}
return true;
}
/**
* Checks if the file is of an allowed mime-type.
*
* @author Vinicius Mendes
* @return boolean
* @param $model Object
* @param $data Array
*/
function uploadCheckInvalidMime(&$model, $data){
foreach($data as $fieldName => $field){
if(!$this->__model[$model->name]->validate[$fieldName]['InvalidMime']['check']) return true;
$options = $this->__fields[$model->name][$fieldName];
if(!empty($field['name']) && count($options['allowed_mime']) > 0 && !in_array($field['type'], $options['allowed_mime'])) {
return false;
}
}
return true;
}
/**
* Checks if the file has an allowed extension.
*
* @author Vinicius Mendes
* @return boolean
* @param $model Object
* @param $data Array
*/
function uploadCheckInvalidExt(&$model, $data){
foreach($data as $fieldName => $field){
if(!$this->__model[$model->name]->validate[$fieldName]['InvalidExt']['check']) return true;
$options = $this->__fields[$model->name][$fieldName];
if(!empty($field['name'])){
if(count($options['allowed_ext']) > 0) {
$matches = 0;
foreach($options['allowed_ext'] as $extension) {
if(strtolower(substr($field['name'],-strlen($extension))) == strtolower($extension)) {
$matches++;
}
}
if($matches == 0) {
return false;
}
}
}
}
return true;
}
/**
* Set a file to be removed in afterSave callback
*
* @author Vinicius Mendes
* @return null
* @param $fieldName String
*/
function setFileToRemove($model,$fieldName){
$filename = $this->__model[$model->name]->field($fieldName);
if(!empty($filename) && $filename != $this->__fields[$model->name][$fieldName]['default']){
$this->__filesToRemove[$model->name][] = array(
'dir' => $this->__fields[$model->name][$fieldName]['dir'],
'name' => $filename
);
}
}
/**
* Include a pattern of reserved word based on a filename, and it's replacement.
*
* @author Vinicius Mendes
* @return null
* @param $default String
*/
function _includeDefaultReplacement($default){
$replacements = $this->replacements;
list($newPattern, $ext) = $this->splitFilenameAndExt($default);
if(!in_array($newPattern, $this->patterns)){
$this->patterns[] = $newPattern;
$newReplacement = $newPattern;
if(isset($newReplacement[1])){
if($newReplacement[1] != '_'){
$newReplacement[1] = '_';
} else {
$newReplacement[1] = 'a';
}
} elseif($newReplacement != '_') {
$newReplacement = '_';
} else {
$newReplacement = 'a';
}
$this->replacements[] = $newReplacement;
}
}
/**
* Removes the bad characters from the $filename and replace reserved words. It updates the $model->data.
*
* @author Vinicius Mendes
* @return null
* @param $fieldName String
*/
function fixName($model, $fieldName){
// updates the filename removing the keywords thumb and default name for the field.
list($filename, $ext) = $this->splitFilenameAndExt($this->__model[$model->name]->data[$this->__model[$model->name]->name][$fieldName]['name']);
$filename = str_replace($this->patterns,$this->replacements,$filename);
$filename = Inflector::slug($filename);
$i = 0;
$newFilename = $filename;
while(file_exists($this->__fields[$model->name][$fieldName]['dir'].DS.$newFilename.'.'.$ext)){
$newFilename = $filename.$i;
$i++;
}
$this->__model->data[$model->name][$this->__model[$model->name]->name][$fieldName]['name'] = $newFilename.'.'.$ext;
}
/**
* Splits a filename in two parts: the name and the extension. Returns an array with it respectively.
*
* @author Vinicius Mendes
* @return Array
* @param $filename String
*/
function splitFilenameAndExt($filename){
$parts = explode('.',$filename);
$ext = $parts[count($parts)-1];
unset($parts[count($parts)-1]);
$filename = implode('.',$parts);
return array($filename,$ext);
}
/**
* Sets the validation rules for each field.
*
* @return true
* @param $model Object
*/
function beforeValidate(&$model) {
foreach($this->__fields[$model->name] as $fieldName=>$options){
$this->setupValidation($model, $fieldName, $options);
}
return true;
}
/**
* Uploads the files before saving the record.
*
* @author Vinicius Mendes
* @param $model Object
*/
function beforeSave(&$model) {
foreach($this->__fields[$model->name] as $fieldName=>$options){
// if the file is marked to be deleted, use the default or set the field to null
if(!empty($model->data[$model->name][$fieldName]['remove'])){
if($options['default']){
$model->data[$model->name][$fieldName] = $options['default'];
} else {
$model->data[$model->name][$fieldName] = null;
}
//if the record is already saved in the database, set the existing file to be removed after the save is sucessfull
if(!empty($model->data[$model->name][$model->primaryKey])){
$this->setFileToRemove($model,$fieldName);
}
continue;
}
// If no file has been upload, then unset the field to avoid overwriting existant file
if(!isset($model->data[$model->name][$fieldName]) || !is_array($model->data[$model->name][$fieldName]) || empty($model->data[$model->name][$fieldName]['name'])){
if(!empty($model->data[$model->name][$model->primaryKey]) || !$options['default']){
unset($model->data[$model->name][$fieldName]);
} else {
$model->data[$model->name][$fieldName] = $options['default'];
}
continue;
}
//if the record is already saved in the database, set the existing file to be removed after the save is sucessfull
if(!empty($model->data[$model->name][$model->primaryKey])){
$this->setFileToRemove($model,$fieldName);
}
// Fix the filename, removing bad characters and avoiding from overwriting existing ones
$this->_includeDefaultReplacement($options['default']);
$this->fixName($model, $fieldName);
$saveAs = $options['dir'].DS.$model->data[$model->name][$fieldName]['name'];
// Attempt to move uploaded file
if(!move_uploaded_file($model->data[$model->name][$fieldName]['tmp_name'], $saveAs)){
$model->validationErrors[$field] = $moveErrorMsg;
return false;
}
// It the file is an image, try to make the thumbnails
if (count($options['allowed_ext']) > 0 && in_array($model->data[$model->name][$fieldName]['type'], array('image/jpeg', 'image/pjpeg', 'image/png'))) {
foreach ($options['thumbsizes'] as $key => $value) {
// If a 'normal' thumbnail is set, then it will overwrite the original file
if($key == 'normal'){
$thumbSaveAs = $saveAs;
// Otherwise, set the thumb filename to thumb.$key.$filename.$ext
} else {
$thumbSaveAs = $options['dir'].DS.'thumb.'.$key.'.'.$model->data[$model->name][$fieldName]['name'];
}
$this->createthumb($saveAs, $thumbSaveAs, $value['width'], $value['height']);
}
}
// Update model data
$model->data[$model->name][$options['fields']['dir']] = $options['dir'];
$model->data[$model->name][$options['fields']['mimetype']] = $model->data[$model->name][$fieldName]['type'];
$model->data[$model->name][$options['fields']['filesize']] = $model->data[$model->name][$fieldName]['size'];
$model->data[$model->name][$fieldName] = $model->data[$model->name][$fieldName]['name'];
}
return true;
}
/**
* Deletes the files marked to be deleted in the save method. A file can be marked to be deleted if it is overwriten by another or if the user mark it to be deleted.
*
* @author Vinicius Mendes
* @param $model Object
*/
function afterSave(&$model) {
foreach($this->__filesToRemove as $file){
if($file['name'])
$this->_deleteFiles($file['name'], $file['dir']);
}
// Reset the filesToRemove array
$this->__filesToRemove[$model->name] = array();
}
/**
* Deletes all files associated with the record beforing delete it.
*
* @author Vinicius Mendes
* @param $model Object
*/
function beforeDelete(&$model) {
$model->read(null, $model->id);
if(isset($model->data)) {
foreach($this->__fields[$model->name] as $field=>$options) {
$file = $model->data[$model->name][$field];
if($file && $file != $options['default'])
$this->_deleteFiles($file, $options['dir']);
}
}
return true;
}
/**
* Delete the $filename inside the $dir and the thumbnails.
* Returns true if the file is deleted and false otherwise.
*
* @author Vinicius Mendes
* @return boolean
* @param $filename Object
* @param $dir Object
*/
function _deleteFiles($filename, $dir){
$saveAs = $dir . DS . $filename;
if(is_file($saveAs) && !unlink($saveAs))
{
return false;
}
$folder = &new Folder($dir);
$files = $folder->find('thumb\.[a-zA-Z0-9]+\.'.$filename);
foreach($files as $f) unlink($dir.DS.$f);
return true;
}
// Function to create thumbnail image
// This requires Nate Constant's thumbnail generator for PHPThumb
// http://bakery.cakephp.org/articles/view/phpthumb-component
// Thi function is original from digital spaghetti's version
function createthumb($name, $filename, $new_w, $new_h)
{
App::import('Component', 'Thumb');
$system = explode(".", $name);
if (preg_match("/jpg|jpeg/", $system[1]))
{
$src_img = imagecreatefromjpeg($name);
}
if (preg_match("/png/", $system[1]))
{
$src_img = imagecreatefrompng($name);
}
$old_x = imagesx($src_img);
$old_y = imagesy($src_img);
if ($old_x >= $old_y)
{
$thumb_w = $new_w;
$ratio = $old_y / $old_x;
$thumb_h = $ratio * $new_w;
} else if ($old_x
The code I used was adapted from http://mediumexposure.com/smart-image-resizing-while-preserving-transparency-php-and-gd-library/
So... here's the block of code that worked for me - add it in the "createthumb" method, at line 748, just below the line that says "$dst_img = imagecreatetruecolor($thumb_w, $thumb_h);":
if (preg_match("/png/", $system[1])) {
$trnprt_indx = imagecolortransparent($src_img);
// If we have a specific transparent color
if ($trnprt_indx >= 0) {
// Get the original image's transparent color's RGB values
$trnprt_color = imagecolorsforindex($src_img, $trnprt_indx);
// Allocate the same color in the new image resource
$trnprt_indx = imagecolorallocate($dst_img, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
// Completely fill the background of the new image with allocated color.
imagefill($dst_img, 0, 0, $trnprt_indx);
// Set the background color for new image to transparent
imagecolortransparent($dst_img, $trnprt_indx);
}
// Always make a transparent background color for PNGs that don't have one allocated already
elseif (preg_match("/png/", $system[1])) {
// Turn off transparency blending (temporarily)
imagealphablending($dst_img, false);
// Create a new transparent color for image
$color = imagecolorallocatealpha($dst_img, 0, 0, 0, 127);
// Completely fill the background of the new image with allocated color.
imagefill($dst_img, 0, 0, $color);
// Restore transparency blending
imagesavealpha($dst_img, true);
}
}
Has anyone else had this problem, or does anyone know the solution?
Thanks in advance.
Thanks
Thank you all who worked. Congratulations.
http://github.com/josegonzalez/MeioUpload/tree/master
Hi, where we can find the fixed version?
Thanks in advance.
As is customary, I forgot the link. I've updated my comment and am also including a link here.
http://github.com/josegonzalez/MeioUpload/tree/master
Feel free to yell if anything breaks horribly :)
function createthumb($path, $dest_path, $width, $height)
{
$need_aspect = $width/$height;
list($img_w, $img_h) = getimagesize($path);
if ($img_h < $height)
$img_h = $height;
elseif ($img_w < $width)
$img_w = $width;
$aspect = $img_w / $img_h;
if ($aspect > $need_aspect)
$img_w = $img_h * $need_aspect;
elseif ($aspect <= $need_aspect)
$img_h = $img_w / $need_aspect;
if ($width == $height)
exec(CONVERT." $path -gravity North -strip -crop ".$img_w.'x'.$img_h."+0+0 +repage -quality 95 $dest_path");
else
exec(CONVERT." $path -gravity Center -strip -crop ".$img_w.'x'.$img_h."+0+0 +repage -quality 95 $dest_path");
exec(CONVERT." $dest_path -resize ".$width."x".$height."\\> $dest_path");
}
...
// It the file is an image, try to make the thumbnails
if (count($options['allowed_ext']) > 0 && in_array($model->data[$model->name][$fieldName]['type'], array('image/jpeg', 'image/pjpeg', 'image/png', 'image/gif'))) {
...
it's interesting, but gif is image too, and i need thumbnails for it too:)
It's writed that you need that thumbPhp for making thumbnails, but your behavior dont use it?.. you just have a function createthumb for making thumbs :)
'FieldName' => array(
'rule' => array('uploadCheckFieldName'),
'check' => true,
'message' => 'This field was not defined in MeioUploadBehavior.'
),
'Dir' => array(
'rule' => array('uploadCheckDir'),
'check' => true,
'message' => 'Cannot write to the directory.'
),
'Empty' => array(
'rule' => array('uploadCheckEmpty'),
'check' => true,
'on' => 'create',
'message' => 'The file cannot be empty.'
),
'UploadError' => array(
'rule' => array('uploadCheckUploadError'),
'check' => true,
'message' => 'There was a problem uploading the file'
),
'MaxSize' => array(
'rule' => array('uploadCheckMaxSize'),
'check' => true,
'message' => 'The file exceeds the maximum size.'
),
'InvalidMime' => array(
'rule' => array('uploadCheckInvalidMime'),
'check' => true,
'message' => 'Invalid file type.'
),
'InvalidExt' => array(
'rule' => array('uploadCheckInvalidExt'),
'check' => true,
'message' => 'Invalid file extension.'
)
I had some permissions issues and kept getting "Invalid File Extension" back as my error.
So ensure that you are able to upload a regular file first (through your controller or whatever), THEN drop in this bad boy.
Works like a charm. My only caveat is that it doesn't display validation errors with _added_ validation from another model.
Eg.
I use a Model (Images) with this behavior. Another Model (Product) "hasOne Image". I have custom validation on the "product_id" field for "isUnique" (I'm trying to enforce the hasOne image). If I upload straight through the Images model, everything is fine. If I upload through the Product Model the validation fails, but I don't get the error back.
A bit frustrating, but for all what this behavior does, it's worth it.
Thanks for your Great Work!
I wonder if it is possible to upload PDF and video files by modifying MeioUpload Behavior.
Comments are closed for articles over a year old