Passed
Push — master ( 176280...4c9570 )
by Xavier
01:42
created

Crossref::getIssnList()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
ccs 4
cts 4
cp 1
cc 3
eloc 5
nc 3
nop 0
crap 3
1
<?php
2
3
namespace PubPeerFoundation\PublicationDataExtractor\Resources\Extractors;
4
5
use PubPeerFoundation\PublicationDataExtractor\Support\UpdateTypesStandardiser;
6
use PubPeerFoundation\PublicationDataExtractor\Exceptions\UnparseableApiException;
7
use PubPeerFoundation\PublicationDataExtractor\Exceptions\JournalTitleNotFoundException;
8
9
class Crossref implements Extractor, ProvidesPublicationData, ProvidesIdentifiersData, ProvidesJournalData, ProvidesAuthorsData, ProvidesUpdatesData
10
{
11
    protected $document;
12
13
    protected $searchTree;
14
15
    protected $output = [];
16
17 24
    public function __construct($document)
18
    {
19 24
        $this->document = $document;
20 24
    }
21
22 11
    public function extract(): array
23
    {
24 11
        $this->getDataFromDocument();
25
26 9
        $this->extractAuthorsData();
27 9
        $this->extractIdentifiersData();
28 9
        try {
29 9
            $this->extractJournalData();
30 9
        } catch (JournalTitleNotFoundException $e) {
31 9
            $this->searchTree['container-title'] = $this->searchTree['publisher'];
32 9
        }
33
        $this->extractPublicationData();
34 9
        $this->extractTagsData();
35
        $this->extractTypesData();
36
        $this->extractUpdatesData();
37 7
38
        return $this->output;
39 7
    }
40 2
41
    protected function getDataFromDocument()
42
    {
43 5
        if ('ok' !== $this->document['status']) {
44 5
            throw new UnparseableApiException();
45
        }
46
47
        $this->searchTree = $this->document['message'];
48
    }
49 11
50
    /**
51 11
     * Extract and format data needed for the Publication Model.
52
     */
53 11
    public function extractPublicationData()
54 11
    {
55 11
        $date = $this->extractDateFrom(['published-print', 'published-online', 'issued']);
56 11
57 11
        $this->output['publication'] = [
58
            'title' => get_string($this->searchTree, 'title'),
59 11
            'abstract' => get_string($this->searchTree, 'abstract'),
60
            'url' => $this->searchTree['URL'] ?? null,
61
            'published_at' => $date,
62
        ];
63
    }
64 11
65
    /**
66 11
     * Extract and format data needed for the Identifiers Relationship
67
     * on the Publication Model.
68
     */
69
    public function extractIdentifiersData()
70
    {
71
        if (! empty($this->searchTree['DOI'])) {
72
            $this->output['identifiers'][] = [
73 17
                'value' => $this->searchTree['DOI'],
74
                'type' => 'doi',
75 17
            ];
76 9
        }
77 9
78 9
        foreach (get_array($this->searchTree, 'ISSN') as $issn) {
79
            $this->output['identifiers'][] = [
80
                'value' => $issn,
81
                'type' => 'issn',
82 17
            ];
83 12
        }
84 11
    }
85 11
86 11
    /**
87 11
     * Extract and format data needed for the Journal Relationship
88
     * on the Publication Model.
89
     *
90
     * @throws JournalTitleNotFoundException
91 1
     */
92 1
    public function extractJournalData()
93 1
    {
94
        if (empty($this->searchTree['container-title']) && empty($this->searchTree['ISSN'])) {
95
            throw new JournalTitleNotFoundException();
96
        }
97 17
98
        $this->output['journal'] = [
99
            'title' => get_string($this->searchTree, 'container-title'),
100
            'issn' => get_array($this->searchTree, 'ISSN'),
101
            'publisher' => get_string($this->searchTree, 'publisher'),
102
        ];
103 12
    }
104
105 12
    /**
106 1
     * Extract and format data needed for the Authors Relationship
107
     * on the Publication Model.
108
     */
109 12
    public function extractAuthorsData()
110 12
    {
111 12
        foreach (get_array($this->searchTree, 'author') as $author) {
112 12
            if (isset($author['family'])) {
113
                $this->output['authors'][] = [
114 12
                    'first_name' => get_string($author, 'given'),
115
                    'last_name' => get_string($author, 'family'),
116
                    'orcid' => get_string($author, 'ORCID'),
117
                    'affiliation' => get_array($author, 'affiliation'),
118
                ];
119
            }
120 9
        }
121
    }
122 9
123 9
    /**
124 9
     * Extract and format data needed for the Types Relationship
125 9
     * on the Publication Model.
126 9
     */
127 9
    public function extractTypesData()
128 9
    {
129 9
        $this->output['types'][] = [
130
            'name' => get_string($this->searchTree, 'type'),
131
        ];
132
    }
133
134 9
    /**
135
     * Extract and format data needed for the tags Relationship
136
     * on the Publication Model.
137
     */
138
    public function extractTagsData()
139
    {
140 9
        foreach (get_array($this->searchTree, 'subject') as $tag) {
141
            $this->output['tags'][] = [
142 9
                'name' => $tag,
143 9
            ];
144
        }
145 9
    }
146
147
    protected function extractDateFrom($array)
148
    {
149
        $datePartsContainer = array_values(array_filter($array, function ($string) {
150
            return isset($this->searchTree[$string]);
151 9
        }))[0];
152
153 9
        return date_from_parts($this->searchTree[$datePartsContainer]['date-parts'][0]);
154 9
    }
155 9
156 9
    public function extractUpdatesData()
157
    {
158
        foreach (get_array($this->searchTree, 'update-to') as $update) {
159
            $this->output['updates'][] = [
160 9
                'timestamp' => $update['updated']['timestamp'],
161
                'identifier' => [
162
                    'doi' => get_string($update, 'DOI'),
163
                ],
164 11
                'type' => UpdateTypesStandardiser::getType($update['type']),
165 11
            ];
166 11
        }
167
    }
168
}
169