I want to properly use Content Security Policy on my Wordpress site, but also not hardcode URIs.
I am moving all my inline scripts to one file, and adding hashes to all script tags to use with Subresource Integrity.
The ajax localization gives me a hard time; It runs PHP to get the JS file name, and outputs it inline to an object (which gets used by ajax calls).
In order to make admin-ajax available, I have
global $wp_query;
wp_localize_script('project-js', 'ajax_object', array(
'ajaxurl' => admin_url('admin-ajax.php'),
'some_vars' => json_encode($wp_query->query)
));
Which outputs:
<script type="text/javascript" id="project-js-js-extra">
/* <![CDATA[ */
var ajax_object = {"ajaxurl":"http:\/\/domain.tld\/wp\/wp-admin\/admin-ajax.php","some_vars":"[]"};
/* ]]> */
</script>
I need to be able to add a hash to this tag but I cannot find the right way.
I'm able to generate it in PHP like:
global $wp_scripts;
$l10n_candidate = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'some_vars' => json_encode( $wp_query->query )
);
$script_content = "/* <![CDATA[ */
var ajaxpagination = " . wp_json_encode( $l10n_candidate ) . ';
/* ]]> */';
$script_hash = hash('sha256', $script_content);
But I don't know how to add this to the page correctly, and also, this feels too hacky.
Without either outputting this hash, or moving this object creation to my main JavaScript file, the page will not pass my CSP and script will not run.
How do I accomplish this?
As of this moment the only way I could solve it is by using [wp_enqueue_scripts][1], which is the hook used by [wp_enqueue_script][2] when utilizing [wp_localize_script][3]
Doesn't feel like the best solution but it does work.
function abr_ajax_pagi_obj(){
global $wp_query;
$l10n_candidate = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'some_vars' => json_encode( $wp_query->query ),
);
$script_content = "/* <![CDATA[ */
var ajaxpagination = " . wp_json_encode( $l10n_candidate ) . ';
/* ]]> */';
$script_hash = 'sha256-' . base64_encode(hash('sha256', $script_content,true));
?><script integrity="<?php echo $script_hash?>"><?php
echo $script_content;?></script><?php
}
add_action( 'wp_enqueue_scripts', 'abr_ajax_pagi_obj', 5, 5 );
[1]: https://developer.wordpress.org/reference/hooks/wp_enqueue_scripts/
[2]: https://developer.wordpress.org/reference/functions/wp_enqueue_script/
[3]: https://developer.wordpress.org/reference/functions/wp_localize_script/
Related
I'm trying to make some SQL queries using PHP in Wordpress, to auto populate and check values on a gravity form against the existing database.
To do that however, I'm going to need to pass some javascript variables to php, then use that to interact and pull that data back to the form. As someone with minimal web dev background, easier said then done.
My main issue is with an AJAX call that properly carries over a value, but only to the action function. All other calls will show null (I assume due to scoping, but globals don't seem to help).
The main relevant PHP is in a custom plugin as follows:
$address = 0;
function my_enqueue() {
wp_register_script( 'lead-scheduler', null);
wp_enqueue_script( 'lead-scheduler', plugins_url( '/lead_ajax.js', __FILE__ ), array('jquery') );
wp_localize_script( 'lead-scheduler', 'leadajax', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
wp_enqueue_script( 'jquery' );
wp_register_script( 'lead_ajax', null);
wp_enqueue_script( 'lead_ajax' );
}
add_action( 'init', 'my_enqueue' );
function handle_request(){
//Check post address, then apply to global variable
echo $_POST['address'] . "\n";
global $address;
$address = $_POST['address'];
echo $address . "\n";
wp_die("RIP");
}
add_action( 'wp_ajax_handle_request', 'handle_request' );
add_action( 'wp_ajax_nopriv_handle_request', 'handle_request' );
function functionCaller() {
if (is_page ('')) {
?>
<script type="text/javascript">
jQuery(document).ready(function ($) {
$(function(){
var addressField = document.getElementById('input_22_2');
var temp;
//Set up event listener
addressField.onchange = addressCheck;
function addressCheck(){
//Get foreign script
$.getScript("/wp-content/plugins/lead-scheduler/lead_ajax.js", function(){
//Wait until done to execute console.log
$.when(adrCheck()).done(function(){
console.log("Logging: " + "<?php global $address; echo $address ?>");
});
});
}
});
});
</script>
<?php
}
}
add_action('wp_head', 'functionCaller'); ?>
The AJAX call comes from a JS file that I call to:
//AJAX
function adrCheck(){
jQuery(document).ready( function() {
console.log("called")
var addressField = document.getElementById('input_22_2').value;
jQuery.ajax({
type : "post",
url : leadajax.ajax_url,
data : {action: "handle_request", address: addressField},
success: function(response) {
console.log(response)
},error: function(response){
console.log(response);
}
})
})
}
The call seems to work, as the echo in handle_request() works fine. But calling that variable anywhere else returns null. $.when.done doesn't seem to do much, nor does anything synchronous.
I'm sure there's something super elementary that I'm missing, but I can't seem to find it.
Im trying to translate this string in javascript but i cant seem to do it properly.
$(".search-overlay .s").attr("placeholder", "Type here to search");
Ive tried the following but it gives errors, any ideas ?
$(".search-overlay .s").attr("placeholder", "<?php _e( '"Type here to search"', 'romeo' ); ?>");
Thanks.
You should do this proper Wordpress way by using wp_localize_script() function
Please check this codex page out:
https://codex.wordpress.org/Function_Reference/wp_localize_script
Basically in php:
// Register the script
wp_register_script( 'some_handle', 'path/to/myscript.js' );
// Localize the script with new data
$translation_array = array(
'some_string' => __( 'Some string to translate', 'plugin-domain' ),
'a_value' => '10'
);
wp_localize_script( 'some_handle', 'object_name', $translation_array );
// Enqueued script with localized data.
wp_enqueue_script( 'some_handle' );
And in javascript:
alert(object_name.some_string);
I have the following code which works. (When I press the button "test" is displayed on the input form.
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-
core/6.1.19/browser.min.js"></script>
<script>
function btn1() {
document.getElementsByName("admin-status")[0].value = "test";
}
</script>
I want to retrieve the username, so I thought I added it correctly, but it says not defined.
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-
core/6.1.19/browser.min.js"></script>
<script>
global $current_user;
$current_user = wp_get_current_user();
function btn1() {
document.getElementsByName("admin-status")[0].value = $current_user;
}
</script>
What am I missing? Thanks. Noob here.
The better way to add localize script
add_action( 'wp_enqueue_scripts', 'wp12311_enqueue_scripts' );
function wp12311_enqueue_scripts() {
wp_enqueue_script( 'wp12311-scripts', 'your_script_path/test.js', array( 'jquery' ), false, true );
wp_localize_script( 'wp12311-scripts', 'test', array(
'current_user' => wp_get_current_user()
) ) );
}
Now in test.js file you can access current user data like
var displayName = test.current_user.display_name;
You'll probably see a " is undefined" in js console and/or other errors. Note that you forgot the php <?php and ?> around the php code, and the $current_user would be "<?php echo $current_user ?>
If you are doing anything more than one line script you really should enqueue script and then localize script to a variable you can use in js on the page anywhere, not mix php and js!
This question already has answers here:
How to get JavaScript variable value in PHP
(10 answers)
Closed 5 years ago.
So I am helping my friend with his woocommerce WordPress site. He has some short javascript code that needs to be added to the thank you page for the site.
The javascript code takes three variables (totalCost, orderId and setProductId). I can not get to the HTML. So how do I add this code to the PHP and also, how do I access the variables from the PHP and write them into the javascript?
And where in the already existing code should I add it? Is it in the functions.php file for the theme?
I would be super thankful for help!
EDIT:
So would this work?
add_action( 'studentkortet_tracking', 'my_custom_tracking' );
function studentkortet_tracking($order_id){
?>
<script id="pap_x2s6df8d" src="http://URL_TO_PostAffiliatePro/scripts/trackjs.js" type="text/javascript">
</script>
<script type="text/javascript">
PostAffTracker.setAccountId(’xxxxxx’);
var sale = PostAffTracker.createSale();
sale.setTotalCost('<?php echo ($order->order_total - $order->order_shipping); ?>');
sale.setOrderID('<?php echo $order->id; ?>');
sale.setCurrency('<?php echo $order->get_order_currency(); ?>');
PostAffTracker.register();
</script>
<?php
}
Here is some working code, answered here
<script>
var p1 = "success";
</script>
<?php
echo "<script>document.writeln(p1);</script>";
?>
Here's the correct way of accessing PHP variables within a script. It utilises the function wp_localize_script() so that PHP variables are accessible in a script file. First include this file in your functions.php file
function example_enqueue_scripts() {
if( is_checkout() ) {
$args = array( 'total_cost' => 443, 'order_id' => 4567, 'set_product_id' => 123 );
wp_register_script( 'checkout-script', get_stylesheet_directory_uri() . '/checkout-script.js' );
wp_localize_script( 'checkout-script', 'checkout_script', $args );
wp_enqueue_script( 'checkout-script' );
}
}
add_action( 'wp_enqueue_scripts', 'example_enqueue_scripts' );
Then include this javascript in a file under your theme folder called checkout-script.js for example.
(function( $ ) {
'use strict';
$(function() {
var totalCost = checkout_script.total_cost;
var orderId = checkout_script.order_id;
var setProductId = checkout_script.set_product_id;
exampleFunction( totalCost, orderId, setProductId );
function exampleFunction( totalCost, orderId, setProductId ) {
//Do something in here
//alert(totalCost);
}
});
})( jQuery );
I don't know what setProductId is meant to be as a variable, but the hook you are looking for is woocommerce_thankyou. The $order_id is passed by default, which you can then use to grab the order object. Pretty much all the info related to the order can be accessed through the setter/getter methods on the order object.
/**
* Print Javascript on Thankyou page.
* #param int $order_id
*/
function so_47117329_thankyou( $order_id ){
$order = wc_get_order( $order_id ); ?>
<script id="pap_x2s6df8d" src="http://URL_TO_PostAffiliatePro/scripts/trackjs.js" type="text/javascript">
</script>
<script type="text/javascript">
PostAffTracker.setAccountId(’xxxxxx’);
var sale = PostAffTracker.createSale();
sale.setTotalCost('<?php echo $order->get_total() - $order->get_shipping_
(); ?>');
sale.setOrderID('<?php echo $order_id; ?>');
sale.setCurrency('<?php echo $order->get_order_currency(); ?>');
PostAffTracker.register();
</script>
<?php
}
add_action( 'woocommerce_thankyou', 'so_47117329_thankyou' );
Editing to add an alternative for enqueuing the scripts as suggested by #Andrew-Schultz. Using the woocommerce_thankyou hook gets you easy access to the $order_id, which would otherwise need to be retrieved from the URL. You will still access the javascript variables as he's shown in his answer.
/**
* Enqueue Javascript on Thankyou page.
* #param int $order_id
*/
function so_47117329_thankyou( $order_id ){
$order = wc_get_order( $order_id );
$args = array(
'total_cost' => $order->get_total(),
'order_id' => $order_id,
'set_product_id' => 123
);
wp_register_script( 'checkout-script', get_stylesheet_directory_uri() . '/checkout-script.js', array(), false, true ); // Last parameter loads script in footer
wp_localize_script( 'checkout-script', 'checkout_script', $args );
wp_enqueue_script( 'checkout-script' );
}
add_action( 'woocommerce_thankyou', 'so_47117329_thankyou' );
My javascript file etheme.js is not loading on all my pages. I'm running on the newest version of wordpress and theme. The theme-functions file code is provided bellow. I've reuploaded my backup and still get this issue.
if(!function_exists('etheme_enqueue_styles')) {
function etheme_enqueue_styles() {
global $etheme_responsive;
$custom_css = etheme_get_option('custom_css');
if ( !is_admin() ) {wp_enqueue_style("fa",get_template_directory_uri().'/css/font-awesome.min.css');
wp_enqueue_style("bootstrap",get_template_directory_uri().'/css/bootstrap.min.css');
wp_enqueue_style("parent-style",get_template_directory_uri().'/style.css');
if($etheme_responsive)
wp_enqueue_style("responsive",get_template_directory_uri().'/css/responsive.css');
wp_enqueue_style("font-open-sans",et_http()."fonts.googleapis.com/css?family=Open+Sans:300,400,700,300italic");
wp_enqueue_style("font-roboto",et_http()."fonts.googleapis.com/css?family=Roboto:400,500,700,300&subset=latin,cyrillic-ext");
wp_enqueue_style('js_composer_front');
if($custom_css) {
wp_enqueue_style("custom",get_template_directory_uri().'/custom.css');}
$etheme_color_version = etheme_get_option('main_color_scheme');
if($etheme_color_version=='dark') {
wp_enqueue_style("dark",get_template_directory_uri().'/css/dark.css');}
$script_depends = array();
if(class_exists('WooCommerce')) {
$script_depends = array('wc-add-to-cart-variation');}
wp_enqueue_script('jquery');
wp_enqueue_script('modernizr', get_template_directory_uri().'/js/modernizr.js');
wp_enqueue_script('head', get_template_directory_uri().'/js/head.js');
if(class_exists('WooCommerce') && is_product())
wp_enqueue_script('zoom', get_template_directory_uri().'/js/zoom.js',array(),false,true);
wp_enqueue_script('etheme', get_template_directory_uri().'/js/etheme.js',$script_depends,false,true);
wp_localize_script( 'etheme', 'myAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'noresults' => __('No results were found!', ETHEME_DOMAIN)));}}}
add_action( 'wp_enqueue_scripts', 'etheme_enqueue_styles', 30);
Try adding this to your HTML contents:
<script language="javascript" type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
Also try alert('I'); to see if Javascript works.