Should I have one view for this? Is 2 views alright? - php

I am trying to program in MVC architecture.
So, I have one HTML form where user can insert, let's say, a movie. I have one controller for that (for adding that movie) and one view for the HTML form.
But I also want user to be able to edit that movie after he added it. So, he presses a button "Edit a movie" and he's redirected to the new URL and I have new controller and new view (it has the same form as when user adds the movie, but only now he sees values in inputs which he entered previously, I hope you understand what I mean) for this editing form.
Also, when I want to show how his movie looks like to other users, I once more time have new Controller and new View for that.
edit: I also have to validate what he enters. So, that validations should be in model? Because I validate twice, it doesn't seem right.
Is it correct thinking of MVC? Or what's the best approach for making this? Thanks.

You got it almost right, but there is still some place to simplify it. Common thing is to create action functions inside of your controller which handle certain (surprise, surprise) actions user can do. Usually you'd have, for example, Article controller with actions add, remove, edit etc. This way you centralize actions for common entity of your application and prevent overflow of controllers. It's easier to maintain, easier to find if you want to change something asap and you will nicely follow DRY principle.
Another thing you could do is to create abstract base controller for common stuff that's used in multiple controllers (dynamic loading of meta data from database comes in mind).
Having multiple views is fine. You don't have much of a choice anyway. But I'd recommend using some templating engine which would make your life easier and once again force you to not repeat yourself. Twig or Smarty would be perfect choice.
Validation logic should be located in model. Model is responsible for most of the backend logic (data manipulation, its validation...). Controllers just take requests, loads appropriate data from Models and point you to proper View. Don't get confused though, you usually end up validating your Models inside Controller (calling validate() functions, for example).
Anyway, in the end, you'll find out there are quite many ways how to look at MVC pattern. Some people prefer "fat models" and "skinny controllers", some the other way around. Use whatever fits your needs and keep it simple!
If you want some studying materials, take a look at Symfony2 framework or CakePHP tutorials. There are some valuable information regarding this topic. Maybe you'll end up using one of them instead of reinventing the wheel :)

No, it is overly complicated.
You do not need different controller for another action you want to make on something. Eg. if you have a controller for creating a movie, you do not need separate controller for editing it. You need separate action, not controller.
Basically you should employ DRY (Don't-Repeat-Yourself) rule for that. If view only differs by the values and form's action, just use one view for both actions (create & edit). View should generate similar code for both actions - one will have no form fields filled, with form's action set to eg. "movies/create" and the second one will have prepopulated form fields with form's action set to eg. "movies/<movie_ID_here>/update" (naming convention is up to you).
Validation should be in model, but as additional help for the users you can validate it also on the client side, using JavaScript or HTML5 (depending what you want), so they do not need to submit the form to know they forgot about something.

Using a typical project layout for me, I might have something like the following:
Controllers
| |
| - MoviesController.php
|
Models
| |
| - Movie.php
Views
| |
| - Movies
| |- Create.php
| |- Edit.php
| - Partials
| |- _MovieForm.php
MoviesController contains two actions - Create() and Edit($id), which have their own views. I personally would have a third action as well, which handles the form submission from both actions:
public function Save()
{
//...snip...
}
Create() simply loads the corresponding view. Edit() is slightly different in that it retrieves an existing record from the database first, using our Model, before passing it to the view.
The two views have a nested "partial", which is a fragment of commonly used HTML - in this case, _MovieForm.php, which has our form inputs (which are capable of displaying passed-in values).
The form also contains a hidden input field for our row id. This is only given a value when we call the Edit() action.
The form submits to the Save() method of MoviesController, which checks if we have a passed row id. If so, get our row from the database (again, represented by our Model), update the values, and call our Model's Save() method.Model::Save() runs our validation logic on our data and either saves to the database, or passes the data back along with our validation error message to the view.
Hope this helps :)

Related

Simple PHP MVC framework design

So, for weeks now I have been playing around with my own PHP MVC Framework, purely for learning purposes. I've got the basics done, and I think I know what goes where, etcetera. But I have so far not been able to figure out the following.
Say I have a music database, and I have a "music controller", a "music model" and obviously a "music view". What I want to end up doing is, being able to ofcourse insert a new artist, and/or a new track, also I would like to be able to edit them, and so on. My URL's look like this:
example.com/controller/mainfunction
In my "music controller" I have a method as follows:
public function addTrack()
{
if (isset($_POST["submit_add_track"]))
{
// call the model to add track to database etc..
}
}
So, if I were to have a form in my "music view" and submit that, I could add a new track to the database. I also have a method to add a new artist, and so on.
But here is what I am struggling with. How should I design this? Should I use the music controller to add tracks and artists? Like so:
example.com/music/add/artist
example.com/music/add/track
Or should I do it differently, maybe I should use the "music controller" just to display the artists and tracks, and insert stuff with another controller? Like so:
example.com/insert/artist
example.com/insert/track
The latter seems the way to go for me, but I am not sure if this would be good design.
I think maybe what I am asking is, would it be good to use an "insert" controller, and then a "track method" to display the "insert track" form in the view? Next to this, there will be a lot more pages, not only music. But I just cannot figure out the logic behind this on how to do this properly so I can easily extend.
As you can see, I'm lost, any pointers (big or small) would help me a lot. Thanks in advance!!
Edit:
So, just to see if I'm on the right track now. I have a music controller with the code pasted below. If in the controller the "addArtist" method get's called, it goes to the model, adds the artist to the database, returns something to the controller, and it's done. Now for the part where I still have troubles. How do I display the form to actually add an artist? I know it should be in the view. But how should I call it? Something like this?
example.com/music/insertArtist
This could work, but then I would have an "insertArtist" method, for just displaying the form, and an "addArtist" method, for actually inserting the new artist to the database each time the form is submit. I know I am missing something, but I cannot quite figure this out still. What I am thinking is, in the "addArtist" method, I include the "addArtist" view file to be displayed, which holds the form, and I put in some "if submit then add the artist". Does that make sense and if so, am I on the wrong track?
public function addArtist()
{
// $artist_model->addArtist();
}
public function editArtist($artistID)
{
// $artist_model->editArtist();
}
public function deleteArtist($artistID)
{
// $artist_model->deleteArtist();
}
public function addTrack()
{
// $artist_model->addTrack();
}
public function editTrack($trackID)
{
// $artist_model->addTrack();
}
public function deleteTrack($trackID)
{
// $artist_model->addTrack();
}
example.com/music/addArtist
example.com/music/addTrack
You must strictly follow the format of /controller/method
When I say method, I mean literally, method. In fact, in your base controller class, the way you should call a method is
/**
* Executes the requested action
*/
public function ExecuteMethod($method)
{
$this->{$method}();
}
where you would pass addArtist or addTrack to the method.
Basically, the /controller/ part just tells apache which actual controller class to construct, and the /method/ tells it which method in that controller to execute.
EDIT:
This is the best MVC tutorial I know of. I based my MVC knowledge largely on this. However, it is okay to variate the standard MVC structure a bit to suite your needs better, as long as you do not change the core values of MVC that make it so powerful.
EDIT 2: (reply to your edit)
So what you're asking it how to view the form.
Viewing the form and submitting the form are two entirely different actions, and should be treated as such. Additionally, EVERY controller action, MUST have it's own view.
An easy way to put it, every time a user needs ANY data (or action) from the server, you MUST have an action and a view for that.
What this means, is that you will have two separate methods in your controller, viewForm() and submitForm(). Now, what you showed in your controller class, where you had addArtist(), editArtist(), etc, is inefficient, as you are just aliasing them to their corresponding model functions, which sort of skips the entire point of MVC.
I can't really tell you exactly how to implement the controller, as I do not know exactly what your goal is. But let's assume that you have a page that lists all the Artists, and you have buttons next to each for all the actions (Btw, as I said in the comments, in an implementation like this, if you are displaying Artists and Tracks on different pages, they should really have separate controllers). In this implementation, you would have a controller -> view setup like this:
/Artists/view -> returns an html list of artists with buttons
/Artists/viewAddForm -> returns a blank form you would use for creating new artists
/Artists/submitAdd -> returns an html confirmation page
/Artists/viewEditForm -> returns a form for editing with prefilled values
/Artists/submitAdd -> returns an html confirmation page
/Artists/delete -> returns an html confirmation page
So a user is presented with a list of artists. They have 3 options.
They click add, fill out the form, submit it, and get taken to a confirmation page.
They click edit, edit the form, submit it, and get taken to a confirmation page.
They click delete, and they get taken directly to a confirmation page since there is no data to fill.
The structure for Tracks would be exactly the same.
The way I handled this in my framework was to try and support a RESTful interface. I have
example.com/artist
example.com/track
I then use the HTTP verbs to represent the intent (POST/PUT/DELETE/GET)
It doesn't always fit neatly, but it's one way of doing it.
In your case I would worry about putting too much code in a single file. If you put all the responsibility in an insert controller, that quickly becomes an unwieldy code file. In your case I would probably go with two controllers and then create the right methods on each.

MVC Controller(s) with RESTful API(s), multiple Models and shared Views

Foreword: The following text is of decent size, because I tried to maximize the value to other readers with similar, fundamental and conceptual questions.
Introduction
Currently I am developing an web-based event management tool, which uses the Laravel MVC framework to maintain a proper application structure and ease development.
The goals targeted with the application are to
provide a efficient way to create (respectively CRUD) events
invite registered users to those events
allow users to confirm their participation on previously created events
Following the MVC-Pattern, I created
a Model named Event
a EventController
multiple views
a static event view, displaying already existing events
a form view for creation and editing named eventForm
eventIndex, a list of all events
Up to this point, everything seemed to be relatively straight-forward, but I ran into design problems, when I tried to implement further functionality to allow users to confirm their participation on specific events.
Further Details
For further clarification, each Event has a number of attributes (some omitted):
Title
Description
Multiple EventDates, consisting out of this attributes:
Title
A timespan (for example 09-20-2013 09:00 AM to 09-20-2013 05:00 PM)
The aforementioned EventDate is also a model with an associated database table.
Distinguished by the account a user is logged in with, I made a boolean variable $admin available to all views and controllers, which is used to alter the view event in the following way:
$admin = true: The view is a static page, showing the Events attributes and EventDates in a table
$admin = false: In addition, the view has a hidden form and buttons for each EventDate table row, allowing the users to confirm or decline their participation on each of the EventDates
Using a variable and #if...#endif-blocks to alter the view seems acceptable to me, as, despite of the hidden form, the differences between User-Mode and Admin-Mode are quite small.
The Problem
Now, the problem I am stuck at, is the following:
Who is responsible for processing the POSTed data of the User-Mode hidden form?
At first, here a few facts to the current development state:
The Event controller currently offers the following functions:
/* CRUD functions */
public function CreateEvent()
public function ShowEvent($id)
public function UpdateEvent($id)
public function DeleteEvent($id)
/* Form display helpers */
public function NewEvent()
public function EditEvent()
The EventDate Model is separate from the Event Model, as a Event has multiple EventDates
Confirmations are stored per user and EventDate in another separate table bound to the EventDateConfirmation model
Solution approaches
These are the options I have thougth of:
The EventController, which must be extended with methods like CreateEventDateConfirmation() and so on, leading to multiple CRUD methods, which not even belong to this controller, as they are not directly regarded to the Event model and no change at all happens in the events table
In a separate EventDateConfirmationController, only responsible for getting and setting the EventDateConfirmation model data, with two usage possibilities:
Calling the EventDateConfirmationControler methods from the EventController by using the somewhat clunky
Controller::resolve(DEFAULT_BUNDLE,'EventDateConfirmationController')->CreateConfirmation($params);
Setting the route which responds to the hidden form POST-request to the corresponding EventDateConfirmationController action directly
The first possibility has the disadvantage of calling an external controller in a unpleasant way which seems wrong to me, the second is not practicable when the form also contains data which belong directly to a event and therefore must be handled by the Event controller
??
In my opinion, neither #1 nor #2 are good solutions to the problem, as they seem to be hack-ish and do not fit very well in the MVC-pattern.
What alternatives are available, which would be a clean solution to this problem?
Thank you in advance!
I think you might be able to do #2 and make it a little less hackish but still not have to change much from before. Otherwise I think #1 is not a good choice.
Realistically what I would do if I were in your circumstance is create the EventDateConfirmationController and in the User-Mode view, make it a separate form that is asynchronous ajax. Either submit the form when the user clicks [assuming] the checkbox that he/she is going, or on when they submit the other form.
I definitely feel like javascript can help you keep your code consistent and still MVC like.

MVC design in codeigniter PHP

When should a new model or controller be made? Should there only be controllers that go with a corresponding view 1 to 1 and like so with controllers and models? Or is it good practice to have controllers for functionality not tied up with any particular view? Take for example voting, should all voting code go in a voting controller or be spread among controllers that have views using voting. Seems likely a voting controller would be best.
First of all , you cannot actually implement classical MVC in php. The best you can do is Model2 MVC.
Model - responsible for all the business logic. Has no clue about where the data is stored or actually comes from. The storage and retrieval is responsibility of DataMappers or DAOs. Model itself should never contain SQL. Ever.
Controller - binds model(s) to the view and changes the state of both. It does not retrieve information from models for sending it to view.
View - responsible for all presentational logic. Retrieves information from models and binds it to appropriate templates. View itself is not a template.
You can wither have 1:1 relationship between views an controller or many:many. it depends on how you implement the view itself.
For example, your view can require a separate object which handles the rendering. And providing different type of objects ( this is where polymorphism matters ), you can make your view to render either xml, html or json.
Or you can do the same by changing the templates. A ListView class can render a list of articles as well as list of users, if the basic presentation logic does not change and you provide just a different template for each.
In the case of voting , it seems ok to have a single controller for all voting related operations, and you can have a single view with switching the templates for your output.
Some of this sort of thing is down to preferences and opinion; there's no single correct way. Some approaches might be more flexible, but maybe at the expense of being more complex.
With regard to your example of "voting", that may depend upon how voting is going to be used in your site. Will votes appear on different types of pages? If so, some sort of component is a good approach; the voting component view can then be used to display its data within different pages, with a Voting component controller accepting the results of votes and then maybe redirecting somewhere else (or accepting votes by an Ajax request).
Very often you'll find that a models (and controllers) map more or less 1:1 to tables in a database. So if I have a table users, I might have a corresponding User model, and UserController controller.
Remember what a controller is intended to do: respond to a request, working out which models need to be loaded, then asking them to store, manipulate and return data which is then transferred to the view for displaying. It's fine to have controllers that don't map directly to models. You might have a controller called DebugController that responds to requests to http://examples.com/debug/, and doesn't map directly to a Debug model and table, but gathers information about the system and various models (of course, there is the argument that all that stuff should be wrapped up into a Debug model, which in turn loads other models and assembles the data that the controller requests).
As for views, you will normally have more than one view for a given controller; often one view per action. So UserController::indexAction() has views/user/index.php, UserController::editAction() has views/user/edit.php etc.
The approach might be flexible, that is true.
Models - Describe the tier that is communicating directly with database, all the SQL queries.
You can have model for each table in DB that will handle all actions connected to that table (select, insert, update, delete).
You can have model for each "logical entity", modul in your application that will handle the actions for this entity. Like in your example "Voting", where you can define the logic of this modul.
(Check if the user has allready voted, getVoteCount...)
Controler - Handle the request by executing functions in the model (they should not comunicate directly in DB) and passing the processed data to appropriate View. If you need to present the same data differently on different page, the controler should decide on which view to send the data.
View - You need view for each page, form, module in you application. It is on personal experiance how you are going to organize the views.

MVC for dummies: why does controller have to send anything to views?

If I get this right than function of the Controller is processing POST data and technically making changes to the state of the application (e.g. DB) via Model.
As far as I understand, View also gets data from the Model.
So this is how I understand the workflow:
Client request --> App Front Controller --> (if method = POST --> Controller) --> View --> back to Client
Here Model is used by Controller to read and write data and by View to read data.
So controller is not used every time the page is loaded, in fact, only when app data is added/updated. Most of the times Controller is bypassed.
Thus, how come almost every resource about MVC is talking about Controller sending data to views?
I am trying to write an app using MVC-like pattern. So in my app views always get data for the page from the Model. When Model is updated, I add specific model update time to Memcache. At runtime each View looks up last update time(s) of related model(s) and last time cache for this view was generated. If model was updated before cache was saved, view reads cache, otherwise re-renders based on updated model.
The controller is responsible for presenting views based on the data that is requested. It's there so neither the model nor the view need to know about the request. Yes, the view gets data from the model, but not always directly; the controller may have to make some decisions as well depending on the request.
It's something like having waiters in a restaurant so they can take orders from and serve dishes to customers. It's not the chefs who bring out the meals after preparing them; it's the waiters. It's not the customers who go to the kitchen asking for meals; it's the waiters who take their orders then let the chefs know what to prepare for whom. In the same way, the controller is there to handle client requests, whatever their nature may be. It's a very rough comparison though, but I hope you get the picture.
Unless I misinterpreted your question: The problem is with the view accessing the model directly. That's not supposed to happen as it defeats the reason for the MVC pattern. The view shouldn't know anything about the model itself, so the model can be exchanged for something else - the controller should supply the data (at most times it a flattened or projected way) to the view.
If I did: The controller is never bypassed. Just because it doesn't do anything with the data, doesn't mean it isn't needed - it provides a layer of abstraction between model and view. The point is to be able to exchange the model without having to adjust the view.
The controller is never bypassed as it is required to instruct which views are shown and what data (if any) is used in those views. Each get or post request to an MVC site uses the controller to control what is shown or collected to/from the client.
At its core MVC is used to separate concerns. The model works with the data, the views handle presentation and the controller provides the logic between the two.
If you are a person that learn faster by getter hands dirty with codes or looking to something visual , like me ....
I will suggest you to follow the tutorial in railsforzombies.org . It pretty much explain all the basic using rails , including MVC. In the tutorial , It mention that if you put all those logic in view , It will be messy. The code will sux a little bit because the guys that want to use your code will be confused with codes. By putting all the logic in controller and output it in view. It will be very clear for the person that look into your codes.

			
				
Usually Controller uses Model, and passes proccessed data to View. View shouldn't see Model. Main goal is - to keep View separately from Model!
MVC for dummies: why does controller
have to send anything to views?
This is the main point of MVC: to create loose coupling by separating and distinguishing the application's concerns. You have the View, Model, and Controller doing specific tasks.
Why the need for separation because it's hard to debug and fix a one gigantic godzilla app. Imagine fixing a car made from stone. There are no bolts. Everything is chiseled from a big rock. How hard is fixing that if you just want to change the wheels. You will need to chisel out the rock itself.
The main job of the controller is to handle requests and display the appropriate view. That it's job. It's like asking why does the mailman need to send the mail. Because that's his job.

Blog in CodeIgniter : Where Does the Model start, and the Controller End?

I'm testing CodeIgniter, and trying to create a simple blog. The video tutorial on the CodeIgniter site is nice, but very incomplete. I'm not too familiar with the MVC structure, and I am wondering exactly how a model is used. For instance, I'm currently doing the "admin" portion of my blog, which allows you to create, delete, and modify entries. The view only contains xhtml, and the controller takes care of the rest. What should be in the model? Does everything database related occur in the model (i.e. inserts, updates, selects, etc.)?
Depends who you ask.
Some people like to put as much as possible in the model (validation, data retrieval, etc), and have the controller just poke it to get the data it needs, which it then hands over to the view.
Think about it like this: if you have more than one controller accessing a single model, then shouldn't common things between them be in a common place (as long as that common thing actually has something to do with the model)?
The Model should contain everything database related, and perform all of the basic CRUD operations (Create, Get, Update, Delete).
The Controller should handle all communication between the model and the view. So for example, if you have a form for adding a new post, you should have a view for that form, which is called from a controller. The Controller would check to see if anything has been submitted, and if something has, call the create/insert method from the Post Model.
For me, model is a where I do all 'dirty' work for my data. I fetch, insert, update data to database, all in a model. I create 1 model for 1 table in the db.
Controller will be logic central for a page that I build. It need as slim as possible. If a function go beyond 1 screen, then it's too long (except if it do form validation which is must be done in controller). This is where Model come to play. Controller just pass the data into model. I do checking, processing, and formatting the data in model. My controller then fetch processed data from model, pass it to view, finish.
model = is object that "talking with your database"
view = is object that building user interface
controller = is the commander .. he got command from user and then he pass it on the model and serve to the user through view.
to create a simple blog, try to read Codeigniter getting started. it will help you a lot after you watch the video. the codeigniter references are good documented and well explained. try that first.

Categories