Array to string Error while uploading an Image - cakephp

i was trying to upload image using cakephp , i got the following error :
Notice (8): Array to string conversion [CORE\Cake\Model\Datasource\DboSource.php, line 1009]
<?php echo $this->Form->create('User',array('type'=>'file'));
echo $this->Form->input('profile_pic', array('type'=>'file'));
echo $this->Form->end('submit');
?>
anything wrong with what i've did ?

You study cakephp manual properly HOW form type can be File ?????? :)
Use this
<?php echo $this->Form->create('User',array('enctype'=>'multipart/form-data'));
echo $this->Form->input('profile_pic', array('type'=>'file'));
echo $this->Form->end('submit');
?>

You need to treat the file upload in the controller. If you debug the request you'll see that profile_pic field is an array:
# in controller:
if ($this->request->is('post')) {
debug($this->request->data); die();
}
# result:
array(
'User' => array(
'profile_pic' => array(
'name' => 'wappy500x500.jpg',
'type' => 'image/jpeg',
'tmp_name' => '/tmp/phptk28hE',
'error' => (int) 0,
'size' => (int) 238264
)
)
)
Short answer:
public function upload() {
if ($this->request->is('post')) {
if(isset($this->request->data['User']['profile_pic']['error']) && $this->request->data['User']['profile_pic']['error'] === 0) {
$source = $this->request->data['User']['profile_pic']['tmp_name']; // Source
$dest = ROOT . DS . 'app' . DS . 'webroot' . DS . 'uploads' . DS; // Destination
move_uploaded_file($source, $dest.'your-file-name.jpg'); // Move from source to destination (you need write permissions in that dir)
$this->request->data['User']['profile_pic'] = 'your-file-name.jpg'; // Replace the array with a string in order to save it in the DB
$this->User->create(); // We have a new entry
$this->User->save($this->request->data); // Save the request
$this->Session->setFlash(__('The user has been saved.')); // Send a success flash message
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
}
}
Of course you need to make extra validations on the uploaded file.
Further reading: https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=site:stackoverflow.com+cakephp+upload+file

Related

Cakephp 3.3 - Not able to save images using plugin josegonzalez

I am not able to save the photo name and photo dir in the users table based on logged in used id.I am trying to upload the user photo for the existing user based on his used id.The photo fields are not getting updated for the existing user. I am trying to upload the photo using this plugin josegonzalez. Please help me.
<?php echo $this->Form->create($user, ['type' => 'file']); ?>
<?php echo $this->Form->input('photo',['type' => 'file', 'class' => 'form-control']); ?>
<?php echo $this->Form->input('photo_dir', ['type' => 'hidden']); ?>
<?php echo $this->Form->button(__('Submit'), ['type'=>'submit','class' => 'btn btn-success']); ?>
<?php echo $this->Form->end(); ?>
UsersTable
$this->addBehavior('Josegonzalez/Upload.Upload', [
'photo' => [
'fields' => [
// if these fields or their defaults exist
// the values will be set.
'dir' => 'photo_dir', // defaults to `dir`
],
],
]);
UsersController/add
public function add($id=null)
{
if ($this->request->is('post')) {
if (!$id) {
$id = $this->Auth->user('id');
}
$user = $this->Users->get($id);
$fileName = $this->request->data['photo']['name'];
$user->photo = $fileName;
//$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->success(__('Your photo has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to add your photo.'));
}
$this->set('user', $user);
}
Have you tried using 'enctype' in your form tag?
<form enctype="multipart/form-data">
It is explained here.
You can use Proffer plugin. It is easy to use and can be used to generate thumbnails too. I'm using it since 3.1 and working fine. It's even working on 3.3
https://github.com/davidyell/CakePHP3-Proffer
This is how it worked. I did not use any plugin. I uploaded single image at a time.
UsersController/add function.
public function add()
{
//check for logged in user authentication
$id = $this->Auth->user('id');
$user = '';
//check if the request is post
if ($this->request->is('post')) {
$user = $this->Users->get($id);
//check if upload file is not empty
if(!empty($this->request->data['photo']['name'])){
$fileName = $this->request->data['photo']['name'];
$extention = pathinfo($fileName,PATHINFO_EXTENSION);
$arr_ext = array('jpg', 'jpeg', 'gif','png');
//check for uploded file extension
if(in_array($extention, $arr_ext)){
$newfileName=$id.'.'.$extention;
$destDir = WWW_ROOT .'img'. DS .'users'. DS . $newfileName;
//move uploded file to destination
if(move_uploaded_file($this->request->data['photo']['tmp_name'],$destDir)){
$user->photo = $newfileName;
//save the uploded image in user table
if ($this->Users->save($user)) {
$this->Flash->success(__('Your profile photo has been uploaded successfully.'));
return $this->redirect([
'controller' => 'Users',
'action' => 'view', $id
]);
} else{
$this->Flash->error(__('Unable to upload image, please try again.'));
}
}else{
$this->Flash->error(__('Unable to upload image, please try again.'));
}
}else{
$this->Flash->error(__('Please choose a image to upload.'));
}
}
}
$this->set(compact('user'));
$this->set('_serialize', ['user']);
$this->set('id', $id);
}

import data from csv to mysql using cakephp 2.7.5

I have csv file. and i have already uploaded now i want put its data into my database in cakephp 2.7.5
csv file contain field name exactly same as employee table field name
my question is how to put data in employee table
here function code
public function import_csv(){
$this->loadModel('Csvimport');
if ($this->request->is('post', 'put')) {
$this->request->data['Csvimport']['created_user_id'] = $this->Auth->user('id');
$this->request->data['Csvimport']['modified_user_id'] = $this->Auth->user('id');
if (!empty($this->request->data)) {
$file = $this->request->data['Csvimport']['file_name'];
$name = explode(".", $file['name']);
//echo "before:".$file['name'][$i];
$name = uniqid().".".$name[1];
//echo "after:".$name;
$ext = substr(strtolower(strrchr($name, '.')), 1); //get the extension
$arr_ext = array('csv'); //set allowed extensions
//only process if the extension is valid
if ($file['size'] < 1000000) {
if(in_array($ext, $arr_ext)){
//do the actual uploading of the file. First arg is the tmp name, second arg is
//where we are putting it
move_uploaded_file($file['tmp_name'], WWW_ROOT . '/attachments/csvimports/' . $name);
//prepare the filename for database entry
$this->request->data['Csvimport']['file_name'] = $name;
$this->request->data['Csvimport']['file_type'] = $file['type'];
$this->request->data['Csvimport']['file_size'] = $file['size'];
}else{
$message = 'Your File should be in given formats only.';
$this->set('message',$message);
$this->Session->setFlash($message, 'error_flesh', array(), 'error');
$this->redirect(array('controller' => 'csvimports' , 'action' => 'import_csv'));
}
}else{
$message = 'Your File should be Upto 1MB only.';
$this->set('message',$message);
$this->Session->setFlash($message, 'error_flesh', array(), 'error');
$this->redirect(array('controller' => 'csvimports' , 'action' => 'import_csv'));
}
}
$this->Csvimport->id = $id;
if ($this->Csvimport->save($this->request->data)){
$message = 'The Csv File has been Uploaded';
$this->set('message',$message);
$this->Session->setFlash($message, 'success_flesh', array(), 'successfully');
$this->redirect(array('controller' => 'csvimports' , 'action' => 'import_csv'));
} else {
$message = 'The Csv File could not be Uploaded. Please, try again.';
$this->set('message',$message);
$this->Session->setFlash($message, 'error_flesh', array(), 'error');
}
}
}
If you need to loop over every row of data before importing it,
consider using
$this->Csvimport->create()
$this->Csvimport->save(['fieldName'=>$data1, 'fieldName'=>$data2, ... ]);
If you don't need that, then use saveAll on the whole array once you have it as such.
here is cakes documentation:
http://book.cakephp.org/2.0/en/models/saving-your-data.html

Cakephp Upload Image - Can not determine the mimetype

The following validation is being done in my model
'image' => array(
'uploadErrror' => array(
'rule' => 'uploadError',
'message' => 'The image upload failed.',
'allowEmpty'=> True
),
'mimeType' => array(
'rule' => array('mimeType',array('image/gif','image/png','image/jpeg')),
'message' => 'Please only upload images (gif, png, jpg).',
'allowEmpty' => true
),
'fileSize'=> array(
'rule' => array('fileSize', '<=', '1MB'),
'message' => 'Image must be less than 1MB.',
'allowEmpty' => true
),
'processImageUpload' => array(
'rule' => 'processImageUpload',
'message' => 'Unable to process image upload.',
'allowEmpty'=> true
) )
public function processImageUpload($check = array()){
if(!is_uploaded_file($check['image']['tmp_name']))
{
return FALSE;
}
$targetdir = WWW_ROOT . 'img' . DS . 'uploads' . DS . $check['image']['name'];
if(!move_uploaded_file($check['image']['tmp_name'],$targetdir))
{
return false;
}
$this->data[$this->alias]['image'] = 'uploads' . DS . $check['image']['name'];
return true;
}
The error I am receiving is the below, I also enabled debug 2 but no further clarification was provided.
Can not determine the mimetype.
I have already tried un-commenting
extension=php_fileinfo.dll
and restarted WAMPServer fully but it still did not work.
Also in the controller class I have the following code for add
public function add() {
if ($this->request->is('post')) {
$this->Image->create();
$data = $this->request->data['Image'];
if (!$data['image']['name'])
{
$this->Session->setFlash(__('There was no image provided.'));
}
if ($this->Image->save($data)) {
$this->Session->setFlash(__('The image has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The image could not be saved. Please, try again.'));
}
}
}
Add View Code
<?php echo $this->Form->create('Image',array('type'=>'file')); ?>
<fieldset>
<legend><?php echo __('Add Image'); ?></legend>
<?php
echo $this->Form->input('description');
echo $this->Form->input('image',array('type'=>'file'));
echo $this->Form->input('property_id');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
Any suggestions would be greatly appreciated.
Not sure if this is the whole problem, but:
'mimeType' => array(
'rule' => array('mimeType',array('image/gif','image/png','image/jpeg')),
'message' => 'Please only upload images (gif, png, jpg).',
'alllowEmpty' => true
),
'alllowEmpty' has 3 L's.
The closes solution which isn't checking mime but just extension is
$ext = substr(strtolower(strrchr($check['image']['name'], '.')), 1); //get the extension
$arr_ext = array('jpg', 'jpeg', 'gif'); //set allowed extensions
if (in_array($ext, $arr_ext)) {
//upload code
}
else
{
return 'Please only upload images (gif, png, jpg).';
}
Change the text ;extension=php_fileinfo.dll into extension=php_fileinfo.dll on php.ini
It works for me. Hope it help you guys. I'm using xampp.
In general, Cake expects to find the file to check at location specified in original
$this->data[$this->alias]['image']['tmp_name'] // or whatever is the name of the field
during validation. So make sure the ...['tmp_name'] points to valid location with (still) existing uploaded file.
ORIGINAL ANSWER:
I think the problem is here (I had also similar problem):
$this->data[$this->alias]['image'] = 'uploads' . DS . $check['image']['name'];
After you move the uploaded file, you assign path infromation to $this->data[$this->alias]['image'] but CakePHP thinks that there is an array with all information about uploaded file. That is why the whole validation will fail.
To be specific, CakePHP will try to look for tmp_name in $this->data[$this->alias]['image'] but it won't find it there, after that it will try to determine mime type of "nothing" and it will fail.

Not able upload filename into db, in uploading concepts

In my UsersController.php
public function uploadFile()
{
$filename = '';
if ($this->request->is('post')) {
$uploadData = $this->data['uploadFile']['image'];
if ( $uploadData['size'] == 0 || $uploadData['error'] !== 0) {
return false;
}
$filename = basename($uploadData['name']);
if ($this->User->save($filename)) {
$this->Session->setFlash(__('Your imagename has been saved.'));
}
$uploadFolder = WWW_ROOT. 'files';
$filename = time() .'_'. $filename;
$uploadPath = $uploadFolder . DS . $filename;
if( !file_exists($uploadFolder) ){
mkdir($uploadFolder);
}
if (!move_uploaded_file($uploadData['tmp_name'], $uploadPath)) {
//$this->set('pdf_path', $fileName);
return false;
}
}
}
}
And in my uploadfile.ctp
<?php
echo $this->Form->create('uploadFile', array( 'type' => 'file'));
echo $this->Form->input('image', array('type' => 'file','label' => 'Pdf'));
echo $this->Form->end('Upload file');
?>
In my db I have table name "image" along with some other fields. Now I'm not able to upload file name into db.
If you have a table name called 'image', then it should be related to the user model. $this->User->save($filename) needs at least a table field called 'filename' in the User table AND it needs to be assigned to a user via $this->User->id = $user_id;
If your image table has an image model which is related to the user model, read the book's chapter 'Saving related model data' http://book.cakephp.org/2.0/en/models/saving-your-data.html#saving-related-model-data-hasone-hasmany-belongsto

Cakephp: combine input values to create hidden name input

I've searched high and low for a solution but can't seem to get this figured out. What I'm trying to do is upon adding a product, I want the name field to be populated from the inputs in the form. So the name would include the values the user selects for type_id,category_id and subcategory_id. Does anyone know of a way to accomplish this?
Add product View page
<fieldset>
<legend><?php echo __('Add Product'); ?></legend>
<?php
echo $this->Form->input('type_id');
echo $this->Form->input('category_id', array('label' => 'Vendor'));
echo $this->Form->input('subcategory_id', array('label' => 'Model'));
echo $this->Form->input('location', array('label' => 'Location'));
echo $this->Form->input('sku', array('label' => 'Asset Tag'));
echo $this->Form->input('mac');
echo $this->Form->input('description', array('label' => 'Notes'));
echo $this->Form->input('name', array( 'value' => ['type_id']['category_id'] , 'type' => 'hidden'));
//echo $this->Form->input('cost');
// echo $this->Form->input('Tag');
?>
</fieldset>
Product controller add function
public function add() {
if ($this->request->is('post')) {
$this->Product->create();
if ($this->Product->save($this->request->data)) {
$this->Session->setFlash(__('The product has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The product could not be saved. Please, try again.'));
}
}
$subcategories = $this->Product->Subcategory->find('list',array('order'=>'Subcategory.name asc'));
$categories = $this->Product->Category->find('list',array('order'=>'Category.name asc'));
$types = $this->Product->Type->find('list',array('order'=>'Type.name asc'));
$this->set(compact('subcategories', 'categories', 'types'));
}
In order to do it the way you are trying to do it, you would have to use client-side javascript to update the input value "on-the-fly", but that's not very safe and can easily be messed with. It would make much more sense to drop the name input altogether and just handle this in the beforeSave method of your Product model (or alternatively by defining the name value in your Controller just before saving).
public function beforeSave($options = array()) {
// Generate the name based on type and category
$this->data['Product']['name'] = $this->data['Product']['type_id'] .
$this->data['Product']['category_id'];
return true;
}
Update based on your comment.
In order to get the names, just find those names (assuming your models are associated) and define those:
public function beforeSave($options = array()) {
// Get the type name
$type = $this->Type->field('name', array(
// Set the condition for the field
'Type.id' => $this->data['Product']['type_id']
));
// Get the category name
$category = $this->Category->field('name', array(
// Set the condition for the field
'Category.id' => $this->data['Product']['category_id']
));
// Generate the name based on type and category
$this->data['Product']['name'] = $type . $category;
return true;
}

Resources