Unlimited Elements For Elementor (Free Widgets, Addons, Templates) - Version 1.4.96

Version Description

Download this release

Release Info

Developer valiano
Plugin Icon 128x128 Unlimited Elements For Elementor (Free Widgets, Addons, Templates)
Version 1.4.96
Comparing to
See all releases

Code changes from version 1.4.88 to 1.4.96

Files changed (50) hide show
  1. assets_libraries/filters/ue_filters.js +41 -16
  2. assets_libraries/owl-carousel-new/owl.carousel.js +1 -0
  3. assets_libraries/remote/ue-remote-controls.js +1193 -253
  4. css/unitecreator_styles.css +10 -1
  5. images/banner-black-friday-2021.jpg +0 -0
  6. inc_php/framework/zip.class.php +5 -5
  7. inc_php/layouts/unitecreator_layouts.class.php +0 -25
  8. inc_php/manager/unitecreator_manager.class.php +15 -6
  9. inc_php/manager/unitecreator_manager_addons.class.php +13 -5
  10. inc_php/manager/unitecreator_manager_inline.class.php +10 -0
  11. inc_php/unitecreator_actions.class.php +1 -9
  12. inc_php/unitecreator_addon.class.php +31 -0
  13. inc_php/unitecreator_dialog_param.class.php +5 -11
  14. inc_php/unitecreator_filters_process.class.php +1 -1
  15. inc_php/unitecreator_globals.class.php +1 -1
  16. inc_php/unitecreator_helper.class.php +1 -1
  17. inc_php/unitecreator_helperhtml.class.php +15 -4
  18. inc_php/unitecreator_output.class.php +26 -12
  19. inc_php/unitecreator_params_editor.class.php +1 -2
  20. inc_php/unitecreator_params_processor.class.php +12 -7
  21. inc_php/unitecreator_settings.class.php +3 -0
  22. inc_php/unitecreator_template_engine.class.php +17 -2
  23. inc_php/unitecreator_unitegallery.class.php +684 -4
  24. includes.php +1 -1
  25. js/unitecreator_assets.js +0 -2
  26. js/unitecreator_includes.js +20 -9
  27. js/unitecreator_params_dialog.js +43 -9
  28. js/unitecreator_params_editor.js +67 -36
  29. provider/admin_notices.class.php +25 -5
  30. provider/core/plugins/unlimited_elements/elementor/elementor_background_widget.class.php +1 -1
  31. provider/core/plugins/unlimited_elements/elementor/elementor_widget.class.php +19 -5
  32. provider/core/plugins/unlimited_elements/elementor/pagination.class.php +1 -2
  33. provider/core/plugins/unlimited_elements/globals.class.php +8 -7
  34. provider/core/plugins/unlimited_elements/helper_provider_core.class.php +13 -10
  35. provider/core/plugins/unlimited_elements/settings/general_settings_el.xml +10 -1
  36. provider/functions_wordpress.class.php +26 -66
  37. provider/provider_globals.class.php +2 -0
  38. provider/provider_helper.class.php +21 -1
  39. provider/provider_layout.class.php +0 -16
  40. provider/provider_layouts.class.php +0 -16
  41. provider/provider_operations.class.php +1 -1
  42. provider/provider_params_processor.class.php +166 -42
  43. provider/provider_settings.class.php +82 -24
  44. provider/woocommerce_integrate.class.php +69 -0
  45. readme.txt +200 -114
  46. release_log.txt +68 -0
  47. unitecreator_admin.php +0 -1
  48. unlimited_elements.php +12 -10
  49. views/objects/addon_view.class.php +1 -1
  50. views/objects/addon_view_childparams.class.php +49 -0
assets_libraries/filters/ue_filters.js CHANGED
@@ -453,7 +453,7 @@ function UEDynamicFilters(){
453
  throw new Error("Grid not found!");
454
 
455
  //run the ajax, prevent default
456
-
457
  refreshAjaxGrid(objGrid);
458
 
459
  event.preventDefault();
@@ -525,8 +525,8 @@ function UEDynamicFilters(){
525
  throw new Error("Grid not found!");
526
 
527
  //run the ajax, prevent default
528
-
529
- refreshAjaxGrid(objGrid, true);
530
 
531
  }
532
 
@@ -1243,7 +1243,16 @@ function UEDynamicFilters(){
1243
  /**
1244
  * refresh ajax grid
1245
  */
1246
- function refreshAjaxGrid(objGrid, isLoadMore){
 
 
 
 
 
 
 
 
 
1247
 
1248
  //get all grid filters
1249
  var objFilters = objGrid.data("filters");
@@ -1300,7 +1309,7 @@ function UEDynamicFilters(){
1300
  * get grid ajax options
1301
  */
1302
  function getGridAjaxOptions(objFilters, objGrid){
1303
-
1304
  if(!objFilters)
1305
  return(false);
1306
 
@@ -1341,7 +1350,7 @@ function UEDynamicFilters(){
1341
 
1342
  if(objTerm)
1343
  arrTerms.push(objTerm);
1344
-
1345
  break;
1346
  case g_types.CHECKBOX:
1347
 
@@ -1561,16 +1570,34 @@ function UEDynamicFilters(){
1561
 
1562
  }
1563
 
 
1564
  /**
1565
- * ajax init grid filters
1566
  */
1567
- function ajaxInitGridFilters(objGrid){
 
 
 
1568
 
1569
- trace("ajax init");
 
1570
 
 
 
 
 
 
 
 
 
 
 
1571
 
 
1572
  }
1573
 
 
 
1574
  /**
1575
  * check and call ajax init filters
1576
  */
@@ -1585,14 +1612,12 @@ function UEDynamicFilters(){
1585
 
1586
  var objGrid = jQuery(grid);
1587
 
1588
- var objInitFilters = objGrid.data("ajax_init_filters");
1589
 
1590
- /*
1591
- trace("check for init after");
1592
- trace(objInitFilters);
1593
- */
1594
 
1595
- //ajaxInitGridFilters(objGrid);
1596
 
1597
  });
1598
 
@@ -1615,7 +1640,7 @@ function UEDynamicFilters(){
1615
 
1616
  initFilters();
1617
 
1618
- //ajaxInitFilters();
1619
 
1620
  }
1621
 
453
  throw new Error("Grid not found!");
454
 
455
  //run the ajax, prevent default
456
+
457
  refreshAjaxGrid(objGrid);
458
 
459
  event.preventDefault();
525
  throw new Error("Grid not found!");
526
 
527
  //run the ajax, prevent default
528
+
529
+ refreshAjaxGrid(objGrid, "loadmore");
530
 
531
  }
532
 
1243
  /**
1244
  * refresh ajax grid
1245
  */
1246
+ function refreshAjaxGrid(objGrid, refreshType){
1247
+
1248
+ var isLoadMore = (refreshType == "loadmore");
1249
+
1250
+ if(refreshType = "filters"){
1251
+
1252
+ trace("init by filters");
1253
+ return(false);
1254
+ }
1255
+
1256
 
1257
  //get all grid filters
1258
  var objFilters = objGrid.data("filters");
1309
  * get grid ajax options
1310
  */
1311
  function getGridAjaxOptions(objFilters, objGrid){
1312
+
1313
  if(!objFilters)
1314
  return(false);
1315
 
1350
 
1351
  if(objTerm)
1352
  arrTerms.push(objTerm);
1353
+
1354
  break;
1355
  case g_types.CHECKBOX:
1356
 
1570
 
1571
  }
1572
 
1573
+
1574
  /**
1575
+ * get filter taxonomy id's
1576
  */
1577
+ function getFilterTaxIDs(objFilter, objIDs){
1578
+
1579
+ //skip the if
1580
+ var objItems = objFilter.find(".ue_taxonomy_item");
1581
 
1582
+ if(objItems.length == 0)
1583
+ return([]);
1584
 
1585
+ jQuery.each(objItems, function(index, item){
1586
+
1587
+ var objItem = jQuery(item);
1588
+ var taxID = objItem.data("id");
1589
+
1590
+ if(!taxID)
1591
+ return(true);
1592
+
1593
+ objIDs[taxID] = true;
1594
+ });
1595
 
1596
+ return(objIDs);
1597
  }
1598
 
1599
+
1600
+
1601
  /**
1602
  * check and call ajax init filters
1603
  */
1612
 
1613
  var objGrid = jQuery(grid);
1614
 
1615
+ var objInitFilters = objGrid.data("filters_init_after");
1616
 
1617
+ if(!objInitFilters || objInitFilters.length == 0)
1618
+ return(true);
 
 
1619
 
1620
+ refreshAjaxGrid(objGrid, "filters");
1621
 
1622
  });
1623
 
1640
 
1641
  initFilters();
1642
 
1643
+ ajaxInitFilters();
1644
 
1645
  }
1646
 
assets_libraries/owl-carousel-new/owl.carousel.js CHANGED
@@ -3206,6 +3206,7 @@
3206
  * @param {Number} [speed=false] - The time in milliseconds for the transition.
3207
  */
3208
  Navigation.prototype.next = function(speed) {
 
3209
  $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
3210
  };
3211
 
3206
  * @param {Number} [speed=false] - The time in milliseconds for the transition.
3207
  */
3208
  Navigation.prototype.next = function(speed) {
3209
+
3210
  $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
3211
  };
3212
 
assets_libraries/remote/ue-remote-controls.js CHANGED
@@ -1,10 +1,23 @@
1
  /**
2
  * remote gallery api class
3
  */
4
- function UERemoteGalleryAPI(){
5
 
6
- var g_api, g_isInited;
7
- var t = this;
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  /**
10
  * console log some string
@@ -14,60 +27,354 @@ function UERemoteGalleryAPI(){
14
  }
15
 
16
  /**
17
- * validate that the object is inited
18
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  function validateInited(){
20
 
21
- if(g_isInited == false)
22
- throw new Error("The owl carousel API is not inited");
 
 
 
23
  }
24
 
25
  /**
26
- do some action
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  */
28
- this.doAction = function(action){
29
 
30
  validateInited();
 
 
 
 
 
 
 
 
 
 
 
 
31
 
 
32
  switch(action){
33
- case "next":
34
- g_api.nextItem();
 
 
 
 
35
  break;
36
- case "prev":
37
- g_api.prevItem();
 
 
 
 
 
 
 
 
 
38
  break;
 
39
  default:
40
- throw new Error("GALLERY API: Wrong action: "+action);
41
  break;
42
  }
43
 
44
  }
45
 
 
46
  /**
47
- * init the api
48
- */
49
- this.init = function(objParent){
50
 
51
- g_api = objParent.data("unitegallery-api");
52
- if(!g_api)
53
- return(false);
54
 
55
- g_isInited = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
- return(true);
58
  }
59
 
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
  }
63
 
64
 
 
65
  /**
66
- * remote tabs api class
67
  */
68
- function UERemoteTabsAPI(){
69
 
70
- var g_objTabs, g_isInited;
71
  var t = this;
72
 
73
  /**
@@ -89,23 +396,19 @@ function UERemoteTabsAPI(){
89
  /**
90
  do some action
91
  */
92
- this.doAction = function(action, arg){
93
 
94
  validateInited();
95
 
96
  switch(action){
97
- case "next":
98
-
99
- g_objTabs.trigger("next-tab");
100
-
101
  break;
102
  case "prev":
103
-
104
- g_objTabs.trigger("prev-tab");
105
-
106
  break;
107
  default:
108
- throw new Error("TABS API: Wrong action: "+action);
109
  break;
110
  }
111
 
@@ -116,12 +419,10 @@ function UERemoteTabsAPI(){
116
  */
117
  this.init = function(objParent){
118
 
119
- var tabsLoaded = objParent.data("tabs-loaded");
120
- if(!tabsLoaded)
121
  return(false);
122
-
123
- g_objTabs = objParent;
124
-
125
  g_isInited = true;
126
 
127
  return(true);
@@ -166,24 +467,28 @@ function UERemoteCarouselAPI(){
166
  return(total);
167
  }
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  /**
170
  do some action
171
  */
172
  this.doAction = function(action, arg1, arg2){
173
-
174
  validateInited();
175
 
 
176
  switch(action){
177
- case "next":
178
-
179
- g_owlCarousel.trigger('next.owl.carousel');
180
-
181
- break;
182
- case "prev":
183
-
184
- g_owlCarousel.trigger('prev.owl.carousel');
185
-
186
- break;
187
  case "play":
188
 
189
  g_owlCarousel.trigger('play.owl.autoplay');
@@ -212,13 +517,13 @@ function UERemoteCarouselAPI(){
212
 
213
  break;
214
  case "get_progress_time":
215
-
216
  var progressTime = g_owl.settings.autoplayTimeout / 1000;
217
  return(progressTime);
218
 
219
  break;
220
  case "get_modified_progress_time":
221
-
222
  var progressTime = (g_owl.settings.autoplayTimeout - g_owl.settings.smartSpeed) / 1000;
223
  return(progressTime);
224
 
@@ -238,8 +543,8 @@ function UERemoteCarouselAPI(){
238
  return(owlTotalItems);
239
 
240
  break;
241
- case "get_current_text":
242
-
243
  var owlCurrentItem = g_owl.relative(g_owl.current()) + 1;
244
  if(owlCurrentItem.toString().length < 2){
245
  owlCurrentItem = "0" + owlCurrentItem;
@@ -250,16 +555,23 @@ function UERemoteCarouselAPI(){
250
  case 'change_item':
251
 
252
  var total = getTotalItems()
 
 
253
  var slideNum = arg1;
254
 
 
 
 
255
  if(slideNum >= total)
256
  slideNum = (total-1);
257
  else
258
  if(slideNum < 0)
259
  slideNum = 0;
260
-
261
  g_owlCarousel.trigger('to.owl.carousel', [slideNum, null, true]);
262
 
 
 
263
  break;
264
  default:
265
  throw new Error("Carousel API: Wrong action: "+action);
@@ -268,13 +580,15 @@ function UERemoteCarouselAPI(){
268
 
269
  }
270
 
 
 
271
  /*
272
  events
273
  */
274
  this.onEvent = function(name, func){
275
-
276
  validateInited();
277
-
278
  switch(name){
279
  case "play":
280
 
@@ -287,7 +601,7 @@ function UERemoteCarouselAPI(){
287
 
288
  break;
289
  case "change":
290
-
291
  g_owlCarousel.on("changed.owl.carousel", func);
292
 
293
  break;
@@ -313,6 +627,16 @@ function UERemoteCarouselAPI(){
313
  }
314
  }
315
 
 
 
 
 
 
 
 
 
 
 
316
  /**
317
  * init the api
318
  */
@@ -323,12 +647,11 @@ function UERemoteCarouselAPI(){
323
 
324
  g_owlCarousel = objParent;
325
 
326
-
327
  g_owl = g_owlCarousel.data("owl.carousel");
328
-
329
  if(!g_owl)
330
  return(false);
331
-
332
  g_isInited = true;
333
 
334
  return(true);
@@ -337,6 +660,271 @@ function UERemoteCarouselAPI(){
337
 
338
  }
339
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  /**
341
  * ---------------------------------------------------
342
  * remote carousel api class
@@ -344,7 +932,7 @@ function UERemoteCarouselAPI(){
344
  function UERemoteWidgets(){
345
 
346
  var g_objParent, g_objWidget, g_parentID;
347
- var g_api;
348
  var t = this;
349
 
350
  var g_vars = {
@@ -352,13 +940,21 @@ function UERemoteWidgets(){
352
  funcOnInit:null,
353
  is_editor:null,
354
  widget_id:null,
355
- init_options:null
 
 
 
 
 
 
 
 
356
  };
357
 
358
  var g_types = {
359
  CAROUSEL:"carousel",
360
- TABS:"tabs",
361
- GALLERY:"gallery"
362
  };
363
 
364
 
@@ -422,8 +1018,14 @@ function UERemoteWidgets(){
422
  if(g_objParent.hasClass("owl-carousel"))
423
  return(g_types.CAROUSEL);
424
 
 
 
 
 
 
 
425
  var remoteType = g_objParent.data("remote-type");
426
-
427
  if(!remoteType)
428
  return(null);
429
 
@@ -442,6 +1044,8 @@ function UERemoteWidgets(){
442
  }
443
 
444
  return(null);
 
 
445
  }
446
 
447
  /**
@@ -466,13 +1070,32 @@ function UERemoteWidgets(){
466
 
467
  var elementOffset = objElement.offset();
468
 
 
 
 
 
 
469
  jQuery.each(objParents, function(index, parent){
470
 
471
  var objParent = jQuery(parent);
472
  var parentOffset = objParent.offset();
473
 
 
 
 
 
 
 
 
474
  var distance = getOffsetsDistance(parentOffset, elementOffset);
475
 
 
 
 
 
 
 
 
476
  if(distance < minDiff){
477
  minDiff = distance;
478
  objClosest = objParent;
@@ -487,12 +1110,18 @@ function UERemoteWidgets(){
487
  /**
488
  * detect closest parent
489
  */
490
- function detectClosestParent(){
491
 
492
- var objParents = jQuery(".uc-remote-parent").not(g_objWidget);
 
 
 
 
 
 
493
 
494
  var numParents = objParents.length;
495
-
496
  if(numParents == 0)
497
  return(null);
498
 
@@ -501,16 +1130,27 @@ function UERemoteWidgets(){
501
 
502
  //filter by auto
503
 
 
 
 
504
  var objParentsFiltered = objParents.filter("[data-remoteid='"+g_parentID+"']");
505
 
506
- if(objParentsFiltered.lenght == 1)
507
  return(objParentsFiltered);
508
 
509
  //find by offset
510
- var objClosest = getClosestByOffset(objParentsFiltered, g_objWidget);
 
 
 
 
 
511
 
512
  if(objClosest)
513
  return(objClosest);
 
 
 
514
 
515
  var firstParent = jQuery(objParentsFiltered[0]);
516
 
@@ -522,44 +1162,87 @@ function UERemoteWidgets(){
522
  * set parent object
523
  */
524
  function setParentObject(){
525
-
526
  var objForceParent = getVal(g_vars.init_options, "force_parent_obj");
527
 
 
 
 
 
 
528
  if(objForceParent){
 
529
  g_objParent = objForceParent;
 
 
 
 
 
 
530
  return(false);
531
  }
532
 
533
  if(!g_parentID)
534
  throw new Error("Parent controller ID not found");
535
-
536
  if(!g_objParent || g_objParent.length == 0){
537
 
538
  if(g_parentID == "auto"){
539
-
540
  g_objParent = detectClosestParent();
541
 
 
 
 
 
 
542
  if(!g_objParent)
543
  throw new Error("Can't detect remote parent");
544
-
545
  }
546
  else{
547
- g_objParent = jQuery(".uc-remote-parent[data-remoteid='"+g_parentID+"']").not(g_objWidget);
548
 
 
 
 
 
 
 
 
 
 
 
 
 
549
  if(g_objParent.length == 0)
550
  throw new Error("Parent widget with remote name:'"+g_parentID+"' not found");
551
  }
552
 
553
  }
554
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  }
556
 
 
557
  /**
558
- * init parent
559
- */
560
- function initParent(){
561
-
562
- setParentObject();
563
 
564
  //set type and related objects
565
  if(!g_api){
@@ -571,14 +1254,21 @@ function UERemoteWidgets(){
571
  throw new Error("No parent type found");
572
  }
573
 
 
574
  //init the api
575
  switch(parentType){
576
  case g_types.CAROUSEL:
577
  g_api = new UERemoteCarouselAPI();
578
  break;
 
 
 
 
 
579
  case g_types.TABS:
580
 
581
- g_api = new UERemoteTabsAPI();
 
582
 
583
  break;
584
  case g_types.GALLERY:
@@ -591,10 +1281,28 @@ function UERemoteWidgets(){
591
  break;
592
  }
593
 
594
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
595
 
596
- var isInited = g_api.init(g_objParent);
597
 
 
 
598
  return(isInited);
599
  }
600
 
@@ -609,9 +1317,11 @@ function UERemoteWidgets(){
609
 
610
  g_vars.is_inited = initParent();
611
 
612
- if(g_vars.is_inited == false)
 
613
  g_objParent.on("uc-object-ready", func);
614
-
 
615
  }
616
 
617
 
@@ -624,8 +1334,12 @@ function UERemoteWidgets(){
624
  if(g_vars.is_inited == false)
625
  throw new Error("Widget not inited");
626
 
627
- if(typeof objElement == "string")
 
628
  objElement = g_objWidget.find(objElement);
 
 
 
629
 
630
  if(!objElement || objElement.length == 0)
631
  throw new Error("Element not inited");
@@ -635,14 +1349,15 @@ function UERemoteWidgets(){
635
 
636
  //avoid double action
637
  var linkedAction = objElement.data("uc-action");
 
638
  if(linkedAction)
639
- throw new Error("No double actions allowed! existing: "+linkedAction+" new: "+action);
640
 
641
  objElement.data("uc-action", action);
642
 
643
  objElement.on("click",function(){
644
 
645
- g_api.doAction(action);
646
 
647
  });
648
 
@@ -653,7 +1368,7 @@ function UERemoteWidgets(){
653
  * run this function after the widget is ready to use
654
  */
655
  function onWidgetReady(){
656
-
657
  checkWidgetDebug();
658
 
659
  var isEditorMode = isInsideEditor();
@@ -671,7 +1386,7 @@ function UERemoteWidgets(){
671
  }
672
 
673
 
674
- function _______ERROR_________(){}
675
 
676
 
677
  /**
@@ -682,14 +1397,17 @@ function UERemoteWidgets(){
682
  if(!g_objWidget || g_objWidget.length == 0)
683
  return(false);
684
 
685
- //don't hide if no message
686
 
687
- var hasError = g_objWidget.data("uc-has-error");
 
 
688
 
689
- if(hasError !== true)
690
  return(false);
691
 
692
- var objError = g_objWidget.find('.uc-remote-error');
 
693
 
694
  objError.hide();
695
 
@@ -697,31 +1415,60 @@ function UERemoteWidgets(){
697
  "border" : "none"
698
  });
699
 
700
- g_objWidget.data("uc-has-error", false);
701
-
 
702
  }
703
 
 
 
 
 
 
 
 
 
 
 
 
704
 
705
 
706
  /**
707
  * add error message div on the widget div
708
  *
709
  */
710
- function addErrorMessageDiv(objWidget){
711
 
712
- var divError = "<div class='uc-remote-error'></div>";
713
- g_objWidget.append(divError);
714
 
715
- var objError = objWidget.find('.uc-remote-error');
716
 
717
- objError.css({
718
- "position":"absolute",
719
- "color":"red",
720
- "top":"-30px",
721
- "left":"0px"
722
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
723
 
724
- var objError = objWidget.find('.uc-remote-error');
725
 
726
  return(objError);
727
  }
@@ -729,39 +1476,53 @@ function UERemoteWidgets(){
729
  /**
730
  * display some error on widget interface
731
  */
732
- function displayErrorOnWidget(objWidget, message){
 
 
 
 
 
 
 
 
 
 
733
 
734
- var objError = objWidget.find('.uc-remote-error');
735
-
736
  //add error div if missing. pause error in editor
737
  //second time the div will be not empty and it will show the message
738
- if(objError.length == 0){
739
- objError = addErrorMessageDiv(objWidget);
 
740
 
741
- var isInEditor = isInsideEditor();
742
- if(isInEditor == true){
 
743
 
744
- setTimeout(function(){
745
- displayErrorOnWidget(objWidget, message);
746
- },2000);
 
 
 
 
 
747
 
748
- return(false);
749
  }
750
 
751
  }
752
 
753
- //add the error
754
-
755
- g_objWidget.data("uc-has-error",true);
756
-
757
- g_objWidget.css({
758
- "border" : "2px solid red",
759
- "position" : "relative"
760
- });
761
-
762
- objError.show();
763
 
764
- objError.html(message);
 
765
 
766
  }
767
 
@@ -771,13 +1532,19 @@ function UERemoteWidgets(){
771
  */
772
  function displayErrorMessage(message){
773
 
774
- if(g_objWidget && g_objWidget.length)
775
- displayErrorOnWidget(g_objWidget, message);
776
-
777
- trace(g_objWidget);
778
-
779
- console.log("UE Remote Error: "+message);
780
- console.log(message);
 
 
 
 
 
 
781
 
782
  }
783
 
@@ -787,9 +1554,12 @@ function UERemoteWidgets(){
787
  /**
788
  * return if the debug is active
789
  */
790
- function isDebugActive(){
791
 
792
- var isActive = g_objWidget.data("debug_active");
 
 
 
793
 
794
  if(isActive === true)
795
  return(true);
@@ -801,50 +1571,77 @@ function UERemoteWidgets(){
801
  /**
802
  * remove debug visual from the widget
803
  */
804
- function removeDebugVisual(){
 
 
 
805
 
806
  g_objWidget.data("debug_active", false);
807
 
808
- g_objWidget.css("border","none");
 
 
 
809
  }
810
 
 
811
  /**
812
  * set debug visual
813
  */
814
- function setDebugVisual(color){
 
 
 
 
 
 
 
 
 
 
 
815
 
816
- g_objWidget.data("debug_active", true);
 
 
 
 
 
817
 
818
- g_objWidget.css("border","3px solid "+color);
 
819
 
 
820
  }
821
 
 
822
  /**
823
- * check widget debug
824
  */
825
- function checkWidgetDebug(){
826
 
827
- //get debug color
 
828
 
829
- if(!g_objParent || g_vars.is_inited == false){
830
- removeDebugVisual();
831
- return(false);
832
- }
833
-
834
- var dataDebug = g_objParent.data("debug");
835
- var isDebug = (dataDebug === true);
836
 
837
- var isActive = isDebugActive();
838
 
839
- //trace("check! "+isActive+" "+isDebug);
840
- //trace(g_objParent);
 
 
 
841
 
842
  //remove debug if active but no need
843
 
844
  if(isDebug == false){
845
 
846
  if(isActive == true)
847
- removeDebugVisual();
848
 
849
  return(false);
850
  }
@@ -854,28 +1651,100 @@ function UERemoteWidgets(){
854
  if(isActive == false){
855
 
856
  //get parent color
857
- var color = addParentDebug();
858
-
859
- setDebugVisual(color);
860
 
861
  }
862
 
863
 
864
  }
865
 
866
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
867
  this.onEvent = function(name, func){
868
- g_api.onEvent(name,func)
869
  }
870
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
871
  this.doAction = function(action, arg1, arg2){
872
- return(g_api.doAction(action, arg1, arg2));
 
 
 
 
 
 
 
 
 
 
 
873
  }
874
 
875
  /**
876
  * add the parent some debug color
877
  */
878
- function addParentDebug(){
 
 
 
879
 
880
  var color = g_objParent.data("uc-debug-color");
881
  if(color)
@@ -901,6 +1770,39 @@ function UERemoteWidgets(){
901
  }
902
 
903
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
904
  function _______EDITOR_RELATED_________(){}
905
 
906
 
@@ -938,8 +1840,8 @@ function UERemoteWidgets(){
938
 
939
  g_objParent = null;
940
  g_api = null;
941
- g_vars.is_inited = false
942
- g_vars.funcOnInit = null;
943
  }
944
 
945
 
@@ -947,7 +1849,7 @@ function UERemoteWidgets(){
947
  * check widget inside editor
948
  */
949
  function checkWidgetInsideEditor(){
950
-
951
  //check for disconnect
952
  try{
953
 
@@ -959,6 +1861,7 @@ function UERemoteWidgets(){
959
 
960
  //disconnect
961
  resetSettingsInsideEditor();
 
962
  }
963
 
964
  }else{
@@ -966,8 +1869,21 @@ function UERemoteWidgets(){
966
  //check for connect
967
  g_vars.is_inited = initParent();
968
 
969
- if(g_vars.is_inited == false)
970
- g_objParent.on("uc-object-ready", g_vars.funcOnInit);
 
 
 
 
 
 
 
 
 
 
 
 
 
971
  }
972
 
973
  checkWidgetDebug();
@@ -988,9 +1904,9 @@ function UERemoteWidgets(){
988
  * on widget init
989
  */
990
  this.onWidgetInit = function(widgetID, func, options){
991
-
992
  try{
993
-
994
  if(!g_vars.funcOnInit){
995
 
996
  if(typeof func != "function")
@@ -998,16 +1914,39 @@ function UERemoteWidgets(){
998
 
999
  g_vars.funcOnInit = func;
1000
  }
 
 
 
1001
 
1002
- g_vars.init_options = options;
 
1003
 
1004
  initGlobal(widgetID, t.onWidgetInit);
1005
-
1006
  if(g_vars.is_inited == false)
1007
  return(false);
1008
 
1009
- //widget is inited
 
 
 
 
 
 
1010
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1011
  onWidgetReady();
1012
 
1013
  g_vars.funcOnInit(g_objWidget);
@@ -1029,84 +1968,58 @@ function UERemoteWidgets(){
1029
  }
1030
 
1031
  /**
1032
- * set sync events between 2 apis
1033
  */
1034
- function setSyncEvents(objLocalAPI, objRemoteAPI){
1035
 
1036
- var totalItemsLocal = objLocalAPI.doAction("get_total_items");
1037
- var totalItemsRemote = objRemoteAPI.doAction("get_total_items");
1038
-
1039
- if(totalItemsLocal !== totalItemsRemote)
1040
- throw new Error("Sync failed, number of items should be the same. Now it's "+totalItemsLocal+" and "+totalItemsRemote);
1041
-
1042
-
1043
- //sync on local change
1044
-
1045
- objLocalAPI.onEvent("change",function(){
1046
-
1047
- var currentNumCurrent = objLocalAPI.doAction("get_num_current");
1048
- var currentNumRemote = objRemoteAPI.doAction("get_num_current");
1049
-
1050
- if(currentNumCurrent != currentNumRemote)
1051
- objRemoteAPI.doAction("change_item", currentNumCurrent);
1052
- });
1053
 
 
1054
 
1055
- //sync on remote change
 
1056
 
1057
- objRemoteAPI.onEvent("change",function(){
1058
-
1059
- var currentNumCurrent = objLocalAPI.doAction("get_num_current");
1060
- var currentNumRemote = objRemoteAPI.doAction("get_num_current");
1061
-
1062
- if(currentNumCurrent != currentNumRemote)
1063
- objLocalAPI.doAction("change_item", currentNumRemote);
1064
- });
1065
 
 
1066
 
 
1067
  }
1068
-
1069
 
1070
  /**
1071
- * start parent sync
1072
  */
1073
  function startParentSync(){
1074
 
1075
- var currentID = g_objParent.attr("id");
1076
 
1077
- var classSync = "uc-is-sync";
1078
-
1079
- if(g_objParent.hasClass(classSync))
1080
  return(false);
1081
 
1082
- var objRemoteAPI = new UERemoteWidgets();
1083
- var objLocalAPI = new UERemoteWidgets();
1084
 
1085
- objRemoteAPI.onWidgetInit(currentID, function(objWidget){
1086
-
1087
- var objConnectedParent = objRemoteAPI.getParent();
1088
-
1089
- //check classes
1090
- if(objConnectedParent.hasClass(classSync))
1091
- return(false);
1092
-
1093
- if(objWidget.hasClass(classSync))
1094
- return(false);
1095
-
1096
- //add classs
1097
-
1098
- objConnectedParent.addClass(classSync)
1099
- objWidget.addClass(classSync);
1100
-
1101
- //create second api
1102
- objLocalAPI.onWidgetInit(currentID, function(objWidget){
1103
-
1104
- setSyncEvents(objLocalAPI, objRemoteAPI);
1105
 
1106
- },{force_parent_obj:objWidget});
1107
-
1108
- });
 
 
 
 
 
1109
 
 
 
 
 
 
 
 
 
 
 
1110
 
1111
  }
1112
 
@@ -1114,25 +2027,51 @@ function UERemoteWidgets(){
1114
  /**
1115
  * parent init, init the debug
1116
  */
1117
- this.onParentInit = function(objParent){
1118
-
1119
- g_objParent = objParent;
1120
-
1121
- if(!g_objParent)
1122
- return(false);
1123
 
1124
- if(g_objParent.length == 0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1125
  return(false);
1126
-
1127
- var isDebug = g_objParent.data("debug");
1128
-
1129
- if(isDebug === true)
1130
- addParentDebug(objParent);
1131
-
1132
- var isSync = objParent.data("sync");
1133
-
1134
- if(isSync == true)
1135
- startParentSync();
1136
 
1137
  }
1138
 
@@ -1150,6 +2089,7 @@ function UERemoteWidgets(){
1150
 
1151
  }
1152
 
 
1153
  /**
1154
  * get the connected parent
1155
  */
@@ -1160,11 +2100,11 @@ function UERemoteWidgets(){
1160
 
1161
  }
1162
 
1163
- jQuery("body").on("uc-remote-parent-init",function(event, objParent){
1164
 
1165
  var objRemote = new UERemoteWidgets();
1166
 
1167
- objRemote.onParentInit(objParent);
1168
 
1169
  });
1170
 
1
  /**
2
  * remote gallery api class
3
  */
4
+ function UERemoteGeneralAPI(){
5
 
6
+ var t = this, g_objParent;
7
+ var g_isTypeEvents = false;
8
+ var g_options = null;
9
+
10
+
11
+ var g_vars = {
12
+ class_items:"",
13
+ class_active:"",
14
+ selector_item_trigger:""
15
+ };
16
+
17
+ var g_temp = {
18
+ handle:null,
19
+ trashold:50
20
+ };
21
 
22
  /**
23
  * console log some string
27
  }
28
 
29
  /**
30
+ * get object property
31
+ */
32
+ function getVal(obj, name, defaultValue){
33
+
34
+ if(!defaultValue)
35
+ var defaultValue = "";
36
+
37
+ var val = "";
38
+
39
+ if(!obj || typeof obj != "object")
40
+ val = defaultValue;
41
+ else if(obj.hasOwnProperty(name) == false){
42
+ val = defaultValue;
43
+ }else{
44
+ val = obj[name];
45
+ }
46
+
47
+ return(val);
48
+ }
49
+
50
+
51
+ /**
52
+ * run function with trashold
53
+ */
54
+ function runWithTrashold(func, trashold){
55
+
56
+ if(g_temp.handle)
57
+ clearTimeout(g_temp.handle);
58
+
59
+ g_temp.handle = setTimeout(func, g_temp.trashold);
60
+
61
+ };
62
+
63
+
64
+ /**
65
+ * validate inited
66
+ */
67
  function validateInited(){
68
 
69
+ var isInited = g_objParent.data("remote_inited");
70
+
71
+ if(isInited == false)
72
+ throw new Error("The remote parent not inited");
73
+
74
  }
75
 
76
  /**
77
+ * get items objet
78
+ */
79
+ function getObjItems(){
80
+
81
+ var objItems = g_objParent.find("."+g_vars.class_items);
82
+
83
+ return(objItems);
84
+ }
85
+
86
+
87
+ /**
88
+ * get total items
89
+ */
90
+ function getNumTotal(){
91
+
92
+ var objItems = g_objParent.find("."+g_vars.class_items);
93
+
94
+ var numTotal = objItems.length;
95
+
96
+ return(numTotal);
97
+ }
98
+
99
+
100
+ /**
101
+ * get current item
102
+ */
103
+ function getObjCurrentItem(){
104
+
105
+ var selector = "."+g_vars.class_items+"."+g_vars.class_active;
106
+
107
+ var objCurrent = g_objParent.find(selector);
108
+
109
+ return(objCurrent);
110
+ }
111
+
112
+
113
+ /**
114
+ * get current item
115
+ */
116
+ function getNumCurrent(){
117
+
118
+ var objCurrent = getObjCurrentItem();
119
+
120
+ if(objCurrent.length == 0)
121
+ return(0);
122
+
123
+ var index = objCurrent.index();
124
+
125
+ return(index);
126
+ }
127
+
128
+ /**
129
+ * get item by index
130
+ */
131
+ function getItem(index){
132
+
133
+ if(index < 0)
134
+ index = 0;
135
+
136
+ var objItems = getObjItems();
137
+
138
+ if(objItems.length == 0)
139
+ return(null);
140
+
141
+ if(index >= objItems.length )
142
+ index = objItems.length-1;
143
+
144
+ var objItem = jQuery(objItems[index]);
145
+
146
+ return(objItem);
147
+ }
148
+
149
+
150
+
151
+ /**
152
+ * get item number
153
+ */
154
+ function getItemNum(num){
155
+
156
+ var total = getNumTotal();
157
+
158
+ if(jQuery.isNumeric(num) == false)
159
+ throw new Error("num item should be numeric");
160
+
161
+ if(num >= total )
162
+ num = total-1;
163
+
164
+ if(num < 0)
165
+ num = 0;
166
+
167
+ return(num);
168
+ }
169
+
170
+
171
+ /**
172
+ * change item
173
+ */
174
+ function changeItem(mixed){
175
+
176
+ var numItem = getItemNum(mixed);
177
+
178
+ var objItem = getItem(numItem);
179
+
180
+ if(!g_vars.selector_item_trigger){
181
+
182
+ objItem.trigger("click");
183
+ return(false);
184
+ }
185
+
186
+ var objInner = objItem.find(g_vars.selector_item_trigger);
187
+
188
+ if(objInner.length == 0){
189
+ trace(objItem);
190
+ throw new Error("Can't find inner by selector:"+g_vars.selector_item_trigger);
191
+ }
192
+
193
+ objInner.trigger("click");
194
+
195
+ }
196
+
197
+
198
+
199
+ /*
200
+ events
201
+ */
202
+ this.onEvent = function(name, func){
203
+
204
+ validateInited();
205
+
206
+ switch(name){
207
+ case "change":
208
+
209
+ g_objParent.on("uc_change", func);
210
+
211
+ break;
212
+ default:
213
+ throw new Error("General API: Wrong event: "+event);
214
+ break;
215
+
216
+ }
217
+ }
218
+
219
+
220
+ /**
221
+ * do some action
222
  */
223
+ this.doAction = function(action, arg1, arg2){
224
 
225
  validateInited();
226
+
227
+ if(g_isTypeEvents == true){
228
+
229
+ var funcRunAction = getVal(g_options, "func_doAction");
230
+
231
+ if(!funcRunAction)
232
+ throw new Error("Missing option: 'func_doAction' ");
233
+
234
+ var response = g_options.func_doAction(action, arg1, arg2);
235
+
236
+ return(response);
237
+ }
238
 
239
+
240
  switch(action){
241
+
242
+ case 'get_num_current':
243
+
244
+ var current = getNumCurrent();
245
+
246
+ return(current);
247
  break;
248
+ case "get_total_items":
249
+
250
+ var total = getNumTotal();
251
+
252
+ return(total);
253
+
254
+ break;
255
+ case 'change_item':
256
+
257
+ changeItem(arg1);
258
+
259
  break;
260
+
261
  default:
262
+ throw new Error("General API: Wrong action: "+action);
263
  break;
264
  }
265
 
266
  }
267
 
268
+
269
  /**
270
+ * init obzerver events
271
+ */
272
+ function initEvents(){
273
 
274
+ var objItems = getObjItems();
275
+
276
+ jQuery.each(objItems, function(index, item){
277
 
278
+ var observer = new MutationObserver(function(records){
279
+
280
+ runWithTrashold(function(){
281
+
282
+ g_objParent.trigger("uc_change");
283
+
284
+ });
285
+
286
+ });
287
+
288
+ var config = { attributes: true};
289
+
290
+ observer.observe(item, config);
291
+ });
292
 
 
293
  }
294
 
295
 
296
+ /**
297
+ * get element
298
+ */
299
+ this.getElement = function(){
300
+
301
+ return(g_objParent);
302
+ }
303
+
304
+
305
+ /**
306
+ * init by classes
307
+ */
308
+ function initByClasses(){
309
+
310
+ try{
311
+
312
+ var widgetName = g_objParent.data("widgetname");
313
+
314
+ g_vars.class_items = getVal(g_options, "class_items");
315
+
316
+ if(!g_vars.class_items)
317
+ throw new Error(widgetName +" - missing 'class_items' option");
318
+
319
+ g_vars.class_active = getVal(g_options, "class_active");
320
+
321
+ if(!g_vars.class_active)
322
+ throw new Error(widgetName +" - missing 'class_active' in options");
323
+
324
+ g_vars.selector_item_trigger = getVal(g_options, "selector_item_trigger");
325
+
326
+ }
327
+ catch(e){
328
+
329
+ trace("ERROR: "+e);
330
+
331
+ trace("passed options: ");
332
+ trace(g_options);
333
+ throw e;
334
+ }
335
+ }
336
+
337
+
338
+
339
+ /**
340
+ * init the api
341
+ */
342
+ this.init = function(objParent, options){
343
+
344
+
345
+ //not allow to init general api without options
346
+ if(!options)
347
+ return(false);
348
+
349
+ g_objParent = objParent;
350
+
351
+ var connectType = getVal(options, "connect_type");
352
+ if(connectType == "events")
353
+ g_isTypeEvents = true;
354
+
355
+ g_options = options;
356
+
357
+ if(g_isTypeEvents == false)
358
+ initByClasses();
359
+
360
+ g_objParent.data("remote_inited", true);
361
+
362
+ if(g_isTypeEvents == false)
363
+ setTimeout(initEvents, 1000);
364
+
365
+ return(true);
366
+ }
367
 
368
  }
369
 
370
 
371
+
372
  /**
373
+ * remote gallery api class
374
  */
375
+ function UERemoteGalleryAPI(){
376
 
377
+ var g_api, g_isInited;
378
  var t = this;
379
 
380
  /**
396
  /**
397
  do some action
398
  */
399
+ this.doAction = function(action){
400
 
401
  validateInited();
402
 
403
  switch(action){
404
+ case "next":
405
+ g_api.nextItem();
 
 
406
  break;
407
  case "prev":
408
+ g_api.prevItem();
 
 
409
  break;
410
  default:
411
+ throw new Error("GALLERY API: Wrong action: "+action);
412
  break;
413
  }
414
 
419
  */
420
  this.init = function(objParent){
421
 
422
+ g_api = objParent.data("unitegallery-api");
423
+ if(!g_api)
424
  return(false);
425
+
 
 
426
  g_isInited = true;
427
 
428
  return(true);
467
  return(total);
468
  }
469
 
470
+ /**
471
+ * reset the autoplay if exists
472
+ */
473
+ function resetAutoplay(){
474
+
475
+ if(g_owl.settings.autoplay == false)
476
+ return(false);
477
+
478
+ g_owlCarousel.trigger('stop.owl.autoplay');
479
+ g_owlCarousel.trigger('play.owl.autoplay');
480
+
481
+ }
482
+
483
  /**
484
  do some action
485
  */
486
  this.doAction = function(action, arg1, arg2){
487
+
488
  validateInited();
489
 
490
+
491
  switch(action){
 
 
 
 
 
 
 
 
 
 
492
  case "play":
493
 
494
  g_owlCarousel.trigger('play.owl.autoplay');
517
 
518
  break;
519
  case "get_progress_time":
520
+
521
  var progressTime = g_owl.settings.autoplayTimeout / 1000;
522
  return(progressTime);
523
 
524
  break;
525
  case "get_modified_progress_time":
526
+
527
  var progressTime = (g_owl.settings.autoplayTimeout - g_owl.settings.smartSpeed) / 1000;
528
  return(progressTime);
529
 
543
  return(owlTotalItems);
544
 
545
  break;
546
+ case "get_current_text":
547
+
548
  var owlCurrentItem = g_owl.relative(g_owl.current()) + 1;
549
  if(owlCurrentItem.toString().length < 2){
550
  owlCurrentItem = "0" + owlCurrentItem;
555
  case 'change_item':
556
 
557
  var total = getTotalItems()
558
+ var currentItem = g_owl.relative(g_owl.current());
559
+
560
  var slideNum = arg1;
561
 
562
+ if(slideNum == currentItem)
563
+ return(false);
564
+
565
  if(slideNum >= total)
566
  slideNum = (total-1);
567
  else
568
  if(slideNum < 0)
569
  slideNum = 0;
570
+
571
  g_owlCarousel.trigger('to.owl.carousel', [slideNum, null, true]);
572
 
573
+ resetAutoplay();
574
+
575
  break;
576
  default:
577
  throw new Error("Carousel API: Wrong action: "+action);
580
 
581
  }
582
 
583
+
584
+
585
  /*
586
  events
587
  */
588
  this.onEvent = function(name, func){
589
+
590
  validateInited();
591
+
592
  switch(name){
593
  case "play":
594
 
601
 
602
  break;
603
  case "change":
604
+
605
  g_owlCarousel.on("changed.owl.carousel", func);
606
 
607
  break;
627
  }
628
  }
629
 
630
+
631
+ /**
632
+ * get the element
633
+ */
634
+ this.getElement = function(){
635
+
636
+ return(g_owlCarousel);
637
+ }
638
+
639
+
640
  /**
641
  * init the api
642
  */
647
 
648
  g_owlCarousel = objParent;
649
 
 
650
  g_owl = g_owlCarousel.data("owl.carousel");
651
+
652
  if(!g_owl)
653
  return(false);
654
+
655
  g_isInited = true;
656
 
657
  return(true);
660
 
661
  }
662
 
663
+ /**
664
+ * sync object
665
+ */
666
+ function UESyncObject(){
667
+
668
+ var g_objApis = {};
669
+ var g_groupName, g_objIDs;
670
+ var t = this;
671
+
672
+ var g_vars = {
673
+ is_editor:false,
674
+ is_editor_func_started:false
675
+ };
676
+
677
+ /**
678
+ * console log some string
679
+ */
680
+ function trace(str){
681
+ console.log(str);
682
+ }
683
+
684
+
685
+
686
+ /**
687
+ * validate api, that they match the existing by number of items
688
+ */
689
+ function validate(objAPI){
690
+
691
+ if(g_objApis.length == 0)
692
+ return(false);
693
+
694
+ var numItems = objAPI.doAction("get_total_items");
695
+
696
+ //check with first existing api number of items
697
+ for(var elID in g_objApis){
698
+
699
+ var firstExistingAPI = g_objApis[elID];
700
+
701
+ var numItemsExisting = firstExistingAPI.doAction("get_total_items");
702
+
703
+ if(numItemsExisting !== numItems)
704
+ throw new Error("Sync failed, number of items should be the same. Now it's "+numItems+" and "+numItemsExisting);
705
+
706
+ return(false);
707
+ }
708
+
709
+
710
+ }
711
+
712
+
713
+ /**
714
+ * set options
715
+ */
716
+ this.setOptions = function(groupName, isEditor){
717
+
718
+ if(isEditor === true)
719
+ g_vars.is_editor = true;
720
+
721
+ if(!g_groupName)
722
+ g_groupName = groupName;
723
+
724
+ }
725
+
726
+
727
+ /**
728
+ * get api parent id
729
+ */
730
+ function getElementID(objAPI){
731
+
732
+ var objElement = objAPI.getElement();
733
+
734
+ var elementID = objElement.attr("id");
735
+
736
+ return(elementID);
737
+ }
738
+
739
+
740
+ /**
741
+ * get all ips except the given
742
+ */
743
+ function mapAPIs(func, objElement){
744
+
745
+ var elementID = null;
746
+
747
+ if(objElement){
748
+
749
+ var elementID = objElement.attr("id");
750
+
751
+ if(g_objApis.length == 1)
752
+ return(null);
753
+ }
754
+
755
+ for(var elID in g_objApis){
756
+
757
+ var api = g_objApis[elID];
758
+
759
+ //except if exists
760
+ if(elementID && elID == elementID)
761
+ continue;
762
+
763
+ func(api);
764
+
765
+ }
766
+
767
+ }
768
+
769
+
770
+ /**
771
+ * activate change command on all other apis
772
+ */
773
+ function onItemChange(objAPI){
774
+
775
+ var numCurrent = objAPI.doAction("get_num_current");
776
+
777
+ var objElement = objAPI.getElement();
778
+
779
+ mapAPIs(function(api){
780
+
781
+ api.doAction("change_item", numCurrent);
782
+
783
+ }, objElement);
784
+
785
+ }
786
+
787
+
788
+ /**
789
+ * trigger some action
790
+ */
791
+ function trigger(action, params){
792
+
793
+ var realAction = "uc_remote_sync_"+g_groupName+"_action_"+action;
794
+
795
+ jQuery("body").trigger(realAction, params);
796
+ }
797
+
798
+
799
+ /**
800
+ * on event
801
+ */
802
+ this.on = function(action, func){
803
+
804
+ var realAction = "uc_remote_sync_"+g_groupName+"_action_"+action;
805
+
806
+ jQuery("body").on(realAction, func);
807
+
808
+ }
809
+
810
+
811
+ /**
812
+ * get debug text
813
+ */
814
+ this.getDebugText = function(objElement){
815
+
816
+ var text = "sync group: <b>" + g_groupName+"</b>, ";
817
+
818
+ var textWidgets = "";
819
+
820
+ mapAPIs(function(api){
821
+
822
+ var objElement = api.getElement();
823
+ var widgetName = objElement.data("widgetname");
824
+ var widgetID = objElement.attr("id");
825
+
826
+ if(textWidgets)
827
+ textWidgets += ", ";
828
+
829
+ textWidgets += "<a href='#"+widgetID+"' style='color:green;text-decoration:underline'><b>" + widgetName + "</b></a>";
830
+
831
+ }, objElement);
832
+
833
+ if(textWidgets)
834
+ text += "sync with: " + textWidgets;
835
+
836
+ return(text);
837
+ }
838
+
839
+
840
+ /**
841
+ * remove deleted from page APIs
842
+ */
843
+ function removeDeletedAPIs(){
844
+
845
+ var objAPIsNew = {};
846
+
847
+ mapAPIs(function(api){
848
+
849
+ var elementID = getElementID(api);
850
+ var objElement = jQuery("#"+elementID);
851
+
852
+ if(objElement.length == 0)
853
+ return(false);
854
+
855
+ var parent = objElement.parent();
856
+
857
+ objAPIsNew[elementID] = api;
858
+
859
+ });
860
+
861
+ g_objApis = objAPIsNew;
862
+
863
+ }
864
+
865
+
866
+ /**
867
+ * on editor check
868
+ */
869
+ function onEditorCheck(){
870
+
871
+ removeDeletedAPIs();
872
+
873
+ trigger("update_debug", g_groupName);
874
+
875
+ }
876
+
877
+ /**
878
+ * get group name
879
+ */
880
+ this.getGroupName = function(){
881
+
882
+ return(g_groupName);
883
+ }
884
+
885
+ /**
886
+ * add widget to sync object
887
+ */
888
+ this.addAPI = function(objAPI){
889
+
890
+ var id = getElementID(objAPI);
891
+
892
+ if(g_objApis.hasOwnProperty(id))
893
+ return(false);
894
+
895
+ g_objApis[id] = objAPI;
896
+
897
+ if(g_vars.is_editor == true)
898
+ removeDeletedAPIs();
899
+
900
+ validate(objAPI);
901
+
902
+ //debug
903
+ var objElement = objAPI.getElement();
904
+
905
+ //add debug
906
+ trigger("update_debug", g_groupName);
907
+
908
+ //set events
909
+ objAPI.onEvent("change", function(){
910
+
911
+ onItemChange(objAPI);
912
+
913
+ });
914
+
915
+
916
+ if(g_vars.is_editor == true && g_vars.is_editor_func_started == false){
917
+
918
+ setInterval(onEditorCheck, 700);
919
+ g_vars.is_editor_func_started = false;
920
+ }
921
+
922
+
923
+ }
924
+
925
+
926
+ }
927
+
928
  /**
929
  * ---------------------------------------------------
930
  * remote carousel api class
932
  function UERemoteWidgets(){
933
 
934
  var g_objParent, g_objWidget, g_parentID;
935
+ var g_api, g_objSync;
936
  var t = this;
937
 
938
  var g_vars = {
940
  funcOnInit:null,
941
  is_editor:null,
942
  widget_id:null,
943
+ init_options:null,
944
+ is_parent_mode: false,
945
+ is_debug: false,
946
+ syncid:null,
947
+ options_api:null,
948
+ debug_connect:false,
949
+ debug_show_ids:false,
950
+ debug_show_widget: "",
951
+ trace_debug:false
952
  };
953
 
954
  var g_types = {
955
  CAROUSEL:"carousel",
956
+ GALLERY:"gallery",
957
+ GENERAL:"general"
958
  };
959
 
960
 
1018
  if(g_objParent.hasClass("owl-carousel"))
1019
  return(g_types.CAROUSEL);
1020
 
1021
+
1022
+ return(g_types.GENERAL);
1023
+
1024
+
1025
+ /* remove me
1026
+ *
1027
  var remoteType = g_objParent.data("remote-type");
1028
+
1029
  if(!remoteType)
1030
  return(null);
1031
 
1044
  }
1045
 
1046
  return(null);
1047
+ */
1048
+
1049
  }
1050
 
1051
  /**
1070
 
1071
  var elementOffset = objElement.offset();
1072
 
1073
+ if(g_vars.trace_debug){
1074
+ trace("Widget Offset: ");
1075
+ trace(elementOffset);
1076
+ }
1077
+
1078
  jQuery.each(objParents, function(index, parent){
1079
 
1080
  var objParent = jQuery(parent);
1081
  var parentOffset = objParent.offset();
1082
 
1083
+ if(parentOffset.top == 0){
1084
+
1085
+ var firstParent = getWidgetContainer(objParent);
1086
+ var parentOffset = firstParent.offset();
1087
+
1088
+ }
1089
+
1090
  var distance = getOffsetsDistance(parentOffset, elementOffset);
1091
 
1092
+ if(g_vars.trace_debug){
1093
+ trace("Parent offset: ");
1094
+ trace(objParent);
1095
+ trace(parentOffset);
1096
+ trace("distance: " + distance);
1097
+ }
1098
+
1099
  if(distance < minDiff){
1100
  minDiff = distance;
1101
  objClosest = objParent;
1110
  /**
1111
  * detect closest parent
1112
  */
1113
+ function detectClosestParent(objParents){
1114
 
1115
+ if(!objParents)
1116
+ var objParents = jQuery(".uc-remote-parent").not(g_objWidget);
1117
+
1118
+ if(g_vars.trace_debug){
1119
+ trace("detect closest start. group:");
1120
+ trace(objParents);
1121
+ }
1122
 
1123
  var numParents = objParents.length;
1124
+
1125
  if(numParents == 0)
1126
  return(null);
1127
 
1130
 
1131
  //filter by auto
1132
 
1133
+ if(g_vars.trace_debug)
1134
+ trace("filter auto");
1135
+
1136
  var objParentsFiltered = objParents.filter("[data-remoteid='"+g_parentID+"']");
1137
 
1138
+ if(objParentsFiltered.length == 1)
1139
  return(objParentsFiltered);
1140
 
1141
  //find by offset
1142
+
1143
+ if(g_vars.trace_debug){
1144
+ trace("filter offset");
1145
+ }
1146
+
1147
+ var objClosest = getClosestByOffset(objParents, g_objWidget);
1148
 
1149
  if(objClosest)
1150
  return(objClosest);
1151
+
1152
+ if(g_vars.trace_debug)
1153
+ trace("get first");
1154
 
1155
  var firstParent = jQuery(objParentsFiltered[0]);
1156
 
1162
  * set parent object
1163
  */
1164
  function setParentObject(){
1165
+
1166
  var objForceParent = getVal(g_vars.init_options, "force_parent_obj");
1167
 
1168
+ var widgetID = g_objWidget.attr("id");
1169
+
1170
+ if(g_vars.trace_debug)
1171
+ trace("start set parent for: "+widgetID);
1172
+
1173
  if(objForceParent){
1174
+
1175
  g_objParent = objForceParent;
1176
+
1177
+ if(g_vars.trace_debug){
1178
+ trace("set force parent");
1179
+ trace(g_objParent);
1180
+ }
1181
+
1182
  return(false);
1183
  }
1184
 
1185
  if(!g_parentID)
1186
  throw new Error("Parent controller ID not found");
1187
+
1188
  if(!g_objParent || g_objParent.length == 0){
1189
 
1190
  if(g_parentID == "auto"){
1191
+
1192
  g_objParent = detectClosestParent();
1193
 
1194
+ if(g_vars.trace_debug){
1195
+ trace("detect closest");
1196
+ trace(g_objParent);
1197
+ }
1198
+
1199
  if(!g_objParent)
1200
  throw new Error("Can't detect remote parent");
1201
+
1202
  }
1203
  else{
 
1204
 
1205
+ var objParents = jQuery(".uc-remote-parent[data-remoteid='"+g_parentID+"']").not(g_objWidget);
1206
+
1207
+ if(g_vars.trace_debug)
1208
+ trace("Detect from group: "+g_parentID);
1209
+
1210
+ g_objParent = detectClosestParent(objParents);
1211
+
1212
+ if(g_vars.trace_debug){
1213
+ trace("detected from group");
1214
+ trace(g_objParent);
1215
+ }
1216
+
1217
  if(g_objParent.length == 0)
1218
  throw new Error("Parent widget with remote name:'"+g_parentID+"' not found");
1219
  }
1220
 
1221
  }
1222
 
1223
+ if(g_objParent && g_objParent.length > 1){
1224
+ g_objParent = jQuery(g_objParent[0]);
1225
+ }
1226
+
1227
+ if(g_vars.debug_connect == true){
1228
+
1229
+ var parentID = g_objParent.attr("id");
1230
+ var widgetID = g_objWidget.attr("id");
1231
+
1232
+ trace("widget: "+widgetID+" connected to: "+parentID);
1233
+
1234
+ }
1235
+
1236
+ if(!g_objParent || g_objParent.length == 0)
1237
+ throw new Error("Remote parent not found");
1238
+
1239
  }
1240
 
1241
+
1242
  /**
1243
+ * init api variable
1244
+ */
1245
+ function initAPI(){
 
 
1246
 
1247
  //set type and related objects
1248
  if(!g_api){
1254
  throw new Error("No parent type found");
1255
  }
1256
 
1257
+
1258
  //init the api
1259
  switch(parentType){
1260
  case g_types.CAROUSEL:
1261
  g_api = new UERemoteCarouselAPI();
1262
  break;
1263
+ case g_types.GENERAL:
1264
+
1265
+ g_api = new UERemoteGeneralAPI();
1266
+
1267
+ break;
1268
  case g_types.TABS:
1269
 
1270
+ //g_api = new UERemoteTabsAPI();
1271
+ g_api = new UERemoteGeneralAPI();
1272
 
1273
  break;
1274
  case g_types.GALLERY:
1281
  break;
1282
  }
1283
 
1284
+ }
1285
+
1286
+ var optionsFromData = g_objParent.data("uc-remote-options");
1287
+
1288
+ if(optionsFromData)
1289
+ g_vars.options_api = optionsFromData;
1290
+
1291
+ var isInited = g_api.init(g_objParent, g_vars.options_api);
1292
+
1293
+ return(isInited);
1294
+ }
1295
+
1296
+
1297
+ /**
1298
+ * init parent
1299
+ */
1300
+ function initParent(){
1301
 
1302
+ setParentObject();
1303
 
1304
+ var isInited = initAPI();
1305
+
1306
  return(isInited);
1307
  }
1308
 
1317
 
1318
  g_vars.is_inited = initParent();
1319
 
1320
+ if(g_vars.is_inited == false){
1321
+
1322
  g_objParent.on("uc-object-ready", func);
1323
+
1324
+ }
1325
  }
1326
 
1327
 
1334
  if(g_vars.is_inited == false)
1335
  throw new Error("Widget not inited");
1336
 
1337
+ if(typeof objElement == "string"){
1338
+ var selector = objElement;
1339
  objElement = g_objWidget.find(objElement);
1340
+ if(objElement.length == 0)
1341
+ throw new Error("Remote '"+action+"' action error: element: "+selector+" not found");
1342
+ }
1343
 
1344
  if(!objElement || objElement.length == 0)
1345
  throw new Error("Element not inited");
1349
 
1350
  //avoid double action
1351
  var linkedAction = objElement.data("uc-action");
1352
+
1353
  if(linkedAction)
1354
+ return(false);
1355
 
1356
  objElement.data("uc-action", action);
1357
 
1358
  objElement.on("click",function(){
1359
 
1360
+ t.doAction(action);
1361
 
1362
  });
1363
 
1368
  * run this function after the widget is ready to use
1369
  */
1370
  function onWidgetReady(){
1371
+
1372
  checkWidgetDebug();
1373
 
1374
  var isEditorMode = isInsideEditor();
1386
  }
1387
 
1388
 
1389
+ function _______TEXT_ON_WIDGET_________(){}
1390
 
1391
 
1392
  /**
1397
  if(!g_objWidget || g_objWidget.length == 0)
1398
  return(false);
1399
 
1400
+ var objParent = getWidgetContainer(g_objWidget);
1401
 
1402
+ //don't hide if no message
1403
+
1404
+ var objError = objParent.find('.uc-remote-error');
1405
 
1406
+ if(objError.length == 0)
1407
  return(false);
1408
 
1409
+ if(objError.is(":visible") == false)
1410
+ return(false);
1411
 
1412
  objError.hide();
1413
 
1415
  "border" : "none"
1416
  });
1417
 
1418
+ //try to set the debug if avaliable
1419
+ checkWidgetDebug();
1420
+
1421
  }
1422
 
1423
+ /**
1424
+ * get widget container
1425
+ */
1426
+ function getWidgetContainer(objWidget){
1427
+
1428
+ var objParent = objWidget.parents(".elementor-widget-container");
1429
+ if(objParent.length == 0)
1430
+ objParent = objWidget.parent();
1431
+
1432
+ return(objParent);
1433
+ }
1434
 
1435
 
1436
  /**
1437
  * add error message div on the widget div
1438
  *
1439
  */
1440
+ function addTextDiv(objWidget, type){
1441
 
1442
+ var objParent = getWidgetContainer(objWidget);
 
1443
 
1444
+ var isDebug = (type == "debug");
1445
 
1446
+ var className = "uc-remote-error";
1447
+ if(isDebug == true)
1448
+ className = "uc-remote-debug";
1449
+
1450
+ var divText = "<div class='"+className+"'></div>";
1451
+ objParent.append(divText);
1452
+
1453
+ var objError = objParent.find('.'+className+'');
1454
+
1455
+ var css = {
1456
+ "position":"absolute",
1457
+ "color":"red",
1458
+ "top":"-30px",
1459
+ "left":"0px",
1460
+ "z-index":"999999",
1461
+ "background-color":"#ffffff"
1462
+ };
1463
+
1464
+ if(isDebug == true){
1465
+ css["color"] = "green";
1466
+ css["z-index"] = "999998";
1467
+ }
1468
+
1469
+ objError.css(css);
1470
 
1471
+ var objError = objParent.find('.'+className+'');
1472
 
1473
  return(objError);
1474
  }
1476
  /**
1477
  * display some error on widget interface
1478
  */
1479
+ function displayTextOnWidget(objWidget, message, type){
1480
+
1481
+ var isDebug = (type == "debug");
1482
+
1483
+ var className = "uc-remote-error";
1484
+ if(isDebug == true)
1485
+ className = "uc-remote-debug";
1486
+
1487
+ var objParent = getWidgetContainer(objWidget);
1488
+
1489
+ objText = objParent.find("."+className);
1490
 
 
 
1491
  //add error div if missing. pause error in editor
1492
  //second time the div will be not empty and it will show the message
1493
+ if(objText.length == 0){
1494
+
1495
+ objText = addTextDiv(objWidget, type);
1496
 
1497
+ if(isDebug == false){
1498
+
1499
+ var isInEditor = isInsideEditor();
1500
 
1501
+ if(isInEditor == true){
1502
+
1503
+ setTimeout(function(){
1504
+ displayTextOnWidget(objWidget, message, type);
1505
+ },2000);
1506
+
1507
+ return(false);
1508
+ }
1509
 
 
1510
  }
1511
 
1512
  }
1513
 
1514
+ //add the error border
1515
+ if(isDebug == false){
1516
+
1517
+ objWidget.css({
1518
+ "border" : "2px solid red",
1519
+ "position" : "relative"
1520
+ });
1521
+
1522
+ }
 
1523
 
1524
+ objText.show();
1525
+ objText.html(message);
1526
 
1527
  }
1528
 
1532
  */
1533
  function displayErrorMessage(message){
1534
 
1535
+ if(g_vars.is_parent_mode == false){
1536
+
1537
+ if(g_objWidget && g_objWidget.length)
1538
+ displayTextOnWidget(g_objWidget, message,"error");
1539
+
1540
+ }else{
1541
+
1542
+ displayTextOnWidget(g_objParent, message, "error");
1543
+
1544
+ }
1545
+
1546
+ //console.log("UE Remote Error: "+message);
1547
+ //console.log(message);
1548
 
1549
  }
1550
 
1554
  /**
1555
  * return if the debug is active
1556
  */
1557
+ function isDebugActive(objWidget){
1558
 
1559
+ if(!objWidget)
1560
+ objWidget = g_objWidget;
1561
+
1562
+ var isActive = objWidget.data("debug_active");
1563
 
1564
  if(isActive === true)
1565
  return(true);
1571
  /**
1572
  * remove debug visual from the widget
1573
  */
1574
+ function removeDebugVisual(objWidget){
1575
+
1576
+ if(!objWidget)
1577
+ objWidget = g_objWidget;
1578
 
1579
  g_objWidget.data("debug_active", false);
1580
 
1581
+ g_objWidget.css({
1582
+ "border-style":"none"
1583
+ });
1584
+
1585
  }
1586
 
1587
+
1588
  /**
1589
  * set debug visual
1590
  */
1591
+ function setDebugVisual(color, objWidget){
1592
+
1593
+ if(!objWidget)
1594
+ objWidget = g_objWidget;
1595
+
1596
+ objWidget.data("debug_active", true);
1597
+
1598
+ objWidget.css({
1599
+ "border-style":"solid",
1600
+ "border-width":"3px",
1601
+ "border-color":color
1602
+ });
1603
 
1604
+ }
1605
+
1606
+ /**
1607
+ * check if parent debug is active
1608
+ */
1609
+ function isParentDebugActive(objParent){
1610
 
1611
+ var dataDebug = objParent.data("debug");
1612
+ var isDebug = (dataDebug === true);
1613
 
1614
+ return(isDebug);
1615
  }
1616
 
1617
+
1618
  /**
1619
+ * check widget debug work
1620
  */
1621
+ function checkWidgetDebugWork(objWidget, objParent){
1622
 
1623
+ if(!objWidget)
1624
+ objWidget = g_objWidget;
1625
 
1626
+ if(!objParent)
1627
+ objParent = g_objParent;
1628
+
1629
+ var isDebug = isParentDebugActive(objParent);
 
 
 
1630
 
1631
+ var isActive = isDebugActive(objWidget);
1632
 
1633
+ /*
1634
+ trace("check! "+isActive+" "+isDebug);
1635
+ trace(objParent);
1636
+ trace(objWidget);
1637
+ */
1638
 
1639
  //remove debug if active but no need
1640
 
1641
  if(isDebug == false){
1642
 
1643
  if(isActive == true)
1644
+ removeDebugVisual(objWidget);
1645
 
1646
  return(false);
1647
  }
1651
  if(isActive == false){
1652
 
1653
  //get parent color
1654
+ var color = addParentDebug(objParent);
1655
+ setDebugVisual(color, objWidget);
 
1656
 
1657
  }
1658
 
1659
 
1660
  }
1661
 
1662
+ /**
1663
+ * check widget debug
1664
+ */
1665
+ function checkWidgetDebug(){
1666
+
1667
+ var noDebugCheck = getVal(g_vars.init_options, "no_debug_check");
1668
+
1669
+ if(noDebugCheck === true)
1670
+ return(false);
1671
+
1672
+ //get debug color
1673
+ if(!g_objParent || g_vars.is_inited == false){
1674
+ removeDebugVisual();
1675
+ return(false);
1676
+ }
1677
+
1678
+ checkWidgetDebugWork();
1679
+
1680
+ }
1681
+
1682
+ /**
1683
+ * on api event
1684
+ */
1685
  this.onEvent = function(name, func){
1686
+ g_api.onEvent(name,func);
1687
  }
1688
 
1689
+
1690
+ /**
1691
+ * change item by action
1692
+ */
1693
+ function changeItemByAction(dir){
1694
+
1695
+ var current = t.doAction("get_num_current");
1696
+ var total = t.doAction("get_total_items");
1697
+
1698
+ switch(dir){
1699
+ case "next":
1700
+
1701
+ var num = current+1;
1702
+ if(num >= total )
1703
+ num = 0;
1704
+
1705
+ break;
1706
+ case "prev":
1707
+
1708
+ var num = current-1;
1709
+ if(num < 0)
1710
+ num = total-1;
1711
+
1712
+ break;
1713
+ default:
1714
+ throw new Error("wrong direction type: "+dir);
1715
+ break;
1716
+ }
1717
+
1718
+ t.doAction("change_item", num);
1719
+
1720
+ }
1721
+
1722
+
1723
+ /**
1724
+ * do api action
1725
+ */
1726
  this.doAction = function(action, arg1, arg2){
1727
+
1728
+ switch(action){
1729
+ case "prev":
1730
+ case "next":
1731
+ changeItemByAction(action);
1732
+ return(false);
1733
+ break;
1734
+ }
1735
+
1736
+ var response = g_api.doAction(action, arg1, arg2);
1737
+
1738
+ return(response);
1739
  }
1740
 
1741
  /**
1742
  * add the parent some debug color
1743
  */
1744
+ function addParentDebug(objParent){
1745
+
1746
+ if(!objParent)
1747
+ objParent = g_objParent;
1748
 
1749
  var color = g_objParent.data("uc-debug-color");
1750
  if(color)
1770
  }
1771
 
1772
 
1773
+ /**
1774
+ * update sync debug
1775
+ */
1776
+ function updateSyncDebug(event, syncID){
1777
+
1778
+ //if show id's disable other debug
1779
+ if(g_vars.debug_show_ids == true)
1780
+ return(false);
1781
+
1782
+ try{
1783
+
1784
+ if(syncID != g_vars.syncid){
1785
+
1786
+ var name = g_objParent.data("widgetname");
1787
+ throw new Error("Wrong sync group mishmash "+g_vars.syncid+" and " + syncID);
1788
+ }
1789
+
1790
+ var debugText = g_objSync.getDebugText(g_objParent);
1791
+
1792
+ if(!debugText)
1793
+ return(false);
1794
+
1795
+ displayTextOnWidget(g_objParent, debugText, "debug");
1796
+
1797
+ }catch(error){
1798
+
1799
+ displayErrorMessage(error);
1800
+
1801
+ }
1802
+
1803
+ }
1804
+
1805
+
1806
  function _______EDITOR_RELATED_________(){}
1807
 
1808
 
1840
 
1841
  g_objParent = null;
1842
  g_api = null;
1843
+ g_vars.is_inited = false;
1844
+
1845
  }
1846
 
1847
 
1849
  * check widget inside editor
1850
  */
1851
  function checkWidgetInsideEditor(){
1852
+
1853
  //check for disconnect
1854
  try{
1855
 
1861
 
1862
  //disconnect
1863
  resetSettingsInsideEditor();
1864
+ trace("reset all");
1865
  }
1866
 
1867
  }else{
1869
  //check for connect
1870
  g_vars.is_inited = initParent();
1871
 
1872
+ if(g_vars.is_inited == true){
1873
+
1874
+ g_vars.funcOnInit();
1875
+ }
1876
+ else
1877
+ if(g_vars.is_inited == false){
1878
+
1879
+ g_objParent.on("uc-object-ready", function(){
1880
+
1881
+ g_vars.is_inited = true;
1882
+ g_vars.funcOnInit();
1883
+
1884
+ });
1885
+ }
1886
+
1887
  }
1888
 
1889
  checkWidgetDebug();
1904
  * on widget init
1905
  */
1906
  this.onWidgetInit = function(widgetID, func, options){
1907
+
1908
  try{
1909
+
1910
  if(!g_vars.funcOnInit){
1911
 
1912
  if(typeof func != "function")
1914
 
1915
  g_vars.funcOnInit = func;
1916
  }
1917
+
1918
+ if(options && g_vars.init_options == null)
1919
+ g_vars.init_options = options;
1920
 
1921
+ if(g_vars.debug_show_widget && g_vars.debug_show_widget == widgetID)
1922
+ g_vars.trace_debug = true;
1923
 
1924
  initGlobal(widgetID, t.onWidgetInit);
1925
+
1926
  if(g_vars.is_inited == false)
1927
  return(false);
1928
 
1929
+ //show id's on the widgets
1930
+ if(g_vars.debug_show_ids == true){
1931
+
1932
+ trace("start debug show id's");
1933
+
1934
+ displayTextOnWidget(g_objWidget, g_objWidget.attr("id"), "debug");
1935
+ }
1936
 
1937
+ if(g_vars.debug_connect == true)
1938
+ trace("start debug - show connect");
1939
+
1940
+ if(g_objParent.length > 1){
1941
+
1942
+ trace(g_objWidget);
1943
+ trace(g_objParent);
1944
+
1945
+ throw new Error("Remote widget can't connect to more then 1 parents");
1946
+ }
1947
+
1948
+ //widget is inited
1949
+
1950
  onWidgetReady();
1951
 
1952
  g_vars.funcOnInit(g_objWidget);
1968
  }
1969
 
1970
  /**
1971
+ * get the sync object, if not exists, create one
1972
  */
1973
+ function getSyncObject(syncID){
1974
 
1975
+ var syncRealID = "uc_sync_"+syncID;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1976
 
1977
+ var objSync = getVal(window, syncRealID);
1978
 
1979
+ if(objSync)
1980
+ return(objSync);
1981
 
1982
+ var objSync = new UESyncObject();
 
 
 
 
 
 
 
1983
 
1984
+ window[syncRealID] = objSync;
1985
 
1986
+ return(objSync);
1987
  }
1988
+
1989
 
1990
  /**
1991
+ * start sync
1992
  */
1993
  function startParentSync(){
1994
 
1995
+ var syncID = g_objParent.data("syncid");
1996
 
1997
+ if(!syncID)
 
 
1998
  return(false);
1999
 
2000
+ var objSync = getSyncObject(syncID);
 
2001
 
2002
+ var isEditorMode = isInsideEditor();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2003
 
2004
+ objSync.setOptions(syncID, isEditorMode);
2005
+
2006
+ var isInited = initAPI();
2007
+
2008
+ if(isInited == false)
2009
+ throw new Error("Sync Error - can't init api");
2010
+
2011
+ g_vars.syncid = syncID;
2012
 
2013
+ //add debug event listener
2014
+ if(g_vars.is_debug === true)
2015
+ objSync.on("update_debug", updateSyncDebug);
2016
+
2017
+ g_objSync = objSync;
2018
+
2019
+ objSync.addAPI(g_api);
2020
+
2021
+ //if(isEditorMode == true)
2022
+ //setInterval(checkSyncInsideEditor, 700);
2023
 
2024
  }
2025
 
2027
  /**
2028
  * parent init, init the debug
2029
  */
2030
+ this.onParentInit = function(objParent, optionsAPI){
 
 
 
 
 
2031
 
2032
+ try{
2033
+
2034
+ g_objParent = objParent;
2035
+
2036
+ if(!g_objParent)
2037
+ return(false);
2038
+
2039
+ if(g_objParent.length == 0)
2040
+ return(false);
2041
+
2042
+ g_vars.is_parent_mode = true;
2043
+
2044
+ var optionsFromData = g_objParent.data("uc-remote-options");
2045
+
2046
+ if(optionsFromData)
2047
+ optionsAPI = optionsFromData;
2048
+
2049
+ if(optionsAPI)
2050
+ g_vars.options_api = optionsAPI;
2051
+
2052
+ var isDebug = g_objParent.data("debug");
2053
+
2054
+ g_vars.is_debug = isDebug;
2055
+
2056
+ if(isDebug === true)
2057
+ addParentDebug(objParent);
2058
+
2059
+ var isSync = objParent.data("sync");
2060
+
2061
+ if(isSync == true)
2062
+ startParentSync();
2063
+
2064
+ if(g_vars.debug_show_ids == true){
2065
+ displayTextOnWidget(g_objParent, g_objParent.attr("id"), "debug");
2066
+ }
2067
+
2068
+ }catch(message){
2069
+
2070
+ displayErrorMessage(message);
2071
+
2072
  return(false);
2073
+
2074
+ }
 
 
 
 
 
 
 
 
2075
 
2076
  }
2077
 
2089
 
2090
  }
2091
 
2092
+
2093
  /**
2094
  * get the connected parent
2095
  */
2100
 
2101
  }
2102
 
2103
+ jQuery("body").on("uc-remote-parent-init",function(event, objParent, optionsAPI){
2104
 
2105
  var objRemote = new UERemoteWidgets();
2106
 
2107
+ objRemote.onParentInit(objParent, optionsAPI);
2108
 
2109
  });
2110
 
css/unitecreator_styles.css CHANGED
@@ -909,7 +909,7 @@
909
 
910
  .uc-dialog-param-error {
911
  position: absolute;
912
- top: 396px;
913
  left: 29px;
914
  width: 360px;
915
  }
@@ -961,6 +961,10 @@
961
  text-decoration:underline;
962
  }
963
 
 
 
 
 
964
  .uc-dialog-label-inline {
965
  display: inline-block !important;
966
  vertical-align: top;
@@ -1164,6 +1168,11 @@
1164
  display:block;
1165
  }
1166
 
 
 
 
 
 
1167
  .----------------ASSETS_TAB------------- {}
1168
  .uc-assets-folder-wrapper {
1169
  padding: 20px;
909
 
910
  .uc-dialog-param-error {
911
  position: absolute;
912
+ top: 430px;
913
  left: 29px;
914
  width: 360px;
915
  }
961
  text-decoration:underline;
962
  }
963
 
964
+ .uc-dialog-condition-attribute{
965
+ max-width:120px !important;
966
+ }
967
+
968
  .uc-dialog-label-inline {
969
  display: inline-block !important;
970
  vertical-align: top;
1168
  display:block;
1169
  }
1170
 
1171
+ .uc-dialog-include-settings__values{
1172
+ max-height:82px !important;
1173
+ }
1174
+
1175
+
1176
  .----------------ASSETS_TAB------------- {}
1177
  .uc-assets-folder-wrapper {
1178
  padding: 20px;
images/banner-black-friday-2021.jpg ADDED
Binary file
inc_php/framework/zip.class.php CHANGED
@@ -234,13 +234,13 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
234
 
235
  switch ($result) {
236
  case ZipArchive::ER_NOZIP:
237
- UniteFunctionsCDCP::throwError('not a zip archive');
238
  case ZipArchive::ER_INCONS :
239
- UniteFunctionsCDCP::throwError('consistency check failed');
240
  case ZipArchive::ER_CRC :
241
- UniteFunctionsCDCP::throwError('checksum failed');
242
  default:
243
- UniteFunctionsCDCP::throwError('error ' . $result);
244
  }
245
 
246
  return(false);
@@ -659,7 +659,7 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
659
  $success = $this->extract_zipArchive($src, $dest);
660
 
661
  if($success == false){
662
- UniteFunctionsCDCP::throwError("Can't extract zip");
663
  }
664
 
665
  }
234
 
235
  switch ($result) {
236
  case ZipArchive::ER_NOZIP:
237
+ UniteFunctionsUC::throwError('not a zip archive');
238
  case ZipArchive::ER_INCONS :
239
+ UniteFunctionsUC::throwError('consistency check failed');
240
  case ZipArchive::ER_CRC :
241
+ UniteFunctionsUC::throwError('checksum failed');
242
  default:
243
+ UniteFunctionsUC::throwError('error ' . $result);
244
  }
245
 
246
  return(false);
659
  $success = $this->extract_zipArchive($src, $dest);
660
 
661
  if($success == false){
662
+ UniteFunctionsUC::throwError("Can't extract zip");
663
  }
664
 
665
  }
inc_php/layouts/unitecreator_layouts.class.php CHANGED
@@ -576,31 +576,6 @@ class UniteCreatorLayoutsWork extends UniteElementsBaseUC{
576
 
577
  }
578
 
579
- /**
580
- * duplicate layout from data
581
- */
582
- public function duplicateLayoutFromData($data){
583
-
584
-
585
- $redirectToLayout = UniteFunctionsUC::getVal($data, "redirect_to_layout");
586
- $redirectToLayout = UniteFunctionsUC::strToBool($redirectToLayout);
587
-
588
- $objLayout = $this->getLayoutFromData($data);
589
-
590
- $duplicatedID = $objLayout->duplicate();
591
- $this->lastDuplicatedID = $duplicatedID;
592
-
593
- if($redirectToLayout == true){
594
-
595
- $urlRedirect = HelperUC::getViewUrl_Layout($duplicatedID);
596
- return($urlRedirect);
597
- }
598
-
599
- return(null);
600
- }
601
-
602
-
603
-
604
 
605
  /**
606
  * get layout name, and find name that don't exists in database using counter *
576
 
577
  }
578
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
579
 
580
  /**
581
  * get layout name, and find name that don't exists in database using counter *
inc_php/manager/unitecreator_manager.class.php CHANGED
@@ -167,16 +167,22 @@ class UniteCreatorManager{
167
  * get category list
168
  */
169
  protected function getCatList(){
170
- dmp("getCatList - function for override!!!");exit();
 
 
 
 
171
  }
172
 
173
 
174
  /**
175
  * put categories html
176
  */
177
- private function putHtmlCats(){
 
 
 
178
 
179
- $htmlCatList = $this->getCatList();
180
  $showAllButtons = false;
181
 
182
  ?>
@@ -754,9 +760,12 @@ class UniteCreatorManager{
754
  $this->managerAddHtml .= " ".$optionOptions;
755
  }
756
 
757
-
758
- try{
759
 
 
 
 
 
 
760
  ?>
761
 
762
  <div id="uc_managerw" class="uc-manager-outer <?php echo esc_attr($managerClass)?>" data-managername="<?php echo esc_attr($this->managerName)?>" data-type="<?php echo esc_attr($this->type)?>" <?php echo UniteProviderFunctionsUC::escAddParam($htmlPassData)?> <?php echo UniteProviderFunctionsUC::escAddParam($this->managerAddHtml)?>>
@@ -773,7 +782,7 @@ class UniteCreatorManager{
773
 
774
  <tr>
775
  <td class="cell_cats" width="220px" valign="top">
776
- <?php $this->putHtmlCats()?>
777
  </td>
778
 
779
  <td class="cell_items" valign="top">
167
  * get category list
168
  */
169
  protected function getCatList(){
170
+
171
+ dmp("getCatList - function for override!!!");
172
+ UniteFunctionsUC::showTrace();
173
+
174
+ exit();
175
  }
176
 
177
 
178
  /**
179
  * put categories html
180
  */
181
+ private function putHtmlCats($htmlCatList = null){
182
+
183
+ if(empty($htmlCatList))
184
+ $htmlCatList = $this->getCatList();
185
 
 
186
  $showAllButtons = false;
187
 
188
  ?>
760
  $this->managerAddHtml .= " ".$optionOptions;
761
  }
762
 
 
 
763
 
764
+ try{
765
+ $htmlCatList = $this->getCatList();
766
+
767
+ HelperHtmlUC::putHtmlAdminNotices();
768
+
769
  ?>
770
 
771
  <div id="uc_managerw" class="uc-manager-outer <?php echo esc_attr($managerClass)?>" data-managername="<?php echo esc_attr($this->managerName)?>" data-type="<?php echo esc_attr($this->type)?>" <?php echo UniteProviderFunctionsUC::escAddParam($htmlPassData)?> <?php echo UniteProviderFunctionsUC::escAddParam($this->managerAddHtml)?>>
782
 
783
  <tr>
784
  <td class="cell_cats" width="220px" valign="top">
785
+ <?php $this->putHtmlCats($htmlCatList)?>
786
  </td>
787
 
788
  <td class="cell_items" valign="top">
inc_php/manager/unitecreator_manager_addons.class.php CHANGED
@@ -1657,14 +1657,15 @@ class UniteCreatorManagerAddonsWork extends UniteCreatorManager{
1657
  * get categories with catalog
1658
  */
1659
  private function getCatsWithCatalog($filterCatalog, $params = array()){
1660
-
1661
  $objAddons = new UniteCreatorAddons();
1662
  $webAPI = $this->getWebAPI();
1663
-
1664
  $arrCats = $objAddons->getAddonsWidthCategories(true, true, $this->filterAddonType, $params);
1665
 
1666
- $arrCats = $this->modifyLocalCats($arrCats);
1667
-
 
1668
  if($this->objAddonType->allowManagerWebCatalog == true)
1669
  $arrCats = $webAPI->mergeCatsAndAddonsWithCatalog($arrCats, true, $this->objAddonType, $params);
1670
 
@@ -1802,10 +1803,17 @@ class UniteCreatorManagerAddonsWork extends UniteCreatorManager{
1802
 
1803
  if($arrCats === null)
1804
  $arrCats = $this->getArrCats($params);
 
 
 
 
 
 
 
 
1805
 
1806
  $htmlCatList = $this->objCats->getHtmlCatList($selectCatID, $this->objAddonType, $arrCats);
1807
 
1808
-
1809
  return($htmlCatList);
1810
  }
1811
 
1657
  * get categories with catalog
1658
  */
1659
  private function getCatsWithCatalog($filterCatalog, $params = array()){
1660
+
1661
  $objAddons = new UniteCreatorAddons();
1662
  $webAPI = $this->getWebAPI();
1663
+
1664
  $arrCats = $objAddons->getAddonsWidthCategories(true, true, $this->filterAddonType, $params);
1665
 
1666
+ if(empty($params))
1667
+ $arrCats = $this->modifyLocalCats($arrCats);
1668
+
1669
  if($this->objAddonType->allowManagerWebCatalog == true)
1670
  $arrCats = $webAPI->mergeCatsAndAddonsWithCatalog($arrCats, true, $this->objAddonType, $params);
1671
 
1803
 
1804
  if($arrCats === null)
1805
  $arrCats = $this->getArrCats($params);
1806
+
1807
+ //check for error
1808
+ if(empty($arrCats)){
1809
+
1810
+ $urlApiConnectivity = HelperUC::getViewUrl("troubleshooting-connectivity");
1811
+
1812
+ HelperUC::addAdminNotice("No widgets fetched from the API. Please check <a href='$urlApiConnectivity'>api connectivity</a> from general settings - troubleshooting");
1813
+ }
1814
 
1815
  $htmlCatList = $this->objCats->getHtmlCatList($selectCatID, $this->objAddonType, $arrCats);
1816
 
 
1817
  return($htmlCatList);
1818
  }
1819
 
inc_php/manager/unitecreator_manager_inline.class.php CHANGED
@@ -80,6 +80,16 @@ class UniteCreatorManagerInline extends UniteCreatorManager{
80
 
81
  }
82
 
 
 
 
 
 
 
 
 
 
 
83
 
84
  /**
85
  * get single item menu
80
 
81
  }
82
 
83
+ /**
84
+ * get category list
85
+ */
86
+ protected function getCatList($selectCatID = null, $arrCats = null, $params = array()){
87
+
88
+ $htmlCatList = "";
89
+
90
+ return($htmlCatList);
91
+ }
92
+
93
 
94
  /**
95
  * get single item menu
inc_php/unitecreator_actions.class.php CHANGED
@@ -37,6 +37,7 @@ class UniteCreatorActions{
37
 
38
  }
39
 
 
40
  /**
41
  * get data array from request
42
  */
@@ -345,15 +346,6 @@ class UniteCreatorActions{
345
 
346
  HelperUC::ajaxResponseSuccessRedirect(HelperUC::getText("layout_deleted"), $urlLayouts);
347
 
348
- break;
349
- case "duplicate_layout":
350
-
351
- $urlRedirect = $layouts->duplicateLayoutFromData($data);
352
- if(empty($urlRedirect))
353
- $urlRedirect = HelperUC::getViewUrl_LayoutsList();
354
-
355
- HelperUC::ajaxResponseSuccessRedirect(HelperUC::getText("layout_duplicated"), $urlRedirect);
356
-
357
  break;
358
  case "export_layout":
359
 
37
 
38
  }
39
 
40
+
41
  /**
42
  * get data array from request
43
  */
346
 
347
  HelperUC::ajaxResponseSuccessRedirect(HelperUC::getText("layout_deleted"), $urlLayouts);
348
 
 
 
 
 
 
 
 
 
 
349
  break;
350
  case "export_layout":
351
 
inc_php/unitecreator_addon.class.php CHANGED
@@ -1034,6 +1034,29 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
1034
 
1035
  return($this->params);
1036
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1037
 
1038
 
1039
  /**
@@ -1675,6 +1698,14 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
1675
 
1676
  foreach($this->includesJSLib as $libName){
1677
 
 
 
 
 
 
 
 
 
1678
  //process provider library instead of get files
1679
  if($processProvider == true){
1680
  $isProcessed = $objLibrary->processProviderLibrary($libName);
1034
 
1035
  return($this->params);
1036
  }
1037
+
1038
+
1039
+ /**
1040
+ * get array of default values assoc
1041
+ */
1042
+ public function getParamsDefaultValuesAssoc(){
1043
+
1044
+ $arrDefaults = array();
1045
+
1046
+ foreach($this->params as $param){
1047
+
1048
+ if(array_key_exists("default_value", $param) == false)
1049
+ continue;
1050
+
1051
+ $name = UniteFunctionsUC::getVal($param, "name");
1052
+ $defaultValue = UniteFunctionsUC::getVal($param, "default_value");
1053
+
1054
+ $arrDefaults[$name] = $defaultValue;
1055
+
1056
+ }
1057
+
1058
+ return($arrDefaults);
1059
+ }
1060
 
1061
 
1062
  /**
1698
 
1699
  foreach($this->includesJSLib as $libName){
1700
 
1701
+ //maybe disable font awesome, if set in general setting
1702
+
1703
+ if($libName == "font-awsome"){
1704
+ $optionDisable = HelperProviderCoreUC_EL::getGeneralSetting("force_disable_font_awesome");
1705
+ if($optionDisable == "disable")
1706
+ continue;
1707
+ }
1708
+
1709
  //process provider library instead of get files
1710
  if($processProvider == true){
1711
  $isProcessed = $objLibrary->processProviderLibrary($libName);
inc_php/unitecreator_dialog_param.class.php CHANGED
@@ -808,10 +808,10 @@ class UniteCreatorDialogParamWork{
808
 
809
  $htmlSelect = HelperHtmlUC::getHTMLSelect($arrItems,"template","name='use_for' class='unite-inputs-select uc-control' data-controlled-selector='.uc-listing-param-options'", true);
810
 
811
-
812
  $arrRemoteItems = array(
813
  "parent"=>__("Remote Parent","unlimited-elements-for-elementor"),
814
- "controller"=>__("Remote Controller","unlimited-elements-for-elementor")
 
815
  );
816
 
817
  $htmlSelectRemote = HelperHtmlUC::getHTMLSelect($arrRemoteItems,"parent","name='remote_type' class='unite-inputs-select'", true);
@@ -848,11 +848,13 @@ class UniteCreatorDialogParamWork{
848
 
849
  <div class="uc-listing-param-options" data-control="remote">
850
 
851
- <?php
852
 
853
  _e("Widget Type","unlimited-elements-for-elementor");?>:
854
 
855
  <?php echo $htmlSelectRemote; ?>
 
 
856
  </div>
857
 
858
  <?php
@@ -907,14 +909,6 @@ class UniteCreatorDialogParamWork{
907
  $this->putCheckbox("show_image_sizes", __("Show Image Sizes Select", "unlimited-elements-for-elementor"));
908
  ?>
909
 
910
- <?php if(GlobalsUC::$inDev == true):?>
911
- <div class="vert_sap10"></div>
912
-
913
- <?php
914
- $this->putCheckbox("is_filterable", __("Enable Filterable Options", "unlimited-elements-for-elementor"));
915
- ?>
916
- <?php endif?>
917
-
918
  <div class="vert_sap10"></div>
919
 
920
  <?php
808
 
809
  $htmlSelect = HelperHtmlUC::getHTMLSelect($arrItems,"template","name='use_for' class='unite-inputs-select uc-control' data-controlled-selector='.uc-listing-param-options'", true);
810
 
 
811
  $arrRemoteItems = array(
812
  "parent"=>__("Remote Parent","unlimited-elements-for-elementor"),
813
+ "controller"=>__("Remote Controller","unlimited-elements-for-elementor"),
814
+ "background"=>__("Remote Background","unlimited-elements-for-elementor")
815
  );
816
 
817
  $htmlSelectRemote = HelperHtmlUC::getHTMLSelect($arrRemoteItems,"parent","name='remote_type' class='unite-inputs-select'", true);
848
 
849
  <div class="uc-listing-param-options" data-control="remote">
850
 
851
+ <?php
852
 
853
  _e("Widget Type","unlimited-elements-for-elementor");?>:
854
 
855
  <?php echo $htmlSelectRemote; ?>
856
+
857
+
858
  </div>
859
 
860
  <?php
909
  $this->putCheckbox("show_image_sizes", __("Show Image Sizes Select", "unlimited-elements-for-elementor"));
910
  ?>
911
 
 
 
 
 
 
 
 
 
912
  <div class="vert_sap10"></div>
913
 
914
  <?php
inc_php/unitecreator_filters_process.class.php CHANGED
@@ -772,7 +772,7 @@ class UniteCreatorFiltersProcess{
772
  $strData = UniteFunctionsUC::jsonEncodeForClientSide($arrData);
773
 
774
  $script = "//Unlimited Elements Filters \n";
775
- $script .= "var g_strFiltersData = $strData";
776
 
777
  UniteProviderFunctionsUC::printCustomScript($script);
778
  }
772
  $strData = UniteFunctionsUC::jsonEncodeForClientSide($arrData);
773
 
774
  $script = "//Unlimited Elements Filters \n";
775
+ $script .= "var g_strFiltersData = {$strData};";
776
 
777
  UniteProviderFunctionsUC::printCustomScript($script);
778
  }
inc_php/unitecreator_globals.class.php CHANGED
@@ -136,7 +136,7 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
136
  public static $is_admin;
137
  public static $isLocal; //if website located in localhost
138
  public static $is_admin_debug_mode = false;
139
- public static $isCDCPSupported = true;
140
  public static $is_ssl;
141
  public static $path_base;
142
  public static $path_cache;
136
  public static $is_admin;
137
  public static $isLocal; //if website located in localhost
138
  public static $is_admin_debug_mode = false;
139
+ public static $isDOUBLYSupported = true;
140
  public static $is_ssl;
141
  public static $path_base;
142
  public static $path_cache;
inc_php/unitecreator_helper.class.php CHANGED
@@ -1317,7 +1317,7 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
1317
 
1318
  return($url);
1319
  }
1320
-
1321
 
1322
  public static function a______SCRIPTS______(){}
1323
 
1317
 
1318
  return($url);
1319
  }
1320
+
1321
 
1322
  public static function a______SCRIPTS______(){}
1323
 
inc_php/unitecreator_helperhtml.class.php CHANGED
@@ -791,7 +791,7 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
791
 
792
  $html = "";
793
  foreach($arrNotices as $notice){
794
- $notice = esc_attr($notice);
795
  $html .= "\n<div class='unite-admin-notice'>{$notice}</div>\n";
796
  }
797
 
@@ -1043,7 +1043,7 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
1043
  </td>
1044
  <td>
1045
  <div class="uc-dialog-condition-value-wrapper">
1046
- <select class="uc-dialog-condition-value" name="condition_value"></select>
1047
 
1048
  <a href="javascript:void(0)" class="uc-dialog-link-addcondition" title="<?php _e("Add Condition", "unlimited-elements-for-elementor") ?>">+</a>
1049
  </div>
@@ -1077,12 +1077,23 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
1077
  /**
1078
  * put remote parent js
1079
  */
1080
- public static function putRemoteParentJS($arg1){
 
 
 
 
 
 
1081
 
1082
  ?>
 
 
 
 
1083
  <?php echo $arg1?>.trigger("uc-object-ready");
1084
- jQuery("body").trigger("uc-remote-parent-init", [<?php echo $arg1?>]);
1085
  <?php
 
1086
  }
1087
 
1088
 
791
 
792
  $html = "";
793
  foreach($arrNotices as $notice){
794
+
795
  $html .= "\n<div class='unite-admin-notice'>{$notice}</div>\n";
796
  }
797
 
1043
  </td>
1044
  <td>
1045
  <div class="uc-dialog-condition-value-wrapper">
1046
+ <select class="uc-dialog-condition-value" name="condition_value" multiple></select>
1047
 
1048
  <a href="javascript:void(0)" class="uc-dialog-link-addcondition" title="<?php _e("Add Condition", "unlimited-elements-for-elementor") ?>">+</a>
1049
  </div>
1077
  /**
1078
  * put remote parent js
1079
  */
1080
+ public static function putRemoteParentJS($arg1, $arg2 = null){
1081
+
1082
+ $strOptions = "[$arg1";
1083
+
1084
+ //maybe put something here
1085
+
1086
+ $strOptions .= "]";
1087
 
1088
  ?>
1089
+ <?php if(!empty($arg2)):?>
1090
+ <?php echo $arg1?>.data("uc-remote-options", <?php echo $arg2?>);
1091
+ <?php endif?>
1092
+
1093
  <?php echo $arg1?>.trigger("uc-object-ready");
1094
+ jQuery("body").trigger("uc-remote-parent-init", <?php echo $strOptions?>);
1095
  <?php
1096
+
1097
  }
1098
 
1099
 
inc_php/unitecreator_output.class.php CHANGED
@@ -169,16 +169,22 @@ class UniteCreatorOutputWork extends HtmlOutputBaseUC{
169
  return(false);
170
 
171
  $params = $this->getAddonParams();
172
-
173
  if(array_key_exists($name, $params) == false)
174
  return(true);
175
 
176
  $paramValue = $params[$name];
 
 
177
 
178
- if($paramValue === $value)
179
- return(true);
180
- else
181
- return(false);
 
 
 
 
182
  }
183
 
184
 
@@ -192,8 +198,9 @@ class UniteCreatorOutputWork extends HtmlOutputBaseUC{
192
  foreach($arrIncludes as $handle => $include){
193
 
194
  $urlInclude = $include;
195
-
196
  if(is_array($include)){
 
197
  $urlInclude = UniteFunctionsUC::getVal($include, "url");
198
  $condition = UniteFunctionsUC::getVal($include, "condition");
199
  $isIncludeByCondition = $this->checkIncludeCondition($condition);
@@ -1317,12 +1324,11 @@ class UniteCreatorOutputWork extends HtmlOutputBaseUC{
1317
  $id = $post->ID;
1318
  $alias = $post->post_name;
1319
  }
1320
-
1321
-
1322
  $num = $index+1;
1323
 
1324
-
1325
  $status = $post->post_status;
 
1326
 
1327
  $arrTermsNames = UniteFunctionsWPUC::getPostTermsTitles($post);
1328
  $strTerms = implode(",", $arrTermsNames);
@@ -1331,7 +1337,7 @@ class UniteCreatorOutputWork extends HtmlOutputBaseUC{
1331
  if($status != "publish")
1332
  $htmlAfterAlias = ", [$status post]";
1333
 
1334
- $text = "{$num}. <b>$title</b> (<i style='font-size:13px;'>$alias{$htmlAfterAlias}, $id | $strTerms </i>)";
1335
 
1336
  dmp($text);
1337
 
@@ -1657,11 +1663,19 @@ class UniteCreatorOutputWork extends HtmlOutputBaseUC{
1657
 
1658
 
1659
  }catch(Exception $e){
1660
-
1661
  $message = $e->getMessage();
1662
 
1663
  $message = "Error in widget $title, ".$message;
1664
- UniteFunctionsUC::throwError($message);
 
 
 
 
 
 
 
 
1665
  }
1666
 
1667
  return($output);
169
  return(false);
170
 
171
  $params = $this->getAddonParams();
172
+
173
  if(array_key_exists($name, $params) == false)
174
  return(true);
175
 
176
  $paramValue = $params[$name];
177
+
178
+ if(is_array($value)){
179
 
180
+ $index = array_search($paramValue, $value);
181
+
182
+ $isEqual = ($index !== false);
183
+
184
+ }else
185
+ $isEqual = ($paramValue === $value);
186
+
187
+ return($isEqual);
188
  }
189
 
190
 
198
  foreach($arrIncludes as $handle => $include){
199
 
200
  $urlInclude = $include;
201
+
202
  if(is_array($include)){
203
+
204
  $urlInclude = UniteFunctionsUC::getVal($include, "url");
205
  $condition = UniteFunctionsUC::getVal($include, "condition");
206
  $isIncludeByCondition = $this->checkIncludeCondition($condition);
1324
  $id = $post->ID;
1325
  $alias = $post->post_name;
1326
  }
1327
+
 
1328
  $num = $index+1;
1329
 
 
1330
  $status = $post->post_status;
1331
+ $menuOrder = $post->menu_order;
1332
 
1333
  $arrTermsNames = UniteFunctionsWPUC::getPostTermsTitles($post);
1334
  $strTerms = implode(",", $arrTermsNames);
1337
  if($status != "publish")
1338
  $htmlAfterAlias = ", [$status post]";
1339
 
1340
+ $text = "{$num}. <b>$title</b> (<i style='font-size:13px;'>$alias{$htmlAfterAlias}, $id | $strTerms </i>), menu order: $menuOrder";
1341
 
1342
  dmp($text);
1343
 
1663
 
1664
 
1665
  }catch(Exception $e){
1666
+
1667
  $message = $e->getMessage();
1668
 
1669
  $message = "Error in widget $title, ".$message;
1670
+
1671
+ if(GlobalsUC::SHOW_TRACE == true){
1672
+
1673
+ dmp($message);
1674
+ UniteFunctionsUC::throwError($e);
1675
+ }
1676
+
1677
+
1678
+ UniteFunctionsUC::throwError($message);
1679
  }
1680
 
1681
  return($output);
inc_php/unitecreator_params_editor.class.php CHANGED
@@ -58,8 +58,7 @@ class UniteCreatorParamsEditor{
58
 
59
  <div class="uc-dialog-param">
60
  <?php
61
- if(GlobalsUC::$inDev)
62
- HelperHtmlUC::putHtmlConditions("section")
63
  ?>
64
  </div>
65
 
58
 
59
  <div class="uc-dialog-param">
60
  <?php
61
+ HelperHtmlUC::putHtmlConditions("section")
 
62
  ?>
63
  </div>
64
 
inc_php/unitecreator_params_processor.class.php CHANGED
@@ -795,7 +795,6 @@ class UniteCreatorParamsProcessorWork{
795
 
796
  $alt = esc_attr($alt);
797
  $attributes .= " alt=\"{$alt}\"";
798
-
799
  }
800
 
801
  $data[$name."_attributes_nosize"] = $attributes;
@@ -850,7 +849,7 @@ class UniteCreatorParamsProcessorWork{
850
  * get image as json processed data
851
  */
852
  private function getProcessedParamsValue_imageJson($data, $value, $param){
853
-
854
  //if the value is emtpy
855
  if(empty($value)){
856
 
@@ -885,7 +884,7 @@ class UniteCreatorParamsProcessorWork{
885
  * @param $param
886
  */
887
  protected function getProcessedParamsValue_image($data, $value, $param){
888
-
889
  $mediaType = UniteFunctionsUC::getVal($param, "media_type");
890
 
891
  $name = $param["name"];
@@ -928,7 +927,7 @@ class UniteCreatorParamsProcessorWork{
928
  $isNoImageData = UniteFunctionsUC::getVal($param, "no_image_data");
929
 
930
  $data = $this->addOtherImageThumbs($data, $name, $value, $sizeFilters);
931
-
932
  if($isNoImageData !== true)
933
  $data = $this->addOtherImageData($data, $name, $value);
934
 
@@ -1453,7 +1452,8 @@ class UniteCreatorParamsProcessorWork{
1453
  $url = UniteFunctionsUC::getVal($value, "url");
1454
  $isExternal = UniteFunctionsUC::getVal($value, "is_external");
1455
  $noFollow = UniteFunctionsUC::getVal($value, "nofollow");
1456
-
 
1457
  $urlFull = $url;
1458
  $scheme = parse_url($url, PHP_URL_SCHEME);
1459
 
@@ -1471,14 +1471,19 @@ class UniteCreatorParamsProcessorWork{
1471
  if($noFollow == "on")
1472
  $addHtml .= " rel='nofollow'";
1473
 
 
 
 
 
1474
  $data[$name] = $url;
1475
  $data[$name."_html_attributes"] = $addHtml;
1476
- $data[$name."_full"] = $addHtml;
1477
- $data[$name."_noprefix"] = $addHtml;
1478
 
1479
  return($data);
1480
  }
1481
 
 
1482
  /**
1483
  * get menu data
1484
  */
795
 
796
  $alt = esc_attr($alt);
797
  $attributes .= " alt=\"{$alt}\"";
 
798
  }
799
 
800
  $data[$name."_attributes_nosize"] = $attributes;
849
  * get image as json processed data
850
  */
851
  private function getProcessedParamsValue_imageJson($data, $value, $param){
852
+
853
  //if the value is emtpy
854
  if(empty($value)){
855
 
884
  * @param $param
885
  */
886
  protected function getProcessedParamsValue_image($data, $value, $param){
887
+
888
  $mediaType = UniteFunctionsUC::getVal($param, "media_type");
889
 
890
  $name = $param["name"];
927
  $isNoImageData = UniteFunctionsUC::getVal($param, "no_image_data");
928
 
929
  $data = $this->addOtherImageThumbs($data, $name, $value, $sizeFilters);
930
+
931
  if($isNoImageData !== true)
932
  $data = $this->addOtherImageData($data, $name, $value);
933
 
1452
  $url = UniteFunctionsUC::getVal($value, "url");
1453
  $isExternal = UniteFunctionsUC::getVal($value, "is_external");
1454
  $noFollow = UniteFunctionsUC::getVal($value, "nofollow");
1455
+ $customAttributes = UniteFunctionsUC::getVal($value, "custom_attributes");
1456
+
1457
  $urlFull = $url;
1458
  $scheme = parse_url($url, PHP_URL_SCHEME);
1459
 
1471
  if($noFollow == "on")
1472
  $addHtml .= " rel='nofollow'";
1473
 
1474
+ if(!empty($customAttributes))
1475
+ $addHtml .= " ".$customAttributes;
1476
+
1477
+
1478
  $data[$name] = $url;
1479
  $data[$name."_html_attributes"] = $addHtml;
1480
+ $data[$name."_full"] = $urlFull;
1481
+ $data[$name."_noprefix"] = $urlNoPrefix;
1482
 
1483
  return($data);
1484
  }
1485
 
1486
+
1487
  /**
1488
  * get menu data
1489
  */
inc_php/unitecreator_settings.class.php CHANGED
@@ -27,6 +27,7 @@ class UniteCreatorSettingsWork extends UniteSettingsAdvancedUC{
27
 
28
  private function a___________GETTERS_________(){}
29
 
 
30
 
31
  /**
32
  * get settings in creator format
@@ -542,6 +543,8 @@ class UniteCreatorSettingsWork extends UniteSettingsAdvancedUC{
542
  dmp("addFiltersItemSelector - function for override");
543
  exit();
544
  }
 
 
545
 
546
  /**
547
  * add setting by creator param
27
 
28
  private function a___________GETTERS_________(){}
29
 
30
+
31
 
32
  /**
33
  * get settings in creator format
543
  dmp("addFiltersItemSelector - function for override");
544
  exit();
545
  }
546
+
547
+
548
 
549
  /**
550
  * add setting by creator param
inc_php/unitecreator_template_engine.class.php CHANGED
@@ -815,7 +815,6 @@ class UniteCreatorTemplateEngineWork{
815
 
816
  $term = HelperProviderUC::getPostTermForTemplate($arg1, $arg2, $arg3);
817
  return($term);
818
-
819
  break;
820
  case "is_post_has_term":
821
 
@@ -852,6 +851,22 @@ class UniteCreatorTemplateEngineWork{
852
 
853
  return($arrVariations);
854
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
855
  case "get_unitegallery_js":
856
 
857
  $objUniteGallery = new UniteCreatorUniteGallery();
@@ -862,7 +877,7 @@ class UniteCreatorTemplateEngineWork{
862
  break;
863
  case "put_remote_parent_js":
864
 
865
- HelperHtmlUC::putRemoteParentJS($arg1);
866
 
867
  break;
868
  default:
815
 
816
  $term = HelperProviderUC::getPostTermForTemplate($arg1, $arg2, $arg3);
817
  return($term);
 
818
  break;
819
  case "is_post_has_term":
820
 
851
 
852
  return($arrVariations);
853
  break;
854
+ case "get_woo_gallery":
855
+ case "get_wc_gallery":
856
+
857
+ $productID = $arg1;
858
+
859
+ $objWoo = new UniteCreatorWooIntegrate();
860
+ $arrGallery = $objWoo->getProductGallery($productID);
861
+
862
+ return($arrGallery);
863
+ break;
864
+ case "get_woo_endpoint":
865
+
866
+ $arrEndpoints = UniteCreatorWooIntegrate::getWooEndpoint($arg1);
867
+
868
+ return($arrEndpoints);
869
+ break;
870
  case "get_unitegallery_js":
871
 
872
  $objUniteGallery = new UniteCreatorUniteGallery();
877
  break;
878
  case "put_remote_parent_js":
879
 
880
+ HelperHtmlUC::putRemoteParentJS($arg1, $arg2);
881
 
882
  break;
883
  default:
inc_php/unitecreator_unitegallery.class.php CHANGED
@@ -8,17 +8,697 @@
8
  defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
9
 
10
  class UniteCreatorUniteGallery{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
 
13
  /**
14
  * get gallery js settings from data
15
  */
16
- public function getUniteGalleryJsSettings($data,UniteCreatorAddon $addon){
 
 
17
 
18
- dmp($data);
19
- dmp("get settings from data");
20
- //exit();
21
 
 
22
  }
23
 
24
  }
8
  defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
9
 
10
  class UniteCreatorUniteGallery{
11
+
12
+ private $arrParams = array();
13
+ private $arrOriginalParams; //params as they came originally from the database
14
+ private $skipJsOptions = array();
15
+ private $arrJsParamsAssoc = array();
16
+ private $arrJsParams = array();
17
+ private $galleryType = "";
18
+
19
+
20
+ const TYPE_NUMBER = "number";
21
+ const TYPE_BOOLEAN = "boolean";
22
+ const TYPE_OBJECT = "object";
23
+ const TYPE_SIZE = "size";
24
+
25
+ const VALIDATE_EXISTS = "validate";
26
+ const VALIDATE_NUMERIC = "numeric";
27
+ const VALIDATE_SIZE = "size";
28
+ const FORCE_NUMERIC = "force_numeric";
29
+ const FORCE_BOOLEAN = "force_boolean";
30
+ const FORCE_SIZE = "force_size";
31
+ const TRIM = "trim";
32
+
33
+ const THEME_DEFAULT = "default";
34
+ const THEME_COMPACT = "compact";
35
+ const THEME_SLIDER = "slider";
36
+ const THEME_GRID = "grid";
37
+ const THEME_VIDEO = "video";
38
+ const THEME_TILES = "tiles";
39
+ const THEME_TILESGRID = "tilesgrid";
40
+ const THEME_CAROUSEL = "carousel";
41
+
42
+ const TYPE_TILES_COLUMNS = "tiles_columns";
43
+ const TYPE_TILES_JUSTIFIED = "tiles_justified";
44
+ const TYPE_TILES_NESTED = "tiles_nested";
45
+
46
+
47
+
48
+ /**
49
+ * validate gallery theme
50
+ */
51
+ private function validateGalleryType($type){
52
+
53
+ $type = esc_html($type);
54
+
55
+ switch($type){
56
+ case self::THEME_DEFAULT:
57
+ case self::THEME_COMPACT:
58
+ case self::THEME_SLIDER:
59
+ case self::THEME_GRID:
60
+ case self::THEME_VIDEO:
61
+ case self::THEME_TILESGRID:
62
+ case self::THEME_CAROUSEL:
63
+ case self::TYPE_TILES_COLUMNS:
64
+ case self::TYPE_TILES_JUSTIFIED:
65
+ case self::TYPE_TILES_NESTED:
66
+ return(true);
67
+ break;
68
+ default:
69
+
70
+ UniteFunctionsUC::throwError("Wrong gallery type: $type");
71
+
72
+ break;
73
+ }
74
+
75
+ }
76
+
77
+
78
+ /**
79
+ * get must fields that will be thrown from the settings anyway
80
+ */
81
+ private function getArrMustFields(){
82
+ $arrMustKeys = array(
83
+ "gallery_theme",
84
+ "full_width",
85
+ "gallery_width",
86
+ "gallery_height",
87
+ "position",
88
+ "margin_top",
89
+ "margin_bottom",
90
+ "margin_left",
91
+ "margin_right"
92
+ );
93
+
94
+ return($arrMustKeys);
95
+ }
96
+
97
+ /**
98
+ * check if some param exists in params array
99
+ */
100
+ private function isParamExists($name){
101
+ $exists = array_key_exists($name, $this->arrParams);
102
+ return $exists;
103
+ }
104
+
105
+
106
+ /**
107
+ *
108
+ * get some param
109
+ */
110
+ protected function getParam($name, $validateMode = null){
111
+
112
+ if(is_array($this->arrParams) == false)
113
+ $this->arrParams = array();
114
+
115
+ if(array_key_exists($name, $this->arrParams)){
116
+ $arrParams = $this->arrParams;
117
+ $value = $this->arrParams[$name];
118
+ }
119
+ else{
120
+ if(is_array($this->arrOriginalParams) == false)
121
+ $this->arrOriginalParams = array();
122
+
123
+ $arrParams = $this->arrOriginalParams;
124
+ $value = UniteFunctionsUC::getVal($this->arrOriginalParams, $name);
125
+ }
126
+
127
+ switch ($validateMode) {
128
+ case self::VALIDATE_EXISTS:
129
+ if (array_key_exists($name, $arrParams) == false)
130
+ UniteFunctionsUC::throwError("The param: {$name} don't exists");
131
+ break;
132
+ case self::VALIDATE_NUMERIC:
133
+
134
+ if (is_numeric($value) == false)
135
+ UniteFunctionsUC::throwError("The param: {$name} is not numeric ($value)");
136
+ break;
137
+ case self::VALIDATE_SIZE:
138
+ if(strpos($value, "%") === false && is_numeric($value) == false)
139
+ UniteFunctionsUC::throwError("The param: {$name} is not size");
140
+ break;
141
+ case self::FORCE_SIZE:
142
+ $isPercent = (strpos($value, "%") !== false);
143
+ if($isPercent == false && is_numeric($value) == false)
144
+ UniteFunctionsUC::throwError("The param: {$name} is not size");
145
+
146
+ if($isPercent == false)
147
+ $value .= "px";
148
+ break;
149
+ case self::FORCE_NUMERIC:
150
+ $value = floatval($value);
151
+ $value = (double) $value;
152
+ break;
153
+ case self::FORCE_BOOLEAN:
154
+ $value = UniteFunctionsUC::strToBool($value);
155
+ break;
156
+ case self::TRIM:
157
+ $value = trim($value);
158
+ break;
159
+ }
160
+
161
+ return($value);
162
+ }
163
+
164
+
165
+
166
+ /**
167
+ * build javascript param
168
+ */
169
+ private function buildJsParam($paramName, $validate = null, $type = null, $replaceParamName = null){
170
+
171
+ if(array_key_exists($paramName, $this->arrJsParamsAssoc))
172
+ UniteFunctionsUC::throwError("Unable to biuld js param: <b>$paramName</b> already exists");
173
+
174
+ $output = array("name"=>$paramName, "validate"=>$validate, "type"=>$type, "replace"=>$replaceParamName);
175
+
176
+ $this->arrJsParamsAssoc[$paramName] = true;
177
+
178
+ $this->arrJsParams[] = $output;
179
+
180
+ }
181
+
182
+
183
+
184
+ /**
185
+ * build theme related js params
186
+ */
187
+ private function buildThemeRelatedJSParams($arr){
188
+
189
+
190
+ //----- tiles grid --------
191
+
192
+ switch($this->galleryType){
193
+
194
+ case self::THEME_TILESGRID:
195
+
196
+ $arr[] = $this->buildJsParam("theme_gallery_padding", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
197
+ $arr[] = $this->buildJsParam("grid_padding", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
198
+ $arr[] = $this->buildJsParam("grid_num_rows", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
199
+
200
+ $arr[] = $this->buildJsParam("grid_space_between_mobile", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
201
+ $arr[] = $this->buildJsParam("grid_min_cols", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
202
+
203
+ $arr[] = $this->buildJsParam("theme_navigation_type");
204
+ $arr[] = $this->buildJsParam("theme_arrows_margin_top", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
205
+ $arr[] = $this->buildJsParam("theme_space_between_arrows", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
206
+ $arr[] = $this->buildJsParam("theme_bullets_color");
207
+ $arr[] = $this->buildJsParam("bullets_space_between", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
208
+ $arr[] = $this->buildJsParam("theme_bullets_margin_top", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
209
+
210
+ $arr[] = $this->buildJsParam("theme_open_lightbox_at_start", null, self::TYPE_BOOLEAN);
211
+ $arr[] = $this->buildJsParam("theme_grid_align");
212
+
213
+ break;
214
+ case self::TYPE_TILES_COLUMNS:
215
+
216
+ $arr[] = $this->buildJsParam("theme_open_lightbox_at_start_columns", null, self::TYPE_BOOLEAN, "theme_open_lightbox_at_start");
217
+
218
+ $arr[] = $this->buildJsParam("theme_gallery_padding_columns", self::VALIDATE_NUMERIC, self::TYPE_NUMBER,"theme_gallery_padding");
219
+ $arr[] = $this->buildJsParam("tiles_include_padding", null, self::TYPE_BOOLEAN);
220
+ $arr[] = $this->buildJsParam("tiles_col_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
221
+ $arr[] = $this->buildJsParam("tiles_space_between_cols", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
222
+ $arr[] = $this->buildJsParam("tiles_set_initial_height", null, self::TYPE_BOOLEAN);
223
+ $arr[] = $this->buildJsParam("tiles_space_between_cols_mobile", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
224
+ $arr[] = $this->buildJsParam("tiles_exact_width", null, self::TYPE_BOOLEAN);
225
+ $arr[] = $this->buildJsParam("tiles_min_columns", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
226
+ $arr[] = $this->buildJsParam("tiles_max_columns", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
227
+
228
+ $arr[] = $this->buildJsParam("theme_enable_preloader", null, self::TYPE_BOOLEAN);
229
+ $arr[] = $this->buildJsParam("theme_preloading_height", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
230
+ $arr[] = $this->buildJsParam("theme_preloader_vertpos", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
231
+ $arr[] = $this->buildJsParam("tiles_enable_transition", null, self::TYPE_BOOLEAN);
232
+ $arr[] = $this->buildJsParam("theme_appearance_order");
233
+
234
+ $arr[] = $this->buildJsParam("tiles_align"); //param not in settings
235
+
236
+ $arr[] = $this->buildJsParam("theme_auto_open", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
237
+
238
+ break;
239
+ default:
240
+
241
+ UniteFunctionsUC::throwError("buildThemeRelatedJSParams: no options for this type yet: ".$this->galleryType);
242
+
243
+ break;
244
+ }
245
+
246
+
247
+
248
+ return($arr);
249
+ }
250
+
251
+
252
+ /**
253
+ * get params array defenitions that shouls be put as is from the settings
254
+ */
255
+ private function buildJSOptions(){
256
+
257
+ $arr = array();
258
+ $arr[] = $this->buildJsParam("gallery_theme");
259
+ $arr[] = $this->buildJsParam("tiles_type");
260
+ $arr[] = $this->buildJsParam("gallery_width", self::VALIDATE_SIZE, self::TYPE_SIZE);
261
+ $arr[] = $this->buildJsParam("gallery_height", self::VALIDATE_SIZE, self::TYPE_SIZE);
262
+ $arr[] = $this->buildJsParam("gallery_min_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
263
+ $arr[] = $this->buildJsParam("gallery_min_height", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
264
+ $arr[] = $this->buildJsParam("gallery_skin");
265
+ $arr[] = $this->buildJsParam("gallery_images_preload_type");
266
+ $arr[] = $this->buildJsParam("gallery_autoplay", null, self::TYPE_BOOLEAN);
267
+ $arr[] = $this->buildJsParam("gallery_play_interval", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
268
+ $arr[] = $this->buildJsParam("gallery_pause_on_mouseover", null, self::TYPE_BOOLEAN);
269
+ $arr[] = $this->buildJsParam("gallery_mousewheel_role");
270
+ $arr[] = $this->buildJsParam("gallery_control_keyboard", null, self::TYPE_BOOLEAN);
271
+ $arr[] = $this->buildJsParam("gallery_preserve_ratio", null, self::TYPE_BOOLEAN);
272
+ $arr[] = $this->buildJsParam("gallery_shuffle", null, self::TYPE_BOOLEAN);
273
+ $arr[] = $this->buildJsParam("gallery_debug_errors", null, self::TYPE_BOOLEAN);
274
+ $arr[] = $this->buildJsParam("slider_background_color");
275
+ $arr[] = $this->buildJsParam("slider_background_opacity", self::FORCE_NUMERIC, self::TYPE_NUMBER);
276
+
277
+ $arr[] = $this->buildJsParam("slider_scale_mode");
278
+ $arr[] = $this->buildJsParam("slider_scale_mode_media");
279
+ $arr[] = $this->buildJsParam("slider_scale_mode_fullscreen");
280
+
281
+ $arr[] = $this->buildJsParam("slider_transition");
282
+ $arr[] = $this->buildJsParam("slider_transition_speed", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
283
+ $arr[] = $this->buildJsParam("slider_transition_easing");
284
+ $arr[] = $this->buildJsParam("slider_control_swipe", null, self::TYPE_BOOLEAN);
285
+ $arr[] = $this->buildJsParam("slider_control_zoom", null, self::TYPE_BOOLEAN);
286
+ $arr[] = $this->buildJsParam("slider_zoom_max_ratio", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
287
+ $arr[] = $this->buildJsParam("slider_enable_links", null, self::TYPE_BOOLEAN);
288
+ $arr[] = $this->buildJsParam("slider_links_newpage", null, self::TYPE_BOOLEAN);
289
+
290
+ $arr[] = $this->buildJsParam("slider_video_enable_closebutton", null, self::TYPE_BOOLEAN);
291
+
292
+ $arr[] = $this->buildJsParam("slider_controls_always_on", null, self::TYPE_BOOLEAN);
293
+ $arr[] = $this->buildJsParam("slider_controls_appear_ontap", null, self::TYPE_BOOLEAN);
294
+ $arr[] = $this->buildJsParam("slider_controls_appear_duration", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
295
+
296
+ $arr[] = $this->buildJsParam("slider_loader_type", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
297
+ $arr[] = $this->buildJsParam("slider_loader_color");
298
+
299
+ $arr[] = $this->buildJsParam("slider_enable_bullets", null, self::TYPE_BOOLEAN);
300
+ $arr[] = $this->buildJsParam("slider_bullets_skin");
301
+ $arr[] = $this->buildJsParam("slider_bullets_space_between", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
302
+ $arr[] = $this->buildJsParam("slider_bullets_align_hor");
303
+ $arr[] = $this->buildJsParam("slider_bullets_align_vert");
304
+ $arr[] = $this->buildJsParam("slider_bullets_offset_hor", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
305
+ $arr[] = $this->buildJsParam("slider_bullets_offset_vert", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
306
+
307
+ $arr[] = $this->buildJsParam("slider_enable_arrows", null, self::TYPE_BOOLEAN);
308
+ $arr[] = $this->buildJsParam("slider_arrows_skin");
309
+ $arr[] = $this->buildJsParam("slider_arrow_left_align_hor");
310
+ $arr[] = $this->buildJsParam("slider_arrow_left_align_vert");
311
+ $arr[] = $this->buildJsParam("slider_arrow_left_offset_hor", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
312
+ $arr[] = $this->buildJsParam("slider_arrow_left_offset_vert", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
313
+ $arr[] = $this->buildJsParam("slider_arrow_right_align_hor");
314
+ $arr[] = $this->buildJsParam("slider_arrow_right_align_vert");
315
+ $arr[] = $this->buildJsParam("slider_arrow_right_offset_hor", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
316
+ $arr[] = $this->buildJsParam("slider_arrow_right_offset_vert", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
317
+
318
+ $arr[] = $this->buildJsParam("slider_enable_progress_indicator", null, self::TYPE_BOOLEAN);
319
+ $arr[] = $this->buildJsParam("slider_progress_indicator_type");
320
+ $arr[] = $this->buildJsParam("slider_progress_indicator_align_hor");
321
+ $arr[] = $this->buildJsParam("slider_progress_indicator_align_vert");
322
+ $arr[] = $this->buildJsParam("slider_progress_indicator_offset_hor", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
323
+ $arr[] = $this->buildJsParam("slider_progress_indicator_offset_vert", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
324
+
325
+ $arr[] = $this->buildJsParam("slider_progressbar_color");
326
+ $arr[] = $this->buildJsParam("slider_progressbar_opacity", self::FORCE_NUMERIC, self::TYPE_NUMBER);
327
+ $arr[] = $this->buildJsParam("slider_progressbar_line_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
328
+
329
+ $arr[] = $this->buildJsParam("slider_progresspie_color1");
330
+ $arr[] = $this->buildJsParam("slider_progresspie_color2");
331
+ $arr[] = $this->buildJsParam("slider_progresspie_stroke_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
332
+ $arr[] = $this->buildJsParam("slider_progresspie_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
333
+ $arr[] = $this->buildJsParam("slider_progresspie_height", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
334
+
335
+ $arr[] = $this->buildJsParam("slider_enable_play_button", null, self::TYPE_BOOLEAN);
336
+ $arr[] = $this->buildJsParam("slider_play_button_skin");
337
+ $arr[] = $this->buildJsParam("slider_play_button_align_hor");
338
+ $arr[] = $this->buildJsParam("slider_play_button_align_vert");
339
+ $arr[] = $this->buildJsParam("slider_play_button_offset_hor", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
340
+ $arr[] = $this->buildJsParam("slider_play_button_offset_vert", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
341
+
342
+ $arr[] = $this->buildJsParam("slider_enable_fullscreen_button", null, self::TYPE_BOOLEAN);
343
+ $arr[] = $this->buildJsParam("slider_fullscreen_button_skin");
344
+ $arr[] = $this->buildJsParam("slider_fullscreen_button_align_hor");
345
+ $arr[] = $this->buildJsParam("slider_fullscreen_button_align_vert");
346
+ $arr[] = $this->buildJsParam("slider_fullscreen_button_offset_hor", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
347
+ $arr[] = $this->buildJsParam("slider_fullscreen_button_offset_vert", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
348
+
349
+ $arr[] = $this->buildJsParam("slider_enable_zoom_panel", null, self::TYPE_BOOLEAN);
350
+ $arr[] = $this->buildJsParam("slider_zoompanel_skin");
351
+ $arr[] = $this->buildJsParam("slider_zoompanel_align_hor");
352
+ $arr[] = $this->buildJsParam("slider_zoompanel_align_vert");
353
+ $arr[] = $this->buildJsParam("slider_zoompanel_offset_hor", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
354
+ $arr[] = $this->buildJsParam("slider_zoompanel_offset_vert", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
355
+
356
+ $arr[] = $this->buildJsParam("slider_enable_text_panel", null, self::TYPE_BOOLEAN);
357
+ $arr[] = $this->buildJsParam("slider_textpanel_always_on", null, self::TYPE_BOOLEAN);
358
+ $arr[] = $this->buildJsParam("slider_textpanel_align");
359
+ $arr[] = $this->buildJsParam("slider_textpanel_margin", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
360
+ $arr[] = $this->buildJsParam("slider_textpanel_text_valign");
361
+ $arr[] = $this->buildJsParam("slider_textpanel_padding_top", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
362
+ $arr[] = $this->buildJsParam("slider_textpanel_padding_bottom", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
363
+ $arr[] = $this->buildJsParam("slider_textpanel_height", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
364
+ $arr[] = $this->buildJsParam("slider_textpanel_padding_title_description", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
365
+ $arr[] = $this->buildJsParam("slider_textpanel_padding_right", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
366
+ $arr[] = $this->buildJsParam("slider_textpanel_padding_left", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
367
+ $arr[] = $this->buildJsParam("slider_textpanel_fade_duration", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
368
+ $arr[] = $this->buildJsParam("slider_textpanel_enable_title", null, self::TYPE_BOOLEAN);
369
+ $arr[] = $this->buildJsParam("slider_textpanel_title_as_link", null, self::TYPE_BOOLEAN);
370
+ $arr[] = $this->buildJsParam("slider_textpanel_enable_description", null, self::TYPE_BOOLEAN);
371
+ $arr[] = $this->buildJsParam("slider_textpanel_enable_bg", null, self::TYPE_BOOLEAN);
372
+ $arr[] = $this->buildJsParam("slider_textpanel_bg_color");
373
+ $arr[] = $this->buildJsParam("slider_textpanel_bg_opacity", self::FORCE_NUMERIC, self::TYPE_NUMBER);
374
+
375
+ $arr[] = $this->buildJsParam("thumb_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
376
+ $arr[] = $this->buildJsParam("thumb_height", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
377
+ $arr[] = $this->buildJsParam("thumb_fixed_size", null, self::TYPE_BOOLEAN);
378
+ $arr[] = $this->buildJsParam("thumb_border_effect", null, self::TYPE_BOOLEAN);
379
+ $arr[] = $this->buildJsParam("thumb_border_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
380
+ $arr[] = $this->buildJsParam("thumb_border_color");
381
+ $arr[] = $this->buildJsParam("thumb_over_border_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
382
+ $arr[] = $this->buildJsParam("thumb_over_border_color");
383
+ $arr[] = $this->buildJsParam("thumb_selected_border_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
384
+ $arr[] = $this->buildJsParam("thumb_selected_border_color");
385
+ $arr[] = $this->buildJsParam("thumb_round_corners_radius", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
386
+ $arr[] = $this->buildJsParam("thumb_color_overlay_effect", null, self::TYPE_BOOLEAN);
387
+ $arr[] = $this->buildJsParam("thumb_overlay_color");
388
+ $arr[] = $this->buildJsParam("thumb_overlay_opacity", self::FORCE_NUMERIC, self::TYPE_NUMBER);
389
+ $arr[] = $this->buildJsParam("thumb_overlay_reverse", null, self::TYPE_BOOLEAN);
390
+ $arr[] = $this->buildJsParam("thumb_image_overlay_effect", null, self::TYPE_BOOLEAN);
391
+ $arr[] = $this->buildJsParam("thumb_image_overlay_type");
392
+ $arr[] = $this->buildJsParam("thumb_transition_duration", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
393
+ $arr[] = $this->buildJsParam("thumb_transition_easing");
394
+ $arr[] = $this->buildJsParam("thumb_show_loader", null, self::TYPE_BOOLEAN);
395
+ $arr[] = $this->buildJsParam("thumb_loader_type");
396
+
397
+ $arr[] = $this->buildJsParam("strippanel_padding_top", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
398
+ $arr[] = $this->buildJsParam("strippanel_padding_bottom", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
399
+ $arr[] = $this->buildJsParam("strippanel_padding_left", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
400
+ $arr[] = $this->buildJsParam("strippanel_padding_right", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
401
+ $arr[] = $this->buildJsParam("strippanel_enable_buttons", null, self::TYPE_BOOLEAN);
402
+ $arr[] = $this->buildJsParam("strippanel_buttons_skin");
403
+ $arr[] = $this->buildJsParam("strippanel_padding_buttons", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
404
+ $arr[] = $this->buildJsParam("strippanel_buttons_role");
405
+ $arr[] = $this->buildJsParam("strippanel_enable_handle", null, self::TYPE_BOOLEAN);
406
+ $arr[] = $this->buildJsParam("strippanel_handle_align");
407
+ $arr[] = $this->buildJsParam("strippanel_handle_offset", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
408
+ $arr[] = $this->buildJsParam("strippanel_handle_skin");
409
+ $arr[] = $this->buildJsParam("strippanel_background_color");
410
+ $arr[] = $this->buildJsParam("strip_thumbs_align");
411
+ $arr[] = $this->buildJsParam("strip_space_between_thumbs", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
412
+ $arr[] = $this->buildJsParam("strip_thumb_touch_sensetivity", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
413
+ $arr[] = $this->buildJsParam("strip_scroll_to_thumb_duration", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
414
+ $arr[] = $this->buildJsParam("strip_scroll_to_thumb_easing");
415
+ $arr[] = $this->buildJsParam("strip_control_avia", null, self::TYPE_BOOLEAN);
416
+ $arr[] = $this->buildJsParam("strip_control_touch", null, self::TYPE_BOOLEAN);
417
+
418
+ $arr[] = $this->buildJsParam("gridpanel_vertical_scroll", null, self::TYPE_BOOLEAN);
419
+ $arr[] = $this->buildJsParam("gridpanel_grid_align");
420
+ $arr[] = $this->buildJsParam("gridpanel_padding_border_top", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
421
+ $arr[] = $this->buildJsParam("gridpanel_padding_border_bottom", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
422
+ $arr[] = $this->buildJsParam("gridpanel_padding_border_left", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
423
+ $arr[] = $this->buildJsParam("gridpanel_padding_border_right", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
424
+ $arr[] = $this->buildJsParam("gridpanel_arrows_skin");
425
+ $arr[] = $this->buildJsParam("gridpanel_arrows_align_vert");
426
+ $arr[] = $this->buildJsParam("gridpanel_arrows_padding_vert", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
427
+ $arr[] = $this->buildJsParam("gridpanel_arrows_align_hor");
428
+ $arr[] = $this->buildJsParam("gridpanel_arrows_padding_hor", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
429
+ $arr[] = $this->buildJsParam("gridpanel_space_between_arrows", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
430
+ $arr[] = $this->buildJsParam("gridpanel_arrows_always_on", null, self::TYPE_BOOLEAN);
431
+ $arr[] = $this->buildJsParam("gridpanel_enable_handle", null, self::TYPE_BOOLEAN);
432
+ $arr[] = $this->buildJsParam("gridpanel_handle_align");
433
+ $arr[] = $this->buildJsParam("gridpanel_handle_offset", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
434
+ $arr[] = $this->buildJsParam("gridpanel_handle_skin");
435
+ $arr[] = $this->buildJsParam("gridpanel_background_color");
436
+
437
+ $arr[] = $this->buildJsParam("grid_panes_direction");
438
+ $arr[] = $this->buildJsParam("grid_num_cols", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
439
+ $arr[] = $this->buildJsParam("grid_space_between_cols", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
440
+ $arr[] = $this->buildJsParam("grid_space_between_rows", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
441
+ $arr[] = $this->buildJsParam("grid_transition_duration", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
442
+ $arr[] = $this->buildJsParam("grid_transition_easing");
443
+ $arr[] = $this->buildJsParam("grid_carousel", null, self::TYPE_BOOLEAN);
444
+
445
+ //category tabs related
446
+ $arr[] = $this->buildJsParam("gallery_urlajax");
447
+ $arr[] = $this->buildJsParam("gallery_enable_tabs", null, self::TYPE_BOOLEAN);
448
+ $arr[] = $this->buildJsParam("tabs_type");
449
+ $arr[] = $this->buildJsParam("tabs_container");
450
+ $arr[] = $this->buildJsParam("gallery_initial_catid");
451
+ $arr[] = $this->buildJsParam("load_api_externally", null, self::TYPE_BOOLEAN);
452
+
453
+ $arr[] = $this->buildJsParam("gallery_enable_loadmore", null, self::TYPE_BOOLEAN);
454
+ $arr[] = $this->buildJsParam("loadmore_container");
455
+
456
+
457
+ $arr[] = $this->buildJsParam("tile_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
458
+ $arr[] = $this->buildJsParam("tile_height", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
459
+ $arr[] = $this->buildJsParam("tile_enable_background", null, self::TYPE_BOOLEAN);
460
+ $arr[] = $this->buildJsParam("tile_background_color");
461
+ $arr[] = $this->buildJsParam("tile_enable_border", null, self::TYPE_BOOLEAN);
462
+ $arr[] = $this->buildJsParam("tile_border_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
463
+ $arr[] = $this->buildJsParam("tile_border_color");
464
+ $arr[] = $this->buildJsParam("tile_border_radius", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
465
+ $arr[] = $this->buildJsParam("tile_enable_outline", null, self::TYPE_BOOLEAN);
466
+ $arr[] = $this->buildJsParam("tile_outline_color");
467
+ $arr[] = $this->buildJsParam("tile_enable_shadow", null, self::TYPE_BOOLEAN);
468
+ $arr[] = $this->buildJsParam("tile_shadow_h", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
469
+ $arr[] = $this->buildJsParam("tile_shadow_v", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
470
+ $arr[] = $this->buildJsParam("tile_shadow_blur", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
471
+ $arr[] = $this->buildJsParam("tile_shadow_spread", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
472
+ $arr[] = $this->buildJsParam("tile_shadow_color");
473
+ $arr[] = $this->buildJsParam("tile_enable_action");
474
+ $arr[] = $this->buildJsParam("tile_as_link", null, self::TYPE_BOOLEAN);
475
+ $arr[] = $this->buildJsParam("tile_link_newpage", null, self::TYPE_BOOLEAN);
476
+ $arr[] = $this->buildJsParam("tile_enable_overlay", null, self::TYPE_BOOLEAN);
477
+ $arr[] = $this->buildJsParam("tile_overlay_opacity", self::FORCE_NUMERIC, self::TYPE_NUMBER);
478
+ $arr[] = $this->buildJsParam("tile_overlay_color");
479
+ $arr[] = $this->buildJsParam("tile_enable_icons", null, self::TYPE_BOOLEAN);
480
+ $arr[] = $this->buildJsParam("tile_show_link_icon", null, self::TYPE_BOOLEAN);
481
+ $arr[] = $this->buildJsParam("tile_space_between_icons");
482
+ $arr[] = $this->buildJsParam("tile_videoplay_icon_always_on");
483
+ $arr[] = $this->buildJsParam("tile_enable_image_effect", null, self::TYPE_BOOLEAN);
484
+ $arr[] = $this->buildJsParam("tile_image_effect_type");
485
+ $arr[] = $this->buildJsParam("tile_image_effect_reverse", null, self::TYPE_BOOLEAN);
486
+ $arr[] = $this->buildJsParam("tile_enable_textpanel", null, self::TYPE_BOOLEAN);
487
+ $arr[] = $this->buildJsParam("tile_textpanel_source");
488
+ $arr[] = $this->buildJsParam("tile_textpanel_position");
489
+
490
+ $arr[] = $this->buildJsParam("tile_textpanel_always_on", null, self::TYPE_BOOLEAN);
491
+ $arr[] = $this->buildJsParam("tile_textpanel_appear_type");
492
+ $arr[] = $this->buildJsParam("tile_textpanel_offset", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
493
+ $arr[] = $this->buildJsParam("tile_textpanel_padding_top", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
494
+ $arr[] = $this->buildJsParam("tile_textpanel_padding_bottom", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
495
+ $arr[] = $this->buildJsParam("tile_textpanel_padding_left", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
496
+ $arr[] = $this->buildJsParam("tile_textpanel_padding_right", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
497
+ $arr[] = $this->buildJsParam("tile_textpanel_bg_color");
498
+ $arr[] = $this->buildJsParam("tile_textpanel_bg_opacity", self::FORCE_NUMERIC, self::TYPE_NUMBER);
499
+ $arr[] = $this->buildJsParam("tile_textpanel_title_color");
500
+ $arr[] = $this->buildJsParam("tile_textpanel_title_text_align");
501
+ $arr[] = $this->buildJsParam("tile_textpanel_title_font_size", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
502
+ $arr[] = $this->buildJsParam("tile_textpanel_title_bold", null, self::TYPE_BOOLEAN);
503
+ $arr[] = $this->buildJsParam("tile_textpanel_desc_bold", null, self::TYPE_BOOLEAN);
504
+
505
+ $arr[] = $this->buildJsParam("lightbox_hide_arrows_onvideoplay", null, self::TYPE_BOOLEAN);
506
+ $arr[] = $this->buildJsParam("lightbox_slider_control_swipe", null, self::TYPE_BOOLEAN);
507
+ $arr[] = $this->buildJsParam("lightbox_slider_control_zoom", null, self::TYPE_BOOLEAN);
508
+ $arr[] = $this->buildJsParam("lightbox_close_on_emptyspace", null, self::TYPE_BOOLEAN);
509
+
510
+ $arr[] = $this->buildJsParam("lightbox_slider_zoom_max_ratio", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
511
+ $arr[] = $this->buildJsParam("lightbox_slider_transition");
512
+ $arr[] = $this->buildJsParam("lightbox_overlay_opacity", self::FORCE_NUMERIC, self::TYPE_NUMBER);
513
+ $arr[] = $this->buildJsParam("lightbox_overlay_color");
514
+
515
+ $arr[] = $this->buildJsParam("lightbox_top_panel_opacity", self::FORCE_NUMERIC, self::TYPE_NUMBER);
516
+ $arr[] = $this->buildJsParam("lightbox_show_numbers", null, self::TYPE_BOOLEAN);
517
+ $arr[] = $this->buildJsParam("lightbox_numbers_size", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
518
+ $arr[] = $this->buildJsParam("lightbox_numbers_color");
519
+ $arr[] = $this->buildJsParam("lightbox_show_textpanel", null, self::TYPE_BOOLEAN);
520
+
521
+ $arr[] = $this->buildJsParam("lightbox_textpanel_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
522
+ $arr[] = $this->buildJsParam("lightbox_textpanel_enable_title", null, self::TYPE_BOOLEAN);
523
+ $arr[] = $this->buildJsParam("lightbox_textpanel_enable_description", null, self::TYPE_BOOLEAN);
524
+
525
+ $arr[] = $this->buildJsParam("lightbox_textpanel_title_color");
526
+ $arr[] = $this->buildJsParam("lightbox_textpanel_title_text_align");
527
+ $arr[] = $this->buildJsParam("lightbox_textpanel_title_font_size", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
528
+ $arr[] = $this->buildJsParam("lightbox_textpanel_title_bold", null, self::TYPE_BOOLEAN);
529
+
530
+ $arr[] = $this->buildJsParam("lightbox_textpanel_desc_color");
531
+ $arr[] = $this->buildJsParam("lightbox_textpanel_desc_text_align");
532
+ $arr[] = $this->buildJsParam("lightbox_textpanel_desc_font_size", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
533
+ $arr[] = $this->buildJsParam("lightbox_textpanel_desc_bold", null, self::TYPE_BOOLEAN);
534
+
535
+ //lightbox compact related styles
536
+ $arr[] = $this->buildJsParam("lightbox_type");
537
+ $arr[] = $this->buildJsParam("lightbox_arrows_position");
538
+ $arr[] = $this->buildJsParam("lightbox_arrows_inside_alwayson", null, self::TYPE_BOOLEAN);
539
+ $arr[] = $this->buildJsParam("lightbox_numbers_padding_top", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
540
+ $arr[] = $this->buildJsParam("lightbox_numbers_padding_right", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
541
+ $arr[] = $this->buildJsParam("lightbox_textpanel_padding_left", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
542
+ $arr[] = $this->buildJsParam("lightbox_textpanel_padding_right", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
543
+ $arr[] = $this->buildJsParam("lightbox_textpanel_padding_top", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
544
+ $arr[] = $this->buildJsParam("lightbox_slider_image_border", null, self::TYPE_BOOLEAN);
545
+ $arr[] = $this->buildJsParam("lightbox_slider_image_border_width", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
546
+ $arr[] = $this->buildJsParam("lightbox_slider_image_border_color");
547
+ $arr[] = $this->buildJsParam("lightbox_slider_image_border_radius", self::VALIDATE_NUMERIC, self::TYPE_NUMBER);
548
+ $arr[] = $this->buildJsParam("lightbox_slider_image_shadow", null, self::TYPE_BOOLEAN);
549
+
550
+
551
+ $arr = $this->buildThemeRelatedJSParams($arr);
552
+
553
+
554
+
555
+ return($arr);
556
+ }
557
+
558
+
559
+ /**
560
+ * get original params
561
+ */
562
+ private function getOriginalParams($data){
563
+
564
+ $arrParams = array();
565
+
566
+ foreach($data as $key => $value){
567
+
568
+ if(array_key_exists($key, $this->arrJsParamsAssoc) == false)
569
+ continue;
570
+
571
+ $arrParams[$key] = $value;
572
+ }
573
+
574
+ return($arrParams);
575
+ }
576
+
577
+
578
+ /**
579
+ * modify the params
580
+ */
581
+ private function modifyParams(){
582
+
583
+ $galleryTheme = UniteFunctionsUC::getVal($this->arrParams, "gallery_theme");
584
+
585
+ switch($galleryTheme){
586
+ case "tiles_columns":
587
+ $this->arrParams["gallery_theme"] = "tiles";
588
+ $this->arrParams["tiles_type"] = "columns";
589
+ break;
590
+ case "tiles_justified":
591
+ $this->arrParams["gallery_theme"] = "tiles";
592
+ $this->arrParams["tiles_type"] = "justified";
593
+ break;
594
+ }
595
+
596
+ }
597
+
598
+
599
+ /**
600
+ * set params by original params, and that not default
601
+ */
602
+ private function setParams($data, $addon){
603
+
604
+ //set the gallery theme
605
+
606
+ $this->galleryType = UniteFunctionsUC::getVal($data, "gallery_theme");
607
+
608
+ $this->validateGalleryType($this->galleryType);
609
+
610
+ $this->buildJSOptions();
611
+
612
+ $arrDefaultValues = $addon->getParamsDefaultValuesAssoc();
613
+
614
+ $arrMustKeys = $this->getArrMustFields();
615
+
616
+ $arrOriginalParams = $this->getOriginalParams($data);
617
+
618
+ $this->arrParams = UniteFunctionsUC::getDiffArrItems($arrOriginalParams, $arrDefaultValues, $arrMustKeys);
619
+
620
+ $this->modifyParams();
621
+
622
+ }
623
+
624
+ /**
625
+ * get the js output of the params
626
+ */
627
+ private function getJSOutput(){
628
+
629
+ if(empty($this->arrParams))
630
+ return("");
631
+
632
+
633
+ $jsOutput = "";
634
+ $counter = 0;
635
+ $tabs = " ";
636
+
637
+ foreach($this->arrJsParams as $arrParam){
638
+
639
+ $name = $arrParam["name"];
640
+ $validate = $arrParam["validate"];
641
+ $type = $arrParam["type"];
642
+ $replaceName = $arrParam["replace"];
643
+
644
+ if(array_key_exists($name, $this->skipJsOptions) == true)
645
+ continue;
646
+
647
+ $isExists = $this->isParamExists($name);
648
+
649
+ if($isExists == false)
650
+ continue;
651
+
652
+ $value = $this->getParam($name, $validate);
653
+
654
+ $putInBrackets = false;
655
+ switch($type){
656
+ case self::TYPE_NUMBER:
657
+ case self::TYPE_BOOLEAN:
658
+ case self::TYPE_OBJECT:
659
+ break;
660
+ case self::TYPE_SIZE:
661
+ if(strpos($value, "%") !== 0)
662
+ $putInBrackets = true;
663
+ break;
664
+ default: //string
665
+ $putInBrackets = true;
666
+ break;
667
+ }
668
+
669
+ if($putInBrackets == true){
670
+ $value = str_replace('"','\\"', $value);
671
+ $value = '"'.$value.'"';
672
+ }
673
+
674
+ if($counter > 0)
675
+ $jsOutput .= ",\n".$tabs;
676
+
677
+ if(!empty($replaceName))
678
+ $name = $replaceName;
679
+
680
+ $jsOutput .= "{$name}:{$value}";
681
+
682
+ $counter++;
683
+ }
684
+
685
+ $jsOutput .= "\n";
686
+
687
+
688
+ return($jsOutput);
689
+ }
690
 
691
 
692
  /**
693
  * get gallery js settings from data
694
  */
695
+ public function getUniteGalleryJsSettings($data, UniteCreatorAddon $addon){
696
+
697
+ $this->setParams($data, $addon);
698
 
699
+ $jsOutput = $this->getJSOutput();
 
 
700
 
701
+ return($jsOutput);
702
  }
703
 
704
  }
includes.php CHANGED
@@ -12,7 +12,7 @@ if(!defined('UNLIMITED_ELEMENTS_INC'))
12
  defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
13
 
14
  if(!defined("UNLIMITED_ELEMENTS_VERSION"))
15
- define("UNLIMITED_ELEMENTS_VERSION", "1.4.88");
16
 
17
  $currentFile = __FILE__;
18
  $currentFolder = dirname($currentFile);
12
  defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
13
 
14
  if(!defined("UNLIMITED_ELEMENTS_VERSION"))
15
+ define("UNLIMITED_ELEMENTS_VERSION", "1.4.96");
16
 
17
  $currentFile = __FILE__;
18
  $currentFolder = dirname($currentFile);
js/unitecreator_assets.js CHANGED
@@ -430,8 +430,6 @@ function UCAssetsManager(){
430
 
431
  }
432
 
433
-
434
-
435
  /**
436
  * open upload dialog, may occur from different managers
437
  */
430
 
431
  }
432
 
 
 
433
  /**
434
  * open upload dialog, may occur from different managers
435
  */
js/unitecreator_includes.js CHANGED
@@ -580,35 +580,43 @@ function UniteCreatorIncludes(){
580
  * fill values select
581
  */
582
  function dialogSettings_fillValuesSelect(objParam, selectedValue){
 
 
583
 
584
- var selectValues = jQuery("#uc_dialog_include_values");
585
-
586
- selectValues.html("");
587
 
588
  var arrValues = [];
589
-
590
  switch(objParam.type){
 
591
  case "uc_radioboolean":
592
- g_ucAdmin.addOptionToSelect(selectValues, objParam.true_value, objParam.true_value);
593
- g_ucAdmin.addOptionToSelect(selectValues, objParam.false_value, objParam.false_value);
594
 
595
  arrValues.push(objParam.true_value);
596
  arrValues.push(objParam.false_value);
597
 
598
  break;
599
  case "uc_dropdown":
 
600
  jQuery.each(objParam.options, function(optionName, optionValue){
601
- g_ucAdmin.addOptionToSelect(selectValues, optionValue, optionName);
602
  arrValues.push(optionValue);
603
  });
 
604
  break;
605
  }
606
 
607
 
608
  if(selectedValue){
609
- var isFound = (jQuery.inArray(selectedValue, arrValues) != -1)
 
 
 
 
 
610
  if(isFound == true)
611
- selectValues.val(selectedValue);
612
  }
613
 
614
  }
@@ -666,9 +674,11 @@ function UniteCreatorIncludes(){
666
  var buttonOpts = {};
667
 
668
  buttonOpts[g_uctext.update] = function(){
 
669
  var paramName = jQuery("#uc_dialog_include_attr").val();
670
  var paramValue = jQuery("#uc_dialog_include_values").val();
671
 
 
672
  updateInputCondition(objRow, paramName, paramValue);
673
 
674
  var rowParams = {};
@@ -750,6 +760,7 @@ function UniteCreatorIncludes(){
750
  throw new Error("param: "+paramName+" not found");
751
 
752
  var objParam = objParams[paramName];
 
753
  dialogSettings_fillValuesSelect(objParam, selectedValue);
754
 
755
  }
580
  * fill values select
581
  */
582
  function dialogSettings_fillValuesSelect(objParam, selectedValue){
583
+
584
+ var objSelectValues = jQuery("#uc_dialog_include_values");
585
 
586
+ objSelectValues.html("");
 
 
587
 
588
  var arrValues = [];
589
+
590
  switch(objParam.type){
591
+
592
  case "uc_radioboolean":
593
+ g_ucAdmin.addOptionToSelect(objSelectValues, objParam.true_value, objParam.true_value);
594
+ g_ucAdmin.addOptionToSelect(objSelectValues, objParam.false_value, objParam.false_value);
595
 
596
  arrValues.push(objParam.true_value);
597
  arrValues.push(objParam.false_value);
598
 
599
  break;
600
  case "uc_dropdown":
601
+
602
  jQuery.each(objParam.options, function(optionName, optionValue){
603
+ g_ucAdmin.addOptionToSelect(objSelectValues, optionValue, optionName);
604
  arrValues.push(optionValue);
605
  });
606
+
607
  break;
608
  }
609
 
610
 
611
  if(selectedValue){
612
+
613
+ if(jQuery.isArray(selectedValue))
614
+ var isFound = true;
615
+ else
616
+ var isFound = (jQuery.inArray(selectedValue, arrValues) != -1)
617
+
618
  if(isFound == true)
619
+ objSelectValues.val(selectedValue);
620
  }
621
 
622
  }
674
  var buttonOpts = {};
675
 
676
  buttonOpts[g_uctext.update] = function(){
677
+
678
  var paramName = jQuery("#uc_dialog_include_attr").val();
679
  var paramValue = jQuery("#uc_dialog_include_values").val();
680
 
681
+
682
  updateInputCondition(objRow, paramName, paramValue);
683
 
684
  var rowParams = {};
760
  throw new Error("param: "+paramName+" not found");
761
 
762
  var objParam = objParams[paramName];
763
+
764
  dialogSettings_fillValuesSelect(objParam, selectedValue);
765
 
766
  }
js/unitecreator_params_dialog.js CHANGED
@@ -337,6 +337,7 @@ function UniteCreatorParamsDialog(){
337
  objInput.trigger("change");
338
  break;
339
  case "checkbox":
 
340
  value = g_ucAdmin.strToBool(value);
341
  objInput.prop("checked", value);
342
  objInput.trigger("change");
@@ -504,6 +505,7 @@ function UniteCreatorParamsDialog(){
504
  else{
505
  g_objWrapper.data("rowindex", rowIndex);
506
  g_objData = objData;
 
507
  fillParamsDialog(objData);
508
  }
509
 
@@ -1409,6 +1411,7 @@ function UniteCreatorParamsDialog(){
1409
  return(false);
1410
  }
1411
 
 
1412
  objRow.removeClass("uc-no-attribute-selected");
1413
 
1414
  //show condition 2
@@ -1440,23 +1443,40 @@ function UniteCreatorParamsDialog(){
1440
 
1441
  if(isInitValues === true)
1442
  var currentValue = g_ucAdmin.getVal(g_objData, selectName);
1443
-
1444
  var isExists = false;
1445
-
1446
  jQuery.each(options,function(text, value){
1447
 
1448
  if(currentValue === null)
1449
  currentValue = value;
1450
 
1451
- if(currentValue === value)
1452
- isExists = true;
 
 
 
 
 
 
1453
 
1454
  g_ucAdmin.addOptionToSelect(objSelectValues, value, text);
1455
  });
1456
-
1457
- if(isExists == true)
 
 
 
 
 
 
 
 
1458
  objSelectValues.val(currentValue);
1459
-
 
 
 
1460
  }
1461
 
1462
 
@@ -1537,7 +1557,7 @@ function UniteCreatorParamsDialog(){
1537
 
1538
  var arrParams = g_objParent.getControlParams(g_currentOpenedType);
1539
  var hasParams = (jQuery.isEmptyObject(arrParams) == false);
1540
-
1541
  //show empty mode
1542
  if(hasParams == false){
1543
  objSelects.html("");
@@ -1624,7 +1644,21 @@ function UniteCreatorParamsDialog(){
1624
  /**
1625
  * handle sections conditions
1626
  */
1627
- this.handleSectionConditions = function(){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1628
 
1629
  triggerEvent(events.OPEN);
1630
 
337
  objInput.trigger("change");
338
  break;
339
  case "checkbox":
340
+
341
  value = g_ucAdmin.strToBool(value);
342
  objInput.prop("checked", value);
343
  objInput.trigger("change");
505
  else{
506
  g_objWrapper.data("rowindex", rowIndex);
507
  g_objData = objData;
508
+
509
  fillParamsDialog(objData);
510
  }
511
 
1411
  return(false);
1412
  }
1413
 
1414
+
1415
  objRow.removeClass("uc-no-attribute-selected");
1416
 
1417
  //show condition 2
1443
 
1444
  if(isInitValues === true)
1445
  var currentValue = g_ucAdmin.getVal(g_objData, selectName);
1446
+
1447
  var isExists = false;
1448
+
1449
  jQuery.each(options,function(text, value){
1450
 
1451
  if(currentValue === null)
1452
  currentValue = value;
1453
 
1454
+ if(jQuery.isArray(currentValue) == true){
1455
+
1456
+ if(currentValue.indexOf(value) !== -1)
1457
+ isExists = true;
1458
+ }else{
1459
+ if(currentValue === value)
1460
+ isExists = true;
1461
+ }
1462
 
1463
  g_ucAdmin.addOptionToSelect(objSelectValues, value, text);
1464
  });
1465
+
1466
+ //set current value, fit to multiple
1467
+
1468
+ if(isExists == true){
1469
+
1470
+ var type = typeof currentValue;
1471
+
1472
+ if(jQuery.isArray(currentValue) == false)
1473
+ currentValue = [currentValue];
1474
+
1475
  objSelectValues.val(currentValue);
1476
+
1477
+ }
1478
+
1479
+
1480
  }
1481
 
1482
 
1557
 
1558
  var arrParams = g_objParent.getControlParams(g_currentOpenedType);
1559
  var hasParams = (jQuery.isEmptyObject(arrParams) == false);
1560
+
1561
  //show empty mode
1562
  if(hasParams == false){
1563
  objSelects.html("");
1644
  /**
1645
  * handle sections conditions
1646
  */
1647
+ this.handleSectionConditions = function(objData){
1648
+
1649
+ g_objData = objData;
1650
+
1651
+ //on / off enable conditions checkbox
1652
+
1653
+ var objCheck = jQuery("#uc_dialog_left_condition_section");
1654
+
1655
+ var enableCondition = g_ucAdmin.getVal(objData,"enable_condition");
1656
+
1657
+ enableCondition = g_ucAdmin.strToBool(enableCondition);
1658
+
1659
+ objCheck.prop("checked", enableCondition);
1660
+ objCheck.trigger("change");
1661
+
1662
 
1663
  triggerEvent(events.OPEN);
1664
 
js/unitecreator_params_editor.js CHANGED
@@ -586,16 +586,25 @@ function UniteCreatorParamsEditor(){
586
 
587
  title = jQuery.trim(title);
588
 
 
 
589
  var data = {};
590
- data["id"] = objRow.data("id");
 
 
 
 
 
 
591
  data["title"] = title;
592
 
593
  if(includeTab === true)
594
  data["tab"] = getCatTab(objRow);
595
-
596
  return(data);
597
  }
598
 
 
599
  /**
600
  * get category tab
601
  */
@@ -736,14 +745,21 @@ function UniteCreatorParamsEditor(){
736
  /**
737
  * add tab section to some tab
738
  */
739
- function addCatToTab(tab, catTitle, catID){
740
 
741
- //check and rename if exists
 
 
 
 
742
 
 
 
743
  var objCat = getCatByID(catID);
744
 
745
  if(objCat){
746
  renameCategory(objCat, catTitle, true);
 
747
 
748
  return(false);
749
  }
@@ -775,11 +791,13 @@ function UniteCreatorParamsEditor(){
775
  html += "</li>";
776
 
777
  var objCat = jQuery(html);
778
-
779
  var objList = jQuery("#uc_attr_list_sections_"+tab);
780
  g_ucAdmin.validateNotEmpty(objList, "list sections");
781
-
782
  objList.append(objCat);
 
 
783
 
784
  return(catID);
785
  }
@@ -1070,7 +1088,7 @@ function UniteCreatorParamsEditor(){
1070
  * init categories from data
1071
  */
1072
  function initCatsFromData(arrParamsCats){
1073
-
1074
  if(!arrParamsCats)
1075
  return(false);
1076
 
@@ -1083,26 +1101,14 @@ function UniteCreatorParamsEditor(){
1083
  var title = g_ucAdmin.getVal(objCat, "title");
1084
  var id = g_ucAdmin.getVal(objCat, "id");
1085
 
1086
- addCatToTab(tab, title, id);
1087
 
1088
  });
1089
 
1090
  }
1091
 
1092
- /**
1093
- * update category extra data
1094
- */
1095
- function updateCatData(catID, catData){
1096
-
1097
- var objCat = getCatByID(catID);
1098
-
1099
- if(!objCat)
1100
- return(false);
1101
-
1102
- objCat.data("catdata", catData);
1103
-
1104
- }
1105
-
1106
  function ______________COPY_CATEGORY______________(){}
1107
 
1108
 
@@ -1198,7 +1204,7 @@ function UniteCreatorParamsEditor(){
1198
 
1199
  var title = g_ucAdmin.getVal(objData, "title");
1200
 
1201
- var catID = addCatToTab(tab, title);
1202
 
1203
  // add attributes
1204
 
@@ -1341,10 +1347,9 @@ function UniteCreatorParamsEditor(){
1341
 
1342
  objButton.html(buttonText);
1343
 
1344
- objInput.focus();
1345
 
1346
- //handle conditions
1347
- g_objParamsDialogSpecial.handleSectionConditions();
1348
 
1349
  }, dialogOptions);
1350
 
@@ -1366,7 +1371,7 @@ function UniteCreatorParamsEditor(){
1366
  /**
1367
  * get dialog cat extra data (conditions values);
1368
  */
1369
- function getDialogCatData(objDialog){
1370
 
1371
  var objData = {};
1372
 
@@ -1405,6 +1410,7 @@ function UniteCreatorParamsEditor(){
1405
  return(objData);
1406
  }
1407
 
 
1408
  /**
1409
  * add the section
1410
  */
@@ -1422,9 +1428,7 @@ function UniteCreatorParamsEditor(){
1422
 
1423
  catTitle = jQuery.trim(catTitle);
1424
 
1425
- var catData = getDialogCatData(objDialog);
1426
-
1427
- trace(catData);
1428
 
1429
  if(!catTitle){
1430
  var textError = objError.data("error_empty");
@@ -1440,23 +1444,50 @@ function UniteCreatorParamsEditor(){
1440
  if(isEdit === true){
1441
 
1442
  var catID = objDialog.data("catid");
 
1443
  renameCategory(catID, catTitle);
1444
 
1445
- updateCatData(catID, catData);
 
1446
 
1447
  }else{ //add
1448
 
1449
  var tab = objDialog.data("tab");
1450
- var catID = addCatToTab(tab, catTitle);
1451
-
1452
- updateCatData(catID, catData);
1453
-
1454
  }
1455
-
1456
 
1457
  objDialog.dialog("close");
1458
  }
1459
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1460
 
1461
 
1462
  function ______________ACTIONS______________(){}
586
 
587
  title = jQuery.trim(title);
588
 
589
+ var catID = objRow.data("id");
590
+
591
  var data = {};
592
+
593
+ var conditionsData = getConditionsCatData(catID);
594
+
595
+ if(conditionsData && jQuery.isEmptyObject(conditionsData) == false && typeof conditionsData == "object")
596
+ jQuery.extend(data, conditionsData);
597
+
598
+ data["id"] = catID;
599
  data["title"] = title;
600
 
601
  if(includeTab === true)
602
  data["tab"] = getCatTab(objRow);
603
+
604
  return(data);
605
  }
606
 
607
+
608
  /**
609
  * get category tab
610
  */
745
  /**
746
  * add tab section to some tab
747
  */
748
+ function addCatToTab(tab, catTitle, catID, objData){
749
 
750
+ var data = jQuery.extend({}, objData);
751
+
752
+ delete data.id;
753
+ delete data.tab;
754
+ delete data.title;
755
 
756
+ //check and rename if exists
757
+
758
  var objCat = getCatByID(catID);
759
 
760
  if(objCat){
761
  renameCategory(objCat, catTitle, true);
762
+ updateCatConditionsData(catID, data);
763
 
764
  return(false);
765
  }
791
  html += "</li>";
792
 
793
  var objCat = jQuery(html);
794
+
795
  var objList = jQuery("#uc_attr_list_sections_"+tab);
796
  g_ucAdmin.validateNotEmpty(objList, "list sections");
797
+
798
  objList.append(objCat);
799
+
800
+ updateCatConditionsData(catID, data);
801
 
802
  return(catID);
803
  }
1088
  * init categories from data
1089
  */
1090
  function initCatsFromData(arrParamsCats){
1091
+
1092
  if(!arrParamsCats)
1093
  return(false);
1094
 
1101
  var title = g_ucAdmin.getVal(objCat, "title");
1102
  var id = g_ucAdmin.getVal(objCat, "id");
1103
 
1104
+ addCatToTab(tab, title, id, objCat);
1105
 
1106
  });
1107
 
1108
  }
1109
 
1110
+
1111
+
 
 
 
 
 
 
 
 
 
 
 
 
1112
  function ______________COPY_CATEGORY______________(){}
1113
 
1114
 
1204
 
1205
  var title = g_ucAdmin.getVal(objData, "title");
1206
 
1207
+ var catID = addCatToTab(tab, title, null, objData);
1208
 
1209
  // add attributes
1210
 
1347
 
1348
  objButton.html(buttonText);
1349
 
1350
+ g_objParamsDialogSpecial.handleSectionConditions(catData);
1351
 
1352
+ objInput.focus();
 
1353
 
1354
  }, dialogOptions);
1355
 
1371
  /**
1372
  * get dialog cat extra data (conditions values);
1373
  */
1374
+ function getDialogConditionsData(objDialog){
1375
 
1376
  var objData = {};
1377
 
1410
  return(objData);
1411
  }
1412
 
1413
+
1414
  /**
1415
  * add the section
1416
  */
1428
 
1429
  catTitle = jQuery.trim(catTitle);
1430
 
1431
+ var conditionsData = getDialogConditionsData(objDialog);
 
 
1432
 
1433
  if(!catTitle){
1434
  var textError = objError.data("error_empty");
1444
  if(isEdit === true){
1445
 
1446
  var catID = objDialog.data("catid");
1447
+
1448
  renameCategory(catID, catTitle);
1449
 
1450
+ updateCatConditionsData(catID, conditionsData);
1451
+
1452
 
1453
  }else{ //add
1454
 
1455
  var tab = objDialog.data("tab");
1456
+ var catID = addCatToTab(tab, catTitle, null, conditionsData);
1457
+
 
 
1458
  }
 
1459
 
1460
  objDialog.dialog("close");
1461
  }
1462
 
1463
+ /**
1464
+ * update category extra data
1465
+ */
1466
+ function updateCatConditionsData(catID, catData){
1467
+
1468
+ var objCat = getCatByID(catID);
1469
+
1470
+ if(!objCat)
1471
+ return(false);
1472
+
1473
+ objCat.data("catdata", catData);
1474
+
1475
+ }
1476
+
1477
+ /**
1478
+ * get category data
1479
+ */
1480
+ function getConditionsCatData(catID){
1481
+
1482
+ var objCat = getCatByID(catID);
1483
+
1484
+ var data = objCat.data("catdata");
1485
+
1486
+ if(!data)
1487
+ var data = {};
1488
+
1489
+ return(data);
1490
+ }
1491
 
1492
 
1493
  function ______________ACTIONS______________(){}
provider/admin_notices.class.php CHANGED
@@ -28,7 +28,8 @@ class UniteCreatorAdminNotices{
28
  //don't let to add more then limited notices
29
  if(count(self::$arrNotices) >= self::NOTICES_LIMIT)
30
  return(false);
31
-
 
32
  $type = UniteFunctionsUC::getVal($params, "type");
33
 
34
  if(empty($text) && $type != self::TYPE_BANNER)
@@ -48,7 +49,7 @@ class UniteCreatorAdminNotices{
48
 
49
  $arrNotice = array_merge($arrNotice, $params);
50
  }
51
-
52
  if(isset(self::$arrNotices[$id]))
53
  return(false);
54
 
@@ -66,13 +67,26 @@ class UniteCreatorAdminNotices{
66
 
67
  $type = UniteFunctionsUC::getVal($params, "type");
68
 
 
 
 
 
 
 
 
 
69
  $class = "notice uc-admin-notice notice-info uc-banner-type-banner";
70
 
71
  if($type == self::TYPE_ADVANCED)
72
  $class .= " uc-notice-advanced";
73
-
74
- if($type == self::TYPE_BANNER)
75
  $class = "notice uc-admin-notice";
 
 
 
 
 
76
 
77
  $classDissmissable = "is-dismissible";
78
  $classDissmissable = "";
@@ -195,6 +209,12 @@ class UniteCreatorAdminNotices{
195
  font-size:16px;
196
  }
197
 
 
 
 
 
 
 
198
  .uc-admin-notice .uc-notice-advanced-wrapper span{
199
  display:table-cell;
200
  vertical-align:middle;
@@ -239,7 +259,7 @@ class UniteCreatorAdminNotices{
239
  .uc-admin-notice .uc-notice-dismiss:hover::before{
240
  color: #c00;
241
  }
242
-
243
  .uc-notice-banner-link{
244
  display:block;
245
  }
28
  //don't let to add more then limited notices
29
  if(count(self::$arrNotices) >= self::NOTICES_LIMIT)
30
  return(false);
31
+
32
+
33
  $type = UniteFunctionsUC::getVal($params, "type");
34
 
35
  if(empty($text) && $type != self::TYPE_BANNER)
49
 
50
  $arrNotice = array_merge($arrNotice, $params);
51
  }
52
+
53
  if(isset(self::$arrNotices[$id]))
54
  return(false);
55
 
67
 
68
  $type = UniteFunctionsUC::getVal($params, "type");
69
 
70
+ $isNoWrap = UniteFunctionsUC::getVal($params, "no-notice-wrap");
71
+ $isNoWrap = UniteFunctionsUC::strToBool($isNoWrap);
72
+
73
+ $classWrap = "notice ";
74
+
75
+ if($isNoWrap == true)
76
+ $classWrap = "";
77
+
78
  $class = "notice uc-admin-notice notice-info uc-banner-type-banner";
79
 
80
  if($type == self::TYPE_ADVANCED)
81
  $class .= " uc-notice-advanced";
82
+
83
+ if($type == self::TYPE_BANNER){
84
  $class = "notice uc-admin-notice";
85
+
86
+ if($isNoWrap == true)
87
+ $class .= " uc-admin-notice--nowrap";
88
+
89
+ }
90
 
91
  $classDissmissable = "is-dismissible";
92
  $classDissmissable = "";
209
  font-size:16px;
210
  }
211
 
212
+ .uc-admin-notice--nowrap{
213
+ padding:0px !important;
214
+ border:none !important;
215
+ background-color:transparent !important;
216
+ }
217
+
218
  .uc-admin-notice .uc-notice-advanced-wrapper span{
219
  display:table-cell;
220
  vertical-align:middle;
259
  .uc-admin-notice .uc-notice-dismiss:hover::before{
260
  color: #c00;
261
  }
262
+
263
  .uc-notice-banner-link{
264
  display:block;
265
  }
provider/core/plugins/unlimited_elements/elementor/elementor_background_widget.class.php CHANGED
@@ -107,7 +107,7 @@ class UniteCreatorElementorBackgroundWidget extends UniteCreatorElementorWidget
107
  $params = $this->modifyBGWidgetParams($params);
108
 
109
  $params = $this->addDynamicAttributes($params);
110
-
111
  foreach($params as $param){
112
 
113
  $type = UniteFunctionsUC::getVal($param, "type");
107
  $params = $this->modifyBGWidgetParams($params);
108
 
109
  $params = $this->addDynamicAttributes($params);
110
+
111
  foreach($params as $param){
112
 
113
  $type = UniteFunctionsUC::getVal($param, "type");
provider/core/plugins/unlimited_elements/elementor/elementor_widget.class.php CHANGED
@@ -635,14 +635,14 @@ class UniteCreatorElementorWidget extends Widget_Base {
635
  * get elementor condition from the param
636
  */
637
  private function getControlArrayUC_getCondition($param, $elementorCondition = null){
638
-
639
  $conditionAttribute = UniteFunctionsUC::getVal($param, "condition_attribute");
640
  $conditionOperator = UniteFunctionsUC::getVal($param, "condition_operator");
641
  $conditionValue = UniteFunctionsUC::getVal($param, "condition_value");
642
 
643
  if(empty($conditionAttribute))
644
  return($elementorCondition);
645
-
646
  $arrCondition = array();
647
 
648
  if(!empty($elementorCondition) && is_array($elementorCondition))
@@ -670,7 +670,6 @@ class UniteCreatorElementorWidget extends Widget_Base {
670
 
671
  $arrCondition[$conditionAttribute2] = $conditionValue2;
672
 
673
-
674
  return($arrCondition);
675
  }
676
 
@@ -717,6 +716,7 @@ class UniteCreatorElementorWidget extends Widget_Base {
717
  }
718
 
719
  switch($type){
 
720
  case UniteCreatorDialogParam::PARAM_TEXTFIELD:
721
  $controlType = Controls_Manager::TEXT;
722
  if($disabled === true){ //show disabled input rawadd_dynamic html
@@ -872,7 +872,9 @@ class UniteCreatorElementorWidget extends Widget_Base {
872
 
873
  default:
874
 
875
- dmp("param not found");
 
 
876
  dmp($param);
877
  UniteFunctionsUC::showTrace();
878
  UniteFunctionsUC::throwError("Wrong param type: ".$type);
@@ -2145,7 +2147,7 @@ class UniteCreatorElementorWidget extends Widget_Base {
2145
 
2146
  $hasListing = false;
2147
  $listingParam = null;
2148
-
2149
  //foreach the categories
2150
  foreach($arrCatsAndParams as $catID => $arrCat){
2151
 
@@ -2162,6 +2164,18 @@ class UniteCreatorElementorWidget extends Widget_Base {
2162
  if($catTab == "style")
2163
  $arrSectionOptions["tab"] = "style";
2164
 
 
 
 
 
 
 
 
 
 
 
 
 
2165
  $this->start_controls_section($catID, $arrSectionOptions);
2166
 
2167
  if($isGeneralSection == true && $isItemsEnabled == true && $itemsType == "image")
635
  * get elementor condition from the param
636
  */
637
  private function getControlArrayUC_getCondition($param, $elementorCondition = null){
638
+
639
  $conditionAttribute = UniteFunctionsUC::getVal($param, "condition_attribute");
640
  $conditionOperator = UniteFunctionsUC::getVal($param, "condition_operator");
641
  $conditionValue = UniteFunctionsUC::getVal($param, "condition_value");
642
 
643
  if(empty($conditionAttribute))
644
  return($elementorCondition);
645
+
646
  $arrCondition = array();
647
 
648
  if(!empty($elementorCondition) && is_array($elementorCondition))
670
 
671
  $arrCondition[$conditionAttribute2] = $conditionValue2;
672
 
 
673
  return($arrCondition);
674
  }
675
 
716
  }
717
 
718
  switch($type){
719
+ case "uc_post":
720
  case UniteCreatorDialogParam::PARAM_TEXTFIELD:
721
  $controlType = Controls_Manager::TEXT;
722
  if($disabled === true){ //show disabled input rawadd_dynamic html
872
 
873
  default:
874
 
875
+ $addonTitle = $this->objAddon->getTitle();
876
+
877
+ dmp("param not found in widget: $addonTitle");
878
  dmp($param);
879
  UniteFunctionsUC::showTrace();
880
  UniteFunctionsUC::throwError("Wrong param type: ".$type);
2147
 
2148
  $hasListing = false;
2149
  $listingParam = null;
2150
+
2151
  //foreach the categories
2152
  foreach($arrCatsAndParams as $catID => $arrCat){
2153
 
2164
  if($catTab == "style")
2165
  $arrSectionOptions["tab"] = "style";
2166
 
2167
+ //section conditions
2168
+ $enableCondition = UniteFunctionsUC::getVal($arrCat, "enable_condition");
2169
+ $enableCondition = UniteFunctionsUC::strToBool($enableCondition);
2170
+
2171
+ if($enableCondition == true){
2172
+
2173
+ $elementorCondition = $this->getControlArrayUC_getCondition($arrCat);
2174
+
2175
+ if(!empty($elementorCondition))
2176
+ $arrSectionOptions["condition"] = $elementorCondition;
2177
+ }
2178
+
2179
  $this->start_controls_section($catID, $arrSectionOptions);
2180
 
2181
  if($isGeneralSection == true && $isItemsEnabled == true && $itemsType == "image")
provider/core/plugins/unlimited_elements/elementor/pagination.class.php CHANGED
@@ -539,10 +539,9 @@ class UniteCreatorElementorPagination{
539
 
540
  $isArchivePage = UniteFunctionsWPUC::isArchiveLocation();
541
 
542
- if($isArchivePage == true && !empty(GlobalsProviderUC::$lastPostQuery_type) && GlobalsProviderUC::$lastPostQuery_type != GlobalsProviderUC::QUERY_TYPE_CURRENT)
543
  $isArchivePage = false;
544
 
545
-
546
  if($isArchivePage == true){
547
 
548
  $options = $this->getArchivePageOptions($options);
539
 
540
  $isArchivePage = UniteFunctionsWPUC::isArchiveLocation();
541
 
542
+ if($isArchivePage == true && !empty(GlobalsProviderUC::$lastPostQuery_paginationType) && GlobalsProviderUC::$lastPostQuery_paginationType != GlobalsProviderUC::QUERY_TYPE_CURRENT)
543
  $isArchivePage = false;
544
 
 
545
  if($isArchivePage == true){
546
 
547
  $options = $this->getArchivePageOptions($options);
provider/core/plugins/unlimited_elements/globals.class.php CHANGED
@@ -9,21 +9,22 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
9
 
10
  class GlobalsUnlimitedElements{
11
 
12
- public static $enableInsideNotification = false;
13
- public static $insideNotificationText = "";
14
- public static $insideNotificationUrl = "https://unlimited-elements.com/sale/";
15
 
16
  public static $showAdminNotice = false;
17
  public static $arrAdminNotice = array(
18
- "id"=>"birthday2_sale3",
19
  //"text"=>"Birthday Sale IS Here!",
20
- "banner"=>"banner-bd-sale.jpg",
21
  //"type"=>"advanced",
22
  "type"=>"banner", //advanced,banner
23
  //"button_text"=>"Show Me More",
24
- "button_link"=>"https://unlimited-elements.com/sale/",
25
  "expire"=>"",
26
- "free_only"=>true
 
27
  );
28
 
29
  const PLUGIN_NAME = "unlimitedelements";
9
 
10
  class GlobalsUnlimitedElements{
11
 
12
+ public static $enableInsideNotification = true;
13
+ public static $insideNotificationText = "Unlock Access To All PRO Widgets and Features. <a href='https://unlimited-elements.com/pricing/' target='_blank'>Upgrade Now</a> ";
14
+ public static $insideNotificationUrl = "https://unlimited-elements.com/blackfriday/";
15
 
16
  public static $showAdminNotice = false;
17
  public static $arrAdminNotice = array(
18
+ "id"=>"black_friday_sale",
19
  //"text"=>"Birthday Sale IS Here!",
20
+ "banner"=>"banner-black-friday-2021.jpg",
21
  //"type"=>"advanced",
22
  "type"=>"banner", //advanced,banner
23
  //"button_text"=>"Show Me More",
24
+ "button_link"=>"https://unlimited-elements.com/blackfriday/",
25
  "expire"=>"",
26
+ "free_only"=>true,
27
+ "no-notice-wrap"=>true
28
  );
29
 
30
  const PLUGIN_NAME = "unlimitedelements";
provider/core/plugins/unlimited_elements/helper_provider_core.class.php CHANGED
@@ -219,13 +219,16 @@ class HelperProviderCoreUC_EL{
219
  if(!empty(self::$arrCacheElementorTemplate))
220
  return(self::$arrCacheElementorTemplate);
221
 
222
-
223
- $arrOptions = array();
224
- $arrOptions["post_type"] = "elementor_library";
225
- $arrOptions["numberposts"] = 500;
226
- $arrOptions["state"] = "published";
227
-
228
- $arrPosts = get_posts($arrOptions);
 
 
 
229
 
230
  if(empty($arrPosts))
231
  return(array());
@@ -235,9 +238,9 @@ class HelperProviderCoreUC_EL{
235
 
236
  foreach($arrPosts as $post){
237
 
238
- $postID = $post->ID;
239
- $title = $post->post_title;
240
- $slug = $post->post_name;
241
 
242
  $templateType = get_post_meta($postID, "_elementor_template_type", true);
243
 
219
  if(!empty(self::$arrCacheElementorTemplate))
220
  return(self::$arrCacheElementorTemplate);
221
 
222
+ //our db avoid some filters like polylang
223
+ try{
224
+ $db = HelperUC::getDB();
225
+ $arrPosts = $db->fetch(UniteProviderFunctionsUC::$tablePosts,
226
+ array("post_type"=>"elementor_library",
227
+ "post_status"=>"publish"));
228
+
229
+ }catch(Exception $e){
230
+ $arrPosts = array();
231
+ }
232
 
233
  if(empty($arrPosts))
234
  return(array());
238
 
239
  foreach($arrPosts as $post){
240
 
241
+ $postID = UniteFunctionsUC::getVal($post, "ID");
242
+ $title = UniteFunctionsUC::getVal($post, "post_title");
243
+ $slug = UniteFunctionsUC::getVal($post, "post_name");
244
 
245
  $templateType = get_post_meta($postID, "_elementor_template_type", true);
246
 
provider/core/plugins/unlimited_elements/settings/general_settings_el.xml CHANGED
@@ -83,7 +83,16 @@
83
  hidden="true"
84
  description="">
85
  </field>
86
-
 
 
 
 
 
 
 
 
 
87
  <field type="bulk_control_end"/>
88
 
89
  </fieldset>
83
  hidden="true"
84
  description="">
85
  </field>
86
+
87
+ <field name="force_disable_font_awesome"
88
+ type="list"
89
+ default="enable"
90
+ label=" Force Disable Font Awesome"
91
+ description="Disable font awesome from loading from the plugin in all widgets. Sometimes good for optimization.">
92
+ <option value="enable" text="Load Normally"></option>
93
+ <option value="disable" text="Force Disable"></option>
94
+ </field>
95
+
96
  <field type="bulk_control_end"/>
97
 
98
  </fieldset>
provider/functions_wordpress.class.php CHANGED
@@ -1874,6 +1874,27 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
1874
  return($output);
1875
  }
1876
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1877
 
1878
  public static function a__________POST_ACTIONS_________(){}
1879
 
@@ -2033,72 +2054,6 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
2033
  $db->delete($tablePostMeta, "post_id=$postID");
2034
  }
2035
 
2036
- /**
2037
- * duplicate post
2038
- */
2039
- public static function duplicatePost($postID, $newTitle = null){
2040
-
2041
- $post = get_post($postID);
2042
- if(empty($post))
2043
- UniteFunctionsUC::throwError("Post now found");
2044
-
2045
- $current_user = wp_get_current_user();
2046
- $new_post_author = $current_user->ID;
2047
-
2048
- $postTitle = $post->post_title;
2049
- if(!empty($newTitle))
2050
- $postTitle = $newTitle;
2051
-
2052
- $args = array(
2053
- 'comment_status' => $post->comment_status,
2054
- 'ping_status' => $post->ping_status,
2055
- 'post_author' => $new_post_author,
2056
- 'post_content' => $post->post_content,
2057
- 'post_excerpt' => $post->post_excerpt,
2058
- 'post_name' => $post->post_name,
2059
- 'post_parent' => $post->post_parent,
2060
- 'post_password' => $post->post_password,
2061
- 'post_status' => $post->post_status,
2062
- 'post_title' => $postTitle,
2063
- 'post_type' => $post->post_type,
2064
- 'to_ping' => $post->to_ping,
2065
- 'menu_order' => $post->menu_order
2066
- );
2067
-
2068
-
2069
- $newPostID = wp_insert_post( $args );
2070
-
2071
- if(empty($newPostID))
2072
- UniteFunctionsUC::throwError("Can't duplicate post: $postID");
2073
-
2074
-
2075
- //set all taxanomies to the new post (category, tags)
2076
- $taxonomies = get_object_taxonomies($post->post_type);
2077
- foreach ($taxonomies as $taxonomy) {
2078
- $post_terms = wp_get_object_terms($postID, $taxonomy, array('fields' => 'slugs'));
2079
- wp_set_object_terms($newPostID, $post_terms, $taxonomy, false);
2080
- }
2081
-
2082
- //duplicate meta
2083
- global $wpdb;
2084
-
2085
- //duplicate all post meta just in two SQL queries
2086
- $post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$postID");
2087
- if (count($post_meta_infos)!=0) {
2088
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
2089
- foreach ($post_meta_infos as $meta_info) {
2090
- $meta_key = $meta_info->meta_key;
2091
- if( $meta_key == '_wp_old_slug' ) continue;
2092
- $meta_value = addslashes($meta_info->meta_value);
2093
- $sql_query_sel[]= "SELECT $newPostID, '$meta_key', '$meta_value'";
2094
- }
2095
- $sql_query.= implode(" UNION ALL ", $sql_query_sel);
2096
- $wpdb->query($sql_query);
2097
- }
2098
-
2099
-
2100
- return($newPostID);
2101
- }
2102
 
2103
  /**
2104
  * delete multiple posts
@@ -2271,7 +2226,12 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
2271
  if(empty($urlThumb))
2272
  $urlThumb = $post->guid;
2273
 
 
 
 
 
2274
  $item["thumb"] = $urlThumb;
 
2275
 
2276
  $item["title"] = $title;
2277
  $item["description"] = $post->post_content;
1874
  return($output);
1875
  }
1876
 
1877
+
1878
+ /**
1879
+ * get post content
1880
+ */
1881
+ public static function getPostContent($post){
1882
+
1883
+ if(empty($post))
1884
+ return("");
1885
+
1886
+ $postID = $post->post_id;
1887
+
1888
+ $isEditMode = HelperUC::isElementorEditMode();
1889
+ if($isEditMode == false)
1890
+ $content = get_the_content( null, false, $post);
1891
+ else
1892
+ $content = $post->post_content;
1893
+
1894
+ $content = apply_filters("widget_text_content", $content);
1895
+
1896
+ return($content);
1897
+ }
1898
 
1899
  public static function a__________POST_ACTIONS_________(){}
1900
 
2054
  $db->delete($tablePostMeta, "post_id=$postID");
2055
  }
2056
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2057
 
2058
  /**
2059
  * delete multiple posts
2226
  if(empty($urlThumb))
2227
  $urlThumb = $post->guid;
2228
 
2229
+ $urlThumbLarge = self::getUrlAttachmentImage($thumbID,self::THUMB_LARGE);
2230
+ if(empty($urlThumbLarge))
2231
+ $urlThumbLarge = $urlThumb;
2232
+
2233
  $item["thumb"] = $urlThumb;
2234
+ $item["thumb_large"] = $urlThumb;
2235
 
2236
  $item["title"] = $title;
2237
  $item["description"] = $post->post_content;
provider/provider_globals.class.php CHANGED
@@ -29,6 +29,8 @@ class GlobalsProviderUC{
29
  public static $lastPostQuery = null;
30
  public static $lastPostQuery_page = null;
31
  public static $lastPostQuery_type = null;
 
 
32
 
33
  const QUERY_TYPE_CURRENT = "current";
34
  const QUERY_TYPE_CUSTOM = "custom";
29
  public static $lastPostQuery = null;
30
  public static $lastPostQuery_page = null;
31
  public static $lastPostQuery_type = null;
32
+ public static $lastPostQuery_paginationType = null;
33
+
34
 
35
  const QUERY_TYPE_CURRENT = "current";
36
  const QUERY_TYPE_CUSTOM = "custom";
provider/provider_helper.class.php CHANGED
@@ -11,7 +11,7 @@ class HelperProviderUC{
11
 
12
  if(isset($unl_fs) == false)
13
  return(false);
14
-
15
  $isActivated = $unl_fs->is_paying();
16
 
17
  return($isActivated);
@@ -118,6 +118,26 @@ class HelperProviderUC{
118
 
119
  return($arrNames);
120
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
 
123
  /**
11
 
12
  if(isset($unl_fs) == false)
13
  return(false);
14
+
15
  $isActivated = $unl_fs->is_paying();
16
 
17
  return($isActivated);
118
 
119
  return($arrNames);
120
  }
121
+
122
+ /**
123
+ * get remote parent names
124
+ */
125
+ public static function getArrRemoteSyncNames(){
126
+
127
+ $arrNames = array();
128
+ $arrNames["group1"] = __("Sync Group 1", "unlimited-elements-for-elementor");
129
+ $arrNames["group2"] = __("Sync Group 2", "unlimited-elements-for-elementor");
130
+ $arrNames["group3"] = __("Sync Group 3", "unlimited-elements-for-elementor");
131
+ $arrNames["group4"] = __("Sync Group 4", "unlimited-elements-for-elementor");
132
+ $arrNames["group5"] = __("Sync Group 5", "unlimited-elements-for-elementor");
133
+ $arrNames["group6"] = __("Sync Group 6", "unlimited-elements-for-elementor");
134
+ $arrNames["group7"] = __("Sync Group 7", "unlimited-elements-for-elementor");
135
+ $arrNames["group8"] = __("Sync Group 8", "unlimited-elements-for-elementor");
136
+ $arrNames["group9"] = __("Sync Group 9", "unlimited-elements-for-elementor");
137
+ $arrNames["group10"] = __("Sync Group 10", "unlimited-elements-for-elementor");
138
+
139
+ return($arrNames);
140
+ }
141
 
142
 
143
  /**
provider/provider_layout.class.php CHANGED
@@ -318,22 +318,6 @@ class UniteCreatorLayout extends UniteCreatorLayoutWork{
318
  }
319
 
320
 
321
- /**
322
- * duplicate layout
323
- */
324
- public function duplicate(){
325
-
326
- $this->validateInited();
327
-
328
- $newTitle = $this->getDuplicateTitle();
329
- $postID = $this->id;
330
-
331
- $newPostID = UniteFunctionsWPUC::duplicatePost($postID, $newTitle);
332
-
333
- return($newPostID);
334
- }
335
-
336
-
337
  /**
338
  * delete layout
339
  */
318
  }
319
 
320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  /**
322
  * delete layout
323
  */
provider/provider_layouts.class.php CHANGED
@@ -31,23 +31,7 @@ class UniteCreatorLayouts extends UniteCreatorLayoutsWork{
31
  UniteFunctionsWPUC::deleteMultiplePosts($arrIDs);
32
  }
33
 
34
-
35
- /**
36
- * duplicate layout redirect to page if needed
37
- */
38
- public function duplicateLayoutFromData($data){
39
-
40
- $urlRedirect = parent::duplicateLayoutFromData($data);
41
 
42
- $redirectToWP = UniteFunctionsUC::getVal($data, "redirect_to_wp_page");
43
- $redirectToWP = UniteFunctionsUC::strToBool($redirectToWP);
44
-
45
- if($redirectToWP == true)
46
- $urlRedirect = UniteFunctionsWPUC::getUrlEditPost($this->lastDuplicatedID);
47
-
48
- return($urlRedirect);
49
- }
50
-
51
 
52
  /**
53
  * check if layout exists by title
31
  UniteFunctionsWPUC::deleteMultiplePosts($arrIDs);
32
  }
33
 
 
 
 
 
 
 
 
34
 
 
 
 
 
 
 
 
 
 
35
 
36
  /**
37
  * check if layout exists by title
provider/provider_operations.class.php CHANGED
@@ -85,7 +85,7 @@ class ProviderOperationsUC extends UCOperations{
85
 
86
  if(empty($arrIDs))
87
  return(null);
88
-
89
  $response = UniteFunctionsWPUC::getPostTitlesByIDs($arrIDs);
90
 
91
  if(empty($response))
85
 
86
  if(empty($arrIDs))
87
  return(null);
88
+
89
  $response = UniteFunctionsWPUC::getPostTitlesByIDs($arrIDs);
90
 
91
  if(empty($response))
provider/provider_params_processor.class.php CHANGED
@@ -469,6 +469,43 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
469
  return($taxonomy);
470
  }
471
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
472
 
473
  /**
474
  * get post category fields
@@ -493,15 +530,7 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
493
 
494
  $arrCatsOutput = $this->modifyArrTermsForOutput($arrTerms, $taxonomy);
495
 
496
- //get term data
497
- if(count($arrTerms) == 1){ //single
498
- $arrTermData = UniteFunctionsUC::getArrFirstValue($arrTerms);
499
- }else{ //multiple
500
-
501
- unset($arrTerms["uncategorized"]);
502
-
503
- $arrTermData = UniteFunctionsUC::getArrFirstValue($arrTerms);
504
- }
505
 
506
  $catID = UniteFunctionsUC::getVal($arrTermData, "term_id");
507
 
@@ -558,10 +587,7 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
558
  $arrData["alias"] = UniteFunctionsUC::getVal($arrPost, "post_name");
559
  $arrData["author_id"] = UniteFunctionsUC::getVal($arrPost, "post_author");
560
 
561
- $content = UniteFunctionsUC::getVal($arrPost, "post_content");
562
-
563
- //modify the content
564
- $content = apply_filters("the_content", $content);
565
 
566
  $arrData["content"] = $content;
567
 
@@ -576,8 +602,9 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
576
  }
577
 
578
  if(!empty($intro)){
579
- $intro = strip_tags($intro);
580
  $introFull = $intro;
 
581
  $intro = UniteFunctionsUC::truncateString($intro, 100);
582
  }
583
 
@@ -1381,10 +1408,17 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
1381
 
1382
  $metaKey = UniteFunctionsUC::getVal($value, "{$name}_includeby_metakey");
1383
  $metaCompare = UniteFunctionsUC::getVal($value, "{$name}_includeby_metacompare");
1384
- $metaValue = UniteFunctionsUC::getVal($value, "{$name}_includeby_metavalue");
1385
 
 
1386
  $metaValue = $this->modifyMetaValueForCompare($metaValue);
1387
 
 
 
 
 
 
 
 
1388
  if(!empty($metaKey)){
1389
 
1390
  $arrMetaQuery[] = array(
@@ -1392,6 +1426,31 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
1392
  'value' => $metaValue,
1393
  'compare'=>$metaCompare
1394
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1395
  }
1396
 
1397
  break;
@@ -1688,7 +1747,12 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
1688
  GlobalsProviderUC::$lastPostQuery = $query;
1689
  GlobalsProviderUC::$lastPostQuery_page = 1;
1690
  GlobalsProviderUC::$lastPostQuery_type = $type;
1691
-
 
 
 
 
 
1692
  $queryVars = $query->query;
1693
 
1694
  $perPage = UniteFunctionsUC::getVal($queryVars, "posts_per_page");
@@ -1714,7 +1778,6 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
1714
  */
1715
  private function getPostListData_currentPosts($value, $name, $data){
1716
 
1717
-
1718
  //add debug for further use
1719
  HelperUC::addDebug("Getting Current Posts");
1720
 
@@ -1727,7 +1790,7 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
1727
 
1728
  if($orderDir == "default")
1729
  $orderDir = null;
1730
-
1731
  global $wp_query;
1732
  $currentQueryVars = $wp_query->query_vars;
1733
 
@@ -1787,7 +1850,7 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
1787
 
1788
  //save last query
1789
  $this->saveLastQueryAndPage($query, GlobalsProviderUC::QUERY_TYPE_CURRENT);
1790
-
1791
  $arrPosts = $query->posts;
1792
 
1793
  if(empty($arrPosts))
@@ -1941,7 +2004,7 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
1941
 
1942
  $useCategory = UniteFunctionsUC::getVal($param, "use_category");
1943
  $useCategory = UniteFunctionsUC::strToBool($useCategory);
1944
-
1945
  $arrPostAdditions = HelperProviderUC::getPostDataAdditions($useCustomFields, $useCategory);
1946
 
1947
  HelperUC::addDebug("post additions", $arrPostAdditions);
@@ -2482,13 +2545,13 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
2482
 
2483
  $isDebug = UniteFunctionsUC::getVal($value, $name."_debug");
2484
  $isDebug = UniteFunctionsUC::strToBool($isDebug);
2485
-
2486
  $isSync = UniteFunctionsUC::getVal($value, $name."_sync");
2487
  $isSync = UniteFunctionsUC::strToBool($isSync);
2488
 
 
2489
 
2490
-
2491
- if($isEnable == false){
2492
 
2493
  $arrOutput["attributes"] = "";
2494
  $arrOutput["class"] = "";
@@ -2500,47 +2563,103 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
2500
 
2501
  HelperUC::addRemoteControlsScript();
2502
 
2503
- //get the name
2504
- $parentName = UniteFunctionsUC::getVal($value, $name."_name");
2505
-
2506
- if($parentName == "custom")
2507
- $parentName = UniteFunctionsUC::getVal($value, $name."_custom_name");
2508
 
2509
- if(empty($parentName))
2510
- $parentName = "auto";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2511
 
2512
- $parentName = UniteFunctionsUC::sanitizeAttr($parentName);
 
2513
 
2514
- //create attributes and classes
2515
 
2516
- $attributes = " data-remoteid='$parentName'";
 
2517
 
2518
- if($isDebug == true)
2519
- $attributes .= " data-debug='true'";
2520
 
2521
  if($isSync == true){
2522
 
2523
  //get the name
2524
  $syncParentName = UniteFunctionsUC::getVal($value, $name."_sync_name");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2525
 
2526
- if($syncParentName == "custom")
2527
- $syncParentName = UniteFunctionsUC::getVal($value, $name."_sync_custom_name");
2528
 
2529
- if(empty($syncParentName))
2530
- $syncParentName = "auto";
2531
 
2532
- $attributes .= " data-sync='true' data-parentid='$syncParentName'";
2533
  }
 
 
2534
 
2535
- $class = " uc-remote-parent";
 
2536
 
2537
- //output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2538
 
2539
  $arrOutput["attributes"] = $attributes;
2540
  $arrOutput["class"] = $class;
2541
 
2542
  $data[$name] = $arrOutput;
2543
 
 
 
2544
  return($data);
2545
  }
2546
 
@@ -2589,6 +2708,11 @@ class UniteCreatorParamsProcessor extends UniteCreatorParamsProcessorWork{
2589
  case "parent":
2590
  $data = $this->getRemoteParentData($value, $name, $processType, $param, $data);
2591
  break;
 
 
 
 
 
2592
  }
2593
 
2594
 
469
  return($taxonomy);
470
  }
471
 
472
+ /**
473
+ * get post main category from the list of terms
474
+ */
475
+ private function getPostMainCategory($arrTerms, $postID){
476
+
477
+
478
+ //get term data
479
+
480
+ if(count($arrTerms) == 1){ //single
481
+ $arrTermData = UniteFunctionsUC::getArrFirstValue($arrTerms);
482
+ return($arrTermData);
483
+ }
484
+
485
+ $yoastMainCategory = get_post_meta($postID, "_yoast_wpseo_primary_category", true);
486
+
487
+ if(empty($yoastMainCategory)){
488
+
489
+ unset($arrTerms["uncategorized"]);
490
+ $arrTermData = UniteFunctionsUC::getArrFirstValue($arrTerms);
491
+
492
+ return($arrTermData);
493
+ }
494
+
495
+ foreach($arrTerms as $term){
496
+
497
+ $termID = UniteFunctionsUC::getVal($term, "term_id");
498
+
499
+ if($termID == $yoastMainCategory)
500
+ return($term);
501
+ }
502
+
503
+ unset($arrTerms["uncategorized"]);
504
+ $arrTermData = UniteFunctionsUC::getArrFirstValue($arrTerms);
505
+
506
+ return($arrTermData);
507
+ }
508
+
509
 
510
  /**
511
  * get post category fields
530
 
531
  $arrCatsOutput = $this->modifyArrTermsForOutput($arrTerms, $taxonomy);
532
 
533
+ $arrTermData = $this->getPostMainCategory($arrTerms, $postID);
 
 
 
 
 
 
 
 
534
 
535
  $catID = UniteFunctionsUC::getVal($arrTermData, "term_id");
536
 
587
  $arrData["alias"] = UniteFunctionsUC::getVal($arrPost, "post_name");
588
  $arrData["author_id"] = UniteFunctionsUC::getVal($arrPost, "post_author");
589
 
590
+ $content = UniteFunctionsWPUC::getPostContent($post);
 
 
 
591
 
592
  $arrData["content"] = $content;
593
 
602
  }
603
 
604
  if(!empty($intro)){
605
+ $intro = wp_strip_all_tags($intro, true);
606
  $introFull = $intro;
607
+
608
  $intro = UniteFunctionsUC::truncateString($intro, 100);
609
  }
610
 
1408
 
1409
  $metaKey = UniteFunctionsUC::getVal($value, "{$name}_includeby_metakey");
1410
  $metaCompare = UniteFunctionsUC::getVal($value, "{$name}_includeby_metacompare");
 
1411
 
1412
+ $metaValue = UniteFunctionsUC::getVal($value, "{$name}_includeby_metavalue");
1413
  $metaValue = $this->modifyMetaValueForCompare($metaValue);
1414
 
1415
+ $metaValue2 = UniteFunctionsUC::getVal($value, "{$name}_includeby_metavalue2");
1416
+ $metaValue2 = $this->modifyMetaValueForCompare($metaValue2);
1417
+
1418
+ $metaValue3 = UniteFunctionsUC::getVal($value, "{$name}_includeby_metavalue3");
1419
+ $metaValue3 = $this->modifyMetaValueForCompare($metaValue3);
1420
+
1421
+
1422
  if(!empty($metaKey)){
1423
 
1424
  $arrMetaQuery[] = array(
1426
  'value' => $metaValue,
1427
  'compare'=>$metaCompare
1428
  );
1429
+
1430
+
1431
+ if(!empty($metaValue2)){
1432
+
1433
+ $arrMetaQuery[] = array(
1434
+ 'key' => $metaKey,
1435
+ 'value' => $metaValue2,
1436
+ 'compare'=>$metaCompare
1437
+ );
1438
+
1439
+ $arrMetaQuery["relation"] = "OR";
1440
+ }
1441
+
1442
+ if(!empty($metaValue3)){
1443
+
1444
+ $arrMetaQuery[] = array(
1445
+ 'key' => $metaKey,
1446
+ 'value' => $metaValue3,
1447
+ 'compare'=>$metaCompare
1448
+ );
1449
+
1450
+ $arrMetaQuery["relation"] = "OR";
1451
+ }
1452
+
1453
+
1454
  }
1455
 
1456
  break;
1747
  GlobalsProviderUC::$lastPostQuery = $query;
1748
  GlobalsProviderUC::$lastPostQuery_page = 1;
1749
  GlobalsProviderUC::$lastPostQuery_type = $type;
1750
+
1751
+ //set type for pagination, stay on current if exists
1752
+ if(GlobalsProviderUC::$lastPostQuery_paginationType != GlobalsProviderUC::QUERY_TYPE_CURRENT)
1753
+ GlobalsProviderUC::$lastPostQuery_paginationType = $type;
1754
+
1755
+
1756
  $queryVars = $query->query;
1757
 
1758
  $perPage = UniteFunctionsUC::getVal($queryVars, "posts_per_page");
1778
  */
1779
  private function getPostListData_currentPosts($value, $name, $data){
1780
 
 
1781
  //add debug for further use
1782
  HelperUC::addDebug("Getting Current Posts");
1783
 
1790
 
1791
  if($orderDir == "default")
1792
  $orderDir = null;
1793
+
1794
  global $wp_query;
1795
  $currentQueryVars = $wp_query->query_vars;
1796
 
1850
 
1851
  //save last query
1852
  $this->saveLastQueryAndPage($query, GlobalsProviderUC::QUERY_TYPE_CURRENT);
1853
+
1854
  $arrPosts = $query->posts;
1855
 
1856
  if(empty($arrPosts))
2004
 
2005
  $useCategory = UniteFunctionsUC::getVal($param, "use_category");
2006
  $useCategory = UniteFunctionsUC::strToBool($useCategory);
2007
+
2008
  $arrPostAdditions = HelperProviderUC::getPostDataAdditions($useCustomFields, $useCategory);
2009
 
2010
  HelperUC::addDebug("post additions", $arrPostAdditions);
2545
 
2546
  $isDebug = UniteFunctionsUC::getVal($value, $name."_debug");
2547
  $isDebug = UniteFunctionsUC::strToBool($isDebug);
2548
+
2549
  $isSync = UniteFunctionsUC::getVal($value, $name."_sync");
2550
  $isSync = UniteFunctionsUC::strToBool($isSync);
2551
 
2552
+ $widgetName = $this->addon->getTitle();
2553
 
2554
+ if($isEnable == false && $isSync == false){
 
2555
 
2556
  $arrOutput["attributes"] = "";
2557
  $arrOutput["class"] = "";
2563
 
2564
  HelperUC::addRemoteControlsScript();
2565
 
2566
+ $attributes = "";
 
 
 
 
2567
 
2568
+ //get the name
2569
+ if($isEnable == true){
2570
+
2571
+ $parentName = UniteFunctionsUC::getVal($value, $name."_name");
2572
+
2573
+ if($parentName == "custom")
2574
+ $parentName = UniteFunctionsUC::getVal($value, $name."_custom_name");
2575
+
2576
+ if(empty($parentName))
2577
+ $parentName = "auto";
2578
+
2579
+ $parentName = UniteFunctionsUC::sanitizeAttr($parentName);
2580
+
2581
+ //create attributes and classes
2582
+
2583
+ $attributes .= " data-remoteid='$parentName'";
2584
+ }
2585
 
2586
+ if($isDebug == true)
2587
+ $attributes .= " data-debug='true'";
2588
 
2589
+ $widgetName = UniteFunctionsUC::sanitizeAttr($widgetName);
2590
 
2591
+ if(!empty($widgetName))
2592
+ $attributes .= " data-widgetname='$widgetName'";
2593
 
 
 
2594
 
2595
  if($isSync == true){
2596
 
2597
  //get the name
2598
  $syncParentName = UniteFunctionsUC::getVal($value, $name."_sync_name");
2599
+
2600
+ $attributes .= " data-sync='true' data-syncid='$syncParentName'";
2601
+ }
2602
+
2603
+ $class = " uc-remote-parent";
2604
+
2605
+ //output
2606
+
2607
+ $arrOutput["attributes"] = $attributes;
2608
+ $arrOutput["class"] = $class;
2609
+
2610
+ $data[$name] = $arrOutput;
2611
+
2612
+ return($data);
2613
+ }
2614
+
2615
+ /**
2616
+ * get background data
2617
+ */
2618
+ private function getRemoteBackgroundData($value, $name, $processType, $param, $data){
2619
+
2620
+
2621
+ $isSync = UniteFunctionsUC::getVal($value, $name."_sync");
2622
+ $isSync = UniteFunctionsUC::strToBool($isSync);
2623
+
2624
+ if($isSync == false){
2625
 
2626
+ $arrOutput["attributes"] = "";
2627
+ $arrOutput["class"] = "";
2628
 
2629
+ $data[$name] = $arrOutput;
 
2630
 
2631
+ return($data);
2632
  }
2633
+
2634
+ $syncParentName = UniteFunctionsUC::getVal($value, $name."_sync_name");
2635
 
2636
+ $isDebug = UniteFunctionsUC::getVal($value, $name."_debug");
2637
+ $isDebug = UniteFunctionsUC::strToBool($isDebug);
2638
 
2639
+ HelperUC::addRemoteControlsScript();
2640
+
2641
+ $attributes = "";
2642
+ $attributes .= " data-sync='true' data-syncid='$syncParentName'";
2643
+
2644
+ if($isDebug == true)
2645
+ $attributes .= " data-debug='true'";
2646
+
2647
+ $widgetName = $this->addon->getTitle();
2648
+ $widgetName = UniteFunctionsUC::sanitizeAttr($widgetName);
2649
+
2650
+ if(!empty($widgetName))
2651
+ $attributes .= " data-widgetname='$widgetName'";
2652
+
2653
+
2654
+ $class = " uc-remote-parent";
2655
 
2656
  $arrOutput["attributes"] = $attributes;
2657
  $arrOutput["class"] = $class;
2658
 
2659
  $data[$name] = $arrOutput;
2660
 
2661
+
2662
+
2663
  return($data);
2664
  }
2665
 
2708
  case "parent":
2709
  $data = $this->getRemoteParentData($value, $name, $processType, $param, $data);
2710
  break;
2711
+ case "background":
2712
+
2713
+ $data = $this->getRemoteBackgroundData($value, $name, $processType, $param, $data);
2714
+
2715
+ break;
2716
  }
2717
 
2718
 
provider/provider_settings.class.php CHANGED
@@ -415,7 +415,6 @@ class UniteCreatorSettings extends UniteCreatorSettingsWork{
415
  $this->addRadioBoolean($name."_init_after_grid", __("Init After Grid", "unlimited-elements-for-elementor"), false, "Yes", "No", $params);
416
 
417
 
418
-
419
  //---------- add hr ---------
420
 
421
  $params = array();
@@ -1423,13 +1422,19 @@ class UniteCreatorSettings extends UniteCreatorSettingsWork{
1423
  $params["origtype"] = UniteCreatorDialogParam::PARAM_TEXTFIELD;
1424
  $params["placeholder"] = __("Meta Value","unlimited-elements-for-elementor");
1425
  $params["add_dynamic"] = true;
1426
- $params["description"] = "Special keywords you can use: {current_user_id}";
1427
 
1428
  $params["elementor_condition"] = $arrConditionIncludeMeta;
1429
 
1430
 
1431
  $this->addTextBox($name."_includeby_metavalue", "", esc_html__("Include by Meta Value", "unlimited-elements-for-elementor"), $params);
1432
-
 
 
 
 
 
 
1433
  // --------- include by PHP Function -------------
1434
 
1435
  $arrConditionIncludeFunction = $arrConditionIncludeBy;
@@ -2081,9 +2086,9 @@ class UniteCreatorSettings extends UniteCreatorSettingsWork{
2081
  $arrSizes = array_flip($arrSizes);
2082
  $this->addSelect($name."_image_size", $arrSizes, __("Big Image Size", "unlimited-elements-for-elementor"), "large", $params);
2083
 
2084
-
2085
  }
2086
 
 
2087
  /**
2088
  * add remote parent settings
2089
  */
@@ -2102,7 +2107,6 @@ class UniteCreatorSettings extends UniteCreatorSettingsWork{
2102
 
2103
  $this->addRadioBoolean($remoteEnableName, __("Enable Remote Connection", "unlimited-elements-for-elementor"), false, "Yes", "No", $params);
2104
 
2105
-
2106
  //widget name
2107
 
2108
  $arrNames = HelperProviderUC::getArrRemoteParentNames();
@@ -2122,45 +2126,50 @@ class UniteCreatorSettings extends UniteCreatorSettingsWork{
2122
 
2123
  $this->addTextBox($prefix."custom_name", "", __("Custom Name","unlimited-elements-for-elementor"), $params);
2124
 
 
 
 
2125
 
2126
- //debug remote widgets
2127
-
2128
- $params = array();
2129
- $params["origtype"] = UniteCreatorDialogParam::PARAM_RADIOBOOLEAN;
2130
- $params["description"] = __("Show information about remote widgets that connected to this widget. Please turn off this option before release", "unlimited-elements-for-elementor");
2131
- $params["elementor_condition"] = $condition;
2132
-
2133
- $this->addRadioBoolean($prefix."debug", __("Debug Connected Widgets", "unlimited-elements-for-elementor"), false, "Yes", "No", $params);
2134
 
2135
  //sync
2136
 
 
 
 
2137
  $params = array();
2138
  $params["origtype"] = UniteCreatorDialogParam::PARAM_RADIOBOOLEAN;
2139
- $params["elementor_condition"] = $condition;
2140
 
2141
  $this->addRadioBoolean($prefix."sync", __("Sync", "unlimited-elements-for-elementor"), false, "Yes", "No", $params);
2142
 
2143
  //sync with widget name
2144
 
2145
- $arrNames = HelperProviderUC::getArrRemoteParentNames();
2146
  $arrNames = array_flip($arrNames);
2147
-
2148
- $conditionSync = $condition;
2149
- $conditionSync[$prefix."sync"] = "true";
2150
-
2151
  $params = array(
2152
- "description"=>__("Choose remote name of the widget that you want to sync with"),
2153
  "origtype" => UniteCreatorDialogParam::PARAM_DROPDOWN,
2154
  "elementor_condition" => $conditionSync
2155
  );
2156
 
2157
- $this->addSelect($prefix."sync_name", $arrNames, __("Widget Name for Sync", "unlimited-elements-for-elementor"), "auto", $params);
2158
 
 
 
 
 
 
 
 
 
2159
  $params = array();
2160
- $params["origtype"] = UniteCreatorDialogParam::PARAM_TEXTFIELD;
2161
- $params["elementor_condition"] = array($remoteEnableName=>"true",$prefix."sync_name"=>"custom",$prefix."sync"=>"true");
 
 
2162
 
2163
- $this->addTextBox($prefix."sync_custom_name", "", __("Custom Name for Sync","unlimited-elements-for-elementor"), $params);
2164
 
2165
  }
2166
 
@@ -2195,6 +2204,50 @@ class UniteCreatorSettings extends UniteCreatorSettingsWork{
2195
 
2196
  }
2197
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2198
 
2199
  /**
2200
  * add remote settings
@@ -2208,6 +2261,11 @@ class UniteCreatorSettings extends UniteCreatorSettingsWork{
2208
 
2209
  $this->addRemoteSettingsController($name,$value,$title,$param);
2210
 
 
 
 
 
 
2211
  break;
2212
  default:
2213
  case "parent":
415
  $this->addRadioBoolean($name."_init_after_grid", __("Init After Grid", "unlimited-elements-for-elementor"), false, "Yes", "No", $params);
416
 
417
 
 
418
  //---------- add hr ---------
419
 
420
  $params = array();
1422
  $params["origtype"] = UniteCreatorDialogParam::PARAM_TEXTFIELD;
1423
  $params["placeholder"] = __("Meta Value","unlimited-elements-for-elementor");
1424
  $params["add_dynamic"] = true;
1425
+ $params["description"] = "";
1426
 
1427
  $params["elementor_condition"] = $arrConditionIncludeMeta;
1428
 
1429
 
1430
  $this->addTextBox($name."_includeby_metavalue", "", esc_html__("Include by Meta Value", "unlimited-elements-for-elementor"), $params);
1431
+ $this->addTextBox($name."_includeby_metavalue2", "", esc_html__("Include by Meta Value 2", "unlimited-elements-for-elementor"), $params);
1432
+
1433
+ $params["description"] = "Special keywords you can use: {current_user_id}";
1434
+
1435
+ $this->addTextBox($name."_includeby_metavalue3", "", esc_html__("Include by Meta Value 3", "unlimited-elements-for-elementor"), $params);
1436
+
1437
+
1438
  // --------- include by PHP Function -------------
1439
 
1440
  $arrConditionIncludeFunction = $arrConditionIncludeBy;
2086
  $arrSizes = array_flip($arrSizes);
2087
  $this->addSelect($name."_image_size", $arrSizes, __("Big Image Size", "unlimited-elements-for-elementor"), "large", $params);
2088
 
 
2089
  }
2090
 
2091
+
2092
  /**
2093
  * add remote parent settings
2094
  */
2107
 
2108
  $this->addRadioBoolean($remoteEnableName, __("Enable Remote Connection", "unlimited-elements-for-elementor"), false, "Yes", "No", $params);
2109
 
 
2110
  //widget name
2111
 
2112
  $arrNames = HelperProviderUC::getArrRemoteParentNames();
2126
 
2127
  $this->addTextBox($prefix."custom_name", "", __("Custom Name","unlimited-elements-for-elementor"), $params);
2128
 
2129
+ $params = array(
2130
+ "origtype" => UniteCreatorDialogParam::PARAM_HR,
2131
+ );
2132
 
2133
+ $this->addHr("hr_before_sync",$params);
 
 
 
 
 
 
 
2134
 
2135
  //sync
2136
 
2137
+ $remoteSyncName = $prefix."sync";
2138
+ $conditionSync = array($remoteSyncName=>"true");
2139
+
2140
  $params = array();
2141
  $params["origtype"] = UniteCreatorDialogParam::PARAM_RADIOBOOLEAN;
2142
+ $params["description"] = __("Sync slide run with other widgets", "unlimited-elements-for-elementor");
2143
 
2144
  $this->addRadioBoolean($prefix."sync", __("Sync", "unlimited-elements-for-elementor"), false, "Yes", "No", $params);
2145
 
2146
  //sync with widget name
2147
 
2148
+ $arrNames = HelperProviderUC::getArrRemoteSyncNames();
2149
  $arrNames = array_flip($arrNames);
2150
+
 
 
 
2151
  $params = array(
2152
+ "description"=>__("Choose the sync group"),
2153
  "origtype" => UniteCreatorDialogParam::PARAM_DROPDOWN,
2154
  "elementor_condition" => $conditionSync
2155
  );
2156
 
2157
+ $this->addSelect($prefix."sync_name", $arrNames, __("Sync Group", "unlimited-elements-for-elementor"), "group1", $params);
2158
 
2159
+ $params = array(
2160
+ "origtype" => UniteCreatorDialogParam::PARAM_HR
2161
+ );
2162
+
2163
+ $this->addHr("hr_before_debug",$params);
2164
+
2165
+ //debug remote widgets
2166
+
2167
  $params = array();
2168
+ $params["origtype"] = UniteCreatorDialogParam::PARAM_RADIOBOOLEAN;
2169
+ $params["description"] = __("Show information about remote widgets that connected to this widget. Please turn off this option before release", "unlimited-elements-for-elementor");
2170
+
2171
+ $this->addRadioBoolean($prefix."debug", __("Show Debug", "unlimited-elements-for-elementor"), false, "Yes", "No", $params);
2172
 
 
2173
 
2174
  }
2175
 
2204
 
2205
  }
2206
 
2207
+ /**
2208
+ * add remote background settings
2209
+ */
2210
+ protected function addRemoteSettingsBackground($name,$value,$title,$param){
2211
+
2212
+ $prefix = $name."_";
2213
+
2214
+ // --- sync ----
2215
+
2216
+ $params = array();
2217
+ $params["origtype"] = UniteCreatorDialogParam::PARAM_RADIOBOOLEAN;
2218
+
2219
+ $condition = UniteFunctionsUC::getVal($param, "elementor_condition");
2220
+ $params["elementor_condition"] = $condition;
2221
+
2222
+ $this->addRadioBoolean($prefix."sync", __("Enable Sync", "unlimited-elements-for-elementor"), false, "Yes", "No", $params);
2223
+
2224
+ // --- sync name ----
2225
+
2226
+ $arrNames = HelperProviderUC::getArrRemoteSyncNames();
2227
+ $arrNames = array_flip($arrNames);
2228
+
2229
+ $conditionSync = $condition;
2230
+ $conditionSync[$prefix."sync"] = "true";
2231
+
2232
+ $params = array(
2233
+ "origtype" => UniteCreatorDialogParam::PARAM_DROPDOWN,
2234
+ "elementor_condition" => $conditionSync
2235
+ );
2236
+
2237
+ $this->addSelect($prefix."sync_name", $arrNames, __("Sync Group", "unlimited-elements-for-elementor"), "group1", $params);
2238
+
2239
+
2240
+ // --- debug ---
2241
+
2242
+ $params = array();
2243
+ $params["origtype"] = UniteCreatorDialogParam::PARAM_RADIOBOOLEAN;
2244
+ $params["elementor_condition"] = $conditionSync;
2245
+
2246
+ $this->addRadioBoolean($prefix."debug", __("Show Debug", "unlimited-elements-for-elementor"), false, "Yes", "No", $params);
2247
+
2248
+
2249
+ }
2250
+
2251
 
2252
  /**
2253
  * add remote settings
2261
 
2262
  $this->addRemoteSettingsController($name,$value,$title,$param);
2263
 
2264
+ break;
2265
+ case "background":
2266
+
2267
+ $this->addRemoteSettingsBackground($name,$value,$title,$param);
2268
+
2269
  break;
2270
  default:
2271
  case "parent":
provider/woocommerce_integrate.class.php CHANGED
@@ -485,6 +485,37 @@ class UniteCreatorWooIntegrate{
485
  return($variations);
486
  }
487
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
 
489
  /**
490
  * get product data
@@ -620,6 +651,44 @@ class UniteCreatorWooIntegrate{
620
 
621
  }
622
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
623
  /**
624
  * get woo commerce data by type
625
  */
485
  return($variations);
486
  }
487
 
488
+ /**
489
+ *
490
+ * get product gallery
491
+ */
492
+ public function getProductGallery($productID){
493
+
494
+ if(function_exists("wc_get_product") == false)
495
+ return(array());
496
+
497
+ $product = wc_get_product($productID);
498
+
499
+ if(empty($product))
500
+ return(array());
501
+
502
+ $arrAttachmentIDs = $product->get_gallery_image_ids();
503
+
504
+ if(empty($arrAttachmentIDs))
505
+ return(array());
506
+
507
+ $arrImages = array();
508
+
509
+ foreach($arrAttachmentIDs as $id){
510
+
511
+ $data = UniteFunctionsWPUC::getAttachmentData($id);
512
+
513
+ $arrImages[] = $data;
514
+ }
515
+
516
+ return($arrImages);
517
+ }
518
+
519
 
520
  /**
521
  * get product data
651
 
652
  }
653
 
654
+ /**
655
+ * get the endpoints - url's
656
+ */
657
+ public static function getWooEndpoint($type){
658
+
659
+ switch($type){
660
+ case "cart":
661
+ $url = wc_get_cart_url();
662
+ break;
663
+ case "checkout":
664
+ $url = wc_get_checkout_url();
665
+ break;
666
+ case "myaccount":
667
+
668
+ $myAccountID = get_option( 'woocommerce_myaccount_page_id' );
669
+ $url = "";
670
+ if(!empty($myAccountID))
671
+ $url = get_permalink($myAccountID);
672
+ break;
673
+ case "shop":
674
+
675
+ $url = "";
676
+ $shopPageID = wc_get_page_id($type);
677
+
678
+ if(!empty($shopPageID) && $shopPageID != -1)
679
+ $url = get_permalink($shopPageID);
680
+
681
+ break;
682
+ default:
683
+ $type = esc_html($type);
684
+ UniteFunctionsUC::throwError("get_woo_endpoints error: wrong endpoint type: $type,
685
+ allowed endpoints are: cart, checkout, myaccount, shop");
686
+ break;
687
+ }
688
+
689
+ return($url);
690
+ }
691
+
692
  /**
693
  * get woo commerce data by type
694
  */
readme.txt CHANGED
@@ -3,13 +3,14 @@ Contributors: unitecms, valiano, iritmega
3
  Donate link: http://unlimited-elements.com/
4
  Tags: elementor, elements, addons, elementor addons, elementor widget, page builder, builder, visual editor, wordpress page builder, elementor
5
  Requires at least: 3.5
6
- Tested up to: 5.7
7
  Stable tag: 1.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
  The best package of Free Elementor Addons. +100 Free Elementor Widgets, +10 Free Animated Backgrounds, +30 Free Elementor Templates, WooCommerce Widgets, Full Screen Menu Addons, Testimonial Slider, Post Grid, Carousel Widgets, Event Widgets, Button Effects for Elementor, Instagram Addons, Icon Boxes, Flipbox, Image Accordion, Timeline Widget, Video Galleries Dynamic Loop Builder, Whatsapp Chat, Price List Addons. Including the one and only Widget Creator Elementor Website Builder and Editor for Elementor to create custom.
12
 
 
13
  == Description ==
14
 
15
 
@@ -92,55 +93,57 @@ Fully compatible and integrated with Toolset custom post types and fields.
92
  <h3>Creative Widgets for Elementor</h3>
93
  <ol>
94
  <li><a href="https://unlimited-elements.com/blob-shape-widget-for-elementor/">Blob Shapes Widget for Elementor (Free)</a> - Create Blob Shapes with animated morphing effects. This free Elementor widget will help you make your images into random, unique, and organic-looking blob shapes. </li>
95
- <li><a href="https://unlimited-elements.com/timeline-bullets-widget-for-elementor/">Timeline Bullets Widget for Elementor (Free)</a> - List your features or services using bullet points in a timeline layout to make it easier for users to read the important information.</li>
96
- <li><a href="https://unlimited-elements.com/animated-hamburger-icon-for-elementor/">Animated Hamburger Icon Widget for Elementor (Free)</a> - Use the animated hamburger icon widget to toggle Elementor pro popus. You can even put a menu in a popup and create a full screen menu.</li>
97
- <li><a href="https://unlimited-elements.com/flip-box-widget-for-elementor/">Flip Box Widget for Elementor (Free)</a> - Make your content more interesting with the Elementor Flip Box widget. Use the animated Flip Boxes to highlight any content inside your page with a flip effect.</li>
98
- <li><a href="https://unlimited-elements.com/lordicon-animated-icons-widget-for-elementor/">Lordicon: Animated Icons Widget for Elementor (Free)</a> - The most powerful animated icon library with 1500+ free and premium animated Lottie animations.</li>
99
- <li><a href="https://unlimited-elements.com/image-tooltip-widget-for-elementor/">Image Tooltip Widget for Elementor (Free)</a> - The easiest way to set a tooltip to any Image on the page with a short text description or any HTML code.</li>
100
  <li><a href="https://unlimited-elements.com/number-box-widget-widget-for-elementor/">Number Box Widget for Elementor (Free)</a> - Create stunning number blocks with various styles. The Number Box widget for Elementor helps you display content for step by step diagrams and instructions.</li>
101
- <li><a href="https://unlimited-elements.com/material-bullets-widget-for-elementor">Material Bullets Widget for Elementor (Free)</a> - Display feature lists with custom icons and styles. Each list item can have its own icon title and text. Use the bullets widget to display features and highlights on your Elementor website.</li>
102
- <li><a href="https://unlimited-elements.com/svg-animation-widget-for-elementor">SVG Animation Widget for Elementor (Free)</a> - The SVG animation widget for Elementor makes it easy -to create impressive SVG animations for your websitet, without any coding skills just copy paste your SVG code and your animated icon is ready.</li>
103
  <li><a href="https://unlimited-elements.com/animated-mouse-scroll-icon-widget-for-elementor/">Animated Mouse Scroll Icon Widget for Elementor (Free)</a> - The Animated Mouse Scroll Icon is a small micro animation that indicates to user they needs to scroll the page. You can make the icon an anchor point which scroll down to any section when clicked on.
104
  </li>
105
- <li><a href="https://unlimited-elements.com/interactive-circle-infographic-widget-for-elementor/">Interactive Circle Infographic Widget for Elementor (Pro)</a> - The Circle Infographic widget for Elementor is a simple and engaging way to present data, processes, concepts, structures and more. Helps your audience understand an entire cycle using a circular interactive tab layout.
106
-
107
- </li>
 
 
 
 
108
  <li><a href="https://unlimited-elements.com/icon-accordion-widget-for-elementor/">Icon Accordion Widget for Elementor (Pro)</a> - Advanced accordion addon for Elementor page builder offers multiple styles to create interactive collapsable content with multiple layouts on your page.</li>
 
109
  <li><a href="https://unlimited-elements.com/image-shapes-for-elementor-page-builder/">Image Shapes Widget for Elementor (Pro)</a> - The Image Shapes Elementor Widget allows you to make complex shape addons by clipping images using CSS to make various element layouts: circle, ellipse, polygon and more.</li>
110
  <li><a href="https://unlimited-elements.com/image-particle-widget-for-elementor/">Particle Image Widget for Elementor (Pro)</a> - Create a dispersion interactive mouse aware distortion effect for any image using the Particle Image widget for Elementor.</li>
111
  <li><a href="https://unlimited-elements.com/image-zoom-magnifier-widget-for-elementor/">Image Zoom Magnifier Widget for Elementor (Pro)</a> - Image Zoom Magnifier is a Elmentor Widget for creating a direction-aware magnifying glass effect to provide an inner zoom functionality on any given image. Enlarge images on touch, click, or mouseover.</li>
112
  <li><a href="https://unlimited-elements.com/background-switcher-widget-for-elementor/">Background Switcher Widget for Elementor (Pro)</a> - The background switcher addon lets you set up cool content boxes. When you hover over a box it will change the background for the whole section. </li>
113
- <li><a href="https://unlimited-elements.com/before-after-image-comparison-widget-for-elementor/">Before After Widget for Elementor (Pro)</a> - The Before After widget is an image comparison addon for Elementor. This widget allows you to create the effect for comparing two before and after images.</li>
114
  <li><a href="https://unlimited-elements.com/audio-player-widget-for-elementor/">Audio Player Widget for Elementor (Pro)</a> - MP3 Music Player is a very easy to use Audio Player for Elementor. It gives you the ability to add unlimited audio tracks to any page using our Elementor addon let users listen to music on your website. </li>
115
- <li><a href="https://unlimited-elements.com/audio-playlist-widget-for-elementor">Audio Playlist Widget for Elementor (Pro)</a> - Create MP3 Audio Playlists inside of Elementor. Use this widget to add the ability to create unlimited numbers of playlists, albums, and audio tracks.</li>
116
  <li><a href="https://unlimited-elements.com/hotspots-for-elementor-page-builder/">Hotspots Widget for Elementor (Pro)</a> - Add hotspots to your images with a tooltip an option for opening a built in popup. Each hotspot popup can contain and image and description text.</li>
117
- <li><a href="https://unlimited-elements.com/icon-tabs-widget-for-elementor">Icon Tabs Widget for Elementor (Pro)</a> - The Tab Widget for Elementor will help you show your text on your page divided into horizontal or vertical tabs. Customize your tabs using icons and make the content on your website interactive and fun to read.</li>
118
  <li><a href="https://unlimited-elements.com/image-accordion-widget-for-elementor/">Image Accordion Widget for Elementor (Pro)</a> - Our image accordion addon for Elementor highlights your images with amazing hover effects and interactive layouts.</li>
119
  <li><a href="https://unlimited-elements.com/shape-bullets-widget-for-elementor/">Shape Bullets Widget for Elementor (Pro)</a> - The Shape Bullets Widget for Elementor, creates an easy-to-manage bulleted list of items. Each item can be highlighted by its own icon.
120
  </li>
121
- <li><a href="https://unlimited-elements.com/image-reveal-on-scroll-widget-for-elementor">Image Reveal On Scroll Widget for Elementor (Pro)</a> - The Image Reveal on Scroll widget adds an awesome reveal on scroll effect to your images to spice up your Elementor website design.</li>
 
 
 
 
 
122
  </ol>
123
 
124
  <h3>Post Widgets for Elementor</h3>
125
  <ol>
126
- <li><a href="https://unlimited-elements.com/post-pagination-widget-for-elementor/">Post Pagination Widget for Elementor (Free)</a></li>
 
127
  <li><a href="https://unlimited-elements.com/post-blocks-widget-for-elementor">Post Blocks Widget for Elementor (Free)</a></li>
128
  <li><a href="https://unlimited-elements.com/post-list-widget-for-elementor">Post List Widget for Elementor (Free)</a></li>
129
- <li><a href="https://unlimited-elements.com/load-more-infinite-scroll-widget-for-elementor/">Load More / Infinite Scroll Widget for Elementor (Free)</a> - Add a load more button to your post or product grids. You can even make an infinite scroll effect that works with AJAX.</li>
130
  <li><a href="https://unlimited-elements.com/post-news-ticker-widget-for-elementor">Post Ticker Widget for Elementor (Free)</a></li>
131
- <li><a href="https://unlimited-elements.com/post-tabs-for-elementor/">Post Tabs Widget for Elementor (Free)</a></li>
132
  <li><a href="https://unlimited-elements.com/card-post-carousel-widget-for-elementor">Card Post Carousel Widget for Elementor (Free)</a></li>
133
- <li><a href="https://unlimited-elements.com/post-accordions-for-elementor/">Post Accordion Widget for Elementor (Free)</a></li>
134
- <li><a href="https://unlimited-elements.com/post-magazine-grid-widget-for-elementor/">Post Magazine Grid Widget for Elementor (Pro)</a></li>
135
  <li><a href="https://unlimited-elements.com/post-gallery-widget-for-elementor">Post Gallery Widget for Elementor (Pro)</a></li>
136
  <li><a href="https://unlimited-elements.com/elementor-author-list-widget/">Author List Widget for Elementor (Pro)</a></li>
137
  <li><a href="https://unlimited-elements.com/masonry-post-grid-widget-for-elementor">Masonry Post Grid Widget for Elementor (Pro)</a></li>
138
  <li><a href="https://unlimited-elements.com/taxonomy-terms-widget-for-elementor/">Taxonomy Terms Widget for Elementor (Pro)</a></li>
139
  <li><a href="https://unlimited-elements.com/post-tiles-widget-for-elementor">Post Tile Widget for Elementor (Pro)</a></li>
140
- <li><a href="https://unlimited-elements.com/blog-card-slider-widget-for-elementor">Post Card Slider Widget for Elementor (Pro)</a></li>
141
- <li><a href="https://unlimited-elements.com/post-timeline-widget-for-elementor/">Post Timeline Widget for Elementor (Pro)</a></li>
142
  <li><a href="https://unlimited-elements.com/post-sliders/">Post Slider Widget for Elementor (Pro)</a></li>
 
 
143
  <li><a href="https://unlimited-elements.com/post-carousels-for-elementor/">Post Carousel Widget for Elementor (Pro)</a></li>
 
144
  <li><a href="https://unlimited-elements.com/post-scroll-widget-for-elementor">Post Scroll Widget for Elementor (Pro)</a></li>
145
  <li><a href="https://unlimited-elements.com/post-grid">Post Grid Widget for Elementor (Pro)</a></li>
146
  <li><a href="https://unlimited-elements.com/post-horizontal-timeline-widget-for-elementor/">Post Horizontal Timeline Widget for Elementor (Pro)</a></li>
@@ -149,27 +152,28 @@ Fully compatible and integrated with Toolset custom post types and fields.
149
  <h3>Marketing Widgets for Elementor</h3>
150
  <ol>
151
  <li><a href="https://unlimited-elements.com/unlimited-timeline-widget-for-elementor">Unlimited Timeline Widget for Elementor (Free)</a> - Showcase your story or company history in a vertical timeline layout using the powerful Unlimited Timeline addon for Elementor.</li>
152
- <li><a href="https://unlimited-elements.com/event-box-widget-for-elementor">Event Box Widget for Elementor (Free)</a> - Showcase events & special occasions on your websites using this unique Elementor addon.</li>
153
  <li><a href="https://unlimited-elements.com/overlay-product-box-widget-for-elementor/">Overlay Product Box Widget for Elementor (Free)</a></li>
154
  <li><a href="https://unlimited-elements.com/business-hours-widget-for-elementor">Business Hours Widget for Elementor (Free)</a></li>
155
  <li><a href="https://unlimited-elements.com/timer-countdowns-for-elementor-page-builder/">Timer Countdown Widget for Elementor (Free)</a> - Instantly create a beautiful, animated countdown clock addon, to share on your Elementor website. Count down to a date with your own unique timer.
156
 
157
  </li>
158
  <li><a href="https://unlimited-elements.com/call-to-action-button-widget-for-elementor/">Call To Action Button Widget for Elementor (Free)</a> - The Call to Action Button Widget is a tool for creating beautiful buttons that combine an icon, some text, and message notification.</li>
159
- <li><a href="https://unlimited-elements.com/statistic-counters-for-elementor">Counter Widget for Elementor (Free)</a> - Showcasing your business statistics and show fun facts and figures on your Elementor website.</li>
160
  <li><a href="https://unlimited-elements.com/price-list-widget-for-elementor/">Price List Widget for Elementor (Free)</a> - A powerful addon that allows displaying a list of items, products, services or features for your business with easy styling options.</li>
161
- <li><a href="https://unlimited-elements.com/price-label-product-box-widget-for-elementor/">Product Box Widget for Elementor (Free)</a></li>
162
- <li><a href="https://unlimited-elements.com/notification-widget-for-elementor">Notification Widget for Elementor (Free)</a> - The Notification widget enables you to display a colored alert box and draw attention to important messages on your Elementor website.</li>
163
- <li><a href="https://unlimited-elements.com/review-box-widget-for-elementor">Review Box Widget for Elementor (Free)</a> - Simply create and display reviews on your Elementor website to build customers� trust and increase SEO.</li>
164
- <li><a href="http://unlimited-elements.com/food-menu-box-widget-for-elementor/">Product Card Widget for Elementor (Free)</a></li>
165
  <li><a href="https://unlimited-elements.com/pricing-table-widget-for-elementor/">Pricing Table Widget for Elementor (Free)</a> - Present the available pricing plans in an easy to read format. Use the Pricing Table widget to help your customers make purchasing decisions.</li>
 
 
 
 
166
  <li><a href="https://unlimited-elements.com/product-bullets-widget-for-elementor">Product Bullets Widget for Elementor (Pro)</a></li>
167
- <li><a href="https://unlimited-elements.com/two-column-product-bullets-widget-for-elementor/">Product Highlights Widget for Elementor (Pro)</a> - Design a visually attractive product feature lists that will help your potential buyers to make purchase decision and learn more about your products. </li>
168
- <li><a href="https://unlimited-elements.com/whatsapp-chat-widget-for-elementor">Whatsapp Chat Widget for Elementor (Pro)</a> - A floating WhatsApp button that allows your website visitors to start a chat conversation from your website directly to your WhatsApp phone number with just one click.</li>
169
  <li><a href="https://unlimited-elements.com/icon-mobile-menu-for-elementor">Icon Mobile Menu Widget for Elementor (Pro)</a> - A perfect way to add an icon menu for making your CTA buttons stand out for website visitors using mobile devices.</li>
170
- <li><a href="https://unlimited-elements.com/step-process-widget-for-elementor">Step Process Widget for Elementor (Pro)</a> - Showcase process/steps with unique layout variations. Create visual diagrams of step by step instructions to simplify processes to your website visitors.</li>
171
- <li><a href="https://unlimited-elements.com/price-box-widget-for-elementor/">Price Box Widget for Elementor (Pro)</a></li>
172
  <li><a href="https://unlimited-elements.com/food-menu-carousel-widget-for-elementor">Product Carousel Widget for Elementor (Pro)</a></li>
 
173
  <li><a href="https://unlimited-elements.com/event-list-widget-for-elementor/">Event List Widget for Elementor (Pro)</a> - The event list widget is a way to easily show your recent events like concerts, conferences, parties or special occasions.
174
  </li>
175
  <li><a href="https://unlimited-elements.com/pricing-flip-box-widget-for-elementor/">Pricing Table Flip Box Widget for Elementor (Pro)</a> - The Pricing Table Flip Box allows you to showcase the prices for your products, services, or packages in a beautiful flip box pricing table.</li>
@@ -177,15 +181,16 @@ Fully compatible and integrated with Toolset custom post types and fields.
177
  <li><a href="https://unlimited-elements.com/card-testimonial-review-carousel-widget-for-elementor">Review Carousel Widget for Elementor (Pro)</a> - The Reviews Carousel increases the visibility reviews you want to highlight to your users by letting you display them throughout your site in an interactive carousel format. </li>
178
  <li><a href="https://unlimited-elements.com/timer-countdown-banner-widget-for-elementor">Timer Countdown Banner Widget for Elementor (Pro)</a> - An awesome countdown banner with a a call to action button.</li>
179
  <li><a href="https://unlimited-elements.com/google-maps-widget-for-elementor">Unlimited Google Maps Widget for Elementor (Pro)</a></li>
 
180
  <li><a href="https://unlimited-elements.com/copy-coupon-code-widget-for-elementor">Copy Coupon Code Widget for Elementor (Pro)</a> - Click to copy coupon code to the clipboard. This widgets makes it easy for users to redeem your promotions coupon codes.</li>
181
- <li><a href="https://unlimited-elements.com/mobile-conversion-menu-for-elementor">Mobile Conversion Menu Widget for Elementor (Pro)</a> - Floating action buttons that display the primary actions in your Elementor website. Provide quick access to social icons or any important or common actions to increase conversions.</li>
182
  </ol>
183
 
184
  <h3>Woocommerce for Elementor</h3>
185
  <ol>
186
  <li><a href="https://unlimited-elements.com/woocommerce-product-list-widget-for-elementor/">Woocommerce Product List Widget for Elementor (Free)</a></li>
187
- <li><a href="https://unlimited-elements.com/woocommerce-product-carousel-widget-for-elementor">Woocommerce Product Carousel Widget for Elementor (Pro)</a></li>
188
  <li><a href="https://unlimited-elements.com/woocommerce-product-slider-widget-for-elementor">Woocommerce Product Slider Widget for Elementor (Pro)</a></li>
 
189
  <li><a href="https://unlimited-elements.com/woocommerce-product-grid-widget-for-elementor/">Woocommerce Product Grid Widget for Elementor (Pro)</a></li>
190
  <li><a href="https://unlimited-elements.com/woocommerce-category-grid-for-elemenetor/">Woocommerce Category Grid Widget for Elementor (Pro)</a></li>
191
  <li><a href="https://unlimited-elements.com/woocommerce-category-carousel-widget-for-elementor/">Woocommerce Category Carousel Widget for Elementor (Pro)</a></li>
@@ -200,29 +205,11 @@ Fully compatible and integrated with Toolset custom post types and fields.
200
  <li><a href="https://unlimited-elements.com/dynamic-template-accordion-widget-for-elementor/">Dynamic Template Accordion Widget for Elementor (Pro)</a></li>
201
  </ol>
202
 
203
- <h3>Testimonials for Elementor</h3>
204
- <ol>
205
- <li><a href="https://unlimited-elements.com/box-testimonial-widget-for-elementor/">Testimonial Box Widget for Elementor (Free)</a></li>
206
- <li><a href="https://unlimited-elements.com/logo-card-testimonial-widget-for-elementor">Testimonial Card Widget for Elementor (Free)</a></li>
207
- <li><a href="https://unlimited-elements.com/testimonial-carousel-widget-for-elementor/">Testimonial Carousel Widget for Elementor (Pro)</a></li>
208
- <li><a href="https://unlimited-elements.com/3d-testimonial-card-carousel-widget-for-elementor">Testimonial Card Carousel Widget for Elementor (Pro)</a></li>
209
- </ol>
210
-
211
- <h3>Team Members for Elementor</h3>
212
- <ol>
213
- <li><a href="http://unlimited-elements.com/team-member-card-widget-for-elementor/">Team Member Card Widget for Elementor (Free)</a></li>
214
- <li><a href="https://unlimited-elements.com/team-member-box-overlay-widget-for-elementor">Team Member Box Widget for Elementor (Free)</a></li>
215
- <li><a href="http://unlimited-elements.com/team-member-carousel-widget-for-elementor/">Team Member Carousel Widget for Elementor (Pro)</a></li>
216
- <li><a href="https://unlimited-elements.com/icon-team-member-widget-for-elementor">Team Member Icon Effect Widget for Elementor (Pro)</a></li>
217
- <li><a href="http://unlimited-elements.com/team-member-grid-widget-for-elementor/">Team Member Grid Widget for Elementor (Pro)</a></li>
218
- <li><a href="https://unlimited-elements.com/sliding-effect-team-member-widget-for-elementor">Team Member Sliding Effect Widget for Elementor (Pro)</a></li>
219
- </ol>
220
-
221
  <h3>Menu Widgets for Elementor</h3>
222
  <ol>
223
  <li><a href="https://unlimited-elements.com/simple-fullscreen-navigation-menu-widget-for-elementor/">Fullscreen Navigation Menu Widget for Elementor (Free)</a></li>
224
  <li><a href="https://unlimited-elements.com/simple-list-menu-widget-for-elementor">List Menu Widget for Elementor (Free)</a></li>
225
- <li><a href="http://unlimited-elements.com/side-menu-widget-for-elementor">Side Menu Widget for Elementor (Pro)</a></li>
226
  <li><a href="https://unlimited-elements.com/liquid-fullscreen-menu-widget-for-elementor">Liquid Full Screen Menu Widget for Elementor (Pro)</a> - Code Credit:
227
  https://github.com/ykob/shape-overlays</li>
228
  <li><a href="https://unlimited-elements.com/one-page-scroll-navigation-widget-for-elementor">One Page Scroll Navigation Widget for Elementor (Pro)</a></li>
@@ -232,7 +219,7 @@ https://github.com/ykob/shape-overlays</li>
232
 
233
  <h3>Carousel Widgets for Elementor</h3>
234
  <ol>
235
- <li><a href="https://unlimited-elements.com/card-carousel-widget-for-elementor/">Card Carousel Widget for Elementor (Free)</a></li>
236
  <li><a href="https://unlimited-elements.com/coverflow-carousel-widget-for-elementor/">Coverflow Carousel Widget for Elementor (Pro)</a></li>
237
  <li><a href="https://unlimited-elements.com/icon-carousel-widget-for-elementor/">Icon Carousel Widget for Elementor (Pro)</a></li>
238
  <li><a href="https://unlimited-elements.com/image-card-carousel-widget-for-elementor">Image Card Carousel Widget for Elementor (Pro)</a></li>
@@ -243,6 +230,24 @@ https://github.com/ykob/shape-overlays</li>
243
  <li><a href="https://unlimited-elements.com/justified-image-carousel-widget-for-elementor/">Justified Image Carousel Widget for Elementor (Pro)</a></li>
244
  </ol>
245
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  <h3>Slider Widgets for Elementor</h3>
247
  <ol>
248
  <li><a href="https://unlimited-elements.com/simple-slider-widget-for-elementor/">Simple Slider Widget for Elementor (Free)</a></li>
@@ -252,10 +257,10 @@ https://github.com/ykob/shape-overlays</li>
252
 
253
  <h3>Content Boxes for Elementor</h3>
254
  <ol>
255
- <li><a href="https://unlimited-elements.com/image-zoom-content-box-widget-for-elementor/">Content Box Image Zoom Widget for Elementor (Free)</a></li>
256
- <li><a href="https://unlimited-elements.com/image-card-content-box-widget-for-elementor/">Content Box Image Card Widget for Elementor (Free)</a></li>
257
  <li><a href="https://unlimited-elements.com/hover-text-reveal-content-box-widget-for-elementor/">Content Box Hover Text Reveal Widget for Elementor (Free)</a></li>
258
- <li><a href="https://unlimited-elements.com/icon-image-content-box-widget-for-elementor">Content Box Icon Image Widget for Elementor (Free)</a></li>
259
  <li><a href="https://unlimited-elements.com/icon-content-box-widget-for-elementor">Icon Content Box Widget for Elementor (Free)</a></li>
260
  <li><a href="https://unlimited-elements.com/zoom-caption-reveal-content-box-widget-for-elementor">Content Box Zoom Caption Reveal Widget for Elementor (Pro)</a></li>
261
  <li><a href="https://unlimited-elements.com/subtle-overlay-content-box-widget-for-elementor/">Content Box Overlay Widget for Elementor (Pro)</a></li>
@@ -295,22 +300,23 @@ https://github.com/ykob/shape-overlays</li>
295
  <h3>Button Widgets for Elementor</h3>
296
  <ol>
297
  <li><a href="https://unlimited-elements.com/video-play-button-popup-widget-for-elementor/">Video Play Button Widget for Elementor (Free)</a></li>
 
 
 
298
  <li><a href="https://unlimited-elements.com/toggle-text-button-widget-for-elementor/">Toggle Text Button Widget for Elementor (Free)</a></li>
299
  <li><a href="https://unlimited-elements.com/parellogram-button-widget-for-elementor/">Parallelogram Button Widget for Elementor (Free)</a></li>
300
- <li><a href="https://unlimited-elements.com/gradient-button-widget-for-elementor/">Gradient Button Widget for Elementor (Free)</a></li>
301
- <li><a href="https://unlimited-elements.com/overlay-button-widget-for-elementor/">Overlay Button Widget for Elementor (Free)</a></li>
302
  <li><a href="https://unlimited-elements.com/icon-pointer-button-widget-for-elementor/">Icon Pointer Button Widget for Elementor (Free)</a></li>
303
- <li><a href="https://unlimited-elements.com/multi-line-button-widget-for-elementor/">Multi Line Button Widget for Elementor (Free)</a></li>
304
- <li><a href="https://unlimited-elements.com/underline-animated-button-widget-for-elementor/">Underline Animated Button Widget for Elementor (Free)</a></li>
305
- <li><a href="https://unlimited-elements.com/button-group-widget-for-elementor/">Button Group Widget for Elementor (Free)</a></li>
306
- <li><a href="https://unlimited-elements.com/simple-artistic-button-widget-for-elementor/">Simple Artistic Button Widget for Elementor (Pro)</a></li>
307
- <li><a href="https://unlimited-elements.com/neon-glowing-button-effect-widget-for-elementor/">Neon Glowing Button Effect Widget for Elementor (Pro)</a></li>
308
  <li><a href="https://unlimited-elements.com/border-button-effect-widget-for-elementor/">Border Button Effect Widget for Elementor (Pro)</a></li>
309
- <li><a href="https://unlimited-elements.com/liquid-button-widget-for-elementor/">Liquid Button Widget for Elementor (Pro)</a></li>
310
  <li><a href="https://unlimited-elements.com/gradient-hover-effect-button-widget-for-elementor/">Gradient Hover Effect Button Widget for Elementor (Pro)</a></li>
311
- <li><a href="https://unlimited-elements.com/glare-effect-button-widget-for-elementor/">Glare Button Effect Widget for Elementor (Pro)</a></li>
 
 
312
  <li><a href="http://unlimited-elements.com/underline-link-hover-effect-widget-for-elementor">Underline Link Hover Effect Widget for Elementor (Pro)</a></li>
313
- <li><a href="https://unlimited-elements.com/icon-hover-effect-button-widget-for-elementor/">Button Icon Hover Effect Widget for Elementor (Pro)</a></li>
314
  </ol>
315
 
316
  <h3>Typography for Elementor</h3>
@@ -329,6 +335,7 @@ https://github.com/ykob/shape-overlays</li>
329
  <li><a href="https://unlimited-elements.com/image-background-text-effect-widget-for-elementor/">Image Background Text Effect Widget for Elementor (Pro)</a></li>
330
  <li><a href="https://unlimited-elements.com/typewriter-text-effect-for-elementor/">Typewriter Text Effect Widget for Elementor (Pro)</a></li>
331
  <li><a href="https://unlimited-elements.com/side-line-heading-widget-for-elementor/">Side Line Heading Widget for Elementor (Pro)</a></li>
 
332
  </ol>
333
 
334
  <h3>Content Widgets for Elementor</h3>
@@ -418,6 +425,7 @@ https://github.com/ykob/shape-overlays</li>
418
  <li><a href="https://unlimited-elements.com/separator-and-dividers-widgets-for-elementor/">Three Icons Separator Widget for Elementor (Pro)</a></li>
419
  <li><a href="https://unlimited-elements.com/separator-and-dividers-widgets-for-elementor/">Christmas Candy Separator Widget for Elementor (Pro)</a></li>
420
  <li><a href="https://unlimited-elements.com/separator-and-dividers-widgets-for-elementor/">Animated Wave Separator Widget for Elementor (Pro)</a></li>
 
421
  </ol>
422
 
423
  <h3>Google Charts for Elementor</h3>
@@ -445,6 +453,15 @@ https://github.com/ykob/shape-overlays</li>
445
  <li><a href="https://unlimited-elements.com/solid-color-hero-widget-for-elementor">Solid Color Hero Widget for Elementor (Pro)</a></li>
446
  </ol>
447
 
 
 
 
 
 
 
 
 
 
448
 
449
 
450
 
@@ -459,29 +476,98 @@ Note : This plugin works with Elementor. Make sure you have [Elementor](https://
459
 
460
  == Changelog ==
461
 
462
- version 1.4.86 = 2021-11-08:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
 
464
- -Fix: fixed gutenberg support in widgets
465
- -Fix: fixed all the pagination issues in archive page
466
 
467
 
468
  version 1.4.86 = 2021-11-01:
469
 
470
- -Fix: fixed some load more last issues
471
- -Feature: added code for taxonomy terms filter
472
- -Feature: added code for checkbox filter
473
 
474
 
475
  version 1.4.86 = 2021-10-29:
476
 
477
- -Feature: improved current query debug - full type
478
- -Feature: added dropdown responsive placeholders
479
- -Feature: added radio boolean attribute responsive controls
480
 
481
- -Fix: fixed controls tabs functionality
482
- -Fix: fixed load more custom image bug
483
- -Fix: fixed double load more in a page mishmash bug
484
- -Fix: fixed all load more issues
485
 
486
 
487
  version 1.4.85 = 2021-10-13:
@@ -490,46 +576,46 @@ version 1.4.85 = 2021-10-13:
490
 
491
  version 1.4.84 = 2021-10-13:
492
 
493
- -Feature: added taxonomy terms full query debug option
494
- -Feature: improved full debug type in posts query
495
- -Feature: added items support in editor->background switcher
496
- -Feature: added support for remote controls
497
- -Feature: functionality to posts load more
498
- -Feature: added second condition
499
- -Feature: added tabs functionality to attributes
500
- -Addition: added %,px to slider units
501
- -Fix: fixed avoid duplicates related bug
502
- -Fix: fixed conflicting wordpress codemirror script
503
- -Fix: fixed post selection values init from editor
504
- -Fix: fixed pagination on front page
505
- -Fix: fixed some polylang related bugs
506
 
507
 
508
  version 1.4.83 = 2021-09-22:
509
 
510
- -Fix: fixed styles mishmash inside elementor editor navigator
511
- -Fix: fixed dissapearing carousels after refresh bug
512
- -Fix: fixed dynamic grid pagination not changed
513
 
514
 
515
  version 1.4.82 = 2021-09-20:
516
 
517
- -Feature: added troubleshooting setting - show php error message
518
- -Feature: added px, vh, % options for slider attribute
519
- -Feature: added dynamic group attributes for galleries, including image and video
520
- -Feature: added option to convert one date string to another with ucdate filter
521
- -Feature: added option to use items in background widgets
522
- -Feature: added ucfunc("set") and ucfunc("get") functions in twig for remember and retrieve variables
523
- -Feature: added include by option: "children of current term" to category selection options
524
- -Feature: added option to pull woo product variations in twig
525
- -Feature: added placeholder: link_withprefix, link_noprefix for link attribute
526
- -Fix: fixed error when exists dynamic link in dynamic loop widgets
527
- -Fix: enabled pagination in a single type in dynamic template grid
528
- -Fix: the "not equal" attributes condition now works
529
- -Fix: fixed not editable empty dropdown attribute in widget editor
530
- -Fix: fixed mb_string absence php bug
531
- -Fix: fixed heading attribute label
532
- -Fix: fixed responsive elementor controls in widget items
533
 
534
 
535
 
@@ -1138,8 +1224,8 @@ version 1.4.11 - 2019-07-10 =
1138
  version 1.4.10 - 2019-28-9 =
1139
 
1140
  -bug fix: added some front end protection against db not installed bug
1141
- -feature(pro): added do_action for custom wp actions run
1142
- -feature(pro): added apply_filters for custom wp actions run
1143
  -bug fix: fixed export widget with assets path
1144
  -change: added instructions to download pro version.
1145
 
3
  Donate link: http://unlimited-elements.com/
4
  Tags: elementor, elements, addons, elementor addons, elementor widget, page builder, builder, visual editor, wordpress page builder, elementor
5
  Requires at least: 3.5
6
+ Tested up to: 5.8.2
7
  Stable tag: 1.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
  The best package of Free Elementor Addons. +100 Free Elementor Widgets, +10 Free Animated Backgrounds, +30 Free Elementor Templates, WooCommerce Widgets, Full Screen Menu Addons, Testimonial Slider, Post Grid, Carousel Widgets, Event Widgets, Button Effects for Elementor, Instagram Addons, Icon Boxes, Flipbox, Image Accordion, Timeline Widget, Video Galleries Dynamic Loop Builder, Whatsapp Chat, Price List Addons. Including the one and only Widget Creator Elementor Website Builder and Editor for Elementor to create custom.
12
 
13
+
14
  == Description ==
15
 
16
 
93
  <h3>Creative Widgets for Elementor</h3>
94
  <ol>
95
  <li><a href="https://unlimited-elements.com/blob-shape-widget-for-elementor/">Blob Shapes Widget for Elementor (Free)</a> - Create Blob Shapes with animated morphing effects. This free Elementor widget will help you make your images into random, unique, and organic-looking blob shapes. </li>
 
 
 
 
 
96
  <li><a href="https://unlimited-elements.com/number-box-widget-widget-for-elementor/">Number Box Widget for Elementor (Free)</a> - Create stunning number blocks with various styles. The Number Box widget for Elementor helps you display content for step by step diagrams and instructions.</li>
 
 
97
  <li><a href="https://unlimited-elements.com/animated-mouse-scroll-icon-widget-for-elementor/">Animated Mouse Scroll Icon Widget for Elementor (Free)</a> - The Animated Mouse Scroll Icon is a small micro animation that indicates to user they needs to scroll the page. You can make the icon an anchor point which scroll down to any section when clicked on.
98
  </li>
99
+ <li><a href="https://unlimited-elements.com/svg-animation-widget-for-elementor">SVG Animation Widget for Elementor (Free)</a> - The SVG animation widget for Elementor makes it easy -to create impressive SVG animations for your websitet, without any coding skills just copy paste your SVG code and your animated icon is ready.</li>
100
+ <li><a href="https://unlimited-elements.com/material-bullets-widget-for-elementor">Material Bullets Widget for Elementor (Free)</a> - Display feature lists with custom icons and styles. Each list item can have its own icon title and text. Use the bullets widget to display features and highlights on your Elementor website.</li>
101
+ <li><a href="https://unlimited-elements.com/animated-hamburger-icon-for-elementor/">Animated Hamburger Icon Widget for Elementor (Free)</a> - Use the animated hamburger icon widget to toggle Elementor pro popus. You can even put a menu in a popup and create a full screen menu.</li>
102
+ <li><a href="https://unlimited-elements.com/timeline-bullets-widget-for-elementor/">Timeline Bullets Widget for Elementor (Free)</a> - List your features or services using bullet points in a timeline layout to make it easier for users to read the important information.</li>
103
+ <li><a href="https://unlimited-elements.com/lordicon-animated-icons-widget-for-elementor/">Lordicon: Animated Icons Widget for Elementor (Free)</a> - The most powerful animated icon library with 1500+ free and premium animated Lottie animations.</li>
104
+ <li><a href="https://unlimited-elements.com/flip-box-widget-for-elementor/">Flip Box Widget for Elementor (Free)</a> - Make your content more interesting with the Elementor Flip Box widget. Use the animated Flip Boxes to highlight any content inside your page with a flip effect.</li>
105
+ <li><a href="https://unlimited-elements.com/image-tooltip-widget-for-elementor/">Image Tooltip Widget for Elementor (Free)</a> - The easiest way to set a tooltip to any Image on the page with a short text description or any HTML code.</li>
106
  <li><a href="https://unlimited-elements.com/icon-accordion-widget-for-elementor/">Icon Accordion Widget for Elementor (Pro)</a> - Advanced accordion addon for Elementor page builder offers multiple styles to create interactive collapsable content with multiple layouts on your page.</li>
107
+ <li><a href="https://unlimited-elements.com/image-reveal-on-scroll-widget-for-elementor">Image Reveal On Scroll Widget for Elementor (Pro)</a> - The Image Reveal on Scroll widget adds an awesome reveal on scroll effect to your images to spice up your Elementor website design.</li>
108
  <li><a href="https://unlimited-elements.com/image-shapes-for-elementor-page-builder/">Image Shapes Widget for Elementor (Pro)</a> - The Image Shapes Elementor Widget allows you to make complex shape addons by clipping images using CSS to make various element layouts: circle, ellipse, polygon and more.</li>
109
  <li><a href="https://unlimited-elements.com/image-particle-widget-for-elementor/">Particle Image Widget for Elementor (Pro)</a> - Create a dispersion interactive mouse aware distortion effect for any image using the Particle Image widget for Elementor.</li>
110
  <li><a href="https://unlimited-elements.com/image-zoom-magnifier-widget-for-elementor/">Image Zoom Magnifier Widget for Elementor (Pro)</a> - Image Zoom Magnifier is a Elmentor Widget for creating a direction-aware magnifying glass effect to provide an inner zoom functionality on any given image. Enlarge images on touch, click, or mouseover.</li>
111
  <li><a href="https://unlimited-elements.com/background-switcher-widget-for-elementor/">Background Switcher Widget for Elementor (Pro)</a> - The background switcher addon lets you set up cool content boxes. When you hover over a box it will change the background for the whole section. </li>
112
+ <li><a href="https://unlimited-elements.com/icon-tabs-widget-for-elementor">Icon Tabs Widget for Elementor (Pro)</a> - The Tab Widget for Elementor will help you show your text on your page divided into horizontal or vertical tabs. Customize your tabs using icons and make the content on your website interactive and fun to read.</li>
113
  <li><a href="https://unlimited-elements.com/audio-player-widget-for-elementor/">Audio Player Widget for Elementor (Pro)</a> - MP3 Music Player is a very easy to use Audio Player for Elementor. It gives you the ability to add unlimited audio tracks to any page using our Elementor addon let users listen to music on your website. </li>
114
+ <li><a href="https://unlimited-elements.com/before-after-image-comparison-widget-for-elementor/">Before After Widget for Elementor (Pro)</a> - The Before After widget is an image comparison addon for Elementor. This widget allows you to create the effect for comparing two before and after images.</li>
115
  <li><a href="https://unlimited-elements.com/hotspots-for-elementor-page-builder/">Hotspots Widget for Elementor (Pro)</a> - Add hotspots to your images with a tooltip an option for opening a built in popup. Each hotspot popup can contain and image and description text.</li>
 
116
  <li><a href="https://unlimited-elements.com/image-accordion-widget-for-elementor/">Image Accordion Widget for Elementor (Pro)</a> - Our image accordion addon for Elementor highlights your images with amazing hover effects and interactive layouts.</li>
117
  <li><a href="https://unlimited-elements.com/shape-bullets-widget-for-elementor/">Shape Bullets Widget for Elementor (Pro)</a> - The Shape Bullets Widget for Elementor, creates an easy-to-manage bulleted list of items. Each item can be highlighted by its own icon.
118
  </li>
119
+ <li><a href="https://unlimited-elements.com/audio-playlist-widget-for-elementor">Audio Playlist Widget for Elementor (Pro)</a> - Create MP3 Audio Playlists inside of Elementor. Use this widget to add the ability to create unlimited numbers of playlists, albums, and audio tracks.</li>
120
+ <li><a href="https://unlimited-elements.com/interactive-circle-infographic-widget-for-elementor/">Interactive Circle Infographic Widget for Elementor (Pro)</a> - The Circle Infographic widget for Elementor is a simple and engaging way to present data, processes, concepts, structures and more. Helps your audience understand an entire cycle using a circular interactive tab layout.
121
+
122
+ </li>
123
+ <li><a href="https://unlimited-elements.com/flip-box-carousel-widget-for-elementor/">Flip Box Carousel Widget for Elementor (Pro)</a></li>
124
+ <li><a href="https://unlimited-elements.com/christmas-icons-widget-for-elementor/">Christmas Icons Widget for Elementor (Pro)</a></li>
125
  </ol>
126
 
127
  <h3>Post Widgets for Elementor</h3>
128
  <ol>
129
+ <li><a href="https://unlimited-elements.com/post-tabs-for-elementor/">Post Tabs Widget for Elementor (Free)</a></li>
130
+ <li><a href="https://unlimited-elements.com/post-accordions-for-elementor/">Post Accordion Widget for Elementor (Free)</a></li>
131
  <li><a href="https://unlimited-elements.com/post-blocks-widget-for-elementor">Post Blocks Widget for Elementor (Free)</a></li>
132
  <li><a href="https://unlimited-elements.com/post-list-widget-for-elementor">Post List Widget for Elementor (Free)</a></li>
 
133
  <li><a href="https://unlimited-elements.com/post-news-ticker-widget-for-elementor">Post Ticker Widget for Elementor (Free)</a></li>
 
134
  <li><a href="https://unlimited-elements.com/card-post-carousel-widget-for-elementor">Card Post Carousel Widget for Elementor (Free)</a></li>
135
+ <li><a href="https://unlimited-elements.com/post-pagination-widget-for-elementor/">Post Pagination Widget for Elementor (Free)</a></li>
 
136
  <li><a href="https://unlimited-elements.com/post-gallery-widget-for-elementor">Post Gallery Widget for Elementor (Pro)</a></li>
137
  <li><a href="https://unlimited-elements.com/elementor-author-list-widget/">Author List Widget for Elementor (Pro)</a></li>
138
  <li><a href="https://unlimited-elements.com/masonry-post-grid-widget-for-elementor">Masonry Post Grid Widget for Elementor (Pro)</a></li>
139
  <li><a href="https://unlimited-elements.com/taxonomy-terms-widget-for-elementor/">Taxonomy Terms Widget for Elementor (Pro)</a></li>
140
  <li><a href="https://unlimited-elements.com/post-tiles-widget-for-elementor">Post Tile Widget for Elementor (Pro)</a></li>
141
+ <li><a href="https://unlimited-elements.com/post-magazine-grid-widget-for-elementor/">Post Magazine Grid Widget for Elementor (Pro)</a></li>
 
142
  <li><a href="https://unlimited-elements.com/post-sliders/">Post Slider Widget for Elementor (Pro)</a></li>
143
+ <li><a href="https://unlimited-elements.com/blog-card-slider-widget-for-elementor">Post Card Slider Widget for Elementor (Pro)</a></li>
144
+ <li><a href="https://unlimited-elements.com/load-more-infinite-scroll-widget-for-elementor/">Load More / Infinite Scroll Widget for Elementor (Pro)</a> - Add a load more button to your post or product grids. You can even make an infinite scroll effect that works with AJAX.</li>
145
  <li><a href="https://unlimited-elements.com/post-carousels-for-elementor/">Post Carousel Widget for Elementor (Pro)</a></li>
146
+ <li><a href="https://unlimited-elements.com/post-timeline-widget-for-elementor/">Post Timeline Widget for Elementor (Pro)</a></li>
147
  <li><a href="https://unlimited-elements.com/post-scroll-widget-for-elementor">Post Scroll Widget for Elementor (Pro)</a></li>
148
  <li><a href="https://unlimited-elements.com/post-grid">Post Grid Widget for Elementor (Pro)</a></li>
149
  <li><a href="https://unlimited-elements.com/post-horizontal-timeline-widget-for-elementor/">Post Horizontal Timeline Widget for Elementor (Pro)</a></li>
152
  <h3>Marketing Widgets for Elementor</h3>
153
  <ol>
154
  <li><a href="https://unlimited-elements.com/unlimited-timeline-widget-for-elementor">Unlimited Timeline Widget for Elementor (Free)</a> - Showcase your story or company history in a vertical timeline layout using the powerful Unlimited Timeline addon for Elementor.</li>
155
+ <li><a href="https://unlimited-elements.com/notification-widget-for-elementor">Notification Widget for Elementor (Free)</a> - The Notification widget enables you to display a colored alert box and draw attention to important messages on your Elementor website.</li>
156
  <li><a href="https://unlimited-elements.com/overlay-product-box-widget-for-elementor/">Overlay Product Box Widget for Elementor (Free)</a></li>
157
  <li><a href="https://unlimited-elements.com/business-hours-widget-for-elementor">Business Hours Widget for Elementor (Free)</a></li>
158
  <li><a href="https://unlimited-elements.com/timer-countdowns-for-elementor-page-builder/">Timer Countdown Widget for Elementor (Free)</a> - Instantly create a beautiful, animated countdown clock addon, to share on your Elementor website. Count down to a date with your own unique timer.
159
 
160
  </li>
161
  <li><a href="https://unlimited-elements.com/call-to-action-button-widget-for-elementor/">Call To Action Button Widget for Elementor (Free)</a> - The Call to Action Button Widget is a tool for creating beautiful buttons that combine an icon, some text, and message notification.</li>
 
162
  <li><a href="https://unlimited-elements.com/price-list-widget-for-elementor/">Price List Widget for Elementor (Free)</a> - A powerful addon that allows displaying a list of items, products, services or features for your business with easy styling options.</li>
163
+ <li><a href="https://unlimited-elements.com/event-box-widget-for-elementor">Event Box Widget for Elementor (Free)</a> - Showcase events & special occasions on your websites using this unique Elementor addon.</li>
164
+ <li><a href="https://unlimited-elements.com/statistic-counters-for-elementor">Counter Widget for Elementor (Free)</a> - Showcasing your business statistics and show fun facts and figures on your Elementor website.</li>
 
 
165
  <li><a href="https://unlimited-elements.com/pricing-table-widget-for-elementor/">Pricing Table Widget for Elementor (Free)</a> - Present the available pricing plans in an easy to read format. Use the Pricing Table widget to help your customers make purchasing decisions.</li>
166
+ <li><a href="http://unlimited-elements.com/food-menu-box-widget-for-elementor/">Product Card Widget for Elementor (Free)</a></li>
167
+ <li><a href="https://unlimited-elements.com/list-widget-for-elementor/">List Widget for Elementor (Free)</a> - Create styled ordered and unordered lists easily. The ordered list will add index numbers automatically to your list items.</li>
168
+ <li><a href="https://unlimited-elements.com/review-box-widget-for-elementor">Review Box Widget for Elementor (Free)</a> - Simply create and display reviews on your Elementor website to build customers� trust and increase SEO.</li>
169
+ <li><a href="https://unlimited-elements.com/price-label-product-box-widget-for-elementor/">Product Box Widget for Elementor (Free)</a></li>
170
  <li><a href="https://unlimited-elements.com/product-bullets-widget-for-elementor">Product Bullets Widget for Elementor (Pro)</a></li>
171
+ <li><a href="https://unlimited-elements.com/whatsapp-chat-widget-for-elementor">WhatsApp Chat Widget for Elementor (Pro)</a> - A floating WhatsApp button that allows your website visitors to start a chat conversation from your website directly to your WhatsApp phone number with just one click.</li>
172
+ <li><a href="https://unlimited-elements.com/mobile-conversion-menu-for-elementor">Mobile Conversion Menu Widget for Elementor (Pro)</a> - Floating action buttons that display the primary actions in your Elementor website. Provide quick access to social icons or any important or common actions to increase conversions.</li>
173
  <li><a href="https://unlimited-elements.com/icon-mobile-menu-for-elementor">Icon Mobile Menu Widget for Elementor (Pro)</a> - A perfect way to add an icon menu for making your CTA buttons stand out for website visitors using mobile devices.</li>
174
+ <li><a href="https://unlimited-elements.com/memory-game-widget-for-elementor">Memory Game Widget for Elementor (Pro)</a></li>
 
175
  <li><a href="https://unlimited-elements.com/food-menu-carousel-widget-for-elementor">Product Carousel Widget for Elementor (Pro)</a></li>
176
+ <li><a href="https://unlimited-elements.com/step-process-widget-for-elementor">Step Process Widget for Elementor (Pro)</a> - Showcase process/steps with unique layout variations. Create visual diagrams of step by step instructions to simplify processes to your website visitors.</li>
177
  <li><a href="https://unlimited-elements.com/event-list-widget-for-elementor/">Event List Widget for Elementor (Pro)</a> - The event list widget is a way to easily show your recent events like concerts, conferences, parties or special occasions.
178
  </li>
179
  <li><a href="https://unlimited-elements.com/pricing-flip-box-widget-for-elementor/">Pricing Table Flip Box Widget for Elementor (Pro)</a> - The Pricing Table Flip Box allows you to showcase the prices for your products, services, or packages in a beautiful flip box pricing table.</li>
181
  <li><a href="https://unlimited-elements.com/card-testimonial-review-carousel-widget-for-elementor">Review Carousel Widget for Elementor (Pro)</a> - The Reviews Carousel increases the visibility reviews you want to highlight to your users by letting you display them throughout your site in an interactive carousel format. </li>
182
  <li><a href="https://unlimited-elements.com/timer-countdown-banner-widget-for-elementor">Timer Countdown Banner Widget for Elementor (Pro)</a> - An awesome countdown banner with a a call to action button.</li>
183
  <li><a href="https://unlimited-elements.com/google-maps-widget-for-elementor">Unlimited Google Maps Widget for Elementor (Pro)</a></li>
184
+ <li><a href="https://unlimited-elements.com/two-column-product-bullets-widget-for-elementor/">Product Highlights Widget for Elementor (Pro)</a> - Design a visually attractive product feature lists that will help your potential buyers to make purchase decision and learn more about your products. </li>
185
  <li><a href="https://unlimited-elements.com/copy-coupon-code-widget-for-elementor">Copy Coupon Code Widget for Elementor (Pro)</a> - Click to copy coupon code to the clipboard. This widgets makes it easy for users to redeem your promotions coupon codes.</li>
186
+ <li><a href="https://unlimited-elements.com/price-box-widget-for-elementor/">Price Box Widget for Elementor (Pro)</a></li>
187
  </ol>
188
 
189
  <h3>Woocommerce for Elementor</h3>
190
  <ol>
191
  <li><a href="https://unlimited-elements.com/woocommerce-product-list-widget-for-elementor/">Woocommerce Product List Widget for Elementor (Free)</a></li>
 
192
  <li><a href="https://unlimited-elements.com/woocommerce-product-slider-widget-for-elementor">Woocommerce Product Slider Widget for Elementor (Pro)</a></li>
193
+ <li><a href="https://unlimited-elements.com/woocommerce-product-carousel-widget-for-elementor">Woocommerce Product Carousel Widget for Elementor (Pro)</a></li>
194
  <li><a href="https://unlimited-elements.com/woocommerce-product-grid-widget-for-elementor/">Woocommerce Product Grid Widget for Elementor (Pro)</a></li>
195
  <li><a href="https://unlimited-elements.com/woocommerce-category-grid-for-elemenetor/">Woocommerce Category Grid Widget for Elementor (Pro)</a></li>
196
  <li><a href="https://unlimited-elements.com/woocommerce-category-carousel-widget-for-elementor/">Woocommerce Category Carousel Widget for Elementor (Pro)</a></li>
205
  <li><a href="https://unlimited-elements.com/dynamic-template-accordion-widget-for-elementor/">Dynamic Template Accordion Widget for Elementor (Pro)</a></li>
206
  </ol>
207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  <h3>Menu Widgets for Elementor</h3>
209
  <ol>
210
  <li><a href="https://unlimited-elements.com/simple-fullscreen-navigation-menu-widget-for-elementor/">Fullscreen Navigation Menu Widget for Elementor (Free)</a></li>
211
  <li><a href="https://unlimited-elements.com/simple-list-menu-widget-for-elementor">List Menu Widget for Elementor (Free)</a></li>
212
+ <li><a href="http://unlimited-elements.com/side-menu-widget-for-elementor">Side Menu Widget for Elementor (Pro)</a> - Off Canvas sidebar with a WordPress menu inside that can include icon links and a search bar. Use the toggle button to open the side menu and the close icon to close it.</li>
213
  <li><a href="https://unlimited-elements.com/liquid-fullscreen-menu-widget-for-elementor">Liquid Full Screen Menu Widget for Elementor (Pro)</a> - Code Credit:
214
  https://github.com/ykob/shape-overlays</li>
215
  <li><a href="https://unlimited-elements.com/one-page-scroll-navigation-widget-for-elementor">One Page Scroll Navigation Widget for Elementor (Pro)</a></li>
219
 
220
  <h3>Carousel Widgets for Elementor</h3>
221
  <ol>
222
+ <li><a href="https://unlimited-elements.com/card-carousel-widget-for-elementor/">Card Carousel Widget for Elementor (Free)</a> - Use the card carousel widget to display two or more pieces of content in a carousel format. Create any kind of carousel you can think about.</li>
223
  <li><a href="https://unlimited-elements.com/coverflow-carousel-widget-for-elementor/">Coverflow Carousel Widget for Elementor (Pro)</a></li>
224
  <li><a href="https://unlimited-elements.com/icon-carousel-widget-for-elementor/">Icon Carousel Widget for Elementor (Pro)</a></li>
225
  <li><a href="https://unlimited-elements.com/image-card-carousel-widget-for-elementor">Image Card Carousel Widget for Elementor (Pro)</a></li>
230
  <li><a href="https://unlimited-elements.com/justified-image-carousel-widget-for-elementor/">Justified Image Carousel Widget for Elementor (Pro)</a></li>
231
  </ol>
232
 
233
+ <h3>Testimonials for Elementor</h3>
234
+ <ol>
235
+ <li><a href="https://unlimited-elements.com/box-testimonial-widget-for-elementor/">Testimonial Box Widget for Elementor (Free)</a></li>
236
+ <li><a href="https://unlimited-elements.com/logo-card-testimonial-widget-for-elementor">Testimonial Card Widget for Elementor (Free)</a></li>
237
+ <li><a href="https://unlimited-elements.com/testimonial-carousel-widget-for-elementor/">Testimonial Carousel Widget for Elementor (Pro)</a></li>
238
+ <li><a href="https://unlimited-elements.com/3d-testimonial-card-carousel-widget-for-elementor">Testimonial Card Carousel Widget for Elementor (Pro)</a></li>
239
+ </ol>
240
+
241
+ <h3>Team Members for Elementor</h3>
242
+ <ol>
243
+ <li><a href="http://unlimited-elements.com/team-member-card-widget-for-elementor/">Team Member Card Widget for Elementor (Free)</a></li>
244
+ <li><a href="https://unlimited-elements.com/team-member-box-overlay-widget-for-elementor">Team Member Box Widget for Elementor (Free)</a></li>
245
+ <li><a href="http://unlimited-elements.com/team-member-carousel-widget-for-elementor/">Team Member Carousel Widget for Elementor (Pro)</a></li>
246
+ <li><a href="https://unlimited-elements.com/icon-team-member-widget-for-elementor">Team Member Icon Effect Widget for Elementor (Pro)</a></li>
247
+ <li><a href="http://unlimited-elements.com/team-member-grid-widget-for-elementor/">Team Member Grid Widget for Elementor (Pro)</a></li>
248
+ <li><a href="https://unlimited-elements.com/sliding-effect-team-member-widget-for-elementor">Team Member Sliding Effect Widget for Elementor (Pro)</a></li>
249
+ </ol>
250
+
251
  <h3>Slider Widgets for Elementor</h3>
252
  <ol>
253
  <li><a href="https://unlimited-elements.com/simple-slider-widget-for-elementor/">Simple Slider Widget for Elementor (Free)</a></li>
257
 
258
  <h3>Content Boxes for Elementor</h3>
259
  <ol>
260
+ <li><a href="https://unlimited-elements.com/image-zoom-content-box-widget-for-elementor/">Image Zoom Content Box Widget for Elementor (Free)</a></li>
261
+ <li><a href="https://unlimited-elements.com/image-card-content-box-widget-for-elementor/">Image Card Widget for Elementor (Free)</a></li>
262
  <li><a href="https://unlimited-elements.com/hover-text-reveal-content-box-widget-for-elementor/">Content Box Hover Text Reveal Widget for Elementor (Free)</a></li>
263
+ <li><a href="https://unlimited-elements.com/icon-image-content-box-widget-for-elementor">Icon Image Content Box Widget for Elementor (Free)</a></li>
264
  <li><a href="https://unlimited-elements.com/icon-content-box-widget-for-elementor">Icon Content Box Widget for Elementor (Free)</a></li>
265
  <li><a href="https://unlimited-elements.com/zoom-caption-reveal-content-box-widget-for-elementor">Content Box Zoom Caption Reveal Widget for Elementor (Pro)</a></li>
266
  <li><a href="https://unlimited-elements.com/subtle-overlay-content-box-widget-for-elementor/">Content Box Overlay Widget for Elementor (Pro)</a></li>
300
  <h3>Button Widgets for Elementor</h3>
301
  <ol>
302
  <li><a href="https://unlimited-elements.com/video-play-button-popup-widget-for-elementor/">Video Play Button Widget for Elementor (Free)</a></li>
303
+ <li><a href="https://unlimited-elements.com/button-group-widget-for-elementor/">Button Group Widget for Elementor (Free)</a></li>
304
+ <li><a href="https://unlimited-elements.com/underline-animated-button-widget-for-elementor/">Underline Animated Button Widget for Elementor (Free)</a></li>
305
+ <li><a href="https://unlimited-elements.com/multi-line-button-widget-for-elementor/">Multi Line Button Widget for Elementor (Free)</a></li>
306
  <li><a href="https://unlimited-elements.com/toggle-text-button-widget-for-elementor/">Toggle Text Button Widget for Elementor (Free)</a></li>
307
  <li><a href="https://unlimited-elements.com/parellogram-button-widget-for-elementor/">Parallelogram Button Widget for Elementor (Free)</a></li>
 
 
308
  <li><a href="https://unlimited-elements.com/icon-pointer-button-widget-for-elementor/">Icon Pointer Button Widget for Elementor (Free)</a></li>
309
+ <li><a href="https://unlimited-elements.com/overlay-button-widget-for-elementor/">Overlay Button Widget for Elementor (Free)</a></li>
310
+ <li><a href="https://unlimited-elements.com/gradient-button-widget-for-elementor/">Gradient Button Widget for Elementor (Free)</a></li>
311
+ <li><a href="https://unlimited-elements.com/glare-effect-button-widget-for-elementor/">Glare Button Effect Widget for Elementor (Pro)</a></li>
312
+ <li><a href="https://unlimited-elements.com/icon-hover-effect-button-widget-for-elementor/">Button Icon Hover Effect Widget for Elementor (Pro)</a></li>
 
313
  <li><a href="https://unlimited-elements.com/border-button-effect-widget-for-elementor/">Border Button Effect Widget for Elementor (Pro)</a></li>
 
314
  <li><a href="https://unlimited-elements.com/gradient-hover-effect-button-widget-for-elementor/">Gradient Hover Effect Button Widget for Elementor (Pro)</a></li>
315
+ <li><a href="https://unlimited-elements.com/liquid-button-widget-for-elementor/">Liquid Button Widget for Elementor (Pro)</a></li>
316
+ <li><a href="https://unlimited-elements.com/neon-glowing-button-effect-widget-for-elementor/">Neon Glowing Button Effect Widget for Elementor (Pro)</a></li>
317
+ <li><a href="https://unlimited-elements.com/simple-artistic-button-widget-for-elementor/">Simple Artistic Button Widget for Elementor (Pro)</a></li>
318
  <li><a href="http://unlimited-elements.com/underline-link-hover-effect-widget-for-elementor">Underline Link Hover Effect Widget for Elementor (Pro)</a></li>
319
+ <li><a href="https://unlimited-elements.com/christmas-button-widget-for-elementor">Christmas Button Widget for Elementor (Pro)</a></li>
320
  </ol>
321
 
322
  <h3>Typography for Elementor</h3>
335
  <li><a href="https://unlimited-elements.com/image-background-text-effect-widget-for-elementor/">Image Background Text Effect Widget for Elementor (Pro)</a></li>
336
  <li><a href="https://unlimited-elements.com/typewriter-text-effect-for-elementor/">Typewriter Text Effect Widget for Elementor (Pro)</a></li>
337
  <li><a href="https://unlimited-elements.com/side-line-heading-widget-for-elementor/">Side Line Heading Widget for Elementor (Pro)</a></li>
338
+ <li><a href="https://unlimited-elements.com/christmas-text-widget-for-elementor">Christmas Text Widget for Elementor (Pro)</a></li>
339
  </ol>
340
 
341
  <h3>Content Widgets for Elementor</h3>
425
  <li><a href="https://unlimited-elements.com/separator-and-dividers-widgets-for-elementor/">Three Icons Separator Widget for Elementor (Pro)</a></li>
426
  <li><a href="https://unlimited-elements.com/separator-and-dividers-widgets-for-elementor/">Christmas Candy Separator Widget for Elementor (Pro)</a></li>
427
  <li><a href="https://unlimited-elements.com/separator-and-dividers-widgets-for-elementor/">Animated Wave Separator Widget for Elementor (Pro)</a></li>
428
+ <li><a href="https://unlimited-elements.com/christmas-lights-widget-for-elementor/">Christmas Lights Widget for Elementor (Pro)</a></li>
429
  </ol>
430
 
431
  <h3>Google Charts for Elementor</h3>
453
  <li><a href="https://unlimited-elements.com/solid-color-hero-widget-for-elementor">Solid Color Hero Widget for Elementor (Pro)</a></li>
454
  </ol>
455
 
456
+ <h3>Remote Control Widgets for Elementor</h3>
457
+ <ol>
458
+ <li><a href="https://unlimited-elements.com/remote-control-widgets">Remote Arrows Widget for Elementor (Free)</a></li>
459
+ <li><a href="https://unlimited-elements.com/remote-control-widgets">Remote Bullets Widget for Elementor (Free)</a></li>
460
+ <li><a href="https://unlimited-elements.com/remote-control-widgets">Remote Counter Widget for Elementor (Free)</a></li>
461
+ <li><a href="https://unlimited-elements.com/remote-control-widgets">Remote Play Pause Widget for Elementor (Free)</a></li>
462
+ <li><a href="https://unlimited-elements.com/remote-control-widgets">Remote Item Navigation Widget for Elementor (Pro)</a></li>
463
+ <li><a href="https://unlimited-elements.com/remote-control-widgets">Remote Tabs Widget for Elementor (Pro)</a></li>
464
+ </ol>
465
 
466
 
467
 
476
 
477
  == Changelog ==
478
 
479
+ version 1.4.96 = 2021-12-29:
480
+
481
+ * Feature: use yoast main category feature to determine post main category
482
+ * Feature: added get woocommerce product gallery functionality to twig
483
+ * Feature: added support for multiple attribute conditoins values
484
+ * Feature: added menu order in advanced widget debug type
485
+ * Feature: added WooCommerce endpoints links code to twig
486
+ * Feature: added option to disable font awesome in general settings
487
+ * Fix: fixed some filters related issue
488
+ * Fix: added custom attributes to link attributes output
489
+
490
+
491
+ version 1.4.95 = 2021-12-16:
492
+
493
+ *Fix: fixed db table not found php bug in some cases
494
+
495
+
496
+ version 1.4.94 = 2021-12-14:
497
+
498
+ * Feature: made posible multiple includes condition values per assets
499
+ * Feature: added meta value2 and meta value3 in include by meta value post selection
500
+ * Feature: added error notice if no api connectivity
501
+ * Feature: added attributes section conditions
502
+ * Feature: prepared code base for the new galleries
503
+ * Fix: fixed some small pagination related bug
504
+ * Fix: fixed remote connection parent detection in some cases
505
+ * Fix: added content filtering by filter widget_text_content for all the embed and other content modifications
506
+ * Fix: fixed edit defaulsin widget settings
507
+ * Fix: fixed some polylang issues with the template in dynamic template widgets
508
+ * Fix: [security] remove the "duplicate layout" functionality (not used in the plugin) that had some security issues
509
+
510
+
511
+ version 1.4.93 = 2021-12-03:
512
+
513
+
514
+ * Fix: fixed some connected widgets bugs when there is many of them in the page
515
+ * Change: removed the black friday sale banner
516
+ * Feature: added general remote API for various widgets connections
517
+ * Feature: add some code base for the new gallery output
518
+
519
+
520
+ version 1.4.92 = 2021-11-24:
521
+
522
+ * Fix: fixed similar post content in post list
523
+ * Change: saparated remote and sync options in connected widgets settings
524
+
525
+
526
+ version 1.4.91 = 2021-11-23:
527
+
528
+ * Fix: fixed the wrong post intro in editor mode
529
+
530
+
531
+ version 1.4.90 = 2021-11-22:
532
+
533
+ * Addition: added black friday banner discount banner and link
534
+ * Change: improved "sync widgets" editor experience
535
+ * Fix: fixed depricated "post" attribute bug
536
+ * Fix: modified zip extracting error messages
537
+
538
+
539
+ version 1.4.89 = 2021-11-17:
540
+
541
+ * Feature: done the functionality for sync widgets
542
+ * Feature: done the functionality remote widgets
543
+ * Fix: fixed error message on remote widgets
544
+ * Fix: fixed css in post content in editor
545
+ * Fix: use better strip tags for post intro
546
+
547
+
548
+ version 1.4.88 = 2021-11-08:
549
 
550
+ * Fix: fixed gutenberg support in widgets
551
+ * Fix: fixed all the pagination issues in archive page
552
 
553
 
554
  version 1.4.86 = 2021-11-01:
555
 
556
+ * Fix: fixed some load more last issues
557
+ * Feature: added code for taxonomy terms filter
558
+ * Feature: added code for checkbox filter
559
 
560
 
561
  version 1.4.86 = 2021-10-29:
562
 
563
+ * Feature: improved current query debug - full type
564
+ * Feature: added dropdown responsive placeholders
565
+ * Feature: added radio boolean attribute responsive controls
566
 
567
+ * Fix: fixed controls tabs functionality
568
+ * Fix: fixed load more custom image bug
569
+ * Fix: fixed double load more in a page mishmash bug
570
+ * Fix: fixed all load more issues
571
 
572
 
573
  version 1.4.85 = 2021-10-13:
576
 
577
  version 1.4.84 = 2021-10-13:
578
 
579
+ * Feature: added taxonomy terms full query debug option
580
+ * Feature: improved full debug type in posts query
581
+ * Feature: added items support in editor->background switcher
582
+ * Feature: added support for remote controls
583
+ * Feature: functionality to posts load more
584
+ * Feature: added second condition
585
+ * Feature: added tabs functionality to attributes
586
+ * Addition: added %,px to slider units
587
+ * Fix: fixed avoid duplicates related bug
588
+ * Fix: fixed conflicting wordpress codemirror script
589
+ * Fix: fixed post selection values init from editor
590
+ * Fix: fixed pagination on front page
591
+ * Fix: fixed some polylang related bugs
592
 
593
 
594
  version 1.4.83 = 2021-09-22:
595
 
596
+ * Fix: fixed styles mishmash inside elementor editor navigator
597
+ * Fix: fixed dissapearing carousels after refresh bug
598
+ * Fix: fixed dynamic grid pagination not changed
599
 
600
 
601
  version 1.4.82 = 2021-09-20:
602
 
603
+ * Feature: added troubleshooting setting - show php error message
604
+ * Feature: added px, vh, % options for slider attribute
605
+ * Feature: added dynamic group attributes for galleries, including image and video
606
+ * Feature: added option to convert one date string to another with ucdate filter
607
+ * Feature: added option to use items in background widgets
608
+ * Feature: added ucfunc("set") and ucfunc("get") functions in twig for remember and retrieve variables
609
+ * Feature: added include by option: "children of current term" to category selection options
610
+ * Feature: added option to pull woo product variations in twig
611
+ * Feature: added placeholder: link_withprefix, link_noprefix for link attribute
612
+ * Fix: fixed error when exists dynamic link in dynamic loop widgets
613
+ * Fix: enabled pagination in a single type in dynamic template grid
614
+ * Fix: the "not equal" attributes condition now works
615
+ * Fix: fixed not editable empty dropdown attribute in widget editor
616
+ * Fix: fixed mb_string absence php bug
617
+ * Fix: fixed heading attribute label
618
+ * Fix: fixed responsive elementor controls in widget items
619
 
620
 
621
 
1224
  version 1.4.10 - 2019-28-9 =
1225
 
1226
  -bug fix: added some front end protection against db not installed bug
1227
+ * Feature(pro): added do_action for custom wp actions run
1228
+ * Feature(pro): added apply_filters for custom wp actions run
1229
  -bug fix: fixed export widget with assets path
1230
  -change: added instructions to download pro version.
1231
 
release_log.txt CHANGED
@@ -1,4 +1,72 @@
1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  version 1.4.88:
3
 
4
  -bug fix: fixed gutenberg support in widgets
1
 
2
+
3
+ version 1.4.96:
4
+
5
+ -bug fix: fixed some filters related issue
6
+ -feature: use yoast main category feature to determine post main category
7
+ -feature: added get woocommerce product gallery functionality to twig
8
+ -feature: added support for multiple attribute conditoins values
9
+ -feature: added menu order in advanced widget debug type
10
+ -bug fix: added custom attributes to link attributes output
11
+ -feature: added WooCommerce endpoints links code to twig
12
+ -feature: added option to disable font awesome in general settings
13
+
14
+
15
+ version 1.4.95:
16
+
17
+ -bug fix: fixed db table not found php bug in some cases
18
+
19
+ version 1.4.94:
20
+
21
+ -bug fix: fixed some small pagination related bug
22
+ -feature: added meta value2 and meta value3 in include by meta value post selection
23
+ -feature: added error notice if no api connectivity
24
+ -bug fix: fixed remote connection parent detection in some cases
25
+ -feature: made posible multiple includes condition values per assets
26
+ -bug fix: added content filtering by filter widget_text_content for all the embed and other content modifications
27
+ -feature: added attributes section conditions
28
+ -bug fix: fixed edit defaulsin widget settings
29
+ -bug fix: fixed some polylang issues with the template in dynamic template widgets
30
+ -security fix: remove the "duplicate layout" functionality (not used in the plugin) that had some security issues
31
+ -feature: prepared code base for the new galleries
32
+
33
+
34
+ version 1.4.93:
35
+
36
+ -bug fix: fixed some connected widgets bugs when there is many of them in the page
37
+ -change: removed the black friday sale banner
38
+ -feature: added general remote API for various widgets connections
39
+ -feature: add some code base for the new gallery output
40
+
41
+
42
+ version 1.4.92:
43
+
44
+ -bug fix: fixed similar post content in post list
45
+ -change: saparated remote and sync options in connected widgets settings
46
+
47
+
48
+ version 1.4.91:
49
+
50
+ - bug fix: fixed the wrong post intro in editor mode
51
+
52
+
53
+ version 1.4.90:
54
+
55
+ -addition: added black friday banner discount banner and link
56
+ -change: improved "sync widgets" editor experience
57
+ -bug fix: fixed depricated "post" attribute bug
58
+ -bug fix: modified zip extracting error messages
59
+
60
+
61
+ version 1.4.89:
62
+
63
+ -bug fix: fixed error message on remote widgets
64
+ -bug fix: fixed css in post content in editor
65
+ -bug fix: use better strip tags for post intro
66
+ -feature: done the functionality for sync widgets
67
+ -feature: done the functionality remote widgets
68
+
69
+
70
  version 1.4.88:
71
 
72
  -bug fix: fixed gutenberg support in widgets
unitecreator_admin.php CHANGED
@@ -108,7 +108,6 @@ defined('UNLIMITED_ELEMENTS_INC') or die('Restricted access');
108
  HelperUC::addScript("select2.full.min", "select2_js","js/select2");
109
  HelperUC::addStyle("select2", "select2_css","js/select2");
110
 
111
-
112
  //include codemirror
113
  HelperUC::addScript("codemirror.min", "codemirror_js","js/codemirror");
114
  HelperUC::addScript("css", "codemirror_cssjs","js/codemirror/mode/css");
108
  HelperUC::addScript("select2.full.min", "select2_js","js/select2");
109
  HelperUC::addStyle("select2", "select2_css","js/select2");
110
 
 
111
  //include codemirror
112
  HelperUC::addScript("codemirror.min", "codemirror_js","js/codemirror");
113
  HelperUC::addScript("css", "codemirror_cssjs","js/codemirror/mode/css");
unlimited_elements.php CHANGED
@@ -1,15 +1,17 @@
1
  <?php
2
  /*
3
- Plugin Name: Unlimited Elements for Elementor
4
- Plugin URI: http://unlimited-elements.com
5
- Description: Unlimited Elements - Huge Widgets Pack for Elementor Website Builder, with html/css/js widget creator and editor
6
- Author: Unlimited Elements
7
- Version: 1.4.88
8
- Author URI: http://unlimited-elements.com
9
- Text Domain: unlimited-elements-for-elementor
10
- Domain Path: /languages
11
- Elementor tested up to: 3.4.5
12
- Elementor Pro tested up to: 3.4.2
 
 
13
  */
14
 
15
  if(!defined("UNLIMITED_ELEMENTS_INC"))
1
  <?php
2
  /*
3
+ * Plugin Name: Unlimited Elements for Elementor
4
+ * Plugin URI: http://unlimited-elements.com
5
+ * Description: Unlimited Elements - Huge Widgets Pack for Elementor Website Builder, with html/css/js widget creator and editor
6
+ * Author: Unlimited Elements
7
+ * Version: 1.4.96
8
+ * Author URI: http://unlimited-elements.com
9
+ * Text Domain: unlimited-elements-for-elementor
10
+ * Domain Path: /languages
11
+ *
12
+ * Tested up to: 5.8.2
13
+ * Elementor tested up to: 3.5.3
14
+ * Elementor Pro tested up to: 3.5.2
15
  */
16
 
17
  if(!defined("UNLIMITED_ELEMENTS_INC"))
views/objects/addon_view.class.php CHANGED
@@ -644,7 +644,7 @@ class UniteCreatorAddonView{
644
 
645
  <span class="hor_sap5"></span>
646
 
647
- <select id="uc_dialog_include_values"></select>
648
 
649
  </span>
650
 
644
 
645
  <span class="hor_sap5"></span>
646
 
647
+ <select id="uc_dialog_include_values" multiple class="uc-dialog-include-settings__values"></select>
648
 
649
  </span>
650
 
views/objects/addon_view_childparams.class.php CHANGED
@@ -890,6 +890,53 @@ function {{uc_id}}_start(){
890
  return($arrParam);
891
  }
892
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
893
  /**
894
  * create add child products param
895
  */
@@ -938,6 +985,8 @@ function {{uc_id}}_start(){
938
 
939
  $arrParams[] = $this->createWooPostParam_getChildProducts();
940
  $arrParams[] = $this->createWooPostParam_putVariations();
 
 
941
 
942
  foreach($arrKeys as $key){
943
 
890
  return($arrParam);
891
  }
892
 
893
+ /**
894
+ * create add child products param
895
+ */
896
+ private function createWooPostParam_putProductGallery(){
897
+
898
+ $strCode = "\n";
899
+ $strCode .= "{%set gallery = ucfunc(\"get_wc_gallery\", [param_prefix].id) %}\n\n";
900
+ $strCode .= "{% for gallery_item in gallery %}\n\n";
901
+ $strCode .= "<!--\n";
902
+ $strCode .= "{{gallery_item.image}}\n";
903
+ $strCode .= "{{gallery_item.thumb_large}}\n";
904
+ $strCode .= "{{gallery_item.title}}\n";
905
+ $strCode .= "-->\n";
906
+ $strCode .= "<img src=\"{{gallery_item.thumb}}\">\n";
907
+ $strCode .= "{% endfor %}\">\n";
908
+
909
+ $arrParam = $this->createChildParam("putWooProductGallery", null, array("raw_insert_text"=>$strCode));
910
+
911
+ return($arrParam);
912
+ }
913
+
914
+ /**
915
+ * create add child products param
916
+ */
917
+ private function createWooPostParam_getEndpoints(){
918
+
919
+ $strCode = "\n";
920
+ $strCode .= "{%set url_cart = ucfunc(\"get_woo_endpoint\",\"cart\") %}\n";
921
+ $strCode .= "{%set url_checkout = ucfunc(\"get_woo_endpoint\",\"checkout\") %}\n";
922
+ $strCode .= "{%set url_myaccount = ucfunc(\"get_woo_endpoint\",\"myaccount\") %}\n";
923
+ $strCode .= "{%set url_shop = ucfunc(\"get_woo_endpoint\",\"shop\") %}\n\n";
924
+
925
+ $strCode .= "{{url_cart}}\n";
926
+ $strCode .= "<br>\n";
927
+ $strCode .= "{{url_checkout}}\n";
928
+ $strCode .= "<br>\n";
929
+ $strCode .= "{{url_myaccount}}\n";
930
+ $strCode .= "<br>\n";
931
+ $strCode .= "{{url_shop}}\n\n";
932
+
933
+
934
+ $arrParam = $this->createChildParam("getWooEndpoints", null, array("raw_insert_text"=>$strCode));
935
+
936
+ return($arrParam);
937
+ }
938
+
939
+
940
  /**
941
  * create add child products param
942
  */
985
 
986
  $arrParams[] = $this->createWooPostParam_getChildProducts();
987
  $arrParams[] = $this->createWooPostParam_putVariations();
988
+ $arrParams[] = $this->createWooPostParam_putProductGallery();
989
+ $arrParams[] = $this->createWooPostParam_getEndpoints();
990
 
991
  foreach($arrKeys as $key){
992