Search code examples
phpjsonzend-framework2

Checking if a array isn't empty with FormData and Zend Framework 2


I'm trying to see if a array sent from FormData javascript is not empty and if it isn't, use the array to make a directory and upload a file. It shows up as a normal array with all the indexes in $_FILES in the console but when for some reason it is not working on the PHP side. Here is the code that pertains to this:

model -

public function postStatus($status, array $image = array())
{
    if (empty($status)) {
        throw new StatusException("Status text cannot be left empty.");
    } else {
        // get the user's id based on $this->user
        $this->select->columns(array('id'))
        ->where(array('username' => $this->user));

        $query = $this->sql->getAdapter()->query(
            $this->sql->buildSqlString($this->select),
            Adapter::QUERY_MODE_EXECUTE
        );

        if ($query->count() > 0) {
            foreach ($query as $result) {
                $row = $result;
            }

            $select = $this->gateway->select(array('id' => $row['id']));

            if ($select->count() > 0) {
                // update status
                $update_data = array(
                    'status' => $status,
                );

                $update = $this->gateway->update($update_data, array('id' => $row['id']));

                if ($update > 0) {
                    return true;
                } else {
                    throw new StatusException("Error posting status.");
                }
            } else {
                // insert status
                $insert_data = array(
                    'id'     => $row['id'],
                    'status' => $row['status'],
                );

                $insert = $this->gateway->insert($insert_data);

                if ($insert > 0) {
                    // put image into status folder
                    if (count($image) > 0) { // this is the culprit I believe
                        if (!is_dir(getcwd() . '/public/images/profile/' . $this->user . '/status')) {
                            // make the status directory
                            // then insert any images if found
                            mkdir(getcwd() . '/public/images/profile/' . $this->user . '/status');

                            if (is_uploaded_file($image['tmp_name'])) {
                                move_uploaded_file($image['tmp_name'], getcwd() . '/public/images/profile/' . $this->user . '/status/' . $image['name']);
                                return true;
                            } else {
                                throw new StatusException("Error uploading your image for your status.");
                            }
                        } else {
                            // insert any images if found
                            if (is_uploaded_file($image['tmp_name'])) {
                                move_uploaded_file($image['tmp_name'], getcwd() . '/public/images/profile/' . $this->user . '/status/' . $image['name']);
                                return true;
                            } else {
                                throw new StatusException("Error uploading your image for your status.");
                            }
                        }
                    } 

                    // no image
                    return true;
                } else {
                    throw new StatusException("Error posting status.");
                }
            }
        } else {
            throw new StatusException("Invalid username passed.");
        }
    }
}

The array that is passed is as follows:

name: "boned.jpg", type: "image/jpeg", tmp_name: "C:\xampp\tmp\php3684.tmp", error: 0, size: 25388

As you can see, the array isn't empty but the code inside the model is not creating the directory and uploading the file. I've checked the error log and it isn't saying anything about creating the directory or uploading the file, so I am not sure what is going on.

Oh, I am using FormData for the jquery ajax call, so just in case, here is the code for it

$('#post-status').on('click', function() {
   if ($('#status').html() != "Status: " && $('#status').html() != "") {
       var status = $('#status').html();

       var getstatus;
       var getfile;

       var formData = new FormData();

       if (document.getElementById('status-photo') == null) {
           formData.append("statustext", status);

           getstatus = formData.get("statustext");
       } else {
           formData.append("statustext", status);
           formData.append("userfile", document.getElementById('status-photo').files[0]);

           var getstatus = formData.get("statustext");
           var getfile = formData.get("userfile");
       }


       $('#status-msg').html("");

       $.ajax({
           type: "POST",
           contentType: false,
           processData: false,
           url: "/members/status/post-status",
           dataType: "json",
           data: formData
       }).done(function(msg) {
           console.log(msg);
           $('#status-msg').html(msg.success);
           $('#status').html('Status: ');

           $('#added-status-photos').attr('style', 'display: none;');
           $('#delete-include-pic').attr('style', 'display: none;');

           $('#include-pic').attr('style', 'display: block;');

           // update status text
           $.getJSON('/members/status/get-status', function(stat) {
                $('#current-status').html("Current Status: " + stat.status);
           });
        }).fail(function(msg) {
            console.log(msg.fail);
            $('#status-msg').html(msg.fail);

            $('#added-status-photos').attr('style', 'display: none;');
            $('#delete-include-pic').attr('style', 'display: none;');

            $('#include-pic').attr('style', 'display: block;');
        }); 
    } else {
        $('#status-msg').html("Please enter a valid status.");
        return;
    }
});

Any help would be appreciated, as this is driving me nuts.

Thanks!

Update:

Sorry, I thought I put in the controller code, here it is again:

public function poststatusAction()
{
    $layout = $this->layout();
    $layout->setTerminal(true);

    $view_model = new ViewModel();
    $view_model->setTerminal(true);

    if ($this->request->isPost()) {
        try {
            $status = $this->params()->fromPost('statustext');
            $file = $this->params()->fromFiles('userfile');

            if (count($file) > 0) {
                if ($this->getStatusService()->postStatus($status, $file)) {
                    echo json_encode(array('success' => 'Status updated'));
                } 
            } else {
                if ($this->getStatusService()->postStatus($status)) {
                    echo json_encode(array('success' => 'Status updated'));
                }
            }
        } catch (StatusException $e) {
            echo json_encode(array('fail' => $e->getMessage()));
        }
    }

    return $view_model;
}

Solution

  • It might not be clear from my comments so I am putting the code here. You don't need to do this $decoded = json_decode($image, true); since $image is an array not a json.

    if (! empty($image)) {
        if (! is_dir(getcwd() . '/public/images/profile/' . $this->user . '/status')) {
            // make the status directory
            // then insert any images if found
            mkdir(getcwd() . '/public/images/profile/' . $this->user . '/status');
    
            if (is_uploaded_file($image['tmp_name'])) {
                move_uploaded_file($image['tmp_name'], getcwd() . '/public/images/profile/' . $this->user . '/status/' . $image['name']);
                return true;
            } else {
                throw new StatusException("Error uploading your image for your status.");
            }
        } else {
            // insert any images if found
            if (is_uploaded_file($image['tmp_name'])) {
                move_uploaded_file($image['tmp_name'], getcwd() . '/public/images/profile/' . $this->user . '/status/' . $image['name']);
                return true;
            } else {
                throw new StatusException("Error uploading your image for your status.");
            }
        }
    }
    

    Try to change the code to this and you will exactly know where the problem is happening. It looks to me you don't have privileges to create directories.

    if (count($image) > 0) {
        $storeImagesDir = getcwd() . '/data/cache/' . $this->user . '/status';
        if (! is_dir($storeImagesDir)) {
            $dirCreated = mkdir($storeImagesDir,'0755', true);
            if(false === $dirCreated) {
                throw new StatusException("You don't have privileges to create the directory '.".$storeImagesDir."' for storing images.");
            } 
        }
        if (is_uploaded_file($image['tmp_name'])) {
            $imageMoved = move_uploaded_file($image['tmp_name'], $storeImagesDir.'/'. $image['name']);
            if(false === $imageMoved) {
                throw new StatusException("The uploaded image file cannot be moved.");
            }
            return true;
        } else {
            throw new StatusException("The uploaded image file is not found.");
        }
    } else {
        throw new StatusException("Error posting status.");
    }