Is there any difference between a class method and a regular function? - php

I'm trying to learn wordpress to create my wordpress themes. But the problem is, whenever I try to load my css files by using the wp_enqueue_style() inside a class then my wordpress admin area just breaks up. What I mean by breaking is that, it's js file fails to load due to which it's coloring scheme turns from blue to red and functionality of buttons like "Screen Options" or "Help" stops working.
Here is the working code:
function wp_custom_styles(){
wp_enqueue_style("bootstrap_css", get_template_directory_uri() . "/css/bootstrap.min.css");
wp_enqueue_style("style_css", get_stylesheet_uri());
}
add_action("wp_enqueue_scripts", "wp_custom_styles");
But if I use this:
class wp_theme_preparation{
public function __construct(){
add_action("wp_enqueue_scripts", $this->add_theme_styles());
}
public function add_theme_styles(){
wp_enqueue_style("bootstrap_css", get_template_directory_uri() . "/css/bootstrap.min.css");
wp_enqueue_style("style_css", get_stylesheet_uri());
}
}
$instance = new wp_theme_preparation();
The admin area crashes. And it ends like this:
As you can see from the image I clicked on the "Screen Options" button but it doesn't work.
So my question is what is the difference between these two codes ?
Why the first piece of code is working and second isn't when both of them are just calling a function ?

To register an action that is a method, you should use
add_action("wp_enqueue_scripts", array( $this, 'add_theme_styles') );
See the documentation (particularly the 'Using with a class` section).
UPDATE
Your original code
add_action("wp_enqueue_scripts", $this->add_theme_styles());
attempts to register the return value of calling $this->add_theme_styles() as a callback, not what you intended.
WordPress makes use of PHP's call_user_func, which expects a callable argument. From that page:
A PHP function is passed by its name as a string. Any built-in or
user-defined function can be used, except language constructs such as:
array(), echo, empty(), eval(), exit(), isset(), list(), print or
unset().
A method of an instantiated object is passed as an array containing an
object at index 0 and the method name at index 1.
That last sentence comes down to passing array( $objectInstance, 'method_name' ) as the callback.

Related

php Warning: Missing argument 2 for {closure}()

I have encountered a warning I am not understanding, and I'd like to know in which way this may affect my code. As far as I can tell, the code works and everything looks like it should.
I am working in a WordPress setting, however it seems to me that the problem is a misunderstanding on how to use anonymous function, and not strictly related to WordPress.
However, this is the situation. I have a class with a few methods creating standard pages, which I need to repeat for several instances of that class. The class methods return the content of the page and they work correctly.
I want to add these pages to the wordpress admin menu, and normally I would simply call the function
$t = new My_Class();
//the method of the class that generates the content
$function_name = "foo";
add_submenu_page( $parent_slug, $title, $menu_title , 'manage_options', $function_name, array( $t, $function_name) );
However, in this case the function returns the content instead of echoing it, so that would result in a blank page. So I tried this
add_submenu_page( $parent_slug, $title, $menu_title , 'manage_options', $function_name, function ($t, $function_name ) use ($t, $function_name) {
echo $t->$function_name();
} );
As I said, this works, but it generates that warning and it made me wonder if I am doing something wrong or if I am misunderstanding what the code is doing (thus potentially leading to unwanted behaviours in the future).
PS: I KNOW I could simply add a new method that echoes the content of the other one, or add a parameter to echo the content instead of returning it. However, I'd rather understand what the problem is, if any.
To get rid of the error message do this
add_submenu_page( $parent_slug, $title, $menu_title , 'manage_options', $function_name, function () use ($t, $function_name) {
echo $t->$function_name();
});
I'm not familiar with WP so I don't know what add_submenu_page() does but it seems that it passes one argument to the anonymous function, which you overwrite by adding the same named $t to the anonymous function lexical scope with use ($t, $function_name).
Essentially, second argument to function ($t, $function_name) is not being passed, but in the end it works because you have same variable names, and you overwrite them with the variables 'injected' with the use keyword

Working with smarty template engine for WHMCS. Need to use php function from external php file in .tpl file

Trying to fetch output in A.tpl but not getting any output. I think i'm doing something wrong to call php function in tpl file.
A.tpl
{myModifier}
B.php
class Geolocation{
public function sm_loc($params, Smarty_Internal_Template $template)
{
return "100.70";
}
}
$smarty1 = new Smarty();
$smarty1->registerPlugin('modifier', 'myModifier', array('Geolocation', 'sm_loc'));
I 've already used this code. And this doesn't seem to work. It also breaks my existing working code in A.tpl post this use.
My Need here is to get output from the php function in A.tpl from an external php file.
Thanks in Advance. Sorry for being noob.
To add this modifier to Smarty and use it in your template, you're best to use a WHMCS hook.
If you create a new PHP file under the '~/includes/hooks/' directory (you can name it anything - in this case, let's use 'myhook.php'), WHMCS will automatically inject this hook on each request.
For this, you're going to want to use the ClientAreaPage hook. Inside your hook, you can then access the global $smarty variable.
Example:
function MySmartyModifierHook(array $vars) {
global $smarty;
// I recommend putting your Geolocation class in a separate PHP file,
// and using 'include()' here instead.
class Geolocation{
public function sm_loc($params, Smarty_Internal_Template $template) {
return "100.70";
}
}
// Register the Smarty plugin
$smarty->registerPlugin('modifier', 'myModifier', array('Geolocation', 'sm_loc'));
}
// Assign the hook
add_hook('ClientAreaPage', 1, 'MySmartyModifierHook');
That should do the trick. If you want to explore with other hooks, you can take a look at the Hook Index in the WHMCS documentation.
The function names in each of your hook files must be unique.
As a side note, if you're only wanting to run this hook on specific pages, you can check the templatefile key in the passed $vars array. For example, say you only wanted this hook to run on the 'View Cart' page on the order form:
function MySmartyModifierHook(array $vars) {
global $smarty;
// If the current template is not 'viewcart', then return
if ($vars['templatefile'] != 'viewcart')
return;
// ... your code here ...
}
Also, note that with hooks like the 'ClientAreaPage' hook, returning an array of keys and values will automatically add them as Smarty variables. So if your hook function ended with return ['currentTime' => time()];, you could then use {$currentTime} in your Smarty template to output its value.

How to call a function that doesn't exist yet in WordPress?

I have a theme that has a plugin called Option Tree integrated in it to create a theme options panel (that plugin allows for a "theme mode" so it isn't installed as a plugin).
The Option Tree plugin allows you to access the saved data in the theme options by using this function:
$data_of_a_single_option = ot_get_option( 'name_of_option_field_to_retrieve', NULL );
I have another plugin that needs to get data saved in the theme option, but the theme (and option tree) is loaded after the plugin is, so calling the function leads to a "function does not exist" error.
Is there a way the plugin can call that function and get the data and be able to store that data in a variable?
I tried using an action like this:
function get_special_data() {
$test = ot_get_option( 'test_field', NULL );
return $test;
var_dump( $test );
}
add_action('after_theme_setup', 'get_special_data', 2);
// then just below in same plugin
$data_from_theme = get_special_data();
Because I read that Option tree is loaded after_Theme_setup with a priority of 1.
By using add_action, I can see the data (var_dump outputs it correctly), but I can't get the data from inside the plugin by calling the get_special_data() function because it sends a "ot_get_option function does not exist" error.
Is there any way to do this? Or am I trying to solve the wrong problem?
Thanks in advance!
I believe you are looking for the plugins_loaded action. That should work as long as the plugin defines that function without some other action required first to load the function.
Also, in your code example $data_from_theme = get_special_data(); is going to execute before the action callback you're defining actually fires.

add_action function in wordpress

well im learning to create a wordpress plugin
i downloaded one and read the codes, and i saw this
i assume 'foo' is the tag where it will add action to..
but what does the array() exactly do?
add_action('foo', array('foo1', 'foo2'));
i looked at http://codex.wordpress.org/Function_Reference/add_action
and there is no clear definition about it ..
Right, the first argument is the tag (to which you'll be adding the action), and the second argument specifies the function to call (i.e. your callback).
The second argument takes in a PHP callback, and as such, accepts a number of valid forms. Check this out for all of them :
PHP Callback Pseudo-Types
The type you've shown above is of type 2. The first element of the array specifies a class, and the second element specifies which function of the class you'd like to call.
So with the example you've given above, what that will do is that, whenever the foo() action is called, it will eventually call foo1->foo2() as well.
The second argument of the add_action function is the function to be called with the hook.
function hello_header() {
echo "I'm in the header!";
}
add_action('wp_head', 'hello_header');
The usage of an array as the second argument is to pass a objects method rather than just a regular function.
Have a read up on the how the call_user_func works. Should provide some more insight.
http://us2.php.net/manual/en/language.pseudo-types.php#language.types.callback(dead link)

Custom hooks in WordPress across plugins

I'm trying to create a hook in one Wordpress plugin that could be used by other plugins. First off, is this even possible? I'm also sending some additional args so this may be 2 questions in one since I've been having trouble finding definitive information on how to do this.
Here is what I've tried so far:
In the plugin that is creating the hook (call it Plugin 1) I added:
do_action('plugin1_hook', $customArg1, $customArg2, $customArg3);
at the point that I want the hook to fire. Then, in a different plugin (Plugin 2), I added:
add_action('plugin1_hook', 'my_function');
and
function my_function($customArg1, $customArg2, $customArg3) { //my code }
This does not seem to be firing the function, however.
My refence for this has been the Wordpress hook comment_post, which is defined by Wordpress as:
do_action('comment_post', $comment_ID, $commentdata['comment_approved']);
and I am using as:
add_action('comment_post', 'my_comment');
function my_comment($comment_id) { //my code }
The above snippet is functioning properly.
I thought I'd post this as an answer as it's a little clearer to explain :)
When you hook a function, but do not specify the number of arguments, WordPress will always pass back one argument.
You won't get errors for something like this;
function do_my_hook($arg1, $arg2 = '', $arg3 = '') {}
add_action('my_hook', 'do_my_hook');
But you will for something like this;
function do_my_hook($arg1, $arg2, $arg3) {}
add_action('my_hook', 'do_my_hook');
WordPress is trying to call do_my_hook(), but it's only passing back one argument. The first example uses PHP default function arguments, so that you can call a function without passing all available arguments, but without error.
The second example will trigger a 'missing argument(s)' PHP error, as all three arguments are required.
The fix?
add_action('my_hook', 'do_my_hook', 10, 3);
The idea behind defining how many arguments your function takes is to avoid errors like these (though technically they are as easily avoided using default arguments!).
My guess is the second plugin is loading after the first one, so the hook has already fired by the time you add an action to it. You might try this for the first plugin:
function my_custom_hook_insertion($arg1, $arg2, $arg3){
do_action('plugin1_hook', $arg1, $arg2, $arg3);
}
add_action('plugins_loaded', 'my_custom_hook_insertion');
That will wait until all plugins are loaded before firing the hook.
Changing my add_action to this fixed the problem:
add_action('plugin1_hook', 'my_function', 10, 3);
The 10 represents the priority, and the 3 represents the number of args that the function will take. I'm not exactly sure how the matching works, since the default is 1, and I use plenty of hooks without specifying 0 args and I've used hooks that pass more than 1 arg but only used 1 arg in my function signature. Source: WordPress Codex: Function Reference/add action
It is working though, so cross plugin hooks are possible.

Categories