AuthorityRecord::normalize_name()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Scriptotek\SimpleMarcParser;
4
5
use Carbon\Carbon;
6
use Danmichaelo\QuiteSimpleXmlElement\QuiteSimpleXmlElement;
7
8
/**
9
 * @property int      $id                 Local record identifier
10
 * @property string   $class              One of 'person'|'corporation'|'meeting'|'topicalTerm'
11
 * @property Carbon\Carbon   $modified
12
 * @property string   $cataloging
13
 * @property string   $catalogingAgency
14
 * @property string   $language
15
 * @property string   $transcribingAgency
16
 * @property string   $modifyingAgency
17
 * @property string   $agency
18
 * @property string[] $genders
19
 * @property string   $gender
20
 * @property string   $name
21
 * @property string   $label
22
 * @property string   $birth
23
 * @property string   $death
24
 * @property string   $term
25
 * @property string   $vocabulary
26
 * @property string   $altLabels
27
 */
28
class AuthorityRecord extends Record
29
{
30
    // http://www.loc.gov/marc/authority/ad008.html
31
    public static $cat_rules = array(
32
        'a' => 'Earlier rules',
33
        'b' => 'AACR 1',
34
        'c' => 'AACR 2',
35
        'd' => 'AACR 2 compatible',
36
        'z' => 'Other',
37
    );
38
39
    public static $vocabularies = array(
40
        'a' => 'lcsh',
41
        'b' => 'lccsh', // LC subject headings for children's literature
42
        'c' => 'mesh', // Medical Subject Headings
43
        'd' => 'atg', // National Agricultural Library subject authority file (?)
44
        'k' => 'cash', // Canadian Subject Headings
45
        'r' => 'aat', // Art and Architecture Thesaurus
46
        's' => 'sears', // Sears List of Subject Heading
47
        'v' => 'rvm', // Répertoire de vedettes-matière
48
    );
49
50
    /**
51
     * @param string $value
52
     *
53
     * @return string
54
     */
55
    public function normalize_name($value)
56
    {
57
        $spl = explode(', ', $value);
58
        if (count($spl) == 2) {
59
            return $spl[1] . ' ' . $spl[0];
60
        }
61
62
        return $value;
63
    }
64
65
    /**
66
     * @param \Danmichaelo\QuiteSimpleXMLElement\QuiteSimpleXMLElement $data
67
     */
68
    public function __construct(QuiteSimpleXmlElement $data = null)
69
    {
70
        if (is_null($data)) {
71
            return;
72
        }
73
74
        $altLabels = array();
75
76
        // 001: Control number
77
        $this->id = $data->text('marc:controlfield[@tag="001"]');
78
79
        // 003: MARC code for the agency whose system control number is
80
        // contained in field 001 (Control Number)
81
        // See http://www.loc.gov/marc/authority/ecadorg.html
82
        $this->agency = $data->text('marc:controlfield[@tag="003"]');
83
84
        // 005: Modified
85
        $this->modified = $this->parseDateTime($data->text('marc:controlfield[@tag="005"]'));
86
87
        // 008: Extract *some* information
88
        $f008 = $data->text('marc:controlfield[@tag="008"]');
89
        $r = substr($f008, 10, 1);
90
        $this->cataloging = isset(self::$cat_rules[$r]) ? self::$cat_rules[$r] : null;
91
        $r = substr($f008, 11, 1);
92
        $this->vocabulary = isset(self::$vocabularies[$r]) ? self::$vocabularies[$r] : null;
93
94
        // 040:
95
        $source = $data->first('marc:datafield[@tag="040"]');
96
        if ($source) {
97
            $this->catalogingAgency = $source->text('marc:subfield[@code="a"]') ?: null;
98
            $this->language = $source->text('marc:subfield[@code="b"]') ?: null;
99
            $this->transcribingAgency = $source->text('marc:subfield[@code="c"]') ?: null;
100
            $this->modifyingAgency = $source->text('marc:subfield[@code="d"]') ?: null;
101
            $this->vocabulary = $source->text('marc:subfield[@code="f"]') ?: $this->vocabulary;
102
        }
103
104
        // 100: Personal name (NR)
105
        foreach ($data->all('marc:datafield[@tag="100"]') as $field) {
106
            $this->class = 'person';
107
            $this->name = $field->text('marc:subfield[@code="a"]');
108
            $this->label = $this->normalize_name($this->name);
109
            $enum = $field->text('marc:subfield[@code="b"]');
110
            if (!empty($enum)) {
111
                $this->name = "{$this->name} {$enum}";
112
                $this->label = "{$this->label} {$enum}";
113
            }
114
            $bd = $field->text('marc:subfield[@code="d"]');
115
            $bd = explode('-', $bd);
116
            $this->birth = $bd[0] ?: null;
117
            $this->death = (count($bd) > 1 && $bd[1]) ? $bd[1] : null;
118
        }
119
120
        // 110: Corporate Name (NR)
121
        foreach ($data->all('marc:datafield[@tag="110"]') as $field) {
122
            $this->class = 'corporation';
123
            $this->name = $field->text('marc:subfield[@code="a"]');
124
            $subdiv = $field->text('marc:subfield[@code="b"]');
125
126
            $this->label = ($field->attr('ind1') == '0')  // Inverted name
127
                ? $this->normalize_name($this->name)
128
                : $this->name;
129
130
            if (!empty($subdiv)) {
131
                $this->name = "{$this->name} : {$subdiv}";
132
                $this->label = "{$this->label} : {$subdiv}";
133
            }
134
        }
135
136
        // 111: Meeting Name (NR)
137
        foreach ($data->all('marc:datafield[@tag="111"]') as $field) {
138
            $this->class = 'meeting';
139
            $this->name = $field->text('marc:subfield[@code="a"]');
140
            $this->label = ($field->attr('ind1') == '0')  // Inverted name
141
                ? $this->normalize_name($this->name)
142
                : $this->name;
143
        }
144
145
        // 130: Uniform title
146
        foreach ($data->all('marc:datafield[@tag="130"]') as $field) {
147
            $this->class = 'uniform_title';
148
            $label = $field->text('marc:subfield[@code="a"]');
149
            foreach ($field->all('marc:subfield[@code="d"]') as $s) {
150
                $label .= ' (' . $s . ')';
151
            }
152
            $this->name = $label;
153
        }
154
155
        // 150: Topical Term (NR)
156
        foreach ($data->all('marc:datafield[@tag="150"]') as $field) {
157
            $this->class = 'topicalTerm';
158
            $this->term = $field->text('marc:subfield[@code="a"]');
159
            $label = $field->text('marc:subfield[@code="a"]');
160
            foreach ($field->all('marc:subfield[@code="x"]') as $s) {
161
                $label .= ' : ' . $s;
162
            }
163
            foreach ($field->all('marc:subfield[@code="v"]') as $s) {
164
                $label .= ' : ' . $s;
165
            }
166
            foreach ($field->all('marc:subfield[@code="y"]') as $s) {
167
                $label .= ' : ' . $s;
168
            }
169
            foreach ($field->all('marc:subfield[@code="z"]') as $s) {
170
                $label .= ' : ' . $s;
171
            }
172
            $this->label = $label;
173
            // TODO: ...
174
        }
175
176
        // 151: Geographic Term (NR)
177
        // 155: Genre/form Term (NR)
178
179
        // 375: Gender (R)
180
        $genders = array();
181
        foreach ($data->all('marc:datafield[@tag="375"]') as $field) {
182
            $gender = $field->text('marc:subfield[@code="a"]');
183
            $start = $field->text('marc:subfield[@code="s"]');
184
            $end = $field->text('marc:subfield[@code="e"]');
185
            $genders[] = array(
186
                'value' => $gender,
187
                'from' => $start,
188
                'until' => $end,
189
            );
190
        }
191
        $this->genders = $genders;
192
193
        // Alias gender to the last value to make utilizing easier
194
        $this->gender = (count($this->genders) > 0)
195
            ? $this->genders[count($this->genders) - 1]['value']  // assume sane ordering for now
196
            : null;
197
198
        // 400: See From Tracing-Personal Name (R)
199
        foreach ($data->all('marc:datafield[@tag="400"]') as $field) {
200
            $altLabels[] = $field->text('marc:subfield[@code="a"]');
201
        }
202
203
        // 410: See From Tracing-Corporate Name (R)
204
        foreach ($data->all('marc:datafield[@tag="410"]') as $field) {
205
            $s = $field->text('marc:subfield[@code="a"]');
206
            if ($field->has('marc:subfield[@code="b"]')) {
207
                $s .= ' : ' . $field->text('marc:subfield[@code="b"]');
208
            }
209
            $altLabels[] = $s;
210
        }
211
212
        // 411: See From Tracing-Meeting Name (R)
213
        foreach ($data->all('marc:datafield[@tag="411"]') as $field) {
214
            $altLabels[] = $field->text('marc:subfield[@code="a"]');
215
        }
216
217
        // TODO: rest
218
219
        $this->altLabels = $altLabels;
220
    }
221
}
222
223
/*
224
<?xml version="1.0"?>
225
<recordData>
226
    <marc:record xmlns:marc="info:lc/xmlns/marcxchange-v1" format="MARC21" type="Authority">
227
    <marc:leader>99999nz a2299999n 4500</marc:leader>
228
    <marc:controlfield tag="001">x90531735</marc:controlfield>
229
    <marc:controlfield tag="003">NO-TrBIB</marc:controlfield>
230
    <marc:controlfield tag="005">20090407000000.0</marc:controlfield>
231
    <marc:controlfield tag="008">090407n adznnaabn| |a|ana| </marc:controlfield>
232
    <marc:datafield tag="016" ind1="7" ind2=" ">
233
        <marc:subfield code="a">x90531735</marc:subfield>
234
        <marc:subfield code="2">NO-TrBIB</marc:subfield>
235
    </marc:datafield>
236
    <marc:datafield tag="040" ind1=" " ind2=" ">
237
        <marc:subfield code="a">NO-OsNB</marc:subfield>
238
        <marc:subfield code="b">nob</marc:subfield>
239
        <marc:subfield code="c">NO-TrBIB</marc:subfield>
240
        <marc:subfield code="f">noraf</marc:subfield>
241
    </marc:datafield>
242
    <marc:datafield tag="100" ind1="1" ind2=" ">
243
        <marc:subfield code="a">Bakke, Dagfinn</marc:subfield>
244
        <marc:subfield code="d">1933-</marc:subfield>
245
    </marc:datafield>
246
    <marc:datafield tag="375" ind1=" " ind2=" ">
247
        <marc:subfield code="a">male</marc:subfield>
248
    </marc:datafield>
249
    <marc:datafield tag="400" ind1="0" ind2=" ">
250
        <marc:subfield code="a">DAN</marc:subfield>
251
    </marc:datafield>
252
</marc:record>
253
</recordData>
254
*/
255