I think it is necessary to access the session data from every where especially in the model, I don't know what is the conflict with the design or logic of CakePHP.
I wonder if we can use the Session class globally as Text class.
Does the problem just about the design and logic and nothing related to errors can be rises in the future?
As per Framework concept you can read/write/modify session from Controller.But have not read and write access in Model.
In CakePHP v3 you can manage session in model as mentioned below
\Cake\Routing\Router::getRequest()->session()->read('key');
\Cake\Routing\Router::getRequest()->session()->write('key', 'value');
Related
I have used this tutorial for creating my user login in Laravel: Laravel Authentication Essentials. So I have a SessionController that contains the methods create, store and destroy, for showing the form, logging in and out respectively.
But there is no model in this tutorial, the validation and Auth::attempt is in the controller. And that doesn't feel right. I can not create a Session model, since the Session class already exists.
Should I put the login/out logic in the User model, or is there another way to do this that complies with the MVC architectural pattern?
First, remember (or know) that you can change everything in Laravel. If you need a Session model using a sessions table, go to app/config/session.php and change the Laravel sessions table to laravel_sessions:
'table' => 'laravel_sessions',
People are doing things differently these days, methods are improving on a daily basis and the way you do your code must be confortable to you. If you feel it is not right the way you are seeing people doing it, change it, Laravel give you the power to change and do things your way. And if you feel you just found a better way of doing it, share it.
This is a 2013 video and today Jeffrey is doing authentication in a completly different way. Sign up for a Laracasts account and take the full Build a Larabook video series to see how he's doing it now.
There's no Session model in this tutorial because he's not storing sessions (successful logins) in a sessions table.
In the tutorial he never touches the User model, so there is no login in the user model. The only thing he's using to do authentication is Auth::attempt(), a Laravel facade method which uses internally the user model (M), to find a user and check if the password matches. He's working with a Session controller (C) and everything related to login (or sign in) and showing login views (V) is done inside that particular controller.
If it is easier to you, you can rename SessionsController to LoginController, I, myself, don't really like the Sessions name for login, but that's a matter of taste not code correctness.
That being said I don't see an MVC (or whatever name people like to call it this week) problem in that video.
EDIT Answering the comment:
The purpose of the model is towards data, no data, no model. In the context of Laravel and a database management system, yes, no table, no model. In the context, for instance, of a client-server API, your server API (Laravel, Rails...) will provide data for your client model (Angular, EmberJS...), so, there will be no table directly related to the client model, but still a model.
But in that particular case you are accessing a model, the user model, via a service, the Authentication service.
Imagine that I want to login a user. The user sends the validation data, and my controller gets the POST request so it calls a User Repository method in order to registered him.
I'd like to start the user Session with the user data. But how should I start the session? Should it start in the controller or the model? I think it should be the model, since it's my business logic who says that session have to be started. But how? Should I pass the session object to my Repository?
Im using Doctrine for the model layer, and my own framework for the rest. I use dependency injection but I don't see how to get access to the Session from the entities / repositories layer.
The only solution I've got right now is to call the repository method passing the session as a parameter, but it doesn't feel right.
I think session handling should be done in the controller, but just personal opinion. If you are trying to have a clean separation of concern, it should defiantly be done it the controller. It doesn't make a lot of sense to make Doctrine (which has a very strong focus on abstraction and independence) dependable on the session.
Make a controller which calls a method from model to register the user. The model method returns the user specific data, which you pass to the Session (from controller). You will probably use session in a lot of places, not relevant to model. Why make it stretch to two levels, if you can encapsulate it in one?
I am working on this app that accesses session variables in the model layer. This just seems wrong but am willing to be proven wrong. Maybe not wrong but, in most places in app, session variables are handled in controller and passed in as arguments but, in other places, the session value is just accessed. Am I wrong that this seems like bad practice?
edit:
one reason I don't like sessions in models is that it seems to make it more complex to test. Keep it as just params passsed to functions and then recordset passed back.
thx
It depends.
The way I think about this is such:
A Model represents your data layer.
most of the time that data layer will be DB Table based
The Session is just another data storage medium.
Conclusion: If the data that your model represents is stored in the Session, than it is OK to access that data from within the model
An example is a Session based shopping cart. My cart's objects are models of my session data.
Controller shd do a check weather session exist or not before using the model which uses that session inside it .
No it shouldn't. The storage type, should be apart from your business logic. For example:
I have one simple plug-in that perform the access check and put the user object on the registry. So, instead of access session, the model have access to the registry, which is well defined.
$User = Zend_Registry::get('User'); // User model object
From the theoretical point of view, everything should be accessed through data mappers. In the future, if you change from session storage to something else, you'll need to update it just in one place. Your models do not need to know from where the data came from.
If you are taking more than one path to get your data, probably this will cause some problems when your application get large.
The OOP and layered systems approach suggestion is to created specialized objects and layers and keep things simple preventing specific actions to be spread all over the code.
But again, you do not need to change that unless you see advantages.
Keep in mind that sometimes refactoring is more efficient than try to predict everything.
What's stored in the session variables? If it's simply 'logged in? Y/N', then they probably don't need to be part of the model layer. If, however, it's more complex than that, they are probably inextricably linked to your business model and should be treated as such.
The examples at the bottom of the Zend Test documentation show how to test the full MVC using a login function. Presumably you could do the same when testing models?
Cake's documentation says "Most commonly, controllers are used to manage the logic for a single model." I'm finding this is uncommon for most of my code, and I don't want to break convention unless it is proper to do so.
For example, my application sends a user to their account dashboard after they log in - this uses data from probably half a dozen tables, not all of which are even related. Do I create a "dashboard" controller for this (even though there is no dashboard model or table)? Or do I create a dashboard method in an existing controller?
Thanks, Brian
I have a similar situation and how I handle it is keeping the actions that connect a lot of models in the controller that is the most centric. For instance, my user can create voicenotes, comments, has settings, has twitter and facebook information. All this information I can get from my user model $this->User->Voicenotes->find('all'), for example.
I believe creating additional controllers might just confuse you, use what cake gives you, you can specify that models are to be used in a controller either by setting the $uses variable or using loadModel in the controller action, if you have your relations set up you can just do it the way i described before, no need to create additional controllers.
I guess it depends on how you want your own app to work and what comes easier in your situation.
I'm working on simple PHP framework which follows MVC best practices. Core classes (config, request, response, router, dispatcher, db etc) are stored in registry which is also some kind of DIC.
The question is - where to put models which also is needed throughout application? For example User model.
One more question regarding this - User model will be created on login. When there is no logged in user, should User model be null or what? I don't like this because is_null() checks will be needed in many places.
MVC design patter is quite straight forward look and the documentation of major frameworks like Codeigniter,Kohana or even kissmvc which is simple and will help u identify the structure of the framework.
And regarding the login question , You can have a separate class to manage the sessions and use this to set if a user model was created not the object it self. You can getter better idea if you read the Zend_Auth Manual. Its simple to understand.