Bonjour à tous.
J'ai un comportement assez spécial avec un projet en cours. En effet, suivant le navigateur que j'utilise, la méthode find() de mes modèles a un comportement différent et vu qu'on parle d'une opération coté serveur, je ne comprends pas trop ce qu'il se passe. Je suis sur cakePHP 2.7.7.

Pour minimiser l'opération et essayer de comprendre, j'ai fait un simple debug d'un find('all') comme le montre le code suivant :

class AlbumsController extends AppController {   
    public function test(){
        debug($this->Album->find('all', array(
        )));die();
    }

    [...]
}

Et du coup, voici les rendus pour chrome, firefox, opera et ie :



Je suis loin d'être nouveau dans le dev web et je dirais plutôt qualifié avec cakePHP, mais là j'avoue être complètement perdu. Est-ce que quelqu'un a une idée car j'avoue que ça doit être tellement évident que je n'y pense pas ?

14 réponses


Xeta
Réponse acceptée

Tu ne lui spécifie pas de locale avant de faire ton find ?
Si non, alors oui, sa vient de Cake.
Si aucune locale n'est spécifiée à Cake, alors il va essayer de la déterminer suivant le header HTTP_ACCEPT_LANGUAGE et vue que ce header peut changer de format suivant le navigateur, voilà d'où ça vient.

https://github.com/cakephp/cakephp/blob/2.7/lib/Cake/I18n/I18n.php#L211-L223
https://github.com/cakephp/cakephp/blob/2.7/lib/Cake/I18n/L10n.php#L410-L431

Il faudrait que tu test de faire des debug dans les parties de code que je vient de te montrer pour voir se qu'envoie IE et Opera comparé à Firefox et Chrome.

DrSnake
Auteur

Je viens de créer une copie des données de mon site et j'ai utilisé cake bake pour en générer le contenu. Toutes les actions de tous les controlleurs ont bien des résultats identiques sur les 4 navigateurs. Du coup, le problème vient bien de mon code, mais d'où ... Je ne réalise moi même aucun filtrage en fonction du navigateur (et de toutes façons, ça n'impacte pas le travail du coté serveur pour la récupération de mes données ...). La section que j'essaie d'afficher est en dehors d'une zone privée et les actions sont bien déclarée en mode autorisé ( $this->Auth->allow(...) ).

Pensant que cela vient de cette zone privée du site mal déclarée, j'ai commenté les $components dans l'AppController, le deny dans le beforeFilter de l'AppController et le allow dans le beforeFilter de l'AlbumsController. Rien n'a changé, j'ai toujours un tableau vide en retour de $this->Album->find('all') pour certains navigateurs et pas d'autres.

Le problème est donc de plus en plus déconcertant pour moi :(.

Jamais vu ça non plus. Désolé de ne pas pouvoir t'aider. super bizarre qu'un code côté serveur donne un résutat différent côté client. Si tu trouves, je veux bien l'explication plus tard. Bon courage.

Bonjour,
tu as déjà du y penser mais ne serait-ce pas un problème de cache coté navigateur?

DrSnake
Auteur

@boostyweb.fr : oui en effet, c'est incompréhenssible. Le seul lien que j'aurais pu faire, c'est un check de variable sur $this->request mais je n'en fais rien et j'ai vérifié, cet objet est le même quelque soit le navigateur.

@TransientDev : Non je n'avais pas pensé au cache, mais comme j'ai téléchargé Opera spécialement pour tester, il n'y avait pas de cache. De plus, après ton message, pour le test, j'ai vidé le cache là où ça marche et là où ne ça marche pas, cela ne change rien.

J'ai essayé aussi de changer la config de mon serveur. D'un coté, un Ubuntu 14.04.3 avec Apache et PHP à jour et de l'autre, un vieux XAMPP sur Windows. Cela ne change rien non plus ... le résultat est le même, Chrome et Firefox affichent ce qu'il faut et pas Opera et IE.

Salut,

j'ai vidé le cache là où ça marche et là où ne ça marche pas, cela ne change rien

Tu as fait ctrl+F5 pour actualiser une page sans utiliser le cache ? C'est la solution la plus probable, surtout quand on voit la différence de ligne dans Edge (l12 dans tout les navigateurs sauf dans Edge, avec l20).

DrSnake
Auteur

@tleb : oui quand je dis que cela ne change rien, c'est à mon problème, ça recharge bien les images and co ;).

Peux-tu nous donner les lignes 12 à 20 de ton fichier app/Controller/AlbumsController.php ?

DrSnake
Auteur

Voici les lignes complètes (sans les commentaires au dessus du App::uses) :

App::uses('AppController', 'Controller');
class AlbumsController extends AppController {
    public $components = array('Paginator');

    public function beforeFilter(){
        parent::beforeFilter();
        //$this->Auth->allow(array('index', 'view'));
    }

    public function test(){
        debug($this->Album->find('all'));die();
    }

    [...]
}

Pour ce qui est du beforeFilter de l'AppController, pour le test, il n'y a plus de $this->Auth->deny() (plus nécessaire car le allow est commenté dans l'AlbumController). De plus comme dis dans le premier message, j'ai commenté les components de l'AppController (donc plus de Session ni Auth ni Cookie). Ce qui reste dans le beforeFilter de l'AppController :

class AppController extends Controller {
   /* public $components = array('Session', 'Cookie', 'Auth'=>array(
        'loginAction' => array(
            'admin'=>false,
            'controller' => 'users',
            'action' => 'login'
        ),
        'authenticate'=>array(
            'Form'=>array(
                'scope'=>array('User.is_active'=>true)
            )
        )

    ));*/

    function beforeFilter() {
        if (isset($this->params['prefix']) && $this->params['prefix'] == 'admin') {
            $this->layout = 'admin';
        }
        else{
            $this->layout = 'main';
        }

        $db = ConnectionManager::getDataSource('default');
        $data = $db->fetchAll("SELECT * FROM configs as Config");
        foreach($data as $var){
            Configure::write($var['Config']['tag'], $var['Config']['value']);
        }

        //$this->Auth->deny();
    }
    [...]
}
DrSnake
Auteur

Bon, j'ai trouvé d'où ça vient, mais pas comment résoudre le problème. En gros, j'ai utilisé le système de traduction intégré à CakePHP, donc dans mon modèle Album, j'ai un $actsAs comme ceci :

public $actsAs = array('Translate'=>array('name'=>'_name'));

Si je le retire, mon modèle fonctionne correctement sur tous les navigateurs. Alors maintenant, il faut que je trouve pourquoi quand mon modèle est traduisible, il marche ou pas selon le navigateur ... Ça fait longtemps que je l'utilises, mais je n'ai jamais vu qu'il posait problème, je dev seulement sur Chrome et je n'ai malheureusement pas vérifié avant.

EDIT : Ha, maintenant que j'ai trouvé d'où ça vient, je vois que le problème existait sur une ancienne version de CakePHP : lien. Le truc, c'est que je n'utilise pas de détection de langue comme dans l'exemple du lien avec un libellé de langue qui change suivant les navigateurs, je fixe mes propres libellé de langue (fra par défaut et l'utilisateur alterne entre fra et eng).

T'a essayé de passer de la 2.7 à la 2.8 de cakePHP ?

DrSnake
Auteur

Hum, je venais déjà d'une version 2.6.x. Je suis donc passé à la dernière version stable 2.7.7. Je n'ai pas testé des versions pas released. D'ailleurs... au cas où je fasse n'importe quoi , quelle est la procédure ?

DrSnake
Auteur

Je récapipète le problème avant de clore le sujet et d'en créer un nouveau sous un libellé plus approprié :

  • j'ai un problème qui affecte mon modèle suivant le navigateur que j'utilise;
  • ce problème a été diagnostiqué comme faisant partie du système de traduction de CakePHP utilisable en signalant le modèle comme traduisible comme ci dessous;
    public $actsAs = array('Translate'=>array('name'=>'_name'));
  • pour ce système de traduction, j'utilise mes propres libellés de langue et non ceux produits par les navigateurs, donc je n'ai à priori pas de problème lorsque ceux ci sont générés automatiquement par le navigateur.
  • le problème est le suivant. Lorsque je fais un simple find('all'), sur chrome et firefox, pas de problème, par contre, rien ne sort du modèle sur opera et ie, comme montré sur le premier post;

    class AlbumsController extends AppController {   
    public function test(){
        debug($this->Album->find('all', array(
        )));die();
    }
    
    [...]
    }
  • enfin, je suis sur CakePHP 2.7.7. Le problème était le même sur 2.6.x.
DrSnake
Auteur

Bordel je suis un débile profond, merci de m'avoir aiguillé. En effet, je fais un $this->Album->locale = $this->_getLocales() qui me retourne le tableau des langues et que je lis dans la config du site. Sauf que j'avais effectué cette action seulement dans les actions de la partie admin de ce controlleur ... J'ai déplacé ça dans le beforeFilter de l'AppController $this->{$this->modelClass}->locale = $this->_getLocales() , ça va tout de suite mieux ...

Mais je ne m'explique pas pourquoi sur certains navigateurs ça marchait car j'utilise des tags de langue en 3 lettres (fra, eng, ...) et pas en deux lettre comme Chrome (fr, en, ...) ou en deux parties comme pour Firefox (fr-FR, en-EN, ...). C'est pas bien grave.

Merci !