Passed
Pull Request — master (#123)
by Sebastian
03:15
created

Mods::getHolders()   C

Complexity

Conditions 14
Paths 5

Size

Total Lines 41
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 14
eloc 31
c 2
b 0
f 0
nc 5
nop 0
dl 0
loc 41
rs 6.2666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
5
 *
6
 * This file is part of the Kitodo and TYPO3 projects.
7
 *
8
 * @license GNU General Public License version 3 or later.
9
 * For the full copyright and license information, please read the
10
 * LICENSE.txt file that was distributed with this source code.
11
 */
12
13
namespace Kitodo\Dlf\Format;
14
15
use Kitodo\Dlf\Api\Orcid\Profile;
16
17
/**
18
 * Metadata MODS format class for the 'dlf' extension
19
 *
20
 * @author Sebastian Meyer <[email protected]>
21
 * @package TYPO3
22
 * @subpackage dlf
23
 * @access public
24
 */
25
class Mods implements \Kitodo\Dlf\Common\MetadataInterface
26
{
27
    /**
28
     * The metadata XML
29
     *
30
     * @var \SimpleXMLElement
31
     **/
32
    private $xml;
33
34
    /**
35
     * The metadata array
36
     *
37
     * @var array
38
     **/
39
    private $metadata;
40
41
    /**
42
     * This extracts the essential MODS metadata from XML
43
     *
44
     * @access public
45
     *
46
     * @param \SimpleXMLElement $xml: The XML to extract the metadata from
47
     * @param array &$metadata: The metadata array to fill
48
     *
49
     * @return void
50
     */
51
    public function extractMetadata(\SimpleXMLElement $xml, array &$metadata)
52
    {
53
        $this->xml = $xml;
54
        $this->metadata = $metadata;
55
56
        $this->xml->registerXPathNamespace('mods', 'http://www.loc.gov/mods/v3');
57
58
        $this->getAuthors();
59
        $this->getHolders();
60
        $this->getPlaces();
61
        $this->getYears();
62
63
        $metadata = $this->metadata;
64
    }
65
66
    /**
67
     * Get "author" and "author_sorting".
68
     *
69
     * @access private
70
     *
71
     * @return void
72
     */
73
    private function getAuthors() {
74
        $authors = $this->xml->xpath('./mods:name[./mods:role/mods:roleTerm[@type="code" and @authority="marcrelator"]="aut"]');
75
76
        // Get "author" and "author_sorting" again if that was too sophisticated.
77
        if (empty($authors)) {
78
            // Get all names which do not have any role term assigned and assume these are authors.
79
            $authors = $this->xml->xpath('./mods:name[not(./mods:role)]');
80
        }
81
        if (!empty($authors)) {
82
            for ($i = 0, $j = count($authors); $i < $j; $i++) {
83
                $authors[$i]->registerXPathNamespace('mods', 'http://www.loc.gov/mods/v3');
84
85
                $identifier = $authors[$i]->xpath('./mods:name/mods:nameIdentifier[@type="orcid"]');
86
                if (!empty((string) $identifier[0])) {
87
                    $profile = new Profile((string) $identifier[0]);
88
                    $this->metadata['author'][$i] = $profile->getFullName();
89
                } else {
90
                    // Check if there is a display form.
91
                    if (($displayForm = $authors[$i]->xpath('./mods:displayForm'))) {
92
                        $this->metadata['author'][$i] = (string) $displayForm[0];
93
                    } elseif (($nameParts = $authors[$i]->xpath('./mods:namePart'))) {
94
                        $name = [];
95
                        $k = 4;
96
                        foreach ($nameParts as $namePart) {
97
                            if (
98
                                isset($namePart['type'])
99
                                && (string) $namePart['type'] == 'family'
100
                            ) {
101
                                $name[0] = (string) $namePart;
102
                            } elseif (
103
                                isset($namePart['type'])
104
                                && (string) $namePart['type'] == 'given'
105
                            ) {
106
                                $name[1] = (string) $namePart;
107
                            } elseif (
108
                                isset($namePart['type'])
109
                                && (string) $namePart['type'] == 'termsOfAddress'
110
                            ) {
111
                                $name[2] = (string) $namePart;
112
                            } elseif (
113
                                isset($namePart['type'])
114
                                && (string) $namePart['type'] == 'date'
115
                            ) {
116
                                $name[3] = (string) $namePart;
117
                            } else {
118
                                $name[$k] = (string) $namePart;
119
                            }
120
                            $k++;
121
                        }
122
                        ksort($name);
123
                        $this->metadata['author'][$i] = trim(implode(', ', $name));
124
                    }
125
                    // Append "valueURI" to name using Unicode unit separator.
126
                    if (isset($authors[$i]['valueURI'])) {
127
                        $this->metadata['author'][$i] .= chr(31) . (string) $authors[$i]['valueURI'];
128
                    }
129
                }
130
            }
131
        }
132
    }
133
134
    /**
135
     * Get holder.
136
     *
137
     * @access private
138
     *
139
     * @return void
140
     */
141
    private function getHolders() {
142
        $holders = $this->xml->xpath('./mods:name[./mods:role/mods:roleTerm[@type="code" and @authority="marcrelator"]="prv"]');
143
144
        if (!empty($holders)) {
145
            for ($i = 0, $j = count($holders); $i < $j; $i++) {
146
                $holders[$i]->registerXPathNamespace('mods', 'http://www.loc.gov/mods/v3');
147
148
                // Check if there is a display form.
149
                if (($displayForm = $holders[$i]->xpath('./mods:displayForm'))) {
150
                    $this->metadata['holder'][$i] = (string) $displayForm[0];
151
                } elseif (($nameParts = $holders[$i]->xpath('./mods:namePart'))) {
152
                    $name = [];
153
                    $k = 4;
154
                    foreach ($nameParts as $namePart) {
155
                        if (
156
                            isset($namePart['type'])
157
                            && (string) $namePart['type'] == 'family'
158
                        ) {
159
                            $name[0] = (string) $namePart;
160
                        } elseif (
161
                            isset($namePart['type'])
162
                            && (string) $namePart['type'] == 'given'
163
                        ) {
164
                            $name[1] = (string) $namePart;
165
                        } elseif (
166
                            isset($namePart['type'])
167
                            && (string) $namePart['type'] == 'termsOfAddress'
168
                        ) {
169
                            $name[2] = (string) $namePart;
170
                        } elseif (
171
                            isset($namePart['type'])
172
                            && (string) $namePart['type'] == 'date'
173
                        ) {
174
                            $name[3] = (string) $namePart;
175
                        } else {
176
                            $name[$k] = (string) $namePart;
177
                        }
178
                        $k++;
179
                    }
180
                    ksort($name);
181
                    $this->metadata['holder'][$i] = trim(implode(', ', $name));
182
                }
183
            }
184
        }
185
    }
186
187
    /**
188
     * Get "place" and "place_sorting".
189
     *
190
     * @access private
191
     *
192
     * @return void
193
     */
194
    private function getPlaces() {
195
        $places = $this->xml->xpath('./mods:originInfo[not(./mods:edition="[Electronic ed.]")]/mods:place/mods:placeTerm');
196
        // Get "place" and "place_sorting" again if that was to sophisticated.
197
        if (empty($places)) {
198
            // Get all places and assume these are places of publication.
199
            $places = $this->xml->xpath('./mods:originInfo/mods:place/mods:placeTerm');
200
        }
201
        if (!empty($places)) {
202
            foreach ($places as $place) {
203
                $this->metadata['place'][] = (string) $place;
204
                if (!$this->metadata['place_sorting'][0]) {
205
                    $this->metadata['place_sorting'][0] = preg_replace('/[[:punct:]]/', '', (string) $place);
206
                }
207
            }
208
        }
209
    }
210
211
    /**
212
     * Get "year" and "year_sorting".
213
     *
214
     * @access private
215
     *
216
     * @return void
217
     */
218
    private function getYears() {
219
        // Get "year_sorting".
220
        if (($years_sorting = $this->xml->xpath('./mods:originInfo[not(./mods:edition="[Electronic ed.]")]/mods:dateOther[@type="order" and @encoding="w3cdtf"]'))) {
221
            foreach ($years_sorting as $year_sorting) {
222
                $this->metadata['year_sorting'][0] = intval($year_sorting);
223
            }
224
        }
225
        // Get "year" and "year_sorting" if not specified separately.
226
        $years = $this->xml->xpath('./mods:originInfo[not(./mods:edition="[Electronic ed.]")]/mods:dateIssued[@keyDate="yes"]');
227
        // Get "year" and "year_sorting" again if that was to sophisticated.
228
        if (empty($years)) {
229
            // Get all dates and assume these are dates of publication.
230
            $years = $this->xml->xpath('./mods:originInfo/mods:dateIssued');
231
        }
232
        if (!empty($years)) {
233
            foreach ($years as $year) {
234
                $this->metadata['year'][] = (string) $year;
235
                if (!$this->metadata['year_sorting'][0]) {
236
                    $year_sorting = str_ireplace('x', '5', preg_replace('/[^\d.x]/i', '', (string) $year));
237
                    if (
238
                        strpos($year_sorting, '.')
0 ignored issues
show
Bug introduced by
It seems like $year_sorting can also be of type array; however, parameter $haystack of strpos() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

238
                        strpos(/** @scrutinizer ignore-type */ $year_sorting, '.')
Loading history...
239
                        || strlen($year_sorting) < 3
0 ignored issues
show
Bug introduced by
It seems like $year_sorting can also be of type array; however, parameter $string of strlen() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

239
                        || strlen(/** @scrutinizer ignore-type */ $year_sorting) < 3
Loading history...
240
                    ) {
241
                        $year_sorting = ((intval(trim($year_sorting, '.')) - 1) * 100) + 50;
0 ignored issues
show
Bug introduced by
It seems like $year_sorting can also be of type array; however, parameter $string of trim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

241
                        $year_sorting = ((intval(trim(/** @scrutinizer ignore-type */ $year_sorting, '.')) - 1) * 100) + 50;
Loading history...
242
                    }
243
                    $this->metadata['year_sorting'][0] = intval($year_sorting);
244
                }
245
            }
246
        }
247
    }
248
}
249