Is there any way to access the current controller or request object outside mvc in CakePHP(2.*)?
Basically I need to access the request object in a library that is designed for CakePHP but should function on its own as much as possible - in other words I'd like to avoid any unnecessary lib-specific initialization code in the controller itself to keep the.
I have written a component for this purpose but not all calls to the lib will be directly from the controller. I'd also like to avoid passing the $controller or $request variable around anywhere else but inside the lib.
I've never looked into CakePHP class loading much, but I can recall something about ClassRegistry from when CakePHP 1.3 was new. Soon after testing ClassRegistry in a controller action I found it to be empty(determined with ClassRegistry::keys() and pr()'ing directly from the class)
So, is there any friendly way to get the request object or should I resort to uglier methods?
Router::getRequest() should get you the CakeRequest instance.
Do the following code example help you?
//in Socials Controller importing SocialUsers controller
function __checkSocialUser($title, $user_id){
App::import('Controller', 'SocialUsers');
$SocialUsers = new SocialUsersController;
$SocialUsers->constructClasses();
$ourUserId = $this->Auth->user('id');
$SocialUsers->data = array('SocialUser' => array('title' => $title, 'identifier' => $user_id, 'user_id' => $ourUserId));
$result = $SocialUsers->checkUser($title, $user_id);....
Related
I am using cakephp 3.x have put database queries in model in which i want to check the current controller action and based on that i will make my database queries.
I know i can pass controller action from my controller itself to my model function but is there a way i can just check my current controller action inside my model only so that i do not need to pass it in my multiple functions which are inside model only.
My Try -- UsersTable.php
public function initialize(array $config)
{
parent::initialize($config);
$this->table('users');
$this->primaryKey('user_id');
echo '<pre>';
print_r($GLOBALS);
exit;
}
so far if i do this, i got an array in response and in which i found this the best result out of other things in that array
[REQUEST_URI] => /5p_group/users/add
I m also trying to use this
echo '<pre>';
print_r($GLOBALS['_SERVER']['HTTP_REFERER']);
exit;
which gives me this output
http://localhost/5p_group/users/archived
so eventually i am getting the result which i want but i want another proper method which cakephp 3.x uses ..
So is there any other way or more frequent way from that i can get my current controller action ?
Any ideas will be appreciated ..
Thanks
First of all you should use the routing class in your model. So at the top you can call it like below
use Cake\Routing\Router;
And then in your initialize function you can check the params like
debug(Router::getRequest());
Or to be more specific you can use
debug(Router::getRequest()->params['action']);
I think this is the solution using cakephp classes only, though a small hack.
For more function reference you can access the cookbook at Router Class
The question was about a Model, but it shows up on Google.
When inside a view (.ctp file), use
\Cake\Routing\Router::getRequest()->getAttributes();
CakePHP 3
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
I have a shopping cart site and on successful purchase I need to send a mail with all product details in the order as attachment. I have used fat model skinny controller approach and all my functions are in model. I have a controller action which will give the order details by passing order id along with view. Using dompdf I can convert this html to pdf and can create a file. So for creating attachment I can use the same function by passing some parameter. My mail sending code is in model. From here I need to call the controller action and need to get the pdf file name that just created. I know calling controller action from model is against MVC architecture. But how can I achieve this functionality ?
'fat' models is a good thing to do, however, try not to put things in a Model that should not be in a Model. In MVC, Models should handle all things related to data.
Fat models
The 'fat' Model concept is to reduce the amount of code in your Controller, by moving data related code to the Model. for example:
In stead of this; (in your Controller):
public function view($id)
{
$this->request->data = $this->SomeModel->find('first', array(
'fields' => array(
// list of fields to retrieve
),
'conditions' => array(
// conditions
),
// etc.
);
}
Move the find instructions to a method inside your model and use this:
public function view($id)
{
$this->request->data = $this->SomeModel->someMethod($id);
}
Other locations to put your code
Code that is not related to data, can also be moved outside your Controller (to make it 'skinny'). CakePHP offers other locations to move your code to, for example inside a Component
Then inside your Controller;
this:
public function view($id)
{
$this->request->data = $this->SomeModel->someMethod($id);
// use functionality of a component
$this->SomeComponent->doSomething();
}
Triggering functionality via Events
To keep code and logic outside your controller, CakePHP 2.x now offers an 'Event' system. This allows you to execute code if a certain event happens. You can pass additional information through the events (the event will become a 'communication channel' that passes through your application).
Sending e-mails for certain events is a good example. The CakePHP also uses sending mails to illustrate the Event system in CakePHP; this is probably what you are looking for:
Dispatching Events - send emails
Make your model method return the data so you have it in the controller and pass it to the other model function together with your pdf related data.
I've run into a problem in my CakePHP app as a result of adding some ajax actions.
My table is called orders so obviously my controller is called OrdersController and the model is called Order
It is my understanding of CakePHP's best practices that if I am going to run any logic on the Order model, that it should be done in the OrdersController. This is fine for the basic CRUD stuff but now that some of my views need to send ajax requests to manipulate Order data I have a problem.
The problem is that for ajax to work properly, I have to put this at the beginning of the OrdersController
var $layout = 'ajax'; // uses an empty layout
var $autoRender=false; // renders nothing by default
Then, to stop the security component interfering with my Ajax form submissions, I also need this:
public function beforeFilter() {
parent::beforeFilter();
$this->Security->csrfUseOnce = false;
$this->Security->csrfExpires = '+1 hour';
}
None of this would be a problem if the controller was only being used for Ajax requests, but the problem is that it's being used for regular Cake actions too.
Is the answer that I should have two controllers? One for regular actions and one for ajax actions? This doesn't seem to be mentioned in the Cake docs and it doesn't seem like a very efficient way of doing things.
I know I can change the layout and possibly the auto-render setting on a per-action basis, but I don't see how it's possible to do this with the csrf settings, which need to be in the beforeFilter.
No need for a separate controller. Use cakes request handler. In your controller method, you can test if it's an Ajax request.
if ($this->request->is('ajax')) {
//set to Ajax layout and security settings, etc
You'll need to include the request handler component at the top of your controller:
public $components = array('RequestHandler');
See this page in the cook book For more info: http://book.cakephp.org/2.0/en/core-libraries/components/request-handling.html
In my cakephp application i need to use my controller in helper.php. Its not working. will any one explain it with little syntax?
I really hate thinking that code can tell me how to think instead of me telling it what to do ... anyway ... here is an example for loading the controller rendering the page, and it can load any controller inside the helper.
<?Php
class HelperNameHelper extends AppHelper{
private $controller;
public function __construct(View $view, $settings = array()) {
parent::__construct($view, $settings);
$this->controller=$this->loadController();
}
protected function loadController($name=null){
if (is_null($name)) $name=$this->params['controller'];
$className = ucfirst($name) . 'Controller';
list($plugin, $className) = pluginSplit($className, true);
App::import('Controller', $name);
$cont = new $className;
$cont->constructClasses();
$cont->request=$this->request;
return $cont;
}
}
EDIT: just realiced this is such an old post :( ... this is working in cakephp 2.2.3
Helpers are not designed to have access to the controller. If you're trying to access the controller you may want to rethink your application design.
I actually had this same problem myself. I have a CakePHP 1.1 application where I was accessing the controller by passing the name of the controller as a parameter to the view. After trying to upgrade the code to work with 1.2 I realized that this was bad design. It was my first experience with CakePHP and MVC, so I chalked that up as a lesson learned.
MVC requires some up-front design to make sure that you're putting your functions in the right places (controller, model, or view).
(P.S. You can also try the #cakephp channel on irc.freenode.net)
Its an MVC.
You shouldn't use a Controller in your helper, rather use your helper in your controller.
Why would wan't to do that in the first place.
Read this:
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller