EutilsEfetch::createAuthorEntry()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 10
c 0
b 0
f 0
rs 10
ccs 0
cts 0
cp 0
cc 2
nc 2
nop 1
crap 6
1
<?php
2
3
namespace PubPeerFoundation\PublicationDataExtractor\Resources\Extractors;
4
5
use PubPeerFoundation\PublicationDataExtractor\Support\UpdateTypesStandardiser;
6
use Tightenco\Collect\Support\Arr;
7
8
class EutilsEfetch extends Extractor implements ProvidesPublicationData, ProvidesIdentifiersData, ProvidesAuthorsData, ProvidesJournalData, ProvidesUpdatesData
9
{
10
    /**
11
     * Create search tree.
12
     */
13
    protected function fillSearchTree(): void
14
    {
15
        $this->searchTree = $this->document->{'PubmedArticle'};
16 8
    }
17
18 8
    /**
19 8
     * Extract and format data needed for the Publication Model.
20 8
     */
21
    public function extractPublicationData(): void
22 4
    {
23
        $this->resourceOutput['publication'] = [
24 4
            'title' => get_string($this->searchTree, 'MedlineCitation.Article.ArticleTitle'),
25
            'url' => (string) 'http://www.ncbi.nlm.nih.gov/pubmed/'.get_string($this->searchTree, 'MedlineCitation.PMID'),
26 4
            'published_at' => date_from_pub_date(data_get($this->searchTree, 'MedlineCitation.Article.Journal.JournalIssue.PubDate')),
27 4
            'abstract' => get_string($this->searchTree, 'MedlineCitation.Article.Abstract.AbstractText'),
28 4
        ];
29 4
    }
30
31 4
    /**
32
     * Extract and format data needed for the Identifiers Relationship
33
     * on the Publication Model.
34 4
     */
35
    public function extractIdentifiersData(): void
36 4
    {
37 4
        foreach ($this->searchTree->PubmedData->ArticleIdList->ArticleId as $identifier) {
38
            $this->resourceOutput['identifiers'][] = [
39
                'value' => (string) $identifier,
40
                'type' => (string) $identifier['IdType'],
41
            ];
42 4
        }
43
        if ($value = get_string($this->searchTree, 'MedlineCitation.Article.Journal.ISSN')) {
44 4
            $this->resourceOutput['identifiers'][] = [
45 4
                'value' => $value,
46 4
                'type' => 'issn',
47 4
            ];
48 4
        }
49
    }
50 4
51
    /**
52
     * Extract and format data needed for the Journals Relationship
53
     * on the Publication Model.
54
     */
55
    public function extractJournalData(): void
56 4
    {
57
        $this->resourceOutput['journal'] = [
58 4
            'title' => get_string($this->searchTree, 'MedlineCitation.Article.Journal.Title'),
59 4
            'issn' => $this->getIssns(),
60 4
        ];
61 4
    }
62
63
    /**
64
     * Extract and format data needed for the Authors Relationship
65 4
     * on the Publication Model.
66 4
     */
67 4
    public function extractAuthorsData(): void
68 4
    {
69
        try {
70
            $this->loopOverAuthors();
71 4
        } catch (\Exception $e) {
72
            // Empty catch block, don't want anything to happen in case of exception.
73
        }
74
    }
75
76
    public function extractUpdatesData(): void
77 4
    {
78
        try {
79 4
            foreach ($this->searchTree->MedlineCitation->CommentsCorrectionsList->CommentsCorrections as $correction) {
80
                $this->getUpdateFromCorrection($correction);
81 4
            }
82 4
        } catch (\Exception $e) {
83
            // Don't stop in case of unreadable date format
84
        }
85 4
    }
86 4
87
    /**
88
     * @param  $correction
89 4
     */
90 4
    protected function getUpdateFromCorrection($correction): void
91 4
    {
92
        if (in_array(stringify($correction['RefType']), array_keys(UpdateTypesStandardiser::TYPES_MAP))) {
93 4
            $this->resourceOutput['updates'][] = [
94
                'timestamp' => $this->getUpdateTimestamp(stringify($correction->RefSource)),
95
                'identifier' => [
96
                    'pubmed' => get_string($correction, 'PMID'),
97
                ],
98
                'type' => UpdateTypesStandardiser::getType(stringify($correction['RefType'])),
99 8
            ];
100
        }
101
    }
102 8
103 7
    /**
104 7
     * Get all available ISSNs values from the tree.
105 7
     *
106 7
     * @return array
107
     */
108
    protected function getIssns()
109 1
    {
110
        $issn = [];
111 8
112
        if ($number = get_string($this->searchTree, 'MedlineCitation.Article.Journal.ISSN')) {
113
            $issn[] = $number;
114
        }
115
116
        if ($number = get_string($this->searchTree, 'MedlineCitation.MedlineJournalInfo.ISSNLinking')) {
117
            $issn[] = $number;
118
        }
119
120
        return $issn;
121
    }
122
123
    /**
124
     * Loop over authors array.
125
     */
126
    protected function loopOverAuthors(): void
127
    {
128
        foreach ($this->searchTree->MedlineCitation->Article->AuthorList->Author as $author) {
129
            $this->createAuthorEntry($author);
130
        }
131
    }
132
133
    /**
134
     * Create an author entry in output.
135
     *
136
     * @param  $author
137
     */
138
    protected function createAuthorEntry($author): void
139
    {
140
        if (! empty($lastName = get_string($author, 'LastName'))) {
141
            $affiliations = $this->loopOverAffiliations($author);
142
143
            $this->resourceOutput['authors'][] = [
144
                'first_name' => get_string($author, 'ForeName'),
145
                'last_name' => $lastName,
146
                'email' => $this->getEmailsFromAffiliations($affiliations),
147
                'affiliation' => $affiliations,
148
            ];
149
        }
150
    }
151
152
    /**
153
     * Loop over affiliations.
154
     *
155
     * @param  array  $author
156
     * @return array
157
     */
158
    protected function loopOverAffiliations($author): array
159
    {
160
        $affiliations = [];
161
        foreach ($author->AffiliationInfo as $affiliation) {
162
            $affiliations[]['name'] = get_string($affiliation, 'Affiliation');
163
        }
164
165
        return $affiliations;
166
    }
167
168
    /**
169
     * Get emails from affiliations array.
170
     *
171
     * @param  array  $affiliations
172
     * @return string
173
     */
174
    protected function getEmailsFromAffiliations($affiliations): string
175
    {
176
        return get_string(find_emails_in_array(Arr::pluck($affiliations, 'name')), 0);
177
    }
178
179
    protected function getUpdateTimestamp($refSource)
180
    {
181
        preg_match('/\s(\d{4}\s\w{3}(\s\d{1,2})?);/', $refSource, $matches);
182
183
        return date_from_human_readable($matches[1])->timestamp;
184
    }
185
}
186