Bonjour
j’aimerais savoir si c'est possible d'inclure deux fonction afterFind dans un model?
si oui comment le faire?
sinon ce n'est le cas comment remédier?
merci

30 réponses


Kareylo
Réponse acceptée

Donc, il faut que tu changes ta route qui pointe vers follow :

Router::connect('/users/follow/:id-:slug.html',array('controller'=>'users','action'=>'follow'),array(
    'pass'=>array('id', 'slug'),
    'id'=> '[0-9]+',
    'slug'=>'[a-z0-9]+'
));

et dans le model, ajouter la ligne du slug dans le tableau d'index 'follow'.

$s'User']'follow'] = array(
                    'controller' => 'Users',
                    'action' => 'follow',
                    'slug' => $s'User']'slug'],
                    'id' => $s'User']'id']
                 );

Ensuite, dans ta vue, à la place de ton image :

$this->Html->link($this->Html->image('suivreeglise.png'), $user'User']'follow'], array('escape' => false));

Et ça devrait fonctionner

Si c'est à ce que je penses, as-tu essayé de debugué $results ?

Exemple de "multi afterFind"

foreach($results as $k => $result){
    if(isset($result'Post'])){
    // Ton code pour la partie "post"
        $results$k]'Post'] = $result'Post'];
    }
    if(isset($result'Category'])){
        // Ton code pour la partie "category"
        $results$k]'Category'] = $result'Category'];
    }
    // etc...
    return $results;
}
wenz
Auteur

ça ne donne rien, voici mon code afterFind

public function afterFind($data,$primary=false)
    {
        foreach($data as &$s)
        {
            if(isset($s'User']'id']) && isset($s'User']'nom']))
            {
                $s'User']'slug'] = Inflector::slug(strtolower($s'User']'nom']), '-');
                $s'User']'link'] = array(
                    'controller' => 'Users',
                    'action' => 'view',
                    'slug' => $s'User']'slug'],
                    'id' => $s'User']'id'],
                    'ext' => 'html',
                 );
}
              if(isset($s'User']'id']) && isset($s'User']'nom']))
            {
                $s'User']'slug'] = Inflector::slug(strtolower($s'User']'nom']), '-');
                $s'User']'link'] = array(
                    'controller' => 'Users',
                    'action' => 'follow',
                    'slug' => $s'User']'slug'],
                    'id' => $s'User']'id'],
                    'ext' => 'html',
                 );

            }

        }
        return $data;
        debug($data);

    }

Tes conditions sont identiques. Mais si j'ai bien compris ce que tu veux faire, pourquoi tu n'as pas pensé à faire deux index différents ?
Et de plus, ton debug après le return, il sert à rien, il faut le mettre avant, sinon, il ne sera jamais appelé

public function afterFind($data,$primary=false)
    {
        debug($data); //Pour voir à quoi ressemble tes données récupérées
        foreach($data as &$s)
        {
            if(isset($s'User']'id']) && isset($s'User']'nom']))
            {
                $s'User']'slug'] = Inflector::slug(strtolower($s'User']'nom']), '-');
                $s'User']'link'] = array(
                    'controller' => 'Users',
                    'action' => 'view',
                    'slug' => $s'User']'slug'],
                    'id' => $s'User']'id'],
                    'ext' => 'html',
                 );
                $s'User']'follow'] = array(
                    'controller' => 'Users',
                    'action' => 'follow',
                    'slug' => $s'User']'slug'],
                    'id' => $s'User']'id'],
                    'ext' => 'html',
                 );    
            }
        }
        debug($data); // Pour voir à quoi ressemble tes données finales
        return $data;      
    }
wenz
Auteur

desolé c'est une erreur de ma part,comment deux index différents ce n'est pas pour la même vue, l'un c'est pour la view et l'autre pour la vue follow, oubien c'est moi qui te saisi mal?

Salut, pourrais-je savoir pourquoi 2 afterFind ? personnellement j'pense qu'il y a une solution si y a besoin d'utiliser deux afterFind.

Cordialement.

wenz
Auteur

bonsoir freezlike je voudrais avoir une url de se genre:http://localhost/test/users/follow/2-liste.html, c'est avoir l'id du user dans l'url.
merci

Pourquoi deux index ? Car il n'y a pas moyen de récupérer l'action dans le model (Je me suis amusé à "var_dump($this); die;" pour voir si on le récupérait), donc, c'est le seul moyen que j'ai trouvé pour résoudre ton problème. J'avoue, c'est pas ultra propre comme solution, mais ça devrait fonctionner.

Dans le pire des cas, tu pourrais aussi créer un helper ou un behaior pour plus de flexibilité.

wenz
Auteur

ok explique moi ta procédé de deux index stp.
merci

euh pour l’extension dans l'afterFind tu t'en passe
dans tu passe par routes.php
pour faire

Router::connect('/users/follow/:id-liste.html',array('controller'=>'users','action'=>'follow'),array(
    'pass'=>array('id'),
    'id'=> '[0-9]+'
));

dans ton model

function afterFind($results, $primary = false) {
        parent::afterFind($results, $primary);
        foreach ($results as $k => $d) {
            if (isset($d'User']'id']) && isset($d'Post']'nom'])) {
                $d'User']'link'] = array(
                    'controller' => 'Users',
                    'action' => 'follow',
                    'id' => $d'User']'id']
                );
                $results$k] = $d;
            }
        }
        return $results;
    }

ps : cette afterFind te rajoute un tableau pour avoir un lien comme tes dires

dans ce sens là
http://localhost/test/users/follow/2-liste.html

Cordialement.

wenz
Auteur

merci freezlik pour ta réponse, mais on se comprends pas: au premier à bord dans mon model User il y a un afterFind qui oriente pour la vue view et me donne un lien du genre http://localhost/test/users/2-slug.html
maintenant je voudrais faire un lien vers un vue (follow) en cliquant sur un bouton qui se trouve dans sur la page( http://localhost/test/users/2-slug.html)et j'aimerais que l'url de cette page soit par exemple http://localhost/test/users/follow/2-liste.html.
c'est pour cette raison je voudrais créer le deuxième afterFind.
merci

Suite à ton dernier message :

public function afterFind($data,$primary=false)
    {
        foreach($data as &$s)
        {
            if(isset($s'User']'id']) && isset($s'User']'nom']))
            {
                $s'User']'slug'] = Inflector::slug(strtolower($s'User']'nom']), '-');

                // Création de l'index 'link' pour avoir le lien vers l'action 'view'.
                $s'User']'link'] = array(
                    'controller' => 'Users',
                    'action' => 'view',
                    'slug' => $s'User']'slug'],
                    'id' => $s'User']'id']
                 );

                // Création de l'index 'follow' pour avoir le lien vers l'action 'follow'.
                $s'User']'follow'] = array(
                    'controller' => 'Users',
                    'action' => 'follow',
                    'id' => $s'User']'id']
                 );   
            }
        }
        return $data;     
    }

et dans routes.php

Router::connect('/users/:id-:slug.html',array('controller'=>'users','action'=>'view'),array(
    'pass'=>array('id', 'slug'),
    'id'=> '[0-9]+',
    'slug'=>'[a-z0-9]+'
));
Router::connect('/users/follow/:id-liste.html',array('controller'=>'users','action'=>'follow'),array(
    'pass'=>array('id'),
    'id'=> '[0-9]+'
));

je t'en prie,
et bien c'est confus pour moi si j'étais à coté je serais en mesure de t'aider parce que là attends si j'ai bien compris là ton premier afterFind donc ça va on est tout bon ! dans la page du user que tu va follow tu veux avoir l'id encore pour passer à l'action follow sous un lien comme le tien l'id de ce user via le premier lien c'est ça en gros ?

Et dans ta vue http://localhost/test/users/2-slug.html, tu n'as plus qu'à utiliser

$this->Html->link('S\'abonner', $d'user']'follow']);

j'crois que Kareylo à compris la même chose que moi si c'est ça que tu need problème résolu pour moi :)

wenz
Auteur

freezlike oui c'est ce que je veux

wenz
Auteur

Kareylo merci pour ta réponse mais dans ton code :

$this->Html->link('S\'abonner', $d'user']'follow']);

, $d représente quoi stp

Les données que tu $this->set() dans ton controller.

wenz
Auteur

j'ai une erreur : Notice (8): Undefined variable: d [APP\View\Users\view.ctp, line 67]

wenz
Auteur

voici le controller qui gère ma vue:

public function view($id, $slug)
    {   
       $this->loadModel('Event');
       $user = $this->User->find('first',
         array(

           'conditions' => array('id'=>$id),
           'recursive' => 0
           ));
         debug($user);
        if($slug != $user'User']'slug'])

        $this->redirect($user'User']'link'], 301);
        $this->set('user',$user);

    $event=$this->Event->find('all', 
    array(
      'conditions'=> array('user_id'=>$id)));

       $this->set('event',$event);

    }

$d est $event, sans ton cas.

wenz
Auteur

j'ai pas compri comment $d doit être $event,
$event c'est pour avoir tous les event de l'user ça n'a rien à avoir avec le bouton follow et je fais find first pour avoir accès les données qui correspondent à user_id.
merci

wenz
Auteur

je vais mettre le site en ligne là tu vas tester toi même.

Ah, zut, je me suis trompé. C'est $user, pas $event. Désolé de ma bête erreur

wenz
Auteur

voici l'adresse du site :http://adenka-lawyers.com/egliz/
Quand on clique sur la petite photo en bas on va sur la page de User avec le lien egliz/users/74-main-de-dieu-vivant.html
sur cette page l'image (suivez-nous)nous permet d'avoir accès à la deuxième page(follow) dont l'url doit être de ce egliz/users/follow/74-main-de-dieu-vivant.html.

je ne sais pas si j'ai bien expliqué.
merci pour votre disponibilité et votre attention

à mon avis pour ne pas te compliquer la vie c'est un peu louche comme méthode j'avoue mais tu peut faire une condition sur le

$this->here;

normalement dans ton cas tu as comme retour la chaîne '/egliz/users/74-main-de-dieu-vivant.html' ou '/users/74-main-de-dieu-vivant.html'
mais dans le deux cas tu peut faire quelque chose comme ça

$urlUser = $this->Html->url($user'link']);
    if($this->here == $urlUser){
        $save = explode('/', $this->here);
        $item = $save[3];
        $save[3] = 'follow';
        $save[4] = $item;
        $newLink = '/' .$save[1] . '/' . $save[2]. '/' . $save[3]. '/' . $save[4];
        debug($newLink);
    }

j'sais c'est pas très propre mais ça te permet d'avoir la new URL avec un petit script et si une fois ton projet terminé tu peut y retourné pour trouver une meilleure solution pour améliorer ton appli.

Cordialement.

wenz
Auteur

merci pour votre disponibilité, merci bcp
ça marche

De rien, content d'avoir pu t'aider.

Bonjour

Moi aussi j'ai un problème similaire que j'ai du mal à comprendre pour afterFind

ca c'est mon model

<?php
class Post extends AppModel{
    public function afterFind($data){
    foreach($data as $k=>$d){
    if (isset($d'Post']'slug']) && isset($d'Post']'id'])){
      $d'Post']'link'] = array(
      'controller' => 'pages',
      'action' => 'show' ,
      'id' => $d'Post']'id'],
      'slug' => $d'Post']'slug']
        );
     }
     $data$k] = $d;
}
    debug($data);
    }
}

et ca mon menu.ctp

<?php $pages = $this->requestAction(array('controller'=>'pages','action'=>'menu'array('return')));?>
<ul class="nav navbar-nav">
    <?php foreach($pages as $k=>$v): $v = current($v);?>
    <li> <?php echo $this->Html->link($v'name'],$v'link']);?></li>
     <?php endforeach; ?>
  </ul>

J'ai ajouter au menu le array('return')

Je ne sais pas si cela à une influence mais mon menu se retrouve avec une seconde bar superposée de plus je suis en debug et il s'affiche derriere ma navbar alors qu'avant j'avais l'espace debug dessus et la barre dessous.

Désolé je débute et la j'ai un peu perdu le fil
comme la copie d'écran.