shoppingmallv2/app/Controllers/EcommerceController.php
최준흠git config git config --helpgit config --global user.name 최준흠 b4de105a7d shoppingmallv2 init...
2023-08-10 22:26:56 +09:00

183 lines
7.7 KiB
PHP

<?php
namespace App\Controllers;
use App\Entities\PaymentEntity;
use App\Models\OrderModel;
use App\Models\PaymentModel;
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']}이 서로 다릅니다.");
}
// echo var_export($this->_viewDatas['fieldDatas']);
// exit;
//상품명을 복사해서 구매한 상품명에 넣기
$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);
}
}
//주문취소(uid -> order_uid)
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);
}
}
}