override in child theme a function that is included in functions.php - php

I am trying to override a function included in parent's theme functions.php.
The function I am trying to override lives in functions/widget-fblikebox.php
What I have in my parent's functions.php:
include("functions/widget-fblikebox.php");
functions/widget-fblikebox.php begins with this:
add_action('widgets_init', 'facebook_like_load_widgets');
function facebook_like_load_widgets()
{
register_widget('Facebook_Like_Widget');
}
class Facebook_Like_Widget extends WP_Widget {
I tried following this answer and this is what I did:
I created functions.php in my child theme and I entered there this:
<?php
// Add Facebook Like box Widget
include("functions/widget-fblikebox.php");
?>
I created a file in my child theme folder functions/widget-fblikebox.php that beginnis with this:
add_action( 'init', 'remove_facebook_like_load_widgets' );
function remove_facebook_like_load_widgets() {
remove_action('widgets_init', 'facebook_like_load_widgets' );
add_action( 'init', 'custom_facebook_like_load_widgets' );
}
function custom_facebook_like_load_widgets()
{
register_widget('Facebook_Like_Widget');
}
class Facebook_Like_Widget extends WP_Widget {
but I get an error
Fatal error: Cannot redeclare class Facebook_Like_Widget in /home/electronhe/over9000/www/wp-content/themes/truepixel/functions/widget-fblikebox.php on line 125
I googled this extensively and also tried everything that came to my mind to resolve this. I tried renaming the class in my child theme, using include_once in my child theme functions.php, etc. but to no avail. I you could please shed some light on this that would be greatly, greatly appreciated. The reason I am messing with this in the first place is that I would like to change the localization of the Facebook like box that comes with my theme (from mythemeshop, TruePixel) but it seems that there are no settings for the locale in the DB and the only idea of changing this that came to my mind was to redefine the class and hardcode proper locale in the URL of the iframe talking to FB.

Technically you can't override function declarations. Once it is declared, that's it.
To get around this, you can ask the parent theme author to support function overriding (they would wrap their function declaration in an if statement that checks to see if the function has already been declared) or you can just modify their file manually (but be careful of updating the parent theme.

Related

How to override a non pluggable and non hookable function in a Wordpress parent theme?

My parent theme has some bugs in a function I then want to override in my child theme.
The thing is it is neither pluggable and hookable. It is just defined like so :
// no if(!function_exists())
function parentThemeFunction() {
//some bad coding
}
// no add_action
And that is all. It is not defined in functions.php either, but in "parentTheme/directory/file.php"
So i heard about "runkit_function_redefine" and "runkit_function_rename", but it means i have to implement "runkit" library on my server.
So far, my only option is to edit the original function in the parent theme. With the risk to see my code overrided at the very next theme update.
Any idea?

Calling a Class from a parent Theme issue Wordpress

I have a Wordpress parent theme that my child theme is extending a lot of functionality from. My issue though is that when I want to use or extend a class from the Parent them in my child theme folder structure, I get errors of "class is not defined" or "class not found"
What is the correct way to use classes from the parent theme?
Here is an example of one of the classes:
class MyNewClass extends ReadAndDigestWidget {}
And that class will call more classes inside it that are from the parent theme.
Any help in understanding Wordpress and php more deeply is greatly appreciated!
PHP is not an OOP language by design so the results can be trivial at times. Here is a basic example of how inheritance works in PHP
class ChildTheme extends ParentTheme {
function parentDropDownMenu(){
parent::dropDownMenu();
//do additionall stuff
}
}
theme = new ParentTheme();
$theme->dropDownMenu(); // will call the parent function directly
$theme->parentDropDownMenu(); // will call the function override
Typically I wouldn't even override my parent's class methods in PHP but merely extend the class if I don't have complete control over the parent class. What if an upgrade takes place in wordpress and you override a must needed upgrade?

How to override a widget in a child theme in WordPress?

I want to make a simple modification in a PHP file located here in my parent theme:
wp-content\themes\sailing\inc\widgets\gallery\tpl\base.php
So I created the same folder structure in my child theme and did the modification I need in this file. I also copied/pasted all the PHP files needed to declare this widget.
wp-content\themes\sailing\inc\widgets\widgets.php
wp-content\themes\sailing\inc\widgets\gallery\gallery.php
wp-content\themes\sailing-child\inc\widgets\widgets.php
wp-content\themes\sailing-child\inc\widgets\gallery\gallery.php
What am I missing here ?
WordPress child themes are not working this way. The only files that you can override by using the same path in your child themes are the "basic" files: index.php, page.php, style.css... Mostly the template files.
When it comes to overriding functions or classes in a child theme. You've several ways to handle it:
re-declaring the functions/classes
duplicating the functions/classes
But it depends on how your theme is built and if it's "child theme" ready. Let's have a look with your widget issue.
If you open your widget declaration file within your parent theme, you'll see something like:
class Widget_Name extends WP_Widget {
...
CODE OF THE WIDGET
...
See: https://codex.wordpress.org/Widgets_API
The ideal case is you don't see the above lines first but:
if(!class_exists('Widget_Name')) {
class Widget_Name extends WP_Widget {
...
CODE OF THE WIDGET
...
Which means, you can just copy/past your file and that'll work just fine, you widget will override the parent one and no error will be thrown as the parent widget won't be executed. That's the "child theme ready" theme. Note that it's the same with functions (if(!function_exists('function_name')).
Don't forget to call your file from your child-theme/functions.php file as it won't be called by default.
Like:
require_once('path/to/your/widget_class.php');
Other way, if you don't have a class_exists call is to just duplicate the file, call it with the require_once. You should see an error as you're defining 2 times the same class. PHP won't let that happen, fatal error.
Just rename:
class Widget_Name2 extends WP_Widget {
And somewhere (most of the time at the end) of your file, look for register_widget( and edit the class name:
register_widget( 'Widget_Name2' );
That's not the most handy way as you'll have 2 times the same widget but that does work though.
So since #2Fwebd answer is kinda incomplete (as marked in the comment), here is a more complete answer (just to make it clearer than an answer and its comment. ) I've suggested an edit for his answer, but while it isn't accepted, here is a more complete answer :
WordPress child themes are not working this way. The only files that you can override by using the same path in your child themes are the "basic" files: index.php, page.php, style.css... Mostly the template files.
When it comes to overriding functions or classes in a child theme. You've several ways to handle it:
re-declaring the functions/classes
duplicating the functions/classes
But it depends on how your theme is built and if it's "child theme" ready. Let's have a look with your widget issue.
If you open your widget declaration file within your parent theme, you'll see something like:
class Widget_Name extends WP_Widget {
...
CODE OF THE WIDGET
...
See: https://codex.wordpress.org/Widgets_API
The ideal case is you don't see the above lines first but:
if(!class_exists('Widget_Name')) {
class Widget_Name extends WP_Widget {
...
CODE OF THE WIDGET
...
Which mean, you can just copy/past your file and that'll work just fine, you widget will override the parent one and no error will be thrown as the parent widget won't be executed. That's the "child theme ready" theme. Note that it's the same with functions (if(!function_exists('function_name')).
Don't forget to call your file from your child-theme/functions.php file as it won't be called by default.
Like:
require_once('path/to/your/widget_class.php');
Other way, if you don't have a class_exists call is to just duplicate the file, call it with the require_once. You should see an error as you're defining 2 times the same class. PHP won't let that happen, fatal error.
Just rename:
class Widget_Name2 extends WP_Widget {
Then, change your id_base in your parent::_construct to a unique id (like this :
parent::__construct( 'new_uniq_id', 'name of your widget', ...)
And somewhere (most of the time at the end) of your file, look for register_widget( and edit the class name:
register_widget( 'Widget_Name2' );
That's not the most handy way as you'll have 2 times the same widget but that does work though.
Hope it helps someone.

Wordpress child theme - modifying file of includes folder

I know there are many others who are trying to deal with that problem, but I didn't find an answer.
I'd like to modify a file which is located in the includes folder of a theme.
I need to change the following line:
$html .= '<span class="profile-widget-info-item"><i class="fa fa-star"></i> '.__('Channel','mars').'</span>';
of this file: http://pastebin.com/Qm5r9NeW
How can I do this in my child theme?
Thank you all in advance,
Jake
Copy the file you have pasted to your child theme.
At the very top you will see an if statement that is checking if a function already exists. By placing this file in your child theme, the file will run first and prevent the parent theme from adding the function. You will need to change the name of the widget class so you don't cause a conflict. I've changed the class name from Mars_LoginForm_Widget_Class to Jake_LoginForm_Widget_Class.
if( !defined('ABSPATH') ) exit;
if( !function_exists('Mars_LoginForm_Widget') ){
function Mars_LoginForm_Widget() {
register_widget('Jake_LoginForm_Widget_Class');
}
add_action('widgets_init', 'Mars_LoginForm_Widget');
}
Now you also need to update the class name in the class definition to match the name you've given the class above.
class Jake_LoginForm_Widget_Class extends WP_Widget{
After that just make sure you are including this file in your child theme and then you can freely edit the widget class.

Why do we need function_exists?

Why do we need to check function_exists for user defined functions? It looks ok for internal or core PHP functions but if user know and defined a function himself then why do need to check for its existance?
Below is custom user defined function
if( !function_exists( 'bia_register_menu' ) ) {
function bia_register_menu() {
register_nav_menu('primary-menu', __('Primary Menu'));
}
add_action('init', 'bia_register_menu');
}
Thanks
To make sure you don't register the same function twice, which will cause an error.
You also use if(function_exists('function_name')) when you are calling functions defined in plugins. In case you deactivated your plugin, your site will still be functional.
In dynamically loaded files using autoloaders, the file containing the function or class might not have loaded, so you need to check if it exists
This answer on the Wordpress StackExchange clarifies why you should sometimes use if function_exists around a function declaration in a theme:
The if function_exists approach allows for a child theme to override the function definition by simply defining the function themselves. Since child theme's functions.php files load first, then they will define the function first and the parent's definition will not get loaded.
I suppose it's analogous to the protected keyword in object oriented languages.
However I still wonder whether there would be any need for it around function declarations in plugins.
Imagine that you use you're URL to get the function name and call it.
Then we have the following info:
url: http://mysite.com/my/page/
When converting this url into a function name, you would do something like this:
implode('_', $myUrlPart); //my_page
The output would be "my_page" as string. But if you call this right away and the function does not exist, an error will be shown. This is where the function_exists comes in, take a look:
if (function_exists($function_name)) {
$function_name(); //the function is called
} else {
//call other function to show HTTP 404 page or something like that
}
Does this makes it a little clearer?
Because WordPress is designed so poorly it does not have any proper mechanism for autoloading modules like that, so you need to add safeguards.

Categories