So, I finally found a way to affect the desired function.
The function I was trying to modify is contained in a class so, I did something like this:
class my_Check extends Appointments {
function __construct() {
$this->unregister_parent_hook();
add_action( 'wp_ajax_post_confirmation', array( $this, 'post_confirmation' ) );
add_action( 'wp_ajax_nopriv_post_confirmation', array( $this, 'post_confirmation' ) );
}
function unregister_parent_hook() {
global $appointments; //this was the object created with the parent class
remove_action( 'wp_ajax_post_confirmation', array( $appointments, 'post_confirmation' ) );
remove_action( 'wp_ajax_nopriv_post_confirmation', array( $appointments, 'post_confirmation' ) );
}
function post_confirmation() {
...do the stuff with my mods...
}
}
$new_Check = new my_Check();
Only, I have a new problem now. The parent class does a lot more in the __construct() (many add_action()'s, etc. And $this is populated with a lot of data). The problem is, these other things and data do not seem to be carrying over into the child class. I tried adding a parent::__construct() in the child's __construct() function, but that did not seem to work.
The code with my mods works except for things that need more data in the $this carried over from the parent class.
How can I maintain all the parent class's variable, functions, hooks & filters, etc. into the child class?
And, I can't really change the file with the parent class because that is in a plugin core file which I don't want to modify directly.
I had seen many examples where people were using parent::__construct() to pass the parent's variables, etc. and they were placing it in the child's class __construct() function. That wasn't working for me.
However, I was finally able to get it to work by calling the parent constructor within the new function I was adding to the parent class. Like this:
function post_confirmation() {
parent::__construct();
...do the stuff with my mods...
}
Got the solution from this post > https://stackoverflow.com/a/32232406/1848815
Related
In this simple mock-up PHP class below I have 2 methods for adding JavaScript files into a page.
The goal is to use this in my apps plugin system so that user plugins which will extend this PluginCore class below will be able to call a function allowing them to include JavaScript files from there plugin into the main app.
PluginCore has an an Array $this->jsFilesArray which is used to store all the JavaScript files that should be included into the page.
There is a setter method to add new JS files to this array.
There is also a method which will iterate over the array and insert each JavaScript file into the page with script tags.
My question now is, how can I allow any plugin classes which extend from PluginCore class be able to somehow get there JS files added into the parent classes $this->jsFilesArray array so that when the core class inserts the files into the page, it will include any plugin JS files that have called a function of some sort to add files?
One idea I had is to use a WordPress style plugin/hook functionality so that the plugins would basically call a hook that is fired from the PluginCore class and inserts the JS files into the page. THE child plugins would simply hook into that action event.
This method will work but I was hoping to find other methods to achieve my desired result for learning purposes and also to test different methods.
Another idea is to have the child plugins have a addJsFile() function which would return an array of JS files for that plugin when called. The parent class could then call this method on the child class and do so for each plugin while combining the results of all them into a single array and passing that one into the PluginCore class.
So how can I achieve this?
Mock-up Class code to give a visual of what it might look like?
class PluginCore {
public $jsFilesArray = array();
public function __construct () {
$this->addJsFile('jsFileCOre1', 'http://file-path-url-to-js-file/jsfilecore1.js');
}
public function addJsFile($jsFileKey, $jsFileUrl) {
if( ! isset($this->jsFilesArray[$jsFileKey] )){
$this->jsFilesArray[$jsFileKey] = $jsFileUrl;
}
}
public function loadJsFilesIntoDom() {
foreach($jsFiles as $fileKey => $fileValue){
echo '<script type="text/javascript" src="'.$fileValue['fileUrl'].'"></script>\n';
}
}
}
One way is to make it static:
class PluginCore {
public static $jsFilesArray = array();
public function __construct () {
self::addJsFile('jsFileCOre1', 'http://file-path-url-to-js-file/jsfilecore1.js');
}
public static function addJsFile($jsFileKey, $jsFileUrl) {
if( ! isset(self::$jsFilesArray[$jsFileKey] )){
self::$jsFilesArray[$jsFileKey] = $jsFileUrl;
}
}
public function loadJsFilesIntoDom() {
foreach(self::$jsFilesArray as $fileKey => $fileValue){
echo '<script type="text/javascript" src="'.$fileValue['fileUrl'].'"></script>\n';
}
}
}
class PluginShell extends PluginCore {
public function __construct() {
self::addJsFile('jsFileShell1', 'http://file-path-url-to-js-file/jsfileshell1.js');
}
}
$core = new PluginCore();
$shell = new PluginShell();
var_dump(PluginCore::$jsFilesArray);
var_dump(PluginShell::$jsFilesArray);
This way $jsFilesArray is not bound to the instance of the class but the class itself so you don't have to worry about the communication between both classes.
But you might want to read about when to use static methods (and when not). Here the answer of IonuČ› G. Stan is very interesting and may help you further with your class if static is not the way you want to go.
I'm changing my class structure around to store common database methods in one class. Then extending it from a child class. This should cut down on code but also allows me to overwrite the parent methods when I need to.
I've done the following, for this example I've simplified to the basics compared to the original code which contains more classes.
class parent_object{
private $table_name;
public function all_records(){
$sql = "SELECT * FROM ".$this->table_name;
return $this->execute_sql($sql);
}
}
class child_object extends parent_object{
protected static $table_name="tbl_name";
public function __construct(){
parent::__construct(self::$table_name);
}
}
I want to call the all_records() statically to save myself creating a new object every time.
I'm stuck having to instantiate the child and then call the parent method
$child = new child_object();
$all = $child->all_records();
What I really want to be able to call the parent method statically:
$all = child_object::all_records();
I understand why I can't do it with my code, but would like some way that the child instantiates first then accesses the parent method.
I could write all_records() method in the child_object to instantiate itself and call the parent all_records() but that sort defeats the purpose of extending to cut down on code and the same methods in my child class.
I'm sure its quite simple or some new high level oop function can do it.
Thanks for your help.
The answer is relatively simple, you can turn all your properties into static properties, and then use static:: instead of self::.
http://php.net/manual/en/language.oop5.late-static-bindings.php
Solving your problem this way is considered a bad practice though. Good luck.
You could do something like this:
class child_object extends parent_object
{
protected static $table_name="tbl_name";
public static function factory()
{
return new child_object();
}
public function __construct()
{
parent::__construct(self::$table_name);
}
}
Then when you use it you just do:
$all = child_object::factory()->all_records();
I'm quite new to OOP and there are a few things I'd like to ask.
I'm writing a plugin for WordPress using OOP and I want to find out how I can allow other plugin developers to extend and redefine certain functions.
I have the main code wrapped in a class as follows and the class is instantiated at the bottom of the file:
class MyPlugin {
// .. methods here ..
public function myMethod(){
// do something
}
}
$myplugin = new MyPlugin;
However, I also want another plugin to be able to rewrite myMethod() by extending the class.
class OtherPlugin extends MyPlugin {
public function myMethod(){
// do something else
}
}
But in order for $myplugin->myMethod() to 'do something else', should I do this to override the $myplugin object:
$myplugin = new OtherPlugin;
Yes, you would want to reload that variable with the new, modified class... unless you pass by reference. Check it out... it's a neat little trick.
Happy coding! =)
I have a class PlaylistTrack that I want to extend class Song.
When I construct Song I pass in an array of data like artist, title etc.
When I construct PlaylistTrack I want it to have all song's methods as well as the new methods it introduces.
But I also want to pass in the specific song in its constructor.
So I'm doing this:
class Song {
function __construct( $song_data ) {
$this->_data = $song_data;
// etc
}
}
And then this. Don't shoot me!
class PlaylistTrack extends Song {
function __construct( $song ) {
// call the song's constructor again in the context of this class
// to give access to its methods.
parent::__construct( $song->_data );
// other PlaylistTrack-specific material to go here
}
}
This feels peculiar, to say the least. Is it ok? Is there an alternative?
The constructor is inherited automatically when extending a class. If you aren't planning to add functionality to your existing constructor, you don't need to polymorph it.
If you do want to add functionality to it, what you've done is perfectly fine.
Sorry for constantly re-editing my question but looks like this is the only way to ask it properly.
My original problem is the following pseudo-code (a controller and it's parent) isn't working as i would like to:
class Parent {
var $data = array();
public function __construct( OtherClass $otherClass ) {
$this->data = $otherClass->getData(); //contains some => thing
$this->init($otherClass->getClassName());
}
public function init( $className ) {
new $className; //new Child
}
public function __get( $name ) {
return array_key_exists($name, $this->data) ? $this->data[$name] : null;
}
}
class Child extends Parent {
public function __construct() {
echo $this->some; //won't return 'thing';
}
}
fireeyedboy helped me a lot (thank you) and pointed out Zend_Controller_Action is doing what i want but i can't understand how they do it?
Original question
I know there was some similar questions here but i cannot dump them. Also i know i can reverse the whole process so i can initialize Child first then call parent::__construct but this seems unwanted for me. How can i access Parent variables easily in my case?
Update:
Let me clarify a little bit. Child is an arbitrary controller. Parent is the mother of all controllers. Many frameworks are doing the same but controllers can utilize their parent controllers variables, methods or objects without calling parent::__construct (and therefore filling child class constructors with unnecessary arguments). I don't like to rewrite any of these frameworks but i'd like to understand how they're operating.
Your child class doesn't call parent constructor. Here's a fix:
class Child extends Parent {
public function __construct() {
parent::__construct();
echo $this->some;
}
}
Update: Parent classes' constructors aren't called automatically in PHP. See the documentation:
Note: Parent constructors are not
called implicitly if the child class
defines a constructor. In order to run
a parent constructor, a call to
parent::__construct() within the child
constructor is required.
So what you're asking does not happen. Either you have misinterpreted the class structure or how they operate. Note that PHP also supports legacy constructor naming (at least until 5.3.3): If there is no __construct() method in a class, PHP assumes the constructor is named after the class (ie. class Foo { function Foo() {}) treats the Foo() method as constructor).
Injecting ANYTHING using controller's construct is generally a BAD PRACTICE! Problem lies in your design. What kind of object is OtherClass? Is it DB adapter? Is it ACL? Is it some helper class?
If you need external class in your controller I suggest using action helpers. That's what they are created for ;) Or create an action helper that will fetch this OtherClass from somewhere when needed.
You should NEVER use __construct() to do any of your dirty work. That's what init() is used for. But it has no params. And there is a reason for that - again - you should not inject dependencies like this ;)
Update:
Note your class uses discouraged PHP4 member variable definition syntax. Try replacing your var with protected.
The problem is that your Child class does not call the base constructor.
Incidentally, Parent is not a valid class name in PHP. I have changed the class names for clarity. See below:
class ChildClass extends ParentClass {
public function __construct() {
parent::__construct(/* what goes here? */);
echo $this->some;
}
}
However, note the what goes here? part: your base class requires a reference to an OtherClass instance to be constructed. Therefore, since ChildClass IS-A ParentClass, it also needs to get such an instance somehow. You will need to either add a parameter to ChildClass::__construct and forward the value to parent::__construct, or somehow figure out a default value yourself.