6Answers
  • 12
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

cakePHP 3.0 uploading images

I want to upload images in my cakephp 3.0 app. But I get the error message:

Notice (8): Undefined index: Images [APP/Controller/ImagesController.php, line 55]

Are there already some examples for uploading files (multiple files at once) in cakePHP 3.0? Because I can only find examples for cakePHP 2.x !

I think I need to add a custom validation method in my ImagesTable.php? But I can't get it to work.

ImagesTable

public function initialize(array $config) {
    $validator
       ->requirePresence('image_path', 'create')
       ->notEmpty('image_path')
       ->add('processImageUpload', 'custom', [
          'rule' => 'processImageUpload'
       ])
}

public function processImageUpload($check = array()) {
    if(!is_uploaded_file($check['image_path']['tmp_name'])){
       return FALSE;
    }
    if (!move_uploaded_file($check['image_path']['tmp_name'], WWW_ROOT . 'img' . DS . 'images' . DS . $check['image_path']['name'])){
        return FALSE;
    }
    $this->data[$this->alias]['image_path'] = 'images' . DS . $check['image_path']['name'];
    return TRUE;
}

ImagesController

public function add()
    {
        $image = $this->Images->newEntity();
        if ($this->request->is('post')) {
            $image = $this->Images->patchEntity($image, $this->request->data);

            $data = $this->request->data['Images'];
            //var_dump($this->request->data);
            if(!$data['image_path']['name']){
                unset($data['image_path']);
            }

            // var_dump($this->request->data);
            if ($this->Images->save($image)) {
                $this->Flash->success('The image has been saved.');
                return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error('The image could not be saved. Please, try again.');
            }
        }
        $images = $this->Images->Images->find('list', ['limit' => 200]);
        $projects = $this->Images->Projects->find('list', ['limit' => 200]);
        $this->set(compact('image', 'images', 'projects'));
        $this->set('_serialize', ['image']);
    }

Image add.ctp

<?php
   echo $this->Form->input('image_path', [
      'label' => 'Image',
      'type' => 'file'
      ]
   );
?>

Image Entity

protected $_accessible = [
    'image_path' => true,
];

In your view file, add like this, in my case Users/dashboard.ctp

<div class="ChImg">
<?php 
echo $this->Form->create($particularRecord, ['enctype' => 'multipart/form-data']);
echo $this->Form->input('upload', ['type' => 'file']);
echo $this->Form->button('Update Details', ['class' => 'btn btn-lg btn-success1 btn-block padding-t-b-15']);
echo $this->Form->end();       
?>
</div>

In your controller add like this, In my case UsersController

if (!empty($this->request->data)) {
if (!empty($this->request->data['upload']['name'])) {
$file = $this->request->data['upload']; //put the data into a var for easy use

$ext = substr(strtolower(strrchr($file['name'], '.')), 1); //get the extension
$arr_ext = array('jpg', 'jpeg', 'gif'); //set allowed extensions
$setNewFileName = time() . "_" . rand(000000, 999999);

//only process if the extension is valid
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 . '/upload/avatar/' . $setNewFileName . '.' . $ext);

    //prepare the filename for database entry 
    $imageFileName = $setNewFileName . '.' . $ext;
    }
}

$getFormvalue = $this->Users->patchEntity($particularRecord, $this->request->data);

if (!empty($this->request->data['upload']['name'])) {
            $getFormvalue->avatar = $imageFileName;
}


if ($this->Users->save($getFormvalue)) {
   $this->Flash->success('Your profile has been sucessfully updated.');
   return $this->redirect(['controller' => 'Users', 'action' => 'dashboard']);
   } else {
   $this->Flash->error('Records not be saved. Please, try again.');
   }
}

Before using this, create a folder in webroot named upload/avatar.

Note: The input('Name Here'), is used in

$this->request->data['upload']['name']

you can print it if you want to see the array result.

Its works like a charm in CakePHP 3.x

  • 11
Reply Report
      • 1
    • Dude I tried your code and image uploading worked very well. But the issue is that no other field data is getting saved now. Why is it so?? Do I need to make any change to ensure proper save??
      • 2
    • $this->request->data should return have the form data 'name' as in the column name for ex: email in table name should be in the email text box. The rest works as the same. No changes required.

Now that everyone makes advertisement for his plugins here, let me do this as well. I've checked the Uploadable behavior linked in the other question, it's pretty simple and half done it seems.

If you want a complete solution that is made to scale on enterprise level check FileStorage out. It has some features I haven't seen in any other implementations yet like taking care of ensuring your won't run into file system limitations in the case you get really many files. It works together with Imagine to process the images. You can use each alone or in combination, this follows SoC.

It is completely event based, you can change everything by implementing your own event listeners. It will require some intermediate level of experience with CakePHP.

There is a quick start guide to see how easy it is to implement it. The following code is taken from it, it's a complete example, please see the quick start guide, it's more detailed.

class Products extends Table {
    public function initialize() {
        parent::initialize();
        $this->hasMany('Images', [
            'className' => 'ProductImages',
            'foreignKey' => 'foreign_key',
            'conditions' => [
                'Documents.model' => 'ProductImage'
            ]
        ]);
        $this->hasMany('Documents', [
            'className' => 'FileStorage.FileStorage',
            'foreignKey' => 'foreign_key',
            'conditions' => [
                'Documents.model' => 'ProductDocument'
            ]
        ]);
    }
}

class ProductsController extends ApController {
    // Upload an image
    public function upload($productId = null) {
        if (!$this->request->is('get')) {
            if ($this->Products->Images->upload($productId, $this->request->data)) {
                $this->Session->set(__('Upload successful!');
            }
        }
    }
}

class ProductImagesTable extends ImageStorageTable {
    public function uploadImage($productId, $data) {
        $data['adapter'] = 'Local';
        $data['model'] = 'ProductImage',
        $data['foreign_key'] = $productId;
        $entity = $this->newEntity($data);
        return $this->save($data);
    }
    public function uploadDocument($productId, $data) {
        $data['adapter'] = 'Local';
        $data['model'] = 'ProductDocument',
        $data['foreign_key'] = $productId;
        $entity = $this->newEntity($data);
        return $this->save($data);
    }
}
  • 2
Reply Report

Maybe the following would help. It's a behavior who helps you to upload files very easy!

http://cakemanager.org/docs/utils/1.0/behaviors/uploadable/

Let me know if you struggle.

Greetz

  • 1
Reply Report
/*Path to Images folder*/
$dir = WWW_ROOT . 'img' .DS. 'thumbnail';
/*Explode the name and ext*/
                $f = explode('.',$data['image']['name']);
                 $ext = '.'.end($f);
    /*Generate a Name in my case i use ID  & slug*/
                $filename = strtolower($id."-".$slug);

     /*Associate the name to the extension  */
                $image = $filename.$ext;


/*Initialize you object and update you table in my case videos*/
                $Videos->image = $image;     
            if ($this->Videos->save($Videos)) {
/*Save image in the thumbnail folders and replace if exist */
            move_uploaded_file($data['image']['tmp_name'],$dir.DS.$filename.'_o'.$ext);

            unlink($dir.DS.$filename.'_o'.$ext);
                } 
  • 0
Reply Report
<?php
namespace App\Controller\Component;

use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
use Cake\Network\Exception\InternalErrorException;
use Cake\Utility\Text;

/**
 * Upload component
 */
class UploadRegCompanyComponent extends Component
{

    public $max_files = 1;


    public function send( $data )
    {
        if ( !empty( $data ) ) 
        {
            if ( count( $data ) > $this->max_files ) 
            {
                throw new InternalErrorException("Error Processing Request. Max number files accepted is {$this->max_files}", 1);
            }

            foreach ($data as $file) 
            {
                $filename = $file['name'];
                $file_tmp_name = $file['tmp_name'];
                $dir = WWW_ROOT.'img'.DS.'uploads/reg_companies';
                $allowed = array('png', 'jpg', 'jpeg');
                if ( !in_array( substr( strrchr( $filename , '.') , 1 ) , $allowed) ) 
                {
                    throw new InternalErrorException("Error Processing Request.", 1);       
                }
                elseif( is_uploaded_file( $file_tmp_name ) )
                {
                    move_uploaded_file($file_tmp_name, $dir.DS.Text::uuid().'-'.$filename);
                }
            }
        }
    }
}
  • 0
Reply Report

We're using https://github.com/josegonzalez/cakephp-upload with great success in our production app, and has done so for quite some time.

Has awesome support for using "Flysystem" (https://flysystem.thephpleague.com/) as well - which is abstractions from specific file system(s) - so moving from normal local file system to S3 is a no-brainer, or Dropbox or whatever place you want :-)

You can find related (high quality) plugins on file uploading right here: https://github.com/FriendsOfCake/awesome-cakephp#files - I've used "Proffer" with success as well, and it's by no means "almost done" or anything alike - both has all my recommendations and is in my eyes production ready!

  • 0
Reply Report

Warm tip !!!

This article is reproduced from Stack Exchange / Stack Overflow, please click

Trending Tags

Related Questions