Mysql
 sql >> Base de données >  >> RDS >> Mysql

Télécharger des images dans CKEditor sans utiliser de plugin

Lors de la rédaction d'un article sur votre blog, vous aurez souvent besoin d'afficher des images entre les textes, généralement à des fins d'illustration. CKEditor vous aide à y parvenir, mais cela peut être un peu délicat ou difficile à utiliser si vous n'utilisez pas de plugin. La raison en est que CKEditor n'accepte que l'URL de l'image à insérer dans le texte de publication, et l'image doit déjà exister sur Internet et non sur votre machine locale.

Ce que nous devons faire maintenant, c'est trouver un moyen de télécharger l'image dans un répertoire d'images de notre projet pendant que nous écrivons encore le message ; une fois l'image téléchargée, l'URL de l'image sera renvoyée que nous pourrons ensuite utiliser dans notre CKEditor.

La première chose est que nous allons ajouter un bouton qui, lorsqu'il est cliqué, parcourt l'ordinateur local de l'utilisateur à la recherche d'images (de la même manière qu'un clic sur un élément ferait l'affaire). Une fois que l'utilisateur a sélectionné une image, cette image est immédiatement téléchargée en arrière-plan à l'aide d'Ajax (sans recharger la page) dans un événement onChange et l'URL de cette image particulière est renvoyée par le serveur. L'URL renvoyée est affichée dans une fenêtre contextuelle qui est copiée dans le presse-papiers lorsque l'utilisateur clique dessus. L'utilisateur peut maintenant cliquer sur l'icône de l'image dans CKEditor et y coller l'URL de l'image.

Implémentons cela sur un mini-projet et voyons comment cela fonctionne.

Créez un dossier appelé ckeditor-images et à l'intérieur de ce dossier, créez un sous-dossier appelé images et 4 fichiers à savoir :index.php, server.php, scripts.js et main.css.

Le dossier images contiendra les images téléchargées depuis notre CKEditor.

Ouvrez index.php et placez-y le code suivant.

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">&times;</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>

Comme vous pouvez le voir, nous avons ajouté CSS et JS bootstrap via CDN. Nous avons également ajouté JQuery car nous allons télécharger les images à l'aide d'appels Ajax. Enfin, nous avons ajouté le code du plugin CKEditor qu'il nous reste à initialiser sur notre zone de texte dans le formulaire. scripts.js est l'endroit où résidera le script JQuery.

Juste après le formulaire de publication, nous avons ajouté du code pour le pop-up modal avec l'id défini sur id="myModal". Ce modal n'est pas utilisé maintenant mais lorsque l'image a été téléchargée, l'URL renvoyée de l'image sera affichée sur ce modal. Alors oubliez ça pour l'instant.

Si vous accédez à http://localhost/ckeditor-images/index.php, vous verrez la publication statique affichée et le formulaire. Ouvrez main.css et ajoutons quelques styles à cette page.

principal.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;
}

Ouvrez scripts.js et ajoutez ce code à l'intérieur :

scripts.js :

// initialize ckeditor
CKEDITOR.replace('body');

Actualisez la page et vous remarquerez quelques changements dans le style ainsi que dans la zone de texte qui est maintenant notre CKEditor chargé de nombreuses icônes.

Créez une base de données appelée ckeditor-images. Dans cette base de données, créez une table appelée posts avec des champs :

  • identifiant - INT(11)
  • titre - VARCHAR(255)
  • corps - VARCHAR(255)

Insérez maintenant un ou plusieurs messages factices dans le tableau des messages afin que nous puissions l'interroger et l'afficher sur la page.

Connexion à la base de données

Ouvrez server.php et entrez-y ce code :

<?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);
?>

Ce code récupère les messages qui se trouvent dans la base de données dans une variable $posts. Cette variable est rendue disponible dans notre fichier index.php par l'instruction include à la première ligne de code dans index.php -- la ligne qui inclut le fichier server.php dans index.php.

Dans le fichier index.php, supprimez l'intégralité de l'élément div qui a l'attribut class="post" et remplacez-le par ce code :

// ... 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

Comme vous pouvez le voir, chaque publication, lorsqu'on clique sur son titre, conduit à details.php en lui transmettant l'identifiant de la publication. Créez un fichier nommé details.php et collez-y ce code :

détails.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>

Dans la section supérieure, nous nous connectons à la base de données, récupérons l'identifiant de publication qui a été envoyé à partir de la page index.php et interrogeons cette publication particulière. La publication est ensuite stockée dans la variable $post qui est ensuite affichée sur la page.

Nous pouvons maintenant commencer à coder la dynamique du téléchargement de l'image dans CKEditor. Ouvrez scripts.js et remplacez tout ce qu'il contient par ceci :

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);
				}
			});
		});

	});
});

Suivez les commentaires dans ce code et vous comprendrez les étapes. Tout d'abord, l'utilisateur clique sur le bouton "télécharger l'image". Cela déclenche un événement de clic sur l'entrée de fichier dont l'affichage a été défini sur aucun. Une fois que l'utilisateur a sélectionné une image sur son ordinateur local, un événement onChange est déclenché sur l'entrée du fichier, et c'est là que nous téléchargeons l'image à l'aide d'Ajax.

À ce stade, notre image est déjà envoyée au serveur dans une requête Ajax. Mais jusqu'à présent, dans notre server.php, nous nous sommes uniquement connectés à la base de données. Nous n'avons pas encore écrit le code pour recevoir l'image de la requête Ajax et la télécharger dans le dossier images. Faisons-le maintenant.

Ouvrez à nouveau le fichier server.php et ajoutez-y ce code :

serveur.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();
  	}
}

Ce code accepte la requête Ajax fournie avec l'image, télécharge l'image dans le dossier images et renvoie une URL complète vers l'image. N'oubliez pas qu'à ce stade, l'utilisateur est toujours occupé à rédiger son message sur le formulaire de création de message et que tout cela se passe en arrière-plan.

L'URL qui a été renvoyée par le serveur est ensuite affichée dans une fenêtre contextuelle qui s'affiche pour que l'utilisateur copie l'URL. Lorsque le modal apparaît et que l'utilisateur clique sur l'URL affichée, il est copié dans le presse-papiers et l'utilisateur peut continuer à utiliser cette URL d'image dans CKEditor en collant cette URL à l'endroit approprié.

Nous avons à peu près terminé avec le concept de base de ce tutoriel. Il nous reste maintenant à appuyer sur Soumettre pour que notre message soit soumis au serveur et enregistré dans la base de données. Pour ce faire, nous ne toucherons qu'un seul fichier.

Ouvrez server.php et ajoutez ce code à la fin du fichier :

// ... 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");
}

Et cela nous amène à la fin de ce tutoriel. J'espère que vous avez bien compris notre objectif dans ce tutoriel et comment nous l'avons abordé.

 Regarder de plus près

À ce stade, tout semble bien fonctionner. Nous téléchargeons une image et utilisons son URL dans notre CKEditor, mais quelle est l'efficacité de ce système. Supposons que vous commenciez à écrire un article et que vous vous sentiez épuisé après avoir téléchargé quelques images, comment annuler les téléchargements. Comment libérer de l'espace sur votre serveur ? Une solution que je proposerais est de créer une table d'images dans la base de données qui ne prend que le postID et le nom de l'image. Chaque fois que vous téléchargez une image, vous enregistrez le nom de l'image dans la table des images avec null comme postID. Si vous changez d'avis et que vous n'enregistrez pas le message à la fin, le null reste dans la table des images. Ensuite, vous pouvez écrire un script qui interrogera toutes les images de base de données qui ont null comme postID associé. Relevez le défi et codez-le. Si vous rencontrez des difficultés, laissez-les dans les commentaires ci-dessous et de l'aide viendra.

Comme toujours, merci pour votre temps. J'espère que ceci vous aidera. Si vous avez apprécié cet article, consultez mes autres tutoriels et partagez et recommandez mon site à vos amis.

Cordialement !