Sign up (with export icon)

Laravel

Show the table of contents

This guide describes the integration of CKBox in a Laravel application. If you prefer to jump straight to the code, you can find the complete code of the application described in this guide on GitHub.

Prerequisites

Copy link

Before we start, please ensure that you have composer installed in your system. If the tool is not available from the command line, please follow Composer’s installation instructions first.

Creating the application

Copy link

As a base in our example, we will create a new Laravel project using the Composer create-project command:

composer create-project laravel/laravel ckbox-laravel-example
Copy code

After the project is created, you can enter the directory and start the development server:

cd ckbox-laravel-example
php artisan serve
Copy code

The application will be available under http://127.0.0.1:8000.

Creating the controller

Copy link

First, let’s create a controller. The controller will contain two actions: one for displaying the HTML content of the example and the second one for serving the token URL, used to authenticate users in CKBox.

Token URL

Copy link

CKBox, like other CKEditor Cloud Services, uses JWT tokens for authentication and authorization. All these tokens are generated on your application side and signed with a shared secret that you can obtain in the Customer Portal. For information on how to create access credentials, please refer to the Creating access credentials article in the Authentication guide

Now that we have the required access credentials, namely: the environment ID and the access key, let’s create the token endpoint. As a base, we will use the code of the generic token endpoint in PHP.

First, let’s install the firebase/php-jwt library for creating JWT tokens:

composer require firebase/php-jwt
Copy code

As a base, we will use the code of the generic token endpoint in PHP. Let’s wrap the logic of the PHP token endpoint in Laravel action and generate a token with the payload required by CKBox.

Complete controller code

Copy link
// app/Http/Controllers/CKBoxExampleController.php

namespace App\Http\Controllers;

use \Firebase\JWT\JWT;
use Illuminate\Http\Response;
use Illuminate\View\View;

class CKBoxExampleController extends Controller
{
    /**
     * Show the CKBox example.
     */
    public function show(string $example = null): View
    {
        if (in_array($example, ['ckeditor', 'modal', 'full-page'])) {
            return view('ckbox-example-' . $example);
        }

        return view('ckbox-example-list');
    }

    /**
     * Create CKBox JWT token.
     */
    public function token(): Response
    {
        $environmentId = env('CKBOX_ENVIRONMENT_ID');
        $accessKey = env('CKBOX_ACCESS_KEY');

        $payload = [
            'aud' => $environmentId,
            'iat' => time(),
            'sub' => 'unique-user-id', // Unique user ID in your application
            'auth' => [
                'ckbox' => [
                    'role' => 'superadmin',
                ]
            ]
        ];

        $jwtToken = JWT::encode($payload, $accessKey, 'HS256');

        return new Response($jwtToken);
    }
}
Copy code

As you can see on the code listing above, the access credentials required to sign JWT tokens are obtained from the environment variables. Thanks to this, you can conveniently add them to the .env file:

# .env
CKBOX_ENVIRONMENT_ID=REPLACE-WITH-ENVIRONMENT-ID
CKBOX_ACCESS_KEY=REPLACE-WITH-ACCESS-KEY
Copy code

Now, let’s register the required routes:

// routes/web.php

use App\Http\Controllers\CKBoxExampleController;
use Illuminate\Support\Facades\Route;

Route::get('/ckbox/token', [CKBoxExampleController::class, 'token'])->name('ckbox_token');
Route::get('/{example?}', [CKBoxExampleController::class, 'show'])->name('ckbox_example');
Copy code

Adding CKBox script to the page

Copy link

CKBox can be embedded in the application in multiple ways. For simplicity, in our example, we will use the CKBox script served from the CDN.

Examples in this guide will cover three popular scenarios of using CKBox:

  • CKBox integrated with CKEditor
  • CKBox used as a file picker in dialog mode
  • CKBox used as a full-page application

To avoid code repetition, let’s prepare a base Blade template that includes CKBox script, which we will reuse in all three examples:

<!-- resources/views/ckbox-example-layout.blade.php -->
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8"/>
        <script src="https://cdn.ckbox.io/ckbox/2.8.2/ckbox.js"></script>
        @stack('head')
        <title>CKBox example</title>
    </head>
    <body>
    @yield('content')
    </body>
</html>
Copy code

Now, let’s add views for the three examples.

CKBox with CKEditor 5

Copy link

In this example, we will use the quickest and easiest way to run CKEditor 5 – served from the CDN. For more advanced integration scenarios, please refer to the CKEditor 5 documentation.

Let’s create the child view that extends the layout we have created in the previous step:

<!-- resources/views/ckbox-example-ckeditor.blade.php -->
@extends('ckbox-example-layout')

@push('head')
    <script type="importmap">
        {
            "imports": {
                "ckeditor5": "https://cdn.ckeditor.com/ckeditor5/46.1.0/ckeditor5.js",
                "ckeditor5/": "https://cdn.ckeditor.com/ckeditor5/46.1.0/"
            }
        }
    </script>
    <link rel="stylesheet" href="https://cdn.ckeditor.com/ckeditor5/46.1.0/ckeditor5.css" />
@endpush

@section('content')
    <textarea id="editor"><?php echo htmlspecialchars('<h1>Example</h1><p>Hello world</p>'); ?></textarea>

    <script type="module">
        import {
            ClassicEditor,
            CKBox,
            Essentials,
            Bold,
            Italic,
            Font,
            Paragraph
        } from 'ckeditor5';

        ClassicEditor
            .create( document.querySelector( '#editor' ), {
                plugins: [ CKBox, Essentials, Bold, Italic, Font, Paragraph ],
                ckbox: {
                    tokenUrl: 'https://your.token.url',
                    theme: 'lark'
                },
                toolbar: [
                    'ckbox', '|', 'undo', 'redo', '|', 'bold', 'italic', '|',
                    'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor'
                ],
            } )
            .catch( error => {
                console.error( error );
            } );
    </script>
@endsection
Copy code

The above example includes a predefined CKEditor build from the CDN, which includes the required CKBox plugin. Then, CKEditor is configured to use CKBox by setting the required parameters of the ckbox attribute. Please note that in the ckbox.tokenUrl configuration option we pass the URL of the token endpoint created in one of the previous steps, which will be used to obtain JWT tokens used to authenticate users in CKBox.

CKBox as file picker

Copy link

One of the common scenarios is to use CKBox as a file picker, where the user can choose one of the files stored in the file manager. After choosing the file, we want to obtain information about the chosen files, especially their URLs. This can be achieved using the assets.onChoose callback passed as the CKBox’s configuration option:

<!-- resources/views/ckbox-example-modal.blade.php -->
@extends('ckbox-example-layout')

@section('content')
    <input type="text" id="file-url"></input><button id="choose">Choose file</button>
    <div id="ckbox"></div>
    <script>
        document.getElementById('choose').addEventListener('click', function () {
            CKBox.mount(document.querySelector('#ckbox'), {
                tokenUrl: '{{ route('ckbox_token') }}',
                dialog: true,
                assets: {
                    // Callback executed after choosing assets
                    onChoose: (assets) => {
                        document.getElementById('file-url').value = assets[0].data.url;

                        assets.forEach((asset) => {
                            console.log(asset.data.url);
                        })
                    }
                }
            });
        });
    </script>
@endsection
Copy code

CKBox in full-page mode

Copy link

To start CKBox in full-page mode, you can attach it to the document.body and adjust the required CSS styles:

@extends('ckbox-example-layout')

@push('head')
    <style>
        html, body {
            margin: 0;
            padding: 0;
            height: 100vh;
        }
    </style>
@endpush

@section('content')
    <script>
        CKBox.mount(document.body, {
            tokenUrl: '{{ route('ckbox_token') }}'
        });
    </script>
@endsection
Copy code

Complete code

Copy link

On GitHub, you can find the complete code of the application described in this guide.