Skip to content

Instantly share code, notes, and snippets.

@jotazzu
Last active January 26, 2024 20:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jotazzu/3d74c0c6f989148e7ea79a82b67edfdf to your computer and use it in GitHub Desktop.
Save jotazzu/3d74c0c6f989148e7ea79a82b67edfdf to your computer and use it in GitHub Desktop.
Makes WordPress plugin "Tabify Edit Screen" running again with PHP 8.1 and WP 6.4.2. Three files tabify-edit-screen.php, inc/edit-screen.php and inc/settings-base.php. Replace the original files in plugin folder .../wp-content/plugins/tabify-edit-screen/. Related https://wordpress.org/support/topic/patch-for-php-8-1-and-wp-6-4-2/
<?php
/**
* //jt 26.05.21: WP core function 'remove_meta_box()' sets $metabox = false. Adjusted for compatibility with PHP 7.4.
*/
include 'tabs.php';
class Tabify_Edit_Screen_Edit_Screen {
private $tab_location = 'default';
private $all_metaboxes = array();
private $editscreen_tabs;
private $settings;
/**
* Set hooks for redirection and showing tabs
*
* @since 0.9.0
*/
public function __construct() {
add_filter( 'redirect_post_location', array( $this, 'redirect_add_current_tab' ), 10 );
add_action( 'admin_head', array( $this, 'show_tabs' ), 100 );
}
/**
* When a post is saved let it return to the current selected tab
*
* @param string $location The location the user will be sent to
*
* @return string $location The new location the user will be sent to
*
* @since 0.2.0
*/
public function redirect_add_current_tab( $location ) {
if ( isset( $_REQUEST['tab'] ) ) {
$location = esc_url_raw( add_query_arg( 'tab', $_REQUEST['tab'], $location ) );
}
return $location;
}
/**
* Show the tabs on the edit screens
* This will load the tab class, tab options and actions
* It will also will add the required classes to all the metaboxes
*
* @since 0.1.0
*/
public function show_tabs() {
$screen = get_current_screen();
if ( ! $screen || 'post' != $screen->base ) {
return;
}
$this->tab_location = apply_filters( 'tabify_tab_location', $this->tab_location, 'posttype' );
$post_type = $screen->post_type;
$options = get_option( 'tabify-edit-screen', array() );
if ( ! isset( $options['posttypes'][ $post_type ] ) ) {
return;
}
// Ability to change if the tabs should be showed or not.
$display_tabs = apply_filters( 'tabify_tab_posttype_show', (bool) $options['posttypes'][ $post_type ]['show'] );
// Check if this post type is enabled.
if ( ! $display_tabs ) {
return;
}
add_filter( 'admin_body_class', array( $this, 'add_admin_body_class' ) );
add_action( 'admin_print_footer_scripts', array( $this, 'generate_javascript' ), 9 );
$default_metaboxes = $this->get_default_items( $post_type );
$this->all_metaboxes = $this->get_meta_boxes( $post_type );
// Filter the tabs
$tabs = apply_filters( 'tabify_tab_posttype_tabs', $options['posttypes'][ $post_type ]['tabs'], $post_type );
// Filter empty tabs
$tabs = array_filter( $tabs, array( $this, 'filter_empty_tabs' ) );
// Create Tabify_Edit_Screen_Tabs that is for displaying the UI.
$this->editscreen_tabs = new Tabify_Edit_Screen_Tabs( $tabs );
// Load the tabs on the edit screen.
$this->load_tabs();
$tab_index = 0;
foreach ( $tabs as $tab_index => $tab ) {
$class = 'tabifybox tabifybox-' . $tab_index;
if ( $this->editscreen_tabs->get_current_tab() != $tab_index ) {
$class .= ' tabifybox-hide';
}
if ( isset( $tab['items'] ) ) {
foreach ( $tab['items'] as $metabox_id_fallback => $metabox_id ) {
if ( intval( $metabox_id_fallback ) == 0 && $metabox_id_fallback !== 0 ) {
$metabox_id = $metabox_id_fallback;
}
if ( ! in_array( $metabox_id, $default_metaboxes ) ) {
if ( $metabox_id == 'titlediv' || $metabox_id == 'postdivrich' ) {
add_action( 'tabify_custom_javascript', function() use ( $class, $metabox_id ) {
echo 'jQuery(\'#' . $metabox_id . '\').addClass(\'' . $class . '\');';
} );
}
else {
add_action( 'postbox_classes_' . $post_type . '_' . $metabox_id, function( $args ) use ( $class ) {
array_push( $args, $class );
return $args;
} );
if ( isset( $this->all_metaboxes[ $metabox_id ] ) ) {
unset( $this->all_metaboxes[ $metabox_id ] );
}
}
}
}
}
}
$this->show_unattached_metaboxes( $tab_index );
}
/**
* Show unattached metaboxes
*
* @since 1.0.0
*/
private function show_unattached_metaboxes( $tab_index ) {
$show = apply_filters( 'tabify_unattached_metaboxes_show', true, get_post_type() );
do_action( 'tabify_unattached_metaboxes', $this->all_metaboxes, $show );
// Check if unattached metaboxes should be showed
if ( ! $show || empty( $this->all_metaboxes ) ) {
return;
}
foreach ( $this->all_metaboxes as $metabox_id ) {
$last_index = $tab_index;
$unattached_metaboxes_index = apply_filters( 'tabify_unattached_metaboxes_index', $last_index, get_post_type() );
if ( $unattached_metaboxes_index < 0 || $unattached_metaboxes_index > $last_index ) {
$unattached_metaboxes_index = $last_index;
}
$class = 'tabifybox tabifybox-' . $unattached_metaboxes_index;
if ( $this->editscreen_tabs->get_current_tab() != $unattached_metaboxes_index ) {
$class .= ' tabifybox-hide';
}
add_action( 'postbox_classes_' . get_post_type() . '_' . $metabox_id, function( $args ) use ( $class ) {
array_push( $args, $class );
return $args;
} );
}
}
/**
* Get meta boxes from a post type
*
* @param string $post_type Post type name
*
* @return array $metaboxes List of metaboxes
*
* @since 1.0.0
*/
private function get_meta_boxes( $post_type ) {
global $wp_meta_boxes;
$metaboxes = array();
$default_metaboxes = $this->get_default_items( $post_type );
foreach ( $wp_meta_boxes[ $post_type ] as $priorities ) {
foreach ( $priorities as $priority => $_metaboxes ) {
foreach ( $_metaboxes as $metabox ) {
//jt 26.05.21: WP core function 'remove_meta_box()' sets $metabox = false. Adjusted for compatibility with PHP 7.4.
//if ( ! in_array( $metabox['id'], $default_metaboxes ) ) {
if ( is_array( $metabox ) && ! in_array( $metabox['id'], $default_metaboxes ) ) {
$metaboxes[ $metabox['id'] ] = $metabox['id'];
}
}
}
}
return $metaboxes;
}
/**
* Adds tabity location class
*
* @param string $body List of classes
*
* @return string $body List of classes with addition of the tabify locatin class
*
* @since 0.5.0
*/
public function add_admin_body_class( $body ) {
if ( $this->tab_location ) {
$body .= ' tabify_tab' . $this->tab_location;
}
return $body;
}
/**
* Check where tabs should be loaded and fire the right action and callback for it
*
* @since 0.5.0
*/
private function load_tabs() {
if ( 'after_title' == $this->tab_location ) {
add_action( 'edit_form_after_title', array( $this, 'output_tabs' ), 9 );
}
else { //default
$tabs = $this->submit_button();
$tabs .= $this->editscreen_tabs->get_tabs_with_container();
add_action( 'tabify_custom_javascript', function() use ( $tabs ) {
echo '$(\'#post\').prepend(\'' . addslashes( $tabs ) . '\');';
} );
}
}
/**
* Outputs the tabs
*
* @since 0.5.0
*/
public function output_tabs() {
echo $this->submit_button();
echo $this->editscreen_tabs->get_tabs_with_container();
}
/**
* Add submit button when the submitbox isn't showed on every tab
*
* @return string $text Return custom submit button
*
* @since 0.7.0
*/
private function submit_button() {
$post = get_post();
$default = $this->get_default_items( $post->post_type );
if ( in_array( 'submitdiv', $default ) ) {
return;
}
$post_type_object = get_post_type_object( $post->post_type );
$can_publish = current_user_can( $post_type_object->cap->publish_posts );
if ( ! in_array( $post->post_status, array( 'publish', 'future', 'private' ) ) || 0 == $post->ID ) {
if ( $can_publish ) {
if ( ! empty( $post->post_date_gmt ) && time() < strtotime( $post->post_date_gmt . ' +0000' ) ) {
$text = __( 'Schedule' );
}
else {
$text = __( 'Publish' );
}
}
else {
$text = __( 'Submit for Review' );
}
}
else {
$text = __('Update');
}
return get_submit_button( $text, 'secondary', 'second-submit', false );
}
/**
* Generate the javascript for the edit screen
*
* @since 0.1.0
*/
public function generate_javascript() {
echo '<script type="text/javascript">';
echo 'jQuery(function($) {';
do_action( 'tabify_custom_javascript' );
echo '});';
echo '</script>';
}
/**
* Filter out tabs that don't have any meta boxes to show
*
* @param string $tab Tab information
*
* @since 0.9.6
*/
public function filter_empty_tabs( $tab ) {
if ( isset( $tab['items'] ) ) {
$tab['items'] = array_intersect( $tab['items'], $this->all_metaboxes );
return $tab['items'];
}
return false;
}
/**
* Get list of items that are always displayed
*
* @param string $post_type The post type
*
* @return array List of default items
*
* @since 0.9.6
*/
private function get_default_items( $post_type ) {
if ( ! $this->settings ) {
$this->settings = new Tabify_Edit_Screen_Settings_Posttypes;
}
return $this->settings->get_default_items( $post_type );
}
}
<?php
/**
* //jt 22.01.2024: check if $tab['items'] is a valid array
*/
abstract class Tabify_Edit_Screen_Settings_Base {
private $type;
private $sections;
private $base_url;
private $tabs;
private $options;
protected $items = array();
protected $defaults = array();
/**
* Set properties and load the sections and tabs
*
* @param string $type Where the settings are for
*
* @since 0.4.0
*/
public function __construct( $type ) {
$this->type = $type;
$this->sections = $this->load_sections();
$this->base_url = remove_query_arg( array( 'type', 'section' ), $_SERVER["REQUEST_URI"] );
$this->tabs = new Tabify_Edit_Screen_Tabs( $this->sections, 'vertical', 'subtab' );
}
/**
* Set the items property when needed.
*
* @since 1.0.0
*/
abstract protected function load_items();
/**
* Set properties and load the sections and tabs
*
* @return array The sections
*
* @since 0.4.0
*/
abstract protected function load_sections();
/**
* Get sections
*
* @return array The sections
*
* @since 0.4.0
*/
protected function get_sections() {
return $this->sections;
}
/**
* Get the sections as a tab menu
*
* @since 0.4.0
*/
public function get_sections_menu() {
echo $this->tabs->get_tabs_with_container();
}
/**
* Get all the metaboxes that should always be showed
*
* @return array All the metaboxes id's in an array
*
* @since 0.4.0
*/
public function get_default_items( $id ) {
$defaults = apply_filters( 'tabify_default_metaboxes', $this->defaults, $id, $this->type );
$defaults = apply_filters( 'tabify_default_metaboxes_' . $this->type, $defaults, $id );
return $defaults;
}
/**
* Echo all the items
*
* @since 0.4.0
*/
public function get_sections_box() {
$sections = $this->get_sections();
foreach ( $sections as $section => $label ) {
$this->get_section_box( $section );
}
$this->print_buttons();
$this->print_backbone_template();
}
/**
* Get the HTML for one pacticular section
*
* @param string $section The section name
*
* @since 1.0.0
*/
private function get_section_box( $section ) {
$options = $this->get_options( $this->type );
$default_items = $this->get_default_items( $section );
if ( ! isset( $options[ $section ] ) ) {
$options[ $section ] = array (
'tabs' => array(
array(
'title' => __( 'Others', 'tabify-edit-screen' ),
'items' => array()
)
)
);
}
if ( $section == $this->tabs->get_current_tab() ) {
echo '<div class="tabifybox tabifybox-' . $section . '">';
}
else {
echo '<div class="tabifybox tabifybox-hide tabifybox-' . $section . '" style="display: none;">';
}
$this->get_section_settings( $section );
echo '<div class="tabify_control tabify_control_tabs">';
$tab_id = 0;
$remove = false;
if ( 1 < count( $options[ $section ]['tabs'] ) ) {
$remove = true;
}
foreach ( $options[ $section ]['tabs'] as $tab ) {
$tab['id'] = $tab_id;
if ( ! isset( $tab['permissions'] ) ) {
$tab['permissions'] = array();
}
if ( $tab['title'] == '' ) {
$tab['title'] = __( 'Choose title', 'tabify-edit-screen' );
}
echo '<div class="menu-item-handle tabify_tab">';
$this->get_section_tab_title( $section, $tab['title'], $tab, $remove );
//jt 22.01.2024: check if $tab['items'] is a valid array
if ( !isset($tab['items']) || !is_array($tab['items'])) {
$tab['items'] = array();
}
$this->get_section_box_list( $section, $tab['items'], $tab_id, $default_items );
echo '</div>';
$tab_id++;
}
echo '</div>';
echo '</div>';
}
/**
* Get the settings HTML for one pacticular section
*
* @param string $section The section name
*
* @since 1.0.0
*/
private function get_section_settings( $section ) {
$options = $this->get_options( $this->type );
$checked = '';
if ( isset( $options[ $section ]['show'] ) && $options[ $section ]['show'] == 1 ) {
$checked = ' checked="checked"';
}
echo '<div class="tabifybox-options">';
echo '<p id="show-type">';
_e( 'Show tabs in this post type:', 'tabify-edit-screen' );
echo ' <span class="switch">';
echo '<input type="checkbox" name="tabify[' . $this->type . '][' . $section . '][show]" value="1" class="switch-checkbox" id="switch-' . $this->type . '-' . $section . '"' . $checked . '>';
echo '<label data-tg-off="' . __( 'Off', 'tabify-edit-screen' ) . '" data-tg-on="' . __( 'On', 'tabify-edit-screen' ) . '" for="switch-' . $this->type . '-' . $section . '" class="switch-label"></label>';
echo '</span>';
echo '</p>';
do_action( 'tabify_settings', $section, $this->type );
echo '</div>';
}
/**
* Get the html for one pacticular section
*
* @param string $section The section name
* @param string $title The title
* @param array $tab Tab information
* @param boolean $remove
*
* @since 0.4.0
*/
private function get_section_tab_title( $section, $title, $tab, $remove ) {
echo '<h2><span class="hide-if-no-js">' . $title . '</span><input type="text" name="tabify[' . $this->type . '][' . $section . '][tabs][' . $tab['id'] . '][title]" value="' . esc_html( $title ) . '" class="hide-if-js" /></h2>';
echo '<div class="tabify-title-box">';
do_action( 'tabify_settings_tab_title_box', $tab, $section, $this->type );
echo '<a href="#" class="tabify-remove-tab hide-if-no-js"';
if ( ! $remove ) {
echo ' style="display: none;"';
}
echo '>' . __( 'Remove', 'tabify-edit-screen' ) . '</a>';
echo '</div>';
echo '<div class="clear"></div>';
do_action( 'tabify_settings_tab_title_after', $tab, $section, $this->type );
}
/**
* Get the html for the section sortable list
*
* @param string $section The section name
* @param array $items List of all items in the section
* @param integer $tab_id The id of the tab the list is in
* @param array $default_items List of items that are always shown
*
* @since 1.0.0
*/
private function get_section_box_list( $section, $items, $tab_id, $default_items ) {
$this->load_items();
$options = $this->get_options( $this->type );
echo '<ul>';
if ( isset( $items ) ) {
foreach ( $items as $item_id ) {
if ( empty( $item_id ) ) {
continue;
}
$item_title = '';
if ( isset( $this->items[ $section ][ $item_id ] ) ) {
$item_title = $this->items[ $section ][ $item_id ];
$item_title = apply_filters( 'tabify_items_title', $item_title, $item_id );
$item_title = apply_filters( 'tabify_items_title_' . $item_id , $item_title );
}
$this->list_show_items( $item_id, $item_title, $tab_id, $section, $default_items );
unset( $this->items[ $section ][ $item_id ] );
}
}
if ( ! isset( $options[ $section ] )|| count( $options[ $section ]['tabs'] ) == ( $tab_id + 1 ) ) {
foreach ( $this->items[ $section ] as $item_id => $item_title ) {
if ( empty( $item_id ) ) {
continue;
}
$item_title = apply_filters( 'tabify_items_title', $item_title, $item_id );
$item_title = apply_filters( 'tabify_items_title_' . $item_id , $item_title );
$this->list_show_items( $item_id, $item_title, $tab_id, $section, $default_items );
}
}
echo '</ul>';
}
/**
* Show the items for the sortable list
*
* @param integer $item_id The id of the item in the list
* @param string $item_title The title of the item
* @param integer $tab_id The id of the tab the list is in
* @param string $section The section name
* @param array $default_items List of items that are always shown
*
* @since 0.4.0
*/
protected function list_show_items( $item_id, $item_title, $tab_id, $section, $default_items ) {
$options = $this->get_options( $this->type );
// Most likely a meta box that doesn't exist anymore
if ( empty( $item_title ) ) {
return;
}
$item_title = strip_tags( $item_title );
if ( in_array( $item_id, $default_items ) ) {
echo '<li id="' . $section . '-' . $item_id . '" class="tabifybox-hide">';
}
else {
echo '<li id="' . $section . '-' . $item_id . '">';
}
echo '<div class="menu-item-bar"><div class="menu-item-handle">';
echo '<span class="item-title">' . $item_title . '</span>';
echo '<input type="hidden" name="tabify[' . $this->type . '][' . $section . '][tabs][' . $tab_id . '][items][]" value="' . $item_id . '" />';
echo '<span class="item-order hide-if-js">';
echo '<select name="tabify[' . $this->type . '][' . $section . '][tabs][' . $tab_id . '][items_tab][]">';
if ( isset( $options[ $section ] ) ) {
$amount_tabs = count( $options[ $section ]['tabs'] );
for( $i = 0; $i < $amount_tabs; $i++ ) {
if ( ! isset( $options[ $section ]['tabs'][ $i ] ) ) {
continue;
}
if ( $i == $tab_id ) {
echo '<option value="' . $i . '" selected="selected">' . esc_html( $options[ $section ]['tabs'][ $i ]['title'] ) . '</option>';
}
else {
echo '<option value="' . $i . '">' . esc_html( $options[ $section ]['tabs'][ $i ]['title'] ) . '</option>';
}
}
}
echo '</select>';
echo '</span>';
echo '</div></div></li>';
}
/**
* Display general buttons.
*
* @since 1.0.0
*/
private function print_buttons() {
echo '<p class="submit">';
echo '<input type="submit" id="create_tab" name="create_tab" class="button button-secondary" value="' . __( 'Create a new tab', 'tabify-edit-screen' ) . '" />';
submit_button( '', 'primary', 'submit', false );
echo '</p>';
}
/**
* New tabify tab template
*
* @since 0.4.0
*/
private function print_backbone_template() {
$tab = array(
'id' => '{{ data.tab_id }}',
'permissions' => array()
);
echo '<script type="text/template" id="tmpl-new-tab">';
echo '<div class="menu-item-handle tabify_tab">';
$this->get_section_tab_title( '{{ data.section }}', __( 'Choose title', 'tabify-edit-screen' ), $tab, true );
echo '<ul></ul>';
echo '</div>';
echo '</script>';
}
/**
* Get the options of the current type
*
* @since 0.4.0
*/
protected function get_options( $type = null ) {
if ( ! $this->options ) {
$this->options = get_option( 'tabify-edit-screen', array() );
}
if ( $type && isset( $this->options[ $type ] ) ) {
return $this->options[ $type ];
}
return $this->options;
}
}
<?php
/*
Plugin Name: Tabify Edit Screen
Description: Enables tabs in the edit screen and manage them from the back-end. | JT 25.05.2021+22.01.2024: Modified for compatibility with PHP 8.1.
Version: 1.0.0.1-JT02
Plugin URI: https://codekitchen.eu/products/tabify-edit-screen/
Author: CodeKitchen B.V.
Author URI: https://codekitchen.eu
Donate link: https://codekitchen.eu/donate
Text Domain: tabify-edit-screen
Domain Path: /languages
*/
/**
* jt 25.05.2021: modified file inc/edit-screen.php: check for array type
* jt 22.01.2024: modified this file: set plugin version number to $version = '1.0.0.1-JT02';
* jt 22.01.2024: modified file inc/settings-base.php: check if array entry $tab['items'] exists
*/
/* Copyright 2013-2016 Tabify Edit Screen (email : info@markoheijnen.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Tabify_Edit_Screen {
public $version = '1.0.0.1-JT02';
private $loaded_features = array();
/**
* Construct method to add hooks when on the admin side
*
* @since 0.1.0
*/
public function __construct() {
if ( is_admin() ) {
add_action( 'plugins_loaded', array( $this, 'load' ) );
add_action( 'plugins_loaded', array( $this, 'load_translation' ) );
}
}
/**
* Load functionality
*
* @since 0.9.0
*/
public function load() {
include 'inc/edit-screen.php';
include 'inc/settings-page.php';
new Tabify_Edit_Screen_Edit_Screen();
new Tabify_Edit_Screen_Settings_Page();
add_action( 'admin_init', array( $this, 'load_features' ), 1 );
}
/**
* Load Translations
*
* @since 0.4.0
*/
public function load_translation() {
load_plugin_textdomain( 'tabify-edit-screen', false, basename( dirname( __FILE__ ) ) . '/languages' );
}
/**
* Load features
*
* @since 0.9.0
*/
public function load_features() {
$features = array(
'detection',
'permissions'
);
if ( apply_filters( 'tabify_plugin_support', false ) ) {
$features[] = 'plugin-support';
}
foreach ( $features as $feature ) {
$this->loaded_features[] = $feature;
$class_name = 'Tabify_Edit_Screen_Feature_' . str_replace( '-', '_', $feature );
include 'features/' . $feature . '/' . $feature . '.php';
new $class_name;
}
}
}
$GLOBALS['tabify_edit_screen'] = new Tabify_Edit_Screen();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment