MemberOrder

The Paid Memberships Pro MemberOrder class.

Defined (1)

The class is defined in the following location(s).

/classes/class.memberorder.php  
  1. class MemberOrder 
  2. /** 
  3. * Constructor 
  4. */ 
  5. function __construct($id = NULL) 
  6. //set up the gateway 
  7. $this->setGateway(pmpro_getOption("gateway")); 
  8.  
  9. //get data if an id was passed 
  10. if($id) 
  11. if(is_numeric($id)) 
  12. return $this->getMemberOrderByID($id); 
  13. else 
  14. return $this->getMemberOrderByCode($id); 
  15. else 
  16. return $this->getEmptyMemberOrder(); //blank constructor 
  17.  
  18. /** 
  19. * Returns an empty (but complete) order object. 
  20. * @return stdClass $order - a 'clean' order object 
  21. * @since: 1.8.6.8 
  22. */ 
  23. function getEmptyMemberOrder() 
  24.  
  25. //defaults 
  26. $order = new stdClass(); 
  27. $order->code = $this->getRandomCode(); 
  28. $order->user_id = ""; 
  29. $order->membership_id = ""; 
  30. $order->subtotal = ""; 
  31. $order->tax = ""; 
  32. $order->couponamount = ""; 
  33. $order->total = ""; 
  34. $order->payment_type = ""; 
  35. $order->cardtype = ""; 
  36. $order->accountnumber = ""; 
  37. $order->expirationmonth = ""; 
  38. $order->expirationyear = ""; 
  39. $order->status = "success"; 
  40. $order->gateway = pmpro_getOption("gateway"); 
  41. $order->gateway_environment = pmpro_getOption("gateway_environment"); 
  42. $order->payment_transaction_id = ""; 
  43. $order->subscription_transaction_id = ""; 
  44. $order->affiliate_id = ""; 
  45. $order->affiliate_subid = ""; 
  46. $order->notes = ""; 
  47. $order->checkout_id = 0; 
  48.  
  49. $order->billing = new stdClass(); 
  50. $order->billing->name = ""; 
  51. $order->billing->street = ""; 
  52. $order->billing->city = ""; 
  53. $order->billing->state = ""; 
  54. $order->billing->zip = ""; 
  55. $order->billing->country = ""; 
  56. $order->billing->phone = ""; 
  57.  
  58. return $order; 
  59.  
  60. /** 
  61. * Retrieve a member order from the DB by ID 
  62. */ 
  63. function getMemberOrderByID($id) 
  64. global $wpdb; 
  65.  
  66. if(!$id) 
  67. return false; 
  68.  
  69. $gmt_offset = get_option('gmt_offset'); 
  70. $dbobj = $wpdb->get_row("SELECT *, UNIX_TIMESTAMP(timestamp) + " . ($gmt_offset * 3600) . " as timestamp FROM $wpdb->pmpro_membership_orders WHERE id = '$id' LIMIT 1"); 
  71.  
  72. if($dbobj) 
  73. $this->id = $dbobj->id; 
  74. $this->code = $dbobj->code; 
  75. $this->session_id = $dbobj->session_id; 
  76. $this->user_id = $dbobj->user_id; 
  77. $this->membership_id = $dbobj->membership_id; 
  78. $this->paypal_token = $dbobj->paypal_token; 
  79. $this->billing = new stdClass(); 
  80. $this->billing->name = $dbobj->billing_name; 
  81. $this->billing->street = $dbobj->billing_street; 
  82. $this->billing->city = $dbobj->billing_city; 
  83. $this->billing->state = $dbobj->billing_state; 
  84. $this->billing->zip = $dbobj->billing_zip; 
  85. $this->billing->country = $dbobj->billing_country; 
  86. $this->billing->phone = $dbobj->billing_phone; 
  87.  
  88. //split up some values 
  89. $nameparts = pnp_split_full_name($this->billing->name); 
  90.  
  91. if(!empty($nameparts['fname'])) 
  92. $this->FirstName = $nameparts['fname']; 
  93. else 
  94. $this->FirstName = ""; 
  95. if(!empty($nameparts['lname'])) 
  96. $this->LastName = $nameparts['lname']; 
  97. else 
  98. $this->LastName = ""; 
  99.  
  100. $this->Address1 = $this->billing->street; 
  101.  
  102. //get email from user_id 
  103. $this->Email = $wpdb->get_var("SELECT user_email FROM $wpdb->users WHERE ID = '" . $this->user_id . "' LIMIT 1"); 
  104.  
  105. $this->subtotal = $dbobj->subtotal; 
  106. $this->tax = $dbobj->tax; 
  107. $this->couponamount = $dbobj->couponamount; 
  108. $this->certificate_id = $dbobj->certificate_id; 
  109. $this->certificateamount = $dbobj->certificateamount; 
  110. $this->total = $dbobj->total; 
  111. $this->payment_type = $dbobj->payment_type; 
  112. $this->cardtype = $dbobj->cardtype; 
  113. $this->accountnumber = trim($dbobj->accountnumber); 
  114. $this->expirationmonth = $dbobj->expirationmonth; 
  115. $this->expirationyear = $dbobj->expirationyear; 
  116.  
  117. //date formats sometimes useful 
  118. $this->ExpirationDate = $this->expirationmonth . $this->expirationyear; 
  119. $this->ExpirationDate_YdashM = $this->expirationyear . "-" . $this->expirationmonth; 
  120.  
  121. $this->status = $dbobj->status; 
  122. $this->gateway = $dbobj->gateway; 
  123. $this->gateway_environment = $dbobj->gateway_environment; 
  124. $this->payment_transaction_id = $dbobj->payment_transaction_id; 
  125. $this->subscription_transaction_id = $dbobj->subscription_transaction_id; 
  126. $this->timestamp = $dbobj->timestamp; 
  127. $this->affiliate_id = $dbobj->affiliate_id; 
  128. $this->affiliate_subid = $dbobj->affiliate_subid; 
  129.  
  130. $this->notes = $dbobj->notes; 
  131. $this->checkout_id = $dbobj->checkout_id; 
  132.  
  133. //reset the gateway 
  134. if(empty($this->nogateway)) 
  135. $this->setGateway(); 
  136.  
  137. return $this->id; 
  138. else 
  139. return false; //didn't find it in the DB 
  140.  
  141. /** 
  142. * Set up the Gateway class to use with this order. 
  143. * @param string $gateway Name/label for the gateway to set. 
  144. */ 
  145. function setGateway($gateway = NULL) { 
  146. //set the gateway property 
  147. if(isset($gateway)) { 
  148. $this->gateway = $gateway; 
  149.  
  150. //which one to load? 
  151. $classname = "PMProGateway"; //default test gateway 
  152. if(!empty($this->gateway) && $this->gateway != "free") { 
  153. $classname .= "_" . $this->gateway; //adding the gateway suffix 
  154.  
  155. if(class_exists($classname) && isset($this->gateway)) { 
  156. $this->Gateway = new $classname($this->gateway); 
  157. } else { 
  158. $this->Gateway = null; //null out any current gateway 
  159. $error = new WP_Error("PMPro1001", "Could not locate the gateway class file with class name = " . $classname . "."); 
  160.  
  161. if(!empty($this->Gateway)) { 
  162. return $this->Gateway; 
  163. } else { 
  164. //gateway wasn't setup 
  165. return false; 
  166.  
  167. /** 
  168. * Get the most recent order for a user. 
  169. * @param int $user_id ID of user to find order for. 
  170. * @param string $status Limit search to only orders with this status. Defaults to "success". 
  171. * @param int $membership_id Limit search to only orders for this membership level. Defaults to NULL to find orders for any level. 
  172. * @return MemberOrder 
  173. */ 
  174. function getLastMemberOrder($user_id = NULL, $status = 'success', $membership_id = NULL, $gateway = NULL, $gateway_environment = NULL) 
  175. global $current_user, $wpdb; 
  176. if(!$user_id) 
  177. $user_id = $current_user->ID; 
  178.  
  179. if(!$user_id) 
  180. return false; 
  181.  
  182. //build query 
  183. $this->sqlQuery = "SELECT id FROM $wpdb->pmpro_membership_orders WHERE user_id = '" . $user_id . "' "; 
  184. if(!empty($status) && is_array($status)) 
  185. $this->sqlQuery .= "AND status IN('" . implode("', '", $status) . "') "; 
  186. elseif(!empty($status)) 
  187. $this->sqlQuery .= "AND status = '" . esc_sql($status) . "' "; 
  188.  
  189. if(!empty($membership_id)) 
  190. $this->sqlQuery .= "AND membership_id = '" . $membership_id . "' "; 
  191.  
  192. if(!empty($gateway)) 
  193. $this->sqlQuery .= "AND gateway = '" . esc_sql($gateway) . "' "; 
  194.  
  195. if(!empty($gateway_environment)) 
  196. $this->sqlQuery .= "AND gateway_environment = '" . esc_sql($gateway_environment) . "' "; 
  197.  
  198. $this->sqlQuery .= "ORDER BY timestamp DESC LIMIT 1"; 
  199.  
  200. //get id 
  201. $id = $wpdb->get_var($this->sqlQuery); 
  202.  
  203. return $this->getMemberOrderByID($id); 
  204.  
  205. /** 
  206. Returns the order using the given order code. 
  207. */ 
  208. function getMemberOrderByCode($code) 
  209. global $wpdb; 
  210. $id = $wpdb->get_var("SELECT id FROM $wpdb->pmpro_membership_orders WHERE code = '" . $code . "' LIMIT 1"); 
  211. if($id) 
  212. return $this->getMemberOrderByID($id); 
  213. else 
  214. return false; 
  215.  
  216. /** 
  217. Returns the last order using the given payment_transaction_id. 
  218. */ 
  219. function getMemberOrderByPaymentTransactionID($payment_transaction_id) 
  220. //did they pass a trans id? 
  221. if(empty($payment_transaction_id)) 
  222. return false; 
  223.  
  224. global $wpdb; 
  225. $id = $wpdb->get_var("SELECT id FROM $wpdb->pmpro_membership_orders WHERE payment_transaction_id = '" . esc_sql($payment_transaction_id) . "' LIMIT 1"); 
  226. if($id) 
  227. return $this->getMemberOrderByID($id); 
  228. else 
  229. return false; 
  230.  
  231. /** 
  232. * Returns the last order using the given subscription_transaction_id. 
  233. */ 
  234. function getLastMemberOrderBySubscriptionTransactionID($subscription_transaction_id) 
  235. //did they pass a sub id? 
  236. if(empty($subscription_transaction_id)) 
  237. return false; 
  238.  
  239. global $wpdb; 
  240. $id = $wpdb->get_var("SELECT id FROM $wpdb->pmpro_membership_orders WHERE subscription_transaction_id = '" . esc_sql($subscription_transaction_id) . "' ORDER BY id DESC LIMIT 1"); 
  241.  
  242. if($id) 
  243. return $this->getMemberOrderByID($id); 
  244. else 
  245. return false; 
  246.  
  247. /** 
  248. * Returns the last order using the given paypal token. 
  249. */ 
  250. function getMemberOrderByPayPalToken($token) 
  251. global $wpdb; 
  252. $id = $wpdb->get_var("SELECT id FROM $wpdb->pmpro_membership_orders WHERE paypal_token = '" . $token . "' LIMIT 1"); 
  253. if($id) 
  254. return $this->getMemberOrderByID($id); 
  255. else 
  256. return false; 
  257.  
  258. /** 
  259. * Get a discount code object for the code used in this order. 
  260. * @param bool $force If true, it will query the database again. 
  261. */ 
  262. function getDiscountCode($force = false) 
  263. if(!empty($this->discount_code) && !$force) 
  264. return $this->discount_code; 
  265.  
  266. global $wpdb; 
  267. $this->discount_code = $wpdb->get_row("SELECT dc.* FROM $wpdb->pmpro_discount_codes dc LEFT JOIN $wpdb->pmpro_discount_codes_uses dcu ON dc.id = dcu.code_id WHERE dcu.order_id = '" . $this->id . "' LIMIT 1"); 
  268.  
  269. //filter @since v1.7.14 
  270. $this->discount_code = apply_filters("pmpro_order_discount_code", $this->discount_code, $this); 
  271.  
  272. return $this->discount_code; 
  273.  
  274. /** 
  275. * Get a user object for the user associated with this order. 
  276. */ 
  277. function getUser() 
  278. global $wpdb; 
  279.  
  280. if(!empty($this->user)) 
  281. return $this->user; 
  282.  
  283. $gmt_offset = get_option('gmt_offset'); 
  284. $this->user = $wpdb->get_row("SELECT *, UNIX_TIMESTAMP(user_registered) + " . ($gmt_offset * 3600) . " as user_registered FROM $wpdb->users WHERE ID = '" . $this->user_id . "' LIMIT 1"); 
  285. return $this->user; 
  286.  
  287. /** 
  288. * Get a membership level object for the level associated with this order. 
  289. * @param bool $force If true, it will query the database again. 
  290. */ 
  291. function getMembershipLevel($force = false) 
  292. global $wpdb; 
  293.  
  294. if(!empty($this->membership_level) && empty($force)) 
  295. return $this->membership_level; 
  296.  
  297. //check if there is an entry in memberships_users first 
  298. if(!empty($this->user_id)) 
  299. $this->membership_level = $wpdb->get_row("SELECT l.id as level_id, l.name, l.description, l.allow_signups, l.expiration_number, l.expiration_period, mu.*, UNIX_TIMESTAMP(mu.startdate) as startdate, UNIX_TIMESTAMP(mu.enddate) as enddate, l.name, l.description, l.allow_signups FROM $wpdb->pmpro_membership_levels l LEFT JOIN $wpdb->pmpro_memberships_users mu ON l.id = mu.membership_id WHERE mu.status = 'active' AND l.id = '" . $this->membership_id . "' AND mu.user_id = '" . $this->user_id . "' LIMIT 1"); 
  300.  
  301. //fix the membership level id 
  302. if(!empty($this->membership_level->level_id)) 
  303. $this->membership_level->id = $this->membership_level->level_id; 
  304.  
  305. //okay, do I have a discount code to check? (if there is no membership_level->membership_id value, that means there was no entry in memberships_users) 
  306. if(!empty($this->discount_code) && empty($this->membership_level->membership_id)) 
  307. if(!empty($this->discount_code->code)) 
  308. $discount_code = $this->discount_code->code; 
  309. else 
  310. $discount_code = $this->discount_code; 
  311.  
  312. $sqlQuery = "SELECT l.id, cl.*, l.name, l.description, l.allow_signups FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id LEFT JOIN $wpdb->pmpro_discount_codes dc ON dc.id = cl.code_id WHERE dc.code = '" . $discount_code . "' AND cl.level_id = '" . $this->membership_id . "' LIMIT 1"; 
  313.  
  314. $this->membership_level = $wpdb->get_row($sqlQuery); 
  315.  
  316. //just get the info from the membership table (sigh, I really need to standardize the column names for membership_id/level_id) but we're checking if we got the information already or not 
  317. if(empty($this->membership_level->membership_id) && empty($this->membership_level->level_id)) 
  318. $this->membership_level = $wpdb->get_row("SELECT l.* FROM $wpdb->pmpro_membership_levels l WHERE l.id = '" . $this->membership_id . "' LIMIT 1"); 
  319.  
  320. return $this->membership_level; 
  321.  
  322. /** 
  323. * Apply tax rules for the price given. 
  324. */ 
  325. function getTaxForPrice($price) 
  326. //get options 
  327. $tax_state = pmpro_getOption("tax_state"); 
  328. $tax_rate = pmpro_getOption("tax_rate"); 
  329.  
  330. //default 
  331. $tax = 0; 
  332.  
  333. //calculate tax 
  334. if($tax_state && $tax_rate) 
  335. //we have values, is this order in the tax state? 
  336. if(!empty($this->billing) && trim(strtoupper($this->billing->state)) == trim(strtoupper($tax_state))) 
  337. //return value, pass through filter 
  338. $tax = round((float)$price * (float)$tax_rate, 2); 
  339.  
  340. //set values array for filter 
  341. $values = array("price" => $price, "tax_state" => $tax_state, "tax_rate" => $tax_rate); 
  342. if(!empty($this->billing->state)) 
  343. $values['billing_state'] = $this->billing->state; 
  344. if(!empty($this->billing->city)) 
  345. $values['billing_city'] = $this->billing->city; 
  346. if(!empty($this->billing->zip)) 
  347. $values['billing_zip'] = $this->billing->zip; 
  348. if(!empty($this->billing->country)) 
  349. $values['billing_country'] = $this->billing->country; 
  350.  
  351. //filter 
  352. $tax = apply_filters("pmpro_tax", $tax, $values, $this); 
  353. return $tax; 
  354.  
  355. /** 
  356. * Get the tax amount for this order. 
  357. */ 
  358. function getTax($force = false) 
  359. if(!empty($this->tax) && !$force) 
  360. return $this->tax; 
  361.  
  362. //reset 
  363. $this->tax = $this->getTaxForPrice($this->subtotal); 
  364.  
  365. return $this->tax; 
  366.  
  367. /** 
  368. * Change the timestamp of an order by passing in year, month, day, time 
  369. */ 
  370. function updateTimestamp($year, $month, $day, $time = NULL) 
  371. if(empty($this->id)) 
  372. return false; //need a saved order 
  373.  
  374. if(empty($time)) 
  375. $time = "00:00:00"; 
  376.  
  377. $date = $year . "-" . $month . "-" . $day . " " . $time; 
  378.  
  379. global $wpdb; 
  380. $this->sqlQuery = "UPDATE $wpdb->pmpro_membership_orders SET timestamp = '" . $date . "' WHERE id = '" . $this->id . "' LIMIT 1"; 
  381.  
  382. if($wpdb->query($this->sqlQuery) !== "false") 
  383. return $this->getMemberOrderByID($this->id); 
  384. else 
  385. return false; 
  386.  
  387. /** 
  388. * Save/update the values of the order in the database. 
  389. */ 
  390. function saveOrder() 
  391. global $current_user, $wpdb, $pmpro_checkout_id; 
  392.  
  393. //get a random code to use for the public ID 
  394. if(empty($this->code)) 
  395. $this->code = $this->getRandomCode(); 
  396.  
  397. //figure out how much we charged 
  398. if(!empty($this->InitialPayment)) 
  399. $amount = $this->InitialPayment; 
  400. elseif(!empty($this->subtotal)) 
  401. $amount = $this->subtotal; 
  402. else 
  403. $amount = 0; 
  404.  
  405. //Todo: Tax?!, Coupons, Certificates, affiliates 
  406. if(empty($this->subtotal)) 
  407. $this->subtotal = $amount; 
  408. if(isset($this->tax)) 
  409. $tax = $this->tax; 
  410. else 
  411. $tax = $this->getTax(true); 
  412. $this->certificate_id = ""; 
  413. $this->certificateamount = ""; 
  414.  
  415. //calculate total 
  416. if(!empty($this->total)) 
  417. $total = $this->total; 
  418. else { 
  419. $total = (float)$amount + (float)$tax; 
  420. $this->total = $total; 
  421.  
  422. //these fix some warnings/notices 
  423. if(empty($this->billing)) 
  424. $this->billing = new stdClass(); 
  425. $this->billing->name = $this->billing->street = $this->billing->city = $this->billing->state = $this->billing->zip = $this->billing->country = $this->billing->phone = ""; 
  426. if(empty($this->user_id)) 
  427. $this->user_id = 0; 
  428. if(empty($this->paypal_token)) 
  429. $this->paypal_token = ""; 
  430. if(empty($this->couponamount)) 
  431. $this->couponamount = ""; 
  432. if(empty($this->payment_type)) 
  433. $this->payment_type = ""; 
  434. if(empty($this->payment_transaction_id)) 
  435. $this->payment_transaction_id = ""; 
  436. if(empty($this->subscription_transaction_id)) 
  437. $this->subscription_transaction_id = ""; 
  438. if(empty($this->affiliate_id)) 
  439. $this->affiliate_id = ""; 
  440. if(empty($this->affiliate_subid)) 
  441. $this->affiliate_subid = ""; 
  442. if(empty($this->session_id)) 
  443. $this->session_id = ""; 
  444. if(empty($this->accountnumber)) 
  445. $this->accountnumber = ""; 
  446. if(empty($this->cardtype)) 
  447. $this->cardtype = ""; 
  448. if(empty($this->ExpirationDate)) 
  449. $this->ExpirationDate = ""; 
  450. if (empty($this->status)) 
  451. $this->status = ""; 
  452.  
  453. if(empty($this->gateway)) 
  454. $this->gateway = pmpro_getOption("gateway"); 
  455. if(empty($this->gateway_environment)) 
  456. $this->gateway_environment = pmpro_getOption("gateway_environment"); 
  457.  
  458. if(empty($this->datetime) && empty($this->timestamp)) 
  459. $this->datetime = date_i18n("Y-m-d H:i:s", current_time("timestamp")); //use current time 
  460. elseif(empty($this->datetime) && !empty($this->timestamp) && is_numeric($this->timestamp)) 
  461. $this->datetime = date_i18n("Y-m-d H:i:s", $this->timestamp); //get datetime from timestamp 
  462. elseif(empty($this->datetime) && !empty($this->timestamp)) 
  463. $this->datetime = $this->timestamp; //must have a datetime in it 
  464.  
  465. if(empty($this->notes)) 
  466. $this->notes = ""; 
  467.  
  468. if(empty($this->checkout_id) || intval($this->checkout_id)<1) { 
  469. $highestval = $wpdb->get_var("SELECT MAX(checkout_id) FROM $wpdb->pmpro_membership_orders"); 
  470. $this->checkout_id = intval($highestval)+1; 
  471. $pmpro_checkout_id = $this->checkout_id; 
  472.  
  473. //build query 
  474. if(!empty($this->id)) 
  475. //set up actions 
  476. $before_action = "pmpro_update_order"; 
  477. $after_action = "pmpro_updated_order"; 
  478. //update 
  479. $this->sqlQuery = "UPDATE $wpdb->pmpro_membership_orders 
  480. SET `code` = '" . $this->code . "',  
  481. `session_id` = '" . $this->session_id . "',  
  482. `user_id` = " . intval($this->user_id) . ",  
  483. `membership_id` = " . intval($this->membership_id) . ",  
  484. `paypal_token` = '" . $this->paypal_token . "',  
  485. `billing_name` = '" . esc_sql($this->billing->name) . "',  
  486. `billing_street` = '" . esc_sql($this->billing->street) . "',  
  487. `billing_city` = '" . esc_sql($this->billing->city) . "',  
  488. `billing_state` = '" . esc_sql($this->billing->state) . "',  
  489. `billing_zip` = '" . esc_sql($this->billing->zip) . "',  
  490. `billing_country` = '" . esc_sql($this->billing->country) . "',  
  491. `billing_phone` = '" . esc_sql($this->billing->phone) . "',  
  492. `subtotal` = '" . $this->subtotal . "',  
  493. `tax` = '" . $this->tax . "',  
  494. `couponamount` = '" . $this->couponamount . "',  
  495. `certificate_id` = " . intval($this->certificate_id) . ",  
  496. `certificateamount` = '" . $this->certificateamount . "',  
  497. `total` = '" . $this->total . "',  
  498. `payment_type` = '" . $this->payment_type . "',  
  499. `cardtype` = '" . $this->cardtype . "',  
  500. `accountnumber` = '" . $this->accountnumber . "',  
  501. `expirationmonth` = '" . $this->expirationmonth . "',  
  502. `expirationyear` = '" . $this->expirationyear . "',  
  503. `status` = '" . esc_sql($this->status) . "',  
  504. `gateway` = '" . $this->gateway . "',  
  505. `gateway_environment` = '" . $this->gateway_environment . "',  
  506. `payment_transaction_id` = '" . esc_sql($this->payment_transaction_id) . "',  
  507. `subscription_transaction_id` = '" . esc_sql($this->subscription_transaction_id) . "',  
  508. `timestamp` = '" . esc_sql($this->datetime) . "',  
  509. `affiliate_id` = '" . esc_sql($this->affiliate_id) . "',  
  510. `affiliate_subid` = '" . esc_sql($this->affiliate_subid) . "',  
  511. `notes` = '" . esc_sql($this->notes) . "',  
  512. `checkout_id` = " . intval($this->checkout_id) . " 
  513. WHERE id = '" . $this->id . "' 
  514. LIMIT 1"; 
  515. else 
  516. //set up actions 
  517. $before_action = "pmpro_add_order"; 
  518. $after_action = "pmpro_added_order"; 
  519. //insert 
  520. $this->sqlQuery = "INSERT INTO $wpdb->pmpro_membership_orders 
  521. (`code`, `session_id`, `user_id`, `membership_id`, `paypal_token`, `billing_name`, `billing_street`, `billing_city`, `billing_state`, `billing_zip`, `billing_country`, `billing_phone`, `subtotal`, `tax`, `couponamount`, `certificate_id`, `certificateamount`, `total`, `payment_type`, `cardtype`, `accountnumber`, `expirationmonth`, `expirationyear`, `status`, `gateway`, `gateway_environment`, `payment_transaction_id`, `subscription_transaction_id`, `timestamp`, `affiliate_id`, `affiliate_subid`, `notes`, `checkout_id`) 
  522. VALUES('" . $this->code . "',  
  523. '" . session_id() . "',  
  524. " . intval($this->user_id) . ",  
  525. " . intval($this->membership_id) . ",  
  526. '" . $this->paypal_token . "',  
  527. '" . esc_sql(trim($this->billing->name)) . "',  
  528. '" . esc_sql(trim($this->billing->street)) . "',  
  529. '" . esc_sql($this->billing->city) . "',  
  530. '" . esc_sql($this->billing->state) . "',  
  531. '" . esc_sql($this->billing->zip) . "',  
  532. '" . esc_sql($this->billing->country) . "',  
  533. '" . cleanPhone($this->billing->phone) . "',  
  534. '" . $this->subtotal . "',  
  535. '" . $tax . "',  
  536. '" . $this->couponamount. "',  
  537. " . intval($this->certificate_id) . ",  
  538. '" . $this->certificateamount . "',  
  539. '" . $total . "',  
  540. '" . $this->payment_type . "',  
  541. '" . $this->cardtype . "',  
  542. '" . hideCardNumber($this->accountnumber, false) . "',  
  543. '" . substr($this->ExpirationDate, 0, 2) . "',  
  544. '" . substr($this->ExpirationDate, 2, 4) . "',  
  545. '" . esc_sql($this->status) . "',  
  546. '" . $this->gateway . "',  
  547. '" . $this->gateway_environment . "',  
  548. '" . esc_sql($this->payment_transaction_id) . "',  
  549. '" . esc_sql($this->subscription_transaction_id) . "',  
  550. '" . esc_sql($this->datetime) . "',  
  551. '" . esc_sql($this->affiliate_id) . "',  
  552. '" . esc_sql($this->affiliate_subid) . "',  
  553. '" . esc_sql($this->notes) . "',  
  554. " . intval($this->checkout_id) . " 
  555. )"; 
  556.  
  557. do_action($before_action, $this); 
  558. if($wpdb->query($this->sqlQuery) !== false) 
  559. if(empty($this->id)) 
  560. $this->id = $wpdb->insert_id; 
  561. do_action($after_action, $this); 
  562. return $this->getMemberOrderByID($this->id); 
  563. else 
  564. return false; 
  565.  
  566. /** 
  567. * Get a random code to use as the order code. 
  568. */ 
  569. function getRandomCode() 
  570. global $wpdb; 
  571.  
  572. while(empty($code)) 
  573.  
  574. $scramble = md5(AUTH_KEY . current_time('timestamp') . SECURE_AUTH_KEY); 
  575. $code = substr($scramble, 0, 10); 
  576. $code = apply_filters("pmpro_random_code", $code, $this); //filter 
  577. $check = $wpdb->get_var("SELECT id FROM $wpdb->pmpro_membership_orders WHERE code = '$code' LIMIT 1"); 
  578. if($check || is_numeric($code)) 
  579. $code = NULL; 
  580.  
  581. return strtoupper($code); 
  582.  
  583. /** 
  584. * Update the status of the order in the database. 
  585. */ 
  586. function updateStatus($newstatus) 
  587. global $wpdb; 
  588.  
  589. if(empty($this->id)) 
  590. return false; 
  591.  
  592. $this->status = $newstatus; 
  593. $this->sqlQuery = "UPDATE $wpdb->pmpro_membership_orders SET status = '" . esc_sql($newstatus) . "' WHERE id = '" . $this->id . "' LIMIT 1"; 
  594. if($wpdb->query($this->sqlQuery) !== false) 
  595. return true; 
  596. else 
  597. return false; 
  598.  
  599. /** 
  600. * Call the process step of the gateway class. 
  601. */ 
  602. function process() 
  603. if (is_object($this->Gateway)) { 
  604. return $this->Gateway->process($this); 
  605.  
  606. /** 
  607. * For offsite gateways with a confirm step. 
  608. * @since 1.8 
  609. */ 
  610. function confirm() 
  611. if (is_object($this->Gateway)) { 
  612. return $this->Gateway->confirm($this); 
  613.  
  614. /** 
  615. * Cancel an order and call the cancel step of the gateway class if needed. 
  616. */ 
  617. function cancel() 
  618. //only need to cancel on the gateway if there is a subscription id 
  619. if(empty($this->subscription_transaction_id)) 
  620. //just mark as cancelled 
  621. $this->updateStatus("cancelled"); 
  622. return true; 
  623. else 
  624. //cancel the gateway subscription first 
  625. if (is_object($this->Gateway)) { 
  626. $result = $this->Gateway->cancel( $this ); 
  627. } else { 
  628. $result = false; 
  629.  
  630. if($result == false) 
  631. //there was an error, but cancel the order no matter what 
  632. $this->updateStatus("cancelled"); 
  633.  
  634. //we should probably notify the admin 
  635. $pmproemail = new PMProEmail(); 
  636. $pmproemail->template = "subscription_cancel_error"; 
  637. $pmproemail->data = array("body"=>"<p>" . sprintf(__("There was an error canceling the subscription for user with ID=%s. You will want to check your payment gateway to see if their subscription is still active.", 'paid-memberships-pro' ), strval($this->user_id)) . "</p><p>Error: " . $this->error . "</p>"); 
  638. $pmproemail->data["body"] .= "<p>Associated Order:<br />" . nl2br(var_export($this, true)) . "</p>"; 
  639. $pmproemail->sendEmail(get_bloginfo("admin_email")); 
  640.  
  641. return false; 
  642. else 
  643. //Note: status would have been set to cancelled by the gateway class. So we don't have to update it here. 
  644.  
  645. //remove billing numbers in pmpro_memberships_users if the membership is still active 
  646. global $wpdb; 
  647. $sqlQuery = "UPDATE $wpdb->pmpro_memberships_users SET initial_payment = 0, billing_amount = 0, cycle_number = 0 WHERE user_id = '" . $this->user_id . "' AND membership_id = '" . $this->membership_id . "' AND status = 'active'"; 
  648. $wpdb->query($sqlQuery); 
  649.  
  650. return $result; 
  651.  
  652. /** 
  653. * Call the update method of the gateway class. 
  654. */ 
  655. function updateBilling() 
  656. if (is_object($this->Gateway)) { 
  657. return $this->Gateway->update( $this ); 
  658.  
  659. /** 
  660. * Call the getSubscriptionStatus method of the gateway class. 
  661. */ 
  662. function getGatewaySubscriptionStatus() 
  663. if (is_object($this->Gateway)) { 
  664. return $this->Gateway->getSubscriptionStatus( $this ); 
  665.  
  666. /** 
  667. * Call the getTransactionStatus method of the gateway class. 
  668. */ 
  669. function getGatewayTransactionStatus() 
  670. if (is_object($this->Gateway)) { 
  671. return $this->Gateway->getTransactionStatus( $this ); 
  672.  
  673. /** 
  674. * Delete an order and associated data. 
  675. */ 
  676. function deleteMe() 
  677. if(empty($this->id)) 
  678. return false; 
  679.  
  680. global $wpdb; 
  681. $this->sqlQuery = "DELETE FROM $wpdb->pmpro_membership_orders WHERE id = '" . $this->id . "' LIMIT 1"; 
  682. if($wpdb->query($this->sqlQuery) !== false) 
  683. do_action("pmpro_delete_order", $this->id, $this); 
  684. return true; 
  685. else 
  686. return false;