Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like EEM_Base often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use EEM_Base, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
36 | abstract class EEM_Base extends EE_Base implements ResettableInterface |
||
37 | { |
||
38 | |||
39 | /** |
||
40 | * Flag to indicate whether the values provided to EEM_Base have already been prepared |
||
41 | * by the model object or not (ie, the model object has used the field's _prepare_for_set function on the values). |
||
42 | * They almost always WILL NOT, but it's not necessarily a requirement. |
||
43 | * For example, if you want to run EEM_Event::instance()->get_all(array(array('EVT_ID'=>$_GET['event_id']))); |
||
44 | * |
||
45 | * @var boolean |
||
46 | */ |
||
47 | private $_values_already_prepared_by_model_object = 0; |
||
48 | |||
49 | /** |
||
50 | * when $_values_already_prepared_by_model_object equals this, we assume |
||
51 | * the data is just like form input that needs to have the model fields' |
||
52 | * prepare_for_set and prepare_for_use_in_db called on it |
||
53 | */ |
||
54 | const not_prepared_by_model_object = 0; |
||
55 | |||
56 | /** |
||
57 | * when $_values_already_prepared_by_model_object equals this, we |
||
58 | * assume this value is coming from a model object and doesn't need to have |
||
59 | * prepare_for_set called on it, just prepare_for_use_in_db is used |
||
60 | */ |
||
61 | const prepared_by_model_object = 1; |
||
62 | |||
63 | /** |
||
64 | * when $_values_already_prepared_by_model_object equals this, we assume |
||
65 | * the values are already to be used in the database (ie no processing is done |
||
66 | * on them by the model's fields) |
||
67 | */ |
||
68 | const prepared_for_use_in_db = 2; |
||
69 | |||
70 | |||
71 | protected $singular_item = 'Item'; |
||
72 | |||
73 | protected $plural_item = 'Items'; |
||
74 | |||
75 | /** |
||
76 | * @type \EE_Table_Base[] $_tables array of EE_Table objects for defining which tables comprise this model. |
||
77 | */ |
||
78 | protected $_tables; |
||
79 | |||
80 | /** |
||
81 | * with two levels: top-level has array keys which are database table aliases (ie, keys in _tables) |
||
82 | * and the value is an array. Each of those sub-arrays have keys of field names (eg 'ATT_ID', which should also be |
||
83 | * variable names on the model objects (eg, EE_Attendee), and the keys should be children of EE_Model_Field |
||
84 | * |
||
85 | * @var \EE_Model_Field_Base[][] $_fields |
||
86 | */ |
||
87 | protected $_fields; |
||
88 | |||
89 | /** |
||
90 | * array of different kinds of relations |
||
91 | * |
||
92 | * @var \EE_Model_Relation_Base[] $_model_relations |
||
93 | */ |
||
94 | protected $_model_relations; |
||
95 | |||
96 | /** |
||
97 | * @var \EE_Index[] $_indexes |
||
98 | */ |
||
99 | protected $_indexes = array(); |
||
100 | |||
101 | /** |
||
102 | * Default strategy for getting where conditions on this model. This strategy is used to get default |
||
103 | * where conditions which are added to get_all, update, and delete queries. They can be overridden |
||
104 | * by setting the same columns as used in these queries in the query yourself. |
||
105 | * |
||
106 | * @var EE_Default_Where_Conditions |
||
107 | */ |
||
108 | protected $_default_where_conditions_strategy; |
||
109 | |||
110 | /** |
||
111 | * Strategy for getting conditions on this model when 'default_where_conditions' equals 'minimum'. |
||
112 | * This is particularly useful when you want something between 'none' and 'default' |
||
113 | * |
||
114 | * @var EE_Default_Where_Conditions |
||
115 | */ |
||
116 | protected $_minimum_where_conditions_strategy; |
||
117 | |||
118 | /** |
||
119 | * String describing how to find the "owner" of this model's objects. |
||
120 | * When there is a foreign key on this model to the wp_users table, this isn't needed. |
||
121 | * But when there isn't, this indicates which related model, or transiently-related model, |
||
122 | * has the foreign key to the wp_users table. |
||
123 | * Eg, for EEM_Registration this would be 'Event' because registrations are directly |
||
124 | * related to events, and events have a foreign key to wp_users. |
||
125 | * On EEM_Transaction, this would be 'Transaction.Event' |
||
126 | * |
||
127 | * @var string |
||
128 | */ |
||
129 | protected $_model_chain_to_wp_user = ''; |
||
130 | |||
131 | /** |
||
132 | * String describing how to find the model with a password controlling access to this model. This property has the |
||
133 | * same format as $_model_chain_to_wp_user. This is primarily used by the query param "exclude_protected". |
||
134 | * This value is the path of models to follow to arrive at the model with the password field. |
||
135 | * If it is an empty string, it means this model has the password field. If it is null, it means there is no |
||
136 | * model with a password that should affect reading this on the front-end. |
||
137 | * Eg this is an empty string for the Event model because it has a password. |
||
138 | * This is null for the Registration model, because its event's password has no bearing on whether |
||
139 | * you can read the registration or not on the front-end (it just depends on your capabilities.) |
||
140 | * This is 'Datetime.Event' on the Ticket model, because model queries for tickets that set "exclude_protected" |
||
141 | * should hide tickets for datetimes for events that have a password set. |
||
142 | * @var string |null |
||
143 | */ |
||
144 | protected $model_chain_to_password = null; |
||
145 | |||
146 | /** |
||
147 | * This is a flag typically set by updates so that we don't load the where strategy on updates because updates |
||
148 | * don't need it (particularly CPT models) |
||
149 | * |
||
150 | * @var bool |
||
151 | */ |
||
152 | protected $_ignore_where_strategy = false; |
||
153 | |||
154 | /** |
||
155 | * String used in caps relating to this model. Eg, if the caps relating to this |
||
156 | * model are 'ee_edit_events', 'ee_read_events', etc, it would be 'events'. |
||
157 | * |
||
158 | * @var string. If null it hasn't been initialized yet. If false then we |
||
159 | * have indicated capabilities don't apply to this |
||
160 | */ |
||
161 | protected $_caps_slug = null; |
||
162 | |||
163 | /** |
||
164 | * 2d array where top-level keys are one of EEM_Base::valid_cap_contexts(), |
||
165 | * and next-level keys are capability names, and each's value is a |
||
166 | * EE_Default_Where_Condition. If the requester requests to apply caps to the query, |
||
167 | * they specify which context to use (ie, frontend, backend, edit or delete) |
||
168 | * and then each capability in the corresponding sub-array that they're missing |
||
169 | * adds the where conditions onto the query. |
||
170 | * |
||
171 | * @var array |
||
172 | */ |
||
173 | protected $_cap_restrictions = array( |
||
174 | self::caps_read => array(), |
||
175 | self::caps_read_admin => array(), |
||
176 | self::caps_edit => array(), |
||
177 | self::caps_delete => array(), |
||
178 | ); |
||
179 | |||
180 | /** |
||
181 | * Array defining which cap restriction generators to use to create default |
||
182 | * cap restrictions to put in EEM_Base::_cap_restrictions. |
||
183 | * Array-keys are one of EEM_Base::valid_cap_contexts(), and values are a child of |
||
184 | * EE_Restriction_Generator_Base. If you don't want any cap restrictions generated |
||
185 | * automatically set this to false (not just null). |
||
186 | * |
||
187 | * @var EE_Restriction_Generator_Base[] |
||
188 | */ |
||
189 | protected $_cap_restriction_generators = array(); |
||
190 | |||
191 | /** |
||
192 | * constants used to categorize capability restrictions on EEM_Base::_caps_restrictions |
||
193 | */ |
||
194 | const caps_read = 'read'; |
||
195 | |||
196 | const caps_read_admin = 'read_admin'; |
||
197 | |||
198 | const caps_edit = 'edit'; |
||
199 | |||
200 | const caps_delete = 'delete'; |
||
201 | |||
202 | /** |
||
203 | * Keys are all the cap contexts (ie constants EEM_Base::_caps_*) and values are their 'action' |
||
204 | * as how they'd be used in capability names. Eg EEM_Base::caps_read ('read_frontend') |
||
205 | * maps to 'read' because when looking for relevant permissions we're going to use |
||
206 | * 'read' in teh capabilities names like 'ee_read_events' etc. |
||
207 | * |
||
208 | * @var array |
||
209 | */ |
||
210 | protected $_cap_contexts_to_cap_action_map = array( |
||
211 | self::caps_read => 'read', |
||
212 | self::caps_read_admin => 'read', |
||
213 | self::caps_edit => 'edit', |
||
214 | self::caps_delete => 'delete', |
||
215 | ); |
||
216 | |||
217 | /** |
||
218 | * Timezone |
||
219 | * This gets set via the constructor so that we know what timezone incoming strings|timestamps are in when there |
||
220 | * are EE_Datetime_Fields in use. This can also be used before a get to set what timezone you want strings coming |
||
221 | * out of the created objects. NOT all EEM_Base child classes use this property but any that use a |
||
222 | * EE_Datetime_Field data type will have access to it. |
||
223 | * |
||
224 | * @var string |
||
225 | */ |
||
226 | protected $_timezone; |
||
227 | |||
228 | |||
229 | /** |
||
230 | * This holds the id of the blog currently making the query. Has no bearing on single site but is used for |
||
231 | * multisite. |
||
232 | * |
||
233 | * @var int |
||
234 | */ |
||
235 | protected static $_model_query_blog_id; |
||
236 | |||
237 | /** |
||
238 | * A copy of _fields, except the array keys are the model names pointed to by |
||
239 | * the field |
||
240 | * |
||
241 | * @var EE_Model_Field_Base[] |
||
242 | */ |
||
243 | private $_cache_foreign_key_to_fields = array(); |
||
244 | |||
245 | /** |
||
246 | * Cached list of all the fields on the model, indexed by their name |
||
247 | * |
||
248 | * @var EE_Model_Field_Base[] |
||
249 | */ |
||
250 | private $_cached_fields = null; |
||
251 | |||
252 | /** |
||
253 | * Cached list of all the fields on the model, except those that are |
||
254 | * marked as only pertinent to the database |
||
255 | * |
||
256 | * @var EE_Model_Field_Base[] |
||
257 | */ |
||
258 | private $_cached_fields_non_db_only = null; |
||
259 | |||
260 | /** |
||
261 | * A cached reference to the primary key for quick lookup |
||
262 | * |
||
263 | * @var EE_Model_Field_Base |
||
264 | */ |
||
265 | private $_primary_key_field = null; |
||
266 | |||
267 | /** |
||
268 | * Flag indicating whether this model has a primary key or not |
||
269 | * |
||
270 | * @var boolean |
||
271 | */ |
||
272 | protected $_has_primary_key_field = null; |
||
273 | |||
274 | /** |
||
275 | * Whether or not this model is based off a table in WP core only (CPTs should set |
||
276 | * this to FALSE, but if we were to make an EE_WP_Post model, it should set this to true). |
||
277 | * This should be true for models that deal with data that should exist independent of EE. |
||
278 | * For example, if the model can read and insert data that isn't used by EE, this should be true. |
||
279 | * It would be false, however, if you could guarantee the model would only interact with EE data, |
||
280 | * even if it uses a WP core table (eg event and venue models set this to false for that reason: |
||
281 | * they can only read and insert events and venues custom post types, not arbitrary post types) |
||
282 | * @var boolean |
||
283 | */ |
||
284 | protected $_wp_core_model = false; |
||
285 | |||
286 | /** |
||
287 | * @var bool stores whether this model has a password field or not. |
||
288 | * null until initialized by hasPasswordField() |
||
289 | */ |
||
290 | protected $has_password_field; |
||
291 | |||
292 | /** |
||
293 | * @var EE_Password_Field|null Automatically set when calling getPasswordField() |
||
294 | */ |
||
295 | protected $password_field; |
||
296 | |||
297 | /** |
||
298 | * List of valid operators that can be used for querying. |
||
299 | * The keys are all operators we'll accept, the values are the real SQL |
||
300 | * operators used |
||
301 | * |
||
302 | * @var array |
||
303 | */ |
||
304 | protected $_valid_operators = array( |
||
305 | '=' => '=', |
||
306 | '<=' => '<=', |
||
307 | '<' => '<', |
||
308 | '>=' => '>=', |
||
309 | '>' => '>', |
||
310 | '!=' => '!=', |
||
311 | 'LIKE' => 'LIKE', |
||
312 | 'like' => 'LIKE', |
||
313 | 'NOT_LIKE' => 'NOT LIKE', |
||
314 | 'not_like' => 'NOT LIKE', |
||
315 | 'NOT LIKE' => 'NOT LIKE', |
||
316 | 'not like' => 'NOT LIKE', |
||
317 | 'IN' => 'IN', |
||
318 | 'in' => 'IN', |
||
319 | 'NOT_IN' => 'NOT IN', |
||
320 | 'not_in' => 'NOT IN', |
||
321 | 'NOT IN' => 'NOT IN', |
||
322 | 'not in' => 'NOT IN', |
||
323 | 'between' => 'BETWEEN', |
||
324 | 'BETWEEN' => 'BETWEEN', |
||
325 | 'IS_NOT_NULL' => 'IS NOT NULL', |
||
326 | 'is_not_null' => 'IS NOT NULL', |
||
327 | 'IS NOT NULL' => 'IS NOT NULL', |
||
328 | 'is not null' => 'IS NOT NULL', |
||
329 | 'IS_NULL' => 'IS NULL', |
||
330 | 'is_null' => 'IS NULL', |
||
331 | 'IS NULL' => 'IS NULL', |
||
332 | 'is null' => 'IS NULL', |
||
333 | 'REGEXP' => 'REGEXP', |
||
334 | 'regexp' => 'REGEXP', |
||
335 | 'NOT_REGEXP' => 'NOT REGEXP', |
||
336 | 'not_regexp' => 'NOT REGEXP', |
||
337 | 'NOT REGEXP' => 'NOT REGEXP', |
||
338 | 'not regexp' => 'NOT REGEXP', |
||
339 | ); |
||
340 | |||
341 | /** |
||
342 | * operators that work like 'IN', accepting a comma-separated list of values inside brackets. Eg '(1,2,3)' |
||
343 | * |
||
344 | * @var array |
||
345 | */ |
||
346 | protected $_in_style_operators = array('IN', 'NOT IN'); |
||
347 | |||
348 | /** |
||
349 | * operators that work like 'BETWEEN'. Typically used for datetime calculations, i.e. "BETWEEN '12-1-2011' AND |
||
350 | * '12-31-2012'" |
||
351 | * |
||
352 | * @var array |
||
353 | */ |
||
354 | protected $_between_style_operators = array('BETWEEN'); |
||
355 | |||
356 | /** |
||
357 | * Operators that work like SQL's like: input should be assumed to be a string, already prepared for a LIKE query. |
||
358 | * @var array |
||
359 | */ |
||
360 | protected $_like_style_operators = array('LIKE', 'NOT LIKE'); |
||
361 | /** |
||
362 | * operators that are used for handling NUll and !NULL queries. Typically used for when checking if a row exists |
||
363 | * on a join table. |
||
364 | * |
||
365 | * @var array |
||
366 | */ |
||
367 | protected $_null_style_operators = array('IS NOT NULL', 'IS NULL'); |
||
368 | |||
369 | /** |
||
370 | * Allowed values for $query_params['order'] for ordering in queries |
||
371 | * |
||
372 | * @var array |
||
373 | */ |
||
374 | protected $_allowed_order_values = array('asc', 'desc', 'ASC', 'DESC'); |
||
375 | |||
376 | /** |
||
377 | * When these are keys in a WHERE or HAVING clause, they are handled much differently |
||
378 | * than regular field names. It is assumed that their values are an array of WHERE conditions |
||
379 | * |
||
380 | * @var array |
||
381 | */ |
||
382 | private $_logic_query_param_keys = array('not', 'and', 'or', 'NOT', 'AND', 'OR'); |
||
383 | |||
384 | /** |
||
385 | * Allowed keys in $query_params arrays passed into queries. Note that 0 is meant to always be a |
||
386 | * 'where', but 'where' clauses are so common that we thought we'd omit it |
||
387 | * |
||
388 | * @var array |
||
389 | */ |
||
390 | private $_allowed_query_params = array( |
||
391 | 0, |
||
392 | 'limit', |
||
393 | 'order_by', |
||
394 | 'group_by', |
||
395 | 'having', |
||
396 | 'force_join', |
||
397 | 'order', |
||
398 | 'on_join_limit', |
||
399 | 'default_where_conditions', |
||
400 | 'caps', |
||
401 | 'extra_selects', |
||
402 | 'exclude_protected', |
||
403 | ); |
||
404 | |||
405 | /** |
||
406 | * All the data types that can be used in $wpdb->prepare statements. |
||
407 | * |
||
408 | * @var array |
||
409 | */ |
||
410 | private $_valid_wpdb_data_types = array('%d', '%s', '%f'); |
||
411 | |||
412 | /** |
||
413 | * @var EE_Registry $EE |
||
414 | */ |
||
415 | protected $EE = null; |
||
416 | |||
417 | |||
418 | /** |
||
419 | * Property which, when set, will have this model echo out the next X queries to the page for debugging. |
||
420 | * |
||
421 | * @var int |
||
422 | */ |
||
423 | protected $_show_next_x_db_queries = 0; |
||
424 | |||
425 | /** |
||
426 | * When using _get_all_wpdb_results, you can specify a custom selection. If you do so, |
||
427 | * it gets saved on this property as an instance of CustomSelects so those selections can be used in |
||
428 | * WHERE, GROUP_BY, etc. |
||
429 | * |
||
430 | * @var CustomSelects |
||
431 | */ |
||
432 | protected $_custom_selections = array(); |
||
433 | |||
434 | /** |
||
435 | * key => value Entity Map using array( EEM_Base::$_model_query_blog_id => array( ID => model object ) ) |
||
436 | * caches every model object we've fetched from the DB on this request |
||
437 | * |
||
438 | * @var array |
||
439 | */ |
||
440 | protected $_entity_map; |
||
441 | |||
442 | /** |
||
443 | * @var LoaderInterface $loader |
||
444 | */ |
||
445 | private static $loader; |
||
446 | |||
447 | |||
448 | /** |
||
449 | * constant used to show EEM_Base has not yet verified the db on this http request |
||
450 | */ |
||
451 | const db_verified_none = 0; |
||
452 | |||
453 | /** |
||
454 | * constant used to show EEM_Base has verified the EE core db on this http request, |
||
455 | * but not the addons' dbs |
||
456 | */ |
||
457 | const db_verified_core = 1; |
||
458 | |||
459 | /** |
||
460 | * constant used to show EEM_Base has verified the addons' dbs (and implicitly |
||
461 | * the EE core db too) |
||
462 | */ |
||
463 | const db_verified_addons = 2; |
||
464 | |||
465 | /** |
||
466 | * indicates whether an EEM_Base child has already re-verified the DB |
||
467 | * is ok (we don't want to do it repetitively). Should be set to one the constants |
||
468 | * looking like EEM_Base::db_verified_* |
||
469 | * |
||
470 | * @var int - 0 = none, 1 = core, 2 = addons |
||
471 | */ |
||
472 | protected static $_db_verification_level = EEM_Base::db_verified_none; |
||
473 | |||
474 | /** |
||
475 | * @const constant for 'default_where_conditions' to apply default where conditions to ALL queried models |
||
476 | * (eg, if retrieving registrations ordered by their datetimes, this will only return non-trashed |
||
477 | * registrations for non-trashed tickets for non-trashed datetimes) |
||
478 | */ |
||
479 | const default_where_conditions_all = 'all'; |
||
480 | |||
481 | /** |
||
482 | * @const constant for 'default_where_conditions' to apply default where conditions to THIS model only, but |
||
483 | * no other models which are joined to (eg, if retrieving registrations ordered by their datetimes, this will |
||
484 | * return non-trashed registrations, regardless of the related datetimes and tickets' statuses). |
||
485 | * It is preferred to use EEM_Base::default_where_conditions_minimum_others because, when joining to |
||
486 | * models which share tables with other models, this can return data for the wrong model. |
||
487 | */ |
||
488 | const default_where_conditions_this_only = 'this_model_only'; |
||
489 | |||
490 | /** |
||
491 | * @const constant for 'default_where_conditions' to apply default where conditions to other models queried, |
||
492 | * but not the current model (eg, if retrieving registrations ordered by their datetimes, this will |
||
493 | * return all registrations related to non-trashed tickets and non-trashed datetimes) |
||
494 | */ |
||
495 | const default_where_conditions_others_only = 'other_models_only'; |
||
496 | |||
497 | /** |
||
498 | * @const constant for 'default_where_conditions' to apply minimum where conditions to all models queried. |
||
499 | * For most models this the same as EEM_Base::default_where_conditions_none, except for models which share |
||
500 | * their table with other models, like the Event and Venue models. For example, when querying for events |
||
501 | * ordered by their venues' name, this will be sure to only return real events with associated real venues |
||
502 | * (regardless of whether those events and venues are trashed) |
||
503 | * In contrast, using EEM_Base::default_where_conditions_none would could return WP posts other than EE |
||
504 | * events. |
||
505 | */ |
||
506 | const default_where_conditions_minimum_all = 'minimum'; |
||
507 | |||
508 | /** |
||
509 | * @const constant for 'default_where_conditions' to apply apply where conditions to other models, and full default |
||
510 | * where conditions for the queried model (eg, when querying events ordered by venues' names, this will |
||
511 | * return non-trashed events for any venues, regardless of whether those associated venues are trashed or |
||
512 | * not) |
||
513 | */ |
||
514 | const default_where_conditions_minimum_others = 'full_this_minimum_others'; |
||
515 | |||
516 | /** |
||
517 | * @const constant for 'default_where_conditions' to NOT apply any where conditions. This should very rarely be |
||
518 | * used, because when querying from a model which shares its table with another model (eg Events and Venues) |
||
519 | * it's possible it will return table entries for other models. You should use |
||
520 | * EEM_Base::default_where_conditions_minimum_all instead. |
||
521 | */ |
||
522 | const default_where_conditions_none = 'none'; |
||
523 | |||
524 | |||
525 | |||
526 | /** |
||
527 | * About all child constructors: |
||
528 | * they should define the _tables, _fields and _model_relations arrays. |
||
529 | * Should ALWAYS be called after child constructor. |
||
530 | * In order to make the child constructors to be as simple as possible, this parent constructor |
||
531 | * finalizes constructing all the object's attributes. |
||
532 | * Generally, rather than requiring a child to code |
||
533 | * $this->_tables = array( |
||
534 | * 'Event_Post_Table' => new EE_Table('Event_Post_Table','wp_posts') |
||
535 | * ...); |
||
536 | * (thus repeating itself in the array key and in the constructor of the new EE_Table,) |
||
537 | * each EE_Table has a function to set the table's alias after the constructor, using |
||
538 | * the array key ('Event_Post_Table'), instead of repeating it. The model fields and model relations |
||
539 | * do something similar. |
||
540 | * |
||
541 | * @param null $timezone |
||
542 | * @throws EE_Error |
||
543 | */ |
||
544 | protected function __construct($timezone = null) |
||
686 | |||
687 | |||
688 | |||
689 | /** |
||
690 | * Used to set the $_model_query_blog_id static property. |
||
691 | * |
||
692 | * @param int $blog_id If provided then will set the blog_id for the models to this id. If not provided then the |
||
693 | * value for get_current_blog_id() will be used. |
||
694 | */ |
||
695 | public static function set_model_query_blog_id($blog_id = 0) |
||
699 | |||
700 | |||
701 | |||
702 | /** |
||
703 | * Returns whatever is set as the internal $model_query_blog_id. |
||
704 | * |
||
705 | * @return int |
||
706 | */ |
||
707 | public static function get_model_query_blog_id() |
||
711 | |||
712 | |||
713 | |||
714 | /** |
||
715 | * This function is a singleton method used to instantiate the Espresso_model object |
||
716 | * |
||
717 | * @param string $timezone string representing the timezone we want to set for returned Date Time Strings |
||
718 | * (and any incoming timezone data that gets saved). |
||
719 | * Note this just sends the timezone info to the date time model field objects. |
||
720 | * Default is NULL |
||
721 | * (and will be assumed using the set timezone in the 'timezone_string' wp option) |
||
722 | * @return static (as in the concrete child class) |
||
723 | * @throws EE_Error |
||
724 | * @throws InvalidArgumentException |
||
725 | * @throws InvalidDataTypeException |
||
726 | * @throws InvalidInterfaceException |
||
727 | */ |
||
728 | public static function instance($timezone = null) |
||
743 | |||
744 | |||
745 | |||
746 | /** |
||
747 | * resets the model and returns it |
||
748 | * |
||
749 | * @param null | string $timezone |
||
750 | * @return EEM_Base|null (if the model was already instantiated, returns it, with |
||
751 | * all its properties reset; if it wasn't instantiated, returns null) |
||
752 | * @throws EE_Error |
||
753 | * @throws ReflectionException |
||
754 | * @throws InvalidArgumentException |
||
755 | * @throws InvalidDataTypeException |
||
756 | * @throws InvalidInterfaceException |
||
757 | */ |
||
758 | public static function reset($timezone = null) |
||
783 | |||
784 | |||
785 | |||
786 | /** |
||
787 | * @return LoaderInterface |
||
788 | * @throws InvalidArgumentException |
||
789 | * @throws InvalidDataTypeException |
||
790 | * @throws InvalidInterfaceException |
||
791 | */ |
||
792 | private static function getLoader() |
||
799 | |||
800 | |||
801 | |||
802 | /** |
||
803 | * retrieve the status details from esp_status table as an array IF this model has the status table as a relation. |
||
804 | * |
||
805 | * @param boolean $translated return localized strings or JUST the array. |
||
806 | * @return array |
||
807 | * @throws EE_Error |
||
808 | * @throws InvalidArgumentException |
||
809 | * @throws InvalidDataTypeException |
||
810 | * @throws InvalidInterfaceException |
||
811 | */ |
||
812 | public function status_array($translated = false) |
||
828 | |||
829 | |||
830 | |||
831 | /** |
||
832 | * Gets all the EE_Base_Class objects which match the $query_params, by querying the DB. |
||
833 | * |
||
834 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
835 | * or if you have the development copy of EE you can view this at the path: |
||
836 | * /docs/G--Model-System/model-query-params.md |
||
837 | * @return EE_Base_Class[] *note that there is NO option to pass the output type. If you want results different |
||
838 | * from EE_Base_Class[], use get_all_wpdb_results(). Array keys are object IDs (if there is a primary key on the model. |
||
839 | * if not, numerically indexed) Some full examples: get 10 transactions |
||
840 | * which have Scottish attendees: EEM_Transaction::instance()->get_all( |
||
841 | * array( array( |
||
842 | * 'OR'=>array( |
||
843 | * 'Registration.Attendee.ATT_fname'=>array('like','Mc%'), |
||
844 | * 'Registration.Attendee.ATT_fname*other'=>array('like','Mac%') |
||
845 | * ) |
||
846 | * ), |
||
847 | * 'limit'=>10, |
||
848 | * 'group_by'=>'TXN_ID' |
||
849 | * )); |
||
850 | * get all the answers to the question titled "shirt size" for event with id |
||
851 | * 12, ordered by their answer EEM_Answer::instance()->get_all(array( array( |
||
852 | * 'Question.QST_display_text'=>'shirt size', |
||
853 | * 'Registration.Event.EVT_ID'=>12 |
||
854 | * ), |
||
855 | * 'order_by'=>array('ANS_value'=>'ASC') |
||
856 | * )); |
||
857 | * @throws EE_Error |
||
858 | */ |
||
859 | public function get_all($query_params = array()) |
||
868 | |||
869 | |||
870 | |||
871 | /** |
||
872 | * Modifies the query parameters so we only get back model objects |
||
873 | * that "belong" to the current user |
||
874 | * |
||
875 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
876 | * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
877 | */ |
||
878 | public function alter_query_params_to_only_include_mine($query_params = array()) |
||
886 | |||
887 | |||
888 | |||
889 | /** |
||
890 | * Returns the name of the field's name that points to the WP_User table |
||
891 | * on this model (or follows the _model_chain_to_wp_user and uses that model's |
||
892 | * foreign key to the WP_User table) |
||
893 | * |
||
894 | * @return string|boolean string on success, boolean false when there is no |
||
895 | * foreign key to the WP_User table |
||
896 | */ |
||
897 | public function wp_user_field_name() |
||
915 | |||
916 | |||
917 | |||
918 | /** |
||
919 | * Returns the _model_chain_to_wp_user string, which indicates which related model |
||
920 | * (or transiently-related model) has a foreign key to the wp_users table; |
||
921 | * useful for finding if model objects of this type are 'owned' by the current user. |
||
922 | * This is an empty string when the foreign key is on this model and when it isn't, |
||
923 | * but is only non-empty when this model's ownership is indicated by a RELATED model |
||
924 | * (or transiently-related model) |
||
925 | * |
||
926 | * @return string |
||
927 | */ |
||
928 | public function model_chain_to_wp_user() |
||
932 | |||
933 | |||
934 | |||
935 | /** |
||
936 | * Whether this model is 'owned' by a specific wordpress user (even indirectly, |
||
937 | * like how registrations don't have a foreign key to wp_users, but the |
||
938 | * events they are for are), or is unrelated to wp users. |
||
939 | * generally available |
||
940 | * |
||
941 | * @return boolean |
||
942 | */ |
||
943 | public function is_owned() |
||
955 | |||
956 | |||
957 | /** |
||
958 | * Used internally to get WPDB results, because other functions, besides get_all, may want to do some queries, but |
||
959 | * may want to preserve the WPDB results (eg, update, which first queries to make sure we have all the tables on |
||
960 | * the model) |
||
961 | * |
||
962 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
963 | * @param string $output ARRAY_A, OBJECT_K, etc. Just like |
||
964 | * @param mixed $columns_to_select , What columns to select. By default, we select all columns specified by the |
||
965 | * fields on the model, and the models we joined to in the query. However, you can |
||
966 | * override this and set the select to "*", or a specific column name, like |
||
967 | * "ATT_ID", etc. If you would like to use these custom selections in WHERE, |
||
968 | * GROUP_BY, or HAVING clauses, you must instead provide an array. Array keys are |
||
969 | * the aliases used to refer to this selection, and values are to be |
||
970 | * numerically-indexed arrays, where 0 is the selection and 1 is the data type. |
||
971 | * Eg, array('count'=>array('COUNT(REG_ID)','%d')) |
||
972 | * @return array | stdClass[] like results of $wpdb->get_results($sql,OBJECT), (ie, output type is OBJECT) |
||
973 | * @throws EE_Error |
||
974 | * @throws InvalidArgumentException |
||
975 | */ |
||
976 | protected function _get_all_wpdb_results($query_params = array(), $output = ARRAY_A, $columns_to_select = null) |
||
994 | |||
995 | |||
996 | /** |
||
997 | * Get a CustomSelects object if the $query_params or $columns_to_select allows for it. |
||
998 | * Note: $query_params['extra_selects'] will always override any $columns_to_select values. It is the preferred |
||
999 | * method of including extra select information. |
||
1000 | * |
||
1001 | * @param array $query_params |
||
1002 | * @param null|array|string $columns_to_select |
||
1003 | * @return null|CustomSelects |
||
1004 | * @throws InvalidArgumentException |
||
1005 | */ |
||
1006 | protected function getCustomSelection(array $query_params, $columns_to_select = null) |
||
1015 | |||
1016 | |||
1017 | |||
1018 | /** |
||
1019 | * Gets an array of rows from the database just like $wpdb->get_results would, |
||
1020 | * but you can use the model query params to more easily |
||
1021 | * take care of joins, field preparation etc. |
||
1022 | * |
||
1023 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
1024 | * @param string $output ARRAY_A, OBJECT_K, etc. Just like |
||
1025 | * @param mixed $columns_to_select , What columns to select. By default, we select all columns specified by the |
||
1026 | * fields on the model, and the models we joined to in the query. However, you can |
||
1027 | * override this and set the select to "*", or a specific column name, like |
||
1028 | * "ATT_ID", etc. If you would like to use these custom selections in WHERE, |
||
1029 | * GROUP_BY, or HAVING clauses, you must instead provide an array. Array keys are |
||
1030 | * the aliases used to refer to this selection, and values are to be |
||
1031 | * numerically-indexed arrays, where 0 is the selection and 1 is the data type. |
||
1032 | * Eg, array('count'=>array('COUNT(REG_ID)','%d')) |
||
1033 | * @return array|stdClass[] like results of $wpdb->get_results($sql,OBJECT), (ie, output type is OBJECT) |
||
1034 | * @throws EE_Error |
||
1035 | */ |
||
1036 | public function get_all_wpdb_results($query_params = array(), $output = ARRAY_A, $columns_to_select = null) |
||
1040 | |||
1041 | |||
1042 | |||
1043 | /** |
||
1044 | * For creating a custom select statement |
||
1045 | * |
||
1046 | * @param mixed $columns_to_select either a string to be inserted directly as the select statement, |
||
1047 | * or an array where keys are aliases, and values are arrays where 0=>the selection |
||
1048 | * SQL, and 1=>is the datatype |
||
1049 | * @throws EE_Error |
||
1050 | * @return string |
||
1051 | */ |
||
1052 | private function _construct_select_from_input($columns_to_select) |
||
1091 | |||
1092 | |||
1093 | |||
1094 | /** |
||
1095 | * Convenient wrapper for getting the primary key field's name. Eg, on Registration, this would be 'REG_ID' |
||
1096 | * |
||
1097 | * @return string |
||
1098 | * @throws EE_Error |
||
1099 | */ |
||
1100 | public function primary_key_name() |
||
1104 | |||
1105 | |||
1106 | |||
1107 | /** |
||
1108 | * Gets a single item for this model from the DB, given only its ID (or null if none is found). |
||
1109 | * If there is no primary key on this model, $id is treated as primary key string |
||
1110 | * |
||
1111 | * @param mixed $id int or string, depending on the type of the model's primary key |
||
1112 | * @return EE_Base_Class |
||
1113 | */ |
||
1114 | public function get_one_by_ID($id) |
||
1126 | |||
1127 | |||
1128 | |||
1129 | /** |
||
1130 | * Alters query parameters to only get items with this ID are returned. |
||
1131 | * Takes into account that the ID might be a string produced by EEM_Base::get_index_primary_key_string(), |
||
1132 | * or could just be a simple primary key ID |
||
1133 | * |
||
1134 | * @param int $id |
||
1135 | * @param array $query_params |
||
1136 | * @return array of normal query params, @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
1137 | * @throws EE_Error |
||
1138 | */ |
||
1139 | public function alter_query_params_to_restrict_by_ID($id, $query_params = array()) |
||
1153 | |||
1154 | |||
1155 | |||
1156 | /** |
||
1157 | * Gets a single item for this model from the DB, given the $query_params. Only returns a single class, not an |
||
1158 | * array. If no item is found, null is returned. |
||
1159 | * |
||
1160 | * @param array $query_params like EEM_Base's $query_params variable. |
||
1161 | * @return EE_Base_Class|EE_Soft_Delete_Base_Class|NULL |
||
1162 | * @throws EE_Error |
||
1163 | */ |
||
1164 | View Code Duplication | public function get_one($query_params = array()) |
|
1184 | |||
1185 | |||
1186 | |||
1187 | /** |
||
1188 | * Returns the next x number of items in sequence from the given value as |
||
1189 | * found in the database matching the given query conditions. |
||
1190 | * |
||
1191 | * @param mixed $current_field_value Value used for the reference point. |
||
1192 | * @param null $field_to_order_by What field is used for the |
||
1193 | * reference point. |
||
1194 | * @param int $limit How many to return. |
||
1195 | * @param array $query_params Extra conditions on the query. |
||
1196 | * @param null $columns_to_select If left null, then an array of |
||
1197 | * EE_Base_Class objects is returned, |
||
1198 | * otherwise you can indicate just the |
||
1199 | * columns you want returned. |
||
1200 | * @return EE_Base_Class[]|array |
||
1201 | * @throws EE_Error |
||
1202 | */ |
||
1203 | public function next_x( |
||
1219 | |||
1220 | |||
1221 | |||
1222 | /** |
||
1223 | * Returns the previous x number of items in sequence from the given value |
||
1224 | * as found in the database matching the given query conditions. |
||
1225 | * |
||
1226 | * @param mixed $current_field_value Value used for the reference point. |
||
1227 | * @param null $field_to_order_by What field is used for the |
||
1228 | * reference point. |
||
1229 | * @param int $limit How many to return. |
||
1230 | * @param array $query_params Extra conditions on the query. |
||
1231 | * @param null $columns_to_select If left null, then an array of |
||
1232 | * EE_Base_Class objects is returned, |
||
1233 | * otherwise you can indicate just the |
||
1234 | * columns you want returned. |
||
1235 | * @return EE_Base_Class[]|array |
||
1236 | * @throws EE_Error |
||
1237 | */ |
||
1238 | public function previous_x( |
||
1254 | |||
1255 | |||
1256 | |||
1257 | /** |
||
1258 | * Returns the next item in sequence from the given value as found in the |
||
1259 | * database matching the given query conditions. |
||
1260 | * |
||
1261 | * @param mixed $current_field_value Value used for the reference point. |
||
1262 | * @param null $field_to_order_by What field is used for the |
||
1263 | * reference point. |
||
1264 | * @param array $query_params Extra conditions on the query. |
||
1265 | * @param null $columns_to_select If left null, then an EE_Base_Class |
||
1266 | * object is returned, otherwise you |
||
1267 | * can indicate just the columns you |
||
1268 | * want and a single array indexed by |
||
1269 | * the columns will be returned. |
||
1270 | * @return EE_Base_Class|null|array() |
||
1271 | * @throws EE_Error |
||
1272 | */ |
||
1273 | View Code Duplication | public function next( |
|
1289 | |||
1290 | |||
1291 | |||
1292 | /** |
||
1293 | * Returns the previous item in sequence from the given value as found in |
||
1294 | * the database matching the given query conditions. |
||
1295 | * |
||
1296 | * @param mixed $current_field_value Value used for the reference point. |
||
1297 | * @param null $field_to_order_by What field is used for the |
||
1298 | * reference point. |
||
1299 | * @param array $query_params Extra conditions on the query. |
||
1300 | * @param null $columns_to_select If left null, then an EE_Base_Class |
||
1301 | * object is returned, otherwise you |
||
1302 | * can indicate just the columns you |
||
1303 | * want and a single array indexed by |
||
1304 | * the columns will be returned. |
||
1305 | * @return EE_Base_Class|null|array() |
||
1306 | * @throws EE_Error |
||
1307 | */ |
||
1308 | View Code Duplication | public function previous( |
|
1324 | |||
1325 | |||
1326 | |||
1327 | /** |
||
1328 | * Returns the a consecutive number of items in sequence from the given |
||
1329 | * value as found in the database matching the given query conditions. |
||
1330 | * |
||
1331 | * @param mixed $current_field_value Value used for the reference point. |
||
1332 | * @param string $operand What operand is used for the sequence. |
||
1333 | * @param string $field_to_order_by What field is used for the reference point. |
||
1334 | * @param int $limit How many to return. |
||
1335 | * @param array $query_params Extra conditions on the query. |
||
1336 | * @param null $columns_to_select If left null, then an array of EE_Base_Class objects is returned, |
||
1337 | * otherwise you can indicate just the columns you want returned. |
||
1338 | * @return EE_Base_Class[]|array |
||
1339 | * @throws EE_Error |
||
1340 | */ |
||
1341 | protected function _get_consecutive( |
||
1390 | |||
1391 | |||
1392 | |||
1393 | /** |
||
1394 | * This sets the _timezone property after model object has been instantiated. |
||
1395 | * |
||
1396 | * @param null | string $timezone valid PHP DateTimeZone timezone string |
||
1397 | */ |
||
1398 | public function set_timezone($timezone) |
||
1414 | |||
1415 | |||
1416 | |||
1417 | /** |
||
1418 | * This just returns whatever is set for the current timezone. |
||
1419 | * |
||
1420 | * @access public |
||
1421 | * @return string |
||
1422 | */ |
||
1423 | public function get_timezone() |
||
1440 | |||
1441 | |||
1442 | |||
1443 | /** |
||
1444 | * This returns the date formats set for the given field name and also ensures that |
||
1445 | * $this->_timezone property is set correctly. |
||
1446 | * |
||
1447 | * @since 4.6.x |
||
1448 | * @param string $field_name The name of the field the formats are being retrieved for. |
||
1449 | * @param bool $pretty Whether to return the pretty formats (true) or not (false). |
||
1450 | * @throws EE_Error If the given field_name is not of the EE_Datetime_Field type. |
||
1451 | * @return array formats in an array with the date format first, and the time format last. |
||
1452 | */ |
||
1453 | public function get_formats_for($field_name, $pretty = false) |
||
1468 | |||
1469 | |||
1470 | |||
1471 | /** |
||
1472 | * This returns the current time in a format setup for a query on this model. |
||
1473 | * Usage of this method makes it easier to setup queries against EE_Datetime_Field columns because |
||
1474 | * it will return: |
||
1475 | * - a formatted string in the timezone and format currently set on the EE_Datetime_Field for the given field for |
||
1476 | * NOW |
||
1477 | * - or a unix timestamp (equivalent to time()) |
||
1478 | * Note: When requesting a formatted string, if the date or time format doesn't include seconds, for example, |
||
1479 | * the time returned, because it uses that format, will also NOT include seconds. For this reason, if you want |
||
1480 | * the time returned to be the current time down to the exact second, set $timestamp to true. |
||
1481 | * @since 4.6.x |
||
1482 | * @param string $field_name The field the current time is needed for. |
||
1483 | * @param bool $timestamp True means to return a unix timestamp. Otherwise a |
||
1484 | * formatted string matching the set format for the field in the set timezone will |
||
1485 | * be returned. |
||
1486 | * @param string $what Whether to return the string in just the time format, the date format, or both. |
||
1487 | * @throws EE_Error If the given field_name is not of the EE_Datetime_Field type. |
||
1488 | * @return int|string If the given field_name is not of the EE_Datetime_Field type, then an EE_Error |
||
1489 | * exception is triggered. |
||
1490 | */ |
||
1491 | public function current_time_for_query($field_name, $timestamp = false, $what = 'both') |
||
1511 | |||
1512 | |||
1513 | |||
1514 | /** |
||
1515 | * This receives a time string for a given field and ensures that it is setup to match what the internal settings |
||
1516 | * for the model are. Returns a DateTime object. |
||
1517 | * Note: a gotcha for when you send in unix timestamp. Remember a unix timestamp is already timezone agnostic, |
||
1518 | * (functionally the equivalent of UTC+0). So when you send it in, whatever timezone string you include is |
||
1519 | * ignored. |
||
1520 | * |
||
1521 | * @param string $field_name The field being setup. |
||
1522 | * @param string $timestring The date time string being used. |
||
1523 | * @param string $incoming_format The format for the time string. |
||
1524 | * @param string $timezone By default, it is assumed the incoming time string is in timezone for |
||
1525 | * the blog. If this is not the case, then it can be specified here. If incoming |
||
1526 | * format is |
||
1527 | * 'U', this is ignored. |
||
1528 | * @return DateTime |
||
1529 | * @throws EE_Error |
||
1530 | */ |
||
1531 | public function convert_datetime_for_query($field_name, $timestring, $incoming_format, $timezone = '') |
||
1541 | |||
1542 | |||
1543 | |||
1544 | /** |
||
1545 | * Gets all the tables comprising this model. Array keys are the table aliases, and values are EE_Table objects |
||
1546 | * |
||
1547 | * @return EE_Table_Base[] |
||
1548 | */ |
||
1549 | public function get_tables() |
||
1553 | |||
1554 | |||
1555 | |||
1556 | /** |
||
1557 | * Updates all the database entries (in each table for this model) according to $fields_n_values and optionally |
||
1558 | * also updates all the model objects, where the criteria expressed in $query_params are met.. |
||
1559 | * Also note: if this model has multiple tables, this update verifies all the secondary tables have an entry for |
||
1560 | * each row (in the primary table) we're trying to update; if not, it inserts an entry in the secondary table. Eg: |
||
1561 | * if our model has 2 tables: wp_posts (primary), and wp_esp_event (secondary). Let's say we are trying to update a |
||
1562 | * model object with EVT_ID = 1 |
||
1563 | * (which means where wp_posts has ID = 1, because wp_posts.ID is the primary key's column), which exists, but |
||
1564 | * there is no entry in wp_esp_event for this entry in wp_posts. So, this update script will insert a row into |
||
1565 | * wp_esp_event, using any available parameters from $fields_n_values (eg, if "EVT_limit" => 40 is in |
||
1566 | * $fields_n_values, the new entry in wp_esp_event will set EVT_limit = 40, and use default for other columns which |
||
1567 | * are not specified) |
||
1568 | * |
||
1569 | * @param array $fields_n_values keys are model fields (exactly like keys in EEM_Base::_fields, NOT db |
||
1570 | * columns!), values are strings, ints, floats, and maybe arrays if they |
||
1571 | * are to be serialized. Basically, the values are what you'd expect to be |
||
1572 | * values on the model, NOT necessarily what's in the DB. For example, if |
||
1573 | * we wanted to update only the TXN_details on any Transactions where its |
||
1574 | * ID=34, we'd use this method as follows: |
||
1575 | * EEM_Transaction::instance()->update( |
||
1576 | * array('TXN_details'=>array('detail1'=>'monkey','detail2'=>'banana'), |
||
1577 | * array(array('TXN_ID'=>34))); |
||
1578 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
1579 | * Eg, consider updating Question's QST_admin_label field is of type |
||
1580 | * Simple_HTML. If you use this function to update that field to $new_value |
||
1581 | * = (note replace 8's with appropriate opening and closing tags in the |
||
1582 | * following example)"8script8alert('I hack all');8/script88b8boom |
||
1583 | * baby8/b8", then if you set $values_already_prepared_by_model_object to |
||
1584 | * TRUE, it is assumed that you've already called |
||
1585 | * EE_Simple_HTML_Field->prepare_for_set($new_value), which removes the |
||
1586 | * malicious javascript. However, if |
||
1587 | * $values_already_prepared_by_model_object is left as FALSE, then |
||
1588 | * EE_Simple_HTML_Field->prepare_for_set($new_value) will be called on it, |
||
1589 | * and every other field, before insertion. We provide this parameter |
||
1590 | * because model objects perform their prepare_for_set function on all |
||
1591 | * their values, and so don't need to be called again (and in many cases, |
||
1592 | * shouldn't be called again. Eg: if we escape HTML characters in the |
||
1593 | * prepare_for_set method...) |
||
1594 | * @param boolean $keep_model_objs_in_sync if TRUE, makes sure we ALSO update model objects |
||
1595 | * in this model's entity map according to $fields_n_values that match |
||
1596 | * $query_params. This obviously has some overhead, so you can disable it |
||
1597 | * by setting this to FALSE, but be aware that model objects being used |
||
1598 | * could get out-of-sync with the database |
||
1599 | * @return int how many rows got updated or FALSE if something went wrong with the query (wp returns FALSE or num |
||
1600 | * rows affected which *could* include 0 which DOES NOT mean the query was |
||
1601 | * bad) |
||
1602 | * @throws EE_Error |
||
1603 | */ |
||
1604 | public function update($fields_n_values, $query_params, $keep_model_objs_in_sync = true) |
||
1748 | |||
1749 | |||
1750 | |||
1751 | /** |
||
1752 | * Analogous to $wpdb->get_col, returns a 1-dimensional array where teh values |
||
1753 | * are teh values of the field specified (or by default the primary key field) |
||
1754 | * that matched the query params. Note that you should pass the name of the |
||
1755 | * model FIELD, not the database table's column name. |
||
1756 | * |
||
1757 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
1758 | * @param string $field_to_select |
||
1759 | * @return array just like $wpdb->get_col() |
||
1760 | * @throws EE_Error |
||
1761 | */ |
||
1762 | public function get_col($query_params = array(), $field_to_select = null) |
||
1777 | |||
1778 | |||
1779 | |||
1780 | /** |
||
1781 | * Returns a single column value for a single row from the database |
||
1782 | * |
||
1783 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
1784 | * @param string $field_to_select @see EEM_Base::get_col() |
||
1785 | * @return string |
||
1786 | * @throws EE_Error |
||
1787 | */ |
||
1788 | public function get_var($query_params = array(), $field_to_select = null) |
||
1797 | |||
1798 | |||
1799 | |||
1800 | /** |
||
1801 | * Makes the SQL for after "UPDATE table_X inner join table_Y..." and before "...WHERE". Eg "Question.name='party |
||
1802 | * time?', Question.desc='what do you think?',..." Values are filtered through wpdb->prepare to avoid against SQL |
||
1803 | * injection, but currently no further filtering is done |
||
1804 | * |
||
1805 | * @global $wpdb |
||
1806 | * @param array $fields_n_values array keys are field names on this model, and values are what those fields should |
||
1807 | * be updated to in the DB |
||
1808 | * @return string of SQL |
||
1809 | * @throws EE_Error |
||
1810 | */ |
||
1811 | public function _construct_update_sql($fields_n_values) |
||
1827 | |||
1828 | |||
1829 | |||
1830 | /** |
||
1831 | * Deletes a single row from the DB given the model object's primary key value. (eg, EE_Attendee->ID()'s value). |
||
1832 | * Performs a HARD delete, meaning the database row should always be removed, |
||
1833 | * not just have a flag field on it switched |
||
1834 | * Wrapper for EEM_Base::delete_permanently() |
||
1835 | * |
||
1836 | * @param mixed $id |
||
1837 | * @param boolean $allow_blocking |
||
1838 | * @return int the number of rows deleted |
||
1839 | * @throws EE_Error |
||
1840 | */ |
||
1841 | View Code Duplication | public function delete_permanently_by_ID($id, $allow_blocking = true) |
|
1851 | |||
1852 | |||
1853 | |||
1854 | /** |
||
1855 | * Deletes a single row from the DB given the model object's primary key value. (eg, EE_Attendee->ID()'s value). |
||
1856 | * Wrapper for EEM_Base::delete() |
||
1857 | * |
||
1858 | * @param mixed $id |
||
1859 | * @param boolean $allow_blocking |
||
1860 | * @return int the number of rows deleted |
||
1861 | * @throws EE_Error |
||
1862 | */ |
||
1863 | View Code Duplication | public function delete_by_ID($id, $allow_blocking = true) |
|
1873 | |||
1874 | |||
1875 | |||
1876 | /** |
||
1877 | * Identical to delete_permanently, but does a "soft" delete if possible, |
||
1878 | * meaning if the model has a field that indicates its been "trashed" or |
||
1879 | * "soft deleted", we will just set that instead of actually deleting the rows. |
||
1880 | * |
||
1881 | * @see EEM_Base::delete_permanently |
||
1882 | * @param array $query_params |
||
1883 | * @param boolean $allow_blocking |
||
1884 | * @return int how many rows got deleted |
||
1885 | * @throws EE_Error |
||
1886 | */ |
||
1887 | public function delete($query_params, $allow_blocking = true) |
||
1891 | |||
1892 | |||
1893 | |||
1894 | /** |
||
1895 | * Deletes the model objects that meet the query params. Note: this method is overridden |
||
1896 | * in EEM_Soft_Delete_Base so that soft-deleted model objects are instead only flagged |
||
1897 | * as archived, not actually deleted |
||
1898 | * |
||
1899 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
1900 | * @param boolean $allow_blocking if TRUE, matched objects will only be deleted if there is no related model info |
||
1901 | * that blocks it (ie, there' sno other data that depends on this data); if false, |
||
1902 | * deletes regardless of other objects which may depend on it. Its generally |
||
1903 | * advisable to always leave this as TRUE, otherwise you could easily corrupt your |
||
1904 | * DB |
||
1905 | * @return int how many rows got deleted |
||
1906 | * @throws EE_Error |
||
1907 | */ |
||
1908 | public function delete_permanently($query_params, $allow_blocking = true) |
||
2008 | |||
2009 | |||
2010 | |||
2011 | /** |
||
2012 | * Checks all the relations that throw error messages when there are blocking related objects |
||
2013 | * for related model objects. If there are any related model objects on those relations, |
||
2014 | * adds an EE_Error, and return true |
||
2015 | * |
||
2016 | * @param EE_Base_Class|int $this_model_obj_or_id |
||
2017 | * @param EE_Base_Class $ignore_this_model_obj a model object like 'EE_Event', or 'EE_Term_Taxonomy', which |
||
2018 | * should be ignored when determining whether there are related |
||
2019 | * model objects which block this model object's deletion. Useful |
||
2020 | * if you know A is related to B and are considering deleting A, |
||
2021 | * but want to see if A has any other objects blocking its deletion |
||
2022 | * before removing the relation between A and B |
||
2023 | * @return boolean |
||
2024 | * @throws EE_Error |
||
2025 | */ |
||
2026 | public function delete_is_blocked_by_related_models($this_model_obj_or_id, $ignore_this_model_obj = null) |
||
2061 | |||
2062 | |||
2063 | /** |
||
2064 | * Builds the columns and values for items to delete from the incoming $row_results_for_deleting array. |
||
2065 | * @param array $row_results_for_deleting |
||
2066 | * @param bool $allow_blocking |
||
2067 | * @return array The shape of this array depends on whether the model `has_primary_key_field` or not. If the |
||
2068 | * model DOES have a primary_key_field, then the array will be a simple single dimension array where |
||
2069 | * the key is the fully qualified primary key column and the value is an array of ids that will be |
||
2070 | * deleted. Example: |
||
2071 | * array('Event.EVT_ID' => array( 1,2,3)) |
||
2072 | * If the model DOES NOT have a primary_key_field, then the array will be a two dimensional array |
||
2073 | * where each element is a group of columns and values that get deleted. Example: |
||
2074 | * array( |
||
2075 | * 0 => array( |
||
2076 | * 'Term_Relationship.object_id' => 1 |
||
2077 | * 'Term_Relationship.term_taxonomy_id' => 5 |
||
2078 | * ), |
||
2079 | * 1 => array( |
||
2080 | * 'Term_Relationship.object_id' => 1 |
||
2081 | * 'Term_Relationship.term_taxonomy_id' => 6 |
||
2082 | * ) |
||
2083 | * ) |
||
2084 | * @throws EE_Error |
||
2085 | */ |
||
2086 | protected function _get_ids_for_delete(array $row_results_for_deleting, $allow_blocking = true) |
||
2137 | |||
2138 | |||
2139 | /** |
||
2140 | * This receives an array of columns and values set to be deleted (as prepared by _get_ids_for_delete) and prepares |
||
2141 | * the corresponding query_part for the query performing the delete. |
||
2142 | * |
||
2143 | * @param array $ids_to_delete_indexed_by_column @see _get_ids_for_delete for how this array might be shaped. |
||
2144 | * @return string |
||
2145 | * @throws EE_Error |
||
2146 | */ |
||
2147 | protected function _build_query_part_for_deleting_from_columns_and_values(array $ids_to_delete_indexed_by_column) |
||
2175 | |||
2176 | |||
2177 | |||
2178 | /** |
||
2179 | * Gets the model field by the fully qualified name |
||
2180 | * @param string $qualified_column_name eg 'Event_CPT.post_name' or $field_obj->get_qualified_column() |
||
2181 | * @return EE_Model_Field_Base |
||
2182 | */ |
||
2183 | public function get_field_by_column($qualified_column_name) |
||
2198 | |||
2199 | |||
2200 | |||
2201 | /** |
||
2202 | * Count all the rows that match criteria the model query params. |
||
2203 | * If $field_to_count isn't provided, the model's primary key is used. Otherwise, we count by field_to_count's |
||
2204 | * column |
||
2205 | * |
||
2206 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
2207 | * @param string $field_to_count field on model to count by (not column name) |
||
2208 | * @param bool $distinct if we want to only count the distinct values for the column then you can trigger |
||
2209 | * that by the setting $distinct to TRUE; |
||
2210 | * @return int |
||
2211 | * @throws EE_Error |
||
2212 | */ |
||
2213 | public function count($query_params = array(), $field_to_count = null, $distinct = false) |
||
2241 | |||
2242 | |||
2243 | |||
2244 | /** |
||
2245 | * Sums up the value of the $field_to_sum (defaults to the primary key, which isn't terribly useful) |
||
2246 | * |
||
2247 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
2248 | * @param string $field_to_sum name of field (array key in $_fields array) |
||
2249 | * @return float |
||
2250 | * @throws EE_Error |
||
2251 | */ |
||
2252 | public function sum($query_params, $field_to_sum = null) |
||
2270 | |||
2271 | |||
2272 | |||
2273 | /** |
||
2274 | * Just calls the specified method on $wpdb with the given arguments |
||
2275 | * Consolidates a little extra error handling code |
||
2276 | * |
||
2277 | * @param string $wpdb_method |
||
2278 | * @param array $arguments_to_provide |
||
2279 | * @throws EE_Error |
||
2280 | * @global wpdb $wpdb |
||
2281 | * @return mixed |
||
2282 | */ |
||
2283 | protected function _do_wpdb_query($wpdb_method, $arguments_to_provide) |
||
2337 | |||
2338 | |||
2339 | |||
2340 | /** |
||
2341 | * Attempts to run the indicated WPDB method with the provided arguments, |
||
2342 | * and if there's an error tries to verify the DB is correct. Uses |
||
2343 | * the static property EEM_Base::$_db_verification_level to determine whether |
||
2344 | * we should try to fix the EE core db, the addons, or just give up |
||
2345 | * |
||
2346 | * @param string $wpdb_method |
||
2347 | * @param array $arguments_to_provide |
||
2348 | * @return mixed |
||
2349 | */ |
||
2350 | private function _process_wpdb_query($wpdb_method, $arguments_to_provide) |
||
2383 | |||
2384 | |||
2385 | |||
2386 | /** |
||
2387 | * Verifies the EE core database is up-to-date and records that we've done it on |
||
2388 | * EEM_Base::$_db_verification_level |
||
2389 | * |
||
2390 | * @param string $wpdb_method |
||
2391 | * @param array $arguments_to_provide |
||
2392 | * @return string |
||
2393 | */ |
||
2394 | View Code Duplication | private function _verify_core_db($wpdb_method, $arguments_to_provide) |
|
2412 | |||
2413 | |||
2414 | |||
2415 | /** |
||
2416 | * Verifies the EE addons' database is up-to-date and records that we've done it on |
||
2417 | * EEM_Base::$_db_verification_level |
||
2418 | * |
||
2419 | * @param $wpdb_method |
||
2420 | * @param $arguments_to_provide |
||
2421 | * @return string |
||
2422 | */ |
||
2423 | View Code Duplication | private function _verify_addons_db($wpdb_method, $arguments_to_provide) |
|
2441 | |||
2442 | |||
2443 | |||
2444 | /** |
||
2445 | * In order to avoid repeating this code for the get_all, sum, and count functions, put the code parts |
||
2446 | * that are identical in here. Returns a string of SQL of everything in a SELECT query except the beginning |
||
2447 | * SELECT clause, eg " FROM wp_posts AS Event INNER JOIN ... WHERE ... ORDER BY ... LIMIT ... GROUP BY ... HAVING |
||
2448 | * ..." |
||
2449 | * |
||
2450 | * @param EE_Model_Query_Info_Carrier $model_query_info |
||
2451 | * @return string |
||
2452 | */ |
||
2453 | private function _construct_2nd_half_of_select_query(EE_Model_Query_Info_Carrier $model_query_info) |
||
2462 | |||
2463 | |||
2464 | |||
2465 | /** |
||
2466 | * Set to easily debug the next X queries ran from this model. |
||
2467 | * |
||
2468 | * @param int $count |
||
2469 | */ |
||
2470 | public function show_next_x_db_queries($count = 1) |
||
2474 | |||
2475 | |||
2476 | |||
2477 | /** |
||
2478 | * @param $sql_query |
||
2479 | */ |
||
2480 | public function show_db_query_if_previously_requested($sql_query) |
||
2487 | |||
2488 | |||
2489 | |||
2490 | /** |
||
2491 | * Adds a relationship of the correct type between $modelObject and $otherModelObject. |
||
2492 | * There are the 3 cases: |
||
2493 | * 'belongsTo' relationship: sets $id_or_obj's foreign_key to be $other_model_id_or_obj's primary_key. If |
||
2494 | * $otherModelObject has no ID, it is first saved. |
||
2495 | * 'hasMany' relationship: sets $other_model_id_or_obj's foreign_key to be $id_or_obj's primary_key. If $id_or_obj |
||
2496 | * has no ID, it is first saved. |
||
2497 | * 'hasAndBelongsToMany' relationships: checks that there isn't already an entry in the join table, and adds one. |
||
2498 | * If one of the model Objects has not yet been saved to the database, it is saved before adding the entry in the |
||
2499 | * join table |
||
2500 | * |
||
2501 | * @param EE_Base_Class /int $thisModelObject |
||
2502 | * @param EE_Base_Class /int $id_or_obj EE_base_Class or ID of other Model Object |
||
2503 | * @param string $relationName , key in EEM_Base::_relations |
||
2504 | * an attendee to a group, you also want to specify which role they |
||
2505 | * will have in that group. So you would use this parameter to |
||
2506 | * specify array('role-column-name'=>'role-id') |
||
2507 | * @param array $extra_join_model_fields_n_values This allows you to enter further query params for the relation |
||
2508 | * to for relation to methods that allow you to further specify |
||
2509 | * extra columns to join by (such as HABTM). Keep in mind that the |
||
2510 | * only acceptable query_params is strict "col" => "value" pairs |
||
2511 | * because these will be inserted in any new rows created as well. |
||
2512 | * @return EE_Base_Class which was added as a relation. Object referred to by $other_model_id_or_obj |
||
2513 | * @throws EE_Error |
||
2514 | */ |
||
2515 | public function add_relationship_to( |
||
2524 | |||
2525 | |||
2526 | |||
2527 | /** |
||
2528 | * Removes a relationship of the correct type between $modelObject and $otherModelObject. |
||
2529 | * There are the 3 cases: |
||
2530 | * 'belongsTo' relationship: sets $modelObject's foreign_key to null, if that field is nullable.Otherwise throws an |
||
2531 | * error |
||
2532 | * 'hasMany' relationship: sets $otherModelObject's foreign_key to null,if that field is nullable.Otherwise throws |
||
2533 | * an error |
||
2534 | * 'hasAndBelongsToMany' relationships:removes any existing entry in the join table between the two models. |
||
2535 | * |
||
2536 | * @param EE_Base_Class /int $id_or_obj |
||
2537 | * @param EE_Base_Class /int $other_model_id_or_obj EE_Base_Class or ID of other Model Object |
||
2538 | * @param string $relationName key in EEM_Base::_relations |
||
2539 | * @return boolean of success |
||
2540 | * @throws EE_Error |
||
2541 | * @param array $where_query This allows you to enter further query params for the relation to for relation to |
||
2542 | * methods that allow you to further specify extra columns to join by (such as HABTM). |
||
2543 | * Keep in mind that the only acceptable query_params is strict "col" => "value" pairs |
||
2544 | * because these will be inserted in any new rows created as well. |
||
2545 | */ |
||
2546 | public function remove_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array()) |
||
2551 | |||
2552 | |||
2553 | |||
2554 | /** |
||
2555 | * @param mixed $id_or_obj |
||
2556 | * @param string $relationName |
||
2557 | * @param array $where_query_params |
||
2558 | * @param EE_Base_Class[] objects to which relations were removed |
||
2559 | * @return \EE_Base_Class[] |
||
2560 | * @throws EE_Error |
||
2561 | */ |
||
2562 | public function remove_relations($id_or_obj, $relationName, $where_query_params = array()) |
||
2567 | |||
2568 | |||
2569 | |||
2570 | /** |
||
2571 | * Gets all the related items of the specified $model_name, using $query_params. |
||
2572 | * Note: by default, we remove the "default query params" |
||
2573 | * because we want to get even deleted items etc. |
||
2574 | * |
||
2575 | * @param mixed $id_or_obj EE_Base_Class child or its ID |
||
2576 | * @param string $model_name like 'Event', 'Registration', etc. always singular |
||
2577 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
2578 | * @return EE_Base_Class[] |
||
2579 | * @throws EE_Error |
||
2580 | */ |
||
2581 | public function get_all_related($id_or_obj, $model_name, $query_params = null) |
||
2587 | |||
2588 | |||
2589 | |||
2590 | /** |
||
2591 | * Deletes all the model objects across the relation indicated by $model_name |
||
2592 | * which are related to $id_or_obj which meet the criteria set in $query_params. |
||
2593 | * However, if the model objects can't be deleted because of blocking related model objects, then |
||
2594 | * they aren't deleted. (Unless the thing that would have been deleted can be soft-deleted, that still happens). |
||
2595 | * |
||
2596 | * @param EE_Base_Class|int|string $id_or_obj |
||
2597 | * @param string $model_name |
||
2598 | * @param array $query_params |
||
2599 | * @return int how many deleted |
||
2600 | * @throws EE_Error |
||
2601 | */ |
||
2602 | public function delete_related($id_or_obj, $model_name, $query_params = array()) |
||
2608 | |||
2609 | |||
2610 | |||
2611 | /** |
||
2612 | * Hard deletes all the model objects across the relation indicated by $model_name |
||
2613 | * which are related to $id_or_obj which meet the criteria set in $query_params. If |
||
2614 | * the model objects can't be hard deleted because of blocking related model objects, |
||
2615 | * just does a soft-delete on them instead. |
||
2616 | * |
||
2617 | * @param EE_Base_Class|int|string $id_or_obj |
||
2618 | * @param string $model_name |
||
2619 | * @param array $query_params |
||
2620 | * @return int how many deleted |
||
2621 | * @throws EE_Error |
||
2622 | */ |
||
2623 | public function delete_related_permanently($id_or_obj, $model_name, $query_params = array()) |
||
2629 | |||
2630 | |||
2631 | |||
2632 | /** |
||
2633 | * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default, |
||
2634 | * unless otherwise specified in the $query_params |
||
2635 | * |
||
2636 | * @param int /EE_Base_Class $id_or_obj |
||
2637 | * @param string $model_name like 'Event', or 'Registration' |
||
2638 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
2639 | * @param string $field_to_count name of field to count by. By default, uses primary key |
||
2640 | * @param bool $distinct if we want to only count the distinct values for the column then you can trigger |
||
2641 | * that by the setting $distinct to TRUE; |
||
2642 | * @return int |
||
2643 | * @throws EE_Error |
||
2644 | */ |
||
2645 | public function count_related( |
||
2663 | |||
2664 | |||
2665 | |||
2666 | /** |
||
2667 | * Instead of getting the related model objects, simply sums up the values of the specified field. |
||
2668 | * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params |
||
2669 | * |
||
2670 | * @param int /EE_Base_Class $id_or_obj |
||
2671 | * @param string $model_name like 'Event', or 'Registration' |
||
2672 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
2673 | * @param string $field_to_sum name of field to count by. By default, uses primary key |
||
2674 | * @return float |
||
2675 | * @throws EE_Error |
||
2676 | */ |
||
2677 | public function sum_related($id_or_obj, $model_name, $query_params, $field_to_sum = null) |
||
2701 | |||
2702 | |||
2703 | |||
2704 | /** |
||
2705 | * Uses $this->_relatedModels info to find the first related model object of relation $relationName to the given |
||
2706 | * $modelObject |
||
2707 | * |
||
2708 | * @param int | EE_Base_Class $id_or_obj EE_Base_Class child or its ID |
||
2709 | * @param string $other_model_name , key in $this->_relatedModels, eg 'Registration', or 'Events' |
||
2710 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
2711 | * @return EE_Base_Class |
||
2712 | * @throws EE_Error |
||
2713 | */ |
||
2714 | public function get_first_related(EE_Base_Class $id_or_obj, $other_model_name, $query_params) |
||
2723 | |||
2724 | |||
2725 | |||
2726 | /** |
||
2727 | * Gets the model's name as it's expected in queries. For example, if this is EEM_Event model, that would be Event |
||
2728 | * |
||
2729 | * @return string |
||
2730 | */ |
||
2731 | public function get_this_model_name() |
||
2735 | |||
2736 | |||
2737 | |||
2738 | /** |
||
2739 | * Gets the model field on this model which is of type EE_Any_Foreign_Model_Name_Field |
||
2740 | * |
||
2741 | * @return EE_Any_Foreign_Model_Name_Field |
||
2742 | * @throws EE_Error |
||
2743 | */ |
||
2744 | public function get_field_containing_related_model_name() |
||
2759 | |||
2760 | |||
2761 | |||
2762 | /** |
||
2763 | * Inserts a new entry into the database, for each table. |
||
2764 | * Note: does not add the item to the entity map because that is done by EE_Base_Class::save() right after this. |
||
2765 | * If client code uses EEM_Base::insert() directly, then although the item isn't in the entity map, |
||
2766 | * we also know there is no model object with the newly inserted item's ID at the moment (because |
||
2767 | * if there were, then they would already be in the DB and this would fail); and in the future if someone |
||
2768 | * creates a model object with this ID (or grabs it from the DB) then it will be added to the |
||
2769 | * entity map at that time anyways. SO, no need for EEM_Base::insert ot add to the entity map |
||
2770 | * |
||
2771 | * @param array $field_n_values keys are field names, values are their values (in the client code's domain if |
||
2772 | * $values_already_prepared_by_model_object is false, in the model object's domain if |
||
2773 | * $values_already_prepared_by_model_object is true. See comment about this at the top |
||
2774 | * of EEM_Base) |
||
2775 | * @return int|string new primary key on main table that got inserted |
||
2776 | * @throws EE_Error |
||
2777 | */ |
||
2778 | public function insert($field_n_values) |
||
2807 | |||
2808 | |||
2809 | |||
2810 | /** |
||
2811 | * Checks that the result would satisfy the unique indexes on this model |
||
2812 | * |
||
2813 | * @param array $field_n_values |
||
2814 | * @param string $action |
||
2815 | * @return boolean |
||
2816 | * @throws EE_Error |
||
2817 | */ |
||
2818 | protected function _satisfies_unique_indexes($field_n_values, $action = 'insert') |
||
2844 | |||
2845 | |||
2846 | |||
2847 | /** |
||
2848 | * Checks the database for an item that conflicts (ie, if this item were |
||
2849 | * saved to the DB would break some uniqueness requirement, like a primary key |
||
2850 | * or an index primary key set) with the item specified. $id_obj_or_fields_array |
||
2851 | * can be either an EE_Base_Class or an array of fields n values |
||
2852 | * |
||
2853 | * @param EE_Base_Class|array $obj_or_fields_array |
||
2854 | * @param boolean $include_primary_key whether to use the model object's primary key |
||
2855 | * when looking for conflicts |
||
2856 | * (ie, if false, we ignore the model object's primary key |
||
2857 | * when finding "conflicts". If true, it's also considered). |
||
2858 | * Only works for INT primary key, |
||
2859 | * STRING primary keys cannot be ignored |
||
2860 | * @throws EE_Error |
||
2861 | * @return EE_Base_Class|array |
||
2862 | */ |
||
2863 | public function get_one_conflicting($obj_or_fields_array, $include_primary_key = true) |
||
2901 | |||
2902 | |||
2903 | |||
2904 | /** |
||
2905 | * Like count, but is optimized and returns a boolean instead of an int |
||
2906 | * |
||
2907 | * @param array $query_params |
||
2908 | * @return boolean |
||
2909 | * @throws EE_Error |
||
2910 | */ |
||
2911 | public function exists($query_params) |
||
2916 | |||
2917 | |||
2918 | |||
2919 | /** |
||
2920 | * Wrapper for exists, except ignores default query parameters so we're only considering ID |
||
2921 | * |
||
2922 | * @param int|string $id |
||
2923 | * @return boolean |
||
2924 | * @throws EE_Error |
||
2925 | */ |
||
2926 | public function exists_by_ID($id) |
||
2937 | |||
2938 | |||
2939 | |||
2940 | /** |
||
2941 | * Inserts a new row in $table, using the $cols_n_values which apply to that table. |
||
2942 | * If a $new_id is supplied and if $table is an EE_Other_Table, we assume |
||
2943 | * we need to add a foreign key column to point to $new_id (which should be the primary key's value |
||
2944 | * on the main table) |
||
2945 | * This is protected rather than private because private is not accessible to any child methods and there MAY be |
||
2946 | * cases where we want to call it directly rather than via insert(). |
||
2947 | * |
||
2948 | * @access protected |
||
2949 | * @param EE_Table_Base $table |
||
2950 | * @param array $fields_n_values each key should be in field's keys, and value should be an int, string or |
||
2951 | * float |
||
2952 | * @param int $new_id for now we assume only int keys |
||
2953 | * @throws EE_Error |
||
2954 | * @global WPDB $wpdb only used to get the $wpdb->insert_id after performing an insert |
||
2955 | * @return int ID of new row inserted, or FALSE on failure |
||
2956 | */ |
||
2957 | protected function _insert_into_specific_table(EE_Table_Base $table, $fields_n_values, $new_id = 0) |
||
3002 | |||
3003 | |||
3004 | |||
3005 | /** |
||
3006 | * Prepare the $field_obj 's value in $fields_n_values for use in the database. |
||
3007 | * If the field doesn't allow NULL, try to use its default. (If it doesn't allow NULL, |
||
3008 | * and there is no default, we pass it along. WPDB will take care of it) |
||
3009 | * |
||
3010 | * @param EE_Model_Field_Base $field_obj |
||
3011 | * @param array $fields_n_values |
||
3012 | * @return mixed string|int|float depending on what the table column will be expecting |
||
3013 | * @throws EE_Error |
||
3014 | */ |
||
3015 | protected function _prepare_value_or_use_default($field_obj, $fields_n_values) |
||
3031 | |||
3032 | |||
3033 | |||
3034 | /** |
||
3035 | * Consolidates code for preparing a value supplied to the model for use int eh db. Calls the field's |
||
3036 | * prepare_for_use_in_db method on the value, and depending on $value_already_prepare_by_model_obj, may also call |
||
3037 | * the field's prepare_for_set() method. |
||
3038 | * |
||
3039 | * @param mixed $value value in the client code domain if $value_already_prepared_by_model_object is |
||
3040 | * false, otherwise a value in the model object's domain (see lengthy comment at |
||
3041 | * top of file) |
||
3042 | * @param EE_Model_Field_Base $field field which will be doing the preparing of the value. If null, we assume |
||
3043 | * $value is a custom selection |
||
3044 | * @return mixed a value ready for use in the database for insertions, updating, or in a where clause |
||
3045 | */ |
||
3046 | private function _prepare_value_for_use_in_db($value, $field) |
||
3066 | |||
3067 | |||
3068 | |||
3069 | /** |
||
3070 | * Returns the main table on this model |
||
3071 | * |
||
3072 | * @return EE_Primary_Table |
||
3073 | * @throws EE_Error |
||
3074 | */ |
||
3075 | protected function _get_main_table() |
||
3087 | |||
3088 | |||
3089 | |||
3090 | /** |
||
3091 | * table |
||
3092 | * returns EE_Primary_Table table name |
||
3093 | * |
||
3094 | * @return string |
||
3095 | * @throws EE_Error |
||
3096 | */ |
||
3097 | public function table() |
||
3101 | |||
3102 | |||
3103 | |||
3104 | /** |
||
3105 | * table |
||
3106 | * returns first EE_Secondary_Table table name |
||
3107 | * |
||
3108 | * @return string |
||
3109 | */ |
||
3110 | public function second_table() |
||
3116 | |||
3117 | |||
3118 | |||
3119 | /** |
||
3120 | * get_table_obj_by_alias |
||
3121 | * returns table name given it's alias |
||
3122 | * |
||
3123 | * @param string $table_alias |
||
3124 | * @return EE_Primary_Table | EE_Secondary_Table |
||
3125 | */ |
||
3126 | public function get_table_obj_by_alias($table_alias = '') |
||
3130 | |||
3131 | |||
3132 | |||
3133 | /** |
||
3134 | * Gets all the tables of type EE_Other_Table from EEM_CPT_Basel_Model::_tables |
||
3135 | * |
||
3136 | * @return EE_Secondary_Table[] |
||
3137 | */ |
||
3138 | protected function _get_other_tables() |
||
3148 | |||
3149 | |||
3150 | |||
3151 | /** |
||
3152 | * Finds all the fields that correspond to the given table |
||
3153 | * |
||
3154 | * @param string $table_alias , array key in EEM_Base::_tables |
||
3155 | * @return EE_Model_Field_Base[] |
||
3156 | */ |
||
3157 | public function _get_fields_for_table($table_alias) |
||
3161 | |||
3162 | |||
3163 | |||
3164 | /** |
||
3165 | * Recurses through all the where parameters, and finds all the related models we'll need |
||
3166 | * to complete this query. Eg, given where parameters like array('EVT_ID'=>3) from within Event model, we won't |
||
3167 | * need any related models. But if the array were array('Registrations.REG_ID'=>3), we'd need the related |
||
3168 | * Registration model. If it were array('Registrations.Transactions.Payments.PAY_ID'=>3), then we'd need the |
||
3169 | * related Registration, Transaction, and Payment models. |
||
3170 | * |
||
3171 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
3172 | * @return EE_Model_Query_Info_Carrier |
||
3173 | * @throws EE_Error |
||
3174 | */ |
||
3175 | public function _extract_related_models_from_query($query_params) |
||
3228 | |||
3229 | |||
3230 | |||
3231 | /** |
||
3232 | * For extracting related models from WHERE (0), HAVING (having), ORDER BY (order_by) or forced joins (force_join) |
||
3233 | * |
||
3234 | * @param array $sub_query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#-0-where-conditions |
||
3235 | * @param EE_Model_Query_Info_Carrier $model_query_info_carrier |
||
3236 | * @param string $query_param_type one of $this->_allowed_query_params |
||
3237 | * @throws EE_Error |
||
3238 | * @return \EE_Model_Query_Info_Carrier |
||
3239 | */ |
||
3240 | private function _extract_related_models_from_sub_params_array_keys( |
||
3299 | |||
3300 | |||
3301 | |||
3302 | /** |
||
3303 | * For extracting related models from forced_joins, where the array values contain the info about what |
||
3304 | * models to join with. Eg an array like array('Attendee','Price.Price_Type'); |
||
3305 | * |
||
3306 | * @param array $sub_query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
||
3307 | * @param EE_Model_Query_Info_Carrier $model_query_info_carrier |
||
3308 | * @param string $query_param_type one of $this->_allowed_query_params |
||
3309 | * @throws EE_Error |
||
3310 | * @return \EE_Model_Query_Info_Carrier |
||
3311 | */ |
||
3312 | private function _extract_related_models_from_sub_params_array_values( |
||
3335 | |||
3336 | |||
3337 | /** |
||
3338 | * Extract all the query parts from model query params |
||
3339 | * and put into a EEM_Related_Model_Info_Carrier for easy extraction into a query. We create this object |
||
3340 | * instead of directly constructing the SQL because often we need to extract info from the $query_params |
||
3341 | * but use them in a different order. Eg, we need to know what models we are querying |
||
3342 | * before we know what joins to perform. However, we need to know what data types correspond to which fields on |
||
3343 | * other models before we can finalize the where clause SQL. |
||
3344 | * |
||
3345 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
3346 | * @throws EE_Error |
||
3347 | * @return EE_Model_Query_Info_Carrier |
||
3348 | * @throws ModelConfigurationException |
||
3349 | */ |
||
3350 | public function _create_model_query_info_carrier($query_params) |
||
3552 | |||
3553 | |||
3554 | |||
3555 | /** |
||
3556 | * Gets the where conditions that should be imposed on the query based on the |
||
3557 | * context (eg reading frontend, backend, edit or delete). |
||
3558 | * |
||
3559 | * @param string $context one of EEM_Base::valid_cap_contexts() |
||
3560 | * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
||
3561 | * @throws EE_Error |
||
3562 | */ |
||
3563 | public function caps_where_conditions($context = self::caps_read) |
||
3585 | |||
3586 | |||
3587 | |||
3588 | /** |
||
3589 | * Verifies that $should_be_order_string is in $this->_allowed_order_values, |
||
3590 | * otherwise throws an exception |
||
3591 | * |
||
3592 | * @param string $should_be_order_string |
||
3593 | * @return string either ASC, asc, DESC or desc |
||
3594 | * @throws EE_Error |
||
3595 | */ |
||
3596 | View Code Duplication | private function _extract_order($should_be_order_string) |
|
3612 | |||
3613 | |||
3614 | |||
3615 | /** |
||
3616 | * Looks at all the models which are included in this query, and asks each |
||
3617 | * for their universal_where_params, and returns them in the same format as $query_params[0] (where), |
||
3618 | * so they can be merged |
||
3619 | * |
||
3620 | * @param EE_Model_Query_Info_Carrier $query_info_carrier |
||
3621 | * @param string $use_default_where_conditions can be 'none','other_models_only', or 'all'. |
||
3622 | * 'none' means NO default where conditions will |
||
3623 | * be used AT ALL during this query. |
||
3624 | * 'other_models_only' means default where |
||
3625 | * conditions from other models will be used, but |
||
3626 | * not for this primary model. 'all', the default, |
||
3627 | * means default where conditions will apply as |
||
3628 | * normal |
||
3629 | * @param array $where_query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
||
3630 | * @throws EE_Error |
||
3631 | * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
||
3632 | */ |
||
3633 | private function _get_default_where_conditions_for_models_in_query( |
||
3678 | |||
3679 | |||
3680 | |||
3681 | /** |
||
3682 | * Determines whether or not we should use default where conditions for the model in question |
||
3683 | * (this model, or other related models). |
||
3684 | * Basically, we should use default where conditions on this model if they have requested to use them on all models, |
||
3685 | * this model only, or to use minimum where conditions on all other models and normal where conditions on this one. |
||
3686 | * We should use default where conditions on related models when they requested to use default where conditions |
||
3687 | * on all models, or specifically just on other related models |
||
3688 | * @param $default_where_conditions_value |
||
3689 | * @param bool $for_this_model false means this is for OTHER related models |
||
3690 | * @return bool |
||
3691 | */ |
||
3692 | private function _should_use_default_where_conditions($default_where_conditions_value, $for_this_model = true) |
||
3718 | |||
3719 | /** |
||
3720 | * Determines whether or not we should use default minimum conditions for the model in question |
||
3721 | * (this model, or other related models). |
||
3722 | * Basically, we should use minimum where conditions on this model only if they requested all models to use minimum |
||
3723 | * where conditions. |
||
3724 | * We should use minimum where conditions on related models if they requested to use minimum where conditions |
||
3725 | * on this model or others |
||
3726 | * @param $default_where_conditions_value |
||
3727 | * @param bool $for_this_model false means this is for OTHER related models |
||
3728 | * @return bool |
||
3729 | */ |
||
3730 | private function _should_use_minimum_where_conditions($default_where_conditions_value, $for_this_model = true) |
||
3748 | |||
3749 | |||
3750 | /** |
||
3751 | * Checks if any of the defaults have been overridden. If there are any that AREN'T overridden, |
||
3752 | * then we also add a special where condition which allows for that model's primary key |
||
3753 | * to be null (which is important for JOINs. Eg, if you want to see all Events ordered by Venue's name, |
||
3754 | * then Event's with NO Venue won't appear unless you allow VNU_ID to be NULL) |
||
3755 | * |
||
3756 | * @param array $default_where_conditions |
||
3757 | * @param array $provided_where_conditions |
||
3758 | * @param EEM_Base $model |
||
3759 | * @param string $model_relation_path like 'Transaction.Payment.' |
||
3760 | * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
||
3761 | * @throws EE_Error |
||
3762 | */ |
||
3763 | private function _override_defaults_or_make_null_friendly( |
||
3790 | |||
3791 | |||
3792 | |||
3793 | /** |
||
3794 | * Uses the _default_where_conditions_strategy set during __construct() to get |
||
3795 | * default where conditions on all get_all, update, and delete queries done by this model. |
||
3796 | * Use the same syntax as client code. Eg on the Event model, use array('Event.EVT_post_type'=>'esp_event'), |
||
3797 | * NOT array('Event_CPT.post_type'=>'esp_event'). |
||
3798 | * |
||
3799 | * @param string $model_relation_path eg, path from Event to Payment is "Registration.Transaction.Payment." |
||
3800 | * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
||
3801 | */ |
||
3802 | private function _get_default_where_conditions($model_relation_path = null) |
||
3809 | |||
3810 | |||
3811 | |||
3812 | /** |
||
3813 | * Uses the _minimum_where_conditions_strategy set during __construct() to get |
||
3814 | * minimum where conditions on all get_all, update, and delete queries done by this model. |
||
3815 | * Use the same syntax as client code. Eg on the Event model, use array('Event.EVT_post_type'=>'esp_event'), |
||
3816 | * NOT array('Event_CPT.post_type'=>'esp_event'). |
||
3817 | * Similar to _get_default_where_conditions |
||
3818 | * |
||
3819 | * @param string $model_relation_path eg, path from Event to Payment is "Registration.Transaction.Payment." |
||
3820 | * @return array @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
||
3821 | */ |
||
3822 | protected function _get_minimum_where_conditions($model_relation_path = null) |
||
3829 | |||
3830 | |||
3831 | |||
3832 | /** |
||
3833 | * Creates the string of SQL for the select part of a select query, everything behind SELECT and before FROM. |
||
3834 | * Eg, "Event.post_id, Event.post_name,Event_Detail.EVT_ID..." |
||
3835 | * |
||
3836 | * @param EE_Model_Query_Info_Carrier $model_query_info |
||
3837 | * @return string |
||
3838 | * @throws EE_Error |
||
3839 | */ |
||
3840 | private function _construct_default_select_sql(EE_Model_Query_Info_Carrier $model_query_info) |
||
3853 | |||
3854 | |||
3855 | |||
3856 | /** |
||
3857 | * Gets an array of columns to select for this model, which are necessary for it to create its objects. |
||
3858 | * So that's going to be the columns for all the fields on the model |
||
3859 | * |
||
3860 | * @param string $model_relation_chain like 'Question.Question_Group.Event' |
||
3861 | * @return array numerically indexed, values are columns to select and rename, eg "Event.ID AS 'Event.ID'" |
||
3862 | */ |
||
3863 | public function _get_columns_to_select_for_this_model($model_relation_chain = '') |
||
3896 | |||
3897 | |||
3898 | |||
3899 | /** |
||
3900 | * Given a $query_param like 'Registration.Transaction.TXN_ID', pops off 'Registration.', |
||
3901 | * gets the join statement for it; gets the data types for it; and passes the remaining 'Transaction.TXN_ID' |
||
3902 | * onto its related Transaction object to do the same. Returns an EE_Join_And_Data_Types object which contains the |
||
3903 | * SQL for joining, and the data types |
||
3904 | * |
||
3905 | * @param null|string $original_query_param |
||
3906 | * @param string $query_param like Registration.Transaction.TXN_ID |
||
3907 | * @param EE_Model_Query_Info_Carrier $passed_in_query_info |
||
3908 | * @param string $query_param_type like Registration.Transaction.TXN_ID |
||
3909 | * or 'PAY_ID'. Otherwise, we don't expect there to be a |
||
3910 | * column name. We only want model names, eg 'Event.Venue' |
||
3911 | * or 'Registration's |
||
3912 | * @param string $original_query_param what it originally was (eg |
||
3913 | * Registration.Transaction.TXN_ID). If null, we assume it |
||
3914 | * matches $query_param |
||
3915 | * @throws EE_Error |
||
3916 | * @return void only modifies the EEM_Related_Model_Info_Carrier passed into it |
||
3917 | */ |
||
3918 | private function _extract_related_model_info_from_query_param( |
||
4016 | |||
4017 | |||
4018 | /** |
||
4019 | * Extracts any possible join model information from the provided possible_join_string. |
||
4020 | * This method will read the provided $possible_join_string value and determine if there are any possible model join |
||
4021 | * parts that should be added to the query. |
||
4022 | * |
||
4023 | * @param EE_Model_Query_Info_Carrier $query_info_carrier |
||
4024 | * @param string $possible_join_string Such as Registration.REG_ID, or Registration |
||
4025 | * @param null|string $original_query_param |
||
4026 | * @param string $query_parameter_type The type for the source of the $possible_join_string |
||
4027 | * ('where', 'order_by', 'group_by', 'custom_selects' etc.) |
||
4028 | * @return bool returns true if a join was added and false if not. |
||
4029 | * @throws EE_Error |
||
4030 | */ |
||
4031 | private function extractJoinModelFromQueryParams( |
||
4077 | |||
4078 | |||
4079 | /** |
||
4080 | * Extracts related models from Custom Selects and sets up any joins for those related models. |
||
4081 | * @param EE_Model_Query_Info_Carrier $query_info_carrier |
||
4082 | * @throws EE_Error |
||
4083 | */ |
||
4084 | private function extractRelatedModelsFromCustomSelects(EE_Model_Query_Info_Carrier $query_info_carrier) |
||
4102 | |||
4103 | |||
4104 | |||
4105 | /** |
||
4106 | * Privately used by _extract_related_model_info_from_query_param to add a join to $model_name |
||
4107 | * and store it on $passed_in_query_info |
||
4108 | * |
||
4109 | * @param string $model_name |
||
4110 | * @param EE_Model_Query_Info_Carrier $passed_in_query_info |
||
4111 | * @param string $original_query_param used to extract the relation chain between the queried |
||
4112 | * model and $model_name. Eg, if we are querying Event, |
||
4113 | * and are adding a join to 'Payment' with the original |
||
4114 | * query param key |
||
4115 | * 'Registration.Transaction.Payment.PAY_amount', we want |
||
4116 | * to extract 'Registration.Transaction.Payment', in case |
||
4117 | * Payment wants to add default query params so that it |
||
4118 | * will know what models to prepend onto its default query |
||
4119 | * params or in case it wants to rename tables (in case |
||
4120 | * there are multiple joins to the same table) |
||
4121 | * @return void |
||
4122 | * @throws EE_Error |
||
4123 | */ |
||
4124 | private function _add_join_to_model( |
||
4156 | |||
4157 | |||
4158 | |||
4159 | /** |
||
4160 | * Constructs SQL for where clause, like "WHERE Event.ID = 23 AND Transaction.amount > 100" etc. |
||
4161 | * |
||
4162 | * @param array $where_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
||
4163 | * @return string of SQL |
||
4164 | * @throws EE_Error |
||
4165 | */ |
||
4166 | private function _construct_where_clause($where_params) |
||
4174 | |||
4175 | |||
4176 | |||
4177 | /** |
||
4178 | * Just like the _construct_where_clause, except prepends 'HAVING' instead of 'WHERE', |
||
4179 | * and should be passed HAVING parameters, not WHERE parameters |
||
4180 | * |
||
4181 | * @param array $having_params |
||
4182 | * @return string |
||
4183 | * @throws EE_Error |
||
4184 | */ |
||
4185 | private function _construct_having_clause($having_params) |
||
4193 | |||
4194 | |||
4195 | /** |
||
4196 | * Used for creating nested WHERE conditions. Eg "WHERE ! (Event.ID = 3 OR ( Event_Meta.meta_key = 'bob' AND |
||
4197 | * Event_Meta.meta_value = 'foo'))" |
||
4198 | * |
||
4199 | * @param array $where_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
||
4200 | * @param string $glue joins each subclause together. Should really only be " AND " or " OR "... |
||
4201 | * @throws EE_Error |
||
4202 | * @return string of SQL |
||
4203 | */ |
||
4204 | private function _construct_condition_clause_recursive($where_params, $glue = ' AND') |
||
4258 | |||
4259 | |||
4260 | |||
4261 | /** |
||
4262 | * Takes the input parameter and extract the table name (alias) and column name |
||
4263 | * |
||
4264 | * @param string $query_param like Registration.Transaction.TXN_ID, Event.Datetime.start_time, or REG_ID |
||
4265 | * @throws EE_Error |
||
4266 | * @return string table alias and column name for SQL, eg "Transaction.TXN_ID" |
||
4267 | */ |
||
4268 | private function _deduce_column_name_from_query_param($query_param) |
||
4299 | |||
4300 | |||
4301 | |||
4302 | /** |
||
4303 | * Removes the * and anything after it from the condition query param key. It is useful to add the * to condition |
||
4304 | * query param keys (eg, 'OR*', 'EVT_ID') in order for the array keys to still be unique, so that they don't get |
||
4305 | * overwritten Takes a string like 'Event.EVT_ID*', 'TXN_total**', 'OR*1st', and 'DTT_reg_start*foobar' to |
||
4306 | * 'Event.EVT_ID', 'TXN_total', 'OR', and 'DTT_reg_start', respectively. |
||
4307 | * |
||
4308 | * @param string $condition_query_param_key |
||
4309 | * @return string |
||
4310 | */ |
||
4311 | View Code Duplication | private function _remove_stars_and_anything_after_from_condition_query_param_key($condition_query_param_key) |
|
4320 | |||
4321 | |||
4322 | |||
4323 | /** |
||
4324 | * creates the SQL for the operator and the value in a WHERE clause, eg "< 23" or "LIKE '%monkey%'" |
||
4325 | * |
||
4326 | * @param mixed array | string $op_and_value |
||
4327 | * @param EE_Model_Field_Base|string $field_obj . If string, should be one of EEM_Base::_valid_wpdb_data_types |
||
4328 | * @throws EE_Error |
||
4329 | * @return string |
||
4330 | */ |
||
4331 | private function _construct_op_and_value($op_and_value, $field_obj) |
||
4439 | |||
4440 | |||
4441 | |||
4442 | /** |
||
4443 | * Creates the operands to be used in a BETWEEN query, eg "'2014-12-31 20:23:33' AND '2015-01-23 12:32:54'" |
||
4444 | * |
||
4445 | * @param array $values |
||
4446 | * @param EE_Model_Field_Base|string $field_obj if string, it should be the datatype to be used when querying, eg |
||
4447 | * '%s' |
||
4448 | * @return string |
||
4449 | * @throws EE_Error |
||
4450 | */ |
||
4451 | public function _construct_between_value($values, $field_obj) |
||
4459 | |||
4460 | |||
4461 | |||
4462 | /** |
||
4463 | * Takes an array or a comma-separated list of $values and cleans them |
||
4464 | * according to $data_type using $wpdb->prepare, and then makes the list a |
||
4465 | * string surrounded by ( and ). Eg, _construct_in_value(array(1,2,3),'%d') would |
||
4466 | * return '(1,2,3)'; _construct_in_value("1,2,hack",'%d') would return '(1,2,1)' (assuming |
||
4467 | * I'm right that a string, when interpreted as a digit, becomes a 1. It might become a 0) |
||
4468 | * |
||
4469 | * @param mixed $values array or comma-separated string |
||
4470 | * @param EE_Model_Field_Base|string $field_obj if string, it should be a wpdb data type like '%s', or '%d' |
||
4471 | * @return string of SQL to follow an 'IN' or 'NOT IN' operator |
||
4472 | * @throws EE_Error |
||
4473 | */ |
||
4474 | public function _construct_in_value($values, $field_obj) |
||
4500 | |||
4501 | |||
4502 | |||
4503 | /** |
||
4504 | * @param mixed $value |
||
4505 | * @param EE_Model_Field_Base|string $field_obj if string it should be a wpdb data type like '%d' |
||
4506 | * @throws EE_Error |
||
4507 | * @return false|null|string |
||
4508 | */ |
||
4509 | private function _wpdb_prepare_using_field($value, $field_obj) |
||
4530 | |||
4531 | |||
4532 | |||
4533 | /** |
||
4534 | * Takes the input parameter and finds the model field that it indicates. |
||
4535 | * |
||
4536 | * @param string $query_param_name like Registration.Transaction.TXN_ID, Event.Datetime.start_time, or REG_ID |
||
4537 | * @throws EE_Error |
||
4538 | * @return EE_Model_Field_Base |
||
4539 | */ |
||
4540 | protected function _deduce_field_from_query_param($query_param_name) |
||
4567 | |||
4568 | |||
4569 | |||
4570 | /** |
||
4571 | * Given a field's name (ie, a key in $this->field_settings()), uses the EE_Model_Field object to get the table's |
||
4572 | * alias and column which corresponds to it |
||
4573 | * |
||
4574 | * @param string $field_name |
||
4575 | * @throws EE_Error |
||
4576 | * @return string |
||
4577 | */ |
||
4578 | public function _get_qualified_column_for_field($field_name) |
||
4596 | |||
4597 | |||
4598 | |||
4599 | /** |
||
4600 | * similar to \EEM_Base::_get_qualified_column_for_field() but returns an array with data for ALL fields. |
||
4601 | * Example usage: |
||
4602 | * EEM_Ticket::instance()->get_all_wpdb_results( |
||
4603 | * array(), |
||
4604 | * ARRAY_A, |
||
4605 | * EEM_Ticket::instance()->get_qualified_columns_for_all_fields() |
||
4606 | * ); |
||
4607 | * is equivalent to |
||
4608 | * EEM_Ticket::instance()->get_all_wpdb_results( array(), ARRAY_A, '*' ); |
||
4609 | * and |
||
4610 | * EEM_Event::instance()->get_all_wpdb_results( |
||
4611 | * array( |
||
4612 | * array( |
||
4613 | * 'Datetime.Ticket.TKT_ID' => array( '<', 100 ), |
||
4614 | * ), |
||
4615 | * ARRAY_A, |
||
4616 | * implode( |
||
4617 | * ', ', |
||
4618 | * array_merge( |
||
4619 | * EEM_Event::instance()->get_qualified_columns_for_all_fields( '', false ), |
||
4620 | * EEM_Ticket::instance()->get_qualified_columns_for_all_fields( 'Datetime', false ) |
||
4621 | * ) |
||
4622 | * ) |
||
4623 | * ) |
||
4624 | * ); |
||
4625 | * selects rows from the database, selecting all the event and ticket columns, where the ticket ID is below 100 |
||
4626 | * |
||
4627 | * @param string $model_relation_chain the chain of models used to join between the model you want to query |
||
4628 | * and the one whose fields you are selecting for example: when querying |
||
4629 | * tickets model and selecting fields from the tickets model you would |
||
4630 | * leave this parameter empty, because no models are needed to join |
||
4631 | * between the queried model and the selected one. Likewise when |
||
4632 | * querying the datetime model and selecting fields from the tickets |
||
4633 | * model, it would also be left empty, because there is a direct |
||
4634 | * relation from datetimes to tickets, so no model is needed to join |
||
4635 | * them together. However, when querying from the event model and |
||
4636 | * selecting fields from the ticket model, you should provide the string |
||
4637 | * 'Datetime', indicating that the event model must first join to the |
||
4638 | * datetime model in order to find its relation to ticket model. |
||
4639 | * Also, when querying from the venue model and selecting fields from |
||
4640 | * the ticket model, you should provide the string 'Event.Datetime', |
||
4641 | * indicating you need to join the venue model to the event model, |
||
4642 | * to the datetime model, in order to find its relation to the ticket model. |
||
4643 | * This string is used to deduce the prefix that gets added onto the |
||
4644 | * models' tables qualified columns |
||
4645 | * @param bool $return_string if true, will return a string with qualified column names separated |
||
4646 | * by ', ' if false, will simply return a numerically indexed array of |
||
4647 | * qualified column names |
||
4648 | * @return array|string |
||
4649 | */ |
||
4650 | public function get_qualified_columns_for_all_fields($model_relation_chain = '', $return_string = true) |
||
4659 | |||
4660 | |||
4661 | |||
4662 | /** |
||
4663 | * constructs the select use on special limit joins |
||
4664 | * NOTE: for now this has only been tested and will work when the table alias is for the PRIMARY table. Although |
||
4665 | * its setup so the select query will be setup on and just doing the special select join off of the primary table |
||
4666 | * (as that is typically where the limits would be set). |
||
4667 | * |
||
4668 | * @param string $table_alias The table the select is being built for |
||
4669 | * @param mixed|string $limit The limit for this select |
||
4670 | * @return string The final select join element for the query. |
||
4671 | */ |
||
4672 | public function _construct_limit_join_select($table_alias, $limit) |
||
4688 | |||
4689 | |||
4690 | |||
4691 | /** |
||
4692 | * Constructs the internal join if there are multiple tables, or simply the table's name and alias |
||
4693 | * Eg "wp_post AS Event" or "wp_post AS Event INNER JOIN wp_postmeta Event_Meta ON Event.ID = Event_Meta.post_id" |
||
4694 | * |
||
4695 | * @return string SQL |
||
4696 | * @throws EE_Error |
||
4697 | */ |
||
4698 | public function _construct_internal_join() |
||
4704 | |||
4705 | |||
4706 | |||
4707 | /** |
||
4708 | * Constructs the SQL for joining all the tables on this model. |
||
4709 | * Normally $alias should be the primary table's alias, but in cases where |
||
4710 | * we have already joined to a secondary table (eg, the secondary table has a foreign key and is joined before the |
||
4711 | * primary table) then we should provide that secondary table's alias. Eg, with $alias being the primary table's |
||
4712 | * alias, this will construct SQL like: |
||
4713 | * " INNER JOIN wp_esp_secondary_table AS Secondary_Table ON Primary_Table.pk = Secondary_Table.fk". |
||
4714 | * With $alias being a secondary table's alias, this will construct SQL like: |
||
4715 | * " INNER JOIN wp_esp_primary_table AS Primary_Table ON Primary_Table.pk = Secondary_Table.fk". |
||
4716 | * |
||
4717 | * @param string $alias_prefixed table alias to join to (this table should already be in the FROM SQL clause) |
||
4718 | * @return string |
||
4719 | */ |
||
4720 | public function _construct_internal_join_to_table_with_alias($alias_prefixed) |
||
4739 | |||
4740 | |||
4741 | |||
4742 | /** |
||
4743 | * Gets an array for storing all the data types on the next-to-be-executed-query. |
||
4744 | * This should be a growing array of keys being table-columns (eg 'EVT_ID' and 'Event.EVT_ID'), and values being |
||
4745 | * their data type (eg, '%s', '%d', etc) |
||
4746 | * |
||
4747 | * @return array |
||
4748 | */ |
||
4749 | public function _get_data_types() |
||
4759 | |||
4760 | |||
4761 | |||
4762 | /** |
||
4763 | * Gets the model object given the relation's name / model's name (eg, 'Event', 'Registration',etc. Always singular) |
||
4764 | * |
||
4765 | * @param string $model_name |
||
4766 | * @throws EE_Error |
||
4767 | * @return EEM_Base |
||
4768 | */ |
||
4769 | public function get_related_model_obj($model_name) |
||
4780 | |||
4781 | |||
4782 | |||
4783 | /** |
||
4784 | * Returns the array of EE_ModelRelations for this model. |
||
4785 | * |
||
4786 | * @return EE_Model_Relation_Base[] |
||
4787 | */ |
||
4788 | public function relation_settings() |
||
4792 | |||
4793 | |||
4794 | |||
4795 | /** |
||
4796 | * Gets all related models that this model BELONGS TO. Handy to know sometimes |
||
4797 | * because without THOSE models, this model probably doesn't have much purpose. |
||
4798 | * (Eg, without an event, datetimes have little purpose.) |
||
4799 | * |
||
4800 | * @return EE_Belongs_To_Relation[] |
||
4801 | */ |
||
4802 | public function belongs_to_relations() |
||
4812 | |||
4813 | |||
4814 | |||
4815 | /** |
||
4816 | * Returns the specified EE_Model_Relation, or throws an exception |
||
4817 | * |
||
4818 | * @param string $relation_name name of relation, key in $this->_relatedModels |
||
4819 | * @throws EE_Error |
||
4820 | * @return EE_Model_Relation_Base |
||
4821 | */ |
||
4822 | public function related_settings_for($relation_name) |
||
4840 | |||
4841 | |||
4842 | |||
4843 | /** |
||
4844 | * A convenience method for getting a specific field's settings, instead of getting all field settings for all |
||
4845 | * fields |
||
4846 | * |
||
4847 | * @param string $fieldName |
||
4848 | * @param boolean $include_db_only_fields |
||
4849 | * @throws EE_Error |
||
4850 | * @return EE_Model_Field_Base |
||
4851 | */ |
||
4852 | public function field_settings_for($fieldName, $include_db_only_fields = true) |
||
4864 | |||
4865 | |||
4866 | |||
4867 | /** |
||
4868 | * Checks if this field exists on this model |
||
4869 | * |
||
4870 | * @param string $fieldName a key in the model's _field_settings array |
||
4871 | * @return boolean |
||
4872 | */ |
||
4873 | public function has_field($fieldName) |
||
4881 | |||
4882 | |||
4883 | |||
4884 | /** |
||
4885 | * Returns whether or not this model has a relation to the specified model |
||
4886 | * |
||
4887 | * @param string $relation_name possibly one of the keys in the relation_settings array |
||
4888 | * @return boolean |
||
4889 | */ |
||
4890 | public function has_relation($relation_name) |
||
4898 | |||
4899 | |||
4900 | |||
4901 | /** |
||
4902 | * gets the field object of type 'primary_key' from the fieldsSettings attribute. |
||
4903 | * Eg, on EE_Answer that would be ANS_ID field object |
||
4904 | * |
||
4905 | * @param $field_obj |
||
4906 | * @return boolean |
||
4907 | */ |
||
4908 | public function is_primary_key_field($field_obj) |
||
4912 | |||
4913 | |||
4914 | |||
4915 | /** |
||
4916 | * gets the field object of type 'primary_key' from the fieldsSettings attribute. |
||
4917 | * Eg, on EE_Answer that would be ANS_ID field object |
||
4918 | * |
||
4919 | * @return EE_Model_Field_Base |
||
4920 | * @throws EE_Error |
||
4921 | */ |
||
4922 | public function get_primary_key_field() |
||
4940 | |||
4941 | |||
4942 | |||
4943 | /** |
||
4944 | * Returns whether or not not there is a primary key on this model. |
||
4945 | * Internally does some caching. |
||
4946 | * |
||
4947 | * @return boolean |
||
4948 | */ |
||
4949 | public function has_primary_key_field() |
||
4961 | |||
4962 | |||
4963 | |||
4964 | /** |
||
4965 | * Finds the first field of type $field_class_name. |
||
4966 | * |
||
4967 | * @param string $field_class_name class name of field that you want to find. Eg, EE_Datetime_Field, |
||
4968 | * EE_Foreign_Key_Field, etc |
||
4969 | * @return EE_Model_Field_Base or null if none is found |
||
4970 | */ |
||
4971 | public function get_a_field_of_type($field_class_name) |
||
4980 | |||
4981 | |||
4982 | |||
4983 | /** |
||
4984 | * Gets a foreign key field pointing to model. |
||
4985 | * |
||
4986 | * @param string $model_name eg Event, Registration, not EEM_Event |
||
4987 | * @return EE_Foreign_Key_Field_Base |
||
4988 | * @throws EE_Error |
||
4989 | */ |
||
4990 | public function get_foreign_key_to($model_name) |
||
5010 | |||
5011 | |||
5012 | |||
5013 | /** |
||
5014 | * Gets the table name (including $wpdb->prefix) for the table alias |
||
5015 | * |
||
5016 | * @param string $table_alias eg Event, Event_Meta, Registration, Transaction, but maybe |
||
5017 | * a table alias with a model chain prefix, like 'Venue__Event_Venue___Event_Meta'. |
||
5018 | * Either one works |
||
5019 | * @return string |
||
5020 | */ |
||
5021 | public function get_table_for_alias($table_alias) |
||
5026 | |||
5027 | |||
5028 | |||
5029 | /** |
||
5030 | * Returns a flat array of all field son this model, instead of organizing them |
||
5031 | * by table_alias as they are in the constructor. |
||
5032 | * |
||
5033 | * @param bool $include_db_only_fields flag indicating whether or not to include the db-only fields |
||
5034 | * @return EE_Model_Field_Base[] where the keys are the field's name |
||
5035 | */ |
||
5036 | public function field_settings($include_db_only_fields = false) |
||
5062 | |||
5063 | |||
5064 | |||
5065 | /** |
||
5066 | * cycle though array of attendees and create objects out of each item |
||
5067 | * |
||
5068 | * @access private |
||
5069 | * @param array $rows of results of $wpdb->get_results($query,ARRAY_A) |
||
5070 | * @return \EE_Base_Class[] array keys are primary keys (if there is a primary key on the model. if not, |
||
5071 | * numerically indexed) |
||
5072 | * @throws EE_Error |
||
5073 | */ |
||
5074 | protected function _create_objects($rows = array()) |
||
5144 | |||
5145 | |||
5146 | /** |
||
5147 | * This will parse a given row of results from the db and see if any keys in the results match an alias within the |
||
5148 | * current CustomSelects object. This will be used to build an array of values indexed by those keys. |
||
5149 | * |
||
5150 | * @param array $db_results_row |
||
5151 | * @return array |
||
5152 | */ |
||
5153 | protected function getValuesForCustomSelectAliasesFromResults(array $db_results_row) |
||
5168 | |||
5169 | |||
5170 | /** |
||
5171 | * This will set the value for the given alias |
||
5172 | * @param string $value |
||
5173 | * @param string $datatype (one of %d, %s, %f) |
||
5174 | * @return int|string|float (int for %d, string for %s, float for %f) |
||
5175 | */ |
||
5176 | protected function convertValueToDataType($value, $datatype) |
||
5187 | |||
5188 | |||
5189 | /** |
||
5190 | * The purpose of this method is to allow us to create a model object that is not in the db that holds default |
||
5191 | * values. A typical example of where this is used is when creating a new item and the initial load of a form. We |
||
5192 | * dont' necessarily want to test for if the object is present but just assume it is BUT load the defaults from the |
||
5193 | * object (as set in the model_field!). |
||
5194 | * |
||
5195 | * @return EE_Base_Class single EE_Base_Class object with default values for the properties. |
||
5196 | */ |
||
5197 | public function create_default_object() |
||
5209 | |||
5210 | |||
5211 | |||
5212 | /** |
||
5213 | * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value |
||
5214 | * or an stdClass where each property is the name of a column, |
||
5215 | * @return EE_Base_Class |
||
5216 | * @throws EE_Error |
||
5217 | */ |
||
5218 | public function instantiate_class_from_array_or_object($cols_n_values) |
||
5267 | |||
5268 | |||
5269 | |||
5270 | /** |
||
5271 | * Gets the model object from the entity map if it exists |
||
5272 | * |
||
5273 | * @param int|string $id the ID of the model object |
||
5274 | * @return EE_Base_Class |
||
5275 | */ |
||
5276 | public function get_from_entity_map($id) |
||
5281 | |||
5282 | |||
5283 | |||
5284 | /** |
||
5285 | * add_to_entity_map |
||
5286 | * Adds the object to the model's entity mappings |
||
5287 | * Effectively tells the models "Hey, this model object is the most up-to-date representation of the data, |
||
5288 | * and for the remainder of the request, it's even more up-to-date than what's in the database. |
||
5289 | * So, if the database doesn't agree with what's in the entity mapper, ignore the database" |
||
5290 | * If the database gets updated directly and you want the entity mapper to reflect that change, |
||
5291 | * then this method should be called immediately after the update query |
||
5292 | * Note: The map is indexed by whatever the current blog id is set (via EEM_Base::$_model_query_blog_id). This is |
||
5293 | * so on multisite, the entity map is specific to the query being done for a specific site. |
||
5294 | * |
||
5295 | * @param EE_Base_Class $object |
||
5296 | * @throws EE_Error |
||
5297 | * @return \EE_Base_Class |
||
5298 | */ |
||
5299 | public function add_to_entity_map(EE_Base_Class $object) |
||
5324 | |||
5325 | |||
5326 | |||
5327 | /** |
||
5328 | * if a valid identifier is provided, then that entity is unset from the entity map, |
||
5329 | * if no identifier is provided, then the entire entity map is emptied |
||
5330 | * |
||
5331 | * @param int|string $id the ID of the model object |
||
5332 | * @return boolean |
||
5333 | */ |
||
5334 | public function clear_entity_map($id = null) |
||
5346 | |||
5347 | |||
5348 | |||
5349 | /** |
||
5350 | * Public wrapper for _deduce_fields_n_values_from_cols_n_values. |
||
5351 | * Given an array where keys are column (or column alias) names and values, |
||
5352 | * returns an array of their corresponding field names and database values |
||
5353 | * |
||
5354 | * @param array $cols_n_values |
||
5355 | * @return array |
||
5356 | */ |
||
5357 | public function deduce_fields_n_values_from_cols_n_values($cols_n_values) |
||
5361 | |||
5362 | |||
5363 | |||
5364 | /** |
||
5365 | * _deduce_fields_n_values_from_cols_n_values |
||
5366 | * Given an array where keys are column (or column alias) names and values, |
||
5367 | * returns an array of their corresponding field names and database values |
||
5368 | * |
||
5369 | * @param string $cols_n_values |
||
5370 | * @return array |
||
5371 | */ |
||
5372 | protected function _deduce_fields_n_values_from_cols_n_values($cols_n_values) |
||
5405 | |||
5406 | |||
5407 | |||
5408 | /** |
||
5409 | * @param $cols_n_values |
||
5410 | * @param $qualified_column |
||
5411 | * @param $regular_column |
||
5412 | * @return null |
||
5413 | */ |
||
5414 | protected function _get_column_value_with_table_alias_or_not($cols_n_values, $qualified_column, $regular_column) |
||
5427 | |||
5428 | |||
5429 | |||
5430 | /** |
||
5431 | * refresh_entity_map_from_db |
||
5432 | * Makes sure the model object in the entity map at $id assumes the values |
||
5433 | * of the database (opposite of EE_base_Class::save()) |
||
5434 | * |
||
5435 | * @param int|string $id |
||
5436 | * @return EE_Base_Class |
||
5437 | * @throws EE_Error |
||
5438 | */ |
||
5439 | public function refresh_entity_map_from_db($id) |
||
5461 | |||
5462 | |||
5463 | |||
5464 | /** |
||
5465 | * refresh_entity_map_with |
||
5466 | * Leaves the entry in the entity map alone, but updates it to match the provided |
||
5467 | * $replacing_model_obj (which we assume to be its equivalent but somehow NOT in the entity map). |
||
5468 | * This is useful if you have a model object you want to make authoritative over what's in the entity map currently. |
||
5469 | * Note: The old $replacing_model_obj should now be destroyed as it's now un-authoritative |
||
5470 | * |
||
5471 | * @param int|string $id |
||
5472 | * @param EE_Base_Class $replacing_model_obj |
||
5473 | * @return \EE_Base_Class |
||
5474 | * @throws EE_Error |
||
5475 | */ |
||
5476 | public function refresh_entity_map_with($id, $replacing_model_obj) |
||
5497 | |||
5498 | |||
5499 | |||
5500 | /** |
||
5501 | * Gets the EE class that corresponds to this model. Eg, for EEM_Answer that |
||
5502 | * would be EE_Answer.To import that class, you'd just add ".class.php" to the name, like so |
||
5503 | * require_once($this->_getClassName().".class.php"); |
||
5504 | * |
||
5505 | * @return string |
||
5506 | */ |
||
5507 | private function _get_class_name() |
||
5511 | |||
5512 | |||
5513 | |||
5514 | /** |
||
5515 | * Get the name of the items this model represents, for the quantity specified. Eg, |
||
5516 | * if $quantity==1, on EEM_Event, it would 'Event' (internationalized), otherwise |
||
5517 | * it would be 'Events'. |
||
5518 | * |
||
5519 | * @param int $quantity |
||
5520 | * @return string |
||
5521 | */ |
||
5522 | public function item_name($quantity = 1) |
||
5526 | |||
5527 | |||
5528 | |||
5529 | /** |
||
5530 | * Very handy general function to allow for plugins to extend any child of EE_TempBase. |
||
5531 | * If a method is called on a child of EE_TempBase that doesn't exist, this function is called |
||
5532 | * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments. Instead of |
||
5533 | * requiring a plugin to extend the EE_TempBase (which works fine is there's only 1 plugin, but when will that |
||
5534 | * happen?) they can add a hook onto 'filters_hook_espresso__{className}__{methodName}' (eg, |
||
5535 | * filters_hook_espresso__EE_Answer__my_great_function) and accepts 2 arguments: the object on which the function |
||
5536 | * was called, and an array of the original arguments passed to the function. Whatever their callback function |
||
5537 | * returns will be returned by this function. Example: in functions.php (or in a plugin): |
||
5538 | * add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3); function |
||
5539 | * my_callback($previousReturnValue,EE_TempBase $object,$argsArray){ |
||
5540 | * $returnString= "you called my_callback! and passed args:".implode(",",$argsArray); |
||
5541 | * return $previousReturnValue.$returnString; |
||
5542 | * } |
||
5543 | * require('EEM_Answer.model.php'); |
||
5544 | * $answer=EEM_Answer::instance(); |
||
5545 | * echo $answer->my_callback('monkeys',100); |
||
5546 | * //will output "you called my_callback! and passed args:monkeys,100" |
||
5547 | * |
||
5548 | * @param string $methodName name of method which was called on a child of EE_TempBase, but which |
||
5549 | * @param array $args array of original arguments passed to the function |
||
5550 | * @throws EE_Error |
||
5551 | * @return mixed whatever the plugin which calls add_filter decides |
||
5552 | */ |
||
5553 | View Code Duplication | public function __call($methodName, $args) |
|
5573 | |||
5574 | |||
5575 | |||
5576 | /** |
||
5577 | * Ensures $base_class_obj_or_id is of the EE_Base_Class child that corresponds ot this model. |
||
5578 | * If not, assumes its an ID, and uses $this->get_one_by_ID() to get the EE_Base_Class. |
||
5579 | * |
||
5580 | * @param EE_Base_Class|string|int $base_class_obj_or_id either: |
||
5581 | * the EE_Base_Class object that corresponds to this Model, |
||
5582 | * the object's class name |
||
5583 | * or object's ID |
||
5584 | * @param boolean $ensure_is_in_db if set, we will also verify this model object |
||
5585 | * exists in the database. If it does not, we add it |
||
5586 | * @throws EE_Error |
||
5587 | * @return EE_Base_Class |
||
5588 | */ |
||
5589 | public function ensure_is_obj($base_class_obj_or_id, $ensure_is_in_db = false) |
||
5629 | |||
5630 | |||
5631 | |||
5632 | /** |
||
5633 | * Similar to ensure_is_obj(), this method makes sure $base_class_obj_or_id |
||
5634 | * is a value of the this model's primary key. If it's an EE_Base_Class child, |
||
5635 | * returns it ID. |
||
5636 | * |
||
5637 | * @param EE_Base_Class|int|string $base_class_obj_or_id |
||
5638 | * @return int|string depending on the type of this model object's ID |
||
5639 | * @throws EE_Error |
||
5640 | */ |
||
5641 | public function ensure_is_ID($base_class_obj_or_id) |
||
5666 | |||
5667 | |||
5668 | |||
5669 | /** |
||
5670 | * Sets whether the values passed to the model (eg, values in WHERE, values in INSERT, UPDATE, etc) |
||
5671 | * have already been ran through the appropriate model field's prepare_for_use_in_db method. IE, they have |
||
5672 | * been sanitized and converted into the appropriate domain. |
||
5673 | * Usually the only place you'll want to change the default (which is to assume values have NOT been sanitized by |
||
5674 | * the model object/model field) is when making a method call from WITHIN a model object, which has direct access |
||
5675 | * to its sanitized values. Note: after changing this setting, you should set it back to its previous value (using |
||
5676 | * get_assumption_concerning_values_already_prepared_by_model_object()) eg. |
||
5677 | * $EVT = EEM_Event::instance(); $old_setting = |
||
5678 | * $EVT->get_assumption_concerning_values_already_prepared_by_model_object(); |
||
5679 | * $EVT->assume_values_already_prepared_by_model_object(true); |
||
5680 | * $EVT->update(array('foo'=>'bar'),array(array('foo'=>'monkey'))); |
||
5681 | * $EVT->assume_values_already_prepared_by_model_object($old_setting); |
||
5682 | * |
||
5683 | * @param int $values_already_prepared like one of the constants on EEM_Base |
||
5684 | * @return void |
||
5685 | */ |
||
5686 | public function assume_values_already_prepared_by_model_object( |
||
5691 | |||
5692 | |||
5693 | |||
5694 | /** |
||
5695 | * Read comments for assume_values_already_prepared_by_model_object() |
||
5696 | * |
||
5697 | * @return int |
||
5698 | */ |
||
5699 | public function get_assumption_concerning_values_already_prepared_by_model_object() |
||
5703 | |||
5704 | |||
5705 | |||
5706 | /** |
||
5707 | * Gets all the indexes on this model |
||
5708 | * |
||
5709 | * @return EE_Index[] |
||
5710 | */ |
||
5711 | public function indexes() |
||
5715 | |||
5716 | |||
5717 | |||
5718 | /** |
||
5719 | * Gets all the Unique Indexes on this model |
||
5720 | * |
||
5721 | * @return EE_Unique_Index[] |
||
5722 | */ |
||
5723 | public function unique_indexes() |
||
5733 | |||
5734 | |||
5735 | |||
5736 | /** |
||
5737 | * Gets all the fields which, when combined, make the primary key. |
||
5738 | * This is usually just an array with 1 element (the primary key), but in cases |
||
5739 | * where there is no primary key, it's a combination of fields as defined |
||
5740 | * on a primary index |
||
5741 | * |
||
5742 | * @return EE_Model_Field_Base[] indexed by the field's name |
||
5743 | * @throws EE_Error |
||
5744 | */ |
||
5745 | public function get_combined_primary_key_fields() |
||
5754 | |||
5755 | |||
5756 | |||
5757 | /** |
||
5758 | * Used to build a primary key string (when the model has no primary key), |
||
5759 | * which can be used a unique string to identify this model object. |
||
5760 | * |
||
5761 | * @param array $cols_n_values keys are field names, values are their values |
||
5762 | * @return string |
||
5763 | * @throws EE_Error |
||
5764 | */ |
||
5765 | public function get_index_primary_key_string($cols_n_values) |
||
5773 | |||
5774 | |||
5775 | |||
5776 | /** |
||
5777 | * Gets the field values from the primary key string |
||
5778 | * |
||
5779 | * @see EEM_Base::get_combined_primary_key_fields() and EEM_Base::get_index_primary_key_string() |
||
5780 | * @param string $index_primary_key_string |
||
5781 | * @return null|array |
||
5782 | * @throws EE_Error |
||
5783 | */ |
||
5784 | public function parse_index_primary_key_string($index_primary_key_string) |
||
5797 | |||
5798 | |||
5799 | |||
5800 | /** |
||
5801 | * verifies that an array of key-value pairs for model fields has a key |
||
5802 | * for each field comprising the primary key index |
||
5803 | * |
||
5804 | * @param array $key_vals |
||
5805 | * @return boolean |
||
5806 | * @throws EE_Error |
||
5807 | */ |
||
5808 | public function has_all_combined_primary_key_fields($key_vals) |
||
5818 | |||
5819 | |||
5820 | |||
5821 | /** |
||
5822 | * Finds all model objects in the DB that appear to be a copy of $model_object_or_attributes_array. |
||
5823 | * We consider something to be a copy if all the attributes match (except the ID, of course). |
||
5824 | * |
||
5825 | * @param array|EE_Base_Class $model_object_or_attributes_array If its an array, it's field-value pairs |
||
5826 | * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
||
5827 | * @throws EE_Error |
||
5828 | * @return \EE_Base_Class[] Array keys are object IDs (if there is a primary key on the model. if not, numerically |
||
5829 | * indexed) |
||
5830 | */ |
||
5831 | public function get_all_copies($model_object_or_attributes_array, $query_params = array()) |
||
5855 | |||
5856 | |||
5857 | |||
5858 | /** |
||
5859 | * Gets the first copy we find. See get_all_copies for more details |
||
5860 | * |
||
5861 | * @param mixed EE_Base_Class | array $model_object_or_attributes_array |
||
5862 | * @param array $query_params |
||
5863 | * @return EE_Base_Class |
||
5864 | * @throws EE_Error |
||
5865 | */ |
||
5866 | View Code Duplication | public function get_one_copy($model_object_or_attributes_array, $query_params = array()) |
|
5886 | |||
5887 | |||
5888 | |||
5889 | /** |
||
5890 | * Updates the item with the specified id. Ignores default query parameters because |
||
5891 | * we have specified the ID, and its assumed we KNOW what we're doing |
||
5892 | * |
||
5893 | * @param array $fields_n_values keys are field names, values are their new values |
||
5894 | * @param int|string $id the value of the primary key to update |
||
5895 | * @return int number of rows updated |
||
5896 | * @throws EE_Error |
||
5897 | */ |
||
5898 | public function update_by_ID($fields_n_values, $id) |
||
5906 | |||
5907 | |||
5908 | |||
5909 | /** |
||
5910 | * Changes an operator which was supplied to the models into one usable in SQL |
||
5911 | * |
||
5912 | * @param string $operator_supplied |
||
5913 | * @return string an operator which can be used in SQL |
||
5914 | * @throws EE_Error |
||
5915 | */ |
||
5916 | private function _prepare_operator_for_sql($operator_supplied) |
||
5934 | |||
5935 | |||
5936 | |||
5937 | /** |
||
5938 | * Gets the valid operators |
||
5939 | * @return array keys are accepted strings, values are the SQL they are converted to |
||
5940 | */ |
||
5941 | public function valid_operators() |
||
5945 | |||
5946 | |||
5947 | |||
5948 | /** |
||
5949 | * Gets the between-style operators (take 2 arguments). |
||
5950 | * @return array keys are accepted strings, values are the SQL they are converted to |
||
5951 | */ |
||
5952 | public function valid_between_style_operators() |
||
5959 | |||
5960 | /** |
||
5961 | * Gets the "like"-style operators (take a single argument, but it may contain wildcards) |
||
5962 | * @return array keys are accepted strings, values are the SQL they are converted to |
||
5963 | */ |
||
5964 | public function valid_like_style_operators() |
||
5971 | |||
5972 | /** |
||
5973 | * Gets the "in"-style operators |
||
5974 | * @return array keys are accepted strings, values are the SQL they are converted to |
||
5975 | */ |
||
5976 | public function valid_in_style_operators() |
||
5983 | |||
5984 | /** |
||
5985 | * Gets the "null"-style operators (accept no arguments) |
||
5986 | * @return array keys are accepted strings, values are the SQL they are converted to |
||
5987 | */ |
||
5988 | public function valid_null_style_operators() |
||
5995 | |||
5996 | /** |
||
5997 | * Gets an array where keys are the primary keys and values are their 'names' |
||
5998 | * (as determined by the model object's name() function, which is often overridden) |
||
5999 | * |
||
6000 | * @param array $query_params like get_all's |
||
6001 | * @return string[] |
||
6002 | * @throws EE_Error |
||
6003 | */ |
||
6004 | public function get_all_names($query_params = array()) |
||
6013 | |||
6014 | |||
6015 | |||
6016 | /** |
||
6017 | * Gets an array of primary keys from the model objects. If you acquired the model objects |
||
6018 | * using EEM_Base::get_all() you don't need to call this (and probably shouldn't because |
||
6019 | * this is duplicated effort and reduces efficiency) you would be better to use |
||
6020 | * array_keys() on $model_objects. |
||
6021 | * |
||
6022 | * @param \EE_Base_Class[] $model_objects |
||
6023 | * @param boolean $filter_out_empty_ids if a model object has an ID of '' or 0, don't bother including it |
||
6024 | * in the returned array |
||
6025 | * @return array |
||
6026 | * @throws EE_Error |
||
6027 | */ |
||
6028 | public function get_IDs($model_objects, $filter_out_empty_ids = false) |
||
6063 | |||
6064 | |||
6065 | |||
6066 | /** |
||
6067 | * Returns the string used in capabilities relating to this model. If there |
||
6068 | * are no capabilities that relate to this model returns false |
||
6069 | * |
||
6070 | * @return string|false |
||
6071 | */ |
||
6072 | public function cap_slug() |
||
6076 | |||
6077 | |||
6078 | |||
6079 | /** |
||
6080 | * Returns the capability-restrictions array (@see EEM_Base::_cap_restrictions). |
||
6081 | * If $context is provided (which should be set to one of EEM_Base::valid_cap_contexts()) |
||
6082 | * only returns the cap restrictions array in that context (ie, the array |
||
6083 | * at that key) |
||
6084 | * |
||
6085 | * @param string $context |
||
6086 | * @return EE_Default_Where_Conditions[] indexed by associated capability |
||
6087 | * @throws EE_Error |
||
6088 | */ |
||
6089 | public function cap_restrictions($context = EEM_Base::caps_read) |
||
6110 | |||
6111 | |||
6112 | |||
6113 | /** |
||
6114 | * Indicating whether or not this model thinks its a wp core model |
||
6115 | * |
||
6116 | * @return boolean |
||
6117 | */ |
||
6118 | public function is_wp_core_model() |
||
6122 | |||
6123 | |||
6124 | |||
6125 | /** |
||
6126 | * Gets all the caps that are missing which impose a restriction on |
||
6127 | * queries made in this context |
||
6128 | * |
||
6129 | * @param string $context one of EEM_Base::caps_ constants |
||
6130 | * @return EE_Default_Where_Conditions[] indexed by capability name |
||
6131 | * @throws EE_Error |
||
6132 | */ |
||
6133 | public function caps_missing($context = EEM_Base::caps_read) |
||
6146 | |||
6147 | |||
6148 | |||
6149 | /** |
||
6150 | * Gets the mapping from capability contexts to action strings used in capability names |
||
6151 | * |
||
6152 | * @return array keys are one of EEM_Base::valid_cap_contexts(), and values are usually |
||
6153 | * one of 'read', 'edit', or 'delete' |
||
6154 | */ |
||
6155 | public function cap_contexts_to_cap_action_map() |
||
6163 | |||
6164 | |||
6165 | |||
6166 | /** |
||
6167 | * Gets the action string for the specified capability context |
||
6168 | * |
||
6169 | * @param string $context |
||
6170 | * @return string one of EEM_Base::cap_contexts_to_cap_action_map() values |
||
6171 | * @throws EE_Error |
||
6172 | */ |
||
6173 | public function cap_action_for_context($context) |
||
6190 | |||
6191 | |||
6192 | |||
6193 | /** |
||
6194 | * Returns all the capability contexts which are valid when querying models |
||
6195 | * |
||
6196 | * @return array |
||
6197 | */ |
||
6198 | public static function valid_cap_contexts() |
||
6207 | |||
6208 | |||
6209 | |||
6210 | /** |
||
6211 | * Returns all valid options for 'default_where_conditions' |
||
6212 | * |
||
6213 | * @return array |
||
6214 | */ |
||
6215 | public static function valid_default_where_conditions() |
||
6226 | |||
6227 | // public static function default_where_conditions_full |
||
6228 | /** |
||
6229 | * Verifies $context is one of EEM_Base::valid_cap_contexts(), if not it throws an exception |
||
6230 | * |
||
6231 | * @param string $context |
||
6232 | * @return bool |
||
6233 | * @throws EE_Error |
||
6234 | */ |
||
6235 | public static function verify_is_valid_cap_context($context) |
||
6253 | |||
6254 | |||
6255 | |||
6256 | /** |
||
6257 | * Clears all the models field caches. This is only useful when a sub-class |
||
6258 | * might have added a field or something and these caches might be invalidated |
||
6259 | */ |
||
6260 | protected function _invalidate_field_caches() |
||
6266 | |||
6267 | |||
6268 | |||
6269 | /** |
||
6270 | * Gets the list of all the where query param keys that relate to logic instead of field names |
||
6271 | * (eg "and", "or", "not"). |
||
6272 | * |
||
6273 | * @return array |
||
6274 | */ |
||
6275 | public function logic_query_param_keys() |
||
6279 | |||
6280 | |||
6281 | |||
6282 | /** |
||
6283 | * Determines whether or not the where query param array key is for a logic query param. |
||
6284 | * Eg 'OR', 'not*', and 'and*because-i-say-so' should all return true, whereas |
||
6285 | * 'ATT_fname', 'EVT_name*not-you-or-me', and 'ORG_name' should return false |
||
6286 | * |
||
6287 | * @param $query_param_key |
||
6288 | * @return bool |
||
6289 | */ |
||
6290 | public function is_logic_query_param_key($query_param_key) |
||
6301 | |||
6302 | /** |
||
6303 | * Returns true if this model has a password field on it (regardless of whether that password field has any content) |
||
6304 | * @since 4.9.74.p |
||
6305 | * @return boolean |
||
6306 | */ |
||
6307 | public function hasPassword() |
||
6316 | |||
6317 | /** |
||
6318 | * Returns the password field on this model, if there is one |
||
6319 | * @since 4.9.74.p |
||
6320 | * @return EE_Password_Field|null |
||
6321 | */ |
||
6322 | public function getPasswordField() |
||
6332 | |||
6333 | |||
6334 | /** |
||
6335 | * Returns the list of field (as EE_Model_Field_Bases) that are protected by the password |
||
6336 | * @since 4.9.74.p |
||
6337 | * @return EE_Model_Field_Base[] |
||
6338 | * @throws EE_Error |
||
6339 | */ |
||
6340 | public function getPasswordProtectedFields() |
||
6352 | |||
6353 | |||
6354 | /** |
||
6355 | * Checks if the current user can perform the requested action on this model |
||
6356 | * @since 4.9.74.p |
||
6357 | * @param string $cap_to_check one of the array keys from _cap_contexts_to_cap_action_map |
||
6358 | * @param EE_Base_Class|array $model_obj_or_fields_n_values |
||
6359 | * @return bool |
||
6360 | * @throws EE_Error |
||
6361 | * @throws InvalidArgumentException |
||
6362 | * @throws InvalidDataTypeException |
||
6363 | * @throws InvalidInterfaceException |
||
6364 | * @throws ReflectionException |
||
6365 | * @throws UnexpectedEntityException |
||
6366 | */ |
||
6367 | public function currentUserCan($cap_to_check, $model_obj_or_fields_n_values) |
||
6392 | |||
6393 | /** |
||
6394 | * Returns the query param where conditions key to the password affecting this model. |
||
6395 | * Eg on EEM_Event this would just be "password", on EEM_Datetime this would be "Event.password", etc. |
||
6396 | * @since 4.9.74.p |
||
6397 | * @return null|string |
||
6398 | * @throws EE_Error |
||
6399 | * @throws InvalidArgumentException |
||
6400 | * @throws InvalidDataTypeException |
||
6401 | * @throws InvalidInterfaceException |
||
6402 | * @throws ModelConfigurationException |
||
6403 | * @throws ReflectionException |
||
6404 | */ |
||
6405 | public function modelChainAndPassword() |
||
6449 | |||
6450 | /** |
||
6451 | * Returns true if there is a password on a related model which restricts access to some of this model's rows, |
||
6452 | * or if this model itself has a password affecting access to some of its other fields. |
||
6453 | * @since 4.9.74.p |
||
6454 | * @return boolean |
||
6455 | */ |
||
6456 | public function restrictedByRelatedModelPassword() |
||
6460 | } |
||
6461 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
string
values, the empty string''
is a special case, in particular the following results might be unexpected: