cakephp print data from another model - cakephp

My problem is this. I have a controller "FacsController", and a method.
public function access()
{
$facs = $this->Facs->find()->all();
return $facs;
}
This method works perfectly, data is returned properly.
But what I need is to call this method within another controller, "PagesController".
public function display()
{
$var = new FacsController();
$var->access();
$this->set('vars', $var);
$this->set('_serialize', ['vars']);
}
Unfortunately here I do not get the data returned from the FacsController.
Can someone help me? What am I doing wrong.

If you want data from a model, then you use the model, not a controller! If you ever feel the need that one controller needs to access another controller, then this is almost always an indicator for a failure in your application design. Also you never instantiate controllers yourself (unless in unit tests maybe)!
If you want to keep things DRY, create proper custom methods in your model (table class) and use them to encapsulate further logic.
That being said, like in every other controller, load the model via $this->loadModel(), or even TableRegistry::get().
$var = $this->loadModel('Facs')->find()->all();
See also
Cookbook > Controllers > Loading Additional Models
Cookbook > Database Access & ORM > Table Objects > Getting Instances of a Table Class

Related

How to use: $this->Auth->user('id') in a model? Cakephp 3.0

I've been working on the skinny controller fat model way. Before, I used this in my controller:
$this
->find('all')
->contain(['Declarator'])
->where(['user_id' => $this->Auth->user('id')])
->order(['Declarations.created' => 'DESC']);
However, $this->Auth->user('id'), doesn't work in a model.
What other way is there to get the id from the authenticated user in a model?
What other way is there to get the id from the authenticated user in a model?
Simply pass it to a model method:
public function someModelMethod($userId, array $postData) {
// Do something here, move your code from the controller here
return $something;
}
public function someControllerAction() {
$this->set('data', $this->Model->someModelMethod(
$this->Auth->user('id'),
$this->request->data
);
}
Cake doesn't have a layer that would take the business logic so most of the time it's put in the model layer. Cake also doesn't use dependency injection so passing whole instances around like the auth object is sometimes cumbersome. Also I don't think the auth object itself should intersect with the model layer. We want to avoid tight coupling. To simplify this (also for testing) it is much easier to just pass the required values to the methods.
Mayby it's not a good idea, but in cake's model You can get users id using $_SESSION['Auth']['User']['id']
Or just use Cake\Routing\Router; at the top of your Table class and then, You can get access to session using:
Router::getRequest()->getSession()->read('Auth.User.id');
In CakePHP 2.x it's done as stated below. I'm quite sure that, even though it's not in the docs, it may be done the same way.
// Use anywhere
AuthComponent::user('id')
// From inside a controller
$this->Auth->user('id');
Source: http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#accessing-the-logged-in-user
Docs for version 3.x: http://book.cakephp.org/3.0/en/controllers/components/authentication.html#accessing-the-logged-in-user

How to add queries in model in Cakephp 2.x and call that function in controller

I want to add my save, update, find queries in model and call those functions in controller, rather than adding the queries in controller.
I'm not sure what's you precisely want to acheive, but I first of all hope you know that CakePHP has implemented save, update and find functions for your models. If not, look at the docs, e.g. here: http://book.cakephp.org/2.0/en/models/saving-your-data.html
If you want to add functions with custom queries to your model, you can simply add them as a normal function in your model, e.g.:
MODEL
public function myMethod(){
// Fetch data
return $this->query("SELECT * FROM pictures LIMIT 2;");
}
CONTROLLER
public function index(){
// Get data from model-method
$data = $this->ModelName->myMethod();
// Send data to view
$this->set(compact('data'));
}
In your model classes you don't have to refer to your model in your code:
In your controller: $this->ModelName->function()
In your model: $this->function()
Has the same meaning.

In CakePHP, how do I call an AppController method from a helper?

Follow up question to: In CakePHP, where would I put a method that performs a check on the Session User?
Background: In my previous question, I was informed that the correct place to place a method such as levelCheck() which performs a semi-complicated evaluation of a user's level, and is needed in practically all my controllers, is the AppController.
Now, this method is also incredibly useful for the way I design menu layouts and other view devices. For that reason, I would like to create a helper that can make use of that method.
Problem: I recognize that it's generally frowned upon to call a controller method from the view... however there is no viable way for me to pass data to replicate the function of this method, nor do I want to replicate the method in two places (violating DRY methodology).
Question: How then do I call this method from a helper, or is there a better way to provide use of this method in the view/elements?
Put the method in AppController, also - set a variable that will save the result.
In the beforeRender callback, set the result as a viewVar.
some code:
// AppController
class AppController extends Controller
{
$levelCheckResult = null;
function levelCheck(){
$this->levelCheckResult = true/false;
}
function beforeRender(){
$this->set('levelCheckResult', $this->levelCheckResult);
}
}
that's it, now you can access it in the view.
edit
create a public function in the app_controller, and in the beforeRender(), send the app_controller itself, to the view.
class AppController extends Controller
{
function levelCheck(){
....
}
function beforeRender(){
$this->set('TheApp', $this);
}
}
// in the view
$TheApp::levelCheck();
However, please consider again the design. this kind of manipulation is strongly suggest that you should change some stuff there.
In short - the view is still backend execution of the program and not the client side, so in definition - it should and can be controlled, from the controller...
The solution I ended up using was to move the method to a component (CurrentUserComponent).
From there, it was as simple as calling the component in the head of my helper...
App::uses('CurrentUserComponent', 'Controller/Component');
And referencing the component's static method:
CurrentUserComponent::levelCheck(x,y,z);
I don't think this is entirely within the intention of the MVC pattern, but it doesn't pervert it horribly, and allows access to the method from anywhere in the application.

Make sure variable exist throughout the application

In my controller, I would like to set some values and have them exist (or live) throughout the different views in my app.
I read somewhere that I need to use beforeFilter function, but I am not sure if that is correct and how I go about doing that.
So in my controller I want to have
public function page1() {
$this->Model->setId('123');
}
public function page2() {
$this->Model->getId(); // would able to get the Id that was set from page1 function
$this->Model->setName('Bob');
}
public function page3() {
$this->Model->getId();
$this->Model->getName();
}
Let me know if you have questions.
To have this kind of "persistence" throughout the views, I guess the most simple approach is sessions.
Note that with the code you provided (I know is not a working example), you want the variable to be persistent inside a model, but that same model wont be maintained between actions of the same controller (or other controller for that matter).
You have to set that variable in sessions and retrieve it when you want to use it, or in the database and create methods in the model to get the last inserted id, for example.
So your code would be like
public function page1() {
$this->Session->write('id', '123');
}
public function page2() {
$this->Session->read('id');
$this->Session->write('name', 'Bob');
}
public function page3() {
$this->Session->read('id');
$this->Session->read('name');
}
Have a single model method that returns all your data in an array like
return array('varName' => $value, 'varName2' => $value2);
You can then call this model method from the controllers before filter and simply do
$this->set(ClassRegistry::init('MyModel')->commonViewVars());
If you would describe for what you think you need to do that I could give you a better advice like using requestAction() for example, this might be another option depending on what you're trying to do.
Depending on what data you want to pass to every page you should really consider to cache it. If its a menu for example cache it "forever" and just update the cache when the menu changes.

CakePHP global variables in model

I am making one CakePHP project with Auth component. When I log in I got Session variable with user data. At the moment I am using this variable in controllers to pass data to the model.
$user = $this->Session->read('Auth');
$costs = $this->Posts->get_quartal_cost($user, $quartal, TRUE);
As I am using this in many controllers/models I am thinking that this is not DRY approach, so I wanted to make it better - something in AppModel(?)
Do you have some advice how to do that better?
Thanks
You could use the beforeFilter event in your AppController and do something like this:
public function beforeFilter()
{
if ( $this->Session->check('Auth') )
Configure::write('Auth', $this->Session->read('Auth'));
}
From anywhere in your controllers, models and even views, you'll be able to access it by using echo Configure::read('Auth');. See the Configuration class documentation for more information.

Resources