Intégrer CKeditor dans CakePHP
Descendant de FCKeditor, CKeditor est un puissant éditeur WYSIWYG. Nous allons créer un Assistant ou Helper pour transformer facilement un simple champ de type textarea en éditeur de texte complet, ainsi que le gestionnaire d’images et de fichier multimédia associé, CKfinder. Nous allons aussi voir comment il est possible de restreindre l’accès aux fonctionnalités de CKfinder aux utilisateurs authentifiés uniquement.
1. Installation
Commençons par télécharger CKeditor. Nous récupérons une archive que nous décompressons dans le dossier js de notre application. Nous faisons de même pour CKfinder (version PHP), pour obtenir au final l’arborescence suivante :
_ app |_ webroot |_ js |_ ckeditor |_ ckfinder
2. Configuration de CKeditor
Nous créons ensuite un fichier de configuration spécifique à l’application, que nous nommons naturellement app.config.js à l’intérieur du répertoire ckeditor. Ceci n’est qu’un exemple, à charge du lecteur de se documenter sur toutes les options disponibles :
CKEDITOR.editorConfig = function(config) { config.language = 'fr'; config.entities_latin = false; config.width = 640; config.height = 320; config.toolbar_App = [ ['Source','-','Save','Preview','-','About'], ['Cut','Copy','Paste','-','Print'], ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], '/', ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['Link','Unlink','Anchor'], ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'], '/', ['Styles','Format','Font','FontSize'], ['TextColor','BGColor'], ['Maximize', 'ShowBlocks'] ]; config.toolbar = 'App'; };
3. L’Assistant CkHelper
Voyons maintenant le code de l’Assistant lui-même, que nous recopions dans un nouveau fichier {app}/views/helpers/ck.php :
<?php class CkHelper extends AppHelper { var $helpers = array('Html', 'Javascript'); function replace($fieldName, $options = array()) { $defaults = array( 'customConfig' => '/js/ckeditor/app.config.js', 'loadFinder' => true ); $options = array_merge($defaults, $options); $fieldId = $this->domId($fieldName); $loadFinder = $options['loadFinder']; unset($options['loadFinder']); $script = "\tvar ck_$fieldId = CKEDITOR.replace('$fieldId', {$this->Javascript->object($options)});"; if($loadFinder) { $script .= "\n\tCKFinder.SetupCKEditor(ck_$fieldId, '/js/ckfinder/');"; } return $this->Html->scriptBlock($script); } } ?>
Le code n’est pas très compliqué, l’unique méthode replace() accepte deux arguments :
- le nom d’un champ de formulaire que nous souhaitons remplacer par CKeditor, typiquement un
textarea; - un tableau de paramètres dont deux sont remplis par défaut : le chemin vers notre fichier de configuration globale créé plus haut, et un booléen pour charger le gestionnaire d’images CKfinder. Ce tableau d’options peut permettre de prendre la main sur les variables de configuration du fichier
app.config.jssi besoin.
4. Utilisation de l’Assistant
Comme n’importe quel Helper, nous devons appeler le nôtre dans un Contrôleur (ou dans l’AppController si tous les contrôleurs doivent l’utiliser) :
class ArticlesController extends AppController { var $helpers = array('Ck'); }
Voyons maintenant une vue de ce contrôleur, dans laquelle nous allons appeler les fichiers javascript nécessaires au bon fonctionnement de CKeditor et CKfinder, et créer un textarea pour le remplacer par l’éditeur :
<?php // {app}/views/articles/admin_add.ctp $this->set('title_for_layout', "Ajouter un article"); // Appel des fichiers javascript nécessaires echo $this->Html->script('ckeditor/ckeditor', array('inline' => false)); echo $this->Html->script('ckfinder/ckfinder', array('inline' => false)); ?> <?php echo $this->Form->create('Article'); ?> <fieldset> <legend>Nouvel article</legend> <?php echo $this->Form->input('title', array('label' => "Titre :")); ?> </fieldset> <fieldset> <legend>Contenu</legend> <?php echo $this->Form->textarea('description'); ?> <?php echo $this->Ck->replace('description'); ?> </fieldset> <?php echo $this->Form->end("Valider"); ?>
L’appel des deux fichiers javascript requis ne sera effectif que si nous ajoutons echo $scripts_for_layout quelque part dans le header HTML de notre layout.
Voilà, nous obtenons un puissant éditeur HTML pour enrichir facilement le texte de l’article.
5. Configuration de CKfinder
Nous devons maintenant configurer CKfinder pour qu’il sache où stocker les images et les fichiers multimédias, par exemple le dossier {app}/webroot/files. Nous ouvrons le fichier {app}/webroot/js/ckfinder/config.php et modifions la ligne suivante :
$baseUrl = '/ckfinder/userfiles/';
En :
$baseUrl = '/files/';
Nous prenons garde que le dossier files existe bien et que les droits d’accès sont suffisants (chmod 755).
6. Restriction du CKfinder aux utilisateurs logués
Nous souhaitons que l’accès au gestionnaire multimédia soit tout à fait interdit aux utilisateurs non authentifiés. CKfinder demande d’ailleurs que l’on implémente la méthode CheckAuthentication() qui retourne false par défaut, interdisant tout accès à quiconque, authentifié ou pas. Nous allons donc implémenter cette méthode en retournant false sauf si le composant Auth a bien renseigné la session, prouvant par là que l’utilisateur est logué. Attention, CakePHP utilise un nom de session différent du nom par défaut de PHP, il faut penser à le définir en tout premier lieu, avant d’appeler session_start().
Nous modifions donc le tout début du fichier config.php comme suit :
session_name('CAKEPHP'); session_start(); /** * This function must check the user session to be sure that he/she is * authorized to upload and access files in the File Browser. * * @return boolean */ function CheckAuthentication() { return !empty($_SESSION['Auth']['User']); }
Cette fois nous pouvons accèder au gestionnaire d’images en cliquant sur l’icône correspondante dans CKeditor.
Commentaires
10 décembre 2009 à 9:08
Bonjour, J’ai également commencé récemment la création d’un Helper CKEditor pour CakePHP1.3. La principale différence est qu’il permet d’utiliser la gestion des buffers pour que le code Javascript puisse être placé en fin de page. Si celà peut t’intéresser, j’ai mis le code ici : http://gist.github.com/253193 (mais bon, il est loin d’être fini !)
Pierre
12 décembre 2009 à 20:42
J’ai suivi le tuto,
j’ai l’erreur suivante : Undefined property: View::$Ck [APP/views/administrators/nouvelles_ajouter.ctp, line 11]
qui correspond à :
17 décembre 2009 à 9:01
[...] Intégrer CKeditor dans CakePHP [...]
11 janvier 2010 à 16:51
excellent comme tous les articles de ce site. L’editeur marche bien mais par contre il m’est impossible de modifier les paramètres du fichier app.config.js. Si je mets par exemple config.width = 500; ça n’a aucun effet. De même si je modifie la liste des options. une idée ?
11 janvier 2010 à 18:43
@William : as-tu donné une taille en colonnes à ton textarea ? Si oui, essaie de l’enlever.
11 janvier 2010 à 19:29
j’ai supprimé la taille en colonnes mais ça ne change rien. D’ailleurs, le changements d’options ne marche pas non plus. On dirai qu’aucun élément du fichier de config ne marche. Et pourtant l’éditeur fonctionne nickel.
17 janvier 2010 à 2:57
@William : J’ai rencontré exactement le même problème que toi. Je l’ai résolu, pour l’instant, en spécifiant dans les URLs du helper « ck.php » le nom du répertoire racine de mon application. j’ai changé :
Et idem pour l’URL dans le bloc
Toutefois je ne trouve pas la méthode « propre » (je débute sous cakePHP) donc si quelqu’un a mieux à proposer, je suis preneur.
En espérant que cela t’aidera à résoudre ton problème, cordialement.
24 janvier 2010 à 14:45
Bonjour,
J’ai le même problème que William et RP..
Christophe
13 mars 2010 à 22:38
bonjour, aprés avoir configurer l’éditeur avec cakephp, je souhaite récupérer des champs de tables d’une base de donnée, et l’insérer dynamiquement dans le texte, c’est possible non ? SOS
14 avril 2010 à 14:13
@William : J’ai trouvé !
En fait le lien de configuration ne s’affichait pas du tout dans le block javascript, parcequ’il n’est pas spécifier qu’il doit être écrit !
19 avril 2010 à 23:36
@william: j’ai le méme pb ke vous et voila la solution, remplacer : Ck->replace(‘description’); ?>
par : replace(‘description’); ?>
mais moi j’un autre probleme : Method HtmlHelper::scriptBlock does not exist [CORE\cake\libs\view\helper.php, line 143]
s’il vous plais j’ai besoin de votre aide le plus rapide possible(le temps me press
)
25 mai 2010 à 21:09
Merci pour ce tuto !
21 juin 2010 à 16:02
Bonjour !
Je ne sais pas si les librairies ont changé récemment, mais une petite erreur dans le helper rendait l’utilisation de CkFinder impossible.
Il m’a fallu remplacer, à la ligne :
$script .= « \n\tCKFinder.SetupCKEditor(ck_$fieldId, ‘/js/ckfinder/’); »;
SetupCKEditor par setupCKEditor
Merci pour les infos, en tout cas
27 juin 2010 à 2:19
J’utilise CakePHP 1.2.7. L’éditeur ne replace pas les textarea. Lorsque je décommente les lignes suivantes: //echo $html->script(‘ckeditor/ckeditor’, array(‘inline’ => false)); //echo $html->script(‘ckfinder/ckfinder’, array(‘inline’ => false));
J’obtient le message d’erreur suivant : Method HtmlHelper::script does not exist [CORE\cake\libs\view\helper.php, line 142]
Lorsque j’utilise la fonction replace, comme dans l’exemple suivant : echo $form->textarea(‘shortdesc’); echo $ck->replace(‘shortdesc’, array(‘label’ => « Description courte : »));
J’obtient le message suivant : echo $form->textarea(‘shortdesc’); echo $ck->replace(‘shortdesc’, array(‘label’ => « Description courte : »));
Quelqu’un peut m’aider à corriger mon problème s.v.p.?
Merci
11 juillet 2010 à 3:27
Salut.
@Jérémie : je confirme. Si on ne mets pas le « s » de « Setup » en minuscule, le bouton « Explorer le serveur » n’apparaît pas.
J’ai un autre problème par contre, lorsque je clique sur ce bouton, j’obtiens cette erreur :
getDocumentRootPath() . $baseUrl; } $utilsSecurity =& CKFinderConnectorCoreFactory::getInstance(« UtilsSecurity »); $uti… …
La popup s’affiche bien, mais ce long message d’erreur (pas en intégralité ici) apparaît et empêche d’utiliser Ckfinder… :S
Quelqu’un a-t-il eu ce problème et a réussi à le résoudre ?
Merci d’avance.
9 octobre 2010 à 13:20
@MakeItSmile : Pourtant, normalement, le Javascript-object() dans
Par contre, le helper Javascript est déprécié à l’avenir, donc il vaut mieux utiliser le helper Js à la place qui fait la même chose.
Et je +1 pour le setupCKEditor au lieu de SetupCKEditor ; du coup, le code complet et fonctionnel (pour moi, CakePHP v 1.3.4) ça donne :
J’ai aussi rajouté l’option
9 octobre 2010 à 13:25
mmmh, mon commentaire a un peu souffert de la « sanitazation » ! Retrouvez le code complet ici : http://gist.github.com/618139
15 octobre 2010 à 16:11
Bonjour, j’ai intégré ce Helper et tout fonctionne très bien. Cependant, dès que mon RTE contient un peu trop de texte, au bout de quelques actions, il devient très lent…
Par exemple je surligne du texte, je clique sur « mettre en gras » (B) et il me faut bien 5 secondes pour que je puisse faire une autre action, tout mon onglet est freezé pendant ce temps là…
Je voulais savoir si quelqu’un avait déjà ressenti ce genre de ralentissement et s’il savait d’où ça vient ?
Merci beaucoup
27 avril 2011 à 17:35
Pour ceux qui ont le fichier de configuration ‘app.config.js’ qui n’est pas pris en compte, il suffit d’aller dans ck.php et de modifier
Chez moi cela fonctionne.
30 août 2011 à 23:37
Bonjour,
Tout d’abord excellent tuto !
Pour moi un résultat un peu exotique: lors du premier chargement, ok, mais lors de la soumission du formulaire, erreur JavaScript: Uncaught [CKEDITOR.editor] The instance « PageContenu » already exists :: prototype.js
le champs en question ayant le nom « data['Page']['contenu'].
Merci à la bonne âme qui pourra m’aider.
3 septembre 2011 à 19:19
Bien j’ai résolu mon problème, il venait du fait que mon site utilise AJAX.
Donc, en d’autre terme, l’éditeur une fois créé reste dans le DOM (même en changeant de page) et dès qu’on a le malheur de recharger la même page: collision d’ID dans le conteneur d’instance (CKEDITOR.instances). De plus, le contenu du textarea n’est pas mis à jour.
Il faut donc forcer manuellement la résolution de ces problèmes:
Et voilà, ça fonctionne avec un site en AJAX !
5 février 2012 à 11:59
Bonjour à tous,
Merci beaucoup pour tout les excellents tutos présents sur ce site…d’une précision exceptionnelle alors un grand bravo !!
Juste une petite remarque pour ceux qui souhaitent intégrer cakephp dans un sous-répertoire (dans EasyPhp/www/mon_site/ par exemple), il faut modifier la ligne du helper :