This commit is contained in:
Dr Masroor Ehsan 2025-01-22 11:52:20 +06:00
parent 8c580f55d6
commit 5c03963116
8 changed files with 80 additions and 39 deletions

View File

@ -0,0 +1,9 @@
<?php
namespace App\Domain\Rule;
enum MatchCondition: string
{
case And = 'AND';
case Or = 'OR';
}

View File

@ -0,0 +1,12 @@
<?php
namespace App\Domain\Rule;
enum MatchMode: string
{
case Exact = 'EXACT';
case Contains = 'CONTAINS';
case StartsWith = 'STARTS_WITH';
case EndsWith = 'ENDS_WITH';
case Regex = 'REGEX';
}

View File

@ -1,12 +0,0 @@
<?php
namespace App\Domain\Rule;
enum StringMatchMode: int
{
case Exact = 0;
case Contains = 1;
case StartsWith = 2;
case EndsWith = 3;
case Regex = 4;
}

View File

@ -2,7 +2,7 @@
namespace App\Services\Pacs;
use App\Domain\Rule\StringMatchMode;
use App\Domain\Rule\MatchMode;
use App\Services\StringMatcher;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
@ -21,8 +21,8 @@ public static function map(?string $input): array
if (empty(self::$patterns)) {
self::$patterns = Cache::remember('institute_names',
now()->addMinutes(15),
fn () => DB::table('dicom_mapping_rules')
->orderByDesc('sort_order')
fn () => DB::table('dicom_routing_rules')
->orderByDesc('priority')
->get()->toArray()
);
self::$catchAll = DB::table('institutes')->first('id')->id;
@ -32,7 +32,7 @@ public static function map(?string $input): array
$input = strtolower($input);
foreach (self::$patterns as $pattern) {
if (StringMatcher::match($input, $pattern->name, StringMatchMode::from($pattern->match_mode))) {
if (StringMatcher::match($input, $pattern->name, MatchMode::from($pattern->match_mode))) {
return [$pattern->institute_id, $pattern->facility_id];
}
}

View File

@ -2,27 +2,27 @@
namespace App\Services;
use App\Domain\Rule\StringMatchMode;
use App\Domain\Rule\MatchMode;
final class StringMatcher
{
public static function match(string $input, string $pattern, StringMatchMode $mode): bool
public static function match(string $input, string $pattern, MatchMode $mode): bool
{
if (blank($input) || blank($pattern)) {
return false;
}
if ($mode !== StringMatchMode::Regex) {
if ($mode !== MatchMode::Regex) {
$input = strtolower($input);
$pattern = strtolower($pattern);
}
return match ($mode) {
StringMatchMode::Exact => strcasecmp($input, $pattern) === 0,
StringMatchMode::Contains => str_contains($input, $pattern) ,
StringMatchMode::StartsWith => str_starts_with($input, $pattern),
StringMatchMode::EndsWith => str_ends_with($input, $pattern),
StringMatchMode::Regex => preg_match($pattern, $input) === 1,
MatchMode::Exact => strcasecmp($input, $pattern) === 0,
MatchMode::Contains => str_contains($input, $pattern) ,
MatchMode::StartsWith => str_starts_with($input, $pattern),
MatchMode::EndsWith => str_ends_with($input, $pattern),
MatchMode::Regex => preg_match($pattern, $input) === 1,
default => false,
};
}

View File

@ -1,6 +1,6 @@
<?php
use App\Domain\Rule\StringMatchMode;
use App\Domain\Rule\MatchCondition;
use App\Models\Facility;
use App\Models\Institute;
use Illuminate\Database\Migrations\Migration;
@ -11,22 +11,22 @@
{
public function up(): void
{
Schema::create('dicom_mapping_rules', static function (Blueprint $table) {
Schema::create('dicom_routing_rules', static function (Blueprint $table) {
$table->id();
$table->boolean('is_active')->default(true);
$table->foreignIdFor(Institute::class)->constrained()->cascadeOnDelete();
$table->foreignIdFor(Facility::class)->nullable()->constrained()->cascadeOnDelete();
$table->string('dicom_tag');
$table->string('search_pattern');
$table->unsignedTinyInteger('match_mode')->default(StringMatchMode::Exact->value);
$table->unsignedTinyInteger('sort_order')->default(0);
$table->string('description')->nullable();
$table->string('match_condition')->default(MatchCondition::Or->value);
$table->unsignedTinyInteger('priority')->default(0);
$table->timestamps();
$table->unique(['institute_id', 'dicom_tag']);
$table->index(['is_active', 'priority']);
});
}
public function down(): void
{
Schema::dropIfExists('dicom_mapping_rules');
Schema::dropIfExists('dicom_routing_rules');
}
};

View File

@ -0,0 +1,30 @@
<?php
use App\Domain\Rule\MatchMode;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('dicom_rule_conditions', function (Blueprint $table) {
$table->id();
$table->foreignId('dicom_routing_rule_id')->constrained()->cascadeOnDelete();
$table->string('dicom_tag');
$table->string('search_pattern');
$table->boolean('case_sensitive')->default(false);
$table->string('match_mode')->default(MatchMode::Exact->value);
$table->unsignedTinyInteger('priority')->default(0);
$table->timestamps();
$table->index(['dicom_mapping_rules_id', 'priority']);
});
}
public function down(): void
{
Schema::dropIfExists('dicom_rule_conditions');
}
};

View File

@ -2,7 +2,7 @@
namespace Database\Seeders;
use App\Domain\Rule\StringMatchMode;
use App\Domain\Rule\MatchMode;
use App\Models\DicomServer;
use App\Models\Facility;
use App\Models\Institute;
@ -45,15 +45,17 @@ public function run(): void
]
);
DB::table('institute_names')->insert([
DB::table('dicom_mapping_rules')->insert([
'dicom_tag' => 'InstitutionName',
'name' => 'CHEVRON CLINICAL LABORATORY , PANCHLAISH,CTG',
'institute_id' => $chev->id,
'match_mode' => StringMatchMode::Exact->value,
'search_pattern' => $chev->id,
'match_mode' => MatchMode::Exact->value,
]);
DB::table('institute_names')->insert([
'name' => 'CHEVRON CLINICAL',
DB::table('dicom_mapping_rules')->insert([
'dicom_tag' => 'InstitutionName',
'search_pattern' => 'CHEVRON CLINICAL',
'institute_id' => $chev->id,
'match_mode' => StringMatchMode::StartsWith->value,
'match_mode' => MatchMode::StartsWith->value,
]);
DicomServer::create(