This theme I was handed from another dev company is littered with add_action/filter( 'hook/filter', create_function( '', 'return blah('blah')' );
We will be moving this site to a server running php 7.2
.
I am wondering what's the appropriate method to remove these actions and filters. Or can I simply just copy and paste the /path/to/file in the child directory and know that this will be overwritten?
Here's an example
if ( ! function_exists( 'ot_register_theme_options_page' ) ) {
function ot_register_theme_options_page() {
/* get the settings array */
$get_settings = _ut_theme_options();
/* sections array */
$sections = isset( $get_settings['sections'] ) ? $get_settings['sections'] : [];
/* settings array */
$settings = isset( $get_settings['settings'] ) ? $get_settings['settings'] : [];
/* build the Theme Options */
if ( function_exists( 'ot_register_settings' ) && OT_USE_THEME_OPTIONS ) {
ot_register_settings(
[
[
'id' => 'option_tree',
'pages' => [
[
'id' => 'ot_theme_options',
'parent_slug' => apply_filters( 'ot_theme_options_parent_slug', 'unite-welcome-page' ),
'page_title' => apply_filters( 'ot_theme_options_page_title', __( 'Theme Options', 'option-tree' ) ),
'menu_title' => apply_filters( 'ot_theme_options_menu_title', __( 'Theme Options', 'option-tree' ) ),
'capability' => $caps = apply_filters( 'ot_theme_options_capability', 'edit_theme_options' ),
'menu_slug' => apply_filters( 'ot_theme_options_menu_slug', 'ut_theme_options' ),
'icon_url' => apply_filters( 'ot_theme_options_icon_url', null ),
'position' => apply_filters( 'ot_theme_options_position', null ),
'updated_message' => apply_filters( 'ot_theme_options_updated_message', __( 'Theme Options updated.', 'option-tree' ) ),
'reset_message' => apply_filters( 'ot_theme_options_reset_message', __( 'Theme Options reset.', 'option-tree' ) ),
'button_text' => apply_filters( 'ot_theme_options_button_text', __( 'Save Changes', 'option-tree' ) ),
'screen_icon' => 'themes',
'sections' => $sections,
'settings' => $settings,
],
],
],
]
);
// Filters the options.php to add the minimum user capabilities.
add_filter( 'option_page_capability_option_tree', create_function( '$caps', "return '$caps';" ), 999 );
}
}
}
I'm aware the appropriate add_filter
would come out to being add_filter( 'option_page_capability_option_tree', function($caps) { return $caps; }, 999);
This theme I was handed from another dev company is littered with add_action/filter( 'hook/filter', create_function( '', 'return blah('blah')' );
We will be moving this site to a server running php 7.2
.
I am wondering what's the appropriate method to remove these actions and filters. Or can I simply just copy and paste the /path/to/file in the child directory and know that this will be overwritten?
Here's an example
if ( ! function_exists( 'ot_register_theme_options_page' ) ) {
function ot_register_theme_options_page() {
/* get the settings array */
$get_settings = _ut_theme_options();
/* sections array */
$sections = isset( $get_settings['sections'] ) ? $get_settings['sections'] : [];
/* settings array */
$settings = isset( $get_settings['settings'] ) ? $get_settings['settings'] : [];
/* build the Theme Options */
if ( function_exists( 'ot_register_settings' ) && OT_USE_THEME_OPTIONS ) {
ot_register_settings(
[
[
'id' => 'option_tree',
'pages' => [
[
'id' => 'ot_theme_options',
'parent_slug' => apply_filters( 'ot_theme_options_parent_slug', 'unite-welcome-page' ),
'page_title' => apply_filters( 'ot_theme_options_page_title', __( 'Theme Options', 'option-tree' ) ),
'menu_title' => apply_filters( 'ot_theme_options_menu_title', __( 'Theme Options', 'option-tree' ) ),
'capability' => $caps = apply_filters( 'ot_theme_options_capability', 'edit_theme_options' ),
'menu_slug' => apply_filters( 'ot_theme_options_menu_slug', 'ut_theme_options' ),
'icon_url' => apply_filters( 'ot_theme_options_icon_url', null ),
'position' => apply_filters( 'ot_theme_options_position', null ),
'updated_message' => apply_filters( 'ot_theme_options_updated_message', __( 'Theme Options updated.', 'option-tree' ) ),
'reset_message' => apply_filters( 'ot_theme_options_reset_message', __( 'Theme Options reset.', 'option-tree' ) ),
'button_text' => apply_filters( 'ot_theme_options_button_text', __( 'Save Changes', 'option-tree' ) ),
'screen_icon' => 'themes',
'sections' => $sections,
'settings' => $settings,
],
],
],
]
);
// Filters the options.php to add the minimum user capabilities.
add_filter( 'option_page_capability_option_tree', create_function( '$caps', "return '$caps';" ), 999 );
}
}
}
I'm aware the appropriate add_filter
would come out to being add_filter( 'option_page_capability_option_tree', function($caps) { return $caps; }, 999);
2 Answers
Reset to default 1In order to remove the hooks and filters, we need to be able to get a reference to the callable that was added, but in this case, create_function
was used, so that's extremely difficult. It's also the reason you're getting deprecation notices. Sadly the only way to fix those deprecations is to change the parent theme to fix it.
Fixing The Deprecations
The PHP docs say that create_function
works like this:
string create_function ( string $args , string $code )
Creates an anonymous function from the parameters passed, and returns a unique name for it.
And of note, create_function
is deprecated in PHP 7.2
So this:
create_function( '$a', 'return $a + 1;' )
Becomes:
function( $a ) {
return $a + 1;
}
Or even
function add_one( $a ) {
return $a + 1;
}
This should eliminate the create_function
calls, and turn the anonymous functions into normal calls that can be removed in a child theme
Removing The Hooks and Filters
Now that we've done that, we can now remove and replace them in the child theme.
To do this, we need 2 things:
- to run the removal code after they were added
- to be able to unhook the filters/actions
Putting your replacement in is easy, just use add_filter
and add_action
, but that adds your version, we need to remove the parent themes version.
Lets assume that this code is in the parent theme:
add_filter('wp_add_numbers_together' 'add_one' );
And that we want to replace it with a multiply_by_two
function. First lets do this on the init
hook:
function nickm_remove_parent_hooks() {
//
}
add_action('init', 'nickm_remove_parent_hooks' );
Then call remove_filter and
add_filter`:
function nickm_remove_parent_hooks() {
remove_filter( 'wp_add_numbers_together' 'add_one' );
}
add_action( 'init', 'nickm_remove_parent_hooks' );
add_action( 'wp_add_numbers_together', 'multiply_by_two' );
Keep in mind that child themes let you override templates, but functions.php
is not a template, and child themes don't change how include
or require
work. A child themes functions.php
is loaded first, but otherwise, they're similar to plugins.
And Finally
You shouldn't be registering post types, roles, capabilities, and taxonomies in a theme, it's a big red flag and creates lock in, preventing data portability. These things are supposed to be in plugins, not themes
So turns out taking the following, and just removing if ( ! function_exists( 'ot_register_theme_options_page' ) ) { }
and adjusting the filter will take priority over the parent theme.
if ( ! function_exists( 'ot_register_theme_options_page' ) ) {
function ot_register_theme_options_page() {
/* get the settings array */
$get_settings = _ut_theme_options();
/* sections array */
$sections = isset( $get_settings['sections'] ) ? $get_settings['sections'] : [];
/* settings array */
$settings = isset( $get_settings['settings'] ) ? $get_settings['settings'] : [];
/* build the Theme Options */
if ( function_exists( 'ot_register_settings' ) && OT_USE_THEME_OPTIONS ) {
ot_register_settings(
[
[
'id' => 'option_tree',
'pages' => [
[
'id' => 'ot_theme_options',
'parent_slug' => apply_filters( 'ot_theme_options_parent_slug', 'unite-welcome-page' ),
'page_title' => apply_filters( 'ot_theme_options_page_title', __( 'Theme Options', 'option-tree' ) ),
'menu_title' => apply_filters( 'ot_theme_options_menu_title', __( 'Theme Options', 'option-tree' ) ),
'capability' => $caps = apply_filters( 'ot_theme_options_capability', 'edit_theme_options' ),
'menu_slug' => apply_filters( 'ot_theme_options_menu_slug', 'ut_theme_options' ),
'icon_url' => apply_filters( 'ot_theme_options_icon_url', null ),
'position' => apply_filters( 'ot_theme_options_position', null ),
'updated_message' => apply_filters( 'ot_theme_options_updated_message', __( 'Theme Options updated.', 'option-tree' ) ),
'reset_message' => apply_filters( 'ot_theme_options_reset_message', __( 'Theme Options reset.', 'option-tree' ) ),
'button_text' => apply_filters( 'ot_theme_options_button_text', __( 'Save Changes', 'option-tree' ) ),
'screen_icon' => 'themes',
'sections' => $sections,
'settings' => $settings,
],
],
],
]
);
// Filters the options.php to add the minimum user capabilities.
add_filter( 'option_page_capability_option_tree', create_function( '$caps', "return '$caps';" ), 999 );
}
}
}
create_function
is going to be removed in a future PHP version, that part has nothing to do with WordPress, see stackoverflow/questions/48161526/… – Tom J Nowell ♦ Commented Dec 21, 2018 at 0:57