Passed
Push — master ( cff466...b9a473 )
by Xavier
01:16
created

Crossref   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 176
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 29
dl 0
loc 176
c 0
b 0
f 0
rs 10
ccs 84
cts 84
cp 1

12 Methods

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