Files
adsManager/app/Controllers/AdvertisementManager/Automation/AutomationController.php
T
2025-03-05 14:02:29 +09:00

1741 lines
84 KiB
PHP

<?php
namespace App\Controllers\AdvertisementManager\Automation;
use App\Controllers\BaseController;
use App\Libraries\slack_api\SlackChat;
use App\Models\Advertiser\AdvGoogleManagerModel;
use App\Models\Advertiser\AutomationModel;
use App\Services\AdvLoggerService;
use App\ThirdParty\facebook_api\ZenithFB;
use App\ThirdParty\googleads_api\ZenithGG;
use App\ThirdParty\moment_api\ZenithKM;
use CodeIgniter\API\ResponseTrait;
use CodeIgniter\CLI\CLI;
use CodeIgniter\I18n\Time;
use DateTime;
use Exception;
class AutomationController extends BaseController
{
use ResponseTrait;
protected $automation, $google;
public function __construct()
{
$this->automation = model(AutomationModel::class);
$this->google = model(AdvGoogleManagerModel::class);
}
public function index()
{
return view('automation/automation');
}
public function getList()
{
if($this->request->isAJAX() && strtolower($this->request->getMethod()) === 'get'){
$arg = $this->request->getGet();
$automations = $this->automation->getAutomationList($arg);
$result = $this->automationList($automations);
return $this->respond($result);
}else{
return $this->fail("잘못된 요청");
}
}
private function automationList($lists) {
// 현재 시간을 설정
$currentDate = new Time('now');
// 목록의 각 항목을 순회
foreach ($lists['data'] as &$data) {
$closestTime = null;
// 상태가 1이 아니면 예상 실행 시간을 빈 문자열로 설정하고 다음 항목으로 넘어감
if (!isset($data['aa_status']) || $data['aa_status'] != 1) {
$data['expected_time'] = '';
continue;
}
// 스케줄 값을 변환
$schedule = $this->convertJsonToTimes($data['aas_schedule_value']);
$currentDay = $currentDate->format('N'); // 현재 요일 (1: 월요일, 7: 일요일)
$currentTime = $currentDate->format('H:i'); // 현재 시간 (HH:MM)
// 스케줄 탐색을 위한 요일 배열 생성 및 정렬
$days = array_keys($schedule);
sort($days);
$found = false;
// 이번 주 스케줄 탐색
foreach ($days as $day) {
// 오늘 실행된 항목이 있으면 현재 요일 이후의 스케줄을 계속 탐색
if (!empty($data['aar_exec_timestamp_success'])) {
$execTimestampSuccess = Time::parse($data['aar_exec_timestamp_success']); // 실행 시간
$execDay = $execTimestampSuccess->format('N'); // 실행 시간의 요일
if ($data['aas_exec_once'] == 1 && $execDay == $day && $execDay == $currentDay) {
continue;
}
}
// 현재 요일 이후의 스케줄을 탐색하여 가장 가까운 시간을 찾음
foreach ($schedule[$day] as $time) {
$scheduledTime = Time::parse($time);
$scheduledDateTime = $currentDate->setISODate($currentDate->year, $currentDate->weekOfYear, $day)->setTime($scheduledTime->hour, $scheduledTime->minute);
// 현재 시간 이후의 스케줄 시간 중 가장 가까운 시간을 찾음
if ($scheduledDateTime->isAfter($currentDate)) {
if (is_null($closestTime) || $scheduledDateTime->isBefore($closestTime)) {
$closestTime = $scheduledDateTime;
$found = true;
}
} else if ($scheduledDateTime->difference($currentDate)->getMinutes() <= 30) {
// 현재 시간과 30분 이내의 차이가 나는 스케줄 시간 중 가장 가까운 시간을 찾음
$interval = 5; // 5분 단위
$nextPossibleTime = $currentDate->addMinutes($interval - ($currentDate->getMinute() % $interval));
if ($nextPossibleTime->isAfter($currentDate) && (is_null($closestTime) || $nextPossibleTime->isBefore($closestTime))) {
$closestTime = $nextPossibleTime;
$found = true;
}
}
}
// 가장 가까운 시간을 찾았으면 루프를 종료
if ($found) break;
}
// 이번 주에 실행할 스케줄이 없으면 다음 주 스케줄 탐색
if (!$found) {
foreach ($days as $day) {
foreach ($schedule[$day] as $time) {
$scheduledTime = Time::parse($time);
$scheduledDateTime = $currentDate->addDays(7 - $currentDay + $day)->setTime($scheduledTime->hour, $scheduledTime->minute);
if (is_null($closestTime) || $scheduledDateTime->isBefore($closestTime)) {
$closestTime = $scheduledDateTime;
}
}
}
}
// 가장 가까운 시간을 예상 실행 시간으로 설정
if (!is_null($closestTime)) {
$data['expected_time'] = $closestTime->toDateTimeString();
}
}
// 예상 실행 시간이 포함된 목록을 반환
return $lists;
}
public function getAutomation()
{
if($this->request->isAJAX() && strtolower($this->request->getMethod()) === 'get'){
$arg = $this->request->getGet();
$result = $this->automation->getAutomation($arg);
$result['aas_schedule_value'] = json_decode($result['aas_schedule_value']);
if(!empty($result['targets'])){
foreach ($result['targets'] as &$target) {
switch ($target['media']) {
case 'company':
$target['media'] = '광고주';
break;
case 'facebook':
$target['media'] = '페이스북';
break;
case 'google':
$target['media'] = '구글';
break;
case 'kakao':
$target['media'] = '카카오';
break;
default:
break;
}
switch ($target['type']) {
case 'advertiser':
$target['type'] = '광고주';
break;
case 'account':
$target['type'] = '매체광고주';
break;
case 'campaign':
$target['type'] = '캠페인';
break;
case 'adgroup':
$target['type'] = '광고그룹';
break;
case 'ad':
$target['type'] = '광고';
break;
default:
break;
}
if($target['status'] == 1 || $target['status'] == 'ON' || $target['status'] == 'ENABLED' || $target['status'] == 'ACTIVE'){
$target['status'] = '활성';
}else{
$target['status'] = '비활성';
}
}
}
foreach ($result['executions'] as &$execution) {
switch ($execution['media']) {
case 'facebook':
$execution['media'] = '페이스북';
break;
case 'google':
$execution['media'] = '구글';
break;
case 'kakao':
$execution['media'] = '카카오';
break;
default:
break;
}
switch ($execution['type']) {
case 'campaign':
$execution['type'] = '캠페인';
break;
case 'adgroup':
$execution['type'] = '광고그룹';
break;
case 'ad':
$execution['type'] = '광고';
break;
default:
break;
}
if($execution['status'] == 1 || $execution['status'] == 'ON' || $execution['status'] == 'ENABLED' || $execution['status'] == 'ACTIVE'){
$execution['status'] = '활성';
}else{
$execution['status'] = '비활성';
}
}
return $this->respond($result);
}else{
return $this->fail("잘못된 요청");
}
}
public function setStatus()
{
if($this->request->isAJAX() && strtolower($this->request->getMethod()) === 'put'){
$arg = $this->request->getRawInput();
$data = [
'seq' => $arg['seq'],
'status' => $arg['status'],
];
$result = $this->automation->setAutomationStatus($data);
return $this->respond($result);
}else{
return $this->fail("잘못된 요청");
}
}
public function getAdv()
{
if($this->request->isAJAX() && strtolower($this->request->getMethod()) === 'get'){
$arg = $this->request->getGet();
switch ($arg['tab']) {
case 'advertiser':
if(!empty($arg['adv'])){
$result = $this->automation->getSearchCompaniesWithAdv($arg);
}else{
$result = $this->automation->getSearchCompanies($arg);
}
break;
case 'account':
if(!empty($arg['adv'])){
$result = $this->automation->getSearchAccountsWithAdv($arg);
}else{
$result = $this->automation->getSearchAccounts($arg);
}
break;
case 'campaign':
if(!empty($arg['adv'])){
$result = $this->automation->getSearchCampaignsWithAdv($arg);
}else{
$result = $this->automation->getSearchCampaigns($arg);
}
break;
case 'adgroup':
if(!empty($arg['adv'])){
$result = $this->automation->getSearchAdsetsWithAdv($arg);
}else{
$result = $this->automation->getSearchAdsets($arg);
}
break;
case 'ad':
if(!empty($arg['adv'])){
$result = $this->automation->getSearchAdsWithAdv($arg);
}else{
$result = $this->automation->getSearchAds($arg);
}
break;
default:
return $this->fail("잘못된 요청");
break;
}
foreach ($result['data'] as &$row) {
if(isset($row['status']) && $row['status'] == 1 || $row['status'] == 'ON' || $row['status'] == 'ENABLED' || $row['status'] == 'ACTIVE'){
$row['status'] = '활성';
}else{
$row['status'] = '비활성';
}
}
$result = [
'data' => $result['data'],
'recordsTotal' => $result['allCount'],
'recordsFiltered' => $result['allCount'],
'draw' => intval($arg['draw']),
];
return $this->respond($result);
}else{
return $this->fail("잘못된 요청");
}
}
public function getLogs()
{
if($this->request->isAJAX() && strtolower($this->request->getMethod()) === 'get'){
$arg = $this->request->getGet();
$result = $this->automation->getLogs($arg);
foreach ($result['data'] as &$data) {
switch ($data['result']) {
case 'success':
$data['result'] = '실행됨';
break;
case 'failed':
$data['result'] = '실패';
break;
case 'not_execution':
$data['result'] = '실행되지 않음';
break;
default:
$data['result'] = '';
}
$descFields = ['schedule_desc', 'target_desc', 'conditions_desc', 'executions_desc'];
foreach($descFields as $field) {
if(!empty($data[$field])) {
$decoded = json_decode($data[$field], true);
if(!empty($decoded)){
if($field == 'executions_desc'){
$errorMsgs = [];
if(is_array($decoded)){
foreach($decoded as $item) {
if(is_array($item)){
if($item['result'] == false) {
$errorMsgs[] = '실패 - '.'['.$item['data']['media'].']['.$item['data']['type'].']['.$item['data']['id'].'] '.$item['data']['exec_type'].' => '.$item['data']['exec_value']." ".$item['msg'];
}
}else{
$errorMsgs = '실패 - '.$decoded['msg'];
continue;
}
}
if(empty($errorMsgs)){
$data[$field] = '통과';
}else{
$data[$field] = $errorMsgs;
}
}
}else{
if($decoded !== null) {
if(isset($decoded['result']) && $decoded['result'] === true) {
$data[$field] = '통과';
} else{
$data[$field] = '실패 - '.(isset($decoded['msg']) ? $decoded['msg'] : '');
}
}
}
}
}
}
}
$result = [
'data' => $result['data'],
];
return $this->respond($result);
}else{
return $this->fail("잘못된 요청");
}
}
public function getLogByAdv()
{
if($this->request->isAJAX() && strtolower($this->request->getMethod()) === 'get'){
$arg = $this->request->getGet();
$sliceId = explode("_", $arg['id']);
$id = $sliceId[1];
$automations = $this->automation->getAutomationByAdv($id);
$result = $this->automation->getLogsByAdv($arg, $id);
foreach ($result['data'] as &$data) {
switch ($data['result']) {
case 'success':
$data['result'] = '실행됨';
break;
case 'failed':
$data['result'] = '실패';
break;
case 'not_execution':
$data['result'] = '실행되지 않음';
break;
default:
$data['result'] = '';
}
$descFields = ['schedule_desc', 'target_desc', 'conditions_desc', 'executions_desc'];
foreach($descFields as $field) {
if(!empty($data[$field])) {
$decoded = json_decode($data[$field], true);
if(!empty($decoded)){
if($field == 'executions_desc'){
$errorMsgs = [];
if(is_array($decoded)){
foreach($decoded as $item) {
if(is_array($item)){
if($item['result'] == false) {
$errorMsgs[] = '실패 - '.'['.$item['data']['media'].']['.$item['data']['type'].']['.$item['data']['id'].'] '.$item['data']['exec_type'].' => '.$item['data']['exec_value']." ".$item['msg'];
}
}else{
$errorMsgs = '실패 - '.$decoded['msg'];
continue;
}
}
if(empty($errorMsgs)){
$data[$field] = '통과';
}else{
$data[$field] = $errorMsgs;
}
}
}else{
if($decoded !== null) {
if(isset($decoded['result']) && $decoded['result'] === true) {
$data[$field] = '통과';
} else{
$data[$field] = '실패 - '.(isset($decoded['msg']) ? $decoded['msg'] : '');
}
}
}
}
}
}
}
$result = [
'data' => $result['data'],
'automation' => $automations,
'recordsTotal' => $result['allCount'],
'recordsFiltered' => $result['allCount'],
'draw' => intval($arg['draw']),
];
return $this->respond($result);
}else{
return $this->fail("잘못된 요청");
}
}
public function createAutomation()
{
if($this->request->isAJAX() && strtolower($this->request->getMethod()) === 'post'){
$data = $this->request->getRawInput();
$validationResult = $this->validationData($data);
if($validationResult['result'] != true){
return $this->failValidationErrors($validationResult);
}
$mediaMapping = ['광고주' => 'company', '페이스북' => 'facebook', '구글' => 'google', '카카오' => 'kakao'];
$typeMapping = ['광고주' => 'advertiser', '매체광고주' => 'account', '캠페인' => 'campaign', '광고그룹' => 'adgroup', '광고' => 'ad'];
$execTypeMapping = ['상태' => 'status', '예산' => 'budget'];
$execBudgetTypeMapping = ['원' => 'won', '%' => 'percent'];
$data['schedule']['schedule_value'] = json_encode($data['schedule']['schedule_value']);
$data['schedule']['exec_once'] = !empty($data['schedule']['exec_once']) ? 1 : 0;
if(!empty($data['target'])) {
foreach ($data['target'] as &$target) {
$target['media'] = $mediaMapping[$target['media']] ?? $target['media'];
$target['type'] = $typeMapping[$target['type']] ?? $target['type'];
}
}
if(!empty($data['execution'])) {
foreach ($data['execution'] as &$execution) {
$execution['media'] = $mediaMapping[$execution['media']] ?? $execution['media'];
$execution['type'] = $typeMapping[$execution['type']] ?? $execution['type'];
$execution['exec_type'] = $execTypeMapping[$execution['exec_type']] ?? $execution['exec_type'];
$execution['exec_budget_type'] = $execBudgetTypeMapping[$execution['exec_budget_type']] ?? $execution['exec_budget_type'];
}
}
if(!empty($data['target_create_type']) && $data['target_create_type'] == 'target_seperate'){
$seperateDatas = [];
foreach ($data['target'] as $key => $targetData) {
$newItem = [
'schedule' => $data['schedule'],
'target' => [$targetData],
'condition' => $data['condition'],
'detail' => $data['detail']
];
$newItem['detail']['subject'] = $newItem['detail']['subject']." 개별 적용 - ".$key+1;
foreach ($data['execution'] as $executionData) {
if($targetData['id'] == $executionData['id'] && $targetData['media'] == $executionData['media']){
$newItem['execution'] = [$executionData];
}
continue;
}
$seperateDatas[] = $newItem;
}
$db = \Config\Database::connect();
$db->transStart();
foreach ($seperateDatas as $seperateData) {
$result = $this->automation->createAutomation($seperateData);
if (!$result) { // If creation fails, rollback and exit
$db->transRollback();
return false;
}
}
$result = $db->transComplete();
return $this->respond($result);
}
$result = $this->automation->createAutomation($data);
return $this->respond($result);
}else{
return $this->fail("잘못된 요청");
}
}
public function copyAutomation()
{
if($this->request->isAJAX() && strtolower($this->request->getMethod()) === 'post'){
$data = $this->request->getRawInput();
$result = $this->automation->copyAutomation($data);
return $this->respond($result);
}else{
return $this->fail("잘못된 요청");
}
}
public function updateAutomation()
{
if($this->request->isAJAX() && strtolower($this->request->getMethod()) === 'put'){
$data = $this->request->getRawInput();
if(empty($data['seq'])){
return $this->fail("잘못된 요청");
}
$validationResult = $this->validationData($data);
if($validationResult['result'] != true){
return $this->failValidationErrors($validationResult);
}
$mediaMapping = ['광고주' => 'company', '페이스북' => 'facebook', '구글' => 'google', '카카오' => 'kakao'];
$typeMapping = ['광고주' => 'advertiser', '매체광고주' => 'account', '캠페인' => 'campaign', '광고그룹' => 'adgroup', '광고' => 'ad'];
$execTypeMapping = ['상태' => 'status', '예산' => 'budget'];
$execBudgetTypeMapping = ['원' => 'won', '%' => 'percent'];
$data['schedule']['schedule_value'] = json_encode($data['schedule']['schedule_value']);
$data['schedule']['exec_once'] = $data['schedule']['exec_once'] == "true" ? 1 : 0;
if(!empty($data['target'])) {
foreach ($data['target'] as &$target) {
$target['media'] = $mediaMapping[$target['media']] ?? $target['media'];
$target['type'] = $typeMapping[$target['type']] ?? $target['type'];
}
}
if(!empty($data['execution'])) {
foreach ($data['execution'] as &$execution) {
$execution['media'] = $mediaMapping[$execution['media']] ?? $execution['media'];
$execution['type'] = $typeMapping[$execution['type']] ?? $execution['type'];
$execution['exec_type'] = $execTypeMapping[$execution['exec_type']] ?? $execution['exec_type'];
$execution['exec_budget_type'] = $execBudgetTypeMapping[$execution['exec_budget_type']] ?? $execution['exec_budget_type'];
}
}
$result = $this->automation->updateAutomation($data);
return $this->respond($result);
}else{
return $this->fail("잘못된 요청");
}
}
public function deleteAutomation()
{
if($this->request->isAJAX() && strtolower($this->request->getMethod()) === 'delete'){
$data = $this->request->getRawInput();
$result = $this->automation->deleteAutomation($data);
return $this->respond($result);
}else{
return $this->fail("잘못된 요청");
}
}
private function validationData($data)
{
$validation = \Config\Services::validation();
$validationRules = [
'schedule.schedule_value' => 'required',
];
$validationMessages = [
'schedule.schedule_value' => [
'required' => '일정을 지정해주세요.',
],
];
$validation->setRules($validationRules, $validationMessages);
if (!$validation->run($data)) {
$result = [
'result' => false,
'msg' => $validation->getErrors(),
];
return $result;
}
$validation->reset();
if(!empty($data['target'])){
foreach ($data['condition'] as $condition) {
$validationRules = [
'type' => 'required',
'type_value' => 'required',
'compare' => 'required',
'operation' => 'required',
];
$validationMessages = [
'type' => ['required' => '조건 항목은 필수 항목입니다.'],
'type_value' => ['required' => '조건 값은 필수 항목입니다.'],
'compare' => ['required' => '일치여부는 필수 항목입니다.'],
'operation' => ['required' => '연산조건은 필수 항목입니다.'],
];
$validation->setRules($validationRules, $validationMessages);
if (!$validation->run($condition)) {
$result = [
'result' => false,
'msg' => $validation->getErrors(),
];
return $result;
}
}
$validation->reset();
}
if(empty($data['execution'])){
$validationRules['execution'] = 'required';
$validationMessages['execution'] = ['required' => '실행항목을 추가해주세요.'];
}else{
foreach ($data['execution'] as $execution) {
$validationRules = [
'order' => 'required',
'exec_type' => 'required',
'exec_value' => 'required',
];
$validationMessages = [
'order' => ['required' => '실행순서는 필수 항목입니다.'],
'exec_type' => ['required' => '실행항목은 필수 항목입니다.'],
'exec_value' => ['required' => '세부항목은 필수 항목입니다.'],
];
if($execution['exec_type'] == '예산'){
$validationRules['exec_budget_type'] = 'required';
$validationMessages['exec_budget_type'] = ['required' => '단위는 필수 항목입니다.'];
}
$validation->setRules($validationRules, $validationMessages);
if (!$validation->run($execution)) {
$result = [
'result' => false,
'msg' => $validation->getErrors(),
];
return $result;
}
}
}
$validation->reset();
$validationRules = ['detail.subject' => 'required'];
$validationMessages = ['detail.subject' => ['required' => '제목은 필수 항목입니다.']];
$validation->setRules($validationRules, $validationMessages);
if (!$validation->run($data)) {
$result = [
'result' => false,
'msg' => $validation->getErrors(),
];
return $result;
}
return ['result' => true];
}
public function automation()
{
CLI::write("자동화를 실행합니다.", "light_red");
$automations = $this->automation->getAutomations();
$seqs = [];
$logs = [];
$step = 1;
$total = count($automations);
foreach ($automations as $automation) {
$result = [];
//if($automation['aa_seq'] != '202'){continue;}
if(!empty($automation)){
$schedulePassData = $this->checkAutomationSchedule($automation);
$result['schedule'] = $schedulePassData;
if(!empty($schedulePassData['result'])){
$targets = $this->automation->getAutomationTargets($automation['aa_seq']);
if(!empty($targets)){
$checkTargets = [];
foreach ($targets as $target) {
$targetData = $this->checkAutomationTarget($target);
if($targetData['result'] == false){
continue;
}
$checkTargets[] = $targetData['target'];
}
$targetDatas = $this->setData($checkTargets);
if(empty($targetDatas)){
$resultRow = $this->recordResult([
'seq' => $automation['aa_seq'],
'status'=> 'not_execution'
]);
$resultTarget = [
'result' => false,
'msg' => '비교 대상 데이터가 존재하지 않습니다.',
'seq' => $automation['aa_seq'],
];
$result['target'] = $resultTarget;
if(!empty($resultRow)){
$this->recordLog($result, $resultRow);
}
continue;
}else{
$resultTarget = [
'result' => true,
'msg' => '대상이 일치합니다.',
'seq' => $automation['aa_seq'],
'target' => $targetDatas,
];
$result['target'] = $resultTarget;
}
if(!empty($targetDatas)){
$conditionPassData = $this->checkAutomationCondition($targetDatas, $automation['aa_seq']);
$result['conditions'] = $conditionPassData;
if($conditionPassData['result'] == false){
$resultRow = $this->recordResult($conditionPassData);
if(!empty($resultRow)){
$this->recordLog($result, $resultRow);
}
continue;
}
$seqs[] = $conditionPassData['seq'];
$logs[] = $result;
}
}else{
$seqs[] = $schedulePassData['seq'];
$logs[] = $result;
}
}
}
}
if(!empty($seqs)){
$executionData = [];
foreach ($seqs as $seq) {
CLI::showProgress($step++, $total);
$executionData[] = $this->automationExecution($seq);
}
foreach ($executionData as $exec) {
$resultRow = $this->recordResult($exec['result']);
if(!empty($resultRow)){
foreach ($logs as &$log) {
if($log['schedule']['seq'] === $exec['result']['seq']){
$log['executions'] = $exec['log'];
$this->recordLog($log, $resultRow);
}
}
}
}
foreach ($executionData as $exec) {
if($exec['result'] == true){
$automation = $this->automation->getAutomationBySeq($exec['result']['seq']);
if(!empty($automation['aa_slack_webhook']) && !empty($automation['aa_slack_msg'])){
$slackChat = new SlackChat;
$slackChat->sendWebHookMessage($automation['aa_slack_webhook'], $automation['aa_slack_msg']);
}
}
}
}
CLI::write("자동화 실행 완료", "light_red");
}
public function checkAutomationSchedule($automation)
{
$resultArray = [
'result' => false,
'status' => 'not_execution',
'msg' => '설정 시간 일치하지 않음',
'seq' => $automation['aa_seq'],
];
$currentDate = new Time('now');
$currentDay = $currentDate->format('N');
$currentTime = $currentDate->toTimeString();
$schedule = $this->convertJsonToTimes($automation['aas_schedule_value']);
if (array_key_exists($currentDay, $schedule)) {
if (!empty($automation['aas_exec_once']) && !empty($automation['aar_exec_timestamp_success'])) {
$execTimestampSuccess = Time::parse($automation['aar_exec_timestamp_success']);
if ($execTimestampSuccess->toDateString() === $currentDate->toDateString()) {
return $resultArray;
}
}
foreach ($schedule[$currentDay] as $time) {
$startTime = Time::parse($time);
$endTime = $startTime->addMinutes(30);
$now = Time::parse($currentTime);
if ($now->isAfter($startTime) && $now->isBefore($endTime)) {
$resultArray = [
'result' => true,
'status' => 'success',
'msg' => '설정 시간 일치',
'seq' => $automation['aa_seq'],
];
return $resultArray;
}
}
}
return $resultArray;
}
public function checkAutomationTarget($target)
{
$types = ['advertiser', 'account', 'campaign', 'adgroup', 'ad'];
$mediaTypes = ['company', 'facebook', 'google', 'kakao'];
//값 별로 메소드 매칭
if (in_array($target['aat_type'], $types) && in_array($target['aat_media'], $mediaTypes)) {
$methodName = "getTarget" . ucfirst($target['aat_media']);
if (method_exists($this->automation, $methodName)) {
$data = $this->automation->$methodName($target);
if(empty($data)){
return ['result' => false];
}
$data = $this->sumData($data);
return [
'result' => true,
'seq' => $target['aat_idx'],
'target' => $data,
];
}
}
}
public function checkAutomationCondition($targetData, $seq)
{
$types = ['status', 'budget', 'dbcost', 'unique_total', 'spend', 'margin', 'margin_rate', 'sales', 'conversion'];
$conditions = $this->automation->getAutomationConditionBySeq($seq);
if(empty($conditions)){
return [
"result" => false,
'status' => 'failed',
"msg" => '조건이 존재하지 않음',
"seq" => $seq,
];
}
$isTargetMatched = false;
$allConditionsMatched = true;
$operation = $conditions[0]['operation'];
foreach ($conditions as $condition) {
$conditionMatched = false;
$message = "일치하는 조건이 없습니다.";
if ($condition['type'] === 'status') {//status 비교
if ($targetData['status'] == $condition['type_value']) {
$conditionMatched = true;
$message = 'status 일치';
}else{
$message = 'status가 일치하지 않습니다.';
}
}else{//그 외 필드 비교
foreach ($types as $type) {
if ($condition['type'] === $type) {
switch ($condition['compare']) {
case 'less':
$conditionMatched = $targetData[$type] < $condition['type_value'];
$message = $conditionMatched ? $type." ".$condition['compare'].' 조건 일치' : $type.'값이 조건값보다 큽니다.'."(".$condition['compare'].")";
break;
case 'greater':
$conditionMatched = $targetData[$type] > $condition['type_value'];
$message = $conditionMatched ? $type." ".$condition['compare'].' 조건 일치' : $type.'값이 조건값보다 작습니다.'."(".$condition['compare'].")";
break;
case 'less_equal':
$conditionMatched = $targetData[$type] <= $condition['type_value'];
$message = $conditionMatched ? $type." ".$condition['compare'].' 조건 일치' : $type.'값이 조건값보다 크거나 같지 않습니다.'."(".$condition['compare'].")";
break;
case 'greater_equal':
$conditionMatched = $targetData[$type] >= $condition['type_value'];
$message = $conditionMatched ? $type." ".$condition['compare'].' 조건 일치' : $type.'값이 조건값보다 작거나 같지 않습니다.'."(".$condition['compare'].")";
break;
case 'equal':
$conditionMatched = $targetData[$type] == $condition['type_value'];
$message = $conditionMatched ? $type." ".$condition['compare'].' 조건 일치' : $type.'값이 조건값과 일치하지 않습니다.'."(".$condition['compare'].")";
break;
case 'not_equal':
$conditionMatched = $targetData[$type] != $condition['type_value'];
$message = $conditionMatched ? $type." ".$condition['compare'].' 조건 일치' : $type.'값이 조건값과 같습니다.'."(".$condition['compare'].")";
break;
default:
$conditionMatched = false;
break;
}
}
}
}
if($operation == 'or'){
if($conditionMatched){
$isTargetMatched = true;
break;
}
}
if($operation == 'and'){
if (!$conditionMatched) {
$allConditionsMatched = false;
break;
}
}
}
if(($operation == 'or' && $isTargetMatched) || ($operation == 'and' && $allConditionsMatched)){
return [
"result" => true,
'status' => 'success',
"msg" => $message,
"seq" => $seq,
];
}else{
return [
"result" => false,
'status' => 'not_execution',
"msg" => $message,
"seq" => $seq,
];
}
}
public function automationExecution($seq)
{
$executions = $this->automation->getExecution($seq);
if(empty($executions)){
return [
"result" => false,
'status' => 'failed',
"msg" => '실행항목이 존재하지 않음',
"seq" => $seq,
];
}
$originalSettings = [];
$result = [
'result' => [],
'log' => [],
];
try {
foreach ($executions as $execution) {
$zenith = null;
switch ($execution['media']) {
case 'facebook':
$zenith = new ZenithFB();
break;
case 'google':
$zenith = new ZenithGG();
break;
case 'kakao':
$zenith = new ZenithKM();
break;
default:
break;
}
if($zenith){
switch ($execution['type']) {
case 'campaign':
$customerId = null;
if ($execution['media'] === 'google') {
$customerId = $this->google->getCustomerById($execution['id'], 'campaign');
}
switch ($execution['exec_type']) {
case 'status':
if ($execution['media'] === 'facebook') {
if($execution['exec_value'] === "ON"){
$status = 'ACTIVE';
}else{
$status = 'PAUSED';
}
$originalData = $zenith->getCampaignStatusBudget($execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'status' => $originalData['status'],
];
$return = $zenith->setCampaignStatus($execution['id'], $status);
}
} else if ($execution['media'] === 'google') {
if($execution['exec_value'] === "ON"){
$status = ['status' => 'ENABLED'];
}else{
$status = ['status' => 'PAUSED'];
}
$originalData = $zenith->getCampaignStatusBudget($customerId['customerId'], $execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'status' => $originalData['status'],
];
$return = $zenith->updateCampaign($customerId['customerId'], $execution['id'], $status);
}else{
$return = false;
}
} else if ($execution['media'] === 'kakao') {
$originalData = $zenith->getCampaignStatusBudget($execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'status' => $originalData['status'],
];
$return = $zenith->setCampaignOnOff($execution['id'], $execution['exec_value']);
if(isset($return['http_code'])){
if($return['http_code'] == 200){
$return = true;
}else{
throw new Exception("카카오 캠페인 상태 수정 오류 발생.");
}
}else{
throw new Exception("카카오 캠페인 상태 수정 오류 발생.");
}
}else{
$return = false;
}
}
break;
case 'budget':
if ($execution['media'] === 'facebook') {
$originalData = $zenith->getCampaignStatusBudget($execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'budget' => $originalData['budget'] ?? 0,
];
if ($execution['exec_budget_type'] == 'percent') {
$adjustedBudget = ($originalData['budget']) * (1 + ($execution['exec_value'] / 100));
$adjustedBudget = round($adjustedBudget);
} else {
$adjustedBudget = $execution['exec_value'];
}
$data = [
'id' => $execution['id'],
'budget' => $adjustedBudget
];
$return = $zenith->updateCampaignBudget($data);
}else{
$return = false;
}
} else if ($execution['media'] === 'google') {
$originalData = $zenith->getCampaignStatusBudget($customerId['customerId'], $execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'budget' => $originalData['budget'] ?? 0,
];
if ($execution['exec_budget_type'] == 'percent') {
$adjustedBudget = ($originalData['budget']) * (1 + ($execution['exec_value'] / 100));
$adjustedBudget = round($adjustedBudget);
} else {
$adjustedBudget = $execution['exec_value'];
}
$return = $zenith->updateCampaignBudget($customerId['customerId'], $execution['id'], ['budget' => $adjustedBudget]);
}else{
$return = false;
}
} else if ($execution['media'] === 'kakao') {
$originalData = $zenith->getCampaignStatusBudget($execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'budget' => $originalData['budget'] ?? 0,
];
if ($execution['exec_budget_type'] == 'percent') {
$adjustedBudget = ($originalData['budget']) * (1 + ($execution['exec_value'] / 100));
$adjustedBudget = round($adjustedBudget);
} else {
$adjustedBudget = $execution['exec_value'];
}
$data = [
'type' => 'campaign',
'id' => $execution['id'],
'budget' => $adjustedBudget
];
$return = $zenith->setDailyBudgetAmount($data);
if(isset($return['code']) && isset($return['msg'])){
throw new Exception($return['msg']);
}else{
$return = true;
}
}else{
$return = false;
}
}
break;
default:
break;
}
break;
case 'adgroup':
$customerId = null;
if ($execution['media'] === 'google') {
$customerId = $this->google->getCustomerById($execution['id'], 'adgroup');
}
switch ($execution['exec_type']) {
case 'status':
if ($execution['media'] === 'facebook') {
if($execution['exec_value'] === "ON"){
$status = 'ACTIVE';
}else{
$status = 'PAUSED';
}
$originalData = $zenith->getAdsetStatusBudget($execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'status' => $originalData['status'],
];
$return = $zenith->setAdsetStatus($execution['id'], $status);
}else{
$return = false;
}
} else if ($execution['media'] === 'google') {
if($execution['exec_value'] === "ON"){
$status = ['status' => 'ENABLED'];
}else{
$status = ['status' => 'PAUSED'];
}
$originalData = $zenith->getAdgroupStatus($customerId['customerId'], $execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'status' => $originalData['status'],
];
$return = $zenith->updateAdGroup($customerId['customerId'], $execution['id'], $status);
}else{
$return = false;
}
} else if ($execution['media'] === 'kakao') {
$originalData = $zenith->getAdgroupStatusBudget($execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'status' => $originalData['status'],
];
$return = $zenith->setAdGroupOnOff($execution['id'], $execution['exec_value']);
if(isset($return['http_code'])){
if($return['http_code'] == 200){
$return = true;
}else{
throw new Exception("카카오 광고그룹 상태 수정 오류 발생.");
}
}else{
throw new Exception("카카오 광고그룹 상태 수정 오류 발생.");
}
}else{
$return = false;
}
}
break;
case 'budget':
if ($execution['media'] === 'facebook') {
$originalData = $zenith->getAdsetStatusBudget($execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'budget' => $originalData['budget'] ?? 0,
];
if ($execution['exec_budget_type'] == 'percent') {
$adjustedBudget = ($originalData['budget']) * (1 + ($execution['exec_value'] / 100));
$adjustedBudget = round($adjustedBudget);
} else {
$adjustedBudget = $execution['exec_value'];
}
$data = [
'id' => $execution['id'],
'budget' => $adjustedBudget
];
$return = $zenith->updateAdSetBudget($data);
}else{
$return = false;
}
} else if ($execution['media'] === 'kakao') {
$originalData = $zenith->getAdgroupStatusBudget($execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'budget' => $originalData['budget'] ?? 0,
];
if ($execution['exec_budget_type'] == 'percent') {
$adjustedBudget = ($originalData['budget']) * (1 + ($execution['exec_value'] / 100));
$adjustedBudget = round($adjustedBudget);
} else {
$adjustedBudget = $execution['exec_value'];
}
$data = [
'type' => 'adgroup',
'id' => $execution['id'],
'budget' => $adjustedBudget
];
$return = $zenith->setDailyBudgetAmount($data);
if(isset($return['code']) && isset($return['msg'])){
throw new Exception($return['msg']);
}else{
$return = true;
}
}else{
$return = false;
}
}
break;
default:
break;
}
break;
case 'ad':
$customerId = null;
if ($execution['media'] === 'google') {
$customerId = $this->google->getCustomerById($execution['id'], 'ad');
}
switch ($execution['exec_type']) {
case 'status':
if ($execution['media'] === 'facebook') {
if($execution['exec_value'] === "ON"){
$status = 'ACTIVE';
}else{
$status = 'PAUSED';
}
$originalData = $zenith->getAdStatusBudget($execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'status' => $originalData['status'],
];
$return = $zenith->setAdStatus($execution['id'], $status);
}else{
$return = false;
}
} else if ($execution['media'] === 'google') {
if($execution['exec_value'] === "ON"){
$status = ['status' => 'ENABLED'];
}else{
$status = ['status' => 'PAUSED'];
}
$originalData = $zenith->getAdStatus($customerId['customerId'], $execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'status' => $originalData['status'],
];
$return = $zenith->updateAdGroupAd($customerId['customerId'], null, $execution['id'], $status);
}else{
$return = false;
}
} else if ($execution['media'] === 'kakao') {
$originalData = $zenith->getAdStatusBudget($execution['id']);
if(!empty($originalData)){
$originalSettings[] = [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'status' => $originalData['status'],
];
$return = $zenith->setCreativeOnOff($execution['id'], $execution['exec_value']);
if(isset($return['http_code'])){
if($return['http_code'] == 200){
$return = true;
}else{
throw new Exception("카카오 광고그룹 상태 수정 오류 발생.");
}
}else{
throw new Exception("카카오 광고그룹 상태 수정 오류 발생.");
}
}else{
$return = false;
}
}
break;
}
break;
default:
break;
}
if(!empty($return)){
$logData = [
'media' => $execution['media'],
'id' => $execution['id'],
'type' => $execution['type'],
'change_type' => $execution['exec_type'] == 'status' ? 'status' : 'budget',
'old_value' => '',
'change_value' => $execution['exec_value'],
'nickname' => '자동화',
];
$logger = new AdvLoggerService();
$logger->insertLog($logData);
$result['log'][] = [
"result" => true,
'status' => 'success',
"msg" => '실행 완료',
"seq" => $seq,
"data" => [
'media' => $execution['media'],
'type' => $execution['type'],
'id' => $execution['id'],
'exec_type' => $execution['exec_type'],
'exec_value' => $execution['exec_value'],
]
];
}else{
throw new Exception("Api 오류 발생.");
}
}
}
$result['result'] = [
"result" => true,
'status' => 'success',
"seq" => $seq,
];
return $result;
} catch (Exception $e) {
foreach ($originalSettings as $original) {
switch ($original['media']) {
case 'facebook':
$zenith = new ZenithFB();
break;
case 'google':
$zenith = new ZenithGG();
break;
case 'kakao':
$zenith = new ZenithKM();
break;
default:
break;
}
switch ($original['type']) {
case 'campaign':
$customerId = null;
if ($original['media'] === 'google') {
$customerId = $this->google->getCustomerById($original['id'], 'campaign');
}
if(isset($original['status'])){
if ($original['media'] === 'facebook') {
$zenith->setCampaignStatus($original['id'], $original['status']);
} else if ($original['media'] === 'google') {
$zenith->updateCampaign($customerId['customerId'], $original['id'], $original['status']);
} else if ($original['media'] === 'kakao') {
$zenith->setCampaignOnOff($original['id'], $original['status']);
}
}
if(isset($original['budget'])){
if ($original['media'] === 'facebook') {
$data = [
'id' => $original['id'],
'budget' => $original['budget']
];
$zenith->updateCampaignBudget($data);
} else if ($original['media'] === 'google') {
$zenith->updateCampaignBudget($customerId['customerId'], $original['id'], ['budget' => $original['budget']]);
} else if ($original['media'] === 'kakao') {
$data = [
'type' => 'campaign',
'id' => $original['id'],
'budget' => $original['budget']
];
$zenith->setDailyBudgetAmount($data);
}
}
break;
case 'adgroup':
$customerId = null;
if ($original['media'] === 'google') {
$customerId = $this->google->getCustomerById($original['id'], 'adgroup');
}
if(isset($original['status'])){
if ($original['media'] === 'facebook') {
$zenith->setAdsetStatus($original['id'], $original['status']);
} else if ($original['media'] === 'google') {
$zenith->updateAdGroup($customerId['customerId'], $original['id'], $original['status']);
} else if ($original['media'] === 'kakao') {
$zenith->setAdGroupOnOff($original['id'], $original['status']);
}
}
if(isset($original['budget'])){
if ($original['media'] === 'facebook') {
$data = [
'id' => $original['id'],
'budget' => $original['budget']
];
$zenith->updateAdSetBudget($data);
} else if ($original['media'] === 'kakao') {
$data = [
'type' => 'adgroup',
'id' => $original['id'],
'budget' => $original['budget']
];
$zenith->setDailyBudgetAmount($data);
}
}
break;
case 'ad':
$customerId = null;
if ($original['media'] === 'google') {
$customerId = $this->google->getCustomerById($original['id'], 'ad');
}
if(isset($original['status'])){
if ($original['media'] === 'facebook') {
$zenith->setAdStatus($original['id'], $original['status']);
} else if ($original['media'] === 'google') {
$zenith->updateAdGroupAd($customerId['customerId'], null, $original['id'], $original['status']);
} else if ($original['media'] === 'kakao') {
$zenith->setCreativeOnOff($original['id'], $original['status']);
}
}
break;
default:
break;
}
}
$result['result'] = [
"result" => false,
'status' => 'failed',
"seq" => $seq
];
$result['log'] = [
"result" => false,
'status' => 'failed',
'msg' => $e->getMessage(),
"seq" => $seq,
];
return $result;
}
}
/* public function checkAutomationCondition($target)
{
$types = ['budget', 'dbcost', 'dbcount', 'cost', 'margin', 'margin_rate', 'sale', 'impression', 'click', 'cpc', 'ctr', 'conversion'];
$conditions = $this->automation->getAutomationConditionBySeq($target['aa_seq']);
if(empty($conditions)){return false;}
//순서 재정렬
usort($conditions, function($a, $b) {
return $a['order'] - $b['order'];
});
$isTargetMatched = false;
$allConditionsMatched = true;
foreach ($conditions as $condition) {
$conditionMatched = false;
$message = "일치하는 조건이 존재하지 않습니다.";
if ($condition['type'] === 'status') {//status 비교
if ($target['status'] == $condition['type_value']) {
$conditionMatched = true;
$message = 'status 일치';
}else{
$message = 'status가 일치하지 않습니다.';
}
}else{//그 외 필드 비교
foreach ($types as $type) {
if ($condition['type'] === $type) {
switch ($condition['compare']) {
case 'less':
$conditionMatched = $target[$type] < $condition['type_value'];
$message = $conditionMatched ? $condition['compare'].' 조건 일치' : $type.'값이 조건값보다 큽니다.'."(".$condition['compare'].")";;
break;
case 'greater':
$conditionMatched = $target[$type] > $condition['type_value'];
$message = $conditionMatched ? $condition['compare'].' 조건 일치' : $type.'값이 조건값보다 작습니다.'."(".$condition['compare'].")";;
break;
case 'less_equal':
$conditionMatched = $target[$type] <= $condition['type_value'];
$message = $conditionMatched ? $condition['compare'].' 조건 일치' : $type.'값이 조건값보다 크거나 같지 않습니다.'."(".$condition['compare'].")";;
break;
case 'greater_equal':
$conditionMatched = $target[$type] >= $condition['type_value'];
$message = $conditionMatched ? $condition['compare'].' 조건 일치' : $type.'값이 조건값보다 작거나 같지 않습니다.'."(".$condition['compare'].")";;
break;
case 'equal':
$conditionMatched = $target[$type] == $condition['type_value'];
$message = $conditionMatched ? $condition['compare'].' 조건 일치' : $type.'값이 조건값과 일치하지 않습니다.'."(".$condition['compare'].")";;
break;
case 'not_equal':
$conditionMatched = $target[$type] != $condition['type_value'];
$message = $conditionMatched ? $condition['compare'].' 조건 일치' : $type.'값이 조건값과 같습니다.'."(".$condition['compare'].")";
break;
default:
$conditionMatched = false;
$message = '비교할 조건이 존재하지 않습니다.';
break;
}
}
}
}
if($condition['operation'] == 'or'){
if($conditionMatched){
$isTargetMatched = true;
break;
}else{
//조건이 하나이고 조건에 해당되지 않을때
if(count($conditions) == 1){
$allConditionsMatched = false;
}
//and 조건이 없을때
if (!in_array('and', array_column($conditions, 'operation'))) {
$allConditionsMatched = false;
}
}
}
if($condition['operation'] == 'and'){
if(!$conditionMatched){
$allConditionsMatched = false;
//뒤에 or 조건이 있을수 있어서 or 조건이 없을때만 break
$nextKey = array_search($condition, $conditions) + 1;
if ($nextKey < count($conditions)) {
if ($conditions[$nextKey]['operation'] != 'or') {
break;
}
} else {
break;
}
}
}
}
if($isTargetMatched || $allConditionsMatched){
$matchedArray['match'][] = [
'aa_seq' => $target['aa_seq'],
'msg' => $message
];
}else{
$matchedArray['notMatch'][] = [
'aa_seq' => $target['aa_seq'],
'msg' => $message
];
}
return $matchedArray;
} */
private function sumData($data)
{
$formatData = [];
$formatData['budget'] = $formatData['click'] = $formatData['spend'] = $formatData['sales'] = $formatData['unique_total'] = $formatData['margin'] = 0;
if(isset($data[0]['status']) && in_array($data[0]['status'], ['ON', '1', 'ACTIVE', 'ENABLED'])){
$formatData['status'] = 'ON';
}else{
$formatData['status'] = 'OFF';
}
foreach ($data as $d) {
$formatData['budget'] += $d['budget'];
//$formatData['impressions'] += $d['impressions'];
$formatData['click'] += $d['click'];
$formatData['spend'] += $d['spend'];
$formatData['sales'] += $d['sales'];
$formatData['unique_total'] += $d['unique_total'];
$formatData['margin'] += $d['margin'];
}
return $formatData;
}
private function setData($data)
{
$formatData = [];
$formatData['budget'] = $formatData['click'] = $formatData['spend'] = $formatData['sales'] = $formatData['unique_total'] = $formatData['margin'] = $formatData['dbcost'] = $formatData['conversion']= $formatData['margin_rate'] = 0;
if(isset($data[0]['status']) && in_array($data[0]['status'], ['ON', '1', 'ACTIVE', 'ENABLED'])){
$formatData['status'] = 'ON';
}else{
$formatData['status'] = 'OFF';
}
foreach ($data as $d) {
$formatData['budget'] += $d['budget'];
//$formatData['impressions'] += $d['impressions'];
$formatData['click'] += $d['click'];
$formatData['spend'] += $d['spend'];
$formatData['sales'] += $d['sales'];
$formatData['unique_total'] += $d['unique_total'];
$formatData['margin'] += $d['margin'];
//CPC(Cost Per Click: 클릭당단가 (1회 클릭당 비용)) = 지출액/링크클릭
/* if($formatData['click'] > 0){
$formatData['cpc'] = round($formatData['spend'] / $formatData['click']);
} */
//CTR(Click Through Rate: 클릭율 (노출 대비 클릭한 비율)) = (링크클릭/노출수)*100
/* if($formatData['impressions'] > 0){
$formatData['ctr'] = ($formatData['click'] / $formatData['impressions']) * 100;
} */
//CPA(Cost Per Action: 현재 DB단가(전환당 비용)) = 지출액/유효db
if($formatData['unique_total'] > 0){
$formatData['dbcost'] = round($formatData['spend'] / $formatData['unique_total']);
}
//CVR(Conversion Rate:전환율 = (유효db / 링크클릭)*100
if ($formatData['click'] > 0) {
$formatData['conversion'] = ($formatData['unique_total'] / $formatData['click']) * 100;
}
//수익률 = (수익/매출액)*100
if ($formatData['sales'] > 0) {
$formatData['margin_rate'] = round(($formatData['margin'] / $formatData['sales']) * 100);
} else {
$formatData['margin_rate'] = 0;
}
}
return $formatData;
}
private function recordResult($result)
{
$resultData = [
'idx' => $result['seq'],
'result' => $result['status'],
'exec_timestamp' => date('Y-m-d H:i:s')
];
$row = $this->automation->recodeResult($resultData);
return $row;
}
private function recordLog($log, $resultRow)
{
$data = [];
if(!empty($log['schedule'])){
$data['idx'] = $resultRow['seq'];
$data['reg_datetime'] = $resultRow['reg_datetime'];
$data['schedule_desc'] = json_encode($log['schedule'], JSON_UNESCAPED_UNICODE);
}
if(isset($log['target'])) {
$data['idx'] = $resultRow['seq'];
$data['reg_datetime'] = $resultRow['reg_datetime'];
$data['target_desc'] = json_encode($log['target'], JSON_UNESCAPED_UNICODE);
}
if(isset($log['conditions'])) {
$data['idx'] = $resultRow['seq'];
$data['reg_datetime'] = $resultRow['reg_datetime'];
$data['conditions_desc'] = json_encode($log['conditions'], JSON_UNESCAPED_UNICODE);
}
if(isset($log['executions'])) {
$data['reg_datetime'] = $resultRow['reg_datetime'];
$data['executions_desc'] = json_encode($log['executions'], JSON_UNESCAPED_UNICODE);
}
if(!empty($data)){
$this->automation->recodeLog($data);
}
}
private function convertJsonToTimes($json) {
$data = json_decode($json, true);
$convertedTimes = [];
foreach ($data as $key => $times) {
foreach ($times as $time) {
// 값을 2로 나누어 시간으로 변환
$hour = floor($time / 2);
$minute = ($time % 2) * 30;
$convertedTime = sprintf("%d:%02d", $hour, $minute);
$convertedTimes[$key][] = $convertedTime;
}
}
return $convertedTimes;
}
}