Search code examples
laravelamazon-web-servicesamazon-s3summernote

Store Summernote files into AWS s3


I am using summernote rich editor in my Laravel project and I want to store attachments like images and videos in AWS s3 instead of my storing them in my project.

This is what I have but it's not working am getting CORS policy from console log

    <?php
    $bucket = 'bucketNameHere';
    // $folder = 'summer';
    
    // these can be found on your Account page, under Security Credentials > Access Keys
    $accessKeyId = env('AWS_ACCESS_KEY_ID');
    $secret = env('AWS_SECRET_ACCESS_KEY');
    
    $policy = base64_encode(
        json_encode([
            // 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' => [['bucket' => $bucket], ['acl' => 'public-read'], ['success_action_status' => '201'], ['starts-with', '$key', '/']],
        ]),
    );
    
    $signature = base64_encode(hash_hmac('sha1', $policy, $secret, true));
    
    ?>

And This is Javascript scripts

  $(document).ready(function() {
            $('#description').summernote({
                height: 500,
                callbacks: {
                    onImageUpload: function(files) {
                        for (let i = 0; i < files.length; i++) {
                            sendFile(files[i]);
                        }
                    }
                }
            });

            function sendFile(file, editor, welEditable) {
                formData = new FormData();
                formData.append('key', '/' + 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();
                        console.log(url);
                        editor.insertImage(welEditable, url);
                    }
                });
            }
        });

How can I achieve this?


Solution

  • I was able to store summernote files in aws s3 using the code snippet below in my Laravel Controller:

        $summernote = new Blog();
    
        $description = $request->description;
    
        $dom = new \DomDocument('1.0', 'UTF-8');
        libxml_use_internal_errors(true);
    
        $dom->loadHtml($description, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);    
    
        $images = $dom->getElementsByTagName('img');
    
        foreach($images as $k => $img){
    
            $data = $img->getAttribute('src');
    
            list($type, $data) = explode(';', $data);
    
            list($type, $data) = explode(',', $data);
    
            $data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data));
    
            $filePath=  time().$k.'.png';
    
            Storage::disk('s3')->put($filePath, $data);
            
            $url = 'your-bucket/'.$filePath;
    
            $img->removeAttribute('src');
    
            $img->setAttribute('src',  $url);
    
         }
    
        $description = $dom->saveHTML();
    
        $summernote->description = $description;
        $summernote->save();