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

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.

Related

cakephp print data from another model

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

Cakephp using Cache in Component

I am using Cakephp 2.3 , i want to perform lots of common calculation in my several controllers. so i write those functions in my appcontroller and i cached some datas..
but what happens is my appController will become fatty.. so i create some component to perform these actions.. i dont know my approach is right or not..? please suggest..
i want to use cache in my component, i tried this code. but nothing is cached..
public $helpers =array('Cache');
and
$result = Cache::read('fm_data', 'long');
if (!$result) {
$result =
$this->TFmStation->find('all',array('contain'=>array('TLocation',
'TLanguage','TMediaOrg','TContactPerson',
'TAddress','TFmProgram'=>array('TTargetGroup'))));
Cache::write('fm_data', $result, 'long');
}
return $result;
please help me to how to use cache in component
how to effectively use component class in cakephp in the case of more common functions in the application.. when i write these functions in appController it load all the functions so according to memory prespective, how to effectively use component
Model TFmStation is best place to have the above logic. Components are there for generic functionality like UploadComponent, EmailComponent, RecaptchaComponent etc. If your logic part have something to do with model, then it should go into that model.
A Model can be called from AppController.php in a similar fashion as you calling your Component.

temporarily disable controller redirect

I'm trying to re-use a plugin's controller method for adding a user (the plugin is usermgmt, a purchased plugin). The plugin's method does everything I need, however it finishes by doing a redirect to another page.
I don't want to modify the plugin code, and I am wondering if it is possible to temporarily disable the Controller:redirect method
class MyController extends AppController{
function signUpUser(){
//populate $this->request->data to be what plugin controller method is looking for
//temporarily disable Controller::redirect
//make call to plugin's controller method
$usersController = new UsersController();
$usersController->constructClasses();
$usersController->addUser();
//re-enable Controller::redirect
//Do my own redirect
$this->redirect('/welcome');
}
}
You are not supposed to use controllers that way, there's probably a model or component which you could use instead. Extending the users controller may also be an option. Anyways, since you said you've bought it, why don't you contact the support, they should know best how their stuff works?
That being said, let me answer the actual question. In order to be able to disable redirection via your controller, you would have to override the Controller::redirect() method and implement some logic that allows you to disable the functionality.
Here's an untested example, it uses a property which defines whether redirects are enabled:
public $redirectEnabled = true;
public function redirect($url, $status = null, $exit = true) {
if($this->redirectEnabled) {
parent::redirect($url, $status, $exit);
}
}
This should be pretty much self-explantory.
In your controller you could set $this->redirectEnabled to true/false to enable/disable the redirect functionality.

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