/** * shopp_add_order_event - log an order event * * @api * @since 1.2 * * @param int $order (conditionally required default:false) Will be false for purchase events, but needs the order id otherwise. * @param string $type (required) the order event type * @param array $message (optional default:array()) the event message protocol * @return bool true on success, false on error **/ function shopp_add_order_event($order = false, $type = false, $message = array()) { if (false !== $order && !shopp_order_exists($order)) { shopp_debug(__FUNCTION__ . " '{$type}' failed: Invalid order id."); return false; } if (!$type || !OrderEvent::handler($type)) { shopp_debug(__FUNCTION__ . " failed: Missing or invalid order event type"); return false; } return OrderEvent::add($order, $type, $message); }
/** * Updates a purchase order with transaction information from order events * * @author Jonathan Davis * @since 1.2 * * @param OrderEvent $Event The order event passed by the action hook * @return void **/ public static function event($Event) { $Purchase = $Event->order(); if (!$Purchase) { shopp_debug('Cannot update. No event order.'); return; } // Transaction status is the same as the event, no update needed if ($Purchase->txnstatus == $Event->name) { shopp_debug('Transaction status (' . $Purchase->txnstatus . ') for purchase order #' . $Purchase->id . ' is the same as the new event, no update necessary.'); return; } $status = false; $txnid = false; // Set transaction status from event name $txnstatus = $Event->name; if ('refunded' == $txnstatus) { // Determine if this is fully refunded (previous refunds + this refund amount) if (empty($Purchase->events)) { $Purchase->load_events(); } // Not refunded if less than captured, so don't update txnstatus if ($Purchase->refunded + $Event->amount < $Purchase->captured) { $txnstatus = false; } } if ('voided' == $txnstatus) { // Determine if the transaction has been cancelled if (empty($Purchase->events)) { $Purchase->load_events(); } if ($Purchase->captured) { $txnstatus = false; } // If previously captured, don't mark voided } if ('shipped' == $txnstatus) { $txnstatus = false; } // 'shipped' is not a valid txnstatus // Set order workflow status from status label mapping $labels = (array) shopp_setting('order_status'); $events = (array) shopp_setting('order_states'); $key = array_search($Event->name, $events); if (false !== $key && isset($labels[$key])) { $status = (int) $key; } // Set the transaction ID if available if (isset($Event->txnid) && !empty($Event->txnid)) { $txnid = $Event->txnid; } $updates = compact('txnstatus', 'txnid', 'status'); $updates = array_filter($updates); $data = sDB::escape($updates); $data = array_map(create_function('$value', 'return "\'$value\'";'), $data); $dataset = ShoppDatabaseObject::dataset($data); if (!empty($dataset)) { $table = ShoppDatabaseObject::tablename(self::$table); $query = "UPDATE {$table} SET {$dataset} WHERE id='{$Event->order}' LIMIT 1"; sDB::query($query); } $Purchase->updates($updates); return; }
/** * Callback for loading concrete OrderEventMesssage objects from a record set * * @author Jonathan Davis * @since 1.2 * * @param array $records A reference to the loaded record set * @param object $record Result record data object * @return void **/ public function loader(array &$records, &$record, $type = false, $index = 'id', $collate = false) { if ($type !== false && isset($record->{$type}) && class_exists(OrderEvent::handler($record->{$type}))) { $OrderEventClass = OrderEvent::handler($record->{$type}); } elseif (isset($this)) { if ('id' == $index) { $index = $this->_key; } $OrderEventClass = get_class($this); } $index = isset($record->{$index}) ? $record->{$index} : '!NO_INDEX!'; $Object = new $OrderEventClass(false); $Object->msgprops(); $Object->populate($record); if (method_exists($Object, 'expopulate')) { $Object->expopulate(); } if ($collate) { if (!isset($records[$index])) { $records[$index] = array(); } $records[$index][] = $Object; } else { $records[$index] = $Object; } }