3
3
namespace Scriptotek \Marc \Fields ;
4
4
5
5
use File_MARC_Field ;
6
+ use File_MARC_Subfield ;
6
7
use JsonSerializable ;
7
8
use Scriptotek \Marc \MagicAccess ;
8
9
use Scriptotek \Marc \Record ;
9
10
11
+ /**
12
+ * The MARC field wrapper.
13
+ *
14
+ * We wrap File_MARC_Field rather than extend it, just like in our Record
15
+ * class. File_MARC_Field has two known subclasses, namely File_MARC_Data_Field
16
+ * and File_MARC_Control_Field.
17
+ *
18
+ * Methods on the wrapped field that are not implemented here may be accessed
19
+ * using magic method calls, or through `getField()`. Method tags are included
20
+ * below to aid IDE code hinting, but using the getter will give you better
21
+ * code
22
+ * hinting and documentation.
23
+ *
24
+ * @method string getTag()
25
+ * @method string setTag()
26
+ * @method bool isEmpty()
27
+ * @method bool isControlField()
28
+ * @method bool isDataField()
29
+ * @method string toRaw()
30
+ * @method formatField(array $exclude = array('2'))
31
+ *
32
+ * FIXME: These methods are just implemented in File_MARC_Data_Field and not in
33
+ * File_MARC_Field or File_MARC_Control_Field, so they may not always be
34
+ * available:
35
+ *
36
+ * @method File_MARC_Subfield appendSubfield(File_MARC_Subfield $new_subfield)
37
+ * @method File_MARC_Subfield prependSubfield(File_MARC_Subfield $new_subfield)
38
+ * @method File_MARC_Subfield insertSubfield(File_MARC_Subfield $new_field, File_MARC_Subfield $existing_field, bool $before = false)
39
+ * @method int addSubfields(array $subfields)
40
+ * @method deleteSubfield(File_MARC_Subfield $subfield)
41
+ * @method string getIndicator(int $ind)
42
+ * @method string setIndicator(int $ind, string $value)
43
+ * @method string getSubfield(string $code = null, bool $pcre = null)
44
+ * @method array getSubfields(string $code = null, bool $pcre = null)
45
+ * @method string getContents(string $joinChar = '')
46
+ *
47
+ * FIXME: These methods are just implemented in File_MARC_Control_Field and not
48
+ * in File_MARC_Field or File_MARC_Data_Field, so they may not always be
49
+ * available:
50
+ *
51
+ * @method string getData()
52
+ * @method bool setData(string $data)
53
+ */
10
54
class Field implements JsonSerializable
11
55
{
12
56
use SerializableField, MagicAccess;
13
57
14
58
/**
15
- * @var array List of properties to be included when serializing the record using the `toArray()` method.
59
+ * @var array List of properties to be included when serializing the record
60
+ * using the `toArray()` method.
16
61
*/
17
62
public $ properties = [];
18
63
64
+ /**
65
+ * The characters used to separate values of a subfield.
66
+ *
67
+ * @var string
68
+ */
19
69
public static $ glue = ' : ' ;
70
+
71
+ /**
72
+ * Whether to strip punctuation from the end of some field values.
73
+ *
74
+ * @var bool
75
+ */
20
76
public static $ chopPunctuation = true ;
21
77
78
+ /**
79
+ * The wrapped field.
80
+ *
81
+ * @var \File_MARC_Field
82
+ */
22
83
protected $ field ;
23
84
85
+ /**
86
+ * Field constructor.
87
+ *
88
+ * @param \File_MARC_Field $field
89
+ * The field to wrap.
90
+ */
24
91
public function __construct (File_MARC_Field $ field )
25
92
{
26
93
$ this ->field = $ field ;
@@ -36,16 +103,41 @@ public function getField()
36
103
return $ this ->field ;
37
104
}
38
105
106
+ /**
107
+ * Delegate all unknown method calls to the wrapped field.
108
+ *
109
+ * @param string $name
110
+ * The name of the method being called.
111
+ * @param array $args
112
+ * The arguments being passed to the method.
113
+ *
114
+ * @return mixed
115
+ */
39
116
public function __call ($ name , $ args )
40
117
{
41
118
return call_user_func_array ([$ this ->field , $ name ], $ args );
42
119
}
43
120
121
+ /**
122
+ * Get a string representation of this field.
123
+ *
124
+ * @return string
125
+ */
44
126
public function __toString ()
45
127
{
46
128
return $ this ->field ->__toString ();
47
129
}
48
130
131
+ /**
132
+ * Remove extra whitespace and punctuation from field values.
133
+ *
134
+ * @param string $value
135
+ * The value to clean.
136
+ * @param array $options
137
+ * A list of options. Currently only the chopPunctuation key is used.
138
+ *
139
+ * @return string
140
+ */
49
141
protected function clean ($ value , $ options = [])
50
142
{
51
143
$ chopPunctuation = isset ($ options ['chopPunctuation ' ]) ? $ options ['chopPunctuation ' ] : static ::$ chopPunctuation ;
@@ -57,15 +149,20 @@ protected function clean($value, $options = [])
57
149
}
58
150
59
151
/**
152
+ * Extract values from subfields of this field.
153
+ *
60
154
* @param string|string[] $codes
61
- * @return array
155
+ * The subfield code or an array of such codes.
156
+ * @return string[]
157
+ * The values that were contained in the requested subfields.
62
158
*/
63
159
protected function getSubfieldValues ($ codes )
64
160
{
65
161
if (!is_array ($ codes )) {
66
162
$ codes = [$ codes ];
67
163
}
68
164
$ parts = [];
165
+ /** @var \File_MARC_Subfield $sf */
69
166
foreach ($ this ->field ->getSubfields () as $ sf ) {
70
167
if (in_array ($ sf ->getCode (), $ codes )) {
71
168
$ parts [] = trim ($ sf ->getData ());
@@ -79,8 +176,11 @@ protected function getSubfieldValues($codes)
79
176
* Return concatenated string of the given subfields.
80
177
*
81
178
* @param string[] $codes
82
- * @param array $options
179
+ * The subfield codes to retrieve.
180
+ * @param array $options
181
+ * Options to pass to the `clean` method.
83
182
* @return string
183
+ * The concatenated subfield values.
84
184
*/
85
185
protected function toString ($ codes , $ options = [])
86
186
{
@@ -89,19 +189,22 @@ protected function toString($codes, $options = [])
89
189
}
90
190
91
191
/**
92
- * Return a line MARC representation of the field. If the field is deleted,
93
- * null is returned.
192
+ * Get a line MARC representation of the field.
94
193
*
95
- * @param string $sep Subfield separator character, defaults to '$'
96
- * @param string $blank Blank indicator character, defaults to ' '
97
- * @return string|null.
194
+ * @param string $sep
195
+ * Subfield separator character, defaults to '$'
196
+ * @param string $blank
197
+ * Blank indicator character, defaults to ' '
198
+ * @return string|null
199
+ * A line MARC representation of the field or NULL if the field is empty.
98
200
*/
99
201
public function asLineMarc ($ sep = '$ ' , $ blank = ' ' )
100
202
{
101
203
if ($ this ->field ->isEmpty ()) {
102
204
return null ;
103
205
}
104
206
$ subfields = [];
207
+ /** @var \File_MARC_Subfield $sf */
105
208
foreach ($ this ->field ->getSubfields () as $ sf ) {
106
209
$ subfields [] = $ sep . $ sf ->getCode () . ' ' . $ sf ->getData ();
107
210
}
@@ -122,30 +225,44 @@ public function asLineMarc($sep = '$', $blank = ' ')
122
225
* Return the data value of the *first* subfield with a given code.
123
226
*
124
227
* @param string $code
228
+ * The subfield identifier.
125
229
* @param mixed $default
230
+ * The fallback value to return if the subfield does not exist.
126
231
* @return mixed
127
232
*/
128
233
public function sf ($ code , $ default = null )
129
234
{
130
-
131
235
// In PHP, ("a" == 0) will evaluate to TRUE, so it's actually very important that we ensure type here!
132
236
$ code = (string ) $ code ;
133
237
134
- $ subfield = $ this ->getSubfield ($ code );
238
+ /** @var \File_MARC_Subfield $subfield */
239
+ $ subfield = $ this ->field ->getSubfield ($ code );
135
240
if (!$ subfield ) {
136
241
return $ default ;
137
242
}
138
243
139
244
return trim ($ subfield ->getData ());
140
245
}
141
246
247
+ /**
248
+ * TODO: document this function.
249
+ *
250
+ * @param $map
251
+ * TODO: ?
252
+ * @param bool $includeNullValues
253
+ * TODO: ?
254
+ *
255
+ * @return array
256
+ * TODO: ?
257
+ */
142
258
public function mapSubFields ($ map , $ includeNullValues = false )
143
259
{
144
260
$ o = [];
145
261
foreach ($ map as $ code => $ prop ) {
146
262
$ value = $ this ->sf ($ code );
147
263
148
- foreach ($ this ->getSubfields () as $ q ) {
264
+ /** @var \File_MARC_Subfield $q */
265
+ foreach ($ this ->field ->getSubfields () as $ q ) {
149
266
if ($ q ->getCode () === $ code ) {
150
267
$ value = $ q ->getData ();
151
268
}
@@ -158,7 +275,20 @@ public function mapSubFields($map, $includeNullValues = false)
158
275
return $ o ;
159
276
}
160
277
161
- public static function makeFieldObject (Record $ record , $ tag , $ pcre =false )
278
+ /**
279
+ * TODO: document this function.
280
+ *
281
+ * @param \Scriptotek\Marc\Record $record
282
+ * TODO: ?
283
+ * @param string $tag
284
+ * The tag name.
285
+ * @param bool $pcre
286
+ * If true, match as a regular expression.
287
+ *
288
+ * @return \Scriptotek\Marc\Fields\Field
289
+ * TODO: ?
290
+ */
291
+ public static function makeFieldObject (Record $ record , $ tag , $ pcre = false )
162
292
{
163
293
$ field = $ record ->getField ($ tag , $ pcre );
164
294
@@ -167,10 +297,22 @@ public static function makeFieldObject(Record $record, $tag, $pcre=false)
167
297
return $ field ? new static ($ field ->getField ()) : null ;
168
298
}
169
299
170
- public static function makeFieldObjects (Record $ record , $ tag , $ pcre =false )
300
+ /**
301
+ * TODO: document this function.
302
+ *
303
+ * @param \Scriptotek\Marc\Record $record
304
+ * TODO: ?
305
+ * @param string $tag
306
+ * The tag name.
307
+ * @param bool $pcre
308
+ * If true, match as a regular expression.
309
+ *
310
+ * @return \Scriptotek\Marc\Fields\Field[]
311
+ * TODO: ?
312
+ */
313
+ public static function makeFieldObjects (Record $ record , $ tag , $ pcre = false )
171
314
{
172
- return array_map (function ($ field ) {
173
-
315
+ return array_map (function (Field $ field ) {
174
316
// Note: `new static()` is a way of creating a new instance of the
175
317
// called class using late static binding.
176
318
return new static ($ field ->getField ());
0 commit comments