Hi, We developed a plugin for our cake PHP projects this is very usefull and manage user access, permisitions rests, etc. Five our projects use this plugin, and we are not being DRY, cause we’re repeating a lot of code to call this functions inside every AppController project. Is there a way to make AppController from each project extend AppController from this Core plugin? We tried to call use Core\Controller\AppController but didn’t work, we tryed to use as a component and call this functions inside AppController (project) but this don’t work as expected. Actualy for each request cake must load first this Core AppController than AppController from project and finaly the FinalController, like one extending another untill the end. Do anyone know how we could implement it?
I think you would need a component.
Here is a simple example how to do something like that: https://github.com/rrd108/rBruteForce
A component doesn’t allow you to share constants, functions like beforeFilter(), and $this->set() for various site-wide variables, etc. I have the exact same requirement: a way to have a common ancestor for my application’s AppController from a Plugin. The only alternative is a lot of marshalling calls to the component, which isn’t exactly dry either.
Well, I have a menu plugin with a builMenu() method in menusTable.php.
I call it from the AppController (with loadModel).
Works like a charm.
Thanks for the reply, but again, this is not what we are looking for. Please read the original question.
I haven’t tried it, but it seems that standard object oriented programming with namespaces should make this work exactly as desired. When you try to have your application’s AppController
extend the plugin’s AppController
, what part of it doesn’t work?
Yes, that’s what I would have expected as well. I’ve tried various things. The plugin is called Logos, and I want a base controller, so I created Logos/src/Controller/BaseController.php:
namespace Logos\Controller;
use Cake\Controller\AppController;
use Cake\Event\Event;
/**
* Common Controller functions
*/
class BaseController extends AppController
{
...
}
Then, in the main AppController:
class AppController extends \Logos\Controller\BaseController
{
}
The error I get is this:
Fatal error : Class ‘Cake\Controller\AppController’ not found in /var/www/logos/dev/plugins/Logos/src/Controller/BaseController.php on line 18
So, the BaseController is found, but inside the plugin the ‘core’ Cake AppController is not! I also tried
use \Cake\Controller\AppController;
use App\Controller\AppController;
use \App\Controller\AppController;
inside BaseController.php, but no go… Perhaps somebody with more insight in the Cake loading process can clarify why this is the case?
Your problem is that \Cake\Controller\AppController
doesn’t exist. There is no AppController
class in the core CakePHP library, you’re looking for \Cake\Controller\Controller
@dakote: I think you put me on the right track, and I found the problem: a circular reference.
The ‘main’ AppController in an application is derived from Cake\Controller\Controller; if we write out the definition using full namespaces it reads like this:
/* src/Controller/AppController.php */
class App\Controller\AppController extends Cake\Controller\Controller
{
}
A freshly generated plugin looks like this:
/* plugins/src/Logos/Controller/AppController.php */
namespace Logos\Controller;
use App\Controller\AppController as BaseController;
class AppController extends BaseController
{
}
So the plugin AppController is derived from your main AppController [*]:
class Logos\Controller\AppController extends App\Controller\AppController [extends Cake\Controller\Controller]
Clearly, we need a different route. I created a Logos/src/Controller/BaseController.php and derived it from Cake\Controller, just as a ‘regular’ AppController.
/* plugins/Logos/src/Controller/BaseController.php */
namespace Logos\Controller;
use Cake\Controller\Controller;
class BaseController extends Controller
{
protected $user_language = 'nl';
public function beforeFilter (\Cake\Event\Event $e)
{
$this->set ('lang_id', $this->user_language);
}
}
Then in my main AppController:
/* src/Controller/AppController.php */
class AppController extends \Logos\Controller\BaseController
{
public function beforeFilter (\Cake\Event\Event $e)
{
parent::beforeFilter ($e);
}
}
…and the lang_id variable is set!
[*] One could doubt the wisdom of having plugins derive their AppController from the main one; there could be all kinds of name conflicts or overloaded functions that affect your plugin, while IMO a plugin should be independent and unaffected by whatever application it is included in.
The idea here is that 99% of the time, the plugin author/consumer would want the plugin to use the same base configuration as the rest of the application (i.e. authentication, etc.)