jeudi 23 juin 2016

API calls in WordPress Plugin

I've got an issue I've been working on for several days, and I just don't know how best to go about fixing it. I'm creating a WordPress plugin that allows users to upload their entire GoodReads Library export.

I have a sample export of 12,000+ books. For each book on the spreadsheet, an API call is made to Amazon Books, Google Books, OpenLibrary, and more, to grab as much info as possible about the title, and then store in their MySql database.

The problem I'm having is that the script stops executing after about 2 minutes. I've tried to modify the PHP execution time limit from within the plugin, but it doesn't work.

I thought about trying a cron job, but that would require each user to provide a username/password to their hosting server, wouldn't it?

Also, I've played around with the PHP memory limits, but that doesn't seem to be the issue, it seems that execution time is the major limiter.

I'm new to both web service calls and on jobs, so I'm not sure how to go about this. The ultimate goal would be to get all 12,000+ titles in my sample spreadsheet reliably uploaded after making all the API calls I possibly can.

This is the last issue I need a good solution for and then my plugin can be released. I appreciate the help!!!

Here is the script I'm currently using to upload the titles:

<?php
require( $_SERVER['DOCUMENT_ROOT'].'/wp-load.php' );
ini_set('memory_limit', '-1');
ini_set('max_execution_time', 300);
global $wpdb;
str_replace(' ', '_', $_POST['table']);
$table_name = $wpdb->prefix .'wpbooklist_jre_'.$_POST['table'];
$table_name_options = $wpdb->prefix .'wpbooklist_jre_user_options';
$options_results = $wpdb->get_row("SELECT * FROM $table_name_options");
$selected_goodreads = $_POST['selected-goodreads'];
$book_title = null;
$author = null; 
$isbn = null;
$finished_yes = null;
$finished_no = null;
$book_signed_yes = null;
$book_signed_no = null;
$first_edition_yes = null;
$first_edition_no =null;
$year_finished = null;
$coverimage = null;
$pagenum = null;
$pubdate = null;
$publisher = null;
$category = null;
$description = null;
$notes = null;
$google_preview = null;
$itunespage = null;
$amazon_detail_page = null;

// Setting the overwrite or add to variable
if(isset($_POST['append'])){
    $upload_mode = 'append';
}else{
    $upload_mode = 'erase';
}

if($upload_mode == 'erase'){
    $delete = $wpdb->query("TRUNCATE TABLE $table_name");
}

$rows = array_map('str_getcsv', file(plugins_url('/uploads/'.$selected_goodreads, __FILE__ )));
$header = array_shift($rows);
$csv = array();
foreach ($rows as $row) {
  $csv[] = array_combine($header, $row);
}

//for each title that was returned...
foreach($csv as $indiv_book){
    sleep(1);
    set_time_limit(0);
    $amazon_array = array();
    $params = array();
    $s_array = array();
    $final_array = array();


    // Grabbing the data from the uploaded spreadsheet and setting some default variables
    if(strlen($indiv_book['ISBN13']) == 16){
        $isbn = substr($indiv_book['ISBN13'],2,13);
    } else if(strlen($indiv_book['ISBN10'] > 3)){
        $isbn = substr($indiv_book['ISBN10'],2,10);
    } else {
        $isbn = 'noisbn';
    }
    $goodreads_id = $indiv_book['Book Id'];
    $book_title = $indiv_book['Title'];
    $publisher = $indiv_book['Publisher'];
    $pubdate = $indiv_book['Year Published'];
    $author = $indiv_book['Author'];
    $notes = $indiv_book['My Review'];
    $pagenum = $indiv_book['Number of Pages'];
    $current_date = substr($indiv_book['Date Added'],0,4);
    $year_finished = substr($indiv_book['Date Read'],0,4);
    if(strlen($year_finished) > 1){
        $finished_yes = 'yes';
    } else {

    }
    $book_signed_no = "no";
    $first_edition_no = "no";


    // Begin Amazon Data Grab
    $region = 'com';
    $public_key = 'AKIAIIHVG3QSRVEDY4EQ';
    $private_key = 'hKRLT0aJ9bFBYpNg1uuQ2J19KYfizzAW0IyFvloF';
    $associate_tag = $options_results->amazonaff;

    // If there is no ISBN in the spreadsheet, search by title  
    if($isbn != 'noisbn'){           
    $params = array("Operation"=>"ItemLookup",
                "ItemId"=>$isbn,
                "ResponseGroup"=>"Large",
                "SearchIndex"=>"Books",
                "IdType"=>"ISBN"
          );
 } else {
    $params = array("Operation"=>"ItemSearch",
                "ResponseGroup"=>"Large",
                "SearchIndex"=>"Books",
                "Title"=> $book_title
            );

 }


$response = aws_signed_request($region, $params, $public_key, $private_key, $associate_tag, $version='2011-08-01');
$response = file_get_contents($response);
$xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA);

$json = json_encode($xml);
$amazon_array = json_decode($json,TRUE);

if($isbn == 'noisbn'){ 
    if(!empty($amazon_array['Items']['Item'][0]['ItemAttributes']['ISBN'])){
        $isbn = $amazon_array['Items']['Item'][0]['ItemAttributes']['ISBN'];
    } else {
        $isbn =  $amazon_array['Items']['Item']['ItemAttributes']['ISBN'];
    }

    if((strlen($isbn) < 10) || ($isbn == null) || ($isbn == '') || ($isbn == 0) || ($isbn == false)){ 
        if(!empty($amazon_array['Items']['Item'][0]['ItemAttributes']['EISBN'])){
            $isbn = $amazon_array['Items']['Item'][0]['ItemAttributes']['EISBN'];
        } else {
            $isbn =  $amazon_array['Items']['Item']['ItemAttributes']['EISBN'];
        }
    }


        // Now that we have isbn, make another request based on isbn    
        $params = array("Operation"=>"ItemLookup",
                        "ItemId"=>$isbn,
                        "ResponseGroup"=>"Large",
                        "SearchIndex"=>"Books",
                        "IdType"=>"ISBN"
            );


    $response = aws_signed_request($region, $params, $public_key, $private_key, $associate_tag, $version='2011-08-01');
    $response = file_get_contents($response);
    $xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA);

    $json = json_encode($xml);
    $amazon_array = json_decode($json,TRUE);
}



// Get book image
if(!empty($amazon_array['Items']['Item'][0]['LargeImage']['URL'])){
    $coverimage = $amazon_array['Items']['Item'][0]['LargeImage']['URL'];
}else {
    $coverimage = $amazon_array['Items']['Item']['LargeImage']['URL'];
}

// Get page number if spreadsheet was blank
if((strlen($indiv_book['Number of Pages']) < 1) || (strlen($indiv_book['Number of Pages']) == 0) || ($indiv_book['Number of Pages'] == null) || ($indiv_book['Number of Pages'] == '') ){
    if(!empty($amazon_array['Items']['Item'][0]['ItemAttributes']['NumberOfPages'])){
        $pagenum = $amazon_array['Items']['Item'][0]['ItemAttributes']['NumberOfPages'];
} else {
        $pagenum =  $amazon_array['Items']['Item']['ItemAttributes']['NumberOfPages'];
}
}

// Get pubdate if spreadsheet was blank
if((strlen($indiv_book['Year Published']) < 1) || (strlen($indiv_book['Year Published']) == 0) || ($indiv_book['Year Published'] == null) || ($indiv_book['Year Published'] == '') ){
    if(!empty($amazon_array['Items']['Item'][0]['ItemAttributes']['PublicationDate'])){
        $pubdate = $amazon_array['Items']['Item'][0]['ItemAttributes']['PublicationDate'];
} else {
        $pubdate =  $amazon_array['Items']['Item']['ItemAttributes']['PublicationDate'];
}

$pubdate = substr(0,4,$pubdate);
}

// Get publisher if spreadsheet was blank
if((strlen($indiv_book['Publisher']) < 1) || (strlen($indiv_book['Publisher']) == 0) || ($indiv_book['Publisher'] == null) || ($indiv_book['Publisher'] == '') ){
    if(!empty($amazon_array['Items']['Item'][0]['ItemAttributes']['Publisher'])){
        $publisher = $amazon_array['Items']['Item'][0]['ItemAttributes']['Publisher'];
} else {
        $publisher =  $amazon_array['Items']['Item']['ItemAttributes']['Publisher'];
}
}

// Get description
if(!empty($amazon_array['Items']['Item'][0]['EditorialReviews']['EditorialReview']['Content'])){
    $description = $amazon_array['Items']['Item'][0]['EditorialReviews']['EditorialReview']['Content'];
} else if(!empty($amazon_array['Items']['Item']['EditorialReviews']['EditorialReview']['Content'])) {
    $description = $amazon_array['Items']['Item']['EditorialReviews']['EditorialReview']['Content'];
} else if(!empty($amazon_array['Items']['Item']['EditorialReviews']['EditorialReview'][0]['Content'])){
        $description = $amazon_array['Items']['Item']['EditorialReviews']['EditorialReview'][0]['Content'];
} else {

}

if(!empty($amazon_array['Items']['Item'][0]['DetailPageURL'])){
    $amazon_detail_page = $amazon_array['Items']['Item'][0]['DetailPageURL'];
} else {
    $amazon_detail_page  = $amazon_array['Items']['Item']['DetailPageURL'];
}

$final_array = array(
                'book_title' => $book_title, 
                'author' => $author,
                'isbn' => $isbn,
                'finishedyes' => $finished_yes,
                'finishedno' => $finished_no,
                'booksignedyes' => $book_signed_yes,
                'booksignedno' => $book_signed_no,
                'firsteditionyes' => $first_edition_yes,
                'firsteditionno' => $first_edition_no,
                'yearfinished' => $year_finished,
                'coverimage' => $coverimage,
                'pagenum' => $pagenum,
                'pubdate' => $pubdate,
                'publisher' => $publisher,
                'category' => htmlspecialchars($category),
                'description' =>  htmlspecialchars_decode($description),
                'notes' => htmlspecialchars_decode(htmlspecialchars($notes)),
                'googlepreview' => $google_preview,
                'itunespage' => $itunespage,
                'amazondetailpage' => $amazon_detail_page
                );

                $s_array = array( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s','%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s');


$wpdb->insert( $table_name,  $final_array, $s_array);

$amazon_array = null;  
unset($amazon_array);

$params = null;  
unset($params);

$s_array = null;  
unset($s_array);

$final_array = null;  
unset($final_array);

$response = null;  
unset($response);

$xml = null;  
unset($xml);

$json = null;  
unset($json);

}


function aws_signed_request($region, $params, $public_key, $private_key, $associate_tag=NULL, $version='2011-08-01')
{

// some paramters
$method = 'GET';
$host = 'webservices.amazon.'.$region;
$uri = '/onca/xml';

// additional parameters
$params['Service'] = 'AWSECommerceService';
$params['AWSAccessKeyId'] = $public_key;
// GMT timestamp
$params['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
// API version
$params['Version'] = $version;
if ($associate_tag !== NULL) {
    $params['AssociateTag'] = $associate_tag;
}

// sort the parameters
ksort($params);

// create the canonicalized query
$canonicalized_query = array();
foreach ($params as $param=>$value)
{
$param = str_replace('%7E', '~', rawurlencode($param));
    $value = str_replace('%7E', '~', rawurlencode($value));
    $canonicalized_query[] = $param.'='.$value;
}
$canonicalized_query = implode('&', $canonicalized_query);

// create the string to sign
$string_to_sign = $method."\n".$host."\n".$uri."\n".$canonicalized_query;

// calculate HMAC with SHA256 and base64-encoding
$signature = base64_encode(hash_hmac('sha256', $string_to_sign, $private_key, TRUE));

// encode the signature for the request
$signature = str_replace('%7E', '~', rawurlencode($signature));

// create request
$request = 'http://'.$host.$uri.'?'.$canonicalized_query.'&Signature='.$signature;

return $request;
}   


?>



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire