PHP|Débutant :: Forums

Advertisement

Besoin d'aide ? N'hésitez pas, mais respectez les règles

Vous n'êtes pas identifié(e).

#1 Re : Forum Général PHP » [MVC] inclure une vue dans une autre? » 17-12-2013 00:05:24

Le soucis, c'est que la variable $posts(de /posts/index.php) est construite depuis le contrôleur PostsController, et qu'elle est transmise à la vue index.php, d'où l’impossibilité de récupérer la variable $posts dans une vue autre que celle de son contrôleur/action.

Il faudrait que je puisse créer une méthode qui gère la construction de la variable $posts dans une "super class" dont héritera les controlleurs PostsController et PagesController, mais je ne sais pas comment faire...

Que ce soit pour PostsController ou PagesController, les 2 extends de d'un fichier Controller
Je peux donc envisager de déclarer $posts dans ce fichier Controller.php ?
Je ne sais pas, je suis complètement paumée dans ce soucis, au plus je fais des tests, au plus je me paume...

Pour info, voici le contenu de PostsController: (je n'ai copié que les fonctions pertinentes)


<?php
class PostsController extends Controller{
 
  /**
  * Blog, liste les articles
  **/
  function index(){
    $perPage = 10;
    $this->loadModel('Post');
    $condition = array('online' => 1,'type'=>'post');
    $d['posts'] = $this->Post->find(array(
      'conditions' => $condition,
      'fields'     => 'Post.id,Post.name,Post.slug,Post.created,Category.name as catname,Post.content,Category.slug as catslug',
      'order'      => 'created DESC',
      'limit'      => ($perPage*($this->request->page-1)).','.$perPage,
      'join'       => array('categories as Category'=>'Category.id=Post.category_id')
    ));
    $d['total'] = $this->Post->findCount($condition);
    $d['page'] = ceil($d['total'] / $perPage);
    $this->set($d);
  }

  /**
  * Permet d'afficher les posts d'une catégorie
  **/
  function category($slug){
    $this->loadModel('Category');
    $category = $this->Category->findFirst(array(
      'conditions' => array('slug' => $slug),
      'fields'     => 'id,name'
    ));
    if(empty($category)){
      $this->e404();
    }
    $perPage = 10;
    $this->loadModel('Post');
    $condition = array('online' => 1,'type'=>'post','category_id' => $category->id);
    $d['posts'] = $this->Post->find(array(
      'conditions' => $condition,
      'fields'     => 'Post.id,Post.name,Post.slug,Post.created,Category.name as catname,Post.content,Category.slug as catslug',
      'order'      => 'created DESC',
      'limit'      => ($perPage*($this->request->page-1)).','.$perPage,
      'join'       => array('categories as Category'=>'Category.id=Post.category_id')
    ));
    $d['total'] = $this->Post->findCount($condition);
    $d['page'] = ceil($d['total'] / $perPage);
    $d['title'] = 'Tous les articles "'.$category->name.'"';
    $this->set($d);
    // Le système est le même que la page index alors on rend la vue Index
    $this->render('index');
  }

  /**
  * Affiche un article en particulier
  **/
  function view($id,$slug){
    $this->loadModel('Post');
    $d['post']  = $this->Post->findFirst(array(
      'fields'   => 'Post.id,Post.content,Post.name,Post.slug,Category.name as catname,Category.slug as catslug',
      'conditions' => array('Post.online' => 1,'Post.id'=>$id,'Post.type'=>'post'),
      'join'     => array('categories as Category'=>'Category.id=Post.category_id')
    ));
    if(empty($d['post'])){
      $this->e404('Page introuvable');
    }
    if($slug != $d['post']->slug){
      $this->redirect("posts/view/id:$id/slug:".$d['post']->slug,301);
    }
    $this->set($d);
  }
}
 

Et voici mon fichier Controller.php:


<?php
class Controller{
 
  public $request;    
  private $vars     = array();  
  public $layout    = 'default';    
  private $rendered = false;  

  function __construct($request = null){
    $this->Session = new Session();
    $this->Form = new Form($this);

    if($request){
      $this->request = $request;  // On stock la request dans l'instance 
      require ROOT.DS.'config'.DS.'hook.php';    
    }
   
  }

  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();
    require($view);
    $content_for_layout = ob_get_clean();  
    require ROOT.DS.'view'.DS.'layout'.DS.$this->layout.'.php';
    $this->rendered = true;
  }

  public function set($key,$value=null){
    if(is_array($key)){
      $this->vars += $key;
    }else{
      $this->vars[$key] = $value;
    }
  }

  function loadModel($name){
    if(!isset($this->$name)){
      $file = ROOT.DS.'model'.DS.$name.'.php';
      require_once($file);
      $this->$name = new $name();
      if(isset($this->Form)){
        $this->$name->Form = $this->Form;  
      }
    }

  }

  function e404($message){ 
    header("HTTP/1.0 404 Not Found");
    $this->set('message',$message);
    $this->render('/errors/404');
    die();
  }

  function request($controller,$action, $params = null){
    $controller .= 'Controller';
    require_once ROOT.DS.'controller'.DS.$controller.'.php';
    $c = new $controller();
    return $c->$action();
  }

  function redirect($url,$code = null ){
    if($code == 301){
      header("HTTP/1.1 301 Moved Permanently");
    }
    header("Location: ".Router::url($url));
  }


}
?>
 

Merci de votre aide, je suis perdue lol

#2 Re : Forum Général PHP » [MVC] inclure une vue dans une autre? » 17-12-2013 00:05:24

Bon, alors je ne sais pas si je suis dans le bon, j'ai cherché dans les messages récents du forum sans succès, mais j'ai trouvé ceci: developpez.com
J'ai donc modifier mon includes, et j'ai fait ceci:


<?php
  if ($page->id == 1){
    include_once(dirname(__DIR__) .'/posts/index.php');
  }
?>
 

Pour information, voici ce que contient le fichier /view/posts/index.php que je tente d'inclure:

<div>
  <div class="row">
    <div class="span13">
      <div class="page-header">
        <h1><?php echo isset($title)?$title:'Le blog'; ?></h1>
      </div>
      <?php foreach ($posts as $k => $v): ?>
        <div class="clearfix">
          <h3><?php echo $v->name; ?></h3>
          <?php echo substr(strip_tags($v->content),0,300); ?>...
        </div>
        <p style="text-align:right"><a href="<?php echo Router::url("posts/view/id:{$v->id}/slug:$v->slug"); ?>">Lire la suite &rarr;</a></p>
        <p>&nbsp;</p>
      <?php endforeach ?>

      <div class="pagination">
        <ul>
          <?php for($i=1; $i <= $page; $i++): ?>
            <li <?php if($i==$this->request->page) echo 'class="active"'; ?>><a href="?page=<?php echo $i; ?>"><?php echo $i; ?></a></li>
          <?php endfor; ?>
        </ul>
      </div>
    </div>
    <!-- INCLUSION SIDEBAR
      <?php require('sidebar.php'); ?>
    -->
  </div>
</div>

Mon inclusion "fonctionne" puisqu'elle affiche ce qui est en statique, mais pour le reste j'ai quelques erreurs:

Undefined variable: posts et Invalid argument supplied for foreach() in... pour la ligne

<?php foreach ($posts as $k => $v): ?>

et 2 erreurs Object of class stdClass could not be converted to int in... pour cette ligne:

<?php for($i=1; $i <= $page; $i++): ?>

Je précise que ce fichier à inclure, il fonctionne sans erreur si j'y accède via sur url propre.
Je sais pas, je suis un peu paumée je crois, l'erreur peu venir de pas mal de trucs: mes redirections, mes htaccess peut être?

Pas le choix je dois trouver une solution, mon projet est lancé lol

#3 Re : Forum Général PHP » [MVC] inclure une vue dans une autre? » 17-12-2013 00:05:24

OK, merci à vous d'avoir pris la peine de me répondre, c'est très aimable. smile
Je vais visiter le forum à la recherche des chemins d'accès, et je reviendrai ici si j'ai une question/interrogation à ce sujet.

En attendant, bon à vous week-end également

Cordialement

#4 Forum Général PHP » [MVC] inclure une vue dans une autre? » 17-12-2013 00:05:24

caema
Réponses : 6

Bonjour à tous,

J'ai conçu un MVC en suivant le tuto du site MVC Grafikart.
Tout fonctionne bien, j'ai réalisé le tuto jusqu'au bout.

La question que je me pose concerne la page d'accueil de mon site.
Actuellement elle est gérée comme toutes les autres pages, pourtant c'est une page un peu "spéciale": je souhaite en effet qu'elle contienne un div reprenant les dernières news.
Ces news, je les gère déjà via un controller PostsController, et une vue index.php.
En gros, j'ai donc cette arborescence:

/controller
    * PagesController.php
    * PostsController.php

/view
    /pages
        * view.php
    /posts
        * index.php

Mon idée de départ, c'était de mettre ceci dans view.php:


<?php
  if ($page->id == 1){
    include_once('posts/index.php');
  }
?>
 

et donc d'inclure une vue, dans une autre vue.
Mais ce semble pas fonctionner puisque j'ai 2 erreurs:

Warning: include_once(posts/index.php): failed to open stream: No such file or directory in ....
Warning: include_once(): Failed opening 'posts/index.php' for inclusion (include_path='.;C:\wamp\bin\php\php5.4.16\pear;') in ...

Ma question est donc, en MVC, est-il possible d'inclure une vue dans une autre vue?
Et si non, comment raisonner pour résoudre mon problème?


D'avance merci!

#5 Forum Général PHP » Affichage d'un sous menu dynamique: problème conception d'un foreach? » 27-11-2013 09:48:58

caema
Réponses : 2

Bonjour à tous,

Pour les besoin d'une formation, j'ai réalisé un site en MVC et POO.
Je suis en train d'essayer d'améliorer ce site, afin de bosser un peu mes compétences, et je commence à sécher en ce qui concerne l'affichage de mon sous menu...

Voici le menu, en statique, tel que je souhaite le réaliser (ce code est fonctionnel):


<div class="navbar-collapse collapse">
     <ul class="nav navbar-nav">
         <li class="active"><a href="#">Item 1</a></li>
         <li><a href="#">Item 2</a></li>
         <!-- Sub menu -->
    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown">Item 3 <b class="caret"></b></a>
                          <ul class="dropdown-menu">
                          <li><a href="#">Submenu 1</a></li>
              <li><a href="#">Submenu 2</a></li>
              <li><a href="#">Submenu 3</a></li>
         </ul>
              </li>
         <li><a href="#">Item 4</a></li>
      /ul>
</div>
 

Ensuite, voilà comment j'ai imaginé rendre ce menu dynamique:

Au niveau de ma base de données, j'ai un champ id_post, qui est en clé étrangère et qui référence le champ id de la table posts. Ainsi, les élément qui correspondent bien au menu ont un id_posts null, et les élément correspondant au sous menu ont un id_posts valant 3, liant donc à l'id 3 de ma table.

Ensuite, dans le fichier qui doit rendre mon menu, actuellement j'ai ceci:


<ul class="nav navbar-nav">
    <!-- MENU -->
    <?php $pagesMenu = $this->request('Pages','getMenu'); ?>
    <?php foreach($pagesMenu as $p): ?>
           <li><a href="<?php echo Router::url('pages/view/id:'.$p->id.'/slug:'.$p->slug); ?>" title="<?php echo $p->name; ?>"><?php echo $p->name; ?></a></li>
    <?php endforeach; ?>
                       
     <!-- SOUS_MENU -->
     <?php $pagesMenu = $this->request('Pages','getSubMenu'); ?>
     <?php foreach($pagesMenu as $p): ?>
             <li class="dropdown">
                   <a class="dropdown-toggle" data-toggle="dropdown" href="<?php echo Router::url('pages/view/id:'.$p->id.'/slug:'.$p->slug); ?>" title="<?php echo $p->name; ?>"><?php echo $p->name; ?></a>
                   <ul class="dropdown-menu">
                         <li><a href="<?php echo Router::url('pages/view/id:'.$p->id.'/slug:'.$p->slug); ?>"><?php echo $p->name; ?></a></li>
                    </ul>
              </li>
      <?php endforeach; ?>
</ul>
 

Le résultat: tous les éléments correspondant au menu apparaissent, et à la suite, j'ai les éléments de mon sous-menu.
C'est déjà pas mal, ça prouve que mes requêtes sql sont correctes.

Le soucis, c'est que je souhaite que les éléments de mon sous-menu s'affichent sous l’élément de menu item 3... et ça n'est pas le cas.

Je comprends bien que le soucis se situe au niveau de mes boucles foreach, je suppose d'ailleurs (arrêter moi si je me trompe), que la boucle foreach qui traite le sous menu doit être imbriquée dans la boucle foreach de traitement du menu mais je n'arrive pas à la construire correctement, pour tout dire je suis un peu perdue...
Je planche sur ce soucis depuis quelques jours, sans succès..

J'espère de tout cœur avoir été suffisamment claire, si ça n'est pas le cas, n'hésitez pas à demander, en tout cas j'ai besoin d'aide, car à force... j'ai juste envie de prendre mon PC et de le balancer par la fenêtre lol.

D'avance merci!

Pied de page des forums

Propulsé par FluxBB