Bonjour,
Je suis nouveau sur ce forum, veuillez m'excuser pour le retard de ce post. Merci d'avance.

Voila je rencontre un petit problème avec mon code.

Ce que je fais

Décrivez ici votre code ou ce que vous cherchez à faire
Je tiens à remercier tout le monde ici, j'ai suivi les tutos sur développer un site et créer le code en suivant les étapes, sauf je bloque sur la partie administration du site.

Entourez votre code pour bien le mettre en forme

( ! ) Notice: Undefined property: stdClass::$password in C:\wamp64\www\appDev\app1\controller\UsersController.php on line 9
Call Stack

Time Memory Function Location

1 0.0007 405480 {main}( ) ...\index.php:0
2 0.0027 415768 Dispatcher->__construct( ) ...\index.php:11
3 0.0037 419496 UsersController->login( ) ...\Dispatcher.php:20

( ! ) Notice: Undefined property: stdClass::$login in C:\wamp64\www\appDev\app1\controller\UsersController.php on line 12
Call Stack

Time Memory Function Location

1 0.0007 405480 {main}( ) ...\index.php:0
2 0.0027 415768 Dispatcher->__construct( ) ...\index.php:11

Cette érreur s'affiche après avoir rentré le couple identifiant de la base de donnée

Ce que je veux

Voici le code des pages qui se sont ajoutés
Le fonction find du Model principale

" public function find($req = array()){
$sql = 'SELECT ';

    if(isset($req['fields'])){
        if(is_array($req['fields'])){
            $sql .= implode(', ',$$req['fields']);
        }else{
            $sql .= $req['fields'];
        }
    }else{
        $sql .= '*';
    }
    $sql .= ' FROM '.$this->table.' as '.get_class($this).' ';

    // Construction de la condition
    if(isset($req['conditions'])){
        $sql .= 'WHERE ';
        if(!is_array($req['conditions'])){
            $sql .= $req['conditions'];
        }else{
            $cond = array();
            foreach ($req['conditions'] as $k => $v){
                // code à executer
                if(!is_numeric($v)){
                    $v = '"'.addslashes($v).'"';//mysql_real_escape_string($v)= '"'.addslashes($v).'"';
                }
                $cond[] = "$k=$v";
            }
            $sql .= implode(' AND ',$cond);
        }
    }

    if(isset($req['order'])){
        $sql .= ' ORDER BY '.$req['order'];
    }
    // Construction de la limt
    if(isset($req['limit'])){
        $sql .= ' LIMIT '.$req['limit'];
    }
    $pre = $this->db->prepare($sql);
    $pre->execute();
    return $pre->fetchAll(PDO::FETCH_OBJ);
}

"

Ce que j'obtiens

J'obtiens au finale une erreur stdClass.

Que puis-je faire pour resoudre ce problème? Merci d'avance. Thomassam!

12 réponses


Bonsoir,
Il nous faudrais le code de la view 'users/login.php' et le la méthode login du UserController
Merci

thomasam
Auteur

Bjr Carouge10 et Merci, je vous transmets les codes.

<?php 
class User extends Model{

    var $validate = array(
        'login' => array(
            'alphaNumeric' => array(
                'rule' => 'notEmpty',
                'required' => true,
                'message' => 'Chiffres et lettres uniquement !'
            ),
            'between' => array(
                'rule' => array('lengthBetween', 5, 15),
                'message' => 'Entre 5 et 15 caractères'
            )
        ),
        'password' => array(
            'rule' => array('minLength', '4'),
            'message' => '4 caractères minimum'
        )
    );
}

et

<?php 
class UsersController extends Controller{
    /**
     * Login
     */
    function login(){
        if($this->request->data){
            $data = $this->request->data;
            $data->password = sha1($data->password);
            $this->loadModel('User');
            $user = $this->User->findFirst(array(
                'conditions' => array('login' => $data->login,'password' => $data->password)
            ));
            if(!empty($user)){
                $this->Session->write('User',$user);
            }
            $this->request->data->password = '';
        }
        if($this->Session->isLogged()){
            if($this->Session->user('role') == 'admin'){
                $this->redirect('cockpit');

            }else{
                $this->redirect('');
            }
        }

    }
<!DOCTYPE html>
<html lang="fr">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title><?php echo isset($title_for_layout)?$title_for_layout: 'Mon site' ; ?></title>

    <!-- Bootstrap -->
    <link href="<?php echo Router::webroot('css/bootstrap.css'); ?>" rel="stylesheet">
  </head>
  <body>

        <nav class="navbar navbar-inverse">
          <div class="container">
            <div class="navbar-header">
              <a class="navbar-brand" href="#">DLMA</a>
            </div>
            <div id="navbar" class="collapse navbar-collapse">
              <ul class="nav navbar-nav">
                  <?php $pagesMenu = $this->request('Pages','getMenu'); ?>
                  <?php foreach ($pagesMenu as $p): ?>
                    <li><a href="<?php echo BASE_URL.'/pages/view/'.$p->id; ?>" title="<?php echo $p->name; ?>"><?php echo $p->name; ?></a></li> 
                  <?php endforeach; ?>
            <ul class="nav navbar-nav navbar-right">
              <li><a href="<?php echo Router::url('posts/index') ;?>">Actualité</a></li>
            </ul>
              </ul>
            <ul class="nav navbar-nav navbar-right">
              <li><a href="<?php echo Router::url('users/login'); ?>">Se connecter</a></li>
            </ul>
            </div><!--/.nav-collapse -->
          </div>
        </nav>        

        <div class="container" style="padding-top: 60px; ">

          <?php echo $this->Session->flash(); ?>
          <?php echo $content_for_layout; ?>
        </div>

  </body>
  <script type="text/javascript" src="<?php echo Router::webroot('js/jquery-1.8.3.js'); ?>"></script>

  <p></p>
</html>

Puis le controller post

<?php 
class Post extends Model{

    function validates($data){
        $errors = array();
        foreach($this->validate as $k=>$v){
                if(!isset($data->$k)){
                    $errors[$k] = $v['message'];
                }else{
                    if($v['rule'] == 'notEmpty'){
                        if(empty($data->$k)){
                            $errors[$k] = $v['message'];
                        }
                    }elseif(!preg_match('/^'.$v['rule'].'$/',$data->$k)){
                        $errors[$k] = $v['message'];
                    }
                }
        }
        $this->errors = $errors;
        if(isset($this->Form)){
            $this->Form->errors = $errors;
        }
        if(empty($errors)){
            return true;
        }
        return false;
    }

    var $validate = array(
        'name' => array(
            'rule' => 'notEmpty',
            'message' => 'Vous devez préciser un titre'
        ),
        'slug' => array(
            'rule' => '([a-z0-9\-]+)',
            'message' => "L'url n'est pas valide"
        )
    );

}

Merci.

Je n'ai pas la vue du login (formulaire pour se loger) et que donne un var_dump($data) dans la méthode login ?

thomasam
Auteur

Bonjour à tous,
pour le formulaire, voici et la page

<div class="page-header">
    <h1>Zone réservée</h1>
</div>
<div class="container">
<form class="form-signin" action="<?php echo router::url('users/login'); ?>" method="post">
  <h2 class="form-signin-heading">Veuillez vous identifier</h2>
    <?php echo $this->Form->input('login','Indentifiant'); ?><br />
    <?php echo $this->Form->input('password','Mot de passe',array('type'=>'password')); ?><br />
  <!--<div class="checkbox">
    <label>
      <input type="checkbox" value="remember-me"> Se souvenir de moi
    </label>
  </div> -->
  <button class="btn btn btn-primary " type="submit">Se connecter</button>
</form>

et le helper form dans le core

<?php 
class Form{
    public $controller;
    public $errors;

    public function __construct($controller){
        $this->controller = $controller;
    }

    public function input($name,$label,$options = array()){
        $error = false;
        $classError = '';
        if(isset($this->errors[$name])){
            $error = $this->errors[$name];
            $classError = ' error';
        }
        if(!isset($this->controller->request->data->$name)){
            $value = '';
        }else{
            $value = $this->controller->request->data->$name;
        }
        if($label == 'hidden'){
            return '<input type="hidden" name="'.$name.'" value="'.$value.'">';
        }
        $html =  '<div class="clearfix'.$classError.'">
                    <label  for="input'.$name.'">'.$label.'</label>  
                    <div class="input">';
        $attr = ' ';
        foreach($options as $k=>$v){ if($k!='type'){
            $attr .= " $k=\"$v\"";
        }}            
        if(!isset($options['type'])){
            $html .= '<input type="text" class="form-control" id="input'.$name.'" name="'.$name.'" value="'.$value.'"'.$attr.'>';
        }elseif($options['type'] == 'textarea'){
            $html .= '<textarea id="input'.$name.'" name="'.$name.'"'.$attr.'>'.$value.'</textarea>';
        }elseif($options['type'] == 'checkbox'){
            $html .= '<input type="hidden" name="'.$name.'" value="0"><input type="checkbox" name="'.$name.'" value="1" '.(empty($value)?'':'checked').'>';
        }elseif ($options['type'] == 'file'){
            $html .= '<input type="file"  id="input'.$name.'" name="'.$name.'"'.$attr.'/>';
        }elseif ($options['type'] == 'password'){
            $html .= '<input type="password" class="form-control" id="input'.$name.'" name"'.$name.'" value="'.$value.'"'.$attr.'>';
        }   
        if($error){
            $html .= '<span class="help-inline">'.$error.'</span>';
        }     
        $html .= '</div></div>'; 
        return $html;
    }

}

J'ai essayé de debuger data, la classe me renvoie un tableau vide.

Salut,
en faisant un var_dump($this->request->data), ça te renvoie des données ?

peut-être que c'est pas lié mais dans ta page login ton router est différent des autres le "r" n'est pas en majuscul.

ce format "action="<?php echo router::url('users/login'); ?>"" n'est pas obligatoire vue que lors de la soumission du formulaire la page va s'appeler lui même.

thomasam
Auteur

Bonjour à tous, et merci pour votre contribution.
En fait j'ai comme l'impression que le problème vient des requêtes pâssée dans le model principal, parceque le tuto à été réalisé avec la version PHP 5 et aujourd'hui, nous sommes à la version 7.


                // code à executer
                if(!is_numeric($v)){
                    $v = '"'.addslashes($v).'"';//mysql_real_escape_string($v)= '"'.addslashes($v).'"';
                }

Ce bout de code me semble être la source du problème.

mysql_real_escape_string($v)

Avec la version 7 de PHP elle deviennent obcelètes.
Bonne journée à vous.

thomasam
Auteur

Voici le model principal, je l'ai scruter, et essayé de modifier plusieurs fois, j'ai toujour la même erreur.

<?php 
class Model{
    static $connections = array(); // Permet de stocker les connections
    public $conf = 'default';
    public $table = false;
    public $db;
    public $primaryKey = 'id';
    public $id;
    public $errors = array();
    public $form;

    public function __construct(){
        // ici on initialise quelques variables
        if($this->table === false){
            $this->table = strtolower(get_class($this)).'s';
        }
        // Ici, on se connecte à la base de donnée
        $conf = Conf::$databases[$this->conf];
        if(isset(Model::$connections[$this->conf])){
            $this->db = Model::$connections[$this->conf];
            return true;
        }
        try{
            // Organisation pour forcer l'encadage
            $pdo = new PDO(
                'mysql:host='.$conf['host'].';dbname='.$conf['database'].';',
                $conf['login'],
                $conf['password'],
                array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8')
            );
            $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);

            Model::$connections[$this->conf] = $pdo;
            $this->db = $pdo;
        }catch(PDOException $e){
            // Condition pour debugger la connection
            if(Conf::$debug >= 1){
                die($e->getMessage());
            } else{
                die('Impossible de se connecter à la base de donnée');
            }
        }
    }

    /**
     * 
     */
    public function find($req = array()){
        $sql = 'SELECT ';

        if(isset($req['fields'])){
            if(is_array($req['fields'])){
                $sql .= implode(', ',$$req['fields']);
            }else{
                $sql .= $req['fields'];
            }
        }else{
            $sql .= '*';
        }
        $sql .= ' FROM '.$this->table.' as '.get_class($this).' ';

        // Construction de la condition
        if(isset($req['conditions'])){
            $sql .= 'WHERE ';
            if(!is_array($req['conditions'])){
                $sql .= $req['conditions'];
            }else{
                $cond = array();
                foreach ($req['conditions'] as $k => $v){
                    // code à executer
                    if(!is_numeric($v)){
                        $v = '"'.addslashes($v).'"';//mysql_real_escape_string($v)= '"'.addslashes($v).'"';
                    }
                    $cond[] = "$k=$v";
                }
                $sql .= implode(' AND ',$cond);
            }
        }

        if(isset($req['order'])){
            $sql .= ' ORDER BY '.$req['order'];
        }
        // Construction de la limt
        if(isset($req['limit'])){
            $sql .= ' LIMIT '.$req['limit'];
        }
        $pre = $this->db->prepare($sql);
        $pre->execute();
        return $pre->fetchAll(PDO::FETCH_OBJ);
    }

    public function findFirst($req){
       return current($this->find($req));
    }

    /**
     * Permet d'afficher le nombre d'articles postés
     */
    public function findCount($conditions){
        $res = $this->findFirst(array(
            'fields' => 'COUNT('.$this->primaryKey.') as count',
            'conditions' => $conditions
        ));
        return $res->count;
    }

    public function delete($id){
        $sql = "DELETE FROM {$this->table} WHERE {$this->primaryKey} = $id";
        $this->db->query($sql);
    }

    public function save($data){
        $key = $this->primaryKey;
        $fields = array();
        $d = array();
        foreach($data as $k=>$v){
            if($k!=$this->primaryKey){
                $fields[] = "$k=:$k";
                $d[":$k"] = $v;
            }elseif(!empty($v)){
                $d[":$k"] = $v;
            }
        }
        if(isset($data->$key) && !empty($data->$key)){
            $sql = 'UPDATE '.$this->table.' SET '.implode(',',$fields).' WHERE '.$key.'=:'.$key;
            $this->id = $data->$key;
            $action = 'update';
        }else{
            $sql = 'INSERT INTO '.$this->table.' SET '.implode(',',$fields);
            $action = 'insert'; 
        }

        $pre = $this->db->prepare($sql);
        $pre->execute($d);
        if($action == 'insert'){
            $this->id = $this->db->lastInsertId();
        } 
    }

    /*public function validates($data){
        $errors = array();
        foreach($this->validate as $k => $v) {
            if(!isset($data->$k)){
                $errors[$k] = $v['message'];
            }else{
                if($v['rule'] == 'notEmpty'){
                    if(empty($data->$k)){
                        $errors[$k] = $v['message'];
                    }
                }elseif(!preg_match('/^'.$v['rule'].'$/',$data->$k)){
                    $errors[$k] = $v['message'];
                }
            }
        }

        $this->errors = $errors;
        if(isset($this->Form)){
            $this->Form->errors = $errors;
        }
        if(empty($errors)){
            return true;
        }
        return false;
    }*/
    public function _validates($action, $table) {
        $validate = array();

        foreach($table as $fields => $rules) {
            if(isset($rules['message'])) {
                $message = $rules['message'];
                unset($rules['message']);
            } else {
                $message = null;
            }
            if(!is_array($rules) || (is_array($rules) && isset($rules['rule']))) {
                $rules = array('rule' => $rules);
            }
            $rules = current($rules);
            foreach($rules['rule'] as $k => $v) {
                $d = get_object_vars($this->data);
                $validate[id] = call_user_func_array(array('Validate', $k), array($field, $v, $d[$field], (isset($message[$k])) ? $message[$k] : null));
            }
        }

        if(in_array(false, $valid, true)) {
            $this->validate[Error] = call_user_func(array('Validate', '_return'));
            return false;
        } else {
            return true;
        }
    }
}

il faut verifier si ton formulaire envoie des données et que ton controller les récupère si c'est pas le cas il peut avoir un problème de routage.
tu dis "J'ai essayé de debuger data, la classe me renvoie un tableau vide." mais a quel niveau ?

thomasam
Auteur

Comme tu dis, peut-être que j'ai oublié quelque chose au niveau du controller principal, je l'envoie pour vérification. Pour le moment j'ai supprimé toute la partie admin du site pour essayer d'autres entrée plus simples sans passer par la structure MVC.

<?php
class Controller{
    public $request;                    // Objet Request
    private $vars     = array();        // Variables à passer à la vue
    public $layout    = 'default';      // Layout à utiliser pour rendre la vue
    private $rendered = false;          // Si le rendu a été fait ou pas ?

    /**
     * Constructeur
     * @param $request Objet request de notre application
     */
    function __construct($request = null){

        $this->Session = new Session();
        $this->Form = new Form($this);

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

    }

    /**
     * permet de rendre la la vue à l'utilisateur
     * @param $view Fichier à rendre depuis la vue principale
     */
    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;
    }

    /**
     * permet de passer  une ou plusieurs variable à la vue
     * @param $key nom de la variable OU tableau de variables
     * @param $value Valeur de la variable
     */
    public function set($key,$value=null){
        if(is_array($key)){
            $this->vars += $key;
        }else{
            $this->vars[$key] = $value;
        }
    }

    /**
     * Permet de charger un model
     */
    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;
            }
        }
    }

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

    /**
     * Permet d'appeller un controlle depuis une view
     */
    function request($controller,$action){
        $controller .= 'Controller';
        require_once ROOT.DS.'controller'.DS.$controller.'.php';
        $c = new $controller();
        return $c->$action();
    }

    /**
     * Permet de redidiger après action
     */
    function redirect($url,$code = null){
        if($code == 301){
            header("HTTP/101 301 Moved Permanently");
        }
        header("Location: ".Router::url($url));
        die();
    }
}
?> 

En fait avant de poster ma préocupation, j'ai parcouru le forum pour voir si quelqu'un avait déjà eu le même problème que moi. Sauf les réposes sont plus liées à l'ajout d'autre fonctionnalités sur les sites. Merci d'avance.

Dans la class Form,

le code

elseif ($options['type'] == 'password'){
            $html .= '<input type="password" class="form-control" id="input'.$name.'" name"'.$name.'" value="'.$value.'"'.$attr.'>';
        }  

dans le name il manque le =.

Normalement ça va regler le problème.

thomasam
Auteur

Je vais tout réactiver pour voir si ça marche.

thomasam
Auteur

Merci pour votre contribution,
J'ai toujours le même problème. Mon application semble ne pas stocker les mots de passe. Je vous recontacte si j'ai une solution.