最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - WP nonce invalid

programmeradmin0浏览0评论

Have a quick script to search for untranslated pages, and then returning a translate link. (Polylang makes a new post for a translation, which is then linked to the original.)

All is working well, except the nonce:

$url = admin_url('post-new.php?post_type=product&from_post=' . $ID . '&new_lang=' . $lang);

$nonce_url = wp_nonce_url($url);

Returns a beautifully formatted url, with an invalid nonce:

.php?post_type=product&from_post=2851&new_lang=nl&_wpnonce=fb63ac7002

The link in the admin panel reads exactly the same, but with a working nonce:

.php?post_type=product&from_post=2851&new_lang=nl&_wpnonce=c17b1a3a2a

I like to think Im alright with WP, but this is breaking my head. Does anyone have any sort of idea why it is generating invalid links??

Full code:

require_once('../../../wp-load.php');

$lang = $_POST['lang'];
if ($lang == 'nl') { $language = 'Dutch';}
elseif ($lang == 'pt') { $language = 'Portuguese';}
else { $language = 'Something is going awry, I dont know ' . $lang;}

echo '<h2>Missing ' . $language . ' translations</h2>';
// An array of all published WC_Product Objects
$products = wc_get_products( array( 'status' => 'publish', 'limit' => -1,'lang' => 'en', ) );

// Displaying the number of products in this array
echo '<p>Total number of products published: ' . sizeof( $products ) . '</p>';

// Loop through products and save some data using WC_Product and stuff in array
$tobearray = [];
$count = 0;
foreach ( $products as $product ){
    $ID = $product->get_id();
    $title = $product->get_title();

    if (!pll_get_post($ID, $lang)) {

                  $url = admin_url('post-new.php?post_type=product&from_post=' . $ID . '&new_lang=' . $lang);

                  $nonce_url = wp_nonce_url($url);
                      //wp_nonce_url( $url);  // Adding our nonce to the url with a unique id made from the expiry timestamp

        $addpostlink = '<a href="' . wp_nonce_url('/wp-admin/post-new.php?post_type=product&from_post=' . $ID . '&new_lang=' . $lang) . '" target="_blank"> click here</a>';


        $tobearray[] = ['ID' => $ID, 'Title' => $title, 'Link' => $addpostlink ];
        $count++;
        }
}
echo '<p>Number of Products that are missing their ' . $lang . ' translation: ' . $count . '</p>';
echo 'Posts that need a ' . $language . ' translation: ';

?>
<p>
    Click on the link in the table below to create a new translation.  After the link opens (its a bit slow, pls wait), just open the original English product to copy and paste the title and description so you can translate them.
</p>
<table border="1">
<tr><th>ID</th><th>Title</th><th>Link</th></tr> 
<?php foreach($tobearray as $row) {
  echo('<tr>');
  echo('<td>');
  echo(implode('</td><td>', $row));
  echo('</td>');
  echo('</tr>');
} ?>
</table>

Have a quick script to search for untranslated pages, and then returning a translate link. (Polylang makes a new post for a translation, which is then linked to the original.)

All is working well, except the nonce:

$url = admin_url('post-new.php?post_type=product&from_post=' . $ID . '&new_lang=' . $lang);

$nonce_url = wp_nonce_url($url);

Returns a beautifully formatted url, with an invalid nonce:

https://yaddayadda/wp-admin/post-new.php?post_type=product&from_post=2851&new_lang=nl&_wpnonce=fb63ac7002

The link in the admin panel reads exactly the same, but with a working nonce:

https://yaddayadda/wp-admin/post-new.php?post_type=product&from_post=2851&new_lang=nl&_wpnonce=c17b1a3a2a

I like to think Im alright with WP, but this is breaking my head. Does anyone have any sort of idea why it is generating invalid links??

Full code:

require_once('../../../wp-load.php');

$lang = $_POST['lang'];
if ($lang == 'nl') { $language = 'Dutch';}
elseif ($lang == 'pt') { $language = 'Portuguese';}
else { $language = 'Something is going awry, I dont know ' . $lang;}

echo '<h2>Missing ' . $language . ' translations</h2>';
// An array of all published WC_Product Objects
$products = wc_get_products( array( 'status' => 'publish', 'limit' => -1,'lang' => 'en', ) );

// Displaying the number of products in this array
echo '<p>Total number of products published: ' . sizeof( $products ) . '</p>';

// Loop through products and save some data using WC_Product and stuff in array
$tobearray = [];
$count = 0;
foreach ( $products as $product ){
    $ID = $product->get_id();
    $title = $product->get_title();

    if (!pll_get_post($ID, $lang)) {

                  $url = admin_url('post-new.php?post_type=product&from_post=' . $ID . '&new_lang=' . $lang);

                  $nonce_url = wp_nonce_url($url);
                      //wp_nonce_url( $url);  // Adding our nonce to the url with a unique id made from the expiry timestamp

        $addpostlink = '<a href="' . wp_nonce_url('/wp-admin/post-new.php?post_type=product&from_post=' . $ID . '&new_lang=' . $lang) . '" target="_blank"> click here</a>';


        $tobearray[] = ['ID' => $ID, 'Title' => $title, 'Link' => $addpostlink ];
        $count++;
        }
}
echo '<p>Number of Products that are missing their ' . $lang . ' translation: ' . $count . '</p>';
echo 'Posts that need a ' . $language . ' translation: ';

?>
<p>
    Click on the link in the table below to create a new translation.  After the link opens (its a bit slow, pls wait), just open the original English product to copy and paste the title and description so you can translate them.
</p>
<table border="1">
<tr><th>ID</th><th>Title</th><th>Link</th></tr> 
<?php foreach($tobearray as $row) {
  echo('<tr>');
  echo('<td>');
  echo(implode('</td><td>', $row));
  echo('</td>');
  echo('</tr>');
} ?>
</table>
Share Improve this question edited Sep 6, 2019 at 16:23 user2642724 asked Sep 6, 2019 at 15:45 user2642724user2642724 215 bronze badges 6
  • Nonces are per-user (and possibly per-user-session). Does the script run as the same user that's trying to use the link? – Rup Commented Sep 6, 2019 at 15:54
  • Well, its a plugin so I assumed it was run by the user logged into the admin section. I cant find anything in the codex about setting a user either... Would you have any idea how to do this? – user2642724 Commented Sep 6, 2019 at 16:00
  • 1 Can you tell us more about this script and how it's triggered? It is possible for things to run without any user, e.g. if it's running on a cron job, it's not clear what the script is though, it could be a WP CLI command, a Cron job, a standalone PHP file, etc. Why are you generating a nonce btw? And how is it being checked? I noticed there's no action specified for your nonce URL – Tom J Nowell Commented Sep 6, 2019 at 16:06
  • Full code added. It is a plugin file, the first page of which the (admin) user picks a language, and a POST variable is passed indicating the language. My little script then checks for products which require a translation and generates links to do so. – user2642724 Commented Sep 6, 2019 at 16:19
  • At first glance from code in /wp-admin/ that uses wp_nonce_url, you don't want the /wp-admin/ in the string that you pass to wp_nonce_url. i.e. '/wp-admin/' . wp_nonce_url('post-new.php?...') or admin_url(wp_nonce_url('post-new.php?...')). ... except now I've found some examples with admin_url or self_admin_url inside the wp_nonce_url. Maybe that's not it. I'd suggest you add trace to the wp_nonce_url and see what your version and the admin version are passing. – Rup Commented Sep 6, 2019 at 16:31
 |  Show 1 more comment

1 Answer 1

Reset to default 1

Found out what the problem was. Polylang plugin verifies the nonces, so you need to pass it the 'new-post-translation' arg.

The solution is: wp_nonce_url( $link, 'new-post-translation' );

it might help someone, but maybe no ;)

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论