WordPress Plugin Function - wordpress

I had a developer write this plugin for me to add functionality to import bulk pricing to products through WP All Import, a while back. He has not been getting back to me regarding this. I had to delete the auto import that we had set up together and I don't remember how to use it to import the bulk pricing with the system he built. Could someone explain what the code indicate that I would do to use it?
<?php
/*
Plugin Name: WP All Import Woo Bulk Pricing Add-On
Description: Import data related to bulk pricing
Version: 1.0 */
//
function import_pricing_fields($id, $xml_node) {
// return;
$post_type = get_post_type($id);
if($post_type == 'product' || $post_type == 'product_variation' ){
$xml_node = (array) $xml_node;
$_product = wc_get_product( $id );
$number_of_prices = 3;
if( $_product->is_type( 'simple' ) ) {
update_post_meta($id,'_regular_price', $xml_node['price']);
update_post_meta($id,'_price', $xml_node['price']);
$pricing_array = array();
for($i=1;$i<$number_of_prices;$i++){
if(isset($xml_node['qb_'.$i]) && $xml_node['qb_'.$i] != 0){
$pricing_array[$i]['min'] = $xml_node['qb_'.$i];
if($i > 1){
$pricing_array[$i-1]['max'] = $xml_node['qb_'.$i]-1;
$pricing_array[$i]['max'] = "*";
} else {
$pricing_array[$i]['max'] = "*";
}
$pricing_array[$i]['val'] = $xml_node['price_'.$i];
}
}
$pricing_array = array_values($pricing_array);
if(!empty($pricing_array)) {
update_post_meta($id,'_wc_bulk_pricing_ruleset','_custom');
update_post_meta($id,'_wc_bulk_pricing_custom_ruleset', $pricing_array);
}
} else{
$var_id = wc_get_product_id_by_sku($xml_node['catalog']);
$variations = $_product->get_children();
if(!empty($variations)) {
foreach ($variations as $variation) {
$sku = get_post_meta($variation, '_sku', true);
if(!empty($sku) && $sku == $xml_node['catalog']) {
$var_id = $variation;
}
}
}
update_post_meta($var_id,'_regular_price', $xml_node['price']);
update_post_meta($var_id,'_price', $xml_node['price']);
if(isset($xml_node['qb_1'])) {
$pricing_array = array();
for($i=1;$i<$number_of_prices;$i++){
if(isset($xml_node['qb_'.$i]) && $xml_node['qb_'.$i] != 0){
$pricing_array[$i]['min'] = $xml_node['qb_'.$i];
if($i > 1){
$pricing_array[$i-1]['max'] = $xml_node['qb_'.$i]-1;
$pricing_array[$i]['max'] = "*";
} else {
$pricing_array[$i]['max'] = "*";
}
$pricing_array[$i]['val'] = $xml_node['price_'.$i];
}
}
$pricing_array = array_values($pricing_array);
if(!empty($pricing_array)) {
update_post_meta($var_id,'_wc_bulk_pricing_ruleset','_custom');
update_post_meta($var_id,'_wc_bulk_pricing_custom_ruleset', $pricing_array);
}
}
}
}
}
add_action('pmxi_saved_post','import_pricing_fields', 10, 2);

Could someone explain what the code indicate that I would do to use
it?
The function import_pricing_fields() is hooked into the 'pmxi_saved_post' action.
http://www.wpallimport.com/documentation/advanced/action-reference/
What this means is that every time you import a post using WP All Import it will also run the function import_pricing_fields().
However this is one check to pass before the majority of the code in this function will run, and that is on line 4 if($post_type == 'product' || $post_type == 'product_variation' ). Which simply means if the post is a product or product_variation continue running this code.
The rest of the code looks like it does what you said, import bulk pricing...

Related

WooCommerce WC()->session->set not working

I want to add some of the fields from a form into custom fields on a product so I can use them into an API call after payment is made. I have a redirection on my form that gets to the checkout page and add the product in the basket, code below:
<script>
document.addEventListener( 'wpcf7mailsent', function( event ) {
if (jQuery("input[type='checkbox'][name='try[]']").is(':checked')) {
location = 'http://www.thelittlegym.co.za/checkout/?add-to-cart=2506';
}
}, false );
</script>
Then, I have some code in my function.php to save the form data in the WC session.
I had to add declare the new session otherwise the set function didn't work.
If I do the init then I get an error saying "wc_empty_cart();" isn't defined (this function is from the WooCommerce plugin.
add_action('wpcf7_before_send_mail', 'send_form_data_to_wc_session', 5, 1);
function send_form_data_to_wc_session($contact_form) {
$submission = WPCF7_Submission::get_instance();
if($submission) {
$posted_data = $submission->get_posted_data();
if (!empty($posted_data['try'][0])) {
// Set data to WooCommerce session
WC()->session = new WC_Session_Handler();
// WC()->session->init();
WC()->session->set('cf7_posted_data', $posted_data);
}
}
}
Finally, I'm trying to retrieve the session data with the code below.
The var dump just returns NULL.
add_action('woocommerce_checkout_before_customer_details', 'wc_save_cf7_data_to_order', 10, 1);
function wc_save_cf7_data_to_order($order_id) {
$posted_data = WC()->session->get('cf7_posted_data');
var_dump($posted_data);
if(!empty($posted_data)) {
foreach($posted_data as $key => $data) {
echo '<b>', $key, ' : </b> ', $data, '<br />';
}
WC()->session->__unset('cf7_posted_data');
}
}
I believe the WC session set isn't working. I'm looking in the console for the Session Storage and can only see "wc_cart_hash_xxxxxxx", "wc_fragment_xxxxxxx" and "wc_cart_created".
Any idea how I can go ahead to debug this?
I've found an alternative solution on another topic, which solved my problem even if it doesn't explain why the code above didn't work.
add_action('wpcf7_before_send_mail', 'send_form_data_to_wc_session', 5, 1);
function send_form_data_to_wc_session($contact_form) {
$submission = WPCF7_Submission::get_instance();
if($submission) {
$posted_data = $submission->get_posted_data();
if (!empty($posted_data['try'][0])) {
// Set data to Session
session_start();//place this at the top of all code
$_SESSION['cf7_posted_data']=$posted_data;
}
}
}
and to retrieve:
add_action('woocommerce_checkout_before_customer_details', 'wc_save_cf7_data_to_order', 10, 1);
function wc_save_cf7_data_to_order($order_id) {
session_start();
$posted_data = $_SESSION['cf7_posted_data'];
var_dump($posted_data);
}

How do I modify wpDataTables cell values using filters?

In wpDataTables, I would like to modify (i.e. conditionally format) each cell value in a specific column for a specific table programmatically using PHP. How would I accomplish this?
First, install the Code Snippets plugin. Then create a new snippet set to "Run Snippet Everywhere" (required for JSON filtering) using the code below. It will filter both HTML and JSON. For more information, refer to wpDataTables - Filters.
function custom_wpdatatables_filter_initial_table_construct($tbl) {
// Edit below.
$table_name_to_modify = 'My Table Name';
$table_column_to_modify = 'my_table_column';
$cell_modification_function = function($value) {
return 'Modified: ' . $value;
};
// Check table name.
if ($tbl->getName() !== $table_name_to_modify) {
return $tbl;
}
$rows = $tbl->getDataRows();
foreach ($rows as &$row) {
if (array_key_exists($table_column_to_modify, $row)) {
$row['intermentobituary'] = $cell_modification_function($row['intermentobituary']);
}
}
$tbl->setDataRows($rows);
return $tbl;
}
add_filter('wpdatatables_filter_initial_table_construct', 'custom_wpdatatables_filter_initial_table_construct', 10, 1);
function custom_wpdatatables_filter_server_side_data($json, $tableId, $get) {
// Edit below.
$table_name_to_modify = 'My Table Name';
$table_column_to_modify = 'my_table_column';
$cell_modification_function = function($value) {
return 'Modified: ' . $value;
};
// Check table name.
$tableData = WDTConfigController::loadTableFromDB($tableId);
if (empty($tableData->content)) {
return $json;
} else if ($tableData->title !== $table_name_to_modify) {
return $json;
}
// Get columns.
$columns = [];
foreach ($tableData->columns as $column) {
// wdt_ID will be first column.
$columns[] = $column->orig_header;
}
// Modify column values.
$json = json_decode($json, true);
$rows = $json['data'];
foreach ($rows as $row_key => $row_value) {
foreach ($row_value as $row_attr_key => $row_attr_value) {
if ( ! empty($columns[$row_attr_key]) && $columns[$row_attr_key] === $table_column_to_modify) {
$rows[$row_key][$row_attr_key] = $cell_modification_function($row_attr_value);
}
}
}
$json['data'] = $rows;
return json_encode($json);
}
add_filter('wpdatatables_filter_server_side_data', 'custom_wpdatatables_filter_server_side_data', 10, 3);

Contact Form 7 (CF7) Field required if other field filled

I have a CF7-Form that asks for a name and date of birth.
The name is not a required field, but if a name is entered, the birthday is required in any case.
Therefore, the date of birth is not included as required by default.
CF7 Simplified code:
<div class="cf7-conditional-wrapper">
<label>Name [text your-name class:field-a]</label>
<label>Birthday<span class="asterisk-placeholder"></span> [date your-date class:field-b-required-if-a-set]</label>
</div>
In the first step I work on the fact that the field should also be perceived as a required field by CF7.
let cf7_conditional_wrappers = document.getElementsByClassName("cf7-conditional-wrapper");
for (let cf7_conditional_wrapper of cf7_conditional_wrappers) {
let field_a = cf7_conditional_wrapper.getElementsByClassName("field-a")[0],
field_b = cf7_conditional_wrapper.getElementsByClassName("field-b-required-if-a-set")[0],
asterisk_placeholder = cf7_conditional_wrapper.getElementsByClassName("asterisk-placeholder")[0];
if (field_a && field_b && asterisk_placeholder) {
checkRequiredFields(field_a, field_b, asterisk_placeholder);
}
}
function checkRequiredFields(field_a, field_b, asterisk_placeholder) {
let timeout = null;
// Listen for keystroke events
field_a.addEventListener('keyup', function (e) {
clearTimeout(timeout);
timeout = setTimeout(function () {
//console.log('Input Value:', field_a.value);
//console.log('Input Value Length:', field_a.value.length);
if (field_a.value.length > 0) {
// Set Required
field_b.classList.add('wpcf7-validates-as-required');
//field_b.classList.add('wpcf7-not-valid');
field_b.setAttribute("aria-required", "true");
//field_b.setAttribute("aria-invalid", "false");
//field_b.setAttribute("required", "");
//field_b.required = true;
asterisk_placeholder.textContent = "*";
} else {
field_b.classList.remove('wpcf7-validates-as-required');
//field_b.classList.remove('wpcf7-not-valid');
field_b.removeAttribute("aria-required");
//field_b.setAttribute("aria-invalid", "false");
//field_b.removeAttribute("required");
//field_b.required = false;
asterisk_placeholder.textContent = "";
}
}, 1000);
});
}
Everything appears visually to be correct, but the new required field is not checked when the form is submitted.
Does anyone have any tips that I haven't considered?
For safety, I would also solve the same query on the server side via PHP and have looked at the following approach. However, the entry from 2015 was unsuccessful in the first tests, although the code is still similar to that of the plugin's database today.
add_filter( 'wpcf7_validate_date', 'custom_date_confirmation_validation_filter', 20, 2 );
function custom_date_confirmation_validation_filter( $result, $tag ) {
if ( 'birth-date' == $tag->name ) {
$your_birth_date = isset( $_POST['birth-date'] ) ? trim( $_POST['birth-date'] ) : '';
if ( $your_birth_date != '' ) {
$result->invalidate( $tag, "Test to override Required Message" );
}
}
return $result;
}
Example in manual from 2015: https://contactform7.com/2015/03/28/custom-validation/
add_filter( 'wpcf7_validate_date', 'custom_date_confirmation_validation_filter', 20, 2 );
function custom_date_confirmation_validation_filter( $result, $tag ) {
$name = isset( $_POST['name'] ) ? trim( $_POST['name'] ) : '';
if ( 'birth-date' == $tag->name ) {
$your_birth_date = isset( $_POST['birth-date'] ) ? trim( $_POST['birth-date'] ) : '';
if ( trim($name) != '' && trim($your_birth_date) == '' ) {
$result->invalidate( $tag, "Please enter date of birth" );
}
}
return $result;
}
Check if name is not empty and birth date is empty then show warning message.

Wordpress Display ACF only in first depth nav

I write function for display acf in menu.
I need to display only in depth [0].
All work. But i still to se terrible notice:
Notice: Undefined index: nav_menu_item_depth in
here is my code:
add_filter('acf/location/rule_types', 'acf_location_rules_types');
function acf_location_rules_types($choices)
{
$choices['Menu']['menu_level'] = 'Livello Menu';
return $choices;
}
add_filter('acf/location/rule_values/menu_level', 'acf_location_rule_values_level');
function acf_location_rule_values_level($choices)
{
$choices[0] = '0';
$choices[1] = '1';
return $choices;
}
add_filter('acf/location/rule_match/menu_level', 'acf_location_rule_match_level', 10, 4);
function acf_location_rule_match_level($match, $rule, $options, $field_group)
{
global $current_screen;
if ($current_screen->id == 'nav-menus') {
if ($rule ['operator'] == "==") {
$match = ($options['nav_menu_item_depth'] == $rule['value']); // <-- Problem is here
}
}
return $match;
}
Some can help me to understand?
Thanks
Ciao Paolo! It worked for me by adding an isset() check on $options['nav_menu_item_depth']. My guess is that this runs on the whole nav-menus page before hitting the nav-items.
function acf_location_rule_match_level($match, $rule, $options, $field_group)
{
global $current_screen;
if ($current_screen->id == 'nav-menus' && isset($options['nav_menu_item_depth'])) {
if ($rule ['operator'] == "==") {
$match = ($options['nav_menu_item_depth'] == $rule['value']); // <-- Problem is here
}
}
return $match;
}
I'm pretty new to WP so I'd love to hear if there is a better way to do this or if this is a bad idea for some reason.

Improving FrontEnd Uploads in Wordpress

I want to improve the process of uploading pictures in a Real Estate Website. This website is running WordPress 3.8. The theme offers front end submission with a very simple interface. The user selects the images (one by one) and then clicks to add. Finally when the user submit the listing all the images are uploaded at once. This is the screenshot of how it looks: Original Option: Listing Images.
This is the JQuery Plugin I am currently using,
/*!
* jQuery imagesLoaded plugin v2.1.1
* http://github.com/desandro/imagesloaded
*
* MIT License. by Paul Irish et al.
*/
/*jshint curly: true, eqeqeq: true, noempty: true, strict: true, undef: true, browser: true */
/*global jQuery: false */
;(function($, undefined) {
'use strict';
// blank image data-uri bypasses webkit log warning (thx doug jones)
var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
$.fn.imagesLoaded = function( callback ) {
var $this = this,
deferred = $.isFunction($.Deferred) ? $.Deferred() : 0,
hasNotify = $.isFunction(deferred.notify),
$images = $this.find('img').add( $this.filter('img') ),
loaded = [],
proper = [],
broken = [];
// Register deferred callbacks
if ($.isPlainObject(callback)) {
$.each(callback, function (key, value) {
if (key === 'callback') {
callback = value;
} else if (deferred) {
deferred[key](value);
}
});
}
function doneLoading() {
var $proper = $(proper),
$broken = $(broken);
if ( deferred ) {
if ( broken.length ) {
deferred.reject( $images, $proper, $broken );
} else {
deferred.resolve( $images );
}
}
if ( $.isFunction( callback ) ) {
callback.call( $this, $images, $proper, $broken );
}
}
function imgLoadedHandler( event ) {
imgLoaded( event.target, event.type === 'error' );
}
function imgLoaded( img, isBroken ) {
// don't proceed if BLANK image, or image is already loaded
if ( img.src === BLANK || $.inArray( img, loaded ) !== -1 ) {
return;
}
// store element in loaded images array
loaded.push( img );
// keep track of broken and properly loaded images
if ( isBroken ) {
broken.push( img );
} else {
proper.push( img );
}
// cache image and its state for future calls
$.data( img, 'imagesLoaded', { isBroken: isBroken, src: img.src } );
// trigger deferred progress method if present
if ( hasNotify ) {
deferred.notifyWith( $(img), [ isBroken, $images, $(proper), $(broken) ] );
}
// call doneLoading and clean listeners if all images are loaded
if ( $images.length === loaded.length ) {
setTimeout( doneLoading );
$images.unbind( '.imagesLoaded', imgLoadedHandler );
}
}
// if no images, trigger immediately
if ( !$images.length ) {
doneLoading();
} else {
$images.bind( 'load.imagesLoaded error.imagesLoaded', imgLoadedHandler )
.each( function( i, el ) {
var src = el.src;
// find out if this image has been already checked for status
// if it was, and src has not changed, call imgLoaded on it
var cached = $.data( el, 'imagesLoaded' );
if ( cached && cached.src === src ) {
imgLoaded( el, cached.isBroken );
return;
}
// if complete is true and browser supports natural sizes, try
// to check for image status manually
if ( el.complete && el.naturalWidth !== undefined ) {
imgLoaded( el, el.naturalWidth === 0 || el.naturalHeight === 0 );
return;
}
// cached images don't fire load sometimes, so we reset src, but only when
// dealing with IE, or image is complete (loaded) and failed manual check
// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
if ( el.readyState || el.complete ) {
el.src = BLANK;
el.src = src;
}
});
}
return deferred ? deferred.promise( $this ) : $this;
};
})(jQuery);
My goal is to have a more flexible system, where all the images can be selected at the same time and it starts loading right away. This will speed up the process and improve user experience. Also to arrange them in any order by moving them around. This is an example I found on another website. See screenshot: New Option: Multiple Image Upload
What programing language is good for this development? Any recommendations of where I can find code snippets for this application? Thanks in advance for your help!!
rough draft.....you need jquery and wordpress media js..just watch the js variable names below if there are errors it will be with these...
php in functions file:
if(function_exists( 'wp_enqueue_media' )){
wp_enqueue_media();
}
javascript...add to the page header..wp_enqueue_scripts or to your template (do this first to make sure its working!) you'll need your element called upload_image_button or change accordinely
// Uploading files
var media_uploader;
jQuery('.upload_image_button').live('click', function( event ){
var button = jQuery( this );
// If the media uploader already exists, reopen it.
if ( media_uploader ) {
media_uploader.open();
return;
}
// Create the media uploader.
media_uploader = wp.media.frames.media_uploader = wp.media({
title: button.data( 'uploader-title' ),
// Tell the modal to show only images.
library: {
type: 'image',
query: false
},
button: {
text: button.data( 'uploader-button-text' ),
},
multiple: button.data( 'uploader-allow-multiple' )
});
// Create a callback when the uploader is called
media_uploader.on( 'select', function() {
var selection = media_uploader.state().get('selection'),
input_name = button.data( 'input-name' ),
bucket = $( '#' + input_name + '-thumbnails');
selection.map( function( attachment ) {
attachment = attachment.toJSON();
// console.log(attachment);
bucket.append(function() {
return '<img src="'+attachment.sizes.thumbnail.url+'" width="'+attachment.sizes.thumbnail.width+'" height="'+attachment.sizes.thumbnail.height+'" class="submission_thumb thumbnail" /><input name="'+input_name+'[]" type="hidden" value="'+attachment.id+'" />'
});
});
});
// Open the uploader
media_uploader.open();
});
template file:
<span class="upload_image_button alt_button" data-input-name="images" data-uploader- title="Upload Images" data-uploader-button-text="Add to Submission" data-uploader-allow-multiple="true">Upload</span>
php $_POST return
if ( !empty( $_POST['submission_images'] ) ) {
// do something with the files, set featured img, add to content or save post_meta
}
or..............i came across a plugin that does this a lot better........sorry its in OOP and designed on back end but you can modify for front end! The problem with multi file uploader from WP is it required users to hit "CTRL" + click with no guidance....massive problem on front-end forms...this one you can add more guidance to easily...sorry i havent a frontend sample yet, i have yet to create :)
"Multi File Upload"
e.g.
public function render_meta_box_content($post)
{
// Add an nonce field so we can check for it later.
wp_nonce_field('miu_inner_custom_box', 'miu_inner_custom_box_nonce');
// Use get_post_meta to retrieve an existing value from the database.
$value = get_post_meta($post->ID, '_ad_images', true);
$metabox_content = '<div id="miu_images"></div><input type="button" onClick="addRow()" value="Add Image" class="button" />';
echo $metabox_content;
$images = unserialize($value);
$script = "<script>
itemsCount= 0;";
if (!empty($images))
{
foreach ($images as $image)
{
$script.="addRow('{$image}');";
}
}
$script .="</script>";
echo $script;
}
save function
public function save_image($post_id)
{
/*
* We need to verify this came from the our screen and with proper authorization,
* because save_post can be triggered at other times.
*/
// Check if our nonce is set.
if (!isset($_POST['miu_inner_custom_box_nonce']))
return $post_id;
$nonce = $_POST['miu_inner_custom_box_nonce'];
// Verify that the nonce is valid.
if (!wp_verify_nonce($nonce, 'miu_inner_custom_box'))
return $post_id;
// If this is an autosave, our form has not been submitted,
// so we don't want to do anything.
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return $post_id;
// Check the user's permissions.
if ('page' == $_POST['post_type'])
{
if (!current_user_can('edit_page', $post_id))
return $post_id;
} else
{
if (!current_user_can('edit_post', $post_id))
return $post_id;
}
/* OK, its safe for us to save the data now. */
// Validate user input.
$posted_images = $_POST['miu_images'];
$miu_images = array();
foreach ($posted_images as $image_url)
{
if(!empty ($image_url))
$miu_images[] = esc_url_raw($image_url);
}
// Update the miu_images meta field.
update_post_meta($post_id, '_ad_images', serialize($miu_images));
}
js file
jQuery(document).ready(function(){
jQuery('.miu-remove').live( "click", function(e) {
e.preventDefault();
var id = jQuery(this).attr("id")
var btn = id.split("-");
var img_id = btn[1];
jQuery("#row-"+img_id ).remove();
});
var formfield;
var img_id;
jQuery('.Image_button').live( "click", function(e) {
e.preventDefault();
var id = jQuery(this).attr("id")
var btn = id.split("-");
img_id = btn[1];
jQuery('html').addClass('Image');
formfield = jQuery('#img-'+img_id).attr('name');
tb_show('', 'media-upload.php?type=image&TB_iframe=true');
return false;
});
window.original_send_to_editor = window.send_to_editor;
window.send_to_editor = function(html){
if (formfield) {
fileurl = jQuery('img',html).attr('src');
jQuery('#img-'+img_id).val(fileurl);
tb_remove();
jQuery('html').removeClass('Image');
} else {
window.original_send_to_editor(html);
}
};
});
function addRow(image_url){
if(typeof(image_url)==='undefined') image_url = "";
itemsCount+=1;
var emptyRowTemplate = '<div id=row-'+itemsCount+'> <input style=\'width:70%\' id=img- '+itemsCount+' type=\'text\' name=\'miu_images['+itemsCount+']\' value=\''+image_url+'\' />'
+'<input type=\'button\' href=\'#\' class=\'Image_button button\' id=\'Image_button- '+itemsCount+'\' value=\'Upload\'>'
+'<input class="miu-remove button" type=\'button\' value=\'Remove\' id=\'remove-'+itemsCount+'\' /></div>';
jQuery('#miu_images').append(emptyRowTemplate);
}

Resources