My Controller
creates an instance of Class, SoapWrapper.php
, which contains a function that retrieves some data from a Web Service. As the Web Service only allows you to gather 100 records per query, I am finding out the total number of records for a query and then looping and calling the Web Service query every 100 records to get all the data.
To give some kind of feedback to the user that the request is being processed (a loading screen of sorts), I would like to return a View
which displays an HTML
box with some text that says Loading record x of y
, where y
is the total number of records, and x
is updated at each iteration of the loop.
Here is the current Model
, SoapWrapper.php
:
<?php namespace App\Models;
use SoapClient;
use Illuminate\Http\RedirectResponse;
use Redirect;
class SoapWrapper {
// SOAP exchange for WoS authentication
public $auth_client;
public $auth_response;
// SOAP exchange for WoS search
public $search_client;
public $search_response;
// number of records found
public $len;
// XML data to send as SOAP Request to WoS
public $data;
// array to store records
public $records = [];
// function to iterate and store all relevant data returned from SOAP exchange
public function iterateWosSearch($submit) {
// variable to store average time/record retrieval (based on calculations)
$avg = 0.08;
// create a variable to store time for loading screen
$timeDecimal = (round((($submit->len)*$avg), 2));
// create an array to represent citation values to ignore, i.e. not interested
// in any publications with less than 4 citations
$ignore = array(0, 1, 2, 3);
// create a counter variable to use for progress bar
$counter = 1;
// turn time into readable format (mins & secs, rather than just secs)
if ($timeDecimal > 59.99) {
$minutes = round(($timeDecimal/60), 0, PHP_ROUND_HALF_DOWN);
while ($timeDecimal > 59.99) {
$timeDecimal -= 60;
$seconds = round($timeDecimal, 0);
};
} else {
$minutes = 0;
$seconds = round($timeDecimal, 0);
};
// iterate through all records, perform search for each 100 records (max per call)
// and tabulate data
for ($i = 1; $i <= ($submit->len); $i+=100) {
// set search parameters for current iteration (first record = 1, 101, 201, 301 etc.)
$submit->data['retrieveParameters']['firstRecord'] = $i;
// gather search response for current iteration
try {
$submit->search_response = $submit->search_client->search($submit->data);
} catch (Exception $e) {
echo $e->getMessage();
};
// turn Soap Client object from current response into XML element
$xml = simplexml_load_string($submit->search_response->return->records);
// save variable names for citations, country and publication year
$citations = "";
$pubyear = "";
$country = "";
// iterate through current data set and store to $records array
foreach($xml->REC as $record) {
// create authors array for this REC data
$authors = [];
return View::make('loading', array('minutes' => $minutes, 'seconds' => $seconds, 'counter' => $counter));
// authors
foreach($record->static_data->summary->names->name as $thisAuthor) {
array_push($authors, $thisAuthor->full_name);
}
// country (if exists)
if (isset($record->static_data->item->reprint_contact->address_spec->country)) {
$country = (string)$record->static_data->item->reprint_contact->address_spec->country;
} else {
$country = "";
};
// set current publication year
$pubyear = (string)$record->static_data->summary->pub_info->attributes()->pubyear;
// number of citations, if 0-3 ($ignore array) then 'break' out of loop entirely
if (!in_array($record->dynamic_data->citation_related->tc_list->silo_tc->attributes(), $ignore)) {
$citations = (string)$record->dynamic_data->citation_related->tc_list->silo_tc->attributes();
} else {
// break from both loops
break 2;
};
// for this iteration map all the values recorded into a temporary array variable,
// $aRecord (equivalent to one row of data in table)
$arecord = [
"authors" => $authors,
"ID" => "",
"pubyear" => $pubyear,
"country" => $country,
"citations" => $citations
];
// pass the data from this iteration into the array variable '$records',
// after all iterations, each element in $records will be a single
// record or row of data for a single journal
array_push($submit->records, $arecord) ;
}
// increment for next record
$counter+=100;
}
}
};
Then the View
called loading
would be called at each iteration of the loop, return the estimated time the query will take by passing in <?php echo $minutes ?>
, and the same for seconds, and the current value of $counter
to reflect which set of records it's currently processing:
<p>Loading record <?php echo $counter ?> of <?php echo $len ?></p>
Is it possible to return a View
from within a Model
? I'm not sure how else I can create a 'loading' page for this.
via Chebli Mohamed
Aucun commentaire:
Enregistrer un commentaire