174 lines
5.7 KiB
PHP
174 lines
5.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
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)
|
|
* - scheduled_at (옵션) : 'Y-m-d H:i' 또는 'Y-m-d H:i:s' (미래면 예약, 아니면 즉시)
|
|
*
|
|
* @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) 업체별 발송 (실제는 업체 DB insert)
|
|
return match ($this->companyName) {
|
|
'lguplus' => $this->lguplusSend($payload),
|
|
'sms2' => $this->sms2Send($payload),
|
|
default => false,
|
|
};
|
|
} catch (\Throwable $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;
|
|
}
|
|
|
|
/**
|
|
* 예약시간 처리(CI3 로직 그대로)
|
|
* - scheduled_at이 없으면 now()
|
|
* - 'Y-m-d H:i'면 ':00' 붙임
|
|
* - 미래면 그 시간, 과거/형식오류면 now()
|
|
*/
|
|
private function resolveProviderSendDate(?string $scheduledAt): string
|
|
{
|
|
$now = now()->format('Y-m-d H:i:s');
|
|
if (!$scheduledAt) return $now;
|
|
|
|
$scheduled = trim($scheduledAt);
|
|
|
|
// 폼은 Y-m-d H:i 로 오니 :00 붙임
|
|
if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/', $scheduled)) {
|
|
$scheduled .= ':00';
|
|
}
|
|
|
|
if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $scheduled)) {
|
|
if (strtotime($now) < strtotime($scheduled)) {
|
|
return $scheduled; // 미래면 예약
|
|
}
|
|
}
|
|
|
|
return $now; // 과거/형식오류면 즉시
|
|
}
|
|
|
|
/**
|
|
* CI: lguplus_send 이식
|
|
* - 메시지 길이(EUC-KR) 기준 90 이하 sms, 초과 mms
|
|
* - sms_type이 명시되면 그걸 우선
|
|
* - scheduled_at이 미래면 업체 예약 컬럼에 해당 시간으로 insert
|
|
* - SMS: SC_TRAN.TR_SENDDATE
|
|
* - MMS: MMS_MSG.REQDATE
|
|
*/
|
|
private function lguplusSend(array $data): bool
|
|
{
|
|
$conn = DB::connection('sms_server');
|
|
$smsSendType = $this->resolveSendType($data);
|
|
|
|
// 예약/즉시 결정
|
|
$sendDate = $this->resolveProviderSendDate($data['scheduled_at'] ?? null);
|
|
|
|
return (bool) $conn->transaction(function () use ($conn, $smsSendType, $data, $sendDate) {
|
|
|
|
if ($smsSendType === 'sms') {
|
|
return $conn->table('SC_TRAN')->insert([
|
|
'TR_SENDDATE' => $sendDate,
|
|
'TR_SENDSTAT' => '0',
|
|
'TR_MSGTYPE' => '0',
|
|
'TR_PHONE' => $data['to_number'],
|
|
'TR_CALLBACK' => $data['from_number'],
|
|
'TR_MSG' => $data['message'],
|
|
]);
|
|
}
|
|
|
|
$subject = $data['subject'] ?? mb_substr($data['message'], 0, 22, 'UTF-8');
|
|
|
|
return $conn->table('MMS_MSG')->insert([
|
|
'SUBJECT' => $subject,
|
|
'PHONE' => $data['to_number'],
|
|
'CALLBACK' => $data['from_number'],
|
|
'STATUS' => '0',
|
|
'REQDATE' => $sendDate,
|
|
'MSG' => $data['message'],
|
|
'FILE_CNT' => 0,
|
|
'FILE_PATH1' => '',
|
|
'TYPE' => '0',
|
|
]);
|
|
});
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|