Remiya,
I agree with you. I think the main problem is, that while you know what you want to achieve with the separation, the implementation is not so easy in some cases. Thanks to people at this forum I finally make some progress in rewriting my latest project, because I know that if I won't do it ASAP, it would be a pain to make any changes in the next few months. I tried some unit testing with the current code base and while it's possible to do, it took some time to establish all the code because of so many dependencies etc.
So personally when I see a $this->retrieve_any_kind_of_data() in a Controller class it makes me shiver
Please check my questions at the bottom. They refer to that...
Based on the entries in this tread, I began to play a bit with sessions to finnaly bring my LoginBox to life
So here are some general thoughts how I'd like to implement it.
I have my custom session handler which manages sessions in the database.
So, index.php could look similar to:
PHP Code:
require 'class/session.php';
require 'class/db.php';
require 'class/page.php';
$page = new Page($db,new Translator($db), new Session($db));
Now, the page.php is a the main controller.
1. I think I should do session stuff here (start, check if expired, set some vars like is_logged)
2. As I'm using some xmlhttp, I just send such requests with additional header, so I can easily check on the server side, if the request is xmlhttp or not without some fancy url vars. I'd like to check that in page.php too and set some variable like is_xmlhttp
page.php
PHP Code:
class Page {
(...)
function __construct($db,$translator,$session) {
$this->db = $db;
$this->translator = $translator;
$this->session = $session;
// ok, so here I'd like to start the session
$this->session->start();
// get session data (id, some vars etc)
// check if user is logged and set is_logged etc
// is this the right place to do it?
$this->getSessionData();
// I need to check the request type,
// mainly if it was made through xmlhttprequest or not
// method name is just an example
$this->isAjax();
}
// I changed the loginBox to userBox, because if user is logged in,
// he can see some links instead of the login form
// so here, I'd check if the user is logged
// and create proper child controller
protected function getUserBox() {
if (!$this->is_logged) {
// I need to pass $db object and the session object
$childcontroller = new LoginBox($this->db, $this->sesison, $this->is_xmlhttp);
} else {
$childcontroller = new UserLinks($this->translator);
}
return $childcontroller->execute();
}
OK, so if user is not logged in, we are passed to the loginBox controller
The login component needs to talk with the database, but only if the login attempt appeared at all, so here is some code snippet and the specific questions wil follow
PHP Code:
class LoginBox {
(...)
function __construct($db, $session, $xmlhttp) {
$this->db = $db;
$this->session = $session;
$this->is_xmlhttp = $xmlhttp;
}
function execute() {
// ok, so if the posted data contains
// 'form_login_etc' (which will be a hidden input), then it means, that
// user has attempted to log in (at least used THAT form)
// I need to validate the data and do some actions when it's ok
// Here I also need the model to talk to db,
// is it a good please to create an object??
if (isset($_POST['form_login_etc'])) {
$this->model = new Login_Model($this->db);
// check the validation state and fire the proper action
if ($this->validate($_POST)) {
// update session
$this->updateSessionData();
//update database
$this->model->updateLoginDate();
// if it's the xmlhttp, send some json string and exit
if ($this->is_xmlhttp) {
$this->sendJsonResponse();
}
// if it's not xmlhttp, I should send header('Location
// but it looks a bit dirty here.... - where to do it??
}
}
return $this->render('login.tpl.php');
}
// some example validation, it uses model to check some data!
// errors are stored in an Array, so if the validation fails,
// errors as just shown in the form in the proper place
function validate($data) {
if (trim($data['login']) == '' || trim($data['password']) == '') {
$this->errors['login'] = $this->__('LOGIN_ERROR');
return false;
}
if (!$this->model->checkLogin($data['login'], $data['password'])) {
$this->errors['login'] = $this->__('LOGIN_ERROR');
return false;
}
return true;
}
1. Where I should update the session data, in the controller or in the model? Can controller read any data (aside from validation) from the model at all?
I think that the controller is the right place to do the job, but then, I'd need to grab the data (username, id, privileges etc) from the model...
2. Is my use of model correct at all? What would be the better way of handling this stuff based on the code above?
3. Is such validation OK? Or should I write additional class for that purpose etc? The example is quite simple, but if the form contains 30 fields, the validation would get much bigger
4. Is my handling session/some checkings in the Page controller constructor OK? I know I need to check the session and request ASAP, because those things will be needed by other components. And I want to check that only once in my application.
I will be grateful for any opinions and help.
Cheers!
Daniel
Bookmarks