-
Notifications
You must be signed in to change notification settings - Fork 1
/
bmlt-cms-satellite-plugin.php
3784 lines (3288 loc) · 261 KB
/
bmlt-cms-satellite-plugin.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?php
/****************************************************************************************//**
* \file bmlt-cms-satellite-plugin.php *
* *
* \brief This is a generic CMS plugin class for a BMLT satellite client. *
* \version 3.9.11 *
* *
* This file is part of the BMLT Common Satellite Base Class Project. The project GitHub *
* page is available here: https://github.com/MAGSHARE/BMLT-Common-CMS-Plugin-Class *
* *
* This file is part of the Basic Meeting List Toolbox (BMLT). *
* *
* Find out more at: https://bmlt.app *
* *
* BMLT is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* BMLT is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this code. If not, see <http://www.gnu.org/licenses/>. *
********************************************************************************************/
// define ( '_DEBUG_MODE_', 1 ); //Uncomment for easier JavaScript debugging.
// Include the satellite driver class.
if (!defined('ROOTPATH')) {
require_once(__DIR__.'/../bmlt-satellite-driver/bmlt_satellite_controller.class.php');
} else {
require_once(ROOTPATH .'/vendor/bmlt/bmlt-satellite-driver/bmlt_satellite_controller.class.php');
}
global $g_lang_keys;
global $g_my_languages;
$g_my_languages = array();
$g_lang_keys = array();
$dirname = dirname(__FILE__) . "/lang";
$dir = new DirectoryIterator($dirname);
foreach ($dir as $fileinfo) {
if (!$fileinfo->isDot()) {
$fName = $fileinfo->getFilename();
if (($fName != "index.php") && preg_match("|^lang_|", $fName)) {
$fPath = $dirname . "/" . $fName;
if ($file = fopen($fPath, "r")) {
$line0 = fgets($file);
$line1 = fgets($file);
$lang_name = trim(substr($line1, 3));
$lang_key = trim(substr($fName, 5, -4));
if ($lang_name && $lang_key) {
include_once($fPath);
$eval_string = '$lang_instance = new BMLT_Localized_BaseClass_' . $lang_key . '();';
eval($eval_string);
$g_my_languages[$lang_key] = $lang_instance;
}
}
}
}
}
// This is the cookie (and parameter) name used to explicitly set the language used by the client.
if (!defined('_LANG_COOKIE_NAME')) {
define('_LANG_COOKIE_NAME', 'bmlt_admin_lang_pref');
}
global $bmlt_localization; ///< Use this to control the localization.
$tmp_local = false; ///< This will hold the selected language as we test for an explicit one.
// We can use a cookie to store the language pref. The name is historical, and comes from an existing cookie for the Root Server.
if (isset($_COOKIE) && isset($_COOKIE[_LANG_COOKIE_NAME]) && $_COOKIE[_LANG_COOKIE_NAME]) {
$tmp_local = $_COOKIE[_LANG_COOKIE_NAME];
}
// GET overpowers cookie.
if (isset($_GET['lang_enum']) && $_GET['lang_enum']) {
$tmp_local = $_GET['lang_enum'];
}
// POST overpowers GET.
if (isset($_POST['lang_enum']) && $_POST['lang_enum']) {
$tmp_local = $_POST['lang_enum'];
}
// This allows us a "superparameter" to override the standard 'lang_enum'.
// GET overpowers cookie.
if (isset($_GET[_LANG_COOKIE_NAME]) && $_GET[_LANG_COOKIE_NAME]) {
$tmp_local = $_GET[_LANG_COOKIE_NAME];
}
// POST overpowers GET.
if (isset($_POST[_LANG_COOKIE_NAME]) && $_POST[_LANG_COOKIE_NAME]) {
$tmp_local = $_POST[_LANG_COOKIE_NAME];
}
// If the language is not valid, we fall back on the existing global.
if ((!$tmp_local || !file_exists(dirname(__FILE__)."/lang/lang_".$tmp_local.".php")) && isset($bmlt_localization) && $bmlt_localization) { // Fall back on a previously set global.
$tmp_local = $bmlt_localization;
}
// If the language is not valid, we fall back on the existing global.
if (!$tmp_local) {
$tmp_local = 'en';
}
$bmlt_localization = $tmp_local;
/****************************************************************************************//**
* \class BMLTPlugin *
* *
* \brief This is the class that implements and encapsulates the plugin functionality. *
* A single instance of this is created, and manages the plugin. *
* *
* This plugin registers errors by echoing HTML comments, so look at the source code of *
* the page if things aren't working right. *
********************************************************************************************/
// phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
abstract class BMLTPlugin
// phpcs:enable PSR1.Classes.ClassDeclaration.MissingNamespace
{
/************************************************************************************//**
* STATIC DATA MEMBERS (SINGLETON) *
****************************************************************************************/
/// This is a SINGLETON pattern. There can only be one...
public static $g_s_there_can_only_be_one = null; ///< This is a static variable that holds the single instance.
/************************************************************************************//**
* STATIC DATA MEMBERS (DEFAULTS) *
* In Version 2, these are all ignored: *
* $default_bmlt_fullscreen *
* $default_support_old_browsers *
* $default_sb_array *
****************************************************************************************/
public static $adminOptionsName = "BMLTAdminOptions"; ///< The name, in the database, for the version 1 options for this plugin.
public static $admin2OptionsName = "BMLT2AdminOptions"; ///< These options are for version 2.
// These are the old settings that we still care about.
public static $default_rootserver = ''; ///< This is the default root BMLT server URI.
public static $default_map_center_latitude = 29.764377375163125; ///< This is the default basic search map center latitude
public static $default_map_center_longitude = -95.4931640625; ///< This is the default basic search map center longitude
public static $default_map_zoom = 8; ///< This is the default basic search map zoom level
public static $default_details_map_zoom = 11; ///< This is the default basic search map zoom level
public static $default_location_checked = 0; ///< If nonzero, then the "This is a location" checkbox will be preselected.
public static $default_location_services = 0; ///< This tells the new default implementation whether or not location services should be available only for mobile devices.
public static $default_gkey = ''; ///< This is only necessary for older versions.
public static $default_additional_css = ''; ///< This is additional CSS that is inserted inline into the <head> section.
public static $default_initial_view = ''; ///< The initial view for old-style BMLT. It can be 'map', 'text', 'advanced', 'advanced map', 'advanced text' or ''.
public static $default_theme = 'default'; ///< This is the default for the "style theme" for the plugin. Different settings can have different themes.
public static $default_language = 'en'; ///< The default language is English, but the root server can override.
public static $default_language_string = 'English'; ///< The default language is English, and the name is spelled out, here.
public static $default_distance_units = 'mi'; ///< The default distance units are miles.
public static $default_grace_period = 15; ///< The default grace period for the mobile search (in minutes).
public static $default_time_offset = 0; ///< The default time offset from the main server (in hours).
public static $default_military_time = false; ///< If this is true, then time displays will be in military time.
public static $default_startWeekday = 1; ///< The default starting weekday (Sunday)
public static $default_duration = '1:30'; ///< The default duration of meetings.
public static $default_geo_width = '-10'; ///< The default geo width for searches.
/************************************************************************************//**
* STATIC DATA MEMBERS (MISC) *
****************************************************************************************/
public static $local_options_success_time = 2000; ///< The number of milliseconds a success message is displayed.
public static $local_options_failure_time = 5000; ///< The number of milliseconds a failure message is displayed.
/************************************************************************************//**
* DYNAMIC DATA MEMBERS *
****************************************************************************************/
public $my_driver = null; ///< This will contain an instance of the BMLT satellite driver class.
public $my_params = null; ///< This will contain the $this->my_http_vars and $_POST query variables.
public $my_http_vars = null; ///< This will hold all of the query arguments.
public $my_table_next_id = 0; ///< The next ID to use for the table.
public $my_current_language; ///< This contains whatever the current localization object is.
/************************************************************************************//**
* FUNCTIONS/METHODS *
****************************************************************************************/
/************************************************************************************//**
* \brief Get the instance *
* *
* \return An instance of BMLTPlugin *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public static function get_plugin_object()
{
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
return self::$g_s_there_can_only_be_one;
}
/************************************************************************************//**
* ACCESSORS AND INTERNAL FUNCTIONS *
****************************************************************************************/
/************************************************************************************//**
* \brief Adapts all the static data members to the selected language. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public function adapt_to_lang( $in_lang = "en" ///< The language code. Default is English.
)
{
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
global $g_my_languages;
$this->my_current_language = $g_my_languages[$in_lang];
}
/************************************************************************************//**
* \brief Accessor: This gets the driver object. *
* *
* \returns a reference to the bmlt_satellite_controller driver object *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public function &get_my_driver()
{
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
return $this->my_driver;
}
/************************************************************************************//**
* \brief Loads the parameter list. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public function load_params()
{
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
$this->my_params = self::get_params($this->my_http_vars);
}
/************************************************************************************//**
* \brief Loads a parameter list. *
* *
* \returns a string, containing the joined parameters. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public static function get_params($in_array)
{
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
$my_params = '';
foreach ($in_array as $key => $value) {
if (($key != 'lang_enum') && isset($in_array['direct_simple']) || (!isset($in_array['direct_simple']) && $key != 'switcher') && ($key != 'redirect_ajax_json')) { // We don't propagate switcher or the language.
if (isset($value) && is_array($value) && count($value)) {
foreach ($value as $val) {
if (isset($val) && is_array($val) && count($val)) {
// This stupid, stupid, kludgy dance, is because Drupal 7
// Doesn't seem to acknowledge the existence of the join() or
// implode() functions, and puts out a notice.
$val_ar = '';
foreach ($val as $v) {
if (!is_array($v)) { // This makes sure that we ignore any nested arrays, which can happen for some CMS implementations.
if ($val_ar) {
$val_ar .= ',';
}
$val_ar .= $v;
}
}
$val = strval($val_ar);
} elseif (!isset($val)) {
$val = '';
}
$my_params .= '&'.urlencode($key) ."[]=". urlencode($val);
}
$key = null;
}
if ($key) {
$my_params .= '&'.urlencode($key);
if ($value) {
$my_params .= "=". urlencode($value);
}
}
}
}
return $my_params;
}
/************************************************************************************//**
* This will strip the cruft out of CSS and JS files. *
* \returns a string, with the stripped CSS. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public static function stripFile(
$in_filename, ///< The filename to open and optimize. If in a subdirectory (other than themes), then that should be part of the string.
$in_theme_dirname = null ///< The dirname of the theme to use. Default is NULL (Looks in the same directory as this file).
) {
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
$pathname = dirname(__FILE__) . ($in_theme_dirname ? '/themes/' . $in_theme_dirname : '') . '/' . $in_filename;
if (file_exists($pathname)) {
$opt = file_get_contents($pathname);
$opt = preg_replace("|\/\*.*?\*\/|s", "", $opt);
$opt = preg_replace("|[^:]\/\/.*?\n|s", "", $opt);
if (!defined('_DEBUG_MODE_')) {
$opt = preg_replace("|\s+|s", " ", $opt);
}
return $opt;
}
return "";
}
/****************************************************************************************//**
* \brief Checks the UA of the caller, to see if it should return XHTML Strict or WML. *
* *
* NOTE: This is very, very basic. It is not meant to be a studly check, like WURFL. *
* *
* \returns A string. The supported type ('xhtml', 'xhtml_mp' or 'wml') *
********************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public static function mobile_sniff_ua( $in_http_vars ///< The query variables.
)
{
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
if (isset($in_http_vars['WML']) && (intval($in_http_vars['WML']) == 1)) {
$language = 'wml';
} elseif (isset($in_http_vars['WML']) && (intval($in_http_vars['WML']) == 2)) {
$language = 'xhtml_mp';
} else {
if (!isset($_SERVER['HTTP_ACCEPT'])) {
return false;
}
$http_accept = explode(',', $_SERVER['HTTP_ACCEPT']);
$accept = array();
foreach ($http_accept as $type) {
$type = strtolower(trim(preg_replace('/\;.*$/', '', preg_replace('/\s+/', '', $type))));
$accept[$type] = true;
}
$language = 'xhtml';
if (isset($accept['text/vnd.wap.wml'])) {
$language = 'wml';
if (isset($accept['application/xhtml+xml']) || isset($accept['application/vnd.wap.xhtml+xml'])) {
$language = 'xhtml_mp';
}
} else {
if (preg_match('/ipod/i', $_SERVER['HTTP_USER_AGENT'])
|| preg_match('/ipad/i', $_SERVER['HTTP_USER_AGENT'])
|| preg_match('/iphone/i', $_SERVER['HTTP_USER_AGENT'])
|| preg_match('/android/i', $_SERVER['HTTP_USER_AGENT'])
|| preg_match('/blackberry/i', $_SERVER['HTTP_USER_AGENT'])
|| preg_match("/opera\s+mini/i", $_SERVER['HTTP_USER_AGENT'])
|| isset($in_http_vars['simulate_smartphone'])
) {
$language = 'smartphone';
}
}
}
return $language;
}
/************************************************************************************//**
* \brief This will parse the given text, to see if it contains the submitted code. *
* *
* The code can be contained in EITHER an HTML comment (<!--CODE-->), OR a double-[[]] *
* notation. *
* *
* \returns Boolean true if the code is found (1 or more instances), OR an associative *
* array of data that is associated with the code (anything within parentheses). Null *
* is returned if there is no shortcode detected. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public static function get_shortcode(
$in_text_to_parse, ///< The text to search for shortcodes
$in_code ///< The code that w're looking for.
) {
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
$ret = null;
$code_regex_html = "\<\!\-\-\s?".preg_quote(strtolower(trim($in_code)))."\s?(\(.*?\))?\s?\-\-\>";
$code_regex_brackets = "\[\[\s?".preg_quote(strtolower(trim($in_code)))."\s?(\(.*?\))?\s?\]\]";
$matches = array();
if (preg_match('|'.$code_regex_html.'|i', $in_text_to_parse, $matches) || preg_match('|'.$code_regex_brackets.'|i', $in_text_to_parse, $matches)) {
if (!isset($matches[1]) || !($ret = trim($matches[1], '()'))) { // See if we have any parameters.
$ret = true;
}
}
return $ret;
}
/************************************************************************************//**
* \brief This will parse the given text, to see if it contains the submitted code. *
* *
* The code can be contained in EITHER an HTML comment (<!--CODE-->), OR a double-[[]] *
* notation. *
* *
* \returns A string, consisting of the new text. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public static function replace_shortcode(
$in_text_to_parse, ///< The text to search for shortcodes
$in_code, ///< The code that w're looking for.
$in_replacement_text ///< The text we'll be replacing the shortcode with.
) {
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
$code_regex_html = "#(\<p[^\>]*?\>)?\<\!\-\-\s?".preg_quote(strtolower(trim($in_code)))."\s?(\(.*?\))?\s?\-\-\>(\<\/p>)?#i";
$code_regex_brackets = "#(\<p[^\>]*?\>)?\[\[\s?".preg_quote(strtolower(trim($in_code)))."\s?(\(.*?\))?\s?\]\](\<\/p>)?#i";
$ret = preg_replace($code_regex_html, $in_replacement_text, $in_text_to_parse, 1);
$ret = preg_replace($code_regex_brackets, $in_replacement_text, $ret, 1);
return $ret;
}
/************************************************************************************//**
* OPTIONS MANAGEMENT *
*****************************************************************************************
* This takes some 'splainin'. *
* *
* The admin2 options track how many servers we're tracking, and allow the admin to *
* increment by 1. The first options don't have a number. "Numbered" options begin at *
* 2. You are allowed to save new options at 1 past the current number of options. You *
* delete options by decrementing the number in the admin2 options (the index). If you *
* re-increment the options, you will see the old values. It is possible to reset to *
* default, and you do that by specifying an option number less than 0 (-1). *
* *
* The reason for this funky, complex game, is so we can have multiple options, and we *
* don't ignore old options from previous versions. *
* *
* I considered setting up an abstracted, object-based system for managing these, but *
* it's complex enough without the added overhead, and, besides, that would give a lot *
* more room for bugs. It's kinda hairy already, and the complexity is not great *
* enough to justify designing a whole object subsystem for it. *
****************************************************************************************/
/************************************************************************************//**
* \brief This gets the default admin options from the object (not the DB). *
* *
* \returns an associative array, with the default option settings. *
****************************************************************************************/
protected function geDefaultBMLTOptions()
{
global $bmlt_localization;
// These are the defaults. If the saved option has a different value, it replaces the ones in here.
$ret = array ( 'root_server' => self::$default_rootserver,
'map_center_latitude' => self::$default_map_center_latitude,
'map_center_longitude' => self::$default_map_center_longitude,
'map_zoom' => self::$default_map_zoom,
'bmlt_initial_view' => self::$default_initial_view,
'additional_css' => self::$default_additional_css,
'id' => strval(time() + intval(rand(0, 999))), // This gives the option a unique slug
'setting_name' => '',
'bmlt_location_checked'=> self::$default_location_checked,
'bmlt_location_services' => self::$default_location_services,
'theme' => self::$default_theme,
'distance_units' => self::$default_distance_units,
'grace_period' => self::$default_grace_period,
'time_offset' => self::$default_time_offset,
'military_time' => self::$default_military_time,
'startWeekday' => self::$default_startWeekday,
'google_api_key' => 'INVALID',
'region_bias' => 'us',
'lang' => $bmlt_localization,
'default_geo_width' => self::$default_geo_width
);
return $ret;
}
/************************************************************************************//**
* \brief This gets the admin options from the database. *
* *
* \returns an associative array, with the option settings. *
****************************************************************************************/
public function getBMLTOptions( $in_option_number = null /**< It is possible to store multiple options.
If there is a number here (>=1), that will be used.
If <0, a new option will be returned (not saved).
*/
)
{
$BMLTOptions = $this->geDefaultBMLTOptions(); // Start off with the defaults.
// Make sure we aren't resetting to default.
if (($in_option_number == null) || (intval($in_option_number) > 0)) {
$option_number = null;
// If they want a certain option number, then it needs to be greater than 1, and within the number we have assigned.
if ((intval($in_option_number) > 1) && (intval($in_option_number) <= $this->get_num_options() )) {
$option_number = '_'.intval($in_option_number);
}
// These are the standard options.
$old_BMLTOptions = $this->cms_get_option(self::$adminOptionsName.$option_number);
if (is_array($old_BMLTOptions) && count($old_BMLTOptions)) {
foreach ($old_BMLTOptions as $key => $value) {
if (isset($BMLTOptions[$key])) { // We deliberately ignore old settings that no longer apply.
$BMLTOptions[$key] = $value;
}
}
}
// Strip off the trailing slash.
$BMLTOptions['root_server'] = preg_replace("#\/$#", "", trim($BMLTOptions['root_server']), 1);
}
if (isset($BMLTOptions['lang']) || !$BMLTOptions['lang']) {
global $bmlt_localization;
$BMLTOptions['lang'] = $bmlt_localization;
}
if (!$BMLTOptions['lang']) {
$BMLTOptions['lang'] = self::$default_language;
}
return $BMLTOptions;
}
/************************************************************************************//**
* \brief This gets the admin options from the database, but by using the option id. *
* *
* \returns an associative array, with the option settings. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public function getBMLTOptions_by_id(
$in_option_id, ///< The option ID. It cannot be optional.
&$out_option_number = null ///< This can be optional. A reference to an integer that will be given the option number.
) {
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
$BMLTOptions = null;
if (isset($out_option_number)) {
$out_option_number = 0;
}
if (!$in_option_id) {
$BMLTOptions = $this->getBMLTOptions(1);
if (isset($out_option_number)) {
$out_option_number = 1;
}
} else {
$count = $this->get_num_options();
// We sort through the available options, looking for the ID.
for ($i = 1; $i <= $count; $i++) {
$option_number = '';
if ($i > 1) { // We do this, for compatibility with older options.
$option_number = "_$i";
}
$name = self::$adminOptionsName.$option_number;
$temp_BMLTOptions = $this->cms_get_option($name);
if (is_array($temp_BMLTOptions) && count($temp_BMLTOptions)) {
if ($temp_BMLTOptions['id'] == $in_option_id) {
$BMLTOptions = $temp_BMLTOptions;
// If they want to know the ID, we supply it here.
if (isset($out_option_number)) {
$out_option_number = $i;
}
break;
}
} else {
echo "<!-- BMLTPlugin ERROR (getBMLTOptions_by_id)! No options found for $name! -->";
}
}
}
if (!isset($BMLTOptions['lang']) || !$BMLTOptions['lang']) {
global $bmlt_localization;
$BMLTOptions['lang'] = $bmlt_localization;
}
if (!isset($BMLTOptions['lang']) || !$BMLTOptions['lang']) {
$BMLTOptions['lang'] = self::$default_language;
}
if (!isset($BMLTOptions['default_geo_width']) || !$BMLTOptions['default_geo_width']) {
$BMLTOptions['default_geo_width'] = self::$default_geo_width;
}
return $BMLTOptions;
}
/************************************************************************************//**
* \brief This updates the database with the given options. *
* *
* \returns a boolean. true if success. *
****************************************************************************************/
public function setBMLTOptions(
$in_options, ///< An array. The options to be stored. If no number is supplied in the next parameter, the ID is used.
$in_option_number = 1 ///< It is possible to store multiple options. If there is a number here, that will be used.
) {
$ret = false;
if (($in_option_number == null) || (intval($in_option_number) < 1) || (intval($in_option_number) > ($this->get_num_options() + 1))) {
$in_option_number = 0;
$this->getBMLTOptions_by_id($in_options['id'], $in_option_number);
}
if (intval($in_option_number) > 0) {
$option_number = null;
// If they want a certain option number, then it needs to be greater than 1, and within the number we have assigned (We can also increase by 1).
if ((intval($in_option_number) > 1) && (intval($in_option_number) <= ($this->get_num_options() + 1))) {
$option_number = '_'.intval($in_option_number);
}
$in_option_number = (intval($in_option_number) > 1) ? intval($in_option_number) : 1;
$name = self::$adminOptionsName.$option_number;
// If this is a new option, then we also update the admin 2 options, incrementing the number of servers.
if (intval($in_option_number) == ($this->get_num_options() + 1)) {
$in_options['id'] = strval(time() + intval(rand(0, 999))); // This gives the option a unique slug
$admin2Options = array ('num_servers' => intval($in_option_number));
$gKey = '';
if (isset($in_options['google_api_key']) && ('' != $in_options['google_api_key']) && ('INVALID' != $in_options['google_api_key'])) {
$gKey = $in_options['google_api_key'];
}
for ($c = 0; $c < count($in_options); $c++) {
if ($num != $in_option_number) {
$option = $this->getBMLTOptions($c);
$option['google_api_key'] = $gKey;
}
}
$admin2Options = array ('num_servers' => intval($in_option_number), 'google_api_key' => $gKey );
$this->setAdmin2Options($admin2Options);
}
$this->cms_set_option($name, $in_options);
$ret = true;
} else {
echo "<!-- BMLTPlugin ERROR (setBMLTOptions)! The option number ($in_option_number) is out of range! -->";
}
return $ret;
}
/************************************************************************************//**
* \brief This gets the admin 2 options from the database. *
* *
* \returns an associative array, with the option settings. *
****************************************************************************************/
public function getAdmin2Options()
{
$bmlt2_BMLTOptions = null;
// We have a special set of options for version 2.
$old_BMLTOptions = $this->cms_get_option(self::$admin2OptionsName);
if (is_array($old_BMLTOptions) && count($old_BMLTOptions)) {
foreach ($old_BMLTOptions as $key => $value) {
$bmlt2_BMLTOptions[$key] = $value;
}
} else {
$bmlt2_BMLTOptions = array ('num_servers' => 1, 'google_api_key' => '' );
$this->setAdmin2Options($old_BMLTOptions);
}
return $bmlt2_BMLTOptions;
}
/************************************************************************************//**
* \brief This updates the database with the given options (Admin2 options). *
* *
* \returns a boolean. true if success. *
****************************************************************************************/
public function setAdmin2Options( $in_options ///< An array. The options to be stored.
)
{
$ret = false;
if ($this->cms_set_option(self::$admin2OptionsName, $in_options)) {
$ret = true;
}
return $ret;
}
/************************************************************************************//**
* \brief Gets the number of active options. *
* *
* \returns an integer. The number of options. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public function get_num_options()
{
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
$ret = 1;
$opts = $this->getAdmin2Options();
if (isset($opts['num_servers'])) {
$ret = intval($opts['num_servers']);
} else // If the options weren't already set, we create them now.
{
$opts = array ( 'num_servers' => 1, 'google_api_key' => '' );
$this->setAdmin2Options($opts);
}
return $ret;
}
/************************************************************************************//**
* \brief Makes a new set of options, set as default. *
* *
* \returns An integer. The index of the options (It will always be the number of *
* initial options, plus 1. Null if failed. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public function make_new_options()
{
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
$opt = $this->getBMLTOptions(-1);
$ret = null;
// If we successfully get the options, we save them, in order to put them in place
if (is_array($opt) && count($opt)) {
$this->setBMLTOptions($opt, $this->get_num_options() + 1);
$ret = $this->get_num_options();
} else {
echo "<!-- BMLTPlugin ERROR (make_new_options)! Failed to create new options! -->";
}
return $ret;
}
/************************************************************************************//**
* \brief Deletes the options by ID. *
* *
* \returns a boolean. true if success. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public function delete_options_by_id( $in_option_id ///< The ID of the option to delete.
)
{
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
$ret = false;
$option_num = 0;
$this->getBMLTOptions_by_id($in_option_id, $option_num); // We just want the option number.
if ($option_num > 0) { // If it's 1, we'll let the next function register the error.
$ret = $this->delete_options($option_num);
}
return $ret;
}
/************************************************************************************//**
* \brief Deletes the indexed options. *
* *
* This is a bit of a delicate operation, because we need to re-index all of the other *
* options, beyond the one being deleted. *
* *
* You cannot delete the first options (1), if they are the only ones. *
* *
* \returns a boolean. true if success. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public function delete_options( $in_option_number /**< The index of the option to delete.
It can be 1 -> the number of available options.
For safety's sake, this cannot be optional.
We cannot delete the first (primary) option if there are no others.
*/
)
{
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
$first_num = intval($in_option_number);
$ret = false;
if ($first_num) {
$last_num = $this->get_num_options();
if ((($first_num > 1) && ($first_num <= $last_num )) || (($first_num == 1) && ($last_num > 1))) {
/*
OK. At this point, we know which option we'll be deleting. The way we "delete"
the option is to cascade all the ones after it down, and then we delete the last one.
If this is the last one, then there's no need for a cascade, and we simply delete it.
*/
for ($i = $first_num; $i < $last_num; $i++) {
$opt = $this->getBMLTOptions($i + 1);
$this->setBMLTOptions($opt, $i);
}
$option_number = "_$last_num";
// Delete the selected option
$option_name = self::$adminOptionsName.$option_number;
$this->cms_delete_option($option_name);
$admin2Options = $this->getAdmin2Options();
// This actually decrements the number of available options.
$admin2Options['num_servers'] = $last_num - 1;
$this->setAdmin2Options($admin2Options);
$ret = true;
} else {
if ($first_num > 1) {
echo "<!-- BMLTPlugin ERROR (delete_options)! Option request number out of range! It must be between 1 and $last_num -->";
} elseif ($first_num == 1) {
echo "<!-- BMLTPlugin ERROR (delete_options)! You can't delete the last option! -->";
} else {
echo "<!-- BMLTPlugin ERROR (delete_options)! -->";
}
}
} else {
echo "<!-- BMLTPlugin ERROR (delete_options)! Option request number ($first_num) out of range! -->";
}
return $ret;
}
/************************************************************************************//**
* ADMIN PAGE DISPLAY AND PROCESSING FUNCTIONS *
****************************************************************************************/
/************************************************************************************//**
* \brief This does any admin actions necessary. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public function process_admin_page( &$out_option_number ///< If an option number needs to be selected, it is set here.
)
{
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
$out_option_number = 1;
global $bmlt_localization;
$this->adapt_to_lang($bmlt_localization);
$timing = self::$local_options_success_time; // Success is a shorter fade, but failure is longer.
$ret = '<div id="BMLTPlugin_Message_bar_div" class="BMLTPlugin_Message_bar_div">';
if (isset($this->my_http_vars['BMLTPlugin_create_option'])) {
$out_option_number = $this->make_new_options();
if ($out_option_number) {
$new_options = $this->getBMLTOptions($out_option_number);
$def_options = $this->getBMLTOptions(1);
$new_options = $def_options;
unset($new_options['setting_name']);
unset($new_options['id']);
unset($new_options['theme']);
$this->setBMLTOptions($new_options, $out_option_number);
$ret .= '<h2 id="BMLTPlugin_Fader" class="BMLTPlugin_Message_bar_success">';
$ret .= $this->process_text($this->my_current_language->local_options_create_success);
$ret .= '</h2>';
} else {
$timing = self::$local_options_failure_time;
$ret .= '<h2 id="BMLTPlugin_Fader" class="BMLTPlugin_Message_bar_fail">';
$ret .= $this->process_text($this->my_current_language->local_options_create_failure);
$ret .= '</h2>';
}
} elseif (isset($this->my_http_vars['BMLTPlugin_delete_option'])) {
$option_index = intval($this->my_http_vars['BMLTPlugin_delete_option']);
if ($this->delete_options($option_index)) {
$ret .= '<h2 id="BMLTPlugin_Fader" class="BMLTPlugin_Message_bar_success">';
$ret .= $this->process_text($this->my_current_language->local_options_delete_success);
$ret .= '</h2>';
} else {
$timing = self::$local_options_failure_time;
$ret .= '<h2 id="BMLTPlugin_Fader" class="BMLTPlugin_Message_bar_fail">';
$ret .= $this->process_text($this->my_current_language->local_options_delete_failure);
$ret .= '</h2>';
}
} else {
$ret .= '<h2 id="BMLTPlugin_Fader" class="BMLTPlugin_Message_bar_fail"> </h2>';
}
$ret .= '<script type="text/javascript">g_BMLTPlugin_TimeToFade = '.$timing.';BMLTPlugin_StartFader()</script>';
$ret .= '</div>';
return $ret;
}
/************************************************************************************//**
* \brief Returns the HTML for the admin page. *
* *
* \returns a string. The XHTML for the page. *
****************************************************************************************/
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
public function return_admin_page()
{
// phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
$selected_option = 1;
$process_html = $this->process_admin_page($selected_option);
$options_coords = array();
$html = '<div class="BMLTPlugin_option_page" id="BMLTPlugin_option_page_div">';
$html .= '<noscript class="no_js">'.$this->process_text($this->my_current_language->local_noscript).'</noscript>';
$html .= '<div id="BMLTPlugin_options_container" style="display:none">'; // This is displayed using JavaScript.
$html .= '<h1 class="BMLTPlugin_Admin_h1">'.$this->process_text($this->my_current_language->local_options_title).'</h1>';
$html .= $process_html;
$html .= '<form class="BMLTPlugin_sheet_form" id="BMLTPlugin_sheet_form" action ="'.$this->get_admin_form_uri().'" method="get" onsubmit="function(){return false}">';
$html .= '<fieldset class="BMLTPlugin_option_fieldset" id="BMLTPlugin_option_fieldset">';
$html .= '<legend id="BMLTPlugin_legend" class="BMLTPlugin_legend">';
$count = $this->get_num_options();
if ($count > 1) {
$html .= '<select id="BMLTPlugin_legend_select" onchange="BMLTPlugin_SelectOptionSheet(this.value,'.$count.')">';
for ($i = 1; $i <= $count; $i++) {
$options = $this->getBMLTOptions($i);
if (is_array($options) && count($options) && isset($options['id'])) {
$options_coords[$i] = array ( 'lat' => $options['map_center_latitude'], 'lng' => $options['map_center_longitude'], 'zoom' => $options['map_zoom'] );
$html .= '<option id="BMLTPlugin_option_sel_'.$i.'" value="'.$i.'"';
if ($i == $selected_option) {
$html .= ' selected="selected"';
}
$html .= '>';
if (isset($options['setting_name']) && $options['setting_name']) {
$html .= htmlspecialchars($options['setting_name']);
} else {
$html .= $this->process_text($this->my_current_language->local_options_prefix).$i;
}
$html .= '</option>';
} else {
echo "<!-- BMLTPlugin ERROR (admin_page)! Options not found for $i! -->";
}
}
$html .= '</select>';
} elseif ($count == 1) {
$options = $this->getBMLTOptions(1);
$options_coords[1] = array ( 'lat' => $options['map_center_latitude'], 'lng' => $options['map_center_longitude'], 'zoom' => $options['map_zoom'] );
if (isset($options['setting_name']) && $options['setting_name']) {
$html .= htmlspecialchars($options['setting_name']);
} else {
$html .= $this->process_text($this->my_current_language->local_options_prefix).'1';
}
} else {
echo "<!-- BMLTPlugin ERROR (admin_page)! No options! -->";
}
$html .= '</legend>';
for ($i = 1; $i <= $count; $i++) {
$html .= $this->display_options_sheet($i, (($i == $selected_option) ? 'block' : 'none'));
}
$html .= '</fieldset>';
$html .= '</form>';
$html .= '<div class="BMLTPlugin_toolbar_line_bottom">';
$html .= '<form action ="'.$this->get_admin_form_uri().'" method="post">';
$html .= '<div id="BMLTPlugin_bottom_button_div" class="BMLTPlugin_bottom_button_div">';
if ($count > 1) {
$html .= '<div class="BMLTPlugin_toolbar_button_line_left">';
$html .= '<script type="text/javascript">';
$html .= "var c_g_delete_confirm_message='".$this->process_text($this->my_current_language->local_options_delete_option_confirm).(defined('_DEBUG_MODE_') ? "';\n" : "';");
$html .= '</script>';
$html .= '<input type="button" id="BMLTPlugin_toolbar_button_del" class="BMLTPlugin_delete_button" value="'.$this->process_text($this->my_current_language->local_options_delete_option).'" onclick="BMLTPlugin_DeleteOptionSheet()" />';
$html .= '</div>';
}
$html .= '<input type="submit" id="BMLTPlugin_toolbar_button_new" class="BMLTPlugin_create_button" name="BMLTPlugin_create_option" value="'.$this->process_text($this->my_current_language->local_options_add_new).'" />';
$html .= '<div class="BMLTPlugin_toolbar_button_line_right">';
$html .= '<input id="BMLTPlugin_toolbar_button_save" type="button" value="'.$this->process_text($this->my_current_language->local_options_save).'" onclick="BMLTPlugin_SaveOptions()" />';
$html .= '</div>';
$html .= '</div>';
$html .= '</form>';
$html .= '</div>';
$html .= '<div class="BMLTPlugin_toolbar_line_map">';
$html .= '<h2 class="BMLTPlugin_map_label_h2">'.$this->process_text($this->my_current_language->local_options_map_label).'</h2>';
$html .= '<div class="BMLTPlugin_Map_Div" id="BMLTPlugin_Map_Div"></div>';
$html .= '<script type="text/javascript">' . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "BMLTPlugin_DirtifyOptionSheet(true);" . (defined('_DEBUG_MODE_') ? "\n" : ''); // This sets up the "Save Changes" button as disabled.
// This is a trick I use to hide irrelevant content from non-JS browsers. The element is drawn, hidden, then uses JS to show. No JS, no element.
$html .= "document.getElementById('BMLTPlugin_options_container').style.display='block';" . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "var c_g_BMLTPlugin_no_name = '".$this->process_text(str_replace("'", "\\'", $this->my_current_language->local_options_no_name_string))."';" . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "var c_g_BMLTPlugin_no_root = '".$this->process_text(str_replace("'", "\\'", $this->my_current_language->local_options_no_root_server_string))."';" . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "var c_g_BMLTPlugin_root_canal = '".$this->my_current_language->local_options_url_bad.(defined('_DEBUG_MODE_') ? "';\n" : "';");
$html .= "var c_g_BMLTPlugin_success_message = '".$this->process_text(str_replace("'", "\\'", $this->my_current_language->local_options_save_success))."';" . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "var c_g_BMLTPlugin_failure_message = '".$this->process_text(str_replace("'", "\\'", $this->my_current_language->local_options_save_failure))."';" . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "var c_g_BMLTPlugin_success_time = ".intval(self::$local_options_success_time).";" . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "var c_g_BMLTPlugin_failure_time = ".intval(self::$local_options_failure_time).";" . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "var c_g_BMLTPlugin_unsaved_prompt = '".$this->process_text(str_replace("'", "\\'", $this->my_current_language->local_options_unsaved_message))."';" . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "var c_g_BMLTPlugin_test_server_success = '".$this->process_text(str_replace("'", "\\'", $this->my_current_language->local_options_test_server_success))."';" . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "var c_g_BMLTPlugin_test_server_failure = '".$this->process_text(str_replace("'", "\\'", $this->my_current_language->local_options_test_server_failure))."';" . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "var c_g_BMLTPlugin_coords = new Array();" . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "var g_BMLTPlugin_TimeToFade = ".intval(self::$local_options_success_time).";" . (defined('_DEBUG_MODE_') ? "\n" : '');
$html .= "var g_BMLTPlugin_no_gkey_string = '".$this->process_text(str_replace("'", "\\'", $this->my_current_language->local_options_no_gkey_string))."';" . (defined('_DEBUG_MODE_') ? "\n" : '');