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

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);
}

Related

Hide "Attributes" tab for a "Simple Product" type option

I have added a third checkmark option to the "Simple Product" tab, like this:
add_filter("product_type_options", function ($product_type_options) {
$product_type_options["personalize"] = [
"id" => "_personalize",
"wrapper_class" => "show_if_simple",
"label" => "Personalize",
"description" => "personalize Products",
"default" => "no",
];
return $product_type_options;
});
add_action("save_post_product", function ($post_ID, $product, $update) {
update_post_meta(
$product->ID
, "_personalize"
, isset($_POST["_personalize"]) ? "yes" : "no"
);
}, 10, 3);
I need to hide the "Attributes" tab when this custom "Personalize" checkbox is selected. ie., if you click on the "Virtual" option checkbox, the "Shipping" tab hides. Likewise, I need the "Personalize" option checkbox to hide the "Attributes" tab upon selection.
I have tried:
add_filter('woocommerce_product_data_tabs', 'misha_product_data_tabs' );
function misha_product_data_tabs( $tabs ){
$tabs['attribute']['class'][] = 'hide_if_personalize';
return $tabs;
}
But it is not working. Can you please help?
Check screenshot: https://snipboard.io/vhqMyA.jpg
First, you have to update the meta value on the checkbox change. then you can add class hide_if_personalize if meta value is yes using this woocommerce_product_data_tabs filter hook. check below code.
add_filter("product_type_options", function ( $product_type_options ) {
$product_type_options["personalize"] = [
"id" => "_personalize",
"wrapper_class" => "show_if_simple",
"label" => "Personalize",
"description" => "personalize Products",
"default" => "no",
];
return $product_type_options;
});
add_filter('woocommerce_product_data_tabs', 'misha_product_data_tabs' );
function misha_product_data_tabs( $tabs ){
$personalize = get_post_meta( get_the_ID() , "_personalize" , true );
if( $personalize == 'yes' ){
$tabs['attribute']['class'] = 'hide_if_personalize';
}
return $tabs;
}
add_action( 'wp_ajax_hide_attribute_if_personalize', 'hide_attribute_if_personalize' );
add_action( 'wp_ajax_nopriv_hide_attribute_if_personalize', 'hide_attribute_if_personalize' );
function hide_attribute_if_personalize(){
$personalize = $_POST['personalize'];
$product_id = $_POST['product_id'];
update_post_meta( $product_id, '_personalize', $personalize );
}
function add_custom_admin_js_css(){
?>
<style type="text/css">
li.attribute_options.attribute_tab.hide_if_personalize {
display: none !important;
}
</style>
<script type="text/javascript">
(function($){
$(document).ready(function(){
$( document ).on('change','#_personalize',function(){
var personalize = 'no';
if( $(this).is(":checked") ){
$('li.attribute_options.attribute_tab').addClass('hide_if_personalize');
personalize = 'yes';
}else{
$('li.attribute_options.attribute_tab').removeClass('hide_if_personalize');
}
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: "post",
data: {personalize:personalize,product_id:$('#post_ID').val(),action:'hide_attribute_if_personalize'},
success: function( response ) {
},error: function (jqXHR, exception) {
var msg = '';
if (jqXHR.status === 0) {
msg = 'Not connect.\n Verify Network.';
} else if (jqXHR.status == 404) {
msg = 'Requested page not found. [404]';
} else if (jqXHR.status == 500) {
msg = 'Internal Server Error [500].';
} else if (exception === 'parsererror') {
msg = 'Requested JSON parse failed.';
} else if (exception === 'timeout') {
msg = 'Time out error.';
} else if (exception === 'abort') {
msg = 'Ajax request aborted.';
} else {
msg = 'Uncaught Error.\n' + jqXHR.responseText;
}
console.log(msg);
},
});
});
});
})(jQuery);
</script>
<?php }
add_action( 'admin_footer', 'add_custom_admin_js_css', 10, 1 );
Tested and works.
You can hide the "Attributes" tab via a jQuery script.
The showHideAttributeTab() script it will be activated when the page is loaded and when the "Personalize" checkbox is clicked.
It is also important to disable the <input> and <select> fields of the
add attributes form to ensure that they are not sent when saving the
product.
In fact, a user could add one or more attributes to the product, check the "Personalize" checkbox and finally save the product.
If you simply hide the elements, it is true that they will not be visible to the user, but they will still be captured by the Ajax function for saving attributes.
To prevent this it is necessary to disable any field of the Attributes tab. Then, after saving, all attributes will be removed if the "Personalize" checkbox is checked.
ADDITION
When the "Personalize" checkbox is unchecked, the "General" tab is
automatically activated.
Also, if the "Attributes" tab is active and the user selects "Personalize", it automatically activates the "General" tab to avoid white content.
// adds script in Wordpress backend to show or hide attribute tab based on custom field
add_action( 'admin_footer', 'show_hide_attribute_tab' );
function show_hide_attribute_tab() {
?>
<script type="text/javascript">
function showHideAttributeTab() {
if ( jQuery('#_personalize').is(':checked') ) {
jQuery('li.attribute_options.attribute_tab').hide();
jQuery('#product_attributes').hide();
// disable all fields of the "Attributes" tab
jQuery("#product_attributes input, #product_attributes select").each(function() {
jQuery(this).prop("disabled", true);
});
// if user enables "Attributes" tab, switch to general tab.
if ( jQuery( '.attribute_options.attribute_tab' ).hasClass( 'active' ) ) {
jQuery( '.general_options.general_tab > a' ).trigger( 'click' );
}
} else {
jQuery('li.attribute_options.attribute_tab').show();
jQuery('#product_attributes').show();
// enables all fields of the "Attributes" tab
jQuery("#product_attributes input, #product_attributes select").each(function() {
jQuery(this).prop("disabled", false);
});
// switch to general tab
jQuery("li.general_options.general_tab > a").trigger("click");
}
}
// runs the script when the page loads
showHideAttributeTab();
// runs the script when the "Personalize" checkbox is clicked
jQuery("#_personalize").click(function() {
showHideAttributeTab();
});
</script>
<?php
}
The code has been tested and works. Add it to your active theme's functions.php.

dynamically populated cascading dropdown error

I found very useful article on the web
for contact form 7
<?php
function ajax_cf7_populate_values() {
// read the CSV file in the $makes_models_years array
$makes_models_years = array();
$uploads_folder = wp_upload_dir()['basedir'];
$file = fopen($uploads_folder.'\make_model_year.csv', 'r');
$firstline = true;
while (($line = fgetcsv($file)) !== FALSE) {
if ($firstline) {
$firstline = false;
continue;
}
$makes_models_years[$line[0]][$line[1]][] = $line[2];
}
fclose($file);
// setup the initial array that will be returned to the the client side script as a JSON object.
$return_array = array(
'makes' => array_keys($makes_models_years),
'models' => array(),
'years' => array(),
'current_make' => false,
'current_model' => false
);
// collect the posted values from the submitted form
$make = key_exists('make', $_POST) ? $_POST['make'] : false;
$model = key_exists('model', $_POST) ? $_POST['model'] : false;
$year = key_exists('year', $_POST) ? $_POST['year'] : false;
// populate the $return_array with the necessary values
if ($make) {
$return_array['current_make'] = $make;
$return_array['models'] = array_keys($makes_models_years[$make]);
if ($model) {
$return_array['current_model'] = $model;
$return_array['years'] = $makes_models_years[$make][$model];
if ($year) {
$return_array['current_year'] = $year;
}
}
}
// encode the $return_array as a JSON object and echo it
echo json_encode($return_array);
wp_die();
}
// These action hooks are needed to tell WordPress that the cf7_populate_values() function needs to be called
// if a script is POSTing the action : 'cf7_populate_values'
add_action( 'wp_ajax_cf7_populate_values', 'ajax_cf7_populate_values' );
add_action( 'wp_ajax_nopriv_cf7_populate_values', 'ajax_cf7_populate_values' );
and some java
<script>
(function($) {
// create references to the 3 dropdown fields for later use.
var $makes_dd = $('[name="makes"]');
var $models_dd = $('[name="models"]');
var $years_dd = $('[name="years"]');
// run the populate_fields function, and additionally run it every time a value changes
populate_fields();
$('select').change(function() {
populate_fields();
});
function populate_fields() {
var data = {
// action needs to match the action hook part after wp_ajax_nopriv_ and wp_ajax_ in the server side script.
'action' : 'cf7_populate_values',
// pass all the currently selected values to the server side script.
'make' : $makes_dd.val(),
'model' : $models_dd.val(),
'year' : $years_dd.val()
};
// call the server side script, and on completion, update all dropdown lists with the received values.
$.post('/wp-admin/admin-ajax.php', data, function(response) {
all_values = response;
$makes_dd.html('').append($('<option>').text(' -- choose make -- '));
$models_dd.html('').append($('<option>').text(' -- choose model -- '));
$years_dd.html('').append($('<option>').text(' -- choose year -- '));
$.each(all_values.makes, function() {
$option = $("<option>").text(this).val(this);
if (all_values.current_make == this) {
$option.attr('selected','selected');
}
$makes_dd.append($option);
});
$.each(all_values.models, function() {
$option = $("<option>").text(this).val(this);
if (all_values.current_model == this) {
$option.attr('selected','selected');
}
$models_dd.append($option);
});
$.each(all_values.years, function() {
$option = $("<option>").text(this).val(this);
if (all_values.current_year == this) {
$option.attr('selected','selected');
}
$years_dd.append($option);
});
},'json');
}
})( jQuery );
</script>
but when i add it to me website nothing appear in the dropdowns. They are empty.
I tried to contact the blogger but there is no answer yet. Give me some advice
I copied the csv almost as the one in the post. So I think the function is mistaken... somewhere
I found the solution: in the article the file name is mistaken. It has to be "make_model_year.csv" !!!

How can i sure that mysql statements done susseccfully in wordpress

I added some field to wordpress commments and add below code for save them :
add_action ('comment_post', 'add_comment_bid_values', 1);
function add_comment_bid_values($comment_id) {
if(isset($_POST['bidprice'])) {
$bidprice = wp_filter_nohtml_kses($_POST['bidprice']);
add_comment_meta($comment_id, 'bidprice', $bidprice, false);
}
if(isset($_POST['bidday'])) {
$bidday = wp_filter_nohtml_kses($_POST['bidday']);
add_comment_meta($comment_id, 'bidday', $bidday, false);
}
if(isset($_POST['bidprepay'])) {
$bidprepay = wp_filter_nohtml_kses($_POST['bidprepay']);
add_comment_meta($comment_id, 'bidprepay', $bidprepay, false);
}
if(isset($_POST['bidsponsor'])) {
$bidsponsor = wp_filter_nohtml_kses($_POST['bidsponsor']);
add_comment_meta($comment_id, 'bidsponsor', $bidsponsor, false);
}
if(isset($_POST['bidfetured'])) {
$bidfetured = wp_filter_nohtml_kses($_POST['bidfetured']);
add_comment_meta($comment_id, 'bidfetured', $bidfetured, false);
}
}
Now
How i can sure that comment and it's meta inserted into wordpress database, because some information save by comment_form function and this meta save by above code and also wordpress don't have transaction .
Thanks
As wp code reference says - 'comment_post' action hook is fired immediately AFTER a comment is inserted into the database. That means your code will be executed only if comment successfully inserted in database. For comment meta checking you can do something like that:
$result = add_comment_meta($comment_id, 'your_meta_key', $yourMetaValue, false)
//add_comment_meta will return false on error
if (false === $result) {
//do something here for example wp_die( __('Comment meta error', 'textdomain') );
}

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);
}

WordPress Plugin Event Call Before Shortcode

I am writing a plugin and I am having some difficulty with when to trigger specific functions of the plugin code.
/*
// Plugin information goes here
*/
// ***** Area A
$GLOBALS['example_class'] = new example_class;
class example_class {
// ***** Area B
public function admin_init() {
add_menu_page(
// ...
);
} // End of admin_init function
} // End of example class
add_action('init', function() {
global $example_class;
// ***** Area C
if ( ?????? ) {
// Sanitize and set the view role
$view = ( isset( $_REQUEST['view'] ) ) ? sanitize_key( $_REQUEST['ex'] ) : 'get_all';
// Manage submitted data
switch ( $view ) {
// ...
} // End of switch for view
// Sanitize and set the action role
$action = ( isset( $_REQUEST['action'] ) ) ? sanitize_key( $_REQUEST['action'] ) : NULL;
// Manage submitted data
switch ( $action ) {
//...
} // End of switch for action
} // End of if page is being shown
});
add_action( 'admin_menu', function() {
global $example_class;
$example_class->admin_init();
});
add_shortcode( 'show_public_random', function () {
global $example_class;
// ...
});
As per suggested in a previous post on stackexchange, I separated the controller side of my plugin into a function called by the init event. However, I do not want the code contained in the init event function to be evaluated at every page load - I want my code to be evaluated only when the page containing the shortcode is loaded.
I have tried loading a boolean class variable that initializes as false but is changed to true from within the add_shortcode function, but by that time, it's too late - the init event has fired, and the function's contents is not run.
Please help me - which expression should I use in Area C of my code? What should I test against to ensure the init event function is run only when the shortcode is being used?
I've found an answer, although messy.
/*
// Plugin information goes here
*/
$GLOBALS['example_class'] = new example_class;
class example_class {
var $public_loaded = false,
$content = '';
public function admin_init() {
add_menu_page(
// ...
);
} // End of admin_init function
public function get_random( ) {
// ...
}
} // End of example class
add_action('init', function() {
global $example_class;
// ***** Area A
// Check for arbitrary variable sent with every user interaction
if ( if ( isset( sanitize_key( $_REQUEST['tni'] ) ) ) {
// ***** Area B
/* Set the class variable `public_loaded` to true after it's
* clear we're loading a public page which uses our plugin */
$example_class->public_loaded = true;
// Sanitize and set the action role
$action = ( isset( $_REQUEST['action'] ) ) ? sanitize_key( $_REQUEST['action'] ) : NULL;
// Manage submitted data
switch ( $action ) {
// ...
} // End of switch for action
// Sanitize and set the view role
$view = ( isset( $_REQUEST['view'] ) ) ? sanitize_key( $_REQUEST['ex'] ) : 'get_all';
// Manage submitted data
switch ( $view ) {
// ... Generate content and store in $this->content
} // End of switch for view
} // End of if page is being shown
});
add_action( 'admin_menu', function() {
global $example_class;
$example_class->admin_init();
});
add_shortcode( 'show_public_random', function () {
global $example_class;
// ***** Area C
/* Check to see if page has loaded using the telltale sign
* If not, load a default view - a random post */
if ( $example_class->public_loaded === false ) {
$example_class->content = $example_class->get_random();
// ...
}
// Return the generated content
return $example_class->content;
});
In Area A I've set a qualifying statement to see if a user submitted a variable along with their interaction with my plugin. If the plugin is mine, the code is evaluated, and action and view modes are evaluated. As well, the function will set the class variable public_loaded to true.
In Area C I've set a qualifying statement to see if the class variable has been set to true; if not, a default view is set for the shortcode.

Resources