Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
Total | |
90.00% |
54 / 60 |
|
90.48% |
38 / 42 |
|
35.29% |
12 / 34 |
|
77.78% |
7 / 9 |
CRAP | |
0.00% |
0 / 1 |
MultiInstance | |
90.00% |
54 / 60 |
|
90.48% |
38 / 42 |
|
35.29% |
12 / 34 |
|
77.78% |
7 / 9 |
180.05 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
curlErrorNumber | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
curlErrorInfo | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setPreferred | |
100.00% |
6 / 6 |
|
100.00% |
6 / 6 |
|
25.00% |
1 / 4 |
|
100.00% |
1 / 1 |
6.80 | |||
getIterator | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
findBestContributorByAnalysisType | |
83.33% |
10 / 12 |
|
88.24% |
15 / 17 |
|
17.65% |
3 / 17 |
|
0.00% |
0 / 1 |
43.75 | |||
fetch | |
100.00% |
19 / 19 |
|
100.00% |
4 / 4 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
3 | |||
keepOnlyRowsWithMdpSet | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
findContributors | |
77.78% |
14 / 18 |
|
80.00% |
8 / 10 |
|
16.67% |
1 / 6 |
|
0.00% |
0 / 1 |
19.47 |
1 | <?php |
2 | namespace Dbmi\Webservice\Contributor; |
3 | |
4 | use ArrayIterator; |
5 | use IteratorAggregate; |
6 | use Traversable; |
7 | |
8 | use Dbmi\Webservice\Quake\IdStruct as DS_QuakeId; |
9 | use Dbmi\Webservice\Contributor\SingleInstance as Contributor; |
10 | use Dbmi\Webservice\Contributor\Struct as DS_Contributor; |
11 | |
12 | /** |
13 | * Get contributors |
14 | */ |
15 | class MultiInstance implements IteratorAggregate{ |
16 | private const templateUrl = 'https://emidius.mi.ingv.it/services/macroseismic/query?eventid=%s&includeallmdpsets=true&format=textmacro'; |
17 | private const minValidResponseLines = 2; |
18 | |
19 | private DS_QuakeId $quakeId; |
20 | private array $details = array(); |
21 | |
22 | private array $contributors = array(); |
23 | |
24 | private int $curlErrNum = 0; |
25 | private string $curlErrInfo = ''; |
26 | |
27 | |
28 | public function __construct(DS_QuakeId $quakeId){ |
29 | $this->quakeId = $quakeId; |
30 | } |
31 | |
32 | public function curlErrorNumber(){ return $this->curlErrNum; } |
33 | public function curlErrorInfo(){ return $this->curlErrInfo; } |
34 | |
35 | /** |
36 | * string $contributor set already choose contributor |
37 | * |
38 | * @return bool TRUE contributor found, false otherwise |
39 | */ |
40 | public function setPreferred(DS_Contributor $contributor):bool{ |
41 | $found = false; |
42 | foreach($this->contributors as $elem){ |
43 | $elem->setPreferred( $elem->details()->name() == $contributor->name() ); |
44 | if( ! $found ) |
45 | $found = ($elem->details()->name() == $contributor->name()); |
46 | } |
47 | return $found; |
48 | } |
49 | |
50 | /** |
51 | * get all contributors |
52 | * |
53 | * @return array array of strings with the found contributors |
54 | */ |
55 | public function getIterator():Traversable{ return new ArrayIterator($this->contributors); } |
56 | |
57 | /** |
58 | * get the "best" contributor based an array of analysis type |
59 | * |
60 | * @param array $analysisName find the contributor with the analysis preferred based |
61 | * on array of names, sorted by preference (for example: array('MCS', 'EMS', ...) |
62 | * @return Dbmi\Webservice\Contributor\SingleInstance the Contributor found or null |
63 | */ |
64 | public function findBestContributorByAnalysisType(array $analysisNames):?Contributor { |
65 | if ( empty($analysisNames) ) |
66 | return null; |
67 | |
68 | $bestContributor = null; |
69 | foreach($analysisNames as $name){ |
70 | foreach($this->contributors as $contributor){ |
71 | //same analysis and isPreferred -> it's the best |
72 | if( $contributor->analisysExists($name) && $contributor->isPreferred() ) |
73 | return $contributor; |
74 | |
75 | //same analysis -> i can take it but i loop for a better solution (maybe preferred is later...) |
76 | if( $contributor->analisysExists($name) ) |
77 | $bestContributor = $contributor; |
78 | } |
79 | |
80 | //if a contributor is found, i'll get it before instead search it in other analysis |
81 | if( ! is_null($bestContributor) ) |
82 | return $bestContributor; |
83 | } |
84 | |
85 | return $bestContributor; |
86 | } |
87 | |
88 | /** |
89 | * find contributor based on quakeId |
90 | * |
91 | * @return int number of studies found |
92 | */ |
93 | public function fetch():int{ |
94 | $curlSession = curl_init(); |
95 | curl_setopt_array($curlSession, array( |
96 | CURLOPT_URL => sprintf(self::templateUrl, $this->quakeId->id()), |
97 | CURLOPT_HEADER => false, |
98 | CURLOPT_CUSTOMREQUEST => 'GET', |
99 | CURLOPT_RETURNTRANSFER => true, |
100 | CURLOPT_FAILONERROR => true |
101 | ) |
102 | ); |
103 | $downloadedData = curl_exec($curlSession); |
104 | |
105 | $this->curlErrNum = curl_errno($curlSession); |
106 | $this->curlErrInfo = curl_error($curlSession); |
107 | curl_close($curlSession); |
108 | |
109 | if(CURLE_OK != $this->curlErrNum){ |
110 | // @codeCoverageIgnoreStart |
111 | error_log(sprintf("[%s] [CurlErr: %d] %s", __METHOD__, $this->curlErrNum, $this->curlErrInfo)); |
112 | return -1; |
113 | // @codeCoverageIgnoreEnd |
114 | } |
115 | |
116 | $rows = preg_split("/\n/", trim($downloadedData)); |
117 | |
118 | if( count($rows) < self::minValidResponseLines ){ //header+data |
119 | error_log(sprintf("[%s] Invalid contributors response, see below\n'%s'", __METHOD__, $downloadedData)); |
120 | return -2; |
121 | } |
122 | |
123 | return $this->findContributors($downloadedData); |
124 | } |
125 | |
126 | /** |
127 | * filter rows with no mdpset |
128 | */ |
129 | private function keepOnlyRowsWithMdpSet($row){ return preg_match('@.*mdpset/(.*)/\d*@', $row); } |
130 | |
131 | /** |
132 | * divide found contributors by intensity-type of study |
133 | */ |
134 | private function findContributors($downloadedData):int{ |
135 | $originaldataArray = preg_split("/\n/", $downloadedData); |
136 | |
137 | $dataArray = array_filter($originaldataArray, array($this, 'keepOnlyRowsWithMdpSet')); |
138 | if(0 == count($dataArray)){ |
139 | error_log(sprintf("[%s] No contributor lines with mdpset data\n'%s'", __METHOD__, $downloadedData)); |
140 | return 0; |
141 | } |
142 | |
143 | //default/dbmiPreferred contributor should be in the first line |
144 | $firstLine = true; |
145 | foreach($dataArray as $data){ |
146 | list($eventId, $mdpsetId, $originTime, $region, $mdpCount, $maxIntensity, $macroseismicScale) = str_getcsv($data, '|'); |
147 | if( ! isset($macroseismicScale) ){ |
148 | error_log(sprintf("[%s] No macroseismic scale found at index[6]\n'%s'", __METHOD__, $data)); |
149 | continue; |
150 | } |
151 | |
152 | preg_match('@.*mdpset/(.*)/\d*@', $mdpsetId, $matchArray); |
153 | $contributorName = $matchArray[1]; |
154 | |
155 | if( ! array_key_exists($contributorName, $this->contributors) ) |
156 | $this->contributors[ $contributorName ] = new Contributor( new DS_Contributor($contributorName, $mdpsetId), $this->quakeId, $firstLine ); |
157 | |
158 | $this->contributors[$contributorName]->addAnalysis($macroseismicScale); |
159 | $firstLine = false; |
160 | } |
161 | |
162 | return count($this->contributors); |
163 | } |
164 | } |
165 | |
166 | ?> |
167 |
Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not
necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once.
Please also be aware that some branches may be implicit rather than explicit, e.g. an if
statement
always has an else
as part of its logical flow even if you didn't write one.
28 | public function __construct(DS_QuakeId $quakeId){ |
29 | $this->quakeId = $quakeId; |
30 | } |
33 | public function curlErrorInfo(){ return $this->curlErrInfo; } |
32 | public function curlErrorNumber(){ return $this->curlErrNum; } |
94 | $curlSession = curl_init(); |
95 | curl_setopt_array($curlSession, array( |
96 | CURLOPT_URL => sprintf(self::templateUrl, $this->quakeId->id()), |
97 | CURLOPT_HEADER => false, |
98 | CURLOPT_CUSTOMREQUEST => 'GET', |
99 | CURLOPT_RETURNTRANSFER => true, |
100 | CURLOPT_FAILONERROR => true |
101 | ) |
102 | ); |
103 | $downloadedData = curl_exec($curlSession); |
104 | |
105 | $this->curlErrNum = curl_errno($curlSession); |
106 | $this->curlErrInfo = curl_error($curlSession); |
107 | curl_close($curlSession); |
108 | |
109 | if(CURLE_OK != $this->curlErrNum){ |
116 | $rows = preg_split("/\n/", trim($downloadedData)); |
117 | |
118 | if( count($rows) < self::minValidResponseLines ){ //header+data |
119 | error_log(sprintf("[%s] Invalid contributors response, see below\n'%s'", __METHOD__, $downloadedData)); |
120 | return -2; |
123 | return $this->findContributors($downloadedData); |
124 | } |
64 | public function findBestContributorByAnalysisType(array $analysisNames):?Contributor { |
65 | if ( empty($analysisNames) ) |
66 | return null; |
68 | $bestContributor = null; |
69 | foreach($analysisNames as $name){ |
69 | foreach($analysisNames as $name){ |
70 | foreach($this->contributors as $contributor){ |
70 | foreach($this->contributors as $contributor){ |
72 | if( $contributor->analisysExists($name) && $contributor->isPreferred() ) |
72 | if( $contributor->analisysExists($name) && $contributor->isPreferred() ) |
72 | if( $contributor->analisysExists($name) && $contributor->isPreferred() ) |
73 | return $contributor; |
76 | if( $contributor->analisysExists($name) ) |
70 | foreach($this->contributors as $contributor){ |
71 | //same analysis and isPreferred -> it's the best |
72 | if( $contributor->analisysExists($name) && $contributor->isPreferred() ) |
73 | return $contributor; |
74 | |
75 | //same analysis -> i can take it but i loop for a better solution (maybe preferred is later...) |
76 | if( $contributor->analisysExists($name) ) |
77 | $bestContributor = $contributor; |
70 | foreach($this->contributors as $contributor){ |
70 | foreach($this->contributors as $contributor){ |
71 | //same analysis and isPreferred -> it's the best |
72 | if( $contributor->analisysExists($name) && $contributor->isPreferred() ) |
73 | return $contributor; |
74 | |
75 | //same analysis -> i can take it but i loop for a better solution (maybe preferred is later...) |
76 | if( $contributor->analisysExists($name) ) |
77 | $bestContributor = $contributor; |
78 | } |
79 | |
80 | //if a contributor is found, i'll get it before instead search it in other analysis |
81 | if( ! is_null($bestContributor) ) |
82 | return $bestContributor; |
69 | foreach($analysisNames as $name){ |
69 | foreach($analysisNames as $name){ |
70 | foreach($this->contributors as $contributor){ |
71 | //same analysis and isPreferred -> it's the best |
72 | if( $contributor->analisysExists($name) && $contributor->isPreferred() ) |
73 | return $contributor; |
74 | |
75 | //same analysis -> i can take it but i loop for a better solution (maybe preferred is later...) |
76 | if( $contributor->analisysExists($name) ) |
77 | $bestContributor = $contributor; |
78 | } |
79 | |
80 | //if a contributor is found, i'll get it before instead search it in other analysis |
81 | if( ! is_null($bestContributor) ) |
82 | return $bestContributor; |
83 | } |
84 | |
85 | return $bestContributor; |
86 | } |
134 | private function findContributors($downloadedData):int{ |
135 | $originaldataArray = preg_split("/\n/", $downloadedData); |
136 | |
137 | $dataArray = array_filter($originaldataArray, array($this, 'keepOnlyRowsWithMdpSet')); |
138 | if(0 == count($dataArray)){ |
139 | error_log(sprintf("[%s] No contributor lines with mdpset data\n'%s'", __METHOD__, $downloadedData)); |
140 | return 0; |
144 | $firstLine = true; |
145 | foreach($dataArray as $data){ |
145 | foreach($dataArray as $data){ |
146 | list($eventId, $mdpsetId, $originTime, $region, $mdpCount, $maxIntensity, $macroseismicScale) = str_getcsv($data, '|'); |
147 | if( ! isset($macroseismicScale) ){ |
148 | error_log(sprintf("[%s] No macroseismic scale found at index[6]\n'%s'", __METHOD__, $data)); |
149 | continue; |
152 | preg_match('@.*mdpset/(.*)/\d*@', $mdpsetId, $matchArray); |
153 | $contributorName = $matchArray[1]; |
154 | |
155 | if( ! array_key_exists($contributorName, $this->contributors) ) |
156 | $this->contributors[ $contributorName ] = new Contributor( new DS_Contributor($contributorName, $mdpsetId), $this->quakeId, $firstLine ); |
157 | |
158 | $this->contributors[$contributorName]->addAnalysis($macroseismicScale); |
145 | foreach($dataArray as $data){ |
146 | list($eventId, $mdpsetId, $originTime, $region, $mdpCount, $maxIntensity, $macroseismicScale) = str_getcsv($data, '|'); |
147 | if( ! isset($macroseismicScale) ){ |
148 | error_log(sprintf("[%s] No macroseismic scale found at index[6]\n'%s'", __METHOD__, $data)); |
149 | continue; |
150 | } |
151 | |
152 | preg_match('@.*mdpset/(.*)/\d*@', $mdpsetId, $matchArray); |
153 | $contributorName = $matchArray[1]; |
154 | |
155 | if( ! array_key_exists($contributorName, $this->contributors) ) |
156 | $this->contributors[ $contributorName ] = new Contributor( new DS_Contributor($contributorName, $mdpsetId), $this->quakeId, $firstLine ); |
157 | |
158 | $this->contributors[$contributorName]->addAnalysis($macroseismicScale); |
145 | foreach($dataArray as $data){ |
146 | list($eventId, $mdpsetId, $originTime, $region, $mdpCount, $maxIntensity, $macroseismicScale) = str_getcsv($data, '|'); |
147 | if( ! isset($macroseismicScale) ){ |
148 | error_log(sprintf("[%s] No macroseismic scale found at index[6]\n'%s'", __METHOD__, $data)); |
149 | continue; |
150 | } |
151 | |
152 | preg_match('@.*mdpset/(.*)/\d*@', $mdpsetId, $matchArray); |
153 | $contributorName = $matchArray[1]; |
154 | |
155 | if( ! array_key_exists($contributorName, $this->contributors) ) |
156 | $this->contributors[ $contributorName ] = new Contributor( new DS_Contributor($contributorName, $mdpsetId), $this->quakeId, $firstLine ); |
157 | |
158 | $this->contributors[$contributorName]->addAnalysis($macroseismicScale); |
159 | $firstLine = false; |
160 | } |
161 | |
162 | return count($this->contributors); |
163 | } |
55 | public function getIterator():Traversable{ return new ArrayIterator($this->contributors); } |
129 | private function keepOnlyRowsWithMdpSet($row){ return preg_match('@.*mdpset/(.*)/\d*@', $row); } |
40 | public function setPreferred(DS_Contributor $contributor):bool{ |
41 | $found = false; |
42 | foreach($this->contributors as $elem){ |
42 | foreach($this->contributors as $elem){ |
43 | $elem->setPreferred( $elem->details()->name() == $contributor->name() ); |
44 | if( ! $found ) |
42 | foreach($this->contributors as $elem){ |
43 | $elem->setPreferred( $elem->details()->name() == $contributor->name() ); |
44 | if( ! $found ) |
45 | $found = ($elem->details()->name() == $contributor->name()); |
42 | foreach($this->contributors as $elem){ |
42 | foreach($this->contributors as $elem){ |
43 | $elem->setPreferred( $elem->details()->name() == $contributor->name() ); |
44 | if( ! $found ) |
45 | $found = ($elem->details()->name() == $contributor->name()); |
46 | } |
47 | return $found; |
48 | } |