I'm building a simple Virtual Learning Environment(VLE) system for a test project with CakePHP. The project contains the following:
Courses
Lessons
Questions
Answers
I've made the Controller, Models and Views for the courses and Lessons and I'm able to add lessons to a course and delete them. I've generally been following cakePHPs blog tutorial and changing as I go along.
This however leaves me with a very rigid structure of content and pages and URL's (I understand how to change the URL's to be more user and SEO friendly with Routes). My pages are all /{controler}/{method}
Part of the project is to create a management panel for the courses. On the page you can see lessons, and the students assigned to the course with links to add/edit these.
I can not however work out how to do this combination of several models into an admin style page. I can think of a few ways of dong this involving perhaps cakePHP pages, or routes and bringing one models data into another's controller to get it into the view. However I am trying to find out the correct way of doing this with cakePHP or failing that in MVC frameworks in general.
I apologise if this is laid out anywhere obvious but I've looked and have yet of find any answer that coveres my issue is a laid out fashion. Unfortunately I really need this spelling out for me as I'm just overwhelmed with a lot of MVC without anyone to ask and haivng only worked in CMS systems.
Just create a Controller called "DashboardsController" or something like that.
Within it's actions, you can load any model(s) you want, then use it just as you would in the respective Controller:
$this->loadModel('Course');
$courses = $this->Course->find('all');
$this->set(compact('courses'));
This is a very common problem/solution, and I believe I even asked this same question a few years ago on here myself (though I couldn't find it). You still retain the MVC structure, as it still acts as the Controller - it just accesses methods from varying models.
It's incredibly common to call more than just the model of the controller you're in, so in a case like this, you just load whichever models you want/need.
You can make a Dashboard.php model as well and just set
$useTable = false;
to tell it you don't need a "dashboards" table.
I have one of these "generic" controllers in almost every project I do, and am not really sure of any other/better way to handle it. This seems the cleanest, easiest, and most logical approach IMO.
Related
I am currently trying to understand how the MVC framework does work in PHP. Therefore, I have created this basic sketch of how I think that MVC is implemented in PHP:
[I know that some steps are missing, e.g. how the Routerparses the route in order to know what View and Controller to load, but these steps are rather technical based and are not important in order to understand the general flow of MVC in PHP.]
I draw my understanding of MVC in PHP from this article series. However, I think that this structure will differ from most of the structures people think off, when they talk about MVC in PHP, because of this article (The article basically states that not only the Controller but also the View does communicate with the Model).
What I'd like to ask you now are several questions:
Is this generally a right way of implementing MVC in PHP?
How can I add a Login/Logout-System to this approach? So that user, who are not logged in, will always see the LoginView and users who are logged in can see different views? (I know how a login system does work, but I can't figure out where to place it in the MVC, so I don't have to insert the code multiple times, e.g. in each Controller.)
What if my application consist of multiple elements (say a user bar [with user name, link to settings, etc.], a navigation and a content container) that are always loaded? How can I assemble these elements to a final view? (The only idea that comes to my mind is to assemble the final view in each view separately, but that would mean that I have to insert the code for it multiple times in each view, which misses the point of MVC, doesn't it?)
What if I want to use AJAX in my application? My idea would be to send ajax requests through the framework as well, while only accessing controllers and views that are made for ajax? In other words the AjaxViews do only return e.g. json objects and the AjaxControllers do always expect authentication codes to prove that these ajax calls are legtitim?
I know that there have already been asked dozens of questions about MVC in PHP and I've been reading quiet a lot of articles until now, but I think that only reading does not enable me to understand MVC completely.
Furthermore, after reading the articles linked above, I'm not longer sure whether other articles about MVC, I find on the web, does explain MVC the same way as the articles above. Because if they don't, I'm trying to understand one framework while reading about two or multiple different approaches.
Thank you very much in advance for taking the time to answer my question!
-- --- --- Update --- --- --
According to the answer below I've changed my MVC sketch. Just in case someone finds this link and wants to know more.
Let me first answer your questions, then place my take on it.
There's no right way of writing MVC. There are so many flavors and variations, and that get even multiplied when talking about web MVC.
About Logging in and Logging out. I think the most robust system would be a Role Based Access Control combined with an Access Control List, see How can I implement an Access Control List in my Web MVC application?.
There are generally two approaches, either you have a 1:1 ratio between Controllers and Views, and then after the Controller is done, your bootstrap script calls the View with the same name (LoginController, LoginView), or your Controller returns the View name along with action and parameters, to be called by the bootstrapper. The view then picks a template, and that template can include other sub-templates (like the user bar, or the footer).
In that case, your view needs to have an ability to select a different template based on the Accept: HTTP header (and send something like Accept: application/json in your AJAX requests). Your view then returns a JSON template instead of an HTML template.
What is wrong with your sketch?
Your model isn't just the gateway to your database, it's where all the logic happens. All the computation. See this yet another excellent answer that explains How should a model be structured in MVC?.
The idea of MVC is to simply separate your application into three layers: Input (controller), Logic (model) and Output (view). This is to extend on the usual way PHP works (here's a request, give me a response, all in the same page).
For that reason, implementation details may vary, the concept is what matters. "Web MVC" is merely the result of good OOP practices and some naming convention someone made up a few decades ago.
It is for parallel development and code reuse ability. There is a separation of concern how your system works and how users work. This provides a solution of the problem. There is boundry now, MVC.
I am testing an MVC framework to use in my project and i have few questions regarding the YII.
I have create a model using GII, I know from java the code generation suppose to be a helper and most of the time should not be modified, because you may want to regenrate in the future, how is that suppose to work here?
I have created a CRUD out of the model and it gave a nice gui for it, I want to keep the gui for the admin side but i want to do a different one for the user side, what is the approach here?
If i am deciding to use some ORM in my app, this means that i need to create a different model, and i see that the current model inherits from an other one... problem?
In general
Which is suppose to be faster in terms of load, CI? or YII?
correct me If i am wrong but MVC architecture does not really gives you a way to be really OOP, like java. interfaces, inheritance and polymorphic, it is a nice way to build a nice app quickly, not more than that. I am saying that because your controllers and model are already inheriting some classes.
Thanks
1) Usually models work ok after generation and most of time there's no need to change anything. If you add a field in your database and you need to regenerate it, when you do that you have in gii what's the new code, so you can copy/paste. Usually you don't need to do that, when i add fields to a database I add those fields in the model "by hand". Very easy and quickly, trust me
2) use templates. Create a new template in your layout views, and assign it to the controllers of the front end with $this->layout = '//my//layout';
3) Yii AR implementation is enougth for me. Can't answer to this questions, but you should not have any problem.
4) Depends on what kind of app you are running. I have worked with CI and Yii, i prefer yii for developer time and for speed.
5) You are "right" with that point.
Well, I have been thinking a lot about the first real CodeIgniter site I am coding. I want to modularize the site in such a way that I have a controller that formats the navbar, one that formats a multipurpose right column, and one that formats the content area.
My idea is to have a controller for each state of any part of the site (an example would be the right column, it would have 3 states; new posts, related posts, and search filters). I would also have the content area be many different states aswell (things like search results, view post, new posts, etc).
The problem is that I can't find a way to take multiple controller outputs and compile it into a single template (notice, I said controllers, not views).
I have seen the HMVC extension, but that is going to far for my first site, and am hoping for a more simplistic solution (unless you can prove me wrong, and show that HMVC is easier than what I've seen).
This seems a little wonky to me in an MVC model.
If you're using a single stateful view for your right panel that might change state based on input (i.e. which page the user is currently on), then I would add a model for the panel. The controller's action would be responsible for setting the correct model state (i.e. "you're in home page state"). The model could be responsible for telling the right panel view which child views to load.
That's how I'd probably implement something like that anyway. HMVC seems overkill and with this example, wouldn't be used as intended.
For what you're trying to accomplish the matchbox module suggested in the comments seems way overkill. I don't think that using controllers to format each of these areas is a very good approach to take.
Usually people who want the type of functionality that you're describing when working with CodeIgniter end up using a template library. There are several open source template libraries for CodeIgniter that can easily be found with a google search for "codeigniter template library".
I've never used any of them so I will not recommend any particular library. However the app that I'm working on has borrowed some ideas from Phil Sturgeon's template library. You may not find an exact match to features that you need but at least you'll be able to draw some inspiration from solutions that others have come up with.
I'm looking for advice, tutorials and links at how to set up a mid-sized web application with Kohana 3. I have implemented MVC patterns in the past but never worked against a "formalized" MVC framework so I'm still getting my head around the terminology - toying around with basic examples, building views and templates, and so on.
I'm progressing fairly well but I want to set up a real-world web project (one of my own that I've been planning for quite some time now) as a learning object.
I learn best by example, but example-based documentation is a bit sparse for Kohana 3 right now - they say so themselves on the site. While I'm not worried about learning the framework as I go along, I want to make sure the code base is healthily structured from the start - i.e. controllers are split nicely, named well and according to standards, and most importantly the business logic is separated into appropriately sized models.
My application could, in its core, be described as a business directory with a range of search and listing functions, and a login area for each entry owner. The actual administrative database backend is already taken care of.
Supposing I have all the API worked out and in place already - list all businesses, edit business, list businesses by street name, create offer logged in as business, and so on, and I'm just looking for how to fit the functionality into a MVC pattern and into a Kohana application structure that can be easily extended.
Do you know real-life examples of "database-heavy" applications like directories, online communities... with a log-in area built on Kohana 3, preferably Open Source so I could take a peek how they do it?
Are there conventions or best practices on how to structure an extendable login area for end users in a Kohana project that is not only able to handle a business directory page, but further products on separate pages as well?
Do you know any good resources on building complex applications with Kohana?
Have you built something similar and could give me recommendations on a project structure?
Bounty
I'm awarding the bounty to #antpaw because he provided me with a Kohana application with some business logic that is giving me a lot of examples. Cheers #Pixel Developer for your excellent input as well - as so often, I'd wish one could split a bounty!
Lots of questions to answer here, I'll try my best.
Do you know real-life examples of "database-heavy" applications like directories, online communities... with a log-in area built on Kohana 3 where I could take a peek how they do it?
There's a few example applications out there. Woody Gilk (Kohana founder) has published the code to his personal website on github. For the login area he assigns a cookie value. Kohana 3 / 2.4 sign the cookies which makes it safe and removes the requirement for sessions. This might not be up to everyone's tastes so you can always use built in authentication library that uses both sessions and cookies.
Here are some other projects you might be interested in:
Shindig - Light weight blog module for kohana 3
Kohanut - An extensible CMS written in Kohana 3
Are there conventions or best practices on how to structure an extendable login area for end users in a Kohana project that is not only able to handle a business directory page, but further products on separate pages as well?
If I understand you correctly you want to generate a login box for each of those pages? This is easy with Kohana 3 as we can take advantage of the H in HMVC. Sam de Fressyinet wrote an article detailing what this all about on the iBuilding Tech Blog. Scaling Web Applications with HMVC.
What you can then do is perform an internal request to the login controller or action and dump the response into your view page.
$login = Request::factory('login')->execute()->response;
$login now contains the login form, which you can put anywhere you like. You may want to return a different response if the request is internal which is why this piece of code can be useful:
if (Request::instance() !== $this->request)
{
print 'Internal called made with Request::factory';
}
Do you know any good resources on building complex applications with Kohana?
There's not going to be documentation showing you how to build complicated applications. The view of the Kohana community is that you're a PHP developer and should be able to solve these problems for yourself. If you can't, well you shouldn't be using Kohana then.
Have you built something similar and could give me recommendations on a project structure?
Once you understand how Kohana 3 finds files things are easy to understand.
|- classes
|-- controller
|-- model
|- views
For example:
Controller_Mathew extends Controller
Will look for a file called mathew.php in:
classes/controller
Underscores can be used to specify deeper directories. Example:
Controller_Mathew_Davies extends Controller
will look for a file called davies.php in:
classes/controller/mathew/
As you can see, the underscores in the controller name act as directory separators. This rings true for models and vanilla classes.
i would use the auth module that comes with kohana for the login. This will give you the roles table where you can setup the possible permission options and relating them to the users later. After that you can check inside the __constructor() or action_function() of each controller whether the user has the required role e.g. with the ->has() function. You also should use the ORM module, its just awesome, since you have many relations between the tables. Also the __get() method inside an ORM object can be extremely handy.
Its also pretty easy to extend a controller function by setting the new parameter to NULL and checking for that in a if statement. e.g. you need only one function for editing a old entry or adding a new one.
public funciton action_manage($id = NULL)
{
$entry = ORM::factory('entry', $id); // if id is null a new entry will be returned
}
It's also important that you structure the views into sub folders to avoid a messy view directory.
I have a pretty large site, and I am looking for the most time efficient way to manage it (I am the sole coder).
I am trying to devise a very simple MVC structure (i don't want to use a framework) to help keep all my code in order.
For a huge site, is it better to have only one controller to handle all the pages, or is it better and easier to split them up?
If just one, what is a good example of a non-framework controller?
I would split any logical divisions into different controllers - if it's all static pages, then serve it up with all the same 'static page' controller.
If you have some static pages, a FAQ page (or section), a product list - use a controller for each different section. So the static pages would be pulled from flat files or a database by one controller, the FAQ pages would be generated from a FAQ table by another controller, the products and info would be generated by whatever the source for that is.
Every time the way a page is generated or the data is accessed, use a different controller.
Of course, class inheritance can be used to create the base class with the code needed by any controller.
Not sure what you mean by a non-framework controller - I'd checkout the Zend (gasp) 'Framework', the MVC pattern, and even the controller itself, can be used apart from the rest of the framework.
I tend to split the controllers up based on their responsibility to a specific section of a site/application. This makes maintaining the code so much easier. Furthermore, I group controllers (and views, models) within modules (folders). Here's an example from a current project I'm working on:
Blog
Posts
Comments
Categories
Settings
Posts
Users
The more complex a site, the more modules I use. Although most of my modules only contain one 'Index' controller, I do like the organization they provide.
Then I use a router (front controller) that maps a REST style URI to the proper module / controller / action. Ex: mysite.com/blog/posts/view/7 would call Controller_Posts::view(7) from the "blog" module. An added benefit of using modules is I can have more specific URIs than if I didn't have modules. Although I suppose that could be remedied by using a router that supports defining custom routes, but I'm not too fond of that.
As many other things, it boils down to what you're comfortable with as a developer, but we can probably agree that more organization you have, the better off you are, so long as you don't over complicate things.
As a quick aside, I would recommend you look into using a framework. I understand if you don't want to use one of the ones out there already, as I avoided those too. I ended up writing my own which for the past year has served me very well. It was a great learning experience and it only contains what I want / need. That being said, you might want to look into Kohana and CakePHP - they're not overly bloated IMO and they will definitely save you time should you decide not to write your own.
Typically people split up controllers into controllers focused on specific areas of functionality.
Then they stick a "front-controller" in front of it all, so there's only one entry point to the application. The front-controller's only job is to route incoming requests to the appropriate controller.
Look at the way the Zend_Controller component is set up. It may provide everything you need, and you're free to use it without buying into the complete Zend Framework.
It depends how you other parts will work. If you only have one model file then it's probably not worth splitting up the controller. If you can split up the model into sections as well as the controller, then do that.
However, I often find that there's too much overlap between models to separate them. You might have a model for articles, but if you want to display the top 20 articles in a sidebar on other pages, that code should be in the article model - and you're going to need that on every page.
Honestly though, the only way to do it is try it and see. Start with a single entry point, and if it gets too, unwieldy, refactor it into smaller chunks.
One router/dispatcher, many controllers would be my advice. Controllers ought to map to URLs, which means differing functionality. A controller will collaborate with different services to accomplish each use case, so one controller for your entire app would become too unwieldy if your app has more than a handful of use cases.