Completed
Branch FET/rule-specific-exclusions-l... (334422)
by
unknown
17:10 queued 32s
created
core/db_classes/EE_Taxes.class.php 2 patches
Indentation   +123 added lines, -123 removed lines patch added patch discarded remove patch
@@ -10,138 +10,138 @@
 block discarded – undo
10 10
 class EE_Taxes extends EE_Base
11 11
 {
12 12
 
13
-    /**
14
-     * This is used for when EE_Taxes is used statically by the admin
15
-     *
16
-     * @var array
17
-     */
18
-    private static $_subtotal = array();
13
+	/**
14
+	 * This is used for when EE_Taxes is used statically by the admin
15
+	 *
16
+	 * @var array
17
+	 */
18
+	private static $_subtotal = array();
19 19
 
20
-    /**
21
-     * This holds an array of EE_Price objects that are of PRT_ID == 4 (tax price types)
22
-     *
23
-     * @var EE_Price[]
24
-     */
25
-    private static $_default_taxes = array();
20
+	/**
21
+	 * This holds an array of EE_Price objects that are of PRT_ID == 4 (tax price types)
22
+	 *
23
+	 * @var EE_Price[]
24
+	 */
25
+	private static $_default_taxes = array();
26 26
 
27 27
 
28
-    /**
29
-     * This method simply calculates the total taxes for a given ticket (by pulling the prices attached to the ticket
30
-     * and applying default taxes to it). Note: this is just an intermediary helper method added to facilitate quick
31
-     * calc of taxes for tickets listed in the event editor.
32
-     *
33
-     * @param  EE_Ticket $ticket incoming EE_Ticket
34
-     * @return float             total taxes to apply to ticket.
35
-     * @throws \EE_Error
36
-     */
37
-    public static function get_total_taxes_for_admin(EE_Ticket $ticket)
38
-    {
39
-        $tax = 0;
40
-        $total_tax = 0;
41
-        // This first checks to see if the given ticket is taxable.
42
-        if (! $ticket->get('TKT_taxable')) {
43
-            return $tax;
44
-        }
45
-        // get subtotal (notice we're only retrieving a subtotal if there isn't one given)
46
-        $subtotal = self::get_subtotal_for_admin($ticket);
47
-        // get taxes
48
-        $taxes = self::get_taxes_for_admin();
49
-        // apply taxes to subtotal
50
-        foreach ($taxes as $tax) {
51
-            // assuming taxes are not cumulative
52
-            $total_tax += $subtotal * $tax->get('PRC_amount') / 100;
53
-        }
54
-        return $total_tax;
55
-    }
28
+	/**
29
+	 * This method simply calculates the total taxes for a given ticket (by pulling the prices attached to the ticket
30
+	 * and applying default taxes to it). Note: this is just an intermediary helper method added to facilitate quick
31
+	 * calc of taxes for tickets listed in the event editor.
32
+	 *
33
+	 * @param  EE_Ticket $ticket incoming EE_Ticket
34
+	 * @return float             total taxes to apply to ticket.
35
+	 * @throws \EE_Error
36
+	 */
37
+	public static function get_total_taxes_for_admin(EE_Ticket $ticket)
38
+	{
39
+		$tax = 0;
40
+		$total_tax = 0;
41
+		// This first checks to see if the given ticket is taxable.
42
+		if (! $ticket->get('TKT_taxable')) {
43
+			return $tax;
44
+		}
45
+		// get subtotal (notice we're only retrieving a subtotal if there isn't one given)
46
+		$subtotal = self::get_subtotal_for_admin($ticket);
47
+		// get taxes
48
+		$taxes = self::get_taxes_for_admin();
49
+		// apply taxes to subtotal
50
+		foreach ($taxes as $tax) {
51
+			// assuming taxes are not cumulative
52
+			$total_tax += $subtotal * $tax->get('PRC_amount') / 100;
53
+		}
54
+		return $total_tax;
55
+	}
56 56
 
57 57
 
58
-    /**
59
-     * Gets the total percentage of tax that should be applied to taxable line items
60
-     *
61
-     * @return float the percentage of tax that should be added to taxable items
62
-     * @throws \EE_Error
63
-     * eg 20 for %20 tax (NOT 0.20, which
64
-     */
65
-    public static function get_total_taxes_percentage()
66
-    {
67
-        $total_tax_percent = 0;
68
-        foreach (self::get_taxes_for_admin() as $tax_price) {
69
-            $total_tax_percent += $tax_price->get('PRC_amount');
70
-        }
71
-        return $total_tax_percent;
72
-    }
58
+	/**
59
+	 * Gets the total percentage of tax that should be applied to taxable line items
60
+	 *
61
+	 * @return float the percentage of tax that should be added to taxable items
62
+	 * @throws \EE_Error
63
+	 * eg 20 for %20 tax (NOT 0.20, which
64
+	 */
65
+	public static function get_total_taxes_percentage()
66
+	{
67
+		$total_tax_percent = 0;
68
+		foreach (self::get_taxes_for_admin() as $tax_price) {
69
+			$total_tax_percent += $tax_price->get('PRC_amount');
70
+		}
71
+		return $total_tax_percent;
72
+	}
73 73
 
74 74
 
75
-    /**
76
-     * @param EE_Ticket $ticket
77
-     * @return float
78
-     * @throws \EE_Error
79
-     */
80
-    public static function get_subtotal_for_admin(EE_Ticket $ticket)
81
-    {
82
-        $TKT_ID = $ticket->ID();
83
-        return isset(self::$_subtotal[ $TKT_ID ])
84
-            ? self::$_subtotal[ $TKT_ID ]
85
-            : self::_get_subtotal_for_admin($ticket);
86
-    }
75
+	/**
76
+	 * @param EE_Ticket $ticket
77
+	 * @return float
78
+	 * @throws \EE_Error
79
+	 */
80
+	public static function get_subtotal_for_admin(EE_Ticket $ticket)
81
+	{
82
+		$TKT_ID = $ticket->ID();
83
+		return isset(self::$_subtotal[ $TKT_ID ])
84
+			? self::$_subtotal[ $TKT_ID ]
85
+			: self::_get_subtotal_for_admin($ticket);
86
+	}
87 87
 
88 88
 
89
-    /**
90
-     * simply take an incoming ticket and calculate the subtotal for the ticket
91
-     *
92
-     * @param  EE_Ticket $ticket
93
-     * @return float     subtotal calculated from all EE_Price[] on Ticket.
94
-     * @throws \EE_Error
95
-     */
96
-    private static function _get_subtotal_for_admin(EE_Ticket $ticket)
97
-    {
98
-        $subtotal = 0;
99
-        // get all prices
100
-        $prices = $ticket->get_many_related(
101
-            'Price',
102
-            array(
103
-                'default_where_conditions' => 'none',
104
-                'order_by'                 => array('PRC_order' => 'ASC'),
105
-            )
106
-        );
107
-        // let's loop through them (base price is always the first item)
108
-        foreach ($prices as $price) {
109
-            if ($price instanceof EE_Price) {
110
-                $price_type = $price->type_obj();
111
-                if ($price_type instanceof EE_Price_Type) {
112
-                    switch ($price->type_obj()->base_type()) {
113
-                        case 1: // base price
114
-                        case 3: // surcharges
115
-                            $subtotal += $price->is_percent() ? $subtotal * $price->get('PRC_amount') / 100
116
-                                : $price->get('PRC_amount');
117
-                            break;
118
-                        case 2: // discounts
119
-                            $subtotal -= $price->is_percent() ? $subtotal * $price->get('PRC_amount') / 100
120
-                                : $price->get('PRC_amount');
121
-                            break;
122
-                    }
123
-                }
124
-            }
125
-        }
126
-        $TKT_ID = $ticket->ID();
127
-        self::$_subtotal = array($TKT_ID => $subtotal);
128
-        return $subtotal;
129
-    }
89
+	/**
90
+	 * simply take an incoming ticket and calculate the subtotal for the ticket
91
+	 *
92
+	 * @param  EE_Ticket $ticket
93
+	 * @return float     subtotal calculated from all EE_Price[] on Ticket.
94
+	 * @throws \EE_Error
95
+	 */
96
+	private static function _get_subtotal_for_admin(EE_Ticket $ticket)
97
+	{
98
+		$subtotal = 0;
99
+		// get all prices
100
+		$prices = $ticket->get_many_related(
101
+			'Price',
102
+			array(
103
+				'default_where_conditions' => 'none',
104
+				'order_by'                 => array('PRC_order' => 'ASC'),
105
+			)
106
+		);
107
+		// let's loop through them (base price is always the first item)
108
+		foreach ($prices as $price) {
109
+			if ($price instanceof EE_Price) {
110
+				$price_type = $price->type_obj();
111
+				if ($price_type instanceof EE_Price_Type) {
112
+					switch ($price->type_obj()->base_type()) {
113
+						case 1: // base price
114
+						case 3: // surcharges
115
+							$subtotal += $price->is_percent() ? $subtotal * $price->get('PRC_amount') / 100
116
+								: $price->get('PRC_amount');
117
+							break;
118
+						case 2: // discounts
119
+							$subtotal -= $price->is_percent() ? $subtotal * $price->get('PRC_amount') / 100
120
+								: $price->get('PRC_amount');
121
+							break;
122
+					}
123
+				}
124
+			}
125
+		}
126
+		$TKT_ID = $ticket->ID();
127
+		self::$_subtotal = array($TKT_ID => $subtotal);
128
+		return $subtotal;
129
+	}
130 130
 
131 131
 
132
-    /**
133
-     * get all default prices that are a Tax price type (PRT_ID = 4) and return
134
-     *
135
-     * @return EE_Price[] EE_Price objects that have PRT_ID == 4
136
-     * @throws \EE_Error
137
-     */
138
-    public static function get_taxes_for_admin()
139
-    {
140
-        if (empty(self::$_default_taxes)) {
141
-            self::$_default_taxes = EE_Registry::instance()->load_model('Price')->get_all(
142
-                array(array('Price_Type.PBT_ID' => 4))
143
-            );
144
-        }
145
-        return self::$_default_taxes;
146
-    }
132
+	/**
133
+	 * get all default prices that are a Tax price type (PRT_ID = 4) and return
134
+	 *
135
+	 * @return EE_Price[] EE_Price objects that have PRT_ID == 4
136
+	 * @throws \EE_Error
137
+	 */
138
+	public static function get_taxes_for_admin()
139
+	{
140
+		if (empty(self::$_default_taxes)) {
141
+			self::$_default_taxes = EE_Registry::instance()->load_model('Price')->get_all(
142
+				array(array('Price_Type.PBT_ID' => 4))
143
+			);
144
+		}
145
+		return self::$_default_taxes;
146
+	}
147 147
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -39,7 +39,7 @@  discard block
 block discarded – undo
39 39
         $tax = 0;
40 40
         $total_tax = 0;
41 41
         // This first checks to see if the given ticket is taxable.
42
-        if (! $ticket->get('TKT_taxable')) {
42
+        if ( ! $ticket->get('TKT_taxable')) {
43 43
             return $tax;
44 44
         }
45 45
         // get subtotal (notice we're only retrieving a subtotal if there isn't one given)
@@ -80,8 +80,8 @@  discard block
 block discarded – undo
80 80
     public static function get_subtotal_for_admin(EE_Ticket $ticket)
81 81
     {
82 82
         $TKT_ID = $ticket->ID();
83
-        return isset(self::$_subtotal[ $TKT_ID ])
84
-            ? self::$_subtotal[ $TKT_ID ]
83
+        return isset(self::$_subtotal[$TKT_ID])
84
+            ? self::$_subtotal[$TKT_ID]
85 85
             : self::_get_subtotal_for_admin($ticket);
86 86
     }
87 87
 
Please login to merge, or discard this patch.
core/db_classes/EE_Message_Template_Group.class.php 2 patches
Indentation   +483 added lines, -483 removed lines patch added patch discarded remove patch
@@ -13,487 +13,487 @@
 block discarded – undo
13 13
 class EE_Message_Template_Group extends EE_Soft_Delete_Base_Class
14 14
 {
15 15
 
16
-    /**
17
-     * Extra Meta key prefix for whether a given context for this message tmeplate group is active or not.
18
-     */
19
-    const ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX = 'active_context_';
20
-
21
-    /**
22
-     * @param array  $props_n_values
23
-     * @param string $timezone
24
-     * @return EE_Message_Template_Group|mixed
25
-     * @throws EE_Error
26
-     */
27
-    public static function new_instance($props_n_values = array(), $timezone = '')
28
-    {
29
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone);
30
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone);
31
-    }
32
-
33
-
34
-    /**
35
-     * @param array  $props_n_values
36
-     * @param string $timezone
37
-     * @return EE_Message_Template_Group
38
-     */
39
-    public static function new_instance_from_db($props_n_values = array(), $timezone = '')
40
-    {
41
-        return new self($props_n_values, true, $timezone);
42
-    }
43
-
44
-
45
-    /**
46
-     * @param bool $message_type
47
-     * @throws EE_Error
48
-     */
49
-    public function set_message_type($message_type = false)
50
-    {
51
-        if (! $message_type) {
52
-            throw new EE_Error(esc_html__('Missing required value for the message_type parameter', 'event_espresso'));
53
-        }
54
-        $this->set('MTP_message_type', $message_type);
55
-    }
56
-
57
-
58
-    /**
59
-     * @param bool $messenger
60
-     * @throws EE_Error
61
-     */
62
-    public function set_messenger($messenger = false)
63
-    {
64
-        if (! $messenger) {
65
-            throw new EE_Error(esc_html__('Missing required value for the messenger parameter', 'event_espresso'));
66
-        }
67
-        $this->set('MTP_messenger', $messenger);
68
-    }
69
-
70
-
71
-    /**
72
-     * @param bool $GRP_ID
73
-     * @throws EE_Error
74
-     */
75
-    public function set_group_template_id($GRP_ID = false)
76
-    {
77
-        if (! $GRP_ID) {
78
-            throw new EE_Error(
79
-                esc_html__(
80
-                    'Missing required value for the message template group id',
81
-                    'event_espresso'
82
-                )
83
-            );
84
-        }
85
-        $this->set('GRP_ID', $GRP_ID);
86
-    }
87
-
88
-
89
-    /**
90
-     * get Group ID
91
-     *
92
-     * @access public
93
-     * @return int
94
-     * @throws EE_Error
95
-     */
96
-    public function GRP_ID()
97
-    {
98
-        return $this->get('GRP_ID');
99
-    }
100
-
101
-
102
-    /**
103
-     * get User ID
104
-     *
105
-     * @access public
106
-     * @return int
107
-     * @throws EE_Error
108
-     */
109
-    public function user()
110
-    {
111
-        $user_id = $this->get('MTP_user_id');
112
-        return empty($user_id) ? get_current_user_id() : $user_id;
113
-    }
114
-
115
-
116
-    /**
117
-     * Wrapper for the user function() (preserve backward compat)
118
-     *
119
-     * @since  4.5.0
120
-     * @return int
121
-     * @throws EE_Error
122
-     */
123
-    public function wp_user()
124
-    {
125
-        return $this->user();
126
-    }
127
-
128
-
129
-    /**
130
-     * This simply returns a count of all related events to this message template group
131
-     *
132
-     * @return int
133
-     */
134
-    public function count_events()
135
-    {
136
-        return $this->count_related('Event');
137
-    }
138
-
139
-
140
-    /**
141
-     * returns the name saved in the db for this template
142
-     *
143
-     * @return string
144
-     * @throws EE_Error
145
-     */
146
-    public function name()
147
-    {
148
-        return $this->get('MTP_name');
149
-    }
150
-
151
-
152
-    /**
153
-     * Returns the description saved in the db for this template group
154
-     *
155
-     * @return string
156
-     * @throws EE_Error
157
-     */
158
-    public function description()
159
-    {
160
-        return $this->get('MTP_description');
161
-    }
162
-
163
-
164
-    /**
165
-     * returns all related EE_Message_Template objects
166
-     *
167
-     * @param  array $query_params like EEM_Base::get_all()
168
-     * @return EE_Message_Template[]
169
-     * @throws EE_Error
170
-     */
171
-    public function message_templates($query_params = array())
172
-    {
173
-        return $this->get_many_related('Message_Template', $query_params);
174
-    }
175
-
176
-
177
-    /**
178
-     * get Message Messenger
179
-     *
180
-     * @access public
181
-     * @return string
182
-     * @throws EE_Error
183
-     */
184
-    public function messenger()
185
-    {
186
-        return $this->get('MTP_messenger');
187
-    }
188
-
189
-
190
-    /**
191
-     * get Message Messenger OBJECT
192
-     * If an attempt to get the corresponding messenger object fails, then we set this message
193
-     * template group to inactive, and save to db.  Then return null so client code can handle
194
-     * appropriately.
195
-     *
196
-     * @return EE_messenger
197
-     * @throws EE_Error
198
-     */
199
-    public function messenger_obj()
200
-    {
201
-        $messenger = $this->messenger();
202
-        try {
203
-            $messenger = EEH_MSG_Template::messenger_obj($messenger);
204
-        } catch (EE_Error $e) {
205
-            // if an exception was thrown then let's deactivate this message template group because it means there is no
206
-            // class for this messenger in this group.
207
-            $this->set('MTP_is_active', false);
208
-            $this->save();
209
-            return null;
210
-        }
211
-        return $messenger;
212
-    }
213
-
214
-
215
-    /**
216
-     * get Message Type
217
-     *
218
-     * @access public
219
-     * @return string
220
-     * @throws EE_Error
221
-     */
222
-    public function message_type()
223
-    {
224
-        return $this->get('MTP_message_type');
225
-    }
226
-
227
-
228
-    /**
229
-     * get Message type OBJECT
230
-     * If an attempt to get the corresponding message type object fails, then we set this message
231
-     * template group to inactive, and save to db.  Then return null so client code can handle
232
-     * appropriately.
233
-     *
234
-     * @throws EE_Error
235
-     * @return EE_message_type|false if exception thrown.
236
-     */
237
-    public function message_type_obj()
238
-    {
239
-        $message_type = $this->message_type();
240
-        try {
241
-            $message_type = EEH_MSG_Template::message_type_obj($message_type);
242
-        } catch (EE_Error $e) {
243
-            // if an exception was thrown then let's deactivate this message template group because it means there is no
244
-            // class for the message type in this group.
245
-            $this->set('MTP_is_active', false);
246
-            $this->save();
247
-            return null;
248
-        }
249
-        return $message_type;
250
-    }
251
-
252
-
253
-    /**
254
-     * @return array
255
-     * @throws EE_Error
256
-     */
257
-    public function contexts_config()
258
-    {
259
-        return $this->message_type_obj()->get_contexts();
260
-    }
261
-
262
-
263
-    /**
264
-     * This returns the context_label for contexts as set in the message type object
265
-     * Note this is an array with singular and plural keys
266
-     *
267
-     * @access public
268
-     * @return array labels for "context"
269
-     * @throws EE_Error
270
-     */
271
-    public function context_label()
272
-    {
273
-        $obj = $this->message_type_obj();
274
-        return $obj->get_context_label();
275
-    }
276
-
277
-
278
-    /**
279
-     * This returns an array of EE_Message_Template objects indexed by context and field.
280
-     *
281
-     * @return array ()
282
-     * @throws EE_Error
283
-     */
284
-    public function context_templates()
285
-    {
286
-        $mtps_arr = array();
287
-        $mtps = $this->get_many_related('Message_Template');
288
-        if (empty($mtps)) {
289
-            return array();
290
-        }
291
-        // note contexts could have CHECKBOX fields per context. So we return the objects indexed by context AND field.
292
-        foreach ($mtps as $mtp) {
293
-            $mtps_arr[ $mtp->get('MTP_context') ][ $mtp->get('MTP_template_field') ] = $mtp;
294
-        }
295
-        return $mtps_arr;
296
-    }
297
-
298
-
299
-    /**
300
-     * this returns if the template group this template belongs to is global
301
-     *
302
-     * @return bool true if it is, false if it isn't
303
-     * @throws EE_Error
304
-     */
305
-    public function is_global()
306
-    {
307
-        return $this->get('MTP_is_global');
308
-    }
309
-
310
-
311
-    /**
312
-     * this returns if the template group this template belongs to is active (i.e. turned "on" or not)
313
-     *
314
-     * @return bool true if it is, false if it isn't
315
-     * @throws EE_Error
316
-     */
317
-    public function is_active()
318
-    {
319
-        return $this->get('MTP_is_active');
320
-    }
321
-
322
-
323
-    /**
324
-     * This will return an array of shortcodes => labels from the messenger and message_type objects associated with
325
-     * this template.
326
-     *
327
-     * @since 4.3.0
328
-     * @uses  EEH_MSG_Template::get_shortcodes()
329
-     * @param string $context what context we're going to return shortcodes for
330
-     * @param array  $fields  what fields we're returning valid shortcodes for.  If empty then we assume all fields are
331
-     *                        to be returned.
332
-     * @param bool   $merged  If TRUE then we don't return shortcodes indexed by field but instead an array of the
333
-     *                        unique shortcodes for all the given (or all) fields.
334
-     * @return mixed (array|bool) an array of shortcodes in the format array( '[shortcode] => 'label') OR FALSE if no
335
-     *                        shortcodes found.
336
-     * @throws EE_Error
337
-     */
338
-    public function get_shortcodes($context, $fields = array(), $merged = false)
339
-    {
340
-        $messenger = $this->messenger();
341
-        $message_type = $this->message_type();
342
-        return EEH_MSG_Template::get_shortcodes($message_type, $messenger, $fields, $context, $merged);
343
-    }
344
-
345
-
346
-    /**
347
-     * This just gets the template pack name assigned to this message template group.  If it's not set, then we just
348
-     * use the default template pack.
349
-     *
350
-     * @since 4.5.0
351
-     * @return string
352
-     * @throws EE_Error
353
-     */
354
-    public function get_template_pack_name()
355
-    {
356
-        return $this->get_extra_meta('MTP_template_pack', true, 'default');
357
-    }
358
-
359
-
360
-    /**
361
-     * This returns the specific template pack object referenced by the template pack name attached to this message
362
-     * template group.  If no template pack is assigned then the default template pack is retrieved.
363
-     *
364
-     * @since 4.5.0
365
-     * @return EE_Messages_Template_Pack
366
-     * @throws EE_Error
367
-     * @throws InvalidArgumentException
368
-     * @throws ReflectionException
369
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
370
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
371
-     */
372
-    public function get_template_pack()
373
-    {
374
-        $pack_name = $this->get_template_pack_name();
375
-        EE_Registry::instance()->load_helper('MSG_Template');
376
-        return EEH_MSG_Template::get_template_pack($pack_name);
377
-    }
378
-
379
-
380
-    /**
381
-     * This retrieves the template variation assigned to this message template group.  If it's not set, then we just
382
-     * use the default template variation.
383
-     *
384
-     * @since 4.5.0
385
-     * @return string
386
-     * @throws EE_Error
387
-     */
388
-    public function get_template_pack_variation()
389
-    {
390
-        return $this->get_extra_meta('MTP_variation', true, 'default');
391
-    }
392
-
393
-
394
-    /**
395
-     * This just sets the template pack name attached to this message template group.
396
-     *
397
-     * @since 4.5.0
398
-     * @param string $template_pack_name What message template pack is assigned.
399
-     * @return int
400
-     * @throws EE_Error
401
-     */
402
-    public function set_template_pack_name($template_pack_name)
403
-    {
404
-        return $this->update_extra_meta('MTP_template_pack', $template_pack_name);
405
-    }
406
-
407
-
408
-    /**
409
-     * This just sets the template pack variation attached to this message template group.
410
-     *
411
-     * @since 4.5.0
412
-     * @param string $variation What variation is being set on the message template group.
413
-     * @return int
414
-     * @throws EE_Error
415
-     */
416
-    public function set_template_pack_variation($variation)
417
-    {
418
-        return $this->update_extra_meta('MTP_variation', $variation);
419
-    }
420
-
421
-
422
-    /**
423
-     * Deactivates the given context.
424
-     *
425
-     * @param $context
426
-     * @return bool|int
427
-     * @throws EE_Error
428
-     * @throws InvalidIdentifierException
429
-     */
430
-    public function deactivate_context($context)
431
-    {
432
-        $this->validate_context($context);
433
-        return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, false);
434
-    }
435
-
436
-
437
-    /**
438
-     * Activates the given context.
439
-     *
440
-     * @param $context
441
-     * @return bool|int
442
-     * @throws EE_Error
443
-     * @throws InvalidIdentifierException
444
-     */
445
-    public function activate_context($context)
446
-    {
447
-        $this->validate_context($context);
448
-        return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, true);
449
-    }
450
-
451
-
452
-    /**
453
-     * Returns whether the context is active or not.
454
-     * Note, this will default to true if the extra meta record doesn't exist.
455
-     * Also, this does NOT account for whether the "To" field is empty or not. Some messengers may allow the "To" field
456
-     * to be empty (@see EE_Messenger::allow_empty_to_field()) so an empty "To" field is not always an indicator of
457
-     * whether a context is "active" or not.
458
-     *
459
-     * @param $context
460
-     * @return bool
461
-     * @throws EE_Error
462
-     * @throws InvalidIdentifierException
463
-     */
464
-    public function is_context_active($context)
465
-    {
466
-        $this->validate_context($context);
467
-        return filter_var(
468
-            $this->get_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, true, true),
469
-            FILTER_VALIDATE_BOOLEAN
470
-        );
471
-    }
472
-
473
-
474
-    /**
475
-     * Validates the incoming context to verify it matches a registered context for the related message type.
476
-     *
477
-     * @param string $context
478
-     * @throws EE_Error
479
-     * @throws InvalidIdentifierException
480
-     */
481
-    public function validate_context($context)
482
-    {
483
-        $contexts = $this->contexts_config();
484
-        if (! isset($contexts[ $context ])) {
485
-            throw new InvalidIdentifierException(
486
-                '',
487
-                '',
488
-                sprintf(
489
-                    esc_html__(
490
-                        'An invalid string identifying a context was provided.  "%1$s" was received, and one of "%2$s" was expected.',
491
-                        'event_espresso'
492
-                    ),
493
-                    $context,
494
-                    implode(',', array_keys($contexts))
495
-                )
496
-            );
497
-        }
498
-    }
16
+	/**
17
+	 * Extra Meta key prefix for whether a given context for this message tmeplate group is active or not.
18
+	 */
19
+	const ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX = 'active_context_';
20
+
21
+	/**
22
+	 * @param array  $props_n_values
23
+	 * @param string $timezone
24
+	 * @return EE_Message_Template_Group|mixed
25
+	 * @throws EE_Error
26
+	 */
27
+	public static function new_instance($props_n_values = array(), $timezone = '')
28
+	{
29
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone);
30
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone);
31
+	}
32
+
33
+
34
+	/**
35
+	 * @param array  $props_n_values
36
+	 * @param string $timezone
37
+	 * @return EE_Message_Template_Group
38
+	 */
39
+	public static function new_instance_from_db($props_n_values = array(), $timezone = '')
40
+	{
41
+		return new self($props_n_values, true, $timezone);
42
+	}
43
+
44
+
45
+	/**
46
+	 * @param bool $message_type
47
+	 * @throws EE_Error
48
+	 */
49
+	public function set_message_type($message_type = false)
50
+	{
51
+		if (! $message_type) {
52
+			throw new EE_Error(esc_html__('Missing required value for the message_type parameter', 'event_espresso'));
53
+		}
54
+		$this->set('MTP_message_type', $message_type);
55
+	}
56
+
57
+
58
+	/**
59
+	 * @param bool $messenger
60
+	 * @throws EE_Error
61
+	 */
62
+	public function set_messenger($messenger = false)
63
+	{
64
+		if (! $messenger) {
65
+			throw new EE_Error(esc_html__('Missing required value for the messenger parameter', 'event_espresso'));
66
+		}
67
+		$this->set('MTP_messenger', $messenger);
68
+	}
69
+
70
+
71
+	/**
72
+	 * @param bool $GRP_ID
73
+	 * @throws EE_Error
74
+	 */
75
+	public function set_group_template_id($GRP_ID = false)
76
+	{
77
+		if (! $GRP_ID) {
78
+			throw new EE_Error(
79
+				esc_html__(
80
+					'Missing required value for the message template group id',
81
+					'event_espresso'
82
+				)
83
+			);
84
+		}
85
+		$this->set('GRP_ID', $GRP_ID);
86
+	}
87
+
88
+
89
+	/**
90
+	 * get Group ID
91
+	 *
92
+	 * @access public
93
+	 * @return int
94
+	 * @throws EE_Error
95
+	 */
96
+	public function GRP_ID()
97
+	{
98
+		return $this->get('GRP_ID');
99
+	}
100
+
101
+
102
+	/**
103
+	 * get User ID
104
+	 *
105
+	 * @access public
106
+	 * @return int
107
+	 * @throws EE_Error
108
+	 */
109
+	public function user()
110
+	{
111
+		$user_id = $this->get('MTP_user_id');
112
+		return empty($user_id) ? get_current_user_id() : $user_id;
113
+	}
114
+
115
+
116
+	/**
117
+	 * Wrapper for the user function() (preserve backward compat)
118
+	 *
119
+	 * @since  4.5.0
120
+	 * @return int
121
+	 * @throws EE_Error
122
+	 */
123
+	public function wp_user()
124
+	{
125
+		return $this->user();
126
+	}
127
+
128
+
129
+	/**
130
+	 * This simply returns a count of all related events to this message template group
131
+	 *
132
+	 * @return int
133
+	 */
134
+	public function count_events()
135
+	{
136
+		return $this->count_related('Event');
137
+	}
138
+
139
+
140
+	/**
141
+	 * returns the name saved in the db for this template
142
+	 *
143
+	 * @return string
144
+	 * @throws EE_Error
145
+	 */
146
+	public function name()
147
+	{
148
+		return $this->get('MTP_name');
149
+	}
150
+
151
+
152
+	/**
153
+	 * Returns the description saved in the db for this template group
154
+	 *
155
+	 * @return string
156
+	 * @throws EE_Error
157
+	 */
158
+	public function description()
159
+	{
160
+		return $this->get('MTP_description');
161
+	}
162
+
163
+
164
+	/**
165
+	 * returns all related EE_Message_Template objects
166
+	 *
167
+	 * @param  array $query_params like EEM_Base::get_all()
168
+	 * @return EE_Message_Template[]
169
+	 * @throws EE_Error
170
+	 */
171
+	public function message_templates($query_params = array())
172
+	{
173
+		return $this->get_many_related('Message_Template', $query_params);
174
+	}
175
+
176
+
177
+	/**
178
+	 * get Message Messenger
179
+	 *
180
+	 * @access public
181
+	 * @return string
182
+	 * @throws EE_Error
183
+	 */
184
+	public function messenger()
185
+	{
186
+		return $this->get('MTP_messenger');
187
+	}
188
+
189
+
190
+	/**
191
+	 * get Message Messenger OBJECT
192
+	 * If an attempt to get the corresponding messenger object fails, then we set this message
193
+	 * template group to inactive, and save to db.  Then return null so client code can handle
194
+	 * appropriately.
195
+	 *
196
+	 * @return EE_messenger
197
+	 * @throws EE_Error
198
+	 */
199
+	public function messenger_obj()
200
+	{
201
+		$messenger = $this->messenger();
202
+		try {
203
+			$messenger = EEH_MSG_Template::messenger_obj($messenger);
204
+		} catch (EE_Error $e) {
205
+			// if an exception was thrown then let's deactivate this message template group because it means there is no
206
+			// class for this messenger in this group.
207
+			$this->set('MTP_is_active', false);
208
+			$this->save();
209
+			return null;
210
+		}
211
+		return $messenger;
212
+	}
213
+
214
+
215
+	/**
216
+	 * get Message Type
217
+	 *
218
+	 * @access public
219
+	 * @return string
220
+	 * @throws EE_Error
221
+	 */
222
+	public function message_type()
223
+	{
224
+		return $this->get('MTP_message_type');
225
+	}
226
+
227
+
228
+	/**
229
+	 * get Message type OBJECT
230
+	 * If an attempt to get the corresponding message type object fails, then we set this message
231
+	 * template group to inactive, and save to db.  Then return null so client code can handle
232
+	 * appropriately.
233
+	 *
234
+	 * @throws EE_Error
235
+	 * @return EE_message_type|false if exception thrown.
236
+	 */
237
+	public function message_type_obj()
238
+	{
239
+		$message_type = $this->message_type();
240
+		try {
241
+			$message_type = EEH_MSG_Template::message_type_obj($message_type);
242
+		} catch (EE_Error $e) {
243
+			// if an exception was thrown then let's deactivate this message template group because it means there is no
244
+			// class for the message type in this group.
245
+			$this->set('MTP_is_active', false);
246
+			$this->save();
247
+			return null;
248
+		}
249
+		return $message_type;
250
+	}
251
+
252
+
253
+	/**
254
+	 * @return array
255
+	 * @throws EE_Error
256
+	 */
257
+	public function contexts_config()
258
+	{
259
+		return $this->message_type_obj()->get_contexts();
260
+	}
261
+
262
+
263
+	/**
264
+	 * This returns the context_label for contexts as set in the message type object
265
+	 * Note this is an array with singular and plural keys
266
+	 *
267
+	 * @access public
268
+	 * @return array labels for "context"
269
+	 * @throws EE_Error
270
+	 */
271
+	public function context_label()
272
+	{
273
+		$obj = $this->message_type_obj();
274
+		return $obj->get_context_label();
275
+	}
276
+
277
+
278
+	/**
279
+	 * This returns an array of EE_Message_Template objects indexed by context and field.
280
+	 *
281
+	 * @return array ()
282
+	 * @throws EE_Error
283
+	 */
284
+	public function context_templates()
285
+	{
286
+		$mtps_arr = array();
287
+		$mtps = $this->get_many_related('Message_Template');
288
+		if (empty($mtps)) {
289
+			return array();
290
+		}
291
+		// note contexts could have CHECKBOX fields per context. So we return the objects indexed by context AND field.
292
+		foreach ($mtps as $mtp) {
293
+			$mtps_arr[ $mtp->get('MTP_context') ][ $mtp->get('MTP_template_field') ] = $mtp;
294
+		}
295
+		return $mtps_arr;
296
+	}
297
+
298
+
299
+	/**
300
+	 * this returns if the template group this template belongs to is global
301
+	 *
302
+	 * @return bool true if it is, false if it isn't
303
+	 * @throws EE_Error
304
+	 */
305
+	public function is_global()
306
+	{
307
+		return $this->get('MTP_is_global');
308
+	}
309
+
310
+
311
+	/**
312
+	 * this returns if the template group this template belongs to is active (i.e. turned "on" or not)
313
+	 *
314
+	 * @return bool true if it is, false if it isn't
315
+	 * @throws EE_Error
316
+	 */
317
+	public function is_active()
318
+	{
319
+		return $this->get('MTP_is_active');
320
+	}
321
+
322
+
323
+	/**
324
+	 * This will return an array of shortcodes => labels from the messenger and message_type objects associated with
325
+	 * this template.
326
+	 *
327
+	 * @since 4.3.0
328
+	 * @uses  EEH_MSG_Template::get_shortcodes()
329
+	 * @param string $context what context we're going to return shortcodes for
330
+	 * @param array  $fields  what fields we're returning valid shortcodes for.  If empty then we assume all fields are
331
+	 *                        to be returned.
332
+	 * @param bool   $merged  If TRUE then we don't return shortcodes indexed by field but instead an array of the
333
+	 *                        unique shortcodes for all the given (or all) fields.
334
+	 * @return mixed (array|bool) an array of shortcodes in the format array( '[shortcode] => 'label') OR FALSE if no
335
+	 *                        shortcodes found.
336
+	 * @throws EE_Error
337
+	 */
338
+	public function get_shortcodes($context, $fields = array(), $merged = false)
339
+	{
340
+		$messenger = $this->messenger();
341
+		$message_type = $this->message_type();
342
+		return EEH_MSG_Template::get_shortcodes($message_type, $messenger, $fields, $context, $merged);
343
+	}
344
+
345
+
346
+	/**
347
+	 * This just gets the template pack name assigned to this message template group.  If it's not set, then we just
348
+	 * use the default template pack.
349
+	 *
350
+	 * @since 4.5.0
351
+	 * @return string
352
+	 * @throws EE_Error
353
+	 */
354
+	public function get_template_pack_name()
355
+	{
356
+		return $this->get_extra_meta('MTP_template_pack', true, 'default');
357
+	}
358
+
359
+
360
+	/**
361
+	 * This returns the specific template pack object referenced by the template pack name attached to this message
362
+	 * template group.  If no template pack is assigned then the default template pack is retrieved.
363
+	 *
364
+	 * @since 4.5.0
365
+	 * @return EE_Messages_Template_Pack
366
+	 * @throws EE_Error
367
+	 * @throws InvalidArgumentException
368
+	 * @throws ReflectionException
369
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
370
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
371
+	 */
372
+	public function get_template_pack()
373
+	{
374
+		$pack_name = $this->get_template_pack_name();
375
+		EE_Registry::instance()->load_helper('MSG_Template');
376
+		return EEH_MSG_Template::get_template_pack($pack_name);
377
+	}
378
+
379
+
380
+	/**
381
+	 * This retrieves the template variation assigned to this message template group.  If it's not set, then we just
382
+	 * use the default template variation.
383
+	 *
384
+	 * @since 4.5.0
385
+	 * @return string
386
+	 * @throws EE_Error
387
+	 */
388
+	public function get_template_pack_variation()
389
+	{
390
+		return $this->get_extra_meta('MTP_variation', true, 'default');
391
+	}
392
+
393
+
394
+	/**
395
+	 * This just sets the template pack name attached to this message template group.
396
+	 *
397
+	 * @since 4.5.0
398
+	 * @param string $template_pack_name What message template pack is assigned.
399
+	 * @return int
400
+	 * @throws EE_Error
401
+	 */
402
+	public function set_template_pack_name($template_pack_name)
403
+	{
404
+		return $this->update_extra_meta('MTP_template_pack', $template_pack_name);
405
+	}
406
+
407
+
408
+	/**
409
+	 * This just sets the template pack variation attached to this message template group.
410
+	 *
411
+	 * @since 4.5.0
412
+	 * @param string $variation What variation is being set on the message template group.
413
+	 * @return int
414
+	 * @throws EE_Error
415
+	 */
416
+	public function set_template_pack_variation($variation)
417
+	{
418
+		return $this->update_extra_meta('MTP_variation', $variation);
419
+	}
420
+
421
+
422
+	/**
423
+	 * Deactivates the given context.
424
+	 *
425
+	 * @param $context
426
+	 * @return bool|int
427
+	 * @throws EE_Error
428
+	 * @throws InvalidIdentifierException
429
+	 */
430
+	public function deactivate_context($context)
431
+	{
432
+		$this->validate_context($context);
433
+		return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, false);
434
+	}
435
+
436
+
437
+	/**
438
+	 * Activates the given context.
439
+	 *
440
+	 * @param $context
441
+	 * @return bool|int
442
+	 * @throws EE_Error
443
+	 * @throws InvalidIdentifierException
444
+	 */
445
+	public function activate_context($context)
446
+	{
447
+		$this->validate_context($context);
448
+		return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, true);
449
+	}
450
+
451
+
452
+	/**
453
+	 * Returns whether the context is active or not.
454
+	 * Note, this will default to true if the extra meta record doesn't exist.
455
+	 * Also, this does NOT account for whether the "To" field is empty or not. Some messengers may allow the "To" field
456
+	 * to be empty (@see EE_Messenger::allow_empty_to_field()) so an empty "To" field is not always an indicator of
457
+	 * whether a context is "active" or not.
458
+	 *
459
+	 * @param $context
460
+	 * @return bool
461
+	 * @throws EE_Error
462
+	 * @throws InvalidIdentifierException
463
+	 */
464
+	public function is_context_active($context)
465
+	{
466
+		$this->validate_context($context);
467
+		return filter_var(
468
+			$this->get_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, true, true),
469
+			FILTER_VALIDATE_BOOLEAN
470
+		);
471
+	}
472
+
473
+
474
+	/**
475
+	 * Validates the incoming context to verify it matches a registered context for the related message type.
476
+	 *
477
+	 * @param string $context
478
+	 * @throws EE_Error
479
+	 * @throws InvalidIdentifierException
480
+	 */
481
+	public function validate_context($context)
482
+	{
483
+		$contexts = $this->contexts_config();
484
+		if (! isset($contexts[ $context ])) {
485
+			throw new InvalidIdentifierException(
486
+				'',
487
+				'',
488
+				sprintf(
489
+					esc_html__(
490
+						'An invalid string identifying a context was provided.  "%1$s" was received, and one of "%2$s" was expected.',
491
+						'event_espresso'
492
+					),
493
+					$context,
494
+					implode(',', array_keys($contexts))
495
+				)
496
+			);
497
+		}
498
+	}
499 499
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -48,7 +48,7 @@  discard block
 block discarded – undo
48 48
      */
49 49
     public function set_message_type($message_type = false)
50 50
     {
51
-        if (! $message_type) {
51
+        if ( ! $message_type) {
52 52
             throw new EE_Error(esc_html__('Missing required value for the message_type parameter', 'event_espresso'));
53 53
         }
54 54
         $this->set('MTP_message_type', $message_type);
@@ -61,7 +61,7 @@  discard block
 block discarded – undo
61 61
      */
62 62
     public function set_messenger($messenger = false)
63 63
     {
64
-        if (! $messenger) {
64
+        if ( ! $messenger) {
65 65
             throw new EE_Error(esc_html__('Missing required value for the messenger parameter', 'event_espresso'));
66 66
         }
67 67
         $this->set('MTP_messenger', $messenger);
@@ -74,7 +74,7 @@  discard block
 block discarded – undo
74 74
      */
75 75
     public function set_group_template_id($GRP_ID = false)
76 76
     {
77
-        if (! $GRP_ID) {
77
+        if ( ! $GRP_ID) {
78 78
             throw new EE_Error(
79 79
                 esc_html__(
80 80
                     'Missing required value for the message template group id',
@@ -290,7 +290,7 @@  discard block
 block discarded – undo
290 290
         }
291 291
         // note contexts could have CHECKBOX fields per context. So we return the objects indexed by context AND field.
292 292
         foreach ($mtps as $mtp) {
293
-            $mtps_arr[ $mtp->get('MTP_context') ][ $mtp->get('MTP_template_field') ] = $mtp;
293
+            $mtps_arr[$mtp->get('MTP_context')][$mtp->get('MTP_template_field')] = $mtp;
294 294
         }
295 295
         return $mtps_arr;
296 296
     }
@@ -430,7 +430,7 @@  discard block
 block discarded – undo
430 430
     public function deactivate_context($context)
431 431
     {
432 432
         $this->validate_context($context);
433
-        return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, false);
433
+        return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX.$context, false);
434 434
     }
435 435
 
436 436
 
@@ -445,7 +445,7 @@  discard block
 block discarded – undo
445 445
     public function activate_context($context)
446 446
     {
447 447
         $this->validate_context($context);
448
-        return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, true);
448
+        return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX.$context, true);
449 449
     }
450 450
 
451 451
 
@@ -465,7 +465,7 @@  discard block
 block discarded – undo
465 465
     {
466 466
         $this->validate_context($context);
467 467
         return filter_var(
468
-            $this->get_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, true, true),
468
+            $this->get_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX.$context, true, true),
469 469
             FILTER_VALIDATE_BOOLEAN
470 470
         );
471 471
     }
@@ -481,7 +481,7 @@  discard block
 block discarded – undo
481 481
     public function validate_context($context)
482 482
     {
483 483
         $contexts = $this->contexts_config();
484
-        if (! isset($contexts[ $context ])) {
484
+        if ( ! isset($contexts[$context])) {
485 485
             throw new InvalidIdentifierException(
486 486
                 '',
487 487
                 '',
Please login to merge, or discard this patch.
core/db_classes/EE_Message_Template.class.php 2 patches
Indentation   +169 added lines, -169 removed lines patch added patch discarded remove patch
@@ -13,173 +13,173 @@
 block discarded – undo
13 13
 class EE_Message_Template extends EE_Base_Class
14 14
 {
15 15
 
16
-    /**
17
-     * @param array  $props_n_values
18
-     * @param string $timezone
19
-     * @return EE_Message_Template|mixed
20
-     */
21
-    public static function new_instance($props_n_values = array(), $timezone = '')
22
-    {
23
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone);
24
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone);
25
-    }
26
-
27
-
28
-    /**
29
-     * @param array  $props_n_values
30
-     * @param string $timezone
31
-     * @return EE_Message_Template
32
-     */
33
-    public static function new_instance_from_db($props_n_values = array(), $timezone = '')
34
-    {
35
-        return new self($props_n_values, true, $timezone);
36
-    }
37
-
38
-
39
-    /**
40
-     * @param bool $GRP_ID
41
-     * @throws EE_Error
42
-     */
43
-    public function set_group_template_id($GRP_ID = false)
44
-    {
45
-        if (! $GRP_ID) {
46
-            throw new EE_Error(__('Missing required value for the message template group id', 'event_espresso'));
47
-        }
48
-        $this->set('GRP_ID', $GRP_ID);
49
-    }
50
-
51
-
52
-    /**
53
-     * get Group ID
54
-     *
55
-     * @access public
56
-     * @return int
57
-     */
58
-    public function GRP_ID()
59
-    {
60
-        return $this->get('GRP_ID');
61
-    }
62
-
63
-
64
-    /**
65
-     * get User ID
66
-     *
67
-     * @access public
68
-     * @return int
69
-     */
70
-    public function user()
71
-    {
72
-        return $this->get_first_related('Message_Template_Group')->get('MTP_user_id');
73
-    }
74
-
75
-
76
-    /**
77
-     * get Message Messenger
78
-     *
79
-     * @access public
80
-     * @return string
81
-     */
82
-    public function messenger()
83
-    {
84
-        return $this->get_first_related('Message_Template_Group')->messenger();
85
-    }
86
-
87
-
88
-    /**
89
-     * get Message Messenger OBJECT
90
-     *
91
-     * @access public
92
-     * @return object Messenger Object for the given messenger
93
-     */
94
-    public function messenger_obj()
95
-    {
96
-        return $this->get_first_related('Message_Template_Group')->messenger_obj();
97
-    }
98
-
99
-
100
-    /**
101
-     * get Message Type
102
-     *
103
-     * @access public
104
-     * @return string
105
-     */
106
-    public function message_type()
107
-    {
108
-        return $this->get_first_related('Message_Template_Group')->message_type();
109
-    }
110
-
111
-
112
-    /**
113
-     * get Message type OBJECT
114
-     *
115
-     * @access public
116
-     * @return object  Message Type object for the given message type
117
-     */
118
-    public function message_type_obj()
119
-    {
120
-        return $this->get_first_related('Message_Template_Group')->message_type_obj();
121
-    }
122
-
123
-
124
-    /**
125
-     * This returns the set context array configured in the message type object
126
-     *
127
-     * @access public
128
-     * @return array array of contexts and their configuration.
129
-     */
130
-    public function contexts_config()
131
-    {
132
-        return $this->get_first_related('Message_Template_Group')->contexts_config();
133
-    }
134
-
135
-
136
-    /**
137
-     * This returns the context_label for contexts as set in the message type object
138
-     *
139
-     * @access public
140
-     * @return string label for "context"
141
-     */
142
-    public function context_label()
143
-    {
144
-        return $this->get_first_related('Message_Template_Group')->context_label();
145
-    }
146
-
147
-
148
-    /**
149
-     * this returns if the template group this template belongs to is global
150
-     *
151
-     * @return boolean true if it is, false if it isn't
152
-     */
153
-    public function is_global()
154
-    {
155
-        return $this->get_first_related('Message_Template_Group')->is_global();
156
-    }
157
-
158
-
159
-    /**
160
-     * this returns if the template group this template belongs to is active (i.e. turned "on" or not)
161
-     *
162
-     * @return boolean true if it is, false if it isn't
163
-     */
164
-    public function is_active()
165
-    {
166
-        return $this->get_first_related('Message_Template_Group')->is_active();
167
-    }
168
-
169
-
170
-    /**
171
-     * This will return an array of shortcodes => labels from the messenger and message_type objects associated with
172
-     * this template.
173
-     *
174
-     * @access public
175
-     * @param string $context what context we're going to return shortcodes for
176
-     * @param array  $fields  what fields we're returning valid shortcodes for.  If empty then we assume all fields are
177
-     *                        to be merged and returned.
178
-     * @return mixed (array|bool) an array of shortcodes in the format array( '[shortcode] => 'label') OR FALSE if no
179
-     *               shortcodes found.
180
-     */
181
-    public function get_shortcodes($context, $fields = array())
182
-    {
183
-        return $this->get_first_related('Message_Template_Group')->get_shortcodes($context, $fields);
184
-    }
16
+	/**
17
+	 * @param array  $props_n_values
18
+	 * @param string $timezone
19
+	 * @return EE_Message_Template|mixed
20
+	 */
21
+	public static function new_instance($props_n_values = array(), $timezone = '')
22
+	{
23
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone);
24
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone);
25
+	}
26
+
27
+
28
+	/**
29
+	 * @param array  $props_n_values
30
+	 * @param string $timezone
31
+	 * @return EE_Message_Template
32
+	 */
33
+	public static function new_instance_from_db($props_n_values = array(), $timezone = '')
34
+	{
35
+		return new self($props_n_values, true, $timezone);
36
+	}
37
+
38
+
39
+	/**
40
+	 * @param bool $GRP_ID
41
+	 * @throws EE_Error
42
+	 */
43
+	public function set_group_template_id($GRP_ID = false)
44
+	{
45
+		if (! $GRP_ID) {
46
+			throw new EE_Error(__('Missing required value for the message template group id', 'event_espresso'));
47
+		}
48
+		$this->set('GRP_ID', $GRP_ID);
49
+	}
50
+
51
+
52
+	/**
53
+	 * get Group ID
54
+	 *
55
+	 * @access public
56
+	 * @return int
57
+	 */
58
+	public function GRP_ID()
59
+	{
60
+		return $this->get('GRP_ID');
61
+	}
62
+
63
+
64
+	/**
65
+	 * get User ID
66
+	 *
67
+	 * @access public
68
+	 * @return int
69
+	 */
70
+	public function user()
71
+	{
72
+		return $this->get_first_related('Message_Template_Group')->get('MTP_user_id');
73
+	}
74
+
75
+
76
+	/**
77
+	 * get Message Messenger
78
+	 *
79
+	 * @access public
80
+	 * @return string
81
+	 */
82
+	public function messenger()
83
+	{
84
+		return $this->get_first_related('Message_Template_Group')->messenger();
85
+	}
86
+
87
+
88
+	/**
89
+	 * get Message Messenger OBJECT
90
+	 *
91
+	 * @access public
92
+	 * @return object Messenger Object for the given messenger
93
+	 */
94
+	public function messenger_obj()
95
+	{
96
+		return $this->get_first_related('Message_Template_Group')->messenger_obj();
97
+	}
98
+
99
+
100
+	/**
101
+	 * get Message Type
102
+	 *
103
+	 * @access public
104
+	 * @return string
105
+	 */
106
+	public function message_type()
107
+	{
108
+		return $this->get_first_related('Message_Template_Group')->message_type();
109
+	}
110
+
111
+
112
+	/**
113
+	 * get Message type OBJECT
114
+	 *
115
+	 * @access public
116
+	 * @return object  Message Type object for the given message type
117
+	 */
118
+	public function message_type_obj()
119
+	{
120
+		return $this->get_first_related('Message_Template_Group')->message_type_obj();
121
+	}
122
+
123
+
124
+	/**
125
+	 * This returns the set context array configured in the message type object
126
+	 *
127
+	 * @access public
128
+	 * @return array array of contexts and their configuration.
129
+	 */
130
+	public function contexts_config()
131
+	{
132
+		return $this->get_first_related('Message_Template_Group')->contexts_config();
133
+	}
134
+
135
+
136
+	/**
137
+	 * This returns the context_label for contexts as set in the message type object
138
+	 *
139
+	 * @access public
140
+	 * @return string label for "context"
141
+	 */
142
+	public function context_label()
143
+	{
144
+		return $this->get_first_related('Message_Template_Group')->context_label();
145
+	}
146
+
147
+
148
+	/**
149
+	 * this returns if the template group this template belongs to is global
150
+	 *
151
+	 * @return boolean true if it is, false if it isn't
152
+	 */
153
+	public function is_global()
154
+	{
155
+		return $this->get_first_related('Message_Template_Group')->is_global();
156
+	}
157
+
158
+
159
+	/**
160
+	 * this returns if the template group this template belongs to is active (i.e. turned "on" or not)
161
+	 *
162
+	 * @return boolean true if it is, false if it isn't
163
+	 */
164
+	public function is_active()
165
+	{
166
+		return $this->get_first_related('Message_Template_Group')->is_active();
167
+	}
168
+
169
+
170
+	/**
171
+	 * This will return an array of shortcodes => labels from the messenger and message_type objects associated with
172
+	 * this template.
173
+	 *
174
+	 * @access public
175
+	 * @param string $context what context we're going to return shortcodes for
176
+	 * @param array  $fields  what fields we're returning valid shortcodes for.  If empty then we assume all fields are
177
+	 *                        to be merged and returned.
178
+	 * @return mixed (array|bool) an array of shortcodes in the format array( '[shortcode] => 'label') OR FALSE if no
179
+	 *               shortcodes found.
180
+	 */
181
+	public function get_shortcodes($context, $fields = array())
182
+	{
183
+		return $this->get_first_related('Message_Template_Group')->get_shortcodes($context, $fields);
184
+	}
185 185
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -42,7 +42,7 @@
 block discarded – undo
42 42
      */
43 43
     public function set_group_template_id($GRP_ID = false)
44 44
     {
45
-        if (! $GRP_ID) {
45
+        if ( ! $GRP_ID) {
46 46
             throw new EE_Error(__('Missing required value for the message template group id', 'event_espresso'));
47 47
         }
48 48
         $this->set('GRP_ID', $GRP_ID);
Please login to merge, or discard this patch.
core/db_classes/EE_Ticket_Price.class.php 1 patch
Indentation   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -11,25 +11,25 @@
 block discarded – undo
11 11
 class EE_Ticket_Price extends EE_Base_Class
12 12
 {
13 13
 
14
-    /**
15
-     * @param array  $props_n_values
16
-     * @param string $timezone
17
-     * @return EE_Ticket_Price|mixed
18
-     */
19
-    public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array())
20
-    {
21
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
22
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
23
-    }
14
+	/**
15
+	 * @param array  $props_n_values
16
+	 * @param string $timezone
17
+	 * @return EE_Ticket_Price|mixed
18
+	 */
19
+	public static function new_instance($props_n_values = array(), $timezone = '', $date_formats = array())
20
+	{
21
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
22
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
23
+	}
24 24
 
25 25
 
26
-    /**
27
-     * @param array  $props_n_values
28
-     * @param string $timezone
29
-     * @return EE_Ticket_Price
30
-     */
31
-    public static function new_instance_from_db($props_n_values = array(), $timezone = '')
32
-    {
33
-        return new self($props_n_values, true, $timezone);
34
-    }
26
+	/**
27
+	 * @param array  $props_n_values
28
+	 * @param string $timezone
29
+	 * @return EE_Ticket_Price
30
+	 */
31
+	public static function new_instance_from_db($props_n_values = array(), $timezone = '')
32
+	{
33
+		return new self($props_n_values, true, $timezone);
34
+	}
35 35
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Ticket_Template.class.php 1 patch
Indentation   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -12,25 +12,25 @@
 block discarded – undo
12 12
 class EE_Ticket_Template extends EE_Base_Class
13 13
 {
14 14
 
15
-    /**
16
-     * @param array  $props_n_values
17
-     * @param string $timezone
18
-     * @return EE_Ticket_Template|mixed
19
-     */
20
-    public static function new_instance($props_n_values = array(), $timezone = '')
21
-    {
22
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone);
23
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone);
24
-    }
15
+	/**
16
+	 * @param array  $props_n_values
17
+	 * @param string $timezone
18
+	 * @return EE_Ticket_Template|mixed
19
+	 */
20
+	public static function new_instance($props_n_values = array(), $timezone = '')
21
+	{
22
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone);
23
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone);
24
+	}
25 25
 
26 26
 
27
-    /**
28
-     * @param array  $props_n_values
29
-     * @param string $timezone
30
-     * @return EE_Ticket_Template
31
-     */
32
-    public static function new_instance_from_db($props_n_values = array(), $timezone = '')
33
-    {
34
-        return new self($props_n_values, true, $timezone);
35
-    }
27
+	/**
28
+	 * @param array  $props_n_values
29
+	 * @param string $timezone
30
+	 * @return EE_Ticket_Template
31
+	 */
32
+	public static function new_instance_from_db($props_n_values = array(), $timezone = '')
33
+	{
34
+		return new self($props_n_values, true, $timezone);
35
+	}
36 36
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Line_Item.class.php 2 patches
Indentation   +1426 added lines, -1426 removed lines patch added patch discarded remove patch
@@ -14,1430 +14,1430 @@
 block discarded – undo
14 14
 class EE_Line_Item extends EE_Base_Class implements EEI_Line_Item
15 15
 {
16 16
 
17
-    /**
18
-     * for children line items (currently not a normal relation)
19
-     *
20
-     * @type EE_Line_Item[]
21
-     */
22
-    protected $_children = array();
23
-
24
-    /**
25
-     * for the parent line item
26
-     *
27
-     * @var EE_Line_Item
28
-     */
29
-    protected $_parent;
30
-
31
-
32
-    /**
33
-     *
34
-     * @param array  $props_n_values          incoming values
35
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
36
-     *                                        used.)
37
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
38
-     *                                        date_format and the second value is the time format
39
-     * @return EE_Line_Item
40
-     * @throws EE_Error
41
-     */
42
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
43
-    {
44
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
45
-        return $has_object
46
-            ? $has_object
47
-            : new self($props_n_values, false, $timezone);
48
-    }
49
-
50
-
51
-    /**
52
-     * @param array  $props_n_values  incoming values from the database
53
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
54
-     *                                the website will be used.
55
-     * @return EE_Line_Item
56
-     * @throws EE_Error
57
-     */
58
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
59
-    {
60
-        return new self($props_n_values, true, $timezone);
61
-    }
62
-
63
-
64
-    /**
65
-     * Adds some defaults if they're not specified
66
-     *
67
-     * @param array  $fieldValues
68
-     * @param bool   $bydb
69
-     * @param string $timezone
70
-     * @throws EE_Error
71
-     */
72
-    protected function __construct($fieldValues = array(), $bydb = false, $timezone = '')
73
-    {
74
-        parent::__construct($fieldValues, $bydb, $timezone);
75
-        if (! $this->get('LIN_code')) {
76
-            $this->set_code($this->generate_code());
77
-        }
78
-    }
79
-
80
-
81
-    /**
82
-     * Gets ID
83
-     *
84
-     * @return int
85
-     * @throws EE_Error
86
-     */
87
-    public function ID()
88
-    {
89
-        return $this->get('LIN_ID');
90
-    }
91
-
92
-
93
-    /**
94
-     * Gets TXN_ID
95
-     *
96
-     * @return int
97
-     * @throws EE_Error
98
-     */
99
-    public function TXN_ID()
100
-    {
101
-        return $this->get('TXN_ID');
102
-    }
103
-
104
-
105
-    /**
106
-     * Sets TXN_ID
107
-     *
108
-     * @param int $TXN_ID
109
-     * @throws EE_Error
110
-     */
111
-    public function set_TXN_ID($TXN_ID)
112
-    {
113
-        $this->set('TXN_ID', $TXN_ID);
114
-    }
115
-
116
-
117
-    /**
118
-     * Gets name
119
-     *
120
-     * @return string
121
-     * @throws EE_Error
122
-     */
123
-    public function name()
124
-    {
125
-        $name = $this->get('LIN_name');
126
-        if (! $name) {
127
-            $name = ucwords(str_replace('-', ' ', $this->type()));
128
-        }
129
-        return $name;
130
-    }
131
-
132
-
133
-    /**
134
-     * Sets name
135
-     *
136
-     * @param string $name
137
-     * @throws EE_Error
138
-     */
139
-    public function set_name($name)
140
-    {
141
-        $this->set('LIN_name', $name);
142
-    }
143
-
144
-
145
-    /**
146
-     * Gets desc
147
-     *
148
-     * @return string
149
-     * @throws EE_Error
150
-     */
151
-    public function desc()
152
-    {
153
-        return $this->get('LIN_desc');
154
-    }
155
-
156
-
157
-    /**
158
-     * Sets desc
159
-     *
160
-     * @param string $desc
161
-     * @throws EE_Error
162
-     */
163
-    public function set_desc($desc)
164
-    {
165
-        $this->set('LIN_desc', $desc);
166
-    }
167
-
168
-
169
-    /**
170
-     * Gets quantity
171
-     *
172
-     * @return int
173
-     * @throws EE_Error
174
-     */
175
-    public function quantity()
176
-    {
177
-        return $this->get('LIN_quantity');
178
-    }
179
-
180
-
181
-    /**
182
-     * Sets quantity
183
-     *
184
-     * @param int $quantity
185
-     * @throws EE_Error
186
-     */
187
-    public function set_quantity($quantity)
188
-    {
189
-        $this->set('LIN_quantity', max($quantity, 0));
190
-    }
191
-
192
-
193
-    /**
194
-     * Gets item_id
195
-     *
196
-     * @return string
197
-     * @throws EE_Error
198
-     */
199
-    public function OBJ_ID()
200
-    {
201
-        return $this->get('OBJ_ID');
202
-    }
203
-
204
-
205
-    /**
206
-     * Sets item_id
207
-     *
208
-     * @param string $item_id
209
-     * @throws EE_Error
210
-     */
211
-    public function set_OBJ_ID($item_id)
212
-    {
213
-        $this->set('OBJ_ID', $item_id);
214
-    }
215
-
216
-
217
-    /**
218
-     * Gets item_type
219
-     *
220
-     * @return string
221
-     * @throws EE_Error
222
-     */
223
-    public function OBJ_type()
224
-    {
225
-        return $this->get('OBJ_type');
226
-    }
227
-
228
-
229
-    /**
230
-     * Gets item_type
231
-     *
232
-     * @return string
233
-     * @throws EE_Error
234
-     */
235
-    public function OBJ_type_i18n()
236
-    {
237
-        $obj_type = $this->OBJ_type();
238
-        switch ($obj_type) {
239
-            case 'Event':
240
-                $obj_type = __('Event', 'event_espresso');
241
-                break;
242
-            case 'Price':
243
-                $obj_type = __('Price', 'event_espresso');
244
-                break;
245
-            case 'Promotion':
246
-                $obj_type = __('Promotion', 'event_espresso');
247
-                break;
248
-            case 'Ticket':
249
-                $obj_type = __('Ticket', 'event_espresso');
250
-                break;
251
-            case 'Transaction':
252
-                $obj_type = __('Transaction', 'event_espresso');
253
-                break;
254
-        }
255
-        return apply_filters('FHEE__EE_Line_Item__OBJ_type_i18n', $obj_type, $this);
256
-    }
257
-
258
-
259
-    /**
260
-     * Sets item_type
261
-     *
262
-     * @param string $OBJ_type
263
-     * @throws EE_Error
264
-     */
265
-    public function set_OBJ_type($OBJ_type)
266
-    {
267
-        $this->set('OBJ_type', $OBJ_type);
268
-    }
269
-
270
-
271
-    /**
272
-     * Gets unit_price
273
-     *
274
-     * @return float
275
-     * @throws EE_Error
276
-     */
277
-    public function unit_price()
278
-    {
279
-        return $this->get('LIN_unit_price');
280
-    }
281
-
282
-
283
-    /**
284
-     * Sets unit_price
285
-     *
286
-     * @param float $unit_price
287
-     * @throws EE_Error
288
-     */
289
-    public function set_unit_price($unit_price)
290
-    {
291
-        $this->set('LIN_unit_price', $unit_price);
292
-    }
293
-
294
-
295
-    /**
296
-     * Checks if this item is a percentage modifier or not
297
-     *
298
-     * @return boolean
299
-     * @throws EE_Error
300
-     */
301
-    public function is_percent()
302
-    {
303
-        if ($this->is_tax_sub_total()) {
304
-            // tax subtotals HAVE a percent on them, that percentage only applies
305
-            // to taxable items, so its' an exception. Treat it like a flat line item
306
-            return false;
307
-        }
308
-        $unit_price = abs($this->get('LIN_unit_price'));
309
-        $percent = abs($this->get('LIN_percent'));
310
-        if ($unit_price < .001 && $percent) {
311
-            return true;
312
-        }
313
-        if ($unit_price >= .001 && ! $percent) {
314
-            return false;
315
-        }
316
-        if ($unit_price >= .001 && $percent) {
317
-            throw new EE_Error(
318
-                sprintf(
319
-                    esc_html__('A Line Item can not have a unit price of (%s) AND a percent (%s)!', 'event_espresso'),
320
-                    $unit_price,
321
-                    $percent
322
-                )
323
-            );
324
-        }
325
-        // if they're both 0, assume its not a percent item
326
-        return false;
327
-    }
328
-
329
-
330
-    /**
331
-     * Gets percent (between 100-.001)
332
-     *
333
-     * @return float
334
-     * @throws EE_Error
335
-     */
336
-    public function percent()
337
-    {
338
-        return $this->get('LIN_percent');
339
-    }
340
-
341
-
342
-    /**
343
-     * Sets percent (between 100-0.01)
344
-     *
345
-     * @param float $percent
346
-     * @throws EE_Error
347
-     */
348
-    public function set_percent($percent)
349
-    {
350
-        $this->set('LIN_percent', $percent);
351
-    }
352
-
353
-
354
-    /**
355
-     * Gets total
356
-     *
357
-     * @return float
358
-     * @throws EE_Error
359
-     */
360
-    public function total()
361
-    {
362
-        return $this->get('LIN_total');
363
-    }
364
-
365
-
366
-    /**
367
-     * Sets total
368
-     *
369
-     * @param float $total
370
-     * @throws EE_Error
371
-     */
372
-    public function set_total($total)
373
-    {
374
-        $this->set('LIN_total', $total);
375
-    }
376
-
377
-
378
-    /**
379
-     * Gets order
380
-     *
381
-     * @return int
382
-     * @throws EE_Error
383
-     */
384
-    public function order()
385
-    {
386
-        return $this->get('LIN_order');
387
-    }
388
-
389
-
390
-    /**
391
-     * Sets order
392
-     *
393
-     * @param int $order
394
-     * @throws EE_Error
395
-     */
396
-    public function set_order($order)
397
-    {
398
-        $this->set('LIN_order', $order);
399
-    }
400
-
401
-
402
-    /**
403
-     * Gets parent
404
-     *
405
-     * @return int
406
-     * @throws EE_Error
407
-     */
408
-    public function parent_ID()
409
-    {
410
-        return $this->get('LIN_parent');
411
-    }
412
-
413
-
414
-    /**
415
-     * Sets parent
416
-     *
417
-     * @param int $parent
418
-     * @throws EE_Error
419
-     */
420
-    public function set_parent_ID($parent)
421
-    {
422
-        $this->set('LIN_parent', $parent);
423
-    }
424
-
425
-
426
-    /**
427
-     * Gets type
428
-     *
429
-     * @return string
430
-     * @throws EE_Error
431
-     */
432
-    public function type()
433
-    {
434
-        return $this->get('LIN_type');
435
-    }
436
-
437
-
438
-    /**
439
-     * Sets type
440
-     *
441
-     * @param string $type
442
-     * @throws EE_Error
443
-     */
444
-    public function set_type($type)
445
-    {
446
-        $this->set('LIN_type', $type);
447
-    }
448
-
449
-
450
-    /**
451
-     * Gets the line item of which this item is a composite. Eg, if this is a subtotal, the parent might be a total\
452
-     * If this line item is saved to the DB, fetches the parent from the DB. However, if this line item isn't in the DB
453
-     * it uses its cached reference to its parent line item (which would have been set by `EE_Line_Item::set_parent()`
454
-     * or indirectly by `EE_Line_item::add_child_line_item()`)
455
-     *
456
-     * @return EE_Base_Class|EE_Line_Item
457
-     * @throws EE_Error
458
-     */
459
-    public function parent()
460
-    {
461
-        return $this->ID()
462
-            ? $this->get_model()->get_one_by_ID($this->parent_ID())
463
-            : $this->_parent;
464
-    }
465
-
466
-
467
-    /**
468
-     * Gets ALL the children of this line item (ie, all the parts that contribute towards this total).
469
-     *
470
-     * @return EE_Base_Class[]|EE_Line_Item[]
471
-     * @throws EE_Error
472
-     */
473
-    public function children()
474
-    {
475
-        if ($this->ID()) {
476
-            return $this->get_model()->get_all(
477
-                array(
478
-                    array('LIN_parent' => $this->ID()),
479
-                    'order_by' => array('LIN_order' => 'ASC'),
480
-                )
481
-            );
482
-        }
483
-        if (! is_array($this->_children)) {
484
-            $this->_children = array();
485
-        }
486
-        return $this->_children;
487
-    }
488
-
489
-
490
-    /**
491
-     * Gets code
492
-     *
493
-     * @return string
494
-     * @throws EE_Error
495
-     */
496
-    public function code()
497
-    {
498
-        return $this->get('LIN_code');
499
-    }
500
-
501
-
502
-    /**
503
-     * Sets code
504
-     *
505
-     * @param string $code
506
-     * @throws EE_Error
507
-     */
508
-    public function set_code($code)
509
-    {
510
-        $this->set('LIN_code', $code);
511
-    }
512
-
513
-
514
-    /**
515
-     * Gets is_taxable
516
-     *
517
-     * @return boolean
518
-     * @throws EE_Error
519
-     */
520
-    public function is_taxable()
521
-    {
522
-        return $this->get('LIN_is_taxable');
523
-    }
524
-
525
-
526
-    /**
527
-     * Sets is_taxable
528
-     *
529
-     * @param boolean $is_taxable
530
-     * @throws EE_Error
531
-     */
532
-    public function set_is_taxable($is_taxable)
533
-    {
534
-        $this->set('LIN_is_taxable', $is_taxable);
535
-    }
536
-
537
-
538
-    /**
539
-     * Gets the object that this model-joins-to.
540
-     * returns one of the model objects that the field OBJ_ID can point to... see the 'OBJ_ID' field on
541
-     * EEM_Promotion_Object
542
-     *
543
-     *        Eg, if this line item join model object is for a ticket, this will return the EE_Ticket object
544
-     *
545
-     * @return EE_Base_Class | NULL
546
-     * @throws EE_Error
547
-     */
548
-    public function get_object()
549
-    {
550
-        $model_name_of_related_obj = $this->OBJ_type();
551
-        return $this->get_model()->has_relation($model_name_of_related_obj)
552
-            ? $this->get_first_related($model_name_of_related_obj)
553
-            : null;
554
-    }
555
-
556
-
557
-    /**
558
-     * Like EE_Line_Item::get_object(), but can only ever actually return an EE_Ticket.
559
-     * (IE, if this line item is for a price or something else, will return NULL)
560
-     *
561
-     * @param array $query_params
562
-     * @return EE_Base_Class|EE_Ticket
563
-     * @throws EE_Error
564
-     */
565
-    public function ticket($query_params = array())
566
-    {
567
-        // we're going to assume that when this method is called we always want to receive the attached ticket EVEN if that ticket is archived.  This can be overridden via the incoming $query_params argument
568
-        $remove_defaults = array('default_where_conditions' => 'none');
569
-        $query_params = array_merge($remove_defaults, $query_params);
570
-        return $this->get_first_related('Ticket', $query_params);
571
-    }
572
-
573
-
574
-    /**
575
-     * Gets the EE_Datetime that's related to the ticket, IF this is for a ticket
576
-     *
577
-     * @return EE_Datetime | NULL
578
-     * @throws EE_Error
579
-     */
580
-    public function get_ticket_datetime()
581
-    {
582
-        if ($this->OBJ_type() === 'Ticket') {
583
-            $ticket = $this->ticket();
584
-            if ($ticket instanceof EE_Ticket) {
585
-                $datetime = $ticket->first_datetime();
586
-                if ($datetime instanceof EE_Datetime) {
587
-                    return $datetime;
588
-                }
589
-            }
590
-        }
591
-        return null;
592
-    }
593
-
594
-
595
-    /**
596
-     * Gets the event's name that's related to the ticket, if this is for
597
-     * a ticket
598
-     *
599
-     * @return string
600
-     * @throws EE_Error
601
-     */
602
-    public function ticket_event_name()
603
-    {
604
-        $event_name = esc_html__('Unknown', 'event_espresso');
605
-        $event = $this->ticket_event();
606
-        if ($event instanceof EE_Event) {
607
-            $event_name = $event->name();
608
-        }
609
-        return $event_name;
610
-    }
611
-
612
-
613
-    /**
614
-     * Gets the event that's related to the ticket, if this line item represents a ticket.
615
-     *
616
-     * @return EE_Event|null
617
-     * @throws EE_Error
618
-     */
619
-    public function ticket_event()
620
-    {
621
-        $event = null;
622
-        $ticket = $this->ticket();
623
-        if ($ticket instanceof EE_Ticket) {
624
-            $datetime = $ticket->first_datetime();
625
-            if ($datetime instanceof EE_Datetime) {
626
-                $event = $datetime->event();
627
-            }
628
-        }
629
-        return $event;
630
-    }
631
-
632
-
633
-    /**
634
-     * Gets the first datetime for this lien item, assuming it's for a ticket
635
-     *
636
-     * @param string $date_format
637
-     * @param string $time_format
638
-     * @return string
639
-     * @throws EE_Error
640
-     */
641
-    public function ticket_datetime_start($date_format = '', $time_format = '')
642
-    {
643
-        $first_datetime_string = esc_html__('Unknown', 'event_espresso');
644
-        $datetime = $this->get_ticket_datetime();
645
-        if ($datetime) {
646
-            $first_datetime_string = $datetime->start_date_and_time($date_format, $time_format);
647
-        }
648
-        return $first_datetime_string;
649
-    }
650
-
651
-
652
-    /**
653
-     * Adds the line item as a child to this line item. If there is another child line
654
-     * item with the same LIN_code, it is overwritten by this new one
655
-     *
656
-     * @param EEI_Line_Item $line_item
657
-     * @param bool          $set_order
658
-     * @return bool success
659
-     * @throws EE_Error
660
-     */
661
-    public function add_child_line_item(EEI_Line_Item $line_item, $set_order = true)
662
-    {
663
-        // should we calculate the LIN_order for this line item ?
664
-        if ($set_order || $line_item->order() === null) {
665
-            $line_item->set_order(count($this->children()));
666
-        }
667
-        if ($this->ID()) {
668
-            // check for any duplicate line items (with the same code), if so, this replaces it
669
-            $line_item_with_same_code = $this->get_child_line_item($line_item->code());
670
-            if ($line_item_with_same_code instanceof EE_Line_Item && $line_item_with_same_code !== $line_item) {
671
-                $this->delete_child_line_item($line_item_with_same_code->code());
672
-            }
673
-            $line_item->set_parent_ID($this->ID());
674
-            if ($this->TXN_ID()) {
675
-                $line_item->set_TXN_ID($this->TXN_ID());
676
-            }
677
-            return $line_item->save();
678
-        }
679
-        $this->_children[ $line_item->code() ] = $line_item;
680
-        if ($line_item->parent() !== $this) {
681
-            $line_item->set_parent($this);
682
-        }
683
-        return true;
684
-    }
685
-
686
-
687
-    /**
688
-     * Similar to EE_Base_Class::_add_relation_to, except this isn't a normal relation.
689
-     * If this line item is saved to the DB, this is just a wrapper for set_parent_ID() and save()
690
-     * However, if this line item is NOT saved to the DB, this just caches the parent on
691
-     * the EE_Line_Item::_parent property.
692
-     *
693
-     * @param EE_Line_Item $line_item
694
-     * @throws EE_Error
695
-     */
696
-    public function set_parent($line_item)
697
-    {
698
-        if ($this->ID()) {
699
-            if (! $line_item->ID()) {
700
-                $line_item->save();
701
-            }
702
-            $this->set_parent_ID($line_item->ID());
703
-            $this->save();
704
-        } else {
705
-            $this->_parent = $line_item;
706
-            $this->set_parent_ID($line_item->ID());
707
-        }
708
-    }
709
-
710
-
711
-    /**
712
-     * Gets the child line item as specified by its code. Because this returns an object (by reference)
713
-     * you can modify this child line item and the parent (this object) can know about them
714
-     * because it also has a reference to that line item
715
-     *
716
-     * @param string $code
717
-     * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL
718
-     * @throws EE_Error
719
-     */
720
-    public function get_child_line_item($code)
721
-    {
722
-        if ($this->ID()) {
723
-            return $this->get_model()->get_one(
724
-                array(array('LIN_parent' => $this->ID(), 'LIN_code' => $code))
725
-            );
726
-        }
727
-        return isset($this->_children[ $code ])
728
-            ? $this->_children[ $code ]
729
-            : null;
730
-    }
731
-
732
-
733
-    /**
734
-     * Returns how many items are deleted (or, if this item has not been saved ot the DB yet, just how many it HAD
735
-     * cached on it)
736
-     *
737
-     * @return int
738
-     * @throws EE_Error
739
-     */
740
-    public function delete_children_line_items()
741
-    {
742
-        if ($this->ID()) {
743
-            return $this->get_model()->delete(array(array('LIN_parent' => $this->ID())));
744
-        }
745
-        $count = count($this->_children);
746
-        $this->_children = array();
747
-        return $count;
748
-    }
749
-
750
-
751
-    /**
752
-     * If this line item has been saved to the DB, deletes its child with LIN_code == $code. If this line
753
-     * HAS NOT been saved to the DB, removes the child line item with index $code.
754
-     * Also searches through the child's children for a matching line item. However, once a line item has been found
755
-     * and deleted, stops searching (so if there are line items with duplicate codes, only the first one found will be
756
-     * deleted)
757
-     *
758
-     * @param string $code
759
-     * @param bool   $stop_search_once_found
760
-     * @return int count of items deleted (or simply removed from the line item's cache, if not has not been saved to
761
-     *             the DB yet)
762
-     * @throws EE_Error
763
-     */
764
-    public function delete_child_line_item($code, $stop_search_once_found = true)
765
-    {
766
-        if ($this->ID()) {
767
-            $items_deleted = 0;
768
-            if ($this->code() === $code) {
769
-                $items_deleted += EEH_Line_Item::delete_all_child_items($this);
770
-                $items_deleted += (int) $this->delete();
771
-                if ($stop_search_once_found) {
772
-                    return $items_deleted;
773
-                }
774
-            }
775
-            foreach ($this->children() as $child_line_item) {
776
-                $items_deleted += $child_line_item->delete_child_line_item($code, $stop_search_once_found);
777
-            }
778
-            return $items_deleted;
779
-        }
780
-        if (isset($this->_children[ $code ])) {
781
-            unset($this->_children[ $code ]);
782
-            return 1;
783
-        }
784
-        return 0;
785
-    }
786
-
787
-
788
-    /**
789
-     * If this line item is in the database, is of the type subtotal, and
790
-     * has no children, why do we have it? It should be deleted so this function
791
-     * does that
792
-     *
793
-     * @return boolean
794
-     * @throws EE_Error
795
-     */
796
-    public function delete_if_childless_subtotal()
797
-    {
798
-        if ($this->ID() && $this->type() === EEM_Line_Item::type_sub_total && ! $this->children()) {
799
-            return $this->delete();
800
-        }
801
-        return false;
802
-    }
803
-
804
-
805
-    /**
806
-     * Creates a code and returns a string. doesn't assign the code to this model object
807
-     *
808
-     * @return string
809
-     * @throws EE_Error
810
-     */
811
-    public function generate_code()
812
-    {
813
-        // each line item in the cart requires a unique identifier
814
-        return md5($this->get('OBJ_type') . $this->get('OBJ_ID') . microtime());
815
-    }
816
-
817
-
818
-    /**
819
-     * @return bool
820
-     * @throws EE_Error
821
-     */
822
-    public function is_tax()
823
-    {
824
-        return $this->type() === EEM_Line_Item::type_tax;
825
-    }
826
-
827
-
828
-    /**
829
-     * @return bool
830
-     * @throws EE_Error
831
-     */
832
-    public function is_tax_sub_total()
833
-    {
834
-        return $this->type() === EEM_Line_Item::type_tax_sub_total;
835
-    }
836
-
837
-
838
-    /**
839
-     * @return bool
840
-     * @throws EE_Error
841
-     */
842
-    public function is_line_item()
843
-    {
844
-        return $this->type() === EEM_Line_Item::type_line_item;
845
-    }
846
-
847
-
848
-    /**
849
-     * @return bool
850
-     * @throws EE_Error
851
-     */
852
-    public function is_sub_line_item()
853
-    {
854
-        return $this->type() === EEM_Line_Item::type_sub_line_item;
855
-    }
856
-
857
-
858
-    /**
859
-     * @return bool
860
-     * @throws EE_Error
861
-     */
862
-    public function is_sub_total()
863
-    {
864
-        return $this->type() === EEM_Line_Item::type_sub_total;
865
-    }
866
-
867
-
868
-    /**
869
-     * Whether or not this line item is a cancellation line item
870
-     *
871
-     * @return boolean
872
-     * @throws EE_Error
873
-     */
874
-    public function is_cancellation()
875
-    {
876
-        return EEM_Line_Item::type_cancellation === $this->type();
877
-    }
878
-
879
-
880
-    /**
881
-     * @return bool
882
-     * @throws EE_Error
883
-     */
884
-    public function is_total()
885
-    {
886
-        return $this->type() === EEM_Line_Item::type_total;
887
-    }
888
-
889
-
890
-    /**
891
-     * @return bool
892
-     * @throws EE_Error
893
-     */
894
-    public function is_cancelled()
895
-    {
896
-        return $this->type() === EEM_Line_Item::type_cancellation;
897
-    }
898
-
899
-
900
-    /**
901
-     * @return string like '2, 004.00', formatted according to the localized currency
902
-     * @throws EE_Error
903
-     */
904
-    public function unit_price_no_code()
905
-    {
906
-        return $this->get_pretty('LIN_unit_price', 'no_currency_code');
907
-    }
908
-
909
-
910
-    /**
911
-     * @return string like '2, 004.00', formatted according to the localized currency
912
-     * @throws EE_Error
913
-     */
914
-    public function total_no_code()
915
-    {
916
-        return $this->get_pretty('LIN_total', 'no_currency_code');
917
-    }
918
-
919
-
920
-    /**
921
-     * Gets the final total on this item, taking taxes into account.
922
-     * Has the side-effect of setting the sub-total as it was just calculated.
923
-     * If this is used on a grand-total line item, also updates the transaction's
924
-     * TXN_total (provided this line item is allowed to persist, otherwise we don't
925
-     * want to change a persistable transaction with info from a non-persistent line item)
926
-     *
927
-     * @return float
928
-     * @throws EE_Error
929
-     * @throws InvalidArgumentException
930
-     * @throws InvalidInterfaceException
931
-     * @throws InvalidDataTypeException
932
-     */
933
-    public function recalculate_total_including_taxes()
934
-    {
935
-        $pre_tax_total = $this->recalculate_pre_tax_total();
936
-        $tax_total = $this->recalculate_taxes_and_tax_total();
937
-        $total = $pre_tax_total + $tax_total;
938
-        // no negative totals plz
939
-        $total = max($total, 0);
940
-        $this->set_total($total);
941
-        // only update the related transaction's total
942
-        // if we intend to save this line item and its a grand total
943
-        if ($this->allow_persist() && $this->type() === EEM_Line_Item::type_total
944
-            && $this->transaction()
945
-               instanceof
946
-               EE_Transaction
947
-        ) {
948
-            $this->transaction()->set_total($total);
949
-            if ($this->transaction()->ID()) {
950
-                $this->transaction()->save();
951
-            }
952
-        }
953
-        $this->maybe_save();
954
-        return $total;
955
-    }
956
-
957
-
958
-    /**
959
-     * Recursively goes through all the children and recalculates sub-totals EXCEPT for
960
-     * tax-sub-totals (they're a an odd beast). Updates the 'total' on each line item according to either its
961
-     * unit price * quantity or the total of all its children EXCEPT when we're only calculating the taxable total and
962
-     * when this is called on the grand total
963
-     *
964
-     * @return float
965
-     * @throws InvalidArgumentException
966
-     * @throws InvalidInterfaceException
967
-     * @throws InvalidDataTypeException
968
-     * @throws EE_Error
969
-     */
970
-    public function recalculate_pre_tax_total()
971
-    {
972
-        $total = 0;
973
-        $my_children = $this->children();
974
-        $has_children = ! empty($my_children);
975
-        if ($has_children && $this->is_line_item()) {
976
-            $total = $this->_recalculate_pretax_total_for_line_item($total, $my_children);
977
-        } elseif (! $has_children && ($this->is_sub_line_item() || $this->is_line_item())) {
978
-            $total = $this->unit_price() * $this->quantity();
979
-        } elseif ($this->is_sub_total() || $this->is_total()) {
980
-            $total = $this->_recalculate_pretax_total_for_subtotal($total, $my_children);
981
-        } elseif ($this->is_tax_sub_total() || $this->is_tax() || $this->is_cancelled()) {
982
-            // completely ignore tax totals, tax sub-totals, and cancelled line items, when calculating the pre-tax-total
983
-            return 0;
984
-        }
985
-        // ensure all non-line items and non-sub-line-items have a quantity of 1 (except for Events)
986
-        if (! $this->is_line_item() && ! $this->is_sub_line_item() && ! $this->is_cancellation()
987
-        ) {
988
-            if ($this->OBJ_type() !== 'Event') {
989
-                $this->set_quantity(1);
990
-            }
991
-            if (! $this->is_percent()) {
992
-                $this->set_unit_price($total);
993
-            }
994
-        }
995
-        // we don't want to bother saving grand totals, because that needs to factor in taxes anyways
996
-        // so it ought to be
997
-        if (! $this->is_total()) {
998
-            $this->set_total($total);
999
-            // if not a percent line item, make sure we keep the unit price in sync
1000
-            if ($has_children
1001
-                && $this->is_line_item()
1002
-                && ! $this->is_percent()
1003
-            ) {
1004
-                if ($this->quantity() === 0) {
1005
-                    $new_unit_price = 0;
1006
-                } else {
1007
-                    $new_unit_price = $this->total() / $this->quantity();
1008
-                }
1009
-                $this->set_unit_price($new_unit_price);
1010
-            }
1011
-            $this->maybe_save();
1012
-        }
1013
-        return $total;
1014
-    }
1015
-
1016
-
1017
-    /**
1018
-     * Calculates the pretax total when this line item is a subtotal or total line item.
1019
-     * Basically does a sum-then-round approach (ie, any percent line item that are children
1020
-     * will calculate their total based on the un-rounded total we're working with so far, and
1021
-     * THEN round the result; instead of rounding as we go like with sub-line-items)
1022
-     *
1023
-     * @param float          $calculated_total_so_far
1024
-     * @param EE_Line_Item[] $my_children
1025
-     * @return float
1026
-     * @throws InvalidArgumentException
1027
-     * @throws InvalidInterfaceException
1028
-     * @throws InvalidDataTypeException
1029
-     * @throws EE_Error
1030
-     */
1031
-    protected function _recalculate_pretax_total_for_subtotal($calculated_total_so_far, $my_children = null)
1032
-    {
1033
-        if ($my_children === null) {
1034
-            $my_children = $this->children();
1035
-        }
1036
-        $subtotal_quantity = 0;
1037
-        // get the total of all its children
1038
-        foreach ($my_children as $child_line_item) {
1039
-            if ($child_line_item instanceof EE_Line_Item && ! $child_line_item->is_cancellation()) {
1040
-                // percentage line items are based on total so far
1041
-                if ($child_line_item->is_percent()) {
1042
-                    // round as we go so that the line items add up ok
1043
-                    $percent_total = round(
1044
-                        $calculated_total_so_far * $child_line_item->percent() / 100,
1045
-                        EE_Registry::instance()->CFG->currency->dec_plc
1046
-                    );
1047
-                    $child_line_item->set_total($percent_total);
1048
-                    // so far all percent line items should have a quantity of 1
1049
-                    // (ie, no double percent discounts. Although that might be requested someday)
1050
-                    $child_line_item->set_quantity(1);
1051
-                    $child_line_item->maybe_save();
1052
-                    $calculated_total_so_far += $percent_total;
1053
-                } else {
1054
-                    // verify flat sub-line-item quantities match their parent
1055
-                    if ($child_line_item->is_sub_line_item()) {
1056
-                        $child_line_item->set_quantity($this->quantity());
1057
-                    }
1058
-                    $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total();
1059
-                    $subtotal_quantity += $child_line_item->quantity();
1060
-                }
1061
-            }
1062
-        }
1063
-        if ($this->is_sub_total()) {
1064
-            // no negative totals plz
1065
-            $calculated_total_so_far = max($calculated_total_so_far, 0);
1066
-            $subtotal_quantity = $subtotal_quantity > 0 ? 1 : 0;
1067
-            $this->set_quantity($subtotal_quantity);
1068
-            $this->maybe_save();
1069
-        }
1070
-        return $calculated_total_so_far;
1071
-    }
1072
-
1073
-
1074
-    /**
1075
-     * Calculates the pretax total for a normal line item, in a round-then-sum approach
1076
-     * (where each sub-line-item is applied to the base price for the line item
1077
-     * and the result is immediately rounded, rather than summing all the sub-line-items
1078
-     * then rounding, like we do when recalculating pretax totals on totals and subtotals).
1079
-     *
1080
-     * @param float          $calculated_total_so_far
1081
-     * @param EE_Line_Item[] $my_children
1082
-     * @return float
1083
-     * @throws InvalidArgumentException
1084
-     * @throws InvalidInterfaceException
1085
-     * @throws InvalidDataTypeException
1086
-     * @throws EE_Error
1087
-     */
1088
-    protected function _recalculate_pretax_total_for_line_item($calculated_total_so_far, $my_children = null)
1089
-    {
1090
-        if ($my_children === null) {
1091
-            $my_children = $this->children();
1092
-        }
1093
-        // we need to keep track of the running total for a single item,
1094
-        // because we need to round as we go
1095
-        $unit_price_for_total = 0;
1096
-        $quantity_for_total = 1;
1097
-        // get the total of all its children
1098
-        foreach ($my_children as $child_line_item) {
1099
-            if ($child_line_item instanceof EE_Line_Item && ! $child_line_item->is_cancellation()) {
1100
-                if ($child_line_item->is_percent()) {
1101
-                    // it should be the unit-price-so-far multiplied by teh percent multiplied by the quantity
1102
-                    // not total multiplied by percent, because that ignores rounding along-the-way
1103
-                    $percent_unit_price = round(
1104
-                        $unit_price_for_total * $child_line_item->percent() / 100,
1105
-                        EE_Registry::instance()->CFG->currency->dec_plc
1106
-                    );
1107
-                    $percent_total = $percent_unit_price * $quantity_for_total;
1108
-                    $child_line_item->set_total($percent_total);
1109
-                    // so far all percent line items should have a quantity of 1
1110
-                    // (ie, no double percent discounts. Although that might be requested someday)
1111
-                    $child_line_item->set_quantity(1);
1112
-                    $child_line_item->maybe_save();
1113
-                    $calculated_total_so_far += $percent_total;
1114
-                    $unit_price_for_total += $percent_unit_price;
1115
-                } else {
1116
-                    // verify flat sub-line-item quantities match their parent
1117
-                    if ($child_line_item->is_sub_line_item()) {
1118
-                        $child_line_item->set_quantity($this->quantity());
1119
-                    }
1120
-                    $quantity_for_total = $child_line_item->quantity();
1121
-                    $calculated_total_so_far += $child_line_item->recalculate_pre_tax_total();
1122
-                    $unit_price_for_total += $child_line_item->unit_price();
1123
-                }
1124
-            }
1125
-        }
1126
-        return $calculated_total_so_far;
1127
-    }
1128
-
1129
-
1130
-    /**
1131
-     * Recalculates the total on each individual tax (based on a recalculation of the pre-tax total), sets
1132
-     * the totals on each tax calculated, and returns the final tax total. Re-saves tax line items
1133
-     * and tax sub-total if already in the DB
1134
-     *
1135
-     * @return float
1136
-     * @throws EE_Error
1137
-     */
1138
-    public function recalculate_taxes_and_tax_total()
1139
-    {
1140
-        // get all taxes
1141
-        $taxes = $this->tax_descendants();
1142
-        // calculate the pretax total
1143
-        $taxable_total = $this->taxable_total();
1144
-        $tax_total = 0;
1145
-        foreach ($taxes as $tax) {
1146
-            $total_on_this_tax = $taxable_total * $tax->percent() / 100;
1147
-            // remember the total on this line item
1148
-            $tax->set_total($total_on_this_tax);
1149
-            $tax->maybe_save();
1150
-            $tax_total += $tax->total();
1151
-        }
1152
-        $this->_recalculate_tax_sub_total();
1153
-        return $tax_total;
1154
-    }
1155
-
1156
-
1157
-    /**
1158
-     * Simply forces all the tax-sub-totals to recalculate. Assumes the taxes have been calculated
1159
-     *
1160
-     * @return void
1161
-     * @throws EE_Error
1162
-     */
1163
-    private function _recalculate_tax_sub_total()
1164
-    {
1165
-        if ($this->is_tax_sub_total()) {
1166
-            $total = 0;
1167
-            $total_percent = 0;
1168
-            // simply loop through all its children (which should be taxes) and sum their total
1169
-            foreach ($this->children() as $child_tax) {
1170
-                if ($child_tax instanceof EE_Line_Item) {
1171
-                    $total += $child_tax->total();
1172
-                    $total_percent += $child_tax->percent();
1173
-                }
1174
-            }
1175
-            $this->set_total($total);
1176
-            $this->set_percent($total_percent);
1177
-            $this->maybe_save();
1178
-        } elseif ($this->is_total()) {
1179
-            foreach ($this->children() as $maybe_tax_subtotal) {
1180
-                if ($maybe_tax_subtotal instanceof EE_Line_Item) {
1181
-                    $maybe_tax_subtotal->_recalculate_tax_sub_total();
1182
-                }
1183
-            }
1184
-        }
1185
-    }
1186
-
1187
-
1188
-    /**
1189
-     * Gets the total tax on this line item. Assumes taxes have already been calculated using
1190
-     * recalculate_taxes_and_total
1191
-     *
1192
-     * @return float
1193
-     * @throws EE_Error
1194
-     */
1195
-    public function get_total_tax()
1196
-    {
1197
-        $this->_recalculate_tax_sub_total();
1198
-        $total = 0;
1199
-        foreach ($this->tax_descendants() as $tax_line_item) {
1200
-            if ($tax_line_item instanceof EE_Line_Item) {
1201
-                $total += $tax_line_item->total();
1202
-            }
1203
-        }
1204
-        return $total;
1205
-    }
1206
-
1207
-
1208
-    /**
1209
-     * Gets the total for all the items purchased only
1210
-     *
1211
-     * @return float
1212
-     * @throws EE_Error
1213
-     */
1214
-    public function get_items_total()
1215
-    {
1216
-        // by default, let's make sure we're consistent with the existing line item
1217
-        if ($this->is_total()) {
1218
-            $pretax_subtotal_li = EEH_Line_Item::get_pre_tax_subtotal($this);
1219
-            if ($pretax_subtotal_li instanceof EE_Line_Item) {
1220
-                return $pretax_subtotal_li->total();
1221
-            }
1222
-        }
1223
-        $total = 0;
1224
-        foreach ($this->get_items() as $item) {
1225
-            if ($item instanceof EE_Line_Item) {
1226
-                $total += $item->total();
1227
-            }
1228
-        }
1229
-        return $total;
1230
-    }
1231
-
1232
-
1233
-    /**
1234
-     * Gets all the descendants (ie, children or children of children etc) that
1235
-     * are of the type 'tax'
1236
-     *
1237
-     * @return EE_Line_Item[]
1238
-     */
1239
-    public function tax_descendants()
1240
-    {
1241
-        return EEH_Line_Item::get_tax_descendants($this);
1242
-    }
1243
-
1244
-
1245
-    /**
1246
-     * Gets all the real items purchased which are children of this item
1247
-     *
1248
-     * @return EE_Line_Item[]
1249
-     */
1250
-    public function get_items()
1251
-    {
1252
-        return EEH_Line_Item::get_line_item_descendants($this);
1253
-    }
1254
-
1255
-
1256
-    /**
1257
-     * Returns the amount taxable among this line item's children (or if it has no children,
1258
-     * how much of it is taxable). Does not recalculate totals or subtotals.
1259
-     * If the taxable total is negative, (eg, if none of the tickets were taxable,
1260
-     * but there is a "Taxable" discount), returns 0.
1261
-     *
1262
-     * @return float
1263
-     * @throws EE_Error
1264
-     */
1265
-    public function taxable_total()
1266
-    {
1267
-        $total = 0;
1268
-        if ($this->children()) {
1269
-            foreach ($this->children() as $child_line_item) {
1270
-                if ($child_line_item->type() === EEM_Line_Item::type_line_item && $child_line_item->is_taxable()) {
1271
-                    // if it's a percent item, only take into account the percent
1272
-                    // that's taxable too (the taxable total so far)
1273
-                    if ($child_line_item->is_percent()) {
1274
-                        $total += ($total * $child_line_item->percent() / 100);
1275
-                    } else {
1276
-                        $total += $child_line_item->total();
1277
-                    }
1278
-                } elseif ($child_line_item->type() === EEM_Line_Item::type_sub_total) {
1279
-                    $total += $child_line_item->taxable_total();
1280
-                }
1281
-            }
1282
-        }
1283
-        return max($total, 0);
1284
-    }
1285
-
1286
-
1287
-    /**
1288
-     * Gets the transaction for this line item
1289
-     *
1290
-     * @return EE_Base_Class|EE_Transaction
1291
-     * @throws EE_Error
1292
-     */
1293
-    public function transaction()
1294
-    {
1295
-        return $this->get_first_related('Transaction');
1296
-    }
1297
-
1298
-
1299
-    /**
1300
-     * Saves this line item to the DB, and recursively saves its descendants.
1301
-     * Because there currently is no proper parent-child relation on the model,
1302
-     * save_this_and_cached() will NOT save the descendants.
1303
-     * Also sets the transaction on this line item and all its descendants before saving
1304
-     *
1305
-     * @param int $txn_id if none is provided, assumes $this->TXN_ID()
1306
-     * @return int count of items saved
1307
-     * @throws EE_Error
1308
-     */
1309
-    public function save_this_and_descendants_to_txn($txn_id = null)
1310
-    {
1311
-        $count = 0;
1312
-        if (! $txn_id) {
1313
-            $txn_id = $this->TXN_ID();
1314
-        }
1315
-        $this->set_TXN_ID($txn_id);
1316
-        $children = $this->children();
1317
-        $count += $this->save()
1318
-            ? 1
1319
-            : 0;
1320
-        foreach ($children as $child_line_item) {
1321
-            if ($child_line_item instanceof EE_Line_Item) {
1322
-                $child_line_item->set_parent_ID($this->ID());
1323
-                $count += $child_line_item->save_this_and_descendants_to_txn($txn_id);
1324
-            }
1325
-        }
1326
-        return $count;
1327
-    }
1328
-
1329
-
1330
-    /**
1331
-     * Saves this line item to the DB, and recursively saves its descendants.
1332
-     *
1333
-     * @return int count of items saved
1334
-     * @throws EE_Error
1335
-     */
1336
-    public function save_this_and_descendants()
1337
-    {
1338
-        $count = 0;
1339
-        $children = $this->children();
1340
-        $count += $this->save()
1341
-            ? 1
1342
-            : 0;
1343
-        foreach ($children as $child_line_item) {
1344
-            if ($child_line_item instanceof EE_Line_Item) {
1345
-                $child_line_item->set_parent_ID($this->ID());
1346
-                $count += $child_line_item->save_this_and_descendants();
1347
-            }
1348
-        }
1349
-        return $count;
1350
-    }
1351
-
1352
-
1353
-    /**
1354
-     * returns the cancellation line item if this item was cancelled
1355
-     *
1356
-     * @return EE_Line_Item[]
1357
-     * @throws InvalidArgumentException
1358
-     * @throws InvalidInterfaceException
1359
-     * @throws InvalidDataTypeException
1360
-     * @throws ReflectionException
1361
-     * @throws EE_Error
1362
-     */
1363
-    public function get_cancellations()
1364
-    {
1365
-        EE_Registry::instance()->load_helper('Line_Item');
1366
-        return EEH_Line_Item::get_descendants_of_type($this, EEM_Line_Item::type_cancellation);
1367
-    }
1368
-
1369
-
1370
-    /**
1371
-     * If this item has an ID, then this saves it again to update the db
1372
-     *
1373
-     * @return int count of items saved
1374
-     * @throws EE_Error
1375
-     */
1376
-    public function maybe_save()
1377
-    {
1378
-        if ($this->ID()) {
1379
-            return $this->save();
1380
-        }
1381
-        return false;
1382
-    }
1383
-
1384
-
1385
-    /**
1386
-     * clears the cached children and parent from the line item
1387
-     *
1388
-     * @return void
1389
-     */
1390
-    public function clear_related_line_item_cache()
1391
-    {
1392
-        $this->_children = array();
1393
-        $this->_parent = null;
1394
-    }
1395
-
1396
-
1397
-    /**
1398
-     * @param bool $raw
1399
-     * @return int
1400
-     * @throws EE_Error
1401
-     */
1402
-    public function timestamp($raw = false)
1403
-    {
1404
-        return $raw
1405
-            ? $this->get_raw('LIN_timestamp')
1406
-            : $this->get('LIN_timestamp');
1407
-    }
1408
-
1409
-
1410
-
1411
-
1412
-    /************************* DEPRECATED *************************/
1413
-    /**
1414
-     * @deprecated 4.6.0
1415
-     * @param string $type one of the constants on EEM_Line_Item
1416
-     * @return EE_Line_Item[]
1417
-     */
1418
-    protected function _get_descendants_of_type($type)
1419
-    {
1420
-        EE_Error::doing_it_wrong(
1421
-            'EE_Line_Item::_get_descendants_of_type()',
1422
-            __('Method replaced with EEH_Line_Item::get_descendants_of_type()', 'event_espresso'),
1423
-            '4.6.0'
1424
-        );
1425
-        return EEH_Line_Item::get_descendants_of_type($this, $type);
1426
-    }
1427
-
1428
-
1429
-    /**
1430
-     * @deprecated 4.6.0
1431
-     * @param string $type like one of the EEM_Line_Item::type_*
1432
-     * @return EE_Line_Item
1433
-     */
1434
-    public function get_nearest_descendant_of_type($type)
1435
-    {
1436
-        EE_Error::doing_it_wrong(
1437
-            'EE_Line_Item::get_nearest_descendant_of_type()',
1438
-            __('Method replaced with EEH_Line_Item::get_nearest_descendant_of_type()', 'event_espresso'),
1439
-            '4.6.0'
1440
-        );
1441
-        return EEH_Line_Item::get_nearest_descendant_of_type($this, $type);
1442
-    }
17
+	/**
18
+	 * for children line items (currently not a normal relation)
19
+	 *
20
+	 * @type EE_Line_Item[]
21
+	 */
22
+	protected $_children = array();
23
+
24
+	/**
25
+	 * for the parent line item
26
+	 *
27
+	 * @var EE_Line_Item
28
+	 */
29
+	protected $_parent;
30
+
31
+
32
+	/**
33
+	 *
34
+	 * @param array  $props_n_values          incoming values
35
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
36
+	 *                                        used.)
37
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
38
+	 *                                        date_format and the second value is the time format
39
+	 * @return EE_Line_Item
40
+	 * @throws EE_Error
41
+	 */
42
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
43
+	{
44
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
45
+		return $has_object
46
+			? $has_object
47
+			: new self($props_n_values, false, $timezone);
48
+	}
49
+
50
+
51
+	/**
52
+	 * @param array  $props_n_values  incoming values from the database
53
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
54
+	 *                                the website will be used.
55
+	 * @return EE_Line_Item
56
+	 * @throws EE_Error
57
+	 */
58
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
59
+	{
60
+		return new self($props_n_values, true, $timezone);
61
+	}
62
+
63
+
64
+	/**
65
+	 * Adds some defaults if they're not specified
66
+	 *
67
+	 * @param array  $fieldValues
68
+	 * @param bool   $bydb
69
+	 * @param string $timezone
70
+	 * @throws EE_Error
71
+	 */
72
+	protected function __construct($fieldValues = array(), $bydb = false, $timezone = '')
73
+	{
74
+		parent::__construct($fieldValues, $bydb, $timezone);
75
+		if (! $this->get('LIN_code')) {
76
+			$this->set_code($this->generate_code());
77
+		}
78
+	}
79
+
80
+
81
+	/**
82
+	 * Gets ID
83
+	 *
84
+	 * @return int
85
+	 * @throws EE_Error
86
+	 */
87
+	public function ID()
88
+	{
89
+		return $this->get('LIN_ID');
90
+	}
91
+
92
+
93
+	/**
94
+	 * Gets TXN_ID
95
+	 *
96
+	 * @return int
97
+	 * @throws EE_Error
98
+	 */
99
+	public function TXN_ID()
100
+	{
101
+		return $this->get('TXN_ID');
102
+	}
103
+
104
+
105
+	/**
106
+	 * Sets TXN_ID
107
+	 *
108
+	 * @param int $TXN_ID
109
+	 * @throws EE_Error
110
+	 */
111
+	public function set_TXN_ID($TXN_ID)
112
+	{
113
+		$this->set('TXN_ID', $TXN_ID);
114
+	}
115
+
116
+
117
+	/**
118
+	 * Gets name
119
+	 *
120
+	 * @return string
121
+	 * @throws EE_Error
122
+	 */
123
+	public function name()
124
+	{
125
+		$name = $this->get('LIN_name');
126
+		if (! $name) {
127
+			$name = ucwords(str_replace('-', ' ', $this->type()));
128
+		}
129
+		return $name;
130
+	}
131
+
132
+
133
+	/**
134
+	 * Sets name
135
+	 *
136
+	 * @param string $name
137
+	 * @throws EE_Error
138
+	 */
139
+	public function set_name($name)
140
+	{
141
+		$this->set('LIN_name', $name);
142
+	}
143
+
144
+
145
+	/**
146
+	 * Gets desc
147
+	 *
148
+	 * @return string
149
+	 * @throws EE_Error
150
+	 */
151
+	public function desc()
152
+	{
153
+		return $this->get('LIN_desc');
154
+	}
155
+
156
+
157
+	/**
158
+	 * Sets desc
159
+	 *
160
+	 * @param string $desc
161
+	 * @throws EE_Error
162
+	 */
163
+	public function set_desc($desc)
164
+	{
165
+		$this->set('LIN_desc', $desc);
166
+	}
167
+
168
+
169
+	/**
170
+	 * Gets quantity
171
+	 *
172
+	 * @return int
173
+	 * @throws EE_Error
174
+	 */
175
+	public function quantity()
176
+	{
177
+		return $this->get('LIN_quantity');
178
+	}
179
+
180
+
181
+	/**
182
+	 * Sets quantity
183
+	 *
184
+	 * @param int $quantity
185
+	 * @throws EE_Error
186
+	 */
187
+	public function set_quantity($quantity)
188
+	{
189
+		$this->set('LIN_quantity', max($quantity, 0));
190
+	}
191
+
192
+
193
+	/**
194
+	 * Gets item_id
195
+	 *
196
+	 * @return string
197
+	 * @throws EE_Error
198
+	 */
199
+	public function OBJ_ID()
200
+	{
201
+		return $this->get('OBJ_ID');
202
+	}
203
+
204
+
205
+	/**
206
+	 * Sets item_id
207
+	 *
208
+	 * @param string $item_id
209
+	 * @throws EE_Error
210
+	 */
211
+	public function set_OBJ_ID($item_id)
212
+	{
213
+		$this->set('OBJ_ID', $item_id);
214
+	}
215
+
216
+
217
+	/**
218
+	 * Gets item_type
219
+	 *
220
+	 * @return string
221
+	 * @throws EE_Error
222
+	 */
223
+	public function OBJ_type()
224
+	{
225
+		return $this->get('OBJ_type');
226
+	}
227
+
228
+
229
+	/**
230
+	 * Gets item_type
231
+	 *
232
+	 * @return string
233
+	 * @throws EE_Error
234
+	 */
235
+	public function OBJ_type_i18n()
236
+	{
237
+		$obj_type = $this->OBJ_type();
238
+		switch ($obj_type) {
239
+			case 'Event':
240
+				$obj_type = __('Event', 'event_espresso');
241
+				break;
242
+			case 'Price':
243
+				$obj_type = __('Price', 'event_espresso');
244
+				break;
245
+			case 'Promotion':
246
+				$obj_type = __('Promotion', 'event_espresso');
247
+				break;
248
+			case 'Ticket':
249
+				$obj_type = __('Ticket', 'event_espresso');
250
+				break;
251
+			case 'Transaction':
252
+				$obj_type = __('Transaction', 'event_espresso');
253
+				break;
254
+		}
255
+		return apply_filters('FHEE__EE_Line_Item__OBJ_type_i18n', $obj_type, $this);
256
+	}
257
+
258
+
259
+	/**
260
+	 * Sets item_type
261
+	 *
262
+	 * @param string $OBJ_type
263
+	 * @throws EE_Error
264
+	 */
265
+	public function set_OBJ_type($OBJ_type)
266
+	{
267
+		$this->set('OBJ_type', $OBJ_type);
268
+	}
269
+
270
+
271
+	/**
272
+	 * Gets unit_price
273
+	 *
274
+	 * @return float
275
+	 * @throws EE_Error
276
+	 */
277
+	public function unit_price()
278
+	{
279
+		return $this->get('LIN_unit_price');
280
+	}
281
+
282
+
283
+	/**
284
+	 * Sets unit_price
285
+	 *
286
+	 * @param float $unit_price
287
+	 * @throws EE_Error
288
+	 */
289
+	public function set_unit_price($unit_price)
290
+	{
291
+		$this->set('LIN_unit_price', $unit_price);
292
+	}
293
+
294
+
295
+	/**
296
+	 * Checks if this item is a percentage modifier or not
297
+	 *
298
+	 * @return boolean
299
+	 * @throws EE_Error
300
+	 */
301
+	public function is_percent()
302
+	{
303
+		if ($this->is_tax_sub_total()) {
304
+			// tax subtotals HAVE a percent on them, that percentage only applies
305
+			// to taxable items, so its' an exception. Treat it like a flat line item
306
+			return false;
307
+		}
308
+		$unit_price = abs($this->get('LIN_unit_price'));
309
+		$percent = abs($this->get('LIN_percent'));
310
+		if ($unit_price < .001 && $percent) {
311
+			return true;
312
+		}
313
+		if ($unit_price >= .001 && ! $percent) {
314
+			return false;
315
+		}
316
+		if ($unit_price >= .001 && $percent) {
317
+			throw new EE_Error(
318
+				sprintf(
319
+					esc_html__('A Line Item can not have a unit price of (%s) AND a percent (%s)!', 'event_espresso'),
320
+					$unit_price,
321
+					$percent
322
+				)
323
+			);
324
+		}
325
+		// if they're both 0, assume its not a percent item
326
+		return false;
327
+	}
328
+
329
+
330
+	/**
331
+	 * Gets percent (between 100-.001)
332
+	 *
333
+	 * @return float
334
+	 * @throws EE_Error
335
+	 */
336
+	public function percent()
337
+	{
338
+		return $this->get('LIN_percent');
339
+	}
340
+
341
+
342
+	/**
343
+	 * Sets percent (between 100-0.01)
344
+	 *
345
+	 * @param float $percent
346
+	 * @throws EE_Error
347
+	 */
348
+	public function set_percent($percent)
349
+	{
350
+		$this->set('LIN_percent', $percent);
351
+	}
352
+
353
+
354
+	/**
355
+	 * Gets total
356
+	 *
357
+	 * @return float
358
+	 * @throws EE_Error
359
+	 */
360
+	public function total()
361
+	{
362
+		return $this->get('LIN_total');
363
+	}
364
+
365
+
366
+	/**
367
+	 * Sets total
368
+	 *
369
+	 * @param float $total
370
+	 * @throws EE_Error
371
+	 */
372
+	public function set_total($total)
373
+	{
374
+		$this->set('LIN_total', $total);
375
+	}
376
+
377
+
378
+	/**
379
+	 * Gets order
380
+	 *
381
+	 * @return int
382
+	 * @throws EE_Error
383
+	 */
384
+	public function order()
385
+	{
386
+		return $this->get('LIN_order');
387
+	}
388
+
389
+
390
+	/**
391
+	 * Sets order
392
+	 *
393
+	 * @param int $order
394
+	 * @throws EE_Error
395
+	 */
396
+	public function set_order($order)
397
+	{
398
+		$this->set('LIN_order', $order);
399
+	}
400
+
401
+
402
+	/**
403
+	 * Gets parent
404
+	 *
405
+	 * @return int
406
+	 * @throws EE_Error
407
+	 */
408
+	public function parent_ID()
409
+	{
410
+		return $this->get('LIN_parent');
411
+	}
412
+
413
+
414
+	/**
415
+	 * Sets parent
416
+	 *
417
+	 * @param int $parent
418
+	 * @throws EE_Error
419
+	 */
420
+	public function set_parent_ID($parent)
421
+	{
422
+		$this->set('LIN_parent', $parent);
423
+	}
424
+
425
+
426
+	/**
427
+	 * Gets type
428
+	 *
429
+	 * @return string
430
+	 * @throws EE_Error
431
+	 */
432
+	public function type()
433
+	{
434
+		return $this->get('LIN_type');
435
+	}
436
+
437
+
438
+	/**
439
+	 * Sets type
440
+	 *
441
+	 * @param string $type
442
+	 * @throws EE_Error
443
+	 */
444
+	public function set_type($type)
445
+	{
446
+		$this->set('LIN_type', $type);
447
+	}
448
+
449
+
450
+	/**
451
+	 * Gets the line item of which this item is a composite. Eg, if this is a subtotal, the parent might be a total\
452
+	 * If this line item is saved to the DB, fetches the parent from the DB. However, if this line item isn't in the DB
453
+	 * it uses its cached reference to its parent line item (which would have been set by `EE_Line_Item::set_parent()`
454
+	 * or indirectly by `EE_Line_item::add_child_line_item()`)
455
+	 *
456
+	 * @return EE_Base_Class|EE_Line_Item
457
+	 * @throws EE_Error
458
+	 */
459
+	public function parent()
460
+	{
461
+		return $this->ID()
462
+			? $this->get_model()->get_one_by_ID($this->parent_ID())
463
+			: $this->_parent;
464
+	}
465
+
466
+
467
+	/**
468
+	 * Gets ALL the children of this line item (ie, all the parts that contribute towards this total).
469
+	 *
470
+	 * @return EE_Base_Class[]|EE_Line_Item[]
471
+	 * @throws EE_Error
472
+	 */
473
+	public function children()
474
+	{
475
+		if ($this->ID()) {
476
+			return $this->get_model()->get_all(
477
+				array(
478
+					array('LIN_parent' => $this->ID()),
479
+					'order_by' => array('LIN_order' => 'ASC'),
480
+				)
481
+			);
482
+		}
483
+		if (! is_array($this->_children)) {
484
+			$this->_children = array();
485
+		}
486
+		return $this->_children;
487
+	}
488
+
489
+
490
+	/**
491
+	 * Gets code
492
+	 *
493
+	 * @return string
494
+	 * @throws EE_Error
495
+	 */
496
+	public function code()
497
+	{
498
+		return $this->get('LIN_code');
499
+	}
500
+
501
+
502
+	/**
503
+	 * Sets code
504
+	 *
505
+	 * @param string $code
506
+	 * @throws EE_Error
507
+	 */
508
+	public function set_code($code)
509
+	{
510
+		$this->set('LIN_code', $code);
511
+	}
512
+
513
+
514
+	/**
515
+	 * Gets is_taxable
516
+	 *
517
+	 * @return boolean
518
+	 * @throws EE_Error
519
+	 */
520
+	public function is_taxable()
521
+	{
522
+		return $this->get('LIN_is_taxable');
523
+	}
524
+
525
+
526
+	/**
527
+	 * Sets is_taxable
528
+	 *
529
+	 * @param boolean $is_taxable
530
+	 * @throws EE_Error
531
+	 */
532
+	public function set_is_taxable($is_taxable)
533
+	{
534
+		$this->set('LIN_is_taxable', $is_taxable);
535
+	}
536
+
537
+
538
+	/**
539
+	 * Gets the object that this model-joins-to.
540
+	 * returns one of the model objects that the field OBJ_ID can point to... see the 'OBJ_ID' field on
541
+	 * EEM_Promotion_Object
542
+	 *
543
+	 *        Eg, if this line item join model object is for a ticket, this will return the EE_Ticket object
544
+	 *
545
+	 * @return EE_Base_Class | NULL
546
+	 * @throws EE_Error
547
+	 */
548
+	public function get_object()
549
+	{
550
+		$model_name_of_related_obj = $this->OBJ_type();
551
+		return $this->get_model()->has_relation($model_name_of_related_obj)
552
+			? $this->get_first_related($model_name_of_related_obj)
553
+			: null;
554
+	}
555
+
556
+
557
+	/**
558
+	 * Like EE_Line_Item::get_object(), but can only ever actually return an EE_Ticket.
559
+	 * (IE, if this line item is for a price or something else, will return NULL)
560
+	 *
561
+	 * @param array $query_params
562
+	 * @return EE_Base_Class|EE_Ticket
563
+	 * @throws EE_Error
564
+	 */
565
+	public function ticket($query_params = array())
566
+	{
567
+		// we're going to assume that when this method is called we always want to receive the attached ticket EVEN if that ticket is archived.  This can be overridden via the incoming $query_params argument
568
+		$remove_defaults = array('default_where_conditions' => 'none');
569
+		$query_params = array_merge($remove_defaults, $query_params);
570
+		return $this->get_first_related('Ticket', $query_params);
571
+	}
572
+
573
+
574
+	/**
575
+	 * Gets the EE_Datetime that's related to the ticket, IF this is for a ticket
576
+	 *
577
+	 * @return EE_Datetime | NULL
578
+	 * @throws EE_Error
579
+	 */
580
+	public function get_ticket_datetime()
581
+	{
582
+		if ($this->OBJ_type() === 'Ticket') {
583
+			$ticket = $this->ticket();
584
+			if ($ticket instanceof EE_Ticket) {
585
+				$datetime = $ticket->first_datetime();
586
+				if ($datetime instanceof EE_Datetime) {
587
+					return $datetime;
588
+				}
589
+			}
590
+		}
591
+		return null;
592
+	}
593
+
594
+
595
+	/**
596
+	 * Gets the event's name that's related to the ticket, if this is for
597
+	 * a ticket
598
+	 *
599
+	 * @return string
600
+	 * @throws EE_Error
601
+	 */
602
+	public function ticket_event_name()
603
+	{
604
+		$event_name = esc_html__('Unknown', 'event_espresso');
605
+		$event = $this->ticket_event();
606
+		if ($event instanceof EE_Event) {
607
+			$event_name = $event->name();
608
+		}
609
+		return $event_name;
610
+	}
611
+
612
+
613
+	/**
614
+	 * Gets the event that's related to the ticket, if this line item represents a ticket.
615
+	 *
616
+	 * @return EE_Event|null
617
+	 * @throws EE_Error
618
+	 */
619
+	public function ticket_event()
620
+	{
621
+		$event = null;
622
+		$ticket = $this->ticket();
623
+		if ($ticket instanceof EE_Ticket) {
624
+			$datetime = $ticket->first_datetime();
625
+			if ($datetime instanceof EE_Datetime) {
626
+				$event = $datetime->event();
627
+			}
628
+		}
629
+		return $event;
630
+	}
631
+
632
+
633
+	/**
634
+	 * Gets the first datetime for this lien item, assuming it's for a ticket
635
+	 *
636
+	 * @param string $date_format
637
+	 * @param string $time_format
638
+	 * @return string
639
+	 * @throws EE_Error
640
+	 */
641
+	public function ticket_datetime_start($date_format = '', $time_format = '')
642
+	{
643
+		$first_datetime_string = esc_html__('Unknown', 'event_espresso');
644
+		$datetime = $this->get_ticket_datetime();
645
+		if ($datetime) {
646
+			$first_datetime_string = $datetime->start_date_and_time($date_format, $time_format);
647
+		}
648
+		return $first_datetime_string;
649
+	}
650
+
651
+
652
+	/**
653
+	 * Adds the line item as a child to this line item. If there is another child line
654
+	 * item with the same LIN_code, it is overwritten by this new one
655
+	 *
656
+	 * @param EEI_Line_Item $line_item
657
+	 * @param bool          $set_order
658
+	 * @return bool success
659
+	 * @throws EE_Error
660
+	 */
661
+	public function add_child_line_item(EEI_Line_Item $line_item, $set_order = true)
662
+	{
663
+		// should we calculate the LIN_order for this line item ?
664
+		if ($set_order || $line_item->order() === null) {
665
+			$line_item->set_order(count($this->children()));
666
+		}
667
+		if ($this->ID()) {
668
+			// check for any duplicate line items (with the same code), if so, this replaces it
669
+			$line_item_with_same_code = $this->get_child_line_item($line_item->code());
670
+			if ($line_item_with_same_code instanceof EE_Line_Item && $line_item_with_same_code !== $line_item) {
671
+				$this->delete_child_line_item($line_item_with_same_code->code());
672
+			}
673
+			$line_item->set_parent_ID($this->ID());
674
+			if ($this->TXN_ID()) {
675
+				$line_item->set_TXN_ID($this->TXN_ID());
676
+			}
677
+			return $line_item->save();
678
+		}
679
+		$this->_children[ $line_item->code() ] = $line_item;
680
+		if ($line_item->parent() !== $this) {
681
+			$line_item->set_parent($this);
682
+		}
683
+		return true;
684
+	}
685
+
686
+
687
+	/**
688
+	 * Similar to EE_Base_Class::_add_relation_to, except this isn't a normal relation.
689
+	 * If this line item is saved to the DB, this is just a wrapper for set_parent_ID() and save()
690
+	 * However, if this line item is NOT saved to the DB, this just caches the parent on
691
+	 * the EE_Line_Item::_parent property.
692
+	 *
693
+	 * @param EE_Line_Item $line_item
694
+	 * @throws EE_Error
695
+	 */
696
+	public function set_parent($line_item)
697
+	{
698
+		if ($this->ID()) {
699
+			if (! $line_item->ID()) {
700
+				$line_item->save();
701
+			}
702
+			$this->set_parent_ID($line_item->ID());
703
+			$this->save();
704
+		} else {
705
+			$this->_parent = $line_item;
706
+			$this->set_parent_ID($line_item->ID());
707
+		}
708
+	}
709
+
710
+
711
+	/**
712
+	 * Gets the child line item as specified by its code. Because this returns an object (by reference)
713
+	 * you can modify this child line item and the parent (this object) can know about them
714
+	 * because it also has a reference to that line item
715
+	 *
716
+	 * @param string $code
717
+	 * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL
718
+	 * @throws EE_Error
719
+	 */
720
+	public function get_child_line_item($code)
721
+	{
722
+		if ($this->ID()) {
723
+			return $this->get_model()->get_one(
724
+				array(array('LIN_parent' => $this->ID(), 'LIN_code' => $code))
725
+			);
726
+		}
727
+		return isset($this->_children[ $code ])
728
+			? $this->_children[ $code ]
729
+			: null;
730
+	}
731
+
732
+
733
+	/**
734
+	 * Returns how many items are deleted (or, if this item has not been saved ot the DB yet, just how many it HAD
735
+	 * cached on it)
736
+	 *
737
+	 * @return int
738
+	 * @throws EE_Error
739
+	 */
740
+	public function delete_children_line_items()
741
+	{
742
+		if ($this->ID()) {
743
+			return $this->get_model()->delete(array(array('LIN_parent' => $this->ID())));
744
+		}
745
+		$count = count($this->_children);
746
+		$this->_children = array();
747
+		return $count;
748
+	}
749
+
750
+
751
+	/**
752
+	 * If this line item has been saved to the DB, deletes its child with LIN_code == $code. If this line
753
+	 * HAS NOT been saved to the DB, removes the child line item with index $code.
754
+	 * Also searches through the child's children for a matching line item. However, once a line item has been found
755
+	 * and deleted, stops searching (so if there are line items with duplicate codes, only the first one found will be
756
+	 * deleted)
757
+	 *
758
+	 * @param string $code
759
+	 * @param bool   $stop_search_once_found
760
+	 * @return int count of items deleted (or simply removed from the line item's cache, if not has not been saved to
761
+	 *             the DB yet)
762
+	 * @throws EE_Error
763
+	 */
764
+	public function delete_child_line_item($code, $stop_search_once_found = true)
765
+	{
766
+		if ($this->ID()) {
767
+			$items_deleted = 0;
768
+			if ($this->code() === $code) {
769
+				$items_deleted += EEH_Line_Item::delete_all_child_items($this);
770
+				$items_deleted += (int) $this->delete();
771
+				if ($stop_search_once_found) {
772
+					return $items_deleted;
773
+				}
774
+			}
775
+			foreach ($this->children() as $child_line_item) {
776
+				$items_deleted += $child_line_item->delete_child_line_item($code, $stop_search_once_found);
777
+			}
778
+			return $items_deleted;
779
+		}
780
+		if (isset($this->_children[ $code ])) {
781
+			unset($this->_children[ $code ]);
782
+			return 1;
783
+		}
784
+		return 0;
785
+	}
786
+
787
+
788
+	/**
789
+	 * If this line item is in the database, is of the type subtotal, and
790
+	 * has no children, why do we have it? It should be deleted so this function
791
+	 * does that
792
+	 *
793
+	 * @return boolean
794
+	 * @throws EE_Error
795
+	 */
796
+	public function delete_if_childless_subtotal()
797
+	{
798
+		if ($this->ID() && $this->type() === EEM_Line_Item::type_sub_total && ! $this->children()) {
799
+			return $this->delete();
800
+		}
801
+		return false;
802
+	}
803
+
804
+
805
+	/**
806
+	 * Creates a code and returns a string. doesn't assign the code to this model object
807
+	 *
808
+	 * @return string
809
+	 * @throws EE_Error
810
+	 */
811
+	public function generate_code()
812
+	{
813
+		// each line item in the cart requires a unique identifier
814
+		return md5($this->get('OBJ_type') . $this->get('OBJ_ID') . microtime());
815
+	}
816
+
817
+
818
+	/**
819
+	 * @return bool
820
+	 * @throws EE_Error
821
+	 */
822
+	public function is_tax()
823
+	{
824
+		return $this->type() === EEM_Line_Item::type_tax;
825
+	}
826
+
827
+
828
+	/**
829
+	 * @return bool
830
+	 * @throws EE_Error
831
+	 */
832
+	public function is_tax_sub_total()
833
+	{
834
+		return $this->type() === EEM_Line_Item::type_tax_sub_total;
835
+	}
836
+
837
+
838
+	/**
839
+	 * @return bool
840
+	 * @throws EE_Error
841
+	 */
842
+	public function is_line_item()
843
+	{
844
+		return $this->type() === EEM_Line_Item::type_line_item;
845
+	}
846
+
847
+
848
+	/**
849
+	 * @return bool
850
+	 * @throws EE_Error
851
+	 */
852
+	public function is_sub_line_item()
853
+	{
854
+		return $this->type() === EEM_Line_Item::type_sub_line_item;
855
+	}
856
+
857
+
858
+	/**
859
+	 * @return bool
860
+	 * @throws EE_Error
861
+	 */
862
+	public function is_sub_total()
863
+	{
864
+		return $this->type() === EEM_Line_Item::type_sub_total;
865
+	}
866
+
867
+
868
+	/**
869
+	 * Whether or not this line item is a cancellation line item
870
+	 *
871
+	 * @return boolean
872
+	 * @throws EE_Error
873
+	 */
874
+	public function is_cancellation()
875
+	{
876
+		return EEM_Line_Item::type_cancellation === $this->type();
877
+	}
878
+
879
+
880
+	/**
881
+	 * @return bool
882
+	 * @throws EE_Error
883
+	 */
884
+	public function is_total()
885
+	{
886
+		return $this->type() === EEM_Line_Item::type_total;
887
+	}
888
+
889
+
890
+	/**
891
+	 * @return bool
892
+	 * @throws EE_Error
893
+	 */
894
+	public function is_cancelled()
895
+	{
896
+		return $this->type() === EEM_Line_Item::type_cancellation;
897
+	}
898
+
899
+
900
+	/**
901
+	 * @return string like '2, 004.00', formatted according to the localized currency
902
+	 * @throws EE_Error
903
+	 */
904
+	public function unit_price_no_code()
905
+	{
906
+		return $this->get_pretty('LIN_unit_price', 'no_currency_code');
907
+	}
908
+
909
+
910
+	/**
911
+	 * @return string like '2, 004.00', formatted according to the localized currency
912
+	 * @throws EE_Error
913
+	 */
914
+	public function total_no_code()
915
+	{
916
+		return $this->get_pretty('LIN_total', 'no_currency_code');
917
+	}
918
+
919
+
920
+	/**
921
+	 * Gets the final total on this item, taking taxes into account.
922
+	 * Has the side-effect of setting the sub-total as it was just calculated.
923
+	 * If this is used on a grand-total line item, also updates the transaction's
924
+	 * TXN_total (provided this line item is allowed to persist, otherwise we don't
925
+	 * want to change a persistable transaction with info from a non-persistent line item)
926
+	 *
927
+	 * @return float
928
+	 * @throws EE_Error
929
+	 * @throws InvalidArgumentException
930
+	 * @throws InvalidInterfaceException
931
+	 * @throws InvalidDataTypeException
932
+	 */
933
+	public function recalculate_total_including_taxes()
934
+	{
935
+		$pre_tax_total = $this->recalculate_pre_tax_total();
936
+		$tax_total = $this->recalculate_taxes_and_tax_total();
937
+		$total = $pre_tax_total + $tax_total;
938
+		// no negative totals plz
939
+		$total = max($total, 0);
940
+		$this->set_total($total);
941
+		// only update the related transaction's total
942
+		// if we intend to save this line item and its a grand total
943
+		if ($this->allow_persist() && $this->type() === EEM_Line_Item::type_total
944
+			&& $this->transaction()
945
+			   instanceof
946
+			   EE_Transaction
947
+		) {
948
+			$this->transaction()->set_total($total);
949
+			if ($this->transaction()->ID()) {
950
+				$this->transaction()->save();
951
+			}
952
+		}
953
+		$this->maybe_save();
954
+		return $total;
955
+	}
956
+
957
+
958
+	/**
959
+	 * Recursively goes through all the children and recalculates sub-totals EXCEPT for
960
+	 * tax-sub-totals (they're a an odd beast). Updates the 'total' on each line item according to either its
961
+	 * unit price * quantity or the total of all its children EXCEPT when we're only calculating the taxable total and
962
+	 * when this is called on the grand total
963
+	 *
964
+	 * @return float
965
+	 * @throws InvalidArgumentException
966
+	 * @throws InvalidInterfaceException
967
+	 * @throws InvalidDataTypeException
968
+	 * @throws EE_Error
969
+	 */
970
+	public function recalculate_pre_tax_total()
971
+	{
972
+		$total = 0;
973
+		$my_children = $this->children();
974
+		$has_children = ! empty($my_children);
975
+		if ($has_children && $this->is_line_item()) {
976
+			$total = $this->_recalculate_pretax_total_for_line_item($total, $my_children);
977
+		} elseif (! $has_children && ($this->is_sub_line_item() || $this->is_line_item())) {
978
+			$total = $this->unit_price() * $this->quantity();
979
+		} elseif ($this->is_sub_total() || $this->is_total()) {
980
+			$total = $this->_recalculate_pretax_total_for_subtotal($total, $my_children);
981
+		} elseif ($this->is_tax_sub_total() || $this->is_tax() || $this->is_cancelled()) {
982
+			// completely ignore tax totals, tax sub-totals, and cancelled line items, when calculating the pre-tax-total
983
+			return 0;
984
+		}
985
+		// ensure all non-line items and non-sub-line-items have a quantity of 1 (except for Events)
986
+		if (! $this->is_line_item() && ! $this->is_sub_line_item() && ! $this->is_cancellation()
987
+		) {
988
+			if ($this->OBJ_type() !== 'Event') {
989
+				$this->set_quantity(1);
990
+			}
991
+			if (! $this->is_percent()) {
992
+				$this->set_unit_price($total);
993
+			}
994
+		}
995
+		// we don't want to bother saving grand totals, because that needs to factor in taxes anyways
996
+		// so it ought to be
997
+		if (! $this->is_total()) {
998
+			$this->set_total($total);
999
+			// if not a percent line item, make sure we keep the unit price in sync
1000
+			if ($has_children
1001
+				&& $this->is_line_item()
1002
+				&& ! $this->is_percent()
1003
+			) {
1004
+				if ($this->quantity() === 0) {
1005
+					$new_unit_price = 0;
1006
+				} else {
1007
+					$new_unit_price = $this->total() / $this->quantity();
1008
+				}
1009
+				$this->set_unit_price($new_unit_price);
1010
+			}
1011
+			$this->maybe_save();
1012
+		}
1013
+		return $total;
1014
+	}
1015
+
1016
+
1017
+	/**
1018
+	 * Calculates the pretax total when this line item is a subtotal or total line item.
1019
+	 * Basically does a sum-then-round approach (ie, any percent line item that are children
1020
+	 * will calculate their total based on the un-rounded total we're working with so far, and
1021
+	 * THEN round the result; instead of rounding as we go like with sub-line-items)
1022
+	 *
1023
+	 * @param float          $calculated_total_so_far
1024
+	 * @param EE_Line_Item[] $my_children
1025
+	 * @return float
1026
+	 * @throws InvalidArgumentException
1027
+	 * @throws InvalidInterfaceException
1028
+	 * @throws InvalidDataTypeException
1029
+	 * @throws EE_Error
1030
+	 */
1031
+	protected function _recalculate_pretax_total_for_subtotal($calculated_total_so_far, $my_children = null)
1032
+	{
1033
+		if ($my_children === null) {
1034
+			$my_children = $this->children();
1035
+		}
1036
+		$subtotal_quantity = 0;
1037
+		// get the total of all its children
1038
+		foreach ($my_children as $child_line_item) {
1039
+			if ($child_line_item instanceof EE_Line_Item && ! $child_line_item->is_cancellation()) {
1040
+				// percentage line items are based on total so far
1041
+				if ($child_line_item->is_percent()) {
1042
+					// round as we go so that the line items add up ok
1043
+					$percent_total = round(
1044
+						$calculated_total_so_far * $child_line_item->percent() / 100,
1045
+						EE_Registry::instance()->CFG->currency->dec_plc
1046
+					);
1047
+					$child_line_item->set_total($percent_total);
1048
+					// so far all percent line items should have a quantity of 1
1049
+					// (ie, no double percent discounts. Although that might be requested someday)
1050
+					$child_line_item->set_quantity(1);
1051
+					$child_line_item->maybe_save();
1052
+					$calculated_total_so_far += $percent_total;
1053
+				} else {
1054
+					// verify flat sub-line-item quantities match their parent
1055
+					if ($child_line_item->is_sub_line_item()) {
1056
+						$child_line_item->set_quantity($this->quantity());
1057
+					}
1058
+					$calculated_total_so_far += $child_line_item->recalculate_pre_tax_total();
1059
+					$subtotal_quantity += $child_line_item->quantity();
1060
+				}
1061
+			}
1062
+		}
1063
+		if ($this->is_sub_total()) {
1064
+			// no negative totals plz
1065
+			$calculated_total_so_far = max($calculated_total_so_far, 0);
1066
+			$subtotal_quantity = $subtotal_quantity > 0 ? 1 : 0;
1067
+			$this->set_quantity($subtotal_quantity);
1068
+			$this->maybe_save();
1069
+		}
1070
+		return $calculated_total_so_far;
1071
+	}
1072
+
1073
+
1074
+	/**
1075
+	 * Calculates the pretax total for a normal line item, in a round-then-sum approach
1076
+	 * (where each sub-line-item is applied to the base price for the line item
1077
+	 * and the result is immediately rounded, rather than summing all the sub-line-items
1078
+	 * then rounding, like we do when recalculating pretax totals on totals and subtotals).
1079
+	 *
1080
+	 * @param float          $calculated_total_so_far
1081
+	 * @param EE_Line_Item[] $my_children
1082
+	 * @return float
1083
+	 * @throws InvalidArgumentException
1084
+	 * @throws InvalidInterfaceException
1085
+	 * @throws InvalidDataTypeException
1086
+	 * @throws EE_Error
1087
+	 */
1088
+	protected function _recalculate_pretax_total_for_line_item($calculated_total_so_far, $my_children = null)
1089
+	{
1090
+		if ($my_children === null) {
1091
+			$my_children = $this->children();
1092
+		}
1093
+		// we need to keep track of the running total for a single item,
1094
+		// because we need to round as we go
1095
+		$unit_price_for_total = 0;
1096
+		$quantity_for_total = 1;
1097
+		// get the total of all its children
1098
+		foreach ($my_children as $child_line_item) {
1099
+			if ($child_line_item instanceof EE_Line_Item && ! $child_line_item->is_cancellation()) {
1100
+				if ($child_line_item->is_percent()) {
1101
+					// it should be the unit-price-so-far multiplied by teh percent multiplied by the quantity
1102
+					// not total multiplied by percent, because that ignores rounding along-the-way
1103
+					$percent_unit_price = round(
1104
+						$unit_price_for_total * $child_line_item->percent() / 100,
1105
+						EE_Registry::instance()->CFG->currency->dec_plc
1106
+					);
1107
+					$percent_total = $percent_unit_price * $quantity_for_total;
1108
+					$child_line_item->set_total($percent_total);
1109
+					// so far all percent line items should have a quantity of 1
1110
+					// (ie, no double percent discounts. Although that might be requested someday)
1111
+					$child_line_item->set_quantity(1);
1112
+					$child_line_item->maybe_save();
1113
+					$calculated_total_so_far += $percent_total;
1114
+					$unit_price_for_total += $percent_unit_price;
1115
+				} else {
1116
+					// verify flat sub-line-item quantities match their parent
1117
+					if ($child_line_item->is_sub_line_item()) {
1118
+						$child_line_item->set_quantity($this->quantity());
1119
+					}
1120
+					$quantity_for_total = $child_line_item->quantity();
1121
+					$calculated_total_so_far += $child_line_item->recalculate_pre_tax_total();
1122
+					$unit_price_for_total += $child_line_item->unit_price();
1123
+				}
1124
+			}
1125
+		}
1126
+		return $calculated_total_so_far;
1127
+	}
1128
+
1129
+
1130
+	/**
1131
+	 * Recalculates the total on each individual tax (based on a recalculation of the pre-tax total), sets
1132
+	 * the totals on each tax calculated, and returns the final tax total. Re-saves tax line items
1133
+	 * and tax sub-total if already in the DB
1134
+	 *
1135
+	 * @return float
1136
+	 * @throws EE_Error
1137
+	 */
1138
+	public function recalculate_taxes_and_tax_total()
1139
+	{
1140
+		// get all taxes
1141
+		$taxes = $this->tax_descendants();
1142
+		// calculate the pretax total
1143
+		$taxable_total = $this->taxable_total();
1144
+		$tax_total = 0;
1145
+		foreach ($taxes as $tax) {
1146
+			$total_on_this_tax = $taxable_total * $tax->percent() / 100;
1147
+			// remember the total on this line item
1148
+			$tax->set_total($total_on_this_tax);
1149
+			$tax->maybe_save();
1150
+			$tax_total += $tax->total();
1151
+		}
1152
+		$this->_recalculate_tax_sub_total();
1153
+		return $tax_total;
1154
+	}
1155
+
1156
+
1157
+	/**
1158
+	 * Simply forces all the tax-sub-totals to recalculate. Assumes the taxes have been calculated
1159
+	 *
1160
+	 * @return void
1161
+	 * @throws EE_Error
1162
+	 */
1163
+	private function _recalculate_tax_sub_total()
1164
+	{
1165
+		if ($this->is_tax_sub_total()) {
1166
+			$total = 0;
1167
+			$total_percent = 0;
1168
+			// simply loop through all its children (which should be taxes) and sum their total
1169
+			foreach ($this->children() as $child_tax) {
1170
+				if ($child_tax instanceof EE_Line_Item) {
1171
+					$total += $child_tax->total();
1172
+					$total_percent += $child_tax->percent();
1173
+				}
1174
+			}
1175
+			$this->set_total($total);
1176
+			$this->set_percent($total_percent);
1177
+			$this->maybe_save();
1178
+		} elseif ($this->is_total()) {
1179
+			foreach ($this->children() as $maybe_tax_subtotal) {
1180
+				if ($maybe_tax_subtotal instanceof EE_Line_Item) {
1181
+					$maybe_tax_subtotal->_recalculate_tax_sub_total();
1182
+				}
1183
+			}
1184
+		}
1185
+	}
1186
+
1187
+
1188
+	/**
1189
+	 * Gets the total tax on this line item. Assumes taxes have already been calculated using
1190
+	 * recalculate_taxes_and_total
1191
+	 *
1192
+	 * @return float
1193
+	 * @throws EE_Error
1194
+	 */
1195
+	public function get_total_tax()
1196
+	{
1197
+		$this->_recalculate_tax_sub_total();
1198
+		$total = 0;
1199
+		foreach ($this->tax_descendants() as $tax_line_item) {
1200
+			if ($tax_line_item instanceof EE_Line_Item) {
1201
+				$total += $tax_line_item->total();
1202
+			}
1203
+		}
1204
+		return $total;
1205
+	}
1206
+
1207
+
1208
+	/**
1209
+	 * Gets the total for all the items purchased only
1210
+	 *
1211
+	 * @return float
1212
+	 * @throws EE_Error
1213
+	 */
1214
+	public function get_items_total()
1215
+	{
1216
+		// by default, let's make sure we're consistent with the existing line item
1217
+		if ($this->is_total()) {
1218
+			$pretax_subtotal_li = EEH_Line_Item::get_pre_tax_subtotal($this);
1219
+			if ($pretax_subtotal_li instanceof EE_Line_Item) {
1220
+				return $pretax_subtotal_li->total();
1221
+			}
1222
+		}
1223
+		$total = 0;
1224
+		foreach ($this->get_items() as $item) {
1225
+			if ($item instanceof EE_Line_Item) {
1226
+				$total += $item->total();
1227
+			}
1228
+		}
1229
+		return $total;
1230
+	}
1231
+
1232
+
1233
+	/**
1234
+	 * Gets all the descendants (ie, children or children of children etc) that
1235
+	 * are of the type 'tax'
1236
+	 *
1237
+	 * @return EE_Line_Item[]
1238
+	 */
1239
+	public function tax_descendants()
1240
+	{
1241
+		return EEH_Line_Item::get_tax_descendants($this);
1242
+	}
1243
+
1244
+
1245
+	/**
1246
+	 * Gets all the real items purchased which are children of this item
1247
+	 *
1248
+	 * @return EE_Line_Item[]
1249
+	 */
1250
+	public function get_items()
1251
+	{
1252
+		return EEH_Line_Item::get_line_item_descendants($this);
1253
+	}
1254
+
1255
+
1256
+	/**
1257
+	 * Returns the amount taxable among this line item's children (or if it has no children,
1258
+	 * how much of it is taxable). Does not recalculate totals or subtotals.
1259
+	 * If the taxable total is negative, (eg, if none of the tickets were taxable,
1260
+	 * but there is a "Taxable" discount), returns 0.
1261
+	 *
1262
+	 * @return float
1263
+	 * @throws EE_Error
1264
+	 */
1265
+	public function taxable_total()
1266
+	{
1267
+		$total = 0;
1268
+		if ($this->children()) {
1269
+			foreach ($this->children() as $child_line_item) {
1270
+				if ($child_line_item->type() === EEM_Line_Item::type_line_item && $child_line_item->is_taxable()) {
1271
+					// if it's a percent item, only take into account the percent
1272
+					// that's taxable too (the taxable total so far)
1273
+					if ($child_line_item->is_percent()) {
1274
+						$total += ($total * $child_line_item->percent() / 100);
1275
+					} else {
1276
+						$total += $child_line_item->total();
1277
+					}
1278
+				} elseif ($child_line_item->type() === EEM_Line_Item::type_sub_total) {
1279
+					$total += $child_line_item->taxable_total();
1280
+				}
1281
+			}
1282
+		}
1283
+		return max($total, 0);
1284
+	}
1285
+
1286
+
1287
+	/**
1288
+	 * Gets the transaction for this line item
1289
+	 *
1290
+	 * @return EE_Base_Class|EE_Transaction
1291
+	 * @throws EE_Error
1292
+	 */
1293
+	public function transaction()
1294
+	{
1295
+		return $this->get_first_related('Transaction');
1296
+	}
1297
+
1298
+
1299
+	/**
1300
+	 * Saves this line item to the DB, and recursively saves its descendants.
1301
+	 * Because there currently is no proper parent-child relation on the model,
1302
+	 * save_this_and_cached() will NOT save the descendants.
1303
+	 * Also sets the transaction on this line item and all its descendants before saving
1304
+	 *
1305
+	 * @param int $txn_id if none is provided, assumes $this->TXN_ID()
1306
+	 * @return int count of items saved
1307
+	 * @throws EE_Error
1308
+	 */
1309
+	public function save_this_and_descendants_to_txn($txn_id = null)
1310
+	{
1311
+		$count = 0;
1312
+		if (! $txn_id) {
1313
+			$txn_id = $this->TXN_ID();
1314
+		}
1315
+		$this->set_TXN_ID($txn_id);
1316
+		$children = $this->children();
1317
+		$count += $this->save()
1318
+			? 1
1319
+			: 0;
1320
+		foreach ($children as $child_line_item) {
1321
+			if ($child_line_item instanceof EE_Line_Item) {
1322
+				$child_line_item->set_parent_ID($this->ID());
1323
+				$count += $child_line_item->save_this_and_descendants_to_txn($txn_id);
1324
+			}
1325
+		}
1326
+		return $count;
1327
+	}
1328
+
1329
+
1330
+	/**
1331
+	 * Saves this line item to the DB, and recursively saves its descendants.
1332
+	 *
1333
+	 * @return int count of items saved
1334
+	 * @throws EE_Error
1335
+	 */
1336
+	public function save_this_and_descendants()
1337
+	{
1338
+		$count = 0;
1339
+		$children = $this->children();
1340
+		$count += $this->save()
1341
+			? 1
1342
+			: 0;
1343
+		foreach ($children as $child_line_item) {
1344
+			if ($child_line_item instanceof EE_Line_Item) {
1345
+				$child_line_item->set_parent_ID($this->ID());
1346
+				$count += $child_line_item->save_this_and_descendants();
1347
+			}
1348
+		}
1349
+		return $count;
1350
+	}
1351
+
1352
+
1353
+	/**
1354
+	 * returns the cancellation line item if this item was cancelled
1355
+	 *
1356
+	 * @return EE_Line_Item[]
1357
+	 * @throws InvalidArgumentException
1358
+	 * @throws InvalidInterfaceException
1359
+	 * @throws InvalidDataTypeException
1360
+	 * @throws ReflectionException
1361
+	 * @throws EE_Error
1362
+	 */
1363
+	public function get_cancellations()
1364
+	{
1365
+		EE_Registry::instance()->load_helper('Line_Item');
1366
+		return EEH_Line_Item::get_descendants_of_type($this, EEM_Line_Item::type_cancellation);
1367
+	}
1368
+
1369
+
1370
+	/**
1371
+	 * If this item has an ID, then this saves it again to update the db
1372
+	 *
1373
+	 * @return int count of items saved
1374
+	 * @throws EE_Error
1375
+	 */
1376
+	public function maybe_save()
1377
+	{
1378
+		if ($this->ID()) {
1379
+			return $this->save();
1380
+		}
1381
+		return false;
1382
+	}
1383
+
1384
+
1385
+	/**
1386
+	 * clears the cached children and parent from the line item
1387
+	 *
1388
+	 * @return void
1389
+	 */
1390
+	public function clear_related_line_item_cache()
1391
+	{
1392
+		$this->_children = array();
1393
+		$this->_parent = null;
1394
+	}
1395
+
1396
+
1397
+	/**
1398
+	 * @param bool $raw
1399
+	 * @return int
1400
+	 * @throws EE_Error
1401
+	 */
1402
+	public function timestamp($raw = false)
1403
+	{
1404
+		return $raw
1405
+			? $this->get_raw('LIN_timestamp')
1406
+			: $this->get('LIN_timestamp');
1407
+	}
1408
+
1409
+
1410
+
1411
+
1412
+	/************************* DEPRECATED *************************/
1413
+	/**
1414
+	 * @deprecated 4.6.0
1415
+	 * @param string $type one of the constants on EEM_Line_Item
1416
+	 * @return EE_Line_Item[]
1417
+	 */
1418
+	protected function _get_descendants_of_type($type)
1419
+	{
1420
+		EE_Error::doing_it_wrong(
1421
+			'EE_Line_Item::_get_descendants_of_type()',
1422
+			__('Method replaced with EEH_Line_Item::get_descendants_of_type()', 'event_espresso'),
1423
+			'4.6.0'
1424
+		);
1425
+		return EEH_Line_Item::get_descendants_of_type($this, $type);
1426
+	}
1427
+
1428
+
1429
+	/**
1430
+	 * @deprecated 4.6.0
1431
+	 * @param string $type like one of the EEM_Line_Item::type_*
1432
+	 * @return EE_Line_Item
1433
+	 */
1434
+	public function get_nearest_descendant_of_type($type)
1435
+	{
1436
+		EE_Error::doing_it_wrong(
1437
+			'EE_Line_Item::get_nearest_descendant_of_type()',
1438
+			__('Method replaced with EEH_Line_Item::get_nearest_descendant_of_type()', 'event_espresso'),
1439
+			'4.6.0'
1440
+		);
1441
+		return EEH_Line_Item::get_nearest_descendant_of_type($this, $type);
1442
+	}
1443 1443
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -72,7 +72,7 @@  discard block
 block discarded – undo
72 72
     protected function __construct($fieldValues = array(), $bydb = false, $timezone = '')
73 73
     {
74 74
         parent::__construct($fieldValues, $bydb, $timezone);
75
-        if (! $this->get('LIN_code')) {
75
+        if ( ! $this->get('LIN_code')) {
76 76
             $this->set_code($this->generate_code());
77 77
         }
78 78
     }
@@ -123,7 +123,7 @@  discard block
 block discarded – undo
123 123
     public function name()
124 124
     {
125 125
         $name = $this->get('LIN_name');
126
-        if (! $name) {
126
+        if ( ! $name) {
127 127
             $name = ucwords(str_replace('-', ' ', $this->type()));
128 128
         }
129 129
         return $name;
@@ -480,7 +480,7 @@  discard block
 block discarded – undo
480 480
                 )
481 481
             );
482 482
         }
483
-        if (! is_array($this->_children)) {
483
+        if ( ! is_array($this->_children)) {
484 484
             $this->_children = array();
485 485
         }
486 486
         return $this->_children;
@@ -676,7 +676,7 @@  discard block
 block discarded – undo
676 676
             }
677 677
             return $line_item->save();
678 678
         }
679
-        $this->_children[ $line_item->code() ] = $line_item;
679
+        $this->_children[$line_item->code()] = $line_item;
680 680
         if ($line_item->parent() !== $this) {
681 681
             $line_item->set_parent($this);
682 682
         }
@@ -696,7 +696,7 @@  discard block
 block discarded – undo
696 696
     public function set_parent($line_item)
697 697
     {
698 698
         if ($this->ID()) {
699
-            if (! $line_item->ID()) {
699
+            if ( ! $line_item->ID()) {
700 700
                 $line_item->save();
701 701
             }
702 702
             $this->set_parent_ID($line_item->ID());
@@ -724,8 +724,8 @@  discard block
 block discarded – undo
724 724
                 array(array('LIN_parent' => $this->ID(), 'LIN_code' => $code))
725 725
             );
726 726
         }
727
-        return isset($this->_children[ $code ])
728
-            ? $this->_children[ $code ]
727
+        return isset($this->_children[$code])
728
+            ? $this->_children[$code]
729 729
             : null;
730 730
     }
731 731
 
@@ -777,8 +777,8 @@  discard block
 block discarded – undo
777 777
             }
778 778
             return $items_deleted;
779 779
         }
780
-        if (isset($this->_children[ $code ])) {
781
-            unset($this->_children[ $code ]);
780
+        if (isset($this->_children[$code])) {
781
+            unset($this->_children[$code]);
782 782
             return 1;
783 783
         }
784 784
         return 0;
@@ -811,7 +811,7 @@  discard block
 block discarded – undo
811 811
     public function generate_code()
812 812
     {
813 813
         // each line item in the cart requires a unique identifier
814
-        return md5($this->get('OBJ_type') . $this->get('OBJ_ID') . microtime());
814
+        return md5($this->get('OBJ_type').$this->get('OBJ_ID').microtime());
815 815
     }
816 816
 
817 817
 
@@ -974,7 +974,7 @@  discard block
 block discarded – undo
974 974
         $has_children = ! empty($my_children);
975 975
         if ($has_children && $this->is_line_item()) {
976 976
             $total = $this->_recalculate_pretax_total_for_line_item($total, $my_children);
977
-        } elseif (! $has_children && ($this->is_sub_line_item() || $this->is_line_item())) {
977
+        } elseif ( ! $has_children && ($this->is_sub_line_item() || $this->is_line_item())) {
978 978
             $total = $this->unit_price() * $this->quantity();
979 979
         } elseif ($this->is_sub_total() || $this->is_total()) {
980 980
             $total = $this->_recalculate_pretax_total_for_subtotal($total, $my_children);
@@ -983,18 +983,18 @@  discard block
 block discarded – undo
983 983
             return 0;
984 984
         }
985 985
         // ensure all non-line items and non-sub-line-items have a quantity of 1 (except for Events)
986
-        if (! $this->is_line_item() && ! $this->is_sub_line_item() && ! $this->is_cancellation()
986
+        if ( ! $this->is_line_item() && ! $this->is_sub_line_item() && ! $this->is_cancellation()
987 987
         ) {
988 988
             if ($this->OBJ_type() !== 'Event') {
989 989
                 $this->set_quantity(1);
990 990
             }
991
-            if (! $this->is_percent()) {
991
+            if ( ! $this->is_percent()) {
992 992
                 $this->set_unit_price($total);
993 993
             }
994 994
         }
995 995
         // we don't want to bother saving grand totals, because that needs to factor in taxes anyways
996 996
         // so it ought to be
997
-        if (! $this->is_total()) {
997
+        if ( ! $this->is_total()) {
998 998
             $this->set_total($total);
999 999
             // if not a percent line item, make sure we keep the unit price in sync
1000 1000
             if ($has_children
@@ -1309,7 +1309,7 @@  discard block
 block discarded – undo
1309 1309
     public function save_this_and_descendants_to_txn($txn_id = null)
1310 1310
     {
1311 1311
         $count = 0;
1312
-        if (! $txn_id) {
1312
+        if ( ! $txn_id) {
1313 1313
             $txn_id = $this->TXN_ID();
1314 1314
         }
1315 1315
         $this->set_TXN_ID($txn_id);
Please login to merge, or discard this patch.
core/db_classes/EE_Term_Relationship.class.php 1 patch
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -10,23 +10,23 @@
 block discarded – undo
10 10
 class EE_Term_Relationship extends EE_Base_Class
11 11
 {
12 12
 
13
-    /**
14
-     * @param array $props_n_values
15
-     * @return EE_Term_Relationship
16
-     */
17
-    public static function new_instance($props_n_values = array())
18
-    {
19
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
20
-        return $has_object ? $has_object : new self($props_n_values);
21
-    }
13
+	/**
14
+	 * @param array $props_n_values
15
+	 * @return EE_Term_Relationship
16
+	 */
17
+	public static function new_instance($props_n_values = array())
18
+	{
19
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
20
+		return $has_object ? $has_object : new self($props_n_values);
21
+	}
22 22
 
23 23
 
24
-    /**
25
-     * @param array $props_n_values
26
-     * @return EE_Term_Relationship
27
-     */
28
-    public static function new_instance_from_db($props_n_values = array())
29
-    {
30
-        return new self($props_n_values, true);
31
-    }
24
+	/**
25
+	 * @param array $props_n_values
26
+	 * @return EE_Term_Relationship
27
+	 */
28
+	public static function new_instance_from_db($props_n_values = array())
29
+	{
30
+		return new self($props_n_values, true);
31
+	}
32 32
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Country.class.php 1 patch
Indentation   +119 added lines, -119 removed lines patch added patch discarded remove patch
@@ -10,123 +10,123 @@
 block discarded – undo
10 10
 class EE_Country extends EE_Base_Class
11 11
 {
12 12
 
13
-    /**
14
-     * @param array $props_n_values
15
-     * @return EE_Country|mixed
16
-     */
17
-    public static function new_instance($props_n_values = array())
18
-    {
19
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
20
-        return $has_object ? $has_object : new self($props_n_values);
21
-    }
22
-
23
-
24
-    /**
25
-     * @param array $props_n_values
26
-     * @return EE_Country
27
-     */
28
-    public static function new_instance_from_db($props_n_values = array())
29
-    {
30
-        return new self($props_n_values, true);
31
-    }
32
-
33
-
34
-    /**
35
-     * Gets the country name
36
-     *
37
-     * @return string
38
-     */
39
-    public function name()
40
-    {
41
-        return $this->get('CNT_name');
42
-    }
43
-
44
-
45
-    /**
46
-     * gets the country's currency code
47
-     *
48
-     * @return string
49
-     */
50
-    public function currency_code()
51
-    {
52
-        return $this->get('CNT_cur_code');
53
-    }
54
-
55
-
56
-    /**
57
-     * gets the country's currency sign/symbol
58
-     *
59
-     * @return string
60
-     */
61
-    public function currency_sign()
62
-    {
63
-        $CNT_cur_sign = $this->get('CNT_cur_sign');
64
-        return $CNT_cur_sign ? $CNT_cur_sign : '';
65
-    }
66
-
67
-
68
-    /**
69
-     * Currency name singular
70
-     *
71
-     * @return string
72
-     */
73
-    public function currency_name_single()
74
-    {
75
-        return $this->get('CNT_cur_single');
76
-    }
77
-
78
-
79
-    /**
80
-     * Currency name plural
81
-     *
82
-     * @return string
83
-     */
84
-    public function currency_name_plural()
85
-    {
86
-        return $this->get('CNT_cur_plural');
87
-    }
88
-
89
-
90
-    /**
91
-     * currency_sign_before - ie: $TRUE  or  FALSE$
92
-     *
93
-     * @return boolean
94
-     */
95
-    public function currency_sign_before()
96
-    {
97
-        return $this->get('CNT_cur_sign_b4');
98
-    }
99
-
100
-
101
-    /**
102
-     * currency_decimal_places : 2 = 0.00   3 = 0.000
103
-     *
104
-     * @return integer
105
-     */
106
-    public function currency_decimal_places()
107
-    {
108
-        return $this->get('CNT_cur_dec_plc');
109
-    }
110
-
111
-
112
-    /**
113
-     * currency_decimal_mark :   (comma) ',' = 0,01   or   (decimal) '.' = 0.01
114
-     *
115
-     * @return string
116
-     */
117
-    public function currency_decimal_mark()
118
-    {
119
-        return $this->get('CNT_cur_dec_mrk');
120
-    }
121
-
122
-
123
-    /**
124
-     * currency thousands separator:   (comma) ',' = 1,000   or   (decimal) '.' = 1.000
125
-     *
126
-     * @return string
127
-     */
128
-    public function currency_thousands_separator()
129
-    {
130
-        return $this->get('CNT_cur_thsnds');
131
-    }
13
+	/**
14
+	 * @param array $props_n_values
15
+	 * @return EE_Country|mixed
16
+	 */
17
+	public static function new_instance($props_n_values = array())
18
+	{
19
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
20
+		return $has_object ? $has_object : new self($props_n_values);
21
+	}
22
+
23
+
24
+	/**
25
+	 * @param array $props_n_values
26
+	 * @return EE_Country
27
+	 */
28
+	public static function new_instance_from_db($props_n_values = array())
29
+	{
30
+		return new self($props_n_values, true);
31
+	}
32
+
33
+
34
+	/**
35
+	 * Gets the country name
36
+	 *
37
+	 * @return string
38
+	 */
39
+	public function name()
40
+	{
41
+		return $this->get('CNT_name');
42
+	}
43
+
44
+
45
+	/**
46
+	 * gets the country's currency code
47
+	 *
48
+	 * @return string
49
+	 */
50
+	public function currency_code()
51
+	{
52
+		return $this->get('CNT_cur_code');
53
+	}
54
+
55
+
56
+	/**
57
+	 * gets the country's currency sign/symbol
58
+	 *
59
+	 * @return string
60
+	 */
61
+	public function currency_sign()
62
+	{
63
+		$CNT_cur_sign = $this->get('CNT_cur_sign');
64
+		return $CNT_cur_sign ? $CNT_cur_sign : '';
65
+	}
66
+
67
+
68
+	/**
69
+	 * Currency name singular
70
+	 *
71
+	 * @return string
72
+	 */
73
+	public function currency_name_single()
74
+	{
75
+		return $this->get('CNT_cur_single');
76
+	}
77
+
78
+
79
+	/**
80
+	 * Currency name plural
81
+	 *
82
+	 * @return string
83
+	 */
84
+	public function currency_name_plural()
85
+	{
86
+		return $this->get('CNT_cur_plural');
87
+	}
88
+
89
+
90
+	/**
91
+	 * currency_sign_before - ie: $TRUE  or  FALSE$
92
+	 *
93
+	 * @return boolean
94
+	 */
95
+	public function currency_sign_before()
96
+	{
97
+		return $this->get('CNT_cur_sign_b4');
98
+	}
99
+
100
+
101
+	/**
102
+	 * currency_decimal_places : 2 = 0.00   3 = 0.000
103
+	 *
104
+	 * @return integer
105
+	 */
106
+	public function currency_decimal_places()
107
+	{
108
+		return $this->get('CNT_cur_dec_plc');
109
+	}
110
+
111
+
112
+	/**
113
+	 * currency_decimal_mark :   (comma) ',' = 0,01   or   (decimal) '.' = 0.01
114
+	 *
115
+	 * @return string
116
+	 */
117
+	public function currency_decimal_mark()
118
+	{
119
+		return $this->get('CNT_cur_dec_mrk');
120
+	}
121
+
122
+
123
+	/**
124
+	 * currency thousands separator:   (comma) ',' = 1,000   or   (decimal) '.' = 1.000
125
+	 *
126
+	 * @return string
127
+	 */
128
+	public function currency_thousands_separator()
129
+	{
130
+		return $this->get('CNT_cur_thsnds');
131
+	}
132 132
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Message.class.php 2 patches
Indentation   +867 added lines, -867 removed lines patch added patch discarded remove patch
@@ -10,875 +10,875 @@
 block discarded – undo
10 10
 class EE_Message extends EE_Base_Class implements EEI_Admin_Links
11 11
 {
12 12
 
13
-    /**
14
-     * @deprecated 4.9.0  Added for backward compat with add-on's
15
-     * @type null
16
-     */
17
-    public $template_pack;
18
-
19
-    /**
20
-     * @deprecated 4.9.0 Added for backward compat with add-on's
21
-     * @type null
22
-     */
23
-    public $template_variation;
24
-
25
-    /**
26
-     * @deprecated 4.9.0 Added for backward compat with add-on's
27
-     * @type string
28
-     */
29
-    public $content = '';
30
-
31
-
32
-    /**
33
-     * @type EE_messenger $_messenger
34
-     */
35
-    protected $_messenger = null;
36
-
37
-    /**
38
-     * @type EE_message_type $_message_type
39
-     */
40
-    protected $_message_type = null;
41
-
42
-
43
-    /**
44
-     * @param array  $props_n_values
45
-     * @param string $timezone
46
-     * @param array  $date_formats incoming date formats in an array.  First value is the date_format, second is time
47
-     *                             format.
48
-     * @return EE_Message
49
-     */
50
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
51
-    {
52
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
53
-        // if object doesn't exist, let's generate a unique token on instantiation so that its available even before saving to db.
54
-        if (! $has_object) {
55
-            EE_Registry::instance()->load_helper('URL');
56
-            $props_n_values['MSG_token'] = EEH_URL::generate_unique_token();
57
-        }
58
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
59
-    }
60
-
61
-
62
-    /**
63
-     * @param array  $props_n_values
64
-     * @param string $timezone
65
-     * @return EE_Message
66
-     */
67
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
68
-    {
69
-        return new self($props_n_values, true, $timezone);
70
-    }
71
-
72
-
73
-    /**
74
-     * Gets MSG_token
75
-     *
76
-     * @return int
77
-     */
78
-    public function MSG_token()
79
-    {
80
-        return $this->get('MSG_token');
81
-    }
82
-
83
-
84
-    /**
85
-     * Sets MSG_token
86
-     *
87
-     * @param int $MSG_token
88
-     */
89
-    public function set_MSG_token($MSG_token)
90
-    {
91
-        $this->set('MSG_token', $MSG_token);
92
-    }
93
-
94
-
95
-    /**
96
-     * Gets GRP_ID
97
-     *
98
-     * @return int
99
-     */
100
-    public function GRP_ID()
101
-    {
102
-        return $this->get('GRP_ID');
103
-    }
104
-
105
-
106
-    /**
107
-     * Sets GRP_ID
108
-     *
109
-     * @param int $GRP_ID
110
-     */
111
-    public function set_GRP_ID($GRP_ID)
112
-    {
113
-        $this->set('GRP_ID', $GRP_ID);
114
-    }
115
-
116
-
117
-    /**
118
-     * Gets TXN_ID
119
-     *
120
-     * @return int
121
-     */
122
-    public function TXN_ID()
123
-    {
124
-        return $this->get('TXN_ID');
125
-    }
126
-
127
-
128
-    /**
129
-     * Sets TXN_ID
130
-     *
131
-     * @param int $TXN_ID
132
-     */
133
-    public function set_TXN_ID($TXN_ID)
134
-    {
135
-        $this->set('TXN_ID', $TXN_ID);
136
-    }
137
-
138
-
139
-    /**
140
-     * Gets messenger
141
-     *
142
-     * @return string
143
-     */
144
-    public function messenger()
145
-    {
146
-        return $this->get('MSG_messenger');
147
-    }
148
-
149
-
150
-    /**
151
-     * Sets messenger
152
-     *
153
-     * @param string $messenger
154
-     */
155
-    public function set_messenger($messenger)
156
-    {
157
-        $this->set('MSG_messenger', $messenger);
158
-    }
159
-
160
-
161
-    /**
162
-     * Returns corresponding messenger object for the set messenger on this message
163
-     *
164
-     * @return EE_messenger | null
165
-     */
166
-    public function messenger_object()
167
-    {
168
-        return $this->_messenger;
169
-    }
170
-
171
-
172
-    /**
173
-     * Sets messenger
174
-     *
175
-     * @param EE_messenger $messenger
176
-     */
177
-    public function set_messenger_object(EE_messenger $messenger)
178
-    {
179
-        $this->_messenger = $messenger;
180
-    }
181
-
182
-
183
-    /**
184
-     * validates messenger
185
-     *
186
-     * @param bool $throw_exceptions
187
-     * @return bool
188
-     * @throws \EE_Error
189
-     */
190
-    public function valid_messenger($throw_exceptions = false)
191
-    {
192
-        if ($this->_messenger instanceof EE_messenger) {
193
-            return true;
194
-        }
195
-        if ($throw_exceptions) {
196
-            throw new EE_Error(
197
-                sprintf(
198
-                    __(
199
-                        'The "%1$s" messenger set for this message is missing or invalid. Please double-check the spelling and verify that the correct files exist.',
200
-                        'event_espresso'
201
-                    ),
202
-                    $this->messenger()
203
-                )
204
-            );
205
-        }
206
-        return false;
207
-    }
208
-
209
-
210
-    /**
211
-     * This returns the set localized label for the messenger on this message.
212
-     * Note, if unable to retrieve the EE_messenger object then will just return the messenger slug saved
213
-     * with this message.
214
-     *
215
-     * @param   bool $plural whether to return the plural label or not.
216
-     * @return string
217
-     */
218
-    public function messenger_label($plural = false)
219
-    {
220
-        $label_type = $plural ? 'plural' : 'singular';
221
-        $messenger = $this->messenger_object();
222
-        return $messenger instanceof EE_messenger ? $messenger->label[ $label_type ] : $this->messenger();
223
-    }
224
-
225
-
226
-    /**
227
-     * Gets message_type
228
-     *
229
-     * @return string
230
-     */
231
-    public function message_type()
232
-    {
233
-        return $this->get('MSG_message_type');
234
-    }
235
-
236
-
237
-    /**
238
-     * Sets message_type
239
-     *
240
-     * @param string $message_type
241
-     */
242
-    public function set_message_type($message_type)
243
-    {
244
-        $this->set('MSG_message_type', $message_type);
245
-    }
246
-
247
-
248
-    /**
249
-     * Returns the message type object for the set message type on this message
250
-     *
251
-     * @return EE_message_type | null
252
-     */
253
-    public function message_type_object()
254
-    {
255
-        return $this->_message_type;
256
-    }
257
-
258
-
259
-    /**
260
-     * Sets message_type
261
-     *
262
-     * @param EE_message_type $message_type
263
-     * @param bool            $set_priority   This indicates whether to set the priority to whatever the priority is on
264
-     *                                        the message type or not.
265
-     */
266
-    public function set_message_type_object(EE_message_type $message_type, $set_priority = false)
267
-    {
268
-        $this->_message_type = $message_type;
269
-        if ($set_priority) {
270
-            $this->set_priority($this->_message_type->get_priority());
271
-        }
272
-    }
273
-
274
-
275
-    /**
276
-     * validates message_type
277
-     *
278
-     * @param bool $throw_exceptions
279
-     * @return bool
280
-     * @throws \EE_Error
281
-     */
282
-    public function valid_message_type($throw_exceptions = false)
283
-    {
284
-        if ($this->_message_type instanceof EE_message_type) {
285
-            return true;
286
-        }
287
-        if ($throw_exceptions) {
288
-            throw new EE_Error(
289
-                sprintf(
290
-                    __(
291
-                        'The %1$s message type set for this message is missing or invalid. Please double-check the spelling and verify that the correct files exist.',
292
-                        'event_espresso'
293
-                    ),
294
-                    $this->message_type()
295
-                )
296
-            );
297
-        }
298
-        return false;
299
-    }
300
-
301
-
302
-    /**
303
-     * validates messenger and message_type (that they are valid EE_messenger and EE_message_type objects).
304
-     *
305
-     * @param bool $throw_exceptions
306
-     * @return bool
307
-     * @throws \EE_Error
308
-     */
309
-    public function is_valid($throw_exceptions = false)
310
-    {
311
-        if ($this->valid_messenger($throw_exceptions) && $this->valid_message_type($throw_exceptions)) {
312
-            return true;
313
-        }
314
-        return false;
315
-    }
316
-
317
-
318
-    /**
319
-     * This validates whether the internal messenger and message type objects are valid for sending.
320
-     * Three checks are done:
321
-     * 1. There is a valid messenger object.
322
-     * 2. There is a valid message type object.
323
-     * 3. The message type object is active for the messenger.
324
-     *
325
-     * @throws EE_Error  But only if $throw_exceptions is set to true.
326
-     * @param bool $throw_exceptions
327
-     * @return bool
328
-     */
329
-    public function is_valid_for_sending_or_generation($throw_exceptions = false)
330
-    {
331
-        $valid = false;
332
-        if ($this->is_valid($throw_exceptions)) {
333
-            /** @var EE_Message_Resource_Manager $message_resource_manager */
334
-            $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
335
-            $valid = $message_resource_manager->is_message_type_active_for_messenger(
336
-                $this->messenger(),
337
-                $this->message_type()
338
-            );
339
-            if (! $valid && $throw_exceptions) {
340
-                throw new EE_Error(
341
-                    sprintf(
342
-                        __(
343
-                            'The %1$s message type is not a valid message type for the %2$s messenger so it will not be sent.',
344
-                            'event_espresso'
345
-                        ),
346
-                        $this->message_type(),
347
-                        $this->messenger()
348
-                    )
349
-                );
350
-            }
351
-        }
352
-        return $valid;
353
-    }
354
-
355
-
356
-    /**
357
-     * This returns the set localized label for the message type on this message.
358
-     * Note, if unable to retrieve the EE_message_type object then will just return the message type slug saved
359
-     * with this message.
360
-     *
361
-     * @param   bool $plural whether to return the plural label or not.
362
-     * @return string
363
-     */
364
-    public function message_type_label($plural = false)
365
-    {
366
-        $label_type = $plural ? 'plural' : 'singular';
367
-        $message_type = $this->message_type_object();
368
-        return $message_type instanceof EE_message_type
369
-            ? $message_type->label[ $label_type ]
370
-            : str_replace(
371
-                '_',
372
-                ' ',
373
-                $this->message_type()
374
-            );
375
-    }
376
-
377
-
378
-    /**
379
-     * Gets context
380
-     *
381
-     * @return string
382
-     */
383
-    public function context()
384
-    {
385
-        return $this->get('MSG_context');
386
-    }
387
-
388
-
389
-    /**
390
-     * This returns the corresponding localized label for the given context slug, if possible from installed message
391
-     * types. Otherwise, this will just return the set context slug on this object.
392
-     *
393
-     * @return string
394
-     */
395
-    public function context_label()
396
-    {
397
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
398
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
399
-        $contexts = $message_resource_manager->get_all_contexts();
400
-        return isset($contexts[ $this->context() ]) ? $contexts[ $this->context() ] : $this->context();
401
-    }
402
-
403
-
404
-    /**
405
-     * Sets context
406
-     *
407
-     * @param string $context
408
-     */
409
-    public function set_context($context)
410
-    {
411
-        $this->set('MSG_context', $context);
412
-    }
413
-
414
-
415
-    /**
416
-     * Gets recipient_ID
417
-     *
418
-     * @return int
419
-     */
420
-    public function recipient_ID()
421
-    {
422
-        return $this->get('MSG_recipient_ID');
423
-    }
424
-
425
-
426
-    /**
427
-     * Sets recipient_ID
428
-     *
429
-     * @param string $recipient_ID
430
-     */
431
-    public function set_recipient_ID($recipient_ID)
432
-    {
433
-        $this->set('MSG_recipient_ID', $recipient_ID);
434
-    }
435
-
436
-
437
-    /**
438
-     * Gets recipient_type
439
-     *
440
-     * @return string
441
-     */
442
-    public function recipient_type()
443
-    {
444
-        return $this->get('MSG_recipient_type');
445
-    }
446
-
447
-
448
-    /**
449
-     * Return the related object matching the recipient type and ID.
450
-     *
451
-     * @return EE_Base_Class | null
452
-     */
453
-    public function recipient_object()
454
-    {
455
-        if (! $this->recipient_type() || ! $this->recipient_ID()) {
456
-            return null;
457
-        }
458
-
459
-        return $this->get_first_related($this->recipient_type());
460
-    }
461
-
462
-
463
-    /**
464
-     * Sets recipient_type
465
-     *
466
-     * @param string $recipient_type
467
-     */
468
-    public function set_recipient_type($recipient_type)
469
-    {
470
-        $this->set('MSG_recipient_type', $recipient_type);
471
-    }
472
-
473
-
474
-    /**
475
-     * Gets content
476
-     *
477
-     * @return string
478
-     */
479
-    public function content()
480
-    {
481
-        return $this->get('MSG_content');
482
-    }
483
-
484
-
485
-    /**
486
-     * Sets content
487
-     *
488
-     * @param string $content
489
-     */
490
-    public function set_content($content)
491
-    {
492
-        $this->set('MSG_content', $content);
493
-    }
494
-
495
-
496
-    /**
497
-     * Gets subject
498
-     *
499
-     * @return string
500
-     */
501
-    public function subject()
502
-    {
503
-        return $this->get('MSG_subject');
504
-    }
505
-
506
-
507
-    /**
508
-     * Sets subject
509
-     *
510
-     * @param string $subject
511
-     */
512
-    public function set_subject($subject)
513
-    {
514
-        $this->set('MSG_subject', $subject);
515
-    }
516
-
517
-
518
-    /**
519
-     * Gets to
520
-     *
521
-     * @return string
522
-     */
523
-    public function to()
524
-    {
525
-        $to = $this->get('MSG_to');
526
-        return empty($to) ? __('No recipient', 'event_espresso') : $to;
527
-    }
528
-
529
-
530
-    /**
531
-     * Sets to
532
-     *
533
-     * @param string $to
534
-     */
535
-    public function set_to($to)
536
-    {
537
-        $this->set('MSG_to', $to);
538
-    }
539
-
540
-
541
-    /**
542
-     * Gets from
543
-     *
544
-     * @return string
545
-     */
546
-    public function from()
547
-    {
548
-        return $this->get('MSG_from');
549
-    }
550
-
551
-
552
-    /**
553
-     * Sets from
554
-     *
555
-     * @param string $from
556
-     */
557
-    public function set_from($from)
558
-    {
559
-        $this->set('MSG_from', $from);
560
-    }
561
-
562
-
563
-    /**
564
-     * Gets priority
565
-     *
566
-     * @return int
567
-     */
568
-    public function priority()
569
-    {
570
-        return $this->get('MSG_priority');
571
-    }
572
-
573
-
574
-    /**
575
-     * Sets priority
576
-     * Note.  Send Now Messengers always override any priority that may be set on a Message.  So
577
-     * this method calls the send_now method to verify that.
578
-     *
579
-     * @param int $priority
580
-     */
581
-    public function set_priority($priority)
582
-    {
583
-        $priority = $this->send_now() ? EEM_Message::priority_high : $priority;
584
-        parent::set('MSG_priority', $priority);
585
-    }
586
-
587
-
588
-    /**
589
-     * Overrides parent::set method so we can capture any sets for priority.
590
-     *
591
-     * @see parent::set() for phpdocs
592
-     * @param string $field_name
593
-     * @param mixed  $field_value
594
-     * @param bool   $use_default
595
-     * @throws EE_Error
596
-     */
597
-    public function set($field_name, $field_value, $use_default = false)
598
-    {
599
-        if ($field_name === 'MSG_priority') {
600
-            $this->set_priority($field_value);
601
-        }
602
-        parent::set($field_name, $field_value, $use_default);
603
-    }
604
-
605
-
606
-    /**
607
-     * @return bool
608
-     * @throws \EE_Error
609
-     */
610
-    public function send_now()
611
-    {
612
-        $send_now = $this->valid_messenger() && $this->messenger_object()->send_now() ? EEM_Message::priority_high
613
-            : $this->priority();
614
-        return $send_now === EEM_Message::priority_high ? true : false;
615
-    }
616
-
617
-
618
-    /**
619
-     * Gets STS_ID
620
-     *
621
-     * @return string
622
-     */
623
-    public function STS_ID()
624
-    {
625
-        return $this->get('STS_ID');
626
-    }
627
-
628
-
629
-    /**
630
-     * Sets STS_ID
631
-     *
632
-     * @param string $STS_ID
633
-     */
634
-    public function set_STS_ID($STS_ID)
635
-    {
636
-        $this->set('STS_ID', $STS_ID);
637
-    }
638
-
639
-
640
-    /**
641
-     * Gets created
642
-     *
643
-     * @return string
644
-     */
645
-    public function created()
646
-    {
647
-        return $this->get('MSG_created');
648
-    }
649
-
650
-
651
-    /**
652
-     * Sets created
653
-     *
654
-     * @param string $created
655
-     */
656
-    public function set_created($created)
657
-    {
658
-        $this->set('MSG_created', $created);
659
-    }
660
-
661
-
662
-    /**
663
-     * Gets modified
664
-     *
665
-     * @return string
666
-     */
667
-    public function modified()
668
-    {
669
-        return $this->get('MSG_modified');
670
-    }
671
-
672
-
673
-    /**
674
-     * Sets modified
675
-     *
676
-     * @param string $modified
677
-     */
678
-    public function set_modified($modified)
679
-    {
680
-        $this->set('MSG_modified', $modified);
681
-    }
682
-
683
-
684
-    /**
685
-     * Sets generation data for this message.
686
-     *
687
-     * @param mixed $data
688
-     */
689
-    public function set_generation_data($data)
690
-    {
691
-        $this->set_field_or_extra_meta('MSG_generation_data', $data);
692
-    }
693
-
694
-
695
-    /**
696
-     * Returns any set generation data for this message.
697
-     *
698
-     * @return mixed|null
699
-     */
700
-    public function get_generation_data()
701
-    {
702
-        return $this->get_field_or_extra_meta('MSG_generation_data');
703
-    }
704
-
705
-
706
-    /**
707
-     * Gets any error message.
708
-     *
709
-     * @return mixed|null
710
-     */
711
-    public function error_message()
712
-    {
713
-        return $this->get_field_or_extra_meta('MSG_error');
714
-    }
715
-
716
-
717
-    /**
718
-     * Sets an error message.
719
-     *
720
-     * @param $message
721
-     * @return bool|int
722
-     */
723
-    public function set_error_message($message)
724
-    {
725
-        return $this->set_field_or_extra_meta('MSG_error', $message);
726
-    }
727
-
728
-
729
-    /**
730
-     * This retrieves the associated template pack with this message.
731
-     *
732
-     * @return EE_Messages_Template_Pack | null
733
-     */
734
-    public function get_template_pack()
735
-    {
736
-        /**
737
-         * This is deprecated functionality that will be removed eventually but included here now for backward compat.
738
-         */
739
-        if (! empty($this->template_pack)) {
740
-            return $this->template_pack;
741
-        }
742
-        /** @type EE_Message_Template_Group $grp */
743
-        $grp = $this->get_first_related('Message_Template_Group');
744
-        // if no group then let's try to get the first related group by internal messenger and message type (will use global grp).
745
-        if (! $grp instanceof EE_Message_Template_Group) {
746
-            $grp = EEM_Message_Template_Group::instance()->get_one(
747
-                array(
748
-                    array(
749
-                        'MTP_messenger'    => $this->messenger(),
750
-                        'MTP_message_type' => $this->message_type(),
751
-                        'MTP_is_global'    => true,
752
-                    ),
753
-                )
754
-            );
755
-        }
756
-
757
-        return $grp instanceof EE_Message_Template_Group ? $grp->get_template_pack() : null;
758
-    }
759
-
760
-
761
-    /**
762
-     * Retrieves the variation used for generating this message.
763
-     *
764
-     * @return string
765
-     */
766
-    public function get_template_pack_variation()
767
-    {
768
-        /**
769
-         * This is deprecated functionality that will be removed eventually but included here now for backward compat.
770
-         */
771
-        if (! empty($this->template_variation)) {
772
-            return $this->template_variation;
773
-        }
774
-
775
-        /** @type EE_Message_Template_Group $grp */
776
-        $grp = $this->get_first_related('Message_Template_Group');
777
-
778
-        // if no group then let's try to get the first related group by internal messenger and message type (will use global grp).
779
-        if (! $grp instanceof EE_Message_Template_Group) {
780
-            $grp = EEM_Message_Template_Group::instance()->get_one(
781
-                array(
782
-                    array(
783
-                        'MTP_messenger'    => $this->messenger(),
784
-                        'MTP_message_type' => $this->message_type(),
785
-                        'MTP_is_global'    => true,
786
-                    ),
787
-                )
788
-            );
789
-        }
790
-
791
-        return $grp instanceof EE_Message_Template_Group ? $grp->get_template_pack_variation() : '';
792
-    }
793
-
794
-    /**
795
-     * Return the link to the admin details for the object.
796
-     *
797
-     * @return string
798
-     */
799
-    public function get_admin_details_link()
800
-    {
801
-        EE_Registry::instance()->load_helper('URL');
802
-        EE_Registry::instance()->load_helper('MSG_Template');
803
-        switch ($this->STS_ID()) {
804
-            case EEM_Message::status_failed:
805
-            case EEM_Message::status_debug_only:
806
-                return EEH_MSG_Template::generate_error_display_trigger($this);
807
-                break;
808
-
809
-            case EEM_Message::status_sent:
810
-                return EEH_MSG_Template::generate_browser_trigger($this);
811
-                break;
812
-
813
-            default:
814
-                return '';
815
-        }
816
-    }
817
-
818
-    /**
819
-     * Returns the link to the editor for the object.  Sometimes this is the same as the details.
820
-     *
821
-     * @return string
822
-     */
823
-    public function get_admin_edit_link()
824
-    {
825
-        return $this->get_admin_details_link();
826
-    }
827
-
828
-    /**
829
-     * Returns the link to a settings page for the object.
830
-     *
831
-     * @return string
832
-     */
833
-    public function get_admin_settings_link()
834
-    {
835
-        EE_Registry::instance()->load_helper('URL');
836
-        return EEH_URL::add_query_args_and_nonce(
837
-            array(
838
-                'page'   => 'espresso_messages',
839
-                'action' => 'settings',
840
-            ),
841
-            admin_url('admin.php')
842
-        );
843
-    }
844
-
845
-    /**
846
-     * Returns the link to the "overview" for the object (typically the "list table" view).
847
-     *
848
-     * @return string
849
-     */
850
-    public function get_admin_overview_link()
851
-    {
852
-        EE_Registry::instance()->load_helper('URL');
853
-        return EEH_URL::add_query_args_and_nonce(
854
-            array(
855
-                'page'   => 'espresso_messages',
856
-                'action' => 'default',
857
-            ),
858
-            admin_url('admin.php')
859
-        );
860
-    }
861
-
862
-
863
-    /**
864
-     * This sets the EEM_Message::status_messenger_executing class on the message and the appropriate error message for
865
-     * it.
866
-     * Note this also SAVES the current message object to the db because it adds an error message to accompany the
867
-     * status.
868
-     *
869
-     */
870
-    public function set_messenger_is_executing()
871
-    {
872
-        $this->set_STS_ID(EEM_Message::status_messenger_executing);
873
-        $this->set_error_message(
874
-            esc_html__(
875
-                'A message with this status indicates that there was a problem that occurred while the message was being
13
+	/**
14
+	 * @deprecated 4.9.0  Added for backward compat with add-on's
15
+	 * @type null
16
+	 */
17
+	public $template_pack;
18
+
19
+	/**
20
+	 * @deprecated 4.9.0 Added for backward compat with add-on's
21
+	 * @type null
22
+	 */
23
+	public $template_variation;
24
+
25
+	/**
26
+	 * @deprecated 4.9.0 Added for backward compat with add-on's
27
+	 * @type string
28
+	 */
29
+	public $content = '';
30
+
31
+
32
+	/**
33
+	 * @type EE_messenger $_messenger
34
+	 */
35
+	protected $_messenger = null;
36
+
37
+	/**
38
+	 * @type EE_message_type $_message_type
39
+	 */
40
+	protected $_message_type = null;
41
+
42
+
43
+	/**
44
+	 * @param array  $props_n_values
45
+	 * @param string $timezone
46
+	 * @param array  $date_formats incoming date formats in an array.  First value is the date_format, second is time
47
+	 *                             format.
48
+	 * @return EE_Message
49
+	 */
50
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
51
+	{
52
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
53
+		// if object doesn't exist, let's generate a unique token on instantiation so that its available even before saving to db.
54
+		if (! $has_object) {
55
+			EE_Registry::instance()->load_helper('URL');
56
+			$props_n_values['MSG_token'] = EEH_URL::generate_unique_token();
57
+		}
58
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
59
+	}
60
+
61
+
62
+	/**
63
+	 * @param array  $props_n_values
64
+	 * @param string $timezone
65
+	 * @return EE_Message
66
+	 */
67
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
68
+	{
69
+		return new self($props_n_values, true, $timezone);
70
+	}
71
+
72
+
73
+	/**
74
+	 * Gets MSG_token
75
+	 *
76
+	 * @return int
77
+	 */
78
+	public function MSG_token()
79
+	{
80
+		return $this->get('MSG_token');
81
+	}
82
+
83
+
84
+	/**
85
+	 * Sets MSG_token
86
+	 *
87
+	 * @param int $MSG_token
88
+	 */
89
+	public function set_MSG_token($MSG_token)
90
+	{
91
+		$this->set('MSG_token', $MSG_token);
92
+	}
93
+
94
+
95
+	/**
96
+	 * Gets GRP_ID
97
+	 *
98
+	 * @return int
99
+	 */
100
+	public function GRP_ID()
101
+	{
102
+		return $this->get('GRP_ID');
103
+	}
104
+
105
+
106
+	/**
107
+	 * Sets GRP_ID
108
+	 *
109
+	 * @param int $GRP_ID
110
+	 */
111
+	public function set_GRP_ID($GRP_ID)
112
+	{
113
+		$this->set('GRP_ID', $GRP_ID);
114
+	}
115
+
116
+
117
+	/**
118
+	 * Gets TXN_ID
119
+	 *
120
+	 * @return int
121
+	 */
122
+	public function TXN_ID()
123
+	{
124
+		return $this->get('TXN_ID');
125
+	}
126
+
127
+
128
+	/**
129
+	 * Sets TXN_ID
130
+	 *
131
+	 * @param int $TXN_ID
132
+	 */
133
+	public function set_TXN_ID($TXN_ID)
134
+	{
135
+		$this->set('TXN_ID', $TXN_ID);
136
+	}
137
+
138
+
139
+	/**
140
+	 * Gets messenger
141
+	 *
142
+	 * @return string
143
+	 */
144
+	public function messenger()
145
+	{
146
+		return $this->get('MSG_messenger');
147
+	}
148
+
149
+
150
+	/**
151
+	 * Sets messenger
152
+	 *
153
+	 * @param string $messenger
154
+	 */
155
+	public function set_messenger($messenger)
156
+	{
157
+		$this->set('MSG_messenger', $messenger);
158
+	}
159
+
160
+
161
+	/**
162
+	 * Returns corresponding messenger object for the set messenger on this message
163
+	 *
164
+	 * @return EE_messenger | null
165
+	 */
166
+	public function messenger_object()
167
+	{
168
+		return $this->_messenger;
169
+	}
170
+
171
+
172
+	/**
173
+	 * Sets messenger
174
+	 *
175
+	 * @param EE_messenger $messenger
176
+	 */
177
+	public function set_messenger_object(EE_messenger $messenger)
178
+	{
179
+		$this->_messenger = $messenger;
180
+	}
181
+
182
+
183
+	/**
184
+	 * validates messenger
185
+	 *
186
+	 * @param bool $throw_exceptions
187
+	 * @return bool
188
+	 * @throws \EE_Error
189
+	 */
190
+	public function valid_messenger($throw_exceptions = false)
191
+	{
192
+		if ($this->_messenger instanceof EE_messenger) {
193
+			return true;
194
+		}
195
+		if ($throw_exceptions) {
196
+			throw new EE_Error(
197
+				sprintf(
198
+					__(
199
+						'The "%1$s" messenger set for this message is missing or invalid. Please double-check the spelling and verify that the correct files exist.',
200
+						'event_espresso'
201
+					),
202
+					$this->messenger()
203
+				)
204
+			);
205
+		}
206
+		return false;
207
+	}
208
+
209
+
210
+	/**
211
+	 * This returns the set localized label for the messenger on this message.
212
+	 * Note, if unable to retrieve the EE_messenger object then will just return the messenger slug saved
213
+	 * with this message.
214
+	 *
215
+	 * @param   bool $plural whether to return the plural label or not.
216
+	 * @return string
217
+	 */
218
+	public function messenger_label($plural = false)
219
+	{
220
+		$label_type = $plural ? 'plural' : 'singular';
221
+		$messenger = $this->messenger_object();
222
+		return $messenger instanceof EE_messenger ? $messenger->label[ $label_type ] : $this->messenger();
223
+	}
224
+
225
+
226
+	/**
227
+	 * Gets message_type
228
+	 *
229
+	 * @return string
230
+	 */
231
+	public function message_type()
232
+	{
233
+		return $this->get('MSG_message_type');
234
+	}
235
+
236
+
237
+	/**
238
+	 * Sets message_type
239
+	 *
240
+	 * @param string $message_type
241
+	 */
242
+	public function set_message_type($message_type)
243
+	{
244
+		$this->set('MSG_message_type', $message_type);
245
+	}
246
+
247
+
248
+	/**
249
+	 * Returns the message type object for the set message type on this message
250
+	 *
251
+	 * @return EE_message_type | null
252
+	 */
253
+	public function message_type_object()
254
+	{
255
+		return $this->_message_type;
256
+	}
257
+
258
+
259
+	/**
260
+	 * Sets message_type
261
+	 *
262
+	 * @param EE_message_type $message_type
263
+	 * @param bool            $set_priority   This indicates whether to set the priority to whatever the priority is on
264
+	 *                                        the message type or not.
265
+	 */
266
+	public function set_message_type_object(EE_message_type $message_type, $set_priority = false)
267
+	{
268
+		$this->_message_type = $message_type;
269
+		if ($set_priority) {
270
+			$this->set_priority($this->_message_type->get_priority());
271
+		}
272
+	}
273
+
274
+
275
+	/**
276
+	 * validates message_type
277
+	 *
278
+	 * @param bool $throw_exceptions
279
+	 * @return bool
280
+	 * @throws \EE_Error
281
+	 */
282
+	public function valid_message_type($throw_exceptions = false)
283
+	{
284
+		if ($this->_message_type instanceof EE_message_type) {
285
+			return true;
286
+		}
287
+		if ($throw_exceptions) {
288
+			throw new EE_Error(
289
+				sprintf(
290
+					__(
291
+						'The %1$s message type set for this message is missing or invalid. Please double-check the spelling and verify that the correct files exist.',
292
+						'event_espresso'
293
+					),
294
+					$this->message_type()
295
+				)
296
+			);
297
+		}
298
+		return false;
299
+	}
300
+
301
+
302
+	/**
303
+	 * validates messenger and message_type (that they are valid EE_messenger and EE_message_type objects).
304
+	 *
305
+	 * @param bool $throw_exceptions
306
+	 * @return bool
307
+	 * @throws \EE_Error
308
+	 */
309
+	public function is_valid($throw_exceptions = false)
310
+	{
311
+		if ($this->valid_messenger($throw_exceptions) && $this->valid_message_type($throw_exceptions)) {
312
+			return true;
313
+		}
314
+		return false;
315
+	}
316
+
317
+
318
+	/**
319
+	 * This validates whether the internal messenger and message type objects are valid for sending.
320
+	 * Three checks are done:
321
+	 * 1. There is a valid messenger object.
322
+	 * 2. There is a valid message type object.
323
+	 * 3. The message type object is active for the messenger.
324
+	 *
325
+	 * @throws EE_Error  But only if $throw_exceptions is set to true.
326
+	 * @param bool $throw_exceptions
327
+	 * @return bool
328
+	 */
329
+	public function is_valid_for_sending_or_generation($throw_exceptions = false)
330
+	{
331
+		$valid = false;
332
+		if ($this->is_valid($throw_exceptions)) {
333
+			/** @var EE_Message_Resource_Manager $message_resource_manager */
334
+			$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
335
+			$valid = $message_resource_manager->is_message_type_active_for_messenger(
336
+				$this->messenger(),
337
+				$this->message_type()
338
+			);
339
+			if (! $valid && $throw_exceptions) {
340
+				throw new EE_Error(
341
+					sprintf(
342
+						__(
343
+							'The %1$s message type is not a valid message type for the %2$s messenger so it will not be sent.',
344
+							'event_espresso'
345
+						),
346
+						$this->message_type(),
347
+						$this->messenger()
348
+					)
349
+				);
350
+			}
351
+		}
352
+		return $valid;
353
+	}
354
+
355
+
356
+	/**
357
+	 * This returns the set localized label for the message type on this message.
358
+	 * Note, if unable to retrieve the EE_message_type object then will just return the message type slug saved
359
+	 * with this message.
360
+	 *
361
+	 * @param   bool $plural whether to return the plural label or not.
362
+	 * @return string
363
+	 */
364
+	public function message_type_label($plural = false)
365
+	{
366
+		$label_type = $plural ? 'plural' : 'singular';
367
+		$message_type = $this->message_type_object();
368
+		return $message_type instanceof EE_message_type
369
+			? $message_type->label[ $label_type ]
370
+			: str_replace(
371
+				'_',
372
+				' ',
373
+				$this->message_type()
374
+			);
375
+	}
376
+
377
+
378
+	/**
379
+	 * Gets context
380
+	 *
381
+	 * @return string
382
+	 */
383
+	public function context()
384
+	{
385
+		return $this->get('MSG_context');
386
+	}
387
+
388
+
389
+	/**
390
+	 * This returns the corresponding localized label for the given context slug, if possible from installed message
391
+	 * types. Otherwise, this will just return the set context slug on this object.
392
+	 *
393
+	 * @return string
394
+	 */
395
+	public function context_label()
396
+	{
397
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
398
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
399
+		$contexts = $message_resource_manager->get_all_contexts();
400
+		return isset($contexts[ $this->context() ]) ? $contexts[ $this->context() ] : $this->context();
401
+	}
402
+
403
+
404
+	/**
405
+	 * Sets context
406
+	 *
407
+	 * @param string $context
408
+	 */
409
+	public function set_context($context)
410
+	{
411
+		$this->set('MSG_context', $context);
412
+	}
413
+
414
+
415
+	/**
416
+	 * Gets recipient_ID
417
+	 *
418
+	 * @return int
419
+	 */
420
+	public function recipient_ID()
421
+	{
422
+		return $this->get('MSG_recipient_ID');
423
+	}
424
+
425
+
426
+	/**
427
+	 * Sets recipient_ID
428
+	 *
429
+	 * @param string $recipient_ID
430
+	 */
431
+	public function set_recipient_ID($recipient_ID)
432
+	{
433
+		$this->set('MSG_recipient_ID', $recipient_ID);
434
+	}
435
+
436
+
437
+	/**
438
+	 * Gets recipient_type
439
+	 *
440
+	 * @return string
441
+	 */
442
+	public function recipient_type()
443
+	{
444
+		return $this->get('MSG_recipient_type');
445
+	}
446
+
447
+
448
+	/**
449
+	 * Return the related object matching the recipient type and ID.
450
+	 *
451
+	 * @return EE_Base_Class | null
452
+	 */
453
+	public function recipient_object()
454
+	{
455
+		if (! $this->recipient_type() || ! $this->recipient_ID()) {
456
+			return null;
457
+		}
458
+
459
+		return $this->get_first_related($this->recipient_type());
460
+	}
461
+
462
+
463
+	/**
464
+	 * Sets recipient_type
465
+	 *
466
+	 * @param string $recipient_type
467
+	 */
468
+	public function set_recipient_type($recipient_type)
469
+	{
470
+		$this->set('MSG_recipient_type', $recipient_type);
471
+	}
472
+
473
+
474
+	/**
475
+	 * Gets content
476
+	 *
477
+	 * @return string
478
+	 */
479
+	public function content()
480
+	{
481
+		return $this->get('MSG_content');
482
+	}
483
+
484
+
485
+	/**
486
+	 * Sets content
487
+	 *
488
+	 * @param string $content
489
+	 */
490
+	public function set_content($content)
491
+	{
492
+		$this->set('MSG_content', $content);
493
+	}
494
+
495
+
496
+	/**
497
+	 * Gets subject
498
+	 *
499
+	 * @return string
500
+	 */
501
+	public function subject()
502
+	{
503
+		return $this->get('MSG_subject');
504
+	}
505
+
506
+
507
+	/**
508
+	 * Sets subject
509
+	 *
510
+	 * @param string $subject
511
+	 */
512
+	public function set_subject($subject)
513
+	{
514
+		$this->set('MSG_subject', $subject);
515
+	}
516
+
517
+
518
+	/**
519
+	 * Gets to
520
+	 *
521
+	 * @return string
522
+	 */
523
+	public function to()
524
+	{
525
+		$to = $this->get('MSG_to');
526
+		return empty($to) ? __('No recipient', 'event_espresso') : $to;
527
+	}
528
+
529
+
530
+	/**
531
+	 * Sets to
532
+	 *
533
+	 * @param string $to
534
+	 */
535
+	public function set_to($to)
536
+	{
537
+		$this->set('MSG_to', $to);
538
+	}
539
+
540
+
541
+	/**
542
+	 * Gets from
543
+	 *
544
+	 * @return string
545
+	 */
546
+	public function from()
547
+	{
548
+		return $this->get('MSG_from');
549
+	}
550
+
551
+
552
+	/**
553
+	 * Sets from
554
+	 *
555
+	 * @param string $from
556
+	 */
557
+	public function set_from($from)
558
+	{
559
+		$this->set('MSG_from', $from);
560
+	}
561
+
562
+
563
+	/**
564
+	 * Gets priority
565
+	 *
566
+	 * @return int
567
+	 */
568
+	public function priority()
569
+	{
570
+		return $this->get('MSG_priority');
571
+	}
572
+
573
+
574
+	/**
575
+	 * Sets priority
576
+	 * Note.  Send Now Messengers always override any priority that may be set on a Message.  So
577
+	 * this method calls the send_now method to verify that.
578
+	 *
579
+	 * @param int $priority
580
+	 */
581
+	public function set_priority($priority)
582
+	{
583
+		$priority = $this->send_now() ? EEM_Message::priority_high : $priority;
584
+		parent::set('MSG_priority', $priority);
585
+	}
586
+
587
+
588
+	/**
589
+	 * Overrides parent::set method so we can capture any sets for priority.
590
+	 *
591
+	 * @see parent::set() for phpdocs
592
+	 * @param string $field_name
593
+	 * @param mixed  $field_value
594
+	 * @param bool   $use_default
595
+	 * @throws EE_Error
596
+	 */
597
+	public function set($field_name, $field_value, $use_default = false)
598
+	{
599
+		if ($field_name === 'MSG_priority') {
600
+			$this->set_priority($field_value);
601
+		}
602
+		parent::set($field_name, $field_value, $use_default);
603
+	}
604
+
605
+
606
+	/**
607
+	 * @return bool
608
+	 * @throws \EE_Error
609
+	 */
610
+	public function send_now()
611
+	{
612
+		$send_now = $this->valid_messenger() && $this->messenger_object()->send_now() ? EEM_Message::priority_high
613
+			: $this->priority();
614
+		return $send_now === EEM_Message::priority_high ? true : false;
615
+	}
616
+
617
+
618
+	/**
619
+	 * Gets STS_ID
620
+	 *
621
+	 * @return string
622
+	 */
623
+	public function STS_ID()
624
+	{
625
+		return $this->get('STS_ID');
626
+	}
627
+
628
+
629
+	/**
630
+	 * Sets STS_ID
631
+	 *
632
+	 * @param string $STS_ID
633
+	 */
634
+	public function set_STS_ID($STS_ID)
635
+	{
636
+		$this->set('STS_ID', $STS_ID);
637
+	}
638
+
639
+
640
+	/**
641
+	 * Gets created
642
+	 *
643
+	 * @return string
644
+	 */
645
+	public function created()
646
+	{
647
+		return $this->get('MSG_created');
648
+	}
649
+
650
+
651
+	/**
652
+	 * Sets created
653
+	 *
654
+	 * @param string $created
655
+	 */
656
+	public function set_created($created)
657
+	{
658
+		$this->set('MSG_created', $created);
659
+	}
660
+
661
+
662
+	/**
663
+	 * Gets modified
664
+	 *
665
+	 * @return string
666
+	 */
667
+	public function modified()
668
+	{
669
+		return $this->get('MSG_modified');
670
+	}
671
+
672
+
673
+	/**
674
+	 * Sets modified
675
+	 *
676
+	 * @param string $modified
677
+	 */
678
+	public function set_modified($modified)
679
+	{
680
+		$this->set('MSG_modified', $modified);
681
+	}
682
+
683
+
684
+	/**
685
+	 * Sets generation data for this message.
686
+	 *
687
+	 * @param mixed $data
688
+	 */
689
+	public function set_generation_data($data)
690
+	{
691
+		$this->set_field_or_extra_meta('MSG_generation_data', $data);
692
+	}
693
+
694
+
695
+	/**
696
+	 * Returns any set generation data for this message.
697
+	 *
698
+	 * @return mixed|null
699
+	 */
700
+	public function get_generation_data()
701
+	{
702
+		return $this->get_field_or_extra_meta('MSG_generation_data');
703
+	}
704
+
705
+
706
+	/**
707
+	 * Gets any error message.
708
+	 *
709
+	 * @return mixed|null
710
+	 */
711
+	public function error_message()
712
+	{
713
+		return $this->get_field_or_extra_meta('MSG_error');
714
+	}
715
+
716
+
717
+	/**
718
+	 * Sets an error message.
719
+	 *
720
+	 * @param $message
721
+	 * @return bool|int
722
+	 */
723
+	public function set_error_message($message)
724
+	{
725
+		return $this->set_field_or_extra_meta('MSG_error', $message);
726
+	}
727
+
728
+
729
+	/**
730
+	 * This retrieves the associated template pack with this message.
731
+	 *
732
+	 * @return EE_Messages_Template_Pack | null
733
+	 */
734
+	public function get_template_pack()
735
+	{
736
+		/**
737
+		 * This is deprecated functionality that will be removed eventually but included here now for backward compat.
738
+		 */
739
+		if (! empty($this->template_pack)) {
740
+			return $this->template_pack;
741
+		}
742
+		/** @type EE_Message_Template_Group $grp */
743
+		$grp = $this->get_first_related('Message_Template_Group');
744
+		// if no group then let's try to get the first related group by internal messenger and message type (will use global grp).
745
+		if (! $grp instanceof EE_Message_Template_Group) {
746
+			$grp = EEM_Message_Template_Group::instance()->get_one(
747
+				array(
748
+					array(
749
+						'MTP_messenger'    => $this->messenger(),
750
+						'MTP_message_type' => $this->message_type(),
751
+						'MTP_is_global'    => true,
752
+					),
753
+				)
754
+			);
755
+		}
756
+
757
+		return $grp instanceof EE_Message_Template_Group ? $grp->get_template_pack() : null;
758
+	}
759
+
760
+
761
+	/**
762
+	 * Retrieves the variation used for generating this message.
763
+	 *
764
+	 * @return string
765
+	 */
766
+	public function get_template_pack_variation()
767
+	{
768
+		/**
769
+		 * This is deprecated functionality that will be removed eventually but included here now for backward compat.
770
+		 */
771
+		if (! empty($this->template_variation)) {
772
+			return $this->template_variation;
773
+		}
774
+
775
+		/** @type EE_Message_Template_Group $grp */
776
+		$grp = $this->get_first_related('Message_Template_Group');
777
+
778
+		// if no group then let's try to get the first related group by internal messenger and message type (will use global grp).
779
+		if (! $grp instanceof EE_Message_Template_Group) {
780
+			$grp = EEM_Message_Template_Group::instance()->get_one(
781
+				array(
782
+					array(
783
+						'MTP_messenger'    => $this->messenger(),
784
+						'MTP_message_type' => $this->message_type(),
785
+						'MTP_is_global'    => true,
786
+					),
787
+				)
788
+			);
789
+		}
790
+
791
+		return $grp instanceof EE_Message_Template_Group ? $grp->get_template_pack_variation() : '';
792
+	}
793
+
794
+	/**
795
+	 * Return the link to the admin details for the object.
796
+	 *
797
+	 * @return string
798
+	 */
799
+	public function get_admin_details_link()
800
+	{
801
+		EE_Registry::instance()->load_helper('URL');
802
+		EE_Registry::instance()->load_helper('MSG_Template');
803
+		switch ($this->STS_ID()) {
804
+			case EEM_Message::status_failed:
805
+			case EEM_Message::status_debug_only:
806
+				return EEH_MSG_Template::generate_error_display_trigger($this);
807
+				break;
808
+
809
+			case EEM_Message::status_sent:
810
+				return EEH_MSG_Template::generate_browser_trigger($this);
811
+				break;
812
+
813
+			default:
814
+				return '';
815
+		}
816
+	}
817
+
818
+	/**
819
+	 * Returns the link to the editor for the object.  Sometimes this is the same as the details.
820
+	 *
821
+	 * @return string
822
+	 */
823
+	public function get_admin_edit_link()
824
+	{
825
+		return $this->get_admin_details_link();
826
+	}
827
+
828
+	/**
829
+	 * Returns the link to a settings page for the object.
830
+	 *
831
+	 * @return string
832
+	 */
833
+	public function get_admin_settings_link()
834
+	{
835
+		EE_Registry::instance()->load_helper('URL');
836
+		return EEH_URL::add_query_args_and_nonce(
837
+			array(
838
+				'page'   => 'espresso_messages',
839
+				'action' => 'settings',
840
+			),
841
+			admin_url('admin.php')
842
+		);
843
+	}
844
+
845
+	/**
846
+	 * Returns the link to the "overview" for the object (typically the "list table" view).
847
+	 *
848
+	 * @return string
849
+	 */
850
+	public function get_admin_overview_link()
851
+	{
852
+		EE_Registry::instance()->load_helper('URL');
853
+		return EEH_URL::add_query_args_and_nonce(
854
+			array(
855
+				'page'   => 'espresso_messages',
856
+				'action' => 'default',
857
+			),
858
+			admin_url('admin.php')
859
+		);
860
+	}
861
+
862
+
863
+	/**
864
+	 * This sets the EEM_Message::status_messenger_executing class on the message and the appropriate error message for
865
+	 * it.
866
+	 * Note this also SAVES the current message object to the db because it adds an error message to accompany the
867
+	 * status.
868
+	 *
869
+	 */
870
+	public function set_messenger_is_executing()
871
+	{
872
+		$this->set_STS_ID(EEM_Message::status_messenger_executing);
873
+		$this->set_error_message(
874
+			esc_html__(
875
+				'A message with this status indicates that there was a problem that occurred while the message was being
876 876
                 processed by the messenger.  It is still possible that the message was sent successfully, but at some
877 877
                 point during the processing there was a failure.  This usually is indicative of a timeout issue with PHP 
878 878
                 or memory limits being reached.  If you see this repeatedly you may want to consider upgrading the memory 
879 879
                 available to PHP on your server.',
880
-                'event_espresso'
881
-            )
882
-        );
883
-    }
880
+				'event_espresso'
881
+			)
882
+		);
883
+	}
884 884
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -51,7 +51,7 @@  discard block
 block discarded – undo
51 51
     {
52 52
         $has_object = parent::_check_for_object($props_n_values, __CLASS__);
53 53
         // if object doesn't exist, let's generate a unique token on instantiation so that its available even before saving to db.
54
-        if (! $has_object) {
54
+        if ( ! $has_object) {
55 55
             EE_Registry::instance()->load_helper('URL');
56 56
             $props_n_values['MSG_token'] = EEH_URL::generate_unique_token();
57 57
         }
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
     {
220 220
         $label_type = $plural ? 'plural' : 'singular';
221 221
         $messenger = $this->messenger_object();
222
-        return $messenger instanceof EE_messenger ? $messenger->label[ $label_type ] : $this->messenger();
222
+        return $messenger instanceof EE_messenger ? $messenger->label[$label_type] : $this->messenger();
223 223
     }
224 224
 
225 225
 
@@ -336,7 +336,7 @@  discard block
 block discarded – undo
336 336
                 $this->messenger(),
337 337
                 $this->message_type()
338 338
             );
339
-            if (! $valid && $throw_exceptions) {
339
+            if ( ! $valid && $throw_exceptions) {
340 340
                 throw new EE_Error(
341 341
                     sprintf(
342 342
                         __(
@@ -366,7 +366,7 @@  discard block
 block discarded – undo
366 366
         $label_type = $plural ? 'plural' : 'singular';
367 367
         $message_type = $this->message_type_object();
368 368
         return $message_type instanceof EE_message_type
369
-            ? $message_type->label[ $label_type ]
369
+            ? $message_type->label[$label_type]
370 370
             : str_replace(
371 371
                 '_',
372 372
                 ' ',
@@ -397,7 +397,7 @@  discard block
 block discarded – undo
397 397
         /** @type EE_Message_Resource_Manager $message_resource_manager */
398 398
         $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
399 399
         $contexts = $message_resource_manager->get_all_contexts();
400
-        return isset($contexts[ $this->context() ]) ? $contexts[ $this->context() ] : $this->context();
400
+        return isset($contexts[$this->context()]) ? $contexts[$this->context()] : $this->context();
401 401
     }
402 402
 
403 403
 
@@ -452,7 +452,7 @@  discard block
 block discarded – undo
452 452
      */
453 453
     public function recipient_object()
454 454
     {
455
-        if (! $this->recipient_type() || ! $this->recipient_ID()) {
455
+        if ( ! $this->recipient_type() || ! $this->recipient_ID()) {
456 456
             return null;
457 457
         }
458 458
 
@@ -736,13 +736,13 @@  discard block
 block discarded – undo
736 736
         /**
737 737
          * This is deprecated functionality that will be removed eventually but included here now for backward compat.
738 738
          */
739
-        if (! empty($this->template_pack)) {
739
+        if ( ! empty($this->template_pack)) {
740 740
             return $this->template_pack;
741 741
         }
742 742
         /** @type EE_Message_Template_Group $grp */
743 743
         $grp = $this->get_first_related('Message_Template_Group');
744 744
         // if no group then let's try to get the first related group by internal messenger and message type (will use global grp).
745
-        if (! $grp instanceof EE_Message_Template_Group) {
745
+        if ( ! $grp instanceof EE_Message_Template_Group) {
746 746
             $grp = EEM_Message_Template_Group::instance()->get_one(
747 747
                 array(
748 748
                     array(
@@ -768,7 +768,7 @@  discard block
 block discarded – undo
768 768
         /**
769 769
          * This is deprecated functionality that will be removed eventually but included here now for backward compat.
770 770
          */
771
-        if (! empty($this->template_variation)) {
771
+        if ( ! empty($this->template_variation)) {
772 772
             return $this->template_variation;
773 773
         }
774 774
 
@@ -776,7 +776,7 @@  discard block
 block discarded – undo
776 776
         $grp = $this->get_first_related('Message_Template_Group');
777 777
 
778 778
         // if no group then let's try to get the first related group by internal messenger and message type (will use global grp).
779
-        if (! $grp instanceof EE_Message_Template_Group) {
779
+        if ( ! $grp instanceof EE_Message_Template_Group) {
780 780
             $grp = EEM_Message_Template_Group::instance()->get_one(
781 781
                 array(
782 782
                     array(
Please login to merge, or discard this patch.