BMLT Root Server
c_comdef_meeting_search_manager.class.php
Go to the documentation of this file.
1 <?php
2 /***********************************************************************/
3 /** \file c_comdef_meeting_search_manager.class.php
4 
5  \brief The class file for the c_comdef_meeting_search_manager class.
6 
7  This class is designed to manage the specification and result delivery
8  of searches.
9 
10  This is a generic meeting search manager that is designed to be subclassed for
11  specific implementations (such as for HTTP user agents or RSS feeds).
12 
13  Some search criteria are fed directly to the SQL, while others are run on the
14  results of the SQL search. It is transparent to the caller.
15 
16  This class is meant to be a complete interface to the BMLT server subsystem.
17  It's a Controller class.
18 
19  As a user (searcher, not administrator) of the system, this is the only class
20  you'll need to really know about. You can use it to access other, more specific
21  classes, but all you need to do is instantiate one of these, and it will take care
22  of setting up the server and all the database interactions.
23 
24  The way this class works is that a set of data members are in the object that are
25  set to specify search criteria. A number of functions are provided to help the
26  user to specify criteria.
27 
28  Once the criteria are set, a search is triggered, and this class will present the
29  results as references to objects.
30 
31  The default is a "wide open" search for all meetings.
32 
33  \version 0.93
34 
35  This file is part of the Basic Meeting List Toolbox (BMLT).
36 
37  Find out more at: https://bmlt.app
38 
39  BMLT is free software: you can redistribute it and/or modify
40  it under the terms of the MIT License.
41 
42  BMLT is distributed in the hope that it will be useful,
43  but WITHOUT ANY WARRANTY; without even the implied warranty of
44  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45  MIT License for more details.
46 
47  You should have received a copy of the MIT License along with this code.
48  If not, see <https://opensource.org/licenses/MIT>.
49 */
50 
51 defined('BMLT_EXEC') or die('Cannot Execute Directly'); // Makes sure that this file is in the correct context.
52 
53 require_once(dirname(__FILE__)."/../../server/c_comdef_server.class.php");
54 
55 /// A class to control the basic common functionality of all meeting searches.
56 // phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
57 // phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
59 // phpcs:emable PSR1.Classes.ClassDeclaration.MissingNamespace
60 // phpcs:enable Squiz.Classes.ValidClassName.NotCamelCaps
61 {
62  /// These fields are used to specify the search criteria.
63  protected $_formats = null; /**< An array of integers. These are formats. The filtering will be an "AND" filtering, so qualified meetings
64  must have all of the given formats. The key is the format's shared ID, and the value will be one of these:
65  - -1 NOT (exclude all meetings that contain this format from the search).
66  - 0 No preference (This format will not be a consideration in the search).
67  - 1 Return meetings that contain this format.
68 
69  Default is 0 for all. If no formats are specified (either 1 or -1), then formats will not be a consideration
70  in the meeting search. If any format is specified as 1, then ONLY meetings with the given format will be
71  considered in the search, and you must explicitly set any other formats you wish found.
72  */
73  protected $_formats_comparison_operator = "AND"; /**< A string, controls the comparison operator used for included formats. Valid values are AND and OR.
74  * */
75 
76  protected $_service_bodies = null; /**< An array of integers. The key is the ID for a Service Body, and the value is one of these:
77  - -1 NOT (exclude all meetings that contain this Service Body from the search).
78  - 0 No preference (This Service Body will not be a consideration in the search).
79  - 1 Return meetings that contain this Service Body.
80 
81  Default is 0 for all. If no Service Bodies are specified (either 1 or -1), then Service Bodies will not be a
82  consideration in the meeting search. If any Service Body is specified as 1, then ONLY meetings with the given
83  Service Body will be considered in the search, and you must explicitly set any other Service Bodies you wish found.
84  */
85  protected $_languages = null; /**< An array of integers. The key is the language enum, and the value is as follows:
86  - -1 NOT (exclude all meetings that have this language from the search).
87  - 0 No preference (This language will not be a consideration in the search).
88  - 1 Return meetings that have this language.
89 
90  Default is 0 for all. If no languages are specified (either 1 or -1), then language will not be a
91  consideration in the meeting search. If any language is specified as 1, then ONLY meetings with the given
92  language will be considered in the search, and you must explicitly set any other language you wish found.
93  */
94  protected $_weekdays = null; /**< An array of integers. The key is the weekday (1 = Sunday, 7 = Saturday), and the value is as follows:
95  - -1 NOT (exclude all meetings that occur on this weekday from the search).
96  - 0 No preference (This weekday will not be a consideration in the search).
97  - 1 Return meetings that occur on this weekday.
98 
99  Default is 0 for all. If no weekdays are specified (either 1 or -1), then the weekday will not be a
100  consideration in the meeting search. If any weekday is specified as 1, then ONLY meetings that occur on
101  the given weekday will be considered in the search, and you must explicitly set any other weekday you wish found.
102  */
103 
104  /// These specify the start time and duration of the meeting. The start time can be specified as a "window."
105  protected $_start_after = null; ///< An epoch time (seconds, as returned by time()), that denotes the earliest starting time allowed.
106  protected $_start_before = null; ///< An epoch time (seconds, as returned by time()), that denotes the latest starting time allowed.
107  protected $_end_before = null; ///< An epoch time (seconds, as returned by time()), that denotes the latest ending time allowed.
108  protected $_min_duration = null; ///< The number of seconds a meeting should last as a minimum.
109  protected $_max_duration = null; ///< The number of seconds a meeting can last, at most.
110 
111  /// These specify the search radius (We store it in kilometers).
112  protected $_search_radius = null; ///< If this is not null, it needs to be a positive, floating-point number, indicating the radius, in Kilometers.
113  protected $_search_radius_count = null; ///< If this is not null, it needs to be a positive integer, indicating the number of meetings to find automatically.
114  protected $_search_center_long = null; ///< If $_search_radius is not null, this needs to be a floating-point number that indicates the longitude, in degrees, of the search center.
115  protected $_search_center_lat = null; ///< If $_search_radius is not null, this needs to be a floating-point number that indicates the latitude, in degrees, of the search center.
116 
117  /// We allow a broad string search that goes through all the text items. In English and Spanish, it uses metaphone, which is a "sounds like" phonetic search.
118  protected $_search_string = null; ///< A string to be located from within the results. This search is done after all of the previous ones. This is applied at the end.
119  protected $_search_string_all_words = false; ///< A Boolean. If this is true, then all of the words in a phrase must be present.
120  protected $_search_string_literal = false; ///< A Boolean. If this is true, then the spelling must be literal.
121 
122  /// This allows you to filter out a particular value for a key
123  protected $_meeting_key = null; /**< A string. This is the xact name of the key to match.
124  NOTE: As of Version 1.5, this can be an array of strings (it can still be a single string). The array should contain the names of string fields.
125  */
126  protected $_meeting_key_value = null; /**< A string. The value to match.
127  NOTE: As of Version 1.5, this is matched with a metaphone match, as well as the RegEx match.
128  */
129  protected $_meeting_key_match_case = false; /**< If true, the case must match. Default is false.
130  NOTE: As of Version 1.5, setting this to TRUE also stops the metaphone search.
131  */
132  protected $_meeting_key_contains = false; ///< If this is false, then the string must be complete. Default is false (literal).
133 
134  /// This contains a list of IDs of individual meetings. If it is set, then all other search parameters are ignored.
135  protected $_meeting_id_array = null; ///< An array of positive integers. The Ids of meetings to find. If this is set, all other search criteria are ignored.
136 
137  /// This indicates whether the search should include, exclude, or focus on "published" meetings.
138  protected $_published_search = 0; /**< This only counts if the searcher is a logged-in admin. The value can be:
139  - -1 Search for ONLY unpublished meetings
140  - 0 Search for published and unpublished meetings.
141  - 1 Search for ONLY published meetings.
142  */
143  protected $_sort_search_by_distance = false; ///< If this is true, then the search results may be sorted by distance from the geo center.
144 
145  /// This contains the search results.
146  protected $_search_results = null; ///< A c_comdef_meetings object. If this is null, a new search is performed. This contains the entire search results.
147 
148  private $sort_array = null; ///< This contains an array of strings that represent the sort keys.
149  private $sort_desc = false; ///< This is set to true if the sort is a reverse sort.
150  private $sort_depth = 3; ///< An integer. This is how far back a staged sort goes. Default is 3. 0 is forever.
151 
152  /// This refers to portions of a larger search (pages).
153  private $_results_per_page = 0; ///< The number of meetings to list per page.
154  private $_pageno = 0; ///< An integer. The page number represented by this object. If $_results_per_page is 0, this is ignored.
155 
156  /// If this isn't the root, then this will be a reference to the root.
157  private $_my_root = null; ///< A reference to an instance of c_comdef_meeting_search_manager -The root object.
158 
159  private $_my_server = null; ///< A reference to a c_comdef_server object. This is the server to be used for the search.
160 
161  /*******************************************************************/
162  /** \brief Constructor.
163  */
164  public function __construct(
165  $in_results_per_page = 0, ///< An integer that defines how many results per page you want to see. 0 (default) is all in one page.
166  c_comdef_meeting_search_manager &$in_parent = null, ///< A reference to an existing c_comdef_meeting_search_manager object.
167  c_comdef_meetings &$in_search_results = null, ///< A reference to some pre-parsed search results.
168  $in_pageno = 0 ///< An integer. The page of the main search this is from.
169  ) {
170  // If this is a page of results, we set up the object to reference the root.
171  if ($in_parent instanceof c_comdef_meeting_search_manager) {
172  $this->_my_root = $in_parent;
173  // These all reference the root object's values.
174  $this->_formats = $in_parent->_formats;
175  $this->_formats_comparison_operator = $in_parent->_formats_comparison_operator;
176  $this->_service_bodies = $in_parent->_service_bodies;
177  $this->_languages = $in_parent->_languages;
178  $this->_weekdays = $in_parent->_weekdays;
179  $this->_start_after = $in_parent->_start_after;
180  $this->_start_before = $in_parent->_start_before;
181  $this->_end_before = $in_parent->_end_before;
182  $this->_min_duration = $in_parent->_min_duration;
183  $this->_max_duration = $in_parent->_max_duration;
184  $this->_search_radius = $in_parent->_search_radius;
185  $this->_search_center_long = $in_parent->_search_center_long;
186  $this->_search_center_lat = $in_parent->_search_center_lat;
187  $this->_search_string = $in_parent->_search_string;
188  $this->_meeting_id_array = $in_parent->_meeting_id_array;
189  $this->_published_search = $in_parent->_published_search;
190 
191  $this->_my_server = $in_parent->_my_server;
192 
193  // These may get changed by this instance.
194  $this->sort_array = $in_parent->sort_array;
195  $this->sort_desc = $in_parent->sort_desc;
196 
197  // These are passed in and set at construction
198  $this->_pageno = $in_pageno;
199  $this->_search_results = $in_search_results;
200  } else // If we are the root object, we start clean.
201  {
202  // See if the caller has requested a number of results per page.
203  if ($in_results_per_page) {
204  $this->_results_per_page = $in_results_per_page;
205  }
206 
207  $this->_my_server = c_comdef_server::MakeServer(); // We initialize the server.
208 
209  $this->SetUpFormats(); // We set the formats array.
210  $this->SetUpServiceBodies(); // We set the Service Bodies array.
211  $this->SetUpLanguages(); // We set the Languages array.
212 
213  // Set up the weekday array (1 = Sunday, 7 = Saturday ).
214  $this->_weekdays = null;
215  for ($wd = 1; $wd < 8; $wd++) {
216  $this->_weekdays[$wd] = 0;
217  }
218 
219  // This is the default sort.
220  $this->sort_array = array ( "lang_enum", "weekday_tinyint", "start_time", "id_bigint" );
221 
222  // We have no search parameters or results at this point.
223  }
224  }
225 
226  /*******************************************************************/
227  /** \brief Sets an internal array of integers, containing the Shared IDs for
228  all available formats on the server. They are initialized to 0 (neutral).
229  */
230  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
231  public function SetUpFormats()
232  {
233  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
234  $this->_formats = null;
235 
236  $formats = $this->GetAvailableFormats();
237 
238  // Basic error checking.
239  if (is_array($formats) && count($formats)) {
240  // We look in the server's local language (in case there are no other translations).
241  $my_lang = $this->_my_server->GetLocalLang();
242 
243  $er = $formats[$my_lang];
244 
245  if (is_array($er) && count($er)) {
246  foreach ($er as $key => $value) { // We ignore the value.
247  $this->_formats[$key] = 0;
248  }
249  }
250  }
251  }
252 
253  /*******************************************************************/
254  /** \brief Accessor -Get a reference to the $_formats field.
255 
256  \returns a reference to the $_formats field, which is an array of integers.
257  The key is the format's shared ID, and the value will be one of these:
258  - -1 NOT (exclude all meetings that contain this format from the search).
259  - 0 No preference (This format will not be a consideration in the search).
260  - 1 Return meetings that contain this format.
261 
262  Default is 0 for all. If no formats are specified (either 1 or -1), then formats will not be a consideration
263  in the meeting search. If any format is specified as 1, then ONLY meetings with the given format will be
264  considered in the search, and you must explicitly set any other formats you wish found.
265  */
266  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
267  public function &GetFormats()
268  {
269  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
270  return $this->_formats;
271  }
272 
273  /*******************************************************************/
274  /** \brief Sets a key/value search.
275  */
276  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
277  public function SetKeyValueSearch(
278  $in_meeting_key, ///< A string. This is the exact name of the key to match.
279  $in_meeting_key_value, ///< A string. The value to match.
280  $in_meeting_key_match_case = false, ///< If true, the case must match. Default is false.
281  $in_meeting_key_contains = true ///< If this is false, then the string must be complete. Default is true (contains).
282  ) {
283  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
284  $this->_meeting_key = $in_meeting_key;
285  $this->_meeting_key_value = $in_meeting_key_value;
286  $this->_meeting_key_match_case = $in_meeting_key_match_case;
287  $this->_meeting_key_contains = $in_meeting_key_contains;
288  }
289 
290  /*******************************************************************/
291  /** \brief Sets the sort by distance flag.
292  */
293  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
294  public function SetSortByDistance( $in_sort_search_by_distance = false ///< A Boolean. False is default.
295  )
296  {
297  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
298  $this->_sort_search_by_distance = ($in_sort_search_by_distance != false);
299  }
300 
301  /*******************************************************************/
302  /** \brief Sets an internal array of integers, containing the IDs for
303  all available service bodies on the server. They are initialized
304  to 0 (neutral).
305  */
306  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
307  public function SetUpServiceBodies()
308  {
309  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
310  $this->_service_bodies = array();
311 
312  // Basic error checking.
313  if ($this->_my_server instanceof c_comdef_server) {
314  // Start by getting the service bodies aggregator object.
315  $bodies = $this->_my_server->GetServiceBodyArray();
316  if (is_array($bodies) && count($bodies)) {
317  foreach ($bodies as $body) {
318  $key = $body->GetID();
319  $this->_service_bodies[$key] = 0;
320  }
321  }
322  }
323  }
324 
325  /*******************************************************************/
326  /** \brief Accessor -Get the number of results per page.
327 
328  \returns an integer.
329  */
330  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
331  public function GetResultsPerPage()
332  {
333  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
334  $ret = 0;
335 
336  // This is kept in the root object.
337  if (!$this->_my_root) {
338  $ret = $this->_results_per_page;
339  } elseif ($this->GetRootObject() instanceof c_comdef_meeting_search_manager) {
340  $ret = $this->GetRootObject()->GetResultsPerPage();
341  }
342 
343  return $ret;
344  }
345 
346  /*******************************************************************/
347  /** \brief Accessor -Set the number of results per page.
348  This will only work on the root object.
349 
350  \returns a boolean. If the operation was successful, it is true. False otherwise.
351  */
352  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
353  public function SetResultsPerPage( $in_results_per_page ///< A positive integer. If it is 0, then all results will be returned in one page.
354  )
355  {
356  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
357  $ret = false;
358 
359  if (!$this->_my_root) {
360  $this->_results_per_page = $in_results_per_page;
361  $ret = true;
362  }
363 
364  return $ret;
365  }
366 
367  /*******************************************************************/
368  /** \brief Accessor -Get the page number of this set.
369 
370  \returns an integer.
371  */
372  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
373  public function GetPageNo()
374  {
375  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
376  return $this->_pageno;
377  }
378 
379  /*******************************************************************/
380  /** \brief Accessor -Get the index (1 - based) of the first meeting in this page.
381 
382  \returns an integer.
383  */
384  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
385  public function GetFirstIndexInPage()
386  {
387  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
388  return ($this->GetResultsPerPage() * ($this->GetPageNo() - 1)) + 1;
389  }
390 
391  /*******************************************************************/
392  /** \brief Accessor -Get the index (1 - based) of the last meeting in this page.
393 
394  \returns an integer.
395  */
396  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
397  public function GetLastIndexInPage()
398  {
399  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
400  return ($this->GetFirstIndexInPage() + $this->GetNumberOfResultsInThisPage()) - 1;
401  }
402 
403  /*******************************************************************/
404  /** \brief Accessor -Get the page number of this set.
405 
406  \returns an integer.
407  */
408  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
409  public function GetNumberOfPages()
410  {
411  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
412  $ret = 0;
413 
414  $respp = $this->GetResultsPerPage();
415  $resnum = $this->GetNumberOfResults();
416 
417  if ($respp > 0) {
418  $ret = intval(($resnum + ($respp - 1)) / $respp);
419  } elseif ($resnum > 0) {
420  $ret = 1;
421  }
422 
423  return $ret;
424  }
425 
426  /*******************************************************************/
427  /** \brief Accessor -Get the total number of meetings found.
428  This gives the TOTAL number found, not just the subset in this page.
429 
430  \returns an integer.
431  */
432  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
433  public function GetNumberOfResults()
434  {
435  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
436  $ret = 0;
437 
438  if (!$this->_my_root && $this->_search_results instanceof c_comdef_meetings) {
439  $ret = $this->_search_results->GetNumMeetings();
440  } elseif ($this->_my_root instanceof c_comdef_meeting_search_manager) {
441  $ret = $this->_my_root->GetNumberOfResults();
442  }
443 
444  return $ret;
445  }
446 
447  /*******************************************************************/
448  /** \brief Accessor -Get the number of meetings in this page.
449 
450  \returns an integer.
451  */
452  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
454  {
455  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
456  $ret = 0;
457 
458  if ($this->_search_results instanceof c_comdef_meetings) {
459  $ret = $this->_search_results->GetNumMeetings();
460  }
461 
462  return $ret;
463  }
464 
465  /*******************************************************************/
466  /** \brief Accessor -Get the number of meetings in this page.
467 
468  This system allows each page to be treated independently, like allowing
469  different sorts without re-sorting the entire search.
470 
471  This object needs to be the "root" object to return a page.
472 
473  \returns a new instance (not a reference) to a c_comdef_meeting_search_manager
474  object, containing a subset of the meetings to fill this one page.
475  */
476  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
477  public function GetPageOfResults( $in_page_no = 1 ///< A positive integer. This should be 1 to $this->GetNumberOfPages() (1-based)
478  )
479  {
480  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
481  if ($in_page_no < 1) { // Can't be less than 1.
482  $in_page_no = 1;
483  }
484 
485  if ($in_page_no > $this->GetNumberOfPages()) { // Can't be greater than the last page.
486  $in_page_no = $this->GetNumberOfPages();
487  }
488 
489  $ret = null;
490 
491  // We get pages from the root at all times.
492  if (!$this->_my_root && $this->_search_results instanceof c_comdef_meetings) {
493  // This is the starting index for our page of results.
494  $main_array_1 = $this->_search_results->GetMeetingObjects();
495  $main_array = array();
496  foreach ($main_array_1 as $meeting) {
497  array_push($main_array, $meeting);
498  }
499 
500  $ret_array = array();
501  $min = $this->GetResultsPerPage() * ($in_page_no - 1);
502  $actual = intval($this->GetResultsPerPage());
503  if ($actual > 0) {
504  $max = min(count($main_array), $min + $this->GetResultsPerPage());
505  } else {
506  $max = $this->GetNumberOfResults();
507  }
508 
509  for ($index = intval($min); $index < intval($max); $index++) {
510  if ($main_array[$index] instanceof c_comdef_meeting) {
511  $data = $main_array[$index]->GetMeetingData();
512  if (is_array($data) && count($data)) {
513  $ret_array[$data['id_bigint']] = $main_array[$index];
514  }
515  }
516  }
517 
518  if (count($ret_array)) {
519  $resultsObj = new c_comdef_meetings($this->_search_results->GetParentObj(), $ret_array);
520 
521  if ($resultsObj instanceof c_comdef_meetings) {
522  $ret = new c_comdef_meeting_search_manager(0, $this, $resultsObj, $in_page_no);
523  }
524  }
525  } elseif ($this->_my_root instanceof c_comdef_meeting_search_manager) {
526  $ret = $this->_my_root->GetPageOfResults($in_page_no);
527  }
528 
529  return $ret;
530  }
531 
532  /*******************************************************************/
533  /** \brief Accessor -Get a reference to the $_service_bodies field.
534 
535  \returns a reference to the $_service_bodies field.
536  The key is the Service Body ID. The value is as follows:
537  - -1 NOT (exclude all meetings that contain this Service Body from the search).
538  - 0 No preference (This Service Body will not be a consideration in the search).
539  - 1 Return meetings that contain this Service Body.
540 
541  Default is 0 for all. If no Service Bodies are specified (either 1 or -1), then Service Bodies will not be a
542  consideration in the meeting search. If any Service Body is specified as 1, then ONLY meetings with the given
543  Service Body will be considered in the search, and you must explicitly set any other Service Bodies you wish found.
544  */
545  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
546  public function &GetServiceBodies()
547  {
548  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
549  return $this->_service_bodies;
550  }
551 
552  /*******************************************************************/
553  /** \brief Sets up an internal array of languages.
554  The array uses the language enum as the key, and the -1->0->1
555  form as the selector.
556  */
557  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
558  public function SetUpLanguages()
559  {
560  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
561  $this->_languages = null;
562 
563  // Basic error checking.
564  if ($this->_my_server instanceof c_comdef_server) {
565  $langs = $this->_my_server->GetServerLangs();
566 
567  if (is_array($langs) && count($langs)) {
568  foreach ($langs as $key => $value) {
569  $this->_languages[$key] = 0;
570  }
571  }
572  }
573  }
574 
575  /*******************************************************************/
576  /** \brief Accessor -Get a reference to the $_languages field.
577 
578  \returns a reference to the $_languages field.
579  The key is the language enum, and the value is as follows:
580  - -1 NOT (exclude all meetings that have this language from the search).
581  - 0 No preference (This language will not be a consideration in the search).
582  - 1 Return meetings that have this language.
583 
584  Default is 0 for all. If no languages are specified (either 1 or -1), then language will not be a
585  consideration in the meeting search. If any language is specified as 1, then ONLY meetings with the given
586  language will be considered in the search, and you must explicitly set any other language you wish found.
587  */
588  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
589  public function &GetLanguages()
590  {
591  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
592  return $this->_languages;
593  }
594 
595  /*******************************************************************/
596  /** \brief Accessor -Get a reference to the $_weekdays field.
597 
598  \returns a reference to the $_weekdays field.
599  The key is the weekday (1 = Sunday, 7 = Saturday), and the value is as follows:
600  - -1 NOT (exclude all meetings that occur on this weekday from the search).
601  - 0 No preference (This weekday will not be a consideration in the search).
602  - 1 Return meetings that occur on this weekday.
603 
604  Default is 0 for all. If no weekdays are specified (either 1 or -1), then the weekday will not be a
605  consideration in the meeting search. If any weekday is specified as 1, then ONLY meetings that occur on
606  the given weekday will be considered in the search, and you must explicitly set any other weekday you wish found.
607  */
608  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
609  public function &GetWeekdays()
610  {
611  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
612  return $this->_weekdays;
613  }
614 
615  /*******************************************************************/
616  /** \brief Accessor -Get a reference to the c_comdef_server object.
617 
618  \returns a reference to the c_comdef_server object instantiated by
619  this object.
620  */
621  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
622  public function GetServer()
623  {
624  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
625  return $this->_my_server;
626  }
627 
628  /*******************************************************************/
629  /** \brief Accessor -Get a reference to the root object.
630 
631  \returns a reference to the c_comdef_meeting_search_manager object.
632  If this is the root object, it will return a reference to itself.
633  */
634  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
635  public function GetRootObject()
636  {
637  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
638  $ret = null;
639 
640  if ($this->_my_root instanceof c_comdef_meeting_search_manager) {
641  $ret = $this->_my_root;
642  } else {
643  $ret = $this;
644  }
645 
646  return $ret;
647  }
648 
649  /*******************************************************************/
650  /** \brief Set a search radius and center, with the Radius in miles.
651  */
652  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
654  $in_search_radius_in_miles, ///< The radius as specified in miles, not Km.
655  $in_long_in_degrees, ///< The longitude needs to be specified in degrees.
656  $in_lat_in_degrees ///< The latitude needs to be specified in degrees.
657  ) {
658  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
659  $this->SetSearchRadiusAndCenterInKm(1.609344 * $in_search_radius_in_miles, $in_long_in_degrees, $in_lat_in_degrees);
660  }
661 
662  /*******************************************************************/
663  /** \brief Set a search radius and center, with the radius in Km.
664  */
665  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
667  $in_search_radius_in_km, ///< The radius needs to be specified in kilometers, not miles.
668  $in_long_in_degrees, ///< The longitude needs to be specified in degrees.
669  $in_lat_in_degrees ///< The latitude needs to be specified in degrees.
670  ) {
671  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
672  $this->_search_radius = $in_search_radius_in_km;
673  $this->_search_center_long = $in_long_in_degrees;
674  $this->_search_center_lat = $in_lat_in_degrees;
675  }
676 
677  /*******************************************************************/
678  /** \brief Set a search center, and a count for an auto radius hunt.
679  The way this works is that the center is set, and the optimal
680  radius is selected in kilometers to deliver that many meetings.
681  The radius starts at 25 Km (about 10 miles), and goes up or
682  down in 5Km "clicks." Under 5Km, it reduces to 0.5Km "clicks."
683  It will not go out more than 100Km.
684 
685  When it passes the threshold for the number of meetings in the
686  square, the radius is selected, and the _search_radius is set
687  to the number of Kilometers.
688 
689  We are not looking for an exact meeting count. It should select the
690  first radius that contains AT LEAST the number of meetings requested.
691 
692  If not enough meetings are found, the radius ends up at 0.
693  */
694  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
696  $in_search_result_count, ///< A positive integer. It specifies the number of meetings to find.
697  $in_long_in_degrees, ///< The longitude needs to be specified in degrees.
698  $in_lat_in_degrees ///< The latitude needs to be specified in degrees.
699  ) {
700  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
701  $this->_search_radius_count = $in_search_result_count;
702  $this->_search_radius = 0;
703  $this->_search_center_long = $in_long_in_degrees;
704  $this->_search_center_lat = $in_lat_in_degrees;
705  }
706 
707  /*******************************************************************/
708  /** \brief Get the search radius.
709 
710  \returns a floating-point number. If the $in_miles parameter is false,
711  the returned value is kilometers. If it is true, the returned value
712  is in miles.
713  */
714  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
715  public function GetRadius( $in_miles = false ///< A boolean. If true, the returned value will be in miles. Otherwise, it is returned in kilometers.
716  )
717  {
718  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
719  return $in_miles ? ($this->_search_radius / 1.609344) : $this->_search_radius;
720  }
721 
722  /*******************************************************************/
723  /** \brief Get the longitude.
724 
725  \returns a floating-point number. The return is in degrees.
726  */
727  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
728  public function GetLongitude()
729  {
730  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
731  return $this->_search_center_long;
732  }
733 
734  /*******************************************************************/
735  /** \brief Get the latitude.
736 
737  \returns a floating-point number. The return is in degrees.
738  */
739  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
740  public function GetLatitude()
741  {
742  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
743  return $this->_search_center_lat;
744  }
745 
746  /*******************************************************************/
747  /** \brief Get the search for published value
748 
749  \returns an integer.
750  - -1 Search for ONLY unpublished meetings
751  - 0 Search for published and unpublished meetings.
752  - 1 Search for ONLY published meetings.
753  */
754  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
755  public function GetPublished()
756  {
757  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
758  return $this->_published_search;
759  }
760 
761  /*******************************************************************/
762  /** \brief Sets the search for published value
763  */
764  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
765  public function SetPublished( $in_published_search
766 // The value to set. It can be:
767  // - -1 Search for ONLY unpublished meetings
768  // - 0 Search for published and unpublished meetings.
769  // - 1 Search for ONLY published meetings.
770  )
771  {
772  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
773  $this->_published_search = $in_published_search;
774  }
775 
776  /*******************************************************************/
777  /** \brief Set a start time window.
778  */
779  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
780  public function SetStartTime(
781  $in_starts_after, ///< An epoch time, defining when the meeting should start (or after)
782  $in_starts_before = null ///< If defined, the meeting must start no later than this.
783  ) {
784  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
785  $this->_start_after = $in_starts_after;
786 
787  // We don't let this be less than, or equal to, the start time.
788  if ((null != $in_starts_after) && (null != $in_starts_before)
789  && (intval($in_starts_after) >= intval($in_starts_before))) {
790  $in_starts_before = null;
791  }
792 
793  // We don't let this be less than, or equal to, the start time.
794  if ((null != $in_starts_after) && (null != $in_starts_before)
795  && (intval($in_starts_after) >= intval($in_starts_before))) {
796  $in_starts_before = null;
797  }
798 
799  $this->_start_before = $in_starts_before;
800  }
801 
802  /*******************************************************************/
803  /** \brief Set a maximum end time.
804  */
805  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
806  public function SetEndTime( $in_ends_before ///< An epoch time, defining that the meeting must end no later than this.
807  )
808  {
809  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
810  $this->_end_before = $in_ends_before;
811  }
812 
813  /*******************************************************************/
814  /** \brief Get the "ends before" value
815 
816  \returns an integer, containing the epoch time for the value.
817  */
818  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
819  public function GetEndsBefore()
820  {
821  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
822  return $this->_end_before;
823  }
824 
825  /*******************************************************************/
826  /** \brief Get the "starts after" value
827 
828  \returns an integer, containing the epoch time for the value.
829  */
830  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
831  public function GetStartTime_Min()
832  {
833  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
834  return $this->_start_after;
835  }
836 
837  /*******************************************************************/
838  /** \brief Get the "starts before" value
839 
840  \returns an integer, containing the epoch time for the value.
841  */
842  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
843  public function GetStartTime_Max()
844  {
845  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
846  return $this->_start_before;
847  }
848 
849  /*******************************************************************/
850  /** \brief Set a duration time window.
851  */
852  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
853  public function SetDuration(
854  $in_max_duration, ///< An epoch time, defining the maximum duration of a meeting.
855  $in_min_duration = null ///< If defined, the minimum duration of the meeting.
856  ) {
857  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
858  $this->_max_duration = $in_max_duration;
859 
860  // We don't let this be less than, or equal to, the start time.
861  if (((null != $in_max_duration) && (null != $in_min_duration)) && intval($in_min_duration) >= intval($in_max_duration)) {
862  $in_min_duration = null;
863  }
864 
865  $this->_min_duration = $in_min_duration;
866  }
867 
868  /*******************************************************************/
869  /** \brief Get the Maximum Duration value
870 
871  \returns an integer, containing the epoch time for the value.
872  */
873  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
874  public function GetDuration_Max()
875  {
876  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
877  return $this->_max_duration;
878  }
879 
880  /*******************************************************************/
881  /** \brief Get the Minimum Duration value
882 
883  \returns an integer, containing the epoch time for the value.
884  */
885  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
886  public function GetDuration_Min()
887  {
888  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
889  return $this->_min_duration;
890  }
891 
892  /*******************************************************************/
893  /** \brief Set a search string.
894  */
895  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
896  public function SetSearchString(
897  $in_search_string, ///< A string. This is a string for which to search.
898  $in_all_words = false, ///< A Boolean. If this is true, then all of the words in a phrase must be present.
899  $in_literal = false ///< A Boolean. If this is true, then the spelling must be literal.
900  ) {
901  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
902  $this->_search_string = $in_search_string;
903  $this->_search_string_all_words = $in_all_words;
904  $this->_search_string_literal = $in_literal;
905  }
906 
907  /*******************************************************************/
908  /** \brief Get the current search string.
909 
910  \returns a reference to the search string.
911  */
912  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
913  public function GetSearchString()
914  {
915  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
916  return $this->_search_string;
917  }
918 
919  /*******************************************************************/
920  /** \brief Set the current search string.
921  */
922  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
923  public function SetMeetingIDArray( $in_meeting_id_array ///< An array of positive integers. These are the IDs of individual meetings to find.
924  )
925  {
926  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
927  $this->_meeting_id_array = $in_meeting_id_array;
928  }
929 
930  /*******************************************************************/
931  /** \brief Get the current search string.
932 
933  \returns a reference to the meeting ID array.
934  */
935  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
936  public function GetMeetingIDArray()
937  {
938  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
939  return $this->_meeting_id_array;
940  }
941 
942  /*******************************************************************/
943  /** \brief Get the current search string "all words" flag.
944  */
945  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
946  public function StringSearchForAllWords()
947  {
948  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
949  return $this->_search_string_all_words;
950  }
951 
952  /*******************************************************************/
953  /** \brief Get the current search string literal flag.
954  */
955  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
956  public function StringSearchIsLiteral()
957  {
958  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
959  return $this->_search_string_literal;
960  }
961 
962  /// These functions will help the caller to get information from the server. You can use them to build a search form.
963 
964  /*******************************************************************/
965  /** \brief Returns an array of language enums and names.
966 
967  \returns a reference to an array of strings, containing the server
968  languages in human-readable, local form. The key will be the enum,
969  and the value will be the name of the language.
970  */
971  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
972  public function GetAvailableLanguages()
973  {
974  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
975  $ret = null;
976 
977  // Basic error checking.
978  if ($this->_my_server instanceof c_comdef_server) {
979  $ret = $this->_my_server->GetServerLangs();
980  }
981 
982  return $ret;
983  }
984 
985  /*******************************************************************/
986  /** \brief Returns an array of references to c_comdef_service_body objects.
987 
988  This returns ALL Service bodies; whether or not they contain meetings.
989 
990  \returns a reference to an array of c_comdef_service_body objects.
991  The key will be the ID of the Service body, and the value will be a reference
992  to the object. Null, if the function fails for any reason.
993 
994  This will reference the actual objects controlled by the server.
995  */
996  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
997  public function GetAvailableServiceBodies()
998  {
999  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1000  $ret = null;
1001 
1002  // Basic error checking.
1003  if ($this->_my_server instanceof c_comdef_server) {
1004  $ret = $this->_my_server->GetServiceBodyArray();
1005  }
1006 
1007  return $ret;
1008  }
1009 
1010  /*******************************************************************/
1011  /** \brief Returns a multi-dimensional array of references to c_comdef_format objects.
1012 
1013  This returns ALL formats; whether or not they are used in meetings.
1014 
1015  \returns a reference to a multi-dimensional array of c_comdef_format objects.
1016  The key will be the language enum, and the value will be another array,
1017  which will have its key as the Shared ID of the format, and the value will be
1018  a reference to the object. Null, if the function fails for any reason.
1019 
1020  This will reference the actual objects controlled by the server.
1021  */
1022  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1023  public function GetAvailableFormats()
1024  {
1025  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1026  $ret = null;
1027 
1028  // Basic error checking.
1029  if ($this->_my_server instanceof c_comdef_server) {
1030  // Start by getting the format aggregator object.
1031  $formats_obj = $this->_my_server->GetFormatsObj();
1032 
1033  if ($formats_obj instanceof c_comdef_formats) {
1034  $ret = $formats_obj->GetFormatsArray();
1035  }
1036  }
1037 
1038  return $ret;
1039  }
1040 
1041  /*******************************************************************/
1042  /** \brief Returns an array of all possible field keys to be used for sorting.
1043 
1044  \returns an array of strings, with the key being the same as the value.
1045  NOTE: This contains ALL possible keys, including ones that may not be
1046  used in the found set.
1047  */
1048  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1049  public static function GetAllAvailableSortKeys()
1050  {
1051  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1053  }
1054 
1055  /// These functions deal with the search itself.
1056 
1057  /*******************************************************************/
1058  /** \brief Returns an array of field keys to be used for sorting.
1059  This function is not static, and searches the found set for keys.
1060  As a result, it takes longer.
1061 
1062  \returns an array of strings, with the key being the same as the value.
1063  NOTE: This contains only the keys used in this found set.
1064 
1065  As a result, this will return null until after a search has been performed.
1066  */
1067  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1068  public function GetSpecificSortKeys()
1069  {
1070  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1071  $ret = null;
1072 
1073  if ($this->_search_results instanceof c_comdef_meetings) {
1074  $ret = $this->_search_results->GetMeetingKeys();
1075  }
1076 
1077  return $ret;
1078  }
1079 
1080  /*******************************************************************/
1081  /** \brief Executes a new search. It will always force a new search.
1082 
1083  \returns an integer that indicates the number of meetings found.
1084  */
1085  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1086  public function DoSearch()
1087  {
1088  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1089  $this->GetSearchResults_Obj(true);
1090 
1091  $ret = $this->GetNumberOfResults();
1092 
1093  return $ret;
1094  }
1095 
1096  /*******************************************************************/
1097  /** \brief Returns a reference to the c_comdef_meetings object that
1098  contains the results of the search. If this is null, or if the
1099  $in_new_search parameter is set to true, the search will be
1100  executed, otherwise, this just returns a reference to the existing
1101  search results.
1102 
1103  \returns a reference to the internal $_search_results field (an
1104  instance of c_comdef_search_results).
1105  */
1106  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1107  public function GetSearchResults_Obj( $in_new_search = false ///< If this is set to true, the search is done anew.
1108  )
1109  {
1110  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1111  // See if we need to make a new search. Only the root can do a new search.
1112  if ((null == $this->_my_root) && (true == $in_new_search) || (null == $this->_search_results)) {
1113  $this->_search_results = null;
1114 
1115  // Basic error checking.
1116  if ($this->_my_server instanceof c_comdef_server) {
1117  // If we have an ID array, then we skip everything else, and just search for those IDs.
1118  if (is_array($this->_meeting_id_array) && count($this->_meeting_id_array)) {
1119  $this->_search_results = c_comdef_server::GetMeetingsByID($this->_meeting_id_array);
1120 
1121  if ($this->_search_results instanceof c_comdef_meetings) {
1122  $this->_search_results->RemoveInvalidMeetings();
1123 
1124  // Force a new sort.
1125  $this->SortMeetingObjects();
1126  }
1127  } else {
1128  // We start by specifying a search using the main criteria. We need to interpret the current state into search criteria.
1129 
1130  // Set up our Service Bodies Array.
1131  $service_bodies = null;
1132 
1133  if (is_array($this->_service_bodies) && count($this->_service_bodies)) {
1134  $service_bodies = array();
1135  foreach ($this->_service_bodies as $key => $value) {
1136  // If the value of the Service Body is 1 or -1, we add it to the list.
1137  if (abs($value) == 1) {
1138  array_push($service_bodies, intval($key) * $value);
1139  }
1140  }
1141  }
1142 
1143  // Set up our weekday array.
1144  $weekdays = null;
1145 
1146  if (is_array($this->_weekdays) && count($this->_weekdays)) {
1147  $weekdays = array();
1148  foreach ($this->_weekdays as $key => $value) {
1149  // If the value of the Weekday is 1 or -1, we add it to the list.
1150  if (abs($value) != 0) {
1151  array_push($weekdays, intval($key) * $value);
1152  }
1153  }
1154  }
1155 
1156  // Set up our formats array.
1157  $formats = null;
1158 
1159  if (is_array($this->_formats) && count($this->_formats)) {
1160  $formats = array();
1161  foreach ($this->_formats as $key => $value) {
1162  // If the value of the format is 1 or -1, we add it to the list.
1163  if (abs($value) == 1) {
1164  array_push($formats, intval($key) * $value);
1165  }
1166  }
1167  }
1168 
1169  $languages = null;
1170 
1171  if (is_array($this->_languages) && count($this->_languages)) {
1172  $languages = array();
1173  foreach ($this->_languages as $key => $value) {
1174  // If the value of the format is 1 or -1, we add it to the list.
1175  if (abs($value) == 1) {
1176  array_push($languages, ($value == -1) ? "-$key" : $key);
1177  }
1178  }
1179  }
1180 
1181  // If we will specify a search radius, we specify a restricted area for the search.
1182  $search_rect = $this->GetSquareForRadius($weekdays, $service_bodies);
1183 
1184  // Do the main database search first.
1185  $null_me = null;
1186  $this->_search_results = c_comdef_server::GetMeetings(
1187  $service_bodies,
1188  $languages,
1189  $weekdays,
1190  $formats,
1191  $this->_start_after,
1192  $this->_start_before,
1193  $this->_end_before,
1194  $this->_min_duration,
1195  $this->_max_duration,
1196  $search_rect,
1197  null,
1198  $null_me,
1199  $this->_published_search,
1200  $this->_formats_comparison_operator
1201  );
1202  if (isset($this->_search_results) && $this->_search_results && ($this->_search_results instanceof c_comdef_meetings)) {
1203  $this->_search_results->RemoveInvalidMeetings();
1204 
1205  // Force a new sort.
1206  $this->SortMeetingObjects();
1207 
1208  // These are two "post-database" searches that we do.
1209  if (null != $this->_search_radius) {
1210  $this->_search_results = $this->_search_results->GetMeetingsByDistance($this->_search_center_long, $this->_search_center_lat, $this->_search_radius, true, $this->_sort_search_by_distance);
1211  }
1212 
1213  if (null != $this->_search_string) {
1214  $_search_results = $this->_search_results->GetMeetingsByString($this->_search_string, null, $this->_search_string_all_words, $this->_search_string_literal);
1215  $this->_search_results = null;
1216  $this->_search_results = $_search_results;
1217  }
1218 
1219  if ($this->_meeting_key) {
1220  $key_array = (is_array($this->_meeting_key) && count($this->_meeting_key)) ? $this->_meeting_key : array ( $this->_meeting_key );
1221  $_search_results = $this->_search_results->GetMeetingsByKeyValue($key_array, $this->_meeting_key_value, $this->_meeting_key_contains, $this->_meeting_key_match_case);
1222  $this->_search_results = null;
1223  $this->_search_results = $_search_results;
1224  }
1225  }
1226  }
1227  }
1228  }
1229 
1230  return $this->_search_results;
1231  }
1232 
1233  /*******************************************************************/
1234  /** \brief Clears the search results, so the next access will redo the search.
1235  */
1236  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1237  public function ClearSearch()
1238  {
1239  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1240  // Only the root can clear its search results.
1241  if (null == $this->_my_root) {
1242  $this->_search_results = null;
1243  }
1244  }
1245 
1246  /*******************************************************************/
1247  /** \brief This will return the search results as an array of c_comdef_meeting
1248  objects.
1249 
1250  \returns a reference to an array of references to c_comdef_meeting objects.
1251  */
1252  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1253  public function GetSearchResultsAsArray()
1254  {
1255  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1256  $ret = null;
1257 
1258  if ($this->GetSearchResults_Obj() instanceof c_comdef_meetings) {
1259  $s_array = $this->GetSearchResults_Obj()->GetMeetingObjects();
1260 
1261  if (is_array($s_array) && count($s_array)) {
1262  $ret = $s_array;
1263  }
1264  }
1265 
1266  return $ret;
1267  }
1268 
1269  /// These are sorting functions.
1270 
1271  /*******************************************************************/
1272  /** \brief Simply clears out the sort array, so the search is unsorted.
1273  */
1274  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1275  public function ClearSort()
1276  {
1277  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1278  // Only the root can do this.
1279  if (null == $this->_my_root) {
1280  $this->sort_array = null;
1281  }
1282  }
1283 
1284  /*******************************************************************/
1285  /** \brief Accessor. Set the maximum number of sorts to maintain.
1286  If the current number is more than the new value, then we remove any
1287  beyond that.
1288  */
1289  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1290  public function SetSortDepth( $in_new_depth = 0 ///< A positive integer. If nothing is provided, we set to endless (0).
1291  )
1292  {
1293  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1294  // Only the root can do this.
1295  if (null == $this->_my_root) {
1296  $this->sort_depth = $in_new_depth;
1297  if (0 < $this->sort_depth) { // Only if a depth is defined.
1298  while (count($this->sort_array) > $this->sort_depth) {
1299  array_shift($this->sort_array); // Take off the bottommost one.
1300  }
1301  }
1302 
1303  // Force a new sort, based on the new depth.
1304  $this->SortMeetingObjects();
1305  }
1306  }
1307 
1308  /*******************************************************************/
1309  /** \brief Set a new "top" sort priority.
1310 
1311  The prior "top" sort priority will be made secondary. If the key
1312  was previously "lower" in the sort priority, it is removed from there.
1313 
1314  It will trigger a sort after the new key has been established.
1315 
1316  This allows a very "natural" type of sorting, where the user goes
1317  from one field to another.
1318 
1319  This will always reset the sort direction to the given one (or will
1320  reset to ascending). We could save the direction with each column,
1321  but that is likely to result in a confusing mess. It's a better idea
1322  to just apply the same direction to every column.
1323  */
1324  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1325  public function SetTopSortPriority(
1326  $in_new_top_sort_key, ///< A string. This should be the database table column name for the new "top" sort key.
1327  $in_desc = false ///< If this is set to true, the sort will be highest to lowest. Default is false.
1328  ) {
1329  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1330  // Only the root can do this.
1331  if (null == $this->_my_root) {
1332  // We first remove any previous mention of this key.
1333  for ($i = 0; $i < count($this->sort_array); $i++) {
1334  if ($this->sort_array[$i] == $in_new_top_sort_key) {
1335  unset($this->sort_array[$i]);
1336  break;
1337  }
1338  }
1339 
1340  // The new key goes in as the first item.
1341  if (!is_array($this->sort_array) || (1 > count($this->sort_array))) {
1342  $this->sort_array = array( $in_new_top_sort_key );
1343  } else {
1344  // We first see if we are at the limit for sort depth.
1345 
1346  if (0 < $this->sort_depth) { // Only if a depth is defined.
1347  while (count($this->sort_array) >= $this->sort_depth) {
1348  array_shift($this->sort_array); // Take off the bottommost one.
1349  }
1350  }
1351 
1352  array_unshift($this->sort_array, $in_new_top_sort_key);
1353  }
1354 
1355  // Make sure the new array direction is recorded.
1356  $this->sort_desc = $in_desc;
1357 
1358  // Force a new sort.
1359  $this->SortMeetingObjects();
1360  }
1361  }
1362 
1363  /*******************************************************************/
1364  /** \brief Sets up the sort array and direction. This replaces the
1365  entire array and direction. If the array is longer than the
1366  maximum number of sort keys, only that number of keys are used.
1367 
1368  It will reset the sort direction, so you need to explicitly indicate
1369  the sort direction if you want it descending, as opposed to ascending.
1370  */
1371  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1372  public function SetSort(
1373  $in_sort_fields_array = null,
1374  // An array of strings. The array will deliniate the sort order, by field name.
1375  // Array element [0] will be the highest priority, and it will descend from there.
1376  // If this is not specified, the sort will be cleared.
1377  $in_desc = false, ///< If this is set to true, the sort will be highest to lowest. Default is false.
1378  $in_max_sort_keys = 0 ///< A positive integer, specifying a new maximum sort depth. If it is not specified, the max will not be changed.
1379  ) {
1380  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1381  // Only the root can do this.
1382  if (null == $this->_my_root) {
1383  if (false != $in_desc) {
1384  $in_desc = true;
1385  }
1386 
1387  $this->sort_desc = $in_desc;
1388 
1389  if (0 < $in_max_sort_keys) {
1390  $this->sort_depth = $in_max_sort_keys;
1391  }
1392 
1393  if (null != $in_sort_fields_array) {
1394  $max = min($this->sort_depth, count($in_sort_fields_array));
1395 
1396  if ($max > 0) {
1397  $this->sort_array = array_slice($in_sort_fields_array, 0, $max);
1398  } else {
1399  $this->sort_array = null;
1400  }
1401  }
1402  }
1403  }
1404 
1405  /*******************************************************************/
1406  /** \brief Sorts the meetings.
1407  This will apply a sort, dependent upon the given fields.
1408  The given array contains the field names (SQL columns and keys)
1409  for the data to be sorted.
1410 
1411  If you don't specify any parameters, the ones from the last sort
1412  will be used.
1413  */
1414  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1415  public function SortMeetingObjects(
1416  $in_sort_fields_array = null,
1417  // An array of strings. The array will deliniate the sort order, by field name.
1418  // Array element [0] will be the highest priority, and it will descend from there.
1419  $in_desc = null ///< If this is set to true, the sort will be highest to lowest. Default is false.
1420  ) {
1421  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1422  // Only the root can do this.
1423  if (null == $this->_my_root) {
1424  if (null != $this->_search_results) {
1425  if (null != $in_sort_fields_array) {
1426  $this->sort_array = $in_sort_fields_array;
1427  } else {
1428  $in_sort_fields_array = $this->sort_array;
1429  }
1430 
1431  if (null != $in_desc) {
1432  $this->sort_desc = $in_desc;
1433  } else {
1434  $in_desc = $this->sort_desc;
1435  }
1436 
1437  if (is_array($in_sort_fields_array) && count($in_sort_fields_array)) {
1438  // This is simply a "pass-through" to the object we have on hand.
1439  $this->_search_results->SortMeetingObjects($in_sort_fields_array, $in_desc, $this->_sort_search_by_distance);
1440  }
1441  }
1442  }
1443  }
1444 
1445  /// These are various utility functions.
1446 
1447  /*******************************************************************/
1448  /** \brief This is an internal utility function that takes a specified
1449  radius and center point and calculates a square, in longitude and
1450  latitude points, that encompasses that radius. This greatly narrows
1451  the scope of the search, so the radius calculation will simply eliminate
1452  any meetings that are "in the corners."
1453 
1454  If the setting is for auto-radius, the auto-radius is first resolved, then
1455  the main radius value is set. Remember that auto-radius is for all meetings,
1456  all days of the week. It is really a "density test," as opposed to an
1457  accurate selector.
1458 
1459  \returns an array of floating-point values, in the following form:
1460  - ['east'] = longitude of the Eastern side of the rectangle
1461  - ['west'] = longitude of the Western side of the rectangle
1462  - ['north'] = latitude of the Northern side of the rectangle
1463  - ['south'] = latitude of the Southern side of the rectangle
1464  */
1465  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1466  public function GetSquareForRadius(
1467  $in_weekday_tinyint_array, ///< An array of weekdays in which to filter for.
1468  $in_service_bodies_array = null ///< An array of service bodies in which to filter for.
1469  ) {
1470  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1471  $loc = array ();
1472 
1473  if ($this->_search_radius_count) {
1474  $this->_search_radius = c_comdef_server::HuntForRadius($this->_search_radius_count, $this->_search_center_long, $this->_search_center_lat, $in_weekday_tinyint_array, $in_service_bodies_array);
1475  $this->_search_radius_count = null;
1476  }
1477 
1478  if ($this->_search_radius > 0) {
1479  $loc = c_comdef_server::GetSquareForRadius($this->_search_radius, $this->_search_center_long, $this->_search_center_lat);
1480  }
1481 
1482  return $loc;
1483  }
1484 
1485  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1486  public function SetFormatsComparisonOperator($operator)
1487  {
1488  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1489  if ($operator == "OR") {
1490  $this->_formats_comparison_operator = "OR";
1491  } else {
1492  $this->_formats_comparison_operator = "AND";
1493  }
1494  }
1495 
1496  /// These are static functions for directly accessing meetings via ID.
1497 
1498  /*******************************************************************/
1499  /** \brief This is a static utility function that will return one single
1500  instance of c_comdef_meeting, based upon the ID of that meeting.
1501 
1502  \returns a new (not reference) c_comdef_meeting instance. Null if it fails.
1503  */
1504  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1505  public static function GetSingleMeetingByID( $in_id ///< An integer. The ID of the meeting.
1506  )
1507  {
1508  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1509  return c_comdef_server::GetOneMeeting($in_id);
1510  }
1511 
1512  /*******************************************************************/
1513  /** \brief This is a static utility function that will return multiple
1514  instances of c_comdef_meeting, based upon the IDs of the meetings.
1515  It will create an array to hold these instances
1516 
1517  NOTE: This is NOT the same as the c_comdef_server::GetMeetingsByID()
1518  function, as that function returns an instance of c_comdef_meetings.
1519 
1520  \returns an array of new (not reference) c_comdef_meeting instances.
1521  Null if it fails.
1522  */
1523  // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1524  public static function GetMultipleMeetingsByID( $in_id_array ///< An array of integers. The IDs of the meetings.
1525  )
1526  {
1527  // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
1528  $ret = null;
1529 
1530  if (is_array($in_id_array) && count($in_id_array)) {
1531  foreach ($in_id_array as $id) {
1532  $ret[$id] = c_comdef_search_manager::GetSingleMeetingByID($id);
1533  }
1534  }
1535 
1536  return $ret;
1537  }
1538 }
SetUpLanguages()
Sets up an internal array of languages. The array uses the language enum as the key, and the -1->0->1 form as the selector.
GetRadius($in_miles=false)
Get the search radius.
A class to hold a single meeting object.
GetNumberOfPages()
Accessor -Get the page number of this set.
SetTopSortPriority($in_new_top_sort_key, $in_desc=false)
Set a new "top" sort priority.
static GetAllMeetingKeys()
Returns an array of strings, containing the keys (table columns) used for all meetings (specified in ...
GetAvailableServiceBodies()
Returns an array of references to c_comdef_service_body objects.
GetSpecificSortKeys()
These functions deal with the search itself.
GetPageOfResults($in_page_no=1)
Accessor -Get the number of meetings in this page.
GetSquareForRadius($in_weekday_tinyint_array, $in_service_bodies_array=null)
These are various utility functions.
SetEndTime($in_ends_before)
Set a maximum end time.
DoSearch()
Executes a new search. It will always force a new search.
$ret
Definition: contact.php:226
& GetFormats()
Accessor -Get a reference to the $_formats field.
GetPageNo()
Accessor -Get the page number of this set.
SetSort($in_sort_fields_array=null, $in_desc=false, $in_max_sort_keys=0)
Sets up the sort array and direction. This replaces the entire array and direction. If the array is longer than the maximum number of sort keys, only that number of keys are used.
GetNumberOfResults()
Accessor -Get the total number of meetings found. This gives the TOTAL number found, not just the subset in this page.
GetRootObject()
Accessor -Get a reference to the root object.
GetSearchResults_Obj($in_new_search=false)
Returns a reference to the c_comdef_meetings object that contains the results of the search...
GetFirstIndexInPage()
Accessor -Get the index (1 - based) of the first meeting in this page.
SetDuration($in_max_duration, $in_min_duration=null)
Set a duration time window.
& GetWeekdays()
Accessor -Get a reference to the $_weekdays field.
GetSearchResultsAsArray()
This will return the search results as an array of c_comdef_meeting objects.
GetNumberOfResultsInThisPage()
Accessor -Get the number of meetings in this page.
SetSearchRadiusAndCenterAuto($in_search_result_count, $in_long_in_degrees, $in_lat_in_degrees)
Set a search center, and a count for an auto radius hunt. The way this works is that the center is se...
SortMeetingObjects($in_sort_fields_array=null, $in_desc=null)
Sorts the meetings. This will apply a sort, dependent upon the given fields. The given array contains...
GetLastIndexInPage()
Accessor -Get the index (1 - based) of the last meeting in this page.
& GetServiceBodies()
Accessor -Get a reference to the $_service_bodies field.
Include the format class.
GetResultsPerPage()
Accessor -Get the number of results per page.
GetServer()
Accessor -Get a reference to the c_comdef_server object.
static GetSquareForRadius($in_radius, $in_long_in_degrees, $in_lat_in_degrees)
This is a static utility function that takes a specified radius and center point and calculates a squ...
static GetMeetingsByID($in_id_bigint_array)
Get a series of meetings, each identified by an ID. This does not filter by any of the other major cr...
StringSearchIsLiteral()
Get the current search string literal flag.
SetMeetingIDArray($in_meeting_id_array)
Set the current search string.
SetKeyValueSearch($in_meeting_key, $in_meeting_key_value, $in_meeting_key_match_case=false, $in_meeting_key_contains=true)
Sets a key/value search.
SetSearchString($in_search_string, $in_all_words=false, $in_literal=false)
Set a search string.
GetAvailableLanguages()
These functions will help the caller to get information from the server. You can use them to build a ...
SetSearchRadiusAndCenterInMiles($in_search_radius_in_miles, $in_long_in_degrees, $in_lat_in_degrees)
Set a search radius and center, with the Radius in miles.
static HuntForRadius($in_search_result_count, $in_long_in_degrees, $in_lat_in_degrees, $in_weekday_tinyint_array, $in_service_bodies_array=null)
Find the smallest radius that contains at least the given number of meetings. The way this works is t...
& GetLanguages()
Accessor -Get a reference to the $_languages field.
SetPublished($in_published_search)
Sets the search for published value.
static MakeServer()
This is the factory for the server instantiation. It makes sure that only one instance exists...
This class is the main server class. It instantiates a PDO database object, and is the starting point...
static GetMultipleMeetingsByID($in_id_array)
This is a static utility function that will return multiple instances of c_comdef_meeting, based upon the IDs of the meetings. It will create an array to hold these instances.
SetSortByDistance($in_sort_search_by_distance=false)
Sets the sort by distance flag.
SetUpServiceBodies()
Sets an internal array of integers, containing the IDs for all available service bodies on the server...
defined('BMLT_EXEC') or define('BMLT_EXEC'
Definition: index.php:3
A class to hold a collection of c_comdef_meeting objects.
ClearSearch()
Clears the search results, so the next access will redo the search.
SetUpFormats()
Sets an internal array of integers, containing the Shared IDs for all available formats on the server...
SetResultsPerPage($in_results_per_page)
Accessor -Set the number of results per page. This will only work on the root object.
SetStartTime($in_starts_after, $in_starts_before=null)
Set a start time window.
StringSearchForAllWords()
Get the current search string "all words" flag.
static GetOneMeeting($in_id_bigint, $test_only=false)
Given an ID for a meeting, it returns one instance.
SetSortDepth($in_new_depth=0)
Accessor. Set the maximum number of sorts to maintain. If the current number is more than the new val...
static GetAllAvailableSortKeys()
Returns an array of all possible field keys to be used for sorting.
__construct($in_results_per_page=0, c_comdef_meeting_search_manager &$in_parent=null, c_comdef_meetings &$in_search_results=null, $in_pageno=0)
Constructor.
GetAvailableFormats()
Returns a multi-dimensional array of references to c_comdef_format objects.
static GetMeetings($in_service_body_id_bigint_array=null, $in_lang_filter_array=null, $in_weekday_tinyint_array=null, $in_formats=null, $in_start_after=null, $in_start_before=null, $in_end_before=null, $in_min_duration=null, $in_max_duration=null, $in_search_rect_array=null, $in_first=null, &$in_num=null, $in_published=0, $formats_comparison_operator="AND")
Given a set of one or more main criteria, returns a new c_comdef_meetings object with instances of th...
SetSearchRadiusAndCenterInKm($in_search_radius_in_km, $in_long_in_degrees, $in_lat_in_degrees)
Set a search radius and center, with the radius in Km.
GetPublished()
Get the search for published value.
A class to control the basic common functionality of all meeting searches.
static GetSingleMeetingByID($in_id)
These are static functions for directly accessing meetings via ID.