Skip to content

Commit 91549aa

Browse files
committed
[BC] Make Record json serializable
Add a method on Record to make a simple array/json serialization using a pre-defined set of properties that refer to helper methods on the class. Breaking change: `Subject::getControlNumber()` is now known as `Subject::getId()`
1 parent 2e4d25c commit 91549aa

12 files changed

+230
-23
lines changed

src/BibliographicRecord.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010

1111
class BibliographicRecord extends Record
1212
{
13+
/**
14+
* @var array List of properties to be included when serializing the record using the `toArray()` method.
15+
*/
16+
public $properties = ['id', 'type', 'isbns', 'title', 'subjects'];
17+
1318
/**
1419
* Get the descriptive cataloging form value from LDR/18. Returns any of
1520
* the constants Marc21::NON_ISBD, Marc21::AACR2, Marc21::ISBD_PUNCTUATION_OMITTED,

src/Fields/Field.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
abstract class Field implements \JsonSerializable
88
{
9+
/**
10+
* @var array List of properties to be included when serializing the record using the `toArray()` method.
11+
*/
12+
public $properties = [];
13+
914
protected $field;
1015

1116
public function __construct(\File_MARC_Field $field)
@@ -20,6 +25,18 @@ public function getField()
2025

2126
public function jsonSerialize()
2227
{
28+
if (count($this->properties)) {
29+
$o = [];
30+
foreach ($this->properties as $prop) {
31+
$value = $this->$prop;
32+
if (is_object($value)) {
33+
$o[$prop] = $value->jsonSerialize();
34+
} elseif ($value) {
35+
$o[$prop] = $value;
36+
}
37+
}
38+
return $o;
39+
}
2340
return (string) $this;
2441
}
2542

@@ -90,7 +107,7 @@ public static function makeFieldObject(Record $record, $tag, $pcre=false)
90107

91108
// Note: `new static()` is a way of creating a new instance of the
92109
// called class using late static binding.
93-
return isset($field) ? new static($field) : $field;
110+
return $field ? new static($field) : null;
94111
}
95112

96113
public static function makeFieldObjects(Record $record, $tag, $pcre=false)

src/Fields/Location.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
*/
1818
class Location extends Field implements FieldInterface
1919
{
20+
/**
21+
* @var array List of properties to be included when serializing the record using the `toArray()` method.
22+
*/
23+
public $properties = ['location', 'sublocation', 'shelvinglocation', 'callcode'];
24+
2025
public static function get(Record $record)
2126
{
2227
return parent::makeFieldObjects($record, '852');
@@ -32,12 +37,12 @@ public function getSublocation()
3237
return $this->sf('b');
3338
}
3439

35-
public function getShelvingLocation()
40+
public function getShelvinglocation()
3641
{
3742
return $this->sf('c');
3843
}
3944

40-
public function getCallCode()
45+
public function getCallcode()
4146
{
4247
return $this->toString([
4348
'k', // Call number prefix
@@ -61,5 +66,4 @@ public function __toString()
6166
{
6267
return $this->toString(['a', 'b', 'c', 'k', 'l', 'h', 'm']);
6368
}
64-
6569
}

src/Fields/Subject.php

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
class Subject extends Field implements FieldInterface, SubjectInterface
88
{
9+
/**
10+
* @var array List of properties to be included when serializing the record using the `toArray()` method.
11+
*/
12+
public $properties = ['type', 'vocabulary', 'term', 'id'];
13+
914
public static $glue = ' : ';
1015
public static $termComponentCodes = ['a', 'b', 'x', 'y', 'z'];
1116

@@ -75,7 +80,7 @@ public function getVocabulary()
7580
/**
7681
* Return the Authority record control number
7782
*/
78-
public function getControlNumber()
83+
public function getId()
7984
{
8085
$value = $this->field->getSubfield('0');
8186
return $value ?: null;
@@ -95,14 +100,4 @@ public function __toString()
95100
{
96101
return $this->getTerm();
97102
}
98-
99-
public function jsonSerialize()
100-
{
101-
return [
102-
'type' => $this->getType(),
103-
'vocabulary' => $this->getVocabulary(),
104-
'id' => $this->getControlNumber(),
105-
'term' => (string) $this,
106-
];
107-
}
108103
}

src/Fields/SubjectInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public function getType();
88

99
public function getVocabulary();
1010

11-
public function getControlNumber();
11+
public function getId();
1212

1313
public function getParts();
1414

src/Fields/UncontrolledSubject.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public function getVocabulary()
1717
/**
1818
* Return the Authority record control number
1919
*/
20-
public function getControlNumber()
20+
public function getId()
2121
{
2222
return null;
2323
}

src/HoldingsRecord.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
*/
1313
class HoldingsRecord extends Record
1414
{
15+
/**
16+
* @var array List of properties to be included when serializing the record using the `toArray()` method.
17+
*/
18+
public $properties = ['id', 'type', 'location'];
19+
1520
/*************************************************************************
1621
* Helper methods for specific fields. Each of these are supported by
1722
* a class in src/Fields/

src/Record.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@
2020
* @property string id
2121
* @property string type
2222
*/
23-
class Record
23+
class Record implements \JsonSerializable
2424
{
2525
protected $record;
2626

27+
/**
28+
* @var array List of properties to be included when serializing the record using the `toArray()` method.
29+
*/
30+
public $properties = ['id', 'type'];
31+
2732
/**
2833
* Record constructor.
2934
* @param File_MARC_Record $record
@@ -122,6 +127,28 @@ public function getId()
122127
* Support methods
123128
*************************************************************************/
124129

130+
public function jsonSerialize()
131+
{
132+
$o = [];
133+
foreach ($this->properties as $prop) {
134+
$value = $this->$prop;
135+
if (is_null($value)) {
136+
$o[$prop] = $value;
137+
} elseif (is_array($value)) {
138+
$t = [];
139+
foreach ($value as $v) {
140+
$t[] = $v->jsonSerialize();
141+
}
142+
$o[$prop] = $t;
143+
} else if (is_object($value)) {
144+
$o[$prop] = $value->jsonSerialize();
145+
} else {
146+
$o[$prop] = $value;
147+
}
148+
}
149+
return $o;
150+
}
151+
125152
public function __call($name, $args)
126153
{
127154
return call_user_func_array([$this->record, $name], $args);

tests/RecordTest.php

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use PHPUnit\Framework\TestCase;
44
use Scriptotek\Marc\AuthorityRecord;
55
use Scriptotek\Marc\BibliographicRecord;
6+
use Scriptotek\Marc\Fields\Subject;
67
use Scriptotek\Marc\HoldingsRecord;
78
use Scriptotek\Marc\Marc21;
89
use Scriptotek\Marc\Record;
@@ -91,14 +92,53 @@ public function testRecordTypeAuthority()
9192

9293
public function testRecordTypeHoldings()
9394
{
94-
$record = Record::fromFile(__DIR__ . '/data/holdings-alma.xml');
95+
$record = Record::fromFile(__DIR__ . '/data/holdings.xml');
9596

9697
$this->assertInstanceOf(Record::class, $record);
9798
$this->assertInstanceOf(HoldingsRecord::class, $record);
9899

99100
$this->assertEquals('1030310', $record->location->sublocation);
100-
$this->assertEquals('k00473', $record->location->shelvingLocation);
101-
$this->assertEquals('Plv 157', $record->location->callCode);
101+
$this->assertEquals('k00473', $record->location->shelvinglocation);
102+
$this->assertEquals('Plv 157', $record->location->callcode);
103+
}
104+
105+
public function testHoldingsToJson()
106+
{
107+
$record = Record::fromFile(__DIR__ . '/data/holdings.xml');
108+
109+
$this->assertEquals([
110+
'type' => MARC21::HOLDINGS,
111+
'id' => 'h2051843-47bibsys_ubo',
112+
'location' => [
113+
'sublocation' => '1030310',
114+
'shelvinglocation' => 'k00473',
115+
'callcode' => 'Plv 157',
116+
],
117+
], $record->jsonSerialize());
118+
}
119+
120+
public function testBibliographicToJson()
121+
{
122+
$record = Record::fromFile(__DIR__ . '/data/bibliographic.xml');
123+
124+
$this->assertEquals([
125+
'type' => MARC21::BIBLIOGRAPHIC,
126+
'id' => '999401461934702201',
127+
'title' => 'The eightfold way',
128+
'subjects' => [
129+
[
130+
'type' => Subject::TOPICAL_TERM,
131+
'vocabulary' => 'lcsh',
132+
'term' => 'Eightfold way (Nuclear physics) : Addresses, essays, lectures',
133+
],
134+
[
135+
'type' => Subject::TOPICAL_TERM,
136+
'vocabulary' => 'lcsh',
137+
'term' => 'Nuclear reactions : Addresses, essays, lectures',
138+
],
139+
],
140+
'isbns' => [],
141+
], $record->jsonSerialize());
102142
}
103143

104144
public function testRecordTypeDescriptiveCatalogingForm()

tests/SubjectFieldTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function testSubjects()
3535
$this->assertEquals('noubomn', $subject->vocabulary);
3636
$this->assertEquals('Elementærpartikler', strval($subject));
3737
$this->assertEquals(Subject::TOPICAL_TERM, $subject->getType());
38-
$this->assertNull($subject->getControlNumber());
38+
$this->assertNull($subject->getId());
3939
}
4040

4141
public function testRepeated653a()
@@ -101,7 +101,6 @@ public function testJsonSerialization()
101101
json_encode([
102102
'vocabulary' => 'noubomn',
103103
'type' => Subject::TOPICAL_TERM,
104-
'id' => null,
105104
'term' => 'Elementærpartikler'
106105
]),
107106
json_encode($subject)

0 commit comments

Comments
 (0)