The Events Calendar - Version 4.2.7

Version Description

Download this release

Release Info

Developer barry.hughes
Plugin Icon The Events Calendar
Version 4.2.7
Comparing to
See all releases

Code changes from version 4.2.6 to 4.2.7

Files changed (85) hide show
  1. common/lang/tribe-common.pot +1897 -1893
  2. common/src/Tribe/Abstract_Deactivation.php +71 -71
  3. common/src/Tribe/Admin/Help_Page.php +861 -861
  4. common/src/Tribe/Admin/Helpers.php +163 -163
  5. common/src/Tribe/Admin/Live_Date_Preview.php +58 -58
  6. common/src/Tribe/Admin/Notice/Archive_Slug_Conflict.php +101 -101
  7. common/src/Tribe/Admin/Notice/Plugin_Upgrade_Notice.php +238 -238
  8. common/src/Tribe/App_Shop.php +182 -182
  9. common/src/Tribe/Asset/Factory.php +57 -57
  10. common/src/Tribe/Autoloader.php +246 -246
  11. common/src/Tribe/Cache.php +126 -126
  12. common/src/Tribe/Cache_Listener.php +96 -96
  13. common/src/Tribe/Changelog_Reader.php +53 -53
  14. common/src/Tribe/Credits.php +102 -102
  15. common/src/Tribe/Date_Utils.php +849 -849
  16. common/src/Tribe/Debug.php +59 -59
  17. common/src/Tribe/Dependency.php +206 -0
  18. common/src/Tribe/Exception.php +89 -89
  19. common/src/Tribe/Field.php +616 -616
  20. common/src/Tribe/JSON_LD/Abstract.php +143 -143
  21. common/src/Tribe/Log.php +353 -353
  22. common/src/Tribe/Log/Admin.php +265 -265
  23. common/src/Tribe/Log/File_Logger.php +264 -264
  24. common/src/Tribe/Log/Logger.php +87 -87
  25. common/src/Tribe/Log/Null_Logger.php +105 -105
  26. common/src/Tribe/Main.php +339 -339
  27. common/src/Tribe/Notices.php +76 -76
  28. common/src/Tribe/PUE/Checker.php +884 -884
  29. common/src/Tribe/PUE/Plugin_Info.php +128 -128
  30. common/src/Tribe/PUE/Utility.php +92 -92
  31. common/src/Tribe/Plugin_Download_Notice.php +78 -0
  32. common/src/Tribe/Plugins.php +128 -0
  33. common/src/Tribe/Post_Transient.php +209 -209
  34. common/src/Tribe/Settings.php +641 -641
  35. common/src/Tribe/Settings_Manager.php +349 -349
  36. common/src/Tribe/Settings_Tab.php +227 -227
  37. common/src/Tribe/Support.php +291 -291
  38. common/src/Tribe/Support/Obfuscator.php +67 -67
  39. common/src/Tribe/Support/Template_Checker.php +275 -275
  40. common/src/Tribe/Support/Template_Checker_Report.php +118 -118
  41. common/src/Tribe/Template_Factory.php +188 -188
  42. common/src/Tribe/Template_Part_Cache.php +123 -123
  43. common/src/Tribe/Templates.php +79 -79
  44. common/src/Tribe/Timezones.php +366 -366
  45. common/src/Tribe/Utils/Coordinates_Provider.php +133 -133
  46. common/src/Tribe/Utils/Post_Root_Pool.php +184 -184
  47. common/src/Tribe/Validate.php +500 -500
  48. common/src/Tribe/View_Helpers.php +617 -617
  49. common/src/admin-views/app-shop.php +42 -42
  50. common/src/admin-views/event-log.php +103 -103
  51. common/src/admin-views/tribe-options-display.php +52 -52
  52. common/src/admin-views/tribe-options-general.php +80 -80
  53. common/src/admin-views/tribe-options-help.php +72 -72
  54. common/src/admin-views/tribe-options-licenses.php +73 -73
  55. common/src/admin-views/tribe-options-network.php +35 -35
  56. common/src/deprecated/Tribe__Events__Abstract_Deactivation.php +4 -4
  57. common/src/deprecated/Tribe__Events__Admin__Helpers.php +4 -4
  58. common/src/deprecated/Tribe__Events__App_Shop.php +4 -4
  59. common/src/deprecated/Tribe__Events__Autoloader.php +4 -4
  60. common/src/deprecated/Tribe__Events__Cache.php +4 -4
  61. common/src/deprecated/Tribe__Events__Cache_Listener.php +4 -4
  62. common/src/deprecated/Tribe__Events__Changelog_Reader.php +4 -4
  63. common/src/deprecated/Tribe__Events__Credits.php +4 -4
  64. common/src/deprecated/Tribe__Events__Date_Utils.php +4 -4
  65. common/src/deprecated/Tribe__Events__Field.php +4 -4
  66. common/src/deprecated/Tribe__Events__Settings.php +4 -4
  67. common/src/deprecated/Tribe__Events__Settings_Tab.php +4 -4
  68. common/src/deprecated/Tribe__Events__Support.php +4 -4
  69. common/src/deprecated/Tribe__Events__Template_Part_Cache.php +4 -4
  70. common/src/deprecated/Tribe__Events__Validate.php +4 -4
  71. common/src/deprecated/Tribe__Events__View_Helpers.php +4 -4
  72. common/src/functions/template-tags/date.php +357 -357
  73. common/src/functions/template-tags/general.php +456 -456
  74. common/src/functions/utils.php +59 -27
  75. common/src/resources/css/app-shop.css +66 -66
  76. common/src/resources/css/tribe-common-admin.css +895 -895
  77. common/src/resources/css/tribe-common-admin.min.css +1 -1
  78. common/src/resources/js/admin-date-preview.js +33 -33
  79. common/src/resources/js/admin-log-controls.js +170 -170
  80. common/src/resources/js/app-shop.js +9 -9
  81. common/src/resources/js/inline-bumpdown.js +103 -103
  82. common/src/resources/js/jquery.ba-dotimeout.js +285 -285
  83. common/src/resources/js/notice-dismiss.js +26 -26
  84. common/src/resources/postcss/app-shop.pcss +58 -58
  85. common/src/resources/postcss/tribe-common-admin.pcss +358 -991
common/lang/tribe-common.pot CHANGED
@@ -1,1893 +1,1897 @@
1
- # Copyright (C) 2016 Modern Tribe
2
- # This file is distributed under the same license as the Tribe Common package.
3
- msgid ""
4
- msgstr ""
5
- "Project-Id-Version: Tribe Common 4.2.6\n"
6
- "Report-Msgid-Bugs-To: http://m.tri.be/191x\n"
7
- "POT-Creation-Date: 2016-08-30 19:51:21+00:00\n"
8
- "MIME-Version: 1.0\n"
9
- "Content-Type: text/plain; charset=UTF-8\n"
10
- "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2016-08-30 19:51\n"
12
- "Last-Translator: \n"
13
- "Language-Team: \n"
14
-
15
- #: src/Tribe/Admin/Help_Page.php:48
16
- msgid "The Events Calendar"
17
- msgstr ""
18
-
19
- #: src/Tribe/Admin/Help_Page.php:52
20
- msgid "The Events Calendar is a carefully crafted, extensible plugin that lets you easily share your events."
21
- msgstr ""
22
-
23
- #: src/Tribe/Admin/Help_Page.php:64
24
- msgid "Event Tickets"
25
- msgstr ""
26
-
27
- #: src/Tribe/Admin/Help_Page.php:68
28
- msgid "Events Tickets is a carefully crafted, extensible plugin that lets you easily sell tickets for your events."
29
- msgstr ""
30
-
31
- #: src/Tribe/Admin/Help_Page.php:80
32
- msgid "Advanced Post Manager"
33
- msgstr ""
34
-
35
- #: src/Tribe/Admin/Help_Page.php:84
36
- msgid "Turbo charge your posts admin for any custom post type with sortable filters and columns, and auto-registration of metaboxes."
37
- msgstr ""
38
-
39
- #: src/Tribe/Admin/Help_Page.php:159
40
- msgid " and "
41
- msgstr ""
42
-
43
- #: src/Tribe/Admin/Help_Page.php:183 src/Tribe/App_Shop.php:109
44
- msgid "Events Calendar PRO"
45
- msgstr ""
46
-
47
- #: src/Tribe/Admin/Help_Page.php:192 src/Tribe/App_Shop.php:142
48
- msgid "Eventbrite Tickets"
49
- msgstr ""
50
-
51
- #: src/Tribe/Admin/Help_Page.php:200 src/Tribe/App_Shop.php:119
52
- msgid "Community Events"
53
- msgstr ""
54
-
55
- #: src/Tribe/Admin/Help_Page.php:208 src/Tribe/App_Shop.php:152
56
- msgid "Facebook Events"
57
- msgstr ""
58
-
59
- #: src/Tribe/Admin/Help_Page.php:216
60
- msgid "Events Filter Bar"
61
- msgstr ""
62
-
63
- #: src/Tribe/Admin/Help_Page.php:224 src/Tribe/App_Shop.php:132
64
- msgid "Event Tickets Plus"
65
- msgstr ""
66
-
67
- #: src/Tribe/Admin/Help_Page.php:233 src/Tribe/App_Shop.php:125
68
- msgid "Community Tickets"
69
- msgstr ""
70
-
71
- #: src/Tribe/Admin/Help_Page.php:394
72
- msgctxt "not available"
73
- msgid "n/a"
74
- msgstr ""
75
-
76
- #: src/Tribe/Admin/Help_Page.php:402
77
- msgid "You need to upgrade!"
78
- msgstr ""
79
-
80
- #: src/Tribe/Admin/Help_Page.php:402 src/Tribe/Admin/Help_Page.php:777
81
- msgid "You are up to date!"
82
- msgstr ""
83
-
84
- #: src/Tribe/Admin/Help_Page.php:767
85
- msgid "Activate %s"
86
- msgstr ""
87
-
88
- #: src/Tribe/Admin/Help_Page.php:767
89
- msgid "Activate Plugin"
90
- msgstr ""
91
-
92
- #: src/Tribe/Admin/Help_Page.php:775
93
- msgid "Upgrade Plugin"
94
- msgstr ""
95
-
96
- #: src/Tribe/Admin/Help_Page.php:791
97
- msgid "Install %s"
98
- msgstr ""
99
-
100
- #: src/Tribe/Admin/Help_Page.php:791
101
- msgid "Install Plugin"
102
- msgstr ""
103
-
104
- #: src/Tribe/Admin/Help_Page.php:808
105
- msgid "Latest Version:"
106
- msgstr ""
107
-
108
- #: src/Tribe/Admin/Help_Page.php:811 src/admin-views/app-shop.php:26
109
- msgid "Requires:"
110
- msgstr ""
111
-
112
- #: src/Tribe/Admin/Help_Page.php:812
113
- msgid "WordPress "
114
- msgstr ""
115
-
116
- #: src/Tribe/Admin/Help_Page.php:814
117
- msgid "Active Users:"
118
- msgstr ""
119
-
120
- #: src/Tribe/Admin/Help_Page.php:817
121
- msgid "Rating:"
122
- msgstr ""
123
-
124
- #: src/Tribe/Admin/Help_Page.php:836
125
- msgid "Premium Add-Ons"
126
- msgstr ""
127
-
128
- #: src/Tribe/Admin/Help_Page.php:842
129
- msgid "Plugin Active"
130
- msgstr ""
131
-
132
- #: src/Tribe/Admin/Help_Page.php:844
133
- msgid "Plugin Inactive"
134
- msgstr ""
135
-
136
- #: src/Tribe/Admin/Help_Page.php:849
137
- msgid "Visit the Add-on Page"
138
- msgstr ""
139
-
140
- #: src/Tribe/Admin/Notice/Archive_Slug_Conflict.php:88
141
- msgid "<a href=\"%s\">Edit the page slug</a>"
142
- msgstr ""
143
-
144
- #: src/Tribe/Admin/Notice/Archive_Slug_Conflict.php:89
145
- msgid "Ask the site administrator to edit the page slug"
146
- msgstr ""
147
-
148
- #: src/Tribe/Admin/Notice/Archive_Slug_Conflict.php:94
149
- msgid "<a href=\"%s\">edit Events settings</a>."
150
- msgstr ""
151
-
152
- #: src/Tribe/Admin/Notice/Archive_Slug_Conflict.php:95
153
- msgid " ask the site administrator set a different Events URL slug."
154
- msgstr ""
155
-
156
- #: src/Tribe/App_Shop.php:48 src/Tribe/App_Shop.php:49
157
- #: src/Tribe/App_Shop.php:72
158
- msgid "Event Add-Ons"
159
- msgstr ""
160
-
161
- #: src/Tribe/App_Shop.php:103
162
- msgid "Filter Bar"
163
- msgstr ""
164
-
165
- #: src/Tribe/App_Shop.php:105
166
- msgid "It is awesome that your calendar is <em>THE PLACE</em> to get hooked up with prime choice ways to spend time. You have more events than Jabba the Hutt has rolls. Too bad visitors are hiring a personal assistant to go through all the choices. Ever wish you could just filter the calendar to only show events in walking distance, on a weekend, that are free? BOOM. Now you can. Introducing… the Filter Bar."
167
- msgstr ""
168
-
169
- #: src/Tribe/App_Shop.php:112
170
- msgid "The Events Calendar PRO is a paid Add-On to our open source WordPress plugin %1$sThe Events Calendar%2$s. PRO offers a whole host of calendar features including recurring events, custom event attributes, saved venues and organizers, venue pages, advanced event admin and lots more."
171
- msgstr ""
172
-
173
- #: src/Tribe/App_Shop.php:121
174
- msgid "Enable users to submit events to your calendar with Community Events. You can require user accounts or allow visitors to submit without an account. Want to make sure that nothing fishy is going on? Just turn on moderation. Decide if users can edit and manage their own events, or simply submit. Plus, no scary form setup! Just activate, configure the options & off you go."
175
- msgstr ""
176
-
177
- #: src/Tribe/App_Shop.php:127
178
- msgid "Enable Community Events organizers to offer tickets to their events. You can set flexible payment and fee options. They can even check-in attendees to their events! All of this managed from the front-end of your site without ever needing to grant access to your admin"
179
- msgstr ""
180
-
181
- #: src/Tribe/App_Shop.php:128
182
- msgctxt "Names of required plugins for Community Tickets"
183
- msgid "Event Tickets Plus and Community Events"
184
- msgstr ""
185
-
186
- #: src/Tribe/App_Shop.php:135
187
- msgid "Event Tickets Plus allows you to sell tickets to your events using WooCommerce, Shopp, WP eCommerce, or Easy Digital Downloads. Use it on your posts and pages, or add %1$sThe Events Calendar%2$s and sell tickets from your events listings."
188
- msgstr ""
189
-
190
- #: src/Tribe/App_Shop.php:145
191
- msgid "The Eventbrite Tickets add-on allows you to create & sell tickets through The Events Calendar using the power of %1$sEventbrite%2$s. Whether you’re creating your ticket on the WordPress dashboard or importing the details of an already-existing event from %1$sEventbrite.com%2$s, this add-on brings the power of the Eventbrite API to your calendar."
192
- msgstr ""
193
-
194
- #: src/Tribe/App_Shop.php:154
195
- msgid "With the Facebook Events add-on, imported events are manually or automagically created as entries in The Events Calendar. Basic event data along with venue and organizer are populated appropriately. No more entering information in two places, or having to recreate someone else's listing for a public event you want to include on your WordPress calendar."
196
- msgstr ""
197
-
198
- #: src/Tribe/App_Shop.php:158
199
- msgid "iCal Importer"
200
- msgstr ""
201
-
202
- #: src/Tribe/App_Shop.php:160
203
- msgid "The iCal Importer helps you keep your events calendar full of interesting events! You can import events from any website that publishes an iCal (aka ICS) feed and add them to your listings. The recurring import feature lets you keep your calendar brimming without manual oversight (though you can review every imported event if you like). Add filtering by keyword or geographic region and you can be sure that the kinds of events you get are the kinds you want."
204
- msgstr ""
205
-
206
- #: src/Tribe/Credits.php:31
207
- msgid "This calendar is powered by %1$s."
208
- msgstr ""
209
-
210
- #: src/Tribe/Credits.php:55
211
- msgid "Rate %1$sThe Events Calendar%2$s %3$s"
212
- msgstr ""
213
-
214
- #: src/Tribe/Credits.php:64
215
- msgid "Rate %1$sEvent Tickets%2$s %3$s"
216
- msgstr ""
217
-
218
- #: src/Tribe/Field.php:209
219
- msgid "Invalid field type specified"
220
- msgstr ""
221
-
222
- #: src/Tribe/Field.php:466
223
- msgid "No radio options specified"
224
- msgstr ""
225
-
226
- #: src/Tribe/Field.php:502
227
- msgid "No checkbox options specified"
228
- msgstr ""
229
-
230
- #: src/Tribe/Field.php:558
231
- msgid "No select options specified"
232
- msgstr ""
233
-
234
- #: src/Tribe/Log/Admin.php:132
235
- msgctxt "log selector"
236
- msgid "None currently available"
237
- msgstr ""
238
-
239
- #: src/Tribe/Log/Admin.php:147
240
- msgctxt "log engines"
241
- msgid "None currently available"
242
- msgstr ""
243
-
244
- #: src/Tribe/Log/File_Logger.php:116
245
- msgid "Default (uses temporary files)"
246
- msgstr ""
247
-
248
- #: src/Tribe/Log/Null_Logger.php:26
249
- msgid "Null logger (will log nothing)"
250
- msgstr ""
251
-
252
- #: src/Tribe/Log.php:210
253
- msgid "Cannot set %s as the current logging engine"
254
- msgstr ""
255
-
256
- #: src/Tribe/Log.php:309
257
- msgid "Disabled"
258
- msgstr ""
259
-
260
- #: src/Tribe/Log.php:310
261
- msgid "Only errors"
262
- msgstr ""
263
-
264
- #: src/Tribe/Log.php:311
265
- msgid "Warnings and errors"
266
- msgstr ""
267
-
268
- #: src/Tribe/Log.php:312
269
- msgid "Full debug (all events)"
270
- msgstr ""
271
-
272
- #: src/Tribe/PUE/Checker.php:308
273
- msgid "License Key"
274
- msgstr ""
275
-
276
- #: src/Tribe/PUE/Checker.php:309
277
- msgid "A valid license key is required for support and updates"
278
- msgstr ""
279
-
280
- #: src/Tribe/PUE/Checker.php:380
281
- msgid "License key(s) updated."
282
- msgstr ""
283
-
284
- #: src/Tribe/PUE/Checker.php:419
285
- msgid "unknown date"
286
- msgstr ""
287
-
288
- #: src/Tribe/PUE/Checker.php:422
289
- msgid "Sorry, key validation server is not available."
290
- msgstr ""
291
-
292
- #: src/Tribe/PUE/Checker.php:432
293
- msgid "Valid Key! Expires on %s"
294
- msgstr ""
295
-
296
- #: src/Tribe/PUE/Checker.php:437
297
- msgid "Thanks for setting up a valid key, it will expire on %s"
298
- msgstr ""
299
-
300
- #: src/Tribe/PUE/Checker.php:445
301
- msgid "Hmmm... something's wrong with this validator. Please contact %ssupport%s."
302
- msgstr ""
303
-
304
- #: src/Tribe/PUE/Checker.php:457
305
- msgid "Sorry, there is a problem with your license key. You'll need to %scheck your license%s to have access to updates, downloads, and support."
306
- msgstr ""
307
-
308
- #: src/Tribe/Settings.php:148 src/Tribe/Settings.php:204
309
- #: src/Tribe/Settings.php:205
310
- msgid "Events"
311
- msgstr ""
312
-
313
- #: src/Tribe/Settings.php:216 src/Tribe/Settings.php:236
314
- msgid "Events Settings"
315
- msgstr ""
316
-
317
- #: src/Tribe/Settings.php:217
318
- msgid "Settings"
319
- msgstr ""
320
-
321
- #: src/Tribe/Settings.php:301
322
- msgid "%s Settings"
323
- msgstr ""
324
-
325
- #: src/Tribe/Settings.php:315
326
- msgid "You've requested a non-existent tab."
327
- msgstr ""
328
-
329
- #: src/Tribe/Settings.php:323
330
- msgid "Save Changes"
331
- msgstr ""
332
-
333
- #: src/Tribe/Settings.php:371
334
- msgid "You don't have permission to do that."
335
- msgstr ""
336
-
337
- #: src/Tribe/Settings.php:377
338
- msgid "The request was sent insecurely."
339
- msgstr ""
340
-
341
- #: src/Tribe/Settings.php:383
342
- msgid "The request wasn't sent from this tab."
343
- msgstr ""
344
-
345
- #: src/Tribe/Settings.php:550
346
- msgid "Your form had the following errors:"
347
- msgstr ""
348
-
349
- #: src/Tribe/Settings.php:560
350
- msgid "None of your settings were saved. Please try again."
351
- msgstr ""
352
-
353
- #: src/Tribe/Settings.php:561
354
- msgid "The above setting was not saved. Other settings were successfully saved."
355
- msgid_plural "The above settings were not saved. Other settings were successfully saved."
356
- msgstr[0] ""
357
- msgstr[1] ""
358
-
359
- #: src/Tribe/Settings.php:583
360
- msgid "Settings saved."
361
- msgstr ""
362
-
363
- #: src/Tribe/Settings_Manager.php:55
364
- msgid "General"
365
- msgstr ""
366
-
367
- #: src/Tribe/Settings_Manager.php:56
368
- msgid "Display"
369
- msgstr ""
370
-
371
- #: src/Tribe/Settings_Manager.php:62 src/Tribe/Settings_Manager.php:289
372
- msgid "Help"
373
- msgstr ""
374
-
375
- #: src/Tribe/Settings_Manager.php:229
376
- msgid "Network"
377
- msgstr ""
378
-
379
- #: src/Tribe/Settings_Manager.php:263
380
- #: src/admin-views/tribe-options-licenses.php:46
381
- msgid "Licenses"
382
- msgstr ""
383
-
384
- #: src/Tribe/Settings_Tab.php:222
385
- msgid "There are no fields setup for this tab yet."
386
- msgstr ""
387
-
388
- #: src/Tribe/Support/Template_Checker_Report.php:78
389
- msgid "No notable changes detected"
390
- msgstr ""
391
-
392
- #: src/Tribe/Support/Template_Checker_Report.php:82
393
- msgid "Templates introduced or updated with this release (%s):"
394
- msgstr ""
395
-
396
- #: src/Tribe/Support/Template_Checker_Report.php:92
397
- msgid "Existing theme overrides that may need revision:"
398
- msgstr ""
399
-
400
- #: src/Tribe/Support/Template_Checker_Report.php:96
401
- msgid "version data missing from override"
402
- msgstr ""
403
-
404
- #: src/Tribe/Support/Template_Checker_Report.php:97
405
- msgid "based on %s version"
406
- msgstr ""
407
-
408
- #: src/Tribe/Support/Template_Checker_Report.php:113
409
- msgid "No notable template changes detected."
410
- msgstr ""
411
-
412
- #: src/Tribe/Support/Template_Checker_Report.php:115
413
- msgid "Information about recent template changes and potentially impacted template overrides is provided below."
414
- msgstr ""
415
-
416
- #: src/Tribe/Support.php:159
417
- msgid "English"
418
- msgstr ""
419
-
420
- #: src/Tribe/Support.php:176 src/Tribe/Support.php:177
421
- msgid "Unknown or not set"
422
- msgstr ""
423
-
424
- #: src/Tribe/Support.php:187
425
- msgid "Rewrite rules were purged on load of this help page. Chances are there is a rewrite rule flush occurring in a plugin or theme!"
426
- msgstr ""
427
-
428
- #: src/Tribe/Validate.php:76 src/Tribe/Validate.php:117
429
- msgid "Invalid or incomplete field passed"
430
- msgstr ""
431
-
432
- #: src/Tribe/Validate.php:77 src/Tribe/Validate.php:112
433
- #: src/Tribe/Validate.php:118
434
- msgid "Field ID:"
435
- msgstr ""
436
-
437
- #: src/Tribe/Validate.php:111
438
- msgid "Non-existant field validation function passed"
439
- msgstr ""
440
-
441
- #: src/Tribe/Validate.php:112
442
- msgctxt "non-existant function name passed for field validation"
443
- msgid "with function name:"
444
- msgstr ""
445
-
446
- #: src/Tribe/Validate.php:135 src/Tribe/Validate.php:151
447
- msgid "%s must contain numbers and letters only"
448
- msgstr ""
449
-
450
- #: src/Tribe/Validate.php:167
451
- msgid "%s must contain numbers, letters and dots only"
452
- msgstr ""
453
-
454
- #: src/Tribe/Validate.php:183
455
- msgid "%s must contain numbers, letters, dashes and undescores only"
456
- msgstr ""
457
-
458
- #: src/Tribe/Validate.php:197 src/Tribe/Validate.php:225
459
- msgid "%s must be a positive number."
460
- msgstr ""
461
-
462
- #: src/Tribe/Validate.php:211
463
- msgid "%s must be a positive number or percent."
464
- msgstr ""
465
-
466
- #: src/Tribe/Validate.php:240
467
- msgid "%s must be a valid slug (numbers, letters, dashes, and underscores)."
468
- msgstr ""
469
-
470
- #: src/Tribe/Validate.php:255
471
- msgid "%s must be a valid absolute URL."
472
- msgstr ""
473
-
474
- #: src/Tribe/Validate.php:271 src/Tribe/Validate.php:288
475
- #: src/Tribe/Validate.php:310
476
- msgid "%s must have a value that's part of its options."
477
- msgstr ""
478
-
479
- #: src/Tribe/Validate.php:324
480
- msgid "Comparison validation failed because no comparison value was provided, for field %s"
481
- msgstr ""
482
-
483
- #: src/Tribe/Validate.php:331
484
- msgid "%s cannot be the same as %s."
485
- msgstr ""
486
-
487
- #: src/Tribe/Validate.php:333
488
- msgid "%s cannot be a duplicate"
489
- msgstr ""
490
-
491
- #: src/Tribe/Validate.php:349
492
- msgid "%s must be a number or percentage."
493
- msgstr ""
494
-
495
- #: src/Tribe/Validate.php:403
496
- msgid "%s must be a number between 0 and 21."
497
- msgstr ""
498
-
499
- #: src/Tribe/Validate.php:419
500
- msgid "%s must consist of letters, numbers, dashes, apostrophes, and spaces only."
501
- msgstr ""
502
-
503
- #: src/Tribe/Validate.php:435
504
- msgid "%s must consist of letters, spaces, apostrophes, and dashes."
505
- msgstr ""
506
-
507
- #: src/Tribe/Validate.php:449
508
- msgid "%s must consist of 5 numbers."
509
- msgstr ""
510
-
511
- #: src/Tribe/Validate.php:463
512
- msgid "%s must be a phone number."
513
- msgstr ""
514
-
515
- #: src/Tribe/Validate.php:479
516
- msgid "Country List must be formatted as one country per line in the following format: <br>US, United States <br> UK, United Kingdom."
517
- msgstr ""
518
-
519
- #: src/Tribe/View_Helpers.php:26 src/Tribe/View_Helpers.php:45
520
- msgid "Select a Country:"
521
- msgstr ""
522
-
523
- #: src/Tribe/View_Helpers.php:46
524
- msgid "United States"
525
- msgstr ""
526
-
527
- #: src/Tribe/View_Helpers.php:47
528
- msgid "Afghanistan"
529
- msgstr ""
530
-
531
- #: src/Tribe/View_Helpers.php:48
532
- msgid "Albania"
533
- msgstr ""
534
-
535
- #: src/Tribe/View_Helpers.php:49
536
- msgid "Algeria"
537
- msgstr ""
538
-
539
- #: src/Tribe/View_Helpers.php:50
540
- msgid "American Samoa"
541
- msgstr ""
542
-
543
- #: src/Tribe/View_Helpers.php:51
544
- msgid "Andorra"
545
- msgstr ""
546
-
547
- #: src/Tribe/View_Helpers.php:52
548
- msgid "Angola"
549
- msgstr ""
550
-
551
- #: src/Tribe/View_Helpers.php:53
552
- msgid "Anguilla"
553
- msgstr ""
554
-
555
- #: src/Tribe/View_Helpers.php:54
556
- msgid "Antarctica"
557
- msgstr ""
558
-
559
- #: src/Tribe/View_Helpers.php:55
560
- msgid "Antigua And Barbuda"
561
- msgstr ""
562
-
563
- #: src/Tribe/View_Helpers.php:56
564
- msgid "Argentina"
565
- msgstr ""
566
-
567
- #: src/Tribe/View_Helpers.php:57
568
- msgid "Armenia"
569
- msgstr ""
570
-
571
- #: src/Tribe/View_Helpers.php:58
572
- msgid "Aruba"
573
- msgstr ""
574
-
575
- #: src/Tribe/View_Helpers.php:59
576
- msgid "Australia"
577
- msgstr ""
578
-
579
- #: src/Tribe/View_Helpers.php:60
580
- msgid "Austria"
581
- msgstr ""
582
-
583
- #: src/Tribe/View_Helpers.php:61
584
- msgid "Azerbaijan"
585
- msgstr ""
586
-
587
- #: src/Tribe/View_Helpers.php:62
588
- msgid "Bahamas"
589
- msgstr ""
590
-
591
- #: src/Tribe/View_Helpers.php:63
592
- msgid "Bahrain"
593
- msgstr ""
594
-
595
- #: src/Tribe/View_Helpers.php:64
596
- msgid "Bangladesh"
597
- msgstr ""
598
-
599
- #: src/Tribe/View_Helpers.php:65
600
- msgid "Barbados"
601
- msgstr ""
602
-
603
- #: src/Tribe/View_Helpers.php:66
604
- msgid "Belarus"
605
- msgstr ""
606
-
607
- #: src/Tribe/View_Helpers.php:67
608
- msgid "Belgium"
609
- msgstr ""
610
-
611
- #: src/Tribe/View_Helpers.php:68
612
- msgid "Belize"
613
- msgstr ""
614
-
615
- #: src/Tribe/View_Helpers.php:69
616
- msgid "Benin"
617
- msgstr ""
618
-
619
- #: src/Tribe/View_Helpers.php:70
620
- msgid "Bermuda"
621
- msgstr ""
622
-
623
- #: src/Tribe/View_Helpers.php:71
624
- msgid "Bhutan"
625
- msgstr ""
626
-
627
- #: src/Tribe/View_Helpers.php:72
628
- msgid "Bolivia"
629
- msgstr ""
630
-
631
- #: src/Tribe/View_Helpers.php:73
632
- msgid "Bosnia And Herzegowina"
633
- msgstr ""
634
-
635
- #: src/Tribe/View_Helpers.php:74
636
- msgid "Botswana"
637
- msgstr ""
638
-
639
- #: src/Tribe/View_Helpers.php:75
640
- msgid "Bouvet Island"
641
- msgstr ""
642
-
643
- #: src/Tribe/View_Helpers.php:76
644
- msgid "Brazil"
645
- msgstr ""
646
-
647
- #: src/Tribe/View_Helpers.php:77
648
- msgid "British Indian Ocean Territory"
649
- msgstr ""
650
-
651
- #: src/Tribe/View_Helpers.php:78
652
- msgid "Brunei Darussalam"
653
- msgstr ""
654
-
655
- #: src/Tribe/View_Helpers.php:79
656
- msgid "Bulgaria"
657
- msgstr ""
658
-
659
- #: src/Tribe/View_Helpers.php:80
660
- msgid "Burkina Faso"
661
- msgstr ""
662
-
663
- #: src/Tribe/View_Helpers.php:81
664
- msgid "Burundi"
665
- msgstr ""
666
-
667
- #: src/Tribe/View_Helpers.php:82
668
- msgid "Cambodia"
669
- msgstr ""
670
-
671
- #: src/Tribe/View_Helpers.php:83
672
- msgid "Cameroon"
673
- msgstr ""
674
-
675
- #: src/Tribe/View_Helpers.php:84
676
- msgid "Canada"
677
- msgstr ""
678
-
679
- #: src/Tribe/View_Helpers.php:85
680
- msgid "Cape Verde"
681
- msgstr ""
682
-
683
- #: src/Tribe/View_Helpers.php:86
684
- msgid "Cayman Islands"
685
- msgstr ""
686
-
687
- #: src/Tribe/View_Helpers.php:87
688
- msgid "Central African Republic"
689
- msgstr ""
690
-
691
- #: src/Tribe/View_Helpers.php:88
692
- msgid "Chad"
693
- msgstr ""
694
-
695
- #: src/Tribe/View_Helpers.php:89
696
- msgid "Chile"
697
- msgstr ""
698
-
699
- #: src/Tribe/View_Helpers.php:90
700
- msgid "China"
701
- msgstr ""
702
-
703
- #: src/Tribe/View_Helpers.php:91
704
- msgid "Christmas Island"
705
- msgstr ""
706
-
707
- #: src/Tribe/View_Helpers.php:92
708
- msgid "Cocos (Keeling) Islands"
709
- msgstr ""
710
-
711
- #: src/Tribe/View_Helpers.php:93
712
- msgid "Colombia"
713
- msgstr ""
714
-
715
- #: src/Tribe/View_Helpers.php:94
716
- msgid "Comoros"
717
- msgstr ""
718
-
719
- #: src/Tribe/View_Helpers.php:95
720
- msgid "Congo"
721
- msgstr ""
722
-
723
- #: src/Tribe/View_Helpers.php:96
724
- msgid "Congo, The Democratic Republic Of The"
725
- msgstr ""
726
-
727
- #: src/Tribe/View_Helpers.php:97
728
- msgid "Cook Islands"
729
- msgstr ""
730
-
731
- #: src/Tribe/View_Helpers.php:98
732
- msgid "Costa Rica"
733
- msgstr ""
734
-
735
- #: src/Tribe/View_Helpers.php:99
736
- msgid "Cote D'Ivoire"
737
- msgstr ""
738
-
739
- #: src/Tribe/View_Helpers.php:100
740
- msgid "Croatia (Local Name: Hrvatska)"
741
- msgstr ""
742
-
743
- #: src/Tribe/View_Helpers.php:101
744
- msgid "Cuba"
745
- msgstr ""
746
-
747
- #: src/Tribe/View_Helpers.php:102
748
- msgid "Cyprus"
749
- msgstr ""
750
-
751
- #: src/Tribe/View_Helpers.php:103
752
- msgid "Czech Republic"
753
- msgstr ""
754
-
755
- #: src/Tribe/View_Helpers.php:104
756
- msgid "Denmark"
757
- msgstr ""
758
-
759
- #: src/Tribe/View_Helpers.php:105
760
- msgid "Djibouti"
761
- msgstr ""
762
-
763
- #: src/Tribe/View_Helpers.php:106
764
- msgid "Dominica"
765
- msgstr ""
766
-
767
- #: src/Tribe/View_Helpers.php:107
768
- msgid "Dominican Republic"
769
- msgstr ""
770
-
771
- #: src/Tribe/View_Helpers.php:108
772
- msgid "East Timor"
773
- msgstr ""
774
-
775
- #: src/Tribe/View_Helpers.php:109
776
- msgid "Ecuador"
777
- msgstr ""
778
-
779
- #: src/Tribe/View_Helpers.php:110
780
- msgid "Egypt"
781
- msgstr ""
782
-
783
- #: src/Tribe/View_Helpers.php:111
784
- msgid "El Salvador"
785
- msgstr ""
786
-
787
- #: src/Tribe/View_Helpers.php:112
788
- msgid "Equatorial Guinea"
789
- msgstr ""
790
-
791
- #: src/Tribe/View_Helpers.php:113
792
- msgid "Eritrea"
793
- msgstr ""
794
-
795
- #: src/Tribe/View_Helpers.php:114
796
- msgid "Estonia"
797
- msgstr ""
798
-
799
- #: src/Tribe/View_Helpers.php:115
800
- msgid "Ethiopia"
801
- msgstr ""
802
-
803
- #: src/Tribe/View_Helpers.php:116
804
- msgid "Falkland Islands (Malvinas)"
805
- msgstr ""
806
-
807
- #: src/Tribe/View_Helpers.php:117
808
- msgid "Faroe Islands"
809
- msgstr ""
810
-
811
- #: src/Tribe/View_Helpers.php:118
812
- msgid "Fiji"
813
- msgstr ""
814
-
815
- #: src/Tribe/View_Helpers.php:119
816
- msgid "Finland"
817
- msgstr ""
818
-
819
- #: src/Tribe/View_Helpers.php:120
820
- msgid "France"
821
- msgstr ""
822
-
823
- #: src/Tribe/View_Helpers.php:121
824
- msgid "France, Metropolitan"
825
- msgstr ""
826
-
827
- #: src/Tribe/View_Helpers.php:122
828
- msgid "French Guiana"
829
- msgstr ""
830
-
831
- #: src/Tribe/View_Helpers.php:123
832
- msgid "French Polynesia"
833
- msgstr ""
834
-
835
- #: src/Tribe/View_Helpers.php:124
836
- msgid "French Southern Territories"
837
- msgstr ""
838
-
839
- #: src/Tribe/View_Helpers.php:125
840
- msgid "Gabon"
841
- msgstr ""
842
-
843
- #: src/Tribe/View_Helpers.php:126
844
- msgid "Gambia"
845
- msgstr ""
846
-
847
- #: src/Tribe/View_Helpers.php:127 src/Tribe/View_Helpers.php:326
848
- msgid "Georgia"
849
- msgstr ""
850
-
851
- #: src/Tribe/View_Helpers.php:128
852
- msgid "Germany"
853
- msgstr ""
854
-
855
- #: src/Tribe/View_Helpers.php:129
856
- msgid "Ghana"
857
- msgstr ""
858
-
859
- #: src/Tribe/View_Helpers.php:130
860
- msgid "Gibraltar"
861
- msgstr ""
862
-
863
- #: src/Tribe/View_Helpers.php:131
864
- msgid "Greece"
865
- msgstr ""
866
-
867
- #: src/Tribe/View_Helpers.php:132
868
- msgid "Greenland"
869
- msgstr ""
870
-
871
- #: src/Tribe/View_Helpers.php:133
872
- msgid "Grenada"
873
- msgstr ""
874
-
875
- #: src/Tribe/View_Helpers.php:134
876
- msgid "Guadeloupe"
877
- msgstr ""
878
-
879
- #: src/Tribe/View_Helpers.php:135
880
- msgid "Guam"
881
- msgstr ""
882
-
883
- #: src/Tribe/View_Helpers.php:136
884
- msgid "Guatemala"
885
- msgstr ""
886
-
887
- #: src/Tribe/View_Helpers.php:137
888
- msgid "Guinea"
889
- msgstr ""
890
-
891
- #: src/Tribe/View_Helpers.php:138
892
- msgid "Guinea-Bissau"
893
- msgstr ""
894
-
895
- #: src/Tribe/View_Helpers.php:139
896
- msgid "Guyana"
897
- msgstr ""
898
-
899
- #: src/Tribe/View_Helpers.php:140
900
- msgid "Haiti"
901
- msgstr ""
902
-
903
- #: src/Tribe/View_Helpers.php:141
904
- msgid "Heard And Mc Donald Islands"
905
- msgstr ""
906
-
907
- #: src/Tribe/View_Helpers.php:142
908
- msgid "Holy See (Vatican City State)"
909
- msgstr ""
910
-
911
- #: src/Tribe/View_Helpers.php:143
912
- msgid "Honduras"
913
- msgstr ""
914
-
915
- #: src/Tribe/View_Helpers.php:144
916
- msgid "Hong Kong"
917
- msgstr ""
918
-
919
- #: src/Tribe/View_Helpers.php:145
920
- msgid "Hungary"
921
- msgstr ""
922
-
923
- #: src/Tribe/View_Helpers.php:146
924
- msgid "Iceland"
925
- msgstr ""
926
-
927
- #: src/Tribe/View_Helpers.php:147
928
- msgid "India"
929
- msgstr ""
930
-
931
- #: src/Tribe/View_Helpers.php:148
932
- msgid "Indonesia"
933
- msgstr ""
934
-
935
- #: src/Tribe/View_Helpers.php:149
936
- msgid "Iran (Islamic Republic Of)"
937
- msgstr ""
938
-
939
- #: src/Tribe/View_Helpers.php:150
940
- msgid "Iraq"
941
- msgstr ""
942
-
943
- #: src/Tribe/View_Helpers.php:151
944
- msgid "Ireland"
945
- msgstr ""
946
-
947
- #: src/Tribe/View_Helpers.php:152
948
- msgid "Israel"
949
- msgstr ""
950
-
951
- #: src/Tribe/View_Helpers.php:153
952
- msgid "Italy"
953
- msgstr ""
954
-
955
- #: src/Tribe/View_Helpers.php:154
956
- msgid "Jamaica"
957
- msgstr ""
958
-
959
- #: src/Tribe/View_Helpers.php:155
960
- msgid "Japan"
961
- msgstr ""
962
-
963
- #: src/Tribe/View_Helpers.php:156
964
- msgid "Jordan"
965
- msgstr ""
966
-
967
- #: src/Tribe/View_Helpers.php:157
968
- msgid "Kazakhstan"
969
- msgstr ""
970
-
971
- #: src/Tribe/View_Helpers.php:158
972
- msgid "Kenya"
973
- msgstr ""
974
-
975
- #: src/Tribe/View_Helpers.php:159
976
- msgid "Kiribati"
977
- msgstr ""
978
-
979
- #: src/Tribe/View_Helpers.php:160
980
- msgid "Korea, Democratic People's Republic Of"
981
- msgstr ""
982
-
983
- #: src/Tribe/View_Helpers.php:161
984
- msgid "Korea, Republic Of"
985
- msgstr ""
986
-
987
- #: src/Tribe/View_Helpers.php:162
988
- msgid "Kuwait"
989
- msgstr ""
990
-
991
- #: src/Tribe/View_Helpers.php:163
992
- msgid "Kyrgyzstan"
993
- msgstr ""
994
-
995
- #: src/Tribe/View_Helpers.php:164
996
- msgid "Lao People's Democratic Republic"
997
- msgstr ""
998
-
999
- #: src/Tribe/View_Helpers.php:165
1000
- msgid "Latvia"
1001
- msgstr ""
1002
-
1003
- #: src/Tribe/View_Helpers.php:166
1004
- msgid "Lebanon"
1005
- msgstr ""
1006
-
1007
- #: src/Tribe/View_Helpers.php:167
1008
- msgid "Lesotho"
1009
- msgstr ""
1010
-
1011
- #: src/Tribe/View_Helpers.php:168
1012
- msgid "Liberia"
1013
- msgstr ""
1014
-
1015
- #: src/Tribe/View_Helpers.php:169
1016
- msgid "Libya"
1017
- msgstr ""
1018
-
1019
- #: src/Tribe/View_Helpers.php:170
1020
- msgid "Liechtenstein"
1021
- msgstr ""
1022
-
1023
- #: src/Tribe/View_Helpers.php:171
1024
- msgid "Lithuania"
1025
- msgstr ""
1026
-
1027
- #: src/Tribe/View_Helpers.php:172
1028
- msgid "Luxembourg"
1029
- msgstr ""
1030
-
1031
- #: src/Tribe/View_Helpers.php:173
1032
- msgid "Macau"
1033
- msgstr ""
1034
-
1035
- #: src/Tribe/View_Helpers.php:174
1036
- msgid "Macedonia"
1037
- msgstr ""
1038
-
1039
- #: src/Tribe/View_Helpers.php:175
1040
- msgid "Madagascar"
1041
- msgstr ""
1042
-
1043
- #: src/Tribe/View_Helpers.php:176
1044
- msgid "Malawi"
1045
- msgstr ""
1046
-
1047
- #: src/Tribe/View_Helpers.php:177
1048
- msgid "Malaysia"
1049
- msgstr ""
1050
-
1051
- #: src/Tribe/View_Helpers.php:178
1052
- msgid "Maldives"
1053
- msgstr ""
1054
-
1055
- #: src/Tribe/View_Helpers.php:179
1056
- msgid "Mali"
1057
- msgstr ""
1058
-
1059
- #: src/Tribe/View_Helpers.php:180
1060
- msgid "Malta"
1061
- msgstr ""
1062
-
1063
- #: src/Tribe/View_Helpers.php:181
1064
- msgid "Marshall Islands"
1065
- msgstr ""
1066
-
1067
- #: src/Tribe/View_Helpers.php:182
1068
- msgid "Martinique"
1069
- msgstr ""
1070
-
1071
- #: src/Tribe/View_Helpers.php:183
1072
- msgid "Mauritania"
1073
- msgstr ""
1074
-
1075
- #: src/Tribe/View_Helpers.php:184
1076
- msgid "Mauritius"
1077
- msgstr ""
1078
-
1079
- #: src/Tribe/View_Helpers.php:185
1080
- msgid "Mayotte"
1081
- msgstr ""
1082
-
1083
- #: src/Tribe/View_Helpers.php:186
1084
- msgid "Mexico"
1085
- msgstr ""
1086
-
1087
- #: src/Tribe/View_Helpers.php:187
1088
- msgid "Micronesia, Federated States Of"
1089
- msgstr ""
1090
-
1091
- #: src/Tribe/View_Helpers.php:188
1092
- msgid "Moldova, Republic Of"
1093
- msgstr ""
1094
-
1095
- #: src/Tribe/View_Helpers.php:189
1096
- msgid "Monaco"
1097
- msgstr ""
1098
-
1099
- #: src/Tribe/View_Helpers.php:190
1100
- msgid "Mongolia"
1101
- msgstr ""
1102
-
1103
- #: src/Tribe/View_Helpers.php:191
1104
- msgid "Montenegro"
1105
- msgstr ""
1106
-
1107
- #: src/Tribe/View_Helpers.php:192
1108
- msgid "Montserrat"
1109
- msgstr ""
1110
-
1111
- #: src/Tribe/View_Helpers.php:193
1112
- msgid "Morocco"
1113
- msgstr ""
1114
-
1115
- #: src/Tribe/View_Helpers.php:194
1116
- msgid "Mozambique"
1117
- msgstr ""
1118
-
1119
- #: src/Tribe/View_Helpers.php:195
1120
- msgid "Myanmar"
1121
- msgstr ""
1122
-
1123
- #: src/Tribe/View_Helpers.php:196
1124
- msgid "Namibia"
1125
- msgstr ""
1126
-
1127
- #: src/Tribe/View_Helpers.php:197
1128
- msgid "Nauru"
1129
- msgstr ""
1130
-
1131
- #: src/Tribe/View_Helpers.php:198
1132
- msgid "Nepal"
1133
- msgstr ""
1134
-
1135
- #: src/Tribe/View_Helpers.php:199
1136
- msgid "Netherlands"
1137
- msgstr ""
1138
-
1139
- #: src/Tribe/View_Helpers.php:200
1140
- msgid "Netherlands Antilles"
1141
- msgstr ""
1142
-
1143
- #: src/Tribe/View_Helpers.php:201
1144
- msgid "New Caledonia"
1145
- msgstr ""
1146
-
1147
- #: src/Tribe/View_Helpers.php:202
1148
- msgid "New Zealand"
1149
- msgstr ""
1150
-
1151
- #: src/Tribe/View_Helpers.php:203
1152
- msgid "Nicaragua"
1153
- msgstr ""
1154
-
1155
- #: src/Tribe/View_Helpers.php:204
1156
- msgid "Niger"
1157
- msgstr ""
1158
-
1159
- #: src/Tribe/View_Helpers.php:205
1160
- msgid "Nigeria"
1161
- msgstr ""
1162
-
1163
- #: src/Tribe/View_Helpers.php:206
1164
- msgid "Niue"
1165
- msgstr ""
1166
-
1167
- #: src/Tribe/View_Helpers.php:207
1168
- msgid "Norfolk Island"
1169
- msgstr ""
1170
-
1171
- #: src/Tribe/View_Helpers.php:208
1172
- msgid "Northern Mariana Islands"
1173
- msgstr ""
1174
-
1175
- #: src/Tribe/View_Helpers.php:209
1176
- msgid "Norway"
1177
- msgstr ""
1178
-
1179
- #: src/Tribe/View_Helpers.php:210
1180
- msgid "Oman"
1181
- msgstr ""
1182
-
1183
- #: src/Tribe/View_Helpers.php:211
1184
- msgid "Pakistan"
1185
- msgstr ""
1186
-
1187
- #: src/Tribe/View_Helpers.php:212
1188
- msgid "Palau"
1189
- msgstr ""
1190
-
1191
- #: src/Tribe/View_Helpers.php:213
1192
- msgid "Panama"
1193
- msgstr ""
1194
-
1195
- #: src/Tribe/View_Helpers.php:214
1196
- msgid "Papua New Guinea"
1197
- msgstr ""
1198
-
1199
- #: src/Tribe/View_Helpers.php:215
1200
- msgid "Paraguay"
1201
- msgstr ""
1202
-
1203
- #: src/Tribe/View_Helpers.php:216
1204
- msgid "Peru"
1205
- msgstr ""
1206
-
1207
- #: src/Tribe/View_Helpers.php:217
1208
- msgid "Philippines"
1209
- msgstr ""
1210
-
1211
- #: src/Tribe/View_Helpers.php:218
1212
- msgid "Pitcairn"
1213
- msgstr ""
1214
-
1215
- #: src/Tribe/View_Helpers.php:219
1216
- msgid "Poland"
1217
- msgstr ""
1218
-
1219
- #: src/Tribe/View_Helpers.php:220
1220
- msgid "Portugal"
1221
- msgstr ""
1222
-
1223
- #: src/Tribe/View_Helpers.php:221
1224
- msgid "Puerto Rico"
1225
- msgstr ""
1226
-
1227
- #: src/Tribe/View_Helpers.php:222
1228
- msgid "Qatar"
1229
- msgstr ""
1230
-
1231
- #: src/Tribe/View_Helpers.php:223
1232
- msgid "Reunion"
1233
- msgstr ""
1234
-
1235
- #: src/Tribe/View_Helpers.php:224
1236
- msgid "Romania"
1237
- msgstr ""
1238
-
1239
- #: src/Tribe/View_Helpers.php:225
1240
- msgid "Russian Federation"
1241
- msgstr ""
1242
-
1243
- #: src/Tribe/View_Helpers.php:226
1244
- msgid "Rwanda"
1245
- msgstr ""
1246
-
1247
- #: src/Tribe/View_Helpers.php:227
1248
- msgid "Saint Kitts And Nevis"
1249
- msgstr ""
1250
-
1251
- #: src/Tribe/View_Helpers.php:228
1252
- msgid "Saint Lucia"
1253
- msgstr ""
1254
-
1255
- #: src/Tribe/View_Helpers.php:229
1256
- msgid "Saint Vincent And The Grenadines"
1257
- msgstr ""
1258
-
1259
- #: src/Tribe/View_Helpers.php:230
1260
- msgid "Samoa"
1261
- msgstr ""
1262
-
1263
- #: src/Tribe/View_Helpers.php:231
1264
- msgid "San Marino"
1265
- msgstr ""
1266
-
1267
- #: src/Tribe/View_Helpers.php:232
1268
- msgid "Sao Tome And Principe"
1269
- msgstr ""
1270
-
1271
- #: src/Tribe/View_Helpers.php:233
1272
- msgid "Saudi Arabia"
1273
- msgstr ""
1274
-
1275
- #: src/Tribe/View_Helpers.php:234
1276
- msgid "Senegal"
1277
- msgstr ""
1278
-
1279
- #: src/Tribe/View_Helpers.php:235
1280
- msgid "Serbia"
1281
- msgstr ""
1282
-
1283
- #: src/Tribe/View_Helpers.php:236
1284
- msgid "Seychelles"
1285
- msgstr ""
1286
-
1287
- #: src/Tribe/View_Helpers.php:237
1288
- msgid "Sierra Leone"
1289
- msgstr ""
1290
-
1291
- #: src/Tribe/View_Helpers.php:238
1292
- msgid "Singapore"
1293
- msgstr ""
1294
-
1295
- #: src/Tribe/View_Helpers.php:239
1296
- msgid "Slovakia (Slovak Republic)"
1297
- msgstr ""
1298
-
1299
- #: src/Tribe/View_Helpers.php:240
1300
- msgid "Slovenia"
1301
- msgstr ""
1302
-
1303
- #: src/Tribe/View_Helpers.php:241
1304
- msgid "Solomon Islands"
1305
- msgstr ""
1306
-
1307
- #: src/Tribe/View_Helpers.php:242
1308
- msgid "Somalia"
1309
- msgstr ""
1310
-
1311
- #: src/Tribe/View_Helpers.php:243
1312
- msgid "South Africa"
1313
- msgstr ""
1314
-
1315
- #: src/Tribe/View_Helpers.php:244
1316
- msgid "South Georgia, South Sandwich Islands"
1317
- msgstr ""
1318
-
1319
- #: src/Tribe/View_Helpers.php:245
1320
- msgid "Spain"
1321
- msgstr ""
1322
-
1323
- #: src/Tribe/View_Helpers.php:246
1324
- msgid "Sri Lanka"
1325
- msgstr ""
1326
-
1327
- #: src/Tribe/View_Helpers.php:247
1328
- msgid "St. Helena"
1329
- msgstr ""
1330
-
1331
- #: src/Tribe/View_Helpers.php:248
1332
- msgid "St. Pierre And Miquelon"
1333
- msgstr ""
1334
-
1335
- #: src/Tribe/View_Helpers.php:249
1336
- msgid "Sudan"
1337
- msgstr ""
1338
-
1339
- #: src/Tribe/View_Helpers.php:250
1340
- msgid "Suriname"
1341
- msgstr ""
1342
-
1343
- #: src/Tribe/View_Helpers.php:251
1344
- msgid "Svalbard And Jan Mayen Islands"
1345
- msgstr ""
1346
-
1347
- #: src/Tribe/View_Helpers.php:252
1348
- msgid "Swaziland"
1349
- msgstr ""
1350
-
1351
- #: src/Tribe/View_Helpers.php:253
1352
- msgid "Sweden"
1353
- msgstr ""
1354
-
1355
- #: src/Tribe/View_Helpers.php:254
1356
- msgid "Switzerland"
1357
- msgstr ""
1358
-
1359
- #: src/Tribe/View_Helpers.php:255
1360
- msgid "Syrian Arab Republic"
1361
- msgstr ""
1362
-
1363
- #: src/Tribe/View_Helpers.php:256
1364
- msgid "Taiwan"
1365
- msgstr ""
1366
-
1367
- #: src/Tribe/View_Helpers.php:257
1368
- msgid "Tajikistan"
1369
- msgstr ""
1370
-
1371
- #: src/Tribe/View_Helpers.php:258
1372
- msgid "Tanzania, United Republic Of"
1373
- msgstr ""
1374
-
1375
- #: src/Tribe/View_Helpers.php:259
1376
- msgid "Thailand"
1377
- msgstr ""
1378
-
1379
- #: src/Tribe/View_Helpers.php:260
1380
- msgid "Togo"
1381
- msgstr ""
1382
-
1383
- #: src/Tribe/View_Helpers.php:261
1384
- msgid "Tokelau"
1385
- msgstr ""
1386
-
1387
- #: src/Tribe/View_Helpers.php:262
1388
- msgid "Tonga"
1389
- msgstr ""
1390
-
1391
- #: src/Tribe/View_Helpers.php:263
1392
- msgid "Trinidad And Tobago"
1393
- msgstr ""
1394
-
1395
- #: src/Tribe/View_Helpers.php:264
1396
- msgid "Tunisia"
1397
- msgstr ""
1398
-
1399
- #: src/Tribe/View_Helpers.php:265
1400
- msgid "Turkey"
1401
- msgstr ""
1402
-
1403
- #: src/Tribe/View_Helpers.php:266
1404
- msgid "Turkmenistan"
1405
- msgstr ""
1406
-
1407
- #: src/Tribe/View_Helpers.php:267
1408
- msgid "Turks And Caicos Islands"
1409
- msgstr ""
1410
-
1411
- #: src/Tribe/View_Helpers.php:268
1412
- msgid "Tuvalu"
1413
- msgstr ""
1414
-
1415
- #: src/Tribe/View_Helpers.php:269
1416
- msgid "Uganda"
1417
- msgstr ""
1418
-
1419
- #: src/Tribe/View_Helpers.php:270
1420
- msgid "Ukraine"
1421
- msgstr ""
1422
-
1423
- #: src/Tribe/View_Helpers.php:271
1424
- msgid "United Arab Emirates"
1425
- msgstr ""
1426
-
1427
- #: src/Tribe/View_Helpers.php:272
1428
- msgid "United Kingdom"
1429
- msgstr ""
1430
-
1431
- #: src/Tribe/View_Helpers.php:273
1432
- msgid "United States Minor Outlying Islands"
1433
- msgstr ""
1434
-
1435
- #: src/Tribe/View_Helpers.php:274
1436
- msgid "Uruguay"
1437
- msgstr ""
1438
-
1439
- #: src/Tribe/View_Helpers.php:275
1440
- msgid "Uzbekistan"
1441
- msgstr ""
1442
-
1443
- #: src/Tribe/View_Helpers.php:276
1444
- msgid "Vanuatu"
1445
- msgstr ""
1446
-
1447
- #: src/Tribe/View_Helpers.php:277
1448
- msgid "Venezuela"
1449
- msgstr ""
1450
-
1451
- #: src/Tribe/View_Helpers.php:278
1452
- msgid "Viet Nam"
1453
- msgstr ""
1454
-
1455
- #: src/Tribe/View_Helpers.php:279
1456
- msgid "Virgin Islands (British)"
1457
- msgstr ""
1458
-
1459
- #: src/Tribe/View_Helpers.php:280
1460
- msgid "Virgin Islands (U.S.)"
1461
- msgstr ""
1462
-
1463
- #: src/Tribe/View_Helpers.php:281
1464
- msgid "Wallis And Futuna Islands"
1465
- msgstr ""
1466
-
1467
- #: src/Tribe/View_Helpers.php:282
1468
- msgid "Western Sahara"
1469
- msgstr ""
1470
-
1471
- #: src/Tribe/View_Helpers.php:283
1472
- msgid "Yemen"
1473
- msgstr ""
1474
-
1475
- #: src/Tribe/View_Helpers.php:284
1476
- msgid "Zambia"
1477
- msgstr ""
1478
-
1479
- #: src/Tribe/View_Helpers.php:285
1480
- msgid "Zimbabwe"
1481
- msgstr ""
1482
-
1483
- #: src/Tribe/View_Helpers.php:316
1484
- msgid "Alabama"
1485
- msgstr ""
1486
-
1487
- #: src/Tribe/View_Helpers.php:317
1488
- msgid "Alaska"
1489
- msgstr ""
1490
-
1491
- #: src/Tribe/View_Helpers.php:318
1492
- msgid "Arizona"
1493
- msgstr ""
1494
-
1495
- #: src/Tribe/View_Helpers.php:319
1496
- msgid "Arkansas"
1497
- msgstr ""
1498
-
1499
- #: src/Tribe/View_Helpers.php:320
1500
- msgid "California"
1501
- msgstr ""
1502
-
1503
- #: src/Tribe/View_Helpers.php:321
1504
- msgid "Colorado"
1505
- msgstr ""
1506
-
1507
- #: src/Tribe/View_Helpers.php:322
1508
- msgid "Connecticut"
1509
- msgstr ""
1510
-
1511
- #: src/Tribe/View_Helpers.php:323
1512
- msgid "Delaware"
1513
- msgstr ""
1514
-
1515
- #: src/Tribe/View_Helpers.php:324
1516
- msgid "District of Columbia"
1517
- msgstr ""
1518
-
1519
- #: src/Tribe/View_Helpers.php:325
1520
- msgid "Florida"
1521
- msgstr ""
1522
-
1523
- #: src/Tribe/View_Helpers.php:327
1524
- msgid "Hawaii"
1525
- msgstr ""
1526
-
1527
- #: src/Tribe/View_Helpers.php:328
1528
- msgid "Idaho"
1529
- msgstr ""
1530
-
1531
- #: src/Tribe/View_Helpers.php:329
1532
- msgid "Illinois"
1533
- msgstr ""
1534
-
1535
- #: src/Tribe/View_Helpers.php:330
1536
- msgid "Indiana"
1537
- msgstr ""
1538
-
1539
- #: src/Tribe/View_Helpers.php:331
1540
- msgid "Iowa"
1541
- msgstr ""
1542
-
1543
- #: src/Tribe/View_Helpers.php:332
1544
- msgid "Kansas"
1545
- msgstr ""
1546
-
1547
- #: src/Tribe/View_Helpers.php:333
1548
- msgid "Kentucky"
1549
- msgstr ""
1550
-
1551
- #: src/Tribe/View_Helpers.php:334
1552
- msgid "Louisiana"
1553
- msgstr ""
1554
-
1555
- #: src/Tribe/View_Helpers.php:335
1556
- msgid "Maine"
1557
- msgstr ""
1558
-
1559
- #: src/Tribe/View_Helpers.php:336
1560
- msgid "Maryland"
1561
- msgstr ""
1562
-
1563
- #: src/Tribe/View_Helpers.php:337
1564
- msgid "Massachusetts"
1565
- msgstr ""
1566
-
1567
- #: src/Tribe/View_Helpers.php:338
1568
- msgid "Michigan"
1569
- msgstr ""
1570
-
1571
- #: src/Tribe/View_Helpers.php:339
1572
- msgid "Minnesota"
1573
- msgstr ""
1574
-
1575
- #: src/Tribe/View_Helpers.php:340
1576
- msgid "Mississippi"
1577
- msgstr ""
1578
-
1579
- #: src/Tribe/View_Helpers.php:341
1580
- msgid "Missouri"
1581
- msgstr ""
1582
-
1583
- #: src/Tribe/View_Helpers.php:342
1584
- msgid "Montana"
1585
- msgstr ""
1586
-
1587
- #: src/Tribe/View_Helpers.php:343
1588
- msgid "Nebraska"
1589
- msgstr ""
1590
-
1591
- #: src/Tribe/View_Helpers.php:344
1592
- msgid "Nevada"
1593
- msgstr ""
1594
-
1595
- #: src/Tribe/View_Helpers.php:345
1596
- msgid "New Hampshire"
1597
- msgstr ""
1598
-
1599
- #: src/Tribe/View_Helpers.php:346
1600
- msgid "New Jersey"
1601
- msgstr ""
1602
-
1603
- #: src/Tribe/View_Helpers.php:347
1604
- msgid "New Mexico"
1605
- msgstr ""
1606
-
1607
- #: src/Tribe/View_Helpers.php:348
1608
- msgid "New York"
1609
- msgstr ""
1610
-
1611
- #: src/Tribe/View_Helpers.php:349
1612
- msgid "North Carolina"
1613
- msgstr ""
1614
-
1615
- #: src/Tribe/View_Helpers.php:350
1616
- msgid "North Dakota"
1617
- msgstr ""
1618
-
1619
- #: src/Tribe/View_Helpers.php:351
1620
- msgid "Ohio"
1621
- msgstr ""
1622
-
1623
- #: src/Tribe/View_Helpers.php:352
1624
- msgid "Oklahoma"
1625
- msgstr ""
1626
-
1627
- #: src/Tribe/View_Helpers.php:353
1628
- msgid "Oregon"
1629
- msgstr ""
1630
-
1631
- #: src/Tribe/View_Helpers.php:354
1632
- msgid "Pennsylvania"
1633
- msgstr ""
1634
-
1635
- #: src/Tribe/View_Helpers.php:355
1636
- msgid "Rhode Island"
1637
- msgstr ""
1638
-
1639
- #: src/Tribe/View_Helpers.php:356
1640
- msgid "South Carolina"
1641
- msgstr ""
1642
-
1643
- #: src/Tribe/View_Helpers.php:357
1644
- msgid "South Dakota"
1645
- msgstr ""
1646
-
1647
- #: src/Tribe/View_Helpers.php:358
1648
- msgid "Tennessee"
1649
- msgstr ""
1650
-
1651
- #: src/Tribe/View_Helpers.php:359
1652
- msgid "Texas"
1653
- msgstr ""
1654
-
1655
- #: src/Tribe/View_Helpers.php:360
1656
- msgid "Utah"
1657
- msgstr ""
1658
-
1659
- #: src/Tribe/View_Helpers.php:361
1660
- msgid "Vermont"
1661
- msgstr ""
1662
-
1663
- #: src/Tribe/View_Helpers.php:362
1664
- msgid "Virginia"
1665
- msgstr ""
1666
-
1667
- #: src/Tribe/View_Helpers.php:363
1668
- msgid "Washington"
1669
- msgstr ""
1670
-
1671
- #: src/Tribe/View_Helpers.php:364
1672
- msgid "West Virginia"
1673
- msgstr ""
1674
-
1675
- #: src/Tribe/View_Helpers.php:365
1676
- msgid "Wisconsin"
1677
- msgstr ""
1678
-
1679
- #: src/Tribe/View_Helpers.php:366
1680
- msgid "Wyoming"
1681
- msgstr ""
1682
-
1683
- #: src/admin-views/app-shop.php:4
1684
- msgid "Tribe Event Add-Ons"
1685
- msgstr ""
1686
-
1687
- #: src/admin-views/event-log.php:21
1688
- msgid "Logging level"
1689
- msgstr ""
1690
-
1691
- #: src/admin-views/event-log.php:39
1692
- msgid "Method"
1693
- msgstr ""
1694
-
1695
- #: src/admin-views/event-log.php:57
1696
- msgid "View"
1697
- msgstr ""
1698
-
1699
- #: src/admin-views/event-log.php:99
1700
- msgid "The selected log file is empty or has not been generated yet."
1701
- msgstr ""
1702
-
1703
- #: src/admin-views/event-log.php:104
1704
- msgid "Download log"
1705
- msgstr ""
1706
-
1707
- #: src/admin-views/tribe-options-display.php:22
1708
- msgid "Date Format Settings"
1709
- msgstr ""
1710
-
1711
- #: src/admin-views/tribe-options-display.php:26
1712
- msgid "<p>The following three fields accept the date format options available to the php date() function. <a href=\"http://codex.wordpress.org/Formatting_Date_and_Time\" target=\"_blank\">Learn how to make your own date format here</a>.</p>"
1713
- msgstr ""
1714
-
1715
- #: src/admin-views/tribe-options-display.php:30
1716
- msgid "Datepicker Date Format"
1717
- msgstr ""
1718
-
1719
- #: src/admin-views/tribe-options-display.php:31
1720
- msgid "Select the date format to use in datepickers"
1721
- msgstr ""
1722
-
1723
- #: src/admin-views/tribe-options-general.php:10
1724
- msgid "Thank you for using Event Tickets! All of us at Modern Tribe sincerely appreciate your support and we're excited to see you using our plugins. Check out our handy %1$sNew User Primer%2$s to get started."
1725
- msgstr ""
1726
-
1727
- #: src/admin-views/tribe-options-general.php:15
1728
- msgid "Optimize your site's event listings with %1$sThe Events Calendar%2$s, our free calendar plugin. Looking for additional functionality including recurring events, user-submission, advanced ticket sales and more? Check out our %3$spremium add-ons%4$s."
1729
- msgstr ""
1730
-
1731
- #: src/admin-views/tribe-options-general.php:20
1732
- msgid "Looking for additional functionality including recurring events, custom meta, community events, ticket sales and more?"
1733
- msgstr ""
1734
-
1735
- #: src/admin-views/tribe-options-general.php:20
1736
- msgid "Check out the available add-ons"
1737
- msgstr ""
1738
-
1739
- #: src/admin-views/tribe-options-general.php:25
1740
- msgid "We hope our plugin is helping you out."
1741
- msgstr ""
1742
-
1743
- #: src/admin-views/tribe-options-general.php:30
1744
- msgid "Are you thinking \"Wow, this plugin is amazing! I should say thanks to Modern Tribe for all their hard work.\" The greatest thanks we could ask for is recognition. Add a small text-only link at the bottom of your calendar pointing to The Events Calendar project."
1745
- msgstr ""
1746
-
1747
- #: src/admin-views/tribe-options-general.php:30
1748
- #: src/admin-views/tribe-options-general.php:35
1749
- msgid "See an example of the link"
1750
- msgstr ""
1751
-
1752
- #: src/admin-views/tribe-options-general.php:35
1753
- msgid "Are you thinking \"Wow, this plugin is amazing! I should say thanks to Modern Tribe for all their hard work.\" The greatest thanks we could ask for is recognition. Add a small text only link at the bottom of your calendar pointing to The Events Calendar project."
1754
- msgstr ""
1755
-
1756
- #: src/admin-views/tribe-options-general.php:40
1757
- msgid "Show The Events Calendar link"
1758
- msgstr ""
1759
-
1760
- #: src/admin-views/tribe-options-general.php:58
1761
- msgid "Debug mode"
1762
- msgstr ""
1763
-
1764
- #: src/admin-views/tribe-options-general.php:64
1765
- msgid "Enable this option to log debug information. By default this will log to your server PHP error log. If you'd like to see the log messages in your browser, then we recommend that you install the %s and look for the \"Tribe\" tab in the debug output."
1766
- msgstr ""
1767
-
1768
- #: src/admin-views/tribe-options-general.php:64
1769
- msgid "Debug Bar Plugin"
1770
- msgstr ""
1771
-
1772
- #: src/admin-views/tribe-options-help.php:11
1773
- msgid "Thanks you for using %s! All of us at Modern Tribe sincerely appreciate your support and we’re excited to see you using our plugins."
1774
- msgstr ""
1775
-
1776
- #: src/admin-views/tribe-options-help.php:14
1777
- msgid "Getting Support"
1778
- msgstr ""
1779
-
1780
- #: src/admin-views/tribe-options-help.php:15
1781
- msgid "Our website’s %s is a great place to find tips and tricks for using and customizing our plugins."
1782
- msgstr ""
1783
-
1784
- #: src/admin-views/tribe-options-help.php:15
1785
- msgid "Knowledgebase"
1786
- msgstr ""
1787
-
1788
- #: src/admin-views/tribe-options-help.php:16
1789
- msgid "<strong>Want to dive deeper?</strong> Check out our %s for developers."
1790
- msgstr ""
1791
-
1792
- #: src/admin-views/tribe-options-help.php:16
1793
- msgid "list of available functions"
1794
- msgstr ""
1795
-
1796
- #: src/admin-views/tribe-options-help.php:19
1797
- msgid "Getting More Help"
1798
- msgstr ""
1799
-
1800
- #: src/admin-views/tribe-options-help.php:20
1801
- msgid "While the resources above help solve a majority of the issues we see, there are times you might be looking for extra support. If you need assistance using our plugins and would like us to take a look, please follow these steps:"
1802
- msgstr ""
1803
-
1804
- #: src/admin-views/tribe-options-help.php:24
1805
- msgid "%s. All of the common (and not-so-common) answers to questions we see are here. It’s often the fastest path to finding an answer!"
1806
- msgstr ""
1807
-
1808
- #: src/admin-views/tribe-options-help.php:24
1809
- msgid "Check our Knowledgebase"
1810
- msgstr ""
1811
-
1812
- #: src/admin-views/tribe-options-help.php:25
1813
- msgid "%s. Testing for an existing conflict is the best start for in-depth troubleshooting. We will often ask you to follow these steps when opening a new thread, so doing this ahead of time will be super helpful."
1814
- msgstr ""
1815
-
1816
- #: src/admin-views/tribe-options-help.php:25
1817
- msgid "Test for a theme or plugin conflict"
1818
- msgstr ""
1819
-
1820
- #: src/admin-views/tribe-options-help.php:26
1821
- msgid "%s. There are very few issues we haven’t seen and it’s likely another user has already asked your question and gotten an answer from our support staff. While posting to the forums is open only to paid customers, they are open for anyone to search and review."
1822
- msgstr ""
1823
-
1824
- #: src/admin-views/tribe-options-help.php:26
1825
- msgid "Search our support forum"
1826
- msgstr ""
1827
-
1828
- #: src/admin-views/tribe-options-help.php:30
1829
- msgid "Please note that all hands-on support is provided via the forums. You can email or tweet at us… ​but we will probably point you back to the forums 😄"
1830
- msgstr ""
1831
-
1832
- #: src/admin-views/tribe-options-help.php:31
1833
- msgid "Read more about our support policy"
1834
- msgstr ""
1835
-
1836
- #: src/admin-views/tribe-options-help.php:34
1837
- msgid "System Information"
1838
- msgstr ""
1839
-
1840
- #: src/admin-views/tribe-options-help.php:35
1841
- msgid "The details of your calendar plugin and settings is often needed for you or our staff to help troubleshoot an issue. We may ask you to share this information if you ask for support. If you post in one of our premium forums, please copy and paste this information into the System Information field and it will help us help you faster!"
1842
- msgstr ""
1843
-
1844
- #: src/admin-views/tribe-options-help.php:37
1845
- msgid "Recent Template Changes"
1846
- msgstr ""
1847
-
1848
- #: src/admin-views/tribe-options-help.php:57
1849
- msgid "News and Tutorials"
1850
- msgstr ""
1851
-
1852
- #: src/admin-views/tribe-options-help.php:63
1853
- msgid "More..."
1854
- msgstr ""
1855
-
1856
- #: src/admin-views/tribe-options-licenses.php:13
1857
- msgid "<p>The license key you received when completing your purchase from %1$s will grant you access to support and updates until it expires. You do not need to enter the key below for the plugins to work, but you will need to enter it to get automatic updates. <strong>Find your license keys at <a href=\"%2$s\" target=\"_blank\">%3$s</a></strong>.</p> <p>Each paid add-on has its own unique license key. Simply paste the key into its appropriate field on below, and give it a moment to validate. You know you're set when a green expiration date appears alongside a \"valid\" message.</p> <p>If you're seeing a red message telling you that your key isn't valid or is out of installs, visit <a href=\"%4$s\" target=\"_blank\">%5$s</a> to manage your installs or renew / upgrade your license.</p><p>Not seeing an update but expecting one? In WordPress, go to <a href=\"%6$s\">Dashboard > Updates</a> and click \"Check Again\".</p>"
1858
- msgstr ""
1859
-
1860
- #: src/admin-views/tribe-options-licenses.php:18
1861
- msgid "%1$s Using our plugins in a multisite network? %2$s Please note that your license key will be applied to the entire network, not just this site."
1862
- msgstr ""
1863
-
1864
- #: src/admin-views/tribe-options-licenses.php:27
1865
- msgid "Only license fields for %1$snetwork activated%2$s plugins will be listed on this screen. "
1866
- msgstr ""
1867
-
1868
- #: src/admin-views/tribe-options-network.php:15
1869
- msgid "Network Settings"
1870
- msgstr ""
1871
-
1872
- #: src/admin-views/tribe-options-network.php:19
1873
- msgid "This is where all of the global network settings for Modern Tribe's The Events Calendar can be modified."
1874
- msgstr ""
1875
-
1876
- #: src/admin-views/tribe-options-network.php:27
1877
- msgid "Hide the following settings tabs on every site:"
1878
- msgstr ""
1879
- #. Plugin Name of the plugin/theme
1880
- msgid "Tribe Common"
1881
- msgstr ""
1882
-
1883
- #. Description of the plugin/theme
1884
- msgid "An event settings framework for managing shared options"
1885
- msgstr ""
1886
-
1887
- #. Author of the plugin/theme
1888
- msgid "Modern Tribe, Inc."
1889
- msgstr ""
1890
-
1891
- #. Author URI of the plugin/theme
1892
- msgid "http://m.tri.be/1x"
1893
- msgstr ""
 
 
 
 
1
+ # Copyright (C) 2016 Modern Tribe
2
+ # This file is distributed under the same license as the Tribe Common package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Tribe Common 4.2.7\n"
6
+ "Report-Msgid-Bugs-To: http://m.tri.be/191x\n"
7
+ "POT-Creation-Date: 2016-09-14 15:54:58+00:00\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2016-09-14 15:54\n"
12
+ "Last-Translator: \n"
13
+ "Language-Team: \n"
14
+
15
+ #: src/Tribe/Admin/Help_Page.php:48
16
+ msgid "The Events Calendar"
17
+ msgstr ""
18
+
19
+ #: src/Tribe/Admin/Help_Page.php:52
20
+ msgid "The Events Calendar is a carefully crafted, extensible plugin that lets you easily share your events."
21
+ msgstr ""
22
+
23
+ #: src/Tribe/Admin/Help_Page.php:64
24
+ msgid "Event Tickets"
25
+ msgstr ""
26
+
27
+ #: src/Tribe/Admin/Help_Page.php:68
28
+ msgid "Events Tickets is a carefully crafted, extensible plugin that lets you easily sell tickets for your events."
29
+ msgstr ""
30
+
31
+ #: src/Tribe/Admin/Help_Page.php:80
32
+ msgid "Advanced Post Manager"
33
+ msgstr ""
34
+
35
+ #: src/Tribe/Admin/Help_Page.php:84
36
+ msgid "Turbo charge your posts admin for any custom post type with sortable filters and columns, and auto-registration of metaboxes."
37
+ msgstr ""
38
+
39
+ #: src/Tribe/Admin/Help_Page.php:159
40
+ msgid " and "
41
+ msgstr ""
42
+
43
+ #: src/Tribe/Admin/Help_Page.php:183 src/Tribe/App_Shop.php:109
44
+ msgid "Events Calendar PRO"
45
+ msgstr ""
46
+
47
+ #: src/Tribe/Admin/Help_Page.php:192 src/Tribe/App_Shop.php:142
48
+ msgid "Eventbrite Tickets"
49
+ msgstr ""
50
+
51
+ #: src/Tribe/Admin/Help_Page.php:200 src/Tribe/App_Shop.php:119
52
+ msgid "Community Events"
53
+ msgstr ""
54
+
55
+ #: src/Tribe/Admin/Help_Page.php:208 src/Tribe/App_Shop.php:152
56
+ msgid "Facebook Events"
57
+ msgstr ""
58
+
59
+ #: src/Tribe/Admin/Help_Page.php:216
60
+ msgid "Events Filter Bar"
61
+ msgstr ""
62
+
63
+ #: src/Tribe/Admin/Help_Page.php:224 src/Tribe/App_Shop.php:132
64
+ msgid "Event Tickets Plus"
65
+ msgstr ""
66
+
67
+ #: src/Tribe/Admin/Help_Page.php:233 src/Tribe/App_Shop.php:125
68
+ msgid "Community Tickets"
69
+ msgstr ""
70
+
71
+ #: src/Tribe/Admin/Help_Page.php:394
72
+ msgctxt "not available"
73
+ msgid "n/a"
74
+ msgstr ""
75
+
76
+ #: src/Tribe/Admin/Help_Page.php:402
77
+ msgid "You need to upgrade!"
78
+ msgstr ""
79
+
80
+ #: src/Tribe/Admin/Help_Page.php:402 src/Tribe/Admin/Help_Page.php:777
81
+ msgid "You are up to date!"
82
+ msgstr ""
83
+
84
+ #: src/Tribe/Admin/Help_Page.php:767
85
+ msgid "Activate %s"
86
+ msgstr ""
87
+
88
+ #: src/Tribe/Admin/Help_Page.php:767
89
+ msgid "Activate Plugin"
90
+ msgstr ""
91
+
92
+ #: src/Tribe/Admin/Help_Page.php:775
93
+ msgid "Upgrade Plugin"
94
+ msgstr ""
95
+
96
+ #: src/Tribe/Admin/Help_Page.php:791
97
+ msgid "Install %s"
98
+ msgstr ""
99
+
100
+ #: src/Tribe/Admin/Help_Page.php:791
101
+ msgid "Install Plugin"
102
+ msgstr ""
103
+
104
+ #: src/Tribe/Admin/Help_Page.php:808
105
+ msgid "Latest Version:"
106
+ msgstr ""
107
+
108
+ #: src/Tribe/Admin/Help_Page.php:811 src/admin-views/app-shop.php:26
109
+ msgid "Requires:"
110
+ msgstr ""
111
+
112
+ #: src/Tribe/Admin/Help_Page.php:812
113
+ msgid "WordPress "
114
+ msgstr ""
115
+
116
+ #: src/Tribe/Admin/Help_Page.php:814
117
+ msgid "Active Users:"
118
+ msgstr ""
119
+
120
+ #: src/Tribe/Admin/Help_Page.php:817
121
+ msgid "Rating:"
122
+ msgstr ""
123
+
124
+ #: src/Tribe/Admin/Help_Page.php:836
125
+ msgid "Premium Add-Ons"
126
+ msgstr ""
127
+
128
+ #: src/Tribe/Admin/Help_Page.php:842
129
+ msgid "Plugin Active"
130
+ msgstr ""
131
+
132
+ #: src/Tribe/Admin/Help_Page.php:844
133
+ msgid "Plugin Inactive"
134
+ msgstr ""
135
+
136
+ #: src/Tribe/Admin/Help_Page.php:849
137
+ msgid "Visit the Add-on Page"
138
+ msgstr ""
139
+
140
+ #: src/Tribe/Admin/Notice/Archive_Slug_Conflict.php:88
141
+ msgid "<a href=\"%s\">Edit the page slug</a>"
142
+ msgstr ""
143
+
144
+ #: src/Tribe/Admin/Notice/Archive_Slug_Conflict.php:89
145
+ msgid "Ask the site administrator to edit the page slug"
146
+ msgstr ""
147
+
148
+ #: src/Tribe/Admin/Notice/Archive_Slug_Conflict.php:94
149
+ msgid "<a href=\"%s\">edit Events settings</a>."
150
+ msgstr ""
151
+
152
+ #: src/Tribe/Admin/Notice/Archive_Slug_Conflict.php:95
153
+ msgid " ask the site administrator set a different Events URL slug."
154
+ msgstr ""
155
+
156
+ #: src/Tribe/App_Shop.php:48 src/Tribe/App_Shop.php:49
157
+ #: src/Tribe/App_Shop.php:72
158
+ msgid "Event Add-Ons"
159
+ msgstr ""
160
+
161
+ #: src/Tribe/App_Shop.php:103
162
+ msgid "Filter Bar"
163
+ msgstr ""
164
+
165
+ #: src/Tribe/App_Shop.php:105
166
+ msgid "It is awesome that your calendar is <em>THE PLACE</em> to get hooked up with prime choice ways to spend time. You have more events than Jabba the Hutt has rolls. Too bad visitors are hiring a personal assistant to go through all the choices. Ever wish you could just filter the calendar to only show events in walking distance, on a weekend, that are free? BOOM. Now you can. Introducing… the Filter Bar."
167
+ msgstr ""
168
+
169
+ #: src/Tribe/App_Shop.php:112
170
+ msgid "The Events Calendar PRO is a paid Add-On to our open source WordPress plugin %1$sThe Events Calendar%2$s. PRO offers a whole host of calendar features including recurring events, custom event attributes, saved venues and organizers, venue pages, advanced event admin and lots more."
171
+ msgstr ""
172
+
173
+ #: src/Tribe/App_Shop.php:121
174
+ msgid "Enable users to submit events to your calendar with Community Events. You can require user accounts or allow visitors to submit without an account. Want to make sure that nothing fishy is going on? Just turn on moderation. Decide if users can edit and manage their own events, or simply submit. Plus, no scary form setup! Just activate, configure the options & off you go."
175
+ msgstr ""
176
+
177
+ #: src/Tribe/App_Shop.php:127
178
+ msgid "Enable Community Events organizers to offer tickets to their events. You can set flexible payment and fee options. They can even check-in attendees to their events! All of this managed from the front-end of your site without ever needing to grant access to your admin"
179
+ msgstr ""
180
+
181
+ #: src/Tribe/App_Shop.php:128
182
+ msgctxt "Names of required plugins for Community Tickets"
183
+ msgid "Event Tickets Plus and Community Events"
184
+ msgstr ""
185
+
186
+ #: src/Tribe/App_Shop.php:135
187
+ msgid "Event Tickets Plus allows you to sell tickets to your events using WooCommerce, Shopp, WP eCommerce, or Easy Digital Downloads. Use it on your posts and pages, or add %1$sThe Events Calendar%2$s and sell tickets from your events listings."
188
+ msgstr ""
189
+
190
+ #: src/Tribe/App_Shop.php:145
191
+ msgid "The Eventbrite Tickets add-on allows you to create & sell tickets through The Events Calendar using the power of %1$sEventbrite%2$s. Whether you’re creating your ticket on the WordPress dashboard or importing the details of an already-existing event from %1$sEventbrite.com%2$s, this add-on brings the power of the Eventbrite API to your calendar."
192
+ msgstr ""
193
+
194
+ #: src/Tribe/App_Shop.php:154
195
+ msgid "With the Facebook Events add-on, imported events are manually or automagically created as entries in The Events Calendar. Basic event data along with venue and organizer are populated appropriately. No more entering information in two places, or having to recreate someone else's listing for a public event you want to include on your WordPress calendar."
196
+ msgstr ""
197
+
198
+ #: src/Tribe/App_Shop.php:158
199
+ msgid "iCal Importer"
200
+ msgstr ""
201
+
202
+ #: src/Tribe/App_Shop.php:160
203
+ msgid "The iCal Importer helps you keep your events calendar full of interesting events! You can import events from any website that publishes an iCal (aka ICS) feed and add them to your listings. The recurring import feature lets you keep your calendar brimming without manual oversight (though you can review every imported event if you like). Add filtering by keyword or geographic region and you can be sure that the kinds of events you get are the kinds you want."
204
+ msgstr ""
205
+
206
+ #: src/Tribe/Credits.php:31
207
+ msgid "This calendar is powered by %1$s."
208
+ msgstr ""
209
+
210
+ #: src/Tribe/Credits.php:55
211
+ msgid "Rate %1$sThe Events Calendar%2$s %3$s"
212
+ msgstr ""
213
+
214
+ #: src/Tribe/Credits.php:64
215
+ msgid "Rate %1$sEvent Tickets%2$s %3$s"
216
+ msgstr ""
217
+
218
+ #: src/Tribe/Field.php:209
219
+ msgid "Invalid field type specified"
220
+ msgstr ""
221
+
222
+ #: src/Tribe/Field.php:466
223
+ msgid "No radio options specified"
224
+ msgstr ""
225
+
226
+ #: src/Tribe/Field.php:502
227
+ msgid "No checkbox options specified"
228
+ msgstr ""
229
+
230
+ #: src/Tribe/Field.php:558
231
+ msgid "No select options specified"
232
+ msgstr ""
233
+
234
+ #: src/Tribe/Log/Admin.php:132
235
+ msgctxt "log selector"
236
+ msgid "None currently available"
237
+ msgstr ""
238
+
239
+ #: src/Tribe/Log/Admin.php:147
240
+ msgctxt "log engines"
241
+ msgid "None currently available"
242
+ msgstr ""
243
+
244
+ #: src/Tribe/Log/File_Logger.php:116
245
+ msgid "Default (uses temporary files)"
246
+ msgstr ""
247
+
248
+ #: src/Tribe/Log/Null_Logger.php:26
249
+ msgid "Null logger (will log nothing)"
250
+ msgstr ""
251
+
252
+ #: src/Tribe/Log.php:210
253
+ msgid "Cannot set %s as the current logging engine"
254
+ msgstr ""
255
+
256
+ #: src/Tribe/Log.php:309
257
+ msgid "Disabled"
258
+ msgstr ""
259
+
260
+ #: src/Tribe/Log.php:310
261
+ msgid "Only errors"
262
+ msgstr ""
263
+
264
+ #: src/Tribe/Log.php:311
265
+ msgid "Warnings and errors"
266
+ msgstr ""
267
+
268
+ #: src/Tribe/Log.php:312
269
+ msgid "Full debug (all events)"
270
+ msgstr ""
271
+
272
+ #: src/Tribe/PUE/Checker.php:308
273
+ msgid "License Key"
274
+ msgstr ""
275
+
276
+ #: src/Tribe/PUE/Checker.php:309
277
+ msgid "A valid license key is required for support and updates"
278
+ msgstr ""
279
+
280
+ #: src/Tribe/PUE/Checker.php:380
281
+ msgid "License key(s) updated."
282
+ msgstr ""
283
+
284
+ #: src/Tribe/PUE/Checker.php:419
285
+ msgid "unknown date"
286
+ msgstr ""
287
+
288
+ #: src/Tribe/PUE/Checker.php:422
289
+ msgid "Sorry, key validation server is not available."
290
+ msgstr ""
291
+
292
+ #: src/Tribe/PUE/Checker.php:432
293
+ msgid "Valid Key! Expires on %s"
294
+ msgstr ""
295
+
296
+ #: src/Tribe/PUE/Checker.php:437
297
+ msgid "Thanks for setting up a valid key, it will expire on %s"
298
+ msgstr ""
299
+
300
+ #: src/Tribe/PUE/Checker.php:445
301
+ msgid "Hmmm... something's wrong with this validator. Please contact %ssupport%s."
302
+ msgstr ""
303
+
304
+ #: src/Tribe/PUE/Checker.php:457
305
+ msgid "Sorry, there is a problem with your license key. You'll need to %scheck your license%s to have access to updates, downloads, and support."
306
+ msgstr ""
307
+
308
+ #: src/Tribe/Plugin_Download_Notice.php:68
309
+ msgid "To begin using %1$s, please install and activate the latest version(s) of %2$s."
310
+ msgstr ""
311
+
312
+ #: src/Tribe/Settings.php:148 src/Tribe/Settings.php:204
313
+ #: src/Tribe/Settings.php:205
314
+ msgid "Events"
315
+ msgstr ""
316
+
317
+ #: src/Tribe/Settings.php:216 src/Tribe/Settings.php:236
318
+ msgid "Events Settings"
319
+ msgstr ""
320
+
321
+ #: src/Tribe/Settings.php:217
322
+ msgid "Settings"
323
+ msgstr ""
324
+
325
+ #: src/Tribe/Settings.php:301
326
+ msgid "%s Settings"
327
+ msgstr ""
328
+
329
+ #: src/Tribe/Settings.php:315
330
+ msgid "You've requested a non-existent tab."
331
+ msgstr ""
332
+
333
+ #: src/Tribe/Settings.php:323
334
+ msgid "Save Changes"
335
+ msgstr ""
336
+
337
+ #: src/Tribe/Settings.php:371
338
+ msgid "You don't have permission to do that."
339
+ msgstr ""
340
+
341
+ #: src/Tribe/Settings.php:377
342
+ msgid "The request was sent insecurely."
343
+ msgstr ""
344
+
345
+ #: src/Tribe/Settings.php:383
346
+ msgid "The request wasn't sent from this tab."
347
+ msgstr ""
348
+
349
+ #: src/Tribe/Settings.php:550
350
+ msgid "Your form had the following errors:"
351
+ msgstr ""
352
+
353
+ #: src/Tribe/Settings.php:560
354
+ msgid "None of your settings were saved. Please try again."
355
+ msgstr ""
356
+
357
+ #: src/Tribe/Settings.php:561
358
+ msgid "The above setting was not saved. Other settings were successfully saved."
359
+ msgid_plural "The above settings were not saved. Other settings were successfully saved."
360
+ msgstr[0] ""
361
+ msgstr[1] ""
362
+
363
+ #: src/Tribe/Settings.php:583
364
+ msgid "Settings saved."
365
+ msgstr ""
366
+
367
+ #: src/Tribe/Settings_Manager.php:55
368
+ msgid "General"
369
+ msgstr ""
370
+
371
+ #: src/Tribe/Settings_Manager.php:56
372
+ msgid "Display"
373
+ msgstr ""
374
+
375
+ #: src/Tribe/Settings_Manager.php:62 src/Tribe/Settings_Manager.php:289
376
+ msgid "Help"
377
+ msgstr ""
378
+
379
+ #: src/Tribe/Settings_Manager.php:229
380
+ msgid "Network"
381
+ msgstr ""
382
+
383
+ #: src/Tribe/Settings_Manager.php:263
384
+ #: src/admin-views/tribe-options-licenses.php:46
385
+ msgid "Licenses"
386
+ msgstr ""
387
+
388
+ #: src/Tribe/Settings_Tab.php:222
389
+ msgid "There are no fields setup for this tab yet."
390
+ msgstr ""
391
+
392
+ #: src/Tribe/Support/Template_Checker_Report.php:78
393
+ msgid "No notable changes detected"
394
+ msgstr ""
395
+
396
+ #: src/Tribe/Support/Template_Checker_Report.php:82
397
+ msgid "Templates introduced or updated with this release (%s):"
398
+ msgstr ""
399
+
400
+ #: src/Tribe/Support/Template_Checker_Report.php:92
401
+ msgid "Existing theme overrides that may need revision:"
402
+ msgstr ""
403
+
404
+ #: src/Tribe/Support/Template_Checker_Report.php:96
405
+ msgid "version data missing from override"
406
+ msgstr ""
407
+
408
+ #: src/Tribe/Support/Template_Checker_Report.php:97
409
+ msgid "based on %s version"
410
+ msgstr ""
411
+
412
+ #: src/Tribe/Support/Template_Checker_Report.php:113
413
+ msgid "No notable template changes detected."
414
+ msgstr ""
415
+
416
+ #: src/Tribe/Support/Template_Checker_Report.php:115
417
+ msgid "Information about recent template changes and potentially impacted template overrides is provided below."
418
+ msgstr ""
419
+
420
+ #: src/Tribe/Support.php:159
421
+ msgid "English"
422
+ msgstr ""
423
+
424
+ #: src/Tribe/Support.php:176 src/Tribe/Support.php:177
425
+ msgid "Unknown or not set"
426
+ msgstr ""
427
+
428
+ #: src/Tribe/Support.php:187
429
+ msgid "Rewrite rules were purged on load of this help page. Chances are there is a rewrite rule flush occurring in a plugin or theme!"
430
+ msgstr ""
431
+
432
+ #: src/Tribe/Validate.php:76 src/Tribe/Validate.php:117
433
+ msgid "Invalid or incomplete field passed"
434
+ msgstr ""
435
+
436
+ #: src/Tribe/Validate.php:77 src/Tribe/Validate.php:112
437
+ #: src/Tribe/Validate.php:118
438
+ msgid "Field ID:"
439
+ msgstr ""
440
+
441
+ #: src/Tribe/Validate.php:111
442
+ msgid "Non-existant field validation function passed"
443
+ msgstr ""
444
+
445
+ #: src/Tribe/Validate.php:112
446
+ msgctxt "non-existant function name passed for field validation"
447
+ msgid "with function name:"
448
+ msgstr ""
449
+
450
+ #: src/Tribe/Validate.php:135 src/Tribe/Validate.php:151
451
+ msgid "%s must contain numbers and letters only"
452
+ msgstr ""
453
+
454
+ #: src/Tribe/Validate.php:167
455
+ msgid "%s must contain numbers, letters and dots only"
456
+ msgstr ""
457
+
458
+ #: src/Tribe/Validate.php:183
459
+ msgid "%s must contain numbers, letters, dashes and undescores only"
460
+ msgstr ""
461
+
462
+ #: src/Tribe/Validate.php:197 src/Tribe/Validate.php:225
463
+ msgid "%s must be a positive number."
464
+ msgstr ""
465
+
466
+ #: src/Tribe/Validate.php:211
467
+ msgid "%s must be a positive number or percent."
468
+ msgstr ""
469
+
470
+ #: src/Tribe/Validate.php:240
471
+ msgid "%s must be a valid slug (numbers, letters, dashes, and underscores)."
472
+ msgstr ""
473
+
474
+ #: src/Tribe/Validate.php:255
475
+ msgid "%s must be a valid absolute URL."
476
+ msgstr ""
477
+
478
+ #: src/Tribe/Validate.php:271 src/Tribe/Validate.php:288
479
+ #: src/Tribe/Validate.php:310
480
+ msgid "%s must have a value that's part of its options."
481
+ msgstr ""
482
+
483
+ #: src/Tribe/Validate.php:324
484
+ msgid "Comparison validation failed because no comparison value was provided, for field %s"
485
+ msgstr ""
486
+
487
+ #: src/Tribe/Validate.php:331
488
+ msgid "%s cannot be the same as %s."
489
+ msgstr ""
490
+
491
+ #: src/Tribe/Validate.php:333
492
+ msgid "%s cannot be a duplicate"
493
+ msgstr ""
494
+
495
+ #: src/Tribe/Validate.php:349
496
+ msgid "%s must be a number or percentage."
497
+ msgstr ""
498
+
499
+ #: src/Tribe/Validate.php:403
500
+ msgid "%s must be a number between 0 and 21."
501
+ msgstr ""
502
+
503
+ #: src/Tribe/Validate.php:419
504
+ msgid "%s must consist of letters, numbers, dashes, apostrophes, and spaces only."
505
+ msgstr ""
506
+
507
+ #: src/Tribe/Validate.php:435
508
+ msgid "%s must consist of letters, spaces, apostrophes, and dashes."
509
+ msgstr ""
510
+
511
+ #: src/Tribe/Validate.php:449
512
+ msgid "%s must consist of 5 numbers."
513
+ msgstr ""
514
+
515
+ #: src/Tribe/Validate.php:463
516
+ msgid "%s must be a phone number."
517
+ msgstr ""
518
+
519
+ #: src/Tribe/Validate.php:479
520
+ msgid "Country List must be formatted as one country per line in the following format: <br>US, United States <br> UK, United Kingdom."
521
+ msgstr ""
522
+
523
+ #: src/Tribe/View_Helpers.php:26 src/Tribe/View_Helpers.php:45
524
+ msgid "Select a Country:"
525
+ msgstr ""
526
+
527
+ #: src/Tribe/View_Helpers.php:46
528
+ msgid "United States"
529
+ msgstr ""
530
+
531
+ #: src/Tribe/View_Helpers.php:47
532
+ msgid "Afghanistan"
533
+ msgstr ""
534
+
535
+ #: src/Tribe/View_Helpers.php:48
536
+ msgid "Albania"
537
+ msgstr ""
538
+
539
+ #: src/Tribe/View_Helpers.php:49
540
+ msgid "Algeria"
541
+ msgstr ""
542
+
543
+ #: src/Tribe/View_Helpers.php:50
544
+ msgid "American Samoa"
545
+ msgstr ""
546
+
547
+ #: src/Tribe/View_Helpers.php:51
548
+ msgid "Andorra"
549
+ msgstr ""
550
+
551
+ #: src/Tribe/View_Helpers.php:52
552
+ msgid "Angola"
553
+ msgstr ""
554
+
555
+ #: src/Tribe/View_Helpers.php:53
556
+ msgid "Anguilla"
557
+ msgstr ""
558
+
559
+ #: src/Tribe/View_Helpers.php:54
560
+ msgid "Antarctica"
561
+ msgstr ""
562
+
563
+ #: src/Tribe/View_Helpers.php:55
564
+ msgid "Antigua And Barbuda"
565
+ msgstr ""
566
+
567
+ #: src/Tribe/View_Helpers.php:56
568
+ msgid "Argentina"
569
+ msgstr ""
570
+
571
+ #: src/Tribe/View_Helpers.php:57
572
+ msgid "Armenia"
573
+ msgstr ""
574
+
575
+ #: src/Tribe/View_Helpers.php:58
576
+ msgid "Aruba"
577
+ msgstr ""
578
+
579
+ #: src/Tribe/View_Helpers.php:59
580
+ msgid "Australia"
581
+ msgstr ""
582
+
583
+ #: src/Tribe/View_Helpers.php:60
584
+ msgid "Austria"
585
+ msgstr ""
586
+
587
+ #: src/Tribe/View_Helpers.php:61
588
+ msgid "Azerbaijan"
589
+ msgstr ""
590
+
591
+ #: src/Tribe/View_Helpers.php:62
592
+ msgid "Bahamas"
593
+ msgstr ""
594
+
595
+ #: src/Tribe/View_Helpers.php:63
596
+ msgid "Bahrain"
597
+ msgstr ""
598
+
599
+ #: src/Tribe/View_Helpers.php:64
600
+ msgid "Bangladesh"
601
+ msgstr ""
602
+
603
+ #: src/Tribe/View_Helpers.php:65
604
+ msgid "Barbados"
605
+ msgstr ""
606
+
607
+ #: src/Tribe/View_Helpers.php:66
608
+ msgid "Belarus"
609
+ msgstr ""
610
+
611
+ #: src/Tribe/View_Helpers.php:67
612
+ msgid "Belgium"
613
+ msgstr ""
614
+
615
+ #: src/Tribe/View_Helpers.php:68
616
+ msgid "Belize"
617
+ msgstr ""
618
+
619
+ #: src/Tribe/View_Helpers.php:69
620
+ msgid "Benin"
621
+ msgstr ""
622
+
623
+ #: src/Tribe/View_Helpers.php:70
624
+ msgid "Bermuda"
625
+ msgstr ""
626
+
627
+ #: src/Tribe/View_Helpers.php:71
628
+ msgid "Bhutan"
629
+ msgstr ""
630
+
631
+ #: src/Tribe/View_Helpers.php:72
632
+ msgid "Bolivia"
633
+ msgstr ""
634
+
635
+ #: src/Tribe/View_Helpers.php:73
636
+ msgid "Bosnia And Herzegowina"
637
+ msgstr ""
638
+
639
+ #: src/Tribe/View_Helpers.php:74
640
+ msgid "Botswana"
641
+ msgstr ""
642
+
643
+ #: src/Tribe/View_Helpers.php:75
644
+ msgid "Bouvet Island"
645
+ msgstr ""
646
+
647
+ #: src/Tribe/View_Helpers.php:76
648
+ msgid "Brazil"
649
+ msgstr ""
650
+
651
+ #: src/Tribe/View_Helpers.php:77
652
+ msgid "British Indian Ocean Territory"
653
+ msgstr ""
654
+
655
+ #: src/Tribe/View_Helpers.php:78
656
+ msgid "Brunei Darussalam"
657
+ msgstr ""
658
+
659
+ #: src/Tribe/View_Helpers.php:79
660
+ msgid "Bulgaria"
661
+ msgstr ""
662
+
663
+ #: src/Tribe/View_Helpers.php:80
664
+ msgid "Burkina Faso"
665
+ msgstr ""
666
+
667
+ #: src/Tribe/View_Helpers.php:81
668
+ msgid "Burundi"
669
+ msgstr ""
670
+
671
+ #: src/Tribe/View_Helpers.php:82
672
+ msgid "Cambodia"
673
+ msgstr ""
674
+
675
+ #: src/Tribe/View_Helpers.php:83
676
+ msgid "Cameroon"
677
+ msgstr ""
678
+
679
+ #: src/Tribe/View_Helpers.php:84
680
+ msgid "Canada"
681
+ msgstr ""
682
+
683
+ #: src/Tribe/View_Helpers.php:85
684
+ msgid "Cape Verde"
685
+ msgstr ""
686
+
687
+ #: src/Tribe/View_Helpers.php:86
688
+ msgid "Cayman Islands"
689
+ msgstr ""
690
+
691
+ #: src/Tribe/View_Helpers.php:87
692
+ msgid "Central African Republic"
693
+ msgstr ""
694
+
695
+ #: src/Tribe/View_Helpers.php:88
696
+ msgid "Chad"
697
+ msgstr ""
698
+
699
+ #: src/Tribe/View_Helpers.php:89
700
+ msgid "Chile"
701
+ msgstr ""
702
+
703
+ #: src/Tribe/View_Helpers.php:90
704
+ msgid "China"
705
+ msgstr ""
706
+
707
+ #: src/Tribe/View_Helpers.php:91
708
+ msgid "Christmas Island"
709
+ msgstr ""
710
+
711
+ #: src/Tribe/View_Helpers.php:92
712
+ msgid "Cocos (Keeling) Islands"
713
+ msgstr ""
714
+
715
+ #: src/Tribe/View_Helpers.php:93
716
+ msgid "Colombia"
717
+ msgstr ""
718
+
719
+ #: src/Tribe/View_Helpers.php:94
720
+ msgid "Comoros"
721
+ msgstr ""
722
+
723
+ #: src/Tribe/View_Helpers.php:95
724
+ msgid "Congo"
725
+ msgstr ""
726
+
727
+ #: src/Tribe/View_Helpers.php:96
728
+ msgid "Congo, The Democratic Republic Of The"
729
+ msgstr ""
730
+
731
+ #: src/Tribe/View_Helpers.php:97
732
+ msgid "Cook Islands"
733
+ msgstr ""
734
+
735
+ #: src/Tribe/View_Helpers.php:98
736
+ msgid "Costa Rica"
737
+ msgstr ""
738
+
739
+ #: src/Tribe/View_Helpers.php:99
740
+ msgid "Cote D'Ivoire"
741
+ msgstr ""
742
+
743
+ #: src/Tribe/View_Helpers.php:100
744
+ msgid "Croatia (Local Name: Hrvatska)"
745
+ msgstr ""
746
+
747
+ #: src/Tribe/View_Helpers.php:101
748
+ msgid "Cuba"
749
+ msgstr ""
750
+
751
+ #: src/Tribe/View_Helpers.php:102
752
+ msgid "Cyprus"
753
+ msgstr ""
754
+
755
+ #: src/Tribe/View_Helpers.php:103
756
+ msgid "Czech Republic"
757
+ msgstr ""
758
+
759
+ #: src/Tribe/View_Helpers.php:104
760
+ msgid "Denmark"
761
+ msgstr ""
762
+
763
+ #: src/Tribe/View_Helpers.php:105
764
+ msgid "Djibouti"
765
+ msgstr ""
766
+
767
+ #: src/Tribe/View_Helpers.php:106
768
+ msgid "Dominica"
769
+ msgstr ""
770
+
771
+ #: src/Tribe/View_Helpers.php:107
772
+ msgid "Dominican Republic"
773
+ msgstr ""
774
+
775
+ #: src/Tribe/View_Helpers.php:108
776
+ msgid "East Timor"
777
+ msgstr ""
778
+
779
+ #: src/Tribe/View_Helpers.php:109
780
+ msgid "Ecuador"
781
+ msgstr ""
782
+
783
+ #: src/Tribe/View_Helpers.php:110
784
+ msgid "Egypt"
785
+ msgstr ""
786
+
787
+ #: src/Tribe/View_Helpers.php:111
788
+ msgid "El Salvador"
789
+ msgstr ""
790
+
791
+ #: src/Tribe/View_Helpers.php:112
792
+ msgid "Equatorial Guinea"
793
+ msgstr ""
794
+
795
+ #: src/Tribe/View_Helpers.php:113
796
+ msgid "Eritrea"
797
+ msgstr ""
798
+
799
+ #: src/Tribe/View_Helpers.php:114
800
+ msgid "Estonia"
801
+ msgstr ""
802
+
803
+ #: src/Tribe/View_Helpers.php:115
804
+ msgid "Ethiopia"
805
+ msgstr ""
806
+
807
+ #: src/Tribe/View_Helpers.php:116
808
+ msgid "Falkland Islands (Malvinas)"
809
+ msgstr ""
810
+
811
+ #: src/Tribe/View_Helpers.php:117
812
+ msgid "Faroe Islands"
813
+ msgstr ""
814
+
815
+ #: src/Tribe/View_Helpers.php:118
816
+ msgid "Fiji"
817
+ msgstr ""
818
+
819
+ #: src/Tribe/View_Helpers.php:119
820
+ msgid "Finland"
821
+ msgstr ""
822
+
823
+ #: src/Tribe/View_Helpers.php:120
824
+ msgid "France"
825
+ msgstr ""
826
+
827
+ #: src/Tribe/View_Helpers.php:121
828
+ msgid "France, Metropolitan"
829
+ msgstr ""
830
+
831
+ #: src/Tribe/View_Helpers.php:122
832
+ msgid "French Guiana"
833
+ msgstr ""
834
+
835
+ #: src/Tribe/View_Helpers.php:123
836
+ msgid "French Polynesia"
837
+ msgstr ""
838
+
839
+ #: src/Tribe/View_Helpers.php:124
840
+ msgid "French Southern Territories"
841
+ msgstr ""
842
+
843
+ #: src/Tribe/View_Helpers.php:125
844
+ msgid "Gabon"
845
+ msgstr ""
846
+
847
+ #: src/Tribe/View_Helpers.php:126
848
+ msgid "Gambia"
849
+ msgstr ""
850
+
851
+ #: src/Tribe/View_Helpers.php:127 src/Tribe/View_Helpers.php:326
852
+ msgid "Georgia"
853
+ msgstr ""
854
+
855
+ #: src/Tribe/View_Helpers.php:128
856
+ msgid "Germany"
857
+ msgstr ""
858
+
859
+ #: src/Tribe/View_Helpers.php:129
860
+ msgid "Ghana"
861
+ msgstr ""
862
+
863
+ #: src/Tribe/View_Helpers.php:130
864
+ msgid "Gibraltar"
865
+ msgstr ""
866
+
867
+ #: src/Tribe/View_Helpers.php:131
868
+ msgid "Greece"
869
+ msgstr ""
870
+
871
+ #: src/Tribe/View_Helpers.php:132
872
+ msgid "Greenland"
873
+ msgstr ""
874
+
875
+ #: src/Tribe/View_Helpers.php:133
876
+ msgid "Grenada"
877
+ msgstr ""
878
+
879
+ #: src/Tribe/View_Helpers.php:134
880
+ msgid "Guadeloupe"
881
+ msgstr ""
882
+
883
+ #: src/Tribe/View_Helpers.php:135
884
+ msgid "Guam"
885
+ msgstr ""
886
+
887
+ #: src/Tribe/View_Helpers.php:136
888
+ msgid "Guatemala"
889
+ msgstr ""
890
+
891
+ #: src/Tribe/View_Helpers.php:137
892
+ msgid "Guinea"
893
+ msgstr ""
894
+
895
+ #: src/Tribe/View_Helpers.php:138
896
+ msgid "Guinea-Bissau"
897
+ msgstr ""
898
+
899
+ #: src/Tribe/View_Helpers.php:139
900
+ msgid "Guyana"
901
+ msgstr ""
902
+
903
+ #: src/Tribe/View_Helpers.php:140
904
+ msgid "Haiti"
905
+ msgstr ""
906
+
907
+ #: src/Tribe/View_Helpers.php:141
908
+ msgid "Heard And Mc Donald Islands"
909
+ msgstr ""
910
+
911
+ #: src/Tribe/View_Helpers.php:142
912
+ msgid "Holy See (Vatican City State)"
913
+ msgstr ""
914
+
915
+ #: src/Tribe/View_Helpers.php:143
916
+ msgid "Honduras"
917
+ msgstr ""
918
+
919
+ #: src/Tribe/View_Helpers.php:144
920
+ msgid "Hong Kong"
921
+ msgstr ""
922
+
923
+ #: src/Tribe/View_Helpers.php:145
924
+ msgid "Hungary"
925
+ msgstr ""
926
+
927
+ #: src/Tribe/View_Helpers.php:146
928
+ msgid "Iceland"
929
+ msgstr ""
930
+
931
+ #: src/Tribe/View_Helpers.php:147
932
+ msgid "India"
933
+ msgstr ""
934
+
935
+ #: src/Tribe/View_Helpers.php:148
936
+ msgid "Indonesia"
937
+ msgstr ""
938
+
939
+ #: src/Tribe/View_Helpers.php:149
940
+ msgid "Iran (Islamic Republic Of)"
941
+ msgstr ""
942
+
943
+ #: src/Tribe/View_Helpers.php:150
944
+ msgid "Iraq"
945
+ msgstr ""
946
+
947
+ #: src/Tribe/View_Helpers.php:151
948
+ msgid "Ireland"
949
+ msgstr ""
950
+
951
+ #: src/Tribe/View_Helpers.php:152
952
+ msgid "Israel"
953
+ msgstr ""
954
+
955
+ #: src/Tribe/View_Helpers.php:153
956
+ msgid "Italy"
957
+ msgstr ""
958
+
959
+ #: src/Tribe/View_Helpers.php:154
960
+ msgid "Jamaica"
961
+ msgstr ""
962
+
963
+ #: src/Tribe/View_Helpers.php:155
964
+ msgid "Japan"
965
+ msgstr ""
966
+
967
+ #: src/Tribe/View_Helpers.php:156
968
+ msgid "Jordan"
969
+ msgstr ""
970
+
971
+ #: src/Tribe/View_Helpers.php:157
972
+ msgid "Kazakhstan"
973
+ msgstr ""
974
+
975
+ #: src/Tribe/View_Helpers.php:158
976
+ msgid "Kenya"
977
+ msgstr ""
978
+
979
+ #: src/Tribe/View_Helpers.php:159
980
+ msgid "Kiribati"
981
+ msgstr ""
982
+
983
+ #: src/Tribe/View_Helpers.php:160
984
+ msgid "Korea, Democratic People's Republic Of"
985
+ msgstr ""
986
+
987
+ #: src/Tribe/View_Helpers.php:161
988
+ msgid "Korea, Republic Of"
989
+ msgstr ""
990
+
991
+ #: src/Tribe/View_Helpers.php:162
992
+ msgid "Kuwait"
993
+ msgstr ""
994
+
995
+ #: src/Tribe/View_Helpers.php:163
996
+ msgid "Kyrgyzstan"
997
+ msgstr ""
998
+
999
+ #: src/Tribe/View_Helpers.php:164
1000
+ msgid "Lao People's Democratic Republic"
1001
+ msgstr ""
1002
+
1003
+ #: src/Tribe/View_Helpers.php:165
1004
+ msgid "Latvia"
1005
+ msgstr ""
1006
+
1007
+ #: src/Tribe/View_Helpers.php:166
1008
+ msgid "Lebanon"
1009
+ msgstr ""
1010
+
1011
+ #: src/Tribe/View_Helpers.php:167
1012
+ msgid "Lesotho"
1013
+ msgstr ""
1014
+
1015
+ #: src/Tribe/View_Helpers.php:168
1016
+ msgid "Liberia"
1017
+ msgstr ""
1018
+
1019
+ #: src/Tribe/View_Helpers.php:169
1020
+ msgid "Libya"
1021
+ msgstr ""
1022
+
1023
+ #: src/Tribe/View_Helpers.php:170
1024
+ msgid "Liechtenstein"
1025
+ msgstr ""
1026
+
1027
+ #: src/Tribe/View_Helpers.php:171
1028
+ msgid "Lithuania"
1029
+ msgstr ""
1030
+
1031
+ #: src/Tribe/View_Helpers.php:172
1032
+ msgid "Luxembourg"
1033
+ msgstr ""
1034
+
1035
+ #: src/Tribe/View_Helpers.php:173
1036
+ msgid "Macau"
1037
+ msgstr ""
1038
+
1039
+ #: src/Tribe/View_Helpers.php:174
1040
+ msgid "Macedonia"
1041
+ msgstr ""
1042
+
1043
+ #: src/Tribe/View_Helpers.php:175
1044
+ msgid "Madagascar"
1045
+ msgstr ""
1046
+
1047
+ #: src/Tribe/View_Helpers.php:176
1048
+ msgid "Malawi"
1049
+ msgstr ""
1050
+
1051
+ #: src/Tribe/View_Helpers.php:177
1052
+ msgid "Malaysia"
1053
+ msgstr ""
1054
+
1055
+ #: src/Tribe/View_Helpers.php:178
1056
+ msgid "Maldives"
1057
+ msgstr ""
1058
+
1059
+ #: src/Tribe/View_Helpers.php:179
1060
+ msgid "Mali"
1061
+ msgstr ""
1062
+
1063
+ #: src/Tribe/View_Helpers.php:180
1064
+ msgid "Malta"
1065
+ msgstr ""
1066
+
1067
+ #: src/Tribe/View_Helpers.php:181
1068
+ msgid "Marshall Islands"
1069
+ msgstr ""
1070
+
1071
+ #: src/Tribe/View_Helpers.php:182
1072
+ msgid "Martinique"
1073
+ msgstr ""
1074
+
1075
+ #: src/Tribe/View_Helpers.php:183
1076
+ msgid "Mauritania"
1077
+ msgstr ""
1078
+
1079
+ #: src/Tribe/View_Helpers.php:184
1080
+ msgid "Mauritius"
1081
+ msgstr ""
1082
+
1083
+ #: src/Tribe/View_Helpers.php:185
1084
+ msgid "Mayotte"
1085
+ msgstr ""
1086
+
1087
+ #: src/Tribe/View_Helpers.php:186
1088
+ msgid "Mexico"
1089
+ msgstr ""
1090
+
1091
+ #: src/Tribe/View_Helpers.php:187
1092
+ msgid "Micronesia, Federated States Of"
1093
+ msgstr ""
1094
+
1095
+ #: src/Tribe/View_Helpers.php:188
1096
+ msgid "Moldova, Republic Of"
1097
+ msgstr ""
1098
+
1099
+ #: src/Tribe/View_Helpers.php:189
1100
+ msgid "Monaco"
1101
+ msgstr ""
1102
+
1103
+ #: src/Tribe/View_Helpers.php:190
1104
+ msgid "Mongolia"
1105
+ msgstr ""
1106
+
1107
+ #: src/Tribe/View_Helpers.php:191
1108
+ msgid "Montenegro"
1109
+ msgstr ""
1110
+
1111
+ #: src/Tribe/View_Helpers.php:192
1112
+ msgid "Montserrat"
1113
+ msgstr ""
1114
+
1115
+ #: src/Tribe/View_Helpers.php:193
1116
+ msgid "Morocco"
1117
+ msgstr ""
1118
+
1119
+ #: src/Tribe/View_Helpers.php:194
1120
+ msgid "Mozambique"
1121
+ msgstr ""
1122
+
1123
+ #: src/Tribe/View_Helpers.php:195
1124
+ msgid "Myanmar"
1125
+ msgstr ""
1126
+
1127
+ #: src/Tribe/View_Helpers.php:196
1128
+ msgid "Namibia"
1129
+ msgstr ""
1130
+
1131
+ #: src/Tribe/View_Helpers.php:197
1132
+ msgid "Nauru"
1133
+ msgstr ""
1134
+
1135
+ #: src/Tribe/View_Helpers.php:198
1136
+ msgid "Nepal"
1137
+ msgstr ""
1138
+
1139
+ #: src/Tribe/View_Helpers.php:199
1140
+ msgid "Netherlands"
1141
+ msgstr ""
1142
+
1143
+ #: src/Tribe/View_Helpers.php:200
1144
+ msgid "Netherlands Antilles"
1145
+ msgstr ""
1146
+
1147
+ #: src/Tribe/View_Helpers.php:201
1148
+ msgid "New Caledonia"
1149
+ msgstr ""
1150
+
1151
+ #: src/Tribe/View_Helpers.php:202
1152
+ msgid "New Zealand"
1153
+ msgstr ""
1154
+
1155
+ #: src/Tribe/View_Helpers.php:203
1156
+ msgid "Nicaragua"
1157
+ msgstr ""
1158
+
1159
+ #: src/Tribe/View_Helpers.php:204
1160
+ msgid "Niger"
1161
+ msgstr ""
1162
+
1163
+ #: src/Tribe/View_Helpers.php:205
1164
+ msgid "Nigeria"
1165
+ msgstr ""
1166
+
1167
+ #: src/Tribe/View_Helpers.php:206
1168
+ msgid "Niue"
1169
+ msgstr ""
1170
+
1171
+ #: src/Tribe/View_Helpers.php:207
1172
+ msgid "Norfolk Island"
1173
+ msgstr ""
1174
+
1175
+ #: src/Tribe/View_Helpers.php:208
1176
+ msgid "Northern Mariana Islands"
1177
+ msgstr ""
1178
+
1179
+ #: src/Tribe/View_Helpers.php:209
1180
+ msgid "Norway"
1181
+ msgstr ""
1182
+
1183
+ #: src/Tribe/View_Helpers.php:210
1184
+ msgid "Oman"
1185
+ msgstr ""
1186
+
1187
+ #: src/Tribe/View_Helpers.php:211
1188
+ msgid "Pakistan"
1189
+ msgstr ""
1190
+
1191
+ #: src/Tribe/View_Helpers.php:212
1192
+ msgid "Palau"
1193
+ msgstr ""
1194
+
1195
+ #: src/Tribe/View_Helpers.php:213
1196
+ msgid "Panama"
1197
+ msgstr ""
1198
+
1199
+ #: src/Tribe/View_Helpers.php:214
1200
+ msgid "Papua New Guinea"
1201
+ msgstr ""
1202
+
1203
+ #: src/Tribe/View_Helpers.php:215
1204
+ msgid "Paraguay"
1205
+ msgstr ""
1206
+
1207
+ #: src/Tribe/View_Helpers.php:216
1208
+ msgid "Peru"
1209
+ msgstr ""
1210
+
1211
+ #: src/Tribe/View_Helpers.php:217
1212
+ msgid "Philippines"
1213
+ msgstr ""
1214
+
1215
+ #: src/Tribe/View_Helpers.php:218
1216
+ msgid "Pitcairn"
1217
+ msgstr ""
1218
+
1219
+ #: src/Tribe/View_Helpers.php:219
1220
+ msgid "Poland"
1221
+ msgstr ""
1222
+
1223
+ #: src/Tribe/View_Helpers.php:220
1224
+ msgid "Portugal"
1225
+ msgstr ""
1226
+
1227
+ #: src/Tribe/View_Helpers.php:221
1228
+ msgid "Puerto Rico"
1229
+ msgstr ""
1230
+
1231
+ #: src/Tribe/View_Helpers.php:222
1232
+ msgid "Qatar"
1233
+ msgstr ""
1234
+
1235
+ #: src/Tribe/View_Helpers.php:223
1236
+ msgid "Reunion"
1237
+ msgstr ""
1238
+
1239
+ #: src/Tribe/View_Helpers.php:224
1240
+ msgid "Romania"
1241
+ msgstr ""
1242
+
1243
+ #: src/Tribe/View_Helpers.php:225
1244
+ msgid "Russian Federation"
1245
+ msgstr ""
1246
+
1247
+ #: src/Tribe/View_Helpers.php:226
1248
+ msgid "Rwanda"
1249
+ msgstr ""
1250
+
1251
+ #: src/Tribe/View_Helpers.php:227
1252
+ msgid "Saint Kitts And Nevis"
1253
+ msgstr ""
1254
+
1255
+ #: src/Tribe/View_Helpers.php:228
1256
+ msgid "Saint Lucia"
1257
+ msgstr ""
1258
+
1259
+ #: src/Tribe/View_Helpers.php:229
1260
+ msgid "Saint Vincent And The Grenadines"
1261
+ msgstr ""
1262
+
1263
+ #: src/Tribe/View_Helpers.php:230
1264
+ msgid "Samoa"
1265
+ msgstr ""
1266
+
1267
+ #: src/Tribe/View_Helpers.php:231
1268
+ msgid "San Marino"
1269
+ msgstr ""
1270
+
1271
+ #: src/Tribe/View_Helpers.php:232
1272
+ msgid "Sao Tome And Principe"
1273
+ msgstr ""
1274
+
1275
+ #: src/Tribe/View_Helpers.php:233
1276
+ msgid "Saudi Arabia"
1277
+ msgstr ""
1278
+
1279
+ #: src/Tribe/View_Helpers.php:234
1280
+ msgid "Senegal"
1281
+ msgstr ""
1282
+
1283
+ #: src/Tribe/View_Helpers.php:235
1284
+ msgid "Serbia"
1285
+ msgstr ""
1286
+
1287
+ #: src/Tribe/View_Helpers.php:236
1288
+ msgid "Seychelles"
1289
+ msgstr ""
1290
+
1291
+ #: src/Tribe/View_Helpers.php:237
1292
+ msgid "Sierra Leone"
1293
+ msgstr ""
1294
+
1295
+ #: src/Tribe/View_Helpers.php:238
1296
+ msgid "Singapore"
1297
+ msgstr ""
1298
+
1299
+ #: src/Tribe/View_Helpers.php:239
1300
+ msgid "Slovakia (Slovak Republic)"
1301
+ msgstr ""
1302
+
1303
+ #: src/Tribe/View_Helpers.php:240
1304
+ msgid "Slovenia"
1305
+ msgstr ""
1306
+
1307
+ #: src/Tribe/View_Helpers.php:241
1308
+ msgid "Solomon Islands"
1309
+ msgstr ""
1310
+
1311
+ #: src/Tribe/View_Helpers.php:242
1312
+ msgid "Somalia"
1313
+ msgstr ""
1314
+
1315
+ #: src/Tribe/View_Helpers.php:243
1316
+ msgid "South Africa"
1317
+ msgstr ""
1318
+
1319
+ #: src/Tribe/View_Helpers.php:244
1320
+ msgid "South Georgia, South Sandwich Islands"
1321
+ msgstr ""
1322
+
1323
+ #: src/Tribe/View_Helpers.php:245
1324
+ msgid "Spain"
1325
+ msgstr ""
1326
+
1327
+ #: src/Tribe/View_Helpers.php:246
1328
+ msgid "Sri Lanka"
1329
+ msgstr ""
1330
+
1331
+ #: src/Tribe/View_Helpers.php:247
1332
+ msgid "St. Helena"
1333
+ msgstr ""
1334
+
1335
+ #: src/Tribe/View_Helpers.php:248
1336
+ msgid "St. Pierre And Miquelon"
1337
+ msgstr ""
1338
+
1339
+ #: src/Tribe/View_Helpers.php:249
1340
+ msgid "Sudan"
1341
+ msgstr ""
1342
+
1343
+ #: src/Tribe/View_Helpers.php:250
1344
+ msgid "Suriname"
1345
+ msgstr ""
1346
+
1347
+ #: src/Tribe/View_Helpers.php:251
1348
+ msgid "Svalbard And Jan Mayen Islands"
1349
+ msgstr ""
1350
+
1351
+ #: src/Tribe/View_Helpers.php:252
1352
+ msgid "Swaziland"
1353
+ msgstr ""
1354
+
1355
+ #: src/Tribe/View_Helpers.php:253
1356
+ msgid "Sweden"
1357
+ msgstr ""
1358
+
1359
+ #: src/Tribe/View_Helpers.php:254
1360
+ msgid "Switzerland"
1361
+ msgstr ""
1362
+
1363
+ #: src/Tribe/View_Helpers.php:255
1364
+ msgid "Syrian Arab Republic"
1365
+ msgstr ""
1366
+
1367
+ #: src/Tribe/View_Helpers.php:256
1368
+ msgid "Taiwan"
1369
+ msgstr ""
1370
+
1371
+ #: src/Tribe/View_Helpers.php:257
1372
+ msgid "Tajikistan"
1373
+ msgstr ""
1374
+
1375
+ #: src/Tribe/View_Helpers.php:258
1376
+ msgid "Tanzania, United Republic Of"
1377
+ msgstr ""
1378
+
1379
+ #: src/Tribe/View_Helpers.php:259
1380
+ msgid "Thailand"
1381
+ msgstr ""
1382
+
1383
+ #: src/Tribe/View_Helpers.php:260
1384
+ msgid "Togo"
1385
+ msgstr ""
1386
+
1387
+ #: src/Tribe/View_Helpers.php:261
1388
+ msgid "Tokelau"
1389
+ msgstr ""
1390
+
1391
+ #: src/Tribe/View_Helpers.php:262
1392
+ msgid "Tonga"
1393
+ msgstr ""
1394
+
1395
+ #: src/Tribe/View_Helpers.php:263
1396
+ msgid "Trinidad And Tobago"
1397
+ msgstr ""
1398
+
1399
+ #: src/Tribe/View_Helpers.php:264
1400
+ msgid "Tunisia"
1401
+ msgstr ""
1402
+
1403
+ #: src/Tribe/View_Helpers.php:265
1404
+ msgid "Turkey"
1405
+ msgstr ""
1406
+
1407
+ #: src/Tribe/View_Helpers.php:266
1408
+ msgid "Turkmenistan"
1409
+ msgstr ""
1410
+
1411
+ #: src/Tribe/View_Helpers.php:267
1412
+ msgid "Turks And Caicos Islands"
1413
+ msgstr ""
1414
+
1415
+ #: src/Tribe/View_Helpers.php:268
1416
+ msgid "Tuvalu"
1417
+ msgstr ""
1418
+
1419
+ #: src/Tribe/View_Helpers.php:269
1420
+ msgid "Uganda"
1421
+ msgstr ""
1422
+
1423
+ #: src/Tribe/View_Helpers.php:270
1424
+ msgid "Ukraine"
1425
+ msgstr ""
1426
+
1427
+ #: src/Tribe/View_Helpers.php:271
1428
+ msgid "United Arab Emirates"
1429
+ msgstr ""
1430
+
1431
+ #: src/Tribe/View_Helpers.php:272
1432
+ msgid "United Kingdom"
1433
+ msgstr ""
1434
+
1435
+ #: src/Tribe/View_Helpers.php:273
1436
+ msgid "United States Minor Outlying Islands"
1437
+ msgstr ""
1438
+
1439
+ #: src/Tribe/View_Helpers.php:274
1440
+ msgid "Uruguay"
1441
+ msgstr ""
1442
+
1443
+ #: src/Tribe/View_Helpers.php:275
1444
+ msgid "Uzbekistan"
1445
+ msgstr ""
1446
+
1447
+ #: src/Tribe/View_Helpers.php:276
1448
+ msgid "Vanuatu"
1449
+ msgstr ""
1450
+
1451
+ #: src/Tribe/View_Helpers.php:277
1452
+ msgid "Venezuela"
1453
+ msgstr ""
1454
+
1455
+ #: src/Tribe/View_Helpers.php:278
1456
+ msgid "Viet Nam"
1457
+ msgstr ""
1458
+
1459
+ #: src/Tribe/View_Helpers.php:279
1460
+ msgid "Virgin Islands (British)"
1461
+ msgstr ""
1462
+
1463
+ #: src/Tribe/View_Helpers.php:280
1464
+ msgid "Virgin Islands (U.S.)"
1465
+ msgstr ""
1466
+
1467
+ #: src/Tribe/View_Helpers.php:281
1468
+ msgid "Wallis And Futuna Islands"
1469
+ msgstr ""
1470
+
1471
+ #: src/Tribe/View_Helpers.php:282
1472
+ msgid "Western Sahara"
1473
+ msgstr ""
1474
+
1475
+ #: src/Tribe/View_Helpers.php:283
1476
+ msgid "Yemen"
1477
+ msgstr ""
1478
+
1479
+ #: src/Tribe/View_Helpers.php:284
1480
+ msgid "Zambia"
1481
+ msgstr ""
1482
+
1483
+ #: src/Tribe/View_Helpers.php:285
1484
+ msgid "Zimbabwe"
1485
+ msgstr ""
1486
+
1487
+ #: src/Tribe/View_Helpers.php:316
1488
+ msgid "Alabama"
1489
+ msgstr ""
1490
+
1491
+ #: src/Tribe/View_Helpers.php:317
1492
+ msgid "Alaska"
1493
+ msgstr ""
1494
+
1495
+ #: src/Tribe/View_Helpers.php:318
1496
+ msgid "Arizona"
1497
+ msgstr ""
1498
+
1499
+ #: src/Tribe/View_Helpers.php:319
1500
+ msgid "Arkansas"
1501
+ msgstr ""
1502
+
1503
+ #: src/Tribe/View_Helpers.php:320
1504
+ msgid "California"
1505
+ msgstr ""
1506
+
1507
+ #: src/Tribe/View_Helpers.php:321
1508
+ msgid "Colorado"
1509
+ msgstr ""
1510
+
1511
+ #: src/Tribe/View_Helpers.php:322
1512
+ msgid "Connecticut"
1513
+ msgstr ""
1514
+
1515
+ #: src/Tribe/View_Helpers.php:323
1516
+ msgid "Delaware"
1517
+ msgstr ""
1518
+
1519
+ #: src/Tribe/View_Helpers.php:324
1520
+ msgid "District of Columbia"
1521
+ msgstr ""
1522
+
1523
+ #: src/Tribe/View_Helpers.php:325
1524
+ msgid "Florida"
1525
+ msgstr ""
1526
+
1527
+ #: src/Tribe/View_Helpers.php:327
1528
+ msgid "Hawaii"
1529
+ msgstr ""
1530
+
1531
+ #: src/Tribe/View_Helpers.php:328
1532
+ msgid "Idaho"
1533
+ msgstr ""
1534
+
1535
+ #: src/Tribe/View_Helpers.php:329
1536
+ msgid "Illinois"
1537
+ msgstr ""
1538
+
1539
+ #: src/Tribe/View_Helpers.php:330
1540
+ msgid "Indiana"
1541
+ msgstr ""
1542
+
1543
+ #: src/Tribe/View_Helpers.php:331
1544
+ msgid "Iowa"
1545
+ msgstr ""
1546
+
1547
+ #: src/Tribe/View_Helpers.php:332
1548
+ msgid "Kansas"
1549
+ msgstr ""
1550
+
1551
+ #: src/Tribe/View_Helpers.php:333
1552
+ msgid "Kentucky"
1553
+ msgstr ""
1554
+
1555
+ #: src/Tribe/View_Helpers.php:334
1556
+ msgid "Louisiana"
1557
+ msgstr ""
1558
+
1559
+ #: src/Tribe/View_Helpers.php:335
1560
+ msgid "Maine"
1561
+ msgstr ""
1562
+
1563
+ #: src/Tribe/View_Helpers.php:336
1564
+ msgid "Maryland"
1565
+ msgstr ""
1566
+
1567
+ #: src/Tribe/View_Helpers.php:337
1568
+ msgid "Massachusetts"
1569
+ msgstr ""
1570
+
1571
+ #: src/Tribe/View_Helpers.php:338
1572
+ msgid "Michigan"
1573
+ msgstr ""
1574
+
1575
+ #: src/Tribe/View_Helpers.php:339
1576
+ msgid "Minnesota"
1577
+ msgstr ""
1578
+
1579
+ #: src/Tribe/View_Helpers.php:340
1580
+ msgid "Mississippi"
1581
+ msgstr ""
1582
+
1583
+ #: src/Tribe/View_Helpers.php:341
1584
+ msgid "Missouri"
1585
+ msgstr ""
1586
+
1587
+ #: src/Tribe/View_Helpers.php:342
1588
+ msgid "Montana"
1589
+ msgstr ""
1590
+
1591
+ #: src/Tribe/View_Helpers.php:343
1592
+ msgid "Nebraska"
1593
+ msgstr ""
1594
+
1595
+ #: src/Tribe/View_Helpers.php:344
1596
+ msgid "Nevada"
1597
+ msgstr ""
1598
+
1599
+ #: src/Tribe/View_Helpers.php:345
1600
+ msgid "New Hampshire"
1601
+ msgstr ""
1602
+
1603
+ #: src/Tribe/View_Helpers.php:346
1604
+ msgid "New Jersey"
1605
+ msgstr ""
1606
+
1607
+ #: src/Tribe/View_Helpers.php:347
1608
+ msgid "New Mexico"
1609
+ msgstr ""
1610
+
1611
+ #: src/Tribe/View_Helpers.php:348
1612
+ msgid "New York"
1613
+ msgstr ""
1614
+
1615
+ #: src/Tribe/View_Helpers.php:349
1616
+ msgid "North Carolina"
1617
+ msgstr ""
1618
+
1619
+ #: src/Tribe/View_Helpers.php:350
1620
+ msgid "North Dakota"
1621
+ msgstr ""
1622
+
1623
+ #: src/Tribe/View_Helpers.php:351
1624
+ msgid "Ohio"
1625
+ msgstr ""
1626
+
1627
+ #: src/Tribe/View_Helpers.php:352
1628
+ msgid "Oklahoma"
1629
+ msgstr ""
1630
+
1631
+ #: src/Tribe/View_Helpers.php:353
1632
+ msgid "Oregon"
1633
+ msgstr ""
1634
+
1635
+ #: src/Tribe/View_Helpers.php:354
1636
+ msgid "Pennsylvania"
1637
+ msgstr ""
1638
+
1639
+ #: src/Tribe/View_Helpers.php:355
1640
+ msgid "Rhode Island"
1641
+ msgstr ""
1642
+
1643
+ #: src/Tribe/View_Helpers.php:356
1644
+ msgid "South Carolina"
1645
+ msgstr ""
1646
+
1647
+ #: src/Tribe/View_Helpers.php:357
1648
+ msgid "South Dakota"
1649
+ msgstr ""
1650
+
1651
+ #: src/Tribe/View_Helpers.php:358
1652
+ msgid "Tennessee"
1653
+ msgstr ""
1654
+
1655
+ #: src/Tribe/View_Helpers.php:359
1656
+ msgid "Texas"
1657
+ msgstr ""
1658
+
1659
+ #: src/Tribe/View_Helpers.php:360
1660
+ msgid "Utah"
1661
+ msgstr ""
1662
+
1663
+ #: src/Tribe/View_Helpers.php:361
1664
+ msgid "Vermont"
1665
+ msgstr ""
1666
+
1667
+ #: src/Tribe/View_Helpers.php:362
1668
+ msgid "Virginia"
1669
+ msgstr ""
1670
+
1671
+ #: src/Tribe/View_Helpers.php:363
1672
+ msgid "Washington"
1673
+ msgstr ""
1674
+
1675
+ #: src/Tribe/View_Helpers.php:364
1676
+ msgid "West Virginia"
1677
+ msgstr ""
1678
+
1679
+ #: src/Tribe/View_Helpers.php:365
1680
+ msgid "Wisconsin"
1681
+ msgstr ""
1682
+
1683
+ #: src/Tribe/View_Helpers.php:366
1684
+ msgid "Wyoming"
1685
+ msgstr ""
1686
+
1687
+ #: src/admin-views/app-shop.php:4
1688
+ msgid "Tribe Event Add-Ons"
1689
+ msgstr ""
1690
+
1691
+ #: src/admin-views/event-log.php:21
1692
+ msgid "Logging level"
1693
+ msgstr ""
1694
+
1695
+ #: src/admin-views/event-log.php:39
1696
+ msgid "Method"
1697
+ msgstr ""
1698
+
1699
+ #: src/admin-views/event-log.php:57
1700
+ msgid "View"
1701
+ msgstr ""
1702
+
1703
+ #: src/admin-views/event-log.php:99
1704
+ msgid "The selected log file is empty or has not been generated yet."
1705
+ msgstr ""
1706
+
1707
+ #: src/admin-views/event-log.php:104
1708
+ msgid "Download log"
1709
+ msgstr ""
1710
+
1711
+ #: src/admin-views/tribe-options-display.php:22
1712
+ msgid "Date Format Settings"
1713
+ msgstr ""
1714
+
1715
+ #: src/admin-views/tribe-options-display.php:26
1716
+ msgid "<p>The following three fields accept the date format options available to the php date() function. <a href=\"http://codex.wordpress.org/Formatting_Date_and_Time\" target=\"_blank\">Learn how to make your own date format here</a>.</p>"
1717
+ msgstr ""
1718
+
1719
+ #: src/admin-views/tribe-options-display.php:30
1720
+ msgid "Datepicker Date Format"
1721
+ msgstr ""
1722
+
1723
+ #: src/admin-views/tribe-options-display.php:31
1724
+ msgid "Select the date format to use in datepickers"
1725
+ msgstr ""
1726
+
1727
+ #: src/admin-views/tribe-options-general.php:10
1728
+ msgid "Thank you for using Event Tickets! All of us at Modern Tribe sincerely appreciate your support and we're excited to see you using our plugins. Check out our handy %1$sNew User Primer%2$s to get started."
1729
+ msgstr ""
1730
+
1731
+ #: src/admin-views/tribe-options-general.php:15
1732
+ msgid "Optimize your site's event listings with %1$sThe Events Calendar%2$s, our free calendar plugin. Looking for additional functionality including recurring events, user-submission, advanced ticket sales and more? Check out our %3$spremium add-ons%4$s."
1733
+ msgstr ""
1734
+
1735
+ #: src/admin-views/tribe-options-general.php:20
1736
+ msgid "Looking for additional functionality including recurring events, custom meta, community events, ticket sales and more?"
1737
+ msgstr ""
1738
+
1739
+ #: src/admin-views/tribe-options-general.php:20
1740
+ msgid "Check out the available add-ons"
1741
+ msgstr ""
1742
+
1743
+ #: src/admin-views/tribe-options-general.php:25
1744
+ msgid "We hope our plugin is helping you out."
1745
+ msgstr ""
1746
+
1747
+ #: src/admin-views/tribe-options-general.php:30
1748
+ msgid "Are you thinking \"Wow, this plugin is amazing! I should say thanks to Modern Tribe for all their hard work.\" The greatest thanks we could ask for is recognition. Add a small text-only link at the bottom of your calendar pointing to The Events Calendar project."
1749
+ msgstr ""
1750
+
1751
+ #: src/admin-views/tribe-options-general.php:30
1752
+ #: src/admin-views/tribe-options-general.php:35
1753
+ msgid "See an example of the link"
1754
+ msgstr ""
1755
+
1756
+ #: src/admin-views/tribe-options-general.php:35
1757
+ msgid "Are you thinking \"Wow, this plugin is amazing! I should say thanks to Modern Tribe for all their hard work.\" The greatest thanks we could ask for is recognition. Add a small text only link at the bottom of your calendar pointing to The Events Calendar project."
1758
+ msgstr ""
1759
+
1760
+ #: src/admin-views/tribe-options-general.php:40
1761
+ msgid "Show The Events Calendar link"
1762
+ msgstr ""
1763
+
1764
+ #: src/admin-views/tribe-options-general.php:58
1765
+ msgid "Debug mode"
1766
+ msgstr ""
1767
+
1768
+ #: src/admin-views/tribe-options-general.php:64
1769
+ msgid "Enable this option to log debug information. By default this will log to your server PHP error log. If you'd like to see the log messages in your browser, then we recommend that you install the %s and look for the \"Tribe\" tab in the debug output."
1770
+ msgstr ""
1771
+
1772
+ #: src/admin-views/tribe-options-general.php:64
1773
+ msgid "Debug Bar Plugin"
1774
+ msgstr ""
1775
+
1776
+ #: src/admin-views/tribe-options-help.php:11
1777
+ msgid "Thanks you for using %s! All of us at Modern Tribe sincerely appreciate your support and we’re excited to see you using our plugins."
1778
+ msgstr ""
1779
+
1780
+ #: src/admin-views/tribe-options-help.php:14
1781
+ msgid "Getting Support"
1782
+ msgstr ""
1783
+
1784
+ #: src/admin-views/tribe-options-help.php:15
1785
+ msgid "Our website’s %s is a great place to find tips and tricks for using and customizing our plugins."
1786
+ msgstr ""
1787
+
1788
+ #: src/admin-views/tribe-options-help.php:15
1789
+ msgid "Knowledgebase"
1790
+ msgstr ""
1791
+
1792
+ #: src/admin-views/tribe-options-help.php:16
1793
+ msgid "<strong>Want to dive deeper?</strong> Check out our %s for developers."
1794
+ msgstr ""
1795
+
1796
+ #: src/admin-views/tribe-options-help.php:16
1797
+ msgid "list of available functions"
1798
+ msgstr ""
1799
+
1800
+ #: src/admin-views/tribe-options-help.php:19
1801
+ msgid "Getting More Help"
1802
+ msgstr ""
1803
+
1804
+ #: src/admin-views/tribe-options-help.php:20
1805
+ msgid "While the resources above help solve a majority of the issues we see, there are times you might be looking for extra support. If you need assistance using our plugins and would like us to take a look, please follow these steps:"
1806
+ msgstr ""
1807
+
1808
+ #: src/admin-views/tribe-options-help.php:24
1809
+ msgid "%s. All of the common (and not-so-common) answers to questions we see are here. It’s often the fastest path to finding an answer!"
1810
+ msgstr ""
1811
+
1812
+ #: src/admin-views/tribe-options-help.php:24
1813
+ msgid "Check our Knowledgebase"
1814
+ msgstr ""
1815
+
1816
+ #: src/admin-views/tribe-options-help.php:25
1817
+ msgid "%s. Testing for an existing conflict is the best start for in-depth troubleshooting. We will often ask you to follow these steps when opening a new thread, so doing this ahead of time will be super helpful."
1818
+ msgstr ""
1819
+
1820
+ #: src/admin-views/tribe-options-help.php:25
1821
+ msgid "Test for a theme or plugin conflict"
1822
+ msgstr ""
1823
+
1824
+ #: src/admin-views/tribe-options-help.php:26
1825
+ msgid "%s. There are very few issues we haven’t seen and it’s likely another user has already asked your question and gotten an answer from our support staff. While posting to the forums is open only to paid customers, they are open for anyone to search and review."
1826
+ msgstr ""
1827
+
1828
+ #: src/admin-views/tribe-options-help.php:26
1829
+ msgid "Search our support forum"
1830
+ msgstr ""
1831
+
1832
+ #: src/admin-views/tribe-options-help.php:30
1833
+ msgid "Please note that all hands-on support is provided via the forums. You can email or tweet at us… ​but we will probably point you back to the forums 😄"
1834
+ msgstr ""
1835
+
1836
+ #: src/admin-views/tribe-options-help.php:31
1837
+ msgid "Read more about our support policy"
1838
+ msgstr ""
1839
+
1840
+ #: src/admin-views/tribe-options-help.php:34
1841
+ msgid "System Information"
1842
+ msgstr ""
1843
+
1844
+ #: src/admin-views/tribe-options-help.php:35
1845
+ msgid "The details of your calendar plugin and settings is often needed for you or our staff to help troubleshoot an issue. We may ask you to share this information if you ask for support. If you post in one of our premium forums, please copy and paste this information into the System Information field and it will help us help you faster!"
1846
+ msgstr ""
1847
+
1848
+ #: src/admin-views/tribe-options-help.php:37
1849
+ msgid "Recent Template Changes"
1850
+ msgstr ""
1851
+
1852
+ #: src/admin-views/tribe-options-help.php:57
1853
+ msgid "News and Tutorials"
1854
+ msgstr ""
1855
+
1856
+ #: src/admin-views/tribe-options-help.php:63
1857
+ msgid "More..."
1858
+ msgstr ""
1859
+
1860
+ #: src/admin-views/tribe-options-licenses.php:13
1861
+ msgid "<p>The license key you received when completing your purchase from %1$s will grant you access to support and updates until it expires. You do not need to enter the key below for the plugins to work, but you will need to enter it to get automatic updates. <strong>Find your license keys at <a href=\"%2$s\" target=\"_blank\">%3$s</a></strong>.</p> <p>Each paid add-on has its own unique license key. Simply paste the key into its appropriate field on below, and give it a moment to validate. You know you're set when a green expiration date appears alongside a \"valid\" message.</p> <p>If you're seeing a red message telling you that your key isn't valid or is out of installs, visit <a href=\"%4$s\" target=\"_blank\">%5$s</a> to manage your installs or renew / upgrade your license.</p><p>Not seeing an update but expecting one? In WordPress, go to <a href=\"%6$s\">Dashboard > Updates</a> and click \"Check Again\".</p>"
1862
+ msgstr ""
1863
+
1864
+ #: src/admin-views/tribe-options-licenses.php:18
1865
+ msgid "%1$s Using our plugins in a multisite network? %2$s Please note that your license key will be applied to the entire network, not just this site."
1866
+ msgstr ""
1867
+
1868
+ #: src/admin-views/tribe-options-licenses.php:27
1869
+ msgid "Only license fields for %1$snetwork activated%2$s plugins will be listed on this screen. "
1870
+ msgstr ""
1871
+
1872
+ #: src/admin-views/tribe-options-network.php:15
1873
+ msgid "Network Settings"
1874
+ msgstr ""
1875
+
1876
+ #: src/admin-views/tribe-options-network.php:19
1877
+ msgid "This is where all of the global network settings for Modern Tribe's The Events Calendar can be modified."
1878
+ msgstr ""
1879
+
1880
+ #: src/admin-views/tribe-options-network.php:27
1881
+ msgid "Hide the following settings tabs on every site:"
1882
+ msgstr ""
1883
+ #. Plugin Name of the plugin/theme
1884
+ msgid "Tribe Common"
1885
+ msgstr ""
1886
+
1887
+ #. Description of the plugin/theme
1888
+ msgid "An event settings framework for managing shared options"
1889
+ msgstr ""
1890
+
1891
+ #. Author of the plugin/theme
1892
+ msgid "Modern Tribe, Inc."
1893
+ msgstr ""
1894
+
1895
+ #. Author URI of the plugin/theme
1896
+ msgid "http://m.tri.be/1x"
1897
+ msgstr ""
common/src/Tribe/Abstract_Deactivation.php CHANGED
@@ -1,71 +1,71 @@
1
- <?php
2
-
3
- abstract class Tribe__Abstract_Deactivation {
4
- protected $network = false;
5
-
6
- public function __construct( $network ) {
7
- $this->network = (bool) $network;
8
- }
9
-
10
- /**
11
- * Tell WordPress to flush rewrite rules.
12
- * Since our post types are already registered,
13
- * we delete the option and let WP regenerate it
14
- * on the next page load.
15
- */
16
- protected function flush_rewrite_rules() {
17
- delete_option( 'rewrite_rules' );
18
- }
19
-
20
- /**
21
- * Deactivate the plugin. This should not remove data.
22
- * It's job is to remove run-time traces of the plugin.
23
- *
24
- * @return void
25
- */
26
- public function deactivate() {
27
- if ( is_multisite() && $this->network ) {
28
- $this->multisite_deactivate();
29
- } else {
30
- $this->blog_deactivate();
31
- }
32
- }
33
-
34
- /**
35
- * Run the deactivation script on every blog for a multisite install
36
- *
37
- * @return void
38
- */
39
- protected function multisite_deactivate() {
40
- /** @var wpdb $wpdb */
41
- global $wpdb;
42
- $site = get_current_site();
43
- $blog_ids = $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM {$wpdb->blogs} WHERE site_id=%d", $site->id ) );
44
- $large = wp_is_large_network();
45
- foreach ( $blog_ids as $blog ) {
46
- set_time_limit( 30 );
47
- switch_to_blog( $blog );
48
- $large ? $this->short_blog_deactivate() : $this->blog_deactivate();
49
- restore_current_blog();
50
- }
51
- }
52
-
53
- /**
54
- * The deactivation routine for a single blog
55
- *
56
- * @return void
57
- */
58
- abstract protected function blog_deactivate();
59
-
60
-
61
- /**
62
- * An abridged version that is less DB intensive for use on large networks.
63
- *
64
- * @see wp_is_large_network() and the 'wp_is_large_network' filter
65
- *
66
- * @return void
67
- */
68
- protected function short_blog_deactivate() {
69
- $this->blog_deactivate();
70
- }
71
- }
1
+ <?php
2
+
3
+ abstract class Tribe__Abstract_Deactivation {
4
+ protected $network = false;
5
+
6
+ public function __construct( $network ) {
7
+ $this->network = (bool) $network;
8
+ }
9
+
10
+ /**
11
+ * Tell WordPress to flush rewrite rules.
12
+ * Since our post types are already registered,
13
+ * we delete the option and let WP regenerate it
14
+ * on the next page load.
15
+ */
16
+ protected function flush_rewrite_rules() {
17
+ delete_option( 'rewrite_rules' );
18
+ }
19
+
20
+ /**
21
+ * Deactivate the plugin. This should not remove data.
22
+ * It's job is to remove run-time traces of the plugin.
23
+ *
24
+ * @return void
25
+ */
26
+ public function deactivate() {
27
+ if ( is_multisite() && $this->network ) {
28
+ $this->multisite_deactivate();
29
+ } else {
30
+ $this->blog_deactivate();
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Run the deactivation script on every blog for a multisite install
36
+ *
37
+ * @return void
38
+ */
39
+ protected function multisite_deactivate() {
40
+ /** @var wpdb $wpdb */
41
+ global $wpdb;
42
+ $site = get_current_site();
43
+ $blog_ids = $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM {$wpdb->blogs} WHERE site_id=%d", $site->id ) );
44
+ $large = wp_is_large_network();
45
+ foreach ( $blog_ids as $blog ) {
46
+ set_time_limit( 30 );
47
+ switch_to_blog( $blog );
48
+ $large ? $this->short_blog_deactivate() : $this->blog_deactivate();
49
+ restore_current_blog();
50
+ }
51
+ }
52
+
53
+ /**
54
+ * The deactivation routine for a single blog
55
+ *
56
+ * @return void
57
+ */
58
+ abstract protected function blog_deactivate();
59
+
60
+
61
+ /**
62
+ * An abridged version that is less DB intensive for use on large networks.
63
+ *
64
+ * @see wp_is_large_network() and the 'wp_is_large_network' filter
65
+ *
66
+ * @return void
67
+ */
68
+ protected function short_blog_deactivate() {
69
+ $this->blog_deactivate();
70
+ }
71
+ }
common/src/Tribe/Admin/Help_Page.php CHANGED
@@ -1,862 +1,862 @@
1
- <?php
2
-
3
- // Don't load directly
4
- if ( ! defined( 'ABSPATH' ) ) {
5
- die( '-1' );
6
- }
7
-
8
- /**
9
- * Class with a few helpers for the Administration Pages
10
- *
11
- * @since 4.0
12
- *
13
- */
14
- class Tribe__Admin__Help_Page {
15
- /**
16
- * Static Singleton Holder
17
- * @var Tribe__Admin__Help_Page|null
18
- */
19
- protected static $instance;
20
-
21
- /**
22
- * Static Singleton Factory Method
23
- *
24
- * @return Tribe__Admin__Help_Page
25
- */
26
- public static function instance() {
27
- if ( ! isset( self::$instance ) ) {
28
- self::$instance = new self;
29
- }
30
-
31
- return self::$instance;
32
- }
33
-
34
- /**
35
- * Get the list of plugins
36
- *
37
- * @since 4.0
38
- *
39
- * @param string $plugin_name Should get only one plugin?
40
- * @param boolean $is_active Only get active plugins?
41
- * @return array
42
- */
43
- public function get_plugins( $plugin_name = null, $is_active = true ) {
44
- $plugins = array();
45
-
46
- $plugins['the-events-calendar'] = array(
47
- 'name' => 'the-events-calendar',
48
- 'title' => esc_html__( 'The Events Calendar', 'tribe-common' ),
49
- 'repo' => 'http://wordpress.org/extend/plugins/the-events-calendar/',
50
- 'forum' => 'https://wordpress.org/support/plugin/the-events-calendar/',
51
- 'stars_url' => 'http://wordpress.org/support/view/plugin-reviews/the-events-calendar?filter=5',
52
- 'description' => esc_html__( 'The Events Calendar is a carefully crafted, extensible plugin that lets you easily share your events.', 'tribe-common' ),
53
- 'is_active' => false,
54
- 'version' => null,
55
- );
56
-
57
- if ( class_exists( 'Tribe__Events__Main' ) ) {
58
- $plugins['the-events-calendar']['version'] = Tribe__Events__Main::VERSION;
59
- $plugins['the-events-calendar']['is_active'] = true;
60
- }
61
-
62
- $plugins['event-tickets'] = array(
63
- 'name' => 'event-tickets',
64
- 'title' => esc_html__( 'Event Tickets', 'tribe-common' ),
65
- 'repo' => 'http://wordpress.org/extend/plugins/event-tickets/',
66
- 'forum' => 'https://wordpress.org/support/plugin/event-tickets',
67
- 'stars_url' => 'http://wordpress.org/support/view/plugin-reviews/event-tickets?filter=5',
68
- 'description' => esc_html__( 'Events Tickets is a carefully crafted, extensible plugin that lets you easily sell tickets for your events.', 'tribe-common' ),
69
- 'is_active' => false,
70
- 'version' => null,
71
- );
72
-
73
- if ( class_exists( 'Tribe__Tickets__Main' ) ) {
74
- $plugins['event-tickets']['version'] = Tribe__Tickets__Main::VERSION;
75
- $plugins['event-tickets']['is_active'] = true;
76
- }
77
-
78
- $plugins['advanced-post-manager'] = array(
79
- 'name' => 'advanced-post-manager',
80
- 'title' => esc_html__( 'Advanced Post Manager', 'tribe-common' ),
81
- 'repo' => 'http://wordpress.org/extend/plugins/advanced-post-manager/',
82
- 'forum' => 'https://wordpress.org/support/plugin/advanced-post-manager/',
83
- 'stars_url' => 'http://wordpress.org/support/view/plugin-reviews/advanced-post-manager?filter=5',
84
- 'description' => esc_html__( 'Turbo charge your posts admin for any custom post type with sortable filters and columns, and auto-registration of metaboxes.', 'tribe-common' ),
85
- 'is_active' => false,
86
- 'version' => null,
87
- );
88
-
89
- if ( class_exists( 'Tribe_APM' ) ) {
90
- $plugins['advanced-post-manager']['version'] = 1;
91
- $plugins['advanced-post-manager']['is_active'] = true;
92
- }
93
-
94
- $plugins = (array) apply_filters( 'tribe_help_plugins', $plugins );
95
-
96
- // Only active ones?
97
- if ( true === $is_active ) {
98
- foreach ( $plugins as $key => $plugin ) {
99
- if ( true !== $plugin['is_active'] ) {
100
- unset( $plugins[ $key ] );
101
- }
102
- }
103
- }
104
-
105
- // Do the search
106
- if ( is_string( $plugin_name ) ) {
107
- if ( isset( $plugins[ $plugin_name ] ) ) {
108
- return $plugins[ $plugin_name ];
109
- } else {
110
- return false;
111
- }
112
- } else {
113
- return $plugins;
114
- }
115
- }
116
-
117
- /**
118
- * Get the formatted links of the possible plugins
119
- *
120
- * @since 4.0
121
- *
122
- * @param boolean $is_active Filter only active plugins
123
- * @return array
124
- */
125
- public function get_plugin_forum_links( $is_active = true ) {
126
- $plugins = $this->get_plugins( null, $is_active );
127
-
128
- $list = array();
129
- foreach ( $plugins as $plugin ) {
130
- $list[] = '<a href="' . esc_url( $plugin['forum'] ) . '" target="_blank">' . $plugin['title'] . '</a>';
131
- }
132
-
133
- return $list;
134
- }
135
-
136
- /**
137
- * Get the formatted text of the possible plugins
138
- *
139
- * @since 4.0
140
- *
141
- * @param boolean $is_active Filter only active plugins
142
- * @return string
143
- */
144
- public function get_plugins_text( $is_active = true ) {
145
- $plugins = array_merge( $this->get_plugins( null, $is_active ), $this->get_addons( null, $is_active, true ) );
146
-
147
- $plugins_text = '';
148
- $i = 0;
149
- $count = count( $plugins );
150
- foreach ( $plugins as $plugin ) {
151
- $i++;
152
- if ( ! isset( $plugin['is_active'] ) || $plugin['is_active'] !== $is_active ) {
153
- continue;
154
- }
155
-
156
- $plugins_text .= $plugin['title'];
157
-
158
- if ( $i === $count - 1 ) {
159
- $plugins_text .= esc_html__( ' and ', 'tribe-common' );
160
- } elseif ( $i !== $count ) {
161
- $plugins_text .= ', ';
162
- }
163
- }
164
-
165
- return $plugins_text;
166
- }
167
-
168
- /**
169
- * Get the Addons
170
- *
171
- * @since 4.0
172
- *
173
- * @param string $plugin Plugin Name to filter
174
- * @param string $is_active Filter if it's active
175
- * @param string $is_important filter if the plugin is important
176
- * @return array
177
- */
178
- public function get_addons( $plugin = null, $is_active = null, $is_important = null ) {
179
- $addons = array();
180
-
181
- $addons['events-calendar-pro'] = array(
182
- 'id' => 'events-calendar-pro',
183
- 'title' => esc_html__( 'Events Calendar PRO', 'tribe-common' ),
184
- 'link' => 'http://m.tri.be/dr',
185
- 'plugin' => array( 'the-events-calendar' ),
186
- 'is_active' => class_exists( 'Tribe__Events__Pro__Main' ),
187
- 'is_important' => true,
188
- );
189
-
190
- $addons['eventbrite-tickets'] = array(
191
- 'id' => 'eventbrite-tickets',
192
- 'title' => esc_html__( 'Eventbrite Tickets', 'tribe-common' ),
193
- 'link' => 'http://m.tri.be/ds',
194
- 'plugin' => array( 'the-events-calendar' ),
195
- 'is_active' => class_exists( 'Tribe__Events__Tickets__Eventbrite__Main' ),
196
- );
197
-
198
- $addons['community-events'] = array(
199
- 'id' => 'community-events',
200
- 'title' => esc_html__( 'Community Events', 'tribe-common' ),
201
- 'link' => 'http://m.tri.be/dt',
202
- 'plugin' => array( 'the-events-calendar' ),
203
- 'is_active' => class_exists( 'Tribe__Events__Community__Main' ),
204
- );
205
-
206
- $addons['facebook-events'] = array(
207
- 'id' => 'facebook-events',
208
- 'title' => esc_html__( 'Facebook Events', 'tribe-common' ),
209
- 'link' => 'http://m.tri.be/du',
210
- 'plugin' => array( 'the-events-calendar' ),
211
- 'is_active' => class_exists( 'Tribe__Events__Facebook__Importer' ),
212
- );
213
-
214
- $addons['events-filter-bar'] = array(
215
- 'id' => 'events-filter-bar',
216
- 'title' => esc_html__( 'Events Filter Bar', 'tribe-common' ),
217
- 'link' => 'http://m.tri.be/hu',
218
- 'plugin' => array( 'the-events-calendar' ),
219
- 'is_active' => class_exists( 'Tribe__Events__Filterbar__View' ),
220
- );
221
-
222
- $addons['event-tickets-plus'] = array(
223
- 'id' => 'event-tickets-plus',
224
- 'title' => esc_html__( 'Event Tickets Plus', 'tribe-common' ),
225
- 'link' => 'http://m.tri.be/18wa',
226
- 'plugin' => array( 'event-tickets' ),
227
- 'is_active' => class_exists( 'Tribe__Tickets_Plus__Main' ),
228
- 'is_important' => true,
229
- );
230
-
231
- $addons['event-community-tickets'] = array(
232
- 'id' => 'event-community-tickets',
233
- 'title' => esc_html__( 'Community Tickets', 'tribe-common' ),
234
- 'link' => 'http://m.tri.be/18m2',
235
- 'plugin' => array( 'event-tickets' ),
236
- 'is_active' => class_exists( 'Tribe__Events__Community__Tickets__Main' ),
237
- );
238
-
239
- /**
240
- * Filter the array of premium addons upsold on the sidebar of the Settings > Help tab
241
- *
242
- * @param array $addons
243
- */
244
- $addons = (array) apply_filters( 'tribe_help_addons', $addons );
245
-
246
- // Should I filter something
247
- if ( is_null( $plugin ) && is_null( $is_active ) && is_null( $is_important ) ) {
248
- return $addons;
249
- }
250
-
251
- // Allow for easily grab the addons for a plugin
252
- $filtered = array();
253
- foreach ( $addons as $id => $addon ) {
254
- if ( ! is_null( $plugin ) && ! in_array( $plugin, (array) $addon['plugin'] ) ) {
255
- continue;
256
- }
257
-
258
- // Filter by is_active
259
- if (
260
- ! is_null( $is_active ) &&
261
- ( ! isset( $addon['is_active'] ) || $is_active !== $addon['is_active'] )
262
- ) {
263
- continue;
264
- }
265
-
266
- // Filter by is_important
267
- if (
268
- ! is_null( $is_important ) &&
269
- ( ! isset( $addon['is_important'] ) || $is_important !== $addon['is_important'] )
270
- ) {
271
- continue;
272
- }
273
-
274
- $filtered[ $id ] = $addon;
275
- }
276
-
277
- return $filtered;
278
- }
279
-
280
- public function is_active( $should_be_active ) {
281
- $plugins = $this->get_plugins( null, true );
282
- $addons = $this->get_addons( null, true );
283
-
284
- $actives = array_merge( $plugins, $addons );
285
- $is_active = array();
286
-
287
- foreach ( $actives as $id => $active ) {
288
- if ( in_array( $id, (array) $should_be_active ) ) {
289
- $is_active[] = $id;
290
- }
291
- }
292
-
293
- return count( array_filter( $is_active ) ) === 0 ? false : true;
294
- }
295
-
296
- /**
297
- * From a Given link returns it with a GA arguments
298
- *
299
- * @since 4.0
300
- *
301
- * @param string $link An absolute or a Relative link
302
- * @param boolean $relative Is the Link absolute or relative?
303
- * @return string Link with the GA arguments
304
- */
305
- public function get_ga_link( $link = null, $relative = true ) {
306
- $query_args = array(
307
- 'utm_source' => 'helptab',
308
- 'utm_medium' => 'plugin-tec',
309
- 'utm_campaign' => 'in-app',
310
- );
311
-
312
- if ( true === $relative ) {
313
- $link = trailingslashit( Tribe__Main::$tec_url . $link );
314
- }
315
-
316
- return esc_url( add_query_arg( $query_args, $link ) );
317
- }
318
-
319
- /**
320
- * Gets the Feed items from the The Events Calendar Blog
321
- *
322
- * @since 4.0
323
- *
324
- * @return array Feed Title and Link
325
- */
326
- public function get_feed_items() {
327
- $news_rss = fetch_feed( Tribe__Main::FEED_URL );
328
- $news_feed = array();
329
-
330
- if ( ! is_wp_error( $news_rss ) ) {
331
- /**
332
- * Filter the maximum number of items returned from the tribe news feed
333
- *
334
- * @param int $max_items default 5
335
- */
336
- $maxitems = $news_rss->get_item_quantity( apply_filters( 'tribe_help_rss_max_items', 5 ) );
337
- $rss_items = $news_rss->get_items( 0, $maxitems );
338
- if ( count( $maxitems ) > 0 ) {
339
- foreach ( $rss_items as $item ) {
340
- $item = array(
341
- 'title' => esc_html( $item->get_title() ),
342
- 'link' => esc_url( $item->get_permalink() ),
343
- );
344
- $news_feed[] = $item;
345
- }
346
- }
347
- }
348
-
349
- return $news_feed;
350
- }
351
-
352
- /**
353
- * Get the information from the Plugin API data
354
- *
355
- * @since 4.0
356
- *
357
- * @param object $plugin Plugin Object to be used
358
- * @return object An object with the API data
359
- */
360
- private function get_plugin_api_data( $plugin = null ) {
361
- if ( is_scalar( $plugin ) ) {
362
- return false;
363
- }
364
-
365
- $plugin = (object) $plugin;
366
-
367
- /**
368
- * Filter the amount of time (seconds) we will keep api data to avoid too many external calls
369
- * @var int
370
- */
371
- $timeout = apply_filters( 'tribe_help_api_data_timeout', 3 * HOUR_IN_SECONDS );
372
- $transient = 'tribe_help_api_data-' . $plugin->name;
373
- $data = get_transient( $transient );
374
-
375
- if ( false === $data ) {
376
- if ( ! function_exists( 'plugins_api' ) ) {
377
- include_once ABSPATH . '/wp-admin/includes/plugin-install.php';
378
- }
379
-
380
- // Fetch the data
381
- $data = plugins_api( 'plugin_information', array(
382
- 'slug' => $plugin->name,
383
- 'is_ssl' => is_ssl(),
384
- 'fields' => array(
385
- 'banners' => true,
386
- 'reviews' => true,
387
- 'downloaded' => true,
388
- 'active_installs' => true,
389
- ),
390
- ) );
391
-
392
- if ( ! is_wp_error( $data ) ) {
393
- // Format Downloaded Infomation
394
- $data->downloaded = $data->downloaded ? number_format( $data->downloaded ) : _x( 'n/a', 'not available', 'tribe-common' );
395
- } else {
396
- // If there was a bug on the Current Request just leave
397
- return false;
398
- }
399
-
400
- set_transient( $transient, $data, $timeout );
401
- }
402
- $data->up_to_date = ( version_compare( $plugin->version, $data->version, '<' ) ) ? esc_html__( 'You need to upgrade!', 'tribe-common' ) : esc_html__( 'You are up to date!', 'tribe-common' );
403
-
404
- /**
405
- * Filters the API data that was stored in the Transient option
406
- *
407
- * @var array
408
- * @var object The plugin object, check `$this->get_plugins()` for more info
409
- */
410
- return (object) apply_filters( 'tribe_help_api_data', $data, $plugin );
411
- }
412
-
413
- /**
414
- * Parses the help text from an Array to the final HTML.
415
- *
416
- * It is the responsibility of code calling this function to ensure proper escaping
417
- * within any HTML.
418
- *
419
- * @since 4.0
420
- *
421
- * @param string|array $mixed The mixed value to create the HTML from
422
- * @return string
423
- */
424
- public function get_content_html( $mixed = '' ) {
425
- // If it's an StdObj or String it will be converted
426
- $mixed = (array) $mixed;
427
-
428
- // Loop to start the HTML
429
- foreach ( $mixed as &$line ) {
430
- // If we have content we use that
431
- if ( ! empty( $line->content ) ) {
432
- $line = $line->content;
433
- }
434
-
435
- if ( is_string( $line ) ) {
436
- continue;
437
- } elseif ( is_array( $line ) ) {
438
- // Allow the developer to pass some configuration
439
- if ( empty( $line['type'] ) ) {
440
- $line['type'] = 'ul';
441
- }
442
-
443
- $text = '<' . $line['type'] . '>' . "\n";
444
- foreach ( $line as $key => $item ) {
445
- // Don't add non-numeric items (a.k.a.: configuration)
446
- if ( ! is_numeric( $key ) ) {
447
- continue;
448
- }
449
-
450
- // Only add List Item if is a UL or OL
451
- if ( in_array( $line['type'], array( 'ul', 'ol' ) ) ) {
452
- $text .= '<li>' . "\n";
453
- }
454
-
455
- $text .= $this->get_content_html( $item );
456
-
457
- if ( in_array( $line['type'], array( 'ul', 'ol' ) ) ) {
458
- $text .= '</li>' . "\n";
459
- }
460
- }
461
- $text .= '</' . $line['type'] . '>' . "\n";
462
-
463
- // Create the list as html instead of array
464
- $line = $text;
465
- }
466
- }
467
-
468
- return wpautop( implode( "\n\n", $mixed ) );
469
- }
470
-
471
- /**
472
- * A Private storage for sections.
473
- *
474
- * @since 4.0
475
- *
476
- * @access private
477
- * @var array
478
- */
479
- private $sections = array();
480
-
481
- /**
482
- * Incremented with each method call, then stored in $section->uid.
483
- *
484
- * Used when sorting two instances whose priorities are equal.
485
- *
486
- * @since 4.0
487
- *
488
- * @static
489
- * @access protected
490
- * @var int
491
- */
492
- protected static $section_count = 0;
493
-
494
- /**
495
- * Helper function to compare two objects by priority, ensuring sort stability via uid.
496
- *
497
- * @since 4.0
498
- *
499
- * @access protected
500
- * @param object $a Object A.
501
- * @param object $b Object B.
502
- *
503
- * @return int
504
- */
505
- protected function by_priority( $a, $b ) {
506
- if ( empty( $a->priority ) || empty( $b->priority ) || $a->priority === $b->priority ) {
507
- if ( empty( $a->unique_call_order ) || empty( $b->unique_call_order ) ) {
508
- return 0;
509
- } else {
510
- return $a->unique_call_order - $b->unique_call_order;
511
- }
512
- } else {
513
- return $a->priority - $b->priority;
514
- }
515
- }
516
-
517
- /**
518
- * Adds a new section to the Help Page
519
- *
520
- * @since 4.0
521
- *
522
- * @param string $id HTML like ID
523
- * @param string $title The Title of the section, doesn't allow HTML
524
- * @param integer $priority A Numeric ordering for the Section
525
- * @param string $type by default only 'default' or 'box'
526
- *
527
- * @return object The section added
528
- */
529
- public function add_section( $id, $title = null, $priority = 10, $type = 'default' ) {
530
- if ( empty( $id ) ) {
531
- return false;
532
- }
533
-
534
- // Everytime you call this we will add this up
535
- self::$section_count++;
536
-
537
- $possible_types = (array) apply_filters( 'tribe_help_available_section_types', array( 'default', 'box' ) );
538
-
539
- // Set a Default type
540
- if ( empty( $type ) || ! in_array( $type, $possible_types ) ) {
541
- $type = 'default';
542
- }
543
-
544
- // Create the section and Sanitize the values to avoid having to do it later
545
- $section = (object) array(
546
- 'id' => sanitize_html_class( $id ),
547
- 'title' => esc_html( $title ),
548
- 'priority' => absint( $priority ),
549
- 'type' => sanitize_html_class( $type ),
550
-
551
- // This Method Unique count integer used for ordering with priority
552
- 'unique_call_order' => self::$section_count,
553
-
554
- // Counter for ordering Content
555
- 'content_count' => 0,
556
-
557
- // Setup the Base for the content to come
558
- 'content' => array(),
559
- );
560
-
561
- $this->sections[ $section->id ] = $section;
562
-
563
- return $section;
564
- }
565
-
566
- /**
567
- * Add a New content Item to a Help page Section
568
- *
569
- * @since 4.0
570
- *
571
- * @param string $section_id Which section this content should be assigned to
572
- * @param string|array $content Item text or array of items, will be passed to `$this->get_content_html`
573
- * @param integer $priority A Numeric priority
574
- * @param array $arguments If you need arguments for item, they can be passed here
575
- *
576
- * @return object The content item added
577
- */
578
- public function add_section_content( $section_id, $content, $priority = 10, $arguments = array() ) {
579
- $section_id = sanitize_html_class( $section_id );
580
-
581
- // Check if the section exists
582
- if ( empty( $this->sections[ $section_id ] ) ) {
583
- return false;
584
- }
585
-
586
- // Make sure we have arguments as Array
587
- if ( ! is_array( $arguments ) ) {
588
- return false;
589
- }
590
-
591
- $section = &$this->sections[ $section_id ];
592
-
593
- // Increment the content counter
594
- $section->content_count++;
595
-
596
- $item = (object) $arguments;
597
-
598
- // Set the priority
599
- $item->priority = absint( $priority );
600
-
601
- // Set the uid to help ordering
602
- $item->unique_call_order = $section->content_count;
603
-
604
- // Content is not Safe, will be Sanitized on Output
605
- $item->content = $content;
606
-
607
- $section->content[] = $item;
608
-
609
- return $item;
610
- }
611
-
612
- /**
613
- * Remove a section based on the ID
614
- * This method will remove any sections that are indexed at that ID on the sections array
615
- * And the sections that have a propriety of `id` equals to the given $section_id argument
616
- *
617
- * @param string|int $section_id You can use Numeric or String indexes to search
618
- * @return bool|int Returns `false` when no sections were removed and an `int` with the number of sections removed
619
- */
620
- public function remove_section( $section_id ) {
621
- if (
622
- ! isset( $this->sections[ $section_id ] ) &&
623
- ! in_array( (object) array( 'id' => $section_id ), $this->sections, true )
624
- ) {
625
- // There are no sections to remove, so false
626
- return false;
627
- }
628
-
629
- $removed = array();
630
- foreach ( $this->sections as $id => $section ) {
631
- if ( ! is_numeric( $id ) && ! is_numeric( $section_id ) && ! empty( $section->id ) ) {
632
- if ( $section->id === $section_id ) {
633
- unset( $this->sections[ $id ] );
634
- // Mark that this section was removed
635
- $removed[ $id ] = true;
636
- }
637
- } elseif ( $id === $section_id ) {
638
- unset( $this->sections[ $section_id ] );
639
- // Mark that this section was removed
640
- $removed[ $id ] = true;
641
- } else {
642
- // Mark that this section was NOT removed
643
- $removed[ $id ] = false;
644
- }
645
- }
646
-
647
- // Count how many were removed
648
- $total = count( array_filter( $removed ) );
649
-
650
- // if Zero just return false
651
- return $total === 0 ? false : $total;
652
- }
653
-
654
- /**
655
- * Based on an Array of sections it render the Help Page contents
656
- *
657
- * @since 4.0
658
- *
659
- * @param boolean $print Return or Print the HTML after
660
- * @return void|string
661
- */
662
- public function get_sections( $print = true ) {
663
- /**
664
- * Allow third-party sections here
665
- *
666
- * @var Tribe__Admin__Help_Page
667
- */
668
- do_action( 'tribe_help_pre_get_sections', $this );
669
-
670
- /**
671
- * Allow developers to filter all the sections at once
672
- * NOTE: You should be using `tribe_help_add_sections` to add new sections or content
673
- *
674
- * @var array
675
- */
676
- $sections = apply_filters( 'tribe_help_sections', $this->sections );
677
-
678
- if ( ! is_array( $sections ) || empty( $sections ) ) {
679
- return false;
680
- }
681
-
682
- // Sort by Priority
683
- uasort( $sections, array( $this, 'by_priority' ) );
684
-
685
- $html = array();
686
-
687
- foreach ( $sections as $index => $section ) {
688
- $section = (object) $section;
689
-
690
- // If it has no ID or Content, skip
691
- if ( empty( $section->id ) || empty( $section->content ) ) {
692
- continue;
693
- }
694
-
695
- // Set a Default type
696
- if ( empty( $section->type ) ) {
697
- $section->type = 'default';
698
- }
699
-
700
- /**
701
- * Creates a way to filter a specific section based on the ID
702
- *
703
- * @var object
704
- */
705
- $section = apply_filters( 'tribe_help_section_' . $section->id, $section, $this );
706
-
707
- // Sort by Priority
708
- uasort( $section->content, array( $this, 'by_priority' ) );
709
-
710
- $html[ $section->id . '-start' ] = '<div id="tribe-' . sanitize_html_class( $section->id ) . '" class="tribe-help-section clearfix tribe-section-type-' . sanitize_html_class( $section->type ) . '">';
711
-
712
- if ( ! empty( $section->title ) ) {
713
- $html[ $section->id . '-title' ] = '<h3 class="tribe-help-title">' . esc_html__( $section->title ) . '</h3>';
714
- }
715
-
716
- $html[ $section->id . '-content' ] = $this->get_content_html( $section->content );
717
-
718
- $html[ $section->id . '-end' ] = '</div>';
719
- }
720
-
721
- /**
722
- * Creates a way for developers to hook to the final HTML
723
- * @var array $html
724
- * @var array $sections
725
- */
726
- $html = apply_filters( 'tribe_help_sections_html', $html, $sections );
727
-
728
- if ( true === $print ) {
729
- echo implode( "\n", $html );
730
- } else {
731
- return $html;
732
- }
733
-
734
- }
735
-
736
- /**
737
- * Prints the Plugin box for the given plugin
738
- *
739
- * @since 4.0
740
- *
741
- * @param string $plugin Plugin Name key
742
- * @return void
743
- */
744
- public function print_plugin_box( $plugin ) {
745
- $plugin = (object) $this->get_plugins( $plugin, false );
746
- $api_data = $this->get_plugin_api_data( $plugin );
747
- $addons = $this->get_addons( $plugin->name );
748
- $plugins = get_plugins();
749
-
750
- if ( $api_data ) {
751
- if ( ! function_exists( 'install_plugin_install_status' ) ) {
752
- include_once ABSPATH . '/wp-admin/includes/plugin-install.php';
753
- }
754
- $status = install_plugin_install_status( $api_data );
755
- $plugin_active = is_plugin_active( $status['file'] );
756
- $plugin_exists = isset( $plugins[ $status['file'] ] );
757
-
758
- if ( 'install' !== $status['status'] && ! $plugin_active ) {
759
- $args = array(
760
- 'action' => 'activate',
761
- 'plugin' => $status['file'],
762
- 'plugin_status' => 'all',
763
- 'paged' => 1,
764
- 's' => '',
765
- );
766
- $activate_url = wp_nonce_url( add_query_arg( $args, 'plugins.php' ), 'activate-plugin_' . $status['file'] );
767
- $link = '<a class="button" href="' . $activate_url . '" aria-label="' . esc_attr( sprintf( esc_attr__( 'Activate %s', 'tribe-common' ), $plugin->name ) ) . '">' . esc_html__( 'Activate Plugin', 'tribe-common' ) . '</a>';
768
- } elseif ( 'update_available' === $status['status'] ) {
769
- $args = array(
770
- 'action' => 'upgrade-plugin',
771
- 'plugin' => $status['file'],
772
- );
773
- $update_url = wp_nonce_url( add_query_arg( $args, 'update.php' ), 'upgrade-plugin_' . $status['file'] );
774
-
775
- $link = '<a class="button" href="' . $update_url . '">' . esc_html__( 'Upgrade Plugin', 'tribe-common' ) . '</a>';
776
- } elseif ( $plugin_exists ) {
777
- $link = '<a class="button disabled">' . esc_html__( 'You are up to date!', 'tribe-common' ) . '</a>';
778
- }
779
- }
780
-
781
- if ( ! isset( $link ) ) {
782
- if ( $api_data ) {
783
- $args = array(
784
- 'tab' => 'plugin-information',
785
- 'plugin' => $plugin->name,
786
- 'TB_iframe' => true,
787
- 'width' => 772,
788
- 'height' => 600,
789
- );
790
- $iframe_url = add_query_arg( $args, admin_url( '/plugin-install.php' ) );
791
- $link = '<a class="button thickbox" href="' . $iframe_url . '" aria-label="' . esc_attr( sprintf( esc_attr__( 'Install %s', 'tribe-common' ), $plugin->name ) ) . '">' . esc_html__( 'Install Plugin', 'tribe-common' ) . '</a>';
792
- } else {
793
- $link = null;
794
- }
795
- }
796
- ?>
797
- <div class="tribe-help-plugin-info">
798
- <h3><a href="<?php echo esc_url( $plugin->repo ); ?>"><?php echo esc_html( $plugin->title ); ?></a></h3>
799
-
800
- <?php
801
- if ( ! empty( $plugin->description ) && ! $plugin->is_active ) {
802
- echo wpautop( $plugin->description );
803
- }
804
- ?>
805
-
806
- <?php if ( $api_data ) { ?>
807
- <dl>
808
- <dt><?php esc_html_e( 'Latest Version:', 'tribe-common' ); ?></dt>
809
- <dd><?php echo esc_html( $api_data->version ); ?></dd>
810
-
811
- <dt><?php esc_html_e( 'Requires:', 'tribe-common' ); ?></dt>
812
- <dd><?php echo esc_html__( 'WordPress ', 'tribe-common' ) . esc_html( $api_data->requires ); ?>+</dd>
813
-
814
- <dt><?php esc_html_e( 'Active Users:', 'tribe-common' ); ?></dt>
815
- <dd><?php echo esc_html( number_format( $api_data->active_installs ) ); ?>+</dd>
816
-
817
- <dt><?php esc_html_e( 'Rating:', 'tribe-common' ); ?></dt>
818
- <dd><a href="<?php echo esc_url( $plugin->stars_url ); ?>" target="_blank">
819
- <?php wp_star_rating( array(
820
- 'rating' => $api_data->rating,
821
- 'type' => 'percent',
822
- 'number' => $api_data->num_ratings,
823
- ) );?>
824
- </a></dd>
825
- </dl>
826
- <?php } ?>
827
-
828
- <?php
829
- // Only show the link to the users can use it
830
- if ( current_user_can( 'update_plugins' ) && current_user_can( 'install_plugins' ) ) {
831
- echo $link ? '<p style="text-align: center;">' . $link . '</p>' : '';
832
- }
833
- ?>
834
-
835
- <?php if ( ! empty( $addons ) ) { ?>
836
- <h3><?php esc_html_e( 'Premium Add-Ons', 'tribe-common' ); ?></h3>
837
- <ul class='tribe-list-addons'>
838
- <?php foreach ( $addons as $addon ) {
839
- $addon = (object) $addon;
840
-
841
- if ( isset( $addon->is_active ) && $addon->is_active ) {
842
- $active_title = __( 'Plugin Active', 'tribe-common' );
843
- } else {
844
- $active_title = __( 'Plugin Inactive', 'tribe-common' );
845
- }
846
-
847
- echo '<li title="' . esc_attr( $active_title ) . '" class="' . ( isset( $addon->is_active ) && $addon->is_active ? 'tribe-active-addon' : '' ) . '">';
848
- if ( isset( $addon->link ) ) {
849
- echo '<a href="' . esc_url( $addon->link ) . '" title="' . esc_attr__( 'Visit the Add-on Page', 'tribe-common' ) . '" target="_blank">';
850
- }
851
- echo esc_html( $addon->title );
852
- if ( isset( $addon->link ) ) {
853
- echo '</a>';
854
- }
855
- echo '</li>';
856
- } ?>
857
- </ul>
858
- <?php } ?>
859
- </div>
860
- <?php
861
- }
862
  }
1
+ <?php
2
+
3
+ // Don't load directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ die( '-1' );
6
+ }
7
+
8
+ /**
9
+ * Class with a few helpers for the Administration Pages
10
+ *
11
+ * @since 4.0
12
+ *
13
+ */
14
+ class Tribe__Admin__Help_Page {
15
+ /**
16
+ * Static Singleton Holder
17
+ * @var Tribe__Admin__Help_Page|null
18
+ */
19
+ protected static $instance;
20
+
21
+ /**
22
+ * Static Singleton Factory Method
23
+ *
24
+ * @return Tribe__Admin__Help_Page
25
+ */
26
+ public static function instance() {
27
+ if ( ! isset( self::$instance ) ) {
28
+ self::$instance = new self;
29
+ }
30
+
31
+ return self::$instance;
32
+ }
33
+
34
+ /**
35
+ * Get the list of plugins
36
+ *
37
+ * @since 4.0
38
+ *
39
+ * @param string $plugin_name Should get only one plugin?
40
+ * @param boolean $is_active Only get active plugins?
41
+ * @return array
42
+ */
43
+ public function get_plugins( $plugin_name = null, $is_active = true ) {
44
+ $plugins = array();
45
+
46
+ $plugins['the-events-calendar'] = array(
47
+ 'name' => 'the-events-calendar',
48
+ 'title' => esc_html__( 'The Events Calendar', 'tribe-common' ),
49
+ 'repo' => 'http://wordpress.org/extend/plugins/the-events-calendar/',
50
+ 'forum' => 'https://wordpress.org/support/plugin/the-events-calendar/',
51
+ 'stars_url' => 'http://wordpress.org/support/view/plugin-reviews/the-events-calendar?filter=5',
52
+ 'description' => esc_html__( 'The Events Calendar is a carefully crafted, extensible plugin that lets you easily share your events.', 'tribe-common' ),
53
+ 'is_active' => false,
54
+ 'version' => null,
55
+ );
56
+
57
+ if ( class_exists( 'Tribe__Events__Main' ) ) {
58
+ $plugins['the-events-calendar']['version'] = Tribe__Events__Main::VERSION;
59
+ $plugins['the-events-calendar']['is_active'] = true;
60
+ }
61
+
62
+ $plugins['event-tickets'] = array(
63
+ 'name' => 'event-tickets',
64
+ 'title' => esc_html__( 'Event Tickets', 'tribe-common' ),
65
+ 'repo' => 'http://wordpress.org/extend/plugins/event-tickets/',
66
+ 'forum' => 'https://wordpress.org/support/plugin/event-tickets',
67
+ 'stars_url' => 'http://wordpress.org/support/view/plugin-reviews/event-tickets?filter=5',
68
+ 'description' => esc_html__( 'Events Tickets is a carefully crafted, extensible plugin that lets you easily sell tickets for your events.', 'tribe-common' ),
69
+ 'is_active' => false,
70
+ 'version' => null,
71
+ );
72
+
73
+ if ( class_exists( 'Tribe__Tickets__Main' ) ) {
74
+ $plugins['event-tickets']['version'] = Tribe__Tickets__Main::VERSION;
75
+ $plugins['event-tickets']['is_active'] = true;
76
+ }
77
+
78
+ $plugins['advanced-post-manager'] = array(
79
+ 'name' => 'advanced-post-manager',
80
+ 'title' => esc_html__( 'Advanced Post Manager', 'tribe-common' ),
81
+ 'repo' => 'http://wordpress.org/extend/plugins/advanced-post-manager/',
82
+ 'forum' => 'https://wordpress.org/support/plugin/advanced-post-manager/',
83
+ 'stars_url' => 'http://wordpress.org/support/view/plugin-reviews/advanced-post-manager?filter=5',
84
+ 'description' => esc_html__( 'Turbo charge your posts admin for any custom post type with sortable filters and columns, and auto-registration of metaboxes.', 'tribe-common' ),
85
+ 'is_active' => false,
86
+ 'version' => null,
87
+ );
88
+
89
+ if ( class_exists( 'Tribe_APM' ) ) {
90
+ $plugins['advanced-post-manager']['version'] = 1;
91
+ $plugins['advanced-post-manager']['is_active'] = true;
92
+ }
93
+
94
+ $plugins = (array) apply_filters( 'tribe_help_plugins', $plugins );
95
+
96
+ // Only active ones?
97
+ if ( true === $is_active ) {
98
+ foreach ( $plugins as $key => $plugin ) {
99
+ if ( true !== $plugin['is_active'] ) {
100
+ unset( $plugins[ $key ] );
101
+ }
102
+ }
103
+ }
104
+
105
+ // Do the search
106
+ if ( is_string( $plugin_name ) ) {
107
+ if ( isset( $plugins[ $plugin_name ] ) ) {
108
+ return $plugins[ $plugin_name ];
109
+ } else {
110
+ return false;
111
+ }
112
+ } else {
113
+ return $plugins;
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Get the formatted links of the possible plugins
119
+ *
120
+ * @since 4.0
121
+ *
122
+ * @param boolean $is_active Filter only active plugins
123
+ * @return array
124
+ */
125
+ public function get_plugin_forum_links( $is_active = true ) {
126
+ $plugins = $this->get_plugins( null, $is_active );
127
+
128
+ $list = array();
129
+ foreach ( $plugins as $plugin ) {
130
+ $list[] = '<a href="' . esc_url( $plugin['forum'] ) . '" target="_blank">' . $plugin['title'] . '</a>';
131
+ }
132
+
133
+ return $list;
134
+ }
135
+
136
+ /**
137
+ * Get the formatted text of the possible plugins
138
+ *
139
+ * @since 4.0
140
+ *
141
+ * @param boolean $is_active Filter only active plugins
142
+ * @return string
143
+ */
144
+ public function get_plugins_text( $is_active = true ) {
145
+ $plugins = array_merge( $this->get_plugins( null, $is_active ), $this->get_addons( null, $is_active, true ) );
146
+
147
+ $plugins_text = '';
148
+ $i = 0;
149
+ $count = count( $plugins );
150
+ foreach ( $plugins as $plugin ) {
151
+ $i++;
152
+ if ( ! isset( $plugin['is_active'] ) || $plugin['is_active'] !== $is_active ) {
153
+ continue;
154
+ }
155
+
156
+ $plugins_text .= $plugin['title'];
157
+
158
+ if ( $i === $count - 1 ) {
159
+ $plugins_text .= esc_html__( ' and ', 'tribe-common' );
160
+ } elseif ( $i !== $count ) {
161
+ $plugins_text .= ', ';
162
+ }
163
+ }
164
+
165
+ return $plugins_text;
166
+ }
167
+
168
+ /**
169
+ * Get the Addons
170
+ *
171
+ * @since 4.0
172
+ *
173
+ * @param string $plugin Plugin Name to filter
174
+ * @param string $is_active Filter if it's active
175
+ * @param string $is_important filter if the plugin is important
176
+ * @return array
177
+ */
178
+ public function get_addons( $plugin = null, $is_active = null, $is_important = null ) {
179
+ $addons = array();
180
+
181
+ $addons['events-calendar-pro'] = array(
182
+ 'id' => 'events-calendar-pro',
183
+ 'title' => esc_html__( 'Events Calendar PRO', 'tribe-common' ),
184
+ 'link' => 'http://m.tri.be/dr',
185
+ 'plugin' => array( 'the-events-calendar' ),
186
+ 'is_active' => class_exists( 'Tribe__Events__Pro__Main' ),
187
+ 'is_important' => true,
188
+ );
189
+
190
+ $addons['eventbrite-tickets'] = array(
191
+ 'id' => 'eventbrite-tickets',
192
+ 'title' => esc_html__( 'Eventbrite Tickets', 'tribe-common' ),
193
+ 'link' => 'http://m.tri.be/ds',
194
+ 'plugin' => array( 'the-events-calendar' ),
195
+ 'is_active' => class_exists( 'Tribe__Events__Tickets__Eventbrite__Main' ),
196
+ );
197
+
198
+ $addons['community-events'] = array(
199
+ 'id' => 'community-events',
200
+ 'title' => esc_html__( 'Community Events', 'tribe-common' ),
201
+ 'link' => 'http://m.tri.be/dt',
202
+ 'plugin' => array( 'the-events-calendar' ),
203
+ 'is_active' => class_exists( 'Tribe__Events__Community__Main' ),
204
+ );
205
+
206
+ $addons['facebook-events'] = array(
207
+ 'id' => 'facebook-events',
208
+ 'title' => esc_html__( 'Facebook Events', 'tribe-common' ),
209
+ 'link' => 'http://m.tri.be/du',
210
+ 'plugin' => array( 'the-events-calendar' ),
211
+ 'is_active' => class_exists( 'Tribe__Events__Facebook__Importer' ),
212
+ );
213
+
214
+ $addons['events-filter-bar'] = array(
215
+ 'id' => 'events-filter-bar',
216
+ 'title' => esc_html__( 'Events Filter Bar', 'tribe-common' ),
217
+ 'link' => 'http://m.tri.be/hu',
218
+ 'plugin' => array( 'the-events-calendar' ),
219
+ 'is_active' => class_exists( 'Tribe__Events__Filterbar__View' ),
220
+ );
221
+
222
+ $addons['event-tickets-plus'] = array(
223
+ 'id' => 'event-tickets-plus',
224
+ 'title' => esc_html__( 'Event Tickets Plus', 'tribe-common' ),
225
+ 'link' => 'http://m.tri.be/18wa',
226
+ 'plugin' => array( 'event-tickets' ),
227
+ 'is_active' => class_exists( 'Tribe__Tickets_Plus__Main' ),
228
+ 'is_important' => true,
229
+ );
230
+
231
+ $addons['event-community-tickets'] = array(
232
+ 'id' => 'event-community-tickets',
233
+ 'title' => esc_html__( 'Community Tickets', 'tribe-common' ),
234
+ 'link' => 'http://m.tri.be/18m2',
235
+ 'plugin' => array( 'event-tickets' ),
236
+ 'is_active' => class_exists( 'Tribe__Events__Community__Tickets__Main' ),
237
+ );
238
+
239
+ /**
240
+ * Filter the array of premium addons upsold on the sidebar of the Settings > Help tab
241
+ *
242
+ * @param array $addons
243
+ */
244
+ $addons = (array) apply_filters( 'tribe_help_addons', $addons );
245
+
246
+ // Should I filter something
247
+ if ( is_null( $plugin ) && is_null( $is_active ) && is_null( $is_important ) ) {
248
+ return $addons;
249
+ }
250
+
251
+ // Allow for easily grab the addons for a plugin
252
+ $filtered = array();
253
+ foreach ( $addons as $id => $addon ) {
254
+ if ( ! is_null( $plugin ) && ! in_array( $plugin, (array) $addon['plugin'] ) ) {
255
+ continue;
256
+ }
257
+
258
+ // Filter by is_active
259
+ if (
260
+ ! is_null( $is_active ) &&
261
+ ( ! isset( $addon['is_active'] ) || $is_active !== $addon['is_active'] )
262
+ ) {
263
+ continue;
264
+ }
265
+
266
+ // Filter by is_important
267
+ if (
268
+ ! is_null( $is_important ) &&
269
+ ( ! isset( $addon['is_important'] ) || $is_important !== $addon['is_important'] )
270
+ ) {
271
+ continue;
272
+ }
273
+
274
+ $filtered[ $id ] = $addon;
275
+ }
276
+
277
+ return $filtered;
278
+ }
279
+
280
+ public function is_active( $should_be_active ) {
281
+ $plugins = $this->get_plugins( null, true );
282
+ $addons = $this->get_addons( null, true );
283
+
284
+ $actives = array_merge( $plugins, $addons );
285
+ $is_active = array();
286
+
287
+ foreach ( $actives as $id => $active ) {
288
+ if ( in_array( $id, (array) $should_be_active ) ) {
289
+ $is_active[] = $id;
290
+ }
291
+ }
292
+
293
+ return count( array_filter( $is_active ) ) === 0 ? false : true;
294
+ }
295
+
296
+ /**
297
+ * From a Given link returns it with a GA arguments
298
+ *
299
+ * @since 4.0
300
+ *
301
+ * @param string $link An absolute or a Relative link
302
+ * @param boolean $relative Is the Link absolute or relative?
303
+ * @return string Link with the GA arguments
304
+ */
305
+ public function get_ga_link( $link = null, $relative = true ) {
306
+ $query_args = array(
307
+ 'utm_source' => 'helptab',
308
+ 'utm_medium' => 'plugin-tec',
309
+ 'utm_campaign' => 'in-app',
310
+ );
311
+
312
+ if ( true === $relative ) {
313
+ $link = trailingslashit( Tribe__Main::$tec_url . $link );
314
+ }
315
+
316
+ return esc_url( add_query_arg( $query_args, $link ) );
317
+ }
318
+
319
+ /**
320
+ * Gets the Feed items from the The Events Calendar Blog
321
+ *
322
+ * @since 4.0
323
+ *
324
+ * @return array Feed Title and Link
325
+ */
326
+ public function get_feed_items() {
327
+ $news_rss = fetch_feed( Tribe__Main::FEED_URL );
328
+ $news_feed = array();
329
+
330
+ if ( ! is_wp_error( $news_rss ) ) {
331
+ /**
332
+ * Filter the maximum number of items returned from the tribe news feed
333
+ *
334
+ * @param int $max_items default 5
335
+ */
336
+ $maxitems = $news_rss->get_item_quantity( apply_filters( 'tribe_help_rss_max_items', 5 ) );
337
+ $rss_items = $news_rss->get_items( 0, $maxitems );
338
+ if ( count( $maxitems ) > 0 ) {
339
+ foreach ( $rss_items as $item ) {
340
+ $item = array(
341
+ 'title' => esc_html( $item->get_title() ),
342
+ 'link' => esc_url( $item->get_permalink() ),
343
+ );
344
+ $news_feed[] = $item;
345
+ }
346
+ }
347
+ }
348
+
349
+ return $news_feed;
350
+ }
351
+
352
+ /**
353
+ * Get the information from the Plugin API data
354
+ *
355
+ * @since 4.0
356
+ *
357
+ * @param object $plugin Plugin Object to be used
358
+ * @return object An object with the API data
359
+ */
360
+ private function get_plugin_api_data( $plugin = null ) {
361
+ if ( is_scalar( $plugin ) ) {
362
+ return false;
363
+ }
364
+
365
+ $plugin = (object) $plugin;
366
+
367
+ /**
368
+ * Filter the amount of time (seconds) we will keep api data to avoid too many external calls
369
+ * @var int
370
+ */
371
+ $timeout = apply_filters( 'tribe_help_api_data_timeout', 3 * HOUR_IN_SECONDS );
372
+ $transient = 'tribe_help_api_data-' . $plugin->name;
373
+ $data = get_transient( $transient );
374
+
375
+ if ( false === $data ) {
376
+ if ( ! function_exists( 'plugins_api' ) ) {
377
+ include_once ABSPATH . '/wp-admin/includes/plugin-install.php';
378
+ }
379
+
380
+ // Fetch the data
381
+ $data = plugins_api( 'plugin_information', array(
382
+ 'slug' => $plugin->name,
383
+ 'is_ssl' => is_ssl(),
384
+ 'fields' => array(
385
+ 'banners' => true,
386
+ 'reviews' => true,
387
+ 'downloaded' => true,
388
+ 'active_installs' => true,
389
+ ),
390
+ ) );
391
+
392
+ if ( ! is_wp_error( $data ) ) {
393
+ // Format Downloaded Infomation
394
+ $data->downloaded = $data->downloaded ? number_format( $data->downloaded ) : _x( 'n/a', 'not available', 'tribe-common' );
395
+ } else {
396
+ // If there was a bug on the Current Request just leave
397
+ return false;
398
+ }
399
+
400
+ set_transient( $transient, $data, $timeout );
401
+ }
402
+ $data->up_to_date = ( version_compare( $plugin->version, $data->version, '<' ) ) ? esc_html__( 'You need to upgrade!', 'tribe-common' ) : esc_html__( 'You are up to date!', 'tribe-common' );
403
+
404
+ /**
405
+ * Filters the API data that was stored in the Transient option
406
+ *
407
+ * @var array
408
+ * @var object The plugin object, check `$this->get_plugins()` for more info
409
+ */
410
+ return (object) apply_filters( 'tribe_help_api_data', $data, $plugin );
411
+ }
412
+
413
+ /**
414
+ * Parses the help text from an Array to the final HTML.
415
+ *
416
+ * It is the responsibility of code calling this function to ensure proper escaping
417
+ * within any HTML.
418
+ *
419
+ * @since 4.0
420
+ *
421
+ * @param string|array $mixed The mixed value to create the HTML from
422
+ * @return string
423
+ */
424
+ public function get_content_html( $mixed = '' ) {
425
+ // If it's an StdObj or String it will be converted
426
+ $mixed = (array) $mixed;
427
+
428
+ // Loop to start the HTML
429
+ foreach ( $mixed as &$line ) {
430
+ // If we have content we use that
431
+ if ( ! empty( $line->content ) ) {
432
+ $line = $line->content;
433
+ }
434
+
435
+ if ( is_string( $line ) ) {
436
+ continue;
437
+ } elseif ( is_array( $line ) ) {
438
+ // Allow the developer to pass some configuration
439
+ if ( empty( $line['type'] ) ) {
440
+ $line['type'] = 'ul';
441
+ }
442
+
443
+ $text = '<' . $line['type'] . '>' . "\n";
444
+ foreach ( $line as $key => $item ) {
445
+ // Don't add non-numeric items (a.k.a.: configuration)
446
+ if ( ! is_numeric( $key ) ) {
447
+ continue;
448
+ }
449
+
450
+ // Only add List Item if is a UL or OL
451
+ if ( in_array( $line['type'], array( 'ul', 'ol' ) ) ) {
452
+ $text .= '<li>' . "\n";
453
+ }
454
+
455
+ $text .= $this->get_content_html( $item );
456
+
457
+ if ( in_array( $line['type'], array( 'ul', 'ol' ) ) ) {
458
+ $text .= '</li>' . "\n";
459
+ }
460
+ }
461
+ $text .= '</' . $line['type'] . '>' . "\n";
462
+
463
+ // Create the list as html instead of array
464
+ $line = $text;
465
+ }
466
+ }
467
+
468
+ return wpautop( implode( "\n\n", $mixed ) );
469
+ }
470
+
471
+ /**
472
+ * A Private storage for sections.
473
+ *
474
+ * @since 4.0
475
+ *
476
+ * @access private
477
+ * @var array
478
+ */
479
+ private $sections = array();
480
+
481
+ /**
482
+ * Incremented with each method call, then stored in $section->uid.
483
+ *
484
+ * Used when sorting two instances whose priorities are equal.
485
+ *
486
+ * @since 4.0
487
+ *
488
+ * @static
489
+ * @access protected
490
+ * @var int
491
+ */
492
+ protected static $section_count = 0;
493
+
494
+ /**
495
+ * Helper function to compare two objects by priority, ensuring sort stability via uid.
496
+ *
497
+ * @since 4.0
498
+ *
499
+ * @access protected
500
+ * @param object $a Object A.
501
+ * @param object $b Object B.
502
+ *
503
+ * @return int
504
+ */
505
+ protected function by_priority( $a, $b ) {
506
+ if ( empty( $a->priority ) || empty( $b->priority ) || $a->priority === $b->priority ) {
507
+ if ( empty( $a->unique_call_order ) || empty( $b->unique_call_order ) ) {
508
+ return 0;
509
+ } else {
510
+ return $a->unique_call_order - $b->unique_call_order;
511
+ }
512
+ } else {
513
+ return $a->priority - $b->priority;
514
+ }
515
+ }
516
+
517
+ /**
518
+ * Adds a new section to the Help Page
519
+ *
520
+ * @since 4.0
521
+ *
522
+ * @param string $id HTML like ID
523
+ * @param string $title The Title of the section, doesn't allow HTML
524
+ * @param integer $priority A Numeric ordering for the Section
525
+ * @param string $type by default only 'default' or 'box'
526
+ *
527
+ * @return object The section added
528
+ */
529
+ public function add_section( $id, $title = null, $priority = 10, $type = 'default' ) {
530
+ if ( empty( $id ) ) {
531
+ return false;
532
+ }
533
+
534
+ // Everytime you call this we will add this up
535
+ self::$section_count++;
536
+
537
+ $possible_types = (array) apply_filters( 'tribe_help_available_section_types', array( 'default', 'box' ) );
538
+
539
+ // Set a Default type
540
+ if ( empty( $type ) || ! in_array( $type, $possible_types ) ) {
541
+ $type = 'default';
542
+ }
543
+
544
+ // Create the section and Sanitize the values to avoid having to do it later
545
+ $section = (object) array(
546
+ 'id' => sanitize_html_class( $id ),
547
+ 'title' => esc_html( $title ),
548
+ 'priority' => absint( $priority ),
549
+ 'type' => sanitize_html_class( $type ),
550
+
551
+ // This Method Unique count integer used for ordering with priority
552
+ 'unique_call_order' => self::$section_count,
553
+
554
+ // Counter for ordering Content
555
+ 'content_count' => 0,
556
+
557
+ // Setup the Base for the content to come
558
+ 'content' => array(),
559
+ );
560
+
561
+ $this->sections[ $section->id ] = $section;
562
+
563
+ return $section;
564
+ }
565
+
566
+ /**
567
+ * Add a New content Item to a Help page Section
568
+ *
569
+ * @since 4.0
570
+ *
571
+ * @param string $section_id Which section this content should be assigned to
572
+ * @param string|array $content Item text or array of items, will be passed to `$this->get_content_html`
573
+ * @param integer $priority A Numeric priority
574
+ * @param array $arguments If you need arguments for item, they can be passed here
575
+ *
576
+ * @return object The content item added
577
+ */
578
+ public function add_section_content( $section_id, $content, $priority = 10, $arguments = array() ) {
579
+ $section_id = sanitize_html_class( $section_id );
580
+
581
+ // Check if the section exists
582
+ if ( empty( $this->sections[ $section_id ] ) ) {
583
+ return false;
584
+ }
585
+
586
+ // Make sure we have arguments as Array
587
+ if ( ! is_array( $arguments ) ) {
588
+ return false;
589
+ }
590
+
591
+ $section = &$this->sections[ $section_id ];
592
+
593
+ // Increment the content counter
594
+ $section->content_count++;
595
+
596
+ $item = (object) $arguments;
597
+
598
+ // Set the priority
599
+ $item->priority = absint( $priority );
600
+
601
+ // Set the uid to help ordering
602
+ $item->unique_call_order = $section->content_count;
603
+
604
+ // Content is not Safe, will be Sanitized on Output
605
+ $item->content = $content;
606
+
607
+ $section->content[] = $item;
608
+
609
+ return $item;
610
+ }
611
+
612
+ /**
613
+ * Remove a section based on the ID
614
+ * This method will remove any sections that are indexed at that ID on the sections array
615
+ * And the sections that have a propriety of `id` equals to the given $section_id argument
616
+ *
617
+ * @param string|int $section_id You can use Numeric or String indexes to search
618
+ * @return bool|int Returns `false` when no sections were removed and an `int` with the number of sections removed
619
+ */
620
+ public function remove_section( $section_id ) {
621
+ if (
622
+ ! isset( $this->sections[ $section_id ] ) &&
623
+ ! in_array( (object) array( 'id' => $section_id ), $this->sections, true )
624
+ ) {
625
+ // There are no sections to remove, so false
626
+ return false;
627
+ }
628
+
629
+ $removed = array();
630
+ foreach ( $this->sections as $id => $section ) {
631
+ if ( ! is_numeric( $id ) && ! is_numeric( $section_id ) && ! empty( $section->id ) ) {
632
+ if ( $section->id === $section_id ) {
633
+ unset( $this->sections[ $id ] );
634
+ // Mark that this section was removed
635
+ $removed[ $id ] = true;
636
+ }
637
+ } elseif ( $id === $section_id ) {
638
+ unset( $this->sections[ $section_id ] );
639
+ // Mark that this section was removed
640
+ $removed[ $id ] = true;
641
+ } else {
642
+ // Mark that this section was NOT removed
643
+ $removed[ $id ] = false;
644
+ }
645
+ }
646
+
647
+ // Count how many were removed
648
+ $total = count( array_filter( $removed ) );
649
+
650
+ // if Zero just return false
651
+ return $total === 0 ? false : $total;
652
+ }
653
+
654
+ /**
655
+ * Based on an Array of sections it render the Help Page contents
656
+ *
657
+ * @since 4.0
658
+ *
659
+ * @param boolean $print Return or Print the HTML after
660
+ * @return void|string
661
+ */
662
+ public function get_sections( $print = true ) {
663
+ /**
664
+ * Allow third-party sections here
665
+ *
666
+ * @var Tribe__Admin__Help_Page
667
+ */
668
+ do_action( 'tribe_help_pre_get_sections', $this );
669
+
670
+ /**
671
+ * Allow developers to filter all the sections at once
672
+ * NOTE: You should be using `tribe_help_add_sections` to add new sections or content
673
+ *
674
+ * @var array
675
+ */
676
+ $sections = apply_filters( 'tribe_help_sections', $this->sections );
677
+
678
+ if ( ! is_array( $sections ) || empty( $sections ) ) {
679
+ return false;
680
+ }
681
+
682
+ // Sort by Priority
683
+ uasort( $sections, array( $this, 'by_priority' ) );
684
+
685
+ $html = array();
686
+
687
+ foreach ( $sections as $index => $section ) {
688
+ $section = (object) $section;
689
+
690
+ // If it has no ID or Content, skip
691
+ if ( empty( $section->id ) || empty( $section->content ) ) {
692
+ continue;
693
+ }
694
+
695
+ // Set a Default type
696
+ if ( empty( $section->type ) ) {
697
+ $section->type = 'default';
698
+ }
699
+
700
+ /**
701
+ * Creates a way to filter a specific section based on the ID
702
+ *
703
+ * @var object
704
+ */
705
+ $section = apply_filters( 'tribe_help_section_' . $section->id, $section, $this );
706
+
707
+ // Sort by Priority
708
+ uasort( $section->content, array( $this, 'by_priority' ) );
709
+
710
+ $html[ $section->id . '-start' ] = '<div id="tribe-' . sanitize_html_class( $section->id ) . '" class="tribe-help-section clearfix tribe-section-type-' . sanitize_html_class( $section->type ) . '">';
711
+
712
+ if ( ! empty( $section->title ) ) {
713
+ $html[ $section->id . '-title' ] = '<h3 class="tribe-help-title">' . esc_html__( $section->title ) . '</h3>';
714
+ }
715
+
716
+ $html[ $section->id . '-content' ] = $this->get_content_html( $section->content );
717
+
718
+ $html[ $section->id . '-end' ] = '</div>';
719
+ }
720
+
721
+ /**
722
+ * Creates a way for developers to hook to the final HTML
723
+ * @var array $html
724
+ * @var array $sections
725
+ */
726
+ $html = apply_filters( 'tribe_help_sections_html', $html, $sections );
727
+
728
+ if ( true === $print ) {
729
+ echo implode( "\n", $html );
730
+ } else {
731
+ return $html;
732
+ }
733
+
734
+ }
735
+
736
+ /**
737
+ * Prints the Plugin box for the given plugin
738
+ *
739
+ * @since 4.0
740
+ *
741
+ * @param string $plugin Plugin Name key
742
+ * @return void
743
+ */
744
+ public function print_plugin_box( $plugin ) {
745
+ $plugin = (object) $this->get_plugins( $plugin, false );
746
+ $api_data = $this->get_plugin_api_data( $plugin );
747
+ $addons = $this->get_addons( $plugin->name );
748
+ $plugins = get_plugins();
749
+
750
+ if ( $api_data ) {
751
+ if ( ! function_exists( 'install_plugin_install_status' ) ) {
752
+ include_once ABSPATH . '/wp-admin/includes/plugin-install.php';
753
+ }
754
+ $status = install_plugin_install_status( $api_data );
755
+ $plugin_active = is_plugin_active( $status['file'] );
756
+ $plugin_exists = isset( $plugins[ $status['file'] ] );
757
+
758
+ if ( 'install' !== $status['status'] && ! $plugin_active ) {
759
+ $args = array(
760
+ 'action' => 'activate',
761
+ 'plugin' => $status['file'],
762
+ 'plugin_status' => 'all',
763
+ 'paged' => 1,
764
+ 's' => '',
765
+ );
766
+ $activate_url = wp_nonce_url( add_query_arg( $args, 'plugins.php' ), 'activate-plugin_' . $status['file'] );
767
+ $link = '<a class="button" href="' . $activate_url . '" aria-label="' . esc_attr( sprintf( esc_attr__( 'Activate %s', 'tribe-common' ), $plugin->name ) ) . '">' . esc_html__( 'Activate Plugin', 'tribe-common' ) . '</a>';
768
+ } elseif ( 'update_available' === $status['status'] ) {
769
+ $args = array(
770
+ 'action' => 'upgrade-plugin',
771
+ 'plugin' => $status['file'],
772
+ );
773
+ $update_url = wp_nonce_url( add_query_arg( $args, 'update.php' ), 'upgrade-plugin_' . $status['file'] );
774
+
775
+ $link = '<a class="button" href="' . $update_url . '">' . esc_html__( 'Upgrade Plugin', 'tribe-common' ) . '</a>';
776
+ } elseif ( $plugin_exists ) {
777
+ $link = '<a class="button disabled">' . esc_html__( 'You are up to date!', 'tribe-common' ) . '</a>';
778
+ }
779
+ }
780
+
781
+ if ( ! isset( $link ) ) {
782
+ if ( $api_data ) {
783
+ $args = array(
784
+ 'tab' => 'plugin-information',
785
+ 'plugin' => $plugin->name,
786
+ 'TB_iframe' => true,
787
+ 'width' => 772,
788
+ 'height' => 600,
789
+ );
790
+ $iframe_url = add_query_arg( $args, admin_url( '/plugin-install.php' ) );
791
+ $link = '<a class="button thickbox" href="' . $iframe_url . '" aria-label="' . esc_attr( sprintf( esc_attr__( 'Install %s', 'tribe-common' ), $plugin->name ) ) . '">' . esc_html__( 'Install Plugin', 'tribe-common' ) . '</a>';
792
+ } else {
793
+ $link = null;
794
+ }
795
+ }
796
+ ?>
797
+ <div class="tribe-help-plugin-info">
798
+ <h3><a href="<?php echo esc_url( $plugin->repo ); ?>"><?php echo esc_html( $plugin->title ); ?></a></h3>
799
+
800
+ <?php
801
+ if ( ! empty( $plugin->description ) && ! $plugin->is_active ) {
802
+ echo wpautop( $plugin->description );
803
+ }
804
+ ?>
805
+
806
+ <?php if ( $api_data ) { ?>
807
+ <dl>
808
+ <dt><?php esc_html_e( 'Latest Version:', 'tribe-common' ); ?></dt>
809
+ <dd><?php echo esc_html( $api_data->version ); ?></dd>
810
+
811
+ <dt><?php esc_html_e( 'Requires:', 'tribe-common' ); ?></dt>
812
+ <dd><?php echo esc_html__( 'WordPress ', 'tribe-common' ) . esc_html( $api_data->requires ); ?>+</dd>
813
+
814
+ <dt><?php esc_html_e( 'Active Users:', 'tribe-common' ); ?></dt>
815
+ <dd><?php echo esc_html( number_format( $api_data->active_installs ) ); ?>+</dd>
816
+
817
+ <dt><?php esc_html_e( 'Rating:', 'tribe-common' ); ?></dt>
818
+ <dd><a href="<?php echo esc_url( $plugin->stars_url ); ?>" target="_blank">
819
+ <?php wp_star_rating( array(
820
+ 'rating' => $api_data->rating,
821
+ 'type' => 'percent',
822
+ 'number' => $api_data->num_ratings,
823
+ ) );?>
824
+ </a></dd>
825
+ </dl>
826
+ <?php } ?>
827
+
828
+ <?php
829
+ // Only show the link to the users can use it
830
+ if ( current_user_can( 'update_plugins' ) && current_user_can( 'install_plugins' ) ) {
831
+ echo $link ? '<p style="text-align: center;">' . $link . '</p>' : '';
832
+ }
833
+ ?>
834
+
835
+ <?php if ( ! empty( $addons ) ) { ?>
836
+ <h3><?php esc_html_e( 'Premium Add-Ons', 'tribe-common' ); ?></h3>
837
+ <ul class='tribe-list-addons'>
838
+ <?php foreach ( $addons as $addon ) {
839
+ $addon = (object) $addon;
840
+
841
+ if ( isset( $addon->is_active ) && $addon->is_active ) {
842
+ $active_title = __( 'Plugin Active', 'tribe-common' );
843
+ } else {
844
+ $active_title = __( 'Plugin Inactive', 'tribe-common' );
845
+ }
846
+
847
+ echo '<li title="' . esc_attr( $active_title ) . '" class="' . ( isset( $addon->is_active ) && $addon->is_active ? 'tribe-active-addon' : '' ) . '">';
848
+ if ( isset( $addon->link ) ) {
849
+ echo '<a href="' . esc_url( $addon->link ) . '" title="' . esc_attr__( 'Visit the Add-on Page', 'tribe-common' ) . '" target="_blank">';
850
+ }
851
+ echo esc_html( $addon->title );
852
+ if ( isset( $addon->link ) ) {
853
+ echo '</a>';
854
+ }
855
+ echo '</li>';
856
+ } ?>
857
+ </ul>
858
+ <?php } ?>
859
+ </div>
860
+ <?php
861
+ }
862
  }
common/src/Tribe/Admin/Helpers.php CHANGED
@@ -1,163 +1,163 @@
1
- <?php
2
-
3
- // Don't load directly
4
- if ( ! defined( 'ABSPATH' ) ) {
5
- die( '-1' );
6
- }
7
-
8
- /**
9
- * Class with a few helpers for the Administration Pages
10
- */
11
- class Tribe__Admin__Helpers {
12
- /**
13
- * Static Singleton Holder
14
- * @var Tribe__Admin__Helpers|null
15
- */
16
- protected static $instance;
17
-
18
- /**
19
- * Static Singleton Factory Method
20
- *
21
- * @return Tribe__Admin__Helpers
22
- */
23
- public static function instance() {
24
- if ( empty( self::$instance ) ) {
25
- self::$instance = new self();
26
- }
27
-
28
- return self::$instance;
29
- }
30
-
31
- /**
32
- * Matcher for Admin Pages related to Post Types
33
- *
34
- * @param string|array|null $id What will be checked to see if we return true or false
35
- *
36
- * @return boolean
37
- */
38
- public function is_post_type_screen( $post_type = null ) {
39
- global $current_screen;
40
-
41
- // Not in the admin we don't even care
42
- if ( ! is_admin() ) {
43
- return false;
44
- }
45
-
46
- // Doing AJAX? bail.
47
- if ( Tribe__Main::instance()->doing_ajax() ) {
48
- return false;
49
- }
50
-
51
- // Avoid Notices by checking the object type of WP_Screen
52
- if ( ! ( $current_screen instanceof WP_Screen ) ) {
53
- return false;
54
- }
55
-
56
- $defaults = apply_filters( 'tribe_is_post_type_screen_post_types', Tribe__Main::get_post_types() );
57
-
58
- // Match any Post Type from Tribe
59
- if ( is_null( $post_type ) && in_array( $current_screen->post_type, $defaults ) ) {
60
- return true;
61
- }
62
-
63
- // Match any of the post_types set
64
- if ( ! is_scalar( $post_type ) && in_array( $current_screen->post_type, (array) $post_type ) ) {
65
- return true;
66
- }
67
-
68
- // Match a specific Post Type
69
- if ( $current_screen->post_type === $post_type ) {
70
- return true;
71
- }
72
-
73
- return false;
74
- }
75
-
76
- /**
77
- * Matcher for administration pages that are from Tribe the easier way
78
- *
79
- * @param string|array|null $id What will be checked to see if we return true or false
80
- *
81
- * @return boolean
82
- */
83
- public function is_screen( $id = null ) {
84
- global $current_screen;
85
-
86
- // Not in the admin we don't even care
87
- if ( ! is_admin() ) {
88
- return false;
89
- }
90
-
91
- // Doing AJAX? bail.
92
- if ( Tribe__Main::instance()->doing_ajax() ) {
93
- return false;
94
- }
95
-
96
- // Avoid Notices by checking the object type of WP_Screen
97
- if ( ! ( $current_screen instanceof WP_Screen ) ) {
98
- return false;
99
- }
100
-
101
- // Match any screen from Tribe
102
- if ( is_null( $id ) && false !== strpos( $current_screen->id, 'tribe' ) ) {
103
- return true;
104
- }
105
-
106
- // Match any post type page in the supported post types
107
- $defaults = apply_filters( 'tribe_is_post_type_screen_post_types', Tribe__Main::get_post_types() );
108
-
109
- if ( in_array( $current_screen->post_type, $defaults ) ) {
110
- return true;
111
- }
112
-
113
- // Match any of the pages set
114
- if ( ! is_scalar( $id ) && in_array( $current_screen->id, (array) $id ) ) {
115
- return true;
116
- }
117
-
118
- // Match a specific page
119
- if ( $current_screen->id === $id ) {
120
- return true;
121
- }
122
-
123
- return false;
124
- }
125
-
126
- /**
127
- * Matcher for administration pages action
128
- *
129
- * @param string|array|null $action What will be checked to see if we return true or false
130
- *
131
- * @return boolean
132
- */
133
- public function is_action( $action = null ) {
134
- global $current_screen;
135
-
136
- // Not in the admin we don't even care
137
- if ( ! is_admin() ) {
138
- return false;
139
- }
140
-
141
- // Doing AJAX? bail.
142
- if ( Tribe__Main::instance()->doing_ajax() ) {
143
- return false;
144
- }
145
-
146
- // Avoid Notices by checking the object type of WP_Screen
147
- if ( ! ( $current_screen instanceof WP_Screen ) ) {
148
- return false;
149
- }
150
-
151
- // Match any of the pages set
152
- if ( ! is_scalar( $action ) && in_array( $current_screen->action, (array) $action ) ) {
153
- return true;
154
- }
155
-
156
- // Match a specific page
157
- if ( $current_screen->action === $action ) {
158
- return true;
159
- }
160
-
161
- return false;
162
- }
163
- }
1
+ <?php
2
+
3
+ // Don't load directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ die( '-1' );
6
+ }
7
+
8
+ /**
9
+ * Class with a few helpers for the Administration Pages
10
+ */
11
+ class Tribe__Admin__Helpers {
12
+ /**
13
+ * Static Singleton Holder
14
+ * @var Tribe__Admin__Helpers|null
15
+ */
16
+ protected static $instance;
17
+
18
+ /**
19
+ * Static Singleton Factory Method
20
+ *
21
+ * @return Tribe__Admin__Helpers
22
+ */
23
+ public static function instance() {
24
+ if ( empty( self::$instance ) ) {
25
+ self::$instance = new self();
26
+ }
27
+
28
+ return self::$instance;
29
+ }
30
+
31
+ /**
32
+ * Matcher for Admin Pages related to Post Types
33
+ *
34
+ * @param string|array|null $id What will be checked to see if we return true or false
35
+ *
36
+ * @return boolean
37
+ */
38
+ public function is_post_type_screen( $post_type = null ) {
39
+ global $current_screen;
40
+
41
+ // Not in the admin we don't even care
42
+ if ( ! is_admin() ) {
43
+ return false;
44
+ }
45
+
46
+ // Doing AJAX? bail.
47
+ if ( Tribe__Main::instance()->doing_ajax() ) {
48
+ return false;
49
+ }
50
+
51
+ // Avoid Notices by checking the object type of WP_Screen
52
+ if ( ! ( $current_screen instanceof WP_Screen ) ) {
53
+ return false;
54
+ }
55
+
56
+ $defaults = apply_filters( 'tribe_is_post_type_screen_post_types', Tribe__Main::get_post_types() );
57
+
58
+ // Match any Post Type from Tribe
59
+ if ( is_null( $post_type ) && in_array( $current_screen->post_type, $defaults ) ) {
60
+ return true;
61
+ }
62
+
63
+ // Match any of the post_types set
64
+ if ( ! is_scalar( $post_type ) && in_array( $current_screen->post_type, (array) $post_type ) ) {
65
+ return true;
66
+ }
67
+
68
+ // Match a specific Post Type
69
+ if ( $current_screen->post_type === $post_type ) {
70
+ return true;
71
+ }
72
+
73
+ return false;
74
+ }
75
+
76
+ /**
77
+ * Matcher for administration pages that are from Tribe the easier way
78
+ *
79
+ * @param string|array|null $id What will be checked to see if we return true or false
80
+ *
81
+ * @return boolean
82
+ */
83
+ public function is_screen( $id = null ) {
84
+ global $current_screen;
85
+
86
+ // Not in the admin we don't even care
87
+ if ( ! is_admin() ) {
88
+ return false;
89
+ }
90
+
91
+ // Doing AJAX? bail.
92
+ if ( Tribe__Main::instance()->doing_ajax() ) {
93
+ return false;
94
+ }
95
+
96
+ // Avoid Notices by checking the object type of WP_Screen
97
+ if ( ! ( $current_screen instanceof WP_Screen ) ) {
98
+ return false;
99
+ }
100
+
101
+ // Match any screen from Tribe
102
+ if ( is_null( $id ) && false !== strpos( $current_screen->id, 'tribe' ) ) {
103
+ return true;
104
+ }
105
+
106
+ // Match any post type page in the supported post types
107
+ $defaults = apply_filters( 'tribe_is_post_type_screen_post_types', Tribe__Main::get_post_types() );
108
+
109
+ if ( in_array( $current_screen->post_type, $defaults ) ) {
110
+ return true;
111
+ }
112
+
113
+ // Match any of the pages set
114
+ if ( ! is_scalar( $id ) && in_array( $current_screen->id, (array) $id ) ) {
115
+ return true;
116
+ }
117
+
118
+ // Match a specific page
119
+ if ( $current_screen->id === $id ) {
120
+ return true;
121
+ }
122
+
123
+ return false;
124
+ }
125
+
126
+ /**
127
+ * Matcher for administration pages action
128
+ *
129
+ * @param string|array|null $action What will be checked to see if we return true or false
130
+ *
131
+ * @return boolean
132
+ */
133
+ public function is_action( $action = null ) {
134
+ global $current_screen;
135
+
136
+ // Not in the admin we don't even care
137
+ if ( ! is_admin() ) {
138
+ return false;
139
+ }
140
+
141
+ // Doing AJAX? bail.
142
+ if ( Tribe__Main::instance()->doing_ajax() ) {
143
+ return false;
144
+ }
145
+
146
+ // Avoid Notices by checking the object type of WP_Screen
147
+ if ( ! ( $current_screen instanceof WP_Screen ) ) {
148
+ return false;
149
+ }
150
+
151
+ // Match any of the pages set
152
+ if ( ! is_scalar( $action ) && in_array( $current_screen->action, (array) $action ) ) {
153
+ return true;
154
+ }
155
+
156
+ // Match a specific page
157
+ if ( $current_screen->action === $action ) {
158
+ return true;
159
+ }
160
+
161
+ return false;
162
+ }
163
+ }
common/src/Tribe/Admin/Live_Date_Preview.php CHANGED
@@ -1,58 +1,58 @@
1
- <?php
2
- /**
3
- * Facilitiates live date previews in the Events > Settings > Display admin screen.
4
- */
5
- class Tribe__Admin__Live_Date_Preview {
6
- protected $target_fields = array(
7
- 'dateWithYearFormat',
8
- 'dateWithoutYearFormat',
9
- 'monthAndYearFormat',
10
- 'weekDayFormat',
11
- );
12
-
13
- /**
14
- * Adds live date previews to the display settings tab (nothing is setup unless
15
- * the user is actually on that tab).
16
- */
17
- public function __construct() {
18
- add_action( 'tribe_settings_after_do_tabs', array( $this, 'listen' ) );
19
- }
20
-
21
- /**
22
- * If the user looking at the Display settings tab, adds live date preview facilities.
23
- */
24
- public function listen() {
25
- // We are only interested in the "Display" tab
26
- if ( 'display' !== Tribe__Settings::instance()->currentTab ) {
27
- return;
28
- }
29
-
30
- /**
31
- * Add or remove fields which should have live date/time preview facilities.
32
- *
33
- * @var array $target_fields
34
- */
35
- $this->target_fields = (array) apply_filters( 'tribe_settings_date_preview_fields', $this->target_fields );
36
-
37
- add_filter( 'tribe_field_div_end', array( $this, 'setup_date_previews' ), 10, 2 );
38
- add_action( 'admin_enqueue_scripts', array( $this, 'live_refresh_script' ) );
39
- }
40
-
41
- public function setup_date_previews( $html, $field ) {
42
- // Not one of the fields we're interested in? Return without modification
43
- if ( ! in_array( $field->id, $this->target_fields ) ) {
44
- return $html;
45
- }
46
-
47
- $preview = esc_html( date_i18n( $field->value ) );
48
- return " <code class='live-date-preview'> $preview </code> $html";
49
- }
50
-
51
- /**
52
- * Enquues a script to handle live refresh of the date previews.
53
- */
54
- public function live_refresh_script() {
55
- $url = Tribe__Template_Factory::getMinFile( tribe_resource_url( 'admin-date-preview.js', false, 'common' ), true );
56
- wp_enqueue_script( 'tribe-date-live-refresh', $url, array( 'jquery' ), false, true );
57
- }
58
- }
1
+ <?php
2
+ /**
3
+ * Facilitiates live date previews in the Events > Settings > Display admin screen.
4
+ */
5
+ class Tribe__Admin__Live_Date_Preview {
6
+ protected $target_fields = array(
7
+ 'dateWithYearFormat',
8
+ 'dateWithoutYearFormat',
9
+ 'monthAndYearFormat',
10
+ 'weekDayFormat',
11
+ );
12
+
13
+ /**
14
+ * Adds live date previews to the display settings tab (nothing is setup unless
15
+ * the user is actually on that tab).
16
+ */
17
+ public function __construct() {
18
+ add_action( 'tribe_settings_after_do_tabs', array( $this, 'listen' ) );
19
+ }
20
+
21
+ /**
22
+ * If the user looking at the Display settings tab, adds live date preview facilities.
23
+ */
24
+ public function listen() {
25
+ // We are only interested in the "Display" tab
26
+ if ( 'display' !== Tribe__Settings::instance()->currentTab ) {
27
+ return;
28
+ }
29
+
30
+ /**
31
+ * Add or remove fields which should have live date/time preview facilities.
32
+ *
33
+ * @var array $target_fields
34
+ */
35
+ $this->target_fields = (array) apply_filters( 'tribe_settings_date_preview_fields', $this->target_fields );
36
+
37
+ add_filter( 'tribe_field_div_end', array( $this, 'setup_date_previews' ), 10, 2 );
38
+ add_action( 'admin_enqueue_scripts', array( $this, 'live_refresh_script' ) );
39
+ }
40
+
41
+ public function setup_date_previews( $html, $field ) {
42
+ // Not one of the fields we're interested in? Return without modification
43
+ if ( ! in_array( $field->id, $this->target_fields ) ) {
44
+ return $html;
45
+ }
46
+
47
+ $preview = esc_html( date_i18n( $field->value ) );
48
+ return " <code class='live-date-preview'> $preview </code> $html";
49
+ }
50
+
51
+ /**
52
+ * Enquues a script to handle live refresh of the date previews.
53
+ */
54
+ public function live_refresh_script() {
55
+ $url = Tribe__Template_Factory::getMinFile( tribe_resource_url( 'admin-date-preview.js', false, 'common' ), true );
56
+ wp_enqueue_script( 'tribe-date-live-refresh', $url, array( 'jquery' ), false, true );
57
+ }
58
+ }
common/src/Tribe/Admin/Notice/Archive_Slug_Conflict.php CHANGED
@@ -1,101 +1,101 @@
1
- <?php
2
-
3
-
4
- /**
5
- * Class Tribe__Admin__Notice__Archive_Slug_Conflict
6
- *
7
- * Takes care of adding an admin notice if a page with the `/events` slug has been created in the site.
8
- */
9
- class Tribe__Admin__Notice__Archive_Slug_Conflict {
10
-
11
- /**
12
- * @var static
13
- */
14
- protected static $instance;
15
-
16
- /**
17
- * @var string The slug of The Events Calendar archive page.
18
- */
19
- protected $archive_slug;
20
-
21
- /**
22
- * @var WP_Post The page post object.
23
- */
24
- protected $page;
25
-
26
- /**
27
- * @return Tribe__Admin__Notice__Archive_Slug_Conflict
28
- */
29
- public static function instance() {
30
- if ( empty( self::$instance ) ) {
31
- self::$instance = new self();
32
- }
33
-
34
- return self::$instance;
35
- }
36
-
37
- /**
38
- * Hooks the action to show an admin notice if a page with the `/events` slug exists on the site.
39
- */
40
- public function maybe_add_admin_notice() {
41
- $this->archive_slug = Tribe__Settings_Manager::get_option( 'eventsSlug', 'events' );
42
- $page = get_page_by_path( $this->archive_slug );
43
- if ( ! $page || $page->post_status == 'trash' ) {
44
- return;
45
- }
46
- $this->page = $page;
47
- $dismissed_notices = get_user_meta( get_current_user_id(), 'tribe-dismiss-notice' );
48
-
49
- if ( is_array( $dismissed_notices ) && in_array( 'archive-slug-conflict', $dismissed_notices ) ) {
50
- return;
51
- }
52
- add_action( 'admin_notices', array( $this, 'notice' ) );
53
- }
54
-
55
- /**
56
- * Hooked before maybe_add_admin_notice to prevent a notice to show it has been dimissed
57
- * @return void
58
- */
59
- public function maybe_dismiss() {
60
- if ( empty( $_GET['tribe-dismiss-notice'] ) ) {
61
- return;
62
- }
63
-
64
- $notice = esc_attr( $_GET['tribe-dismiss-notice'] );
65
-
66
- if ( 'archive-slug-conflict' !== $notice ) {
67
- return;
68
- }
69
-
70
- $dimissed_notices = get_user_meta( get_current_user_id(), 'tribe-dismiss-notice' );
71
- if ( in_array( 'archive-slug-conflict', $dimissed_notices ) ) {
72
- return;
73
- }
74
-
75
- add_user_meta( get_current_user_id(), 'tribe-dismiss-notice', 'archive-slug-conflict', false );
76
- }
77
-
78
- /**
79
- * Echoes the admin notice to the page
80
- */
81
- public function notice() {
82
- // What's happening?
83
- $page_title = apply_filters( 'the_title', $this->page->post_title, $this->page->ID );
84
- $line_1 = __( sprintf( 'The page "%1$s" uses the "/%2$s" slug: the Events Calendar plugin will show its calendar in place of the page.', $page_title, $this->archive_slug ), 'tribe-common' );
85
-
86
- // What the user can do
87
- $page_edit_link = get_edit_post_link( $this->page->ID );
88
- $can_edit_page_link = sprintf( __( '<a href="%s">Edit the page slug</a>', 'tribe-common' ), $page_edit_link );
89
- $page_edit_link_string = current_user_can( 'edit_pages' ) ? $can_edit_page_link : __( 'Ask the site administrator to edit the page slug', 'tribe-common' );
90
-
91
- $settings_cap = apply_filters( 'tribe_settings_req_cap', 'manage_options' );
92
- $admin_slug = apply_filters( 'tribe_settings_admin_slug', 'tribe-common' );
93
- $setting_page_link = apply_filters( 'tribe_settings_url', admin_url( 'edit.php?page=' . $admin_slug . '#tribe-field-eventsSlug' ) );
94
- $can_edit_settings_link = sprintf( __( '<a href="%s">edit Events settings</a>.', 'tribe-common' ), $setting_page_link );
95
- $events_settings_link_string = current_user_can( $settings_cap ) ? $can_edit_settings_link : __( ' ask the site administrator set a different Events URL slug.', 'tribe-common' );
96
-
97
- $line_2 = __( sprintf( '%1$s or %2$s', $page_edit_link_string, $events_settings_link_string ), 'tribe-common' );
98
-
99
- echo sprintf( '<div id="message" class="notice error is-dismissible tribe-dismiss-notice" data-ref="archive-slug-conflict"><p>%s</p><p>%s</p></div>', $line_1, $line_2 );
100
- }
101
- }
1
+ <?php
2
+
3
+
4
+ /**
5
+ * Class Tribe__Admin__Notice__Archive_Slug_Conflict
6
+ *
7
+ * Takes care of adding an admin notice if a page with the `/events` slug has been created in the site.
8
+ */
9
+ class Tribe__Admin__Notice__Archive_Slug_Conflict {
10
+
11
+ /**
12
+ * @var static
13
+ */
14
+ protected static $instance;
15
+
16
+ /**
17
+ * @var string The slug of The Events Calendar archive page.
18
+ */
19
+ protected $archive_slug;
20
+
21
+ /**
22
+ * @var WP_Post The page post object.
23
+ */
24
+ protected $page;
25
+
26
+ /**
27
+ * @return Tribe__Admin__Notice__Archive_Slug_Conflict
28
+ */
29
+ public static function instance() {
30
+ if ( empty( self::$instance ) ) {
31
+ self::$instance = new self();
32
+ }
33
+
34
+ return self::$instance;
35
+ }
36
+
37
+ /**
38
+ * Hooks the action to show an admin notice if a page with the `/events` slug exists on the site.
39
+ */
40
+ public function maybe_add_admin_notice() {
41
+ $this->archive_slug = Tribe__Settings_Manager::get_option( 'eventsSlug', 'events' );
42
+ $page = get_page_by_path( $this->archive_slug );
43
+ if ( ! $page || $page->post_status == 'trash' ) {
44
+ return;
45
+ }
46
+ $this->page = $page;
47
+ $dismissed_notices = get_user_meta( get_current_user_id(), 'tribe-dismiss-notice' );
48
+
49
+ if ( is_array( $dismissed_notices ) && in_array( 'archive-slug-conflict', $dismissed_notices ) ) {
50
+ return;
51
+ }
52
+ add_action( 'admin_notices', array( $this, 'notice' ) );
53
+ }
54
+
55
+ /**
56
+ * Hooked before maybe_add_admin_notice to prevent a notice to show it has been dimissed
57
+ * @return void
58
+ */
59
+ public function maybe_dismiss() {
60
+ if ( empty( $_GET['tribe-dismiss-notice'] ) ) {
61
+ return;
62
+ }
63
+
64
+ $notice = esc_attr( $_GET['tribe-dismiss-notice'] );
65
+
66
+ if ( 'archive-slug-conflict' !== $notice ) {
67
+ return;
68
+ }
69
+
70
+ $dimissed_notices = get_user_meta( get_current_user_id(), 'tribe-dismiss-notice' );
71
+ if ( in_array( 'archive-slug-conflict', $dimissed_notices ) ) {
72
+ return;
73
+ }
74
+
75
+ add_user_meta( get_current_user_id(), 'tribe-dismiss-notice', 'archive-slug-conflict', false );
76
+ }
77
+
78
+ /**
79
+ * Echoes the admin notice to the page
80
+ */
81
+ public function notice() {
82
+ // What's happening?
83
+ $page_title = apply_filters( 'the_title', $this->page->post_title, $this->page->ID );
84
+ $line_1 = __( sprintf( 'The page "%1$s" uses the "/%2$s" slug: the Events Calendar plugin will show its calendar in place of the page.', $page_title, $this->archive_slug ), 'tribe-common' );
85
+
86
+ // What the user can do
87
+ $page_edit_link = get_edit_post_link( $this->page->ID );
88
+ $can_edit_page_link = sprintf( __( '<a href="%s">Edit the page slug</a>', 'tribe-common' ), $page_edit_link );
89
+ $page_edit_link_string = current_user_can( 'edit_pages' ) ? $can_edit_page_link : __( 'Ask the site administrator to edit the page slug', 'tribe-common' );
90
+
91
+ $settings_cap = apply_filters( 'tribe_settings_req_cap', 'manage_options' );
92
+ $admin_slug = apply_filters( 'tribe_settings_admin_slug', 'tribe-common' );
93
+ $setting_page_link = apply_filters( 'tribe_settings_url', admin_url( 'edit.php?page=' . $admin_slug . '#tribe-field-eventsSlug' ) );
94
+ $can_edit_settings_link = sprintf( __( '<a href="%s">edit Events settings</a>.', 'tribe-common' ), $setting_page_link );
95
+ $events_settings_link_string = current_user_can( $settings_cap ) ? $can_edit_settings_link : __( ' ask the site administrator set a different Events URL slug.', 'tribe-common' );
96
+
97
+ $line_2 = __( sprintf( '%1$s or %2$s', $page_edit_link_string, $events_settings_link_string ), 'tribe-common' );
98
+
99
+ echo sprintf( '<div id="message" class="notice error is-dismissible tribe-dismiss-notice" data-ref="archive-slug-conflict"><p>%s</p><p>%s</p></div>', $line_1, $line_2 );
100
+ }
101
+ }
common/src/Tribe/Admin/Notice/Plugin_Upgrade_Notice.php CHANGED
@@ -1,239 +1,239 @@
1
- <?php
2
- /**
3
- * When appropriate, displays a plugin upgrade message "inline" within the plugin
4
- * admin screen.
5
- *
6
- * This is drawn from the Upgrade Notice section of the plugin readme.txt file (ie,
7
- * the one belonging to the current stable accessible via WP SVN - at least by
8
- * default).
9
- */
10
- class Tribe__Admin__Notice__Plugin_Upgrade_Notice {
11
- /**
12
- * Currently installed version of the plugin
13
- *
14
- * @var string
15
- */
16
- protected $current_version = '';
17
-
18
- /**
19
- * The plugin path as it is within the plugins directory, ie
20
- * "some-plugin/main-file.php".
21
- *
22
- * @var string
23
- */
24
- protected $plugin_path = '';
25
-
26
- /**
27
- * Contains the plugin upgrade notice (empty if none are available).
28
- *
29
- * @var string
30
- */
31
- protected $upgrade_notice = '';
32
-
33
-
34
- /**
35
- * Test for and display any plugin upgrade messages (if any are available) inline
36
- * beside the plugin listing itself.
37
- *
38
- * The optional third param is the object which actually checks to see if there
39
- * are any upgrade notices worth displaying. If not provided, an object of the
40
- * default type will be created (which connects to WP SVN).
41
- *
42
- * @param string $current_version
43
- * @param string $plugin_path (ie "plugin-dir/main-file.php")
44
- */
45
- public function __construct( $current_version, $plugin_path ) {
46
- $this->current_version = $current_version;
47
- $this->plugin_path = $plugin_path;
48
-
49
- add_action( "in_plugin_update_message-$plugin_path", array( $this, 'maybe_run' ) );
50
- }
51
-
52
- /**
53
- * Test if there is a plugin upgrade notice and displays it if so.
54
- *
55
- * Expects to fire during "in_plugin_update_message-{plugin_path}", therefore
56
- * this should only run if WordPress has detected that an upgrade is indeed
57
- * available.
58
- */
59
- public function maybe_run() {
60
- $this->test_for_upgrade_notice();
61
-
62
- if ( $this->upgrade_notice ) {
63
- $this->display_message();
64
- }
65
- }
66
-
67
- /**
68
- * Tests to see if an upgrade notice is available.
69
- */
70
- protected function test_for_upgrade_notice() {
71
- $cache_key = $this->cache_key();
72
- $this->upgrade_notice = get_transient( $cache_key );
73
-
74
- if ( false === $this->upgrade_notice ) {
75
- $this->discover_upgrade_notice();
76
- }
77
-
78
- set_transient( $cache_key, $this->upgrade_notice, $this->cache_expiration() );
79
- }
80
-
81
- /**
82
- * Returns a cache key unique to the current plugin path and version, that
83
- * still fits within the 45-char limit of regular WP transient keys.
84
- *
85
- * @return string
86
- */
87
- protected function cache_key() {
88
- return 'tribe_plugin_upgrade_notice-' . hash( 'crc32b', $this->plugin_path . $this->current_version );
89
- }
90
-
91
- /**
92
- * Returns the period of time (in seconds) for which to cache plugin upgrade messages.
93
- *
94
- * @return int
95
- */
96
- protected function cache_expiration() {
97
- /**
98
- * Number of seconds to cache plugin upgrade messages for.
99
- *
100
- * Defaults to one day, which provides a decent balance between efficiency savings
101
- * and allowing for the possibility that some upgrade messages may be changed or
102
- * rescinded.
103
- *
104
- * @var int $cache_expiration
105
- */
106
- return (int) apply_filters( 'tribe_plugin_upgrade_notice_expiration', DAY_IN_SECONDS, $this->plugin_path );
107
- }
108
-
109
- /**
110
- * Looks at the current stable plugin readme.txt and parses to try and find the first
111
- * available upgrade notice relating to a plugin version higher than this one.
112
- *
113
- * By default, WP SVN is the source.
114
- */
115
- protected function discover_upgrade_notice() {
116
- /**
117
- * The URL for the current plugin readme.txt file.
118
- *
119
- * @var string $url
120
- * @var string $plugin_path
121
- */
122
- $readme_url = apply_filters( 'tribe_plugin_upgrade_readme_url',
123
- $this->form_wp_svn_readme_url(),
124
- $this->plugin_path
125
- );
126
-
127
- if ( ! empty( $readme_url ) ) {
128
- $response = wp_safe_remote_get( $readme_url );
129
- }
130
-
131
- if ( ! empty( $response ) && ! is_wp_error( $response ) ) {
132
- $readme = $response['body'];
133
- }
134
-
135
- if ( ! empty( $readme ) ) {
136
- $this->parse_for_upgrade_notice( $readme );
137
- $this->format_upgrade_notice();
138
- }
139
-
140
- /**
141
- * The upgrade notice for the current plugin (may be empty).
142
- *
143
- * @var string $upgrade_notice
144
- * @var string $plugin_path
145
- */
146
- return apply_filters( 'tribe_plugin_upgrade_notice',
147
- $this->upgrade_notice,
148
- $this->plugin_path
149
- );
150
- }
151
-
152
- /**
153
- * Forms the expected URL to the trunk readme.txt file as it is on WP SVN
154
- * or an empty string if for any reason it cannot be determined.
155
- *
156
- * @return string
157
- */
158
- protected function form_wp_svn_readme_url() {
159
- $parts = explode( '/', $this->plugin_path );
160
- $slug = empty( $parts[0] ) ? '' : $parts[0];
161
- return esc_url( "https://plugins.svn.wordpress.org/$slug/trunk/readme.txt" );
162
- }
163
-
164
- /**
165
- * Given a standard Markdown-format WP readme.txt file, finds the first upgrade
166
- * notice (if any) for a version higher than $this->current_version.
167
- *
168
- * @param string $readme
169
- * @return string
170
- */
171
- protected function parse_for_upgrade_notice( $readme ) {
172
- $in_upgrade_notice = false;
173
- $in_version_notice = false;
174
- $readme_text = fopen( "data:://text/plain,$readme", 'r' );
175
-
176
- while ( $line = fgets( $readme_text ) ) {
177
- // Once we leave the Upgrade Notice section (ie, we encounter a new section header), bail
178
- if ( $in_upgrade_notice && 0 === strpos( $line, '==' ) ) {
179
- break;
180
- }
181
-
182
- // Look out for the start of the Upgrade Notice section
183
- if ( ! $in_upgrade_notice && preg_match( '/^==\s*Upgrade\s+Notice\s*==/i', $line ) ) {
184
- $in_upgrade_notice = true;
185
- }
186
-
187
- // Also test to see if we have left the version specific note (ie, we encounter a new sub heading or header)
188
- if ( $in_upgrade_notice && $in_version_notice && 0 === strpos( $line, '=' ) ) {
189
- break;
190
- }
191
-
192
- // Look out for the first applicable version-specific note within the Upgrade Notice section
193
- if ( $in_upgrade_notice && ! $in_version_notice && preg_match( '/^=\s*([0-9\.]{3,})\s*=/', $line, $matches ) ) {
194
- // Is this a higher version than currently installed?
195
- if ( version_compare( $matches[1], $this->current_version, '>' ) ) {
196
- $in_version_notice = true;
197
- }
198
- }
199
-
200
- // Copy the details of the upgrade notice for the first higher version we find
201
- if ( $in_upgrade_notice && $in_version_notice ) {
202
- $this->upgrade_notice .= $line;
203
- }
204
- }
205
- }
206
-
207
- /**
208
- * Convert the plugin version header and any links from Markdown to HTML.
209
- */
210
- protected function format_upgrade_notice() {
211
- // Convert [links](http://...) to <a href="..."> tags
212
- $this->upgrade_notice = preg_replace(
213
- '/\[([^\]]*)\]\(([^\)]*)\)/',
214
- '<a href="${2}">${1}</a>',
215
- $this->upgrade_notice
216
- );
217
-
218
- // Convert =4.0= headings to <h4 class="version">4.0</h4> tags
219
- $this->upgrade_notice = preg_replace(
220
- '/=\s*([a-zA-Z0-9\.]{3,})\s*=/',
221
- '<h4 class="version">${1}</h4>',
222
- $this->upgrade_notice
223
- );
224
- }
225
-
226
- /**
227
- * Render the actual upgrade notice.
228
- *
229
- * Please note if plugin-specific styling is required for the message, you can
230
- * use an ID generated by WordPress for one of the message's parent elements
231
- * which takes the form "{plugin_name}-update". Example:
232
- *
233
- * #the-events-calendar-update .tribe-plugin-update-message { ... }
234
- */
235
- public function display_message() {
236
- $notice = wp_kses_post( $this->upgrade_notice );
237
- echo "<div class='tribe-plugin-update-message'> $notice </div>";
238
- }
239
  }
1
+ <?php
2
+ /**
3
+ * When appropriate, displays a plugin upgrade message "inline" within the plugin
4
+ * admin screen.
5
+ *
6
+ * This is drawn from the Upgrade Notice section of the plugin readme.txt file (ie,
7
+ * the one belonging to the current stable accessible via WP SVN - at least by
8
+ * default).
9
+ */
10
+ class Tribe__Admin__Notice__Plugin_Upgrade_Notice {
11
+ /**
12
+ * Currently installed version of the plugin
13
+ *
14
+ * @var string
15
+ */
16
+ protected $current_version = '';
17
+
18
+ /**
19
+ * The plugin path as it is within the plugins directory, ie
20
+ * "some-plugin/main-file.php".
21
+ *
22
+ * @var string
23
+ */
24
+ protected $plugin_path = '';
25
+
26
+ /**
27
+ * Contains the plugin upgrade notice (empty if none are available).
28
+ *
29
+ * @var string
30
+ */
31
+ protected $upgrade_notice = '';
32
+
33
+
34
+ /**
35
+ * Test for and display any plugin upgrade messages (if any are available) inline
36
+ * beside the plugin listing itself.
37
+ *
38
+ * The optional third param is the object which actually checks to see if there
39
+ * are any upgrade notices worth displaying. If not provided, an object of the
40
+ * default type will be created (which connects to WP SVN).
41
+ *
42
+ * @param string $current_version
43
+ * @param string $plugin_path (ie "plugin-dir/main-file.php")
44
+ */
45
+ public function __construct( $current_version, $plugin_path ) {
46
+ $this->current_version = $current_version;
47
+ $this->plugin_path = $plugin_path;
48
+
49
+ add_action( "in_plugin_update_message-$plugin_path", array( $this, 'maybe_run' ) );
50
+ }
51
+
52
+ /**
53
+ * Test if there is a plugin upgrade notice and displays it if so.
54
+ *
55
+ * Expects to fire during "in_plugin_update_message-{plugin_path}", therefore
56
+ * this should only run if WordPress has detected that an upgrade is indeed
57
+ * available.
58
+ */
59
+ public function maybe_run() {
60
+ $this->test_for_upgrade_notice();
61
+
62
+ if ( $this->upgrade_notice ) {
63
+ $this->display_message();
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Tests to see if an upgrade notice is available.
69
+ */
70
+ protected function test_for_upgrade_notice() {
71
+ $cache_key = $this->cache_key();
72
+ $this->upgrade_notice = get_transient( $cache_key );
73
+
74
+ if ( false === $this->upgrade_notice ) {
75
+ $this->discover_upgrade_notice();
76
+ }
77
+
78
+ set_transient( $cache_key, $this->upgrade_notice, $this->cache_expiration() );
79
+ }
80
+
81
+ /**
82
+ * Returns a cache key unique to the current plugin path and version, that
83
+ * still fits within the 45-char limit of regular WP transient keys.
84
+ *
85
+ * @return string
86
+ */
87
+ protected function cache_key() {
88
+ return 'tribe_plugin_upgrade_notice-' . hash( 'crc32b', $this->plugin_path . $this->current_version );
89
+ }
90
+
91
+ /**
92
+ * Returns the period of time (in seconds) for which to cache plugin upgrade messages.
93
+ *
94
+ * @return int
95
+ */
96
+ protected function cache_expiration() {
97
+ /**
98
+ * Number of seconds to cache plugin upgrade messages for.
99
+ *
100
+ * Defaults to one day, which provides a decent balance between efficiency savings
101
+ * and allowing for the possibility that some upgrade messages may be changed or
102
+ * rescinded.
103
+ *
104
+ * @var int $cache_expiration
105
+ */
106
+ return (int) apply_filters( 'tribe_plugin_upgrade_notice_expiration', DAY_IN_SECONDS, $this->plugin_path );
107
+ }
108
+
109
+ /**
110
+ * Looks at the current stable plugin readme.txt and parses to try and find the first
111
+ * available upgrade notice relating to a plugin version higher than this one.
112
+ *
113
+ * By default, WP SVN is the source.
114
+ */
115
+ protected function discover_upgrade_notice() {
116
+ /**
117
+ * The URL for the current plugin readme.txt file.
118
+ *
119
+ * @var string $url
120
+ * @var string $plugin_path
121
+ */
122
+ $readme_url = apply_filters( 'tribe_plugin_upgrade_readme_url',
123
+ $this->form_wp_svn_readme_url(),
124
+ $this->plugin_path
125
+ );
126
+
127
+ if ( ! empty( $readme_url ) ) {
128
+ $response = wp_safe_remote_get( $readme_url );
129
+ }
130
+
131
+ if ( ! empty( $response ) && ! is_wp_error( $response ) ) {
132
+ $readme = $response['body'];
133
+ }
134
+
135
+ if ( ! empty( $readme ) ) {
136
+ $this->parse_for_upgrade_notice( $readme );
137
+ $this->format_upgrade_notice();
138
+ }
139
+
140
+ /**
141
+ * The upgrade notice for the current plugin (may be empty).
142
+ *
143
+ * @var string $upgrade_notice
144
+ * @var string $plugin_path
145
+ */
146
+ return apply_filters( 'tribe_plugin_upgrade_notice',
147
+ $this->upgrade_notice,
148
+ $this->plugin_path
149
+ );
150
+ }
151
+
152
+ /**
153
+ * Forms the expected URL to the trunk readme.txt file as it is on WP SVN
154
+ * or an empty string if for any reason it cannot be determined.
155
+ *
156
+ * @return string
157
+ */
158
+ protected function form_wp_svn_readme_url() {
159
+ $parts = explode( '/', $this->plugin_path );
160
+ $slug = empty( $parts[0] ) ? '' : $parts[0];
161
+ return esc_url( "https://plugins.svn.wordpress.org/$slug/trunk/readme.txt" );
162
+ }
163
+
164
+ /**
165
+ * Given a standard Markdown-format WP readme.txt file, finds the first upgrade
166
+ * notice (if any) for a version higher than $this->current_version.
167
+ *
168
+ * @param string $readme
169
+ * @return string
170
+ */
171
+ protected function parse_for_upgrade_notice( $readme ) {
172
+ $in_upgrade_notice = false;
173
+ $in_version_notice = false;
174
+ $readme_text = fopen( "data:://text/plain,$readme", 'r' );
175
+
176
+ while ( $line = fgets( $readme_text ) ) {
177
+ // Once we leave the Upgrade Notice section (ie, we encounter a new section header), bail
178
+ if ( $in_upgrade_notice && 0 === strpos( $line, '==' ) ) {
179
+ break;
180
+ }
181
+
182
+ // Look out for the start of the Upgrade Notice section
183
+ if ( ! $in_upgrade_notice && preg_match( '/^==\s*Upgrade\s+Notice\s*==/i', $line ) ) {
184
+ $in_upgrade_notice = true;
185
+ }
186
+
187
+ // Also test to see if we have left the version specific note (ie, we encounter a new sub heading or header)
188
+ if ( $in_upgrade_notice && $in_version_notice && 0 === strpos( $line, '=' ) ) {
189
+ break;
190
+ }
191
+
192
+ // Look out for the first applicable version-specific note within the Upgrade Notice section
193
+ if ( $in_upgrade_notice && ! $in_version_notice && preg_match( '/^=\s*([0-9\.]{3,})\s*=/', $line, $matches ) ) {
194
+ // Is this a higher version than currently installed?
195
+ if ( version_compare( $matches[1], $this->current_version, '>' ) ) {
196
+ $in_version_notice = true;
197
+ }
198
+ }
199
+
200
+ // Copy the details of the upgrade notice for the first higher version we find
201
+ if ( $in_upgrade_notice && $in_version_notice ) {
202
+ $this->upgrade_notice .= $line;
203
+ }
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Convert the plugin version header and any links from Markdown to HTML.
209
+ */
210
+ protected function format_upgrade_notice() {
211
+ // Convert [links](http://...) to <a href="..."> tags
212
+ $this->upgrade_notice = preg_replace(
213
+ '/\[([^\]]*)\]\(([^\)]*)\)/',
214
+ '<a href="${2}">${1}</a>',
215
+ $this->upgrade_notice
216
+ );
217
+
218
+ // Convert =4.0= headings to <h4 class="version">4.0</h4> tags
219
+ $this->upgrade_notice = preg_replace(
220
+ '/=\s*([a-zA-Z0-9\.]{3,})\s*=/',
221
+ '<h4 class="version">${1}</h4>',
222
+ $this->upgrade_notice
223
+ );
224
+ }
225
+
226
+ /**
227
+ * Render the actual upgrade notice.
228
+ *
229
+ * Please note if plugin-specific styling is required for the message, you can
230
+ * use an ID generated by WordPress for one of the message's parent elements
231
+ * which takes the form "{plugin_name}-update". Example:
232
+ *
233
+ * #the-events-calendar-update .tribe-plugin-update-message { ... }
234
+ */
235
+ public function display_message() {
236
+ $notice = wp_kses_post( $this->upgrade_notice );
237
+ echo "<div class='tribe-plugin-update-message'> $notice </div>";
238
+ }
239
  }
common/src/Tribe/App_Shop.php CHANGED
@@ -1,182 +1,182 @@
1
- <?php
2
-
3
- // don't load directly
4
- if ( ! defined( 'ABSPATH' ) ) {
5
- die( '-1' );
6
- }
7
-
8
- if ( ! class_exists( 'Tribe__App_Shop' ) ) {
9
- /**
10
- * Class that handles the integration with our Shop App API
11
- */
12
- class Tribe__App_Shop {
13
-
14
- /**
15
- * Slug of the WP admin menu item
16
- */
17
- const MENU_SLUG = 'tribe-app-shop';
18
-
19
- /**
20
- * Singleton instance
21
- *
22
- * @var null or Tribe__App_Shop
23
- */
24
- private static $instance = null;
25
- /**
26
- * The slug for the new admin page
27
- *
28
- * @var string
29
- */
30
- private $admin_page = null;
31
-
32
- /**
33
- * Class constructor
34
- */
35
- public function __construct() {
36
- add_action( 'admin_menu', array( $this, 'add_menu_page' ), 100 );
37
- add_action( 'wp_before_admin_bar_render', array( $this, 'add_toolbar_item' ), 20 );
38
- }
39
-
40
- /**
41
- * Adds the page to the admin menu
42
- */
43
- public function add_menu_page() {
44
- if ( ! Tribe__Settings::instance()->should_setup_pages() ) {
45
- return;
46
- }
47
-
48
- $page_title = esc_html__( 'Event Add-Ons', 'tribe-common' );
49
- $menu_title = esc_html__( 'Event Add-Ons', 'tribe-common' );
50
- $capability = apply_filters( 'tribe_events_addon_page_capability', 'install_plugins' );
51
-
52
- $where = Tribe__Settings::instance()->get_parent_slug();
53
-
54
- $this->admin_page = add_submenu_page( $where, $page_title, $menu_title, $capability, self::MENU_SLUG, array( $this, 'do_menu_page' ) );
55
-
56
- add_action( 'admin_print_styles-' . $this->admin_page, array( $this, 'enqueue' ) );
57
- }
58
-
59
- /**
60
- * Adds a link to the shop app to the WP admin bar
61
- */
62
- public function add_toolbar_item() {
63
-
64
- $capability = apply_filters( 'tribe_events_addon_page_capability', 'install_plugins' );
65
-
66
- // prevent users who cannot install plugins from seeing addons link
67
- if ( current_user_can( $capability ) ) {
68
- global $wp_admin_bar;
69
-
70
- $wp_admin_bar->add_menu( array(
71
- 'id' => 'tribe-events-app-shop',
72
- 'title' => esc_html__( 'Event Add-Ons', 'tribe-common' ),
73
- 'href' => Tribe__Settings::instance()->get_url( array( 'page' => self::MENU_SLUG ) ),
74
- 'parent' => 'tribe-events-settings-group',
75
- ) );
76
- }
77
- }
78
-
79
- /**
80
- * Enqueue the styles and script
81
- */
82
- public function enqueue() {
83
- wp_enqueue_style( 'app-shop', tribe_resource_url( 'app-shop.css', false, 'common' ), array(), apply_filters( 'tribe_events_css_version', Tribe__Main::VERSION ) );
84
- wp_enqueue_script( 'app-shop', tribe_resource_url( 'app-shop.js', false, 'common' ), array(), apply_filters( 'tribe_events_js_version', Tribe__Main::VERSION ) );
85
- }
86
-
87
- /**
88
- * Renders the Shop App page
89
- */
90
- public function do_menu_page() {
91
- $products = $this->get_all_products();
92
- include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/app-shop.php';
93
- }
94
-
95
- /**
96
- * Get's all products from the API
97
- *
98
- * @return array|WP_Error
99
- */
100
- private function get_all_products() {
101
- $products = array(
102
- (object) array(
103
- 'title' => __( 'Filter Bar', 'tribe-common' ),
104
- 'link' => 'https://theeventscalendar.com/product/wordpress-events-filterbar/?utm_campaign=in-app&utm_source=addonspage&utm_medium=wordpress-events-filterbar&utm_content=appstoreembedded-1',
105
- 'description' => __( 'It is awesome that your calendar is <em>THE PLACE</em> to get hooked up with prime choice ways to spend time. You have more events than Jabba the Hutt has rolls. Too bad visitors are hiring a personal assistant to go through all the choices. Ever wish you could just filter the calendar to only show events in walking distance, on a weekend, that are free? BOOM. Now you can. Introducing… the Filter Bar.', 'tribe-common' ),
106
- 'image' => 'images/app-shop-filter-bar.jpg',
107
- ),
108
- (object) array(
109
- 'title' => __( 'Events Calendar PRO', 'tribe-common' ),
110
- 'link' => 'https://theeventscalendar.com/product/wordpress-events-calendar-pro/?utm_campaign=in-app&utm_source=addonspage&utm_medium=wordpress-events-calendar-pro&utm_content=appstoreembedded-1',
111
- 'description' => sprintf(
112
- __( 'The Events Calendar PRO is a paid Add-On to our open source WordPress plugin %1$sThe Events Calendar%2$s. PRO offers a whole host of calendar features including recurring events, custom event attributes, saved venues and organizers, venue pages, advanced event admin and lots more.', 'tribe-common' ),
113
- '<a href="http://m.tri.be/18vc">',
114
- '</a>'
115
- ),
116
- 'image' => 'images/app-shop-pro.jpg',
117
- ),
118
- (object) array(
119
- 'title' => __( 'Community Events', 'tribe-common' ),
120
- 'link' => 'https://theeventscalendar.com/product/wordpress-community-events/?utm_campaign=in-app&utm_source=addonspage&utm_medium=wordpress-community-events&utm_content=appstoreembedded-1',
121
- 'description' => __( 'Enable users to submit events to your calendar with Community Events. You can require user accounts or allow visitors to submit without an account. Want to make sure that nothing fishy is going on? Just turn on moderation. Decide if users can edit and manage their own events, or simply submit. Plus, no scary form setup! Just activate, configure the options & off you go.', 'tribe-common' ),
122
- 'image' => 'images/app-shop-community.jpg',
123
- ),
124
- (object) array(
125
- 'title' => __( 'Community Tickets', 'tribe-common' ),
126
- 'link' => 'https://theeventscalendar.com/product/community-tickets/?utm_campaign=in-app&utm_source=addonspage&utm_medium=community-tickets&utm_content=appstoreembedded-1',
127
- 'description' => __( 'Enable Community Events organizers to offer tickets to their events. You can set flexible payment and fee options. They can even check-in attendees to their events! All of this managed from the front-end of your site without ever needing to grant access to your admin', 'tribe-common' ),
128
- 'requires' => _x( 'Event Tickets Plus and Community Events', 'Names of required plugins for Community Tickets', 'tribe-common' ),
129
- 'image' => 'images/app-shop-community-tickets.jpg',
130
- ),
131
- (object) array(
132
- 'title' => __( 'Event Tickets Plus', 'tribe-common' ),
133
- 'link' => 'https://theeventscalendar.com/product/wordpress-event-tickets-plus/?utm_campaign=in-app&utm_source=addonspage&utm_medium=wordpress-event-tickets-plus&utm_content=appstoreembedded-1',
134
- 'description' => sprintf(
135
- __( 'Event Tickets Plus allows you to sell tickets to your events using WooCommerce, Shopp, WP eCommerce, or Easy Digital Downloads. Use it on your posts and pages, or add %1$sThe Events Calendar%2$s and sell tickets from your events listings.', 'tribe-common' ),
136
- '<a href="http://m.tri.be/18vc">',
137
- '</a>'
138
- ),
139
- 'image' => 'images/app-shop-tickets-plus.jpg',
140
- ),
141
- (object) array(
142
- 'title' => __( 'Eventbrite Tickets', 'tribe-common' ),
143
- 'link' => 'https://theeventscalendar.com/product/wordpress-eventbrite-tickets/?utm_campaign=in-app&utm_source=addonspage&utm_medium=wordpress-eventbrite-tickets&utm_content=appstoreembedded-1',
144
- 'description' => sprintf(
145
- __( 'The Eventbrite Tickets add-on allows you to create & sell tickets through The Events Calendar using the power of %1$sEventbrite%2$s. Whether you’re creating your ticket on the WordPress dashboard or importing the details of an already-existing event from %1$sEventbrite.com%2$s, this add-on brings the power of the Eventbrite API to your calendar.', 'tribe-common' ),
146
- '<a href="http://www.eventbrite.com/r/etp">',
147
- '</a>'
148
- ),
149
- 'image' => 'images/app-shop-eventbrite.jpg',
150
- ),
151
- (object) array(
152
- 'title' => __( 'Facebook Events', 'tribe-common' ),
153
- 'link' => 'https://theeventscalendar.com/product/facebook-events/?utm_campaign=in-app&utm_source=addonspage&utm_medium=facebook-events&utm_content=appstoreembedded-1',
154
- 'description' => __( 'With the Facebook Events add-on, imported events are manually or automagically created as entries in The Events Calendar. Basic event data along with venue and organizer are populated appropriately. No more entering information in two places, or having to recreate someone else\'s listing for a public event you want to include on your WordPress calendar.', 'tribe-common' ),
155
- 'image' => 'images/app-shop-facebook.jpg',
156
- ),
157
- (object) array(
158
- 'title' => __( 'iCal Importer', 'tribe-common' ),
159
- 'link' => 'https://theeventscalendar.com/product/ical-importer/?utm_campaign=in-app&utm_source=addonspage&utm_medium=ical-importer&utm_content=appstoreembedded-1',
160
- 'description' => __( 'The iCal Importer helps you keep your events calendar full of interesting events! You can import events from any website that publishes an iCal (aka ICS) feed and add them to your listings. The recurring import feature lets you keep your calendar brimming without manual oversight (though you can review every imported event if you like). Add filtering by keyword or geographic region and you can be sure that the kinds of events you get are the kinds you want.', 'tribe-common' ),
161
- 'image' => 'images/app-shop-ical.jpg',
162
- ),
163
- );
164
-
165
- return $products;
166
- }
167
-
168
- /**
169
- * Static Singleton Factory Method
170
- *
171
- * @return Tribe__App_Shop
172
- */
173
- public static function instance() {
174
- if ( ! isset( self::$instance ) ) {
175
- $className = __CLASS__;
176
- self::$instance = new $className;
177
- }
178
-
179
- return self::$instance;
180
- }
181
- }
182
- }
1
+ <?php
2
+
3
+ // don't load directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ die( '-1' );
6
+ }
7
+
8
+ if ( ! class_exists( 'Tribe__App_Shop' ) ) {
9
+ /**
10
+ * Class that handles the integration with our Shop App API
11
+ */
12
+ class Tribe__App_Shop {
13
+
14
+ /**
15
+ * Slug of the WP admin menu item
16
+ */
17
+ const MENU_SLUG = 'tribe-app-shop';
18
+
19
+ /**
20
+ * Singleton instance
21
+ *
22
+ * @var null or Tribe__App_Shop
23
+ */
24
+ private static $instance = null;
25
+ /**
26
+ * The slug for the new admin page
27
+ *
28
+ * @var string
29
+ */
30
+ private $admin_page = null;
31
+
32
+ /**
33
+ * Class constructor
34
+ */
35
+ public function __construct() {
36
+ add_action( 'admin_menu', array( $this, 'add_menu_page' ), 100 );
37
+ add_action( 'wp_before_admin_bar_render', array( $this, 'add_toolbar_item' ), 20 );
38
+ }
39
+
40
+ /**
41
+ * Adds the page to the admin menu
42
+ */
43
+ public function add_menu_page() {
44
+ if ( ! Tribe__Settings::instance()->should_setup_pages() ) {
45
+ return;
46
+ }
47
+
48
+ $page_title = esc_html__( 'Event Add-Ons', 'tribe-common' );
49
+ $menu_title = esc_html__( 'Event Add-Ons', 'tribe-common' );
50
+ $capability = apply_filters( 'tribe_events_addon_page_capability', 'install_plugins' );
51
+
52
+ $where = Tribe__Settings::instance()->get_parent_slug();
53
+
54
+ $this->admin_page = add_submenu_page( $where, $page_title, $menu_title, $capability, self::MENU_SLUG, array( $this, 'do_menu_page' ) );
55
+
56
+ add_action( 'admin_print_styles-' . $this->admin_page, array( $this, 'enqueue' ) );
57
+ }
58
+
59
+ /**
60
+ * Adds a link to the shop app to the WP admin bar
61
+ */
62
+ public function add_toolbar_item() {
63
+
64
+ $capability = apply_filters( 'tribe_events_addon_page_capability', 'install_plugins' );
65
+
66
+ // prevent users who cannot install plugins from seeing addons link
67
+ if ( current_user_can( $capability ) ) {
68
+ global $wp_admin_bar;
69
+
70
+ $wp_admin_bar->add_menu( array(
71
+ 'id' => 'tribe-events-app-shop',
72
+ 'title' => esc_html__( 'Event Add-Ons', 'tribe-common' ),
73
+ 'href' => Tribe__Settings::instance()->get_url( array( 'page' => self::MENU_SLUG ) ),
74
+ 'parent' => 'tribe-events-settings-group',
75
+ ) );
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Enqueue the styles and script
81
+ */
82
+ public function enqueue() {
83
+ wp_enqueue_style( 'app-shop', tribe_resource_url( 'app-shop.css', false, 'common' ), array(), apply_filters( 'tribe_events_css_version', Tribe__Main::VERSION ) );
84
+ wp_enqueue_script( 'app-shop', tribe_resource_url( 'app-shop.js', false, 'common' ), array(), apply_filters( 'tribe_events_js_version', Tribe__Main::VERSION ) );
85
+ }
86
+
87
+ /**
88
+ * Renders the Shop App page
89
+ */
90
+ public function do_menu_page() {
91
+ $products = $this->get_all_products();
92
+ include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/app-shop.php';
93
+ }
94
+
95
+ /**
96
+ * Get's all products from the API
97
+ *
98
+ * @return array|WP_Error
99
+ */
100
+ private function get_all_products() {
101
+ $products = array(
102
+ (object) array(
103
+ 'title' => __( 'Filter Bar', 'tribe-common' ),
104
+ 'link' => 'https://theeventscalendar.com/product/wordpress-events-filterbar/?utm_campaign=in-app&utm_source=addonspage&utm_medium=wordpress-events-filterbar&utm_content=appstoreembedded-1',
105
+ 'description' => __( 'It is awesome that your calendar is <em>THE PLACE</em> to get hooked up with prime choice ways to spend time. You have more events than Jabba the Hutt has rolls. Too bad visitors are hiring a personal assistant to go through all the choices. Ever wish you could just filter the calendar to only show events in walking distance, on a weekend, that are free? BOOM. Now you can. Introducing… the Filter Bar.', 'tribe-common' ),
106
+ 'image' => 'images/app-shop-filter-bar.jpg',
107
+ ),
108
+ (object) array(
109
+ 'title' => __( 'Events Calendar PRO', 'tribe-common' ),
110
+ 'link' => 'https://theeventscalendar.com/product/wordpress-events-calendar-pro/?utm_campaign=in-app&utm_source=addonspage&utm_medium=wordpress-events-calendar-pro&utm_content=appstoreembedded-1',
111
+ 'description' => sprintf(
112
+ __( 'The Events Calendar PRO is a paid Add-On to our open source WordPress plugin %1$sThe Events Calendar%2$s. PRO offers a whole host of calendar features including recurring events, custom event attributes, saved venues and organizers, venue pages, advanced event admin and lots more.', 'tribe-common' ),
113
+ '<a href="http://m.tri.be/18vc">',
114
+ '</a>'
115
+ ),
116
+ 'image' => 'images/app-shop-pro.jpg',
117
+ ),
118
+ (object) array(
119
+ 'title' => __( 'Community Events', 'tribe-common' ),
120
+ 'link' => 'https://theeventscalendar.com/product/wordpress-community-events/?utm_campaign=in-app&utm_source=addonspage&utm_medium=wordpress-community-events&utm_content=appstoreembedded-1',
121
+ 'description' => __( 'Enable users to submit events to your calendar with Community Events. You can require user accounts or allow visitors to submit without an account. Want to make sure that nothing fishy is going on? Just turn on moderation. Decide if users can edit and manage their own events, or simply submit. Plus, no scary form setup! Just activate, configure the options & off you go.', 'tribe-common' ),
122
+ 'image' => 'images/app-shop-community.jpg',
123
+ ),
124
+ (object) array(
125
+ 'title' => __( 'Community Tickets', 'tribe-common' ),
126
+ 'link' => 'https://theeventscalendar.com/product/community-tickets/?utm_campaign=in-app&utm_source=addonspage&utm_medium=community-tickets&utm_content=appstoreembedded-1',
127
+ 'description' => __( 'Enable Community Events organizers to offer tickets to their events. You can set flexible payment and fee options. They can even check-in attendees to their events! All of this managed from the front-end of your site without ever needing to grant access to your admin', 'tribe-common' ),
128
+ 'requires' => _x( 'Event Tickets Plus and Community Events', 'Names of required plugins for Community Tickets', 'tribe-common' ),
129
+ 'image' => 'images/app-shop-community-tickets.jpg',
130
+ ),
131
+ (object) array(
132
+ 'title' => __( 'Event Tickets Plus', 'tribe-common' ),
133
+ 'link' => 'https://theeventscalendar.com/product/wordpress-event-tickets-plus/?utm_campaign=in-app&utm_source=addonspage&utm_medium=wordpress-event-tickets-plus&utm_content=appstoreembedded-1',
134
+ 'description' => sprintf(
135
+ __( 'Event Tickets Plus allows you to sell tickets to your events using WooCommerce, Shopp, WP eCommerce, or Easy Digital Downloads. Use it on your posts and pages, or add %1$sThe Events Calendar%2$s and sell tickets from your events listings.', 'tribe-common' ),
136
+ '<a href="http://m.tri.be/18vc">',
137
+ '</a>'
138
+ ),
139
+ 'image' => 'images/app-shop-tickets-plus.jpg',
140
+ ),
141
+ (object) array(
142
+ 'title' => __( 'Eventbrite Tickets', 'tribe-common' ),
143
+ 'link' => 'https://theeventscalendar.com/product/wordpress-eventbrite-tickets/?utm_campaign=in-app&utm_source=addonspage&utm_medium=wordpress-eventbrite-tickets&utm_content=appstoreembedded-1',
144
+ 'description' => sprintf(
145
+ __( 'The Eventbrite Tickets add-on allows you to create & sell tickets through The Events Calendar using the power of %1$sEventbrite%2$s. Whether you’re creating your ticket on the WordPress dashboard or importing the details of an already-existing event from %1$sEventbrite.com%2$s, this add-on brings the power of the Eventbrite API to your calendar.', 'tribe-common' ),
146
+ '<a href="http://www.eventbrite.com/r/etp">',
147
+ '</a>'
148
+ ),
149
+ 'image' => 'images/app-shop-eventbrite.jpg',
150
+ ),
151
+ (object) array(
152
+ 'title' => __( 'Facebook Events', 'tribe-common' ),
153
+ 'link' => 'https://theeventscalendar.com/product/facebook-events/?utm_campaign=in-app&utm_source=addonspage&utm_medium=facebook-events&utm_content=appstoreembedded-1',
154
+ 'description' => __( 'With the Facebook Events add-on, imported events are manually or automagically created as entries in The Events Calendar. Basic event data along with venue and organizer are populated appropriately. No more entering information in two places, or having to recreate someone else\'s listing for a public event you want to include on your WordPress calendar.', 'tribe-common' ),
155
+ 'image' => 'images/app-shop-facebook.jpg',
156
+ ),
157
+ (object) array(
158
+ 'title' => __( 'iCal Importer', 'tribe-common' ),
159
+ 'link' => 'https://theeventscalendar.com/product/ical-importer/?utm_campaign=in-app&utm_source=addonspage&utm_medium=ical-importer&utm_content=appstoreembedded-1',
160
+ 'description' => __( 'The iCal Importer helps you keep your events calendar full of interesting events! You can import events from any website that publishes an iCal (aka ICS) feed and add them to your listings. The recurring import feature lets you keep your calendar brimming without manual oversight (though you can review every imported event if you like). Add filtering by keyword or geographic region and you can be sure that the kinds of events you get are the kinds you want.', 'tribe-common' ),
161
+ 'image' => 'images/app-shop-ical.jpg',
162
+ ),
163
+ );
164
+
165
+ return $products;
166
+ }
167
+
168
+ /**
169
+ * Static Singleton Factory Method
170
+ *
171
+ * @return Tribe__App_Shop
172
+ */
173
+ public static function instance() {
174
+ if ( ! isset( self::$instance ) ) {
175
+ $className = __CLASS__;
176
+ self::$instance = new $className;
177
+ }
178
+
179
+ return self::$instance;
180
+ }
181
+ }
182
+ }
common/src/Tribe/Asset/Factory.php CHANGED
@@ -1,57 +1,57 @@
1
- <?php
2
-
3
- class Tribe__Asset__Factory {
4
- /**
5
- * @param string $name
6
- *
7
- * @return Tribe__Asset__Abstract_Asset|false Either a new instance of the asset class or false.
8
- */
9
- public function make_for_name( $name ) {
10
- // `jquery-resize` to `Jquery_Resize`
11
- $class_name = $this->get_asset_class_name( $name );
12
-
13
- // `Jquery_Resize` to `Tribe__Asset__Jquery_Resize`
14
- $full_class_name = $this->get_asset_full_class_name( $class_name );
15
-
16
- return class_exists( $full_class_name ) ? new $full_class_name() : false;
17
- }
18
-
19
- protected function get_asset_class_name( $name ) {
20
- // `jquery-resize` to `Jquery_Resize`
21
- $class_name = str_replace( ' ', '_', ucwords( str_replace( '-', ' ', $name ) ) );
22
-
23
- return $class_name;
24
- }
25
-
26
- /**
27
- * @param string $class_name
28
- *
29
- * @return string
30
- */
31
- private function get_asset_full_class_name( $class_name ) {
32
- // `Jquery_Resize` to `Tribe__Asset__Jquery_Resize`
33
- $full_class_name = $this->get_asset_class_name_prefix() . $class_name;
34
-
35
- return $full_class_name;
36
- }
37
-
38
- /**
39
- * @return string
40
- */
41
- protected function get_asset_class_name_prefix() {
42
- return 'Tribe__Asset__';
43
- }
44
-
45
- /**
46
- * @return Tribe__Asset__Factory
47
- */
48
- public static function instance() {
49
- static $instance;
50
-
51
- if ( ! $instance ) {
52
- $instance = new self;
53
- }
54
-
55
- return $instance;
56
- }
57
- }
1
+ <?php
2
+
3
+ class Tribe__Asset__Factory {
4
+ /**
5
+ * @param string $name
6
+ *
7
+ * @return Tribe__Asset__Abstract_Asset|false Either a new instance of the asset class or false.
8
+ */
9
+ public function make_for_name( $name ) {
10
+ // `jquery-resize` to `Jquery_Resize`
11
+ $class_name = $this->get_asset_class_name( $name );
12
+
13
+ // `Jquery_Resize` to `Tribe__Asset__Jquery_Resize`
14
+ $full_class_name = $this->get_asset_full_class_name( $class_name );
15
+
16
+ return class_exists( $full_class_name ) ? new $full_class_name() : false;
17
+ }
18
+
19
+ protected function get_asset_class_name( $name ) {
20
+ // `jquery-resize` to `Jquery_Resize`
21
+ $class_name = str_replace( ' ', '_', ucwords( str_replace( '-', ' ', $name ) ) );
22
+
23
+ return $class_name;
24
+ }
25
+
26
+ /**
27
+ * @param string $class_name
28
+ *
29
+ * @return string
30
+ */
31
+ private function get_asset_full_class_name( $class_name ) {
32
+ // `Jquery_Resize` to `Tribe__Asset__Jquery_Resize`
33
+ $full_class_name = $this->get_asset_class_name_prefix() . $class_name;
34
+
35
+ return $full_class_name;
36
+ }
37
+
38
+ /**
39
+ * @return string
40
+ */
41
+ protected function get_asset_class_name_prefix() {
42
+ return 'Tribe__Asset__';
43
+ }
44
+
45
+ /**
46
+ * @return Tribe__Asset__Factory
47
+ */
48
+ public static function instance() {
49
+ static $instance;
50
+
51
+ if ( ! $instance ) {
52
+ $instance = new self;
53
+ }
54
+
55
+ return $instance;
56
+ }
57
+ }
common/src/Tribe/Autoloader.php CHANGED
@@ -1,246 +1,246 @@
1
- <?php
2
-
3
- if ( ! class_exists( 'Tribe__Autoloader' ) ) {
4
- /**
5
- * Class Tribe__Autoloader
6
- *
7
- * Allows for autoloading of Tribe plugins classes.
8
- *
9
- * Example usage:
10
- *
11
- * // will be `/var/www/site/wp-content/plugins/the-events-calendar'
12
- * $this_dir = dirname(__FILE__);
13
- *
14
- * // gets hold of the singleton instance of the class
15
- * $autoloader = Tribe__Autoloader::instance();
16
- *
17
- * // register one by one or use `register_prefixes` method
18
- * $autoloader->register_prefix( 'Tribe__Admin__', $this_dir . '/src/Tribe/admin' );
19
- * $autoloader->register_prefix( 'Tribe__Admin__', $this_dir . '/src/Tribe/another-dir' );
20
- * $autoloader->register_prefix( 'Tribe__Utils__', $this_dir . '/src/Tribe/another-dir' );
21
- *
22
- * // register a direct class to path
23
- * $autoloader->register_class( 'Tribe__Some_Class', $this_dir . '/some/path/to/Some_Class.php' );
24
- *
25
- * // register a fallback dir to be searched for the class before giving up
26
- * $autoloader->add_fallback_dir( $this_dir . '/all-the-classes' );
27
- *
28
- * // calls `spl_autoload_register`
29
- * $autoloader->register_autoloader();
30
- *
31
- * // class will be searched in the path
32
- * // `/var/www/site/wp-content/plugins/the-events-calendar/src/Tribe/admin/Some_Class.php'
33
- * // and
34
- * // `/var/www/site/wp-content/plugins/the-events-calendar/src/Tribe/another-dir/Some_Class.php'
35
- * $i = new Tribe__Admin__Some_Class();
36
- *
37
- * // class will be searched in the path
38
- * // `/var/www/site/wp-content/plugins/the-events-calendar/utils/some-dir/Some_Util.php'
39
- * $i = new Tribe__Utils__Some_Util();
40
- *
41
- * // class will be searched in the path
42
- * // `/var/www/site/wp-content/plugins/the-events-calendar/deprecated/Tribe_DeprecatedClass.php'
43
- * $i = new Tribe_DeprecatedClass();
44
- */
45
- class Tribe__Autoloader {
46
-
47
- /**
48
- * @var Tribe__Autoloader
49
- */
50
- protected static $instance;
51
-
52
- /**
53
- * An arrays of arrays each containing absolute paths.
54
- *
55
- * Paths are stored trimming any trailing `/`.
56
- * E.g. `/var/www/tribe-pro/wp-content/plugins/the-event-calendar/src/Tribe`
57
- *
58
- * @var string[][]
59
- */
60
- protected $prefixes;
61
-
62
- /**
63
- * The string acting as a directory separator in a class name.
64
- *
65
- * E.g.: given `__` as `$dir_separator` then `Admin__Metabox__Some_Metabox`
66
- * will map to `/Admin/Metabox/SomeMetabox.php`.
67
- *
68
- * @var string
69
- */
70
- protected $dir_separator = '__';
71
-
72
- /** @var string[] */
73
- protected $fallback_dirs = array();
74
-
75
- /**
76
- * @var array
77
- */
78
- protected $class_paths = array();
79
-
80
- /**
81
- * Returns the singleton instance of the class.
82
- *
83
- * @return Tribe__Autoloader
84
- */
85
- public static function instance() {
86
- if ( ! self::$instance instanceof Tribe__Autoloader ) {
87
- self::$instance = new self();
88
- }
89
-
90
- return self::$instance;
91
- }
92
-
93
- /**
94
- * Registers prefixes and root dirs using an array.
95
- *
96
- * Same as calling `register_prefix` on each one.
97
- *
98
- * @param array $prefixes_to_root_dirs
99
- */
100
- public function register_prefixes( array $prefixes_to_root_dirs ) {
101
- foreach ( $prefixes_to_root_dirs as $prefix => $root_dir ) {
102
- $this->register_prefix( $prefix, $root_dir );
103
- }
104
- }
105
-
106
- /**
107
- * Associates a class prefix to an absolute path.
108
- *
109
- * @param string $prefix A class prefix, e.g. `Tribe__Admin__`
110
- * @param string $root_dir The absolute path to the dir containing
111
- * the prefixed classes.
112
- */
113
- public function register_prefix( $prefix, $root_dir ) {
114
- $root_dir = $this->normalize_root_dir( $root_dir );
115
-
116
- if ( ! isset( $this->prefixes[ $prefix ] ) ) {
117
- $this->prefixes[ $prefix ] = array();
118
- }
119
- $this->prefixes[ $prefix ][] = $root_dir;
120
- }
121
-
122
- /**
123
- * Triggers the registration of the autoload method in the SPL
124
- * autoload register.
125
- */
126
- public function register_autoloader() {
127
- spl_autoload_register( array( $this, 'autoload' ) );
128
- }
129
-
130
- /**
131
- * Includes the file defining a class.
132
- *
133
- * This is the function that's registered as an autoloader.
134
- *
135
- * @param string $class
136
- */
137
- public function autoload( $class ) {
138
- $include_path = $this->get_class_path( $class );
139
- if ( ! empty( $include_path ) ) {
140
- include_once( $include_path );
141
- }
142
- }
143
-
144
- private function normalize_root_dir( $root_dir ) {
145
- return rtrim( $root_dir, '/' );
146
- }
147
-
148
- protected function get_prefixed_path( $class ) {
149
- foreach ( $this->prefixes as $prefix => $dirs ) {
150
- if ( strpos( $class, $prefix ) !== 0 ) {
151
- continue;
152
- }
153
- $class_name = str_replace( $prefix, '', $class );
154
- $class_path_frag = implode( '/', explode( $this->dir_separator, $class_name ) ) . '.php';
155
- foreach ( $dirs as $dir ) {
156
- $path = $dir . '/' . $class_path_frag;
157
- if ( ! file_exists( $path ) ) {
158
- // check if the file exists in lowercase
159
- $class_path_frag = strtolower( $class_path_frag );
160
- $path = $dir . '/' . $class_path_frag;
161
- }
162
- if ( ! file_exists( $path ) ) {
163
- continue;
164
- }
165
-
166
- return $path;
167
- }
168
- }
169
- return false;
170
- }
171
-
172
- protected function get_fallback_path( $class ) {
173
- foreach ( $this->fallback_dirs as $fallback_dir ) {
174
- $include_path = $fallback_dir . '/' . $class . '.php';
175
- if ( ! file_exists( $include_path ) ) {
176
- // check if the file exists in lowercase
177
- $class = strtolower( $class );
178
- $include_path = $fallback_dir . '/' . $class . '.php';
179
- }
180
- if ( ! file_exists( $include_path ) ) {
181
- continue;
182
- }
183
-
184
- return $include_path;
185
- }
186
- }
187
-
188
- /**
189
- * Gets the absolute path to a class file.
190
- *
191
- * @param string $class The class name
192
- *
193
- * @return string Either the absolute path to the class file or an
194
- * empty string if the file was not found.
195
- */
196
- public function get_class_path( $class ) {
197
- $prefixed_path = $this->get_prefixed_path( $class );
198
- if ( $prefixed_path ) {
199
- return $prefixed_path;
200
- }
201
-
202
- $class_path = ! empty( $this->class_paths[ $class ] ) ? $this->class_paths[ $class ] :false;
203
- if ( $class_path ) {
204
- return $class_path;
205
- }
206
-
207
- $fallback_path = $this->get_fallback_path( $class );
208
-
209
- return $fallback_path ? $fallback_path : '';
210
- }
211
-
212
- /**
213
- * Adds a folder to search for classes that were not found among
214
- * the prefixed ones.
215
- *
216
- * This is the method to use to register a directory of deprecated
217
- * classes.
218
- *
219
- * @param string $dir An absolute path dto a dir.
220
- */
221
- public function add_fallback_dir( $dir ) {
222
- if ( in_array( $dir, $this->fallback_dirs ) ) {
223
- return;
224
- }
225
- $this->fallback_dirs[] = $this->normalize_root_dir( $dir );
226
- }
227
-
228
- /**
229
- * @return string
230
- */
231
- public function get_dir_separator() {
232
- return $this->dir_separator;
233
- }
234
-
235
- /**
236
- * @param string $dir_separator
237
- */
238
- public function set_dir_separator( $dir_separator ) {
239
- $this->dir_separator = $dir_separator;
240
- }
241
-
242
- public function register_class( $class, $path ) {
243
- $this->class_paths[ $class ] = $path;
244
- }
245
- }
246
- }
1
+ <?php
2
+
3
+ if ( ! class_exists( 'Tribe__Autoloader' ) ) {
4
+ /**
5
+ * Class Tribe__Autoloader
6
+ *
7
+ * Allows for autoloading of Tribe plugins classes.
8
+ *
9
+ * Example usage:
10
+ *
11
+ * // will be `/var/www/site/wp-content/plugins/the-events-calendar'
12
+ * $this_dir = dirname(__FILE__);
13
+ *
14
+ * // gets hold of the singleton instance of the class
15
+ * $autoloader = Tribe__Autoloader::instance();
16
+ *
17
+ * // register one by one or use `register_prefixes` method
18
+ * $autoloader->register_prefix( 'Tribe__Admin__', $this_dir . '/src/Tribe/admin' );
19
+ * $autoloader->register_prefix( 'Tribe__Admin__', $this_dir . '/src/Tribe/another-dir' );
20
+ * $autoloader->register_prefix( 'Tribe__Utils__', $this_dir . '/src/Tribe/another-dir' );
21
+ *
22
+ * // register a direct class to path
23
+ * $autoloader->register_class( 'Tribe__Some_Class', $this_dir . '/some/path/to/Some_Class.php' );
24
+ *
25
+ * // register a fallback dir to be searched for the class before giving up
26
+ * $autoloader->add_fallback_dir( $this_dir . '/all-the-classes' );
27
+ *
28
+ * // calls `spl_autoload_register`
29
+ * $autoloader->register_autoloader();
30
+ *
31
+ * // class will be searched in the path
32
+ * // `/var/www/site/wp-content/plugins/the-events-calendar/src/Tribe/admin/Some_Class.php'
33
+ * // and
34
+ * // `/var/www/site/wp-content/plugins/the-events-calendar/src/Tribe/another-dir/Some_Class.php'
35
+ * $i = new Tribe__Admin__Some_Class();
36
+ *
37
+ * // class will be searched in the path
38
+ * // `/var/www/site/wp-content/plugins/the-events-calendar/utils/some-dir/Some_Util.php'
39
+ * $i = new Tribe__Utils__Some_Util();
40
+ *
41
+ * // class will be searched in the path
42
+ * // `/var/www/site/wp-content/plugins/the-events-calendar/deprecated/Tribe_DeprecatedClass.php'
43
+ * $i = new Tribe_DeprecatedClass();
44
+ */
45
+ class Tribe__Autoloader {
46
+
47
+ /**
48
+ * @var Tribe__Autoloader
49
+ */
50
+ protected static $instance;
51
+
52
+ /**
53
+ * An arrays of arrays each containing absolute paths.
54
+ *
55
+ * Paths are stored trimming any trailing `/`.
56
+ * E.g. `/var/www/tribe-pro/wp-content/plugins/the-event-calendar/src/Tribe`
57
+ *
58
+ * @var string[][]
59
+ */
60
+ protected $prefixes;
61
+
62
+ /**
63
+ * The string acting as a directory separator in a class name.
64
+ *
65
+ * E.g.: given `__` as `$dir_separator` then `Admin__Metabox__Some_Metabox`
66
+ * will map to `/Admin/Metabox/SomeMetabox.php`.
67
+ *
68
+ * @var string
69
+ */
70
+ protected $dir_separator = '__';
71
+
72
+ /** @var string[] */
73
+ protected $fallback_dirs = array();
74
+
75
+ /**
76
+ * @var array
77
+ */
78
+ protected $class_paths = array();
79
+
80
+ /**
81
+ * Returns the singleton instance of the class.
82
+ *
83
+ * @return Tribe__Autoloader
84
+ */
85
+ public static function instance() {
86
+ if ( ! self::$instance instanceof Tribe__Autoloader ) {
87
+ self::$instance = new self();
88
+ }
89
+
90
+ return self::$instance;
91
+ }
92
+
93
+ /**
94
+ * Registers prefixes and root dirs using an array.
95
+ *
96
+ * Same as calling `register_prefix` on each one.
97
+ *
98
+ * @param array $prefixes_to_root_dirs
99
+ */
100
+ public function register_prefixes( array $prefixes_to_root_dirs ) {
101
+ foreach ( $prefixes_to_root_dirs as $prefix => $root_dir ) {
102
+ $this->register_prefix( $prefix, $root_dir );
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Associates a class prefix to an absolute path.
108
+ *
109
+ * @param string $prefix A class prefix, e.g. `Tribe__Admin__`
110
+ * @param string $root_dir The absolute path to the dir containing
111
+ * the prefixed classes.
112
+ */
113
+ public function register_prefix( $prefix, $root_dir ) {
114
+ $root_dir = $this->normalize_root_dir( $root_dir );
115
+
116
+ if ( ! isset( $this->prefixes[ $prefix ] ) ) {
117
+ $this->prefixes[ $prefix ] = array();
118
+ }
119
+ $this->prefixes[ $prefix ][] = $root_dir;
120
+ }
121
+
122
+ /**
123
+ * Triggers the registration of the autoload method in the SPL
124
+ * autoload register.
125
+ */
126
+ public function register_autoloader() {
127
+ spl_autoload_register( array( $this, 'autoload' ) );
128
+ }
129
+
130
+ /**
131
+ * Includes the file defining a class.
132
+ *
133
+ * This is the function that's registered as an autoloader.
134
+ *
135
+ * @param string $class
136
+ */
137
+ public function autoload( $class ) {
138
+ $include_path = $this->get_class_path( $class );
139
+ if ( ! empty( $include_path ) ) {
140
+ include_once( $include_path );
141
+ }
142
+ }
143
+
144
+ private function normalize_root_dir( $root_dir ) {
145
+ return rtrim( $root_dir, '/' );
146
+ }
147
+
148
+ protected function get_prefixed_path( $class ) {
149
+ foreach ( $this->prefixes as $prefix => $dirs ) {
150
+ if ( strpos( $class, $prefix ) !== 0 ) {
151
+ continue;
152
+ }
153
+ $class_name = str_replace( $prefix, '', $class );
154
+ $class_path_frag = implode( '/', explode( $this->dir_separator, $class_name ) ) . '.php';
155
+ foreach ( $dirs as $dir ) {
156
+ $path = $dir . '/' . $class_path_frag;
157
+ if ( ! file_exists( $path ) ) {
158
+ // check if the file exists in lowercase
159
+ $class_path_frag = strtolower( $class_path_frag );
160
+ $path = $dir . '/' . $class_path_frag;
161
+ }
162
+ if ( ! file_exists( $path ) ) {
163
+ continue;
164
+ }
165
+
166
+ return $path;
167
+ }
168
+ }
169
+ return false;
170
+ }
171
+
172
+ protected function get_fallback_path( $class ) {
173
+ foreach ( $this->fallback_dirs as $fallback_dir ) {
174
+ $include_path = $fallback_dir . '/' . $class . '.php';
175
+ if ( ! file_exists( $include_path ) ) {
176
+ // check if the file exists in lowercase
177
+ $class = strtolower( $class );
178
+ $include_path = $fallback_dir . '/' . $class . '.php';
179
+ }
180
+ if ( ! file_exists( $include_path ) ) {
181
+ continue;
182
+ }
183
+
184
+ return $include_path;
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Gets the absolute path to a class file.
190
+ *
191
+ * @param string $class The class name
192
+ *
193
+ * @return string Either the absolute path to the class file or an
194
+ * empty string if the file was not found.
195
+ */
196
+ public function get_class_path( $class ) {
197
+ $prefixed_path = $this->get_prefixed_path( $class );
198
+ if ( $prefixed_path ) {
199
+ return $prefixed_path;
200
+ }
201
+
202
+ $class_path = ! empty( $this->class_paths[ $class ] ) ? $this->class_paths[ $class ] :false;
203
+ if ( $class_path ) {
204
+ return $class_path;
205
+ }
206
+
207
+ $fallback_path = $this->get_fallback_path( $class );
208
+
209
+ return $fallback_path ? $fallback_path : '';
210
+ }
211
+
212
+ /**
213
+ * Adds a folder to search for classes that were not found among
214
+ * the prefixed ones.
215
+ *
216
+ * This is the method to use to register a directory of deprecated
217
+ * classes.
218
+ *
219
+ * @param string $dir An absolute path dto a dir.
220
+ */
221
+ public function add_fallback_dir( $dir ) {
222
+ if ( in_array( $dir, $this->fallback_dirs ) ) {
223
+ return;
224
+ }
225
+ $this->fallback_dirs[] = $this->normalize_root_dir( $dir );
226
+ }
227
+
228
+ /**
229
+ * @return string
230
+ */
231
+ public function get_dir_separator() {
232
+ return $this->dir_separator;
233
+ }
234
+
235
+ /**
236
+ * @param string $dir_separator
237
+ */
238
+ public function set_dir_separator( $dir_separator ) {
239
+ $this->dir_separator = $dir_separator;
240
+ }
241
+
242
+ public function register_class( $class, $path ) {
243
+ $this->class_paths[ $class ] = $path;
244
+ }
245
+ }
246
+ }
common/src/Tribe/Cache.php CHANGED
@@ -1,126 +1,126 @@
1
- <?php
2
-
3
- /**
4
- * Manage setting and expiring cached data
5
- *
6
- * Select actions can be used to force cached
7
- * data to expire. Implemented so far:
8
- * - save_post
9
- *
10
- */
11
- class Tribe__Cache {
12
- const NO_EXPIRATION = 0;
13
- const NON_PERSISTENT = - 1;
14
-
15
- public static function setup() {
16
- wp_cache_add_non_persistent_groups( array( 'tribe-events-non-persistent' ) );
17
- }
18
-
19
- /**
20
- * @param string $id
21
- * @param mixed $value
22
- * @param int $expiration
23
- * @param string $expiration_trigger
24
- *
25
- * @return bool
26
- */
27
- public function set( $id, $value, $expiration = 0, $expiration_trigger = '' ) {
28
- if ( $expiration == self::NON_PERSISTENT ) {
29
- $group = 'tribe-events-non-persistent';
30
- $expiration = 1;
31
- } else {
32
- $group = 'tribe-events';
33
- }
34
-
35
- return wp_cache_set( $this->get_id( $id, $expiration_trigger ), $value, $group, $expiration );
36
- }
37
-
38
- /**
39
- * @param $id
40
- * @param $value
41
- * @param int $expiration
42
- * @param string $expiration_trigger
43
- *
44
- * @return bool
45
- */
46
- public function set_transient( $id, $value, $expiration = 0, $expiration_trigger = '' ) {
47
- return set_transient( $this->get_id( $id, $expiration_trigger ), $value, $expiration );
48
- }
49
-
50
- /**
51
- * @param string $id
52
- * @param string $expiration_trigger
53
- *
54
- * @return mixed
55
- */
56
- public function get( $id, $expiration_trigger = '' ) {
57
- return wp_cache_get( $this->get_id( $id, $expiration_trigger ), 'tribe-events' );
58
- }
59
-
60
- /**
61
- * @param string $id
62
- * @param string $expiration_trigger
63
- *
64
- * @return mixed
65
- */
66
- public function get_transient( $id, $expiration_trigger = '' ) {
67
- return get_transient( $this->get_id( $id, $expiration_trigger ) );
68
- }
69
-
70
- /**
71
- * @param string $id
72
- * @param string $expiration_trigger
73
- *
74
- * @return bool
75
- */
76
- public function delete( $id, $expiration_trigger = '' ) {
77
- return wp_cache_delete( $this->get_id( $id, $expiration_trigger ), 'tribe-events' );
78
- }
79
-
80
- /**
81
- * @param string $id
82
- * @param string $expiration_trigger
83
- *
84
- * @return bool
85
- */
86
- public function delete_transient( $id, $expiration_trigger = '' ) {
87
- return delete_transient( $this->get_id( $id, $expiration_trigger ) );
88
- }
89
-
90
- /**
91
- * @param string $key
92
- * @param string $expiration_trigger
93
- *
94
- * @return string
95
- */
96
- public function get_id( $key, $expiration_trigger = '' ) {
97
- $last = empty( $expiration_trigger ) ? '' : $this->get_last_occurrence( $expiration_trigger );
98
- $id = $key . $last;
99
- if ( strlen( $id ) > 40 ) {
100
- $id = md5( $id );
101
- }
102
-
103
- return $id;
104
- }
105
-
106
- /**
107
- * @param string $action
108
- *
109
- * @return int
110
- */
111
- public function get_last_occurrence( $action ) {
112
- return (int) get_option( 'tribe_last_' . $action, time() );
113
- }
114
-
115
- /**
116
- * @param string $action
117
- * @param int $timestamp
118
- */
119
- public function set_last_occurrence( $action, $timestamp = 0 ) {
120
- if ( empty( $timestamp ) ) {
121
- $timestamp = time();
122
- }
123
- update_option( 'tribe_last_' . $action, (int) $timestamp );
124
- }
125
- }
126
-
1
+ <?php
2
+
3
+ /**
4
+ * Manage setting and expiring cached data
5
+ *
6
+ * Select actions can be used to force cached
7
+ * data to expire. Implemented so far:
8
+ * - save_post
9
+ *
10
+ */
11
+ class Tribe__Cache {
12
+ const NO_EXPIRATION = 0;
13
+ const NON_PERSISTENT = - 1;
14
+
15
+ public static function setup() {
16
+ wp_cache_add_non_persistent_groups( array( 'tribe-events-non-persistent' ) );
17
+ }
18
+
19
+ /**
20
+ * @param string $id
21
+ * @param mixed $value
22
+ * @param int $expiration
23
+ * @param string $expiration_trigger
24
+ *
25
+ * @return bool
26
+ */
27
+ public function set( $id, $value, $expiration = 0, $expiration_trigger = '' ) {
28
+ if ( $expiration == self::NON_PERSISTENT ) {
29
+ $group = 'tribe-events-non-persistent';
30
+ $expiration = 1;
31
+ } else {
32
+ $group = 'tribe-events';
33
+ }
34
+
35
+ return wp_cache_set( $this->get_id( $id, $expiration_trigger ), $value, $group, $expiration );
36
+ }
37
+
38
+ /**
39
+ * @param $id
40
+ * @param $value
41
+ * @param int $expiration
42
+ * @param string $expiration_trigger
43
+ *
44
+ * @return bool
45
+ */
46
+ public function set_transient( $id, $value, $expiration = 0, $expiration_trigger = '' ) {
47
+ return set_transient( $this->get_id( $id, $expiration_trigger ), $value, $expiration );
48
+ }
49
+
50
+ /**
51
+ * @param string $id
52
+ * @param string $expiration_trigger
53
+ *
54
+ * @return mixed
55
+ */
56
+ public function get( $id, $expiration_trigger = '' ) {
57
+ return wp_cache_get( $this->get_id( $id, $expiration_trigger ), 'tribe-events' );
58
+ }
59
+
60
+ /**
61
+ * @param string $id
62
+ * @param string $expiration_trigger
63
+ *
64
+ * @return mixed
65
+ */
66
+ public function get_transient( $id, $expiration_trigger = '' ) {
67
+ return get_transient( $this->get_id( $id, $expiration_trigger ) );
68
+ }
69
+
70
+ /**
71
+ * @param string $id
72
+ * @param string $expiration_trigger
73
+ *
74
+ * @return bool
75
+ */
76
+ public function delete( $id, $expiration_trigger = '' ) {
77
+ return wp_cache_delete( $this->get_id( $id, $expiration_trigger ), 'tribe-events' );
78
+ }
79
+
80
+ /**
81
+ * @param string $id
82
+ * @param string $expiration_trigger
83
+ *
84
+ * @return bool
85
+ */
86
+ public function delete_transient( $id, $expiration_trigger = '' ) {
87
+ return delete_transient( $this->get_id( $id, $expiration_trigger ) );
88
+ }
89
+
90
+ /**
91
+ * @param string $key
92
+ * @param string $expiration_trigger
93
+ *
94
+ * @return string
95
+ */
96
+ public function get_id( $key, $expiration_trigger = '' ) {
97
+ $last = empty( $expiration_trigger ) ? '' : $this->get_last_occurrence( $expiration_trigger );
98
+ $id = $key . $last;
99
+ if ( strlen( $id ) > 40 ) {
100
+ $id = md5( $id );
101
+ }
102
+
103
+ return $id;
104
+ }
105
+
106
+ /**
107
+ * @param string $action
108
+ *
109
+ * @return int
110
+ */
111
+ public function get_last_occurrence( $action ) {
112
+ return (int) get_option( 'tribe_last_' . $action, time() );
113
+ }
114
+
115
+ /**
116
+ * @param string $action
117
+ * @param int $timestamp
118
+ */
119
+ public function set_last_occurrence( $action, $timestamp = 0 ) {
120
+ if ( empty( $timestamp ) ) {
121
+ $timestamp = time();
122
+ }
123
+ update_option( 'tribe_last_' . $action, (int) $timestamp );
124
+ }
125
+ }
126
+
common/src/Tribe/Cache_Listener.php CHANGED
@@ -1,96 +1,96 @@
1
- <?php
2
- /**
3
- * Listen for events and update their timestamps
4
- */
5
- class Tribe__Cache_Listener {
6
-
7
- private static $instance = null;
8
- private $cache = null;
9
-
10
- /**
11
- * Class constructor.
12
- *
13
- * @return void
14
- */
15
- public function __construct() {
16
- $this->cache = new Tribe__Cache();
17
- }
18
-
19
- /**
20
- * Run the init functionality (like add_hooks).
21
- *
22
- * @return void
23
- */
24
- public function init() {
25
- $this->add_hooks();
26
- }
27
-
28
- /**
29
- * Add the hooks necessary.
30
- *
31
- * @return void
32
- */
33
- private function add_hooks() {
34
- add_action( 'save_post', array( $this, 'save_post' ), 0, 2 );
35
- add_action( 'updated_option', array( $this, 'update_last_save_post' ) );
36
- }
37
-
38
- /**
39
- * Run the caching functionality that is executed on save post.
40
- *
41
- * @param int $post_id The post_id.
42
- * @param WP_Post $post The current post object being saved.
43
- */
44
- public function save_post( $post_id, $post ) {
45
- if ( in_array( $post->post_type, Tribe__Main::get_post_types() ) ) {
46
- $this->cache->set_last_occurrence( 'save_post' );
47
- }
48
- }
49
-
50
- /**
51
- * Run the caching functionality that is executed on saving tribe calendar options.
52
- *
53
- * @param string $option
54
- * @see 'updated_option'
55
- */
56
- public function update_last_save_post( $option ) {
57
- if ( $option != 'tribe_last_save_post' ) {
58
- $this->cache->set_last_occurrence( 'save_post' );
59
- }
60
- }
61
-
62
- /**
63
- * For any hook that doesn't need any additional filtering
64
- *
65
- * @param $method
66
- * @param $args
67
- */
68
- public function __call( $method, $args ) {
69
- $this->cache->set_last_occurrence( $method );
70
- }
71
-
72
- /**
73
- * Instance method of the cache listener.
74
- *
75
- * @return Tribe__Cache_Listener
76
- */
77
- public static function instance() {
78
- if ( empty( self::$instance ) ) {
79
- self::$instance = self::create_listener();
80
- }
81
-
82
- return self::$instance;
83
- }
84
-
85
- /**
86
- * Create a cache listener.
87
- *
88
- * @return Tribe__Cache_Listener
89
- */
90
- private static function create_listener() {
91
- $listener = new self();
92
- $listener->init();
93
-
94
- return $listener;
95
- }
96
- }
1
+ <?php
2
+ /**
3
+ * Listen for events and update their timestamps
4
+ */
5
+ class Tribe__Cache_Listener {
6
+
7
+ private static $instance = null;
8
+ private $cache = null;
9
+
10
+ /**
11
+ * Class constructor.
12
+ *
13
+ * @return void
14
+ */
15
+ public function __construct() {
16
+ $this->cache = new Tribe__Cache();
17
+ }
18
+
19
+ /**
20
+ * Run the init functionality (like add_hooks).
21
+ *
22
+ * @return void
23
+ */
24
+ public function init() {
25
+ $this->add_hooks();
26
+ }
27
+
28
+ /**
29
+ * Add the hooks necessary.
30
+ *
31
+ * @return void
32
+ */
33
+ private function add_hooks() {
34
+ add_action( 'save_post', array( $this, 'save_post' ), 0, 2 );
35
+ add_action( 'updated_option', array( $this, 'update_last_save_post' ) );
36
+ }
37
+
38
+ /**
39
+ * Run the caching functionality that is executed on save post.
40
+ *
41
+ * @param int $post_id The post_id.
42
+ * @param WP_Post $post The current post object being saved.
43
+ */
44
+ public function save_post( $post_id, $post ) {
45
+ if ( in_array( $post->post_type, Tribe__Main::get_post_types() ) ) {
46
+ $this->cache->set_last_occurrence( 'save_post' );
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Run the caching functionality that is executed on saving tribe calendar options.
52
+ *
53
+ * @param string $option
54
+ * @see 'updated_option'
55
+ */
56
+ public function update_last_save_post( $option ) {
57
+ if ( $option != 'tribe_last_save_post' ) {
58
+ $this->cache->set_last_occurrence( 'save_post' );
59
+ }
60
+ }
61
+
62
+ /**
63
+ * For any hook that doesn't need any additional filtering
64
+ *
65
+ * @param $method
66
+ * @param $args
67
+ */
68
+ public function __call( $method, $args ) {
69
+ $this->cache->set_last_occurrence( $method );
70
+ }
71
+
72
+ /**
73
+ * Instance method of the cache listener.
74
+ *
75
+ * @return Tribe__Cache_Listener
76
+ */
77
+ public static function instance() {
78
+ if ( empty( self::$instance ) ) {
79
+ self::$instance = self::create_listener();
80
+ }
81
+
82
+ return self::$instance;
83
+ }
84
+
85
+ /**
86
+ * Create a cache listener.
87
+ *
88
+ * @return Tribe__Cache_Listener
89
+ */
90
+ private static function create_listener() {
91
+ $listener = new self();
92
+ $listener->init();
93
+
94
+ return $listener;
95
+ }
96
+ }
common/src/Tribe/Changelog_Reader.php CHANGED
@@ -1,53 +1,53 @@
1
- <?php
2
-
3
- class Tribe__Changelog_Reader {
4
- protected $version_count = 3;
5
- protected $readme_file = '';
6
-
7
- public function __construct( $version_count = 3, $readme_file = '' ) {
8
- $this->version_count = (int) $version_count;
9
- $this->readme_file = empty( $readme_file ) ? $this->default_readme_file() : $readme_file;
10
- }
11
-
12
- protected function default_readme_file() {
13
- return dirname( Tribe__Main::instance()->plugin_path ) . '/readme.txt';
14
- }
15
-
16
- public function get_changelog() {
17
- $contents = $this->extract_changelog_section();
18
- $lines = explode( "\n", $contents );
19
-
20
- $sections = array();
21
- $current_section = '';
22
- foreach ( $lines as $line ) {
23
- $line = trim( $line );
24
- if ( substr( $line, 0, 1 ) == '=' ) {
25
- if ( count( $sections ) >= $this->version_count ) {
26
- break;
27
- }
28
- $header = trim( $line, '= ' );
29
- $current_section = esc_html( $header );
30
- $sections[ $current_section ] = array();
31
- } elseif ( strlen( $line ) > 0 ) {
32
- $message = trim( $line, '* ' );
33
- $sections[ $current_section ][] = esc_html( $message );
34
- }
35
- }
36
- return $sections;
37
- }
38
-
39
- protected function extract_changelog_section() {
40
- $contents = $this->get_readme_file_contents();
41
- $start = strpos( $contents, '== Changelog ==' );
42
- if ( $start === false ) {
43
- return '';
44
- }
45
- $start += 16; // account for the length of the header
46
- $end = strpos( $contents, '==', $start );
47
- return trim( substr( $contents, $start, $end - $start ) );
48
- }
49
-
50
- protected function get_readme_file_contents() {
51
- return file_get_contents( $this->readme_file );
52
- }
53
- }
1
+ <?php
2
+
3
+ class Tribe__Changelog_Reader {
4
+ protected $version_count = 3;
5
+ protected $readme_file = '';
6
+
7
+ public function __construct( $version_count = 3, $readme_file = '' ) {
8
+ $this->version_count = (int) $version_count;
9
+ $this->readme_file = empty( $readme_file ) ? $this->default_readme_file() : $readme_file;
10
+ }
11
+
12
+ protected function default_readme_file() {
13
+ return dirname( Tribe__Main::instance()->plugin_path ) . '/readme.txt';
14
+ }
15
+
16
+ public function get_changelog() {
17
+ $contents = $this->extract_changelog_section();
18
+ $lines = explode( "\n", $contents );
19
+
20
+ $sections = array();
21
+ $current_section = '';
22
+ foreach ( $lines as $line ) {
23
+ $line = trim( $line );
24
+ if ( substr( $line, 0, 1 ) == '=' ) {
25
+ if ( count( $sections ) >= $this->version_count ) {
26
+ break;
27
+ }
28
+ $header = trim( $line, '= ' );
29
+ $current_section = esc_html( $header );
30
+ $sections[ $current_section ] = array();
31
+ } elseif ( strlen( $line ) > 0 ) {
32
+ $message = trim( $line, '* ' );
33
+ $sections[ $current_section ][] = esc_html( $message );
34
+ }
35
+ }
36
+ return $sections;
37
+ }
38
+
39
+ protected function extract_changelog_section() {
40
+ $contents = $this->get_readme_file_contents();
41
+ $start = strpos( $contents, '== Changelog ==' );
42
+ if ( $start === false ) {
43
+ return '';
44
+ }
45
+ $start += 16; // account for the length of the header
46
+ $end = strpos( $contents, '==', $start );
47
+ return trim( substr( $contents, $start, $end - $start ) );
48
+ }
49
+
50
+ protected function get_readme_file_contents() {
51
+ return file_get_contents( $this->readme_file );
52
+ }
53
+ }
common/src/Tribe/Credits.php CHANGED
@@ -1,102 +1,102 @@
1
- <?php
2
-
3
- /**
4
- * Handles output of The Events Calendar credits
5
- */
6
- class Tribe__Credits {
7
-
8
- public static function init() {
9
- self::instance()->hook();
10
- }
11
-
12
- /**
13
- * Hook the functionality of this class into the world
14
- */
15
- public function hook() {
16
- add_filter( 'tribe_events_after_html', array( $this, 'html_comment_credit' ) );
17
- add_filter( 'admin_footer_text', array( $this, 'rating_nudge' ), 1, 2 );
18
- }
19
-
20
- /**
21
- * Add credit in HTML page source
22
- *
23
- * @return void
24
- **/
25
- public function html_comment_credit( $after_html ) {
26
-
27
- if ( ! class_exists( 'Tribe__Events__Main' ) ) {
28
- return $after_html;
29
- }
30
-
31
- $html_credit = "\n<!--\n" . esc_html__( 'This calendar is powered by %1$s.', 'tribe-common' ) . "\nhttp://m.tri.be/18wn\n-->\n";
32
- $after_html .= apply_filters( 'tribe_html_credit', $html_credit );
33
- return $after_html;
34
- }
35
-
36
- /**
37
- * Add ratings nudge in admin footer
38
- *
39
- * @param $footer_text
40
- *
41
- * @return string
42
- */
43
- public function rating_nudge( $footer_text ) {
44
- $admin_helpers = Tribe__Admin__Helpers::instance();
45
-
46
- add_filter( 'tribe_tickets_post_types', array( $this, 'tmp_return_tribe_events' ), 99 );
47
-
48
- // only display custom text on Tribe Admin Pages
49
- if ( $admin_helpers->is_screen() || $admin_helpers->is_post_type_screen() ) {
50
-
51
- if ( class_exists( 'Tribe__Events__Main' ) ) {
52
- $review_url = 'https://wordpress.org/support/view/plugin-reviews/the-events-calendar?filter=5';
53
-
54
- $footer_text = sprintf(
55
- esc_html__( 'Rate %1$sThe Events Calendar%2$s %3$s', 'tribe-common' ),
56
- '<strong>',
57
- '</strong>',
58
- '<a href="' . $review_url . '" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
59
- );
60
- } else {
61
- $review_url = 'https://wordpress.org/support/view/plugin-reviews/event-tickets?filter=5';
62
-
63
- $footer_text = sprintf(
64
- esc_html__( 'Rate %1$sEvent Tickets%2$s %3$s', 'tribe-common' ),
65
- '<strong>',
66
- '</strong>',
67
- '<a href="' . $review_url . '" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
68
- );
69
- }
70
- }
71
-
72
- remove_filter( 'tribe_tickets_post_types', array( $this, 'tmp_return_tribe_events' ), 99 );
73
-
74
- return $footer_text;
75
- }
76
-
77
- /**
78
- * temporary function to filter event types down to only tribe-specific types
79
- *
80
- * This will limit the request for ratings to only those post type pages
81
- */
82
- public function tmp_return_tribe_events( $unused_post_types ) {
83
- return array( 'tribe_events' );
84
- }
85
-
86
- /**
87
- * @var $instance
88
- */
89
- private static $instance = null;
90
-
91
- /**
92
- * @return self
93
- */
94
- public static function instance() {
95
- if ( empty( self::$instance ) ) {
96
- self::$instance = new self();
97
- }
98
-
99
- return self::$instance;
100
- }
101
-
102
- }
1
+ <?php
2
+
3
+ /**
4
+ * Handles output of The Events Calendar credits
5
+ */
6
+ class Tribe__Credits {
7
+
8
+ public static function init() {
9
+ self::instance()->hook();
10
+ }
11
+
12
+ /**
13
+ * Hook the functionality of this class into the world
14
+ */
15
+ public function hook() {
16
+ add_filter( 'tribe_events_after_html', array( $this, 'html_comment_credit' ) );
17
+ add_filter( 'admin_footer_text', array( $this, 'rating_nudge' ), 1, 2 );
18
+ }
19
+
20
+ /**
21
+ * Add credit in HTML page source
22
+ *
23
+ * @return void
24
+ **/
25
+ public function html_comment_credit( $after_html ) {
26
+
27
+ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
28
+ return $after_html;
29
+ }
30
+
31
+ $html_credit = "\n<!--\n" . esc_html__( 'This calendar is powered by %1$s.', 'tribe-common' ) . "\nhttp://m.tri.be/18wn\n-->\n";
32
+ $after_html .= apply_filters( 'tribe_html_credit', $html_credit );
33
+ return $after_html;
34
+ }
35
+
36
+ /**
37
+ * Add ratings nudge in admin footer
38
+ *
39
+ * @param $footer_text
40
+ *
41
+ * @return string
42
+ */
43
+ public function rating_nudge( $footer_text ) {
44
+ $admin_helpers = Tribe__Admin__Helpers::instance();
45
+
46
+ add_filter( 'tribe_tickets_post_types', array( $this, 'tmp_return_tribe_events' ), 99 );
47
+
48
+ // only display custom text on Tribe Admin Pages
49
+ if ( $admin_helpers->is_screen() || $admin_helpers->is_post_type_screen() ) {
50
+
51
+ if ( class_exists( 'Tribe__Events__Main' ) ) {
52
+ $review_url = 'https://wordpress.org/support/view/plugin-reviews/the-events-calendar?filter=5';
53
+
54
+ $footer_text = sprintf(
55
+ esc_html__( 'Rate %1$sThe Events Calendar%2$s %3$s', 'tribe-common' ),
56
+ '<strong>',
57
+ '</strong>',
58
+ '<a href="' . $review_url . '" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
59
+ );
60
+ } else {
61
+ $review_url = 'https://wordpress.org/support/view/plugin-reviews/event-tickets?filter=5';
62
+
63
+ $footer_text = sprintf(
64
+ esc_html__( 'Rate %1$sEvent Tickets%2$s %3$s', 'tribe-common' ),
65
+ '<strong>',
66
+ '</strong>',
67
+ '<a href="' . $review_url . '" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
68
+ );
69
+ }
70
+ }
71
+
72
+ remove_filter( 'tribe_tickets_post_types', array( $this, 'tmp_return_tribe_events' ), 99 );
73
+
74
+ return $footer_text;
75
+ }
76
+
77
+ /**
78
+ * temporary function to filter event types down to only tribe-specific types
79
+ *
80
+ * This will limit the request for ratings to only those post type pages
81
+ */
82
+ public function tmp_return_tribe_events( $unused_post_types ) {
83
+ return array( 'tribe_events' );
84
+ }
85
+
86
+ /**
87
+ * @var $instance
88
+ */
89
+ private static $instance = null;
90
+
91
+ /**
92
+ * @return self
93
+ */
94
+ public static function instance() {
95
+ if ( empty( self::$instance ) ) {
96
+ self::$instance = new self();
97
+ }
98
+
99
+ return self::$instance;
100
+ }
101
+
102
+ }
common/src/Tribe/Date_Utils.php CHANGED
@@ -1,849 +1,849 @@
1
- <?php
2
- /**
3
- * Date utility functions used throughout TEC + Addons
4
- */
5
-
6
- // Don't load directly
7
- if ( ! defined( 'ABSPATH' ) ) {
8
- die( '-1' );
9
- }
10
-
11
- if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
12
- class Tribe__Date_Utils {
13
- // Default formats, they are overridden by WP options or by arguments to date methods
14
- const DATEONLYFORMAT = 'F j, Y';
15
- const TIMEFORMAT = 'g:i A';
16
- const HOURFORMAT = 'g';
17
- const MINUTEFORMAT = 'i';
18
- const MERIDIANFORMAT = 'A';
19
- const DBDATEFORMAT = 'Y-m-d';
20
- const DBDATETIMEFORMAT = 'Y-m-d H:i:s';
21
- const DBTIMEFORMAT = 'H:i:s';
22
- const DBYEARMONTHTIMEFORMAT = 'Y-m';
23
-
24
- /**
25
- * Get the datepicker format, that is used to translate the option from the DB to a string
26
- *
27
- * @param int $translate The db Option from datepickerFormat
28
- * @return string|array If $translate is not set returns the full array, if not returns the `Y-m-d`
29
- */
30
- public static function datepicker_formats( $translate = null ) {
31
- $formats = array(
32
- 'Y-m-d',
33
- 'n/j/Y',
34
- 'm/d/Y',
35
- 'j/n/Y',
36
- 'd/m/Y',
37
- 'n-j-Y',
38
- 'm-d-Y',
39
- 'j-n-Y',
40
- 'd-m-Y',
41
- );
42
-
43
- if ( is_null( $translate ) ) {
44
- return $formats;
45
- }
46
-
47
- return isset( $formats[ $translate ] ) ? $formats[ $translate ] : $formats[0];
48
- }
49
-
50
- /**
51
- * As PHP 5.2 doesn't have a good version of `date_parse_from_format`, this is how we deal with
52
- * possible weird datepicker formats not working
53
- *
54
- * @param string $format The weird format you are using
55
- * @param string $date The date string to parse
56
- *
57
- * @return string A DB formated Date, includes time if possible
58
- */
59
- public static function datetime_from_format( $format, $date ) {
60
- // Reverse engineer the relevant date formats
61
- $keys = array(
62
- // Year with 4 Digits
63
- 'Y' => array( 'year', '\d{4}' ),
64
-
65
- // Year with 2 Digits
66
- 'y' => array( 'year', '\d{2}' ),
67
-
68
- // Month with leading 0
69
- 'm' => array( 'month', '\d{2}' ),
70
-
71
- // Month without the leading 0
72
- 'n' => array( 'month', '\d{1,2}' ),
73
-
74
- // Month ABBR 3 letters
75
- 'M' => array( 'month', '[A-Z][a-z]{2}' ),
76
-
77
- // Month Name
78
- 'F' => array( 'month', '[A-Z][a-z]{2,8}' ),
79
-
80
- // Day with leading 0
81
- 'd' => array( 'day', '\d{2}' ),
82
-
83
- // Day without leading 0
84
- 'j' => array( 'day', '\d{1,2}' ),
85
-
86
- // Day ABBR 3 Letters
87
- 'D' => array( 'day', '[A-Z][a-z]{2}' ),
88
-
89
- // Day Name
90
- 'l' => array( 'day', '[A-Z][a-z]{5,8}' ),
91
-
92
- // Hour 12h formatted, with leading 0
93
- 'h' => array( 'hour', '\d{2}' ),
94
-
95
- // Hour 24h formatted, with leading 0
96
- 'H' => array( 'hour', '\d{2}' ),
97
-
98
- // Hour 12h formatted, without leading 0
99
- 'g' => array( 'hour', '\d{1,2}' ),
100
-
101
- // Hour 24h formatted, without leading 0
102
- 'G' => array( 'hour', '\d{1,2}' ),
103
-
104
- // Minutes with leading 0
105
- 'i' => array( 'minute', '\d{2}' ),
106
-
107
- // Seconds with leading 0
108
- 's' => array( 'second', '\d{2}' ),
109
- );
110
-
111
- $date_regex = "/{$keys['Y'][1]}-{$keys['m'][1]}-{$keys['d'][1]}( {$keys['H'][1]}:{$keys['i'][1]}:{$keys['s'][1]})?$/";
112
-
113
- // if the date is already in Y-m-d or Y-m-d H:i:s, just return it
114
- if ( preg_match( $date_regex, $date ) ) {
115
- return $date;
116
- }
117
-
118
-
119
- // Convert format string to regex
120
- $regex = '';
121
- $chars = str_split( $format );
122
- foreach ( $chars as $n => $char ) {
123
- $last_char = isset( $chars[ $n - 1 ] ) ? $chars[ $n - 1 ] : '';
124
- $skip_current = '\\' == $last_char;
125
- if ( ! $skip_current && isset( $keys[ $char ] ) ) {
126
- $regex .= '(?P<' . $keys[ $char ][0] . '>' . $keys[ $char ][1] . ')';
127
- } elseif ( '\\' == $char ) {
128
- $regex .= $char;
129
- } else {
130
- $regex .= preg_quote( $char );
131
- }
132
- }
133
-
134
- $dt = array();
135
-
136
- // Now try to match it
137
- if ( preg_match( '#^' . $regex . '$#', $date, $dt ) ){
138
- // Remove unwanted Indexes
139
- foreach ( $dt as $k => $v ){
140
- if ( is_int( $k ) ){
141
- unset( $dt[ $k ] );
142
- }
143
- }
144
-
145
- // We need at least Month + Day + Year to work with
146
- if ( ! checkdate( $dt['month'], $dt['day'], $dt['year'] ) ){
147
- return false;
148
- }
149
- } else {
150
- return false;
151
- }
152
-
153
- $dt['month'] = str_pad( $dt['month'], 2, '0', STR_PAD_LEFT );
154
- $dt['day'] = str_pad( $dt['day'], 2, '0', STR_PAD_LEFT );
155
-
156
- $formatted = '{year}-{month}-{day}' . ( isset( $dt['hour'], $dt['minute'], $dt['second'] ) ? ' {hour}:{minute}:{second}' : '' );
157
- foreach ( $dt as $key => $value ) {
158
- $formatted = str_replace( '{' . $key . '}', $value, $formatted );
159
- }
160
-
161
- return $formatted;
162
- }
163
-
164
- /**
165
- * Returns the date only.
166
- *
167
- * @param int|string $date The date (timestamp or string).
168
- * @param bool $isTimestamp Is $date in timestamp format?
169
- * @param string|null $format The format used
170
- *
171
- * @return string The date only in DB format.
172
- */
173
- public static function date_only( $date, $isTimestamp = false, $format = null ) {
174
- $date = $isTimestamp ? $date : strtotime( $date );
175
-
176
- if ( is_null( $format ) ) {
177
- $format = self::DBDATEFORMAT;
178
- }
179
-
180
- return date( $format, $date );
181
- }
182
-
183
- /**
184
- * Returns the date only.
185
- *
186
- * @param string $date The date.
187
- *
188
- * @return string The time only in DB format.
189
- */
190
- public static function time_only( $date ) {
191
- return date( self::DBTIMEFORMAT, strtotime( $date ) );
192
- }
193
-
194
- /**
195
- * Returns the hour only.
196
- *
197
- * @param string $date The date.
198
- *
199
- * @return string The hour only.
200
- */
201
- public static function hour_only( $date ) {
202
- return date( self::HOURFORMAT, strtotime( $date ) );
203
- }
204
-
205
- /**
206
- * Returns the minute only.
207
- *
208
- * @param string $date The date.
209
- *
210
- * @return string The minute only.
211
- */
212
- public static function minutes_only( $date ) {
213
- return date( self::MINUTEFORMAT, strtotime( $date ) );
214
- }
215
-
216
- /**
217
- * Returns the meridian (am or pm) only.
218
- *
219
- * @param string $date The date.
220
- *
221
- * @return string The meridian only in DB format.
222
- */
223
- public static function meridian_only( $date ) {
224
- return date( self::MERIDIANFORMAT, strtotime( $date ) );
225
- }
226
-
227
- /**
228
- * Returns the number of seconds (absolute value) between two dates/times.
229
- *
230
- * @param string $date1 The first date.
231
- * @param string $date2 The second date.
232
- *
233
- * @return int The number of seconds between the dates.
234
- */
235
- public static function time_between( $date1, $date2 ) {
236
- return abs( strtotime( $date1 ) - strtotime( $date2 ) );
237
- }
238
-
239
- /**
240
- * The number of days between two arbitrary dates.
241
- *
242
- * @param string $date1 The first date.
243
- * @param string $date2 The second date.
244
- *
245
- * @return int The number of days between two dates.
246
- */
247
- public static function date_diff( $date1, $date2 ) {
248
- // Get number of days between by finding seconds between and dividing by # of seconds in a day
249
- $days = self::time_between( $date1, $date2 ) / ( 60 * 60 * 24 );
250
-
251
- return $days;
252
- }
253
-
254
- /**
255
- * Returns the last day of the month given a php date.
256
- *
257
- * @param int $timestamp THe timestamp.
258
- *
259
- * @return string The last day of the month.
260
- */
261
- public static function get_last_day_of_month( $timestamp ) {
262
- $curmonth = date( 'n', $timestamp );
263
- $curYear = date( 'Y', $timestamp );
264
- $nextmonth = mktime( 0, 0, 0, $curmonth + 1, 1, $curYear );
265
- $lastDay = strtotime( date( self::DBDATETIMEFORMAT, $nextmonth ) . ' - 1 day' );
266
-
267
- return date( 'j', $lastDay );
268
- }
269
-
270
- /**
271
- * Returns true if the timestamp is a weekday.
272
- *
273
- * @param int $curDate A timestamp.
274
- *
275
- * @return bool If the timestamp is a weekday.
276
- */
277
- public static function is_weekday( $curdate ) {
278
- return in_array( date( 'N', $curdate ), array( 1, 2, 3, 4, 5 ) );
279
- }
280
-
281
- /**
282
- * Returns true if the timestamp is a weekend.
283
- *
284
- * @param int $curDate A timestamp.
285
- *
286
- * @return bool If the timestamp is a weekend.
287
- */
288
- public static function is_weekend( $curdate ) {
289
- return in_array( date( 'N', $curdate ), array( 6, 7 ) );
290
- }
291
-
292
- /**
293
- * Gets the last day of the week in a month (ie the last Tuesday). Passing in -1 gives you the last day in the month.
294
- *
295
- * @param int $curdate A timestamp.
296
- * @param int $day_of_week The index of the day of the week.
297
- *
298
- * @return int The timestamp of the date that fits the qualifications.
299
- */
300
- public static function get_last_day_of_week_in_month( $curdate, $day_of_week ) {
301
- $nextdate = mktime( date( 'H', $curdate ), date( 'i', $curdate ), date( 's', $curdate ), date( 'n', $curdate ), self::get_last_day_of_month( $curdate ), date( 'Y', $curdate ) );;
302
-
303
- while ( date( 'N', $nextdate ) != $day_of_week && $day_of_week != - 1 ) {
304
- $nextdate = strtotime( date( self::DBDATETIMEFORMAT, $nextdate ) . ' - 1 day' );
305
- }
306
-
307
- return $nextdate;
308
- }
309
-
310
- /**
311
- * Gets the first day of the week in a month (ie the first Tuesday).
312
- *
313
- * @param int $curdate A timestamp.
314
- * @param int $day_of_week The index of the day of the week.
315
- *
316
- * @return int The timestamp of the date that fits the qualifications.
317
- */
318
- public static function get_first_day_of_week_in_month( $curdate, $day_of_week ) {
319
- $nextdate = mktime( 0, 0, 0, date( 'n', $curdate ), 1, date( 'Y', $curdate ) );
320
-
321
- while ( ! ( $day_of_week > 0 && date( 'N', $nextdate ) == $day_of_week ) &&
322
- ! ( $day_of_week == - 1 && self::is_weekday( $nextdate ) ) &&
323
- ! ( $day_of_week == - 2 && self::is_weekend( $nextdate ) ) ) {
324
- $nextdate = strtotime( date( self::DBDATETIMEFORMAT, $nextdate ) . ' + 1 day' );
325
- }
326
-
327
- return $nextdate;
328
- }
329
-
330
- /**
331
- * From http://php.net/manual/en/function.date.php
332
- *
333
- * @param int $number A number.
334
- *
335
- * @return string The ordinal for that number.
336
- */
337
- public static function number_to_ordinal( $number ) {
338
- $output = $number . ( ( ( strlen( $number ) > 1 ) && ( substr( $number, - 2, 1 ) == '1' ) ) ?
339
- 'th' : date( 'S', mktime( 0, 0, 0, 0, substr( $number, - 1 ), 0 ) ) );
340
-
341
- return apply_filters( 'tribe_events_number_to_ordinal', $output, $number );
342
- }
343
-
344
- /**
345
- * check if a given string is a timestamp
346
- *
347
- * @param $timestamp
348
- *
349
- * @return bool
350
- */
351
- public static function is_timestamp( $timestamp ) {
352
- if ( is_numeric( $timestamp ) && (int) $timestamp == $timestamp && date( 'U', $timestamp ) == $timestamp ) {
353
- return true;
354
- }
355
-
356
- return false;
357
- }
358
-
359
- /**
360
- * Accepts a string representing a date/time and attempts to convert it to
361
- * the specified format, returning an empty string if this is not possible.
362
- *
363
- * @param $dt_string
364
- * @param $new_format
365
- *
366
- * @return string
367
- */
368
- public static function reformat( $dt_string, $new_format ) {
369
- $timestamp = strtotime( $dt_string );
370
- $revised = date( $new_format, $timestamp );
371
-
372
- return $revised ? $revised : '';
373
- }
374
-
375
- /**
376
- * Accepts a numeric offset (such as "4" or "-6" as stored in the gmt_offset
377
- * option) and converts it to a strtotime() style modifier that can be used
378
- * to adjust a DateTime object, etc.
379
- *
380
- * @param $offset
381
- *
382
- * @return string
383
- */
384
- public static function get_modifier_from_offset( $offset ) {
385
- $modifier = '';
386
- $offset = (float) $offset;
387
-
388
- // Separate out hours, minutes, polarity
389
- $hours = (int) $offset;
390
- $minutes = (int) ( ( $offset - $hours ) * 60 );
391
- $polarity = ( $offset >= 0 ) ? '+' : '-';
392
-
393
- // Correct hours and minutes to positive values
394
- if ( $hours < 0 ) $hours *= -1;
395
- if ( $minutes < 0 ) $minutes *= -1;
396
-
397
- // Form the modifier string
398
- if ( $hours >= 0 ) $modifier = "$polarity $hours hours ";
399
- if ( $minutes > 0 ) $modifier .= "$minutes minutes";
400
-
401
- return $modifier;
402
- }
403
-
404
- /**
405
- * Returns the weekday of the 1st day of the month in
406
- * "w" format (ie, Sunday is 0 and Saturday is 6) or
407
- * false if this cannot be established.
408
- *
409
- * @param mixed $month
410
- * @return int|bool
411
- */
412
- public static function first_day_in_month( $month ) {
413
- try {
414
- $date = new DateTime( $month );
415
- $day_1 = new DateTime( $date->format( 'Y-m-01 ' ) );
416
- return $day_1->format( 'w' );
417
- }
418
- catch ( Exception $e ) {
419
- return false;
420
- }
421
- }
422
-
423
- /**
424
- * Returns the weekday of the last day of the month in
425
- * "w" format (ie, Sunday is 0 and Saturday is 6) or
426
- * false if this cannot be established.
427
- *
428
- * @param mixed $month
429
- * @return int|bool
430
- */
431
- public static function last_day_in_month( $month ) {
432
- try {
433
- $date = new DateTime( $month );
434
- $day_1 = new DateTime( $date->format( 'Y-m-t' ) );
435
- return $day_1->format( 'w' );
436
- }
437
- catch ( Exception $e ) {
438
- return false;
439
- }
440
- }
441
-
442
- /**
443
- * Returns the day of the week the week ends on, expressed as a "w" value
444
- * (ie, Sunday is 0 and Saturday is 6).
445
- *
446
- * @param int $week_starts_on
447
- *
448
- * @return int
449
- */
450
- public static function week_ends_on( $week_starts_on ) {
451
- if ( --$week_starts_on < 0 ) $week_starts_on = 6;
452
- return $week_starts_on;
453
- }
454
-
455
- /**
456
- * Helper method to convert EventAllDay values to a boolean
457
- *
458
- * @param mixed $all_day_value Value to check for "all day" status. All day values: (true, 'true', 'TRUE', 'yes')
459
- *
460
- * @return boolean Is value considered "All Day"?
461
- */
462
- public static function is_all_day( $all_day_value ) {
463
- $all_day_value = trim( $all_day_value );
464
-
465
- return (
466
- 'true' === strtolower( $all_day_value )
467
- || 'yes' === strtolower( $all_day_value )
468
- || true === $all_day_value
469
- || 1 == $all_day_value
470
- );
471
- }
472
-
473
- /**
474
- * Given 2 datetime ranges, return whether the 2nd one occurs during the 1st one
475
- * Note: all params should be unix timestamps
476
- *
477
- * @param integer $range_1_start timestamp for start of the first range
478
- * @param integer $range_1_end timestamp for end of the first range
479
- * @param integer $range_2_start timestamp for start of the second range
480
- * @param integer $range_2_end timestamp for end of the second range
481
- *
482
- * @return bool
483
- */
484
- public static function range_coincides( $range_1_start, $range_1_end, $range_2_start, $range_2_end ) {
485
-
486
- // Initialize the return value
487
- $range_coincides = false;
488
-
489
- /**
490
- * conditions:
491
- * range 2 starts during range 1 (range 2 start time is between start and end of range 1 )
492
- * range 2 ends during range 1 (range 2 end time is between start and end of range 1 )
493
- * range 2 encloses range 1 (range 2 starts before range 1 and ends after range 1)
494
- */
495
-
496
- $range_2_starts_during_range_1 = $range_2_start >= $range_1_start && $range_2_start < $range_1_end;
497
- $range_2_ends_during_range_1 = $range_2_end > $range_1_start && $range_2_end <= $range_1_end;
498
- $range_2_encloses_range_1 = $range_2_start < $range_1_start && $range_2_end > $range_1_end;
499
-
500
- if ( $range_2_starts_during_range_1 || $range_2_ends_during_range_1 || $range_2_encloses_range_1 ) {
501
- $range_coincides = true;
502
- }
503
-
504
- return $range_coincides;
505
-
506
- }
507
-
508
- /**
509
- * Converts a locally-formatted date to a unix timestamp. This is a drop-in
510
- * replacement for `strtotime()`, except that where strtotime assumes GMT, this
511
- * assumes local time (as described below). If a timezone is specified, this
512
- * function defers to strtotime().
513
- *
514
- * If there is a timezone_string available, the date is assumed to be in that
515
- * timezone, otherwise it simply subtracts the value of the 'gmt_offset'
516
- * option.
517
- *
518
- * @see strtotime()
519
- * @uses get_option() to retrieve the value of 'gmt_offset'
520
- *
521
- * @param string $string A date/time string. See `strtotime` for valid formats
522
- *
523
- * @return int UNIX timestamp.
524
- */
525
- public static function wp_strtotime( $string ) {
526
- // If there's a timezone specified, we shouldn't convert it
527
- try {
528
- $test_date = new DateTime( $string );
529
- if ( 'UTC' != $test_date->getTimezone()->getName() ) {
530
- return strtotime( $string );
531
- }
532
- } catch ( Exception $e ) {
533
- return strtotime( $string );
534
- }
535
-
536
- $tz = get_option( 'timezone_string' );
537
- if ( ! empty( $tz ) ) {
538
- $date = date_create( $string, new DateTimeZone( $tz ) );
539
- if ( ! $date ) {
540
- return strtotime( $string );
541
- }
542
- $date->setTimezone( new DateTimeZone( 'UTC' ) );
543
- return $date->format( 'U' );
544
- } else {
545
- $offset = (float) get_option( 'gmt_offset' );
546
- $seconds = intval( $offset * HOUR_IN_SECONDS );
547
- $timestamp = strtotime( $string ) - $seconds;
548
- return $timestamp;
549
- }
550
- }
551
-
552
- // DEPRECATED METHODS
553
- // @codingStandardsIgnoreStart
554
- /**
555
- * Deprecated camelCase version of self::date_only
556
- *
557
- * @param int|string $date The date (timestamp or string).
558
- * @param bool $isTimestamp Is $date in timestamp format?
559
- *
560
- * @return string The date only in DB format.
561
- */
562
- public static function dateOnly( $date, $isTimestamp = false ) {
563
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::date_only' );
564
- return self::date_only( $date, $isTimestamp );
565
- }
566
-
567
- /**
568
- * Deprecated camelCase version of self::time_only
569
- *
570
- * @param string $date The date.
571
- *
572
- * @return string The time only in DB format.
573
- */
574
- public static function timeOnly( $date ) {
575
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::time_only' );
576
- return self::time_only( $date );
577
- }
578
-
579
- /**
580
- * Deprecated camelCase version of self::hour_only
581
- *
582
- * @param string $date The date.
583
- *
584
- * @return string The hour only.
585
- */
586
- public static function hourOnly( $date ) {
587
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::hour_only' );
588
- return self::hour_only( $date );
589
- }
590
-
591
- /**
592
- * Deprecated camelCase version of self::minutes_only
593
- *
594
- * @param string $date The date.
595
- *
596
- * @return string The minute only.
597
- */
598
- public static function minutesOnly( $date ) {
599
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::minutes_only' );
600
- return self::minutes_only( $date );
601
- }
602
-
603
- /**
604
- * Deprecated camelCase version of self::meridian_only
605
- *
606
- * @param string $date The date.
607
- *
608
- * @return string The meridian only in DB format.
609
- */
610
- public static function meridianOnly( $date ) {
611
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::meridian_only' );
612
- return self::meridian_only( $date );
613
- }
614
-
615
- /**
616
- * Returns the end of a given day.
617
- *
618
- * @deprecated since 3.10 - use tribe_event_end_of_day()
619
- * @todo remove in 4.1
620
- *
621
- * @param int|string $date The date (timestamp or string).
622
- * @param bool $isTimestamp Is $date in timestamp format?
623
- *
624
- * @return string The date and time of the end of a given day
625
- */
626
- public static function endOfDay( $date, $isTimestamp = false ) {
627
- _deprecated_function( __METHOD__, '3.10', 'tribe_event_end_of_day' );
628
-
629
- if ( $isTimestamp ) {
630
- $date = date( self::DBDATEFORMAT, $date );
631
- }
632
-
633
- return tribe_event_end_of_day( $date, self::DBDATETIMEFORMAT );
634
- }
635
-
636
- /**
637
- * Returns the beginning of a given day.
638
- *
639
- * @deprecated since 3.10
640
- * @todo remove in 4.1
641
- *
642
- * @param int|string $date The date (timestamp or string).
643
- * @param bool $isTimestamp Is $date in timestamp format?
644
- *
645
- * @return string The date and time of the beginning of a given day.
646
- */
647
- public static function beginningOfDay( $date, $isTimestamp = false ) {
648
- _deprecated_function( __METHOD__, '3.10', 'tribe_event_beginning_of_day' );
649
-
650
- if ( $isTimestamp ) {
651
- $date = date( self::DBDATEFORMAT, $date );
652
- }
653
-
654
- return tribe_event_beginning_of_day( $date, self::DBDATETIMEFORMAT );
655
- }
656
-
657
- /**
658
- * Deprecated camelCase version of self::time_between
659
- *
660
- * @param string $date1 The first date.
661
- * @param string $date2 The second date.
662
- *
663
- * @return int The number of seconds between the dates.
664
- */
665
- public static function timeBetween( $date1, $date2 ) {
666
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::time_between' );
667
- return self::time_between( $date1, $date2 );
668
- }
669
-
670
- /**
671
- * Deprecated camelCase version of self::date_diff
672
- *
673
- * @param string $date1 The first date.
674
- * @param string $date2 The second date.
675
- *
676
- * @return int The number of days between two dates.
677
- */
678
- public static function dateDiff( $date1, $date2 ) {
679
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::date_diff' );
680
- return self::date_diff( $date1, $date2 );
681
- }
682
-
683
- /**
684
- * Deprecated camelCase version of self::get_last_day_of_month
685
- *
686
- * @param int $timestamp THe timestamp.
687
- *
688
- * @return string The last day of the month.
689
- */
690
- public static function getLastDayOfMonth( $timestamp ) {
691
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::get_last_day_of_month' );
692
- return self::get_last_day_of_month( $timestamp );
693
- }
694
-
695
- /**
696
- * Deprecated camelCase version of self::is_weekday
697
- *
698
- * @param int $curDate A timestamp.
699
- *
700
- * @return bool If the timestamp is a weekday.
701
- */
702
- public static function isWeekday( $curdate ) {
703
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_weekday' );
704
- return self::is_weekday( $curdate );
705
- }
706
-
707
- /**
708
- * Deprecated camelCase version of self::is_weekend
709
- *
710
- * @param int $curDate A timestamp.
711
- *
712
- * @return bool If the timestamp is a weekend.
713
- */
714
- public static function isWeekend( $curdate ) {
715
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_weekend' );
716
- return self::is_weekend( $curdate );
717
- }
718
-
719
- /**
720
- * Deprecated camelCase version of self::get_last_day_of_week_in_month
721
- *
722
- * @param int $curdate A timestamp.
723
- * @param int $day_of_week The index of the day of the week.
724
- *
725
- * @return int The timestamp of the date that fits the qualifications.
726
- */
727
- public static function getLastDayOfWeekInMonth( $curdate, $day_of_week ) {
728
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::get_last_day_of_week_in_month' );
729
- return self::get_last_day_of_week_in_month( $curdate, $day_of_week );
730
- }
731
-
732
- /**
733
- * Deprecated camelCase version of self::get_first_day_of_week_in_month
734
- *
735
- * @param int $curdate A timestamp.
736
- * @param int $day_of_week The index of the day of the week.
737
- *
738
- * @return int The timestamp of the date that fits the qualifications.
739
- */
740
- public static function getFirstDayOfWeekInMonth( $curdate, $day_of_week ) {
741
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::get_fist_day_of_week_in_month' );
742
- return self::get_first_day_of_week_in_month( $curdate, $day_of_week );
743
- }
744
-
745
- /**
746
- * Deprecated camelCase version of self::number_to_ordinal
747
- *
748
- * @param int $number A number.
749
- *
750
- * @return string The ordinal for that number.
751
- */
752
- public static function numberToOrdinal( $number ) {
753
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::number_to_ordinal' );
754
- return self::number_to_ordinal( $number );
755
- }
756
-
757
- /**
758
- * Deprecated camelCase version of self::is_timestamp
759
- *
760
- * @param $timestamp
761
- *
762
- * @return bool
763
- */
764
- public static function isTimestamp( $timestamp ) {
765
- _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_timestamp' );
766
- return self::is_timestamp( $timestamp );
767
- }
768
-
769
- /**
770
- * Gets the timestamp of a day in week, month and year context.
771
- *
772
- * Kudos to [icedwater StackOverflow user](http://stackoverflow.com/users/1091386/icedwater) in
773
- * [his answer](http://stackoverflow.com/questions/924246/get-the-first-or-last-friday-in-a-month).
774
- *
775
- * Usage examples:
776
- * "The second Wednesday of March 2015" - `get_day_timestamp( 3, 2, 3, 2015, 1)`
777
- * "The last Friday of December 2015" - `get_day_timestamp( 5, 1, 12, 2015, -1)`
778
- * "The first Monday of April 2016 - `get_day_timestamp( 1, 1, 4, 2016, 1)`
779
- * "The penultimate Thursday of January 2012" - `get_day_timestamp( 4, 2, 1, 2012, -1)`
780
- *
781
- * @param int $day_of_week The day representing the number in the week, Monday is `1`, Tuesday is `2`, Sunday is `7`
782
- * @param int $week_in_month The week number in the month; first week is `1`, second week is `2`; when direction is reverse
783
- * then `1` is last week of the month, `2` is penultimate week of the month and so on.
784
- * @param int $month The month number in the year, January is `1`
785
- * @param int $year The year number, e.g. "2015"
786
- * @param int $week_direction Either `1` or `-1`; the direction for the search referring to the week, defaults to `1`
787
- * to specify weeks in natural order so:
788
- * $week_direction `1` and $week_in_month `1` means "first week of the month"
789
- * $week_direction `1` and $week_in_month `3` means "third week of the month"
790
- * $week_direction `-1` and $week_in_month `1` means "last week of the month"
791
- * $week_direction `-1` and $week_in_month `2` means "penultimmate week of the month"
792
- *
793
- * @return int The day timestamp
794
- */
795
- public static function get_weekday_timestamp( $day_of_week, $week_in_month, $month, $year, $week_direction = 1 ) {
796
- if (
797
- ! (
798
- is_numeric( $day_of_week )
799
- && is_numeric( $week_in_month )
800
- && is_numeric( $month )
801
- && is_numeric( $year )
802
- && is_numeric( $week_direction )
803
- && in_array( $week_direction, array( - 1, 1 ) )
804
- )
805
- ) {
806
- return false;
807
- }
808
-
809
- if ( $week_direction > 0 ) {
810
- $startday = 1;
811
- } else {
812
- $startday = date( 't', mktime( 0, 0, 0, $month, 1, $year ) );
813
- }
814
-
815
- $start = mktime( 0, 0, 0, $month, $startday, $year );
816
- $weekday = date( 'N', $start );
817
-
818
- if ( $week_direction * $day_of_week >= $week_direction * $weekday ) {
819
- $offset = - $week_direction * 7;
820
- } else {
821
- $offset = 0;
822
- }
823
-
824
- $offset += $week_direction * ( $week_in_month * 7 ) + ( $day_of_week - $weekday );
825
-
826
- return mktime( 0, 0, 0, $month, $startday + $offset, $year );
827
- }
828
-
829
- /**
830
- * Unescapes date format strings to be used in functions like `date`.
831
- *
832
- * Double escaping happens when storing a date format in the database.
833
- *
834
- * @param mixed $date_format A date format string.
835
- *
836
- * @return mixed Either the original input or an unescaped date format string.
837
- */
838
- public static function unescape_date_format( $date_format ) {
839
- if ( ! is_string( $date_format ) ) {
840
- return $date_format;
841
- }
842
-
843
- // Why so simple? Let's handle other cases as those come up. We have tests in place!
844
- return str_replace( '\\\\', '\\', $date_format );
845
- }
846
- // @codingStandardsIgnoreEnd
847
- }
848
-
849
- }
1
+ <?php
2
+ /**
3
+ * Date utility functions used throughout TEC + Addons
4
+ */
5
+
6
+ // Don't load directly
7
+ if ( ! defined( 'ABSPATH' ) ) {
8
+ die( '-1' );
9
+ }
10
+
11
+ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
12
+ class Tribe__Date_Utils {
13
+ // Default formats, they are overridden by WP options or by arguments to date methods
14
+ const DATEONLYFORMAT = 'F j, Y';
15
+ const TIMEFORMAT = 'g:i A';
16
+ const HOURFORMAT = 'g';
17
+ const MINUTEFORMAT = 'i';
18
+ const MERIDIANFORMAT = 'A';
19
+ const DBDATEFORMAT = 'Y-m-d';
20
+ const DBDATETIMEFORMAT = 'Y-m-d H:i:s';
21
+ const DBTIMEFORMAT = 'H:i:s';
22
+ const DBYEARMONTHTIMEFORMAT = 'Y-m';
23
+
24
+ /**
25
+ * Get the datepicker format, that is used to translate the option from the DB to a string
26
+ *
27
+ * @param int $translate The db Option from datepickerFormat
28
+ * @return string|array If $translate is not set returns the full array, if not returns the `Y-m-d`
29
+ */
30
+ public static function datepicker_formats( $translate = null ) {
31
+ $formats = array(
32
+ 'Y-m-d',
33
+ 'n/j/Y',
34
+ 'm/d/Y',
35
+ 'j/n/Y',
36
+ 'd/m/Y',
37
+ 'n-j-Y',
38
+ 'm-d-Y',
39
+ 'j-n-Y',
40
+ 'd-m-Y',
41
+ );
42
+
43
+ if ( is_null( $translate ) ) {
44
+ return $formats;
45
+ }
46
+
47
+ return isset( $formats[ $translate ] ) ? $formats[ $translate ] : $formats[0];
48
+ }
49
+
50
+ /**
51
+ * As PHP 5.2 doesn't have a good version of `date_parse_from_format`, this is how we deal with
52
+ * possible weird datepicker formats not working
53
+ *
54
+ * @param string $format The weird format you are using
55
+ * @param string $date The date string to parse
56
+ *
57
+ * @return string A DB formated Date, includes time if possible
58
+ */
59
+ public static function datetime_from_format( $format, $date ) {
60
+ // Reverse engineer the relevant date formats
61
+ $keys = array(
62
+ // Year with 4 Digits
63
+ 'Y' => array( 'year', '\d{4}' ),
64
+
65
+ // Year with 2 Digits
66
+ 'y' => array( 'year', '\d{2}' ),
67
+
68
+ // Month with leading 0
69
+ 'm' => array( 'month', '\d{2}' ),
70
+
71
+ // Month without the leading 0
72
+ 'n' => array( 'month', '\d{1,2}' ),
73
+
74
+ // Month ABBR 3 letters
75
+ 'M' => array( 'month', '[A-Z][a-z]{2}' ),
76
+
77
+ // Month Name
78
+ 'F' => array( 'month', '[A-Z][a-z]{2,8}' ),
79
+
80
+ // Day with leading 0
81
+ 'd' => array( 'day', '\d{2}' ),
82
+
83
+ // Day without leading 0
84
+ 'j' => array( 'day', '\d{1,2}' ),
85
+
86
+ // Day ABBR 3 Letters
87
+ 'D' => array( 'day', '[A-Z][a-z]{2}' ),
88
+
89
+ // Day Name
90
+ 'l' => array( 'day', '[A-Z][a-z]{5,8}' ),
91
+
92
+ // Hour 12h formatted, with leading 0
93
+ 'h' => array( 'hour', '\d{2}' ),
94
+
95
+ // Hour 24h formatted, with leading 0
96
+ 'H' => array( 'hour', '\d{2}' ),
97
+
98
+ // Hour 12h formatted, without leading 0
99
+ 'g' => array( 'hour', '\d{1,2}' ),
100
+
101
+ // Hour 24h formatted, without leading 0
102
+ 'G' => array( 'hour', '\d{1,2}' ),
103
+
104
+ // Minutes with leading 0
105
+ 'i' => array( 'minute', '\d{2}' ),
106
+
107
+ // Seconds with leading 0
108
+ 's' => array( 'second', '\d{2}' ),
109
+ );
110
+
111
+ $date_regex = "/{$keys['Y'][1]}-{$keys['m'][1]}-{$keys['d'][1]}( {$keys['H'][1]}:{$keys['i'][1]}:{$keys['s'][1]})?$/";
112
+
113
+ // if the date is already in Y-m-d or Y-m-d H:i:s, just return it
114
+ if ( preg_match( $date_regex, $date ) ) {
115
+ return $date;
116
+ }
117
+
118
+
119
+ // Convert format string to regex
120
+ $regex = '';
121
+ $chars = str_split( $format );
122
+ foreach ( $chars as $n => $char ) {
123
+ $last_char = isset( $chars[ $n - 1 ] ) ? $chars[ $n - 1 ] : '';
124
+ $skip_current = '\\' == $last_char;
125
+ if ( ! $skip_current && isset( $keys[ $char ] ) ) {
126
+ $regex .= '(?P<' . $keys[ $char ][0] . '>' . $keys[ $char ][1] . ')';
127
+ } elseif ( '\\' == $char ) {
128
+ $regex .= $char;
129
+ } else {
130
+ $regex .= preg_quote( $char );
131
+ }
132
+ }
133
+
134
+ $dt = array();
135
+
136
+ // Now try to match it
137
+ if ( preg_match( '#^' . $regex . '$#', $date, $dt ) ){
138
+ // Remove unwanted Indexes
139
+ foreach ( $dt as $k => $v ){
140
+ if ( is_int( $k ) ){
141
+ unset( $dt[ $k ] );
142
+ }
143
+ }
144
+
145
+ // We need at least Month + Day + Year to work with
146
+ if ( ! checkdate( $dt['month'], $dt['day'], $dt['year'] ) ){
147
+ return false;
148
+ }
149
+ } else {
150
+ return false;
151
+ }
152
+
153
+ $dt['month'] = str_pad( $dt['month'], 2, '0', STR_PAD_LEFT );
154
+ $dt['day'] = str_pad( $dt['day'], 2, '0', STR_PAD_LEFT );
155
+
156
+ $formatted = '{year}-{month}-{day}' . ( isset( $dt['hour'], $dt['minute'], $dt['second'] ) ? ' {hour}:{minute}:{second}' : '' );
157
+ foreach ( $dt as $key => $value ) {
158
+ $formatted = str_replace( '{' . $key . '}', $value, $formatted );
159
+ }
160
+
161
+ return $formatted;
162
+ }
163
+
164
+ /**
165
+ * Returns the date only.
166
+ *
167
+ * @param int|string $date The date (timestamp or string).
168
+ * @param bool $isTimestamp Is $date in timestamp format?
169
+ * @param string|null $format The format used
170
+ *
171
+ * @return string The date only in DB format.
172
+ */
173
+ public static function date_only( $date, $isTimestamp = false, $format = null ) {
174
+ $date = $isTimestamp ? $date : strtotime( $date );
175
+
176
+ if ( is_null( $format ) ) {
177
+ $format = self::DBDATEFORMAT;
178
+ }
179
+
180
+ return date( $format, $date );
181
+ }
182
+
183
+ /**
184
+ * Returns the date only.
185
+ *
186
+ * @param string $date The date.
187
+ *
188
+ * @return string The time only in DB format.
189
+ */
190
+ public static function time_only( $date ) {
191
+ return date( self::DBTIMEFORMAT, strtotime( $date ) );
192
+ }
193
+
194
+ /**
195
+ * Returns the hour only.
196
+ *
197
+ * @param string $date The date.
198
+ *
199
+ * @return string The hour only.
200
+ */
201
+ public static function hour_only( $date ) {
202
+ return date( self::HOURFORMAT, strtotime( $date ) );
203
+ }
204
+
205
+ /**
206
+ * Returns the minute only.
207
+ *
208
+ * @param string $date The date.
209
+ *
210
+ * @return string The minute only.
211
+ */
212
+ public static function minutes_only( $date ) {
213
+ return date( self::MINUTEFORMAT, strtotime( $date ) );
214
+ }
215
+
216
+ /**
217
+ * Returns the meridian (am or pm) only.
218
+ *
219
+ * @param string $date The date.
220
+ *
221
+ * @return string The meridian only in DB format.
222
+ */
223
+ public static function meridian_only( $date ) {
224
+ return date( self::MERIDIANFORMAT, strtotime( $date ) );
225
+ }
226
+
227
+ /**
228
+ * Returns the number of seconds (absolute value) between two dates/times.
229
+ *
230
+ * @param string $date1 The first date.
231
+ * @param string $date2 The second date.
232
+ *
233
+ * @return int The number of seconds between the dates.
234
+ */
235
+ public static function time_between( $date1, $date2 ) {
236
+ return abs( strtotime( $date1 ) - strtotime( $date2 ) );
237
+ }
238
+
239
+ /**
240
+ * The number of days between two arbitrary dates.
241
+ *
242
+ * @param string $date1 The first date.
243
+ * @param string $date2 The second date.
244
+ *
245
+ * @return int The number of days between two dates.
246
+ */
247
+ public static function date_diff( $date1, $date2 ) {
248
+ // Get number of days between by finding seconds between and dividing by # of seconds in a day
249
+ $days = self::time_between( $date1, $date2 ) / ( 60 * 60 * 24 );
250
+
251
+ return $days;
252
+ }
253
+
254
+ /**
255
+ * Returns the last day of the month given a php date.
256
+ *
257
+ * @param int $timestamp THe timestamp.
258
+ *
259
+ * @return string The last day of the month.
260
+ */
261
+ public static function get_last_day_of_month( $timestamp ) {
262
+ $curmonth = date( 'n', $timestamp );
263
+ $curYear = date( 'Y', $timestamp );
264
+ $nextmonth = mktime( 0, 0, 0, $curmonth + 1, 1, $curYear );
265
+ $lastDay = strtotime( date( self::DBDATETIMEFORMAT, $nextmonth ) . ' - 1 day' );
266
+
267
+ return date( 'j', $lastDay );
268
+ }
269
+
270
+ /**
271
+ * Returns true if the timestamp is a weekday.
272
+ *
273
+ * @param int $curDate A timestamp.
274
+ *
275
+ * @return bool If the timestamp is a weekday.
276
+ */
277
+ public static function is_weekday( $curdate ) {
278
+ return in_array( date( 'N', $curdate ), array( 1, 2, 3, 4, 5 ) );
279
+ }
280
+
281
+ /**
282
+ * Returns true if the timestamp is a weekend.
283
+ *
284
+ * @param int $curDate A timestamp.
285
+ *
286
+ * @return bool If the timestamp is a weekend.
287
+ */
288
+ public static function is_weekend( $curdate ) {
289
+ return in_array( date( 'N', $curdate ), array( 6, 7 ) );
290
+ }
291
+
292
+ /**
293
+ * Gets the last day of the week in a month (ie the last Tuesday). Passing in -1 gives you the last day in the month.
294
+ *
295
+ * @param int $curdate A timestamp.
296
+ * @param int $day_of_week The index of the day of the week.
297
+ *
298
+ * @return int The timestamp of the date that fits the qualifications.
299
+ */
300
+ public static function get_last_day_of_week_in_month( $curdate, $day_of_week ) {
301
+ $nextdate = mktime( date( 'H', $curdate ), date( 'i', $curdate ), date( 's', $curdate ), date( 'n', $curdate ), self::get_last_day_of_month( $curdate ), date( 'Y', $curdate ) );;
302
+
303
+ while ( date( 'N', $nextdate ) != $day_of_week && $day_of_week != - 1 ) {
304
+ $nextdate = strtotime( date( self::DBDATETIMEFORMAT, $nextdate ) . ' - 1 day' );
305
+ }
306
+
307
+ return $nextdate;
308
+ }
309
+
310
+ /**
311
+ * Gets the first day of the week in a month (ie the first Tuesday).
312
+ *
313
+ * @param int $curdate A timestamp.
314
+ * @param int $day_of_week The index of the day of the week.
315
+ *
316
+ * @return int The timestamp of the date that fits the qualifications.
317
+ */
318
+ public static function get_first_day_of_week_in_month( $curdate, $day_of_week ) {
319
+ $nextdate = mktime( 0, 0, 0, date( 'n', $curdate ), 1, date( 'Y', $curdate ) );
320
+
321
+ while ( ! ( $day_of_week > 0 && date( 'N', $nextdate ) == $day_of_week ) &&
322
+ ! ( $day_of_week == - 1 && self::is_weekday( $nextdate ) ) &&
323
+ ! ( $day_of_week == - 2 && self::is_weekend( $nextdate ) ) ) {
324
+ $nextdate = strtotime( date( self::DBDATETIMEFORMAT, $nextdate ) . ' + 1 day' );
325
+ }
326
+
327
+ return $nextdate;
328
+ }
329
+
330
+ /**
331
+ * From http://php.net/manual/en/function.date.php
332
+ *
333
+ * @param int $number A number.
334
+ *
335
+ * @return string The ordinal for that number.
336
+ */
337
+ public static function number_to_ordinal( $number ) {
338
+ $output = $number . ( ( ( strlen( $number ) > 1 ) && ( substr( $number, - 2, 1 ) == '1' ) ) ?
339
+ 'th' : date( 'S', mktime( 0, 0, 0, 0, substr( $number, - 1 ), 0 ) ) );
340
+
341
+ return apply_filters( 'tribe_events_number_to_ordinal', $output, $number );
342
+ }
343
+
344
+ /**
345
+ * check if a given string is a timestamp
346
+ *
347
+ * @param $timestamp
348
+ *
349
+ * @return bool
350
+ */
351
+ public static function is_timestamp( $timestamp ) {
352
+ if ( is_numeric( $timestamp ) && (int) $timestamp == $timestamp && date( 'U', $timestamp ) == $timestamp ) {
353
+ return true;
354
+ }
355
+
356
+ return false;
357
+ }
358
+
359
+ /**
360
+ * Accepts a string representing a date/time and attempts to convert it to
361
+ * the specified format, returning an empty string if this is not possible.
362
+ *
363
+ * @param $dt_string
364
+ * @param $new_format
365
+ *
366
+ * @return string
367
+ */
368
+ public static function reformat( $dt_string, $new_format ) {
369
+ $timestamp = strtotime( $dt_string );
370
+ $revised = date( $new_format, $timestamp );
371
+
372
+ return $revised ? $revised : '';
373
+ }
374
+
375
+ /**
376
+ * Accepts a numeric offset (such as "4" or "-6" as stored in the gmt_offset
377
+ * option) and converts it to a strtotime() style modifier that can be used
378
+ * to adjust a DateTime object, etc.
379
+ *
380
+ * @param $offset
381
+ *
382
+ * @return string
383
+ */
384
+ public static function get_modifier_from_offset( $offset ) {
385
+ $modifier = '';
386
+ $offset = (float) $offset;
387
+
388
+ // Separate out hours, minutes, polarity
389
+ $hours = (int) $offset;
390
+ $minutes = (int) ( ( $offset - $hours ) * 60 );
391
+ $polarity = ( $offset >= 0 ) ? '+' : '-';
392
+
393
+ // Correct hours and minutes to positive values
394
+ if ( $hours < 0 ) $hours *= -1;
395
+ if ( $minutes < 0 ) $minutes *= -1;
396
+
397
+ // Form the modifier string
398
+ if ( $hours >= 0 ) $modifier = "$polarity $hours hours ";
399
+ if ( $minutes > 0 ) $modifier .= "$minutes minutes";
400
+
401
+ return $modifier;
402
+ }
403
+
404
+ /**
405
+ * Returns the weekday of the 1st day of the month in
406
+ * "w" format (ie, Sunday is 0 and Saturday is 6) or
407
+ * false if this cannot be established.
408
+ *
409
+ * @param mixed $month
410
+ * @return int|bool
411
+ */
412
+ public static function first_day_in_month( $month ) {
413
+ try {
414
+ $date = new DateTime( $month );
415
+ $day_1 = new DateTime( $date->format( 'Y-m-01 ' ) );
416
+ return $day_1->format( 'w' );
417
+ }
418
+ catch ( Exception $e ) {
419
+ return false;
420
+ }
421
+ }
422
+
423
+ /**
424
+ * Returns the weekday of the last day of the month in
425
+ * "w" format (ie, Sunday is 0 and Saturday is 6) or
426
+ * false if this cannot be established.
427
+ *
428
+ * @param mixed $month
429
+ * @return int|bool
430
+ */
431
+ public static function last_day_in_month( $month ) {
432
+ try {
433
+ $date = new DateTime( $month );
434
+ $day_1 = new DateTime( $date->format( 'Y-m-t' ) );
435
+ return $day_1->format( 'w' );
436
+ }
437
+ catch ( Exception $e ) {
438
+ return false;
439
+ }
440
+ }
441
+
442
+ /**
443
+ * Returns the day of the week the week ends on, expressed as a "w" value
444
+ * (ie, Sunday is 0 and Saturday is 6).
445
+ *
446
+ * @param int $week_starts_on
447
+ *
448
+ * @return int
449
+ */
450
+ public static function week_ends_on( $week_starts_on ) {
451
+ if ( --$week_starts_on < 0 ) $week_starts_on = 6;
452
+ return $week_starts_on;
453
+ }
454
+
455
+ /**
456
+ * Helper method to convert EventAllDay values to a boolean
457
+ *
458
+ * @param mixed $all_day_value Value to check for "all day" status. All day values: (true, 'true', 'TRUE', 'yes')
459
+ *
460
+ * @return boolean Is value considered "All Day"?
461
+ */
462
+ public static function is_all_day( $all_day_value ) {
463
+ $all_day_value = trim( $all_day_value );
464
+
465
+ return (
466
+ 'true' === strtolower( $all_day_value )
467
+ || 'yes' === strtolower( $all_day_value )
468
+ || true === $all_day_value
469
+ || 1 == $all_day_value
470
+ );
471
+ }
472
+
473
+ /**
474
+ * Given 2 datetime ranges, return whether the 2nd one occurs during the 1st one
475
+ * Note: all params should be unix timestamps
476
+ *
477
+ * @param integer $range_1_start timestamp for start of the first range
478
+ * @param integer $range_1_end timestamp for end of the first range
479
+ * @param integer $range_2_start timestamp for start of the second range
480
+ * @param integer $range_2_end timestamp for end of the second range
481
+ *
482
+ * @return bool
483
+ */
484
+ public static function range_coincides( $range_1_start, $range_1_end, $range_2_start, $range_2_end ) {
485
+
486
+ // Initialize the return value
487
+ $range_coincides = false;
488
+
489
+ /**
490
+ * conditions:
491
+ * range 2 starts during range 1 (range 2 start time is between start and end of range 1 )
492
+ * range 2 ends during range 1 (range 2 end time is between start and end of range 1 )
493
+ * range 2 encloses range 1 (range 2 starts before range 1 and ends after range 1)
494
+ */
495
+
496
+ $range_2_starts_during_range_1 = $range_2_start >= $range_1_start && $range_2_start < $range_1_end;
497
+ $range_2_ends_during_range_1 = $range_2_end > $range_1_start && $range_2_end <= $range_1_end;
498
+ $range_2_encloses_range_1 = $range_2_start < $range_1_start && $range_2_end > $range_1_end;
499
+
500
+ if ( $range_2_starts_during_range_1 || $range_2_ends_during_range_1 || $range_2_encloses_range_1 ) {
501
+ $range_coincides = true;
502
+ }
503
+
504
+ return $range_coincides;
505
+
506
+ }
507
+
508
+ /**
509
+ * Converts a locally-formatted date to a unix timestamp. This is a drop-in
510
+ * replacement for `strtotime()`, except that where strtotime assumes GMT, this
511
+ * assumes local time (as described below). If a timezone is specified, this
512
+ * function defers to strtotime().
513
+ *
514
+ * If there is a timezone_string available, the date is assumed to be in that
515
+ * timezone, otherwise it simply subtracts the value of the 'gmt_offset'
516
+ * option.
517
+ *
518
+ * @see strtotime()
519
+ * @uses get_option() to retrieve the value of 'gmt_offset'
520
+ *
521
+ * @param string $string A date/time string. See `strtotime` for valid formats
522
+ *
523
+ * @return int UNIX timestamp.
524
+ */
525
+ public static function wp_strtotime( $string ) {
526
+ // If there's a timezone specified, we shouldn't convert it
527
+ try {
528
+ $test_date = new DateTime( $string );
529
+ if ( 'UTC' != $test_date->getTimezone()->getName() ) {
530
+ return strtotime( $string );
531
+ }
532
+ } catch ( Exception $e ) {
533
+ return strtotime( $string );
534
+ }
535
+
536
+ $tz = get_option( 'timezone_string' );
537
+ if ( ! empty( $tz ) ) {
538
+ $date = date_create( $string, new DateTimeZone( $tz ) );
539
+ if ( ! $date ) {
540
+ return strtotime( $string );
541
+ }
542
+ $date->setTimezone( new DateTimeZone( 'UTC' ) );
543
+ return $date->format( 'U' );
544
+ } else {
545
+ $offset = (float) get_option( 'gmt_offset' );
546
+ $seconds = intval( $offset * HOUR_IN_SECONDS );
547
+ $timestamp = strtotime( $string ) - $seconds;
548
+ return $timestamp;
549
+ }
550
+ }
551
+
552
+ // DEPRECATED METHODS
553
+ // @codingStandardsIgnoreStart
554
+ /**
555
+ * Deprecated camelCase version of self::date_only
556
+ *
557
+ * @param int|string $date The date (timestamp or string).
558
+ * @param bool $isTimestamp Is $date in timestamp format?
559
+ *
560
+ * @return string The date only in DB format.
561
+ */
562
+ public static function dateOnly( $date, $isTimestamp = false ) {
563
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::date_only' );
564
+ return self::date_only( $date, $isTimestamp );
565
+ }
566
+
567
+ /**
568
+ * Deprecated camelCase version of self::time_only
569
+ *
570
+ * @param string $date The date.
571
+ *
572
+ * @return string The time only in DB format.
573
+ */
574
+ public static function timeOnly( $date ) {
575
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::time_only' );
576
+ return self::time_only( $date );
577
+ }
578
+
579
+ /**
580
+ * Deprecated camelCase version of self::hour_only
581
+ *
582
+ * @param string $date The date.
583
+ *
584
+ * @return string The hour only.
585
+ */
586
+ public static function hourOnly( $date ) {
587
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::hour_only' );
588
+ return self::hour_only( $date );
589
+ }
590
+
591
+ /**
592
+ * Deprecated camelCase version of self::minutes_only
593
+ *
594
+ * @param string $date The date.
595
+ *
596
+ * @return string The minute only.
597
+ */
598
+ public static function minutesOnly( $date ) {
599
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::minutes_only' );
600
+ return self::minutes_only( $date );
601
+ }
602
+
603
+ /**
604
+ * Deprecated camelCase version of self::meridian_only
605
+ *
606
+ * @param string $date The date.
607
+ *
608
+ * @return string The meridian only in DB format.
609
+ */
610
+ public static function meridianOnly( $date ) {
611
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::meridian_only' );
612
+ return self::meridian_only( $date );
613
+ }
614
+
615
+ /**
616
+ * Returns the end of a given day.
617
+ *
618
+ * @deprecated since 3.10 - use tribe_event_end_of_day()
619
+ * @todo remove in 4.1
620
+ *
621
+ * @param int|string $date The date (timestamp or string).
622
+ * @param bool $isTimestamp Is $date in timestamp format?
623
+ *
624
+ * @return string The date and time of the end of a given day
625
+ */
626
+ public static function endOfDay( $date, $isTimestamp = false ) {
627
+ _deprecated_function( __METHOD__, '3.10', 'tribe_event_end_of_day' );
628
+
629
+ if ( $isTimestamp ) {
630
+ $date = date( self::DBDATEFORMAT, $date );
631
+ }
632
+
633
+ return tribe_event_end_of_day( $date, self::DBDATETIMEFORMAT );
634
+ }
635
+
636
+ /**
637
+ * Returns the beginning of a given day.
638
+ *
639
+ * @deprecated since 3.10
640
+ * @todo remove in 4.1
641
+ *
642
+ * @param int|string $date The date (timestamp or string).
643
+ * @param bool $isTimestamp Is $date in timestamp format?
644
+ *
645
+ * @return string The date and time of the beginning of a given day.
646
+ */
647
+ public static function beginningOfDay( $date, $isTimestamp = false ) {
648
+ _deprecated_function( __METHOD__, '3.10', 'tribe_event_beginning_of_day' );
649
+
650
+ if ( $isTimestamp ) {
651
+ $date = date( self::DBDATEFORMAT, $date );
652
+ }
653
+
654
+ return tribe_event_beginning_of_day( $date, self::DBDATETIMEFORMAT );
655
+ }
656
+
657
+ /**
658
+ * Deprecated camelCase version of self::time_between
659
+ *
660
+ * @param string $date1 The first date.
661
+ * @param string $date2 The second date.
662
+ *
663
+ * @return int The number of seconds between the dates.
664
+ */
665
+ public static function timeBetween( $date1, $date2 ) {
666
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::time_between' );
667
+ return self::time_between( $date1, $date2 );
668
+ }
669
+
670
+ /**
671
+ * Deprecated camelCase version of self::date_diff
672
+ *
673
+ * @param string $date1 The first date.
674
+ * @param string $date2 The second date.
675
+ *
676
+ * @return int The number of days between two dates.
677
+ */
678
+ public static function dateDiff( $date1, $date2 ) {
679
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::date_diff' );
680
+ return self::date_diff( $date1, $date2 );
681
+ }
682
+
683
+ /**
684
+ * Deprecated camelCase version of self::get_last_day_of_month
685
+ *
686
+ * @param int $timestamp THe timestamp.
687
+ *
688
+ * @return string The last day of the month.
689
+ */
690
+ public static function getLastDayOfMonth( $timestamp ) {
691
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::get_last_day_of_month' );
692
+ return self::get_last_day_of_month( $timestamp );
693
+ }
694
+
695
+ /**
696
+ * Deprecated camelCase version of self::is_weekday
697
+ *
698
+ * @param int $curDate A timestamp.
699
+ *
700
+ * @return bool If the timestamp is a weekday.
701
+ */
702
+ public static function isWeekday( $curdate ) {
703
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_weekday' );
704
+ return self::is_weekday( $curdate );
705
+ }
706
+
707
+ /**
708
+ * Deprecated camelCase version of self::is_weekend
709
+ *
710
+ * @param int $curDate A timestamp.
711
+ *
712
+ * @return bool If the timestamp is a weekend.
713
+ */
714
+ public static function isWeekend( $curdate ) {
715
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_weekend' );
716
+ return self::is_weekend( $curdate );
717
+ }
718
+
719
+ /**
720
+ * Deprecated camelCase version of self::get_last_day_of_week_in_month
721
+ *
722
+ * @param int $curdate A timestamp.
723
+ * @param int $day_of_week The index of the day of the week.
724
+ *
725
+ * @return int The timestamp of the date that fits the qualifications.
726
+ */
727
+ public static function getLastDayOfWeekInMonth( $curdate, $day_of_week ) {
728
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::get_last_day_of_week_in_month' );
729
+ return self::get_last_day_of_week_in_month( $curdate, $day_of_week );
730
+ }
731
+
732
+ /**
733
+ * Deprecated camelCase version of self::get_first_day_of_week_in_month
734
+ *
735
+ * @param int $curdate A timestamp.
736
+ * @param int $day_of_week The index of the day of the week.
737
+ *
738
+ * @return int The timestamp of the date that fits the qualifications.
739
+ */
740
+ public static function getFirstDayOfWeekInMonth( $curdate, $day_of_week ) {
741
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::get_fist_day_of_week_in_month' );
742
+ return self::get_first_day_of_week_in_month( $curdate, $day_of_week );
743
+ }
744
+
745
+ /**
746
+ * Deprecated camelCase version of self::number_to_ordinal
747
+ *
748
+ * @param int $number A number.
749
+ *
750
+ * @return string The ordinal for that number.
751
+ */
752
+ public static function numberToOrdinal( $number ) {
753
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::number_to_ordinal' );
754
+ return self::number_to_ordinal( $number );
755
+ }
756
+
757
+ /**
758
+ * Deprecated camelCase version of self::is_timestamp
759
+ *
760
+ * @param $timestamp
761
+ *
762
+ * @return bool
763
+ */
764
+ public static function isTimestamp( $timestamp ) {
765
+ _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_timestamp' );
766
+ return self::is_timestamp( $timestamp );
767
+ }
768
+
769
+ /**
770
+ * Gets the timestamp of a day in week, month and year context.
771
+ *
772
+ * Kudos to [icedwater StackOverflow user](http://stackoverflow.com/users/1091386/icedwater) in
773
+ * [his answer](http://stackoverflow.com/questions/924246/get-the-first-or-last-friday-in-a-month).
774
+ *
775
+ * Usage examples:
776
+ * "The second Wednesday of March 2015" - `get_day_timestamp( 3, 2, 3, 2015, 1)`
777
+ * "The last Friday of December 2015" - `get_day_timestamp( 5, 1, 12, 2015, -1)`
778
+ * "The first Monday of April 2016 - `get_day_timestamp( 1, 1, 4, 2016, 1)`
779
+ * "The penultimate Thursday of January 2012" - `get_day_timestamp( 4, 2, 1, 2012, -1)`
780
+ *
781
+ * @param int $day_of_week The day representing the number in the week, Monday is `1`, Tuesday is `2`, Sunday is `7`
782
+ * @param int $week_in_month The week number in the month; first week is `1`, second week is `2`; when direction is reverse
783
+ * then `1` is last week of the month, `2` is penultimate week of the month and so on.
784
+ * @param int $month The month number in the year, January is `1`
785
+ * @param int $year The year number, e.g. "2015"
786
+ * @param int $week_direction Either `1` or `-1`; the direction for the search referring to the week, defaults to `1`
787
+ * to specify weeks in natural order so:
788
+ * $week_direction `1` and $week_in_month `1` means "first week of the month"
789
+ * $week_direction `1` and $week_in_month `3` means "third week of the month"
790
+ * $week_direction `-1` and $week_in_month `1` means "last week of the month"
791
+ * $week_direction `-1` and $week_in_month `2` means "penultimmate week of the month"
792
+ *
793
+ * @return int The day timestamp
794
+ */
795
+ public static function get_weekday_timestamp( $day_of_week, $week_in_month, $month, $year, $week_direction = 1 ) {
796
+ if (
797
+ ! (
798
+ is_numeric( $day_of_week )
799
+ && is_numeric( $week_in_month )
800
+ && is_numeric( $month )
801
+ && is_numeric( $year )
802
+ && is_numeric( $week_direction )
803
+ && in_array( $week_direction, array( - 1, 1 ) )
804
+ )
805
+ ) {
806
+ return false;
807
+ }
808
+
809
+ if ( $week_direction > 0 ) {
810
+ $startday = 1;
811
+ } else {
812
+ $startday = date( 't', mktime( 0, 0, 0, $month, 1, $year ) );
813
+ }
814
+
815
+ $start = mktime( 0, 0, 0, $month, $startday, $year );
816
+ $weekday = date( 'N', $start );
817
+
818
+ if ( $week_direction * $day_of_week >= $week_direction * $weekday ) {
819
+ $offset = - $week_direction * 7;
820
+ } else {
821
+ $offset = 0;
822
+ }
823
+
824
+ $offset += $week_direction * ( $week_in_month * 7 ) + ( $day_of_week - $weekday );
825
+
826
+ return mktime( 0, 0, 0, $month, $startday + $offset, $year );
827
+ }
828
+
829
+ /**
830
+ * Unescapes date format strings to be used in functions like `date`.
831
+ *
832
+ * Double escaping happens when storing a date format in the database.
833
+ *
834
+ * @param mixed $date_format A date format string.
835
+ *
836
+ * @return mixed Either the original input or an unescaped date format string.
837
+ */
838
+ public static function unescape_date_format( $date_format ) {
839
+ if ( ! is_string( $date_format ) ) {
840
+ return $date_format;
841
+ }
842
+
843
+ // Why so simple? Let's handle other cases as those come up. We have tests in place!
844
+ return str_replace( '\\\\', '\\', $date_format );
845
+ }
846
+ // @codingStandardsIgnoreEnd
847
+ }
848
+
849
+ }
common/src/Tribe/Debug.php CHANGED
@@ -1,59 +1,59 @@
1
- <?php
2
-
3
- class Tribe__Debug {
4
- /**
5
- * constructor
6
- */
7
- public function __construct() {
8
- add_action( 'tribe_debug', array( __CLASS__, 'render' ), 10, 2 );
9
- }
10
-
11
- /**
12
- * Tribe debug function. usage: self::debug( 'Message', $data, 'log' );
13
- *
14
- * @param string $title Message to display in log
15
- * @param string|bool $data Optional data to display
16
- * @param string $format Optional format (log|warning|error|notice)
17
- *
18
- * @return void
19
- */
20
- public static function debug( $title, $data = false, $format = 'log' ) {
21
- do_action( 'tribe_debug', $title, $data, $format );
22
- }
23
-
24
- /**
25
- * Render the debug logging to the php error log. This can be over-ridden by removing the filter.
26
- *
27
- * @param string $title - message to display in log
28
- * @param string|bool $data - optional data to display
29
- * @param string $format - optional format (log|warning|error|notice)
30
- *
31
- * @return void
32
- */
33
- public static function render( $title, $data = false, $format = 'log' ) {
34
- $format = ucfirst( $format );
35
- if ( Tribe__Settings_Manager::instance()->get_option( 'debugEvents' ) ) {
36
- $plugin = basename( dirname( Tribe__Main::instance()->plugin_path ) );
37
- error_log( "$plugin/common - $format: $title" );
38
- if ( $data && $data != '' ) {
39
- error_log( "$plugin/common - $format: " . print_r( $data, true ) );
40
- }
41
- }
42
- }
43
-
44
- /**
45
- * Static Singleton Factory Method
46
- *
47
- * @return Tribe__Debug
48
- */
49
- public static function instance() {
50
- static $instance;
51
-
52
- if ( ! $instance ) {
53
- $class_name = __CLASS__;
54
- $instance = new $class_name;
55
- }
56
-
57
- return $instance;
58
- }
59
- }
1
+ <?php
2
+
3
+ class Tribe__Debug {
4
+ /**
5
+ * constructor
6
+ */
7
+ public function __construct() {
8
+ add_action( 'tribe_debug', array( __CLASS__, 'render' ), 10, 2 );
9
+ }
10
+
11
+ /**
12
+ * Tribe debug function. usage: self::debug( 'Message', $data, 'log' );
13
+ *
14
+ * @param string $title Message to display in log
15
+ * @param string|bool $data Optional data to display
16
+ * @param string $format Optional format (log|warning|error|notice)
17
+ *
18
+ * @return void
19
+ */
20
+ public static function debug( $title, $data = false, $format = 'log' ) {
21
+ do_action( 'tribe_debug', $title, $data, $format );
22
+ }
23
+
24
+ /**
25
+ * Render the debug logging to the php error log. This can be over-ridden by removing the filter.
26
+ *
27
+ * @param string $title - message to display in log
28
+ * @param string|bool $data - optional data to display
29
+ * @param string $format - optional format (log|warning|error|notice)
30
+ *
31
+ * @return void
32
+ */
33
+ public static function render( $title, $data = false, $format = 'log' ) {
34
+ $format = ucfirst( $format );
35
+ if ( Tribe__Settings_Manager::instance()->get_option( 'debugEvents' ) ) {
36
+ $plugin = basename( dirname( Tribe__Main::instance()->plugin_path ) );
37
+ error_log( "$plugin/common - $format: $title" );
38
+ if ( $data && $data != '' ) {
39
+ error_log( "$plugin/common - $format: " . print_r( $data, true ) );
40
+ }
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Static Singleton Factory Method
46
+ *
47
+ * @return Tribe__Debug
48
+ */
49
+ public static function instance() {
50
+ static $instance;
51
+
52
+ if ( ! $instance ) {
53
+ $class_name = __CLASS__;
54
+ $instance = new $class_name;
55
+ }
56
+
57
+ return $instance;
58
+ }
59
+ }
common/src/Tribe/Dependency.php ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Don't load directly
3
+ defined( 'WPINC' ) or die;
4
+
5
+ if ( ! class_exists( 'Tribe__Dependency' ) ) {
6
+ /**
7
+ * Tracks which tribe plugins are currently activated
8
+ */
9
+ class Tribe__Dependency {
10
+
11
+ /**
12
+ * An multidimensional array of active tribe plugins in the following format
13
+ *
14
+ * array(
15
+ * 'class' => 'main class name',
16
+ * 'version' => 'version num', (optional)
17
+ * 'path' => 'Path to the main plugin/bootstrap file' (optional)
18
+ * )
19
+ */
20
+ protected $active_plugins = array();
21
+
22
+ /**
23
+ * Static Singleton Holder
24
+ *
25
+ * @var self
26
+ */
27
+ private static $instance;
28
+
29
+
30
+ /**
31
+ * Static Singleton Factory Method
32
+ *
33
+ * @return self
34
+ */
35
+ public static function instance() {
36
+ if ( ! self::$instance ) {
37
+ self::$instance = new self;
38
+ }
39
+ return self::$instance;
40
+ }
41
+
42
+
43
+ public function __construct() {
44
+ $this->add_legacy_plugins();
45
+ }
46
+
47
+
48
+ /**
49
+ * Registers older plugins that did not use this class
50
+ *
51
+ * @TODO Consider removing this in 5.0
52
+ */
53
+ private function add_legacy_plugins() {
54
+ // Version 4.2 and under of the plugins do not register themselves here, so we'll register them
55
+
56
+ $tribe_plugins = new Tribe__Plugins();
57
+
58
+ foreach ( $tribe_plugins->get_list() as $plugin ) {
59
+ if ( ! class_exists( $plugin['class'] ) ) {
60
+ continue;
61
+ }
62
+
63
+ $ver_const = $plugin['class'] . '::VERSION';
64
+ $version = defined( $ver_const ) ? constant( $ver_const ) : null;
65
+
66
+ $this->add_active_plugin( $plugin['class'], $version );
67
+ }
68
+ }
69
+
70
+
71
+ /**
72
+ * Retrieves active plugin array
73
+ *
74
+ * @return array
75
+ */
76
+ public function get_active_plugins() {
77
+ return $this->active_plugins;
78
+ }
79
+
80
+
81
+ /**
82
+ * Adds a plugin to the active list
83
+ *
84
+ * @param string $main_class Main/base class for this plugin
85
+ * @param string $version Version number of plugin
86
+ * @param string $path Path to the main plugin/bootstrap file
87
+ */
88
+ public function add_active_plugin( $main_class, $version = null, $path = null ) {
89
+
90
+ $plugin = array(
91
+ 'class' => $main_class,
92
+ 'version' => $version,
93
+ 'path' => $path,
94
+ );
95
+
96
+ $this->active_plugins[ $main_class ] = $plugin;
97
+ }
98
+
99
+
100
+ /**
101
+ * Searches the plugin list for key/value pair and return the full details for that plugin
102
+ *
103
+ * @param string $search_key The array key this value will appear in
104
+ * @param string $search_val The value itself
105
+ *
106
+ * @return array|null
107
+ */
108
+ public function get_plugin_by_key( $search_key, $search_val ) {
109
+ foreach ( $this->active_plugins as $plugin ) {
110
+ if ( isset( $plugin[ $search_key ] ) && $plugin[ $search_key ] === $search_val ) {
111
+ return $plugin;
112
+ }
113
+ }
114
+
115
+ return null;
116
+ }
117
+
118
+
119
+ /**
120
+ * Retrieves the plugins details by class name
121
+ *
122
+ * @param string $main_class Main/base class for this plugin
123
+ *
124
+ * @return array|null
125
+ */
126
+ public function get_plugin_by_class( $main_class ) {
127
+ return $this->get_plugin_by_key( 'class', $main_class );
128
+ }
129
+
130
+
131
+ /**
132
+ * Retrieves the version of the plugin
133
+ *
134
+ * @param string $main_class Main/base class for this plugin
135
+ *
136
+ * @return string|null Version
137
+ */
138
+ public function get_plugin_version( $main_class ) {
139
+ $plugin = $this->get_plugin_by_class( $main_class );
140
+
141
+ return ( isset( $plugin['version'] ) ? $plugin['version'] : null );
142
+ }
143
+
144
+
145
+ /**
146
+ * Checks if the plugin is active
147
+ *
148
+ * @param string $main_class Main/base class for this plugin
149
+ *
150
+ * @return bool
151
+ */
152
+ public function is_plugin_active( $main_class ) {
153
+ return ( $this->get_plugin_by_class( $main_class ) !== null );
154
+ }
155
+
156
+
157
+ /**
158
+ * Checks if a plugin is active and has the specified version
159
+ *
160
+ * @param string $main_class Main/base class for this plugin
161
+ * @param string $version Version to do a compare against
162
+ * @param string $compare Version compare string, defaults to >=
163
+ *
164
+ * @return bool
165
+ */
166
+ public function is_plugin_version( $main_class, $version, $compare = '>=' ) {
167
+
168
+ if ( ! $this->is_plugin_active( $main_class ) ) {
169
+ return false;
170
+ } elseif ( version_compare( $this->get_plugin_version( $main_class ), $version, $compare ) ) {
171
+ return true;
172
+ } elseif ( $this->get_plugin_version( $main_class ) === null ) {
173
+ // If the plugin version is not set default to assuming it's a compatible version
174
+ return true;
175
+ }
176
+
177
+ return false;
178
+ }
179
+
180
+
181
+ /**
182
+ * Checks if each plugin is active and exceeds the specified version number
183
+ *
184
+ * @param array $plugins_required Each item is a 'class_name' => 'min version' pair. Min ver can be null.
185
+ *
186
+ * @return bool
187
+ */
188
+ public function has_requisite_plugins( $plugins_required = array() ) {
189
+
190
+ foreach ( $plugins_required as $class => $version ) {
191
+ // Return false if the plugin is not set or is a lesser version
192
+ if ( ! $this->is_plugin_active( $class ) ) {
193
+ return false;
194
+ }
195
+
196
+ if ( null !== $version && ! $this->is_plugin_version( $class, $version ) ) {
197
+ return false;
198
+ }
199
+ }
200
+
201
+ return true;
202
+ }
203
+
204
+ }
205
+
206
+ }
common/src/Tribe/Exception.php CHANGED
@@ -1,90 +1,90 @@
1
- <?php
2
-
3
-
4
- /**
5
- * Class Tribe__Exception
6
- *
7
- * Handles exceptions to log when not in debug mode.
8
- */
9
- class Tribe__Exception extends Exception {
10
-
11
- /**
12
- * @var Exception
13
- */
14
- private $original_exception;
15
-
16
- /**
17
- * Tribe__Exception constructor.
18
- *
19
- * @param Exception $original_exception
20
- */
21
- public function __construct( Exception $original_exception ) {
22
- $this->original_exception = $original_exception;
23
- }
24
-
25
- /**
26
- * Handles the exception throwing the original when debugging (`WP_DEBUG` defined and `true`)
27
- * or quietly logging when `WP_DEBUG` is `false` or not set.
28
- *
29
- * @return bool `true` if the message was logged, `false` otherwise.
30
- *
31
- * @throws Exception
32
- */
33
- public function handle() {
34
- $debug = defined( 'WP_DEBUG' ) && WP_DEBUG;
35
-
36
- if ( $debug ) {
37
- $this->throw_original_exception();
38
- }
39
-
40
- return $this->log_original_exception_message();
41
- }
42
-
43
- /**
44
- * @return string
45
- */
46
- private function get_log_type_for_exception_code( $code ) {
47
- $map = array(
48
- // @todo: let's add a decent exception code to log type map here
49
- );
50
-
51
- return isset( $map[ $code ] ) ? $map[ $code ] : Tribe__Log::ERROR;
52
- }
53
-
54
- /**
55
- * Throws the original exception.
56
- *
57
- * Provided as a manual override over the default `WP_DEBUG` dependent behaviour.
58
- *
59
- * @see Tribe__Exception::handle()
60
- *
61
- * @throws Exception
62
- */
63
- public function throw_original_exception() {
64
- throw $this->original_exception;
65
- }
66
-
67
- /**
68
- * Logs the original exception message.
69
- *
70
- * Provided as a manual override over the default `WP_DEBUG` dependent behaviour.
71
- *
72
- * @see Tribe__Exception::handle()
73
- *
74
- * @return bool `true` if the message was logged, `false` otherwise.
75
- */
76
- private function log_original_exception_message() {
77
- if ( ! class_exists( 'Tribe__Log' ) ) {
78
- return false;
79
- }
80
-
81
- $logger = new Tribe__Log();
82
- $message = $this->original_exception->getMessage();
83
- $log_type = $this->get_log_type_for_exception_code( $this->original_exception->getCode() );
84
- $src = $this->original_exception->getFile() . ':' . $this->original_exception->getLine();
85
-
86
- $logger->log( $message, $log_type, $src );
87
-
88
- return true;
89
- }
90
  }
1
+ <?php
2
+
3
+
4
+ /**
5
+ * Class Tribe__Exception
6
+ *
7
+ * Handles exceptions to log when not in debug mode.
8
+ */
9
+ class Tribe__Exception extends Exception {
10
+
11
+ /**
12
+ * @var Exception
13
+ */
14
+ private $original_exception;
15
+
16
+ /**
17
+ * Tribe__Exception constructor.
18
+ *
19
+ * @param Exception $original_exception
20
+ */
21
+ public function __construct( Exception $original_exception ) {
22
+ $this->original_exception = $original_exception;
23
+ }
24
+
25
+ /**
26
+ * Handles the exception throwing the original when debugging (`WP_DEBUG` defined and `true`)
27
+ * or quietly logging when `WP_DEBUG` is `false` or not set.
28
+ *
29
+ * @return bool `true` if the message was logged, `false` otherwise.
30
+ *
31
+ * @throws Exception
32
+ */
33
+ public function handle() {
34
+ $debug = defined( 'WP_DEBUG' ) && WP_DEBUG;
35
+
36
+ if ( $debug ) {
37
+ $this->throw_original_exception();
38
+ }
39
+
40
+ return $this->log_original_exception_message();
41
+ }
42
+
43
+ /**
44
+ * @return string
45
+ */
46
+ private function get_log_type_for_exception_code( $code ) {
47
+ $map = array(
48
+ // @todo: let's add a decent exception code to log type map here
49
+ );
50
+
51
+ return isset( $map[ $code ] ) ? $map[ $code ] : Tribe__Log::ERROR;
52
+ }
53
+
54
+ /**
55
+ * Throws the original exception.
56
+ *
57
+ * Provided as a manual override over the default `WP_DEBUG` dependent behaviour.
58
+ *
59
+ * @see Tribe__Exception::handle()
60
+ *
61
+ * @throws Exception
62
+ */
63
+ public function throw_original_exception() {
64
+ throw $this->original_exception;
65
+ }
66
+
67
+ /**
68
+ * Logs the original exception message.
69
+ *
70
+ * Provided as a manual override over the default `WP_DEBUG` dependent behaviour.
71
+ *
72
+ * @see Tribe__Exception::handle()
73
+ *
74
+ * @return bool `true` if the message was logged, `false` otherwise.
75
+ */
76
+ private function log_original_exception_message() {
77
+ if ( ! class_exists( 'Tribe__Log' ) ) {
78
+ return false;
79
+ }
80
+
81
+ $logger = new Tribe__Log();
82
+ $message = $this->original_exception->getMessage();
83
+ $log_type = $this->get_log_type_for_exception_code( $this->original_exception->getCode() );
84
+ $src = $this->original_exception->getFile() . ':' . $this->original_exception->getLine();
85
+
86
+ $logger->log( $message, $log_type, $src );
87
+
88
+ return true;
89
+ }
90
  }
common/src/Tribe/Field.php CHANGED
@@ -1,616 +1,616 @@
1
- <?php
2
-
3
- // Don't load directly
4
- if ( ! defined( 'ABSPATH' ) ) {
5
- die( '-1' );
6
- }
7
-
8
- if ( ! class_exists( 'Tribe__Field' ) ) {
9
- /**
10
- * helper class that creates fields for use in Settings, MetaBoxes, Users, anywhere.
11
- * Instantiate it whenever you need a field
12
- *
13
- */
14
- class Tribe__Field {
15
-
16
- /**
17
- * the field's id
18
- * @var string
19
- */
20
- public $id;
21
-
22
- /**
23
- * the field's name (also known as it's label)
24
- * @var string
25
- */
26
- public $name;
27
-
28
- /**
29
- * the field's attributes
30
- * @var array
31
- */
32
- public $attributes;
33
-
34
- /**
35
- * the field's arguments
36
- * @var array
37
- */
38
- public $args;
39
-
40
- /**
41
- * field defaults (static)
42
- * @var array
43
- */
44
- public $defaults;
45
-
46
- /**
47
- * valid field types (static)
48
- * @var array
49
- */
50
- public $valid_field_types;
51
-
52
-
53
- /**
54
- * Class constructor
55
- *
56
- * @param string $id the field id
57
- * @param array $field the field settings
58
- * @param null|mixed $value the field's current value
59
- *
60
- * @return void
61
- */
62
- public function __construct( $id, $field, $value = null ) {
63
-
64
- // setup the defaults
65
- $this->defaults = array(
66
- 'type' => 'html',
67
- 'name' => $id,
68
- 'attributes' => array(),
69
- 'class' => null,
70
- 'label' => null,
71
- 'tooltip' => null,
72
- 'size' => 'medium',
73
- 'html' => null,
74
- 'error' => false,
75
- 'value' => $value,
76
- 'options' => null,
77
- 'conditional' => true,
78
- 'display_callback' => null,
79
- 'if_empty' => null,
80
- 'can_be_empty' => false,
81
- 'clear_after' => true,
82
- );
83
-
84
- // a list of valid field types, to prevent screwy behaviour
85
- $this->valid_field_types = array(
86
- 'heading',
87
- 'html',
88
- 'text',
89
- 'textarea',
90
- 'wysiwyg',
91
- 'radio',
92
- 'checkbox_bool',
93
- 'checkbox_list',
94
- 'dropdown',
95
- 'dropdown_chosen',
96
- 'dropdown_select2',
97
- 'license_key',
98
- );
99
-
100
- $this->valid_field_types = apply_filters( 'tribe_valid_field_types', $this->valid_field_types );
101
-
102
- // parse args with defaults and extract them
103
- $args = wp_parse_args( $field, $this->defaults );
104
-
105
- // sanitize the values just to be safe
106
- $id = esc_attr( $id );
107
- $type = esc_attr( $args['type'] );
108
- $name = esc_attr( $args['name'] );
109
- $class = sanitize_html_class( $args['class'] );
110
- $label = wp_kses(
111
- $args['label'], array(
112
- 'a' => array( 'href' => array(), 'title' => array() ),
113
- 'br' => array(),
114
- 'em' => array(),
115
- 'strong' => array(),
116
- 'b' => array(),
117
- 'i' => array(),
118
- 'u' => array(),
119
- 'img' => array(
120
- 'title' => array(),
121
- 'src' => array(),
122
- 'alt' => array(),
123
- ),
124
- )
125
- );
126
- $tooltip = wp_kses(
127
- $args['tooltip'], array(
128
- 'a' => array( 'href' => array(), 'title' => array(), 'target' => array() ),
129
- 'br' => array(),
130
- 'em' => array(),
131
- 'strong' => array(),
132
- 'b' => array(),
133
- 'i' => array(),
134
- 'u' => array(),
135
- 'img' => array(
136
- 'title' => array(),
137
- 'src' => array(),
138
- 'alt' => array(),
139
- ),
140
- 'code' => array( 'span' => array() ),
141
- 'span' => array(),
142
- )
143
- );
144
- $attributes = $args['attributes'];
145
- if ( is_array( $attributes ) ) {
146
- foreach ( $attributes as $key => &$val ) {
147
- $val = esc_attr( $val );
148
- }
149
- }
150
- if ( is_array( $args['options'] ) ) {
151
- $options = array();
152
- foreach ( $args['options'] as $key => $val ) {
153
- $options[ $key ] = $val;
154
- }
155
- } else {
156
- $options = $args['options'];
157
- }
158
- $size = esc_attr( $args['size'] );
159
- $html = $args['html'];
160
- $error = (bool) $args['error'];
161
- $value = is_array( $value ) ? array_map( 'esc_attr', $value ) : esc_attr( $value );
162
- $conditional = $args['conditional'];
163
- $display_callback = $args['display_callback'];
164
- $if_empty = is_string( $args['if_empty'] ) ? trim( $args['if_empty'] ) : $args['if_empty'];
165
- $can_be_empty = (bool) $args['can_be_empty'];
166
- $clear_after = (bool) $args['clear_after'];
167
-
168
- // set the ID
169
- $this->id = apply_filters( 'tribe_field_id', $id );
170
-
171
- // set each instance variable and filter
172
- foreach ( $this->defaults as $key => $value ) {
173
- $this->{$key} = apply_filters( 'tribe_field_' . $key, $$key, $this->id );
174
- }
175
-
176
- // epicness
177
- $this->doField();
178
-
179
- }
180
-
181
- /**
182
- * Determines how to handle this field's creation
183
- * either calls a callback function or runs this class' course of action
184
- * logs an error if it fails
185
- *
186
- * @return void
187
- */
188
- public function doField() {
189
-
190
- if ( $this->conditional ) {
191
-
192
- if ( $this->display_callback && is_callable( $this->display_callback ) ) {
193
-
194
- // if there's a callback, run it
195
- call_user_func( $this->display_callback );
196
-
197
- } elseif ( in_array( $this->type, $this->valid_field_types ) ) {
198
-
199
- // the specified type exists, run the appropriate method
200
- $field = call_user_func( array( $this, $this->type ) );
201
-
202
- // filter the output
203
- $field = apply_filters( 'tribe_field_output_' . $this->type, $field, $this->id, $this );
204
- echo apply_filters( 'tribe_field_output_' . $this->type . '_' . $this->id, $field, $this->id, $this );
205
-
206
- } else {
207
-
208
- // fail, log the error
209
- Tribe__Main::debug( esc_html__( 'Invalid field type specified', 'tribe-common' ), $this->type, 'notice' );
210
-
211
- }
212
- }
213
- }
214
-
215
- /**
216
- * returns the field's start
217
- *
218
- * @return string the field start
219
- */
220
- public function doFieldStart() {
221
- $return = '<fieldset id="tribe-field-' . $this->id . '"';
222
- $return .= ' class="tribe-field tribe-field-' . $this->type;
223
- $return .= ( $this->error ) ? ' tribe-error' : '';
224
- $return .= ( $this->size ) ? ' tribe-size-' . $this->size : '';
225
- $return .= ( $this->class ) ? ' ' . $this->class . '"' : '"';
226
- $return .= '>';
227
-
228
- return apply_filters( 'tribe_field_start', $return, $this->id, $this->type, $this->error, $this->class, $this );
229
- }
230
-
231
- /**
232
- * returns the field's end
233
- *
234
- * @return string the field end
235
- */
236
- public function doFieldEnd() {
237
- $return = '</fieldset>';
238
- $return .= ( $this->clear_after ) ? '<div class="clear"></div>' : '';
239
-
240
- return apply_filters( 'tribe_field_end', $return, $this->id, $this );
241
- }
242
-
243
- /**
244
- * returns the field's label
245
- *
246
- * @return string the field label
247
- */
248
- public function doFieldLabel() {
249
- $return = '';
250
- if ( $this->label ) {
251
- $return = '<legend class="tribe-field-label">' . $this->label . '</legend>';
252
- }
253
-
254
- return apply_filters( 'tribe_field_label', $return, $this->label, $this );
255
- }
256
-
257
- /**
258
- * returns the field's div start
259
- *
260
- * @return string the field div start
261
- */
262
- public function doFieldDivStart() {
263
- $return = '<div class="tribe-field-wrap">';
264
-
265
- return apply_filters( 'tribe_field_div_start', $return, $this );
266
- }
267
-
268
- /**
269
- * returns the field's div end
270
- *
271
- * @return string the field div end
272
- */
273
- public function doFieldDivEnd() {
274
- $return = $this->doToolTip();
275
- $return .= '</div>';
276
-
277
- return apply_filters( 'tribe_field_div_end', $return, $this );
278
- }
279
-
280
- /**
281
- * returns the field's tooltip/description
282
- *
283
- * @return string the field tooltip
284
- */
285
- public function doToolTip() {
286
- $return = '';
287
- if ( $this->tooltip ) {
288
- $return = '<p class="tooltip description">' . $this->tooltip . '</p>';
289
- }
290
-
291
- return apply_filters( 'tribe_field_tooltip', $return, $this->tooltip, $this );
292
- }
293
-
294
- /**
295
- * returns the screen reader label
296
- *
297
- * @return string the screen reader label
298
- */
299
- public function doScreenReaderLabel() {
300
- $return = '';
301
- if ( $this->tooltip ) {
302
- $return = '<label class="screen-reader-text">' . $this->tooltip . '</label>';
303
- }
304
-
305
- return apply_filters( 'tribe_field_screen_reader_label', $return, $this->tooltip, $this );
306
- }
307
-
308
- /**
309
- * returns the field's value
310
- *
311
- * @return string the field value
312
- */
313
- public function doFieldValue() {
314
- $return = '';
315
- if ( $this->value ) {
316
- $return = ' value="' . $this->value . '"';
317
- }
318
-
319
- return apply_filters( 'tribe_field_value', $return, $this->value, $this );
320
- }
321
-
322
- /**
323
- * returns the field's name
324
- *
325
- * @param bool $multi
326
- *
327
- * @return string the field name
328
- */
329
- public function doFieldName( $multi = false ) {
330
- $return = '';
331
- if ( $this->name ) {
332
- if ( $multi ) {
333
- $return = ' name="' . $this->name . '[]"';
334
- } else {
335
- $return = ' name="' . $this->name . '"';
336
- }
337
- }
338
-
339
- return apply_filters( 'tribe_field_name', $return, $this->name, $this );
340
- }
341
-
342
- /**
343
- * Return a string of attributes for the field
344
- *
345
- * @return string
346
- **/
347
- public function doFieldAttributes() {
348
- $return = '';
349
- if ( ! empty( $this->attributes ) ) {
350
- foreach ( $this->attributes as $key => $value ) {
351
- $return .= ' ' . $key . '="' . $value . '"';
352
- }
353
- }
354
-
355
- return apply_filters( 'tribe_field_attributes', $return, $this->name, $this );
356
- }
357
-
358
- /**
359
- * generate a heading field
360
- *
361
- * @return string the field
362
- */
363
- public function heading() {
364
- $field = '<h3>' . $this->label . '</h3>';
365
-
366
- return $field;
367
- }
368
-
369
- /**
370
- * generate an html field
371
- *
372
- * @return string the field
373
- */
374
- public function html() {
375
- $field = $this->doFieldLabel();
376
- $field .= $this->html;
377
-
378
- return $field;
379
- }
380
-
381
- /**
382
- * generate a simple text field
383
- *
384
- * @return string the field
385
- */
386
- public function text() {
387
- $field = $this->doFieldStart();
388
- $field .= $this->doFieldLabel();
389
- $field .= $this->doFieldDivStart();
390
- $field .= '<input';
391
- $field .= ' type="text"';
392
- $field .= $this->doFieldName();
393
- $field .= $this->doFieldValue();
394
- $field .= '/>';
395
- $field .= $this->doScreenReaderLabel();
396
- $field .= $this->doFieldDivEnd();
397
- $field .= $this->doFieldEnd();
398
-
399
- return $field;
400
- }
401
-
402
- /**
403
- * generate a textarea field
404
- *
405
- * @return string the field
406
- */
407
- public function textarea() {
408
- $field = $this->doFieldStart();
409
- $field .= $this->doFieldLabel();
410
- $field .= $this->doFieldDivStart();
411
- $field .= '<textarea';
412
- $field .= $this->doFieldName();
413
- $field .= '>';
414
- $field .= esc_html( stripslashes( $this->value ) );
415
- $field .= '</textarea>';
416
- $field .= $this->doScreenReaderLabel();
417
- $field .= $this->doFieldDivEnd();
418
- $field .= $this->doFieldEnd();
419
-
420
- return $field;
421
- }
422
-
423
- /**
424
- * generate a wp_editor field
425
- *
426
- * @return string the field
427
- */
428
- public function wysiwyg() {
429
- $settings = array(
430
- 'teeny' => true,
431
- 'wpautop' => true,
432
- );
433
- ob_start();
434
- wp_editor( html_entity_decode( ( $this->value ) ), $this->name, $settings );
435
- $editor = ob_get_clean();
436
- $field = $this->doFieldStart();
437
- $field .= $this->doFieldLabel();
438
- $field .= $this->doFieldDivStart();
439
- $field .= $editor;
440
- $field .= $this->doScreenReaderLabel();
441
- $field .= $this->doFieldDivEnd();
442
- $field .= $this->doFieldEnd();
443
-
444
- return $field;
445
- }
446
-
447
- /**
448
- * generate a radio button field
449
- *
450
- * @return string the field
451
- */
452
- public function radio() {
453
- $field = $this->doFieldStart();
454
- $field .= $this->doFieldLabel();
455
- $field .= $this->doFieldDivStart();
456
- if ( is_array( $this->options ) ) {
457
- foreach ( $this->options as $option_id => $title ) {
458
- $field .= '<label title="' . esc_attr( strip_tags( $title ) ) . '">';
459
- $field .= '<input type="radio"';
460
- $field .= $this->doFieldName();
461
- $field .= ' value="' . esc_attr( $option_id ) . '" ' . checked( $this->value, $option_id, false ) . '/>';
462
- $field .= $title;
463
- $field .= '</label>';
464
- }
465
- } else {
466
- $field .= '<span class="tribe-error">' . esc_html__( 'No radio options specified', 'tribe-common' ) . '</span>';
467
- }
468
- $field .= $this->doFieldDivEnd();
469
- $field .= $this->doFieldEnd();
470
-
471
- return $field;
472
- }
473
-
474
- /**
475
- * generate a checkbox_list field
476
- *
477
- * @return string the field
478
- */
479
- public function checkbox_list() {
480
- $field = $this->doFieldStart();
481
- $field .= $this->doFieldLabel();
482
- $field .= $this->doFieldDivStart();
483
-
484
- if ( ! is_array( $this->value ) ) {
485
- if ( ! empty( $this->value ) ) {
486
- $this->value = array( $this->value );
487
- } else {
488
- $this->value = array();
489
- }
490
- }
491
-
492
- if ( is_array( $this->options ) ) {
493
- foreach ( $this->options as $option_id => $title ) {
494
- $field .= '<label title="' . esc_attr( $title ) . '">';
495
- $field .= '<input type="checkbox"';
496
- $field .= $this->doFieldName( true );
497
- $field .= ' value="' . esc_attr( $option_id ) . '" ' . checked( in_array( $option_id, $this->value ), true, false ) . '/>';
498
- $field .= $title;
499
- $field .= '</label>';
500
- }
501
- } else {
502
- $field .= '<span class="tribe-error">' . esc_html__( 'No checkbox options specified', 'tribe-common' ) . '</span>';
503
- }
504
- $field .= $this->doFieldDivEnd();
505
- $field .= $this->doFieldEnd();
506
-
507
- return $field;
508
- }
509
-
510
- /**
511
- * generate a boolean checkbox field
512
- *
513
- * @return string the field
514
- */
515
- public function checkbox_bool() {
516
- $field = $this->doFieldStart();
517
- $field .= $this->doFieldLabel();
518
- $field .= $this->doFieldDivStart();
519
- $field .= '<input type="checkbox"';
520
- $field .= $this->doFieldName();
521
- $field .= ' value="1" ' . checked( $this->value, true, false );
522
- $field .= $this->doFieldAttributes();
523
- $field .= '/>';
524
- $field .= $this->doScreenReaderLabel();
525
- $field .= $this->doFieldDivEnd();
526
- $field .= $this->doFieldEnd();
527
-
528
- return $field;
529
- }
530
-
531
- /**
532
- * generate a dropdown field
533
- *
534
- * @return string the field
535
- */
536
- public function dropdown() {
537
- $field = $this->doFieldStart();
538
- $field .= $this->doFieldLabel();
539
- $field .= $this->doFieldDivStart();
540
- if ( is_array( $this->options ) && ! empty( $this->options ) ) {
541
- $field .= '<select';
542
- $field .= $this->doFieldName();
543
- $field .= '>';
544
- foreach ( $this->options as $option_id => $title ) {
545
- $field .= '<option value="' . esc_attr( $option_id ) . '"';
546
- if ( is_array( $this->value ) ) {
547
- $field .= isset( $this->value[0] ) ? selected( $this->value[0], $option_id, false ) : '';
548
- } else {
549
- $field .= selected( $this->value, $option_id, false );
550
- }
551
- $field .= '>' . esc_html( $title ) . '</option>';
552
- }
553
- $field .= '</select>';
554
- $field .= $this->doScreenReaderLabel();
555
- } elseif ( $this->if_empty ) {
556
- $field .= '<span class="empty-field">' . (string) $this->if_empty . '</span>';
557
- } else {
558
- $field .= '<span class="tribe-error">' . esc_html__( 'No select options specified', 'tribe-common' ) . '</span>';
559
- }
560
- $field .= $this->doFieldDivEnd();
561
- $field .= $this->doFieldEnd();
562
-
563
- return $field;
564
- }
565
-
566
- /**
567
- * generate a chosen dropdown field - the same as the
568
- * regular dropdown but wrapped so it can have the
569
- * right css class applied to it
570
- *
571
- * @return string the field
572
- */
573
- public function dropdown_chosen() {
574
- $field = $this->dropdown();
575
-
576
- return $field;
577
- }
578
-
579
- /**
580
- * generate a select2 dropdown field - the same as the
581
- * regular dropdown but wrapped so it can have the
582
- * right css class applied to it
583
- *
584
- * @return string the field
585
- */
586
- public function dropdown_select2() {
587
- $field = $this->dropdown();
588
-
589
- return $field;
590
- }
591
-
592
- /**
593
- * generate a license key field
594
- *
595
- * @return string the field
596
- */
597
- public function license_key() {
598
- $field = $this->doFieldStart();
599
- $field .= $this->doFieldLabel();
600
- $field .= $this->doFieldDivStart();
601
- $field .= '<input';
602
- $field .= ' type="text"';
603
- $field .= $this->doFieldName();
604
- $field .= $this->doFieldValue();
605
- $field .= '/>';
606
- $field .= '<p class="license-test-results"><img src="' . esc_url( admin_url( 'images/wpspin_light.gif' ) ) . '" class="ajax-loading-license" alt="Loading" style="display: none"/>';
607
- $field .= '<span class="key-validity"></span>';
608
- $field .= $this->doScreenReaderLabel();
609
- $field .= $this->doFieldDivEnd();
610
- $field .= $this->doFieldEnd();
611
-
612
- return $field;
613
- }
614
-
615
- } // end class
616
- } // endif class_exists
1
+ <?php
2
+
3
+ // Don't load directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ die( '-1' );
6
+ }
7
+
8
+ if ( ! class_exists( 'Tribe__Field' ) ) {
9
+ /**
10
+ * helper class that creates fields for use in Settings, MetaBoxes, Users, anywhere.
11
+ * Instantiate it whenever you need a field
12
+ *
13
+ */
14
+ class Tribe__Field {
15
+
16
+ /**
17
+ * the field's id
18
+ * @var string
19
+ */
20
+ public $id;
21
+
22
+ /**
23
+ * the field's name (also known as it's label)
24
+ * @var string
25
+ */
26
+ public $name;
27
+
28
+ /**
29
+ * the field's attributes
30
+ * @var array
31
+ */
32
+ public $attributes;
33
+
34
+ /**
35
+ * the field's arguments
36
+ * @var array
37
+ */
38
+ public $args;
39
+
40
+ /**
41
+ * field defaults (static)
42
+ * @var array
43
+ */
44
+ public $defaults;
45
+
46
+ /**
47
+ * valid field types (static)
48
+ * @var array
49
+ */
50
+ public $valid_field_types;
51
+
52
+
53
+ /**
54
+ * Class constructor
55
+ *
56
+ * @param string $id the field id
57
+ * @param array $field the field settings
58
+ * @param null|mixed $value the field's current value
59
+ *
60
+ * @return void
61
+ */
62
+ public function __construct( $id, $field, $value = null ) {
63
+
64
+ // setup the defaults
65
+ $this->defaults = array(
66
+ 'type' => 'html',
67
+ 'name' => $id,
68
+ 'attributes' => array(),
69
+ 'class' => null,
70
+ 'label' => null,
71
+ 'tooltip' => null,
72
+ 'size' => 'medium',
73
+ 'html' => null,
74
+ 'error' => false,
75
+ 'value' => $value,
76
+ 'options' => null,
77
+ 'conditional' => true,
78
+ 'display_callback' => null,
79
+ 'if_empty' => null,
80
+ 'can_be_empty' => false,
81
+ 'clear_after' => true,
82
+ );
83
+
84
+ // a list of valid field types, to prevent screwy behaviour
85
+ $this->valid_field_types = array(
86
+ 'heading',
87
+ 'html',
88
+ 'text',
89
+ 'textarea',
90
+ 'wysiwyg',
91
+ 'radio',
92
+ 'checkbox_bool',
93
+ 'checkbox_list',
94
+ 'dropdown',
95
+ 'dropdown_chosen',
96
+ 'dropdown_select2',
97
+ 'license_key',
98
+ );
99
+
100
+ $this->valid_field_types = apply_filters( 'tribe_valid_field_types', $this->valid_field_types );
101
+
102
+ // parse args with defaults and extract them
103
+ $args = wp_parse_args( $field, $this->defaults );
104
+
105
+ // sanitize the values just to be safe
106
+ $id = esc_attr( $id );
107
+ $type = esc_attr( $args['type'] );
108
+ $name = esc_attr( $args['name'] );
109
+ $class = sanitize_html_class( $args['class'] );
110
+ $label = wp_kses(
111
+ $args['label'], array(
112
+ 'a' => array( 'href' => array(), 'title' => array() ),
113
+ 'br' => array(),
114
+ 'em' => array(),
115
+ 'strong' => array(),
116
+ 'b' => array(),
117
+ 'i' => array(),
118
+ 'u' => array(),
119
+ 'img' => array(
120
+ 'title' => array(),
121
+ 'src' => array(),
122
+ 'alt' => array(),
123
+ ),
124
+ )
125
+ );
126
+ $tooltip = wp_kses(
127
+ $args['tooltip'], array(
128
+ 'a' => array( 'href' => array(), 'title' => array(), 'target' => array() ),
129
+ 'br' => array(),
130
+ 'em' => array(),
131
+ 'strong' => array(),
132
+ 'b' => array(),
133
+ 'i' => array(),
134
+ 'u' => array(),
135
+ 'img' => array(
136
+ 'title' => array(),
137
+ 'src' => array(),
138
+ 'alt' => array(),
139
+ ),
140
+ 'code' => array( 'span' => array() ),
141
+ 'span' => array(),
142
+ )
143
+ );
144
+ $attributes = $args['attributes'];
145
+ if ( is_array( $attributes ) ) {
146
+ foreach ( $attributes as $key => &$val ) {
147
+ $val = esc_attr( $val );
148
+ }
149
+ }
150
+ if ( is_array( $args['options'] ) ) {
151
+ $options = array();
152
+ foreach ( $args['options'] as $key => $val ) {
153
+ $options[ $key ] = $val;
154
+ }
155
+ } else {
156
+ $options = $args['options'];
157
+ }
158
+ $size = esc_attr( $args['size'] );
159
+ $html = $args['html'];
160
+ $error = (bool) $args['error'];
161
+ $value = is_array( $value ) ? array_map( 'esc_attr', $value ) : esc_attr( $value );
162
+ $conditional = $args['conditional'];
163
+ $display_callback = $args['display_callback'];
164
+ $if_empty = is_string( $args['if_empty'] ) ? trim( $args['if_empty'] ) : $args['if_empty'];
165
+ $can_be_empty = (bool) $args['can_be_empty'];
166
+ $clear_after = (bool) $args['clear_after'];
167
+
168
+ // set the ID
169
+ $this->id = apply_filters( 'tribe_field_id', $id );
170
+
171
+ // set each instance variable and filter
172
+ foreach ( $this->defaults as $key => $value ) {
173
+ $this->{$key} = apply_filters( 'tribe_field_' . $key, $$key, $this->id );
174
+ }
175
+
176
+ // epicness
177
+ $this->doField();
178
+
179
+ }
180
+
181
+ /**
182
+ * Determines how to handle this field's creation
183
+ * either calls a callback function or runs this class' course of action
184
+ * logs an error if it fails
185
+ *
186
+ * @return void
187
+ */
188
+ public function doField() {
189
+
190
+ if ( $this->conditional ) {
191
+
192
+ if ( $this->display_callback && is_callable( $this->display_callback ) ) {
193
+
194
+ // if there's a callback, run it
195
+ call_user_func( $this->display_callback );
196
+
197
+ } elseif ( in_array( $this->type, $this->valid_field_types ) ) {
198
+
199
+ // the specified type exists, run the appropriate method
200
+ $field = call_user_func( array( $this, $this->type ) );
201
+
202
+ // filter the output
203
+ $field = apply_filters( 'tribe_field_output_' . $this->type, $field, $this->id, $this );
204
+ echo apply_filters( 'tribe_field_output_' . $this->type . '_' . $this->id, $field, $this->id, $this );
205
+
206
+ } else {
207
+
208
+ // fail, log the error
209
+ Tribe__Main::debug( esc_html__( 'Invalid field type specified', 'tribe-common' ), $this->type, 'notice' );
210
+
211
+ }
212
+ }
213
+ }
214
+
215
+ /**
216
+ * returns the field's start
217
+ *
218
+ * @return string the field start
219
+ */
220
+ public function doFieldStart() {
221
+ $return = '<fieldset id="tribe-field-' . $this->id . '"';
222
+ $return .= ' class="tribe-field tribe-field-' . $this->type;
223
+ $return .= ( $this->error ) ? ' tribe-error' : '';
224
+ $return .= ( $this->size ) ? ' tribe-size-' . $this->size : '';
225
+ $return .= ( $this->class ) ? ' ' . $this->class . '"' : '"';
226
+ $return .= '>';
227
+
228
+ return apply_filters( 'tribe_field_start', $return, $this->id, $this->type, $this->error, $this->class, $this );
229
+ }
230
+
231
+ /**
232
+ * returns the field's end
233
+ *
234
+ * @return string the field end
235
+ */
236
+ public function doFieldEnd() {
237
+ $return = '</fieldset>';
238
+ $return .= ( $this->clear_after ) ? '<div class="clear"></div>' : '';
239
+
240
+ return apply_filters( 'tribe_field_end', $return, $this->id, $this );
241
+ }
242
+
243
+ /**
244
+ * returns the field's label
245
+ *
246
+ * @return string the field label
247
+ */
248
+ public function doFieldLabel() {
249
+ $return = '';
250
+ if ( $this->label ) {
251
+ $return = '<legend class="tribe-field-label">' . $this->label . '</legend>';
252
+ }
253
+
254
+ return apply_filters( 'tribe_field_label', $return, $this->label, $this );
255
+ }
256
+
257
+ /**
258
+ * returns the field's div start
259
+ *
260
+ * @return string the field div start
261
+ */
262
+ public function doFieldDivStart() {
263
+ $return = '<div class="tribe-field-wrap">';
264
+
265
+ return apply_filters( 'tribe_field_div_start', $return, $this );
266
+ }
267
+
268
+ /**
269
+ * returns the field's div end
270
+ *
271
+ * @return string the field div end
272
+ */
273
+ public function doFieldDivEnd() {
274
+ $return = $this->doToolTip();
275
+ $return .= '</div>';
276
+
277
+ return apply_filters( 'tribe_field_div_end', $return, $this );
278
+ }
279
+
280
+ /**
281
+ * returns the field's tooltip/description
282
+ *
283
+ * @return string the field tooltip
284
+ */
285
+ public function doToolTip() {
286
+ $return = '';
287
+ if ( $this->tooltip ) {
288
+ $return = '<p class="tooltip description">' . $this->tooltip . '</p>';
289
+ }
290
+
291
+ return apply_filters( 'tribe_field_tooltip', $return, $this->tooltip, $this );
292
+ }
293
+
294
+ /**
295
+ * returns the screen reader label
296
+ *
297
+ * @return string the screen reader label
298
+ */
299
+ public function doScreenReaderLabel() {
300
+ $return = '';
301
+ if ( $this->tooltip ) {
302
+ $return = '<label class="screen-reader-text">' . $this->tooltip . '</label>';
303
+ }
304
+
305
+ return apply_filters( 'tribe_field_screen_reader_label', $return, $this->tooltip, $this );
306
+ }
307
+
308
+ /**
309
+ * returns the field's value
310
+ *
311
+ * @return string the field value
312
+ */
313
+ public function doFieldValue() {
314
+ $return = '';
315
+ if ( $this->value ) {
316
+ $return = ' value="' . $this->value . '"';
317
+ }
318
+
319
+ return apply_filters( 'tribe_field_value', $return, $this->value, $this );
320
+ }
321
+
322
+ /**
323
+ * returns the field's name
324
+ *
325
+ * @param bool $multi
326
+ *
327
+ * @return string the field name
328
+ */
329
+ public function doFieldName( $multi = false ) {
330
+ $return = '';
331
+ if ( $this->name ) {
332
+ if ( $multi ) {
333
+ $return = ' name="' . $this->name . '[]"';
334
+ } else {
335
+ $return = ' name="' . $this->name . '"';
336
+ }
337
+ }
338
+
339
+ return apply_filters( 'tribe_field_name', $return, $this->name, $this );
340
+ }
341
+
342
+ /**
343
+ * Return a string of attributes for the field
344
+ *
345
+ * @return string
346
+ **/
347
+ public function doFieldAttributes() {
348
+ $return = '';
349
+ if ( ! empty( $this->attributes ) ) {
350
+ foreach ( $this->attributes as $key => $value ) {
351
+ $return .= ' ' . $key . '="' . $value . '"';
352
+ }
353
+ }
354
+
355
+ return apply_filters( 'tribe_field_attributes', $return, $this->name, $this );
356
+ }
357
+
358
+ /**
359
+ * generate a heading field
360
+ *
361
+ * @return string the field
362
+ */
363
+ public function heading() {
364
+ $field = '<h3>' . $this->label . '</h3>';
365
+
366
+ return $field;
367
+ }
368
+
369
+ /**
370
+ * generate an html field
371
+ *
372
+ * @return string the field
373
+ */
374
+ public function html() {
375
+ $field = $this->doFieldLabel();
376
+ $field .= $this->html;
377
+
378
+ return $field;
379
+ }
380
+
381
+ /**
382
+ * generate a simple text field
383
+ *
384
+ * @return string the field
385
+ */
386
+ public function text() {
387
+ $field = $this->doFieldStart();
388
+ $field .= $this->doFieldLabel();
389
+ $field .= $this->doFieldDivStart();
390
+ $field .= '<input';
391
+ $field .= ' type="text"';
392
+ $field .= $this->doFieldName();
393
+ $field .= $this->doFieldValue();
394
+ $field .= '/>';
395
+ $field .= $this->doScreenReaderLabel();
396
+ $field .= $this->doFieldDivEnd();
397
+ $field .= $this->doFieldEnd();
398
+
399
+ return $field;
400
+ }
401
+
402
+ /**
403
+ * generate a textarea field
404
+ *
405
+ * @return string the field
406
+ */
407
+ public function textarea() {
408
+ $field = $this->doFieldStart();
409
+ $field .= $this->doFieldLabel();
410
+ $field .= $this->doFieldDivStart();
411
+ $field .= '<textarea';
412
+ $field .= $this->doFieldName();
413
+ $field .= '>';
414
+ $field .= esc_html( stripslashes( $this->value ) );
415
+ $field .= '</textarea>';
416
+ $field .= $this->doScreenReaderLabel();
417
+ $field .= $this->doFieldDivEnd();
418
+ $field .= $this->doFieldEnd();
419
+
420
+ return $field;
421
+ }
422
+
423
+ /**
424
+ * generate a wp_editor field
425
+ *
426
+ * @return string the field
427
+ */
428
+ public function wysiwyg() {
429
+ $settings = array(
430
+ 'teeny' => true,
431
+ 'wpautop' => true,
432
+ );
433
+ ob_start();
434
+ wp_editor( html_entity_decode( ( $this->value ) ), $this->name, $settings );
435
+ $editor = ob_get_clean();
436
+ $field = $this->doFieldStart();
437
+ $field .= $this->doFieldLabel();
438
+ $field .= $this->doFieldDivStart();
439
+ $field .= $editor;
440
+ $field .= $this->doScreenReaderLabel();
441
+ $field .= $this->doFieldDivEnd();
442
+ $field .= $this->doFieldEnd();
443
+
444
+ return $field;
445
+ }
446
+
447
+ /**
448
+ * generate a radio button field
449
+ *
450
+ * @return string the field
451
+ */
452
+ public function radio() {
453
+ $field = $this->doFieldStart();
454
+ $field .= $this->doFieldLabel();
455
+ $field .= $this->doFieldDivStart();
456
+ if ( is_array( $this->options ) ) {
457
+ foreach ( $this->options as $option_id => $title ) {
458
+ $field .= '<label title="' . esc_attr( strip_tags( $title ) ) . '">';
459
+ $field .= '<input type="radio"';
460
+ $field .= $this->doFieldName();
461
+ $field .= ' value="' . esc_attr( $option_id ) . '" ' . checked( $this->value, $option_id, false ) . '/>';
462
+ $field .= $title;
463
+ $field .= '</label>';
464
+ }
465
+ } else {
466
+ $field .= '<span class="tribe-error">' . esc_html__( 'No radio options specified', 'tribe-common' ) . '</span>';
467
+ }
468
+ $field .= $this->doFieldDivEnd();
469
+ $field .= $this->doFieldEnd();
470
+
471
+ return $field;
472
+ }
473
+
474
+ /**
475
+ * generate a checkbox_list field
476
+ *
477
+ * @return string the field
478
+ */
479
+ public function checkbox_list() {
480
+ $field = $this->doFieldStart();
481
+ $field .= $this->doFieldLabel();
482
+ $field .= $this->doFieldDivStart();
483
+
484
+ if ( ! is_array( $this->value ) ) {
485
+ if ( ! empty( $this->value ) ) {
486
+ $this->value = array( $this->value );
487
+ } else {
488
+ $this->value = array();
489
+ }
490
+ }
491
+
492
+ if ( is_array( $this->options ) ) {
493
+ foreach ( $this->options as $option_id => $title ) {
494
+ $field .= '<label title="' . esc_attr( $title ) . '">';
495
+ $field .= '<input type="checkbox"';
496
+ $field .= $this->doFieldName( true );
497
+ $field .= ' value="' . esc_attr( $option_id ) . '" ' . checked( in_array( $option_id, $this->value ), true, false ) . '/>';
498
+ $field .= $title;
499
+ $field .= '</label>';
500
+ }
501
+ } else {
502
+ $field .= '<span class="tribe-error">' . esc_html__( 'No checkbox options specified', 'tribe-common' ) . '</span>';
503
+ }
504
+ $field .= $this->doFieldDivEnd();
505
+ $field .= $this->doFieldEnd();
506
+
507
+ return $field;
508
+ }
509
+
510
+ /**
511
+ * generate a boolean checkbox field
512
+ *
513
+ * @return string the field
514
+ */
515
+ public function checkbox_bool() {
516
+ $field = $this->doFieldStart();
517
+ $field .= $this->doFieldLabel();
518
+ $field .= $this->doFieldDivStart();
519
+ $field .= '<input type="checkbox"';
520
+ $field .= $this->doFieldName();
521
+ $field .= ' value="1" ' . checked( $this->value, true, false );
522
+ $field .= $this->doFieldAttributes();
523
+ $field .= '/>';
524
+ $field .= $this->doScreenReaderLabel();
525
+ $field .= $this->doFieldDivEnd();
526
+ $field .= $this->doFieldEnd();
527
+
528
+ return $field;
529
+ }
530
+
531
+ /**
532
+ * generate a dropdown field
533
+ *
534
+ * @return string the field
535
+ */
536
+ public function dropdown() {
537
+ $field = $this->doFieldStart();
538
+ $field .= $this->doFieldLabel();
539
+ $field .= $this->doFieldDivStart();
540
+ if ( is_array( $this->options ) && ! empty( $this->options ) ) {
541
+ $field .= '<select';
542
+ $field .= $this->doFieldName();
543
+ $field .= '>';
544
+ foreach ( $this->options as $option_id => $title ) {
545
+ $field .= '<option value="' . esc_attr( $option_id ) . '"';
546
+ if ( is_array( $this->value ) ) {
547
+ $field .= isset( $this->value[0] ) ? selected( $this->value[0], $option_id, false ) : '';
548
+ } else {
549
+ $field .= selected( $this->value, $option_id, false );
550
+ }
551
+ $field .= '>' . esc_html( $title ) . '</option>';
552
+ }
553
+ $field .= '</select>';
554
+ $field .= $this->doScreenReaderLabel();
555
+ } elseif ( $this->if_empty ) {
556
+ $field .= '<span class="empty-field">' . (string) $this->if_empty . '</span>';
557
+ } else {
558
+ $field .= '<span class="tribe-error">' . esc_html__( 'No select options specified', 'tribe-common' ) . '</span>';
559
+ }
560
+ $field .= $this->doFieldDivEnd();
561
+ $field .= $this->doFieldEnd();
562
+
563
+ return $field;
564
+ }
565
+
566
+ /**
567
+ * generate a chosen dropdown field - the same as the
568
+ * regular dropdown but wrapped so it can have the
569
+ * right css class applied to it
570
+ *
571
+ * @return string the field
572
+ */
573
+ public function dropdown_chosen() {
574
+ $field = $this->dropdown();
575
+
576
+ return $field;
577
+ }
578
+
579
+ /**
580
+ * generate a select2 dropdown field - the same as the
581
+ * regular dropdown but wrapped so it can have the
582
+ * right css class applied to it
583
+ *
584
+ * @return string the field
585
+ */
586
+ public function dropdown_select2() {
587
+ $field = $this->dropdown();
588
+
589
+ return $field;
590
+ }
591
+
592
+ /**
593
+ * generate a license key field
594
+ *
595
+ * @return string the field
596
+ */
597
+ public function license_key() {
598
+ $field = $this->doFieldStart();
599
+ $field .= $this->doFieldLabel();
600
+ $field .= $this->doFieldDivStart();
601
+ $field .= '<input';
602
+ $field .= ' type="text"';
603
+ $field .= $this->doFieldName();
604
+ $field .= $this->doFieldValue();
605
+ $field .= '/>';
606
+ $field .= '<p class="license-test-results"><img src="' . esc_url( admin_url( 'images/wpspin_light.gif' ) ) . '" class="ajax-loading-license" alt="Loading" style="display: none"/>';
607
+ $field .= '<span class="key-validity"></span>';
608
+ $field .= $this->doScreenReaderLabel();
609
+ $field .= $this->doFieldDivEnd();
610
+ $field .= $this->doFieldEnd();
611
+
612
+ return $field;
613
+ }
614
+
615
+ } // end class
616
+ } // endif class_exists
common/src/Tribe/JSON_LD/Abstract.php CHANGED
@@ -1,143 +1,143 @@
1
- <?php
2
-
3
- // Don't load directly
4
- if ( ! defined( 'ABSPATH' ) ) {
5
- die( '-1' );
6
- }
7
-
8
- /**
9
- * An Abstract class that will allow us to have a base to go for all
10
- * the other JSON-LD classes.
11
- *
12
- * Always extend this when doing a new JSON-LD object
13
- */
14
- abstract class Tribe__JSON_LD__Abstract {
15
-
16
- /**
17
- * Holder of the Instances
18
- * @var array
19
- */
20
- private static $instances = array();
21
-
22
- /**
23
- * The class singleton constructor.
24
- *
25
- * @return Tribe__JSON_LD__Abstract
26
- */
27
- public static function instance( $name = null ) {
28
- if ( empty( self::$instances[ $name ] ) ) {
29
- self::$instances[ $name ] = new $name();
30
- }
31
-
32
- return self::$instances[ $name ];
33
- }
34
-
35
- /**
36
- * Which type of element this actually is
37
- *
38
- * @see https://developers.google.com/structured-data/rich-snippets/
39
- * @var string
40
- */
41
- public $type = 'Thing';
42
-
43
- /**
44
- * Compile the schema.org event data into an array
45
- */
46
- public function get_data( $post = null, $args = array() ) {
47
- if ( ! $post instanceof WP_Post ) {
48
- $post = Tribe__Main::post_id_helper( $post );
49
- }
50
- $post = get_post( $post );
51
-
52
- if ( ! $post instanceof WP_Post ) {
53
- return array();
54
- }
55
-
56
- $data = (object) array();
57
-
58
- // We may need to prevent the context to be triggered
59
- if ( ! isset( $args['context'] ) || false !== $args['context'] ) {
60
- $data->{'@context'} = 'http://schema.org';
61
- }
62
- $data->{'@type'} = $this->type;
63
-
64
- $data->name = esc_js( get_the_title( $post ) );
65
- $data->description = esc_js( tribe_events_get_the_excerpt( $post ) );
66
-
67
- if ( has_post_thumbnail( $post ) ) {
68
- $data->image = wp_get_attachment_url( get_post_thumbnail_id( $post ) );
69
- }
70
-
71
- $data->url = esc_url_raw( get_permalink( $post ) );
72
-
73
- // Index by ID: this will allow filter code to identify the actual event being referred to
74
- // without injecting an additional property
75
- return array( $post->ID => $data );
76
- }
77
-
78
- /**
79
- * puts together the actual html/json javascript block for output
80
- * @return string
81
- */
82
- public function get_markup( $post = null, $args = array() ) {
83
- $data = $this->get_data( $post, $args );
84
-
85
- $type = strtolower( esc_attr( $this->type ) );
86
-
87
- foreach ( $data as $post_id => $_data ) {
88
- /**
89
- * Allows the event data to be modifed by themes and other plugins.
90
- *
91
- * @example tribe_json_ld_thing_object
92
- * @example tribe_json_ld_event_object
93
- *
94
- * @param object $data objects representing the Google Markup for each event.
95
- * @param array $args the arguments used to get data
96
- * @param WP_Post $post the arguments used to get data
97
- */
98
- $data[ $post_id ] = apply_filters( "tribe_json_ld_{$type}_object", $_data, $args, get_post( $post_id ) );
99
- }
100
-
101
- /**
102
- * Allows the event data to be modifed by themes and other plugins.
103
- *
104
- * @example tribe_json_ld_thing_data
105
- * @example tribe_json_ld_event_data
106
- *
107
- * @param array $data objects representing the Google Markup for each event.
108
- * @param array $args the arguments used to get data
109
- */
110
- $data = apply_filters( "tribe_json_ld_{$type}_data", $data, $args );
111
-
112
- // Strip the post ID indexing before returning
113
- $data = array_values( $data );
114
-
115
- if ( ! empty( $data ) ) {
116
- $html[] = '<script type="application/ld+json">';
117
- $html[] = str_replace( '\/', '/', json_encode( $data ) );
118
- $html[] = '</script>';
119
- }
120
-
121
- return ! empty( $html ) ? implode( "\r\n", $html ) : '';
122
- }
123
-
124
- public function markup( $post = null, $args = array() ) {
125
- $html = $this->get_markup( $post, $args );
126
-
127
- /**
128
- * Allows users to filter the end markup of JSON-LD
129
- * @deprecated
130
- * @todo Remove on 4.4
131
- * @param string The HTML for the JSON LD markup
132
- */
133
- $html = apply_filters( 'tribe_google_data_markup_json', $html );
134
-
135
- /**
136
- * Allows users to filter the end markup of JSON-LD
137
- * @param string The HTML for the JSON LD markup
138
- */
139
- $html = apply_filters( 'tribe_json_ld_markup', $html );
140
-
141
- echo $html;
142
- }
143
- }
1
+ <?php
2
+
3
+ // Don't load directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ die( '-1' );
6
+ }
7
+
8
+ /**
9
+ * An Abstract class that will allow us to have a base to go for all
10
+ * the other JSON-LD classes.
11
+ *
12
+ * Always extend this when doing a new JSON-LD object
13
+ */
14
+ abstract class Tribe__JSON_LD__Abstract {
15
+
16
+ /**
17
+ * Holder of the Instances
18
+ * @var array
19
+ */
20
+ private static $instances = array();
21
+
22
+ /**
23
+ * The class singleton constructor.
24
+ *
25
+ * @return Tribe__JSON_LD__Abstract
26
+ */
27
+ public static function instance( $name = null ) {
28
+ if ( empty( self::$instances[ $name ] ) ) {
29
+ self::$instances[ $name ] = new $name();
30
+ }
31
+
32
+ return self::$instances[ $name ];
33
+ }
34
+
35
+ /**
36
+ * Which type of element this actually is
37
+ *
38
+ * @see https://developers.google.com/structured-data/rich-snippets/
39
+ * @var string
40
+ */
41
+ public $type = 'Thing';
42
+
43
+ /**
44
+ * Compile the schema.org event data into an array
45
+ */
46
+ public function get_data( $post = null, $args = array() ) {
47
+ if ( ! $post instanceof WP_Post ) {
48
+ $post = Tribe__Main::post_id_helper( $post );
49
+ }
50
+ $post = get_post( $post );
51
+
52
+ if ( ! $post instanceof WP_Post ) {
53
+ return array();
54
+ }
55
+
56
+ $data = (object) array();
57
+
58
+ // We may need to prevent the context to be triggered
59
+ if ( ! isset( $args['context'] ) || false !== $args['context'] ) {
60
+ $data->{'@context'} = 'http://schema.org';
61
+ }
62
+ $data->{'@type'} = $this->type;
63
+
64
+ $data->name = esc_js( get_the_title( $post ) );
65
+ $data->description = esc_js( tribe_events_get_the_excerpt( $post ) );
66
+
67
+ if ( has_post_thumbnail( $post ) ) {
68
+ $data->image = wp_get_attachment_url( get_post_thumbnail_id( $post ) );
69
+ }
70
+
71
+ $data->url = esc_url_raw( get_permalink( $post ) );
72
+
73
+ // Index by ID: this will allow filter code to identify the actual event being referred to
74
+ // without injecting an additional property
75
+ return array( $post->ID => $data );
76
+ }
77
+
78
+ /**
79
+ * puts together the actual html/json javascript block for output
80
+ * @return string
81
+ */
82
+ public function get_markup( $post = null, $args = array() ) {
83
+ $data = $this->get_data( $post, $args );
84
+
85
+ $type = strtolower( esc_attr( $this->type ) );
86
+
87
+ foreach ( $data as $post_id => $_data ) {
88
+ /**
89
+ * Allows the event data to be modifed by themes and other plugins.
90
+ *
91
+ * @example tribe_json_ld_thing_object
92
+ * @example tribe_json_ld_event_object
93
+ *
94
+ * @param object $data objects representing the Google Markup for each event.
95
+ * @param array $args the arguments used to get data
96
+ * @param WP_Post $post the arguments used to get data
97
+ */
98
+ $data[ $post_id ] = apply_filters( "tribe_json_ld_{$type}_object", $_data, $args, get_post( $post_id ) );
99
+ }
100
+
101
+ /**
102
+ * Allows the event data to be modifed by themes and other plugins.
103
+ *
104
+ * @example tribe_json_ld_thing_data
105
+ * @example tribe_json_ld_event_data
106
+ *
107
+ * @param array $data objects representing the Google Markup for each event.
108
+ * @param array $args the arguments used to get data
109
+ */
110
+ $data = apply_filters( "tribe_json_ld_{$type}_data", $data, $args );
111
+
112
+ // Strip the post ID indexing before returning
113
+ $data = array_values( $data );
114
+
115
+ if ( ! empty( $data ) ) {
116
+ $html[] = '<script type="application/ld+json">';
117
+ $html[] = str_replace( '\/', '/', json_encode( $data ) );
118
+ $html[] = '</script>';
119
+ }
120
+
121
+ return ! empty( $html ) ? implode( "\r\n", $html ) : '';
122
+ }
123
+
124
+ public function markup( $post = null, $args = array() ) {
125
+ $html = $this->get_markup( $post, $args );
126
+
127
+ /**
128
+ * Allows users to filter the end markup of JSON-LD
129
+ * @deprecated
130
+ * @todo Remove on 4.4
131
+ * @param string The HTML for the JSON LD markup
132
+ */
133
+ $html = apply_filters( 'tribe_google_data_markup_json', $html );
134
+
135
+ /**
136
+ * Allows users to filter the end markup of JSON-LD
137
+ * @param string The HTML for the JSON LD markup
138
+ */
139
+ $html = apply_filters( 'tribe_json_ld_markup', $html );
140
+
141
+ echo $html;
142
+ }
143
+ }
common/src/Tribe/Log.php CHANGED
@@ -1,354 +1,354 @@
1
- <?php
2
- if ( class_exists( 'Tribe__Log' ) ) {
3
- return;
4
- }
5
-
6
- /**
7
- * Provides access to and management of core logging facilities.
8
- */
9
- class Tribe__Log {
10
- const DISABLE = 'disable';
11
- const DEBUG = 'debug';
12
- const WARNING = 'warning';
13
- const ERROR = 'error';
14
- const CLEANUP = 'tribe_common_log_cleanup';
15
-
16
- /**
17
- * @var Tribe__Log__Admin
18
- */
19
- protected $admin;
20
-
21
- /**
22
- * @var Tribe__Log__Logger
23
- */
24
- protected $current_logger;
25
-
26
- /**
27
- * @var string
28
- */
29
- protected $current_level;
30
-
31
- /**
32
- * All logging levels in priority order. Each level is represented by
33
- * an array in the form [ code => description ].
34
- *
35
- * @var array
36
- */
37
- protected $levels = array();
38
-
39
- /**
40
- * Alternative representation of the $levels property allowing quick look
41
- * up of levels by priority.
42
- *
43
- * @var array
44
- */
45
- protected $prioritized_levels = array();
46
-
47
- /**
48
- * Instantiated loggers, stored for re-use.
49
- *
50
- * @var array
51
- */
52
- protected $loggers = array();
53
-
54
-
55
- public function __construct() {
56
- if ( is_admin() ) {
57
- $this->admin = new Tribe__Log__Admin();
58
- }
59
-
60
- $this->current_level = $this->get_level();
61
- $this->log_cleanup();
62
- }
63
-
64
- /**
65
- * @return Tribe__Log__Admin
66
- */
67
- public function admin() {
68
- return $this->admin;
69
- }
70
-
71
- /**
72
- * Facilitates daily cleanup and log rotation.
73
- */
74
- protected function log_cleanup() {
75
- $this->register_cleanup_task();
76
- do_action( self::CLEANUP, array( $this, 'do_cleanup' ) );
77
- }
78
-
79
- /**
80
- * Schedules a daily cleanup task if one is not already in place.
81
- */
82
- protected function register_cleanup_task() {
83
- if ( ! wp_next_scheduled( self::CLEANUP ) ) {
84
- wp_schedule_event( strtotime( '+1 day' ), 'daily', self::CLEANUP );
85
- }
86
- }
87
-
88
- /**
89
- * Call the cleanup() method for each available logging engine.
90
- *
91
- * We don't just call it on the current engine since, if there was a recent change,
92
- * we'll generally still want the now unused engine's output to be cleaned up.
93
- */
94
- public function do_cleanup() {
95
- foreach ( $this->get_logging_engines() as $engine ) {
96
- /**
97
- * @var Tribe__Log__Logger $engine
98
- */
99
- $engine->cleanup();
100
- }
101
- }
102
-
103
- /**
104
- * Logs a debug-level entry.
105
- *
106
- * @param string $entry
107
- * @param string $src
108
- */
109
- public function log_debug( $entry, $src ) {
110
- $this->log( $entry, self::DEBUG, $src );
111
- }
112
-
113
- /**
114
- * Logs a warning.
115
- *
116
- * @param string $entry
117
- * @param string $src
118
- */
119
- public function log_warning( $entry, $src ) {
120
- $this->log( $entry, self::WARNING, $src );
121
- }
122
-
123
- /**
124
- * Logs an error.
125
- *
126
- * @param string $entry
127
- * @param string $src
128
- */
129
- public function log_error( $entry, $src ) {
130
- $this->log( $entry, self::ERROR, $src );
131
- }
132
-
133
- /**
134
- * Adds an entry to the log (if it is at the appropriate level, etc).
135
- *
136
- * This is simply a shorthand for calling log() on the current logger.
137
- */
138
- public function log( $entry, $type = self::DEBUG, $src = '' ) {
139
- if ( $this->should_log( $type ) ) {
140
- $this->get_current_logger()->log( $entry, $type, $src );
141
- }
142
- }
143
-
144
- /**
145
- * Returns a list of available logging engines as an array where each
146
- * key is the classname and the value is the logger itself.
147
- *
148
- * @return array
149
- */
150
- public function get_logging_engines() {
151
- $available_engines = array();
152
- $bundled_engines = array(
153
- 'Tribe__Log__File_Logger',
154
- );
155
-
156
- foreach ( $bundled_engines as $engine_class ) {
157
- $engine = $this->get_engine( $engine_class );
158
-
159
- // Check that we have a valid engine that is available for use in the current environment
160
- if ( $engine && $engine->is_available() ) {
161
- $available_engines[ $engine_class ] = $engine;
162
- }
163
- }
164
-
165
- /**
166
- * Offers a chance to modify the array of currently available logging engines.
167
- *
168
- * The array is organized with each key as the class name of the logging
169
- * implementation and the matching value is the actual logger object.
170
- *
171
- * @var array $available_engines
172
- */
173
- return apply_filters( 'tribe_common_logging_engines', $available_engines );
174
- }
175
-
176
- /**
177
- * Returns the currently active logger or null if none is set/none are
178
- * available.
179
- *
180
- * @return Tribe__Log__Logger|null
181
- */
182
- public function get_current_logger() {
183
- if ( ! $this->current_logger ) {
184
- $engine = tribe_get_option( 'logging_class', null );
185
- $available = $this->get_logging_engines();
186
-
187
- if ( empty( $engine ) || ! isset( $available[ $engine ] ) ) {
188
- return null;
189
- }
190
-
191
- $this->current_logger = $this->get_engine( $engine );
192
- }
193
-
194
- return $this->current_logger;
195
- }
196
-
197
- /**
198
- * Sets the current logging engine to the provided class (if it is a valid
199
- * and currently available logging class, else will set this to null - ie
200
- * no logging).
201
- *
202
- * @param string $engine
203
- *
204
- * @throws Exception if the specified logging engine is invalid
205
- */
206
- public function set_current_logger( $engine ) {
207
- $available_engines = $this->get_logging_engines();
208
-
209
- if ( ! isset( $available_engines[ $engine ] ) ) {
210
- throw new Exception( sprintf( __( 'Cannot set %s as the current logging engine', 'tribe-common' ), $engine ) );
211
- }
212
-
213
- tribe_update_option( 'logging_class', $engine );
214
- $this->current_logger = $available_engines[ $engine ];
215
- }
216
-
217
- /**
218
- * Attempts to return the requested logging object or null if that
219
- * is not possible.
220
- *
221
- * @param $class_name
222
- *
223
- * @return Tribe__Log__Logger|null
224
- */
225
- public function get_engine( $class_name ) {
226
- if ( ! isset( $this->loggers[ $class_name ] ) ) {
227
- $object = new $class_name;
228
-
229
- if ( is_a( $object, 'Tribe__Log__Logger' ) ) {
230
- $this->loggers[ $class_name ] = new $class_name();
231
- }
232
- }
233
-
234
- if ( isset( $this->loggers[ $class_name ] ) ) {
235
- return $this->loggers[ $class_name ];
236
- }
237
-
238
- return null;
239
- }
240
-
241
- /**
242
- * Sets the current logging level to the provided level (if it is a valid
243
- * level, else will set the level to 'default').
244
- *
245
- * @param string $level
246
- */
247
- public function set_level( $level ) {
248
- $available_levels = wp_list_pluck( $this->get_logging_levels(), 0 );
249
-
250
- if ( ! in_array( $level, $available_levels ) ) {
251
- $level = self::DISABLE;
252
- }
253
-
254
- tribe_update_option( 'logging_level', $level );
255
- $this->current_level = $level;
256
- }
257
-
258
- /**
259
- * Returns the current logging level as a string.
260
- *
261
- * @return string
262
- */
263
- public function get_level() {
264
- $current_level = tribe_get_option( 'logging_level', null );
265
- $available_levels = wp_list_pluck( $this->get_logging_levels(), 0 );
266
-
267
- if ( ! in_array( $current_level, $available_levels ) ) {
268
- $current_level = self::DISABLE;
269
- }
270
-
271
- return $current_level;
272
- }
273
-
274
- /**
275
- * Returns a list of logging levels.
276
- *
277
- * The format is an array of arrays, each inner array being comprised of the
278
- * level code (index 0) and a human readable description (index 1).
279
- *
280
- * The ordering of the inner arrays is critical as it dictates what will be logged
281
- * when a given logging level is in effect. Example: if the current logging level
282
- * is "error" mode (only record error-level problems) then debug-level notices will
283
- * *not* be recorded and nor will warnings.
284
- *
285
- * On the other hand, if the current logging level is "debug" then debug level
286
- * notices *and* all higher levels (including warnings and errors) will be recorded.
287
- *
288
- * @return array
289
- */
290
- public function get_logging_levels() {
291
- if ( empty( $this->levels ) ) {
292
- /**
293
- * Provides an opportunity to add or remove logging levels. This is expected
294
- * to be organized as an array of arrays: the ordering of each inner array
295
- * is critical, see Tribe__Log::get_logging_levels() docs.
296
- *
297
- * General form:
298
- *
299
- * [
300
- * [ 'disable' => 'description' ], // * Do not log anything
301
- * [ 'error' => 'description' ], // ^ Log only the most critical problems
302
- * [ 'warning' => 'description' ], // | ...
303
- * [ 'debug' => 'description' ] // v Log as much data as possible, including less important trivia
304
- * ]
305
- *
306
- * @param array $logging_levels
307
- */
308
- $this->levels = (array) apply_filters( 'tribe_common_logging_levels', array(
309
- array( self::DISABLE, __( 'Disabled', 'tribe-common' ) ),
310
- array( self::ERROR, __( 'Only errors', 'tribe-common' ) ),
311
- array( self::WARNING, __( 'Warnings and errors', 'tribe-common' ) ),
312
- array( self::DEBUG, __( 'Full debug (all events)', 'tribe-common' ) ),
313
- ) );
314
- }
315
-
316
- return $this->levels;
317
- }
318
-
319
- /**
320
- * Indicates if errors relating to the specified logging level should indeed
321
- * be logged.
322
- *
323
- * Examples if the current logging level is "warning" (log all warnings and errors):
324
- *
325
- * * Returns true for "error"
326
- * * Returns true for "warning"
327
- * * Returns false for "debug"
328
- *
329
- * The above assumes we are using the default logging levels.
330
- *
331
- * @param string $level_code
332
- *
333
- * @return bool
334
- */
335
- protected function should_log( $level_code ) {
336
- if ( empty( $this->prioritized_levels ) ) {
337
- $this->build_prioritized_levels();
338
- }
339
-
340
- return $this->prioritized_levels[ $level_code ] <= $this->prioritized_levels[ $this->current_level ];
341
- }
342
-
343
- /**
344
- * Creates a second list of logging levels allowing easy lookup of
345
- * their relative priorities (ie, a means of quickly checking if
346
- * an "error" level entry should be recorded when we're in debug
347
- * mode).
348
- */
349
- protected function build_prioritized_levels() {
350
- foreach ( $this->get_logging_levels() as $index => $level_data ) {
351
- $this->prioritized_levels[ $level_data[1] ] = $index;
352
- }
353
- }
354
  }
1
+ <?php
2
+ if ( class_exists( 'Tribe__Log' ) ) {
3
+ return;
4
+ }
5
+
6
+ /**
7
+ * Provides access to and management of core logging facilities.
8
+ */
9
+ class Tribe__Log {
10
+ const DISABLE = 'disable';
11
+ const DEBUG = 'debug';
12
+ const WARNING = 'warning';
13
+ const ERROR = 'error';
14
+ const CLEANUP = 'tribe_common_log_cleanup';
15
+
16
+ /**
17
+ * @var Tribe__Log__Admin
18
+ */
19
+ protected $admin;
20
+
21
+ /**
22
+ * @var Tribe__Log__Logger
23
+ */
24
+ protected $current_logger;
25
+
26
+ /**
27
+ * @var string
28
+ */
29
+ protected $current_level;
30
+
31
+ /**
32
+ * All logging levels in priority order. Each level is represented by
33
+ * an array in the form [ code => description ].
34
+ *
35
+ * @var array
36
+ */
37
+ protected $levels = array();
38
+
39
+ /**
40
+ * Alternative representation of the $levels property allowing quick look
41
+ * up of levels by priority.
42
+ *
43
+ * @var array
44
+ */
45
+ protected $prioritized_levels = array();
46
+
47
+ /**
48
+ * Instantiated loggers, stored for re-use.
49
+ *
50
+ * @var array
51
+ */
52
+ protected $loggers = array();
53
+
54
+
55
+ public function __construct() {
56
+ if ( is_admin() ) {
57
+ $this->admin = new Tribe__Log__Admin();
58
+ }
59
+
60
+ $this->current_level = $this->get_level();
61
+ $this->log_cleanup();
62
+ }
63
+
64
+ /**
65
+ * @return Tribe__Log__Admin
66
+ */
67
+ public function admin() {
68
+ return $this->admin;
69
+ }
70
+
71
+ /**
72
+ * Facilitates daily cleanup and log rotation.
73
+ */
74
+ protected function log_cleanup() {
75
+ $this->register_cleanup_task();
76
+ do_action( self::CLEANUP, array( $this, 'do_cleanup' ) );
77
+ }
78
+
79
+ /**
80
+ * Schedules a daily cleanup task if one is not already in place.
81
+ */
82
+ protected function register_cleanup_task() {
83
+ if ( ! wp_next_scheduled( self::CLEANUP ) ) {
84
+ wp_schedule_event( strtotime( '+1 day' ), 'daily', self::CLEANUP );
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Call the cleanup() method for each available logging engine.
90
+ *
91
+ * We don't just call it on the current engine since, if there was a recent change,
92
+ * we'll generally still want the now unused engine's output to be cleaned up.
93
+ */
94
+ public function do_cleanup() {
95
+ foreach ( $this->get_logging_engines() as $engine ) {
96
+ /**
97
+ * @var Tribe__Log__Logger $engine
98
+ */
99
+ $engine->cleanup();
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Logs a debug-level entry.
105
+ *
106
+ * @param string $entry
107
+ * @param string $src
108
+ */
109
+ public function log_debug( $entry, $src ) {
110
+ $this->log( $entry, self::DEBUG, $src );
111
+ }
112
+
113
+ /**
114
+ * Logs a warning.
115
+ *
116
+ * @param string $entry
117
+ * @param string $src
118
+ */
119
+ public function log_warning( $entry, $src ) {
120
+ $this->log( $entry, self::WARNING, $src );
121
+ }
122
+
123
+ /**
124
+ * Logs an error.
125
+ *
126
+ * @param string $entry
127
+ * @param string $src
128
+ */
129
+ public function log_error( $entry, $src ) {
130
+ $this->log( $entry, self::ERROR, $src );
131
+ }
132
+
133
+ /**
134
+ * Adds an entry to the log (if it is at the appropriate level, etc).
135
+ *
136
+ * This is simply a shorthand for calling log() on the current logger.
137
+ */
138
+ public function log( $entry, $type = self::DEBUG, $src = '' ) {
139
+ if ( $this->should_log( $type ) ) {
140
+ $this->get_current_logger()->log( $entry, $type, $src );
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Returns a list of available logging engines as an array where each
146
+ * key is the classname and the value is the logger itself.
147
+ *
148
+ * @return array
149
+ */
150
+ public function get_logging_engines() {
151
+ $available_engines = array();
152
+ $bundled_engines = array(
153
+ 'Tribe__Log__File_Logger',
154
+ );
155
+
156
+ foreach ( $bundled_engines as $engine_class ) {
157
+ $engine = $this->get_engine( $engine_class );
158
+
159
+ // Check that we have a valid engine that is available for use in the current environment
160
+ if ( $engine && $engine->is_available() ) {
161
+ $available_engines[ $engine_class ] = $engine;
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Offers a chance to modify the array of currently available logging engines.
167
+ *
168
+ * The array is organized with each key as the class name of the logging
169
+ * implementation and the matching value is the actual logger object.
170
+ *
171
+ * @var array $available_engines
172
+ */
173
+ return apply_filters( 'tribe_common_logging_engines', $available_engines );
174
+ }
175
+
176
+ /**
177
+ * Returns the currently active logger or null if none is set/none are
178
+ * available.
179
+ *
180
+ * @return Tribe__Log__Logger|null
181
+ */
182
+ public function get_current_logger() {
183
+ if ( ! $this->current_logger ) {
184
+ $engine = tribe_get_option( 'logging_class', null );
185
+ $available = $this->get_logging_engines();
186
+
187
+ if ( empty( $engine ) || ! isset( $available[ $engine ] ) ) {
188
+ return null;
189
+ }
190
+
191
+ $this->current_logger = $this->get_engine( $engine );
192
+ }
193
+
194
+ return $this->current_logger;
195
+ }
196
+
197
+ /**
198
+ * Sets the current logging engine to the provided class (if it is a valid
199
+ * and currently available logging class, else will set this to null - ie
200
+ * no logging).
201
+ *
202
+ * @param string $engine
203
+ *
204
+ * @throws Exception if the specified logging engine is invalid
205
+ */
206
+ public function set_current_logger( $engine ) {
207
+ $available_engines = $this->get_logging_engines();
208
+
209
+ if ( ! isset( $available_engines[ $engine ] ) ) {
210
+ throw new Exception( sprintf( __( 'Cannot set %s as the current logging engine', 'tribe-common' ), $engine ) );
211
+ }
212
+
213
+ tribe_update_option( 'logging_class', $engine );
214
+ $this->current_logger = $available_engines[ $engine ];
215
+ }
216
+
217
+ /**
218
+ * Attempts to return the requested logging object or null if that
219
+ * is not possible.
220
+ *
221
+ * @param $class_name
222
+ *
223
+ * @return Tribe__Log__Logger|null
224
+ */
225
+ public function get_engine( $class_name ) {
226
+ if ( ! isset( $this->loggers[ $class_name ] ) ) {
227
+ $object = new $class_name;
228
+
229
+ if ( is_a( $object, 'Tribe__Log__Logger' ) ) {
230
+ $this->loggers[ $class_name ] = new $class_name();
231
+ }
232
+ }
233
+
234
+ if ( isset( $this->loggers[ $class_name ] ) ) {
235
+ return $this->loggers[ $class_name ];
236
+ }
237
+
238
+ return null;
239
+ }
240
+
241
+ /**
242
+ * Sets the current logging level to the provided level (if it is a valid
243
+ * level, else will set the level to 'default').
244
+ *
245
+ * @param string $level
246
+ */
247
+ public function set_level( $level ) {
248
+ $available_levels = wp_list_pluck( $this->get_logging_levels(), 0 );
249
+
250
+ if ( ! in_array( $level, $available_levels ) ) {
251
+ $level = self::DISABLE;
252
+ }
253
+
254
+ tribe_update_option( 'logging_level', $level );
255
+ $this->current_level = $level;
256
+ }
257
+
258
+ /**
259
+ * Returns the current logging level as a string.
260
+ *
261
+ * @return string
262
+ */
263
+ public function get_level() {
264
+ $current_level = tribe_get_option( 'logging_level', null );
265
+ $available_levels = wp_list_pluck( $this->get_logging_levels(), 0 );
266
+
267
+ if ( ! in_array( $current_level, $available_levels ) ) {
268
+ $current_level = self::DISABLE;
269
+ }
270
+
271
+ return $current_level;
272
+ }
273
+
274
+ /**
275
+ * Returns a list of logging levels.
276
+ *
277
+ * The format is an array of arrays, each inner array being comprised of the
278
+ * level code (index 0) and a human readable description (index 1).
279
+ *
280
+ * The ordering of the inner arrays is critical as it dictates what will be logged
281
+ * when a given logging level is in effect. Example: if the current logging level
282
+ * is "error" mode (only record error-level problems) then debug-level notices will
283
+ * *not* be recorded and nor will warnings.
284
+ *
285
+ * On the other hand, if the current logging level is "debug" then debug level
286
+ * notices *and* all higher levels (including warnings and errors) will be recorded.
287
+ *
288
+ * @return array
289
+ */
290
+ public function get_logging_levels() {
291
+ if ( empty( $this->levels ) ) {
292
+ /**
293
+ * Provides an opportunity to add or remove logging levels. This is expected
294
+ * to be organized as an array of arrays: the ordering of each inner array
295
+ * is critical, see Tribe__Log::get_logging_levels() docs.
296
+ *
297
+ * General form:
298
+ *
299
+ * [
300
+ * [ 'disable' => 'description' ], // * Do not log anything
301
+ * [ 'error' => 'description' ], // ^ Log only the most critical problems
302
+ * [ 'warning' => 'description' ], // | ...
303
+ * [ 'debug' => 'description' ] // v Log as much data as possible, including less important trivia
304
+ * ]
305
+ *
306
+ * @param array $logging_levels
307
+ */
308
+ $this->levels = (array) apply_filters( 'tribe_common_logging_levels', array(
309
+ array( self::DISABLE, __( 'Disabled', 'tribe-common' ) ),
310
+ array( self::ERROR, __( 'Only errors', 'tribe-common' ) ),
311
+ array( self::WARNING, __( 'Warnings and errors', 'tribe-common' ) ),
312
+ array( self::DEBUG, __( 'Full debug (all events)', 'tribe-common' ) ),
313
+ ) );
314
+ }
315
+
316
+ return $this->levels;
317
+ }
318
+
319
+ /**
320
+ * Indicates if errors relating to the specified logging level should indeed
321
+ * be logged.
322
+ *
323
+ * Examples if the current logging level is "warning" (log all warnings and errors):
324
+ *
325
+ * * Returns true for "error"
326
+ * * Returns true for "warning"
327
+ * * Returns false for "debug"
328
+ *
329
+ * The above assumes we are using the default logging levels.
330
+ *
331
+ * @param string $level_code
332
+ *
333
+ * @return bool
334
+ */
335
+ protected function should_log( $level_code ) {
336
+ if ( empty( $this->prioritized_levels ) ) {
337
+ $this->build_prioritized_levels();
338
+ }
339
+
340
+ return $this->prioritized_levels[ $level_code ] <= $this->prioritized_levels[ $this->current_level ];
341
+ }
342
+
343
+ /**
344
+ * Creates a second list of logging levels allowing easy lookup of
345
+ * their relative priorities (ie, a means of quickly checking if
346
+ * an "error" level entry should be recorded when we're in debug
347
+ * mode).
348
+ */
349
+ protected function build_prioritized_levels() {
350
+ foreach ( $this->get_logging_levels() as $index => $level_data ) {
351
+ $this->prioritized_levels[ $level_data[1] ] = $index;
352
+ }
353
+ }
354
  }
common/src/Tribe/Log/Admin.php CHANGED
@@ -1,266 +1,266 @@
1
- <?php
2
- class Tribe__Log__Admin {
3
- public function __construct() {
4
- add_action( 'wp_ajax_tribe_logging_controls', array( $this, 'listen' ) );
5
- add_action( 'init', array( $this, 'serve_log_downloads' ) );
6
- add_action( 'init', array( $this, 'register_script' ) );
7
- }
8
-
9
- /**
10
- * Returns the HTML comprising the event log section for use in the
11
- * Events > Settings > Help screen.
12
- *
13
- * @return string
14
- */
15
- public function display_log() {
16
- $log_choices = $this->get_available_logs();
17
- $log_engines = $this->get_log_engines();
18
- $log_levels = $this->get_logging_levels();
19
- $log_entries = $this->get_log_entries();
20
- $download_url = $this->get_log_url();
21
-
22
- $this->setup_script();
23
-
24
- ob_start();
25
- include trailingslashit( Tribe__Main::instance()->plugin_path ) . 'src/admin-views/event-log.php';
26
- return ob_get_clean();
27
- }
28
-
29
- /**
30
- * Listens for changes to the event log settings updating and returning
31
- * an appropriate response.
32
- */
33
- public function listen() {
34
- $fields = wp_parse_args( $_POST, array(
35
- 'check' => '',
36
- 'log-level' => '',
37
- 'log-engine' => '',
38
- ) );
39
-
40
- foreach ( $fields as &$single_field ) {
41
- $single_field = sanitize_text_field( $single_field );
42
- }
43
-
44
- if ( ! wp_verify_nonce( $fields['check'], 'logging-controls' ) ) {
45
- return;
46
- }
47
-
48
- /**
49
- * Fires before log settings are committed.
50
- *
51
- * This will not happen unless a nonce check has already passed.
52
- */
53
- do_action( 'tribe_common_update_log_settings' );
54
-
55
- $this->update_logging_level( $fields['log-level'] );
56
- $this->update_logging_engine( $fields['log-engine'] );
57
-
58
- /**
59
- * Fires immediately after log settings have been committed.
60
- */
61
- do_action( 'tribe_common_updated_log_settings' );
62
-
63
- $data = array(
64
- 'logs' => $this->get_available_logs(),
65
- );
66
-
67
- if ( ! empty( $fields['log-view'] ) ) {
68
- $data['entries'] = $this->get_log_entries( $fields['log-view'] );
69
- }
70
-
71
- wp_send_json_success( $data );
72
- }
73
-
74
- /**
75
- * Sets the current logging level to the provided level (if it is a valid
76
- * level, else will set the level to 'default').
77
- *
78
- * @param string $level
79
- */
80
- protected function update_logging_level( $level ) {
81
- $this->log_manager()->set_level( $level );
82
- }
83
-
84
- /**
85
- * Sets the current logging engine to the provided class (if it is a valid
86
- * and currently available logging class, else will set this to null - ie
87
- * no logging).
88
- *
89
- * @param string $engine
90
- */
91
- protected function update_logging_engine( $engine ) {
92
- try {
93
- $this->log_manager()->set_current_logger( $engine );
94
- }
95
- catch ( Exception $e ) {
96
- // The class name did not relate to a valid logging engine
97
- }
98
- }
99
-
100
- /**
101
- * Register our script early.
102
- */
103
- public function register_script() {
104
- wp_register_script(
105
- 'tribe-common-logging-controls',
106
- tribe_resource_url( 'admin-log-controls.js', false, 'common' ),
107
- array( 'jquery' ),
108
- Tribe__Main::VERSION,
109
- true
110
- );
111
- }
112
-
113
- /**
114
- * Adds a script to handle the event log settings.
115
- */
116
- protected function setup_script() {
117
- wp_enqueue_script( 'tribe-common-logging-controls' );
118
- wp_localize_script( 'tribe-common-logging-controls', 'tribe_logger_data', array(
119
- 'check' => wp_create_nonce( 'logging-controls' )
120
- ) );
121
- }
122
-
123
- /**
124
- * Returns a list of logs that are available for perusal.
125
- *
126
- * @return array
127
- */
128
- protected function get_available_logs() {
129
- $available_logs = $this->current_logger()->list_available_logs();
130
-
131
- if ( empty( $available_logs ) ) {
132
- return array( '' => _x( 'None currently available', 'log selector', 'tribe-common' ) );
133
- }
134
-
135
- return $available_logs;
136
- }
137
-
138
- /**
139
- * Returns a list of logging engines that are available for use.
140
- *
141
- * @return array
142
- */
143
- protected function get_log_engines(){
144
- $available_engines = $this->log_manager()->get_logging_engines();
145
-
146
- if ( empty( $available_engines ) ) {
147
- return array( '' => _x( 'None currently available', 'log engines', 'tribe-common' ) );
148
- }
149
-
150
- $engine_list = array();
151
-
152
- foreach ( $available_engines as $class_name => $engine ) {
153
- /**
154
- * @var Tribe__Log__Logger $engine
155
- */
156
- $engine_list[ $class_name ] = $engine->get_name();
157
- }
158
-
159
- return $engine_list;
160
- }
161
-
162
- /**
163
- * Returns all log entries for the current or specified log.
164
- *
165
- * @return array
166
- */
167
- protected function get_log_entries( $log = null ) {
168
- $logger = $this->current_logger();
169
- $logger->use_log( $log );
170
- return $logger->retrieve();
171
- }
172
-
173
- /**
174
- * Returns an array of logging levels arranged as key:value pairs, with
175
- * each key being the level code and the value being the human-friendly
176
- * description.
177
- *
178
- * @return array
179
- */
180
- protected function get_logging_levels() {
181
- $levels = array();
182
- $available_levels = $this->log_manager()->get_logging_levels();
183
-
184
- foreach ( $available_levels as $logging_level ) {
185
- $levels[ $logging_level[0] ] = $logging_level[1];
186
- }
187
-
188
- return $levels;
189
- }
190
-
191
- /**
192
- * Provides a URL that can be used to download the current or specified
193
- * log.
194
- *
195
- * @param $log
196
- *
197
- * @return string
198
- */
199
- protected function get_log_url( $log = null ) {
200
- $query = array(
201
- 'tribe-common-log' => 'download',
202
- 'check' => wp_create_nonce( 'download_log' )
203
- );
204
-
205
- $log_download_url = add_query_arg( $query, get_admin_url( null, 'edit.php' ) );
206
-
207
- return esc_url( $log_download_url );
208
- }
209
-
210
- /**
211
- * Facilitate downloading of logs.
212
- */
213
- public function serve_log_downloads() {
214
- if ( empty( $_GET['tribe-common-log'] ) || 'download' !== $_GET['tribe-common-log'] ) {
215
- return;
216
- }
217
-
218
- if ( ! wp_verify_nonce( @$_GET['check'], 'download_log' ) ) {
219
- return;
220
- }
221
-
222
- if ( empty( $_GET['log'] ) || ! in_array( $_GET['log'], $this->get_available_logs() ) ) {
223
- return;
224
- }
225
-
226
- $log_name = sanitize_file_name( $_GET['log'] );
227
- $this->current_logger()->use_log( $log_name );
228
-
229
- /**
230
- * Provides an opportunity to modify the recommended filename for a downloaded
231
- * log file.
232
- *
233
- * @param string $log_name
234
- */
235
- $log_name = apply_filters( 'tribe_common_log_download_filename', $log_name );
236
-
237
- header( 'Content-Disposition: attachment; filename="tribe-log-' . $log_name . '"' );
238
- $output = fopen( 'php://output', 'w' );
239
-
240
- foreach ( $this->current_logger()->retrieve() as $log_entry ) {
241
- fputcsv( $output, $log_entry );
242
- }
243
-
244
- fclose( $output );
245
- exit();
246
- }
247
-
248
- /**
249
- * Returns a reference to the main log management object.
250
- *
251
- * @return Tribe__Log
252
- */
253
- protected function log_manager() {
254
- return Tribe__Main::instance()->log();
255
- }
256
-
257
- /**
258
- * Returns the currently enabled logging object or null if it is not
259
- * available.
260
- *
261
- * @return Tribe__Log__Logger|null
262
- */
263
- protected function current_logger() {
264
- return Tribe__Main::instance()->log()->get_current_logger();
265
- }
266
  }
1
+ <?php
2
+ class Tribe__Log__Admin {
3
+ public function __construct() {
4
+ add_action( 'wp_ajax_tribe_logging_controls', array( $this, 'listen' ) );
5
+ add_action( 'init', array( $this, 'serve_log_downloads' ) );
6
+ add_action( 'init', array( $this, 'register_script' ) );
7
+ }
8
+
9
+ /**
10
+ * Returns the HTML comprising the event log section for use in the
11
+ * Events > Settings > Help screen.
12
+ *
13
+ * @return string
14
+ */
15
+ public function display_log() {
16
+ $log_choices = $this->get_available_logs();
17
+ $log_engines = $this->get_log_engines();
18
+ $log_levels = $this->get_logging_levels();
19
+ $log_entries = $this->get_log_entries();
20
+ $download_url = $this->get_log_url();
21
+
22
+ $this->setup_script();
23
+
24
+ ob_start();
25
+ include trailingslashit( Tribe__Main::instance()->plugin_path ) . 'src/admin-views/event-log.php';
26
+ return ob_get_clean();
27
+ }
28
+
29
+ /**
30
+ * Listens for changes to the event log settings updating and returning
31
+ * an appropriate response.
32
+ */
33
+ public function listen() {
34
+ $fields = wp_parse_args( $_POST, array(
35
+ 'check' => '',
36
+ 'log-level' => '',
37
+ 'log-engine' => '',
38
+ ) );
39
+
40
+ foreach ( $fields as &$single_field ) {
41
+ $single_field = sanitize_text_field( $single_field );
42
+ }
43
+
44
+ if ( ! wp_verify_nonce( $fields['check'], 'logging-controls' ) ) {
45
+ return;
46
+ }
47
+
48
+ /**
49
+ * Fires before log settings are committed.
50
+ *
51
+ * This will not happen unless a nonce check has already passed.
52
+ */
53
+ do_action( 'tribe_common_update_log_settings' );
54
+
55
+ $this->update_logging_level( $fields['log-level'] );
56
+ $this->update_logging_engine( $fields['log-engine'] );
57
+
58
+ /**
59
+ * Fires immediately after log settings have been committed.
60
+ */
61
+ do_action( 'tribe_common_updated_log_settings' );
62
+
63
+ $data = array(
64
+ 'logs' => $this->get_available_logs(),
65
+ );
66
+
67
+ if ( ! empty( $fields['log-view'] ) ) {
68
+ $data['entries'] = $this->get_log_entries( $fields['log-view'] );
69
+ }
70
+
71
+ wp_send_json_success( $data );
72
+ }
73
+
74
+ /**
75
+ * Sets the current logging level to the provided level (if it is a valid
76
+ * level, else will set the level to 'default').
77
+ *
78
+ * @param string $level
79
+ */
80
+ protected function update_logging_level( $level ) {
81
+ $this->log_manager()->set_level( $level );
82
+ }
83
+
84
+ /**
85
+ * Sets the current logging engine to the provided class (if it is a valid
86
+ * and currently available logging class, else will set this to null - ie
87
+ * no logging).
88
+ *
89
+ * @param string $engine
90
+ */
91
+ protected function update_logging_engine( $engine ) {
92
+ try {
93
+ $this->log_manager()->set_current_logger( $engine );
94
+ }
95
+ catch ( Exception $e ) {
96
+ // The class name did not relate to a valid logging engine
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Register our script early.
102
+ */
103
+ public function register_script() {
104
+ wp_register_script(
105
+ 'tribe-common-logging-controls',
106
+ tribe_resource_url( 'admin-log-controls.js', false, 'common' ),
107
+ array( 'jquery' ),
108
+ Tribe__Main::VERSION,
109
+ true
110
+ );
111
+ }
112
+
113
+ /**
114
+ * Adds a script to handle the event log settings.
115
+ */
116
+ protected function setup_script() {
117
+ wp_enqueue_script( 'tribe-common-logging-controls' );
118
+ wp_localize_script( 'tribe-common-logging-controls', 'tribe_logger_data', array(
119
+ 'check' => wp_create_nonce( 'logging-controls' )
120
+ ) );
121
+ }
122
+
123
+ /**
124
+ * Returns a list of logs that are available for perusal.
125
+ *
126
+ * @return array
127
+ */
128
+ protected function get_available_logs() {
129
+ $available_logs = $this->current_logger()->list_available_logs();
130
+
131
+ if ( empty( $available_logs ) ) {
132
+ return array( '' => _x( 'None currently available', 'log selector', 'tribe-common' ) );
133
+ }
134
+
135
+ return $available_logs;
136
+ }
137
+
138
+ /**
139
+ * Returns a list of logging engines that are available for use.
140
+ *
141
+ * @return array
142
+ */
143
+ protected function get_log_engines(){
144
+ $available_engines = $this->log_manager()->get_logging_engines();
145
+
146
+ if ( empty( $available_engines ) ) {
147
+ return array( '' => _x( 'None currently available', 'log engines', 'tribe-common' ) );
148
+ }
149
+
150
+ $engine_list = array();
151
+
152
+ foreach ( $available_engines as $class_name => $engine ) {
153
+ /**
154
+ * @var Tribe__Log__Logger $engine
155
+ */
156
+ $engine_list[ $class_name ] = $engine->get_name();
157
+ }
158
+
159
+ return $engine_list;
160
+ }
161
+
162
+ /**
163
+ * Returns all log entries for the current or specified log.
164
+ *
165
+ * @return array
166
+ */
167
+ protected function get_log_entries( $log = null ) {
168
+ $logger = $this->current_logger();
169
+ $logger->use_log( $log );
170
+ return $logger->retrieve();
171
+ }
172
+
173
+ /**
174
+ * Returns an array of logging levels arranged as key:value pairs, with
175
+ * each key being the level code and the value being the human-friendly
176
+ * description.
177
+ *
178
+ * @return array
179
+ */
180
+ protected function get_logging_levels() {
181
+ $levels = array();
182
+ $available_levels = $this->log_manager()->get_logging_levels();
183
+
184
+ foreach ( $available_levels as $logging_level ) {
185
+ $levels[ $logging_level[0] ] = $logging_level[1];
186
+ }
187
+
188
+ return $levels;
189
+ }
190
+
191
+ /**
192
+ * Provides a URL that can be used to download the current or specified
193
+ * log.
194
+ *
195
+ * @param $log
196
+ *
197
+ * @return string
198
+ */
199
+ protected function get_log_url( $log = null ) {
200
+ $query = array(
201
+ 'tribe-common-log' => 'download',
202
+ 'check' => wp_create_nonce( 'download_log' )
203
+ );
204
+
205
+ $log_download_url = add_query_arg( $query, get_admin_url( null, 'edit.php' ) );
206
+
207
+ return esc_url( $log_download_url );
208
+ }
209
+
210
+ /**
211
+ * Facilitate downloading of logs.
212
+ */
213
+ public function serve_log_downloads() {
214
+ if ( empty( $_GET['tribe-common-log'] ) || 'download' !== $_GET['tribe-common-log'] ) {
215
+ return;
216
+ }
217
+
218
+ if ( ! wp_verify_nonce( @$_GET['check'], 'download_log' ) ) {
219
+ return;
220
+ }
221
+
222
+ if ( empty( $_GET['log'] ) || ! in_array( $_GET['log'], $this->get_available_logs() ) ) {
223
+ return;
224
+ }
225
+
226
+ $log_name = sanitize_file_name( $_GET['log'] );
227
+ $this->current_logger()->use_log( $log_name );
228
+
229
+ /**
230
+ * Provides an opportunity to modify the recommended filename for a downloaded
231
+ * log file.
232
+ *
233
+ * @param string $log_name
234
+ */
235
+ $log_name = apply_filters( 'tribe_common_log_download_filename', $log_name );
236
+
237
+ header( 'Content-Disposition: attachment; filename="tribe-log-' . $log_name . '"' );
238
+ $output = fopen( 'php://output', 'w' );
239
+
240
+ foreach ( $this->current_logger()->retrieve() as $log_entry ) {
241
+ fputcsv( $output, $log_entry );
242
+ }
243
+
244
+ fclose( $output );
245
+ exit();
246
+ }
247
+
248
+ /**
249
+ * Returns a reference to the main log management object.
250
+ *
251
+ * @return Tribe__Log
252
+ */
253
+ protected function log_manager() {
254
+ return Tribe__Main::instance()->log();
255
+ }
256
+
257
+ /**
258
+ * Returns the currently enabled logging object or null if it is not
259
+ * available.
260
+ *
261
+ * @return Tribe__Log__Logger|null
262
+ */
263
+ protected function current_logger() {
264
+ return Tribe__Main::instance()->log()->get_current_logger();
265
+ }
266
  }
common/src/Tribe/Log/File_Logger.php CHANGED
@@ -1,265 +1,265 @@
1
- <?php
2
- /**
3
- * Simple file based logging implementation.
4
- *
5
- * By default, this logger uses the system temporary directory for logging
6
- * purposes and performs daily log rotation.
7
- */
8
- class Tribe__Log__File_Logger implements Tribe__Log__Logger {
9
- protected $module_id = 'tribe_tmp_file_logger';
10
- protected $log_dir = '';
11
- protected $log_file = '';
12
- protected $context = 'a';
13
- protected $handle;
14
-
15
- public function __construct() {
16
- $this->set_log_dir();
17
- $this->set_log_file();
18
- }
19
-
20
- public function __destruct() {
21
- $this->close_handle();
22
- }
23
-
24
- protected function set_log_dir() {
25
- /**
26
- * Controls the directory used for logging.
27
- *
28
- * @var string $log_dir
29
- */
30
- $this->log_dir = apply_filters( 'tribe_file_logger_directory', sys_get_temp_dir() );
31
- }
32
-
33
- /**
34
- * Sets the path for the log file we're currently interested in using.
35
- *
36
- * @param string $date = null
37
- */
38
- protected function set_log_file( $date = null ) {
39
- $this->log_file = $this->get_log_file_name( $date );
40
- $this->obtain_handle();
41
- }
42
-
43
- /**
44
- * Used to switch between contexts for reading ('r') and writing
45
- * ('a' := append) modes.
46
- *
47
- * @see fopen() documentation
48
- *
49
- * @param string $context
50
- */
51
- protected function set_context( $context ) {
52
- $this->context = $context;
53
- $this->close_handle();
54
- $this->obtain_handle();
55
- }
56
-
57
- /**
58
- * Attempts to obtain a file handle for the current log file.
59
- */
60
- protected function obtain_handle() {
61
- $this->close_handle();
62
- $this->handle = fopen( $this->log_file, $this->context );
63
- }
64
-
65
- /**
66
- * Closes the current file handle, if one is open.
67
- */
68
- protected function close_handle() {
69
- // is_resource() only returns true for open resources
70
- if ( is_resource( $this->handle ) ) {
71
- fclose( $this->handle );
72
- }
73
- }
74
-
75
- /**
76
- * Returns the log name to be used for reading/writing events for a specified date
77
- * (defaulting to today, if no date is specified).
78
- *
79
- * @param string $date = null
80
- *
81
- * @return string
82
- */
83
- protected function get_log_file_name( $date = null ) {
84
- if ( null === $date ) {
85
- $date = date_i18n( 'Y-m-d' );
86
- }
87
-
88
- $filename = $this->log_dir . DIRECTORY_SEPARATOR . $this->get_log_file_basename() . $date . '.log';
89
-
90
- /**
91
- * Dictates the filename of the log used to record events for the specified date.
92
- *
93
- * @var string $filename
94
- * @var string $date
95
- */
96
- return apply_filters( 'tribe_file_logger_filename', $filename, $date );
97
- }
98
-
99
- protected function get_log_file_basename() {
100
- /**
101
- * Log files share a common prefix, which aids identifying archived/rotated logs.
102
- * This filter allows a degree of control to be exercised over the prefix to avoid
103
- * conflicts, etc.
104
- *
105
- * @var string $log_file_base_name
106
- */
107
- return apply_filters( 'tribe_file_logger_file_prefix', $this->module_id . '_' );
108
- }
109
-
110
- /**
111
- * Returns a 'human friendly' name for the logging implementation.
112
- *
113
- * @return string
114
- */
115
- public function get_name() {
116
- return __( 'Default (uses temporary files)', 'tribe-common' );
117
- }
118
-
119
- /**
120
- * Indicates if the logger will work in the current environment.
121
- *
122
- * @return bool
123
- */
124
- public function is_available() {
125
- return is_writable( $this->log_dir ) && is_readable( $this->log_dir );
126
- }
127
-
128
- /**
129
- * Responsible for commiting the entry to the log.
130
- *
131
- * @param string $entry
132
- * @param string $type
133
- * @param string $src
134
- */
135
- public function log( $entry, $type = Tribe__Log::DEBUG, $src = '' ) {
136
- // Ensure we're in 'append' mode before we try to write
137
- if ( 'a' !== $this->context ) {
138
- $this->set_context( 'a' );
139
- }
140
-
141
- fputcsv( $this->handle, array( date_i18n( 'Y-m-d H:i:s' ), $entry, $type, $src ) );
142
- }
143
-
144
- /**
145
- * Retrieve up to $limit most recent log entries in reverse chronological
146
- * order. If $limit is a negative or zero value, there is no limit.
147
- *
148
- * Supports passing a 'log' argument to recover
149
- *
150
- * @see Tribe__Log__Logger::list_available_logs()
151
- *
152
- * @param int $limit
153
- * @param array $args
154
- *
155
- * @return array
156
- */
157
- public function retrieve( $limit = 0, array $args = array() ) {
158
- // Ensure we're in 'read' mode before we try to retrieve
159
- if ( 'r' !== $this->context ) {
160
- $this->set_context( 'r' );
161
- }
162
-
163
- $rows = array();
164
-
165
- while ( $current_row = fgetcsv( $this->handle ) ) {
166
- if ( $limit && $limit === count( $rows ) ) {
167
- array_shift( $rows );
168
- }
169
-
170
- $rows[] = $current_row;
171
- }
172
-
173
- return array_reverse( $rows );
174
- }
175
-
176
- /**
177
- * Returns a list of currently accessible logs (current first, oldest last).
178
- * Each is refered to by date.
179
- *
180
- * Example:
181
- *
182
- * [ '2016-12-31',
183
- * '2016-12-30',
184
- * '2016-12-30',
185
- * '2016-12-30',
186
- * '2016-12-30', ... ]
187
- *
188
- * @return array
189
- */
190
- public function list_available_logs() {
191
- $logs = array();
192
- $basename = $this->get_log_file_basename();
193
-
194
- // Look through the log storage directory
195
- foreach ( new DirectoryIterator( $this->log_dir ) as $node ) {
196
- $name = $node->getFilename();
197
-
198
- // Skip unless it is a .log file with the expected prefix
199
- if ( 'log' !== $node->getExtension() || 0 !== strpos( $name, $basename ) ) {
200
- continue;
201
- }
202
-
203
- if ( preg_match( '/([0-9]{4}\-[0-9]{2}\-[0-9]{2})/', $name, $matches ) ) {
204
- $logs[] = $matches[1];
205
- }
206
- }
207
-
208
- rsort( $logs );
209
- return $logs;
210
- }
211
-
212
- /**
213
- * Switches to the specified log. The $log_identifier should take the
214
- * form of a "yyyy-mm-dd" format date string.
215
- *
216
- * If optional param $create is true then it will try to create a log
217
- * using the provided identifier. If the log does not exist, cannot be
218
- * created or an invalid identifier has been passed in then boolean false
219
- * will be returned, otherwise it will attempt to switch to the new log.
220
- *
221
- * @param mixed $log_identifier
222
- * @param bool $create
223
- *
224
- * @return bool
225
- */
226
- public function use_log( $log_identifier, $create = false ) {
227
- $log_file = $this->get_log_file_name( $log_identifier );
228
- $exists = file_exists( $log_file );
229
-
230
- if ( ! $exists && ! $create ) {
231
- return false;
232
- }
233
-
234
- if ( ! $exists && $create && preg_match( '/^([0-9]{4}\-[0-9]{2}\-[0-9]{2})$/', $log_file ) ) {
235
- if ( false === file_put_contents( $log_file, '' ) ) {
236
- return false;
237
- }
238
- }
239
-
240
- $this->set_log_file( $log_identifier );
241
- return true;
242
- }
243
-
244
- /**
245
- * Performs routine maintenance and cleanup work (such as log rotation)
246
- * whenever it is called.
247
- */
248
- public function cleanup() {
249
- // Default to retaining 7 days worth of logs
250
- $cutoff = date_i18n( 'Y-m-d', current_time( 'timestamp' ) - WEEK_IN_SECONDS );
251
-
252
- /**
253
- * Logs falling on or earlier than this date will be removed.
254
- *
255
- * @param string $cutoff 'Y-m-d' format date string
256
- */
257
- $cutoff = apply_filters( 'tribe_file_logger_cutoff', $cutoff );
258
-
259
- foreach ( $this->list_available_logs() as $available_log ) {
260
- if ( $available_log <= $cutoff ) {
261
- unlink( $this->get_log_file_name( $available_log ) );
262
- }
263
- }
264
- }
265
  }
1
+ <?php
2
+ /**
3
+ * Simple file based logging implementation.
4
+ *
5
+ * By default, this logger uses the system temporary directory for logging
6
+ * purposes and performs daily log rotation.
7
+ */
8
+ class Tribe__Log__File_Logger implements Tribe__Log__Logger {
9
+ protected $module_id = 'tribe_tmp_file_logger';
10
+ protected $log_dir = '';
11
+ protected $log_file = '';
12
+ protected $context = 'a';
13
+ protected $handle;
14
+
15
+ public function __construct() {
16
+ $this->set_log_dir();
17
+ $this->set_log_file();
18
+ }
19
+
20
+ public function __destruct() {
21
+ $this->close_handle();
22
+ }
23
+
24
+ protected function set_log_dir() {
25
+ /**
26
+ * Controls the directory used for logging.
27
+ *
28
+ * @var string $log_dir
29
+ */
30
+ $this->log_dir = apply_filters( 'tribe_file_logger_directory', sys_get_temp_dir() );
31
+ }
32
+
33
+ /**
34
+ * Sets the path for the log file we're currently interested in using.
35
+ *
36
+ * @param string $date = null
37
+ */
38
+ protected function set_log_file( $date = null ) {
39
+ $this->log_file = $this->get_log_file_name( $date );
40
+ $this->obtain_handle();
41
+ }
42
+
43
+ /**
44
+ * Used to switch between contexts for reading ('r') and writing
45
+ * ('a' := append) modes.
46
+ *
47
+ * @see fopen() documentation
48
+ *
49
+ * @param string $context
50
+ */
51
+ protected function set_context( $context ) {
52
+ $this->context = $context;
53
+ $this->close_handle();
54
+ $this->obtain_handle();
55
+ }
56
+
57
+ /**
58
+ * Attempts to obtain a file handle for the current log file.
59
+ */
60
+ protected function obtain_handle() {
61
+ $this->close_handle();
62
+ $this->handle = fopen( $this->log_file, $this->context );
63
+ }
64
+
65
+ /**
66
+ * Closes the current file handle, if one is open.
67
+ */
68
+ protected function close_handle() {
69
+ // is_resource() only returns true for open resources
70
+ if ( is_resource( $this->handle ) ) {
71
+ fclose( $this->handle );
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Returns the log name to be used for reading/writing events for a specified date
77
+ * (defaulting to today, if no date is specified).
78
+ *
79
+ * @param string $date = null
80
+ *
81
+ * @return string
82
+ */
83
+ protected function get_log_file_name( $date = null ) {
84
+ if ( null === $date ) {
85
+ $date = date_i18n( 'Y-m-d' );
86
+ }
87
+
88
+ $filename = $this->log_dir . DIRECTORY_SEPARATOR . $this->get_log_file_basename() . $date . '.log';
89
+
90
+ /**
91
+ * Dictates the filename of the log used to record events for the specified date.
92
+ *
93
+ * @var string $filename
94
+ * @var string $date
95
+ */
96
+ return apply_filters( 'tribe_file_logger_filename', $filename, $date );
97
+ }
98
+
99
+ protected function get_log_file_basename() {
100
+ /**
101
+ * Log files share a common prefix, which aids identifying archived/rotated logs.
102
+ * This filter allows a degree of control to be exercised over the prefix to avoid
103
+ * conflicts, etc.
104
+ *
105
+ * @var string $log_file_base_name
106
+ */
107
+ return apply_filters( 'tribe_file_logger_file_prefix', $this->module_id . '_' );
108
+ }
109
+
110
+ /**
111
+ * Returns a 'human friendly' name for the logging implementation.
112
+ *
113
+ * @return string
114
+ */
115
+ public function get_name() {
116
+ return __( 'Default (uses temporary files)', 'tribe-common' );
117
+ }
118
+
119
+ /**
120
+ * Indicates if the logger will work in the current environment.
121
+ *
122
+ * @return bool
123
+ */
124
+ public function is_available() {
125
+ return is_writable( $this->log_dir ) && is_readable( $this->log_dir );
126
+ }
127
+
128
+ /**
129
+ * Responsible for commiting the entry to the log.
130
+ *
131
+ * @param string $entry
132
+ * @param string $type
133
+ * @param string $src
134
+ */
135
+ public function log( $entry, $type = Tribe__Log::DEBUG, $src = '' ) {
136
+ // Ensure we're in 'append' mode before we try to write
137
+ if ( 'a' !== $this->context ) {
138
+ $this->set_context( 'a' );
139
+ }
140
+
141
+ fputcsv( $this->handle, array( date_i18n( 'Y-m-d H:i:s' ), $entry, $type, $src ) );
142
+ }
143
+
144
+ /**
145
+ * Retrieve up to $limit most recent log entries in reverse chronological
146
+ * order. If $limit is a negative or zero value, there is no limit.
147
+ *
148
+ * Supports passing a 'log' argument to recover
149
+ *
150
+ * @see Tribe__Log__Logger::list_available_logs()
151
+ *
152
+ * @param int $limit
153
+ * @param array $args
154
+ *
155
+ * @return array
156
+ */
157
+ public function retrieve( $limit = 0, array $args = array() ) {
158
+ // Ensure we're in 'read' mode before we try to retrieve
159
+ if ( 'r' !== $this->context ) {
160
+ $this->set_context( 'r' );
161
+ }
162
+
163
+ $rows = array();
164
+
165
+ while ( $current_row = fgetcsv( $this->handle ) ) {
166
+ if ( $limit && $limit === count( $rows ) ) {
167
+ array_shift( $rows );
168
+ }
169
+
170
+ $rows[] = $current_row;
171
+ }
172
+
173
+ return array_reverse( $rows );
174
+ }
175
+
176
+ /**
177
+ * Returns a list of currently accessible logs (current first, oldest last).
178
+ * Each is refered to by date.
179
+ *
180
+ * Example:
181
+ *
182
+ * [ '2016-12-31',
183
+ * '2016-12-30',
184
+ * '2016-12-30',
185
+ * '2016-12-30',
186
+ * '2016-12-30', ... ]
187
+ *
188
+ * @return array
189
+ */
190
+ public function list_available_logs() {
191
+ $logs = array();
192
+ $basename = $this->get_log_file_basename();
193
+
194
+ // Look through the log storage directory
195
+ foreach ( new DirectoryIterator( $this->log_dir ) as $node ) {
196
+ $name = $node->getFilename();
197
+
198
+ // Skip unless it is a .log file with the expected prefix
199
+ if ( 'log' !== $node->getExtension() || 0 !== strpos( $name, $basename ) ) {
200
+ continue;
201
+ }
202
+
203
+ if ( preg_match( '/([0-9]{4}\-[0-9]{2}\-[0-9]{2})/', $name, $matches ) ) {
204
+ $logs[] = $matches[1];
205
+ }
206
+ }
207
+
208
+ rsort( $logs );
209
+ return $logs;
210
+ }
211
+
212
+ /**
213
+ * Switches to the specified log. The $log_identifier should take the
214
+ * form of a "yyyy-mm-dd" format date string.
215
+ *
216
+ * If optional param $create is true then it will try to create a log
217
+ * using the provided identifier. If the log does not exist, cannot be
218
+ * created or an invalid identifier has been passed in then boolean false
219
+ * will be returned, otherwise it will attempt to switch to the new log.
220
+ *
221
+ * @param mixed $log_identifier
222
+ * @param bool $create
223
+ *
224
+ * @return bool
225
+ */
226
+ public function use_log( $log_identifier, $create = false ) {
227
+ $log_file = $this->get_log_file_name( $log_identifier );
228
+ $exists = file_exists( $log_file );
229
+
230
+ if ( ! $exists && ! $create ) {
231
+ return false;
232
+ }
233
+
234
+ if ( ! $exists && $create && preg_match( '/^([0-9]{4}\-[0-9]{2}\-[0-9]{2})$/', $log_file ) ) {
235
+ if ( false === file_put_contents( $log_file, '' ) ) {
236
+ return false;
237
+ }
238
+ }
239
+
240
+ $this->set_log_file( $log_identifier );
241
+ return true;
242
+ }
243
+
244
+ /**
245
+ * Performs routine maintenance and cleanup work (such as log rotation)
246
+ * whenever it is called.
247
+ */
248
+ public function cleanup() {
249
+ // Default to retaining 7 days worth of logs
250
+ $cutoff = date_i18n( 'Y-m-d', current_time( 'timestamp' ) - WEEK_IN_SECONDS );
251
+
252
+ /**
253
+ * Logs falling on or earlier than this date will be removed.
254
+ *
255
+ * @param string $cutoff 'Y-m-d' format date string
256
+ */
257
+ $cutoff = apply_filters( 'tribe_file_logger_cutoff', $cutoff );
258
+
259
+ foreach ( $this->list_available_logs() as $available_log ) {
260
+ if ( $available_log <= $cutoff ) {
261
+ unlink( $this->get_log_file_name( $available_log ) );
262
+ }
263
+ }
264
+ }
265
  }
common/src/Tribe/Log/Logger.php CHANGED
@@ -1,88 +1,88 @@
1
- <?php
2
- /**
3
- * Specifies the minimal interface required of all logging implementations.
4
- */
5
- interface Tribe__Log__Logger {
6
- /**
7
- * Indicates if the logger will work in the current environment.
8
- *
9
- * @return bool
10
- */
11
- public function is_available();
12
-
13
- /**
14
- * Returns a 'human friendly' name for the logging implementation.
15
- *
16
- * @return string
17
- */
18
- public function get_name();
19
-
20
- /**
21
- * Responsible for commiting the entry to the log (but only if the debug level
22
- * is appropriate).
23
- *
24
- * @param string $entry
25
- * @param string $type
26
- * @param string $src
27
- */
28
- public function log( $entry, $type = Tribe__Log::DEBUG, $src = '' );
29
-
30
- /**
31
- * Retrieve up to $limit most recent log entries in reverse chronological
32
- * order. If $limit is a negative or zero value, there is no limit.
33
- *
34
- * Implementation-specific arguments can optionally be provided as a second
35
- * parameter. This may include support for a 'log' param where an identifer
36
- * obtained via the list_availalbe_logs() method is passed in order to query
37
- * a specific archived log.
38
- *
39
- * @see Tribe__Log__Logger::list_available_logs()
40
- *
41
- * @param int $limit
42
- * @param array $args
43
- *
44
- * @return array
45
- */
46
- public function retrieve( $limit = 0, array $args = array() );
47
-
48
- /**
49
- * Returns a list of currently accessible logs (current first, oldest last).
50
- *
51
- * This can be useful if, for instance, a particular logger organizes logging
52
- * by dates and keeps an archive of upto 1 week's worth of logs - in which case
53
- * the array might look like:
54
- *
55
- * [ '2016-12-31',
56
- * '2016-12-30',
57
- * '2016-12-30',
58
- * '2016-12-30',
59
- * '2016-12-30', ... ]
60
- *
61
- * Note that a) the array may be empty and b) it won't necessarily contain
62
- * date strings, it could contain identifiers like 'current', 'prev', 'prev2'
63
- * or really anything the logging engine prefers.
64
- *
65
- * @return array
66
- */
67
- public function list_available_logs();
68
-
69
- /**
70
- * Switches to the specified log.
71
- *
72
- * If optional param $create is true the logger will try to create a new log
73
- * using the provided identifier if it doesn't already exist.
74
- *
75
- * @param mixed $log_identifier
76
- * @param bool $create
77
- *
78
- * @return bool
79
- */
80
- public function use_log( $log_identifier, $create = false );
81
-
82
-
83
- /**
84
- * Performs routine maintenance and cleanup work (such as log rotation)
85
- * whenever it is called.
86
- */
87
- public function cleanup();
88
  }
1
+ <?php
2
+ /**
3
+ * Specifies the minimal interface required of all logging implementations.
4
+ */
5
+ interface Tribe__Log__Logger {
6
+ /**
7
+ * Indicates if the logger will work in the current environment.
8
+ *
9
+ * @return bool
10
+ */
11
+ public function is_available();
12
+
13
+ /**
14
+ * Returns a 'human friendly' name for the logging implementation.
15
+ *
16
+ * @return string
17
+ */
18
+ public function get_name();
19
+
20
+ /**
21
+ * Responsible for commiting the entry to the log (but only if the debug level
22
+ * is appropriate).
23
+ *
24
+ * @param string $entry
25
+ * @param string $type
26
+ * @param string $src
27
+ */
28
+ public function log( $entry, $type = Tribe__Log::DEBUG, $src = '' );
29
+
30
+ /**
31
+ * Retrieve up to $limit most recent log entries in reverse chronological
32
+ * order. If $limit is a negative or zero value, there is no limit.
33
+ *
34
+ * Implementation-specific arguments can optionally be provided as a second
35
+ * parameter. This may include support for a 'log' param where an identifer
36
+ * obtained via the list_availalbe_logs() method is passed in order to query
37
+ * a specific archived log.
38
+ *
39
+ * @see Tribe__Log__Logger::list_available_logs()
40
+ *
41
+ * @param int $limit
42
+ * @param array $args
43
+ *
44
+ * @return array
45
+ */
46
+ public function retrieve( $limit = 0, array $args = array() );
47
+
48
+ /**
49
+ * Returns a list of currently accessible logs (current first, oldest last).
50
+ *
51
+ * This can be useful if, for instance, a particular logger organizes logging
52
+ * by dates and keeps an archive of upto 1 week's worth of logs - in which case
53
+ * the array might look like:
54
+ *
55
+ * [ '2016-12-31',
56
+ * '2016-12-30',
57
+ * '2016-12-30',
58
+ * '2016-12-30',
59
+ * '2016-12-30', ... ]
60
+ *
61
+ * Note that a) the array may be empty and b) it won't necessarily contain
62
+ * date strings, it could contain identifiers like 'current', 'prev', 'prev2'
63
+ * or really anything the logging engine prefers.
64
+ *
65
+ * @return array
66
+ */
67
+ public function list_available_logs();
68
+
69
+ /**
70
+ * Switches to the specified log.
71
+ *
72
+ * If optional param $create is true the logger will try to create a new log
73
+ * using the provided identifier if it doesn't already exist.
74
+ *
75
+ * @param mixed $log_identifier
76
+ * @param bool $create
77
+ *
78
+ * @return bool
79
+ */
80
+ public function use_log( $log_identifier, $create = false );
81
+
82
+
83
+ /**
84
+ * Performs routine maintenance and cleanup work (such as log rotation)
85
+ * whenever it is called.
86
+ */
87
+ public function cleanup();
88
  }
common/src/Tribe/Log/Null_Logger.php CHANGED
@@ -1,106 +1,106 @@
1
- <?php
2
-
3
-
4
- /**
5
- * Class Null_Logger
6
- *
7
- * Logs nothing, reads nothing.
8
- */
9
- class Tribe__Log__Null_Logger implements Tribe__Log__Logger{
10
-
11
- /**
12
- * Indicates if the logger will work in the current environment.
13
- *
14
- * @return bool
15
- */
16
- public function is_available() {
17
- return true;
18
- }
19
-
20
- /**
21
- * Returns a 'human friendly' name for the logging implementation.
22
- *
23
- * @return string
24
- */
25
- public function get_name() {
26
- return __( 'Null logger (will log nothing)', 'tribe-common' );
27
- }
28
-
29
- /**
30
- * Responsible for commiting the entry to the log (but only if the debug level
31
- * is appropriate).
32
- *
33
- * @param string $entry
34
- * @param string $type
35
- * @param string $src
36
- */
37
- public function log( $entry, $type = Tribe__Log::DEBUG, $src = '' ) {
38
- // no-op
39
- }
40
-
41
- /**
42
- * Retrieve up to $limit most recent log entries in reverse chronological
43
- * order. If $limit is a negative or zero value, there is no limit.
44
- *
45
- * Implementation-specific arguments can optionally be provided as a second
46
- * parameter. This may include support for a 'log' param where an identifer
47
- * obtained via the list_availalbe_logs() method is passed in order to query
48
- * a specific archived log.
49
- *
50
- * @see Tribe__Log__Logger::list_available_logs()
51
- *
52
- * @param int $limit
53
- * @param array $args
54
- *
55
- * @return array
56
- */
57
- public function retrieve( $limit = 0, array $args = array() ) {
58
- return array();
59
- }
60
-
61
- /**
62
- * Returns a list of currently accessible logs (current first, oldest last).
63
- *
64
- * This can be useful if, for instance, a particular logger organizes logging
65
- * by dates and keeps an archive of upto 1 week's worth of logs - in which case
66
- * the array might look like:
67
- *
68
- * [ '2016-12-31',
69
- * '2016-12-30',
70
- * '2016-12-30',
71
- * '2016-12-30',
72
- * '2016-12-30', ... ]
73
- *
74
- * Note that a) the array may be empty and b) it won't necessarily contain
75
- * date strings, it could contain identifiers like 'current', 'prev', 'prev2'
76
- * or really anything the logging engine prefers.
77
- *
78
- * @return array
79
- */
80
- public function list_available_logs() {
81
- return array();
82
- }
83
-
84
- /**
85
- * Switches to the specified log.
86
- *
87
- * If optional param $create is true the logger will try to create a new log
88
- * using the provided identifier if it doesn't already exist.
89
- *
90
- * @param mixed $log_identifier
91
- * @param bool $create
92
- *
93
- * @return bool
94
- */
95
- public function use_log( $log_identifier, $create = false ) {
96
- // no-op
97
- }
98
-
99
- /**
100
- * Performs routine maintenance and cleanup work (such as log rotation)
101
- * whenever it is called.
102
- */
103
- public function cleanup() {
104
- // no-op
105
- }
106
  }
1
+ <?php
2
+
3
+
4
+ /**
5
+ * Class Null_Logger
6
+ *
7
+ * Logs nothing, reads nothing.
8
+ */
9
+ class Tribe__Log__Null_Logger implements Tribe__Log__Logger{
10
+
11
+ /**
12
+ * Indicates if the logger will work in the current environment.
13
+ *
14
+ * @return bool
15
+ */
16
+ public function is_available() {
17
+ return true;
18
+ }
19
+
20
+ /**
21
+ * Returns a 'human friendly' name for the logging implementation.
22
+ *
23
+ * @return string
24
+ */
25
+ public function get_name() {
26
+ return __( 'Null logger (will log nothing)', 'tribe-common' );
27
+ }
28
+
29
+ /**
30
+ * Responsible for commiting the entry to the log (but only if the debug level
31
+ * is appropriate).
32
+ *
33
+ * @param string $entry
34
+ * @param string $type
35
+ * @param string $src
36
+ */
37
+ public function log( $entry, $type = Tribe__Log::DEBUG, $src = '' ) {
38
+ // no-op
39
+ }
40
+
41
+ /**
42
+ * Retrieve up to $limit most recent log entries in reverse chronological
43
+ * order. If $limit is a negative or zero value, there is no limit.
44
+ *
45
+ * Implementation-specific arguments can optionally be provided as a second
46
+ * parameter. This may include support for a 'log' param where an identifer
47
+ * obtained via the list_availalbe_logs() method is passed in order to query
48
+ * a specific archived log.
49
+ *
50
+ * @see Tribe__Log__Logger::list_available_logs()
51
+ *
52
+ * @param int $limit
53
+ * @param array $args
54
+ *
55
+ * @return array
56
+ */
57
+ public function retrieve( $limit = 0, array $args = array() ) {
58
+ return array();
59
+ }
60
+
61
+ /**
62
+ * Returns a list of currently accessible logs (current first, oldest last).
63
+ *
64
+ * This can be useful if, for instance, a particular logger organizes logging
65
+ * by dates and keeps an archive of upto 1 week's worth of logs - in which case
66
+ * the array might look like:
67
+ *
68
+ * [ '2016-12-31',
69
+ * '2016-12-30',
70
+ * '2016-12-30',
71
+ * '2016-12-30',
72
+ * '2016-12-30', ... ]
73
+ *
74
+ * Note that a) the array may be empty and b) it won't necessarily contain
75
+ * date strings, it could contain identifiers like 'current', 'prev', 'prev2'
76
+ * or really anything the logging engine prefers.
77
+ *
78
+ * @return array
79
+ */
80
+ public function list_available_logs() {
81
+ return array();
82
+ }
83
+
84
+ /**
85
+ * Switches to the specified log.
86
+ *
87
+ * If optional param $create is true the logger will try to create a new log
88
+ * using the provided identifier if it doesn't already exist.
89
+ *
90
+ * @param mixed $log_identifier
91
+ * @param bool $create
92
+ *
93
+ * @return bool
94
+ */
95
+ public function use_log( $log_identifier, $create = false ) {
96
+ // no-op
97
+ }
98
+
99
+ /**
100
+ * Performs routine maintenance and cleanup work (such as log rotation)
101
+ * whenever it is called.
102
+ */
103
+ public function cleanup() {
104
+ // no-op
105
+ }
106
  }
common/src/Tribe/Main.php CHANGED
@@ -1,339 +1,339 @@
1
- <?php
2
- /**
3
- * Main Tribe Common class.
4
- */
5
-
6
- // Don't load directly
7
- if ( ! defined( 'ABSPATH' ) ) {
8
- die( '-1' );
9
- }
10
-
11
- if ( class_exists( 'Tribe__Main' ) ) {
12
- return;
13
- }
14
-
15
- class Tribe__Main {
16
- const EVENTSERROROPT = '_tribe_events_errors';
17
- const OPTIONNAME = 'tribe_events_calendar_options';
18
- const OPTIONNAMENETWORK = 'tribe_events_calendar_network_options';
19
-
20
- const VERSION = '4.2.6';
21
- const FEED_URL = 'https://theeventscalendar.com/feed/';
22
-
23
- protected $plugin_context;
24
- protected $plugin_context_class;
25
- protected $doing_ajax = false;
26
- protected $log;
27
-
28
- public static $tribe_url = 'http://tri.be/';
29
- public static $tec_url = 'http://theeventscalendar.com/';
30
-
31
- public $plugin_dir;
32
- public $plugin_path;
33
- public $plugin_url;
34
-
35
- /**
36
- * constructor
37
- */
38
- public function __construct( $context = null ) {
39
- if ( is_object( $context ) ) {
40
- $this->plugin_context = $context;
41
- $this->plugin_context_class = get_class( $context );
42
- }
43
-
44
- $this->plugin_path = trailingslashit( dirname( dirname( dirname( __FILE__ ) ) ) );
45
- $this->plugin_dir = trailingslashit( basename( $this->plugin_path ) );
46
- $this->plugin_url = plugins_url( $this->plugin_dir );
47
-
48
- $this->load_text_domain( 'tribe-common', basename( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) ) . '/common/lang/' );
49
-
50
- $this->init_autoloading();
51
-
52
- $this->init_libraries();
53
- $this->add_hooks();
54
-
55
- $this->doing_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX;
56
- }
57
-
58
- /**
59
- * Get's the instantiated context of this class. I.e. the object that instantiated this one.
60
- */
61
- public function context() {
62
- return $this->plugin_context;
63
- }
64
-
65
- /**
66
- * Setup the autoloader for common files
67
- */
68
- protected function init_autoloading() {
69
- if ( ! class_exists( 'Tribe__Autoloader' ) ) {
70
- require_once dirname( __FILE__ ) . '/Autoloader.php';
71
- }
72
-
73
- $prefixes = array( 'Tribe__' => dirname( __FILE__ ) );
74
- $autoloader = Tribe__Autoloader::instance();
75
- $autoloader->register_prefixes( $prefixes );
76
- $autoloader->register_autoloader();
77
- }
78
-
79
- /**
80
- * Get's the class name of the instantiated plugin context of this class. I.e. the class name of the object that instantiated this one.
81
- */
82
- public function context_class() {
83
- return $this->plugin_context_class;
84
- }
85
-
86
- /**
87
- * initializes all required libraries
88
- */
89
- public function init_libraries() {
90
- Tribe__Debug::instance();
91
- Tribe__Settings_Manager::instance();
92
-
93
- require_once $this->plugin_path . 'src/functions/utils.php';
94
- require_once $this->plugin_path . 'src/functions/template-tags/general.php';
95
- require_once $this->plugin_path . 'src/functions/template-tags/date.php';
96
-
97
- // Starting the log manager needs to wait until after the tribe_*_option() functions have loaded
98
- $this->log = new Tribe__Log();
99
- }
100
-
101
- /**
102
- * Registers resources that can/should be enqueued
103
- */
104
- public function register_resources() {
105
- $resources_url = plugins_url( 'src/resources', dirname( dirname( __FILE__ ) ) );
106
-
107
- wp_register_style(
108
- 'tribe-common-admin',
109
- $resources_url . '/css/tribe-common-admin.css',
110
- array(),
111
- apply_filters( 'tribe_events_css_version', self::VERSION )
112
- );
113
-
114
- wp_register_script(
115
- 'ba-dotimeout',
116
- $resources_url . '/js/jquery.ba-dotimeout.js',
117
- array(
118
- 'jquery',
119
- ),
120
- apply_filters( 'tribe_events_css_version', self::VERSION ),
121
- true
122
- );
123
-
124
- wp_register_script(
125
- 'tribe-inline-bumpdown',
126
- $resources_url . '/js/inline-bumpdown.js',
127
- array(
128
- 'ba-dotimeout',
129
- ),
130
- apply_filters( 'tribe_events_css_version', self::VERSION ),
131
- true
132
- );
133
-
134
- wp_register_script(
135
- 'tribe-notice-dismiss',
136
- $resources_url . '/js/notice-dismiss.js',
137
- array( 'jquery' ),
138
- apply_filters( 'tribe_events_css_version', self::VERSION ),
139
- true
140
- );
141
- }
142
-
143
- /**
144
- * Registers vendor assets that can/should be enqueued
145
- */
146
- public function register_vendor() {
147
- $vendor_base = plugins_url( 'vendor', dirname( dirname( __FILE__ ) ) );
148
-
149
- wp_register_style(
150
- 'tribe-jquery-ui-theme',
151
- $vendor_base . '/jquery/ui.theme.css',
152
- array(),
153
- apply_filters( 'tribe_events_css_version', self::VERSION )
154
- );
155
-
156
- wp_register_style(
157
- 'tribe-jquery-ui-datepicker',
158
- $vendor_base . '/jquery/ui.datepicker.css',
159
- array( 'tribe-jquery-ui-theme' ),
160
- apply_filters( 'tribe_events_css_version', self::VERSION )
161
- );
162
-
163
- }
164
-
165
- /**
166
- * Adds core hooks
167
- */
168
- public function add_hooks() {
169
- add_action( 'plugins_loaded', array( 'Tribe__App_Shop', 'instance' ) );
170
-
171
- // Register for the assets to be availble everywhere
172
- add_action( 'init', array( $this, 'register_resources' ), 1 );
173
- add_action( 'init', array( $this, 'register_vendor' ), 1 );
174
-
175
- // Enqueue only when needed (admin)
176
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
177
- }
178
-
179
- /**
180
- * A Helper method to load text domain
181
- * First it tries to load the wp-content/languages translation then if falls to the
182
- * try to load $dir language files
183
- *
184
- * @param string $domain The text domain that will be loaded
185
- * @param string $dir What directory should be used to try to load if the default doenst work
186
- *
187
- * @return bool If it was able to load the text domain
188
- */
189
- public function load_text_domain( $domain, $dir = false ) {
190
- // Added safety just in case this runs twice...
191
- if ( is_textdomain_loaded( $domain ) && ! is_a( $GLOBALS['l10n'][ $domain ], 'NOOP_Translations' ) ) {
192
- return true;
193
- }
194
-
195
- $locale = get_locale();
196
- $mofile = WP_LANG_DIR . '/plugins/' . $domain . '-' . $locale . '.mo';
197
-
198
- /**
199
- * Allows users to filter which file will be loaded for a given text domain
200
- * Be careful when using this filter, it will apply across the whole plugin suite.
201
- *
202
- * @param string $mofile The path for the .mo File
203
- * @param string $domain Which plugin domain we are trying to load
204
- * @param string $locale Which Language we will load
205
- * @param string|bool $dir If there was a custom directory passed on the method call
206
- */
207
- $mofile = apply_filters( 'tribe_load_text_domain', $mofile, $domain, $locale, $dir );
208
-
209
- $loaded = load_plugin_textdomain( $domain, false, $mofile );
210
-
211
- if ( $dir !== false && ! $loaded ) {
212
- return load_plugin_textdomain( $domain, false, $dir );
213
- }
214
-
215
- return $loaded;
216
- }
217
-
218
- public function admin_enqueue_scripts() {
219
- wp_enqueue_script( 'tribe-inline-bumpdown' );
220
- wp_enqueue_script( 'tribe-notice-dismiss' );
221
- wp_enqueue_style( 'tribe-common-admin' );
222
-
223
- $helper = Tribe__Admin__Helpers::instance();
224
- if ( $helper->is_post_type_screen() ) {
225
- wp_enqueue_style( 'tribe-jquery-ui-datepicker' );
226
- }
227
- }
228
-
229
- /**
230
- * @return Tribe__Log
231
- */
232
- public function log() {
233
- return $this->log;
234
- }
235
-
236
- /**
237
- * Returns the post types registered by Tribe plugins
238
- */
239
- public static function get_post_types() {
240
- // we default the post type array to empty in tribe-common. Plugins like TEC add to it
241
- return apply_filters( 'tribe_post_types', array() );
242
- }
243
-
244
- /**
245
- * Insert an array after a specified key within another array.
246
- *
247
- * @param $key
248
- * @param $source_array
249
- * @param $insert_array
250
- *
251
- * @return array
252
- *
253
- */
254
- public static function array_insert_after_key( $key, $source_array, $insert_array ) {
255
- if ( array_key_exists( $key, $source_array ) ) {
256
- $position = array_search( $key, array_keys( $source_array ) ) + 1;
257
- $source_array = array_slice( $source_array, 0, $position, true ) + $insert_array + array_slice( $source_array, $position, null, true );
258
- } else {
259
- // If no key is found, then add it to the end of the array.
260
- $source_array += $insert_array;
261
- }
262
-
263
- return $source_array;
264
- }
265
-
266
- /**
267
- * Insert an array immediately before a specified key within another array.
268
- *
269
- * @param $key
270
- * @param $source_array
271
- * @param $insert_array
272
- *
273
- * @return array
274
- */
275
- public static function array_insert_before_key( $key, $source_array, $insert_array ) {
276
- if ( array_key_exists( $key, $source_array ) ) {
277
- $position = array_search( $key, array_keys( $source_array ) );
278
- $source_array = array_slice( $source_array, 0, $position, true ) + $insert_array + array_slice( $source_array, $position, null, true );
279
- } else {
280
- // If no key is found, then add it to the end of the array.
281
- $source_array += $insert_array;
282
- }
283
-
284
- return $source_array;
285
- }
286
-
287
- /**
288
- * Helper function for getting Post Id. Accepts null or a post id. If no $post object exists, returns false to avoid a PHP NOTICE
289
- *
290
- * @param int $post (optional)
291
- *
292
- * @return int post ID or False
293
- */
294
- public static function post_id_helper( $post = null ) {
295
- if ( ! is_null( $post ) && is_numeric( $post ) > 0 ) {
296
- return (int) $post;
297
- } elseif ( is_object( $post ) && ! empty( $post->ID ) ) {
298
- return (int) $post->ID;
299
- } else {
300
- if ( ! empty( $GLOBALS['post'] ) && $GLOBALS['post'] instanceof WP_Post ) {
301
- return get_the_ID();
302
- } else {
303
- return false;
304
- }
305
- }
306
- }
307
-
308
- /**
309
- * Helper function to indicate whether the current execution context is AJAX
310
- *
311
- * This method exists to allow us test code that behaves differently depending on the execution
312
- * context.
313
- *
314
- * @since 4.0
315
- * @return boolean
316
- */
317
- public function doing_ajax( $doing_ajax = null ) {
318
- if ( ! is_null( $doing_ajax ) ) {
319
- $this->doing_ajax = $doing_ajax;
320
- }
321
-
322
- return $this->doing_ajax;
323
- }
324
-
325
- /**
326
- * Static Singleton Factory Method
327
- *
328
- * @return Tribe__Main
329
- */
330
- public static function instance() {
331
- static $instance;
332
-
333
- if ( ! $instance ) {
334
- $instance = new self;
335
- }
336
-
337
- return $instance;
338
- }
339
- }
1
+ <?php
2
+ /**
3
+ * Main Tribe Common class.
4
+ */
5
+
6
+ // Don't load directly
7
+ if ( ! defined( 'ABSPATH' ) ) {
8
+ die( '-1' );
9
+ }
10
+
11
+ if ( class_exists( 'Tribe__Main' ) ) {
12
+ return;
13
+ }
14
+
15
+ class Tribe__Main {
16
+ const EVENTSERROROPT = '_tribe_events_errors';
17
+ const OPTIONNAME = 'tribe_events_calendar_options';
18
+ const OPTIONNAMENETWORK = 'tribe_events_calendar_network_options';
19
+
20
+ const VERSION = '4.2.7';
21
+ const FEED_URL = 'https://theeventscalendar.com/feed/';
22
+
23
+ protected $plugin_context;
24
+ protected $plugin_context_class;
25
+ protected $doing_ajax = false;
26
+ protected $log;
27
+
28
+ public static $tribe_url = 'http://tri.be/';
29
+ public static $tec_url = 'http://theeventscalendar.com/';
30
+
31
+ public $plugin_dir;
32
+ public $plugin_path;
33
+ public $plugin_url;
34
+
35
+ /**
36
+ * constructor
37
+ */
38
+ public function __construct( $context = null ) {
39
+ if ( is_object( $context ) ) {
40
+ $this->plugin_context = $context;
41
+ $this->plugin_context_class = get_class( $context );
42
+ }
43
+
44
+ $this->plugin_path = trailingslashit( dirname( dirname( dirname( __FILE__ ) ) ) );
45
+ $this->plugin_dir = trailingslashit( basename( $this->plugin_path ) );
46
+ $this->plugin_url = plugins_url( $this->plugin_dir );
47
+
48
+ $this->load_text_domain( 'tribe-common', basename( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) ) . '/common/lang/' );
49
+
50
+ $this->init_autoloading();
51
+
52
+ $this->init_libraries();
53
+ $this->add_hooks();
54
+
55
+ $this->doing_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX;
56
+ }
57
+
58
+ /**
59
+ * Get's the instantiated context of this class. I.e. the object that instantiated this one.
60
+ */
61
+ public function context() {
62
+ return $this->plugin_context;
63
+ }
64
+
65
+ /**
66
+ * Setup the autoloader for common files
67
+ */
68
+ protected function init_autoloading() {
69
+ if ( ! class_exists( 'Tribe__Autoloader' ) ) {
70
+ require_once dirname( __FILE__ ) . '/Autoloader.php';
71
+ }
72
+
73
+ $prefixes = array( 'Tribe__' => dirname( __FILE__ ) );
74
+ $autoloader = Tribe__Autoloader::instance();
75
+ $autoloader->register_prefixes( $prefixes );
76
+ $autoloader->register_autoloader();
77
+ }
78
+
79
+ /**
80
+ * Get's the class name of the instantiated plugin context of this class. I.e. the class name of the object that instantiated this one.
81
+ */
82
+ public function context_class() {
83
+ return $this->plugin_context_class;
84
+ }
85
+
86
+ /**
87
+ * initializes all required libraries
88
+ */
89
+ public function init_libraries() {
90
+ Tribe__Debug::instance();
91
+ Tribe__Settings_Manager::instance();
92
+
93
+ require_once $this->plugin_path . 'src/functions/utils.php';
94
+ require_once $this->plugin_path . 'src/functions/template-tags/general.php';
95
+ require_once $this->plugin_path . 'src/functions/template-tags/date.php';
96
+
97
+ // Starting the log manager needs to wait until after the tribe_*_option() functions have loaded
98
+ $this->log = new Tribe__Log();
99
+ }
100
+
101
+ /**
102
+ * Registers resources that can/should be enqueued
103
+ */
104
+ public function register_resources() {
105
+ $resources_url = plugins_url( 'src/resources', dirname( dirname( __FILE__ ) ) );
106
+
107
+ wp_register_style(
108
+ 'tribe-common-admin',
109
+ $resources_url . '/css/tribe-common-admin.css',
110
+ array(),
111
+ apply_filters( 'tribe_events_css_version', self::VERSION )
112
+ );
113
+
114
+ wp_register_script(
115
+ 'ba-dotimeout',
116
+ $resources_url . '/js/jquery.ba-dotimeout.js',
117
+ array(
118
+ 'jquery',
119
+ ),
120
+ apply_filters( 'tribe_events_css_version', self::VERSION ),
121
+ true
122
+ );
123
+
124
+ wp_register_script(
125
+ 'tribe-inline-bumpdown',
126
+ $resources_url . '/js/inline-bumpdown.js',
127
+ array(
128
+ 'ba-dotimeout',
129
+ ),
130
+ apply_filters( 'tribe_events_css_version', self::VERSION ),
131
+ true
132
+ );
133
+
134
+ wp_register_script(
135
+ 'tribe-notice-dismiss',
136
+ $resources_url . '/js/notice-dismiss.js',
137
+ array( 'jquery' ),
138
+ apply_filters( 'tribe_events_css_version', self::VERSION ),
139
+ true
140
+ );
141
+ }
142
+
143
+ /**
144
+ * Registers vendor assets that can/should be enqueued
145
+ */
146
+ public function register_vendor() {
147
+ $vendor_base = plugins_url( 'vendor', dirname( dirname( __FILE__ ) ) );
148
+
149
+ wp_register_style(
150
+ 'tribe-jquery-ui-theme',
151
+ $vendor_base . '/jquery/ui.theme.css',
152
+ array(),
153
+ apply_filters( 'tribe_events_css_version', self::VERSION )
154
+ );
155
+
156
+ wp_register_style(
157
+ 'tribe-jquery-ui-datepicker',
158
+ $vendor_base . '/jquery/ui.datepicker.css',
159
+ array( 'tribe-jquery-ui-theme' ),
160
+ apply_filters( 'tribe_events_css_version', self::VERSION )
161
+ );
162
+
163
+ }
164
+
165
+ /**
166
+ * Adds core hooks
167
+ */
168
+ public function add_hooks() {
169
+ add_action( 'plugins_loaded', array( 'Tribe__App_Shop', 'instance' ) );
170
+
171
+ // Register for the assets to be availble everywhere
172
+ add_action( 'init', array( $this, 'register_resources' ), 1 );
173
+ add_action( 'init', array( $this, 'register_vendor' ), 1 );
174
+
175
+ // Enqueue only when needed (admin)
176
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
177
+ }
178
+
179
+ /**
180
+ * A Helper method to load text domain
181
+ * First it tries to load the wp-content/languages translation then if falls to the
182
+ * try to load $dir language files
183
+ *
184
+ * @param string $domain The text domain that will be loaded
185
+ * @param string $dir What directory should be used to try to load if the default doenst work
186
+ *
187
+ * @return bool If it was able to load the text domain
188
+ */
189
+ public function load_text_domain( $domain, $dir = false ) {
190
+ // Added safety just in case this runs twice...
191
+ if ( is_textdomain_loaded( $domain ) && ! is_a( $GLOBALS['l10n'][ $domain ], 'NOOP_Translations' ) ) {
192
+ return true;
193
+ }
194
+
195
+ $locale = get_locale();
196
+ $mofile = WP_LANG_DIR . '/plugins/' . $domain . '-' . $locale . '.mo';
197
+
198
+ /**
199
+ * Allows users to filter which file will be loaded for a given text domain
200
+ * Be careful when using this filter, it will apply across the whole plugin suite.
201
+ *
202
+ * @param string $mofile The path for the .mo File
203
+ * @param string $domain Which plugin domain we are trying to load
204
+ * @param string $locale Which Language we will load
205
+ * @param string|bool $dir If there was a custom directory passed on the method call
206
+ */
207
+ $mofile = apply_filters( 'tribe_load_text_domain', $mofile, $domain, $locale, $dir );
208
+
209
+ $loaded = load_plugin_textdomain( $domain, false, $mofile );
210
+
211
+ if ( $dir !== false && ! $loaded ) {
212
+ return load_plugin_textdomain( $domain, false, $dir );
213
+ }
214
+
215
+ return $loaded;
216
+ }
217
+
218
+ public function admin_enqueue_scripts() {
219
+ wp_enqueue_script( 'tribe-inline-bumpdown' );
220
+ wp_enqueue_script( 'tribe-notice-dismiss' );
221
+ wp_enqueue_style( 'tribe-common-admin' );
222
+
223
+ $helper = Tribe__Admin__Helpers::instance();
224
+ if ( $helper->is_post_type_screen() ) {
225
+ wp_enqueue_style( 'tribe-jquery-ui-datepicker' );
226
+ }
227
+ }
228
+
229
+ /**
230
+ * @return Tribe__Log
231
+ */
232
+ public function log() {
233
+ return $this->log;
234
+ }
235
+
236
+ /**
237
+ * Returns the post types registered by Tribe plugins
238
+ */
239
+ public static function get_post_types() {
240
+ // we default the post type array to empty in tribe-common. Plugins like TEC add to it
241
+ return apply_filters( 'tribe_post_types', array() );
242
+ }
243
+
244
+ /**
245
+ * Insert an array after a specified key within another array.
246
+ *
247
+ * @param $key
248
+ * @param $source_array
249
+ * @param $insert_array
250
+ *
251
+ * @return array
252
+ *
253
+ */
254
+ public static function array_insert_after_key( $key, $source_array, $insert_array ) {
255
+ if ( array_key_exists( $key, $source_array ) ) {
256
+ $position = array_search( $key, array_keys( $source_array ) ) + 1;
257
+ $source_array = array_slice( $source_array, 0, $position, true ) + $insert_array + array_slice( $source_array, $position, null, true );
258
+ } else {
259
+ // If no key is found, then add it to the end of the array.
260
+ $source_array += $insert_array;
261
+ }
262
+
263
+ return $source_array;
264
+ }
265
+
266
+ /**
267
+ * Insert an array immediately before a specified key within another array.
268
+ *
269
+ * @param $key
270
+ * @param $source_array
271
+ * @param $insert_array
272
+ *
273
+ * @return array
274
+ */
275
+ public static function array_insert_before_key( $key, $source_array, $insert_array ) {
276
+ if ( array_key_exists( $key, $source_array ) ) {
277
+ $position = array_search( $key, array_keys( $source_array ) );
278
+ $source_array = array_slice( $source_array, 0, $position, true ) + $insert_array + array_slice( $source_array, $position, null, true );
279
+ } else {
280
+ // If no key is found, then add it to the end of the array.
281
+ $source_array += $insert_array;
282
+ }
283
+
284
+ return $source_array;
285
+ }
286
+
287
+ /**
288
+ * Helper function for getting Post Id. Accepts null or a post id. If no $post object exists, returns false to avoid a PHP NOTICE
289
+ *
290
+ * @param int $post (optional)
291
+ *
292
+ * @return int post ID or False
293
+ */
294
+ public static function post_id_helper( $post = null ) {
295
+ if ( ! is_null( $post ) && is_numeric( $post ) > 0 ) {
296
+ return (int) $post;
297
+ } elseif ( is_object( $post ) && ! empty( $post->ID ) ) {
298
+ return (int) $post->ID;
299
+ } else {
300
+ if ( ! empty( $GLOBALS['post'] ) && $GLOBALS['post'] instanceof WP_Post ) {
301
+ return get_the_ID();
302
+ } else {
303
+ return false;
304
+ }
305
+ }
306
+ }
307
+
308
+ /**
309
+ * Helper function to indicate whether the current execution context is AJAX
310
+ *
311
+ * This method exists to allow us test code that behaves differently depending on the execution
312
+ * context.
313
+ *
314
+ * @since 4.0
315
+ * @return boolean
316
+ */
317
+ public function doing_ajax( $doing_ajax = null ) {
318
+ if ( ! is_null( $doing_ajax ) ) {
319
+ $this->doing_ajax = $doing_ajax;
320
+ }
321
+
322
+ return $this->doing_ajax;
323
+ }
324
+
325
+ /**
326
+ * Static Singleton Factory Method
327
+ *
328
+ * @return Tribe__Main
329
+ */
330
+ public static function instance() {
331
+ static $instance;
332
+
333
+ if ( ! $instance ) {
334
+ $instance = new self;
335
+ }
336
+
337
+ return $instance;
338
+ }
339
+ }
common/src/Tribe/Notices.php CHANGED
@@ -1,76 +1,76 @@
1
- <?php
2
-
3
- class Tribe__Notices {
4
- /**
5
- * Notices to be displayed in the admin
6
- * @var array
7
- */
8
- protected $notices = array();
9
-
10
- /**
11
- * Define an admin notice
12
- *
13
- * @param string $key
14
- * @param string $notice
15
- *
16
- * @return bool
17
- */
18
- public static function set_notice( $key, $notice ) {
19
- self::instance()->notices[ $key ] = $notice;
20
-
21
- return true;
22
- }
23
-
24
- /**
25
- * Check to see if an admin notice exists
26
- *
27
- * @param string $key
28
- *
29
- * @return bool
30
- */
31
- public static function is_notice( $key ) {
32
- return ! empty( self::instance()->notices[ $key ] ) ? true : false;
33
- }
34
-
35
- /**
36
- * Remove an admin notice
37
- *
38
- * @param string $key
39
- *
40
- * @return bool
41
- */
42
- public static function remove_notice( $key ) {
43
- if ( self::is_notice( $key ) ) {
44
- unset( self::instance()->notices[ $key ] );
45
-
46
- return true;
47
- } else {
48
- return false;
49
- }
50
- }
51
-
52
- /**
53
- * Get the admin notices
54
- *
55
- * @return array
56
- */
57
- public static function get() {
58
- return self::instance()->notices;
59
- }
60
-
61
- /**
62
- * Static Singleton Factory Method
63
- *
64
- * @return Tribe__Notices
65
- */
66
- public static function instance() {
67
- static $instance;
68
-
69
- if ( ! $instance ) {
70
- $class_name = __CLASS__;
71
- $instance = new $class_name;
72
- }
73
-
74
- return $instance;
75
- }
76
- }
1
+ <?php
2
+
3
+ class Tribe__Notices {
4
+ /**
5
+ * Notices to be displayed in the admin
6
+ * @var array
7
+ */
8
+ protected $notices = array();
9
+
10
+ /**
11
+ * Define an admin notice
12
+ *
13
+ * @param string $key
14
+ * @param string $notice
15
+ *
16
+ * @return bool
17
+ */
18
+ public static function set_notice( $key, $notice ) {
19
+ self::instance()->notices[ $key ] = $notice;
20
+
21
+ return true;
22
+ }
23
+
24
+ /**
25
+ * Check to see if an admin notice exists
26
+ *
27
+ * @param string $key
28
+ *
29
+ * @return bool
30
+ */
31
+ public static function is_notice( $key ) {
32
+ return ! empty( self::instance()->notices[ $key ] ) ? true : false;
33
+ }
34
+
35
+ /**
36
+ * Remove an admin notice
37
+ *
38
+ * @param string $key
39
+ *
40
+ * @return bool
41
+ */
42
+ public static function remove_notice( $key ) {
43
+ if ( self::is_notice( $key ) ) {
44
+ unset( self::instance()->notices[ $key ] );
45
+
46
+ return true;
47
+ } else {
48
+ return false;
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Get the admin notices
54
+ *
55
+ * @return array
56
+ */
57
+ public static function get() {
58
+ return self::instance()->notices;
59
+ }
60
+
61
+ /**
62
+ * Static Singleton Factory Method
63
+ *
64
+ * @return Tribe__Notices
65
+ */
66
+ public static function instance() {
67
+ static $instance;
68
+
69
+ if ( ! $instance ) {
70
+ $class_name = __CLASS__;
71
+ $instance = new $class_name;
72
+ }
73
+
74
+ return $instance;
75
+ }
76
+ }
common/src/Tribe/PUE/Checker.php CHANGED
@@ -1,884 +1,884 @@
1
- <?php
2
- /**
3
- * Plugin Update Engine Class
4
- *
5
- * This is a direct port to Tribe Commons of the PUE classes contained
6
- * in The Events Calendar.
7
- *
8
- * @todo switch all plugins over to use the PUE utilities here in Commons
9
- */
10
-
11
- // Don't load directly
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- die( '-1' );
14
- }
15
-
16
- if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
17
- /**
18
- * A custom plugin update checker.
19
- *
20
- * @original author (c) Janis Elsts
21
- * @heavily modified by Darren Ethier
22
- * @slighty modified by Nick Ciske
23
- * @slighty modified by Joachim Kudish
24
- * @heavily modified by Peter Chester
25
- * @license GPL2 or greater.
26
- * @version 1.7
27
- * @access public
28
- */
29
- class Tribe__PUE__Checker {
30
-
31
- private $pue_update_url = ''; //The URL of the plugin's metadata file.
32
- private $plugin_file = ''; //Plugin filename relative to the plugins directory.
33
- private $plugin_name = ''; //variable used to hold the plugin_name as set by the constructor.
34
- private $slug = ''; //Plugin slug. (with .php extension)
35
- private $download_query = array(); //used to hold the query variables for download checks;
36
-
37
- public $check_period = 12; //How often to check for updates (in hours).
38
- public $pue_option_name = ''; //Where to store the update info.
39
- public $json_error = ''; //for storing any json_error data that get's returned so we can display an admin notice.
40
- public $api_secret_key = ''; //used to hold the user API. If not set then nothing will work!
41
- public $install_key = false; //used to hold the install_key if set (included here for addons that will extend PUE to use install key checks)
42
- public $dismiss_upgrade; //for setting the dismiss upgrade option (per plugin).
43
- public $pue_install_key; //we'll customize this later so each plugin can have it's own install key!
44
-
45
- /**
46
- * Class constructor.
47
- *
48
- * @param string $pue_update_url The URL of the plugin's metadata file.
49
- * @param string $slug The plugin's 'slug'.
50
- * @param array $options Contains any options that need to be set in the class initialization for construct. These are the keys:
51
- *
52
- * @key integer $check_period How often to check for updates (in hours). Defaults to checking every 12 hours. Set to 0 to disable automatic update checks.
53
- * @key string $pue_option_name Where to store book-keeping info about update checks. Defaults to 'external_updates-$slug'.
54
- * @key string $apikey used to authorize download updates from developer server
55
- *
56
- * @param string $plugin_file fully qualified path to the main plugin file.
57
- */
58
- public function __construct( $pue_update_url, $slug = '', $options = array(), $plugin_file = '' ) {
59
-
60
- $this->set_slug( $slug );
61
- $this->set_pue_update_url( $pue_update_url );
62
- $this->set_plugin_file( $plugin_file );
63
- $this->set_options( $options );
64
- $this->hooks();
65
-
66
- }
67
-
68
- /**
69
- * Install the hooks required to run periodic update checks and inject update info
70
- * into WP data structures.
71
- * Also other hooks related to the automatic updates (such as checking agains API and what not (@from Darren)
72
- */
73
- public function hooks() {
74
- // Override requests for plugin information
75
- add_filter( 'plugins_api', array( &$this, 'inject_info' ), 10, 3 );
76
-
77
- // Check for updates when the WP updates are checked and inject our update if needed.
78
- // Only add filter if the TRIBE_DISABLE_PUE constant is not set as true.
79
- if ( ! defined( 'TRIBE_DISABLE_PUE' ) || TRIBE_DISABLE_PUE !== true ) {
80
- add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_for_updates' ) );
81
- }
82
-
83
- add_filter( 'tribe_licensable_addons', array( $this, 'build_addon_list' ) );
84
- add_action( 'tribe_license_fields', array( $this, 'do_license_key_fields' ) );
85
- add_action( 'tribe_settings_after_content_tab_licenses', array( $this, 'do_license_key_javascript' ) );
86
- add_action( 'tribe_settings_success_message', array( $this, 'do_license_key_success_message' ), 10, 2 );
87
-
88
- // Key validation
89
- add_action( 'wp_ajax_pue-validate-key_' . $this->get_slug(), array( $this, 'ajax_validate_key' ) );
90
-
91
- // Dashboard message "dismiss upgrade" link
92
- add_action( 'wp_ajax_' . $this->dismiss_upgrade, array( $this, 'dashboard_dismiss_upgrade' ) );
93
-
94
- add_filter( 'tribe-pue-install-keys', array( $this, 'return_install_key' ) );
95
- }
96
-
97
- /********************** Getter / Setter Functions **********************/
98
-
99
- /**
100
- * Get the slug
101
- *
102
- * @return string
103
- */
104
- public function get_slug() {
105
- return apply_filters( 'pue_get_slug', $this->slug );
106
- }
107
-
108
- /**
109
- * Set the slug
110
- *
111
- * @param string $slug
112
- */
113
- private function set_slug( $slug = '' ) {
114
- $this->slug = $slug;
115
- $clean_slug = str_replace( '-', '_', $this->slug );
116
- $this->dismiss_upgrade = 'pu_dismissed_upgrade_' . $clean_slug;
117
- $this->pue_install_key = 'pue_install_key_' . $clean_slug;
118
- }
119
-
120
- /**
121
- * Get the PUE update API endpoint url
122
- *
123
- * @return string
124
- */
125
- public function get_pue_update_url() {
126
- return apply_filters( 'pue_get_update_url', $this->pue_update_url, $this->get_slug() );
127
- }
128
-
129
- /**
130
- * Set the PUE update URL
131
- *
132
- * This can be overridden using the global constant 'PUE_UPDATE_URL'
133
- *
134
- * @param string $pue_update_url
135
- */
136
- private function set_pue_update_url( $pue_update_url ) {
137
- $this->pue_update_url = ( defined( 'PUE_UPDATE_URL' ) ) ? trailingslashit( PUE_UPDATE_URL ) : trailingslashit( $pue_update_url );
138
- }
139
-
140
- /**
141
- * Get the plugin file path
142
- *
143
- * @return string
144
- */
145
- public function get_plugin_file() {
146
- return apply_filters( 'pue_get_plugin_file', $this->plugin_file, $this->get_slug() );
147
- }
148
-
149
- /**
150
- * Set the plugin file path
151
- *
152
- * @param string $plugin_file
153
- */
154
- private function set_plugin_file( $plugin_file = '' ) {
155
-
156
- if ( ! empty( $plugin_file ) ) {
157
- $this->plugin_file = $plugin_file;
158
-
159
- return;
160
- }
161
-
162
- $slug = $this->get_slug();
163
- if ( ! empty( $slug ) ) {
164
- $this->plugin_file = $slug . '/' . $slug . '.php';
165
- }
166
- }
167
-
168
- /**
169
- * Set the plugin name
170
- *
171
- * @param string $plugin_name
172
- */
173
- private function set_plugin_name( $plugin_name = '' ) {
174
- if ( ! empty( $plugin_name ) ) {
175
- $this->plugin_name = $plugin_name;
176
- } else {
177
- //get name from plugin file itself
178
- if ( ! function_exists( 'get_plugins' ) ) {
179
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
180
- }
181
-
182
- $plugin_details = explode( '/', $this->get_plugin_file() );
183
- $plugin_folder = get_plugins( '/' . $plugin_details[0] );
184
- $this->plugin_name = $plugin_folder[ $plugin_details[1] ]['Name'];
185
- }
186
- }
187
-
188
- /**
189
- * Get the plugin name
190
- *
191
- * @return string
192
- */
193
- public function get_plugin_name() {
194
- if ( empty( $this->plugin_name ) ) {
195
- $this->set_plugin_name();
196
- }
197
-
198
- return apply_filters( 'pue_get_plugin_name', $this->plugin_name, $this->get_slug() );
199
- }
200
-
201
- /**
202
- * Set all the PUE instantiation options
203
- *
204
- * @param array $options
205
- */
206
- private function set_options( $options = array() ) {
207
-
208
- $options = wp_parse_args(
209
- $options, array(
210
- 'pue_option_name' => 'external_updates-' . $this->get_slug(),
211
- 'apikey' => '',
212
- 'installkey' => false,
213
- 'check_period' => 12,
214
- )
215
- );
216
-
217
- $this->pue_option_name = $options['pue_option_name'];
218
- $this->check_period = (int) $options['check_period'];
219
- $this->api_secret_key = $options['apikey'];
220
- if ( isset( $options['installkey'] ) && $options['installkey'] ) {
221
- $this->install_key = trim( $options['installkey'] );
222
- } else {
223
- $this->install_key = trim( $this->get_option( $this->pue_install_key ) );
224
- }
225
-
226
- }
227
-
228
- /**
229
- * Set all the download query array
230
- *
231
- * @param array $download_query
232
- */
233
- private function set_download_query( $download_query = array() ) {
234
-
235
- if ( ! empty( $download_query ) ) {
236
- $this->download_query = $download_query;
237
-
238
- return;
239
- }
240
-
241
- //download query flag
242
- $this->download_query['pu_get_download'] = 1;
243
-
244
- //include current version
245
- if ( $version = $this->get_installed_version() ) {
246
- $this->download_query['pue_active_version'] = $version;
247
- }
248
-
249
- //the following is for install key inclusion (will apply later with PUE addons.)
250
- if ( isset( $this->install_key ) ) {
251
- $this->download_query['pu_install_key'] = $this->install_key;
252
- }
253
-
254
- if ( ! empty( $this->api_secret_key ) ) {
255
- $this->download_query['pu_plugin_api'] = $this->api_secret_key;
256
- }
257
-
258
- }
259
-
260
- /**
261
- * Get the download_query args
262
- *
263
- * @return array
264
- */
265
- public function get_download_query() {
266
- if ( empty( $this->download_query ) ) {
267
- $this->set_download_query();
268
- }
269
-
270
- return apply_filters( 'pue_get_download_query', $this->download_query, $this->get_slug() );
271
- }
272
-
273
-
274
- /********************** General Functions **********************/
275
-
276
- /**
277
- * Compile a list of addons
278
- *
279
- * @param array $addons list of addons
280
- *
281
- * @return array list of addons
282
- */
283
- public function build_addon_list( $addons = array() ) {
284
- $addons[] = $this->get_plugin_name();
285
-
286
- return $addons;
287
- }
288
-
289
- /**
290
- * Inserts license key fields on license key page
291
- *
292
- * @param array $fields List of fields
293
- *
294
- * @return array Modified list of fields.
295
- */
296
- public function do_license_key_fields( $fields ) {
297
-
298
- // we want to inject the following license settings at the end of the licenses tab
299
- $fields = self::array_insert_after_key( 'tribe-form-content-start', $fields, array(
300
- $this->pue_install_key . '-heading' => array(
301
- 'type' => 'heading',
302
- 'label' => $this->get_plugin_name(),
303
- ),
304
- $this->pue_install_key => array(
305
- 'type' => 'license_key',
306
- 'size' => 'large',
307
- 'validation_type' => 'license_key',
308
- 'label' => sprintf( esc_attr__( 'License Key', 'tribe-common' ) ),
309
- 'tooltip' => esc_html__( 'A valid license key is required for support and updates', 'tribe-common' ),
310
- 'parent_option' => false,
311
- 'network_option' => true,
312
- ),
313
- )
314
- );
315
-
316
- return $fields;
317
- }
318
-
319
- /**
320
- * Inserts the javascript that makes the ajax checking
321
- * work on the license key page
322
- *
323
- */
324
- public function do_license_key_javascript() {
325
- ?>
326
- <script>
327
- jQuery(document).ready(function ($) {
328
- $('#tribe-field-<?php echo $this->pue_install_key ?>').change(function () {
329
- <?php echo $this->pue_install_key ?>_validateKey();
330
- });
331
- <?php echo $this->pue_install_key ?>_validateKey();
332
- });
333
- function <?php echo $this->pue_install_key ?>_validateKey() {
334
- var this_id = '#tribe-field-<?php echo $this->pue_install_key ?>';
335
- var $validity_msg = jQuery(this_id + ' .key-validity');
336
-
337
- if (jQuery(this_id + ' input').val() != '') {
338
- jQuery(this_id + ' .tooltip').hide();
339
- jQuery(this_id + ' .ajax-loading-license').show();
340
- $validity_msg.hide();
341
-
342
- // Strip whitespace from key
343
- var <?php echo $this->pue_install_key ?>_license_key = jQuery(this_id + ' input').val().replace(/^\s+|\s+$/g, "");
344
- jQuery(this_id + ' input').val(<?php echo $this->pue_install_key ?>_license_key);
345
-
346
- var data = { action: 'pue-validate-key_<?php echo $this->get_slug(); ?>', key: <?php echo $this->pue_install_key ?>_license_key };
347
- jQuery.post(ajaxurl, data, function (response) {
348
- var data = jQuery.parseJSON(response);
349
-
350
- jQuery(this_id + ' .ajax-loading-license').hide();
351
- $validity_msg.show();
352
- $validity_msg.html(data.message);
353
-
354
- switch ( data.status ) {
355
- case 1: $validity_msg.addClass( 'valid-key' ); break;
356
- case 2: $validity_msg.addClass( 'valid-key service-msg' ); break;
357
- default: $validity_msg.addClass( 'invalid-key' ); break;
358
- }
359
- });
360
- }
361
- }
362
- </script>
363
- <?php
364
- }
365
-
366
- /**
367
- * Filter the success message on license key page
368
- *
369
- * @param string $message
370
- * @param string $tab
371
- *
372
- * @return string
373
- */
374
- public function do_license_key_success_message( $message, $tab ) {
375
-
376
- if ( $tab != 'licenses' ) {
377
- return $message;
378
- }
379
-
380
- return '<div id="message" class="updated"><p><strong>' . esc_html__( 'License key(s) updated.', 'tribe-common' ) . '</strong></p></div>';
381
-
382
- }
383
-
384
- /**
385
- * Echo JSON results for key validation
386
- */
387
- public function ajax_validate_key() {
388
- $response = array();
389
- $response['status'] = 0;
390
- if ( isset( $_POST['key'] ) ) {
391
-
392
- $queryArgs = array(
393
- 'pu_install_key' => trim( $_POST['key'] ),
394
- 'pu_checking_for_updates' => '1',
395
- );
396
-
397
- //include version info
398
- $queryArgs['pue_active_version'] = $this->get_installed_version();
399
-
400
- global $wp_version;
401
- $queryArgs['wp_version'] = $wp_version;
402
-
403
- // For multisite, return the network-level siteurl ... in
404
- // all other cases return the actual URL being serviced
405
- $queryArgs['domain'] = is_multisite() ? $this->get_network_domain() : $_SERVER['SERVER_NAME'];
406
-
407
- if ( is_multisite() ) {
408
- $queryArgs['multisite'] = 1;
409
- $queryArgs['network_activated'] = is_plugin_active_for_network( $this->get_plugin_file() );
410
- global $wpdb;
411
- $queryArgs['active_sites'] = $wpdb->get_var( "SELECT count(blog_id) FROM $wpdb->blogs WHERE public = '1' AND archived = '0' AND spam = '0' AND deleted = '0'" );
412
- } else {
413
- $queryArgs['multisite'] = 0;
414
- $queryArgs['network_activated'] = 0;
415
- $queryArgs['active_sites'] = 1;
416
- }
417
-
418
- $pluginInfo = $this->request_info( $queryArgs );
419
- $expiration = isset( $pluginInfo->expiration ) ? $pluginInfo->expiration : esc_html__( 'unknown date', 'tribe-common' );
420
-
421
- if ( empty( $pluginInfo ) ) {
422
- $response['message'] = esc_html__( 'Sorry, key validation server is not available.', 'tribe-common' );
423
- } elseif ( isset( $pluginInfo->api_expired ) && $pluginInfo->api_expired == 1 ) {
424
- $response['message'] = $this->get_api_message( $pluginInfo );
425
- } elseif ( isset( $pluginInfo->api_upgrade ) && $pluginInfo->api_upgrade == 1 ) {
426
- $response['message'] = $this->get_api_message( $pluginInfo );
427
- } elseif ( isset( $pluginInfo->api_invalid ) && $pluginInfo->api_invalid == 1 ) {
428
- $response['message'] = $this->get_api_message( $pluginInfo );
429
- } else {
430
- $api_secret_key = get_option( $this->pue_install_key );
431
- if ( $api_secret_key && $api_secret_key === $queryArgs['pu_install_key'] ){
432
- $default_success_msg = sprintf( esc_html__( 'Valid Key! Expires on %s', 'tribe-common' ), $expiration );
433
- } else {
434
- // Set the key
435
- update_option( $this->pue_install_key, $queryArgs['pu_install_key'] );
436
-
437
- $default_success_msg = sprintf( esc_html__( 'Thanks for setting up a valid key, it will expire on %s', 'tribe-common' ), $expiration );
438
- }
439
-
440
- $response['status'] = isset( $pluginInfo->api_message ) ? 2 : 1;
441
- $response['message'] = isset( $pluginInfo->api_message ) ? wp_kses( $pluginInfo->api_message, 'data' ) : $default_success_msg;
442
- $response['expiration'] = $expiration;
443
- }
444
- } else {
445
- $response['message'] = sprintf( esc_html__( 'Hmmm... something\'s wrong with this validator. Please contact %ssupport%s.', 'tribe-common' ), '<a href="http://m.tri.be/1u">', '</a>' );
446
- }
447
- echo json_encode( $response );
448
- exit;
449
- }
450
-
451
- /**
452
- * processes variable substitutions for server-side API message
453
- */
454
- private function get_api_message( $info ) {
455
- // this default message should never show, but is here as a fallback just in case.
456
- $message = sprintf(
457
- esc_html__( 'Sorry, there is a problem with your license key. You\'ll need to %scheck your license%s to have access to updates, downloads, and support.', 'tribe-common' ),
458
- '<a href="https://theeventscalendar.com/license-keys/">',
459
- '</a>'
460
- );
461
-
462
- if ( ! empty( $info->api_invalid_message ) ) {
463
- $message = wp_kses( $info->api_invalid_message, 'post' );
464
- }
465
-
466
- $message = str_replace( '%plugin_name%', '<b>' . $this->get_plugin_name() . '</b>', $message );
467
- $message = str_replace( '%plugin_slug%', $this->get_slug(), $message );
468
- $message = str_replace( '%update_url%', $this->get_pue_update_url(), $message );
469
- $message = str_replace( '%version%', $info->version, $message );
470
-
471
- return $message;
472
- }
473
-
474
- /**
475
- * Echo JSON formatted errors
476
- */
477
- public function display_json_error() {
478
- $pluginInfo = $this->json_error;
479
- $update_dismissed = $this->get_option( $this->dismiss_upgrade );
480
-
481
- $is_dismissed = ! empty( $update_dismissed ) && in_array( $pluginInfo->version, $update_dismissed ) ? true : false;
482
-
483
- if ( $is_dismissed ) {
484
- return;
485
- }
486
-
487
- if ( ! current_user_can( 'administrator' ) ) {
488
- return;
489
- }
490
-
491
- //only display messages if there is a new version of the plugin.
492
- if ( version_compare( $pluginInfo->version, $this->get_installed_version(), '>' ) ) {
493
- if ( empty( $pluginInfo->api_invalid ) || $pluginInfo->api_invalid != 1 ) {
494
- return;
495
- }
496
-
497
- $msg = $this->get_api_message( $pluginInfo );
498
-
499
- //Dismiss code idea below is obtained from the Gravity Forms Plugin by rocketgenius.com
500
- ?>
501
- <div class="updated" style="padding:5px; position:relative;" id="pu_dashboard_message"><?php echo wp_kses( $msg, 'post' ); ?>
502
- <a href="javascript:void(0);" onclick="PUDismissUpgrade();" style="float:right;">[X]</a>
503
- </div>
504
- <script type="text/javascript">
505
- function PUDismissUpgrade() {
506
- jQuery("#pu_dashboard_message").slideUp();
507
- jQuery.post( ajaxurl, {
508
- action: "<?php echo esc_attr( $this->dismiss_upgrade ); ?>",
509
- version: "<?php echo esc_attr( $pluginInfo->version ); ?>",
510
- cookie: encodeURIComponent(document.cookie)
511
- } );
512
- }
513
- </script>
514
- <?php
515
- }
516
- }
517
-
518
- /**
519
- * Retrieve plugin info from the configured API endpoint.
520
- *
521
- * @param array $queryArgs Additional query arguments to append to the request. Optional.
522
- *
523
- * @uses wp_remote_get()
524
- * @return string $pluginInfo
525
- */
526
- public function request_info( $queryArgs = array() ) {
527
- //Query args to append to the URL. Plugins can add their own by using a filter callback (see add_query_arg_filter()).
528
- $queryArgs['installed_version'] = $this->get_installed_version();
529
- $queryArgs['pu_request_plugin'] = $this->get_slug();
530
-
531
- if ( empty( $queryArgs['pu_plugin_api'] ) && ! empty( $this->api_secret_key ) ) {
532
- $queryArgs['pu_plugin_api'] = $this->api_secret_key;
533
- }
534
-
535
- if ( empty( $queryArgs['pu_install_key'] ) && ! empty( $this->install_key ) ) {
536
- $queryArgs['pu_install_key'] = $this->install_key;
537
- }
538
-
539
- //include version info
540
- $queryArgs['pue_active_version'] = $this->get_installed_version();
541
-
542
- global $wp_version;
543
- $queryArgs['wp_version'] = $wp_version;
544
-
545
- //include domain and multisite stats
546
- $queryArgs['domain'] = is_multisite() ? $this->get_network_domain() : $_SERVER['SERVER_NAME'];
547
-
548
- if ( is_multisite() ) {
549
- $queryArgs['multisite'] = 1;
550
- $queryArgs['network_activated'] = is_plugin_active_for_network( $this->get_plugin_file() );
551
- global $wpdb;
552
- $queryArgs['active_sites'] = $wpdb->get_var( "SELECT count(blog_id) FROM $wpdb->blogs WHERE public = '1' AND archived = '0' AND spam = '0' AND deleted = '0'" );
553
-
554
- } else {
555
- $queryArgs['multisite'] = 0;
556
- $queryArgs['network_activated'] = 0;
557
- $queryArgs['active_sites'] = 1;
558
- }
559
-
560
- $queryArgs = apply_filters( 'tribe_puc_request_info_query_args-' . $this->get_slug(), $queryArgs );
561
-
562
- //Various options for the wp_remote_get() call. Plugins can filter these, too.
563
- $options = array(
564
- 'timeout' => 15, //seconds
565
- 'headers' => array(
566
- 'Accept' => 'application/json',
567
- ),
568
- );
569
- $options = apply_filters( 'tribe_puc_request_info_options-' . $this->get_slug(), $options );
570
-
571
- $url = $this->get_pue_update_url();
572
- if ( ! empty( $queryArgs ) ) {
573
- $url = esc_url_raw( add_query_arg( $queryArgs, $url ) );
574
- }
575
-
576
- // Cache the API call so it only needs to be made once per plugin per page load.
577
- static $plugin_info_cache;
578
- $key = crc32( implode( '', $queryArgs ) );
579
- if ( isset( $plugin_info_cache[ $key ] ) ) {
580
- return $plugin_info_cache[ $key ];
581
- }
582
-
583
- $result = wp_remote_get(
584
- $url,
585
- $options
586
- );
587
-
588
- //Try to parse the response
589
- $pluginInfo = null;
590
- if ( ! is_wp_error( $result ) && isset( $result['response']['code'] ) && ( $result['response']['code'] == 200 ) && ! empty( $result['body'] ) ) {
591
- $pluginInfo = Tribe__PUE__Plugin_Info::from_json( $result['body'] );
592
- }
593
- $pluginInfo = apply_filters( 'tribe_puc_request_info_result-' . $this->get_slug(), $pluginInfo, $result );
594
-
595
- $plugin_info_cache[ $key ] = $pluginInfo;
596
-
597
- return $pluginInfo;
598
- }
599
-
600
- /**
601
- * Returns the domain contained in the network's siteurl option (not the full URL).
602
- *
603
- * @return string
604
- */
605
- public function get_network_domain() {
606
- $site_url = parse_url( get_site_option( 'siteurl' ) );
607
- if ( ! $site_url || ! isset( $site_url['host'] ) ) {
608
- return '';
609
- } else {
610
- return strtolower( $site_url['host'] );
611
- }
612
- }
613
-
614
- /**
615
- * Retrieve the latest update (if any) from the configured API endpoint.
616
- *
617
- * @uses Tribe__PUE__Checker::request_info()
618
- *
619
- * @return Tribe__PUE__Utility An instance of Tribe__PUE__Utility, or NULL when no updates are available.
620
- */
621
- public function request_update() {
622
- //For the sake of simplicity, this function just calls request_info()
623
- //and transforms the result accordingly.
624
- $pluginInfo = $this->request_info( array( 'pu_checking_for_updates' => '1' ) );
625
- if ( $pluginInfo == null ) {
626
- return null;
627
- }
628
- //admin display for if the update check reveals that there is a new version but the API key isn't valid.
629
- if ( isset( $pluginInfo->api_invalid ) ) { //we have json_error returned let's display a message
630
- $this->json_error = $pluginInfo;
631
- add_action( 'admin_notices', array( &$this, 'display_json_error' ) );
632
-
633
- return null;
634
- }
635
-
636
- if ( isset( $pluginInfo->new_install_key ) ) {
637
- $this->update_option( $this->pue_install_key, $pluginInfo->new_install_key );
638
- }
639
-
640
- //need to correct the download url so it contains the custom user data (i.e. api and any other paramaters)
641
-
642
- $download_query = $this->get_download_query();
643
- if ( ! empty( $download_query ) ) {
644
- $pluginInfo->download_url = esc_url_raw( add_query_arg( $download_query, $pluginInfo->download_url ) );
645
- }
646
-
647
- // Add plugin dirname/file (this will be expected by WordPress when it builds the plugin list table)
648
- $pluginInfo->plugin = $this->get_plugin_file();
649
-
650
- return Tribe__PUE__Utility::from_plugin_info( $pluginInfo );
651
- }
652
-
653
-
654
- /**
655
- * Display the upgrade message in the plugin list under the plugin.
656
- *
657
- * @param $plugin_data
658
- */
659
- public function in_plugin_update_message( $plugin_data ) {
660
- $plugininfo = $this->json_error;
661
- //only display messages if there is a new version of the plugin.
662
- if ( is_object( $plugininfo ) && version_compare( $plugininfo->version, $this->get_installed_version(), '>' ) ) {
663
- if ( $plugininfo->api_invalid ) {
664
- $msg = str_replace( '%plugin_name%', '<strong>' . $this->get_plugin_name() . '</strong>', $plugininfo->api_inline_invalid_message );
665
- $msg = str_replace( '%plugin_slug%', $this->get_slug(), $msg );
666
- $msg = str_replace( '%update_url%', $this->get_pue_update_url(), $msg );
667
- $msg = str_replace( '%version%', $plugininfo->version, $msg );
668
- $msg = str_replace( '%changelog%', '<a class="thickbox" title="' . $this->get_plugin_name() . '" href="plugin-install.php?tab=plugin-information&plugin=' . $this->get_slug() . '&TB_iframe=true&width=640&height=808">what\'s new</a>', $msg );
669
- echo '</tr><tr class="plugin-update-tr"><td colspan="3" class="plugin-update"><div class="update-message">' . $msg . '</div></td>';
670
- }
671
- }
672
- }
673
-
674
-
675
- /**
676
- * Display a changelog when the api key is missing.
677
- */
678
- public function display_changelog() {
679
- //contents of changelog display page when api-key is invalid or missing. It will ONLY show the changelog (hook into existing thickbox?)
680
- }
681
-
682
- /**
683
- * Update option to dismiss the upgrade notice.
684
- */
685
- public function dashboard_dismiss_upgrade() {
686
- $os_ary = $this->get_option( $this->dismiss_upgrade );
687
- if ( ! is_array( $os_ary ) ) {
688
- $os_ary = array();
689
- }
690
-
691
- $os_ary[] = $_POST['version'];
692
- $this->update_option( $this->dismiss_upgrade, $os_ary );
693
- }
694
-
695
- /**
696
- * Get the currently installed version of the plugin.
697
- *
698
- * @return string Version number.
699
- */
700
- public function get_installed_version() {
701
- if ( function_exists( 'get_plugins' ) ) {
702
- $allPlugins = get_plugins();
703
- if ( array_key_exists( $this->get_plugin_file(), $allPlugins ) && array_key_exists( 'Version', $allPlugins[ $this->get_plugin_file() ] ) ) {
704
- return $allPlugins[ $this->get_plugin_file() ]['Version'];
705
- }
706
- }
707
- }
708
-
709
- /**
710
- * Get MU compatible options.
711
- *
712
- * @param string $option_key
713
- * @param bool|mixed $default
714
- *
715
- * @return null|mixed
716
- */
717
- public function get_option( $option_key, $default = false ) {
718
- return get_site_option( $option_key, $default );
719
- }
720
-
721
- /**
722
- * Update MU compatible options.
723
- *
724
- * @param mixed $option_key
725
- * @param mixed $value
726
- */
727
- public function update_option( $option_key, $value ) {
728
- update_site_option( $option_key, $value );
729
- }
730
-
731
- /**
732
- * Check for plugin updates.
733
- *
734
- * The results are stored in the DB option specified in $pue_option_name.
735
- *
736
- * @param array $updates
737
- *
738
- */
739
- public function check_for_updates( $updates = array() ) {
740
- $state = $this->get_option( $this->pue_option_name );
741
- if ( empty( $state ) ) {
742
- $state = new StdClass;
743
- $state->lastCheck = 0;
744
- $state->checkedVersion = '';
745
- $state->update = null;
746
- }
747
-
748
- $state->lastCheck = time();
749
- $state->checkedVersion = $this->get_installed_version();
750
- $this->update_option( $this->pue_option_name, $state ); //Save before checking in case something goes wrong
751
-
752
- $state->update = $this->request_update();
753
-
754
- // If a null update was returned, skip the end of the function.
755
- if ( $state->update == null ) {
756
- return $updates;
757
- }
758
-
759
- //Is there an update to insert?
760
- if ( version_compare( $state->update->version, $this->get_installed_version(), '>' ) ) {
761
- $updates->response[ $this->get_plugin_file() ] = $state->update->to_wp_format();
762
- }
763
-
764
- $this->update_option( $this->pue_option_name, $state );
765
- add_action( 'after_plugin_row_' . $this->get_plugin_file(), array( &$this, 'in_plugin_update_message' ) );
766
-
767
- return $updates;
768
- }
769
-
770
- /**
771
- * Intercept plugins_api() calls that request information about our plugin and
772
- * use the configured API endpoint to satisfy them.
773
- *
774
- * @see plugins_api()
775
- *
776
- * @param mixed $result
777
- * @param string $action
778
- * @param array|object $args
779
- *
780
- * @return mixed
781
- */
782
- public function inject_info( $result, $action = null, $args = null ) {
783
- $relevant = ( $action == 'plugin_information' ) && isset( $args->slug ) && ( $args->slug == $this->slug );
784
- if ( ! $relevant ) {
785
- return $result;
786
- }
787
-
788
- $pluginInfo = $this->request_info( array( 'pu_checking_for_updates' => '1' ) );
789
- if ( $pluginInfo ) {
790
- return $pluginInfo->to_wp_format();
791
- }
792
-
793
- return $result;
794
- }
795
-
796
- /**
797
- * Register a callback for filtering query arguments.
798
- *
799
- * The callback function should take one argument - an associative array of query arguments.
800
- * It should return a modified array of query arguments.
801
- *
802
- * @uses add_filter() This method is a convenience wrapper for add_filter().
803
- *
804
- * @param callback $callback
805
- *
806
- */
807
- public function add_query_arg_filter( $callback ) {
808
- add_filter( 'tribe_puc_request_info_query_args-' . $this->get_slug(), $callback );
809
- }
810
-
811
- /**
812
- * Register a callback for filtering arguments passed to wp_remote_get().
813
- *
814
- * The callback function should take one argument - an associative array of arguments -
815
- * and return a modified array or arguments. See the WP documentation on wp_remote_get()
816
- * for details on what arguments are available and how they work.
817
- *
818
- * @uses add_filter() This method is a convenience wrapper for add_filter().
819
- *
820
- * @param callback $callback
821
- *
822
- */
823
- public function add_http_request_arg_filter( $callback ) {
824
- add_filter( 'tribe_puc_request_info_options-' . $this->get_slug(), $callback );
825
- }
826
-
827
- /**
828
- * Register a callback for filtering the plugin info retrieved from the external API.
829
- *
830
- * The callback function should take two arguments. If the plugin info was retrieved
831
- * successfully, the first argument passed will be an instance of Tribe__PUE__Plugin_Info. Otherwise,
832
- * it will be NULL. The second argument will be the corresponding return value of
833
- * wp_remote_get (see WP docs for details).
834
- *
835
- * The callback function should return a new or modified instance of Tribe__PUE__Plugin_Info or NULL.
836
- *
837
- * @uses add_filter() This method is a convenience wrapper for add_filter().
838
- *
839
- * @param callback $callback
840
- *
841
- */
842
- public function add_result_filter( $callback ) {
843
- add_filter( 'tribe_puc_request_info_result-' . $this->get_slug(), $callback, 10, 2 );
844
- }
845
-
846
- /**
847
- * Insert an array after a specified key within another array.
848
- *
849
- * @param $key
850
- * @param $source_array
851
- * @param $insert_array
852
- *
853
- * @return array
854
- *
855
- */
856
- public static function array_insert_after_key( $key, $source_array, $insert_array ) {
857
- if ( array_key_exists( $key, $source_array ) ) {
858
- $position = array_search( $key, array_keys( $source_array ) ) + 1;
859
- $source_array = array_slice( $source_array, 0, $position, true ) + $insert_array + array_slice( $source_array, $position, null, true );
860
- } else {
861
- // If no key is found, then add it to the end of the array.
862
- $source_array += $insert_array;
863
- }
864
-
865
- return $source_array;
866
- }
867
-
868
- /**
869
- * Add this plugin key to the list of keys
870
- *
871
- * @param array $keys
872
- *
873
- * @return array $keys
874
- *
875
- */
876
- public function return_install_key( $keys = array() ) {
877
- if ( ! empty( $this->install_key ) ) {
878
- $keys[ $this->get_slug() ] = $this->install_key;
879
- }
880
-
881
- return $keys;
882
- }
883
- }
884
- }
1
+ <?php
2
+ /**
3
+ * Plugin Update Engine Class
4
+ *
5
+ * This is a direct port to Tribe Commons of the PUE classes contained
6
+ * in The Events Calendar.
7
+ *
8
+ * @todo switch all plugins over to use the PUE utilities here in Commons
9
+ */
10
+
11
+ // Don't load directly
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die( '-1' );
14
+ }
15
+
16
+ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
17
+ /**
18
+ * A custom plugin update checker.
19
+ *
20
+ * @original author (c) Janis Elsts
21
+ * @heavily modified by Darren Ethier
22
+ * @slighty modified by Nick Ciske
23
+ * @slighty modified by Joachim Kudish
24
+ * @heavily modified by Peter Chester
25
+ * @license GPL2 or greater.
26
+ * @version 1.7
27
+ * @access public
28
+ */
29
+ class Tribe__PUE__Checker {
30
+
31
+ private $pue_update_url = ''; //The URL of the plugin's metadata file.
32
+ private $plugin_file = ''; //Plugin filename relative to the plugins directory.
33
+ private $plugin_name = ''; //variable used to hold the plugin_name as set by the constructor.
34
+ private $slug = ''; //Plugin slug. (with .php extension)
35
+ private $download_query = array(); //used to hold the query variables for download checks;
36
+
37
+ public $check_period = 12; //How often to check for updates (in hours).
38
+ public $pue_option_name = ''; //Where to store the update info.
39
+ public $json_error = ''; //for storing any json_error data that get's returned so we can display an admin notice.
40
+ public $api_secret_key = ''; //used to hold the user API. If not set then nothing will work!
41
+ public $install_key = false; //used to hold the install_key if set (included here for addons that will extend PUE to use install key checks)
42
+ public $dismiss_upgrade; //for setting the dismiss upgrade option (per plugin).
43
+ public $pue_install_key; //we'll customize this later so each plugin can have it's own install key!
44
+
45
+ /**
46
+ * Class constructor.
47
+ *
48
+ * @param string $pue_update_url The URL of the plugin's metadata file.
49
+ * @param string $slug The plugin's 'slug'.
50
+ * @param array $options Contains any options that need to be set in the class initialization for construct. These are the keys:
51
+ *
52
+ * @key integer $check_period How often to check for updates (in hours). Defaults to checking every 12 hours. Set to 0 to disable automatic update checks.
53
+ * @key string $pue_option_name Where to store book-keeping info about update checks. Defaults to 'external_updates-$slug'.
54
+ * @key string $apikey used to authorize download updates from developer server
55
+ *
56
+ * @param string $plugin_file fully qualified path to the main plugin file.
57
+ */
58
+ public function __construct( $pue_update_url, $slug = '', $options = array(), $plugin_file = '' ) {
59
+
60
+ $this->set_slug( $slug );
61
+ $this->set_pue_update_url( $pue_update_url );
62
+ $this->set_plugin_file( $plugin_file );
63
+ $this->set_options( $options );
64
+ $this->hooks();
65
+
66
+ }
67
+
68
+ /**
69
+ * Install the hooks required to run periodic update checks and inject update info
70
+ * into WP data structures.
71
+ * Also other hooks related to the automatic updates (such as checking agains API and what not (@from Darren)
72
+ */
73
+ public function hooks() {
74
+ // Override requests for plugin information
75
+ add_filter( 'plugins_api', array( &$this, 'inject_info' ), 10, 3 );
76
+
77
+ // Check for updates when the WP updates are checked and inject our update if needed.
78
+ // Only add filter if the TRIBE_DISABLE_PUE constant is not set as true.
79
+ if ( ! defined( 'TRIBE_DISABLE_PUE' ) || TRIBE_DISABLE_PUE !== true ) {
80
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_for_updates' ) );
81
+ }
82
+
83
+ add_filter( 'tribe_licensable_addons', array( $this, 'build_addon_list' ) );
84
+ add_action( 'tribe_license_fields', array( $this, 'do_license_key_fields' ) );
85
+ add_action( 'tribe_settings_after_content_tab_licenses', array( $this, 'do_license_key_javascript' ) );
86
+ add_action( 'tribe_settings_success_message', array( $this, 'do_license_key_success_message' ), 10, 2 );
87
+
88
+ // Key validation
89
+ add_action( 'wp_ajax_pue-validate-key_' . $this->get_slug(), array( $this, 'ajax_validate_key' ) );
90
+
91
+ // Dashboard message "dismiss upgrade" link
92
+ add_action( 'wp_ajax_' . $this->dismiss_upgrade, array( $this, 'dashboard_dismiss_upgrade' ) );
93
+
94
+ add_filter( 'tribe-pue-install-keys', array( $this, 'return_install_key' ) );
95
+ }
96
+
97
+ /********************** Getter / Setter Functions **********************/
98
+
99
+ /**
100
+ * Get the slug
101
+ *
102
+ * @return string
103
+ */
104
+ public function get_slug() {
105
+ return apply_filters( 'pue_get_slug', $this->slug );
106
+ }
107
+
108
+ /**
109
+ * Set the slug
110
+ *
111
+ * @param string $slug
112
+ */
113
+ private function set_slug( $slug = '' ) {
114
+ $this->slug = $slug;
115
+ $clean_slug = str_replace( '-', '_', $this->slug );
116
+ $this->dismiss_upgrade = 'pu_dismissed_upgrade_' . $clean_slug;
117
+ $this->pue_install_key = 'pue_install_key_' . $clean_slug;
118
+ }
119
+
120
+ /**
121
+ * Get the PUE update API endpoint url
122
+ *
123
+ * @return string
124
+ */
125
+ public function get_pue_update_url() {
126
+ return apply_filters( 'pue_get_update_url', $this->pue_update_url, $this->get_slug() );
127
+ }
128
+
129
+ /**
130
+ * Set the PUE update URL
131
+ *
132
+ * This can be overridden using the global constant 'PUE_UPDATE_URL'
133
+ *
134
+ * @param string $pue_update_url
135
+ */
136
+ private function set_pue_update_url( $pue_update_url ) {
137
+ $this->pue_update_url = ( defined( 'PUE_UPDATE_URL' ) ) ? trailingslashit( PUE_UPDATE_URL ) : trailingslashit( $pue_update_url );
138
+ }
139
+
140
+ /**
141
+ * Get the plugin file path
142
+ *
143
+ * @return string
144
+ */
145
+ public function get_plugin_file() {
146
+ return apply_filters( 'pue_get_plugin_file', $this->plugin_file, $this->get_slug() );
147
+ }
148
+
149
+ /**
150
+ * Set the plugin file path
151
+ *
152
+ * @param string $plugin_file
153
+ */
154
+ private function set_plugin_file( $plugin_file = '' ) {
155
+
156
+ if ( ! empty( $plugin_file ) ) {
157
+ $this->plugin_file = $plugin_file;
158
+
159
+ return;
160
+ }
161
+
162
+ $slug = $this->get_slug();
163
+ if ( ! empty( $slug ) ) {
164
+ $this->plugin_file = $slug . '/' . $slug . '.php';
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Set the plugin name
170
+ *
171
+ * @param string $plugin_name
172
+ */
173
+ private function set_plugin_name( $plugin_name = '' ) {
174
+ if ( ! empty( $plugin_name ) ) {
175
+ $this->plugin_name = $plugin_name;
176
+ } else {
177
+ //get name from plugin file itself
178
+ if ( ! function_exists( 'get_plugins' ) ) {
179
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
180
+ }
181
+
182
+ $plugin_details = explode( '/', $this->get_plugin_file() );
183
+ $plugin_folder = get_plugins( '/' . $plugin_details[0] );
184
+ $this->plugin_name = $plugin_folder[ $plugin_details[1] ]['Name'];
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Get the plugin name
190
+ *
191
+ * @return string
192
+ */
193
+ public function get_plugin_name() {
194
+ if ( empty( $this->plugin_name ) ) {
195
+ $this->set_plugin_name();
196
+ }
197
+
198
+ return apply_filters( 'pue_get_plugin_name', $this->plugin_name, $this->get_slug() );
199
+ }
200
+
201
+ /**
202
+ * Set all the PUE instantiation options
203
+ *
204
+ * @param array $options
205
+ */
206
+ private function set_options( $options = array() ) {
207
+
208
+ $options = wp_parse_args(
209
+ $options, array(
210
+ 'pue_option_name' => 'external_updates-' . $this->get_slug(),
211
+ 'apikey' => '',
212
+ 'installkey' => false,
213
+ 'check_period' => 12,
214
+ )
215
+ );
216
+
217
+ $this->pue_option_name = $options['pue_option_name'];
218
+ $this->check_period = (int) $options['check_period'];
219
+ $this->api_secret_key = $options['apikey'];
220
+ if ( isset( $options['installkey'] ) && $options['installkey'] ) {
221
+ $this->install_key = trim( $options['installkey'] );
222
+ } else {
223
+ $this->install_key = trim( $this->get_option( $this->pue_install_key ) );
224
+ }
225
+
226
+ }
227
+
228
+ /**
229
+ * Set all the download query array
230
+ *
231
+ * @param array $download_query
232
+ */
233
+ private function set_download_query( $download_query = array() ) {
234
+
235
+ if ( ! empty( $download_query ) ) {
236
+ $this->download_query = $download_query;
237
+
238
+ return;
239
+ }
240
+
241
+ //download query flag
242
+ $this->download_query['pu_get_download'] = 1;
243
+
244
+ //include current version
245
+ if ( $version = $this->get_installed_version() ) {
246
+ $this->download_query['pue_active_version'] = $version;
247
+ }
248
+
249
+ //the following is for install key inclusion (will apply later with PUE addons.)
250
+ if ( isset( $this->install_key ) ) {
251
+ $this->download_query['pu_install_key'] = $this->install_key;
252
+ }
253
+
254
+ if ( ! empty( $this->api_secret_key ) ) {
255
+ $this->download_query['pu_plugin_api'] = $this->api_secret_key;
256
+ }
257
+
258
+ }
259
+
260
+ /**
261
+ * Get the download_query args
262
+ *
263
+ * @return array
264
+ */
265
+ public function get_download_query() {
266
+ if ( empty( $this->download_query ) ) {
267
+ $this->set_download_query();
268
+ }
269
+
270
+ return apply_filters( 'pue_get_download_query', $this->download_query, $this->get_slug() );
271
+ }
272
+
273
+
274
+ /********************** General Functions **********************/
275
+
276
+ /**
277
+ * Compile a list of addons
278
+ *
279
+ * @param array $addons list of addons
280
+ *
281
+ * @return array list of addons
282
+ */
283
+ public function build_addon_list( $addons = array() ) {
284
+ $addons[] = $this->get_plugin_name();
285
+
286
+ return $addons;
287
+ }
288
+
289
+ /**
290
+ * Inserts license key fields on license key page
291
+ *
292
+ * @param array $fields List of fields
293
+ *
294
+ * @return array Modified list of fields.
295
+ */
296
+ public function do_license_key_fields( $fields ) {
297
+
298
+ // we want to inject the following license settings at the end of the licenses tab
299
+ $fields = self::array_insert_after_key( 'tribe-form-content-start', $fields, array(
300
+ $this->pue_install_key . '-heading' => array(
301
+ 'type' => 'heading',
302
+ 'label' => $this->get_plugin_name(),
303
+ ),
304
+ $this->pue_install_key => array(
305
+ 'type' => 'license_key',
306
+ 'size' => 'large',
307
+ 'validation_type' => 'license_key',
308
+ 'label' => sprintf( esc_attr__( 'License Key', 'tribe-common' ) ),
309
+ 'tooltip' => esc_html__( 'A valid license key is required for support and updates', 'tribe-common' ),
310
+ 'parent_option' => false,
311
+ 'network_option' => true,
312
+ ),
313
+ )
314
+ );
315
+
316
+ return $fields;
317
+ }
318
+
319
+ /**
320
+ * Inserts the javascript that makes the ajax checking
321
+ * work on the license key page
322
+ *
323
+ */
324
+ public function do_license_key_javascript() {
325
+ ?>
326
+ <script>
327
+ jQuery(document).ready(function ($) {
328
+ $('#tribe-field-<?php echo $this->pue_install_key ?>').change(function () {
329
+ <?php echo $this->pue_install_key ?>_validateKey();
330
+ });
331
+ <?php echo $this->pue_install_key ?>_validateKey();
332
+ });
333
+ function <?php echo $this->pue_install_key ?>_validateKey() {
334
+ var this_id = '#tribe-field-<?php echo $this->pue_install_key ?>';
335
+ var $validity_msg = jQuery(this_id + ' .key-validity');
336
+
337
+ if (jQuery(this_id + ' input').val() != '') {
338
+ jQuery(this_id + ' .tooltip').hide();
339
+ jQuery(this_id + ' .ajax-loading-license').show();
340
+ $validity_msg.hide();
341
+
342
+ // Strip whitespace from key
343
+ var <?php echo $this->pue_install_key ?>_license_key = jQuery(this_id + ' input').val().replace(/^\s+|\s+$/g, "");
344
+ jQuery(this_id + ' input').val(<?php echo $this->pue_install_key ?>_license_key);
345
+
346
+ var data = { action: 'pue-validate-key_<?php echo $this->get_slug(); ?>', key: <?php echo $this->pue_install_key ?>_license_key };
347
+ jQuery.post(ajaxurl, data, function (response) {
348
+ var data = jQuery.parseJSON(response);
349
+
350
+ jQuery(this_id + ' .ajax-loading-license').hide();
351
+ $validity_msg.show();
352
+ $validity_msg.html(data.message);
353
+
354
+ switch ( data.status ) {
355
+ case 1: $validity_msg.addClass( 'valid-key' ); break;
356
+ case 2: $validity_msg.addClass( 'valid-key service-msg' ); break;
357
+ default: $validity_msg.addClass( 'invalid-key' ); break;
358
+ }
359
+ });
360
+ }
361
+ }
362
+ </script>
363
+ <?php
364
+ }
365
+
366
+ /**
367
+ * Filter the success message on license key page
368
+ *
369
+ * @param string $message
370
+ * @param string $tab
371
+ *
372
+ * @return string
373
+ */
374
+ public function do_license_key_success_message( $message, $tab ) {
375
+
376
+ if ( $tab != 'licenses' ) {
377
+ return $message;
378
+ }
379
+
380
+ return '<div id="message" class="updated"><p><strong>' . esc_html__( 'License key(s) updated.', 'tribe-common' ) . '</strong></p></div>';
381
+
382
+ }
383
+
384
+ /**
385
+ * Echo JSON results for key validation
386
+ */
387
+ public function ajax_validate_key() {
388
+ $response = array();
389
+ $response['status'] = 0;
390
+ if ( isset( $_POST['key'] ) ) {
391
+
392
+ $queryArgs = array(
393
+ 'pu_install_key' => trim( $_POST['key'] ),
394
+ 'pu_checking_for_updates' => '1',
395
+ );
396
+
397
+ //include version info
398
+ $queryArgs['pue_active_version'] = $this->get_installed_version();
399
+
400
+ global $wp_version;
401
+ $queryArgs['wp_version'] = $wp_version;
402
+
403
+ // For multisite, return the network-level siteurl ... in
404
+ // all other cases return the actual URL being serviced
405
+ $queryArgs['domain'] = is_multisite() ? $this->get_network_domain() : $_SERVER['SERVER_NAME'];
406
+
407
+ if ( is_multisite() ) {
408
+ $queryArgs['multisite'] = 1;
409
+ $queryArgs['network_activated'] = is_plugin_active_for_network( $this->get_plugin_file() );
410
+ global $wpdb;
411
+ $queryArgs['active_sites'] = $wpdb->get_var( "SELECT count(blog_id) FROM $wpdb->blogs WHERE public = '1' AND archived = '0' AND spam = '0' AND deleted = '0'" );
412
+ } else {
413
+ $queryArgs['multisite'] = 0;
414
+ $queryArgs['network_activated'] = 0;
415
+ $queryArgs['active_sites'] = 1;
416
+ }
417
+
418
+ $pluginInfo = $this->request_info( $queryArgs );
419
+ $expiration = isset( $pluginInfo->expiration ) ? $pluginInfo->expiration : esc_html__( 'unknown date', 'tribe-common' );
420
+
421
+ if ( empty( $pluginInfo ) ) {
422
+ $response['message'] = esc_html__( 'Sorry, key validation server is not available.', 'tribe-common' );
423
+ } elseif ( isset( $pluginInfo->api_expired ) && $pluginInfo->api_expired == 1 ) {
424
+ $response['message'] = $this->get_api_message( $pluginInfo );
425
+ } elseif ( isset( $pluginInfo->api_upgrade ) && $pluginInfo->api_upgrade == 1 ) {
426
+ $response['message'] = $this->get_api_message( $pluginInfo );
427
+ } elseif ( isset( $pluginInfo->api_invalid ) && $pluginInfo->api_invalid == 1 ) {
428
+ $response['message'] = $this->get_api_message( $pluginInfo );
429
+ } else {
430
+ $api_secret_key = get_option( $this->pue_install_key );
431
+ if ( $api_secret_key && $api_secret_key === $queryArgs['pu_install_key'] ){
432
+ $default_success_msg = sprintf( esc_html__( 'Valid Key! Expires on %s', 'tribe-common' ), $expiration );
433
+ } else {
434
+ // Set the key
435
+ update_option( $this->pue_install_key, $queryArgs['pu_install_key'] );
436
+
437
+ $default_success_msg = sprintf( esc_html__( 'Thanks for setting up a valid key, it will expire on %s', 'tribe-common' ), $expiration );
438
+ }
439
+
440
+ $response['status'] = isset( $pluginInfo->api_message ) ? 2 : 1;
441
+ $response['message'] = isset( $pluginInfo->api_message ) ? wp_kses( $pluginInfo->api_message, 'data' ) : $default_success_msg;
442
+ $response['expiration'] = $expiration;
443
+ }
444
+ } else {
445
+ $response['message'] = sprintf( esc_html__( 'Hmmm... something\'s wrong with this validator. Please contact %ssupport%s.', 'tribe-common' ), '<a href="http://m.tri.be/1u">', '</a>' );
446
+ }
447
+ echo json_encode( $response );
448
+ exit;
449
+ }
450
+
451
+ /**
452
+ * processes variable substitutions for server-side API message
453
+ */
454
+ private function get_api_message( $info ) {
455
+ // this default message should never show, but is here as a fallback just in case.
456
+ $message = sprintf(
457
+ esc_html__( 'Sorry, there is a problem with your license key. You\'ll need to %scheck your license%s to have access to updates, downloads, and support.', 'tribe-common' ),
458
+ '<a href="https://theeventscalendar.com/license-keys/">',
459
+ '</a>'
460
+ );
461
+
462
+ if ( ! empty( $info->api_invalid_message ) ) {
463
+ $message = wp_kses( $info->api_invalid_message, 'post' );
464
+ }
465
+
466
+ $message = str_replace( '%plugin_name%', '<b>' . $this->get_plugin_name() . '</b>', $message );
467
+ $message = str_replace( '%plugin_slug%', $this->get_slug(), $message );
468
+ $message = str_replace( '%update_url%', $this->get_pue_update_url(), $message );
469
+ $message = str_replace( '%version%', $info->version, $message );
470
+
471
+ return $message;
472
+ }
473
+
474
+ /**
475
+ * Echo JSON formatted errors
476
+ */
477
+ public function display_json_error() {
478
+ $pluginInfo = $this->json_error;
479
+ $update_dismissed = $this->get_option( $this->dismiss_upgrade );
480
+
481
+ $is_dismissed = ! empty( $update_dismissed ) && in_array( $pluginInfo->version, $update_dismissed ) ? true : false;
482
+
483
+ if ( $is_dismissed ) {
484
+ return;
485
+ }
486
+
487
+ if ( ! current_user_can( 'administrator' ) ) {
488
+ return;
489
+ }
490
+
491
+ //only display messages if there is a new version of the plugin.
492
+ if ( version_compare( $pluginInfo->version, $this->get_installed_version(), '>' ) ) {
493
+ if ( empty( $pluginInfo->api_invalid ) || $pluginInfo->api_invalid != 1 ) {
494
+ return;
495
+ }
496
+
497
+ $msg = $this->get_api_message( $pluginInfo );
498
+
499
+ //Dismiss code idea below is obtained from the Gravity Forms Plugin by rocketgenius.com
500
+ ?>
501
+ <div class="updated" style="padding:5px; position:relative;" id="pu_dashboard_message"><?php echo wp_kses( $msg, 'post' ); ?>
502
+ <a href="javascript:void(0);" onclick="PUDismissUpgrade();" style="float:right;">[X]</a>
503
+ </div>
504
+ <script type="text/javascript">
505
+ function PUDismissUpgrade() {
506
+ jQuery("#pu_dashboard_message").slideUp();
507
+ jQuery.post( ajaxurl, {
508
+ action: "<?php echo esc_attr( $this->dismiss_upgrade ); ?>",
509
+ version: "<?php echo esc_attr( $pluginInfo->version ); ?>",
510
+ cookie: encodeURIComponent(document.cookie)
511
+ } );
512
+ }
513
+ </script>
514
+ <?php
515
+ }
516
+ }
517
+
518
+ /**
519
+ * Retrieve plugin info from the configured API endpoint.
520
+ *
521
+ * @param array $queryArgs Additional query arguments to append to the request. Optional.
522
+ *
523
+ * @uses wp_remote_get()
524
+ * @return string $pluginInfo
525
+ */
526
+ public function request_info( $queryArgs = array() ) {
527
+ //Query args to append to the URL. Plugins can add their own by using a filter callback (see add_query_arg_filter()).
528
+ $queryArgs['installed_version'] = $this->get_installed_version();
529
+ $queryArgs['pu_request_plugin'] = $this->get_slug();
530
+
531
+ if ( empty( $queryArgs['pu_plugin_api'] ) && ! empty( $this->api_secret_key ) ) {
532
+ $queryArgs['pu_plugin_api'] = $this->api_secret_key;
533
+ }
534
+
535
+ if ( empty( $queryArgs['pu_install_key'] ) && ! empty( $this->install_key ) ) {
536
+ $queryArgs['pu_install_key'] = $this->install_key;
537
+ }
538
+
539
+ //include version info
540
+ $queryArgs['pue_active_version'] = $this->get_installed_version();
541
+
542
+ global $wp_version;
543
+ $queryArgs['wp_version'] = $wp_version;
544
+
545
+ //include domain and multisite stats
546
+ $queryArgs['domain'] = is_multisite() ? $this->get_network_domain() : $_SERVER['SERVER_NAME'];
547
+
548
+ if ( is_multisite() ) {
549
+ $queryArgs['multisite'] = 1;
550
+ $queryArgs['network_activated'] = is_plugin_active_for_network( $this->get_plugin_file() );
551
+ global $wpdb;
552
+ $queryArgs['active_sites'] = $wpdb->get_var( "SELECT count(blog_id) FROM $wpdb->blogs WHERE public = '1' AND archived = '0' AND spam = '0' AND deleted = '0'" );
553
+
554
+ } else {
555
+ $queryArgs['multisite'] = 0;
556
+ $queryArgs['network_activated'] = 0;
557
+ $queryArgs['active_sites'] = 1;
558
+ }
559
+
560
+ $queryArgs = apply_filters( 'tribe_puc_request_info_query_args-' . $this->get_slug(), $queryArgs );
561
+
562
+ //Various options for the wp_remote_get() call. Plugins can filter these, too.
563
+ $options = array(
564
+ 'timeout' => 15, //seconds
565
+ 'headers' => array(
566
+ 'Accept' => 'application/json',
567
+ ),
568
+ );
569
+ $options = apply_filters( 'tribe_puc_request_info_options-' . $this->get_slug(), $options );
570
+
571
+ $url = $this->get_pue_update_url();
572
+ if ( ! empty( $queryArgs ) ) {
573
+ $url = esc_url_raw( add_query_arg( $queryArgs, $url ) );
574
+ }
575
+
576
+ // Cache the API call so it only needs to be made once per plugin per page load.
577
+ static $plugin_info_cache;
578
+ $key = crc32( implode( '', $queryArgs ) );
579
+ if ( isset( $plugin_info_cache[ $key ] ) ) {
580
+ return $plugin_info_cache[ $key ];
581
+ }
582
+
583
+ $result = wp_remote_get(
584
+ $url,
585
+ $options
586
+ );
587
+
588
+ //Try to parse the response
589
+ $pluginInfo = null;
590
+ if ( ! is_wp_error( $result ) && isset( $result['response']['code'] ) && ( $result['response']['code'] == 200 ) && ! empty( $result['body'] ) ) {
591
+ $pluginInfo = Tribe__PUE__Plugin_Info::from_json( $result['body'] );
592
+ }
593
+ $pluginInfo = apply_filters( 'tribe_puc_request_info_result-' . $this->get_slug(), $pluginInfo, $result );
594
+
595
+ $plugin_info_cache[ $key ] = $pluginInfo;
596
+
597
+ return $pluginInfo;
598
+ }
599
+
600
+ /**
601
+ * Returns the domain contained in the network's siteurl option (not the full URL).
602
+ *
603
+ * @return string
604
+ */
605
+ public function get_network_domain() {
606
+ $site_url = parse_url( get_site_option( 'siteurl' ) );
607
+ if ( ! $site_url || ! isset( $site_url['host'] ) ) {
608
+ return '';
609
+ } else {
610
+ return strtolower( $site_url['host'] );
611
+ }
612
+ }
613
+
614
+ /**
615
+ * Retrieve the latest update (if any) from the configured API endpoint.
616
+ *
617
+ * @uses Tribe__PUE__Checker::request_info()
618
+ *
619
+ * @return Tribe__PUE__Utility An instance of Tribe__PUE__Utility, or NULL when no updates are available.
620
+ */
621
+ public function request_update() {
622
+ //For the sake of simplicity, this function just calls request_info()
623
+ //and transforms the result accordingly.
624
+ $pluginInfo = $this->request_info( array( 'pu_checking_for_updates' => '1' ) );
625
+ if ( $pluginInfo == null ) {
626
+ return null;
627
+ }
628
+ //admin display for if the update check reveals that there is a new version but the API key isn't valid.
629
+ if ( isset( $pluginInfo->api_invalid ) ) { //we have json_error returned let's display a message
630
+ $this->json_error = $pluginInfo;
631
+ add_action( 'admin_notices', array( &$this, 'display_json_error' ) );
632
+
633
+ return null;
634
+ }
635
+
636
+ if ( isset( $pluginInfo->new_install_key ) ) {
637
+ $this->update_option( $this->pue_install_key, $pluginInfo->new_install_key );
638
+ }
639
+
640
+ //need to correct the download url so it contains the custom user data (i.e. api and any other paramaters)
641
+
642
+ $download_query = $this->get_download_query();
643
+ if ( ! empty( $download_query ) ) {
644
+ $pluginInfo->download_url = esc_url_raw( add_query_arg( $download_query, $pluginInfo->download_url ) );
645
+ }
646
+
647
+ // Add plugin dirname/file (this will be expected by WordPress when it builds the plugin list table)
648
+ $pluginInfo->plugin = $this->get_plugin_file();
649
+
650
+ return Tribe__PUE__Utility::from_plugin_info( $pluginInfo );
651
+ }
652
+
653
+
654
+ /**
655
+ * Display the upgrade message in the plugin list under the plugin.
656
+ *
657
+ * @param $plugin_data
658
+ */
659
+ public function in_plugin_update_message( $plugin_data ) {
660
+ $plugininfo = $this->json_error;
661
+ //only display messages if there is a new version of the plugin.
662
+ if ( is_object( $plugininfo ) && version_compare( $plugininfo->version, $this->get_installed_version(), '>' ) ) {
663
+ if ( $plugininfo->api_invalid ) {
664
+ $msg = str_replace( '%plugin_name%', '<strong>' . $this->get_plugin_name() . '</strong>', $plugininfo->api_inline_invalid_message );
665
+ $msg = str_replace( '%plugin_slug%', $this->get_slug(), $msg );
666
+ $msg = str_replace( '%update_url%', $this->get_pue_update_url(), $msg );
667
+ $msg = str_replace( '%version%', $plugininfo->version, $msg );
668
+ $msg = str_replace( '%changelog%', '<a class="thickbox" title="' . $this->get_plugin_name() . '" href="plugin-install.php?tab=plugin-information&plugin=' . $this->get_slug() . '&TB_iframe=true&width=640&height=808">what\'s new</a>', $msg );
669
+ echo '</tr><tr class="plugin-update-tr"><td colspan="3" class="plugin-update"><div class="update-message">' . $msg . '</div></td>';
670
+ }
671
+ }
672
+ }
673
+
674
+
675
+ /**
676
+ * Display a changelog when the api key is missing.
677
+ */
678
+ public function display_changelog() {
679
+ //contents of changelog display page when api-key is invalid or missing. It will ONLY show the changelog (hook into existing thickbox?)
680
+ }
681
+
682
+ /**
683
+ * Update option to dismiss the upgrade notice.
684
+ */
685
+ public function dashboard_dismiss_upgrade() {
686
+ $os_ary = $this->get_option( $this->dismiss_upgrade );
687
+ if ( ! is_array( $os_ary ) ) {
688
+ $os_ary = array();
689
+ }
690
+
691
+ $os_ary[] = $_POST['version'];
692
+ $this->update_option( $this->dismiss_upgrade, $os_ary );
693
+ }
694
+
695
+ /**
696
+ * Get the currently installed version of the plugin.
697
+ *
698
+ * @return string Version number.
699
+ */
700
+ public function get_installed_version() {
701
+ if ( function_exists( 'get_plugins' ) ) {
702
+ $allPlugins = get_plugins();
703
+ if ( array_key_exists( $this->get_plugin_file(), $allPlugins ) && array_key_exists( 'Version', $allPlugins[ $this->get_plugin_file() ] ) ) {
704
+ return $allPlugins[ $this->get_plugin_file() ]['Version'];
705
+ }
706
+ }
707
+ }
708
+
709
+ /**
710
+ * Get MU compatible options.
711
+ *
712
+ * @param string $option_key
713
+ * @param bool|mixed $default
714
+ *
715
+ * @return null|mixed
716
+ */
717
+ public function get_option( $option_key, $default = false ) {
718
+ return get_site_option( $option_key, $default );
719
+ }
720
+
721
+ /**
722
+ * Update MU compatible options.
723
+ *
724
+ * @param mixed $option_key
725
+ * @param mixed $value
726
+ */
727
+ public function update_option( $option_key, $value ) {
728
+ update_site_option( $option_key, $value );
729
+ }
730
+
731
+ /**
732
+ * Check for plugin updates.
733
+ *
734
+ * The results are stored in the DB option specified in $pue_option_name.
735
+ *
736
+ * @param array $updates
737
+ *
738
+ */
739
+ public function check_for_updates( $updates = array() ) {
740
+ $state = $this->get_option( $this->pue_option_name );
741
+ if ( empty( $state ) ) {
742
+ $state = new StdClass;
743
+ $state->lastCheck = 0;
744
+ $state->checkedVersion = '';
745
+ $state->update = null;
746
+ }
747
+
748
+ $state->lastCheck = time();
749
+ $state->checkedVersion = $this->get_installed_version();
750
+ $this->update_option( $this->pue_option_name, $state ); //Save before checking in case something goes wrong
751
+
752
+ $state->update = $this->request_update();
753
+
754
+ // If a null update was returned, skip the end of the function.
755
+ if ( $state->update == null ) {
756
+ return $updates;
757
+ }
758
+
759
+ //Is there an update to insert?
760
+ if ( version_compare( $state->update->version, $this->get_installed_version(), '>' ) ) {
761
+ $updates->response[ $this->get_plugin_file() ] = $state->update->to_wp_format();
762
+ }
763
+
764
+ $this->update_option( $this->pue_option_name, $state );
765
+ add_action( 'after_plugin_row_' . $this->get_plugin_file(), array( &$this, 'in_plugin_update_message' ) );
766
+
767
+ return $updates;
768
+ }
769
+
770
+ /**
771
+ * Intercept plugins_api() calls that request information about our plugin and
772
+ * use the configured API endpoint to satisfy them.
773
+ *
774
+ * @see plugins_api()
775
+ *
776
+ * @param mixed $result
777
+ * @param string $action
778
+ * @param array|object $args
779
+ *
780
+ * @return mixed
781
+ */
782
+ public function inject_info( $result, $action = null, $args = null ) {
783
+ $relevant = ( $action == 'plugin_information' ) && isset( $args->slug ) && ( $args->slug == $this->slug );
784
+ if ( ! $relevant ) {
785
+ return $result;
786
+ }
787
+
788
+ $pluginInfo = $this->request_info( array( 'pu_checking_for_updates' => '1' ) );
789
+ if ( $pluginInfo ) {
790
+ return $pluginInfo->to_wp_format();
791
+ }
792
+
793
+ return $result;
794
+ }
795
+
796
+ /**
797
+ * Register a callback for filtering query arguments.
798
+ *
799
+ * The callback function should take one argument - an associative array of query arguments.
800
+ * It should return a modified array of query arguments.
801
+ *
802
+ * @uses add_filter() This method is a convenience wrapper for add_filter().
803
+ *
804
+ * @param callback $callback
805
+ *
806
+ */
807
+ public function add_query_arg_filter( $callback ) {
808
+ add_filter( 'tribe_puc_request_info_query_args-' . $this->get_slug(), $callback );
809
+ }
810
+
811
+ /**
812
+ * Register a callback for filtering arguments passed to wp_remote_get().
813
+ *
814
+ * The callback function should take one argument - an associative array of arguments -
815
+ * and return a modified array or arguments. See the WP documentation on wp_remote_get()
816
+ * for details on what arguments are available and how they work.
817
+ *
818
+ * @uses add_filter() This method is a convenience wrapper for add_filter().
819
+ *
820
+ * @param callback $callback
821
+ *
822
+ */
823
+ public function add_http_request_arg_filter( $callback ) {
824
+ add_filter( 'tribe_puc_request_info_options-' . $this->get_slug(), $callback );
825
+ }
826
+
827
+ /**
828
+ * Register a callback for filtering the plugin info retrieved from the external API.
829
+ *
830
+ * The callback function should take two arguments. If the plugin info was retrieved
831
+ * successfully, the first argument passed will be an instance of Tribe__PUE__Plugin_Info. Otherwise,
832
+ * it will be NULL. The second argument will be the corresponding return value of
833
+ * wp_remote_get (see WP docs for details).
834
+ *
835
+ * The callback function should return a new or modified instance of Tribe__PUE__Plugin_Info or NULL.
836
+ *
837
+ * @uses add_filter() This method is a convenience wrapper for add_filter().
838
+ *
839
+ * @param callback $callback
840
+ *
841
+ */
842
+ public function add_result_filter( $callback ) {
843
+ add_filter( 'tribe_puc_request_info_result-' . $this->get_slug(), $callback, 10, 2 );
844
+ }
845
+
846
+ /**
847
+ * Insert an array after a specified key within another array.
848
+ *
849
+ * @param $key
850
+ * @param $source_array
851
+ * @param $insert_array
852
+ *
853
+ * @return array
854
+ *
855
+ */
856
+ public static function array_insert_after_key( $key, $source_array, $insert_array ) {
857
+ if ( array_key_exists( $key, $source_array ) ) {
858
+ $position = array_search( $key, array_keys( $source_array ) ) + 1;
859
+ $source_array = array_slice( $source_array, 0, $position, true ) + $insert_array + array_slice( $source_array, $position, null, true );
860
+ } else {
861
+ // If no key is found, then add it to the end of the array.
862
+ $source_array += $insert_array;
863
+ }
864
+
865
+ return $source_array;
866
+ }
867
+
868
+ /**
869
+ * Add this plugin key to the list of keys
870
+ *
871
+ * @param array $keys
872
+ *
873
+ * @return array $keys
874
+ *
875
+ */
876
+ public function return_install_key( $keys = array() ) {
877
+ if ( ! empty( $this->install_key ) ) {
878
+ $keys[ $this->get_slug() ] = $this->install_key;
879
+ }
880
+
881
+ return $keys;
882
+ }
883
+ }
884
+ }
common/src/Tribe/PUE/Plugin_Info.php CHANGED
@@ -1,128 +1,128 @@
1
- <?php
2
- /**
3
- * Plugin Info Class
4
- *
5
- * This is a direct port to Tribe Commons of the PUE classes contained
6
- * in The Events Calendar.
7
- *
8
- * @todo switch all plugins over to use the PUE utilities here in Commons
9
- */
10
-
11
- // Don't load directly
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- die( '-1' );
14
- }
15
-
16
- if ( ! class_exists( 'Tribe__PUE__Plugin_Info' ) ) {
17
- /**
18
- * A container class for holding and transforming various plugin metadata.
19
- * @version 1.7
20
- * @access public
21
- */
22
- class Tribe__PUE__Plugin_Info {
23
- // Most fields map directly to the contents of the plugin's info.json file.
24
-
25
- public $name;
26
- public $slug;
27
- public $version;
28
- public $homepage;
29
- public $sections;
30
- public $download_url;
31
-
32
- public $author;
33
- public $author_homepage;
34
-
35
- public $requires;
36
- public $tested;
37
- public $upgrade_notice;
38
-
39
- public $rating;
40
- public $num_ratings;
41
- public $downloaded;
42
- public $last_updated;
43
-
44
- public $id = 0; // The native WP.org API returns numeric plugin IDs, but they're not used for anything.
45
-
46
- /**
47
- * Create a new instance of Tribe__PUE__Plugin_Info from JSON-encoded plugin info
48
- * returned by an external update API.
49
- *
50
- * @param string $json Valid JSON string representing plugin info.
51
- *
52
- *@return Tribe__PUE__Plugin_Info New instance of Tribe__PUE__Plugin_Info, or NULL on error.
53
- */
54
- public static function from_json( $json ) {
55
- $apiResponse = json_decode( $json );
56
- if ( empty( $apiResponse ) || ! is_object( $apiResponse ) ) {
57
- return null;
58
- }
59
-
60
- //Very, very basic validation.
61
- $valid = ( isset( $apiResponse->name ) && ! empty( $apiResponse->name ) && isset( $apiResponse->version ) && ! empty( $apiResponse->version ) ) || ( isset( $apiResponse->api_invalid ) || isset( $apiResponse->no_api ) );
62
- if ( ! $valid ) {
63
- return null;
64
- }
65
-
66
- $info = new Tribe__PUE__Plugin_Info();
67
-
68
- foreach ( get_object_vars( $apiResponse ) as $key => $value ) {
69
- $key = str_replace( 'plugin_', '', $key ); // let's strip out the "plugin_" prefix we've added in plugin-updater-classes.
70
- $info->$key = $value;
71
- }
72
-
73
- return $info;
74
- }
75
-
76
- /**
77
- * Transform plugin info into the format used by the native WordPress.org API
78
- *
79
- * @return object
80
- */
81
- public function to_wp_format() {
82
- $info = new StdClass;
83
-
84
- // The custom update API is built so that many fields have the same name and format
85
- // as those returned by the native WordPress.org API. These can be assigned directly.
86
-
87
- $sameFormat = array(
88
- 'name',
89
- 'slug',
90
- 'version',
91
- 'requires',
92
- 'tested',
93
- 'rating',
94
- 'upgrade_notice',
95
- 'num_ratings',
96
- 'downloaded',
97
- 'homepage',
98
- 'last_updated',
99
- );
100
- foreach ( $sameFormat as $field ) {
101
- if ( isset( $this->$field ) ) {
102
- $info->$field = $this->$field;
103
- } else {
104
- $info->$field = null;
105
- }
106
- }
107
-
108
- //Other fields need to be renamed and/or transformed.
109
- $info->download_link = $this->download_url;
110
-
111
- if ( ! empty( $this->author_homepage ) ) {
112
- $info->author = sprintf( '<a href="%s">%s</a>', esc_url( $this->author_homepage ), $this->author );
113
- } else {
114
- $info->author = $this->author;
115
- }
116
-
117
- if ( is_object( $this->sections ) ) {
118
- $info->sections = get_object_vars( $this->sections );
119
- } elseif ( is_array( $this->sections ) ) {
120
- $info->sections = $this->sections;
121
- } else {
122
- $info->sections = array( 'description' => '' );
123
- }
124
-
125
- return $info;
126
- }
127
- }
128
- }
1
+ <?php
2
+ /**
3
+ * Plugin Info Class
4
+ *
5
+ * This is a direct port to Tribe Commons of the PUE classes contained
6
+ * in The Events Calendar.
7
+ *
8
+ * @todo switch all plugins over to use the PUE utilities here in Commons
9
+ */
10
+
11
+ // Don't load directly
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die( '-1' );
14
+ }
15
+
16
+ if ( ! class_exists( 'Tribe__PUE__Plugin_Info' ) ) {
17
+ /**
18
+ * A container class for holding and transforming various plugin metadata.
19
+ * @version 1.7
20
+ * @access public
21
+ */
22
+ class Tribe__PUE__Plugin_Info {
23
+ // Most fields map directly to the contents of the plugin's info.json file.
24
+
25
+ public $name;
26
+ public $slug;
27
+ public $version;
28
+ public $homepage;
29
+ public $sections;
30
+ public $download_url;
31
+
32
+ public $author;
33
+ public $author_homepage;
34
+
35
+ public $requires;
36
+ public $tested;
37
+ public $upgrade_notice;
38
+
39
+ public $rating;
40
+ public $num_ratings;
41
+ public $downloaded;
42
+ public $last_updated;
43
+
44
+ public $id = 0; // The native WP.org API returns numeric plugin IDs, but they're not used for anything.
45
+
46
+ /**
47
+ * Create a new instance of Tribe__PUE__Plugin_Info from JSON-encoded plugin info
48
+ * returned by an external update API.
49
+ *
50
+ * @param string $json Valid JSON string representing plugin info.
51
+ *
52
+ *@return Tribe__PUE__Plugin_Info New instance of Tribe__PUE__Plugin_Info, or NULL on error.
53
+ */
54
+ public static function from_json( $json ) {
55
+ $apiResponse = json_decode( $json );
56
+ if ( empty( $apiResponse ) || ! is_object( $apiResponse ) ) {
57
+ return null;
58
+ }
59
+
60
+ //Very, very basic validation.
61
+ $valid = ( isset( $apiResponse->name ) && ! empty( $apiResponse->name ) && isset( $apiResponse->version ) && ! empty( $apiResponse->version ) ) || ( isset( $apiResponse->api_invalid ) || isset( $apiResponse->no_api ) );
62
+ if ( ! $valid ) {
63
+ return null;
64
+ }
65
+
66
+ $info = new Tribe__PUE__Plugin_Info();
67
+
68
+ foreach ( get_object_vars( $apiResponse ) as $key => $value ) {
69
+ $key = str_replace( 'plugin_', '', $key ); // let's strip out the "plugin_" prefix we've added in plugin-updater-classes.
70
+ $info->$key = $value;
71
+ }
72
+
73
+ return $info;
74
+ }
75
+
76
+ /**
77
+ * Transform plugin info into the format used by the native WordPress.org API
78
+ *
79
+ * @return object
80
+ */
81
+ public function to_wp_format() {
82
+ $info = new StdClass;
83
+
84
+ // The custom update API is built so that many fields have the same name and format
85
+ // as those returned by the native WordPress.org API. These can be assigned directly.
86
+
87
+ $sameFormat = array(
88
+ 'name',
89
+ 'slug',
90
+ 'version',
91
+ 'requires',
92
+ 'tested',
93
+ 'rating',
94
+ 'upgrade_notice',
95
+ 'num_ratings',
96
+ 'downloaded',
97
+ 'homepage',
98
+ 'last_updated',
99
+ );
100
+ foreach ( $sameFormat as $field ) {
101
+ if ( isset( $this->$field ) ) {
102
+ $info->$field = $this->$field;
103
+ } else {
104
+ $info->$field = null;
105
+ }
106
+ }
107
+
108
+ //Other fields need to be renamed and/or transformed.
109
+ $info->download_link = $this->download_url;
110
+
111
+ if ( ! empty( $this->author_homepage ) ) {
112
+ $info->author = sprintf( '<a href="%s">%s</a>', esc_url( $this->author_homepage ), $this->author );
113
+ } else {
114
+ $info->author = $this->author;
115
+ }
116
+
117
+ if ( is_object( $this->sections ) ) {
118
+ $info->sections = get_object_vars( $this->sections );
119
+ } elseif ( is_array( $this->sections ) ) {
120
+ $info->sections = $this->sections;
121
+ } else {
122
+ $info->sections = array( 'description' => '' );
123
+ }
124
+
125
+ return $info;
126
+ }
127
+ }
128
+ }
common/src/Tribe/PUE/Utility.php CHANGED
@@ -1,92 +1,92 @@
1
- <?php
2
- /**
3
- * Plugin Update Utility Class.
4
- *
5
- * This is a direct port to Tribe Commons of the PUE classes contained
6
- * in The Events Calendar.
7
- *
8
- * @todo switch all plugins over to use the PUE utilities here in Commons
9
- */
10
-
11
- // Don't load directly
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- die( '-1' );
14
- }
15
-
16
- if ( ! class_exists( 'Tribe__PUE__Utility' ) ) {
17
-
18
- /**
19
- * A simple container class for holding information about an available update.
20
- *
21
- * @version 1.7
22
- * @access public
23
- */
24
- class Tribe__PUE__Utility {
25
- public $id = 0;
26
- public $plugin;
27
- public $slug;
28
- public $version;
29
- public $homepage;
30
- public $download_url;
31
- public $sections = array();
32
- public $upgrade_notice;
33
-
34
- /**
35
- * Create a new instance of Tribe__PUE__Utility from its JSON-encoded representation.
36
- *
37
- * @param string $json
38
- *
39
- * @return Tribe__PUE__Utility
40
- */
41
- public static function from_json( $json ) {
42
- //Since update-related information is simply a subset of the full plugin info,
43
- //we can parse the update JSON as if it was a plugin info string, then copy over
44
- //the parts that we care about.
45
- $pluginInfo = Tribe__PUE__Plugin_Info::from_json( $json );
46
- if ( $pluginInfo != null ) {
47
- return self::from_plugin_info( $pluginInfo );
48
- } else {
49
- return null;
50
- }
51
- }
52
-
53
- /**
54
- * Create a new instance of Tribe__PUE__Utility based on an instance of Tribe__PUE__Plugin_Info.
55
- * Basically, this just copies a subset of fields from one object to another.
56
- *
57
- * @param Tribe__PUE__Plugin_Info $info
58
- *
59
- * @return Tribe__PUE__Utility
60
- */
61
- public static function from_plugin_info( $info ) {
62
- $update = new Tribe__PUE__Utility();
63
- $copyFields = array( 'id', 'slug', 'version', 'homepage', 'download_url', 'upgrade_notice', 'sections', 'plugin' );
64
- foreach ( $copyFields as $field ) {
65
- $update->$field = $info->$field;
66
- }
67
-
68
- return $update;
69
- }
70
-
71
- /**
72
- * Transform the update into the format used by WordPress native plugin API.
73
- *
74
- * @return object
75
- */
76
- public function to_wp_format() {
77
- $update = new StdClass;
78
-
79
- $update->id = $this->id;
80
- $update->plugin = $this->plugin;
81
- $update->slug = $this->slug;
82
- $update->new_version = $this->version;
83
- $update->url = $this->homepage;
84
- $update->package = $this->download_url;
85
- if ( ! empty( $this->upgrade_notice ) ) {
86
- $update->upgrade_notice = $this->upgrade_notice;
87
- }
88
-
89
- return $update;
90
- }
91
- }
92
- }
1
+ <?php
2
+ /**
3
+ * Plugin Update Utility Class.
4
+ *
5
+ * This is a direct port to Tribe Commons of the PUE classes contained
6
+ * in The Events Calendar.
7
+ *
8
+ * @todo switch all plugins over to use the PUE utilities here in Commons
9
+ */
10
+
11
+ // Don't load directly
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ die( '-1' );
14
+ }
15
+
16
+ if ( ! class_exists( 'Tribe__PUE__Utility' ) ) {
17
+
18
+ /**
19
+ * A simple container class for holding information about an available update.
20
+ *
21
+ * @version 1.7
22
+ * @access public
23
+ */
24
+ class Tribe__PUE__Utility {
25
+ public $id = 0;
26
+ public $plugin;
27
+ public $slug;
28
+ public $version;
29
+ public $homepage;
30
+ public $download_url;
31
+ public $sections = array();
32
+ public $upgrade_notice;
33
+
34
+ /**
35
+ * Create a new instance of Tribe__PUE__Utility from its JSON-encoded representation.
36
+ *
37
+ * @param string $json
38
+ *
39
+ * @return Tribe__PUE__Utility
40
+ */
41
+ public static function from_json( $json ) {
42
+ //Since update-related information is simply a subset of the full plugin info,
43
+ //we can parse the update JSON as if it was a plugin info string, then copy over
44
+ //the parts that we care about.
45
+ $pluginInfo = Tribe__PUE__Plugin_Info::from_json( $json );
46
+ if ( $pluginInfo != null ) {
47
+ return self::from_plugin_info( $pluginInfo );
48
+ } else {
49
+ return null;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Create a new instance of Tribe__PUE__Utility based on an instance of Tribe__PUE__Plugin_Info.
55
+ * Basically, this just copies a subset of fields from one object to another.
56
+ *
57
+ * @param Tribe__PUE__Plugin_Info $info
58
+ *
59
+ * @return Tribe__PUE__Utility
60
+ */
61
+ public static function from_plugin_info( $info ) {
62
+ $update = new Tribe__PUE__Utility();
63
+ $copyFields = array( 'id', 'slug', 'version', 'homepage', 'download_url', 'upgrade_notice', 'sections', 'plugin' );
64
+ foreach ( $copyFields as $field ) {
65
+ $update->$field = $info->$field;
66
+ }
67
+
68
+ return $update;
69
+ }
70
+
71
+ /**
72
+ * Transform the update into the format used by WordPress native plugin API.
73
+ *
74
+ * @return object
75
+ */
76
+ public function to_wp_format() {
77
+ $update = new StdClass;
78
+
79
+ $update->id = $this->id;
80
+ $update->plugin = $this->plugin;
81
+ $update->slug = $this->slug;
82
+ $update->new_version = $this->version;
83
+ $update->url = $this->homepage;
84
+ $update->package = $this->download_url;
85
+ if ( ! empty( $this->upgrade_notice ) ) {
86
+ $update->upgrade_notice = $this->upgrade_notice;
87
+ }
88
+
89
+ return $update;
90
+ }
91
+ }
92
+ }
common/src/Tribe/Plugin_Download_Notice.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Don't load directly
3
+ defined( 'WPINC' ) or die;
4
+
5
+ if ( ! class_exists( 'Tribe__Plugin_Download_Notice' ) ) {
6
+
7
+ /**
8
+ * Shows an admin notice telling users which requisite plugins they need to download
9
+ *
10
+ * @TODO This whole thing could be reworked in post 4.3 or possibly removed with the introduction of tribe_notice()
11
+ */
12
+ class Tribe__Plugin_Download_Notice {
13
+
14
+ private $plugin_path;
15
+
16
+ private $plugins_required = array();
17
+
18
+ /**
19
+ * @param string $plugin_path Path to the plugin file we're showing a notice for
20
+ */
21
+ public function __construct( $plugin_path ) {
22
+ $this->plugin_path = $plugin_path;
23
+ add_action( 'admin_notices', array( $this, 'show_inactive_plugins_alert' ) );
24
+ }
25
+
26
+ /**
27
+ * Add a required plugin to the notice
28
+ *
29
+ * @param string $name Name of the required plugin
30
+ * @param null $thickbox_url Download or purchase URL for plugin from within /wp-admin/ thickbox
31
+ */
32
+ public function add_required_plugin( $name, $thickbox_url = null ) {
33
+ $this->plugins_required[ $name ] = array(
34
+ 'name' => $name,
35
+ 'thickbox_url' => $thickbox_url,
36
+ );
37
+ }
38
+
39
+ /**
40
+ * Echoes the admin notice, attach to admin_notices
41
+ */
42
+ public function show_inactive_plugins_alert() {
43
+ if ( ! current_user_can( 'activate_plugins' ) ) {
44
+ return;
45
+ }
46
+
47
+ $plugin_data = get_plugin_data( $this->plugin_path );
48
+
49
+ $req_plugins = array();
50
+
51
+ foreach ( $this->plugins_required as $req_plugin ) {
52
+
53
+ $item = esc_html( $req_plugin['name'] );
54
+
55
+ if ( ! empty( $req_plugin['thickbox_url'] ) ) {
56
+ $item = sprintf(
57
+ '<a href="%1$s" class="thickbox" title="%2$s">%3$s</a>',
58
+ esc_attr( $req_plugin['thickbox_url'] ),
59
+ esc_attr( $req_plugin['name'] ),
60
+ $item
61
+ );
62
+ }
63
+
64
+ $req_plugins[] = $item;
65
+ }
66
+
67
+ printf(
68
+ '<div class="error"><p>' . esc_html__( 'To begin using %1$s, please install and activate the latest version(s) of %2$s.', 'tribe-common' ) . '</p></div>',
69
+ $plugin_data['Name'],
70
+ implode( ', ', $req_plugins )
71
+ );
72
+
73
+ }
74
+
75
+
76
+ }
77
+
78
+ }
common/src/Tribe/Plugins.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Don't load directly
3
+ defined( 'WPINC' ) or die;
4
+
5
+ if ( ! class_exists( 'Tribe__Plugins' ) ) {
6
+ /**
7
+ * A list of Tribe's major plugins. Useful when encouraging users to download one of these.
8
+ */
9
+ class Tribe__Plugins {
10
+
11
+ /**
12
+ * A list of tribe plugin's details in this format:
13
+ *
14
+ * array(
15
+ * 'short_name' => Common name for the plugin, used in places such as WP Admin messages
16
+ * 'class' => Main plugin class
17
+ * 'thickbox_url' => Download or purchase URL for plugin from within /wp-admin/ thickbox
18
+ * )
19
+ */
20
+ private $tribe_plugins = array(
21
+ array(
22
+ 'short_name' => 'Event Tickets',
23
+ 'class' => 'Tribe__Tickets__Main',
24
+ 'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=event-tickets&TB_iframe=true',
25
+ ),
26
+ array(
27
+ 'short_name' => 'Event Tickets Plus',
28
+ 'class' => 'Tribe__Tickets_Plus__Main',
29
+ 'thickbox_url' => '//theeventscalendar.com/product/wordpress-event-tickets-plus/?TB_iframe=true',
30
+ ),
31
+ array(
32
+ 'short_name' => 'The Events Calendar',
33
+ 'class' => 'Tribe__Events__Main',
34
+ 'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=the-events-calendar&TB_iframe=true',
35
+ ),
36
+ array(
37
+ 'short_name' => 'Events Calendar Pro',
38
+ 'class' => 'Tribe__Events__Pro__Main',
39
+ 'thickbox_url' => '//theeventscalendar.com/product/wordpress-events-calendar-pro/?TB_iframe=true',
40
+ ),
41
+ array(
42
+ 'short_name' => 'Community Events',
43
+ 'class' => 'Tribe__Events__Community__Main',
44
+ 'thickbox_url' => '//theeventscalendar.com/product/wordpress-community-events/?TB_iframe=true',
45
+ ),
46
+ array(
47
+ 'short_name' => 'Community Tickets',
48
+ 'class' => 'Tribe__Events__Community__Tickets__Main',
49
+ 'thickbox_url' => '//theeventscalendar.com/product/community-tickets/?TB_iframe=true',
50
+ ),
51
+ array(
52
+ 'short_name' => 'Filter Bar',
53
+ 'class' => 'Tribe__Events__Filterbar__View',
54
+ 'thickbox_url' => '//theeventscalendar.com/product/wordpress-events-filterbar/?TB_iframe=true',
55
+ ),
56
+ array(
57
+ 'short_name' => 'Facebook Events',
58
+ 'class' => 'Tribe__Events__Facebook__Importer',
59
+ 'thickbox_url' => '//theeventscalendar.com/product/facebook-events/?TB_iframe=true',
60
+ ),
61
+ array(
62
+ 'short_name' => 'iCal Importer',
63
+ 'class' => 'Tribe__Events__Ical_Importer__Main',
64
+ 'thickbox_url' => '//theeventscalendar.com/product/ical-importer/?TB_iframe=true',
65
+ ),
66
+ array(
67
+ 'short_name' => 'Eventbrite Tickets',
68
+ 'class' => 'Tribe__Events__Tickets__Eventbrite__Main',
69
+ 'thickbox_url' => '//theeventscalendar.com/product/wordpress-eventbrite-tickets/?TB_iframe=true',
70
+ ),
71
+ array(
72
+ 'short_name' => 'Advanced Post Manager',
73
+ 'class' => 'Tribe_APM',
74
+ 'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=advanced-post-manager&TB_iframe=true',
75
+ ),
76
+ );
77
+
78
+ /**
79
+ * Searches the plugin list for key/value pair and return the full details for that plugin
80
+ *
81
+ * @param string $search_key The array key this value will appear in
82
+ * @param string $search_val The value itself
83
+ *
84
+ * @return array|null
85
+ */
86
+ public function get_plugin_by_key( $search_key, $search_val ) {
87
+ foreach ( $this->tribe_plugins as $plugin ) {
88
+ if ( isset( $plugin[ $search_key ] ) && $plugin[ $search_key ] === $search_val ) {
89
+ return $plugin;
90
+ }
91
+ }
92
+
93
+ return null;
94
+ }
95
+
96
+ /**
97
+ * Retrieves plugins details by plugin name
98
+ *
99
+ * @param string $name Common name for the plugin, not necessarily the lengthy name in the WP Admin Plugins list
100
+ *
101
+ * @return array|null
102
+ */
103
+ public function get_plugin_by_name( $name ) {
104
+ return $this->get_plugin_by_key( 'short_name', $name );
105
+ }
106
+
107
+ /**
108
+ * Retrieves plugins details by class name
109
+ *
110
+ * @param string $main_class Main/base class for this plugin
111
+ *
112
+ * @return array|null
113
+ */
114
+ public function get_plugin_by_class( $main_class ) {
115
+ return $this->get_plugin_by_key( 'class', $main_class );
116
+ }
117
+
118
+ /**
119
+ * Retrieves the entire list
120
+ *
121
+ * @return array
122
+ */
123
+ public function get_list() {
124
+ return $this->tribe_plugins;
125
+ }
126
+
127
+ }
128
+ }
common/src/Tribe/Post_Transient.php CHANGED
@@ -1,210 +1,210 @@
1
- <?php
2
-
3
- /**
4
- * A Class to handle Transients for posts, useful for caching complex structures
5
- * It uses the same logic as WordPress Transient, but instead of options it will
6
- * use the Post Meta as the table
7
- *
8
- * @since 4.1
9
- */
10
- class Tribe__Post_Transient {
11
-
12
- /**
13
- * Get (and instantiate, if necessary) the instance of the class
14
- *
15
- * @since 4.1
16
- * @static
17
- * @return self
18
- *
19
- */
20
- public static function instance() {
21
- static $instance;
22
-
23
- if ( ! $instance instanceof self ) {
24
- $instance = new self;
25
- }
26
-
27
- return $instance;
28
- }
29
-
30
- /**
31
- * Delete a post meta transient.
32
- *
33
- * @since 4.1
34
- *
35
- * @param int $post_id The Post ID, can also be a WP_Post
36
- * @param string $transient Post Meta to Delete
37
- * @param string $value Only delete if the value Matches
38
- *
39
- */
40
- public function delete( $post_id, $transient, $value = null ) {
41
- global $_wp_using_ext_object_cache;
42
-
43
- if ( is_numeric( $post_id ) ) {
44
- $post_id = (int) $post_id;
45
- } else {
46
- $post = get_post( $post_id );
47
- $post_id = $post->ID;
48
- }
49
-
50
- /**
51
- * Use this to pre attach an action to deleting a Post Transient
52
- *
53
- * @since 4.1
54
- *
55
- * @param int $post_id Post ID
56
- * @param string $transient The Post Meta Key
57
- */
58
- do_action( 'tribe_delete_post_meta_transient_' . $transient, $post_id, $transient );
59
-
60
- if ( $_wp_using_ext_object_cache ) {
61
- $result = wp_cache_delete( "tribe_{$transient}-{$post_id}", "tribe_post_meta_transient-{$post_id}" );
62
- } else {
63
- $meta_timeout = '_transient_timeout_' . $transient;
64
- $meta = '_transient_' . $transient;
65
- $result = delete_post_meta( $post_id, $meta, $value );
66
- if ( $result ) {
67
- delete_post_meta( $post_id, $meta_timeout, $value );
68
- }
69
- }
70
-
71
- if ( $result ) {
72
- /**
73
- * Use this to attach an Action to when the Transient is deleted
74
- *
75
- * @since 4.1
76
- *
77
- * @param int $post_id Post ID
78
- * @param string $transient The Post Meta Key
79
- */
80
- do_action( 'tribe_deleted_post_meta_transient', $transient, $post_id, $transient );
81
- }
82
-
83
- return $result;
84
- }
85
-
86
- /**
87
- * Fetches the Transient Data
88
- *
89
- * @since 4.1
90
- *
91
- * @param int $post_id The Post ID, can also be a WP_Post
92
- * @param string $transient Post Meta to Fetch
93
- *
94
- */
95
- public function get( $post_id, $transient ) {
96
- global $_wp_using_ext_object_cache;
97
-
98
- if ( is_numeric( $post_id ) ) {
99
- $post_id = (int) $post_id;
100
- } else {
101
- $post = get_post( $post_id );
102
- $post_id = $post->ID;
103
- }
104
-
105
- if ( has_filter( 'tribe_pre_post_meta_transient_' . $transient ) ) {
106
- /**
107
- * Attach an action before getting the new Transient
108
- *
109
- * @since 4.1
110
- *
111
- * @param int $post_id Post ID
112
- * @param string $transient The Post Meta Key
113
- */
114
- $pre = apply_filters( 'tribe_pre_post_meta_transient_' . $transient, $post_id, $transient );
115
- if ( false !== $pre ) {
116
- return $pre;
117
- }
118
- }
119
-
120
- if ( $_wp_using_ext_object_cache ) {
121
- $value = wp_cache_get( "tribe_{$transient}-{$post_id}", "tribe_post_meta_transient-{$post_id}" );
122
- } else {
123
- $meta_timeout = '_transient_timeout_' . $transient;
124
- $meta = '_transient_' . $transient;
125
- $value = get_post_meta( $post_id, $meta, true );
126
- if ( $value && ! defined( 'WP_INSTALLING' ) ) {
127
- if ( get_post_meta( $post_id, $meta_timeout, true ) < time() ) {
128
- $this->delete( $post_id, $transient );
129
- return false;
130
- }
131
- }
132
- }
133
-
134
- /**
135
- * Attach an action after getting the new Transient
136
- *
137
- * @since 4.1
138
- *
139
- * @param int $post_id Post ID
140
- * @param string $transient The Post Meta Key
141
- */
142
- return
143
- has_filter( 'tribe_post_meta_transient_' . $transient )
144
- ? apply_filters( 'tribe_post_meta_transient_' . $transient, $value, $post_id )
145
- : $value;
146
- }
147
-
148
- /**
149
- * Sets a new value for the Transient
150
- *
151
- * @since 4.1
152
- *
153
- * @param int $post_id The Post ID, can also be a WP_Post
154
- * @param string $transient Post Meta to set
155
- * @param string $value Only delete if the value Matches
156
- * @param int $expiration How long this transient will be valid, in seconds
157
- *
158
- */
159
- public function set( $post_id, $transient, $value, $expiration = 0 ) {
160
- global $_wp_using_ext_object_cache;
161
-
162
- if ( is_numeric( $post_id ) ) {
163
- $post_id = (int) $post_id;
164
- } else {
165
- $post = get_post( $post_id );
166
- $post_id = $post->ID;
167
- }
168
-
169
- $this->delete( $post_id, $transient );
170
-
171
- /**
172
- * Attach an action before setting the new Transient
173
- *
174
- * @since 4.1
175
- *
176
- * @param int $post_id Post ID
177
- * @param string $transient The Post Meta Key
178
- */
179
- if ( has_filter( 'tribe_pre_set_post_meta_transient_' . $transient ) ) {
180
- $value = apply_filters( 'tribe_pre_set_post_meta_transient_' . $transient, $value, $post_id, $transient );
181
- }
182
-
183
- if ( $_wp_using_ext_object_cache ) {
184
- $result = wp_cache_set( "tribe_{$transient}-{$post_id}", $value, "tribe_post_meta_transient-{$post_id}", $expiration );
185
- } else {
186
- $meta_timeout = '_transient_timeout_' . $transient;
187
- $meta = '_transient_' . $transient;
188
- if ( $expiration ) {
189
- add_post_meta( $post_id, $meta_timeout, time() + $expiration, true );
190
- }
191
- $result = add_post_meta( $post_id, $meta, $value, true );
192
- }
193
-
194
- if ( $result ) {
195
- /**
196
- * Attach an action after setting the new Transient
197
- *
198
- * @since 4.1
199
- *
200
- * @param int $post_id Post ID
201
- * @param string $transient The Post Meta Key
202
- */
203
- do_action( 'tribe_set_post_meta_transient_' . $transient, $post_id, $transient );
204
- }
205
-
206
- return $result;
207
- }
208
-
209
-
210
  }
1
+ <?php
2
+
3
+ /**
4
+ * A Class to handle Transients for posts, useful for caching complex structures
5
+ * It uses the same logic as WordPress Transient, but instead of options it will
6
+ * use the Post Meta as the table
7
+ *
8
+ * @since 4.1
9
+ */
10
+ class Tribe__Post_Transient {
11
+
12
+ /**
13
+ * Get (and instantiate, if necessary) the instance of the class
14
+ *
15
+ * @since 4.1
16
+ * @static
17
+ * @return self
18
+ *
19
+ */
20
+ public static function instance() {
21
+ static $instance;
22
+
23
+ if ( ! $instance instanceof self ) {
24
+ $instance = new self;
25
+ }
26
+
27
+ return $instance;
28
+ }
29
+
30
+ /**
31
+ * Delete a post meta transient.
32
+ *
33
+ * @since 4.1
34
+ *
35
+ * @param int $post_id The Post ID, can also be a WP_Post
36
+ * @param string $transient Post Meta to Delete
37
+ * @param string $value Only delete if the value Matches
38
+ *
39
+ */
40
+ public function delete( $post_id, $transient, $value = null ) {
41
+ global $_wp_using_ext_object_cache;
42
+
43
+ if ( is_numeric( $post_id ) ) {
44
+ $post_id = (int) $post_id;
45
+ } else {
46
+ $post = get_post( $post_id );
47
+ $post_id = $post->ID;
48
+ }
49
+
50
+ /**
51
+ * Use this to pre attach an action to deleting a Post Transient
52
+ *
53
+ * @since 4.1
54
+ *
55
+ * @param int $post_id Post ID
56
+ * @param string $transient The Post Meta Key
57
+ */
58
+ do_action( 'tribe_delete_post_meta_transient_' . $transient, $post_id, $transient );
59
+
60
+ if ( $_wp_using_ext_object_cache ) {
61
+ $result = wp_cache_delete( "tribe_{$transient}-{$post_id}", "tribe_post_meta_transient-{$post_id}" );
62
+ } else {
63
+ $meta_timeout = '_transient_timeout_' . $transient;
64
+ $meta = '_transient_' . $transient;
65
+ $result = delete_post_meta( $post_id, $meta, $value );
66
+ if ( $result ) {
67
+ delete_post_meta( $post_id, $meta_timeout, $value );
68
+ }
69
+ }
70
+
71
+ if ( $result ) {
72
+ /**
73
+ * Use this to attach an Action to when the Transient is deleted
74
+ *
75
+ * @since 4.1
76
+ *
77
+ * @param int $post_id Post ID
78
+ * @param string $transient The Post Meta Key
79
+ */
80
+ do_action( 'tribe_deleted_post_meta_transient', $transient, $post_id, $transient );
81
+ }
82
+
83
+ return $result;
84
+ }
85
+
86
+ /**
87
+ * Fetches the Transient Data
88
+ *
89
+ * @since 4.1
90
+ *
91
+ * @param int $post_id The Post ID, can also be a WP_Post
92
+ * @param string $transient Post Meta to Fetch
93
+ *
94
+ */
95
+ public function get( $post_id, $transient ) {
96
+ global $_wp_using_ext_object_cache;
97
+
98
+ if ( is_numeric( $post_id ) ) {
99
+ $post_id = (int) $post_id;
100
+ } else {
101
+ $post = get_post( $post_id );
102
+ $post_id = $post->ID;
103
+ }
104
+
105
+ if ( has_filter( 'tribe_pre_post_meta_transient_' . $transient ) ) {
106
+ /**
107
+ * Attach an action before getting the new Transient
108
+ *
109
+ * @since 4.1
110
+ *
111
+ * @param int $post_id Post ID
112
+ * @param string $transient The Post Meta Key
113
+ */
114
+ $pre = apply_filters( 'tribe_pre_post_meta_transient_' . $transient, $post_id, $transient );
115
+ if ( false !== $pre ) {
116
+ return $pre;
117
+ }
118
+ }
119
+
120
+ if ( $_wp_using_ext_object_cache ) {
121
+ $value = wp_cache_get( "tribe_{$transient}-{$post_id}", "tribe_post_meta_transient-{$post_id}" );
122
+ } else {
123
+ $meta_timeout = '_transient_timeout_' . $transient;
124
+ $meta = '_transient_' . $transient;
125
+ $value = get_post_meta( $post_id, $meta, true );
126
+ if ( $value && ! defined( 'WP_INSTALLING' ) ) {
127
+ if ( get_post_meta( $post_id, $meta_timeout, true ) < time() ) {
128
+ $this->delete( $post_id, $transient );
129
+ return false;
130
+ }
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Attach an action after getting the new Transient
136
+ *
137
+ * @since 4.1
138
+ *
139
+ * @param int $post_id Post ID
140
+ * @param string $transient The Post Meta Key
141
+ */
142
+ return
143
+ has_filter( 'tribe_post_meta_transient_' . $transient )
144
+ ? apply_filters( 'tribe_post_meta_transient_' . $transient, $value, $post_id )
145
+ : $value;
146
+ }
147
+
148
+ /**
149
+ * Sets a new value for the Transient
150
+ *
151
+ * @since 4.1
152
+ *
153
+ * @param int $post_id The Post ID, can also be a WP_Post
154
+ * @param string $transient Post Meta to set
155
+ * @param string $value Only delete if the value Matches
156
+ * @param int $expiration How long this transient will be valid, in seconds
157
+ *
158
+ */
159
+ public function set( $post_id, $transient, $value, $expiration = 0 ) {
160
+ global $_wp_using_ext_object_cache;
161
+
162
+ if ( is_numeric( $post_id ) ) {
163
+ $post_id = (int) $post_id;
164
+ } else {
165
+ $post = get_post( $post_id );
166
+ $post_id = $post->ID;
167
+ }
168
+
169
+ $this->delete( $post_id, $transient );
170
+
171
+ /**
172
+ * Attach an action before setting the new Transient
173
+ *
174
+ * @since 4.1
175
+ *
176
+ * @param int $post_id Post ID
177
+ * @param string $transient The Post Meta Key
178
+ */
179
+ if ( has_filter( 'tribe_pre_set_post_meta_transient_' . $transient ) ) {
180
+ $value = apply_filters( 'tribe_pre_set_post_meta_transient_' . $transient, $value, $post_id, $transient );
181
+ }
182
+
183
+ if ( $_wp_using_ext_object_cache ) {
184
+ $result = wp_cache_set( "tribe_{$transient}-{$post_id}", $value, "tribe_post_meta_transient-{$post_id}", $expiration );
185
+ } else {
186
+ $meta_timeout = '_transient_timeout_' . $transient;
187
+ $meta = '_transient_' . $transient;
188
+ if ( $expiration ) {
189
+ add_post_meta( $post_id, $meta_timeout, time() + $expiration, true );
190
+ }
191
+ $result = add_post_meta( $post_id, $meta, $value, true );
192
+ }
193
+
194
+ if ( $result ) {
195
+ /**
196
+ * Attach an action after setting the new Transient
197
+ *
198
+ * @since 4.1
199
+ *
200
+ * @param int $post_id Post ID
201
+ * @param string $transient The Post Meta Key
202
+ */
203
+ do_action( 'tribe_set_post_meta_transient_' . $transient, $post_id, $transient );
204
+ }
205
+
206
+ return $result;
207
+ }
208
+
209
+
210
  }
common/src/Tribe/Settings.php CHANGED
@@ -1,641 +1,641 @@
1
- <?php
2
-
3
- // Don't load directly
4
- if ( ! defined( 'ABSPATH' ) ) {
5
- die( '-1' );
6
- }
7
-
8
- if ( ! class_exists( 'Tribe__Settings' ) ) {
9
- /**
10
- * helper class that allows registration of settings
11
- * this is a static class & uses the singleton design method
12
- * instantiation takes place in Tribe__Main
13
- *
14
- */
15
- class Tribe__Settings {
16
-
17
- /**
18
- * Slug of the parent menu slug
19
- * @var string
20
- */
21
- public static $parent_slug = 'tribe-common';
22
-
23
- /**
24
- * Page of the parent menu
25
- * @var string
26
- */
27
- public static $parent_page = 'edit.php';
28
-
29
- /**
30
- * @var Tribe__Admin__Live_Date_Preview
31
- */
32
- public $live_date_preview;
33
-
34
- /**
35
- * the tabs that will appear in the settings page
36
- * filtered on class construct
37
- * @var array
38
- */
39
- public $tabs;
40
-
41
- /**
42
- * All the tabs registered, not just the ones that will appear
43
- * @var array
44
- */
45
- public $allTabs;
46
-
47
- /**
48
- * multidimentional array of the fields that will be generated
49
- * for the entire settings panel, tabs are represented in the array keys
50
- * @var array
51
- */
52
- public $fields;
53
-
54
- /**
55
- * the default tab for the settings panel
56
- * this should be a tab ID
57
- * @var string
58
- */
59
- public $defaultTab;
60
-
61
- /**
62
- * the current tab being displayed
63
- * @var string
64
- */
65
- public $currentTab;
66
-
67
- /**
68
- * tabs that shouldn't show the save button
69
- * @var array
70
- */
71
- public $noSaveTabs;
72
-
73
- /**
74
- * the slug used in the admin to generate the settings page
75
- * @var string
76
- */
77
- public $adminSlug;
78
-
79
- /**
80
- * the menu name used for the settings page
81
- * @var string
82
- */
83
- public $menuName;
84
-
85
- /**
86
- * the required capability for the settings page
87
- * @var string
88
- */
89
- public $requiredCap;
90
-
91
- /**
92
- * errors that occur after a save operation
93
- * @var mixed
94
- */
95
- public $errors;
96
-
97
- /**
98
- * POST data before/after save
99
- * @var mixed
100
- */
101
- public $sent_data;
102
-
103
- /**
104
- * the $current_screen name corresponding to the admin page
105
- * @var string
106
- */
107
- public $admin_page;
108
-
109
- /**
110
- * true if a major error that prevents saving occurred
111
- * @var bool
112
- */
113
- public $major_error;
114
-
115
- /**
116
- * holds validated fields
117
- * @var array
118
- */
119
- public $validated;
120
-
121
- /**
122
- * Static Singleton Holder
123
- * @var Tribe__Settings|null
124
- */
125
- private static $instance;
126
-
127
- /**
128
- * Static Singleton Factory Method
129
- *
130
- * @return Tribe__Settings
131
- */
132
- public static function instance() {
133
- if ( empty( self::$instance ) ) {
134
- self::$instance = new self();
135
- }
136
-
137
- return self::$instance;
138
- }
139
-
140
- /**
141
- * Class constructor
142
- *
143
- * @return void
144
- */
145
- public function __construct() {
146
-
147
- // set instance variables
148
- $this->menuName = apply_filters( 'tribe_settings_menu_name', esc_html__( 'Events', 'tribe-common' ) );
149
- $this->requiredCap = apply_filters( 'tribe_settings_req_cap', 'manage_options' );
150
- $this->adminSlug = apply_filters( 'tribe_settings_admin_slug', 'tribe-common' );
151
- $this->errors = get_option( 'tribe_settings_errors', array() );
152
- $this->major_error = get_option( 'tribe_settings_major_error', false );
153
- $this->sent_data = get_option( 'tribe_settings_sent_data', array() );
154
- $this->validated = array();
155
- $this->defaultTab = null;
156
- $this->currentTab = null;
157
-
158
- // run actions & filters
159
- add_action( 'admin_menu', array( $this, 'addPage' ) );
160
- add_action( 'network_admin_menu', array( $this, 'addNetworkPage' ) );
161
- add_action( 'admin_init', array( $this, 'initTabs' ) );
162
- add_action( 'tribe_settings_below_tabs', array( $this, 'displayErrors' ) );
163
- add_action( 'tribe_settings_below_tabs', array( $this, 'displaySuccess' ) );
164
- }
165
-
166
- /**
167
- * Determines whether or not the full admin pages should be initialized.
168
- *
169
- * When running in parallel with TEC 3.12.4, TEC should be relied on to handle the admin screens
170
- * that version of TEC (and lower) is tribe-common ignorant. Therefore, tribe-common has to be
171
- * the smarter, more lenient codebase.
172
- *
173
- * @return boolean
174
- */
175
- public function should_setup_pages() {
176
- if ( ! class_exists( 'Tribe__Events__Main' ) ) {
177
- return true;
178
- }
179
-
180
- if ( version_compare( Tribe__Events__Main::VERSION, '4.0beta', '>=' ) ) {
181
- return true;
182
- }
183
-
184
- return false;
185
- }
186
-
187
- /**
188
- * create the main option page
189
- *
190
- * @return void
191
- */
192
- public function addPage() {
193
- if ( ! $this->should_setup_pages() ) {
194
- return;
195
- }
196
-
197
- if ( ! is_multisite() || ( is_multisite() && '0' == Tribe__Settings_Manager::get_network_option( 'allSettingsTabsHidden', '0' ) ) ) {
198
- if ( post_type_exists( 'tribe_events' ) ) {
199
- self::$parent_page = 'edit.php?post_type=tribe_events';
200
- } else {
201
- self::$parent_page = 'admin.php?page=tribe-common';
202
-
203
- add_menu_page(
204
- esc_html__( 'Events', 'tribe-common' ),
205
- esc_html__( 'Events', 'tribe-common' ),
206
- apply_filters( 'tribe_common_event_page_capability', 'manage_options' ),
207
- self::$parent_slug,
208
- null,
209
- 'dashicons-calendar',
210
- 6
211
- );
212
- }
213
-
214
- $this->admin_page = add_submenu_page(
215
- $this->get_parent_slug(),
216
- esc_html__( 'Events Settings', 'tribe-common' ),
217
- esc_html__( 'Settings', 'tribe-common' ),
218
- $this->requiredCap,
219
- self::$parent_slug,
220
- array( $this, 'generatePage' )
221
- );
222
- }
223
- }
224
-
225
- /**
226
- * create the network options page
227
- *
228
- * @return void
229
- */
230
- public function addNetworkPage() {
231
- if ( ! $this->should_setup_pages() ) {
232
- return;
233
- }
234
-
235
- $this->admin_page = add_submenu_page(
236
- 'settings.php', esc_html__( 'Events Settings', 'tribe-common' ), esc_html__( 'Events Settings', 'tribe-common' ), $this->requiredCap, $this->adminSlug, array(
237
- $this,
238
- 'generatePage',
239
- )
240
- );
241
- }
242
-
243
- /**
244
- * init all the tabs
245
- *
246
- * @return void
247
- */
248
- public function initTabs() {
249
- if ( isset( $_GET['page'] ) && $_GET['page'] == $this->adminSlug ) {
250
- // Load settings tab-specific helpers and enhancements
251
- $this->live_date_preview = new Tribe__Admin__Live_Date_Preview;
252
-
253
- do_action( 'tribe_settings_do_tabs' ); // this is the hook to use to add new tabs
254
- $this->tabs = (array) apply_filters( 'tribe_settings_tabs', array() );
255
- $this->allTabs = (array) apply_filters( 'tribe_settings_all_tabs', array() );
256
- $this->noSaveTabs = (array) apply_filters( 'tribe_settings_no_save_tabs', array() );
257
- if ( is_network_admin() ) {
258
- $this->defaultTab = apply_filters( 'tribe_settings_default_tab_network', 'network' );
259
- $this->currentTab = apply_filters( 'tribe_settings_current_tab', ( isset( $_GET['tab'] ) && $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : $this->defaultTab );
260
- $this->url = apply_filters(
261
- 'tribe_settings_url', add_query_arg(
262
- array(
263
- 'page' => $this->adminSlug,
264
- 'tab' => $this->currentTab,
265
- ), network_admin_url( 'settings.php' )
266
- )
267
- );
268
- }
269
- if ( ! is_network_admin() ) {
270
- $tabs_keys = array_keys( $this->tabs );
271
- $this->defaultTab = in_array( apply_filters( 'tribe_settings_default_tab', 'general' ), $tabs_keys ) ? apply_filters( 'tribe_settings_default_tab', 'general' ) : $tabs_keys[0];
272
- $this->currentTab = apply_filters( 'tribe_settings_current_tab', ( isset( $_GET['tab'] ) && $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : $this->defaultTab );
273
- $this->url = apply_filters(
274
- 'tribe_settings_url', add_query_arg(
275
- array(
276
- 'page' => $this->adminSlug,
277
- 'tab' => $this->currentTab,
278
- ),
279
- admin_url( self::$parent_page )
280
- )
281
- );
282
- }
283
- $this->fields_for_save = (array) apply_filters( 'tribe_settings_fields', array() );
284
- do_action( 'tribe_settings_after_do_tabs' );
285
- $this->fields = (array) apply_filters( 'tribe_settings_fields', array() );
286
- $this->validate();
287
- }
288
- }
289
-
290
- /**
291
- * generate the main option page
292
- * includes the view file
293
- *
294
- * @return void
295
- */
296
- public function generatePage() {
297
- do_action( 'tribe_settings_top' );
298
- echo '<div class="tribe_settings wrap">';
299
- screen_icon();
300
- echo '<h1>';
301
- printf( esc_html__( '%s Settings', 'tribe-common' ), $this->menuName );
302
- echo '</h1>';
303
- do_action( 'tribe_settings_above_tabs' );
304
- $this->generateTabs( $this->currentTab );
305
- do_action( 'tribe_settings_below_tabs' );
306
- do_action( 'tribe_settings_below_tabs_tab_' . $this->currentTab );
307
- echo '<div class="tribe-settings-form form">';
308
- do_action( 'tribe_settings_above_form_element' );
309
- do_action( 'tribe_settings_above_form_element_tab_' . $this->currentTab );
310
- echo apply_filters( 'tribe_settings_form_element_tab_' . $this->currentTab, '<form method="post">' );
311
- do_action( 'tribe_settings_before_content' );
312
- do_action( 'tribe_settings_before_content_tab_' . $this->currentTab );
313
- do_action( 'tribe_settings_content_tab_' . $this->currentTab );
314
- if ( ! has_action( 'tribe_settings_content_tab_' . $this->currentTab ) ) {
315
- echo '<p>' . esc_html__( "You've requested a non-existent tab.", 'tribe-common' ) . '</p>';
316
- }
317
- do_action( 'tribe_settings_after_content_tab_' . $this->currentTab );
318
- do_action( 'tribe_settings_after_content' );
319
- if ( has_action( 'tribe_settings_content_tab_' . $this->currentTab ) && ! in_array( $this->currentTab, $this->noSaveTabs ) ) {
320
- wp_nonce_field( 'saving', 'tribe-save-settings' );
321
- echo '<div class="clear"></div>';
322
- echo '<input type="hidden" name="current-settings-tab" id="current-settings-tab" value="' . esc_attr( $this->currentTab ) . '" />';
323
- echo '<input id="tribeSaveSettings" class="button-primary" type="submit" name="tribeSaveSettings" value="' . esc_attr__( 'Save Changes', 'tribe-common' ) . '" />';
324
- }
325
- echo apply_filters( 'tribe_settings_closing_form_element', '</form>' );
326
- do_action( 'tribe_settings_after_form_element' );
327
- do_action( 'tribe_settings_after_form_element_tab_' . $this->currentTab );
328
- echo '</div>';
329
- do_action( 'tribe_settings_after_form_div' );
330
- echo '</div>';
331
- do_action( 'tribe_settings_bottom' );
332
- }
333
-
334
- /**
335
- * generate the tabs in the settings screen
336
- *
337
- * @return void
338
- */
339
- public function generateTabs() {
340
- if ( is_array( $this->tabs ) && ! empty( $this->tabs ) ) {
341
- echo '<h2 id="tribe-settings-tabs" class="nav-tab-wrapper">';
342
- foreach ( $this->tabs as $tab => $name ) {
343
- if ( ! is_network_admin() ) {
344
- $url = '?page=' . $this->adminSlug . '&tab=' . urlencode( $tab );
345
- $url = apply_filters( 'tribe_settings_url', $url );
346
- }
347
- if ( is_network_admin() ) {
348
- $url = '?page=' . $this->adminSlug . '&tab=' . urlencode( $tab );
349
- }
350
- $class = ( $tab == $this->currentTab ) ? ' nav-tab-active' : '';
351
- echo '<a id="' . esc_attr( $tab ) . '" class="nav-tab' . esc_attr( $class ) . '" href="' . esc_url( $url ) . '">' . esc_html( $name ) . '</a>';
352
- }
353
- do_action( 'tribe_settings_after_tabs' );
354
- echo '</h2>';
355
- }
356
- }
357
-
358
- /**
359
- * validate the settings
360
- *
361
- * @return void
362
- */
363
- public function validate() {
364
-
365
- do_action( 'tribe_settings_validate_before_checks' );
366
-
367
- // check that the right POST && variables are set
368
- if ( isset( $_POST['tribeSaveSettings'] ) && isset( $_POST['current-settings-tab'] ) ) {
369
- // check permissions
370
- if ( ! current_user_can( 'manage_options' ) ) {
371
- $this->errors[] = esc_html__( "You don't have permission to do that.", 'tribe-common' );
372
- $this->major_error = true;
373
- }
374
-
375
- // check the nonce
376
- if ( ! wp_verify_nonce( $_POST['tribe-save-settings'], 'saving' ) ) {
377
- $this->errors[] = esc_html__( 'The request was sent insecurely.', 'tribe-common' );
378
- $this->major_error = true;
379
- }
380
-
381
- // check that the request originated from the current tab
382
- if ( $_POST['current-settings-tab'] != $this->currentTab ) {
383
- $this->errors[] = esc_html__( "The request wasn't sent from this tab.", 'tribe-common' );
384
- $this->major_error = true;
385
- }
386
-
387
- // bail if we have errors
388
- if ( count( $this->errors ) ) {
389
- remove_action( 'shutdown', array( $this, 'deleteOptions' ) );
390
- add_option( 'tribe_settings_errors', $this->errors );
391
- add_option( 'tribe_settings_major_error', $this->major_error );
392
- wp_redirect( $this->url );
393
- exit;
394
- }
395
-
396
- // some hooks
397
- do_action( 'tribe_settings_validate' );
398
- do_action( 'tribe_settings_validate_tab_' . $this->currentTab );
399
-
400
- // set the current tab and current fields
401
- $tab = $this->currentTab;
402
- $fields = $this->fields_for_save[ $tab ];
403
-
404
- if ( is_array( $fields ) ) {
405
- // loop through the fields and validate them
406
- foreach ( $fields as $field_id => $field ) {
407
- // get the value
408
- $value = ( isset( $_POST[ $field_id ] ) ) ? $_POST[ $field_id ] : null;
409
- $value = apply_filters( 'tribe_settings_validate_field_value', $value, $field_id, $field );
410
-
411
- // make sure it has validation set up for it, else do nothing
412
- if ( ( ! isset( $field['conditional'] ) || $field['conditional'] ) && ( ! empty( $field['validation_type'] ) || ! empty( $field['validation_callback'] ) ) ) {
413
- // some hooks
414
- do_action( 'tribe_settings_validate_field', $field_id, $value, $field );
415
- do_action( 'tribe_settings_validate_field_' . $field_id, $value, $field );
416
-
417
- // validate this sucka
418
- $validate = new Tribe__Validate( $field_id, $field, $value );
419
-
420
- if ( isset( $validate->result->error ) ) {
421
- // uh oh; validation failed
422
- $this->errors[ $field_id ] = $validate->result->error;
423
- } elseif ( $validate->result->valid ) {
424
- // validation passed
425
- $this->validated[ $field_id ] = new stdClass;
426
- $this->validated[ $field_id ]->field = $validate->field;
427
- $this->validated[ $field_id ]->value = $validate->value;
428
- }
429
- }
430
- }
431
-
432
- // run the saving method
433
- $this->save();
434
- }
435
- }
436
-
437
- }
438
-
439
- /**
440
- * save the settings
441
- *
442
- * @return void
443
- */
444
- public function save() {
445
-
446
- // some hooks
447
- do_action( 'tribe_settings_save' );
448
- do_action( 'tribe_settings_save_tab_' . $this->currentTab );
449
-
450
- // we'll need this later
451
- $parent_options = array();
452
-
453
- /**
454
- * loop through each validated option and either
455
- * save it as is or figure out its parent option ID
456
- * (in that case, it's a serialized option array and
457
- * will be saved in the next loop)
458
- */
459
- if ( ! empty( $this->validated ) ) {
460
- foreach ( $this->validated as $field_id => $validated_field ) {
461
- // get the value and filter it
462
- $value = $validated_field->value;
463
- $value = apply_filters( 'tribe_settings_save_field_value', $value, $field_id, $validated_field );
464
-
465
- // figure out the parent option [could be set to false] and filter it
466
- if ( is_network_admin() ) {
467
- $parent_option = ( isset( $validated_field->field['parent_option'] ) ) ? $validated_field->field['parent_option'] : Tribe__Main::OPTIONNAMENETWORK;
468
- }
469
- if ( ! is_network_admin() ) {
470
- $parent_option = ( isset( $validated_field->field['parent_option'] ) ) ? $validated_field->field['parent_option'] : Tribe__Main::OPTIONNAME;
471
- }
472
-
473
- $parent_option = apply_filters( 'tribe_settings_save_field_parent_option', $parent_option, $field_id );
474
- $network_option = isset( $validated_field->field['network_option'] ) ? (bool) $validated_field->field['network_option'] : false;
475
-
476
- // some hooks
477
- do_action( 'tribe_settings_save_field', $field_id, $value, $validated_field );
478
- do_action( 'tribe_settings_save_field_' . $field_id, $value, $validated_field );
479
-
480
- if ( ! $parent_option ) {
481
- if ( $network_option || is_network_admin() ) {
482
- update_site_option( $field_id, $value );
483
- } else {
484
- update_option( $field_id, $value );
485
- }
486
- } else {
487
- // set the parent option
488
- $parent_options[ $parent_option ][ $field_id ] = $value;
489
- }
490
- }
491
- }
492
-
493
- /**
494
- * loop through parent option arrays
495
- * and save them
496
- * NOTE: in the case of the main option Tribe Options,
497
- * this will save using the Tribe__Settings_Manager::set_options method.
498
- */
499
- foreach ( $parent_options as $option_id => $new_options ) {
500
- // get the old options
501
- if ( $option_id == Tribe__Main::OPTIONNAME ) {
502
- $old_options = (array) get_option( $option_id );
503
- } else {
504
- $old_options = (array) get_site_option( $option_id );
505
- }
506
-
507
- // set the options by parsing old + new and filter that
508
- $options = apply_filters( 'tribe_settings_save_option_array', wp_parse_args( $new_options, $old_options ), $option_id );
509
-
510
- if ( $option_id == Tribe__Main::OPTIONNAME ) {
511
- // save using the Tribe__Settings_Manager method
512
- Tribe__Settings_Manager::set_options( $options );
513
- } elseif ( $option_id == Tribe__Main::OPTIONNAMENETWORK ) {
514
- Tribe__Settings_Manager::set_network_options( $options );
515
- } else {
516
- // save using regular WP method
517
- if ( is_network_admin() ) {
518
- update_site_option( $option_id, $options );
519
- } else {
520
- update_option( $option_id, $options );
521
- }
522
- }
523
- }
524
-
525
- do_action( 'tribe_settings_after_save' );
526
- do_action( 'tribe_settings_after_save_' . $this->currentTab );
527
- remove_action( 'shutdown', array( $this, 'deleteOptions' ) );
528
- add_option( 'tribe_settings_sent_data', $_POST );
529
- add_option( 'tribe_settings_errors', $this->errors );
530
- add_option( 'tribe_settings_major_error', $this->major_error );
531
- wp_redirect( esc_url_raw( add_query_arg( array( 'saved' => true ), $this->url ) ) );
532
- exit;
533
- }
534
-
535
- /**
536
- * display errors, if any, after saving
537
- *
538
- * @return void
539
- */
540
- public function displayErrors() {
541
-
542
- // fetch the errors and filter them
543
- $errors = (array) apply_filters( 'tribe_settings_display_errors', $this->errors );
544
- $count = apply_filters( 'tribe_settings_count_errors', count( $errors ) );
545
-
546
- if ( apply_filters( 'tribe_settings_display_errors_or_not', ( $count > 0 ) ) ) {
547
- // output a message if we have errors
548
-
549
- $output = '<div id="message" class="error"><p><strong>';
550
- $output .= esc_html__( 'Your form had the following errors:', 'tribe-common' );
551
- $output .= '</strong></p><ul class="tribe-errors-list">';
552
-
553
- // loop through each error
554
- foreach ( $errors as $error ) {
555
- $output .= '<li>' . (string) $error . '</li>';
556
- }
557
-
558
- if ( count( $errors ) ) {
559
- $message = ( isset( $this->major_error ) && $this->major_error )
560
- ? esc_html__( 'None of your settings were saved. Please try again.' )
561
- : esc_html( _n( 'The above setting was not saved. Other settings were successfully saved.', 'The above settings were not saved. Other settings were successfully saved.', $count, 'tribe-common' ) );
562
- }
563
-
564
- $output .= '</ul><p>' . $message . '</p></div>';
565
-
566
- // final output, filtered of course
567
- echo apply_filters( 'tribe_settings_error_message', $output );
568
- }
569
- }
570
-
571
- /**
572
- * display success message after saving
573
- *
574
- * @return void
575
- */
576
- public function displaySuccess() {
577
- $errors = (array) apply_filters( 'tribe_settings_display_errors', $this->errors );
578
- $count = apply_filters( 'tribe_settings_count_errors', count( $errors ) );
579
-
580
- // are we coming from the saving place?
581
- if ( isset( $_GET['saved'] ) && ! apply_filters( 'tribe_settings_display_errors_or_not', ( $count > 0 ) ) ) {
582
- // output the filtered message
583
- $message = esc_html__( 'Settings saved.', 'tribe-common' );
584
- $output = '<div id="message" class="updated"><p><strong>' . $message . '</strong></p></div>';
585
- echo apply_filters( 'tribe_settings_success_message', $output, $this->currentTab );
586
- }
587
-
588
- //Delete Temporary Options After Display Errors and Success
589
- $this->deleteOptions();
590
- }
591
-
592
- /**
593
- * delete temporary options
594
- *
595
- * @return void
596
- */
597
- public function deleteOptions() {
598
- delete_option( 'tribe_settings_errors' );
599
- delete_option( 'tribe_settings_major_error' );
600
- delete_option( 'tribe_settings_sent_data' );
601
- }
602
-
603
- /**
604
- * Returns the main admin settings URL.
605
- *
606
- * @return string
607
- */
608
- public function get_url( array $args = array() ) {
609
- $defaults = array(
610
- 'page' => $this->adminSlug,
611
- 'parent' => self::$parent_page,
612
- );
613
-
614
- // Allow the link to be "changed" on the fly
615
- $args = wp_parse_args( $args, $defaults );
616
-
617
- $url = admin_url( $args['parent'] );
618
-
619
- // keep the resulting URL args clean
620
- unset( $args['parent'] );
621
-
622
- return apply_filters( 'tribe_settings_url', add_query_arg( $args, $url ), $args, $url );
623
- }
624
-
625
- /**
626
- * The "slug" used for adding submenu pages
627
- *
628
- * @return string
629
- */
630
- public function get_parent_slug() {
631
- $slug = self::$parent_page;
632
-
633
- // if we don't have an event post type, then we can just use the tribe-common slug
634
- if ( 'edit.php' === $slug || 'admin.php?page=tribe-common' === $slug ) {
635
- $slug = self::$parent_slug;
636
- }
637
-
638
- return $slug;
639
- }
640
- } // end class
641
- } // endif class_exists
1
+ <?php
2
+
3
+ // Don't load directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ die( '-1' );
6
+ }
7
+
8
+ if ( ! class_exists( 'Tribe__Settings' ) ) {
9
+ /**
10
+ * helper class that allows registration of settings
11
+ * this is a static class & uses the singleton design method
12
+ * instantiation takes place in Tribe__Main
13
+ *
14
+ */
15
+ class Tribe__Settings {
16
+
17
+ /**
18
+ * Slug of the parent menu slug
19
+ * @var string
20
+ */
21
+ public static $parent_slug = 'tribe-common';
22
+
23
+ /**
24
+ * Page of the parent menu
25
+ * @var string
26
+ */
27
+ public static $parent_page = 'edit.php';
28
+
29
+ /**
30
+ * @var Tribe__Admin__Live_Date_Preview
31
+ */
32
+ public $live_date_preview;
33
+
34
+ /**
35
+ * the tabs that will appear in the settings page
36
+ * filtered on class construct
37
+ * @var array
38
+ */
39
+ public $tabs;
40
+
41
+ /**
42
+ * All the tabs registered, not just the ones that will appear
43
+ * @var array
44
+ */
45
+ public $allTabs;
46
+
47
+ /**
48
+ * multidimentional array of the fields that will be generated
49
+ * for the entire settings panel, tabs are represented in the array keys
50
+ * @var array
51
+ */
52
+ public $fields;
53
+
54
+ /**
55
+ * the default tab for the settings panel
56
+ * this should be a tab ID
57
+ * @var string
58
+ */
59
+ public $defaultTab;
60
+
61
+ /**
62
+ * the current tab being displayed
63
+ * @var string
64
+ */
65
+ public $currentTab;
66
+
67
+ /**
68
+ * tabs that shouldn't show the save button
69
+ * @var array
70
+ */
71
+ public $noSaveTabs;
72
+
73
+ /**
74
+ * the slug used in the admin to generate the settings page
75
+ * @var string
76
+ */
77
+ public $adminSlug;
78
+
79
+ /**
80
+ * the menu name used for the settings page
81
+ * @var string
82
+ */
83
+ public $menuName;
84
+
85
+ /**
86
+ * the required capability for the settings page
87
+ * @var string
88
+ */
89
+ public $requiredCap;
90
+
91
+ /**
92
+ * errors that occur after a save operation
93
+ * @var mixed
94
+ */
95
+ public $errors;
96
+
97
+ /**
98
+ * POST data before/after save
99
+ * @var mixed
100
+ */
101
+ public $sent_data;
102
+
103
+ /**
104
+ * the $current_screen name corresponding to the admin page
105
+ * @var string
106
+ */
107
+ public $admin_page;
108
+
109
+ /**
110
+ * true if a major error that prevents saving occurred
111
+ * @var bool
112
+ */
113
+ public $major_error;
114
+
115
+ /**
116
+ * holds validated fields
117
+ * @var array
118
+ */
119
+ public $validated;
120
+
121
+ /**
122
+ * Static Singleton Holder
123
+ * @var Tribe__Settings|null
124
+ */
125
+ private static $instance;
126
+
127
+ /**
128
+ * Static Singleton Factory Method
129
+ *
130
+ * @return Tribe__Settings
131
+ */
132
+ public static function instance() {
133
+ if ( empty( self::$instance ) ) {
134
+ self::$instance = new self();
135
+ }
136
+
137
+ return self::$instance;
138
+ }
139
+
140
+ /**
141
+ * Class constructor
142
+ *
143
+ * @return void
144
+ */
145
+ public function __construct() {
146
+
147
+ // set instance variables
148
+ $this->menuName = apply_filters( 'tribe_settings_menu_name', esc_html__( 'Events', 'tribe-common' ) );
149
+ $this->requiredCap = apply_filters( 'tribe_settings_req_cap', 'manage_options' );
150
+ $this->adminSlug = apply_filters( 'tribe_settings_admin_slug', 'tribe-common' );
151
+ $this->errors = get_option( 'tribe_settings_errors', array() );
152
+ $this->major_error = get_option( 'tribe_settings_major_error', false );
153
+ $this->sent_data = get_option( 'tribe_settings_sent_data', array() );
154
+ $this->validated = array();
155
+ $this->defaultTab = null;
156
+ $this->currentTab = null;
157
+
158
+ // run actions & filters
159
+ add_action( 'admin_menu', array( $this, 'addPage' ) );
160
+ add_action( 'network_admin_menu', array( $this, 'addNetworkPage' ) );
161
+ add_action( 'admin_init', array( $this, 'initTabs' ) );
162
+ add_action( 'tribe_settings_below_tabs', array( $this, 'displayErrors' ) );
163
+ add_action( 'tribe_settings_below_tabs', array( $this, 'displaySuccess' ) );
164
+ }
165
+
166
+ /**
167
+ * Determines whether or not the full admin pages should be initialized.
168
+ *
169
+ * When running in parallel with TEC 3.12.4, TEC should be relied on to handle the admin screens
170
+ * that version of TEC (and lower) is tribe-common ignorant. Therefore, tribe-common has to be
171
+ * the smarter, more lenient codebase.
172
+ *
173
+ * @return boolean
174
+ */
175
+ public function should_setup_pages() {
176
+ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
177
+ return true;
178
+ }
179
+
180
+ if ( version_compare( Tribe__Events__Main::VERSION, '4.0beta', '>=' ) ) {
181
+ return true;
182
+ }
183
+
184
+ return false;
185
+ }
186
+
187
+ /**
188
+ * create the main option page
189
+ *
190
+ * @return void
191
+ */
192
+ public function addPage() {
193
+ if ( ! $this->should_setup_pages() ) {
194
+ return;
195
+ }
196
+
197
+ if ( ! is_multisite() || ( is_multisite() && '0' == Tribe__Settings_Manager::get_network_option( 'allSettingsTabsHidden', '0' ) ) ) {
198
+ if ( post_type_exists( 'tribe_events' ) ) {
199
+ self::$parent_page = 'edit.php?post_type=tribe_events';
200
+ } else {
201
+ self::$parent_page = 'admin.php?page=tribe-common';
202
+
203
+ add_menu_page(
204
+ esc_html__( 'Events', 'tribe-common' ),
205
+ esc_html__( 'Events', 'tribe-common' ),
206
+ apply_filters( 'tribe_common_event_page_capability', 'manage_options' ),
207
+ self::$parent_slug,
208
+ null,
209
+ 'dashicons-calendar',
210
+ 6
211
+ );
212
+ }
213
+
214
+ $this->admin_page = add_submenu_page(
215
+ $this->get_parent_slug(),
216
+ esc_html__( 'Events Settings', 'tribe-common' ),
217
+ esc_html__( 'Settings', 'tribe-common' ),
218
+ $this->requiredCap,
219
+ self::$parent_slug,
220
+ array( $this, 'generatePage' )
221
+ );
222
+ }
223
+ }
224
+
225
+ /**
226
+ * create the network options page
227
+ *
228
+ * @return void
229
+ */
230
+ public function addNetworkPage() {
231
+ if ( ! $this->should_setup_pages() ) {
232
+ return;
233
+ }
234
+
235
+ $this->admin_page = add_submenu_page(
236
+ 'settings.php', esc_html__( 'Events Settings', 'tribe-common' ), esc_html__( 'Events Settings', 'tribe-common' ), $this->requiredCap, $this->adminSlug, array(
237
+ $this,
238
+ 'generatePage',
239
+ )
240
+ );
241
+ }
242
+
243
+ /**
244
+ * init all the tabs
245
+ *
246
+ * @return void
247
+ */
248
+ public function initTabs() {
249
+ if ( isset( $_GET['page'] ) && $_GET['page'] == $this->adminSlug ) {
250
+ // Load settings tab-specific helpers and enhancements
251
+ $this->live_date_preview = new Tribe__Admin__Live_Date_Preview;
252
+
253
+ do_action( 'tribe_settings_do_tabs' ); // this is the hook to use to add new tabs
254
+ $this->tabs = (array) apply_filters( 'tribe_settings_tabs', array() );
255
+ $this->allTabs = (array) apply_filters( 'tribe_settings_all_tabs', array() );
256
+ $this->noSaveTabs = (array) apply_filters( 'tribe_settings_no_save_tabs', array() );
257
+ if ( is_network_admin() ) {
258
+ $this->defaultTab = apply_filters( 'tribe_settings_default_tab_network', 'network' );
259
+ $this->currentTab = apply_filters( 'tribe_settings_current_tab', ( isset( $_GET['tab'] ) && $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : $this->defaultTab );
260
+ $this->url = apply_filters(
261
+ 'tribe_settings_url', add_query_arg(
262
+ array(
263
+ 'page' => $this->adminSlug,
264
+ 'tab' => $this->currentTab,
265
+ ), network_admin_url( 'settings.php' )
266
+ )
267
+ );
268
+ }
269
+ if ( ! is_network_admin() ) {
270
+ $tabs_keys = array_keys( $this->tabs );
271
+ $this->defaultTab = in_array( apply_filters( 'tribe_settings_default_tab', 'general' ), $tabs_keys ) ? apply_filters( 'tribe_settings_default_tab', 'general' ) : $tabs_keys[0];
272
+ $this->currentTab = apply_filters( 'tribe_settings_current_tab', ( isset( $_GET['tab'] ) && $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : $this->defaultTab );
273
+ $this->url = apply_filters(
274
+ 'tribe_settings_url', add_query_arg(
275
+ array(
276
+ 'page' => $this->adminSlug,
277
+ 'tab' => $this->currentTab,
278
+ ),
279
+ admin_url( self::$parent_page )
280
+ )
281
+ );
282
+ }
283
+ $this->fields_for_save = (array) apply_filters( 'tribe_settings_fields', array() );
284
+ do_action( 'tribe_settings_after_do_tabs' );
285
+ $this->fields = (array) apply_filters( 'tribe_settings_fields', array() );
286
+ $this->validate();
287
+ }
288
+ }
289
+
290
+ /**
291
+ * generate the main option page
292
+ * includes the view file
293
+ *
294
+ * @return void
295
+ */
296
+ public function generatePage() {
297
+ do_action( 'tribe_settings_top' );
298
+ echo '<div class="tribe_settings wrap">';
299
+ screen_icon();
300
+ echo '<h1>';
301
+ printf( esc_html__( '%s Settings', 'tribe-common' ), $this->menuName );
302
+ echo '</h1>';
303
+ do_action( 'tribe_settings_above_tabs' );
304
+ $this->generateTabs( $this->currentTab );
305
+ do_action( 'tribe_settings_below_tabs' );
306
+ do_action( 'tribe_settings_below_tabs_tab_' . $this->currentTab );
307
+ echo '<div class="tribe-settings-form form">';
308
+ do_action( 'tribe_settings_above_form_element' );
309
+ do_action( 'tribe_settings_above_form_element_tab_' . $this->currentTab );
310
+ echo apply_filters( 'tribe_settings_form_element_tab_' . $this->currentTab, '<form method="post">' );
311
+ do_action( 'tribe_settings_before_content' );
312
+ do_action( 'tribe_settings_before_content_tab_' . $this->currentTab );
313
+ do_action( 'tribe_settings_content_tab_' . $this->currentTab );
314
+ if ( ! has_action( 'tribe_settings_content_tab_' . $this->currentTab ) ) {
315
+ echo '<p>' . esc_html__( "You've requested a non-existent tab.", 'tribe-common' ) . '</p>';
316
+ }
317
+ do_action( 'tribe_settings_after_content_tab_' . $this->currentTab );
318
+ do_action( 'tribe_settings_after_content' );
319
+ if ( has_action( 'tribe_settings_content_tab_' . $this->currentTab ) && ! in_array( $this->currentTab, $this->noSaveTabs ) ) {
320
+ wp_nonce_field( 'saving', 'tribe-save-settings' );
321
+ echo '<div class="clear"></div>';
322
+ echo '<input type="hidden" name="current-settings-tab" id="current-settings-tab" value="' . esc_attr( $this->currentTab ) . '" />';
323
+ echo '<input id="tribeSaveSettings" class="button-primary" type="submit" name="tribeSaveSettings" value="' . esc_attr__( 'Save Changes', 'tribe-common' ) . '" />';
324
+ }
325
+ echo apply_filters( 'tribe_settings_closing_form_element', '</form>' );
326
+ do_action( 'tribe_settings_after_form_element' );
327
+ do_action( 'tribe_settings_after_form_element_tab_' . $this->currentTab );
328
+ echo '</div>';
329
+ do_action( 'tribe_settings_after_form_div' );
330
+ echo '</div>';
331
+ do_action( 'tribe_settings_bottom' );
332
+ }
333
+
334
+ /**
335
+ * generate the tabs in the settings screen
336
+ *
337
+ * @return void
338
+ */
339
+ public function generateTabs() {
340
+ if ( is_array( $this->tabs ) && ! empty( $this->tabs ) ) {
341
+ echo '<h2 id="tribe-settings-tabs" class="nav-tab-wrapper">';
342
+ foreach ( $this->tabs as $tab => $name ) {
343
+ if ( ! is_network_admin() ) {
344
+ $url = '?page=' . $this->adminSlug . '&tab=' . urlencode( $tab );
345
+ $url = apply_filters( 'tribe_settings_url', $url );
346
+ }
347
+ if ( is_network_admin() ) {
348
+ $url = '?page=' . $this->adminSlug . '&tab=' . urlencode( $tab );
349
+ }
350
+ $class = ( $tab == $this->currentTab ) ? ' nav-tab-active' : '';
351
+ echo '<a id="' . esc_attr( $tab ) . '" class="nav-tab' . esc_attr( $class ) . '" href="' . esc_url( $url ) . '">' . esc_html( $name ) . '</a>';
352
+ }
353
+ do_action( 'tribe_settings_after_tabs' );
354
+ echo '</h2>';
355
+ }
356
+ }
357
+
358
+ /**
359
+ * validate the settings
360
+ *
361
+ * @return void
362
+ */
363
+ public function validate() {
364
+
365
+ do_action( 'tribe_settings_validate_before_checks' );
366
+
367
+ // check that the right POST && variables are set
368
+ if ( isset( $_POST['tribeSaveSettings'] ) && isset( $_POST['current-settings-tab'] ) ) {
369
+ // check permissions
370
+ if ( ! current_user_can( 'manage_options' ) ) {
371
+ $this->errors[] = esc_html__( "You don't have permission to do that.", 'tribe-common' );
372
+ $this->major_error = true;
373
+ }
374
+
375
+ // check the nonce
376
+ if ( ! wp_verify_nonce( $_POST['tribe-save-settings'], 'saving' ) ) {
377
+ $this->errors[] = esc_html__( 'The request was sent insecurely.', 'tribe-common' );
378
+ $this->major_error = true;
379
+ }
380
+
381
+ // check that the request originated from the current tab
382
+ if ( $_POST['current-settings-tab'] != $this->currentTab ) {
383
+ $this->errors[] = esc_html__( "The request wasn't sent from this tab.", 'tribe-common' );
384
+ $this->major_error = true;
385
+ }
386
+
387
+ // bail if we have errors
388
+ if ( count( $this->errors ) ) {
389
+ remove_action( 'shutdown', array( $this, 'deleteOptions' ) );
390
+ add_option( 'tribe_settings_errors', $this->errors );
391
+ add_option( 'tribe_settings_major_error', $this->major_error );
392
+ wp_redirect( $this->url );
393
+ exit;
394
+ }
395
+
396
+ // some hooks
397
+ do_action( 'tribe_settings_validate' );
398
+ do_action( 'tribe_settings_validate_tab_' . $this->currentTab );
399
+
400
+ // set the current tab and current fields
401
+ $tab = $this->currentTab;
402
+ $fields = $this->fields_for_save[ $tab ];
403
+
404
+ if ( is_array( $fields ) ) {
405
+ // loop through the fields and validate them
406
+ foreach ( $fields as $field_id => $field ) {
407
+ // get the value
408
+ $value = ( isset( $_POST[ $field_id ] ) ) ? $_POST[ $field_id ] : null;
409
+ $value = apply_filters( 'tribe_settings_validate_field_value', $value, $field_id, $field );
410
+
411
+ // make sure it has validation set up for it, else do nothing
412
+ if ( ( ! isset( $field['conditional'] ) || $field['conditional'] ) && ( ! empty( $field['validation_type'] ) || ! empty( $field['validation_callback'] ) ) ) {
413
+ // some hooks
414
+ do_action( 'tribe_settings_validate_field', $field_id, $value, $field );
415
+ do_action( 'tribe_settings_validate_field_' . $field_id, $value, $field );
416
+
417
+ // validate this sucka
418
+ $validate = new Tribe__Validate( $field_id, $field, $value );
419
+
420
+ if ( isset( $validate->result->error ) ) {
421
+ // uh oh; validation failed
422
+ $this->errors[ $field_id ] = $validate->result->error;
423
+ } elseif ( $validate->result->valid ) {
424
+ // validation passed
425
+ $this->validated[ $field_id ] = new stdClass;
426
+ $this->validated[ $field_id ]->field = $validate->field;
427
+ $this->validated[ $field_id ]->value = $validate->value;
428
+ }
429
+ }
430
+ }
431
+
432
+ // run the saving method
433
+ $this->save();
434
+ }
435
+ }
436
+
437
+ }
438
+
439
+ /**
440
+ * save the settings
441
+ *
442
+ * @return void
443
+ */
444
+ public function save() {
445
+
446
+ // some hooks
447
+ do_action( 'tribe_settings_save' );
448
+ do_action( 'tribe_settings_save_tab_' . $this->currentTab );
449
+
450
+ // we'll need this later
451
+ $parent_options = array();
452
+
453
+ /**
454
+ * loop through each validated option and either
455
+ * save it as is or figure out its parent option ID
456
+ * (in that case, it's a serialized option array and
457
+ * will be saved in the next loop)
458
+ */
459
+ if ( ! empty( $this->validated ) ) {
460
+ foreach ( $this->validated as $field_id => $validated_field ) {
461
+ // get the value and filter it
462
+ $value = $validated_field->value;
463
+ $value = apply_filters( 'tribe_settings_save_field_value', $value, $field_id, $validated_field );
464
+
465
+ // figure out the parent option [could be set to false] and filter it
466
+ if ( is_network_admin() ) {
467
+ $parent_option = ( isset( $validated_field->field['parent_option'] ) ) ? $validated_field->field['parent_option'] : Tribe__Main::OPTIONNAMENETWORK;
468
+ }
469
+ if ( ! is_network_admin() ) {
470
+ $parent_option = ( isset( $validated_field->field['parent_option'] ) ) ? $validated_field->field['parent_option'] : Tribe__Main::OPTIONNAME;
471
+ }
472
+
473
+ $parent_option = apply_filters( 'tribe_settings_save_field_parent_option', $parent_option, $field_id );
474
+ $network_option = isset( $validated_field->field['network_option'] ) ? (bool) $validated_field->field['network_option'] : false;
475
+
476
+ // some hooks
477
+ do_action( 'tribe_settings_save_field', $field_id, $value, $validated_field );
478
+ do_action( 'tribe_settings_save_field_' . $field_id, $value, $validated_field );
479
+
480
+ if ( ! $parent_option ) {
481
+ if ( $network_option || is_network_admin() ) {
482
+ update_site_option( $field_id, $value );
483
+ } else {
484
+ update_option( $field_id, $value );
485
+ }
486
+ } else {
487
+ // set the parent option
488
+ $parent_options[ $parent_option ][ $field_id ] = $value;
489
+ }
490
+ }
491
+ }
492
+
493
+ /**
494
+ * loop through parent option arrays
495
+ * and save them
496
+ * NOTE: in the case of the main option Tribe Options,
497
+ * this will save using the Tribe__Settings_Manager::set_options method.
498
+ */
499
+ foreach ( $parent_options as $option_id => $new_options ) {
500
+ // get the old options
501
+ if ( $option_id == Tribe__Main::OPTIONNAME ) {
502
+ $old_options = (array) get_option( $option_id );
503
+ } else {
504
+ $old_options = (array) get_site_option( $option_id );
505
+ }
506
+
507
+ // set the options by parsing old + new and filter that
508
+ $options = apply_filters( 'tribe_settings_save_option_array', wp_parse_args( $new_options, $old_options ), $option_id );
509
+
510
+ if ( $option_id == Tribe__Main::OPTIONNAME ) {
511
+ // save using the Tribe__Settings_Manager method
512
+ Tribe__Settings_Manager::set_options( $options );
513
+ } elseif ( $option_id == Tribe__Main::OPTIONNAMENETWORK ) {
514
+ Tribe__Settings_Manager::set_network_options( $options );
515
+ } else {
516
+ // save using regular WP method
517
+ if ( is_network_admin() ) {
518
+ update_site_option( $option_id, $options );
519
+ } else {
520
+ update_option( $option_id, $options );
521
+ }
522
+ }
523
+ }
524
+
525
+ do_action( 'tribe_settings_after_save' );
526
+ do_action( 'tribe_settings_after_save_' . $this->currentTab );
527
+ remove_action( 'shutdown', array( $this, 'deleteOptions' ) );
528
+ add_option( 'tribe_settings_sent_data', $_POST );
529
+ add_option( 'tribe_settings_errors', $this->errors );
530
+ add_option( 'tribe_settings_major_error', $this->major_error );
531
+ wp_redirect( esc_url_raw( add_query_arg( array( 'saved' => true ), $this->url ) ) );
532
+ exit;
533
+ }
534
+
535
+ /**
536
+ * display errors, if any, after saving
537
+ *
538
+ * @return void
539
+ */
540
+ public function displayErrors() {
541
+
542
+ // fetch the errors and filter them
543
+ $errors = (array) apply_filters( 'tribe_settings_display_errors', $this->errors );
544
+ $count = apply_filters( 'tribe_settings_count_errors', count( $errors ) );
545
+
546
+ if ( apply_filters( 'tribe_settings_display_errors_or_not', ( $count > 0 ) ) ) {
547
+ // output a message if we have errors
548
+
549
+ $output = '<div id="message" class="error"><p><strong>';
550
+ $output .= esc_html__( 'Your form had the following errors:', 'tribe-common' );
551
+ $output .= '</strong></p><ul class="tribe-errors-list">';
552
+
553
+ // loop through each error
554
+ foreach ( $errors as $error ) {
555
+ $output .= '<li>' . (string) $error . '</li>';
556
+ }
557
+
558
+ if ( count( $errors ) ) {
559
+ $message = ( isset( $this->major_error ) && $this->major_error )
560
+ ? esc_html__( 'None of your settings were saved. Please try again.' )
561
+ : esc_html( _n( 'The above setting was not saved. Other settings were successfully saved.', 'The above settings were not saved. Other settings were successfully saved.', $count, 'tribe-common' ) );
562
+ }
563
+
564
+ $output .= '</ul><p>' . $message . '</p></div>';
565
+
566
+ // final output, filtered of course
567
+ echo apply_filters( 'tribe_settings_error_message', $output );
568
+ }
569
+ }
570
+
571
+ /**
572
+ * display success message after saving
573
+ *
574
+ * @return void
575
+ */
576
+ public function displaySuccess() {
577
+ $errors = (array) apply_filters( 'tribe_settings_display_errors', $this->errors );
578
+ $count = apply_filters( 'tribe_settings_count_errors', count( $errors ) );
579
+
580
+ // are we coming from the saving place?
581
+ if ( isset( $_GET['saved'] ) && ! apply_filters( 'tribe_settings_display_errors_or_not', ( $count > 0 ) ) ) {
582
+ // output the filtered message
583
+ $message = esc_html__( 'Settings saved.', 'tribe-common' );
584
+ $output = '<div id="message" class="updated"><p><strong>' . $message . '</strong></p></div>';
585
+ echo apply_filters( 'tribe_settings_success_message', $output, $this->currentTab );
586
+ }
587
+
588
+ //Delete Temporary Options After Display Errors and Success
589
+ $this->deleteOptions();
590
+ }
591
+
592
+ /**
593
+ * delete temporary options
594
+ *
595
+ * @return void
596
+ */
597
+ public function deleteOptions() {
598
+ delete_option( 'tribe_settings_errors' );
599
+ delete_option( 'tribe_settings_major_error' );
600
+ delete_option( 'tribe_settings_sent_data' );
601
+ }
602
+
603
+ /**
604
+ * Returns the main admin settings URL.
605
+ *
606
+ * @return string
607
+ */
608
+ public function get_url( array $args = array() ) {
609
+ $defaults = array(
610
+ 'page' => $this->adminSlug,
611
+ 'parent' => self::$parent_page,
612
+ );
613
+
614
+ // Allow the link to be "changed" on the fly
615
+ $args = wp_parse_args( $args, $defaults );
616
+
617
+ $url = admin_url( $args['parent'] );
618
+
619
+ // keep the resulting URL args clean
620
+ unset( $args['parent'] );
621
+
622
+ return apply_filters( 'tribe_settings_url', add_query_arg( $args, $url ), $args, $url );
623
+ }
624
+
625
+ /**
626
+ * The "slug" used for adding submenu pages
627
+ *
628
+ * @return string
629
+ */
630
+ public function get_parent_slug() {
631
+ $slug = self::$parent_page;
632
+
633
+ // if we don't have an event post type, then we can just use the tribe-common slug
634
+ if ( 'edit.php' === $slug || 'admin.php?page=tribe-common' === $slug ) {
635
+ $slug = self::$parent_slug;
636
+ }
637
+
638
+ return $slug;
639
+ }
640
+ } // end class
641
+ } // endif class_exists
common/src/Tribe/Settings_Manager.php CHANGED
@@ -1,349 +1,349 @@
1
- <?php
2
-
3
- class Tribe__Settings_Manager {
4
- protected static $network_options;
5
- public static $tribe_events_mu_defaults;
6
-
7
- /**
8
- * constructor
9
- */
10
- public function __construct() {
11
- $this->add_hooks();
12
-
13
- // Load multisite defaults
14
- if ( is_multisite() ) {
15
- $tribe_events_mu_defaults = array();
16
- if ( file_exists( WP_CONTENT_DIR . '/tribe-events-mu-defaults.php' ) ) {
17
- require_once WP_CONTENT_DIR . '/tribe-events-mu-defaults.php';
18
- }
19
- self::$tribe_events_mu_defaults = apply_filters( 'tribe_events_mu_defaults', $tribe_events_mu_defaults );
20
- }
21
- }
22
-
23
- public function add_hooks() {
24
- // option pages
25
- add_action( '_network_admin_menu', array( $this, 'init_options' ) );
26
- add_action( '_admin_menu', array( $this, 'init_options' ) );
27
-
28
- add_action( 'admin_menu', array( $this, 'add_help_admin_menu_item' ), 50 );
29
- add_action( 'tribe_settings_do_tabs', array( $this, 'do_setting_tabs' ) );
30
- add_action( 'tribe_settings_do_tabs', array( $this, 'do_network_settings_tab' ), 400 );
31
- add_action( 'tribe_settings_content_tab_help', array( $this, 'do_help_tab' ) );
32
- add_action( 'tribe_settings_validate_tab_network', array( $this, 'save_all_tabs_hidden' ) );
33
- }
34
-
35
- /**
36
- * Init the settings API and add a hook to add your own setting tabs
37
- *
38
- * @return void
39
- */
40
- public function init_options() {
41
- Tribe__Settings::instance();
42
- }
43
-
44
- /**
45
- * Create setting tabs
46
- *
47
- * @return void
48
- */
49
- public function do_setting_tabs() {
50
- include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-general.php';
51
- include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-display.php';
52
-
53
- $showNetworkTabs = $this->get_network_option( 'showSettingsTabs', false );
54
-
55
- new Tribe__Settings_Tab( 'general', esc_html__( 'General', 'tribe-common' ), $generalTab );
56
- new Tribe__Settings_Tab( 'display', esc_html__( 'Display', 'tribe-common' ), $displayTab );
57
-
58
- $this->do_licenses_tab();
59
-
60
- new Tribe__Settings_Tab(
61
- 'help',
62
- esc_html__( 'Help', 'tribe-common' ),
63
- array(
64
- 'priority' => 60,
65
- 'show_save' => false,
66
- )
67
- );
68
- }
69
-
70
- /**
71
- * Get all options for the Events Calendar
72
- *
73
- * @return array of options
74
- */
75
- public static function get_options() {
76
- $options = get_option( Tribe__Main::OPTIONNAME, array() );
77
- if ( has_filter( 'tribe_get_options' ) ) {
78
- _deprecated_function( 'tribe_get_options', '3.10', 'option_' . Tribe__Main::OPTIONNAME );
79
- $options = apply_filters( 'tribe_get_options', $options );
80
- }
81
- return $options;
82
- }
83
-
84
- /**
85
- * Get value for a specific option
86
- *
87
- * @param string $option_name name of option
88
- * @param string $default default value
89
- *
90
- * @return mixed results of option query
91
- */
92
- public static function get_option( $option_name, $default = '' ) {
93
- if ( ! $option_name ) {
94
- return null;
95
- }
96
- $options = self::get_options();
97
-
98
- $option = $default;
99
- if ( isset( $options[ $option_name ] ) ) {
100
- $option = $options[ $option_name ];
101
- } elseif ( is_multisite() && isset( self::$tribe_events_mu_defaults ) && is_array( self::$tribe_events_mu_defaults ) && in_array( $option_name, array_keys( self::$tribe_events_mu_defaults ) ) ) {
102
- $option = self::$tribe_events_mu_defaults[ $option_name ];
103
- }
104
-
105
- return apply_filters( 'tribe_get_single_option', $option, $default, $option_name );
106
- }
107
-
108
- /**
109
- * Saves the options for the plugin
110
- *
111
- * @param array $options formatted the same as from get_options()
112
- * @param bool $apply_filters
113
- *
114
- * @return void
115
- */
116
- public static function set_options( $options, $apply_filters = true ) {
117
- if ( ! is_array( $options ) ) {
118
- return;
119
- }
120
- if ( $apply_filters == true ) {
121
- $options = apply_filters( 'tribe-events-save-options', $options );
122
- }
123
- update_option( Tribe__Main::OPTIONNAME, $options );
124
- }
125
-
126
- /**
127
- * Set an option
128
- *
129
- * @param string $name
130
- * @param mixed $value
131
- *
132
- * @return void
133
- */
134
- public static function set_option( $name, $value ) {
135
- $newOption = array();
136
- $newOption[ $name ] = $value;
137
- $options = self::get_options();
138
- self::set_options( wp_parse_args( $newOption, $options ) );
139
- }
140
-
141
- /**
142
- * Get all network options for the Events Calendar
143
- *
144
- * @return array of options
145
- * @TODO add force option, implement in setNetworkOptions
146
- */
147
- public static function get_network_options() {
148
- if ( ! isset( self::$network_options ) ) {
149
- $options = get_site_option( Tribe__Main::OPTIONNAMENETWORK, array() );
150
- self::$network_options = apply_filters( 'tribe_get_network_options', $options );
151
- }
152
-
153
- return self::$network_options;
154
- }
155
-
156
- /**
157
- * Get value for a specific network option
158
- *
159
- * @param string $option_name name of option
160
- * @param string $default default value
161
- *
162
- * @return mixed results of option query
163
- */
164
- public static function get_network_option( $option_name, $default = '' ) {
165
- if ( ! $option_name ) {
166
- return null;
167
- }
168
-
169
- if ( ! isset( self::$network_options ) ) {
170
- self::get_network_options();
171
- }
172
-
173
- if ( isset( self::$network_options[ $option_name ] ) ) {
174
- $option = self::$network_options[ $option_name ];
175
- } else {
176
- $option = $default;
177
- }
178
-
179
- return apply_filters( 'tribe_get_single_network_option', $option, $default );
180
- }
181
-
182
- /**
183
- * Saves the network options for the plugin
184
- *
185
- * @param array $options formatted the same as from get_options()
186
- * @param bool $apply_filters
187
- *
188
- * @return void
189
- */
190
- public static function set_network_options( $options, $apply_filters = true ) {
191
- if ( ! is_array( $options ) ) {
192
- return;
193
- }
194
- if ( $apply_filters == true ) {
195
- $options = apply_filters( 'tribe-events-save-network-options', $options );
196
- }
197
-
198
- // @TODO use getNetworkOptions + force
199
- if ( update_site_option( Tribe__Main::OPTIONNAMENETWORK, $options ) ) {
200
- self::$network_options = apply_filters( 'tribe_get_network_options', $options );
201
- } else {
202
- self::$network_options = self::get_network_options();
203
- }
204
- }
205
-
206
- /**
207
- * Add the network admin options page
208
- *
209
- * @return void
210
- */
211
- public static function add_network_options_page() {
212
- $tribe_settings = Tribe__Settings::instance();
213
- add_submenu_page(
214
- 'settings.php', $tribe_settings->menuName, $tribe_settings->menuName, 'manage_network_options', 'tribe-common', array(
215
- $tribe_settings,
216
- 'generatePage',
217
- )
218
- );
219
- }
220
-
221
- /**
222
- * Render network admin options view
223
- *
224
- * @return void
225
- */
226
- public static function do_network_settings_tab() {
227
- include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-network.php';
228
-
229
- new Tribe__Settings_Tab( 'network', esc_html__( 'Network', 'tribe-common' ), $networkTab );
230
- }
231
-
232
- /**
233
- * Registers the license key management tab in the Events > Settings screen,
234
- * only if premium addons are detected.
235
- */
236
- protected function do_licenses_tab() {
237
- $show_tab = ( current_user_can( 'activate_plugins' ) && $this->have_addons() );
238
-
239
- /**
240
- * Provides an oppotunity to override the decision to show or hide the licenses tab
241
- *
242
- * Normally it will only show if the current user has the "activate_plugins" capability
243
- * and there are some currently-activated premium plugins.
244
- *
245
- * @var bool
246
- */
247
- if ( ! apply_filters( 'tribe_events_show_licenses_tab', $show_tab ) ) {
248
- return;
249
- }
250
-
251
- /**
252
- * @var $licenses_tab
253
- */
254
- include Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-licenses.php';
255
-
256
- /**
257
- * Allows the fields displayed in the licenses tab to be modified.
258
- *
259
- * @var array
260
- */
261
- $license_fields = apply_filters( 'tribe_license_fields', $licenses_tab );
262
-
263
- new Tribe__Settings_Tab( 'licenses', esc_html__( 'Licenses', 'tribe-common' ), array(
264
- 'priority' => '40',
265
- 'fields' => $license_fields,
266
- 'network_admin' => is_network_admin() ? true : false,
267
- ) );
268
- }
269
-
270
- /**
271
- * Create the help tab
272
- */
273
- public function do_help_tab() {
274
- include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-help.php';
275
- }
276
-
277
- /**
278
- * Add help menu item to the admin (unless blocked via network admin settings).
279
- *
280
- * @todo move to an admin class
281
- */
282
- public function add_help_admin_menu_item() {
283
- $hidden_settings_tabs = self::get_network_option( 'hideSettingsTabs', array() );
284
- if ( in_array( 'help', $hidden_settings_tabs ) ) {
285
- return;
286
- }
287
-
288
- $parent = Tribe__Settings::$parent_slug;
289
- $title = esc_html__( 'Help', 'tribe-common' );
290
- $slug = esc_url(
291
- apply_filters( 'tribe_settings_url',
292
- add_query_arg(
293
- array(
294
- 'page' => 'tribe-common',
295
- 'tab' => 'help',
296
- ),
297
- Tribe__Settings::$parent_page
298
- )
299
- )
300
- );
301
-
302
- add_submenu_page( $parent, $title, $title, 'manage_options', $slug, '' );
303
- }
304
-
305
- /**
306
- * Tries to discover if licensable addons are activated on the same site.
307
- *
308
- * @return bool
309
- */
310
- protected function have_addons() {
311
- $addons = apply_filters( 'tribe_licensable_addons', array() );
312
- return ! empty( $addons );
313
- }
314
-
315
- /**
316
- * Save hidden tabs
317
- *
318
- * @return void
319
- */
320
- public function save_all_tabs_hidden() {
321
- $all_tabs_keys = array_keys( apply_filters( 'tribe_settings_all_tabs', array() ) );
322
-
323
- $network_options = (array) get_site_option( Tribe__Main::OPTIONNAMENETWORK );
324
-
325
- if ( isset( $_POST['hideSettingsTabs'] ) && $_POST['hideSettingsTabs'] == $all_tabs_keys ) {
326
- $network_options['allSettingsTabsHidden'] = '1';
327
- } else {
328
- $network_options['allSettingsTabsHidden'] = '0';
329
- }
330
-
331
- $this->set_network_options( $network_options );
332
- }
333
-
334
- /**
335
- * Static Singleton Factory Method
336
- *
337
- * @return Tribe__Settings_Manager
338
- */
339
- public static function instance() {
340
- static $instance;
341
-
342
- if ( ! $instance ) {
343
- $class_name = __CLASS__;
344
- $instance = new $class_name;
345
- }
346
-
347
- return $instance;
348
- }
349
- }
1
+ <?php
2
+
3
+ class Tribe__Settings_Manager {
4
+ protected static $network_options;
5
+ public static $tribe_events_mu_defaults;
6
+
7
+ /**
8
+ * constructor
9
+ */
10
+ public function __construct() {
11
+ $this->add_hooks();
12
+
13
+ // Load multisite defaults
14
+ if ( is_multisite() ) {
15
+ $tribe_events_mu_defaults = array();
16
+ if ( file_exists( WP_CONTENT_DIR . '/tribe-events-mu-defaults.php' ) ) {
17
+ require_once WP_CONTENT_DIR . '/tribe-events-mu-defaults.php';
18
+ }
19
+ self::$tribe_events_mu_defaults = apply_filters( 'tribe_events_mu_defaults', $tribe_events_mu_defaults );
20
+ }
21
+ }
22
+
23
+ public function add_hooks() {
24
+ // option pages
25
+ add_action( '_network_admin_menu', array( $this, 'init_options' ) );
26
+ add_action( '_admin_menu', array( $this, 'init_options' ) );
27
+
28
+ add_action( 'admin_menu', array( $this, 'add_help_admin_menu_item' ), 50 );
29
+ add_action( 'tribe_settings_do_tabs', array( $this, 'do_setting_tabs' ) );
30
+ add_action( 'tribe_settings_do_tabs', array( $this, 'do_network_settings_tab' ), 400 );
31
+ add_action( 'tribe_settings_content_tab_help', array( $this, 'do_help_tab' ) );
32
+ add_action( 'tribe_settings_validate_tab_network', array( $this, 'save_all_tabs_hidden' ) );
33
+ }
34
+
35
+ /**
36
+ * Init the settings API and add a hook to add your own setting tabs
37
+ *
38
+ * @return void
39
+ */
40
+ public function init_options() {
41
+ Tribe__Settings::instance();
42
+ }
43
+
44
+ /**
45
+ * Create setting tabs
46
+ *
47
+ * @return void
48
+ */
49
+ public function do_setting_tabs() {
50
+ include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-general.php';
51
+ include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-display.php';
52
+
53
+ $showNetworkTabs = $this->get_network_option( 'showSettingsTabs', false );
54
+
55
+ new Tribe__Settings_Tab( 'general', esc_html__( 'General', 'tribe-common' ), $generalTab );
56
+ new Tribe__Settings_Tab( 'display', esc_html__( 'Display', 'tribe-common' ), $displayTab );
57
+
58
+ $this->do_licenses_tab();
59
+
60
+ new Tribe__Settings_Tab(
61
+ 'help',
62
+ esc_html__( 'Help', 'tribe-common' ),
63
+ array(
64
+ 'priority' => 60,
65
+ 'show_save' => false,
66
+ )
67
+ );
68
+ }
69
+
70
+ /**
71
+ * Get all options for the Events Calendar
72
+ *
73
+ * @return array of options
74
+ */
75
+ public static function get_options() {
76
+ $options = get_option( Tribe__Main::OPTIONNAME, array() );
77
+ if ( has_filter( 'tribe_get_options' ) ) {
78
+ _deprecated_function( 'tribe_get_options', '3.10', 'option_' . Tribe__Main::OPTIONNAME );
79
+ $options = apply_filters( 'tribe_get_options', $options );
80
+ }
81
+ return $options;
82
+ }
83
+
84
+ /**
85
+ * Get value for a specific option
86
+ *
87
+ * @param string $option_name name of option
88
+ * @param string $default default value
89
+ *
90
+ * @return mixed results of option query
91
+ */
92
+ public static function get_option( $option_name, $default = '' ) {
93
+ if ( ! $option_name ) {
94
+ return null;
95
+ }
96
+ $options = self::get_options();
97
+
98
+ $option = $default;
99
+ if ( isset( $options[ $option_name ] ) ) {
100
+ $option = $options[ $option_name ];
101
+ } elseif ( is_multisite() && isset( self::$tribe_events_mu_defaults ) && is_array( self::$tribe_events_mu_defaults ) && in_array( $option_name, array_keys( self::$tribe_events_mu_defaults ) ) ) {
102
+ $option = self::$tribe_events_mu_defaults[ $option_name ];
103
+ }
104
+
105
+ return apply_filters( 'tribe_get_single_option', $option, $default, $option_name );
106
+ }
107
+
108
+ /**
109
+ * Saves the options for the plugin
110
+ *
111
+ * @param array $options formatted the same as from get_options()
112
+ * @param bool $apply_filters
113
+ *
114
+ * @return void
115
+ */
116
+ public static function set_options( $options, $apply_filters = true ) {
117
+ if ( ! is_array( $options ) ) {
118
+ return;
119
+ }
120
+ if ( $apply_filters == true ) {
121
+ $options = apply_filters( 'tribe-events-save-options', $options );
122
+ }
123
+ update_option( Tribe__Main::OPTIONNAME, $options );
124
+ }
125
+
126
+ /**
127
+ * Set an option
128
+ *
129
+ * @param string $name
130
+ * @param mixed $value
131
+ *
132
+ * @return void
133
+ */
134
+ public static function set_option( $name, $value ) {
135
+ $newOption = array();
136
+ $newOption[ $name ] = $value;
137
+ $options = self::get_options();
138
+ self::set_options( wp_parse_args( $newOption, $options ) );
139
+ }
140
+
141
+ /**
142
+ * Get all network options for the Events Calendar
143
+ *
144
+ * @return array of options
145
+ * @TODO add force option, implement in setNetworkOptions
146
+ */
147
+ public static function get_network_options() {
148
+ if ( ! isset( self::$network_options ) ) {
149
+ $options = get_site_option( Tribe__Main::OPTIONNAMENETWORK, array() );
150
+ self::$network_options = apply_filters( 'tribe_get_network_options', $options );
151
+ }
152
+
153
+ return self::$network_options;
154
+ }
155
+
156
+ /**
157
+ * Get value for a specific network option
158
+ *
159
+ * @param string $option_name name of option
160
+ * @param string $default default value
161
+ *
162
+ * @return mixed results of option query
163
+ */
164
+ public static function get_network_option( $option_name, $default = '' ) {
165
+ if ( ! $option_name ) {
166
+ return null;
167
+ }
168
+
169
+ if ( ! isset( self::$network_options ) ) {
170
+ self::get_network_options();
171
+ }
172
+
173
+ if ( isset( self::$network_options[ $option_name ] ) ) {
174
+ $option = self::$network_options[ $option_name ];
175
+ } else {
176
+ $option = $default;
177
+ }
178
+
179
+ return apply_filters( 'tribe_get_single_network_option', $option, $default );
180
+ }
181
+
182
+ /**
183
+ * Saves the network options for the plugin
184
+ *
185
+ * @param array $options formatted the same as from get_options()
186
+ * @param bool $apply_filters
187
+ *
188
+ * @return void
189
+ */
190
+ public static function set_network_options( $options, $apply_filters = true ) {
191
+ if ( ! is_array( $options ) ) {
192
+ return;
193
+ }
194
+ if ( $apply_filters == true ) {
195
+ $options = apply_filters( 'tribe-events-save-network-options', $options );
196
+ }
197
+
198
+ // @TODO use getNetworkOptions + force
199
+ if ( update_site_option( Tribe__Main::OPTIONNAMENETWORK, $options ) ) {
200
+ self::$network_options = apply_filters( 'tribe_get_network_options', $options );
201
+ } else {
202
+ self::$network_options = self::get_network_options();
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Add the network admin options page
208
+ *
209
+ * @return void
210
+ */
211
+ public static function add_network_options_page() {
212
+ $tribe_settings = Tribe__Settings::instance();
213
+ add_submenu_page(
214
+ 'settings.php', $tribe_settings->menuName, $tribe_settings->menuName, 'manage_network_options', 'tribe-common', array(
215
+ $tribe_settings,
216
+ 'generatePage',
217
+ )
218
+ );
219
+ }
220
+
221
+ /**
222
+ * Render network admin options view
223
+ *
224
+ * @return void
225
+ */
226
+ public static function do_network_settings_tab() {
227
+ include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-network.php';
228
+
229
+ new Tribe__Settings_Tab( 'network', esc_html__( 'Network', 'tribe-common' ), $networkTab );
230
+ }
231
+
232
+ /**
233
+ * Registers the license key management tab in the Events > Settings screen,
234
+ * only if premium addons are detected.
235
+ */
236
+ protected function do_licenses_tab() {
237
+ $show_tab = ( current_user_can( 'activate_plugins' ) && $this->have_addons() );
238
+
239
+ /**
240
+ * Provides an oppotunity to override the decision to show or hide the licenses tab
241
+ *
242
+ * Normally it will only show if the current user has the "activate_plugins" capability
243
+ * and there are some currently-activated premium plugins.
244
+ *
245
+ * @var bool
246
+ */
247
+ if ( ! apply_filters( 'tribe_events_show_licenses_tab', $show_tab ) ) {
248
+ return;
249
+ }
250
+
251
+ /**
252
+ * @var $licenses_tab
253
+ */
254
+ include Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-licenses.php';
255
+
256
+ /**
257
+ * Allows the fields displayed in the licenses tab to be modified.
258
+ *
259
+ * @var array
260
+ */
261
+ $license_fields = apply_filters( 'tribe_license_fields', $licenses_tab );
262
+
263
+ new Tribe__Settings_Tab( 'licenses', esc_html__( 'Licenses', 'tribe-common' ), array(
264
+ 'priority' => '40',
265
+ 'fields' => $license_fields,
266
+ 'network_admin' => is_network_admin() ? true : false,
267
+ ) );
268
+ }
269
+
270
+ /**
271
+ * Create the help tab
272
+ */
273
+ public function do_help_tab() {
274
+ include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-help.php';
275
+ }
276
+
277
+ /**
278
+ * Add help menu item to the admin (unless blocked via network admin settings).
279
+ *
280
+ * @todo move to an admin class
281
+ */
282
+ public function add_help_admin_menu_item() {
283
+ $hidden_settings_tabs = self::get_network_option( 'hideSettingsTabs', array() );
284
+ if ( in_array( 'help', $hidden_settings_tabs ) ) {
285
+ return;
286
+ }
287
+
288
+ $parent = Tribe__Settings::$parent_slug;
289
+ $title = esc_html__( 'Help', 'tribe-common' );
290
+ $slug = esc_url(
291
+ apply_filters( 'tribe_settings_url',
292
+ add_query_arg(
293
+ array(
294
+ 'page' => 'tribe-common',
295
+ 'tab' => 'help',
296
+ ),
297
+ Tribe__Settings::$parent_page
298
+ )
299
+ )
300
+ );
301
+
302
+ add_submenu_page( $parent, $title, $title, 'manage_options', $slug, '' );
303
+ }
304
+
305
+ /**
306
+ * Tries to discover if licensable addons are activated on the same site.
307
+ *
308
+ * @return bool
309
+ */
310
+ protected function have_addons() {
311
+ $addons = apply_filters( 'tribe_licensable_addons', array() );
312
+ return ! empty( $addons );
313
+ }
314
+
315
+ /**
316
+ * Save hidden tabs
317
+ *
318
+ * @return void
319
+ */
320
+ public function save_all_tabs_hidden() {
321
+ $all_tabs_keys = array_keys( apply_filters( 'tribe_settings_all_tabs', array() ) );
322
+
323
+ $network_options = (array) get_site_option( Tribe__Main::OPTIONNAMENETWORK );
324
+
325
+ if ( isset( $_POST['hideSettingsTabs'] ) && $_POST['hideSettingsTabs'] == $all_tabs_keys ) {
326
+ $network_options['allSettingsTabsHidden'] = '1';
327
+ } else {
328
+ $network_options['allSettingsTabsHidden'] = '0';
329
+ }
330
+
331
+ $this->set_network_options( $network_options );
332
+ }
333
+
334
+ /**
335
+ * Static Singleton Factory Method
336
+ *
337
+ * @return Tribe__Settings_Manager
338
+ */
339
+ public static function instance() {
340
+ static $instance;
341
+
342
+ if ( ! $instance ) {
343
+ $class_name = __CLASS__;
344
+ $instance = new $class_name;
345
+ }
346
+
347
+ return $instance;
348
+ }
349
+ }
common/src/Tribe/Settings_Tab.php CHANGED
@@ -1,227 +1,227 @@
1
- <?php
2
-
3
- // Don't load directly
4
- if ( ! defined( 'ABSPATH' ) ) {
5
- die( '-1' );
6
- }
7
-
8
- if ( ! class_exists( 'Tribe__Settings_Tab' ) ) {
9
- /**
10
- * helper class that creates a settings tab
11
- * this is a public API, use it to create tabs
12
- * simply by instantiating this class
13
- *
14
- */
15
- class Tribe__Settings_Tab {
16
-
17
- /**
18
- * Tab ID, used in query string and elsewhere
19
- * @var string
20
- */
21
- public $id;
22
-
23
- /**
24
- * Tab's name
25
- * @var string
26
- */
27
- public $name;
28
-
29
- /**
30
- * Tab's arguments
31
- * @var array
32
- */
33
- public $args;
34
-
35
- /**
36
- * Defaults for tabs
37
- * @var array
38
- */
39
- public $defaults;
40
-
41
- /**
42
- * class constructor
43
- *
44
- * @param string $id the tab's id (no spaces or special characters)
45
- * @param string $name the tab's visible name
46
- * @param array $args additional arguments for the tab
47
- */
48
- public function __construct( $id, $name, $args = array() ) {
49
-
50
- // setup the defaults
51
- $this->defaults = array(
52
- 'fields' => array(),
53
- 'priority' => 50,
54
- 'show_save' => true,
55
- 'display_callback' => false,
56
- 'network_admin' => false,
57
- );
58
-
59
- // parse args with defaults
60
- $this->args = wp_parse_args( $args, $this->defaults );
61
-
62
- // set each instance variable and filter
63
- $this->id = apply_filters( 'tribe_settings_tab_id', $id );
64
- $this->name = apply_filters( 'tribe_settings_tab_name', $name );
65
- foreach ( $this->defaults as $key => $value ) {
66
- $this->{$key} = apply_filters( 'tribe_settings_tab_' . $key, $this->args[ $key ], $id );
67
- }
68
-
69
- // run actions & filters
70
- if ( ! $this->network_admin ) {
71
- add_filter( 'tribe_settings_all_tabs', array( $this, 'addAllTabs' ) );
72
- }
73
- add_filter( 'tribe_settings_tabs', array( $this, 'addTab' ), $this->priority );
74
- }
75
-
76
- /**
77
- * filters the tabs array from Tribe__Settings
78
- * and adds the current tab to it
79
- * does not add a tab if it's empty
80
- *
81
- * @param array $tabs the $tabs from Tribe__Settings
82
- *
83
- * @return array $tabs the filtered tabs
84
- */
85
- public function addTab( $tabs ) {
86
- $hideSettingsTabs = Tribe__Settings_Manager::get_network_option( 'hideSettingsTabs', array() );
87
- if ( ( isset( $this->fields ) || has_action( 'tribe_settings_content_tab_' . $this->id ) ) && ( empty( $hideSettingsTabs ) || ! in_array( $this->id, $hideSettingsTabs ) ) ) {
88
- if ( ( is_network_admin() && $this->args['network_admin'] ) || ( ! is_network_admin() && ! $this->args['network_admin'] ) ) {
89
- $tabs[ $this->id ] = $this->name;
90
- add_filter( 'tribe_settings_fields', array( $this, 'addFields' ) );
91
- add_filter( 'tribe_settings_no_save_tabs', array( $this, 'showSaveTab' ) );
92
- add_filter( 'tribe_settings_content_tab_' . $this->id, array( $this, 'doContent' ) );
93
- }
94
- }
95
-
96
- return $tabs;
97
- }
98
-
99
- /**
100
- * Adds this tab to the list of total tabs, even if it is not displayed.
101
- *
102
- * @param array $allTabs All the tabs from Tribe__Settings.
103
- *
104
- * @return array $allTabs All the tabs.
105
- */
106
- public function addAllTabs( $allTabs ) {
107
- $allTabs[ $this->id ] = $this->name;
108
-
109
- return $allTabs;
110
- }
111
-
112
-
113
- /**
114
- * filters the fields array from Tribe__Settings
115
- * and adds the current tab's fields to it
116
- *
117
- * @param array $field the $fields from Tribe__Settings
118
- *
119
- * @return array $fields the filtered fields
120
- */
121
- public function addFields( $fields ) {
122
- if ( ! empty ( $this->fields ) ) {
123
- $fields[ $this->id ] = $this->fields;
124
- } elseif ( has_action( 'tribe_settings_content_tab_' . $this->id ) ) {
125
- $fields[ $this->id ] = $this->fields = array( 0 => null ); // just to trick it
126
- }
127
-
128
- return $fields;
129
- }
130
-
131
- /**
132
- * sets whether the current tab should show the save
133
- * button or not
134
- *
135
- * @param array $noSaveTabs the $noSaveTabs from Tribe__Settings
136
- *
137
- * @return array $noSaveTabs the filtered non saving tabs
138
- */
139
- public function showSaveTab( $noSaveTabs ) {
140
- if ( ! $this->show_save || empty( $this->fields ) ) {
141
- $noSaveTabs[ $this->id ] = $this->id;
142
- }
143
-
144
- return $noSaveTabs;
145
- }
146
-
147
- /**
148
- * displays the content for the tab
149
- *
150
- * @return void
151
- */
152
- public function doContent() {
153
- if ( $this->display_callback && is_callable( $this->display_callback ) ) {
154
- call_user_func( $this->display_callback );
155
-
156
- return;
157
- }
158
-
159
- $sent_data = get_option( 'tribe_settings_sent_data', array() );
160
-
161
- if ( is_array( $this->fields ) && ! empty( $this->fields ) ) {
162
- foreach ( $this->fields as $key => $field ) {
163
- if ( isset( $sent_data[ $key ] ) ) {
164
- // if we just saved [or attempted to], get the value that was inputed
165
- $value = $sent_data[ $key ];
166
- } else {
167
- // Some options should always be stored at network level
168
- $network_option = isset( $field['network_option'] ) ? (bool) $field['network_option'] : false;
169
-
170
- if ( is_network_admin() ) {
171
- $parent_option = ( isset( $field['parent_option'] ) ) ? $field['parent_option'] : Tribe__Main::OPTIONNAMENETWORK;
172
- }
173
- if ( ! is_network_admin() ) {
174
- $parent_option = ( isset( $field['parent_option'] ) ) ? $field['parent_option'] : Tribe__Main::OPTIONNAME;
175
- }
176
- // get the field's parent_option in order to later get the field's value
177
- $parent_option = apply_filters( 'tribe_settings_do_content_parent_option', $parent_option, $key );
178
- $default = ( isset( $field['default'] ) ) ? $field['default'] : null;
179
- $default = apply_filters( 'tribe_settings_field_default', $default, $field );
180
-
181
- if ( ! $parent_option ) {
182
- // no parent option, get the straight up value
183
- if ( $network_option || is_network_admin() ) {
184
- $value = get_site_option( $key, $default );
185
- } else {
186
- $value = get_option( $key, $default );
187
- }
188
- } else {
189
- // there's a parent option
190
- if ( $parent_option == Tribe__Main::OPTIONNAME ) {
191
- // get the options from Tribe__Settings_Manager if we're getting the main array
192
- $value = Tribe__Settings_Manager::get_option( $key, $default );
193
- } elseif ( $parent_option == Tribe__Main::OPTIONNAMENETWORK ) {
194
- $value = Tribe__Settings_Manager::get_network_option( $key, $default );
195
- } else {
196
- // else, get the parent option normally
197
- if ( is_network_admin() ) {
198
- $options = (array) get_site_option( $parent_option );
199
- } else {
200
- $options = (array) get_option( $parent_option );
201
- }
202
- $value = ( isset( $options[ $key ] ) ) ? $options[ $key ] : $default;
203
- }
204
- }
205
- }
206
-
207
- // escape the value for display
208
- if ( ! empty( $field['esc_display'] ) && function_exists( $field['esc_display'] ) ) {
209
- $value = $field['esc_display']( $value );
210
- } elseif ( is_string( $value ) ) {
211
- $value = esc_attr( stripslashes( $value ) );
212
- }
213
-
214
- // filter the value
215
- $value = apply_filters( 'tribe_settings_get_option_value_pre_display', $value, $key, $field );
216
-
217
- // create the field
218
- new Tribe__Field( $key, $field, $value );
219
- }
220
- } else {
221
- // no fields setup for this tab yet
222
- echo '<p>' . esc_html__( 'There are no fields setup for this tab yet.', 'tribe-common' ) . '</p>';
223
- }
224
- }
225
-
226
- } // end class
227
- } // endif class_exists
1
+ <?php
2
+
3
+ // Don't load directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ die( '-1' );
6
+ }
7
+
8
+ if ( ! class_exists( 'Tribe__Settings_Tab' ) ) {
9
+ /**
10
+ * helper class that creates a settings tab
11
+ * this is a public API, use it to create tabs
12
+ * simply by instantiating this class
13
+ *
14
+ */
15
+ class Tribe__Settings_Tab {
16
+
17
+ /**
18
+ * Tab ID, used in query string and elsewhere
19
+ * @var string
20
+ */
21
+ public $id;
22
+
23
+ /**
24
+ * Tab's name
25
+ * @var string
26
+ */
27
+ public $name;
28
+
29
+ /**
30
+ * Tab's arguments
31
+ * @var array
32
+ */
33
+ public $args;
34
+
35
+ /**
36
+ * Defaults for tabs
37
+ * @var array
38
+ */
39
+ public $defaults;
40
+
41
+ /**
42
+ * class constructor
43
+ *
44
+ * @param string $id the tab's id (no spaces or special characters)
45
+ * @param string $name the tab's visible name
46
+ * @param array $args additional arguments for the tab
47
+ */
48
+ public function __construct( $id, $name, $args = array() ) {
49
+
50
+ // setup the defaults
51
+ $this->defaults = array(
52
+ 'fields' => array(),
53
+ 'priority' => 50,
54
+ 'show_save' => true,
55
+ 'display_callback' => false,
56
+ 'network_admin' => false,
57
+ );
58
+
59
+ // parse args with defaults
60
+ $this->args = wp_parse_args( $args, $this->defaults );
61
+
62
+ // set each instance variable and filter
63
+ $this->id = apply_filters( 'tribe_settings_tab_id', $id );
64
+ $this->name = apply_filters( 'tribe_settings_tab_name', $name );
65
+ foreach ( $this->defaults as $key => $value ) {
66
+ $this->{$key} = apply_filters( 'tribe_settings_tab_' . $key, $this->args[ $key ], $id );
67
+ }
68
+
69
+ // run actions & filters
70
+ if ( ! $this->network_admin ) {
71
+ add_filter( 'tribe_settings_all_tabs', array( $this, 'addAllTabs' ) );
72
+ }
73
+ add_filter( 'tribe_settings_tabs', array( $this, 'addTab' ), $this->priority );
74
+ }
75
+
76
+ /**
77
+ * filters the tabs array from Tribe__Settings
78
+ * and adds the current tab to it
79
+ * does not add a tab if it's empty
80
+ *
81
+ * @param array $tabs the $tabs from Tribe__Settings
82
+ *
83
+ * @return array $tabs the filtered tabs
84
+ */
85
+ public function addTab( $tabs ) {
86
+ $hideSettingsTabs = Tribe__Settings_Manager::get_network_option( 'hideSettingsTabs', array() );
87
+ if ( ( isset( $this->fields ) || has_action( 'tribe_settings_content_tab_' . $this->id ) ) && ( empty( $hideSettingsTabs ) || ! in_array( $this->id, $hideSettingsTabs ) ) ) {
88
+ if ( ( is_network_admin() && $this->args['network_admin'] ) || ( ! is_network_admin() && ! $this->args['network_admin'] ) ) {
89
+ $tabs[ $this->id ] = $this->name;
90
+ add_filter( 'tribe_settings_fields', array( $this, 'addFields' ) );
91
+ add_filter( 'tribe_settings_no_save_tabs', array( $this, 'showSaveTab' ) );
92
+ add_filter( 'tribe_settings_content_tab_' . $this->id, array( $this, 'doContent' ) );
93
+ }
94
+ }
95
+
96
+ return $tabs;
97
+ }
98
+
99
+ /**
100
+ * Adds this tab to the list of total tabs, even if it is not displayed.
101
+ *
102
+ * @param array $allTabs All the tabs from Tribe__Settings.
103
+ *
104
+ * @return array $allTabs All the tabs.
105
+ */
106
+ public function addAllTabs( $allTabs ) {
107
+ $allTabs[ $this->id ] = $this->name;
108
+
109
+ return $allTabs;
110
+ }
111
+
112
+
113
+ /**
114
+ * filters the fields array from Tribe__Settings
115
+ * and adds the current tab's fields to it
116
+ *
117
+ * @param array $field the $fields from Tribe__Settings
118
+ *
119
+ * @return array $fields the filtered fields
120
+ */
121
+ public function addFields( $fields ) {
122
+ if ( ! empty ( $this->fields ) ) {
123
+ $fields[ $this->id ] = $this->fields;
124
+ } elseif ( has_action( 'tribe_settings_content_tab_' . $this->id ) ) {
125
+ $fields[ $this->id ] = $this->fields = array( 0 => null ); // just to trick it
126
+ }
127
+
128
+ return $fields;
129
+ }
130
+
131
+ /**
132
+ * sets whether the current tab should show the save
133
+ * button or not
134
+ *
135
+ * @param array $noSaveTabs the $noSaveTabs from Tribe__Settings
136
+ *
137
+ * @return array $noSaveTabs the filtered non saving tabs
138
+ */
139
+ public function showSaveTab( $noSaveTabs ) {
140
+ if ( ! $this->show_save || empty( $this->fields ) ) {
141
+ $noSaveTabs[ $this->id ] = $this->id;
142
+ }
143
+
144
+ return $noSaveTabs;
145
+ }
146
+
147
+ /**
148
+ * displays the content for the tab
149
+ *
150
+ * @return void
151
+ */
152
+ public function doContent() {
153
+ if ( $this->display_callback && is_callable( $this->display_callback ) ) {
154
+ call_user_func( $this->display_callback );
155
+
156
+ return;
157
+ }
158
+
159
+ $sent_data = get_option( 'tribe_settings_sent_data', array() );
160
+
161
+ if ( is_array( $this->fields ) && ! empty( $this->fields ) ) {
162
+ foreach ( $this->fields as $key => $field ) {
163
+ if ( isset( $sent_data[ $key ] ) ) {
164
+ // if we just saved [or attempted to], get the value that was inputed
165
+ $value = $sent_data[ $key ];
166
+ } else {
167
+ // Some options should always be stored at network level
168
+ $network_option = isset( $field['network_option'] ) ? (bool) $field['network_option'] : false;
169
+
170
+ if ( is_network_admin() ) {
171
+ $parent_option = ( isset( $field['parent_option'] ) ) ? $field['parent_option'] : Tribe__Main::OPTIONNAMENETWORK;
172
+ }
173
+ if ( ! is_network_admin() ) {
174
+ $parent_option = ( isset( $field['parent_option'] ) ) ? $field['parent_option'] : Tribe__Main::OPTIONNAME;
175
+ }
176
+ // get the field's parent_option in order to later get the field's value
177
+ $parent_option = apply_filters( 'tribe_settings_do_content_parent_option', $parent_option, $key );
178
+ $default = ( isset( $field['default'] ) ) ? $field['default'] : null;
179
+ $default = apply_filters( 'tribe_settings_field_default', $default, $field );
180
+
181
+ if ( ! $parent_option ) {
182
+ // no parent option, get the straight up value
183
+ if ( $network_option || is_network_admin() ) {
184
+ $value = get_site_option( $key, $default );
185
+ } else {
186
+ $value = get_option( $key, $default );
187
+ }
188
+ } else {
189
+ // there's a parent option
190
+ if ( $parent_option == Tribe__Main::OPTIONNAME ) {
191
+ // get the options from Tribe__Settings_Manager if we're getting the main array
192
+ $value = Tribe__Settings_Manager::get_option( $key, $default );
193
+ } elseif ( $parent_option == Tribe__Main::OPTIONNAMENETWORK ) {
194
+ $value = Tribe__Settings_Manager::get_network_option( $key, $default );
195
+ } else {
196
+ // else, get the parent option normally
197
+ if ( is_network_admin() ) {
198
+ $options = (array) get_site_option( $parent_option );
199
+ } else {
200
+ $options = (array) get_option( $parent_option );
201
+ }
202
+ $value = ( isset( $options[ $key ] ) ) ? $options[ $key ] : $default;
203
+ }
204
+ }
205
+ }
206
+
207
+ // escape the value for display
208
+ if ( ! empty( $field['esc_display'] ) && function_exists( $field['esc_display'] ) ) {
209
+ $value = $field['esc_display']( $value );
210
+ } elseif ( is_string( $value ) ) {
211
+ $value = esc_attr( stripslashes( $value ) );
212
+ }
213
+
214
+ // filter the value
215
+ $value = apply_filters( 'tribe_settings_get_option_value_pre_display', $value, $key, $field );
216
+
217
+ // create the field
218
+ new Tribe__Field( $key, $field, $value );
219
+ }
220
+ } else {
221
+ // no fields setup for this tab yet
222
+ echo '<p>' . esc_html__( 'There are no fields setup for this tab yet.', 'tribe-common' ) . '</p>';
223
+ }
224
+ }
225
+
226
+ } // end class
227
+ } // endif class_exists
common/src/Tribe/Support.php CHANGED
@@ -1,291 +1,291 @@
1
- <?php
2
- /**
3
- * Class for managing technical support components
4
- */
5
-
6
- // Don't load directly
7
- if ( ! defined( 'ABSPATH' ) ) {
8
- die( '-1' );
9
- }
10
-
11
- if ( ! class_exists( 'Tribe__Support' ) ) {
12
-
13
- class Tribe__Support {
14
-
15
- public static $support;
16
- public $rewrite_rules_purged = false;
17
-
18
- /**
19
- * @var Tribe__Support__Obfuscator
20
- */
21
- protected $obfuscator;
22
-
23
- /**
24
- * Fields listed here contain HTML and should be escaped before being
25
- * printed.
26
- *
27
- * @var array
28
- */
29
- protected $must_escape = array(
30
- 'tribeEventsAfterHTML',
31
- 'tribeEventsBeforeHTML',
32
- );
33
-
34
- /**
35
- * Field prefixes here should be partially obfuscated before being printed.
36
- *
37
- * @var array
38
- */
39
- protected $must_obfuscate_prefixes = array(
40
- 'pue_install_key_',
41
- );
42
-
43
- private function __construct() {
44
- $this->must_escape = (array) apply_filters( 'tribe_help_must_escape_fields', $this->must_escape );
45
- add_action( 'tribe_help_pre_get_sections', array( $this, 'append_system_info' ), 10 );
46
- add_action( 'delete_option_rewrite_rules', array( $this, 'log_rewrite_rule_purge' ) );
47
- }
48
-
49
- /**
50
- * Display help tab info in events settings
51
- * @param Tribe__Admin__Help_Page $help The Help Page Instance
52
- */
53
- public function append_system_info( Tribe__Admin__Help_Page $help ) {
54
- $help->add_section_content( 'system-info', $this->formattedSupportStats(), 10 );
55
- }
56
-
57
- /**
58
- * Collect system information for support
59
- *
60
- * @return array of system data for support
61
- */
62
- public function getSupportStats() {
63
- global $wpdb;
64
- $user = wp_get_current_user();
65
-
66
- $plugins = array();
67
- if ( function_exists( 'get_plugin_data' ) ) {
68
- $plugins_raw = wp_get_active_and_valid_plugins();
69
- foreach ( $plugins_raw as $k => $v ) {
70
- $plugin_details = get_plugin_data( $v );
71
- $plugin = $plugin_details['Name'];
72
- if ( ! empty( $plugin_details['Version'] ) ) {
73
- $plugin .= sprintf( ' version %s', $plugin_details['Version'] );
74
- }
75
- if ( ! empty( $plugin_details['Author'] ) ) {
76
- $plugin .= sprintf( ' by %s', $plugin_details['Author'] );
77
- }
78
- if ( ! empty( $plugin_details['AuthorURI'] ) ) {
79
- $plugin .= sprintf( '(%s)', $plugin_details['AuthorURI'] );
80
- }
81
- $plugins[] = $plugin;
82
- }
83
- }
84
-
85
- $network_plugins = array();
86
- if ( is_multisite() && function_exists( 'get_plugin_data' ) ) {
87
- $plugins_raw = wp_get_active_network_plugins();
88
- foreach ( $plugins_raw as $k => $v ) {
89
- $plugin_details = get_plugin_data( $v );
90
- $plugin = $plugin_details['Name'];
91
- if ( ! empty( $plugin_details['Version'] ) ) {
92
- $plugin .= sprintf( ' version %s', $plugin_details['Version'] );
93
- }
94
- if ( ! empty( $plugin_details['Author'] ) ) {
95
- $plugin .= sprintf( ' by %s', $plugin_details['Author'] );
96
- }
97
- if ( ! empty( $plugin_details['AuthorURI'] ) ) {
98
- $plugin .= sprintf( '(%s)', $plugin_details['AuthorURI'] );
99
- }
100
- $network_plugins[] = $plugin;
101
- }
102
- }
103
-
104
- $mu_plugins = array();
105
- if ( function_exists( 'get_mu_plugins' ) ) {
106
- $mu_plugins_raw = get_mu_plugins();
107
- foreach ( $mu_plugins_raw as $k => $v ) {
108
- $plugin = $v['Name'];
109
- if ( ! empty( $v['Version'] ) ) {
110
- $plugin .= sprintf( ' version %s', $v['Version'] );
111
- }
112
- if ( ! empty( $v['Author'] ) ) {
113
- $plugin .= sprintf( ' by %s', $v['Author'] );
114
- }
115
- if ( ! empty( $v['AuthorURI'] ) ) {
116
- $plugin .= sprintf( '(%s)', $v['AuthorURI'] );
117
- }
118
- $mu_plugins[] = $plugin;
119
- }
120
- }
121
-
122
- $keys = apply_filters( 'tribe-pue-install-keys', array() );
123
- //Obfuscate the License Keys for Security
124
- if ( is_array( $keys ) && ! empty( $keys ) ) {
125
- $secure_keys = array();
126
- foreach ( $keys as $plugin => $license ) {
127
- $secure_keys[ $plugin ] = preg_replace( '/^(.{4}).*(.{4})$/', '$1' . str_repeat( '#', 32 ) . '$2', $license );
128
- }
129
- $keys = $secure_keys;
130
- }
131
-
132
- //Server
133
- $server = explode( ' ', $_SERVER['SERVER_SOFTWARE'] );
134
- $server = explode( '/', reset( $server ) );
135
-
136
- //PHP Information
137
- $php_info = array();
138
- $php_vars = array(
139
- 'max_execution_time',
140
- 'memory_limit',
141
- 'upload_max_filesize',
142
- 'post_max_size',
143
- 'display_errors',
144
- 'log_errors',
145
- );
146
-
147
- foreach ( $php_vars as $php_var ) {
148
- if ( isset( $wpdb->qm_php_vars ) && isset( $wpdb->qm_php_vars[ $php_var ] ) ) {
149
- $val = $wpdb->qm_php_vars[ $php_var ];
150
- } else {
151
- $val = ini_get( $php_var );
152
- }
153
- $php_info[ $php_var ] = $val;
154
- }
155
-
156
- $systeminfo = array(
157
- 'Home URL' => get_home_url(),
158
- 'Site URL' => get_site_url(),
159
- 'Site Language' => get_option( 'WPLANG' ) ? get_option( 'WPLANG' ) : esc_html__( 'English', 'tribe-common' ),
160
- 'Character Set' => get_option( 'blog_charset' ),
161
- 'WP Permalinks' => get_option( 'permalink_structure' ),
162
- 'Name' => $user->display_name,
163
- 'Email' => $user->user_email,
164
- 'Install keys' => $keys,
165
- 'WordPress version' => get_bloginfo( 'version' ),
166
- 'PHP version' => phpversion(),
167
- 'PHP' => $php_info,
168
- 'Server' => $server[0],
169
- 'SAPI' => php_sapi_name(),
170
- 'Plugins' => $plugins,
171
- 'Network Plugins' => $network_plugins,
172
- 'MU Plugins' => $mu_plugins,
173
- 'Theme' => wp_get_theme()->get( 'Name' ),
174
- 'Multisite' => is_multisite(),
175
- 'Settings' => Tribe__Settings_Manager::get_options(),
176
- 'WP Timezone' => get_option( 'timezone_string' ) ? get_option( 'timezone_string' ) : esc_html__( 'Unknown or not set', 'tribe-common' ),
177
- 'WP GMT Offset' => get_option( 'gmt_offset' ) ? ' ' . get_option( 'gmt_offset' ) : esc_html__( 'Unknown or not set', 'tribe-common' ),
178
- 'Server Timezone' => date_default_timezone_get(),
179
- 'WP Date Format' => get_option( 'date_format' ),
180
- 'WP Time Format' => get_option( 'time_format' ),
181
- 'Week Starts On' => get_option( 'start_of_week' ),
182
- 'Common Library Dir' => $GLOBALS['tribe-common-info']['dir'],
183
- 'Common Library Version' => $GLOBALS['tribe-common-info']['version'],
184
- );
185
-
186
- if ( $this->rewrite_rules_purged ) {
187
- $systeminfo['rewrite rules purged'] = esc_html__( 'Rewrite rules were purged on load of this help page. Chances are there is a rewrite rule flush occurring in a plugin or theme!', 'tribe-common' );
188
- }
189
- $systeminfo = apply_filters( 'tribe-events-pro-support', $systeminfo );
190
-
191
- return $systeminfo;
192
- }
193
-
194
- /**
195
- * Render system information into a pretty output
196
- *
197
- * @return string pretty HTML
198
- */
199
- public function formattedSupportStats() {
200
- $systeminfo = $this->getSupportStats();
201
- $output = '';
202
- $output .= '<dl class="support-stats">';
203
- foreach ( $systeminfo as $k => $v ) {
204
-
205
- switch ( $k ) {
206
- case 'name' :
207
- case 'email' :
208
- continue 2;
209
- break;
210
- case 'url' :
211
- $v = sprintf( '<a href="%s">%s</a>', $v, $v );
212
- break;
213
- }
214
-
215
- if ( is_array( $v ) ) {
216
- $keys = array_keys( $v );
217
- $key = array_shift( $keys );
218
- $is_numeric_array = is_numeric( $key );
219
- unset( $keys );
220
- unset( $key );
221
- }
222
-
223
- $output .= sprintf( '<dt>%s</dt>', $k );
224
- if ( empty( $v ) ) {
225
- $output .= '<dd class="support-stats-null">-</dd>';
226
- } elseif ( is_bool( $v ) ) {
227
- $output .= sprintf( '<dd class="support-stats-bool">%s</dd>', $v );
228
- } elseif ( is_string( $v ) ) {
229
- $output .= sprintf( '<dd class="support-stats-string">%s</dd>', $v );
230
- } elseif ( is_array( $v ) && $is_numeric_array ) {
231
- $output .= sprintf( '<dd class="support-stats-array"><ul><li>%s</li></ul></dd>', join( '</li><li>', $v ) );
232
- } else {
233
- $formatted_v = array();
234
- foreach ( $v as $obj_key => $obj_val ) {
235
- if ( in_array( $obj_key, $this->must_escape ) ) {
236
- $obj_val = esc_html( $obj_val );
237
- }
238
-
239
- $obj_val = $this->obfuscator->obfuscate( $obj_key, $obj_val );
240
-
241
- if ( is_array( $obj_val ) ) {
242
- $formatted_v[] = sprintf( '<li>%s = <pre>%s</pre></li>', $obj_key, print_r( $obj_val, true ) );
243
- } else {
244
- $formatted_v[] = sprintf( '<li>%s = %s</li>', $obj_key, $obj_val );
245
- }
246
- }
247
- $v = join( "\n", $formatted_v );
248
- $output .= sprintf( '<dd class="support-stats-object"><ul>%s</ul></dd>', print_r( $v, true ) );
249
- }
250
- }
251
- $output .= '</dl>';
252
-
253
- return $output;
254
- }
255
-
256
- /**
257
- * Logs the occurence of rewrite rule purging
258
- */
259
- public function log_rewrite_rule_purge() {
260
- $this->rewrite_rules_purged = true;
261
- }//end log_rewrite_rule_purge
262
-
263
- /**
264
- * Sets the obfuscator to be used.
265
- *
266
- * @param Tribe__Support__Obfuscator $obfuscator
267
- */
268
- public function set_obfuscator( Tribe__Support__Obfuscator $obfuscator ) {
269
- $this->obfuscator = $obfuscator;
270
- }
271
-
272
- /****************** SINGLETON GUTS ******************/
273
-
274
- /**
275
- * Enforce Singleton Pattern
276
- */
277
- private static $instance;
278
-
279
-
280
- public static function getInstance() {
281
- if ( null == self::$instance ) {
282
- $instance = new self;
283
- $instance->set_obfuscator( new Tribe__Support__Obfuscator( $instance->must_obfuscate_prefixes ) );
284
- self::$instance = $instance;
285
- }
286
-
287
- return self::$instance;
288
- }
289
- }
290
-
291
- }
1
+ <?php
2
+ /**
3
+ * Class for managing technical support components
4
+ */
5
+
6
+ // Don't load directly
7
+ if ( ! defined( 'ABSPATH' ) ) {
8
+ die( '-1' );
9
+ }
10
+
11
+ if ( ! class_exists( 'Tribe__Support' ) ) {
12
+
13
+ class Tribe__Support {
14
+
15
+ public static $support;
16
+ public $rewrite_rules_purged = false;
17
+
18
+ /**
19
+ * @var Tribe__Support__Obfuscator
20
+ */
21
+ protected $obfuscator;
22
+
23
+ /**
24
+ * Fields listed here contain HTML and should be escaped before being
25
+ * printed.
26
+ *
27
+ * @var array
28
+ */
29
+ protected $must_escape = array(
30
+ 'tribeEventsAfterHTML',
31
+ 'tribeEventsBeforeHTML',
32
+ );
33
+
34
+ /**
35
+ * Field prefixes here should be partially obfuscated before being printed.
36
+ *
37
+ * @var array
38
+ */
39
+ protected $must_obfuscate_prefixes = array(
40
+ 'pue_install_key_',
41
+ );
42
+
43
+ private function __construct() {
44
+ $this->must_escape = (array) apply_filters( 'tribe_help_must_escape_fields', $this->must_escape );
45
+ add_action( 'tribe_help_pre_get_sections', array( $this, 'append_system_info' ), 10 );
46
+ add_action( 'delete_option_rewrite_rules', array( $this, 'log_rewrite_rule_purge' ) );
47
+ }
48
+
49
+ /**
50
+ * Display help tab info in events settings
51
+ * @param Tribe__Admin__Help_Page $help The Help Page Instance
52
+ */
53
+ public function append_system_info( Tribe__Admin__Help_Page $help ) {
54
+ $help->add_section_content( 'system-info', $this->formattedSupportStats(), 10 );
55
+ }
56
+
57
+ /**
58
+ * Collect system information for support
59
+ *
60
+ * @return array of system data for support
61
+ */
62
+ public function getSupportStats() {
63
+ global $wpdb;
64
+ $user = wp_get_current_user();
65
+
66
+ $plugins = array();
67
+ if ( function_exists( 'get_plugin_data' ) ) {
68
+ $plugins_raw = wp_get_active_and_valid_plugins();
69
+ foreach ( $plugins_raw as $k => $v ) {
70
+ $plugin_details = get_plugin_data( $v );
71
+ $plugin = $plugin_details['Name'];
72
+ if ( ! empty( $plugin_details['Version'] ) ) {
73
+ $plugin .= sprintf( ' version %s', $plugin_details['Version'] );
74
+ }
75
+ if ( ! empty( $plugin_details['Author'] ) ) {
76
+ $plugin .= sprintf( ' by %s', $plugin_details['Author'] );
77
+ }
78
+ if ( ! empty( $plugin_details['AuthorURI'] ) ) {
79
+ $plugin .= sprintf( '(%s)', $plugin_details['AuthorURI'] );
80
+ }
81
+ $plugins[] = $plugin;
82
+ }
83
+ }
84
+
85
+ $network_plugins = array();
86
+ if ( is_multisite() && function_exists( 'get_plugin_data' ) ) {
87
+ $plugins_raw = wp_get_active_network_plugins();
88
+ foreach ( $plugins_raw as $k => $v ) {
89
+ $plugin_details = get_plugin_data( $v );
90
+ $plugin = $plugin_details['Name'];
91
+ if ( ! empty( $plugin_details['Version'] ) ) {
92
+ $plugin .= sprintf( ' version %s', $plugin_details['Version'] );
93
+ }
94
+ if ( ! empty( $plugin_details['Author'] ) ) {
95
+ $plugin .= sprintf( ' by %s', $plugin_details['Author'] );
96
+ }
97
+ if ( ! empty( $plugin_details['AuthorURI'] ) ) {
98
+ $plugin .= sprintf( '(%s)', $plugin_details['AuthorURI'] );
99
+ }
100
+ $network_plugins[] = $plugin;
101
+ }
102
+ }
103
+
104
+ $mu_plugins = array();
105
+ if ( function_exists( 'get_mu_plugins' ) ) {
106
+ $mu_plugins_raw = get_mu_plugins();
107
+ foreach ( $mu_plugins_raw as $k => $v ) {
108
+ $plugin = $v['Name'];
109
+ if ( ! empty( $v['Version'] ) ) {
110
+ $plugin .= sprintf( ' version %s', $v['Version'] );
111
+ }
112
+ if ( ! empty( $v['Author'] ) ) {
113
+ $plugin .= sprintf( ' by %s', $v['Author'] );
114
+ }
115
+ if ( ! empty( $v['AuthorURI'] ) ) {
116
+ $plugin .= sprintf( '(%s)', $v['AuthorURI'] );
117
+ }
118
+ $mu_plugins[] = $plugin;
119
+ }
120
+ }
121
+
122
+ $keys = apply_filters( 'tribe-pue-install-keys', array() );
123
+ //Obfuscate the License Keys for Security
124
+ if ( is_array( $keys ) && ! empty( $keys ) ) {
125
+ $secure_keys = array();
126
+ foreach ( $keys as $plugin => $license ) {
127
+ $secure_keys[ $plugin ] = preg_replace( '/^(.{4}).*(.{4})$/', '$1' . str_repeat( '#', 32 ) . '$2', $license );
128
+ }
129
+ $keys = $secure_keys;
130
+ }
131
+
132
+ //Server
133
+ $server = explode( ' ', $_SERVER['SERVER_SOFTWARE'] );
134
+ $server = explode( '/', reset( $server ) );
135
+
136
+ //PHP Information
137
+ $php_info = array();
138
+ $php_vars = array(
139
+ 'max_execution_time',
140
+ 'memory_limit',
141
+ 'upload_max_filesize',
142
+ 'post_max_size',
143
+ 'display_errors',
144
+ 'log_errors',
145
+ );
146
+
147
+ foreach ( $php_vars as $php_var ) {
148
+ if ( isset( $wpdb->qm_php_vars ) && isset( $wpdb->qm_php_vars[ $php_var ] ) ) {
149
+ $val = $wpdb->qm_php_vars[ $php_var ];
150
+ } else {
151
+ $val = ini_get( $php_var );
152
+ }
153
+ $php_info[ $php_var ] = $val;
154
+ }
155
+
156
+ $systeminfo = array(
157
+ 'Home URL' => get_home_url(),
158
+ 'Site URL' => get_site_url(),
159
+ 'Site Language' => get_option( 'WPLANG' ) ? get_option( 'WPLANG' ) : esc_html__( 'English', 'tribe-common' ),
160
+ 'Character Set' => get_option( 'blog_charset' ),
161
+ 'WP Permalinks' => get_option( 'permalink_structure' ),
162
+ 'Name' => $user->display_name,
163
+ 'Email' => $user->user_email,
164
+ 'Install keys' => $keys,
165
+ 'WordPress version' => get_bloginfo( 'version' ),
166
+ 'PHP version' => phpversion(),
167
+ 'PHP' => $php_info,
168
+ 'Server' => $server[0],
169
+ 'SAPI' => php_sapi_name(),
170
+ 'Plugins' => $plugins,
171
+ 'Network Plugins' => $network_plugins,
172
+ 'MU Plugins' => $mu_plugins,
173
+ 'Theme' => wp_get_theme()->get( 'Name' ),
174
+ 'Multisite' => is_multisite(),
175
+ 'Settings' => Tribe__Settings_Manager::get_options(),
176
+ 'WP Timezone' => get_option( 'timezone_string' ) ? get_option( 'timezone_string' ) : esc_html__( 'Unknown or not set', 'tribe-common' ),
177
+ 'WP GMT Offset' => get_option( 'gmt_offset' ) ? ' ' . get_option( 'gmt_offset' ) : esc_html__( 'Unknown or not set', 'tribe-common' ),
178
+ 'Server Timezone' => date_default_timezone_get(),
179
+ 'WP Date Format' => get_option( 'date_format' ),
180
+ 'WP Time Format' => get_option( 'time_format' ),
181
+ 'Week Starts On' => get_option( 'start_of_week' ),
182
+ 'Common Library Dir' => $GLOBALS['tribe-common-info']['dir'],
183
+ 'Common Library Version' => $GLOBALS['tribe-common-info']['version'],
184
+ );
185
+
186
+ if ( $this->rewrite_rules_purged ) {
187
+ $systeminfo['rewrite rules purged'] = esc_html__( 'Rewrite rules were purged on load of this help page. Chances are there is a rewrite rule flush occurring in a plugin or theme!', 'tribe-common' );
188
+ }
189
+ $systeminfo = apply_filters( 'tribe-events-pro-support', $systeminfo );
190
+
191
+ return $systeminfo;
192
+ }
193
+
194
+ /**
195
+ * Render system information into a pretty output
196
+ *
197
+ * @return string pretty HTML
198
+ */
199
+ public function formattedSupportStats() {
200
+ $systeminfo = $this->getSupportStats();
201
+ $output = '';
202
+ $output .= '<dl class="support-stats">';
203
+ foreach ( $systeminfo as $k => $v ) {
204
+
205
+ switch ( $k ) {
206
+ case 'name' :
207
+ case 'email' :
208
+ continue 2;
209
+ break;
210
+ case 'url' :
211
+ $v = sprintf( '<a href="%s">%s</a>', $v, $v );
212
+ break;
213
+ }
214
+
215
+ if ( is_array( $v ) ) {
216
+ $keys = array_keys( $v );
217
+ $key = array_shift( $keys );
218
+ $is_numeric_array = is_numeric( $key );
219
+ unset( $keys );
220
+ unset( $key );
221
+ }
222
+
223
+ $output .= sprintf( '<dt>%s</dt>', $k );
224
+ if ( empty( $v ) ) {
225
+ $output .= '<dd class="support-stats-null">-</dd>';
226
+ } elseif ( is_bool( $v ) ) {
227
+ $output .= sprintf( '<dd class="support-stats-bool">%s</dd>', $v );
228
+ } elseif ( is_string( $v ) ) {
229
+ $output .= sprintf( '<dd class="support-stats-string">%s</dd>', $v );
230
+ } elseif ( is_array( $v ) && $is_numeric_array ) {
231
+ $output .= sprintf( '<dd class="support-stats-array"><ul><li>%s</li></ul></dd>', join( '</li><li>', $v ) );
232
+ } else {
233
+ $formatted_v = array();
234
+ foreach ( $v as $obj_key => $obj_val ) {
235
+ if ( in_array( $obj_key, $this->must_escape ) ) {
236
+ $obj_val = esc_html( $obj_val );
237
+ }
238
+
239
+ $obj_val = $this->obfuscator->obfuscate( $obj_key, $obj_val );
240
+
241
+ if ( is_array( $obj_val ) ) {
242
+ $formatted_v[] = sprintf( '<li>%s = <pre>%s</pre></li>', $obj_key, print_r( $obj_val, true ) );
243
+ } else {
244
+ $formatted_v[] = sprintf( '<li>%s = %s</li>', $obj_key, $obj_val );
245
+ }
246
+ }
247
+ $v = join( "\n", $formatted_v );
248
+ $output .= sprintf( '<dd class="support-stats-object"><ul>%s</ul></dd>', print_r( $v, true ) );
249
+ }
250
+ }
251
+ $output .= '</dl>';
252
+
253
+ return $output;
254
+ }
255
+
256
+ /**
257
+ * Logs the occurence of rewrite rule purging
258
+ */
259
+ public function log_rewrite_rule_purge() {
260
+ $this->rewrite_rules_purged = true;
261
+ }//end log_rewrite_rule_purge
262
+
263
+ /**
264
+ * Sets the obfuscator to be used.
265
+ *
266
+ * @param Tribe__Support__Obfuscator $obfuscator
267
+ */
268
+ public function set_obfuscator( Tribe__Support__Obfuscator $obfuscator ) {
269
+ $this->obfuscator = $obfuscator;
270
+ }
271
+
272
+ /****************** SINGLETON GUTS ******************/
273
+
274
+ /**
275
+ * Enforce Singleton Pattern
276
+ */
277
+ private static $instance;
278
+
279
+
280
+ public static function getInstance() {
281
+ if ( null == self::$instance ) {
282
+ $instance = new self;
283
+ $instance->set_obfuscator( new Tribe__Support__Obfuscator( $instance->must_obfuscate_prefixes ) );
284
+ self::$instance = $instance;
285
+ }
286
+
287
+ return self::$instance;
288
+ }
289
+ }
290
+
291
+ }
common/src/Tribe/Support/Obfuscator.php CHANGED
@@ -1,68 +1,68 @@
1
- <?php
2
-
3
-
4
- class Tribe__Support__Obfuscator {
5
-
6
- /**
7
- * @var array
8
- */
9
- protected $prefixes = array();
10
-
11
- /**
12
- * Tribe__Support__Obfuscator constructor.
13
- *
14
- * @param array $prefixes
15
- */
16
- public function __construct( array $prefixes = array() ) {
17
- $this->prefixes = $prefixes;
18
- }
19
-
20
- /**
21
- * Whether a value should be obfuscated or not.
22
- *
23
- * @param string $key
24
- *
25
- * @return bool
26
- */
27
- public function should_obfuscate( $key ) {
28
- foreach ( $this->prefixes as $prefix ) {
29
- if ( strpos( $key, $prefix ) === 0 ) {
30
- return true;
31
- }
32
- }
33
-
34
- return false;
35
- }
36
-
37
- /**
38
- * Conditionally obfuscates a string value.
39
- *
40
- * @param string $key
41
- * @param mixed $string_value
42
- *
43
- * @return mixed Either the obfuscated string or the original value if not a string.
44
- */
45
- public function obfuscate( $key, $string_value ) {
46
- if ( ! is_string( $string_value ) ) {
47
- return $string_value;
48
- }
49
- if ( ! $this->should_obfuscate( $key ) ) {
50
- return $string_value;
51
- }
52
-
53
- $length = strlen( $string_value );
54
- if ( $length <= 3 ) {
55
- return preg_replace( "/./", "#", $string_value );
56
- } elseif ( $length > 3 && $length <= 5 ) {
57
- return preg_replace( '/^(.{1}).*$/', '$1' . str_repeat( '#', $length - 1 ) . '$2', $string_value );
58
- } elseif ( $length > 5 && $length <= 9 ) {
59
- return preg_replace( '/^(.{1}).*(.{1})$/', '$1' . str_repeat( '#', $length - 2 ) . '$2', $string_value );
60
- } elseif ( $length > 9 && $length <= 19 ) {
61
- return preg_replace( '/^(.{2}).*(.{2})$/', '$1' . str_repeat( '#', $length - 4 ) . '$2', $string_value );
62
- } elseif ( $length > 19 && $length <= 31 ) {
63
- return preg_replace( '/^(.{3}).*(.{3})$/', '$1' . str_repeat( '#', $length - 6 ) . '$2', $string_value );
64
- }
65
-
66
- return preg_replace( '/^(.{4}).*(.{4})$/', '$1' . str_repeat( '#', $length - 8 ) . '$2', $string_value );
67
- }
68
  }
1
+ <?php
2
+
3
+
4
+ class Tribe__Support__Obfuscator {
5
+
6
+ /**
7
+ * @var array
8
+ */
9
+ protected $prefixes = array();
10
+
11
+ /**
12
+ * Tribe__Support__Obfuscator constructor.
13
+ *
14
+ * @param array $prefixes
15
+ */
16
+ public function __construct( array $prefixes = array() ) {
17
+ $this->prefixes = $prefixes;
18
+ }
19
+
20
+ /**
21
+ * Whether a value should be obfuscated or not.
22
+ *
23
+ * @param string $key
24
+ *
25
+ * @return bool
26
+ */
27
+ public function should_obfuscate( $key ) {
28
+ foreach ( $this->prefixes as $prefix ) {
29
+ if ( strpos( $key, $prefix ) === 0 ) {
30
+ return true;
31
+ }
32
+ }
33
+
34
+ return false;
35
+ }
36
+
37
+ /**
38
+ * Conditionally obfuscates a string value.
39
+ *
40
+ * @param string $key
41
+ * @param mixed $string_value
42
+ *
43
+ * @return mixed Either the obfuscated string or the original value if not a string.
44
+ */
45
+ public function obfuscate( $key, $string_value ) {
46
+ if ( ! is_string( $string_value ) ) {
47
+ return $string_value;
48
+ }
49
+ if ( ! $this->should_obfuscate( $key ) ) {
50
+ return $string_value;
51
+ }
52
+
53
+ $length = strlen( $string_value );
54
+ if ( $length <= 3 ) {
55
+ return preg_replace( "/./", "#", $string_value );
56
+ } elseif ( $length > 3 && $length <= 5 ) {
57
+ return preg_replace( '/^(.{1}).*$/', '$1' . str_repeat( '#', $length - 1 ) . '$2', $string_value );
58
+ } elseif ( $length > 5 && $length <= 9 ) {
59
+ return preg_replace( '/^(.{1}).*(.{1})$/', '$1' . str_repeat( '#', $length - 2 ) . '$2', $string_value );
60
+ } elseif ( $length > 9 && $length <= 19 ) {
61
+ return preg_replace( '/^(.{2}).*(.{2})$/', '$1' . str_repeat( '#', $length - 4 ) . '$2', $string_value );
62
+ } elseif ( $length > 19 && $length <= 31 ) {
63
+ return preg_replace( '/^(.{3}).*(.{3})$/', '$1' . str_repeat( '#', $length - 6 ) . '$2', $string_value );
64
+ }
65
+
66
+ return preg_replace( '/^(.{4}).*(.{4})$/', '$1' . str_repeat( '#', $length - 8 ) . '$2', $string_value );
67
+ }
68
  }
common/src/Tribe/Support/Template_Checker.php CHANGED
@@ -1,276 +1,276 @@
1
- <?php
2
- /**
3
- * Examines a plugin's views directory and builds a list of view filenames
4
- * and their respective version numbers.
5
- */
6
- class Tribe__Support__Template_Checker {
7
- protected $plugin_name = '';
8
- protected $plugin_version = '';
9
- protected $plugin_views_dir = '';
10
- protected $theme_views_dir = '';
11
-
12
- protected $originals = array();
13
- protected $overrides = array();
14
-
15
-
16
- /**
17
- * Examine the plugin views (and optionally any theme overrides) and analyse
18
- * the version numbers where possible.
19
- *
20
- * @param string $plugin_version
21
- * @param string $plugin_views_dir
22
- * @param string $theme_views_dir
23
- */
24
- public function __construct( $plugin_version, $plugin_views_dir, $theme_views_dir = '' ) {
25
- $this->plugin_version = $this->base_version_number( $plugin_version );
26
- $this->plugin_views_dir = $plugin_views_dir;
27
- $this->theme_views_dir = $theme_views_dir;
28
-
29
- $this->scan_view_directory();
30
- $this->scan_for_overrides();
31
- }
32
-
33
- /**
34
- * Given a version number with an alpha/beta type suffix, strips that suffix and
35
- * returns the "base" version number.
36
- *
37
- * For example, given "9.8.2beta1" this method will return "9.8.2".
38
- *
39
- * The utility of this is that if the author of a template change sets the
40
- * version tag in the template header to 9.8.2 (to continue the same example) we
41
- * don't need to worry about updating that for each alpha, beta or RC we put out.
42
- *
43
- * @param string $version_number
44
- *
45
- * @return string
46
- */
47
- protected function base_version_number( $version_number ) {
48
- return preg_replace( '/[a-z]+[a-z0-9]*$/i', '', $version_number );
49
- }
50
-
51
- /**
52
- * Recursively scans the plugin's view directory and examines the template headers
53
- * of each file it finds within.
54
- */
55
- protected function scan_view_directory() {
56
- // If the provided directory is invalid flag the problem and go no further
57
- if ( $this->bad_directory( $this->plugin_views_dir ) ) {
58
- return;
59
- }
60
-
61
- $view_directory = new RecursiveDirectoryIterator( $this->plugin_views_dir );
62
- $directory_list = new RecursiveIteratorIterator( $view_directory );
63
-
64
- foreach ( $directory_list as $file ) {
65
- $this->scan_view( $file );
66
- }
67
- }
68
-
69
- /**
70
- * Scans an individual view file, adding it's version number (if found) to the
71
- * $this->views array.
72
- *
73
- * @param SplFileInfo $file
74
- */
75
- protected function scan_view( SplFileInfo $file ) {
76
- if ( ! $file->isFile() || ! $file->isReadable() ) {
77
- return;
78
- }
79
-
80
- $version = $this->get_template_version( $file->getPathname() );
81
- $this->originals[ $this->short_name( $file->getPathname() ) ] = $version;
82
- }
83
-
84
- protected function scan_for_overrides() {
85
- // If the provided directory is invalid flag the problem and go no further
86
- if ( $this->bad_directory( $this->theme_views_dir ) ) {
87
- return;
88
- }
89
-
90
- foreach ( $this->originals as $view_file => $current_version ) {
91
- $override_path = trailingslashit( $this->theme_views_dir ) . $view_file;
92
-
93
- if ( ! is_file( $override_path ) || ! is_readable( $override_path ) ) {
94
- continue;
95
- }
96
-
97
- $this->overrides[ $view_file ] = $this->get_template_version( $override_path );
98
- }
99
- }
100
-
101
- /**
102
- * Tests to ensure the provided view directory path is invalid or unreadable.
103
- *
104
- * @param string $directory
105
- * @return bool
106
- */
107
- protected function bad_directory( $directory ) {
108
- if ( is_dir( $directory ) && is_readable( $directory ) ) {
109
- return false;
110
- }
111
-
112
- return true;
113
- }
114
-
115
- /**
116
- * Inspects the template header block within the specified file and extracts the
117
- * version number, if one can be found.
118
- *
119
- * @param string $template_filepath
120
- * @return string
121
- */
122
- protected function get_template_version( $template_filepath ) {
123
- if ( ! is_file( $template_filepath ) || ! is_readable( $template_filepath ) ) {
124
- return '';
125
- }
126
-
127
- $view_content = file_get_contents( $template_filepath );
128
-
129
- if ( ! preg_match( '/^\s*\*\s*@version\s*([0-9\.]+)/mi', $view_content, $matches ) ) {
130
- return '';
131
- }
132
-
133
- return $matches[1];
134
- }
135
-
136
- /**
137
- * Given a full filepath (ie, to a view file), chops off the base path found
138
- * in $this->plugin_views_dir.
139
- *
140
- * For example, given:
141
- *
142
- * $this->plugin_views_dir = '/srv/project/wp-content/plugins/my-plugin/views'
143
- * $full_filepath = '/srv/project/wp-content/plugins/my-plugin/views/modules/icon.php'
144
- *
145
- * Returns:
146
- *
147
- * 'modules/icon.php'
148
- *
149
- * @param string $full_filepath
150
- * @return string
151
- */
152
- protected function short_name( $full_filepath ) {
153
- if ( 0 === strpos( $full_filepath, $this->plugin_views_dir ) ) {
154
- return trim( substr( $full_filepath, strlen( $this->plugin_views_dir ) ), DIRECTORY_SEPARATOR );
155
- }
156
-
157
- return $full_filepath;
158
- }
159
-
160
- /**
161
- * Returns an array of the plugin's shipped view files, where each key is the
162
- * view filename and the value is the version it was last updated.
163
- *
164
- * @return array
165
- */
166
- public function get_views() {
167
- return $this->originals;
168
- }
169
-
170
- /**
171
- * Returns an array of any or all of the plugin's shipped view files that contain
172
- * a version field in their header blocks.
173
- *
174
- * @see $this->get_views() for format of returned array
175
- *
176
- * @return array
177
- */
178
- public function get_versioned_views() {
179
- $versioned_views = array();
180
-
181
- foreach ( $this->originals as $key => $version ) {
182
- if ( ! empty( $version ) ) {
183
- $versioned_views[ $key ] = $version;
184
- }
185
- }
186
-
187
- return $versioned_views;
188
- }
189
-
190
- /**
191
- * Returns an array of any shipped plugin views that were updated or introduced
192
- * with the current release (as specified by $this->plugin_version).
193
- *
194
- * @see $this->get_views() for format of returned array
195
- *
196
- * @return array
197
- */
198
- public function get_views_tagged_this_release() {
199
- $currently_tagged_views = array();
200
-
201
- foreach ( $this->get_versioned_views() as $key => $version ) {
202
- if ( $version === $this->plugin_version ) {
203
- $currently_tagged_views[ $key ] = $version;
204
- }
205
- }
206
-
207
- return $currently_tagged_views;
208
- }
209
-
210
- /**
211
- * Returns an array of theme overrides, where each key is the view filename and the
212
- * value is the version it was last updated (may be empty).
213
- *
214
- * @return array
215
- */
216
- public function get_overrides() {
217
- return $this->overrides;
218
- }
219
-
220
- /**
221
- * Returns an array of any or all theme overrides that contain a version field in their
222
- * header blocks.
223
- *
224
- * @see $this->get_overrides() for format of returned array
225
- *
226
- * @return array
227
- */
228
- public function get_versioned_overrides() {
229
- $versioned_views = array();
230
-
231
- foreach ( $this->overrides as $key => $version ) {
232
- if ( ! empty( $version ) ) {
233
- $versioned_views[ $key ] = $version;
234
- }
235
- }
236
-
237
- return $versioned_views;
238
- }
239
-
240
- /**
241
- * Returns an array of any or all theme overrides that seem to be based on an earlier
242
- * version than that which currently ships with the plugin.
243
- *
244
- * If optional param $include_unknown is set to true, the list will include theme
245
- * overrides where the version could not be determined (for instance, this might result
246
- * in theme overrides where the template header - or version tag - was removed being
247
- * included).
248
- *
249
- * @see $this->get_overrides() for format of returned array
250
- *
251
- * @param bool $include_unknown = false
252
- * @return array
253
- */
254
- public function get_outdated_overrides( $include_unknown = false ) {
255
- $outdated = array();
256
- $originals = $this->get_versioned_views();
257
-
258
- $overrides = $include_unknown
259
- ? $this->get_overrides()
260
- : $this->get_versioned_overrides();
261
-
262
- foreach ( $overrides as $view => $override_version ) {
263
- if ( empty( $originals[ $view ] ) ) {
264
- continue;
265
- }
266
-
267
- $shipped_version = $originals[ $view ];
268
-
269
- if ( version_compare( $shipped_version, $override_version, '>' ) ) {
270
- $outdated[ $view ] = $override_version;
271
- }
272
- }
273
-
274
- return $outdated;
275
- }
276
  }
1
+ <?php
2
+ /**
3
+ * Examines a plugin's views directory and builds a list of view filenames
4
+ * and their respective version numbers.
5
+ */
6
+ class Tribe__Support__Template_Checker {
7
+ protected $plugin_name = '';
8
+ protected $plugin_version = '';
9
+ protected $plugin_views_dir = '';
10
+ protected $theme_views_dir = '';
11
+
12
+ protected $originals = array();
13
+ protected $overrides = array();
14
+
15
+
16
+ /**
17
+ * Examine the plugin views (and optionally any theme overrides) and analyse
18
+ * the version numbers where possible.
19
+ *
20
+ * @param string $plugin_version
21
+ * @param string $plugin_views_dir
22
+ * @param string $theme_views_dir
23
+ */
24
+ public function __construct( $plugin_version, $plugin_views_dir, $theme_views_dir = '' ) {
25
+ $this->plugin_version = $this->base_version_number( $plugin_version );
26
+ $this->plugin_views_dir = $plugin_views_dir;
27
+ $this->theme_views_dir = $theme_views_dir;
28
+
29
+ $this->scan_view_directory();
30
+ $this->scan_for_overrides();
31
+ }
32
+
33
+ /**
34
+ * Given a version number with an alpha/beta type suffix, strips that suffix and
35
+ * returns the "base" version number.
36
+ *
37
+ * For example, given "9.8.2beta1" this method will return "9.8.2".
38
+ *
39
+ * The utility of this is that if the author of a template change sets the
40
+ * version tag in the template header to 9.8.2 (to continue the same example) we
41
+ * don't need to worry about updating that for each alpha, beta or RC we put out.
42
+ *
43
+ * @param string $version_number
44
+ *
45
+ * @return string
46
+ */
47
+ protected function base_version_number( $version_number ) {
48
+ return preg_replace( '/[a-z]+[a-z0-9]*$/i', '', $version_number );
49
+ }
50
+
51
+ /**
52
+ * Recursively scans the plugin's view directory and examines the template headers
53
+ * of each file it finds within.
54
+ */
55
+ protected function scan_view_directory() {
56
+ // If the provided directory is invalid flag the problem and go no further
57
+ if ( $this->bad_directory( $this->plugin_views_dir ) ) {
58
+ return;
59
+ }
60
+
61
+ $view_directory = new RecursiveDirectoryIterator( $this->plugin_views_dir );
62
+ $directory_list = new RecursiveIteratorIterator( $view_directory );
63
+
64
+ foreach ( $directory_list as $file ) {
65
+ $this->scan_view( $file );
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Scans an individual view file, adding it's version number (if found) to the
71
+ * $this->views array.
72
+ *
73
+ * @param SplFileInfo $file
74
+ */
75
+ protected function scan_view( SplFileInfo $file ) {
76
+ if ( ! $file->isFile() || ! $file->isReadable() ) {
77
+ return;
78
+ }
79
+
80
+ $version = $this->get_template_version( $file->getPathname() );
81
+ $this->originals[ $this->short_name( $file->getPathname() ) ] = $version;
82
+ }
83
+
84
+ protected function scan_for_overrides() {
85
+ // If the provided directory is invalid flag the problem and go no further
86
+ if ( $this->bad_directory( $this->theme_views_dir ) ) {
87
+ return;
88
+ }
89
+
90
+ foreach ( $this->originals as $view_file => $current_version ) {
91
+ $override_path = trailingslashit( $this->theme_views_dir ) . $view_file;
92
+
93
+ if ( ! is_file( $override_path ) || ! is_readable( $override_path ) ) {
94
+ continue;
95
+ }
96
+
97
+ $this->overrides[ $view_file ] = $this->get_template_version( $override_path );
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Tests to ensure the provided view directory path is invalid or unreadable.
103
+ *
104
+ * @param string $directory
105
+ * @return bool
106
+ */
107
+ protected function bad_directory( $directory ) {
108
+ if ( is_dir( $directory ) && is_readable( $directory ) ) {
109
+ return false;
110
+ }
111
+
112
+ return true;
113
+ }
114
+
115
+ /**
116
+ * Inspects the template header block within the specified file and extracts the
117
+ * version number, if one can be found.
118
+ *
119
+ * @param string $template_filepath
120
+ * @return string
121
+ */
122
+ protected function get_template_version( $template_filepath ) {
123
+ if ( ! is_file( $template_filepath ) || ! is_readable( $template_filepath ) ) {
124
+ return '';
125
+ }
126
+
127
+ $view_content = file_get_contents( $template_filepath );
128
+
129
+ if ( ! preg_match( '/^\s*\*\s*@version\s*([0-9\.]+)/mi', $view_content, $matches ) ) {
130
+ return '';
131
+ }
132
+
133
+ return $matches[1];
134
+ }
135
+
136
+ /**
137
+ * Given a full filepath (ie, to a view file), chops off the base path found
138
+ * in $this->plugin_views_dir.
139
+ *
140
+ * For example, given:
141
+ *
142
+ * $this->plugin_views_dir = '/srv/project/wp-content/plugins/my-plugin/views'
143
+ * $full_filepath = '/srv/project/wp-content/plugins/my-plugin/views/modules/icon.php'
144
+ *
145
+ * Returns:
146
+ *
147
+ * 'modules/icon.php'
148
+ *
149
+ * @param string $full_filepath
150
+ * @return string
151
+ */
152
+ protected function short_name( $full_filepath ) {
153
+ if ( 0 === strpos( $full_filepath, $this->plugin_views_dir ) ) {
154
+ return trim( substr( $full_filepath, strlen( $this->plugin_views_dir ) ), DIRECTORY_SEPARATOR );
155
+ }
156
+
157
+ return $full_filepath;
158
+ }
159
+
160
+ /**
161
+ * Returns an array of the plugin's shipped view files, where each key is the
162
+ * view filename and the value is the version it was last updated.
163
+ *
164
+ * @return array
165
+ */
166
+ public function get_views() {
167
+ return $this->originals;
168
+ }
169
+
170
+ /**
171
+ * Returns an array of any or all of the plugin's shipped view files that contain
172
+ * a version field in their header blocks.
173
+ *
174
+ * @see $this->get_views() for format of returned array
175
+ *
176
+ * @return array
177
+ */
178
+ public function get_versioned_views() {
179
+ $versioned_views = array();
180
+
181
+ foreach ( $this->originals as $key => $version ) {
182
+ if ( ! empty( $version ) ) {
183
+ $versioned_views[ $key ] = $version;
184
+ }
185
+ }
186
+
187
+ return $versioned_views;
188
+ }
189
+
190
+ /**
191
+ * Returns an array of any shipped plugin views that were updated or introduced
192
+ * with the current release (as specified by $this->plugin_version).
193
+ *
194
+ * @see $this->get_views() for format of returned array
195
+ *
196
+ * @return array
197
+ */
198
+ public function get_views_tagged_this_release() {
199
+ $currently_tagged_views = array();
200
+
201
+ foreach ( $this->get_versioned_views() as $key => $version ) {
202
+ if ( $version === $this->plugin_version ) {
203
+ $currently_tagged_views[ $key ] = $version;
204
+ }
205
+ }
206
+
207
+ return $currently_tagged_views;
208
+ }
209
+
210
+ /**
211
+ * Returns an array of theme overrides, where each key is the view filename and the
212
+ * value is the version it was last updated (may be empty).
213
+ *
214
+ * @return array
215
+ */
216
+ public function get_overrides() {
217
+ return $this->overrides;
218
+ }
219
+
220
+ /**
221
+ * Returns an array of any or all theme overrides that contain a version field in their
222
+ * header blocks.
223
+ *
224
+ * @see $this->get_overrides() for format of returned array
225
+ *
226
+ * @return array
227
+ */
228
+ public function get_versioned_overrides() {
229
+ $versioned_views = array();
230
+
231
+ foreach ( $this->overrides as $key => $version ) {
232
+ if ( ! empty( $version ) ) {
233
+ $versioned_views[ $key ] = $version;
234
+ }
235
+ }
236
+
237
+ return $versioned_views;
238
+ }
239
+
240
+ /**
241
+ * Returns an array of any or all theme overrides that seem to be based on an earlier
242
+ * version than that which currently ships with the plugin.
243
+ *
244
+ * If optional param $include_unknown is set to true, the list will include theme
245
+ * overrides where the version could not be determined (for instance, this might result
246
+ * in theme overrides where the template header - or version tag - was removed being
247
+ * included).
248
+ *
249
+ * @see $this->get_overrides() for format of returned array
250
+ *
251
+ * @param bool $include_unknown = false
252
+ * @return array
253
+ */
254
+ public function get_outdated_overrides( $include_unknown = false ) {
255
+ $outdated = array();
256
+ $originals = $this->get_versioned_views();
257
+
258
+ $overrides = $include_unknown
259
+ ? $this->get_overrides()
260
+ : $this->get_versioned_overrides();
261
+
262
+ foreach ( $overrides as $view => $override_version ) {
263
+ if ( empty( $originals[ $view ] ) ) {
264
+ continue;
265
+ }
266
+
267
+ $shipped_version = $originals[ $view ];
268
+
269
+ if ( version_compare( $shipped_version, $override_version, '>' ) ) {
270
+ $outdated[ $view ] = $override_version;
271
+ }
272
+ }
273
+
274
+ return $outdated;
275
+ }
276
  }
common/src/Tribe/Support/Template_Checker_Report.php CHANGED
@@ -1,119 +1,119 @@
1
- <?php
2
- /**
3
- * Assembles a report of recently updated plugin views and template overrides in
4
- * possible revision, for each plugin that registers itself and its template
5
- * filepaths.
6
- */
7
- class Tribe__Support__Template_Checker_Report {
8
- const VERSION_INDEX = 0;
9
- const INCLUDED_VIEWS_INDEX = 1;
10
- const THEME_OVERRIDES_INDEX = 2;
11
-
12
- /**
13
- * Contains the individual view/template reports for each registered plugin.
14
- *
15
- * @var array
16
- */
17
- protected static $plugin_reports = array();
18
-
19
- /**
20
- * Container for finished report.
21
- *
22
- * @var string
23
- */
24
- protected static $complete_report = '';
25
-
26
- /**
27
- * Provides an up-to-date report concerning template changes.
28
- *
29
- * @return string
30
- */
31
- public static function generate() {
32
- foreach ( self::registered_plugins() as $plugin_name => $plugin_template_system ) {
33
- self::generate_for( $plugin_name, $plugin_template_system );
34
- }
35
-
36
- self::wrap_report();
37
- return self::$complete_report;
38
- }
39
-
40
- protected static function registered_plugins() {
41
- /**
42
- * Provides a mechanism for plugins to register information about their template/view
43
- * setups.
44
- *
45
- * This should be done by adding an entry to $registere_template_systems where the key
46
- * should be the plugin name and the element an array structured as follows:
47
- *
48
- * [
49
- * plugin_version,
50
- * path_to_included_views,
51
- * path_to_theme_overrides
52
- * ]
53
- *
54
- * @var array $registered_template_systems
55
- */
56
- return apply_filters( 'tribe_support_registered_template_systems', array() );
57
- }
58
-
59
- /**
60
- * Creates a report for the specified plugin.
61
- *
62
- * @param string $plugin_name
63
- * @param array $template_system
64
- */
65
- protected static function generate_for( $plugin_name, array $template_system ) {
66
- $report = '<dt>' . esc_html( $plugin_name ) . '</dt>';
67
-
68
- $scanner = new Tribe__Support__Template_Checker(
69
- $template_system[ self::VERSION_INDEX ],
70
- $template_system[ self::INCLUDED_VIEWS_INDEX ],
71
- $template_system[ self::THEME_OVERRIDES_INDEX ]
72
- );
73
-
74
- $newly_introduced_or_updated = $scanner->get_views_tagged_this_release();
75
- $outdated_or_unknown = $scanner->get_outdated_overrides( true );
76
-
77
- if ( empty( $newly_introduced_or_updated ) && empty( $outdated_or_unknown ) ) {
78
- $report .= '<dd>' . __( 'No notable changes detected', 'tribe-common' ) . '</dd>';
79
- }
80
-
81
- if ( ! empty( $newly_introduced_or_updated ) ) {
82
- $report .= '<dd><p>' . sprintf( __( 'Templates introduced or updated with this release (%s):', 'tribe-common' ), $template_system[ self::VERSION_INDEX ] ) . '</p><ul>';
83
-
84
- foreach ( $newly_introduced_or_updated as $view_name => $version ) {
85
- $report .= '<li>' . esc_html( $view_name ) . '</li>';
86
- }
87
-
88
- $report .= '</ul></dd>';
89
- }
90
-
91
- if ( ! empty( $outdated_or_unknown ) ) {
92
- $report .= '<dd><p>' . __( 'Existing theme overrides that may need revision:', 'tribe-common' ) . '</p><ul>';
93
-
94
- foreach ( $outdated_or_unknown as $view_name => $version ) {
95
- $version_note = empty( $version )
96
- ? __( 'version data missing from override', 'tribe-common' )
97
- : sprintf( __( 'based on %s version', 'tribe-common' ), $version );
98
-
99
- $report .= '<li>' . esc_html( $view_name ) . ' (' . $version_note . ') </li>';
100
- }
101
-
102
- $report .= '</ul></dd>';
103
- }
104
-
105
- self::$plugin_reports[ $plugin_name ] = $report;
106
- }
107
-
108
- /**
109
- * Wraps the individual plugin template reports ready for display.
110
- */
111
- protected static function wrap_report() {
112
- if ( empty( self::$plugin_reports ) ) {
113
- self::$complete_report = '<p>' . __( 'No notable template changes detected.', 'tribe-common' ) . '</p>';
114
- } else {
115
- self::$complete_report = '<p>' . __( 'Information about recent template changes and potentially impacted template overrides is provided below.', 'tribe-common' ) . '</p>'
116
- . '<div class="template-updates-wrapper">' . join( ' ', self::$plugin_reports ) . '</div>';
117
- }
118
- }
119
  }
1
+ <?php
2
+ /**
3
+ * Assembles a report of recently updated plugin views and template overrides in
4
+ * possible revision, for each plugin that registers itself and its template
5
+ * filepaths.
6
+ */
7
+ class Tribe__Support__Template_Checker_Report {
8
+ const VERSION_INDEX = 0;
9
+ const INCLUDED_VIEWS_INDEX = 1;
10
+ const THEME_OVERRIDES_INDEX = 2;
11
+
12
+ /**
13
+ * Contains the individual view/template reports for each registered plugin.
14
+ *
15
+ * @var array
16
+ */
17
+ protected static $plugin_reports = array();
18
+
19
+ /**
20
+ * Container for finished report.
21
+ *
22
+ * @var string
23
+ */
24
+ protected static $complete_report = '';
25
+
26
+ /**
27
+ * Provides an up-to-date report concerning template changes.
28
+ *
29
+ * @return string
30
+ */
31
+ public static function generate() {
32
+ foreach ( self::registered_plugins() as $plugin_name => $plugin_template_system ) {
33
+ self::generate_for( $plugin_name, $plugin_template_system );
34
+ }
35
+
36
+ self::wrap_report();
37
+ return self::$complete_report;
38
+ }
39
+
40
+ protected static function registered_plugins() {
41
+ /**
42
+ * Provides a mechanism for plugins to register information about their template/view
43
+ * setups.
44
+ *
45
+ * This should be done by adding an entry to $registere_template_systems where the key
46
+ * should be the plugin name and the element an array structured as follows:
47
+ *
48
+ * [
49
+ * plugin_version,
50
+ * path_to_included_views,
51
+ * path_to_theme_overrides
52
+ * ]
53
+ *
54
+ * @var array $registered_template_systems
55
+ */
56
+ return apply_filters( 'tribe_support_registered_template_systems', array() );
57
+ }
58
+
59
+ /**
60
+ * Creates a report for the specified plugin.
61
+ *
62
+ * @param string $plugin_name
63
+ * @param array $template_system
64
+ */
65
+ protected static function generate_for( $plugin_name, array $template_system ) {
66
+ $report = '<dt>' . esc_html( $plugin_name ) . '</dt>';
67
+
68
+ $scanner = new Tribe__Support__Template_Checker(
69
+ $template_system[ self::VERSION_INDEX ],
70
+ $template_system[ self::INCLUDED_VIEWS_INDEX ],
71
+ $template_system[ self::THEME_OVERRIDES_INDEX ]
72
+ );
73
+
74
+ $newly_introduced_or_updated = $scanner->get_views_tagged_this_release();
75
+ $outdated_or_unknown = $scanner->get_outdated_overrides( true );
76
+
77
+ if ( empty( $newly_introduced_or_updated ) && empty( $outdated_or_unknown ) ) {
78
+ $report .= '<dd>' . __( 'No notable changes detected', 'tribe-common' ) . '</dd>';
79
+ }
80
+
81
+ if ( ! empty( $newly_introduced_or_updated ) ) {
82
+ $report .= '<dd><p>' . sprintf( __( 'Templates introduced or updated with this release (%s):', 'tribe-common' ), $template_system[ self::VERSION_INDEX ] ) . '</p><ul>';
83
+
84
+ foreach ( $newly_introduced_or_updated as $view_name => $version ) {
85
+ $report .= '<li>' . esc_html( $view_name ) . '</li>';
86
+ }
87
+
88
+ $report .= '</ul></dd>';
89
+ }
90
+
91
+ if ( ! empty( $outdated_or_unknown ) ) {
92
+ $report .= '<dd><p>' . __( 'Existing theme overrides that may need revision:', 'tribe-common' ) . '</p><ul>';
93
+
94
+ foreach ( $outdated_or_unknown as $view_name => $version ) {
95
+ $version_note = empty( $version )
96
+ ? __( 'version data missing from override', 'tribe-common' )
97
+ : sprintf( __( 'based on %s version', 'tribe-common' ), $version );
98
+
99
+ $report .= '<li>' . esc_html( $view_name ) . ' (' . $version_note . ') </li>';
100
+ }
101
+
102
+ $report .= '</ul></dd>';
103
+ }
104
+
105
+ self::$plugin_reports[ $plugin_name ] = $report;
106
+ }
107
+
108
+ /**
109
+ * Wraps the individual plugin template reports ready for display.
110
+ */
111
+ protected static function wrap_report() {
112
+ if ( empty( self::$plugin_reports ) ) {
113
+ self::$complete_report = '<p>' . __( 'No notable template changes detected.', 'tribe-common' ) . '</p>';
114
+ } else {
115
+ self::$complete_report = '<p>' . __( 'Information about recent template changes and potentially impacted template overrides is provided below.', 'tribe-common' ) . '</p>'
116
+ . '<div class="template-updates-wrapper">' . join( ' ', self::$plugin_reports ) . '</div>';
117
+ }
118
+ }
119
  }
common/src/Tribe/Template_Factory.php CHANGED
@@ -1,188 +1,188 @@
1
- <?php
2
- /**
3
- * Template Factory
4
- *
5
- * The parent class for managing the view methods in core and addons
6
- *
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) {
10
- die( '-1' );
11
- }
12
-
13
- if ( class_exists( 'Tribe__Template_Factory' ) ) {
14
- return;
15
- }
16
-
17
- class Tribe__Template_Factory {
18
-
19
- /**
20
- * Array of asset packages needed for this template
21
- *
22
- * @var array
23
- **/
24
- protected $asset_packages = array();
25
-
26
- /**
27
- * Static variable that holds array of vendor script handles, for adding to later deps.
28
- *
29
- * @static
30
- * @var array
31
- */
32
- protected static $vendor_scripts = array();
33
-
34
- /**
35
- * Constant that holds the ajax hook suffix for the view
36
- *
37
- * @static
38
- * @var string
39
- */
40
- const AJAX_HOOK = '';
41
-
42
- /**
43
- * Run include packages, set up hooks
44
- *
45
- * @return void
46
- **/
47
- public function __construct() {
48
- $this->asset_packages();
49
- }
50
-
51
- /**
52
- * Manage the asset packages defined for this template
53
- *
54
- * @return void
55
- **/
56
- protected function asset_packages() {
57
- foreach ( $this->asset_packages as $asset_package ) {
58
- $this->asset_package( $asset_package );
59
- }
60
- }
61
-
62
- /**
63
- * Handles an asset package request.
64
- *
65
- * @param string $name The asset name in the `hyphen-separated-format`
66
- * @param array $deps An array of dependency handles
67
- * @param string $vendor_url URL to vendor scripts and styles dir
68
- * @param string $prefix MT script and style prefix
69
- * @param Tribe__Main $tec An instance of the main plugin class
70
- */
71
- protected static function handle_asset_package_request( $name, $deps, $vendor_url, $prefix, $tec ) {
72
-
73
- $asset = self::get_asset_factory_instance( $name );
74
-
75
- self::prepare_asset_package_request( $asset, $name, $deps, $vendor_url, $prefix, $tec );
76
- }
77
-
78
- /**
79
- * initializes asset package request
80
- *
81
- * @param object $asset The Tribe__*Asset object
82
- * @param string $name The asset name in the `hyphen-separated-format`
83
- * @param array $deps An array of dependency handles
84
- * @param string $vendor_url URL to vendor scripts and styles dir
85
- * @param string $prefix MT script and style prefix
86
- * @param Tribe__Main $common An instance of the main plugin class
87
- */
88
- protected static function prepare_asset_package_request( $asset, $name, $deps, $vendor_url, $prefix, $common ) {
89
- if ( ! $asset ) {
90
- do_action( $prefix . '-' . $name );
91
-
92
- return;
93
- }
94
-
95
- $asset->set_name( $name );
96
- $asset->set_deps( $deps );
97
- $asset->set_vendor_url( $vendor_url );
98
- $asset->set_prefix( $prefix );
99
- $asset->set_tec( $common );
100
-
101
- $asset->handle();
102
- }
103
-
104
- /**
105
- * Retrieves the appropriate asset factory instance
106
- */
107
- protected static function get_asset_factory_instance( $name ) {
108
- $asset = Tribe__Asset__Factory::instance()->make_for_name( $name );
109
- return $asset;
110
- }
111
-
112
- /**
113
- * @param string $script_handle A registered script handle.
114
- */
115
- public static function add_vendor_script( $script_handle ) {
116
- if ( in_array( $script_handle, self::$vendor_scripts ) ) {
117
- return;
118
- }
119
- self::$vendor_scripts[] = $script_handle;
120
- }
121
-
122
- /**
123
- * @return string[] An array of registered vendor script handles.
124
- */
125
- public static function get_vendor_scripts() {
126
- return self::$vendor_scripts;
127
- }
128
-
129
- /**
130
- * Asset calls for vendor packages
131
- *
132
- * @param string $name
133
- * @param array $deps Dependents
134
- */
135
- public static function asset_package( $name, $deps = array() ) {
136
-
137
- $common = Tribe__Main::instance();
138
- $prefix = 'tribe-events';
139
-
140
- // setup plugin resources & 3rd party vendor urls
141
- $vendor_url = trailingslashit( $common->plugin_url ) . 'vendor/';
142
-
143
- self::handle_asset_package_request( $name, $deps, $vendor_url, $prefix, $common );
144
- }
145
-
146
- /**
147
- * Returns the path to a minified version of a js or css file, if it exists.
148
- * If the file does not exist, returns false.
149
- *
150
- * @param string $url The path or URL to the un-minified file.
151
- * @param bool $default_to_original Whether to just return original path if min version not found.
152
- *
153
- * @return string|false The path/url to minified version or false, if file not found.
154
- */
155
- public static function getMinFile( $url, $default_to_original = false ) {
156
- if ( ! defined( 'SCRIPT_DEBUG' ) || SCRIPT_DEBUG === false ) {
157
- if ( substr( $url, - 3, 3 ) == '.js' ) {
158
- $url_new = substr_replace( $url, '.min', - 3, 0 );
159
- }
160
- if ( substr( $url, - 4, 4 ) == '.css' ) {
161
- $url_new = substr_replace( $url, '.min', - 4, 0 );
162
- }
163
- }
164
-
165
- if ( isset( $url_new ) && file_exists( str_replace( WP_CONTENT_URL, WP_CONTENT_DIR, $url_new ) ) ) {
166
- return $url_new;
167
- } elseif ( $default_to_original ) {
168
- return $url;
169
- } else {
170
- return false;
171
- }
172
- }
173
-
174
- /**
175
- * Playing ping-pong with WooCommerce. They keep changing their script.
176
- * See https://github.com/woothemes/woocommerce/issues/3623
177
- */
178
- public static function get_placeholder_handle() {
179
- $placeholder_handle = 'jquery-placeholder';
180
- global $woocommerce;
181
- if ( class_exists( 'Woocommerce' ) && version_compare( $woocommerce->version, '2.0.11', '>=' ) && version_compare( $woocommerce->version, '2.0.13', '<=' )
182
- ) {
183
- $placeholder_handle = 'tribe-placeholder';
184
- }
185
-
186
- return $placeholder_handle;
187
- }
188
- }
1
+ <?php
2
+ /**
3
+ * Template Factory
4
+ *
5
+ * The parent class for managing the view methods in core and addons
6
+ *
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ die( '-1' );
11
+ }
12
+
13
+ if ( class_exists( 'Tribe__Template_Factory' ) ) {
14
+ return;
15
+ }
16
+
17
+ class Tribe__Template_Factory {
18
+
19
+ /**
20
+ * Array of asset packages needed for this template
21
+ *
22
+ * @var array
23
+ **/
24
+ protected $asset_packages = array();
25
+
26
+ /**
27
+ * Static variable that holds array of vendor script handles, for adding to later deps.
28
+ *
29
+ * @static
30
+ * @var array
31
+ */
32
+ protected static $vendor_scripts = array();
33
+
34
+ /**
35
+ * Constant that holds the ajax hook suffix for the view
36
+ *
37
+ * @static
38
+ * @var string
39
+ */
40
+ const AJAX_HOOK = '';
41
+
42
+ /**
43
+ * Run include packages, set up hooks
44
+ *
45
+ * @return void
46
+ **/
47
+ public function __construct() {
48
+ $this->asset_packages();
49
+ }
50
+
51
+ /**
52
+ * Manage the asset packages defined for this template
53
+ *
54
+ * @return void
55
+ **/
56
+ protected function asset_packages() {
57
+ foreach ( $this->asset_packages as $asset_package ) {
58
+ $this->asset_package( $asset_package );
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Handles an asset package request.
64
+ *
65
+ * @param string $name The asset name in the `hyphen-separated-format`
66
+ * @param array $deps An array of dependency handles
67
+ * @param string $vendor_url URL to vendor scripts and styles dir
68
+ * @param string $prefix MT script and style prefix
69
+ * @param Tribe__Main $tec An instance of the main plugin class
70
+ */
71
+ protected static function handle_asset_package_request( $name, $deps, $vendor_url, $prefix, $tec ) {
72
+
73
+ $asset = self::get_asset_factory_instance( $name );
74
+
75
+ self::prepare_asset_package_request( $asset, $name, $deps, $vendor_url, $prefix, $tec );
76
+ }
77
+
78
+ /**
79
+ * initializes asset package request
80
+ *
81
+ * @param object $asset The Tribe__*Asset object
82
+ * @param string $name The asset name in the `hyphen-separated-format`
83
+ * @param array $deps An array of dependency handles
84
+ * @param string $vendor_url URL to vendor scripts and styles dir
85
+ * @param string $prefix MT script and style prefix
86
+ * @param Tribe__Main $common An instance of the main plugin class
87
+ */
88
+ protected static function prepare_asset_package_request( $asset, $name, $deps, $vendor_url, $prefix, $common ) {
89
+ if ( ! $asset ) {
90
+ do_action( $prefix . '-' . $name );
91
+
92
+ return;
93
+ }
94
+
95
+ $asset->set_name( $name );
96
+ $asset->set_deps( $deps );
97
+ $asset->set_vendor_url( $vendor_url );
98
+ $asset->set_prefix( $prefix );
99
+ $asset->set_tec( $common );
100
+
101
+ $asset->handle();
102
+ }
103
+
104
+ /**
105
+ * Retrieves the appropriate asset factory instance
106
+ */
107
+ protected static function get_asset_factory_instance( $name ) {
108
+ $asset = Tribe__Asset__Factory::instance()->make_for_name( $name );
109
+ return $asset;
110
+ }
111
+
112
+ /**
113
+ * @param string $script_handle A registered script handle.
114
+ */
115
+ public static function add_vendor_script( $script_handle ) {
116
+ if ( in_array( $script_handle, self::$vendor_scripts ) ) {
117
+ return;
118
+ }
119
+ self::$vendor_scripts[] = $script_handle;
120
+ }
121
+
122
+ /**
123
+ * @return string[] An array of registered vendor script handles.
124
+ */
125
+ public static function get_vendor_scripts() {
126
+ return self::$vendor_scripts;
127
+ }
128
+
129
+ /**
130
+ * Asset calls for vendor packages
131
+ *
132
+ * @param string $name
133
+ * @param array $deps Dependents
134
+ */
135
+ public static function asset_package( $name, $deps = array() ) {
136
+
137
+ $common = Tribe__Main::instance();
138
+ $prefix = 'tribe-events';
139
+
140
+ // setup plugin resources & 3rd party vendor urls
141
+ $vendor_url = trailingslashit( $common->plugin_url ) . 'vendor/';
142
+
143
+ self::handle_asset_package_request( $name, $deps, $vendor_url, $prefix, $common );
144
+ }
145
+
146
+ /**
147
+ * Returns the path to a minified version of a js or css file, if it exists.
148
+ * If the file does not exist, returns false.
149
+ *
150
+ * @param string $url The path or URL to the un-minified file.
151
+ * @param bool $default_to_original Whether to just return original path if min version not found.
152
+ *
153
+ * @return string|false The path/url to minified version or false, if file not found.
154
+ */
155
+ public static function getMinFile( $url, $default_to_original = false ) {
156
+ if ( ! defined( 'SCRIPT_DEBUG' ) || SCRIPT_DEBUG === false ) {
157
+ if ( substr( $url, - 3, 3 ) == '.js' ) {
158
+ $url_new = substr_replace( $url, '.min', - 3, 0 );
159
+ }
160
+ if ( substr( $url, - 4, 4 ) == '.css' ) {
161
+ $url_new = substr_replace( $url, '.min', - 4, 0 );
162
+ }
163
+ }
164
+
165
+ if ( isset( $url_new ) && file_exists( str_replace( WP_CONTENT_URL, WP_CONTENT_DIR, $url_new ) ) ) {
166
+ return $url_new;
167
+ } elseif ( $default_to_original ) {
168
+ return $url;
169
+ } else {
170
+ return false;
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Playing ping-pong with WooCommerce. They keep changing their script.
176
+ * See https://github.com/woothemes/woocommerce/issues/3623
177
+ */
178
+ public static function get_placeholder_handle() {
179
+ $placeholder_handle = 'jquery-placeholder';
180
+ global $woocommerce;
181
+ if ( class_exists( 'Woocommerce' ) && version_compare( $woocommerce->version, '2.0.11', '>=' ) && version_compare( $woocommerce->version, '2.0.13', '<=' )
182
+ ) {
183
+ $placeholder_handle = 'tribe-placeholder';
184
+ }
185
+
186
+ return $placeholder_handle;
187
+ }
188
+ }
common/src/Tribe/Template_Part_Cache.php CHANGED
@@ -1,123 +1,123 @@
1
- <?php
2
-
3
- /**
4
- * Class Tribe__Template_Part_Cache
5
- *
6
- * @uses TribeEventsCache
7
- */
8
- class Tribe__Template_Part_Cache {
9
-
10
- /**
11
- * @var string
12
- */
13
- private $template;
14
-
15
- /**
16
- * @var int
17
- */
18
- private $expiration;
19
-
20
- /**
21
- * @var string
22
- */
23
- private $expiration_trigger;
24
-
25
- /**
26
- * @var TribeEventsCache
27
- */
28
- private $cache;
29
-
30
- /**
31
- * @var string
32
- */
33
- private $html;
34
-
35
- /**
36
- ** Short description
37
- *
38
- * @param $template - which template in the views directory is being cached (relative path).
39
- * @param $id - a unique identifier for this fragment.
40
- * @param $expiration - expiration time for the cached fragment.
41
- * @param $expiration_trigger - wordpress hook to expire on.
42
- */
43
- public function __construct( $template, $id, $expiration, $expiration_trigger ) {
44
- $this->template = $template;
45
- $this->key = $template . '_' . $id;
46
- $this->expiration = $expiration;
47
- $this->expiration_trigger = $expiration_trigger;
48
- $this->cache = new Tribe__Cache();
49
-
50
- $this->add_hooks();
51
- }
52
-
53
- /**
54
- * Hook in to show cached content and bypass queries where needed
55
- */
56
- public function add_hooks() {
57
-
58
- // set the cached html in transients after the template part is included
59
- add_filter( 'tribe_get_template_part_content', array( $this, 'set' ), 10, 2 );
60
-
61
- // get the cached html right before the setup_view runs so it's available for bypassing any view logic
62
- add_action( 'tribe_events_before_view', array( $this, 'get' ), 9, 1 );
63
-
64
- // when the specified template part is included, show the cached html instead
65
- add_filter( 'tribe_get_template_part_path_' . $this->template, array( $this, 'display' ) );
66
- }
67
-
68
- /**
69
- * Checks if there is a cached html fragment in the transients, if it's there,
70
- * don't include the requested file path. If not, just return the file path like normal
71
- *
72
- * @param $path file path to the month view template part
73
- *
74
- * @return bool
75
- * @uses tribe_get_template_part_path_[template] hook
76
- */
77
- public function display( $path ) {
78
-
79
- if ( $this->html !== false ) {
80
- echo $this->html;
81
-
82
- return false;
83
- }
84
-
85
- return $path;
86
-
87
- }
88
-
89
- /**
90
- * Set cached html in transients
91
- *
92
- * @param $html
93
- * @param $template
94
- *
95
- * @return string
96
- * @uses tribe_get_template_part_content hook
97
- */
98
- public function set( $html, $template ) {
99
- if ( $template == $this->template ) {
100
- $this->cache->set_transient( $this->key, $html, $this->expiration, $this->expiration_trigger );
101
- }
102
-
103
- return $html;
104
- }
105
-
106
- /**
107
- * Retrieve the cached html from transients, set class property
108
- *
109
- * @uses tribe_events_before_view hook
110
- */
111
- public function get() {
112
-
113
- if ( isset( $this->html ) ) {
114
-
115
- return $this->html;
116
- }
117
-
118
- $this->html = $this->cache->get_transient( $this->key, $this->expiration_trigger );
119
-
120
- return $this->html;
121
-
122
- }
123
- }
1
+ <?php
2
+
3
+ /**
4
+ * Class Tribe__Template_Part_Cache
5
+ *
6
+ * @uses TribeEventsCache
7
+ */
8
+ class Tribe__Template_Part_Cache {
9
+
10
+ /**
11
+ * @var string
12
+ */
13
+ private $template;
14
+
15
+ /**
16
+ * @var int
17
+ */
18
+ private $expiration;
19
+
20
+ /**
21
+ * @var string
22
+ */
23
+ private $expiration_trigger;
24
+
25
+ /**
26
+ * @var TribeEventsCache
27
+ */
28
+ private $cache;
29
+
30
+ /**
31
+ * @var string
32
+ */
33
+ private $html;
34
+
35
+ /**
36
+ ** Short description
37
+ *
38
+ * @param $template - which template in the views directory is being cached (relative path).
39
+ * @param $id - a unique identifier for this fragment.
40
+ * @param $expiration - expiration time for the cached fragment.
41
+ * @param $expiration_trigger - wordpress hook to expire on.
42
+ */
43
+ public function __construct( $template, $id, $expiration, $expiration_trigger ) {
44
+ $this->template = $template;
45
+ $this->key = $template . '_' . $id;
46
+ $this->expiration = $expiration;
47
+ $this->expiration_trigger = $expiration_trigger;
48
+ $this->cache = new Tribe__Cache();
49
+
50
+ $this->add_hooks();
51
+ }
52
+
53
+ /**
54
+ * Hook in to show cached content and bypass queries where needed
55
+ */
56
+ public function add_hooks() {
57
+
58
+ // set the cached html in transients after the template part is included
59
+ add_filter( 'tribe_get_template_part_content', array( $this, 'set' ), 10, 2 );
60
+
61
+ // get the cached html right before the setup_view runs so it's available for bypassing any view logic
62
+ add_action( 'tribe_events_before_view', array( $this, 'get' ), 9, 1 );
63
+
64
+ // when the specified template part is included, show the cached html instead
65
+ add_filter( 'tribe_get_template_part_path_' . $this->template, array( $this, 'display' ) );
66
+ }
67
+
68
+ /**
69
+ * Checks if there is a cached html fragment in the transients, if it's there,
70
+ * don't include the requested file path. If not, just return the file path like normal
71
+ *
72
+ * @param $path file path to the month view template part
73
+ *
74
+ * @return bool
75
+ * @uses tribe_get_template_part_path_[template] hook
76
+ */
77
+ public function display( $path ) {
78
+
79
+ if ( $this->html !== false ) {
80
+ echo $this->html;
81
+
82
+ return false;
83
+ }
84
+
85
+ return $path;
86
+
87
+ }
88
+
89
+ /**
90
+ * Set cached html in transients
91
+ *
92
+ * @param $html
93
+ * @param $template
94
+ *
95
+ * @return string
96
+ * @uses tribe_get_template_part_content hook
97
+ */
98
+ public function set( $html, $template ) {
99
+ if ( $template == $this->template ) {
100
+ $this->cache->set_transient( $this->key, $html, $this->expiration, $this->expiration_trigger );
101
+ }
102
+
103
+ return $html;
104
+ }
105
+
106
+ /**
107
+ * Retrieve the cached html from transients, set class property
108
+ *
109
+ * @uses tribe_events_before_view hook
110
+ */
111
+ public function get() {
112
+
113
+ if ( isset( $this->html ) ) {
114
+
115
+ return $this->html;
116
+ }
117
+
118
+ $this->html = $this->cache->get_transient( $this->key, $this->expiration_trigger );
119
+
120
+ return $this->html;
121
+
122
+ }
123
+ }
common/src/Tribe/Templates.php CHANGED
@@ -1,79 +1,79 @@
1
- <?php
2
- /**
3
- * Templating functionality for common tribe
4
- */
5
-
6
- // don't load directly
7
- if ( ! defined( 'ABSPATH' ) ) {
8
- die( '-1' );
9
- }
10
-
11
- if ( class_exists( 'Tribe__Templates' ) ) {
12
- return;
13
- }
14
-
15
- /**
16
- * Handle views and template files.
17
- */
18
- class Tribe__Templates {
19
- /**
20
- * Check to see if this is operating in the main loop
21
- *
22
- * @param WP_Query $query
23
- *
24
- * @return bool
25
- */
26
- protected static function is_main_loop( $query ) {
27
- return $query->is_main_query();
28
- }
29
-
30
- /**
31
- * Look for the stylesheets. Fall back to $fallback path if the stylesheets can't be located or the array is empty.
32
- *
33
- * @param array|string $stylesheets Path to the stylesheet
34
- * @param bool|string $fallback Path to fallback stylesheet
35
- *
36
- * @return bool|string Path to stylesheet
37
- */
38
- public static function locate_stylesheet( $stylesheets, $fallback = false ) {
39
- if ( ! is_array( $stylesheets ) ) {
40
- $stylesheets = array( $stylesheets );
41
- }
42
- if ( empty( $stylesheets ) ) {
43
- return $fallback;
44
- }
45
- foreach ( $stylesheets as $filename ) {
46
- if ( file_exists( STYLESHEETPATH . '/' . $filename ) ) {
47
- $located = trailingslashit( get_stylesheet_directory_uri() ) . $filename;
48
- break;
49
- } else {
50
- if ( file_exists( TEMPLATEPATH . '/' . $filename ) ) {
51
- $located = trailingslashit( get_template_directory_uri() ) . $filename;
52
- break;
53
- }
54
- }
55
- }
56
- if ( empty( $located ) ) {
57
- return $fallback;
58
- }
59
-
60
- return $located;
61
- }
62
-
63
- /**
64
- * Add our own method is_embed to check by WordPress Version and function is_embed
65
- * to prevent fatal errors in WordPress 4.3 and earlier
66
- *
67
- * @version 4.2.1
68
- */
69
- public static function is_embed() {
70
- global $wp_version;
71
- if ( version_compare( $wp_version, '4.4', '<' ) || ! function_exists( 'is_embed' ) ) {
72
- return false;
73
- }
74
-
75
- return is_embed();
76
-
77
- }
78
-
79
- }//end class
1
+ <?php
2
+ /**
3
+ * Templating functionality for common tribe
4
+ */
5
+
6
+ // don't load directly
7
+ if ( ! defined( 'ABSPATH' ) ) {
8
+ die( '-1' );
9
+ }
10
+
11
+ if ( class_exists( 'Tribe__Templates' ) ) {
12
+ return;
13
+ }
14
+
15
+ /**
16
+ * Handle views and template files.
17
+ */
18
+ class Tribe__Templates {
19
+ /**
20
+ * Check to see if this is operating in the main loop
21
+ *
22
+ * @param WP_Query $query
23
+ *
24
+ * @return bool
25
+ */
26
+ protected static function is_main_loop( $query ) {
27
+ return $query->is_main_query();
28
+ }
29
+
30
+ /**
31
+ * Look for the stylesheets. Fall back to $fallback path if the stylesheets can't be located or the array is empty.
32
+ *
33
+ * @param array|string $stylesheets Path to the stylesheet
34
+ * @param bool|string $fallback Path to fallback stylesheet
35
+ *
36
+ * @return bool|string Path to stylesheet
37
+ */
38
+ public static function locate_stylesheet( $stylesheets, $fallback = false ) {
39
+ if ( ! is_array( $stylesheets ) ) {
40
+ $stylesheets = array( $stylesheets );
41
+ }
42
+ if ( empty( $stylesheets ) ) {
43
+ return $fallback;
44
+ }
45
+ foreach ( $stylesheets as $filename ) {
46
+ if ( file_exists( STYLESHEETPATH . '/' . $filename ) ) {
47
+ $located = trailingslashit( get_stylesheet_directory_uri() ) . $filename;
48
+ break;
49
+ } else {
50
+ if ( file_exists( TEMPLATEPATH . '/' . $filename ) ) {
51
+ $located = trailingslashit( get_template_directory_uri() ) . $filename;
52
+ break;
53
+ }
54
+ }
55
+ }
56
+ if ( empty( $located ) ) {
57
+ return $fallback;
58
+ }
59
+
60
+ return $located;
61
+ }
62
+
63
+ /**
64
+ * Add our own method is_embed to check by WordPress Version and function is_embed
65
+ * to prevent fatal errors in WordPress 4.3 and earlier
66
+ *
67
+ * @version 4.2.1
68
+ */
69
+ public static function is_embed() {
70
+ global $wp_version;
71
+ if ( version_compare( $wp_version, '4.4', '<' ) || ! function_exists( 'is_embed' ) ) {
72
+ return false;
73
+ }
74
+
75
+ return is_embed();
76
+
77
+ }
78
+
79
+ }//end class
common/src/Tribe/Timezones.php CHANGED
@@ -1,366 +1,366 @@
1
- <?php
2
-
3
- /**
4
- * Helpers for handling timezone based event datetimes.
5
- *
6
- * In our timezone logic, the term "local" refers to the locality of an event
7
- * rather than the local WordPress timezone.
8
- */
9
- class Tribe__Timezones {
10
- const SITE_TIMEZONE = 'site';
11
- const EVENT_TIMEZONE = 'event';
12
-
13
-
14
- /**
15
- * Container for reusable DateTimeZone objects.
16
- *
17
- * @var array
18
- */
19
- protected static $timezones = array();
20
-
21
-
22
- public static function init() {
23
- self::invalidate_caches();
24
- }
25
-
26
- /**
27
- * Clear any cached timezone-related values when appropriate.
28
- *
29
- * Currently we are concerned only with the site timezone abbreviation.
30
- */
31
- protected static function invalidate_caches() {
32
- add_filter( 'pre_update_option_gmt_offset', array( __CLASS__, 'clear_site_timezone_abbr' ) );
33
- add_filter( 'pre_update_option_timezone_string', array( __CLASS__, 'clear_site_timezone_abbr' ) );
34
- }
35
-
36
- /**
37
- * Wipe the cached site timezone abbreviation, if set.
38
- *
39
- * @param mixed $option_val (passed through without modification)
40
- *
41
- * @return mixed
42
- */
43
- public static function clear_site_timezone_abbr( $option_val ) {
44
- delete_transient( 'tribe_events_wp_timezone_abbr' );
45
- return $option_val;
46
- }
47
-
48
- /**
49
- * Returns the current site-wide timezone string.
50
- *
51
- * Based on the core WP code found in wp-admin/options-general.php.
52
- *
53
- * @return string
54
- */
55
- public static function wp_timezone_string() {
56
- $current_offset = get_option( 'gmt_offset' );
57
- $tzstring = get_option( 'timezone_string' );
58
-
59
- // Return the timezone string if already set
60
- if ( ! empty( $tzstring ) ) {
61
- return $tzstring;
62
- }
63
-
64
- // Otherwise return the UTC offset
65
- if ( 0 == $current_offset ) {
66
- return 'UTC+0';
67
- } elseif ( $current_offset < 0 ) {
68
- return 'UTC' . $current_offset;
69
- }
70
-
71
- return 'UTC+' . $current_offset;
72
- }
73
-
74
- /**
75
- * Returns the current site-wide timezone string abbreviation, if it can be
76
- * determined or falls back on the full timezone string/offset text.
77
- *
78
- * @param string $date
79
- *
80
- * @return string
81
- */
82
- public static function wp_timezone_abbr( $date ) {
83
- $abbr = get_transient( 'tribe_events_wp_timezone_abbr' );
84
-
85
- if ( empty( $abbr ) ) {
86
- $timezone_string = self::wp_timezone_string();
87
- $abbr = self::abbr( $date, $timezone_string );
88
- set_transient( 'tribe_events_wp_timezone_abbr', $abbr );
89
- }
90
-
91
- return empty( $abbr )
92
- ? $timezone_string
93
- : $abbr;
94
- }
95
-
96
- /**
97
- * Helper function to retrieve the timezone string for a given UTC offset
98
- *
99
- * This is a close copy of WooCommerce's wc_timezone_string() method
100
- *
101
- * @param string $offset UTC offset
102
- *
103
- * @return string
104
- */
105
- public static function generate_timezone_string_from_utc_offset( $offset ) {
106
- if ( ! self::is_utc_offset( $offset ) ) {
107
- return $offset;
108
- }
109
-
110
- // ensure we have the minutes on the offset
111
- if ( ! strpos( $offset, ':' ) ) {
112
- $offset .= ':00';
113
- }
114
-
115
- $offset = str_replace( 'UTC', '', $offset );
116
-
117
- list( $hours, $minutes ) = explode( ':', $offset );
118
- $seconds = $hours * 60 * 60 + $minutes * 60;
119
-
120
- // attempt to guess the timezone string from the UTC offset
121
- $timezone = timezone_name_from_abbr( '', $seconds, 0 );
122
-
123
- if ( false === $timezone ) {
124
- $is_dst = date( 'I' );
125
-
126
- foreach ( timezone_abbreviations_list() as $abbr ) {
127
- foreach ( $abbr as $city ) {
128
- if (
129
- $city['dst'] == $is_dst
130
- && $city['offset'] == $seconds
131
- ) {
132
- return $city['timezone_id'];
133
- }
134
- }
135
- }
136
-
137
- // fallback to UTC
138
- return 'UTC';
139
- }
140
-
141
- return $timezone;
142
- }
143
-
144
- /**
145
- * Tried to convert the provided $datetime to UTC from the timezone represented by $tzstring.
146
- *
147
- * Though the usual range of formats are allowed, $datetime ordinarily ought to be something
148
- * like the "Y-m-d H:i:s" format (ie, no timezone information). If it itself contains timezone
149
- * data, the results may be unexpected.
150
- *
151
- * In those cases where the conversion fails to take place, the $datetime string will be
152
- * returned untouched.
153
- *
154
- * @param string $datetime
155
- * @param string $tzstring
156
- *
157
- * @return string
158
- */
159
- public static function to_utc( $datetime, $tzstring ) {
160
- if ( self::is_utc_offset( $tzstring ) ) {
161
- return self::apply_offset( $datetime, $tzstring, true );
162
- }
163
-
164
- try {
165
- $local = self::get_timezone( $tzstring );
166
- $utc = self::get_timezone( 'UTC' );
167
-
168
- // We can't use method chaining here (ie "date_create(...)->setTimezone(...)") due to PHP 5.2 compatibility concerns
169
- $datetime = date_create( $datetime, $local );
170
-
171
- if ( $datetime && false !== $datetime->setTimezone( $utc ) ) {
172
- return $datetime->format( Tribe__Date_Utils::DBDATETIMEFORMAT );
173
- }
174
- }
175
- catch ( Exception $e ) {}
176
-
177
- return $datetime;
178
- }
179
-
180
- /**
181
- * Tries to convert the provided $datetime to the timezone represented by $tzstring.
182
- *
183
- * This is the sister function of self::to_utc() - please review the docs for that method
184
- * for more information.
185
- *
186
- * @param string $datetime
187
- * @param string $tzstring
188
- *
189
- * @return string
190
- */
191
- public static function to_tz( $datetime, $tzstring ) {
192
- if ( self::is_utc_offset( $tzstring ) ) {
193
- return self::apply_offset( $datetime, $tzstring );
194
- }
195
-
196
- try {
197
- $local = self::get_timezone( $tzstring );
198
- $utc = self::get_timezone( 'UTC' );
199
-
200
- // We can't use method chaining here (ie "date_create(...)->setTimezone(...)") due to PHP 5.2 compatibility concerns
201
- $datetime = date_create( $datetime, $utc );
202
-
203
- if ( $datetime && false !== $datetime->setTimezone( $local ) ) {
204
- return $datetime->format( Tribe__Date_Utils::DBDATETIMEFORMAT );
205
- }
206
- }
207
- catch ( Exception $e ) {}
208
-
209
- return $datetime;
210
- }
211
-
212
- /**
213
- * Tests to see if the timezone string is a UTC offset, ie "UTC+2".
214
- *
215
- * @param string $timezone
216
- *
217
- * @return bool
218
- */
219
- public static function is_utc_offset( $timezone ) {
220
- $timezone = trim( $timezone );
221
- return ( 0 === strpos( $timezone, 'UTC' ) && strlen( $timezone ) > 3 );
222
- }
223
-
224
- /**
225
- * @param string $datetime
226
- * @param mixed $offset (string or numeric offset)
227
- * @param bool $invert = false
228
- *
229
- * @return string
230
- */
231
- public static function apply_offset( $datetime, $offset, $invert = false ) {
232
- // Normalize
233
- $offset = strtolower( trim( $offset ) );
234
-
235
- // Strip any leading "utc" text if set
236
- if ( 0 === strpos( $offset, 'utc' ) ) {
237
- $offset = substr( $offset, 3 );
238
- }
239
-
240
- // It's possible no adjustment will be needed
241
- if ( 0 === $offset ) {
242
- return $datetime;
243
- }
244
-
245
- // Convert the offset to minutes for easier handling of fractional offsets
246
- $offset = (int) ( $offset * 60 );
247
-
248
- // Invert the offset? Useful for stripping an offset that has already been applied
249
- if ( $invert ) {
250
- $offset *= -1;
251
- }
252
-
253
- try {
254
- if ( $offset > 0 ) $offset = '+' . $offset;
255
- $offset = $offset . ' minutes';
256
-
257
- // We can't use method chaining here (ie "date_create(...)->modify(...)") due to PHP 5.2 compatibility concerns
258
- $datetime = date_create( $datetime );
259
-
260
- if ( $datetime && false !== $datetime->modify( $offset ) ) {
261
- return $datetime->format( Tribe__Date_Utils::DBDATETIMEFORMAT );
262
- }
263
- }
264
- catch ( Exception $e ) {}
265
-
266
- return $datetime;
267
- }
268
-
269
- /**
270
- * Accepts a unix timestamp and adjusts it so that when it is used to consitute
271
- * a new datetime string, that string reflects the designated timezone.
272
- *
273
- * @param string $unix_timestamp
274
- * @param string $tzstring
275
- *
276
- * @return string
277
- */
278
- public static function adjust_timestamp( $unix_timestamp, $tzstring ) {
279
- try {
280
- $local = self::get_timezone( $tzstring );
281
- $datetime = date_create_from_format( 'U', $unix_timestamp )->format( Tribe__Date_Utils::DBDATETIMEFORMAT );
282
-
283
- // We prefer format('U') to getTimestamp() here due to our requirement for compatibility with PHP 5.2
284
- return date_create_from_format( 'Y-m-d H:i:s', $datetime, $local )->format( 'U' );
285
- }
286
- catch( Exception $e ) {
287
- return $unix_timestamp;
288
- }
289
- }
290
-
291
- /**
292
- * Returns a DateTimeZone object matching the representation in $tzstring where
293
- * possible, or else representing UTC (or, in the worst case, false).
294
- *
295
- * If optional parameter $with_fallback is true, which is the default, then in
296
- * the event it cannot find/create the desired timezone it will try to return the
297
- * UTC DateTimeZone before bailing.
298
- *
299
- * @param string $tzstring
300
- * @param bool $with_fallback = true
301
- *
302
- * @return DateTimeZone|false
303
- */
304
- public static function get_timezone( $tzstring, $with_fallback = true ) {
305
- if ( isset( self::$timezones[ $tzstring ] ) ) {
306
- return self::$timezones[ $tzstring ];
307
- }
308
-
309
- try {
310
- self::$timezones[ $tzstring ] = new DateTimeZone( $tzstring );
311
- return self::$timezones[ $tzstring ];
312
- }
313
- catch ( Exception $e ) {
314
- if ( $with_fallback ) {
315
- return self::get_timezone( 'UTC', true );
316
- }
317
- }
318
-
319
- return false;
320
- }
321
-
322
- /**
323
- * Returns a string representing the timezone/offset currently desired for
324
- * the display of dates and times.
325
- *
326
- * @return string
327
- */
328
- public static function mode() {
329
- $mode = self::EVENT_TIMEZONE;
330
-
331
- if ( 'site' === tribe_get_option( 'tribe_events_timezone_mode' ) ) {
332
- $mode = self::SITE_TIMEZONE;
333
- }
334
-
335
- return apply_filters( 'tribe_events_current_display_timezone', $mode );
336
- }
337
-
338
- /**
339
- * Confirms if the current timezone mode matches the $possible_mode.
340
- *
341
- * @param string $possible_mode
342
- *
343
- * @return bool
344
- */
345
- public static function is_mode( $possible_mode ) {
346
- return $possible_mode === self::mode();
347
- }
348
-
349
- /**
350
- * Attempts to provide the correct timezone abbreviation for the provided timezone string
351
- * on the date given (and so should account for daylight saving time, etc).
352
- *
353
- * @param string $date
354
- * @param string $timezone_string
355
- *
356
- * @return string
357
- */
358
- public static function abbr( $date, $timezone_string ) {
359
- try {
360
- return date_create( $date, new DateTimeZone( $timezone_string ) )->format( 'T' );
361
- }
362
- catch ( Exception $e ) {
363
- return '';
364
- }
365
- }
366
- }
1
+ <?php
2
+
3
+ /**
4
+ * Helpers for handling timezone based event datetimes.
5
+ *
6
+ * In our timezone logic, the term "local" refers to the locality of an event
7
+ * rather than the local WordPress timezone.
8
+ */
9
+ class Tribe__Timezones {
10
+ const SITE_TIMEZONE = 'site';
11
+ const EVENT_TIMEZONE = 'event';
12
+
13
+
14
+ /**
15
+ * Container for reusable DateTimeZone objects.
16
+ *
17
+ * @var array
18
+ */
19
+ protected static $timezones = array();
20
+
21
+
22
+ public static function init() {
23
+ self::invalidate_caches();
24
+ }
25
+
26
+ /**
27
+ * Clear any cached timezone-related values when appropriate.
28
+ *
29
+ * Currently we are concerned only with the site timezone abbreviation.
30
+ */
31
+ protected static function invalidate_caches() {
32
+ add_filter( 'pre_update_option_gmt_offset', array( __CLASS__, 'clear_site_timezone_abbr' ) );
33
+ add_filter( 'pre_update_option_timezone_string', array( __CLASS__, 'clear_site_timezone_abbr' ) );
34
+ }
35
+
36
+ /**
37
+ * Wipe the cached site timezone abbreviation, if set.
38
+ *
39
+ * @param mixed $option_val (passed through without modification)
40
+ *
41
+ * @return mixed
42
+ */
43
+ public static function clear_site_timezone_abbr( $option_val ) {
44
+ delete_transient( 'tribe_events_wp_timezone_abbr' );
45
+ return $option_val;
46
+ }
47
+
48
+ /**
49
+ * Returns the current site-wide timezone string.
50
+ *
51
+ * Based on the core WP code found in wp-admin/options-general.php.
52
+ *
53
+ * @return string
54
+ */
55
+ public static function wp_timezone_string() {
56
+ $current_offset = get_option( 'gmt_offset' );
57
+ $tzstring = get_option( 'timezone_string' );
58
+
59
+ // Return the timezone string if already set
60
+ if ( ! empty( $tzstring ) ) {
61
+ return $tzstring;
62
+ }
63
+
64
+ // Otherwise return the UTC offset
65
+ if ( 0 == $current_offset ) {
66
+ return 'UTC+0';
67
+ } elseif ( $current_offset < 0 ) {
68
+ return 'UTC' . $current_offset;
69
+ }
70
+
71
+ return 'UTC+' . $current_offset;
72
+ }
73
+
74
+ /**
75
+ * Returns the current site-wide timezone string abbreviation, if it can be
76
+ * determined or falls back on the full timezone string/offset text.
77
+ *
78
+ * @param string $date
79
+ *
80
+ * @return string
81
+ */
82
+ public static function wp_timezone_abbr( $date ) {
83
+ $abbr = get_transient( 'tribe_events_wp_timezone_abbr' );
84
+
85
+ if ( empty( $abbr ) ) {
86
+ $timezone_string = self::wp_timezone_string();
87
+ $abbr = self::abbr( $date, $timezone_string );
88
+ set_transient( 'tribe_events_wp_timezone_abbr', $abbr );
89
+ }
90
+
91
+ return empty( $abbr )
92
+ ? $timezone_string
93
+ : $abbr;
94
+ }
95
+
96
+ /**
97
+ * Helper function to retrieve the timezone string for a given UTC offset
98
+ *
99
+ * This is a close copy of WooCommerce's wc_timezone_string() method
100
+ *
101
+ * @param string $offset UTC offset
102
+ *
103
+ * @return string
104
+ */
105
+ public static function generate_timezone_string_from_utc_offset( $offset ) {
106
+ if ( ! self::is_utc_offset( $offset ) ) {
107
+ return $offset;
108
+ }
109
+
110
+ // ensure we have the minutes on the offset
111
+ if ( ! strpos( $offset, ':' ) ) {
112
+ $offset .= ':00';
113
+ }
114
+
115
+ $offset = str_replace( 'UTC', '', $offset );
116
+
117
+ list( $hours, $minutes ) = explode( ':', $offset );
118
+ $seconds = $hours * 60 * 60 + $minutes * 60;
119
+
120
+ // attempt to guess the timezone string from the UTC offset
121
+ $timezone = timezone_name_from_abbr( '', $seconds, 0 );
122
+
123
+ if ( false === $timezone ) {
124
+ $is_dst = date( 'I' );
125
+
126
+ foreach ( timezone_abbreviations_list() as $abbr ) {
127
+ foreach ( $abbr as $city ) {
128
+ if (
129
+ $city['dst'] == $is_dst
130
+ && $city['offset'] == $seconds
131
+ ) {
132
+ return $city['timezone_id'];
133
+ }
134
+ }
135
+ }
136
+
137
+ // fallback to UTC
138
+ return 'UTC';
139
+ }
140
+
141
+ return $timezone;
142
+ }
143
+
144
+ /**
145
+ * Tried to convert the provided $datetime to UTC from the timezone represented by $tzstring.
146
+ *
147
+ * Though the usual range of formats are allowed, $datetime ordinarily ought to be something
148
+ * like the "Y-m-d H:i:s" format (ie, no timezone information). If it itself contains timezone
149
+ * data, the results may be unexpected.
150
+ *
151
+ * In those cases where the conversion fails to take place, the $datetime string will be
152
+ * returned untouched.
153
+ *
154
+ * @param string $datetime
155
+ * @param string $tzstring
156
+ *
157
+ * @return string
158
+ */
159
+ public static function to_utc( $datetime, $tzstring ) {
160
+ if ( self::is_utc_offset( $tzstring ) ) {
161
+ return self::apply_offset( $datetime, $tzstring, true );
162
+ }
163
+
164
+ try {
165
+ $local = self::get_timezone( $tzstring );
166
+ $utc = self::get_timezone( 'UTC' );
167
+
168
+ // We can't use method chaining here (ie "date_create(...)->setTimezone(...)") due to PHP 5.2 compatibility concerns
169
+ $datetime = date_create( $datetime, $local );
170
+
171
+ if ( $datetime && false !== $datetime->setTimezone( $utc ) ) {
172
+ return $datetime->format( Tribe__Date_Utils::DBDATETIMEFORMAT );
173
+ }
174
+ }
175
+ catch ( Exception $e ) {}
176
+
177
+ return $datetime;
178
+ }
179
+
180
+ /**
181
+ * Tries to convert the provided $datetime to the timezone represented by $tzstring.
182
+ *
183
+ * This is the sister function of self::to_utc() - please review the docs for that method
184
+ * for more information.
185
+ *
186
+ * @param string $datetime
187
+ * @param string $tzstring
188
+ *
189
+ * @return string
190
+ */
191
+ public static function to_tz( $datetime, $tzstring ) {
192
+ if ( self::is_utc_offset( $tzstring ) ) {
193
+ return self::apply_offset( $datetime, $tzstring );
194
+ }
195
+
196
+ try {
197
+ $local = self::get_timezone( $tzstring );
198
+ $utc = self::get_timezone( 'UTC' );
199
+
200
+ // We can't use method chaining here (ie "date_create(...)->setTimezone(...)") due to PHP 5.2 compatibility concerns
201
+ $datetime = date_create( $datetime, $utc );
202
+
203
+ if ( $datetime && false !== $datetime->setTimezone( $local ) ) {
204
+ return $datetime->format( Tribe__Date_Utils::DBDATETIMEFORMAT );
205
+ }
206
+ }
207
+ catch ( Exception $e ) {}
208
+
209
+ return $datetime;
210
+ }
211
+
212
+ /**
213
+ * Tests to see if the timezone string is a UTC offset, ie "UTC+2".
214
+ *
215
+ * @param string $timezone
216
+ *
217
+ * @return bool
218
+ */
219
+ public static function is_utc_offset( $timezone ) {
220
+ $timezone = trim( $timezone );
221
+ return ( 0 === strpos( $timezone, 'UTC' ) && strlen( $timezone ) > 3 );
222
+ }
223
+
224
+ /**
225
+ * @param string $datetime
226
+ * @param mixed $offset (string or numeric offset)
227
+ * @param bool $invert = false
228
+ *
229
+ * @return string
230
+ */
231
+ public static function apply_offset( $datetime, $offset, $invert = false ) {
232
+ // Normalize
233
+ $offset = strtolower( trim( $offset ) );
234
+
235
+ // Strip any leading "utc" text if set
236
+ if ( 0 === strpos( $offset, 'utc' ) ) {
237
+ $offset = substr( $offset, 3 );
238
+ }
239
+
240
+ // It's possible no adjustment will be needed
241
+ if ( 0 === $offset ) {
242
+ return $datetime;
243
+ }
244
+
245
+ // Convert the offset to minutes for easier handling of fractional offsets
246
+ $offset = (int) ( $offset * 60 );
247
+
248
+ // Invert the offset? Useful for stripping an offset that has already been applied
249
+ if ( $invert ) {
250
+ $offset *= -1;
251
+ }
252
+
253
+ try {
254
+ if ( $offset > 0 ) $offset = '+' . $offset;
255
+ $offset = $offset . ' minutes';
256
+
257
+ // We can't use method chaining here (ie "date_create(...)->modify(...)") due to PHP 5.2 compatibility concerns
258
+ $datetime = date_create( $datetime );
259
+
260
+ if ( $datetime && false !== $datetime->modify( $offset ) ) {
261
+ return $datetime->format( Tribe__Date_Utils::DBDATETIMEFORMAT );
262
+ }
263
+ }
264
+ catch ( Exception $e ) {}
265
+
266
+ return $datetime;
267
+ }
268
+
269
+ /**
270
+ * Accepts a unix timestamp and adjusts it so that when it is used to consitute
271
+ * a new datetime string, that string reflects the designated timezone.
272
+ *
273
+ * @param string $unix_timestamp
274
+ * @param string $tzstring
275
+ *
276
+ * @return string
277
+ */
278
+ public static function adjust_timestamp( $unix_timestamp, $tzstring ) {
279
+ try {
280
+ $local = self::get_timezone( $tzstring );
281
+ $datetime = date_create_from_format( 'U', $unix_timestamp )->format( Tribe__Date_Utils::DBDATETIMEFORMAT );
282
+
283
+ // We prefer format('U') to getTimestamp() here due to our requirement for compatibility with PHP 5.2
284
+ return date_create_from_format( 'Y-m-d H:i:s', $datetime, $local )->format( 'U' );
285
+ }
286
+ catch( Exception $e ) {
287
+ return $unix_timestamp;
288
+ }
289
+ }
290
+
291
+ /**
292
+ * Returns a DateTimeZone object matching the representation in $tzstring where
293
+ * possible, or else representing UTC (or, in the worst case, false).
294
+ *
295
+ * If optional parameter $with_fallback is true, which is the default, then in
296
+ * the event it cannot find/create the desired timezone it will try to return the
297
+ * UTC DateTimeZone before bailing.
298
+ *
299
+ * @param string $tzstring
300
+ * @param bool $with_fallback = true
301
+ *
302
+ * @return DateTimeZone|false
303
+ */
304
+ public static function get_timezone( $tzstring, $with_fallback = true ) {
305
+ if ( isset( self::$timezones[ $tzstring ] ) ) {
306
+ return self::$timezones[ $tzstring ];
307
+ }
308
+
309
+ try {
310
+ self::$timezones[ $tzstring ] = new DateTimeZone( $tzstring );
311
+ return self::$timezones[ $tzstring ];
312
+ }
313
+ catch ( Exception $e ) {
314
+ if ( $with_fallback ) {
315
+ return self::get_timezone( 'UTC', true );
316
+ }
317
+ }
318
+
319
+ return false;
320
+ }
321
+
322
+ /**
323
+ * Returns a string representing the timezone/offset currently desired for
324
+ * the display of dates and times.
325
+ *
326
+ * @return string
327
+ */
328
+ public static function mode() {
329
+ $mode = self::EVENT_TIMEZONE;
330
+
331
+ if ( 'site' === tribe_get_option( 'tribe_events_timezone_mode' ) ) {
332
+ $mode = self::SITE_TIMEZONE;
333
+ }
334
+
335
+ return apply_filters( 'tribe_events_current_display_timezone', $mode );
336
+ }
337
+
338
+ /**
339
+ * Confirms if the current timezone mode matches the $possible_mode.
340
+ *
341
+ * @param string $possible_mode
342
+ *
343
+ * @return bool
344
+ */
345
+ public static function is_mode( $possible_mode ) {
346
+ return $possible_mode === self::mode();
347
+ }
348
+
349
+ /**
350
+ * Attempts to provide the correct timezone abbreviation for the provided timezone string
351
+ * on the date given (and so should account for daylight saving time, etc).
352
+ *
353
+ * @param string $date
354
+ * @param string $timezone_string
355
+ *
356
+ * @return string
357
+ */
358
+ public static function abbr( $date, $timezone_string ) {
359
+ try {
360
+ return date_create( $date, new DateTimeZone( $timezone_string ) )->format( 'T' );
361
+ }
362
+ catch ( Exception $e ) {
363
+ return '';
364
+ }
365
+ }
366
+ }
common/src/Tribe/Utils/Coordinates_Provider.php CHANGED
@@ -1,134 +1,134 @@
1
- <?php
2
-
3
-
4
- /**
5
- * Class Tribe__Utils__Coordinates_Provider
6
- *
7
- * Provided latitude and longitude coordinates for a location.
8
- */
9
- class Tribe__Utils__Coordinates_Provider {
10
-
11
- /**
12
- * @var string
13
- */
14
- public static $google_api_base = 'http://maps.googleapis.com/maps/api/geocode/';
15
-
16
- /**
17
- * @var string
18
- */
19
- public static $google_api_json_format = 'json';
20
-
21
- /**
22
- * @var string
23
- */
24
- public static $transient_name = 'tribe_resolved_address_coordinates';
25
-
26
- /**
27
- * @var bool
28
- */
29
- protected $transient = false;
30
-
31
- /**
32
- * @var WP_Http
33
- */
34
- private $http;
35
-
36
- /**
37
- * @var Tribe__Utils__Coordinates_Provider
38
- */
39
- protected static $instance;
40
-
41
- /**
42
- * The class singleton constructor.
43
- *
44
- * @return Tribe__Utils__Coordinates_Provider
45
- */
46
- public static function instance() {
47
- if ( empty( self::$instance ) ) {
48
- self::$instance = new self();
49
- }
50
-
51
- return self::$instance;
52
- }
53
-
54
- /**
55
- * Tribe__Utils__Coordinates_Provider constructor.
56
- *
57
- * @param WP_Http|null $http
58
- */
59
- public function __construct( WP_Http $http = null ) {
60
- $this->http = ! empty( $http ) ? $http : _wp_http_get_object();
61
- }
62
-
63
- /**
64
- * @param string|array $address
65
- */
66
- public function provide_coordinates_for_address( $address ) {
67
-
68
- if ( is_array( $address ) ) {
69
- $address = implode( ', ', array_filter( array_map( 'trim', $address ) ) );
70
- }
71
-
72
- $address = trim( $address );
73
-
74
- if ( $location = $this->get_resolved( $address ) ) {
75
- return $location;
76
- }
77
-
78
- $base_request_url = trailingslashit( $this->get_google_api_base() ) . $this->get_google_api_json_format();
79
- $url = esc_url( add_query_arg( array( 'address' => $address ), $base_request_url ) );
80
- $response = $this->http->get( $url );
81
-
82
- if ( is_wp_error( $response ) ) {
83
- return false;
84
- }
85
-
86
- $decoded = json_decode( $response['body'], true );
87
-
88
- if ( empty( $decoded['status'] ) || 'OK' !== $decoded['status'] ) {
89
- return false;
90
- }
91
-
92
- if ( empty( $decoded['results'][0]['place_id'] ) || empty( $decoded['results'][0]['geometry']['location']['lat'] ) || empty( $decoded['results'][0]['geometry']['location']['lng'] ) ) {
93
- return false;
94
- }
95
-
96
- $location = $decoded['results'][0]['geometry']['location'];
97
-
98
- $updated_transient = array_merge( $this->get_transient(), array( $address => $location ) );
99
- set_transient( self::$transient_name, $updated_transient );
100
- $this->transient = $updated_transient;
101
-
102
- return $location;
103
- }
104
-
105
- /**
106
- * @return null|WP_Http
107
- */
108
- public function get_http() {
109
- return $this->http;
110
- }
111
-
112
- protected function get_google_api_base() {
113
- return self::$google_api_base;
114
- }
115
-
116
- protected function get_google_api_json_format() {
117
- return self::$google_api_json_format;
118
- }
119
-
120
- protected function get_transient() {
121
- if ( ! is_array( $this->transient ) ) {
122
- $transient = get_transient( self::$transient_name );
123
- $this->transient = is_array( $transient ) ? $transient : array();
124
- }
125
-
126
- return $this->transient;
127
- }
128
-
129
- protected function get_resolved( $address ) {
130
- $transient = $this->get_transient();
131
-
132
- return isset( $transient[ $address ] ) ? $transient[ $address ] : false;
133
- }
134
  }
1
+ <?php
2
+
3
+
4
+ /**
5
+ * Class Tribe__Utils__Coordinates_Provider
6
+ *
7
+ * Provided latitude and longitude coordinates for a location.
8
+ */
9
+ class Tribe__Utils__Coordinates_Provider {
10
+
11
+ /**
12
+ * @var string
13
+ */
14
+ public static $google_api_base = 'http://maps.googleapis.com/maps/api/geocode/';
15
+
16
+ /**
17
+ * @var string
18
+ */
19
+ public static $google_api_json_format = 'json';
20
+
21
+ /**
22
+ * @var string
23
+ */
24
+ public static $transient_name = 'tribe_resolved_address_coordinates';
25
+
26
+ /**
27
+ * @var bool
28
+ */
29
+ protected $transient = false;
30
+
31
+ /**
32
+ * @var WP_Http
33
+ */
34
+ private $http;
35
+
36
+ /**
37
+ * @var Tribe__Utils__Coordinates_Provider
38
+ */
39
+ protected static $instance;
40
+
41
+ /**
42
+ * The class singleton constructor.
43
+ *
44
+ * @return Tribe__Utils__Coordinates_Provider
45
+ */
46
+ public static function instance() {
47
+ if ( empty( self::$instance ) ) {
48
+ self::$instance = new self();
49
+ }
50
+
51
+ return self::$instance;
52
+ }
53
+
54
+ /**
55
+ * Tribe__Utils__Coordinates_Provider constructor.
56
+ *
57
+ * @param WP_Http|null $http
58
+ */
59
+ public function __construct( WP_Http $http = null ) {
60
+ $this->http = ! empty( $http ) ? $http : _wp_http_get_object();
61
+ }
62
+
63
+ /**
64
+ * @param string|array $address
65
+ */
66
+ public function provide_coordinates_for_address( $address ) {
67
+
68
+ if ( is_array( $address ) ) {
69
+ $address = implode( ', ', array_filter( array_map( 'trim', $address ) ) );
70
+ }
71
+
72
+ $address = trim( $address );
73
+
74
+ if ( $location = $this->get_resolved( $address ) ) {
75
+ return $location;
76
+ }
77
+
78
+ $base_request_url = trailingslashit( $this->get_google_api_base() ) . $this->get_google_api_json_format();
79
+ $url = esc_url( add_query_arg( array( 'address' => $address ), $base_request_url ) );
80
+ $response = $this->http->get( $url );
81
+
82
+ if ( is_wp_error( $response ) ) {
83
+ return false;
84
+ }
85
+
86
+ $decoded = json_decode( $response['body'], true );
87
+
88
+ if ( empty( $decoded['status'] ) || 'OK' !== $decoded['status'] ) {
89
+ return false;
90
+ }
91
+
92
+ if ( empty( $decoded['results'][0]['place_id'] ) || empty( $decoded['results'][0]['geometry']['location']['lat'] ) || empty( $decoded['results'][0]['geometry']['location']['lng'] ) ) {
93
+ return false;
94
+ }
95
+
96
+ $location = $decoded['results'][0]['geometry']['location'];
97
+
98
+ $updated_transient = array_merge( $this->get_transient(), array( $address => $location ) );
99
+ set_transient( self::$transient_name, $updated_transient );
100
+ $this->transient = $updated_transient;
101
+
102
+ return $location;
103
+ }
104
+
105
+ /**
106
+ * @return null|WP_Http
107
+ */
108
+ public function get_http() {
109
+ return $this->http;
110
+ }
111
+
112
+ protected function get_google_api_base() {
113
+ return self::$google_api_base;
114
+ }
115
+
116
+ protected function get_google_api_json_format() {
117
+ return self::$google_api_json_format;
118
+ }
119
+
120
+ protected function get_transient() {
121
+ if ( ! is_array( $this->transient ) ) {
122
+ $transient = get_transient( self::$transient_name );
123
+ $this->transient = is_array( $transient ) ? $transient : array();
124
+ }
125
+
126
+ return $this->transient;
127
+ }
128
+
129
+ protected function get_resolved( $address ) {
130
+ $transient = $this->get_transient();
131
+
132
+ return isset( $transient[ $address ] ) ? $transient[ $address ] : false;
133
+ }
134
  }
common/src/Tribe/Utils/Post_Root_Pool.php CHANGED
@@ -1,185 +1,185 @@
1
- <?php
2
-
3
-
4
- class Tribe__Utils__Post_Root_Pool {
5
-
6
- /**
7
- * @var string
8
- */
9
- protected $pool_transient_name = 'tribe_ticket_prefix_pool';
10
-
11
- /**
12
- * @var array|bool
13
- */
14
- protected static $prefix_pool = false;
15
-
16
- /**
17
- * @var string
18
- */
19
- protected $root_separator = '-';
20
-
21
- /**
22
- * @var array
23
- */
24
- protected $postfix = 1;
25
-
26
- /**
27
- * @var WP_Post
28
- */
29
- protected $current_post = null;
30
-
31
- /**
32
- * Generates a unique root for a post using its post_name.
33
- *
34
- * @param WP_Post $post
35
- *
36
- * @return string
37
- */
38
- public function generate_unique_root( WP_Post $post ) {
39
- $post_name = $post->post_name;
40
-
41
- $this->current_post = $post;
42
- $flipped_pool = array_flip( $this->fetch_pool() );
43
-
44
- if ( isset( $flipped_pool[ $this->current_post->ID ] ) ) {
45
- return $flipped_pool[ $this->current_post->ID ] . $this->root_separator;
46
- }
47
-
48
- $root = $this->build_root_from( $post_name );
49
-
50
- return $root . $this->root_separator;
51
- }
52
-
53
- /**
54
- * @param string $post_name
55
- *
56
- * @param string $postfix
57
- *
58
- * @return string
59
- */
60
- protected function build_root_from( $post_name, $postfix = '' ) {
61
- $candidate = $this->build_root_candidate( $post_name, $postfix );
62
-
63
- $initial_candidate = $candidate;
64
-
65
- while ( $this->is_in_pool( $candidate ) ) {
66
- $postfix = $this->postfix;
67
- $candidate = $initial_candidate . '-' . $postfix;
68
- $this->postfix ++;
69
- }
70
-
71
- $this->postfix = 1;
72
-
73
- $this->insert_root_in_pool( $candidate );
74
-
75
- return $candidate;
76
- }
77
-
78
- /**
79
- * @return string
80
- */
81
- public function get_pool_transient_name() {
82
- return $this->pool_transient_name;
83
- }
84
-
85
- /**
86
- * @param $string
87
- *
88
- * @return string
89
- */
90
- protected function uc_first_letter( $string ) {
91
- return is_numeric( $string ) ? $string : strtoupper( $string[0] );
92
- }
93
-
94
- /**
95
- * @param string $candidate
96
- */
97
- protected function is_in_pool( $candidate ) {
98
- $pool = $this->fetch_pool();
99
-
100
- return isset( $pool[ $candidate ] );
101
- }
102
-
103
- /**
104
- * @return array
105
- */
106
- protected function fetch_pool() {
107
- if ( false === self::$prefix_pool ) {
108
- $this->maybe_init_pool();
109
- }
110
-
111
- return self::$prefix_pool;
112
- }
113
-
114
- protected function maybe_init_pool() {
115
- self::$prefix_pool = get_transient( $this->pool_transient_name );
116
- if ( self::$prefix_pool === false ) {
117
- self::$prefix_pool = array();
118
- set_transient( $this->pool_transient_name, array() );
119
- }
120
- }
121
-
122
- /**
123
- * @param string $unique_root
124
- */
125
- protected function insert_root_in_pool( $unique_root ) {
126
- $prefix_pool = $this->fetch_pool();
127
- $prefix_pool[ $unique_root ] = $this->current_post->ID;
128
- self::$prefix_pool = $prefix_pool;
129
- set_transient( $this->pool_transient_name, $prefix_pool );
130
- }
131
-
132
- public static function reset_pool() {
133
- self::$prefix_pool = false;
134
- }
135
-
136
- /**
137
- * @param $post_name
138
- * @param $postfix
139
- *
140
- * @return string
141
- */
142
- protected function build_root_candidate( $post_name, $postfix ) {
143
- $frags = explode( '-', $post_name );
144
-
145
- $candidate = implode( '', array_map( 'strtoupper', $frags ) );
146
-
147
- if ( strlen( $candidate ) > 9 ) {
148
- $frags = array_filter( $frags );
149
- $candidate = implode( '', array_map( array( $this, 'uc_first_letter' ), $frags ) );
150
- }
151
-
152
- $candidate = $candidate . $postfix;
153
-
154
- return $candidate;
155
- }
156
-
157
- /**
158
- * Primes the post pool.
159
- *
160
- * @param array $pool
161
- * @param bool $override_transient If `true` the transient too will be overwritten.
162
- */
163
- public function set_pool( array $pool, $override_transient = false ) {
164
- self::$prefix_pool = $pool;
165
- if ( $override_transient ) {
166
- set_transient( $this->pool_transient_name, $pool );
167
- }
168
- }
169
-
170
- /**
171
- * Whether the pool transient has been primed or not.
172
- *
173
- * @return bool
174
- */
175
- public function is_primed() {
176
- return get_transient( $this->pool_transient_name ) !== false;
177
- }
178
-
179
- /**
180
- * @return array
181
- */
182
- public function get_pool() {
183
- return $this->fetch_pool();
184
- }
185
  }
1
+ <?php
2
+
3
+
4
+ class Tribe__Utils__Post_Root_Pool {
5
+
6
+ /**
7
+ * @var string
8
+ */
9
+ protected $pool_transient_name = 'tribe_ticket_prefix_pool';
10
+
11
+ /**
12
+ * @var array|bool
13
+ */
14
+ protected static $prefix_pool = false;
15
+
16
+ /**
17
+ * @var string
18
+ */
19
+ protected $root_separator = '-';
20
+
21
+ /**
22
+ * @var array
23
+ */
24
+ protected $postfix = 1;
25
+
26
+ /**
27
+ * @var WP_Post
28
+ */
29
+ protected $current_post = null;
30
+
31
+ /**
32
+ * Generates a unique root for a post using its post_name.
33
+ *
34
+ * @param WP_Post $post
35
+ *
36
+ * @return string
37
+ */
38
+ public function generate_unique_root( WP_Post $post ) {
39
+ $post_name = $post->post_name;
40
+
41
+ $this->current_post = $post;
42
+ $flipped_pool = array_flip( $this->fetch_pool() );
43
+
44
+ if ( isset( $flipped_pool[ $this->current_post->ID ] ) ) {
45
+ return $flipped_pool[ $this->current_post->ID ] . $this->root_separator;
46
+ }
47
+
48
+ $root = $this->build_root_from( $post_name );
49
+
50
+ return $root . $this->root_separator;
51
+ }
52
+
53
+ /**
54
+ * @param string $post_name
55
+ *
56
+ * @param string $postfix
57
+ *
58
+ * @return string
59
+ */
60
+ protected function build_root_from( $post_name, $postfix = '' ) {
61
+ $candidate = $this->build_root_candidate( $post_name, $postfix );
62
+
63
+ $initial_candidate = $candidate;
64
+
65
+ while ( $this->is_in_pool( $candidate ) ) {
66
+ $postfix = $this->postfix;
67
+ $candidate = $initial_candidate . '-' . $postfix;
68
+ $this->postfix ++;
69
+ }
70
+
71
+ $this->postfix = 1;
72
+
73
+ $this->insert_root_in_pool( $candidate );
74
+
75
+ return $candidate;
76
+ }
77
+
78
+ /**
79
+ * @return string
80
+ */
81
+ public function get_pool_transient_name() {
82
+ return $this->pool_transient_name;
83
+ }
84
+
85
+ /**
86
+ * @param $string
87
+ *
88
+ * @return string
89
+ */
90
+ protected function uc_first_letter( $string ) {
91
+ return is_numeric( $string ) ? $string : strtoupper( $string[0] );
92
+ }
93
+
94
+ /**
95
+ * @param string $candidate
96
+ */
97
+ protected function is_in_pool( $candidate ) {
98
+ $pool = $this->fetch_pool();
99
+
100
+ return isset( $pool[ $candidate ] );
101
+ }
102
+
103
+ /**
104
+ * @return array
105
+ */
106
+ protected function fetch_pool() {
107
+ if ( false === self::$prefix_pool ) {
108
+ $this->maybe_init_pool();
109
+ }
110
+
111
+ return self::$prefix_pool;
112
+ }
113
+
114
+ protected function maybe_init_pool() {
115
+ self::$prefix_pool = get_transient( $this->pool_transient_name );
116
+ if ( self::$prefix_pool === false ) {
117
+ self::$prefix_pool = array();
118
+ set_transient( $this->pool_transient_name, array() );
119
+ }
120
+ }
121
+
122
+ /**
123
+ * @param string $unique_root
124
+ */
125
+ protected function insert_root_in_pool( $unique_root ) {
126
+ $prefix_pool = $this->fetch_pool();
127
+ $prefix_pool[ $unique_root ] = $this->current_post->ID;
128
+ self::$prefix_pool = $prefix_pool;
129
+ set_transient( $this->pool_transient_name, $prefix_pool );
130
+ }
131
+
132
+ public static function reset_pool() {
133
+ self::$prefix_pool = false;
134
+ }
135
+
136
+ /**
137
+ * @param $post_name
138
+ * @param $postfix
139
+ *
140
+ * @return string
141
+ */
142
+ protected function build_root_candidate( $post_name, $postfix ) {
143
+ $frags = explode( '-', $post_name );
144
+
145
+ $candidate = implode( '', array_map( 'strtoupper', $frags ) );
146
+
147
+ if ( strlen( $candidate ) > 9 ) {
148
+ $frags = array_filter( $frags );
149
+ $candidate = implode( '', array_map( array( $this, 'uc_first_letter' ), $frags ) );
150
+ }
151
+
152
+ $candidate = $candidate . $postfix;
153
+
154
+ return $candidate;
155
+ }
156
+
157
+ /**
158
+ * Primes the post pool.
159
+ *
160
+ * @param array $pool
161
+ * @param bool $override_transient If `true` the transient too will be overwritten.
162
+ */
163
+ public function set_pool( array $pool, $override_transient = false ) {
164
+ self::$prefix_pool = $pool;
165
+ if ( $override_transient ) {
166
+ set_transient( $this->pool_transient_name, $pool );
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Whether the pool transient has been primed or not.
172
+ *
173
+ * @return bool
174
+ */
175
+ public function is_primed() {
176
+ return get_transient( $this->pool_transient_name ) !== false;
177
+ }
178
+
179
+ /**
180
+ * @return array
181
+ */
182
+ public function get_pool() {
183
+ return $this->fetch_pool();
184
+ }
185
  }
common/src/Tribe/Validate.php CHANGED
@@ -1,500 +1,500 @@
1
- <?php
2
-
3
- // Don't load directly
4
- if ( ! defined( 'ABSPATH' ) ) {
5
- die( '-1' );
6
- }
7
-
8
- if ( ! class_exists( 'Tribe__Validate' ) ) {
9
- /**
10
- * helper class that validates fields for use in Settings, MetaBoxes, Users, anywhere.
11
- * Instantiate whenever you want to validate a field
12
- *
13
- */
14
- class Tribe__Validate {
15
-
16
- /**
17
- * the field object to validate
18
- * @var array
19
- */
20
- public $field;
21
-
22
- /**
23
- * the field's value
24
- * @var mixed
25
- */
26
- public $value;
27
-
28
- /**
29
- * additional arguments for validation
30
- * used by some methods only
31
- * @var array
32
- */
33
- public $additional_args;
34
-
35
-
36
- /**
37
- * the field's label, used in error messages
38
- * @var string
39
- */
40
- public $label;
41
-
42
- /**
43
- * the type of validation to perform
44
- * @var string
45
- */
46
- public $type;
47
-
48
-
49
- /**
50
- * the result object of the validation
51
- * @var stdClass
52
- */
53
- public $result;
54
-
55
- /**
56
- * Class constructor
57
- *
58
- * @param string $field_id the field ID to validate
59
- * @param array $field_id the field object to validate
60
- * @param mixed $value the value to validate
61
- *
62
- * @return array $result the result of the validation
63
- */
64
- public function __construct( $field_id, $field, $value, $additional_args = array() ) {
65
-
66
- // prepare object properties
67
- $this->result = new stdClass;
68
- $this->field = $field;
69
- $this->field['id'] = $field_id;
70
- $this->value = $value;
71
- $this->additional_args = $additional_args;
72
-
73
- // if the field is invalid or incomplete, fail validation
74
- if ( ! is_array( $this->field ) || ( ! isset( $this->field['validation_type'] ) && ! isset( $this->field['validation_callback'] ) ) ) {
75
- $this->result->valid = false;
76
- $this->result->error = esc_html__( 'Invalid or incomplete field passed', 'tribe-common' );
77
- $this->result->error .= ( isset( $this->field['id'] ) ) ? ' (' . esc_html__( 'Field ID:', 'tribe-common' ) . ' ' . $this->field['id'] . ' )' : '';
78
-
79
- return $this->result;
80
- }
81
-
82
- // call validation callback if a validation callback function is set
83
- if ( isset( $this->field['validation_callback'] ) ) {
84
- if ( function_exists( $this->field['validation_callback'] ) ) {
85
- if ( ( ! isset( $_POST[ $field_id ] ) || ! $_POST[ $field_id ] || $_POST[ $field_id ] == '' ) && isset( $this->field['can_be_empty'] ) && $this->field['can_be_empty'] ) {
86
- $this->result->valid = true;
87
-
88
- return $this->result;
89
- } else {
90
- return call_user_func( $validation_callback );
91
- }
92
- }
93
- }
94
-
95
-
96
- if ( isset( $this->field['validation_type'] ) ) {
97
- if ( method_exists( $this, $this->field['validation_type'] ) ) {
98
- // make sure there's a field validation type set for this validation and that such method exists
99
- $this->type = $this->field['validation_type'];
100
- $this->label = isset( $this->field['label'] ) ? $this->field['label'] : $this->field['id'];
101
- if ( ( ! isset( $_POST[ $field_id ] ) || ! $_POST[ $field_id ] || $_POST[ $field_id ] == '' ) && isset( $this->field['can_be_empty'] ) && $this->field['can_be_empty'] ) {
102
- $this->result->valid = true;
103
-
104
- return $this->result;
105
- } else {
106
- call_user_func( array( $this, $this->type ) ); // run the validation
107
- }
108
- } else {
109
- // invalid validation type set, validation fails
110
- $this->result->valid = false;
111
- $this->result->error = esc_html__( 'Non-existant field validation function passed', 'tribe-common' );
112
- $this->result->error .= ( isset( $this->field['id'] ) ) ? ' (' . esc_html__( 'Field ID:', 'tribe-common' ) . ' ' . $this->field['id'] . ' ' . _x( 'with function name:', 'non-existant function name passed for field validation', 'tribe-common' ) . ' ' . $this->field['validation_type'] . ' )' : '';
113
- }
114
- } else {
115
- // no validation type set, validation fails
116
- $this->result->valid = false;
117
- $this->result->error = esc_html__( 'Invalid or incomplete field passed', 'tribe-common' );
118
- $this->result->error .= ( isset( $this->field['id'] ) ) ? ' (' . esc_html__( 'Field ID:', 'tribe-common' ) . ' ' . $this->field['id'] . ' )' : '';
119
- }
120
-
121
- // return the result
122
- return $this->result;
123
- }
124
-
125
- /**
126
- * validates a field as a string containing only letters and numbers
127
- *
128
- * @return stdClass validation result object
129
- */
130
- public function alpha_numeric() {
131
- if ( preg_match( '/^[a-zA-Z0-9]+$/', $this->value ) ) {
132
- $this->result->valid = true;
133
- } else {
134
- $this->result->valid = false;
135
- $this->result->error = sprintf( esc_html__( '%s must contain numbers and letters only', 'tribe-common' ), $this->label );
136
- }
137
- }
138
-
139
- /**
140
- * validates a field as a string containing only letters,
141
- * numbers and carriage returns
142
- *
143
- * @return stdClass validation result object
144
- */
145
- public function alpha_numeric_multi_line() {
146
- if ( preg_match( '/^[a-zA-Z0-9\s]+$/', $this->value ) ) {
147
- $this->result->valid = true;
148
- $this->value = tribe_multi_line_remove_empty_lines( $this->value );
149
- } else {
150
- $this->result->valid = false;
151
- $this->result->error = sprintf( esc_html__( '%s must contain numbers and letters only', 'tribe-common' ), $this->label );
152
- }
153
- }
154
-
155
- /**
156
- * Validates a field as a string containing only letters,
157
- * numbers, dots and carriage returns
158
- *
159
- * @return stdClass validation result object
160
- */
161
- public function alpha_numeric_multi_line_with_dots_and_dashes() {
162
- if ( preg_match( '/^[a-zA-Z0-9\s.-]+$/', $this->value ) ) {
163
- $this->result->valid = true;
164
- $this->value = tribe_multi_line_remove_empty_lines( $this->value );
165
- } else {
166
- $this->result->valid = false;
167
- $this->result->error = sprintf( esc_html__( '%s must contain numbers, letters and dots only', 'tribe-common' ), $this->label );
168
- }
169
- }
170
-
171
- /**
172
- * Validates a field as a string containing only letters,
173
- * numbers, dashes and underscores
174
- *
175
- * @return stdClass validation result object
176
- */
177
- public function alpha_numeric_with_dashes_and_underscores() {
178
- $this->value = trim( $this->value );
179
- if ( preg_match( '/^[a-zA-Z0-9_-]+$/', $this->value ) ) {
180
- $this->result->valid = true;
181
- } else {
182
- $this->result->valid = false;
183
- $this->result->error = sprintf( esc_html__( '%s must contain numbers, letters, dashes and undescores only', 'tribe-common' ), $this->label );
184
- }
185
- }
186
-
187
- /**
188
- * validates a field as being positive decimal
189
- *
190
- * @return stdClass validation result object
191
- */
192
- public function positive_decimal() {
193
- if ( preg_match( '/^[0-9]+(\.[0-9]+)?$/', $this->value ) && $this->value > 0 ) {
194
- $this->result->valid = true;
195
- } else {
196
- $this->result->valid = false;
197
- $this->result->error = sprintf( esc_html__( '%s must be a positive number.', 'tribe-common' ), $this->label );
198
- }
199
- }
200
-
201
- /**
202
- * validates a field as being positive decimal or percent
203
- *
204
- * @return stdClass validation result object
205
- */
206
- public function positive_decimal_or_percent() {
207
- if ( preg_match( '/^[0-9]+(\.[0-9]+)?%?$/', $this->value ) && $this->value > 0 ) {
208
- $this->result->valid = true;
209
- } else {
210
- $this->result->valid = false;
211
- $this->result->error = sprintf( esc_html__( '%s must be a positive number or percent.', 'tribe-common' ), $this->label );
212
- }
213
- }
214
-
215
- /**
216
- * validates a field as being positive integers
217
- *
218
- * @return stdClass validation result object
219
- */
220
- public function positive_int() {
221
- if ( preg_match( '/^[0-9]+$/', $this->value ) && $this->value > 0 ) {
222
- $this->result->valid = true;
223
- } else {
224
- $this->result->valid = false;
225
- $this->result->error = sprintf( esc_html__( '%s must be a positive number.', 'tribe-common' ), $this->label );
226
- }
227
- }
228
-
229
- /**
230
- * validates & sanitizes fields as URL slugs
231
- *
232
- * @return stdClass validation result object
233
- */
234
- public function slug() {
235
- if ( preg_match( '/^[a-zA-Z0-9-_]+$/', $this->value ) ) {
236
- $this->result->valid = true;
237
- $this->value = sanitize_title( $this->value );
238
- } else {
239
- $this->result->valid = false;
240
- $this->result->error = sprintf( esc_html__( '%s must be a valid slug (numbers, letters, dashes, and underscores).', 'tribe-common' ), $this->label );
241
- }
242
- }
243
-
244
- /**
245
- * validates & sanitizes fields as URLs
246
- *
247
- * @return stdClass validation result object
248
- */
249
- public function url() {
250
-
251
- if ( esc_url_raw( $this->value ) == $this->value ) {
252
- $this->result->valid = true;
253
- } else {
254
- $this->result->valid = false;
255
- $this->result->error = sprintf( esc_html__( '%s must be a valid absolute URL.', 'tribe-common' ), $this->label );
256
- }
257
- }
258
-
259
- /**
260
- * validates fields that have options (radios, dropdowns, etc.)
261
- * by making sure the value is part of the options array
262
- *
263
- * @return stdClass validation result object
264
- */
265
- public function options() {
266
- if ( array_key_exists( $this->value, $this->field['options'] ) ) {
267
- $this->value = ( $this->value === 0 ) ? false : $this->value;
268
- $this->result->valid = true;
269
- } else {
270
- $this->result->valid = false;
271
- $this->result->error = sprintf( esc_html__( "%s must have a value that's part of its options.", 'tribe-common' ), $this->label );
272
- }
273
- }
274
-
275
- /**
276
- * validates fields that have multiple options (checkbox list, etc.)
277
- * by making sure the value is part of the options array
278
- *
279
- * @return stdClass validation result object
280
- */
281
- public function options_multi() {
282
- foreach ( $this->value as $val ) {
283
- if ( array_key_exists( $val, $this->field['options'] ) ) {
284
- $this->value = ( $this->value === 0 ) ? false : $this->value;
285
- $this->result->valid = true;
286
- } else {
287
- $this->result->valid = false;
288
- $this->result->error = sprintf( esc_html__( "%s must have a value that's part of its options.", 'tribe-common' ), $this->label );
289
- }
290
- }
291
- }
292
-
293
- /**
294
- * validates fields that have options (radios, dropdowns, etc.)
295
- * by making sure the value is part of the options array
296
- * then combines the value into an array containg the value
297
- * and name from the option
298
- *
299
- * @return stdClass validation result object
300
- */
301
- public function options_with_label() {
302
- if ( array_key_exists( $this->value, $this->field['options'] ) ) {
303
- $this->value = ( $this->value === 0 ) ? false : array(
304
- $this->value,
305
- $this->field['options'][ $this->value ],
306
- );
307
- $this->result->valid = true;
308
- } else {
309
- $this->result->valid = false;
310
- $this->result->error = sprintf( esc_html__( "%s must have a value that's part of its options.", 'tribe-common' ), $this->label );
311
- }
312
- }
313
-
314
- /**
315
- * validates a field as not being able to be the same
316
- * as the specified value as specified in
317
- * $this->additional_args['compare_name']
318
- *
319
- * @return stdClass validation result object
320
- */
321
- public function cannot_be_the_same_as() {
322
- if ( ! isset( $this->additional_args['compare'] ) ) {
323
- $this->result->valid = false;
324
- $this->result->error = sprintf( esc_html__( 'Comparison validation failed because no comparison value was provided, for field %s', 'tribe-common' ), $this->field['id'] );
325
- } else {
326
- if ( $this->value != $this->additional_args['compare'] ) {
327
- $this->result = true;
328
- } else {
329
- $this->result->valid = false;
330
- if ( isset( $this->additional_args['compare_name'] ) ) {
331
- $this->result->error = sprintf( esc_html__( '%s cannot be the same as %s.', 'tribe-common' ), $this->label, $this->additional_args['compare_name'] );
332
- } else {
333
- $this->result->error = sprintf( esc_html__( '%s cannot be a duplicate', 'tribe-common' ), $this->label );
334
- }
335
- }
336
- }
337
- }
338
-
339
- /**
340
- * validates a field as being a number or a percentage
341
- *
342
- * @return stdClass validation result object
343
- */
344
- public function number_or_percent() {
345
- if ( preg_match( '/^[0-9]+%{0,1}$/', $this->value ) ) {
346
- $this->result->valid = true;
347
- } else {
348
- $this->result->valid = false;
349
- $this->result->error = sprintf( esc_html__( '%s must be a number or percentage.', 'tribe-common' ), $this->label );
350
- }
351
- }
352
-
353
- /**
354
- * sanitizes an html field
355
- *
356
- * @return stdClass validation result object
357
- */
358
- public function html() {
359
- $this->value = balanceTags( $this->value );
360
- $this->result->valid = true;
361
- }
362
-
363
- /**
364
- * sanitizes a license key
365
- *
366
- * @return stdClass validation result object
367
- */
368
- public function license_key() {
369
- $this->value = trim( $this->value );
370
- $this->result->valid = true;
371
- }
372
-
373
- /**
374
- * sanitizes a textarea field
375
- *
376
- * @return stdClass validation result object
377
- */
378
- public function textarea() {
379
- $this->value = wp_kses( $this->value, array() );
380
- $this->result->valid = true;
381
- }
382
-
383
- /**
384
- * sanitizes a field as beeing a boolean
385
- *
386
- * @return stdClass validation result object
387
- */
388
- public function boolean() {
389
- $this->value = (bool) $this->value;
390
- $this->result->valid = true;
391
- }
392
-
393
- /**
394
- * validates a Google Maps Zoom field
395
- *
396
- * @return stdClass validation result object
397
- */
398
- public function google_maps_zoom() {
399
- if ( preg_match( '/^([0-9]|[0-1][0-9]|2[0-1])$/', $this->value ) ) {
400
- $this->result->valid = true;
401
- } else {
402
- $this->result->valid = false;
403
- $this->result->error = sprintf( esc_html__( '%s must be a number between 0 and 21.', 'tribe-common' ), $this->label );
404
- }
405
- }
406
-
407
- /**
408
- * validates a field as being part of an address
409
- * allows for letters, numbers, dashses and spaces only
410
- *
411
- * @return stdClass validation result object
412
- */
413
- public function address() {
414
- $this->value = stripslashes( $this->value );
415
- if ( preg_match( "/^[0-9\S '-]+$/", $this->value ) ) {
416
- $this->result->valid = true;
417
- } else {
418
- $this->result->valid = false;
419
- $this->result->error = sprintf( esc_html__( '%s must consist of letters, numbers, dashes, apostrophes, and spaces only.', 'tribe-common' ), $this->label );
420
- }
421
- }
422
-
423
- /**
424
- * validates a field as being a city or province
425
- * allows for letters, dashses and spaces only
426
- *
427
- * @return stdClass validation result object
428
- */
429
- public function city_or_province() {
430
- $this->value = stripslashes( $this->value );
431
- if ( preg_match( "/^[\D '\-]+$/", $this->value ) ) {
432
- $this->result->valid = true;
433
- } else {
434
- $this->result->valid = false;
435
- $this->result->error = sprintf( esc_html__( '%s must consist of letters, spaces, apostrophes, and dashes.', 'tribe-common' ), $this->label );
436
- }
437
- }
438
-
439
- /**
440
- * validates a field as being a zip code
441
- *
442
- * @return stdClass validation result object
443
- */
444
- public function zip() {
445
- if ( preg_match( '/^[0-9]{5}$/', $this->value ) ) {
446
- $this->result->valid = true;
447
- } else {
448
- $this->result->valid = false;
449
- $this->result->error = sprintf( esc_html__( '%s must consist of 5 numbers.', 'tribe-common' ), $this->label );
450
- }
451
- }
452
-
453
- /**
454
- * validates a field as being a phone number
455
- *
456
- * @return stdClass validation result object
457
- */
458
- public function phone() {
459
- if ( preg_match( '/^[0-9\(\)\+ -]+$/', $this->value ) ) {
460
- $this->result->valid = true;
461
- } else {
462
- $this->result->valid = false;
463
- $this->result->error = sprintf( esc_html__( '%s must be a phone number.', 'tribe-common' ), $this->label );
464
- }
465
- }
466
-
467
- /**
468
- * validates & sanitizes a field as being a country list
469
- *
470
- * @return stdClass validation result object
471
- */
472
- public function country_list() {
473
- $country_rows = explode( "\n", $this->value );
474
- if ( is_array( $country_rows ) ) {
475
- foreach ( $country_rows as $crow ) {
476
- $country = explode( ',', $crow );
477
- if ( ! isset( $country[0] ) || ! isset( $country[1] ) ) {
478
- $this->result->valid = false;
479
- $this->result->error = sprintf( esc_html__( 'Country List must be formatted as one country per line in the following format: <br>US, United States <br> UK, United Kingdom.', 'tribe-common' ), $this->label );
480
- $this->value = wp_kses( $this->value, array() );
481
-
482
- return;
483
- }
484
- }
485
- }
486
- $this->result->valid = true;
487
- }
488
-
489
- /**
490
- * automatically validate a field regardless of the value
491
- * Don't use this unless you know what you are doing
492
- *
493
- * @return stdClass validation result object
494
- */
495
- public function none() {
496
- $this->result->valid = true;
497
- }
498
-
499
- } // end class
500
- } // endif class_exists
1
+ <?php
2
+
3
+ // Don't load directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ die( '-1' );
6
+ }
7
+
8
+ if ( ! class_exists( 'Tribe__Validate' ) ) {
9
+ /**
10
+ * helper class that validates fields for use in Settings, MetaBoxes, Users, anywhere.
11
+ * Instantiate whenever you want to validate a field
12
+ *
13
+ */
14
+ class Tribe__Validate {
15
+
16
+ /**
17
+ * the field object to validate
18
+ * @var array
19
+ */
20
+ public $field;
21
+
22
+ /**
23
+ * the field's value
24
+ * @var mixed
25
+ */
26
+ public $value;
27
+
28
+ /**
29
+ * additional arguments for validation
30
+ * used by some methods only
31
+ * @var array
32
+ */
33
+ public $additional_args;
34
+
35
+
36
+ /**
37
+ * the field's label, used in error messages
38
+ * @var string
39
+ */
40
+ public $label;
41
+
42
+ /**
43
+ * the type of validation to perform
44
+ * @var string
45
+ */
46
+ public $type;
47
+
48
+
49
+ /**
50
+ * the result object of the validation
51
+ * @var stdClass
52
+ */
53
+ public $result;
54
+
55
+ /**
56
+ * Class constructor
57
+ *
58
+ * @param string $field_id the field ID to validate
59
+ * @param array $field_id the field object to validate
60
+ * @param mixed $value the value to validate
61
+ *
62
+ * @return array $result the result of the validation
63
+ */
64
+ public function __construct( $field_id, $field, $value, $additional_args = array() ) {
65
+
66
+ // prepare object properties
67
+ $this->result = new stdClass;
68
+ $this->field = $field;
69
+ $this->field['id'] = $field_id;
70
+ $this->value = $value;
71
+ $this->additional_args = $additional_args;
72
+
73
+ // if the field is invalid or incomplete, fail validation
74
+ if ( ! is_array( $this->field ) || ( ! isset( $this->field['validation_type'] ) && ! isset( $this->field['validation_callback'] ) ) ) {
75
+ $this->result->valid = false;
76
+ $this->result->error = esc_html__( 'Invalid or incomplete field passed', 'tribe-common' );
77
+ $this->result->error .= ( isset( $this->field['id'] ) ) ? ' (' . esc_html__( 'Field ID:', 'tribe-common' ) . ' ' . $this->field['id'] . ' )' : '';
78
+
79
+ return $this->result;
80
+ }
81
+
82
+ // call validation callback if a validation callback function is set
83
+ if ( isset( $this->field['validation_callback'] ) ) {
84
+ if ( function_exists( $this->field['validation_callback'] ) ) {
85
+ if ( ( ! isset( $_POST[ $field_id ] ) || ! $_POST[ $field_id ] || $_POST[ $field_id ] == '' ) && isset( $this->field['can_be_empty'] ) && $this->field['can_be_empty'] ) {
86
+ $this->result->valid = true;
87
+
88
+ return $this->result;
89
+ } else {
90
+ return call_user_func( $validation_callback );
91
+ }
92
+ }
93
+ }
94
+
95
+
96
+ if ( isset( $this->field['validation_type'] ) ) {
97
+ if ( method_exists( $this, $this->field['validation_type'] ) ) {
98
+ // make sure there's a field validation type set for this validation and that such method exists
99
+ $this->type = $this->field['validation_type'];
100
+ $this->label = isset( $this->field['label'] ) ? $this->field['label'] : $this->field['id'];
101
+ if ( ( ! isset( $_POST[ $field_id ] ) || ! $_POST[ $field_id ] || $_POST[ $field_id ] == '' ) && isset( $this->field['can_be_empty'] ) && $this->field['can_be_empty'] ) {
102
+ $this->result->valid = true;
103
+
104
+ return $this->result;
105
+ } else {
106
+ call_user_func( array( $this, $this->type ) ); // run the validation
107
+ }
108
+ } else {
109
+ // invalid validation type set, validation fails
110
+ $this->result->valid = false;
111
+ $this->result->error = esc_html__( 'Non-existant field validation function passed', 'tribe-common' );
112
+ $this->result->error .= ( isset( $this->field['id'] ) ) ? ' (' . esc_html__( 'Field ID:', 'tribe-common' ) . ' ' . $this->field['id'] . ' ' . _x( 'with function name:', 'non-existant function name passed for field validation', 'tribe-common' ) . ' ' . $this->field['validation_type'] . ' )' : '';
113
+ }
114
+ } else {
115
+ // no validation type set, validation fails
116
+ $this->result->valid = false;
117
+ $this->result->error = esc_html__( 'Invalid or incomplete field passed', 'tribe-common' );
118
+ $this->result->error .= ( isset( $this->field['id'] ) ) ? ' (' . esc_html__( 'Field ID:', 'tribe-common' ) . ' ' . $this->field['id'] . ' )' : '';
119
+ }
120
+
121
+ // return the result
122
+ return $this->result;
123
+ }
124
+
125
+ /**
126
+ * validates a field as a string containing only letters and numbers
127
+ *
128
+ * @return stdClass validation result object
129
+ */
130
+ public function alpha_numeric() {
131
+ if ( preg_match( '/^[a-zA-Z0-9]+$/', $this->value ) ) {
132
+ $this->result->valid = true;
133
+ } else {
134
+ $this->result->valid = false;
135
+ $this->result->error = sprintf( esc_html__( '%s must contain numbers and letters only', 'tribe-common' ), $this->label );
136
+ }
137
+ }
138
+
139
+ /**
140
+ * validates a field as a string containing only letters,
141
+ * numbers and carriage returns
142
+ *
143
+ * @return stdClass validation result object
144
+ */
145
+ public function alpha_numeric_multi_line() {
146
+ if ( preg_match( '/^[a-zA-Z0-9\s]+$/', $this->value ) ) {
147
+ $this->result->valid = true;
148
+ $this->value = tribe_multi_line_remove_empty_lines( $this->value );
149
+ } else {
150
+ $this->result->valid = false;
151
+ $this->result->error = sprintf( esc_html__( '%s must contain numbers and letters only', 'tribe-common' ), $this->label );
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Validates a field as a string containing only letters,
157
+ * numbers, dots and carriage returns
158
+ *
159
+ * @return stdClass validation result object
160
+ */
161
+ public function alpha_numeric_multi_line_with_dots_and_dashes() {
162
+ if ( preg_match( '/^[a-zA-Z0-9\s.-]+$/', $this->value ) ) {
163
+ $this->result->valid = true;
164
+ $this->value = tribe_multi_line_remove_empty_lines( $this->value );
165
+ } else {
166
+ $this->result->valid = false;
167
+ $this->result->error = sprintf( esc_html__( '%s must contain numbers, letters and dots only', 'tribe-common' ), $this->label );
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Validates a field as a string containing only letters,
173
+ * numbers, dashes and underscores
174
+ *
175
+ * @return stdClass validation result object
176
+ */
177
+ public function alpha_numeric_with_dashes_and_underscores() {
178
+ $this->value = trim( $this->value );
179
+ if ( preg_match( '/^[a-zA-Z0-9_-]+$/', $this->value ) ) {
180
+ $this->result->valid = true;
181
+ } else {
182
+ $this->result->valid = false;
183
+ $this->result->error = sprintf( esc_html__( '%s must contain numbers, letters, dashes and undescores only', 'tribe-common' ), $this->label );
184
+ }
185
+ }
186
+
187
+ /**
188
+ * validates a field as being positive decimal
189
+ *
190
+ * @return stdClass validation result object
191
+ */
192
+ public function positive_decimal() {
193
+ if ( preg_match( '/^[0-9]+(\.[0-9]+)?$/', $this->value ) && $this->value > 0 ) {
194
+ $this->result->valid = true;
195
+ } else {
196
+ $this->result->valid = false;
197
+ $this->result->error = sprintf( esc_html__( '%s must be a positive number.', 'tribe-common' ), $this->label );
198
+ }
199
+ }
200
+
201
+ /**
202
+ * validates a field as being positive decimal or percent
203
+ *
204
+ * @return stdClass validation result object
205
+ */
206
+ public function positive_decimal_or_percent() {
207
+ if ( preg_match( '/^[0-9]+(\.[0-9]+)?%?$/', $this->value ) && $this->value > 0 ) {
208
+ $this->result->valid = true;
209
+ } else {
210
+ $this->result->valid = false;
211
+ $this->result->error = sprintf( esc_html__( '%s must be a positive number or percent.', 'tribe-common' ), $this->label );
212
+ }
213
+ }
214
+
215
+ /**
216
+ * validates a field as being positive integers
217
+ *
218
+ * @return stdClass validation result object
219
+ */
220
+ public function positive_int() {
221
+ if ( preg_match( '/^[0-9]+$/', $this->value ) && $this->value > 0 ) {
222
+ $this->result->valid = true;
223
+ } else {
224
+ $this->result->valid = false;
225
+ $this->result->error = sprintf( esc_html__( '%s must be a positive number.', 'tribe-common' ), $this->label );
226
+ }
227
+ }
228
+
229
+ /**
230
+ * validates & sanitizes fields as URL slugs
231
+ *
232
+ * @return stdClass validation result object
233
+ */
234
+ public function slug() {
235
+ if ( preg_match( '/^[a-zA-Z0-9-_]+$/', $this->value ) ) {
236
+ $this->result->valid = true;
237
+ $this->value = sanitize_title( $this->value );
238
+ } else {
239
+ $this->result->valid = false;
240
+ $this->result->error = sprintf( esc_html__( '%s must be a valid slug (numbers, letters, dashes, and underscores).', 'tribe-common' ), $this->label );
241
+ }
242
+ }
243
+
244
+ /**
245
+ * validates & sanitizes fields as URLs
246
+ *
247
+ * @return stdClass validation result object
248
+ */
249
+ public function url() {
250
+
251
+ if ( esc_url_raw( $this->value ) == $this->value ) {
252
+ $this->result->valid = true;
253
+ } else {
254
+ $this->result->valid = false;
255
+ $this->result->error = sprintf( esc_html__( '%s must be a valid absolute URL.', 'tribe-common' ), $this->label );
256
+ }
257
+ }
258
+
259
+ /**
260
+ * validates fields that have options (radios, dropdowns, etc.)
261
+ * by making sure the value is part of the options array
262
+ *
263
+ * @return stdClass validation result object
264
+ */
265
+ public function options() {
266
+ if ( array_key_exists( $this->value, $this->field['options'] ) ) {
267
+ $this->value = ( $this->value === 0 ) ? false : $this->value;
268
+ $this->result->valid = true;
269
+ } else {
270
+ $this->result->valid = false;
271
+ $this->result->error = sprintf( esc_html__( "%s must have a value that's part of its options.", 'tribe-common' ), $this->label );
272
+ }
273
+ }
274
+
275
+ /**
276
+ * validates fields that have multiple options (checkbox list, etc.)
277
+ * by making sure the value is part of the options array
278
+ *
279
+ * @return stdClass validation result object
280
+ */
281
+ public function options_multi() {
282
+ foreach ( $this->value as $val ) {
283
+ if ( array_key_exists( $val, $this->field['options'] ) ) {
284
+ $this->value = ( $this->value === 0 ) ? false : $this->value;
285
+ $this->result->valid = true;
286
+ } else {
287
+ $this->result->valid = false;
288
+ $this->result->error = sprintf( esc_html__( "%s must have a value that's part of its options.", 'tribe-common' ), $this->label );
289
+ }
290
+ }
291
+ }
292
+
293
+ /**
294
+ * validates fields that have options (radios, dropdowns, etc.)
295
+ * by making sure the value is part of the options array
296
+ * then combines the value into an array containg the value
297
+ * and name from the option
298
+ *
299
+ * @return stdClass validation result object
300
+ */
301
+ public function options_with_label() {
302
+ if ( array_key_exists( $this->value, $this->field['options'] ) ) {
303
+ $this->value = ( $this->value === 0 ) ? false : array(
304
+ $this->value,
305
+ $this->field['options'][ $this->value ],
306
+ );
307
+ $this->result->valid = true;
308
+ } else {
309
+ $this->result->valid = false;
310
+ $this->result->error = sprintf( esc_html__( "%s must have a value that's part of its options.", 'tribe-common' ), $this->label );
311
+ }
312
+ }
313
+
314
+ /**
315
+ * validates a field as not being able to be the same
316
+ * as the specified value as specified in
317
+ * $this->additional_args['compare_name']
318
+ *
319
+ * @return stdClass validation result object
320
+ */
321
+ public function cannot_be_the_same_as() {
322
+ if ( ! isset( $this->additional_args['compare'] ) ) {
323
+ $this->result->valid = false;
324
+ $this->result->error = sprintf( esc_html__( 'Comparison validation failed because no comparison value was provided, for field %s', 'tribe-common' ), $this->field['id'] );
325
+ } else {
326
+ if ( $this->value != $this->additional_args['compare'] ) {
327
+ $this->result = true;
328
+ } else {
329
+ $this->result->valid = false;
330
+ if ( isset( $this->additional_args['compare_name'] ) ) {
331
+ $this->result->error = sprintf( esc_html__( '%s cannot be the same as %s.', 'tribe-common' ), $this->label, $this->additional_args['compare_name'] );
332
+ } else {
333
+ $this->result->error = sprintf( esc_html__( '%s cannot be a duplicate', 'tribe-common' ), $this->label );
334
+ }
335
+ }
336
+ }
337
+ }
338
+
339
+ /**
340
+ * validates a field as being a number or a percentage
341
+ *
342
+ * @return stdClass validation result object
343
+ */
344
+ public function number_or_percent() {
345
+ if ( preg_match( '/^[0-9]+%{0,1}$/', $this->value ) ) {
346
+ $this->result->valid = true;
347
+ } else {
348
+ $this->result->valid = false;
349
+ $this->result->error = sprintf( esc_html__( '%s must be a number or percentage.', 'tribe-common' ), $this->label );
350
+ }
351
+ }
352
+
353
+ /**
354
+ * sanitizes an html field
355
+ *
356
+ * @return stdClass validation result object
357
+ */
358
+ public function html() {
359
+ $this->value = balanceTags( $this->value );
360
+ $this->result->valid = true;
361
+ }
362
+
363
+ /**
364
+ * sanitizes a license key
365
+ *
366
+ * @return stdClass validation result object
367
+ */
368
+ public function license_key() {
369
+ $this->value = trim( $this->value );
370
+ $this->result->valid = true;
371
+ }
372
+
373
+ /**
374
+ * sanitizes a textarea field
375
+ *
376
+ * @return stdClass validation result object
377
+ */
378
+ public function textarea() {
379
+ $this->value = wp_kses( $this->value, array() );
380
+ $this->result->valid = true;
381
+ }
382
+
383
+ /**
384
+ * sanitizes a field as beeing a boolean
385
+ *
386
+ * @return stdClass validation result object
387
+ */
388
+ public function boolean() {
389
+ $this->value = (bool) $this->value;
390
+ $this->result->valid = true;
391
+ }
392
+
393
+ /**
394
+ * validates a Google Maps Zoom field
395
+ *
396
+ * @return stdClass validation result object
397
+ */
398
+ public function google_maps_zoom() {
399
+ if ( preg_match( '/^([0-9]|[0-1][0-9]|2[0-1])$/', $this->value ) ) {
400
+ $this->result->valid = true;
401
+ } else {
402
+ $this->result->valid = false;
403
+ $this->result->error = sprintf( esc_html__( '%s must be a number between 0 and 21.', 'tribe-common' ), $this->label );
404
+ }
405
+ }
406
+
407
+ /**
408
+ * validates a field as being part of an address
409
+ * allows for letters, numbers, dashses and spaces only
410
+ *
411
+ * @return stdClass validation result object
412
+ */
413
+ public function address() {
414
+ $this->value = stripslashes( $this->value );
415
+ if ( preg_match( "/^[0-9\S '-]+$/", $this->value ) ) {
416
+ $this->result->valid = true;
417
+ } else {
418
+ $this->result->valid = false;
419
+ $this->result->error = sprintf( esc_html__( '%s must consist of letters, numbers, dashes, apostrophes, and spaces only.', 'tribe-common' ), $this->label );
420
+ }
421
+ }
422
+
423
+ /**
424
+ * validates a field as being a city or province
425
+ * allows for letters, dashses and spaces only
426
+ *
427
+ * @return stdClass validation result object
428
+ */
429
+ public function city_or_province() {
430
+ $this->value = stripslashes( $this->value );
431
+ if ( preg_match( "/^[\D '\-]+$/", $this->value ) ) {
432
+ $this->result->valid = true;
433
+ } else {
434
+ $this->result->valid = false;
435
+ $this->result->error = sprintf( esc_html__( '%s must consist of letters, spaces, apostrophes, and dashes.', 'tribe-common' ), $this->label );
436
+ }
437
+ }
438
+
439
+ /**
440
+ * validates a field as being a zip code
441
+ *
442
+ * @return stdClass validation result object
443
+ */
444
+ public function zip() {
445
+ if ( preg_match( '/^[0-9]{5}$/', $this->value ) ) {
446
+ $this->result->valid = true;
447
+ } else {
448
+ $this->result->valid = false;
449
+ $this->result->error = sprintf( esc_html__( '%s must consist of 5 numbers.', 'tribe-common' ), $this->label );
450
+ }
451
+ }
452
+
453
+ /**
454
+ * validates a field as being a phone number
455
+ *
456
+ * @return stdClass validation result object
457
+ */
458
+ public function phone() {
459
+ if ( preg_match( '/^[0-9\(\)\+ -]+$/', $this->value ) ) {
460
+ $this->result->valid = true;
461
+ } else {
462
+ $this->result->valid = false;
463
+ $this->result->error = sprintf( esc_html__( '%s must be a phone number.', 'tribe-common' ), $this->label );
464
+ }
465
+ }
466
+
467
+ /**
468
+ * validates & sanitizes a field as being a country list
469
+ *
470
+ * @return stdClass validation result object
471
+ */
472
+ public function country_list() {
473
+ $country_rows = explode( "\n", $this->value );
474
+ if ( is_array( $country_rows ) ) {
475
+ foreach ( $country_rows as $crow ) {
476
+ $country = explode( ',', $crow );
477
+ if ( ! isset( $country[0] ) || ! isset( $country[1] ) ) {
478
+ $this->result->valid = false;
479
+ $this->result->error = sprintf( esc_html__( 'Country List must be formatted as one country per line in the following format: <br>US, United States <br> UK, United Kingdom.', 'tribe-common' ), $this->label );
480
+ $this->value = wp_kses( $this->value, array() );
481
+
482
+ return;
483
+ }
484
+ }
485
+ }
486
+ $this->result->valid = true;
487
+ }
488
+
489
+ /**
490
+ * automatically validate a field regardless of the value
491
+ * Don't use this unless you know what you are doing
492
+ *
493
+ * @return stdClass validation result object
494
+ */
495
+ public function none() {
496
+ $this->result->valid = true;
497
+ }
498
+
499
+ } // end class
500
+ } // endif class_exists
common/src/Tribe/View_Helpers.php CHANGED
@@ -1,617 +1,617 @@
1
- <?php
2
- /**
3
- * Various helper methods used in views
4
- */
5
-
6
- // Don't load directly
7
- if ( ! defined( 'ABSPATH' ) ) {
8
- die( '-1' );
9
- }
10
-
11
- if ( ! class_exists( 'Tribe__View_Helpers' ) ) {
12
- class Tribe__View_Helpers {
13
-
14
- /**
15
- * Get the countries being used and available for the plugin.
16
- *
17
- * @param string $postId The post ID.
18
- * @param bool $useDefault Should we use the defaults?
19
- *
20
- * @return array The countries array.
21
- */
22
- public static function constructCountries( $postId = '', $useDefault = true ) {
23
-
24
- if ( tribe_get_option( 'tribeEventsCountries' ) != '' ) {
25
- $countries = array(
26
- '' => esc_html__( 'Select a Country:', 'tribe-common' ),
27
- );
28
-
29
- $country_rows = explode( "\n", tribe_get_option( 'tribeEventsCountries' ) );
30
- foreach ( $country_rows as $crow ) {
31
- $country = explode( ',', $crow );
32
- if ( isset( $country[0] ) && isset( $country[1] ) ) {
33
- $country[0] = trim( $country[0] );
34
- $country[1] = trim( $country[1] );
35
-
36
- if ( $country[0] && $country[1] ) {
37
- $countries[ $country[0] ] = $country[1];
38
- }
39
- }
40
- }
41
- }
42
-
43
- if ( ! isset( $countries ) || ! is_array( $countries ) || count( $countries ) == 1 ) {
44
- $countries = array(
45
- '' => esc_html__( 'Select a Country:', 'tribe-common' ),
46
- 'US' => esc_html__( 'United States', 'tribe-common' ),
47
- 'AF' => esc_html__( 'Afghanistan', 'tribe-common' ),
48
- 'AL' => esc_html__( 'Albania', 'tribe-common' ),
49
- 'DZ' => esc_html__( 'Algeria', 'tribe-common' ),
50
- 'AS' => esc_html__( 'American Samoa', 'tribe-common' ),
51
- 'AD' => esc_html__( 'Andorra', 'tribe-common' ),
52
- 'AO' => esc_html__( 'Angola', 'tribe-common' ),
53
- 'AI' => esc_html__( 'Anguilla', 'tribe-common' ),
54
- 'AQ' => esc_html__( 'Antarctica', 'tribe-common' ),
55
- 'AG' => esc_html__( 'Antigua And Barbuda', 'tribe-common' ),
56
- 'AR' => esc_html__( 'Argentina', 'tribe-common' ),
57
- 'AM' => esc_html__( 'Armenia', 'tribe-common' ),
58
- 'AW' => esc_html__( 'Aruba', 'tribe-common' ),
59
- 'AU' => esc_html__( 'Australia', 'tribe-common' ),
60
- 'AT' => esc_html__( 'Austria', 'tribe-common' ),
61
- 'AZ' => esc_html__( 'Azerbaijan', 'tribe-common' ),
62
- 'BS' => esc_html__( 'Bahamas', 'tribe-common' ),
63
- 'BH' => esc_html__( 'Bahrain', 'tribe-common' ),
64
- 'BD' => esc_html__( 'Bangladesh', 'tribe-common' ),
65
- 'BB' => esc_html__( 'Barbados', 'tribe-common' ),
66
- 'BY' => esc_html__( 'Belarus', 'tribe-common' ),
67
- 'BE' => esc_html__( 'Belgium', 'tribe-common' ),
68
- 'BZ' => esc_html__( 'Belize', 'tribe-common' ),
69
- 'BJ' => esc_html__( 'Benin', 'tribe-common' ),
70
- 'BM' => esc_html__( 'Bermuda', 'tribe-common' ),
71
- 'BT' => esc_html__( 'Bhutan', 'tribe-common' ),
72
- 'BO' => esc_html__( 'Bolivia', 'tribe-common' ),
73
- 'BA' => esc_html__( 'Bosnia And Herzegowina', 'tribe-common' ),
74
- 'BW' => esc_html__( 'Botswana', 'tribe-common' ),
75
- 'BV' => esc_html__( 'Bouvet Island', 'tribe-common' ),
76
- 'BR' => esc_html__( 'Brazil', 'tribe-common' ),
77
- 'IO' => esc_html__( 'British Indian Ocean Territory', 'tribe-common' ),
78
- 'BN' => esc_html__( 'Brunei Darussalam', 'tribe-common' ),
79
- 'BG' => esc_html__( 'Bulgaria', 'tribe-common' ),
80
- 'BF' => esc_html__( 'Burkina Faso', 'tribe-common' ),
81
- 'BI' => esc_html__( 'Burundi', 'tribe-common' ),
82
- 'KH' => esc_html__( 'Cambodia', 'tribe-common' ),
83
- 'CM' => esc_html__( 'Cameroon', 'tribe-common' ),
84
- 'CA' => esc_html__( 'Canada', 'tribe-common' ),
85
- 'CV' => esc_html__( 'Cape Verde', 'tribe-common' ),
86
- 'KY' => esc_html__( 'Cayman Islands', 'tribe-common' ),
87
- 'CF' => esc_html__( 'Central African Republic', 'tribe-common' ),
88
- 'TD' => esc_html__( 'Chad', 'tribe-common' ),
89
- 'CL' => esc_html__( 'Chile', 'tribe-common' ),
90
- 'CN' => esc_html__( 'China', 'tribe-common' ),
91
- 'CX' => esc_html__( 'Christmas Island', 'tribe-common' ),
92
- 'CC' => esc_html__( 'Cocos (Keeling) Islands', 'tribe-common' ),
93
- 'CO' => esc_html__( 'Colombia', 'tribe-common' ),
94
- 'KM' => esc_html__( 'Comoros', 'tribe-common' ),
95
- 'CG' => esc_html__( 'Congo', 'tribe-common' ),
96
- 'CD' => esc_html__( 'Congo, The Democratic Republic Of The', 'tribe-common' ),
97
- 'CK' => esc_html__( 'Cook Islands', 'tribe-common' ),
98
- 'CR' => esc_html__( 'Costa Rica', 'tribe-common' ),
99
- 'CI' => esc_html__( "Cote D'Ivoire", 'tribe-common' ),
100
- 'HR' => esc_html__( 'Croatia (Local Name: Hrvatska)', 'tribe-common' ),
101
- 'CU' => esc_html__( 'Cuba', 'tribe-common' ),
102
- 'CY' => esc_html__( 'Cyprus', 'tribe-common' ),
103
- 'CZ' => esc_html__( 'Czech Republic', 'tribe-common' ),
104
- 'DK' => esc_html__( 'Denmark', 'tribe-common' ),
105
- 'DJ' => esc_html__( 'Djibouti', 'tribe-common' ),
106
- 'DM' => esc_html__( 'Dominica', 'tribe-common' ),
107
- 'DO' => esc_html__( 'Dominican Republic', 'tribe-common' ),
108
- 'TP' => esc_html__( 'East Timor', 'tribe-common' ),
109
- 'EC' => esc_html__( 'Ecuador', 'tribe-common' ),
110
- 'EG' => esc_html__( 'Egypt', 'tribe-common' ),
111
- 'SV' => esc_html__( 'El Salvador', 'tribe-common' ),
112
- 'GQ' => esc_html__( 'Equatorial Guinea', 'tribe-common' ),
113
- 'ER' => esc_html__( 'Eritrea', 'tribe-common' ),
114
- 'EE' => esc_html__( 'Estonia', 'tribe-common' ),
115
- 'ET' => esc_html__( 'Ethiopia', 'tribe-common' ),
116
- 'FK' => esc_html__( 'Falkland Islands (Malvinas)', 'tribe-common' ),
117
- 'FO' => esc_html__( 'Faroe Islands', 'tribe-common' ),
118
- 'FJ' => esc_html__( 'Fiji', 'tribe-common' ),
119
- 'FI' => esc_html__( 'Finland', 'tribe-common' ),
120
- 'FR' => esc_html__( 'France', 'tribe-common' ),
121
- 'FX' => esc_html__( 'France, Metropolitan', 'tribe-common' ),
122
- 'GF' => esc_html__( 'French Guiana', 'tribe-common' ),
123
- 'PF' => esc_html__( 'French Polynesia', 'tribe-common' ),
124
- 'TF' => esc_html__( 'French Southern Territories', 'tribe-common' ),
125
- 'GA' => esc_html__( 'Gabon', 'tribe-common' ),
126
- 'GM' => esc_html__( 'Gambia', 'tribe-common' ),
127
- 'GE' => esc_html__( 'Georgia', 'tribe-common' ),
128
- 'DE' => esc_html__( 'Germany', 'tribe-common' ),
129
- 'GH' => esc_html__( 'Ghana', 'tribe-common' ),
130
- 'GI' => esc_html__( 'Gibraltar', 'tribe-common' ),
131
- 'GR' => esc_html__( 'Greece', 'tribe-common' ),
132
- 'GL' => esc_html__( 'Greenland', 'tribe-common' ),
133
- 'GD' => esc_html__( 'Grenada', 'tribe-common' ),
134
- 'GP' => esc_html__( 'Guadeloupe', 'tribe-common' ),
135
- 'GU' => esc_html__( 'Guam', 'tribe-common' ),
136
- 'GT' => esc_html__( 'Guatemala', 'tribe-common' ),
137
- 'GN' => esc_html__( 'Guinea', 'tribe-common' ),
138
- 'GW' => esc_html__( 'Guinea-Bissau', 'tribe-common' ),
139
- 'GY' => esc_html__( 'Guyana', 'tribe-common' ),
140
- 'HT' => esc_html__( 'Haiti', 'tribe-common' ),
141
- 'HM' => esc_html__( 'Heard And Mc Donald Islands', 'tribe-common' ),
142
- 'VA' => esc_html__( 'Holy See (Vatican City State)', 'tribe-common' ),
143
- 'HN' => esc_html__( 'Honduras', 'tribe-common' ),
144
- 'HK' => esc_html__( 'Hong Kong', 'tribe-common' ),
145
- 'HU' => esc_html__( 'Hungary', 'tribe-common' ),
146
- 'IS' => esc_html__( 'Iceland', 'tribe-common' ),
147
- 'IN' => esc_html__( 'India', 'tribe-common' ),
148
- 'ID' => esc_html__( 'Indonesia', 'tribe-common' ),
149
- 'IR' => esc_html__( 'Iran (Islamic Republic Of)', 'tribe-common' ),
150
- 'IQ' => esc_html__( 'Iraq', 'tribe-common' ),
151
- 'IE' => esc_html__( 'Ireland', 'tribe-common' ),
152
- 'IL' => esc_html__( 'Israel', 'tribe-common' ),
153
- 'IT' => esc_html__( 'Italy', 'tribe-common' ),
154
- 'JM' => esc_html__( 'Jamaica', 'tribe-common' ),
155
- 'JP' => esc_html__( 'Japan', 'tribe-common' ),
156
- 'JO' => esc_html__( 'Jordan', 'tribe-common' ),
157
- 'KZ' => esc_html__( 'Kazakhstan', 'tribe-common' ),
158
- 'KE' => esc_html__( 'Kenya', 'tribe-common' ),
159
- 'KI' => esc_html__( 'Kiribati', 'tribe-common' ),
160
- 'KP' => esc_html__( "Korea, Democratic People's Republic Of", 'tribe-common' ),
161
- 'KR' => esc_html__( 'Korea, Republic Of', 'tribe-common' ),
162
- 'KW' => esc_html__( 'Kuwait', 'tribe-common' ),
163
- 'KG' => esc_html__( 'Kyrgyzstan', 'tribe-common' ),
164
- 'LA' => esc_html__( "Lao People's Democratic Republic", 'tribe-common' ),
165
- 'LV' => esc_html__( 'Latvia', 'tribe-common' ),
166
- 'LB' => esc_html__( 'Lebanon', 'tribe-common' ),
167
- 'LS' => esc_html__( 'Lesotho', 'tribe-common' ),
168
- 'LR' => esc_html__( 'Liberia', 'tribe-common' ),
169
- 'LY' => esc_html__( 'Libya', 'tribe-common' ),
170
- 'LI' => esc_html__( 'Liechtenstein', 'tribe-common' ),
171
- 'LT' => esc_html__( 'Lithuania', 'tribe-common' ),
172
- 'LU' => esc_html__( 'Luxembourg', 'tribe-common' ),
173
- 'MO' => esc_html__( 'Macau', 'tribe-common' ),
174
- 'MK' => esc_html__( 'Macedonia', 'tribe-common' ),
175
- 'MG' => esc_html__( 'Madagascar', 'tribe-common' ),
176
- 'MW' => esc_html__( 'Malawi', 'tribe-common' ),
177
- 'MY' => esc_html__( 'Malaysia', 'tribe-common' ),
178
- 'MV' => esc_html__( 'Maldives', 'tribe-common' ),
179
- 'ML' => esc_html__( 'Mali', 'tribe-common' ),
180
- 'MT' => esc_html__( 'Malta', 'tribe-common' ),
181
- 'MH' => esc_html__( 'Marshall Islands', 'tribe-common' ),
182
- 'MQ' => esc_html__( 'Martinique', 'tribe-common' ),
183
- 'MR' => esc_html__( 'Mauritania', 'tribe-common' ),
184
- 'MU' => esc_html__( 'Mauritius', 'tribe-common' ),
185
- 'YT' => esc_html__( 'Mayotte', 'tribe-common' ),
186
- 'MX' => esc_html__( 'Mexico', 'tribe-common' ),
187
- 'FM' => esc_html__( 'Micronesia, Federated States Of', 'tribe-common' ),
188
- 'MD' => esc_html__( 'Moldova, Republic Of', 'tribe-common' ),
189
- 'MC' => esc_html__( 'Monaco', 'tribe-common' ),
190
- 'MN' => esc_html__( 'Mongolia', 'tribe-common' ),
191
- 'ME' => esc_html__( 'Montenegro', 'tribe-common' ),
192
- 'MS' => esc_html__( 'Montserrat', 'tribe-common' ),
193
- 'MA' => esc_html__( 'Morocco', 'tribe-common' ),
194
- 'MZ' => esc_html__( 'Mozambique', 'tribe-common' ),
195
- 'MM' => esc_html__( 'Myanmar', 'tribe-common' ),
196
- 'NA' => esc_html__( 'Namibia', 'tribe-common' ),
197
- 'NR' => esc_html__( 'Nauru', 'tribe-common' ),
198
- 'NP' => esc_html__( 'Nepal', 'tribe-common' ),
199
- 'NL' => esc_html__( 'Netherlands', 'tribe-common' ),
200
- 'AN' => esc_html__( 'Netherlands Antilles', 'tribe-common' ),
201
- 'NC' => esc_html__( 'New Caledonia', 'tribe-common' ),
202
- 'NZ' => esc_html__( 'New Zealand', 'tribe-common' ),
203
- 'NI' => esc_html__( 'Nicaragua', 'tribe-common' ),
204
- 'NE' => esc_html__( 'Niger', 'tribe-common' ),
205
- 'NG' => esc_html__( 'Nigeria', 'tribe-common' ),
206
- 'NU' => esc_html__( 'Niue', 'tribe-common' ),
207
- 'NF' => esc_html__( 'Norfolk Island', 'tribe-common' ),
208
- 'MP' => esc_html__( 'Northern Mariana Islands', 'tribe-common' ),
209
- 'NO' => esc_html__( 'Norway', 'tribe-common' ),
210
- 'OM' => esc_html__( 'Oman', 'tribe-common' ),
211
- 'PK' => esc_html__( 'Pakistan', 'tribe-common' ),
212
- 'PW' => esc_html__( 'Palau', 'tribe-common' ),
213
- 'PA' => esc_html__( 'Panama', 'tribe-common' ),
214
- 'PG' => esc_html__( 'Papua New Guinea', 'tribe-common' ),
215
- 'PY' => esc_html__( 'Paraguay', 'tribe-common' ),
216
- 'PE' => esc_html__( 'Peru', 'tribe-common' ),
217
- 'PH' => esc_html__( 'Philippines', 'tribe-common' ),
218
- 'PN' => esc_html__( 'Pitcairn', 'tribe-common' ),
219
- 'PL' => esc_html__( 'Poland', 'tribe-common' ),
220
- 'PT' => esc_html__( 'Portugal', 'tribe-common' ),
221
- 'PR' => esc_html__( 'Puerto Rico', 'tribe-common' ),
222
- 'QA' => esc_html__( 'Qatar', 'tribe-common' ),
223
- 'RE' => esc_html__( 'Reunion', 'tribe-common' ),
224
- 'RO' => esc_html__( 'Romania', 'tribe-common' ),
225
- 'RU' => esc_html__( 'Russian Federation', 'tribe-common' ),
226
- 'RW' => esc_html__( 'Rwanda', 'tribe-common' ),
227
- 'KN' => esc_html__( 'Saint Kitts And Nevis', 'tribe-common' ),
228
- 'LC' => esc_html__( 'Saint Lucia', 'tribe-common' ),
229
- 'VC' => esc_html__( 'Saint Vincent And The Grenadines', 'tribe-common' ),
230
- 'WS' => esc_html__( 'Samoa', 'tribe-common' ),
231
- 'SM' => esc_html__( 'San Marino', 'tribe-common' ),
232
- 'ST' => esc_html__( 'Sao Tome And Principe', 'tribe-common' ),
233
- 'SA' => esc_html__( 'Saudi Arabia', 'tribe-common' ),
234
- 'SN' => esc_html__( 'Senegal', 'tribe-common' ),
235
- 'RS' => esc_html__( 'Serbia', 'tribe-common' ),
236
- 'SC' => esc_html__( 'Seychelles', 'tribe-common' ),
237
- 'SL' => esc_html__( 'Sierra Leone', 'tribe-common' ),
238
- 'SG' => esc_html__( 'Singapore', 'tribe-common' ),
239
- 'SK' => esc_html__( 'Slovakia (Slovak Republic)', 'tribe-common' ),
240
- 'SI' => esc_html__( 'Slovenia', 'tribe-common' ),
241
- 'SB' => esc_html__( 'Solomon Islands', 'tribe-common' ),
242
- 'SO' => esc_html__( 'Somalia', 'tribe-common' ),
243
- 'ZA' => esc_html__( 'South Africa', 'tribe-common' ),
244
- 'GS' => esc_html__( 'South Georgia, South Sandwich Islands', 'tribe-common' ),
245
- 'ES' => esc_html__( 'Spain', 'tribe-common' ),
246
- 'LK' => esc_html__( 'Sri Lanka', 'tribe-common' ),
247
- 'SH' => esc_html__( 'St. Helena', 'tribe-common' ),
248
- 'PM' => esc_html__( 'St. Pierre And Miquelon', 'tribe-common' ),
249
- 'SD' => esc_html__( 'Sudan', 'tribe-common' ),
250
- 'SR' => esc_html__( 'Suriname', 'tribe-common' ),
251
- 'SJ' => esc_html__( 'Svalbard And Jan Mayen Islands', 'tribe-common' ),
252
- 'SZ' => esc_html__( 'Swaziland', 'tribe-common' ),
253
- 'SE' => esc_html__( 'Sweden', 'tribe-common' ),
254
- 'CH' => esc_html__( 'Switzerland', 'tribe-common' ),
255
- 'SY' => esc_html__( 'Syrian Arab Republic', 'tribe-common' ),
256
- 'TW' => esc_html__( 'Taiwan', 'tribe-common' ),
257
- 'TJ' => esc_html__( 'Tajikistan', 'tribe-common' ),
258
- 'TZ' => esc_html__( 'Tanzania, United Republic Of', 'tribe-common' ),
259
- 'TH' => esc_html__( 'Thailand', 'tribe-common' ),
260
- 'TG' => esc_html__( 'Togo', 'tribe-common' ),
261
- 'TK' => esc_html__( 'Tokelau', 'tribe-common' ),
262
- 'TO' => esc_html__( 'Tonga', 'tribe-common' ),
263
- 'TT' => esc_html__( 'Trinidad And Tobago', 'tribe-common' ),
264
- 'TN' => esc_html__( 'Tunisia', 'tribe-common' ),
265
- 'TR' => esc_html__( 'Turkey', 'tribe-common' ),
266
- 'TM' => esc_html__( 'Turkmenistan', 'tribe-common' ),
267
- 'TC' => esc_html__( 'Turks And Caicos Islands', 'tribe-common' ),
268
- 'TV' => esc_html__( 'Tuvalu', 'tribe-common' ),
269
- 'UG' => esc_html__( 'Uganda', 'tribe-common' ),
270
- 'UA' => esc_html__( 'Ukraine', 'tribe-common' ),
271
- 'AE' => esc_html__( 'United Arab Emirates', 'tribe-common' ),
272
- 'GB' => esc_html__( 'United Kingdom', 'tribe-common' ),
273
- 'UM' => esc_html__( 'United States Minor Outlying Islands', 'tribe-common' ),
274
- 'UY' => esc_html__( 'Uruguay', 'tribe-common' ),
275
- 'UZ' => esc_html__( 'Uzbekistan', 'tribe-common' ),
276
- 'VU' => esc_html__( 'Vanuatu', 'tribe-common' ),
277
- 'VE' => esc_html__( 'Venezuela', 'tribe-common' ),
278
- 'VN' => esc_html__( 'Viet Nam', 'tribe-common' ),
279
- 'VG' => esc_html__( 'Virgin Islands (British)', 'tribe-common' ),
280
- 'VI' => esc_html__( 'Virgin Islands (U.S.)', 'tribe-common' ),
281
- 'WF' => esc_html__( 'Wallis And Futuna Islands', 'tribe-common' ),
282
- 'EH' => esc_html__( 'Western Sahara', 'tribe-common' ),
283
- 'YE' => esc_html__( 'Yemen', 'tribe-common' ),
284
- 'ZM' => esc_html__( 'Zambia', 'tribe-common' ),
285
- 'ZW' => esc_html__( 'Zimbabwe', 'tribe-common' ),
286
- );
287
- }
288
- if ( ( $postId || $useDefault ) ) {
289
- $countryValue = get_post_meta( $postId, '_EventCountry', true );
290
- if ( $countryValue ) {
291
- $defaultCountry = array( array_search( $countryValue, $countries ), $countryValue );
292
- } else {
293
- $defaultCountry = tribe_get_default_value( 'country' );
294
- }
295
- if ( $defaultCountry && $defaultCountry[0] != '' ) {
296
- $selectCountry = array_shift( $countries );
297
- asort( $countries );
298
- $countries = array( $defaultCountry[0] => __( $defaultCountry[1], 'tribe-common' ) ) + $countries;
299
- $countries = array( '' => __( $selectCountry, 'tribe-common' ) ) + $countries;
300
- array_unique( $countries );
301
- }
302
-
303
- return $countries;
304
- } else {
305
- return $countries;
306
- }
307
- }
308
-
309
- /**
310
- * Get the i18ned states available to the plugin.
311
- *
312
- * @return array The states array.
313
- */
314
- public static function loadStates() {
315
- return array(
316
- 'AL' => esc_html__( 'Alabama', 'tribe-common' ),
317
- 'AK' => esc_html__( 'Alaska', 'tribe-common' ),
318
- 'AZ' => esc_html__( 'Arizona', 'tribe-common' ),
319
- 'AR' => esc_html__( 'Arkansas', 'tribe-common' ),
320
- 'CA' => esc_html__( 'California', 'tribe-common' ),
321
- 'CO' => esc_html__( 'Colorado', 'tribe-common' ),
322
- 'CT' => esc_html__( 'Connecticut', 'tribe-common' ),
323
- 'DE' => esc_html__( 'Delaware', 'tribe-common' ),
324
- 'DC' => esc_html__( 'District of Columbia', 'tribe-common' ),
325
- 'FL' => esc_html__( 'Florida', 'tribe-common' ),
326
- 'GA' => esc_html__( 'Georgia', 'tribe-common' ),
327
- 'HI' => esc_html__( 'Hawaii', 'tribe-common' ),
328
- 'ID' => esc_html__( 'Idaho', 'tribe-common' ),
329
- 'IL' => esc_html__( 'Illinois', 'tribe-common' ),
330
- 'IN' => esc_html__( 'Indiana', 'tribe-common' ),
331
- 'IA' => esc_html__( 'Iowa', 'tribe-common' ),
332
- 'KS' => esc_html__( 'Kansas', 'tribe-common' ),
333
- 'KY' => esc_html__( 'Kentucky', 'tribe-common' ),
334
- 'LA' => esc_html__( 'Louisiana', 'tribe-common' ),
335
- 'ME' => esc_html__( 'Maine', 'tribe-common' ),
336
- 'MD' => esc_html__( 'Maryland', 'tribe-common' ),
337
- 'MA' => esc_html__( 'Massachusetts', 'tribe-common' ),
338
- 'MI' => esc_html__( 'Michigan', 'tribe-common' ),
339
- 'MN' => esc_html__( 'Minnesota', 'tribe-common' ),
340
- 'MS' => esc_html__( 'Mississippi', 'tribe-common' ),
341
- 'MO' => esc_html__( 'Missouri', 'tribe-common' ),
342
- 'MT' => esc_html__( 'Montana', 'tribe-common' ),
343
- 'NE' => esc_html__( 'Nebraska', 'tribe-common' ),
344
- 'NV' => esc_html__( 'Nevada', 'tribe-common' ),
345
- 'NH' => esc_html__( 'New Hampshire', 'tribe-common' ),
346
- 'NJ' => esc_html__( 'New Jersey', 'tribe-common' ),
347
- 'NM' => esc_html__( 'New Mexico', 'tribe-common' ),
348
- 'NY' => esc_html__( 'New York', 'tribe-common' ),
349
- 'NC' => esc_html__( 'North Carolina', 'tribe-common' ),
350
- 'ND' => esc_html__( 'North Dakota', 'tribe-common' ),
351
- 'OH' => esc_html__( 'Ohio', 'tribe-common' ),
352
- 'OK' => esc_html__( 'Oklahoma', 'tribe-common' ),
353
- 'OR' => esc_html__( 'Oregon', 'tribe-common' ),
354
- 'PA' => esc_html__( 'Pennsylvania', 'tribe-common' ),
355
- 'RI' => esc_html__( 'Rhode Island', 'tribe-common' ),
356
- 'SC' => esc_html__( 'South Carolina', 'tribe-common' ),
357
- 'SD' => esc_html__( 'South Dakota', 'tribe-common' ),
358
- 'TN' => esc_html__( 'Tennessee', 'tribe-common' ),
359
- 'TX' => esc_html__( 'Texas', 'tribe-common' ),
360
- 'UT' => esc_html__( 'Utah', 'tribe-common' ),
361
- 'VT' => esc_html__( 'Vermont', 'tribe-common' ),
362
- 'VA' => esc_html__( 'Virginia', 'tribe-common' ),
363
- 'WA' => esc_html__( 'Washington', 'tribe-common' ),
364
- 'WV' => esc_html__( 'West Virginia', 'tribe-common' ),
365
- 'WI' => esc_html__( 'Wisconsin', 'tribe-common' ),
366
- 'WY' => esc_html__( 'Wyoming', 'tribe-common' ),
367
- );
368
- }
369
-
370
- /**
371
- * Builds a set of options for displaying an hour chooser
372
- *
373
- * @param string $date the current date (optional)
374
- * @param bool $isStart
375
- *
376
- * @return string a set of HTML options with hours (current hour selected)
377
- */
378
- public static function getHourOptions( $date = '', $isStart = false ) {
379
- $hours = self::hours();
380
-
381
- if ( count( $hours ) == 12 ) {
382
- $h = 'h';
383
- } else {
384
- $h = 'H';
385
- }
386
- $options = '';
387
-
388
- if ( empty( $date ) ) {
389
- $hour = ( $isStart ) ? '08' : ( count( $hours ) == 12 ? '05' : '17' );
390
- } else {
391
- $timestamp = strtotime( $date );
392
- $hour = date( $h, $timestamp );
393
- // fix hours if time_format has changed from what is saved
394
- if ( preg_match( '(pm|PM)', $timestamp ) && $h == 'H' ) {
395
- $hour = $hour + 12;
396
- }
397
- if ( $hour > 12 && $h == 'h' ) {
398
- $hour = $hour - 12;
399
- }
400
- }
401
-
402
- $hour = apply_filters( 'tribe_get_hour_options', $hour, $date, $isStart );
403
-
404
- foreach ( $hours as $hourText ) {
405
- if ( $hour == $hourText ) {
406
- $selected = 'selected="selected"';
407
- } else {
408
- $selected = '';
409
- }
410
- $options .= "<option value='$hourText' $selected>$hourText</option>\n";
411
- }
412
-
413
- return $options;
414
- }
415
-
416
- /**
417
- * Builds a set of options for displaying a minute chooser
418
- *
419
- * @param string $date the current date (optional)
420
- * @param bool $isStart
421
- *
422
- * @return string a set of HTML options with minutes (current minute selected)
423
- */
424
- public static function getMinuteOptions( $date = '', $isStart = false ) {
425
- $options = '';
426
-
427
- if ( empty( $date ) ) {
428
- $minute = '00';
429
- } else {
430
- $minute = date( 'i', strtotime( $date ) );
431
- }
432
-
433
- $minute = apply_filters( 'tribe_get_minute_options', $minute, $date, $isStart );
434
- $minutes = self::minutes( $minute );
435
-
436
- foreach ( $minutes as $minuteText ) {
437
- if ( $minute == $minuteText ) {
438
- $selected = 'selected="selected"';
439
- } else {
440
- $selected = '';
441
- }
442
- $options .= "<option value='$minuteText' $selected>$minuteText</option>\n";
443
- }
444
-
445
- return $options;
446
- }
447
-
448
- /**
449
- * Helper method to return an array of 1-12 for hours
450
- *
451
- * @return array The hours array.
452
- */
453
- private static function hours() {
454
- $hours = array();
455
- $rangeMax = self::is_24hr_format() ? 23 : 12;
456
- $rangeStart = $rangeMax > 12 ? 0 : 1;
457
- foreach ( range( $rangeStart, $rangeMax ) as $hour ) {
458
- if ( $hour < 10 ) {
459
- $hour = '0' . $hour;
460
- }
461
- $hours[ $hour ] = $hour;
462
- }
463
-
464
- // In a 12hr context lets put 12 at the start (so the sequence will run 12, 1, 2, 3 ... 11)
465
- if ( 12 === $rangeMax ) {
466
- array_unshift( $hours, array_pop( $hours ) );
467
- }
468
-
469
- return $hours;
470
- }
471
-
472
- /**
473
- * Determines if the provided date/time format (or else the default WordPress time_format)
474
- * is 24hr or not.
475
- *
476
- * In inconclusive cases, such as if there are now hour-format characters, 12hr format is
477
- * assumed.
478
- *
479
- * @param null $format
480
- * @return bool
481
- */
482
- public static function is_24hr_format( $format = null ) {
483
- // Use the provided format or else use the value of the current time_format setting
484
- $format = ( null === $format ) ? get_option( 'time_format', Tribe__Date_Utils::TIMEFORMAT ) : $format;
485
-
486
- // Count instances of the H and G symbols
487
- $h_symbols = substr_count( $format, 'H' );
488
- $g_symbols = substr_count( $format, 'G' );
489
-
490
- // If none have been found then consider the format to be 12hr
491
- if ( ! $h_symbols && ! $g_symbols ) return false;
492
-
493
- // It's possible H or G have been included as escaped characters
494
- $h_escaped = substr_count( $format, '\H' );
495
- $g_escaped = substr_count( $format, '\G' );
496
-
497
- // Final check, accounting for possibility of escaped values
498
- return ( $h_symbols > $h_escaped || $g_symbols > $g_escaped );
499
- }
500
-
501
- /**
502
- * Helper method to return an array of 00-59 for minutes
503
- *
504
- * @param int $exact_minute optionally specify an exact minute to be included (outwith the default intervals)
505
- *
506
- * @return array The minutes array.
507
- */
508
- private static function minutes( $exact_minute = 0 ) {
509
- $minutes = array();
510
-
511
- // The exact minute should be an absint between 0 and 59
512
- $exact_minute = absint( $exact_minute );
513
-
514
- if ( $exact_minute < 0 || $exact_minute > 59 ) {
515
- $exact_minute = 0;
516
- }
517
-
518
- /**
519
- * Filters the amount of minutes to increment the minutes drop-down by
520
- *
521
- * @param int Increment amount (defaults to 5)
522
- */
523
- $default_increment = apply_filters( 'tribe_minutes_increment', 5 );
524
-
525
- // Unless an exact minute has been specified we can minimize the amount of looping we do
526
- $increment = ( 0 === $exact_minute ) ? $default_increment : 1;
527
-
528
- for ( $minute = 0; $minute < 60; $minute += $increment ) {
529
- // Skip if this $minute doesn't meet the increment pattern and isn't an additional exact minute
530
- if ( 0 !== $minute % $default_increment && $exact_minute !== $minute ) {
531
- continue;
532
- }
533
-
534
- if ( $minute < 10 ) {
535
- $minute = '0' . $minute;
536
- }
537
- $minutes[ $minute ] = $minute;
538
- }
539
-
540
- return $minutes;
541
- }
542
-
543
- /**
544
- * Builds a set of options for diplaying a meridian chooser
545
- *
546
- * @param string $date YYYY-MM-DD HH:MM:SS to select (optional)
547
- * @param bool $isStart
548
- *
549
- * @return string a set of HTML options with all meridians
550
- */
551
- public static function getMeridianOptions( $date = '', $isStart = false ) {
552
- if ( strstr( get_option( 'time_format', Tribe__Date_Utils::TIMEFORMAT ), 'A' ) ) {
553
- $a = 'A';
554
- $meridians = array( 'AM', 'PM' );
555
- } else {
556
- $a = 'a';
557
- $meridians = array( 'am', 'pm' );
558
- }
559
- if ( empty( $date ) ) {
560
- $meridian = ( $isStart ) ? $meridians[0] : $meridians[1];
561
- } else {
562
- $meridian = date( $a, strtotime( $date ) );
563
- }
564
-
565
- $meridian = apply_filters( 'tribe_get_meridian_options', $meridian, $date, $isStart );
566
-
567
- $return = '';
568
- foreach ( $meridians as $m ) {
569
- $return .= "<option value='$m'";
570
- if ( $m == $meridian ) {
571
- $return .= ' selected="selected"';
572
- }
573
- $return .= ">$m</option>\n";
574
- }
575
-
576
- return $return;
577
- }
578
-
579
- /**
580
- * Helper method to return an array of years
581
- * default is back 5 and forward 5
582
- *
583
- * @return array The array of years.
584
- */
585
- private static function years() {
586
- $current_year = (int) date_i18n( 'Y' );
587
- $years_back = (int) apply_filters( 'tribe_years_to_go_back', 5, $current_year );
588
- $years_forward = (int) apply_filters( 'tribe_years_to_go_forward', 5, $current_year );
589
- $years = array();
590
- for ( $i = $years_back; $i > 0; $i -- ) {
591
- $year = $current_year - $i;
592
- $years[] = $year;
593
- }
594
- $years[] = $current_year;
595
- for ( $i = 1; $i <= $years_forward; $i ++ ) {
596
- $year = $current_year + $i;
597
- $years[] = $year;
598
- }
599
-
600
- return (array) apply_filters( 'tribe_years_array', $years );
601
- }
602
-
603
- /**
604
- * Helper method to return an array of 1-31 for days
605
- *
606
- * @return array The days array.
607
- */
608
- public static function days( $totalDays ) {
609
- $days = array();
610
- foreach ( range( 1, $totalDays ) as $day ) {
611
- $days[ $day ] = $day;
612
- }
613
-
614
- return $days;
615
- }
616
- }
617
- }
1
+ <?php
2
+ /**
3
+ * Various helper methods used in views
4
+ */
5
+
6
+ // Don't load directly
7
+ if ( ! defined( 'ABSPATH' ) ) {
8
+ die( '-1' );
9
+ }
10
+
11
+ if ( ! class_exists( 'Tribe__View_Helpers' ) ) {
12
+ class Tribe__View_Helpers {
13
+
14
+ /**
15
+ * Get the countries being used and available for the plugin.
16
+ *
17
+ * @param string $postId The post ID.
18
+ * @param bool $useDefault Should we use the defaults?
19
+ *
20
+ * @return array The countries array.
21
+ */
22
+ public static function constructCountries( $postId = '', $useDefault = true ) {
23
+
24
+ if ( tribe_get_option( 'tribeEventsCountries' ) != '' ) {
25
+ $countries = array(
26
+ '' => esc_html__( 'Select a Country:', 'tribe-common' ),
27
+ );
28
+
29
+ $country_rows = explode( "\n", tribe_get_option( 'tribeEventsCountries' ) );
30
+ foreach ( $country_rows as $crow ) {
31
+ $country = explode( ',', $crow );
32
+ if ( isset( $country[0] ) && isset( $country[1] ) ) {
33
+ $country[0] = trim( $country[0] );
34
+ $country[1] = trim( $country[1] );
35
+
36
+ if ( $country[0] && $country[1] ) {
37
+ $countries[ $country[0] ] = $country[1];
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ if ( ! isset( $countries ) || ! is_array( $countries ) || count( $countries ) == 1 ) {
44
+ $countries = array(
45
+ '' => esc_html__( 'Select a Country:', 'tribe-common' ),
46
+ 'US' => esc_html__( 'United States', 'tribe-common' ),
47
+ 'AF' => esc_html__( 'Afghanistan', 'tribe-common' ),
48
+ 'AL' => esc_html__( 'Albania', 'tribe-common' ),
49
+ 'DZ' => esc_html__( 'Algeria', 'tribe-common' ),
50
+ 'AS' => esc_html__( 'American Samoa', 'tribe-common' ),
51
+ 'AD' => esc_html__( 'Andorra', 'tribe-common' ),
52
+ 'AO' => esc_html__( 'Angola', 'tribe-common' ),
53
+ 'AI' => esc_html__( 'Anguilla', 'tribe-common' ),
54
+ 'AQ' => esc_html__( 'Antarctica', 'tribe-common' ),
55
+ 'AG' => esc_html__( 'Antigua And Barbuda', 'tribe-common' ),
56
+ 'AR' => esc_html__( 'Argentina', 'tribe-common' ),
57
+ 'AM' => esc_html__( 'Armenia', 'tribe-common' ),
58
+ 'AW' => esc_html__( 'Aruba', 'tribe-common' ),
59
+ 'AU' => esc_html__( 'Australia', 'tribe-common' ),
60
+ 'AT' => esc_html__( 'Austria', 'tribe-common' ),
61
+ 'AZ' => esc_html__( 'Azerbaijan', 'tribe-common' ),
62
+ 'BS' => esc_html__( 'Bahamas', 'tribe-common' ),
63
+ 'BH' => esc_html__( 'Bahrain', 'tribe-common' ),
64
+ 'BD' => esc_html__( 'Bangladesh', 'tribe-common' ),
65
+ 'BB' => esc_html__( 'Barbados', 'tribe-common' ),
66
+ 'BY' => esc_html__( 'Belarus', 'tribe-common' ),
67
+ 'BE' => esc_html__( 'Belgium', 'tribe-common' ),
68
+ 'BZ' => esc_html__( 'Belize', 'tribe-common' ),
69
+ 'BJ' => esc_html__( 'Benin', 'tribe-common' ),
70
+ 'BM' => esc_html__( 'Bermuda', 'tribe-common' ),
71
+ 'BT' => esc_html__( 'Bhutan', 'tribe-common' ),
72
+ 'BO' => esc_html__( 'Bolivia', 'tribe-common' ),
73
+ 'BA' => esc_html__( 'Bosnia And Herzegowina', 'tribe-common' ),
74
+ 'BW' => esc_html__( 'Botswana', 'tribe-common' ),
75
+ 'BV' => esc_html__( 'Bouvet Island', 'tribe-common' ),
76
+ 'BR' => esc_html__( 'Brazil', 'tribe-common' ),
77
+ 'IO' => esc_html__( 'British Indian Ocean Territory', 'tribe-common' ),
78
+ 'BN' => esc_html__( 'Brunei Darussalam', 'tribe-common' ),
79
+ 'BG' => esc_html__( 'Bulgaria', 'tribe-common' ),
80
+ 'BF' => esc_html__( 'Burkina Faso', 'tribe-common' ),
81
+ 'BI' => esc_html__( 'Burundi', 'tribe-common' ),
82
+ 'KH' => esc_html__( 'Cambodia', 'tribe-common' ),
83
+ 'CM' => esc_html__( 'Cameroon', 'tribe-common' ),
84
+ 'CA' => esc_html__( 'Canada', 'tribe-common' ),
85
+ 'CV' => esc_html__( 'Cape Verde', 'tribe-common' ),
86
+ 'KY' => esc_html__( 'Cayman Islands', 'tribe-common' ),
87
+ 'CF' => esc_html__( 'Central African Republic', 'tribe-common' ),
88
+ 'TD' => esc_html__( 'Chad', 'tribe-common' ),
89
+ 'CL' => esc_html__( 'Chile', 'tribe-common' ),
90
+ 'CN' => esc_html__( 'China', 'tribe-common' ),
91
+ 'CX' => esc_html__( 'Christmas Island', 'tribe-common' ),
92
+ 'CC' => esc_html__( 'Cocos (Keeling) Islands', 'tribe-common' ),
93
+ 'CO' => esc_html__( 'Colombia', 'tribe-common' ),
94
+ 'KM' => esc_html__( 'Comoros', 'tribe-common' ),
95
+ 'CG' => esc_html__( 'Congo', 'tribe-common' ),
96
+ 'CD' => esc_html__( 'Congo, The Democratic Republic Of The', 'tribe-common' ),
97
+ 'CK' => esc_html__( 'Cook Islands', 'tribe-common' ),
98
+ 'CR' => esc_html__( 'Costa Rica', 'tribe-common' ),
99
+ 'CI' => esc_html__( "Cote D'Ivoire", 'tribe-common' ),
100
+ 'HR' => esc_html__( 'Croatia (Local Name: Hrvatska)', 'tribe-common' ),
101
+ 'CU' => esc_html__( 'Cuba', 'tribe-common' ),
102
+ 'CY' => esc_html__( 'Cyprus', 'tribe-common' ),
103
+ 'CZ' => esc_html__( 'Czech Republic', 'tribe-common' ),
104
+ 'DK' => esc_html__( 'Denmark', 'tribe-common' ),
105
+ 'DJ' => esc_html__( 'Djibouti', 'tribe-common' ),
106
+ 'DM' => esc_html__( 'Dominica', 'tribe-common' ),
107
+ 'DO' => esc_html__( 'Dominican Republic', 'tribe-common' ),
108
+ 'TP' => esc_html__( 'East Timor', 'tribe-common' ),
109
+ 'EC' => esc_html__( 'Ecuador', 'tribe-common' ),
110
+ 'EG' => esc_html__( 'Egypt', 'tribe-common' ),
111
+ 'SV' => esc_html__( 'El Salvador', 'tribe-common' ),
112
+ 'GQ' => esc_html__( 'Equatorial Guinea', 'tribe-common' ),
113
+ 'ER' => esc_html__( 'Eritrea', 'tribe-common' ),
114
+ 'EE' => esc_html__( 'Estonia', 'tribe-common' ),
115
+ 'ET' => esc_html__( 'Ethiopia', 'tribe-common' ),
116
+ 'FK' => esc_html__( 'Falkland Islands (Malvinas)', 'tribe-common' ),
117
+ 'FO' => esc_html__( 'Faroe Islands', 'tribe-common' ),
118
+ 'FJ' => esc_html__( 'Fiji', 'tribe-common' ),
119
+ 'FI' => esc_html__( 'Finland', 'tribe-common' ),
120
+ 'FR' => esc_html__( 'France', 'tribe-common' ),
121
+ 'FX' => esc_html__( 'France, Metropolitan', 'tribe-common' ),
122
+ 'GF' => esc_html__( 'French Guiana', 'tribe-common' ),
123
+ 'PF' => esc_html__( 'French Polynesia', 'tribe-common' ),
124
+ 'TF' => esc_html__( 'French Southern Territories', 'tribe-common' ),
125
+ 'GA' => esc_html__( 'Gabon', 'tribe-common' ),
126
+ 'GM' => esc_html__( 'Gambia', 'tribe-common' ),
127
+ 'GE' => esc_html__( 'Georgia', 'tribe-common' ),
128
+ 'DE' => esc_html__( 'Germany', 'tribe-common' ),
129
+ 'GH' => esc_html__( 'Ghana', 'tribe-common' ),
130
+ 'GI' => esc_html__( 'Gibraltar', 'tribe-common' ),
131
+ 'GR' => esc_html__( 'Greece', 'tribe-common' ),
132
+ 'GL' => esc_html__( 'Greenland', 'tribe-common' ),
133
+ 'GD' => esc_html__( 'Grenada', 'tribe-common' ),
134
+ 'GP' => esc_html__( 'Guadeloupe', 'tribe-common' ),
135
+ 'GU' => esc_html__( 'Guam', 'tribe-common' ),
136
+ 'GT' => esc_html__( 'Guatemala', 'tribe-common' ),
137
+ 'GN' => esc_html__( 'Guinea', 'tribe-common' ),
138
+ 'GW' => esc_html__( 'Guinea-Bissau', 'tribe-common' ),
139
+ 'GY' => esc_html__( 'Guyana', 'tribe-common' ),
140
+ 'HT' => esc_html__( 'Haiti', 'tribe-common' ),
141
+ 'HM' => esc_html__( 'Heard And Mc Donald Islands', 'tribe-common' ),
142
+ 'VA' => esc_html__( 'Holy See (Vatican City State)', 'tribe-common' ),
143
+ 'HN' => esc_html__( 'Honduras', 'tribe-common' ),
144
+ 'HK' => esc_html__( 'Hong Kong', 'tribe-common' ),
145
+ 'HU' => esc_html__( 'Hungary', 'tribe-common' ),
146
+ 'IS' => esc_html__( 'Iceland', 'tribe-common' ),
147
+ 'IN' => esc_html__( 'India', 'tribe-common' ),
148
+ 'ID' => esc_html__( 'Indonesia', 'tribe-common' ),
149
+ 'IR' => esc_html__( 'Iran (Islamic Republic Of)', 'tribe-common' ),
150
+ 'IQ' => esc_html__( 'Iraq', 'tribe-common' ),
151
+ 'IE' => esc_html__( 'Ireland', 'tribe-common' ),
152
+ 'IL' => esc_html__( 'Israel', 'tribe-common' ),
153
+ 'IT' => esc_html__( 'Italy', 'tribe-common' ),
154
+ 'JM' => esc_html__( 'Jamaica', 'tribe-common' ),
155
+ 'JP' => esc_html__( 'Japan', 'tribe-common' ),
156
+ 'JO' => esc_html__( 'Jordan', 'tribe-common' ),
157
+ 'KZ' => esc_html__( 'Kazakhstan', 'tribe-common' ),
158
+ 'KE' => esc_html__( 'Kenya', 'tribe-common' ),
159
+ 'KI' => esc_html__( 'Kiribati', 'tribe-common' ),
160
+ 'KP' => esc_html__( "Korea, Democratic People's Republic Of", 'tribe-common' ),
161
+ 'KR' => esc_html__( 'Korea, Republic Of', 'tribe-common' ),
162
+ 'KW' => esc_html__( 'Kuwait', 'tribe-common' ),
163
+ 'KG' => esc_html__( 'Kyrgyzstan', 'tribe-common' ),
164
+ 'LA' => esc_html__( "Lao People's Democratic Republic", 'tribe-common' ),
165
+ 'LV' => esc_html__( 'Latvia', 'tribe-common' ),
166
+ 'LB' => esc_html__( 'Lebanon', 'tribe-common' ),
167
+ 'LS' => esc_html__( 'Lesotho', 'tribe-common' ),
168
+ 'LR' => esc_html__( 'Liberia', 'tribe-common' ),
169
+ 'LY' => esc_html__( 'Libya', 'tribe-common' ),
170
+ 'LI' => esc_html__( 'Liechtenstein', 'tribe-common' ),
171
+ 'LT' => esc_html__( 'Lithuania', 'tribe-common' ),
172
+ 'LU' => esc_html__( 'Luxembourg', 'tribe-common' ),
173
+ 'MO' => esc_html__( 'Macau', 'tribe-common' ),
174
+ 'MK' => esc_html__( 'Macedonia', 'tribe-common' ),
175
+ 'MG' => esc_html__( 'Madagascar', 'tribe-common' ),
176
+ 'MW' => esc_html__( 'Malawi', 'tribe-common' ),
177
+ 'MY' => esc_html__( 'Malaysia', 'tribe-common' ),
178
+ 'MV' => esc_html__( 'Maldives', 'tribe-common' ),
179
+ 'ML' => esc_html__( 'Mali', 'tribe-common' ),
180
+ 'MT' => esc_html__( 'Malta', 'tribe-common' ),
181
+ 'MH' => esc_html__( 'Marshall Islands', 'tribe-common' ),
182
+ 'MQ' => esc_html__( 'Martinique', 'tribe-common' ),
183
+ 'MR' => esc_html__( 'Mauritania', 'tribe-common' ),
184
+ 'MU' => esc_html__( 'Mauritius', 'tribe-common' ),
185
+ 'YT' => esc_html__( 'Mayotte', 'tribe-common' ),
186
+ 'MX' => esc_html__( 'Mexico', 'tribe-common' ),
187
+ 'FM' => esc_html__( 'Micronesia, Federated States Of', 'tribe-common' ),
188
+ 'MD' => esc_html__( 'Moldova, Republic Of', 'tribe-common' ),
189
+ 'MC' => esc_html__( 'Monaco', 'tribe-common' ),
190
+ 'MN' => esc_html__( 'Mongolia', 'tribe-common' ),
191
+ 'ME' => esc_html__( 'Montenegro', 'tribe-common' ),
192
+ 'MS' => esc_html__( 'Montserrat', 'tribe-common' ),
193
+ 'MA' => esc_html__( 'Morocco', 'tribe-common' ),
194
+ 'MZ' => esc_html__( 'Mozambique', 'tribe-common' ),
195
+ 'MM' => esc_html__( 'Myanmar', 'tribe-common' ),
196
+ 'NA' => esc_html__( 'Namibia', 'tribe-common' ),
197
+ 'NR' => esc_html__( 'Nauru', 'tribe-common' ),
198
+ 'NP' => esc_html__( 'Nepal', 'tribe-common' ),
199
+ 'NL' => esc_html__( 'Netherlands', 'tribe-common' ),
200
+ 'AN' => esc_html__( 'Netherlands Antilles', 'tribe-common' ),
201
+ 'NC' => esc_html__( 'New Caledonia', 'tribe-common' ),
202
+ 'NZ' => esc_html__( 'New Zealand', 'tribe-common' ),
203
+ 'NI' => esc_html__( 'Nicaragua', 'tribe-common' ),
204
+ 'NE' => esc_html__( 'Niger', 'tribe-common' ),
205
+ 'NG' => esc_html__( 'Nigeria', 'tribe-common' ),
206
+ 'NU' => esc_html__( 'Niue', 'tribe-common' ),
207
+ 'NF' => esc_html__( 'Norfolk Island', 'tribe-common' ),
208
+ 'MP' => esc_html__( 'Northern Mariana Islands', 'tribe-common' ),
209
+ 'NO' => esc_html__( 'Norway', 'tribe-common' ),
210
+ 'OM' => esc_html__( 'Oman', 'tribe-common' ),
211
+ 'PK' => esc_html__( 'Pakistan', 'tribe-common' ),
212
+ 'PW' => esc_html__( 'Palau', 'tribe-common' ),
213
+ 'PA' => esc_html__( 'Panama', 'tribe-common' ),
214
+ 'PG' => esc_html__( 'Papua New Guinea', 'tribe-common' ),
215
+ 'PY' => esc_html__( 'Paraguay', 'tribe-common' ),
216
+ 'PE' => esc_html__( 'Peru', 'tribe-common' ),
217
+ 'PH' => esc_html__( 'Philippines', 'tribe-common' ),
218
+ 'PN' => esc_html__( 'Pitcairn', 'tribe-common' ),
219
+ 'PL' => esc_html__( 'Poland', 'tribe-common' ),
220
+ 'PT' => esc_html__( 'Portugal', 'tribe-common' ),
221
+ 'PR' => esc_html__( 'Puerto Rico', 'tribe-common' ),
222
+ 'QA' => esc_html__( 'Qatar', 'tribe-common' ),
223
+ 'RE' => esc_html__( 'Reunion', 'tribe-common' ),
224
+ 'RO' => esc_html__( 'Romania', 'tribe-common' ),
225
+ 'RU' => esc_html__( 'Russian Federation', 'tribe-common' ),
226
+ 'RW' => esc_html__( 'Rwanda', 'tribe-common' ),
227
+ 'KN' => esc_html__( 'Saint Kitts And Nevis', 'tribe-common' ),
228
+ 'LC' => esc_html__( 'Saint Lucia', 'tribe-common' ),
229
+ 'VC' => esc_html__( 'Saint Vincent And The Grenadines', 'tribe-common' ),
230
+ 'WS' => esc_html__( 'Samoa', 'tribe-common' ),
231
+ 'SM' => esc_html__( 'San Marino', 'tribe-common' ),
232
+ 'ST' => esc_html__( 'Sao Tome And Principe', 'tribe-common' ),
233
+ 'SA' => esc_html__( 'Saudi Arabia', 'tribe-common' ),
234
+ 'SN' => esc_html__( 'Senegal', 'tribe-common' ),
235
+ 'RS' => esc_html__( 'Serbia', 'tribe-common' ),
236
+ 'SC' => esc_html__( 'Seychelles', 'tribe-common' ),
237
+ 'SL' => esc_html__( 'Sierra Leone', 'tribe-common' ),
238
+ 'SG' => esc_html__( 'Singapore', 'tribe-common' ),
239
+ 'SK' => esc_html__( 'Slovakia (Slovak Republic)', 'tribe-common' ),
240
+ 'SI' => esc_html__( 'Slovenia', 'tribe-common' ),
241
+ 'SB' => esc_html__( 'Solomon Islands', 'tribe-common' ),
242
+ 'SO' => esc_html__( 'Somalia', 'tribe-common' ),
243
+ 'ZA' => esc_html__( 'South Africa', 'tribe-common' ),
244
+ 'GS' => esc_html__( 'South Georgia, South Sandwich Islands', 'tribe-common' ),
245
+ 'ES' => esc_html__( 'Spain', 'tribe-common' ),
246
+ 'LK' => esc_html__( 'Sri Lanka', 'tribe-common' ),
247
+ 'SH' => esc_html__( 'St. Helena', 'tribe-common' ),
248
+ 'PM' => esc_html__( 'St. Pierre And Miquelon', 'tribe-common' ),
249
+ 'SD' => esc_html__( 'Sudan', 'tribe-common' ),
250
+ 'SR' => esc_html__( 'Suriname', 'tribe-common' ),
251
+ 'SJ' => esc_html__( 'Svalbard And Jan Mayen Islands', 'tribe-common' ),
252
+ 'SZ' => esc_html__( 'Swaziland', 'tribe-common' ),
253
+ 'SE' => esc_html__( 'Sweden', 'tribe-common' ),
254
+ 'CH' => esc_html__( 'Switzerland', 'tribe-common' ),
255
+ 'SY' => esc_html__( 'Syrian Arab Republic', 'tribe-common' ),
256
+ 'TW' => esc_html__( 'Taiwan', 'tribe-common' ),
257
+ 'TJ' => esc_html__( 'Tajikistan', 'tribe-common' ),
258
+ 'TZ' => esc_html__( 'Tanzania, United Republic Of', 'tribe-common' ),
259
+ 'TH' => esc_html__( 'Thailand', 'tribe-common' ),
260
+ 'TG' => esc_html__( 'Togo', 'tribe-common' ),
261
+ 'TK' => esc_html__( 'Tokelau', 'tribe-common' ),
262
+ 'TO' => esc_html__( 'Tonga', 'tribe-common' ),
263
+ 'TT' => esc_html__( 'Trinidad And Tobago', 'tribe-common' ),
264
+ 'TN' => esc_html__( 'Tunisia', 'tribe-common' ),
265
+ 'TR' => esc_html__( 'Turkey', 'tribe-common' ),
266
+ 'TM' => esc_html__( 'Turkmenistan', 'tribe-common' ),
267
+ 'TC' => esc_html__( 'Turks And Caicos Islands', 'tribe-common' ),
268
+ 'TV' => esc_html__( 'Tuvalu', 'tribe-common' ),
269
+ 'UG' => esc_html__( 'Uganda', 'tribe-common' ),
270
+ 'UA' => esc_html__( 'Ukraine', 'tribe-common' ),
271
+ 'AE' => esc_html__( 'United Arab Emirates', 'tribe-common' ),
272
+ 'GB' => esc_html__( 'United Kingdom', 'tribe-common' ),
273
+ 'UM' => esc_html__( 'United States Minor Outlying Islands', 'tribe-common' ),
274
+ 'UY' => esc_html__( 'Uruguay', 'tribe-common' ),
275
+ 'UZ' => esc_html__( 'Uzbekistan', 'tribe-common' ),
276
+ 'VU' => esc_html__( 'Vanuatu', 'tribe-common' ),
277
+ 'VE' => esc_html__( 'Venezuela', 'tribe-common' ),
278
+ 'VN' => esc_html__( 'Viet Nam', 'tribe-common' ),
279
+ 'VG' => esc_html__( 'Virgin Islands (British)', 'tribe-common' ),
280
+ 'VI' => esc_html__( 'Virgin Islands (U.S.)', 'tribe-common' ),
281
+ 'WF' => esc_html__( 'Wallis And Futuna Islands', 'tribe-common' ),
282
+ 'EH' => esc_html__( 'Western Sahara', 'tribe-common' ),
283
+ 'YE' => esc_html__( 'Yemen', 'tribe-common' ),
284
+ 'ZM' => esc_html__( 'Zambia', 'tribe-common' ),
285
+ 'ZW' => esc_html__( 'Zimbabwe', 'tribe-common' ),
286
+ );
287
+ }
288
+ if ( ( $postId || $useDefault ) ) {
289
+ $countryValue = get_post_meta( $postId, '_EventCountry', true );
290
+ if ( $countryValue ) {
291
+ $defaultCountry = array( array_search( $countryValue, $countries ), $countryValue );
292
+ } else {
293
+ $defaultCountry = tribe_get_default_value( 'country' );
294
+ }
295
+ if ( $defaultCountry && $defaultCountry[0] != '' ) {
296
+ $selectCountry = array_shift( $countries );
297
+ asort( $countries );
298
+ $countries = array( $defaultCountry[0] => __( $defaultCountry[1], 'tribe-common' ) ) + $countries;
299
+ $countries = array( '' => __( $selectCountry, 'tribe-common' ) ) + $countries;
300
+ array_unique( $countries );
301
+ }
302
+
303
+ return $countries;
304
+ } else {
305
+ return $countries;
306
+ }
307
+ }
308
+
309
+ /**
310
+ * Get the i18ned states available to the plugin.
311
+ *
312
+ * @return array The states array.
313
+ */
314
+ public static function loadStates() {
315
+ return array(
316
+ 'AL' => esc_html__( 'Alabama', 'tribe-common' ),
317
+ 'AK' => esc_html__( 'Alaska', 'tribe-common' ),
318
+ 'AZ' => esc_html__( 'Arizona', 'tribe-common' ),
319
+ 'AR' => esc_html__( 'Arkansas', 'tribe-common' ),
320
+ 'CA' => esc_html__( 'California', 'tribe-common' ),
321
+ 'CO' => esc_html__( 'Colorado', 'tribe-common' ),
322
+ 'CT' => esc_html__( 'Connecticut', 'tribe-common' ),
323
+ 'DE' => esc_html__( 'Delaware', 'tribe-common' ),
324
+ 'DC' => esc_html__( 'District of Columbia', 'tribe-common' ),
325
+ 'FL' => esc_html__( 'Florida', 'tribe-common' ),
326
+ 'GA' => esc_html__( 'Georgia', 'tribe-common' ),
327
+ 'HI' => esc_html__( 'Hawaii', 'tribe-common' ),
328
+ 'ID' => esc_html__( 'Idaho', 'tribe-common' ),
329
+ 'IL' => esc_html__( 'Illinois', 'tribe-common' ),
330
+ 'IN' => esc_html__( 'Indiana', 'tribe-common' ),
331
+ 'IA' => esc_html__( 'Iowa', 'tribe-common' ),
332
+ 'KS' => esc_html__( 'Kansas', 'tribe-common' ),
333
+ 'KY' => esc_html__( 'Kentucky', 'tribe-common' ),
334
+ 'LA' => esc_html__( 'Louisiana', 'tribe-common' ),
335
+ 'ME' => esc_html__( 'Maine', 'tribe-common' ),
336
+ 'MD' => esc_html__( 'Maryland', 'tribe-common' ),
337
+ 'MA' => esc_html__( 'Massachusetts', 'tribe-common' ),
338
+ 'MI' => esc_html__( 'Michigan', 'tribe-common' ),
339
+ 'MN' => esc_html__( 'Minnesota', 'tribe-common' ),
340
+ 'MS' => esc_html__( 'Mississippi', 'tribe-common' ),
341
+ 'MO' => esc_html__( 'Missouri', 'tribe-common' ),
342
+ 'MT' => esc_html__( 'Montana', 'tribe-common' ),
343
+ 'NE' => esc_html__( 'Nebraska', 'tribe-common' ),
344
+ 'NV' => esc_html__( 'Nevada', 'tribe-common' ),
345
+ 'NH' => esc_html__( 'New Hampshire', 'tribe-common' ),
346
+ 'NJ' => esc_html__( 'New Jersey', 'tribe-common' ),
347
+ 'NM' => esc_html__( 'New Mexico', 'tribe-common' ),
348
+ 'NY' => esc_html__( 'New York', 'tribe-common' ),
349
+ 'NC' => esc_html__( 'North Carolina', 'tribe-common' ),
350
+ 'ND' => esc_html__( 'North Dakota', 'tribe-common' ),
351
+ 'OH' => esc_html__( 'Ohio', 'tribe-common' ),
352
+ 'OK' => esc_html__( 'Oklahoma', 'tribe-common' ),
353
+ 'OR' => esc_html__( 'Oregon', 'tribe-common' ),
354
+ 'PA' => esc_html__( 'Pennsylvania', 'tribe-common' ),
355
+ 'RI' => esc_html__( 'Rhode Island', 'tribe-common' ),
356
+ 'SC' => esc_html__( 'South Carolina', 'tribe-common' ),
357
+ 'SD' => esc_html__( 'South Dakota', 'tribe-common' ),
358
+ 'TN' => esc_html__( 'Tennessee', 'tribe-common' ),
359
+ 'TX' => esc_html__( 'Texas', 'tribe-common' ),
360
+ 'UT' => esc_html__( 'Utah', 'tribe-common' ),
361
+ 'VT' => esc_html__( 'Vermont', 'tribe-common' ),
362
+ 'VA' => esc_html__( 'Virginia', 'tribe-common' ),
363
+ 'WA' => esc_html__( 'Washington', 'tribe-common' ),
364
+ 'WV' => esc_html__( 'West Virginia', 'tribe-common' ),
365
+ 'WI' => esc_html__( 'Wisconsin', 'tribe-common' ),
366
+ 'WY' => esc_html__( 'Wyoming', 'tribe-common' ),
367
+ );
368
+ }
369
+
370
+ /**
371
+ * Builds a set of options for displaying an hour chooser
372
+ *
373
+ * @param string $date the current date (optional)
374
+ * @param bool $isStart
375
+ *
376
+ * @return string a set of HTML options with hours (current hour selected)
377
+ */
378
+ public static function getHourOptions( $date = '', $isStart = false ) {
379
+ $hours = self::hours();
380
+
381
+ if ( count( $hours ) == 12 ) {
382
+ $h = 'h';
383
+ } else {
384
+ $h = 'H';
385
+ }
386
+ $options = '';
387
+
388
+ if ( empty( $date ) ) {
389
+ $hour = ( $isStart ) ? '08' : ( count( $hours ) == 12 ? '05' : '17' );
390
+ } else {
391
+ $timestamp = strtotime( $date );
392
+ $hour = date( $h, $timestamp );
393
+ // fix hours if time_format has changed from what is saved
394
+ if ( preg_match( '(pm|PM)', $timestamp ) && $h == 'H' ) {
395
+ $hour = $hour + 12;
396
+ }
397
+ if ( $hour > 12 && $h == 'h' ) {
398
+ $hour = $hour - 12;
399
+ }
400
+ }
401
+
402
+ $hour = apply_filters( 'tribe_get_hour_options', $hour, $date, $isStart );
403
+
404
+ foreach ( $hours as $hourText ) {
405
+ if ( $hour == $hourText ) {
406
+ $selected = 'selected="selected"';
407
+ } else {
408
+ $selected = '';
409
+ }
410
+ $options .= "<option value='$hourText' $selected>$hourText</option>\n";
411
+ }
412
+
413
+ return $options;
414
+ }
415
+
416
+ /**
417
+ * Builds a set of options for displaying a minute chooser
418
+ *
419
+ * @param string $date the current date (optional)
420
+ * @param bool $isStart
421
+ *
422
+ * @return string a set of HTML options with minutes (current minute selected)
423
+ */
424
+ public static function getMinuteOptions( $date = '', $isStart = false ) {
425
+ $options = '';
426
+
427
+ if ( empty( $date ) ) {
428
+ $minute = '00';
429
+ } else {
430
+ $minute = date( 'i', strtotime( $date ) );
431
+ }
432
+
433
+ $minute = apply_filters( 'tribe_get_minute_options', $minute, $date, $isStart );
434
+ $minutes = self::minutes( $minute );
435
+
436
+ foreach ( $minutes as $minuteText ) {
437
+ if ( $minute == $minuteText ) {
438
+ $selected = 'selected="selected"';
439
+ } else {
440
+ $selected = '';
441
+ }
442
+ $options .= "<option value='$minuteText' $selected>$minuteText</option>\n";
443
+ }
444
+
445
+ return $options;
446
+ }
447
+
448
+ /**
449
+ * Helper method to return an array of 1-12 for hours
450
+ *
451
+ * @return array The hours array.
452
+ */
453
+ private static function hours() {
454
+ $hours = array();
455
+ $rangeMax = self::is_24hr_format() ? 23 : 12;
456
+ $rangeStart = $rangeMax > 12 ? 0 : 1;
457
+ foreach ( range( $rangeStart, $rangeMax ) as $hour ) {
458
+ if ( $hour < 10 ) {
459
+ $hour = '0' . $hour;
460
+ }
461
+ $hours[ $hour ] = $hour;
462
+ }
463
+
464
+ // In a 12hr context lets put 12 at the start (so the sequence will run 12, 1, 2, 3 ... 11)
465
+ if ( 12 === $rangeMax ) {
466
+ array_unshift( $hours, array_pop( $hours ) );
467
+ }
468
+
469
+ return $hours;
470
+ }
471
+
472
+ /**
473
+ * Determines if the provided date/time format (or else the default WordPress time_format)
474
+ * is 24hr or not.
475
+ *
476
+ * In inconclusive cases, such as if there are now hour-format characters, 12hr format is
477
+ * assumed.
478
+ *
479
+ * @param null $format
480
+ * @return bool
481
+ */
482
+ public static function is_24hr_format( $format = null ) {
483
+ // Use the provided format or else use the value of the current time_format setting
484
+ $format = ( null === $format ) ? get_option( 'time_format', Tribe__Date_Utils::TIMEFORMAT ) : $format;
485
+
486
+ // Count instances of the H and G symbols
487
+ $h_symbols = substr_count( $format, 'H' );
488
+ $g_symbols = substr_count( $format, 'G' );
489
+
490
+ // If none have been found then consider the format to be 12hr
491
+ if ( ! $h_symbols && ! $g_symbols ) return false;
492
+
493
+ // It's possible H or G have been included as escaped characters
494
+ $h_escaped = substr_count( $format, '\H' );
495
+ $g_escaped = substr_count( $format, '\G' );
496
+
497
+ // Final check, accounting for possibility of escaped values
498
+ return ( $h_symbols > $h_escaped || $g_symbols > $g_escaped );
499
+ }
500
+
501
+ /**
502
+ * Helper method to return an array of 00-59 for minutes
503
+ *
504
+ * @param int $exact_minute optionally specify an exact minute to be included (outwith the default intervals)
505
+ *
506
+ * @return array The minutes array.
507
+ */
508
+ private static function minutes( $exact_minute = 0 ) {
509
+ $minutes = array();
510
+
511
+ // The exact minute should be an absint between 0 and 59
512
+ $exact_minute = absint( $exact_minute );
513
+
514
+ if ( $exact_minute < 0 || $exact_minute > 59 ) {
515
+ $exact_minute = 0;
516
+ }
517
+
518
+ /**
519
+ * Filters the amount of minutes to increment the minutes drop-down by
520
+ *
521
+ * @param int Increment amount (defaults to 5)
522
+ */
523
+ $default_increment = apply_filters( 'tribe_minutes_increment', 5 );
524
+
525
+ // Unless an exact minute has been specified we can minimize the amount of looping we do
526
+ $increment = ( 0 === $exact_minute ) ? $default_increment : 1;
527
+
528
+ for ( $minute = 0; $minute < 60; $minute += $increment ) {
529
+ // Skip if this $minute doesn't meet the increment pattern and isn't an additional exact minute
530
+ if ( 0 !== $minute % $default_increment && $exact_minute !== $minute ) {
531
+ continue;
532
+ }
533
+
534
+ if ( $minute < 10 ) {
535
+ $minute = '0' . $minute;
536
+ }
537
+ $minutes[ $minute ] = $minute;
538
+ }
539
+
540
+ return $minutes;
541
+ }
542
+
543
+ /**
544
+ * Builds a set of options for diplaying a meridian chooser
545
+ *
546
+ * @param string $date YYYY-MM-DD HH:MM:SS to select (optional)
547
+ * @param bool $isStart
548
+ *
549
+ * @return string a set of HTML options with all meridians
550
+ */
551
+ public static function getMeridianOptions( $date = '', $isStart = false ) {
552
+ if ( strstr( get_option( 'time_format', Tribe__Date_Utils::TIMEFORMAT ), 'A' ) ) {
553
+ $a = 'A';
554
+ $meridians = array( 'AM', 'PM' );
555
+ } else {
556
+ $a = 'a';
557
+ $meridians = array( 'am', 'pm' );
558
+ }
559
+ if ( empty( $date ) ) {
560
+ $meridian = ( $isStart ) ? $meridians[0] : $meridians[1];
561
+ } else {
562
+ $meridian = date( $a, strtotime( $date ) );
563
+ }
564
+
565
+ $meridian = apply_filters( 'tribe_get_meridian_options', $meridian, $date, $isStart );
566
+
567
+ $return = '';
568
+ foreach ( $meridians as $m ) {
569
+ $return .= "<option value='$m'";
570
+ if ( $m == $meridian ) {
571
+ $return .= ' selected="selected"';
572
+ }
573
+ $return .= ">$m</option>\n";
574
+ }
575
+
576
+ return $return;
577
+ }
578
+
579
+ /**
580
+ * Helper method to return an array of years
581
+ * default is back 5 and forward 5
582
+ *
583
+ * @return array The array of years.
584
+ */
585
+ private static function years() {
586
+ $current_year = (int) date_i18n( 'Y' );
587
+ $years_back = (int) apply_filters( 'tribe_years_to_go_back', 5, $current_year );
588
+ $years_forward = (int) apply_filters( 'tribe_years_to_go_forward', 5, $current_year );
589
+ $years = array();
590
+ for ( $i = $years_back; $i > 0; $i -- ) {
591
+ $year = $current_year - $i;
592
+ $years[] = $year;
593
+ }
594
+ $years[] = $current_year;
595
+ for ( $i = 1; $i <= $years_forward; $i ++ ) {
596
+ $year = $current_year + $i;
597
+ $years[] = $year;
598
+ }
599
+
600
+ return (array) apply_filters( 'tribe_years_array', $years );
601
+ }
602
+
603
+ /**
604
+ * Helper method to return an array of 1-31 for days
605
+ *
606
+ * @return array The days array.
607
+ */
608
+ public static function days( $totalDays ) {
609
+ $days = array();
610
+ foreach ( range( 1, $totalDays ) as $day ) {
611
+ $days[ $day ] = $day;
612
+ }
613
+
614
+ return $days;
615
+ }
616
+ }
617
+ }
common/src/admin-views/app-shop.php CHANGED
@@ -1,42 +1,42 @@
1
- <div id="tribe-app-shop" class="wrap">
2
-
3
- <div class="header">
4
- <h1><?php esc_html_e( 'Tribe Event Add-Ons', 'tribe-common' ); ?></h1>
5
- <a href="https://theeventscalendar.com/?utm_campaign=in-app&utm_source=addonspage&utm_medium=top-banner" target="_blank"><img src="<?php echo esc_url( tribe_resource_url( 'images/app-shop-banner.jpg', false, 'common' ) ); ?>" /></a>
6
- </div>
7
-
8
- <div class="content-wrapper">
9
- <div class="addon-grid">
10
- <?php
11
- $i = 0;
12
- foreach ( $products as $product ) {
13
- ?>
14
- <div class="tribe-addon<?php echo ( $i % 4 == 0 ) ? ' first tribe-clearfix' : '';?>">
15
- <div class="thumb">
16
- <a href="<?php echo esc_url( $product->link ); ?>"><img src="<?php echo esc_url( tribe_resource_url( $product->image, false, 'common' ) ); ?>" /></a>
17
- </div>
18
- <div class="caption">
19
- <h4><a href="<?php echo esc_url( $product->link ); ?>"><?php echo esc_html( $product->title ); ?></a></h4>
20
-
21
- <div class="description">
22
- <p><?php echo $product->description; ?></p>
23
- <?php
24
- if ( isset( $product->requires ) ) {
25
- ?>
26
- <p><strong><?php esc_html_e( 'Requires:', 'tribe-common' );?></strong> <?php echo esc_html( $product->requires );?></p>
27
- <?php
28
- }
29
- ?>
30
- </div>
31
-
32
- <a class="button button-primary" href="<?php echo esc_url( $product->link ); ?>">Get This Add-on</a>
33
- </div>
34
- </div>
35
-
36
- <?php
37
- $i++;
38
- }
39
- ?>
40
- </div>
41
- </div>
42
- </div>
1
+ <div id="tribe-app-shop" class="wrap">
2
+
3
+ <div class="header">
4
+ <h1><?php esc_html_e( 'Tribe Event Add-Ons', 'tribe-common' ); ?></h1>
5
+ <a href="https://theeventscalendar.com/?utm_campaign=in-app&utm_source=addonspage&utm_medium=top-banner" target="_blank"><img src="<?php echo esc_url( tribe_resource_url( 'images/app-shop-banner.jpg', false, 'common' ) ); ?>" /></a>
6
+ </div>
7
+
8
+ <div class="content-wrapper">
9
+ <div class="addon-grid">
10
+ <?php
11
+ $i = 0;
12
+ foreach ( $products as $product ) {
13
+ ?>
14
+ <div class="tribe-addon<?php echo ( $i % 4 == 0 ) ? ' first tribe-clearfix' : '';?>">
15
+ <div class="thumb">
16
+ <a href="<?php echo esc_url( $product->link ); ?>"><img src="<?php echo esc_url( tribe_resource_url( $product->image, false, 'common' ) ); ?>" /></a>
17
+ </div>
18
+ <div class="caption">
19
+ <h4><a href="<?php echo esc_url( $product->link ); ?>"><?php echo esc_html( $product->title ); ?></a></h4>
20
+
21
+ <div class="description">
22
+ <p><?php echo $product->description; ?></p>
23
+ <?php
24
+ if ( isset( $product->requires ) ) {
25
+ ?>
26
+ <p><strong><?php esc_html_e( 'Requires:', 'tribe-common' );?></strong> <?php echo esc_html( $product->requires );?></p>
27
+ <?php
28
+ }
29
+ ?>
30
+ </div>
31
+
32
+ <a class="button button-primary" href="<?php echo esc_url( $product->link ); ?>">Get This Add-on</a>
33
+ </div>
34
+ </div>
35
+
36
+ <?php
37
+ $i++;
38
+ }
39
+ ?>
40
+ </div>
41
+ </div>
42
+ </div>
common/src/admin-views/event-log.php CHANGED
@@ -1,104 +1,104 @@
1
- <?php
2
- /**
3
- * @var array $log_choices
4
- * @var array $log_engines
5
- * @var array $log_levels
6
- * @var array $log_entries
7
- * @var string $download_url
8
- */
9
- ?>
10
- <div id="tribe-log-controls">
11
-
12
- <?php
13
- /**
14
- * Fires within the #tribe-log-controls div, before any of the default
15
- * controls are generated.
16
- */
17
- do_action( 'tribe_common_log_controls_top' );
18
- ?>
19
-
20
- <div>
21
- <label for="log-levels"><?php esc_html_e( 'Logging level', 'tribe-common' ) ?></label>
22
- <select name="log-level" id="log-level">
23
- <?php foreach ( $log_levels as $code => $name ): ?>
24
- <option name="<?php echo esc_attr( $code ) ?>" <?php selected( $code, tribe_get_option( 'logging_level') ); ?>>
25
- <?php echo esc_html( $name ) ?>
26
- </option>
27
- <?php endforeach; ?>
28
- </select>
29
- </div>
30
-
31
- <?php
32
- /**
33
- * Fires within the #tribe-log-controls div, after the #log-level control.
34
- */
35
- do_action( 'tribe_common_log_controls_after_log_level' );
36
- ?>
37
-
38
- <div>
39
- <label for="log-engine"><?php esc_html_e( 'Method', 'tribe-common' ) ?></label>
40
- <select name="log-engine" id="log-engine">
41
- <?php foreach ( $log_engines as $code => $name ): ?>
42
- <option name="<?php echo esc_attr( $code ) ?>" <?php selected( $code, tribe_get_option( 'logging_engine') ); ?>>
43
- <?php echo esc_html( $name ) ?>
44
- </option>
45
- <?php endforeach; ?>
46
- </select>
47
- </div>
48
-
49
- <?php
50
- /**
51
- * Fires within the #tribe-log-controls div, after the #log-engine control.
52
- */
53
- do_action( 'tribe_common_log_controls_after_log_engine' );
54
- ?>
55
-
56
- <div>
57
- <label for="log-selector"><?php esc_html_e( 'View', 'tribe-common' ) ?></label>
58
- <select name="log-selector" id="log-selector">
59
- <?php foreach ( $log_choices as $name ): ?>
60
- <option name="<?php echo esc_attr( $name ) ?>"><?php echo esc_html( $name ) ?></option>
61
- <?php endforeach; ?>
62
- </select>
63
- </div>
64
-
65
- <?php
66
- /**
67
- * Fires within the #tribe-log-controls div, after the #log-selector control.
68
- */
69
- do_action( 'tribe_common_log_controls_after_log_selector' );
70
- ?>
71
-
72
- <div class="working hidden">
73
- <img src="<?php echo esc_url( get_admin_url( null, '/images/spinner.gif' ) ); ?>" />
74
- </div>
75
-
76
- <?php
77
- /**
78
- * Fires within the #tribe-log-controls div, after all of the default
79
- * controls have been generated.
80
- */
81
- do_action( 'tribe_common_log_controls_bottom' );
82
- ?>
83
-
84
- </div>
85
-
86
- <div id="tribe-log-viewer">
87
-
88
- <table>
89
- <?php foreach ( $log_entries as $data ): ?>
90
- <tr>
91
- <?php foreach ( $data as $single_cell ): ?>
92
- <td><?php echo esc_html( $single_cell ); ?></td>
93
- <?php endforeach; ?>
94
- </tr>
95
- <?php endforeach; ?>
96
- </table>
97
-
98
- <?php if ( empty( $log_entries ) ): ?>
99
- <p><?php esc_html_e( 'The selected log file is empty or has not been generated yet.', 'tribe-common' ); ?></p>
100
- <?php endif; ?>
101
-
102
- </div>
103
-
104
  <p> <a href="<?php echo esc_url( $download_url ) ?>" class="download_log" target="_blank"><?php esc_html_e( 'Download log', 'tribe-common' ); ?> </a> </p>
1
+ <?php
2
+ /**
3
+ * @var array $log_choices
4
+ * @var array $log_engines
5
+ * @var array $log_levels
6
+ * @var array $log_entries
7
+ * @var string $download_url
8
+ */
9
+ ?>
10
+ <div id="tribe-log-controls">
11
+
12
+ <?php
13
+ /**
14
+ * Fires within the #tribe-log-controls div, before any of the default
15
+ * controls are generated.
16
+ */
17
+ do_action( 'tribe_common_log_controls_top' );
18
+ ?>
19
+
20
+ <div>
21
+ <label for="log-levels"><?php esc_html_e( 'Logging level', 'tribe-common' ) ?></label>
22
+ <select name="log-level" id="log-level">
23
+ <?php foreach ( $log_levels as $code => $name ): ?>
24
+ <option name="<?php echo esc_attr( $code ) ?>" <?php selected( $code, tribe_get_option( 'logging_level') ); ?>>
25
+ <?php echo esc_html( $name ) ?>
26
+ </option>
27
+ <?php endforeach; ?>
28
+ </select>
29
+ </div>
30
+
31
+ <?php
32
+ /**
33
+ * Fires within the #tribe-log-controls div, after the #log-level control.
34
+ */
35
+ do_action( 'tribe_common_log_controls_after_log_level' );
36
+ ?>
37
+
38
+ <div>
39
+ <label for="log-engine"><?php esc_html_e( 'Method', 'tribe-common' ) ?></label>
40
+ <select name="log-engine" id="log-engine">
41
+ <?php foreach ( $log_engines as $code => $name ): ?>
42
+ <option name="<?php echo esc_attr( $code ) ?>" <?php selected( $code, tribe_get_option( 'logging_engine') ); ?>>
43
+ <?php echo esc_html( $name ) ?>
44
+ </option>
45
+ <?php endforeach; ?>
46
+ </select>
47
+ </div>
48
+
49
+ <?php
50
+ /**
51
+ * Fires within the #tribe-log-controls div, after the #log-engine control.
52
+ */
53
+ do_action( 'tribe_common_log_controls_after_log_engine' );
54
+ ?>
55
+
56
+ <div>
57
+ <label for="log-selector"><?php esc_html_e( 'View', 'tribe-common' ) ?></label>
58
+ <select name="log-selector" id="log-selector">
59
+ <?php foreach ( $log_choices as $name ): ?>
60
+ <option name="<?php echo esc_attr( $name ) ?>"><?php echo esc_html( $name ) ?></option>
61
+ <?php endforeach; ?>
62
+ </select>
63
+ </div>
64
+
65
+ <?php
66
+ /**
67
+ * Fires within the #tribe-log-controls div, after the #log-selector control.
68
+ */
69
+ do_action( 'tribe_common_log_controls_after_log_selector' );
70
+ ?>
71
+
72
+ <div class="working hidden">
73
+ <img src="<?php echo esc_url( get_admin_url( null, '/images/spinner.gif' ) ); ?>" />
74
+ </div>
75
+
76
+ <?php
77
+ /**
78
+ * Fires within the #tribe-log-controls div, after all of the default
79
+ * controls have been generated.
80
+ */
81
+ do_action( 'tribe_common_log_controls_bottom' );
82
+ ?>
83
+
84
+ </div>
85
+
86
+ <div id="tribe-log-viewer">
87
+
88
+ <table>
89
+ <?php foreach ( $log_entries as $data ): ?>
90
+ <tr>
91
+ <?php foreach ( $data as $single_cell ): ?>
92
+ <td><?php echo esc_html( $single_cell ); ?></td>
93
+ <?php endforeach; ?>
94
+ </tr>
95
+ <?php endforeach; ?>
96
+ </table>
97
+
98
+ <?php if ( empty( $log_entries ) ): ?>
99
+ <p><?php esc_html_e( 'The selected log file is empty or has not been generated yet.', 'tribe-common' ); ?></p>
100
+ <?php endif; ?>
101
+
102
+ </div>
103
+
104
  <p> <a href="<?php echo esc_url( $download_url ) ?>" class="download_log" target="_blank"><?php esc_html_e( 'Download log', 'tribe-common' ); ?> </a> </p>
common/src/admin-views/tribe-options-display.php CHANGED
@@ -1,52 +1,52 @@
1
- <?php
2
-
3
- $sample_date = strtotime( 'January 15 ' . date( 'Y' ) );
4
-
5
- $displayTab = array(
6
- 'priority' => 20,
7
- 'fields' =>
8
- /**
9
- * Filter the fields available on the display settings tab
10
- *
11
- * @param array $fields a nested associative array of fields & field info passed to Tribe__Field
12
- * @see Tribe__Field
13
- */
14
- apply_filters(
15
- 'tribe_display_settings_tab_fields', array(
16
- 'tribe-form-content-start' => array(
17
- 'type' => 'html',
18
- 'html' => '<div class="tribe-settings-form-wrap">',
19
- ),
20
- 'tribeEventsDateFormatSettingsTitle' => array(
21
- 'type' => 'html',
22
- 'html' => '<h3>' . esc_html__( 'Date Format Settings', 'tribe-common' ) . '</h3>',
23
- ),
24
- 'tribeEventsDateFormatExplanation' => array(
25
- 'type' => 'html',
26
- 'html' => __( '<p>The following three fields accept the date format options available to the php date() function. <a href="http://codex.wordpress.org/Formatting_Date_and_Time" target="_blank">Learn how to make your own date format here</a>.</p>', 'tribe-common' ),
27
- ),
28
- 'datepickerFormat' => array(
29
- 'type' => 'dropdown_select2',
30
- 'label' => esc_html__( 'Datepicker Date Format', 'tribe-common' ),
31
- 'tooltip' => esc_html__( 'Select the date format to use in datepickers', 'tribe-common' ),
32
- 'default' => 'Y-m-d',
33
- 'options' => array(
34
- '0' => date( 'Y-m-d', $sample_date ),
35
- '1' => date( 'n/j/Y', $sample_date ),
36
- '2' => date( 'm/d/Y', $sample_date ),
37
- '3' => date( 'j/n/Y', $sample_date ),
38
- '4' => date( 'd/m/Y', $sample_date ),
39
- '5' => date( 'n-j-Y', $sample_date ),
40
- '6' => date( 'm-d-Y', $sample_date ),
41
- '7' => date( 'j-n-Y', $sample_date ),
42
- '8' => date( 'd-m-Y', $sample_date ),
43
- ),
44
- 'validation_type' => 'options',
45
- ),
46
- 'tribe-form-content-end' => array(
47
- 'type' => 'html',
48
- 'html' => '</div>',
49
- ),
50
- )
51
- ),
52
- );
1
+ <?php
2
+
3
+ $sample_date = strtotime( 'January 15 ' . date( 'Y' ) );
4
+
5
+ $displayTab = array(
6
+ 'priority' => 20,
7
+ 'fields' =>
8
+ /**
9
+ * Filter the fields available on the display settings tab
10
+ *
11
+ * @param array $fields a nested associative array of fields & field info passed to Tribe__Field
12
+ * @see Tribe__Field
13
+ */
14
+ apply_filters(
15
+ 'tribe_display_settings_tab_fields', array(
16
+ 'tribe-form-content-start' => array(
17
+ 'type' => 'html',
18
+ 'html' => '<div class="tribe-settings-form-wrap">',
19
+ ),
20
+ 'tribeEventsDateFormatSettingsTitle' => array(
21
+ 'type' => 'html',
22
+ 'html' => '<h3>' . esc_html__( 'Date Format Settings', 'tribe-common' ) . '</h3>',
23
+ ),
24
+ 'tribeEventsDateFormatExplanation' => array(
25
+ 'type' => 'html',
26
+ 'html' => __( '<p>The following three fields accept the date format options available to the php date() function. <a href="http://codex.wordpress.org/Formatting_Date_and_Time" target="_blank">Learn how to make your own date format here</a>.</p>', 'tribe-common' ),
27
+ ),
28
+ 'datepickerFormat' => array(
29
+ 'type' => 'dropdown_select2',
30
+ 'label' => esc_html__( 'Datepicker Date Format', 'tribe-common' ),
31
+ 'tooltip' => esc_html__( 'Select the date format to use in datepickers', 'tribe-common' ),
32
+ 'default' => 'Y-m-d',
33
+ 'options' => array(
34
+ '0' => date( 'Y-m-d', $sample_date ),
35
+ '1' => date( 'n/j/Y', $sample_date ),
36
+ '2' => date( 'm/d/Y', $sample_date ),
37
+ '3' => date( 'j/n/Y', $sample_date ),
38
+ '4' => date( 'd/m/Y', $sample_date ),
39
+ '5' => date( 'n-j-Y', $sample_date ),
40
+ '6' => date( 'm-d-Y', $sample_date ),
41
+ '7' => date( 'j-n-Y', $sample_date ),
42
+ '8' => date( 'd-m-Y', $sample_date ),
43
+ ),
44
+ 'validation_type' => 'options',
45
+ ),
46
+ 'tribe-form-content-end' => array(
47
+ 'type' => 'html',
48
+ 'html' => '</div>',
49
+ ),
50
+ )
51
+ ),
52
+ );
common/src/admin-views/tribe-options-general.php CHANGED
@@ -1,80 +1,80 @@
1
- <?php
2
-
3
- $generalTabFields = array(
4
- 'info-start' => array(
5
- 'type' => 'html',
6
- 'html' => '<div id="modern-tribe-info"><img src="' . plugins_url( 'resources/images/modern-tribe@2x.png', dirname( __FILE__ ) ) . '" alt="Modern Tribe Inc." title="Modern Tribe Inc.">',
7
- ),
8
- 'event-tickets-info' => array(
9
- 'type' => 'html',
10
- 'html' => '<p>' . sprintf( esc_html__( 'Thank you for using Event Tickets! All of us at Modern Tribe sincerely appreciate your support and we\'re excited to see you using our plugins. Check out our handy %1$sNew User Primer%2$s to get started.', 'tribe-common' ), '<a href="http://m.tri.be/18nd">', '</a>' ) . '</p>',
11
- 'conditional' => ! class_exists( 'Tribe__Events__Main' ),
12
- ),
13
- 'event-tickets-upsell-info' => array(
14
- 'type' => 'html',
15
- 'html' => '<p>' . sprintf( esc_html__( 'Optimize your site\'s event listings with %1$sThe Events Calendar%2$s, our free calendar plugin. Looking for additional functionality including recurring events, user-submission, advanced ticket sales and more? Check out our %3$spremium add-ons%4$s.', 'tribe-common' ), '<a href="http://m.tri.be/18x6">', '</a>', '<a href="http://m.tri.be/18x5">', '</a>' ) . '</p>',
16
- 'conditional' => ! class_exists( 'Tribe__Events__Main' ),
17
- ),
18
- 'upsell-info' => array(
19
- 'type' => 'html',
20
- 'html' => '<p>' . esc_html__( 'Looking for additional functionality including recurring events, custom meta, community events, ticket sales and more?', 'tribe-common' ) . ' <a href="' . Tribe__Main::$tec_url . 'products/?utm_source=generaltab&utm_medium=plugin-tec&utm_campaign=in-app">' . esc_html__( 'Check out the available add-ons', 'tribe-common' ) . '</a>.</p>',
21
- 'conditional' => ( ! defined( 'TRIBE_HIDE_UPSELL' ) || ! TRIBE_HIDE_UPSELL ) && class_exists( 'Tribe__Events__Main' ),
22
- ),
23
- 'donate-link-heading' => array(
24
- 'type' => 'heading',
25
- 'label' => esc_html__( 'We hope our plugin is helping you out.', 'tribe-common' ),
26
- 'conditional' => class_exists( 'Tribe__Events__Main' ),
27
- ),
28
- 'donate-link-info' => array(
29
- 'type' => 'html',
30
- 'html' => '<p>' . esc_html__( 'Are you thinking "Wow, this plugin is amazing! I should say thanks to Modern Tribe for all their hard work." The greatest thanks we could ask for is recognition. Add a small text-only link at the bottom of your calendar pointing to The Events Calendar project.', 'tribe-common' ) . '<br><a href="' . esc_url( plugins_url( 'resources/images/donate-link-screenshot.jpg', dirname( __FILE__ ) ) ) . '" class="thickbox">' . esc_html__( 'See an example of the link', 'tribe-common' ) . '</a>.</p>',
31
- 'conditional' => ! class_exists( 'Tribe__Events__Pro__Main' ) && class_exists( 'Tribe__Events__Main' ),
32
- ),
33
- 'donate-link-pro-info' => array(
34
- 'type' => 'html',
35
- 'html' => '<p>' . esc_html__( 'Are you thinking "Wow, this plugin is amazing! I should say thanks to Modern Tribe for all their hard work." The greatest thanks we could ask for is recognition. Add a small text only link at the bottom of your calendar pointing to The Events Calendar project.', 'tribe-common' ) . '<br><a href="' . esc_url( plugins_url( 'resources/images/donate-link-pro-screenshot.jpg', dirname( __FILE__ ) ) ) . '" class="thickbox">' . esc_html__( 'See an example of the link', 'tribe-common' ) . '</a>.</p>',
36
- 'conditional' => class_exists( 'Tribe__Events__Pro__Main' ),
37
- ),
38
- 'donate-link' => array(
39
- 'type' => 'checkbox_bool',
40
- 'label' => esc_html__( 'Show The Events Calendar link', 'tribe-common' ),
41
- 'default' => false,
42
- 'validation_type' => 'boolean',
43
- 'conditional' => class_exists( 'Tribe__Events__Main' ),
44
- ),
45
- 'info-end' => array(
46
- 'type' => 'html',
47
- 'html' => '</div>',
48
- ),
49
- 'tribe-form-content-start' => array(
50
- 'type' => 'html',
51
- 'html' => '<div class="tribe-settings-form-wrap">',
52
- ),
53
- );
54
-
55
- if ( is_super_admin() ) {
56
- $generalTabFields['debugEvents'] = array(
57
- 'type' => 'checkbox_bool',
58
- 'label' => esc_html__( 'Debug mode', 'tribe-common' ),
59
- 'default' => false,
60
- 'validation_type' => 'boolean',
61
- );
62
- $generalTabFields['debugEventsHelper'] = array(
63
- 'type' => 'html',
64
- 'html' => '<p class="tribe-field-indent tribe-field-description description" style="max-width:400px;">' . sprintf( esc_html__( 'Enable this option to log debug information. By default this will log to your server PHP error log. If you\'d like to see the log messages in your browser, then we recommend that you install the %s and look for the "Tribe" tab in the debug output.', 'tribe-common' ), '<a href="http://wordpress.org/extend/plugins/debug-bar/" target="_blank">' . esc_html__( 'Debug Bar Plugin', 'tribe-common' ) . '</a>' ) . '</p>',
65
- 'conditional' => ( '' != get_option( 'permalink_structure' ) ),
66
- );
67
- }
68
-
69
- // Closes form
70
- $generalTabFields['tribe-form-content-end'] = array(
71
- 'type' => 'html',
72
- 'html' => '</div>',
73
- );
74
-
75
-
76
- $generalTab = array(
77
- 'priority' => 10,
78
- 'fields' => apply_filters( 'tribe_general_settings_tab_fields', $generalTabFields ),
79
- );
80
-
1
+ <?php
2
+
3
+ $generalTabFields = array(
4
+ 'info-start' => array(
5
+ 'type' => 'html',
6
+ 'html' => '<div id="modern-tribe-info"><img src="' . plugins_url( 'resources/images/modern-tribe@2x.png', dirname( __FILE__ ) ) . '" alt="Modern Tribe Inc." title="Modern Tribe Inc.">',
7
+ ),
8
+ 'event-tickets-info' => array(
9
+ 'type' => 'html',
10
+ 'html' => '<p>' . sprintf( esc_html__( 'Thank you for using Event Tickets! All of us at Modern Tribe sincerely appreciate your support and we\'re excited to see you using our plugins. Check out our handy %1$sNew User Primer%2$s to get started.', 'tribe-common' ), '<a href="http://m.tri.be/18nd">', '</a>' ) . '</p>',
11
+ 'conditional' => ! class_exists( 'Tribe__Events__Main' ),
12
+ ),
13
+ 'event-tickets-upsell-info' => array(
14
+ 'type' => 'html',
15
+ 'html' => '<p>' . sprintf( esc_html__( 'Optimize your site\'s event listings with %1$sThe Events Calendar%2$s, our free calendar plugin. Looking for additional functionality including recurring events, user-submission, advanced ticket sales and more? Check out our %3$spremium add-ons%4$s.', 'tribe-common' ), '<a href="http://m.tri.be/18x6">', '</a>', '<a href="http://m.tri.be/18x5">', '</a>' ) . '</p>',
16
+ 'conditional' => ! class_exists( 'Tribe__Events__Main' ),
17
+ ),
18
+ 'upsell-info' => array(
19
+ 'type' => 'html',
20
+ 'html' => '<p>' . esc_html__( 'Looking for additional functionality including recurring events, custom meta, community events, ticket sales and more?', 'tribe-common' ) . ' <a href="' . Tribe__Main::$tec_url . 'products/?utm_source=generaltab&utm_medium=plugin-tec&utm_campaign=in-app">' . esc_html__( 'Check out the available add-ons', 'tribe-common' ) . '</a>.</p>',
21
+ 'conditional' => ( ! defined( 'TRIBE_HIDE_UPSELL' ) || ! TRIBE_HIDE_UPSELL ) && class_exists( 'Tribe__Events__Main' ),
22
+ ),
23
+ 'donate-link-heading' => array(
24
+ 'type' => 'heading',
25
+ 'label' => esc_html__( 'We hope our plugin is helping you out.', 'tribe-common' ),
26
+ 'conditional' => class_exists( 'Tribe__Events__Main' ),
27
+ ),
28
+ 'donate-link-info' => array(
29
+ 'type' => 'html',
30
+ 'html' => '<p>' . esc_html__( 'Are you thinking "Wow, this plugin is amazing! I should say thanks to Modern Tribe for all their hard work." The greatest thanks we could ask for is recognition. Add a small text-only link at the bottom of your calendar pointing to The Events Calendar project.', 'tribe-common' ) . '<br><a href="' . esc_url( plugins_url( 'resources/images/donate-link-screenshot.jpg', dirname( __FILE__ ) ) ) . '" class="thickbox">' . esc_html__( 'See an example of the link', 'tribe-common' ) . '</a>.</p>',
31
+ 'conditional' => ! class_exists( 'Tribe__Events__Pro__Main' ) && class_exists( 'Tribe__Events__Main' ),
32
+ ),
33
+ 'donate-link-pro-info' => array(
34
+ 'type' => 'html',
35
+ 'html' => '<p>' . esc_html__( 'Are you thinking "Wow, this plugin is amazing! I should say thanks to Modern Tribe for all their hard work." The greatest thanks we could ask for is recognition. Add a small text only link at the bottom of your calendar pointing to The Events Calendar project.', 'tribe-common' ) . '<br><a href="' . esc_url( plugins_url( 'resources/images/donate-link-pro-screenshot.jpg', dirname( __FILE__ ) ) ) . '" class="thickbox">' . esc_html__( 'See an example of the link', 'tribe-common' ) . '</a>.</p>',
36
+ 'conditional' => class_exists( 'Tribe__Events__Pro__Main' ),
37
+ ),
38
+ 'donate-link' => array(
39
+ 'type' => 'checkbox_bool',
40
+ 'label' => esc_html__( 'Show The Events Calendar link', 'tribe-common' ),
41
+ 'default' => false,
42
+ 'validation_type' => 'boolean',
43
+ 'conditional' => class_exists( 'Tribe__Events__Main' ),
44
+ ),
45
+ 'info-end' => array(
46
+ 'type' => 'html',
47
+ 'html' => '</div>',
48
+ ),
49
+ 'tribe-form-content-start' => array(
50
+ 'type' => 'html',
51
+ 'html' => '<div class="tribe-settings-form-wrap">',
52
+ ),
53
+ );
54
+
55
+ if ( is_super_admin() ) {
56
+ $generalTabFields['debugEvents'] = array(
57
+ 'type' => 'checkbox_bool',
58
+ 'label' => esc_html__( 'Debug mode', 'tribe-common' ),
59
+ 'default' => false,
60
+ 'validation_type' => 'boolean',
61
+ );
62
+ $generalTabFields['debugEventsHelper'] = array(
63
+ 'type' => 'html',
64
+ 'html' => '<p class="tribe-field-indent tribe-field-description description" style="max-width:400px;">' . sprintf( esc_html__( 'Enable this option to log debug information. By default this will log to your server PHP error log. If you\'d like to see the log messages in your browser, then we recommend that you install the %s and look for the "Tribe" tab in the debug output.', 'tribe-common' ), '<a href="http://wordpress.org/extend/plugins/debug-bar/" target="_blank">' . esc_html__( 'Debug Bar Plugin', 'tribe-common' ) . '</a>' ) . '</p>',
65
+ 'conditional' => ( '' != get_option( 'permalink_structure' ) ),
66
+ );
67
+ }
68
+
69
+ // Closes form
70
+ $generalTabFields['tribe-form-content-end'] = array(
71
+ 'type' => 'html',
72
+ 'html' => '</div>',
73
+ );
74
+
75
+
76
+ $generalTab = array(
77
+ 'priority' => 10,
78
+ 'fields' => apply_filters( 'tribe_general_settings_tab_fields', $generalTabFields ),
79
+ );
80
+
common/src/admin-views/tribe-options-help.php CHANGED
@@ -1,73 +1,73 @@
1
- <?php
2
- // Fetch the Help page Instance
3
- $help = Tribe__Admin__Help_Page::instance();
4
-
5
- // Fetch plugins
6
- $plugins = $help->get_plugins( null, false );
7
-
8
- // Creates the Feature Box section
9
- $help->add_section( 'feature-box', null, 0, 'box' );
10
- $help->add_section_content( 'feature-box', '<img src="' . esc_url( plugins_url( 'resources/images/modern-tribe@2x.png', dirname( __FILE__ ) ) ) . '" alt="Modern Tribe Inc." title="Modern Tribe Inc.">' );
11
- $help->add_section_content( 'feature-box', sprintf( esc_html__( 'Thanks you for using %s! All of us at Modern Tribe sincerely appreciate your support and we’re excited to see you using our plugins.', 'tribe-common' ), $help->get_plugins_text() ) );
12
-
13
- // Creates the Support section
14
- $help->add_section( 'support', __( 'Getting Support', 'tribe-common' ), 10 );
15
- $help->add_section_content( 'support', sprintf( __( 'Our website’s %s is a great place to find tips and tricks for using and customizing our plugins.', 'tribe-common' ), '<a href="http://m.tri.be/18j9" target="_blank">' . __( 'Knowledgebase', 'tribe-common' ) . '</a>' ), 0 );
16
- $help->add_section_content( 'support', sprintf( __( '<strong>Want to dive deeper?</strong> Check out our %s for developers.', 'tribe-common' ), '<a href="http://m.tri.be/18jf" target="_blank">' . __( 'list of available functions', 'tribe-common' ) . '</a>' ), 50 );
17
-
18
- // Creates the Extra Help section
19
- $help->add_section( 'extra-help', __( 'Getting More Help', 'tribe-common' ), 20 );
20
- $help->add_section_content( 'extra-help', __( 'While the resources above help solve a majority of the issues we see, there are times you might be looking for extra support. If you need assistance using our plugins and would like us to take a look, please follow these steps:', 'tribe-common' ), 0 );
21
- $help->add_section_content( 'extra-help', array(
22
- 'type' => 'ol',
23
-
24
- sprintf( __( '%s. All of the common (and not-so-common) answers to questions we see are here. It’s often the fastest path to finding an answer!', 'tribe-common' ), '<strong><a href="http://m.tri.be/18j9" target="_blank">' . __( 'Check our Knowledgebase', 'tribe-common' ) . '</a></strong>' ),
25
- sprintf( __( '%s. Testing for an existing conflict is the best start for in-depth troubleshooting. We will often ask you to follow these steps when opening a new thread, so doing this ahead of time will be super helpful.', 'tribe-common' ), '<strong><a href="http://m.tri.be/18jh" target="_blank">' . __( 'Test for a theme or plugin conflict', 'tribe-common' ) . '</a></strong>' ),
26
- sprintf( __( '%s. There are very few issues we haven’t seen and it’s likely another user has already asked your question and gotten an answer from our support staff. While posting to the forums is open only to paid customers, they are open for anyone to search and review.', 'tribe-common' ), '<strong><a href="http://m.tri.be/4w/" target="_blank">' . __( 'Search our support forum', 'tribe-common' ) . '</a></strong>' ),
27
- ), 10 );
28
-
29
- // By default these three will be gathered
30
- $help->add_section_content( 'extra-help', __( 'Please note that all hands-on support is provided via the forums. You can email or tweet at us… ​but we will probably point you back to the forums 😄', 'tribe-common' ), 40 );
31
- $help->add_section_content( 'extra-help', '<div style="text-align: right;"><a href="http://m.tri.be/18ji" target="_blank" class="button">' . __( 'Read more about our support policy', 'tribe-common' ) . '</a></div>', 40 );
32
-
33
- // Creates the System Info section
34
- $help->add_section( 'system-info', __( 'System Information', 'tribe-common' ), 30 );
35
- $help->add_section_content( 'system-info', __( 'The details of your calendar plugin and settings is often needed for you or our staff to help troubleshoot an issue. We may ask you to share this information if you ask for support. If you post in one of our premium forums, please copy and paste this information into the System Information field and it will help us help you faster!', 'tribe-common' ), 0 );
36
-
37
- $help->add_section( 'template-changes', __( 'Recent Template Changes', 'tribe-common' ), 40 );
38
- $help->add_section_content( 'template-changes', Tribe__Support__Template_Checker_Report::generate() );
39
- ?>
40
-
41
- <div id="tribe-help-general">
42
- <?php $help->get_sections(); ?>
43
- </div>
44
-
45
-
46
- <div id="tribe-help-sidebar">
47
- <?php
48
- /**
49
- * Fires at the top of the sidebar on Settings > Help tab
50
- */
51
- do_action( 'tribe_help_sidebar_before' );
52
-
53
- foreach ( $plugins as $key => $plugin ) {
54
- $help->print_plugin_box( $key );
55
- }
56
- ?>
57
- <h3><?php esc_html_e( 'News and Tutorials', 'tribe-common' ); ?></h3>
58
- <ul>
59
- <?php
60
- foreach ( $help->get_feed_items() as $item ) {
61
- echo '<li><a href="' . $help->get_ga_link( $item['link'], false ) . '">' . $item['title'] . '</a></li>';
62
- }
63
- echo '<li><a href="' . $help->get_ga_link( 'category/products' ) . '">' . esc_html__( 'More...', 'tribe-common' ) . '</a></li>';
64
- ?>
65
- </ul>
66
-
67
- <?php
68
- /**
69
- * Fires at the bottom of the sidebar on the Settings > Help tab
70
- */
71
- do_action( 'tribe_help_sidebar_after' ); ?>
72
-
73
  </div>
1
+ <?php
2
+ // Fetch the Help page Instance
3
+ $help = Tribe__Admin__Help_Page::instance();
4
+
5
+ // Fetch plugins
6
+ $plugins = $help->get_plugins( null, false );
7
+
8
+ // Creates the Feature Box section
9
+ $help->add_section( 'feature-box', null, 0, 'box' );
10
+ $help->add_section_content( 'feature-box', '<img src="' . esc_url( plugins_url( 'resources/images/modern-tribe@2x.png', dirname( __FILE__ ) ) ) . '" alt="Modern Tribe Inc." title="Modern Tribe Inc.">' );
11
+ $help->add_section_content( 'feature-box', sprintf( esc_html__( 'Thanks you for using %s! All of us at Modern Tribe sincerely appreciate your support and we’re excited to see you using our plugins.', 'tribe-common' ), $help->get_plugins_text() ) );
12
+
13
+ // Creates the Support section
14
+ $help->add_section( 'support', __( 'Getting Support', 'tribe-common' ), 10 );
15
+ $help->add_section_content( 'support', sprintf( __( 'Our website’s %s is a great place to find tips and tricks for using and customizing our plugins.', 'tribe-common' ), '<a href="http://m.tri.be/18j9" target="_blank">' . __( 'Knowledgebase', 'tribe-common' ) . '</a>' ), 0 );
16
+ $help->add_section_content( 'support', sprintf( __( '<strong>Want to dive deeper?</strong> Check out our %s for developers.', 'tribe-common' ), '<a href="http://m.tri.be/18jf" target="_blank">' . __( 'list of available functions', 'tribe-common' ) . '</a>' ), 50 );
17
+
18
+ // Creates the Extra Help section
19
+ $help->add_section( 'extra-help', __( 'Getting More Help', 'tribe-common' ), 20 );
20
+ $help->add_section_content( 'extra-help', __( 'While the resources above help solve a majority of the issues we see, there are times you might be looking for extra support. If you need assistance using our plugins and would like us to take a look, please follow these steps:', 'tribe-common' ), 0 );
21
+ $help->add_section_content( 'extra-help', array(
22
+ 'type' => 'ol',
23
+
24
+ sprintf( __( '%s. All of the common (and not-so-common) answers to questions we see are here. It’s often the fastest path to finding an answer!', 'tribe-common' ), '<strong><a href="http://m.tri.be/18j9" target="_blank">' . __( 'Check our Knowledgebase', 'tribe-common' ) . '</a></strong>' ),
25
+ sprintf( __( '%s. Testing for an existing conflict is the best start for in-depth troubleshooting. We will often ask you to follow these steps when opening a new thread, so doing this ahead of time will be super helpful.', 'tribe-common' ), '<strong><a href="http://m.tri.be/18jh" target="_blank">' . __( 'Test for a theme or plugin conflict', 'tribe-common' ) . '</a></strong>' ),
26
+ sprintf( __( '%s. There are very few issues we haven’t seen and it’s likely another user has already asked your question and gotten an answer from our support staff. While posting to the forums is open only to paid customers, they are open for anyone to search and review.', 'tribe-common' ), '<strong><a href="http://m.tri.be/4w/" target="_blank">' . __( 'Search our support forum', 'tribe-common' ) . '</a></strong>' ),
27
+ ), 10 );
28
+
29
+ // By default these three will be gathered
30
+ $help->add_section_content( 'extra-help', __( 'Please note that all hands-on support is provided via the forums. You can email or tweet at us… ​but we will probably point you back to the forums 😄', 'tribe-common' ), 40 );
31
+ $help->add_section_content( 'extra-help', '<div style="text-align: right;"><a href="http://m.tri.be/18ji" target="_blank" class="button">' . __( 'Read more about our support policy', 'tribe-common' ) . '</a></div>', 40 );
32
+
33
+ // Creates the System Info section
34
+ $help->add_section( 'system-info', __( 'System Information', 'tribe-common' ), 30 );
35
+ $help->add_section_content( 'system-info', __( 'The details of your calendar plugin and settings is often needed for you or our staff to help troubleshoot an issue. We may ask you to share this information if you ask for support. If you post in one of our premium forums, please copy and paste this information into the System Information field and it will help us help you faster!', 'tribe-common' ), 0 );
36
+
37
+ $help->add_section( 'template-changes', __( 'Recent Template Changes', 'tribe-common' ), 40 );
38
+ $help->add_section_content( 'template-changes', Tribe__Support__Template_Checker_Report::generate() );
39
+ ?>
40
+
41
+ <div id="tribe-help-general">
42
+ <?php $help->get_sections(); ?>
43
+ </div>
44
+
45
+
46
+ <div id="tribe-help-sidebar">
47
+ <?php
48
+ /**
49
+ * Fires at the top of the sidebar on Settings > Help tab
50
+ */
51
+ do_action( 'tribe_help_sidebar_before' );
52
+
53
+ foreach ( $plugins as $key => $plugin ) {
54
+ $help->print_plugin_box( $key );
55
+ }
56
+ ?>
57
+ <h3><?php esc_html_e( 'News and Tutorials', 'tribe-common' ); ?></h3>
58
+ <ul>
59
+ <?php
60
+ foreach ( $help->get_feed_items() as $item ) {
61
+ echo '<li><a href="' . $help->get_ga_link( $item['link'], false ) . '">' . $item['title'] . '</a></li>';
62
+ }
63
+ echo '<li><a href="' . $help->get_ga_link( 'category/products' ) . '">' . esc_html__( 'More...', 'tribe-common' ) . '</a></li>';
64
+ ?>
65
+ </ul>
66
+
67
+ <?php
68
+ /**
69
+ * Fires at the bottom of the sidebar on the Settings > Help tab
70
+ */
71
+ do_action( 'tribe_help_sidebar_after' ); ?>
72
+
73
  </div>
common/src/admin-views/tribe-options-licenses.php CHANGED
@@ -1,73 +1,73 @@
1
- <?php
2
- $link = add_query_arg(
3
- array(
4
- 'utm_campaign' => 'in-app',
5
- 'utm_medium' => 'plugin-tec',
6
- 'utm_source' => 'notice',
7
- ), Tribe__Main::$tec_url . 'license-keys/'
8
- );
9
-
10
- $link = esc_url( $link );
11
-
12
- // Explanatory text about license settings for the tab information box
13
- $html = __( '<p>The license key you received when completing your purchase from %1$s will grant you access to support and updates until it expires. You do not need to enter the key below for the plugins to work, but you will need to enter it to get automatic updates. <strong>Find your license keys at <a href="%2$s" target="_blank">%3$s</a></strong>.</p> <p>Each paid add-on has its own unique license key. Simply paste the key into its appropriate field on below, and give it a moment to validate. You know you\'re set when a green expiration date appears alongside a "valid" message.</p> <p>If you\'re seeing a red message telling you that your key isn\'t valid or is out of installs, visit <a href="%4$s" target="_blank">%5$s</a> to manage your installs or renew / upgrade your license.</p><p>Not seeing an update but expecting one? In WordPress, go to <a href="%6$s">Dashboard > Updates</a> and click "Check Again".</p>', 'tribe-common' );
14
-
15
- // Expand with extra information for mu network users
16
- if ( is_multisite() ) {
17
- $network_all_sites_text = sprintf(
18
- esc_html__( '%1$s Using our plugins in a multisite network? %2$s Please note that your license key will be applied to the entire network, not just this site.', 'tribe-common' ),
19
- '<strong>',
20
- '</strong>'
21
- );
22
-
23
- $network_admin_only = '';
24
-
25
- if ( is_network_admin() ) {
26
- $network_admin_only = sprintf(
27
- esc_html__(
28
- 'Only license fields for %1$snetwork activated%2$s plugins will be listed on this screen. ',
29
- 'tribe-common'
30
- ),
31
- '<strong>',
32
- '</strong>'
33
- );
34
- }
35
-
36
- $html .= "<p> $network_all_sites_text $network_admin_only </p>";
37
- }
38
-
39
- $licenses_tab = array(
40
- 'info-start' => array(
41
- 'type' => 'html',
42
- 'html' => '<div id="modern-tribe-info">',
43
- ),
44
- 'info-box-title' => array(
45
- 'type' => 'html',
46
- 'html' => '<h2>' . esc_html__( 'Licenses', 'tribe-common' ) . '</h2>',
47
- ),
48
- 'info-box-description' => array(
49
- 'type' => 'html',
50
- 'html' => sprintf(
51
- $html,
52
- Tribe__Main::$tec_url,
53
- $link,
54
- Tribe__Main::$tec_url . 'license-keys/',
55
- $link,
56
- Tribe__Main::$tec_url . 'license-keys/',
57
- admin_url( '/update-core.php' )
58
- ),
59
- ),
60
- 'info-end' => array(
61
- 'type' => 'html',
62
- 'html' => '</div>',
63
- ),
64
- 'tribe-form-content-start' => array(
65
- 'type' => 'html',
66
- 'html' => '<div class="tribe-settings-form-wrap">',
67
- ),
68
- // TODO: Figure out how properly close this wrapper after the license content
69
- 'tribe-form-content-end' => array(
70
- 'type' => 'html',
71
- 'html' => '</div>',
72
- ),
73
- );
1
+ <?php
2
+ $link = add_query_arg(
3
+ array(
4
+ 'utm_campaign' => 'in-app',
5
+ 'utm_medium' => 'plugin-tec',
6
+ 'utm_source' => 'notice',
7
+ ), Tribe__Main::$tec_url . 'license-keys/'
8
+ );
9
+
10
+ $link = esc_url( $link );
11
+
12
+ // Explanatory text about license settings for the tab information box
13
+ $html = __( '<p>The license key you received when completing your purchase from %1$s will grant you access to support and updates until it expires. You do not need to enter the key below for the plugins to work, but you will need to enter it to get automatic updates. <strong>Find your license keys at <a href="%2$s" target="_blank">%3$s</a></strong>.</p> <p>Each paid add-on has its own unique license key. Simply paste the key into its appropriate field on below, and give it a moment to validate. You know you\'re set when a green expiration date appears alongside a "valid" message.</p> <p>If you\'re seeing a red message telling you that your key isn\'t valid or is out of installs, visit <a href="%4$s" target="_blank">%5$s</a> to manage your installs or renew / upgrade your license.</p><p>Not seeing an update but expecting one? In WordPress, go to <a href="%6$s">Dashboard > Updates</a> and click "Check Again".</p>', 'tribe-common' );
14
+
15
+ // Expand with extra information for mu network users
16
+ if ( is_multisite() ) {
17
+ $network_all_sites_text = sprintf(
18
+ esc_html__( '%1$s Using our plugins in a multisite network? %2$s Please note that your license key will be applied to the entire network, not just this site.', 'tribe-common' ),
19
+ '<strong>',
20
+ '</strong>'
21
+ );
22
+
23
+ $network_admin_only = '';
24
+
25
+ if ( is_network_admin() ) {
26
+ $network_admin_only = sprintf(
27
+ esc_html__(
28
+ 'Only license fields for %1$snetwork activated%2$s plugins will be listed on this screen. ',
29
+ 'tribe-common'
30
+ ),
31
+ '<strong>',
32
+ '</strong>'
33
+ );
34
+ }
35
+
36
+ $html .= "<p> $network_all_sites_text $network_admin_only </p>";
37
+ }
38
+
39
+ $licenses_tab = array(
40
+ 'info-start' => array(
41
+ 'type' => 'html',
42
+ 'html' => '<div id="modern-tribe-info">',
43
+ ),
44
+ 'info-box-title' => array(
45
+ 'type' => 'html',
46
+ 'html' => '<h2>' . esc_html__( 'Licenses', 'tribe-common' ) . '</h2>',
47
+ ),
48
+ 'info-box-description' => array(
49
+ 'type' => 'html',
50
+ 'html' => sprintf(
51
+ $html,
52
+ Tribe__Main::$tec_url,
53
+ $link,
54
+ Tribe__Main::$tec_url . 'license-keys/',
55
+ $link,
56
+ Tribe__Main::$tec_url . 'license-keys/',
57
+ admin_url( '/update-core.php' )
58
+ ),
59
+ ),
60
+ 'info-end' => array(
61
+ 'type' => 'html',
62
+ 'html' => '</div>',
63
+ ),
64
+ 'tribe-form-content-start' => array(
65
+ 'type' => 'html',
66
+ 'html' => '<div class="tribe-settings-form-wrap">',
67
+ ),
68
+ // TODO: Figure out how properly close this wrapper after the license content
69
+ 'tribe-form-content-end' => array(
70
+ 'type' => 'html',
71
+ 'html' => '</div>',
72
+ ),
73
+ );
common/src/admin-views/tribe-options-network.php CHANGED
@@ -1,35 +1,35 @@
1
- <?php
2
- $allTabs = apply_filters( 'tribe_settings_all_tabs', array() );
3
-
4
- $networkTab = array(
5
- 'priority' => 10,
6
- 'network_admin' => true,
7
- 'fields' => apply_filters(
8
- 'tribe_network_settings_tab_fields', array(
9
- 'info-start' => array(
10
- 'type' => 'html',
11
- 'html' => '<div id="modern-tribe-info">',
12
- ),
13
- 'info-box-title' => array(
14
- 'type' => 'html',
15
- 'html' => '<h1>' . esc_html__( 'Network Settings', 'tribe-common' ) . '</h1>',
16
- ),
17
- 'info-box-description' => array(
18
- 'type' => 'html',
19
- 'html' => '<p>' . esc_html__( 'This is where all of the global network settings for Modern Tribe\'s The Events Calendar can be modified.', 'tribe-common' ) . '</p>',
20
- ),
21
- 'info-end' => array(
22
- 'type' => 'html',
23
- 'html' => '</div>',
24
- ),
25
- 'hideSettingsTabs' => array(
26
- 'type' => 'checkbox_list',
27
- 'label' => esc_html__( 'Hide the following settings tabs on every site:', 'tribe-common' ),
28
- 'default' => false,
29
- 'options' => $allTabs,
30
- 'validation_type' => 'options_multi',
31
- 'can_be_empty' => true,
32
- ),
33
- )
34
- ),
35
- );
1
+ <?php
2
+ $allTabs = apply_filters( 'tribe_settings_all_tabs', array() );
3
+
4
+ $networkTab = array(
5
+ 'priority' => 10,
6
+ 'network_admin' => true,
7
+ 'fields' => apply_filters(
8
+ 'tribe_network_settings_tab_fields', array(
9
+ 'info-start' => array(
10
+ 'type' => 'html',
11
+ 'html' => '<div id="modern-tribe-info">',
12
+ ),
13
+ 'info-box-title' => array(
14
+ 'type' => 'html',
15
+ 'html' => '<h1>' . esc_html__( 'Network Settings', 'tribe-common' ) . '</h1>',
16
+ ),
17
+ 'info-box-description' => array(
18
+ 'type' => 'html',
19
+ 'html' => '<p>' . esc_html__( 'This is where all of the global network settings for Modern Tribe\'s The Events Calendar can be modified.', 'tribe-common' ) . '</p>',
20
+ ),
21
+ 'info-end' => array(
22
+ 'type' => 'html',
23
+ 'html' => '</div>',
24
+ ),
25
+ 'hideSettingsTabs' => array(
26
+ 'type' => 'checkbox_list',
27
+ 'label' => esc_html__( 'Hide the following settings tabs on every site:', 'tribe-common' ),
28
+ 'default' => false,
29
+ 'options' => $allTabs,
30
+ 'validation_type' => 'options_multi',
31
+ 'can_be_empty' => true,
32
+ ),
33
+ )
34
+ ),
35
+ );
common/src/deprecated/Tribe__Events__Abstract_Deactivation.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Abstract_Deactivation.php' );
3
-
4
- abstract class Tribe__Events__Abstract_Deactivation extends Tribe__Abstract_Deactivation {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Abstract_Deactivation.php' );
3
+
4
+ abstract class Tribe__Events__Abstract_Deactivation extends Tribe__Abstract_Deactivation {}
common/src/deprecated/Tribe__Events__Admin__Helpers.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Admin__Helpers.php' );
3
-
4
- class Tribe__Events__Admin__Helpers extends Tribe__Admin__Helpers {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Admin__Helpers.php' );
3
+
4
+ class Tribe__Events__Admin__Helpers extends Tribe__Admin__Helpers {}
common/src/deprecated/Tribe__Events__App_Shop.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__App_Shop.php' );
3
-
4
- class Tribe__Events__App_Shop extends Tribe__App_Shop {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__App_Shop.php' );
3
+
4
+ class Tribe__Events__App_Shop extends Tribe__App_Shop {}
common/src/deprecated/Tribe__Events__Autoloader.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Autoloader.php' );
3
-
4
- class Tribe__Events__Autoloader extends Tribe__Autoloader {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Autoloader.php' );
3
+
4
+ class Tribe__Events__Autoloader extends Tribe__Autoloader {}
common/src/deprecated/Tribe__Events__Cache.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Cache.php' );
3
-
4
- class Tribe__Events__Cache extends Tribe__Cache {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Cache.php' );
3
+
4
+ class Tribe__Events__Cache extends Tribe__Cache {}
common/src/deprecated/Tribe__Events__Cache_Listener.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Cache_Listener.php' );
3
-
4
- class Tribe__Events__Cache_Listener extends Tribe__Cache_Listener {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Cache_Listener.php' );
3
+
4
+ class Tribe__Events__Cache_Listener extends Tribe__Cache_Listener {}
common/src/deprecated/Tribe__Events__Changelog_Reader.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Changelog_Reader.php' );
3
-
4
- class Tribe__Events__Changelog_Reader extends Tribe__Changelog_Reader {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Changelog_Reader.php' );
3
+
4
+ class Tribe__Events__Changelog_Reader extends Tribe__Changelog_Reader {}
common/src/deprecated/Tribe__Events__Credits.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Credits.php' );
3
-
4
- class Tribe__Events__Credits extends Tribe__Credits {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Credits.php' );
3
+
4
+ class Tribe__Events__Credits extends Tribe__Credits {}
common/src/deprecated/Tribe__Events__Date_Utils.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Date_Utils.php' );
3
-
4
- class Tribe__Events__Date_Utils extends Tribe__Date_Utils {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Date_Utils.php' );
3
+
4
+ class Tribe__Events__Date_Utils extends Tribe__Date_Utils {}
common/src/deprecated/Tribe__Events__Field.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Field.php' );
3
-
4
- class Tribe__Events__Field extends Tribe__Field {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Field.php' );
3
+
4
+ class Tribe__Events__Field extends Tribe__Field {}
common/src/deprecated/Tribe__Events__Settings.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Settings.php' );
3
-
4
- class Tribe__Events__Settings extends Tribe__Settings {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Settings.php' );
3
+
4
+ class Tribe__Events__Settings extends Tribe__Settings {}
common/src/deprecated/Tribe__Events__Settings_Tab.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Settings_Tab.php' );
3
-
4
- class Tribe__Events__Settings_Tab extends Tribe__Settings_Tab {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Settings_Tab.php' );
3
+
4
+ class Tribe__Events__Settings_Tab extends Tribe__Settings_Tab {}
common/src/deprecated/Tribe__Events__Support.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Support.php' );
3
-
4
- class Tribe__Events__Support extends Tribe__Support {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Support.php' );
3
+
4
+ class Tribe__Events__Support extends Tribe__Support {}
common/src/deprecated/Tribe__Events__Template_Part_Cache.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Template_Part_Cache.php' );
3
-
4
- class Tribe__Events__Template_Part_Cache extends Tribe__Template_Part_Cache {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Template_Part_Cache.php' );
3
+
4
+ class Tribe__Events__Template_Part_Cache extends Tribe__Template_Part_Cache {}
common/src/deprecated/Tribe__Events__Validate.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__Validate.php' );
3
-
4
- class Tribe__Events__Validate extends Tribe__Validate {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__Validate.php' );
3
+
4
+ class Tribe__Events__Validate extends Tribe__Validate {}
common/src/deprecated/Tribe__Events__View_Helpers.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- _deprecated_file( __FILE__, '4.0', 'Tribe__View_Helpers.php' );
3
-
4
- class Tribe__Events__View_Helpers extends Tribe__View_Helpers {}
1
+ <?php
2
+ _deprecated_file( __FILE__, '4.0', 'Tribe__View_Helpers.php' );
3
+
4
+ class Tribe__Events__View_Helpers extends Tribe__View_Helpers {}
common/src/functions/template-tags/date.php CHANGED
@@ -1,357 +1,357 @@
1
- <?php
2
- /**
3
- * Date Functions
4
- *
5
- * Display functions (template-tags) for use in WordPress templates.
6
- */
7
-
8
- // Don't load directly
9
- if ( ! defined( 'ABSPATH' ) ) {
10
- die( '-1' );
11
- }
12
-
13
- if ( ! class_exists( 'Tribe__Main' ) ) {
14
- return;
15
- }
16
-
17
- if ( ! function_exists( 'tribe_format_date' ) ) {
18
- /**
19
- * Formatted Date
20
- *
21
- * Returns formatted date
22
- *
23
- * @category Events
24
- *
25
- * @param string $date String representing the datetime, assumed to be UTC (relevant if timezone conversion is used)
26
- * @param bool $display_time If true shows date and time, if false only shows date
27
- * @param string $date_format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
28
- *
29
- * @return string
30
- */
31
- function tribe_format_date( $date, $display_time = true, $date_format = '' ) {
32
-
33
- if ( ! Tribe__Date_Utils::is_timestamp( $date ) ) {
34
- $date = strtotime( $date );
35
- }
36
-
37
- if ( $date_format ) {
38
- $format = $date_format;
39
- } else {
40
- $date_year = date( 'Y', $date );
41
- $cur_year = date( 'Y', current_time( 'timestamp' ) );
42
-
43
- // only show the year in the date if it's not in the current year
44
- $with_year = $date_year == $cur_year ? false : true;
45
-
46
- if ( $display_time ) {
47
- $format = tribe_get_datetime_format( $with_year );
48
- } else {
49
- $format = tribe_get_date_format( $with_year );
50
- }
51
- }
52
-
53
- $date = date_i18n( $format, $date );
54
-
55
- /**
56
- * Deprecated tribe_event_formatted_date in 4.0 in favor of tribe_formatted_date. Remove in 5.0
57
- */
58
- $date = apply_filters( 'tribe_event_formatted_date', $date, $display_time, $date_format );
59
-
60
- return apply_filters( 'tribe_formatted_date', $date, $display_time, $date_format );
61
- }
62
- }//end if
63
-
64
- if ( ! function_exists( 'tribe_beginning_of_day' ) ) {
65
- /**
66
- * Returns formatted date for the official beginning of the day according to the Multi-day cutoff time option
67
- *
68
- * @category Events
69
- *
70
- * @param string $date The date to find the beginning of the day, defaults to today
71
- * @param string $format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
72
- *
73
- * @return string
74
- */
75
- function tribe_beginning_of_day( $date = null, $format = 'Y-m-d H:i:s' ) {
76
- $multiday_cutoff = explode( ':', tribe_get_option( 'multiDayCutoff', '00:00' ) );
77
- $hours_to_add = $multiday_cutoff[0];
78
- $minutes_to_add = $multiday_cutoff[1];
79
- if ( is_null( $date ) || empty( $date ) ) {
80
- $date = date( $format, strtotime( date( 'Y-m-d' ) . ' +' . $hours_to_add . ' hours ' . $minutes_to_add . ' minutes' ) );
81
- } else {
82
- $date = date( $format, strtotime( date( 'Y-m-d', strtotime( $date ) ) . ' +' . $hours_to_add . ' hours ' . $minutes_to_add . ' minutes' ) );
83
- }
84
-
85
- /**
86
- * Deprecated filter tribe_event_beginning_of_day in 4.0 in favor of tribe_beginning_of_day. Remove in 5.0
87
- */
88
- $date = apply_filters( 'tribe_event_beginning_of_day', $date );
89
-
90
- /**
91
- * Filters the beginning of day date
92
- *
93
- * @param string $date
94
- */
95
- return apply_filters( 'tribe_beginning_of_day', $date );
96
- }
97
- }//end if
98
-
99
- if ( ! function_exists( 'tribe_end_of_day' ) ) {
100
- /**
101
- * Returns formatted date for the official end of the day according to the Multi-day cutoff time option
102
- *
103
- * @category Events
104
- *
105
- * @param string $date The date to find the end of the day, defaults to today
106
- * @param string $format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
107
- *
108
- * @return string
109
- */
110
- function tribe_end_of_day( $date = null, $format = 'Y-m-d H:i:s' ) {
111
- $multiday_cutoff = explode( ':', tribe_get_option( 'multiDayCutoff', '00:00' ) );
112
- $hours_to_add = $multiday_cutoff[0];
113
- $minutes_to_add = $multiday_cutoff[1];
114
- if ( is_null( $date ) || empty( $date ) ) {
115
- $date = date( $format, strtotime( 'tomorrow +' . $hours_to_add . ' hours ' . $minutes_to_add . ' minutes' ) - 1 );
116
- } else {
117
- $date = date( $format, strtotime( date( 'Y-m-d', strtotime( $date ) ) . ' +1 day ' . $hours_to_add . ' hours ' . $minutes_to_add . ' minutes' ) - 1 );
118
- }
119
-
120
- /**
121
- * Deprecated filter tribe_event_end_of_day in 4.0 in favor of tribe_end_of_day. Remove in 5.0
122
- */
123
- $date = apply_filters( 'tribe_event_end_of_day', $date );
124
-
125
- /**
126
- * Filters the end of day date
127
- *
128
- * @param string $date
129
- */
130
- return apply_filters( 'tribe_end_of_day', $date );
131
- }
132
- }//end if
133
-
134
- if ( ! function_exists( 'tribe_get_datetime_separator' ) ) {
135
- /**
136
- * Get the datetime saparator from the database option with escaped characters or not ;)
137
- *
138
- * @param string $default Default Separator if it's blank on the Database
139
- * @param bool $esc If it's going to be used on a `date` function or method it needs to be escaped
140
- *
141
- * @filter tribe_datetime_separator
142
- *
143
- * @return string
144
- */
145
- function tribe_get_datetime_separator( $default = ' @ ', $esc = false ) {
146
- $separator = (string) tribe_get_option( 'dateTimeSeparator', $default );
147
- if ( $esc ) {
148
- $separator = (array) str_split( $separator );
149
- $separator = ( ! empty( $separator ) ? '\\' : '' ) . implode( '\\', $separator );
150
- }
151
-
152
- return apply_filters( 'tribe_datetime_separator', $separator );
153
- }
154
- }//end if
155
-
156
- if ( ! function_exists( 'tribe_get_start_time' ) ) {
157
- /**
158
- * Start Time
159
- *
160
- * Returns the event start time
161
- *
162
- * @category Events
163
- *
164
- * @param int $event (optional)
165
- * @param string $date_format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
166
- * @param string $timezone Timezone in which to present the date/time (or default behaviour if not set)
167
- *
168
- * @return string|null Time
169
- */
170
- function tribe_get_start_time( $event = null, $date_format = '', $timezone = null ) {
171
- if ( is_null( $event ) ) {
172
- global $post;
173
- $event = $post;
174
- }
175
-
176
- if ( is_numeric( $event ) ) {
177
- $event = get_post( $event );
178
- }
179
-
180
- if ( ! is_object( $event ) ) {
181
- return;
182
- }
183
-
184
- if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
185
- return;
186
- }
187
-
188
- // @todo move timezones to Common
189
- if ( class_exists( 'Tribe__Events__Timezones' ) ) {
190
- $start_date = Tribe__Events__Timezones::event_start_timestamp( $event->ID, $timezone );
191
- }
192
-
193
- if ( '' == $date_format ) {
194
- $date_format = tribe_get_time_format();
195
- }
196
-
197
- return tribe_format_date( $start_date, false, $date_format );
198
- }
199
- }
200
-
201
- if ( ! function_exists( 'tribe_get_end_time' ) ) {
202
- /**
203
- * End Time
204
- *
205
- * Returns the event end time
206
- *
207
- * @category Events
208
- *
209
- * @param int $event (optional)
210
- * @param string $date_format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
211
- * @param string $timezone Timezone in which to present the date/time (or default behaviour if not set)
212
- *
213
- * @return string|null Time
214
- */
215
- function tribe_get_end_time( $event = null, $date_format = '', $timezone = null ) {
216
- if ( is_null( $event ) ) {
217
- global $post;
218
- $event = $post;
219
- }
220
-
221
- if ( is_numeric( $event ) ) {
222
- $event = get_post( $event );
223
- }
224
-
225
- if ( ! is_object( $event ) ) {
226
- return;
227
- }
228
-
229
- if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
230
- return;
231
- }
232
-
233
- // @todo move timezones to Common
234
- if ( class_exists( 'Tribe__Events__Timezones' ) ) {
235
- $end_date = Tribe__Events__Timezones::event_end_timestamp( $event->ID, $timezone );
236
- }
237
-
238
- if ( '' == $date_format ) {
239
- $date_format = tribe_get_time_format();
240
- }
241
-
242
- return tribe_format_date( $end_date, false, $date_format );
243
- }
244
- }
245
-
246
- if ( ! function_exists( 'tribe_get_start_date' ) ) {
247
- /**
248
- * Start Date
249
- *
250
- * Returns the event start date and time
251
- *
252
- * @category Events
253
- *
254
- * @param int $event (optional)
255
- * @param bool $display_time If true shows date and time, if false only shows date
256
- * @param string $date_format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
257
- * @param string $timezone Timezone in which to present the date/time (or default behaviour if not set)
258
- *
259
- * @return string|null Date
260
- */
261
- function tribe_get_start_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
262
- if ( is_null( $event ) ) {
263
- global $post;
264
- $event = $post;
265
- }
266
-
267
- if ( is_numeric( $event ) ) {
268
- $event = get_post( $event );
269
- }
270
-
271
- if ( ! is_object( $event ) ) {
272
- return '';
273
- }
274
-
275
- if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
276
- $display_time = false;
277
- }
278
-
279
- // @todo move timezones to Common
280
- if ( class_exists( 'Tribe__Events__Timezones' ) ) {
281
- $start_date = Tribe__Events__Timezones::event_start_timestamp( $event->ID, $timezone );
282
- } else {
283
- return null;
284
- }
285
-
286
- return tribe_format_date( $start_date, $display_time, $date_format );
287
- }
288
- }
289
-
290
- if ( ! function_exists( 'tribe_get_end_date' ) ) {
291
- /**
292
- * End Date
293
- *
294
- * Returns the event end date
295
- *
296
- * @category Events
297
- *
298
- * @param int $event (optional)
299
- * @param bool $display_time If true shows date and time, if false only shows date
300
- * @param string $date_format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
301
- * @param string $timezone Timezone in which to present the date/time (or default behaviour if not set)
302
- *
303
- * @return string|null Date
304
- */
305
- function tribe_get_end_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
306
- if ( is_null( $event ) ) {
307
- global $post;
308
- $event = $post;
309
- }
310
-
311
- if ( is_numeric( $event ) ) {
312
- $event = get_post( $event );
313
- }
314
-
315
- if ( ! is_object( $event ) ) {
316
- return '';
317
- }
318
-
319
- if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
320
- $display_time = false;
321
- }
322
-
323
- // @todo move timezones to Common
324
- if ( class_exists( 'Tribe__Events__Timezones' ) ) {
325
- $end_date = Tribe__Events__Timezones::event_end_timestamp( $event->ID, $timezone );
326
- } else {
327
- return null;
328
- }
329
-
330
- return tribe_format_date( $end_date, $display_time, $date_format );
331
- }
332
- }
333
-
334
- if ( ! function_exists( 'tribe_normalize_manual_utc_offset' ) ) {
335
- /**
336
- * Normalizes a manual UTC offset string.
337
- *
338
- * @param string $utc_offset
339
- *
340
- * @return string The normalized manual UTC offset.
341
- * e.g. 'UTC+3', 'UTC-4.5', 'UTC+2.75'
342
- */
343
- function tribe_normalize_manual_utc_offset( $utc_offset ) {
344
- $matches = array();
345
- if ( preg_match( '/^UTC\\s*((\\+|-)(\\d{1,2}))((:|.|,)(\\d{1,2})+)*/ui', $utc_offset, $matches ) ) {
346
- if ( ! empty( $matches[6] ) ) {
347
- $minutes = $matches[6] > 10 && $matches[6] <= 60 ? $minutes = $matches[6] / 60 : $matches[6];
348
- $minutes = str_replace( '0.', '', $minutes );
349
- }
350
-
351
- $utc_offset = sprintf( 'UTC%s%s', $matches[1], ! empty( $minutes ) ? '.' . $minutes : '' );
352
-
353
- }
354
-
355
- return $utc_offset;
356
- }
357
- }
1
+ <?php
2
+ /**
3
+ * Date Functions
4
+ *
5
+ * Display functions (template-tags) for use in WordPress templates.
6
+ */
7
+
8
+ // Don't load directly
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ die( '-1' );
11
+ }
12
+
13
+ if ( ! class_exists( 'Tribe__Main' ) ) {
14
+ return;
15
+ }
16
+
17
+ if ( ! function_exists( 'tribe_format_date' ) ) {
18
+ /**
19
+ * Formatted Date
20
+ *
21
+ * Returns formatted date
22
+ *
23
+ * @category Events
24
+ *
25
+ * @param string $date String representing the datetime, assumed to be UTC (relevant if timezone conversion is used)
26
+ * @param bool $display_time If true shows date and time, if false only shows date
27
+ * @param string $date_format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
28
+ *
29
+ * @return string
30
+ */
31
+ function tribe_format_date( $date, $display_time = true, $date_format = '' ) {
32
+
33
+ if ( ! Tribe__Date_Utils::is_timestamp( $date ) ) {
34
+ $date = strtotime( $date );
35
+ }
36
+
37
+ if ( $date_format ) {
38
+ $format = $date_format;
39
+ } else {
40
+ $date_year = date( 'Y', $date );
41
+ $cur_year = date( 'Y', current_time( 'timestamp' ) );
42
+
43
+ // only show the year in the date if it's not in the current year
44
+ $with_year = $date_year == $cur_year ? false : true;
45
+
46
+ if ( $display_time ) {
47
+ $format = tribe_get_datetime_format( $with_year );
48
+ } else {
49
+ $format = tribe_get_date_format( $with_year );
50
+ }
51
+ }
52
+
53
+ $date = date_i18n( $format, $date );
54
+
55
+ /**
56
+ * Deprecated tribe_event_formatted_date in 4.0 in favor of tribe_formatted_date. Remove in 5.0
57
+ */
58
+ $date = apply_filters( 'tribe_event_formatted_date', $date, $display_time, $date_format );
59
+
60
+ return apply_filters( 'tribe_formatted_date', $date, $display_time, $date_format );
61
+ }
62
+ }//end if
63
+
64
+ if ( ! function_exists( 'tribe_beginning_of_day' ) ) {
65
+ /**
66
+ * Returns formatted date for the official beginning of the day according to the Multi-day cutoff time option
67
+ *
68
+ * @category Events
69
+ *
70
+ * @param string $date The date to find the beginning of the day, defaults to today
71
+ * @param string $format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
72
+ *
73
+ * @return string
74
+ */
75
+ function tribe_beginning_of_day( $date = null, $format = 'Y-m-d H:i:s' ) {
76
+ $multiday_cutoff = explode( ':', tribe_get_option( 'multiDayCutoff', '00:00' ) );
77
+ $hours_to_add = $multiday_cutoff[0];
78
+ $minutes_to_add = $multiday_cutoff[1];
79
+ if ( is_null( $date ) || empty( $date ) ) {
80
+ $date = date( $format, strtotime( date( 'Y-m-d' ) . ' +' . $hours_to_add . ' hours ' . $minutes_to_add . ' minutes' ) );
81
+ } else {
82
+ $date = date( $format, strtotime( date( 'Y-m-d', strtotime( $date ) ) . ' +' . $hours_to_add . ' hours ' . $minutes_to_add . ' minutes' ) );
83
+ }
84
+
85
+ /**
86
+ * Deprecated filter tribe_event_beginning_of_day in 4.0 in favor of tribe_beginning_of_day. Remove in 5.0
87
+ */
88
+ $date = apply_filters( 'tribe_event_beginning_of_day', $date );
89
+
90
+ /**
91
+ * Filters the beginning of day date
92
+ *
93
+ * @param string $date
94
+ */
95
+ return apply_filters( 'tribe_beginning_of_day', $date );
96
+ }
97
+ }//end if
98
+
99
+ if ( ! function_exists( 'tribe_end_of_day' ) ) {
100
+ /**
101
+ * Returns formatted date for the official end of the day according to the Multi-day cutoff time option
102
+ *
103
+ * @category Events
104
+ *
105
+ * @param string $date The date to find the end of the day, defaults to today
106
+ * @param string $format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
107
+ *
108
+ * @return string
109
+ */
110
+ function tribe_end_of_day( $date = null, $format = 'Y-m-d H:i:s' ) {
111
+ $multiday_cutoff = explode( ':', tribe_get_option( 'multiDayCutoff', '00:00' ) );
112
+ $hours_to_add = $multiday_cutoff[0];
113
+ $minutes_to_add = $multiday_cutoff[1];
114
+ if ( is_null( $date ) || empty( $date ) ) {
115
+ $date = date( $format, strtotime( 'tomorrow +' . $hours_to_add . ' hours ' . $minutes_to_add . ' minutes' ) - 1 );
116
+ } else {
117
+ $date = date( $format, strtotime( date( 'Y-m-d', strtotime( $date ) ) . ' +1 day ' . $hours_to_add . ' hours ' . $minutes_to_add . ' minutes' ) - 1 );
118
+ }
119
+
120
+ /**
121
+ * Deprecated filter tribe_event_end_of_day in 4.0 in favor of tribe_end_of_day. Remove in 5.0
122
+ */
123
+ $date = apply_filters( 'tribe_event_end_of_day', $date );
124
+
125
+ /**
126
+ * Filters the end of day date
127
+ *
128
+ * @param string $date
129
+ */
130
+ return apply_filters( 'tribe_end_of_day', $date );
131
+ }
132
+ }//end if
133
+
134
+ if ( ! function_exists( 'tribe_get_datetime_separator' ) ) {
135
+ /**
136
+ * Get the datetime saparator from the database option with escaped characters or not ;)
137
+ *
138
+ * @param string $default Default Separator if it's blank on the Database
139
+ * @param bool $esc If it's going to be used on a `date` function or method it needs to be escaped
140
+ *
141
+ * @filter tribe_datetime_separator
142
+ *
143
+ * @return string
144
+ */
145
+ function tribe_get_datetime_separator( $default = ' @ ', $esc = false ) {
146
+ $separator = (string) tribe_get_option( 'dateTimeSeparator', $default );
147
+ if ( $esc ) {
148
+ $separator = (array) str_split( $separator );
149
+ $separator = ( ! empty( $separator ) ? '\\' : '' ) . implode( '\\', $separator );
150
+ }
151
+
152
+ return apply_filters( 'tribe_datetime_separator', $separator );
153
+ }
154
+ }//end if
155
+
156
+ if ( ! function_exists( 'tribe_get_start_time' ) ) {
157
+ /**
158
+ * Start Time
159
+ *
160
+ * Returns the event start time
161
+ *
162
+ * @category Events
163
+ *
164
+ * @param int $event (optional)
165
+ * @param string $date_format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
166
+ * @param string $timezone Timezone in which to present the date/time (or default behaviour if not set)
167
+ *
168
+ * @return string|null Time
169
+ */
170
+ function tribe_get_start_time( $event = null, $date_format = '', $timezone = null ) {
171
+ if ( is_null( $event ) ) {
172
+ global $post;
173
+ $event = $post;
174
+ }
175
+
176
+ if ( is_numeric( $event ) ) {
177
+ $event = get_post( $event );
178
+ }
179
+
180
+ if ( ! is_object( $event ) ) {
181
+ return;
182
+ }
183
+
184
+ if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
185
+ return;
186
+ }
187
+
188
+ // @todo move timezones to Common
189
+ if ( class_exists( 'Tribe__Events__Timezones' ) ) {
190
+ $start_date = Tribe__Events__Timezones::event_start_timestamp( $event->ID, $timezone );
191
+ }
192
+
193
+ if ( '' == $date_format ) {
194
+ $date_format = tribe_get_time_format();
195
+ }
196
+
197
+ return tribe_format_date( $start_date, false, $date_format );
198
+ }
199
+ }
200
+
201
+ if ( ! function_exists( 'tribe_get_end_time' ) ) {
202
+ /**
203
+ * End Time
204
+ *
205
+ * Returns the event end time
206
+ *
207
+ * @category Events
208
+ *
209
+ * @param int $event (optional)
210
+ * @param string $date_format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
211
+ * @param string $timezone Timezone in which to present the date/time (or default behaviour if not set)
212
+ *
213
+ * @return string|null Time
214
+ */
215
+ function tribe_get_end_time( $event = null, $date_format = '', $timezone = null ) {
216
+ if ( is_null( $event ) ) {
217
+ global $post;
218
+ $event = $post;
219
+ }
220
+
221
+ if ( is_numeric( $event ) ) {
222
+ $event = get_post( $event );
223
+ }
224
+
225
+ if ( ! is_object( $event ) ) {
226
+ return;
227
+ }
228
+
229
+ if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
230
+ return;
231
+ }
232
+
233
+ // @todo move timezones to Common
234
+ if ( class_exists( 'Tribe__Events__Timezones' ) ) {
235
+ $end_date = Tribe__Events__Timezones::event_end_timestamp( $event->ID, $timezone );
236
+ }
237
+
238
+ if ( '' == $date_format ) {
239
+ $date_format = tribe_get_time_format();
240
+ }
241
+
242
+ return tribe_format_date( $end_date, false, $date_format );
243
+ }
244
+ }
245
+
246
+ if ( ! function_exists( 'tribe_get_start_date' ) ) {
247
+ /**
248
+ * Start Date
249
+ *
250
+ * Returns the event start date and time
251
+ *
252
+ * @category Events
253
+ *
254
+ * @param int $event (optional)
255
+ * @param bool $display_time If true shows date and time, if false only shows date
256
+ * @param string $date_format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
257
+ * @param string $timezone Timezone in which to present the date/time (or default behaviour if not set)
258
+ *
259
+ * @return string|null Date
260
+ */
261
+ function tribe_get_start_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
262
+ if ( is_null( $event ) ) {
263
+ global $post;
264
+ $event = $post;
265
+ }
266
+
267
+ if ( is_numeric( $event ) ) {
268
+ $event = get_post( $event );
269
+ }
270
+
271
+ if ( ! is_object( $event ) ) {
272
+ return '';
273
+ }
274
+
275
+ if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
276
+ $display_time = false;
277
+ }
278
+
279
+ // @todo move timezones to Common
280
+ if ( class_exists( 'Tribe__Events__Timezones' ) ) {
281
+ $start_date = Tribe__Events__Timezones::event_start_timestamp( $event->ID, $timezone );
282
+ } else {
283
+ return null;
284
+ }
285
+
286
+ return tribe_format_date( $start_date, $display_time, $date_format );
287
+ }
288
+ }
289
+
290
+ if ( ! function_exists( 'tribe_get_end_date' ) ) {
291
+ /**
292
+ * End Date
293
+ *
294
+ * Returns the event end date
295
+ *
296
+ * @category Events
297
+ *
298
+ * @param int $event (optional)
299
+ * @param bool $display_time If true shows date and time, if false only shows date
300
+ * @param string $date_format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
301
+ * @param string $timezone Timezone in which to present the date/time (or default behaviour if not set)
302
+ *
303
+ * @return string|null Date
304
+ */
305
+ function tribe_get_end_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
306
+ if ( is_null( $event ) ) {
307
+ global $post;
308
+ $event = $post;
309
+ }
310
+
311
+ if ( is_numeric( $event ) ) {
312
+ $event = get_post( $event );
313
+ }
314
+
315
+ if ( ! is_object( $event ) ) {
316
+ return '';
317
+ }
318
+
319
+ if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
320
+ $display_time = false;
321
+ }
322
+
323
+ // @todo move timezones to Common
324
+ if ( class_exists( 'Tribe__Events__Timezones' ) ) {
325
+ $end_date = Tribe__Events__Timezones::event_end_timestamp( $event->ID, $timezone );
326
+ } else {
327
+ return null;
328
+ }
329
+
330
+ return tribe_format_date( $end_date, $display_time, $date_format );
331
+ }
332
+ }
333
+
334
+ if ( ! function_exists( 'tribe_normalize_manual_utc_offset' ) ) {
335
+ /**
336
+ * Normalizes a manual UTC offset string.
337
+ *
338
+ * @param string $utc_offset
339
+ *
340
+ * @return string The normalized manual UTC offset.
341
+ * e.g. 'UTC+3', 'UTC-4.5', 'UTC+2.75'
342
+ */
343
+ function tribe_normalize_manual_utc_offset( $utc_offset ) {
344
+ $matches = array();
345
+ if ( preg_match( '/^UTC\\s*((\\+|-)(\\d{1,2}))((:|.|,)(\\d{1,2})+)*/ui', $utc_offset, $matches ) ) {
346
+ if ( ! empty( $matches[6] ) ) {
347
+ $minutes = $matches[6] > 10 && $matches[6] <= 60 ? $minutes = $matches[6] / 60 : $matches[6];
348
+ $minutes = str_replace( '0.', '', $minutes );
349
+ }
350
+
351
+ $utc_offset = sprintf( 'UTC%s%s', $matches[1], ! empty( $minutes ) ? '.' . $minutes : '' );
352
+
353
+ }
354
+
355
+ return $utc_offset;
356
+ }
357
+ }
common/src/functions/template-tags/general.php CHANGED
@@ -1,456 +1,456 @@
1
- <?php
2
- /**
3
- * Display functions (template-tags) for use in WordPress templates.
4
- */
5
-
6
- // Don't load directly
7
- if ( ! defined( 'ABSPATH' ) ) {
8
- die( '-1' );
9
- }
10
-
11
- if ( ! class_exists( 'Tribe__Main' ) ) {
12
- return;
13
- }
14
-
15
- if ( ! function_exists( 'tribe_get_option' ) ) {
16
- /**
17
- * Get Options
18
- *
19
- * Retrieve specific key from options array, optionally provide a default return value
20
- *
21
- * @category Events
22
- * @param string $optionName Name of the option to retrieve.
23
- * @param string $default Value to return if no such option is found.
24
- *
25
- * @return mixed Value of the option if found.
26
- * @todo Abstract this function out of template tags or otherwise secure it from other namespace conflicts.
27
- */
28
- function tribe_get_option( $optionName, $default = '' ) {
29
- return apply_filters( 'tribe_get_option', Tribe__Settings_Manager::get_option( $optionName, $default ), $optionName, $default );
30
- }
31
- }//end if
32
-
33
- if ( ! function_exists( 'tribe_update_option' ) ) {
34
- /**
35
- * Update Option
36
- *
37
- * Set specific key from options array, optionally provide a default return value
38
- *
39
- * @category Events
40
- * @param string $optionName Name of the option to retrieve.
41
- * @param string $value Value to save
42
- *
43
- * @return void
44
- */
45
- function tribe_update_option( $optionName, $value ) {
46
- Tribe__Settings_Manager::set_option( $optionName, $value );
47
- }
48
- }//end if
49
-
50
- if ( ! function_exists( 'tribe_get_network_option' ) ) {
51
- /**
52
- * Get Network Options
53
- *
54
- * Retrieve specific key from options array, optionally provide a default return value
55
- *
56
- * @category Events
57
- * @param string $optionName Name of the option to retrieve.
58
- * @param string $default Value to return if no such option is found.
59
- *
60
- * @return mixed Value of the option if found.
61
- * @todo Abstract this function out of template tags or otherwise secure it from other namespace conflicts.
62
- */
63
- function tribe_get_network_option( $optionName, $default = '' ) {
64
- return Tribe__Settings_Manager::get_network_option( $optionName, $default );
65
- }
66
- }
67
-
68
- if ( ! function_exists( 'tribe_resource_url' ) ) {
69
- /**
70
- * Returns or echoes a url to a file in the Events Calendar plugin resources directory
71
- *
72
- * @category Events
73
- * @param string $resource the filename of the resource
74
- * @param bool $echo whether or not to echo the url
75
- * @param string $root_dir directory to hunt for resource files (src or common)
76
- *
77
- * @return string
78
- **/
79
- function tribe_resource_url( $resource, $echo = false, $root_dir = 'src' ) {
80
- $extension = pathinfo( $resource, PATHINFO_EXTENSION );
81
-
82
- if ( 'src' !== $root_dir ) {
83
- $root_dir .= '/src';
84
- }
85
-
86
- $resources_path = $root_dir . '/resources/';
87
- switch ( $extension ) {
88
- case 'css':
89
- $resource_path = $resources_path .'css/';
90
- break;
91
- case 'js':
92
- $resource_path = $resources_path .'js/';
93
- break;
94
- case 'scss':
95
- $resource_path = $resources_path .'scss/';
96
- break;
97
- default:
98
- $resource_path = $resources_path;
99
- break;
100
- }
101
-
102
- $path = $resource_path . $resource;
103
-
104
- $plugin_path = trailingslashit( dirname( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) ) );
105
- $plugin_dir = trailingslashit( basename( $plugin_path ) );
106
- $url = plugins_url( $plugin_dir );
107
-
108
- /**
109
- * Filters the resource URL
110
- *
111
- * @param $url
112
- * @param $resource
113
- */
114
- $url = apply_filters( 'tribe_resource_url', $url . $path, $resource );
115
-
116
- /**
117
- * Deprected the tribe_events_resource_url filter in 4.0 in favor of tribe_resource_url. Remove in 5.0
118
- */
119
- $url = apply_filters( 'tribe_events_resource_url', $url, $resource );
120
-
121
- if ( $echo ) {
122
- echo $url;
123
- }
124
-
125
- return $url;
126
- }
127
- }//end if
128
-
129
- if ( ! function_exists( 'tribe_multi_line_remove_empty_lines' ) ) {
130
- /**
131
- * helper function to remove empty lines from multi-line strings
132
- *
133
- * @category Events
134
- * @link http://stackoverflow.com/questions/709669/how-do-i-remove-blank-lines-from-text-in-php
135
- *
136
- * @param string $multi_line_string a multiline string
137
- *
138
- * @return string the same string without empty lines
139
- */
140
- function tribe_multi_line_remove_empty_lines( $multi_line_string ) {
141
- return preg_replace( "/^\n+|^[\t\s]*\n+/m", '', $multi_line_string );
142
- }
143
- }//end if
144
-
145
- if ( ! function_exists( 'tribe_get_date_format' ) ) {
146
- /**
147
- * Get the date format specified in the tribe options
148
- *
149
- * @category Events
150
- * @param bool $with_year
151
- *
152
- * @return mixed
153
- */
154
- function tribe_get_date_format( $with_year = false ) {
155
- if ( $with_year ) {
156
- $format = tribe_get_date_option( 'dateWithYearFormat', get_option( 'date_format' ) );
157
- } else {
158
- $format = tribe_get_date_option( 'dateWithoutYearFormat', 'F j' );
159
- }
160
-
161
- return apply_filters( 'tribe_date_format', $format );
162
- }
163
- }//end if
164
-
165
- if ( ! function_exists( 'tribe_get_datetime_format' ) ) {
166
- /**
167
- * Get the Datetime Format
168
- *
169
- * @category Events
170
- *
171
- * @param bool $with_year
172
- *
173
- * @return mixed|void
174
- */
175
- function tribe_get_datetime_format( $with_year = false ) {
176
- $separator = (array) str_split( tribe_get_option( 'dateTimeSeparator', ' @ ' ) );
177
-
178
- $format = tribe_get_date_format( $with_year );
179
- $format .= ( ! empty( $separator ) ? '\\' : '' ) . implode( '\\', $separator );
180
- $format .= get_option( 'time_format' );
181
-
182
- return apply_filters( 'tribe_datetime_format', $format );
183
-
184
- }
185
- }//end if
186
-
187
- if ( ! function_exists( 'tribe_get_time_format' ) ) {
188
- /**
189
- * Get the time format
190
- *
191
- * @category Events
192
- *
193
- * @return mixed|void
194
- */
195
- function tribe_get_time_format( ) {
196
- $format = get_option( 'time_format' );
197
- return apply_filters( 'tribe_time_format', $format );
198
- }
199
- }//end if
200
-
201
- if ( ! function_exists( 'tribe_get_days_between' ) ) {
202
- /**
203
- * Accepts two dates and returns the number of days between them
204
- *
205
- * @category Events
206
- *
207
- * @param string $start_date
208
- * @param string $end_date
209
- * @param string|bool $day_cutoff
210
- *
211
- * @return int
212
- * @see Tribe__Date_Utils::date_diff()
213
- **/
214
- function tribe_get_days_between( $start_date, $end_date, $day_cutoff = '00:00' ) {
215
- if ( $day_cutoff === false ) {
216
- $day_cutoff = '00:00';
217
- } elseif ( $day_cutoff === true ) {
218
- $day_cutoff = tribe_get_option( 'multiDayCutoff', '00:00' );
219
- }
220
-
221
- $start_date = new DateTime( $start_date );
222
- if ( $start_date < new DateTime( $start_date->format( 'Y-m-d ' . $day_cutoff ) ) ) {
223
- $start_date->modify( '-1 day' );
224
- }
225
- $end_date = new DateTime( $end_date );
226
- if ( $end_date <= new DateTime( $end_date->format( 'Y-m-d ' . $day_cutoff ) ) ) {
227
- $end_date->modify( '-1 day' );
228
- }
229
-
230
- return Tribe__Date_Utils::date_diff( $start_date->format( 'Y-m-d ' . $day_cutoff ), $end_date->format( 'Y-m-d ' . $day_cutoff ) );
231
- }
232
- }//end if
233
-
234
- if ( ! function_exists( 'tribe_prepare_for_json' ) ) {
235
- /**
236
- * Function to prepare content for use as a value in a json encoded string destined for storage on a html data attribute.
237
- * Hence the double quote fun, especially in case they pass html encoded &quot; along. Any of those getting through to the data att will break jquery's parseJSON method.
238
- * Themers can use this function to prepare data they may want to send to tribe_events_template_data() in the templates, and we use it in that function ourselves.
239
- *
240
- * @category Events
241
- *
242
- * @param $string
243
- *
244
- * @return string
245
- */
246
- function tribe_prepare_for_json( $string ) {
247
-
248
- $value = trim( htmlspecialchars( $string, ENT_QUOTES, 'UTF-8' ) );
249
- $value = str_replace( '&quot;', '"', $value );
250
-
251
- return $value;
252
- }
253
- }//end if
254
-
255
- if ( ! function_exists( 'tribe_prepare_for_json_deep' ) ) {
256
- /**
257
- * Recursively iterate through an nested structure, calling
258
- * tribe_prepare_for_json() on all scalar values
259
- *
260
- * @category Events
261
- *
262
- * @param mixed $value The data to be cleaned
263
- *
264
- * @return mixed The clean data
265
- */
266
- function tribe_prepare_for_json_deep( $value ) {
267
- if ( is_array( $value ) ) {
268
- $value = array_map( 'tribe_prepare_for_json_deep', $value );
269
- } elseif ( is_object( $value ) ) {
270
- $vars = get_object_vars( $value );
271
- foreach ( $vars as $key => $data ) {
272
- $value->{$key} = tribe_prepare_for_json_deep( $data );
273
- }
274
- } elseif ( is_string( $value ) ) {
275
- $value = tribe_prepare_for_json( $value );
276
- }
277
- return $value;
278
- }
279
- }//end if
280
-
281
- if ( ! function_exists( 'tribe_the_notices' ) ) {
282
- /**
283
- * Generates html for any notices that have been queued on the current view
284
- *
285
- * @category Events
286
- *
287
- * @param bool $echo Whether or not to echo the notices html
288
- *
289
- * @return void | string
290
- * @see Tribe__Notices::get()
291
- **/
292
- function tribe_the_notices( $echo = true ) {
293
- $notices = Tribe__Notices::get();
294
-
295
- $html = ! empty( $notices ) ? '<div class="tribe-events-notices"><ul><li>' . implode( '</li><li>', $notices ) . '</li></ul></div>' : '';
296
-
297
- /**
298
- * Deprecated the tribe_events_the_notices filter in 4.0 in favor of tribe_the_notices. Remove in 5.0
299
- */
300
- $the_notices = apply_filters( 'tribe_events_the_notices', $html, $notices );
301
-
302
- /**
303
- * filters the notices HTML
304
- */
305
- $the_notices = apply_filters( 'tribe_the_notices', $html, $notices );
306
- if ( $echo ) {
307
- echo $the_notices;
308
- } else {
309
- return $the_notices;
310
- }
311
- }
312
- }//end if
313
-
314
- if ( ! function_exists( 'tribe_is_bot' ) ) {
315
- /**
316
- * tribe_is_bot checks if the visitor is a bot and returns status
317
- *
318
- * @category Events
319
- *
320
- * @return bool
321
- */
322
- function tribe_is_bot() {
323
- // get the current user agent
324
- $user_agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
325
-
326
- // check if the user agent is empty since most browsers identify themselves, so possibly a bot
327
- if ( empty( $user_agent ) ) {
328
- return apply_filters( 'tribe_is_bot_status', true, $user_agent, null );
329
- }
330
-
331
- // declare known bot user agents (lowercase)
332
- $user_agent_bots = (array) apply_filters(
333
- 'tribe_is_bot_list', array(
334
- 'bot',
335
- 'slurp',
336
- 'spider',
337
- 'crawler',
338
- 'yandex',
339
- )
340
- );
341
-
342
- foreach ( $user_agent_bots as $bot ) {
343
- if ( stripos( $user_agent, $bot ) !== false ) {
344
- return apply_filters( 'tribe_is_bot_status', true, $user_agent, $bot );
345
- }
346
- }
347
-
348
- // we think this is probably a real human
349
- return apply_filters( 'tribe_is_bot_status', false, $user_agent, null );
350
- }
351
- }//end if
352
-
353
- if ( ! function_exists( 'tribe_count_hierarchical_keys' ) ) {
354
- /**
355
- * Count keys in a hierarchical array
356
- *
357
- * @param $value
358
- * @param $key
359
- * @todo - remove, only used in the meta walker
360
- */
361
- function tribe_count_hierarchical_keys( $value, $key ) {
362
- global $tribe_count_hierarchical_increment;
363
- $tribe_count_hierarchical_increment++;
364
- }
365
- }//end if
366
-
367
- if ( ! function_exists( 'tribe_count_hierarchical' ) ) {
368
- /**
369
- * Count items in a hierarchical array
370
- *
371
- * @param array $walk
372
- *
373
- * @return int
374
- * @todo - remove, only used in the meta walker
375
- */
376
- function tribe_count_hierarchical( array $walk ) {
377
- global $tribe_count_hierarchical_increment;
378
- $tribe_count_hierarchical_increment = 0;
379
- array_walk_recursive( $walk, 'tribe_count_hierarchical_keys' );
380
-
381
- return $tribe_count_hierarchical_increment;
382
- }
383
- }//end if
384
-
385
- if ( ! function_exists( 'tribe_get_mobile_breakpoint' ) ) {
386
- /**
387
- * Mobile breakpoint
388
- *
389
- * Get the breakpoint for switching to mobile styles. Defaults to 768.
390
- *
391
- * @category Events
392
- *
393
- * @param int $default The default width (in pixels) at which to break into mobile styles
394
- *
395
- * @return int
396
- */
397
- function tribe_get_mobile_breakpoint( $default = 768 ) {
398
- return apply_filters( 'tribe_events_mobile_breakpoint', $default );
399
- }
400
- }//end if
401
-
402
- if ( ! function_exists( 'tribe_format_currency' ) ) {
403
- /**
404
- * Receives a float and formats it with a currency symbol
405
- *
406
- * @category Cost
407
- * @param string $cost pricing to format
408
- * @param null|int $post_id
409
- * @param null|string $currency_symbol
410
- * @param null|bool $reverse_position
411
- *
412
- * @return string
413
- */
414
- function tribe_format_currency( $cost, $post_id = null, $currency_symbol = null, $reverse_position = null ) {
415
-
416
- $post_id = Tribe__Main::post_id_helper( $post_id );
417
-
418
- $currency_symbol = apply_filters( 'tribe_currency_symbol', $currency_symbol, $post_id );
419
-
420
- // if no currency symbol was passed, or we're not looking at a particular event,
421
- // let's get the default currency symbol
422
- if ( ! $post_id || ! $currency_symbol ) {
423
- $currency_symbol = tribe_get_option( 'defaultCurrencySymbol', '$' );
424
- }
425
-
426
- $reverse_position = apply_filters( 'tribe_reverse_currency_position', $reverse_position, $post_id );
427
-
428
- if ( ! $reverse_position || ! $post_id ) {
429
- $reverse_position = tribe_get_option( 'reverseCurrencyPosition', false );
430
- }
431
-
432
- $cost = $reverse_position ? $cost . $currency_symbol : $currency_symbol . $cost;
433
-
434
- return $cost;
435
-
436
- }
437
- }//end if
438
-
439
- if ( ! function_exists( 'tribe_get_date_option' ) ) {
440
- /**
441
- * Get a date option.
442
- *
443
- * Retrieve an option value taking care to escape it to preserve date format slashes.
444
- *
445
- * @category Events
446
- * @param string $optionName Name of the option to retrieve.
447
- * @param string $default Value to return if no such option is found.
448
- *
449
- * @return mixed Value of the option if found
450
- */
451
- function tribe_get_date_option( $optionName, $default = '' ) {
452
- $value = tribe_get_option( $optionName, $default );
453
-
454
- return Tribe__Date_Utils::unescape_date_format($value);
455
- }
456
- }
1
+ <?php
2
+ /**
3
+ * Display functions (template-tags) for use in WordPress templates.
4
+ */
5
+
6
+ // Don't load directly
7
+ if ( ! defined( 'ABSPATH' ) ) {
8
+ die( '-1' );
9
+ }
10
+
11
+ if ( ! class_exists( 'Tribe__Main' ) ) {
12
+ return;
13
+ }
14
+
15
+ if ( ! function_exists( 'tribe_get_option' ) ) {
16
+ /**
17
+ * Get Options
18
+ *
19
+ * Retrieve specific key from options array, optionally provide a default return value
20
+ *
21
+ * @category Events
22
+ * @param string $optionName Name of the option to retrieve.
23
+ * @param string $default Value to return if no such option is found.
24
+ *
25
+ * @return mixed Value of the option if found.
26
+ * @todo Abstract this function out of template tags or otherwise secure it from other namespace conflicts.
27
+ */
28
+ function tribe_get_option( $optionName, $default = '' ) {
29
+ return apply_filters( 'tribe_get_option', Tribe__Settings_Manager::get_option( $optionName, $default ), $optionName, $default );
30
+ }
31
+ }//end if
32
+
33
+ if ( ! function_exists( 'tribe_update_option' ) ) {
34
+ /**
35
+ * Update Option
36
+ *
37
+ * Set specific key from options array, optionally provide a default return value
38
+ *
39
+ * @category Events
40
+ * @param string $optionName Name of the option to retrieve.
41
+ * @param string $value Value to save
42
+ *
43
+ * @return void
44
+ */
45
+ function tribe_update_option( $optionName, $value ) {
46
+ Tribe__Settings_Manager::set_option( $optionName, $value );
47
+ }
48
+ }//end if
49
+
50
+ if ( ! function_exists( 'tribe_get_network_option' ) ) {
51
+ /**
52
+ * Get Network Options
53
+ *
54
+ * Retrieve specific key from options array, optionally provide a default return value
55
+ *
56
+ * @category Events
57
+ * @param string $optionName Name of the option to retrieve.
58
+ * @param string $default Value to return if no such option is found.
59
+ *
60
+ * @return mixed Value of the option if found.
61
+ * @todo Abstract this function out of template tags or otherwise secure it from other namespace conflicts.
62
+ */
63
+ function tribe_get_network_option( $optionName, $default = '' ) {
64
+ return Tribe__Settings_Manager::get_network_option( $optionName, $default );
65
+ }
66
+ }
67
+
68
+ if ( ! function_exists( 'tribe_resource_url' ) ) {
69
+ /**
70
+ * Returns or echoes a url to a file in the Events Calendar plugin resources directory
71
+ *
72
+ * @category Events
73
+ * @param string $resource the filename of the resource
74
+ * @param bool $echo whether or not to echo the url
75
+ * @param string $root_dir directory to hunt for resource files (src or common)
76
+ *
77
+ * @return string
78
+ **/
79
+ function tribe_resource_url( $resource, $echo = false, $root_dir = 'src' ) {
80
+ $extension = pathinfo( $resource, PATHINFO_EXTENSION );
81
+
82
+ if ( 'src' !== $root_dir ) {
83
+ $root_dir .= '/src';
84
+ }
85
+
86
+ $resources_path = $root_dir . '/resources/';
87
+ switch ( $extension ) {
88
+ case 'css':
89
+ $resource_path = $resources_path .'css/';
90
+ break;
91
+ case 'js':
92
+ $resource_path = $resources_path .'js/';
93
+ break;
94
+ case 'scss':
95
+ $resource_path = $resources_path .'scss/';
96
+ break;
97
+ default:
98
+ $resource_path = $resources_path;
99
+ break;
100
+ }
101
+
102
+ $path = $resource_path . $resource;
103
+
104
+ $plugin_path = trailingslashit( dirname( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) ) );
105
+ $plugin_dir = trailingslashit( basename( $plugin_path ) );
106
+ $url = plugins_url( $plugin_dir );
107
+
108
+ /**
109
+ * Filters the resource URL
110
+ *
111
+ * @param $url
112
+ * @param $resource
113
+ */
114
+ $url = apply_filters( 'tribe_resource_url', $url . $path, $resource );
115
+
116
+ /**
117
+ * Deprected the tribe_events_resource_url filter in 4.0 in favor of tribe_resource_url. Remove in 5.0
118
+ */
119
+ $url = apply_filters( 'tribe_events_resource_url', $url, $resource );
120
+
121
+ if ( $echo ) {
122
+ echo $url;
123
+ }
124
+
125
+ return $url;
126
+ }
127
+ }//end if
128
+
129
+ if ( ! function_exists( 'tribe_multi_line_remove_empty_lines' ) ) {
130
+ /**
131
+ * helper function to remove empty lines from multi-line strings
132
+ *
133
+ * @category Events
134
+ * @link http://stackoverflow.com/questions/709669/how-do-i-remove-blank-lines-from-text-in-php
135
+ *
136
+ * @param string $multi_line_string a multiline string
137
+ *
138
+ * @return string the same string without empty lines
139
+ */
140
+ function tribe_multi_line_remove_empty_lines( $multi_line_string ) {
141
+ return preg_replace( "/^\n+|^[\t\s]*\n+/m", '', $multi_line_string );
142
+ }
143
+ }//end if
144
+
145
+ if ( ! function_exists( 'tribe_get_date_format' ) ) {
146
+ /**
147
+ * Get the date format specified in the tribe options
148
+ *
149
+ * @category Events
150
+ * @param bool $with_year
151
+ *
152
+ * @return mixed
153
+ */
154
+ function tribe_get_date_format( $with_year = false ) {
155
+ if ( $with_year ) {
156
+ $format = tribe_get_date_option( 'dateWithYearFormat', get_option( 'date_format' ) );
157
+ } else {
158
+ $format = tribe_get_date_option( 'dateWithoutYearFormat', 'F j' );
159
+ }
160
+
161
+ return apply_filters( 'tribe_date_format', $format );
162
+ }
163
+ }//end if
164
+
165
+ if ( ! function_exists( 'tribe_get_datetime_format' ) ) {
166
+ /**
167
+ * Get the Datetime Format
168
+ *
169
+ * @category Events
170
+ *
171
+ * @param bool $with_year
172
+ *
173
+ * @return mixed|void
174
+ */
175
+ function tribe_get_datetime_format( $with_year = false ) {
176
+ $separator = (array) str_split( tribe_get_option( 'dateTimeSeparator', ' @ ' ) );
177
+
178
+ $format = tribe_get_date_format( $with_year );
179
+ $format .= ( ! empty( $separator ) ? '\\' : '' ) . implode( '\\', $separator );
180
+ $format .= get_option( 'time_format' );
181
+
182
+ return apply_filters( 'tribe_datetime_format', $format );
183
+
184
+ }
185
+ }//end if
186
+
187
+ if ( ! function_exists( 'tribe_get_time_format' ) ) {
188
+ /**
189
+ * Get the time format
190
+ *
191
+ * @category Events
192
+ *
193
+ * @return mixed|void
194
+ */
195
+ function tribe_get_time_format( ) {
196
+ $format = get_option( 'time_format' );
197
+ return apply_filters( 'tribe_time_format', $format );
198
+ }
199
+ }//end if
200
+
201
+ if ( ! function_exists( 'tribe_get_days_between' ) ) {
202
+ /**
203
+ * Accepts two dates and returns the number of days between them
204
+ *
205
+ * @category Events
206
+ *
207
+ * @param string $start_date
208
+ * @param string $end_date
209
+ * @param string|bool $day_cutoff
210
+ *
211
+ * @return int
212
+ * @see Tribe__Date_Utils::date_diff()
213
+ **/
214
+ function tribe_get_days_between( $start_date, $end_date, $day_cutoff = '00:00' ) {
215
+ if ( $day_cutoff === false ) {
216
+ $day_cutoff = '00:00';
217
+ } elseif ( $day_cutoff === true ) {
218
+ $day_cutoff = tribe_get_option( 'multiDayCutoff', '00:00' );
219
+ }
220
+
221
+ $start_date = new DateTime( $start_date );
222
+ if ( $start_date < new DateTime( $start_date->format( 'Y-m-d ' . $day_cutoff ) ) ) {
223
+ $start_date->modify( '-1 day' );
224
+ }
225
+ $end_date = new DateTime( $end_date );
226
+ if ( $end_date <= new DateTime( $end_date->format( 'Y-m-d ' . $day_cutoff ) ) ) {
227
+ $end_date->modify( '-1 day' );
228
+ }
229
+
230
+ return Tribe__Date_Utils::date_diff( $start_date->format( 'Y-m-d ' . $day_cutoff ), $end_date->format( 'Y-m-d ' . $day_cutoff ) );
231
+ }
232
+ }//end if
233
+
234
+ if ( ! function_exists( 'tribe_prepare_for_json' ) ) {
235
+ /**
236
+ * Function to prepare content for use as a value in a json encoded string destined for storage on a html data attribute.
237
+ * Hence the double quote fun, especially in case they pass html encoded &quot; along. Any of those getting through to the data att will break jquery's parseJSON method.
238
+ * Themers can use this function to prepare data they may want to send to tribe_events_template_data() in the templates, and we use it in that function ourselves.
239
+ *
240
+ * @category Events
241
+ *
242
+ * @param $string
243
+ *
244
+ * @return string
245
+ */
246
+ function tribe_prepare_for_json( $string ) {
247
+
248
+ $value = trim( htmlspecialchars( $string, ENT_QUOTES, 'UTF-8' ) );
249
+ $value = str_replace( '&quot;', '"', $value );
250
+
251
+ return $value;
252
+ }
253
+ }//end if
254
+
255
+ if ( ! function_exists( 'tribe_prepare_for_json_deep' ) ) {
256
+ /**
257
+ * Recursively iterate through an nested structure, calling
258
+ * tribe_prepare_for_json() on all scalar values
259
+ *
260
+ * @category Events
261
+ *
262
+ * @param mixed $value The data to be cleaned
263
+ *
264
+ * @return mixed The clean data
265
+ */
266
+ function tribe_prepare_for_json_deep( $value ) {
267
+ if ( is_array( $value ) ) {
268
+ $value = array_map( 'tribe_prepare_for_json_deep', $value );
269
+ } elseif ( is_object( $value ) ) {
270
+ $vars = get_object_vars( $value );
271
+ foreach ( $vars as $key => $data ) {
272
+ $value->{$key} = tribe_prepare_for_json_deep( $data );
273
+ }
274
+ } elseif ( is_string( $value ) ) {
275
+ $value = tribe_prepare_for_json( $value );
276
+ }
277
+ return $value;
278
+ }
279
+ }//end if
280
+
281
+ if ( ! function_exists( 'tribe_the_notices' ) ) {
282
+ /**
283
+ * Generates html for any notices that have been queued on the current view
284
+ *
285
+ * @category Events
286
+ *
287
+ * @param bool $echo Whether or not to echo the notices html
288
+ *
289
+ * @return void | string
290
+ * @see Tribe__Notices::get()
291
+ **/
292
+ function tribe_the_notices( $echo = true ) {
293
+ $notices = Tribe__Notices::get();
294
+
295
+ $html = ! empty( $notices ) ? '<div class="tribe-events-notices"><ul><li>' . implode( '</li><li>', $notices ) . '</li></ul></div>' : '';
296
+
297
+ /**
298
+ * Deprecated the tribe_events_the_notices filter in 4.0 in favor of tribe_the_notices. Remove in 5.0
299
+ */
300
+ $the_notices = apply_filters( 'tribe_events_the_notices', $html, $notices );
301
+
302
+ /**
303
+ * filters the notices HTML
304
+ */
305
+ $the_notices = apply_filters( 'tribe_the_notices', $html, $notices );
306
+ if ( $echo ) {
307
+ echo $the_notices;
308
+ } else {
309
+ return $the_notices;
310
+ }
311
+ }
312
+ }//end if
313
+
314
+ if ( ! function_exists( 'tribe_is_bot' ) ) {
315
+ /**
316
+ * tribe_is_bot checks if the visitor is a bot and returns status
317
+ *
318
+ * @category Events
319
+ *
320
+ * @return bool
321
+ */
322
+ function tribe_is_bot() {
323
+ // get the current user agent
324
+ $user_agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
325
+
326
+ // check if the user agent is empty since most browsers identify themselves, so possibly a bot
327
+ if ( empty( $user_agent ) ) {
328
+ return apply_filters( 'tribe_is_bot_status', true, $user_agent, null );
329
+ }
330
+
331
+ // declare known bot user agents (lowercase)
332
+ $user_agent_bots = (array) apply_filters(
333
+ 'tribe_is_bot_list', array(
334
+ 'bot',
335
+ 'slurp',
336
+ 'spider',
337
+ 'crawler',
338
+ 'yandex',
339
+ )
340
+ );
341
+
342
+ foreach ( $user_agent_bots as $bot ) {
343
+ if ( stripos( $user_agent, $bot ) !== false ) {
344
+ return apply_filters( 'tribe_is_bot_status', true, $user_agent, $bot );
345
+ }
346
+ }
347
+
348
+ // we think this is probably a real human
349
+ return apply_filters( 'tribe_is_bot_status', false, $user_agent, null );
350
+ }
351
+ }//end if
352
+
353
+ if ( ! function_exists( 'tribe_count_hierarchical_keys' ) ) {
354
+ /**
355
+ * Count keys in a hierarchical array
356
+ *
357
+ * @param $value
358
+ * @param $key
359
+ * @todo - remove, only used in the meta walker
360
+ */
361
+ function tribe_count_hierarchical_keys( $value, $key ) {
362
+ global $tribe_count_hierarchical_increment;
363
+ $tribe_count_hierarchical_increment++;
364
+ }
365
+ }//end if
366
+
367
+ if ( ! function_exists( 'tribe_count_hierarchical' ) ) {
368
+ /**
369
+ * Count items in a hierarchical array
370
+ *
371
+ * @param array $walk
372
+ *
373
+ * @return int
374
+ * @todo - remove, only used in the meta walker
375
+ */
376
+ function tribe_count_hierarchical( array $walk ) {
377
+ global $tribe_count_hierarchical_increment;
378
+ $tribe_count_hierarchical_increment = 0;
379
+ array_walk_recursive( $walk, 'tribe_count_hierarchical_keys' );
380
+
381
+ return $tribe_count_hierarchical_increment;
382
+ }
383
+ }//end if
384
+
385
+ if ( ! function_exists( 'tribe_get_mobile_breakpoint' ) ) {
386
+ /**
387
+ * Mobile breakpoint
388
+ *
389
+ * Get the breakpoint for switching to mobile styles. Defaults to 768.
390
+ *
391
+ * @category Events
392
+ *
393
+ * @param int $default The default width (in pixels) at which to break into mobile styles
394
+ *
395
+ * @return int
396
+ */
397
+ function tribe_get_mobile_breakpoint( $default = 768 ) {
398
+ return apply_filters( 'tribe_events_mobile_breakpoint', $default );
399
+ }
400
+ }//end if
401
+
402
+ if ( ! function_exists( 'tribe_format_currency' ) ) {
403
+ /**
404
+ * Receives a float and formats it with a currency symbol
405
+ *
406
+ * @category Cost
407
+ * @param string $cost pricing to format
408
+ * @param null|int $post_id
409
+ * @param null|string $currency_symbol
410
+ * @param null|bool $reverse_position
411
+ *
412
+ * @return string
413
+ */
414
+ function tribe_format_currency( $cost, $post_id = null, $currency_symbol = null, $reverse_position = null ) {
415
+
416
+ $post_id = Tribe__Main::post_id_helper( $post_id );
417
+
418
+ $currency_symbol = apply_filters( 'tribe_currency_symbol', $currency_symbol, $post_id );
419
+
420
+ // if no currency symbol was passed, or we're not looking at a particular event,
421
+ // let's get the default currency symbol
422
+ if ( ! $post_id || ! $currency_symbol ) {
423
+ $currency_symbol = tribe_get_option( 'defaultCurrencySymbol', '$' );
424
+ }
425
+
426
+ $reverse_position = apply_filters( 'tribe_reverse_currency_position', $reverse_position, $post_id );
427
+
428
+ if ( ! $reverse_position || ! $post_id ) {
429
+ $reverse_position = tribe_get_option( 'reverseCurrencyPosition', false );
430
+ }
431
+
432
+ $cost = $reverse_position ? $cost . $currency_symbol : $currency_symbol . $cost;
433
+
434
+ return $cost;
435
+
436
+ }
437
+ }//end if
438
+
439
+ if ( ! function_exists( 'tribe_get_date_option' ) ) {
440
+ /**
441
+ * Get a date option.
442
+ *
443
+ * Retrieve an option value taking care to escape it to preserve date format slashes.
444
+ *
445
+ * @category Events
446
+ * @param string $optionName Name of the option to retrieve.
447
+ * @param string $default Value to return if no such option is found.
448
+ *
449
+ * @return mixed Value of the option if found
450
+ */
451
+ function tribe_get_date_option( $optionName, $default = '' ) {
452
+ $value = tribe_get_option( $optionName, $default );
453
+
454
+ return Tribe__Date_Utils::unescape_date_format($value);
455
+ }
456
+ }
common/src/functions/utils.php CHANGED
@@ -1,27 +1,59 @@
1
- <?php
2
-
3
- if ( ! function_exists( 'tribe_array_merge_recursive' ) ) {
4
- /**
5
- * Recursively merge two arrays preserving keys.
6
- *
7
- * @link http://php.net/manual/en/function.array-merge-recursive.php#92195
8
- *
9
- * @param array $array1
10
- * @param array $array2
11
- *
12
- * @return array
13
- */
14
- function tribe_array_merge_recursive( array &$array1, array &$array2 ) {
15
- $merged = $array1;
16
-
17
- foreach ( $array2 as $key => &$value ) {
18
- if ( is_array( $value ) && isset ( $merged [ $key ] ) && is_array( $merged [ $key ] ) ) {
19
- $merged [ $key ] = tribe_array_merge_recursive( $merged [ $key ], $value );
20
- } else {
21
- $merged [ $key ] = $value;
22
- }
23
- }
24
-
25
- return $merged;
26
- }
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! function_exists( 'tribe_array_merge_recursive' ) ) {
4
+ /**
5
+ * Recursively merge two arrays preserving keys.
6
+ *
7
+ * @link http://php.net/manual/en/function.array-merge-recursive.php#92195
8
+ *
9
+ * @param array $array1
10
+ * @param array $array2
11
+ *
12
+ * @return array
13
+ */
14
+ function tribe_array_merge_recursive( array &$array1, array &$array2 ) {
15
+ $merged = $array1;
16
+
17
+ foreach ( $array2 as $key => &$value ) {
18
+ if ( is_array( $value ) && isset( $merged [ $key ] ) && is_array( $merged [ $key ] ) ) {
19
+ $merged [ $key ] = tribe_array_merge_recursive( $merged [ $key ], $value );
20
+ } else {
21
+ $merged [ $key ] = $value;
22
+ }
23
+ }
24
+
25
+ return $merged;
26
+ }
27
+ }
28
+
29
+ if ( ! function_exists( 'tribe_register_plugin' ) ) {
30
+ /**
31
+ * Checks if this plugin has permission to run, if not it notifies the admin
32
+ *
33
+ * @param string $file_path Full file path to the base plugin file
34
+ * @param string $main_class The Main/base class for this plugin
35
+ * @param string $version The version
36
+ * @param array $classes_req Any Main class files/tribe plugins required for this to run
37
+ *
38
+ * @return bool Indicates if plugin should continue initialization
39
+ */
40
+ function tribe_register_plugin( $file_path, $main_class, $version, $classes_req = array() ) {
41
+ $tribe_plugins = Tribe__Dependency::instance();
42
+
43
+ if ( $tribe_plugins->has_requisite_plugins( $classes_req ) ) {
44
+ $tribe_plugins->add_active_plugin( $main_class, $version, $file_path );
45
+
46
+ return true;
47
+ } elseif ( is_admin() ) {
48
+ $tribe_plugins = new Tribe__Plugins();
49
+ $admin_notice = new Tribe__Plugin_Download_Notice( $file_path );
50
+
51
+ foreach ( $classes_req as $class => $version ) {
52
+ $plugin = $tribe_plugins->get_plugin_by_class( $class );
53
+ $admin_notice->add_required_plugin( $plugin['short_name'], $plugin['thickbox_url'] );
54
+ }
55
+ }
56
+
57
+ return false;
58
+ }
59
+ }
common/src/resources/css/app-shop.css CHANGED
@@ -1,66 +1,66 @@
1
- /**
2
- * This CSS file was auto-generated via PostCSS
3
- *
4
- * Contributors should avoid editing this file, but instead edit the associated
5
- * src/resources/postcss/ file. For more information, check out our engineering
6
- * docs on how we handle CSS in our engineering docs.
7
- *
8
- * @see: http://moderntribe.github.io/products-engineering/css/
9
- */
10
-
11
- .tribe-addon {
12
- box-sizing: border-box;
13
- display: inline-block;
14
- margin-right: 10px;
15
- overflow: hidden;
16
- padding: 20px 20px 20px 0;
17
- vertical-align: top;
18
- width: 300px;
19
- }
20
-
21
- .tribe-addon .thumb img {
22
- max-width: 100%;
23
- width: 100%;
24
- }
25
-
26
- .tribe-addon h4 {
27
- font-size: 1.17em;
28
- }
29
-
30
- .tribe-addon h4 a {
31
- text-decoration: none;
32
- }
33
-
34
- .addon-grid {
35
- width: 100%;
36
- }
37
-
38
- .category-title {
39
- clear: both;
40
- display: block;
41
- margin-bottom: 10px;
42
- }
43
-
44
- .tribe-addon.first {
45
- border-bottom: 1px solid #dfdfdf;
46
- margin: 20px 0 10px;
47
- overflow: hidden;
48
- padding: 0 0 20px 330px;
49
- width: 100%;
50
- }
51
-
52
- .tribe-addon.first h4 {
53
- font-size: 20px;
54
- line-height: 1.4;
55
- margin: 0;
56
- }
57
-
58
- .tribe-addon.first .thumb {
59
- float: left;
60
- margin-left: -330px;
61
- width: 300px;
62
- }
63
-
64
- .tribe-addon.first .description {
65
- max-width: 600px;
66
- }
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ .tribe-addon {
12
+ box-sizing: border-box;
13
+ display: inline-block;
14
+ margin-right: 10px;
15
+ overflow: hidden;
16
+ padding: 20px 20px 20px 0;
17
+ vertical-align: top;
18
+ width: 300px;
19
+ }
20
+
21
+ .tribe-addon .thumb img {
22
+ max-width: 100%;
23
+ width: 100%;
24
+ }
25
+
26
+ .tribe-addon h4 {
27
+ font-size: 1.17em;
28
+ }
29
+
30
+ .tribe-addon h4 a {
31
+ text-decoration: none;
32
+ }
33
+
34
+ .addon-grid {
35
+ width: 100%;
36
+ }
37
+
38
+ .category-title {
39
+ clear: both;
40
+ display: block;
41
+ margin-bottom: 10px;
42
+ }
43
+
44
+ .tribe-addon.first {
45
+ border-bottom: 1px solid #dfdfdf;
46
+ margin: 20px 0 10px;
47
+ overflow: hidden;
48
+ padding: 0 0 20px 330px;
49
+ width: 100%;
50
+ }
51
+
52
+ .tribe-addon.first h4 {
53
+ font-size: 20px;
54
+ line-height: 1.4;
55
+ margin: 0;
56
+ }
57
+
58
+ .tribe-addon.first .thumb {
59
+ float: left;
60
+ margin-left: -330px;
61
+ width: 300px;
62
+ }
63
+
64
+ .tribe-addon.first .description {
65
+ max-width: 600px;
66
+ }
common/src/resources/css/tribe-common-admin.css CHANGED
@@ -1,895 +1,895 @@
1
- /**
2
- * This CSS file was auto-generated via PostCSS
3
- *
4
- * Contributors should avoid editing this file, but instead edit the associated
5
- * src/resources/postcss/ file. For more information, check out our engineering
6
- * docs on how we handle CSS in our engineering docs.
7
- *
8
- * @see: http://moderntribe.github.io/products-engineering/css/
9
- */
10
-
11
- /* = Shared CSS Elements
12
- =============================================*/
13
- .invalid input {
14
- border: 2px solid red !important;
15
- }
16
- .valid input {
17
- border: 1px solid green;
18
- }
19
- .clearfix {
20
- zoom: 1; /* For IE */
21
- }
22
- .placeholder {
23
- color: #999;
24
- cursor: text;
25
- padding: 4px 4px 4px 4px;
26
- }
27
- input:placeholder,
28
- textarea:placeholder {
29
- color: #999;
30
- }
31
- input::-webkit-input-placeholder,
32
- textarea::-webkit-input-placeholder {
33
- color: #999;
34
- }
35
- .bubble {
36
- -khtml-border-radius: 3px;
37
- background-color: #f9f9f9;
38
- border-color: #dfdfdf;
39
- border-radius: 3px;
40
- border-spacing: 0;
41
- border-style: solid;
42
- border-style: solid;
43
- border-width: 1px;
44
- padding: 10px;
45
- }
46
- .tribe-sticky-tooltip {
47
- color: #bbb;
48
- }
49
- td.tribe_message {
50
- padding-bottom: 10px !important;
51
- }
52
- #tribe_thanks {
53
- float: left;
54
- margin: 5px 0 0 0;
55
- width: 200px;
56
- }
57
- .tribe_brand {
58
- font-family: Georgia !important;
59
- font-size: 17px !important;
60
- font-weight: normal;
61
- margin: 8px 0;
62
- }
63
- /* = Upgrade Screen
64
- =============================================*/
65
- #tribe-upgrade {
66
- background: #f6f6f6;
67
- border: 1px solid #ccc;
68
- border-radius: 5px;
69
- margin: 20px 0 30px;
70
- padding: 0 20px 20px;
71
- }
72
- #tribe-upgrade .message {
73
- background-color: #ffffe0;
74
- border-color: #e6db55;
75
- border-radius: 3px;
76
- border-style: solid;
77
- border-width: 1px;
78
- padding: 6px 12px;
79
- }
80
- /* = Plugin Screen
81
- =============================================*/
82
- table.plugins .tribe-plugin-update-message {
83
- background: #d54e21; /* taken from colour scheme in list-tables.css */
84
- color: white;
85
- display: inline-table;
86
- margin: 6px 0;
87
- padding: 10px 12px;
88
- }
89
- table.plugins .tribe-plugin-update-message h4 {
90
- display: inline;
91
- font-weight: bold;
92
- margin-right: 8px;
93
- }
94
- table.plugins .tribe-plugin-update-message h4:after {
95
- content: ' \00BB ';
96
- }
97
- table.plugins .tribe-plugin-update-message a {
98
- color: white;
99
- text-decoration: underline;
100
- }
101
- /* = Settings Screen
102
- =============================================*/
103
- .tribe-settings-form {
104
- max-width: 1000px;
105
- }
106
- .tribe-settings-form fieldset {
107
- clear: both;
108
- display: inline-block;
109
- padding: 10px 0;
110
- }
111
- .tribe-settings-form legend {
112
- float: left;
113
- font-weight: bold;
114
- margin-right: 20px;
115
- width: 220px;
116
- }
117
- .tribe-settings-form fieldset.tribe-field-license_key legend {
118
- width: auto;
119
- }
120
- .tribe-settings-form .tribe-field-wrap {
121
- float: left;
122
- max-width: 500px;
123
- }
124
- .tribe-settings-form .tribe-field-radio label,
125
- .tribe-settings-form .tribe-field-checkbox_list label {
126
- display: block;
127
- margin: 5px 0;
128
- }
129
- .tribe-settings-form .tribe-field-radio label input,
130
- .tribe-settings-form .tribe-field-checkbox_list label input {
131
- margin-right: 5px;
132
- }
133
- .tribe-settings-form .tribe-settings-form-wrap fieldset,
134
- .tribe-settings-form .tribe-settings-form-wrap .description,
135
- .tribe-settings-form fieldset[id^='tribe-field-geoloc_'] {
136
- padding-left: 12px;
137
- }
138
- .tribe-settings-form .tribe-settings-form-wrap fieldset .description {
139
- margin-left: 0;
140
- max-width: 450px;
141
- padding-left: 0;
142
- }
143
- .tribe-settings-form .tribe-settings-form-wrap h3 {
144
- background-color: #f9f9f9;
145
- margin-bottom: 10px;
146
- padding: 6px 0 6px 12px;
147
- }
148
- .tribe-settings-form .tribe-settings-form-wrap h3 ~ h3 {
149
- margin-top: 2.25em;
150
- }
151
- .tribe-settings-form .tribe-settings-form-wrap h3 + p {
152
- margin: 0 0 10px;
153
- padding-left: 12px;
154
- }
155
- .tribe_settings .tribe-field-indent {
156
- margin-left: 245px;
157
- }
158
- .tribe_settings #pu_dashboard_message {
159
- display: none;
160
- }
161
- .tribe_settings .tribe-errors-list {
162
- margin-left: 15px;
163
- }
164
- .tribe_settings .expiring-license {
165
- color: red;
166
- }
167
- .tribe_settings .tribe-error {
168
- border: 1px solid #f00;
169
- }
170
- .tribe_settings .tribe-field-description {
171
- margin-bottom: 0;
172
- position: relative;
173
- top: -12px;
174
- }
175
- .tribe_settings #ical-link {
176
- top: -14px;
177
- }
178
- .tribe-settings-form #tribe-field-stylesheetOption label {
179
- margin-left: 20px;
180
- }
181
- .tribe-settings-form #tribe-field-stylesheetOption input {
182
- margin-left: -20px;
183
- margin-right: 8px;
184
- }
185
- .tribe-settings-form #tribe-field-stylesheetOption p.description {
186
- color: #999;
187
- }
188
- /* Modern Tribe box */
189
- #modern-tribe-info {
190
- -khtml-border-radius: 4px;
191
- background-color: #f9f9f9;
192
- border: 1px solid #ccc;
193
- border-radius: 4px;
194
- margin: 20px 0;
195
- padding: 8px 20px 12px;
196
- }
197
- #modern-tribe-info img {
198
- height: 18px;
199
- margin: 10px 0;
200
- width: 250px;
201
- }
202
- #modern-tribe-info ul {
203
- list-style: disc;
204
- margin-left: 20px;
205
- }
206
- #modern-tribe-info ul ul {
207
- list-style: circle;
208
- }
209
- /* sizes */
210
- .tribe-field-textarea.tribe-size-small textarea {
211
- height: 60px;
212
- width: 180px;
213
- }
214
- .tribe-field-textarea.tribe-size-medium textarea {
215
- height: 80px;
216
- width: 300px;
217
- }
218
- .tribe-field-textarea.tribe-size-large textarea {
219
- height: 120px;
220
- width: 450px;
221
- }
222
- .tribe-field-text.tribe-size-small input,
223
- .tribe-field-license_key.tribe-size-small input {
224
- width: 50px;
225
- }
226
- .tribe-field-text.tribe-size-medium input,
227
- .tribe-field-license_key.tribe-size-medium input {
228
- width: 225px;
229
- }
230
- .tribe-field-text.tribe-size-large input,
231
- .tribe-field-license_key.tribe-size-large input {
232
- width: 450px;
233
- }
234
- .tribe-field-dropdown.tribe-size-small select {
235
- width: 100px;
236
- }
237
- .tribe-field-dropdown.tribe-size-medium select {
238
- width: 300px;
239
- }
240
- .tribe-field-dropdown.tribe-size-large select {
241
- width: 450px;
242
- }
243
- .tribe-field-dropdown_chosen.tribe-size-small select {
244
- width: 100px;
245
- }
246
- .tribe-field-dropdown_chosen.tribe-size-medium select {
247
- width: 200px;
248
- }
249
- .tribe-field-dropdown_chosen.tribe-size-large select {
250
- width: 300px;
251
- }
252
- /* license keys */
253
- .ajax-loading-license,
254
- .valid-key,
255
- .invalid-key {
256
- display: none;
257
- margin: 0 5px;
258
- }
259
- .ajax-loading-license {
260
- position: relative;
261
- top: 5px;
262
- }
263
- .key-validity {
264
- display: inline-block;
265
- }
266
- .invalid-key {
267
- color: red;
268
- }
269
- .valid-key {
270
- color: green;
271
- }
272
- .valid-key.service-msg {
273
- color: #b72;
274
- }
275
- /* additional fields */
276
- #additional-field-table {
277
- margin-bottom: 20px;
278
- }
279
- /* miscellaneous */
280
- .tribe-admin-box-left {
281
- -khtml-border-radius: 4px;
282
- background-color: #f9f9f9;
283
- border: 1px solid #ccc;
284
- border-radius: 4px;
285
- float: left;
286
- margin: 20px 0;
287
- padding: 0 20px 15px;
288
- width: 20%;
289
- }
290
- .tribe-admin-box-right {
291
- -khtml-border-radius: 4px;
292
- background-color: #f9f9f9;
293
- border: 1px solid #ccc;
294
- border-radius: 4px;
295
- float: right;
296
- margin: 20px 0;
297
- padding: 0 20px 15px;
298
- width: 68%;
299
- }
300
- .ajax-loader {
301
- float: right;
302
- margin: 10px;
303
- }
304
- .tribe-arrangeable-item {
305
- border: 1px solid lightGrey;
306
- border-radius: 6px;
307
- }
308
- .tribe-arrangeable-item .ui-state-default {
309
- border: none;
310
- }
311
- .tribe-arrangeable-item-top {
312
- padding: 6px;
313
- }
314
- .tribe-arrangeable-item-top:hover {
315
- cursor: move;
316
- }
317
- .tribe-arrangeable-action {
318
- float: right;
319
- }
320
- .tribe-arrangeable-child {
321
- background-color: #f9f9f9;
322
- border-top: 1px solid lightGrey;
323
- display: none;
324
- padding: 25px;
325
- }
326
- .tribe-arrangeable-child label {
327
- display: block;
328
- margin: 0 0 7px 0;
329
- }
330
- .tribe_events_active_filter_type_options {
331
- margin: 10px 0;
332
- }
333
- .tribe_events_active_filter_type_options label {
334
- margin: 7px 0;
335
- }
336
- .tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection {
337
- margin-bottom: 18px;
338
- }
339
- .OrganizerInfo td small,
340
- #event_organizer td small {
341
- display: block;
342
- margin: 0;
343
- max-width: 250px;
344
- }
345
- .OrganizerInfo .organizer-email,
346
- #event_organizer .organizer-email {
347
- vertical-align: top;
348
- }
349
- .tribe-table-field-label {
350
- max-width: 100%;
351
- width: 200px;
352
- }
353
- /* = Help Screen
354
- =============================================*/
355
- #tribe-help-general,
356
- #tribe-help-sidebar {
357
- float: left;
358
- margin-top: 20px;
359
- }
360
- #tribe-help-general p {
361
- margin-left: 15px;
362
- }
363
- #tribe-help-general ul {
364
- list-style-type: square;
365
- margin-bottom: 20px;
366
- margin-left: 35px;
367
- }
368
- #tribe-help-general ol {
369
- margin-bottom: 20px;
370
- margin-left: 35px;
371
- }
372
- #tribe-help-general h3 {
373
- background-color: #f9f9f9;
374
- margin-bottom: 10px;
375
- padding: 6px 0 6px 12px;
376
- }
377
- #tribe-help-general h3 ~ h3 {
378
- margin-top: 2.25em;
379
- }
380
- #tribe-help-general h3 + p {
381
- margin: 0 0 20px;
382
- padding-left: 12px;
383
- }
384
- #tribe-help-general {
385
- width: 65%;
386
- }
387
- .tribe-help-section {
388
- padding-bottom: 10px;
389
- }
390
- .tribe-section-type-box {
391
- -khtml-border-radius: 4px;
392
- background-color: #f9f9f9;
393
- border: 1px solid #ccc;
394
- border-radius: 4px;
395
- padding: 8px 20px 12px;
396
- }
397
- .tribe-section-type-box img {
398
- height: auto;
399
- margin: 10px 0;
400
- max-width: 300px;
401
- }
402
- .tribe-section-type-box ul {
403
- list-style: disc;
404
- margin-left: 20px;
405
- }
406
- .tribe-section-type-box ul ul {
407
- list-style: circle;
408
- }
409
- #tribe-log-controls {
410
- padding-bottom: 16px;
411
- padding-bottom: 1rem;
412
-
413
- /* For consistency with help screen h3 and p elements */
414
- padding-left: 12px;
415
- }
416
- #tribe-log-controls > div {
417
- display: inline-block;
418
- padding-right: 16px;
419
- padding-right: 1rem;
420
- }
421
- #tribe-log-controls .working {
422
- opacity: 1;
423
- -webkit-transition: opacity 0.2s;
424
- transition: opacity 0.2s;
425
- }
426
- #tribe-log-controls .working.hidden {
427
- opacity: 0;
428
- -webkit-transition: opacity 0.2s;
429
- transition: opacity 0.2s;
430
- }
431
- #tribe-system-info dl.support-stats,
432
- #tribe-log-viewer,
433
- .template-updates-wrapper {
434
- background: #000;
435
- border-radius: 2px;
436
- color: #888;
437
- max-height: 400px;
438
- overflow: scroll;
439
- padding: 10px;
440
- }
441
- #tribe-system-info dl.support-stats dt,
442
- .template-updates-wrapper dt {
443
- clear: both;
444
- float: left;
445
- font-weight: bold;
446
- text-transform: uppercase;
447
- width: 25%;
448
- }
449
- #tribe-system-info dl.support-stats dd,
450
- .template-updates-wrapper dd {
451
- margin-left: 25%;
452
- padding-left: 10px;
453
- }
454
- .template-updates-wrapper p {
455
- margin-top: 0;
456
- }
457
- #tribe-help-sidebar {
458
- margin: 20px 0 0 3%;
459
- max-width: 225px;
460
- width: 32%;
461
- }
462
- .tribe-help-plugin-info {
463
- border: 1px solid #ccc;
464
- padding: 0 12px 12px;
465
- }
466
- .tribe-help-plugin-info dt,
467
- .tribe-help-plugin-info dd {
468
- display: inline;
469
- margin: 0;
470
- }
471
- .tribe-help-plugin-info dt {
472
- font-weight: bold;
473
- }
474
- .tribe-help-plugin-info dd::after {
475
- content: '';
476
- display: block;
477
- height: .4em;
478
- }
479
- .tribe-help-plugin-info dd:last-child::after {
480
- height: 0;
481
- }
482
- .tribe-help-plugin-info + .tribe-help-plugin-info {
483
- margin-top: 20px;
484
- }
485
- .tribe-help-plugin-info > div {
486
- line-height: 2em;
487
- }
488
- .tribe-help-plugin-info .star-rating {
489
- display: inline-block;
490
- margin-left: 3px;
491
- position: relative;
492
- top: -2px;
493
- }
494
- .tribe-help-plugin-info .tribe-list-addons {
495
- color: #21a6cb;
496
- font-size: 24px;
497
- list-style: circle inside;
498
- margin-bottom: 10px;
499
- margin-top: 10px;
500
- padding-left: 4px;
501
- }
502
- .tribe-help-plugin-info .tribe-list-addons a {
503
- font-size: 13px;
504
- left: -5px;
505
- position: relative;
506
- top: -5px;
507
- }
508
- .tribe-help-plugin-info .tribe-list-addons .tribe-active-addon {
509
- list-style: disc inside;
510
- }
511
- /* = jQuery UI
512
- =============================================*/
513
- .ui-widget-overlay {
514
- background: #666;
515
- filter: Alpha(Opacity=50);
516
- opacity: .50;
517
- }
518
- .ui-widget-shadow {
519
- background: #000;
520
- -webkit-border-radius: 5px;
521
- -moz-border-radius: 5px;
522
- filter: Alpha(Opacity=20);
523
- margin: -5px 0 0 -5px;
524
- opacity: .20;
525
- padding: 5px;
526
- }
527
- .ui-resizable {
528
- position: relative;
529
- }
530
- .ui-resizable-handle {
531
- display: block;
532
- font-size: .1px;
533
- position: absolute;
534
- z-index: 99999;
535
- }
536
- .ui-resizable-disabled .ui-resizable-handle,
537
- .ui-resizable-autohide .ui-resizable-handle {
538
- display: none;
539
- }
540
- .ui-resizable-n {
541
- cursor: n-resize;
542
- height: 7px;
543
- left: 0;
544
- top: -5px;
545
- width: 100%;
546
- }
547
- .ui-resizable-s {
548
- bottom: -5px;
549
- cursor: s-resize;
550
- height: 7px;
551
- left: 0;
552
- width: 100%;
553
- }
554
- .ui-resizable-e {
555
- cursor: e-resize;
556
- height: 100%;
557
- right: -5px;
558
- top: 0;
559
- width: 7px;
560
- }
561
- .ui-resizable-w {
562
- cursor: w-resize;
563
- height: 100%;
564
- left: -5px;
565
- top: 0;
566
- width: 7px;
567
- }
568
- .ui-resizable-se {
569
- bottom: 1px;
570
- cursor: se-resize;
571
- height: 12px;
572
- right: 1px;
573
- width: 12px;
574
- }
575
- .ui-resizable-sw {
576
- bottom: -5px;
577
- cursor: sw-resize;
578
- height: 9px;
579
- left: -5px;
580
- width: 9px;
581
- }
582
- .ui-resizable-nw {
583
- cursor: nw-resize;
584
- height: 9px;
585
- left: -5px;
586
- top: -5px;
587
- width: 9px;
588
- }
589
- .ui-resizable-ne {
590
- cursor: ne-resize;
591
- height: 9px;
592
- right: -5px;
593
- top: -5px;
594
- width: 9px;
595
- }
596
- .ui-dialog {
597
- padding: .2em;
598
- position: relative;
599
- width: 375px;
600
- }
601
- .ui-dialog .ui-dialog-titlebar {
602
- padding: .5em .3em .3em 1em;
603
- position: relative;
604
- }
605
- .ui-dialog .ui-dialog-title {
606
- float: left;
607
- margin: .1em 0 .2em;
608
- }
609
- .ui-dialog .ui-dialog-titlebar-close {
610
- height: 18px;
611
- margin: -10px 0 0 0;
612
- padding: 1px;
613
- position: absolute;
614
- right: .3em;
615
- top: 50%;
616
- width: 19px;
617
- }
618
- .ui-dialog .ui-dialog-titlebar-close span {
619
- display: block;
620
- margin-left: -8px;
621
- margin-top: -8px;
622
- }
623
- .ui-dialog .ui-dialog-titlebar-close:hover,
624
- .ui-dialog .ui-dialog-titlebar-close:focus {
625
- padding: 0;
626
- }
627
- .ui-dialog .ui-dialog-content {
628
- background: none;
629
- border: 0;
630
- overflow: auto;
631
- padding: .5em 1em;
632
- zoom: 1;
633
- }
634
- .ui-dialog .ui-dialog-buttonpane {
635
- background-image: none;
636
- border-width: 1px 0 0 0;
637
- margin: .5em 0 0 0;
638
- padding: .3em 1em .5em !important;
639
- text-align: right;
640
- }
641
- .ui-dialog .ui-dialog-buttonpane button {
642
- cursor: pointer;
643
- line-height: 1.4em;
644
- margin: .5em .4em .5em !important;
645
- overflow: visible;
646
- padding: .2em .6em .3em;
647
- text-shadow: none;
648
- width: auto;
649
- }
650
- .ui-dialog .ui-resizable-se {
651
- bottom: 3px;
652
- height: 14px;
653
- right: 3px;
654
- width: 14px;
655
- }
656
- .ui-draggable .ui-dialog-titlebar {
657
- cursor: move;
658
- }
659
- .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
660
- float: none !important;
661
- text-align: center;
662
- }
663
- .ui-button-text-only .ui-button-text {
664
- padding: .4em 1em;
665
- }
666
- .ui-button .ui-button-text {
667
- display: block;
668
- line-height: 1.4;
669
- }
670
- .ui-datepicker {
671
- font-size: 8pt;
672
- }
673
- #ui-datepicker-div {
674
- display: none;
675
- }
676
- #tribe-loading {
677
- background: #fff;
678
- background: rgba(255, 255, 255, .8);
679
- display: none;
680
- height: 100%;
681
- left: 0;
682
- position: absolute;
683
- top: 0;
684
- -webkit-transition: all 1s linear;
685
- transition: all 1s linear;
686
- webkit-transition: all 1s linear;
687
- width: 100%;
688
- z-index: 4;
689
- }
690
- #tribe-loading span {
691
- background: url(../images/tribe-loading.gif) 0 0 no-repeat;
692
- background-size: 32px 32px;
693
- height: 32px;
694
- left: 50%;
695
- margin: -16px 0 0 -16px;
696
- position: absolute;
697
- top: 50%;
698
- width: 32px;
699
- }
700
- /* = Admin Retina Bits
701
- =============================================*/
702
- /* = TEC Welcome & Update Pages // Displays after installation & plugin update
703
- ===============================================================================*/
704
- .tribe_welcome_page,
705
- .tribe_update_page {
706
- max-width: 1000px;
707
- }
708
- .tribe-half-column {
709
- float: left;
710
- margin-bottom: 30px;
711
- margin-right: 5%;
712
- width: 45%;
713
- }
714
- .tribe-row:before,
715
- .tribe-row:after {
716
- content: '';
717
- display: table;
718
- }
719
- .tribe-row:after {
720
- clear: both;
721
- }
722
- .tribe-row {
723
- clear: both;
724
- }
725
- .tribe-row .tribe-half-column:last-child {
726
- margin-right: 0;
727
- width: 50%;
728
- }
729
- .tribe_welcome_page h2,
730
- .tribe_update_page h2 {
731
- font-size: 30px;
732
- line-height: 1.2;
733
- margin-bottom: 20px;
734
- }
735
- .tribe_welcome_page h3,
736
- .tribe_update_page h3 {
737
- font-size: 24px;
738
- font-weight: 400;
739
- line-height: 24px;
740
- margin-top: 0;
741
- }
742
- .tribe_welcome_page h4,
743
- .tribe_update_page h4 {
744
- font-size: 18px;
745
- font-weight: 600;
746
- line-height: 18px;
747
- margin: 0;
748
- }
749
- .tribe_welcome_page p,
750
- .tribe_update_page p {
751
- font-size: 14px;
752
- }
753
- p.tribe-welcome-message {
754
- font-size: 20px;
755
- font-weight: 400;
756
- }
757
- .tribe_welcome_page h2:before,
758
- .tribe_update_page h2:before {
759
- content: '\f145';
760
- font-family: 'dashicons';
761
- font-size: 34px;
762
- line-height: 1;
763
- margin-right: 5px;
764
- position: relative;
765
- top: 5px;
766
- }
767
- .tribe-welcome-video-wrapper {
768
- height: 0;
769
- margin-bottom: 40px;
770
- padding-bottom: 56.25%; /* 16:9 */
771
- padding-top: 25px;
772
- position: relative;
773
- }
774
- .tribe-welcome-video-wrapper iframe {
775
- height: 100%;
776
- left: 0;
777
- position: absolute;
778
- top: 0;
779
- width: 100%;
780
- }
781
- a.tribe-rating-link {
782
- text-decoration: none;
783
- }
784
- .tribe-welcome-links,
785
- .tribe-update-links {
786
- margin-top: 30px;
787
- }
788
- .tribe_welcome_page li:before,
789
- .tribe_update_page li:before {
790
- content: '\2022';
791
- padding-right: 3px;
792
- }
793
- .tribe_update_page .rss-widget {
794
- margin: 1em 0;
795
- }
796
- .tribe_update_page a.rsswidget {
797
- font-size: 14px;
798
- font-weight: 400;
799
- line-height: 1;
800
- }
801
- .tribe_update_page .rss-widget li:before {
802
- display: none;
803
- }
804
- /* Media Queries for Mobile Dashboard */
805
- .tribe-update-bar {
806
- display: inline-block;
807
- }
808
- .tribe-update-bar .progress {
809
- border: 1px solid #ccc;
810
- float: left;
811
- margin-right: 16px;
812
- margin-right: 1rem;
813
- padding: 1px;
814
- width: 288px;
815
- width: 18rem;
816
- }
817
- .tribe-update-bar .progress .bar {
818
- background: #ffba00;
819
- height: 16px;
820
- height: 1rem;
821
- width: 1%;
822
- }
823
- .tribe-update-bar .progress .bar {
824
- background: #7ad03a;
825
- }
826
- /* bumpdown */
827
- .bumpdown {
828
- background: #f1f1f1;
829
- margin: 16px 0;
830
- margin: 1rem 0;
831
- padding: 16px 24px 16px 16px;
832
- padding: 1rem 1.5rem 1rem 1rem;
833
- position: relative;
834
- }
835
- #poststuff .bumpdown h1,
836
- #poststuff .bumpdown h2,
837
- #poststuff .bumpdown h3,
838
- #poststuff .bumpdown h4,
839
- .bumpdown h1,
840
- .bumpdown h2,
841
- .bumpdown h3,
842
- .bumpdown h4 {
843
- padding-left: 0;
844
- padding-top: 0;
845
- }
846
- .bumpdown-arrow {
847
- display: none;
848
- }
849
- .bumpdown-close {
850
- color: #686868;
851
- cursor: pointer;
852
- position: absolute;
853
- right: 8px;
854
- right: .5rem;
855
- top: 8px;
856
- top: .5rem;
857
- z-index: 2;
858
- }
859
- .bumpdown-trigger .target {
860
- color: #0074a2;
861
- }
862
- /* Useful to ensure modals rise above the grey 'miasma' */
863
- .ui-front {
864
- z-index: 1000000;
865
- }
866
- @media
867
- only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) {
868
- #tribe-loading span {
869
- background-image: url(../images/tribe-loading@2x.gif);
870
- }
871
- }
872
- @media screen and (max-width: 782px) {
873
- .tribe-half-column,
874
- .tribe-row .tribe-half-column:last-child {
875
- margin: 0 0 20px 0;
876
- width: 100%;
877
- }
878
- input[type='email'] {
879
- width: 100%;
880
- }
881
- }
882
- @media screen and ( max-width: 782px ) {
883
- .events-cal .subsubsub {
884
- float: none;
885
- }
886
- .events-cal .search-box {
887
- width: 98%;
888
- }
889
- .events-cal #search-submit {
890
- width: 100%;
891
- }
892
- .events-cal .tablenav.top {
893
- display: none;
894
- }
895
- }
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ /* = Shared CSS Elements
12
+ =============================================*/
13
+ .invalid input {
14
+ border: 2px solid red !important;
15
+ }
16
+ .valid input {
17
+ border: 1px solid green;
18
+ }
19
+ .clearfix {
20
+ zoom: 1; /* For IE */
21
+ }
22
+ .placeholder {
23
+ color: #999;
24
+ cursor: text;
25
+ padding: 4px 4px 4px 4px;
26
+ }
27
+ input:placeholder,
28
+ textarea:placeholder {
29
+ color: #999;
30
+ }
31
+ input::-webkit-input-placeholder,
32
+ textarea::-webkit-input-placeholder {
33
+ color: #999;
34
+ }
35
+ .bubble {
36
+ -khtml-border-radius: 3px;
37
+ background-color: #f9f9f9;
38
+ border-color: #dfdfdf;
39
+ border-radius: 3px;
40
+ border-spacing: 0;
41
+ border-style: solid;
42
+ border-style: solid;
43
+ border-width: 1px;
44
+ padding: 10px;
45
+ }
46
+ .tribe-sticky-tooltip {
47
+ color: #bbb;
48
+ }
49
+ td.tribe_message {
50
+ padding-bottom: 10px !important;
51
+ }
52
+ #tribe_thanks {
53
+ float: left;
54
+ margin: 5px 0 0 0;
55
+ width: 200px;
56
+ }
57
+ .tribe_brand {
58
+ font-family: Georgia !important;
59
+ font-size: 17px !important;
60
+ font-weight: normal;
61
+ margin: 8px 0;
62
+ }
63
+ /* = Upgrade Screen
64
+ =============================================*/
65
+ #tribe-upgrade {
66
+ background: #f6f6f6;
67
+ border: 1px solid #ccc;
68
+ border-radius: 5px;
69
+ margin: 20px 0 30px;
70
+ padding: 0 20px 20px;
71
+ }
72
+ #tribe-upgrade .message {
73
+ background-color: #ffffe0;
74
+ border-color: #e6db55;
75
+ border-radius: 3px;
76
+ border-style: solid;
77
+ border-width: 1px;
78
+ padding: 6px 12px;
79
+ }
80
+ /* = Plugin Screen
81
+ =============================================*/
82
+ table.plugins .tribe-plugin-update-message {
83
+ background: #d54e21; /* taken from colour scheme in list-tables.css */
84
+ color: white;
85
+ display: inline-table;
86
+ margin: 6px 0;
87
+ padding: 10px 12px;
88
+ }
89
+ table.plugins .tribe-plugin-update-message h4 {
90
+ display: inline;
91
+ font-weight: bold;
92
+ margin-right: 8px;
93
+ }
94
+ table.plugins .tribe-plugin-update-message h4:after {
95
+ content: ' \00BB ';
96
+ }
97
+ table.plugins .tribe-plugin-update-message a {
98
+ color: white;
99
+ text-decoration: underline;
100
+ }
101
+ /* = Settings Screen
102
+ =============================================*/
103
+ .tribe-settings-form {
104
+ max-width: 1000px;
105
+ }
106
+ .tribe-settings-form fieldset {
107
+ clear: both;
108
+ display: inline-block;
109
+ padding: 10px 0;
110
+ }
111
+ .tribe-settings-form legend {
112
+ float: left;
113
+ font-weight: bold;
114
+ margin-right: 20px;
115
+ width: 220px;
116
+ }
117
+ .tribe-settings-form fieldset.tribe-field-license_key legend {
118
+ width: auto;
119
+ }
120
+ .tribe-settings-form .tribe-field-wrap {
121
+ float: left;
122
+ max-width: 500px;
123
+ }
124
+ .tribe-settings-form .tribe-field-radio label,
125
+ .tribe-settings-form .tribe-field-checkbox_list label {
126
+ display: block;
127
+ margin: 5px 0;
128
+ }
129
+ .tribe-settings-form .tribe-field-radio label input,
130
+ .tribe-settings-form .tribe-field-checkbox_list label input {
131
+ margin-right: 5px;
132
+ }
133
+ .tribe-settings-form .tribe-settings-form-wrap fieldset,
134
+ .tribe-settings-form .tribe-settings-form-wrap .description,
135
+ .tribe-settings-form fieldset[id^='tribe-field-geoloc_'] {
136
+ padding-left: 12px;
137
+ }
138
+ .tribe-settings-form .tribe-settings-form-wrap fieldset .description {
139
+ margin-left: 0;
140
+ max-width: 450px;
141
+ padding-left: 0;
142
+ }
143
+ .tribe-settings-form .tribe-settings-form-wrap h3 {
144
+ background-color: #f9f9f9;
145
+ margin-bottom: 10px;
146
+ padding: 6px 0 6px 12px;
147
+ }
148
+ .tribe-settings-form .tribe-settings-form-wrap h3 ~ h3 {
149
+ margin-top: 2.25em;
150
+ }
151
+ .tribe-settings-form .tribe-settings-form-wrap h3 + p {
152
+ margin: 0 0 10px;
153
+ padding-left: 12px;
154
+ }
155
+ .tribe_settings .tribe-field-indent {
156
+ margin-left: 245px;
157
+ }
158
+ .tribe_settings #pu_dashboard_message {
159
+ display: none;
160
+ }
161
+ .tribe_settings .tribe-errors-list {
162
+ margin-left: 15px;
163
+ }
164
+ .tribe_settings .expiring-license {
165
+ color: red;
166
+ }
167
+ .tribe_settings .tribe-error {
168
+ border: 1px solid #f00;
169
+ }
170
+ .tribe_settings .tribe-field-description {
171
+ margin-bottom: 0;
172
+ position: relative;
173
+ top: -12px;
174
+ }
175
+ .tribe_settings #ical-link {
176
+ top: -14px;
177
+ }
178
+ .tribe-settings-form #tribe-field-stylesheetOption label {
179
+ margin-left: 20px;
180
+ }
181
+ .tribe-settings-form #tribe-field-stylesheetOption input {
182
+ margin-left: -20px;
183
+ margin-right: 8px;
184
+ }
185
+ .tribe-settings-form #tribe-field-stylesheetOption p.description {
186
+ color: #999;
187
+ }
188
+ /* Modern Tribe box */
189
+ #modern-tribe-info {
190
+ -khtml-border-radius: 4px;
191
+ background-color: #f9f9f9;
192
+ border: 1px solid #ccc;
193
+ border-radius: 4px;
194
+ margin: 20px 0;
195
+ padding: 8px 20px 12px;
196
+ }
197
+ #modern-tribe-info img {
198
+ height: 18px;
199
+ margin: 10px 0;
200
+ width: 250px;
201
+ }
202
+ #modern-tribe-info ul {
203
+ list-style: disc;
204
+ margin-left: 20px;
205
+ }
206
+ #modern-tribe-info ul ul {
207
+ list-style: circle;
208
+ }
209
+ /* sizes */
210
+ .tribe-field-textarea.tribe-size-small textarea {
211
+ height: 60px;
212
+ width: 180px;
213
+ }
214
+ .tribe-field-textarea.tribe-size-medium textarea {
215
+ height: 80px;
216
+ width: 300px;
217
+ }
218
+ .tribe-field-textarea.tribe-size-large textarea {
219
+ height: 120px;
220
+ width: 450px;
221
+ }
222
+ .tribe-field-text.tribe-size-small input,
223
+ .tribe-field-license_key.tribe-size-small input {
224
+ width: 50px;
225
+ }
226
+ .tribe-field-text.tribe-size-medium input,
227
+ .tribe-field-license_key.tribe-size-medium input {
228
+ width: 225px;
229
+ }
230
+ .tribe-field-text.tribe-size-large input,
231
+ .tribe-field-license_key.tribe-size-large input {
232
+ width: 450px;
233
+ }
234
+ .tribe-field-dropdown.tribe-size-small select {
235
+ width: 100px;
236
+ }
237
+ .tribe-field-dropdown.tribe-size-medium select {
238
+ width: 300px;
239
+ }
240
+ .tribe-field-dropdown.tribe-size-large select {
241
+ width: 450px;
242
+ }
243
+ .tribe-field-dropdown_chosen.tribe-size-small select {
244
+ width: 100px;
245
+ }
246
+ .tribe-field-dropdown_chosen.tribe-size-medium select {
247
+ width: 200px;
248
+ }
249
+ .tribe-field-dropdown_chosen.tribe-size-large select {
250
+ width: 300px;
251
+ }
252
+ /* license keys */
253
+ .ajax-loading-license,
254
+ .valid-key,
255
+ .invalid-key {
256
+ display: none;
257
+ margin: 0 5px;
258
+ }
259
+ .ajax-loading-license {
260
+ position: relative;
261
+ top: 5px;
262
+ }
263
+ .key-validity {
264
+ display: inline-block;
265
+ }
266
+ .invalid-key {
267
+ color: red;
268
+ }
269
+ .valid-key {
270
+ color: green;
271
+ }
272
+ .valid-key.service-msg {
273
+ color: #b72;
274
+ }
275
+ /* additional fields */
276
+ #additional-field-table {
277
+ margin-bottom: 20px;
278
+ }
279
+ /* miscellaneous */
280
+ .tribe-admin-box-left {
281
+ -khtml-border-radius: 4px;
282
+ background-color: #f9f9f9;
283
+ border: 1px solid #ccc;
284
+ border-radius: 4px;
285
+ float: left;
286
+ margin: 20px 0;
287
+ padding: 0 20px 15px;
288
+ width: 20%;
289
+ }
290
+ .tribe-admin-box-right {
291
+ -khtml-border-radius: 4px;
292
+ background-color: #f9f9f9;
293
+ border: 1px solid #ccc;
294
+ border-radius: 4px;
295
+ float: right;
296
+ margin: 20px 0;
297
+ padding: 0 20px 15px;
298
+ width: 68%;
299
+ }
300
+ .ajax-loader {
301
+ float: right;
302
+ margin: 10px;
303
+ }
304
+ .tribe-arrangeable-item {
305
+ border: 1px solid lightGrey;
306
+ border-radius: 6px;
307
+ }
308
+ .tribe-arrangeable-item .ui-state-default {
309
+ border: none;
310
+ }
311
+ .tribe-arrangeable-item-top {
312
+ padding: 6px;
313
+ }
314
+ .tribe-arrangeable-item-top:hover {
315
+ cursor: move;
316
+ }
317
+ .tribe-arrangeable-action {
318
+ float: right;
319
+ }
320
+ .tribe-arrangeable-child {
321
+ background-color: #f9f9f9;
322
+ border-top: 1px solid lightGrey;
323
+ display: none;
324
+ padding: 25px;
325
+ }
326
+ .tribe-arrangeable-child label {
327
+ display: block;
328
+ margin: 0 0 7px 0;
329
+ }
330
+ .tribe_events_active_filter_type_options {
331
+ margin: 10px 0;
332
+ }
333
+ .tribe_events_active_filter_type_options label {
334
+ margin: 7px 0;
335
+ }
336
+ .tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection {
337
+ margin-bottom: 18px;
338
+ }
339
+ .OrganizerInfo td small,
340
+ #event_organizer td small {
341
+ display: block;
342
+ margin: 0;
343
+ max-width: 250px;
344
+ }
345
+ .OrganizerInfo .organizer-email,
346
+ #event_organizer .organizer-email {
347
+ vertical-align: top;
348
+ }
349
+ .tribe-table-field-label {
350
+ max-width: 100%;
351
+ width: 200px;
352
+ }
353
+ /* = Help Screen
354
+ =============================================*/
355
+ #tribe-help-general,
356
+ #tribe-help-sidebar {
357
+ float: left;
358
+ margin-top: 20px;
359
+ }
360
+ #tribe-help-general p {
361
+ margin-left: 15px;
362
+ }
363
+ #tribe-help-general ul {
364
+ list-style-type: square;
365
+ margin-bottom: 20px;
366
+ margin-left: 35px;
367
+ }
368
+ #tribe-help-general ol {
369
+ margin-bottom: 20px;
370
+ margin-left: 35px;
371
+ }
372
+ #tribe-help-general h3 {
373
+ background-color: #f9f9f9;
374
+ margin-bottom: 10px;
375
+ padding: 6px 0 6px 12px;
376
+ }
377
+ #tribe-help-general h3 ~ h3 {
378
+ margin-top: 2.25em;
379
+ }
380
+ #tribe-help-general h3 + p {
381
+ margin: 0 0 20px;
382
+ padding-left: 12px;
383
+ }
384
+ #tribe-help-general {
385
+ width: 65%;
386
+ }
387
+ .tribe-help-section {
388
+ padding-bottom: 10px;
389
+ }
390
+ .tribe-section-type-box {
391
+ -khtml-border-radius: 4px;
392
+ background-color: #f9f9f9;
393
+ border: 1px solid #ccc;
394
+ border-radius: 4px;
395
+ padding: 8px 20px 12px;
396
+ }
397
+ .tribe-section-type-box img {
398
+ height: auto;
399
+ margin: 10px 0;
400
+ max-width: 300px;
401
+ }
402
+ .tribe-section-type-box ul {
403
+ list-style: disc;
404
+ margin-left: 20px;
405
+ }
406
+ .tribe-section-type-box ul ul {
407
+ list-style: circle;
408
+ }
409
+ #tribe-log-controls {
410
+ padding-bottom: 16px;
411
+ padding-bottom: 1rem;
412
+
413
+ /* For consistency with help screen h3 and p elements */
414
+ padding-left: 12px;
415
+ }
416
+ #tribe-log-controls > div {
417
+ display: inline-block;
418
+ padding-right: 16px;
419
+ padding-right: 1rem;
420
+ }
421
+ #tribe-log-controls .working {
422
+ opacity: 1;
423
+ -webkit-transition: opacity 0.2s;
424
+ transition: opacity 0.2s;
425
+ }
426
+ #tribe-log-controls .working.hidden {
427
+ opacity: 0;
428
+ -webkit-transition: opacity 0.2s;
429
+ transition: opacity 0.2s;
430
+ }
431
+ #tribe-system-info dl.support-stats,
432
+ #tribe-log-viewer,
433
+ .template-updates-wrapper {
434
+ background: #000;
435
+ border-radius: 2px;
436
+ color: #888;
437
+ max-height: 400px;
438
+ overflow: scroll;
439
+ padding: 10px;
440
+ }
441
+ #tribe-system-info dl.support-stats dt,
442
+ .template-updates-wrapper dt {
443
+ clear: both;
444
+ float: left;
445
+ font-weight: bold;
446
+ text-transform: uppercase;
447
+ width: 25%;
448
+ }
449
+ #tribe-system-info dl.support-stats dd,
450
+ .template-updates-wrapper dd {
451
+ margin-left: 25%;
452
+ padding-left: 10px;
453
+ }
454
+ .template-updates-wrapper p {
455
+ margin-top: 0;
456
+ }
457
+ #tribe-help-sidebar {
458
+ margin: 20px 0 0 3%;
459
+ max-width: 225px;
460
+ width: 32%;
461
+ }
462
+ .tribe-help-plugin-info {
463
+ border: 1px solid #ccc;
464
+ padding: 0 12px 12px;
465
+ }
466
+ .tribe-help-plugin-info dt,
467
+ .tribe-help-plugin-info dd {
468
+ display: inline;
469
+ margin: 0;
470
+ }
471
+ .tribe-help-plugin-info dt {
472
+ font-weight: bold;
473
+ }
474
+ .tribe-help-plugin-info dd::after {
475
+ content: '';
476
+ display: block;
477
+ height: .4em;
478
+ }
479
+ .tribe-help-plugin-info dd:last-child::after {
480
+ height: 0;
481
+ }
482
+ .tribe-help-plugin-info + .tribe-help-plugin-info {
483
+ margin-top: 20px;
484
+ }
485
+ .tribe-help-plugin-info > div {
486
+ line-height: 2em;
487
+ }
488
+ .tribe-help-plugin-info .star-rating {
489
+ display: inline-block;
490
+ margin-left: 3px;
491
+ position: relative;
492
+ top: -2px;
493
+ }
494
+ .tribe-help-plugin-info .tribe-list-addons {
495
+ color: #21a6cb;
496
+ font-size: 24px;
497
+ list-style: circle inside;
498
+ margin-bottom: 10px;
499
+ margin-top: 10px;
500
+ padding-left: 4px;
501
+ }
502
+ .tribe-help-plugin-info .tribe-list-addons a {
503
+ font-size: 13px;
504
+ left: -5px;
505
+ position: relative;
506
+ top: -5px;
507
+ }
508
+ .tribe-help-plugin-info .tribe-list-addons .tribe-active-addon {
509
+ list-style: disc inside;
510
+ }
511
+ /* = jQuery UI
512
+ =============================================*/
513
+ .ui-widget-overlay {
514
+ background: #666;
515
+ filter: Alpha(Opacity=50);
516
+ opacity: .50;
517
+ }
518
+ .ui-widget-shadow {
519
+ background: #000;
520
+ -webkit-border-radius: 5px;
521
+ -moz-border-radius: 5px;
522
+ filter: Alpha(Opacity=20);
523
+ margin: -5px 0 0 -5px;
524
+ opacity: .20;
525
+ padding: 5px;
526
+ }
527
+ .ui-resizable {
528
+ position: relative;
529
+ }
530
+ .ui-resizable-handle {
531
+ display: block;
532
+ font-size: .1px;
533
+ position: absolute;
534
+ z-index: 99999;
535
+ }
536
+ .ui-resizable-disabled .ui-resizable-handle,
537
+ .ui-resizable-autohide .ui-resizable-handle {
538
+ display: none;
539
+ }
540
+ .ui-resizable-n {
541
+ cursor: n-resize;
542
+ height: 7px;
543
+ left: 0;
544
+ top: -5px;
545
+ width: 100%;
546
+ }
547
+ .ui-resizable-s {
548
+ bottom: -5px;
549
+ cursor: s-resize;
550
+ height: 7px;
551
+ left: 0;
552
+ width: 100%;
553
+ }
554
+ .ui-resizable-e {
555
+ cursor: e-resize;
556
+ height: 100%;
557
+ right: -5px;
558
+ top: 0;
559
+ width: 7px;
560
+ }
561
+ .ui-resizable-w {
562
+ cursor: w-resize;
563
+ height: 100%;
564
+ left: -5px;
565
+ top: 0;
566
+ width: 7px;
567
+ }
568
+ .ui-resizable-se {
569
+ bottom: 1px;
570
+ cursor: se-resize;
571
+ height: 12px;
572
+ right: 1px;
573
+ width: 12px;
574
+ }
575
+ .ui-resizable-sw {
576
+ bottom: -5px;
577
+ cursor: sw-resize;
578
+ height: 9px;
579
+ left: -5px;
580
+ width: 9px;
581
+ }
582
+ .ui-resizable-nw {
583
+ cursor: nw-resize;
584
+ height: 9px;
585
+ left: -5px;
586
+ top: -5px;
587
+ width: 9px;
588
+ }
589
+ .ui-resizable-ne {
590
+ cursor: ne-resize;
591
+ height: 9px;
592
+ right: -5px;
593
+ top: -5px;
594
+ width: 9px;
595
+ }
596
+ .ui-dialog {
597
+ padding: .2em;
598
+ position: relative;
599
+ width: 375px;
600
+ }
601
+ .ui-dialog .ui-dialog-titlebar {
602
+ padding: .5em .3em .3em 1em;
603
+ position: relative;
604
+ }
605
+ .ui-dialog .ui-dialog-title {
606
+ float: left;
607
+ margin: .1em 0 .2em;
608
+ }
609
+ .ui-dialog .ui-dialog-titlebar-close {
610
+ height: 18px;
611
+ margin: -10px 0 0 0;
612
+ padding: 1px;
613
+ position: absolute;
614
+ right: .3em;
615
+ top: 50%;
616
+ width: 19px;
617
+ }
618
+ .ui-dialog .ui-dialog-titlebar-close span {
619
+ display: block;
620
+ margin-left: -8px;
621
+ margin-top: -8px;
622
+ }
623
+ .ui-dialog .ui-dialog-titlebar-close:hover,
624
+ .ui-dialog .ui-dialog-titlebar-close:focus {
625
+ padding: 0;
626
+ }
627
+ .ui-dialog .ui-dialog-content {
628
+ background: none;
629
+ border: 0;
630
+ overflow: auto;
631
+ padding: .5em 1em;
632
+ zoom: 1;
633
+ }
634
+ .ui-dialog .ui-dialog-buttonpane {
635
+ background-image: none;
636
+ border-width: 1px 0 0 0;
637
+ margin: .5em 0 0 0;
638
+ padding: .3em 1em .5em !important;
639
+ text-align: right;
640
+ }
641
+ .ui-dialog .ui-dialog-buttonpane button {
642
+ cursor: pointer;
643
+ line-height: 1.4em;
644
+ margin: .5em .4em .5em !important;
645
+ overflow: visible;
646
+ padding: .2em .6em .3em;
647
+ text-shadow: none;
648
+ width: auto;
649
+ }
650
+ .ui-dialog .ui-resizable-se {
651
+ bottom: 3px;
652
+ height: 14px;
653
+ right: 3px;
654
+ width: 14px;
655
+ }
656
+ .ui-draggable .ui-dialog-titlebar {
657
+ cursor: move;
658
+ }
659
+ .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
660
+ float: none !important;
661
+ text-align: center;
662
+ }
663
+ .ui-button-text-only .ui-button-text {
664
+ padding: .4em 1em;
665
+ }
666
+ .ui-button .ui-button-text {
667
+ display: block;
668
+ line-height: 1.4;
669
+ }
670
+ .ui-datepicker {
671
+ font-size: 8pt;
672
+ }
673
+ #ui-datepicker-div {
674
+ display: none;
675
+ }
676
+ #tribe-loading {
677
+ background: #fff;
678
+ background: rgba(255, 255, 255, .8);
679
+ display: none;
680
+ height: 100%;
681
+ left: 0;
682
+ position: absolute;
683
+ top: 0;
684
+ -webkit-transition: all 1s linear;
685
+ transition: all 1s linear;
686
+ webkit-transition: all 1s linear;
687
+ width: 100%;
688
+ z-index: 4;
689
+ }
690
+ #tribe-loading span {
691
+ background: url(../images/tribe-loading.gif) 0 0 no-repeat;
692
+ background-size: 32px 32px;
693
+ height: 32px;
694
+ left: 50%;
695
+ margin: -16px 0 0 -16px;
696
+ position: absolute;
697
+ top: 50%;
698
+ width: 32px;
699
+ }
700
+ /* = Admin Retina Bits
701
+ =============================================*/
702
+ /* = TEC Welcome & Update Pages // Displays after installation & plugin update
703
+ ===============================================================================*/
704
+ .tribe_welcome_page,
705
+ .tribe_update_page {
706
+ max-width: 1000px;
707
+ }
708
+ .tribe-half-column {
709
+ float: left;
710
+ margin-bottom: 30px;
711
+ margin-right: 5%;
712
+ width: 45%;
713
+ }
714
+ .tribe-row:before,
715
+ .tribe-row:after {
716
+ content: '';
717
+ display: table;
718
+ }
719
+ .tribe-row:after {
720
+ clear: both;
721
+ }
722
+ .tribe-row {
723
+ clear: both;
724
+ }
725
+ .tribe-row .tribe-half-column:last-child {
726
+ margin-right: 0;
727
+ width: 50%;
728
+ }
729
+ .tribe_welcome_page h2,
730
+ .tribe_update_page h2 {
731
+ font-size: 30px;
732
+ line-height: 1.2;
733
+ margin-bottom: 20px;
734
+ }
735
+ .tribe_welcome_page h3,
736
+ .tribe_update_page h3 {
737
+ font-size: 24px;
738
+ font-weight: 400;
739
+ line-height: 24px;
740
+ margin-top: 0;
741
+ }
742
+ .tribe_welcome_page h4,
743
+ .tribe_update_page h4 {
744
+ font-size: 18px;
745
+ font-weight: 600;
746
+ line-height: 18px;
747
+ margin: 0;
748
+ }
749
+ .tribe_welcome_page p,
750
+ .tribe_update_page p {
751
+ font-size: 14px;
752
+ }
753
+ p.tribe-welcome-message {
754
+ font-size: 20px;
755
+ font-weight: 400;
756
+ }
757
+ .tribe_welcome_page h2:before,
758
+ .tribe_update_page h2:before {
759
+ content: '\f145';
760
+ font-family: 'dashicons';
761
+ font-size: 34px;
762
+ line-height: 1;
763
+ margin-right: 5px;
764
+ position: relative;
765
+ top: 5px;
766
+ }
767
+ .tribe-welcome-video-wrapper {
768
+ height: 0;
769
+ margin-bottom: 40px;
770
+ padding-bottom: 56.25%; /* 16:9 */
771
+ padding-top: 25px;
772
+ position: relative;
773
+ }
774
+ .tribe-welcome-video-wrapper iframe {
775
+ height: 100%;
776
+ left: 0;
777
+ position: absolute;
778
+ top: 0;
779
+ width: 100%;
780
+ }
781
+ a.tribe-rating-link {
782
+ text-decoration: none;
783
+ }
784
+ .tribe-welcome-links,
785
+ .tribe-update-links {
786
+ margin-top: 30px;
787
+ }
788
+ .tribe_welcome_page li:before,
789
+ .tribe_update_page li:before {
790
+ content: '\2022';
791
+ padding-right: 3px;
792
+ }
793
+ .tribe_update_page .rss-widget {
794
+ margin: 1em 0;
795
+ }
796
+ .tribe_update_page a.rsswidget {
797
+ font-size: 14px;
798
+ font-weight: 400;
799
+ line-height: 1;
800
+ }
801
+ .tribe_update_page .rss-widget li:before {
802
+ display: none;
803
+ }
804
+ /* Media Queries for Mobile Dashboard */
805
+ .tribe-update-bar {
806
+ display: inline-block;
807
+ }
808
+ .tribe-update-bar .progress {
809
+ border: 1px solid #ccc;
810
+ float: left;
811
+ margin-right: 16px;
812
+ margin-right: 1rem;
813
+ padding: 1px;
814
+ width: 288px;
815
+ width: 18rem;
816
+ }
817
+ .tribe-update-bar .progress .bar {
818
+ background: #ffba00;
819
+ height: 16px;
820
+ height: 1rem;
821
+ width: 1%;
822
+ }
823
+ .tribe-update-bar .progress .bar {
824
+ background: #7ad03a;
825
+ }
826
+ /* bumpdown */
827
+ .bumpdown {
828
+ background: #f1f1f1;
829
+ margin: 16px 0;
830
+ margin: 1rem 0;
831
+ padding: 16px 24px 16px 16px;
832
+ padding: 1rem 1.5rem 1rem 1rem;
833
+ position: relative;
834
+ }
835
+ #poststuff .bumpdown h1,
836
+ #poststuff .bumpdown h2,
837
+ #poststuff .bumpdown h3,
838
+ #poststuff .bumpdown h4,
839
+ .bumpdown h1,
840
+ .bumpdown h2,
841
+ .bumpdown h3,
842
+ .bumpdown h4 {
843
+ padding-left: 0;
844
+ padding-top: 0;
845
+ }
846
+ .bumpdown-arrow {
847
+ display: none;
848
+ }
849
+ .bumpdown-close {
850
+ color: #686868;
851
+ cursor: pointer;
852
+ position: absolute;
853
+ right: 8px;
854
+ right: .5rem;
855
+ top: 8px;
856
+ top: .5rem;
857
+ z-index: 2;
858
+ }
859
+ .bumpdown-trigger .target {
860
+ color: #0074a2;
861
+ }
862
+ /* Useful to ensure modals rise above the grey 'miasma' */
863
+ .ui-front {
864
+ z-index: 1000000;
865
+ }
866
+ @media
867
+ only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) {
868
+ #tribe-loading span {
869
+ background-image: url(../images/tribe-loading@2x.gif);
870
+ }
871
+ }
872
+ @media screen and (max-width: 782px) {
873
+ .tribe-half-column,
874
+ .tribe-row .tribe-half-column:last-child {
875
+ margin: 0 0 20px 0;
876
+ width: 100%;
877
+ }
878
+ input[type='email'] {
879
+ width: 100%;
880
+ }
881
+ }
882
+ @media screen and ( max-width: 782px ) {
883
+ .events-cal .subsubsub {
884
+ float: none;
885
+ }
886
+ .events-cal .search-box {
887
+ width: 98%;
888
+ }
889
+ .events-cal #search-submit {
890
+ width: 100%;
891
+ }
892
+ .events-cal .tablenav.top {
893
+ display: none;
894
+ }
895
+ }
common/src/resources/css/tribe-common-admin.min.css CHANGED
@@ -1 +1 @@
1
- .invalid input{border:2px solid red!important}.valid input{border:1px solid green}.clearfix{zoom:1}.placeholder{color:#999;cursor:text;padding:4px}input:placeholder,textarea:placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.bubble{-khtml-border-radius:3px;background-color:#f9f9f9;border:1px solid #dfdfdf;border-radius:3px;border-spacing:0;border-style:solid;padding:10px}.tribe-sticky-tooltip{color:#bbb}td.tribe_message{padding-bottom:10px!important}#tribe_thanks{float:left;margin:5px 0 0;width:200px}.tribe_brand{font-family:Georgia!important;font-size:17px!important;font-weight:400;margin:8px 0}#tribe-upgrade{background:#f6f6f6;border:1px solid #ccc;border-radius:5px;margin:20px 0 30px;padding:0 20px 20px}#tribe-upgrade .message{background-color:#ffffe0;border:1px solid #e6db55;border-radius:3px;padding:6px 12px}table.plugins .tribe-plugin-update-message{background:#d54e21;color:#fff;display:inline-table;margin:6px 0;padding:10px 12px}table.plugins .tribe-plugin-update-message h4{display:inline;font-weight:700;margin-right:8px}table.plugins .tribe-plugin-update-message h4:after{content:' \00BB '}table.plugins .tribe-plugin-update-message a{color:#fff;text-decoration:underline}.tribe-settings-form{max-width:1000px}.tribe-settings-form fieldset{clear:both;display:inline-block;padding:10px 0}.tribe-settings-form legend{float:left;font-weight:700;margin-right:20px;width:220px}.tribe-settings-form fieldset.tribe-field-license_key legend{width:auto}.tribe-settings-form .tribe-field-wrap{float:left;max-width:500px}.tribe-settings-form .tribe-field-checkbox_list label,.tribe-settings-form .tribe-field-radio label{display:block;margin:5px 0}.tribe-settings-form .tribe-field-checkbox_list label input,.tribe-settings-form .tribe-field-radio label input{margin-right:5px}.tribe-settings-form .tribe-settings-form-wrap .description,.tribe-settings-form .tribe-settings-form-wrap fieldset,.tribe-settings-form fieldset[id^=tribe-field-geoloc_]{padding-left:12px}.tribe-settings-form .tribe-settings-form-wrap fieldset .description{margin-left:0;max-width:450px;padding-left:0}.tribe-settings-form .tribe-settings-form-wrap h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}.tribe-settings-form .tribe-settings-form-wrap h3~h3{margin-top:2.25em}.tribe-settings-form .tribe-settings-form-wrap h3+p{margin:0 0 10px;padding-left:12px}.tribe_settings .tribe-field-indent{margin-left:245px}.tribe_settings #pu_dashboard_message{display:none}.tribe_settings .tribe-errors-list{margin-left:15px}.tribe_settings .expiring-license{color:red}.tribe_settings .tribe-error{border:1px solid red}.tribe_settings .tribe-field-description{margin-bottom:0;position:relative;top:-12px}.tribe_settings #ical-link{top:-14px}.tribe-settings-form #tribe-field-stylesheetOption label{margin-left:20px}.tribe-settings-form #tribe-field-stylesheetOption input{margin-left:-20px;margin-right:8px}.tribe-settings-form #tribe-field-stylesheetOption p.description{color:#999}#modern-tribe-info{-khtml-border-radius:4px;background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:8px 20px 12px}#modern-tribe-info img{height:18px;margin:10px 0;width:250px}#modern-tribe-info ul{list-style:disc;margin-left:20px}#modern-tribe-info ul ul{list-style:circle}.tribe-field-textarea.tribe-size-small textarea{height:60px;width:180px}.tribe-field-textarea.tribe-size-medium textarea{height:80px;width:300px}.tribe-field-textarea.tribe-size-large textarea{height:120px;width:450px}.tribe-field-license_key.tribe-size-small input,.tribe-field-text.tribe-size-small input{width:50px}.tribe-field-license_key.tribe-size-medium input,.tribe-field-text.tribe-size-medium input{width:225px}.tribe-field-license_key.tribe-size-large input,.tribe-field-text.tribe-size-large input{width:450px}.tribe-field-dropdown.tribe-size-small select{width:100px}.tribe-field-dropdown.tribe-size-medium select{width:300px}.tribe-field-dropdown.tribe-size-large select{width:450px}.tribe-field-dropdown_chosen.tribe-size-small select{width:100px}.tribe-field-dropdown_chosen.tribe-size-medium select{width:200px}.tribe-field-dropdown_chosen.tribe-size-large select{width:300px}.ajax-loading-license,.invalid-key,.valid-key{display:none;margin:0 5px}.ajax-loading-license{position:relative;top:5px}.key-validity{display:inline-block}.invalid-key{color:red}.valid-key{color:green}.valid-key.service-msg{color:#b72}#additional-field-table{margin-bottom:20px}.tribe-admin-box-left{float:left;width:20%}.tribe-admin-box-left,.tribe-admin-box-right{-khtml-border-radius:4px;background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:0 20px 15px}.tribe-admin-box-right{float:right;width:68%}.ajax-loader{float:right;margin:10px}.tribe-arrangeable-item{border:1px solid #d3d3d3;border-radius:6px}.tribe-arrangeable-item .ui-state-default{border:none}.tribe-arrangeable-item-top{padding:6px}.tribe-arrangeable-item-top:hover{cursor:move}.tribe-arrangeable-action{float:right}.tribe-arrangeable-child{background-color:#f9f9f9;border-top:1px solid #d3d3d3;display:none;padding:25px}.tribe-arrangeable-child label{display:block;margin:0 0 7px}.tribe_events_active_filter_type_options{margin:10px 0}.tribe_events_active_filter_type_options label{margin:7px 0}.tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection{margin-bottom:18px}#event_organizer td small,.OrganizerInfo td small{display:block;margin:0;max-width:250px}#event_organizer .organizer-email,.OrganizerInfo .organizer-email{vertical-align:top}.tribe-table-field-label{max-width:100%;width:200px}#tribe-help-general,#tribe-help-sidebar{float:left;margin-top:20px}#tribe-help-general p{margin-left:15px}#tribe-help-general ul{list-style-type:square}#tribe-help-general ol,#tribe-help-general ul{margin-bottom:20px;margin-left:35px}#tribe-help-general h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}#tribe-help-general h3~h3{margin-top:2.25em}#tribe-help-general h3+p{margin:0 0 20px;padding-left:12px}#tribe-help-general{width:65%}.tribe-help-section{padding-bottom:10px}.tribe-section-type-box{-khtml-border-radius:4px;background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;padding:8px 20px 12px}.tribe-section-type-box img{height:auto;margin:10px 0;max-width:300px}.tribe-section-type-box ul{list-style:disc;margin-left:20px}.tribe-section-type-box ul ul{list-style:circle}#tribe-log-controls{padding-bottom:16px;padding-bottom:1rem;padding-left:12px}#tribe-log-controls>div{display:inline-block;padding-right:16px;padding-right:1rem}#tribe-log-controls .working{opacity:1;-webkit-transition:opacity .2s;transition:opacity .2s}#tribe-log-controls .working.hidden{opacity:0;-webkit-transition:opacity .2s;transition:opacity .2s}#tribe-log-viewer,#tribe-system-info dl.support-stats,.template-updates-wrapper{background:#000;border-radius:2px;color:#888;max-height:400px;overflow:scroll;padding:10px}#tribe-system-info dl.support-stats dt,.template-updates-wrapper dt{clear:both;float:left;font-weight:700;text-transform:uppercase;width:25%}#tribe-system-info dl.support-stats dd,.template-updates-wrapper dd{margin-left:25%;padding-left:10px}.template-updates-wrapper p{margin-top:0}#tribe-help-sidebar{margin:20px 0 0 3%;max-width:225px;width:32%}.tribe-help-plugin-info{border:1px solid #ccc;padding:0 12px 12px}.tribe-help-plugin-info dd,.tribe-help-plugin-info dt{display:inline;margin:0}.tribe-help-plugin-info dt{font-weight:700}.tribe-help-plugin-info dd:after{content:'';display:block;height:.4em}.tribe-help-plugin-info dd:last-child:after{height:0}.tribe-help-plugin-info+.tribe-help-plugin-info{margin-top:20px}.tribe-help-plugin-info>div{line-height:2em}.tribe-help-plugin-info .star-rating{display:inline-block;margin-left:3px;position:relative;top:-2px}.tribe-help-plugin-info .tribe-list-addons{color:#21a6cb;font-size:24px;list-style:circle inside;margin-bottom:10px;margin-top:10px;padding-left:4px}.tribe-help-plugin-info .tribe-list-addons a{font-size:13px;left:-5px;position:relative;top:-5px}.tribe-help-plugin-info .tribe-list-addons .tribe-active-addon{list-style:disc inside}.ui-widget-overlay{background:#666;filter:Alpha(Opacity=50);opacity:.5}.ui-widget-shadow{background:#000;-webkit-border-radius:5px;-moz-border-radius:5px;filter:Alpha(Opacity=20);margin:-5px 0 0 -5px;opacity:.2;padding:5px}.ui-resizable{position:relative}.ui-resizable-handle{display:block;font-size:.1px;position:absolute;z-index:3}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;left:0;top:-5px;width:100%}.ui-resizable-s{bottom:-5px;cursor:s-resize;height:7px;left:0;width:100%}.ui-resizable-e{cursor:e-resize;height:100%;right:-5px;top:0;width:7px}.ui-resizable-w{cursor:w-resize;height:100%;left:-5px;top:0;width:7px}.ui-resizable-se{bottom:1px;cursor:se-resize;height:12px;right:1px;width:12px}.ui-resizable-sw{bottom:-5px;cursor:sw-resize;height:9px;left:-5px;width:9px}.ui-resizable-nw{cursor:nw-resize;height:9px;left:-5px;top:-5px;width:9px}.ui-resizable-ne{cursor:ne-resize;height:9px;right:-5px;top:-5px;width:9px}.ui-dialog{padding:.2em;position:relative;width:375px}.ui-dialog .ui-dialog-titlebar{padding:.5em .3em .3em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0 .2em}.ui-dialog .ui-dialog-titlebar-close{height:18px;margin:-10px 0 0;padding:1px;position:absolute;right:.3em;top:50%;width:19px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin-left:-8px;margin-top:-8px}.ui-dialog .ui-dialog-titlebar-close:focus,.ui-dialog .ui-dialog-titlebar-close:hover{padding:0}.ui-dialog .ui-dialog-content{background:none;border:0;overflow:auto;padding:.5em 1em;zoom:1}.ui-dialog .ui-dialog-buttonpane{background-image:none;border-width:1px 0 0;margin:.5em 0 0;padding:.3em 1em .5em!important;text-align:right}.ui-dialog .ui-dialog-buttonpane button{cursor:pointer;line-height:1.4em;margin:.5em .4em!important;overflow:visible;padding:.2em .6em .3em;text-shadow:none;width:auto}.ui-dialog .ui-resizable-se{bottom:3px;height:14px;right:3px;width:14px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:none!important;text-align:center}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button .ui-button-text{display:block;line-height:1.4}.ui-datepicker{font-size:8pt}#ui-datepicker-div{display:none}#tribe-loading{background:#fff;background:hsla(0,0%,100%,.8);display:none;height:100%;left:0;position:absolute;top:0;-webkit-transition:all 1s linear;transition:all 1s linear;webkit-transition:all 1s linear;width:100%;z-index:2}#tribe-loading span{background:url(../images/tribe-loading.gif) 0 0 no-repeat;background-size:32px 32px;height:32px;left:50%;margin:-16px 0 0 -16px;position:absolute;top:50%;width:32px}.tribe_update_page,.tribe_welcome_page{max-width:1000px}.tribe-half-column{float:left;margin-bottom:30px;margin-right:5%;width:45%}.tribe-row:after,.tribe-row:before{content:'';display:table}.tribe-row,.tribe-row:after{clear:both}.tribe-row .tribe-half-column:last-child{margin-right:0;width:50%}.tribe_update_page h2,.tribe_welcome_page h2{font-size:30px;margin-bottom:20px}.tribe_update_page h3,.tribe_welcome_page h3{font-size:24px;font-weight:400;line-height:24px;margin-top:0}.tribe_update_page h4,.tribe_welcome_page h4{font-size:18px;font-weight:600;line-height:18px;margin:0}.tribe_update_page p,.tribe_welcome_page p{font-size:14px}p.tribe-welcome-message{font-size:20px;font-weight:400}.tribe_update_page h2:before,.tribe_welcome_page h2:before{content:'\f145';font-family:dashicons;font-size:34px;line-height:1;margin-right:5px;position:relative;top:5px}.tribe-welcome-video-wrapper{height:0;margin-bottom:40px;padding-bottom:56.25%;padding-top:25px;position:relative}.tribe-welcome-video-wrapper iframe{height:100%;left:0;position:absolute;top:0;width:100%}a.tribe-rating-link{text-decoration:none}.tribe-update-links,.tribe-welcome-links{margin-top:30px}.tribe_update_page li:before,.tribe_welcome_page li:before{content:'\2022';padding-right:3px}.tribe_update_page .rss-widget{margin:1em 0}.tribe_update_page a.rsswidget{font-size:14px;font-weight:400;line-height:1}.tribe_update_page .rss-widget li:before{display:none}.tribe-update-bar{display:inline-block}.tribe-update-bar .progress{border:1px solid #ccc;float:left;margin-right:16px;margin-right:1rem;padding:1px;width:288px;width:18rem}.tribe-update-bar .progress .bar{background:#ffba00;height:16px;height:1rem;width:1%;background:#7ad03a}.bumpdown{background:#f1f1f1;margin:16px 0;margin:1rem 0;padding:16px 24px 16px 16px;padding:1rem 1.5rem 1rem 1rem;position:relative}#poststuff .bumpdown h1,#poststuff .bumpdown h2,#poststuff .bumpdown h3,#poststuff .bumpdown h4,.bumpdown h1,.bumpdown h2,.bumpdown h3,.bumpdown h4{padding-left:0;padding-top:0}.bumpdown-arrow{display:none}.bumpdown-close{color:#686868;cursor:pointer;position:absolute;right:8px;right:.5rem;top:8px;top:.5rem;z-index:1}.bumpdown-trigger .target{color:#0074a2}.ui-front{z-index:4}@media only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min--moz-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){#tribe-loading span{background-image:url(../images/tribe-loading@2x.gif)}}@media screen and (max-width:782px){.tribe-half-column,.tribe-row .tribe-half-column:last-child{margin:0 0 20px;width:100%}input[type=email]{width:100%}}@media screen and (max-width:782px){.events-cal .subsubsub{float:none}.events-cal .search-box{width:98%}.events-cal #search-submit{width:100%}.events-cal .tablenav.top{display:none}}
1
+ .invalid input{border:2px solid red!important}.valid input{border:1px solid green}.clearfix{zoom:1}.placeholder{color:#999;cursor:text;padding:4px}input:placeholder,textarea:placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.bubble{-khtml-border-radius:3px;background-color:#f9f9f9;border:1px solid #dfdfdf;border-radius:3px;border-spacing:0;border-style:solid;padding:10px}.tribe-sticky-tooltip{color:#bbb}td.tribe_message{padding-bottom:10px!important}#tribe_thanks{float:left;margin:5px 0 0;width:200px}.tribe_brand{font-family:Georgia!important;font-size:17px!important;font-weight:400;margin:8px 0}#tribe-upgrade{background:#f6f6f6;border:1px solid #ccc;border-radius:5px;margin:20px 0 30px;padding:0 20px 20px}#tribe-upgrade .message{background-color:#ffffe0;border:1px solid #e6db55;border-radius:3px;padding:6px 12px}table.plugins .tribe-plugin-update-message{background:#d54e21;color:#fff;display:inline-table;margin:6px 0;padding:10px 12px}table.plugins .tribe-plugin-update-message h4{display:inline;font-weight:700;margin-right:8px}table.plugins .tribe-plugin-update-message h4:after{content:' \00BB '}table.plugins .tribe-plugin-update-message a{color:#fff;text-decoration:underline}.tribe-settings-form{max-width:1000px}.tribe-settings-form fieldset{clear:both;display:inline-block;padding:10px 0}.tribe-settings-form legend{float:left;font-weight:700;margin-right:20px;width:220px}.tribe-settings-form fieldset.tribe-field-license_key legend{width:auto}.tribe-settings-form .tribe-field-wrap{float:left;max-width:500px}.tribe-settings-form .tribe-field-checkbox_list label,.tribe-settings-form .tribe-field-radio label{display:block;margin:5px 0}.tribe-settings-form .tribe-field-checkbox_list label input,.tribe-settings-form .tribe-field-radio label input{margin-right:5px}.tribe-settings-form .tribe-settings-form-wrap .description,.tribe-settings-form .tribe-settings-form-wrap fieldset,.tribe-settings-form fieldset[id^=tribe-field-geoloc_]{padding-left:12px}.tribe-settings-form .tribe-settings-form-wrap fieldset .description{margin-left:0;max-width:450px;padding-left:0}.tribe-settings-form .tribe-settings-form-wrap h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}.tribe-settings-form .tribe-settings-form-wrap h3~h3{margin-top:2.25em}.tribe-settings-form .tribe-settings-form-wrap h3+p{margin:0 0 10px;padding-left:12px}.tribe_settings .tribe-field-indent{margin-left:245px}.tribe_settings #pu_dashboard_message{display:none}.tribe_settings .tribe-errors-list{margin-left:15px}.tribe_settings .expiring-license{color:red}.tribe_settings .tribe-error{border:1px solid red}.tribe_settings .tribe-field-description{margin-bottom:0;position:relative;top:-12px}.tribe_settings #ical-link{top:-14px}.tribe-settings-form #tribe-field-stylesheetOption label{margin-left:20px}.tribe-settings-form #tribe-field-stylesheetOption input{margin-left:-20px;margin-right:8px}.tribe-settings-form #tribe-field-stylesheetOption p.description{color:#999}#modern-tribe-info{-khtml-border-radius:4px;background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:8px 20px 12px}#modern-tribe-info img{height:18px;margin:10px 0;width:250px}#modern-tribe-info ul{list-style:disc;margin-left:20px}#modern-tribe-info ul ul{list-style:circle}.tribe-field-textarea.tribe-size-small textarea{height:60px;width:180px}.tribe-field-textarea.tribe-size-medium textarea{height:80px;width:300px}.tribe-field-textarea.tribe-size-large textarea{height:120px;width:450px}.tribe-field-license_key.tribe-size-small input,.tribe-field-text.tribe-size-small input{width:50px}.tribe-field-license_key.tribe-size-medium input,.tribe-field-text.tribe-size-medium input{width:225px}.tribe-field-license_key.tribe-size-large input,.tribe-field-text.tribe-size-large input{width:450px}.tribe-field-dropdown.tribe-size-small select{width:100px}.tribe-field-dropdown.tribe-size-medium select{width:300px}.tribe-field-dropdown.tribe-size-large select{width:450px}.tribe-field-dropdown_chosen.tribe-size-small select{width:100px}.tribe-field-dropdown_chosen.tribe-size-medium select{width:200px}.tribe-field-dropdown_chosen.tribe-size-large select{width:300px}.ajax-loading-license,.invalid-key,.valid-key{display:none;margin:0 5px}.ajax-loading-license{position:relative;top:5px}.key-validity{display:inline-block}.invalid-key{color:red}.valid-key{color:green}.valid-key.service-msg{color:#b72}#additional-field-table{margin-bottom:20px}.tribe-admin-box-left{float:left;width:20%}.tribe-admin-box-left,.tribe-admin-box-right{-khtml-border-radius:4px;background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:0 20px 15px}.tribe-admin-box-right{float:right;width:68%}.ajax-loader{float:right;margin:10px}.tribe-arrangeable-item{border:1px solid #d3d3d3;border-radius:6px}.tribe-arrangeable-item .ui-state-default{border:none}.tribe-arrangeable-item-top{padding:6px}.tribe-arrangeable-item-top:hover{cursor:move}.tribe-arrangeable-action{float:right}.tribe-arrangeable-child{background-color:#f9f9f9;border-top:1px solid #d3d3d3;display:none;padding:25px}.tribe-arrangeable-child label{display:block;margin:0 0 7px}.tribe_events_active_filter_type_options{margin:10px 0}.tribe_events_active_filter_type_options label{margin:7px 0}.tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection{margin-bottom:18px}#event_organizer td small,.OrganizerInfo td small{display:block;margin:0;max-width:250px}#event_organizer .organizer-email,.OrganizerInfo .organizer-email{vertical-align:top}.tribe-table-field-label{max-width:100%;width:200px}#tribe-help-general,#tribe-help-sidebar{float:left;margin-top:20px}#tribe-help-general p{margin-left:15px}#tribe-help-general ul{list-style-type:square}#tribe-help-general ol,#tribe-help-general ul{margin-bottom:20px;margin-left:35px}#tribe-help-general h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}#tribe-help-general h3~h3{margin-top:2.25em}#tribe-help-general h3+p{margin:0 0 20px;padding-left:12px}#tribe-help-general{width:65%}.tribe-help-section{padding-bottom:10px}.tribe-section-type-box{-khtml-border-radius:4px;background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;padding:8px 20px 12px}.tribe-section-type-box img{height:auto;margin:10px 0;max-width:300px}.tribe-section-type-box ul{list-style:disc;margin-left:20px}.tribe-section-type-box ul ul{list-style:circle}#tribe-log-controls{padding-bottom:16px;padding-bottom:1rem;padding-left:12px}#tribe-log-controls>div{display:inline-block;padding-right:16px;padding-right:1rem}#tribe-log-controls .working{opacity:1;-webkit-transition:opacity .2s;transition:opacity .2s}#tribe-log-controls .working.hidden{opacity:0;-webkit-transition:opacity .2s;transition:opacity .2s}#tribe-log-viewer,#tribe-system-info dl.support-stats,.template-updates-wrapper{background:#000;border-radius:2px;color:#888;max-height:400px;overflow:scroll;padding:10px}#tribe-system-info dl.support-stats dt,.template-updates-wrapper dt{clear:both;float:left;font-weight:700;text-transform:uppercase;width:25%}#tribe-system-info dl.support-stats dd,.template-updates-wrapper dd{margin-left:25%;padding-left:10px}.template-updates-wrapper p{margin-top:0}#tribe-help-sidebar{margin:20px 0 0 3%;max-width:225px;width:32%}.tribe-help-plugin-info{border:1px solid #ccc;padding:0 12px 12px}.tribe-help-plugin-info dd,.tribe-help-plugin-info dt{display:inline;margin:0}.tribe-help-plugin-info dt{font-weight:700}.tribe-help-plugin-info dd:after{content:'';display:block;height:.4em}.tribe-help-plugin-info dd:last-child:after{height:0}.tribe-help-plugin-info+.tribe-help-plugin-info{margin-top:20px}.tribe-help-plugin-info>div{line-height:2em}.tribe-help-plugin-info .star-rating{display:inline-block;margin-left:3px;position:relative;top:-2px}.tribe-help-plugin-info .tribe-list-addons{color:#21a6cb;font-size:24px;list-style:circle inside;margin-bottom:10px;margin-top:10px;padding-left:4px}.tribe-help-plugin-info .tribe-list-addons a{font-size:13px;left:-5px;position:relative;top:-5px}.tribe-help-plugin-info .tribe-list-addons .tribe-active-addon{list-style:disc inside}.ui-widget-overlay{background:#666;filter:Alpha(Opacity=50);opacity:.5}.ui-widget-shadow{background:#000;-webkit-border-radius:5px;-moz-border-radius:5px;filter:Alpha(Opacity=20);margin:-5px 0 0 -5px;opacity:.2;padding:5px}.ui-resizable{position:relative}.ui-resizable-handle{display:block;font-size:.1px;position:absolute;z-index:3}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;left:0;top:-5px;width:100%}.ui-resizable-s{bottom:-5px;cursor:s-resize;height:7px;left:0;width:100%}.ui-resizable-e{cursor:e-resize;height:100%;right:-5px;top:0;width:7px}.ui-resizable-w{cursor:w-resize;height:100%;left:-5px;top:0;width:7px}.ui-resizable-se{bottom:1px;cursor:se-resize;height:12px;right:1px;width:12px}.ui-resizable-sw{bottom:-5px;cursor:sw-resize;height:9px;left:-5px;width:9px}.ui-resizable-nw{cursor:nw-resize;height:9px;left:-5px;top:-5px;width:9px}.ui-resizable-ne{cursor:ne-resize;height:9px;right:-5px;top:-5px;width:9px}.ui-dialog{padding:.2em;position:relative;width:375px}.ui-dialog .ui-dialog-titlebar{padding:.5em .3em .3em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0 .2em}.ui-dialog .ui-dialog-titlebar-close{height:18px;margin:-10px 0 0;padding:1px;position:absolute;right:.3em;top:50%;width:19px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin-left:-8px;margin-top:-8px}.ui-dialog .ui-dialog-titlebar-close:focus,.ui-dialog .ui-dialog-titlebar-close:hover{padding:0}.ui-dialog .ui-dialog-content{background:none;border:0;overflow:auto;padding:.5em 1em;zoom:1}.ui-dialog .ui-dialog-buttonpane{background-image:none;border-width:1px 0 0;margin:.5em 0 0;padding:.3em 1em .5em!important;text-align:right}.ui-dialog .ui-dialog-buttonpane button{cursor:pointer;line-height:1.4em;margin:.5em .4em!important;overflow:visible;padding:.2em .6em .3em;text-shadow:none;width:auto}.ui-dialog .ui-resizable-se{bottom:3px;height:14px;right:3px;width:14px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:none!important;text-align:center}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button .ui-button-text{display:block;line-height:1.4}.ui-datepicker{font-size:8pt}#ui-datepicker-div{display:none}#tribe-loading{background:#fff;background:hsla(0,0%,100%,.8);display:none;height:100%;left:0;position:absolute;top:0;-webkit-transition:all 1s linear;transition:all 1s linear;webkit-transition:all 1s linear;width:100%;z-index:2}#tribe-loading span{background:url(../images/tribe-loading.gif) 0 0 no-repeat;background-size:32px 32px;height:32px;left:50%;margin:-16px 0 0 -16px;position:absolute;top:50%;width:32px}.tribe_update_page,.tribe_welcome_page{max-width:1000px}.tribe-half-column{float:left;margin-bottom:30px;margin-right:5%;width:45%}.tribe-row:after,.tribe-row:before{content:'';display:table}.tribe-row,.tribe-row:after{clear:both}.tribe-row .tribe-half-column:last-child{margin-right:0;width:50%}.tribe_update_page h2,.tribe_welcome_page h2{font-size:30px;line-height:1.2;margin-bottom:20px}.tribe_update_page h3,.tribe_welcome_page h3{font-size:24px;font-weight:400;line-height:24px;margin-top:0}.tribe_update_page h4,.tribe_welcome_page h4{font-size:18px;font-weight:600;line-height:18px;margin:0}.tribe_update_page p,.tribe_welcome_page p{font-size:14px}p.tribe-welcome-message{font-size:20px;font-weight:400}.tribe_update_page h2:before,.tribe_welcome_page h2:before{content:'\f145';font-family:dashicons;font-size:34px;line-height:1;margin-right:5px;position:relative;top:5px}.tribe-welcome-video-wrapper{height:0;margin-bottom:40px;padding-bottom:56.25%;padding-top:25px;position:relative}.tribe-welcome-video-wrapper iframe{height:100%;left:0;position:absolute;top:0;width:100%}a.tribe-rating-link{text-decoration:none}.tribe-update-links,.tribe-welcome-links{margin-top:30px}.tribe_update_page li:before,.tribe_welcome_page li:before{content:'\2022';padding-right:3px}.tribe_update_page .rss-widget{margin:1em 0}.tribe_update_page a.rsswidget{font-size:14px;font-weight:400;line-height:1}.tribe_update_page .rss-widget li:before{display:none}.tribe-update-bar{display:inline-block}.tribe-update-bar .progress{border:1px solid #ccc;float:left;margin-right:16px;margin-right:1rem;padding:1px;width:288px;width:18rem}.tribe-update-bar .progress .bar{background:#ffba00;height:16px;height:1rem;width:1%;background:#7ad03a}.bumpdown{background:#f1f1f1;margin:16px 0;margin:1rem 0;padding:16px 24px 16px 16px;padding:1rem 1.5rem 1rem 1rem;position:relative}#poststuff .bumpdown h1,#poststuff .bumpdown h2,#poststuff .bumpdown h3,#poststuff .bumpdown h4,.bumpdown h1,.bumpdown h2,.bumpdown h3,.bumpdown h4{padding-left:0;padding-top:0}.bumpdown-arrow{display:none}.bumpdown-close{color:#686868;cursor:pointer;position:absolute;right:8px;right:.5rem;top:8px;top:.5rem;z-index:1}.bumpdown-trigger .target{color:#0074a2}.ui-front{z-index:4}@media only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min--moz-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){#tribe-loading span{background-image:url(../images/tribe-loading@2x.gif)}}@media screen and (max-width:782px){.tribe-half-column,.tribe-row .tribe-half-column:last-child{margin:0 0 20px;width:100%}input[type=email]{width:100%}}@media screen and (max-width:782px){.events-cal .subsubsub{float:none}.events-cal .search-box{width:98%}.events-cal #search-submit{width:100%}.events-cal .tablenav.top{display:none}}
common/src/resources/js/admin-date-preview.js CHANGED
@@ -1,34 +1,34 @@
1
- /**
2
- * Provides live preview facilities for the event date format fields, akin
3
- * to (and using the same ajax mechanism as) the date format preview in WP's
4
- * general settings screen.
5
- */
6
- jQuery( document ).ready( function( $ ) {
7
- // Whenever the input field for a date format changes, update the matching
8
- // live preview area
9
- $( ".live-date-preview" ).siblings( "input" ).change( function() {
10
- var $format_field = $( this );
11
- var new_format = $format_field.val();
12
- var $preview_field = $format_field.siblings( ".live-date-preview" );
13
-
14
- /**
15
- * Update the preview field when we get our response back from WP.
16
- */
17
- var show_update = function( preview_text ) {
18
- preview_text = $( "<div/>" ).html( preview_text ).text(); // Escaping!
19
- $preview_field.html( preview_text );
20
- }
21
-
22
- // Before making the request, show the spinner (this should naturally be "wiped"
23
- // when the response is rendered)
24
- $preview_field.append( "<span class='spinner'></span>" );
25
- $preview_field.find( ".spinner" ).css( "visibility", "visible" );
26
-
27
- var request = {
28
- action: "date_format",
29
- date: new_format
30
- }
31
-
32
- $.post( ajaxurl, request, show_update, "text" );
33
- } );
34
  } );
1
+ /**
2
+ * Provides live preview facilities for the event date format fields, akin
3
+ * to (and using the same ajax mechanism as) the date format preview in WP's
4
+ * general settings screen.
5
+ */
6
+ jQuery( document ).ready( function( $ ) {
7
+ // Whenever the input field for a date format changes, update the matching
8
+ // live preview area
9
+ $( ".live-date-preview" ).siblings( "input" ).change( function() {
10
+ var $format_field = $( this );
11
+ var new_format = $format_field.val();
12
+ var $preview_field = $format_field.siblings( ".live-date-preview" );
13
+
14
+ /**
15
+ * Update the preview field when we get our response back from WP.
16
+ */
17
+ var show_update = function( preview_text ) {
18
+ preview_text = $( "<div/>" ).html( preview_text ).text(); // Escaping!
19
+ $preview_field.html( preview_text );
20
+ }
21
+
22
+ // Before making the request, show the spinner (this should naturally be "wiped"
23
+ // when the response is rendered)
24
+ $preview_field.append( "<span class='spinner'></span>" );
25
+ $preview_field.find( ".spinner" ).css( "visibility", "visible" );
26
+
27
+ var request = {
28
+ action: "date_format",
29
+ date: new_format
30
+ }
31
+
32
+ $.post( ajaxurl, request, show_update, "text" );
33
+ } );
34
  } );
common/src/resources/js/admin-log-controls.js CHANGED
@@ -1,171 +1,171 @@
1
- var tribe_logger_admin = tribe_logger_admin || {};
2
- var tribe_logger_data = tribe_logger_data || {};
3
-
4
- ( function( $, obj ) {
5
- var working = false;
6
- var current_view = '';
7
- var current_engine = '';
8
- var view_changed = false;
9
- var $controls = $( '#tribe-log-controls' );
10
- var $options = $controls.find( 'select' );
11
- var $spinner = $controls.find( '.working' );
12
- var $viewer = $( '#tribe-log-viewer' );
13
- var $download_link = $( 'a.download_log' );
14
-
15
- /**
16
- * Update the log view based on changes to the various selectors.
17
- */
18
- function update() {
19
- // If an update is already in progress let's wait until that job completes
20
- if ( working ) {
21
- return;
22
- }
23
-
24
- detect_view_change();
25
- freeze();
26
- request();
27
- }
28
-
29
- /**
30
- * Communicate any changes back to the server so we can obtain fresh log data
31
- * to display to the user.
32
- */
33
- function request() {
34
- var data = {
35
- 'action': 'tribe_logging_controls',
36
- 'check': tribe_logger_data.check,
37
- 'log-level': $( '#log-level' ).find( ':selected' ).attr( 'name' ),
38
- 'log-engine': $( '#log-engine' ).find( ':selected' ).attr( 'name' )
39
- };
40
-
41
- if ( view_changed ) {
42
- data['log-view'] = current_view;
43
- }
44
-
45
- $.ajax( ajaxurl, {
46
- 'method': 'POST',
47
- 'success': on_success,
48
- 'error': on_error,
49
- 'dataType': 'json',
50
- 'data': data
51
- } );
52
- }
53
-
54
- /**
55
- * Unfreeze the controls (following an update) and refresh on-screen data as needed.
56
- *
57
- * @param data
58
- */
59
- function on_success( data ) {
60
- unfreeze();
61
-
62
- if ( $.isArray( data.data.entries ) ) {
63
- $viewer.html( to_table( data.data.entries ) );
64
- update_download_link();
65
- }
66
- }
67
-
68
- /**
69
- * Converts data_array, which is expected to be an array of
70
- * arrays, into an HTML table.
71
- */
72
- function to_table( data_array ) {
73
- var html = '<table>';
74
-
75
- for ( var row in data_array ) {
76
- html += '<tr>';
77
-
78
- for ( var cell in data_array[row] ) {
79
- html += '<td>' + data_array[row][cell] + '</td>';
80
- }
81
-
82
- html += '</tr>';
83
- }
84
-
85
- return html + '</table>';
86
- }
87
-
88
- /**
89
- * Add, append or update the log download link so it points to the
90
- * currently selected log file.
91
- */
92
- function update_download_link() {
93
- var url = $download_link.attr( 'href' );
94
- var log = encodeURI( get_current_view() );
95
- var matches = url.match(/&log=([a-z0-9\-]+)/i);
96
-
97
- // Update or add the log parameter
98
- if ( $.isArray( matches ) && 2 === matches.length ) {
99
- url = url.replace( matches[0], '&log=' + log );
100
- } else if ( url.indexOf( '?' ) ) {
101
- url = url + '&log=' + log;
102
- } else {
103
- url = url + '?log=' + log;
104
- }
105
-
106
- $download_link.attr( 'href', url );
107
- }
108
-
109
- /**
110
- * If our request back to the server failed, unfreeze the controls so
111
- * we can try again.
112
- *
113
- * @todo in a future iteration we should add substantive handling for this scenario
114
- */
115
- function on_error() {
116
- unfreeze();
117
- }
118
-
119
- /**
120
- * Freeze/disable the controls and show the spinner.
121
- */
122
- function freeze() {
123
- working = true;
124
- $options.prop( 'disabled', true );
125
- $spinner.removeClass( 'hidden' );
126
- }
127
-
128
- /**
129
- * Unfreeze/enable the controls and hide the spinner.
130
- */
131
- function unfreeze() {
132
- working = false;
133
- $options.prop( 'disabled', false );
134
- $spinner.addClass( 'hidden' );
135
- }
136
-
137
- /**
138
- * Check if a change in controls constituting a change of view has occured.
139
- *
140
- * This could be because the user changed logging engine or because they picked
141
- * a different log to peruse; a change in logging level on the other hand does
142
- * not count.
143
- */
144
- function detect_view_change() {
145
- var new_view = get_current_view();
146
- var new_engine = get_current_engine();
147
-
148
- if ( new_view !== current_view || new_engine !== current_engine ) {
149
- view_changed = true;
150
- current_view = new_view;
151
- current_engine = new_engine;
152
- } else {
153
- view_changed = false;
154
- }
155
- }
156
-
157
- function get_current_view() {
158
- return $( '#log-selector' ).find( ':selected' ).attr( 'name' );
159
- }
160
-
161
- function get_current_engine() {
162
- return $( '#log-engine' ).find( ':selected' ).attr( 'name' );
163
- }
164
-
165
- // Setup
166
- current_view = get_current_view();
167
- current_engine = get_current_engine();
168
-
169
- update_download_link();
170
- $options.change( update );
171
  } )( jQuery, tribe_logger_admin );
1
+ var tribe_logger_admin = tribe_logger_admin || {};
2
+ var tribe_logger_data = tribe_logger_data || {};
3
+
4
+ ( function( $, obj ) {
5
+ var working = false;
6
+ var current_view = '';
7
+ var current_engine = '';
8
+ var view_changed = false;
9
+ var $controls = $( '#tribe-log-controls' );
10
+ var $options = $controls.find( 'select' );
11
+ var $spinner = $controls.find( '.working' );
12
+ var $viewer = $( '#tribe-log-viewer' );
13
+ var $download_link = $( 'a.download_log' );
14
+
15
+ /**
16
+ * Update the log view based on changes to the various selectors.
17
+ */
18
+ function update() {
19
+ // If an update is already in progress let's wait until that job completes
20
+ if ( working ) {
21
+ return;
22
+ }
23
+
24
+ detect_view_change();
25
+ freeze();
26
+ request();
27
+ }
28
+
29
+ /**
30
+ * Communicate any changes back to the server so we can obtain fresh log data
31
+ * to display to the user.
32
+ */
33
+ function request() {
34
+ var data = {
35
+ 'action': 'tribe_logging_controls',
36
+ 'check': tribe_logger_data.check,
37
+ 'log-level': $( '#log-level' ).find( ':selected' ).attr( 'name' ),
38
+ 'log-engine': $( '#log-engine' ).find( ':selected' ).attr( 'name' )
39
+ };
40
+
41
+ if ( view_changed ) {
42
+ data['log-view'] = current_view;
43
+ }
44
+
45
+ $.ajax( ajaxurl, {
46
+ 'method': 'POST',
47
+ 'success': on_success,
48
+ 'error': on_error,
49
+ 'dataType': 'json',
50
+ 'data': data
51
+ } );
52
+ }
53
+
54
+ /**
55
+ * Unfreeze the controls (following an update) and refresh on-screen data as needed.
56
+ *
57
+ * @param data
58
+ */
59
+ function on_success( data ) {
60
+ unfreeze();
61
+
62
+ if ( $.isArray( data.data.entries ) ) {
63
+ $viewer.html( to_table( data.data.entries ) );
64
+ update_download_link();
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Converts data_array, which is expected to be an array of
70
+ * arrays, into an HTML table.
71
+ */
72
+ function to_table( data_array ) {
73
+ var html = '<table>';
74
+
75
+ for ( var row in data_array ) {
76
+ html += '<tr>';
77
+
78
+ for ( var cell in data_array[row] ) {
79
+ html += '<td>' + data_array[row][cell] + '</td>';
80
+ }
81
+
82
+ html += '</tr>';
83
+ }
84
+
85
+ return html + '</table>';
86
+ }
87
+
88
+ /**
89
+ * Add, append or update the log download link so it points to the
90
+ * currently selected log file.
91
+ */
92
+ function update_download_link() {
93
+ var url = $download_link.attr( 'href' );
94
+ var log = encodeURI( get_current_view() );
95
+ var matches = url.match(/&log=([a-z0-9\-]+)/i);
96
+
97
+ // Update or add the log parameter
98
+ if ( $.isArray( matches ) && 2 === matches.length ) {
99
+ url = url.replace( matches[0], '&log=' + log );
100
+ } else if ( url.indexOf( '?' ) ) {
101
+ url = url + '&log=' + log;
102
+ } else {
103
+ url = url + '?log=' + log;
104
+ }
105
+
106
+ $download_link.attr( 'href', url );
107
+ }
108
+
109
+ /**
110
+ * If our request back to the server failed, unfreeze the controls so
111
+ * we can try again.
112
+ *
113
+ * @todo in a future iteration we should add substantive handling for this scenario
114
+ */
115
+ function on_error() {
116
+ unfreeze();
117
+ }
118
+
119
+ /**
120
+ * Freeze/disable the controls and show the spinner.
121
+ */
122
+ function freeze() {
123
+ working = true;
124
+ $options.prop( 'disabled', true );
125
+ $spinner.removeClass( 'hidden' );
126
+ }
127
+
128
+ /**
129
+ * Unfreeze/enable the controls and hide the spinner.
130
+ */
131
+ function unfreeze() {
132
+ working = false;
133
+ $options.prop( 'disabled', false );
134
+ $spinner.addClass( 'hidden' );
135
+ }
136
+
137
+ /**
138
+ * Check if a change in controls constituting a change of view has occured.
139
+ *
140
+ * This could be because the user changed logging engine or because they picked
141
+ * a different log to peruse; a change in logging level on the other hand does
142
+ * not count.
143
+ */
144
+ function detect_view_change() {
145
+ var new_view = get_current_view();
146
+ var new_engine = get_current_engine();
147
+
148
+ if ( new_view !== current_view || new_engine !== current_engine ) {
149
+ view_changed = true;
150
+ current_view = new_view;
151
+ current_engine = new_engine;
152
+ } else {
153
+ view_changed = false;
154
+ }
155
+ }
156
+
157
+ function get_current_view() {
158
+ return $( '#log-selector' ).find( ':selected' ).attr( 'name' );
159
+ }
160
+
161
+ function get_current_engine() {
162
+ return $( '#log-engine' ).find( ':selected' ).attr( 'name' );
163
+ }
164
+
165
+ // Setup
166
+ current_view = get_current_view();
167
+ current_engine = get_current_engine();
168
+
169
+ update_download_link();
170
+ $options.change( update );
171
  } )( jQuery, tribe_logger_admin );
common/src/resources/js/app-shop.js CHANGED
@@ -1,10 +1,10 @@
1
- jQuery( document ).ready( function() {
2
-
3
- var maxHeight = 0;
4
- jQuery( "div.tribe-addon .caption" ).each( function() {
5
- var h = jQuery( this ).height();
6
- maxHeight = h > maxHeight ? h : maxHeight;
7
- } );
8
-
9
- jQuery( "div.tribe-addon:not(.first) .caption" ).css( 'height', maxHeight );
10
  } );
1
+ jQuery( document ).ready( function() {
2
+
3
+ var maxHeight = 0;
4
+ jQuery( "div.tribe-addon .caption" ).each( function() {
5
+ var h = jQuery( this ).height();
6
+ maxHeight = h > maxHeight ? h : maxHeight;
7
+ } );
8
+
9
+ jQuery( "div.tribe-addon:not(.first) .caption" ).css( 'height', maxHeight );
10
  } );
common/src/resources/js/inline-bumpdown.js CHANGED
@@ -1,103 +1,103 @@
1
- (function( $ ) {
2
- 'use strict';
3
- var methods = {};
4
-
5
- methods.clicked = false;
6
- methods.opening = false;
7
-
8
- methods.close_bumpdown = function( $bumpdown ) {
9
- if ( ! $bumpdown.is( ':visible' ) ) {
10
- return;
11
- }//end if
12
-
13
- $bumpdown.slideUp( 'fast' );
14
- };
15
-
16
- methods.open_bumpdown = function( $bumpdown ) {
17
- if ( $bumpdown.is( ':visible' ) ) {
18
- return;
19
- }//end if
20
-
21
- methods.opening = true;
22
-
23
- $bumpdown.slideDown( 'fast', function() {
24
- methods.opening = false;
25
- });
26
- };
27
-
28
- $.fn.bumpdown = function() {
29
- return this.each( function() {
30
- var $el = $( this );
31
- var the_id = $el.attr( 'id' );
32
- var $trigger_source = $el.find( '.target' );
33
-
34
- $el.addClass( 'bumpdown-trigger' );
35
-
36
- // get the first block-level parent
37
- var $parent = $el.parents().filter( function() {
38
- return 'block' === $( this ).css( 'display' );
39
- }).first();
40
-
41
- if ( ! $trigger_source.length ) {
42
- $trigger_source = $el;
43
- }//end if
44
-
45
- if ( ! the_id ) {
46
- $.error( 'bumpdowns need an id' );
47
- }//end if
48
-
49
- var bumpdown_selector = '[data-trigger="' + the_id + '"]';
50
-
51
- var $bumpdown = $( bumpdown_selector );
52
-
53
- $bumpdown.addClass( 'bumpdown' );
54
-
55
- var source = {};
56
-
57
- source.offset = $trigger_source.offset();
58
- source.width = $trigger_source.outerWidth();
59
- source.halfway = ( source.offset.left - $parent.offset().left ) + Math.round( source.width / 2 ) - 16;
60
-
61
- $bumpdown.prepend( '<a class="bumpdown-close" title="Close"><i class="dashicons dashicons-no"></i></a>' );
62
- $bumpdown.prepend( '<span class="bumpdown-arrow" style="left: ' + source.halfway + 'px;"></span>' );
63
-
64
- $( document ).on( 'click', bumpdown_selector, function() {
65
- if ( $bumpdown.is( ':visible' ) && ! methods.opening ) {
66
- methods.clicked = true;
67
- }//end if
68
- });
69
-
70
- $( document ).on( 'click', function() {
71
- if ( ! methods.clicked && ! methods.opening && $bumpdown.is( ':visible' ) ) {
72
- methods.close_bumpdown( $bumpdown );
73
- }//end if
74
-
75
- methods.clicked = false;
76
- });
77
-
78
- $el.on( 'mouseover', function() {
79
- $el.doTimeout( the_id, 300, function() {
80
- if ( ! $bumpdown.is( ':visible' ) ) {
81
- methods.open_bumpdown( $bumpdown );
82
- }//end if
83
- });
84
- });
85
-
86
- $el.on( 'click', function( e ) {
87
- e.preventDefault();
88
-
89
- if ( ! $bumpdown.is( ':visible' ) ) {
90
- e.stopPropagation();
91
- methods.open_bumpdown( $bumpdown );
92
- }//end if
93
- });
94
-
95
- $bumpdown.find( '.bumpdown-close' ).on( 'click', function( e ) {
96
- e.preventDefault();
97
- e.stopPropagation();
98
-
99
- methods.close_bumpdown( $bumpdown );
100
- });
101
- });
102
- };
103
- }( jQuery ));
1
+ (function( $ ) {
2
+ 'use strict';
3
+ var methods = {};
4
+
5
+ methods.clicked = false;
6
+ methods.opening = false;
7
+
8
+ methods.close_bumpdown = function( $bumpdown ) {
9
+ if ( ! $bumpdown.is( ':visible' ) ) {
10
+ return;
11
+ }//end if
12
+
13
+ $bumpdown.slideUp( 'fast' );
14
+ };
15
+
16
+ methods.open_bumpdown = function( $bumpdown ) {
17
+ if ( $bumpdown.is( ':visible' ) ) {
18
+ return;
19
+ }//end if
20
+
21
+ methods.opening = true;
22
+
23
+ $bumpdown.slideDown( 'fast', function() {
24
+ methods.opening = false;
25
+ });
26
+ };
27
+
28
+ $.fn.bumpdown = function() {
29
+ return this.each( function() {
30
+ var $el = $( this );
31
+ var the_id = $el.attr( 'id' );
32
+ var $trigger_source = $el.find( '.target' );
33
+
34
+ $el.addClass( 'bumpdown-trigger' );
35
+
36
+ // get the first block-level parent
37
+ var $parent = $el.parents().filter( function() {
38
+ return 'block' === $( this ).css( 'display' );
39
+ }).first();
40
+
41
+ if ( ! $trigger_source.length ) {
42
+ $trigger_source = $el;
43
+ }//end if
44
+
45
+ if ( ! the_id ) {
46
+ $.error( 'bumpdowns need an id' );
47
+ }//end if
48
+
49
+ var bumpdown_selector = '[data-trigger="' + the_id + '"]';
50
+
51
+ var $bumpdown = $( bumpdown_selector );
52
+
53
+ $bumpdown.addClass( 'bumpdown' );
54
+
55
+ var source = {};
56
+
57
+ source.offset = $trigger_source.offset();
58
+ source.width = $trigger_source.outerWidth();
59
+ source.halfway = ( source.offset.left - $parent.offset().left ) + Math.round( source.width / 2 ) - 16;
60
+
61
+ $bumpdown.prepend( '<a class="bumpdown-close" title="Close"><i class="dashicons dashicons-no"></i></a>' );
62
+ $bumpdown.prepend( '<span class="bumpdown-arrow" style="left: ' + source.halfway + 'px;"></span>' );
63
+
64
+ $( document ).on( 'click', bumpdown_selector, function() {
65
+ if ( $bumpdown.is( ':visible' ) && ! methods.opening ) {
66
+ methods.clicked = true;
67
+ }//end if
68
+ });
69
+
70
+ $( document ).on( 'click', function() {
71
+ if ( ! methods.clicked && ! methods.opening && $bumpdown.is( ':visible' ) ) {
72
+ methods.close_bumpdown( $bumpdown );
73
+ }//end if
74
+
75
+ methods.clicked = false;
76
+ });
77
+
78
+ $el.on( 'mouseover', function() {
79
+ $el.doTimeout( the_id, 300, function() {
80
+ if ( ! $bumpdown.is( ':visible' ) ) {
81
+ methods.open_bumpdown( $bumpdown );
82
+ }//end if
83
+ });
84
+ });
85
+
86
+ $el.on( 'click', function( e ) {
87
+ e.preventDefault();
88
+
89
+ if ( ! $bumpdown.is( ':visible' ) ) {
90
+ e.stopPropagation();
91
+ methods.open_bumpdown( $bumpdown );
92
+ }//end if
93
+ });
94
+
95
+ $bumpdown.find( '.bumpdown-close' ).on( 'click', function( e ) {
96
+ e.preventDefault();
97
+ e.stopPropagation();
98
+
99
+ methods.close_bumpdown( $bumpdown );
100
+ });
101
+ });
102
+ };
103
+ }( jQuery ));
common/src/resources/js/jquery.ba-dotimeout.js CHANGED
@@ -1,285 +1,285 @@
1
- /*!
2
- * jQuery doTimeout: Like setTimeout, but better! - v1.0 - 3/3/2010
3
- * http://benalman.com/projects/jquery-dotimeout-plugin/
4
- *
5
- * Copyright (c) 2010 "Cowboy" Ben Alman
6
- * Dual licensed under the MIT and GPL licenses.
7
- * http://benalman.com/about/license/
8
- */
9
-
10
- // Script: jQuery doTimeout: Like setTimeout, but better!
11
- //
12
- // *Version: 1.0, Last updated: 3/3/2010*
13
- //
14
- // Project Home - http://benalman.com/projects/jquery-dotimeout-plugin/
15
- // GitHub - http://github.com/cowboy/jquery-dotimeout/
16
- // Source - http://github.com/cowboy/jquery-dotimeout/raw/master/jquery.ba-dotimeout.js
17
- // (Minified) - http://github.com/cowboy/jquery-dotimeout/raw/master/jquery.ba-dotimeout.min.js (1.0kb)
18
- //
19
- // About: License
20
- //
21
- // Copyright (c) 2010 "Cowboy" Ben Alman,
22
- // Dual licensed under the MIT and GPL licenses.
23
- // http://benalman.com/about/license/
24
- //
25
- // About: Examples
26
- //
27
- // These working examples, complete with fully commented code, illustrate a few
28
- // ways in which this plugin can be used.
29
- //
30
- // Debouncing - http://benalman.com/code/projects/jquery-dotimeout/examples/debouncing/
31
- // Delays, Polling - http://benalman.com/code/projects/jquery-dotimeout/examples/delay-poll/
32
- // Hover Intent - http://benalman.com/code/projects/jquery-dotimeout/examples/hoverintent/
33
- //
34
- // About: Support and Testing
35
- //
36
- // Information about what version or versions of jQuery this plugin has been
37
- // tested with, what browsers it has been tested in, and where the unit tests
38
- // reside (so you can test it yourself).
39
- //
40
- // jQuery Versions - 1.3.2, 1.4.2
41
- // Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1.
42
- // Unit Tests - http://benalman.com/code/projects/jquery-dotimeout/unit/
43
- //
44
- // About: Release History
45
- //
46
- // 1.0 - (3/3/2010) Callback can now be a string, in which case it will call
47
- // the appropriate $.method or $.fn.method, depending on where .doTimeout
48
- // was called. Callback must now return `true` (not just a truthy value)
49
- // to poll.
50
- // 0.4 - (7/15/2009) Made the "id" argument optional, some other minor tweaks
51
- // 0.3 - (6/25/2009) Initial release
52
-
53
- (function($){
54
- '$:nomunge'; // Used by YUI compressor.
55
-
56
- var cache = {},
57
-
58
- // Reused internal string.
59
- doTimeout = 'doTimeout',
60
-
61
- // A convenient shortcut.
62
- aps = Array.prototype.slice;
63
-
64
- // Method: jQuery.doTimeout
65
- //
66
- // Initialize, cancel, or force execution of a callback after a delay.
67
- //
68
- // If delay and callback are specified, a doTimeout is initialized. The
69
- // callback will execute, asynchronously, after the delay. If an id is
70
- // specified, this doTimeout will override and cancel any existing doTimeout
71
- // with the same id. Any additional arguments will be passed into callback
72
- // when it is executed.
73
- //
74
- // If the callback returns true, the doTimeout loop will execute again, after
75
- // the delay, creating a polling loop until the callback returns a non-true
76
- // value.
77
- //
78
- // Note that if an id is not passed as the first argument, this doTimeout will
79
- // NOT be able to be manually canceled or forced. (for debouncing, be sure to
80
- // specify an id).
81
- //
82
- // If id is specified, but delay and callback are not, the doTimeout will be
83
- // canceled without executing the callback. If force_mode is specified, the
84
- // callback will be executed, synchronously, but will only be allowed to
85
- // continue a polling loop if force_mode is true (provided the callback
86
- // returns true, of course). If force_mode is false, no polling loop will
87
- // continue, even if the callback returns true.
88
- //
89
- // Usage:
90
- //
91
- // > jQuery.doTimeout( [ id, ] delay, callback [, arg ... ] );
92
- // > jQuery.doTimeout( id [, force_mode ] );
93
- //
94
- // Arguments:
95
- //
96
- // id - (String) An optional unique identifier for this doTimeout. If id is
97
- // not specified, the doTimeout will NOT be able to be manually canceled or
98
- // forced.
99
- // delay - (Number) A zero-or-greater delay in milliseconds after which
100
- // callback will be executed.
101
- // callback - (Function) A function to be executed after delay milliseconds.
102
- // callback - (String) A jQuery method to be executed after delay
103
- // milliseconds. This method will only poll if it explicitly returns
104
- // true.
105
- // force_mode - (Boolean) If true, execute that id's doTimeout callback
106
- // immediately and synchronously, continuing any callback return-true
107
- // polling loop. If false, execute the callback immediately and
108
- // synchronously but do NOT continue a callback return-true polling loop.
109
- // If omitted, cancel that id's doTimeout.
110
- //
111
- // Returns:
112
- //
113
- // If force_mode is true, false or undefined and there is a
114
- // yet-to-be-executed callback to cancel, true is returned, but if no
115
- // callback remains to be executed, undefined is returned.
116
-
117
- $[doTimeout] = function() {
118
- return p_doTimeout.apply( window, [ 0 ].concat( aps.call( arguments ) ) );
119
- };
120
-
121
- // Method: jQuery.fn.doTimeout
122
- //
123
- // Initialize, cancel, or force execution of a callback after a delay.
124
- // Operates like <jQuery.doTimeout>, but the passed callback executes in the
125
- // context of the jQuery collection of elements, and the id is stored as data
126
- // on the first element in that collection.
127
- //
128
- // If delay and callback are specified, a doTimeout is initialized. The
129
- // callback will execute, asynchronously, after the delay. If an id is
130
- // specified, this doTimeout will override and cancel any existing doTimeout
131
- // with the same id. Any additional arguments will be passed into callback
132
- // when it is executed.
133
- //
134
- // If the callback returns true, the doTimeout loop will execute again, after
135
- // the delay, creating a polling loop until the callback returns a non-true
136
- // value.
137
- //
138
- // Note that if an id is not passed as the first argument, this doTimeout will
139
- // NOT be able to be manually canceled or forced (for debouncing, be sure to
140
- // specify an id).
141
- //
142
- // If id is specified, but delay and callback are not, the doTimeout will be
143
- // canceled without executing the callback. If force_mode is specified, the
144
- // callback will be executed, synchronously, but will only be allowed to
145
- // continue a polling loop if force_mode is true (provided the callback
146
- // returns true, of course). If force_mode is false, no polling loop will
147
- // continue, even if the callback returns true.
148
- //
149
- // Usage:
150
- //
151
- // > jQuery('selector').doTimeout( [ id, ] delay, callback [, arg ... ] );
152
- // > jQuery('selector').doTimeout( id [, force_mode ] );
153
- //
154
- // Arguments:
155
- //
156
- // id - (String) An optional unique identifier for this doTimeout, stored as
157
- // jQuery data on the element. If id is not specified, the doTimeout will
158
- // NOT be able to be manually canceled or forced.
159
- // delay - (Number) A zero-or-greater delay in milliseconds after which
160
- // callback will be executed.
161
- // callback - (Function) A function to be executed after delay milliseconds.
162
- // callback - (String) A jQuery.fn method to be executed after delay
163
- // milliseconds. This method will only poll if it explicitly returns
164
- // true (most jQuery.fn methods return a jQuery object, and not `true`,
165
- // which allows them to be chained and prevents polling).
166
- // force_mode - (Boolean) If true, execute that id's doTimeout callback
167
- // immediately and synchronously, continuing any callback return-true
168
- // polling loop. If false, execute the callback immediately and
169
- // synchronously but do NOT continue a callback return-true polling loop.
170
- // If omitted, cancel that id's doTimeout.
171
- //
172
- // Returns:
173
- //
174
- // When creating a <jQuery.fn.doTimeout>, the initial jQuery collection of
175
- // elements is returned. Otherwise, if force_mode is true, false or undefined
176
- // and there is a yet-to-be-executed callback to cancel, true is returned,
177
- // but if no callback remains to be executed, undefined is returned.
178
-
179
- $.fn[doTimeout] = function() {
180
- var args = aps.call( arguments ),
181
- result = p_doTimeout.apply( this, [ doTimeout + args[0] ].concat( args ) );
182
-
183
- return typeof args[0] === 'number' || typeof args[1] === 'number'
184
- ? this
185
- : result;
186
- };
187
-
188
- function p_doTimeout( jquery_data_key ) {
189
- var that = this,
190
- elem,
191
- data = {},
192
-
193
- // Allows the plugin to call a string callback method.
194
- method_base = jquery_data_key ? $.fn : $,
195
-
196
- // Any additional arguments will be passed to the callback.
197
- args = arguments,
198
- slice_args = 4,
199
-
200
- id = args[1],
201
- delay = args[2],
202
- callback = args[3];
203
-
204
- if ( typeof id !== 'string' ) {
205
- slice_args--;
206
-
207
- id = jquery_data_key = 0;
208
- delay = args[1];
209
- callback = args[2];
210
- }
211
-
212
- // If id is passed, store a data reference either as .data on the first
213
- // element in a jQuery collection, or in the internal cache.
214
- if ( jquery_data_key ) { // Note: key is 'doTimeout' + id
215
-
216
- // Get id-object from the first element's data, otherwise initialize it to {}.
217
- elem = that.eq(0);
218
- elem.data( jquery_data_key, data = elem.data( jquery_data_key ) || {} );
219
-
220
- } else if ( id ) {
221
- // Get id-object from the cache, otherwise initialize it to {}.
222
- data = cache[ id ] || ( cache[ id ] = {} );
223
- }
224
-
225
- // Clear any existing timeout for this id.
226
- data.id && clearTimeout( data.id );
227
- delete data.id;
228
-
229
- // Clean up when necessary.
230
- function cleanup() {
231
- if ( jquery_data_key ) {
232
- elem.removeData( jquery_data_key );
233
- } else if ( id ) {
234
- delete cache[ id ];
235
- }
236
- };
237
-
238
- // Yes, there actually is a setTimeout call in here!
239
- function actually_setTimeout() {
240
- data.id = setTimeout( function(){ data.fn(); }, delay );
241
- };
242
-
243
- if ( callback ) {
244
- // A callback (and delay) were specified. Store the callback reference for
245
- // possible later use, and then setTimeout.
246
- data.fn = function( no_polling_loop ) {
247
-
248
- // If the callback value is a string, it is assumed to be the name of a
249
- // method on $ or $.fn depending on where doTimeout was executed.
250
- if ( typeof callback === 'string' ) {
251
- callback = method_base[ callback ];
252
- }
253
-
254
- callback.apply( that, aps.call( args, slice_args ) ) === true && !no_polling_loop
255
-
256
- // Since the callback returned true, and we're not specifically
257
- // canceling a polling loop, do it again!
258
- ? actually_setTimeout()
259
-
260
- // Otherwise, clean up and quit.
261
- : cleanup();
262
- };
263
-
264
- // Set that timeout!
265
- actually_setTimeout();
266
-
267
- } else if ( data.fn ) {
268
- // No callback passed. If force_mode (delay) is true, execute the data.fn
269
- // callback immediately, continuing any callback return-true polling loop.
270
- // If force_mode is false, execute the data.fn callback immediately but do
271
- // NOT continue a callback return-true polling loop. If force_mode is
272
- // undefined, simply clean up. Since data.fn was still defined, whatever
273
- // was supposed to happen hadn't yet, so return true.
274
- delay === undefined ? cleanup() : data.fn( delay === false );
275
- return true;
276
-
277
- } else {
278
- // Since no callback was passed, and data.fn isn't defined, it looks like
279
- // whatever was supposed to happen already did. Clean up and quit!
280
- cleanup();
281
- }
282
-
283
- };
284
-
285
- })(jQuery);
1
+ /*!
2
+ * jQuery doTimeout: Like setTimeout, but better! - v1.0 - 3/3/2010
3
+ * http://benalman.com/projects/jquery-dotimeout-plugin/
4
+ *
5
+ * Copyright (c) 2010 "Cowboy" Ben Alman
6
+ * Dual licensed under the MIT and GPL licenses.
7
+ * http://benalman.com/about/license/
8
+ */
9
+
10
+ // Script: jQuery doTimeout: Like setTimeout, but better!
11
+ //
12
+ // *Version: 1.0, Last updated: 3/3/2010*
13
+ //
14
+ // Project Home - http://benalman.com/projects/jquery-dotimeout-plugin/
15
+ // GitHub - http://github.com/cowboy/jquery-dotimeout/
16
+ // Source - http://github.com/cowboy/jquery-dotimeout/raw/master/jquery.ba-dotimeout.js
17
+ // (Minified) - http://github.com/cowboy/jquery-dotimeout/raw/master/jquery.ba-dotimeout.min.js (1.0kb)
18
+ //
19
+ // About: License
20
+ //
21
+ // Copyright (c) 2010 "Cowboy" Ben Alman,
22
+ // Dual licensed under the MIT and GPL licenses.
23
+ // http://benalman.com/about/license/
24
+ //
25
+ // About: Examples
26
+ //
27
+ // These working examples, complete with fully commented code, illustrate a few
28
+ // ways in which this plugin can be used.
29
+ //
30
+ // Debouncing - http://benalman.com/code/projects/jquery-dotimeout/examples/debouncing/
31
+ // Delays, Polling - http://benalman.com/code/projects/jquery-dotimeout/examples/delay-poll/
32
+ // Hover Intent - http://benalman.com/code/projects/jquery-dotimeout/examples/hoverintent/
33
+ //
34
+ // About: Support and Testing
35
+ //
36
+ // Information about what version or versions of jQuery this plugin has been
37
+ // tested with, what browsers it has been tested in, and where the unit tests
38
+ // reside (so you can test it yourself).
39
+ //
40
+ // jQuery Versions - 1.3.2, 1.4.2
41
+ // Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1.
42
+ // Unit Tests - http://benalman.com/code/projects/jquery-dotimeout/unit/
43
+ //
44
+ // About: Release History
45
+ //
46
+ // 1.0 - (3/3/2010) Callback can now be a string, in which case it will call
47
+ // the appropriate $.method or $.fn.method, depending on where .doTimeout
48
+ // was called. Callback must now return `true` (not just a truthy value)
49
+ // to poll.
50
+ // 0.4 - (7/15/2009) Made the "id" argument optional, some other minor tweaks
51
+ // 0.3 - (6/25/2009) Initial release
52
+
53
+ (function($){
54
+ '$:nomunge'; // Used by YUI compressor.
55
+
56
+ var cache = {},
57
+
58
+ // Reused internal string.
59
+ doTimeout = 'doTimeout',
60
+
61
+ // A convenient shortcut.
62
+ aps = Array.prototype.slice;
63
+
64
+ // Method: jQuery.doTimeout
65
+ //
66
+ // Initialize, cancel, or force execution of a callback after a delay.
67
+ //
68
+ // If delay and callback are specified, a doTimeout is initialized. The
69
+ // callback will execute, asynchronously, after the delay. If an id is
70
+ // specified, this doTimeout will override and cancel any existing doTimeout
71
+ // with the same id. Any additional arguments will be passed into callback
72
+ // when it is executed.
73
+ //
74
+ // If the callback returns true, the doTimeout loop will execute again, after
75
+ // the delay, creating a polling loop until the callback returns a non-true
76
+ // value.
77
+ //
78
+ // Note that if an id is not passed as the first argument, this doTimeout will
79
+ // NOT be able to be manually canceled or forced. (for debouncing, be sure to
80
+ // specify an id).
81
+ //
82
+ // If id is specified, but delay and callback are not, the doTimeout will be
83
+ // canceled without executing the callback. If force_mode is specified, the
84
+ // callback will be executed, synchronously, but will only be allowed to
85
+ // continue a polling loop if force_mode is true (provided the callback
86
+ // returns true, of course). If force_mode is false, no polling loop will
87
+ // continue, even if the callback returns true.
88
+ //
89
+ // Usage:
90
+ //
91
+ // > jQuery.doTimeout( [ id, ] delay, callback [, arg ... ] );
92
+ // > jQuery.doTimeout( id [, force_mode ] );
93
+ //
94
+ // Arguments:
95
+ //
96
+ // id - (String) An optional unique identifier for this doTimeout. If id is
97
+ // not specified, the doTimeout will NOT be able to be manually canceled or
98
+ // forced.
99
+ // delay - (Number) A zero-or-greater delay in milliseconds after which
100
+ // callback will be executed.
101
+ // callback - (Function) A function to be executed after delay milliseconds.
102
+ // callback - (String) A jQuery method to be executed after delay
103
+ // milliseconds. This method will only poll if it explicitly returns
104
+ // true.
105
+ // force_mode - (Boolean) If true, execute that id's doTimeout callback
106
+ // immediately and synchronously, continuing any callback return-true
107
+ // polling loop. If false, execute the callback immediately and
108
+ // synchronously but do NOT continue a callback return-true polling loop.
109
+ // If omitted, cancel that id's doTimeout.
110
+ //
111
+ // Returns:
112
+ //
113
+ // If force_mode is true, false or undefined and there is a
114
+ // yet-to-be-executed callback to cancel, true is returned, but if no
115
+ // callback remains to be executed, undefined is returned.
116
+
117
+ $[doTimeout] = function() {
118
+ return p_doTimeout.apply( window, [ 0 ].concat( aps.call( arguments ) ) );
119
+ };
120
+
121
+ // Method: jQuery.fn.doTimeout
122
+ //
123
+ // Initialize, cancel, or force execution of a callback after a delay.
124
+ // Operates like <jQuery.doTimeout>, but the passed callback executes in the
125
+ // context of the jQuery collection of elements, and the id is stored as data
126
+ // on the first element in that collection.
127
+ //
128
+ // If delay and callback are specified, a doTimeout is initialized. The
129
+ // callback will execute, asynchronously, after the delay. If an id is
130
+ // specified, this doTimeout will override and cancel any existing doTimeout
131
+ // with the same id. Any additional arguments will be passed into callback
132
+ // when it is executed.
133
+ //
134
+ // If the callback returns true, the doTimeout loop will execute again, after
135
+ // the delay, creating a polling loop until the callback returns a non-true
136
+ // value.
137
+ //
138
+ // Note that if an id is not passed as the first argument, this doTimeout will
139
+ // NOT be able to be manually canceled or forced (for debouncing, be sure to
140
+ // specify an id).
141
+ //
142
+ // If id is specified, but delay and callback are not, the doTimeout will be
143
+ // canceled without executing the callback. If force_mode is specified, the
144
+ // callback will be executed, synchronously, but will only be allowed to
145
+ // continue a polling loop if force_mode is true (provided the callback
146
+ // returns true, of course). If force_mode is false, no polling loop will
147
+ // continue, even if the callback returns true.
148
+ //
149
+ // Usage:
150
+ //
151
+ // > jQuery('selector').doTimeout( [ id, ] delay, callback [, arg ... ] );
152
+ // > jQuery('selector').doTimeout( id [, force_mode ] );
153
+ //
154
+ // Arguments:
155
+ //
156
+ // id - (String) An optional unique identifier for this doTimeout, stored as
157
+ // jQuery data on the element. If id is not specified, the doTimeout will
158
+ // NOT be able to be manually canceled or forced.
159
+ // delay - (Number) A zero-or-greater delay in milliseconds after which
160
+ // callback will be executed.
161
+ // callback - (Function) A function to be executed after delay milliseconds.
162
+ // callback - (String) A jQuery.fn method to be executed after delay
163
+ // milliseconds. This method will only poll if it explicitly returns
164
+ // true (most jQuery.fn methods return a jQuery object, and not `true`,
165
+ // which allows them to be chained and prevents polling).
166
+ // force_mode - (Boolean) If true, execute that id's doTimeout callback
167
+ // immediately and synchronously, continuing any callback return-true
168
+ // polling loop. If false, execute the callback immediately and
169
+ // synchronously but do NOT continue a callback return-true polling loop.
170
+ // If omitted, cancel that id's doTimeout.
171
+ //
172
+ // Returns:
173
+ //
174
+ // When creating a <jQuery.fn.doTimeout>, the initial jQuery collection of
175
+ // elements is returned. Otherwise, if force_mode is true, false or undefined
176
+ // and there is a yet-to-be-executed callback to cancel, true is returned,
177
+ // but if no callback remains to be executed, undefined is returned.
178
+
179
+ $.fn[doTimeout] = function() {
180
+ var args = aps.call( arguments ),
181
+ result = p_doTimeout.apply( this, [ doTimeout + args[0] ].concat( args ) );
182
+
183
+ return typeof args[0] === 'number' || typeof args[1] === 'number'
184
+ ? this
185
+ : result;
186
+ };
187
+
188
+ function p_doTimeout( jquery_data_key ) {
189
+ var that = this,
190
+ elem,
191
+ data = {},
192
+
193
+ // Allows the plugin to call a string callback method.
194
+ method_base = jquery_data_key ? $.fn : $,
195
+
196
+ // Any additional arguments will be passed to the callback.
197
+ args = arguments,
198
+ slice_args = 4,
199
+
200
+ id = args[1],
201
+ delay = args[2],
202
+ callback = args[3];
203
+
204
+ if ( typeof id !== 'string' ) {
205
+ slice_args--;
206
+
207
+ id = jquery_data_key = 0;
208
+ delay = args[1];
209
+ callback = args[2];
210
+ }
211
+
212
+ // If id is passed, store a data reference either as .data on the first
213
+ // element in a jQuery collection, or in the internal cache.
214
+ if ( jquery_data_key ) { // Note: key is 'doTimeout' + id
215
+
216
+ // Get id-object from the first element's data, otherwise initialize it to {}.
217
+ elem = that.eq(0);
218
+ elem.data( jquery_data_key, data = elem.data( jquery_data_key ) || {} );
219
+
220
+ } else if ( id ) {
221
+ // Get id-object from the cache, otherwise initialize it to {}.
222
+ data = cache[ id ] || ( cache[ id ] = {} );
223
+ }
224
+
225
+ // Clear any existing timeout for this id.
226
+ data.id && clearTimeout( data.id );
227
+ delete data.id;
228
+
229
+ // Clean up when necessary.
230
+ function cleanup() {
231
+ if ( jquery_data_key ) {
232
+ elem.removeData( jquery_data_key );
233
+ } else if ( id ) {
234
+ delete cache[ id ];
235
+ }
236
+ };
237
+
238
+ // Yes, there actually is a setTimeout call in here!
239
+ function actually_setTimeout() {
240
+ data.id = setTimeout( function(){ data.fn(); }, delay );
241
+ };
242
+
243
+ if ( callback ) {
244
+ // A callback (and delay) were specified. Store the callback reference for
245
+ // possible later use, and then setTimeout.
246
+ data.fn = function( no_polling_loop ) {
247
+
248
+ // If the callback value is a string, it is assumed to be the name of a
249
+ // method on $ or $.fn depending on where doTimeout was executed.
250
+ if ( typeof callback === 'string' ) {
251
+ callback = method_base[ callback ];
252
+ }
253
+
254
+ callback.apply( that, aps.call( args, slice_args ) ) === true && !no_polling_loop
255
+
256
+ // Since the callback returned true, and we're not specifically
257
+ // canceling a polling loop, do it again!
258
+ ? actually_setTimeout()
259
+
260
+ // Otherwise, clean up and quit.
261
+ : cleanup();
262
+ };
263
+
264
+ // Set that timeout!
265
+ actually_setTimeout();
266
+
267
+ } else if ( data.fn ) {
268
+ // No callback passed. If force_mode (delay) is true, execute the data.fn
269
+ // callback immediately, continuing any callback return-true polling loop.
270
+ // If force_mode is false, execute the data.fn callback immediately but do
271
+ // NOT continue a callback return-true polling loop. If force_mode is
272
+ // undefined, simply clean up. Since data.fn was still defined, whatever
273
+ // was supposed to happen hadn't yet, so return true.
274
+ delay === undefined ? cleanup() : data.fn( delay === false );
275
+ return true;
276
+
277
+ } else {
278
+ // Since no callback was passed, and data.fn isn't defined, it looks like
279
+ // whatever was supposed to happen already did. Clean up and quit!
280
+ cleanup();
281
+ }
282
+
283
+ };
284
+
285
+ })(jQuery);
common/src/resources/js/notice-dismiss.js CHANGED
@@ -1,27 +1,27 @@
1
- /**
2
- * Notice Dismiss structure
3
- */
4
- ( function( $ ) {
5
- // Add / Update a key-value pair in the URL query parameters
6
- function update_query_string(uri, key, value) {
7
- // remove the hash part before operating on the uri
8
- var i = uri.indexOf( '#' );
9
- var hash = i === -1 ? '' : uri.substr(i);
10
- uri = i === -1 ? uri : uri.substr(0, i);
11
-
12
- var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
13
- var separator = uri.indexOf('?') !== -1 ? "&" : "?";
14
- if (uri.match(re)) {
15
- uri = uri.replace(re, '$1' + key + "=" + value + '$2');
16
- } else {
17
- uri = uri + separator + key + "=" + value;
18
- }
19
- return uri + hash; // finally append the hash as well
20
- }
21
-
22
- $( document ).ready( function() {
23
- $( '.tribe-dismiss-notice.is-dismissible' ).on( 'click', '.notice-dismiss', function() {
24
- window.location.href = update_query_string( window.location.href, 'tribe-dismiss-notice', $( this ).parents( '.tribe-dismiss-notice' ).data( 'ref' ) );
25
- } );
26
- } );
27
  }( jQuery ) );
1
+ /**
2
+ * Notice Dismiss structure
3
+ */
4
+ ( function( $ ) {
5
+ // Add / Update a key-value pair in the URL query parameters
6
+ function update_query_string(uri, key, value) {
7
+ // remove the hash part before operating on the uri
8
+ var i = uri.indexOf( '#' );
9
+ var hash = i === -1 ? '' : uri.substr(i);
10
+ uri = i === -1 ? uri : uri.substr(0, i);
11
+
12
+ var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
13
+ var separator = uri.indexOf('?') !== -1 ? "&" : "?";
14
+ if (uri.match(re)) {
15
+ uri = uri.replace(re, '$1' + key + "=" + value + '$2');
16
+ } else {
17
+ uri = uri + separator + key + "=" + value;
18
+ }
19
+ return uri + hash; // finally append the hash as well
20
+ }
21
+
22
+ $( document ).ready( function() {
23
+ $( '.tribe-dismiss-notice.is-dismissible' ).on( 'click', '.notice-dismiss', function() {
24
+ window.location.href = update_query_string( window.location.href, 'tribe-dismiss-notice', $( this ).parents( '.tribe-dismiss-notice' ).data( 'ref' ) );
25
+ } );
26
+ } );
27
  }( jQuery ) );
common/src/resources/postcss/app-shop.pcss CHANGED
@@ -1,58 +1,58 @@
1
- .tribe-addon {
2
- -webkit-box-sizing: border-box;
3
- -moz-box-sizing: border-box;
4
- box-sizing: border-box;
5
- display: inline-block;
6
- margin-right: 10px;
7
- overflow: hidden;
8
- padding: 20px 20px 20px 0;
9
- vertical-align: top;
10
- width: 300px;
11
- }
12
-
13
- .tribe-addon .thumb img {
14
- max-width: 100%;
15
- width: 100%;
16
- }
17
-
18
- .tribe-addon h4 {
19
- font-size: 1.17em;
20
- }
21
-
22
- .tribe-addon h4 a {
23
- text-decoration: none;
24
- }
25
-
26
- .addon-grid {
27
- width: 100%;
28
- }
29
-
30
- .category-title {
31
- clear: both;
32
- display: block;
33
- margin-bottom: 10px;
34
- }
35
-
36
- .tribe-addon.first {
37
- border-bottom: 1px solid #dfdfdf;
38
- margin: 20px 0 10px;
39
- overflow: hidden;
40
- padding: 0 0 20px 330px;
41
- width: 100%;
42
- }
43
-
44
- .tribe-addon.first h4 {
45
- font-size: 20px;
46
- line-height: 1.4;
47
- margin: 0;
48
- }
49
-
50
- .tribe-addon.first .thumb {
51
- float: left;
52
- margin-left: -330px;
53
- width: 300px;
54
- }
55
-
56
- .tribe-addon.first .description {
57
- max-width: 600px;
58
- }
1
+ .tribe-addon {
2
+ -webkit-box-sizing: border-box;
3
+ -moz-box-sizing: border-box;
4
+ box-sizing: border-box;
5
+ display: inline-block;
6
+ margin-right: 10px;
7
+ overflow: hidden;
8
+ padding: 20px 20px 20px 0;
9
+ vertical-align: top;
10
+ width: 300px;
11
+ }
12
+
13
+ .tribe-addon .thumb img {
14
+ max-width: 100%;
15
+ width: 100%;
16
+ }
17
+
18
+ .tribe-addon h4 {
19
+ font-size: 1.17em;
20
+ }
21
+
22
+ .tribe-addon h4 a {
23
+ text-decoration: none;
24
+ }
25
+
26
+ .addon-grid {
27
+ width: 100%;
28
+ }
29
+
30
+ .category-title {
31
+ clear: both;
32
+ display: block;
33
+ margin-bottom: 10px;
34
+ }
35
+
36
+ .tribe-addon.first {
37
+ border-bottom: 1px solid #dfdfdf;
38
+ margin: 20px 0 10px;
39
+ overflow: hidden;
40
+ padding: 0 0 20px 330px;
41
+ width: 100%;
42
+ }
43
+
44
+ .tribe-addon.first h4 {
45
+ font-size: 20px;
46
+ line-height: 1.4;
47
+ margin: 0;
48
+ }
49
+
50
+ .tribe-addon.first .thumb {
51
+ float: left;
52
+ margin-left: -330px;
53
+ width: 300px;
54
+ }
55
+
56
+ .tribe-addon.first .description {
57
+ max-width: 600px;
58
+ }
common/src/resources/postcss/tribe-common-admin.pcss CHANGED
@@ -1,991 +1,991 @@
1
- /* = Shared CSS Elements
2
- =============================================*/
3
- .invalid input {
4
- border: 2px solid red !important;
5
- }
6
- .valid input {
7
- border: 1px solid green;
8
- }
9
- .clearfix {
10
- zoom: 1; /* For IE */
11
- }
12
- .placeholder {
13
- color: #999;
14
- cursor: text;
15
- padding: 4px 4px 4px 4px;
16
- }
17
- input:placeholder,
18
- textarea:placeholder {
19
- color: #999;
20
- }
21
- input::-webkit-input-placeholder,
22
- textarea::-webkit-input-placeholder {
23
- color: #999;
24
- }
25
- .bubble {
26
- -khtml-border-radius: 3px;
27
- background-color: #f9f9f9;
28
- border-color: #dfdfdf;
29
- -webkit-border-radius: 3px;
30
- -moz-border-radius: 3px;
31
- border-radius: 3px;
32
- border-spacing: 0;
33
- border-style: solid;
34
- border-style: solid;
35
- border-width: 1px;
36
- padding: 10px;
37
- }
38
- .tribe-sticky-tooltip {
39
- color: #bbb;
40
- }
41
- td.tribe_message {
42
- padding-bottom: 10px !important;
43
- }
44
-
45
- #tribe_thanks {
46
- float: left;
47
- margin: 5px 0 0 0;
48
- width: 200px;
49
- }
50
- .tribe_brand {
51
- font-family: Georgia !important;
52
- font-size: 17px !important;
53
- font-weight: normal;
54
- margin: 8px 0;
55
- }
56
-
57
- /* = Upgrade Screen
58
- =============================================*/
59
- #tribe-upgrade {
60
- background: #f6f6f6;
61
- border: 1px solid #ccc;
62
- -webkit-border-radius: 5px;
63
- -moz-border-radius: 5px;
64
- border-radius: 5px;
65
- margin: 20px 0 30px;
66
- padding: 0 20px 20px;
67
- }
68
- #tribe-upgrade .message {
69
- background-color: #ffffe0;
70
- border-color: #e6db55;
71
- -webkit-border-radius: 3px;
72
- -moz-border-radius: 3px;
73
- border-radius: 3px;
74
- border-style: solid;
75
- border-width: 1px;
76
- padding: 6px 12px;
77
- }
78
-
79
- /* = Plugin Screen
80
- =============================================*/
81
- table.plugins .tribe-plugin-update-message {
82
- background: #d54e21; /* taken from colour scheme in list-tables.css */
83
- color: white;
84
- display: inline-table;
85
- margin: 6px 0;
86
- padding: 10px 12px;
87
- }
88
-
89
- table.plugins .tribe-plugin-update-message h4 {
90
- display: inline;
91
- font-weight: bold;
92
- margin-right: 8px;
93
- }
94
-
95
- table.plugins .tribe-plugin-update-message h4:after {
96
- content: ' \00BB ';
97
- }
98
-
99
-
100
- table.plugins .tribe-plugin-update-message a {
101
- color: white;
102
- text-decoration: underline;
103
- }
104
-
105
- /* = Settings Screen
106
- =============================================*/
107
- .tribe-settings-form {
108
- max-width: 1000px;
109
- }
110
- .tribe-settings-form fieldset {
111
- clear: both;
112
- display: inline-block;
113
- padding: 10px 0;
114
- }
115
- .tribe-settings-form legend {
116
- float: left;
117
- font-weight: bold;
118
- margin-right: 20px;
119
- width: 220px;
120
- }
121
- .tribe-settings-form fieldset.tribe-field-license_key legend {
122
- width: auto;
123
- }
124
- .tribe-settings-form .tribe-field-wrap {
125
- float: left;
126
- max-width: 500px;
127
- }
128
- .tribe-settings-form .tribe-field-radio label,
129
- .tribe-settings-form .tribe-field-checkbox_list label {
130
- display: block;
131
- margin: 5px 0;
132
- }
133
- .tribe-settings-form .tribe-field-radio label input,
134
- .tribe-settings-form .tribe-field-checkbox_list label input {
135
- margin-right: 5px;
136
- }
137
- .tribe-settings-form .tribe-settings-form-wrap fieldset,
138
- .tribe-settings-form .tribe-settings-form-wrap .description,
139
- .tribe-settings-form fieldset[id^='tribe-field-geoloc_'] {
140
- padding-left: 12px;
141
- }
142
- .tribe-settings-form .tribe-settings-form-wrap fieldset .description {
143
- margin-left: 0;
144
- max-width: 450px;
145
- padding-left: 0;
146
- }
147
- .tribe-settings-form .tribe-settings-form-wrap h3 {
148
- background-color: #f9f9f9;
149
- margin-bottom: 10px;
150
- padding: 6px 0 6px 12px;
151
- }
152
- .tribe-settings-form .tribe-settings-form-wrap h3 ~ h3 {
153
- margin-top: 2.25em;
154
- }
155
- .tribe-settings-form .tribe-settings-form-wrap h3 + p {
156
- margin: 0 0 10px;
157
- padding-left: 12px;
158
- }
159
- .tribe_settings .tribe-field-indent {
160
- margin-left: 245px;
161
- }
162
- .tribe_settings #pu_dashboard_message {
163
- display: none;
164
- }
165
- .tribe_settings .tribe-errors-list {
166
- margin-left: 15px;
167
- }
168
- .tribe_settings .expiring-license {
169
- color: red;
170
- }
171
- .tribe_settings .tribe-error {
172
- border: 1px solid #f00;
173
- }
174
- .tribe_settings .tribe-field-description {
175
- margin-bottom: 0;
176
- position: relative;
177
- top: -12px;
178
- }
179
- .tribe_settings #ical-link {
180
- top: -14px;
181
- }
182
- .tribe-settings-form #tribe-field-stylesheetOption label {
183
- margin-left: 20px;
184
- }
185
- .tribe-settings-form #tribe-field-stylesheetOption input {
186
- margin-left: -20px;
187
- margin-right: 8px;
188
- }
189
- .tribe-settings-form #tribe-field-stylesheetOption p.description {
190
- color: #999;
191
- }
192
- /* Modern Tribe box */
193
- #modern-tribe-info {
194
- -khtml-border-radius: 4px;
195
- background-color: #f9f9f9;
196
- border: 1px solid #ccc;
197
- -webkit-border-radius: 4px;
198
- -moz-border-radius: 4px;
199
- -o-border-radius: 4px;
200
- border-radius: 4px;
201
- margin: 20px 0;
202
- padding: 8px 20px 12px;
203
- }
204
- #modern-tribe-info img {
205
- height: 18px;
206
- margin: 10px 0;
207
- width: 250px;
208
- }
209
- #modern-tribe-info ul {
210
- list-style: disc;
211
- margin-left: 20px;
212
- }
213
- #modern-tribe-info ul ul {
214
- list-style: circle;
215
- }
216
-
217
- /* sizes */
218
- .tribe-field-textarea.tribe-size-small textarea {
219
- height: 60px;
220
- width: 180px;
221
- }
222
- .tribe-field-textarea.tribe-size-medium textarea {
223
- height: 80px;
224
- width: 300px;
225
- }
226
- .tribe-field-textarea.tribe-size-large textarea {
227
- height: 120px;
228
- width: 450px;
229
- }
230
-
231
- .tribe-field-text.tribe-size-small input,
232
- .tribe-field-license_key.tribe-size-small input {
233
- width: 50px;
234
- }
235
- .tribe-field-text.tribe-size-medium input,
236
- .tribe-field-license_key.tribe-size-medium input {
237
- width: 225px;
238
- }
239
- .tribe-field-text.tribe-size-large input,
240
- .tribe-field-license_key.tribe-size-large input {
241
- width: 450px;
242
- }
243
-
244
- .tribe-field-dropdown.tribe-size-small select {
245
- width: 100px;
246
- }
247
- .tribe-field-dropdown.tribe-size-medium select {
248
- width: 300px;
249
- }
250
- .tribe-field-dropdown.tribe-size-large select {
251
- width: 450px;
252
- }
253
-
254
- .tribe-field-dropdown_chosen.tribe-size-small select {
255
- width: 100px;
256
- }
257
- .tribe-field-dropdown_chosen.tribe-size-medium select {
258
- width: 200px;
259
- }
260
- .tribe-field-dropdown_chosen.tribe-size-large select {
261
- width: 300px;
262
- }
263
-
264
- /* license keys */
265
- .ajax-loading-license,
266
- .valid-key,
267
- .invalid-key {
268
- display: none;
269
- margin: 0 5px;
270
- }
271
- .ajax-loading-license {
272
- position: relative;
273
- top: 5px;
274
- }
275
- .key-validity {
276
- display: inline-block;
277
- }
278
- .invalid-key {
279
- color: red;
280
- }
281
- .valid-key {
282
- color: green;
283
- }
284
- .valid-key.service-msg {
285
- color: #b72;
286
- }
287
-
288
- /* additional fields */
289
- #additional-field-table {
290
- margin-bottom: 20px;
291
- }
292
-
293
- /* miscellaneous */
294
- .tribe-admin-box-left {
295
- -khtml-border-radius: 4px;
296
- background-color: #f9f9f9;
297
- border: 1px solid #ccc;
298
- -webkit-border-radius: 4px;
299
- -moz-border-radius: 4px;
300
- -o-border-radius: 4px;
301
- border-radius: 4px;
302
- float: left;
303
- margin: 20px 0;
304
- padding: 0 20px 15px;
305
- width: 20%;
306
- }
307
- .tribe-admin-box-right {
308
- -khtml-border-radius: 4px;
309
- background-color: #f9f9f9;
310
- border: 1px solid #ccc;
311
- -webkit-border-radius: 4px;
312
- -moz-border-radius: 4px;
313
- -o-border-radius: 4px;
314
- border-radius: 4px;
315
- float: right;
316
- margin: 20px 0;
317
- padding: 0 20px 15px;
318
- width: 68%;
319
- }
320
- .ajax-loader {
321
- float: right;
322
- margin: 10px;
323
- }
324
- .tribe-arrangeable-item {
325
- border: 1px solid lightGrey;
326
- -moz-border-radius: 6px;
327
- border-radius: 6px;
328
- }
329
- .tribe-arrangeable-item .ui-state-default {
330
- border: none;
331
- }
332
- .tribe-arrangeable-item-top {
333
- padding: 6px;
334
- }
335
- .tribe-arrangeable-item-top:hover {
336
- cursor: move;
337
- }
338
- .tribe-arrangeable-action {
339
- float: right;
340
- }
341
- .tribe-arrangeable-child {
342
- background-color: #f9f9f9;
343
- border-top: 1px solid lightGrey;
344
- display: none;
345
- padding: 25px;
346
- }
347
- .tribe-arrangeable-child label {
348
- display: block;
349
- margin: 0 0 7px 0;
350
- }
351
- .tribe_events_active_filter_type_options {
352
- margin: 10px 0;
353
- }
354
- .tribe_events_active_filter_type_options label {
355
- margin: 7px 0;
356
- }
357
- .tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection {
358
- margin-bottom: 18px;
359
- }
360
- .OrganizerInfo td small,
361
- #event_organizer td small {
362
- display: block;
363
- margin: 0;
364
- max-width: 250px;
365
- }
366
- .OrganizerInfo .organizer-email,
367
- #event_organizer .organizer-email {
368
- vertical-align: top;
369
- }
370
-
371
- .tribe-table-field-label {
372
- max-width: 100%;
373
- width: 200px;
374
- }
375
-
376
- /* = Help Screen
377
- =============================================*/
378
-
379
- #tribe-help-general,
380
- #tribe-help-sidebar {
381
- float: left;
382
- margin-top: 20px;
383
- }
384
-
385
- #tribe-help-general p {
386
- margin-left: 15px;
387
- }
388
-
389
- #tribe-help-general ul {
390
- list-style-type: square;
391
- margin-bottom: 20px;
392
- margin-left: 35px;
393
- }
394
-
395
- #tribe-help-general ol {
396
- margin-bottom: 20px;
397
- margin-left: 35px;
398
- }
399
-
400
- #tribe-help-general h3 {
401
- background-color: #f9f9f9;
402
- margin-bottom: 10px;
403
- padding: 6px 0 6px 12px;
404
- }
405
-
406
- #tribe-help-general h3 ~ h3 {
407
- margin-top: 2.25em;
408
- }
409
-
410
- #tribe-help-general h3 + p {
411
- margin: 0 0 20px;
412
- padding-left: 12px;
413
- }
414
-
415
- #tribe-help-general {
416
- width: 65%;
417
- }
418
-
419
- .tribe-help-section {
420
- padding-bottom: 10px;
421
- }
422
-
423
- .tribe-section-type-box {
424
- -khtml-border-radius: 4px;
425
- background-color: #f9f9f9;
426
- border: 1px solid #ccc;
427
- -webkit-border-radius: 4px;
428
- -moz-border-radius: 4px;
429
- -o-border-radius: 4px;
430
- border-radius: 4px;
431
- padding: 8px 20px 12px;
432
- }
433
-
434
- .tribe-section-type-box img {
435
- height: auto;
436
- margin: 10px 0;
437
- max-width: 300px;
438
- }
439
-
440
- .tribe-section-type-box ul {
441
- list-style: disc;
442
- margin-left: 20px;
443
- }
444
-
445
- .tribe-section-type-box ul ul {
446
- list-style: circle;
447
- }
448
-
449
- #tribe-log-controls {
450
- padding-bottom: 1rem;
451
-
452
- /* For consistency with help screen h3 and p elements */
453
- padding-left: 12px;
454
-
455
- & > div {
456
- display: inline-block;
457
- padding-right: 1rem;
458
- }
459
-
460
- .working {
461
- opacity: 1;
462
- transition: opacity 0.2s;
463
- }
464
-
465
- .working.hidden {
466
- opacity: 0;
467
- transition: opacity 0.2s;
468
- }
469
- }
470
-
471
- #tribe-system-info dl.support-stats,
472
- #tribe-log-viewer,
473
- .template-updates-wrapper {
474
- background: #000;
475
- border-radius: 2px;
476
- color: #888;
477
- max-height: 400px;
478
- overflow: scroll;
479
- padding: 10px;
480
- }
481
-
482
- #tribe-system-info dl.support-stats dt,
483
- .template-updates-wrapper dt {
484
- clear: both;
485
- float: left;
486
- font-weight: bold;
487
- text-transform: uppercase;
488
- width: 25%;
489
- }
490
-
491
- #tribe-system-info dl.support-stats dd,
492
- .template-updates-wrapper dd {
493
- margin-left: 25%;
494
- padding-left: 10px;
495
- }
496
-
497
- .template-updates-wrapper p {
498
- margin-top: 0;
499
- }
500
-
501
- #tribe-help-sidebar {
502
- margin: 20px 0 0 3%;
503
- max-width: 225px;
504
- width: 32%;
505
- }
506
-
507
- .tribe-help-plugin-info {
508
- border: 1px solid #ccc;
509
- padding: 0 12px 12px;
510
- }
511
-
512
- .tribe-help-plugin-info dt,
513
- .tribe-help-plugin-info dd {
514
- display: inline;
515
- margin: 0;
516
- }
517
-
518
- .tribe-help-plugin-info dt {
519
- font-weight: bold;
520
- }
521
-
522
- .tribe-help-plugin-info dd::after {
523
- content: '';
524
- display: block;
525
- height: .4em;
526
- }
527
-
528
- .tribe-help-plugin-info dd:last-child::after {
529
- height: 0;
530
- }
531
-
532
- .tribe-help-plugin-info + .tribe-help-plugin-info {
533
- margin-top: 20px;
534
- }
535
-
536
- .tribe-help-plugin-info > div {
537
- line-height: 2em;
538
- }
539
-
540
- .tribe-help-plugin-info .star-rating {
541
- display: inline-block;
542
- margin-left: 3px;
543
- position: relative;
544
- top: -2px;
545
- }
546
-
547
- .tribe-help-plugin-info .tribe-list-addons {
548
- color: #21a6cb;
549
- font-size: 24px;
550
- list-style: circle inside;
551
- margin-bottom: 10px;
552
- margin-top: 10px;
553
- padding-left: 4px;
554
- }
555
-
556
- .tribe-help-plugin-info .tribe-list-addons a {
557
- font-size: 13px;
558
- left: -5px;
559
- position: relative;
560
- top: -5px;
561
- }
562
-
563
- .tribe-help-plugin-info .tribe-list-addons .tribe-active-addon {
564
- list-style: disc inside;
565
- }
566
-
567
- /* = jQuery UI
568
- =============================================*/
569
- .ui-widget-overlay {
570
- background: #666;
571
- filter: Alpha(Opacity=50);
572
- opacity: .50;
573
- }
574
- .ui-widget-shadow {
575
- background: #000;
576
- -webkit-border-radius: 5px;
577
- -moz-border-radius: 5px;
578
- filter: Alpha(Opacity=20);
579
- margin: -5px 0 0 -5px;
580
- opacity: .20;
581
- padding: 5px;
582
- }
583
- .ui-resizable {
584
- position: relative;
585
- }
586
- .ui-resizable-handle {
587
- display: block;
588
- font-size: .1px;
589
- position: absolute;
590
- z-index: 99999;
591
- }
592
- .ui-resizable-disabled .ui-resizable-handle,
593
- .ui-resizable-autohide .ui-resizable-handle {
594
- display: none;
595
- }
596
- .ui-resizable-n {
597
- cursor: n-resize;
598
- height: 7px;
599
- left: 0;
600
- top: -5px;
601
- width: 100%;
602
- }
603
- .ui-resizable-s {
604
- bottom: -5px;
605
- cursor: s-resize;
606
- height: 7px;
607
- left: 0;
608
- width: 100%;
609
- }
610
- .ui-resizable-e {
611
- cursor: e-resize;
612
- height: 100%;
613
- right: -5px;
614
- top: 0;
615
- width: 7px;
616
- }
617
- .ui-resizable-w {
618
- cursor: w-resize;
619
- height: 100%;
620
- left: -5px;
621
- top: 0;
622
- width: 7px;
623
- }
624
- .ui-resizable-se {
625
- bottom: 1px;
626
- cursor: se-resize;
627
- height: 12px;
628
- right: 1px;
629
- width: 12px;
630
- }
631
- .ui-resizable-sw {
632
- bottom: -5px;
633
- cursor: sw-resize;
634
- height: 9px;
635
- left: -5px;
636
- width: 9px;
637
- }
638
- .ui-resizable-nw {
639
- cursor: nw-resize;
640
- height: 9px;
641
- left: -5px;
642
- top: -5px;
643
- width: 9px;
644
- }
645
- .ui-resizable-ne {
646
- cursor: ne-resize;
647
- height: 9px;
648
- right: -5px;
649
- top: -5px;
650
- width: 9px;
651
- }
652
- .ui-dialog {
653
- padding: .2em;
654
- position: relative;
655
- width: 375px;
656
- }
657
- .ui-dialog .ui-dialog-titlebar {
658
- padding: .5em .3em .3em 1em;
659
- position: relative;
660
- }
661
- .ui-dialog .ui-dialog-title {
662
- float: left;
663
- margin: .1em 0 .2em;
664
- }
665
- .ui-dialog .ui-dialog-titlebar-close {
666
- height: 18px;
667
- margin: -10px 0 0 0;
668
- padding: 1px;
669
- position: absolute;
670
- right: .3em;
671
- top: 50%;
672
- width: 19px;
673
- }
674
- .ui-dialog .ui-dialog-titlebar-close span {
675
- display: block;
676
- margin-left: -8px;
677
- margin-top: -8px;
678
- }
679
- .ui-dialog .ui-dialog-titlebar-close:hover,
680
- .ui-dialog .ui-dialog-titlebar-close:focus {
681
- padding: 0;
682
- }
683
- .ui-dialog .ui-dialog-content {
684
- background: none;
685
- border: 0;
686
- overflow: auto;
687
- padding: .5em 1em;
688
- zoom: 1;
689
- }
690
- .ui-dialog .ui-dialog-buttonpane {
691
- background-image: none;
692
- border-width: 1px 0 0 0;
693
- margin: .5em 0 0 0;
694
- padding: .3em 1em .5em !important;
695
- text-align: right;
696
- }
697
- .ui-dialog .ui-dialog-buttonpane button {
698
- cursor: pointer;
699
- line-height: 1.4em;
700
- margin: .5em .4em .5em !important;
701
- overflow: visible;
702
- padding: .2em .6em .3em;
703
- text-shadow: none;
704
- width: auto;
705
- }
706
- .ui-dialog .ui-resizable-se {
707
- bottom: 3px;
708
- height: 14px;
709
- right: 3px;
710
- width: 14px;
711
- }
712
- .ui-draggable .ui-dialog-titlebar {
713
- cursor: move;
714
- }
715
- .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
716
- float: none !important;
717
- text-align: center;
718
- }
719
- .ui-button-text-only .ui-button-text {
720
- padding: .4em 1em;
721
- }
722
- .ui-button .ui-button-text {
723
- display: block;
724
- line-height: 1.4;
725
- }
726
- .ui-datepicker {
727
- font-size: 8pt;
728
- }
729
- #ui-datepicker-div {
730
- display: none;
731
- }
732
-
733
- #tribe-loading {
734
- background: #fff;
735
- background: rgba(255, 255, 255, .8);
736
- display: none;
737
- height: 100%;
738
- left: 0;
739
- position: absolute;
740
- top: 0;
741
- -moz-transition: all 1s linear;
742
- -ms-transition: all 1s linear;
743
- -o-transition: all 1s linear;
744
- transition: all 1s linear;
745
- webkit-transition: all 1s linear;
746
- width: 100%;
747
- z-index: 4;
748
- }
749
-
750
- #tribe-loading span {
751
- background: url(../images/tribe-loading.gif) 0 0 no-repeat;
752
- -webkit-background-size: 32px 32px;
753
- background-size: 32px 32px;
754
- height: 32px;
755
- left: 50%;
756
- margin: -16px 0 0 -16px;
757
- position: absolute;
758
- top: 50%;
759
- width: 32px;
760
- }
761
-
762
- /* = Admin Retina Bits
763
- =============================================*/
764
- @media
765
- only screen and (min--moz-device-pixel-ratio: 2),
766
- only screen and (-o-min-device-pixel-ratio: 2/1),
767
- only screen and (-webkit-min-device-pixel-ratio: 2),
768
- only screen and (min-device-pixel-ratio: 2) {
769
- #tribe-loading span {
770
- background-image: url(../images/tribe-loading@2x.gif);
771
- }
772
- }
773
-
774
- /* = TEC Welcome & Update Pages // Displays after installation & plugin update
775
- ===============================================================================*/
776
-
777
- .tribe_welcome_page,
778
- .tribe_update_page {
779
- max-width: 1000px;
780
- }
781
-
782
- .tribe-half-column {
783
- float: left;
784
- margin-bottom: 30px;
785
- margin-right: 5%;
786
- width: 45%;
787
- }
788
-
789
- .tribe-row:before,
790
- .tribe-row:after {
791
- content: '';
792
- display: table;
793
- }
794
-
795
- .tribe-row:after {
796
- clear: both;
797
- }
798
-
799
- .tribe-row {
800
- clear: both;
801
- }
802
-
803
- .tribe-row .tribe-half-column:last-child {
804
- margin-right: 0;
805
- width: 50%;
806
- }
807
-
808
- .tribe_welcome_page h2,
809
- .tribe_update_page h2 {
810
- font-size: 30px;
811
- line-height: 1.2;
812
- margin-bottom: 20px;
813
- }
814
-
815
- .tribe_welcome_page h3,
816
- .tribe_update_page h3 {
817
- font-size: 24px;
818
- font-weight: 400;
819
- line-height: 24px;
820
- margin-top: 0;
821
- }
822
-
823
- .tribe_welcome_page h4,
824
- .tribe_update_page h4 {
825
- font-size: 18px;
826
- font-weight: 600;
827
- line-height: 18px;
828
- margin: 0;
829
- }
830
-
831
- .tribe_welcome_page p,
832
- .tribe_update_page p {
833
- font-size: 14px;
834
- }
835
-
836
- p.tribe-welcome-message {
837
- font-size: 20px;
838
- font-weight: 400;
839
- }
840
-
841
- .tribe_welcome_page h2:before,
842
- .tribe_update_page h2:before {
843
- content: '\f145';
844
- font-family: 'dashicons';
845
- font-size: 34px;
846
- line-height: 1;
847
- margin-right: 5px;
848
- position: relative;
849
- top: 5px;
850
- }
851
-
852
- .tribe-welcome-video-wrapper {
853
- height: 0;
854
- margin-bottom: 40px;
855
- padding-bottom: 56.25%; /* 16:9 */
856
- padding-top: 25px;
857
- position: relative;
858
- }
859
-
860
- .tribe-welcome-video-wrapper iframe {
861
- height: 100%;
862
- left: 0;
863
- position: absolute;
864
- top: 0;
865
- width: 100%;
866
- }
867
-
868
- a.tribe-rating-link {
869
- text-decoration: none;
870
- }
871
-
872
- .tribe-welcome-links,
873
- .tribe-update-links {
874
- margin-top: 30px;
875
- }
876
-
877
- .tribe_welcome_page li:before,
878
- .tribe_update_page li:before {
879
- content: '\2022';
880
- padding-right: 3px;
881
- }
882
-
883
- .tribe_update_page .rss-widget {
884
- margin: 1em 0;
885
- }
886
-
887
- .tribe_update_page a.rsswidget {
888
- font-size: 14px;
889
- font-weight: 400;
890
- line-height: 1;
891
- }
892
-
893
- .tribe_update_page .rss-widget li:before {
894
- display: none;
895
- }
896
-
897
- /* Media Queries for Mobile Dashboard */
898
- @media screen and (max-width: 782px) {
899
- .tribe-half-column,
900
- .tribe-row .tribe-half-column:last-child {
901
- margin: 0 0 20px 0;
902
- width: 100%;
903
- }
904
-
905
- input[type='email'] {
906
- width: 100%;
907
- }
908
- }
909
-
910
-
911
- @media screen and ( max-width: 782px ) {
912
- .events-cal .subsubsub {
913
- float: none;
914
- }
915
-
916
- .events-cal .search-box {
917
- width: 98%;
918
- }
919
-
920
- .events-cal #search-submit {
921
- width: 100%;
922
- }
923
-
924
- .events-cal .tablenav.top {
925
- display: none;
926
- }
927
- }
928
-
929
- .tribe-update-bar {
930
- display: inline-block;
931
- }
932
-
933
- .tribe-update-bar .progress {
934
- border: 1px solid #ccc;
935
- float: left;
936
- margin-right: 1rem;
937
- padding: 1px;
938
- width: 18rem;
939
- }
940
-
941
- .tribe-update-bar .progress .bar {
942
- background: #ffba00;
943
- height: 1rem;
944
- width: 1%;
945
- }
946
-
947
- .tribe-update-bar .progress .bar {
948
- background: #7ad03a;
949
- }
950
-
951
- /* bumpdown */
952
- .bumpdown {
953
- background: #f1f1f1;
954
- margin: 1rem 0;
955
- padding: 1rem 1.5rem 1rem 1rem;
956
- position: relative;
957
- }
958
-
959
- #poststuff .bumpdown h1,
960
- #poststuff .bumpdown h2,
961
- #poststuff .bumpdown h3,
962
- #poststuff .bumpdown h4,
963
- .bumpdown h1,
964
- .bumpdown h2,
965
- .bumpdown h3,
966
- .bumpdown h4 {
967
- padding-left: 0;
968
- padding-top: 0;
969
- }
970
-
971
- .bumpdown-arrow {
972
- display: none;
973
- }
974
-
975
- .bumpdown-close {
976
- color: #686868;
977
- cursor: pointer;
978
- position: absolute;
979
- right: .5rem;
980
- top: .5rem;
981
- z-index: 2;
982
- }
983
-
984
- .bumpdown-trigger .target {
985
- color: #0074a2;
986
- }
987
-
988
- /* Useful to ensure modals rise above the grey 'miasma' */
989
- .ui-front {
990
- z-index: 1000000;
991
- }
1
+ /* = Shared CSS Elements
2
+ =============================================*/
3
+ .invalid input {
4
+ border: 2px solid red !important;
5
+ }
6
+ .valid input {
7
+ border: 1px solid green;
8
+ }
9
+ .clearfix {
10
+ zoom: 1; /* For IE */
11
+ }
12
+ .placeholder {
13
+ color: #999;
14
+ cursor: text;
15
+ padding: 4px 4px 4px 4px;
16
+ }
17
+ input:placeholder,
18
+ textarea:placeholder {
19
+ color: #999;
20
+ }
21
+ input::-webkit-input-placeholder,
22
+ textarea::-webkit-input-placeholder {
23
+ color: #999;
24
+ }
25
+ .bubble {
26
+ -khtml-border-radius: 3px;
27
+ background-color: #f9f9f9;
28
+ border-color: #dfdfdf;
29
+ -webkit-border-radius: 3px;
30
+ -moz-border-radius: 3px;
31
+ border-radius: 3px;
32
+ border-spacing: 0;
33
+ border-style: solid;
34
+ border-style: solid;
35
+ border-width: 1px;
36
+ padding: 10px;
37
+ }
38
+ .tribe-sticky-tooltip {
39
+ color: #bbb;
40
+ }
41
+ td.tribe_message {
42
+ padding-bottom: 10px !important;
43
+ }
44
+
45
+ #tribe_thanks {
46
+ float: left;
47
+ margin: 5px 0 0 0;
48
+ width: 200px;
49
+ }
50
+ .tribe_brand {
51
+ font-family: Georgia !important;
52
+ font-size: 17px !important;
53
+ font-weight: normal;
54
+ margin: 8px 0;
55
+ }
56
+
57
+ /* = Upgrade Screen
58
+ =============================================*/
59
+ #tribe-upgrade {
60
+ background: #f6f6f6;
61
+ border: 1px solid #ccc;
62
+ -webkit-border-radius: 5px;
63
+ -moz-border-radius: 5px;
64
+ border-radius: 5px;
65
+ margin: 20px 0 30px;
66
+ padding: 0 20px 20px;
67
+ }
68
+ #tribe-upgrade .message {
69
+ background-color: #ffffe0;
70
+ border-color: #e6db55;
71
+ -webkit-border-radius: 3px;
72
+ -moz-border-radius: 3px;
73
+ border-radius: 3px;
74
+ border-style: solid;
75
+ border-width: 1px;
76
+ padding: 6px 12px;
77
+ }
78
+
79
+ /* = Plugin Screen
80
+ =============================================*/
81
+ table.plugins .tribe-plugin-update-message {
82
+ background: #d54e21; /* taken from colour scheme in list-tables.css */
83
+ color: white;
84
+ display: inline-table;
85
+ margin: 6px 0;
86
+ padding: 10px 12px;
87
+ }
88
+
89
+ table.plugins .tribe-plugin-update-message h4 {
90
+ display: inline;
91
+ font-weight: bold;
92
+ margin-right: 8px;
93
+ }
94
+
95
+ table.plugins .tribe-plugin-update-message h4:after {
96
+ content: ' \00BB ';
97
+ }
98
+
99
+
100
+ table.plugins .tribe-plugin-update-message a {
101
+ color: white;
102
+ text-decoration: underline;
103
+ }
104
+
105
+ /* = Settings Screen
106
+ =============================================*/
107
+ .tribe-settings-form {
108
+ max-width: 1000px;
109
+ }
110
+ .tribe-settings-form fieldset {
111
+ clear: both;
112
+ display: inline-block;
113
+ padding: 10px 0;
114
+ }
115
+ .tribe-settings-form legend {
116
+ float: left;
117
+ font-weight: bold;
118
+ margin-right: 20px;
119
+ width: 220px;
120
+ }
121
+ .tribe-settings-form fieldset.tribe-field-license_key legend {
122
+ width: auto;
123
+ }
124
+ .tribe-settings-form .tribe-field-wrap {
125
+ float: left;
126
+ max-width: 500px;
127
+ }
128
+ .tribe-settings-form .tribe-field-radio label,
129
+ .tribe-settings-form .tribe-field-checkbox_list label {
130
+ display: block;
131
+ margin: 5px 0;
132
+ }
133
+ .tribe-settings-form .tribe-field-radio label input,
134
+ .tribe-settings-form .tribe-field-checkbox_list label input {
135
+ margin-right: 5px;
136
+ }
137
+ .tribe-settings-form .tribe-settings-form-wrap fieldset,
138
+ .tribe-settings-form .tribe-settings-form-wrap .description,
139
+ .tribe-settings-form fieldset[id^='tribe-field-geoloc_'] {
140
+ padding-left: 12px;
141
+ }
142
+ .tribe-settings-form .tribe-settings-form-wrap fieldset .description {
143
+ margin-left: 0;
144
+ max-width: 450px;
145
+ padding-left: 0;
146
+ }
147
+ .tribe-settings-form .tribe-settings-form-wrap h3 {
148
+ background-color: #f9f9f9;
149
+ margin-bottom: 10px;
150
+ padding: 6px 0 6px 12px;
151
+ }
152
+ .tribe-settings-form .tribe-settings-form-wrap h3 ~ h3 {
153
+ margin-top: 2.25em;
154
+ }
155
+ .tribe-settings-form .tribe-settings-form-wrap h3 + p {
156
+ margin: 0 0 10px;
157
+ padding-left: 12px;
158
+ }
159
+ .tribe_settings .tribe-field-indent {
160
+ margin-left: 245px;
161
+ }
162
+ .tribe_settings #pu_dashboard_message {
163
+ display: none;
164
+ }
165
+ .tribe_settings .tribe-errors-list {
166
+ margin-left: 15px;
167
+ }
168
+ .tribe_settings .expiring-license {
169
+ color: red;
170
+ }
171
+ .tribe_settings .tribe-error {
172
+ border: 1px solid #f00;
173
+ }
174
+ .tribe_settings .tribe-field-description {
175
+ margin-bottom: 0;
176
+ position: relative;
177
+ top: -12px;
178
+ }
179
+ .tribe_settings #ical-link {
180
+ top: -14px;
181
+ }
182
+ .tribe-settings-form #tribe-field-stylesheetOption label {
183
+ margin-left: 20px;
184
+ }
185
+ .tribe-settings-form #tribe-field-stylesheetOption input {
186
+ margin-left: -20px;
187
+ margin-right: 8px;
188
+ }
189
+ .tribe-settings-form #tribe-field-stylesheetOption p.description {
190
+ color: #999;
191
+ }
192
+ /* Modern Tribe box */
193
+ #modern-tribe-info {
194
+ -khtml-border-radius: 4px;
195
+ background-color: #f9f9f9;
196
+ border: 1px solid #ccc;
197
+ -webkit-border-radius: 4px;
198
+ -moz-border-radius: 4px;
199
+ -o-border-radius: 4px;
200
+ border-radius: 4px;
201
+ margin: 20px 0;
202
+ padding: 8px 20px 12px;
203
+ }
204
+ #modern-tribe-info img {
205
+ height: 18px;
206
+ margin: 10px 0;
207
+ width: 250px;
208
+ }
209
+ #modern-tribe-info ul {
210
+ list-style: disc;
211
+ margin-left: 20px;
212
+ }
213
+ #modern-tribe-info ul ul {
214
+ list-style: circle;
215
+ }
216
+
217
+ /* sizes */
218
+ .tribe-field-textarea.tribe-size-small textarea {
219
+ height: 60px;
220
+ width: 180px;
221
+ }
222
+ .tribe-field-textarea.tribe-size-medium textarea {
223
+ height: 80px;
224
+ width: 300px;
225
+ }
226
+ .tribe-field-textarea.tribe-size-large textarea {
227
+ height: 120px;
228
+ width: 450px;
229
+ }
230
+
231
+ .tribe-field-text.tribe-size-small input,
232
+ .tribe-field-license_key.tribe-size-small input {
233
+ width: 50px;
234
+ }
235
+ .tribe-field-text.tribe-size-medium input,
236
+ .tribe-field-license_key.tribe-size-medium input {
237
+ width: 225px;
238
+ }
239
+ .tribe-field-text.tribe-size-large input,
240
+ .tribe-field-license_key.tribe-size-large input {
241
+ width: 450px;
242
+ }
243
+
244
+ .tribe-field-dropdown.tribe-size-small select {
245
+ width: 100px;
246
+ }
247
+ .tribe-field-dropdown.tribe-size-medium select {
248
+ width: 300px;
249
+ }
250
+ .tribe-field-dropdown.tribe-size-large select {
251
+ width: 450px;
252
+ }
253
+
254
+ .tribe-field-dropdown_chosen.tribe-size-small select {
255
+ width: 100px;
256
+ }
257
+ .tribe-field-dropdown_chosen.tribe-size-medium select {
258
+ width: 200px;
259
+ }
260
+ .tribe-field-dropdown_chosen.tribe-size-large select {
261
+ width: 300px;
262
+ }
263
+
264
+ /* license keys */
265
+ .ajax-loading-license,
266
+ .valid-key,
267
+ .invalid-key {
268
+ display: none;
269
+ margin: 0 5px;
270
+ }
271
+ .ajax-loading-license {
272
+ position: relative;
273
+ top: 5px;
274
+ }
275
+ .key-validity {
276
+ display: inline-block;
277
+ }
278
+ .invalid-key {
279
+ color: red;
280
+ }
281
+ .valid-key {
282
+ color: green;
283
+ }
284
+ .valid-key.service-msg {
285
+ color: #b72;
286
+ }
287
+
288
+ /* additional fields */
289
+ #additional-field-table {
290
+ margin-bottom: 20px;
291
+ }
292
+
293
+ /* miscellaneous */
294
+ .tribe-admin-box-left {
295
+ -khtml-border-radius: 4px;
296
+ background-color: #f9f9f9;
297
+ border: 1px solid #ccc;
298
+ -webkit-border-radius: 4px;
299
+ -moz-border-radius: 4px;
300
+ -o-border-radius: 4px;
301
+ border-radius: 4px;
302
+ float: left;
303
+ margin: 20px 0;
304
+ padding: 0 20px 15px;
305
+ width: 20%;
306
+ }
307
+ .tribe-admin-box-right {
308
+ -khtml-border-radius: 4px;
309
+ background-color: #f9f9f9;
310
+ border: 1px solid #ccc;
311
+ -webkit-border-radius: 4px;
312
+ -moz-border-radius: 4px;
313
+ -o-border-radius: 4px;
314
+ border-radius: 4px;
315
+ float: right;
316
+ margin: 20px 0;
317
+ padding: 0 20px 15px;
318
+ width: 68%;
319
+ }
320
+ .ajax-loader {
321
+ float: right;
322
+ margin: 10px;
323
+ }
324
+ .tribe-arrangeable-item {
325
+ border: 1px solid lightGrey;
326
+ -moz-border-radius: 6px;
327
+ border-radius: 6px;
328
+ }
329
+ .tribe-arrangeable-item .ui-state-default {
330
+ border: none;
331
+ }
332
+ .tribe-arrangeable-item-top {
333
+ padding: 6px;
334
+ }
335
+ .tribe-arrangeable-item-top:hover {
336
+ cursor: move;
337
+ }
338
+ .tribe-arrangeable-action {
339
+ float: right;
340
+ }
341
+ .tribe-arrangeable-child {
342
+ background-color: #f9f9f9;
343
+ border-top: 1px solid lightGrey;
344
+ display: none;
345
+ padding: 25px;
346
+ }
347
+ .tribe-arrangeable-child label {
348
+ display: block;
349
+ margin: 0 0 7px 0;
350
+ }
351
+ .tribe_events_active_filter_type_options {
352
+ margin: 10px 0;
353
+ }
354
+ .tribe_events_active_filter_type_options label {
355
+ margin: 7px 0;
356
+ }
357
+ .tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection {
358
+ m