177 lines
7.5 KiB
PHP
177 lines
7.5 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers;
|
|
|
|
use App\Models\OrderModel;
|
|
use App\Models\ProductModel;
|
|
use CodeIgniter\Controller;
|
|
use CodeIgniter\HTTP\CLIRequest;
|
|
use CodeIgniter\HTTP\IncomingRequest;
|
|
use CodeIgniter\HTTP\RequestInterface;
|
|
use CodeIgniter\HTTP\ResponseInterface;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
class EcommerceController extends Controller
|
|
{
|
|
/**
|
|
* Instance of the main Request object.
|
|
*
|
|
* @var CLIRequest|IncomingRequest
|
|
*/
|
|
protected $request;
|
|
|
|
/**
|
|
* An array of helpers to be loaded automatically upon
|
|
* class instantiation. These helpers will be available
|
|
* to all other controllers that extend BaseController.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $helpers = ['Common'];
|
|
|
|
/**
|
|
* Be sure to declare properties for any property fetch you initialized.
|
|
* The creation of dynamic property is deprecated in PHP 8.2.
|
|
*/
|
|
// protected $session;
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
private $_session = null;
|
|
private $_viewDatas = array();
|
|
private $_orderModel = null;
|
|
private $_productModel = null;
|
|
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
|
|
{
|
|
parent::initController($request, $response, $logger);
|
|
$this->_session = \Config\Services::session();
|
|
$this->_viewDatas['title'] = '장바구니';
|
|
$this->_viewDatas['session'] = $this->_session;
|
|
}
|
|
private function getOrderModel()
|
|
{
|
|
return $this->_orderModel = $this->_orderModel ?: new OrderModel();
|
|
}
|
|
private function getProductModel()
|
|
{
|
|
return $this->_productModel = $this->_productModel ?: new ProductModel();
|
|
}
|
|
|
|
//주문
|
|
private function addCart_validate()
|
|
{
|
|
//fieldData Rule 검사
|
|
if (!$this->validate($this->_viewDatas['fieldRules'])) {
|
|
throw new \Exception("{$this->_viewDatas['title']}의 검증 오류발생\n" . implode("\n", $this->validator->getErrors()));
|
|
}
|
|
//fieldData 적용
|
|
$this->_viewDatas['fieldDatas'] = array();
|
|
foreach ($this->_viewDatas['fields'] as $field) {
|
|
$this->_viewDatas['fieldDatas'][$field] = $this->request->getVar($field);
|
|
}
|
|
}
|
|
|
|
public function addCart()
|
|
{
|
|
$msg = "";
|
|
try {
|
|
$this->_viewDatas['fields'] = ["product_uid", "quantity", "price"];
|
|
$this->_viewDatas['fieldRules'] = $this->getOrderModel()->getFieldRules($this->_viewDatas['fields']);
|
|
//Transaction 시작
|
|
$this->getOrderModel()->transStart();
|
|
//장바구니정보 검증
|
|
$this->addCart_validate();
|
|
//상품정보 가져오기
|
|
$product = $this->getProductModel()->getEntity([$this->getProductModel()->getPrimaryKey() => $this->_viewDatas['fieldDatas']['product_uid']]);
|
|
//재고수 비교
|
|
if ($product->stock < $this->_viewDatas['fieldDatas']['quantity']) {
|
|
throw new \Exception("구매수량이 너무 많습니다.\n구매수량:{$this->_viewDatas['fieldDatas']['quantity']}개, 남은 재고수량:{$product->stock}개");
|
|
}
|
|
//구매 금액 비교
|
|
$price = $product->price * $this->_viewDatas['fieldDatas']['quantity'];
|
|
if ($price != $this->_viewDatas['fieldDatas']['price']) {
|
|
throw new \Exception("실 상품금액{$price} 와 구매금액{$this->_viewDatas['fieldDatas']['price']}이 서로 다릅니다.");
|
|
}
|
|
//상품명을 복사해서 구매한 상품명에 넣기
|
|
$this->_viewDatas['fieldDatas'][$this->getOrderModel()->getTitleField()] = $product->getTitle();
|
|
//주문추가
|
|
$entity = $this->getOrderModel()->addCart($this->_viewDatas['fieldDatas']);
|
|
//상품재고감소
|
|
$product = $this->getProductModel()->addCart($product, $this->_viewDatas['fieldDatas']['quantity']);
|
|
//주문정보 세션에 넣기
|
|
$order_uids = $this->_session->get(SESSION_NAMES['CART']) ?: array();
|
|
$this->_session->set(SESSION_NAMES['CART'], [...$order_uids, $entity->getPrimaryKey()]);
|
|
//Transaction Commit
|
|
$this->getOrderModel()->transComplete();
|
|
$msg = sprintf(
|
|
"%s\n 상품명:%s\n 상품갯수:%s개, 구매금액:%s원\n 장바구니에 담았습니다.",
|
|
$this->_viewDatas['title'],
|
|
$entity->getTitle(),
|
|
$entity->quantity,
|
|
number_format($entity->price)
|
|
);
|
|
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
|
|
} catch (\Exception $e) {
|
|
//Transaction Rollback
|
|
$this->getOrderModel()->transRollback();
|
|
log_message("error", $e->getMessage());
|
|
$msg = sprintf(
|
|
"%s에서 다음 오류로 인해 장바구니에 담기를 실패하였습니다.\n%s",
|
|
$this->_viewDatas['title'],
|
|
$e->getMessage()
|
|
);
|
|
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
|
|
} finally {
|
|
$this->_session->setFlashdata("return_message", $msg);
|
|
}
|
|
}
|
|
|
|
//주문취소
|
|
public function cancelCart($uid)
|
|
{
|
|
$msg = "";
|
|
try {
|
|
//주문정보 가져오기
|
|
$entity = $this->getOrderModel()->getEntity([$this->getOrderModel()->getPrimaryKey() => $uid]);
|
|
//Transaction 시작
|
|
$this->getOrderModel()->transStart();
|
|
//주문취소
|
|
if (!$this->getOrderModel()->cancelCart($entity)) {
|
|
log_message("error", __FUNCTION__ . "에서 호출:" . $this->getOrderModel()->getLastQuery());
|
|
log_message("error", implode("\n", $this->getOrderModel()->errors()));
|
|
throw new \Exception(__FUNCTION__ . " 오류 발생.\n" . var_export($this->getOrderModel()->errors(), true));
|
|
}
|
|
//상품정보 가져오기
|
|
$product = $this->getProductModel()->getEntity([$this->getProductModel()->getPrimaryKey() => $entity->product_uid]);
|
|
//상품반환
|
|
$product = $this->getProductModel()->cancelCart($product, $entity->quantity);
|
|
//주문정보 세션에서 빼기
|
|
$order_uids = $this->_session->get(SESSION_NAMES['CART']) ?: array();
|
|
$temps = array();
|
|
foreach ($order_uids as $order_uid) {
|
|
if ($order_uid != $entity->getPrimaryKey()) {
|
|
array_push($temps, $order_uid);
|
|
}
|
|
}
|
|
$this->_session->set(SESSION_NAMES['CART'], $temps);
|
|
//Transaction Commit
|
|
$this->getOrderModel()->transComplete();
|
|
$msg = "{$this->_viewDatas['title']}에서 {$entity->getTitle()} {$entity->quantity}개의 주문을 취소하였습니다.";
|
|
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
|
|
} catch (\Exception $e) {
|
|
//Transaction Rollback
|
|
$this->getOrderModel()->transRollback();
|
|
$msg = sprintf(
|
|
"%s에서 다음 오류로 인해 주문취소를 실패하였습니다.\n%s",
|
|
$this->_viewDatas['title'],
|
|
$e->getMessage()
|
|
);
|
|
log_message("error", $e->getMessage());
|
|
return redirect()->to($this->_session->getFlashdata(SESSION_NAMES['RETURN_URL']));
|
|
} finally {
|
|
$this->_session->setFlashdata("return_message", $msg);
|
|
}
|
|
}
|
|
}
|