I have three classes:
MyPlugin extends OtherPluginClass extends Service
MyService extends AccesibilityService
LoggerClass implements BaseLoggerClass
MyService starts when the user authorizes it in Accessibility settings. MyPlugin is started and controlled by a different application (tho' I have access to its source code).
The problem is the LoggerClass is coordinated by MyService, however LoggerClass needs the context of MyPlugin to perform some operations.
I've tried to create a static sharedContext variable in MyPlugin and populate it in the onCreate method, but LoggerClass always sees sharedContext as null.
What would be the best way for LoggerClass to access MyPlugin's context?
Related
Something that should be trivial in IMHO.
I have a public function in my webapp AppController - call it getDbConfig()
I have a plugin and I want to reference the getDbConfig() function that was defined in the system-wide AppController.
Obviously $this->getDbConfig() does not work - since $this refers to the local context - but for the life of me I cannot figure out how to specify the path to public functions in the system AppController in Plugin AppControllers
Doesn't make sense IMHO. A plugin is made to live outside you application. Ideally you could make you plugin public so that other developers could use it inside their application.
If you reference a function that you (and only you) have in your AppControll your plugin is no more a plugin.
I think that this is the typical case where you should create a Component. Put the getDbConfig() inside a Component so that you can call that component both from the Plugin and the AppController
but for the life of me I cannot figure out how to specify the path to public functions in the system AppController in Plugin AppControllers
Read about php OOP namespace basics. You need to import and alias the class. And inherit from your apps AppController. This would make the plugin rely on having the App namespace available, however, at least I have never seen a CakePHP app using another namespace. If it's another one the developer can still fork and use that fork and make the change to it.
Alternatively make the code in question a component or utility class and check in your plugins AppController if that class exists and then instantiate the utility lib it or load the component.
You should pass the function to your plugin/component as a configuration parameter, or the results from getDbConfig() (I assume it won't change much).
So:
class MyComponent extends Component
{
private $dbconfig = null;
public function initialize (array $config)
{
parent::initialize ($config);
if (isset ($config['dbconfig']))
{
$this->dbconfig = $config['dbconfig'];
}
}
}
Then, in your controller:
class MyController extends AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent ('My', ['dbconfig' => $this->getDbConfig()]);
}
}
If you really must reference a function and call it, use variable functions.
This question already has answers here:
How to extend a component with dependency injection?
(4 answers)
Closed 6 years ago.
In my quest to learn Angular2, i came across the following situation:
1 base class, which uses the angular2/http dependency
1 inheriting class which extends the base class
How can I inject the angular2/http dependency in the base class's constructor, without having to pass http as a parameter when instantiating the inheriting class.
I don't use http in the inheriting class, so I don't want to see it there!
For example
// base class
class CRUDService {
// http is used in this service, so I need to inject it here
constructor(#Inject(Http) http) {}
findAll() {
return this.http.get('http://some.api.com/api/some-model');
}
}
// inheriting class
class ThingService extends CRUDService {
constructor() {
// because we extend the base class, we need to call super()
// this will fail since it expects http as a parameter
// BUT i don't use http in this class, I don't want to inject it here
super();
}
}
Ideally, I would just create a new http instance in the base class and use that like so let http = new Http();, but that obviously doesn't work.
That's not supported. If you want inject something you have to list it in the constructor of the sub-class and if you want to pass it to the super-class you can by using super(someDependency). There is no way around.
That's not an Angular limitation but a language limitation that is quite common among typed classes.
I am using cakephp v2.6 to develop a web app.
Is it possible to call a controller within another controller in CAKEPHP.
Is it correct way for doing the same
In SecondController.php
App::uses('FirstController','Controller');
class SecondController extends AppController
{
$firstcontrollerobject=$this->FirstController;
}
Thanqs
Short answer is Yes, but you shouldn't.
You should use either a component or a model. Or put your action in AppController if you want it to be used by other controllers.
App::uses('FirstController','Controller');
class SecondController extends AppController
{
public function test() {
$FirstController = new FirstController();
$Firstcontroller->action();
}
}
Put PHP code in the Component, if you want to share between several controllers
Components are packages of logic that are shared between controllers. CakePHP comes with a fantastic set of core components you can use to aid in various common tasks. You can also create your own components. If you find yourself wanting to copy and paste things between controllers, you should consider creating your own component to contain the functionality. Creating components keeps controller code clean and allows you to reuse code between projects.
http://book.cakephp.org/2.0/en/controllers/components.html
I have a custom structure in my CakePHP app which goes like this:
class AppController extends Controller // default
class ExtendedAppController extends AppController
class ChildController extends ExtendedAppController
The components I declare in ExtendedAppController get erased when I declare components in a ChildController class. I guess I will have this same problem with helpers also. How do I merge the arrays to avoid this?
Cake merges the current controller's variables with only ONE parent class which by default is set in the variable $_mergeParent = 'AppController'; in the core Controller class.
You can override this variable in your ChildController by defining:
class ChildController extends ExtendedAppController {
protected $_mergeParent = 'ExtendedAppController';
}
However, this will ignore all the helpers and components defined in AppController, so copy the components and helpers from your AppController to your ExtendedAppController. This should answer your question I guess as you will be able to use ExtendedAppController's components from your ChildController and other controllers extending AppController will use AppController's components.
It is the way the Controller::_mergeControllerVars() method is written in the core. This is precisely why the book says:
The HtmlHelper, FormHelper, and SessionHelper are available by
default, as is the SessionComponent. But if you choose to define your
own $helpers array in AppController, make sure to include HtmlHelper
and FormHelper if you want them still available by default in your
Controllers.
Using CakePHP, I am finding that I'm duplicating some code between controller actions. I have a dozen or so actions (belonging to various controllers) that all need to run the same query and set() the same 10 variables for the use in a particular layout. They also need to handle any errors in the same way and render an error page.
I know that components are intended to centralize logic used among controllers, but in my case, this logic needs access to the set() and render() methods of the controller. What is the suggested approach to this situation?
Thanks, Brian
Put the logic in your AppController class which your controller should extend from.
Check out the docs: http://book.cakephp.org/view/957/The-App-Controller
Ended up rolling my own sort of business logic layer on this one. Example below. Thoughts/comments welcome.
class MyController extends AppController {
public function my_action() {
// The BLL class is specific for this action and gets the entire
// controller so has access to the set() method as well as components.
$this->Bll = new MyActionLogic($this);
$this->Bll->do_whatever();
}
}