Saat menulis artikel di blog Anda, Anda akan sering perlu menampilkan gambar di antara teks biasanya untuk tujuan ilustrasi. CKEditor membantu Anda mencapai ini, tetapi ini bisa menjadi sedikit rumit atau sulit untuk dikerjakan jika Anda tidak menggunakan plugin. Alasannya adalah CKEditor hanya menerima URL gambar untuk dimasukkan ke dalam teks postingan, dan gambar tersebut harus sudah ada di internet dan bukan di komputer lokal Anda.
Yang perlu kita lakukan sekarang adalah menemukan cara untuk mengupload gambar ke direktori gambar di proyek kita saat kita masih menulis postingan; setelah gambar diunggah, URL gambar akan dikirim kembali yang kemudian dapat kami gunakan di CKEditor kami.
Hal pertama adalah kita akan menambahkan tombol yang ketika diklik akan menelusuri komputer lokal pengguna untuk mencari gambar (dengan cara yang sama seperti klik pada elemen ). Setelah pengguna memilih gambar, gambar tersebut segera diupload di latar belakang menggunakan Ajax (tanpa memuat ulang halaman) dalam peristiwa onChange dan URL gambar tersebut dikembalikan dari server. URL yang dikembalikan ditampilkan dalam modal pop-up yang akan disalin ke clipboard ketika pengguna mengkliknya. Pengguna sekarang dapat mengklik ikon gambar di CKEditor dan menempelkan URL gambar di dalamnya.
Mari kita terapkan ini pada proyek mini dan lihat cara kerjanya.
Buat folder bernama ckeditor-images dan di dalam folder ini, buat subfolder bernama images, dan 4 file yaitu:index.php, server.php, scripts.js, dan main.css.
Folder gambar akan menampung gambar yang diunggah dari CKEditor kami.
Buka index.php dan tempatkan kode berikut di dalamnya.
index.php:
<?php include('server.php') ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Uploading images in CKEditor using PHP</title>
<!-- Bootstra CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<!-- Custom styling -->
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2 post-div">
<!-- Display a list of posts from database -->
<?php foreach ($posts as $post): ?>
<div class="post">
<h3>
<a href="details.php?id=<?php echo $post['id'] ?>"><?php echo $post['title']; ?></a>
</h3>
<p>
<?php echo html_entity_decode(preg_replace('/\s+?(\S+)?$/', '', substr($post["body"], 0, 200))); ?>
</p>
</div>
<?php endforeach ?>
<!-- Form to create posts -->
<form action="index.php" method="post" enctype="multipart/form-data" class="post-form">
<h1 class="text-center">Add Blog Post</h1>
<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" class="form-control" >
</div>
<div class="form-group" style="position: relative;">
<label for="post">Body</label>
<!-- Upload image button -->
<a href="#" class="btn btn-xs btn-default pull-right upload-img-btn" data-toggle="modal" data-target="#myModal">upload image</a>
<!-- Input to browse your machine and select image to upload -->
<input type="file" id="image-input" style="display: none;">
<textarea name="body" id="body" class="form-control" cols="30" rows="5"></textarea>
</div>
<div class="form-group">
<button type="submit" name="save-post" class="btn btn-success pull-right">Save Post</button>
</div>
</form>
<!-- Pop-up Modal to display image URL -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Click below to copy image url</h4>
</div>
<div class="modal-body">
<!-- returned image url will be displayed here -->
<input
type="text"
id="post_image_url"
onclick="return copyUrl()"
class="form-control"
>
<p id="feedback_msg" style="color: green; display: none;"><b>Image url copied to clipboard</b></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- JQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- CKEditor -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/ckeditor/4.8.0/ckeditor.js"></script>
<!-- custom scripts -->
<script src="scripts.js"></script>
</body>
</html>
Seperti yang Anda lihat, kami telah menambahkan bootstrap CSS dan JS melalui CDN. Kami juga menambahkan JQuery karena kami akan mengunggah gambar menggunakan panggilan Ajax. Terakhir, kami menambahkan kode plugin CKEditor yang masih akan kami inisialisasi pada textarea kami di formulir. scripts.js adalah tempat skrip JQuery akan berada.
Tepat setelah formulir posting, kami menambahkan beberapa kode untuk modal pop-up dengan id disetel ke id="myModal". Modal ini tidak digunakan sekarang tetapi ketika gambar telah diunggah, URL gambar yang dikembalikan akan ditampilkan pada modal ini. Jadi lupakan saja untuk saat ini.
Jika Anda membuka http://localhost/ckeditor-images/index.php, Anda akan melihat postingan statis dan formulirnya. Buka main.css dan mari tambahkan beberapa gaya ke halaman ini.
main.css:
p {
font-size: 1.1em;
}
.post {
border: 1px solid #ccc;
padding: 10px;
margin-top: 15px;
}
.post h3 {
margin: 0px;
}
.post-div {
border: 1px solid #ccc;
margin-top: 30px;
margin-bottom: 30px;
padding: 20px;
}
.post-form {
margin-top: 80px;
}
/*DETAILS PAGE*/
.post-details p {
text-align: justify;
margin: 20px auto;
font-size: 1.2em;
}
.upload-img-btn {
position: absolute;
z-index: 9;
top: 35px;
right: 5px;
}
Buka scripts.js dan tambahkan kode ini di dalamnya:
scripts.js:
// initialize ckeditor
CKEDITOR.replace('body');
Segarkan halaman dan Anda akan melihat beberapa perubahan dalam gaya serta area teks yang sekarang menjadi CKEditor kami yang sarat dengan banyak ikon.
Buat database bernama ckeditor-images. Dalam database ini, buat tabel yang disebut posting dengan bidang:
- id - INT(11)
- judul - VARCHAR(255)
- tubuh - VARCHAR(255)
Sekarang masukkan satu atau lebih posting dummy ke dalam tabel posting sehingga kita dapat menanyakannya dan menampilkannya di halaman.
Menghubungkan ke database
Buka server.php dan masukkan kode ini di dalamnya:
<?php
// connect to database
$db = mysqli_connect("localhost", "root", "", "ckeditor-images");
// retrieve posts from database
$result = mysqli_query($db, "SELECT * FROM posts");
$posts = mysqli_fetch_all($result, MYSQLI_ASSOC);
?>
Kode ini mengambil postingan yang ada di database ke dalam variabel $posts. Variabel ini tersedia di file index.php kami dengan pernyataan include pada baris pertama kode di index.php -- baris yang menyertakan file server.php di dalam index.php.
Dalam file index.php, hapus seluruh elemen div yang memiliki atribut class="post" dan ganti dengan kode ini:
// ... more code here
<?php if (isset($posts)): ?>
<?php foreach ($posts as $post): ?>
<div class="post">
<h3>
<a href="details.php?id=<?php echo $post['id'] ?>"><?php echo $post['title'] ?></a>
</h3>
<p><?php echo $post['body']; ?></p>
</div>
<?php endforeach ?>
<?php else: ?>
<h2>No posts available</h2>
<?php endif ?>
// ... more code here
Seperti yang Anda lihat, setiap postingan saat diklik pada judulnya, mengarah ke details.php dengan meneruskan id postingan ke sana. Buat file bernama details.php dan paste kode ini di dalamnya:
detail.php:
<?php
// connect to database
$db = mysqli_connect("localhost", "root", "", "ckeditor-images");
if (isset($_GET['id'])) {
$id = $_GET['id'];
$result = mysqli_query($db, "SELECT * FROM posts WHERE id=$id");
$post = mysqli_fetch_assoc($result);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Uploading images in CKEditor using PHP</title>
<!-- Bootstra -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<!-- Custom styling -->
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2 post-div">
<div class="post-details">
<h2><?php echo $post['title'] ?></h2>
<p><?php echo html_entity_decode($post['body']); ?></p>
</div>
</div>
</div>
</div>
<!-- JQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- JQuery scripts -->
<script>
</script>
</body>
</html>
Di bagian atas, kita terhubung ke database, ambil id posting yang dikirim dari halaman index.php dan query posting tertentu. Postingan tersebut kemudian disimpan dalam variabel $post yang kemudian ditampilkan pada halaman tersebut.
Sekarang kita dapat mulai mengkodekan dinamika mengunggah gambar di CKEditor. Buka scripts.js dan ganti semua yang ada di dalamnya dengan ini:
scripts.js:
// initialize ckeditor
CKEDITOR.replace('body');
// Javascript function to copy image url to clipboard from modal
function copyUrl() {
var copyText = document.getElementById("post_image_url");
copyText.select();
document.execCommand("Copy");
// replace url with confirm message
$('#post_image_url').hide(1000);
$('#feedback_msg').show();
// hide modal after 2 seconds
setTimeout(function(){
$('#myModal').modal('hide');
$('#feedback_msg').hide();
$('#post_image_url').show();
}, 2000);
}
$(document).ready(function(){
// When user clicks the 'upload image' button
$('.upload-img-btn').on('click', function(){
// Add click event on the image upload input
// field when button is clicked
$('#image-input').click();
$(document).on('change', '#image-input', function(e){
// Get the selected image and all its properties
var image_file = document.getElementById('image-input').files[0];
// Initialize the image name
var image_name = image_file.name;
// determine the image extension and validate image
var image_extension = image_name.split('.').pop().toLowerCase();
if (jQuery.inArray(image_extension, ['gif', 'png', 'jpg', 'jpeg']) == -1) {
alert('That image type is not supported');
return;
}
// Get the image size. Validate size
var image_size = image_file.size;
if (image_size > 3000000) {
alert('The image size is too big');
return;
}
// Compile form values from the form to send to the server
// In this case, we are taking the image file which
// has key 'post_image' and value 'image_file'
var form_data = new FormData();
form_data.append('post_image', image_file);
form_data.append('uploading_file', 1);
// upload image to the server in an ajax call (without reloading the page)
$.ajax({
url: 'index.php',
method: 'POST',
data: form_data,
contentType: false,
cache: false,
processData: false,
beforeSend : function(){
},
success : function(data){
// how the pop up modal
$('#myModal').modal('show');
// the server returns a URL of the uploaded image
// show the URL on the popup modal
$('#post_image_url').val(data);
}
});
});
});
});
Ikuti komentar dalam kode ini dan Anda akan memahami langkah-langkahnya. Pertama, pengguna mengklik tombol "upload gambar". Ini memicu peristiwa klik pada input file yang tampilannya telah disetel ke none. Setelah pengguna memilih gambar dari komputer lokal mereka, peristiwa onChange dipicu pada input file, dan di sinilah kami mengunggah gambar menggunakan Ajax.
Pada titik ini, gambar kita sudah dikirim ke server dalam permintaan Ajax. Tapi sejauh ini di server.php kita, kita hanya terhubung ke database. Kami belum menulis kode untuk menerima gambar dari permintaan Ajax dan mengunggahnya ke folder gambar. Ayo lakukan sekarang.
Buka file server.php sekali lagi dan tambahkan kode ini ke dalamnya:
server.php:
// ... more code here ...
// if 'upload image' buttton is clicked
if (isset($_POST['uploading_file'])) {
// Get image name
$image = $_FILES['post_image']['name'];
// image file directory
$target = "images/" . basename($image);
if (move_uploaded_file($_FILES['post_image']['tmp_name'], $target)) {
echo "http://localhost/ckeditor-images/" . $target;
exit();
}else{
echo "Failed to upload image";
exit();
}
}
Kode ini menerima permintaan Ajax yang disertakan dengan gambar, mengunggah gambar ke folder gambar dan mengembalikan URL yang sepenuhnya memenuhi syarat ke gambar. Ingatlah bahwa saat ini pengguna masih sibuk menulis postingan mereka di formulir pembuatan postingan dan semua ini terjadi di latar belakang.
URL yang telah dikembalikan dari server kemudian ditampilkan pada modal pop-up yang muncul bagi pengguna untuk menyalin URL. Saat modal muncul dan pengguna mengklik URL yang ditampilkan, modal tersebut akan disalin ke clipboard dan pengguna dapat melanjutkan untuk menggunakan URL gambar ini di CKEditor dengan menempelkan URL ini di tempat yang sesuai.
Kami cukup banyak selesai dengan konsep inti dari tutorial ini. Saatnya tinggal kita tekan submit agar postingan kita bisa disubmit ke server dan disimpan di database. Untuk melakukan itu, kita hanya akan menyentuh satu file.
Buka server.php dan tambahkan kode ini di akhir file:
// ... more code here ...
// if form save button is clicked, save post in the database
if (isset($_POST['save-post'])) {
$title = mysqli_real_escape_string($db, $_POST['title']);
$body = htmlentities(mysqli_real_escape_string($db, $_POST['body']));
$sql = "INSERT INTO posts (title, body) VALUES ('$title', '$body')";
mysqli_query($db, $sql);
header("location: index.php");
}
Dan itu membawa kita ke akhir tutorial ini. Saya harap Anda memahami dengan baik tujuan kami dalam tutorial ini dan bagaimana kami mengatasinya.
Melihat lebih dekat
Pada titik ini, semuanya tampak bekerja dengan baik. Kami mengunggah gambar dan menggunakan URL-nya di CKEditor kami dengan baik, tetapi seberapa efisien sistem ini. Katakanlah Anda mulai menulis posting dan sepanjang jalan Anda merasa lelah setelah mengunggah beberapa gambar, bagaimana Anda membatalkan unggahan. Bagaimana Anda mengosongkan ruang di server Anda? Solusi yang saya usulkan adalah Anda membuat tabel gambar di database yang hanya menggunakan postID dan nama gambar. Setiap kali Anda mengunggah gambar, Anda menyimpan nama gambar di tabel gambar dengan null sebagai postID. Jika Anda berubah pikiran dan tidak menyimpan postingan pada akhirnya, null tetap ada di tabel gambar. Kemudian Anda dapat menulis skrip yang akan menanyakan semua gambar basis data yang memiliki null sebagai postID terkait. Tantang diri Anda dengan ini dan kodekan. Jika Anda mengalami kesulitan, tinggalkan di komentar di bawah dan bantuan akan datang.
Seperti biasa, terima kasih atas waktunya. Harap Anda menemukan ini bermanfaat. Jika Anda menikmati posting ini, silakan lihat tutorial saya yang lain dan silakan bagikan dan rekomendasikan situs saya dengan teman-teman Anda.
Salam hangat!