Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
81.82% covered (warning)
81.82%
36 / 44
75.00% covered (warning)
75.00%
18 / 24
24.14% covered (danger)
24.14%
7 / 29
42.86% covered (danger)
42.86%
3 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
Analysis
81.82% covered (warning)
81.82%
36 / 44
75.00% covered (warning)
75.00%
18 / 24
24.14% covered (danger)
24.14%
7 / 29
42.86% covered (danger)
42.86%
3 / 7
99.57
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 curlErrorNumber
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 curlErrorInfo
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getIterator
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 fetch
86.49% covered (warning)
86.49%
32 / 37
81.25% covered (warning)
81.25%
13 / 16
13.64% covered (danger)
13.64%
3 / 22
0.00% covered (danger)
0.00%
0 / 1
38.56
 filterEmptyDataLine
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 isCurlCloseSupported
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2namespace Dbmi\Webservice\Analysis;
3
4use ArrayIterator;
5use IteratorAggregate;
6use Traversable;
7
8use Dbmi\Webservice\Quake\QuakeId;
9
10use Dbmi\Webservice\Contributor\ContributorData;
11use Fdsn\Webservices\Event\Structs\LatLon as DS_LatLon;
12
13/**
14 * Get analysis
15 */
16class Analysis implements IteratorAggregate{
17    private const templateUrlDataByContributor = 'https://emidius.mi.ingv.it/services/macroseismic/query?format=textmacro&includemdps=true&eventid=%s&contributor=%s';
18    private const templateUrlDataByContributorAndMdpId = 'https://emidius.mi.ingv.it/services/macroseismic/query?format=textmacro&includemdps=true&eventid=%s&contributor=%s&mdpsetid=%s';
19
20    private const curlCloceLatestPhpVersion = 7;
21    
22    private ContributorData $contributor;
23    private QuakeId $quakeId;
24
25    private array $localities = array();
26
27    private int $curlErrNum = 0;
28    private string $curlErrInfo = '';
29
30    public function __construct(ContributorData $contributor, QuakeId $quakeId){
31        $this->contributor = $contributor;
32        $this->quakeId = $quakeId;
33    }
34
35    public function curlErrorNumber(){ return $this->curlErrNum; }
36    public function curlErrorInfo(){ return $this->curlErrInfo; }
37
38    /**
39     * get all localities intensity
40     * 
41     * @return array locality intensity
42     */
43    public function getIterator():Traversable{ return new ArrayIterator($this->localities); }
44
45    /**
46     * find contributor based on quakeId
47     *
48     * @return int number of studies found
49     */
50    public function fetch():int{
51        $url = ( ! is_null ($this->contributor->mdpSetId()) ) 
52            ? sprintf(self::templateUrlDataByContributorAndMdpId, $this->quakeId->id(), $this->contributor->name(), $this->contributor->mdpSetId() )
53            : sprintf(self::templateUrlDataByContributor, $this->quakeId->id(), $this->contributor->name() );
54
55        $curlSession = curl_init();
56        curl_setopt_array($curlSession, array(
57            CURLOPT_URL         => $url,
58            CURLOPT_HEADER         => false,
59            CURLOPT_CUSTOMREQUEST    => 'GET',
60            CURLOPT_RETURNTRANSFER    => true,
61            CURLOPT_FAILONERROR     => true
62            )
63        );
64        $downloadedData = curl_exec($curlSession);
65
66        $this->curlErrNum = curl_errno($curlSession);
67        $this->curlErrInfo = curl_error($curlSession);
68        if ( $this->isCurlCloseSupported() )
69            curl_close($curlSession);
70
71        if(CURLE_OK != $this->curlErrNum){
72            error_log(sprintf("[%s] [CurlErr: %d] %s", __METHOD__, $this->curlErrNum, $this->curlErrInfo));
73            return -1;
74        }
75
76        $stringsData = preg_split("/\n/", $downloadedData);
77        $stringsArray = array_filter($stringsData, array($this, 'filterEmptyDataLine'));
78
79        if(0 == count($stringsArray)){
80            error_log(sprintf("[%s] No data\n'%s'", __METHOD__, $stringsData));
81            return 0;
82        }
83        
84        foreach($stringsArray as $data){    
85            $dataArray = str_getcsv($data, '|', "\"", "\\");
86
87            try{
88                $this->localities[] = new Locality(
89                    $dataArray[8],
90                    $dataArray[9],
91                    new DS_LatLon($dataArray[10], $dataArray[11]),
92                    new Intensity($dataArray[12])
93                );
94            } 
95            catch(\TypeError $e){
96                error_log(sprintf( "[%s] Skipping invalid data with error '%s'", __METHOD__, $e->getMessage() ));
97                continue;
98            }
99        }
100
101        return count($this->localities);
102    }
103
104    /**
105     * filter empty lines or comment lines (starting with #)
106     */
107    private function filterEmptyDataLine($data){
108        return !(preg_match('/^$/', $data) || preg_match("/^#/", $data));
109    }
110    /**
111     * Check if curl_close is still supported
112     * @return bool true is supported, false otherwise
113     */
114    private function isCurlCloseSupported():bool{ return PHP_MAJOR_VERSION <= self::curlCloceLatestPhpVersion; }
115
116}
117
118?>
119