CakePHP how to retrieve data from another controller? - php

I need to show latest news titles on the main page of my site.
Main page is static and based on the Cake's default PagesController.
I have table, model, controller and view for news part of my site.
In the Cookbook I found the
Controller::requestAction
method, but it also says that it can cause a poor performance if I don't use cache.
As I know I also can create a method needed for all (or some) of my controllers in the AppController itself, but how I can link this method with specific model?
What is a proper OOP way to achieve my goals?

If you need to share logic/data between controllers your best bet is to use a component. Put your logic in your component and simply call the component's method from each of your controllers.
Edit
To access your model from your component, you can simply pass whichever model it is to your component's method. Example:
Component
public function fetchMyData($model) {
return $model->find('all');
}
Controller
$mydata = $this->ComponentName->fetchMyData($this->ModelName);

I don't know if that's what you meant, but you can access models that arn't related to a specific controller by adding
public $uses = array('modelINeed');
in your controller's definitions. For more info, look at this Controllers in cakePHP, CTRL + F and look for "$uses", .
I do not suggest loading one controller into another. Use the models to retrieve data from the database!

Related

Is it bad to inject controller class into a controller class?

By trying to follow single responsibility principle, I decided that rendering form view I could move to another class. Also to render form I already am planning to use 5 dependencies. So the main controller which injects form will have less dependencies which is good.
I never injected controller classes into a controller class. What I usually do is I create the library. I have libraries folder made as sibling to controllers folder.
But now thinking - maybe better idea would be to have another controller injected into a controller?
Tried to search for this, but did not find any examples. But at the same time tried creating controller with just constructor function and echo a string. Then inject this controller into another. And string gets displayed.
So this means it is possible to inject controller into controller. So is it good? Or maybe this would be a must?
By default laravel do not even have libraries folder which is interesting, maybe creators assumes that it is not needed.
Yes it's bad. Controllers not only must have one single responsibility, but they are also a different kind of class that should have only one job: A controller is a proxy between the HTTP request and your application (models, repositories, views). So basically it should receive an HTTP request, get some data from your models and pass it away to a view.
Everything else should be done by your support classes (models, repositories, helpers, composers, etc.).
If you are in need to call a second controller class, it's probably because you need methods on that controller that should not be in that controller, because your controllers are doing more than what their job is.
This is one of my controllers:
class Connect extends BaseController {
public function index()
{
$connections = $this->execute(GetConnectionsCommand::class);
return View::make('connections.index')->with('connections', $connections);
}
}
There's a lot happening behind the scenes in that GetConnectionsCommand to get the information to show all connections, and my controller should not know any about it all.
There are some subviews on that ´connections.index´ view, but calling subviews are a view responsibility, my controller doesn't have to know that a particular view needs subviews to be rendered. I can have a master view and some #ifs inside it to render them all properly.
A controller returns data (a rendered view, rendered by another class) back to the response object (behind scenes in Laravel), which is the guy responsible for effectively rendering the data which will be passed back to your browser. So a controller is right in the middle of something, doing very little orquestration, because, the more it knows about your business logic, the more you'll feel it needs to ´talk´ to another controller. You can think of it as MVP if you like, but this is pure MVP using the Single Responsibility Principle as it should be. But in this case the Controller is not decoupled from the view, because there is no Interface between them, so it's not really MVP.

cakephp registration and login form

I'm doing registration and login form using cakephp. I'm new to cakephp framework. I have downloaded and installed cakephp on my system. And I've already connected into my database table. I've made few changes in core.php and database.php.
I'm following these tutorials to do registration and login form.
http://alvinalexander.com/php/cakephp-user-registration-form-example-recipe
http://www.grasphub.com/2013/01/simplest-registration-form-in-cakephp/
http://karven.wordpress.com/2009/07/30/create-simple-user-authentication-using-cakephp-auth-component/
I've tried everthing. But none of them does not works. I don't know where i need to create these php files. I'm new to MVC design pattern too... Here anyone give me some step by step procedure to finish this simple task.. I'm not ask any coding here.. I want some step by step procedure..
It may look a bit hard, but when you understand its scheme it becomes super simple:
The model layer handles everything about data. It will silently connect to the database configuration declared in the variable "useDbConfig" in the model (if not declared, it will connect to default config). They are stored in the Models folder. "Handles everything about data" means that it fetches the data from a datasource, validates data that will be saved, formats data, etc.
Models can attach a behavior. Think of it as an "interface" in OOP terms (not the same, but somewhat close). They provide common functionality between them (for example, TranslateBehavior makes data for that model translatable). They are stored in the Models/Behavior folder. You can call them in the array variable $actsAs, or load it on the fly. For example:
public $actsAs = array('Translate');
The controller layer handles all actions that will be done with the data. It will silently instance the model with the same name as the controller to handle the data, but you can tell a controller to instance many different models to suit your needs. They are stored in the Controllers folder. Usually functions in controllers are called actions, because when a HTTP request is handled in your server, it will be delegated to the corresponding function in your controller. Say, http://www.example.com/users/login will call your action login() inside UsersController.
Controllers can attach a component. It's the same as a behavior, but specifically for controllers. They are stored in Controllers/Components folder. For example, PaginationComponent makes the data fetched in a controller paginable, so you can sort it, divide it by pages, etc. You can call it in the variable $components, or load it on the fly. For example:
public $components = array('Paginate');
The view layer handles all your presentation. It means that they have all the HTML + Javascript that the user will see. It's called from a controller after an action is resolved. It silently will render the view inside View/ControllerName/action.ctp, It means that, for example, when login() action has finished, it will then render the view View/Users/login.ctp. Views usually use the layout default to render, but you can change it in the variable $layout inside the controller. You can pass variables from controllers to view through the function $set() in the controller.
Views can use helpers; they are the same as components and behaviors, but for the views. But you have to declare them in the controller in the variable $helpers. They are stored in the Views/Helpers folder. For example, the default HtmlHelper lets you make some tags easier, like <img>, <a>, <script> or <link> for css.
Also views can use elements. They are kind of blocks that you can reuse in any view or layout you want. You just create an element in Views/Elements folder, and use them with $this->element('nameOfTheElement');.
In summary, you for the login you will need an User.php model, an UsersController.php controller, and a login.ctp view. In the controller you will need the AuthComponent to load, because it will handle the login. In the view you probably will need the HtmlHelper and FormHelper, but they are loaded by default. And in the login() function in the controller, you just check if Auth->login() succeeds or not, and take the proper actions.
Once you're more experienced, you can look at the convention called fat models, skinny controllers to be more organized.
Good luck!

How to access a controller from a model using CodeIgntier?

I want to access a controller, which is located in application/controller/example.php, from a model - located in application/model/users.php
class Users extends CI_Model {
//access the example.php controller
}
Who could i accomplish this ?
You don't want to ever do that, hence why CodeIgniter cannot do it. You should be accessing everything else from your Controller, not the other way around.
A good old resource from CodeIgniter :)
http://codeigniter.com/user_guide/overview/mvc.html
You dont have to access an controller from a model. Models (Views, helpers, libraries ect) should all be accessed from controllers. ( Model are used from manipulating data ( usually in database ) )
The idea behind the MVC is to have a Model, Viewer and Controller.
In other words the Controller handles the request, the Model gets the data and the Viewer displays something to the user.
The Model is used ONLY to manipulate the data - doesn't matter if it's a database connection or other data resource.
Model is where you store your bussines logic. Controller is where you call things and operate with data. Views are for creating output.
Bassically you can do everything from withing controller, but that is wrong, since it does not gain you any clarity. Try to offload as much as possible to models and views and keep controllers small and readable, well commented.

Do I need to create a Model for every Controller? What is the better practise?

Let's say I have a Model 'Retrieve.php' where I have a class named 'Retrieve' and it retrieves posts from a database. Then I have Controller in Index.php where I load that model, retrieve posts and pass it to view.
And now, I have one more page where I have to show those posts. Let's say Sidebar.php or something. And now again, I have to retrieve those posts. So, can I load 'Retrieve.php' once more, or I have to create one more model for Sidebar.php which extends 'Retrieve.php'? What is better practise?
And, in general, do I need for every controller create a new model in a good PHP MVC? If yes, probably Controller and Model should be named the same? Any more advices/comments?
Thank you.
In general, the model should represent a business entity and not a process. I.e., it should be a noun and not a verb. In your case, you want a model for a post, and the methods on that model will perform "the things you do with/to a post." The controller then describes what actions occur for a page. In this case, a controller for the /post page would retrieve a post and pass it to the view for rendering.
Only create the models you need. Remember, the whole point of MVC is that the models are decoupled from the views. This means it's perfectly fine to reuse whatever you need to get the job done. If you have multiple views which need access to the same data, just reuse the same model. Just be sure to give the models descriptive names so there's no confusion as to what they're supposed to represent.
You should only have one Model class for each data structure that that model represents. So if you have 5 Controllers that each access the same Model, you should still only ever have one Model class.
No --
Model should be what your application manages -- so instead of Retrieve, your model class should probably be Post (and maybe you have other Model classes for the nouns in your domain-- Thread, Author...)
The controllers should access the model classes they need to do their jobs; one model class could be used by several controllers, and one controller could use several model classes.

model access from layout file in CakePHP

I am working on a CMS using CakePHP and I want to create a dynamic menu which is the same on all the pages the user can access. So I figured out to create in the layout (since it shared among so many pages and view) but I don't seem to know how to acces the model and get the data from the database to construct the menu. any help is appreciated.
That's because for proper MVC separation* in Cake you're not supposed to access the Model from the View. The only part with access to data should be the Controller (via the Model), which hands it down to the View, which simply displays the data.
As such, using a beforeFilter callback in your global AppController to set() the data is probably the best choice.
In emergencies you can always access anything from anywhere by loading an instance of the needed Class using ClassRegistry::init, but you really shouldn't.
* Actually, in "proper MVC" there's no problem with the View getting data directly from the model. You shouldn't do that in templates necessarily, but View related code can well get data from the model to visualise the model state. It just doesn't really work that way in Cake, because Cake is not proper MVC and default Cake views are only templates.
An alternative could be requestAction, it allows you to call controller actions from views/layouts, and in those actions you can then access the desired model(s).

Categories