-3

I am working on a basic blog application in Codeigniter 3.1.8.

There is a create post and an update post functionality.

When a post is created, there is the option to upload a post thumbnail, else a default image is displayed. In the post controller there is the method for creating posts:

public function create() {

    // More code here

    if($this->form_validation->run() === FALSE){
        $this->load->view('partials/header', $data);
        $this->load->view('create');
        $this->load->view('partials/footer');
    } else {
        // Upload image
        $config['upload_path'] = './assets/img/posts';
        $config['allowed_types'] = 'jpg|png';
        $config['max_size'] = '2048';

        $this->load->library('upload', $config);

        if(!$this->upload->do_upload()){
            $errors = array('error' => $this->upload->display_errors());
            $post_image = 'default.jpg';
        } else {
            $data = array('upload_data' => $this->upload->data());
            $post_image = $_FILES['userfile']['name'];
        }

        $this->Posts_model->create_post($post_image);
        redirect('posts');
    }
}

There is a method for updating posts:

public function update() {
    // Form data validation rules
    // irrelevant for the question suppressed 

    $id = $this->input->post('id');

    // Upload image
    $config['upload_path'] = './assets/img/posts';
    $config['allowed_types'] = 'jpg|png';
    $config['max_size'] = '2048';

    $this->load->library('upload', $config);

    $data = array('upload_data' => $this->upload->data());
    $this->upload->do_upload();
    $post_image = $_FILES['userfile']['name'];

    if ($this->form_validation->run()) {
        $this->Posts_model->update_post($id, $post_image);
        redirect('posts/post/' . $id);
    } else {
        $this->edit($id);
    }
}

In the Posts_model model:

public function update_post($id, $post_image) {
    $data = [
        'title' => $this->input->post('title'),
        'description' => $this->input->post('desc'),
        'content' => $this->input->post('body'),
        'post_image' => $post_image,
        'cat_id' => $this->input->post('category')
    ];

    $this->db->where('id', $id);
    return $this->db->update('posts', $data);
}

The edit post view:

 <?php echo form_open_multipart(base_url('posts/update')); ?>
        <input type="hidden" name="id" id="pid" value="<?php echo $post->id; ?>">

        <div class="form-group <?php if(form_error('title')) echo 'has-error';?>">
          <input type="text" name="title" id="title" class="form-control" placeholder="Title" value="<?php echo $post->title; ?>">
          <?php if(form_error('title')) echo form_error('title'); ?> 
        </div>

        <div class="form-group <?php if(form_error('desc')) echo 'has-error';?>">
          <input type="text" name="desc" id="desc" class="form-control" placeholder="Short decription" value="<?php echo $post->description; ?>">
          <?php if(form_error('desc')) echo form_error('desc'); ?> 
        </div>

        <div class="form-group <?php if(form_error('body')) echo 'has-error';?>">
          <textarea name="body" id="body" cols="30" rows="5" class="form-control" placeholder="Add post body"><?php echo $post->content; ?></textarea>
          <?php if(form_error('body')) echo form_error('body'); ?> 
        </div>

        <div class="form-group">
          <select name="category" id="category" class="form-control">
            <?php foreach ($categories as $category): ?>
              <?php if ($category->id == $post->cat_id): ?>
                <option value="<?php echo $category->id; ?>" selected><?php echo $category->name; ?></option>
              <?php else: ?>
              <option value="<?php echo $category->id; ?>"><?php echo $category->name; ?></option>
              <?php endif; ?>
            <?php endforeach; ?>
          </select>
        </div>

        <label for="postimage">Upload an image</label>
        <div class="form-group">
          <input type="file" name="userfile" id="postimage" size="20">
        </div>

        <div class="form-group">
          <input type="submit" value="Save" class="btn btn-block btn-md btn-success">
        </div>
 <?php echo form_close(); ?>

The problem with the update() method is that, when editing a post, unless I replace it's existing thumbnail with a new one (in other words, if I let the file upload field empty), results in leaving the post without a thumbnail:

<img src="http://localhost/ciblog/assets/img/posts/">

What I have tried (not the best idea, I admit) is to fetch the name pg the file already existing in the posts table this way:

$data['post'] = $this->Posts_model->get_post($id);
$post_image = $data['post']->post_image;

But it gives the error Trying to get property of non-object.

What am I doing wrong?

Razvan Zamfir
  • 4,209
  • 6
  • 38
  • 252
  • Trying to get property of non-object: https://stackoverflow.com/a/26572398/2275490 in your case most like object versus array problem, but you need to show your model – Vickel Apr 29 '18 at 18:29
  • In `Posts_model->update_post($id, $post_image);` - when `$post_image` is empty, then don't include it in your update query. Only include it if that variable has value. – Karlo Kokkak Apr 30 '18 at 01:38

1 Answers1

1

Solved it:

In the edit post form, I have added an input of type hidden above the file input, in order to "capture" the posts image from the database:

<input type="hidden" name="postimage" id="postimage" value="<?php echo $post->post_image; ?>">
<label for="postimage">Upload an image</label><div class="form-group">
   <input type="file" name="userfile" id="postimage" size="20">
</div>

In the Posts controller, I have replaced

$data = array('upload_data' => $this->upload->data());
$this->upload->do_upload();
$post_image = $_FILES['userfile']['name'];

with:

if(!$this->upload->do_upload()){
    $errors = array('error' => $this->upload->display_errors());
    $post_image = $this->input->post('postimage');
} else {
    $data = array('upload_data' => $this->upload->data());
    $post_image = $_FILES['userfile']['name'];
}

The code above means: if no new image is uploaded, write the name of the existing one in the posts table again, instead of writing nothing. If instead a new photo is uploaded, write the name of the new photo.

Razvan Zamfir
  • 4,209
  • 6
  • 38
  • 252
  • 1
    Or you could just not write anything to that column as it's an update and a) already contains something b) doesn't contain something but nothing was uploaded... – Alex May 01 '18 at 08:00
  • That means I should modify the *Posts_model* model and right now I don't know how. – Razvan Zamfir May 01 '18 at 10:34
  • Well honestly, and I think I've addressed this before in a question I answered for you, it is best for refactoring if you keep post vars in controller and just send the $data array to the model. So your model function would just look like `$this->db->where(...); return $this->db->update(...);` .etc. Then its rather simple. Just don't include `$data['post_image']` when you pass to your array to the model if no image is uploa. https://stackoverflow.com/questions/4096632/codeigniter-best-practice-in-accessing-this-input-post?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – Alex May 01 '18 at 22:16