Skip to content

Commit 85fd59a

Browse files
committed
refactor: Move code out of Record [BC]
Breaking change: - `Subject::getType()` now returns the tag number (like "650)" instead of a string representing the tag (like "topic"). Constants have been defined on `Subject` for comparison, so to check if a subject is a topical term, you can do `$subject->type == Subject::TOPICAL_TERM`.
1 parent 19898d5 commit 85fd59a

File tree

7 files changed

+113
-54
lines changed

7 files changed

+113
-54
lines changed

src/Fields/ControlField.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,15 @@
22

33
namespace Scriptotek\Marc\Fields;
44

5+
use Scriptotek\Marc\Record;
6+
57
class ControlField extends Field implements FieldInterface
68
{
9+
public static function get(Record $record, $tag)
10+
{
11+
return parent::makeFieldObject($record, $tag);
12+
}
13+
714
public function __toString()
815
{
916
return $this->field->getData();

src/Fields/Field.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Scriptotek\Marc\Fields;
44

5+
use Scriptotek\Marc\Record;
6+
57
class Field
68
{
79
protected $field;
@@ -29,4 +31,20 @@ public function sf($code)
2931
$x = $this->getSubfield($code);
3032
return $x->getData();
3133
}
34+
35+
public static function makeFieldObject(Record $record, $tag, $pcre=false)
36+
{
37+
$field = $record->getField($tag, $pcre);
38+
39+
// Note: `new static()` is a way of creating a new instance of the
40+
// called class using late static binding.
41+
return isset($field) ? new static($field) : $field;
42+
}
43+
44+
public static function makeFieldObjects(Record $record, $tag, $pcre=false)
45+
{
46+
return array_map(function($field) {
47+
return new self($field);
48+
}, $record->getFields($tag, $pcre));
49+
}
3250
}

src/Fields/Isbn.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Scriptotek\Marc\Fields;
44

5+
use Scriptotek\Marc\Record;
6+
57
class Isbn extends Field implements FieldInterface
68
{
79
public function __toString()
@@ -13,4 +15,9 @@ public function __toString()
1315

1416
return $a->getData();
1517
}
18+
19+
public static function get(Record $record)
20+
{
21+
return parent::makeFieldObjects($record, '020');
22+
}
1623
}

src/Fields/Subject.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,28 @@
22

33
namespace Scriptotek\Marc\Fields;
44

5+
use Scriptotek\Marc\Record;
6+
57
class Subject extends Field implements FieldInterface
68
{
79
public static $glue = ' : ';
810

11+
const PERSONAL_NAME = '600';
12+
const CORPORATION_NAME = '601';
13+
const MEETING_NAME = '611';
14+
const UNIFORM_TITLE = '630';
15+
const NAMED_EVENT = '647';
16+
const CHRONOLOGICAL_TERM = '648';
17+
const TOPICAL_TERM = '650';
18+
const GEOGRAPHIC_NAME = '651';
19+
const UNCONTROLLED_INDEX_TERM = '653';
20+
const FACETED_TOPICAL_TERM = '654';
21+
const GENRE_FORM = '655';
22+
const OCCUPATION = '656';
23+
const FUNCTION_TERM = '657';
24+
const CURRICULUM_OBJECTIVE = '658';
25+
const HIERARCHICAL_PLACE_NAME = '662';
26+
927
protected $vocabularies = array(
1028
'0' => 'lcsh', // 0: Library of Congress Subject Headings
1129
'1' => 'lccsh', // 1: LC subject headings for children's literature
@@ -17,6 +35,15 @@ class Subject extends Field implements FieldInterface
1735
// 7: Source specified in subfield $2
1836
);
1937

38+
public static function get(Record $record) {
39+
return parent::makeFieldObjects($record, '6..', true);
40+
}
41+
42+
public function getType()
43+
{
44+
return $this->getTag();
45+
}
46+
2047
public function getVocabulary()
2148
{
2249
$ind2 = $this->field->getIndicator(2);
@@ -28,7 +55,7 @@ public function getVocabulary()
2855
return $sf2->getData();
2956
}
3057

31-
return;
58+
return null;
3259
}
3360

3461
/**

src/Fields/Title.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@
22

33
namespace Scriptotek\Marc\Fields;
44

5+
use Scriptotek\Marc\Record;
6+
57
class Title extends Field implements FieldInterface
68
{
79

10+
public static function get(Record $record)
11+
{
12+
return parent::makeFieldObject($record, '245');
13+
}
14+
815
/**
916
* Returns the string representation $a, $b, $n and $p).
1017
* - Joins the subfields by colon if no ISBD marker present at the end of $a

src/Record.php

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
use File_MARC_Reference;
77
use Scriptotek\Marc\Exceptions\RecordNotFound;
88
use Scriptotek\Marc\Exceptions\UnknownRecordType;
9+
use Scriptotek\Marc\Fields\ControlField;
10+
use Scriptotek\Marc\Fields\Isbn;
11+
use Scriptotek\Marc\Fields\Subject;
12+
use Scriptotek\Marc\Fields\Title;
913

1014
class Record
1115
{
@@ -67,7 +71,7 @@ public static function fromString($data)
6771
* constants.
6872
*
6973
* @return string
70-
* @throws ErrorException
74+
* @throws UnknownRecordType
7175
*/
7276
public function getType()
7377
{
@@ -107,64 +111,52 @@ public function getType()
107111
* a class in src/Fields/
108112
*************************************************************************/
109113

110-
public function getIsbns()
114+
/**
115+
* Get the value of the 001 field as a `ControlField` object.
116+
*
117+
* @return Title
118+
*/
119+
public function getId()
111120
{
112-
$fields = array();
113-
foreach ($this->record->getFields('020') as $field) {
114-
$fields[] = $this->makeField('Isbn', $field);
115-
}
116-
117-
return $fields;
121+
return ControlField::get($this, '001');
118122
}
119123

120-
public function getSubjects($vocabulary = null, $type = null)
124+
/**
125+
* Get an array of the 020 fields as `Isbn` objects.
126+
*
127+
* @return Isbn[]
128+
*/
129+
public function getIsbns()
121130
{
122-
$fields = array();
123-
$saf = array(
124-
'600' => 'person', # Subject Added Entry - Personal name
125-
'610' => 'corporation', # Subject Added Entry - Corporate name
126-
'611' => 'meeting', # Subject Added Entry - Meeting name
127-
'630' => 'uniform-title', # Subject Added Entry - Uniform title
128-
'648' => 'time', # Subject Added Entry - Chronological Term
129-
'650' => 'topic', # Subject Added Entry - Topical Term
130-
'651' => 'place', # Subject Added Entry - Geographic Name
131-
'653' => 'uncontrolled', # Index Term - Uncontrolled
132-
// 654 : Subject Added Entry - Faceted Topical Terms
133-
'655' => 'form', # Index Term - Genre/Form
134-
'656' => 'occupation', # Index Term - Occupation
135-
// 657 - Index Term - Function
136-
// 658 - Index Term - Curriculum Objective
137-
// 662 - Subject Added Entry - Hierarchical Place Name
138-
// 69X - Local Subject Access Fields
139-
);
140-
foreach ($saf as $k => $v) {
141-
foreach ($this->record->getFields($k) as $field) { // or 655, 648, etc.
142-
$f = $this->makeField('Subject', $field);
143-
$f->type = $v;
144-
$fields[] = $f;
145-
}
146-
}
147-
148-
return array_filter($fields, function ($s) use ($vocabulary, $type) {
149-
$a = is_null($vocabulary) || $vocabulary == $s->vocabulary;
150-
$b = is_null($type) || $type == $s->type;
151-
152-
return $a && $b;
153-
});
131+
return Isbn::get($this);
154132
}
155133

134+
/**
135+
* Get the 245 field as a `Title` object. Returns null if no such field was found.
136+
*
137+
* @return Title
138+
*/
156139
public function getTitle()
157140
{
158-
$field = $this->record->getField('245');
159-
160-
return $field ? $this->makeField('Title', $field) : null;
141+
return Title::get($this);
161142
}
162143

163-
public function getId()
144+
/**
145+
* Get an array of the 6XX fields as `Subject` objects, optionally filtered by
146+
* vocabulary and/or tag.
147+
*
148+
* @param string $vocabulary
149+
* @param string $tag
150+
* @return Subject[]
151+
*/
152+
public function getSubjects($vocabulary = null, $tag = null)
164153
{
165-
$field = $this->record->getField('001');
154+
return array_filter(Subject::get($this), function ($field) use ($vocabulary, $tag) {
155+
$a = is_null($vocabulary) || $vocabulary == $field->vocabulary;
156+
$b = is_null($tag) || $tag == $field->type;
166157

167-
return $field ? $this->makeField('ControlField', $field) : null;
158+
return $a && $b;
159+
});
168160
}
169161

170162
/*************************************************************************

tests/SubjectFieldTest.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
use Scriptotek\Marc\Collection;
4+
use Scriptotek\Marc\Fields\Subject;
45

56
class SubjectFieldTest extends \PHPUnit_Framework_TestCase
67
{
@@ -18,7 +19,7 @@ public function testSubjectString()
1819
# Vocabulary from indicator2
1920
$sub = $record->subjects[0];
2021
$this->assertEquals('lcsh', $sub->vocabulary);
21-
$this->assertEquals('topic', $sub->type);
22+
$this->assertEquals(Subject::TOPICAL_TERM, $sub->type);
2223
$this->assertEquals('Eightfold way (Nuclear physics) : Addresses, essays, lectures', strval($sub));
2324
}
2425

@@ -31,24 +32,24 @@ public function testSubjects()
3132
$this->assertInstanceOf('Scriptotek\Marc\Fields\Subject', $subject);
3233
$this->assertEquals('noubomn', $subject->vocabulary);
3334
$this->assertEquals('Elementærpartikler', strval($subject));
34-
$this->assertEquals('650', $subject->getTag('650'));
35+
$this->assertEquals('650', $subject->getTag());
3536
$this->assertNull($subject->getControlNumber());
3637

3738
$subject = $record->subjects[3];
3839
$this->assertInstanceOf('Scriptotek\Marc\Fields\Subject', $subject);
3940
$this->assertNull($subject->vocabulary);
4041
$this->assertEquals('elementærpartikler', strval($subject));
41-
$this->assertEquals('653', $subject->getTag('650'));
42+
$this->assertEquals('653', $subject->getTag());
4243
}
4344

44-
public function testGetSubjects()
45+
public function testGetSubjectsFiltering()
4546
{
4647
$record = $this->getNthrecord(3);
4748

4849
$lcsh = $record->getSubjects('lcsh');
4950
$noubomn = $record->getSubjects('noubomn');
50-
$noubomn_topic = $record->getSubjects('noubomn', 'topic');
51-
$noubomn_place = $record->getSubjects('noubomn', 'place');
51+
$noubomn_topic = $record->getSubjects('noubomn', Subject::TOPICAL_TERM);
52+
$noubomn_place = $record->getSubjects('noubomn', Subject::GEOGRAPHIC_NAME);
5253

5354
$this->assertCount(1, $lcsh);
5455
$this->assertCount(2, $noubomn);

0 commit comments

Comments
 (0)