I installed the modal forms module in drupal 7 (https://drupal.org/project/modal_forms) to create a modal window login form. But now, I'm tryig to change its appereance with css but I don't know how to do it.
Anyone knows how to change for example the appereance of input submit button applying one css class?
This is my code:
function get_output_ajax(){
$output = array();
ctools_add_js('ajax-responder');
$output[] = ctools_modal_command_dismiss(t('Login success'));
if (isset($_GET['destination'])) {
$output[] = ctools_ajax_command_redirect($_GET['destination']);
}
elseif(module_exists('login_destination')) {
$destination = login_destination_get_destination('login');
$output[] = ctools_ajax_command_redirect($destination['path']);
}
else {
$output[] = ctools_ajax_command_reload();
}
return $output;
}
function modal_forms_login($js = NULL) {
// Fall back if $js is not set.
if (!$js) {
return drupal_get_form('user_login');
}
$output = get_output_ajax();
}
}
else{
$output = get_output_ajax();
}
print ajax_render($output);
} global $user;
if ($user->uid == 0) {
$output = ctools_modal_form_wrapper('user_login', $form_state);
if (!empty($form_state['executed'])) {
$output = get_output_ajax();
}
}
else{
$output = get_output_ajax();
}
print ajax_render($output);
}
Thanks in advance.
Here my solution, it works for me:
function modal_forms_login($js = NULL) {
// Fall back if $js is not set.
if (!$js) {
return drupal_get_form('user_login');
}
ctools_include('modal');
ctools_include('ajax');
$form_state = array(
// 'title' => t('Log in'),
'ajax' => TRUE,
);
global $user;
if ($user->uid == 0) {
$output = ctools_modal_form_wrapper('user_login', $form_state);
//Necesario para editar el boton del login
$cadena = $output[0]['output'];
$patrón = '/class="form-submit"/';
$sustitución = 'class="form-submit btn btn-primary"';
$output[0]['output'] = preg_replace($patrón, $sustitución, $cadena);
if (!empty($form_state['executed'])) {
$output = get_output_ajax();
}
}
else{
$output = get_output_ajax();
}
print ajax_render($output);
}
Related
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
I am trying to make a function to check if the gform has some entries, has all entries or is empty and return $status according to status.
I have looped through the entries and checked if they are infact shown as an empty string if empty but I only ever get partial or empty.
function set_form_status($form_id) {
$entries = GFAPI::get_entries( $form_id, entry_search_criteria());
$status = '';
if (count($entries) > 0) {
foreach($entries as $entry) {
$keys = array_keys($entry);
foreach($keys as $key) {
if ($entry[$key] === '') {
$status = 'partial';
}
if ($entry[$key] !== '') {
$status = 'filled';
}
}
}
} else {
$status = 'empty';
}
return $status;
}
I'd suggest running it like below and seeing what gets returned. I did remove the entry_search_criteria function but other than that I'm just echoing the key/value.
What I found was even if I'm not using purchasing in a form, there are fields created for it and they are empty. They don't show on the back end entry view even if I select show empty fields. You may have a similar scenario.
function set_form_status($form_id) {
$entries = GFAPI::get_entries( $form_id);
$status = '';
if (count($entries) > 0) {
foreach($entries as $entry) {
$keys = array_keys($entry);
foreach($keys as $key) {
echo $key . ' - ' . $entry[$key] . '<br>';
if ($entry[$key] === '') {
$status = 'partial';
}
if ($entry[$key] !== '') {
$status = 'filled';
}
}
}
} else {
$status = 'empty';
}
return $status;
}
Did some refactoring and debugging together with a co-worker, there was HTML fields on all of the forms and all of them returned an empty string. This is the working version.
function set_form_status($form) {
define('FORM_EMPTY', 0);
define('FORM_PARTIAL', 1);
define('FORM_FILLED', 2);
//checks if the form is my special kind of form
if (is_eligible_form($form)) {
$earlier_entry = get_last_entry($form['id']);
if ($earlier_entry === false) {
return STATUS_EMPTY;
} else {
foreach($form['fields'] as $key => $field) {
if ($earlier_entry[$field->id] === '' && $field->type !== 'html') {
return FORM_PARTIAL;
}
}
}
}
return FORM_FILLED;
}
I'm using this solution to remove sub-categories from the url on my blog posts:
Remove sub category slug from permalink URL of blog post and custom post type in WordPress
add_filter('post_link','custom_post_type_link',10,3);
function custom_post_type_link($permalink, $post, $leavename) {
if (!gettype($post) == 'post') {
return $permalink;
}
switch ($post->post_type) {
case 'post':
//$permalink = get_home_url() . '/' . $post->post_name . '/';
$cats = get_the_category($post->ID);
$subcats = array();
foreach( $cats as $cat ) {
$cat = get_category($cat->term_id);
if($cat->parent) { $subcats[] = sanitize_title($cat->name); }
}
if($subcats) {
foreach($subcats as $subcat) {
$subcat = $subcat.'/';
$permalink = str_replace($subcat, "", $permalink);
}
}
break;
}
return $permalink;}
It's working fine but there is still a little problem with the code.
If I have an URL like this:
www.myblog.com/parentcategory/nameofchildcategory/slugpost
I will get this:
www.myblog.com/parentcategory/slugpost
Which is exactly what I want.
But if I have an URL like this:
www.myblog.com/parentcategory/nameofchildcategory/slugpost-with-nameofchildcategory
I will get this:
www.myblog.com/parentcategory/slugpost-with- (mssing the end of the slug)
...and a 404 page for every link to this article.
So the problem is that when the child category text appears in the slug's post, the code will also remove this part of the URL.
Anyone have an idea on how to solve this?
Thanks in advance!
I have found this solution, adding two functions. I'm not sure the code is optimal but it works perfectly.
add_filter('post_link','custom_post_type_link',10,3);
//function to see if URL ends with...
function endsWith($string, $endString) {
$len = strlen($endString);
if ($len == 0) {
return true;
}
return (substr($string, -$len) === $endString);
}
//function to replace only first match
function str_replace_first($from, $to, $content)
{
$from = '/'.preg_quote($from, '/').'/';
return preg_replace($from, $to, $content, 1);
}
function custom_post_type_link($permalink, $post, $leavename) {
if (!gettype($post) == 'post') {
return $permalink;
}
switch ($post->post_type) {
case 'post':
//$permalink = get_home_url() . '/' . $post->post_name . '/';
$cats = get_the_category($post->ID);
$subcats = array();
foreach( $cats as $cat ) {
$cat = get_category($cat->term_id);
if($cat->parent) { $subcats[] = sanitize_title($cat->name); }
}
if($subcats) {
foreach($subcats as $subcat) {
$subcat = $subcat.'/';
//If URL ends with category name
if(endsWith($permalink,$subcat)){
//And if the category name appears more than once
if(substr_count($permalink,$subcat)>1){
// Remove only first match
$permalink = str_replace_first($subcat, "", $permalink);
}else{
//do nothing
}
}
// If URL does NOT end with category name
else{
$permalink = str_replace($subcat, "", $permalink);
}
}
}
break;
}
return $permalink;}
Try delimiting both ends of the slug, like:
foreach ($subcats as $subcat) {
$permalink = str_replace('/'.$subcat.'/', '/', $permalink);
}
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>
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.