mardi 27 octobre 2015

Returning a View from a Model in Laravel 5

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