Good content takes time and effort to come up with.

Please consider supporting us by just disabling your AD BLOCKER and reloading this page again.







SummerNote Text Editor Save Images To Public Path Laravel | StackCoder


SummerNote WYSIWYG Text Editor Save Images To Public Path In PHP Laravel


Share On     Share On WhatsApp     Share On LinkedIn


When the user fills SummerNote WYSIWYG text editor with some text, images and uploads then save these images to specific public path and update textarea content with this path and store the content in the database using PHP Laravel.


NOTE: Code available in GitHub @ SummerNote WYSIWYG Text Editor Save Images


NOTE: The following you will basically use for Blog or any admin/client-related textarea WYSIWYG editor.

Basic Knowledge & Installation Process


Just in case if you're wondering how to install and work with the basic SummerNote Text Editor then feel free to check my another article @ SummerNote WYSIWYG Text Editor. Don't worry I will walk you through this article, but it won't be in-depth.


Basically SummerNote text editor looks like the following


SummerNote Text Editor Default View

SummerNote Text Editor Default View


How?


Let me answer how on earth I am simplifying the process of storing the images of the SummerNote text editor.


SummerNote Text Editor Converts Images To Base 64

Yes, the SummerNote text editor is simply superb. When you upload any image and content then it will instantly convert images to base64. So when we submit the form it will be posted as a string.


Implementation


Let's start implementing it in our project.


Intervention Package

composer require intervention/image


web.php

Route::get('/', 'FileUploadsController@create');
Route::post('/file-uploads', 'FileUploadsController@store');


Blade Templates


views/layouts/master.blade.php

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Form Upload</title>
        <link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        @yield('stylesheets')
    </head>
    <body>
        @yield('content')
        @yield('javascripts')
    </body>
</html>



views/file-uploads/create.blade.php

@extends('layouts.master')
@section('stylesheets')
    <!-- SummerNote CSS -->
    <link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-lite.min.css" rel="stylesheet">
@endsection
@section('javascripts')
    <!-- jQuery JS Library -->
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    
    <!-- SummerNote Javascript Library -->
    <script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-lite.min.js"></script>
    <script>
        $(document).ready(function () {
            /** Initialize SummerNote Javscript For Textarea */
            $('#message').summernote({
                height: '300px'
            });
        });
    </script>
@endsection
@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <h2 class="text-primary">WYSIWYG Editor</h2>
            <form action="{{ url('file-uploads') }}" method="post" enctype="multipart/form-data">
                @csrf
                <div class="row">
                    <div class="col-md-12 form-group">
                        <label for="message">Message Body</label>
                        @error('message')
                        <div class="text-danger">{{ $message }}</div>
                        @enderror
                        <textarea rows="10" name="message" id="message" class="form-control"></textarea>
                    </div>
                </div>
                <br>
                <div class="row">
                    <div class="col-md-12 form-group">
                        <input type="submit" value="Upload File" class="btn btn-primary">
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>
@endsection


* User fills the text editor and submits the form. Which will post all the text and images. Images will be converted to base64 on the fly with the SummerNote text editor.

* In Controller we will use PHP DomDocument for manipulating the HTML DOM 

* We will find all images from the message body

* Each image has base64 encoded string. Use this encoded string to create Image.

* We will use an Intervention package to create image using the base64 string

* Then save the new image generated with Intervention in Public folder. Make sure to create this folder prior.

* Make sure to save the new image name in some variable

* Once saved now replace the message body images image source from base64 to the new uploaded image path

* Now you have manipulated the DOM of the message. It's ready to save in the database


app/Http/Controllers/FileUploadsController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Intervention\Image\Facades\Image;

class FileUploadsController extends Controller
{
    public function create()
    {
        return view('file-uploads.create');
    }

    public function store()
    {
        /** Form validation */
        request()->validate([
            'message' => 'required'
        ]);

        /** Get the message body */
        $message = request()->get('message');

        /** PHP DomDocument For Manipulating The HTML DOM 
         * We will find all images from message_body
         * Each image has base64 encoded string
         * We will use Intervention package to create image using the base64 string
         * Then save the new image generated with Intervention in Public folder
         * Make sure to save the new image name in some variable
         * Once saved now replace the message body images image source from base64 to the new uploaded image path
         * Now you have manipulated the DOM of message. It's ready to save in the database
         */
        $dom = new \DomDocument();

        /**
         * LIBXML_HTML_NOIMPLIED - Turns off automatic adding of implied elements
         * LIBXML_HTML_NODEFDTD - Prevents adding HTML doctype if default not found
         */
        $dom->loadHtml($message, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

        /** I want all the images to upload them locally and replace from base64 to new image name */
        $images = $dom->getElementsByTagName('img');

        foreach ($images as $image) {
            $imageSrc = $image->getAttribute('src');
            /** if image source is 'data-url' */
            if (preg_match('/data:image/', $imageSrc)) {
                /** etch the current image mimetype and stores in $mime */
                preg_match('/data:image\/(?<mime>.*?)\;/', $imageSrc, $mime);
                $mimeType = $mime['mime'];
                /** Create new file name with random string */
                $filename = uniqid();

                /** Public path. Make sure to create the folder
                 * public/uploads
                 */
                $filePath = "/uploads/$filename.$mimeType";

                /** Using Intervention package to create Image */
                Image::make($imageSrc)
                    /** encode file to the specified mimeType */
                    ->encode($mimeType, 100)
                    /** public_path - points directly to public path */
                    ->save(public_path($filePath));

                $newImageSrc = asset($filePath);
                $image->removeAttribute('src');
                $image->setAttribute('src', $newImageSrc);
            }
        }
        /** Save this new message body in the database table */
        $newMessageBody = $dom->saveHTML();
        
        /** Your database saving implementation */
    }
}

Conclusion


NOTE: Code available in GitHub @ SummerNote WYSIWYG Text Editor Save Images


Most of the code I have explained with the comments. Hope you enjoyed the article. Please share it with your friends.




Author Image
AUTHOR

Channaveer Hakari

I am a full-stack developer working at WifiDabba India Pvt Ltd. I started this blog so that I can share my knowledge and enhance my skills with constant learning.

Never stop learning. If you stop learning, you stop growing