New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using amazon s3 storage with summernote #72

Closed
ankur1708 opened this Issue Oct 13, 2013 · 73 comments

Comments

Projects
None yet
@ankur1708

ankur1708 commented Oct 13, 2013

Summernote converts uploaded image as a base64 data which is too large to store.
Is there way to inject amazon s3 service, so that only link gets stored in db?

@ghost ghost assigned hackerwins Oct 13, 2013

@drewhamlett

This comment has been minimized.

Show comment
Hide comment
@drewhamlett

drewhamlett Oct 31, 2013

This is what I have. Sorry for the coffeescript. It only does the first image dragged in right now.

sendFile = (file, callback) ->

  data = new FormData()
  data.append("file", file)
  $.ajax {
    url: '/upload',
    data: data,
    cache: false,
    contentType: false,
    processData: false,
    type: 'POST',
    success: (data) ->
      callback(data)
  }

$ () ->
  $post = $('#post-create')
  $post.summernote {
    height: "350px",
    onImageUpload: (files, editor, welEditable) ->
      sendFile files[0], (data) ->
        url = "#{data.scheme}://#{data.host}#{data.path}"
        editor.insertImage(welEditable, url)

Rails controller

class UploadsController < ApplicationController

  def create
    @file = params[:file].tempfile
    s3 = AWS::S3.new
    random = SecureRandom.hex
    image = s3.buckets['my-bucket'].objects.create("#{random}.jpg", @file)

    render(json: image.public_url)
  end
end

drewhamlett commented Oct 31, 2013

This is what I have. Sorry for the coffeescript. It only does the first image dragged in right now.

sendFile = (file, callback) ->

  data = new FormData()
  data.append("file", file)
  $.ajax {
    url: '/upload',
    data: data,
    cache: false,
    contentType: false,
    processData: false,
    type: 'POST',
    success: (data) ->
      callback(data)
  }

$ () ->
  $post = $('#post-create')
  $post.summernote {
    height: "350px",
    onImageUpload: (files, editor, welEditable) ->
      sendFile files[0], (data) ->
        url = "#{data.scheme}://#{data.host}#{data.path}"
        editor.insertImage(welEditable, url)

Rails controller

class UploadsController < ApplicationController

  def create
    @file = params[:file].tempfile
    s3 = AWS::S3.new
    random = SecureRandom.hex
    image = s3.buckets['my-bucket'].objects.create("#{random}.jpg", @file)

    render(json: image.public_url)
  end
end
@ankur1708

This comment has been minimized.

Show comment
Hide comment
@ankur1708

ankur1708 Nov 2, 2013

Thanks drewhjava. That helps.
I will modify it to delete images from s3 as well on removing images from editor content and post it here soon.

ankur1708 commented Nov 2, 2013

Thanks drewhjava. That helps.
I will modify it to delete images from s3 as well on removing images from editor content and post it here soon.

@hackerwins

This comment has been minimized.

Show comment
Hide comment
@hackerwins

hackerwins Nov 3, 2013

Member

@ankur1708, @drewhjava Great!!! 👍

Member

hackerwins commented Nov 3, 2013

@ankur1708, @drewhjava Great!!! 👍

hackerwins added a commit that referenced this issue Nov 3, 2013

@moffepoffe

This comment has been minimized.

Show comment
Hide comment
@moffepoffe

moffepoffe Nov 4, 2013

based on @drewhjava code.

jQuery(document).ready(function() {
    jQuery('#summernote').summernote({
        height: "500px",
        onImageUpload: function(files, editor, welEditable) {
            sendFile(files[0],editor,welEditable);
        }
    });
});
function sendFile(file,editor,welEditable) {
    data = new FormData();
    data.append("file", file);
    $.ajax({
        data: data,
        type: "POST",
        url: "/ajax/saveimage",
        cache: false,
        contentType: false,
        processData: false,
        success: function(url) {
                editor.insertImage(welEditable, url);
        }
    });
}

PHP server side

$f3->route('POST /ajax/saveimage', function($f3){
        $name = randomString();
        $ext = explode('.',$_FILES['file']['name']);
        $filename = $name.'.'.$ext[1];
        $destination = '/home/xxx/public_html/images/'.$filename;
        $location =  $_FILES["file"]["tmp_name"];
        move_uploaded_file($location,$destination);
        echo 'http://xxx.com/images/'.$filename;
    });
function randomString() {
    return md5(rand(100, 200));
}

will work on it to be dynamic :-)

moffepoffe commented Nov 4, 2013

based on @drewhjava code.

jQuery(document).ready(function() {
    jQuery('#summernote').summernote({
        height: "500px",
        onImageUpload: function(files, editor, welEditable) {
            sendFile(files[0],editor,welEditable);
        }
    });
});
function sendFile(file,editor,welEditable) {
    data = new FormData();
    data.append("file", file);
    $.ajax({
        data: data,
        type: "POST",
        url: "/ajax/saveimage",
        cache: false,
        contentType: false,
        processData: false,
        success: function(url) {
                editor.insertImage(welEditable, url);
        }
    });
}

PHP server side

$f3->route('POST /ajax/saveimage', function($f3){
        $name = randomString();
        $ext = explode('.',$_FILES['file']['name']);
        $filename = $name.'.'.$ext[1];
        $destination = '/home/xxx/public_html/images/'.$filename;
        $location =  $_FILES["file"]["tmp_name"];
        move_uploaded_file($location,$destination);
        echo 'http://xxx.com/images/'.$filename;
    });
function randomString() {
    return md5(rand(100, 200));
}

will work on it to be dynamic :-)

@eyeris

This comment has been minimized.

Show comment
Hide comment
@eyeris

eyeris Nov 13, 2013

Hi I have tried this code several times and everything works out until the,

success: function(url) {
editor.insertImage(welEditable, url);

The php function prints the correct image path and I can even access the stored file in browser address bar. but its doesn't insert to the editor. any suggestions

eyeris commented Nov 13, 2013

Hi I have tried this code several times and everything works out until the,

success: function(url) {
editor.insertImage(welEditable, url);

The php function prints the correct image path and I can even access the stored file in browser address bar. but its doesn't insert to the editor. any suggestions

@titosemi

This comment has been minimized.

Show comment
Hide comment
@titosemi

titosemi Nov 16, 2013

@eyeris Your php code has to return back the url to the file in order to be able to render it.

titosemi commented Nov 16, 2013

@eyeris Your php code has to return back the url to the file in order to be able to render it.

@mirivlad

This comment has been minimized.

Show comment
Hide comment
@mirivlad

mirivlad Nov 18, 2013

@moffepoffe, @ankur1708 How do remove the picture from the server if it is removed in the editor? Please show me an example, do not have a high skill in javascript :(

mirivlad commented Nov 18, 2013

@moffepoffe, @ankur1708 How do remove the picture from the server if it is removed in the editor? Please show me an example, do not have a high skill in javascript :(

@drewhamlett

This comment has been minimized.

Show comment
Hide comment
@drewhamlett

drewhamlett Nov 18, 2013

@mirivlad I just leave it on the server. Your talking less then a cent. You should always run your images through imagemagick before uploading.

If I were doing it, I would implement a scraper that runs every day and listed out all images(older ones) on s3 and see if they existed in the posts.

Put it this way.

You store 10,000 100kb images(some will be smaller). That's 0.953674 gb. That's $0.01 on Amazon S3. I think it actually counts as free usage tier also.

http://calculator.s3.amazonaws.com/calc5.html

drewhamlett commented Nov 18, 2013

@mirivlad I just leave it on the server. Your talking less then a cent. You should always run your images through imagemagick before uploading.

If I were doing it, I would implement a scraper that runs every day and listed out all images(older ones) on s3 and see if they existed in the posts.

Put it this way.

You store 10,000 100kb images(some will be smaller). That's 0.953674 gb. That's $0.01 on Amazon S3. I think it actually counts as free usage tier also.

http://calculator.s3.amazonaws.com/calc5.html

@mirivlad

This comment has been minimized.

Show comment
Hide comment
@mirivlad

mirivlad Nov 18, 2013

@drewhjava Yes, I think you're right. Old habits are still with me :)

mirivlad commented Nov 18, 2013

@drewhjava Yes, I think you're right. Old habits are still with me :)

@drewhamlett

This comment has been minimized.

Show comment
Hide comment
@drewhamlett

drewhamlett Nov 18, 2013

@mirivlad Look at the bright side, if you start storing millions of images on Amazon S3 that means your product is successful enough to hopefully have some income. Haha.

drewhamlett commented Nov 18, 2013

@mirivlad Look at the bright side, if you start storing millions of images on Amazon S3 that means your product is successful enough to hopefully have some income. Haha.

@mirivlad

This comment has been minimized.

Show comment
Hide comment
@mirivlad

mirivlad Nov 18, 2013

@drewhjava I'm not going to store images in AS3. The project is small and will be located at the customer's hosting about which I know nothing. If the customer will be required to AS3 to store pictures, I realize it feature for an additional cash :)

mirivlad commented Nov 18, 2013

@drewhjava I'm not going to store images in AS3. The project is small and will be located at the customer's hosting about which I know nothing. If the customer will be required to AS3 to store pictures, I realize it feature for an additional cash :)

@moffepoffe

This comment has been minimized.

Show comment
Hide comment
@moffepoffe

moffepoffe Nov 18, 2013

@mirivlad i will try to fix the code for you later today :)

moffepoffe commented Nov 18, 2013

@mirivlad i will try to fix the code for you later today :)

@mirivlad

This comment has been minimized.

Show comment
Hide comment
@mirivlad

mirivlad Nov 19, 2013

@moffepoffe I would be inordinately grateful to you :)

mirivlad commented Nov 19, 2013

@moffepoffe I would be inordinately grateful to you :)

@soomtong

This comment has been minimized.

Show comment
Hide comment
@soomtong

soomtong Nov 29, 2013

Contributor

thanks friends!

Contributor

soomtong commented Nov 29, 2013

thanks friends!

@soomtong soomtong closed this Nov 29, 2013

@uro

This comment has been minimized.

Show comment
Hide comment
@uro

uro Jan 15, 2014

Hello can anyone help me out?
Since two days i'm trying to figure out how to fix something that should work, but it doesn't (for whatever silly reason).
Sorry for posting this here, just thought it's not big enought to create a new issue.
I belive that a clever person would has a quick look an be able to point the problem whitin the matter of second :) apparently i'm not the cleverest one.

I'ive applied @moffepoffe's method into my project and when i try upload the pic, javascript console comes back with "Uncaught TypeError: Cannot read property '0' of undefined ", second line of pasted text

      onImageUpload: function(files, editor, welEditable) {
            sendFile(files[0],editor,welEditable);
        }

My code:

  $(document).ready(function(){
    $('select').select2();
    $('.note-editable').css('overflow','auto');
    $('.summernote').summernote({
        height: 400,
        onImageUpload: function(files, editor, welEditable) {
            
            sendFile(files[0],editor,welEditable);
        }
      });
    function sendFile(file,editor,welEditable) {
      data = new FormData();
      data.append("file", file);
      console.log('image upload:', file, editor, welEditable);
      console.log(data);
      $.ajax({
          data: data,
          type: "POST",
          url: "upload/index/news",
          cache: false,
          contentType: 'multipart/form-data',
          processData: false,
          success: function(url) {
            editor.insertImage(welEditable, url);
          }
      });
    }
  });

PS: I have tested the upload function on the server side and it works.
PPS: When i uploading the pic to base64 it works fine too.

Now, using the mantioned method uploading pic to server does not work, (looks like the pic not be chosen correctly or for some reason it didn't follow the procedure of chooseing it)

Let me show debug:
a15005656

A big thank you to anyone who can put a hit of light on to this problem, any clues would highly appreciated 👍

uro commented Jan 15, 2014

Hello can anyone help me out?
Since two days i'm trying to figure out how to fix something that should work, but it doesn't (for whatever silly reason).
Sorry for posting this here, just thought it's not big enought to create a new issue.
I belive that a clever person would has a quick look an be able to point the problem whitin the matter of second :) apparently i'm not the cleverest one.

I'ive applied @moffepoffe's method into my project and when i try upload the pic, javascript console comes back with "Uncaught TypeError: Cannot read property '0' of undefined ", second line of pasted text

      onImageUpload: function(files, editor, welEditable) {
            sendFile(files[0],editor,welEditable);
        }

My code:

  $(document).ready(function(){
    $('select').select2();
    $('.note-editable').css('overflow','auto');
    $('.summernote').summernote({
        height: 400,
        onImageUpload: function(files, editor, welEditable) {
            
            sendFile(files[0],editor,welEditable);
        }
      });
    function sendFile(file,editor,welEditable) {
      data = new FormData();
      data.append("file", file);
      console.log('image upload:', file, editor, welEditable);
      console.log(data);
      $.ajax({
          data: data,
          type: "POST",
          url: "upload/index/news",
          cache: false,
          contentType: 'multipart/form-data',
          processData: false,
          success: function(url) {
            editor.insertImage(welEditable, url);
          }
      });
    }
  });

PS: I have tested the upload function on the server side and it works.
PPS: When i uploading the pic to base64 it works fine too.

Now, using the mantioned method uploading pic to server does not work, (looks like the pic not be chosen correctly or for some reason it didn't follow the procedure of chooseing it)

Let me show debug:
a15005656

A big thank you to anyone who can put a hit of light on to this problem, any clues would highly appreciated 👍

@mjim

This comment has been minimized.

Show comment
Hide comment
@mjim

mjim Feb 6, 2014

@oparkadiusz Did you ever resolve this? I'm having the same problem. Summernote is my preferred editor but if my clients can't upload images, then it is useless.

mjim commented Feb 6, 2014

@oparkadiusz Did you ever resolve this? I'm having the same problem. Summernote is my preferred editor but if my clients can't upload images, then it is useless.

@derek3x

This comment has been minimized.

Show comment
Hide comment
@derek3x

derek3x Feb 11, 2014

In case anyone is looking through this issue for help.

I am using Summernote in a Python(Flask) web app. I used python with regex to find the base64 images that my form was submitting. I then converted them back to a proper image, saved it on the server and changed the img src link to be that of the image. It works great.

It could be used as a work around for some people if they have not thought of catching the base64 this way. I agree it seems a bit much considering it gets converted twice now, but I simply could not get the image upload to work with flask.

derek3x commented Feb 11, 2014

In case anyone is looking through this issue for help.

I am using Summernote in a Python(Flask) web app. I used python with regex to find the base64 images that my form was submitting. I then converted them back to a proper image, saved it on the server and changed the img src link to be that of the image. It works great.

It could be used as a work around for some people if they have not thought of catching the base64 this way. I agree it seems a bit much considering it gets converted twice now, but I simply could not get the image upload to work with flask.

@pRdm

This comment has been minimized.

Show comment
Hide comment
@pRdm

pRdm Feb 20, 2014

Amazon recently opened up support for CORS, which allows direct javascript interaction with its buckets.

In order to achieve this, first you have to update the CORS configuration of your S3 bucket.

This is what I use for allowing uploads via the POST action:

<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>https://www.yourdomain.com</AllowedOrigin>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
    </CORSRule>
</CORSConfiguration>

Here's a helpful article from Amazon(http://aws.amazon.com/articles/1434) detailing what you need inside the POST request.

I pre-render the base64 encoded signature and policy strings in the controller:

def load_s3_metadata
  @signature = signature
  @policy = policy
end

def signature(options = {})
  Base64.encode64(
    OpenSSL::HMAC.digest(
      OpenSSL::Digest::Digest.new('sha1'),
      SECRET_ACCESS_KEY,
      policy({ secret_access_key: SECRET_ACCESS_KEY })
    )
  ).gsub(/\n/, '')
end

def policy(options = {})
  Base64.encode64(
    {
      expiration: 30.minutes.from_now.utc.strftime('%Y-%m-%dT%H:%M:%S.000Z'),
      conditions: [
        { bucket: MY_BUCKET },
        { acl: 'public-read' },
        { success_action_status: '201' },
        ["starts-with", "$key", "my_folder/"],
        ["content-length-range", 0, 2097152]
      ]
    }.to_json
  ).gsub(/\n|\r/, '')
end

The conditions inside policy can be modified to fit your requirements. They are outlined in the above Amazon article.

Now in the javascript code (this upload gets triggered in summernote's onImageUpload callback)

$(document).ready(function() {
  $('.summernote').summernote({
    height: 500,
    onImageUpload: function(files, editor, welEditable) {
      sendFile(files[0], editor, welEditable);
    }
  });

  function sendFile(file, editor, welEditable) {
    formData = new FormData();
    formData.append('key', 'my_folder/' + file.name);
    formData.append('AWSAccessKeyId', '<%= ACCESS_KEY %>');
    formData.append('acl', 'public-read');
    formData.append('policy', '<%= @policy %>');
    formData.append('signature', '<%= @signature %>');
    formData.append('success_action_status', '201');
    formData.append('file', file);

    $.ajax({
      data: formData,
      dataType: 'xml',
      type: "POST",
      cache: false,
      contentType: false,
      processData: false,
      url: "https://<%= MY_BUCKET %>.s3-ap-southeast-2.amazonaws.com/",
      success: function(data) {

        // getting the url of the file from amazon and insert it into the editor
        var url = $(data).find('Location').text();
        editor.insertImage(welEditable, url);
      }
    });
  }
});

And voila!

p.s. note that its important to have the following in the ajax or jQuery is going to try and encode the request, resulting in a malformed POST error from Amazon.

  contentType: false,
  processData: false,

pRdm commented Feb 20, 2014

Amazon recently opened up support for CORS, which allows direct javascript interaction with its buckets.

In order to achieve this, first you have to update the CORS configuration of your S3 bucket.

This is what I use for allowing uploads via the POST action:

<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>https://www.yourdomain.com</AllowedOrigin>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
    </CORSRule>
</CORSConfiguration>

Here's a helpful article from Amazon(http://aws.amazon.com/articles/1434) detailing what you need inside the POST request.

I pre-render the base64 encoded signature and policy strings in the controller:

def load_s3_metadata
  @signature = signature
  @policy = policy
end

def signature(options = {})
  Base64.encode64(
    OpenSSL::HMAC.digest(
      OpenSSL::Digest::Digest.new('sha1'),
      SECRET_ACCESS_KEY,
      policy({ secret_access_key: SECRET_ACCESS_KEY })
    )
  ).gsub(/\n/, '')
end

def policy(options = {})
  Base64.encode64(
    {
      expiration: 30.minutes.from_now.utc.strftime('%Y-%m-%dT%H:%M:%S.000Z'),
      conditions: [
        { bucket: MY_BUCKET },
        { acl: 'public-read' },
        { success_action_status: '201' },
        ["starts-with", "$key", "my_folder/"],
        ["content-length-range", 0, 2097152]
      ]
    }.to_json
  ).gsub(/\n|\r/, '')
end

The conditions inside policy can be modified to fit your requirements. They are outlined in the above Amazon article.

Now in the javascript code (this upload gets triggered in summernote's onImageUpload callback)

$(document).ready(function() {
  $('.summernote').summernote({
    height: 500,
    onImageUpload: function(files, editor, welEditable) {
      sendFile(files[0], editor, welEditable);
    }
  });

  function sendFile(file, editor, welEditable) {
    formData = new FormData();
    formData.append('key', 'my_folder/' + file.name);
    formData.append('AWSAccessKeyId', '<%= ACCESS_KEY %>');
    formData.append('acl', 'public-read');
    formData.append('policy', '<%= @policy %>');
    formData.append('signature', '<%= @signature %>');
    formData.append('success_action_status', '201');
    formData.append('file', file);

    $.ajax({
      data: formData,
      dataType: 'xml',
      type: "POST",
      cache: false,
      contentType: false,
      processData: false,
      url: "https://<%= MY_BUCKET %>.s3-ap-southeast-2.amazonaws.com/",
      success: function(data) {

        // getting the url of the file from amazon and insert it into the editor
        var url = $(data).find('Location').text();
        editor.insertImage(welEditable, url);
      }
    });
  }
});

And voila!

p.s. note that its important to have the following in the ajax or jQuery is going to try and encode the request, resulting in a malformed POST error from Amazon.

  contentType: false,
  processData: false,
@mjim

This comment has been minimized.

Show comment
Hide comment
@mjim

mjim Feb 24, 2014

@pRdm Thank you for the in-depth response! It now works for me using Php.

Here is what I use:
(Php from this page: http://www.plupload.com/docs/Upload-to-Amazon-S3#prepare-server-side )

<?php
$bucket = 'my_bucketname';
$folder = 'demo';

// these can be found on your Account page, under Security Credentials > Access Keys
$accessKeyId = 'replace with your access key id';
$secret = 'replace with your secret access key';

$policy = base64_encode(json_encode(array(
  // ISO 8601 - date('c'); generates uncompatible date, so better do it manually
  'expiration' => date('Y-m-d\TH:i:s.000\Z', strtotime('+2 days')), 
  'conditions' => array(
    array('bucket' => $bucket),
    array('acl' => 'public-read'),
    array('success_action_status' => '201'),
    array('starts-with', '$key', $folder.'/')
  )
)));

$signature = base64_encode(hash_hmac('sha1', $policy, $secret, true));

?>

And then my sendFile function with Php:

        function sendFile(file, editor, welEditable) {
          formData = new FormData();
          formData.append('key', '<?php echo $folder; ?>/' + file.name);
          formData.append('AWSAccessKeyId', '<?php echo $accessKeyId; ?>');
          formData.append('acl', 'public-read');
          formData.append('policy', '<?php echo $policy; ?>');
          formData.append('signature', '<?php echo $signature; ?>');
          formData.append('success_action_status', '201');
          formData.append('file', file);

          $.ajax({
            data: formData,
            dataType: 'xml',
            type: "POST",
            cache: false,
            contentType: false,
            processData: false,
            url: "https://<?php echo $bucket ?>.s3.amazonaws.com/",
            success: function(data) {
              // getting the url of the file from amazon and insert it into the editor
              var url = $(data).find('Location').text();
              editor.insertImage(welEditable, url);
            }
          });
        }

mjim commented Feb 24, 2014

@pRdm Thank you for the in-depth response! It now works for me using Php.

Here is what I use:
(Php from this page: http://www.plupload.com/docs/Upload-to-Amazon-S3#prepare-server-side )

<?php
$bucket = 'my_bucketname';
$folder = 'demo';

// these can be found on your Account page, under Security Credentials > Access Keys
$accessKeyId = 'replace with your access key id';
$secret = 'replace with your secret access key';

$policy = base64_encode(json_encode(array(
  // ISO 8601 - date('c'); generates uncompatible date, so better do it manually
  'expiration' => date('Y-m-d\TH:i:s.000\Z', strtotime('+2 days')), 
  'conditions' => array(
    array('bucket' => $bucket),
    array('acl' => 'public-read'),
    array('success_action_status' => '201'),
    array('starts-with', '$key', $folder.'/')
  )
)));

$signature = base64_encode(hash_hmac('sha1', $policy, $secret, true));

?>

And then my sendFile function with Php:

        function sendFile(file, editor, welEditable) {
          formData = new FormData();
          formData.append('key', '<?php echo $folder; ?>/' + file.name);
          formData.append('AWSAccessKeyId', '<?php echo $accessKeyId; ?>');
          formData.append('acl', 'public-read');
          formData.append('policy', '<?php echo $policy; ?>');
          formData.append('signature', '<?php echo $signature; ?>');
          formData.append('success_action_status', '201');
          formData.append('file', file);

          $.ajax({
            data: formData,
            dataType: 'xml',
            type: "POST",
            cache: false,
            contentType: false,
            processData: false,
            url: "https://<?php echo $bucket ?>.s3.amazonaws.com/",
            success: function(data) {
              // getting the url of the file from amazon and insert it into the editor
              var url = $(data).find('Location').text();
              editor.insertImage(welEditable, url);
            }
          });
        }
@jaequery

This comment has been minimized.

Show comment
Hide comment
@jaequery

jaequery Mar 9, 2014

Hello all, someone please help. i don't know why image upload works in the github example page, but not in my local app. i'm just testing on the example page, is there some restriction I should be aware of?

jaequery commented Mar 9, 2014

Hello all, someone please help. i don't know why image upload works in the github example page, but not in my local app. i'm just testing on the example page, is there some restriction I should be aware of?

@seanbotha123

This comment has been minimized.

Show comment
Hide comment
@seanbotha123

seanbotha123 May 2, 2014

anyone who has .NET code for this (preferably VB)? I love summernote, but need to use s3 and .net, I have no idea of how Ruby works so struggling with converting.

Thanks! :)

seanbotha123 commented May 2, 2014

anyone who has .NET code for this (preferably VB)? I love summernote, but need to use s3 and .net, I have no idea of how Ruby works so struggling with converting.

Thanks! :)

@Olivierko

This comment has been minimized.

Show comment
Hide comment
@hamerw

This comment has been minimized.

Show comment
Hide comment
@hamerw

hamerw Jul 19, 2014

This is my 2-cents for a php solution...
setting up summernote...

jQuery(document).ready(function() {
    jQuery('#summernote').summernote({
        height: "500px",
        onImageUpload: function(files, editor, $editable) {
           sendFile(files[0],editor,$editable);
        }
    });
    function sendFile(file,editor,welEditable) {
    data = new FormData();
    data.append("file", file);
      $.ajax({
          url: "saveimage.php",
          data: data,
          cache: false,
          contentType: false,
          processData: false,
          type: 'POST',
          success: function(data){
          alert(data);
            editor.insertImage(welEditable, data);
          },
         error: function(jqXHR, textStatus, errorThrown) {
           console.log(textStatus+" "+errorThrown);
         }
      });
    }
});

php file... saveimage.php

<?php
// A list of permitted file extensions
$allowed = array('png', 'jpg', 'gif','zip');

if(isset($_FILES['file']) && $_FILES['file']['error'] == 0){

    $extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);

    if(!in_array(strtolower($extension), $allowed)){
        echo '{"status":"error"}';
        exit;
    }

    if(move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/'.$_FILES['file']['name'])){
        $tmp='uploads/'.$_FILES['file']['name'];
        echo 'uploads/'.$_FILES['file']['name'];
        //echo '{"status":"success"}';
        exit;
    }
}

echo '{"status":"error"}';
exit;

and that's it. Unless you want to move the image to a different directory, but that's for you to figure out.. :)

hamerw commented Jul 19, 2014

This is my 2-cents for a php solution...
setting up summernote...

jQuery(document).ready(function() {
    jQuery('#summernote').summernote({
        height: "500px",
        onImageUpload: function(files, editor, $editable) {
           sendFile(files[0],editor,$editable);
        }
    });
    function sendFile(file,editor,welEditable) {
    data = new FormData();
    data.append("file", file);
      $.ajax({
          url: "saveimage.php",
          data: data,
          cache: false,
          contentType: false,
          processData: false,
          type: 'POST',
          success: function(data){
          alert(data);
            editor.insertImage(welEditable, data);
          },
         error: function(jqXHR, textStatus, errorThrown) {
           console.log(textStatus+" "+errorThrown);
         }
      });
    }
});

php file... saveimage.php

<?php
// A list of permitted file extensions
$allowed = array('png', 'jpg', 'gif','zip');

if(isset($_FILES['file']) && $_FILES['file']['error'] == 0){

    $extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);

    if(!in_array(strtolower($extension), $allowed)){
        echo '{"status":"error"}';
        exit;
    }

    if(move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/'.$_FILES['file']['name'])){
        $tmp='uploads/'.$_FILES['file']['name'];
        echo 'uploads/'.$_FILES['file']['name'];
        //echo '{"status":"success"}';
        exit;
    }
}

echo '{"status":"error"}';
exit;

and that's it. Unless you want to move the image to a different directory, but that's for you to figure out.. :)

@hamerw

This comment has been minimized.

Show comment
Hide comment
@hamerw

hamerw Jul 19, 2014

Hey

I'm not sure how you have things setup.. but when I replace your url: img_upload.php with my url:saveimage.php it works fine. I have posted my saveimage.php in the blog.

Wayne.

On Saturday, July 19, 2014 12:43:53 PM, suyudo notifications@github.com wrote:

i get error like that.... how to solved it ?
my code
$(document).ready(function() { $('#summernote').summernote({ height: 300, minHeight: null, maxHeight: null, onImageUpload: function(files, editor, welEditable) { data = new FormData(); data.append("file", files[0]); $.ajax({ data: data, type: "POST", url: "img_upload.php", cache: false, contentType: false, processData: false, success: function(data) { alert(data); editor.insertImage(welEditable,data); }, error: function(jqXHR, textStatus, errorThrown) { console.log(textStatus+" "+errorThrown); } }); }, focus: true, toolbar: [ //[groupname, [button list]] ['style', ['bold', 'italic', 'underline', 'clear']], ['font', ['strikethrough']], ['fontsize', ['fontsize']], ['color', ['color']], ['para', ['ul', 'ol', 'paragraph']], ['height', ['height']], ['picture',['picture']] ] , onkeyup: function(e) { console.log(sHTML); }
}); });

Reply to this email directly or view it on GitHub.

hamerw commented Jul 19, 2014

Hey

I'm not sure how you have things setup.. but when I replace your url: img_upload.php with my url:saveimage.php it works fine. I have posted my saveimage.php in the blog.

Wayne.

On Saturday, July 19, 2014 12:43:53 PM, suyudo notifications@github.com wrote:

i get error like that.... how to solved it ?
my code
$(document).ready(function() { $('#summernote').summernote({ height: 300, minHeight: null, maxHeight: null, onImageUpload: function(files, editor, welEditable) { data = new FormData(); data.append("file", files[0]); $.ajax({ data: data, type: "POST", url: "img_upload.php", cache: false, contentType: false, processData: false, success: function(data) { alert(data); editor.insertImage(welEditable,data); }, error: function(jqXHR, textStatus, errorThrown) { console.log(textStatus+" "+errorThrown); } }); }, focus: true, toolbar: [ //[groupname, [button list]] ['style', ['bold', 'italic', 'underline', 'clear']], ['font', ['strikethrough']], ['fontsize', ['fontsize']], ['color', ['color']], ['para', ['ul', 'ol', 'paragraph']], ['height', ['height']], ['picture',['picture']] ] , onkeyup: function(e) { console.log(sHTML); }
}); });

Reply to this email directly or view it on GitHub.

@greerde

This comment has been minimized.

Show comment
Hide comment
@greerde

greerde Aug 31, 2014

Is there an API call to add a class to the generated HTML IMG tag? Specifically, I would like the ability to add the bootstrap img-responsive class to any image uploaded via Summernote.

I have thought about doing it when the the rich text is actually displayed on another page (not in the editor) - but that's not pretty.

Another option is to modify the code within the editor during onblur or similar.

greerde commented Aug 31, 2014

Is there an API call to add a class to the generated HTML IMG tag? Specifically, I would like the ability to add the bootstrap img-responsive class to any image uploaded via Summernote.

I have thought about doing it when the the rich text is actually displayed on another page (not in the editor) - but that's not pretty.

Another option is to modify the code within the editor during onblur or similar.

@Xeoncross

This comment has been minimized.

Show comment
Hide comment
@Xeoncross

Xeoncross Oct 14, 2014

I keep seeing sendFile(files[0],editor,$editable); in these comments. Shouldn't that be a foreach/each loop over files?

https://github.com/HackerWins/summernote/blob/develop/dist/summernote.js#L3737

onImageUpload: function(files, editor, $editable) {
        $.each(files, function (idx, file) {
            sendFile(file,editor,$editable,file.name);
        });
},

Xeoncross commented Oct 14, 2014

I keep seeing sendFile(files[0],editor,$editable); in these comments. Shouldn't that be a foreach/each loop over files?

https://github.com/HackerWins/summernote/blob/develop/dist/summernote.js#L3737

onImageUpload: function(files, editor, $editable) {
        $.each(files, function (idx, file) {
            sendFile(file,editor,$editable,file.name);
        });
},
@sangyoo91

This comment has been minimized.

Show comment
Hide comment
@sangyoo91

sangyoo91 Nov 29, 2014

@pRdm Hello Patrick. I'm trying to follow some of these methods. I'm using Meteor. So I'm working with Javascript / Jquery, and your answer is the most closest I am getting. I am a completely new beginner and linking summer note to S3 has been a big difficult task for me. Could you kindly explain to me which parts I have to edit to my own settings from your example so I can study it and try to make it work? Thank you :)

sangyoo91 commented Nov 29, 2014

@pRdm Hello Patrick. I'm trying to follow some of these methods. I'm using Meteor. So I'm working with Javascript / Jquery, and your answer is the most closest I am getting. I am a completely new beginner and linking summer note to S3 has been a big difficult task for me. Could you kindly explain to me which parts I have to edit to my own settings from your example so I can study it and try to make it work? Thank you :)

@ste6an

This comment has been minimized.

Show comment
Hide comment
@ste6an

ste6an Dec 16, 2014

onImageUpload: function(files, editor, welEditable) {
    sendImage(files).done(function(urls){
        $.each(urls, function(idx, url){
            editor.insertImage(welEditable, url);
        });
    });
}

sendImage = function(files) {
    var defer = $.Deferred();
    $.when.apply($, $.map(files, function(file){
        var data = new FormData();
        data.append("file", file);
        return $.ajax({
            data: data,
            type: "POST",
            url: "/uploadimage",
            contentType: false,
            processData: false
        })
    })).done(function(){
        console.log(arguments);
        if (files.length == 1){
            defer.resolve([arguments[0].url]);
        }else{
            defer.resolve($.map(arguments, function(responseData){
                return responseData[0].url;
            }));
        }
    });

    return defer.promise();
};

ste6an commented Dec 16, 2014

onImageUpload: function(files, editor, welEditable) {
    sendImage(files).done(function(urls){
        $.each(urls, function(idx, url){
            editor.insertImage(welEditable, url);
        });
    });
}

sendImage = function(files) {
    var defer = $.Deferred();
    $.when.apply($, $.map(files, function(file){
        var data = new FormData();
        data.append("file", file);
        return $.ajax({
            data: data,
            type: "POST",
            url: "/uploadimage",
            contentType: false,
            processData: false
        })
    })).done(function(){
        console.log(arguments);
        if (files.length == 1){
            defer.resolve([arguments[0].url]);
        }else{
            defer.resolve($.map(arguments, function(responseData){
                return responseData[0].url;
            }));
        }
    });

    return defer.promise();
};
@WilsonFpz

This comment has been minimized.

Show comment
Hide comment
@WilsonFpz

WilsonFpz Jan 16, 2015

If the dragged image by user is not from local desktop, but from the same html, such as a thumbnail.
How could make the summernote identifier the "src" and attached to the editor zone automatically?
Thanks.
[edited: Closed#841]

WilsonFpz commented Jan 16, 2015

If the dragged image by user is not from local desktop, but from the same html, such as a thumbnail.
How could make the summernote identifier the "src" and attached to the editor zone automatically?
Thanks.
[edited: Closed#841]

@EvilCult

This comment has been minimized.

Show comment
Hide comment
@EvilCult

EvilCult May 5, 2015

I've tried these codes, but no one worked. The php code is ok, but jQuery got an error at:

success: function(url) {
editor.insertImage(welEditable, url);

And, here is my solution...In case someone got the same problem..
based on @drewhamlett

    function setSummerNote () {
        $('#summernote').summernote({
            height: 300,  
            focus: true,
            onImageUpload: function(files) {
                sendFile(files[0]);
            }
        });
    }
    function sendFile(file) {
        data = new FormData();
        data.append("file", file);
        $.ajax({
            data: data,
            type: "POST",
            url: "xxxx.php",// your php url
            cache: false,
            contentType: false,
            processData: false,
            success: function(url) {
                $('#summernote').summernote('editor.insertImage', url);
            }
        });

Hope this could help someone~

EvilCult commented May 5, 2015

I've tried these codes, but no one worked. The php code is ok, but jQuery got an error at:

success: function(url) {
editor.insertImage(welEditable, url);

And, here is my solution...In case someone got the same problem..
based on @drewhamlett

    function setSummerNote () {
        $('#summernote').summernote({
            height: 300,  
            focus: true,
            onImageUpload: function(files) {
                sendFile(files[0]);
            }
        });
    }
    function sendFile(file) {
        data = new FormData();
        data.append("file", file);
        $.ajax({
            data: data,
            type: "POST",
            url: "xxxx.php",// your php url
            cache: false,
            contentType: false,
            processData: false,
            success: function(url) {
                $('#summernote').summernote('editor.insertImage', url);
            }
        });

Hope this could help someone~

@easylogic

This comment has been minimized.

Show comment
Hide comment
@easylogic

easylogic May 6, 2015

Member

@EvilCult

can you tell me your summernote's version , browser' name and version ?

Member

easylogic commented May 6, 2015

@EvilCult

can you tell me your summernote's version , browser' name and version ?

@EvilCult

This comment has been minimized.

Show comment
Hide comment
@EvilCult

EvilCult May 6, 2015

@easylogic
I download SummerNote from summernote.org, the version is 0.6.6 dist.
And I'm using Chrome version:41.0.2272.104 (64-bit).

Try the basic code like this:

var $summernote = $('#summernote');
$summernote.summernote({
  onImageUpload: function(files, editor, welEditable) {
    console.log(files, editor, welEditable);
  }
});

Then console shows this:

FileList {0: File, length: 1, item: function}0: Filelength: 1__proto__: FileList undefined undefined

EvilCult commented May 6, 2015

@easylogic
I download SummerNote from summernote.org, the version is 0.6.6 dist.
And I'm using Chrome version:41.0.2272.104 (64-bit).

Try the basic code like this:

var $summernote = $('#summernote');
$summernote.summernote({
  onImageUpload: function(files, editor, welEditable) {
    console.log(files, editor, welEditable);
  }
});

Then console shows this:

FileList {0: File, length: 1, item: function}0: Filelength: 1__proto__: FileList undefined undefined
@tangpanqing

This comment has been minimized.

Show comment
Hide comment
@tangpanqing

tangpanqing May 7, 2015

@EvilCult
thanks,its helpful.

tangpanqing commented May 7, 2015

@EvilCult
thanks,its helpful.

@hainguyents13

This comment has been minimized.

Show comment
Hide comment
@hainguyents13

hainguyents13 May 9, 2015

@EvilCult just awesome 👍 thank you alot, i've stucked on this for days

hainguyents13 commented May 9, 2015

@EvilCult just awesome 👍 thank you alot, i've stucked on this for days

@gzldx

This comment has been minimized.

Show comment
Hide comment
@gzldx

gzldx May 11, 2015

@EvilCult I got the same problem..Thanks a lot
qq 20150512000333

gzldx commented May 11, 2015

@EvilCult I got the same problem..Thanks a lot
qq 20150512000333

@MACscr

This comment has been minimized.

Show comment
Hide comment
@MACscr

MACscr Sep 25, 2015

So what is the final working solution?

MACscr commented Sep 25, 2015

So what is the final working solution?

@mozillazg

This comment has been minimized.

Show comment
Hide comment
@mozillazg

mozillazg Sep 25, 2015

@MACscr Hi, I written a demo, maybe it'll help you: https://output.jsbin.com/taxire

mozillazg commented Sep 25, 2015

@MACscr Hi, I written a demo, maybe it'll help you: https://output.jsbin.com/taxire

@cssjockey

This comment has been minimized.

Show comment
Hide comment
@cssjockey

cssjockey Oct 13, 2015

Here's how I implemented this:

jQuery Code

$('.wysiwyg').summernote({
    height: 500,
    onImageUpload: function(files, editor, welEditable) {
        // upload image to server and create imgNode...
        for (var i = files.length - 1; i >= 0; i--) {
            sendFile(files[i], this);
        }
    }
});

function sendFile(file, el) {
    var form_data = new FormData();
    form_data.append('file', file);
    $.ajax({
        data: form_data,
        type: "POST",
        url: "/media/ajaxupload",
        cache: false,
        contentType: false,
        processData: false,
        success: function(url) {
            $(el).summernote('editor.insertImage', url);
        }
    });
}

PHP Code should return the URL and this code will insert selected images to the editor.

Hope this helps.

cssjockey commented Oct 13, 2015

Here's how I implemented this:

jQuery Code

$('.wysiwyg').summernote({
    height: 500,
    onImageUpload: function(files, editor, welEditable) {
        // upload image to server and create imgNode...
        for (var i = files.length - 1; i >= 0; i--) {
            sendFile(files[i], this);
        }
    }
});

function sendFile(file, el) {
    var form_data = new FormData();
    form_data.append('file', file);
    $.ajax({
        data: form_data,
        type: "POST",
        url: "/media/ajaxupload",
        cache: false,
        contentType: false,
        processData: false,
        success: function(url) {
            $(el).summernote('editor.insertImage', url);
        }
    });
}

PHP Code should return the URL and this code will insert selected images to the editor.

Hope this helps.

@geekpeng

This comment has been minimized.

Show comment
Hide comment
@geekpeng

geekpeng Jan 7, 2016

maybe you can do like this(use base64 data at first, after upload successful use the response url replace img src, if take a lot time upload photos )

var postSummernot = $("#summernote-post").summernote({
    callbacks: {
        onImageUpload: function(files) {
            sendFile(files[0]);
        }
    }
});

function sendFile(file) {
    var formData = new FormData();
    formData.append("photo", file);

    var fileData = URL.createObjectURL(file);
    postSummernot.summernote('insertImage', fileData,function ($image) {
        $.ajax({
            url: "/photo/upload",
            data: formData,
            cache: false,
            contentType: false,
            processData: false,
            dataType:"json",
            type: 'POST',
            success: function(data){
                $image.attr('src', data.url);
            }
        });

    });
}

geekpeng commented Jan 7, 2016

maybe you can do like this(use base64 data at first, after upload successful use the response url replace img src, if take a lot time upload photos )

var postSummernot = $("#summernote-post").summernote({
    callbacks: {
        onImageUpload: function(files) {
            sendFile(files[0]);
        }
    }
});

function sendFile(file) {
    var formData = new FormData();
    formData.append("photo", file);

    var fileData = URL.createObjectURL(file);
    postSummernot.summernote('insertImage', fileData,function ($image) {
        $.ajax({
            url: "/photo/upload",
            data: formData,
            cache: false,
            contentType: false,
            processData: false,
            dataType:"json",
            type: 'POST',
            success: function(data){
                $image.attr('src', data.url);
            }
        });

    });
}
@achese15

This comment has been minimized.

Show comment
Hide comment
@achese15

achese15 Jan 31, 2016

Please can someone help me structure a code for summer note which will upload images to my server e.g "Bob.com/img/uploads" and then return the link back to the text editor so I could use it .....am new with this...please help...thank you

achese15 commented Jan 31, 2016

Please can someone help me structure a code for summer note which will upload images to my server e.g "Bob.com/img/uploads" and then return the link back to the text editor so I could use it .....am new with this...please help...thank you

@piaoyizhimei

This comment has been minimized.

Show comment
Hide comment
@piaoyizhimei

piaoyizhimei Apr 14, 2016

Hi,I use the onImageUpload ,I have the result, Before My Submit , An image's src is '/upload/1460626854.jpg', but after my submit, the src is 'blob:http%3A//a.test.com/c8f2bbe5-38b1-402c-949e-c00be1680c41'。How can i use the '/upload/1460626854.jpg' ? help !!!!

piaoyizhimei commented Apr 14, 2016

Hi,I use the onImageUpload ,I have the result, Before My Submit , An image's src is '/upload/1460626854.jpg', but after my submit, the src is 'blob:http%3A//a.test.com/c8f2bbe5-38b1-402c-949e-c00be1680c41'。How can i use the '/upload/1460626854.jpg' ? help !!!!

@jcshep

This comment has been minimized.

Show comment
Hide comment
@jcshep

jcshep May 23, 2016

@piaoyizhimei
Did you ever figure this out? I'm having the same issue using 0.8.1

jcshep commented May 23, 2016

@piaoyizhimei
Did you ever figure this out? I'm having the same issue using 0.8.1

@mrrtee

This comment has been minimized.

Show comment
Hide comment
@mrrtee

mrrtee Jul 31, 2016

Contributor

I also got same problem as occurred with @piaoyizhimei , I'm using summernote v0.8.1, I can upload image to folder, but script return image as base64 code

Contributor

mrrtee commented Jul 31, 2016

I also got same problem as occurred with @piaoyizhimei , I'm using summernote v0.8.1, I can upload image to folder, but script return image as base64 code

@merajiyan

This comment has been minimized.

Show comment
Hide comment
@merajiyan

merajiyan Oct 6, 2016

hello everyone,
i've tested some ways of this page but it didnt work correctly i just want upload my files into my folder instead of base64
any working way?

merajiyan commented Oct 6, 2016

hello everyone,
i've tested some ways of this page but it didnt work correctly i just want upload my files into my folder instead of base64
any working way?

@lilicbush

This comment has been minimized.

Show comment
Hide comment
@lilicbush

lilicbush Oct 19, 2016

$(document).ready(function () {
    var $summernote = $('.summernote-textarea').summernote({
        lang: 'ru-RU',
        height: 400,
        callbacks: {
            onImageUpload: function (files) {
                sendFile($summernote, files[0]);
            }
        }
    });
});

function sendFile($summernote, file) {
    var formData = new FormData();
    formData.append("file", file);
    $.ajax({
        url: '/new/files/upload',
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        type: 'POST',
        success: function (data) {
            $summernote.summernote('insertImage', data, function ($image) {
                $image.attr('src', data);
            });
        }
    });

}

lilicbush commented Oct 19, 2016

$(document).ready(function () {
    var $summernote = $('.summernote-textarea').summernote({
        lang: 'ru-RU',
        height: 400,
        callbacks: {
            onImageUpload: function (files) {
                sendFile($summernote, files[0]);
            }
        }
    });
});

function sendFile($summernote, file) {
    var formData = new FormData();
    formData.append("file", file);
    $.ajax({
        url: '/new/files/upload',
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        type: 'POST',
        success: function (data) {
            $summernote.summernote('insertImage', data, function ($image) {
                $image.attr('src', data);
            });
        }
    });

}

@merajiyan

This comment has been minimized.

Show comment
Hide comment
@merajiyan

merajiyan Oct 19, 2016

@lilicbush
when i put this code on my page and then i select a image to upload it doesnt appear on page!why?

merajiyan commented Oct 19, 2016

@lilicbush
when i put this code on my page and then i select a image to upload it doesnt appear on page!why?

@AlejandroSC

This comment has been minimized.

Show comment
Hide comment
@AlejandroSC

AlejandroSC Dec 23, 2016

this is my code for js:

	$(document).ready(function() {
		$('#summernote').summernote({
			placeholder: 'Escribe aquí',
			lang: 'es-ES',
			height: 500,	// set editor height
			minHeight: null,	// set minimum height of editor
			maxHeight: null,	// set maximum height of editor
			focus: true,	// set focus to editable area after initializing summernote
			callbacks: {
				onImageUpload: function(files)
				{
					for(var i = 0; i < files.length; i++)
					{
						SubirImagen(files[i]);
					}
				}
			}
		});
	});

Function for upload image

	function SubirImagen(file)
	{
		if(file.type.includes('image'))
		{
			var name = file.name.split(".");
			name = name[0];  
			var data = new FormData();
			data.append('file', file);
			$.ajax({
				url: 'subir.php',
				type: 'POST',
				contentType: false,
				cache: false,
				processData: false,
				dataType: 'JSON',
				data: data,
				success: function (response) 
				{
					if(response.is_ok)
					{
						$('#summernote').summernote('insertImage', response.url, name);
					}
					else
					{
						console.log(response.error);
					}
				}
			})
			.fail(function(e) {
				console.log(e);
			});
		}
		else
		{
			console.log("El tipo de archivo que intentaste subir no es una imagen");
		}
	}

And for PHP:

	$message['is_ok'] = false;

	if(isset($_FILES))
	{
		if(!$_FILES['file']['error'])
		{
			if(preg_match("/image/", $_FILES['file']['type']))
			{
				$name = md5(rand(100, 200));
				$ext = explode('.', $_FILES['file']['name']);
				$filename = $name . '.' . $ext[1];
				$destination = 'C:\\xampp\\htdocs\\summernote\\images\\' . $filename;
				$location = $_FILES["file"]["tmp_name"];
				move_uploaded_file($location, $destination);
				$message['url'] = '/summernote/images/' . $filename; 
				$message['is_ok'] = true;
			}
			else
			{
				$message['error'] = 'El tipo de archivo no es una imagen';
			}
		}
		else
		{
			$message['error'] = "La imagen no se ha subido correctamente error(".$_FILES['file']['error'].")";
		}	
	}
	else
	{
		$message['error'] = "No se ha enviado ningun archivo";
	}

	echo json_encode($message);

AlejandroSC commented Dec 23, 2016

this is my code for js:

	$(document).ready(function() {
		$('#summernote').summernote({
			placeholder: 'Escribe aquí',
			lang: 'es-ES',
			height: 500,	// set editor height
			minHeight: null,	// set minimum height of editor
			maxHeight: null,	// set maximum height of editor
			focus: true,	// set focus to editable area after initializing summernote
			callbacks: {
				onImageUpload: function(files)
				{
					for(var i = 0; i < files.length; i++)
					{
						SubirImagen(files[i]);
					}
				}
			}
		});
	});

Function for upload image

	function SubirImagen(file)
	{
		if(file.type.includes('image'))
		{
			var name = file.name.split(".");
			name = name[0];  
			var data = new FormData();
			data.append('file', file);
			$.ajax({
				url: 'subir.php',
				type: 'POST',
				contentType: false,
				cache: false,
				processData: false,
				dataType: 'JSON',
				data: data,
				success: function (response) 
				{
					if(response.is_ok)
					{
						$('#summernote').summernote('insertImage', response.url, name);
					}
					else
					{
						console.log(response.error);
					}
				}
			})
			.fail(function(e) {
				console.log(e);
			});
		}
		else
		{
			console.log("El tipo de archivo que intentaste subir no es una imagen");
		}
	}

And for PHP:

	$message['is_ok'] = false;

	if(isset($_FILES))
	{
		if(!$_FILES['file']['error'])
		{
			if(preg_match("/image/", $_FILES['file']['type']))
			{
				$name = md5(rand(100, 200));
				$ext = explode('.', $_FILES['file']['name']);
				$filename = $name . '.' . $ext[1];
				$destination = 'C:\\xampp\\htdocs\\summernote\\images\\' . $filename;
				$location = $_FILES["file"]["tmp_name"];
				move_uploaded_file($location, $destination);
				$message['url'] = '/summernote/images/' . $filename; 
				$message['is_ok'] = true;
			}
			else
			{
				$message['error'] = 'El tipo de archivo no es una imagen';
			}
		}
		else
		{
			$message['error'] = "La imagen no se ha subido correctamente error(".$_FILES['file']['error'].")";
		}	
	}
	else
	{
		$message['error'] = "No se ha enviado ningun archivo";
	}

	echo json_encode($message);
@Gorbulev-Sergey

This comment has been minimized.

Show comment
Hide comment
@Gorbulev-Sergey

Gorbulev-Sergey Dec 26, 2016

Спасибо авторам за Summernote, отличный редактор.
Спасибо ребятам за примеры. На основании ваших примеров написал свой код для asn.net mvc:

VIEW:

<textarea name="содержимое" id="содержимое"></textarea>

`<script>

$(document).ready(function () {
    $('#содержимое').summernote({
       callbacks: {
           onImageUpload: function (files) {
                for (var i = 0; i < files.length; i++) {
                    send(files[i]);
                }
            }
        }
    });
});
function send(file) {
    if (file.type.includes('image')) {
        var name = file.name.split(".");
        name = name[0];
        var data = new FormData();
        data.append('file', file);
        $.ajax({
            url: '/Записи/Сохранить',
            type: 'POST',
            contentType: false,
            cache: false,
            processData: false,
            dataType: 'JSON',
            data: data,
            success: function (url) {
                $('#содержимое').summernote('insertImage', url);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                alert(textStatus + " " + errorThrown);
            }
        });
    }
}

</script>`

CONTROLLER:

[HttpPost]
public ActionResult Сохранить(System.Web.HttpPostedFileWrapper file)
{
if (!System.IO.File.Exists(Server.MapPath(file.FileName)))
{
file.SaveAs( Server.MapPath(file.FileName));
}
return Json(file.FileName);
}

Gorbulev-Sergey commented Dec 26, 2016

Спасибо авторам за Summernote, отличный редактор.
Спасибо ребятам за примеры. На основании ваших примеров написал свой код для asn.net mvc:

VIEW:

<textarea name="содержимое" id="содержимое"></textarea>

`<script>

$(document).ready(function () {
    $('#содержимое').summernote({
       callbacks: {
           onImageUpload: function (files) {
                for (var i = 0; i < files.length; i++) {
                    send(files[i]);
                }
            }
        }
    });
});
function send(file) {
    if (file.type.includes('image')) {
        var name = file.name.split(".");
        name = name[0];
        var data = new FormData();
        data.append('file', file);
        $.ajax({
            url: '/Записи/Сохранить',
            type: 'POST',
            contentType: false,
            cache: false,
            processData: false,
            dataType: 'JSON',
            data: data,
            success: function (url) {
                $('#содержимое').summernote('insertImage', url);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                alert(textStatus + " " + errorThrown);
            }
        });
    }
}

</script>`

CONTROLLER:

[HttpPost]
public ActionResult Сохранить(System.Web.HttpPostedFileWrapper file)
{
if (!System.IO.File.Exists(Server.MapPath(file.FileName)))
{
file.SaveAs( Server.MapPath(file.FileName));
}
return Json(file.FileName);
}

@patourasalexandros

This comment has been minimized.

Show comment
Hide comment
@patourasalexandros

patourasalexandros Jan 31, 2017

@titosemi can you explain me more the answer you gave to @eyeris ? i have the same problem (i work inside codeigniter) and the url of the image is correct

patourasalexandros commented Jan 31, 2017

@titosemi can you explain me more the answer you gave to @eyeris ? i have the same problem (i work inside codeigniter) and the url of the image is correct

@feldy

This comment has been minimized.

Show comment
Hide comment
@feldy

feldy Feb 19, 2017

Thanks @AlejandroSC. your script work for me. btw can you explain how to handle the process so that can't duplicate files on folder?

feldy commented Feb 19, 2017

Thanks @AlejandroSC. your script work for me. btw can you explain how to handle the process so that can't duplicate files on folder?

@gomako

This comment has been minimized.

Show comment
Hide comment
@gomako

gomako Mar 27, 2017

Just to throw my Laravel (5.2) version into the mix.

Using @Gorbulev-Sergey javascript with the addition of the Laravel csrf token.

$('#summernote').summernote({
  height: 500,
  callbacks: {
    onImageUpload: function(files) {
      for(var i=0; i < files.length; i++) {
        sendCMSFile(files[i]);
      } 
    }
  }
});

function sendCMSFile(file) {
  if (file.type.includes('image')) {
    var name = file.name.split(".");
    name = name[0];
    var data = new FormData();
    data.append('file', file);
    data.append('_token', window.Laravel.csrfToken); // https://laravel.com/docs/5.4/csrf#csrf-introduction
    $.ajax({
        url: '/uploadCMSFile',
        type: 'POST',
        contentType: false,
        cache: false,
        processData: false,
        dataType: 'JSON',
        data: data,
        success: function (url) {
          $('#summernote').summernote('insertImage', url);
        },
        error: function (jqXHR, textStatus, errorThrown) {
          console.error(textStatus + " " + errorThrown);
        }
    });
  }
}

The controller reached by posting to /uploadCMSFlle which uses the excellent Intervention Image package

public function uploadCMSFile(Request $request)
{
        $storageName = \Faker\Provider\Uuid::uuid();
        $ext = $file->guessExtension();

        // The publicly accessible URL (you will want to change this to suit your needs)
        $url = '/assets/' . $storageName . '.' . $ext;

        // The actual path to store the file
        $fullPath =  public_path($url);

        // Resize the image and save
        InterventionImage::make($file)->resize(800, null, function ($constraint) {
            $constraint->aspectRatio(); // Maintain aspect ratio
            $constraint->upsize(); // Don't scale up
        })->save($fullPath); // Save

        return response()->json($url);
}

If you want to avoid any duplicate files, you could skip the UUID bit and just rely on the original filename, but you may find you run into issues with overwriting files.

gomako commented Mar 27, 2017

Just to throw my Laravel (5.2) version into the mix.

Using @Gorbulev-Sergey javascript with the addition of the Laravel csrf token.

$('#summernote').summernote({
  height: 500,
  callbacks: {
    onImageUpload: function(files) {
      for(var i=0; i < files.length; i++) {
        sendCMSFile(files[i]);
      } 
    }
  }
});

function sendCMSFile(file) {
  if (file.type.includes('image')) {
    var name = file.name.split(".");
    name = name[0];
    var data = new FormData();
    data.append('file', file);
    data.append('_token', window.Laravel.csrfToken); // https://laravel.com/docs/5.4/csrf#csrf-introduction
    $.ajax({
        url: '/uploadCMSFile',
        type: 'POST',
        contentType: false,
        cache: false,
        processData: false,
        dataType: 'JSON',
        data: data,
        success: function (url) {
          $('#summernote').summernote('insertImage', url);
        },
        error: function (jqXHR, textStatus, errorThrown) {
          console.error(textStatus + " " + errorThrown);
        }
    });
  }
}

The controller reached by posting to /uploadCMSFlle which uses the excellent Intervention Image package

public function uploadCMSFile(Request $request)
{
        $storageName = \Faker\Provider\Uuid::uuid();
        $ext = $file->guessExtension();

        // The publicly accessible URL (you will want to change this to suit your needs)
        $url = '/assets/' . $storageName . '.' . $ext;

        // The actual path to store the file
        $fullPath =  public_path($url);

        // Resize the image and save
        InterventionImage::make($file)->resize(800, null, function ($constraint) {
            $constraint->aspectRatio(); // Maintain aspect ratio
            $constraint->upsize(); // Don't scale up
        })->save($fullPath); // Save

        return response()->json($url);
}

If you want to avoid any duplicate files, you could skip the UUID bit and just rely on the original filename, but you may find you run into issues with overwriting files.

@crsssl

This comment has been minimized.

Show comment
Hide comment
@crsssl

crsssl Jul 19, 2017

Here's a workable MeteorJS version for you:

On the client:

var snDefaults = _.extend(YOUR_SUMMERNOTE_DEFAULTS, {
  callbacks: {
    // Upload an image to AWS and replace with an IMG node (with src attr as URL)
    onImageUpload: function(files) {
      var self = this;
      var reader = new FileReader();
      reader.onload = function () {
        var imageFile = _.pick(files[0], 'name', 'type', 'size');   // Convert to EJSON-able object
        var imageData = reader.result;                              // Binary string version
        Meteor.call('saveImageFile', imageFile, imageData, function(err, res) {
          if (!err) {
            $(self).summernote('insertImage', res, slugify(imageFile.name));
          }
        });  
      };
      reader.readAsBinaryString(new Blob([files[0]]));              // 
    }
  }
});

$("#inputNode").summernote(snDefaults);

And on the server:

Meteor.methods({
  saveImageFile: function(file, blob) {
    check(file, Object);    // Recall this is an EJSON object (no blobs allowed!)
    check(blob, String);    // The image blob is passed as a binary string instead

    // SETUP:

    var bucketName        = Meteor.settings.public.bucketName;    // **Replace with yours**
    var bucketUrl         = Meteor.settings.public.bucketUrl;     // **Replace with the full URL**
    var imageStore        = Meteor.settings.public.imageFolder;   // **Replace with yours**

    var allowedImageExtensions = /\.(gif|jpg|jpeg|png)$/;
    var allowedImageTypes      = ["image/gif", "image/jpeg", "image/png"];
    var allowedImageSize       = 5242880;  // 5 MB

    // Simple filename cleanup function
    function cleanName(str) {
      if (str) { return slugify(str.replace(/\.\./g,'')); }
    }

    // CHECK:

    if (! allowedImageExtensions.test(file.name.toLowerCase())) { throw new Meteor.Error('Invalid image file extension.'); return; }
    if (allowedImageTypes.indexOf(file.type.toLowerCase()) < 0) { throw new Meteor.Error('Invalid image file type.'); return; }
    if (allowedImageSize < file.size) { throw new Meteor.Error('Invalid image file size.'); return; }

    // PROCESS:

    var serverFileName = Random.id() + '_' + cleanName(file.name);
    var key = imageStore + "/" + serverFileName;

    try {

      var s3 = new AWS.S3();
      var res = s3.putObjectSync({
        "Bucket": bucketName,
        "ACL": 'public-read',
        "Body": new Buffer(blob, 'binary'),
        "ContentType": file.type,
        "Key": key
      });

    } catch(error) {
      throw new Meteor.Error(error.message);
    }

    return bucketUrl + key;        // Return the full URL for the client to use
  }

});

Where:

  • YOUR_SUMMERNOTE_DEFAULTS are the usual setup parms for summernote, or {} for defaults,
  • AWS.S3() is the AWS SDK service for S3 (I use the peerlibrary:aws-sdk package for this), and
  • slugify() is your slugification function of choice, to ensure a good/readable URL

Hope this helps someone. It was a major pain in the ass getting this right. ;)

crsssl commented Jul 19, 2017

Here's a workable MeteorJS version for you:

On the client:

var snDefaults = _.extend(YOUR_SUMMERNOTE_DEFAULTS, {
  callbacks: {
    // Upload an image to AWS and replace with an IMG node (with src attr as URL)
    onImageUpload: function(files) {
      var self = this;
      var reader = new FileReader();
      reader.onload = function () {
        var imageFile = _.pick(files[0], 'name', 'type', 'size');   // Convert to EJSON-able object
        var imageData = reader.result;                              // Binary string version
        Meteor.call('saveImageFile', imageFile, imageData, function(err, res) {
          if (!err) {
            $(self).summernote('insertImage', res, slugify(imageFile.name));
          }
        });  
      };
      reader.readAsBinaryString(new Blob([files[0]]));              // 
    }
  }
});

$("#inputNode").summernote(snDefaults);

And on the server:

Meteor.methods({
  saveImageFile: function(file, blob) {
    check(file, Object);    // Recall this is an EJSON object (no blobs allowed!)
    check(blob, String);    // The image blob is passed as a binary string instead

    // SETUP:

    var bucketName        = Meteor.settings.public.bucketName;    // **Replace with yours**
    var bucketUrl         = Meteor.settings.public.bucketUrl;     // **Replace with the full URL**
    var imageStore        = Meteor.settings.public.imageFolder;   // **Replace with yours**

    var allowedImageExtensions = /\.(gif|jpg|jpeg|png)$/;
    var allowedImageTypes      = ["image/gif", "image/jpeg", "image/png"];
    var allowedImageSize       = 5242880;  // 5 MB

    // Simple filename cleanup function
    function cleanName(str) {
      if (str) { return slugify(str.replace(/\.\./g,'')); }
    }

    // CHECK:

    if (! allowedImageExtensions.test(file.name.toLowerCase())) { throw new Meteor.Error('Invalid image file extension.'); return; }
    if (allowedImageTypes.indexOf(file.type.toLowerCase()) < 0) { throw new Meteor.Error('Invalid image file type.'); return; }
    if (allowedImageSize < file.size) { throw new Meteor.Error('Invalid image file size.'); return; }

    // PROCESS:

    var serverFileName = Random.id() + '_' + cleanName(file.name);
    var key = imageStore + "/" + serverFileName;

    try {

      var s3 = new AWS.S3();
      var res = s3.putObjectSync({
        "Bucket": bucketName,
        "ACL": 'public-read',
        "Body": new Buffer(blob, 'binary'),
        "ContentType": file.type,
        "Key": key
      });

    } catch(error) {
      throw new Meteor.Error(error.message);
    }

    return bucketUrl + key;        // Return the full URL for the client to use
  }

});

Where:

  • YOUR_SUMMERNOTE_DEFAULTS are the usual setup parms for summernote, or {} for defaults,
  • AWS.S3() is the AWS SDK service for S3 (I use the peerlibrary:aws-sdk package for this), and
  • slugify() is your slugification function of choice, to ensure a good/readable URL

Hope this helps someone. It was a major pain in the ass getting this right. ;)

@ft0907

This comment has been minimized.

Show comment
Hide comment
@ft0907

ft0907 Aug 29, 2017

Pictures uploaded in the tomcat8.5 JDK1.8 environment, upload pictures can not be displayed, you need to delay the implementation of the background JAVA upload code, 5 seconds to normal display Why does this problem arise? May I ask if you have similar problems?

ft0907 commented Aug 29, 2017

Pictures uploaded in the tomcat8.5 JDK1.8 environment, upload pictures can not be displayed, you need to delay the implementation of the background JAVA upload code, 5 seconds to normal display Why does this problem arise? May I ask if you have similar problems?

@Ontokrat

This comment has been minimized.

Show comment
Hide comment
@Ontokrat

Ontokrat Sep 5, 2017

Contributor

@crsssl & every Meteor user
I manage it also with the FileReader API in a faster and lighter (in code & server charge) way: no Blob needed, no Binary string version

  • To manage the upload to S3, I use the jamiesoncj:slingshot package (fork of mainstream edgee:slingshot but enabling AWS side encryption): no file sent to the server.
  • I rewrite the name of files to avoid slugification issues (but see very easy way by @crsssl above if you want to keep the files' name) and of course I clean HTML elsewhere.

So everything is on client, except slingshot upload directive on server (see).

// inside summernote callbacks
onImageUpload: function(files) {
  var self = this;
  
  // Read & write with FileReader API
  var reader = new FileReader();
  
  reader.onload = function () {
    // Convert to EJSON-able object
    var imageFile = _.pick(files[0], 'name', 'type', 'size');
    // Check image's size (in bytes)
    if (imageFile.size > (1024 * 1024 * 1)) {
      // inform client here
    } 
    // check if file is an image
    else if (!imageFile.type.includes('image')) {
      // inform client here
    } else {
      // get a random filename
      var storagefilename = Random.hexString(18) + ".jpg";
      // create a new file with new name 
      var renamedFile = new File([files[0]], storagefilename, {type: "image/jpeg", lastModified: new Date()});
      // Upload to S3
      var uploader = new Slingshot.Upload("<nameofuploaddirective>", {sse: true, key: <yourKey>});
      uploader.send(renamedFile, function (error, downloadUrl) {
        if (error) {
          // inform client here
        } else {
          // insert image in editor
          $(self).summernote('insertImage', downloadUrl, storagefilename);
        }
      });        
    } 
  };

  reader.readAsArrayBuffer(files[0]);

},

Contributor

Ontokrat commented Sep 5, 2017

@crsssl & every Meteor user
I manage it also with the FileReader API in a faster and lighter (in code & server charge) way: no Blob needed, no Binary string version

  • To manage the upload to S3, I use the jamiesoncj:slingshot package (fork of mainstream edgee:slingshot but enabling AWS side encryption): no file sent to the server.
  • I rewrite the name of files to avoid slugification issues (but see very easy way by @crsssl above if you want to keep the files' name) and of course I clean HTML elsewhere.

So everything is on client, except slingshot upload directive on server (see).

// inside summernote callbacks
onImageUpload: function(files) {
  var self = this;
  
  // Read & write with FileReader API
  var reader = new FileReader();
  
  reader.onload = function () {
    // Convert to EJSON-able object
    var imageFile = _.pick(files[0], 'name', 'type', 'size');
    // Check image's size (in bytes)
    if (imageFile.size > (1024 * 1024 * 1)) {
      // inform client here
    } 
    // check if file is an image
    else if (!imageFile.type.includes('image')) {
      // inform client here
    } else {
      // get a random filename
      var storagefilename = Random.hexString(18) + ".jpg";
      // create a new file with new name 
      var renamedFile = new File([files[0]], storagefilename, {type: "image/jpeg", lastModified: new Date()});
      // Upload to S3
      var uploader = new Slingshot.Upload("<nameofuploaddirective>", {sse: true, key: <yourKey>});
      uploader.send(renamedFile, function (error, downloadUrl) {
        if (error) {
          // inform client here
        } else {
          // insert image in editor
          $(self).summernote('insertImage', downloadUrl, storagefilename);
        }
      });        
    } 
  };

  reader.readAsArrayBuffer(files[0]);

},

@crsssl

This comment has been minimized.

Show comment
Hide comment
@crsssl

crsssl Sep 6, 2017

Nice job @Ontokrat, and thanks for pointing out that package. It'll really help.

crsssl commented Sep 6, 2017

Nice job @Ontokrat, and thanks for pointing out that package. It'll really help.

@rafyong

This comment has been minimized.

Show comment
Hide comment
@rafyong

rafyong Dec 20, 2017

Hi, how to upload image to server instead of base64 using asp.net webform? not the MVC.
I don't know using ajax. what needs to put on URL?

Im writing this javascript inside news_create.aspx. Then I define a function to upload the image in server.
So. how to call the function from this sendFile javascript function?

function sendFile(file,editor,welEditable) {
data = new FormData();
data.append("file", file);
$.ajax({
data: data,
type: "POST",
url: "/ajax/saveimage",
cache: false,
contentType: false,
processData: false,
success: function(url) {
editor.insertImage(welEditable, url);
}
});
}

rafyong commented Dec 20, 2017

Hi, how to upload image to server instead of base64 using asp.net webform? not the MVC.
I don't know using ajax. what needs to put on URL?

Im writing this javascript inside news_create.aspx. Then I define a function to upload the image in server.
So. how to call the function from this sendFile javascript function?

function sendFile(file,editor,welEditable) {
data = new FormData();
data.append("file", file);
$.ajax({
data: data,
type: "POST",
url: "/ajax/saveimage",
cache: false,
contentType: false,
processData: false,
success: function(url) {
editor.insertImage(welEditable, url);
}
});
}

@jonalport

This comment has been minimized.

Show comment
Hide comment
@jonalport

jonalport Feb 12, 2018

I had the same problem as @piaoyizhimei and a few others...

If you are updating the img src in the insertImage callback, you may need to trigger a change event manually after doing so:

$summernote.trigger('summernote.change');

jonalport commented Feb 12, 2018

I had the same problem as @piaoyizhimei and a few others...

If you are updating the img src in the insertImage callback, you may need to trigger a change event manually after doing so:

$summernote.trigger('summernote.change');
@Laeng

This comment has been minimized.

Show comment
Hide comment
@Laeng

Laeng May 28, 2018

if you using laravel 5.5 or higher, Try to using my code!

$('#editor').summernote({
        callbacks: {
            onImageUpload: function(files) {
                for(let i=0; i < files.length; i++) {
                    $.upload('image', files[i]);
                }
            }
        },
        placeholder: 'Image upload test',
        width: 500,
        height: 500,
    });
$.upload = function (file) {
    let out = new FormData();
    out.append('file', file, file.name);

    $.ajax({
        method: 'POST',
        url: '/post/upload',
        //check laravel document: https://laravel.com/docs/5.6/csrf#csrf-x-csrf-token
        headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
        contentType: false,
        cache: false,
        processData: false,
        dataType: 'JSON',
        data: out,
        success: function (r) {
            $('#editor').summernote('insertImage', r.url);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.error(textStatus + " " + errorThrown);
        }
    });
};

Laeng commented May 28, 2018

if you using laravel 5.5 or higher, Try to using my code!

$('#editor').summernote({
        callbacks: {
            onImageUpload: function(files) {
                for(let i=0; i < files.length; i++) {
                    $.upload('image', files[i]);
                }
            }
        },
        placeholder: 'Image upload test',
        width: 500,
        height: 500,
    });
$.upload = function (file) {
    let out = new FormData();
    out.append('file', file, file.name);

    $.ajax({
        method: 'POST',
        url: '/post/upload',
        //check laravel document: https://laravel.com/docs/5.6/csrf#csrf-x-csrf-token
        headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
        contentType: false,
        cache: false,
        processData: false,
        dataType: 'JSON',
        data: out,
        success: function (r) {
            $('#editor').summernote('insertImage', r.url);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.error(textStatus + " " + errorThrown);
        }
    });
};
@heihachi88

This comment has been minimized.

Show comment
Hide comment
@heihachi88

heihachi88 Jun 22, 2018

@Laeng i keep getting error 500, when trying to upload an image through summernote, could you post your php method to handle these DB uploads, please?

I have figured out, you have the error on this line:

$('#editor').summernote('insertImage', r.url);

it should be just "r", why you have used "r.url" - i have no idea.

heihachi88 commented Jun 22, 2018

@Laeng i keep getting error 500, when trying to upload an image through summernote, could you post your php method to handle these DB uploads, please?

I have figured out, you have the error on this line:

$('#editor').summernote('insertImage', r.url);

it should be just "r", why you have used "r.url" - i have no idea.

@Laeng

This comment has been minimized.

Show comment
Hide comment
@Laeng

Laeng Jun 23, 2018

@heihachi88
letter 'r' is mean returned json value from server! so, 'r' mean return.

I using 'Xpresss Engine 3' and it's based laravel 5.5.
Some methods is not support at pure laravel 5.5 and other CMS.

public function upload(Request $request)
    {
        $r = (object)[]; //it's will return values.

        if (($uploadedFile = $request->file('file')) === null) {
            $r->error = "Upload Fail: File is empty.";
            return json_encode($r);
        }

        if ($uploadedFile->getSize() > 10 * pow(1024, 2)) {
            $r->error = "Upload Fail: File is exceed 10 MB.";
            return json_encode($r);
        }

        $extensions = array(
            'png', 'jpg', 'jpeg', 'jpe', 'svg', 'bmp', 'tif', 'tiff', 'ico',
            'asf', 'asx', 'wmv', 'wmx', 'wm', 'avi', 'divx', 'flv', 'mov', 'qt', 'mpeg', 'mpg', 'mpe', 'mp4', 'm4v', 'ogv', 'webm', 'mkv',
            'mp3', 'm4a', 'm4b', 'ogg', 'oga', 'mid', 'midi', 'wma', 'wmx', 'mka',
            'txt', 'pdf', 'zip', 'gz', 'gzip', 'rar', '7z', 'hwp',
            'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx',
            'obt', 'odp', 'ods', 'odg', 'odc', 'odb', 'odf',
            'key', 'numbers', 'pages'
        );

        if (!in_array(strtolower($uploadedFile->getClientOriginalExtension()), $extensions)) {
            $r->error = "Upload Fail: Unacceptable extension.";
            return json_encode($r);
        }


        /**
           * Save File
         **/

        $file = XeStorage::upload($uploadedFile, 'public/editor');
        $r->url = sprintf("/storage/app/%s/%s", $file->path, $file->filename); 

        return json_encode($r);
    }

Laeng commented Jun 23, 2018

@heihachi88
letter 'r' is mean returned json value from server! so, 'r' mean return.

I using 'Xpresss Engine 3' and it's based laravel 5.5.
Some methods is not support at pure laravel 5.5 and other CMS.

public function upload(Request $request)
    {
        $r = (object)[]; //it's will return values.

        if (($uploadedFile = $request->file('file')) === null) {
            $r->error = "Upload Fail: File is empty.";
            return json_encode($r);
        }

        if ($uploadedFile->getSize() > 10 * pow(1024, 2)) {
            $r->error = "Upload Fail: File is exceed 10 MB.";
            return json_encode($r);
        }

        $extensions = array(
            'png', 'jpg', 'jpeg', 'jpe', 'svg', 'bmp', 'tif', 'tiff', 'ico',
            'asf', 'asx', 'wmv', 'wmx', 'wm', 'avi', 'divx', 'flv', 'mov', 'qt', 'mpeg', 'mpg', 'mpe', 'mp4', 'm4v', 'ogv', 'webm', 'mkv',
            'mp3', 'm4a', 'm4b', 'ogg', 'oga', 'mid', 'midi', 'wma', 'wmx', 'mka',
            'txt', 'pdf', 'zip', 'gz', 'gzip', 'rar', '7z', 'hwp',
            'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx',
            'obt', 'odp', 'ods', 'odg', 'odc', 'odb', 'odf',
            'key', 'numbers', 'pages'
        );

        if (!in_array(strtolower($uploadedFile->getClientOriginalExtension()), $extensions)) {
            $r->error = "Upload Fail: Unacceptable extension.";
            return json_encode($r);
        }


        /**
           * Save File
         **/

        $file = XeStorage::upload($uploadedFile, 'public/editor');
        $r->url = sprintf("/storage/app/%s/%s", $file->path, $file->filename); 

        return json_encode($r);
    }
@heihachi88

This comment has been minimized.

Show comment
Hide comment
@heihachi88

heihachi88 Jun 23, 2018

@Laeng

Can't i get ajax data with the following method:

$file = $request->input('file');

It returns me nothing.

heihachi88 commented Jun 23, 2018

@Laeng

Can't i get ajax data with the following method:

$file = $request->input('file');

It returns me nothing.

@Laeng

This comment has been minimized.

Show comment
Hide comment
@Laeng

Laeng Jun 23, 2018

@heihachi88

ajax post to server with query 'file' and server is most receive 'file'.

larave 5.5 is not used at file upload to $requset->input('file');
Could you change as shown below?

$request->file('file');

Laeng commented Jun 23, 2018

@heihachi88

ajax post to server with query 'file' and server is most receive 'file'.

larave 5.5 is not used at file upload to $requset->input('file');
Could you change as shown below?

$request->file('file');
@heihachi88

This comment has been minimized.

Show comment
Hide comment
@heihachi88

heihachi88 Jun 23, 2018

@Laeng

I am using Laravel 5.6, but seems like ajax post not actually posting data to my controller.

$file = $request->file('file');
return response()->json($file->getRealPath());

Still returns nothing:

"message": "Call to a member function getRealPath() on null"

heihachi88 commented Jun 23, 2018

@Laeng

I am using Laravel 5.6, but seems like ajax post not actually posting data to my controller.

$file = $request->file('file');
return response()->json($file->getRealPath());

Still returns nothing:

"message": "Call to a member function getRealPath() on null"

@Laeng

This comment has been minimized.

Show comment
Hide comment
@Laeng

Laeng Jun 23, 2018

let's check debug!
using method dd();

dd($requset->file('file'));

Please put it before 'return'.

if image is successful upload,

Laeng commented Jun 23, 2018

let's check debug!
using method dd();

dd($requset->file('file'));

Please put it before 'return'.

if image is successful upload,

@heihachi88

This comment has been minimized.

Show comment
Hide comment
@heihachi88

heihachi88 Jun 23, 2018

Why you wrapped dd() with quotes?

heihachi88 commented Jun 23, 2018

Why you wrapped dd() with quotes?

@Laeng

This comment has been minimized.

Show comment
Hide comment
@Laeng

Laeng Jun 23, 2018

@heihachi88 it's my mistake.... haha!
Don't wrap the quotes!

Laeng commented Jun 23, 2018

@heihachi88 it's my mistake.... haha!
Don't wrap the quotes!

@heihachi88

This comment has been minimized.

Show comment
Hide comment
@heihachi88

heihachi88 Jun 23, 2018

Here's response i get with dd():

<script> Sfdump = window.Sfdump || (function (doc) { var refStyle = doc.createElement('style'), rxEsc = /([.*+?^${}()|\[\]\/\\])/g, idRx = /\bsf-dump-\d+-ref[012]\w+\b/, keyHint = 0 <= navigator.platform.toUpperCase().indexOf('MAC') ? 'Cmd' : 'Ctrl', addEventListener = function (e, n, cb) { e.addEventListener(n, cb, false); }; (doc.documentElement.firstElementChild || doc.documentElement.children[0]).appendChild(refStyle); if (!doc.addEventListener) { addEventListener = function (element, eventName, callback) { element.attachEvent('on' + eventName, function (e) { e.preventDefault = function () {e.returnValue = false;}; e.target = e.srcElement; callback(e); }); }; } function toggle(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass; if (/\bsf-dump-compact\b/.test(oldClass)) { arrow = '&#9660;'; newClass = 'sf-dump-expanded'; } else if (/\bsf-dump-expanded\b/.test(oldClass)) { arrow = '&#9654;'; newClass = 'sf-dump-compact'; } else { return false; } if (doc.createEvent && s.dispatchEvent) { var event = doc.createEvent('Event'); event.initEvent('sf-dump-expanded' === newClass ? 'sfbeforedumpexpand' : 'sfbeforedumpcollapse', true, false); s.dispatchEvent(event); } a.lastChild.innerHTML = arrow; s.className = s.className.replace(/\bsf-dump-(compact|expanded)\b/, newClass); if (recursive) { try { a = s.querySelectorAll('.'+oldClass); for (s = 0; s < a.length; ++s) { if (-1 == a[s].className.indexOf(newClass)) { a[s].className = newClass; a[s].previousSibling.lastChild.innerHTML = arrow; } } } catch (e) { } } return true; }; function collapse(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; if (/\bsf-dump-expanded\b/.test(oldClass)) { toggle(a, recursive); return true; } return false; }; function expand(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; if (/\bsf-dump-compact\b/.test(oldClass)) { toggle(a, recursive); return true; } return false; }; function collapseAll(root) { var a = root.querySelector('a.sf-dump-toggle'); if (a) { collapse(a, true); expand(a); return true; } return false; } function reveal(node) { var previous, parents = []; while ((node = node.parentNode || {}) && (previous = node.previousSibling) && 'A' === previous.tagName) { parents.push(previous); } if (0 !== parents.length) { parents.forEach(function (parent) { expand(parent); }); return true; } return false; } function highlight(root, activeNode, nodes) { resetHighlightedNodes(root); Array.from(nodes||[]).forEach(function (node) { if (!/\bsf-dump-highlight\b/.test(node.className)) { node.className = node.className + ' sf-dump-highlight'; } }); if (!/\bsf-dump-highlight-active\b/.test(activeNode.className)) { activeNode.className = activeNode.className + ' sf-dump-highlight-active'; } } function resetHighlightedNodes(root) { Array.from(root.querySelectorAll('.sf-dump-str, .sf-dump-key, .sf-dump-public, .sf-dump-protected, .sf-dump-private')).forEach(function (strNode) { strNode.className = strNode.className.replace(/\bsf-dump-highlight\b/, ''); strNode.className = strNode.className.replace(/\bsf-dump-highlight-active\b/, ''); }); } return function (root, x) { root = doc.getElementById(root); var indentRx = new RegExp('^('+(root.getAttribute('data-indent-pad') || ' ').replace(rxEsc, '\\$1')+')+', 'm'), options = {"maxDepth":1,"maxStringLength":160,"fileLinkFormat":false}, elt = root.getElementsByTagName('A'), len = elt.length, i = 0, s, h, t = []; while (i < len) t.push(elt[i++]); for (i in x) { options[i] = x[i]; } function a(e, f) { addEventListener(root, e, function (e) { if ('A' == e.target.tagName) { f(e.target, e); } else if ('A' == e.target.parentNode.tagName) { f(e.target.parentNode, e); } else if (e.target.nextElementSibling && 'A' == e.target.nextElementSibling.tagName) { f(e.target.nextElementSibling, e, true); } }); }; function isCtrlKey(e) { return e.ctrlKey || e.metaKey; } function xpathString(str) { var parts = str.match(/[^'"]+|['"]/g).map(function (part) { if ("'" == part) { return '"\'"'; } if ('"' == part) { return "'\"'"; } return "'" + part + "'"; }); return "concat(" + parts.join(",") + ", '')"; } function xpathHasClass(className) { return "contains(concat(' ', normalize-space(@class), ' '), ' " + className +" ')"; } addEventListener(root, 'mouseover', function (e) { if ('' != refStyle.innerHTML) { refStyle.innerHTML = ''; } }); a('mouseover', function (a, e, c) { if (c) { e.target.style.cursor = "pointer"; } else if (a = idRx.exec(a.className)) { try { refStyle.innerHTML = 'pre.sf-dump .'+a[0]+'{background-color: #B729D9; color: #FFF !important; border-radius: 2px}'; } catch (e) { } } }); a('click', function (a, e, c) { if (/\bsf-dump-toggle\b/.test(a.className)) { e.preventDefault(); if (!toggle(a, isCtrlKey(e))) { var r = doc.getElementById(a.getAttribute('href').substr(1)), s = r.previousSibling, f = r.parentNode, t = a.parentNode; t.replaceChild(r, a); f.replaceChild(a, s); t.insertBefore(s, r); f = f.firstChild.nodeValue.match(indentRx); t = t.firstChild.nodeValue.match(indentRx); if (f && t && f[0] !== t[0]) { r.innerHTML = r.innerHTML.replace(new RegExp('^'+f[0].replace(rxEsc, '\\$1'), 'mg'), t[0]); } if (/\bsf-dump-compact\b/.test(r.className)) { toggle(s, isCtrlKey(e)); } } if (c) { } else if (doc.getSelection) { try { doc.getSelection().removeAllRanges(); } catch (e) { doc.getSelection().empty(); } } else { doc.selection.empty(); } } else if (/\bsf-dump-str-toggle\b/.test(a.className)) { e.preventDefault(); e = a.parentNode.parentNode; e.className = e.className.replace(/\bsf-dump-str-(expand|collapse)\b/, a.parentNode.className); } }); elt = root.getElementsByTagName('SAMP'); len = elt.length; i = 0; while (i < len) t.push(elt[i++]); len = t.length; for (i = 0; i < len; ++i) { elt = t[i]; if ('SAMP' == elt.tagName) { a = elt.previousSibling || {}; if ('A' != a.tagName) { a = doc.createElement('A'); a.className = 'sf-dump-ref'; elt.parentNode.insertBefore(a, elt); } else { a.innerHTML += ' '; } a.title = (a.title ? a.title+'\n[' : '[')+keyHint+'+click] Expand all children'; a.innerHTML += '<span>&#9660;</span>'; a.className += ' sf-dump-toggle'; x = 1; if ('sf-dump' != elt.parentNode.className) { x += elt.parentNode.getAttribute('data-depth')/1; } elt.setAttribute('data-depth', x); var className = elt.className; elt.className = 'sf-dump-expanded'; if (className ? 'sf-dump-expanded' !== className : (x > options.maxDepth)) { toggle(a); } } else if (/\bsf-dump-ref\b/.test(elt.className) && (a = elt.getAttribute('href'))) { a = a.substr(1); elt.className += ' '+a; if (/[\[{]$/.test(elt.previousSibling.nodeValue)) { a = a != elt.nextSibling.id && doc.getElementById(a); try { s = a.nextSibling; elt.appendChild(a); s.parentNode.insertBefore(a, s); if (/^[@#]/.test(elt.innerHTML)) { elt.innerHTML += ' <span>&#9654;</span>'; } else { elt.innerHTML = '<span>&#9654;</span>'; elt.className = 'sf-dump-ref'; } elt.className += ' sf-dump-toggle'; } catch (e) { if ('&' == elt.innerHTML.charAt(0)) { elt.innerHTML = '&hellip;'; elt.className = 'sf-dump-ref'; } } } } } if (doc.evaluate && Array.from && root.children.length > 1) { root.setAttribute('tabindex', 0); SearchState = function () { this.nodes = []; this.idx = 0; }; SearchState.prototype = { next: function () { if (this.isEmpty()) { return this.current(); } this.idx = this.idx < (this.nodes.length - 1) ? this.idx + 1 : 0; return this.current(); }, previous: function () { if (this.isEmpty()) { return this.current(); } this.idx = this.idx > 0 ? this.idx - 1 : (this.nodes.length - 1); return this.current(); }, isEmpty: function () { return 0 === this.count(); }, current: function () { if (this.isEmpty()) { return null; } return this.nodes[this.idx]; }, reset: function () { this.nodes = []; this.idx = 0; }, count: function () { return this.nodes.length; }, }; function showCurrent(state) { var currentNode = state.current(); if (currentNode) { reveal(currentNode); highlight(root, currentNode, state.nodes); } counter.textContent = (state.isEmpty() ? 0 : state.idx + 1) + ' of ' + state.count(); } var search = doc.createElement('div'); search.className = 'sf-dump-search-wrapper sf-dump-search-hidden'; search.innerHTML = ' <input type="text" class="sf-dump-search-input"> <span class="sf-dump-search-count">0 of 0<\/span> <button type="button" class="sf-dump-search-input-previous" tabindex="-1"> <svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> <path d="M1683 1331l-166 165q-19 19-45 19t-45-19l-531-531-531 531q-19 19-45 19t-45-19l-166-165q-19-19-19-45.5t19-45.5l742-741q19-19 45-19t45 19l742 741q19 19 19 45.5t-19 45.5z"\/> <\/svg> <\/button> <button type="button" class="sf-dump-search-input-next" tabindex="-1"> <svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> <path d="M1683 808l-742 741q-19 19-45 19t-45-19l-742-741q-19-19-19-45.5t19-45.5l166-165q19-19 45-19t45 19l531 531 531-531q19-19 45-19t45 19l166 165q19 19 19 45.5t-19 45.5z"\/> <\/svg> <\/button> '; root.insertBefore(search, root.firstChild); var state = new SearchState(); var searchInput = search.querySelector('.sf-dump-search-input'); var counter = search.querySelector('.sf-dump-search-count'); var searchInputTimer = 0; var previousSearchQuery = ''; addEventListener(searchInput, 'keyup', function (e) { var searchQuery = e.target.value; /* Don't perform anything if the pressed key didn't change the query */ if (searchQuery === previousSearchQuery) { return; } previousSearchQuery = searchQuery; clearTimeout(searchInputTimer); searchInputTimer = setTimeout(function () { state.reset(); collapseAll(root); resetHighlightedNodes(root); if ('' === searchQuery) { counter.textContent = '0 of 0'; return; } var classMatches = [ "sf-dump-str", "sf-dump-key", "sf-dump-public", "sf-dump-protected", "sf-dump-private", ].map(xpathHasClass).join(' or '); var xpathResult = doc.evaluate('.//span[' + classMatches + '][contains(translate(child::text(), ' + xpathString(searchQuery.toUpperCase()) + ', ' + xpathString(searchQuery.toLowerCase()) + '), ' + xpathString(searchQuery.toLowerCase()) + ')]', root, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); while (node = xpathResult.iterateNext()) state.nodes.push(node); showCurrent(state); }, 400); }); Array.from(search.querySelectorAll('.sf-dump-search-input-next, .sf-dump-search-input-previous')).forEach(function (btn) { addEventListener(btn, 'click', function (e) { e.preventDefault(); -1 !== e.target.className.indexOf('next') ? state.next() : state.previous(); searchInput.focus(); collapseAll(root); showCurrent(state); }) }); addEventListener(root, 'keydown', function (e) { var isSearchActive = !/\bsf-dump-search-hidden\b/.test(search.className); if ((114 === e.keyCode && !isSearchActive) || (isCtrlKey(e) && 70 === e.keyCode)) { /* F3 or CMD/CTRL + F */ e.preventDefault(); search.className = search.className.replace(/\bsf-dump-search-hidden\b/, ''); searchInput.focus(); } else if (isSearchActive) { if (27 === e.keyCode) { /* ESC key */ search.className += ' sf-dump-search-hidden'; e.preventDefault(); resetHighlightedNodes(root); searchInput.value = ''; } else if ( (isCtrlKey(e) && 71 === e.keyCode) /* CMD/CTRL + G */ || 13 === e.keyCode /* Enter */ || 114 === e.keyCode /* F3 */ ) { e.preventDefault(); e.shiftKey ? state.previous() : state.next(); collapseAll(root); showCurrent(state); } } }); } if (0 >= options.maxStringLength) { return; } try { elt = root.querySelectorAll('.sf-dump-str'); len = elt.length; i = 0; t = []; while (i < len) t.push(elt[i++]); len = t.length; for (i = 0; i < len; ++i) { elt = t[i]; s = elt.innerText || elt.textContent; x = s.length - options.maxStringLength; if (0 < x) { h = elt.innerHTML; elt[elt.innerText ? 'innerText' : 'textContent'] = s.substring(0, options.maxStringLength); elt.className += ' sf-dump-str-collapse'; elt.innerHTML = '<span class=sf-dump-str-collapse>'+h+'<a class="sf-dump-ref sf-dump-str-toggle" title="Collapse"> &#9664;</a></span>'+ '<span class=sf-dump-str-expand>'+elt.innerHTML+'<a class="sf-dump-ref sf-dump-str-toggle" title="'+x+' remaining characters"> &#9654;</a></span>'; } } } catch (e) { } }; })(document); </script><style> pre.sf-dump { display: block; white-space: pre; padding: 5px; } pre.sf-dump:after { content: ""; visibility: hidden; display: block; height: 0; clear: both; } pre.sf-dump span { display: inline; } pre.sf-dump .sf-dump-compact { display: none; } pre.sf-dump abbr { text-decoration: none; border: none; cursor: help; } pre.sf-dump a { text-decoration: none; cursor: pointer; border: 0; outline: none; color: inherit; } pre.sf-dump .sf-dump-ellipsis { display: inline-block; overflow: visible; text-overflow: ellipsis; max-width: 5em; white-space: nowrap; overflow: hidden; vertical-align: top; } pre.sf-dump .sf-dump-ellipsis+.sf-dump-ellipsis { max-width: none; } pre.sf-dump code { display:inline; padding:0; background:none; } .sf-dump-str-collapse .sf-dump-str-collapse { display: none; } .sf-dump-str-expand .sf-dump-str-expand { display: none; } .sf-dump-public.sf-dump-highlight, .sf-dump-protected.sf-dump-highlight, .sf-dump-private.sf-dump-highlight, .sf-dump-str.sf-dump-highlight, .sf-dump-key.sf-dump-highlight { background: rgba(111, 172, 204, 0.3); border: 1px solid #7DA0B1; border-radius: 3px; } .sf-dump-public.sf-dump-highlight-active, .sf-dump-protected.sf-dump-highlight-active, .sf-dump-private.sf-dump-highlight-active, .sf-dump-str.sf-dump-highlight-active, .sf-dump-key.sf-dump-highlight-active { background: rgba(253, 175, 0, 0.4); border: 1px solid #ffa500; border-radius: 3px; } pre.sf-dump .sf-dump-search-hidden { display: none; } pre.sf-dump .sf-dump-search-wrapper { float: right; font-size: 0; white-space: nowrap; max-width: 100%; text-align: right; } pre.sf-dump .sf-dump-search-wrapper > * { vertical-align: top; box-sizing: border-box; height: 21px; font-weight: normal; border-radius: 0; background: #FFF; color: #757575; border: 1px solid #BBB; } pre.sf-dump .sf-dump-search-wrapper > input.sf-dump-search-input { padding: 3px; height: 21px; font-size: 12px; border-right: none; width: 140px; border-top-left-radius: 3px; border-bottom-left-radius: 3px; color: #000; } pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next, pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-previous { background: #F2F2F2; outline: none; border-left: none; font-size: 0; line-height: 0; } pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next { border-top-right-radius: 3px; border-bottom-right-radius: 3px; } pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next > svg, pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-previous > svg { pointer-events: none; width: 12px; height: 12px; } pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-count { display: inline-block; padding: 0 5px; margin: 0; border-left: none; line-height: 21px; font-size: 12px; }pre.sf-dump, pre.sf-dump .sf-dump-default{background-color:#18171B; color:#FF8400; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: break-all}pre.sf-dump .sf-dump-num{font-weight:bold; color:#1299DA}pre.sf-dump .sf-dump-const{font-weight:bold}pre.sf-dump .sf-dump-str{font-weight:bold; color:#56DB3A}pre.sf-dump .sf-dump-note{color:#1299DA}pre.sf-dump .sf-dump-ref{color:#A0A0A0}pre.sf-dump .sf-dump-public{color:#FFFFFF}pre.sf-dump .sf-dump-protected{color:#FFFFFF}pre.sf-dump .sf-dump-private{color:#FFFFFF}pre.sf-dump .sf-dump-meta{color:#B729D9}pre.sf-dump .sf-dump-key{color:#56DB3A}pre.sf-dump .sf-dump-index{color:#1299DA}pre.sf-dump .sf-dump-ellipsis{color:#FF8400}</style><pre class=sf-dump id=sf-dump-2122892111 data-indent-pad="  "><span class=sf-dump-const>null</span>
</pre><script>Sfdump("sf-dump-2122892111")</script>

Something wrong with the ajax post.

heihachi88 commented Jun 23, 2018

Here's response i get with dd():

<script> Sfdump = window.Sfdump || (function (doc) { var refStyle = doc.createElement('style'), rxEsc = /([.*+?^${}()|\[\]\/\\])/g, idRx = /\bsf-dump-\d+-ref[012]\w+\b/, keyHint = 0 <= navigator.platform.toUpperCase().indexOf('MAC') ? 'Cmd' : 'Ctrl', addEventListener = function (e, n, cb) { e.addEventListener(n, cb, false); }; (doc.documentElement.firstElementChild || doc.documentElement.children[0]).appendChild(refStyle); if (!doc.addEventListener) { addEventListener = function (element, eventName, callback) { element.attachEvent('on' + eventName, function (e) { e.preventDefault = function () {e.returnValue = false;}; e.target = e.srcElement; callback(e); }); }; } function toggle(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass; if (/\bsf-dump-compact\b/.test(oldClass)) { arrow = '&#9660;'; newClass = 'sf-dump-expanded'; } else if (/\bsf-dump-expanded\b/.test(oldClass)) { arrow = '&#9654;'; newClass = 'sf-dump-compact'; } else { return false; } if (doc.createEvent && s.dispatchEvent) { var event = doc.createEvent('Event'); event.initEvent('sf-dump-expanded' === newClass ? 'sfbeforedumpexpand' : 'sfbeforedumpcollapse', true, false); s.dispatchEvent(event); } a.lastChild.innerHTML = arrow; s.className = s.className.replace(/\bsf-dump-(compact|expanded)\b/, newClass); if (recursive) { try { a = s.querySelectorAll('.'+oldClass); for (s = 0; s < a.length; ++s) { if (-1 == a[s].className.indexOf(newClass)) { a[s].className = newClass; a[s].previousSibling.lastChild.innerHTML = arrow; } } } catch (e) { } } return true; }; function collapse(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; if (/\bsf-dump-expanded\b/.test(oldClass)) { toggle(a, recursive); return true; } return false; }; function expand(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; if (/\bsf-dump-compact\b/.test(oldClass)) { toggle(a, recursive); return true; } return false; }; function collapseAll(root) { var a = root.querySelector('a.sf-dump-toggle'); if (a) { collapse(a, true); expand(a); return true; } return false; } function reveal(node) { var previous, parents = []; while ((node = node.parentNode || {}) && (previous = node.previousSibling) && 'A' === previous.tagName) { parents.push(previous); } if (0 !== parents.length) { parents.forEach(function (parent) { expand(parent); }); return true; } return false; } function highlight(root, activeNode, nodes) { resetHighlightedNodes(root); Array.from(nodes||[]).forEach(function (node) { if (!/\bsf-dump-highlight\b/.test(node.className)) { node.className = node.className + ' sf-dump-highlight'; } }); if (!/\bsf-dump-highlight-active\b/.test(activeNode.className)) { activeNode.className = activeNode.className + ' sf-dump-highlight-active'; } } function resetHighlightedNodes(root) { Array.from(root.querySelectorAll('.sf-dump-str, .sf-dump-key, .sf-dump-public, .sf-dump-protected, .sf-dump-private')).forEach(function (strNode) { strNode.className = strNode.className.replace(/\bsf-dump-highlight\b/, ''); strNode.className = strNode.className.replace(/\bsf-dump-highlight-active\b/, ''); }); } return function (root, x) { root = doc.getElementById(root); var indentRx = new RegExp('^('+(root.getAttribute('data-indent-pad') || ' ').replace(rxEsc, '\\$1')+')+', 'm'), options = {"maxDepth":1,"maxStringLength":160,"fileLinkFormat":false}, elt = root.getElementsByTagName('A'), len = elt.length, i = 0, s, h, t = []; while (i < len) t.push(elt[i++]); for (i in x) { options[i] = x[i]; } function a(e, f) { addEventListener(root, e, function (e) { if ('A' == e.target.tagName) { f(e.target, e); } else if ('A' == e.target.parentNode.tagName) { f(e.target.parentNode, e); } else if (e.target.nextElementSibling && 'A' == e.target.nextElementSibling.tagName) { f(e.target.nextElementSibling, e, true); } }); }; function isCtrlKey(e) { return e.ctrlKey || e.metaKey; } function xpathString(str) { var parts = str.match(/[^'"]+|['"]/g).map(function (part) { if ("'" == part) { return '"\'"'; } if ('"' == part) { return "'\"'"; } return "'" + part + "'"; }); return "concat(" + parts.join(",") + ", '')"; } function xpathHasClass(className) { return "contains(concat(' ', normalize-space(@class), ' '), ' " + className +" ')"; } addEventListener(root, 'mouseover', function (e) { if ('' != refStyle.innerHTML) { refStyle.innerHTML = ''; } }); a('mouseover', function (a, e, c) { if (c) { e.target.style.cursor = "pointer"; } else if (a = idRx.exec(a.className)) { try { refStyle.innerHTML = 'pre.sf-dump .'+a[0]+'{background-color: #B729D9; color: #FFF !important; border-radius: 2px}'; } catch (e) { } } }); a('click', function (a, e, c) { if (/\bsf-dump-toggle\b/.test(a.className)) { e.preventDefault(); if (!toggle(a, isCtrlKey(e))) { var r = doc.getElementById(a.getAttribute('href').substr(1)), s = r.previousSibling, f = r.parentNode, t = a.parentNode; t.replaceChild(r, a); f.replaceChild(a, s); t.insertBefore(s, r); f = f.firstChild.nodeValue.match(indentRx); t = t.firstChild.nodeValue.match(indentRx); if (f && t && f[0] !== t[0]) { r.innerHTML = r.innerHTML.replace(new RegExp('^'+f[0].replace(rxEsc, '\\$1'), 'mg'), t[0]); } if (/\bsf-dump-compact\b/.test(r.className)) { toggle(s, isCtrlKey(e)); } } if (c) { } else if (doc.getSelection) { try { doc.getSelection().removeAllRanges(); } catch (e) { doc.getSelection().empty(); } } else { doc.selection.empty(); } } else if (/\bsf-dump-str-toggle\b/.test(a.className)) { e.preventDefault(); e = a.parentNode.parentNode; e.className = e.className.replace(/\bsf-dump-str-(expand|collapse)\b/, a.parentNode.className); } }); elt = root.getElementsByTagName('SAMP'); len = elt.length; i = 0; while (i < len) t.push(elt[i++]); len = t.length; for (i = 0; i < len; ++i) { elt = t[i]; if ('SAMP' == elt.tagName) { a = elt.previousSibling || {}; if ('A' != a.tagName) { a = doc.createElement('A'); a.className = 'sf-dump-ref'; elt.parentNode.insertBefore(a, elt); } else { a.innerHTML += ' '; } a.title = (a.title ? a.title+'\n[' : '[')+keyHint+'+click] Expand all children'; a.innerHTML += '<span>&#9660;</span>'; a.className += ' sf-dump-toggle'; x = 1; if ('sf-dump' != elt.parentNode.className) { x += elt.parentNode.getAttribute('data-depth')/1; } elt.setAttribute('data-depth', x); var className = elt.className; elt.className = 'sf-dump-expanded'; if (className ? 'sf-dump-expanded' !== className : (x > options.maxDepth)) { toggle(a); } } else if (/\bsf-dump-ref\b/.test(elt.className) && (a = elt.getAttribute('href'))) { a = a.substr(1); elt.className += ' '+a; if (/[\[{]$/.test(elt.previousSibling.nodeValue)) { a = a != elt.nextSibling.id && doc.getElementById(a); try { s = a.nextSibling; elt.appendChild(a); s.parentNode.insertBefore(a, s); if (/^[@#]/.test(elt.innerHTML)) { elt.innerHTML += ' <span>&#9654;</span>'; } else { elt.innerHTML = '<span>&#9654;</span>'; elt.className = 'sf-dump-ref'; } elt.className += ' sf-dump-toggle'; } catch (e) { if ('&' == elt.innerHTML.charAt(0)) { elt.innerHTML = '&hellip;'; elt.className = 'sf-dump-ref'; } } } } } if (doc.evaluate && Array.from && root.children.length > 1) { root.setAttribute('tabindex', 0); SearchState = function () { this.nodes = []; this.idx = 0; }; SearchState.prototype = { next: function () { if (this.isEmpty()) { return this.current(); } this.idx = this.idx < (this.nodes.length - 1) ? this.idx + 1 : 0; return this.current(); }, previous: function () { if (this.isEmpty()) { return this.current(); } this.idx = this.idx > 0 ? this.idx - 1 : (this.nodes.length - 1); return this.current(); }, isEmpty: function () { return 0 === this.count(); }, current: function () { if (this.isEmpty()) { return null; } return this.nodes[this.idx]; }, reset: function () { this.nodes = []; this.idx = 0; }, count: function () { return this.nodes.length; }, }; function showCurrent(state) { var currentNode = state.current(); if (currentNode) { reveal(currentNode); highlight(root, currentNode, state.nodes); } counter.textContent = (state.isEmpty() ? 0 : state.idx + 1) + ' of ' + state.count(); } var search = doc.createElement('div'); search.className = 'sf-dump-search-wrapper sf-dump-search-hidden'; search.innerHTML = ' <input type="text" class="sf-dump-search-input"> <span class="sf-dump-search-count">0 of 0<\/span> <button type="button" class="sf-dump-search-input-previous" tabindex="-1"> <svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> <path d="M1683 1331l-166 165q-19 19-45 19t-45-19l-531-531-531 531q-19 19-45 19t-45-19l-166-165q-19-19-19-45.5t19-45.5l742-741q19-19 45-19t45 19l742 741q19 19 19 45.5t-19 45.5z"\/> <\/svg> <\/button> <button type="button" class="sf-dump-search-input-next" tabindex="-1"> <svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> <path d="M1683 808l-742 741q-19 19-45 19t-45-19l-742-741q-19-19-19-45.5t19-45.5l166-165q19-19 45-19t45 19l531 531 531-531q19-19 45-19t45 19l166 165q19 19 19 45.5t-19 45.5z"\/> <\/svg> <\/button> '; root.insertBefore(search, root.firstChild); var state = new SearchState(); var searchInput = search.querySelector('.sf-dump-search-input'); var counter = search.querySelector('.sf-dump-search-count'); var searchInputTimer = 0; var previousSearchQuery = ''; addEventListener(searchInput, 'keyup', function (e) { var searchQuery = e.target.value; /* Don't perform anything if the pressed key didn't change the query */ if (searchQuery === previousSearchQuery) { return; } previousSearchQuery = searchQuery; clearTimeout(searchInputTimer); searchInputTimer = setTimeout(function () { state.reset(); collapseAll(root); resetHighlightedNodes(root); if ('' === searchQuery) { counter.textContent = '0 of 0'; return; } var classMatches = [ "sf-dump-str", "sf-dump-key", "sf-dump-public", "sf-dump-protected", "sf-dump-private", ].map(xpathHasClass).join(' or '); var xpathResult = doc.evaluate('.//span[' + classMatches + '][contains(translate(child::text(), ' + xpathString(searchQuery.toUpperCase()) + ', ' + xpathString(searchQuery.toLowerCase()) + '), ' + xpathString(searchQuery.toLowerCase()) + ')]', root, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); while (node = xpathResult.iterateNext()) state.nodes.push(node); showCurrent(state); }, 400); }); Array.from(search.querySelectorAll('.sf-dump-search-input-next, .sf-dump-search-input-previous')).forEach(function (btn) { addEventListener(btn, 'click', function (e) { e.preventDefault(); -1 !== e.target.className.indexOf('next') ? state.next() : state.previous(); searchInput.focus(); collapseAll(root); showCurrent(state); }) }); addEventListener(root, 'keydown', function (e) { var isSearchActive = !/\bsf-dump-search-hidden\b/.test(search.className); if ((114 === e.keyCode && !isSearchActive) || (isCtrlKey(e) && 70 === e.keyCode)) { /* F3 or CMD/CTRL + F */ e.preventDefault(); search.className = search.className.replace(/\bsf-dump-search-hidden\b/, ''); searchInput.focus(); } else if (isSearchActive) { if (27 === e.keyCode) { /* ESC key */ search.className += ' sf-dump-search-hidden'; e.preventDefault(); resetHighlightedNodes(root); searchInput.value = ''; } else if ( (isCtrlKey(e) && 71 === e.keyCode) /* CMD/CTRL + G */ || 13 === e.keyCode /* Enter */ || 114 === e.keyCode /* F3 */ ) { e.preventDefault(); e.shiftKey ? state.previous() : state.next(); collapseAll(root); showCurrent(state); } } }); } if (0 >= options.maxStringLength) { return; } try { elt = root.querySelectorAll('.sf-dump-str'); len = elt.length; i = 0; t = []; while (i < len) t.push(elt[i++]); len = t.length; for (i = 0; i < len; ++i) { elt = t[i]; s = elt.innerText || elt.textContent; x = s.length - options.maxStringLength; if (0 < x) { h = elt.innerHTML; elt[elt.innerText ? 'innerText' : 'textContent'] = s.substring(0, options.maxStringLength); elt.className += ' sf-dump-str-collapse'; elt.innerHTML = '<span class=sf-dump-str-collapse>'+h+'<a class="sf-dump-ref sf-dump-str-toggle" title="Collapse"> &#9664;</a></span>'+ '<span class=sf-dump-str-expand>'+elt.innerHTML+'<a class="sf-dump-ref sf-dump-str-toggle" title="'+x+' remaining characters"> &#9654;</a></span>'; } } } catch (e) { } }; })(document); </script><style> pre.sf-dump { display: block; white-space: pre; padding: 5px; } pre.sf-dump:after { content: ""; visibility: hidden; display: block; height: 0; clear: both; } pre.sf-dump span { display: inline; } pre.sf-dump .sf-dump-compact { display: none; } pre.sf-dump abbr { text-decoration: none; border: none; cursor: help; } pre.sf-dump a { text-decoration: none; cursor: pointer; border: 0; outline: none; color: inherit; } pre.sf-dump .sf-dump-ellipsis { display: inline-block; overflow: visible; text-overflow: ellipsis; max-width: 5em; white-space: nowrap; overflow: hidden; vertical-align: top; } pre.sf-dump .sf-dump-ellipsis+.sf-dump-ellipsis { max-width: none; } pre.sf-dump code { display:inline; padding:0; background:none; } .sf-dump-str-collapse .sf-dump-str-collapse { display: none; } .sf-dump-str-expand .sf-dump-str-expand { display: none; } .sf-dump-public.sf-dump-highlight, .sf-dump-protected.sf-dump-highlight, .sf-dump-private.sf-dump-highlight, .sf-dump-str.sf-dump-highlight, .sf-dump-key.sf-dump-highlight { background: rgba(111, 172, 204, 0.3); border: 1px solid #7DA0B1; border-radius: 3px; } .sf-dump-public.sf-dump-highlight-active, .sf-dump-protected.sf-dump-highlight-active, .sf-dump-private.sf-dump-highlight-active, .sf-dump-str.sf-dump-highlight-active, .sf-dump-key.sf-dump-highlight-active { background: rgba(253, 175, 0, 0.4); border: 1px solid #ffa500; border-radius: 3px; } pre.sf-dump .sf-dump-search-hidden { display: none; } pre.sf-dump .sf-dump-search-wrapper { float: right; font-size: 0; white-space: nowrap; max-width: 100%; text-align: right; } pre.sf-dump .sf-dump-search-wrapper > * { vertical-align: top; box-sizing: border-box; height: 21px; font-weight: normal; border-radius: 0; background: #FFF; color: #757575; border: 1px solid #BBB; } pre.sf-dump .sf-dump-search-wrapper > input.sf-dump-search-input { padding: 3px; height: 21px; font-size: 12px; border-right: none; width: 140px; border-top-left-radius: 3px; border-bottom-left-radius: 3px; color: #000; } pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next, pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-previous { background: #F2F2F2; outline: none; border-left: none; font-size: 0; line-height: 0; } pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next { border-top-right-radius: 3px; border-bottom-right-radius: 3px; } pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next > svg, pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-previous > svg { pointer-events: none; width: 12px; height: 12px; } pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-count { display: inline-block; padding: 0 5px; margin: 0; border-left: none; line-height: 21px; font-size: 12px; }pre.sf-dump, pre.sf-dump .sf-dump-default{background-color:#18171B; color:#FF8400; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: break-all}pre.sf-dump .sf-dump-num{font-weight:bold; color:#1299DA}pre.sf-dump .sf-dump-const{font-weight:bold}pre.sf-dump .sf-dump-str{font-weight:bold; color:#56DB3A}pre.sf-dump .sf-dump-note{color:#1299DA}pre.sf-dump .sf-dump-ref{color:#A0A0A0}pre.sf-dump .sf-dump-public{color:#FFFFFF}pre.sf-dump .sf-dump-protected{color:#FFFFFF}pre.sf-dump .sf-dump-private{color:#FFFFFF}pre.sf-dump .sf-dump-meta{color:#B729D9}pre.sf-dump .sf-dump-key{color:#56DB3A}pre.sf-dump .sf-dump-index{color:#1299DA}pre.sf-dump .sf-dump-ellipsis{color:#FF8400}</style><pre class=sf-dump id=sf-dump-2122892111 data-indent-pad="  "><span class=sf-dump-const>null</span>
</pre><script>Sfdump("sf-dump-2122892111")</script>

Something wrong with the ajax post.

@Laeng

This comment has been minimized.

Show comment
Hide comment
@Laeng

Laeng Jun 23, 2018

@heihachi88

Okay, image is not received to server.
hm.....

Laeng commented Jun 23, 2018

@heihachi88

Okay, image is not received to server.
hm.....

@Laeng

This comment has been minimized.

Show comment
Hide comment
@Laeng

Laeng Jun 23, 2018

@heihachi88
Sorry, heihachi88, I don't know your error reasons....
The obvious thing is that the image was not received to the server.

Laeng commented Jun 23, 2018

@heihachi88
Sorry, heihachi88, I don't know your error reasons....
The obvious thing is that the image was not received to the server.

@heihachi88

This comment has been minimized.

Show comment
Hide comment
@heihachi88

heihachi88 Jun 23, 2018

I can confirm, that #72 (comment) works in Laravel 5.6 perfectly.

In case someone stuck with it, just like a did, i'm posting my method for accepting post images:

    public function summerUploads(Request $request)
    {
        if ($request->ajax()) {
            if ($request->hasFile('file')) {
                $file = $request->file('file');
                $store = $file->store('summer-uploads');
            }

            return response()->json($request->root() . '/' . $store, 200, [], JSON_UNESCAPED_SLASHES);
        }

        return App::abort(404);
    }

heihachi88 commented Jun 23, 2018

I can confirm, that #72 (comment) works in Laravel 5.6 perfectly.

In case someone stuck with it, just like a did, i'm posting my method for accepting post images:

    public function summerUploads(Request $request)
    {
        if ($request->ajax()) {
            if ($request->hasFile('file')) {
                $file = $request->file('file');
                $store = $file->store('summer-uploads');
            }

            return response()->json($request->root() . '/' . $store, 200, [], JSON_UNESCAPED_SLASHES);
        }

        return App::abort(404);
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment