The Events Calendar - Version 5.1.2.1

Version Description

= [5.0] =

Please see the changelog for the complete list of changes in this release. Previous versions of The Events Calendar are not cross-compatible with 5.X add-ons. Remember to always make a backup of your database and files before updating!

Download this release

Release Info

Developer borkweb
Plugin Icon The Events Calendar
Version 5.1.2.1
Comparing to
See all releases

Code changes from version 5.1.2 to 5.1.2.1

common/src/resources/js/dropdowns.js CHANGED
@@ -49,9 +49,6 @@ var tribe_dropdowns = window.tribe_dropdowns || {};
49
  return null;
50
  };
51
 
52
- obj.allow_html_markup = function ( m ) {
53
- return m;
54
- };
55
 
56
  /**
57
  * Better Search ID for Select2, compatible with WordPress ID from WP_Query
@@ -266,7 +263,7 @@ var tribe_dropdowns = window.tribe_dropdowns || {};
266
 
267
  // Don't Remove HTML elements or escape elements
268
  if ( $select.is( '[data-allow-html]' ) ) {
269
- args.escapeMarkup = obj.allow_html_markup;
270
  }
271
 
272
  // If we are dealing with a Input Hidden we need to set the Data for it to work.
@@ -356,7 +353,7 @@ var tribe_dropdowns = window.tribe_dropdowns || {};
356
  args.data = { results: [] };
357
 
358
  // Allows HTML from Select2 AJAX calls
359
- args.escapeMarkup = obj.allow_html_markup;
360
 
361
  // Format for Parents breadcrumbs
362
  args.formatResult = function ( item, container, query ) {
49
  return null;
50
  };
51
 
 
 
 
52
 
53
  /**
54
  * Better Search ID for Select2, compatible with WordPress ID from WP_Query
263
 
264
  // Don't Remove HTML elements or escape elements
265
  if ( $select.is( '[data-allow-html]' ) ) {
266
+
267
  }
268
 
269
  // If we are dealing with a Input Hidden we need to set the Data for it to work.
353
  args.data = { results: [] };
354
 
355
  // Allows HTML from Select2 AJAX calls
356
+
357
 
358
  // Format for Parents breadcrumbs
359
  args.formatResult = function ( item, container, query ) {
common/src/resources/js/dropdowns.min.js CHANGED
@@ -1 +1,509 @@
1
- var tribe_dropdowns=window.tribe_dropdowns||{};!function(e,t,r){"use strict";t.selector={dropdown:".tribe-dropdown",created:".tribe-dropdown-created",searchField:".select2-search__field"},e.fn.tribe_dropdowns=function(){return t.dropdown(this,{}),this},t.freefrom_create_search_choice=function(t){var a=e.trim(t.term);if(""===a)return null;var o=this.options.options,s=o.$select;if(a.match(o.regexToken)&&(!s.is("[data-int]")||s.is("[data-int]")&&a.match(/\d+/))){var i={id:a,text:a,new:!0};return s.is("[data-create-choice-template]")&&(i.text=r.template(s.data("createChoiceTemplate"))({term:a})),i}return null},t.allow_html_markup=function(e){return e},t.search_id=function(e){var t=void 0;return void 0!==e.id?t=e.id:void 0!==e.ID?t=e.ID:void 0!==e.value&&(t=e.value),void 0===e?void 0:t},t.matcher=function(a,o){if(""===e.trim(a.term))return o;if(void 0===o.text)return null;var s=e.trim(a.term),i=o.text,n=e(o.element).closest("select").data("dropdown"),d=-1!==i.toUpperCase().indexOf(s.toUpperCase());if(!d&&void 0!==n.tags){var l=r.where(n.tags,{text:i});if(n.tags.length>0&&r.isObject(l))d=-1!==t.search_id(l[0]).toUpperCase().indexOf(s.toUpperCase())}return d},t.init_selection=function(t,r){var a=t.is("[multiple]"),o=t.data("dropdown"),s=(t.data("isEmpty"),t.val().split(o.regexSplit)),i=[];if(e(s).each(function(r,a){var s=function t(r,a){if(!e.isArray(a))return!1;for(var o in a){var s=a[o];if(s.hasOwnProperty("id")&&s.id==r.id)return s;if(s.hasOwnProperty("text")&&s.text==r.text)return s;if(s.hasOwnProperty("children")&&e.isArray(s.children)){var i=t(r,s.children);if(i)return i}}return!1}({id:this,text:this},o.ajax?t.data("options"):o.data);s&&s.selected&&i.push(s)}),i.length&&a)r(i);else{if(!i.length)return void r(!1);r(i[0])}},t.getSelectClasses=function(e){var t=e.attr("class").split(/\s+/);return r.difference(t,["select2-hidden-accessible","hide-before-select2-init"])},t.element=function(a,o){var s,i=e(a);o=e.extend({},o);if(i.addClass(t.selector.created.className()),o.$select=i,o.dropdownAutoWidth=!0,o.width="resolve",o.containerCss={},i.is(":visible")&&(o.containerCss.display="inline-block",o.containerCss.position="relative"),o.dropdownCss={},o.dropdownCss.width="auto",i.is("[data-dropdown-css-width]")&&(o.dropdownCss.width=i.data("dropdown-css-width"),o.dropdownCss.width&&"false"!==o.dropdownCss.width||(delete o.dropdownCss.width,delete o.containerCss)),o.allowClear=!0,i.is("[data-prevent-clear]")&&(o.allowClear=!1),i.is("[data-searching-placeholder]")&&(o.formatSearching=i.data("searching-placeholder")),!i.is("[data-placeholder]")&&i.is("[placeholder]")&&(o.placeholder=i.attr("placeholder")),i.is("[data-allow-html]")&&(o.escapeMarkup=t.allow_html_markup),i.is("[data-options]")&&(o.data=i.data("options")),o.minimumResultsForSearch=10,i.is("[data-hide-search]")&&(o.minimumResultsForSearch=1/0),i.is("[data-force-search]")&&delete o.minimumResultsForSearch,i.is("[data-freeform]")&&(o.createTag=t.freefrom_create_search_choice,o.tags=!0,i.data("tags",!0)),i.is("[multiple]")&&(o.multiple=!0,i.is("[data-maximum-selection-size]")&&(o.maximumSelectionSize=i.data("maximum-selection-size")),i.is("data-separator")||i.data("separator",","),r.isArray(i.data("separator"))?o.tokenSeparators=i.data("separator"):o.tokenSeparators=[i.data("separator")],o.separator=i.data("separator"),o.regexSeparatorElements=["^("],o.regexSplitElements=["(?:"],e.each(o.tokenSeparators,function(e,t){o.regexSeparatorElements.push("[^"+t+"]+"),o.regexSplitElements.push("["+t+"]")}),o.regexSeparatorElements.push(")$"),o.regexSplitElements.push(")"),o.regexSeparatorString=o.regexSeparatorElements.join(""),o.regexSplitString=o.regexSplitElements.join(""),o.regexToken=new RegExp(o.regexSeparatorString,"ig"),o.regexSplit=new RegExp(o.regexSplitString,"ig")),i.is("[data-tags]")&&(o.tags=i.data("tags"),o.createSearchChoice=function(e,t){if(e.match(o.regexToken))return{id:e,text:e}},0===o.tags.length&&(o.formatNoMatches=function(){return i.attr("placeholder")})),i.is("[data-source]")){var n=i.data("source");o.data={results:[]},o.escapeMarkup=t.allow_html_markup,o.formatResult=function(t,r,a){return void 0!==t.breadcrumbs?e.merge(t.breadcrumbs,[t.text]).join(" » "):t.text},o.ajax={dataType:"json",type:"POST",url:t.ajaxurl(),processResults:function(t,r,a){return e.isPlainObject(t)&&void 0!==t.success?e.isPlainObject(t.data)&&void 0!==t.data.results?t.success?t.data:("string"===e.type(t.data.message)?console.error(t.data.message):console.error("The Select2 search failed in some way... Verify the source."),{results:[]}):(console.error("We received a malformed results array, could not complete the Select2 Search."),{results:[]}):(console.error("We received a malformed Object, could not complete the Select2 Search."),{results:[]})}},o.ajax.data=function(e,t){return{action:"tribe_dropdown",source:n,search:e,page:t,args:i.data("source-args")}}}i.data("dropdown",o),(s=i.select2(o)).data("select2").$container.addClass(t.getSelectClasses(i).join(" ")),s.data("select2").$container.removeClass("hide-before-select2-init"),s.on("select2:open",t.action_select2_open)},t.ajaxurl=function(){return void 0!==window.ajaxurl?window.ajaxurl:"undefined"!=typeof TEC&&void 0!==TEC.ajaxurl?TEC.ajaxurl:void console.error("Dropdowns framework cannot properly do an AJAX request without the WordPress `ajaxurl` variable setup.")},t.action_select2_open=function(r){var a=e(this),o=(a.data("dropdown"),a.data("select2")),s=o.$dropdown.find(t.selector.searchField);o.$dropdown.addClass(t.selector.dropdown.className()),a.is("[data-search-placeholder]")&&s.attr("placeholder",a.data("searchPlaceholder"))},t.dropdown=function(e,r){var a=e.not(".select2-offscreen, .select2-container, "+t.selector.created.className());return 0===a.length?a:(r||(r={}),a.each(function(e,a){t.element(a,r)}),a)},e(function(){e(t.selector.dropdown).tribe_dropdowns()}),e(window).on("unload",function(){e(t.selector.dropdown).tribe_dropdowns()})}(jQuery,tribe_dropdowns,window.underscore||window._);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global console, jQuery */
2
+ var tribe_dropdowns = window.tribe_dropdowns || {};
3
+
4
+ ( function( $, obj, _ ) {
5
+ 'use strict';
6
+
7
+ obj.selector = {
8
+ dropdown: '.tribe-dropdown',
9
+ created: '.tribe-dropdown-created',
10
+ searchField: '.select2-search__field',
11
+ };
12
+
13
+ // Setup a Dependent
14
+ $.fn.tribe_dropdowns = function () {
15
+ obj.dropdown( this, {} );
16
+
17
+ return this;
18
+ };
19
+
20
+ obj.freefrom_create_search_choice = function( params ) {
21
+ var term = $.trim( params.term );
22
+
23
+ if ( '' === term ) {
24
+ return null;
25
+ }
26
+
27
+ var args = this.options.options;
28
+ var $select = args.$select;
29
+
30
+ if (
31
+ term.match( args.regexToken )
32
+ && (
33
+ ! $select.is( '[data-int]' )
34
+ || (
35
+ $select.is( '[data-int]' )
36
+ && term.match( /\d+/ )
37
+ )
38
+ )
39
+ ) {
40
+ var choice = { id: term, text: term, new: true };
41
+
42
+ if ( $select.is( '[data-create-choice-template]' ) ) {
43
+ choice.text = _.template( $select.data( 'createChoiceTemplate' ) )( { term: term } );
44
+ }
45
+
46
+ return choice;
47
+ }
48
+
49
+ return null;
50
+ };
51
+
52
+
53
+ /**
54
+ * Better Search ID for Select2, compatible with WordPress ID from WP_Query
55
+ *
56
+ * @param {object|string} e Searched object or the actual ID
57
+ * @return {string} ID of the object
58
+ */
59
+ obj.search_id = function ( e ) {
60
+ var id = undefined;
61
+
62
+ if ( 'undefined' !== typeof e.id ){
63
+ id = e.id;
64
+ } else if ( 'undefined' !== typeof e.ID ){
65
+ id = e.ID;
66
+ } else if ( 'undefined' !== typeof e.value ){
67
+ id = e.value;
68
+ }
69
+ return undefined === e ? undefined : id;
70
+ };
71
+
72
+ /**
73
+ * Better way of matching results
74
+ *
75
+ * @param {string} term Which term we are searching for
76
+ * @param {string} text Search here
77
+ * @return {boolean}
78
+ */
79
+ obj.matcher = function ( params, data ) {
80
+ // If there are no search terms, return all of the data
81
+ if ( $.trim( params.term ) === '') {
82
+ return data;
83
+ }
84
+
85
+ // Do not display the item if there is no 'text' property
86
+ if ( typeof data.text === 'undefined' ) {
87
+ return null;
88
+ }
89
+
90
+ var term = $.trim( params.term );
91
+ var text = data.text;
92
+ var $select = $( data.element ).closest( 'select' );
93
+ var args = $select.data( 'dropdown' );
94
+ var result = text.toUpperCase().indexOf( term.toUpperCase() ) !== -1;
95
+
96
+ if ( ! result && 'undefined' !== typeof args.tags ){
97
+ var possible = _.where( args.tags, { text: text } );
98
+ if ( args.tags.length > 0 && _.isObject( possible ) ){
99
+ var test_value = obj.search_id( possible[0] );
100
+ result = test_value.toUpperCase().indexOf( term.toUpperCase() ) !== -1;
101
+ }
102
+ }
103
+
104
+ return result;
105
+ };
106
+
107
+ /**
108
+ * If the element used as the basis of a dropdown specifies one or more numeric/text
109
+ * identifiers in its val attribute, then use those to preselect the appropriate options.
110
+ *
111
+ * @param {object} $select
112
+ * @param {function} make_selection
113
+ */
114
+ obj.init_selection = function( $select, make_selection ) {
115
+ var isMultiple = $select.is( '[multiple]' );
116
+ var options = $select.data( 'dropdown' );
117
+ var isEmpty = $select.data( 'isEmpty' );
118
+ var currentValues = $select.val().split( options.regexSplit );
119
+ var selectedItems = [];
120
+
121
+ $( currentValues ).each( function( index, value ) {
122
+ var searchFor = { id: this, text: this };
123
+ var data = options.ajax ? $select.data( 'options' ) : options.data;
124
+ var locatedItem = find_item( searchFor, data );
125
+
126
+ if ( locatedItem && locatedItem.selected ) {
127
+ selectedItems.push( locatedItem );
128
+ }
129
+ } );
130
+
131
+ if ( selectedItems.length && isMultiple ) {
132
+ make_selection( selectedItems );
133
+ } else if ( selectedItems.length ) {
134
+ make_selection( selectedItems[ 0 ] );
135
+ } else {
136
+ make_selection( false );
137
+ return;
138
+ }
139
+ };
140
+
141
+ /**
142
+ * Searches array 'haystack' for objects that match 'description'.
143
+ *
144
+ * The 'description' object should take the form { id: number, text: string }. The first
145
+ * object within the haystack that matches one of those two properties will be returned.
146
+ *
147
+ * If objects contain an array named 'children', then that array will also be searched.
148
+ *
149
+ * @param {Object} description
150
+ * @param {Array} haystack
151
+ *
152
+ * @return {Object|boolean}
153
+ */
154
+ function find_item( description, haystack ) {
155
+ if ( ! $.isArray( haystack ) ) {
156
+ return false;
157
+ }
158
+
159
+ for ( var index in haystack ) {
160
+ var possible_match = haystack[ index ];
161
+
162
+ if ( possible_match.hasOwnProperty( 'id' ) && possible_match.id == description.id ) {
163
+ return possible_match;
164
+ }
165
+
166
+ if ( possible_match.hasOwnProperty( 'text' ) && possible_match.text == description.text ) {
167
+ return possible_match;
168
+ }
169
+
170
+ if ( possible_match.hasOwnProperty( 'children' ) && $.isArray( possible_match.children ) ) {
171
+ var subsearch = find_item( description, possible_match.children );
172
+
173
+ if ( subsearch ) {
174
+ return subsearch;
175
+ }
176
+ }
177
+ }
178
+
179
+ return false;
180
+ }
181
+
182
+ obj.getSelectClasses = function( $select ) {
183
+ var classesToRemove = [
184
+ 'select2-hidden-accessible',
185
+ 'hide-before-select2-init',
186
+ ];
187
+ var originalClasses = $select.attr( 'class' ).split( /\s+/ );
188
+ return _.difference( originalClasses, classesToRemove );
189
+ };
190
+
191
+ obj.element = function( field, args ) {
192
+ var $select = $( field );
193
+ var args = $.extend( {}, args );
194
+ var carryOverData = [
195
+ 'depends',
196
+ 'condition',
197
+ 'conditionNot',
198
+ 'condition-not',
199
+ 'conditionNotEmpty',
200
+ 'condition-not-empty',
201
+ 'conditionEmpty',
202
+ 'condition-empty',
203
+ 'conditionIsNumeric',
204
+ 'condition-is-numeric',
205
+ 'conditionIsNotNumeric',
206
+ 'condition-is-not-numeric',
207
+ 'conditionChecked',
208
+ 'condition-is-checked',
209
+ ];
210
+
211
+ var $container;
212
+
213
+ // Add a class for dropdown created
214
+ $select.addClass( obj.selector.created.className() );
215
+
216
+ // args.debug = true;
217
+
218
+ // For Reference we save the jQuery element as an Arg.
219
+ args.$select = $select;
220
+
221
+ // Auto define the Width of the Select2.
222
+ args.dropdownAutoWidth = true;
223
+ args.width = 'resolve';
224
+
225
+ // CSS for the container
226
+ args.containerCss = {};
227
+
228
+ // Only apply visibility when it's a Visible Select2.
229
+ if ( $select.is( ':visible' ) ) {
230
+ args.containerCss.display = 'inline-block';
231
+ args.containerCss.position = 'relative';
232
+ }
233
+
234
+ // CSS for the dropdown
235
+ args.dropdownCss = {};
236
+ args.dropdownCss.width = 'auto';
237
+
238
+ // When we have this we replace the default with what's in the param.
239
+ if ( $select.is( '[data-dropdown-css-width]' ) ) {
240
+ args.dropdownCss.width = $select.data( 'dropdown-css-width' );
241
+
242
+ if ( ! args.dropdownCss.width || 'false' === args.dropdownCss.width ) {
243
+ delete args.dropdownCss.width;
244
+ delete args.containerCss;
245
+ }
246
+ }
247
+
248
+ // By default we allow The field to be cleared
249
+ args.allowClear = true;
250
+ if ( $select.is( '[data-prevent-clear]' ) ) {
251
+ args.allowClear = false;
252
+ }
253
+
254
+ // Pass the "Searching..." placeholder if specified
255
+ if ( $select.is( '[data-searching-placeholder]' ) ) {
256
+ args.formatSearching = $select.data( 'searching-placeholder' );
257
+ }
258
+
259
+ // If we are dealing with a Input Hidden we need to set the Data for it to work
260
+ if ( ! $select.is( '[data-placeholder]' ) && $select.is( '[placeholder]' ) ) {
261
+ args.placeholder = $select.attr( 'placeholder' );
262
+ }
263
+
264
+ // Don't Remove HTML elements or escape elements
265
+ if ( $select.is( '[data-allow-html]' ) ) {
266
+
267
+ }
268
+
269
+ // If we are dealing with a Input Hidden we need to set the Data for it to work.
270
+ if ( $select.is( '[data-options]' ) ) {
271
+ args.data = $select.data( 'options' );
272
+ }
273
+
274
+ // With less then 10 args we wouldn't show the search.
275
+ args.minimumResultsForSearch = 10;
276
+
277
+ // Prevents the Search box to show
278
+ if ( $select.is( '[data-hide-search]' ) ) {
279
+ args.minimumResultsForSearch = Infinity;
280
+ }
281
+
282
+ // Makes sure search shows up.
283
+ if ( $select.is( '[data-force-search]' ) ) {
284
+ delete args.minimumResultsForSearch;
285
+ }
286
+
287
+ // Allows freeform entry
288
+ if ( $select.is( '[data-freeform]' ) ) {
289
+ args.createTag = obj.freefrom_create_search_choice;
290
+ args.tags = true;
291
+ $select.data( 'tags', true );
292
+ }
293
+
294
+ if ( $select.is( '[multiple]' ) ) {
295
+ args.multiple = true;
296
+
297
+ // Set the max select items, if defined
298
+ if ( $select.is( '[data-maximum-selection-size]' ) ) {
299
+ args.maximumSelectionSize = $select.data( 'maximum-selection-size' );
300
+ }
301
+
302
+ // If you don't have separator, add one (comma)
303
+ if ( ! $select.is( 'data-separator' ) ) {
304
+ $select.data( 'separator', ',' );
305
+ }
306
+
307
+ if ( ! _.isArray( $select.data( 'separator' ) ) ) {
308
+ args.tokenSeparators = [ $select.data( 'separator' ) ];
309
+ } else {
310
+ args.tokenSeparators = $select.data( 'separator' );
311
+ }
312
+ args.separator = $select.data( 'separator' );
313
+
314
+ // Define the regular Exp based on
315
+ args.regexSeparatorElements = [ '^(' ];
316
+ args.regexSplitElements = [ '(?:' ];
317
+ $.each( args.tokenSeparators, function ( i, token ) {
318
+ args.regexSeparatorElements.push( '[^' + token + ']+' );
319
+ args.regexSplitElements.push( '[' + token + ']' );
320
+ } );
321
+ args.regexSeparatorElements.push( ')$' );
322
+ args.regexSplitElements.push( ')' );
323
+
324
+ args.regexSeparatorString = args.regexSeparatorElements.join( '' );
325
+ args.regexSplitString = args.regexSplitElements.join( '' );
326
+
327
+ args.regexToken = new RegExp( args.regexSeparatorString, 'ig' );
328
+ args.regexSplit = new RegExp( args.regexSplitString, 'ig' );
329
+ }
330
+
331
+ // Select also allows Tags, so we go with that too
332
+ if ( $select.is( '[data-tags]' ) ) {
333
+ args.tags = $select.data( 'tags' );
334
+
335
+ args.createSearchChoice = function( term, data ) {
336
+ if ( term.match( args.regexToken ) ) {
337
+ return { id: term, text: term };
338
+ }
339
+ };
340
+
341
+ if ( 0 === args.tags.length ) {
342
+ args.formatNoMatches = function() {
343
+ return $select.attr( 'placeholder' );
344
+ };
345
+ }
346
+ }
347
+
348
+ // When we have a source, we do an AJAX call
349
+ if ( $select.is( '[data-source]' ) ) {
350
+ var source = $select.data( 'source' );
351
+
352
+ // For AJAX we reset the data
353
+ args.data = { results: [] };
354
+
355
+ // Allows HTML from Select2 AJAX calls
356
+
357
+
358
+ // Format for Parents breadcrumbs
359
+ args.formatResult = function ( item, container, query ) {
360
+ if ( 'undefined' !== typeof item.breadcrumbs ) {
361
+ return $.merge( item.breadcrumbs, [ item.text ] ).join( ' » ' );
362
+ }
363
+
364
+ return item.text;
365
+ };
366
+
367
+ // instead of writing the function to execute the request we use Select2's convenient helper.
368
+ args.ajax = {
369
+ dataType: 'json',
370
+ type: 'POST',
371
+ url: obj.ajaxurl(),
372
+
373
+ // parse the results into the format expected by Select2.
374
+ processResults: function ( response, page, query ) {
375
+ if ( ! $.isPlainObject( response ) || 'undefined' === typeof response.success ) {
376
+ console.error( 'We received a malformed Object, could not complete the Select2 Search.' );
377
+ return { results: [] };
378
+ }
379
+
380
+ if (
381
+ ! $.isPlainObject( response.data )
382
+ || 'undefined' === typeof response.data.results
383
+ ) {
384
+ console.error( 'We received a malformed results array, could not complete the Select2 Search.' );
385
+ return { results: [] };
386
+ }
387
+
388
+ if ( ! response.success ) {
389
+ if ( 'string' === $.type( response.data.message ) ) {
390
+ console.error( response.data.message );
391
+ } else {
392
+ console.error( 'The Select2 search failed in some way... Verify the source.' );
393
+ }
394
+ return { results: [] };
395
+ }
396
+
397
+ return response.data;
398
+ },
399
+ };
400
+
401
+ // By default only send the source
402
+ args.ajax.data = function( search, page ) {
403
+ return {
404
+ action: 'tribe_dropdown',
405
+ source: source,
406
+ search: search,
407
+ page: page,
408
+ args: $select.data( 'source-args' ),
409
+ };
410
+ };
411
+ }
412
+
413
+ // Save data on Dropdown
414
+ $select.data( 'dropdown', args );
415
+
416
+ $container = $select.select2( args );
417
+
418
+ // Propagating original input classes to the select2 container.
419
+ $container.data( 'select2' ).$container.addClass( obj.getSelectClasses( $select ).join( ' ' ) );
420
+
421
+ // Propagating original input classes to the select2 container.
422
+ $container.data( 'select2' ).$container.removeClass( 'hide-before-select2-init' );
423
+
424
+ $container.on( 'select2:open', obj.action_select2_open );
425
+
426
+ /**
427
+ * @todo @bordoni Investigate how and if we should be doing this.
428
+ *
429
+ if ( carryOverData.length > 0 ) {
430
+ carryOverData.map( function( dataKey ) {
431
+ var attr = 'data-' + dataKey;
432
+ var val = $select.attr( attr );
433
+
434
+ if ( ! val ) {
435
+ return;
436
+ }
437
+
438
+ this.attr( attr, val );
439
+ }, $container );
440
+ }
441
+ */
442
+ };
443
+
444
+ obj.ajaxurl = function() {
445
+ if ( 'undefined' !== typeof window.ajaxurl ) {
446
+ return window.ajaxurl;
447
+ }
448
+
449
+ if ( 'undefined' !== typeof TEC && 'undefined' !== typeof TEC.ajaxurl ) {
450
+ return TEC.ajaxurl;
451
+ }
452
+
453
+ console.error( 'Dropdowns framework cannot properly do an AJAX request without the WordPress `ajaxurl` variable setup.' );
454
+ };
455
+
456
+ obj.action_select2_open = function( event ) {
457
+ var $select = $( this );
458
+ var args = $select.data( 'dropdown' );
459
+ var select2Data = $select.data( 'select2' );
460
+ var $search = select2Data.$dropdown.find( obj.selector.searchField );
461
+
462
+ select2Data.$dropdown.addClass( obj.selector.dropdown.className() );
463
+
464
+ // If we have a placeholder for search, apply it!
465
+ if ( $select.is( '[data-search-placeholder]' ) ) {
466
+ $search.attr( 'placeholder', $select.data( 'searchPlaceholder' ) );
467
+ }
468
+ };
469
+
470
+ /**
471
+ * Configure the Drop Down Fields
472
+ *
473
+ * @param {jQuery} $fields All the fields from the page
474
+ * @param {array} args Allow extending the arguments
475
+ *
476
+ * @return {jQuery} Affected fields
477
+ */
478
+ obj.dropdown = function( $fields, args ) {
479
+ var $elements = $fields.not( '.select2-offscreen, .select2-container, ' + obj.selector.created.className() );
480
+
481
+ if ( 0 === $elements.length ) {
482
+ return $elements;
483
+ }
484
+
485
+ // Default args to avoid Undefined
486
+ if ( ! args ) {
487
+ args = {};
488
+ }
489
+
490
+ $elements
491
+ .each( function( index, element ) {
492
+ // Apply element to all given items and pass args
493
+ obj.element( element, args );
494
+ } );
495
+
496
+ // return to be able to chain jQuery calls
497
+ return $elements;
498
+ };
499
+
500
+ $( function() {
501
+ $( obj.selector.dropdown ).tribe_dropdowns();
502
+ } );
503
+
504
+ // Addresses some problems with Select2 inputs not being initialized when using a browser's "Back" button.
505
+ $( window ).on( 'unload', function() {
506
+ $( obj.selector.dropdown ).tribe_dropdowns();
507
+ });
508
+
509
+ } )( jQuery, tribe_dropdowns, window.underscore || window._ );
readme.txt CHANGED
@@ -4,7 +4,7 @@ Contributors: ModernTribe, borkweb, barry.hughes, bordoni, brianjessee, aguseo,
4
  Tags: events, calendar, event, venue, organizer, dates, date, google maps, conference, workshop, concert, meeting, seminar, summit, class, modern tribe, tribe, widget
5
  Donate link: https://m.tri.be/29
6
  Requires at least: 4.9
7
- Stable tag: 5.1.2
8
  Tested up to: 5.4.1
9
  Requires PHP: 5.6
10
  License: GPLv2 or later
@@ -221,6 +221,10 @@ Remember to always make a backup of your database and files before updating!
221
 
222
  == Changelog ==
223
 
 
 
 
 
224
  = [5.1.2] 2020-05-27 =
225
 
226
  * Tweak - Prevent undefined errors when using tribe_get_events and forcing a cache refresh.
@@ -1868,3 +1872,4 @@ Remember to always make a backup of your database and files before updating!
1868
  = 3.x and previous =
1869
 
1870
  For release notes from the 3.x and older lifecycles, see our [full historical release notes](https://theeventscalendar.com/category/products/release-notes/).
 
4
  Tags: events, calendar, event, venue, organizer, dates, date, google maps, conference, workshop, concert, meeting, seminar, summit, class, modern tribe, tribe, widget
5
  Donate link: https://m.tri.be/29
6
  Requires at least: 4.9
7
+ Stable tag: 5.1.2.1
8
  Tested up to: 5.4.1
9
  Requires PHP: 5.6
10
  License: GPLv2 or later
221
 
222
  == Changelog ==
223
 
224
+ = [5.1.2.1] 2020-06-09 =
225
+
226
+ * Security - Remove deprecated usage of escapeMarkup in Select2 (props to miha.jirov for reporting this).
227
+
228
  = [5.1.2] 2020-05-27 =
229
 
230
  * Tweak - Prevent undefined errors when using tribe_get_events and forcing a cache refresh.
1872
  = 3.x and previous =
1873
 
1874
  For release notes from the 3.x and older lifecycles, see our [full historical release notes](https://theeventscalendar.com/category/products/release-notes/).
1875
+
src/Tribe/Main.php CHANGED
@@ -33,7 +33,7 @@ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
33
  const VENUE_POST_TYPE = 'tribe_venue';
34
  const ORGANIZER_POST_TYPE = 'tribe_organizer';
35
 
36
- const VERSION = '5.1.2';
37
 
38
  /**
39
  * Min Pro Addon
33
  const VENUE_POST_TYPE = 'tribe_venue';
34
  const ORGANIZER_POST_TYPE = 'tribe_organizer';
35
 
36
+ const VERSION = '5.1.2.1';
37
 
38
  /**
39
  * Min Pro Addon
src/resources/js/aggregator-fields.js CHANGED
@@ -909,7 +909,7 @@ tribe_aggregator.fields = {
909
  var args = {
910
  formatResult: upsellFormatter,
911
  formatSelection: upsellFormatter,
912
- escapeMarkup: function( m ) {return m; },
913
  };
914
 
915
  tribe_dropdowns.dropdown( $fields.filter( '.tribe-ea-dropdown' ), args );
909
  var args = {
910
  formatResult: upsellFormatter,
911
  formatSelection: upsellFormatter,
912
+
913
  };
914
 
915
  tribe_dropdowns.dropdown( $fields.filter( '.tribe-ea-dropdown' ), args );
src/resources/js/aggregator-fields.min.js CHANGED
@@ -1 +1,1225 @@
1
- var tribe_aggregator=tribe_aggregator||{};tribe_aggregator.fields={selector:{container:".tribe-ea",form:".tribe-ea-form",help:".tribe-ea-help",fields:".tribe-ea-field",dropdown:".tribe-ea-dropdown",origin_field:"#tribe-ea-field-origin",field_url_source:"#tribe-ea-field-url_source",eventbrite_url_source:"#tribe-ea-field-eventbrite_source",post_status:".tribe-ea-field-post_status",import_type_field:".tribe-import-type",media_button:".tribe-ea-media_button",datepicker:".tribe-datepicker",save_credentials_button:".enter-credentials .tribe-save",preview_container:".tribe-preview-container",preview_button:".tribe-preview:visible",refine_filters:".tribe-refine-filters",clear_filters_button:".tribe-clear-filters",finalize_button:".tribe-finalize",cancel_button:".tribe-cancel",schedule_delete_link:".tribe-ea-tab-scheduled a.submitdelete",tab_new:".tribe-ea-tab-new",action:"#tribe-action",view_filters:".tribe-view-filters"},media:{},$:{},construct:{},events:{},import_id:null,result_fetch_count:0,max_result_fetch_count:15,polling_frequency_index:0,polling_frequencies:[500,1e3,5e3,2e4],progress:{},eventbrite:{refineControls:".tribe-refine-filters.eventbrite, .tribe-refine-filters.eventbrite .tribe-refine",refineControlsHideMap:{event:"tr.tribe-refine-filters",organizer:""},detect_type:function(e){if(!tribe_aggregator.source_origin_regexp.eventbrite)return null;var t=tribe_aggregator.source_origin_regexp.eventbrite,r={event:t+"e/[A-z0-9_-]+",organizer:t+"o/[A-z0-9_-]+"},i=void 0;return _.each(r,function(t,r){null!==new RegExp(t,"g").exec(e)&&(i=r)}),i}}},function(e,t,r,i){"use strict";r.init=function(){r.$.container=e(r.selector.container),r.$.form=e(r.selector.form),r.$.action=e(r.selector.action),r.$.fields=r.$.container.find(r.selector.fields),r.$.preview_container=e(r.selector.preview_container),r.origin=e("#tribe-ea-field-origin"),r.importType=e("#tribe-ea-field-url_import_type"),r.urlImport={startDate:e("#tribe-ea-field-url_start"),originalMinDate:e("#tribe-ea-field-url_start").datepicker("option","minDate")||""},e.each(r.construct,function(e,t){t(r.$.fields)});var a=e(document.getElementById("eventDetails"));a.data("datepicker_format")&&(tribe_ev.state.datepicker_format=a.data("datepicker_format")),e(document).on("keypress",r.selector.fields,r.events.trigger_field_change).on("click",r.selector.save_credentials_button,r.events.trigger_save_credentials).on("click",r.selector.clear_filters_button,r.clear_filters).on("click",r.selector.finalize_button,r.finalize_manual_import).on("click",r.selector.preview_button,r.preview_import).on("click",r.selector.cancel_button,r.events.cancel_edit).on("click",r.selector.schedule_delete_link,r.events.verify_schedule_delete).on("click",r.selector.view_filters,r.events.toggle_view_filters).on("blur",r.selector.datepicker,r.date_helper).on("submit",r.selector.tab_new,r.events.suppress_submission).on("change",r.selector.import_type_field,function(){r.reset_preview();var t=e(this),i=e(this).next(r.selector.fields),a=t.val();i.val("schedule"===a?"daily":"").change(),r.$.form.attr("data-type",a),r.maybeLimitUrlStartDate()}).on("change",r.selector.origin_field,function(){var t=e(this),a=(e(this).data("select2"),t.val());r.$.form.attr("data-origin",a),r.reset_preview(),e(".tribe-bumpdown-active").removeClass("tribe-bumpdown-active"),e(".tribe-bumpdown:visible").hide(),"redirect"===e(this).val()&&(window.open("https://theeventscalendar.com/wordpress-event-aggregator/?utm_source=importoptions&utm_medium=plugin-tec&utm_campaign=in-app","_blank"),location.reload()),""!==a&&e(r.selector.post_status).val(i.default_settings[a].post_status).trigger("change"),r.maybeLimitUrlStartDate()}).on("change",r.selector.eventbrite_url_source,function(t){e(r.eventbrite.refineControls).show();var i=r.eventbrite.detect_type(e("#tribe-ea-field-eventbrite_source").val());if(i){var a=r.eventbrite.refineControlsHideMap[i];a&&e(a).hide()}}).on("change",r.selector.field_url_source,function(a){var n=e(this),s=(e(this).data("select2"),n.val()),o=null;if(s&&(t.each(i.source_origin_regexp,function(e,t){null!==new RegExp(e,"g").exec(s)&&(o=t)}),null!=o)){var l=e(r.selector.origin_field);if(l.find('option[value="'+o+'"]').length){var c=e("#tribe-ea-field-url_import_type"),d=c.val(),_=null;"schedule"===d&&(_=e("#tribe-ea-field-url_import_frequency").val()),c.val(""),l.val(o).trigger("change"),e("#tribe-ea-field-"+o+"_import_type").val(d).trigger("change"),"schedule"===d&&e("#tribe-ea-field-"+o+"_import_frequency").val(_).trigger("change"),"eventbrite"===o&&(e("#tribe-ea-field-"+o+"_source_type_url").trigger("click"),e("#tribe-ea-field-"+o+"_import_source").val("source_type_url").trigger("change")),e("#tribe-ea-field-"+o+"_source").val(s).trigger("change")}}}),e(".tribe-dependency").change(),tribe_timepickers.setup_timepickers(e(tribe_timepickers.selector.timepicker)),"edit"===r.$.action.val()&&(r.$.form.addClass("edit-form"),e(r.selector.finalize_button).html(i.l10n.edit_save)),"object"==typeof tribe_aggregator_save&&r.progress.init()},r.preview_import=function(t){t.preventDefault();var i=e(".tribe-ea-form.tribe-validation");if(r.reset_post_status(),i.trigger("validation.tribe"),!tribe.validation.hasErrors(i)){r.reset_polling_counter();e(".tribe-fetch-warning-message").html("");var a=e("#tribe-post_id");a.data("value",a.val()),a.val("");var n=e("#tribe-import_id");n.data("value",n.val()),n.val("");var s=e(r.selector.preview_button),o=(i=s.closest("form")).serialize();a.val(a.data("value")),n.val(a.data("value")),r.$.preview_container.addClass("tribe-fetching").removeClass("tribe-fetch-error"),r.$.form.removeClass("show-data"),s.prop("disabled",!0);var l=e(".dataTable").data("table");void 0!==l&&l.clear().draw(),"edit"===r.$.action.val()?r.preview_save_import(o):r.create_import(o)}},r.reset_post_status=function(){var t=e(r.selector.origin_field),a=0===t.length?"":t.val();""!==a&&e(r.selector.post_status).val(i.default_settings[a].post_status).trigger("change")},r.reset_polling_counter=function(){r.polling_frequency_index=0,r.result_fetch_count=0},r.reset_form=function(){r.$.fields.val("").trigger("change"),e('[id$="import_frequency"]').val("daily").trigger("change"),r.$.form.removeClass("show-data")},r.reset_preview=function(){r.$.form.removeClass("show-data"),e(".tribe-fetched, .tribe-fetching, .tribe-fetch-error").removeClass("tribe-fetched tribe-fetching tribe-fetch-error")},r.clear_filters=function(){e(r.selector.refine_filters).find("input, select").val("").trigger("change")},r.preview_save_import=function(t){e.ajax({type:"POST",url:ajaxurl+"?action=tribe_aggregator_preview_import",data:t,dataType:"json"}).done(r.handle_preview_create_results)},r.create_import=function(t){e.ajax({type:"POST",url:ajaxurl+"?action=tribe_aggregator_create_import",data:t,dataType:"json"}).done(r.handle_preview_create_results)},r.handle_preview_create_results=function(a){if(!a.success){var n=a.data;return t.isString(n)||(n=n.message),void r.display_fetch_error(["<b>",i.l10n.preview_fetch_error_prefix,"</b>"," "+n].join(" "))}if(r.import_id=a.data.data.import_id,e("#tribe-import_id").val(r.import_id),void 0!==a.data.data.items)return r.init_datatable(a.data.data),void r.$.preview_container.removeClass("tribe-fetching").addClass("tribe-fetched");r.$.container.find(".spinner-message").html(i.l10n.preview_polling[0]),setTimeout(r.poll_for_results,r.polling_frequencies[r.polling_frequency_index])},r.poll_for_results=function(){r.result_fetch_count++,e.ajax({type:"GET",url:ajaxurl+"?action=tribe_aggregator_fetch_import&import_id="+r.import_id,dataType:"json"}).done(function(t){if(void 0!==t.data.warning&&t.data.warning){var a=t.data.warning;r.display_fetch_warning(["<b>",i.l10n.preview_fetch_warning_prefix,"</b>"," "+a].join(" "))}var n;if(!t.success)return void 0!==t.data.message?n=t.data.message:void 0!==t.data[0].message&&(n=t.data[0].message),void r.display_fetch_error(["<b>",i.l10n.preview_fetch_error_prefix,"</b>"," "+n].join(" "));"error"===t.data.status?r.display_fetch_error(t.data.message):"success"!==t.data.status?(r.result_fetch_count>r.max_result_fetch_count&&(r.polling_frequency_index++,r.$.container.find(".spinner-message").html(i.l10n.preview_polling[r.polling_frequency_index]),r.result_fetch_count=0),void 0===r.polling_frequencies[r.polling_frequency_index]?r.display_fetch_error(i.l10n.preview_timeout):setTimeout(r.poll_for_results,r.polling_frequencies[r.polling_frequency_index])):(t.data.data.items=t.data.data.events,r.init_datatable(t.data.data),r.$.preview_container.removeClass("tribe-fetching").addClass("tribe-fetched"),e(r.selector.preview_button).prop("disabled",!1))})},r.init_datatable=function(t){var a=!1,n="csv"===(x=e(r.selector.origin_field).val()),s=e('[id$="import_type"]:visible'),o="manual";if(void 0!==i.default_settings[x])for(var l in i.default_settings[x]){if(i.default_settings[x].hasOwnProperty(l))e("#tribe-ea-field-"+l).val(i.default_settings[x][l]).trigger("change")}if(s.length&&(o=e("#"+s.first().attr("id").replace("s2id_","")).val()),"manual"!==o||t.items.length){s.length&&"manual"!==o||(a=!0);var c=r.$.preview_container.find(".data-container table"),d=[];for(var _ in t.items){var p=t.items[_];p.checkbox=a?'<input type="checkbox">':"",p.all_day?p.start_time=i.l10n.all_day:(void 0!==p.start_meridian&&p.start_meridian||(parseInt(p.start_hour,10)>11?p.start_meridian=i.l10n.pm:p.start_meridian=i.l10n.am),p.start_hour>12&&(p.start_hour=p.start_hour-12),p.start_time=(0===parseInt(p.start_hour,10)?12:p.start_hour)+":"+("00"+p.start_minute).slice(-2),p.start_time+=" "+p.start_meridian),d.push(p)}a&&!n?c.addClass("display-checkboxes"):c.removeClass("display-checkboxes"),r.$.form.addClass("show-data");var u,f={lengthMenu:[[5,10,25,50,-1],[5,10,25,50,tribe_l10n_datatables.pagination.all]],order:[[1,"asc"]],columnDefs:[{cellType:"th",className:"check-column",orderable:!1,targets:0}],data:d};if(void 0!==t.columns){f.columns=[{data:"checkbox"}];var g=c.find("thead tr"),v=c.find("tfoot tr"),m=e({}),b="",h="";if(g.find("th:first").nextAll().remove(),v.find("th:first").nextAll().remove(),n){var w=c.closest(".data-container");c.closest(".data-container").addClass("csv-data"),w.find(".tribe-preview-message .tribe-csv-filename").html(e("#tribe-ea-field-csv_file_name").text()),g.closest("thead").prepend('<tr class="tribe-column-map"><th scope="row" class="check-column column-cb"></th></tr>'),m=e(".tribe-column-map"),h=(h=e("#tribe-ea-field-csv_content_type").val()).replace("tribe_",""),b=e("#tribe-csv-column-map-"+h).html()}var y=0;for(_ in t.columns){if(f.columns.push({data:t.columns[_]}),g.append('<th scope="col">'+t.columns[_]+"</th>"),v.append('<th scope="col">'+t.columns[_]+"</th>"),n){var $=t.columns[_].toLowerCase().replace(/^\s+|\s+$/g,"").replace(/\s/g,"_").replace(/[^a-z0-9_]/,"");m.append('<th scope="col">'+b.replace('name="column_map[]"','name="aggregator[column_map]['+y+']" id="column-'+y+'"')+"</th>");var k=m.find("#column-"+y);void 0!==i.csv_column_mapping[h][y]&&($=i.csv_column_mapping[h][y]),k.find('option[value="'+$+'"]').prop("selected",!0)}y++}f.scrollX=!0}else f.columns=[{data:"checkbox"},{data:"start_date"},{data:"start_time"},{data:"end_date"},{data:"title"}],f.autoWidth=!1;c.tribeDataTable(f),r.wrap_cell_content(),c.on("select.dt",r.events.twiddle_finalize_button_text).on("deselect.dt",r.events.twiddle_finalize_button_text).on("draw.dt",r.wrap_cell_content),"new"===r.$.action.val()&&(u="manual"===o&&n?i.l10n.import_all_no_number:"manual"===o?i.l10n.import_all.replace("%d",d.length):i.l10n.create_schedule),e(r.selector.finalize_button).html(u)}else{var x=t.origin,C=void 0!==i.l10n[x]&&void 0!==i.l10n[x].no_results?i.l10n[x].no_results:i.l10n.no_results;r.display_fetch_error(C)}},r.wrap_cell_content=function(){e(".dataTable").find("tbody td").each(function(){var t=e(this);t.html('<div class="tribe-td-height-limit">'+t.html()+"</div>")})},r.display_fetch_error=function(t){var i=e(".tribe-fetch-error-message");r.$.preview_container.removeClass("tribe-fetching").addClass("tribe-fetch-error"),i.html(""),r.display_error(i,t),e(r.selector.preview_button).prop("disabled",!1)},r.display_fetch_warning=function(t){var i=e(".tribe-fetch-warning-message");r.$.preview_container.removeClass("tribe-fetching").addClass("tribe-fetch-warning"),i.html(""),r.display_warning(i,t)},r.display_error=function(e,t){e.prepend(['<div class="notice notice-error">',"<p>",t,"</p>","</div>"].join(""))},r.display_warning=function(e,t){e.prepend(['<div class="notice notice-warning">',"<p>",t,"</p>","</div>"].join(""))},r.display_success=function(e,t){e.prepend(['<div class="notice notice-success">',"<p>",t,"</p>","</div>"].join(""))},r.save_credentials=function(t){var r=t.find(".tribe-fieldset").find("input").serialize(),i=ajaxurl+"?action=tribe_aggregator_save_credentials";e.post(i,r).done(function(e){e.success&&(t.addClass("credentials-entered"),t.find('[name="has-credentials"]').val(1).change())})},r.finalize_manual_import=function(){var t=e("#tribe-ea-field-origin").val(),a=e(".dataTable"),n=window.tribe_data_table;if(a.hasClass("display-checkboxes")){var s=n.rows({selected:!0});if(s[0].length||(s=n.rows()),!s[0].length)return void r.display_error(e(".tribe-finalize-container"),i.l10n.events_required_for_manual_submit);var o=s.data(),l=[],c=null;if("meetup"===t?c="meetup_id":"eventbrite"===t?c="eventbrite_id":"ical"===t||"ics"===t||"gcal"===t?c="uid":"url"===t&&(c="id"),null!==c){for(var d in o)isNaN(d)||void 0!==o[d][c]&&l.push(o[d][c]);e("#tribe-selected-rows").text(JSON.stringify(l))}else e("#tribe-selected-rows").text("all")}else e("#tribe-selected-rows").text("all");e(".dataTables_scrollBody").find('[name^="aggregator[column_map]"]').remove(),r.$.form.submit()},r.search_id=function(e){var t=null;return void 0!==e.id?t=e.id:void 0!==e.ID?t=e.ID:void 0!==e.value&&(t=e.value),null==e?null:t},r.construct.dropdown=function(t){var r=function(t){var r=e(t.element);return"string"==typeof r.data("subtitle")&&(t.text=t.text+'<br><span class="tribe-dropdown-subtitle">'+r.data("subtitle")+"</span>"),t.text},i={formatResult:r,formatSelection:r,escapeMarkup:function(e){return e}};return tribe_dropdowns.dropdown(t.filter(".tribe-ea-dropdown"),i),t},r.construct.media_button=function(t){var i=t.filter(r.selector.media_button);return"undefined"!=typeof wp&&wp.media&&wp.media.editor?(i.each(function(){var t=e(this),i=t.data("input"),a=e("#"+i),n=e("#"+i+"_name"),s=r.media[i]=wp.media({title:t.data("mediaTitle"),library:{type:t.data("mimeType")},multiple:!1});s.on("select",function(){var e=s.state().get("selection");e&&e.each(function(e){a.data({id:e.attributes.id,text:e.attributes.title}),a.val(e.attributes.id),a.change(),n.html(e.attributes.filename),n.attr("title",e.attributes.filename)})})}),r.$.container.on("click",r.selector.media_button,function(t){if(t.preventDefault(),e(this).is(":visible")){var i=e(this).data("input");return r.media[i].open(i),!1}}),i):i},r.events.trigger_field_change=function(){e(this).change()},r.events.trigger_save_credentials=function(){r.save_credentials(e(this).closest(".enter-credentials"))},r.events.suppress_submission=function(t){e("#tribe-ea-field-origin").val();if(e("#tribe-selected-rows").val().length)return!0;t.preventDefault()},r.events.twiddle_finalize_button_text=function(t,a){if("new"===r.$.action.val()){var n=a.rows({selected:!0})[0].length,s=i.l10n.import_checked;n||(s=i.l10n.import_all,n=a.rows()[0].length),s=s.replace("%d",n),e(r.selector.finalize_button).html(s)}},r.events.cancel_edit=function(e){e.preventDefault();var t=window.location.href;t=(t=t.replace("tab=edit","tab=scheduled")).replace(/id=\d+/,""),window.location.href=t},r.events.verify_schedule_delete=function(){return confirm(i.l10n.verify_schedule_delete)},r.events.toggle_view_filters=function(t){t.preventDefault();var r=e(this);r.toggleClass("tribe-active"),r.is(".tribe-active")?r.html(i.l10n.hide_filters):r.html(i.l10n.view_filters)},r.progress.init=function(){r.progress.data={},r.progress.$={},r.progress.$.notice=e(".tribe-notice-aggregator-update-msg"),r.progress.$.spinner=r.progress.$.notice.find("img"),r.progress.$.progress=r.progress.$.notice.find(".progress"),r.progress.$.tracker=r.progress.$.notice.find(".tracker"),r.progress.$.created=r.progress.$.tracker.find(".track-created .value"),r.progress.$.updated=r.progress.$.tracker.find(".track-updated .value"),r.progress.$.skipped=r.progress.$.tracker.find(".track-skipped .value"),r.progress.$.remaining=r.progress.$.tracker.find(".track-remaining .value"),r.progress.$.bar=r.progress.$.notice.find(".bar"),r.progress.data.time=Date.now(),setTimeout(r.progress.start)},r.progress.start=function(){r.progress.send_request(),r.progress.update(tribe_aggregator_save.progress,tribe_aggregator_save.progressText)},r.progress.handle_response=function(e){var t=Date.now()-r.progress.data.time;e.html&&r.progress.data.notice.html(e.html),isNaN(parseInt(e.progress,10))||r.progress.update(e),e.continue&&(t<500?setTimeout(r.progress.send_request,500-t):r.progress.send_request()),e.error?(r.progress.$.notice.find(".tribe-message").html(e.error_text),r.progress.$.tracker.remove(),r.progress.$.notice.find(".progress-container").remove(),r.progress.$.notice.removeClass("warning").addClass("error")):e.complete&&(r.progress.$.notice.find(".tribe-message").html(e.complete_text),r.progress.$.tracker.remove(),r.progress.$.notice.find(".progress-container").remove(),r.progress.$.notice.removeClass("warning").addClass("completed"))},r.progress.send_request=function(){var t={record:tribe_aggregator_save.record_id,check:tribe_aggregator_save.check,action:"tribe_aggregator_realtime_update"};e.post(ajaxurl,t,r.progress.handle_response,"json")},r.progress.update=function(e){var t=parseInt(e.progress,10);if(!(t<0||t>100)&&void 0!==e.counts){var i=["created","updated","skipped"];for(var a in i)if(e.counts[i[a]]){var n=e.counts[i[a]],s=r.progress.$[i[a]];if("updated"===i[a]||"skipped"===i[a])n>(s?s.html():0)&&s.html(n);else s.html(n);r.progress.$.tracker.hasClass("has-"+i[a])||r.progress.$.tracker.addClass("has-"+i[a])}r.progress.$.bar.css("width",t+"%"),r.progress.$.progress.attr("title",e.progress_text)}},r.progress.remove_notice=function(){r.progress.$.notice.animate({opacity:0,height:"toggle"},1e3,function(){r.progress.$.notice.remove()})},r.date_helper=function(){var t;if((t=e(this)).hasClass("tribe-datepicker")){var r=t.val();if(""!==r&&null!==r){var i=t.attr("id").match("tribe-ea-field-(.*)_start")[1];""!==i&&null!==i&&jQuery("#tribe-date-helper-date-"+i).html(r)}}},r.maybeLimitUrlStartDate=function(){"url"===r.origin.val()&&("schedule"!==r.importType.val()?r.urlImport.startDate.data("datepicker-min-date",null):r.urlImport.startDate.data("datepicker-min-date","today"))},e(document).ready(r.init)}(jQuery,_,tribe_aggregator.fields,tribe_aggregator);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable */
2
+ var tribe_aggregator = tribe_aggregator || {};
3
+
4
+ // Setup the global Variable
5
+ tribe_aggregator.fields = {
6
+ // Store the Required Selectors
7
+ selector: {
8
+ container : '.tribe-ea',
9
+ form : '.tribe-ea-form',
10
+ help : '.tribe-ea-help',
11
+ fields : '.tribe-ea-field',
12
+ dropdown : '.tribe-ea-dropdown',
13
+ origin_field : '#tribe-ea-field-origin',
14
+ field_url_source : '#tribe-ea-field-url_source',
15
+ eventbrite_url_source : '#tribe-ea-field-eventbrite_source',
16
+ post_status : '.tribe-ea-field-post_status',
17
+ import_type_field : '.tribe-import-type',
18
+ media_button : '.tribe-ea-media_button',
19
+ datepicker : '.tribe-datepicker',
20
+ save_credentials_button : '.enter-credentials .tribe-save',
21
+ preview_container : '.tribe-preview-container',
22
+ preview_button : '.tribe-preview:visible',
23
+ refine_filters : '.tribe-refine-filters',
24
+ clear_filters_button : '.tribe-clear-filters',
25
+ finalize_button : '.tribe-finalize',
26
+ cancel_button : '.tribe-cancel',
27
+ schedule_delete_link : '.tribe-ea-tab-scheduled a.submitdelete',
28
+ tab_new : '.tribe-ea-tab-new',
29
+ action : '#tribe-action',
30
+ view_filters : '.tribe-view-filters'
31
+ },
32
+
33
+ media: {},
34
+
35
+ // Store the jQuery elements
36
+ $: {},
37
+
38
+ // Store the methods for creating the fields
39
+ construct: {},
40
+
41
+ // Store the methods that will act as event handlers
42
+ events: {},
43
+
44
+ // store the current import_id
45
+ import_id: null,
46
+
47
+ // track how many result fetches have been executed via polling
48
+ result_fetch_count: 0,
49
+
50
+ // the maximum number of result fetches that can be done per frequency before erroring out
51
+ max_result_fetch_count: 15,
52
+
53
+ // frequency at which we will poll for results
54
+ polling_frequency_index: 0,
55
+
56
+ polling_frequencies: [
57
+ 500,
58
+ 1000,
59
+ 5000,
60
+ 20000
61
+ ],
62
+
63
+ progress: {},
64
+
65
+ // A "module" of sorts related to Eventbrite only imports.
66
+ eventbrite: {
67
+ refineControls: '.tribe-refine-filters.eventbrite, .tribe-refine-filters.eventbrite .tribe-refine',
68
+ refineControlsHideMap: {
69
+ 'event': 'tr.tribe-refine-filters',
70
+ 'organizer': ''
71
+ },
72
+ detect_type: function ( url ) {
73
+ if ( ! tribe_aggregator.source_origin_regexp.eventbrite ) {
74
+ return null;
75
+ }
76
+
77
+ var baseRegex = tribe_aggregator.source_origin_regexp.eventbrite;
78
+ var type_regexps = {
79
+ // E.g. https://www.eventbrite.fr/e/some-event
80
+ 'event': baseRegex + 'e\/[A-z0-9_-]+',
81
+ // E.g. https://www.eventbrite.fr/o/some-organizer
82
+ 'organizer': baseRegex + 'o\/[A-z0-9_-]+'
83
+ };
84
+ var type = undefined;
85
+
86
+ _.each( type_regexps, function ( regularExpression, key ) {
87
+ var exp = new RegExp( regularExpression, 'g' );
88
+ var match = exp.exec( url );
89
+
90
+ if ( null === match ) {
91
+ return;
92
+ }
93
+
94
+ type = key;
95
+ } );
96
+
97
+ return type;
98
+ }
99
+ }
100
+ };
101
+
102
+ ( function( $, _, obj, ea ) {
103
+ 'use strict';
104
+ /**
105
+ * Sets up the fields for EA pages
106
+ *
107
+ * @return void
108
+ */
109
+ obj.init = function() {
110
+ obj.$.container = $( obj.selector.container );
111
+
112
+ obj.$.form = $( obj.selector.form );
113
+
114
+ obj.$.action = $( obj.selector.action );
115
+
116
+ // Update what fields we currently have to setup
117
+ obj.$.fields = obj.$.container.find( obj.selector.fields );
118
+
119
+ // Setup the preview container
120
+ obj.$.preview_container = $( obj.selector.preview_container );
121
+
122
+ // setup some variables we might reuse
123
+ obj.origin = $( '#tribe-ea-field-origin' );
124
+ obj.importType = $( '#tribe-ea-field-url_import_type' );
125
+ obj.urlImport = {
126
+ startDate: $( '#tribe-ea-field-url_start' ),
127
+ originalMinDate: $( '#tribe-ea-field-url_start' ).datepicker( 'option', 'minDate' ) || '',
128
+ };
129
+
130
+ // Setup each type of field
131
+ $.each( obj.construct, function( key, callback ){
132
+ callback( obj.$.fields );
133
+ } );
134
+
135
+ var $tribe_events = $( document.getElementById( 'eventDetails' ) );
136
+ if ( $tribe_events.data( 'datepicker_format' ) ) {
137
+ tribe_ev.state.datepicker_format = $tribe_events.data( 'datepicker_format' );
138
+ }
139
+
140
+ $( document )
141
+ .on( 'keypress' , obj.selector.fields , obj.events.trigger_field_change )
142
+ .on( 'click' , obj.selector.save_credentials_button , obj.events.trigger_save_credentials )
143
+ .on( 'click' , obj.selector.clear_filters_button , obj.clear_filters )
144
+ .on( 'click' , obj.selector.finalize_button , obj.finalize_manual_import )
145
+ .on( 'click' , obj.selector.preview_button , obj.preview_import )
146
+ .on( 'click' , obj.selector.cancel_button , obj.events.cancel_edit )
147
+ .on( 'click' , obj.selector.schedule_delete_link , obj.events.verify_schedule_delete )
148
+ .on( 'click' , obj.selector.view_filters , obj.events.toggle_view_filters )
149
+ .on( 'blur' , obj.selector.datepicker , obj.date_helper )
150
+ .on( 'submit' , obj.selector.tab_new , obj.events.suppress_submission )
151
+ .on( 'change' , obj.selector.import_type_field , function() {
152
+ // Resets the Preview
153
+ obj.reset_preview()
154
+
155
+ // Every time you change Type of import we reset the frequency field
156
+ var $this = $( this ),
157
+ $frequency = $( this ).next( obj.selector.fields );
158
+
159
+ var importType = $this.val();
160
+
161
+ $frequency.val( ( 'schedule' === importType ? 'daily' : '' ) ).change();
162
+
163
+ // set a data attribute on the form indicating the schedule type
164
+ obj.$.form.attr( 'data-type', importType );
165
+
166
+ obj.maybeLimitUrlStartDate()
167
+ } )
168
+ .on( 'change' , obj.selector.origin_field , function() {
169
+ var $field = $( this );
170
+ var selectData = $( this ).data( 'select2' );
171
+ var origin = $field.val();
172
+ obj.$.form.attr( 'data-origin', origin );
173
+ obj.reset_preview();
174
+
175
+ // reset all bumpdowns
176
+ $( '.tribe-bumpdown-active' ).removeClass( 'tribe-bumpdown-active' );
177
+ $( '.tribe-bumpdown:visible' ).hide();
178
+
179
+ if ( 'redirect' === $( this ).val() ) {
180
+ window.open( 'https://theeventscalendar.com/wordpress-event-aggregator/?utm_source=importoptions&utm_medium=plugin-tec&utm_campaign=in-app', '_blank' );
181
+ location.reload();
182
+ }
183
+
184
+ // A "reset" of the Post Status select2 selector when an origin is selected.
185
+ if ( '' !== origin ) {
186
+ $( obj.selector.post_status )
187
+ .val( ea.default_settings[ origin ][ 'post_status' ] )
188
+ .trigger( 'change' );
189
+ }
190
+
191
+ obj.maybeLimitUrlStartDate()
192
+ } )
193
+ .on( 'change', obj.selector.eventbrite_url_source, function ( e ) {
194
+ // Show all UI controls at first, even if we bail the user will have a full UI.
195
+ $( obj.eventbrite.refineControls ).show();
196
+
197
+ var type = obj.eventbrite.detect_type( $( '#tribe-ea-field-eventbrite_source' ).val() );
198
+
199
+ if ( ! type ) {
200
+ return;
201
+ }
202
+
203
+ // And then hide the ones that should be hidden for this import type if there are any.
204
+ var controlsToHide = obj.eventbrite.refineControlsHideMap[ type ];
205
+ if ( controlsToHide ) {
206
+ $( controlsToHide ).hide();
207
+ }
208
+ } )
209
+ .on( 'change', obj.selector.field_url_source, function( e ) {
210
+ var $field = $( this );
211
+ var selectData = $( this ).data( 'select2' );
212
+ var value = $field.val();
213
+ var origin = null;
214
+
215
+ if ( ! value ) {
216
+ return;
217
+ }
218
+
219
+ _.each( ea.source_origin_regexp, function( regularExpression, key ) {
220
+ var exp = new RegExp( regularExpression, 'g' );
221
+ var match = exp.exec( value );
222
+
223
+ if ( null === match ) {
224
+ return;
225
+ }
226
+
227
+ origin = key;
228
+ } );
229
+
230
+ if ( null == origin ) {
231
+ return;
232
+ }
233
+
234
+ var $origin = $( obj.selector.origin_field );
235
+
236
+ // Prevent Changing when dealing with Non-Existant Origin
237
+ if ( ! $origin.find( 'option[value="' + origin + '"]' ).length ) {
238
+ return;
239
+ }
240
+
241
+ var $type = $( '#tribe-ea-field-url_import_type' );
242
+ var typeValue = $type.val();
243
+ var frequencyValue = null;
244
+ if ( 'schedule' === typeValue ) {
245
+ frequencyValue = $( '#tribe-ea-field-url_import_frequency' ).val();
246
+ }
247
+
248
+ // Reset type value to avoid bugs
249
+ $type.val( '' );
250
+
251
+ // Change the Origin to what ever matched
252
+ $origin.val( origin ).trigger( 'change' );
253
+
254
+ // Change the frequency accordingly
255
+ $( '#tribe-ea-field-' + origin + '_import_type' ).val( typeValue ).trigger( 'change' );
256
+ if ( 'schedule' === typeValue ) {
257
+ $( '#tribe-ea-field-' + origin + '_import_frequency' ).val( frequencyValue ).trigger( 'change' );
258
+ }
259
+
260
+ if ( 'eventbrite' === origin ) {
261
+ $( '#tribe-ea-field-' + origin + '_source_type_url' ).trigger( 'click' );
262
+ $( '#tribe-ea-field-' + origin + '_import_source' ).val( 'source_type_url' ).trigger( 'change' );
263
+ }
264
+
265
+ // Change the Source URL accordingly
266
+ $( '#tribe-ea-field-' + origin + '_source' ).val( value ).trigger( 'change' );
267
+ } );
268
+
269
+ $( '.tribe-dependency' ).change();
270
+
271
+ // Configure TimePickers
272
+ tribe_timepickers.setup_timepickers( $( tribe_timepickers.selector.timepicker ) );
273
+
274
+ if ( 'edit' === obj.$.action.val() ) {
275
+ obj.$.form.addClass( 'edit-form' );
276
+ $( obj.selector.finalize_button ).html( ea.l10n.edit_save );
277
+ }
278
+
279
+ if ( 'object' === typeof tribe_aggregator_save ) {
280
+ obj.progress.init();
281
+ }
282
+ };
283
+
284
+ /**
285
+ * Send an Ajax request to preview the import
286
+ */
287
+ obj.preview_import = function( event ) {
288
+ event.preventDefault();
289
+
290
+ var $form = $( '.tribe-ea-form.tribe-validation' );
291
+
292
+ obj.reset_post_status();
293
+
294
+ // Makes sure we have validation
295
+ $form.trigger( 'validation.tribe' );
296
+
297
+ // Prevent anything from happening when there are errors
298
+ if ( tribe.validation.hasErrors( $form ) ) {
299
+ return;
300
+ }
301
+
302
+ obj.reset_polling_counter();
303
+
304
+ // clear the warning area
305
+ var $message_container = $( '.tribe-fetch-warning-message' ).html( '' );
306
+
307
+ // when generating data for previews, temporarily remove the post ID and import ID values from their fields
308
+ var $post_id = $( '#tribe-post_id' );
309
+ $post_id.data( 'value', $post_id.val() );
310
+ $post_id.val( '' );
311
+
312
+ var $import_id = $( '#tribe-import_id' );
313
+ $import_id.data( 'value', $import_id.val() );
314
+ $import_id.val( '' );
315
+
316
+ var $preview = $( obj.selector.preview_button );
317
+ var $form = $preview.closest( 'form' );
318
+ var data = $form.serialize();
319
+
320
+ // add the post_id value back into the field now that we've generated the serialized form data
321
+ $post_id.val( $post_id.data( 'value' ) );
322
+ $import_id.val( $post_id.data( 'value' ) );
323
+
324
+ obj.$.preview_container
325
+ .addClass( 'tribe-fetching' )
326
+ .removeClass( 'tribe-fetch-error' );
327
+
328
+ obj.$.form.removeClass( 'show-data' );
329
+
330
+ $preview.prop( 'disabled', true );
331
+
332
+ var table = $( '.dataTable' ).data( 'table' );
333
+ if ( 'undefined' !== typeof table ) {
334
+ table.clear().draw();
335
+ }
336
+
337
+ if ( 'edit' === obj.$.action.val() ) {
338
+ // preview the import
339
+ obj.preview_save_import( data );
340
+ } else {
341
+ // create the import
342
+ obj.create_import( data );
343
+ }
344
+ };
345
+
346
+ /**
347
+ * Reset the post status to the default state when a new import is taking place
348
+ */
349
+ obj.reset_post_status = function() {
350
+ var $origin = $( obj.selector.origin_field ); // eslint-disable-line no-var
351
+ var origin = $origin.length === 0 ? '' : $origin.val(); // eslint-disable-line no-var
352
+
353
+ if ( origin === '' ) {
354
+ return;
355
+ }
356
+
357
+ // Set the default state of the post_status
358
+ $( obj.selector.post_status )
359
+ .val( ea.default_settings[ origin ].post_status )
360
+ .trigger( 'change' );
361
+ };
362
+
363
+ obj.reset_polling_counter = function() {
364
+ obj.polling_frequency_index = 0;
365
+ obj.result_fetch_count = 0;
366
+ };
367
+
368
+ /**
369
+ * Clears the refine filters
370
+ */
371
+ obj.reset_form = function() {
372
+ obj.$.fields.val( '' ).trigger( 'change' );
373
+ $( '[id$="import_frequency"]' ).val( 'daily' ).trigger( 'change' );
374
+ obj.$.form.removeClass( 'show-data' );
375
+ };
376
+
377
+ /**
378
+ * Resets the preview area of a form
379
+ */
380
+ obj.reset_preview = function() {
381
+ obj.$.form.removeClass( 'show-data' );
382
+ $( '.tribe-fetched, .tribe-fetching, .tribe-fetch-error' ).removeClass( 'tribe-fetched tribe-fetching tribe-fetch-error' );
383
+ };
384
+
385
+ /**
386
+ * Clears the refine filters
387
+ */
388
+ obj.clear_filters = function() {
389
+ $( obj.selector.refine_filters )
390
+ .find( 'input, select' )
391
+ .val( '' )
392
+ .trigger( 'change' );
393
+ };
394
+
395
+ /**
396
+ * Edits an import and polls for results
397
+ */
398
+ obj.preview_save_import = function( data ) {
399
+ var jqxhr = $.ajax( {
400
+ type: 'POST',
401
+ url: ajaxurl + '?action=tribe_aggregator_preview_import',
402
+ data: data,
403
+ dataType: 'json'
404
+ } );
405
+
406
+ jqxhr.done( obj.handle_preview_create_results );
407
+ };
408
+
409
+ /**
410
+ * Creates an import and polls for results
411
+ *
412
+ * @param object data Form data for the import
413
+ */
414
+ obj.create_import = function( data ) {
415
+ var jqxhr = $.ajax( {
416
+ type: 'POST',
417
+ url: ajaxurl + '?action=tribe_aggregator_create_import',
418
+ data: data,
419
+ dataType: 'json'
420
+ } );
421
+
422
+ jqxhr.done( obj.handle_preview_create_results );
423
+ };
424
+
425
+ /**
426
+ * Handles the create/edit results
427
+ */
428
+ obj.handle_preview_create_results = function( response ) {
429
+ if ( ! response.success ) {
430
+ var error = response.data;
431
+
432
+ if ( ! _.isString( error ) ) {
433
+ error = error.message;
434
+ }
435
+
436
+ obj.display_fetch_error( [
437
+ '<b>',
438
+ ea.l10n.preview_fetch_error_prefix,
439
+ '</b>',
440
+ ' ' + error
441
+ ].join( ' ' ) );
442
+ return;
443
+ }
444
+
445
+ // set the import id of the page
446
+ obj.import_id = response.data.data.import_id;
447
+ $( '#tribe-import_id' ).val( obj.import_id );
448
+
449
+ if ( 'undefined' !== typeof response.data.data.items ) {
450
+ obj.init_datatable( response.data.data );
451
+ obj.$.preview_container.removeClass( 'tribe-fetching' ).addClass( 'tribe-fetched' );
452
+ return;
453
+ }
454
+
455
+ obj.$.container.find( '.spinner-message' ).html( ea.l10n.preview_polling[0] );
456
+ setTimeout( obj.poll_for_results, obj.polling_frequencies[ obj.polling_frequency_index ] );
457
+ };
458
+
459
+ /**
460
+ * Poll for results from an import
461
+ */
462
+ obj.poll_for_results = function() {
463
+ obj.result_fetch_count++;
464
+
465
+ var jqxhr = $.ajax( {
466
+ type: 'GET',
467
+ url: ajaxurl + '?action=tribe_aggregator_fetch_import&import_id=' + obj.import_id,
468
+ dataType: 'json'
469
+ } );
470
+
471
+ jqxhr.done( function( response ) {
472
+ if ( 'undefined' !== typeof response.data.warning && response.data.warning ) {
473
+ var warning_message = response.data.warning;
474
+
475
+ obj.display_fetch_warning( [
476
+ '<b>',
477
+ ea.l10n.preview_fetch_warning_prefix,
478
+ '</b>',
479
+ ' ' + warning_message
480
+ ].join( ' ' ) );
481
+ }
482
+
483
+ if ( ! response.success ) {
484
+ var error_message;
485
+
486
+ if ( 'undefined' !== typeof response.data.message ) {
487
+ error_message = response.data.message;
488
+ } else if ( 'undefined' !== typeof response.data[0].message ) {
489
+ error_message = response.data[0].message;
490
+ }
491
+
492
+ obj.display_fetch_error( [
493
+ '<b>',
494
+ ea.l10n.preview_fetch_error_prefix,
495
+ '</b>',
496
+ ' ' + error_message
497
+ ].join( ' ' ) );
498
+ return;
499
+ }
500
+
501
+ if ( 'error' === response.data.status ) {
502
+ obj.display_fetch_error( response.data.message );
503
+ } else if ( 'success' !== response.data.status ) {
504
+ if ( obj.result_fetch_count > obj.max_result_fetch_count ) {
505
+ obj.polling_frequency_index++;
506
+ obj.$.container.find( '.spinner-message' ).html( ea.l10n.preview_polling[ obj.polling_frequency_index ] );
507
+ obj.result_fetch_count = 0;
508
+ }
509
+
510
+ if ( 'undefined' === typeof obj.polling_frequencies[ obj.polling_frequency_index ] ) {
511
+ obj.display_fetch_error( ea.l10n.preview_timeout );
512
+ } else {
513
+ setTimeout( obj.poll_for_results, obj.polling_frequencies[ obj.polling_frequency_index ] );
514
+ }
515
+ } else {
516
+ response.data.data.items = response.data.data.events;
517
+ obj.init_datatable( response.data.data );
518
+ obj.$.preview_container.removeClass( 'tribe-fetching' ).addClass( 'tribe-fetched' );
519
+ $( obj.selector.preview_button ).prop( 'disabled', false );
520
+ }
521
+ } );
522
+ };
523
+
524
+ /**
525
+ * Initializes the datatable
526
+ *
527
+ * @param array data Array of events to display in the table
528
+ */
529
+ obj.init_datatable = function( data ) {
530
+ var display_checkboxes = false;
531
+
532
+ var origin = $( obj.selector.origin_field ).val();
533
+ var is_csv = 'csv' === origin;
534
+ var is_eventbrite = 'eventbrite' === origin;
535
+
536
+ var $import_type = $( '[id$="import_type"]:visible' );
537
+ var import_type = 'manual';
538
+
539
+ // set the default settings
540
+ if ( 'undefined' !== typeof ea.default_settings[ origin ] ) {
541
+ for ( var settings_key in ea.default_settings[ origin ] ) {
542
+ if ( ! ea.default_settings[ origin ].hasOwnProperty( settings_key ) ) {
543
+ continue;
544
+ }
545
+
546
+ var $setting_field = $( '#tribe-ea-field-' + settings_key );
547
+
548
+ $setting_field
549
+ .val( ea.default_settings[ origin ][ settings_key ] )
550
+ .trigger( 'change' );
551
+ }
552
+ }
553
+
554
+ if ( $import_type.length ) {
555
+ import_type = $( '#' + $import_type.first().attr( 'id' ).replace( 's2id_', '' ) ).val();
556
+ }
557
+
558
+ if ( 'manual' === import_type && !data.items.length ) {
559
+ var origin = data.origin;
560
+ var origin_specific_no_results_msg = (
561
+ 'undefined' !== typeof ea.l10n[ origin ]
562
+ && 'undefined' !== typeof ea.l10n[ origin ].no_results
563
+ );
564
+
565
+ var message = origin_specific_no_results_msg ?
566
+ ea.l10n[ origin ].no_results
567
+ : ea.l10n.no_results;
568
+
569
+ obj.display_fetch_error(message);
570
+ return;
571
+ }
572
+
573
+ if ( ! $import_type.length || 'manual' === import_type ) {
574
+ display_checkboxes = true;
575
+ }
576
+
577
+ var $table = obj.$.preview_container.find( '.data-container table' );
578
+
579
+ var rows = [];
580
+ for ( var i in data.items ) {
581
+ var row = data.items[ i ];
582
+ row.checkbox = display_checkboxes ? '<input type="checkbox">' : '';
583
+ if ( row.all_day ) {
584
+ row.start_time = ea.l10n.all_day;
585
+ } else {
586
+ if ( 'undefined' === typeof row.start_meridian || ! row.start_meridian ) {
587
+ if ( parseInt( row.start_hour, 10 ) > 11 ) {
588
+ row.start_meridian = ea.l10n.pm;
589
+ } else {
590
+ row.start_meridian = ea.l10n.am;
591
+ }
592
+ }
593
+
594
+ if ( row.start_hour > 12 ) {
595
+ row.start_hour = row.start_hour - 12;
596
+ }
597
+
598
+ row.start_time = ( 0 === parseInt( row.start_hour, 10 ) ? 12 : row.start_hour ) + ':' + ( '00' + row.start_minute ).slice( -2 );
599
+ row.start_time += ' ' + row.start_meridian;
600
+ }
601
+ rows.push( row );
602
+ }
603
+
604
+ if ( display_checkboxes && ! is_csv ) {
605
+ $table.addClass( 'display-checkboxes' );
606
+ } else {
607
+ $table.removeClass( 'display-checkboxes' );
608
+ }
609
+
610
+ obj.$.form.addClass( 'show-data' );
611
+
612
+ var args = {
613
+ lengthMenu: [
614
+ [ 5, 10, 25, 50, -1 ],
615
+ [ 5, 10, 25, 50, tribe_l10n_datatables.pagination.all ]
616
+ ],
617
+ order: [
618
+ [ 1, 'asc' ]
619
+ ],
620
+ columnDefs: [
621
+ {
622
+ cellType: 'th',
623
+ className: 'check-column',
624
+ orderable: false,
625
+ targets: 0
626
+ }
627
+ ],
628
+ data: rows
629
+ };
630
+
631
+ if ( 'undefined' !== typeof data.columns ) {
632
+ args.columns = [
633
+ { data: 'checkbox' }
634
+ ];
635
+
636
+ var $head = $table.find( 'thead tr' );
637
+ var $foot = $table.find( 'tfoot tr' );
638
+ var $map_row = $({});
639
+ var column_map = '';
640
+ var content_type = '';
641
+ $head.find( 'th:first' ).nextAll().remove();
642
+ $foot.find( 'th:first' ).nextAll().remove();
643
+
644
+ if ( is_csv ) {
645
+ var $data_container = $table.closest( '.data-container' );
646
+ $table.closest( '.data-container' ).addClass( 'csv-data' );
647
+
648
+ $data_container.find( '.tribe-preview-message .tribe-csv-filename' ).html( $( '#tribe-ea-field-csv_file_name' ).text() );
649
+ $head.closest( 'thead' ).prepend( '<tr class="tribe-column-map"><th scope="row" class="check-column column-cb"></th></tr>' );
650
+ $map_row = $( '.tribe-column-map' );
651
+ content_type = $( '#tribe-ea-field-csv_content_type' ).val();
652
+ content_type = content_type.replace( 'tribe_', '' );
653
+
654
+ var $mapper_template = $( '#tribe-csv-column-map-' + content_type );
655
+ column_map = $mapper_template.html();
656
+ }
657
+
658
+ var column = 0;
659
+ for ( i in data.columns ) {
660
+ args.columns.push( { data: data.columns[ i ] } );
661
+ $head.append( '<th scope="col">' + data.columns[ i ] + '</th>' );
662
+ $foot.append( '<th scope="col">' + data.columns[ i ] + '</th>' );
663
+
664
+ // if this is a CSV import, add the column map headers and default-select where possible
665
+ if ( is_csv ) {
666
+ var column_slug = data.columns[ i ].toLowerCase()
667
+ .replace( /^\s+|\s+$/g, '' ) // Remove left / right spaces before the word starts
668
+ .replace( /\s/g, '_' ) // change all spaces inside of words to underscores
669
+ .replace( /[^a-z0-9_]/, '' );
670
+ $map_row.append( '<th scope="col">' + column_map.replace( 'name="column_map[]"', 'name="aggregator[column_map][' + column + ']" id="column-' + column + '"' ) + '</th>' );
671
+
672
+ var $map_select = $map_row.find( '#column-' + column );
673
+
674
+ if ( 'undefined' !== typeof ea.csv_column_mapping[ content_type ][ column ] ) {
675
+ column_slug = ea.csv_column_mapping[ content_type ][ column ];
676
+ }
677
+ $map_select.find( 'option[value="' + column_slug + '"]' ).prop( 'selected', true );
678
+ }
679
+
680
+ column++;
681
+ }
682
+
683
+ args.scrollX = true;
684
+ } else {
685
+ args.columns = [
686
+ { data: 'checkbox' },
687
+ { data: 'start_date' },
688
+ { data: 'start_time' },
689
+ { data: 'end_date' },
690
+ { data: 'title' }
691
+ ];
692
+ args.autoWidth = false;
693
+ }
694
+
695
+ $table.tribeDataTable( args );
696
+ obj.wrap_cell_content();
697
+
698
+ $table
699
+ .on( 'select.dt' , obj.events.twiddle_finalize_button_text )
700
+ .on( 'deselect.dt', obj.events.twiddle_finalize_button_text )
701
+ .on( 'draw.dt', obj.wrap_cell_content );
702
+
703
+ var text;
704
+
705
+ if ( 'new' === obj.$.action.val() ) {
706
+ if ( 'manual' === import_type && is_csv ) {
707
+ text = ea.l10n.import_all_no_number;
708
+ } else if ( 'manual' === import_type ) {
709
+ text = ea.l10n.import_all.replace( '%d', rows.length );
710
+ } else {
711
+ text = ea.l10n.create_schedule;
712
+ }
713
+ }
714
+
715
+ $( obj.selector.finalize_button ).html( text );
716
+ };
717
+
718
+ obj.wrap_cell_content = function() {
719
+ $( '.dataTable' ).find( 'tbody td' ).each( function() {
720
+ var $cell = $( this );
721
+ $cell.html( '<div class="tribe-td-height-limit">' + $cell.html() + '</div>' );
722
+ } );
723
+ };
724
+
725
+ /**
726
+ * Displays a fetch error
727
+ */
728
+ obj.display_fetch_error = function( message ) {
729
+ var $message_container = $( '.tribe-fetch-error-message' );
730
+ obj.$.preview_container.removeClass( 'tribe-fetching' ).addClass( 'tribe-fetch-error' );
731
+
732
+ // clear out the error message area
733
+ $message_container.html('');
734
+
735
+ obj.display_error( $message_container, message );
736
+ $( obj.selector.preview_button ).prop( 'disabled', false );
737
+ };
738
+
739
+ /**
740
+ * Displays a fetch warning
741
+ */
742
+ obj.display_fetch_warning = function( message ) {
743
+ var $message_container = $( '.tribe-fetch-warning-message' );
744
+ obj.$.preview_container.removeClass( 'tribe-fetching' ).addClass( 'tribe-fetch-warning' );
745
+
746
+ // clear out the error message area
747
+ $message_container.html('');
748
+
749
+ obj.display_warning( $message_container, message );
750
+ };
751
+
752
+ /**
753
+ * Displays an error to a container on the page
754
+ */
755
+ obj.display_error = function( $container, message ) {
756
+ $container.prepend(
757
+ [
758
+ '<div class="notice notice-error">',
759
+ '<p>',
760
+ message,
761
+ '</p>',
762
+ '</div>'
763
+ ].join( '' )
764
+ );
765
+ };
766
+
767
+ /**
768
+ * Displays a warning to a container on the page
769
+ */
770
+ obj.display_warning = function( $container, message ) {
771
+ $container.prepend(
772
+ [
773
+ '<div class="notice notice-warning">',
774
+ '<p>',
775
+ message,
776
+ '</p>',
777
+ '</div>'
778
+ ].join( '' )
779
+ );
780
+ };
781
+
782
+ /**
783
+ * displays a success message to a container on the page
784
+ */
785
+ obj.display_success = function( $container, message ) {
786
+ $container.prepend(
787
+ [
788
+ '<div class="notice notice-success">',
789
+ '<p>',
790
+ message,
791
+ '</p>',
792
+ '</div>'
793
+ ].join( '' )
794
+ );
795
+ };
796
+
797
+ /**
798
+ * Saves credential form
799
+ */
800
+ obj.save_credentials = function( $credentials_form ) {
801
+ var data = $credentials_form.find( '.tribe-fieldset' ).find( 'input' ).serialize();
802
+
803
+ var url = ajaxurl + '?action=tribe_aggregator_save_credentials';
804
+
805
+ var jqxhr = $.post( url, data );
806
+ jqxhr.done( function( response ) {
807
+ if ( response.success ) {
808
+ $credentials_form.addClass( 'credentials-entered' );
809
+ $credentials_form.find( '[name="has-credentials"]' ).val( 1 ).change();
810
+ }
811
+ } );
812
+ };
813
+
814
+ /**
815
+ * Submits the final version of the import for saving events
816
+ */
817
+ obj.finalize_manual_import = function() {
818
+ var origin = $( '#tribe-ea-field-origin' ).val();
819
+ var $table = $( '.dataTable' );
820
+ var table = window.tribe_data_table;
821
+
822
+ if ( $table.hasClass( 'display-checkboxes' ) ) {
823
+ var row_selection = table.rows( { selected: true } );
824
+ if ( ! row_selection[0].length ) {
825
+ row_selection = table.rows();
826
+ }
827
+
828
+ if ( ! row_selection[0].length ) {
829
+ obj.display_error( $( '.tribe-finalize-container' ), ea.l10n.events_required_for_manual_submit );
830
+ return;
831
+ }
832
+
833
+ var data = row_selection.data();
834
+ var items = [];
835
+ var unique_id_field = null;
836
+
837
+ if ( 'meetup' === origin ) {
838
+ unique_id_field = 'meetup_id';
839
+ } else if ( 'eventbrite' === origin ) {
840
+ unique_id_field = 'eventbrite_id';
841
+ } else if ( 'ical' === origin || 'ics' === origin || 'gcal' === origin ) {
842
+ unique_id_field = 'uid';
843
+ } else if ( 'url' === origin ) {
844
+ unique_id_field = 'id';
845
+ }
846
+
847
+ if ( null !== unique_id_field ) {
848
+ for ( var i in data ) {
849
+ if ( isNaN( i ) ) {
850
+ continue;
851
+ }
852
+
853
+ if ( 'undefined' === typeof data[ i ][ unique_id_field ] ) {
854
+ continue;
855
+ }
856
+
857
+ items.push( data[ i ][ unique_id_field ] );
858
+ }
859
+
860
+ $( '#tribe-selected-rows' ).text( JSON.stringify( items ) );
861
+ } else {
862
+ $( '#tribe-selected-rows' ).text( 'all' );
863
+ }
864
+ } else {
865
+ $( '#tribe-selected-rows' ).text( 'all' );
866
+ }
867
+
868
+ $( '.dataTables_scrollBody' ).find( '[name^="aggregator[column_map]"]' ).remove();
869
+
870
+ obj.$.form.submit();
871
+ };
872
+
873
+ /**
874
+ * Better Search ID for Select2, compatible with WordPress ID from WP_Query
875
+ *
876
+ * @param {object|string} e Searched object or the actual ID
877
+ * @return {string} ID of the object
878
+ */
879
+ obj.search_id = function ( e ) {
880
+ var id = null;
881
+
882
+ if ( 'undefined' !== typeof e.id ){
883
+ id = e.id;
884
+ } else if ( 'undefined' !== typeof e.ID ){
885
+ id = e.ID;
886
+ } else if ( 'undefined' !== typeof e.value ){
887
+ id = e.value;
888
+ }
889
+ return e == undefined ? null : id;
890
+ };
891
+
892
+ /**
893
+ * Configure the Drop Down Fields
894
+ *
895
+ * @param {jQuery} $fields All the fields from the page
896
+ *
897
+ * @return {jQuery} Affected fields
898
+ */
899
+ obj.construct.dropdown = function( $fields ) {
900
+ var upsellFormatter = function( option ) {
901
+ var $option = $( option.element );
902
+
903
+ if ( 'string' === typeof $option.data( 'subtitle' ) ) {
904
+ option.text = option.text + '<br><span class="tribe-dropdown-subtitle">' + $option.data( 'subtitle' ) + '</span>';
905
+ }
906
+
907
+ return option.text;
908
+ };
909
+ var args = {
910
+ formatResult: upsellFormatter,
911
+ formatSelection: upsellFormatter,
912
+
913
+ };
914
+
915
+ tribe_dropdowns.dropdown( $fields.filter( '.tribe-ea-dropdown' ), args );
916
+
917
+ // return to be able to chain jQuery calls
918
+ return $fields;
919
+ };
920
+
921
+ /**
922
+ * Configures the Media Button
923
+ *
924
+ * @param {jQuery} $fields All the fields from the page
925
+ *
926
+ * @return {jQuery} Affected fields
927
+ */
928
+ obj.construct.media_button = function( $fields ) {
929
+ var $elements = $fields.filter( obj.selector.media_button );
930
+
931
+ if ( typeof wp === 'undefined' || ! wp.media || ! wp.media.editor ) {
932
+ return $elements;
933
+ }
934
+
935
+ $elements.each( function(){
936
+ var $button = $( this ),
937
+ input = $button.data( 'input' ),
938
+ $field = $( '#' + input ),
939
+ $name = $( '#' + input + '_name' );
940
+
941
+ // Setup the WP Media for this slug
942
+ var media = obj.media[ input ] = wp.media( {
943
+ title: $button.data( 'mediaTitle' ),
944
+ library: {
945
+ type: $button.data( 'mimeType' )
946
+ },
947
+ multiple: false
948
+ } );
949
+
950
+ // On select send to Select2
951
+ media.on( 'select', function (){
952
+ var state = media.state(),
953
+ selection = state.get('selection');
954
+
955
+ if ( ! selection ) {
956
+ return;
957
+ }
958
+
959
+ selection.each( function( attachment ) {
960
+ $field.data( { id: attachment.attributes.id, text: attachment.attributes.title } );
961
+ $field.val( attachment.attributes.id );
962
+ $field.change();
963
+ $name.html( attachment.attributes.filename );
964
+ $name.attr( 'title', attachment.attributes.filename );
965
+ } );
966
+ } );
967
+
968
+ // We don't need the Media Library button
969
+ /*
970
+ media.on( 'open', function () {
971
+ $( '.media-router .media-menu-item' ).first().trigger( 'click' );
972
+ } );
973
+ */
974
+ } );
975
+
976
+ obj.$.container.on( 'click', obj.selector.media_button, function( e ) {
977
+ e.preventDefault();
978
+
979
+ if ( ! $( this ).is( ':visible' ) ) {
980
+ return;
981
+ }
982
+
983
+ var input = $( this ).data( 'input' );
984
+ obj.media[ input ].open( input );
985
+ return false;
986
+ } );
987
+
988
+ return $elements;
989
+ };
990
+
991
+ /**
992
+ * Triggers a change event on the given field
993
+ */
994
+ obj.events.trigger_field_change = function() {
995
+ $( this ).change();
996
+ };
997
+
998
+ /**
999
+ * Triggers the saving of credentials
1000
+ */
1001
+ obj.events.trigger_save_credentials = function() {
1002
+ obj.save_credentials( $( this ).closest( '.enter-credentials' ) );
1003
+ };
1004
+
1005
+ /**
1006
+ * Suppress form submissions
1007
+ */
1008
+ obj.events.suppress_submission = function( e ) {
1009
+ var origin = $( '#tribe-ea-field-origin' ).val();
1010
+
1011
+ if ( $( '#tribe-selected-rows' ).val().length ) {
1012
+ return true;
1013
+ }
1014
+
1015
+ e.preventDefault();
1016
+ };
1017
+
1018
+ /**
1019
+ * Adjusts the "Import" button to have contextual text based on selected records to import
1020
+ */
1021
+ obj.events.twiddle_finalize_button_text = function( e, dt ) {
1022
+ if ( 'new' !== obj.$.action.val() ) {
1023
+ return;
1024
+ }
1025
+
1026
+ var selected_rows = dt.rows({ selected: true })[0].length;
1027
+ var text = ea.l10n.import_checked;
1028
+
1029
+ if ( ! selected_rows ) {
1030
+ text = ea.l10n.import_all;
1031
+ selected_rows = dt.rows()[0].length;
1032
+ }
1033
+
1034
+ text = text.replace( '%d', selected_rows );
1035
+ $( obj.selector.finalize_button ).html( text );
1036
+ };
1037
+
1038
+ obj.events.cancel_edit = function( e ) {
1039
+ e.preventDefault();
1040
+ var url = window.location.href;
1041
+ url = url.replace( 'tab=edit', 'tab=scheduled' );
1042
+ url = url.replace( /id=\d+/, '' );
1043
+ window.location.href = url;
1044
+ };
1045
+
1046
+ obj.events.verify_schedule_delete = function() {
1047
+ return confirm( ea.l10n.verify_schedule_delete );
1048
+ };
1049
+
1050
+ /**
1051
+ * Toggles the View Filters link on the Scheduled Imports/History page
1052
+ */
1053
+ obj.events.toggle_view_filters = function( e ) {
1054
+ e.preventDefault();
1055
+ var $el = $( this );
1056
+
1057
+ $el.toggleClass( 'tribe-active' );
1058
+ if ( $el.is( '.tribe-active' ) ) {
1059
+ $el.html( ea.l10n.hide_filters );
1060
+ } else {
1061
+ $el.html( ea.l10n.view_filters );
1062
+ }
1063
+ };
1064
+
1065
+ obj.progress.init = function() {
1066
+ obj.progress.data = {};
1067
+ obj.progress.$ = {};
1068
+ obj.progress.$.notice = $( '.tribe-notice-aggregator-update-msg' );
1069
+ obj.progress.$.spinner = obj.progress.$.notice.find( 'img' );
1070
+ obj.progress.$.progress = obj.progress.$.notice.find( '.progress' );
1071
+ obj.progress.$.tracker = obj.progress.$.notice.find( '.tracker' );
1072
+ obj.progress.$.created = obj.progress.$.tracker.find( '.track-created .value' );
1073
+ obj.progress.$.updated = obj.progress.$.tracker.find( '.track-updated .value' );
1074
+ obj.progress.$.skipped = obj.progress.$.tracker.find( '.track-skipped .value' );
1075
+ obj.progress.$.remaining = obj.progress.$.tracker.find( '.track-remaining .value' );
1076
+ obj.progress.$.bar = obj.progress.$.notice.find( '.bar' );
1077
+ obj.progress.data.time = Date.now();
1078
+
1079
+ setTimeout( obj.progress.start );
1080
+ };
1081
+
1082
+ obj.progress.start = function() {
1083
+ obj.progress.send_request();
1084
+ obj.progress.update( tribe_aggregator_save.progress, tribe_aggregator_save.progressText );
1085
+ };
1086
+
1087
+ obj.progress.handle_response = function( data ) {
1088
+ var now = Date.now();
1089
+ var elapsed = now - obj.progress.data.time;
1090
+
1091
+ if ( data.html ) {
1092
+ obj.progress.data.notice.html( data.html );
1093
+ }
1094
+
1095
+ if ( ! isNaN( parseInt( data.progress, 10 ) ) ) {
1096
+ obj.progress.update( data );
1097
+ }
1098
+
1099
+ if ( data.continue ) {
1100
+ // If multiple editors are open for the same event we don't want to hammer the server
1101
+ // and so a min delay of 1/2 sec is introduced between update requests
1102
+ if ( elapsed < 500 ) {
1103
+ setTimeout( obj.progress.send_request, 500 - elapsed );
1104
+ } else {
1105
+ obj.progress.send_request();
1106
+ }
1107
+ }
1108
+
1109
+ if ( data.error ) {
1110
+ obj.progress.$.notice.find( '.tribe-message' ).html( data.error_text );
1111
+ obj.progress.$.tracker.remove();
1112
+ obj.progress.$.notice.find( '.progress-container' ).remove();
1113
+ obj.progress.$.notice.removeClass( 'warning' ).addClass( 'error' );
1114
+ } else if ( data.complete ) {
1115
+ obj.progress.$.notice.find( '.tribe-message' ).html( data.complete_text );
1116
+ obj.progress.$.tracker.remove();
1117
+ obj.progress.$.notice.find( '.progress-container' ).remove();
1118
+ obj.progress.$.notice.removeClass( 'warning' ).addClass( 'completed' );
1119
+ }
1120
+ };
1121
+
1122
+ obj.progress.send_request = function() {
1123
+ var payload = {
1124
+ record: tribe_aggregator_save.record_id,
1125
+ check: tribe_aggregator_save.check,
1126
+ action: 'tribe_aggregator_realtime_update'
1127
+ };
1128
+ $.post( ajaxurl, payload, obj.progress.handle_response, 'json' );
1129
+ };
1130
+
1131
+ obj.progress.update = function( data ) {
1132
+ var percentage = parseInt( data.progress, 10 );
1133
+
1134
+ // The percentage should never be out of bounds, but let's handle such a thing gracefully if it arises
1135
+ if ( percentage < 0 || percentage > 100 ) {
1136
+ return;
1137
+ }
1138
+
1139
+ if ( 'undefined' === typeof data.counts ) {
1140
+ return;
1141
+ }
1142
+
1143
+ var types = [ 'created', 'updated', 'skipped' ];
1144
+ for ( var i in types ) {
1145
+ if ( ! data.counts[ types[ i ] ] ) {
1146
+ continue;
1147
+ }
1148
+
1149
+ var count = data.counts[ types[ i ] ];
1150
+ var $target = obj.progress.$[ types[ i ] ];
1151
+
1152
+ // update updated and skipped count only if higher
1153
+ if ( 'updated' === types[ i ] || 'skipped' === types[ i ] ) {
1154
+ var current = $target ? $target.html() : 0;
1155
+
1156
+ if ( count > current ) {
1157
+ $target.html( count );
1158
+ }
1159
+ } else {
1160
+ $target.html( count );
1161
+ }
1162
+
1163
+ if ( ! obj.progress.$.tracker.hasClass( 'has-' + types[ i ] ) ) {
1164
+ obj.progress.$.tracker.addClass( 'has-' + types[ i ] );
1165
+ }
1166
+ }
1167
+
1168
+ obj.progress.$.bar.css( 'width', percentage + '%' );
1169
+ obj.progress.$.progress.attr( 'title', data.progress_text );
1170
+ };
1171
+
1172
+ obj.progress.remove_notice = function() {
1173
+ var effect = {
1174
+ opacity: 0,
1175
+ height: 'toggle'
1176
+ };
1177
+
1178
+ obj.progress.$.notice.animate( effect, 1000, function() {
1179
+ obj.progress.$.notice.remove();
1180
+ } );
1181
+ };
1182
+
1183
+ /**
1184
+ * helper text for date select
1185
+ */
1186
+ obj.date_helper = function() {
1187
+ var $picker;
1188
+
1189
+ $picker = $( this );
1190
+
1191
+ if ( ! $picker.hasClass( 'tribe-datepicker' ) ) {
1192
+ return;
1193
+ }
1194
+
1195
+ var selected_date = $picker.val();
1196
+ if ( '' === selected_date || null === selected_date ) {
1197
+ return;
1198
+ }
1199
+
1200
+ var tmp = $picker.attr( 'id' ).match( 'tribe-ea-field-(.*)_start' );
1201
+ var origin = tmp[1];
1202
+ if ( '' === origin || null === origin ) {
1203
+ return;
1204
+ }
1205
+
1206
+ jQuery( '#tribe-date-helper-date-' + origin ).html( selected_date );
1207
+ };
1208
+
1209
+ obj.maybeLimitUrlStartDate = function() {
1210
+ if( 'url' !== obj.origin.val() ){
1211
+ return;
1212
+ }
1213
+
1214
+ if( 'schedule' === obj.importType.val() ){
1215
+ obj.urlImport.startDate.data( 'datepicker-min-date', 'today' );
1216
+
1217
+ return;
1218
+ }
1219
+
1220
+ obj.urlImport.startDate.data( 'datepicker-min-date', null );
1221
+ };
1222
+
1223
+ // Run Init on Document Ready
1224
+ $( document ).ready( obj.init );
1225
+ } )( jQuery, _, tribe_aggregator.fields, tribe_aggregator );
the-events-calendar.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Plugin Name: The Events Calendar
4
  * Description: The Events Calendar is a carefully crafted, extensible plugin that lets you easily share your events. Beautiful. Solid. Awesome.
5
- * Version: 5.1.2
6
  * Author: Modern Tribe, Inc.
7
  * Author URI: http://m.tri.be/1x
8
  * Text Domain: the-events-calendar
@@ -71,4 +71,4 @@ require_once dirname( TRIBE_EVENTS_FILE ) . '/src/Tribe/Main.php';
71
  Tribe__Events__Main::instance();
72
 
73
  register_activation_hook( TRIBE_EVENTS_FILE, array( 'Tribe__Events__Main', 'activate' ) );
74
- register_deactivation_hook( TRIBE_EVENTS_FILE, array( 'Tribe__Events__Main', 'deactivate' ) );
2
  /**
3
  * Plugin Name: The Events Calendar
4
  * Description: The Events Calendar is a carefully crafted, extensible plugin that lets you easily share your events. Beautiful. Solid. Awesome.
5
+ * Version: 5.1.2.1
6
  * Author: Modern Tribe, Inc.
7
  * Author URI: http://m.tri.be/1x
8
  * Text Domain: the-events-calendar
71
  Tribe__Events__Main::instance();
72
 
73
  register_activation_hook( TRIBE_EVENTS_FILE, array( 'Tribe__Events__Main', 'activate' ) );
74
+ register_deactivation_hook( TRIBE_EVENTS_FILE, array( 'Tribe__Events__Main', 'deactivate' ) );