I have a table called settings. I created a controller for this as settings controller.
<?php
class SettingsController extends AppController {
....
....
}
?>
By default I have app controller
<?php
class AppController extends Controller {
....
....
}
?>
In app controller I put some logic in beforeFilter method which is common for all controllers, Now I have to user some logics in beforeFilter in settings controller. But, I am unable to do so.. If I put beforeFilter in settings controller it doesn't access logics from appController before filetr,
Can anyone advice regarding this?
Can anyone advice regarding this?
Yes, learn about the basics of OOP in php first before trying to use an OOP based framework. Especially pay attention to the overloading section for what you want to do.
SettingsController already inherits the code from AppController because it extends it. The examples in the manual of the framework should already show you this:
public function beforeFilter() {
// Your code here
parent::beforeFilter();
// Your code here
}
You need to call the parent method.
Related
I see the line
parent::initialize();
in all the preloaded methods in CakePHP 3.x and in all the 3.x documentation.
Removing the line, or forgetting to add the line to new methods, doesn't seem to have any negative effects.
Which begs the question, what does it do?
Apologies is this is a totally noob question..
It is simple OOP. It calls the parent method of the same name.
Aclass {
public function foo() { echo 'bar'; };
}
Bclass extends Aclass {
public function foo() { parent::foo(); echo 'foobar'; }
}
Just try it and remove the parent call, you'll see what it does. The parents usually should be called, especially in methods like the initialize() callbacks. However, when to call or not to call them is a decision you have to make. It depends on if you want or need to call the parent methods logic or not. This is called "overloading".
This allows you to add functionality before or after the parent call of the method, which is a pretty common thing. I recommend you to read the OOP chapter of the php manual.
In your Controller’s initialize() method you can define any components you want loaded, and any
configuration data for them:
public function initialize()
{
parent::initialize();
$this->loadComponent('Security');
$this->loadComponent('Paginator');
$this->loadComponent('RequestHandler');
}
It is exactly what it says your running a method from the parent class. So the for example.
class AppController extends Controller {
public function initialize() {
echo 'hello world';
// do more sh*t
}
}
class UsersController extends AppController {
public function initialize() {
parent::initialize(); // this will run the method initialize from app controller that will echo 'hello world'
// do more sh*t
}
}
It's not doing anything when you remove it because there's nothing inside the parent initialize function, but it's there just in case you want to extend functionality from your parent controller to a child controller. For example:
In AppController there's a beforeFilter function that defines what I want to run before the page loads. Let's say I want a function to run on every single page - a simple redirect function if the user isn't logged in:
if (!$this->Auth->user()) {
$this->redirect('Users/login');
}
Instead of putting this in the beforeFilter on every single controller I go to, I can put it inside the beforeFilter of AppController.
My other controllers, like UsersController, extend from AppController:
class UsersController extends AppController {
So in the beforeFilter in my UsersController I can do:
public function beforeFilter(Event $event) {
parent::beforeFilter($event);
}
Now I inherit this redirect behavior from the parent controller(AppController), so that same code also runs in my child controller (UsersController) - and no matter what controller users go to they get redirected to the login page if they're not logged in.
This works the same way with parent::initialize(); you're inheriting what functionality exists inside the initialize function in the parent controller. This is just functionality included to eliminate redundant code.
So basically, if you see code that you're using on every single page, find a way to make it a bit object oriented by removing it and placing it in a file that your code can inherit from. It's along the same vein of moving the header and footer code out of HTML documents and placing them in their own php files so you can make a change in one area and have all affected derivatives updated, rather than editing the header and footer in every HTML document.
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.
I have a CakePHP app setup with Auth and ACL.
I have also made a Plugin within this app that includes a separate login to another part of the site away from the App. This uses Auth to login on a different table, and doesn't require ACL as users will be able to access all areas of this small section of the site.
I have managed to separate the two Auths using:
AuthComponent::$sessionKey= 'Auth.Recipient';
in the Plugin's AppController and
AuthComponent::$sessionKey= 'Auth.User';
in the App's AppController
This seems to work well and lets me login to both areas of the site separately.
Next when I tried to add more methods inside my Plugin I received the error:
AclNode::node() - Couldn't find Aro node identified by "Array ( [Aro0.model] => Group [Aro0.foreign_key] => ) "
I tried running AclExtras.AclExtras aco_sync out of desperation but that, not surprisingly didn't work.
I attempted to work around this, by adding another group (I am using Group ACL) called "Customer" and then assigning all users created in my Plugin table the Customer group id.
This stopped the error, I next tried to add a new row for my users/initdb method for these users so that they could only access the customers controller. However, if they attempt to access this they are kicked out to the login page as if they do not have access to this controller.
Adding the method names to:
$this->Auth->allow('');
works but obviously isn't a solution, although is pointing me in the direction of this being permission related.
The ideal solution for me, would be one where I could simply stop the plugin having any inheritance of ACL from the App.
I have 2 possible suggestions for breaking the inheritence structure of CakePHP to prevent the plugin from loading the components
Pseudo App Controller
Create a new controller class for example MyAppController which extends the core AppController which can then be used as a parent for main app's controllers, while the core AppController which remains empty is used for the plugins. The plugins then do not inherit anything
Your structure should be something like
A normal AppController class
// app/Controller/AppController.php
class AppController extends Controller
{
// left empty intentionally
}
A pseudo-AppController for your plugin
class MyAppController extends Controller
{
// all code for the main app
// used for all your normal app controllers
public $components = array('Acl', 'Auth');
// -- snip -- //
}
An example controller from the main app
App::uses('Controller', 'MyAppController');
class PostsController extends MyAppController
{
}
And the plugin app controller
class PluginAppController extends AppController
{
}
This will prevent any methods or instance variables being inherited by the plugin, but obviously is not great design as you will loose any methods you wish to share between the App and its plugins. Unless you extract them into components and add them to the AppController
Override the plugin controller __construct
Take advantage of OOP and override the __construct method in the plugins PluginAppController to prevent the ACL component from being loaded at all
class PluginAppController extends AppController
{
public __constrcut($request = null, $response = null)
{
// modify this to prevent components you don't want
}
}
Is it possible to load something on every CakePHP page without having to add a request in every actions in every model? Just add it somewhere and it's done for all the pages?
First off, Models do not have actions. Controllers have actions.
You can load data in all controllers by using AppController::beforeFilter()
class AppController extends Controller {
public function beforeFilter() {
$this->set('something', $foobar);
}
}
You can also load view stuff on all pages in the layout file.
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