0

I'm currently working on my first Wordpress plugin a I want to get JSON Data from a Webserver via a GET request. I already tried some code like this: https://stackoverflow.com/a/36780287/4460483 but it's not what I'm looking for.

Also jquery tells me: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

So the problem is that the data somehow doesn't load fast enough and the page can't load. The reason is that you need to directly return a result for a shortcode, right? But I guess that takes too much time. So what is the best way to make GET requests without freezing the thread building the page (in PHP)? Is there somehow Events to do something like that?

My current code looks somehow like this:

function stats_shortcode($atts)
{
  $attributes = shortcode_atts(array(
      'player_name' => 'Default'
   ),$atts);
  extract($atts);

  $url = 'https://url/to'.$attributes['playername'];
  $mh = curl_multi_init();

  // Build the individual requests, but do not execute them
  $chs = [];
  $chs['ID0001'] = curl_init($url);

  foreach ($chs as $ch) {
      curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,  // Return requested content as string
        CURLOPT_SSL_VERIFYPEER => false,         // Don't save returned headers to result
        CURLOPT_CONNECTTIMEOUT => 10,    // Max seconds wait for connect
        CURLOPT_TIMEOUT => 20,           // Max seconds on all of request
        CURLOPT_USERAGENT => 'Robot YetAnotherRobo 1.0',
      ]);

      // Add every $ch to the multi-curl handle
      curl_multi_add_handle($mh, $ch);
  }

  // Execute all of queries simultaneously, and continue when ALL OF THEM are complete
  $running = null;
  do {
      curl_multi_exec($mh, $running);
  } while ($running);

  // Close the handles
  foreach ($chs as $ch) {
      curl_multi_remove_handle($mh, $ch);
  }
  curl_multi_close($mh);

  $profile = json_decode($responses['ID0001']);

  return "<div><span>$profile->{'data'}</span></div>"

}

function stat_shortcodes_init()
{
    add_shortcode('stats', 'stats_shortcode');
    wp_register_style('StatStylesheet', plugins_url('styles.css', __FILE__));
    wp_enqueue_style('StatStylesheet');
}

add_action('init', 'stat_shortcodes_init');


This somehow works local (when I wait long enough), but not on my server.

Community
  • 1
  • 1
Drayke
  • 367
  • 1
  • 3
  • 14
  • Post your code! Id like to see your jquery and php code. I dont know what you mean by return a result for a shortcode. In my plugin, the shortcode just causees certain html and javascript to load on the page and once the page is ready the javascript starts to fire off ajax requests and populates the page. – victor Apr 04 '17 at 16:23
  • @victor I added the code. My goal is it to display stats of a player. And I just wanted to use a shortcode for that. In the Tutorials I used to learn, it worked like you can see in my code. (but your version sounds better) – Drayke Apr 04 '17 at 16:40
  • this is probably not your problem but I found a type: $profile = json_decode($responses['ID0001']); return "
    $profil->{'data'}
    "
    – victor Apr 04 '17 at 17:05
  • are the php script timeout times the same in your local environment and on the server? You said it works locally when you wait long enough so im just wondering if all those requests are taking too long on your server. – victor Apr 04 '17 at 17:06
  • Yes they are the same. But I don't want the user to wait 20s to let the page appear. – Drayke Apr 04 '17 at 17:16
  • if you dont want to wait 20s for the screen to appear then I suggest you write some html and javascript to handle making the network calls and use the wordpress plugin to just load the html, js, and css files needed. – victor Apr 04 '17 at 17:24
  • @victor Could you maybe explain this a littlebit further? I think this could be the solution I'm looking for. – Drayke Apr 04 '17 at 17:26

1 Answers1

1

so create an html file that looks like this (no body or head tags, its more of an html template)

<div id="stats"></div>

Then you need a javascript file to populate this template:

jQuery(document).ready(
  jQuery.ajax({
    url: url,
    type: 'GET',
    success: function (response) {
        // take the response and populate the div with id="stats"
    },
    error: function (response) {
        console.log(response);
    }
});
)

and finally, here is the WordPress plugin:

   <?php
/*
Plugin Name: General Widget 
Plugin URI: 
Description: 
Author:
Version: 1
Author URI:
*/
// register widget
add_action('widgets_init', create_function('', 'return register_widget("General_Widget");'));

class General_Widget extends WP_Widget {

// constructor
    function General_Widget() {
        // Give widget name here
        parent::WP_Widget(false, $name = __('General Widget', 'wp_widget_plugin'));

        // link the style sheet for the widget
        add_action( 'wp_enqueue_scripts', array($this,'add_styles'));  
        // link javascript file
        add_action( 'wp_enqueue_scripts', array($this,'add_scripts'));  
        // register the shortcode
        // TODO: 
        add_shortcode('INSERT SHORTCODE HERE', array($this, 'shortcode'));
    }

    // function that enqueues the necessary javascript files
    function add_scripts() {    
    // TODO:    
        // NOTE this is risky, might mess with your theme.
        wp_deregister_script( 'jquery' ); // we will use our own versions of jquery
        wp_deregister_script( 'jquery-migrate' );
        global $post;
        // only register and add scripts for this widget if the widget is active or if the post has a shortcode
        if(has_shortcode($post->post_content, 'INSERT SHORTCODE HERE') ||  is_active_widget( false, false, $this->id_base, true )) {
            // register the different scripts
            wp_register_script('jqueryMin', plugins_url('js/lib/jquery-2.2.4.min.js', __FILE__), array(), false, false); // https://developer.wordpress.org/reference/functions/wp_register_script/

            // add them to document
            wp_enqueue_script('jqueryMin');
        }
    }

    // enqueues the stylesheet
    function add_styles() {
        // TODO: 
        global $post;
        if(has_shortcode($post->post_content, 'INSERT SHORTCODE HERE') ||  is_active_widget( false, false, $this->id_base, true )) {
            // register the different style sheets
            wp_register_style('bootstrapMinStyle', plugins_url('css/lib/bootstrap.min.css', __FILE__), array(), false, "all"); // https://codex.wordpress.org/Function_Reference/wp_register_style
            wp_register_style('commonStyle', plugins_url('css/common.css', __FILE__), array(), false, "all"); // https://codex.wordpress.org/Function_Reference/wp_register_style
            $arrCoreStyles = array('bootstrapMinStyle', 'commonStyle');

            wp_register_style('quoteStyle', plugins_url('css/quote.css', __FILE__),$arrCoreStyles, false, "all"); // https://codex.wordpress.org/Function_Reference/wp_register_style
            // add style sheet and all of its dependencies
            wp_enqueue_style('quoteStyle');
        }
    }

// widget form creation. This handles the form that the wordpress admin sees when they add the widget to a widget area
    function form($instance) {
    }

    // updates the data stored in the widget when wordpress admin adds widget
    function update($new_instance, $old_instance) {
    }

    // gives the widget shortcode functionality
    function shortcode($atts) {
        $args = shortcode_atts( array(), $atts );
        $this->add_to_args($args);
        $this->display($args);
    }

// displays the widget to the client.
    function widget($args, $instance) {
        $this->add_to_args($args);
        $this->display($args);
    }

// use this to add fields to args before we display
    private function add_to_args(& $args) {
        // TODO: 
        $args['customWidgetHTML'] = "html/NAME OF HTML TEMPLATE.html"; 
    }

// this is an additional function, not inherited from WP_Widget. It is used for displaying html to
// client. Is called by both widget() and shortcode()
    private function display($args) {
        extract($args); 
        // TODO: 
        wp_enqueue_script('quoteJS'); // we dont want this in the header so we just enqueue it here
        echo $before_widget;
        include(plugin_dir_path(__FILE__) . $customWidgetHTML);
        echo $after_widget; 
    }
}
?>
victor
  • 802
  • 7
  • 12