Bonjour, suite au Tutos Développer un site de A-Z ( j'en profite pour remercier Grafikart :) ), je voudrais integrer un plugin jQuery (elfinder) dans la partie administration pour gérer les fichiés. Mais lors de l'appel ajax, le Dispatcher fait trop bien sont travail :) car il m'indique que le controller textes n’existes pas se qui est tous à fait normale car il n'existe pas du fait que je voudrai faire un simple appel ajax sans regarder l'url pour se dossier en particulier. le code marche sur un site qui n'utilise pas le MVC mais je n'arrive pas a l'intégrer dans celui-ci :(. **** **voici le fichier de configuration de elfinder :** [code] include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderConnector.class.php'; include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinder.class.php'; include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeDriver.class.php'; include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeLocalFileSystem.class.php'; // Required for MySQL storage connector // include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeMySQL.class.php'; // Required for FTP connector support // include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeFTP.class.php'; /** * Simple function to demonstrate how to control file access using "accessControl" callback. * This method will disable accessing files/folders starting from '.' (dot) * * @param string $attr attribute name (read|write|locked|hidden) * @param string $path file path relative to volume root directory started with directory separator * @return bool|null **/ function access($attr, $path, $data, $volume) { return strpos(basename($path), '.') === 0 // if file/folder begins with '.' (dot) ? !($attr == 'read' || $attr == 'write') // set read+write to false, other (locked+hidden) set to true : null; // else elFinder decide it itself } $opts = array( 'debug' => true, 'uploadMaxSize' => '1G', 'fileMode' => 0775, // new files mode 'dirMode' => 0775, 'roots' => array( array( 'driver' => 'LocalFileSystem', // driver for accessing file system (REQUIRED) 'path' => 'textes/', // path to files (REQUIRED) 'URL' => 'textes/', // URL to files (REQUIRED) 'accessControl' => 'access', 'attributes' => array( array( // hide readmes 'uploadMaxSize' => '1G', 'read' => true, 'write' => true ) ) ) ) ); // run elFinder $connector = new elFinderConnector(new elFinder($opts)); $connector->run(); [/code] **et voici mon appel ajax et les configuration de elfinder :** [code] var elf = $('.file-manager').elfinder({ url : '<?php echo ROOT.'/view/textes/'; ?>', commandsOptions : { edit : { editors : [{ mimes : ['text/html','text/plain'], // add here other mimes if required load : function(textarea) { editor1 = CKEDITOR.replace( textarea.id ); console.log(textarea); console.log(elf.getfile()); }, close : function(textarea, instance) { CKEDITOR.remove(editor1); }, save : function(textarea, editor) { var file = elf.selectedFiles(); console.log(elf.selectedFiles()); textarea.value = editor1.getData(); CKEDITOR.remove(editor1); var xhr = new XMLHttpRequest(); xhr.open('put','app/texte/REST-Texte.php',true); xhr.setRequestHeader('content-type', 'multipart/form-data'); xhr.setRequestHeader('x-file-folder', file[0].hash); xhr.setRequestHeader('x-file-name', file[0].name); xhr.send(textarea.value); /*$.ajax({ type: "POST", url: "app/texte/UpdateTexte.php", dataType: "json", data: { file: file }, success: function(reponse){ console.log(reponse); } })*/ } } ] } }, getfile : { folders : true }, handlers : { upload : function(event, instance) { var uploadedFiles = event.data.added; var archives = ['application/zip', 'application/x-gzip', 'application/x-tar', 'application/x-bzip2','texte/plain']; for (i in uploadedFiles) { var file = uploadedFiles*; console.log('test'+file); $.ajax({ type: "POST", url : 'app/texte/REST-Texte.php', data : {file : file}, success : function(json){ instance.exec('reload'); if (json.error) { $('.alert').addClass('alert-error'); $('.alert h4').text('Erreur :').append(json.error); $('.alert').hide().slideDown(500); }else{ elf.exec('reload'); $('.alert').addClass('alert-success'); $('.alert h4').text('Succès : '+json.success); $('.alert').hide().slideDown(500); } } }); } }, } }).elfinder('instance'); [/code] Si quelqu'un peut m'aider SVP je le remercie d'avance.

4 réponses


BenFarhat
Réponse acceptée

As tu un objet qui te permet de dire si ta requêtes est en ajax?

Si oui j'te donne le parallèle

sur cakephp avant tout (la fonction s'appelle beforeFilter) on fait

if($this->RequestHandler->isAjax()){
            $this->layout=null;
            Configure::write('debug', 0);
        }

Sur MVC 3 le principe est identique on test la requetes IsAjaxRequest

@{
if (Request.IsAjaxRequest())
{
    Layout = "~/Areas/Dashboard/Views/Shared/_emptyLayout.cshtml";
}
else
{
    Layout = "~/Areas/Dashboard/Views/Shared/_Layout.cshtml";
}}

ou encore

@{
    Layout = Request.IsAjaxRequest() ? null : "~/Views/Shared/_Layout.cshtml";
}

Sinon en php tu as ce snippets qui fait l'affaire:

/* AJAX check */
if(!empty($_SERVER'HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER'HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
  /* Code pour l'ajax (en l'occurence tu omet ici le rendu du layout */
} 
else {
/* pas d'ajax tu fait ton rendu normalement */
}

source

ou carrément en fonction

function isAjax() {
   return (isset($_SERVER'HTTP_X_REQUESTED_WITH'])
              &&
            ($_SERVER'HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'));
}

source 1 | source 2

j'espère que ca aidera :)

Lorsqu'on clique sur un lien à traiter en jQuery on rajoute à la fin de l’exécution du code un <u><em>return false;</em></u> pour bien dire de ne pas continuer vers le lien cliqué (la valeur de l'href qui niveau MVC route vers un controller et une action),
Peut être que dans ton cas il manque un petit "return false;" pour dire à ton dispatcher de ne pas router vers le controller "textes".

Je ne connais pas elfinder mais dans le code d'utilisation je voit qu'une ligne est réservé à ce return false; ?

<script type="text/javascript">
       function openFinder() {
           $('#finder').elfinder('open');
             return false; // <------------ LA :)
       }
         $().ready(function() {
           var input = $('#dump');
             $('#finder').elfinder({
               url : 'include/elrte-1.2/elfinder/connectors/php/connectorGal.php',
               editorCallback : function(url) { input.val(url) },
               closeOnEditorCallback : true,
               docked : false,
               dialog : {title : 'Gallery manager'}
           });
             $('#finder').elfinder('close');
          });
      </script>

Peut être que c'est une piste à suivre?

ksta
Auteur

Merci de m'aider :)

J'ai du mal m'expliquer :( en faite le fichier php permet d'initialiser l'objet elfinder qui récupère toute les infos nécessaire et le dossier ou on commence l'arborescence etc... se fichier renvoie les informations en json comme ceci :

{"cwd":{"mime":"directory","ts":1358784003,"read":1,"write":1,"size":0,"hash":"l1_dGV4dGUtc3Bpbi9BaWw","name":"Ail","phash":"l1_dGV4dGUtc3Bpbg","date":"Yesterday 17:00","dirs":1},"options":{"path":"textes\/texte-spin\/Ail","url":"\/administration2\/app\/texte\/elfinder-connector\/..\/textes\/","tmbUrl":"\/administration2\/app\/texte\/elfinder-connector\/..\/textes\/.tmb\/","disabled":],"separator":"\/","copyOverwrite":1,"archivers":{"create":"application\/x-tar","application\/x-gzip","application\/x-bzip2","application\/zip","application\/x-rar","application\/x-7z-compressed"],"extract":"application\/x-tar","application\/x-gzip","application\/x-bzip2","application\/zip","application\/x-rar","application\/x-7z-compressed"]}},"files":{"mime":"directory","ts":1355918745,"read":1,"write":1,"size":0,"hash":"l1_Lw","volumeid":"l1_","name":"textes","date":"19 Dec 2012 13:05","locked":1,"dirs":1},{"mime":"directory","ts":1358784003,"read":1,"write":1,"size":0,"hash":"l1_dGV4dGUtc3Bpbg","name":"texte-spin","phash":"l1_Lw","date":"Yesterday 17:00","dirs":1},{"mime":"directory","ts":1356700397,"read":1,"write":1,"size":0,"hash":"l1_dGV4dGVzLUZpeA" etc....

mais quand je fait mon appel ajax je récupère le layout admin se qui est normale je comprend tout a fait car dans le dispatcher on récupère le controller et l'action puis on execute la fonction render.

Se que j'aimerai réussir a faire c'est utiliser l'ajax sans qu'il exeute cette fonction :

constructeur de la class Dispatcher :

function __construct(){
        $this->request = new Request(); 
        Router::parse($this->request->url,$this->request); 
        $controller = $this->loadController();
        $action = $this->request->action;
        if($this->request->prefix){
            $action = $this->request->prefix.'_'.$action;
        }
        if(!in_array($action , array_diff(get_class_methods($controller),get_class_methods('Controller'))) ){
            $this->error('Le controller '.$this->request->controller.' n\'a pas de méthode '.$action); 
        }
        call_user_func_array(array($controller,$action),$this->request->params); 
                    // ici la fonction render
        $controller->render($action);
    }

Je ne sais pas comment faire pour éviter de lancer cette fonction quand je veut faire des apel ajax normal sans perdre le layout admin :) car si je l'enleve sa me met une page blanche :( .

Je sais pas si j'ai réussie a bien m'expliquer.

En tous cas merci de ton aide.

ksta
Auteur

Bonjour, Merci pour ton aide :) sa marche nikel chrome :) J'aurais juste une petite question car tu ma demander : **As tu un objet qui te permet de dire si ta requêtes est en ajax?** Je n'est pas d'objet spécifique pour l'ajax donc serait il préférable que j'en fasse un? car j'ai inséré ta fonction dans l'objet controler se qui fait que je ne touche pas au constructeur du dispatcher mais a la fonction render de la class controller : constructeur Dispatcher : [code] /** * Fonction principale du dispatcher * Charge le controller en fonction du routing **/ function __construct(){ $this->request = new Request(); Router::parse($this->request->url,$this->request); $controller = $this->loadController(); $action = $this->request->action; if($this->request->prefix){ $action = $this->request->prefix.'_'.$action; } call_user_func_array(array($controller,$action),$this->request->params); if(!in_array($action , array_diff(get_class_methods($controller),get_class_methods('Controller'))) ) { $this->error('Le controller '.$this->request->controller.' n\'a pas de méthode '.$action); } $controller->render($action); [/code] **fonction render Constoller :** [code] /** * Permet de rendre une vu * @param $view Fichier à rendre (chemin depuis view ou nom de la vue) **/ public function render($view){ if($this->rendered){ return false; } extract($this->vars); if(strpos($view,'/')===0){ $view = ROOT.DS.'view'.$view.'.php'; }else{ $view = ROOT.DS.'view'.DS.$this->request->controller.DS.$view.'.php'; } ob_start(); // si il y a une requête ajax alors on charge pas la vue if (!$this->isAjax()) { require($view); } $content_for_layout = ob_get_clean(); // si il y a une requête ajax alors on charge pas le layout if (!$this->isAjax()) { require ROOT.DS.'view'.DS.'layout'.DS.$this->layout.'.php'; } $this->rendered = true; } [/code] Je me demande si il est pas préférable de mettre cette fonction dans l'objet request car sa serait plus logique non? Par contre j'ai remarquer que si j'inclue le fichier de configuration dans l'action index, lors d'un upload en drag and drop dans ce dernier alors il ne faisait pas de requête ajax mais un header location se qui m'indique une erreur de retour json car il me retourne le layout se qui est normale. **voici le controller Texte ou j'utilise le fichier de configuration de elfinder :** [code]