본문으로 건너뛰기

소스 변경 전체 보기

PHP 8 · GODO25
변경 파일 수: 19개
변경 파일 목록
총 19개
변경 파일 코드
추가삭제
우체국 반품 수거 연동
Admin/order/popup_epost_apply_frame.php+14
변경 전popup_epost_apply_frame.php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
변경 후popup_epost_apply_frame.php
<script src="<?= gd_set_browser_cache(PATH_ADMIN_GD_SHARE . 'ncds/script/common/aggregator-message-router.js') ?>"></script>
<style>
/* 팝업(720px)이 어드민 공통 body min-width(970px)보다 좁아 오른쪽이 잘리는 것 방지 */
body { min-width: 0; overflow: hidden; }
</style>
<iframe name="epostApply" src="<?= htmlspecialchars($pageUrl, ENT_QUOTES, 'UTF-8') ?>" frameborder="0" marginwidth="0" marginheight="0" width="100%" style="height: 100vh;"></iframe>
<script>
// 허브가 신청 완료 시 MODAL_CLOSE 전송 — iframe 은 창을 못 닫으므로 여기서 팝업 창을 닫는다
IframeMessageRouter.init({
onModalClose: function () {
window.close();
},
});
</script>
 
Admin/order/post_request.php+29-23
변경 전post_request.php
<h3><?=end($naviMenu->location); ?></h3>
</div>
 
<div class="table-title">우체국택배 배송상태 자동 업데이트 </div>
<table class="table table-cols">
<tbody>
<tr>
<td style="padding: 15px 0;">
<div class="notice-info" style="margin-top: 0;margin-bottom: 0">
우체국택배 배송상태를 쇼핑몰에 2시간마다 자동으로 업데이트 합니다.<br/>
2시간마다 자동으로 배송상태를 확인하여 배송이 완료된 주문은 ‘배송완료’로 업데이트 됩니다.
</div>
</td>
</tr>
</tbody>
</table>
 
<div class="table-title">우체국택배 배송상태 수동 업데이트 </div>
<table class="table table-cols">
 
 
 
 
<tbody>
<tr>
<td style="padding: 15px 0 20px 0;">
<div class="notice-info" style="margin-top: 0;margin-bottom: 0">
우체국택배 배송상태를 쇼핑몰에 수동 업데이트하려면, 아래 버튼을 클릭해 주세요.<br/>
수동으로 배송상태를 확인하여 배송이 완료된 주문은 ‘배송완료’로 업데이트 됩니다.
</div>
<div style="padding-top: 15px;"><a href="./post_ps.php?mode=manual" class="btn btn-lg btn-black" target="ifrmProcess" style="color:#fff">배송상태 수동 업데이트</a></div>
 
 
 
 
 
 
 
</td>
</tr>
</tbody>
</table>
<div class="table-title ">우체국택배 신청 </div>
<iframe name="requestPostIfrm" src="https://www.nhn-commerce.com/service/godopost/regist.php?shopSno=<?=$shopSno?>&shopHost=<?=$domainUrl?>" frameborder="0" height="830px" width="100%"></iframe>
 
 
 
 
 
 
 
 
 
 
변경 후post_request.php
<h3><?=end($naviMenu->location); ?></h3>
</div>
 
<div class="table-title">우체국택배 관리</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<table class="table table-cols">
<colgroup>
<col class="width-md" />
<col />
</colgroup>
<tbody>
<tr>
<th>우체국택배 신청</th>
<td>
<?php if ($isUsageNone): ?>
<a href="javascript:void(0)" id="epr-btn-apply" class="btn btn-white btn-sm">서비스 신청하기</a>
<?php elseif ($usageRequestStatus !== null): ?>
<?=$usageRequestStatus->label()?>
<?php endif; ?>
</td>
</tr>
<tr>
<th>우체국택배 배송상태 수동 업데이트</th>
<td>
<a href="./post_ps.php?mode=manual" class="btn btn-gray btn-sm" target="ifrmProcess">배송상태 수동 업데이트</a>
</td>
</tr>
</tbody>
</table>
 
<script>
document.addEventListener('DOMContentLoaded', function () {
var applyBtn = document.querySelector('#epr-btn-apply');
if (applyBtn) {
applyBtn.addEventListener('click', function () {
window.open('./popup_epost_apply.php', 'epostApply', 'width=720,height=800,scrollbars=yes');
});
}
});
</script>
 
Controller/Admin/Order/PostIssueController.php+3-2
변경 전PostIssueController.php
try {
// --- 메뉴 설정
$this->callMenu('order', 'epostParcel', 'issue');
 
$this->addScript(
[
'jquery/jquery.multi_select_box.js',
]
);
$godopost= gd_policy('order.godopost');
if(empty($godopost['compdivcd']) === true) {
throw new AlertBackException(__("우체국택배 서비스 신청 후 이용 가능합니다."));
}
 
변경 후PostIssueController.php
try {
// --- 메뉴 설정
$this->callMenu('order', 'epostParcel', 'issue');
$this->setMenuCode('order', 'epostParcel', 'issue');
$this->addScript(
[
'jquery/jquery.multi_select_box.js',
]
);
$godoPost = \App::load('\\Component\\Godo\\GodoPostServerApi');
if ($godoPost->isUsageNotRequested()) {
throw new AlertBackException(__("우체국택배 서비스 신청 후 이용 가능합니다."));
}
 
Controller/Admin/Order/PostPsController.php+10-1
변경 전PostPsController.php
$postValue = Request::post()->toArray();
$orderAdmin = \App::load('\\Component\\Order\\OrderAdmin');
 
try {
switch (Request::request()->get('mode')) {
// 우체국택배 송장 발급
case 'issue':
 
 
 
 
$result = $orderAdmin->saveOrderInvoice($postValue);
break;
// 우체국택배 예약
case 'reserve':
 
 
 
 
 
$orderAdmin->reserveOrderInvoice($postValue);
throw new LayerException(__("우체국택배로 예약되었습니다."));
break;
break;
// 우체국수동업데이트
case 'manual':
$godoPost = \App::load('\\Component\\Godo\\GodoPostServerApi');
$data = $godoPost->saveManualUpdate();
throw new LayerException(sprintf(__("주문 %s 건의 우체국 택배 배송상태를 수동 업데이트 하였습니다."), $data));
break;
 
변경 후PostPsController.php
$postValue = Request::post()->toArray();
$orderAdmin = \App::load('\\Component\\Order\\OrderAdmin');
$godoPost = \App::load('\\Component\\Godo\\GodoPostServerApi');
try {
switch (Request::request()->get('mode')) {
// 우체국택배 송장 발급
case 'issue':
$this->setMenuCode('order', 'epostParcel', 'issue');
if ($godoPost->isUsageNotRequested()) {
throw new LayerException(__('우체국택배 서비스 신청 후 이용 가능합니다.'));
}
$result = $orderAdmin->saveOrderInvoice($postValue);
break;
// 우체국택배 예약
case 'reserve':
$this->setMenuCode('order', 'epostParcel', 'reserve');
if ($godoPost->isUsageNotRequested()) {
throw new LayerException(__('우체국택배 서비스 신청 후 이용 가능합니다.'));
}
$orderAdmin->reserveOrderInvoice($postValue);
throw new LayerException(__("우체국택배로 예약되었습니다."));
break;
break;
// 우체국수동업데이트
case 'manual':
 
$data = $godoPost->saveManualUpdate();
throw new LayerException(sprintf(__("주문 %s 건의 우체국 택배 배송상태를 수동 업데이트 하였습니다."), $data));
break;
 
Controller/Admin/Order/PostRequestController.php+62-43
변경 전PostRequestController.php
<?php
/**
* This is commercial software, only users who have purchased a valid license
* and accept to the terms of the License Agreement can install and use this
* program.
*
* Do not edit or add to this file if you wish to upgrade Godomall5 to newer
* versions in the future.
*
* @copyright ⓒ 2016, NHN godo: Corp.
* @link http://www.godo.co.kr
*/
namespace Bundle\Controller\Admin\Order;
use Globals;
use Request;
class PostRequestController extends \Controller\Admin\Controller
{
/**
* 우체국택배연동 가입
*
* @author atomyang
* @version 1.0
* @since 1.0
* @copyright ⓒ 2016, NHN godo: Corp.
* @param array $get
* @param array $post
* @param array $files
* @throws Except
*/
public function index()
{
// --- 메뉴 설정
$this->callMenu('order', 'epostParcel', 'request');
// --- 관리자 디자인 템플릿
$gLicense = Globals::get('gLicense');
$this->setData('shopSno', $gLicense['godosno']);
$this->setData('domainUrl', Request::getHostNoPort());
}
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
변경 후PostRequestController.php
<?php
 
/**
* This is commercial software, only users who have purchased a valid license
* and accept to the terms of the License Agreement can install and use this
* program.
*
* Do not edit or add to this file if you wish to upgrade Godomall5 to newer
* versions in the future.
*
* @copyright ⓒ 2016, NHN godo: Corp.
* @link http://www.godo.co.kr
*/
namespace Bundle\Controller\Admin\Order;
 
use Origin\Enum\ApiClient\Epost\EpostUsageRequestStatus;
use Origin\Service\ApiClient\Commerce\Epost\EpostUsageAdminApiClientService;
use Throwable;
 
class PostRequestController extends \Controller\Admin\Controller
{
 
/**
* 우체국택배연동 가입
*
* @author atomyang
* @version 1.0
* @since 1.0
* @copyright ⓒ 2016, NHN godo: Corp.
* @param array $get
* @param array $post
* @param array $files
* @throws Except
*/
public function index()
{
// --- 메뉴 설정
$this->callMenu('order', 'epostParcel', 'request');
$this->setMenuCode('order', 'epostParcel', 'request');
 
// 우체국택배 서비스 신청 진행 상태 — 「우체국택배 신청」 항목 상태 텍스트/버튼 분기용
$usageRequestStatus = $this->findUsageRequestStatus();
$this->setData('usageRequestStatus', $usageRequestStatus);
$this->setData('isUsageNone', $usageRequestStatus === EpostUsageRequestStatus::NONE);
}
 
/**
* 신청 진행 상태 조회 — 실패해도 화면은 정상 노출하고 상태 표기만 생략함
*
* @return EpostUsageRequestStatus|null
*/
private function findUsageRequestStatus(): ?EpostUsageRequestStatus
{
try {
return \App::getInstance(EpostUsageAdminApiClientService::class)
->findUsageRequestStatus()
->getStatus();
} catch (Throwable $e) {
return null;
}
}
}
 
Controller/Admin/Order/PostReserveController.php+3-2
변경 전PostReserveController.php
try {
// --- 메뉴 설정
$this->callMenu('order', 'epostParcel', 'reserve');
 
$godopost= gd_policy('order.godopost');
if(empty($godopost['compdivcd']) === true) {
throw new AlertBackException(__("우체국택배 서비스 신청 후 이용 가능합니다."));
}
 
변경 후PostReserveController.php
try {
// --- 메뉴 설정
$this->callMenu('order', 'epostParcel', 'reserve');
$this->setMenuCode('order', 'epostParcel', 'reserve');
$godoPost = \App::load('\\Component\\Godo\\GodoPostServerApi');
if ($godoPost->isUsageNotRequested()) {
throw new AlertBackException(__("우체국택배 서비스 신청 후 이용 가능합니다."));
}
 
data/skin/front/moment/mypage/_order_goods_list.html+19
변경 전_order_goods_list.html
</div>
<!--{ / }-->
<!--{ : }-->
 
 
 
<div>({=__(..deliveryMethodFlText)})</div>
<!--{ / }-->
 
<!--{ ? ..orderStatus == 'd1' }-->
<a href="#" class="btn_gray_small js_btn_order_delivery"><span>{=__('수취확인')}</span></a>
<!--{ / }-->
}
});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 배송추적
$('.js_btn_delivery_trace').click(function (e) {
win = gd_popup({
 
변경 후_order_goods_list.html
</div>
<!--{ / }-->
<!--{ : }-->
<!--{ ? ..returnTraceUrl }-->
({=__(..deliveryMethodFlText)}) - <a href="{..returnTraceUrl}" class="btn_gray_small js_btn_return_trace"><span>{=__('반송추적')}</span></a>
<!--{ : }-->
<div>({=__(..deliveryMethodFlText)})</div>
<!--{ / }-->
<!--{ / }-->
<!--{ ? ..orderStatus == 'd1' }-->
<a href="#" class="btn_gray_small js_btn_order_delivery"><span>{=__('수취확인')}</span></a>
<!--{ / }-->
}
});
 
// 반송추적 — 서버 조립 URL 팝업 (송장 원문 미노출)
$('.js_btn_return_trace').click(function (e) {
e.preventDefault();
win = gd_popup({
url: $(this).attr('href'),
target: 'returnTrace',
width: 650,
height: 660,
resizable: 'yes',
scrollbars: 'yes'
});
win.focus();
return win;
});
 
// 배송추적
$('.js_btn_delivery_trace').click(function (e) {
win = gd_popup({
 
data/skin/front/moment/mypage/_reorder_goods_list.html+19
변경 전_reorder_goods_list.html
</div>
<!--{ / }-->
<!--{ : }-->
 
 
 
<div>({=__(..deliveryMethodFlText)})</div>
<!--{ / }-->
 
<!--{ ? ..orderStatus == 'd1' }-->
<a href="#" class="btn_gray_small js_btn_order_delivery"><span>{=__('수취확인')}</span></a>
<!--{ / }-->
}
});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 배송추적
$('.js_btn_delivery_trace').click(function (e) {
win = gd_popup({
 
변경 후_reorder_goods_list.html
</div>
<!--{ / }-->
<!--{ : }-->
<!--{ ? ..returnTraceUrl }-->
({=__(..deliveryMethodFlText)}) - <a href="{..returnTraceUrl}" class="btn_gray_small js_btn_return_trace"><span>{=__('반송추적')}</span></a>
<!--{ : }-->
<div>({=__(..deliveryMethodFlText)})</div>
<!--{ / }-->
<!--{ / }-->
<!--{ ? ..orderStatus == 'd1' }-->
<a href="#" class="btn_gray_small js_btn_order_delivery"><span>{=__('수취확인')}</span></a>
<!--{ / }-->
}
});
 
// 반송추적 — 서버 조립 URL 팝업 (송장 원문 미노출)
$('.js_btn_return_trace').click(function (e) {
e.preventDefault();
win = gd_popup({
url: $(this).attr('href'),
target: 'returnTrace',
width: 650,
height: 660,
resizable: 'yes',
scrollbars: 'yes'
});
win.focus();
return win;
});
 
// 배송추적
$('.js_btn_delivery_trace').click(function (e) {
win = gd_popup({
 
data/skin/front/mygreek/mypage/_order_goods_list.html+19
변경 전_order_goods_list.html
</div>
<!--{ / }-->
<!--{ : }-->
 
 
 
<div>({=__(..deliveryMethodFlText)})</div>
<!--{ / }-->
 
<!--{ ? ..orderStatus == 'd1' }-->
<a href="#" class="btn_gray_small js_btn_order_delivery"><span>{=__('수취확인')}</span></a>
<!--{ / }-->
}
});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 배송추적
$('.js_btn_delivery_trace').click(function (e) {
win = gd_popup({
 
변경 후_order_goods_list.html
</div>
<!--{ / }-->
<!--{ : }-->
<!--{ ? ..returnTraceUrl }-->
({=__(..deliveryMethodFlText)}) - <a href="{..returnTraceUrl}" class="btn_gray_small js_btn_return_trace"><span>{=__('반송추적')}</span></a>
<!--{ : }-->
<div>({=__(..deliveryMethodFlText)})</div>
<!--{ / }-->
<!--{ / }-->
<!--{ ? ..orderStatus == 'd1' }-->
<a href="#" class="btn_gray_small js_btn_order_delivery"><span>{=__('수취확인')}</span></a>
<!--{ / }-->
}
});
 
// 반송추적 — 서버 조립 URL 팝업 (송장 원문 미노출)
$('.js_btn_return_trace').click(function (e) {
e.preventDefault();
win = gd_popup({
url: $(this).attr('href'),
target: 'returnTrace',
width: 650,
height: 660,
resizable: 'yes',
scrollbars: 'yes'
});
win.focus();
return win;
});
 
// 배송추적
$('.js_btn_delivery_trace').click(function (e) {
win = gd_popup({
 
data/skin/front/mygreek/mypage/_reorder_goods_list.html+19
변경 전_reorder_goods_list.html
</div>
<!--{ / }-->
<!--{ : }-->
 
 
 
<div>({=__(..deliveryMethodFlText)})</div>
<!--{ / }-->
 
<!--{ ? ..orderStatus == 'd1' }-->
<a href="#" class="btn_gray_small js_btn_order_delivery"><span>{=__('수취확인')}</span></a>
<!--{ / }-->
}
});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 배송추적
$('.js_btn_delivery_trace').click(function (e) {
win = gd_popup({
 
변경 후_reorder_goods_list.html
</div>
<!--{ / }-->
<!--{ : }-->
<!--{ ? ..returnTraceUrl }-->
({=__(..deliveryMethodFlText)}) - <a href="{..returnTraceUrl}" class="btn_gray_small js_btn_return_trace"><span>{=__('반송추적')}</span></a>
<!--{ : }-->
<div>({=__(..deliveryMethodFlText)})</div>
<!--{ / }-->
<!--{ / }-->
<!--{ ? ..orderStatus == 'd1' }-->
<a href="#" class="btn_gray_small js_btn_order_delivery"><span>{=__('수취확인')}</span></a>
<!--{ / }-->
}
});
 
// 반송추적 — 서버 조립 URL 팝업 (송장 원문 미노출)
$('.js_btn_return_trace').click(function (e) {
e.preventDefault();
win = gd_popup({
url: $(this).attr('href'),
target: 'returnTrace',
width: 650,
height: 660,
resizable: 'yes',
scrollbars: 'yes'
});
win.focus();
return win;
});
 
// 배송추적
$('.js_btn_delivery_trace').click(function (e) {
win = gd_popup({
 
data/skin/front/story_g/mypage/_order_goods_list.html+19
변경 전_order_goods_list.html
</span>
<!--{ / }-->
<!--{ : }-->
 
 
 
<div>({=__(..deliveryMethodFlText)})</div>
<!--{ / }-->
 
<!--{ ? ..orderStatus == 'd1' }-->
<div class="button"><a href="#" class="normal-btn small1 btn-order-delivery"><em>{=__('수취확인')}</em></a></div>
<!--{ / }-->
}
});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 배송추적
$('.btn-delivery-trace').click(function (e) {
win = popup({
 
변경 후_order_goods_list.html
</span>
<!--{ / }-->
<!--{ : }-->
<!--{ ? ..returnTraceUrl }-->
({=__(..deliveryMethodFlText)}) - <span class="button"><a href="{..returnTraceUrl}" class="normal-btn small1 btn-return-trace"><em>{=__('반송추적')}</em></a></span>
<!--{ : }-->
<div>({=__(..deliveryMethodFlText)})</div>
<!--{ / }-->
<!--{ / }-->
<!--{ ? ..orderStatus == 'd1' }-->
<div class="button"><a href="#" class="normal-btn small1 btn-order-delivery"><em>{=__('수취확인')}</em></a></div>
<!--{ / }-->
}
});
// 반송추적 — 서버 조립 URL 팝업 (송장 원문 미노출)
$('.btn-return-trace').click(function (e) {
e.preventDefault();
win = popup({
url: $(this).attr('href'),
target: 'returnTrace',
width: 650,
height: 660,
resizable: 'yes',
scrollbars: 'yes'
});
win.focus();
return win;
});
// 배송추적
$('.btn-delivery-trace').click(function (e) {
win = popup({
 
data/skin/front/story_g/mypage/_reorder_goods_list.html+19
변경 전_reorder_goods_list.html
</span>
<!--{ / }-->
<!--{ : }-->
 
 
 
<div>({=__(..deliveryMethodFlText)})</div>
<!--{ / }-->
 
<!--{ ? ..orderStatus == 'd1' }-->
<div class="button"><a href="#" class="normal-btn small1 btn-order-delivery"><em>{=__('수취확인')}</em></a></div>
<!--{ / }-->
}
});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// 배송추적
$('.btn-delivery-trace').click(function (e) {
win = popup({
 
변경 후_reorder_goods_list.html
</span>
<!--{ / }-->
<!--{ : }-->
<!--{ ? ..returnTraceUrl }-->
({=__(..deliveryMethodFlText)}) - <span class="button"><a href="{..returnTraceUrl}" class="normal-btn small1 btn-return-trace"><em>{=__('반송추적')}</em></a></span>
<!--{ : }-->
<div>({=__(..deliveryMethodFlText)})</div>
<!--{ / }-->
<!--{ / }-->
<!--{ ? ..orderStatus == 'd1' }-->
<div class="button"><a href="#" class="normal-btn small1 btn-order-delivery"><em>{=__('수취확인')}</em></a></div>
<!--{ / }-->
}
});
 
// 반송추적 — 서버 조립 URL 팝업 (송장 원문 미노출)
$('.btn-return-trace').click(function (e) {
e.preventDefault();
win = popup({
url: $(this).attr('href'),
target: 'returnTrace',
width: 650,
height: 660,
resizable: 'yes',
scrollbars: 'yes'
});
win.focus();
return win;
});
 
// 배송추적
$('.btn-delivery-trace').click(function (e) {
win = popup({
 
data/skin/mobile/moment/mypage/_order_goods_list.html+4
변경 전_order_goods_list.html
</li>
<!--{ / }-->
<!--{ : }-->
 
 
 
<li>
<a class="delivery_trace_btn" style="max-width:100px; overflow:hidden;">{...deliveryMethodFlText}</a>
</li>
<!--{ / }-->
 
<!--{ ? ...orderStatus == 'd1' }-->
<li><a href="#" class="delivery_order_btn btn_order_delivery" order-no="{..orderNo}" order-goodsno="{...sno}">{=__('수취확인')}</a></li>
<!--{ / }-->
 
변경 후_order_goods_list.html
</li>
<!--{ / }-->
<!--{ : }-->
<!--{ ? ...returnTraceUrl }-->
<li><a href="{...returnTraceUrl}" class="delivery_trace_btn" target="_blank">{=__('반송추적')}</a></li>
<!--{ : }-->
<li>
<a class="delivery_trace_btn" style="max-width:100px; overflow:hidden;">{...deliveryMethodFlText}</a>
</li>
<!--{ / }-->
<!--{ / }-->
<!--{ ? ...orderStatus == 'd1' }-->
<li><a href="#" class="delivery_order_btn btn_order_delivery" order-no="{..orderNo}" order-goodsno="{...sno}">{=__('수취확인')}</a></li>
<!--{ / }-->
 
data/skin/mobile/moment/mypage/_reorder_goods_list.html+4
변경 전_reorder_goods_list.html
</li>
<!--{ / }-->
<!--{ : }-->
 
 
 
<li>
<a class="delivery_trace_btn" style="max-width:100px; overflow:hidden;">{...deliveryMethodFlText}</a>
</li>
<!--{ / }-->
 
<!--{ ? ...orderStatus == 'd1' }-->
<li><a href="#" class="delivery_order_btn btn_order_delivery" order-no="{..orderNo}" order-goodsno="{...sno}">{=__('수취확인')}</a></li>
<!--{ / }-->
 
변경 후_reorder_goods_list.html
</li>
<!--{ / }-->
<!--{ : }-->
<!--{ ? ...returnTraceUrl }-->
<li><a href="{...returnTraceUrl}" class="delivery_trace_btn" target="_blank">{=__('반송추적')}</a></li>
<!--{ : }-->
<li>
<a class="delivery_trace_btn" style="max-width:100px; overflow:hidden;">{...deliveryMethodFlText}</a>
</li>
<!--{ / }-->
<!--{ / }-->
<!--{ ? ...orderStatus == 'd1' }-->
<li><a href="#" class="delivery_order_btn btn_order_delivery" order-no="{..orderNo}" order-goodsno="{...sno}">{=__('수취확인')}</a></li>
<!--{ / }-->
 
data/skin/mobile/mygreek/mypage/_order_goods_list.html+4
변경 전_order_goods_list.html
</li>
<!--{ / }-->
<!--{ : }-->
 
 
 
<li>
<a class="delivery_trace_btn" style="max-width:100px; overflow:hidden;">{...deliveryMethodFlText}</a>
</li>
<!--{ / }-->
 
<!--{ ? ...orderStatus == 'd1' }-->
<li><a href="#" class="delivery_order_btn btn_order_delivery" order-no="{..orderNo}" order-goodsno="{...sno}">{=__('수취확인')}</a></li>
<!--{ / }-->
 
변경 후_order_goods_list.html
</li>
<!--{ / }-->
<!--{ : }-->
<!--{ ? ...returnTraceUrl }-->
<li><a href="{...returnTraceUrl}" class="delivery_trace_btn" target="_blank">{=__('반송추적')}</a></li>
<!--{ : }-->
<li>
<a class="delivery_trace_btn" style="max-width:100px; overflow:hidden;">{...deliveryMethodFlText}</a>
</li>
<!--{ / }-->
<!--{ / }-->
<!--{ ? ...orderStatus == 'd1' }-->
<li><a href="#" class="delivery_order_btn btn_order_delivery" order-no="{..orderNo}" order-goodsno="{...sno}">{=__('수취확인')}</a></li>
<!--{ / }-->
 
data/skin/mobile/mygreek/mypage/_reorder_goods_list.html+4
변경 전_reorder_goods_list.html
</li>
<!--{ / }-->
<!--{ : }-->
 
 
 
<li>
<a class="delivery_trace_btn" style="max-width:100px; overflow:hidden;">{...deliveryMethodFlText}</a>
</li>
<!--{ / }-->
 
<!--{ ? ...orderStatus == 'd1' }-->
<li><a href="#" class="delivery_order_btn btn_order_delivery" order-no="{..orderNo}" order-goodsno="{...sno}">{=__('수취확인')}</a></li>
<!--{ / }-->
 
변경 후_reorder_goods_list.html
</li>
<!--{ / }-->
<!--{ : }-->
<!--{ ? ...returnTraceUrl }-->
<li><a href="{...returnTraceUrl}" class="delivery_trace_btn" target="_blank">{=__('반송추적')}</a></li>
<!--{ : }-->
<li>
<a class="delivery_trace_btn" style="max-width:100px; overflow:hidden;">{...deliveryMethodFlText}</a>
</li>
<!--{ / }-->
<!--{ / }-->
<!--{ ? ...orderStatus == 'd1' }-->
<li><a href="#" class="delivery_order_btn btn_order_delivery" order-no="{..orderNo}" order-goodsno="{...sno}">{=__('수취확인')}</a></li>
<!--{ / }-->
 
data/skin/mobile/story_g/mypage/_order_goods_list.html+4
변경 전_order_goods_list.html
</li>
<!--{ / }-->
<!--{ : }-->
 
 
 
<li>
<a class="btn btn_w">{...deliveryMethodFlText}</a>
</li>
<!--{ / }-->
 
<!--{ ? ...orderStatus == 'd1' }-->
<li><a href="#" class="btn btn_y btn-order-delivery" order-no="{..orderNo}" order-goodsno="{...sno}">{=__('수취확인')}</a></li>
<!--{ / }-->
 
변경 후_order_goods_list.html
</li>
<!--{ / }-->
<!--{ : }-->
<!--{ ? ...returnTraceUrl }-->
<li><a href="{...returnTraceUrl}" class="btn btn_w" target="_blank">{=__('반송추적')}</a></li>
<!--{ : }-->
<li>
<a class="btn btn_w">{...deliveryMethodFlText}</a>
</li>
<!--{ / }-->
<!--{ / }-->
<!--{ ? ...orderStatus == 'd1' }-->
<li><a href="#" class="btn btn_y btn-order-delivery" order-no="{..orderNo}" order-goodsno="{...sno}">{=__('수취확인')}</a></li>
<!--{ / }-->
 
data/skin/mobile/story_g/mypage/_reorder_goods_list.html+4
변경 전_reorder_goods_list.html
</li>
<!--{ / }-->
<!--{ : }-->
 
 
 
<li>
<a class="btn btn_w">{...deliveryMethodFlText}</a>
</li>
<!--{ / }-->
 
<!--{ ? ...orderStatus == 'd1' }-->
<li><a href="#" class="btn btn_y btn-order-delivery" order-no="{..orderNo}" order-goodsno="{...sno}">{=__('수취확인')}</a></li>
<!--{ / }-->
 
변경 후_reorder_goods_list.html
</li>
<!--{ / }-->
<!--{ : }-->
<!--{ ? ...returnTraceUrl }-->
<li><a href="{...returnTraceUrl}" class="btn btn_w" target="_blank">{=__('반송추적')}</a></li>
<!--{ : }-->
<li>
<a class="btn btn_w">{...deliveryMethodFlText}</a>
</li>
<!--{ / }-->
<!--{ / }-->
<!--{ ? ...orderStatus == 'd1' }-->
<li><a href="#" class="btn btn_y btn-order-delivery" order-no="{..orderNo}" order-goodsno="{...sno}">{=__('수취확인')}</a></li>
<!--{ / }-->
 
WebFTP 보안 강화
Controller/Admin/Share/PopupWebftpPsController.php+59
변경 전PopupWebftpPsController.php
]
);
}
 
 
 
 
 
 
 
 
 
 
 
FileHandler::delete(iconv('UTF-8', 'CP949', $file), true);
$this->json(
[
if (!Request::request()->has('target')) {
throw new \InvalidArgumentException(__('변경할 이름을 입력해주세요.'));
}
 
 
 
 
 
 
 
 
 
if (getenv('setting') == 'y') {
FileHandler::rename(iconv('UTF-8', 'CP949', $file), iconv('UTF-8', 'CP949', Request::request()->get('target')));
} else {
exit;
}
 
 
 
 
 
 
// 한글 파일명 업로드를 위해 인코딩 변경 처리
move_uploaded_file($tmpName[0], iconv('UTF-8', 'CP949', $file . '/' . $name[0]));
break;
}
}
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
}
 
변경 후PopupWebftpPsController.php
]
);
}
 
// 목록에 없는 경로를 직접 보내 상점 폴더 밖을 지우는 것을 막는다 — data/../../route.php
if ($this->isOutsideDataPath($file)) {
$this->json(
[
'error' => 1,
'message' => __('삭제할 파일이 없습니다.'),
]
);
}
 
FileHandler::delete(iconv('UTF-8', 'CP949', $file), true);
$this->json(
[
if (!Request::request()->has('target')) {
throw new \InvalidArgumentException(__('변경할 이름을 입력해주세요.'));
}
 
// 세팅 모드 target 은 앞단에서 USERPATH 로 치환돼 들어오므로 아래 호출부와 같은 방식으로 조립한다
$renameTarget = getenv('setting') == 'y' ? Request::request()->get('target') : USERPATH . Request::request()->get('target');
 
// 원본은 밖의 파일을 건드리는 것을(route.php → x.js), 대상은 밖으로 빼내는 것을(a.png → ../../evil.js) 막는다
if ($this->isOutsideDataPath($file) || $this->isOutsideDataPath($renameTarget)) {
throw new \InvalidArgumentException(__('잘못된 경로로 접근하셨습니다.'));
}
 
if (getenv('setting') == 'y') {
FileHandler::rename(iconv('UTF-8', 'CP949', $file), iconv('UTF-8', 'CP949', Request::request()->get('target')));
} else {
exit;
}
 
// 저장 위치와 파일명이 합쳐진 최종 경로로 판정한다 — 둘 중 어느 쪽에 상위 이동이 섞여도 걸린다
if ($this->isOutsideDataPath($file . '/' . $name[0])) {
throw new \InvalidArgumentException(__('잘못된 경로로 접근하셨습니다.'));
}
 
// 한글 파일명 업로드를 위해 인코딩 변경 처리
move_uploaded_file($tmpName[0], iconv('UTF-8', 'CP949', $file . '/' . $name[0]));
break;
}
}
}
 
/**
* 작업 대상이 상점 data 폴더 밖을 가리키는지 확인한다.
*
* @param string $path 파일 처리 함수에 넘어갈 경로
*
* @return bool data 폴더 밖이면 true
*/
protected function isOutsideDataPath(string $path): bool
{
// 세팅 모드 파일 경로는 앞에 슬래시가 하나 더 붙어 들어온다 — //shop/user/data/a.png
$targetPath = preg_replace('#/+#', '/', $path);
 
// 세팅 모드는 화면이 넘긴 현재 경로가 상대형으로 온다 — data/logo.png
if (strpos($targetPath, USERPATH) !== 0) {
$targetPath = USERPATH . ltrim($targetPath, '/');
}
 
// 상위 이동을 해석해 실제로 가리키는 경로를 구한다 — data/skin/../../route.php 는 상점 폴더 밖
$resolved = [];
foreach (explode('/', $targetPath) as $segment) {
if ($segment === '.') {
continue;
}
if ($segment === '..') {
array_pop($resolved);
continue;
}
$resolved[] = $segment;
}
$resolvedPath = implode('/', $resolved);
 
return strpos($resolvedPath, USERPATH . 'data/') !== 0;
}
}