0

I am currently working on a plugin which sends WP posts to an user-specified REST API, every time a post is published.

The problem: I don't want to send every post, I'd rather like the user to choose whether to send it, or not (default: don't send).

So my plugin PHP file looks like this (excerpt):

function post_published_api_call( $ID, $post) {

    $url = get_option('api_url', array('plugin_text_string' => DEFAULT_API_URL))['plugin_text_string'];
    $title = $post->post_title;
    $content = wp_post_to_html($post->post_content);

    $post_data = array(
        'status' => 'publish',
        'title' => $title,
        'content' => $content
    );

    $json_post = json_encode($post_data);

    $data = wp_remote_post($url, array(
        'headers' => array('Content-Type' => 'application/json; charset=utf-8'),
        'body' => $json_post,
        'method' => 'POST'
    ));
}
add_action( 'publish_post', 'post_published_api_call', 10, 2);

wp_remote_post (or better: the whole post_published_api_call function) should only fire, if a custom button in TinyMCE is pressed/activated.

My Custom TinyMCE Editor Button (pb_button.js):

(function() {

tinymce.create('tinymce.plugins.pboerse', {

    init : function(ed, url) {
        var state;

        ed.addButton('pb_button1', {
            text : 'PB',
            title : 'Publish on Projektboerse?',
            cmd : 'pb_button1',

            onclick: function () {


            },

            onpostrender: function() {
                var btn = this;
                ed.on('pb_button1', function(e) {
                    btn.active(e.state);
                });
            }
        });



        ed.addCommand('pb_button1', function() {

            state = !state; /* Switching state */
            ed.fire('pb_button1', {state: state});

            if (state){
                /* Button active */
                var request = new XMLHttpRequest();
                request.open('POST', 'projektboerse.php', true);
                request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                request.send('mydata='+state);
            }
            else {
                /* Button inactive */
            }

        });

    }
});

// Register plugin
tinymce.PluginManager.add( 'pboerse', tinymce.plugins.pboerse );
})();

I know about the difficulties in exchanging states/variables between a server side language like PHP and a client side language like JavaScript.

I googled a lot about AJAX but a problem remains: I can get the button state via the following code

foo = isset($_POST['mydata']);

if (isset($_POST['mydata'])){
   $GLOBALS['foo'] = $_POST['mydata'];
   echo $foo;
   wp_die();
}

but the button state only lives inside the if statement because I guess the rest of the plugin still got the initial default value (which is an empty string).

I tried using the if-block inside the post_published_api_call function, but at this time the $_POST variable seems to be overwritten by wordpress, and so $_POST['mydata'] results in an empty string.

How can I check for the button state inside the post_published_api_call function? Is it possible?

Thanks in advance!

0

I'm not sure you can do it directly using TinyMCE because it's just an editor that modifies the content of the post being edited and does not affect the save operation itself. However, there's a workaround.

The Workaround:

  1. Add a hidden field to the editing page.
  2. Modify it using the TinyMCE button
  3. Read it in post_published_api_call

Adding the field

As mentioned here, using post_submitbox_misc_actions hook you can add a field to the 'Publish' metabox. In your case you will add a hidden one as follows:

add_action( 'post_submitbox_misc_actions', 'wpse325418_my_custom_hidden_field' );
function wpse325418_my_custom_hidden_field() {
    echo "<input id='i-am-hidden' name='publish-to-somewhere' type='hidden' />";
}

The TinyMCE button

The button will have one purpose, to set/clear the hidden field. Assuming your JS code is working, I'll just modify the addCommand part of it:

    ed.addCommand('pb_button1', function() {

        state = !state; /* Switching state */
        ed.fire('pb_button1', {state: state});

        if (state){
            /* Button active */
            document.getElementById("i-am-hidden").value = "1";
        }
        else {
            /* Button inactive */
            document.getElementById("i-am-hidden").value = "0";
        }

    });

Reading the field

Here we will modify your post_published_api_call function to act based on the value of our hidden field:

function post_published_api_call( $ID, $post) {
    if(!isset($_POST['publish-to-somewhere'])) return;
    if($_POSt['publish-to-somewhere'] == '0') return;

    $url = get_option('api_url', array('plugin_text_string' => DEFAULT_API_URL))['plugin_text_string'];
    $title = $post->post_title;
    $content = wp_post_to_html($post->post_content);

    $post_data = array(
        'status' => 'publish',
        'title' => $title,
        'content' => $content
    );

    $json_post = json_encode($post_data);

    $data = wp_remote_post($url, array(
        'headers' => array('Content-Type' => 'application/json; charset=utf-8'),
        'body' => $json_post,
        'method' => 'POST'
    ));
}
add_action( 'publish_post', 'post_published_api_call', 10, 2);
  • Works like a charm after adding a default value for the hidden field (otherwise the button value is unset until the button is pressed at least one time). Thank you! – styx Jan 13 at 9:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.