1 | <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) exit('No direct script access allowed'); |
||
41 | class EEM_Line_Item extends EEM_Base { |
||
42 | |||
43 | /** |
||
44 | * Tax sub-total is just the total of all the taxes, which should be children |
||
45 | * of this line item. There should only ever be one tax sub-total, and it should |
||
46 | * be a direct child of |
||
47 | */ |
||
48 | const type_tax_sub_total = 'tax-sub-total'; |
||
49 | |||
50 | /** |
||
51 | * Tax line items indicate a tax applied to all the taxable line items. |
||
52 | * Should not have any children line items. |
||
53 | */ |
||
54 | const type_tax = 'tax'; |
||
55 | |||
56 | /** |
||
57 | * Indicating individual items purchased, or discounts or surcharges. |
||
58 | * The sum of all the regular line items plus the tax items should equal |
||
59 | * the grand total. |
||
60 | * Possible children fo sub-line-items and cancellations. |
||
61 | */ |
||
62 | const type_line_item = 'line-item'; |
||
63 | |||
64 | /** |
||
65 | * line item indicating all the factors that make a single line item. |
||
66 | * Sub-line items should have NO children line items. |
||
67 | */ |
||
68 | const type_sub_line_item = 'sub-item'; |
||
69 | |||
70 | /** |
||
71 | * line item indicating a sub-total (eg total for an event, or before taxes). |
||
72 | * Direct children can be line items and other sub-totals |
||
73 | * |
||
74 | */ |
||
75 | const type_sub_total = 'sub-total'; |
||
76 | |||
77 | /** |
||
78 | * line item for teh grand total of an order. Its direct children |
||
79 | * should be tax subtotals and subtotals, and possibly a regular line item |
||
80 | * indicating a transaction-wide discount/surcharge |
||
81 | */ |
||
82 | const type_total = 'total'; |
||
83 | |||
84 | /** |
||
85 | * When a line item is cancelled, a sub-line-item of type 'cancellation' |
||
86 | * should be created, indicating the quantity that were cancelled |
||
87 | * (because a line item could have a quantity of 4, and its cancellation item |
||
88 | * could be for 3, indicating that there is still 1 item purchased). |
||
89 | * When items are refunded, a cancellation line item should be made, which points |
||
90 | * to teh payment model object which actually refunded the payment. |
||
91 | * Cancellations should NOT have any children line items. |
||
92 | */ |
||
93 | const type_cancellation = 'cancellation'; |
||
94 | |||
95 | // private instance of the EEM_Line_Item object |
||
96 | protected static $_instance = NULL; |
||
97 | |||
98 | |||
99 | /** |
||
100 | * private constructor to prevent direct creation |
||
101 | * @Constructor |
||
102 | * @access protected |
||
103 | * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any incoming timezone data that gets saved). Note this just sends the timezone info to the date time model field objects. Default is NULL (and will be assumed using the set timezone in the 'timezone_string' wp option) |
||
104 | * @return \EEM_Line_Item |
||
|
|||
105 | */ |
||
106 | protected function __construct( $timezone ) { |
||
107 | $this->singular_item = __('Line Item','event_espresso'); |
||
108 | $this->plural_item = __('Line Items','event_espresso'); |
||
109 | |||
110 | $this->_tables = array( |
||
111 | 'Line_Item'=>new EE_Primary_Table('esp_line_item','LIN_ID') |
||
112 | ); |
||
113 | $line_items_can_be_for = apply_filters( 'FHEE__EEM_Line_Item__line_items_can_be_for', array('Ticket','Price', 'Event' ) ); |
||
114 | $this->_fields = array( |
||
115 | 'Line_Item' => array( |
||
116 | 'LIN_ID' => new EE_Primary_Key_Int_Field( 'LIN_ID', __( "ID", "event_espresso" ) ), |
||
117 | 'LIN_code' => new EE_Slug_Field( 'LIN_code', __( "Code for index into Cart", "event_espresso" ), TRUE ), |
||
118 | 'TXN_ID' => new EE_Foreign_Key_Int_Field( 'TXN_ID', __( "Transaction ID", "event_espresso" ), TRUE, NULL, 'Transaction' ), |
||
119 | 'LIN_name' => new EE_Full_HTML_Field( 'LIN_name', __( "Line Item Name", "event_espresso" ), FALSE, '' ), |
||
120 | 'LIN_desc' => new EE_Full_HTML_Field( 'LIN_desc', __( "Line Item Description", "event_espresso" ), TRUE ), |
||
121 | 'LIN_unit_price' => new EE_Money_Field( 'LIN_unit_price', __( "Unit Price", "event_espresso" ), FALSE, 0 ), |
||
122 | 'LIN_percent' => new EE_Float_Field( 'LIN_percent', __( "Percent", "event_espresso" ), FALSE, 0 ), |
||
123 | 'LIN_is_taxable' => new EE_Boolean_Field( 'LIN_is_taxable', __( "Taxable", "event_espresso" ), FALSE, FALSE ), |
||
124 | 'LIN_order' => new EE_Integer_Field( 'LIN_order', __( "Order of Application towards total of parent", "event_espresso" ), FALSE, 1 ), |
||
125 | 'LIN_total' => new EE_Money_Field( 'LIN_total', __( "Total (unit price x quantity)", "event_espresso" ), FALSE, 0 ), |
||
126 | 'LIN_quantity' => new EE_Integer_Field( 'LIN_quantity', __( "Quantity", "event_espresso" ), TRUE, 1 ), |
||
127 | 'LIN_parent' => new EE_Integer_Field( 'LIN_parent', __( "Parent ID (this item goes towards that Line Item's total)", "event_espresso" ), TRUE, NULL ), |
||
128 | 'LIN_type' => new EE_Enum_Text_Field( 'LIN_type', __( "Type", "event_espresso" ), FALSE, 'line-item', array( |
||
129 | self::type_line_item => __("Line Item", "event_espresso"), |
||
130 | self::type_sub_line_item => __("Sub-Item", "event_espresso"), |
||
131 | self::type_sub_total => __("Subtotal", "event_espresso"), |
||
132 | self::type_tax_sub_total => __("Tax Subtotal", "event_espresso"), |
||
133 | self::type_tax => __("Tax", "event_espresso"), |
||
134 | self::type_total => __("Total", "event_espresso"), |
||
135 | self::type_cancellation => __( 'Cancellation', 'event_espresso' ) |
||
136 | ) |
||
137 | ), |
||
138 | 'OBJ_ID' => new EE_Foreign_Key_Int_Field( 'OBJ_ID', __( 'ID of Item purchased.', 'event_espresso' ), TRUE, NULL, $line_items_can_be_for ), |
||
139 | 'OBJ_type' =>new EE_Any_Foreign_Model_Name_Field( 'OBJ_type', __( "Model Name this Line Item is for", "event_espresso" ), TRUE, NULL, $line_items_can_be_for ), |
||
140 | 'LIN_timestamp' => new EE_Datetime_Field('LIN_timestamp', __('When the line item was created','event_espresso'), false, time(), $timezone ), |
||
141 | ) |
||
142 | ); |
||
143 | $this->_model_relations = array( |
||
144 | 'Transaction' =>new EE_Belongs_To_Relation(), |
||
145 | 'Ticket' =>new EE_Belongs_To_Any_Relation(), |
||
146 | 'Price' =>new EE_Belongs_To_Any_Relation(), |
||
147 | 'Event' => new EE_Belongs_To_Any_Relation() |
||
148 | ); |
||
149 | $this->_model_chain_to_wp_user = 'Transaction.Registration.Event'; |
||
150 | $this->_caps_slug = 'transactions'; |
||
151 | parent::__construct( $timezone ); |
||
152 | } |
||
153 | |||
154 | |||
155 | |||
156 | /** |
||
157 | * Gets all the line items for this transaction of the given type |
||
158 | * @param string $line_item_type like one of EEM_Line_Item::type_* |
||
159 | * @param EE_Transaction|int $transaction |
||
160 | * @return EE_Line_Item[] |
||
161 | */ |
||
162 | public function get_all_of_type_for_transaction( $line_item_type, $transaction ){ |
||
163 | $transaction = EEM_Transaction::instance()->ensure_is_ID( $transaction ); |
||
164 | return $this->get_all( array( array( |
||
165 | 'LIN_type' => $line_item_type, |
||
166 | 'TXN_ID' => $transaction |
||
167 | ))); |
||
168 | } |
||
169 | |||
170 | |||
171 | |||
172 | /** |
||
173 | * Gets all line items unrelated to tickets that are normal line items |
||
174 | * (eg shipping, promotions, and miscellaneous other stuff should probably fit in this category) |
||
175 | * @param EE_Transaction|int $transaction |
||
176 | * @return \EE_Base_Class[] |
||
177 | */ |
||
178 | public function get_all_non_ticket_line_items_for_transaction( $transaction ) { |
||
179 | $transaction = EEM_Transaction::instance()->ensure_is_ID( $transaction ); |
||
180 | return $this->get_all( array( array( |
||
181 | 'LIN_type' => self::type_line_item, |
||
182 | 'TXN_ID' => $transaction, |
||
183 | 'OR' => array( |
||
184 | 'OBJ_type*notticket' => array( '!=', 'Ticket'), |
||
185 | 'OBJ_type*null' => array( 'IS_NULL' )) |
||
186 | ))); |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * Deletes line items with no transaction who have passed the transaction cutoff time. |
||
191 | * This needs to be very efficient |
||
192 | * because if there are spam bots afoot there will be LOTS of line items |
||
193 | * @return int count of how many deleted |
||
194 | */ |
||
195 | public function delete_line_items_with_no_transaction(){ |
||
196 | /** @type WPDB $wpdb */ |
||
197 | global $wpdb; |
||
198 | $time_to_leave_alone = apply_filters( |
||
199 | 'FHEE__EEM_Line_Item__delete_line_items_with_no_transaction__time_to_leave_alone', WEEK_IN_SECONDS |
||
200 | ); |
||
201 | $query = $wpdb->prepare( |
||
202 | 'DELETE li |
||
203 | FROM ' . $this->table() . ' li |
||
204 | LEFT JOIN ' . EEM_Transaction::instance()->table(). ' t ON li.TXN_ID = t.TXN_ID |
||
205 | WHERE t.TXN_ID IS NULL AND li.LIN_timestamp < %s', |
||
206 | // use GMT time because that's what TXN_timestamps are in |
||
207 | gmdate( 'Y-m-d H:i:s', time() - $time_to_leave_alone ) |
||
208 | ); |
||
209 | return $wpdb->query( $query ); |
||
210 | } |
||
211 | |||
212 | |||
213 | |||
214 | /** |
||
215 | * get_line_item_for_transaction_object |
||
216 | * Gets a transaction's line item record for a specific object such as a EE_Event or EE_Ticket |
||
217 | * |
||
218 | * @param int $TXN_ID |
||
219 | * @param \EE_Base_Class $object |
||
220 | * @return EE_Line_Item[] |
||
221 | */ |
||
222 | public function get_line_item_for_transaction_object( $TXN_ID, EE_Base_Class $object ){ |
||
223 | return $this->get_all( array( array( |
||
224 | 'TXN_ID' => $TXN_ID, |
||
225 | 'OBJ_type' => str_replace( 'EE_', '', get_class( $object )), |
||
226 | 'OBJ_ID' => $object->ID() |
||
227 | ))); |
||
228 | } |
||
229 | |||
230 | |||
231 | |||
232 | /** |
||
233 | * get_object_line_items_for_transaction |
||
234 | * Gets all of the the object line items for a transaction, based on an object type plus an array of object IDs |
||
235 | * |
||
236 | * @param int $TXN_ID |
||
237 | * @param string $OBJ_type |
||
238 | * @param array $OBJ_IDs |
||
239 | * @return EE_Line_Item[] |
||
240 | */ |
||
241 | public function get_object_line_items_for_transaction( $TXN_ID, $OBJ_type = 'Event', $OBJ_IDs = array() ){ |
||
252 | |||
253 | |||
254 | |||
255 | /** |
||
256 | * get_existing_promotion_line_item |
||
257 | * searches the cart for existing line items for the specified promotion |
||
258 | * |
||
259 | * @since 1.0.0 |
||
260 | * |
||
261 | * @param EE_Line_Item $parent_line_item |
||
262 | * @param EE_Promotion $promotion |
||
263 | * @return EE_Line_Item |
||
264 | */ |
||
265 | public function get_existing_promotion_line_item( EE_Line_Item $parent_line_item, EE_Promotion $promotion ) { |
||
266 | return $this->get_one( array( |
||
267 | array( |
||
268 | 'TXN_ID' => $parent_line_item->TXN_ID(), |
||
269 | 'LIN_parent' => $parent_line_item->ID(), |
||
270 | 'OBJ_type' => 'Promotion', |
||
271 | 'OBJ_ID' => $promotion->ID() |
||
272 | ) |
||
273 | )); |
||
274 | } |
||
275 | |||
276 | |||
277 | |||
278 | /** |
||
279 | * get_all_promotion_line_items |
||
280 | * searches the cart for any and all existing promotion line items |
||
281 | * |
||
282 | * @since 1.0.0 |
||
283 | * |
||
284 | * @param EE_Line_Item $parent_line_item |
||
285 | * @return EE_Line_Item[] |
||
286 | */ |
||
287 | public function get_all_promotion_line_items( EE_Line_Item $parent_line_item ) { |
||
288 | return $this->get_all( array( |
||
289 | array( |
||
290 | 'TXN_ID' => $parent_line_item->TXN_ID(), |
||
291 | 'LIN_parent' => $parent_line_item->ID(), |
||
292 | 'OBJ_type' => 'Promotion' |
||
293 | ) |
||
294 | )); |
||
295 | } |
||
296 | |||
297 | /** |
||
298 | * Gets the registration's corresponding line item. |
||
299 | * Note: basically does NOT support having multiple line items for a single ticket, |
||
300 | * which would happen if some of the registrations had a price modifier while others didn't. |
||
301 | * In order to support that, we'd probably need a LIN_ID on registrations or something. |
||
302 | * @param EE_Registration $registration |
||
303 | * @return EEM_Line_ITem |
||
304 | */ |
||
305 | public function get_line_item_for_registration( EE_Registration $registration ) { |
||
308 | |||
309 | /** |
||
310 | * Gets the query params used to retrieve a specific line item for the given registration |
||
311 | * @param EE_Registration $registration |
||
312 | * @param array $original_query_params any extra query params you'd like to be merged with |
||
313 | * @return array like EEM_Base::get_all()'s $query_params |
||
314 | */ |
||
315 | public function line_item_for_registration_query_params( EE_Registration $registration, $original_query_params = array() ) { |
||
324 | |||
325 | |||
326 | |||
327 | } |
Adding a
@return
annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.Please refer to the PHP core documentation on constructors.