diff --git a/src/HL7/Message.php b/src/HL7/Message.php index 9b571a5..02f7462 100644 --- a/src/HL7/Message.php +++ b/src/HL7/Message.php @@ -187,15 +187,37 @@ public function getSegmentsByName(string $name): array { $segmentsByName = []; - foreach ($this->segments as $seg) { - if ($seg->getName() === $name) { - $segmentsByName[] = $seg; + foreach ($this->segments as $segment) { + if ($segment->getName() === $name) { + $segmentsByName[] = $segment; } } return $segmentsByName; } + /** + * Return an array of all segments with the given subclass of Segment + * + * @param string $name Segment class + * @return array List of segments identified by class + */ + public function getSegmentsByClass(string $segmentClass): array + { + if (!is_subclass_of($segmentClass, Segment::class)) { + throw new HL7Exception("$segmentClass is not a subclass of " . Segment::class); + } + $segmentsByClass = []; + + foreach ($this->segments as $segment) { + if ($segment instanceof $segmentClass) { + $segmentsByClass[] = $segment; + } + } + + return $segmentsByClass; + } + /** * Remove the segment indexed by $index. * @@ -228,6 +250,24 @@ public function removeSegmentsByName(string $segmentName): int return $count; } + /** + * Remove given segment + * + * @return int Count of segments removed + */ + public function removeSegmentsByClass(string $segmentClass): int + { + if (!is_subclass_of($segmentClass, Segment::class)) { + throw new HL7Exception("$segmentClass is not a subclass of " . Segment::class); + } + $count = 0; + foreach ($this->getSegmentsByClass($segmentClass) as $segment) { + $this->removeSegmentByIndex($this->getSegmentIndex($segment)); + $count++; + } + return $count; + } + /** * Set the segment on index. * @@ -323,11 +363,11 @@ public function toString(bool $pretty = false) /** * Convert Segment object to string */ - public function segmentToString(Segment $seg): string + public function segmentToString(Segment $segment): string { - $segmentName = $seg->getName(); + $segmentName = $segment->getName(); $segmentString = $segmentName . $this->fieldSeparator; - $fields = $seg->getFields(($segmentName === 'MSH' ? 2 : 1)); + $fields = $segment->getFields(($segmentName === 'MSH' ? 2 : 1)); foreach ($fields as $field) { if (is_array($field)) { diff --git a/src/HL7/MessageHelpersTrait.php b/src/HL7/MessageHelpersTrait.php index 7d5da55..3a59da8 100644 --- a/src/HL7/MessageHelpersTrait.php +++ b/src/HL7/MessageHelpersTrait.php @@ -17,13 +17,13 @@ trait MessageHelpersTrait */ public function getSegmentAsString(int $index): ?string { - $seg = $this->getSegmentByIndex($index); + $segment = $this->getSegmentByIndex($index); - if ($seg === null) { + if ($segment === null) { return null; } - return $this->segmentToString($seg); + return $this->segmentToString($segment); } /** @@ -117,6 +117,22 @@ public function hasSegment(string $segment): bool return count($this->getSegmentsByName(strtoupper($segment))) > 0; } + /** + * Check if given segment is present in the message object by class name + */ + public function hasSegmentOfClass(string $segmentClass): bool + { + return count($this->getSegmentsByClass($segmentClass)) > 0; + } + + /** + * Check if given segment is present in the message object by class name + */ + public function hasSegmentByClass(string $segmentClass): bool + { + return count($this->getSegmentsByClass($segmentClass)) > 0; + } + /** * Return the first segment with given name in the message * @@ -130,6 +146,19 @@ public function getFirstSegmentInstance(string $segment) return $this->getSegmentsByName($segment)[0]; } + /** + * Return the first segment of the given class in the message + * + * @return mixed|null + */ + public function getFirstSegmentInstanceByClass(string $segmentClass) + { + if (!$this->hasSegmentOfClass($segmentClass)) { + return null; + } + return $this->getSegmentsByClass($segmentClass)[0]; + } + /** * @param bool $reIndex After deleting, re-index remaining segments of same name */ @@ -145,9 +174,9 @@ public function removeSegment(Segment $segment, bool $reIndex = false): void $segments = $this->getSegmentsByName($segment->getName()); $index = 1; - /** @var Segment $seg */ - foreach ($segments as $seg) { - $seg->setField(1, $index++); + /** @var Segment $segment */ + foreach ($segments as $segment) { + $segment->setField(1, $index++); } } diff --git a/tests/MessageTest.php b/tests/MessageTest.php index a065bac..c09a48f 100644 --- a/tests/MessageTest.php +++ b/tests/MessageTest.php @@ -8,6 +8,8 @@ use Aranyasen\HL7\Message; use Aranyasen\HL7\Segment; use Aranyasen\HL7\Segments\MSH; +use Aranyasen\HL7\Segments\OBR; +use Aranyasen\HL7\Segments\OBX; use Aranyasen\HL7\Segments\PID; use Exception; use InvalidArgumentException; @@ -189,6 +191,11 @@ public function segment_can_be_removed_from_message(): void $msg->toString(true), 'Should reset index of subsequent segments' ); + + $msg = new Message("MSH|^~\\&|1|\nAAA|1||xxx|\nPID|1|\nBBB|2|"); + $segment = $msg->getFirstSegmentInstanceByClass(PID::class); + $msg->removeSegment($segment); + self::assertSame("MSH|^~\\&|1|\nAAA|1||xxx|\nBBB|2|\n", $msg->toString(true)); } /** @test */ @@ -547,6 +554,11 @@ public function first_of_the_given_segment_name_can_be_easily_obtained_using_a_h self::assertIsObject($firstPidSegment); self::assertInstanceOf(PID::class, $firstPidSegment); + $firstPidSegment = $message->getFirstSegmentInstanceByClass(PID::class); + self::assertNotNull($firstPidSegment); + self::assertIsObject($firstPidSegment); + self::assertInstanceOf(PID::class, $firstPidSegment); + self::assertNull($message->getFirstSegmentInstance('XXX'), 'Non existing segment should return null'); } @@ -603,4 +615,22 @@ public function a_message_can_be_saved_in_a_file(): void unlink($hl7File); } } + + /** @test */ + public function segments_can_be_retrieved_by_class(): void + { + $message = new Message("MSH|^~\&|||||||ADT^A01||P|2.3.1|\nPID|||3^0~4^1\nOBX|1|||\nOBX|2|||", + doNotSplitRepetition: true); + $MSHs = $message->getSegmentsByClass(MSH::class); + self::assertCount(1, $MSHs); + self::assertInstanceOf(MSH::class, $MSHs[0]); + $PIDs = $message->getSegmentsByClass(PID::class); + self::assertCount(1, $PIDs); + self::assertInstanceOf(PID::class, $PIDs[0]); + $OBXs = $message->getSegmentsByClass(OBX::class); + self::assertCount(2, $OBXs); + self::assertInstanceOf(OBX::class, $OBXs[0]); + $OBRs = $message->getSegmentsByClass(OBR::class); + self::assertCount(0, $OBRs); + } }