1

I am embarking on converting my PHP script, which calls a news search API to pull down news stories, in to a WordPress plugin. It's early days, I only really have the plugin header so far. I will strip out print_r echos later.

When I activate the plugin, the top of the page returns:

Plugin could not be activated because it triggered a fatal error

Starting... Initialising array and object... Polling API... Fatal error: Call to a member function listStories() on a non-object in /home/mysite/public_html/wp-content/plugins/cxt-user-quotes/cxt-user-quotes.php on line 43

Line 43 is $result = $api_instance->listStories($opts);

The API code is included with require_once(__DIR__ . '/vendor/autoload.php');

Is it failing to see the listStories function from the API file? Is it that $result or $api_instance need to be initialised?

Important to note that the code works fine when executed through PHP on the command line - php myscript.php - just not within the WordPress plugin.

Possibly related - what should I know about hooks and actions in this regard? Maybe this has something to do with execution order?

The while(true) loop at the bottom means that this would call the function fetch_new_stories on an infinite loop at 60-second intervals.

<?php
/**
 * Plugin Name: News Monitor
 * Description: Finds and ingests citations from news media.
 * Version: 1.0.0
 */



 require_once(__DIR__ . '/vendor/autoload.php');




 // Fetch new stories

 function fetch_new_stories($opts){

    // print_r("-----------\n");

   global $api_instance;

   print_r("Initialising array and object...\n\n");
   // Initialise array
   $fetched_stories = [];
   // Initialise object
   $stories = NULL;

   // Whether $stories is empty or not
   while (is_null($stories) || count($stories) > 0) {
     try {
       // Poll the API's Stories (listStories) endpoint and get result
       print_r("Polling API...\n\n");
       $result = $api_instance->listStories($opts);
       // For each story (addition from standard Aylien code)
       for($i = 0; $i < sizeof($result->getStories()); $i++){
         // Echo the headline
         print_r($result->getStories()[$i]->getSource()->getName() . ": " . $result->getStories()[$i]->getTitle() . "\n\n");
       }
     }
       // Error handling
       catch (Exception $e) {
       // Get status code
       $code = $e->getResponseObject()->getErrors()[0]->getStatus();
       // Slow down
       if ($code == '429'){
         print_r("Usage limit are exceeded. Wating for 60 seconds...\n");
         sleep(60);
         continue;
   }
 }

     // Get all "stories" from the query result
     $stories = $result->getStories();
     // Add each story sequentially in to $fetched_stories array
     $fetched_stories = array_merge($fetched_stories, $stories);
     // Pagination stuff
     $opts['cursor'] = $result->getNextPageCursor();

     // Count both new stories from this query and total stories
     // print_r(sprintf("Fetched %d stories. Total story count so far: %d\n", count($stories), count($fetched_stories)));
     print_r(sprintf("Fetched %d stories.\n\n", count($stories)));
   }

   // Pass fetched stories
   return $fetched_stories;
 }




 // Configure API key authorization: app_id
 Aylien\NewsApi\Configuration::getDefaultConfiguration()->setApiKey('X-AYLIEN-NewsAPI-Application-ID', 'xxxxxxxx');

 // Configure API key authorization: app_key
 Aylien\NewsApi\Configuration::getDefaultConfiguration()->setApiKey('X-AYLIEN-NewsAPI-Application-Key', 'xxxxxxxxxxxxxxxxxxxxxxxxx');

 $api_instance = new Aylien\NewsApi\Api\DefaultApi();





 // Query
 $params = array(
   'title' => 'Trump',
   'published_at_start' => 'NOW-1HOUR',
   'published_at_end' => 'NOW',
   'language' => ['en'],
   'per_page' => 50,
   'sort_by' => 'published_at',
   'sort_direction' => 'desc'
 );






 // Infinite loop

 while(true){

    // For each WordPress user {

        print_r("Starting...\n");

        // Fetch new stories from function
        $stories = fetch_new_stories($params);

        print_r("************\n\n");
        // Count stories published during window
        print_r(sprintf("Summary:\n\nPeriod %s to %s: Fetched %d stories\n", $params['published_at_start'], $params['published_at_end'], count($stories)));

        if (count($stories) > 0){
            // Add 10 seconds to last fetched time
            $lastFetchedAt = $stories[0]->getPublishedAt()->add(new DateInterval('PT10S'));

            $params['cursor'] = '*';
            $params['published_at_start'] = $lastFetchedAt->format('Y-m-d\TH:i:s\Z');
    }

        print_r("Sleeping for 60 seconds until next poll...\n\n");
        print_r("************\n\n");
        // print_r("-----------\n\n");

        sleep(60);

    // }
 }
 ?>
  • I figured out that I needed to place the while(true) loop, and the API query $params, inside a function and hook that for WordPress to execute it, am I right? So I did function infinite_loop() and add_action( 'init', 'infinite_loop' ); This makes listStories() okay - I successfully saw the plugin echo API results in the back-end. This prompts a bigger question - is it wise to put this on a 60-second infinite loop inside the plugin? Does this then get executed on every page load? I just want it left running in the background, once. Should I use a cron or is there an attractive method? – Robert Andrews Nov 13 '17 at 12:50

Your Answer

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

Browse other questions tagged or ask your own question.