Passed
Push — master ( 580f3f...4c2e3f )
by Xavier
01:18
created

Crossref::extractDateFrom()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
rs 9.4285
ccs 4
cts 4
cp 1
cc 1
eloc 4
nc 1
nop 1
crap 1
1
<?php
2
3
namespace PubPeerFoundation\PublicationDataExtractor\Resources\Extractors;
4
5
use PubPeerFoundation\PublicationDataExtractor\Helpers\DateHelper;
6
use PubPeerFoundation\PublicationDataExtractor\Helpers\UpdateTypesStandardiser;
7
use PubPeerFoundation\PublicationDataExtractor\Exceptions\UnparseableApiException;
8
use PubPeerFoundation\PublicationDataExtractor\Exceptions\JournalTitleNotFoundException;
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
        foreach ($this->getIssnList() as $issn) {
84 11
            $this->output['identifiers'][] = [
85 11
                'value' => $issn,
86 11
                'type' => 'issn',
87 11
            ];
88
        }
89
    }
90
91 1
    /**
92 1
     * Extract and format data needed for the Journal Relationship
93 1
     * on the Publication Model.
94
     */
95
    public function extractJournalData()
96
    {
97 17
        if (empty($this->searchTree['container-title']) && empty($this->searchTree['ISSN'])) {
98
            throw new JournalTitleNotFoundException();
99
        }
100
101
        $this->output['journal'] = [
102
            'title' => $this->searchTree['container-title'] ?? null,
103 12
            'issn' => $this->getIssnList() ?? null,
104
            'publisher' => $this->searchTree['publisher'] ?? null,
105 12
        ];
106 1
    }
107
108
    /**
109 12
     * Extract and format data needed for the Authors Relationship
110 12
     * on the Publication Model.
111 12
     */
112 12
    public function extractAuthorsData()
113
    {
114 12
        if (array_key_exists('author', $this->searchTree)) {
115
            foreach ($this->searchTree['author'] as $author) {
116
                if (isset($author['family'])) {
117
                    $this->output['authors'][] = [
118
                        'first_name' => $author['given'] ?? null,
119
                        'last_name' => $author['family'] ?? null,
120 9
                        'orcid' => $author['ORCID'] ?? null,
121
                        'affiliation' => $author['affiliation'] ?? null,
122 9
                    ];
123 9
                }
124 9
            }
125 9
        }
126 9
    }
127 9
128 9
    /**
129 9
     * Extract and format data needed for the Types Relationship
130
     * on the Publication Model.
131
     */
132
    public function extractTypesData()
133
    {
134 9
        $this->output['types'][] = [
135
            'name' => $this->searchTree['type'] ?? null,
136
        ];
137
    }
138
139
    /**
140 9
     * Extract and format data needed for the tags Relationship
141
     * on the Publication Model.
142 9
     */
143 9
    public function extractTagsData()
144
    {
145 9
        if (array_key_exists('subject', $this->searchTree)) {
146
            foreach ($this->searchTree['subject'] as $tag) {
147
                $this->output['tags'][] = [
148
                    'name' => $tag,
149
                ];
150
            }
151 9
        }
152
    }
153 9
154 9
    protected function extractDateFrom($array)
155 9
    {
156 9
        $datePartsContainer = array_values(array_filter($array, function ($string) {
157
            return isset($this->searchTree[$string]);
158
        }))[0];
159
160 9
        return (new DateHelper())
161
            ->dateFromDateParts($this->searchTree[$datePartsContainer]['date-parts'][0]);
162
    }
163
164 11
    public function extractUpdatesData()
165 11
    {
166 11
        if (array_key_exists('update-to', $this->searchTree)) {
167
            foreach ($this->searchTree['update-to'] as $update) {
168 11
                $this->output['updates'][] = [
169 11
                    'timestamp' => $update['updated']['timestamp'],
170
                    'identifier' => [
171
                        'doi' => $update['DOI'],
172 9
                    ],
173
                    'type' => UpdateTypesStandardiser::getType($update['type']),
174 9
                ];
175 2
            }
176 2
        }
177 2
    }
178
179 2
    protected function getIssnList()
180
    {
181 2
        if (!empty($this->searchTree['ISSN'])) {
182
            return (is_array($this->searchTree['ISSN']))
183
                ? $this->searchTree['ISSN']
184
                : [$this->searchTree['ISSN']];
185 9
        }
186
187
        return [];
188
    }
189
}
190