Bonjour voila je crée actuellement un site, et j'ai besoin de faire en sorte que quand une visiteur vient sur le site, il arrive sur htpp://exemple.com et qu'il puise uniquement acceder au controller users et au action login, signup et forgot, et rien d'autre. Mais une fois qu'il ce connecte j'aimerais que la page http://exemple.com soit son profil ! Donc une page différente a quand il est pas connecté.

13 réponses


Salut Aurelien,

Dans tes reoutes, il faut tout d'abord définir le fait d'afficher le profil utilisateur à la racine du domaine. Pour cela :

Router::connect('/', array('controller' => 'users', 'action' => 'show'));

Après, je ne connais pas la structure de ton app, mais dans le modèle ci-dessus, le profil fait partie du model user et l'action show affiche le profil de l'utilisateur authentifié.
C'est comme ça que je fonctionne en tout cas, avec dans mon controller user une action du type :

public function show() {
    $profil = $this->User->findbyId($this->Auth->user('id'));
    $this->set('Profil', $profil);
}

Ensuite, comme tu souhaites que tes utilisateurs soient forcément connectés, tu peux définir dans ton AppController le comportement suivant :

function beforeFilter() {
        $this->Auth->deny();
    }

Ainsi, si un utilisateur tente d'accéder à ton site sans être authentifié, il sera automatiquement dirigé vers l'action login de ton controller user.

Déjà je te remercie de m'avoir répondu :D
Mais en fait ça je sais le faire, j'ai du mal expliqué ce que je veux faire.

Je vais essayé d'expliquer mieux alors :D

Je veux que uand tu es pas connecte :
    http://exemple.com/ => Afficher le controller "Pages" et l'action "home"
    Les controllers et actions accessible pour eux sont :
        Action dans le Controller users :
             - login
             - signup
             - forgot

Et je veux que quand tu es connecté : 
    http://exemple.com/ => Affiche le controller "Users" et l'action "home"

Ah ! Alors c'est encore plus simple.

Sur ton controller Pages, sur l'action home, tu rajoutes en début de la fonction :

if ($this->Auth->user())
    {
       $this->redirect(array('controller'=>'users', 'action'=>'home'));
    }
    else
    {
        // Ici tu mets ce qu'il y a actuellement dans ta fonction "home".
    }

Voila ;)

OMG je dois pas reussir a m'expliquer :S !

j'aimerais faire en sorte que quand le visiteur arrive sur http://exemple.com/ il vois le controller pages et l'action home sans que cela soit spécifié dans l'url, et qu'il puise acceder uniquement aux actions dans le Controller users :

  • login
  • signup
  • forgot

Une fois qu'il est connecté, il est automatiquement rediriger sur l'index du site, qui elle devient le controller users et l'action index quand le membre est connecte !

Donc je récapitule :

Je veux que quand le membre est pas connecte :
    http://exemple.com/ => Afficher le controller "Pages" et l'action "home" sans que ça soit specifié dans l'url
    Les controllers et actions accessible pour lui est :
        Action dans le Controller users :
             - login
             - signup
             - forgot

Et je veux que quand tu es connecté :
    http://exemple.com/ => Affiche le controller "Users" et l'action "home" sans que ça soit specifié dans l'url

Tu as mis la même chose qu'au dessus, donc je vais garder la même réponse...

Ou alors effectivement c'est que tu ne t'exprimes pas bien.

Si tu veux que la racine de ton app soit le controller Pages et l'action home, tu le définis dans les routes.
Sur la view correspondant à la page Home, tu afficheras des liens vers les actions login, signup et forgot du controller Users.

Et si tu rajoutes mon bout de code donnée plus haut sur le controller Pages, action home, alors si l'utilisateur est loggé il aura la bonne page. Après le souci c'est l'url, mais sinon, tu peux très bien coder l'action home du controller Users dans le controller Pages, en jouant sur le if ($this->Auth->user()) pour savoir s'il est loggé ou non, et derrière en faisant un loadModel('Users') et en chargeant la bonne vue.

C'est plus long et un peu moins facile, mais tu peux.

Bonjour,

Pakito a raison ce n'est pas bien difficile,
je reprend quelques bouts de son code.

//La route principale de l'accueil est le profil de l'utilisateur ( dans le fichier Config/routes.php
        Router::connect('/', array('controller' => 'users', 'action' => 'profil'));

        //Dans le controller Controller/UsersController.php la fonction profil
        public function profil()
        {
            $d = array();
            //Si elle est connecté
            if(AuthComponent::user('id'))
            {
                $user_id = AuthComponent::user('id');
                //Ici je récupère les information de l'utilisateur
                $d'user'] = $this->User->find('all',array('conditions' => array('id' => $user_id)));
            }
            else
                //Tu rediriges directement vers la page de connexion ou tu fais aussi de cette action une page de connexion
                return $this->redirect(array('action' => 'login'));
            $this->set($d);
        }
        //La fonction de login
        public function login()
        { 
            //Ici tu connais comment faire pour le login je te fais confiance.
        }
       /***
        *Sache que tu peux tout faire dans une action, alors dans ton action profil, au lieu de faire un else avec redirect
        *tu mettras juste tous ce que t'a mis dans ta fonction login, ensuite dans ta vue il faudra tester, si la personne est
        *connectée( utilise $this->Session->read(...) ) tu affiches son profil grâce aux informations que tu auras eu.
        *Sinon tu afficheras un formulaire de connexion.
        *J'espère avoir été claire ;) .
        */

Superbement,
ccvf2s.

Bonjour.
Tu ne peux pas faire ce que tu demandes.
Une adresse URL n'est pas faite juste pour afficher des caractères aux visiteurs mais pour transmettre des informations au site WEB.
Ce que tu veux faire, ce serait demander à ton application d'afficher deux choses différentes sur la même page, pour imager la chose, c'est comme-ci tu voulais être à Londres sans te déplacer alors que tu es en France.
Comment veux-tu que ton application sache ce quelle doit afficher sans avoir d'informations en retour ?
Tu ne peux pas lui demander d'afficher une action et un controller différent selon si la personne est connectée ou non sur la même adresse URL, de plus, à la racine de l'application.

La seule chose que tu puisse faire, c'est par exemple de récupérer les informations de profil de l'utilisateur depuis la fonction home de ton controller pages si la personne est conectée et sur la vue mettre une condition pour afficher soit les informations de bases de l'action, soit celles du profil de l'utilisateur.
Par contre, cela veut dire qu'une fois connecté, il ne pourra pas afficher les informations de base de l'action.
Exemple : PagesController.php

public function home(){
    if(!$this->Auth->loggedIn()){
        /* Informations de base de l'action */
    } else {
        /* Informations du profil du membre */
    }
}

View/Pages/home.ctp

<?php if(!$this->Auth->user('id')): ?>
    <!-- Informations de base de l'action Home -->
    <?php else: ?>
    <!-- Informations du profil du membre -->
<?php endif ?>

Pour simplifier au maximum ce que tu voudrais faire, c'est ceci (dans routes.php) :

if(!$this->Auth->user('id')):
    Router::connect('/', array('controller' => 'pages', 'action' => 'home'));
else:
    Router::connect('/', array('controller' => 'users', 'action' => 'home'));    
endif

Mais je ne crois pas que ce soit possible.

Une adresse URL n'est pas faite juste pour afficher des caractères aux visiteurs mais pour transmettre des informations au site WEB.

Pour gérer qui a accès à quoi, il te faut utiliser le AuthComponent. Pour limiter, donner accès, il y a les méthodes $this->Auth->allow('action1','action2') et $this->Auth->deny('action3','action4')et isAuthorized()

Pour ce qui est d'afficher une page différent selon que l'utilisateur est connecté ou non :

public function ma_homepage(){
    if(!$this->Auth->user('id')){
        $this->render('ma_homepage_avec_connection.ctp');
    }else{
        $this->render('ma_homepage_sans_connexion');
    }
}

dans la vue, tu accèdes au infos utilisateur via AuthComponent::user('username') , AuthComponent::user('ModelAssocie.name'), ...

Bonsoir.
@ amethyste : Tu n'as pas compris ce que j'ai voulu dire avec la phrase que tu as relevée et tu n'as pas non plus compris ce qu'il voulait faire.
Lui ce qu'il veut c'est que la racine de son site web puisse afficher deux action de deux controller différents, sans apporter de code de l'une ou l'autre fonction.
Alors au lieu de dire des bêtises parce que tu n'as pas compris ce que j'ai dit ou ce qu'il veut réellement, réfléchis bien avant de poster ton commentaire, surtout en utilisant des images externes qui n'ont rien à faire sur un forum comme celui-ci.

oulaaaa ... mais c'est qu'il va mordre !

Alors si je pige bien il y a deux trucs a faire:

(1) Limiter les accès si le user est pas loggé aux pages home , login , signup , et forgot. Je suppose que les 3 dernières pages ont leurs url respectives, et la première est celle sur laquelle on arrive en tapant http://www.exemple.com.

(2) Changer la page retournée pas cake lorsque le user demande http://www.exemple.com: S'il n'est pas loggé, ca doit être home, donc, mais s'il est loggé, ca doit être son profile. Je comprends aussi que tu ne veux <u>pas de redirect</u> (ce que je ne m'explique pas mais bon ...), et j'imagine que les pages home et profile doivent être accessibles également a partir de leurs propres url

Encore une fois je ne connais pas cake, et je fait confiance a certains pour me le dire si je dis une anerie ^^, mais:

(1) Limiter les accès en fonction de loggé / pas loggé, je pense pas que ce soit compliqué. Je sais bien que cakePHP n'arrive pas a la cheville de symfony2 (clin d’œil amical a mon copain qui se reconnaitra ;) ...), mais ça, au moins, j'imagine que c'est possible.

(2) Pour le second point, il semble juste qu'il faille déléguer la réponse du controller / action appelé par la requête http://www.exemple.com a un autre couple controller/action. Il faut donc que tu créés:

  • le couple controller/action qui correspond a la route http://www.exemple.com/home (controller = Pages, action = home)
  • le couple controller/action qui correspond a la route http://www.exemple.com/profile (controller = Users, action = home)
    Puis, depuis ton controller appelé par la route http://www.exemple.com, faire le truc suivant:

    $this->autoRender = false;
    $d = new Dispatcher();
    if( !$this->Auth->loggedIn() )
    $d->dispatch( array("controller" => "Pages", "action" => "home") );
    else
    $d->dispatch( array("controller" => "Users", "action" => "home") );

Il semble que cela aurait pour effet de déléguer la réponse a une autre action d'un autre controller, sans utiliser de redirect ...

SOURCE

(tadaaaaam ?)

Bon après je veux pas remuer le couteau dans la plaie, mais sous symfony2 il n'y a qu'a utiliser la fonction forward() a l’intérieur d'une action pour transférer la requête http a un controller/action différent en interne, sans redirect ...

Bonsoir.
Sauf que lui veut juste l'URL de base dans les deux cas (http://exemple.com), il ne veut ni home, ni profile dans l'URL, ou quoi que ce soit.
Je ne veux pas dire que c'est impossible de garder uniquement la racine du site web dans l'URL pour les deux actions, mais lui voudrait ne pas avoir à modifier une des deux actions des controllers concernés.
Par contre, faire ça sur la racine du site web, implique que seule la page du profil de l'utilisateur sera affichée sur la racine de celui-ci et donc plus de réelle page d'accueil du site lorsqu'il est connecté.

C'est bien ce que j'avais compris.

Du coup je pensais que dans l'action qui est appelé par http://exemple.com tu pouvais faire une redirection interne vers une autre action, d'un autre controller (donc pas de changement d'url comme avec un redirect classic) avec la méthode dispatch() de l'objet Dispatcher (c'est d'ailleurs cet objet qui est instancié pour le premier appel a une action a partir de l'url demandée, si je ne me plante pas).
Si tu ajoutes les conditions qui vérifie que le user est loggé ou pas, du peux bien rediriger vers l'une ou l'autre des actions que tu veux.

En parallèle de cela, ces actions peuvent être aussi appelées par les routes que tu veux, non ? Donc tu as une redirection interne si tu demandes http://exemple.com, et si tu veux demander explicitement cette page tu peux utiliser http://exemple.com/home, par exemple.

En résumé: j'avais compris que ...

Dispatcher::dispatch( array( "controller" => "monController", "action" => "monAction") )

... permettait une redirection interne sans changement d'url, mais si tu me dis que non je n'insiste pas, il est bien évident que je ne mets pas en doute ta connaissance de cake.