image processing


Lets have a look at the processing logic for table with image field. For that, we'll create a posts table.

CREATE MODAL AND MIGRATION FILES

php artisan make:model tbl_post -m  

MODAL

 class tbl_post extends Model
{
    protected $table = 'tbl_posts';
    protected $primaryKey = 'pid';
} 

MIGRATION

public function up()
{
  Schema::create('tbl_posts', function (Blueprint $table) {
    $table->increments('pid');
    $table->string('title');
    $table->string('meta_title');
    $table->string('slug');
    $table->string('category');
    $table->longtext('description');
    $table->string('meta_description');
    $table->string('image');
    $table->string('status');
    $table->timestamps();
  });
}  

MIGRATE COLUMNS TO DATABASE TABLE

php artisan migrate  

INSERT POSTS

Let's define the route first to view the page to insert post for which we need to define the closure function in adminController. We'll link the posts to the menus to make it convenient to display data in frontend so we'll retrieve all the menus in this page to include them in the posts table easily.

ADMINCONTROLLER

public function postform(){
  $menus = DB::table('tbl_menus')->get();
  return view ('backend.inserts.post',['menus'=>$menus]);
}  

ROUTE

Route::get('postform','adminController@postform');  

POST FORM

@extends('backend.master')
@section('content')

<div class="row">
  <div class="col-sm-12">
    @if (session('message'))
        <div class="alert alert-success alert-dismissable fade in">
            {{ session('message') }}
        </div>
    @endif
  </div>
  
  <form method="post" action="{{url('addpost')}}" enctype="multipart/form-data">
    <div class="col-sm-6">
      {{ csrf_field() }}
      <input type="hidden" name="table" value="tbl_posts">
      <div class="form-group">
        <label>Title</label>
        <input type="text" name="title" class="form-control">
      </div>
      <div class="form-group">
        <label>Meta Title</label>
        <input type="text" name="meta_title" class="form-control">
      </div>
    </div>
    <div class="col-sm-6">
      <div class="row">
        <div class="col-sm-6">
          <div class="form-group">
            <label>Image</label>
            <input type="file" name="image" class="form-control">
          </div>  
        </div>
        <div class="col-sm-6">
          <div class="form-group">
            <label>Category</label>
            <select name="category" class="form-control">
              @foreach($menus as $menu)
              <option value="{{$menu->slug}}">{{$menu->title}}</option>
              @endforeach
            </select>
          </div>  
        </div>
      </div>   
      <div class="form-group">
        <label>Status</label>
        <select class="form-control" name="status">
          <option value="publish">Publish</option>
          <option value="draft">Draft</option>
        </select>
      </div>
    </div>  
    <div class="col-sm-12">
      <div class="form-group">
        <label>Description</label>
        <textarea name="description" class="form-control" rows="15"></textarea>
      </div>
      <div class="form-group">
        <label>Meta Description</label>
        <textarea name="meta_description" class="form-control" rows="5"></textarea>
      </div>
      <div class="form-group">
        <input type="submit" class="btn btn-success" value="Add Post">
      </div>
    </div>  
    </form>
  </div>
</div>
<script type="text/javascript" src="{{url('public/backend/ckeditor/ckeditor.js')}}"></script>
<script>
 CKEDITOR.replace('description',{
   filebrowserBrowseUrl: "{{url('/public/ckfinder/ckfinder.html')}}",
   filebrowserImageBrowseUrl: "{{url('/public/ckfinder/ckfinder.html?type=Images')}}",
   filebrowserUploadUrl:
   '/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files¤tFolder=/archive/',
   filebrowserImageUploadUrl:
   '/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Images¤tFolder=/cars/'
 });
</script>
@stop

Since we're adding text editor in our post form, we'll need to place our jquery.js link before the ckeditor.js link. So, we'll move our jquery.js link from the footer to the head section and add the ckeditor.js and script to replace input field in the post page. We also added the script to make uploading of image possible inside the textarea too. We displayed the menu titles for selection in the categories field while passing the slug value to database.

ROUTE

Now, the form page is done, we'll point it to the same method we created to add menu.

Route::post('addpost','crudController@insertData');

CRUDCONTROLLER

We created the method insertData to add menu previously. Here, we'll make some changes in the same method to add posts too. Since it's a request with image included, we'll add the logic to process image first.

private function upload($image){
  $name = $image->getClientOriginalName();
  $newName = date('ymdgis').$name;
  $image->move(public_path().'/Uploads',$newName);
  return $newName;
} 

This method will handle the file request coming from the form via post method. It'll take the $_FILES details as it's parameter.

$name will hold the file's original name while we created a new name for the file using datetime. The uploaded file is then moved from temporary location to the destined Uploads folder inside root/public directory and the new name for the file is returned to add as a string value in database image column.

if(Input::hasFile('image')){
  $data['image'] = $this->upload($data['image']);
}
       
DB::table($tbl)->insert($data); 

We simply added a clause in our crudController to check if any file is being sent via request post method. If there's a file we'll send it for processing to the private upload method. If not, other tasks will be performed.

We can define the image column's default value as NULL to make sure the data is submitted without the image value entered in case we need it or check in controller too in order to avoid the validation errors.

if(!empty($data['image'])){
  if(Input::hasFile('image')){
    $data['image'] = $this->upload($data['image']);
  }
}  

DISPLAY POSTS

Lets create the method to display posts from database in adminController. We'll also use pagination here that will be ativated once the data row count exceeds 20.

public function displaypost(){
  $data = DB::table('tbl_posts')->paginate(20);
  return view ('backend.display.post',['data'=>$data]);
}  

Now, lets define the route to point to the adminController method.

Route::get('displaypost','adminController@displaypost');  

Now, we can create the display page to display posts and we'll create it inside the display folder we created in backend.

@extends('backend.master')
@section('content')
<div class="row">
  <div class="col-sm-12">
    @if (session('message'))
        <div class="alert alert-success alert-dismissable fade in">
            {{ session('message') }}
        </div>
    @endif
  </div>
  <div class="col-sm-12">
    <table class="table table-striped table-hover table-bordered">
      <thead>
        <tr>
          <td>S.N.</td>
          <td>Title</td>
          <td>Category</td>
          <td>Description</td>
          <td>Image</td>
          <td>Status</td>
          <td>Edit</td>
          <td>Delete</td>
        </tr>
      </thead>
      <tbody>
        @foreach($data as $key => $post)
        <tr>
          <td>{{++$key}}</td>
          <td>{{$post->title}}</td>
          <td>{{$post->category}}</td>
          <td>{{$post->slug}}</td>
          <td><img src="{{url('public/Uploads')}}/{{$post->image}}" width="100"></td>
          <td>{{$post->status}}</td>          
                    <td><a href="{{url('editpost')}}/{{$post->pid}}" class="btn btn-sm btn-success"><i class="fa fa-edit"></i></a></td>
                    <td><a href="{{url('deletepost')}}/{{$post->pid}}" class="btn btn-sm btn-danger"><i class="fa fa-trash"></i></a></td>
        </tr>
        @endforeach
      </tbody>
    </table>
    <div class="col-sm-12">
      {{$data->links()}}
    </div>
  </div>
</div>
@stop  

DELETE POST

Lets add the method to retrieve and delete post data in adminController.

public function deletepost($id){
  $data = DB::table('tbl_posts')->where('pid',$id)->delete();
  session::flash('message','Post deleted successfully!!!');
  return redirect()->back()->with('message','Post deleted successfully');
}  

Then, define the route for the same.

Route::get('deletepost/{id}','adminController@delete');  

EDIT POST

Lets define the method to edit post in adminController first. We'll also retrieve the menu slugs from menus table to display in the category options. To avoid repetition of the slug that's in the post data, we'll display only those menu slugs that don't match the menu slug in the selected post data.

public function editpost($id){
  $data = DB::table('tbl_posts')->where('pid',$id)->first();
  $menus = DB::table('tbl_menus')->where('slug','!=',$data->category)->get();
  return view ('backend.updates.post',['data'=>$data,'menus'=>$menus]);
}  

Now, we'll define the route to point to the adminController method.

Route::get('editpost/{id}','adminController@editpost');  

Now, the page to display recorded data row and edit it.

@extends('backend.master')
@section('content')

<div class="row">
  <div class="col-sm-12">
    @if (session('message'))
        <div class="alert alert-success alert-dismissable fade in">
            {{ session('message') }}
        </div>
    @endif
  </div>
  
  <form method="post" action="{{url('updatepost')}}/{{$data->pid}}" enctype="multipart/form-data">
    <div class="col-sm-6">
      {{ csrf_field() }}
      <input type="hidden" name="table" value="tbl_posts">
      <input type="hidden" name="pid" value="{{$data->pid}}">
      <div class="form-group">
        <label>Title</label>
        <input type="text" name="title" value="{{$data->title}}" class="form-control">
      </div>
      <div class="form-group">
        <label>Meta Title</label>
        <input type="text" name="meta_title" value="{{$data->meta_title}}" class="form-control">
      </div>
    </div>
    <div class="col-sm-6">
      <div class="row">
        <div class="col-sm-6">
          <div class="form-group">
            <label>Image</label>
            <input type="file" name="image" class="form-control">
          </div>  
        </div>
        <div class="col-sm-6">
          <div class="form-group">
            <label>Category</label>
            <select name="category" class="form-control">
              <option value="{{$data->category}}">{{$data->category}}</option>
              @foreach($menus as $menu)
              <option value="{{$menu->slug}}">{{$menu->slug}}</option>
              @endforeach
            </select>
          </div>  
        </div>
      </div>    
      <div class="form-group">
        <label>Status</label>
        <select class="form-control" name="status">
          <option value="publish">Publish</option>
          <option value="draft">Draft</option>
        </select>
      </div>
    </div>  
    <div class="col-sm-6 col-sm-offset-6">
      <img src="{{url('public/Uploads')}}/{{$data->image}}" width="200">
    </div>
    <div class="col-sm-12">
      <div class="form-group">
        <label>Description</label>
        <textarea name="description" class="form-control" rows="15">
          {{$data->description}}
        </textarea>
      </div>
      <div class="form-group">
        <label>Meta Description</label>
        <textarea name="meta_description" class="form-control" rows="5">
          {{$data->meta_description}}
        </textarea>
      </div>
      <div class="form-group">
        <input type="submit" class="btn btn-success" value="Update Post">
      </div>
    </div>  
    </form>
  </div>
</div>
@stop  

CRUDCONTROLLER

public function updateData()
{
  $data = Input::except('_token');
  $tbl = $data['table'];
  unset ($data['table']);
  $data['updated_at'] = date('Y-m-d H:i:s');
        
  if(Input::has('title')){
    $data['slug'] = $this->slug($data['title']);
  }
        
  if(Input::hasFile('image')){
    $data['image'] = $this->upload($data['image']);
  }  
  
  DB::table($tbl)->where(key($data),reset($data))->update($data);
  session::flash('message','Data updated successfully!!!');
  return redirect()->back()->with('message','Data successfully updated');
}  

ROUTE

Route::post('updatepost/{id}','crudController@updateData');  

NAVIGATION LINKS

<li><a href="{{url('postform')}}"><i class="fa fa-circle-o"></i>Add Posts</a></li>
<li><a href="{{url('displaypost')}}"><i class="fa fa-circle-o"></i>View Posts</a></li>