Skip to content

Commit c759645

Browse files
committed
added new MARCspecParser
1 parent 00500e6 commit c759645

12 files changed

+875
-812
lines changed

Exception/InvalidMARCspecException.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class InvalidMARCspecException extends \UnexpectedValueException {
1717

1818
const METHOD = 'In method ';
1919
const ARGUMENT = 'Tried to parse ';
20-
const UNKNOWN = 'Unknown Error.';
20+
const UNKNOWN = 'Assuming invalid spec.';
2121
const MS = 'MARCspec. ';
2222
const FS = 'Fieldspec. ';
2323
const SF = 'Subfieldspec. ';
@@ -36,7 +36,9 @@ class InvalidMARCspecException extends \UnexpectedValueException {
3636
const LENGTH3 = 'Invalid spec length. At minimum spec must be three characters long.';
3737
const PREFIX = 'Missing prefixed character "$".';
3838
const ESCAPE = 'Unescaped character detected';
39+
const DETECTEDSF = 'Detected Subfield. Use method MARCspec::addSubfields to add subfields.';
3940
const DETECTEDSS = 'Detected Subspec. Use method addSubSpec to add subspecs.';
41+
const MULTISF = 'Detected more than one subfieldspecs. Use method addSubfields to add more than one subfield.';
4042
const INDEX = 'Invalid index detected.';
4143
const PRCHAR = 'For character position or range minimum one digit or character # is required.';
4244
const USELESS = 'Detected useless data fragment.';

Field.php

Lines changed: 48 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,16 @@ class Field extends PositionOrRange implements FieldInterface, \JsonSerializable
6464
*
6565
* @throws InvalidMARCspecException
6666
*/
67-
public function __construct($fieldspec)
67+
public function __construct($fieldspec = null)
6868
{
69+
if(is_null($fieldspec)) return;
70+
6971
$this->checkIfString($fieldspec);
72+
7073
$spec = trim($fieldspec);
74+
7175
$specLength = strlen($fieldspec);
76+
7277
// check string length
7378
if(3 > $specLength)
7479
{
@@ -94,138 +99,51 @@ public function __construct($fieldspec)
9499
$fieldspec
95100
);
96101
}
97-
98-
/**
99-
* $specMatches[0] => whole spec
100-
* $specMatches[1] => tag
101-
* $specMatches[2] => indexSpec
102-
* $specMatches[3] => charSpec
103-
* $specMatches[4] => indicatorSpec
104-
* $specMatches[5] => useless
105-
*/
106-
if(0 === preg_match(
107-
'/^([a-z0-9\.]{3,3}|[A-Z0-9\.]{3,3}|[0-9\.]{3,3})(\[(?:(?:(?:[0-9]+|#)\-(?:[0-9]+|#))|(?:[0-9]+|#))\])?(?:(\/(?:(?:(?:[0-9]+|#)\-(?:[0-9]+|#))|(?:[0-9]+|#)))|(_[_a-z0-9][_a-z0-9]{0,1}))?(.*)?/',
108-
$fieldspec,$specMatches)
109-
)
102+
103+
$parser = new MARCspecParser();
104+
105+
$parser->fieldToArray($fieldspec);
106+
107+
if(array_key_exists('subfields',$parser->parsed))
110108
{
111109
throw new InvalidMARCspecException(
112110
InvalidMARCspecException::FS.
113-
InvalidMARCspecException::UNKNOWN,
111+
InvalidMARCspecException::DETECTEDSF,
114112
$fieldspec
115113
);
116114
}
117-
118-
$this->setTag($specMatches[1]);
119-
120-
if($specLength > 3)
115+
116+
$this->setTag($parser->field['tag']);
117+
118+
if(array_key_exists('index',$parser->field))
121119
{
122-
// check an set indexSpec
123-
if(!array_key_exists(2,$specMatches))
124-
{
125-
throw new InvalidMARCspecException(
126-
InvalidMARCspecException::FS.
127-
InvalidMARCspecException::INDEX,
128-
$fieldspec
129-
);
130-
}
131-
132-
if(!empty($specMatches[2]))
133-
{
134-
if( preg_match('/^\[(.*)\]/', $specMatches[2], $_assumedIndex) )
135-
{
136-
if( $_index = $this->validatePos($_assumedIndex[1]) )
137-
{
138-
$indexEnd = null;
139-
if(array_key_exists('1',$_index))
140-
{
141-
if(null !== ($_index[1]))
142-
{
143-
$indexEnd = $_index[1];
144-
}
145-
}
146-
$this->setIndexStartEnd($_index[0],$indexEnd);
147-
}
148-
}
149-
else
150-
{
151-
throw new InvalidMARCspecException(
152-
InvalidMARCspecException::FS.
153-
InvalidMARCspecException::INDEX,
154-
$fieldspec
155-
);
156-
}
157-
}
158-
159-
if(!empty($specMatches[3]) && !empty($specMatches[4]))
160-
{
161-
throw new InvalidMARCspecException(
162-
InvalidMARCspecException::FS.
163-
InvalidMARCspecException::CHARORIND,
164-
$fieldspec
165-
);
166-
}
167-
168-
if(!empty($specMatches[3]))
169-
{
170-
// check character position or range
171-
$charPosOrRange = substr($specMatches[3], 1);
172-
if('' != $charPosOrRange)
173-
{
174-
if($_charPosOrRange = $this->validatePos($charPosOrRange))
175-
{
176-
$charEnd = null;
177-
if(array_key_exists(1,$_charPosOrRange))
178-
{
179-
if(isset($_charPosOrRange[1]))
180-
{
181-
$charEnd = $_charPosOrRange[1];
182-
}
183-
}
184-
$this->setCharStartEnd($_charPosOrRange[0],$charEnd);
185-
}
186-
}
187-
else
188-
{
189-
throw new InvalidMARCspecException(
190-
InvalidMARCspecException::PR.
191-
InvalidMARCspecException::PRCHAR,
192-
$fieldspec
193-
);
194-
}
195-
}
196-
197-
if(!empty($specMatches[4]))
198-
{
199-
$this->setIndicators(substr($specMatches[4],1));
200-
}
201-
202-
if(!empty($specMatches[5]))
203-
{
204-
throw new InvalidMARCspecException(
205-
InvalidMARCspecException::FS.
206-
InvalidMARCspecException::USELESS,
207-
$fieldspec
208-
);
209-
}
120+
$_pos = MARCspec::validatePos($parser->field['index']);
121+
122+
$this->setIndexStartEnd($_pos[0],$_pos[1]);
210123
}
211124
else
212125
{
213126
// as of MARCspec 3.2.2 spec without index is always an abbreviation
214127
$this->setIndexStartEnd(0,"#");
215128
}
129+
130+
if(array_key_exists('indicators',$parser->field))
131+
{
132+
$this->setIndicators($parser->field['indicators']);
133+
}
134+
elseif(array_key_exists('charpos',$parser->field))
135+
{
136+
$_chars = MARCspec::validatePos($parser->field['charpos']);
137+
138+
$this->setCharStartEnd($_chars[0],$_chars[1]);
139+
}
216140
}
217141

218142
/**
219143
*
220-
* Set the field tag
221-
*
222-
* Provided param gets validated
223-
*
224-
* @access private
225-
*
226-
* @param string $arg The field tag
144+
* {@inheritdoc}
227145
*/
228-
private function setTag($arg)
146+
public function setTag($arg)
229147
{
230148
if($this->validateTag($arg)) $this->tag = $arg;
231149
}
@@ -422,15 +340,9 @@ public function jsonSerialize()
422340
{
423341
$_fieldSpec['tag'] = $this->getTag();
424342

425-
if(($indexStart = $this->getIndexStart()) !== null)
426-
{
427-
$_fieldSpec['indexStart'] = $indexStart;
428-
}
343+
$_fieldSpec['indexStart'] = $this->getIndexStart();
429344

430-
if(($indexEnd = $this->getIndexEnd()) !== null)
431-
{
432-
$_fieldSpec['indexEnd'] = $indexEnd;
433-
}
345+
$_fieldSpec['indexEnd'] = $this->getIndexEnd();
434346

435347
if(($indexLength = $this->getIndexLength()) !== null)
436348
{
@@ -490,24 +402,23 @@ public function jsonSerialize()
490402
public function getBaseSpec()
491403
{
492404
$fieldSpec = $this->getTag();
493-
if(($indexStart = $this->getIndexStart()) !== null)
405+
$indexStart = $this->getIndexStart();
406+
$indexEnd = $this->getIndexEnd();
407+
if(0 === $indexStart && "#" === $indexEnd)
494408
{
495-
$indexEnd = $this->getIndexEnd();
496-
if(0 === $indexStart && "#" === $indexEnd)
497-
{
498-
// use abbreviation
499-
}
500-
else
409+
// use abbreviation
410+
}
411+
else
412+
{
413+
$fieldSpec .= "[".$indexStart;
414+
415+
if($indexEnd !== null && $indexStart !== $indexEnd)
501416
{
502-
$fieldSpec .= "[".$indexStart;
503-
if($indexEnd !== null)
504-
{
505-
$fieldSpec .= "-".$indexEnd;
506-
}
507-
$fieldSpec .= "]";
417+
$fieldSpec .= "-".$indexEnd;
508418
}
509-
419+
$fieldSpec .= "]";
510420
}
421+
511422
if(($charStart = $this->getCharStart()) !== null)
512423
{
513424
$charEnd = $this->getCharEnd();

FieldInterface.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,19 @@ interface FieldInterface
2525
*/
2626
public function __construct($fieldspec);
2727

28+
29+
/**
30+
*
31+
* Set the field tag
32+
*
33+
* Provided param gets validated
34+
*
35+
* @api
36+
*
37+
* @param string $arg The field tag
38+
*/
39+
public function setTag($arg);
40+
2841
/**
2942
*
3043
* Get the field tag

0 commit comments

Comments
 (0)