Completed
Branch master (d4ace2)
by
unknown
04:43
created
core/db_models/EEM_Change_Log.model.php 1 patch
Indentation   +220 added lines, -220 removed lines patch added patch discarded remove patch
@@ -9,89 +9,89 @@  discard block
 block discarded – undo
9 9
  */
10 10
 class EEM_Change_Log extends EEM_Base
11 11
 {
12
-    /**
13
-     * the related object was created log type
14
-     */
15
-    const type_create = 'create';
12
+	/**
13
+	 * the related object was created log type
14
+	 */
15
+	const type_create = 'create';
16 16
 
17
-    /**
18
-     * the related object was updated (changed, or soft-deleted)
19
-     */
20
-    const type_update = 'update';
17
+	/**
18
+	 * the related object was updated (changed, or soft-deleted)
19
+	 */
20
+	const type_update = 'update';
21 21
 
22
-    /**
23
-     * the related object was trashed/restored/deleted
24
-     */
25
-    const type_delete = 'delete';
22
+	/**
23
+	 * the related object was trashed/restored/deleted
24
+	 */
25
+	const type_delete = 'delete';
26 26
 
27
-    /**
28
-     * the related item had something worth noting happen on it, but
29
-     * only for the purposes of debugging problems
30
-     */
31
-    const type_debug = 'debug';
27
+	/**
28
+	 * the related item had something worth noting happen on it, but
29
+	 * only for the purposes of debugging problems
30
+	 */
31
+	const type_debug = 'debug';
32 32
 
33
-    /**
34
-     * the related item had an error occur on it
35
-     */
36
-    const type_error = 'error';
33
+	/**
34
+	 * the related item had an error occur on it
35
+	 */
36
+	const type_error = 'error';
37 37
 
38
-    /**
39
-     * the related item is regarding some gateway interaction, like an IPN
40
-     * or request to process a payment
41
-     */
42
-    const type_gateway = 'gateway';
38
+	/**
39
+	 * the related item is regarding some gateway interaction, like an IPN
40
+	 * or request to process a payment
41
+	 */
42
+	const type_gateway = 'gateway';
43 43
 
44 44
 
45
-    protected static ?EEM_Change_Log $_instance = null;
45
+	protected static ?EEM_Change_Log $_instance = null;
46 46
 
47 47
 
48
-    /**
49
-     * @param string|null $timezone
50
-     * @throws EE_Error
51
-     */
52
-    protected function __construct(?string $timezone = '')
53
-    {
54
-        $this->singular_item       = esc_html__('Log', 'event_espresso');
55
-        $this->plural_item         = esc_html__('Logs', 'event_espresso');
56
-        $this->_tables             = [
57
-            'Log' => new EE_Primary_Table('esp_log', 'LOG_ID'),
58
-        ];
59
-        $models_this_can_attach_to = array_keys(EE_Registry::instance()->non_abstract_db_models);
60
-        $this->_fields             = [
61
-            'Log' => [
62
-                'LOG_ID'      => new EE_Primary_Key_Int_Field('LOG_ID', esc_html__('Log ID', 'event_espresso')),
63
-                'LOG_time'    => new EE_Datetime_Field(
64
-                    'LOG_time',
65
-                    esc_html__("Log Time", 'event_espresso'),
66
-                    false,
67
-                    EE_Datetime_Field::now
68
-                ),
69
-                'OBJ_ID'      => new EE_Foreign_Key_String_Field(
70
-                    'OBJ_ID',
71
-                    esc_html__("Object ID (int or string)", 'event_espresso'),
72
-                    true,
73
-                    null,
74
-                    $models_this_can_attach_to
75
-                ),
76
-                'OBJ_type'    => new EE_Any_Foreign_Model_Name_Field(
77
-                    'OBJ_type',
78
-                    esc_html__("Object Type", 'event_espresso'),
79
-                    true,
80
-                    null,
81
-                    $models_this_can_attach_to
82
-                ),
83
-                'LOG_type'    => new EE_Plain_Text_Field(
84
-                    'LOG_type',
85
-                    esc_html__("Type of log entry", "event_espresso"),
86
-                    false,
87
-                    self::type_debug
88
-                ),
89
-                'LOG_message' => new EE_Maybe_Serialized_Text_Field(
90
-                    'LOG_message',
91
-                    esc_html__("Log Message (body)", 'event_espresso'),
92
-                    true
93
-                ),
94
-                /*
48
+	/**
49
+	 * @param string|null $timezone
50
+	 * @throws EE_Error
51
+	 */
52
+	protected function __construct(?string $timezone = '')
53
+	{
54
+		$this->singular_item       = esc_html__('Log', 'event_espresso');
55
+		$this->plural_item         = esc_html__('Logs', 'event_espresso');
56
+		$this->_tables             = [
57
+			'Log' => new EE_Primary_Table('esp_log', 'LOG_ID'),
58
+		];
59
+		$models_this_can_attach_to = array_keys(EE_Registry::instance()->non_abstract_db_models);
60
+		$this->_fields             = [
61
+			'Log' => [
62
+				'LOG_ID'      => new EE_Primary_Key_Int_Field('LOG_ID', esc_html__('Log ID', 'event_espresso')),
63
+				'LOG_time'    => new EE_Datetime_Field(
64
+					'LOG_time',
65
+					esc_html__("Log Time", 'event_espresso'),
66
+					false,
67
+					EE_Datetime_Field::now
68
+				),
69
+				'OBJ_ID'      => new EE_Foreign_Key_String_Field(
70
+					'OBJ_ID',
71
+					esc_html__("Object ID (int or string)", 'event_espresso'),
72
+					true,
73
+					null,
74
+					$models_this_can_attach_to
75
+				),
76
+				'OBJ_type'    => new EE_Any_Foreign_Model_Name_Field(
77
+					'OBJ_type',
78
+					esc_html__("Object Type", 'event_espresso'),
79
+					true,
80
+					null,
81
+					$models_this_can_attach_to
82
+				),
83
+				'LOG_type'    => new EE_Plain_Text_Field(
84
+					'LOG_type',
85
+					esc_html__("Type of log entry", "event_espresso"),
86
+					false,
87
+					self::type_debug
88
+				),
89
+				'LOG_message' => new EE_Maybe_Serialized_Text_Field(
90
+					'LOG_message',
91
+					esc_html__("Log Message (body)", 'event_espresso'),
92
+					true
93
+				),
94
+				/*
95 95
                  * Note: when querying for a change log's user, the OBJ_ID and OBJ_type fields are used,
96 96
                  * not the LOG_wp_user field. E.g.,
97 97
                  * `EEM_Change_Log::instance()->get_all(array(array('WP_User.ID'=>1)))` will actually return
@@ -100,162 +100,162 @@  discard block
 block discarded – undo
100 100
                  *  If you want the latter, you can't use the model's magic joining. E.g, you would need to do
101 101
                  * `EEM_Change_Log::instance()->get_all(array(array('LOG_wp_user' => 1)))`.
102 102
                  */
103
-                'LOG_wp_user' => new EE_WP_User_Field(
104
-                    'LOG_wp_user',
105
-                    esc_html__("User who was logged in while this occurred", 'event_espresso'),
106
-                    true
107
-                ),
108
-            ],
109
-        ];
110
-        $this->_model_relations    = [];
111
-        foreach ($models_this_can_attach_to as $model) {
112
-            if ($model != 'Change_Log') {
113
-                $this->_model_relations[ $model ] = new EE_Belongs_To_Any_Relation();
114
-            }
115
-        }
116
-        // use completely custom caps for this
117
-        unset($this->_cap_restriction_generators);
118
-        // caps-wise this is all-or-nothing: if you have the default role you can access anything, otherwise nothing
119
-        foreach ($this->_cap_contexts_to_cap_action_map as $cap_context => $action) {
120
-            $this->_cap_restrictions[ $cap_context ][ EE_Restriction_Generator_Base::get_default_restrictions_cap() ]
121
-                = new EE_Return_None_Where_Conditions();
122
-        }
123
-        parent::__construct($timezone);
124
-    }
103
+				'LOG_wp_user' => new EE_WP_User_Field(
104
+					'LOG_wp_user',
105
+					esc_html__("User who was logged in while this occurred", 'event_espresso'),
106
+					true
107
+				),
108
+			],
109
+		];
110
+		$this->_model_relations    = [];
111
+		foreach ($models_this_can_attach_to as $model) {
112
+			if ($model != 'Change_Log') {
113
+				$this->_model_relations[ $model ] = new EE_Belongs_To_Any_Relation();
114
+			}
115
+		}
116
+		// use completely custom caps for this
117
+		unset($this->_cap_restriction_generators);
118
+		// caps-wise this is all-or-nothing: if you have the default role you can access anything, otherwise nothing
119
+		foreach ($this->_cap_contexts_to_cap_action_map as $cap_context => $action) {
120
+			$this->_cap_restrictions[ $cap_context ][ EE_Restriction_Generator_Base::get_default_restrictions_cap() ]
121
+				= new EE_Return_None_Where_Conditions();
122
+		}
123
+		parent::__construct($timezone);
124
+	}
125 125
 
126 126
 
127
-    /**
128
-     * @param string             $log_type !see the acceptable values of LOG_type in EEM__Change_Log::__construct
129
-     * @param array|string       $message  array|string of the message you want to record
130
-     * @param EE_Base_Class|null $related_model_obj
131
-     * @return EE_Change_Log
132
-     * @throws EE_Error
133
-     * @throws ReflectionException
134
-     */
135
-    public function log(string $log_type, $message, ?EE_Base_Class $related_model_obj): EE_Change_Log
136
-    {
137
-        $obj_id   = null;
138
-        $obj_type = null;
139
-        if ($related_model_obj instanceof EE_Base_Class) {
140
-            $obj_id   = $related_model_obj->ID();
141
-            $obj_type = $related_model_obj->get_model()->get_this_model_name();
142
-        }
143
-        $log = EE_Change_Log::new_instance(
144
-            [
145
-                'LOG_type'    => $log_type,
146
-                'LOG_message' => $message,
147
-                'OBJ_ID'      => $obj_id,
148
-                'OBJ_type'    => $obj_type,
149
-            ]
150
-        );
151
-        $log->save();
152
-        return $log;
153
-    }
127
+	/**
128
+	 * @param string             $log_type !see the acceptable values of LOG_type in EEM__Change_Log::__construct
129
+	 * @param array|string       $message  array|string of the message you want to record
130
+	 * @param EE_Base_Class|null $related_model_obj
131
+	 * @return EE_Change_Log
132
+	 * @throws EE_Error
133
+	 * @throws ReflectionException
134
+	 */
135
+	public function log(string $log_type, $message, ?EE_Base_Class $related_model_obj): EE_Change_Log
136
+	{
137
+		$obj_id   = null;
138
+		$obj_type = null;
139
+		if ($related_model_obj instanceof EE_Base_Class) {
140
+			$obj_id   = $related_model_obj->ID();
141
+			$obj_type = $related_model_obj->get_model()->get_this_model_name();
142
+		}
143
+		$log = EE_Change_Log::new_instance(
144
+			[
145
+				'LOG_type'    => $log_type,
146
+				'LOG_message' => $message,
147
+				'OBJ_ID'      => $obj_id,
148
+				'OBJ_type'    => $obj_type,
149
+			]
150
+		);
151
+		$log->save();
152
+		return $log;
153
+	}
154 154
 
155 155
 
156
-    /**
157
-     * Adds a gateway log for the specified object, given its ID and type
158
-     *
159
-     * @param array|string $message
160
-     * @param int|string   $related_obj_id
161
-     * @param string       $related_obj_type
162
-     * @return EE_Change_Log
163
-     * @throws ReflectionException
164
-     * @throws EE_Error
165
-     */
166
-    public function gateway_log($message, $related_obj_id, string $related_obj_type): EE_Change_Log
167
-    {
168
-        if (! EE_Registry::instance()->is_model_name($related_obj_type)) {
169
-            throw new EE_Error(
170
-                sprintf(
171
-                    esc_html__(
172
-                        "'%s' is not a model name. A model name must be provided when making a gateway log. Eg, 'Payment', 'Payment_Method', etc",
173
-                        "event_espresso"
174
-                    ),
175
-                    $related_obj_type
176
-                )
177
-            );
178
-        }
179
-        $log = EE_Change_Log::new_instance(
180
-            [
181
-                'LOG_type'    => EEM_Change_Log::type_gateway,
182
-                'LOG_message' => $message,
183
-                'OBJ_ID'      => $related_obj_id,
184
-                'OBJ_type'    => $related_obj_type,
185
-            ]
186
-        );
187
-        $log->save();
188
-        return $log;
189
-    }
156
+	/**
157
+	 * Adds a gateway log for the specified object, given its ID and type
158
+	 *
159
+	 * @param array|string $message
160
+	 * @param int|string   $related_obj_id
161
+	 * @param string       $related_obj_type
162
+	 * @return EE_Change_Log
163
+	 * @throws ReflectionException
164
+	 * @throws EE_Error
165
+	 */
166
+	public function gateway_log($message, $related_obj_id, string $related_obj_type): EE_Change_Log
167
+	{
168
+		if (! EE_Registry::instance()->is_model_name($related_obj_type)) {
169
+			throw new EE_Error(
170
+				sprintf(
171
+					esc_html__(
172
+						"'%s' is not a model name. A model name must be provided when making a gateway log. Eg, 'Payment', 'Payment_Method', etc",
173
+						"event_espresso"
174
+					),
175
+					$related_obj_type
176
+				)
177
+			);
178
+		}
179
+		$log = EE_Change_Log::new_instance(
180
+			[
181
+				'LOG_type'    => EEM_Change_Log::type_gateway,
182
+				'LOG_message' => $message,
183
+				'OBJ_ID'      => $related_obj_id,
184
+				'OBJ_type'    => $related_obj_type,
185
+			]
186
+		);
187
+		$log->save();
188
+		return $log;
189
+	}
190 190
 
191 191
 
192
-    /**
193
-     * Just gets the bare-bones wpdb results as an array in cases where efficiency is essential
194
-     *
195
-     * @param array $query_params
196
-     * @return array of arrays
197
-     * @throws EE_Error
198
-     * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
199
-     */
200
-    public function get_all_efficiently(array $query_params): array
201
-    {
202
-        return $this->_get_all_wpdb_results($query_params);
203
-    }
192
+	/**
193
+	 * Just gets the bare-bones wpdb results as an array in cases where efficiency is essential
194
+	 *
195
+	 * @param array $query_params
196
+	 * @return array of arrays
197
+	 * @throws EE_Error
198
+	 * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
199
+	 */
200
+	public function get_all_efficiently(array $query_params): array
201
+	{
202
+		return $this->_get_all_wpdb_results($query_params);
203
+	}
204 204
 
205 205
 
206
-    /**
207
-     * Executes a database query to delete gateway logs. Does not affect model objects, so if you attempt to use
208
-     * models after this, they may be out-of-sync with the database
209
-     *
210
-     * @param DateTime $datetime
211
-     * @return false|int
212
-     * @throws EE_Error
213
-     */
214
-    public function delete_gateway_logs_older_than(DateTime $datetime)
215
-    {
216
-        global $wpdb;
217
-        return $wpdb->query(
218
-            $wpdb->prepare(
219
-                'DELETE FROM ' . $this->table() . ' WHERE LOG_type = %s AND LOG_time < %s',
220
-                EEM_Change_Log::type_gateway,
221
-                $datetime->format(EE_Datetime_Field::mysql_timestamp_format)
222
-            )
223
-        );
224
-    }
206
+	/**
207
+	 * Executes a database query to delete gateway logs. Does not affect model objects, so if you attempt to use
208
+	 * models after this, they may be out-of-sync with the database
209
+	 *
210
+	 * @param DateTime $datetime
211
+	 * @return false|int
212
+	 * @throws EE_Error
213
+	 */
214
+	public function delete_gateway_logs_older_than(DateTime $datetime)
215
+	{
216
+		global $wpdb;
217
+		return $wpdb->query(
218
+			$wpdb->prepare(
219
+				'DELETE FROM ' . $this->table() . ' WHERE LOG_type = %s AND LOG_time < %s',
220
+				EEM_Change_Log::type_gateway,
221
+				$datetime->format(EE_Datetime_Field::mysql_timestamp_format)
222
+			)
223
+		);
224
+	}
225 225
 
226 226
 
227
-    /**
228
-     * Returns the map of type to pretty label for identifiers used for `LOG_type`.  Client code can register their own
229
-     * map vai the given filter.
230
-     *
231
-     * @return array
232
-     */
233
-    public static function get_pretty_label_map_for_registered_types(): array
234
-    {
235
-        return apply_filters(
236
-            'FHEE__EEM_Change_Log__get_pretty_label_map_for_registered_types',
237
-            [
238
-                self::type_create  => esc_html__("Create", "event_espresso"),
239
-                self::type_update  => esc_html__("Update", "event_espresso"),
240
-                self::type_delete  => esc_html__("Delete", "event_espresso"),
241
-                self::type_debug   => esc_html__("Debug", "event_espresso"),
242
-                self::type_error   => esc_html__("Error", "event_espresso"),
243
-                self::type_gateway => esc_html__("Gateway Interaction (IPN or Direct Payment)", 'event_espresso'),
244
-            ]
245
-        );
246
-    }
227
+	/**
228
+	 * Returns the map of type to pretty label for identifiers used for `LOG_type`.  Client code can register their own
229
+	 * map vai the given filter.
230
+	 *
231
+	 * @return array
232
+	 */
233
+	public static function get_pretty_label_map_for_registered_types(): array
234
+	{
235
+		return apply_filters(
236
+			'FHEE__EEM_Change_Log__get_pretty_label_map_for_registered_types',
237
+			[
238
+				self::type_create  => esc_html__("Create", "event_espresso"),
239
+				self::type_update  => esc_html__("Update", "event_espresso"),
240
+				self::type_delete  => esc_html__("Delete", "event_espresso"),
241
+				self::type_debug   => esc_html__("Debug", "event_espresso"),
242
+				self::type_error   => esc_html__("Error", "event_espresso"),
243
+				self::type_gateway => esc_html__("Gateway Interaction (IPN or Direct Payment)", 'event_espresso'),
244
+			]
245
+		);
246
+	}
247 247
 
248 248
 
249
-    /**
250
-     * Return the pretty (localized) label for the given log type identifier.
251
-     *
252
-     * @param string $type_identifier
253
-     * @return string
254
-     */
255
-    public static function get_pretty_label_for_type(string $type_identifier): string
256
-    {
257
-        $type_identifier_map = self::get_pretty_label_map_for_registered_types();
258
-        // we fall back to the incoming type identifier if there is no localized label for it.
259
-        return $type_identifier_map[ $type_identifier ] ?? $type_identifier;
260
-    }
249
+	/**
250
+	 * Return the pretty (localized) label for the given log type identifier.
251
+	 *
252
+	 * @param string $type_identifier
253
+	 * @return string
254
+	 */
255
+	public static function get_pretty_label_for_type(string $type_identifier): string
256
+	{
257
+		$type_identifier_map = self::get_pretty_label_map_for_registered_types();
258
+		// we fall back to the incoming type identifier if there is no localized label for it.
259
+		return $type_identifier_map[ $type_identifier ] ?? $type_identifier;
260
+	}
261 261
 }
Please login to merge, or discard this patch.
core/db_models/EEM_Datetime.model.php 1 patch
Indentation   +836 added lines, -836 removed lines patch added patch discarded remove patch
@@ -16,840 +16,840 @@
 block discarded – undo
16 16
  */
17 17
 class EEM_Datetime extends EEM_Soft_Delete_Base
18 18
 {
19
-    protected static ?EEM_Datetime $_instance = null;
20
-
21
-
22
-    /**
23
-     * private constructor to prevent direct creation
24
-     *
25
-     * @param string|null $timezone A string representing the timezone we want to set for returned Date Time Strings
26
-     *                              (and any incoming timezone data that gets saved).
27
-     *                              Note this just sends the timezone info to the date time model field objects.
28
-     *                              Default is NULL
29
-     *                              (and will be assumed using the set timezone in the 'timezone_string' wp option)
30
-     * @throws EE_Error
31
-     */
32
-    protected function __construct(?string $timezone = '')
33
-    {
34
-        $this->singular_item           = esc_html__('Datetime', 'event_espresso');
35
-        $this->plural_item             = esc_html__('Datetimes', 'event_espresso');
36
-        $this->_tables                 = [
37
-            'Datetime' => new EE_Primary_Table('esp_datetime', 'DTT_ID'),
38
-        ];
39
-        $this->_fields                 = [
40
-            'Datetime' => [
41
-                'DTT_ID'          => new EE_Primary_Key_Int_Field(
42
-                    'DTT_ID',
43
-                    esc_html__('Datetime ID', 'event_espresso')
44
-                ),
45
-                'EVT_ID'          => new EE_Foreign_Key_Int_Field(
46
-                    'EVT_ID',
47
-                    esc_html__('Event ID', 'event_espresso'),
48
-                    false,
49
-                    0,
50
-                    'Event'
51
-                ),
52
-                'VNU_ID'          => new EE_Foreign_Key_Int_Field(
53
-                    'VNU_ID',
54
-                    __('Venue ID', 'event_espresso'),
55
-                    false,
56
-                    0,
57
-                    'Venue'
58
-                ),
59
-                'DTT_name'        => new EE_Plain_Text_Field(
60
-                    'DTT_name',
61
-                    esc_html__('Datetime Name', 'event_espresso'),
62
-                    false,
63
-                    ''
64
-                ),
65
-                'DTT_description' => new EE_Post_Content_Field(
66
-                    'DTT_description',
67
-                    esc_html__('Description for Datetime', 'event_espresso'),
68
-                    false,
69
-                    ''
70
-                ),
71
-                'DTT_EVT_start'   => new EE_Datetime_Field(
72
-                    'DTT_EVT_start',
73
-                    esc_html__('Start time/date of Event', 'event_espresso'),
74
-                    false,
75
-                    EE_Datetime_Field::now,
76
-                    $timezone
77
-                ),
78
-                'DTT_EVT_end'     => new EE_Datetime_Field(
79
-                    'DTT_EVT_end',
80
-                    esc_html__('End time/date of Event', 'event_espresso'),
81
-                    false,
82
-                    EE_Datetime_Field::now,
83
-                    $timezone
84
-                ),
85
-                'DTT_reg_limit'   => new EE_Infinite_Integer_Field(
86
-                    'DTT_reg_limit',
87
-                    esc_html__('Registration Limit for this time', 'event_espresso'),
88
-                    false,
89
-                    EE_INF
90
-                ),
91
-                'DTT_sold'        => new EE_Integer_Field(
92
-                    'DTT_sold',
93
-                    esc_html__('How many sales for this Datetime that have occurred', 'event_espresso'),
94
-                    false,
95
-                    0
96
-                ),
97
-                'DTT_reserved'    => new EE_Integer_Field(
98
-                    'DTT_reserved',
99
-                    esc_html__('Quantity of tickets reserved, but not yet fully purchased', 'event_espresso'),
100
-                    false,
101
-                    0
102
-                ),
103
-                'DTT_is_primary'  => new EE_Boolean_Field(
104
-                    'DTT_is_primary',
105
-                    esc_html__('Flag indicating datetime is primary one for event', 'event_espresso'),
106
-                    false,
107
-                    false
108
-                ),
109
-                'DTT_order'       => new EE_Integer_Field(
110
-                    'DTT_order',
111
-                    esc_html__('The order in which the Datetime is displayed', 'event_espresso'),
112
-                    false,
113
-                    0
114
-                ),
115
-                'DTT_parent'      => new EE_Integer_Field(
116
-                    'DTT_parent',
117
-                    esc_html__('Indicates what DTT_ID is the parent of this DTT_ID', 'event_espresso'),
118
-                    true,
119
-                    0
120
-                ),
121
-                'DTT_deleted'     => new EE_Trashed_Flag_Field(
122
-                    'DTT_deleted',
123
-                    esc_html__('Flag indicating datetime is archived', 'event_espresso'),
124
-                    false,
125
-                    false
126
-                ),
127
-            ],
128
-        ];
129
-        $this->_model_relations        = [
130
-            'Ticket'          => new EE_HABTM_Relation('Datetime_Ticket'),
131
-            'Event'           => new EE_Belongs_To_Relation(),
132
-            'Checkin'         => new EE_Has_Many_Relation(),
133
-            'Datetime_Ticket' => new EE_Has_Many_Relation(),
134
-            'Venue'           => new EE_Belongs_To_Relation(),
135
-        ];
136
-        $path_to_event_model           = 'Event';
137
-        $this->model_chain_to_password = $path_to_event_model;
138
-        $this->_model_chain_to_wp_user = $path_to_event_model;
139
-        // this model is generally available for reading
140
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ]       =
141
-            new EE_Restriction_Generator_Event_Related_Public(
142
-                $path_to_event_model
143
-            );
144
-        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] =
145
-            new EE_Restriction_Generator_Event_Related_Protected(
146
-                $path_to_event_model
147
-            );
148
-        $this->_cap_restriction_generators[ EEM_Base::caps_edit ]       =
149
-            new EE_Restriction_Generator_Event_Related_Protected(
150
-                $path_to_event_model
151
-            );
152
-        $this->_cap_restriction_generators[ EEM_Base::caps_delete ]     =
153
-            new EE_Restriction_Generator_Event_Related_Protected(
154
-                $path_to_event_model,
155
-                EEM_Base::caps_edit
156
-            );
157
-        parent::__construct($timezone);
158
-    }
159
-
160
-
161
-    /**
162
-     * create new blank datetime
163
-     *
164
-     * @access public
165
-     * @return EE_Datetime[] array on success, FALSE on fail
166
-     * @throws EE_Error
167
-     * @throws InvalidArgumentException
168
-     * @throws InvalidDataTypeException
169
-     * @throws ReflectionException
170
-     * @throws InvalidInterfaceException
171
-     */
172
-    public function create_new_blank_datetime()
173
-    {
174
-        // makes sure timezone is always set.
175
-        $timezone_string = $this->get_timezone();
176
-        /**
177
-         * Filters the initial start date for the new datetime.
178
-         * Any time included in this value will be overridden later so use additional filters to modify the time.
179
-         *
180
-         * @param int $start_date Unix timestamp representing now + 30 days in seconds.
181
-         * @return int Unix timestamp
182
-         */
183
-        $start_date = apply_filters(
184
-            'FHEE__EEM_Datetime__create_new_blank_datetime__start_date',
185
-            $this->current_time_for_query('DTT_EVT_start', true) + MONTH_IN_SECONDS
186
-        );
187
-        /**
188
-         * Filters the initial end date for the new datetime.
189
-         * Any time included in this value will be overridden later so use additional filters to modify the time.
190
-         *
191
-         * @param int $end_data Unix timestamp representing now + 30 days in seconds.
192
-         * @return int Unix timestamp
193
-         */
194
-        $end_date       = apply_filters(
195
-            'FHEE__EEM_Datetime__create_new_blank_datetime__end_date',
196
-            $this->current_time_for_query('DTT_EVT_end', true) + MONTH_IN_SECONDS
197
-        );
198
-        $blank_datetime = EE_Datetime::new_instance(
199
-            [
200
-                'DTT_EVT_start' => $start_date,
201
-                'DTT_EVT_end'   => $end_date,
202
-                'DTT_order'     => 1,
203
-                'DTT_reg_limit' => EE_INF_IN_DB,
204
-            ],
205
-            $timezone_string
206
-        );
207
-        /**
208
-         * Filters the initial start time and format for the new EE_Datetime instance.
209
-         *
210
-         * @param array $start_time An array having size 2.  First element is the time, second element is the time
211
-         *                          format.
212
-         * @return array
213
-         */
214
-        $start_time = apply_filters(
215
-            'FHEE__EEM_Datetime__create_new_blank_datetime__start_time',
216
-            ['8am', 'ga']
217
-        );
218
-        /**
219
-         * Filters the initial end time and format for the new EE_Datetime instance.
220
-         *
221
-         * @param array $end_time An array having size 2.  First element is the time, second element is the time
222
-         *                        format
223
-         * @return array
224
-         */
225
-        $end_time = apply_filters(
226
-            'FHEE__EEM_Datetime__create_new_blank_datetime__end_time',
227
-            ['5pm', 'ga']
228
-        );
229
-        $this->validateStartAndEndTimeForBlankDate($start_time, $end_time);
230
-        $blank_datetime->set_start_time(
231
-            $this->convert_datetime_for_query(
232
-                'DTT_EVT_start',
233
-                $start_time[0],
234
-                $start_time[1],
235
-                $timezone_string
236
-            )
237
-        );
238
-        $blank_datetime->set_end_time(
239
-            $this->convert_datetime_for_query(
240
-                'DTT_EVT_end',
241
-                $end_time[0],
242
-                $end_time[1],
243
-                $timezone_string
244
-            )
245
-        );
246
-        return [$blank_datetime];
247
-    }
248
-
249
-
250
-    /**
251
-     * Validates whether the start_time and end_time are in the expected format.
252
-     *
253
-     * @param array $start_time
254
-     * @param array $end_time
255
-     * @throws InvalidArgumentException
256
-     * @throws InvalidDataTypeException
257
-     */
258
-    private function validateStartAndEndTimeForBlankDate(array $start_time, array $end_time)
259
-    {
260
-        if (! is_array($start_time)) {
261
-            throw new InvalidDataTypeException('start_time', $start_time, 'array');
262
-        }
263
-        if (! is_array($end_time)) {
264
-            throw new InvalidDataTypeException('end_time', $end_time, 'array');
265
-        }
266
-        if (count($start_time) !== 2) {
267
-            throw new InvalidArgumentException(
268
-                sprintf(
269
-                    'The variable %1$s is expected to be an array with two elements.  The first item in the '
270
-                    . 'array should be a valid time string, the second item in the array should be a valid time format',
271
-                    '$start_time'
272
-                )
273
-            );
274
-        }
275
-        if (count($end_time) !== 2) {
276
-            throw new InvalidArgumentException(
277
-                sprintf(
278
-                    'The variable %1$s is expected to be an array with two elements.  The first item in the '
279
-                    . 'array should be a valid time string, the second item in the array should be a valid time format',
280
-                    '$end_time'
281
-                )
282
-            );
283
-        }
284
-    }
285
-
286
-
287
-    /**
288
-     * get event start date from db
289
-     *
290
-     * @access public
291
-     * @param int $EVT_ID
292
-     * @return EE_Datetime[] array on success, FALSE on fail
293
-     * @throws EE_Error
294
-     * @throws ReflectionException
295
-     */
296
-    public function get_all_event_dates($EVT_ID = 0)
297
-    {
298
-        if (! $EVT_ID) { // on add_new_event event_id gets set to 0
299
-            return $this->create_new_blank_datetime();
300
-        }
301
-        $results = $this->get_datetimes_for_event_ordered_by_DTT_order($EVT_ID);
302
-        if (empty($results)) {
303
-            return $this->create_new_blank_datetime();
304
-        }
305
-        return $results;
306
-    }
307
-
308
-
309
-    /**
310
-     * get all datetimes attached to an event ordered by the DTT_order field
311
-     *
312
-     * @public
313
-     * @param int     $EVT_ID     event id
314
-     * @param boolean $include_expired
315
-     * @param boolean $include_deleted
316
-     * @param int     $limit      If included then limit the count of results by
317
-     *                            the given number
318
-     * @return EE_Datetime[]
319
-     * @throws EE_Error
320
-     */
321
-    public function get_datetimes_for_event_ordered_by_DTT_order(
322
-        int $EVT_ID,
323
-        bool $include_expired = true,
324
-        bool $include_deleted = true,
325
-        $limit = 0
326
-    ) {
327
-        $prev_data_prep_value = $this->prepModelForQuery();
328
-        $where_params         = ['Event.EVT_ID' => absint($EVT_ID)];
329
-        $query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
330
-        $query_params         = $this->addDefaultWhereConditions($query_params);
331
-        $query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
332
-        return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
333
-    }
334
-
335
-
336
-    /**
337
-     * Gets the datetimes for the event (with the given limit), and orders them by "importance".
338
-     * By importance, we mean that the primary datetimes are most important (DEPRECATED FOR NOW),
339
-     * and then the earlier datetimes are the most important.
340
-     * Maybe we'll want this to take into account datetimes that haven't already passed, but we don't yet.
341
-     *
342
-     * @param int $EVT_ID
343
-     * @param int $limit
344
-     * @return EE_Datetime[]|EE_Base_Class[]
345
-     * @throws EE_Error
346
-     */
347
-    public function get_datetimes_for_event_ordered_by_importance(int $EVT_ID, $limit = 0)
348
-    {
349
-        $query_params[0] = ['Event.EVT_ID' => absint($EVT_ID)];
350
-        $query_params    = $this->addDefaultWhereConditions($query_params);
351
-        $query_params    = $this->addDefaultQueryParams($query_params, $limit);
352
-        return $this->get_all($query_params);
353
-    }
354
-
355
-
356
-    /**
357
-     * @param int     $EVT_ID
358
-     * @param boolean $include_expired
359
-     * @param boolean $include_deleted
360
-     * @return EE_Datetime
361
-     * @throws EE_Error
362
-     */
363
-    public function get_oldest_datetime_for_event(
364
-        int $EVT_ID,
365
-        bool $include_expired = false,
366
-        bool $include_deleted = false
367
-    ) {
368
-        $results = $this->get_datetimes_for_event_ordered_by_start_time(
369
-            $EVT_ID,
370
-            $include_expired,
371
-            $include_deleted,
372
-            1
373
-        );
374
-        if ($results) {
375
-            return array_shift($results);
376
-        }
377
-        return null;
378
-    }
379
-
380
-
381
-    /**
382
-     * Gets the 'primary' datetime for an event.
383
-     *
384
-     * @param int  $EVT_ID
385
-     * @param bool $try_to_exclude_expired
386
-     * @param bool $try_to_exclude_deleted
387
-     * @return EE_Datetime
388
-     * @throws EE_Error
389
-     */
390
-    public function get_primary_datetime_for_event(
391
-        int $EVT_ID,
392
-        bool $try_to_exclude_expired = true,
393
-        bool $try_to_exclude_deleted = true
394
-    ) {
395
-        if ($try_to_exclude_expired) {
396
-            $non_expired = $this->get_oldest_datetime_for_event($EVT_ID, false, false);
397
-            if ($non_expired) {
398
-                return $non_expired;
399
-            }
400
-        }
401
-        if ($try_to_exclude_deleted) {
402
-            $expired_even = $this->get_oldest_datetime_for_event($EVT_ID, true);
403
-            if ($expired_even) {
404
-                return $expired_even;
405
-            }
406
-        }
407
-        return $this->get_oldest_datetime_for_event($EVT_ID, true, true);
408
-    }
409
-
410
-
411
-    /**
412
-     * Gets ALL the datetimes for an event (including trashed ones, for now), ordered
413
-     * only by start date
414
-     *
415
-     * @param int     $EVT_ID
416
-     * @param boolean $include_expired
417
-     * @param boolean $include_deleted
418
-     * @param int     $limit
419
-     * @return EE_Datetime[]
420
-     * @throws EE_Error
421
-     */
422
-    public function get_datetimes_for_event_ordered_by_start_time(
423
-        int $EVT_ID,
424
-        bool $include_expired = true,
425
-        bool $include_deleted = true,
426
-        $limit = 0
427
-    ) {
428
-        $prev_data_prep_value = $this->prepModelForQuery();
429
-        $where_params         = ['Event.EVT_ID' => absint($EVT_ID)];
430
-        $query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
431
-        $query_params         = $this->addDefaultWhereConditions(
432
-            $query_params,
433
-            EEM_Base::default_where_conditions_this_only
434
-        );
435
-        $query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
436
-        return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
437
-    }
438
-
439
-
440
-    /**
441
-     * Gets ALL the datetimes for an ticket (including trashed ones, for now), ordered
442
-     * only by start date
443
-     *
444
-     * @param int     $TKT_ID
445
-     * @param boolean $include_expired
446
-     * @param boolean $include_deleted
447
-     * @param int     $limit
448
-     * @return EE_Datetime[]
449
-     * @throws EE_Error
450
-     */
451
-    public function get_datetimes_for_ticket_ordered_by_start_time(
452
-        int $TKT_ID,
453
-        bool $include_expired = true,
454
-        bool $include_deleted = true,
455
-        $limit = 0
456
-    ) {
457
-        $prev_data_prep_value = $this->prepModelForQuery();
458
-        $where_params         = ['Ticket.TKT_ID' => absint($TKT_ID)];
459
-        $query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
460
-        $query_params         = $this->addDefaultQueryParams($query_params, $limit);
461
-        return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
462
-    }
463
-
464
-
465
-    /**
466
-     * Gets all the datetimes for a ticket (including trashed ones, for now), ordered by the DTT_order for the
467
-     * datetimes.
468
-     *
469
-     * @param int      $TKT_ID           ID of ticket to retrieve the datetimes for
470
-     * @param boolean  $include_expired  whether to include expired datetimes or not
471
-     * @param boolean  $include_deleted  whether to include trashed datetimes or not.
472
-     * @param int|null $limit            if null, no limit, if int then limit results by
473
-     *                                   that number
474
-     * @return EE_Datetime[]
475
-     * @throws EE_Error
476
-     */
477
-    public function get_datetimes_for_ticket_ordered_by_DTT_order(
478
-        int $TKT_ID,
479
-        bool $include_expired = true,
480
-        bool $include_deleted = true,
481
-        $limit = 0
482
-    ) {
483
-        $prev_data_prep_value = $this->prepModelForQuery();
484
-        $where_params         = ['Ticket.TKT_ID' => absint($TKT_ID)];
485
-        $query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
486
-        $query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
487
-        return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
488
-    }
489
-
490
-
491
-    /**
492
-     * Gets the most important datetime for a particular event (ie, the primary event usually. But if for some WACK
493
-     * reason it doesn't exist, we consider the earliest event the most important)
494
-     *
495
-     * @param int $EVT_ID
496
-     * @return EE_Datetime
497
-     * @throws EE_Error
498
-     */
499
-    public function get_most_important_datetime_for_event(int $EVT_ID)
500
-    {
501
-        $results = $this->get_datetimes_for_event_ordered_by_importance($EVT_ID, 1);
502
-        if ($results) {
503
-            return array_shift($results);
504
-        }
505
-        return null;
506
-    }
507
-
508
-
509
-    /**
510
-     * This returns a wpdb->results        Array of all DTT month and years matching the incoming query params and
511
-     * grouped by month and year.
512
-     *
513
-     * @param array  $where_params       @see
514
-     *                                   https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
515
-     * @param string $evt_active_status  A string representing the evt active status to filter the months by.
516
-     *                                   Can be:
517
-     *                                   - '' = no filter
518
-     *                                   - upcoming = Published events with at least one upcoming datetime.
519
-     *                                   - expired = Events with all datetimes expired.
520
-     *                                   - active = Events that are published and have at least one datetime that
521
-     *                                   starts before now and ends after now.
522
-     *                                   - inactive = Events that are either not published.
523
-     * @return stdClass[]
524
-     * @throws EE_Error
525
-     * @throws InvalidArgumentException
526
-     * @throws InvalidArgumentException
527
-     */
528
-    public function get_dtt_months_and_years(array $where_params, $evt_active_status = '')
529
-    {
530
-        $current_time_for_DTT_EVT_start = $this->current_time_for_query('DTT_EVT_start');
531
-        $current_time_for_DTT_EVT_end   = $this->current_time_for_query('DTT_EVT_end');
532
-        switch ($evt_active_status) {
533
-            case 'upcoming':
534
-                $where_params['Event.status'] = 'publish';
535
-                // if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
536
-                if (isset($where_params['DTT_EVT_start'])) {
537
-                    $where_params['DTT_EVT_start*****'] = $where_params['DTT_EVT_start'];
538
-                }
539
-                $where_params['DTT_EVT_start'] = ['>', $current_time_for_DTT_EVT_start];
540
-                break;
541
-            case 'expired':
542
-                if (isset($where_params['Event.status'])) {
543
-                    unset($where_params['Event.status']);
544
-                }
545
-                // get events to exclude
546
-                $exclude_query[0] = array_merge(
547
-                    $where_params,
548
-                    ['DTT_EVT_end' => ['>', $current_time_for_DTT_EVT_end]]
549
-                );
550
-                // first get all events that have datetimes where its not expired.
551
-                $event_ids = $this->_get_all_wpdb_results(
552
-                    $exclude_query,
553
-                    OBJECT_K,
554
-                    'Datetime.EVT_ID'
555
-                );
556
-                $event_ids = array_keys($event_ids);
557
-                if (isset($where_params['DTT_EVT_end'])) {
558
-                    $where_params['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
559
-                }
560
-                $where_params['DTT_EVT_end']  = ['<', $current_time_for_DTT_EVT_end];
561
-                $where_params['Event.EVT_ID'] = ['NOT IN', $event_ids];
562
-                break;
563
-            case 'active':
564
-                $where_params['Event.status'] = 'publish';
565
-                if (isset($where_params['DTT_EVT_start'])) {
566
-                    $where_params['Datetime.DTT_EVT_start******'] = $where_params['DTT_EVT_start'];
567
-                }
568
-                if (isset($where_params['Datetime.DTT_EVT_end'])) {
569
-                    $where_params['Datetime.DTT_EVT_end*****'] = $where_params['DTT_EVT_end'];
570
-                }
571
-                $where_params['DTT_EVT_start'] = ['<', $current_time_for_DTT_EVT_start];
572
-                $where_params['DTT_EVT_end']   = ['>', $current_time_for_DTT_EVT_end];
573
-                break;
574
-            case 'inactive':
575
-                if (isset($where_params['Event.status'])) {
576
-                    unset($where_params['Event.status']);
577
-                }
578
-                if (isset($where_params['OR'])) {
579
-                    $where_params['AND']['OR'] = $where_params['OR'];
580
-                }
581
-                if (isset($where_params['DTT_EVT_end'])) {
582
-                    $where_params['AND']['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
583
-                    unset($where_params['DTT_EVT_end']);
584
-                }
585
-                if (isset($where_params['DTT_EVT_start'])) {
586
-                    $where_params['AND']['DTT_EVT_start'] = $where_params['DTT_EVT_start'];
587
-                    unset($where_params['DTT_EVT_start']);
588
-                }
589
-                $where_params['AND']['Event.status'] = ['!=', 'publish'];
590
-                break;
591
-        }
592
-        $query_params[0]          = $where_params;
593
-        $query_params['group_by'] = ['dtt_year', 'dtt_month'];
594
-        $query_params             = $this->addOrderByQueryParams($query_params, 'DTT_EVT_start', 'DESC');
595
-
596
-        $query_interval    = EEH_DTT_Helper::get_sql_query_interval_for_offset(
597
-            $this->get_timezone(),
598
-            'DTT_EVT_start'
599
-        );
600
-        $columns_to_select = [
601
-            'dtt_year'      => ['YEAR(' . $query_interval . ')', '%s'],
602
-            'dtt_month'     => ['MONTHNAME(' . $query_interval . ')', '%s'],
603
-            'dtt_month_num' => ['MONTH(' . $query_interval . ')', '%s'],
604
-        ];
605
-        return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
606
-    }
607
-
608
-
609
-    /**
610
-     * Updates the DTT_sold attribute on each datetime (based on the registrations
611
-     * for the tickets for each datetime)
612
-     *
613
-     * @param EE_Base_Class[]|EE_Datetime[] $datetimes
614
-     * @throws EE_Error
615
-     * @throws ReflectionException
616
-     */
617
-    public function update_sold(array $datetimes)
618
-    {
619
-        EE_Error::doing_it_wrong(
620
-            __FUNCTION__,
621
-            esc_html__(
622
-                'Please use \EEM_Ticket::update_tickets_sold() instead which will in turn correctly update both the Ticket AND Datetime counts.',
623
-                'event_espresso'
624
-            ),
625
-            '4.9.32.rc.005'
626
-        );
627
-        foreach ($datetimes as $datetime) {
628
-            $datetime->update_sold();
629
-        }
630
-    }
631
-
632
-
633
-    /**
634
-     *    Gets the total number of tickets available at a particular datetime
635
-     *    (does NOT take into account the datetime's spaces available)
636
-     *
637
-     * @param int   $DTT_ID
638
-     * @param array $query_params
639
-     * @return int of tickets available. If sold out, return less than 1. If infinite, returns EE_INF,  IF there are NO
640
-     *             tickets attached to datetime then FALSE is returned.
641
-     * @throws EE_Error
642
-     * @throws ReflectionException
643
-     */
644
-    public function sum_tickets_currently_available_at_datetime(int $DTT_ID, array $query_params = [])
645
-    {
646
-        $datetime = $this->get_one_by_ID($DTT_ID);
647
-        if ($datetime instanceof EE_Datetime) {
648
-            return $datetime->tickets_remaining($query_params);
649
-        }
650
-        return 0;
651
-    }
652
-
653
-
654
-    /**
655
-     * This returns an array of counts of datetimes in the database for each Datetime status that can be queried.
656
-     *
657
-     * @param array $stati_to_include  If included you can restrict the statuses we return counts for by including the
658
-     *                                 stati you want counts for as values in the array.  An empty array returns counts
659
-     *                                 for all valid stati.
660
-     * @param array $query_params      If included can be used to refine the conditions for returning the count (i.e.
661
-     *                                 only for Datetimes connected to a specific event, or specific ticket.
662
-     * @return array  The value returned is an array indexed by Datetime Status and the values are the counts.  The
663
-     * @throws EE_Error
664
-     *                                 stati used as index keys are: EE_Datetime::active EE_Datetime::upcoming
665
-     *                                 EE_Datetime::expired
666
-     */
667
-    public function get_datetime_counts_by_status(array $stati_to_include = [], array $query_params = [])
668
-    {
669
-        // only accept where conditions for this query.
670
-        $_where            = isset($query_params[0]) ? $query_params[0] : [];
671
-        $status_query_args = [
672
-            EE_Datetime::active   => array_merge(
673
-                $_where,
674
-                ['DTT_EVT_start' => ['<', time()], 'DTT_EVT_end' => ['>', time()]]
675
-            ),
676
-            EE_Datetime::upcoming => array_merge(
677
-                $_where,
678
-                ['DTT_EVT_start' => ['>', time()]]
679
-            ),
680
-            EE_Datetime::expired  => array_merge(
681
-                $_where,
682
-                ['DTT_EVT_end' => ['<', time()]]
683
-            ),
684
-        ];
685
-        if (! empty($stati_to_include)) {
686
-            foreach (array_keys($status_query_args) as $status) {
687
-                if (! in_array($status, $stati_to_include, true)) {
688
-                    unset($status_query_args[ $status ]);
689
-                }
690
-            }
691
-        }
692
-        // loop through and query counts for each stati.
693
-        $status_query_results = [];
694
-        foreach ($status_query_args as $status => $status_where_conditions) {
695
-            $status_query_results[ $status ] = EEM_Datetime::count(
696
-                [$status_where_conditions],
697
-                'DTT_ID',
698
-                true
699
-            );
700
-        }
701
-        return $status_query_results;
702
-    }
703
-
704
-
705
-    /**
706
-     * Returns the specific count for a given Datetime status matching any given query_params.
707
-     *
708
-     * @param string $status Valid string representation for Datetime status requested. (Defaults to Active).
709
-     * @param array  $query_params
710
-     * @return int
711
-     * @throws EE_Error
712
-     */
713
-    public function get_datetime_count_for_status($status = EE_Datetime::active, array $query_params = [])
714
-    {
715
-        $count = $this->get_datetime_counts_by_status([$status], $query_params);
716
-        return ! empty($count[ $status ]) ? $count[ $status ] : 0;
717
-    }
718
-
719
-
720
-    /**
721
-     * @return bool|int
722
-     * @since   5.0.0.p
723
-     */
724
-    private function prepModelForQuery()
725
-    {
726
-        $prev_data_prep_value = $this->get_assumption_concerning_values_already_prepared_by_model_object();
727
-        $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
728
-        return $prev_data_prep_value;
729
-    }
730
-
731
-
732
-    /**
733
-     * @param array    $query_params
734
-     * @param bool|int $prev_data_prep_value
735
-     * @return EE_Base_Class[]|EE_Datetime[]
736
-     * @throws EE_Error
737
-     * @since   5.0.0.p
738
-     */
739
-    private function getDatetimesAndRestoreModel(array $query_params, $prev_data_prep_value)
740
-    {
741
-        $result = $this->get_all($query_params);
742
-        $this->assume_values_already_prepared_by_model_object($prev_data_prep_value);
743
-        return $result;
744
-    }
745
-
746
-
747
-    /**
748
-     * @param array  $query_params
749
-     * @param int    $limit
750
-     * @param string $order_by
751
-     * @param string $order
752
-     * @return array
753
-     * @since   5.0.0.p
754
-     */
755
-    private function addDefaultQueryParams(array $query_params, $limit = 0, $order_by = 'DTT_EVT_start', $order = 'ASC')
756
-    {
757
-        $query_params = $this->addOrderByQueryParams($query_params, $order_by, $order);
758
-        $query_params = $this->addLimitQueryParams($query_params, $limit);
759
-        return $query_params;
760
-    }
761
-
762
-
763
-    /**
764
-     * @param array  $query_params
765
-     * @param string $default_where_conditions
766
-     * @return array
767
-     * @since   5.0.0.p
768
-     */
769
-    private function addDefaultWhereConditions(
770
-        array $query_params,
771
-        $default_where_conditions = EEM_Base::default_where_conditions_none
772
-    ) {
773
-        $query_params['default_where_conditions'] = $default_where_conditions;
774
-        return $query_params;
775
-    }
776
-
777
-
778
-    /**
779
-     * @param array $where_params
780
-     * @param bool  $include_deleted
781
-     * @param bool  $include_expired
782
-     * @return array
783
-     * @since   5.0.0.p
784
-     */
785
-    private function addDefaultWhereParams(
786
-        array $where_params,
787
-        bool $include_deleted = true,
788
-        bool $include_expired = true
789
-    ) {
790
-        $where_params = $this->addExpiredWhereParams($where_params, $include_expired);
791
-        $where_params = $this->addDeletedWhereParams($where_params, $include_deleted);
792
-        return $where_params;
793
-    }
794
-
795
-
796
-    /**
797
-     * @param array $where_params
798
-     * @param bool  $include_deleted
799
-     * @return array
800
-     * @since   5.0.0.p
801
-     */
802
-    private function addDeletedWhereParams(array $where_params, bool $include_deleted = true)
803
-    {
804
-        $deleted                     = $include_deleted ? [true, false] : [false];
805
-        $where_params['DTT_deleted'] = ['IN', $deleted];
806
-        return $where_params;
807
-    }
808
-
809
-
810
-    /**
811
-     * @param array $where_params
812
-     * @param bool  $include_expired
813
-     * @return array
814
-     * @since   5.0.0.p
815
-     */
816
-    private function addExpiredWhereParams(array $where_params, bool $include_expired = true)
817
-    {
818
-        if (! $include_expired) {
819
-            $where_params['DTT_EVT_end'] = ['>=', current_time('mysql', true)];
820
-        }
821
-        return $where_params;
822
-    }
823
-
824
-
825
-    /**
826
-     * @param array $query_params
827
-     * @param int   $limit
828
-     * @return array
829
-     * @since   5.0.0.p
830
-     */
831
-    private function addLimitQueryParams(array $query_params, $limit = 0)
832
-    {
833
-        if ($limit) {
834
-            $query_params['limit'] = $limit;
835
-        }
836
-        return $query_params;
837
-    }
838
-
839
-
840
-    /**
841
-     * @param array  $query_params
842
-     * @param string $order_by
843
-     * @param string $order
844
-     * @return array
845
-     * @since   5.0.0.p
846
-     */
847
-    private function addOrderByQueryParams(array $query_params, $order_by = 'DTT_EVT_start', $order = 'ASC')
848
-    {
849
-        $order                    = $order === 'ASC' ? 'ASC' : 'DESC';
850
-        $valid_order_columns      = ['DTT_ID', 'DTT_EVT_start', 'DTT_EVT_end', 'DTT_order'];
851
-        $order_by                 = in_array($order_by, $valid_order_columns, true) ? $order_by : 'DTT_EVT_start';
852
-        $query_params['order_by'] = [$order_by => $order];
853
-        return $query_params;
854
-    }
19
+	protected static ?EEM_Datetime $_instance = null;
20
+
21
+
22
+	/**
23
+	 * private constructor to prevent direct creation
24
+	 *
25
+	 * @param string|null $timezone A string representing the timezone we want to set for returned Date Time Strings
26
+	 *                              (and any incoming timezone data that gets saved).
27
+	 *                              Note this just sends the timezone info to the date time model field objects.
28
+	 *                              Default is NULL
29
+	 *                              (and will be assumed using the set timezone in the 'timezone_string' wp option)
30
+	 * @throws EE_Error
31
+	 */
32
+	protected function __construct(?string $timezone = '')
33
+	{
34
+		$this->singular_item           = esc_html__('Datetime', 'event_espresso');
35
+		$this->plural_item             = esc_html__('Datetimes', 'event_espresso');
36
+		$this->_tables                 = [
37
+			'Datetime' => new EE_Primary_Table('esp_datetime', 'DTT_ID'),
38
+		];
39
+		$this->_fields                 = [
40
+			'Datetime' => [
41
+				'DTT_ID'          => new EE_Primary_Key_Int_Field(
42
+					'DTT_ID',
43
+					esc_html__('Datetime ID', 'event_espresso')
44
+				),
45
+				'EVT_ID'          => new EE_Foreign_Key_Int_Field(
46
+					'EVT_ID',
47
+					esc_html__('Event ID', 'event_espresso'),
48
+					false,
49
+					0,
50
+					'Event'
51
+				),
52
+				'VNU_ID'          => new EE_Foreign_Key_Int_Field(
53
+					'VNU_ID',
54
+					__('Venue ID', 'event_espresso'),
55
+					false,
56
+					0,
57
+					'Venue'
58
+				),
59
+				'DTT_name'        => new EE_Plain_Text_Field(
60
+					'DTT_name',
61
+					esc_html__('Datetime Name', 'event_espresso'),
62
+					false,
63
+					''
64
+				),
65
+				'DTT_description' => new EE_Post_Content_Field(
66
+					'DTT_description',
67
+					esc_html__('Description for Datetime', 'event_espresso'),
68
+					false,
69
+					''
70
+				),
71
+				'DTT_EVT_start'   => new EE_Datetime_Field(
72
+					'DTT_EVT_start',
73
+					esc_html__('Start time/date of Event', 'event_espresso'),
74
+					false,
75
+					EE_Datetime_Field::now,
76
+					$timezone
77
+				),
78
+				'DTT_EVT_end'     => new EE_Datetime_Field(
79
+					'DTT_EVT_end',
80
+					esc_html__('End time/date of Event', 'event_espresso'),
81
+					false,
82
+					EE_Datetime_Field::now,
83
+					$timezone
84
+				),
85
+				'DTT_reg_limit'   => new EE_Infinite_Integer_Field(
86
+					'DTT_reg_limit',
87
+					esc_html__('Registration Limit for this time', 'event_espresso'),
88
+					false,
89
+					EE_INF
90
+				),
91
+				'DTT_sold'        => new EE_Integer_Field(
92
+					'DTT_sold',
93
+					esc_html__('How many sales for this Datetime that have occurred', 'event_espresso'),
94
+					false,
95
+					0
96
+				),
97
+				'DTT_reserved'    => new EE_Integer_Field(
98
+					'DTT_reserved',
99
+					esc_html__('Quantity of tickets reserved, but not yet fully purchased', 'event_espresso'),
100
+					false,
101
+					0
102
+				),
103
+				'DTT_is_primary'  => new EE_Boolean_Field(
104
+					'DTT_is_primary',
105
+					esc_html__('Flag indicating datetime is primary one for event', 'event_espresso'),
106
+					false,
107
+					false
108
+				),
109
+				'DTT_order'       => new EE_Integer_Field(
110
+					'DTT_order',
111
+					esc_html__('The order in which the Datetime is displayed', 'event_espresso'),
112
+					false,
113
+					0
114
+				),
115
+				'DTT_parent'      => new EE_Integer_Field(
116
+					'DTT_parent',
117
+					esc_html__('Indicates what DTT_ID is the parent of this DTT_ID', 'event_espresso'),
118
+					true,
119
+					0
120
+				),
121
+				'DTT_deleted'     => new EE_Trashed_Flag_Field(
122
+					'DTT_deleted',
123
+					esc_html__('Flag indicating datetime is archived', 'event_espresso'),
124
+					false,
125
+					false
126
+				),
127
+			],
128
+		];
129
+		$this->_model_relations        = [
130
+			'Ticket'          => new EE_HABTM_Relation('Datetime_Ticket'),
131
+			'Event'           => new EE_Belongs_To_Relation(),
132
+			'Checkin'         => new EE_Has_Many_Relation(),
133
+			'Datetime_Ticket' => new EE_Has_Many_Relation(),
134
+			'Venue'           => new EE_Belongs_To_Relation(),
135
+		];
136
+		$path_to_event_model           = 'Event';
137
+		$this->model_chain_to_password = $path_to_event_model;
138
+		$this->_model_chain_to_wp_user = $path_to_event_model;
139
+		// this model is generally available for reading
140
+		$this->_cap_restriction_generators[ EEM_Base::caps_read ]       =
141
+			new EE_Restriction_Generator_Event_Related_Public(
142
+				$path_to_event_model
143
+			);
144
+		$this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] =
145
+			new EE_Restriction_Generator_Event_Related_Protected(
146
+				$path_to_event_model
147
+			);
148
+		$this->_cap_restriction_generators[ EEM_Base::caps_edit ]       =
149
+			new EE_Restriction_Generator_Event_Related_Protected(
150
+				$path_to_event_model
151
+			);
152
+		$this->_cap_restriction_generators[ EEM_Base::caps_delete ]     =
153
+			new EE_Restriction_Generator_Event_Related_Protected(
154
+				$path_to_event_model,
155
+				EEM_Base::caps_edit
156
+			);
157
+		parent::__construct($timezone);
158
+	}
159
+
160
+
161
+	/**
162
+	 * create new blank datetime
163
+	 *
164
+	 * @access public
165
+	 * @return EE_Datetime[] array on success, FALSE on fail
166
+	 * @throws EE_Error
167
+	 * @throws InvalidArgumentException
168
+	 * @throws InvalidDataTypeException
169
+	 * @throws ReflectionException
170
+	 * @throws InvalidInterfaceException
171
+	 */
172
+	public function create_new_blank_datetime()
173
+	{
174
+		// makes sure timezone is always set.
175
+		$timezone_string = $this->get_timezone();
176
+		/**
177
+		 * Filters the initial start date for the new datetime.
178
+		 * Any time included in this value will be overridden later so use additional filters to modify the time.
179
+		 *
180
+		 * @param int $start_date Unix timestamp representing now + 30 days in seconds.
181
+		 * @return int Unix timestamp
182
+		 */
183
+		$start_date = apply_filters(
184
+			'FHEE__EEM_Datetime__create_new_blank_datetime__start_date',
185
+			$this->current_time_for_query('DTT_EVT_start', true) + MONTH_IN_SECONDS
186
+		);
187
+		/**
188
+		 * Filters the initial end date for the new datetime.
189
+		 * Any time included in this value will be overridden later so use additional filters to modify the time.
190
+		 *
191
+		 * @param int $end_data Unix timestamp representing now + 30 days in seconds.
192
+		 * @return int Unix timestamp
193
+		 */
194
+		$end_date       = apply_filters(
195
+			'FHEE__EEM_Datetime__create_new_blank_datetime__end_date',
196
+			$this->current_time_for_query('DTT_EVT_end', true) + MONTH_IN_SECONDS
197
+		);
198
+		$blank_datetime = EE_Datetime::new_instance(
199
+			[
200
+				'DTT_EVT_start' => $start_date,
201
+				'DTT_EVT_end'   => $end_date,
202
+				'DTT_order'     => 1,
203
+				'DTT_reg_limit' => EE_INF_IN_DB,
204
+			],
205
+			$timezone_string
206
+		);
207
+		/**
208
+		 * Filters the initial start time and format for the new EE_Datetime instance.
209
+		 *
210
+		 * @param array $start_time An array having size 2.  First element is the time, second element is the time
211
+		 *                          format.
212
+		 * @return array
213
+		 */
214
+		$start_time = apply_filters(
215
+			'FHEE__EEM_Datetime__create_new_blank_datetime__start_time',
216
+			['8am', 'ga']
217
+		);
218
+		/**
219
+		 * Filters the initial end time and format for the new EE_Datetime instance.
220
+		 *
221
+		 * @param array $end_time An array having size 2.  First element is the time, second element is the time
222
+		 *                        format
223
+		 * @return array
224
+		 */
225
+		$end_time = apply_filters(
226
+			'FHEE__EEM_Datetime__create_new_blank_datetime__end_time',
227
+			['5pm', 'ga']
228
+		);
229
+		$this->validateStartAndEndTimeForBlankDate($start_time, $end_time);
230
+		$blank_datetime->set_start_time(
231
+			$this->convert_datetime_for_query(
232
+				'DTT_EVT_start',
233
+				$start_time[0],
234
+				$start_time[1],
235
+				$timezone_string
236
+			)
237
+		);
238
+		$blank_datetime->set_end_time(
239
+			$this->convert_datetime_for_query(
240
+				'DTT_EVT_end',
241
+				$end_time[0],
242
+				$end_time[1],
243
+				$timezone_string
244
+			)
245
+		);
246
+		return [$blank_datetime];
247
+	}
248
+
249
+
250
+	/**
251
+	 * Validates whether the start_time and end_time are in the expected format.
252
+	 *
253
+	 * @param array $start_time
254
+	 * @param array $end_time
255
+	 * @throws InvalidArgumentException
256
+	 * @throws InvalidDataTypeException
257
+	 */
258
+	private function validateStartAndEndTimeForBlankDate(array $start_time, array $end_time)
259
+	{
260
+		if (! is_array($start_time)) {
261
+			throw new InvalidDataTypeException('start_time', $start_time, 'array');
262
+		}
263
+		if (! is_array($end_time)) {
264
+			throw new InvalidDataTypeException('end_time', $end_time, 'array');
265
+		}
266
+		if (count($start_time) !== 2) {
267
+			throw new InvalidArgumentException(
268
+				sprintf(
269
+					'The variable %1$s is expected to be an array with two elements.  The first item in the '
270
+					. 'array should be a valid time string, the second item in the array should be a valid time format',
271
+					'$start_time'
272
+				)
273
+			);
274
+		}
275
+		if (count($end_time) !== 2) {
276
+			throw new InvalidArgumentException(
277
+				sprintf(
278
+					'The variable %1$s is expected to be an array with two elements.  The first item in the '
279
+					. 'array should be a valid time string, the second item in the array should be a valid time format',
280
+					'$end_time'
281
+				)
282
+			);
283
+		}
284
+	}
285
+
286
+
287
+	/**
288
+	 * get event start date from db
289
+	 *
290
+	 * @access public
291
+	 * @param int $EVT_ID
292
+	 * @return EE_Datetime[] array on success, FALSE on fail
293
+	 * @throws EE_Error
294
+	 * @throws ReflectionException
295
+	 */
296
+	public function get_all_event_dates($EVT_ID = 0)
297
+	{
298
+		if (! $EVT_ID) { // on add_new_event event_id gets set to 0
299
+			return $this->create_new_blank_datetime();
300
+		}
301
+		$results = $this->get_datetimes_for_event_ordered_by_DTT_order($EVT_ID);
302
+		if (empty($results)) {
303
+			return $this->create_new_blank_datetime();
304
+		}
305
+		return $results;
306
+	}
307
+
308
+
309
+	/**
310
+	 * get all datetimes attached to an event ordered by the DTT_order field
311
+	 *
312
+	 * @public
313
+	 * @param int     $EVT_ID     event id
314
+	 * @param boolean $include_expired
315
+	 * @param boolean $include_deleted
316
+	 * @param int     $limit      If included then limit the count of results by
317
+	 *                            the given number
318
+	 * @return EE_Datetime[]
319
+	 * @throws EE_Error
320
+	 */
321
+	public function get_datetimes_for_event_ordered_by_DTT_order(
322
+		int $EVT_ID,
323
+		bool $include_expired = true,
324
+		bool $include_deleted = true,
325
+		$limit = 0
326
+	) {
327
+		$prev_data_prep_value = $this->prepModelForQuery();
328
+		$where_params         = ['Event.EVT_ID' => absint($EVT_ID)];
329
+		$query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
330
+		$query_params         = $this->addDefaultWhereConditions($query_params);
331
+		$query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
332
+		return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
333
+	}
334
+
335
+
336
+	/**
337
+	 * Gets the datetimes for the event (with the given limit), and orders them by "importance".
338
+	 * By importance, we mean that the primary datetimes are most important (DEPRECATED FOR NOW),
339
+	 * and then the earlier datetimes are the most important.
340
+	 * Maybe we'll want this to take into account datetimes that haven't already passed, but we don't yet.
341
+	 *
342
+	 * @param int $EVT_ID
343
+	 * @param int $limit
344
+	 * @return EE_Datetime[]|EE_Base_Class[]
345
+	 * @throws EE_Error
346
+	 */
347
+	public function get_datetimes_for_event_ordered_by_importance(int $EVT_ID, $limit = 0)
348
+	{
349
+		$query_params[0] = ['Event.EVT_ID' => absint($EVT_ID)];
350
+		$query_params    = $this->addDefaultWhereConditions($query_params);
351
+		$query_params    = $this->addDefaultQueryParams($query_params, $limit);
352
+		return $this->get_all($query_params);
353
+	}
354
+
355
+
356
+	/**
357
+	 * @param int     $EVT_ID
358
+	 * @param boolean $include_expired
359
+	 * @param boolean $include_deleted
360
+	 * @return EE_Datetime
361
+	 * @throws EE_Error
362
+	 */
363
+	public function get_oldest_datetime_for_event(
364
+		int $EVT_ID,
365
+		bool $include_expired = false,
366
+		bool $include_deleted = false
367
+	) {
368
+		$results = $this->get_datetimes_for_event_ordered_by_start_time(
369
+			$EVT_ID,
370
+			$include_expired,
371
+			$include_deleted,
372
+			1
373
+		);
374
+		if ($results) {
375
+			return array_shift($results);
376
+		}
377
+		return null;
378
+	}
379
+
380
+
381
+	/**
382
+	 * Gets the 'primary' datetime for an event.
383
+	 *
384
+	 * @param int  $EVT_ID
385
+	 * @param bool $try_to_exclude_expired
386
+	 * @param bool $try_to_exclude_deleted
387
+	 * @return EE_Datetime
388
+	 * @throws EE_Error
389
+	 */
390
+	public function get_primary_datetime_for_event(
391
+		int $EVT_ID,
392
+		bool $try_to_exclude_expired = true,
393
+		bool $try_to_exclude_deleted = true
394
+	) {
395
+		if ($try_to_exclude_expired) {
396
+			$non_expired = $this->get_oldest_datetime_for_event($EVT_ID, false, false);
397
+			if ($non_expired) {
398
+				return $non_expired;
399
+			}
400
+		}
401
+		if ($try_to_exclude_deleted) {
402
+			$expired_even = $this->get_oldest_datetime_for_event($EVT_ID, true);
403
+			if ($expired_even) {
404
+				return $expired_even;
405
+			}
406
+		}
407
+		return $this->get_oldest_datetime_for_event($EVT_ID, true, true);
408
+	}
409
+
410
+
411
+	/**
412
+	 * Gets ALL the datetimes for an event (including trashed ones, for now), ordered
413
+	 * only by start date
414
+	 *
415
+	 * @param int     $EVT_ID
416
+	 * @param boolean $include_expired
417
+	 * @param boolean $include_deleted
418
+	 * @param int     $limit
419
+	 * @return EE_Datetime[]
420
+	 * @throws EE_Error
421
+	 */
422
+	public function get_datetimes_for_event_ordered_by_start_time(
423
+		int $EVT_ID,
424
+		bool $include_expired = true,
425
+		bool $include_deleted = true,
426
+		$limit = 0
427
+	) {
428
+		$prev_data_prep_value = $this->prepModelForQuery();
429
+		$where_params         = ['Event.EVT_ID' => absint($EVT_ID)];
430
+		$query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
431
+		$query_params         = $this->addDefaultWhereConditions(
432
+			$query_params,
433
+			EEM_Base::default_where_conditions_this_only
434
+		);
435
+		$query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
436
+		return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
437
+	}
438
+
439
+
440
+	/**
441
+	 * Gets ALL the datetimes for an ticket (including trashed ones, for now), ordered
442
+	 * only by start date
443
+	 *
444
+	 * @param int     $TKT_ID
445
+	 * @param boolean $include_expired
446
+	 * @param boolean $include_deleted
447
+	 * @param int     $limit
448
+	 * @return EE_Datetime[]
449
+	 * @throws EE_Error
450
+	 */
451
+	public function get_datetimes_for_ticket_ordered_by_start_time(
452
+		int $TKT_ID,
453
+		bool $include_expired = true,
454
+		bool $include_deleted = true,
455
+		$limit = 0
456
+	) {
457
+		$prev_data_prep_value = $this->prepModelForQuery();
458
+		$where_params         = ['Ticket.TKT_ID' => absint($TKT_ID)];
459
+		$query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
460
+		$query_params         = $this->addDefaultQueryParams($query_params, $limit);
461
+		return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
462
+	}
463
+
464
+
465
+	/**
466
+	 * Gets all the datetimes for a ticket (including trashed ones, for now), ordered by the DTT_order for the
467
+	 * datetimes.
468
+	 *
469
+	 * @param int      $TKT_ID           ID of ticket to retrieve the datetimes for
470
+	 * @param boolean  $include_expired  whether to include expired datetimes or not
471
+	 * @param boolean  $include_deleted  whether to include trashed datetimes or not.
472
+	 * @param int|null $limit            if null, no limit, if int then limit results by
473
+	 *                                   that number
474
+	 * @return EE_Datetime[]
475
+	 * @throws EE_Error
476
+	 */
477
+	public function get_datetimes_for_ticket_ordered_by_DTT_order(
478
+		int $TKT_ID,
479
+		bool $include_expired = true,
480
+		bool $include_deleted = true,
481
+		$limit = 0
482
+	) {
483
+		$prev_data_prep_value = $this->prepModelForQuery();
484
+		$where_params         = ['Ticket.TKT_ID' => absint($TKT_ID)];
485
+		$query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
486
+		$query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
487
+		return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
488
+	}
489
+
490
+
491
+	/**
492
+	 * Gets the most important datetime for a particular event (ie, the primary event usually. But if for some WACK
493
+	 * reason it doesn't exist, we consider the earliest event the most important)
494
+	 *
495
+	 * @param int $EVT_ID
496
+	 * @return EE_Datetime
497
+	 * @throws EE_Error
498
+	 */
499
+	public function get_most_important_datetime_for_event(int $EVT_ID)
500
+	{
501
+		$results = $this->get_datetimes_for_event_ordered_by_importance($EVT_ID, 1);
502
+		if ($results) {
503
+			return array_shift($results);
504
+		}
505
+		return null;
506
+	}
507
+
508
+
509
+	/**
510
+	 * This returns a wpdb->results        Array of all DTT month and years matching the incoming query params and
511
+	 * grouped by month and year.
512
+	 *
513
+	 * @param array  $where_params       @see
514
+	 *                                   https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
515
+	 * @param string $evt_active_status  A string representing the evt active status to filter the months by.
516
+	 *                                   Can be:
517
+	 *                                   - '' = no filter
518
+	 *                                   - upcoming = Published events with at least one upcoming datetime.
519
+	 *                                   - expired = Events with all datetimes expired.
520
+	 *                                   - active = Events that are published and have at least one datetime that
521
+	 *                                   starts before now and ends after now.
522
+	 *                                   - inactive = Events that are either not published.
523
+	 * @return stdClass[]
524
+	 * @throws EE_Error
525
+	 * @throws InvalidArgumentException
526
+	 * @throws InvalidArgumentException
527
+	 */
528
+	public function get_dtt_months_and_years(array $where_params, $evt_active_status = '')
529
+	{
530
+		$current_time_for_DTT_EVT_start = $this->current_time_for_query('DTT_EVT_start');
531
+		$current_time_for_DTT_EVT_end   = $this->current_time_for_query('DTT_EVT_end');
532
+		switch ($evt_active_status) {
533
+			case 'upcoming':
534
+				$where_params['Event.status'] = 'publish';
535
+				// if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
536
+				if (isset($where_params['DTT_EVT_start'])) {
537
+					$where_params['DTT_EVT_start*****'] = $where_params['DTT_EVT_start'];
538
+				}
539
+				$where_params['DTT_EVT_start'] = ['>', $current_time_for_DTT_EVT_start];
540
+				break;
541
+			case 'expired':
542
+				if (isset($where_params['Event.status'])) {
543
+					unset($where_params['Event.status']);
544
+				}
545
+				// get events to exclude
546
+				$exclude_query[0] = array_merge(
547
+					$where_params,
548
+					['DTT_EVT_end' => ['>', $current_time_for_DTT_EVT_end]]
549
+				);
550
+				// first get all events that have datetimes where its not expired.
551
+				$event_ids = $this->_get_all_wpdb_results(
552
+					$exclude_query,
553
+					OBJECT_K,
554
+					'Datetime.EVT_ID'
555
+				);
556
+				$event_ids = array_keys($event_ids);
557
+				if (isset($where_params['DTT_EVT_end'])) {
558
+					$where_params['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
559
+				}
560
+				$where_params['DTT_EVT_end']  = ['<', $current_time_for_DTT_EVT_end];
561
+				$where_params['Event.EVT_ID'] = ['NOT IN', $event_ids];
562
+				break;
563
+			case 'active':
564
+				$where_params['Event.status'] = 'publish';
565
+				if (isset($where_params['DTT_EVT_start'])) {
566
+					$where_params['Datetime.DTT_EVT_start******'] = $where_params['DTT_EVT_start'];
567
+				}
568
+				if (isset($where_params['Datetime.DTT_EVT_end'])) {
569
+					$where_params['Datetime.DTT_EVT_end*****'] = $where_params['DTT_EVT_end'];
570
+				}
571
+				$where_params['DTT_EVT_start'] = ['<', $current_time_for_DTT_EVT_start];
572
+				$where_params['DTT_EVT_end']   = ['>', $current_time_for_DTT_EVT_end];
573
+				break;
574
+			case 'inactive':
575
+				if (isset($where_params['Event.status'])) {
576
+					unset($where_params['Event.status']);
577
+				}
578
+				if (isset($where_params['OR'])) {
579
+					$where_params['AND']['OR'] = $where_params['OR'];
580
+				}
581
+				if (isset($where_params['DTT_EVT_end'])) {
582
+					$where_params['AND']['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
583
+					unset($where_params['DTT_EVT_end']);
584
+				}
585
+				if (isset($where_params['DTT_EVT_start'])) {
586
+					$where_params['AND']['DTT_EVT_start'] = $where_params['DTT_EVT_start'];
587
+					unset($where_params['DTT_EVT_start']);
588
+				}
589
+				$where_params['AND']['Event.status'] = ['!=', 'publish'];
590
+				break;
591
+		}
592
+		$query_params[0]          = $where_params;
593
+		$query_params['group_by'] = ['dtt_year', 'dtt_month'];
594
+		$query_params             = $this->addOrderByQueryParams($query_params, 'DTT_EVT_start', 'DESC');
595
+
596
+		$query_interval    = EEH_DTT_Helper::get_sql_query_interval_for_offset(
597
+			$this->get_timezone(),
598
+			'DTT_EVT_start'
599
+		);
600
+		$columns_to_select = [
601
+			'dtt_year'      => ['YEAR(' . $query_interval . ')', '%s'],
602
+			'dtt_month'     => ['MONTHNAME(' . $query_interval . ')', '%s'],
603
+			'dtt_month_num' => ['MONTH(' . $query_interval . ')', '%s'],
604
+		];
605
+		return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
606
+	}
607
+
608
+
609
+	/**
610
+	 * Updates the DTT_sold attribute on each datetime (based on the registrations
611
+	 * for the tickets for each datetime)
612
+	 *
613
+	 * @param EE_Base_Class[]|EE_Datetime[] $datetimes
614
+	 * @throws EE_Error
615
+	 * @throws ReflectionException
616
+	 */
617
+	public function update_sold(array $datetimes)
618
+	{
619
+		EE_Error::doing_it_wrong(
620
+			__FUNCTION__,
621
+			esc_html__(
622
+				'Please use \EEM_Ticket::update_tickets_sold() instead which will in turn correctly update both the Ticket AND Datetime counts.',
623
+				'event_espresso'
624
+			),
625
+			'4.9.32.rc.005'
626
+		);
627
+		foreach ($datetimes as $datetime) {
628
+			$datetime->update_sold();
629
+		}
630
+	}
631
+
632
+
633
+	/**
634
+	 *    Gets the total number of tickets available at a particular datetime
635
+	 *    (does NOT take into account the datetime's spaces available)
636
+	 *
637
+	 * @param int   $DTT_ID
638
+	 * @param array $query_params
639
+	 * @return int of tickets available. If sold out, return less than 1. If infinite, returns EE_INF,  IF there are NO
640
+	 *             tickets attached to datetime then FALSE is returned.
641
+	 * @throws EE_Error
642
+	 * @throws ReflectionException
643
+	 */
644
+	public function sum_tickets_currently_available_at_datetime(int $DTT_ID, array $query_params = [])
645
+	{
646
+		$datetime = $this->get_one_by_ID($DTT_ID);
647
+		if ($datetime instanceof EE_Datetime) {
648
+			return $datetime->tickets_remaining($query_params);
649
+		}
650
+		return 0;
651
+	}
652
+
653
+
654
+	/**
655
+	 * This returns an array of counts of datetimes in the database for each Datetime status that can be queried.
656
+	 *
657
+	 * @param array $stati_to_include  If included you can restrict the statuses we return counts for by including the
658
+	 *                                 stati you want counts for as values in the array.  An empty array returns counts
659
+	 *                                 for all valid stati.
660
+	 * @param array $query_params      If included can be used to refine the conditions for returning the count (i.e.
661
+	 *                                 only for Datetimes connected to a specific event, or specific ticket.
662
+	 * @return array  The value returned is an array indexed by Datetime Status and the values are the counts.  The
663
+	 * @throws EE_Error
664
+	 *                                 stati used as index keys are: EE_Datetime::active EE_Datetime::upcoming
665
+	 *                                 EE_Datetime::expired
666
+	 */
667
+	public function get_datetime_counts_by_status(array $stati_to_include = [], array $query_params = [])
668
+	{
669
+		// only accept where conditions for this query.
670
+		$_where            = isset($query_params[0]) ? $query_params[0] : [];
671
+		$status_query_args = [
672
+			EE_Datetime::active   => array_merge(
673
+				$_where,
674
+				['DTT_EVT_start' => ['<', time()], 'DTT_EVT_end' => ['>', time()]]
675
+			),
676
+			EE_Datetime::upcoming => array_merge(
677
+				$_where,
678
+				['DTT_EVT_start' => ['>', time()]]
679
+			),
680
+			EE_Datetime::expired  => array_merge(
681
+				$_where,
682
+				['DTT_EVT_end' => ['<', time()]]
683
+			),
684
+		];
685
+		if (! empty($stati_to_include)) {
686
+			foreach (array_keys($status_query_args) as $status) {
687
+				if (! in_array($status, $stati_to_include, true)) {
688
+					unset($status_query_args[ $status ]);
689
+				}
690
+			}
691
+		}
692
+		// loop through and query counts for each stati.
693
+		$status_query_results = [];
694
+		foreach ($status_query_args as $status => $status_where_conditions) {
695
+			$status_query_results[ $status ] = EEM_Datetime::count(
696
+				[$status_where_conditions],
697
+				'DTT_ID',
698
+				true
699
+			);
700
+		}
701
+		return $status_query_results;
702
+	}
703
+
704
+
705
+	/**
706
+	 * Returns the specific count for a given Datetime status matching any given query_params.
707
+	 *
708
+	 * @param string $status Valid string representation for Datetime status requested. (Defaults to Active).
709
+	 * @param array  $query_params
710
+	 * @return int
711
+	 * @throws EE_Error
712
+	 */
713
+	public function get_datetime_count_for_status($status = EE_Datetime::active, array $query_params = [])
714
+	{
715
+		$count = $this->get_datetime_counts_by_status([$status], $query_params);
716
+		return ! empty($count[ $status ]) ? $count[ $status ] : 0;
717
+	}
718
+
719
+
720
+	/**
721
+	 * @return bool|int
722
+	 * @since   5.0.0.p
723
+	 */
724
+	private function prepModelForQuery()
725
+	{
726
+		$prev_data_prep_value = $this->get_assumption_concerning_values_already_prepared_by_model_object();
727
+		$this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
728
+		return $prev_data_prep_value;
729
+	}
730
+
731
+
732
+	/**
733
+	 * @param array    $query_params
734
+	 * @param bool|int $prev_data_prep_value
735
+	 * @return EE_Base_Class[]|EE_Datetime[]
736
+	 * @throws EE_Error
737
+	 * @since   5.0.0.p
738
+	 */
739
+	private function getDatetimesAndRestoreModel(array $query_params, $prev_data_prep_value)
740
+	{
741
+		$result = $this->get_all($query_params);
742
+		$this->assume_values_already_prepared_by_model_object($prev_data_prep_value);
743
+		return $result;
744
+	}
745
+
746
+
747
+	/**
748
+	 * @param array  $query_params
749
+	 * @param int    $limit
750
+	 * @param string $order_by
751
+	 * @param string $order
752
+	 * @return array
753
+	 * @since   5.0.0.p
754
+	 */
755
+	private function addDefaultQueryParams(array $query_params, $limit = 0, $order_by = 'DTT_EVT_start', $order = 'ASC')
756
+	{
757
+		$query_params = $this->addOrderByQueryParams($query_params, $order_by, $order);
758
+		$query_params = $this->addLimitQueryParams($query_params, $limit);
759
+		return $query_params;
760
+	}
761
+
762
+
763
+	/**
764
+	 * @param array  $query_params
765
+	 * @param string $default_where_conditions
766
+	 * @return array
767
+	 * @since   5.0.0.p
768
+	 */
769
+	private function addDefaultWhereConditions(
770
+		array $query_params,
771
+		$default_where_conditions = EEM_Base::default_where_conditions_none
772
+	) {
773
+		$query_params['default_where_conditions'] = $default_where_conditions;
774
+		return $query_params;
775
+	}
776
+
777
+
778
+	/**
779
+	 * @param array $where_params
780
+	 * @param bool  $include_deleted
781
+	 * @param bool  $include_expired
782
+	 * @return array
783
+	 * @since   5.0.0.p
784
+	 */
785
+	private function addDefaultWhereParams(
786
+		array $where_params,
787
+		bool $include_deleted = true,
788
+		bool $include_expired = true
789
+	) {
790
+		$where_params = $this->addExpiredWhereParams($where_params, $include_expired);
791
+		$where_params = $this->addDeletedWhereParams($where_params, $include_deleted);
792
+		return $where_params;
793
+	}
794
+
795
+
796
+	/**
797
+	 * @param array $where_params
798
+	 * @param bool  $include_deleted
799
+	 * @return array
800
+	 * @since   5.0.0.p
801
+	 */
802
+	private function addDeletedWhereParams(array $where_params, bool $include_deleted = true)
803
+	{
804
+		$deleted                     = $include_deleted ? [true, false] : [false];
805
+		$where_params['DTT_deleted'] = ['IN', $deleted];
806
+		return $where_params;
807
+	}
808
+
809
+
810
+	/**
811
+	 * @param array $where_params
812
+	 * @param bool  $include_expired
813
+	 * @return array
814
+	 * @since   5.0.0.p
815
+	 */
816
+	private function addExpiredWhereParams(array $where_params, bool $include_expired = true)
817
+	{
818
+		if (! $include_expired) {
819
+			$where_params['DTT_EVT_end'] = ['>=', current_time('mysql', true)];
820
+		}
821
+		return $where_params;
822
+	}
823
+
824
+
825
+	/**
826
+	 * @param array $query_params
827
+	 * @param int   $limit
828
+	 * @return array
829
+	 * @since   5.0.0.p
830
+	 */
831
+	private function addLimitQueryParams(array $query_params, $limit = 0)
832
+	{
833
+		if ($limit) {
834
+			$query_params['limit'] = $limit;
835
+		}
836
+		return $query_params;
837
+	}
838
+
839
+
840
+	/**
841
+	 * @param array  $query_params
842
+	 * @param string $order_by
843
+	 * @param string $order
844
+	 * @return array
845
+	 * @since   5.0.0.p
846
+	 */
847
+	private function addOrderByQueryParams(array $query_params, $order_by = 'DTT_EVT_start', $order = 'ASC')
848
+	{
849
+		$order                    = $order === 'ASC' ? 'ASC' : 'DESC';
850
+		$valid_order_columns      = ['DTT_ID', 'DTT_EVT_start', 'DTT_EVT_end', 'DTT_order'];
851
+		$order_by                 = in_array($order_by, $valid_order_columns, true) ? $order_by : 'DTT_EVT_start';
852
+		$query_params['order_by'] = [$order_by => $order];
853
+		return $query_params;
854
+	}
855 855
 }
Please login to merge, or discard this patch.
core/db_models/EEM_Message_Template_Group.model.php 1 patch
Indentation   +432 added lines, -432 removed lines patch added patch discarded remove patch
@@ -13,436 +13,436 @@
 block discarded – undo
13 13
  */
14 14
 class EEM_Message_Template_Group extends EEM_Soft_Delete_Base
15 15
 {
16
-    protected static ?EEM_Message_Template_Group $_instance = null;
17
-
18
-
19
-    /**
20
-     * @param string|null $timezone
21
-     * @throws EE_Error
22
-     */
23
-    protected function __construct(?string $timezone = '')
24
-    {
25
-        $this->singular_item    = esc_html__('Message Template Group', 'event_espresso');
26
-        $this->plural_item      = esc_html__('Message Template Groups', 'event_espresso');
27
-        $this->_tables          = [
28
-            'Message_Template_Group' => new EE_Primary_Table('esp_message_template_group', 'GRP_ID'),
29
-        ];
30
-        $this->_fields          = [
31
-            'Message_Template_Group' => [
32
-                'GRP_ID'           => new EE_Primary_Key_Int_Field(
33
-                    'GRP_ID',
34
-                    esc_html__('Message Template Group ID', 'event_espresso')
35
-                ),
36
-                'MTP_name'         => new EE_Plain_Text_Field(
37
-                    'MTP_name',
38
-                    esc_html__('The name of the template group', 'event_espresso'),
39
-                    false,
40
-                    ''
41
-                ),
42
-                'MTP_description'  => new EE_Simple_HTML_Field(
43
-                    'MTP_description',
44
-                    esc_html__(
45
-                        'A brief description about this template.',
46
-                        'event_espresso'
47
-                    ),
48
-                    false,
49
-                    ''
50
-                ),
51
-                'MTP_user_id'      => new EE_WP_User_Field(
52
-                    'MTP_user_id',
53
-                    esc_html__('Template Creator ID', 'event_espresso'),
54
-                    false
55
-                ),
56
-                'MTP_messenger'    => new EE_Plain_Text_Field(
57
-                    'MTP_messenger',
58
-                    esc_html__(
59
-                        'Messenger Used for Template',
60
-                        'event_espresso'
61
-                    ),
62
-                    false,
63
-                    'email'
64
-                ),
65
-                'MTP_message_type' => new EE_Plain_Text_Field(
66
-                    'MTP_message_type',
67
-                    esc_html__('Message Type', 'event_espresso'),
68
-                    false,
69
-                    'registration'
70
-                ),
71
-                'MTP_is_global'    => new EE_Boolean_Field(
72
-                    'MTP_is_global',
73
-                    esc_html__(
74
-                        'Flag indicating if Template Group is Global',
75
-                        'event_espresso'
76
-                    ),
77
-                    false,
78
-                    true
79
-                ),
80
-                'MTP_is_override'  => new EE_Boolean_Field(
81
-                    'MTP_is_override',
82
-                    esc_html__(
83
-                        'Flag indicating if Template Group overrides any other Templates for the messenger/messagetype combination',
84
-                        'event_espresso'
85
-                    ),
86
-                    false,
87
-                    false
88
-                ),
89
-                'MTP_deleted'      => new EE_Trashed_Flag_Field(
90
-                    'MTP_deleted',
91
-                    esc_html__(
92
-                        'Flag indicating whether this has been trashed',
93
-                        'event_espresso'
94
-                    ),
95
-                    false,
96
-                    false
97
-                ),
98
-                'MTP_is_active'    => new EE_Boolean_Field(
99
-                    'MTP_is_active',
100
-                    esc_html__(
101
-                        'Flag indicating whether template group is active',
102
-                        'event_espresso'
103
-                    ),
104
-                    false,
105
-                    true
106
-                ),
107
-            ],
108
-        ];
109
-        $this->_model_relations = [
110
-            'Message_Template' => new EE_Has_Many_Relation(),
111
-            'Message'          => new EE_Has_Many_Relation(),
112
-            'Event'            => new EE_HABTM_Relation('Event_Message_Template'),
113
-            'WP_User'          => new EE_Belongs_To_Relation(),
114
-        ];
115
-        foreach ($this->_cap_contexts_to_cap_action_map as $context => $action) {
116
-            $this->_cap_restriction_generators[ $context ] = new EE_Restriction_Generator_Global('MTP_is_global');
117
-        }
118
-        $this->_caps_slug = 'messages';
119
-
120
-        parent::__construct($timezone);
121
-    }
122
-
123
-
124
-    /**
125
-     * get_all_trashed_message_templates_by_event
126
-     *
127
-     * @access public
128
-     * @param int    $EVT_ID specific event id
129
-     * @param string $orderby
130
-     * @param string $order
131
-     * @param null   $limit
132
-     * @param bool   $count
133
-     * @return array message template objects that are attached to a specific event.
134
-     */
135
-    public function get_all_trashed_message_templates_by_event(
136
-        $EVT_ID,
137
-        $orderby = 'GRP_ID',
138
-        $order = 'ASC',
139
-        $limit = null,
140
-        $count = false
141
-    ) {
142
-        $query_params = [['Event.EVT_ID' => $EVT_ID], 'order_by' => [$orderby => $order], 'limit' => $limit];
143
-        return $count ? $this->count_deleted($query_params, 'GRP_ID', true) : $this->get_all_deleted($query_params);
144
-    }
145
-
146
-
147
-    /**
148
-     * get_all_message_templates_by_messenger
149
-     *
150
-     * @access public
151
-     * @param        $messenger
152
-     * @param string $orderby
153
-     * @param string $order
154
-     * @return array all (including trashed or inactive) message template group objects for the given messenger
155
-     */
156
-    public function get_all_message_templates_by_messenger($messenger, $orderby = 'GRP_ID', $order = 'ASC')
157
-    {
158
-        return $this->get_all_deleted_and_undeleted(
159
-            [['MTP_messenger' => $messenger], 'order_by' => [$orderby => $order]]
160
-        );
161
-    }
162
-
163
-
164
-    /**
165
-     * This simply adds on any messenger/message type filters that may be present in the request
166
-     *
167
-     * @param array $_where any existing where conditions to append these to.
168
-     * @return array          original where conditions or original with additional filters.
169
-     */
170
-    protected function _maybe_mtp_filters($_where = [])
171
-    {
172
-        /** @var RequestInterface $request */
173
-        $request   = LoaderFactory::getLoader()->getShared(RequestInterface::class);
174
-        $messenger = $request->getRequestParam('ee_messenger_filter_by');
175
-        // account for messenger or message type filters
176
-        if ($messenger !== '' && $messenger !== 'none_selected' && $messenger !== 'all') {
177
-            $_where['MTP_messenger'] = $messenger;
178
-        }
179
-        $message_type = $request->getRequestParam('ee_message_type_filter_by');
180
-        if (
181
-            $message_type !== '' && $message_type !== 'none_selected'
182
-        ) {
183
-            $_where['MTP_message_type'] = $message_type;
184
-        }
185
-
186
-        return $_where;
187
-    }
188
-
189
-
190
-    /**
191
-     * get_all_active_message_templates groups
192
-     *
193
-     * @access public
194
-     * @param string $orderby
195
-     * @param string $order
196
-     * @param null   $limit
197
-     * @param bool   $count
198
-     * @param bool   $global
199
-     * @param bool   $user_check
200
-     * @return array|int all active (non_trashed, active) message template objects
201
-     */
202
-    public function get_all_active_message_templates(
203
-        $orderby = 'GRP_ID',
204
-        $order = 'ASC',
205
-        $limit = null,
206
-        $count = false,
207
-        $global = true,
208
-        $user_check = false
209
-    ) {
210
-        $_where                  = $global ? ['MTP_is_global' => true] : ['MTP_is_global' => false];
211
-        $_where['MTP_is_active'] = true;
212
-        $_where                  = $this->_maybe_mtp_filters($_where);
213
-
214
-        if (
215
-            $user_check
216
-            && ! $global
217
-            && ! EE_Registry::instance()->CAP->current_user_can(
218
-                'ee_read_others_messages',
219
-                'get_all_active_message_templates'
220
-            )
221
-        ) {
222
-            $_where['MTP_user_id'] = get_current_user_id();
223
-        }
224
-
225
-        $query_params = [$_where, 'order_by' => [$orderby => $order], 'limit' => $limit];
226
-
227
-        return $count ? $this->count($query_params, 'GRP_ID', true) : $this->get_all($query_params);
228
-    }
229
-
230
-
231
-    /**
232
-     *    retrieve ALL message_template groups from db regardless of wht
233
-     *
234
-     * @access    public
235
-     * @param string $orderby
236
-     * @param string $order
237
-     * @param null   $limit
238
-     * @param bool   $count
239
-     * @return mixed array on success, FALSE on fail
240
-     */
241
-    public function get_all_message_templates($orderby = 'GRP_ID', $order = 'ASC', $limit = null, $count = false)
242
-    {
243
-        $_where = $this->_maybe_mtp_filters();
244
-
245
-        $query_params = [$_where, 'order_by' => [$orderby => $order], 'limit' => $limit];
246
-
247
-        $r_templates = $count
248
-            ? $this->count_deleted_and_undeleted($query_params, 'GRP_ID', true)
249
-            : $this->get_all_deleted_and_undeleted($query_params);
250
-
251
-        return $r_templates;
252
-    }
253
-
254
-
255
-    /**
256
-     * This gets all the custom templates attached to a specific event
257
-     *
258
-     * @param int   $EVT_ID       event id
259
-     * @param array $query_params @see
260
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
261
-     * @return  EE_Message_Template_Group[]
262
-     */
263
-    public function get_all_custom_templates_by_event($EVT_ID, $query_params = [])
264
-    {
265
-        $where = array_merge($query_params, ['Event.EVT_ID' => $EVT_ID]);
266
-        return $this->get_all(
267
-            [$where]
268
-        );
269
-    }
270
-
271
-
272
-    /**
273
-     * get_all_trashed_grouped_message_templates
274
-     * this returns ONLY the template groups where ALL contexts are trashed and none of the group are non-trashed
275
-     *
276
-     * @access public
277
-     * @param string $orderby
278
-     * @param string $order
279
-     * @param null   $limit
280
-     * @param bool   $count
281
-     * @param bool   $global
282
-     * @return array|int EE_Message_Template_Group[] message template groups.
283
-     */
284
-    public function get_all_trashed_grouped_message_templates(
285
-        $orderby = 'GRP_ID',
286
-        $order = 'ASC',
287
-        $limit = null,
288
-        $count = false,
289
-        $global = true
290
-    ) {
291
-        $_where                  = $global ? ['MTP_is_global' => true] : ['MTP_is_global' => false];
292
-        $_where['MTP_is_active'] = true;
293
-        $_where                  = $this->_maybe_mtp_filters($_where);
294
-
295
-        $query_params = [$_where, 'order_by' => [$orderby => $order], 'limit' => $limit];
296
-
297
-        return $count ? $this->count_deleted($query_params, 'GRP_ID', true) : $this->get_all_deleted($query_params);
298
-    }
299
-
300
-
301
-    /**
302
-     * this returns the message template group(s) for a given event, messenger, and message template
303
-     *
304
-     * @param string              $messenger
305
-     * @param string              $message_type
306
-     * @param                     $evt_id
307
-     * @param string              $orderby pointless at this point but still included
308
-     * @param string              $order
309
-     * @param mixed (array|null) $limit   array($offset, $num)
310
-     * @param bool                $count   true = just return count, false = objects
311
-     * @param bool                $active  ignore "active" or not. (default only return active)
312
-     * @return \mixed[]) depending on $count.
313
-     */
314
-    public function get_event_message_templates_by_m_and_mt_and_evt(
315
-        $messenger,
316
-        $message_type,
317
-        $evt_id,
318
-        $orderby = 'GRP_ID',
319
-        $order = 'ASC',
320
-        $limit = null,
321
-        $count = false,
322
-        $active = true
323
-    ) {
324
-        $_where = [
325
-            'MTP_messenger'    => $messenger,
326
-            'MTP_message_type' => $message_type,
327
-            'Event.EVT_ID'     => $evt_id,
328
-            'MTP_is_global'    => true,
329
-            'MTP_is_active'    => $active,
330
-        ];
331
-
332
-        $query_params = [$_where, 'order_by' => [$orderby => $order], 'limit' => $limit];
333
-
334
-        return $count ? $this->count($query_params, 'GRP_ID', true) : $this->get_all($query_params);
335
-    }
336
-
337
-
338
-    /**
339
-     * get all GLOBAL message template groups for the given messenger and message type
340
-     *
341
-     * @param string $messenger     slug for messenger
342
-     * @param string $message_type  slug for message type
343
-     * @param string $orderby       what column to orderby
344
-     * @param string $order         ASC or DESC
345
-     * @param mixed (array|null) $limit array($offset, $num)
346
-     * @param bool   $count         true = just return count, false = objects
347
-     * @param bool   $active        ignore "active" or not. (default only return active) -
348
-     *                              'all' means return both inactive AND inactive.
349
-     * @return array               message template objects that are global (i.e. non-event)
350
-     */
351
-    public function get_global_message_template_by_m_and_mt(
352
-        $messenger,
353
-        $message_type,
354
-        $orderby = 'GRP_ID',
355
-        $order = 'ASC',
356
-        $limit = null,
357
-        $count = false,
358
-        $active = true
359
-    ) {
360
-        $_where = [
361
-            'MTP_messenger'    => $messenger,
362
-            'MTP_message_type' => $message_type,
363
-            'MTP_is_global'    => true,
364
-        ];
365
-
366
-        if ($active != 'all') {
367
-            $_where['MTP_is_active'] = $active;
368
-        }
369
-
370
-        $query_params = [$_where, 'order_by' => [$orderby => $order], 'limit' => $limit];
371
-
372
-        return $count ? $this->count($query_params, 'GRP_ID', true) : $this->get_all($query_params);
373
-    }
374
-
375
-
376
-    /**
377
-     * get all custom message template groups for the given messenger and message type
378
-     *
379
-     * @param string $messenger    messenger
380
-     * @param string $message_type messagetype
381
-     * @param array  $query_params same as EEM_Base->get_all()
382
-     * @return EE_Message_Template_Group[]
383
-     */
384
-    public function get_custom_message_template_by_m_and_mt($messenger, $message_type, $query_params = [])
385
-    {
386
-        return $this->get_all(
387
-            array_merge(
388
-                $query_params,
389
-                [
390
-                    [
391
-                        'MTP_is_global'    => false,
392
-                        'MTP_messenger'    => $messenger,
393
-                        'MTP_message_type' => $message_type,
394
-                    ],
395
-                ]
396
-            )
397
-        );
398
-    }
399
-
400
-
401
-    /**
402
-     * This sends things to the validator for the given messenger and message type.
403
-     *
404
-     * @param array  $fields       the incoming fields to check.
405
-     *                             Note this array is in the formatted fields from the form fields setup.
406
-     *                             So we need to reformat this into an array of expected field refs by the validator.
407
-     *                             Note also that this is not only the fields for the Message Template Group
408
-     *                             but ALSO for Message Template.
409
-     * @param string $context      The context the fields were obtained from.
410
-     * @param string $messenger    The messenger we are validating
411
-     * @param string $message_type The message type we are validating.
412
-     * @return bool
413
-     * @throws DomainException
414
-     */
415
-    public function validate(array $fields, string $context, string $messenger, string $message_type): bool
416
-    {
417
-        /** @var MessageTemplateValidator $validator */
418
-        $validator = LoaderFactory::getShared(MessageTemplateValidator::class);
419
-        return $validator->validateTemplateFields($messenger, $message_type, $context, $fields);
420
-    }
421
-
422
-
423
-    /**
424
-     * Updates all message template groups matching the incoming arguments to inactive status.
425
-     *
426
-     * @param array $messenger_names    The messenger slugs.
427
-     *                                  If empty then all templates matching the message types are marked inactive.
428
-     *                                  Otherwise only templates matching the messengers and message types.
429
-     * @param array $message_type_names The message type slugs.
430
-     *                                  If empty then all templates matching the messengers are marked inactive.
431
-     *                                  Otherwise only templates matching the messengers and message types.
432
-     * @return int  count of updated records.
433
-     */
434
-    public function deactivate_message_template_groups_for($messenger_names = [], $message_type_names = [])
435
-    {
436
-        $query_args = [];
437
-        if (empty($messenger_names) && empty($message_type_names)) {
438
-            return 0;
439
-        }
440
-        if (! empty($messenger_names)) {
441
-            $query_args[0]['MTP_messenger'] = ['IN', (array) $messenger_names];
442
-        }
443
-        if (! empty($message_type_names)) {
444
-            $query_args[0]['MTP_message_type'] = ['IN', (array) $message_type_names];
445
-        }
446
-        return $this->update(['MTP_is_active' => false], $query_args);
447
-    }
16
+	protected static ?EEM_Message_Template_Group $_instance = null;
17
+
18
+
19
+	/**
20
+	 * @param string|null $timezone
21
+	 * @throws EE_Error
22
+	 */
23
+	protected function __construct(?string $timezone = '')
24
+	{
25
+		$this->singular_item    = esc_html__('Message Template Group', 'event_espresso');
26
+		$this->plural_item      = esc_html__('Message Template Groups', 'event_espresso');
27
+		$this->_tables          = [
28
+			'Message_Template_Group' => new EE_Primary_Table('esp_message_template_group', 'GRP_ID'),
29
+		];
30
+		$this->_fields          = [
31
+			'Message_Template_Group' => [
32
+				'GRP_ID'           => new EE_Primary_Key_Int_Field(
33
+					'GRP_ID',
34
+					esc_html__('Message Template Group ID', 'event_espresso')
35
+				),
36
+				'MTP_name'         => new EE_Plain_Text_Field(
37
+					'MTP_name',
38
+					esc_html__('The name of the template group', 'event_espresso'),
39
+					false,
40
+					''
41
+				),
42
+				'MTP_description'  => new EE_Simple_HTML_Field(
43
+					'MTP_description',
44
+					esc_html__(
45
+						'A brief description about this template.',
46
+						'event_espresso'
47
+					),
48
+					false,
49
+					''
50
+				),
51
+				'MTP_user_id'      => new EE_WP_User_Field(
52
+					'MTP_user_id',
53
+					esc_html__('Template Creator ID', 'event_espresso'),
54
+					false
55
+				),
56
+				'MTP_messenger'    => new EE_Plain_Text_Field(
57
+					'MTP_messenger',
58
+					esc_html__(
59
+						'Messenger Used for Template',
60
+						'event_espresso'
61
+					),
62
+					false,
63
+					'email'
64
+				),
65
+				'MTP_message_type' => new EE_Plain_Text_Field(
66
+					'MTP_message_type',
67
+					esc_html__('Message Type', 'event_espresso'),
68
+					false,
69
+					'registration'
70
+				),
71
+				'MTP_is_global'    => new EE_Boolean_Field(
72
+					'MTP_is_global',
73
+					esc_html__(
74
+						'Flag indicating if Template Group is Global',
75
+						'event_espresso'
76
+					),
77
+					false,
78
+					true
79
+				),
80
+				'MTP_is_override'  => new EE_Boolean_Field(
81
+					'MTP_is_override',
82
+					esc_html__(
83
+						'Flag indicating if Template Group overrides any other Templates for the messenger/messagetype combination',
84
+						'event_espresso'
85
+					),
86
+					false,
87
+					false
88
+				),
89
+				'MTP_deleted'      => new EE_Trashed_Flag_Field(
90
+					'MTP_deleted',
91
+					esc_html__(
92
+						'Flag indicating whether this has been trashed',
93
+						'event_espresso'
94
+					),
95
+					false,
96
+					false
97
+				),
98
+				'MTP_is_active'    => new EE_Boolean_Field(
99
+					'MTP_is_active',
100
+					esc_html__(
101
+						'Flag indicating whether template group is active',
102
+						'event_espresso'
103
+					),
104
+					false,
105
+					true
106
+				),
107
+			],
108
+		];
109
+		$this->_model_relations = [
110
+			'Message_Template' => new EE_Has_Many_Relation(),
111
+			'Message'          => new EE_Has_Many_Relation(),
112
+			'Event'            => new EE_HABTM_Relation('Event_Message_Template'),
113
+			'WP_User'          => new EE_Belongs_To_Relation(),
114
+		];
115
+		foreach ($this->_cap_contexts_to_cap_action_map as $context => $action) {
116
+			$this->_cap_restriction_generators[ $context ] = new EE_Restriction_Generator_Global('MTP_is_global');
117
+		}
118
+		$this->_caps_slug = 'messages';
119
+
120
+		parent::__construct($timezone);
121
+	}
122
+
123
+
124
+	/**
125
+	 * get_all_trashed_message_templates_by_event
126
+	 *
127
+	 * @access public
128
+	 * @param int    $EVT_ID specific event id
129
+	 * @param string $orderby
130
+	 * @param string $order
131
+	 * @param null   $limit
132
+	 * @param bool   $count
133
+	 * @return array message template objects that are attached to a specific event.
134
+	 */
135
+	public function get_all_trashed_message_templates_by_event(
136
+		$EVT_ID,
137
+		$orderby = 'GRP_ID',
138
+		$order = 'ASC',
139
+		$limit = null,
140
+		$count = false
141
+	) {
142
+		$query_params = [['Event.EVT_ID' => $EVT_ID], 'order_by' => [$orderby => $order], 'limit' => $limit];
143
+		return $count ? $this->count_deleted($query_params, 'GRP_ID', true) : $this->get_all_deleted($query_params);
144
+	}
145
+
146
+
147
+	/**
148
+	 * get_all_message_templates_by_messenger
149
+	 *
150
+	 * @access public
151
+	 * @param        $messenger
152
+	 * @param string $orderby
153
+	 * @param string $order
154
+	 * @return array all (including trashed or inactive) message template group objects for the given messenger
155
+	 */
156
+	public function get_all_message_templates_by_messenger($messenger, $orderby = 'GRP_ID', $order = 'ASC')
157
+	{
158
+		return $this->get_all_deleted_and_undeleted(
159
+			[['MTP_messenger' => $messenger], 'order_by' => [$orderby => $order]]
160
+		);
161
+	}
162
+
163
+
164
+	/**
165
+	 * This simply adds on any messenger/message type filters that may be present in the request
166
+	 *
167
+	 * @param array $_where any existing where conditions to append these to.
168
+	 * @return array          original where conditions or original with additional filters.
169
+	 */
170
+	protected function _maybe_mtp_filters($_where = [])
171
+	{
172
+		/** @var RequestInterface $request */
173
+		$request   = LoaderFactory::getLoader()->getShared(RequestInterface::class);
174
+		$messenger = $request->getRequestParam('ee_messenger_filter_by');
175
+		// account for messenger or message type filters
176
+		if ($messenger !== '' && $messenger !== 'none_selected' && $messenger !== 'all') {
177
+			$_where['MTP_messenger'] = $messenger;
178
+		}
179
+		$message_type = $request->getRequestParam('ee_message_type_filter_by');
180
+		if (
181
+			$message_type !== '' && $message_type !== 'none_selected'
182
+		) {
183
+			$_where['MTP_message_type'] = $message_type;
184
+		}
185
+
186
+		return $_where;
187
+	}
188
+
189
+
190
+	/**
191
+	 * get_all_active_message_templates groups
192
+	 *
193
+	 * @access public
194
+	 * @param string $orderby
195
+	 * @param string $order
196
+	 * @param null   $limit
197
+	 * @param bool   $count
198
+	 * @param bool   $global
199
+	 * @param bool   $user_check
200
+	 * @return array|int all active (non_trashed, active) message template objects
201
+	 */
202
+	public function get_all_active_message_templates(
203
+		$orderby = 'GRP_ID',
204
+		$order = 'ASC',
205
+		$limit = null,
206
+		$count = false,
207
+		$global = true,
208
+		$user_check = false
209
+	) {
210
+		$_where                  = $global ? ['MTP_is_global' => true] : ['MTP_is_global' => false];
211
+		$_where['MTP_is_active'] = true;
212
+		$_where                  = $this->_maybe_mtp_filters($_where);
213
+
214
+		if (
215
+			$user_check
216
+			&& ! $global
217
+			&& ! EE_Registry::instance()->CAP->current_user_can(
218
+				'ee_read_others_messages',
219
+				'get_all_active_message_templates'
220
+			)
221
+		) {
222
+			$_where['MTP_user_id'] = get_current_user_id();
223
+		}
224
+
225
+		$query_params = [$_where, 'order_by' => [$orderby => $order], 'limit' => $limit];
226
+
227
+		return $count ? $this->count($query_params, 'GRP_ID', true) : $this->get_all($query_params);
228
+	}
229
+
230
+
231
+	/**
232
+	 *    retrieve ALL message_template groups from db regardless of wht
233
+	 *
234
+	 * @access    public
235
+	 * @param string $orderby
236
+	 * @param string $order
237
+	 * @param null   $limit
238
+	 * @param bool   $count
239
+	 * @return mixed array on success, FALSE on fail
240
+	 */
241
+	public function get_all_message_templates($orderby = 'GRP_ID', $order = 'ASC', $limit = null, $count = false)
242
+	{
243
+		$_where = $this->_maybe_mtp_filters();
244
+
245
+		$query_params = [$_where, 'order_by' => [$orderby => $order], 'limit' => $limit];
246
+
247
+		$r_templates = $count
248
+			? $this->count_deleted_and_undeleted($query_params, 'GRP_ID', true)
249
+			: $this->get_all_deleted_and_undeleted($query_params);
250
+
251
+		return $r_templates;
252
+	}
253
+
254
+
255
+	/**
256
+	 * This gets all the custom templates attached to a specific event
257
+	 *
258
+	 * @param int   $EVT_ID       event id
259
+	 * @param array $query_params @see
260
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
261
+	 * @return  EE_Message_Template_Group[]
262
+	 */
263
+	public function get_all_custom_templates_by_event($EVT_ID, $query_params = [])
264
+	{
265
+		$where = array_merge($query_params, ['Event.EVT_ID' => $EVT_ID]);
266
+		return $this->get_all(
267
+			[$where]
268
+		);
269
+	}
270
+
271
+
272
+	/**
273
+	 * get_all_trashed_grouped_message_templates
274
+	 * this returns ONLY the template groups where ALL contexts are trashed and none of the group are non-trashed
275
+	 *
276
+	 * @access public
277
+	 * @param string $orderby
278
+	 * @param string $order
279
+	 * @param null   $limit
280
+	 * @param bool   $count
281
+	 * @param bool   $global
282
+	 * @return array|int EE_Message_Template_Group[] message template groups.
283
+	 */
284
+	public function get_all_trashed_grouped_message_templates(
285
+		$orderby = 'GRP_ID',
286
+		$order = 'ASC',
287
+		$limit = null,
288
+		$count = false,
289
+		$global = true
290
+	) {
291
+		$_where                  = $global ? ['MTP_is_global' => true] : ['MTP_is_global' => false];
292
+		$_where['MTP_is_active'] = true;
293
+		$_where                  = $this->_maybe_mtp_filters($_where);
294
+
295
+		$query_params = [$_where, 'order_by' => [$orderby => $order], 'limit' => $limit];
296
+
297
+		return $count ? $this->count_deleted($query_params, 'GRP_ID', true) : $this->get_all_deleted($query_params);
298
+	}
299
+
300
+
301
+	/**
302
+	 * this returns the message template group(s) for a given event, messenger, and message template
303
+	 *
304
+	 * @param string              $messenger
305
+	 * @param string              $message_type
306
+	 * @param                     $evt_id
307
+	 * @param string              $orderby pointless at this point but still included
308
+	 * @param string              $order
309
+	 * @param mixed (array|null) $limit   array($offset, $num)
310
+	 * @param bool                $count   true = just return count, false = objects
311
+	 * @param bool                $active  ignore "active" or not. (default only return active)
312
+	 * @return \mixed[]) depending on $count.
313
+	 */
314
+	public function get_event_message_templates_by_m_and_mt_and_evt(
315
+		$messenger,
316
+		$message_type,
317
+		$evt_id,
318
+		$orderby = 'GRP_ID',
319
+		$order = 'ASC',
320
+		$limit = null,
321
+		$count = false,
322
+		$active = true
323
+	) {
324
+		$_where = [
325
+			'MTP_messenger'    => $messenger,
326
+			'MTP_message_type' => $message_type,
327
+			'Event.EVT_ID'     => $evt_id,
328
+			'MTP_is_global'    => true,
329
+			'MTP_is_active'    => $active,
330
+		];
331
+
332
+		$query_params = [$_where, 'order_by' => [$orderby => $order], 'limit' => $limit];
333
+
334
+		return $count ? $this->count($query_params, 'GRP_ID', true) : $this->get_all($query_params);
335
+	}
336
+
337
+
338
+	/**
339
+	 * get all GLOBAL message template groups for the given messenger and message type
340
+	 *
341
+	 * @param string $messenger     slug for messenger
342
+	 * @param string $message_type  slug for message type
343
+	 * @param string $orderby       what column to orderby
344
+	 * @param string $order         ASC or DESC
345
+	 * @param mixed (array|null) $limit array($offset, $num)
346
+	 * @param bool   $count         true = just return count, false = objects
347
+	 * @param bool   $active        ignore "active" or not. (default only return active) -
348
+	 *                              'all' means return both inactive AND inactive.
349
+	 * @return array               message template objects that are global (i.e. non-event)
350
+	 */
351
+	public function get_global_message_template_by_m_and_mt(
352
+		$messenger,
353
+		$message_type,
354
+		$orderby = 'GRP_ID',
355
+		$order = 'ASC',
356
+		$limit = null,
357
+		$count = false,
358
+		$active = true
359
+	) {
360
+		$_where = [
361
+			'MTP_messenger'    => $messenger,
362
+			'MTP_message_type' => $message_type,
363
+			'MTP_is_global'    => true,
364
+		];
365
+
366
+		if ($active != 'all') {
367
+			$_where['MTP_is_active'] = $active;
368
+		}
369
+
370
+		$query_params = [$_where, 'order_by' => [$orderby => $order], 'limit' => $limit];
371
+
372
+		return $count ? $this->count($query_params, 'GRP_ID', true) : $this->get_all($query_params);
373
+	}
374
+
375
+
376
+	/**
377
+	 * get all custom message template groups for the given messenger and message type
378
+	 *
379
+	 * @param string $messenger    messenger
380
+	 * @param string $message_type messagetype
381
+	 * @param array  $query_params same as EEM_Base->get_all()
382
+	 * @return EE_Message_Template_Group[]
383
+	 */
384
+	public function get_custom_message_template_by_m_and_mt($messenger, $message_type, $query_params = [])
385
+	{
386
+		return $this->get_all(
387
+			array_merge(
388
+				$query_params,
389
+				[
390
+					[
391
+						'MTP_is_global'    => false,
392
+						'MTP_messenger'    => $messenger,
393
+						'MTP_message_type' => $message_type,
394
+					],
395
+				]
396
+			)
397
+		);
398
+	}
399
+
400
+
401
+	/**
402
+	 * This sends things to the validator for the given messenger and message type.
403
+	 *
404
+	 * @param array  $fields       the incoming fields to check.
405
+	 *                             Note this array is in the formatted fields from the form fields setup.
406
+	 *                             So we need to reformat this into an array of expected field refs by the validator.
407
+	 *                             Note also that this is not only the fields for the Message Template Group
408
+	 *                             but ALSO for Message Template.
409
+	 * @param string $context      The context the fields were obtained from.
410
+	 * @param string $messenger    The messenger we are validating
411
+	 * @param string $message_type The message type we are validating.
412
+	 * @return bool
413
+	 * @throws DomainException
414
+	 */
415
+	public function validate(array $fields, string $context, string $messenger, string $message_type): bool
416
+	{
417
+		/** @var MessageTemplateValidator $validator */
418
+		$validator = LoaderFactory::getShared(MessageTemplateValidator::class);
419
+		return $validator->validateTemplateFields($messenger, $message_type, $context, $fields);
420
+	}
421
+
422
+
423
+	/**
424
+	 * Updates all message template groups matching the incoming arguments to inactive status.
425
+	 *
426
+	 * @param array $messenger_names    The messenger slugs.
427
+	 *                                  If empty then all templates matching the message types are marked inactive.
428
+	 *                                  Otherwise only templates matching the messengers and message types.
429
+	 * @param array $message_type_names The message type slugs.
430
+	 *                                  If empty then all templates matching the messengers are marked inactive.
431
+	 *                                  Otherwise only templates matching the messengers and message types.
432
+	 * @return int  count of updated records.
433
+	 */
434
+	public function deactivate_message_template_groups_for($messenger_names = [], $message_type_names = [])
435
+	{
436
+		$query_args = [];
437
+		if (empty($messenger_names) && empty($message_type_names)) {
438
+			return 0;
439
+		}
440
+		if (! empty($messenger_names)) {
441
+			$query_args[0]['MTP_messenger'] = ['IN', (array) $messenger_names];
442
+		}
443
+		if (! empty($message_type_names)) {
444
+			$query_args[0]['MTP_message_type'] = ['IN', (array) $message_type_names];
445
+		}
446
+		return $this->update(['MTP_is_active' => false], $query_args);
447
+	}
448 448
 }
Please login to merge, or discard this patch.
core/db_models/EEM_Form_Section.model.php 1 patch
Indentation   +231 added lines, -231 removed lines patch added patch discarded remove patch
@@ -20,235 +20,235 @@
 block discarded – undo
20 20
  */
21 21
 class EEM_Form_Section extends EEM_Base
22 22
 {
23
-    public const APPLIES_TO_ALL         = 'all';
24
-
25
-    public const APPLIES_TO_PRIMARY     = 'primary';
26
-
27
-    public const APPLIES_TO_PURCHASER   = 'purchaser';
28
-
29
-    public const APPLIES_TO_REGISTRANTS = 'registrants';
30
-
31
-    protected static ?EEM_Form_Section $_instance = null;
32
-
33
-    private RequestInterface $request;
34
-
35
-    private array $valid_applies_to_options;
36
-
37
-
38
-    /**
39
-     * EEM_Form_Section constructor.
40
-     *
41
-     * @param FormStatus  $form_status
42
-     * @param string|null $timezone
43
-     * @throws EE_Error
44
-     */
45
-    protected function __construct(FormStatus $form_status, ?string $timezone = '')
46
-    {
47
-        $this->valid_applies_to_options = apply_filters(
48
-            'FHEE__EEM_Form_Section__valid_applies_to_options',
49
-            [
50
-                EEM_Form_Section::APPLIES_TO_ALL         => esc_html__('All Registrants', 'event_espresso'),
51
-                EEM_Form_Section::APPLIES_TO_PRIMARY     => esc_html__('Primary Registrant Only', 'event_espresso'),
52
-                EEM_Form_Section::APPLIES_TO_PURCHASER   => esc_html__('Purchasing Agent', 'event_espresso'),
53
-                EEM_Form_Section::APPLIES_TO_REGISTRANTS => esc_html__('Additional Registrants', 'event_espresso'),
54
-            ]
55
-        );
56
-
57
-        $this->singular_item = esc_html__('Form Section', 'event_espresso');
58
-        $this->plural_item   = esc_html__('Form Sections', 'event_espresso');
59
-
60
-        $this->_tables          = [
61
-            'Form_Section' => new EE_Primary_Table('esp_form_section', 'FSC_UUID'),
62
-        ];
63
-        $this->_fields          = [
64
-            'Form_Section' => [
65
-                'FSC_UUID'       => new EE_Primary_Key_String_Field(
66
-                    'FSC_UUID',
67
-                    esc_html__('Form Section UUID (universally unique identifier)', 'event_espresso')
68
-                ),
69
-                'FSC_appliesTo'  => new EE_Enum_Text_Field(
70
-                    'FSC_appliesTo',
71
-                    esc_html(
72
-                        sprintf(
73
-                        /* translators: 1 class name */
74
-                            __(
75
-                                'Form user type that this form section should be presented to. Values correspond to the %s constants.',
76
-                                'event_espresso'
77
-                            ),
78
-                            'EEM_Form_Section::APPLIES_TO_*'
79
-                        )
80
-                    ),
81
-                    false,
82
-                    EEM_Form_Section::APPLIES_TO_ALL,
83
-                    $this->valid_applies_to_options
84
-                ),
85
-                'FSC_attributes' => new EE_JSON_Field(
86
-                    'FSC_attributes',
87
-                    esc_html__(
88
-                        'JSON string of HTML attributes, such as class, to be applied to this form section\'s container.',
89
-                        'event_espresso'
90
-                    ),
91
-                    false,
92
-                    '{}'
93
-                ),
94
-                'FSC_belongsTo'  => new EE_Plain_Text_Field(
95
-                    'FSC_belongsTo',
96
-                    esc_html__('UUID of parent form section that this one belongs to.', 'event_espresso'),
97
-                    false,
98
-                    ''
99
-                ),
100
-                'FSC_label'      => new EE_JSON_Field(
101
-                    'FSC_label',
102
-                    esc_html__(
103
-                        'JSON string of properties pertaining to a form section\'s label.',
104
-                        'event_espresso'
105
-                    ),
106
-                    false,
107
-                    '{}'
108
-                ),
109
-                'FSC_order'      => new EE_Integer_Field(
110
-                    'FSC_order',
111
-                    esc_html__('Order in which form section appears in a form.', 'event_espresso'),
112
-                    false,
113
-                    0
114
-                ),
115
-                'FSC_status'     => new EE_Enum_Text_Field(
116
-                    'FSC_status',
117
-                    esc_html(
118
-                        sprintf(
119
-                        /* translators: 1 class name */
120
-                            __(
121
-                                'Whether form section is active, archived, shared, trashed, or used as a default on new forms. Values correspond to the %1$s class constants.',
122
-                                'event_espresso'
123
-                            ),
124
-                            'EventEspresso\core\services\form\meta\FormStatus'
125
-                        )
126
-                    ),
127
-                    false,
128
-                    FormStatus::ACTIVE,
129
-                    $form_status->validStatusOptions()
130
-                ),
131
-                'FSC_wpUser'     => new EE_WP_User_Field(
132
-                    'FSC_wpUser',
133
-                    esc_html__('ID of the WP User that created this form section.', 'event_espresso'),
134
-                    false
135
-                ),
136
-            ],
137
-        ];
138
-        $this->_model_relations = [
139
-            'Form_Element'    => new EE_Has_Many_Relation(),
140
-            'Form_Submission' => new EE_Has_Many_Relation(),
141
-            'WP_User'         => new EE_Belongs_To_Relation(),
142
-        ];
143
-        // this model is generally available for reading
144
-        $restrictions                              = [];
145
-        $restrictions[ EEM_Base::caps_read ]       = new EE_Restriction_Generator_Public();
146
-        $restrictions[ EEM_Base::caps_read_admin ] = new EE_Restriction_Generator_Reg_Form('FSC_applies_to');
147
-        $restrictions[ EEM_Base::caps_edit ]       = new EE_Restriction_Generator_Reg_Form('FSC_applies_to');
148
-        $restrictions[ EEM_Base::caps_delete ]     = new EE_Restriction_Generator_Reg_Form('FSC_applies_to');
149
-        $this->_cap_restriction_generators         = $restrictions;
150
-        parent::__construct($timezone);
151
-        $this->request = $this->getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
152
-    }
153
-
154
-
155
-    /**
156
-     * @param array $query_params
157
-     * @return array
158
-     */
159
-    private function addDefaultWhereConditions(array $query_params): array
160
-    {
161
-        // might need to add a way to identify GQL requests for admin domains
162
-        $admin_request                            = $this->request->isAdmin() || $this->request->isAdminAjax();
163
-        $query_params['default_where_conditions'] = $admin_request
164
-            ? EEM_Base::default_where_conditions_none
165
-            : EEM_Base::default_where_conditions_all;
166
-        return $query_params;
167
-    }
168
-
169
-
170
-    /**
171
-     * form sections should always be sorted in ascending order via the FSC_order field
172
-     *
173
-     * @param array $query_params
174
-     * @return array
175
-     */
176
-    private function addOrderByQueryParams(array $query_params): array
177
-    {
178
-        $query_params['order_by'] = ['FSC_order' => 'ASC'];
179
-        return $query_params;
180
-    }
181
-
182
-
183
-    /**
184
-     * returns an array of Form Sections that should be added by default to new Events
185
-     *
186
-     * @return EE_Form_Section[]
187
-     * @throws EE_Error
188
-     */
189
-    public function getDefaultFormSections(): array
190
-    {
191
-        return $this->getFormSections(['FSC_status' => FormStatus::DEFAULT]);
192
-    }
193
-
194
-
195
-    /**
196
-     * returns an array of Form Sections for the specified parent Form Section
197
-     *
198
-     * @param string $FSC_UUID
199
-     * @return EE_Form_Section[]
200
-     * @throws EE_Error
201
-     */
202
-    public function getChildFormSections(string $FSC_UUID): array
203
-    {
204
-        return $this->getFormSections(['FSC_belongsTo' => $FSC_UUID]);
205
-    }
206
-
207
-
208
-    /**
209
-     * @return EE_Form_Section[]
210
-     * @throws EE_Error
211
-     */
212
-    public function getFormSections(array $where_params): array
213
-    {
214
-        $query_params = $this->addDefaultWhereConditions([$where_params]);
215
-        $query_params = $this->addOrderByQueryParams($query_params);
216
-        return $this->get_all($query_params);
217
-    }
218
-
219
-
220
-    /**
221
-     * returns an array of Form Sections for the specified Event
222
-     *
223
-     * @param EE_Event $event
224
-     * @return EE_Form_Section[]
225
-     * @throws EE_Error
226
-     * @throws ReflectionException
227
-     */
228
-    public function getFormSectionsForEvent(EE_Event $event): array
229
-    {
230
-        $FSC_UUID = $event->registrationFormUuid();
231
-        return ! empty($FSC_UUID)
232
-            ? $this->getFormSections(
233
-                [
234
-                    'OR' => [
235
-                        'FSC_UUID'      => $FSC_UUID, // top level form
236
-                        'FSC_belongsTo' => $FSC_UUID, // child form sections
237
-                    ],
238
-                ]
239
-            )
240
-            : [];
241
-    }
242
-
243
-
244
-    /**
245
-     * @param bool $constants_only
246
-     * @return array
247
-     */
248
-    public function validAppliesToOptions(bool $constants_only = false): array
249
-    {
250
-        return $constants_only
251
-            ? array_keys($this->valid_applies_to_options)
252
-            : $this->valid_applies_to_options;
253
-    }
23
+	public const APPLIES_TO_ALL         = 'all';
24
+
25
+	public const APPLIES_TO_PRIMARY     = 'primary';
26
+
27
+	public const APPLIES_TO_PURCHASER   = 'purchaser';
28
+
29
+	public const APPLIES_TO_REGISTRANTS = 'registrants';
30
+
31
+	protected static ?EEM_Form_Section $_instance = null;
32
+
33
+	private RequestInterface $request;
34
+
35
+	private array $valid_applies_to_options;
36
+
37
+
38
+	/**
39
+	 * EEM_Form_Section constructor.
40
+	 *
41
+	 * @param FormStatus  $form_status
42
+	 * @param string|null $timezone
43
+	 * @throws EE_Error
44
+	 */
45
+	protected function __construct(FormStatus $form_status, ?string $timezone = '')
46
+	{
47
+		$this->valid_applies_to_options = apply_filters(
48
+			'FHEE__EEM_Form_Section__valid_applies_to_options',
49
+			[
50
+				EEM_Form_Section::APPLIES_TO_ALL         => esc_html__('All Registrants', 'event_espresso'),
51
+				EEM_Form_Section::APPLIES_TO_PRIMARY     => esc_html__('Primary Registrant Only', 'event_espresso'),
52
+				EEM_Form_Section::APPLIES_TO_PURCHASER   => esc_html__('Purchasing Agent', 'event_espresso'),
53
+				EEM_Form_Section::APPLIES_TO_REGISTRANTS => esc_html__('Additional Registrants', 'event_espresso'),
54
+			]
55
+		);
56
+
57
+		$this->singular_item = esc_html__('Form Section', 'event_espresso');
58
+		$this->plural_item   = esc_html__('Form Sections', 'event_espresso');
59
+
60
+		$this->_tables          = [
61
+			'Form_Section' => new EE_Primary_Table('esp_form_section', 'FSC_UUID'),
62
+		];
63
+		$this->_fields          = [
64
+			'Form_Section' => [
65
+				'FSC_UUID'       => new EE_Primary_Key_String_Field(
66
+					'FSC_UUID',
67
+					esc_html__('Form Section UUID (universally unique identifier)', 'event_espresso')
68
+				),
69
+				'FSC_appliesTo'  => new EE_Enum_Text_Field(
70
+					'FSC_appliesTo',
71
+					esc_html(
72
+						sprintf(
73
+						/* translators: 1 class name */
74
+							__(
75
+								'Form user type that this form section should be presented to. Values correspond to the %s constants.',
76
+								'event_espresso'
77
+							),
78
+							'EEM_Form_Section::APPLIES_TO_*'
79
+						)
80
+					),
81
+					false,
82
+					EEM_Form_Section::APPLIES_TO_ALL,
83
+					$this->valid_applies_to_options
84
+				),
85
+				'FSC_attributes' => new EE_JSON_Field(
86
+					'FSC_attributes',
87
+					esc_html__(
88
+						'JSON string of HTML attributes, such as class, to be applied to this form section\'s container.',
89
+						'event_espresso'
90
+					),
91
+					false,
92
+					'{}'
93
+				),
94
+				'FSC_belongsTo'  => new EE_Plain_Text_Field(
95
+					'FSC_belongsTo',
96
+					esc_html__('UUID of parent form section that this one belongs to.', 'event_espresso'),
97
+					false,
98
+					''
99
+				),
100
+				'FSC_label'      => new EE_JSON_Field(
101
+					'FSC_label',
102
+					esc_html__(
103
+						'JSON string of properties pertaining to a form section\'s label.',
104
+						'event_espresso'
105
+					),
106
+					false,
107
+					'{}'
108
+				),
109
+				'FSC_order'      => new EE_Integer_Field(
110
+					'FSC_order',
111
+					esc_html__('Order in which form section appears in a form.', 'event_espresso'),
112
+					false,
113
+					0
114
+				),
115
+				'FSC_status'     => new EE_Enum_Text_Field(
116
+					'FSC_status',
117
+					esc_html(
118
+						sprintf(
119
+						/* translators: 1 class name */
120
+							__(
121
+								'Whether form section is active, archived, shared, trashed, or used as a default on new forms. Values correspond to the %1$s class constants.',
122
+								'event_espresso'
123
+							),
124
+							'EventEspresso\core\services\form\meta\FormStatus'
125
+						)
126
+					),
127
+					false,
128
+					FormStatus::ACTIVE,
129
+					$form_status->validStatusOptions()
130
+				),
131
+				'FSC_wpUser'     => new EE_WP_User_Field(
132
+					'FSC_wpUser',
133
+					esc_html__('ID of the WP User that created this form section.', 'event_espresso'),
134
+					false
135
+				),
136
+			],
137
+		];
138
+		$this->_model_relations = [
139
+			'Form_Element'    => new EE_Has_Many_Relation(),
140
+			'Form_Submission' => new EE_Has_Many_Relation(),
141
+			'WP_User'         => new EE_Belongs_To_Relation(),
142
+		];
143
+		// this model is generally available for reading
144
+		$restrictions                              = [];
145
+		$restrictions[ EEM_Base::caps_read ]       = new EE_Restriction_Generator_Public();
146
+		$restrictions[ EEM_Base::caps_read_admin ] = new EE_Restriction_Generator_Reg_Form('FSC_applies_to');
147
+		$restrictions[ EEM_Base::caps_edit ]       = new EE_Restriction_Generator_Reg_Form('FSC_applies_to');
148
+		$restrictions[ EEM_Base::caps_delete ]     = new EE_Restriction_Generator_Reg_Form('FSC_applies_to');
149
+		$this->_cap_restriction_generators         = $restrictions;
150
+		parent::__construct($timezone);
151
+		$this->request = $this->getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
152
+	}
153
+
154
+
155
+	/**
156
+	 * @param array $query_params
157
+	 * @return array
158
+	 */
159
+	private function addDefaultWhereConditions(array $query_params): array
160
+	{
161
+		// might need to add a way to identify GQL requests for admin domains
162
+		$admin_request                            = $this->request->isAdmin() || $this->request->isAdminAjax();
163
+		$query_params['default_where_conditions'] = $admin_request
164
+			? EEM_Base::default_where_conditions_none
165
+			: EEM_Base::default_where_conditions_all;
166
+		return $query_params;
167
+	}
168
+
169
+
170
+	/**
171
+	 * form sections should always be sorted in ascending order via the FSC_order field
172
+	 *
173
+	 * @param array $query_params
174
+	 * @return array
175
+	 */
176
+	private function addOrderByQueryParams(array $query_params): array
177
+	{
178
+		$query_params['order_by'] = ['FSC_order' => 'ASC'];
179
+		return $query_params;
180
+	}
181
+
182
+
183
+	/**
184
+	 * returns an array of Form Sections that should be added by default to new Events
185
+	 *
186
+	 * @return EE_Form_Section[]
187
+	 * @throws EE_Error
188
+	 */
189
+	public function getDefaultFormSections(): array
190
+	{
191
+		return $this->getFormSections(['FSC_status' => FormStatus::DEFAULT]);
192
+	}
193
+
194
+
195
+	/**
196
+	 * returns an array of Form Sections for the specified parent Form Section
197
+	 *
198
+	 * @param string $FSC_UUID
199
+	 * @return EE_Form_Section[]
200
+	 * @throws EE_Error
201
+	 */
202
+	public function getChildFormSections(string $FSC_UUID): array
203
+	{
204
+		return $this->getFormSections(['FSC_belongsTo' => $FSC_UUID]);
205
+	}
206
+
207
+
208
+	/**
209
+	 * @return EE_Form_Section[]
210
+	 * @throws EE_Error
211
+	 */
212
+	public function getFormSections(array $where_params): array
213
+	{
214
+		$query_params = $this->addDefaultWhereConditions([$where_params]);
215
+		$query_params = $this->addOrderByQueryParams($query_params);
216
+		return $this->get_all($query_params);
217
+	}
218
+
219
+
220
+	/**
221
+	 * returns an array of Form Sections for the specified Event
222
+	 *
223
+	 * @param EE_Event $event
224
+	 * @return EE_Form_Section[]
225
+	 * @throws EE_Error
226
+	 * @throws ReflectionException
227
+	 */
228
+	public function getFormSectionsForEvent(EE_Event $event): array
229
+	{
230
+		$FSC_UUID = $event->registrationFormUuid();
231
+		return ! empty($FSC_UUID)
232
+			? $this->getFormSections(
233
+				[
234
+					'OR' => [
235
+						'FSC_UUID'      => $FSC_UUID, // top level form
236
+						'FSC_belongsTo' => $FSC_UUID, // child form sections
237
+					],
238
+				]
239
+			)
240
+			: [];
241
+	}
242
+
243
+
244
+	/**
245
+	 * @param bool $constants_only
246
+	 * @return array
247
+	 */
248
+	public function validAppliesToOptions(bool $constants_only = false): array
249
+	{
250
+		return $constants_only
251
+			? array_keys($this->valid_applies_to_options)
252
+			: $this->valid_applies_to_options;
253
+	}
254 254
 }
Please login to merge, or discard this patch.
core/db_models/EEM_Datetime_Ticket.model.php 1 patch
Indentation   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -10,58 +10,58 @@
 block discarded – undo
10 10
  */
11 11
 class EEM_Datetime_Ticket extends EEM_Base
12 12
 {
13
-    protected static ?EEM_Datetime_Ticket $_instance = null;
13
+	protected static ?EEM_Datetime_Ticket $_instance = null;
14 14
 
15 15
 
16
-    /**
17
-     * @param string|null $timezone string representing the timezone we want to set for returned Date Time Strings (and
18
-     *                              any incoming timezone data that gets saved).  Note this just sends the timezone
19
-     *                              info to the date time model field objects.  Default is NULL (and will be assumed
20
-     *                              using the set timezone in the 'timezone_string' wp option)
21
-     * @throws EE_Error
22
-     */
23
-    protected function __construct(?string $timezone = '')
24
-    {
25
-        $this->singular_item = esc_html__('Datetime Ticket', 'event_espresso');
26
-        $this->plural_item   = esc_html__('Datetime Tickets', 'event_espresso');
16
+	/**
17
+	 * @param string|null $timezone string representing the timezone we want to set for returned Date Time Strings (and
18
+	 *                              any incoming timezone data that gets saved).  Note this just sends the timezone
19
+	 *                              info to the date time model field objects.  Default is NULL (and will be assumed
20
+	 *                              using the set timezone in the 'timezone_string' wp option)
21
+	 * @throws EE_Error
22
+	 */
23
+	protected function __construct(?string $timezone = '')
24
+	{
25
+		$this->singular_item = esc_html__('Datetime Ticket', 'event_espresso');
26
+		$this->plural_item   = esc_html__('Datetime Tickets', 'event_espresso');
27 27
 
28
-        $this->_tables          = [
29
-            'Datetime_Ticket' => new EE_Primary_Table('esp_datetime_ticket', 'DTK_ID'),
30
-        ];
31
-        $this->_fields          = [
32
-            'Datetime_Ticket' => [
33
-                'DTK_ID' => new EE_Primary_Key_Int_Field('DTK_ID', esc_html__('Datetime Ticket ID', 'event_espresso')),
34
-                'DTT_ID' => new EE_Foreign_Key_Int_Field(
35
-                    'DTT_ID',
36
-                    esc_html__('The ID to the Datetime', 'event_espresso'),
37
-                    false,
38
-                    0,
39
-                    'Datetime'
40
-                ),
41
-                'TKT_ID' => new EE_Foreign_Key_Int_Field(
42
-                    'TKT_ID',
43
-                    esc_html__('The ID to the Ticket', 'event_espresso'),
44
-                    false,
45
-                    0,
46
-                    'Ticket'
47
-                ),
48
-            ],
49
-        ];
50
-        $this->_model_relations = [
51
-            'Ticket'   => new EE_Belongs_To_Relation(),
52
-            'Datetime' => new EE_Belongs_To_Relation(),
53
-        ];
54
-        // this model is generally available for reading
55
-        $path_to_event                                                  = 'Datetime.Event';
56
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ]       =
57
-            new EE_Restriction_Generator_Event_Related_Public($path_to_event);
58
-        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] =
59
-            new EE_Restriction_Generator_Event_Related_Protected($path_to_event);
60
-        $this->_cap_restriction_generators[ EEM_Base::caps_edit ]       =
61
-            new EE_Restriction_Generator_Event_Related_Protected($path_to_event);
62
-        $this->_cap_restriction_generators[ EEM_Base::caps_delete ]     =
63
-            new EE_Restriction_Generator_Event_Related_Protected($path_to_event, EEM_Base::caps_edit);
64
-        $this->model_chain_to_password                                  = $path_to_event;
65
-        parent::__construct($timezone);
66
-    }
28
+		$this->_tables          = [
29
+			'Datetime_Ticket' => new EE_Primary_Table('esp_datetime_ticket', 'DTK_ID'),
30
+		];
31
+		$this->_fields          = [
32
+			'Datetime_Ticket' => [
33
+				'DTK_ID' => new EE_Primary_Key_Int_Field('DTK_ID', esc_html__('Datetime Ticket ID', 'event_espresso')),
34
+				'DTT_ID' => new EE_Foreign_Key_Int_Field(
35
+					'DTT_ID',
36
+					esc_html__('The ID to the Datetime', 'event_espresso'),
37
+					false,
38
+					0,
39
+					'Datetime'
40
+				),
41
+				'TKT_ID' => new EE_Foreign_Key_Int_Field(
42
+					'TKT_ID',
43
+					esc_html__('The ID to the Ticket', 'event_espresso'),
44
+					false,
45
+					0,
46
+					'Ticket'
47
+				),
48
+			],
49
+		];
50
+		$this->_model_relations = [
51
+			'Ticket'   => new EE_Belongs_To_Relation(),
52
+			'Datetime' => new EE_Belongs_To_Relation(),
53
+		];
54
+		// this model is generally available for reading
55
+		$path_to_event                                                  = 'Datetime.Event';
56
+		$this->_cap_restriction_generators[ EEM_Base::caps_read ]       =
57
+			new EE_Restriction_Generator_Event_Related_Public($path_to_event);
58
+		$this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] =
59
+			new EE_Restriction_Generator_Event_Related_Protected($path_to_event);
60
+		$this->_cap_restriction_generators[ EEM_Base::caps_edit ]       =
61
+			new EE_Restriction_Generator_Event_Related_Protected($path_to_event);
62
+		$this->_cap_restriction_generators[ EEM_Base::caps_delete ]     =
63
+			new EE_Restriction_Generator_Event_Related_Protected($path_to_event, EEM_Base::caps_edit);
64
+		$this->model_chain_to_password                                  = $path_to_event;
65
+		parent::__construct($timezone);
66
+	}
67 67
 }
Please login to merge, or discard this patch.
core/db_models/EEM_Ticket.model.php 1 patch
Indentation   +481 added lines, -481 removed lines patch added patch discarded remove patch
@@ -13,485 +13,485 @@
 block discarded – undo
13 13
  */
14 14
 class EEM_Ticket extends EEM_Soft_Delete_Base
15 15
 {
16
-    /**
17
-     * the following constants define where tickets can be viewed throughout the UI
18
-     *  TICKET_VISIBILITY_NONE          - will not be displayed anywhere
19
-     *  TICKET_VISIBILITY_PUBLIC        - basically displayed everywhere
20
-     *  TICKET_VISIBILITY_MEMBERS_ONLY  - displayed to any logged-in user
21
-     *  TICKET_VISIBILITY_ADMINS_ONLY   - displayed to any logged-in user that is an admin
22
-     *  TICKET_VISIBILITY_ADMIN_UI_ONLY - only displayed in the admin, never publicly
23
-     */
24
-    public const TICKET_VISIBILITY_NONE_KEY            = 'NONE';
25
-
26
-    public const TICKET_VISIBILITY_NONE_VALUE          = 0;
27
-
28
-    public const TICKET_VISIBILITY_PUBLIC_KEY          = 'PUBLIC';
29
-
30
-    public const TICKET_VISIBILITY_PUBLIC_VALUE        = 100;
31
-
32
-    public const TICKET_VISIBILITY_MEMBERS_ONLY_KEY    = 'MEMBERS_ONLY';
33
-
34
-    public const TICKET_VISIBILITY_MEMBERS_ONLY_VALUE  = 200;
35
-
36
-    public const TICKET_VISIBILITY_ADMINS_ONLY_KEY     = 'ADMINS_ONLY';
37
-
38
-    public const TICKET_VISIBILITY_ADMINS_ONLY_VALUE   = 300;
39
-
40
-    public const TICKET_VISIBILITY_ADMIN_UI_ONLY_KEY   = 'ADMIN_UI_ONLY';
41
-
42
-    public const TICKET_VISIBILITY_ADMIN_UI_ONLY_VALUE = 400;
43
-
44
-
45
-    /**
46
-     * defines where tickets can be viewed throughout the UI
47
-     *
48
-     * @var array
49
-     */
50
-    private $ticket_visibility;
51
-
52
-    protected static ?EEM_Ticket $_instance = null;
53
-
54
-
55
-    /**
56
-     * private constructor to prevent direct creation
57
-     *
58
-     * @param string|null $timezone string representing the timezone we want to set for returned Date Time Strings
59
-     *                              (and any incoming timezone data that gets saved).
60
-     *                              Note this just sends the timezone info to the date time model field objects.
61
-     *                              Default is NULL
62
-     *                              (and will be assumed using the set timezone in the 'timezone_string' wp option)
63
-     * @throws EE_Error
64
-     * @throws ReflectionException
65
-     */
66
-    protected function __construct(?string $timezone = '')
67
-    {
68
-        $this->singular_item = esc_html__('Ticket', 'event_espresso');
69
-        $this->plural_item   = esc_html__('Tickets', 'event_espresso');
70
-        $this->_tables       = [
71
-            'Ticket' => new EE_Primary_Table('esp_ticket', 'TKT_ID'),
72
-        ];
73
-        $this->parseTicketVisibilityOptions();
74
-        $this->_fields          = [
75
-            'Ticket' => [
76
-                'TKT_ID'                => new EE_Primary_Key_Int_Field(
77
-                    'TKT_ID',
78
-                    esc_html__('Ticket ID', 'event_espresso')
79
-                ),
80
-                'TTM_ID'                => new EE_Foreign_Key_Int_Field(
81
-                    'TTM_ID',
82
-                    esc_html__('Ticket Template ID', 'event_espresso'),
83
-                    false,
84
-                    0,
85
-                    'Ticket_Template'
86
-                ),
87
-                'TKT_name'              => new EE_Plain_Text_Field(
88
-                    'TKT_name',
89
-                    esc_html__('Ticket Name', 'event_espresso'),
90
-                    false,
91
-                    ''
92
-                ),
93
-                'TKT_description'       => new EE_Post_Content_Field(
94
-                    'TKT_description',
95
-                    esc_html__('Description of Ticket', 'event_espresso'),
96
-                    false,
97
-                    ''
98
-                ),
99
-                'TKT_start_date'        => new EE_Datetime_Field(
100
-                    'TKT_start_date',
101
-                    esc_html__('Start time/date of Ticket', 'event_espresso'),
102
-                    false,
103
-                    EE_Datetime_Field::now,
104
-                    $timezone
105
-                ),
106
-                'TKT_end_date'          => new EE_Datetime_Field(
107
-                    'TKT_end_date',
108
-                    esc_html__('End time/date of Ticket', 'event_espresso'),
109
-                    false,
110
-                    EE_Datetime_Field::now,
111
-                    $timezone
112
-                ),
113
-                'TKT_min'               => new EE_Integer_Field(
114
-                    'TKT_min',
115
-                    esc_html__('Minimum quantity of this ticket that must be purchased', 'event_espresso'),
116
-                    false,
117
-                    0
118
-                ),
119
-                'TKT_max'               => new EE_Infinite_Integer_Field(
120
-                    'TKT_max',
121
-                    esc_html__(
122
-                        'Maximum quantity of this ticket that can be purchased in one transaction',
123
-                        'event_espresso'
124
-                    ),
125
-                    false,
126
-                    EE_INF
127
-                ),
128
-                'TKT_price'             => new EE_Money_Field(
129
-                    'TKT_price',
130
-                    esc_html__('Final calculated price for ticket', 'event_espresso'),
131
-                    false,
132
-                    0
133
-                ),
134
-                'TKT_sold'              => new EE_Integer_Field(
135
-                    'TKT_sold',
136
-                    esc_html__('Number of this ticket sold', 'event_espresso'),
137
-                    false,
138
-                    0
139
-                ),
140
-                'TKT_qty'               => new EE_Infinite_Integer_Field(
141
-                    'TKT_qty',
142
-                    esc_html__('Quantity of this ticket that is available', 'event_espresso'),
143
-                    false,
144
-                    EE_INF
145
-                ),
146
-                'TKT_reserved'          => new EE_Integer_Field(
147
-                    'TKT_reserved',
148
-                    esc_html__(
149
-                        'Quantity of this ticket that is reserved, but not yet fully purchased',
150
-                        'event_espresso'
151
-                    ),
152
-                    false,
153
-                    0
154
-                ),
155
-                'TKT_uses'              => new EE_Infinite_Integer_Field(
156
-                    'TKT_uses',
157
-                    esc_html__('Number of datetimes this ticket can be used at', 'event_espresso'),
158
-                    false,
159
-                    EE_INF
160
-                ),
161
-                'TKT_required'          => new EE_Boolean_Field(
162
-                    'TKT_required',
163
-                    esc_html__(
164
-                        'Flag indicating whether this ticket must be purchased with a transaction',
165
-                        'event_espresso'
166
-                    ),
167
-                    false,
168
-                    false
169
-                ),
170
-                'TKT_taxable'           => new EE_Boolean_Field(
171
-                    'TKT_taxable',
172
-                    esc_html__(
173
-                        'Flag indicating whether there is tax applied on this ticket',
174
-                        'event_espresso'
175
-                    ),
176
-                    false,
177
-                    false
178
-                ),
179
-                'TKT_is_default'        => new EE_Boolean_Field(
180
-                    'TKT_is_default',
181
-                    esc_html__('Flag indicating that this ticket is a default ticket', 'event_espresso'),
182
-                    false,
183
-                    false
184
-                ),
185
-                'TKT_order'             => new EE_Integer_Field(
186
-                    'TKT_order',
187
-                    esc_html__(
188
-                        'The order in which the Ticket is displayed in the editor (used for autosaves when the form doesn\'t have the ticket ID yet)',
189
-                        'event_espresso'
190
-                    ),
191
-                    false,
192
-                    0
193
-                ),
194
-                'TKT_row'               => new EE_Integer_Field(
195
-                    'TKT_row',
196
-                    esc_html__('How tickets are displayed in the ui', 'event_espresso'),
197
-                    false,
198
-                    0
199
-                ),
200
-                'TKT_deleted'           => new EE_Trashed_Flag_Field(
201
-                    'TKT_deleted',
202
-                    esc_html__('Flag indicating if this has been archived or not', 'event_espresso'),
203
-                    false,
204
-                    false
205
-                ),
206
-                'TKT_wp_user'           => new EE_WP_User_Field(
207
-                    'TKT_wp_user',
208
-                    esc_html__('Ticket Creator ID', 'event_espresso'),
209
-                    false
210
-                ),
211
-                'TKT_parent'            => new EE_Integer_Field(
212
-                    'TKT_parent',
213
-                    esc_html__(
214
-                        'Indicates what TKT_ID is the parent of this TKT_ID (used in autosaves/revisions)',
215
-                        'event_espresso'
216
-                    ),
217
-                    true,
218
-                    0
219
-                ),
220
-                'TKT_reverse_calculate' => new EE_Boolean_Field(
221
-                    'TKT_reverse_calculate',
222
-                    esc_html__(
223
-                        'Flag indicating whether ticket calculations should run in reverse and calculate the base ticket price from the provided ticket total.',
224
-                        'event_espresso'
225
-                    ),
226
-                    false,
227
-                    false
228
-                ),
229
-                'TKT_visibility'        => new EE_Enum_Integer_Field(
230
-                    'TKT_visibility',
231
-                    esc_html__('Defines where the ticket can be viewed throughout the UI.', 'event_espresso'),
232
-                    false,
233
-                    EEM_Ticket::TICKET_VISIBILITY_PUBLIC_VALUE,
234
-                    $this->getTicketVisibilityEnumOptions()
235
-                ),
236
-            ],
237
-        ];
238
-        $this->_model_relations = [
239
-            'Datetime'        => new EE_HABTM_Relation('Datetime_Ticket'),
240
-            'Datetime_Ticket' => new EE_Has_Many_Relation(),
241
-            'Price'           => new EE_HABTM_Relation('Ticket_Price'),
242
-            'Ticket_Template' => new EE_Belongs_To_Relation(),
243
-            'Registration'    => new EE_Has_Many_Relation(),
244
-            'WP_User'         => new EE_Belongs_To_Relation(),
245
-        ];
246
-        // this model is generally available for reading
247
-        $path_to_event                                            = 'Datetime.Event';
248
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Default_Public(
249
-            'TKT_is_default',
250
-            $path_to_event
251
-        );
252
-
253
-        // account for default tickets in the caps
254
-        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ]
255
-                                                                    = new EE_Restriction_Generator_Default_Protected(
256
-            'TKT_is_default',
257
-            $path_to_event
258
-        );
259
-        $this->_cap_restriction_generators[ EEM_Base::caps_edit ]   = new EE_Restriction_Generator_Default_Protected(
260
-            'TKT_is_default',
261
-            $path_to_event
262
-        );
263
-        $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = new EE_Restriction_Generator_Default_Protected(
264
-            'TKT_is_default',
265
-            $path_to_event
266
-        );
267
-        $this->model_chain_to_password                              = $path_to_event;
268
-        parent::__construct($timezone);
269
-    }
270
-
271
-
272
-    /**
273
-     * This returns all tickets that are defaults from the db
274
-     *
275
-     * @return EE_Ticket[]
276
-     * @throws EE_Error
277
-     * @throws ReflectionException
278
-     */
279
-    public function get_all_default_tickets(): array
280
-    {
281
-        $tickets = $this->get_all(
282
-            [
283
-                [
284
-                    'TKT_is_default' => 1,
285
-                    'TKT_visibility' => ['>', EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE],
286
-                ],
287
-                'order_by' => ['TKT_ID' => 'ASC'],
288
-            ]
289
-        );
290
-        // we need to set the start date and end date to today's date and the start of the default dtt
291
-        return $this->_set_default_dates($tickets);
292
-    }
293
-
294
-
295
-    /**
296
-     * sets up relevant start and end date for EE_Ticket (s)
297
-     *
298
-     * @param EE_Ticket[] $tickets
299
-     * @return EE_Ticket[]
300
-     * @throws EE_Error
301
-     * @throws ReflectionException
302
-     */
303
-    private function _set_default_dates(array $tickets): array
304
-    {
305
-        foreach ($tickets as $ticket) {
306
-            $ticket->set(
307
-                'TKT_start_date',
308
-                (int) $this->current_time_for_query('TKT_start_date', true)
309
-            );
310
-            $ticket->set(
311
-                'TKT_end_date',
312
-                (int) $this->current_time_for_query('TKT_end_date', true) + MONTH_IN_SECONDS
313
-            );
314
-            $ticket->set_end_time(
315
-                $this->convert_datetime_for_query(
316
-                    'TKT_end_date',
317
-                    '11:59 pm',
318
-                    'g:i a',
319
-                    $this->_timezone
320
-                )
321
-            );
322
-        }
323
-        return $tickets;
324
-    }
325
-
326
-
327
-    /**
328
-     * Gets the total number of tickets available at a particular datetime (does
329
-     * NOT take int account the datetime's spaces available)
330
-     *
331
-     * @param int   $DTT_ID
332
-     * @param array $query_params
333
-     * @return int
334
-     * @throws EE_Error
335
-     * @throws ReflectionException
336
-     */
337
-    public function sum_tickets_currently_available_at_datetime(int $DTT_ID, array $query_params = []): int
338
-    {
339
-        $query_params += [['TKT_visibility' => ['>', EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE]]];
340
-        return EEM_Datetime::instance()->sum_tickets_currently_available_at_datetime($DTT_ID, $query_params);
341
-    }
342
-
343
-
344
-    /**
345
-     * Updates the TKT_sold quantity on all the tickets matching $query_params
346
-     *
347
-     * @param EE_Ticket[] $tickets
348
-     * @return void
349
-     * @throws EE_Error
350
-     * @throws ReflectionException
351
-     */
352
-    public function update_tickets_sold(array $tickets)
353
-    {
354
-        foreach ($tickets as $ticket) {
355
-            $ticket->update_tickets_sold();
356
-        }
357
-    }
358
-
359
-
360
-    /**
361
-     * returns an array of EE_Ticket objects with a non-zero value for TKT_reserved
362
-     *
363
-     * @return EE_Base_Class[]|EE_Ticket[]|null
364
-     * @throws EE_Error
365
-     * @throws ReflectionException
366
-     */
367
-    public function get_tickets_with_reservations(): ?array
368
-    {
369
-        return $this->get_all(
370
-            [
371
-                [
372
-                    'TKT_reserved'   => ['>', 0],
373
-                    'TKT_visibility' => ['>', EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE],
374
-                ],
375
-            ]
376
-        );
377
-    }
378
-
379
-
380
-    /**
381
-     * returns an array of EE_Ticket objects matching the supplied list of IDs
382
-     *
383
-     * @param array $ticket_IDs
384
-     * @return EE_Base_Class[]|EE_Ticket[]|null
385
-     * @throws EE_Error
386
-     * @throws ReflectionException
387
-     */
388
-    public function get_tickets_with_IDs(array $ticket_IDs): ?array
389
-    {
390
-        return $this->get_all(
391
-            [
392
-                [
393
-                    'TKT_ID' => ['IN', $ticket_IDs],
394
-                ],
395
-            ]
396
-        );
397
-    }
398
-
399
-
400
-    /**
401
-     * @return void
402
-     */
403
-    private function parseTicketVisibilityOptions()
404
-    {
405
-        $this->ticket_visibility = (array) apply_filters(
406
-            'FHEE__EEM_Ticket__construct__ticket_visibility',
407
-            [
408
-                EEM_Ticket::TICKET_VISIBILITY_PUBLIC_KEY        => [
409
-                    'desc'  => esc_html__('ticket displayed to everyone everywhere', 'event_espresso'),
410
-                    'label' => esc_html__('Public', 'event_espresso'),
411
-                    'value' => EEM_Ticket::TICKET_VISIBILITY_PUBLIC_VALUE,
412
-                ],
413
-                EEM_Ticket::TICKET_VISIBILITY_MEMBERS_ONLY_KEY  => [
414
-                    'desc'  => esc_html__('ticket only displayed to logged-in users', 'event_espresso'),
415
-                    'label' => esc_html__('Members only', 'event_espresso'),
416
-                    'value' => EEM_Ticket::TICKET_VISIBILITY_MEMBERS_ONLY_VALUE,
417
-                ],
418
-                EEM_Ticket::TICKET_VISIBILITY_ADMINS_ONLY_KEY   => [
419
-                    'desc'  => esc_html__('ticket only displayed to logged-in admins', 'event_espresso'),
420
-                    'label' => esc_html__('Admins only', 'event_espresso'),
421
-                    'value' => EEM_Ticket::TICKET_VISIBILITY_ADMINS_ONLY_VALUE,
422
-                ],
423
-                EEM_Ticket::TICKET_VISIBILITY_ADMIN_UI_ONLY_KEY => [
424
-                    'desc'  => esc_html__(
425
-                        'ticket only displayed in the admin UI and not on the frontend',
426
-                        'event_espresso'
427
-                    ),
428
-                    'label' => esc_html__('Admin UI only', 'event_espresso'),
429
-                    'value' => EEM_Ticket::TICKET_VISIBILITY_ADMIN_UI_ONLY_VALUE,
430
-                ],
431
-                EEM_Ticket::TICKET_VISIBILITY_NONE_KEY          => [
432
-                    'desc'  => esc_html__('will hide the ticket everywhere', 'event_espresso'),
433
-                    'label' => esc_html__('None', 'event_espresso'),
434
-                    'value' => EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE,
435
-                ],
436
-            ]
437
-        );
438
-    }
439
-
440
-
441
-    /**
442
-     * @return array
443
-     */
444
-    public function getTicketVisibilityEnumOptions(): array
445
-    {
446
-        $ticket_visibility = [];
447
-        foreach ($this->ticket_visibility as $visibility) {
448
-            if (isset($visibility['value'], $visibility['label'])) {
449
-                $ticket_visibility[ $visibility['value'] ] = $visibility['label'];
450
-            }
451
-        }
452
-        return $ticket_visibility;
453
-    }
454
-
455
-
456
-    /**
457
-     * @return array
458
-     */
459
-    public function getTicketVisibilityValues(): array
460
-    {
461
-        // copy ticket_visibility array
462
-        $ticket_visibility_options = $this->ticket_visibility;
463
-        foreach ($ticket_visibility_options as $ticket_visibility_option) {
464
-            // remove labels because we only want the values
465
-            unset($ticket_visibility_option['label']);
466
-        }
467
-        return $ticket_visibility_options;
468
-    }
469
-
470
-
471
-    /**
472
-     * @return array
473
-     */
474
-    public function getTicketVisibilityLabels(): array
475
-    {
476
-        $ticket_visibility_options = [];
477
-        foreach ($this->ticket_visibility as $key => $ticket_visibility_option) {
478
-            if (isset($ticket_visibility_option['label'])) {
479
-                // change because we only want the labels tied to the keys
480
-                $ticket_visibility_options[] = [
481
-                    'value' => $key,
482
-                    'label' => $ticket_visibility_option['label'],
483
-                ];
484
-            }
485
-        }
486
-        return $ticket_visibility_options;
487
-    }
488
-
489
-
490
-    /**
491
-     * @return array
492
-     */
493
-    public function ticketVisibilityOptions(): array
494
-    {
495
-        return $this->ticket_visibility;
496
-    }
16
+	/**
17
+	 * the following constants define where tickets can be viewed throughout the UI
18
+	 *  TICKET_VISIBILITY_NONE          - will not be displayed anywhere
19
+	 *  TICKET_VISIBILITY_PUBLIC        - basically displayed everywhere
20
+	 *  TICKET_VISIBILITY_MEMBERS_ONLY  - displayed to any logged-in user
21
+	 *  TICKET_VISIBILITY_ADMINS_ONLY   - displayed to any logged-in user that is an admin
22
+	 *  TICKET_VISIBILITY_ADMIN_UI_ONLY - only displayed in the admin, never publicly
23
+	 */
24
+	public const TICKET_VISIBILITY_NONE_KEY            = 'NONE';
25
+
26
+	public const TICKET_VISIBILITY_NONE_VALUE          = 0;
27
+
28
+	public const TICKET_VISIBILITY_PUBLIC_KEY          = 'PUBLIC';
29
+
30
+	public const TICKET_VISIBILITY_PUBLIC_VALUE        = 100;
31
+
32
+	public const TICKET_VISIBILITY_MEMBERS_ONLY_KEY    = 'MEMBERS_ONLY';
33
+
34
+	public const TICKET_VISIBILITY_MEMBERS_ONLY_VALUE  = 200;
35
+
36
+	public const TICKET_VISIBILITY_ADMINS_ONLY_KEY     = 'ADMINS_ONLY';
37
+
38
+	public const TICKET_VISIBILITY_ADMINS_ONLY_VALUE   = 300;
39
+
40
+	public const TICKET_VISIBILITY_ADMIN_UI_ONLY_KEY   = 'ADMIN_UI_ONLY';
41
+
42
+	public const TICKET_VISIBILITY_ADMIN_UI_ONLY_VALUE = 400;
43
+
44
+
45
+	/**
46
+	 * defines where tickets can be viewed throughout the UI
47
+	 *
48
+	 * @var array
49
+	 */
50
+	private $ticket_visibility;
51
+
52
+	protected static ?EEM_Ticket $_instance = null;
53
+
54
+
55
+	/**
56
+	 * private constructor to prevent direct creation
57
+	 *
58
+	 * @param string|null $timezone string representing the timezone we want to set for returned Date Time Strings
59
+	 *                              (and any incoming timezone data that gets saved).
60
+	 *                              Note this just sends the timezone info to the date time model field objects.
61
+	 *                              Default is NULL
62
+	 *                              (and will be assumed using the set timezone in the 'timezone_string' wp option)
63
+	 * @throws EE_Error
64
+	 * @throws ReflectionException
65
+	 */
66
+	protected function __construct(?string $timezone = '')
67
+	{
68
+		$this->singular_item = esc_html__('Ticket', 'event_espresso');
69
+		$this->plural_item   = esc_html__('Tickets', 'event_espresso');
70
+		$this->_tables       = [
71
+			'Ticket' => new EE_Primary_Table('esp_ticket', 'TKT_ID'),
72
+		];
73
+		$this->parseTicketVisibilityOptions();
74
+		$this->_fields          = [
75
+			'Ticket' => [
76
+				'TKT_ID'                => new EE_Primary_Key_Int_Field(
77
+					'TKT_ID',
78
+					esc_html__('Ticket ID', 'event_espresso')
79
+				),
80
+				'TTM_ID'                => new EE_Foreign_Key_Int_Field(
81
+					'TTM_ID',
82
+					esc_html__('Ticket Template ID', 'event_espresso'),
83
+					false,
84
+					0,
85
+					'Ticket_Template'
86
+				),
87
+				'TKT_name'              => new EE_Plain_Text_Field(
88
+					'TKT_name',
89
+					esc_html__('Ticket Name', 'event_espresso'),
90
+					false,
91
+					''
92
+				),
93
+				'TKT_description'       => new EE_Post_Content_Field(
94
+					'TKT_description',
95
+					esc_html__('Description of Ticket', 'event_espresso'),
96
+					false,
97
+					''
98
+				),
99
+				'TKT_start_date'        => new EE_Datetime_Field(
100
+					'TKT_start_date',
101
+					esc_html__('Start time/date of Ticket', 'event_espresso'),
102
+					false,
103
+					EE_Datetime_Field::now,
104
+					$timezone
105
+				),
106
+				'TKT_end_date'          => new EE_Datetime_Field(
107
+					'TKT_end_date',
108
+					esc_html__('End time/date of Ticket', 'event_espresso'),
109
+					false,
110
+					EE_Datetime_Field::now,
111
+					$timezone
112
+				),
113
+				'TKT_min'               => new EE_Integer_Field(
114
+					'TKT_min',
115
+					esc_html__('Minimum quantity of this ticket that must be purchased', 'event_espresso'),
116
+					false,
117
+					0
118
+				),
119
+				'TKT_max'               => new EE_Infinite_Integer_Field(
120
+					'TKT_max',
121
+					esc_html__(
122
+						'Maximum quantity of this ticket that can be purchased in one transaction',
123
+						'event_espresso'
124
+					),
125
+					false,
126
+					EE_INF
127
+				),
128
+				'TKT_price'             => new EE_Money_Field(
129
+					'TKT_price',
130
+					esc_html__('Final calculated price for ticket', 'event_espresso'),
131
+					false,
132
+					0
133
+				),
134
+				'TKT_sold'              => new EE_Integer_Field(
135
+					'TKT_sold',
136
+					esc_html__('Number of this ticket sold', 'event_espresso'),
137
+					false,
138
+					0
139
+				),
140
+				'TKT_qty'               => new EE_Infinite_Integer_Field(
141
+					'TKT_qty',
142
+					esc_html__('Quantity of this ticket that is available', 'event_espresso'),
143
+					false,
144
+					EE_INF
145
+				),
146
+				'TKT_reserved'          => new EE_Integer_Field(
147
+					'TKT_reserved',
148
+					esc_html__(
149
+						'Quantity of this ticket that is reserved, but not yet fully purchased',
150
+						'event_espresso'
151
+					),
152
+					false,
153
+					0
154
+				),
155
+				'TKT_uses'              => new EE_Infinite_Integer_Field(
156
+					'TKT_uses',
157
+					esc_html__('Number of datetimes this ticket can be used at', 'event_espresso'),
158
+					false,
159
+					EE_INF
160
+				),
161
+				'TKT_required'          => new EE_Boolean_Field(
162
+					'TKT_required',
163
+					esc_html__(
164
+						'Flag indicating whether this ticket must be purchased with a transaction',
165
+						'event_espresso'
166
+					),
167
+					false,
168
+					false
169
+				),
170
+				'TKT_taxable'           => new EE_Boolean_Field(
171
+					'TKT_taxable',
172
+					esc_html__(
173
+						'Flag indicating whether there is tax applied on this ticket',
174
+						'event_espresso'
175
+					),
176
+					false,
177
+					false
178
+				),
179
+				'TKT_is_default'        => new EE_Boolean_Field(
180
+					'TKT_is_default',
181
+					esc_html__('Flag indicating that this ticket is a default ticket', 'event_espresso'),
182
+					false,
183
+					false
184
+				),
185
+				'TKT_order'             => new EE_Integer_Field(
186
+					'TKT_order',
187
+					esc_html__(
188
+						'The order in which the Ticket is displayed in the editor (used for autosaves when the form doesn\'t have the ticket ID yet)',
189
+						'event_espresso'
190
+					),
191
+					false,
192
+					0
193
+				),
194
+				'TKT_row'               => new EE_Integer_Field(
195
+					'TKT_row',
196
+					esc_html__('How tickets are displayed in the ui', 'event_espresso'),
197
+					false,
198
+					0
199
+				),
200
+				'TKT_deleted'           => new EE_Trashed_Flag_Field(
201
+					'TKT_deleted',
202
+					esc_html__('Flag indicating if this has been archived or not', 'event_espresso'),
203
+					false,
204
+					false
205
+				),
206
+				'TKT_wp_user'           => new EE_WP_User_Field(
207
+					'TKT_wp_user',
208
+					esc_html__('Ticket Creator ID', 'event_espresso'),
209
+					false
210
+				),
211
+				'TKT_parent'            => new EE_Integer_Field(
212
+					'TKT_parent',
213
+					esc_html__(
214
+						'Indicates what TKT_ID is the parent of this TKT_ID (used in autosaves/revisions)',
215
+						'event_espresso'
216
+					),
217
+					true,
218
+					0
219
+				),
220
+				'TKT_reverse_calculate' => new EE_Boolean_Field(
221
+					'TKT_reverse_calculate',
222
+					esc_html__(
223
+						'Flag indicating whether ticket calculations should run in reverse and calculate the base ticket price from the provided ticket total.',
224
+						'event_espresso'
225
+					),
226
+					false,
227
+					false
228
+				),
229
+				'TKT_visibility'        => new EE_Enum_Integer_Field(
230
+					'TKT_visibility',
231
+					esc_html__('Defines where the ticket can be viewed throughout the UI.', 'event_espresso'),
232
+					false,
233
+					EEM_Ticket::TICKET_VISIBILITY_PUBLIC_VALUE,
234
+					$this->getTicketVisibilityEnumOptions()
235
+				),
236
+			],
237
+		];
238
+		$this->_model_relations = [
239
+			'Datetime'        => new EE_HABTM_Relation('Datetime_Ticket'),
240
+			'Datetime_Ticket' => new EE_Has_Many_Relation(),
241
+			'Price'           => new EE_HABTM_Relation('Ticket_Price'),
242
+			'Ticket_Template' => new EE_Belongs_To_Relation(),
243
+			'Registration'    => new EE_Has_Many_Relation(),
244
+			'WP_User'         => new EE_Belongs_To_Relation(),
245
+		];
246
+		// this model is generally available for reading
247
+		$path_to_event                                            = 'Datetime.Event';
248
+		$this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Default_Public(
249
+			'TKT_is_default',
250
+			$path_to_event
251
+		);
252
+
253
+		// account for default tickets in the caps
254
+		$this->_cap_restriction_generators[ EEM_Base::caps_read_admin ]
255
+																	= new EE_Restriction_Generator_Default_Protected(
256
+			'TKT_is_default',
257
+			$path_to_event
258
+		);
259
+		$this->_cap_restriction_generators[ EEM_Base::caps_edit ]   = new EE_Restriction_Generator_Default_Protected(
260
+			'TKT_is_default',
261
+			$path_to_event
262
+		);
263
+		$this->_cap_restriction_generators[ EEM_Base::caps_delete ] = new EE_Restriction_Generator_Default_Protected(
264
+			'TKT_is_default',
265
+			$path_to_event
266
+		);
267
+		$this->model_chain_to_password                              = $path_to_event;
268
+		parent::__construct($timezone);
269
+	}
270
+
271
+
272
+	/**
273
+	 * This returns all tickets that are defaults from the db
274
+	 *
275
+	 * @return EE_Ticket[]
276
+	 * @throws EE_Error
277
+	 * @throws ReflectionException
278
+	 */
279
+	public function get_all_default_tickets(): array
280
+	{
281
+		$tickets = $this->get_all(
282
+			[
283
+				[
284
+					'TKT_is_default' => 1,
285
+					'TKT_visibility' => ['>', EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE],
286
+				],
287
+				'order_by' => ['TKT_ID' => 'ASC'],
288
+			]
289
+		);
290
+		// we need to set the start date and end date to today's date and the start of the default dtt
291
+		return $this->_set_default_dates($tickets);
292
+	}
293
+
294
+
295
+	/**
296
+	 * sets up relevant start and end date for EE_Ticket (s)
297
+	 *
298
+	 * @param EE_Ticket[] $tickets
299
+	 * @return EE_Ticket[]
300
+	 * @throws EE_Error
301
+	 * @throws ReflectionException
302
+	 */
303
+	private function _set_default_dates(array $tickets): array
304
+	{
305
+		foreach ($tickets as $ticket) {
306
+			$ticket->set(
307
+				'TKT_start_date',
308
+				(int) $this->current_time_for_query('TKT_start_date', true)
309
+			);
310
+			$ticket->set(
311
+				'TKT_end_date',
312
+				(int) $this->current_time_for_query('TKT_end_date', true) + MONTH_IN_SECONDS
313
+			);
314
+			$ticket->set_end_time(
315
+				$this->convert_datetime_for_query(
316
+					'TKT_end_date',
317
+					'11:59 pm',
318
+					'g:i a',
319
+					$this->_timezone
320
+				)
321
+			);
322
+		}
323
+		return $tickets;
324
+	}
325
+
326
+
327
+	/**
328
+	 * Gets the total number of tickets available at a particular datetime (does
329
+	 * NOT take int account the datetime's spaces available)
330
+	 *
331
+	 * @param int   $DTT_ID
332
+	 * @param array $query_params
333
+	 * @return int
334
+	 * @throws EE_Error
335
+	 * @throws ReflectionException
336
+	 */
337
+	public function sum_tickets_currently_available_at_datetime(int $DTT_ID, array $query_params = []): int
338
+	{
339
+		$query_params += [['TKT_visibility' => ['>', EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE]]];
340
+		return EEM_Datetime::instance()->sum_tickets_currently_available_at_datetime($DTT_ID, $query_params);
341
+	}
342
+
343
+
344
+	/**
345
+	 * Updates the TKT_sold quantity on all the tickets matching $query_params
346
+	 *
347
+	 * @param EE_Ticket[] $tickets
348
+	 * @return void
349
+	 * @throws EE_Error
350
+	 * @throws ReflectionException
351
+	 */
352
+	public function update_tickets_sold(array $tickets)
353
+	{
354
+		foreach ($tickets as $ticket) {
355
+			$ticket->update_tickets_sold();
356
+		}
357
+	}
358
+
359
+
360
+	/**
361
+	 * returns an array of EE_Ticket objects with a non-zero value for TKT_reserved
362
+	 *
363
+	 * @return EE_Base_Class[]|EE_Ticket[]|null
364
+	 * @throws EE_Error
365
+	 * @throws ReflectionException
366
+	 */
367
+	public function get_tickets_with_reservations(): ?array
368
+	{
369
+		return $this->get_all(
370
+			[
371
+				[
372
+					'TKT_reserved'   => ['>', 0],
373
+					'TKT_visibility' => ['>', EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE],
374
+				],
375
+			]
376
+		);
377
+	}
378
+
379
+
380
+	/**
381
+	 * returns an array of EE_Ticket objects matching the supplied list of IDs
382
+	 *
383
+	 * @param array $ticket_IDs
384
+	 * @return EE_Base_Class[]|EE_Ticket[]|null
385
+	 * @throws EE_Error
386
+	 * @throws ReflectionException
387
+	 */
388
+	public function get_tickets_with_IDs(array $ticket_IDs): ?array
389
+	{
390
+		return $this->get_all(
391
+			[
392
+				[
393
+					'TKT_ID' => ['IN', $ticket_IDs],
394
+				],
395
+			]
396
+		);
397
+	}
398
+
399
+
400
+	/**
401
+	 * @return void
402
+	 */
403
+	private function parseTicketVisibilityOptions()
404
+	{
405
+		$this->ticket_visibility = (array) apply_filters(
406
+			'FHEE__EEM_Ticket__construct__ticket_visibility',
407
+			[
408
+				EEM_Ticket::TICKET_VISIBILITY_PUBLIC_KEY        => [
409
+					'desc'  => esc_html__('ticket displayed to everyone everywhere', 'event_espresso'),
410
+					'label' => esc_html__('Public', 'event_espresso'),
411
+					'value' => EEM_Ticket::TICKET_VISIBILITY_PUBLIC_VALUE,
412
+				],
413
+				EEM_Ticket::TICKET_VISIBILITY_MEMBERS_ONLY_KEY  => [
414
+					'desc'  => esc_html__('ticket only displayed to logged-in users', 'event_espresso'),
415
+					'label' => esc_html__('Members only', 'event_espresso'),
416
+					'value' => EEM_Ticket::TICKET_VISIBILITY_MEMBERS_ONLY_VALUE,
417
+				],
418
+				EEM_Ticket::TICKET_VISIBILITY_ADMINS_ONLY_KEY   => [
419
+					'desc'  => esc_html__('ticket only displayed to logged-in admins', 'event_espresso'),
420
+					'label' => esc_html__('Admins only', 'event_espresso'),
421
+					'value' => EEM_Ticket::TICKET_VISIBILITY_ADMINS_ONLY_VALUE,
422
+				],
423
+				EEM_Ticket::TICKET_VISIBILITY_ADMIN_UI_ONLY_KEY => [
424
+					'desc'  => esc_html__(
425
+						'ticket only displayed in the admin UI and not on the frontend',
426
+						'event_espresso'
427
+					),
428
+					'label' => esc_html__('Admin UI only', 'event_espresso'),
429
+					'value' => EEM_Ticket::TICKET_VISIBILITY_ADMIN_UI_ONLY_VALUE,
430
+				],
431
+				EEM_Ticket::TICKET_VISIBILITY_NONE_KEY          => [
432
+					'desc'  => esc_html__('will hide the ticket everywhere', 'event_espresso'),
433
+					'label' => esc_html__('None', 'event_espresso'),
434
+					'value' => EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE,
435
+				],
436
+			]
437
+		);
438
+	}
439
+
440
+
441
+	/**
442
+	 * @return array
443
+	 */
444
+	public function getTicketVisibilityEnumOptions(): array
445
+	{
446
+		$ticket_visibility = [];
447
+		foreach ($this->ticket_visibility as $visibility) {
448
+			if (isset($visibility['value'], $visibility['label'])) {
449
+				$ticket_visibility[ $visibility['value'] ] = $visibility['label'];
450
+			}
451
+		}
452
+		return $ticket_visibility;
453
+	}
454
+
455
+
456
+	/**
457
+	 * @return array
458
+	 */
459
+	public function getTicketVisibilityValues(): array
460
+	{
461
+		// copy ticket_visibility array
462
+		$ticket_visibility_options = $this->ticket_visibility;
463
+		foreach ($ticket_visibility_options as $ticket_visibility_option) {
464
+			// remove labels because we only want the values
465
+			unset($ticket_visibility_option['label']);
466
+		}
467
+		return $ticket_visibility_options;
468
+	}
469
+
470
+
471
+	/**
472
+	 * @return array
473
+	 */
474
+	public function getTicketVisibilityLabels(): array
475
+	{
476
+		$ticket_visibility_options = [];
477
+		foreach ($this->ticket_visibility as $key => $ticket_visibility_option) {
478
+			if (isset($ticket_visibility_option['label'])) {
479
+				// change because we only want the labels tied to the keys
480
+				$ticket_visibility_options[] = [
481
+					'value' => $key,
482
+					'label' => $ticket_visibility_option['label'],
483
+				];
484
+			}
485
+		}
486
+		return $ticket_visibility_options;
487
+	}
488
+
489
+
490
+	/**
491
+	 * @return array
492
+	 */
493
+	public function ticketVisibilityOptions(): array
494
+	{
495
+		return $this->ticket_visibility;
496
+	}
497 497
 }
Please login to merge, or discard this patch.
core/db_models/EEM_Answer.model.php 1 patch
Indentation   +179 added lines, -179 removed lines patch added patch discarded remove patch
@@ -9,192 +9,192 @@
 block discarded – undo
9 9
  */
10 10
 class EEM_Answer extends EEM_Base
11 11
 {
12
-    protected static ?EEM_Answer $_instance = null;
12
+	protected static ?EEM_Answer $_instance = null;
13 13
 
14
-    /**
15
-     * Mapping from system question ids to attendee field names
16
-     *
17
-     * @type array
18
-     * @deprecated since version 4.8.8
19
-     */
20
-    protected $_question_id_to_att_field_map = [
21
-        EEM_Attendee::fname_question_id    => 'ATT_fname',
22
-        EEM_Attendee::lname_question_id    => 'ATT_lname',
23
-        EEM_Attendee::email_question_id    => 'ATT_email',
24
-        EEM_Attendee::address_question_id  => 'ATT_address',
25
-        EEM_Attendee::address2_question_id => 'ATT_address2',
26
-        EEM_Attendee::city_question_id     => 'ATT_city',
27
-        EEM_Attendee::state_question_id    => 'STA_ID',
28
-        EEM_Attendee::country_question_id  => 'CNT_ISO',
29
-        EEM_Attendee::zip_question_id      => 'ATT_zip',
30
-        EEM_Attendee::phone_question_id    => 'ATT_phone',
31
-    ];
14
+	/**
15
+	 * Mapping from system question ids to attendee field names
16
+	 *
17
+	 * @type array
18
+	 * @deprecated since version 4.8.8
19
+	 */
20
+	protected $_question_id_to_att_field_map = [
21
+		EEM_Attendee::fname_question_id    => 'ATT_fname',
22
+		EEM_Attendee::lname_question_id    => 'ATT_lname',
23
+		EEM_Attendee::email_question_id    => 'ATT_email',
24
+		EEM_Attendee::address_question_id  => 'ATT_address',
25
+		EEM_Attendee::address2_question_id => 'ATT_address2',
26
+		EEM_Attendee::city_question_id     => 'ATT_city',
27
+		EEM_Attendee::state_question_id    => 'STA_ID',
28
+		EEM_Attendee::country_question_id  => 'CNT_ISO',
29
+		EEM_Attendee::zip_question_id      => 'ATT_zip',
30
+		EEM_Attendee::phone_question_id    => 'ATT_phone',
31
+	];
32 32
 
33 33
 
34
-    /**
35
-     * @param string|null $timezone
36
-     * @throws EE_Error
37
-     */
38
-    protected function __construct(?string $timezone = '')
39
-    {
40
-        $this->singular_item           = esc_html__('Answer', 'event_espresso');
41
-        $this->plural_item             = esc_html__('Answers', 'event_espresso');
42
-        $this->_tables                 = [
43
-            'Answer' => new EE_Primary_Table('esp_answer', 'ANS_ID'),
44
-        ];
45
-        $this->_fields                 = [
46
-            'Answer' => [
47
-                'ANS_ID'    => new EE_Primary_Key_Int_Field('ANS_ID', esc_html__('Answer ID', 'event_espresso')),
48
-                'REG_ID'    => new EE_Foreign_Key_Int_Field(
49
-                    'REG_ID',
50
-                    esc_html__('Registration ID', 'event_espresso'),
51
-                    false,
52
-                    0,
53
-                    'Registration'
54
-                ),
55
-                'QST_ID'    => new EE_Foreign_Key_Int_Field(
56
-                    'QST_ID',
57
-                    esc_html__('Question ID', 'event_espresso'),
58
-                    false,
59
-                    0,
60
-                    'Question'
61
-                ),
62
-                'ANS_value' => new EE_Maybe_Serialized_Simple_HTML_Field(
63
-                    'ANS_value',
64
-                    esc_html__('Answer Value', 'event_espresso'),
65
-                    false,
66
-                    ''
67
-                ),
68
-            ],
69
-        ];
70
-        $this->_model_relations        = [
71
-            'Registration' => new EE_Belongs_To_Relation(),
72
-            'Question'     => new EE_Belongs_To_Relation(),
73
-        ];
74
-        $this->_model_chain_to_wp_user = 'Registration.Event';
75
-        $this->_caps_slug              = 'registrations';
76
-        parent::__construct($timezone);
77
-    }
34
+	/**
35
+	 * @param string|null $timezone
36
+	 * @throws EE_Error
37
+	 */
38
+	protected function __construct(?string $timezone = '')
39
+	{
40
+		$this->singular_item           = esc_html__('Answer', 'event_espresso');
41
+		$this->plural_item             = esc_html__('Answers', 'event_espresso');
42
+		$this->_tables                 = [
43
+			'Answer' => new EE_Primary_Table('esp_answer', 'ANS_ID'),
44
+		];
45
+		$this->_fields                 = [
46
+			'Answer' => [
47
+				'ANS_ID'    => new EE_Primary_Key_Int_Field('ANS_ID', esc_html__('Answer ID', 'event_espresso')),
48
+				'REG_ID'    => new EE_Foreign_Key_Int_Field(
49
+					'REG_ID',
50
+					esc_html__('Registration ID', 'event_espresso'),
51
+					false,
52
+					0,
53
+					'Registration'
54
+				),
55
+				'QST_ID'    => new EE_Foreign_Key_Int_Field(
56
+					'QST_ID',
57
+					esc_html__('Question ID', 'event_espresso'),
58
+					false,
59
+					0,
60
+					'Question'
61
+				),
62
+				'ANS_value' => new EE_Maybe_Serialized_Simple_HTML_Field(
63
+					'ANS_value',
64
+					esc_html__('Answer Value', 'event_espresso'),
65
+					false,
66
+					''
67
+				),
68
+			],
69
+		];
70
+		$this->_model_relations        = [
71
+			'Registration' => new EE_Belongs_To_Relation(),
72
+			'Question'     => new EE_Belongs_To_Relation(),
73
+		];
74
+		$this->_model_chain_to_wp_user = 'Registration.Event';
75
+		$this->_caps_slug              = 'registrations';
76
+		parent::__construct($timezone);
77
+	}
78 78
 
79 79
 
80
-    /**
81
-     * Gets the string answer to the question for this registration (it could either be stored
82
-     * on the attendee or in the answer table. This function finds its value regardless)
83
-     *
84
-     * @param EE_Registration $registration
85
-     * @param int             $question_id
86
-     * @param boolean         $pretty_answer whether to call 'pretty_value' or just 'value'
87
-     * @return string
88
-     */
89
-    public function get_answer_value_to_question(
90
-        EE_Registration $registration,
91
-        $question_id = null,
92
-        $pretty_answer = false
93
-    ) {
94
-        $value = $this->get_attendee_property_answer_value($registration, $question_id, $pretty_answer);
95
-        if ($value === null) {
96
-            $answer_obj = $this->get_registration_question_answer_object($registration, $question_id);
97
-            if ($answer_obj instanceof EE_Answer) {
98
-                if ($pretty_answer) {
99
-                    $value = $answer_obj->pretty_value();
100
-                } else {
101
-                    $value = $answer_obj->value();
102
-                }
103
-            }
104
-        }
105
-        return apply_filters(
106
-            'FHEE__EEM_Answer__get_answer_value_to_question__answer_value',
107
-            $value,
108
-            $registration,
109
-            $question_id
110
-        );
111
-    }
80
+	/**
81
+	 * Gets the string answer to the question for this registration (it could either be stored
82
+	 * on the attendee or in the answer table. This function finds its value regardless)
83
+	 *
84
+	 * @param EE_Registration $registration
85
+	 * @param int             $question_id
86
+	 * @param boolean         $pretty_answer whether to call 'pretty_value' or just 'value'
87
+	 * @return string
88
+	 */
89
+	public function get_answer_value_to_question(
90
+		EE_Registration $registration,
91
+		$question_id = null,
92
+		$pretty_answer = false
93
+	) {
94
+		$value = $this->get_attendee_property_answer_value($registration, $question_id, $pretty_answer);
95
+		if ($value === null) {
96
+			$answer_obj = $this->get_registration_question_answer_object($registration, $question_id);
97
+			if ($answer_obj instanceof EE_Answer) {
98
+				if ($pretty_answer) {
99
+					$value = $answer_obj->pretty_value();
100
+				} else {
101
+					$value = $answer_obj->value();
102
+				}
103
+			}
104
+		}
105
+		return apply_filters(
106
+			'FHEE__EEM_Answer__get_answer_value_to_question__answer_value',
107
+			$value,
108
+			$registration,
109
+			$question_id
110
+		);
111
+	}
112 112
 
113 113
 
114
-    /**
115
-     * Gets the EE_Answer object for the question for this registration (if it exists)
116
-     *
117
-     * @param EE_Registration $registration
118
-     * @param int             $question_id
119
-     * @return EE_Answer
120
-     */
121
-    public function get_registration_question_answer_object(EE_Registration $registration, $question_id = null)
122
-    {
123
-        $answer_obj = $this->get_one([['QST_ID' => $question_id, 'REG_ID' => $registration->ID()]]);
124
-        return apply_filters(
125
-            'FHEE__EEM_Answer__get_registration_question_answer_object__answer_obj',
126
-            $answer_obj,
127
-            $registration,
128
-            $question_id
129
-        );
130
-    }
114
+	/**
115
+	 * Gets the EE_Answer object for the question for this registration (if it exists)
116
+	 *
117
+	 * @param EE_Registration $registration
118
+	 * @param int             $question_id
119
+	 * @return EE_Answer
120
+	 */
121
+	public function get_registration_question_answer_object(EE_Registration $registration, $question_id = null)
122
+	{
123
+		$answer_obj = $this->get_one([['QST_ID' => $question_id, 'REG_ID' => $registration->ID()]]);
124
+		return apply_filters(
125
+			'FHEE__EEM_Answer__get_registration_question_answer_object__answer_obj',
126
+			$answer_obj,
127
+			$registration,
128
+			$question_id
129
+		);
130
+	}
131 131
 
132 132
 
133
-    /**
134
-     * Gets the string answer to the question for this registration's attendee
135
-     *
136
-     * @param EE_Registration $registration
137
-     * @param int|string      $question_system_id if an INT this is understood to be the question's ID; if a string
138
-     *                                            then it should be its QST_system value. Passing in the QST_system
139
-     *                                            value is more efficient
140
-     * @param boolean         $pretty_answer
141
-     * @return string|null (if the registration has no attendee, or the question_system_id is not a QST_ID or
142
-     *                                            QST_system for a question corresponding to an attendee field, returns
143
-     *                                            null)
144
-     * @throws EE_Error
145
-     * @throws ReflectionException
146
-     */
147
-    public function get_attendee_property_answer_value(
148
-        EE_Registration $registration,
149
-        $question_system_id = null,
150
-        $pretty_answer = false
151
-    ) {
152
-        $value = null;
153
-        // backward compat: we still want to find the question's ID
154
-        if (is_numeric($question_system_id)) {
155
-            // find this question's QST_system value
156
-            $question_id        = $question_system_id;
157
-            $question_system_id = EEM_Question::instance()->get_var([['QST_ID' => $question_system_id]], 'QST_system');
158
-        } else {
159
-            $question_id = (int) EEM_Question::instance()->get_var([['QST_system' => $question_system_id]], 'QST_ID');
160
-        }
161
-        // only bother checking if the registration has an attendee
162
-        if ($registration->attendee() instanceof EE_Attendee) {
163
-            $field_name = EEM_Attendee::instance()->get_attendee_field_for_system_question($question_system_id);
164
-            if ($field_name) {
165
-                if ($pretty_answer) {
166
-                    if ($field_name === 'STA_ID') {
167
-                        $state = $registration->attendee()->state_obj();
168
-                        $value = $state instanceof EE_State
169
-                            ? $state->name()
170
-                            : sprintf(
171
-                                esc_html__('Unknown State (%s)', 'event_espresso'),
172
-                                $registration->attendee()->state_ID()
173
-                            );
174
-                    } elseif ($field_name === 'CNT_ISO') {
175
-                        $country = $registration->attendee()->country_obj();
176
-                        $value   = $country instanceof EE_Country
177
-                            ? $country->name()
178
-                            : sprintf(
179
-                                esc_html__('Unknown Country (%s)', "event_espresso"),
180
-                                $registration->attendee()->country_ID()
181
-                            );
182
-                    } else {
183
-                        $value = $registration->attendee()->get_pretty($field_name);
184
-                    }
185
-                    // if field name is blank, leave the value as null too
186
-                } else {
187
-                    $value = $registration->attendee()->get($field_name);
188
-                }
189
-            }
190
-            // if no field was found, leave value blank
191
-        }
192
-        return apply_filters(
193
-            'FHEE__EEM_Answer__get_attendee_question_answer_value__answer_value',
194
-            $value,
195
-            $registration,
196
-            $question_id,
197
-            $question_system_id
198
-        );
199
-    }
133
+	/**
134
+	 * Gets the string answer to the question for this registration's attendee
135
+	 *
136
+	 * @param EE_Registration $registration
137
+	 * @param int|string      $question_system_id if an INT this is understood to be the question's ID; if a string
138
+	 *                                            then it should be its QST_system value. Passing in the QST_system
139
+	 *                                            value is more efficient
140
+	 * @param boolean         $pretty_answer
141
+	 * @return string|null (if the registration has no attendee, or the question_system_id is not a QST_ID or
142
+	 *                                            QST_system for a question corresponding to an attendee field, returns
143
+	 *                                            null)
144
+	 * @throws EE_Error
145
+	 * @throws ReflectionException
146
+	 */
147
+	public function get_attendee_property_answer_value(
148
+		EE_Registration $registration,
149
+		$question_system_id = null,
150
+		$pretty_answer = false
151
+	) {
152
+		$value = null;
153
+		// backward compat: we still want to find the question's ID
154
+		if (is_numeric($question_system_id)) {
155
+			// find this question's QST_system value
156
+			$question_id        = $question_system_id;
157
+			$question_system_id = EEM_Question::instance()->get_var([['QST_ID' => $question_system_id]], 'QST_system');
158
+		} else {
159
+			$question_id = (int) EEM_Question::instance()->get_var([['QST_system' => $question_system_id]], 'QST_ID');
160
+		}
161
+		// only bother checking if the registration has an attendee
162
+		if ($registration->attendee() instanceof EE_Attendee) {
163
+			$field_name = EEM_Attendee::instance()->get_attendee_field_for_system_question($question_system_id);
164
+			if ($field_name) {
165
+				if ($pretty_answer) {
166
+					if ($field_name === 'STA_ID') {
167
+						$state = $registration->attendee()->state_obj();
168
+						$value = $state instanceof EE_State
169
+							? $state->name()
170
+							: sprintf(
171
+								esc_html__('Unknown State (%s)', 'event_espresso'),
172
+								$registration->attendee()->state_ID()
173
+							);
174
+					} elseif ($field_name === 'CNT_ISO') {
175
+						$country = $registration->attendee()->country_obj();
176
+						$value   = $country instanceof EE_Country
177
+							? $country->name()
178
+							: sprintf(
179
+								esc_html__('Unknown Country (%s)', "event_espresso"),
180
+								$registration->attendee()->country_ID()
181
+							);
182
+					} else {
183
+						$value = $registration->attendee()->get_pretty($field_name);
184
+					}
185
+					// if field name is blank, leave the value as null too
186
+				} else {
187
+					$value = $registration->attendee()->get($field_name);
188
+				}
189
+			}
190
+			// if no field was found, leave value blank
191
+		}
192
+		return apply_filters(
193
+			'FHEE__EEM_Answer__get_attendee_question_answer_value__answer_value',
194
+			$value,
195
+			$registration,
196
+			$question_id,
197
+			$question_system_id
198
+		);
199
+	}
200 200
 }
Please login to merge, or discard this patch.
core/db_models/EEM_Question_Group_Question.model.php 1 patch
Indentation   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -13,67 +13,67 @@
 block discarded – undo
13 13
  */
14 14
 class EEM_Question_Group_Question extends EEM_Base
15 15
 {
16
-    protected static ?EEM_Question_Group_Question $_instance = null;
16
+	protected static ?EEM_Question_Group_Question $_instance = null;
17 17
 
18 18
 
19
-    /**
20
-     * @param string|null $timezone
21
-     * @throws EE_Error
22
-     */
23
-    protected function __construct(?string $timezone = '')
24
-    {
25
-        $this->singular_item    = esc_html__('Question Group to Question Link', 'event_espresso');
26
-        $this->plural_item      = esc_html__('Question Group to Question Links', 'event_espresso');
27
-        $this->_tables          = [
28
-            'Question_Group_Question' => new EE_Primary_Table('esp_question_group_question', 'QGQ_ID'),
29
-        ];
30
-        $this->_fields          = [
31
-            'Question_Group_Question' => [
32
-                'QGQ_ID'    => new EE_Primary_Key_Int_Field(
33
-                    'QGQ_ID',
34
-                    esc_html__('Question Group to Question Link ID', 'event_espresso')
35
-                ),
36
-                'QSG_ID'    => new EE_Foreign_Key_Int_Field(
37
-                    'QSG_ID',
38
-                    esc_html__('Question Group ID', 'event_espresso'),
39
-                    false,
40
-                    0,
41
-                    'Question_Group'
42
-                ),
43
-                'QST_ID'    => new EE_Foreign_Key_Int_Field(
44
-                    'QST_ID',
45
-                    esc_html__('Question Id', 'event_espresso'),
46
-                    false,
47
-                    0,
48
-                    'Question'
49
-                ),
50
-                'QGQ_order' => new EE_Integer_Field(
51
-                    'QGQ_order',
52
-                    esc_html__('Question Group Question Order', 'event_espresso'),
53
-                    false,
54
-                    0
55
-                ),
56
-            ],
57
-        ];
58
-        $this->_model_relations = [
59
-            'Question_Group' => new EE_Belongs_To_Relation(),
60
-            'Question'       => new EE_Belongs_To_Relation(),
61
-        ];
19
+	/**
20
+	 * @param string|null $timezone
21
+	 * @throws EE_Error
22
+	 */
23
+	protected function __construct(?string $timezone = '')
24
+	{
25
+		$this->singular_item    = esc_html__('Question Group to Question Link', 'event_espresso');
26
+		$this->plural_item      = esc_html__('Question Group to Question Links', 'event_espresso');
27
+		$this->_tables          = [
28
+			'Question_Group_Question' => new EE_Primary_Table('esp_question_group_question', 'QGQ_ID'),
29
+		];
30
+		$this->_fields          = [
31
+			'Question_Group_Question' => [
32
+				'QGQ_ID'    => new EE_Primary_Key_Int_Field(
33
+					'QGQ_ID',
34
+					esc_html__('Question Group to Question Link ID', 'event_espresso')
35
+				),
36
+				'QSG_ID'    => new EE_Foreign_Key_Int_Field(
37
+					'QSG_ID',
38
+					esc_html__('Question Group ID', 'event_espresso'),
39
+					false,
40
+					0,
41
+					'Question_Group'
42
+				),
43
+				'QST_ID'    => new EE_Foreign_Key_Int_Field(
44
+					'QST_ID',
45
+					esc_html__('Question Id', 'event_espresso'),
46
+					false,
47
+					0,
48
+					'Question'
49
+				),
50
+				'QGQ_order' => new EE_Integer_Field(
51
+					'QGQ_order',
52
+					esc_html__('Question Group Question Order', 'event_espresso'),
53
+					false,
54
+					0
55
+				),
56
+			],
57
+		];
58
+		$this->_model_relations = [
59
+			'Question_Group' => new EE_Belongs_To_Relation(),
60
+			'Question'       => new EE_Belongs_To_Relation(),
61
+		];
62 62
 
63
-        $this->_model_chain_to_wp_user = 'Question_Group';
63
+		$this->_model_chain_to_wp_user = 'Question_Group';
64 64
 
65
-        // this model is generally available for reading
66
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ]       =
67
-            new EE_Restriction_Generator_Public();
68
-        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] =
69
-            new EE_Restriction_Generator_Reg_Form('Question_Group.QSG_system');
70
-        $this->_cap_restriction_generators[ EEM_Base::caps_edit ]       =
71
-            new EE_Restriction_Generator_Reg_Form('Question_Group.QSG_system');
72
-        $this->_cap_restriction_generators[ EEM_Base::caps_delete ]     =
73
-            new EE_Restriction_Generator_Reg_Form('Question_Group.QSG_system');
65
+		// this model is generally available for reading
66
+		$this->_cap_restriction_generators[ EEM_Base::caps_read ]       =
67
+			new EE_Restriction_Generator_Public();
68
+		$this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] =
69
+			new EE_Restriction_Generator_Reg_Form('Question_Group.QSG_system');
70
+		$this->_cap_restriction_generators[ EEM_Base::caps_edit ]       =
71
+			new EE_Restriction_Generator_Reg_Form('Question_Group.QSG_system');
72
+		$this->_cap_restriction_generators[ EEM_Base::caps_delete ]     =
73
+			new EE_Restriction_Generator_Reg_Form('Question_Group.QSG_system');
74 74
 
75
-        // use the caps for question groups
76
-        $this->_caps_slug = 'question_groups';
77
-        parent::__construct($timezone);
78
-    }
75
+		// use the caps for question groups
76
+		$this->_caps_slug = 'question_groups';
77
+		parent::__construct($timezone);
78
+	}
79 79
 }
Please login to merge, or discard this patch.
core/db_models/EEM_Extra_Meta.model.php 1 patch
Indentation   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -14,58 +14,58 @@
 block discarded – undo
14 14
  */
15 15
 class EEM_Extra_Meta extends EEM_Base
16 16
 {
17
-    protected static ?EEM_Extra_Meta $_instance = null;
17
+	protected static ?EEM_Extra_Meta $_instance = null;
18 18
 
19 19
 
20
-    /**
21
-     * @param string|null $timezone
22
-     * @throws EE_Error
23
-     */
24
-    protected function __construct(?string $timezone = '')
25
-    {
26
-        $this->singular_item       = esc_html__('Extra Meta', 'event_espresso');
27
-        $this->plural_item         = esc_html__('Extra Metas', 'event_espresso');
28
-        $this->_tables             = [
29
-            'Extra_Meta' => new EE_Primary_Table('esp_extra_meta', 'EXM_ID'),
30
-        ];
31
-        $models_this_can_attach_to = array_keys(EE_Registry::instance()->non_abstract_db_models);
32
-        $this->_fields             = [
33
-            'Extra_Meta' => [
34
-                'EXM_ID'    => new EE_Primary_Key_Int_Field('EXM_ID', esc_html__("Extra Meta ID", "event_espresso")),
35
-                'OBJ_ID'    => new EE_Foreign_Key_Int_Field(
36
-                    'OBJ_ID',
37
-                    esc_html__("Primary Key of Attached Thing", "event_espresso"),
38
-                    false,
39
-                    0,
40
-                    $models_this_can_attach_to
41
-                ),
42
-                'EXM_type'  => new EE_Any_Foreign_Model_Name_Field(
43
-                    'EXM_type',
44
-                    esc_html__(
45
-                        "Model of Attached Thing",
46
-                        "event_espresso"
47
-                    ),
48
-                    false,
49
-                    'Transaction',
50
-                    $models_this_can_attach_to
51
-                ),
52
-                'EXM_key'   => new EE_Plain_Text_Field('EXM_key', esc_html__("Meta Key", "event_espresso"), false, ''),
53
-                'EXM_value' => new EE_Maybe_Serialized_Text_Field(
54
-                    'EXM_value',
55
-                    esc_html__("Meta Value", "event_espresso"),
56
-                    true
57
-                ),
20
+	/**
21
+	 * @param string|null $timezone
22
+	 * @throws EE_Error
23
+	 */
24
+	protected function __construct(?string $timezone = '')
25
+	{
26
+		$this->singular_item       = esc_html__('Extra Meta', 'event_espresso');
27
+		$this->plural_item         = esc_html__('Extra Metas', 'event_espresso');
28
+		$this->_tables             = [
29
+			'Extra_Meta' => new EE_Primary_Table('esp_extra_meta', 'EXM_ID'),
30
+		];
31
+		$models_this_can_attach_to = array_keys(EE_Registry::instance()->non_abstract_db_models);
32
+		$this->_fields             = [
33
+			'Extra_Meta' => [
34
+				'EXM_ID'    => new EE_Primary_Key_Int_Field('EXM_ID', esc_html__("Extra Meta ID", "event_espresso")),
35
+				'OBJ_ID'    => new EE_Foreign_Key_Int_Field(
36
+					'OBJ_ID',
37
+					esc_html__("Primary Key of Attached Thing", "event_espresso"),
38
+					false,
39
+					0,
40
+					$models_this_can_attach_to
41
+				),
42
+				'EXM_type'  => new EE_Any_Foreign_Model_Name_Field(
43
+					'EXM_type',
44
+					esc_html__(
45
+						"Model of Attached Thing",
46
+						"event_espresso"
47
+					),
48
+					false,
49
+					'Transaction',
50
+					$models_this_can_attach_to
51
+				),
52
+				'EXM_key'   => new EE_Plain_Text_Field('EXM_key', esc_html__("Meta Key", "event_espresso"), false, ''),
53
+				'EXM_value' => new EE_Maybe_Serialized_Text_Field(
54
+					'EXM_value',
55
+					esc_html__("Meta Value", "event_espresso"),
56
+					true
57
+				),
58 58
 
59
-            ],
60
-        ];
61
-        $this->_model_relations    = [];
62
-        foreach ($models_this_can_attach_to as $model) {
63
-            $this->_model_relations[ $model ] = new EE_Belongs_To_Any_Relation();
64
-        }
65
-        foreach ($this->cap_contexts_to_cap_action_map() as $cap_context => $action) {
66
-            $this->_cap_restriction_generators[ $cap_context ] =
67
-                new EE_Restriction_Generator_Meta('EXM_key', 'EXM_value');
68
-        }
69
-        parent::__construct($timezone);
70
-    }
59
+			],
60
+		];
61
+		$this->_model_relations    = [];
62
+		foreach ($models_this_can_attach_to as $model) {
63
+			$this->_model_relations[ $model ] = new EE_Belongs_To_Any_Relation();
64
+		}
65
+		foreach ($this->cap_contexts_to_cap_action_map() as $cap_context => $action) {
66
+			$this->_cap_restriction_generators[ $cap_context ] =
67
+				new EE_Restriction_Generator_Meta('EXM_key', 'EXM_value');
68
+		}
69
+		parent::__construct($timezone);
70
+	}
71 71
 }
Please login to merge, or discard this patch.