Bonjour,

J'ai fait un programme back-end avec :

une classe app\Controller\Account\DetailsController.php qui hérite de app\Controller\Account\AppController.php
héritant elle même de app\Controller\AppController.php qui hérite finalement de core\Controller\Controller.php

Dans app\Controller\Account\AppController.php, je teste si la personne est autorisée sinon elle est redirigée vers une page 401
Si elle est autorisée je déclare des variables

<?php

namespace App\Controller\Account;

use \App;

class AppController extends \App\Controller\AppController{

    protected $client_id;
    protected $client_role;
    protected $client_name;

    public function __construct(){

        parent::__construct();
            
        if(!$_SESSION['auth'])
            {
            $this->forbidden(); //Core/Controller
            }  
        else
            {
            $client_id = $_SESSION['auth'] ;
            $client_role = $_SESSION['role'];
            $client_name= $_SESSION['name'];

            $this->client_role = $client_role;
            $this->client_name = $client_name;
            } 

    }

}


Au niveau de sa classe fille je voudrai récupérer ces valeurs ($client_role et $client_name)

J'y arrive dans le construct mais pas au niveau des autres fonctions (ex Index) et je suis obligé à chaque fois de recréer une autre variable $name pour y arriver

use \App;

use Core\Controller\Controller;
use Core\Table\Table;
use Core\Database\MysqlDatabase;
use Core\Auth\DBAuth;
use Core\Search\Search;


class DetailsController extends AppController{

    public $client_role;
    public $client_name;

    public function __construct(){

        parent::__construct();

        $this->loadModel('Detail');

        $client_name=$this->client_name;
        var_dump($client_name);

                       
        }
    
    public function index(){

        $pageId=29;
        $page_required = $this->Detail->findPage2($pageId)  ;

        $level=$this->Detail->level($pageId);
        $level_id=$level->level;

        $name= $this->client_name;
        //var_dump($name);
                        
        if ($this->client_role > $level_id)
            {
            $this->habilitation();
            }
                 
        $account = $this->Detail->allById($_GET['id']);

        $this->render('account.details.index', compact('account','page_required','role','name'));
    }

Comment faire pour ne pas avoir à recréer cette variable $name

Merci de votre aide
Modifié par dudu22 (03 Sep 2020 - 13:06)
Modérateur
Et l'eau,

Suivant ce que tu dis, c'est louche puisqu'une class fille récupère les attributs parents ($this->client_name). Ensuite, dans ton code, on ne voit pas le tenant et l'aboutissant. Donc, je peux pas vraiment t'aider. Pour finir, l'héritage, c'est quelque chose de bien mais ça apporte son lot de problèmes. Donc, tes classes qui héritent de plusieurs parents, ça me parait suspect comme architecture....
Merci niuxe je t'avoue que c'est pas très clair lol

Mes classes n'héritent pas de plusieurs parents, il s'agit en fait d'une cascade de bas en haut

Dans mon programme en fonction du lien on détermine un controleur et une fonction

if(isset($_GET['p']))
	{
    $page = $_GET['p'];
	}
else
	{
    $page = 'sundries.index';
	}

$page = explode('.', $page);

//ON PREND COMME EXEMPLE account.details.index&id=4


if($page[0] == 'admin')
	{
    $controller = '\App\Controller\Admin\\' . ucfirst($page[1]) . 'Controller';
    $ref_page=$page[0].$page[1].$page[2];
    //$controller = new $controller();
    $action = $page[2];
	}
elseif($page[0] == 'account')
 	{
    // ucfirst($page[1]) CORRESPOND A details ET devient Details   
    $controller = '\App\Controller\Account\\' . ucfirst($page[1]) . 'Controller';
    $ref_page=$page[0].$page[1].$page[2];
    //$controller = new $controller($role=null,$name=null);
    $action = $page[2]; 
    }	
 else
 	{
    $controller = '\App\Controller\\' . ucfirst($page[0]) . 'Controller';
    //$ref_page=$page[1].$page[2];
    //$controller = new $controller();
    $action = $page[1]; /*ex Index*/
	}

$controller = new $controller();

//DEVIENT : $controller = new \App\Controller\Account\DetailsController

$controller->$action(); /*TRANSFORME ACTION PRECEDENT EN FONCTION EX FUNCTION INDEX*/


En étant sur la page

http://www.hervedunoyer.com/index.php?p=account.details.index&id=4

On a un controleur :

DetailsController.php

et une fonction index


public function index(){

        $pageId=29;
        $page_required = $this->Detail->findPage2($pageId)  ;

        $level=$this->Detail->level($pageId);
        $level_id=$level->level;

        $name= $this->getName();
        
        $role= $this->getRole();
                                
        if ($role > $level_id)
            {
            $this->habilitation();
            }
                 
        $account = $this->Detail->allById($_GET['id']);

        $this->render('account.details.index', compact('account','page_required','role','name'));
    }



J'ai modifié par rapport à ce qui est écrit précédemment au niveau de la classe mère


<?php

namespace App\Controller\Account;

use \App;

class AppController extends \App\Controller\AppController{

    protected $client_id;
    protected $client_role;
    protected $client_name;

    public function __construct(){

        parent::__construct();
            
        if(!$_SESSION['auth'])
            {
            $this->forbidden(); //Core/Controller
            }  
        else
            {
            $client_id = $_SESSION['auth'] ;
            $client_role = $_SESSION['role'];
            $client_name= $_SESSION['name'];

            $this->client_role = $client_role;
            $this->client_name = $client_name;
            } 


?>
        <!--<script type="text/javascript">
            setTimeout("window.location='index.php?p=clients.logout'","600000");//En MilliSecondes
        </script>-->

<?php  

    }

    public function getName(){
            return $this->client_name;
            }

    public function getRole(){
            return $this->client_role;
            }        
   
//FIN CLASSE
}


que je récupère dans ma fonction index

Cela fonctionne mais je ne sais pas si c'est correct.

Mon problème est que pour toutes les fonctions de ma classe je répète à chaque fois


$name= $this->getName();
        
        $role= $this->getRole();
                                
        if ($role > $level_id)
            {
            $this->habilitation();
            }


J'aimerai que cela soit fait une fois pour toute dans la classe mère par exemple ou au niveau du constructeur et ne pas à avoir à le répéter dans chaque fonction.

En plus comme tu peux le voir je répète aussi dans chaque fonction en fonction d'un $pageId qui me permet à partir d'une base de données de retrouver les informations de chaque page et de trouver le degré d'habilitation

J'aimerai donc factoriser cela mais je n'y arrive pas

J'espère que c'est un peu plus clair

Merci encore pour ton aide

Hervé
Salut,

Si je comprend bien, et pour dégrossir un peu,
dans DetailsController
$client_name=$this->client_name; fonctionne bien dans le constructeur
mais ton $client_name; de la classe courante est vide dans index() ?
Bonjour Jencal et merci pour ton intervention

J'ai modifié ma classe mère ainsi :


class AppController extends \App\Controller\AppController{

    protected $name;
    protected $role;

     public function __construct(){
 
        parent::__construct();
            
        if(!$_SESSION['auth'])
            {
            $this->forbidden(); //Core/Controller
            }  
        else
            {
            $this->role = $_SESSION['role'];
            $this->name = $_SESSION['name'];
          
            }
 //FIN CONSTRUCT           
    }
                
         
//FIN CLASSE
}


Ainsi que ma classe fille :


class DetailsController extends AppController{

    public function __construct(){
        parent::__construct();
        $this->loadModel('Detail');
    }
       
    public function index(){

        $pageId=29;

        $role= $this->role;
        $name= $this->name;
  
        $page_detail = $this->Detail->findPage2($pageId)  ; 

        $title=$page_detail->title;

        $level_id=$page_detail->level;
                 
       if ($role > $level_id)
            {
            $this->habilitation();
            }
                 
        $account = $this->Detail->allById($_GET['id']);


        $this->render('account.details.index', compact('account','title','role','name'));
    }


Je ne sais pas si cela est correct mais cela marche

Par contre ce que je souhaiterai faire c'est ne pas avoir à répéter pour chaque fonction la même chose :



       $pageId=29;
   
        $role= $this->role;
        $name= $this->name;
  
        $page_detail = $this->Detail->findPage2($pageId)  ; 

        $title=$page_detail->title;

        $level_id=$page_detail->level;
                 
       if ($role > $level_id)
            {
            $this->habilitation();
            }


Seul le numéro de page change

J'avais pensé à créer une classe pour cela ou une fonction (mais où la placer ?)

J'espère que c'est plus clair

Merci d'avance pour votre aide
Modifié par dudu22 (07 Sep 2020 - 20:03)
Modérateur
Hello,

J'ai pas pu te répondre avant. J'étais occupé.

Bon sinon, il y a pleins de choses qui ne vont pas. Vraisemblablement, je ne vois pas de class Routeur .... Je ne vois pas de class Request .... Ton pseudo routeur est mal développé... Tu ne sépares pas les différentes couches.... Aussi, tes variables page, ça veut rien dire....
php 5.x (de mémoire à vérifier l'ordre)

<?php
if(!empty($_GET['p'])){
    $page = $_GET['p'];
}else{
    $page = 'sundries.index';
}

list($action, $controller) = explode('.', $page);

echo $controller.'<br />'.$action;

?>

php 7.x

<?php
if(!empty($_GET['p'])){
    $page = $_GET['p'];
}else{
    $page = 'sundries.index';
}

[$controller, $action] = explode('.', $page);

echo $controller.'<br />'.$action;

?>

Tout ton if du dessous pour déterminer si tu es dans admin, account ou ailleurs, on s'en fout. Tu crées un controller où il y aura une (injection de) dépendance si besoin !

Pour le reste, tu hérites qui hérite, qui hérite et qui hérite, etc.... C'est pas la peine de faire des multiples héritages. Surtout que ça peut jouer des tours de conception. La preuve, tu as sûrement une collision de namespace et de class... (la class AppController qui hérite de AppController Smiley biggol ) L'héritage, c'est bien, mais en abuser, ça va juste te rendre ton code un enfer à maintenir.

Les règles primordiales dans le dev d'application : faire simple, lisible, explicite
Modifié par niuxe (10 Sep 2020 - 00:35)
Oui je suis d'accord avec toi index.php sert de pseudo routeur et c'est pas top

Pour les Controleur effectivement le même nom c'est source d'erreur

Pour créer un vrai router aurais tu un tuto à me conseiller.

Merci encore pour ton aide
Modérateur
Pas à ma connaissance. Le problème étant que ce serait long à t'expliquer. Pourquoi n'utilies tu pas un bon framwork : Laravel, Code Igniter (la version 4 est sortie cet été), Cakephp, etc..