I am a beginner with CodeIgniter still struggling to get a complete grasp on how to use the MVC ideology most cleanly.
I am writing a basic CMS system with the ability to vote on entries and follow people etc, consequently, I have found myself using the same or similar pieces of code across multiple views here and there consisting of various pieces of html and logic such as:
Voting panel
Follow/Unfollow panel
Login/Logout panel
Code to check if a user is logged in etc...
I am wondering where to put this code so it can be unified? I am thinking a helper is the way to go? If I declare the helper in the controller, it can be called from the corresponding view right?
Some of the elements are dynamic - such as a follow/unfollow button - It would need to check if you are already following the user or not and display the appropriate button, which would require a model to check. What I have now is that all the logic is in the controller and it returns an appropriate button, but it seems weird to be returning formed html code in a controller return as well. Should it be more like:
controller checks if you are following someone
the controller passes a boolean to the view
the view calls the helper with this value to draw the appropriate button
Also, as a secondary question, I have been doing a fair bit of looping through mysql arrays in foreach loops to process mysql results returned from the view. It seems like my views are getting somewhat complicated, but I can't think of another way to do it, although perhaps this should be done in another helper as well?
Apologies if this is a naive or repetitive question, there is indeed a lot of discussion surrounding this subject but it is not always easily relatable to another project.
Helpers are certainly one way to modularize anything that isn't DRY. Another is to use Partial Views. CodeIgniter looks like it supports partial views. Here's a good breakdown - not PHP specific but the discussion should be agnostic.
As far as handling user logins is concerned, you will probably want to use a static class and the singleton design pattern, which will allow you to check to see if a particular user is logged in or not anywhere in your application. There is a good tutorial here
http://www.phpandstuff.com/articles/codeigniter-doctrine-scratch-day-4-user-login
Loading the helper, I don't believe loading it in your controller will automatically load it in your view. I think you have to re load the helper in your view file, or you have to autoload the helper. (cant remember off top of head but Im pretty sure).
Regarding looping through the mysql results, you should be using a model for this, always. Any functions which are grabbing or sorting information from your applicaiton, should be done within the model. Then, in your view file you loop through the results and format the data how you choose to.
When developing http://newspapair.com which has the vote functionality you mentioned I used helpers and custom classes to spread the functionality across multiple views.
Helper - has functions without a class. So a standalone function or group of functions can be placed in a file and saved as a helper.
For instance I used a helper with generic form processing functions for NewsPapair, instead of a static class. But this is not the "best practices" thing to do. I did it this way because I already had the functions from a previous project.
As far a looping through MySQL results, try to write a query that allows the DB Server to do the heavy lifting. This will make your code more efficient. Perhaps ask a question about a specific query with example code. Plus do all of the data gathering in your Model.
Related
I have searched the web and found only styling code posts. I want to write site using Code Igniter and I wonder how should I maintain my code.
For example:
Should I use one class for static pages and methods for each page or separate file for every static page. Should I use the same file to load dynamic pages or different one?
Can I use some common code and include it automatically to every class?
How can I have lets say header_view footer_view etc and then just load->view('whatever') and footer, header and other files would load automatically. Maybe there is better way to do that?
In generall what are the best practices when coding using CodeIgniter.
You can use one single class for static pages (and use one method for each page).
You can use the same one to load dynamic pages, but it is better IMO to load them with a separate class. It will be easier to maintain later.
Using common code: You can always override the CI_Controller with your own, and instantiating controllers from yours. Here is an example about how to do it.
You can load multiple views in a single controller function. A view doesn't have to be a full html document. You can also load the same view multiple times (for example in a loop).
Best practices: CodeIgniter is an MVC framework. IMO, MVC is a best practice. Always use the framework's documented features if they are suitable for what you want to achieve (CodeIgniter's documentation is very good. That link is momentarily offline, so please try this one).
Codeigniter is a MVC based framework, MVC is basically used for organizing your code, so at last its up to you how you are going to use it so ease you on the long term.
Basically when I design large projects in codeigniter I tried to to make unit of functionality at one place lets take example of any simple users, messages based project.
I tried to make functionality by grouping main topics, in this example user will be a controller, in that controller there will be methods like login, register, edit, listing, forgot_password now I'll create single model with all the methods which will give data for these above methods. by using this methods our urls will be also meaningfull like /user/login, /user/register etc
like that if its messages I will create controller message and add all related methods in it so that my related functionality will be in a single group.
as far as the question of static pages you can also group them in a single controller if they can be a part of group.
you can also use codeigniter's caching technique for static pages so that your pages will load faster
I recently went through some tutorials on how to program your own PHP MVC framework. To avoid some questions and comments: I don't want to use it in a productive environment, I just like to fiddle and get the idea of whats going on in MVC.
So far I am able to have single pages eg. http://domain/news/show/3 shows me the news-record from the database with id 3 and http://domain/news/all lists them all on one page.
Now I have multiple entities and thus multiple lists and want them all to appear on one page. Preferably the page you see when you open http://domain/
Do I have to write a new model and controller that makes calls to the other models? I'm kinda unsure how to achieve this.
There is no strict definition or convention on this that I'm aware of.
What I would do is this:
Class Overview
Controller_Homepage
Controller_News
Model_NewsArticle
Behavior
Controller_Homepage
Action_Index fetches multiple Model_NewsArticle entities, has them rendered, and passes the output to view. Also fetches any other entities you may need and gives their rendered output to view.
Controller_News
Action_List fetches multiple Model_NewsArticle entities, has them rendered, and passes the output to view.
Action_View calls Model_NewsArticle::factory($id), has it rendered, and passes the output to view.
Model_NewsArticle
Contains a static factory method that accepts an $id. Returns an instance of Model_NewsArticle.
Contains methods used to find multiple articles. A query builder would be nice here.
That's by no means comprehensive and I've left out lots of little details, but it's fairly simple and is pretty dry.
This is a matter of preference really. Having another controller and model makes code separation easier in larger projects. Personally, I would only make a new controller since it is a different page with potentially different actions, and I would use the existing models to get the data to keep your code DRY (Don't Repeat Yourself).
I'm learning the OO and MVC paradigm (using Codeigniter and PHP). I continue to find warnings such as this: If you find yourself pasting the same code into multiple files, then you aren't using OO/MVC properly. So, here's a question for more experienced programmers.
I have a create-user form that I am using two very similar versions of:
Version 1 (at /volunteer/register) is created by an anonymous user. The form lives in the volunteers controller, and needs to be verified by an admin.
Version 2 (at /admin/create_volunteer) is created by a logged-in admin. The form and validation is nearly the same, but it is submitted with different parameters.
Another, similar example:
I want to build different user dashboards that share a template, but will be used by different user roles and have different functions and information based on role. As I see it my choices are:
Create a Dashboard controller with three functions defining the data loaded into the dashboard template.
Add the a dashboard function to each role's controller (Volunteer, Admin etc).
Create a controller for each case (Volunteer, Admin, etc.)
I apologize if this appears sophomoric but essentially I'm looking for rules-of-thumb to determine how to design architecture in MVC.
My questions:
In the first example, is my logical choice of controllers (Volunteer & Admin) less than ideal? Is code replication in this case an acceptable practice?
Can anyone recommend architecting tools to establish logical consistency and good workflow for MVC?
Especially since the two forms are not the same (different rules, different interface) there's absolutely nothing wrong having two separate view files if you need it. Loading the same view file in two different controllers or methods is perfectly acceptable, indeed it's appropriate. If there are only a few tweaks that need to be made, try to reuse the view file by passing different data to it.
If you want to simply load the form view file in different instances, that would save you some code duplication. Just set different rules and if needed, pass different data to the view. It's similar to using the same form to create and edit something in two different methods. If the output is going to be totally different, just write separate view files. If it's the same output but with different data - definitely reuse it.
Don't get obsessed with trying to not duplicate view fragment code - if you are writing even more code to force the reuse of a view file by modifying it for different instances, it kind of defeats the purpose. Try to just make it a general practice to make your code as reusable as possible.
So, without seeing your actual code - I'd say don't worry about it. In my experience, view files for front-end and back-end are almost always unique (completely different UI). In general, if you find you are duplicating the same very similar code a lot, it's time to write a function, class, or template for it.
It seems you would like to use some ACL for distinction between roles (Volunteer and Admin) that will check whether requested module or action can be accessed.
Creating different controllers for the roles doesn't seem to be a good choice since this architecture could not be reused - you don't want to reuse specific Admin or Volunteer functions in other applications but rather a module that lets you create and control such roles.
You would like to reuse a code offering particular functionality, this might be one controller, one model and some view files.
Most programmers consider duplicated code as a sign that the solution to a problem still can be improved.
If the problem in your case is that the from is defined in one controller but you need to use it in another controller as well, then you need a better place to define the form so that both controllers have access to it independently from each other.
Make the form configurable so it's possible to reuse it.
I know normally the data is passed thru to the view with the controller. however, currently in my view I load my model ($this->load->model('Db_model');) so i can use it in a loop to retrieve a users profile picture path from a array of IDs that is passed from controller. Will loading the db model in the view to accomplish this make my site more vulnerable or bad form? To me it seems to be outside of MVC concept but its working atm. thanks
I agree, but it has everything to do with scale. If you are designing a tiny app MVC does not really matter because it is easy to oversee the whole application. However once an application starts to grow, or if you are building a bigger application MVC separation becomes more important.
For instance if you use models in your views, this implies the design team has to know about models. It may also hamper porting the views later on to another framework or swapping templates.
Well if you do something outside of MVC it doesn't mean that it will stop working the very same second. MVC is just a design pattern which should help you design and maintain your site. The basic principle is that model should communicate only with controller and view also only with controller so your idea of calling model directly from the view is not MVC way of doing things.
If you need some additional data from the model why don't fetch it in controller and pass it as another parameter to the view so it can easily use it? It will be the same amount of code probably and your code will be much cleaner. Keeping your code clean may not seem like such a big deal right know when you remember where everything is stored but in few months when you forget some of this stuff you may end up with a headache if you mess your app too much.
Look into Libraries. You should consider creating a library class helper for displaying the profile picture. You can then have the library call the model. Then, in your view, you simply do:
<?php $this->profile_helper->display_picture(); ?>
where profile_helper is your library class and display_picture() is your class function to display the users profile.
This is my first foray into using an MVC construct (CodeIgniter). I'm hoping someone can tell me where the following elements belong. I have them written; I just want to make sure they're placed properly in their respective locations. This is how my application will run:
Call a DB and see if we have a user signed up
Route to a signup page
Route to the main preferences page for existing users
Make DB queries for producing a new user
Make update queries when users change their preferences
The service being provided is a cron job cycling every 10 minutes, which I still have written outside of CodeIgniter. Is this something I should/could add to the logic somewhere? It pings Twitter, and does stuff with any new tweets. Let me know if I can clarify any part of this!
Model
Controller
Controller
Model
Model
Rule of thumb: if it involves the database or the state of the application, it belongs in a model. If it is HTML or presentation logic, it belongs in a view. Controllers handle the rest of the logic, and help link the views and models together.
There are a lot of other things that come up too:
Where should I sanitise data? As it comes from the model - in the controller or finally before I view? I do it generally in the view if it's something like htmlspecialchars() (though I'm sure others might disagree).
Wikipedia has a very good article.