CakePHP reference this controller with $this - cakephp

Using CakePHP how can you get a reference to this controller without specifying it's name?

Why would you ever want to reference a controller by name? Cake only ever has one controller loaded, you should not be loading other controllers in a single request. 1 request == 1 controller.
If you want to referent the model without the name, the default model name is in $this->modelClass
$this->{$this->modelClass}->method();
The accepted answer (if it is a model you want) is wrong.
class UsersController extends AppController {
public $uses = array('People');
public function method() {
$this->{$this->modelClass}->method(); // works
$controller = Inflector::singularize($this->name);
$this->$controller->someMethod(); // fatal error
}
}

I thought I needed to reference this controller to create the following public function.
But the dogmatic69 way is much nicer.
// Controller/AppController.php
public function dumpData() {
if(!Configure::read('debug') > 2)
throw new Exception(".dumpData() can only be accessed in debug mode.");
// $controller = Inflector::singularize($this->name);
// $data = $this->$controller->find('first');
$this->{$this->modelClass}->find('first');
die(debug($data));
}

Related

Symfony 2 FatalErrorException: Error: Call to a member function has() on a non-object

Symfony 2 typical problem, yet no clear response to it(I did some research).
Given the following "DefaultController" class which actually works:
<?php
namespace obbex\AdsBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction()
{
$em = $this->getDoctrine()->getEntityManager();
$connection=$em->getConnection();
$string="SELECT DISTINCT country_code FROM country_data";
$statement = $connection->prepare($string);
$statement->execute();
$result = $statement->fetchAll();
var_dump($result); //works not problem
die();
}
}
I want to delegate database calls to another class called "DatabaseController", the "DefaultController" now is set as following:
<?php
namespace obbex\AdsBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use obbex\AdsBundle\Controller\DatabaseController; //new DatabaseController
class DefaultController extends Controller
{
public function indexAction()
{
$dbController = new DatabaseController();
$res = $dbController->getQuery();
}
}
and the "DatabaseController" is set as following:
namespace obbex\AdsBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DatabaseController extends Controller{
public function __construct() {
}
public function getQuery()
{
$em = $this->getDoctrine()->getEntityManager();
$connection=$em->getConnection();
$string="SELECT DISTINCT country_code FROM country_data";
$statement = $connection->prepare($string);
$statement->execute();
return $statement->fetchAll();
}
}
And this throw and the following error: FatalErrorException: Error: Call to a member function has() on a non-object in /home/alfonso/sites/ads.obbex.com/public_html/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php line 202
my mind is blowing right now because I am extending the exact same class "Controller". Why it is working in one case and not in the other?
Apparently it is a "container problem" that can be set trough a service according to a response in another thread or via extending the "Controller· class however does not work in this case.
First of all, you shouldn`t delegate database management to another controller, that's a bad practice.
Instead, you can inject a service containing all DB logic
Symfony2 Use Doctrine in Service Container
Or use a EntityRepository
http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes
Regarding the issue with has() function, you are creating an instance of a Controller without any container on it. Therefore, when the controller tries to call $this->container->has() throws an error, as container is not defined.
I finally set the object caller and I requested the container service as follows:
on the services.yml file
service:
manage_ads:
class: obbex\AdsBundle\Classes\ManageAds
calls:
- [setContainer, ["#service_container"]]
on the main controller:
$ads_manager = $this->get('manage_ads');
$ads_manager->functionCallingTheRawQuery();
But I still use this optionally because now I am setting my queries from the repository of an entity rather than create my own objects (For now, I am new to symfony2)

Codeigniter Undefined property: xxxx_model::$db only from Model

First the Model class:
class Xxxx_model extends Model
{
function XxxxModel()
{
parent::Model();
$this->load->database();
}
function isInDatabase()
{
// Please ignore the sql query, it's just to show some random sql code with results
11. $result = $this->db->query('SELECT * FROM someTable WHERE ...');
$numberOfRows = $result->num_rows();
...
return $test;
}
}
Now the controller:
function someLogic()
{
$this->load->model('xxxx_Model', 'xxxxModel'); // not necessary to specify
$this->xxxxModel->isInDatabase();
}
When I run this I get the error:
Severity: Notice --> Undefined property: Xxxx_model::$db .../xxxx_model.php line 11
I have no idea why this is. If I put the db code in the controller it seems to work, it's only with this setup in the model that it fails. I can't for the life of me figure out where the code is astray...
You have to load the db library first. In autoload.php add below code,
$autoload[‘libraries’] = array(‘database’);
add library 'datatabase' to autoload.
/application/config/autoload.php
$autoload['libraries'] = array(
'database'
);
Propably you're started new project, like me ;-)
To add to atno's answer:
class Xxxx_model extends Model
{
function XxxxModel() //<--- does not match model name Xxxx_model
{
parent::Model();
$this->load->database();
}
Basically, you are not constructing the class or the parent class Model. If you are on PHP5, you may use __construct(), otherwise you must match the class name exactly, regardless of what alias you load it with in your controller. Example:
class Xxxx_model extends Model
{
function __construct()
{
parent::__construct(); // construct the Model class
}
}
I may be mistaken (haven't used 1.x in a while), but if you construct the Model class, there's no need to load the database if you are using the default connection settings in config/database.php, it should already be loaded for you.
If function XxxxModel() isn't your constructor, you're not loading the database by calling $this->xxxxModel->isInDatabase();
Try autoloading the database library from within autoload.php, or create a proper constructor in your model.

CakePHP doesn't load model

I'm new to cakePhp development. I've stuck on following problem:
I've made few models, controllers and views - it works great. The problem is that after production, I have to made new table(Transactionaltemp table and corresponding model and controller ) in the db that logically is "connected" to other tables, but technically does not needs to - for ex. it holds temporary info on user_id, time, ip and similar. So, other tables doesn't need to be directly connected to that.
The problem is when I try (in some other controller than transactionaltemps_controller):
$this->loadModel('Transactionaltemp');
I get error - the model is not found (it is true because the model is missing in the cache). Interesting enough transactionaltempls_controller is in the cache (in the cake_controllers_list file).
I tried following stuff to resolve the problem:
clear cache
disable cache
tried using uses={..} code in the controller that I would like to use mymodels_controller
tried using init('Transactionaltemp')
with no success. Here is corresponding code:
The model:
<?php
class Transactionaltemp extends AppModel
{
var $name = 'Transactionaltemp';
function beforeSave() {
return true;
}
}
?>
The controller:
<?php
class TransactionaltempsController extends AppController
{
var $name = 'Transactionaltemps';
var $scaffold;
}
?>
I'll very grateful to any help!!!
App:Import('Model','Transactionaltemp');
$this->Transactionaltemp= new Transactionaltemp;
I hope this may work
If you are connecting to a table name with different name than your model, you must specify the table name in it:
<?php
class Transactionaltemp extends AppModel
{
var $uses = 'Transactional';
var $name = 'Transactionaltemp';
function beforeSave() {
return true;
}
}
Try
App::Import('Model', 'YourModelName');
in your controller (or where you want).

CakePHP: best way to call an action of another controller with array as parameter?

In a controller, what is the most appropriate way to call the action of another controller and also pass an array as parameter?
I know that you can use requestAction to call actions within other controllers. But is it possible to pass arrays as parameters using request action?
And no, I do not want to put the action in the App Controller. So that is not a solution for me.
The only other way I know is to load the other controller as explained in:
http://book.cakephp.org/1.3/en/The-Manual/Developing-with-CakePHP/Configuration.html#importing-controllers-models-components-behaviors-views-and-helpers
But is there an easier way to just call the other controllers action while passing an array as parameter?
I am new to cakePHP so any suggestion is appreciated. Thanks.
I would not advice to use the method requestAction but rather import, and instantiate the needed controller.
CakePHP doc says about requestAction that:
"It is rarely appropriate to use in a
controller or model"
http://book.cakephp.org/view/434/requestAction
Once you imported and loaded the controller you can call any method of this controller with its parameters.
<?php
//Import controller
App::import('Controller', 'Posts');
class CommentsController extends AppController {
//Instantiation
$Posts = new PostsController;
//Load model, components...
$Posts->constructClasses();
function index($passArray = array(1,2,3)) {
//Call a method from PostsController with parameter
$Posts->doSomething($passArray);
}
}
?>
Would it be appropriate for you to move the logic from the second controller into its model, then do something like this in your first controller's action?
$var = ClassRegistry::init('SecondModel')->myMethod($array);
$this->set(compact('var'));
Then, in the view for the first controller's action, you can use that data.
I always try to keep controller methods to actions you can hit through the browser, put as much logic in my models, call foreign model methods from controllers actions that need data from models that aren't the model for that controller, then use that data in my views, and if it's data that is viewed frequently, I create an element for it.
As of CakePHP 1.2.5, you should be able to pass various parameter types through the second parameter in requestAction(). e.g.:
$this->requestAction('/users/view', array('pass' => array('123')));
Then in the UsersController:
function view($id) {
echo $id; // should echo 123 I believe, otherwise try $this->params['pass'].
}
Instead of using 'pass' above, you can alternatively try 'form' and 'named' to pass form/named parameters respectively.
CakePHP 2.X:
<?php
App::uses('AppController', 'Controller');
App::uses('PostsController', 'Controller');
class CommentsController extends AppController {
public function index($parameter = null){
//Instantiate
$Posts = new PostsController();
//Load model, components...
$Posts->constructClasses();
//Call a method of Posts passing a parameter
$Posts->aMethod($parameter);
}
}
I put into my AppController class the following method and variable so it is caches in case of multiple calls
var $controllersArray = array();
function _getController( $pControllerName ){
if ( ! isset($this->controllersArray[$pControllerName]) ){
$importRes = App::import('Controller', $pControllerName);// The same as require('controllers/users_controller.php');
$strToEval = "\$controller = new ".$pControllerName."Controller;";
$evalRes = eval($strToEval);
if ( $evalRes === false ){
throw new AppException("Error during eval of given getController '$pControllerName'");
}
$controller->constructClasses();// If we want the model associations, components, etc to be loaded
$this->controllersArray[$pControllerName] = $controller;
}
$result = $this->controllersArray[$pControllerName];
return $result;
}

CakePHP Time Helper Problem

I think I might be making a mistake here.
I am getting the following error when trying to use a simple function in the time helper in my controller. I don't get an error when using the same function call in the view.
Below is the error from the controller.
Followed by the controller code that is failing.
Followed by the view code that is working.
Any help is appreciated!
Error:
Notice (8): Undefined variable: time [APP/controllers/temp_users_controller.php, line 25]
Code $checkTime = $time->gmt();
Fatal error: Call to a member function gmt() on a non-object in /var/www/studydeck/app/controllers/temp_users_controller.php on line 25
Controller:
class TempUsersController extends AppController {
var $name = 'TempUsers';
var $scaffold;
var $components = array('Auth');
var $helpers = array('Time');
function beforeFilter() {
//list of actions that do not need authentication
$this->Auth->allow('userCleanUp');
}
//this function will delete TempUser accounts which have not been activated
function userCleanUp() {
$checkTime = $time->gmt();
$this->set('checkTime',$checkTime);
}
}
View:
echo $time->gmt();
Update:
I tried $time = new TimeHelper();
I received the error
Fatal error: Class 'TimeHelper' not found in /var/www/studydeck/app/controllers/temp_users_controller.php on line 23
I do have var $helpers = array('Time')
Also not that echo $time->gmt(); works in the view with out instantiating time anywhere.
Helpers are thought to be used in views, not in controllers, hence the error. If you really have to use the helper in your controller, you have to instantiate it yourself:
$time = new TimeHelper();
You generally don't use a helper from the controller.
The array you assign in the controller is used to load and instantiate the helper classes before the view is parsed and rendered.
To use the helper in your controller you need to make sure the file is loaded ( included ) correctly and that you have an instance of it to work with. You can also use many of them statically from within a controller, expecially those helpers that don't need access to the controller object.
Cake provides you with a core function that you can use to safely include the files. It will even handle where the file gets loaded from automagically so you don't need to deal with paths.
An example to get you started.
<?php
class TempUsersController extends AppController
{
public $name = "TempUsers";
public function userCleanUp( ){
// include the time helper
App::import( 'Helper', 'Time' );
$time = new TimeHelper;
$checkTime = $time->gmt( );
$this->set( 'checkTime',$checkTime );
}
}
?>
On this line:
$checkTime = $time->gmt();
The $time variable is not defined and is automatically set to null. The error states that it is not an object (which is correct). Did you initialize it properly? I cannot see any initialisation done for the $time variable.

Resources