CakePHP - file structure confusion - different controllers, or all in same? - php

To understand my confusion/question, let me first give a quick overview of the site I'm building: The site has a homepage, and 7 category pages, each with the same/similar layout.
On most category homepages (eg "Dining"), you can do a search (ie a search for restaurants), which will take you to a results page. This will have the same/similar layout as the... "Theaters" search result page...etc etc.
So - although there are a lot of sections, there are not a lot of page layouts.
Question: I'm not sure if I should create separate controllers for each, and just use the same CSS for them? Or if I can use the same view file, but populate each content area on the page differently based on the url/action..etc?
They'll all reference different & multiple tables in the database - for instance, restaurants will reference the restaurants table, the cuisines table, the zip_codes table...etc. Theaters might reference the "movies" table, the zip_codes table...etc etc etc
But - I also want an admin tool for some - ie "restaurants/edit" or "theaters/edit" ...etc - not ALL the pages will have admin for that specific url - ie "outdoors" might just be "businesses/edit" or something generic... I don't know - I'm confused as you can tell.
Any help is GREATLY appreciated. I've read a lot about the technical things to do w/ CakePHP, but I can't find any good resources for general project structures for varying scenarios.

You can answer this yourself. Suppose you implement separate controllers, models and views for each, how do they differ? If they only differ in the table names and labels/strings that they use, then you can use just one generic controller. But, if they are different in other ways (e.g. the Restaurants model has a totally different relationship structure than a Movie model) then use separate controllers.
To prevent too many repetition between controllers and view files when you do use separate controllers, try to push functionality in a common base controller (e.g. AppController, of create your own base controller based on AppController that your MoviesController and RestaurantsController and so on will derive from). Push generic view code into elements.
A word about CSS: Of course you can (and should) reuse that. It's mostyly separate from the view. Just use sensible class names and id's in your views and the CSS will be easy to reuse.
If you are still unsure, I'd go with separate controllers. It may be more work but it will be cleaner and easier to debug. Use the above suggestions to avoid repetition.

-group elements that will share among all site in a layout (ie. site css, site common js library)
-make a view for each of your category(page) (ie. dining page, theater page, restaurants page) and put there page only stuff (ie. theater js, theater includes) there
- in theory, every vew should have a controller and model, so you have to make them separate.
anyway url like "restaurants/edit" or "theaters/edit" actually means model "restaurant", operation "edit" in your controller file.
I suggest you read the blog tutorial from cakephp site, you that should answer all your confusion

Related

Using mvc design pattern in php driven web applications

I have been reading tutorials and questions about mvc on stackoverflow lately and I need to ask a couple of questions to see if I understand the basic concepts correctly.
To my understanding, having only one view object for rendering multiple views (html files) is enough most of the time. Is this correct?
Is putting the presentation logic in view files is better than putting it in view object to avoid adding extra complexity to the view layer?
It is known to be good practice to have one index page and autoloading controllers from there based on request urls and file names. But, doesn't that mean having controllers for every request url? Is it ok to group some of the request urls and map them to one controller. (Having multiple if-else statements on index page or putting the information in an array config file)
If I have one view object, than the relationship with this object and the controllers must be 1:1. Is this true?
Lastly, If I need to pass big amount of information from controller to the view, and some of that information is repeated in other controllers; than is it a good way to handle those repeated information in base controller, which is the parent of other controllers?
As you see, I'm still confused. Thanks in advance.
Well... this is a intresting question... As a general rule MVC was designed to decouple these 3 commonly intertwined components.
If your model cannot support multiple views at the same time, its not MVC
If your model speaks to your controller, or even knows about its existance (this applies to the view also) then its not MVC.
If you have a 1:1 ratio between view and controller its most likely not MVC.
You should be able to swap out any of those 3 components from the system with primarily only config changes.
Its a extremely misused term, and often 'attempts' at MVC end up with the extremely coupled code that the concept of MVC was designed to work around.
There's more than one way to do MVC with PHP.
One class supporting everything (global controller).
It load your classes, it process the URI to know which controller start, it check your data (GET, POST), it check the user session (is it expired?, is there someone logged in? Is he an admin?).
Many classes supporting the interactivity (controllers).
A class managing your News, a class managing your Users, etc...
With static methods doing every user to model action.
Basically "add a new item", "delete an item", "update an item".
Many classes telling how things are organized (model).
Your user have a login, an hashed password, an email adress, etc...
See DAO for more information. (basically, all SQL is in these classes). These classes check nothing except that data given are as expected.
Many classes telling how to show things (views).
Called by a Controller which give what is needed (object, array, output data)
The only place where you have HTML and where the more complicated is a loop in a loop creating a whole HTML .
You will have one showing "a message in a centered box", one showing "a list of element", one showing "a single element", one showing "a single element, with an author sidebar", etc.
HTML Templates/Elements are useful to build your view, but it's the view who call templates/Elements and place them how the view want.

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.

CakePHP - page that accesses multiple tables & categories

I'm making a site that has a lot of different categories, each with their own controller/model/views.
Example site categories: Dining, Movies, Nightlife, Sports...etc
My Controllers: restaurants, theaters, events, articles, cities, users... and more
I also have a site homepage that pulls data from all of them to populate little boxes on the page. And, each category has it's own homepage that also could pull data from different categories - for instance, on the "Movies" homepage, it might also pull in restaurants and sporting events that are nearby the theaters and maybe a few recent articles from the articles model... etc etc - there is a lot of category-overlap.
How do I set this up? The sporting event isn't tied to the movie at all, so I can't imagine any hasMany/belongsTo type relationships - but I still need to access the data. And especially on the homepage, which really has no table at all, but needs to pull data from all of the above.
Your problem is too big to cover in its entirety. I'll address accessing multiple models across different controllers. This can be done in several ways.
by relationship:
$this->Event->City->find(); // relationship to City exists in Event Model
by adding it to the $uses property in your controller:
var $uses = ('City');
by loading into the method as needed:
function some_method() {
App::import('Model', 'City');
$this->City->find();
Each has its own benefits. You should read more about Models in the CakePHP Book. If you have a large amount of relationhships, you should check out LazyModel for lazy loading your models.
Sounds like you need to implement components to handle the various categories. The component will provide the access for the category box for any given page (which will be different from the category home page).
Then I would implement an element called 'category' that you can pass the information to from the component. I would also make all components export similar data. This will keep it simplified but still provide the flexibility you are looking for.
In summary, create components for each category:
DiningComponent
NighlifeComponent
etc.
Pass the output to the category element to be displayed on the page.
At first glance maybe you don't see another model that is overarching, but the idea that you are calling them "categories" means they have to be a category of something, possibly activities. The new model may be pretty thin, but I would maybe suspect something like appearance scheduling to be involved with the activity model, so you can give it a beginning and ending publish date. If you don't want to call it an "activity", maybe something generic like "contentItem" would give you somewhere to control global attributes. Another exercise would be to compare your existing models and look for duplicate attributes. What are those duplicate attributes describing?
You could use the loadModel function if there is no relation between two controllers
$this->loadModel('Foo');
$this->Foo->Bar();
When there is a relation of course, you can do
$this->Foo->Bar->Baz();
This is probably what you want
How to build a dashboard for your cakephp application
To understand more about the data models in CakePHP you can use http://cakeApp.com a online schema builder.

Zend Framework: Controller class == Page?

Am I right in thinking that in Zend Framework, if I plan to have 5 pages at my site, I'd generally need 5 controllers? Do ZF developers typically create 1 controller per page ("page" as abtract app unit)?
The reason I am asking this is that previously for some reason I stuffed a lot of various actions into controllers so that they played role of pages, e.g. index/add, index/view, index/delete and displayed various small screens, e.g. small CRUD screens as opposed to grids displayed by index action.
But as of now I want to check my new understanding that actions are needed mostly for model updates and actions should, once run, immediately redirect back to controller/index. So it seems that views should mostly be used in index actions, and less frequently in other actions.
Does this sound architecturally valid?
I suppose thats one way of doing it... Using your analogy i suppose i use a controller like a "section" and actions like "pages" to those sections.
But thats getting stuck more on the old procedural||static paradigm of pages because really the action controller itself has no more to do with a page or section than the association you make as a developer. Ie. each page can potentially be a composite of numerous actions and views depening on the application's architecture.
For example if i have a blog modules i might have the following:
Controllers:
PostController
CommentController
Views:
post
display (display a single post)
list (list posts)
edit (create/edit post)
comment
display (display n comments)
list (list comments)
edit (create/edit/moderate comment)
embed-list (for use on the Post itself assuming this differs from display)
In my opinion, a controller should always group multiple methods that have a common use case. Try to find "nouns", that describe the functionality of your app: those are the controllers (while verbs are the controller methods).
If you have (for example) a blog, you may have:
ArticleListController (listing all
articles, listing the top 10, listing
all articles for a tag,...)
SingleArticleController (displaying one article, adding comments,...)
AdminController (lets you write Articles)
If you have just 5 pages (e.g. home, about, contact,...) the MVC architecture might not be the right fit.
indexAction is merely the default action for a given controller, useful for displaying a default view (the same as displaying the index.html or index.php page for a sub-directory).
It is completely acceptable to create a variety of actions on a per controller basis that may or may not each have their own views (i.e. add and edit). The controller is intended to group similar actions.
For example usage please refer to the documentation on Zend_Controller_Action. You may also find it useful to familiarize yourself with the workflow of Zend_Controller.

Quick question about MVC in Php

Currently, I am working on restructuring an existing code base. I'm new to php frameworks, but I do know in general how MVC works.
Right now, there is one controller file, one model file, and thirty view files.
Should every model correspond to a table?
Should every view correspond to an html page?
What about the controller? How can I break this thousand line monster into more organized code.
Thanks.
Should every model correspond to a table?
No. A model is often constructed from data from multiple sources. Don't think in terms of tying it to your physical database structure even though there will probably end up being lots of similarity.
Should every view correspond to an html page?
Not to sound trite, but every view should correspond to a view. I'm not sure exactly what you mean by a "page".
Perhaps an example would be useful. Imagine a user registration page. The model is User and might contain fields such as:
Title
Given names
Surname
Date of Birth
Username
Address(es)
Email address
Phone number(s)
etc
Now, that data may be in multiple tables. For example: Party, Person, Contact and Address.
There will probably be several views:
About page
Form page (used for new registration and possibly editing details as well as errors);
Success page;
Failure page.
Typically all of this will be handled by a single controller as all the processes are inter-related.
Every model should correspond to a logical data object - which should generally predominantly be stored in one table (often with foreign keys into other tables, since models generally need to reference other models).
Every view should correspond to a logical way of viewing your data (e.g. on stackoverflow, there is hopefully a view for the list of badges pages, a view for the list of tags pages etc).
Every controller should correspond to a logical grouping of views, which should not be too big (where too big is the line where the file is becoming unmanageable - if you've got 30 views, you can hopefully find a logical way to group them into say 3 controllers).
What about the controller? How can I
break this thousand line monster into
more organized code.
Have a look at CakePHP framework and how it solves the problem of large models, controllers, and numerous views. I find it quite elegant. Complex models can have behaviours. Large controllers can be broken into components. And numerous views are grouped with layouts, while having common bits separated into elements. It might sound complicated and scary at first, but once you try to use it, it really falls into place.
Should every model correspond to a
table?
It doesn't have to but it often will depending on the complexity of your business logic.
Since you're refactoring an existing application, think about how the model is used by the other layers. In MVC, the model is at the bottom of the dependency stack.
How will the view access the model? How will the controller modify it? How will the model be populated?
Should every view correspond to an
html page?
Again, it doesn't have to but it often will.
What about the controller? How can I
break this thousand line monster into
more organized code.
A common strategy is using the front controller pattern. The front controller deals with HTTP requests, application initialisation and site-wide logic (just as your thousand line monster is currently doing) - but then it delegates to more specialised controllers.
These specialised controllers could be grouped by the models it uses, site page structure, or anything else that seems logical. They then interact with the model and select a view to display.
Finally, +1 to frameworks as Leonid suggested. Even if you don't end up using one, there are some great implementations of controller patterns out there.
Hope that helps.

Categories