Pergunta

Encontro exemplos e tutoriais sobre modelos e validação. E eu os lugares que digo que a validação (ou a maioria deles pelo menos) devem estar no modelo, com o qual eu concordo. Mas não posso exemplos ou tutoriais que mostrem como isso deve ser feito.

Alguém poderia me ajudar com um exemplo simples de como isso poderia ser feito? Onde você teria as regras no modelo? Onde a validação aconteceria? Como o controlador saberia se a validação passou ou falhou? Como o controlador receberia mensagens de erro e coisas assim?

Espero que alguém possa ajudar, porque se sinta um pouco perdido aqui: P

Foi útil?

Solução

Eu também tive dificuldade em encontrar exemplos para Kohana3, o exemplo da Bestattendance é para Kohana2.

Aqui está um exemplo que joguei em meus próprios testes:

Aplicativo / Classes / Model / News.php

<?php defined('SYSPATH') OR die('No Direct Script Access');

Class Model_News extends Model
{
    /*
       CREATE TABLE `news_example` (
       `id` INT PRIMARY KEY AUTO_INCREMENT,
       `title` VARCHAR(30) NOT NULL,
       `post` TEXT NOT NULL);
     */

    public function get_latest_news() {
        $sql = 'SELECT * FROM `news_example` ORDER BY `id` DESC LIMIT  0, 10';
        return $this->_db->query(Database::SELECT, $sql, FALSE)
                         ->as_array();
    }

    public function validate_news($arr) {
        return Validate::factory($arr)
            ->filter(TRUE, 'trim')
            ->rule('title', 'not_empty')
            ->rule('post', 'not_empty');
    }
    public function add_news($d) {
        // Create a new user record in the database
        $insert_id = DB::insert('news_example', array('title','post'))
            ->values(array($d['title'],$d['post']))
            ->execute();

        return $insert_id;
    }
}

aplicativo / mensagens / erros.php

<?php
return array(
    'title' => array(
        'not_empty' => 'Title can\'t be blank.',
    ),
    'post' => array(
        'not_empty' => 'Post can\'t be blank.',
    ),
);

Aplicativo / Classes / Controller / News.php

<?php defined('SYSPATH') OR die('No Direct Script Access');

Class Controller_News extends Controller
{
    public function action_index() {
        //setup the model and view
        $news = Model::factory('news');
        $view = View::factory('news')
            ->bind('validator', $validator)
            ->bind('errors', $errors)
            ->bind('recent_posts', $recent_posts);

        if (Request::$method == "POST") {
            //added the arr::extract() method here to pull the keys that we want
            //to stop the user from adding their own post data
            $validator = $news->validate_news(arr::extract($_POST,array('title','post')));
            if ($validator->check()) {
                //validation passed, add to the db
                $news->add_news($validator);
                //clearing so it won't populate the form
                $validator = null;
            } else {
                //validation failed, get errors
                $errors = $validator->errors('errors');
            }
        }
        $recent_posts = $news->get_latest_news();
        $this->request->response = $view;
    }
}

Aplicativo / Views / News.php

<?php if ($errors): ?>
<p>Errors:</p>
<ul>
<?php foreach ($errors as $error): ?>
    <li><?php echo $error ?></li>
<?php endforeach ?>
</ul>
<?php endif ?>

<?php echo Form::open() ?>
<dl>
    <dt><?php echo Form::label('title', 'title') ?></dt>
    <dd><?php echo Form::input('title', $validator['title']) ?></dd>
    <dt><?php echo Form::label('post', 'post') ?></dt>
    <dd><?php echo Form::input('post', $validator['post']) ?></dd>
</dl>
<?php echo Form::submit(NULL, 'Post') ?>
<?php echo Form::close() ?>
<?php if ($recent_posts): ?>
<ul>
<?php foreach ($recent_posts as $post): ?>
    <li><?php echo $post['title'] . ' - ' . $post['post'];?></li>
<?php endforeach ?>
</ul>
<?php endif ?>

Para obter esse código funcionando em uma instalação padrão, você precisaria ativar o módulo de banco de dados e configurá -lo para autenticação. Em seguida, você pode acessá -lo no index.php/notícias usando a configuração padrão.

Ele é testado no Kohana 3.0.7 e deve fornecer um bom ponto de partida de como você pode estabelecer código. Ao contrário de outras estruturas, Kohana parece ser muito aberto, sobre onde você coloca sua lógica, então foi exatamente isso que fazia sentido para mim. Se você deseja usar o ORM em vez de rolar sua própria interação de banco de dados, ele tem sua própria sintaxe para validação que você pode encontrar aqui

Outras dicas

Um exemplo de validação KO3 usada com os modelos ORM. Exemplo foi publicado com permissão por A1986 (BLAA) em #Kohana (Freenode).

<?php defined('SYSPATH') or die('No direct script access.');

class Model_Contract extends ORM {

  protected $_belongs_to = array('user' => array());

  protected $_rules = array(
    'document' => array(
      'Upload::valid'     => NULL,
      'Upload::not_empty' => NULL,
      'Upload::type'      => array(array('pdf', 'doc', 'odt')),
      'Upload::size'      => array('10M')
    )
  );

  protected $_ignored_columns = array('document');


  /**
   * Overwriting the ORM::save() method
   * 
   * Move the uploaded file and save it to the database in the case of success
   * A Log message will be writed if the Upload::save fails to move the uploaded file
   * 
   */
  public function save()
  {
    $user_id = Auth::instance()->get_user()->id;
    $file = Upload::save($this->document, NULL, 'upload/contracts/');

    if (FALSE !== $file)
    {
      $this->sent_on = date('Y-m-d H:i:s');
      $this->filename = $this->document['name'];
      $this->stored_filename = $file;
      $this->user_id = $user_id;
    } 
    else 
    {
      Kohana::$log->add('error', 'Não foi possível salvar o arquivo. A gravação da linha no banco de dados foi abortada.');
    }

    return parent::save();

  }

  /**
   * Overwriting the ORM::delete() method
   * 
   * Delete the database register if the file was deleted 
   * 
   * If not, record a Log message and return FALSE
   * 
   */
  public function delete($id = NULL)
  {

    if (unlink($this->stored_filename))
    {
      return parent::delete($id);
    }

    Kohana::$log->add('error', 'Não foi possível deletar o arquivo do sistema. O registro foi mantido no banco de dados.');
    return FALSE;
  }
}

Aqui está um exemplo simples que funciona para mim.

No meu modelo (client.php):

<?php defined('SYSPATH') or die('No direct script access.');

class Client_Model extends Model {

public $validation;

// This array is needed for validation
public $fields = array(
    'clientName'    =>  ''
);

public function __construct() {
    // load database library into $this->db (can be omitted if not required)
    parent::__construct();

    $this->validation = new Validation($_POST);
    $this->validation->pre_filter('trim','clientName');
    $this->validation->add_rules('clientName','required');
}

public function create() {
    return $this->validation->validate();
}

// This might go in base Model class
public function getFormValues() {
    return arr::overwrite($this->fields, $this->validation->as_array());
}

// This might go in base Model class
public function getValidationErrors() {
    return arr::overwrite($this->fields, $this->validation->errors('form_errors'));
}
}

?>

No meu controlador (clients.php):

<?php defined('SYSPATH') OR die('No direct access allowed.');

class Clients_Controller extends Base_Controller {

public function __construct() {
    parent::__construct();
}

public function index() {

    $content = new View('clients/read');
    $content->foobar = 'bob.';

    $this->template->content = $content;
    $this->template->render(TRUE);

}

/* A new user signs up for an account. */
public function signup() {

    $content = new View('clients/create');
    $post = $this->input->post();
    $client = new Client_Model;

    if (!empty($post) && $this->isPostRequest()) {
        $content->message = 'You submitted the form, '.$this->input->post('clientName');
        $content->message .= '<br />Performing Validation<br />';

        if ($client->create()) {
            // Validation passed
            $content->message .= 'Validation passed';
        } else {
            // Validation failed
            $content->message .= 'Validation failed';
        }

    } else {
        $content->message = 'You did not submit the form.';
    }

    $contnet->message .= '<br />';
    print_r ($client->getFormValues());
    print_r ($client->getValidationErrors());


    $this->template->content = $content;
    $this->template->render(TRUE);
}

   }
?>

No meu arquivo i18n (form_errors.php):

$lang = Array (
'clientName' => Array (
'required' => 'The Client Name field is required.'
)
);

Eu tenho uma breve redação de como lidar com isso no link abaixo, pois demorei um pouco para descobrir e não consegui encontrar um único bom exemplo.

http://www.matt-togo.com/dev/orm_with_validation_in_kohana_3

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top