MeioUpload Behavior – An improved File Upload Behavior for CakePHP

MeioUpload Behavior is an improved File Upload Behavior for the CakePHP framework. It’s based on the Digital Spaghetti’s Upload Behavior.

Juan Basso created a project hosted at github. I am unable to keep working on this behavior an he is making some updates to the code. I think github is a great tool because you can simply fork the project and make your own changes. Go check his work: http://github.com/jrbasso/MeioUpload/tree/master

Download

MeioUploadBehavior version 1.0.1

Related Articles

Features

  • Can be used for any kind of files;
  • Accepts custom directory for files to be uploaded;
  • Validates the file extension and mime-type due to the behavior configuration;
  • Validates the max file size;
  • Allow custom validation rules;
  • Allow as many thumbnails formats as you want;
  • Allow more then one field to be uploadable, with custom options per field;
  • Stores the directory, filesize, and mime-type in the database if the table has these fields. Also allows to customize these fields names;
  • Allow the use of default files and deleting files without deleting the entire record;
  • Delete files when the record is deleted or updated with a new file;
  • Also works in the $model->saveAll method.

Usage

  1. Place the meio_upload.php file in your app/models/behaviors folder;
  2. If you want to use thumbnails, download Nate’s phpThumb Component and place it in your app/controllers/components folder;
  3. Insert in your model table a character varying field:
    CREATE TABLE `products` (
    `id` int(8) unsigned NOT NULL auto_increment,
    `name` varchar(255) default NULL,
    `description` text default NULL,
    `price` double default NULL,
    `picture` varchar(255) default NULL,
    `dir` varchar(255) default NULL,
    `mimetype` varchar(255) NULL,
    `filesize` int(11) unsigned default NULL,
    `created` datetime default NULL,
    `modified` datetime default NULL,
    PRIMARY KEY  (`id`) ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
    
  4. Add the MeioUpload in the $actsAs of your model:
    var $actsAs = array(
        'MeioUpload' => array(
            'picture' => array(
                'dir' => 'img{DS}{model}{DS}{field}',
                'create_directory' => true,
                'allowed_mime' => array('image/jpeg', 'image/pjpeg', 'image/png'),
                'allowed_ext' => array('.jpg', '.jpeg', '.png'),
                'thumbsizes' => array(
                    'normal' => array('width'=>200, 'height'=>200),
                ),
                'default' => 'default.jpg',
            )
        )
    );
    
  5. Use a form file input to the field:
    echo $form->input('picture', array('type' => 'file'));
    
  6. Make sure your form has multipart/form-data enctype:
    echo $form->create('Product',array('type' => 'file'));
    
  7. Make sure the PHP has permission to write in the folder yous specified and the php.ini allow the MAX_FILE_SIZE you specified.

Options

When you apply the MeioUpload Behavior to a Model, you pass an array with your options. Here are the options you can change and it’s defaults.

  1. dir

    The folder where the uploaded files will be saved. It must be inside the app/webroot directory and defaults to an empty string, what means that it will be the app/webroot itself. If you specify some path, then it will be app/webroot/the_path_you/specified. In this option you may use the {DS} pattern, what will be converted to ‘/’ in UNIX systems and to ‘\’ in Windows systems.
  2. allowed_mime

    This option specifies the allowed mime-types for the files. It defaults to an empty array. What means that every mime-type will be accepted. But if you specify an array with the mime-types allowed, only files of these mime-types will be accepted.
    var $actsAs = array(
        'picture' => array(
            'allowed_mime' => array('image/jpeg', 'image/pjpeg', 'image/png')
        )
    );
    
    The code above says that the picture field will be a file uploaded, and it allows ‘image/jpeg’, ‘image/pjpeg’ and ‘image/png’ mime-types.
  3. allowed_ext

    This option specifies the allowed file extensions. It defaults to an empty array. What means that every extension will be accepted. But if you specify an array with the extensions allowed, only files with these extensions will be accepted.
    var $actsAs = array(
        'picture' => array(
            'allowed_ext' => array('.jpg', '.jpeg', '.png')
        )
    );
    
    The code above says that the picture field will be a file uploaded, and it allows ‘.jpg’, ‘.jpeg’ and ‘.png’ extensions.
  4. create_directory

    If you want to create the directory specified in the dir option if it don’t exists, then set this option to true. It already defaults to true, but you can set it to false.
  5. max_size

    The max file size allowed in the upload. Be sure it’s lower then the php.ini configuration. You can set a numeric value of bytes, or set it in other unit like ‘8 Kb’, only ‘kb’, ‘mb’, ‘gb’ and ‘tb’ units are allowed and it’s not case-sensitive. It defaults to 2 Mb.
    var $actsAs = array(
        'picture' => array(
            'max_size' => '4 Mb'
        )
    );
    
  6. default

    If you have a file that you want to use if the field is left blank, like a default picture for users who don’t have one, set this option to the name of this file. Make sure it is inside the folder specified in the ‘dir’ option.
    var $actsAs = array(
        'picture' => array(
            'default' => 'default.jpg'
        )
    );
    
  7. fields

    With this option you can customize the field inside your model table, where the data will be saved. The filename is the key of the options array, and you can setup fields to store the filesize, mime-type and directory. It defaults to ‘filesize’, ‘mimetype’ and ‘dir’ respectively, but you can customize with an array:
    var $actsAs = array(
        'picture' => array(
            'fields' => array(
                'filesize' => 'picture_filesize',
                'mimetype' => '{field}_mimetype',
                'dir' => 'pictures_folder'
            )
        )
    );
    
    The code above says that your filesize, mimetype and dir fields will be ‘picture_filesize’, ‘picture_mimetype’ and ‘picture_folder’ respectively. And the filename field will be pictures. You may notice that in mimetype case, i used the constant {field} that will be replaced with the field name(picture in this case).

Validations

The behavior automatically include some validations to your field. Here they are:

  1. FieldName Checks if the field has been setup to be and uploadable.
  2. Dir Checks if the directory exists or if it can be created. This validation depends on the option ‘create_directory’.
  3. Empty Checks if the filename is not empty. It defaults to be used only on create.
  4. UploadError Checks if ocurred erros in the upload.
  5. MaxSize Checks if the file isn’t bigger then the max file size option.
  6. InvalidMime Checks if the file is of an allowed mime-type.
  7. InvalidExt Checks if the file has an allowed extension.

You can overwrite any of the parameters of these default validation rules. Directly in the model $validate var:

var $validate = array(
    'picture' => array(
        'Empty' => array(
            'check' => false
        ),
        'InvalidExt => array(
            'message' => 'This file extension isn't allowed.'
        )
    )
);
In the code above, i changed the message for the ‘InvalidExt’ default validation. You can also disable any of the default validations by setting the ‘check’ atribute fo false as is shown in the example above for the ‘Empty’ default validation. You can change any of the other parameters of the built-in cake validation:
var $validate = array(
    'picture' => array(
        'Empty' => array(
            'rule' => array('YourDefaultValidation'),
            'on' => 'update',
            'required' => true
        ),
    )
);
You can also change the validation rule for one you have created. But use this functionality carefully.

Setting up file removing

If you send a form data with as field named data[Model][field][remove] not empty, then the behavior will automatically delete the file associated with the record and set it’s value to the default, if it is set, or to empty. To achieve this you can add a checkbox to your form:

echo $form->input('Product.picture.remove', array('type' => 'checkbox'));

138 Responses to “MeioUpload Behavior – An improved File Upload Behavior for CakePHP”

  1. 1
    MeioUpload Behavior 1.0 released! | Meio Código Says:

    [...] am glad to show you the MeioUpload Behavior 1.0. An improved Upload Behavior for CakePHP 1.2. It turns file uploads as simple as definig a [...]

  2. 2
    Nookie Says:

    Is it possible to upload multiple files ?

  3. 3
    Vinicius Mendes Says:

    Yes, it is possible to upload multiple files. But it is not so transparent. I will post an example of this.

  4. 4
    Joey Says:

    I’m looking forward to seeing the multiple image demo!

  5. 5
    luke Says:

    looks good – is it using saveAll the multiple method?

  6. 6
    luke Says:

    hi Vinicius

    I get an error in upload behaviour – fixName() function throws an error (although upload is working and file is saved).

    $this->__model->data is empty array by the time this is called. (so after a validation ?)

    It makes an error notice

  7. 7
    luke Says:

    sorry, just been trying it out. Validation doesnt seemt to work and throws an error for use of Empty validation:

    Warning (2): preg_match() expects parameter 2 to be string, array given [CORE/cake/libs/validation.php, line 876]

  8. 8
    Vinicius Mendes Says:

    Luke,

    I need to know what you made. How is your model? What’s the name of the file you are wanting to upload? You used custom validation rules in your model? It’s very hard to detect an error just with the error message. I will be happy if you answer these questions.

  9. 9
    luke Says:

    Hi Vinicius – thanks for the reply. No, I used just the validation you had.

    I am going to try with the Product model demo I have found and see if I can get it to work. Should this be compatible with RC3 and RC2 of cake 1.2?

  10. 10
    Russell Griffith Says:

    Hello, are the fields defined in the ‘fields’ option optional fields? What I mean is the example field given above “picture varchar(255) default NULL” sufficient for the file to be uploaded or do I need to have the fields filesize, mimetype and dir in my Model.

    Also, wouldn’t multiple images be handled like this:

    var $actsAs = array( ‘MeioUpload’ => array( ‘picture1′ => array( ‘dir’ => ‘img{DS}{model}{DS}{field}’, ‘create_directory’ => true, ‘allowed_mime’ => array(‘image/jpeg’, ‘image/pjpeg’, ‘image/png’), ‘allowed_ext’ => array(‘.jpg’, ‘.jpeg’, ‘.png’), ‘thumbsizes’ => array( ‘normal’ => array(‘width’=>200, ‘height’=>200), ), ‘default’ => ‘default.jpg’, ), ‘picture2′ => array( ‘dir’ => ‘img{DS}{model}{DS}{field}’, ‘create_directory’ => true, ‘allowed_mime’ => array(‘image/jpeg’, ‘image/pjpeg’, ‘image/png’), ‘allowed_ext’ => array(‘.jpg’, ‘.jpeg’, ‘.png’), ‘thumbsizes’ => array( ‘normal’ => array(‘width’=>200, ‘height’=>200), ), ‘default’ => ‘default2.jpg’, ) ) );

  11. 11
    Vinicius Mendes Says:

    @luke I tested it with RC3, but I think it works OK with RC2.

    @Russel Griffith Yes, only the picture field is sufficient, the other ones is available if you want to store these informations in the database. About the multiple upload, it can be this way you said, but in this case, you will limit the amount of files to 2, and you will have two fields in your table to store the path to the files. I think the best way to make multiple uploads is have a model just for uploads and have a row in its table for each uploaded file.

  12. 12
    Russell Griffith Says:

    Thank you for your quick response and answers. About multiple file uploads, I see what you are saying about having a model just for uploads, but wouldn’t that also necessitate a join (called has_many :through in RoR) that would also necessitate an extra field in the “through” table to help identify what type of image it was?

    The kind of join I’m thinking this would have to be is outlined in this article.

    http://debuggable.com/posts/modeling-relationships-in-cakephp-faking-rails-throughassociation:480f4dd6-b990-485e-abe4-4baccbdd56cb

    Seems to me this is the only way to have multiple images related to back to one model. Would you agree with this?

    Hope this makes sense.

  13. 13
    Joey Says:

    is there an easy way to make the thumbnails crop the image instead of keeping the proportions and resizing?

  14. 14
    Joey Says:

    oh, nevermind. i sorted it out. thank you for this! works great!

  15. 15
    luke Says:

    Hi Vin.

    I have tried again just now with the Product demo files you gave using RC3 and I bake the products_controller. I still get a notice for Notice (8): Undefined index: Product [APP/models/behaviors/meio_upload.php, line 506]

    it is the rename fix function. There is no data any more in the array at this point.

    My model, view and my database are EXACTLY as you have in the demo folder.

    I am thinking it is maybe because I do not use a thumbs component? It does upload the file and so on so I can avoid the notice by turning errors off, but I prefer not to.

    thanks for your help. It’s a nice behaviour alright :)

  16. 16
    luke Says:

    I can email you the code but how can I show you on here? I dont think it is possible? Can you email me if you want to see the code? Thank you again for your time and work on this.

  17. 17
    luke Says:

    Hi Vinicius is there a way to disable the validation the behavior does? I will use a custom function I have , which works in a basic way.

    I sent you a zip file yesterday after you mailed me – hope you got it OK!

    thank you for your help on this. thanks, Luke

  18. 18
    Sergio Says:

    Hi,

    great entry! I’m trying to upload images y thumbnails, the image get saved in the specified folder, but it looks like the thumb component is not working. Any idea what am I doing wrong?

    Regards

  19. 19
    jarrett Says:

    Nice piece of code, very helpful, would it b possible and efficient 2 include this behavior in the app_model.php, if most of your models are using it?. And how would I go about this?

  20. 20
    Vinicius Mendes Says:

    @Sergio Without seeing the code I am unable to say what you are doing wrong. To use thumbnails, you have only to write put the component in components path (/app/controllers/components/) and set it in the model. There is an example of this in the docs. Just one thing: if you set the name of the thumbnail as normal, it will resize the file uploaded to this size and overwrite the uploaded one.

  21. 21
    Vinicius Mendes Says:

    @jarret If your models have the same field to store the uploaded file, you can do this. But I think theres a better solution, using a model to store all the files. For example: File. And make a relationship with all models using PolymrpicBehavior ( http://bakery.cakephp.org/articles/view/polymorphic-behavior )

  22. 22
    jarrett Says:

    Tx for fast reply, much appreciated. I had a look at your link, but failed epically:-D. So I created a file manager model separately, based on your behavior, and added a belongsTo relationship to each model using images. And in my controller, before a save, I have, $this->City->Filemanager->save($image) $this->data['City']['filemanager_id'] = $this->City->Filemanager->getLastInsertID(); and it works great:-), tx again, and keepit up..jj

  23. 23
    Vinicius Mendes Says:

    @jarret That’s not the best way to do this. I think the City doesn’t belongs to the File. In my point of view, the File belongsTo the City. And the Polymorphic behavior allows this. It’s basic concept is that you have a foreign key attribute, and a model name attribute. So each File will belong to a different model. And to know wich model the File belongs to, you just have to check it’s model name attribule.

    I saw somewhere an example showing how to use the polymorphic behavior with the upload behavior I was based, but I can’t find it anymore.

  24. 24
    jarrett Says:

    So saving it in a separate model (Filemanager) that handles file uploads and then getting the id and storing it in the model (City) that uses images, not the best way, I see your point, while applying my previous solution through 15 models that all have images. I will spend today on the link you sent me, tx again V…jj

  25. 25
    lucas Says:

    you say that this requires phpthumb, and in your createthumb function you import the Thumb component. however, your code never seems to actually use the Thumb component or phpthumb. what gives????

  26. 26
    Vinicius Mendes Says:

    @lucas This is a requirement of the behavior I used as base. I think you actually don’t need it. You can try it and tell us the result.

  27. 27
    Daniel Says:

    Bom Dia Vinicius, Como que ue faço pra enviar multiplos arquivos com o teu behavior? no caso vo ter vários campos com o nome de imagem[]. No caso seria um array de várias imagens, como eu trato isso com o Behavior?

    Obrigado.

  28. 28
    Gabriel Says:

    Hello

    I have the same problen than luke. It loads the file but it displays the following message :

    Notice (8): Undefined index: {Model} … in 550 meiouploadbehavior::fixname() – [internal], line ?? meiouploadbehavior::fixname() – /homez.40/…/cakephp/app/models/behaviors/meio_upload.php, line 550 meiouploadbehavior::beforesave() – /homez.40/…/cakephp/app/models/behaviors/meio_upload.php, line 628 meiouploadbehavior::dispatchmethod() – /homez.40/…/cakephp/cake/libs/model/behavior.php, line 163 behaviorcollection::trigger() – /homez.40/… /cakephp/cake/libs/model/behavior.php, line 445

    My website runs with CakePHP 1.2.0.7692 RC3

    Thanks for your help

  29. 29
    Luke Says:

    Hi Gabriel, I never have managed to fix this. I am waiting for a new release to try again and perhaps with another version of cake (latest SVN). I tried with RC2 and RC3. But others do not have the problem so I wonder what causes it.

  30. 30
    Gabriel Says:

    Hi Luke,

    Thanks for your answer.

    I noticed another problems. If I load 2 times the same file, the older version is replaced with the new one (the new one isn’t renamed). It failed to create automaticaly a new folder.

    It’s pity because this bahaviour looks great and convenient.

    So do you know another tools for cake to upload files ?

    Gabriel

  31. 31
    Russ (rgreenphotodesign) Says:

    The site I listed is not the one I’m using this for. But I do have a question. Hope it’s not a stupid one :)

    I have a model called Miscfile and the database contains the basic elements in your example with a couple of custom fields.

    var $actsAs = array( ‘MeioUpload’ => array( ‘audiofile’ => array( ‘dir’ => ‘userfiles{DS}audio’, ‘create_directory’ => true, ‘allowed_mime’ => array(‘audio/wav’), ‘allowed_ext’ => array(‘.wav’), ),

       )
    );
    

    I can’t seem to get any data to store in the table, the file uploads fine, but nothing in the database.

    here is my action in controller. function add() { $this->Miscfile->saveAll($this->data); $this->set(‘message’, ‘Your file has been uploaded’); $this->render(‘audio’); }

    View:

    create(‘Miscfile’, array(‘type’ => ‘file’)); ?> input(‘audiofile’, array(‘type’ => ‘file’)); ?> input(‘title’); ?> end(‘Upload File’); ?>

    Again the file uploads fine, but no DB. Feels like I’m missing something super simple or obvious!

  32. 32
    faemino Says:

    Hi Vinicius, First thanks for this useful behavior.

    When I try to update a model from a form with a “remove” checkbox (set true), the recordset be updated but the file isn’t deleted.

    Dive in your code in the beforeSave method the next code block:

    //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($fieldName); }

    don’t delete the file in edit action.

    For now I’ve put these ugly else:

    } else {
    $this->setFileToRemove($fieldName); }

    And edit and file deletion works fine. Another actions like add works too. For now, I can’t look better your code and learn about it to see if I’m wrong or to propose a better solution than a else.

    Sorry for my poor english. Cheers and thanks faemino

  33. 33
    gabriel Says:

    Hi Luke,

    I found the problem for the following message :

    Notice (8): Undefined index: {Model} … in 550 meiouploadbehavior::fixname() – [internal], line ??

    I left caracters after “?>” tag in my class or files configuration. Now it’s ok.

    However I have still this problem : If I load 2 times the same file, the older version is replaced with the new one (the new one isn’t renamed).

    See you

    Gabriel

  34. 34
    gabriel Says:

    Hello,

    What’s happen if I download the same file 2 times (2 rows in the db for one file in the same directoy) and I delete one row in the DB ?

    See you !

  35. 35
    Tickão Says:

    Olá, sou iniciante no Cake.

    Fiz e refiz os passos e não consegui fazer o upload.

    O sistema está em desenvolvimento no windows, tentei varias vezes mas simplesmente não faz o upload, não grava o campo file no BD e não dá nenhum erro.

    Será que vc poderia me ajudar? Fora os procedimentos acima precisa mais algum outro no controller por exemplo?

  36. 36
    Gabriel Says:

    I notice you should set variable debug on 0.

    If debbug > 0 you’ll have the following error :

    Notice (8): Undefined index: {Model} … in 550 meiouploadbehavior::fixname() – [internal], line ??

  37. 37
    berger Says:

    Hi, everything works almost fine with me. Except the redirect after add and delete. For some reasons it gets redirected to the same page (add to add, delete to delete). In the case of delete this results in an infinite loop… any suggestions?

    greetz berger

  38. 38
    Sparkybarkalot Says:

    I’m having problems getting this to work and I’m wondering if you have a solution. When I hit the submit button for the form, I get this notice and error: “Notice (8): Array to string conversion [CORE\cake\libs\model\datasources\dbo_source.php, line 571]” and “Warning (512): SQL Error: 1054: Unknown column ‘Array’ in ‘field list’ [CORE\cake\libs\model\datasources\dbo_source.php, line 514]” I found two recommended solutions elsewhere online, but neither solved my problem. This is in my model: var $actsAs = array( ‘MeioUpload’ => array( ‘picture’ => array( ‘dir’ => ‘files{DS}pictures’, ‘allowed_mime’ => array(‘image/jpeg’, ‘image/pjpeg’, ‘image/png’), ‘allowed_ext’ => array(‘.jpg’, ‘.jpeg’, ‘.png’), ‘default’ => ‘default.jpg’ ) ) );

    This is in my view: create(‘Painting’, array(‘type’ => ‘file’)); ?>

    input('title');
        echo $form->input('location_id');
        echo $form->input('size');
        echo $form->input('date_moved');
        echo $form->input('picture', array('type' => 'file'));
    ?>
    

    end(‘Submit’);?>

    Any suggestions?

  39. 39
    Mohammad Nuaimat Says:

    Dear

    how can i specify ‘dir’ config such that it creates a folder for current model and a subfolder for current model record id then place the file inside this subfolder.

    ex: Model: Profile Id: 12 Fname: test.jpg

    this should be found in /webroot/files/Profile/12/test.jpg

    anyway ??

  40. 40
    John Says:

    Hi. First of all I just want to say thanks for making such a useful bit of code available to everyone. I’ve got the behaviour working in a basic way with no problems at all.

    Apologies in advance as this is probably a really obvious question. I wanted to save the field(s) using a habtm relationship.

    Product HABTM Image

    My Models are as follows:

    array(‘className’ => ‘Image’, ‘joinTable’ => ‘images_products’, ‘foreignKey’ => ‘product_id’, ‘associationForeignKey’ => ‘image_id’, ‘unique’ => true, ‘conditions’ => ”, ‘fields’ => ”, ‘order’ => ”, ‘limit’ => ”, ‘offset’ => ”, ‘finderQuery’ => ”, ‘deleteQuery’ => ”, ‘insertQuery’ => ” ) );

    } ?>

    array(‘className’ => ‘Product’, ‘joinTable’ => ‘images_products’, ‘foreignKey’ => ‘image_id’, ‘associationForeignKey’ => ‘product_id’, ‘unique’ => true, ‘conditions’ => ”, ‘fields’ => ”, ‘order’ => ”, ‘limit’ => ”, ‘offset’ => ”, ‘finderQuery’ => ”, ‘deleteQuery’ => ”, ‘insertQuery’ => ” ) );

    /* use the upload compaonent */
    var $actsAs = array(
        'MeioUpload' => array(
            'filename' => array(
                'dir' => 'img{DS}{model}{DS}{field}',
                'create_directory' => true,
                'allowed_mime' => array('image/jpeg', 'image/pjpeg', 'image/png'),
                'allowed_ext' => array('.jpg', '.jpeg', '.png'),
                'thumbsizes' => array(
                    'small'  => array('width'=>100, 'height'=>100),
                    'medium' => array('width'=>220, 'height'=>220),
                    'large'  => array('width'=>800, 'height'=>600)
                )
                /*'default' => 'default.jpg',*/
            )
        )
    );
    

    } ?>

    And my view is really simple:

    create('Product', array('type' => 'file'));?>
    
    
        input('name');
        echo $form->input('live');
        echo $form->input('deleted');
        //echo $form->input('Image.filename', array('type' => 'file'));  
    
    ?>
    
        Filename
    
    
    
    
    
    end();?>
    

    and my view

    data)) {

            //pr($this->data);
    
            $this->Product->create();
            if ($this->Product->save($this->data)) {
                $this->Session->setFlash(__('The Product has been saved', true));
                $this->redirect(array('action'=>'index'));
            } else {
                $this->Session->setFlash(__('The Product could not be saved. Please, try again.', true));
            }
        }
        $images = $this->Product->Image->find('list');
        $this->set(compact('images'));
    }
    

    I don’t get any error messages, it is just that the image isn’t uploaded and no data is saved to the images table.

    Any help would be greatly appreciated. Thanks.

    Thanks

  41. 41
    John Says:

    Hi – I sorted the problem. I was just being a muppet and it all works beautifully. I changed the relationship from HABTM to Product has Many Images (which is fine as I plan to use the polymorphic behaviour to attach multiple models).

    I also changed the controller from: $this->Product->save($this->data) to $this->Product->saveAll($this->data)

    Thanks.

  42. 42
    gabriel Says:

    Hi,

    I have problem with validation : preg_match() expects parameter 2 to be string, array given [/homez.40/.../cakephp/cake/libs/validation.php, line 877]

    See you

    Gabriel

  43. 43
    gabriel Says:

    I have solved the problem with validation : you have to use PHP5 and I used PHP4

  44. 44
    Noel Says:

    Hello !

    I’d like to say that this project helped me a lot in my own. But I’m facing a small problem now : I can’t delete the files I uploaded via the checkbox. When I put the file to delete in the input, check the box, a new entry is inserted in my DB.

    Can anyone tell me what’s the problem ?

    Thanks in advance.

  45. 45
    John Says:

    Hi Vinicius. I’ve been playing around trying to upload multiple files at the same time – i.e. Product has many ProductImages – in order to save the images I’m using the following in my controler: function admin_add() { if (!empty($this->data)) { $this->Product->create();

            if ($this->Product->save($this->data)) {
    
                $product_id = $this->Product->getLastInsertId();
    
                    // this is multiple images          
                    foreach($this->data['ProductImage'] as $ProductImage => $value){              
    
                        $this->Product->ProductImage->create();
                        $value['product_id'] = $product_id;
                        $this->Product->ProductImage->save($value);
                    }
    
                $this->Session->setFlash(__('The Product has been saved', true));         
                $this->redirect(array('action'=>'index'));            
    
            } else {
                $this->Session->setFlash(__('The Product could not be saved. Please, try again.', true));
            }
        }
    }
    

    The $this->data array would look like this:

    Array ( [Product] => Array ( [name] => Product 0 [live] => 1 )

    [ProductImage] => Array
        (
            [0] => Array
                (
                    [filename] => Array
                        (
                            [name] => doves.jpg
                            [type] => image/jpeg
                            [tmp_name] => E:\xampp\tmp\php7A.tmp
                            [error] => 0
                            [size] => 21024
                        )
    
                )
    
            [1] => Array
                (
                    [filename] => Array
                        (
                            [name] => 2960-medium.jpg
                            [type] => image/jpeg
                            [tmp_name] => E:\xampp\tmp\php7B.tmp
                            [error] => 0
                            [size] => 134256
                        )
    
                )
    
        )
    

    )

    But I was wondering if there was a better way of dealing with this? You mentioned in one of the comments above that you were planning to put up an example of uploading multiple files.

    What I’ve done it above is fine but it would be so much more elegant to push it into the behaviour.

    Cheers

  46. 46
    唯枫志 - CakePHP中使用MeioUpload Behavior上传图片 Says:

    [...] 这款MeioUpload Behavior真是帮我解决了大问题,感谢作者和阿辉,另外CakePHP的app/models/behaviors目录是专门用来存放相关行为处理文件的,大家如果想省事儿,可以到http://bakery.cakephp.org/来先找找有没有人事先写好的代码,记录下图片上传先。 我的文章表里有两个字段:thumbnailimg 和 largeimg ,分别代表小图和大图,文章添加时上传的两张图片到webroot/files/images下,并把路径和文件名分别保存到这两个字段,实现过程如下: [...]

  47. 47
    wkeeper Says:

    Hi, Thank you for this nice behavior!

    I have a small problem. When I’m trying to leave the upload field empty (for example, I want to update other field of the object), behavior replaces filename in database record to the “default.jpg”.

    Does anybody know any solution?

  48. 48
    CorneyWalls Says:

    First of all thnx for such a nice piece of code, its working perfectly in my case expect the thumbnails part, (i copied the phpthumb files to “app\vendors\phpThumb\”, and copied the thumb component to “app\controllers\components\” direcotry ) the model controller and views in my code are as follows.

    ///////////////////////////////////////// data)){ $this->Image->save($this->data); } }
    ?>

    ////////////////////////////////////////////////////// create(“images”,array(“acction”=>”add”,’type’ => ‘file’)); echo $form->input(‘Image.name’, array(‘type’ => ‘file’)); echo $form->end(“Upload”); ?>

    ///////////////////////////////////////////////////// array( ‘name’ => array( ‘dir’ => ‘users_files{DS}posts{DS}images’,
    ‘create_directory’ => true, ‘allowed_mime’ => array(‘image/jpeg’, ‘image/pjpeg’, ‘image/png’), ‘allowed_ext’ => array(‘.jpg’, ‘.jpeg’, ‘.png’), ‘thumbsizes’ => array(‘normal’ => array(‘width’=>200, ‘height’=>200)) ) ) );

    }

    ?> /////////////////////////////////////////

    is there any idea about why the thumbnails are not being created

    thanks

  49. 49
    CorneyWalls Says:

    First of all thnx for such a nice piece of code, its working perfectly in my case expect the thumbnails part, (i copied the phpthumb files to “app\vendors\phpThumb\”, and copied the thumb component to “app\controllers\components\” direcotry )

    i have uploaded the code files here http://www.weborbs.com/files.zip

    is there any idea about why the thumbnails are not being created

    thanks

  50. 50
    Meshach Says:

    faemino,

    Your problem is what I was seeing too, but the solution you offered doesn’t work. Namely, it doesn’t delete images when you edit to override them. Instead of adding a redundant “else” statement, simply remove the “!” on line 623, and it’ll work. The problem appears to have simply been a typo. Here’s what my line 623 of the meio_upload.php looked like before:

    if(!empty($model->data[$model->name][$model->primaryKey])){ $this->setFileToRemove($fieldName); }

    Which I changed to: if(empty($model->data[$model->name][$model->primaryKey])){ $this->setFileToRemove($fieldName); }

    Seems to be working fine now.

    Great work, vin.

  51. 51
    Meshach Says:

    Sorry for the error above. After posting it, I found the real issue. Line 623 SHOULD STAY THE SAME. The problem was that I wasn’t sending the “ID” with my edit form. There is no state check for the if statement on line 623, it’s just checking for whether the file being uploaded is coming with an id already attached. If it is, then it knows that it’s either editing or deleting. I was submitting edits with no id, which meant all things were wrong in the world ;-) .

    It’s fixed now. Here’s my edit form:

    echo $form->input(‘id’); echo $this->element(’show_screenshot’, array(‘picture’ => $this->data['Screenshot']['picture'], ’size’ => ‘t’)); echo $form->input(‘name’); echo $form->input(‘project_id’); echo $form->input(‘resource_id’); echo $form->input(‘picture’, array(‘type’ => ‘file’)); echo $form->input(‘dir’, array(‘type’ => ‘hidden’)); echo $form->input(‘mimetype’, array(‘type’ => ‘hidden’)); echo $form->input(‘filesize’, array(‘type’ => ‘hidden’));

    … notice that I’ve ‘hidden’ my dir, mimetype, and filesize fields, as I don’t want them overridden in edit mode, but the id is automatically hidden by cakephp’s ‘automagic’ form fields, since it’s called ‘id’, and already has a value.

    Enjoy!

  52. 52
    Ramsalt Says:

    Hello. Nice behavior. Trying to use it but had som e problems. I tried overriding default in the actAs options, but it didn’t want to overriden. I changed

    $this->__model->validate[$fieldName] = $this->arrayMerge($options['validations'],$this->__model->validate[$fieldName]);

    to

    $this->__model->validate[$fieldName] = $this->arrayMerge($this->__model->validate[$fieldName],$options['validations']);

  53. 53
    Поведінки, CakePHP та завантаження файлів на сервер. | Meelky Blog Says:

    [...] в таблицю. Як завжди, все дуже просто. Використуєм MeioUpload Behavior написаний Vinicius Brandao [...]

  54. 54
    David Says:

    Hey thanks!!! That behavior really help me, its great!

  55. 55
    Mee Says:

    Hello,

    One more time, thanks for this great behavior. Nevertheless, I have few questions or maybe feautre requests. 1. As far as I understand it doesn’t remove the trash. For example, if I have a record with one file uploaded and then user upload another, first one stays on server’s hard drive. 2. Is it possible to attach a custom name to uploaded file, like record’s ID or some kind of hash to prevent file overwriting when different images with same name are uploaded?

    Thanks in advance for answers, and for you work. mee

  56. 56
    Vinicius Mendes Says:

    Mee,

    All these things you are saying are working in the behavior.

    What PHP version you are using? It seems like the behavior don’t work well with PHP 4. Try using PHP 5.

  57. 57
    Mee Says:

    Vinicius Mendes,

    I’m sorry, double checked, no trash. But as far as I understood there is no way to set up my own names instead of original file names with additional numbers?

  58. 58
    Manop Kongoon Says:

    How to rename file to upload. e.g. id of insert record…..

  59. 59
    vbmendes Says:

    There’s no way to achieve this with this behavior. But the behavior, if used with php 5 renames the file if it already exists.

    To rename with the id is a bit complicated, since it uploads the file before saving it. So, when the file is saved, the id isn’t obtained yet.

  60. 60
    Manop Kongoon Says:

    how to rename file by yearmonthday and time eg. 20090211101450.jpg

  61. 61
    vbmendes Says:

    The MeioUpload don’t support renaming the file. It simply renames files that have the same name.

  62. 62
    vbmendes Says:

    @CorneyWalls

    Thumbsizes with ‘normal’ as key will be the size of the original uploaded image. So, you have to define a key diferent from ‘normal’.

  63. 63
    sutehi Says:

    I’m just beginning to learn my way around cakePHP, and have run into difficulty getting this behavior to work. I’m sure that I’m just doing something wrong, but haven’t been able to figure out.

    I’ve got a simple cakePHP app based on 1.2.1.8004 stable. I have a “Teachers” model, to which I’m trying to attach an image file. Right now, “picture” is an attribute of the Teachers model; once I’ve gotten the behavior working, I’ll worry about moving the attachment over to a separate associated model.

    I’ve downloaded meio_upload.php, and placed it in /app/models/behaviors.

    models/teacher.php (snippet):

    var $actsAs = array( // models/behaviors/meio_upload.php ‘MeioUpload’ => array( ‘picture’ => array( ‘dir’ => ‘files{DS}uploads{DS}{model}’, ‘create_directory’ => true, ‘allowed_mime’ => array(‘image/jpeg’, ‘image/pjpeg’, ‘image/png’), ‘allowed_ext’ => array(‘.jpg’, ‘.jpeg’, ‘.png’), ) ) );

    views/teachers/admin_add.thtml:

    create(‘Teacher’,array(‘type’ => ‘file’)); ?>

    input(‘name’); echo $form->input(‘picture’, array(‘type’ => ‘file’)); ?>

    end(‘Add Teacher’); ?>

    When I post the form, I get the following:

    Notice (8): Array to string conversion [CORE/cake/libs/model/datasources/dbo_source.php, line 571]

    Warning (512): SQL Error: 1054: Unknown column ‘Array’ in ‘field list’ [CORE/cake/libs/model/datasources/dbo_source.php, line 514]

    The posted image’s entire metadata array is being fed to the insert statement, rather than just the image’s filename. I presume this means I haven’t properly installed or initialized meio_upload.php? The notice given (regarding array to string conversion) sounds very relevant to this problem, but I’m not sure what that notice is actually telling me. The line it references is part of the create() function in “The ‘C’ in CRUD”:

    $query = array( ‘table’ => $this->fullTableName($model), ‘fields’ => join(‘, ‘, $fieldInsert), ‘values’ => join(‘, ‘, $valueInsert) <– This line );

    http://www.meiocodigo.com/projects/meioupload/#comment-6214 appears to be having the same issue, although I didn’t see a reply to his comment.

    If anybody has any suggestions on how I might go about troubleshooting this further, or spots the obvious thing I am no doubt missing, I would very much appreciate your comments.

    Thank you for your time.

  64. 64
    vbmendes Says:

    @sutehi Why don’t you use the default $this->Teacher->save($this->data). Looking at your code, it seems like you are trying to create the insert query “by hand” without using the CakePHP database abstraction.

  65. 65
    sutehi Says:

    @vbmendes Thank you for the reply. I think we might have a miscommunication. When you say it looks like I am trying to create the insert query by hand, are you referring to the bit of code that I quoted from CORE/cake/libs/model/datasources/dbo_source.php? This is code which ships with cakePHP, not something I’ve written myself. I just included it, because the notice message I received referenced that bit as being related to the problem.

    My teachers_controller.php does in fact all ready use $this->Teacher->save($this->data) to save the Teacher object.

  66. 66
    calvin Says:

    Hey Vinicius, this is a great plugin. It has saved me a ton of development time and works better than my past implementations.

    However, I did run into a minor a problem while employing MeioUpload. While I did eventually find the solution, it’s not completely obvious, so I thought I’d post it here to save others some time.

    Basically, I wanted the “picture.remove” checkbox to be unchecked by default so that when the user won’t accidentally delete an uploaded picture while editing other fields. But since ‘picture’ is never empty in this situation, Cake’s Form Helper automatically enabled the ‘checked’ attribute by default.

    Initially, I tried to set the ‘checked’ attribute to “unchecked” like so:

    $form->input(‘picture.remove’, array(‘type’ => ‘checkbox’, ‘checked’ => ‘unchecked’));

    But that did not work. Neither did setting it to “false” or “no.” Eventually, I came upon the embarrassingly simple solution of simply setting the ‘value’ attribute to an empty string:

    $form->input(‘picture.remove’, array(‘type’ => ‘checkbox’, ‘value’ => ”));

    So maybe that will save others a little time. If this solution seems obvious, and I’m just dumb, then please ignore or delete this comment.

  67. 67
    Sytze Loor Says:

    @sutehi; I’m also bumping into the problem of the Array in the field list. It looks like the beforeSave function (line 596) in the behavior is not executed. On line 652-655 the model data should be updated, but this isn’t happening. Could you please check whether the beforeSave function is executed in your code? Meanwhile I’ll see whether I can fix the problem. Thank you…

  68. 68
    Vinicius Mendes Says:

    @Sytze Loor: Wich PHP version are you using? a recommend PHP 5.

  69. 69
    Sytze Loor Says:

    I’m using PHP5 (latest XAMP-release) with Cake 1.2.1.8004 Stable. I’m using the following configuration for the behavior: var $actAs = array( ‘MeioUpload’ => array( ‘file’ => array( ‘dir’ => ‘uploads’, ‘create_directory’ => true, ‘fields’ => array( ‘filesize’ => ‘filesize’, ‘mimetype’ => ‘filetype’, ‘dir’ => ‘directory’ ) ) ) ); Any help is welcome!

  70. 70
    Maurício Says:

    Estou tendo um problema na hora de fazer a edição de um cadastro, ele altera o cadastro certinho, e também faz o upload da nova imagem, porem não elimina do FTP a imagem antiga. Ahh e não apresenta erro algum. Se puder me ajudar, agradeço desde já.

  71. 71
    Blaz Says:

    Hi. Very nice behavior! But I have some problems. I have on “Model” which one can have multiple images. So “Model” HasMany Images and before I upload images I already have an id of last inserted “Model” ID and now I want to upload images like this uploads/”Model”/{“MODEL”_ID}/picture.jpg etc. I have tried something, but the problem is because $model in setup() have no data from controller and $model in beforeSave() have all this info, but in beforeSave() I don’t need this information’s :) Do you have any tip on that?

    “Model” = Whatever you want :)

    Thanks Best regards

  72. 72
    José Carlos Says:

    Hello Vinicius, First of all I want to congratulate you, MeioUpload is the best way to deal with file uploads that i found, this makes file upload realy painless! I found a problem in my application when I wrote a model that has two files, an ebook and a cover image, so i configure MeioUpload to deal with these two fields, but sometimes i needed to deal and upload only one field, and i was getting always an error about extension validation of the other file, because since it is declared, it is always validated. The solution i found was adding the following methods do MeioUpload:

    function disableField(&$model, $fieldName) { if(isset($this->__fields[$fieldName])) { $this->__disabledFields[$fieldName] = $this->__fields[$fieldName]; unset($this->__fields[$fieldName]); } }

    function enableField($fieldName) { if(isset($this->__disabledFields[$fieldName])) { $this->__fields[$fieldName] = $this->__disabledFields[$fieldName]; unset($this->__disabledFields[$fieldName]); } }

    and a $this->__disabledFields variable that would store disabled fields.

    Now i when i deal with the pdf file only, i disable cover image file settings, so it isnt validated and don’t cause errors.

    Cumprimentos!

  73. 73
    Sola Ajayi Says:

    @Manop Kongoon (#60) Hi, I found a way to rename a file before upload and its pretty simple. I just changed the filename before it was saved and it worked

    eg.

    if (!empty($this->data)) { $this->data['Model']['filename']['name'] = ‘new-filename.ext’; $this->Model->create(); if ($this->Model->save($this->data)) { ….

  74. 74
    mee Says:

    @Sola Ajayi Great idea, thanks a lot. I would be very useful, thanks.

  75. 75
    Manop Kongoon Says:

    Sola Ajayi – Great idea, thanks a lot.

  76. 76
    Anthony Says:

    Hi everyone, can someone help me please ..

    how to made the file that upload save to folder according user_id or yearmonth ?

    example: ‘dir’ => ‘files{DS}employee{DS}profile{DS}{user_id}’ ..\webroot\files\user\profile\1\
    ..\webroot\files\user\profile\2\ . . .

    or

    ‘dir’ => ‘files{DS}employee{DS}profile{DS}{month}, ..\webroot\files\user\profile901\
    ..\webroot\files\user\profile902\ . . .

    and thanks creator for this nice behavior! please me alot :-)

  77. 77
    Sean Says:

    You have done a wonderful job here, and saved people a huge amount of time. I think this should be in the core behaviors its really super helpful. Thanks again for sharing your hard work! We still look forward to a multiple file upload example!

  78. 78
    Adam Says:

    @Sparkybarkalot @sutehi @Sytze Loor and anyone else who gets an array field problem. I had it because I’d accidently put the script in the wrong location so it wasn’t getting called, and then I had to change the permissions.

    Once I had done that it was fine, so double check!

  79. 79
    Tipos de MIME Types | Daniel Pakuschewski Says:

    [...] usando o MeioUpload para fazer o Upload de arquivos. Precisei saber o MIME Type de um determinado arquivo, achei uma [...]

  80. 80
    Calvin Says:

    Vinicius, I have translated all of the error messages in MeioUpload into English. I did this for my own benefit, but perhaps it might be helpful to others as well.

  81. 81
    Sean Says:

    @Calvin Can you post those error messages in english. Thank you!

    Any example of multiple upload yet?

    Thanks for the great behavior.

  82. 82
    Calvin Says:

    Sean, I’ve posted a copy of my translation here: http://rottenrecords.com/tmp/meio_upload_v1.0.1_english.rar The readme file has a list of the changes.

  83. 83
    faemino.net » » Subir archivos en CakePHP Says:

    [...] desde una aplicación web, en el caso de usar CakePHP, se facilita mucho gracias al behavior MeioUpload de Vinicius [...]

  84. 84
    Sean Says:

    @Calvin

    Thanks for sharing!

  85. 85
    esezako Says:

    @Adam Can you explain better your solution to the problem of array errors?

  86. 86
    esezako Says:

    Hi, i have the following problem:

    I have 3 models, terms, images and sounds. A term hasmany images and sounds. I put my code:

    Models:———————————————————–

    class Image extends AppModel { var $name = ‘Image’; var $components = array(‘Thumb’); var $actsAs = array( ‘MeioUpload’ => array( ‘filename’ => array( ‘dir’ => ‘files{DS}terms{DS}images’, ‘create_directory’ => true, ‘allowed_mime’ => array(‘image/jpeg’, ‘image/pjpeg’, ‘image/png’), ‘allowed_ext’ => array(‘.jpg’ ‘.jpeg’, ‘.png’), ‘thumbsizes’ => array( ‘med’ => array(‘width’=>300, ‘height’=>300), ‘peq’ => array(‘width’=>100, ‘height’=>100) ) ) ) );

    class Sound extends AppModel { var $name = ‘Sound’; var $actsAs = array( ‘MeioUpload’ => array( ’sound’ => array( ‘dir’ => ‘files{DS}terms{DS}sounds’, ‘create_directory’ => true, ‘allowed_mime’ => array(‘audio/mpeg’), ‘allowed_ext’ => array(‘.midi’, ‘.mp3′, ‘.wma’), ) ) ); }

    class Term extends AppModel { var $actsAs = array(‘Containable’);

    var $name = 'Term';

    var $hasAndBelongsToMany = array( ... ... );

    var $hasMany = array( 'Sound', 'Image' );

    }

    In the controller i have a function like this:

    function admin_add() { if (!empty($this->data)) { if ($this->Term->save($this->data)) { if (isset($this->data['Image'])){ $this->data['Image']['term_id']=$this->Term->id; $this->Term->Image->save($this->data); } if (isset($this->data['Sound'])){ $this->data['Sound']['term_id']=$this->Term->id; $this->Term->Sound->save($this->data); } $this->flash(__(‘The term has been saved.’,true), ‘index’); } } }

    And in the view i have:

    echo $form->create(‘Term’,array(‘type’=>’file’)); echo $form->input(‘Term.name’); echo $form->input(‘Term.locale’); echo $form->input(‘Term.definition’, array(‘rows’ => ‘3′); echo $form->input(‘Sound.sound’,array(‘type’ => ‘file’); echo $form->input(‘Image.filename’,array(‘type’ => ‘file’); echo $form->end(__(‘Save’,true));

    When i try to save the form i have this error:

    Notice (8): Array to string conversion [CORE/cake/libs/model/datasources/dbo_source.php, line 582]

    Code | Context

    $model = Sound Sound::$name = “Sound” Sound::$actsAs = array Sound::$useDbConfig = “default” Sound::$useTable = “sounds” Sound::$displayField = “id” Sound::$id = false Sound::$data = array Sound::$table = “sounds” Sound::$primaryKey = “id” Sound::$schema = array Sound::$validate = array Sound::$validationErrors = array Sound::$tablePrefix = “” Sound::$alias = “Sound” Sound::$tableToModel = array Sound::$logTransactions = false Sound::$transactional = false Sound::$cacheQueries = false Sound::$belongsTo = array Sound::$hasOne = array Sound::$hasMany = array Sound::$hasAndBelongsToMany = array Sound::$Behaviors = BehaviorCollection object Sound::$whitelist = array Sound::$cacheSources = true Sound::$findQueryType = NULL Sound::$recursive = 1 Sound::$order = NULL Sound::$_exists = NULL Sound::$__associationKeys = array Sound::$__associations = array Sound::$__backAssociation = array Sound::$__insertID = NULL Sound::$__numRows = NULL Sound::$__affectedRows = NULL Sound::$_findMethods = array Sound::$_log = NULL $fields = array( “sound”, “term_id”, “modified”, “created” ) $values = array( array( “name” => “FX-009.mp3″, “type” => “audio/mpeg”, “tmp_name” => “/tmp/phpTd6h5f”, “error” => 0, “size” => 19644 ), “86″, “2009-05-17 16:30:31″, “2009-05-17 16:30:31″ ) $id = null $count = 4 $i = 4 $valueInsert = array( array( “‘FX-009.mp3′”, “‘audio/mpeg’”, “‘/tmp/phpTd6h5f’”, “‘0′”, “‘19644′” ), “86″, “‘2009-05-17 16:30:31′”, “‘2009-05-17 16:30:31′” ) $fieldInsert = array( “sound“, “term_id“, “modified“, “created” )

        }

    echo $_this-&gt;_output($level, $error, $code, $helpCode, $description, $file, $line, $context);
    

    Debugger::handleError() – CORE/cake/libs/debugger.php, line 221 join – [internal], line ?? DboSource::create() – CORE/cake/libs/model/datasources/dbo_source.php, line 582 Model::save() – CORE/cake/libs/model/model.php, line 1223 TermsController::admin_add() – APP/controllers/terms_controller.php, line 65 Object::dispatchMethod() – CORE/cake/libs/object.php, line 115 Dispatcher::_invoke() – CORE/cake/dispatcher.php, line 227 Dispatcher::dispatch() – CORE/cake/dispatcher.php, line 194 [main] – APP/webroot/index.php, line 88

    Warning (512): SQL Error: 1054: Unknown column ‘Array’ in ‘field list’ [CORE/cake/libs/model/datasources/dbo_source.php, line 525]

    Code | Context

    $sql = “INSERT INTO sounds (sound, term_id, modified, created) VALUES (Array, 86, ‘2009-05-17 16:30:31′, ‘2009-05-17 16:30:31′)” $error = “1054: Unknown column ‘Array’ in ‘field list’” $out = null

        }

    echo $_this-&gt;_output($level, $error, $code, $helpCode, $description, $file, $line, $context);
    

    Debugger::handleError() – CORE/cake/libs/debugger.php, line 221 DboSource::showQuery() – CORE/cake/libs/model/datasources/dbo_source.php, line 525 DboSource::execute() – CORE/cake/libs/model/datasources/dbo_source.php, line 201 DboSource::create() – CORE/cake/libs/model/datasources/dbo_source.php, line 585 Model::save() – CORE/cake/libs/model/model.php, line 1223 TermsController::admin_add() – APP/controllers/terms_controller.php, line 65 Object::dispatchMethod() – CORE/cake/libs/object.php, line 115 Dispatcher::_invoke() – CORE/cake/dispatcher.php, line 227 Dispatcher::dispatch() – CORE/cake/dispatcher.php, line 194 [main] – APP/webroot/index.php, line 88

    Query: INSERT INTO sounds (sound, term_id, modified, created) VALUES (Array, 86, ‘2009-05-17 16:30:31′, ‘2009-05-17 16:30:31′)

    I’ve noticed that if I put a debug() in the beforesave of meiouploadBehavior, this always has the configuration data for the latest model added to hasmany Terms associations (in this case sound).

    Any idea to fix this? Thanks

  87. 87
    MEPTBEЦ Says:

    Конечно, как все говорят, занимательное рядом! :)

  88. 88
    Snowrider Says:

    @esezako I’m having the exact same issue and I think I’ve discovered that the problem is actually with the current release of cake. I recently upgraded to 1.2.3.8166 and then noticed that all of the my file uploads stopped working. I switched the cake folder back to the old version and everything worked fine again.

    This behavior is awesome and super useful for my project, any chance of looking into this bug? Thanks!

  89. 89
    Moon Says:

    Hi, I have a problem using this behaviour. when I try to upload my image, I have an error message:

    Notice (8): Undefined index: Director meio_upload.php, line 551

    It seems to be a problem when trying to fix the name of the file. However the file is correctly uploaded !!!

    My model’s name is: Director My filed’s name is: background_img

    My code for my model:

    var $actsAs = array( ‘MeioUpload’ => array( ‘background_img’ => array( ‘dir’ => ‘img{DS}{model}’, ‘create_directory’ => true, ‘allowed_mime’ => array(‘image/jpeg’, ‘image/pjpeg’, ‘image/png’), ‘allowed_ext’ => array(‘.jpg’, ‘.jpeg’, ‘.png’), ‘thumbsizes’ => array( ‘normal’ => array(‘width’=>200, ‘height’=>200) ) ) ) );

    My code in the vue: create(‘Director’, array(‘type’=>’file’));?> echo $form->input(‘background_img’, array(‘type’=>’file’));

    Please Help ! thinks

  90. 90
    Moon Says:

    Hi, The problem was caused because of my PHP version. It was PHP 4 on my server. Meio_upload seems to work only with PHP 5. It could be great if we can have a PHP 4 version. I’ll try to adapt this behaviour for PHP 4 when I’ll have time.

    Regards.

  91. 91
    Jose Diaz-Gonzalez Says:

    I’ve updated the Behavior a bit (unfortunately I am having issues with the validations not being done in the right order… but that’s not related to the behavior :P ) so here it is:

    http://bin.cakephp.org/saved/46228

  92. 92
    Snowrider Says:

    I just did a quick initial test with your new version and it seems to be working with the latest Cake release. Thanks!!

  93. 93
    BeжливыйCнaйпep Says:

    Хороший блог :) Люблю почитывать каждый день (ну и в другое время тоже :) ).

  94. 94
    кpoшкapoкcиc Says:

    Почитал, улыбнуло :) А может и правда всегда думать только о хорошем, а все плохое отбрасывать?

  95. 95
    БaйaчaБeбe Says:

    Я подписался на RSS ленту, но сообщения почему-то в виде каких-то значков непонятных :( Как это исправить?

  96. 96
    Tom Says:

    doesn’t seem to work with latest release of cake (not sure about other releases)… it tries to save an array to the database.. bringing up an array to string conversion error.

  97. 97
    Flipflops.org » Blog Archive » Two CakePHP behaviours to extend MeioUpload Says:

    [...] been using the the Meio Upload Behaviour for a while as its a very handy piece of code, but as is so often the case it doesn’t do [...]

  98. 98
    John-Henrique Says:

    Estava testando e notei que quando o MeioUpload reconhece que já existe um arquivo com o mesmo nome do que está sendo enviado agora ele renomeia para algo como “arquivo1.jpg”.

    Apesar desta funcionalidade ser bastante útil não consigo de forma alguma recuperar o nome do arquivo. O MeioUpload grava na tabela o nome final do arquivo mas não sei como retornar este nome para gravar em uma sessão.

    Poderia me dizer como retornar o nome final do arquivo?

    Falopa!

  99. 99
    bendo01 Says:

    hei meio :) i tried your meioupload behavior and try it with cake 1.2.3.8166, but every time i upload an image flash error message “Extensão de arquivo inválida.” i tried with .jpeg and .png it’s still show that message, i’m a newbie in cake :D

  100. 100
    Vinícius Mendes Says:

    Bendo, this message is saying that the file extension is invalid. You can set the valid extensions in the ‘allowed_ext’ setting of the behavior. It is explained at Options item 3 in the documentation above.

  101. 101
    bendo01 Says:

    hai Vinícius Mendes thanx for your quick reply :) , but still i use the the same extension as the rules say, if you want take look my code, i make a news form which can upload an image , this is my …/view/news/add.ctp code :

    create(‘News’);?>

    input('title');
        echo $form-&gt;input('content');
        //echo $form-&gt;input('image_url');
        echo $form-&gt;label('File/image', 'Image');
        echo $form-&gt;file('News.picture');
        echo $form-&gt;input('dir');
        echo $form-&gt;input('mimetype');
        echo $form-&gt;input('filesize');
        echo $form-&gt;input('User');
    ?&gt;
    

    end(‘Submit’);?>

    <ul>
        <li>link(__('List News', true), array('action'=&gt;'index'));?&gt;</li>
        <li>link(__('List Users', true), array('controller'=&gt; 'users', 'action'=&gt;'index')); ?&gt; </li>
        <li>link(__('New User', true), array('controller'=&gt; 'users', 'action'=&gt;'add')); ?&gt; </li>
    </ul>
    

    and this is my is my model (…/model/news.php)

    array(‘notempty’), ‘content’ => array(‘notempty’), ‘image_url’ => array(‘notempty’) );

    //The Associations below have been created with all possible keys, those that are not needed can be removed
    var $hasAndBelongsToMany = array(
        'User' =&gt; array(
            'className' =&gt; 'User',
            'joinTable' =&gt; 'news_users',
            'foreignKey' =&gt; 'news_id',
            'associationForeignKey' =&gt; 'user_id',
            'unique' =&gt; true,
            'conditions' =&gt; '',
            'fields' =&gt; '',
            'order' =&gt; '',
            'limit' =&gt; '',
            'offset' =&gt; '',
            'finderQuery' =&gt; '',
            'deleteQuery' =&gt; '',
            'insertQuery' =&gt; ''
        )
    );
    
    var $actsAs = array(
    'MeioUpload' =&gt; array(
        'picture' =&gt; array(
            'dir' =&gt; 'img{DS}{model}{DS}{field}',
            'create_directory' =&gt; true,
            'allowed_mime' =&gt; array('image/jpeg', 'image/pjpeg', 'image/png'),
            'allowed_ext' =&gt; array('.jpg', '.jpeg', '.png'),
            'thumbsizes' =&gt; array(
                'normal' =&gt; array('width'=&gt;200, 'height'=&gt;200),
            ),
            'default' =&gt; 'default.jpg',
        )
    )
    

    ); } ?>

  102. 102
    John Says:

    Hi Vincent

    Thanks for writing this great behaviour, which I’ve been using for ages and in a lot of projects. Recently I’ve just written 2 more behaviours that extend your upload behaviour.

    One the behaviours of them lets you easily use a single model to store all your uploads that can be referenced from any other model. e.g. Post hasMany Upload, Product hasMany Upload

    The other behaviour is designed to let you do multiple uploads at the same time.

    I hope they come in useful to other people, any feedback appreciated.

    I’ve written a post about it here http://www.flipflops.org/2009/06/29/two-cakephp-behaviours-to-extend-meioupload/ and you can download an example app with them both plugged in too.

    Cheers

    John

  103. 103
    Vinícius Mendes Says:

    Bendo, what kind of image are you uploading? What is the full filename (with extension)?

  104. 104
    Steltek Says:

    Is it me or does this have a problem with file extensions that are in upper case? (like .JPG instead of .jpg)

  105. 105
    Vinícius Mendes Says:

    @Steltek I fixed this bug in my fork of the meioupload: http://github.com/vbmendes/MeioUpload/tree/master

  106. 106
    Steltek Says:

    Thanks. I’m in fact using an older version of your fork (no clue where I picked it up) and patched it accordingly. Trying a drop-in replacement of it now, but I did get a parse error on line 909 as there’s a comma missing after “‘maxDimension’ => ”)”.

  107. 107
    vedhmtgg Says:

    VJ2Y0M oswspmcprqwt, [url=http://lkkvlhdgukbq.com/]lkkvlhdgukbq[/url], [link=http://aizmprajfokq.com/]aizmprajfokq[/link], http://xxwowoogwtao.com/

  108. 108
    Jose Diaz-Gonzalez Says:

    @Steltek Vinicius Mendes, jrbasso and I are coordinating (some-what) in bringing some bug fixes and features. I’ve fixed that in my repo and pushed. Some things I’d like to see are better internationalization and translations, moving it into a plugin, advanced configuration of phpThumb, and other types of uploads/transloads.

    FYI, these are the repos that are being worked on:

    http://github.com/jrbasso/MeioUpload/tree/master http://github.com/josegonzalez/MeioUpload/tree/master

  109. 109
    Moon Says:

    Hi, I am leaving a comment to fix a bug on the meio_upload behaviour wehen working under PHP4.

    I had an error in the _fixname function in the behaviour meio_upload.php. The error shown was: undefined index Info, (my model was Info). However it works fine under PHP 5. The problem comes from the setup function of the behaviour in the following line code:

    function setup(&$model, $settings = array()) { /* PHP 5 OK BUT PROBLEM IN fixname WITH PHP 4*/ $this->_model = $model;

    … }

    The solution:

    function setup(&$model, $settings = array()) { // PHP 4 We have to add the “&” $this->__model = &$model;

    … } With out adding the “&”, with PHP 4, a new copy of the model object was created and the data array of the model was empty, that’s why we have the index undefined. We have to use the original model object itself, not a copy.

    Now it works under PHP 4 and 5.

    Regards.

    Moon.

  110. 110
    faemino Says:

    Hi to all,

    I’ve a problem when I try to upload a none image file (pdf, zip, etc).

    Since behavior version 1.7.1 always I try to upload a none image file get a “Invalid file type.” error. Older versions like 1.6.1 works fine but 1.7.1 and 2.0 don’t work. (CakePHP version 1.2.5 and 1.2.4.8284, PHP version 5.2.6)

    I’ve the next behaviour configuration: ‘allowed_mime’ => array( ‘image/gif’, ‘image/jpeg’, ‘image/pjpeg’, ‘image/png’, ‘application/pdf’), ‘allowed_ext’ => array(‘.jpg’, ‘.jpeg’, ‘.png’, ‘.gif’, ‘.pdf’),

    Somebody have the same problem?

    I’m still debuging and some idea will be wellcome.

    Thanks for advance.

  111. 111
    faemino Says:

    Hi to all,

    Ups, sorry to all. About my last comment (110) the problem was the name of the configuration array key name: allowed_mime => allowedMime, allowed_ext => allowedExt.

    Hope that helps somebody.

    Regards

  112. 112
    Skeptic Says:

    Yeah, I’d say overall nice secure work, however, if every table that had a user uploaded image had a table structure like this one, you’d have yourself some very unnormalized data. Files should be stored in a centralized table. Thanks for your work.

  113. 113
    ilcaduceo Says:

    @Sparkybarkalot @sutehi @Sytze Loor and anyone else who gets an array field problem. The name of file that contain behaviour must be meio_upload.php instead MeioUpload.php… I fix this and it was fine! Bye!

  114. 114
    bendo01 Says:

    dear Vinícius Mendes, thank you for this upload behavior, for the past mistakes i’ve done is forgot to add this line echo $form->create(‘Product’,array(‘type’ => ‘file’));

    thanx you so much for this amazing behavior :) you are the best :)

  115. 115
    bendo01 Says:

    ohh yeah i forgot to ask, is there an example for multiple upload ? please i need a guide/ example :)

  116. 116
    Vinicius Mendes Says:

    Dear bendo01. Good that you liked the behavior.

    Since I stopped working with CakePHP, I don’t work with MeioUpload anymore. But some people created a project hosted at github to keep mantaining it. The link to the project is in the start of this post.

  117. 117
    Sebas Says:

    Hello!! thank you very much!!

    I only see a detail about the extension(like JPG), y left a patch.

    Index: app/models/behaviors/meio_upload.php

    — app/models/behaviors/meio_upload.php (revisão X) +++ app/models/behaviors/meio_upload.php (cópia de trabalho) @@ -720,12 +720,12 @@ App::import(‘Component’, ‘Thumb’); $system = explode(“.”, $name);

    • if (preg_match(“/jpg|jpeg/”, $system[1]))
    • if (preg_match("/jpg|jpeg/i", $system[1]))
      {
          $src_img = imagecreatefromjpeg($name);
      }
      
    • if (preg_match("/png/", $system[1]))
      
    • if (preg_match(“/png/i”, $system[1])) { $src_img = imagecreatefrompng($name); }
  118. 118
    Sebas Says:

    Index: app/models/behaviors/meio_upload.php

    --- app/models/behaviors/meio_upload.php (revisão X) +++ app/models/behaviors/meio_upload.php (cópia de trabalho) @@ -720,12 +720,12 @@ App::import('Component', 'Thumb'); $system = explode(".", $name);

    • if (preg_match("/jpg|jpeg/", $system[1]))
    • if (preg_match("/jpg|jpeg/i", $system[1]))
      {
          $src_img = imagecreatefromjpeg($name);
      }
      
    • if (preg_match("/png/", $system[1]))
      
    • if (preg_match("/png/i", $system[1])) { $src_img = imagecreatefrompng($name); }
  119. 119
    CakePHP Tutorial: Videos zu einem Model hinzufügen at Manuel Boy Coder Blog Says:

    [...] den Upload der Video-Datei verwenden wir das absolut geniale Meio-Upload-Behavior. Die Dokumentation auf der Projekt-Seite ist schon sehr aussagekräftig, zur Sicherheit werde ich [...]

  120. 120
    Marcelo Says:

    Olá, gostaria de parabenizalo pelo plugin, ficou muito bom realmente.

    Mas encontrei um problema e não consegui resolver, qdo configuro o thumb ele retorna esse erro:

    Notice (8): Uninitialized string offset: 0 [APP/vendors/phpThumb/phpthumb.class.php, line 527] Notice (8): Uninitialized string offset: 1 [APP/vendors/phpThumb/phpthumb.class.php, line 527]

    A configuração:

    ‘thumbsizes’ => array( ‘normal’ => array(‘width’=>343, ‘height’=>343), ’small’ => array(‘width’=>37, ‘height’=>37), ‘medium’ => array(‘width’=>74, ‘height’=>74), ‘large’ => array(‘width’=>110, ‘height’=>110), )

    Obrigado.

  121. 121
    saints Says:

    Why this SQL error? INSERT INTO images (filename, modified, created) VALUES (Array, ‘2010-01-25 21:52:29′, ‘2010-01-25 21:52:29′)

    ImagesController: var $actsAs = array (‘MeioUpload’ => array( ‘filename’ => array( ‘dir’ => ‘files/images’, )) ); function add() { $this->Image->save($this->data); }

    add.ctp: create(‘Image’,array(‘type’ => ‘file’)); echo $form->file(‘filename’, array(‘type’ => ‘file’)); echo $form->end();?>

    Thank you!

  122. 122
    cédric Says:

    I have the same SQL error

    add.ctp echo $form->create(‘Image’,array(‘type’ => ‘file’)); echo $form->input(‘picture’, array(‘type’ => ‘file’)); echo $form->end(‘Sauver les informations’);

    ImagesController if (!empty($this->data)) { if ($this->Image->save($this->data)) { $this->flash(‘Your image has been saved.’,'/images’);}}}

    Any idea? I’m stuck.. thanks

  123. 123
    cédric Says:

    Ok, I’m a newbie in cake. Correct me if I’m wrong, cake’s conventions are the followings:

    class MeioUpload => file meio_upload.php

    In the downloaded archive, there is an upload.php file, that needs to be renamed meio_upload.php to work correctly.

  124. 124
    cédric Says:

    Sorry, downloaded archive is ok, the thing that put me in a wrong way is here:

    http://cakeforge.org/snippet/detail.php?type=snippet&id=226

    In the last downloadable version, we can see:

    *Usage: *1 Download this behaviour and place it in your models/behaviours/upload.php

  125. 125
    Bernd Says:

    Hey folks, thanks a lot for the work you’ve done so far.

    I have a little problem with the use of multiple files. Uploading is no problem, but if I want to delete one of the uploaded files, this is not really possible.

    So lets say I’m using the following form to upload my files:

    echo $form->input(‘Mediafile.0.filename’, array(‘type’ => ‘file’));

    Why is it not possible to delete the file in the following way?

    echo $form->input(‘Mediafile.0.filename.remove’, array(‘type’ => ‘checkbox’));

    Thanks for your help.

  126. 126
    jmerrow Says:

    Response to comment 125 from Bernd-

    I have the same issue. I notice that if the upload field for the picture you want to delete is populated (i.e. if you’ve chosen another file to upload) it does delete the picture- almost. the value in the db is set to “0.”. If I get this sorted I’ll post here.

    Anyone else solved this?

  127. 127
    John Says:

    greetings,

    thanks for the excellent behavior.

    we can change the uploads folder to which it is situated outside the webroot?

    good day.

    PS: Sorry about my English. :)

  128. 128
    Gennadiy Says:

    Trying to get it to work but I am getting this error: Fatal error: Call to undefined function imagecreatefromjpeg() in C:\Apache2.2\htdocs\app\models\behaviors\meio_upload.php on line 725

    I did download and installed phpThumb , dont know if it is related…

    Any suggestions?

    Thanks

  129. 129
    Pablo Says:

    Hello.

    I want to upload files in different directories depending on the type. For example, images in img, pdf and doc files in docs, etc.

    Is it possible to change the directory as the file is loaded? Or is it possible to define the directory from an input?

    Thank you very much

  130. 130
    Lyubomir Petrov Says:

    Weird.. if i use default=>”filename.jpg”, i got error, that the default option must contain filename + ext. At the source code (meio_upload.php) at line 226, i see: if (strpos($options['default'], ‘.’) !== false) { trigger_error(__d(‘meio_upload’, ‘MeioUploadBehavior Error: The default option must be the filename with extension.’, true), E_USER_ERROR); }

    Is this a typo ? I guess it must be: if (strpos($options['default'], ‘.’) === false) {

  131. 131
    Benny L.E.P Says:

    is this behavior compatible with cake 1.3

  132. 132
    Benny L.E.P Says:

    i’m using meio upload 1.7.1 by josegonzalez ( http://github.com/josegonzalez/MeioUpload/tree/master ) and it’s perfectly with cake 1.3 stable version all you have to do are change “$folder->mkdir” to “$folder ->create” installing phpThumb is a must …. :) happy baking :)

  133. 133
    Fabian Says:

    The MeioUpload works perfectlly!! but i want to know how can I show the current image in my View. I try with this code but doesn’t happend:

    data['Perfil']['picture'])): ?> Imagen actual: <img src="data['Perfil']['dir'] . $this->data['Perfil']['picture']; ?>” alt=”Imagen actual” width=”100″ />

  134. 134
    Sefac Says:

    Is there some way to create squared thumbnails?

    BTW, great behaviour! thanks for all your work.

  135. 135
    Sefac Says:

    OK, nevermind… for those who need it

    in the model set the thumbnail size and zoomcrop true like this:

    ’small’ => array(‘width’=>80, ‘height’=>80, ‘zoomCrop’=>true),

  136. 136
    Connie Says:

    I keep getting an SQL error 1054: Unknown column ‘Array’ in ‘field list’ when I simply duplicated the code for another model, and changed the field name from image to something else, but it doesn’t work. Does the field name always have to be ‘image’?? I can’t use it for multiple models?

  137. 137
    OldWest Says:

    Hello,

    No matter what I do, I continue to get the “Extension not valid” error ( I changed it to English )..

    I’ve checked all of my extensions. Tried various types of files. But continue to get this same exact error.

    I read through the above posts and it appears some other users where having similar trouble.

    Any ideas? SOS.

  138. 138
    Ryan Says:

    OldWest, if you are using a flash or java uploader, chances are it is sending files as application/octet-stream as opposed to it’s actual file type. Adding application/octet-stream to your allowed mime types will fix the issue. If you’re generating thumbnails, you’ll need to add it to the behavior’s $_imageTypes array as well. Hope this helps.

Leave a Reply