Hey all,
So the last week was awesome, I ended up doing some crazy stuff. But this isnt one of them :D Anyway I was told by a friend that he need a WYSIWYG editor for his project. Naturally nicEdit was my choice. Yet again he needed the support of adding image to the content as well, I mean uploading. So I searched and luckily nicEdit has an upload plugin. So the bad newss? Bad news is it's core is designed to upload the image to imgur and attach the url given by their API.
Problem?
All my images would be gone to imgur, I really dont have much problem with that except that every content I post would be depending on the servers of imgur. What if imgur decided that my content is violating their TOS after sometime? :O (Just kidding, need to make a point)
So I hacked the script a bit and saw that their upload mechanism which is AJAX based isnt overly complicated.Best way to use our server to keep images is to make a php script that would mimic imgur API. Wasn't that hard. First let's see how the existing nicEdit upload works.
nicEdit upload process
1) User upload image
2) nicEdit make a creates a POST request to the imgur API
3) API key is added to request
4) Img is added as if it's being uploaded using a HTML form (POST content is send as a multipart form)
5) Request is send to imgur, if everything is fine imgur API responds with a JSON object containing different info about the image
6) nicEdit attach the image using the link send found in the JSON object
Writing something to mimic the imgur API
Script will be written in php but you're free to make it in any language as long as you correctly capture the request and return a correctly formatted JSON object
Request
Request as I mentioned before is as if it's comming from a HTML file upload form. Basically your image data would be available from $_FILES array. From there on we follow the simple php uploader mechanism that is,
1) Check whether the image is a valid image type, to prevent attacks
2) Move the image file from the php temp directory to our img directory
3) Rename it with something unique, I usually do random() or md5() functions for the new name
4) Get the URL to the uploaded image
NOTE:
At this stage you could choose between giving the user a direct URL to the image or making another php script that would return the image data with headers. Well it's more secure, but too much of a trouble. I will continue as if we are giving the direct link to the image.
Response
This is indeed the tricky part. Even if we return the URL to the nicEdit plugin it won't work since it's expecting a JSON object from imgur and I dont want to hack apart everything from the script (No one does :S). This is how the return JSON object would look like (Included ONLY the parts important to ur)
Rest is just simple, we make a JSON object just like this and return :) So let's start
Code
img.php
NOTE:
1) All image are uploaded to a directory named upload, so make sure that dir exists and is CHMOD to 777 (Given read/write permission)
2) Change line 14 to suit your server path
Now we need to tell nicEdit that we are having our own upload script, luckily it's easy.
Open the nicEdit.js (if you download the whole thing with nicUpload plugin).
Find the line starting like xhr.open("POST"...
Replace it with
xhr.open("POST", "http://example.com/path_to_above_script/img.php");
DONE ! Now try uploading something and it would go directly to your server :)
Be back soon !
EDIT
Some of the comments below suggested that the response array should be changed like following for it to work correctly. I think it should be an issue with the latest nicEdit script. So if you are having troubles please try with this code for the '$res' array
Special thanks for jjsteing for pointing the new code
So the last week was awesome, I ended up doing some crazy stuff. But this isnt one of them :D Anyway I was told by a friend that he need a WYSIWYG editor for his project. Naturally nicEdit was my choice. Yet again he needed the support of adding image to the content as well, I mean uploading. So I searched and luckily nicEdit has an upload plugin. So the bad newss? Bad news is it's core is designed to upload the image to imgur and attach the url given by their API.
Problem?
All my images would be gone to imgur, I really dont have much problem with that except that every content I post would be depending on the servers of imgur. What if imgur decided that my content is violating their TOS after sometime? :O (Just kidding, need to make a point)
So I hacked the script a bit and saw that their upload mechanism which is AJAX based isnt overly complicated.Best way to use our server to keep images is to make a php script that would mimic imgur API. Wasn't that hard. First let's see how the existing nicEdit upload works.
nicEdit upload process
1) User upload image
2) nicEdit make a creates a POST request to the imgur API
3) API key is added to request
4) Img is added as if it's being uploaded using a HTML form (POST content is send as a multipart form)
5) Request is send to imgur, if everything is fine imgur API responds with a JSON object containing different info about the image
6) nicEdit attach the image using the link send found in the JSON object
Writing something to mimic the imgur API
Script will be written in php but you're free to make it in any language as long as you correctly capture the request and return a correctly formatted JSON object
Request
Request as I mentioned before is as if it's comming from a HTML file upload form. Basically your image data would be available from $_FILES array. From there on we follow the simple php uploader mechanism that is,
1) Check whether the image is a valid image type, to prevent attacks
2) Move the image file from the php temp directory to our img directory
3) Rename it with something unique, I usually do random() or md5() functions for the new name
4) Get the URL to the uploaded image
NOTE:
At this stage you could choose between giving the user a direct URL to the image or making another php script that would return the image data with headers. Well it's more secure, but too much of a trouble. I will continue as if we are giving the direct link to the image.
Response
This is indeed the tricky part. Even if we return the URL to the nicEdit plugin it won't work since it's expecting a JSON object from imgur and I dont want to hack apart everything from the script (No one does :S). This is how the return JSON object would look like (Included ONLY the parts important to ur)
Response (JSON Object)
- upload => (Array)
- links => (Array)
- original => (URL of img)
- image => (Array)
- width => width of image
- height => height of image
- upload => (Array)
- links => (Array)
- original => (URL of img)
- image => (Array)
- width => width of image
- height => height of image
Rest is just simple, we make a JSON object just like this and return :) So let's start
Code
img.php
- <?php
- //Check if we are getting the image
- if(isset($_FILES['image'])){
- //Get the image array of details
- $img = $_FILES['image'];
- //The new path of the uploaded image, rand is just used for the sake of it
- $path = "upload/" . rand().$img["name"];
- //Move the file to our new path
- move_uploaded_file($img['tmp_name'],$path);
- //Get image info, reuiqred to biuld the JSON object
- $data = getimagesize($path);
- //The direct link to the uploaded image, this might varyu depending on your script location
- $link = "http://$_SERVER[HTTP_HOST]"."/nicedit/".$path;
- //Here we are constructing the JSON Object
- $res = array("upload" => array(
- "links" => array("original" => $link),
- "image" => array("width" => $data[0],
- "height" => $data[1]
- )
- ));
- //echo out the response :)
- echo json_encode($res);
- }
- ?>
NOTE:
1) All image are uploaded to a directory named upload, so make sure that dir exists and is CHMOD to 777 (Given read/write permission)
2) Change line 14 to suit your server path
Now we need to tell nicEdit that we are having our own upload script, luckily it's easy.
Open the nicEdit.js (if you download the whole thing with nicUpload plugin).
Find the line starting like xhr.open("POST"...
Replace it with
xhr.open("POST", "http://example.com/path_to_above_script/img.php");
DONE ! Now try uploading something and it would go directly to your server :)
Be back soon !
EDIT
Some of the comments below suggested that the response array should be changed like following for it to work correctly. I think it should be an issue with the latest nicEdit script. So if you are having troubles please try with this code for the '$res' array
Special thanks for jjsteing for pointing the new code
- $res = array("data" => array(
- "links" => $link),
- "width" => $data[0],
- "height" => $data[1]
- ));
i wanna try
ReplyDeletesuccess, thanks a lot
ReplyDeleteglad it helped :)
ReplyDeletesorry it alert failed to upload image
ReplyDeletemight be a problem with server side, can you show me your code?
Deleteupload your whole code to server
DeleteIncreible, funciono a la perfeccion.
ReplyDeleteAwesome brother... thankssssss.........
ReplyDeletemy pleasure :3
Deletethanks 4 sharing :D
ReplyDeletethanks a lot, it is really halp me
ReplyDeleteTHX! You are my hero ManZzup!!!
ReplyDeletehappy to help guys :)
ReplyDeleteCan not find "xhr.open" please help .
ReplyDeleteany link to your nidEdit js? they may have changed it in their latest release, but would be easy to fix. Try searching for the imgur URL
DeleteCould you please upload the nicEdit.js that you are using? I have checked all archived versions since the upload feature was added (via webarchive.org), but none contain "xhr.open" phrase.
Deleteyou need to download the development version
Deletein here check the nicUpload tick and download then "uncompressed nicEdit for development"
http://nicedit.com/download.php
if u downlod the compressed one, the line is as C.open("POST",..
this is to minify the file size
How could I have missed that var names are changed upon minimisation!? Thank you very much - it works like a charm!!!
ReplyDeletewhen i upload, alert " object ProgressEvent "
ReplyDeletewhere exactly u are getting that error?
DeleteI'm having the same problem in Firefox.
DeleteHi,
ReplyDeleteI did it exactly like you described but the the error 'Failed to upload image'.
Here's a part of my code that seems to break:
var fd = new FormData(); // https://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/
fd.append("image", file);
fd.append("key", "b7ea18a4ecbda8e92203fa4968d10660");
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:8080/acp/functions/nicImageUpload.php");
xhr.onload = function() {
console.log(3.5);
try {
var res = JSON.parse(xhr.responseText);
} catch(e) {
console.log(3.54);
return this.onError();
console.log(3.6);
}
this.onUploaded(res.upload);
(Yes, my XAMPP is on Port 8080)
When I debug, the console throws out 3.5 and 3.54 but not 3.6. So it crashes there I believe.
Any suggestions?
How could i use your script using "upload URL" ? I am trying to, but only upload was successful, but the image is not getting attached to the editor
ReplyDeleteif it's not getting attached, it should be an issue with the postback object, that object consists of the details of where the img was uploaded. Can you provide with more details?
Deleteawesome boy!
ReplyDeleteNice work man. Worked on the first attempt!
ReplyDeleteservices JSON for PHP 4.x:
ReplyDeletehttp://www.epigroove.com/blog/how-to-use-json-in-php-4-or-php-51x
so, add this :
if (!function_exists('json_encode')) {
function json_encode($res) {
require_once 'JSON.php';
$json = new Services_JSON;
return $json->encode($res);
}
}
//before:
echo json_encode($res);
Hi... I am having the same issue as CACA[COBRA]...
ReplyDeleteonly upload was successful, but the image is not getting attached to the editor - See more at: http://manzzup.blogspot.com/2014/03/customize-nicedit-image-upload-to.html#sthash.97qO1HQk.dpuf..and the progress bar continuously shows progress
Change on img.php:
ReplyDelete$res = array("data" => array(
"link" => $link,
"width" => $data[0],
"height" => $data[1]));
And all is working good :)
It is great :) working perfect....
Deletethanks for your sharing
ReplyDeleteThis comment has been removed by the author.
ReplyDeletethanks, is very helpful
ReplyDeletethis code for CodeIgniter:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class NiceUpload extends CI_Controller {
function __construct() {
parent::__construct();
}
public function index(){
$config = array(
'upload_path' => './assets/files/upload/',
'allowed_types' => "jpg",
'overwrite' => TRUE,
'max_size' => "2560",
'file_name' => md5(date('YmdHis')).'.jpg'
);
$this->load->library('upload', $config);
$this->upload->do_upload('image');
$data = array(
'width'=>$this->upload->data('image_width'),
'height'=>$this->upload->data('image_height'),
'file_name'=>$this->upload->data('file_name')
);
$link = base_url().'assets/files/upload/'.$data['file_name'];
$res = array("data" => array(
'link' => $link,
'width' => $data['width'],
'height' => $data['height'])
);
echo json_encode($res);
}
}
i followed the instructions but now the image is uploaded to server but the loading bar keeps going on without stopping. any idea what could go wrong?
ReplyDeleteexact same issue that is happening for me, image is uploaded to server but loading bar just keeps going
Deletepossible reason is that the return object from the server is different than what the script is expecting, i guess due to changes in newer versions of the script. If the code in EDIT section above doesnt work can you send me the exact nicEdit version you are using?
Deleteany suggestion please ?
ReplyDeleteplease refer to comments above, the updated nicEdit version might have different ways of handling the image data
Deleteso in that case you need to use a mention specified in the comments
Hi i got
ReplyDelete"TypeError: D is undefined
if (D.error) {" ?
Image uploaded the specific path but not showing with in the editor?
Also see below if i change in image.php this below code
$res = array("data" => array(
"link" => $link,
"width" => $data[0],
"height" => $data[1]));
Even progress bar also not showing in the editor.
Any Help?
did you try with an earlier version of nicedit? this article seems to be not compatible with the newer versions
DeleteI can never thank you enough for this :D Thank you so so much
ReplyDeleteGlad it helped :D
Deletearray("data" => array(
Delete"link" => $link,
"width" => $data[0]
));
is the current expected response. and rest should be working perfectly. version 0.9 r25
Hi my nicedit version is 0.9 r25 it's released on 4th oct 2015.
ReplyDeleteand i have a error while upload image on my own server
actually image upload is specific folder is success but image uploader is continuously working and not stopping after image upload so can anyone help me please.
my nicedit and img.php code is below.
-------------- nicEdit.js----------------
ReplyDelete/* START CONFIG */
var nicUploadOptions = {
buttons : {
'upload' : {name : 'Upload Image', type : 'nicUploadButton'}
}
};
/* END CONFIG */
var nicUploadButton = nicEditorAdvancedButton.extend({
nicURI : '/include/editor/image.php',
errorText : 'Failed to upload image',
xhr.open("POST", "http://localhost/include/editor/image.php");
ReplyDeletethanks, this working perfectly.
ReplyDeleteI don't find the xhr.open, but I change the "nicURI" path and work.
script can upload the image, but bar never stops, and it doesn´t show the image in the editor.
ReplyDeleteAnyone can help?
I've used your suggestions successfully in the past and it continues to work if I upload to imgur. However, on an Azure VM running IIS 7.5 - the image uploads successfully but doesn't show properly giving an Error 402. If I attempt to display image in a browser, I get the same error. If I manually change the permissions on the image just uploaded, it displays fine. If I delete the image from the folder and upload it again, same issue. I know this is a permissions issue but I can't seem to find the solution no matter what permissions I give the folder. Anyone have any ideas?
ReplyDeleteThanks
Try changing the permissions of the upload directory to 777, which would provide read / write permissions to the directory, so all files in it will inherit it
DeleteThis comment has been removed by the author.
ReplyDeleteImage uploaded successfully. But there is no preview and progress bar appear.
ReplyDeleteSir please help me.
Urgent...
This is straightforward as all you require is to apply for a free record and you're prepared to share your images. free
ReplyDeleteHi, nice tutorial you posted here. I have a question, is it possible to create a "save" button so that the pictures won't directly get uploaded when the upload image button was pressed? I mean we can store the local path for example. So the pictures then will only get uploaded to the server when this "save" button is pressed.. this is maybe a good approach to reduce numbers of people who will accidentally upload wrong images to our server.
ReplyDeleteCan results defined in the json_encode($res) array be used from the results on the img tag?
ReplyDeleteI've tried things like this with no luck.
var A=(JSON.parse(C.responseText).data).width;
var H=JSON.parse(C.responseText).data).height;
if(this.im){this.im.setAttributes({src:D,width:(A&&B.width)?Math.min(A,B.width):"",height:H})}}});nicEditors.registerPlugin(nicPlugin,nicUploadOptions);
For those interested in this topic. I noticed where the value for link is defined.
Deletevar D=B.link;
Letters seem to be redefined over and over in this code but least at this point "B" is the result of the response. I added my own letter "R" to define the result right after the line mentioned above.
var R=B;
I then defined my A and H variables like so.
var A=R.width;
var H=R.height;
The A and H variables are now defined by the JSON response and applied to the image as in my opening question.
Thanks
ReplyDelete