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

Mods::getAuthors()   C

Complexity

Conditions 16
Paths 16

Size

Total Lines 50
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 16
eloc 35
c 1
b 0
f 0
nc 16
nop 0
dl 0
loc 50
rs 5.5666

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

230
                        strpos(/** @scrutinizer ignore-type */ $year_sorting, '.')
Loading history...
231
                        || 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

231
                        || strlen(/** @scrutinizer ignore-type */ $year_sorting) < 3
Loading history...
232
                    ) {
233
                        $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

233
                        $year_sorting = ((intval(trim(/** @scrutinizer ignore-type */ $year_sorting, '.')) - 1) * 100) + 50;
Loading history...
234
                    }
235
                    $this->metadata['year_sorting'][0] = intval($year_sorting);
236
                }
237
            }
238
        }
239
    }
240
}
241