Skip to content

Commit

Permalink
Add methods to access segments by class name
Browse files Browse the repository at this point in the history
  • Loading branch information
jay-knight committed Sep 29, 2024
1 parent 50ca9d5 commit c373704
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 12 deletions.
52 changes: 46 additions & 6 deletions src/HL7/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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)) {
Expand Down
41 changes: 35 additions & 6 deletions src/HL7/MessageHelpersTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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
*
Expand All @@ -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
*/
Expand All @@ -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++);
}
}

Expand Down
32 changes: 32 additions & 0 deletions tests/MessageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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');
}

Expand Down Expand Up @@ -603,4 +615,24 @@ 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);
}
}

0 comments on commit c373704

Please sign in to comment.