Facebook style profile photo upload using PHP + JQuery +Ajax Part1


Introduction:

Hello guys, My last article was “How to build Facebook style Autocomplete using Angular JS, Cygnite PHP, Mysql and Bootstrap template” . Recently I received a request from my readers that “How to build Facebook style profile photo upload, creating thumbnail and save?”. You might have notice many social network when you visit your profile page, you will also notice that when you mouse over into your picture you will see Update Picture or Upload Photo. It is really nice to have on any application. I will not able cover all in a single post. So I decided to divide the post into part. This tutorial will show you how to create "Facebook style profile photo upload using PHP, JQuery and Ajax."

To build this app I am using Cygnite PHP Framework, JQuery, Ajax, Bootstrap template etc. Using framework make my job easier (Since bootstrap theme, inbuilt libraries, MVC, Widget etc), well structured, also gives flexibility to maintain code. If you don't wish use entire framework you can also use Cygnite File Component to do the same.

Installing Composer and Cygnite Framework:

So the first step is to install Cygnite framework to build our application, I will not write "How to install Cygnite into local machine", since it is already covered in my previous article. You can follow below links for Installation of Cygnite Framework but Cygnite v1.2.4 doesn't include File Upload feature, so please update composer.json to download dev-master or manually update the framework core.

Cygnite Framework- Composer Installation

Manual Download from GITHUB

  Live Demo   Download

Step 1:
Let me consider you have already Cygnite installed into your machine. I have installed it into /www/cygnite/ directory. Now create a controller called ProfileController.php into your /cygnite/apps/controllers/ProfileController.php.

We will render the default view page using indexAction. We are not using layout here, but you can also use layout to make your view page much modular, flexible. Paste below code into your controller to call your view page.

 


namespace Apps\Controllers;

use Cygnite\Foundation\Application;
use Cygnite\Mvc\Controller\AbstractBaseController;
use Apps\Models\Country;
use Cygnite\Common\File\Upload\Upload;
use Cygnite\Common\UrlManager\Url;
use Cygnite\FormBuilder\Form;

class AngularController extends AbstractBaseController
{
   protected $templateEngine = false;

   //Plain PHP layout
   //protected $layout = 'layout.base';
  /*
   * Your constructor.
   * @access public
   *
   */
   public function __construct()
   {
      parent::__construct();
   }

  /**
   * Default method for your controller. Render welcome page to user
   * @access public
   *
   */
  public function indexAction()
  { 
     $this->render('index');
  }


   // Upload profile picture
  public function uploadAction()
  {
    $status = Upload::process(function($upload)
    {
        $upload->file = 'document'; // Your file input element name
        $upload->ext = array("JPG", "PNG"); // Add validation for image upload
        //$upload->size = '6144';// limit the size

        if  (isset($_FILES['document'])) {

            if ($upload->save(array("destination"=> "upload",  "fileName"=>"user_profile_".time()))) {

                $response= array('status' => true, 'msg' => 'Uploaded Successfully!' );
            } else {
                $response = array('status' => false, 'msg' => implode(', \n', $upload->getError()) );
            }

            header('Content-type: application/json');
            return  json_encode($response);

        }
    });

    echo $status ;
  }
}


Step 2:
When you create a new controller you also need to create a folder into views/ as same name as controller but lowercase inside /cygnite/apps/views/ directory. I am creating my view page called index.view.php inside /apps/views/profile/index.view.php and paste below code to render our profile default image.



<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="col-sm-9">
    <form enctype="multipart/form-data">
        <div id="profile">
         <a href="javascript:void(0);">
             <img src="<?php echo Url::getBase(); ?>/assets/img/no_image.jpg" class="profile-image"  id="profileImg"/>
               <span id="uploadTrigger"><b>Update Picture</b></span>
               <input name="document"  type="file"  id="file-id" class="active"/>
             </a>
        </div>
        <div style="top:2px;"> </div>
        <div id="status_msg"> </div>
    </form>

</div>

Step 3:
Create a js file called profile.js into cygnite/assets/js/profile.js and paste below code. Cygnite is shipped with bootstrap so you can use it or use cdn link.



$(document).ready(function () {

    $("#uploadTrigger").on('click', function(event) {
        $("#file-id").trigger('click');
    });

//$('.hidden').removeClass('hidden').addClass( 'active');

$(":file").change(function() {

    var file = this.files[0],  name = file.name, size = file.size, type = file.type;
    //Your validation
    var imageType = new Array("image/png","image/jpeg", "image/gif", "image/bmp");

    if(jQuery.inArray(type, imageType )  == -1) {
        $("#status_msg").html("Valid file formats are: jpg, jpeg,png, gif").css('color', '#F00000');
        return false;
    }  else {

        $("#status_msg").html(" ");
        if ($("#file-id").val() !== '') {
            var formData = new FormData($('form')[0]);

            $.ajax({
                url: 'upload',  //Server script to process data
                type: 'POST',
                //Ajax events
                beforeSend: function () {
                    $('#profileImg').addClass( 'profile-image-loading')
                                    .removeClass('profile-image')
                                    .attr('src', '/assets/img/fb_loading.gif');
                },
                success: function (data) {

                    if (data.status) {
                        var reader = new FileReader();
                        reader.onload = function (e) {

                        $('.profile-image-loading')
                            .addClass('profile-image')
                            .removeClass('profile-image-loading')
                            .attr('src', e.target.result);
                           return false;
                        }
                        reader.readAsDataURL(file);

                        $("#status_msg").html(data['msg']).css('color', '#009900');
                    } else {
                        $("#status_msg").html(data['msg']).css('color', '#F00000');
                        return false;
                    }
                },
                // Form data
                data: formData,
                //Options to tell jQuery not to process data or worry about content-type.
                cache: false,
                contentType: false,
                processData: false
            });
        } else {
        alert("Please select valid image.");
        return false;
        }
        }

});

});


Using Standalone Cygnie File Component for File Upload:

If you have already built an application and willing to use only standalone file component you can simply install Cygnite/File component using composer. I have installed composer globally in my system.

Create a composer.json file into your root directory where you want to install component, paste below code and save it.


{
  "require": {
    "php": ">=5.4.0",
    "cygnite/file" : "dev-master"  
  },
  "autoload": {
    "psr-0": {
        "Cygnite\\Common\\File": "cygnite/file/"
     }
   }
}


Now open terminal/command prompt, change to your project directory where composer.json exists and issue below command to install File Upload Component to do the same stuff.



composer install 


I am creating index.php file to access Cygnite File component, and below code to access File Upload feature.




require 'vendor/autoload.php';

use Cygnite\Common\File\Upload\Upload;

$upload = new Upload();

//$upload->setUploadSize(62092);
$upload->file = 'document';
$upload->ext = array("JPG");
$upload->size = '1024';

if(isset($_FILES['document'])) {

    if ( $upload->save(array("destination"=> "upload", /* "fileName"=>"demo_icon","multiUpload"=>true*/)) ) {
        $response = json_encode(array('status' => true, 'msg' => 'Uploaded Successfully!' ));
    }  else {
        $response = json_encode(array('status' => false, 'msg' => $upload->getError() ));
    }

    echo header('Content-type: application/json') .$response;exit;
}


Or you can also use Closure beautiful syntax as below.



require 'vendor/autoload.php';

use Cygnite\Common\File\Upload\Upload;

function fileUpload()
{
    $status = Upload::process( function($upload)   {
        $upload->file = 'document';
        $upload->ext = array("JPG");
        $upload->size = '5000000';

        if  (isset($_FILES['document'])) {

            if ( $upload->save(array("destination"=> "upload",  "fileName"=>"demo_".time(),/*"multiUpload"=>true*/)) ) {
                $response= array('status' => true, 'msg' => 'Uploaded Successfully!' );
            }  else {
                $response = array('status' => false, 'msg' => implode(', \n', $upload->getError()) );
            }

            header('Content-type: application/json');
            return  json_encode($response);
        }
    });

    echo $status ;
}


Now you can call the fileUpload function as usual in core php and calling this method in ajax url will process your ajax file upload. Don't forget to Include all above necessary css and jquery files in order to make the app work.

Finally go to browser and call the application by issuing below url.



http://localhost/cygnite/index.php/profile/


Conclusion:

We sincerely hope you found this article helpful. I will write “How to create thumbnail image / cropping to make image fit into profile area?” in my next post(part 2). If you would like to learn specific tutorial, you can also request tutorial or you are really interested to write tutorial for us please post me. Please don’t forget to like, share with friends, or leave your comments below.

Keep visiting for upcoming posts. Have a nice day.

Related Posts Plugin for WordPress, Blogger...
Follow Us On Facebook Twitter Google+ Linkedin
Copyright @2011-2013 www.appsntech.com. All rights reserved. Powered By- Sanjoy Dey Productions