Is this ideal CodeIgniter App Architecting? - php

I have a pretty good handle on using models to make database calls and handing the data off to...
I understand views and ideal usage. My general thoughts are to create the following for each section (for the most part):
PEOPLE
- controller
- model
- view(s) // add, edit, profile, etc
- library // specific logic and output
then when I want to access people related data; Say from my BORROWER controller I’ll call the people library function and load the appropriate people view into the BORROWER controller and into its view. AND, same naturally for PEOPLE logic. DRY.
Is this ideal?

You can try using HMVC extension for CI where you can develop on modular approach for MVC. This will allow you to load application modules with its own controllers, models and views. The modules can call any other module and can load models of other modules. Have a look in here

Related

Laravel controllers for complex pages

I have started a new laravel website project and I have hit a road block in my understanding of MVC. I need to refactor to continue but I don't know the best way.
Currently I have web pages that display the results of a single bit of logic. I.e. A page listing all users, a page listing the details of just one user etc etc - all handled by a userController. This applies to other pages being handled by other controllers.
I have created models directly relating to the tables in my database, and controllers in relation on the models. I moved the business logic from the controllers to services. The controllers use the services to perform the business logic and with the data returned, pass that data to the views.
This nicely groups similar functionality together and works fine.
userTable -> userModel -> userController -> userService
clientTable -> clientModel -> clientController -> clientService
...
In my routes, I have pages which do related functionality use the same respective controller, but individual methods depending on what the page does
/listallusers -> userController#list -> userList.blade.php
/listallclients -> clientContoller#list -> clientList.blade.php
/listdetailofoneclient -> clientContoller#details -> clientDetails.blade.php
This is ok when dealing with pages that do that functionality and (apart from using services) seems to be what is hinted at in the laravel docs.
However, I'm starting to get confused about controllers when dealing with pages that either don't really use functionality from any of the services or pages that heavily require functionality from multiple services (and the data needs complex manipulation like formatting or such).
A basic index page.
What controller would handle this? The index might link to routes that are handled by existing controllers but it probably won't need to display much functionality apart from that. That means the controller won't need to pass much complex -if any- data to the view. You could stick the logic to return the view in the route file but that is pretty tightly coupled.
A page that shows complex client and user data
You need to pass client data and user data to the view from the controller. But from what controller? This is the part that is really holding me back.
Because I have a limited number of pages but lots of logic displaying on each page, I was thinking of making a page controller (or something) which would handle the routing. Although I have looked, I have not seen any real mention of this idea anywhere which makes me think I am either reinventing the wheel or have failed to grasp some basic concept in laravel / MVC.
Would the page controller in this case handle all the routing? Would it handle only the pages with 'overlapping' existing controller functionality and the pages that don't fall into the existing controllers? Is a page controller even a good idea?
Some more points that have made me question MVC from this issue
Do controllers need an equivalent model?
Can controllers 'control' other controllers in order to separate logic?
I'll take a shot at a couple of these questions.
Having a PageController or HomeController is very acceptable. Controllers don't have to be linked to a specific model, for instance an AuthController would handle logic for logging in and out but isn't tied to a model, or PasswordController which handles setting/resetting passwords, or a PaymentController that handles billing routes. A controller is just a way to organize logic for related routes in one file. Static basic pages are related routes so a PageController makes sense to me.
Are users tied to a specific client? If so you can arrange your controllers in a nested way so you have a ClientController and a UserController and your routes look something like this:
/clients/{client}/users //list all users for this client
For heavy data formatting it's probably best to use a service provider and use dependency injection to inject it into controllers where you need to use it. This allows you to detach your data manipulation from your controller so you could change it out if needed. Say you are using a software to make charts, and you want to change it out later - you want that formatting logic to be removed from your controller.
I hope I helped in some way... sort of a train of thought here!

Need advice on organizing code

I'm using CakePHP 2.2.3 and I need to build an admin/dashboard area for my site.
I have many models and controllers related to this models and in the dashboard I need to have the ability to CRUD all posts/users/news etc.
Obviously I need to build a Dashboard controller with some index action which will be show dashboard "home" page.
My question is: where to put all other actions – for posts/users/other things adding/editing ?
Should I put all this actions in this new dashboard controller or it's better to put this actions to related controllers(Posts/Users..)?
Keep your specific actions in each of their own controllers. A DashbaordsController is fine for whatever pages need to display a lot of different model information, but CRUD actions should be kept in their own Controller.
If you want/need a single page to be able to actually do the CRUD actions ON that page, you can use ajax and STILL call the actions of that specific Controller.
Bottom line, if you try to put all your CRUD into a single Controller, it's just going to get messy, and will be very confusing for future programmers (which includes yourself 6 mo from now).
It's so easy to include data from other Models $this->loadModel('MyModel');, that doing CRUD actions in their own respective Controller is not much of a hindrance. Again - the DashboardsController is still fine for those few pages that really are like dashboards, and have no alliance toward a specific model. But not for each model's CRUD.
Generally the ideal way is to do skinny controllers and keep logic as far down the stack as possible that is near to the models. Ideally you'd want to introduce libraries for code reuse and testing. Robert Martin aka Uncle Bob says that the web delivery and databases should be as much of a plugin as possible. This lets you unit test much better. As far as your particular case i'd want to keep it close to REST as i can so separate controllers ideally delegating to some lower level stuff.

Basic MVC (PHP) Structure

I have the following data flow for a simple login form.
User access controller PHP file. Controller includes model.php and view.php
User submits form, controller sends POST data to model methods, and gets a result back.
User is logged in, and forwarded to a different view (login success message) by the controller.
Currently my views are static HTML (no PHP), so here is my question. What is the correct way to then pass the user a welcome message, e.g "Hello, Craig!"?
Is the view allowed PHP snippets, e.g
<?php echo $username; ?>
since the model is loaded before it in the controller file?
Thanks!
Edit: Is it better practice then to allow the view to access specific class methods e.g
<?php $user->getUsername(); ?>
as opposed to just variables?
Based on other answers, I have found a very useful article, which you may also be interested in.
http://www.nathandavison.com/posts/view/7/custom-php-mvc-tutorial-part-5-views
Here are few things you must consider:
You cannot do classical MVC in PHP. Instead we have MVC-inspired patterns
There exists 1:1 relation between view and controller instances, when implemented for web
Model in MVC is not a class. It is a layer, that contains a lot of different classes
View is not a dumb template, but an instance of class, which deals with presentation logic
View in Web-based MVC
As stated above, views in MVC and MVC-inspired patterns are responsible for presentation logic. That encompass things like showing error messages and pagination. To do this, each view can handle several templates.
View receives information from the model layer, and acts accordingly. The way how the information from model layer ends up in views is one of most significant differences in MVC-ish patterns:
classical MVC pattern
Structures from model layer send the information to view, when state of model has been altered. This is done via observer pattern.
Model2 MVC and HMVC patterns
View has direct access to the model layer and is able to request information from it. This is the closest to the original pattern.
MVVM and MVP patterns
View receives information through controller, which has in turn requested it from model layer. The further difference in patterns stems from what the do with data before passing it to view.
What you seem to have now is actually just a template. Similar to one, that is described in this article. You end up with a structure, that has no place to contain the presentation logic. In long-run this will cause the presentation logic to be pushed into controller.
So what about that "welcome" message ?
To show the welcome message, your view should request from model layer the name of current user. If the model layer returns some sort of error state, view pick the error message template and inserts into the layout.
In case if name of the user was retrieved from model layer without problems, view pick the template which would contain the greeting, sets the value in the template and renders it.
In what order parts should be loaded ?
The idea, that controller should initialize model and view, comes from very primitive interpretation of MVC for web. Pattern know as page controller, which tried to graft MVC directly on static web pages.
In my opinion, this should be the order:
Model
You initialize the structure, through which you will deal with model layer. It most likely would be some sort of service factory, which would let you build things like Authentication service for logins and Library service for handling documents. Things like that. I wrote a bit long'ish comment on model layer's structure earlier. You might find it useful.
View
You create a view instance based on information, that you collected from routing mechanism. If you are implementing Model2 or HMVC, then your view will require an instance of Service Factory in the constructor.
If you are implementing MVVM or MVP, then view's constructor has no special requirements.
Controller
This is the last structure, which you create, because controller is responsible for sending commands to both view and model layer, which then change then change the state of both. Therefore controller should expect to receive both view and service factory in the constructor.
After basic elements of MVC have been initialized, you call a method on the controller, and render current view.
Just keep in mind that this is very simplified description.
You can really put anything in a view that you'd like, but to better adhere to the MVC way of doing things you should restrict PHP in the view to simple echos or prints (possibly really small loops as well, although even those can be pre-calculated in the controller/model). Since that is the only way to get dynamic content, it would be a little silly to say that they are not allowed.
The idea of the view is to let it have a more HTML look-and-feel, so that front-end developers or people who don't know PHP can easily be able to work with the file without getting confused.
Update
To learn more about MVC in general, you can see any of these (there's a ton of tutorials out there):
http://blog.iandavis.com/2008/12/09/what-are-the-benefits-of-mvc/
http://php-html.net/tutorials/model-view-controller-in-php/
http://www.tonymarston.net/php-mysql/model-view-controller.html
To see concrete examples of PHP using MVC, I suggest downloading some of the more prevelant frameworks (such as CodeIgniter, Symfony or Drupal) and just looking through the code. Try to figure out how it works and then recreate the functionality for a simple article-based system.

What could I do to improve my MVC?

I'm thinking of re-working my MVC before I get to far along with it. At the moment it uses a sinle controller which takes the user input and determines the model. The model has maby differ methods which I call actions, because one is called automatically. The model loads its view file, which again holds many different methods. The model can set properties which can be used in the view. Then the controller calls th template classwhich parses the output for display.
Is this the bst way to do it?
Or should each different part (news, contact, about) have its own controller, which loads a specific model and view. Essentially, instead of grouping methods into a single file, it uses multipe files.
I'm kind of lost as to how I should do it.
Cheers
Start using a MVC that works and is well-known like in Symfony or Cake. From that you will decide:
what do to in your own, knowing the best practices;
to drop your own if you feel like you can save time by using theses.
If you are thinking of advancing your own MVC model, like #e-satis have said, you will need to experience what is happening in already developed systems. However, as based on my experience in designing MVC model and determining what is there in opensource community, I stick back to my own MVC for two good reasons. One reason is the flexibility of customization and the other is own MVC privacy.
I used the following approach for MVC design pattern.
A Router.php file identifying user-request urls. This router will be able to fetch controllers and include the file and call the controller default method.
The loaded controller is also able to load other controllers if required to function. This is done using a global method, where all controller Class will extend to a MainController Class which is able to call to other controllers.
I do use a global registry to set and get variables from one controller to the other.
The Models are used to get the Data from Table, and most of my Models will represent Database functions which includes CRUD (Create Read Update Delete). So that a controller can easily manipulate database table data using a model.
Naming conventions in all controller, models, and views is also important, if you want to system to be more intelligent to identify the required action knowing the file name.
I use the Views separately for each type of controller. And these views will be sent to a Master Template View file.
Same as models, the controller will be able to set Views to Master View.
There are other customizations which you can do, like applying security methods before calling a class, or after calling a class/controller/model/view etc.
This is done by the MainController, which it will always look into a folder with autoload class which states what files should be loaded before and after of different actions during the process of building the content and delivering the output.
MVC is not a small scale idea, but it is a design idea which can always be developed. There are so many PHP MVC open source frameworks to be found if you know how to search the major search engines like google.com
But I do advice you that, MVC is not a good solution if you are simply developing a small dynamic website, as it will consume more time in developing compared to developing small websites. MVC is ideal, if you have business logic and needs system automation in order to avoid most routine tasks of developing, and like that I would say MVC is most ideal for larger applications.
The model loads its view file
The Controller should act as a Mediator between the Model and the View.
The Model shouldn't be aware of the way the view renders it, and also the View shouldn't be aware of any kind of logic of the Model.
In theory, if your MVC is well structured, you should be able to represent the same Model with different types of Views (HTML, XML, JSON for example).
Build FrontController which parses request uri and decides which controller to load and which method to run. With .htaccess rewrite all request to index.php
//index.php
class FrontController{
function run(){
//parse request uri here /comment/new
//load controller comment
//run controllers method new and pass some request attributes
}
}
// ../controllers/comment.php
class Controller_Comment extends Controller{
function new($request){
//do stuff here
}
}

models using controllers?

is it usual to use controllers in models?
then you have to include the controller in the model?
Models should not be using controllers.
To clarify, using the MVC pattern, the user communicates with the controller which manipulates the model which dispatches its results to the view back to the user.
Image taken from The Model-View-Controller (MVC) Design Pattern for PHP
Update to Doug's response:
The most logical way to explain how the components work is by starting from the model, then going through the controller, and finally reaching the view. And "MCV" would not have been nearly as appealing a name to the ear as "MVC."
Taken from Chapter 1 of Beginning ASP.NET MVC 1.0 by Simone Chiaretta and Keyvan Nayyeri.
No it is not common. You should never have to use your controllers from your model.
If you feel the need to, it probably means code that is currently in your controller should live in a shared library, or actually be in the model to begin with.
It is of course proper to use a model from a controller.
Update
Code that doesn't directly relate to a specific database table/record (model), or doesn't directly respond to a user's action (controller), would be a good candidate for a utilities or library file.
This is more normal, and where you load it depends on if you are using a framework or not. If it just your custom app, you can just do a require_once in your model and use the utility methods from there.

Categories