diff --git a/Exception/InvalidMARCspecException.php b/Exception/InvalidMARCspecException.php index 569602a..1598a1c 100755 --- a/Exception/InvalidMARCspecException.php +++ b/Exception/InvalidMARCspecException.php @@ -44,7 +44,7 @@ class InvalidMARCspecException extends \UnexpectedValueException { const LENGTHIND = 'For indicators only two characters at are allowed.'; const INDCHAR1 = 'At minimum one indicator must be a digit or a lowercase alphabetic character.'; const INDCHAR2 = 'For indicators only digits, lowercase alphabetic characters and "_" are allowed.'; - const NEGATIVE = 'Ending character position or index must be equal or higher than starting character potion or index.'; + const NEGATIVE = 'Ending character or index position must be equal or higher than starting character or index position.'; const PR1 = 'Assuming index or character position or range. Minimum one character is required. None given.'; const PR2 = 'Assuming index or character position or range. Only digits, the character # and one "-" is allowed.'; const PR3 = 'Assuming index or character range. At least two digits or the character # must be present.'; diff --git a/Field.php b/Field.php index f1c0608..a0b2ca8 100755 --- a/Field.php +++ b/Field.php @@ -425,6 +425,11 @@ public function jsonSerialize() $_fieldSpec['indexEnd'] = $indexEnd; } + if(($indexLength = $this->getIndexLength()) !== null) + { + $_fieldSpec['indexLength'] = $indexLength; + } + if(($charStart = $this->getCharStart()) !== null) { $_fieldSpec['charStart'] = $charStart; @@ -549,6 +554,8 @@ public function offsetExists($offset) break; case 'indexEnd': return isset($this->indexEnd); break; + case 'indexLength': return !is_null($this->getIndexLength()); + break; case 'charStart': return isset($this->charStart); break; case 'charEnd': return isset($this->charEnd); @@ -583,6 +590,8 @@ public function offsetGet($offset) break; case 'indexEnd': return $this->getIndexEnd(); break; + case 'indexLength': return $this->getIndexLength(); + break; case 'charStart': return $this->getCharStart(); break; case 'charEnd': return $this->getCharEnd(); @@ -613,6 +622,7 @@ public function offsetSet($offset,$value) { case 'indexStart': $this->setIndexStartEnd($value); break; + case 'indexEnd': if(!isset($this['indexStart'])) { @@ -623,8 +633,13 @@ public function offsetSet($offset,$value) $this->setIndexStartEnd($this['indexStart'],$value); } break; + + case 'indexLength': throw new \UnexpectedValueException("indexLength is always calculated."); + break; + case 'charStart': $this->setCharStartEnd($value); break; + case 'charEnd': if(!isset($this['charStart'])) { @@ -635,14 +650,19 @@ public function offsetSet($offset,$value) $this->setCharStartEnd($this['charStart'],$value); } break; + case 'charLength': throw new \UnexpectedValueException("CharLength is always calculated."); break; + case 'indicator1': $this->setIndicator1($value); break; + case 'indicator2': $this->setIndicator2($value); break; + case 'subSpecs': $this->addSubSpec($value); break; + default: throw new \UnexpectedValueException("Offset $offset cannot be set."); } } diff --git a/PositionOrRange.php b/PositionOrRange.php index c7ad3df..a30a594 100755 --- a/PositionOrRange.php +++ b/PositionOrRange.php @@ -122,6 +122,46 @@ public function getCharLength() } } + /** + * {@inheritdoc} + */ + public function getIndexLength() + { + if( is_null($this->getIndexStart()) && is_null($this->getIndexEnd()) ) + { + return null; + } + if( !is_null($this->getIndexStart()) && is_null($this->getIndexEnd()) ) + { + return 1; + } + // both defined + if($this->indexStart === $this->indexEnd) + { + return 1; + } + if('#' === $this->indexStart && '#' !== $this->indexEnd) + { + return $this->indexEnd + 1; + } + if('#' !== $this->indexStart && '#' === $this->indexEnd) + { + return null; + } + else + { + $length = $this->indexEnd - $this->indexStart + 1; + if(1 > $length) + { + throw new InvalidMARCspecException( + InvalidMARCspecException::PR. + InvalidMARCspecException::NEGATIVE + ); + } + return $length; + } + } + /** * {@inheritdoc} */ @@ -157,7 +197,7 @@ protected function validatePos($pos) for($x = 0; $x < $posLength; $x++) { - if(!preg_match('/[0-9-#]/', $pos[$x])) // alphabetic characters etc. are not valid + if(!preg_match('/[0-9\-#]/', $pos[$x])) // alphabetic characters etc. are not valid { throw new InvalidMARCspecException( InvalidMARCspecException::PR. diff --git a/PositionOrRangeInterface.php b/PositionOrRangeInterface.php index feea1ac..05dd735 100755 --- a/PositionOrRangeInterface.php +++ b/PositionOrRangeInterface.php @@ -133,4 +133,18 @@ public function getCharEnd(); * @throws \InvalidArgumentException if length is less than 1 */ public function getCharLength(); + + /** + * + * Get length of index range + * + * @api + * + * @access public + * + * @return null|int $length The index range length + * + * @throws \InvalidArgumentException if length is less than 1 + */ + public function getIndexLength(); } // EOI diff --git a/README.md b/README.md index dc6c216..856c3f1 100755 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ For currently supported version of **MARCspec - A common MARC record path langua # Installation -Installation can be done by using [composer](https://getcomposer.org/doc/00-intro.md) +Installation can be done by using [composer](https://getcomposer.org/doc/00-intro.md). -```php +```json { "require": { "ck/php-marcspec": "1.*" diff --git a/Subfield.php b/Subfield.php index 224c649..8b29b53 100755 --- a/Subfield.php +++ b/Subfield.php @@ -278,6 +278,11 @@ public function jsonSerialize() $_subfieldSpec['indexEnd'] = $indexEnd; } + if(($indexLength = $this->getIndexLength()) !== null) + { + $_subfieldSpec['indexLength'] = $indexLength; + } + if(($charStart = $this->getCharStart()) !== null) { $_subfieldSpec['charStart'] = $charStart; @@ -384,26 +389,21 @@ public function offsetExists($offset) { case 'tag': return isset($this->tag); - break; - + break; case 'indexStart': return isset($this->indexStart); - break; - + break; case 'indexEnd': return isset($this->indexEnd); - break; - + break; + case 'indexLength': return !is_null($this->getIndexLength()); + break; case 'charStart': return isset($this->charStart); - break; - + break; case 'charEnd': return isset($this->charEnd); - break; - + break; case 'charLength': return !is_null($this->getCharLength()); - break; - + break; case 'subSpecs': return (0 < count($this->subSpecs)) ? true : false; - break; - + break; default: return false; } } @@ -420,26 +420,21 @@ public function offsetGet($offset) switch($offset) { case 'tag': return $this->getTag(); - break; - + break; case 'indexStart': return $this->getIndexStart(); - break; - + break; case 'indexEnd': return $this->getIndexEnd(); - break; - + break; + case 'indexLength': return $this->getIndexLength(); + break; case 'charStart': return $this->getCharStart(); - break; - + break; case 'charEnd': return $this->getCharEnd(); - break; - + break; case 'charLength': return $this->getCharLength(); - break; - + break; case 'subSpecs': return $this->getSubSpecs(); - break; - + break; default: return null; } } @@ -456,39 +451,42 @@ public function offsetSet($offset,$value) switch($offset) { case 'indexStart': $this->setIndexStartEnd($value); - break; + break; case 'indexEnd': - if(!isset($this['indexStart'])) - { - $this->setIndexStartEnd($value,$value); - } - else - { - $this->setIndexStartEnd($this['indexStart'],$value); - } - break; + if(!isset($this['indexStart'])) + { + $this->setIndexStartEnd($value,$value); + } + else + { + $this->setIndexStartEnd($this['indexStart'],$value); + } + break; - case 'charStart': $this->setCharStartEnd($value); - break; + case 'indexLength': throw new \UnexpectedValueException("indexLength is always calculated."); + break; + case 'charStart': $this->setCharStartEnd($value); + break; + case 'charEnd': - if(!isset($this['charStart'])) - { - $this->setCharStartEnd($value,$value); - } - else - { - $this->setCharStartEnd($this['charStart'],$value); - } - break; - + if(!isset($this['charStart'])) + { + $this->setCharStartEnd($value,$value); + } + else + { + $this->setCharStartEnd($this['charStart'],$value); + } + break; + case 'charLength': throw new \UnexpectedValueException("CharLength is always calculated."); - break; - + break; + case 'subSpecs': $this->addSubSpec($value); - break; - + break; + default: throw new \UnexpectedValueException("Offset $offset cannot be set."); } } diff --git a/Test/FieldTest.php b/Test/FieldTest.php index ca00899..c641af5 100755 --- a/Test/FieldTest.php +++ b/Test/FieldTest.php @@ -234,11 +234,11 @@ public function testValidFieldSpec1() $fieldSpec = $this->fieldspec('245[1-3]'); $this->assertSame(1, $fieldSpec->getIndexStart()); - $this->assertSame(3, $fieldSpec->getIndexEnd()); + $this->assertSame(3, $fieldSpec->getIndexEnd()); $fieldSpec = $this->fieldspec('245[1-#]'); $this->assertSame(1, $fieldSpec->getIndexStart()); - $this->assertSame('#', $fieldSpec->getIndexEnd()); + $this->assertSame('#', $fieldSpec->getIndexEnd()); $fieldSpec = $this->fieldspec('245[#-3]'); $this->assertSame('#', $fieldSpec->getIndexStart()); @@ -320,7 +320,7 @@ public function testValidFieldSpec23() /** * test character position and range */ - public function testSetAndGet() + public function testSetAndGetChar() { $fieldSpec = $this->fieldspec('LDR'); $fieldSpec->setCharStartEnd(0,3); @@ -349,8 +349,40 @@ public function testSetAndGet() $this->assertSame("#", $fieldSpec->getCharStart()); $this->assertSame(3, $fieldSpec->getCharEnd()); $this->assertSame(4, $fieldSpec->getCharLength()); + } + + /** + * test index position and range + */ + public function testSetAndGetIndex() + { + $fieldSpec = $this->fieldspec('300'); + $fieldSpec->setIndexStartEnd(0,3); + $this->assertSame('300', $fieldSpec->getTag()); + $this->assertSame(0, $fieldSpec->getIndexStart()); + $this->assertSame(3, $fieldSpec->getIndexEnd()); + $this->assertSame(4, $fieldSpec->getIndexLength()); - + $fieldSpec = $this->fieldspec('300'); + $fieldSpec->setIndexStartEnd("#",3); + $this->assertSame('300', $fieldSpec->getTag()); + $this->assertSame("#", $fieldSpec->getIndexStart()); + $this->assertSame(3, $fieldSpec->getIndexEnd()); + $this->assertSame(4, $fieldSpec->getIndexLength()); + + $fieldSpec = $this->fieldspec('300'); + $fieldSpec->setIndexStartEnd(0,4); + $this->assertSame('300', $fieldSpec->getTag()); + $this->assertSame(0, $fieldSpec->getIndexStart()); + $this->assertSame(4, $fieldSpec->getIndexEnd()); + $this->assertSame(5, $fieldSpec->getIndexLength()); + + $fieldSpec = $this->fieldspec('300'); + $fieldSpec->setIndexStartLength("#",4); + $this->assertSame('300', $fieldSpec->getTag()); + $this->assertSame("#", $fieldSpec->getIndexStart()); + $this->assertSame(3, $fieldSpec->getIndexEnd()); + $this->assertSame(4, $fieldSpec->getIndexLength()); } /** diff --git a/Test/SubfieldTest.php b/Test/SubfieldTest.php index 4bc5bbb..985c5ae 100755 --- a/Test/SubfieldTest.php +++ b/Test/SubfieldTest.php @@ -255,7 +255,7 @@ public function testValidSubfieldSpec22() /** * test character position and range */ - public function testSetAndGet() + public function testSetAndGetChar() { $Subfield = $this->subfieldspec('$a'); $Subfield->setCharStartEnd('0','3'); @@ -284,10 +284,41 @@ public function testSetAndGet() $this->assertSame("#", $Subfield->getCharStart()); $this->assertSame(3, $Subfield->getCharEnd()); $this->assertSame(4, $Subfield->getCharLength()); - + } + /** + * test index position and range + */ + public function testSetAndGetIndex() + { + $Subfield = $this->subfieldspec('$a'); + $Subfield->setIndexStartEnd('0','3'); + $this->assertSame('a', $Subfield->getTag()); + $this->assertSame(0, $Subfield->getIndexStart()); + $this->assertSame(3, $Subfield->getIndexEnd()); + $this->assertSame(4, $Subfield->getIndexLength()); + + $Subfield = $this->subfieldspec('$a'); + $Subfield->setIndexStartEnd("#",3); + $this->assertSame('a', $Subfield->getTag()); + $this->assertSame("#", $Subfield->getIndexStart()); + $this->assertSame(3, $Subfield->getIndexEnd()); + $this->assertSame(4, $Subfield->getIndexLength()); + + $Subfield = $this->subfieldspec('$a'); + $Subfield->setIndexStartEnd(0,4); + $this->assertSame('a', $Subfield->getTag()); + $this->assertSame(0, $Subfield->getIndexStart()); + $this->assertSame(4, $Subfield->getIndexEnd()); + $this->assertSame(5, $Subfield->getIndexLength()); + + $Subfield = $this->subfieldspec('$a'); + $Subfield->setIndexStartLength("#",4); + $this->assertSame('a', $Subfield->getTag()); + $this->assertSame("#", $Subfield->getIndexStart()); + $this->assertSame(3, $Subfield->getIndexEnd()); + $this->assertSame(4, $Subfield->getIndexLength()); } - /** * test encoding */