BMLT Root Server
c_comdef_meeting.class.php
Go to the documentation of this file.
1 <?php
2 /***********************************************************************/
3 /** \file c_comdef_meeting.class.php
4  \brief The file for the c_comdef_meeting class.
5 
6  This file is part of the Basic Meeting List Toolbox (BMLT).
7 
8  Find out more at: https://bmlt.app
9 
10  BMLT is free software: you can redistribute it and/or modify
11  it under the terms of the MIT License.
12 
13  BMLT is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  MIT License for more details.
17 
18  You should have received a copy of the MIT License along with this code.
19  If not, see <https://opensource.org/licenses/MIT>.
20 */
21 defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context.
22 
23 require_once(dirname(__FILE__)."/../shared/classes/base_templates.inc.php");
24 
25 /**
26  defines for the visibility field of the data items.
27  - Values include:
28  - null or 0 if completely visible (default)
29  - 1 if visible only to logged-in admins and internal processes
30  - 2 if visible only when displayed on a regular Web page or a Mobile page
31  - 3 if visible only when displayed on a regular Web page
32  - 4 if visible only when displayed on a Mobile page
33  - 5 if visible only when printed
34 */
35 
36 define('_VISIBILITY_ALL_', 0);
37 define('_VISIBILITY_NONE_', 1);
38 define('_VISIBILITY_WEB_MOB_', 2);
39 define('_VISIBILITY_WEB_', 3);
40 define('_VISIBILITY_MOB_', 4);
41 define('_VISIBILITY_PRINT_', 5);
42 
43 /***********************************************************************/
44 /** \class c_comdef_meeting
45  \brief A class to hold a single meeting object.
46 
47 ***********************************************************************/
48 // phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
49 // phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
51 // phpcs:enable PSR1.Classes.ClassDeclaration.MissingNamespace
52 // phpcs:enable Squiz.Classes.ValidClassName.NotCamelCaps
53 {
54  /// This is the data for this meeting.
55  private $_my_meeting_data = null;
56 
57  /*******************************************************************/
58  /** \brief Returns the object, in 3 storable arrays.
59 
60  This "unwinds" the object's central data, turning it from a single
61  compound array, with object references, into 3 standalone arrays.
62 
63  \returns an array, containing 3 arrays; one for each table.
64  */
65  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
66  public function ReduceToArrays()
67  {
68  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
69  // We first see whether this is a new instance or an existing one. A new instance will have no ID.
70  $is_update = ( isset($this->_my_meeting_data['id_bigint']) && (0 < intval($this->_my_meeting_data['id_bigint']) ) );
71 
72  // We now set up values for the three tables: The main one, the extra data one, and the long data one.
73  $main_table_values = array();
74  $data_table_values = array();
75  $longdata_table_values = array();
76 
77  // If this is a new meeting, we null it out so that the db will auto increment the value
78  if (!$is_update) {
79  $this->_my_meeting_data['id_bigint'] = null;
80  }
81 
82  // Load the main table first.
83  $main_table_values['id_bigint'] = $this->_my_meeting_data['id_bigint'];
84 
85  if (isset($this->_my_meeting_data['email_contact'])) {
86  $main_table_values['email_contact'] = $this->_my_meeting_data['email_contact'];
87  } else {
88  $main_table_values['email_contact'] = null;
89  }
90  if (isset($this->_my_meeting_data['worldid_mixed'])) {
91  $main_table_values['worldid_mixed'] = $this->_my_meeting_data['worldid_mixed'];
92  } else {
93  $main_table_values['worldid_mixed'] = null;
94  }
95  if (isset($this->_my_meeting_data['service_body_bigint'])) {
96  $main_table_values['service_body_bigint'] = $this->_my_meeting_data['service_body_bigint'];
97  } else {
98  $main_table_values['service_body_bigint'] = null;
99  }
100  if (isset($this->_my_meeting_data['weekday_tinyint'])) {
101  $main_table_values['weekday_tinyint'] = $this->_my_meeting_data['weekday_tinyint'] - 1;
102  } else {
103  $main_table_values['weekday_tinyint'] = null;
104  }
105  if (isset($this->_my_meeting_data['start_time'])) {
106  $main_table_values['start_time'] = $this->_my_meeting_data['start_time'];
107  } else {
108  $main_table_values['start_time'] = null;
109  }
110  if (isset($this->_my_meeting_data['lang_enum'])) {
111  $main_table_values['lang_enum'] = $this->_my_meeting_data['lang_enum'];
112  } else {
113  $main_table_values['lang_enum'] = "en"; // Should never happen.
114  }
115  if (isset($this->_my_meeting_data['duration_time'])) {
116  $main_table_values['duration_time'] = $this->_my_meeting_data['duration_time'];
117  } else {
118  $main_table_values['duration_time'] = null;
119  }
120  if (isset($this->_my_meeting_data['time_zone'])) {
121  $main_table_values['time_zone'] = $this->_my_meeting_data['time_zone'];
122  } else {
123  $main_table_values['time_zone'] = null;
124  }
125  if (isset($this->_my_meeting_data['longitude'])) {
126  $main_table_values['longitude'] = $this->_my_meeting_data['longitude'];
127  } else {
128  $main_table_values['longitude'] = null;
129  }
130  if (isset($this->_my_meeting_data['latitude'])) {
131  $main_table_values['latitude'] = $this->_my_meeting_data['latitude'];
132  } else {
133  $main_table_values['latitude'] = null;
134  }
135  if (isset($this->_my_meeting_data['published'])) {
136  $main_table_values['published'] = $this->_my_meeting_data['published'];
137  } else {
138  $main_table_values['published'] = 0;
139  }
140 
141  // Now, we "unwind" the formats. Remember that we made the formats into an array, and replaced the values with objects, so we just use the keys here.
142  $main_table_values['formats'] = "";
143  if (isset($this->_my_meeting_data['formats']) && is_array($this->_my_meeting_data['formats']) && count($this->_my_meeting_data['formats'])) {
144  foreach ($this->_my_meeting_data['formats'] as $key => $value2) {
145  if ($main_table_values['formats']) {
146  $main_table_values['formats'] .= ",";
147  }
148  $main_table_values['formats'] .= $key;
149  }
150  }
151 
152  // Okay, that does it for the main table. Time to do the two data tables. The way we do that is very simple: We just measure how many bytes are in the data.
153  // Anything over 255 characters in length becomes a member of the longdata table.
154  foreach ($this->_my_meeting_data as $key => $value2) {
155  // We ignore the values in the main table.
156  switch ($key) {
157  case 'published':
158  case 'id_bigint':
159  case 'worldid_mixed':
160  case 'service_body_bigint':
161  case 'weekday_tinyint':
162  case 'start_time':
163  case 'lang_enum':
164  case 'duration_time':
165  case 'time_zone':
166  case 'formats':
167  case 'longitude':
168  case 'latitude':
169  case 'distance_in_km':
170  case 'distance_in_miles':
171  case 'email_contact':
172  break;
173 
174  // Everything else goes into one of the other tables.
175  default:
176  $data_table_value['data_bigint'] = null;
177  unset($data_table_value['data_bigint']);
178  $data_table_value['data_double'] = null;
179  unset($data_table_value['data_double']);
180  $longdata_table_value['data_blob'] = null;
181  unset($longdata_table_value['data_blob']);
182 
183  if (isset($this->_my_meeting_data[$key]['value']) && ( null != $this->_my_meeting_data[$key]['value'] )) {
184  $val = null;
185  $val_key = null;
186  // We reference the correct table for our operation.
187  if (is_int($this->_my_meeting_data[$key]['value'])) {
188  $val_key = 'data_bigint';
189  $val = intval($this->_my_meeting_data[$key]['value']);
190  } elseif (is_float($this->_my_meeting_data[$key]['value'])) {
191  $val_key = 'data_double';
192  $val = floatval($this->_my_meeting_data[$key]['value']);
193  } else {
194  $datalen = strlen($this->_my_meeting_data[$key]['value']);
195  if ($datalen) {
196  // We use the correct table for our operation.
197  if ($datalen > 255) {
198  $longdata_table_value['meetingid_bigint'] = $main_table_values['id_bigint'];
199  $longdata_table_value['lang_enum'] = $this->_my_meeting_data['lang_enum'];
200  $longdata_table_value['field_prompt'] = $this->_my_meeting_data[$key]['prompt'];
201  $longdata_table_value['visibility'] = $this->_my_meeting_data[$key]['visibility'];
202  $longdata_table_value['key'] = $key;
203  // We reference the data, as it may be pretty long.
204  $longdata_table_value['data_blob'] = $this->_my_meeting_data[$key]['value'];
205  $val = null;
206  array_push($longdata_table_values, $longdata_table_value);
207  } else {
208  $val_key = 'data_string';
209  $val = stripslashes($this->_my_meeting_data[$key]['value']);
210  }
211  }
212  }
213 
214  if (null != $val) {
215  $data_table_value['meetingid_bigint'] = $main_table_values['id_bigint'];
216  $data_table_value['lang_enum'] = $this->_my_meeting_data['lang_enum'];
217  $data_table_value['field_prompt'] = $this->_my_meeting_data[$key]['prompt'];
218  $data_table_value['visibility'] = $this->_my_meeting_data[$key]['visibility'];
219  $data_table_value['key'] = $key;
220  $data_table_value[$val_key] = $val;
221  array_push($data_table_values, $data_table_value);
222  }
223  }
224  break;
225  }
226  }
227 
228  $ret_array = array ();
229 
230  array_push($ret_array, $main_table_values);
231  array_push($ret_array, $data_table_values);
232  array_push($ret_array, $longdata_table_values);
233 
234  return $ret_array;
235  }
236 
237  /*******************************************************************/
238  /** \brief Updates the DB to the current values of this instance.
239  (replacing current values of the DB).
240 
241  \returns true if successful, false, otherwise.
242 
243  \throws a PDOException if there is a problem.
244  */
245  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
246  public function UpdateToDB(
247  $is_rollback = false ///< If true, this is a rollback operation.
248  ) {
249  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
250  $ret = false;
251 
253 
254  if ($this->UserCanEdit($user)) {
255  // We take a snapshot of the meeting as it currently sits in the database as a "before" image.
256  $before = null;
257  $before_id = null;
258  $before_lang = null;
259  $service_body_id = null;
260  $before_obj = c_comdef_server::GetServer()->GetOneMeeting($this->GetID());
261 
262  if ($before_obj instanceof c_comdef_meeting) {
263  $service_body_id = $before_obj->GetServiceBodyID();
264  $before = $before_obj->SerializeObject();
265  $before_id = $before_obj->GetID();
266  $before_lang = $before_obj->GetLocalLang();
267  $before_obj = null;
268  }
269 
270  if (null == $service_body_id) {
271  $service_body_id = $this->GetServiceBodyID();
272  }
273 
274  try {
275  // We now set up values for the three tables: The main one, the extra data one, and the long data one.
276  list ( $main_table_values, $data_table_values, $longdata_table_values ) = $this->ReduceToArrays();
277  // Okay, we have our three rows. Time to send them to the database.
278 
279 
280  if (is_array($main_table_values) && count($main_table_values)) {
281  // The first thing we do is delete the current entry. We'll insert a new one.
282  $this->DeleteFromDB_NoRecord();
283 
284  $first = true;
285  $updateSQL = "INSERT INTO `".c_comdef_server::GetMeetingTableName_obj()."_main` (";
286  foreach ($main_table_values as $key => $value) {
287  if (!$first) {
288  $updateSQL .= ",";
289  } else {
290  $first = false;
291  }
292  $updateSQL .= "`$key`";
293  }
294  $first = true;
295  $vals = array();
296  $updateSQL .= ") VALUES (";
297  foreach ($main_table_values as $key => $value) {
298  if (!$first) {
299  $updateSQL .= ",";
300  } else {
301  $first = false;
302  }
303  /// We give the prepared statement a token, that will be filled by a value.
304  $updateSQL .= ":$key";
305  /// We give the value by declaring an associative array element with the token name.
306  $vals[":$key"] = $value;
307  }
308 
309  $updateSQL .= ")";
310 
311  c_comdef_dbsingleton::preparedExec($updateSQL, $vals);
312  if (is_null($this->_my_meeting_data['id_bigint'])) {
313  // This was a new meeting, need to get the generated id
314  $newMeetingId = intval(c_comdef_dbsingleton::lastInsertId());
315  $this->_my_meeting_data['id_bigint'] = $newMeetingId;
316  list ( $main_table_values, $data_table_values, $longdata_table_values ) = $this->ReduceToArrays();
317  }
318 
319  if (is_array($data_table_values) && count($data_table_values)) {
320  foreach ($data_table_values as $data_table_value) {
321  $first = true;
322  $updateSQL = "INSERT INTO `".c_comdef_server::GetMeetingTableName_obj()."_data` (";
323  foreach ($data_table_value as $key => $value) {
324  if (!$first) {
325  $updateSQL .= ",";
326  } else {
327  $first = false;
328  }
329  $updateSQL .= "`$key`";
330  }
331  $first = true;
332  $vals = array();
333  $updateSQL .= ") VALUES (";
334  foreach ($data_table_value as $key => $value) {
335  // Just in case some dork wants to change the meeting ID (BAD idea).
336  if ($key == 'meetingid_bigint') {
337  $value = $main_table_values['id_bigint'];
338  }
339 
340  if (!$first) {
341  $updateSQL .= ",";
342  } else {
343  $first = false;
344  }
345  /// We give the prepared statement a token, that will be filled by a value.
346  $updateSQL .= ":$key";
347  /// We give the value by declaring an associative array element with the token name.
348  $vals[":$key"] = $value;
349  }
350 
351  $updateSQL .= ")";
352 
353  c_comdef_dbsingleton::preparedExec($updateSQL, $vals);
354  }
355  }
356 
357  if (is_array($longdata_table_values) && count($longdata_table_values)) {
358  foreach ($longdata_table_values as $longdata_table_value) {
359  $first = true;
360  $updateSQL = "INSERT INTO `".c_comdef_server::GetMeetingTableName_obj()."_longdata` (";
361  foreach ($longdata_table_value as $key => $value) {
362  // Just in case some dork wants to change the meeting ID (BAD idea).
363  if ($key == 'meetingid_bigint') {
364  $value = $main_table_values['id_bigint'];
365  }
366 
367  if (!$first) {
368  $updateSQL .= ",";
369  } else {
370  $first = false;
371  }
372  $updateSQL .= "`$key`";
373  }
374  $first = true;
375  $vals = array();
376  $updateSQL .= ") VALUES (";
377  foreach ($longdata_table_value as $key => $value) {
378  if (!$first) {
379  $updateSQL .= ",";
380  } else {
381  $first = false;
382  }
383  /// We give the prepared statement a token, that will be filled by a value.
384  $updateSQL .= ":$key";
385  /// We give the value by declaring an associative array element with the token name.
386  $vals[":$key"] = $value;
387  }
388 
389  $updateSQL .= ")";
390 
391  c_comdef_dbsingleton::preparedExec($updateSQL, $vals);
392  }
393  }
394  $after = $this->SerializeObject();
395  $after_id = $this->GetID();
396  $after_lang = $this->GetLocalLang();
397  $cType = (true == $is_rollback) ? 'comdef_change_type_rollback' : ((null != $before) ? 'comdef_change_type_change' : 'comdef_change_type_new');
398  c_comdef_server::AddNewChange($user->GetID(), $cType, $service_body_id, $before, $after, 'c_comdef_meeting', $before_id, $after_id, $before_lang, $after_lang);
399  $ret = true;
400  }
401  } catch (Exception $ex) {
402  global $_COMDEF_DEBUG;
403 
404  if ($_COMDEF_DEBUG) {
405  echo "Exception Thrown in c_comdef_meeting::UpdateToDB()!<br />";
406  var_dump($ex);
407  }
408  throw ( $ex );
409  }
410  }
411 
412  return $ret;
413  }
414 
415  /*******************************************************************/
416  /** \brief Deletes this instance from the database.
417 
418  \returns true if successful, false, otherwise.
419 
420  \throws a PDOException if there is a problem.
421  */
422  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
423  public function DeleteFromDB_NoRecord()
424  {
425  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
426  $ret = false;
427 
429 
430  if ($this->UserCanEdit($user)) {
431  try {
432  $sql = "DELETE FROM `".c_comdef_server::GetMeetingTableName_obj()."_main` WHERE `id_bigint`=?";
433  c_comdef_dbsingleton::preparedExec($sql, array ( $this->_my_meeting_data['id_bigint'] ));
434  $sql = "DELETE FROM `".c_comdef_server::GetMeetingTableName_obj()."_data` WHERE `meetingid_bigint`=?";
435  c_comdef_dbsingleton::preparedExec($sql, array ( $this->_my_meeting_data['id_bigint'] ));
436  $sql = "DELETE FROM `".c_comdef_server::GetMeetingTableName_obj()."_longdata` WHERE `meetingid_bigint`=?";
437  c_comdef_dbsingleton::preparedExec($sql, array ( $this->_my_meeting_data['id_bigint'] ));
438  $ret = true;
439  } catch (Exception $ex) {
440  global $_COMDEF_DEBUG;
441 
442  if ($_COMDEF_DEBUG) {
443  echo "Exception Thrown in c_comdef_meeting::DeleteFromDB()!<br />";
444  var_dump($ex);
445  }
446  throw ( $ex );
447  }
448  }
449 
450  return $ret;
451  }
452 
453  /*******************************************************************/
454  /** \brief Deletes this instance from the database.
455 
456  \returns true if successful, false, otherwise.
457 
458  \throws a PDOException if there is a problem.
459  */
460  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
461  public function DeleteFromDB()
462  {
463  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
464  $ret = false;
465 
467 
468  if ($this->UserCanEdit($user)) {
469  // We take a snapshot of the meeting as it currently sits in the database as a "before" image.
470  $service_body_id = $this->GetServiceBodyID();
471  $id = $this->GetID();
472  $lang = $this->GetLocalLang();
473  $before = $this->SerializeObject();
474 
475  try {
476  $ret = $this->DeleteFromDB_NoRecord();
477 
478  c_comdef_server::AddNewChange($user->GetID(), 'comdef_change_type_delete', $service_body_id, $before, '', 'c_comdef_meeting', $id, null, $lang, null);
479 
480  $ret = true;
481  } catch (Exception $ex) {
482  global $_COMDEF_DEBUG;
483 
484  if ($_COMDEF_DEBUG) {
485  echo "Exception Thrown in c_comdef_meeting::DeleteFromDB()!<br />";
486  var_dump($ex);
487  }
488  throw ( $ex );
489  }
490  }
491 
492  return $ret;
493  }
494 
495  /*******************************************************************/
496  /** \brief Updates this instance to the current values in the DB
497  (replacing current values of the instance).
498 
499  \throws a PDOException if there is a problem.
500  */
501  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
502  public function RestoreFromDB()
503  {
504  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
505  try {
506  $sql = "SELECT * FROM `".c_comdef_server::GetMeetingTableName_obj()."_main` WHERE id_bigint=? LIMIT 1";
507 
508  $rows = c_comdef_dbsingleton::preparedQuery($sql, array ( $this->GetID() ));
509 
510  if (is_array($rows) && count($rows)) {
511  foreach ($rows as $row) {
512  $meeting_row = self::process_meeting_row($row);
513  $this->_my_meeting_data = null;
514  // We set this as our data.
515  $this->_my_meeting_data = $meeting_row;
516  }
517  }
518  } catch (Exception $ex) {
519  global $_COMDEF_DEBUG;
520 
521  if ($_COMDEF_DEBUG) {
522  echo "Exception Thrown in c_comdef_meeting::RestoreFromDB()!<br />";
523  var_dump($ex);
524  }
525  throw ( $ex );
526  }
527  }
528 
529  /*******************************************************************/
530  /** \brief Return an array of data item keys that are used to build an address.
531 
532  \returns an array of strings, containing the data item field keys.
533 
534  \throws an exception if there is a problem.
535  */
536  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
537  public static function GetAddressDataItemKeys( $in_list = false ///< If this is true, then the return is for the list view. If false, for the "More Details" screen.
538  )
539  {
540  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
541  $ret = null;
542 
544 
545  // At this point, we have the format strings. We mow parse them to get the keys used for address display.
546  // The data item keys are surrounded by sets of double percent signs (%%_key_%%).
547  $string_to_parse = $local_strings['comdef_global_more_details_address'];
548 
549  if ($in_list) {
550  $string_to_parse = $local_strings['comdef_global_list_address'];
551  }
552 
553  $matches = array();
554 
555  if (preg_match_all('#\%\%(.*?)\%\%#', $string_to_parse, $matches)) {
557  if (is_array($keys) && count($keys)) {
558  $ret = array();
559 
560  while ($elem = array_shift($matches[1])) {
561  if (in_array($elem, $keys)) {
562  array_push($ret, $elem);
563  }
564  }
565  }
566  }
567 
568  return $ret;
569  }
570 
571  /*******************************************************************/
572  /** \brief Return an array of data item keys, as well as their prefixes and suffixes, that are used to build an address.
573 
574  \returns an array of strings, containing the data item field keys.
575 
576  \throws an exception if there is a problem.
577  */
578  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
579  public static function GetAddressDataItemBuilder( $in_list = false ///< If this is true, then the return is for the list view. If false, for the "More Details" screen.
580  )
581  {
582  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
583  $ret = null;
584 
586 
587  // At this point, we have the format strings. We mow parse them to get the keys used for address display.
588  // The data item keys are surrounded by sets of double percent signs (%%_key_%%).
589  $string_to_parse = $local_strings['comdef_global_more_details_address'];
590 
591  if ($in_list) {
592  $string_to_parse = $local_strings['comdef_global_list_address'];
593  }
594 
595  $matches = array();
596 
597  $parse_targets = explode('@@', $string_to_parse);
598 
599  if (is_array($parse_targets) && count($parse_targets)) {
600  $ret = array ();
602 
603  if (is_array($keys) && count($keys)) {
604  foreach ($parse_targets as $target) {
605  $r['prefix'] = preg_replace('#(.*?)\%(.*)#', "$1", $target);
606  $r['key'] = preg_replace('#(.*?)\%\%(.*?)\%\%(.*)#', "$2", $target);
607  $r['suffix'] = preg_replace('#(.*)\%(.*?)$#', "$2", $target);
608 
609  if (in_array($r['key'], $keys)) {
610  array_push($ret, $r);
611  }
612  }
613  }
614  }
615 
616  return $ret;
617  }
618 
619  /*******************************************************************/
620  /** \brief Returns an array of strings, containing the keys (table columns)
621  used for all meetings (specified in ID 0 table rows).
622 
623  \returns an array of strings, with the key being the same as the value.
624  NOTE: This contains ALL possible keys.
625 
626  \throws a PDOException if there is a problem.
627  */
628  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
629  public static function GetAllMeetingKeys()
630  {
631  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
632  $ret = null;
633 
634  try {
635  // The main table always has these keys.
636  $ret['id_bigint'] = 'id_bigint';
637  $ret['worldid_mixed'] = 'worldid_mixed';
638  $ret['shared_group_id_bigint'] = 'shared_group_id_bigint';
639  $ret['service_body_bigint'] = 'service_body_bigint';
640  $ret['weekday_tinyint'] = 'weekday_tinyint';
641  $ret['start_time'] = 'start_time';
642  $ret['duration_time'] = 'duration_time';
643  $ret['time_zone'] = 'time_zone';
644  $ret['formats'] = 'formats';
645  $ret['lang_enum'] = 'lang_enum';
646  $ret['longitude'] = 'longitude';
647  $ret['latitude'] = 'latitude';
648  $ret['distance_in_km'] = 'distance_in_km';
649  $ret['distance_in_miles'] = 'distance_in_miles';
650  $ret['email_contact'] = 'email_contact';
651 
652  // For the data and longdata tables, the keys can be dynamic, and we create a "0" ID version of them to establish the possibilities.
653  $sql = "SELECT * FROM `".c_comdef_server::GetMeetingTableName_obj()."_data` WHERE meetingid_bigint=0";
654 
655  $rows = c_comdef_dbsingleton::preparedQuery($sql, array ( ));
656 
657  if (is_array($rows) && count($rows)) {
658  foreach ($rows as $row) {
659  $key = $row['key'];
660  $ret[$key] = $key;
661  }
662  }
663 
664  $sql = "SELECT * FROM `".c_comdef_server::GetMeetingTableName_obj()."_longdata` WHERE meetingid_bigint=0";
665 
666  $rows = c_comdef_dbsingleton::preparedQuery($sql, array ( ));
667 
668  if (is_array($rows) && count($rows)) {
669  foreach ($rows as $row) {
670  $key = $row['key'];
671  $ret[$key] = $key;
672  }
673  }
674  } catch (Exception $ex) {
675  global $_COMDEF_DEBUG;
676 
677  if ($_COMDEF_DEBUG) {
678  echo "Exception Thrown in c_comdef_meeting::GetAllMeetingKeys()!<br />";
679  var_dump($ex);
680  }
681  throw ( $ex );
682  }
683 
684  $ret['published'] = 'published'; // The last field is always the published flag.
685  return $ret;
686  }
687 
688  /*******************************************************************/
689  /** \brief Returns an array of values for the given key.
690 
691  \returns an array of strings, with the key being the same as the value.
692  NOTE: This contains ALL possible keys.
693 
694  \throws a PDOException if there is a problem.
695  */
696  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
697  public static function GetAllValuesForKey(
698  $inKey ///< The key to get all the values for.
699  ) {
700  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
701  $ret = null;
702 
703  try {
704  $rows = null;
705 
706  switch (strtolower(trim($inKey))) {
707  case 'shared_group_id_bigint':
708  case 'email_contact':
709  case 'distance_in_km':
710  case 'distance_in_miles':
711  case 'published':
712  break;
713 
714  case 'weekday_tinyint':
715  case 'id_bigint':
716  case 'worldid_mixed':
717  case 'service_body_bigint':
718  case 'start_time':
719  case 'duration_time':
720  case 'time_zone':
721  case 'formats':
722  case 'lang_enum':
723  case 'longitude':
724  case 'latitude':
725  $inKey = strtolower(trim($inKey));
726  $sql = "SELECT `$inKey`,`id_bigint`,`published` FROM `".c_comdef_server::GetMeetingTableName_obj()."_main` WHERE (`id_bigint` > 0) AND (`published`=1) ORDER BY ?";
727  $rows = c_comdef_dbsingleton::preparedQuery($sql, array ( $inKey ));
728  break;
729 
730  default:
731  $temp = self::GetDataTableTemplate();
732  if (isset($temp[$inKey]) && ($temp[$inKey]['visibility'] != 1)) {
733  $sql = "SELECT ".c_comdef_server::GetMeetingTableName_obj()."_main.published,".c_comdef_server::GetMeetingTableName_obj()."_data.meetingid_bigint,".c_comdef_server::GetMeetingTableName_obj()."_data.data_string,".c_comdef_server::GetMeetingTableName_obj()."_data.data_bigint,".c_comdef_server::GetMeetingTableName_obj()."_data.data_double FROM `".c_comdef_server::GetMeetingTableName_obj()."_data` INNER JOIN ".c_comdef_server::GetMeetingTableName_obj()."_main ON ".c_comdef_server::GetMeetingTableName_obj()."_main.id_bigint=".c_comdef_server::GetMeetingTableName_obj()."_data.meetingid_bigint WHERE (`key`=?) AND (`meetingid_bigint`>0) AND (".c_comdef_server::GetMeetingTableName_obj()."_main.published=1) ORDER BY ".c_comdef_server::GetMeetingTableName_obj()."_data.data_double, ".c_comdef_server::GetMeetingTableName_obj()."_data.data_bigint,".c_comdef_server::GetMeetingTableName_obj()."_data.data_string";
734  } else {
735  $temp = self::GetLongDataTableTemplate();
736  if (isset($temp[$inKey]) && ($temp[$inKey]['visibility'] != 1)) {
737  $sql = "SELECT ".c_comdef_server::GetMeetingTableName_obj()."_main.published,".c_comdef_server::GetMeetingTableName_obj()."_longdata.data_longtext,".c_comdef_server::GetMeetingTableName_obj()."_longdata.data_blob FROM `".c_comdef_server::GetMeetingTableName_obj()."_longdata` INNER JOIN ".c_comdef_server::GetMeetingTableName_obj()."_main ON ".c_comdef_server::GetMeetingTableName_obj()."_main.id_bigint=".c_comdef_server::GetMeetingTableName_obj()."_longdata.meetingid_bigint WHERE (`key`=?) AND (`meetingid_bigint`>0) AND (".c_comdef_server::GetMeetingTableName_obj()."_main.published=1)";
738  }
739  }
740  $rows = c_comdef_dbsingleton::preparedQuery($sql, array ( $inKey ));
741  break;
742  }
743 
744  if (is_array($rows) && count($rows)) {
745  foreach ($rows as $row) {
746  if (isset($row['published']) && $row['published']) {
747  $id = (isset($row['id_bigint']) && intval($row['id_bigint'])) ? intval($row['id_bigint']) : null;
748 
749  if (!$id) {
750  $id = (isset($row['meetingid_bigint']) && intval($row['meetingid_bigint'])) ? intval($row['meetingid_bigint']) : null;
751  }
752 
753  $value = null;
754  if (isset($row[$inKey])) {
755  $value = $row[$inKey];
756 
757  if ($inKey == 'weekday_tinyint') {
758  $value = intval($value) + 1;
759  }
760 
761  if ($inKey == 'formats') {
762  $value = explode(',', $value);
763  asort($value);
764  $value = implode("\t", $value);
765  }
766  }
767 
768  if (!$value && isset($row['data_string']) && trim($row['data_string'])) {
769  $value = str_replace(',', '&APOS&', trim($row['data_string']));
770  }
771 
772  if (!$value && isset($row['data_bigint'])) {
773  $value = intval($row['data_bigint']);
774  }
775 
776  if (!$value && isset($row['data_double'])) {
777  $value = floatval($row['data_double']);
778  }
779 
780  if (!$value && isset($row['data_longtext'])) {
781  $value = floatval($row['data_longtext']);
782  }
783 
784  if (!$value && isset($row['data_blob'])) {
785  $value = floatval($row['data_blob']);
786  }
787 
788  if (!$ret) {
789  $ret = array();
790  $ret['NULL'] = '';
791  }
792 
793  if ($value) {
794  $ids = null;
795 
796  if (isset($ret[$value])) {
797  $ids = explode('\t', $ret[$value]);
798  $ids[] = $id;
799  } else {
800  $ids = array ( $id );
801  }
802  $ret[$value] = implode('\t', $ids);
803  } else {
804  $ids = null;
805 
806  if (isset($ret['NULL'])) {
807  $ids = explode('\t', $ret['NULL']);
808  $ids[] = $id;
809  } else {
810  $ids = array ( $id );
811  }
812  $ret['NULL'] = trim(implode('\t', $ids));
813  }
814  }
815  }
816  }
817  } catch (Exception $ex) {
818  global $_COMDEF_DEBUG;
819 
820  if ($_COMDEF_DEBUG) {
821  echo "Exception Thrown in c_comdef_meeting::GetAllMeetingValues()!<br />";
822  var_dump($ex);
823  }
824  throw ( $ex );
825  }
826 
827  if (!$ret['NULL']) {
828  unset($ret['NULL']);
829  }
830 
831  return $ret;
832  }
833 
834  /*******************************************************************/
835  /** \brief Returns an array that provides a template for all tables
836 
837  \returns an array with all of the values.
838  */
839  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
840  public static function GetFullTemplate()
841  {
842  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
843  $main = self::GetMainDataTemplate();
844  $data = self::GetDataTableTemplate();
845  $longData = self::GetLongDataTableTemplate();
846 
847  $ret = array_merge($main, $data);
848  if (isset($longData) && is_array($longData) && count($longData)) {
849  $ret = array_merge($ret, $longData);
850  }
851 
852  return $ret;
853  }
854 
855  /*******************************************************************/
856  /** \brief Returns an array that provides a template for the main table
857  values (the standard values).
858 
859  \returns an array with all of the _main values.
860  */
861  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
862  public static function GetMainDataTemplate()
863  {
864  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
866 
867  $localized_strings = c_comdef_server::GetLocalStrings();
868 
869  $ret = array();
870 
871  $ret['id_bigint']['key'] = 'id_bigint';
872  $ret['worldid_mixed']['key'] = 'worldid_mixed';
873  $ret['shared_group_id_bigint']['key'] = 'shared_group_id_bigint';
874  $ret['service_body_bigint']['key'] = 'service_body_bigint';
875  $ret['weekday_tinyint']['key'] = 'weekday_tinyint';
876  $ret['start_time']['key'] = 'start_time';
877  $ret['duration_time']['key'] = 'duration_time';
878  $ret['time_zone']['key'] = 'time_zone';
879  $ret['formats']['key'] = 'formats';
880  $ret['lang_enum']['key'] = 'lang_enum';
881  $ret['longitude']['key'] = 'longitude';
882  $ret['latitude']['key'] = 'latitude';
883  $ret['published']['key'] = 'published';
884  $ret['email_contact']['key'] = 'email_contact';
885 
886  // Everything gets a lang_enum (determined by global server setting).
887  // Almost all are visibility 0 (everyone can see).
888  foreach ($ret as &$elem) {
889  $elem['visibility'] = ($elem['key'] == 'email_contact') ? 1 : 0; // Email contact is hidden.
890  $elem['lang_enum'] = $comdef_global_language;
891  $elem['field_prompt'] = $localized_strings['comdef_server_admin_strings']['main_prompts'][$elem['key']];
892  }
893  return $ret;
894  }
895 
896  /*******************************************************************/
897  /** \brief Returns an array that provides a template for the data table
898  values (the optional/additional values).
899 
900  \returns an array with all of the _data values.
901 
902  \throws a PDOException if there is a problem.
903  */
904  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
905  public static function GetDataTableTemplate()
906  {
907  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
908  $ret = array();
909 
910  try {
911  $sql = "SELECT * FROM `".c_comdef_server::GetMeetingTableName_obj()."_data` WHERE meetingid_bigint=0";
912 
913  $rows = c_comdef_dbsingleton::preparedQuery($sql, array());
914  foreach ($rows as $row) {
915  $ret[$row['key']]['key'] = $row['key'];
916  $ret[$row['key']]['field_prompt'] = $row['field_prompt'];
917  $ret[$row['key']]['visibility'] = $row['visibility'];
918  $ret[$row['key']]['lang_enum'] = $row['lang_enum'];
919  if ($row['data_string']) {
920  $ret[$row['key']]['value'] = $row['data_string'];
921  } elseif ($row['data_bigint']) {
922  $ret[$row['key']]['value'] = $row['data_bigint'];
923  } elseif ($row['data_double']) {
924  $ret[$row['key']]['value'] = $row['data_double'];
925  } else {
926  $ret[$row['key']]['value'] = null;
927  }
928  }
929  } catch (Exception $ex) {
930  global $_COMDEF_DEBUG;
931 
932  if ($_COMDEF_DEBUG) {
933  echo "Exception Thrown in c_comdef_meeting::GetDataTableTemplate()!<br />";
934  var_dump($ex);
935  }
936  throw ( $ex );
937  }
938 
939  return $ret;
940  }
941 
942  /*******************************************************************/
943  /** \brief Returns an array that provides a template for the long data table
944  values (the optional/additional values).
945 
946  \returns an array with all of the _longdata values.
947 
948  \throws a PDOException if there is a problem.
949  */
950  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
951  public static function GetLongDataTableTemplate(
952  $in_lang_enum = null ///< The language to use. If not given the server default will be used.
953  ) {
954  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
955  $ret = array();
956 
957  if (!$in_lang_enum) {
958  $in_lang_enum = c_comdef_server::GetServer()->GetLocalLang();
959  }
960 
961  // Should never happen.
962  if (!$in_lang_enum) {
963  $in_lang_enum = "en";
964  }
965 
966  try {
967  $sql = "SELECT * FROM `".c_comdef_server::GetMeetingTableName_obj()."_longdata` WHERE meetingid_bigint=0 AND lang_enum=?";
968 
969  $rows = c_comdef_dbsingleton::preparedQuery($sql, array ( $in_lang_enum ));
970  foreach ($rows as $row) {
971  $ret[$row['key']]['key'] = $row['key'];
972  $ret[$row['key']]['field_prompt'] = $row['field_prompt'];
973  $ret[$row['key']]['lang_enum'] = $row['lang_enum'];
974  $ret[$row['key']]['visibility'] = $row['visibility'];
975  if ($row['data_longtext']) {
976  $ret[$row['key']]['value'] = $row['data_longtext'];
977  } elseif ($row['data_blob']) {
978  $ret[$row['key']]['value'] = $row['data_blob'];
979  } else {
980  $ret[$row['key']]['value'] = null;
981  }
982  }
983  } catch (Exception $ex) {
984  global $_COMDEF_DEBUG;
985 
986  if ($_COMDEF_DEBUG) {
987  echo "Exception Thrown in c_comdef_meeting::GetDataTableTemplate()!<br />";
988  var_dump($ex);
989  }
990  throw ( $ex );
991  }
992 
993  return $ret;
994  }
995 
996  /*******************************************************************/
997  /** \brief Constructor
998 
999  This sets the local ID and the parent object.
1000  */
1001  public function __construct(
1002  $in_parent_obj,
1003  $inMeetingData
1004  ) {
1005  $this->SetParentObj($in_parent_obj);
1006  $this->_my_meeting_data = $inMeetingData;
1007  if (isset($this->_my_meeting_data) && isset($this->_my_meeting_data['formats']) && is_array($this->_my_meeting_data['formats']) && count($this->_my_meeting_data['formats'])) {
1008  uksort($this->_my_meeting_data['formats'], array('c_comdef_meeting','format_sorter_preference'));
1009  }
1010 
1011  // Set these inherited characteristics.
1012  $this->SetLocalLang($this->_my_meeting_data['lang_enum']);
1013  if (isset($this->_my_meeting_data['meeting_name']) && $this->_my_meeting_data['meeting_name'] && $this->_my_meeting_data['meeting_name']['value']) {
1014  $this->SetLocalName($this->_my_meeting_data['meeting_name']['value']);
1015  }
1016  }
1017 
1018  /*******************************************************************/
1019  /** \brief Returns a reference to the internal meeting data.
1020 
1021  \returns a reference to the internal array, containing the meeting data.
1022  */
1023  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1024  public function &GetMeetingData()
1025  {
1026  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1027  return $this->_my_meeting_data;
1028  }
1029 
1030  /*******************************************************************/
1031  /** \brief Returns a list of the available keys in this meeting.
1032 
1033  \returns an array of strings, with each one being a key.
1034  */
1035  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1036  public function GetMeetingDataKeys()
1037  {
1038  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1039  $ret = array();
1040 
1041  foreach ($this->_my_meeting_data as $key => &$value) {
1042  array_push($ret, $key);
1043  }
1044 
1045  return $ret;
1046  }
1047 
1048  /*******************************************************************/
1049  /** \brief Returns a reference to the internal meeting data.
1050 
1051  \returns a reference to the value of the requested element. Null if the element is not there.
1052  */
1053  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1054  public function GetMeetingDataValue( $in_key ///< A string. This is the key in the data array.
1055  )
1056  {
1057  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1058  $ret = null;
1059 
1060  if (isset($this->_my_meeting_data[$in_key])) {
1061  if (is_array($this->_my_meeting_data[$in_key]) && isset($this->_my_meeting_data[$in_key]['value'])) {
1062  if (isset($this->_my_meeting_data[$in_key]['visibility']) && ($this->_my_meeting_data[$in_key]['visibility'] == _VISIBILITY_NONE_) && !$this->UserCanObserve()) {
1063  $ret = null;
1064  } else {
1065  $ret = $this->_my_meeting_data[$in_key]['value'];
1066  }
1067  } else {
1068  $ret = $this->_my_meeting_data[$in_key];
1069  }
1070  }
1071 
1072  return $ret;
1073  }
1074 
1075  /*******************************************************************/
1076  /** \brief Returns whether or not a data item is hidden.
1077 
1078  \returns a boolean. True, if the data item is hidden from normal users.
1079  */
1080  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1081  public function IsItemHidden( $in_key ///< A string. This is the key in the data array.
1082  )
1083  {
1084  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1085  $ret = ($in_key == 'email_contact');
1086 
1087  if (!$ret && isset($this->_my_meeting_data[$in_key])) {
1088  if (is_array($this->_my_meeting_data[$in_key]) && isset($this->_my_meeting_data[$in_key]['value'])) {
1089  $ret = (isset($this->_my_meeting_data[$in_key]['visibility']) && ($this->_my_meeting_data[$in_key]['visibility'] == _VISIBILITY_NONE_));
1090  }
1091  }
1092 
1093  return $ret;
1094  }
1095 
1096  /*******************************************************************/
1097  /** \brief Returns the internal meeting data string prompt.
1098 
1099  \returns a string. Null if the element is not there.
1100  */
1101  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1102  public function GetMeetingDataPrompt( $in_key ///< A string. This is the key in the data array.
1103  )
1104  {
1105  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1106  $ret = null;
1107 
1108  if (isset($this->_my_meeting_data[$in_key])) {
1109  $ret = $this->_my_meeting_data[$in_key];
1110  if (is_array($ret) && isset($ret['prompt'])) {
1111  $ret = $ret['prompt'] ;
1112  } else {
1113  $ret = $in_key;
1114  }
1115  }
1116 
1117  return $ret;
1118  }
1119 
1120  /*******************************************************************/
1121  /** \brief Accessor - Returns true if the meeting data is valid.
1122 
1123  \returns a boolean, true if the meeting is valid (has data).
1124  */
1125  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1126  public function IsValidMeeting()
1127  {
1128  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1129  list ( $main_table_values, $data_table_values, $longdata_table_values ) = $this->ReduceToArrays();
1130 
1131  return ( isset($main_table_values['longitude']) && isset($main_table_values['latitude']) && is_array($data_table_values) && (count($data_table_values) > 0));
1132  }
1133 
1134  /*******************************************************************/
1135  /** \brief Accessor - Reflects the meeting's status as a duplicate of another.
1136 
1137  \returns a boolean, true if the meeting is a duplicate.
1138  */
1139  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1140  public function IsCopy()
1141  {
1142  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1143  return (isset($this->_my_meeting_data['copy']) );
1144  }
1145 
1146  /*******************************************************************/
1147  /** \brief Accessor - Reflects the meeting's status as a duplicate of another.
1148 
1149  \returns an integer, if the meeting is a duplicate, it is the ID of the meeting it copies.
1150  */
1151  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1152  public function IsCopyOf()
1153  {
1154  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1155  return (intval($this->_my_meeting_data['copy']) );
1156  }
1157 
1158  /*******************************************************************/
1159  /** \brief Accessor - Reflects the meeting's published status.
1160 
1161  \returns a boolean, true if the meeting is published.
1162  */
1163  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1164  public function IsPublished()
1165  {
1166  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1167  return $this->_my_meeting_data['published'];
1168  }
1169 
1170  /*******************************************************************/
1171  /** \brief Accessor - Sets the meeting's published status.
1172  */
1173  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1174  public function SetPublished( $in_published ///< A boolean. True if the meeting is published.
1175  )
1176  {
1177  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1178  if (!$this->IsCopy()) { // Can't publish copies.
1179  $this->_my_meeting_data['published'] = (intval($in_published) != 0) ? 1 : 0;
1180  }
1181  }
1182 
1183  /*******************************************************************/
1184  /** \brief Accessor - Returns the user ID as an integer.
1185 
1186  \returns an integer, containing the user ID.
1187  */
1188  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1189  public function GetID()
1190  {
1191  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1192  $ret = 0;
1193 
1194  if (isset($this->_my_meeting_data['id_bigint'])) {
1195  $ret = $this->_my_meeting_data['id_bigint'];
1196  }
1197 
1198  return $ret;
1199  }
1200 
1201  /*******************************************************************/
1202  /** \brief Set this meeting's ID.
1203  */
1204  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1205  public function SetMeetingID(
1206  $in_meeting_id_bigint ///< An integer, with the meeting's new ID.
1207  ) {
1208  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1209  $this->_my_meeting_data['id_bigint'] = intval($in_meeting_id_bigint);
1210  }
1211 
1212  /*******************************************************************/
1213  /** \brief Get this meeting's Email Contact Address
1214 
1215  \returns a string, which is the contact email.
1216  */
1217  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1218  public function GetEmailContact()
1219  {
1220  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1221  return $this->_my_meeting_data['email_contact'];
1222  }
1223 
1224  /*******************************************************************/
1225  /** \brief Set this meeting's Email Contact Address
1226  This "vets" the email address, to ensure it has the appropriate structure.
1227  It won't set the address if it is not the appropriate structure.
1228 
1229  \returns a boolean, which is true if the address was set correctly.
1230  */
1231  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1232  public function SetEmailContact( $in_email_contact ///< A string. The contact email address.
1233  )
1234  {
1235  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1236  $ret = false;
1237 
1238  if (preg_match('#^(?:[a-zA-Z0-9_\'^&amp;/+-])+(?:\.(?:[a-zA-Z0-9_\'^&amp;/+-])+)*@(?:(?:\[?(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\.){3}(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\]?)|(?:[a-zA-Z0-9-]+\.)+(?:[a-zA-Z]){2,}\.?)$#', $in_email_contact)) {
1239  $this->_my_meeting_data['email_contact'] = $in_email_contact;
1240  $ret = true;
1241  }
1242 
1243  return $ret;
1244  }
1245 
1246  /*******************************************************************/
1247  /** \brief Get this meeting's Service Body ID
1248 
1249  \returns an integer, which is the ID of the Service Body for this meeting.
1250  */
1251  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1252  public function GetServiceBodyID()
1253  {
1254  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1255  return $this->_my_meeting_data['service_body_bigint'];
1256  }
1257 
1258  /*******************************************************************/
1259  /** \brief Set this meeting's Service Body ID
1260 
1261  \returns an integer, which is the previous ID of the Service Body for this meeting.
1262  */
1263  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1264  public function SetServiceBodyID( $in_service_body_id ///< An integer, the ID of the new Service Body for this meeting.
1265  )
1266  {
1267  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1268  $ret = $this->_my_meeting_data['service_body_bigint'];
1269 
1270  $this->_my_meeting_data['service_body_bigint'] = intval($in_service_body_id);
1271 
1272  return $ret;
1273  }
1274 
1275  /*******************************************************************/
1276  /** \brief Get this meeting's Service Body, as a reference to an object.
1277 
1278  \returns a reference to an instance of c_comdef_service_body, which is the Service Body object for this meeting.
1279  */
1280  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1281  public function GetServiceBodyObj()
1282  {
1283  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1284  return c_comdef_server::GetServiceBodyByIDObj($this->GetServiceBodyID());
1285  }
1286 
1287  /*******************************************************************/
1288  /** \brief Get this meeting's Service Body name, as a string.
1289 
1290  \returns a reference to an instance of c_comdef_service_body, which is the Service Body object for this meeting.
1291  */
1292  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1293  public function GetServiceBodyName()
1294  {
1295  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1296  $ret = $this->_my_meeting_data['service_body_bigint'];
1297  $sb = $this->GetServiceBodyObj();
1298 
1299  if ($sb instanceof c_comdef_service_body) {
1300  $ret = $sb->GetLocalName();
1301  }
1302 
1303  return $ret;
1304  }
1305 
1306  /*******************************************************************/
1307  /** \brief Add a new data field to the object. If the field already
1308  exists, then the existing field is changed to match the new data.
1309 
1310  \returns a bool that is true, if the operation was successful.
1311  */
1312  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1313  public function AddDataField(
1314  $in_key_enum, ///< The data field key, which is a string enum for the field.
1315  $in_field_prompt_string, ///< A string, containing the field prompt.
1316  $in_value_mixed, ///< The value of the data field, which can be passed by reference.
1317  $in_lang_enum = null, ///< The language enum. Optional. If not specified, the meeting value will be used.
1318  $in_visibility = null,
1319  // The visibility of the data field. An integer.
1320  // - null or 0 if completely visible (default)
1321  // - 1 if visible only to logged-in admins and internal processes
1322  // - 2 if visible only when displayed on a regular Web page or a Mobile page
1323  // - 3 if visible only when displayed on a regular Web page
1324  // - 4 if visible only when displayed on a Mobile page
1325  // - 5 if visible only when printed
1326  $in_force = false ///< If this is set to true, then the value is written, regardless of whether or not it is already set. Default is false.
1327  ) {
1328  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1329  // We will not operate on the principal elements.
1330  $_meeting_data_value = array_key_exists($in_key_enum, $this->_my_meeting_data) ? $this->_my_meeting_data[$in_key_enum] : null;
1331  if (($in_force && !isset($_meeting_data_value)) || ($in_force && is_array($_meeting_data_value)) || !is_array($_meeting_data_value)) {
1332  if (!$in_lang_enum) {
1333  $in_lang_enum = $this->_my_meeting_data['lang_enum'];
1334  }
1335  $this->_my_meeting_data[$in_key_enum]['key'] = strval($in_key_enum);
1336  if ($in_field_prompt_string !== null) {
1337  $this->_my_meeting_data[$in_key_enum]['prompt'] = $in_field_prompt_string;
1338  }
1339 
1340  // Hack to make sure there's no such thing as "pure" midnight.
1341  if ($in_key_enum == 'start_time') {
1342  if (($in_value_mixed == '00:00:00') || ($in_value_mixed == '00:00') || ($in_value_mixed == '24:00:00') || ($in_value_mixed == '24:00')) {
1343  $in_value_mixed == '23:59:00';
1344  }
1345  }
1346 
1347  $this->_my_meeting_data[$in_key_enum]['value'] = null; // Just in case of memory leaks.
1348  $this->_my_meeting_data[$in_key_enum]['value'] = $in_value_mixed;
1349  $this->_my_meeting_data[$in_key_enum]['lang_enum'] = $in_lang_enum;
1350  $this->_my_meeting_data[$in_key_enum]['visibility'] = ( $in_visibility === null ) ? ((isset($this->_my_meeting_data[$in_key_enum]) && isset($this->_my_meeting_data[$in_key_enum]['visibility'])) ? intval($this->_my_meeting_data[$in_key_enum]['visibility']) : 0) : intval($in_visibility);
1351  return true;
1352  }
1353 
1354  return false;
1355  }
1356 
1357  /*******************************************************************/
1358  /** \brief Deletes a data field. Will not delete a principal field.
1359 
1360  \returns a bool that is true, if the operation was successful.
1361  */
1362  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1363  public function DeleteDataField(
1364  $in_key_enum ///< The data field key, which is a string enum for the field.
1365  ) {
1366  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1367  // We will not operate on the principal elements.
1368  if (is_array($this->_my_meeting_data[$in_key_enum])) {
1369  // We do this, just so there's no possibility of memory leaks and hanging references.
1370  if (isset($this->_my_meeting_data[$in_key_enum]['prompt'])) {
1371  $this->_my_meeting_data[$in_key_enum]['prompt'] = null;
1372  unset($this->_my_meeting_data[$in_key_enum]['prompt']);
1373  }
1374  if (isset($this->_my_meeting_data[$in_key_enum]['value'])) {
1375  $this->_my_meeting_data[$in_key_enum]['value'] = null;
1376  unset($this->_my_meeting_data[$in_key_enum]['value']);
1377  }
1378  $this->_my_meeting_data[$in_key_enum] = null;
1379  unset($this->_my_meeting_data[$in_key_enum]);
1380 
1381  return true;
1382  }
1383 
1384  return false;
1385  }
1386 
1387  /*******************************************************************/
1388  /** \brief Get this meeting's Language Enum.
1389 
1390  \returns a string, containing the meeting's language.
1391  */
1392  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1393  public function GetMeetingLang()
1394  {
1395  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1396  return $this->_my_meeting_data['lang_enum'];
1397  }
1398 
1399  /*******************************************************************/
1400  /** \brief Get this meeting's Address in the string format specified for this server.
1401 
1402  \returns a string, containing the meeting's address in easily-readable form.
1403  */
1404  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1405  public function GetMeetingAddressString( $in_list = false ///< If this is true, then the version returned will be for the list display. Default is false (The More Details display).
1406  )
1407  {
1408  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1409  $ret = null;
1410 
1411  $builder = self::GetAddressDataItemBuilder($in_list); // Get the parsed address format builder.
1412 
1413  if (is_array($builder) && count($builder)) {
1414  foreach ($builder as $element_ar) {
1415  if (trim($this->GetMeetingDataValue($element_ar['key']))) {
1416  $ret .= $element_ar['prefix'];
1417  $ret .= trim($this->GetMeetingDataValue($element_ar['key']));
1418  $ret .= $element_ar['suffix'];
1419  }
1420  }
1421  }
1422 
1423  return $ret;
1424  }
1425 
1426  /*******************************************************************/
1427  /** \brief Add a format to the meeting (by code).
1428 
1429  Given an integer, representing the format code, it will add it to the
1430  meeting, and will reference the object for the meeting's language
1431  for that format.
1432 
1433  \returns true if the format was not already there, and false if the format was there.
1434  */
1435  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1436  public function AddFormat(
1437  $in_format ///< An integer, containing the format to be added.
1438  ) {
1439  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1440  $myData = $this->GetMeetingData();
1441  $my_formats = c_comdef_server::GetServer()->GetFormatsObj();
1442 
1443  // If we already have the format, we don't add it, but there's no error.
1444  if (!isset($myData['formats'][$in_format])) {
1445  $myData['formats'][$in_format] = $my_formats->GetFormatBySharedIDCodeAndLanguage($in_format, $this->GetMeetingLang());
1446  uksort($myData['formats'], array('c_comdef_meeting','format_sorter_preference'));
1447  return true;
1448  }
1449 
1450  return false;
1451  }
1452 
1453  /*******************************************************************/
1454  /** \brief Remove a format from the meeting (by code).
1455 
1456  Given an integer, representing the format code, it will remove it from the
1457  meeting.
1458 
1459  \returns true if successful, and false if the format was not there.
1460  */
1461  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1462  public function RemoveFormat(
1463  $in_format ///< An integer, containing the format to be removed.
1464  ) {
1465  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1466  $myData = $this->GetMeetingData();
1467 
1468  if (isset($myData['formats'][$in_format])) {
1469  $myData['formats'][$in_format] = null; // Make sure we remove the reference to the object.
1470  unset($myData['formats'][$in_format]);
1471  return true;
1472  }
1473 
1474  return false;
1475  }
1476 
1477  /*******************************************************************/
1478  /** \brief Determines which format goes first (used in sorting).
1479 
1480  Format 4 (Closed) and format 17 (Open) are always in front. Otherwise, it's a simple numeric sort.
1481 
1482  \returns -1 if $a is 4, 17, or less than $b, 0 if they are equal, and 1 if $b is 4, 17 or less than $a
1483  */
1484  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1485  public static function format_sorter_preference(
1486  $a, ///< The first value to check
1487  $b ///< The second value to check
1488  ) {
1489  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1490  $a = intval($a);
1491  $b = intval($b);
1492 
1493  if (($a == 4) || ($a == 17)) {
1494  return -1;
1495  } elseif (($b == 4) || ($b == 17)) {
1496  return 1;
1497  } elseif ($a == $b) {
1498  return 0;
1499  } else {
1500  return ( $a < $b ) ? -1 : 1;
1501  }
1502  }
1503 
1504  /*******************************************************************/
1505  /** \brief Determines which format goes first (used in sorting). Very
1506  simple version, with no preferences.
1507 
1508  \returns -1 if $a is less than $b, 0 if they are equal, and 1 if $b is less than $a
1509  */
1510  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1511  public static function format_sorter_simple(
1512  $a, ///< The first value to check
1513  $b ///< The second value to check
1514  ) {
1515  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1516  $a = intval($a);
1517  $b = intval($b);
1518 
1519  if ($a == $b) {
1520  return 0;
1521  } else {
1522  return ( $a < $b ) ? -1 : 1;
1523  }
1524  }
1525 
1526  /*******************************************************************/
1527  /** \brief Returns a storable serialization of the object, as a string.
1528 
1529  This is only used for the changes, as the serialized string may not
1530  be easily searched.
1531 
1532  \returns an array, containing the 3 component strings, each one a
1533  table array, in serialized form.
1534  */
1535  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1536  public function SerializeObject()
1537  {
1538  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1539  list ( $main_table_values, $data_table_values, $longdata_table_values ) = $this->ReduceToArrays();
1540 
1541  $ret = serialize(array ( 'main_table_values' => serialize($main_table_values),
1542  'data_table_values' => serialize($data_table_values),
1543  'longdata_table_values' => serialize($longdata_table_values) ));
1544 
1545  return $ret;
1546  }
1547 
1548  /*******************************************************************/
1549  /** \brief This takes a serialized object, and instantiates a
1550  new object from it.
1551 
1552  \returns a new instance of c_comdef_meeting, set up according to
1553  the serialized data passed in.
1554  */
1555  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1556  public static function UnserializeObject(
1557  $in_parent, ///< The parent object.
1558  $serialized_array ///< String containing 3 sequential arrays, each with the serialized data.
1559  ) {
1560  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1561  $serialized_array = unserialize($serialized_array);
1562  $main_table_values = unserialize($serialized_array['main_table_values']);
1563  $data_table_values = unserialize($serialized_array['data_table_values']);
1564  $longdata_table_values = unserialize($serialized_array['longdata_table_values']);
1565  $my_data = self::process_meeting_row($main_table_values, $data_table_values, $longdata_table_values);
1566 
1567  $new_meeting = new c_comdef_meeting($in_parent, $my_data);
1568 
1569  return $new_meeting;
1570  }
1571 
1572  /*******************************************************************/
1573  /** \brief This processes the data retrieved from a single main table meeting.
1574  It will look up the corollary data in the data and longdata tables,
1575  and will consolidate it into an atomic array. It will also return
1576  c_comdef_format objects for the formats in the server language.
1577 
1578  \returns an array of data that can be used as the data for the meeting object.
1579  */
1580  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1581  public static function process_meeting_row(
1582  $row, ///< One row of meeting data, fresh from the database.
1583  /// These are used to unserialize the object, which bypasses the database.
1584  $data_rows = null, ///< Optional. If non-null, this should be an array of data table values
1585  $longdata_rows = null ///< Optional. If non-null, this should be an array of longdata table values
1586  ) {
1587  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1588  try {
1589  // The weekday is kept on the server as zero-based, but we keep it 1-based in our implementation.
1590  $row['weekday_tinyint'] = $row['weekday_tinyint'] + 1;
1591  $meeting_id = $row['id_bigint'];
1592  $meeting_row = $row;
1593  // However, we do one thing differently: We split the formats array, so it is in multiple elements. That'll make it easier to handle later.
1594  // We also actually assign a reference to the localized format object itself to the array.
1595  $meeting_row['formats'] = explode(",", $meeting_row['formats']);
1596 
1597  // What we do here is assign the format object to the version for the language of the meeting (not necessarily the server).
1598  // The formats array will use the format codes as keys, so we can use these to access other localizations.
1599  $new_formats = array();
1600 
1601  $my_formats = c_comdef_server::GetServer()->GetFormatsObj();
1602  foreach ($meeting_row['formats'] as $format_id) {
1603  $new_formats[$format_id] = $my_formats->GetFormatBySharedIDCodeAndLanguage($format_id, $row['lang_enum']);
1604  }
1605 
1606  $meeting_row['formats'] = $new_formats;
1607 
1608  // If the row was not already supplied, we fetch it ourselves.
1609  if (null == $data_rows) {
1610  // We do two lookups, because a fancy-ass JOIN takes FOR-EVER. The performance is AWFUL.
1611  // 99% of the time, the longdata table won't have anything in it, so we shouldn't slow
1612  // down the regular data table to include a table that barely ever has anything.
1613  // This has the added advantage of allowing implementations to override the main data, and
1614  // to allow data in the longdata table to override the regular table.
1615 
1616  $sql = "SELECT * FROM `".c_comdef_server::GetMeetingTableName_Obj()."_data` WHERE ".c_comdef_server::GetMeetingTableName_Obj()."_data.meetingid_bigint=?";
1617 
1618  $data_rows = c_comdef_dbsingleton::preparedQuery($sql, array ( $meeting_id ));
1619  }
1620 
1621  if (is_array($data_rows) && count($data_rows)) {
1622  foreach ($data_rows as $data_row) {
1623  $key = $data_row['key'];
1624  if (trim($key)) {
1625  if (isset($data_row['data_string']) && (null != $data_row['data_string'])) {
1626  $meeting_row[$key]['value'] = stripslashes(strval($data_row['data_string']));
1627  } elseif (isset($data_row['data_bigint']) && ( null != $data_row['data_bigint'] )) {
1628  $meeting_row[$key]['value'] = intval($data_row['data_bigint']);
1629  } elseif (isset($data_row['data_double']) && ( null != $data_row['data_double'] )) {
1630  $meeting_row[$key]['value'] = floatval($data_row['data_double']);
1631  }
1632 
1633  // Only set these if we have data.
1634  if (isset($meeting_row[$key]['value'])) {
1635  $meeting_row[$key]['longdata'] = false;
1636  $meeting_row[$key]['prompt'] = $data_row['field_prompt'];
1637  $meeting_row[$key]['lang'] = $data_row['lang_enum'];
1638  $meeting_row[$key]['visibility'] = isset($data_row['visibility']) ? $data_row['visibility'] : 0;
1639  }
1640  }
1641  }
1642  }
1643 
1644  // If the row was not already supplied, we fetch it ourselves.
1645  if (null == $longdata_rows) {
1646  $sql = "SELECT * FROM `".c_comdef_server::GetMeetingTableName_Obj()."_longdata` WHERE ".c_comdef_server::GetMeetingTableName_Obj()."_longdata.meetingid_bigint=?";
1647 
1648  $longdata_rows = c_comdef_dbsingleton::preparedQuery($sql, array ( $meeting_id ));
1649  }
1650 
1651  if (is_array($longdata_rows) && count($longdata_rows)) {
1652  foreach ($longdata_rows as $longdata_row) {
1653  $key = $longdata_row['key'];
1654  if (trim($key) && ((null != $longdata_row['data_blob']) || (null != $longdata_row['data_longtext']))) {
1655  $meeting_row[$key]['longdata'] = true;
1656  $meeting_row[$key]['value'] = (null != $longdata_row['data_blob']) ? $longdata_row['data_blob'] : stripslashes($longdata_row['data_longtext']);
1657  $meeting_row[$key]['prompt'] = $longdata_row['field_prompt'];
1658  $meeting_row[$key]['lang'] = $longdata_row['lang_enum'];
1659  $meeting_row[$key]['visibility'] = $longdata_row['visibility'];
1660  }
1661  }
1662  }
1663 
1664  // At this point, we have all the data for this one meeting, culled from its three tables and aggregated into an array.
1665  return $meeting_row;
1666  } catch (Exception $ex) {
1667  global $_COMDEF_DEBUG;
1668 
1669  if ($_COMDEF_DEBUG) {
1670  echo "Exception Thrown in c_comdef_meeting::process_meeting_row()!<br />";
1671  var_dump($ex);
1672  }
1673  throw ( $ex );
1674  }
1675  }
1676 
1677  /*******************************************************************/
1678  /** \brief Get the contact email for this meeting.
1679  If $in_recursive is false, then it simply looks at this meeting's Service Body.
1680 
1681  \returns a string, which is the contact email for this meeting
1682  */
1683  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1684  public function GetContactEmail( $in_recursive = false ///< If this is true, then the function will return a recursive result. Default is false.
1685  )
1686  {
1687  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1688  $ret = trim($this->GetEmailContact());
1689 
1690  if (!$ret) {
1691  $service_body = $this->GetServiceBodyObj();
1692 
1693  if ($service_body instanceof c_comdef_service_body) {
1694  $ret = $service_body->GetContactEmail($in_recursive);
1695  }
1696  }
1697 
1698  return $ret;
1699  }
1700 
1701  /*******************************************************************/
1702  /** \brief Test to see if a user is allowed to edit an instance (change the data).
1703 
1704  \returns true, if the user is allowed to edit, false, otherwise.
1705  */
1706  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1707  public function UserCanEdit(
1708  $in_user_object = null ///< A reference to a c_comdef_user object, for the user to be validated. If null, or not supplied, the server current user is tested.
1709  ) {
1710  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1711  $ret = false;
1712 
1713  // We load the server user if one wasn't supplied.
1714  if (null == $in_user_object) {
1715  $in_user_object = c_comdef_server::GetCurrentUserObj();
1716  }
1717 
1718  // If it isn't a user object, we fail right there.
1719  if ($in_user_object instanceof c_comdef_user) {
1720  $in_user_object->RestoreFromDB(); // The reason you do this, is to ensure that the user wasn't modified "live." It's a security precaution.
1721 
1722  if (($in_user_object->GetUserLevel() != _USER_LEVEL_SERVER_ADMIN) && ($in_user_object->GetUserLevel() != _USER_LEVEL_DISABLED) && (($in_user_object->GetUserLevel() == _USER_LEVEL_EDITOR) || ($in_user_object->GetUserLevel() == _USER_LEVEL_SERVICE_BODY_ADMIN))) {
1723  // If there is an existing object, then we can't make changes unless it's allowed in the existing object.
1724  $current_obj = c_comdef_server::GetServer()->GetOneMeeting($this->GetID());
1725 
1726  // If there is no current object, then we are a new meeting.
1727  if (null == $current_obj) {
1728  $current_obj = $this;
1729  } else {
1730  // We clone, in case changes have been made, and we don't want to screw them up.
1731  $current_obj = clone $current_obj;
1732  // Otherwise, block dope fiends.
1733  $current_obj->RestoreFromDB();
1734  }
1735 
1736  if ($current_obj instanceof c_comdef_meeting) {
1737  $my_service_body = c_comdef_server::GetServiceBodyByIDObj($current_obj->GetServiceBodyID());
1738 
1739  if ($in_user_object->GetUserLevel() == _USER_LEVEL_EDITOR) {
1740  // Regular meeting list editors can't change published objects. They also can only edit meetings in the exact Service Body to which they are assigned.
1741  $ret = ($my_service_body instanceof c_comdef_service_body) && $my_service_body->IsUserInServiceBody($in_user_object) && !$this->IsPublished();
1742  } elseif (($my_service_body instanceof c_comdef_service_body) && $my_service_body->IsUserInServiceBodyHierarchy($in_user_object)) {
1743  $ret = true;
1744  }
1745  }
1746  } elseif (c_comdef_server::IsUserServerAdmin()) {
1747  $ret = true;
1748  }
1749  }
1750 
1751  return $ret;
1752  }
1753 
1754  /*******************************************************************/
1755  /** \brief Test to see if a user is allowed to observe an instance (view the data).
1756 
1757  \returns true, if the user is allowed to observe, false, otherwise.
1758  */
1759  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1760  public function UserCanObserve(
1761  $in_user_object = null ///< A reference to a c_comdef_user object, for the user to be validated. If null, or not supplied, the server current user is tested.
1762  ) {
1763  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1764  $ret = false;
1765 
1766  // We load the server user if one wasn't supplied.
1767  if (null == $in_user_object) {
1768  $in_user_object = c_comdef_server::GetCurrentUserObj();
1769  }
1770 
1771  // If it isn't a user object, we fail right there.
1772  if ($in_user_object instanceof c_comdef_user) {
1773  $in_user_object->RestoreFromDB(); // The reason you do this, is to ensure that the user wasn't modified "live." It's a security precaution.
1774 
1775  if (($in_user_object->GetUserLevel() == _USER_LEVEL_OBSERVER) || ($in_user_object->GetUserLevel() == _USER_LEVEL_SERVICE_BODY_ADMIN) || ($in_user_object->GetUserLevel() == _USER_LEVEL_SERVER_ADMIN)) {
1776  // If there is an existing object, then we can't make changes unless it's allowed in the existing object.
1777  $current_obj = c_comdef_server::GetServer()->GetOneMeeting($this->GetID());
1778 
1779  // If there is no current object, then we are a new meeting.
1780  if (null == $current_obj) {
1781  $current_obj = $this;
1782  } else {
1783  // We clone, in case changes have been made, and we don't want to screw them up.
1784  $current_obj = clone $current_obj;
1785  // Otherwise, block dope fiends.
1786  $current_obj->RestoreFromDB();
1787  }
1788 
1789  if ($current_obj instanceof c_comdef_meeting) {
1790  $my_service_body = c_comdef_server::GetServiceBodyByIDObj($current_obj->GetServiceBodyID());
1791 
1792  if (($my_service_body instanceof c_comdef_service_body) && $my_service_body->UserCanObserve($in_user_object)) {
1793  $ret = true;
1794  }
1795  }
1796  }
1797  }
1798 
1799  return $ret;
1800  }
1801 }
static GetLocalStrings($in_lang_enum=null)
This gets the appropriate language files, and puts all the the strings into an associative array...
GetMeetingAddressString($in_list=false)
Get this meeting&#39;s Address in the string format specified for this server.
RemoveFormat($in_format)
Remove a format from the meeting (by code).
DeleteFromDB()
Deletes this instance from the database.
SetEmailContact($in_email_contact)
Set this meeting&#39;s Email Contact Address This "vets" the email address, to ensure it has the appropri...
static process_meeting_row($row, $data_rows=null, $longdata_rows=null)
This processes the data retrieved from a single main table meeting. It will look up the corollary dat...
A Class for Service Body Objects.
static AddNewChange($in_user_id_bigint, $in_change_type, $in_service_body_id_bigint, $in_before_string, $in_after_string, $in_object_class_string, $in_before_obj_id_bigint, $in_after_obj_id_bigint, $in_before_obj_lang_enum=null, $in_after_obj_lang_enum=null, $in_name_string=null, $in_description_string=null, $in_lang_enum=null)
Creates a new change record in the Database.
A class to hold a single meeting object.
GetMeetingLang()
Get this meeting&#39;s Language Enum.
UpdateToDB($is_rollback=false)
Updates the DB to the current values of this instance. (replacing current values of the DB)...
$local_strings
Definition: index.php:6
static preparedExec($sql, $params=array())
Wrapper for preparing and executing a PDOStatement that does not return a resultset e...
const _VISIBILITY_MOB_
static GetAllMeetingKeys()
Returns an array of strings, containing the keys (table columns) used for all meetings (specified in ...
IsCopy()
Accessor - Reflects the meeting&#39;s status as a duplicate of another.
static lastInsertId()
Wrapper for PDO::lastInsertId()
This class handles BMLT users. One instance is created for each user on the server.
static GetLongDataTableTemplate($in_lang_enum=null)
Returns an array that provides a template for the long data table values (the optional/additional val...
static GetMeetingTableName_obj()
Simply returns the name of the meetings table.
$ret
Definition: contact.php:226
const _VISIBILITY_PRINT_
global $comdef_global_language
The local server language enum (Will default to English)
SerializeObject()
Returns a storable serialization of the object, as a string.
const _USER_LEVEL_SERVICE_BODY_ADMIN
const _USER_LEVEL_OBSERVER
static preparedQuery($sql, $params=array(), $fetchKeyPair=false)
Wrapper for preparing and executing a PDOStatement that returns a resultset e.g. SELECT SQL statement...
$meeting_id
Definition: contact.php:227
IsValidMeeting()
Accessor - Returns true if the meeting data is valid.
const _USER_LEVEL_DISABLED
SetPublished($in_published)
Accessor - Sets the meeting&#39;s published status.
SetMeetingID($in_meeting_id_bigint)
Set this meeting&#39;s ID.
IsCopyOf()
Accessor - Reflects the meeting&#39;s status as a duplicate of another.
DeleteDataField($in_key_enum)
Deletes a data field. Will not delete a principal field.
const _USER_LEVEL_SERVER_ADMIN
UserCanObserve($in_user_object=null)
Test to see if a user is allowed to observe an instance (view the data).
ReduceToArrays()
Returns the object, in 3 storable arrays.
static GetAllValuesForKey($inKey)
Returns an array of values for the given key.
static GetFullTemplate()
Returns an array that provides a template for all tables.
GetID()
Accessor - Returns the user ID as an integer.
__construct($in_parent_obj, $inMeetingData)
Constructor.
const _VISIBILITY_WEB_MOB_
GetEmailContact()
Get this meeting&#39;s Email Contact Address.
IsItemHidden($in_key)
Returns whether or not a data item is hidden.
AddDataField($in_key_enum, $in_field_prompt_string, $in_value_mixed, $in_lang_enum=null, $in_visibility=null, $in_force=false)
Add a new data field to the object. If the field already exists, then the existing field is changed t...
A very simple class that allows whatever format NAWS will use as an ID to be assigned to the object...
RestoreFromDB()
Updates this instance to the current values in the DB (replacing current values of the instance)...
static UnserializeObject($in_parent, $serialized_array)
This takes a serialized object, and instantiates a new object from it.
const _USER_LEVEL_EDITOR
GetServiceBodyObj()
Get this meeting&#39;s Service Body, as a reference to an object.
SetServiceBodyID($in_service_body_id)
Set this meeting&#39;s Service Body ID.
UserCanEdit($in_user_object=null)
Test to see if a user is allowed to edit an instance (change the data).
static GetMainDataTemplate()
Returns an array that provides a template for the main table values (the standard values)...
static GetServiceBodyByIDObj($in_service_body_id_bigint)
Get the object for a single service body, given an ID.
Interface for entities that can be rendered into serialized form.
static GetAddressDataItemBuilder($in_list=false)
Return an array of data item keys, as well as their prefixes and suffixes, that are used to build an ...
GetMeetingDataKeys()
Returns a list of the available keys in this meeting.
GetContactEmail($in_recursive=false)
Get the contact email for this meeting. If $in_recursive is false, then it simply looks at this meeti...
static format_sorter_preference($a, $b)
Determines which format goes first (used in sorting).
Interface for entities that store themselves in the database.
DeleteFromDB_NoRecord()
Deletes this instance from the database.
const _VISIBILITY_ALL_
GetMeetingDataPrompt($in_key)
Returns the internal meeting data string prompt.
const _VISIBILITY_NONE_
static GetDataTableTemplate()
Returns an array that provides a template for the data table values (the optional/additional values)...
static format_sorter_simple($a, $b)
Determines which format goes first (used in sorting). Very simple version, with no preferences...
defined('BMLT_EXEC') or define('BMLT_EXEC'
Definition: index.php:3
GetMeetingDataValue($in_key)
Returns a reference to the internal meeting data.
GetServiceBodyName()
Get this meeting&#39;s Service Body name, as a string.
AddFormat($in_format)
Add a format to the meeting (by code).
global $_COMDEF_DEBUG
This flag, when set to true, will cause extra debug information to be output.
const _VISIBILITY_WEB_
static GetCurrentUserObj($in_is_ajax=false)
Get the current logged-in user, as a c_comdef_user instance.
static IsUserServerAdmin($in_user_obj=null, $in_is_ajax=false)
Find out if the user is a server admin.
& GetMeetingData()
Returns a reference to the internal meeting data.
GetServiceBodyID()
Get this meeting&#39;s Service Body ID.
static GetAddressDataItemKeys($in_list=false)
Return an array of data item keys that are used to build an address.
Interface for entities that authenticate users.
IsPublished()
Accessor - Reflects the meeting&#39;s published status.