giftcon_dev/app/Services/SmsService.php
2026-01-15 11:15:26 +09:00

157 lines
5.1 KiB
PHP

<?php
namespace App\Services;
use App\Models\Sms\ScTran;
use App\Models\Sms\MmsMsg;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
class SmsService
{
private string $companyName = 'lguplus';
/**
* @param array $payload
* - from_number (필수)
* - to_number (필수)
* - message (필수)
* - subject (mms일 때 없으면 자동 생성)
* - sms_type (sms|mms) (없으면 길이로 판단)
* - country (없으면 세션/기본 82)
*
* @param string|null $companyName
* @return bool
*/
public function send(array $payload, ?string $companyName = null): bool
{
try {
if ($companyName) {
$this->companyName = $companyName;
}
// 1) 필수값 체크 (CI의 Param_exception 대체)
if (empty($payload['from_number'])) return false;
if (empty($payload['to_number'])) return false;
if (empty($payload['message'])) return false;
// 2) country 결정 (CI sess['_mcountry_code'] 로직 대응)
$country = $payload['country'] ?? null;
if ($country === null) {
$sessCountry = Session::get('_mcountry_code'); // 기존 키 그대로 사용
if (!empty($sessCountry)) {
$country = ($sessCountry === '82' || $sessCountry === '') ? '82' : $sessCountry;
}
}
$payload['country'] = $country ?: '82';
// 3) 수신번호 체크/정리
if (!$this->phoneNumberCheck($payload)) {
return false;
}
// 4) 업체별 발송
return match ($this->companyName) {
'lguplus' => $this->lguplusSend($payload),
'sms2' => $this->sms2Send($payload),
default => false,
};
} catch (\Throwable $e) {
// 운영에서는 로깅 권장
// logger()->error('SmsService send failed', ['e' => $e]);
return false;
}
}
/**
* CI: phonenumber_check 로직 이식
* - country=82면 숫자만 남기고 01xxxxxxxxx 형식만 허용
*/
private function phoneNumberCheck(array &$payload): bool
{
if (($payload['country'] ?? '82') === '82') {
$num = preg_replace("/[^0-9]/", "", $payload['to_number'] ?? '');
if (preg_match("/^01[0-9]{8,9}$/", $num)) {
$payload['to_number'] = $num;
return true;
}
return false;
}
// 해외는 CI 원본처럼 그냥 통과(필요하면 국가별 검증 로직 추가)
return true;
}
/**
* CI: lguplus_send 이식
* - 메시지 길이(EUC-KR) 기준 90 이하 sms, 초과 mms
* - sms_type이 명시되면 그걸 우선
*/
private function lguplusSend(array $data): bool
{
$conn = DB::connection('sms_server');
// sms/mms 결정
$smsSendType = $this->resolveSendType($data);
return $conn->transaction(function () use ($smsSendType, $data) {
if ($smsSendType === 'sms') {
// CI의 SC_TRAN insert
$insert = [
'TR_SENDDATE' => now()->format('Y-m-d H:i:s'),
'TR_SENDSTAT' => '0',
'TR_MSGTYPE' => '0',
'TR_PHONE' => $data['to_number'],
'TR_CALLBACK' => $data['from_number'],
'TR_MSG' => $data['message'],
];
// Eloquent 사용
return (bool) ScTran::create($insert);
// 또는 Query Builder:
// return $conn->table('SC_TRAN')->insert($insert);
} else {
// CI의 MMS_MSG insert
$subject = $data['subject'] ?? mb_substr($data['message'], 0, 22, 'UTF-8');
$insert = [
'SUBJECT' => $subject,
'PHONE' => $data['to_number'],
'CALLBACK' => $data['from_number'],
'STATUS' => '0',
'REQDATE' => now()->format('Y-m-d H:i:s'),
'MSG' => $data['message'],
'FILE_CNT' => 0,
'FILE_PATH1' => '',
'TYPE' => '0',
];
return (bool) MmsMsg::create($insert);
// 또는 Query Builder:
// return $conn->table('MMS_MSG')->insert($insert);
}
});
}
private function resolveSendType(array $data): string
{
// CI 로직과 동일한 우선순위 유지
if (!empty($data['sms_type'])) {
if ($data['sms_type'] === 'sms') {
return (mb_strlen($data['message'], 'EUC-KR') <= 90) ? 'sms' : 'mms';
}
return 'mms';
}
return (mb_strlen($data['message'], 'EUC-KR') <= 90) ? 'sms' : 'mms';
}
private function sms2Send(array $data): bool
{
// TODO: 업체 연동 시 구현
return true;
}
}