I'm just getting my feet wet in Wordpress, and I'm trying to write a very simple plugin using OOP techniques. I've been following this tutorial: http://www.yaconiello.com/blog/how-to-write-wordpress-plugin/ . So far I feel like I understand most of what's going on, but I'm slightly puzzled by statements such as this one:
add_action('init', array(&$this, 'init'));
Having read the documentation on Wordpress's add_action() and PHP callables, I gather that the second argument is a method of a class instance. But I don't understand why $this has to be passed by reference.
Found this note in the PHP docs about callables which I suspect may have something to do with it, but I'm still having a hard time wrapping my head around what the difference is:
Note: In PHP 4, it was necessary to use a reference to create a callback that points to the actual object, and not a copy of it. For more details, see References Explained.
If I have PHP 5, am I safe just using array($this,'init')?
Possibly related: add_action in wordpress using OOP?
Yes - you are safe to just use array($this, 'init');.
What this is actually is, is a "callable" in PHP. It will be invoked using call_user_func() or call_user_func_array() (internally inside the add_action method).
PHP's official description of this type of callable:
A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1.
You can read more about callables here.
Related
The following code is the sample code:
$sample= $module->get('data')
->anotherModule
->find(true);
I couldn't understand what exactly is the object hierarchy in here. According to my knowledge, there must be an object $module and that class has a method get which takes the parameter as 'data'.
But according to the code, still it gets deeper to anotherModule and find method. Can anyone explain me what is happening in this code?
This is called method chaining.
A method returns an object which contains other methods. You can find an example for that here: PHP method chaining?
while seeing word press core code in depth i came across a file which has many empty functions for eg :
/**
* #ignore
*/
function apply_filters() {}
i realy dont know what is the use of declaring empty function in php..
i found this in wp-admin/list-scripts.php on line 34 - 37
and in wp-include/plugin.php on line 163 - 207 the same function is re declared with some works in it
In total i have 2 questions
What is the use of declaring an empty function in php
Why wordpress din't show any Fatal error: as the same function is already declared. ?
In PHP (and many other OOP languages), an empty function (or, more precisely, method) can be used in an interface. Any class inheriting that interface must implement the declared functions. However, last time I checked (which is, 2 minutes ago), WordPress isn't really an OOP system, so forward to 2.
list-scripts.php is not a default WordPress file - I can't find it in any of my WP installation. You may want to test by putting a die('called'); on top of the file and see if it gets executed. Therefore, WordPress won't encounter duplicated function declaration, and no fatal errors are introduced.
Now, even if list-scripts.php is a default WP file, when working with WP (and PHP in general) more often than not you see this:
if (!function_exists('apply_filters')) {
function apply_filters($arg1, $arg2) {
// code is poetry
}
}
This makes sure a function is only declared if it hasn't been before, and avoids the fatal error.
I guess wordpress will conditionally include either one or the other file. A lower level API of wordpress expects this functions to be defined and calls them. The extension itself is free to implement the function or not, however it has at least to provide the empty function body. The concepts behind this are much like interfaces work in OOP.
I'm trying to remove an action that a plugin registers in a separate functions.php file, but the syntax is stumping me. The plugin (I can't copy/paste - commercial plugin) infers to the add_action like so:
class Plugin_Class{
function add_actions(){
add_action('tag', array(&$this, 'function_to_remove'), 10);
}
function_to_remove(){
global $wp;
// Code here
}
}
I'm mostly confused with &$this. I know that this refers to the instance of the class, but based off my research it should be removed like so:
Need help with remove_action()
I just don't know how to come up with the syntax for my situation. Why define the global variable? Would I need to do that in my case? I'm assuming the widget array comes from WP core code, but I'm confused on how I need to implement this in my case, which seems to be much simpler. Sorry if this stuff is remedial.
Thanks for any help in advance.
The &$this creates a reference instead of a copy. That way when you access that variable later, you really access this object and not a copy.
http://www.php.net/manual/en/language.references.whatdo.php
See the paragraph about array "not exactly assigning by reference, but equivalent."
A little background: At runtime I would like to be able to inspect the currently called functions javadoc-style documentation, to determine its formal (typed) declaration. This would allow runtime type checking (for simple and complex types) by means of reflection (at a cost) during debugging and testing, something that I would find immensely helpful.
So, in php I would like for a user defined function to get called whenever any other function is about to get called. That is, if a function foo() gets called, I would like to have my callHookHandler() function called immediately before.
One solution would be to implement __call() in all user defined classes, but that is both unwieldy and doesn't include support for functions defined outside classes, so I am looking for a better solution.
This sounds a bit of a fun one so I'm going to give answering it a try.
I hope this helps you. Let me know how it goes.
So, what you are asking can be done, and here's how:
For Functions:
Get all defined functions with $function = get_defined_functions().
Loop through the $functions['user'] key and inspect each one with the ReflectionFunction class. You'll need to get:
The comment using ->getDocComment()
The arguments using ->getParameters()
Do some magic (I'll let you figure out how to parse the comment using some regular extressions and match it up with the parameter list from the reflection. Don't forget optional parameters!)
Rename the function using runkit_function_rename
Generate code in a string that checks the parameters and calls the renamed function
Generate a parameter list as a string
Create a new function with runkit_function_add using the code you generated in step #5 and the parameter list from step #6.
For Classes:
Get a list of classes with $classes = get_declared_classes();
Loop through each one and inspect it with ReflectionObject and ->getMethods() to get the methods. Make sure that the class is not internal with ->isInternal() because we can't do anything about the internal classes.
In an inner loop... go through each method using the ReflectionMethod class. Get the arguments and PHPDoc/JavaDoc comments just like you did with normal functions.
Do the same thing you did with the functions only use runkit_method_add and runkit_method_rename instead.
Downsides:
You won't be able to do the checking on internal class methods and functions (which is fine because they won't have doc comments anyway).
This is a lot of work! I left a lot of parts up to your imagination to avoid this being the length of a short book.
Please send me this or open source it and let me know when you finish, I really want to use this myself. Contact info is on my website which is in my profile ;)
Alternatively:
You can use XDebug's function trace along with reflection then analyze the results after the fact so that you don't have to dynamically edit the code. If you want to write unit-test you could even automate it.
Hope type checking makes it into future versions of PHP and wait: https://wiki.php.net/rfc/typechecking
Notes:
This class reference has a potentially useful example of parsing docComments in the comments section of the page:
http://us.php.net/manual/en/class.reflectionmethod.php
References
get_defined_functions
get_declared_classes
ReflectionFunction
ReflectionObject
ReflectionMethod
runkit
Alternative way to hook into function call is to use a trick with namespaces: Intercepting Execution of System Functions in PHP
You can also use the Go! framework to define an aspect to intercept the execution of system functions automatically.
This question already has answers here:
Redefining PHP function?
(9 answers)
Closed 8 years ago.
Can I redeclare a existing function, with the same name, but different code? Or somehow "disable" the old function?
I want to redefince a core WordPress function, but since plugins and theme call this function a lot, I need to keep the same function name.
You could use the WordPress hooks (called filters and actions) and then use the add_filter() function to override the function you are using.
i.e.
function function_name() {
//code goes here
}
$hook = 'get_options'; // the function name you're filtering
add_filter( $hook, 'function_name' );
The Codex will help a lot with this.
http://codex.wordpress.org/Plugin_API/Filter_Reference
Only if you use something like APD that extends the zend engine to allow for that:
Intro
Override Method Docs
Note: Runkit seems like a better option than APD since it's more specific to this purpose and would allow you to keep the original method intact at a different address.
You can wrap the block defining the original function in a conditional checking if another of the same name is not already defined (I'm assuming you mean Wordpress functions and not core PHP ones)
<?php
if(!function_exists('function_name')){
//old definition here
} ?>
You could then redefine it above while still preserving the original should you need to roll back to it.
Depending on how complex the changes are and how many times you may do this, you may also want to look into Namespaces if you are on PHP 5.
Just comment the old function out and write your new one ;)
In PHP it is not possible to redefine or overload (i.e. define a function with the same name but different parameters) a function natively. There though are extensions like runkit which allow to redefine functions (runkit_function_redefine), but you probably don't want to use these (such extensions are rarely installed and mostly unreliable.)
My attempted solution was to do this:
function suffusion_get_image($options = array()) {
include_once ABSPATH.'wp-content/themes/suffusion-child/functions/media.php';
return childtheme_overide_suffusion_get_image($options = array());
....
}
Obviously there is an overhead at upgrade as you would need to add lines back into the scripts again and I have used this method successfully to date but now trying to do it with get_terms in the wp-includes and hitting a redeclaration issue which I am trying to resolve or workaround at the moment.
My reason to edit core is that the existing core does not provide in a convenient way for a multisite requirement.
Someone has just suggested on another forum however using override_function but the manual is worded such that it appears to be of use only to built-in functions - I took it that means PHP built in functions