PHPのプロジェクトにサクッとwysiwygエディタ を実装する

## 使用したもの
CKEditor(4.22.1)

## インストール方法
下記のサイトにアクセス
https://ckeditor.com/ckeditor-4/download/?null-addons=#ckeditor-4

任意のバージョン、パッケージを選択しzipをダウンロード
※バージョン、パッケージによっては有料のものもあります。その場合コンソールにエラーが表示されるので注意
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370336/9fe2b9ed-c2c3-6102-7104-475e939b5279.png)

下記のように設置
```
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>

    <body>
        <div class="edit-area">
            <div class="edit-main">
                <div class="edit-content">
                    <textarea id="" name="content" class="ckeditor"></textarea>
                </div>
            </div>
        </div>

        <script src="/filepath/to/ckeditor.js"></script>
    </body>
</html>
```

実装完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370336/f384d76b-379d-87b7-109f-2f2adbc481a3.png)

## 細かい実装をしたい場合
/ckeditor/config.js
に細かい設定を書いていきます。(「下記から独自の設定]と書いている箇所)
特に初期設定ではPCから画像をアップロードして文章内に貼り付けることができないですが、
このファイルを少し変更するだけで画像のアップロードができるようになります。

```
/**
 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see https://ckeditor.com/legal/ckeditor-oss-license
 */

CKEDITOR.editorConfig = function (config) {
	// Define changes to default configuration here.
	// For complete reference see:
	// https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html

	// The toolbar groups arrangement, optimized for two toolbar rows.
	config.toolbarGroups = [
		{ name: 'clipboard', groups: ['clipboard', 'undo'] },
		{ name: 'editing', groups: ['find', 'selection', 'spellchecker'] },
		{ name: 'links' },
		{ name: 'insert' },
		{ name: 'forms' },
		{ name: 'tools' },
		{ name: 'document', groups: ['mode', 'document', 'doctools'] },
		{ name: 'others' },
		'/',
		{ name: 'basicstyles', groups: ['basicstyles', 'cleanup'] },
		{ name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align', 'bidi'] },
		{ name: 'styles' },
		{ name: 'colors' },
		{ name: 'about' }
	];

	// Remove some buttons provided by the standard plugins, which are
	// not needed in the Standard(s) toolbar.
	config.removeButtons = 'Underline,Subscript,Superscript';

	// Set the most common block elements.
	config.format_tags = 'p;h1;h2;h3;pre';

	// Simplify the dialog windows.
	config.removeDialogTabs = 'image:advanced;link:advanced';

	//下記から独自の設定
	config.language = 'ja';
	config.filebrowserBrowseUrl = "/ckeditor/attachment_files";
	config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";
	config.filebrowserImageBrowseUrl = "/ckeditor/pictures";
	config.filebrowserImageUploadUrl = "/ckeditor/picture_upload.php"; 
	config.filebrowserUploadUrl = "/ckeditor/attachment_files";
	config.allowedContent = true;
};

```


picure_upload.phpのサンプル
```
<?php
// 画像を保存するディレクトリを指定
$uploadDir = '/uploads/ckeditor/pictures/';

// ディレクトリが存在しない場合は作成
if (!file_exists($uploadDir)) {
    mkdir($uploadDir, 0755, true);  // 再帰的にディレクトリを作成
}

// レスポンスのタイプをJSONに設定
header('Content-Type: application/json');

// CKEditorのファンクションナンバーをチェック
$funcNum = $_GET['CKEditorFuncNum'] ?? '0'; // 未定義の場合、デフォルト値として '0' を使用

// ファイルが正しくアップロードされたかを確認
if (isset($_FILES['upload']['name'])) {
    $tempName = $_FILES['upload']['tmp_name'];  // 一時ファイル名
    $fileName = basename($_FILES['upload']['name']);  // オリジナルのファイル名

    // 画像ファイル名に特殊文字がないかチェック
    $fileName = preg_replace("/[^a-zA-Z0-9.]/", "_", $fileName);
    $filePath = $uploadDir . $fileName;

    // ファイルを指定ディレクトリに移動
    if (move_uploaded_file($tempName, $filePath)) {
        // アップロード成功時のレスポンス
        $url = '/uploads/ckeditor/pictures/' . $fileName;
        echo json_encode(array(
            'uploaded' => 1,
            'fileName' => $fileName,
            'url' => $url,
            'message' => 'ファイルのアップロードに成功しました',
            'CKEditorFuncNum' => $funcNum  // CKEditorに返すファンクションナンバー
        ));
    } else {
        // アップロード失敗時のレスポンス
        echo json_encode(array(
            'uploaded' => 0,
            'error' => array(
                'message' => 'ファイルのアップロードに失敗しました。',
                'CKEditorFuncNum' => $funcNum
            )
        ));
    }
} else {
    // ファイルが存在しない場合のエラーメッセージ
    echo json_encode(array(
        'uploaded' => 0,
        'error' => array(
            'message' => 'アップロードされたファイルが見つかりません。',
            'CKEditorFuncNum' => $funcNum
        )
    ));
}
?>

```

## まとめ
難しいのかなと思っていましたが1時間程度で実装できました！
誰かのためになっていたら嬉しいです🙇‍♂️