I'm fairly new to Codeigniter as well as MVC and I'm having a bit of trouble figuring out the best way to accomplish this.
I need to build an app that allows users to apply to various programs offered by some institutions. However, these institutions must all have a spot in the app yet they want their independence from one another—not sharing one application page for all programs. For instance Institution 1 wants a section of the site to only view and apply to their programs and Institution 2 wants a section of the site to only apply to their programs.
What is the best way to accomplish this? Should I create a separate controller for each institution?
E.g. sitename.com/inst1/apply, sitename.com/inst2/apply
Each of these controllers would essentially be identical with the same create/read/update/etc functions though. What are best practices in this situation? Thank you!
You can create folders to serve your functionality properly. This is widely used for APIs.
For example. You can have your folder structure like this.
- application/
- controllers/
- inst1/
apply.php
- inst2/
apply.php
With this, you'll have the URL endpoints like.
index.php/inst1/apply
index.php/inst2/apply
I think you have it right, you'd create controllers for each institution allowing you to change what data you were pulling for each. The views could be shared since all the functionality would be in the controller/model which is one of the more important aspects of MVC to begin with, the ability to separate those layers and reuse what you need where you need without duplication. If you set up your pages as a template you could even pull different templates to feed the views to that would be institution specific.
For this you probably want to use the same controller and instead handle the variation through passing your function a different uri segment which you can read about here
. In my codeigniter applications i like to keep a specific functionality within each controller or model. So it might look something like:
sitename.com/my_controller/my_function/my_argument
Where the function in your controller looks like:
public function my_function($argument){
//stuff goes here
}
You can of course use your routes file to make the url look however you'd like.
Just build a single controller, and make a flag to differ them. In the view file you may check for this flag to decide weather to show programs and apply or not.
Your url would be like that:
sitename.com/inst/1/apply, sitename.com/inst/2/apply
note: you may also change the numbers in the url with words; to better seo.
Related
I will be working on project that has different theme for each domain (same application will be serving multiple domains).
I need to change location of templates completely outside the application folder, possible on another volume
I need to make it work with multiple domains with multiple themes - i guess theres cache problem
S how to do this stuff with Symfony2 and twig?
EDIT: I will try to ask this: What or where do I need to rewrite to get custom logic on locating specific templates that symfony uses to render pages.
I can't say if first point of your question is a bad practice (and don't know even if it possible, but I would say yes).
However, what I would do is some kind of "manager" that will takes responsibility for choosing what kind of template render, based onto your own logic. Some kind of "intermediate level" between actions and views.
You could create it as a service and use everywhere, without have need to instantiate it every time.
It could read a file for configuration or, even (but less springy), use a class-internal configuration.
Algorithm could be something like this:
Take into account your request
"Eat" data and "spit out" the correct template (name)
Pass template (name) to your view
Extend (dinamically) the template given by your manager
Please, don't ask me some code because it could result in some hundred lines :)
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'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.
All the examples I've seen of what and how MVC SHOULD be have used classes as the models, classes as the controller, and HTML templates as the view. And all of them consisted of one index.php script and different requests in the url to run the entire site.
So they've all been something like...
MODEL
class User{
function getUser($userID){
$sql = mysql_query('SELECT name......');
// more code.....
return $array
}
}
VIEW
<h2><?php echo $user['name']; ?></h2>
CONTROLLER
class Controller{
$userModel = new User;
$userInfo = $userModel->getUser($id);
$template = new Template('usertemplate.tpl');
$template->setVariables($userInfo);
$template->display();
}
I understand why the model is made of classes that simply get and save data (even though I assume classes arent always necessary and functions could be used). I understand why the template consists of mainly HTML. But I dont understand why the controller is a class. I would assume the controller to be a procedural script (like userprofile.php which gets the users data from the model and sends it to the template for displaying).
Also, I was wondering why every tutorial I've read dealt with mod rewriting, and using a single page with requests in the url like "index.php?user=1", or index.php?news=3 to run the entire site. Whats wrong with having separate pages like user_profile.php?id=1, or news.php?id=3...
Can somebody please help me with a quick "tutorial" and an explanation along the way. Like...how would a registration form be implemented using MVC, what would go where and why? thankyou
PS. what other kind of design patterns are there
The big "win" of the controller in PHP's version of MVC is you get away from having a separate PHP page for each and every URL that your application responds to.
When you have a new single page being created for each URL, you're expecting your developers (or yourself) to pull in the needed libraries and initialize the template/layout engine in the same way. Even when you're a single developer, the temptation to break from the "standard" way of doing things usually ends up being too strong, which means each URL/PHP-page ends up being its own mini-application instead of each URL/PHP-page being part of the same application. When you have multiple developers this is guarantied to happen.
The end results is pages and components that don't play nice with each other and are hard to debug (with everything hanging out in the global namespace), giving an inconsistent experience for both the users and the developers who have to work on the project.
MVC frameworks also make it easier to give your site friendly URLs. There's usually enough going on in the routing system that you don't need to resort to a huge number of query string variables. Readable URLs are a plus, for SEO and for savvy users.
Finally, although this is pie in the sky with most shops, when you have a controller the methods on the controller become easily unit testable. While you can technically wrap a test harness around a non-MVC site, it's always a pain in the ass, and never works like you'd like it to.
using a single page with requests in
the url like "index.php?user=1", or
index.php?news=3 to run the entire
site. Whats wrong with having separate
pages like user_profile.php?id=1, or
news.php?id=3...
Using a single entry point makes some things easier, I suppose :
You don't have to duplicate any portion of code in user_profile.php and news.php
If you want to set up any kind of filter (like PHPIDS for security, or ACL, for instance), you only have one file to modify, and it's done for the whole application.
PS. what other kind of design patterns
are there
There are a lot of design patterns ; you can find a list on the Design pattern (computer science) article on wikipedia, for instance -- with links to the page of each one of them, for more details.
There's nothing wrong with having separate scripts for each action, and in fact you CAN create a MVC architecture this way, without using a class for the controller. I'm working on an MVC framework at the moment that supports both styles.
The important thing is really to keep separation of different concerns. Database logic goes in your models, Layout logic goes in templates, and everything else in the controller.
So for a really simple example you could have a script "register.php" with the following code
$signup_options = SignupOptions::getSignupOptions(); // Load some data
require("register_form.php"); // Pass it to the view
And this posts to register_process.php
$username = $_REQUEST['username'];
$password = $_REQUEST['password'];
$email = $_REQUEST['email'];
Users::Register( $username, $password, $email );
header( 'location: register_success.php' );
MVC is not suitable for all applications, so you should consider your architecture on a per project basis. For many sites, just having a bunch of independent scripts works fine. For larger more complex applications however, MVC has proven itself to be a reliable and scalable way of developing web applications.
Another common design pattern is "View-Helper", which is where you call a template directly, and the template calls a "Helper" object that performs business logic between the template and the models. Similar in concept, but you can skip having any extra code for templates that don't need it, while still maintaining separation of concerns like MVC. (The difference is essentially that you call the template directly, rather than calling a controller).
There are several ways to implement a good application, but I am just going to touch on a few concepts. These concepts are taken from Samstyle PHP Framework.
Firstly, you have these components: Model (Table Data Gateway), View, View Controller and Backend Controller.
This View Controller actually controls how the view is going to be like (e.g. display out the registration form). The Backend Controller processes user data on the backend and interacts with the Model (database).
So here we can easily integrate Post-Redirect-Get into it.
Say you have register.php for the View Controller which will display the form and parse the content into the template HTML file.
User uses the form, submit and will then be posted to the Backend Controller deck.php. The Backend Controller validates, check then passes the data to functions (Table Data Gateway) which will help you to interact with the database. After the interaction is done, the user is redirected either to a success page, or the registration page with an error.
In the Model (Table Data Gateway), you actually have functions which take in an array and then CRUD with the database.
1) Where does the homepage of your website fit into "controllers"? I've seen some people use a "page" controller to handle static pages like, about, home, contact, etc., but to me this doesn't seem like a good idea. Would creating a distinct controller just for your homepage be a better option? After all, it may need to access multiple models and doesn't really flow well with the whole, one controller per model theory that some people use.
2) If you need a dashboard for multiple types of users, would that be one dashboard controller that would have toggle code dependent upon which user, or would you have say a dashboard action within each controller per user? For example, admin/dashboard, account/dashboard, etc.
3) It seems to me that using the whole simple CRUD example works like a charm when trying to explain controllers, but that once you get past those simple functions, it breaks down and can cause your controllers to get unwieldy. Why do some people choose to create a login controller, when others make a login function in a user controller? One reason I think is that a lot of us come from a page approach background and it's hard to think of controllers as "objects" or "nouns" because pages don't always work that way. Case in point why on earth would you want to create a "pages" controller that would handle pages that really have nothing to do with each other just to have a "container" to fit actions into. Just doesn't seem right to me.
4) Should controllers have more to do with a use case than an "object" that actions can be performed on? For all intensive purposes, you could create a user controller that does every action in your whole app. Or you could create a controller per "area of concern" as some like to say. Or you could create one controller per view if you wanted. There is so much leeway that it makes it tough to figure out a consistent method to use.
Controllers shouldn't be this confusing probably, but for some reason they baffle the hell out of me. Any helpful comments would be greatly appreciated.
1) I use a simple homebrew set of classes for some of my MVC stuff, and it relates controller names to action and view names (it's a Front Controller style, similar to Zend). For a generic web site, let's assume it has a home page, privacy policy, contact page and an about page. I don't really want to make separate controllers for all these things, so I'll stick them inside my IndexController, with function names like actionIndex(), actionPrivacy(), actionContact(), and actionAbout().
To go along with that, inside my Views directory I have a directory of templates associated with each action. By default, any action automatically looks for an associated template, although you can specify one if you wish. So actionPrivacy() would look for a template file at index/privacy.php, actionContact() would look for index/contact.php, etc.
Of course, this relates to the URLs as well. So a url hit to http://www.example.com/index/about would run actionAbout(), which would load the About page template. Since the about page is completely static content, my actionAbout() does absolutely nothing, other than provide a public action for the Front Controller to see and run.
So to answer the core of your question, I do put multiple "pages" into a single controller, and it works fine for my purposes. One model per controller is a theory I don't think I'd try to follow when working with Web MVC, as it seems to fit an application with state much better.
2) For this, I would have multiple controllers. Following the same methods I use above, I would have /admin/dashboard and /account/dashboard as you suggest, although there's no reason they couldn't use the same (or portions of the same) templates.
I suppose if I had a gazillion different kinds of users, I'd make things more generic and only use one controller, and have a mod_rewrite rule to handle the loading. It would probably depend on how functionally complex the dashboard is, and what the account set up is like.
3) I find CRUD functionality difficult to implement directly into any layer of MVC and still have it be clean, flexible and efficient. I like to abstract CRUD functionality out into a service layer that any object may call upon, and have a base object class from which I can extend any objects needing CRUD.
I would suggest utilizing some of the PHP ORM frameworks out there for CRUD. They can do away with a lot of the hassle of getting a nice implementation.
In terms of login controller versus user controller, I suppose it depends on your application domain. With my style of programming, I would tend to think of "logging in" as a simple operation within the domain of a User model, and thusly have a single operation for it inside a user controller. To be more precise, I would have the UserController instantiate a user model and call a login routine on the model. I can't tell you that this is the proper way, because I couldn't say for sure what the proper way is supposed to be. It's a matter of context.
4) You're right about the leeway. You could easily create a controller that handled everything your app/site wanted to do. However, I think you'd agree that this would become a maintenance nightmare. I still get the jibbly-jibblies thinking about my last job at a market research company, where the internal PHP app was done by an overseas team with what I can only assume was little-to-no training. We're talking 10,000 line scripts that handled the whole site. It was impossible to maintain.
So, I'd suggest you break your app/site down into business domain areas, and create controllers based on that. Figure out the core concepts of your app and go from there.
Example
Let's say I had a web site about manatees, because obviously manatees rock. I'd want some normal site pages (about, contact, etc.), user account management, a forum, a picture gallery, and maybe a research document material area (with the latest science about manatees). Pretty simple, and a lot of it would be static, but you can start to see the breakdown.
IndexController - handles about page, privacy policy, generic static content.
UserController - handles account creation, logging in/out, preferences
PictureController - display pictures, handle uploads
ForumController - probably not much, I'd try to integrate an external forum, which would mean I wouldn't need much functionality here.
LibraryController - show lists of recent news and research
HugAManateeController - virtual manatee hugging in real-time over HTTP
That probably gives you at least a basic separation. If you find a controller becoming extremely large, it's probably time to break down the business domain into separate controllers.
It will be different for every project, so a little planning goes a long way towards what kind of architectural structure you'll have.
Web MVC can get very subjective, as it is quite different from a MVC model where your application has state. I try to keep major functionality out of Controllers when dealing with web apps. I like them to instantiate a few objects or models, run a couple of methods based on the action being taken, and collect some View data to pass off to the View once it's done. The simpler the better, and I put the core business logic into the models, which are supposed to be representative of the state of the application.
Hope that helps.