I want to add a user in users table via link like '/index/adduser/id/7' .
Question
Should I validate user input inside 'adduserAction' function inside controller or somewhere inside model file? I've put files containing database related functions inside 'models' directory. Suppose a user is added to a table via 'id'. This id is sent via 'get'. And finally its added to table by 'AddUser' function (inside model file). Then I should validate this 'id' inside 'adduserAction' or 'AddUser'.? Scalability-wise, would it be better to do it inside 'AddUser'?
There's a popular believe / paradigm that states:
Thin controllers, fat models.
What this means, is that your controller should only be responsible for doing the bare minimum to make sure actions change the state of models and serve the right view in return. With this in mind, the validation should occur in your models. But... hold on for a minute. Models aren't necceseraly 1 tiered layers.
I believe among .NET programmers the following setup (or something similar) is a pretty common practice (if the scale of the project validates it):
Controller
-> ServiceLayer
-> Repository
-> DataObject
And I'm starting too like this setup more and more. Moreover, I believe this setup is very doable in a Zend Framework environment too.
The term Model is somewhat of a vague term. In the above you could consider the three last layers as your Model layer. What the three layers represent is the following:
ServiceLayer:
Responsible for business logic. In other words: retrieving Dataobjects (Models) from the repository, tying Models together, AND validating Models before storing them, mailing a user, etc..
Repository:
Some type of persistence mechanism (like a Database), that serves DataObjects to the service layer, and stores DataObjects back in the persistence mechanism (after the service layer validated them)
DataObject:
You might consider this the actual Models. Preferably DataObjects have common interfaces (independant of the Repository that is), so that Repositories are interchangeable. In other words, when the repository changes from a database to an XML file from some webservice, the DataObject still has the same interface the service layer and ultimately the view can work with.
Hope this makes sense. This is basically my understanding of a more layered MVC setup right now. If anybody feels I have things mixed up please feel free to correct me.
Please keep in mind though, that not all projects dignify such a layered setup. In smaller projects you could perhaps do with just a 1 layered Model layer. In that case, validating should still be the Model's responsiblity. The controller should be thin (just for tying Model state and Views together through actions).
I would say put the validation in your model. You can then keep your validation rules in a central location. How should your controller know the exact length of a valid user name? That is model territory. Your controller can ask the model if a user name length is correct or not sure, but the rule itself needs to be in your model. In my controller I would do something like this:
$model = new Model;
$model->loadFromArray(something to get post);
if (!$model->isValid()) { forward back to form }
$model->save();
the ideal solution is to use validation inside your forms - i.e. appending it to your zend_form_elements - see http://framework.zend.com/manual/en/zend.form.elements.html
I'd do it in the Controller, not the Model. IMHO that's the better place because then the sanitized data is secure to use in the controller already. That's a good thing for comparing things, etc., even before the data is actually saved.
I know it's already answered, but I remember the "younger me" combing the web for some choice resources on sites like this and would like to share my research and what I do here. I do the following:
I use forms to do input validation
and filtering Do my validation inside
models
I have a validation method
which proxies the form validation
method.
This validation method can called upon
internally by model methods or externally
by the controller or view.
Here's a quick example:
//UserModel
class Default_Model_User
{
protected $_form;
public function getForm()
{
if(!isset($this->_form)) {
$this->_form = new Default_Model_Form_User();
}
}
public function validate($data)
{
if($result = $this->getForm()->isValid($data)) {
// if you have custom validation conditions outside of the form, then you
// can do the validation here also.
if($data['controller_entered'] == 'some value') {
$result = false;
}
}
return $result;
}
public function saveUser($data)
{
if($result = $this->validate($data)) {
// do something.
}
return $result;
}
}
If you haven't read it already, be sure to check out the Surviving The Deepend book freely available on the following URL:
http://www.survivethedeepend.com/zendframeworkbook/en/1.0
This chapter is specific to your dilema:
http://www.survivethedeepend.com/zendframeworkbook/en/1.0/implementing.the.domain.model.entries.and.authors#id1491270
You will no doubt run into other issues as you progress through... It may help to check out the comments on my blog post regarding the model layer where I cover this issue: http://www.rvdavid.net/my-zend-framework-model-layer-part-service-part-orm/
Hope this helps someone out.
Related
Let's say whenever I do a CRUD operation or modify a relationship in a specific way I also want to do something else. E.g., whenever someone publishes a post I also want to save something to a table for analytics. Maybe not the best example but in general there's a lot of this "grouped" functionality.
Normally I see this type of logic put into controllers. That's all fine an dandy until you want to reproduce this functionality in lots of places. When you start getting into partials, creating an API and generating dummy content it becomes an issue with keeping things DRY.
The ways I've seen to manage this are events, repositories, libraries, and adding to models. Here are my understandings of each:
Services: This is where most people would probably put this code. My main issue with services is that sometimes it's hard to find specific functionality in them and I feel like they get forgotten about when people are focused on using Eloquent. How would I know I need to call a method publishPost() in a library when I can just do $post->is_published = 1?
The only condition I see this working well in is if you ONLY use services (and ideally make Eloquent inaccessible somehow from controllers all together).
Ultimately it seems like this would just create a bunch of extra unnecessary files if your requests generally follow your model structure.
Repositories: From what I understand this is basically like a service but there's an interface so you can switch between ORMs, which I don't need.
Events: I see this as the most elegant system in a sense because you know your model events are always going to be called on Eloquent methods, so you can write your controllers like you normally would. I can see these getting messy though and if anyone has examples of large projects using events for critical coupling I'd like to see it.
Models: Traditionally I'd have classes that performed CRUD and also handled critical coupling. This actually made things easy because you knew all functionality around CRUD + whatever had to be done with it was there.
Simple, but in MVC architecture this isn't normally what I see done. In a sense though I prefer this over services since it's a bit easier to find, and there are less files to keep track of. It can get a bit disorganized though. I'd like to hear downfalls to this method and why most people don't seem to do it.
What are the advantages / disadvantages of each method? Am I missing something?
I think all patterns / architectures that you present are very useful as long as you follow the SOLID principles.
For the where to add logic I think that it's important to refer to the Single Responsibility Principle. Also, my answer considers that you are working on a medium / large project. If it's a throw-something-on-a-page project, forget this answer and add it all to controllers or models.
The short answer is: Where it makes sense to you (with services).
The long answer:
Controllers: What is the responsibility of Controllers? Sure, you can put all your logic in a controller, but is that the controller's responsibility? I don't think so.
For me, the controller must receive a request and return data and this is not the place to put validations, call db methods, etc..
Models: Is this a good place to add logic like sending an welcome email when a user registers or update the vote count of a post? What if you need to send the same email from another place in your code? Do you create a static method? What if that emails needs information from another model?
I think the model should represent an entity. With Laravel, I only use the model class to add things like fillable, guarded, table and the relations (this is because I use the Repository Pattern, otherwise the model would also have the save, update, find, etc methods).
Repositories (Repository Pattern): At the beginning I was very confused by this. And, like you, I thought "well, I use MySQL and thats that.".
However, I have balanced the pros vs cons of using the Repository Pattern and now I use it. I think that now, at this very moment, I will only need to use MySQL. But, if three years from now I need to change to something like MongoDB most of the work is done. All at the expense of one extra interface and a $app->bind(«interface», «repository»).
Events (Observer Pattern): Events are useful for things that can be thrown at any class any given time. Think, for instance, of sending notifications to a user.
When you need, you fire the event to send a notification at any class of your application. Then, you can have a class like UserNotificationEvents that handles all of your fired events for user notifications.
Services: Until now, you have the choice to add logic to controllers or models. For me, it makes all sense to add the logic within Services. Let's face it, Services is a fancy name for classes. And you can have as many classes as it makes sense to you within your aplication.
Take this example: A short while ago, I developed something like the Google Forms. I started with a CustomFormService and ended up with CustomFormService, CustomFormRender, CustomFieldService, CustomFieldRender, CustomAnswerService and CustomAnswerRender. Why? Because it made sense to me. If you work with a team, you should put your logic where it makes sense to the team.
The advantage of using Services vs Controllers / Models is that you are not constrained by a single Controller or a single Model. You can create as many services as needed based on the design and needs of your application. Add to that the advantage of calling a Service within any class of your application.
This goes long, but I would like to show you how I have structured my application:
app/
controllers/
MyCompany/
Composers/
Exceptions/
Models/
Observers/
Sanitizers/
ServiceProviders/
Services/
Validators/
views
(...)
I use each folder for a specific function. For example the Validators directory contains a BaseValidator class responsible for processing the validation, based on the $rules and $messages of specific validators (usually one for each model). I could as easily put this code within a Service, but it makes sense to me to have a specific folder for this even if it is only used within the service (for now).
I recommend you to read the following articles, as they might explain things a little better to you:
Breaking the Mold by Dayle Rees (author of CodeBright): This is where I put it all together, even though I changed a few things to fit my needs.
Decoupling your code in Laravel using Repositories and Services by Chris Goosey: This post explains well what is a Service and the Repository Pattern and how they fit together.
Laracasts also have the Repositories Simplified and Single Responsibility which are good resources with practical examples (even though you have to pay).
I wanted to post a response to my own question. I could talk about this for days, but I'm going to try to get this posted fast to make sure I get it up.
I ended up utilizing the existing structure that Laravel provides, meaning that I kept my files primarily as Model, View, and Controller. I also have a Libraries folder for reusable components that aren't really models.
I DID NOT WRAP MY MODELS IN SERVICES/LIBRARIES. All of the reasons provided didn't 100% convince me of the benefit of using services. While I may be wrong, as far as I can see they just result in tons of extra nearly empty files I need to create and switch between when working with models and also really reduce the benefit of using eloquent (especially when it comes to RETRIEVING models, e.g., using pagination, scopes, etc).
I put the business logic IN THE MODELS and access eloquent directly from my controllers. I use a number of approaches to make sure that the business logic doesn't get bypassed:
Accessors and mutators: Laravel has great accessors and mutators. If I want to perform an action whenever a post is moved from draft to published I can call this by creating function setIsPublishedAttribute and including the logic in there
Overriding Create/Update etc: You can always override Eloquent methods in your models to include custom functionality. That way you can call functionality on any CRUD operation. Edit: I think there's a bug with overriding create in newer Laravel versions (so I use events now registered in boot)
Validation: I hook my validation in the same way, e.g., I'll run validation by overriding CRUD functions and also accessors/mutators if needed. See Esensi or dwightwatson/validating for more information.
Magic Methods: I use the __get and __set methods of my models to hook into functionality where appropriate
Extending Eloquent: If there's an action you'd like to take on all update/create you can even extend eloquent and apply it to multiple models.
Events: This is a straight forward and generally agreed upon place to do this as well. Biggest drawback with events I think is that exceptions are hard to trace (might not be the new case with Laravel's new events system). I also like to group my events by what they do instead of when they are called...e.g., have a MailSender subscriber which listens for events that send mail.
Adding Pivot/BelongsToMany Events: One of the things I struggled with the longest was how to attach behavior to the modification of belongsToMany relationships. E.g., performing an action whenever a user joins a group. I'm almost done polishing up a custom library for this. I haven't published it yet but it is functional! Will try to post a link soon. EDIT I ended up making all my pivots into normal models and my life has been so much easier...
Addressing people's concerns with using models:
Organization: Yes if you include more logic in models, they can be longer, but in general I've found 75% of my models are still pretty small. If I chose to organize the larger ones I can do it using traits (e.g., create a folder for the model with some more files like PostScopes, PostAccessors, PostValidation, etc as needed). I know this is not necessarily what traits are for but this system works without issue.
Additional Note: I feel like wrapping your models in services is like having a swiss army knife, with lots of tools, and building another knife around it that basically does the same thing? Yeah, sometimes you might want to tape a blade off or make sure two blades are used together...but there are typically other ways to do it...
WHEN TO USE SERVICES: This article articulates very well GREAT examples for when to use services (hint: it's not very often). He says basically when your object uses multiple models or models at strange parts of their lifecycle it makes sense. http://www.justinweiss.com/articles/where-do-you-put-your-code/
What I use to do to create the logic between controllers and models is to create a service layer. Basically, this is my flow for any action within my app:
Controller get user's requested action and sent parameters and delegates everything to a service class.
Service class do all the logic related to the operation: input validation, event logging, database operations, etc...
Model holds information of fields, data transformation, and definitions of attributes validations.
This is how I do it:
This the method of a controller to create something:
public function processCreateCongregation()
{
// Get input data.
$congregation = new Congregation;
$congregation->name = Input::get('name');
$congregation->address = Input::get('address');
$congregation->pm_day_of_week = Input::get('pm_day_of_week');
$pmHours = Input::get('pm_datetime_hours');
$pmMinutes = Input::get('pm_datetime_minutes');
$congregation->pm_datetime = Carbon::createFromTime($pmHours, $pmMinutes, 0);
// Delegates actual operation to service.
try
{
CongregationService::createCongregation($congregation);
$this->success(trans('messages.congregationCreated'));
return Redirect::route('congregations.list');
}
catch (ValidationException $e)
{
// Catch validation errors thrown by service operation.
return Redirect::route('congregations.create')
->withInput(Input::all())
->withErrors($e->getValidator());
}
catch (Exception $e)
{
// Catch any unexpected exception.
return $this->unexpected($e);
}
}
This is the service class that does the logic related to the operation:
public static function createCongregation(Congregation $congregation)
{
// Log the operation.
Log::info('Create congregation.', compact('congregation'));
// Validate data.
$validator = $congregation->getValidator();
if ($validator->fails())
{
throw new ValidationException($validator);
}
// Save to the database.
$congregation->created_by = Auth::user()->id;
$congregation->updated_by = Auth::user()->id;
$congregation->save();
}
And this is my model:
class Congregation extends Eloquent
{
protected $table = 'congregations';
public function getValidator()
{
$data = array(
'name' => $this->name,
'address' => $this->address,
'pm_day_of_week' => $this->pm_day_of_week,
'pm_datetime' => $this->pm_datetime,
);
$rules = array(
'name' => ['required', 'unique:congregations'],
'address' => ['required'],
'pm_day_of_week' => ['required', 'integer', 'between:0,6'],
'pm_datetime' => ['required', 'regex:/([01]?[0-9]|2[0-3]):[0-5]?[0-9]:[0-5][0-9]/'],
);
return Validator::make($data, $rules);
}
public function getDates()
{
return array_merge_recursive(parent::getDates(), array(
'pm_datetime',
'cbs_datetime',
));
}
}
For more information about this way I use to organize my code for a Laravel app: https://github.com/rmariuzzo/Pitimi
In my opinion, Laravel already has many options for you to store your business logic.
Short answer:
Use Laravel's Request objects to automatically validate your input, and then persist the data in the request (create the model). Since all of the users input is directly available in the request, I believe it makes sense to perform this here.
Use Laravel's Job objects to perform tasks that require individual components, then simply dispatch them. I think Job's encompass service classes. They perform a task, such as business logic.
Long(er) answer:
Use Respositories When Required:
Repositories are bound to be over-bloated, and most of the time, are simply used as an accessor to the model. I feel like they definitely have some use, but unless you're developing a massive application that requires that amount of flexibility for you to be able to ditch Laravel entirely, stay away from repositories. You'll thank yourself later and your code will be much more straight forward.
Ask yourself if there's a possibility that you're going to be changing PHP frameworks or to a database type that Laravel doesn't support.
If your answer is "Probably not", then don't implement the repository pattern.
In addition to above, please don't slap a pattern on top of a superb ORM like Eloquent. You're just adding complexity that isn't required and it won't benefit you at all.
Utilize Services sparingly:
Service classes to me, are just a place to store business logic to perform a specific task with its given dependencies. Laravel has these out of the box, called 'Jobs', and they have much more flexibility than a custom Service class.
I feel like Laravel has a well-rounded solution for the MVC logic problem. It's just a matter or organization.
Example:
Request:
namespace App\Http\Requests;
use App\Post;
use App\Jobs\PostNotifier;
use App\Events\PostWasCreated;
use App\Http\Requests\Request;
class PostRequest extends Request
{
public function rules()
{
return [
'title' => 'required',
'description' => 'required'
];
}
public function persist(Post $post)
{
if (! $post->exists) {
// If the post doesn't exist, we'll assign the
// post as created by the current user.
$post->user_id = auth()->id();
}
$post->title = $this->title;
$post->description = $this->description;
$post->save();
// Maybe we'll fire an event here that we can catch somewhere
// else that needs to know when a post was created.
event(new PostWasCreated($post));
// Maybe we'll notify some users of the new post as well.
dispatch(new PostNotifier($post));
return $post;
}
}
Controller:
namespace App\Http\Controllers;
use App\Post;
use App\Http\Requests\PostRequest;
class PostController extends Controller
{
public function store(PostRequest $request)
{
$request->persist(new Post());
flash()->success('Successfully created new post!');
return redirect()->back();
}
public function update(PostRequest $request, Post $post)
{
$request->persist($post);
flash()->success('Successfully updated post!');
return redirect()->back();
}
}
In the example above, the request input is automatically validated, and all we need to do is call the persist method and pass in a new Post. I think readability and maintainability should always trump complex and unneeded design patterns.
You can then utilize the exact same persist method for updating posts as well, since we can check whether or not the post already exists and perform alternating logic when needed.
I'm trying to learn MVC pattern, (but without the models because I don't see for what I can use them when I have the controllers).
So I want to display some content in my view. How do I do that?
This is my controller that takes care of index:
<?php
class Index extends Controller {
function __construct() {
parent::__construct();
$this->view->render('mainpage/index');
}
public function wynik($arg) {
echo $arg;
}
}
$klasa = new Index();
?>
And I want to call the function wynik($arg) in my view. How can I do this? My Controller library looks like this:
<?php
class Controller {
function __construct() {
$this->view = new View();
}
}
?>
And in views/mainpage/index.php I'm trying something like this:
<?php
echo $klasa->wynik('abc');
// tried this too:
$this->wynik('abc');
?>
But it doesn't work:
Notice: Undefined variable: klasa in C:\wamp\www\lvc\views\mainpage\index.php on line 2
and
Fatal error: Call to a member function wynik() on a non-object in C:\wamp\www\lvc\views\mainpage\index.php on line 2
This is View library:
<?php
class View {
function __construct() {
}
public function render($name, $noInclude = false) {
if ($noInclude == true) {
require 'views/' . $name . '.php';
} else {
require 'views/header.php';
require 'views/' . $name . '.php';
require 'views/footer.php';
}
}
}
?>
I was thinking - yeah, it searches for wynik() function in View() class, that's why it errors. I want the view to search through functions in my controller. How can I do this?
This code example is not working because the variable $klasa does not exist when you are trying to reference it. The initialization of the object done by calling "new Index()" must be completed first, then that value will be assigned to $klasa. Thus, your code is trying to access $klasa before it exists.
That said, I wouldn't continue to debug this problem. You are missing the point of MVC entirely, and until you understand it, you will not be able to code a controller and view that work well together. Spend time understanding MVC, not by implementing it yourself, but by using another system as an example.
If PHP is your flavor, try the Yii, CodeIgniter or Symphony Frameworks. If you like Python, try Django. If you like Ruby, try Rails. If you like C, learn Objective-C and try iOS.
The MVC model is very simple:
Model- This is where your data is stored.
View- This is how your data is represented to a user.
Controller- This is what your view talks to, so that it can act on the model.
Let's use a simple ice cream vending machine as an example. Assume the vending machine is one of those machines is like this one, where you can't see the items:
Model- The ACTUAL ice creams stored in the back. Lets say, 4 chocolate, 1 strawberry, 3 vanilla. The view and controller don't care how much of each ice cream are there. It is the model's job to keep track of that and make sure we don't have negative ice creams in slots, or other things that don't make sene, for example.
View- These are the little buttons showing what ice creams exist as choices. The view doesn't know or care how many ice creams are in the back, or what ice creams even exist. It simply shows the user something relating to the model, and it doesn't care what is in the model or how the model is structured.
Controller- When a user interacts with the view (that is, they push a button) the controller will take that input and run it by the model. The controller doesn't care how the model is structured, it doesn't know what is back there. All it knows is "When a user presses a button, I need to use the data in the model to make a decision based on that input". For example, when the user presses on a valid item that is in stock, the controller takes that input, runs it by the model, sees that it is ok and dispenses an ice cream. When the user presses on an invalid item that is not in stock, the controller takes that input, runs it by the model, sees that it is out of stock, and tells the view to display an error.
If you get this basic concept down, MVC as a whole will make a lot more sense and speed up dev time dramatically. Understanding MVC is probably one of the more important things for a budding web/mobile developer right now, as most popular web frameworks are based on it (Django, Rails, Yii/CodeIgniter/Symphony), as well as iOS.
MVC is a design patter which combines two layers:
Model layer
Presentation layer
If your application does not have model layer (which contains all the domain business logic), then there is no MVC.
Presentation layer is made mostly from two groups of structures: views and controllers.
controllers : responsible for reacting to user's input and, based on that, changing the state of model layer and view.
views : responsible for the display(or presentation) logic, based information, that view has received from model layer. Based on this information views choose to appropriate response - it can be either just a HTTP header or HTML file, rendered from multiple template or formated JSON/XML data.
But you do not really have Views either. What you call "view" is actually are simple PHP templates.
As for the view accessing controller's methods, it is against all the principles in MVC and MVC-inspired patterns. View is a separate entity, which acquires data from model layer and has the state changed by controllers.
In classical MVC and Model2 MVC patterns the view is active. It requests the information directly from the model layer. Whereas in MVP and MVVM patterns the view is passive and information from model layer is provided by controllers (though in these patterns they are called "presenters" and "viewmodels" respectively).
Views do not use controllers.
Please, do some research before you start throwing terms around just because you think, that it is the latest thing.
Read the following materials:
GUI Architectures
MVC in PHP part 1: Hello World
Model-View-Confusion part 1: Why the model is accessed by the view in MVC
A Description of the Model-View-Controller User Interface Paradigm in the Smalltalk-80 System
How should a model be structured in MVC?
Instead of MVC and not really knowing why and so on, I suggest you another concept called Transaction Script that also work very well with a Frontend Controller or an Application Controller.
Working with Transaction Scripts allows you to get more familiar with OOP while you also benefit from some application structure without the overhead and problems that a misunderstood MVC does carry.
For example within a transaction script object, everything can access the functions of that a transaction. Your libraries, your view and everything else (the model).
Then you will see things growing. But forget Codeigniter and similar, write this from scratch (don't mimic things), you'll learn more and you will have more efficient code.
And you will have it your way, which is great for learning.
For the libraries, just fetch stuff from the Packagist and Pear repositories you will not have many wishes left.
I am not going to add code samples here, but I hope what I say will help you look in the right direction. LVC (Library, View, Controller) is just you changing one name(Model) to another (Library) Doesnt really matter at all, you are still using MVC, you just happen to call your Model a Library. This is a vast topic, but I am only trying to make you see the use of having models and offloading code into that instead of in controllers.
The way to look at it is like this:
Typically controllers should only perform following - check requests, invoke Model(In your case Library) methods, which process those requests, and take those results and pass to the view to render. Think of each function in a controller to be an endpoint URL that the user can type in the address bar and access.
Think you have a function like profile($user_id) in a controller called user, to show user profile and the user accesses it using the url www.mydomain/user/profile/1234.This is all very fine. But what happens if you start throwing in all kinds of utility functions inside this controller like say, strip_all_zeroes(). It becomes bad if the user can access this using mydomain.com/user/strip_all_zeroes, right? It might start throwing all kinds of warnings,errors, or even expose sensitive data..That is where models come in. They can be used to create all kinds of helper functions, whole data classes as required..
Of course this is very broad, over-simplified and not totally accurate, but I hope you get the idea..
I have seen all types of tutorials:
View running controller, controller passing model to the view, controller setting setter of view.
An example: MVC for a reading of a news.
The controller loads the Model. If the result of the model is 'false' I can call another method from another model containing different block.
The View class must be relevant to, View_found View_not_found?
if (model-> news === true) {
$ comment = model-> comment ()
}
Would this code snippet be the responsibility of the controller or is it a rule that such logic should belong to business model?
in my experience, i tend to program the model and view as "blind". the model and view only receives parameters needed and then spits out what is needed. they should do minimal to no logic at all.
for the model it performs minor checks, like parameter type and validity and returns either a result or false. the controller does not know how the data is stored, where, why etc.
for the view, it should receive a string preferably through only one entry point, a function which will do the escape and echo. other than that, the controller should never echo to a page.
everything else is for the controller to digest like validation, calling what's needed, determine what is what. the controller sees everything:
//get from model, pass parameter - that's it
if (model-> news ('all')) {
//manipulate data for result
//get appropriate view
view->parse(html); //pass html to view, that's it
} else {
//manipulate data for no result
//get appropriate view
view->parse(html); //pass html to view, that's it
}
If you want to find model News comment, you need to create Comment model and get it from your dataProvider and render to view.
Here is a part of controller action code :-). All logic must be in controller. Views is only render content parts.
UPDATED I recommend using here dataProvider. Model method (getter) can return DP object for model.
It depends which framework you're using.
Like said Rasmus Lerdorf
MVC is the current buzz in web application architectures. It comes from4event-driven desktop application design and doesn't fit into web application5design very well. But luckily nobody really knows what MVC means, so we can6call our presentation layer separation mechanism MVC and move on.
As a matter of fact, in web application, it is common to use "action oriented MVC" instead of "event MVC".
You've got a controller that knows his model, and the view to apply.
To display news, You must have a News class which is your model, a NewsProvider which deals with your database.
Your controller compute the datas given by the database and the user and call the proper view.
The best practice is to keep business logic in Models
see below links for reference
http://www.yiiframework.com/doc/guide/1.1/en/basics.best-practices
ASP.NET MVC - Should business logic exist in controllers?
http://blogs.msdn.com/b/aspnetue/archive/2010/09/17/second_2d00_post.aspx
As I understand it, MVP is a derivative of MVC where the Model and the View are loosely or completely decoupled, and the Presenter replaces the Controller and acts as the bridge between the View and the Model. This pattern seems more appropriate than traditional MVC in web applications (whether or not that is true is not the subject of this question, so please refrain from going down that direction).
My problem is in implementing the various MVP pieces in PHP, using a passive view. Here is my current flow of things:
The PHP script sets up an autoloader and a router. To me, this means whatever view was in existence send an event of some kind to the server.
The router then determines which presenter should be used based on the request.
Here be dragons. The Presenter acts as the bridge between the View and the Model and should take a View and a Model as dependencies so it can easily be tested. That means I need to know what model and view I should be using before the presenter is created.
The presenter seems to be the class that knows what Model and what View it needs, so how can I move that logic out of the presenter? I understand that the generic pattern to use is a factory, I just can't seem to understand how to implement it in this case.
Perhaps I am doing this all wrong. Maybe I've been coding for too long of a stretch and am experiencing mind warp. Regardless of why I can't seem to understand how to solve this problem, I'll accept any guidance.
Not 100% sure I know what you're asking. You are right that you load the appropriate controller based on the request. That controller is typically associated with a model and a view.
Let's say you have a URL that looks like: http://www.example.com/test/view/1
It would be fairly standard to load the Test controller, call the method view pass it the argument 1. So let's assume you have:
TestController.php
TestModel.php
test.php (view)
When the TestController loads it includes the model, TestModel, where your "data stuff" goes (I think you understand that). So for this example, let's say view wants to load the last 5 posts from the user with id 1. So in TestController.php:
function view($arg)
{
$userID = $arg;
$posts = $this->model->loadPosts($userID);
$this->render('test', $posts); // outputs the HTML in test.php
}
And in test.php, you can loop through $posts and output it however you choose.
It seems like you already know how this stuff works though, which is why I am confused as to what you're asking. Does this clear up anything?
I find it useful to think of Web Apps in terms of states and state transitions. the application is in a particular state, it's "at" a View, some HTML was with the aid of the associated Presenter from data in the Model and rendered to the browser . The user takes an action and this is going to move our app to a new state. So we are moving from one View/Presenter pair to another. In my mind the Model is a longer lived, evolving thing, I don't see us getting a new Model for each transition.
So you have PresenterA, responsible for responding to events in ViewA.
PresenterA receives some event, performs some work that may result in Model changes, and then decides which View to go to, say ViewB. ViewB can create its Presenter. As per the Wikipedia example (not PHP I realize, but the principle is clear):
public class DomainView: IDomainView
{
private IDomainPresenter domainPresenter;
public DomainView() // Constructor
{
this.domainPresenter = new ConcreteDomainPresenter(this);
}
}
In effect the Presenter is the creator of the next View/Presenter pair. If you have more complex logic replace the explicit constructor
new ConcreteDomainPresenter(this);
with a factory, working with View and Model information.
I've always used the model as something to more or less store and execute database queries. I have heard about the fat model, thin controller concept.
The way I setup my models right now causes a lot of junk in controllers for things like validating forms, formatting data. Does form validation, file uploading and data formatting belong in the controller or the model?
I realize this question is subjective, which should create some good discussion rather than a concrete answer.
Form Validation should definitely be part of the model. I generally represent each form as one model and pass it the sanitized post/get paramaters. The model can then take whatever action is necessary based on the input and use a property (optionally with a getter) to signal success or failure. In psuedo code you want it to look something like:
class Controller
{
function action()
{
$input = new Input();
$form = new FormModel($input);
if ($errors = $form->errors())
{
//load the appropriate view for the errors
}
else
{
//load the appropriate view for success with an optional redirect
}
}
You have two main roads to go. Thin controller/fat model or fat controller/thin model. Basicly is were you put most of the interaction. I prefer to keep at the model the major portion of the code. That way, the code is available in virtually every controller and/or lib. If the code remain at controller, it's hard (but not impossible) to use it in other controllers.
Things lije validations and other common tasks should be in a lib or helper. You can produce a set of "workers" (this is the name I give to them) to do the heavy lifting. Also, CI has a LOT of ready made libs and helpers both from the CI team and the community. Mess around the wiki to find the wealth of information available.
Hope this helps
Vx
The model is what interacts with the data (most often a database). Controllers use the models to access the data.