Posts

마젠토의 주문 상태 state vs status 비교 및 차이점

마젠토 개발을 하다보면 주문관련 데이터베이스 테이블에(sales_flat_order) 주문의 상태를 나타내는 statestatus 필드를 발견할수 있습니다.
단어 자체로만 봤을떄 영어로도 이 두개의 의미는 별반 차이가 없구요 처음 접하거나 차이점을 잘 모르는 사람들에게 혼란만 가중시킬 뿐입니다.
하지만 같은 의미를 가진 이 두가지는 엄연히 용도가 다릅니다.

state vs status


state은 마젠토 데이터베이스 내에서 주문상태를 나타내는 attribute이구요, new, processing, complete, holded, closed, canceled, payment_review, pending_review 등등이 있습니다.
status는 state을 기반으로 관리자가 직접 설정할수 있는 attribute입니다.
관리자 모드 > System > Order Statuses로 가면 주문 status 리스트를 볼수있는데 status는 얼마든지 관리자가 원하는 단어/문구로 바꿀수 있으며 하나의 state을 여러개의 status로 나누어 관리할수도 있습니다.
쉽게말해 state은 마젠토 데이터베이스에서만 사용되는 attribute이고 status는 관리자가 설정하는 attribute 입니다.

하나의 state이 두가지 다른 status로 사용되는 예


마젠토에는 기본적으로 “payment_review”라는 state과 status가 있습니다.
“payment_review”는 아직 결제가 되지 않은 상태이고 단순히 손님의 지불방법을 리뷰하는 단계이며, 예를 들어 운영팀은 주문의 지불방법이 “수표”인 경우에 한해서 이 status를 사용합니다.
이것과 별개로 관리자는 사이트의 보안과 신뢰도를 높이기 위해 주문에 사용된 크레딧카드의 명의와 배송받는 사람의 정보가 연관성이 전혀 없어보일때 주문을 잠깐 홀드시키고 지불한 손님과 연락을 취해서 직접 확인해 보는 단계로 “suspected_fraud”(부정주문 의심)라는 status를 새롭게 만들고자 합니다.
새로운 status를 만든 관리자는 어차피 주문이 결제되지않은 상태이고 지불방법을 리뷰하는 상태이므로 “payment_review”라는 state과 연결시켜 놓습니다.
결국, 마젠토 내에서는 payment_review(status)나 suspected_fraud(status)나 똑같은 payment_review(state)이지만, 이렇게 다른 종류의 status를 만들어 놓으면 운영팀이 어떠한 행동을 취해야 하는지를 알수 있도록 도와줍니다.

sales_order_status_state 데이터베이스 테이블


각각의 state과 status의 연결상태를 데이터베이스에서 확인하려면 sales_order_status_state 테이블을 참고하면 알기 쉽구요, 아래는 제가 캡쳐한 데이터베이스 테이블의(Enterprise 1.14.2 기준) 내용입니다.

mysql> SELECT * FROM sales_order_status_state;
+-----------------+-----------------+------------+
| status          | state           | is_default |
+-----------------+-----------------+------------+
| canceled        | canceled        |          1 |
| closed          | closed          |          1 |
| complete        | complete        |          1 |
| fraud           | payment_review  |          0 |
| holded          | holded          |          1 |
| payment_review  | payment_review  |          1 |
| pending         | new             |          1 |
| pending_ogone   | pending_payment |          0 |
| pending_payment | pending_payment |          1 |
| processed_ogone | processing      |          0 |
| processing      | processing      |          1 |
+-----------------+-----------------+------------+
11 rows in set (0.00 sec)

마젠토 커스텀 세션

마젠토 세션의 기본적 사용방법


마젠토의 기본적인 세션 사용법은 마젠토 세션 사용법에서 간략하게 적어놓았는데요, 지금 보니 지난 몇년전에 작성한 글이라 설명이 좀 부족한듯 해서 조금더 자세한 설명과 나아가 마젠토에 기본적으로 있는 세션 말고 커스텀 세션을 만드는 방법을 설명하도록 하겠습니다.

마젠토에 있는 기본적인 세션의 종류는 Core, Customer, Admin, Checkout 이렇게 네가지 종류가 있구요, 세션을 사용하려면 아래와 같은 코드를 사용하면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Core Session
$coreSession = Mage::getSingleton('core/session');
$coreSession->setMyData('some string'); // "some string"을 "my_data"에 저장
echo $coreSession->getMyData(); // "some string"을 출력
$coreSession->setMyData(); // "my_data" 삭제

// Customer Session
$customerSession = Mage::getSingleton('customer/session');

// Adminhtml Session
$adminhtmlSession = Mage::getSingleton('adminhtml/session');

// Checkout Session
$checkoutSession = Mage::getSingleton('checkout/session');

위의 예제에서는 $coreSession에서만 get/set의 예제를 사용했는데 나머지 customer, adminhtml, checkout 세션 또한 사용법은 다르지 않습니다.

PHP 세션과 마젠토 세션의 비교


아래의 예제는 기본적인 PHP의 세션 사용법입니다.

1
2
3
session_start();
$_SESSION['my_data'] = 'some string';
echo $_SESSION['my_data']; // "some string"을 출력

이렇게 마젠토의 세션 사용방법은 PHP의 기본적인 세션 사용법과는 겉으로 달라 보이긴 해도 결과적으로는 같습니다.
core, customer, adminhtml, checkout은 단지 세션의 용도를 구분짓는 네임스페이스일 뿐, 결과적으로는 모두 $_SESSION에 저장됩니다.
아래 코드를 참고하세요.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// core 세션에 데이터 저장
$coreSession = Mage::getSingleton('core/session');
$coreSession->setMyData('some string'); // "some string"을 "my_data"에 저장

// core 세션의 데이터 출력
echo $coreSession->getMyData();

// 위의 core 세션의 출력은 아래의 php 세션의 출력과 같습니다.
echo $_SESSION['core']['my_data'];

// 마찬가지로 아래와 같이 customer 세션에 데이터를 저장했을때
$customerSession = Mage::getSingleton('customer/session');
$customerSession->setLastLoggedIn(date('Y-m-d H:i:s'));

// 아래 두개의 명령문은 같은 값을 출력합니다.
echo $customerSession->getLastLoggedIn();
echo $_SESSION['customer']['last_logged_in'];

단지 core 세션의 Mage_Core_Model_Session 모델, customer 세션의 Mage_Customer_Model_Session 모델 등등은 모두 최종적으로 Varien_Object 모델을 extend 하기 때문에 array의 형식의 $_SESSION 변수보다는 get/set/uns의 사용이 가능한 object 형식의 변수를 사용하는것 이므로 어렵게 느낄 필요는 없습니다.

커스텀 모듈의 커스텀 세션


커스텀 모듈을 개발하다보면 모듈만의 세션이 필요할때가 있습니다.
기존의 core, customer, checkout, adminhtml 세션과의 중복된 사용을 금지하기 위해서도 그렇고 기존의 세션과는 다른 세션모델을 사용하기 위해서 커스텀 세션이 필요하기도 합니다.
만약 커스텀 모듈만의 세션이 필요할때엔 간단하게 네임스페이스를 하나 더 만들면 됩니다.
커스텀 모듈내에 /app/code/local/{MyCompany}/{MyModule}/Model/Session.php 파일을 하나 작성해서 아래와 같이 $this->init(‘mymodule’); 을 __construct() 함수에 넣어주면 됩니다.
mymodule은 core, customer, checkout 같은 모듈의 이름 또는 세션을 구분하기 위한 네임스페이스 입니다.

1
2
3
4
5
6
7
class MyModule_Custom_Model_Session extends Mage_Core_Model_Session_Abstract
{
    public function __construct()
    {
        $this->init('mymodule');
    }
}

위와 같이 셋업하고 나서 실질적으로 mymodule 세션을 사용하려면 아래와 같은 형식으로 세션을 불러와서 사용할수 있습니다.

1
2
3
4
$myModuleSession = Mage::getSingleton('mymodule/session');
$myModuleSession->setMyData('some string');
echo $myModuleSession->getMyData(); // 'some string' 출력
$myModuleSession->setMyData(); // 데이터 지우기

웹프로그래밍에 있어서 세션은 상당히 널리 사용되고 있구요, 마젠토 내에서 커스텀 모듈을 개발하다보면 모듈 만의 세션이 자주 필요합니다.
그럴때엔 마젠토 기존의 core, customer, checkout, adminhtml 세션을 사용하기 보다는 위의 예제에서 처럼 커스텀 세션을 사용하는것이 훨씬 더 깔끔하고 더 나은 개발 방법입니다.