How To… | Upload images

Javascript doesn’t allow the implementation of images and files uploads. Therefore, this feature utilizes server-side languages, such as PHP.

1) URL path to an upload script

First of all, make sure that you set a proper path to the upload’s file. You can do it by setting Redactor’s option on load, for example:

<!--element -->
<textarea id="content"></textarea>

<!-- call -->
<script>
$R('#content', {
    imageUpload: '/your-upload-script/'
});
</script>

Let’s assume that file will handle images. Its code may look like this:

<?php

// This is a simplified example, which doesn't cover security of uploaded images.
// This example just demonstrate the logic behind the process.

// files storage folder
$dir = '/sitecom/images/';
$files = [];
$types = ['image/png', 'image/jpg', 'image/gif', 'image/jpeg', 'image/pjpeg'];

if (isset($_FILES['file']))
{
    foreach ($_FILES['file']['name'] as $key => $name)
    {
        $type = strtolower($_FILES['file']['type'][$key]);
        if (in_array($type, $types))
        {
            // setting file's mysterious name
            $filename = md5(date('YmdHis')).'.jpg';
            $path = $dir.$filename;

            // copying
            move_uploaded_file($_FILES['file']['tmp_name'][$key], $path);

            $files['file-'.$key] = array(
                'url' => '/tmp/images/'.$filename.'.jpg', 'id' => $id
            );
        }
    }
}

echo stripslashes(json_encode($files));

JSON example:

{
    "file": {
        "url": "image-url.jpg",
        "id": "some-id"
    }
}

And for multiple images:

{
    "file-1": {
        "url": "image-url-1.jpg",
        "id": "some-id"
    },
    "file-2": {
        "url": "image-url-2.jpg",
        "id": "some-id"
    }
}

This is a simplified example, which doesn’t cover the security of any uploaded files. This example just demonstrates the logic behind the process, because for any given Redactor’s integration instance file uploads may widely vary.

2) Custom function

The second way to upload images is a custom function. If you set the function as the imageUpload setting, the upload process is in your hands.

$R('#content', {
    imageUpload: function(formData, files, event)
    {
        // ... your process for uploading an image ...
        //  in the end, you must return JSON or a string with the image URL
        // return json;
        // or
        // return '/images/my-image.jpg';
    }
});

The custom function gets the following arguments:

  • formData – FormData object with all data to upload
  • files – FileList array is files only
  • event – Triggered event if image uploaded with drag and drop

3) Custom function with promises

Here is an example of Promise in the imageUpload custom function:

imageUpload: function(data, files, e, upload)
{
    return new Promise(function(resolve, reject)
    {
        var url = '/upload-path/';
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(e)
        {
            if (xhr.readyState === 4)
            {
                if (xhr.status === 200)
                {
                    resolve(xhr.response);
                }
                else
                {
                    reject(xhr.status);
                }
            }
        }

        xhr.open('post', url);
        xhr.send();

    }).then(function(response)
    {
        // success
        upload.complete(response);

    }).catch(function(response)
    {
        // fail
        upload.complete(response);
    });
}

The success response must contain JSON:

{
    "file": {
        "url": "image-url.jpg",
        "id": "some-id"
    }
}

Or just a string with image’s url, for example:

'/images/my-image.jpg'

The fail response must return JSON with error key like this:

{
    "error": true,
    "message": "Something went wrong..."
}