0

I am using cakephp-2.x. I have one function name user_info() in the UsersController.php i want to access this in another controller name MessagesController.php

Code -

UsersController.php

public function user_info(){
   $user_id=$this->Session->read('Auth.User.id');
   $data=$this->User->findById($user_id);
   $this->set('user_info',$data);
}

MessagesController.php

public function index(){
  //$userInfo=new UsersController();
  //$userInfo->user_info();
  $this->user_info();
  pr($data);
}

Error Message-

Fatal Error

Error: Call to undefined method MessagesController::user_info()
File: E:\xampp\htdocs\2014\myshowcam\msc\app\Controller\MessagesController.php
Line: 18

Notice: If you want to customize this error message, create app\View\Errors\fatal_error.ctp
Developer
  • 2,676
  • 8
  • 43
  • 65

4 Answers4

1

Typically if you're trying to access a function in one controller from another controller you have a fundamental flaw in your project's logic.

But in general object usage is thus:

$otherController = new whateverMyControllerNameIs();
$otherController->functionName();

However I'm not familiar enough with cake to tell you the pitfalls of doing such a thing. For example I have no idea what this would do to routes or what other variables/objects are required to initialize a controller correctly.

EDIT:

Ref: CakePHP 2.3.8: Calling Another Controller function in CronController.php

App::import('Controller', 'Products'); // mention at top
// Instantiation // mention within cron function
$Products = new ProductsController;
// Call a method from
$Products->ControllerFunction();
Community
  • 1
  • 1
Wranorn
  • 798
  • 8
  • 19
  • Not working i am using `$UserData=new UsersController(); $UserData->user_info();`. I am getting `Error: Class 'UsersController' not found` – Developer Nov 06 '14 at 06:30
  • Take a look at this: http://stackoverflow.com/questions/19344988/cakephp-2-3-8-calling-another-controller-function-in-croncontroller-php Might Help IDK. Still say if you have to call a controller from another controller your coding approach is flawed. – Wranorn Nov 06 '14 at 06:34
  • Yes it is working I am using `App::import('Controller', 'Messages');` but i am getting another problem `Error: Call to a member function read() on a non-object ` how to fix that issue? – Developer Nov 06 '14 at 06:46
  • You'll need to dig into the stack trace to find what's calling read. The object it's referencing isn't set. Best I can tell you as the error doesn't have much to go on. – Wranorn Nov 06 '14 at 06:48
  • `$user_id = $this->Session->read('Auth.User.id');` this line i am getting error. says `Error: Call to a member function read() on a non-object` – Developer Nov 06 '14 at 06:50
  • 3
    @chatfun As already mentioned, the need to access other controllers from a controller indicates a flaw in your application logic! Also controllers must not be instantiated manually (except for in unit tests), if you need to share logic between controllers, use components, models, or inheritance! – ndm Nov 06 '14 at 06:52
  • My guess would be that the session hasn't been initialized yet. try (I Think) CakeSession::Start(); (This is the type of stuff I was saying can happen when you try to call controllers in a way they shouldn't be called) – Wranorn Nov 06 '14 at 06:54
  • If i am directly checking in browser `http://localhost/2014/myshowcam/msc/users/user_info` it is working fine. when i access that in other controller i am getting above error `Call to a member function read() on a non-object`. I think my session is working fine. – Developer Nov 06 '14 at 07:03
  • Regardless of what you think, $this->Session isn't set. That's what "non-object" means in this context. The object 'Session' belonging to $this isn't initialized. (BTW, you now have three people telling you, THIS IS BAD PRACTICE). – Wranorn Nov 06 '14 at 07:19
  • @Wranorn please update your answer. add `App::import('Controller', 'Messages');` - Thanks – Developer Nov 06 '14 at 07:32
  • 1
    There is a hell of possible points that might blow up: Session, Auth - any other component as well and who knows what else. **Don't** instantiate controllers inside controllers. It is one of *the* worst things you can do in any MVC framework. Refactor your application logic, as others already stated this *is* a flawed architecture by design. – floriank Nov 06 '14 at 11:43
  • burzum makes Four... :) – Wranorn Nov 06 '14 at 11:50
0

Try requestAction function of cakephp

$result = $this->requestAction(array('controller' => 'users', 'action' => 'user_info'));

Rajeev Ranjan
  • 4,152
  • 3
  • 28
  • 41
Jinank Thakker
  • 121
  • 1
  • 8
  • for that you need to return data from your called controller method Try a look at this: http://book.cakephp.org/2.0/en/controllers.html and try to return some string on the very first line so that you will understand if there is any error in your written code or requestAction has some problems..Do let me know whatever happens – Jinank Thakker Nov 06 '14 at 06:56
  • if you are not getting session id in user_info method, you may pass user_id from MessagesController's index method in $this->requestAction(array('controller' => 'users', 'action' => 'user_info'),$user_id); – Jinank Thakker Nov 06 '14 at 07:17
0

Why would a simple, When can complicated?

All the information for a registered user of User model is accessible in the following manner:

AppController.php

public $user_info;  /* global scope */

public function beforeFilter(){
  $this->user_info = $this->Auth->user(); // for access user data in any controller
  $this->set('user_info_view',$this->Auth->user()); // for access user data in any view or layout
}

MessagesController.php

public function index(){

debug($this->user_info);
$my_messages = $this->Message->find('all',
  array('conditions' => array('Message.user_id' => $this->user_info['id']))
}
....

layout or view.ctp

<?php echo $user_info_view['name']; ?> // email, etc
Salines
  • 5,674
  • 3
  • 25
  • 50
0

Why not take advantage of the way CakePHP handles relationships? There's a very easy way to achieve what you're trying to do without extending controllers or loading in additional controllers which seems excessive for your example.

Inside AppController's beforeFilter()

Configure::write('UserId', $this->Session->read('Auth.User.id'));

This will allow you to access the UserID from your models

Inside your User's model, create the following function

/**
 * Sample query which can be expanded upon, adding fields or contains.
 * 
 * @return array The user data if found
 */
public function findByUserId() {
    $user = $this->find('first', array(
        'conditions' => array(
            'User.id' => Configure::read('UserId')
        )
    ));

    return $user;
}

Inside your Users controller (Minimal is better, no?)

public function user_info() {
    $this->set('user', $this->User->findByUserId());
}

Inside your Messages controller

public function index() {
    $this->set('user', $this->Message->User->findByUserId());
    // --- Some more stuff here ---
}

And that's it, no need to be extending controllers, just make sure your Message and User model are related to each other, failing that you can bindModel or use ClassRegistry::init('User')-> for example.

HelloSpeakman
  • 810
  • 9
  • 22