WooCommerce Variations as Radio Buttons - wordpress

is it possible within WooCommerce to change the variations dropdown into radio buttons without having to work with a plugin? I would like to have the following setup on the variations section:
1 liter (10€)
2 liter (20€)
3 Liter (25€)
The price at the bottom should be automatically changed when you select an option.
Thank you

EDIT: added variation_check() and JS variation checking thanks to #ThomasB!
EDIT2: make sure variation_check() also checks for backorder status to allow selection when a product can be backordered.
The best way I managed to get this working is to add radio button markup directly after the select dropdowns and then hide the select dropdowns using CSS. You'll also need some custom JS to trigger the hidden select value changes so that your price will change according to the radio button you select.
Here's how I added the markup:
function variation_radio_buttons($html, $args) {
$args = wp_parse_args(apply_filters('woocommerce_dropdown_variation_attribute_options_args', $args), array(
'options' => false,
'attribute' => false,
'product' => false,
'selected' => false,
'name' => '',
'id' => '',
'class' => '',
'show_option_none' => __('Choose an option', 'woocommerce'),
));
if(false === $args['selected'] && $args['attribute'] && $args['product'] instanceof WC_Product) {
$selected_key = 'attribute_'.sanitize_title($args['attribute']);
$args['selected'] = isset($_REQUEST[$selected_key]) ? wc_clean(wp_unslash($_REQUEST[$selected_key])) : $args['product']->get_variation_default_attribute($args['attribute']);
}
$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$name = $args['name'] ? $args['name'] : 'attribute_'.sanitize_title($attribute);
$id = $args['id'] ? $args['id'] : sanitize_title($attribute);
$class = $args['class'];
$show_option_none = (bool)$args['show_option_none'];
$show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __('Choose an option', 'woocommerce');
if(empty($options) && !empty($product) && !empty($attribute)) {
$attributes = $product->get_variation_attributes();
$options = $attributes[$attribute];
}
$radios = '<div class="variation-radios">';
if(!empty($options)) {
if($product && taxonomy_exists($attribute)) {
$terms = wc_get_product_terms($product->get_id(), $attribute, array(
'fields' => 'all',
));
foreach($terms as $term) {
if(in_array($term->slug, $options, true)) {
$id = $name.'-'.$term->slug;
$radios .= '<input type="radio" id="'.esc_attr($id).'" name="'.esc_attr($name).'" value="'.esc_attr($term->slug).'" '.checked(sanitize_title($args['selected']), $term->slug, false).'><label for="'.esc_attr($id).'">'.esc_html(apply_filters('woocommerce_variation_option_name', $term->name)).'</label>';
}
}
} else {
foreach($options as $option) {
$id = $name.'-'.$option;
$checked = sanitize_title($args['selected']) === $args['selected'] ? checked($args['selected'], sanitize_title($option), false) : checked($args['selected'], $option, false);
$radios .= '<input type="radio" id="'.esc_attr($id).'" name="'.esc_attr($name).'" value="'.esc_attr($option).'" id="'.sanitize_title($option).'" '.$checked.'><label for="'.esc_attr($id).'">'.esc_html(apply_filters('woocommerce_variation_option_name', $option)).'</label>';
}
}
}
$radios .= '</div>';
return $html.$radios;
}
add_filter('woocommerce_dropdown_variation_attribute_options_html', 'variation_radio_buttons', 20, 2);
function variation_check($active, $variation) {
if(!$variation->is_in_stock() && !$variation->backorders_allowed()) {
return false;
}
return $active;
}
add_filter('woocommerce_variation_is_active', 'variation_check', 10, 2);
And here's the JS I used:
$(document).on('change', '.variation-radios input', function() {
$('.variation-radios input:checked').each(function(index, element) {
var $el = $(element);
var thisName = $el.attr('name');
var thisVal = $el.attr('value');
$('select[name="'+thisName+'"]').val(thisVal).trigger('change');
});
});
$(document).on('woocommerce_update_variation_values', function() {
$('.variation-radios input').each(function(index, element) {
var $el = $(element);
var thisName = $el.attr('name');
var thisVal = $el.attr('value');
$el.removeAttr('disabled');
if($('select[name="'+thisName+'"] option[value="'+thisVal+'"]').is(':disabled')) {
$el.prop('disabled', true);
}
});
});

I don't know how to do that without a plugin, but I suggest you drop that requirement, and use the Woocommerce Radio Buttons plugin. This does exactly what you want:

You can use Variation Swatches for WooCommerce plugin. It worked for me.

I extended further the JavaScript part of cfx' answer to include cases of multiple variations. The idea is to hide and show available variations (radio buttons) based on the select inputs.
<script>
jQuery(document).on('change', '.variation-radios input', function() {
jQuery('.variation-radios input:checked').each(function(index, element) {
let el = jQuery(element);
jQuery('select[name="' + el.attr('name') + '"]').val(el.attr('value')).trigger('change');
recreateRadioInputs();
});
});
jQuery(document).on('woocommerce_update_variation_values', function() {
jQuery('.variation-radios input').each(function(index, element) {
let el = jQuery(element);
el.removeAttr('disabled');
if(jQuery('select[name="' + el.attr('name') + '"] option[value="' + el.attr('value') + '"]').is(':disabled')) {
$el.prop('disabled', true);
}
});
});
// recreate readio inputs based on the select inputs
function recreateRadioInputs() {
jQuery('.variation-radios input, .variation-radios label').hide();
jQuery('.variations select').each(function() {
let inputName = jQuery(this).attr('name');
jQuery(this).find('option').each(function() {
let inputVal = jQuery(this).val();
let radioInput = jQuery('.variation-radios input[value="' + inputVal + '"]');
jQuery('.variation-radios label[for="' + radioInput.attr('id') + '"]').show();
radioInput.show();
});
});
}
</script>

Related

Update post terms in each languages by code

who can hellp with this, i need create post from code, by wp_insert_post
function, so what is going on:
I creating post on each existing laguages, then i update all needed fields and i need to set post term depened of current language.
I have terms (shelters) https://prnt.sc/pklSXojB2jZj - i need that post set to current lang shelter while create, but after creating i got - https://prnt.sc/pz2jFEq1OAMP , 2 posts set in one lang terms. Maybe who know whats goes wrong, below i provided 2 functions who do these actions, Thanks in advance:
function add_pet($form_data, $ready_data, $update_meta = false) {
$allLang = pll_languages_list();
if ($allLang) {
$postsArr = array();
foreach ($allLang as $lang) {
//Add new pet
$post_id = wp_insert_post(array(
'post_title' => $form_data['pet_name'],
'post_status' => 'publish',
'post_author' => $form_data['user_id'],
'post_type' => 'pets',
));
//Check if post created, update all needed fields, and update post terms (shelter)
if ($post_id) {
//Get all translation of term
$shelter_id = pll_get_term(intval($form_data['shelter']), $lang);
$update_meta['shelter'] = $shelter_id;
//In this function we update those terms
$update_success = update_pets_fields($post_id, $ready_data, $update_meta);
$postsArr[$lang] = $post_id;
pll_set_post_language($post_id, $lang);
$postDate = get_post($post_id)->post_date;
$unixDate = strtotime($postDate);
update_post_meta($post_id, 'pet_update_date', $unixDate);
}
}
//Save post translation
if ($postsArr) {
pll_save_post_translations($postsArr);
}
//Old code
// foreach ($allLang as $lang) {
// $cat_id = pll_get_term(intval($form_data['kind_of_animal']), $lang);
// $shelter_id = pll_get_term(intval($form_data['shelter']), $lang);
// $post_id = $postsArr[$lang];
// $update_meta['post_category'] = $cat_id;
// $update_meta['shelter'] = $shelter_id;
// $update_success = update_pets_fields($post_id, $ready_data, $update_meta);
// }
}
if (is_wp_error($post_id)) {
wp_send_json_error($post_id->get_error_message());
}
if ($update_success) {
wp_send_json_success('Post was created.');
} else {
wp_send_json_error('Post was not created.');
}
}
And function who update field
/Update pets fields
function update_pets_fields($post_id, $data, $update_meta = false) {
if (!$post_id) return;
//Update post meta data not acf
if (isset($update_meta) && !empty($update_meta['title'])) {
$post_update = array(
'ID' => $post_id,
'post_title' => $update_meta['title']
);
$result = wp_update_post($post_update);
if (is_wp_error($result)) {
wp_send_json_error('Fields was not updated');
}
}
if (isset($update_meta['shelter']) && !empty($update_meta['shelter']) && intval($update_meta['shelter'])) {
wp_remove_object_terms($post_id, 'uncategorized', 'sholters');
$shelter_id = intval($update_meta['shelter']);
wp_set_post_terms($post_id, array($shelter_id), 'sholters');
if (is_wp_error($result)) {
wp_send_json_error('Term not updated');
}
}
if (isset($update_meta['post_category']) && !empty($update_meta['post_category']) && intval($update_meta['post_category'])) {
wp_remove_object_terms($post_id, 'uncategorized', 'category');
wp_set_post_categories($post_id, intval($update_meta['post_category']));
if (is_wp_error($result)) {
wp_send_json_error('Category not updated');
}
}
if (isset($update_meta['thumbnail']) && !empty($update_meta['thumbnail']) && intval($update_meta['thumbnail'])) {
set_post_thumbnail($post_id, intval($update_meta['thumbnail']));
}
if (is_null($data)) {
wp_send_json_error('No data.');
}
foreach ($data as $field) {
if ($field[3] === 'where_is') {
$field_array['field_62169d3cffb5b'] = array(
$field[2] => $field[1],
);
} else {
$field_array = array(
$field[2] => $field[1],
);
}
if (!empty($field[1])) {
$result = update_field('field_621696a7ffb4e', $field_array, $post_id);
}
}
if ($result) {
return false;
} else {
return true;
}
}
I try update it in diferent variants but it does't work, i check ids that come in args all ids is right and all posts ids is right.But on at the exit we got 2 posts in 1 term

How can I override the price string for WooCommerce Subscriptions only for a specific product?

I have this code and I would like to apply it only for a specific product. What would be those extra lines of code for that? Thank you!
add_filter( 'woocommerce_subscriptions_product_price_string_inclusions', 'wpd_override_subscription_price_string', 10, 2 );
function wpd_override_subscription_price_string( $include, $product ) {
/*
'tax_calculation' => get_option( 'woocommerce_tax_display_shop' ),
'subscription_price' => true,
'subscription_period' => true,
'subscription_length' => true,
'sign_up_fee' => true,
'trial_length' => true,
*/
$include['subscription_period'] = false;
$include['sign_up_fee'] = false;
$include['trial_length'] = false;
return $include;
}
If you want to limit by product ID you can do like this
function wpd_override_subscription_price_string( $include, $product ) {
if($product->get_id() !== '1234'){
return $include;
}
$include['subscription_period'] = false;
$include['sign_up_fee'] = false;
$include['trial_length'] = false;
return $include;
}
Cahnge 1234 to your product ID

Add "insert button" on toolbar tinymce editor

I want to add an "insert button" on my toolbar tinymce editor.
An example of what I want :
An example of what I want
With the toolbar button, I would like to create a button in my editor and change its style. (Like the gutenberg editor does)
gutenberg editor
To use the tinymce editor, I have this code :
function wpc_boutons_tinymce($buttons) {
$buttons[] = 'underline';
$buttons[] = 'fontselect';
$buttons[] = 'fontsizeselect';
$buttons[] = 'edit-block';
return $buttons;
}
add_filter("mce_buttons_3", "wpc_boutons_tinymce");
$content = '';
$editor_id = 'mycustomeditor';
$settings = array(
'wpautop' => false,
'media_buttons' => false,
'quicktags' => array(
'buttons' => 'strong,em,del,ul,ol,li,block,close'
),
);
wp_editor( $content, $editor_id, $settings );
I didn't find how to do, can you help me ?
Here is my implemented code Follow the step
Paste the code in your theme functions.php
add_action( 'init', 'wptuts_buttons' );
function wptuts_buttons() {
add_filter( "mce_external_plugins", "wptuts_add_buttons" );
add_filter( 'mce_buttons', 'wptuts_register_buttons' );
}
function wptuts_add_buttons( $plugin_array ) {
$plugin_array['wptuts'] = get_template_directory_uri() . '/wptuts-editor-buttons/wptuts-plugin.js';
return $plugin_array;
}
function wptuts_register_buttons( $buttons ) {
array_push( $buttons, 'dropcap', 'showrecent' ); // dropcap', 'recentposts
return $buttons;
}
require( 'wptuts-editor-buttons/wptuts.php' );
Create a folder in your theme root file named wptuts-editor-buttons
Then create a file in wptuts-editor-buttons named wptuts.php and paste the code
<?php
add_shortcode( 'recent-posts', 'wptuts_recent_posts' );
function wptuts_recent_posts( $atts ) {
extract( shortcode_atts( array(
'numbers' => '5',
), $atts ) );
$rposts = new WP_Query( array( 'posts_per_page' => $numbers, 'orderby' => 'date' ) );
if ( $rposts->have_posts() ) {
$html = '<h3>Recent Posts</h3><ul class="recent-posts">';
while( $rposts->have_posts() ) {
$rposts->the_post();
$html .= sprintf(
'<li>%s</li>',
get_permalink($rposts->post->ID),
get_the_title(),
get_the_title()
);
}
$html .= '</ul>';
}
wp_reset_query();
return $html;
}
Also, You need to create a js file in wptuts-editor-buttons > wptuts-plugin.js and paste the code
(function() {
tinymce.create('tinymce.plugins.Wptuts', {
init : function(ed, url) {
ed.addButton('dropcap', {
title : 'DropCap',
cmd : 'dropcap',
image : url + '/dropcap.jpg'
});
ed.addButton('showrecent', {
title : 'Add recent posts shortcode',
cmd : 'showrecent',
image : url + '/images.jpg'
});
ed.addCommand('dropcap', function() {
var selected_text = ed.selection.getContent();
var return_text = '';
return_text = '<span class="dropcap">' + selected_text + '</span>';
ed.execCommand('mceInsertContent', 0, return_text);
});
ed.addCommand('showrecent', function() {
var number = prompt("How many posts you want to show ? "),
shortcode;
if (number !== null) {
number = parseInt(number);
if (number > 0 && number <= 20) {
shortcode = '[recent-post number="' + number + '"/]';
ed.execCommand('mceInsertContent', 0, shortcode);
}
else {
alert("The number value is invalid. It should be from 0 to 20.");
}
}
});
},
// ... Hidden code
});
// Register plugin
tinymce.PluginManager.add( 'wptuts', tinymce.plugins.Wptuts );
})();
Whole the Solution I followed the article
https://code.tutsplus.com/tutorials/guide-to-creating-your-own-wordpress-editor-buttons--wp-30182

Wordpress wp_footer not loading

I'm using a theme which i've used before and the wp_footer is loading fine in there. But in the new site the wp_footer is not loading can't find the solution by myself! Is there someone who could help me?
it's in the right place before the </body> tag.
<footer>
<div class="container">
<div class="footermenu">
<?php
$footer = array(
'theme_location' => '',
'menu' => 'footer',
'container' => 'div',
'container_class' => '',
'container_id' => '',
'menu_class' => 'menu',
'menu_id' => '',
'echo' => true,
'fallback_cb' => 'wp_page_menu',
'before' => '',
'after' => '',
'link_before' => '',
'link_after' => '',
'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
'depth' => 0,
'walker' => ''
);
wp_nav_menu($footer);
?>
<img src="http://www.web-lynx.nl/vandervalk/wp-content/uploads/2014/07/PBRB_logo-trans-300x41.png" width="300px" height="41px" class="logofooter"/>
<div class="clear"></div>
</div>
<h2><?php _e("ONZE SOCIAL MEDIA","vertaling"); ?></h2>
<div class="one_third">
<span data-icon="" class="footersocial"></span>
</div>
<div class="one_third">
<span data-icon="" class="footersocial"></span>
</div>
<div class="one_third">
<span data-icon="" class="footersocial"></span>
</div>
<div class="clear"></div>
<br>
Copyright © Van der Valk
</div>
</footer><!-- footer -->
</div><!-- site-wrapper -->
<script type="text/javascript">
jQuery('.googlemaps').click(function(){
if(jQuery('.gmap').css('display') == 'none'){
jQuery('.gmap').slideDown();
}else{
jQuery('.gmap').slideUp();
}
});
jQuery('.firstphone').click(function(){
jQuery('.otherphonenumbers').slideDown();
});
</script>
<script>
/*!
* classie v1.0.0
* class helper functions
* from bonzo https://github.com/ded/bonzo
* MIT license
*
* classie.has( elem, 'my-class' ) -> true/false
* classie.add( elem, 'my-new-class' )
* classie.remove( elem, 'my-unwanted-class' )
* classie.toggle( elem, 'my-class' )
*/
/*jshint browser: true, strict: true, undef: true, unused: true */
/*global define: false */
( function( window ) {
'use strict';
// class helper functions from bonzo https://github.com/ded/bonzo
function classReg( className ) {
return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
}
// classList support for class management
// altho to be fair, the api sucks because it won't accept multiple classes at once
var hasClass, addClass, removeClass;
if ( 'classList' in document.documentElement ) {
hasClass = function( elem, c ) {
return elem.classList.contains( c );
};
addClass = function( elem, c ) {
elem.classList.add( c );
};
removeClass = function( elem, c ) {
elem.classList.remove( c );
};
}
else {
hasClass = function( elem, c ) {
return classReg( c ).test( elem.className );
};
addClass = function( elem, c ) {
if ( !hasClass( elem, c ) ) {
elem.className = elem.className + ' ' + c;
}
};
removeClass = function( elem, c ) {
elem.className = elem.className.replace( classReg( c ), ' ' );
};
}
function toggleClass( elem, c ) {
var fn = hasClass( elem, c ) ? removeClass : addClass;
fn( elem, c );
}
var classie = {
// full names
hasClass: hasClass,
addClass: addClass,
removeClass: removeClass,
toggleClass: toggleClass,
// short names
has: hasClass,
add: addClass,
remove: removeClass,
toggle: toggleClass
};
// transport
if ( typeof define === 'function' && define.amd ) {
// AMD
define( classie );
} else {
// browser global
window.classie = classie;
}
})( window );
(function( window ){
var body = document.body,
mask = document.createElement("div"),
togglePushLeft = document.querySelector( ".toggle-push-left" ),
pushMenuLeft = document.querySelector( ".push-menu-left" ),
activeNav
;
mask.className = "mask";
/* push menu left */
togglePushLeft.addEventListener( "click", function(){
classie.add( body, "pml-open" );
document.body.appendChild(mask);
activeNav = "pml-open";
} );
/* hide active menu if mask is clicked */
mask.addEventListener( "click", function(){
classie.remove( body, activeNav );
activeNav = "";
document.body.removeChild(mask);
} );
})( window );
</script>
<?php wp_footer(); ?>
</body>
</html>
Think it has something to do with this bug!
wp-content/themes/ParadiseHotel/st-framework/admin/page-builder/page-builder.php:50 - Undefined variable: ajax_nonce
this variable is set like this
<?php
#-------------------------------------------------------------
# Smooth Theme Framework Version
#-------------------------------------------------------------
function st_framework_version_init(){
$st_framework_version = '1.0';
if(get_option('st_framework_version_init') != $st_framework_version){
update_option('st_framework_version',$st_framework_version);
}
}
add_action('init','st_framework_version_init',10);
#-------------------------------------------------------------
# Define Admin Path and URL
#-------------------------------------------------------------
define('ST_ADMIN_PATH',dirname(__FILE__));
define('ST_ADMIN_URL',ST_URL.'admin');
define('ST_PAGE_TITLE',ST_THEME_NAME.' Settings Page'); // Theme Option Title
define('ST_MENU_TITLE',ST_THEME_NAME); // Theme Option Menu Title
define('ST_PAGE_SLUG','smooththemes'); // Theme Option URL Slug
#-------------------------------------------------------------
# Load the required Framework Files
#-------------------------------------------------------------
// kiểm tra tính hợp lệ của ajax
$current_user = wp_get_current_user();
$ajax_nonce = wp_create_nonce($current_user->ID);
//check_ajax_referer( $current_user->ID, 'ajax_nonce' );
if(is_admin()){
add_action( 'wp_ajax_smooththemes_save_option_action', 'smooththemes_save_option_action' );
function smooththemes_save_option_action() {
$st_default_lang_code = get_bloginfo('language'); // DO NOT REMOVE
if(isset($_POST['save']) && $_POST['save']=='Y'){
$data = array();
foreach( $_POST as $key => $arr ){
if(strpos($key, ST_SETTINGS_OPTION)!==false){
$k = str_replace(ST_SETTINGS_OPTION.'_', '', $key);
$data[$k]= $arr;
}
}
if(st_is_wpml()){
// ICL_LANGUAGE_CODE
// echo var_dump($st_default_lang_code,ICL_LANGUAGE_CODE);
if($st_default_lang_code==ICL_LANGUAGE_CODE || ICL_LANGUAGE_CODE=='' || strpos($st_default_lang_code,ICL_LANGUAGE_CODE)!==false){
// update_option(ST_FRAMEWORK_SETTINGS_OPTION,$_POST[ST_FRAMEWORK_SETTINGS_OPTION]);
update_option(ST_SETTINGS_OPTION,$data);
}
update_option(ST_SETTINGS_OPTION.'_'.ICL_LANGUAGE_CODE, $data);
do_action('st_save_options',$data);
}else{
echo ST_SETTINGS_OPTION;
update_option(ST_SETTINGS_OPTION,$data);
do_action('st_save_options', $data );
}
flush_rewrite_rules();
}
echo 1;
die();
}
// for media
function st_image_attachment_fields_to_edit($form_fields, $post){
$form_fields["st_custom"]["label"] = '';
$form_fields["st_custom"]["input"] = "html";
$image_attributes = wp_get_attachment_image_src( $post->ID ,'medium' ); // returns an array
$form_fields["st_custom"]["html"] = '
<input type="hidden" class="st_attach_btn" data-src = "'.$image_attributes[0].'" post_id ="'.$post->ID.'" >
';
return $form_fields;
}
add_filter("attachment_fields_to_edit", "st_image_attachment_fields_to_edit", null, 99);
//----------------Show image size in mediabox-------------------
function st_insert_custom_image_sizes( $sizes ) {
// get the custom image sizes
global $_wp_additional_image_sizes;
// if there are none, just return the built-in sizes
if ( empty( $_wp_additional_image_sizes ) )
return $sizes;
// add all the custom sizes to the built-in sizes
foreach ( $_wp_additional_image_sizes as $id => $data ) {
// take the size ID (e.g., 'my-name'), replace hyphens with spaces,
// and capitalise the first letter of each word
if ( !isset($sizes[$id]) )
$sizes[$id] = ucfirst( str_replace( '-', ' ', $id ) );
}
return $sizes;
}
add_filter( 'image_size_names_choose', 'st_insert_custom_image_sizes' );
include(ST_ADMIN_PATH.'/editor/editor.php');
include(ST_ADMIN_PATH.'/admin-users.php');
include(ST_ADMIN_PATH.'/admin-functions.php');
include(ST_ADMIN_PATH.'/admin-menu.php');
include(ST_ADMIN_PATH.'/admin-scripts.php');
include(ST_ADMIN_PATH.'/ajax-media.php');
// include(ST_ADMIN_PATH.'/ajax-slidebar-generator.php');
//
if(file_exists(ST_ADMIN_PATH.'/page-builder/page-builder.php')){
include(ST_ADMIN_PATH.'/page-builder/page-builder.php');
}
if(file_exists(ST_ADMIN_PATH.'/review-control/review.php')){
include(ST_ADMIN_PATH.'/review-control/review.php');
}
include(ST_ADMIN_PATH.'/admin-meta-box.php');
include(ST_DIR.'/settings/meta-box-settings.php');
include(ST_ADMIN_PATH.'/admin-post-type.php');
include(ST_ADMIN_DIR.'admin-customize.php');
include(ST_ADMIN_DIR.'post-type-meta/event.php');
include(ST_ADMIN_DIR.'post-type-meta/room.php');
include(ST_ADMIN_DIR.'post-type-meta/gallery.php');
}

Extending WP_List_Table / handling checkbox options in plugin administration

I'm working on a WordPress plugin, and part of that plugin requires extending WP_List_Table and storing any of the items which are checked in that table to an option. I've managed to figure out how to properly setup and display the required table, but how do I handle storing the checked options?
Here's what I've got so far...
class TDBar_List_Table extends WP_List_Table {
// Reference parent constructor
function __construct() {
global $status, $page;
// Set defaults
parent::__construct( array(
'singular' => 'theme',
'plural' => 'themes',
'ajax' => false
));
}
// Set table classes
function get_table_classes() {
return array('widefat', 'wp-list-table', 'themes');
}
// Setup default column
function column_default($item, $column_name) {
switch($column_name) {
case 'Title':
case 'URI':
case'Description':
return $item[$column_name];
default:
return print_r($item, true);
}
}
// Displaying checkboxes!
function column_cb($item) {
return sprintf(
'<input type="checkbox" name="%1$s" id="%2$s" value="checked" />',
//$this->_args['singular'],
$item['Stylesheet'] . '_status',
$item['Stylesheet'] . '_status'
);
}
// Display theme title
function column_title($item) {
return sprintf(
'<strong>%1$s</strong>',
$item['Title']
);
}
// Display theme preview
function column_preview($item) {
if (file_exists(get_theme_root() . '/' . $item['Stylesheet'] . '/screenshot.png')) {
$preview = get_theme_root_uri() . '/' . $item['Stylesheet'] . '/screenshot.png';
} else {
$preview = '';
}
return sprintf(
'<img src="%3$s" style="width: 150px;" />',
$preview,
$item['Title'],
$preview
);
}
// Display theme description
function column_description($item) {
if (isset($item['Version'])) {
$version = 'Version ' . $item['Version'];
if (isset($item['Author']) || isset($item['URI']))
$version .= ' | ';
} else {
$version = '';
}
if (isset($item['Author'])) {
$author = 'By ' . $item['Author'];
if (isset($item['URI']))
$author .= ' | ';
} else {
$author = '';
}
if (isset($item['URI'])) {
$uri = $item['URI'];
} else {
$uri = '';
}
return sprintf(
'<div class="theme-description"><p>%1$s</p></div><div class="second theme-version-author-uri">%2$s%3$s%4$s',
$item['Description'],
$version,
$author,
$uri
);
}
// Setup columns
function get_columns() {
$columns = array(
'cb' => '<input type="checkbox" />',
'title' => 'Theme',
'preview' => 'Preview',
'description' => 'Description'
);
return $columns;
}
// Make title column sortable
function get_sortable_columns() {
$sortable_columns = array(
'title' => array('Title', true)
);
return $sortable_columns;
}
// Setup bulk actions
function get_bulk_actions() {
$actions = array(
'update' => 'Update'
);
return $actions;
}
// Handle bulk actions
function process_bulk_action() {
// Define our data source
if (defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE == true) {
$themes = get_allowed_themes();
} else {
$themes = get_themes();
}
if ('update' === $this->current_action()) {
foreach ($themes as $theme) {
if ($theme['Stylesheet'] . '_status' == 'checked') {
// Do stuff - here's the problem
}
}
}
}
// Handle data preparation
function prepare_items() {
// How many records per page?
$per_page = 10;
// Define column headers
$columns = $this->get_columns();
$hidden = array();
$sortable = $this->get_sortable_columns();
// Build the array
$this->_column_headers = array($columns, $hidden, $sortable);
// Pass off bulk action
$this->process_bulk_action();
// Define our data source
if (defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE == true) {
$themes = get_allowed_themes();
} else {
$themes = get_themes();
}
// Handle sorting
function usort_reorder($a,$b) {
$orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : 'Title';
$order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'asc';
$result = strcmp($a[$orderby], $b[$orderby]);
return ($order === 'asc') ? $result : -$result;
}
usort($themes, 'usort_reorder');
//MAIN STUFF HERE
//for ($i = 0; i < count($themes); $i++) {
//}
// Figure out the current page and how many items there are
$current_page = $this->get_pagenum();
$total_items = count($themes);
// Only show the current page
$themes = array_slice($themes,(($current_page-1)*$per_page),$per_page);
// Display sorted data
$this->items = $themes;
// Register pagination options
$this->set_pagination_args( array(
'total_items' => $total_items,
'per_page' => $per_page,
'total_pages' => ceil($total_items/$per_page)
));
}
}
Problem is, I can't get it to save properly. I select the rows I want, hit save and it just resets.
I assume you are talking about the checkboxes in your table listing, so this will be how to process bulk actions.
All you need to do is add two new methods to your class and initialize it in the prepare_items method. I use the code below in one of my plugins to delete or export, but you can just as easily run an update.
/**
* Define our bulk actions
*
* #since 1.2
* #returns array() $actions Bulk actions
*/
function get_bulk_actions() {
$actions = array(
'delete' => __( 'Delete' , 'visual-form-builder'),
'export-all' => __( 'Export All' , 'visual-form-builder'),
'export-selected' => __( 'Export Selected' , 'visual-form-builder')
);
return $actions;
}
/**
* Process our bulk actions
*
* #since 1.2
*/
function process_bulk_action() {
$entry_id = ( is_array( $_REQUEST['entry'] ) ) ? $_REQUEST['entry'] : array( $_REQUEST['entry'] );
if ( 'delete' === $this->current_action() ) {
global $wpdb;
foreach ( $entry_id as $id ) {
$id = absint( $id );
$wpdb->query( "DELETE FROM $this->entries_table_name WHERE entries_id = $id" );
}
}
}
Now, call this method inside prepare_items() like so:
function prepare_items() {
//Do other stuff in here
/* Handle our bulk actions */
$this->process_bulk_action();
}
There's a fantastic helper plugin called Custom List Table Example that makes figuring out the WP_List_Table class much easier.

Resources