WP Google Analytics Events - Version 2.6.0

Version Description

Download this release

Release Info

Developer yuvalo
Plugin Icon 128x128 WP Google Analytics Events
Version 2.6.0
Comparing to
See all releases

Code changes from version 2.5.5 to 2.6.0

Files changed (48) hide show
  1. click-tracking-page.png +0 -0
  2. css/style.css +234 -236
  3. css/third-party/jquery.modal.min.css +1 -0
  4. ga-scroll-event.php +411 -200
  5. icon-128x128.png +0 -0
  6. icon-256x256.png +0 -0
  7. images/WPGAE_Logo-177x78.png +0 -0
  8. images/menu-icon.png +0 -0
  9. include/Activation.php +167 -0
  10. include/EventClasses.php +322 -0
  11. include/Settings.php +619 -0
  12. include/Snippets.php +138 -0
  13. include/TrackingTable.php +131 -0
  14. include/ga-events-pro-settings-default.json +1 -0
  15. include/install.php +21 -0
  16. {includes → include}/notice.php +64 -62
  17. include/saved-snippets.php +54 -0
  18. includes/admin.php +0 -715
  19. includes/functions.php +0 -285
  20. js/admin.js +162 -100
  21. js/ajax-settings.js +83 -0
  22. js/ajax.js +0 -194
  23. js/dist/admin-scripts-min.js +1 -0
  24. js/dist/admin-scripts.js +263 -0
  25. js/dist/frontend-scripts-min.js +1 -0
  26. js/dist/frontend-scripts.js +291 -0
  27. js/ga-scroll-events.js +0 -170
  28. js/gae-mapper.js +10 -0
  29. js/main.js +291 -8
  30. js/third-party/jquery.form-validator.min.js +10 -0
  31. js/third-party/jquery.modal.min.js +5 -0
  32. main-plugin-file-sketch.php +41 -0
  33. plugin-general-settings.png +0 -0
  34. readme.txt +44 -23
  35. screenshot-1.png +0 -0
  36. screenshot-2.png +0 -0
  37. screenshot-3.png +0 -0
  38. screenshot-4.png +0 -0
  39. screenshot-5.png +0 -0
  40. scroll-tracking-page.png +0 -0
  41. templates/click-elements-input-table.php +147 -0
  42. templates/click-tracking-modals.php +179 -0
  43. templates/getting-started-guide-section.php +17 -0
  44. templates/scroll-elements-input-table.php +148 -0
  45. templates/scroll-tracking-modals.php +179 -0
  46. templates/whats-new-section-content.php +41 -0
  47. uninstall.php +2 -4
  48. wp-ga-events2.png +0 -0
click-tracking-page.png ADDED
Binary file
css/style.css CHANGED
@@ -1,283 +1,156 @@
1
- .ga_main_general_width {
2
- float:left;
3
- display: block;
4
- max-width: 900px;
 
5
  }
6
-
7
- .ga_main_full_width {
8
- float:left;
9
  display: block;
10
  }
11
- #ga_main th {
12
- /*min-width:100px;*/
13
- }
14
- #ga_main td {
15
- max-width: 400px;
16
- }
17
 
18
- #ga_main li {
19
- list-style-type: none;
20
- }
21
- #ga_mainwrap{
22
- width: 99%;
23
- float: left;
24
  }
25
 
26
- .ga_events_sidebar {
27
- float:right;
28
- width: 250px;
29
- margin-top:52px;
30
- margin-right: 30px;
31
- }
32
-
33
-
34
- .ga_intable {
35
- margin-left:10px;
36
- }
37
 
38
- #ga_main form th[scope="row"] {
39
- width: 0px !important;
40
- padding: 0px !important;
41
- }
42
 
43
- #ga_main form label {
44
- font-size: 1.2em;
45
- margin-bottom: 3px;
46
  }
47
-
48
- #ga_main .inner_table {
49
- margin-top: 10px;
50
  }
51
- #ga_main label {
52
- min-width: 170px;
53
- display: inline-block;
 
54
  }
55
 
56
- #ga_main .inner_table .fa{
57
  font-size: 20px;
58
  }
59
 
60
- .btn-subscribe {
61
-
62
- z-index: 10000;
63
- padding: 8px 12px;
64
- font-size: 18px;
65
- line-height: 1.33;
66
- border-radius: 6px;
67
  display: inline-block;
68
- margin-bottom: 0;
69
- font-weight: normal;
70
- text-align: center;
71
- white-space: nowrap;
72
- vertical-align: middle;
73
- cursor: pointer;
74
- background-image: none;
75
- border: 1px solid rgba(0, 0, 0, 0);
76
- -webkit-user-select: none;
77
- -moz-user-select: none;
78
- -ms-user-select: none;
79
- -o-user-select: none;
80
- user-select: none;
81
- color: #FFF;
82
- background-color: #7ACBA6;
83
- box-shadow: 0 3px 2px #06121E;
84
- border-radius: 7px;
85
- position: relative;
86
  }
87
 
88
- .wpcta {
89
- text-align: center;
90
- }
91
-
92
- .ga_events_banner li {
93
- list-style-type: none !important;
94
- font-size: 14px;
95
- }
96
-
97
- .ga_events_banner li i {
98
- margin-right: 5px;
99
- }
100
-
101
- .ga_events_banner th {
102
- text-align: center;
103
- font-size: 19px;
104
- background-color: #32373c;
105
- color: white !important;
106
- }
107
-
108
-
109
- .ga_events_banner form {
110
- background-color: #96D0B5;
111
- padding: 0px !important;
112
- }
113
-
114
- .ga_events_banner .features td{
115
- padding: 0px 10px !important;
116
  }
117
 
118
- .ga_events_banner .button-large {
119
- font-size: 17px;
120
- line-height: 30px;
121
- height: 32px;
122
  }
123
-
124
- .ga_events_banner form .form-content {
125
- padding: 10px 0 10px 3%;
126
  }
127
-
128
- .ga_events_banner form .clear {
129
- display: block !important;
130
- width: 100% !important;
131
- background-color: #22636A;
132
- padding: 10px 0 10px;
133
  }
134
-
135
- .ga_events_banner form .btn-subscribe {
136
- display: block;
137
- margin: auto;
138
  }
139
 
140
-
141
- #mc_embed_signup input.email {
142
- width: 96% !important;
143
  }
144
 
145
- a[href="admin.php?page=wp-google-analytics-events-upgrade"] {
146
- color: #F7691D !important;
147
  }
148
 
149
- a[href="admin.php?page=wp-google-analytics-events-upgrade"]:hover {
150
- color: #cf471c !important;
151
- }
152
- .popup {
153
  position: fixed;
154
  width: 100%;
155
  height: 100%;
156
  left: 0;
157
  background-color: rgba(0, 0, 0, 0.57);
158
  top: 0;
159
- z-index: 99;
160
  }
161
- .popup h1{
162
- text-align: center;
163
- color: red;
164
  display: block;
165
  margin: 0 auto;
166
  width: 400px;
167
  padding: 20px;
168
- margin-top: 15%;
169
  background: #FFFFFF;
170
  position: relative;
171
  }
172
- a.btn_close_popup img {
173
- width: 23px;
174
  position: absolute;
175
- right: 8px;
176
- top: 6px;
177
  }
178
-
179
- .settings_content{
180
  position: fixed;
181
  width: 100%;
182
  height: 100%;
183
  left: 0;
184
  background-color: rgba(0, 0, 0, 0.57);
185
  top: 0;
186
- display: none;
187
  }
188
- .settings_content form{
 
 
189
  display: block;
190
  margin: 0 auto;
191
  width: 400px;
192
  padding: 20px;
193
- margin-top: 22%;
194
  background: #FFFFFF;
195
  position: relative;
196
  }
197
- .settings_content img{
198
- width: 18px;
199
  position: absolute;
200
- right: 10px;
201
- top: 11px;
 
 
 
 
 
202
  }
203
 
204
- @media only screen and (max-width: 1024px) {
205
-
206
- /* Force table to not be like tables anymore */
207
- #ga-events-inputs table,
208
- #ga-events-inputs thead,
209
- #ga-events-inputs tbody,
210
- #ga-events-inputs th,
211
- #ga-events-inputs td,
212
- #ga-events-inputs tr {
213
- display: block;
214
- }
215
- /* Hide table headers (but not display: none;, for accessibility) */
216
- #ga-events-inputs thead tr {
217
- position: absolute;
218
- top: -9999px;
219
- left: -9999px;
220
- }
221
-
222
- #ga-events-inputs tr { border: 1px solid #ccc; }
223
-
224
- #ga-events-inputs td {
225
- /* Behave like a "row" */
226
- border: none;
227
- border-bottom: 1px solid #eee;
228
- position: relative;
229
- padding-left: 50%;
230
- white-space: normal;
231
- text-align:left;
232
- }
233
-
234
- #ga-events-inputs td:before {
235
- /* Now like a table header */
236
- position: absolute;
237
- /* Top/left values mimic padding */
238
- top: 6px;
239
- left: 6px;
240
- width: 45%;
241
- padding-right: 10px;
242
- white-space: nowrap;
243
- text-align:left;
244
- font-weight: bold;
245
- }
246
-
247
- /*
248
- Label the data
249
- */
250
- #ga-events-inputs td:before { content: attr(data-title); }
251
- }
252
-
253
- .ga-events-help {
254
- margin-right: 2px;
255
- color: #0085ba;
256
  }
257
 
258
  .ga-tooltip{
259
- width: 16px;
260
- height: 16px;
261
- background: url(../images/ga-help.png) no-repeat;
262
- display: inline-block;
263
- margin-left: 5px;
264
- vertical-align:middle;
265
- cursor: help;
266
- margin-top: -10px;
267
  }
268
 
269
  .ui-tooltip, .arrow:after {
270
  background: #356aa0;
271
  border: 2px solid white;
272
- }
273
- .ui-tooltip {
274
  padding: 10px 20px;
275
  color: white;
276
  border-radius: 20px;
277
  box-shadow: 0 0 7px #356aa0;
278
- max-width:350px;
279
- }
280
- .arrow {
281
  width: 70px;
282
  height: 16px;
283
  overflow: hidden;
@@ -285,15 +158,15 @@ a.btn_close_popup img {
285
  left: 50%;
286
  margin-left: -35px;
287
  bottom: -16px;
288
- }
289
- .arrow.top {
290
  top: -16px;
291
  bottom: auto;
292
- }
293
- .arrow.left {
294
  left: 20%;
295
- }
296
- .arrow:after {
297
  content: "";
298
  position: absolute;
299
  z-index:9999;
@@ -307,11 +180,19 @@ a.btn_close_popup img {
307
  -ms-transform: rotate(45deg);
308
  -o-transform: rotate(45deg);
309
  tranform: rotate(45deg);
310
- }
311
- .arrow.top:after {
312
  bottom: -20px;
313
  top: auto;
314
- }
 
 
 
 
 
 
 
 
315
 
316
  .wpgae-container__warning{
317
  padding: 10px 20px;
@@ -323,7 +204,9 @@ a.btn_close_popup img {
323
  margin-bottom: .8em;
324
  }
325
 
326
- .wpgae-alert{
 
 
327
  width: 100%;
328
  padding: 0 12px;
329
  border-left: 4px solid #4b8813;
@@ -331,38 +214,153 @@ a.btn_close_popup img {
331
  box-shadow: 0 1px 2px rgba(0,0,0,.2);
332
  }
333
 
334
- @media screen and (min-width: 1024px){
 
 
 
 
 
 
335
 
336
- .ga_main_general_width{
337
- width: 70%;
338
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
 
340
- .ga_main_full_width{
341
- width: 100%;
342
- }
 
343
 
344
- #ga_main td{
345
- max-width: 100px;
346
- }
347
- #ga_main .click_table input,
348
- #ga_main .click_table select,
349
- #ga_main .divs_table input,
350
- #ga_main .divs_table select{
351
- width: 100%;
352
- }
353
 
354
- #ga_main input[type="submit"]{
355
- width: auto;
356
- }
 
357
  }
358
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
  .ga_events_top {
360
  clear: both;
361
  }
362
 
363
 
364
  .ga_events_featurebox {
365
- width: 385px;
366
  min-height: 252px;
367
  background-color: white;
368
  display: inline-block;
1
+ .ga_main{}
2
+ .ga_main .form-table{}
3
+ .ga_main .form-table td{}
4
+ .ga_main .form-table tbody tr th{
5
+ display: none;
6
  }
7
+ .ga_main .form-table tbody tr td{
8
+ padding: 0;
9
+ /* width: 100%; */
10
  display: block;
11
  }
 
 
 
 
 
 
12
 
13
+ /* Remove blue outline around update button when new row added*/
14
+ #ga_events_options .btn-update:focus{
15
+ box-shadow: none;
16
+ color: #0073aa;
 
 
17
  }
18
 
19
+ .ga_main .form-table .ga-events-table{
 
 
 
 
 
 
 
 
 
 
20
 
21
+ width: 100%;
 
 
 
22
 
23
+ display: block;
 
 
24
  }
25
+ .ga_main .form-table .ga-events-table thead tr th{
26
+ display:table-cell;
27
+ padding: 12px 12px 12px 12px;
28
  }
29
+ .ga_main .form-table .ga-events-table tr td{
30
+ padding: 15px 10px;
31
+ display: table-cell;
32
+ text-align: center;
33
  }
34
 
35
+ .ga-events-table .fa{
36
  font-size: 20px;
37
  }
38
 
39
+ .ga_main label {
40
+ min-width: 290px;
 
 
 
 
 
41
  display: inline-block;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  }
43
 
44
+ .ga-events-table input[type=number],
45
+ .ga-events-table input[type=text]{
46
+ width: 100%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
 
49
+ .link_class {
50
+ display: none;
 
 
51
  }
52
+ .ga_events_track_links {
53
+ margin-right: 10px;
 
54
  }
55
+ .ga_events_link_type {
56
+ margin-left: 20px;
 
 
 
 
57
  }
58
+ #ga_events_nofollow_input{
59
+ margin-right: 10px;
 
 
60
  }
61
 
62
+ #ga_events_nofollow_add{
63
+ margin-left: 20px;
64
+ text-decoration: none;
65
  }
66
 
67
+ .nofollow_tags, .tagsinput{
68
+ margin-left: 290px;
69
  }
70
 
71
+ .settings_content{
 
 
 
72
  position: fixed;
73
  width: 100%;
74
  height: 100%;
75
  left: 0;
76
  background-color: rgba(0, 0, 0, 0.57);
77
  top: 0;
78
+ display: none;
79
  }
80
+ .settings_content form{
 
 
81
  display: block;
82
  margin: 0 auto;
83
  width: 400px;
84
  padding: 20px;
85
+ margin-top: 22%;
86
  background: #FFFFFF;
87
  position: relative;
88
  }
89
+ .settings_content img{
90
+ width: 18px;
91
  position: absolute;
92
+ right: 10px;
93
+ top: 11px;
94
  }
95
+ .popup {
 
96
  position: fixed;
97
  width: 100%;
98
  height: 100%;
99
  left: 0;
100
  background-color: rgba(0, 0, 0, 0.57);
101
  top: 0;
102
+ z-index: 99;
103
  }
104
+ .popup h1{
105
+ text-align: center;
106
+ color: red;
107
  display: block;
108
  margin: 0 auto;
109
  width: 400px;
110
  padding: 20px;
111
+ margin-top: 15%;
112
  background: #FFFFFF;
113
  position: relative;
114
  }
115
+ a.btn_close_popup img {
116
+ width: 23px;
117
  position: absolute;
118
+ right: 8px;
119
+ top: 6px;
120
+ }
121
+
122
+ .ga_main .form-table th {
123
+ width: 0px !important;
124
+ padding-left: 12px;
125
  }
126
 
127
+ .ga-btn-save {
128
+ margin-left: 28px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  }
130
 
131
  .ga-tooltip{
132
+ width: 16px;
133
+ height: 16px;
134
+ background: url(../images/ga-help.png) no-repeat;
135
+ display: inline-block;
136
+ margin-left: 5px;
137
+ vertical-align:middle;
138
+ cursor: help;
139
+ border-radius: 10px;
140
  }
141
 
142
  .ui-tooltip, .arrow:after {
143
  background: #356aa0;
144
  border: 2px solid white;
145
+ }
146
+ .ui-tooltip {
147
  padding: 10px 20px;
148
  color: white;
149
  border-radius: 20px;
150
  box-shadow: 0 0 7px #356aa0;
151
+ max-width:350px;
152
+ }
153
+ .arrow {
154
  width: 70px;
155
  height: 16px;
156
  overflow: hidden;
158
  left: 50%;
159
  margin-left: -35px;
160
  bottom: -16px;
161
+ }
162
+ .arrow.top {
163
  top: -16px;
164
  bottom: auto;
165
+ }
166
+ .arrow.left {
167
  left: 20%;
168
+ }
169
+ .arrow:after {
170
  content: "";
171
  position: absolute;
172
  z-index:9999;
180
  -ms-transform: rotate(45deg);
181
  -o-transform: rotate(45deg);
182
  tranform: rotate(45deg);
183
+ }
184
+ .arrow.top:after {
185
  bottom: -20px;
186
  top: auto;
187
+ }
188
+
189
+ div.tagsinput { border:1px solid #CCC; background: #FFF; padding:5px; width:300px; height:100px; overflow-y: auto;}
190
+ div.tagsinput span.tag { border: 1px solid #292a2d; -moz-border-radius:2px; -webkit-border-radius:2px; display: block; float: left; padding: 5px; text-decoration:none; background: #356aa0; color: #ffffff; margin-right: 5px; margin-bottom:5px;font-family: helvetica; font-size:13px;}
191
+ div.tagsinput span.tag a { font-weight: bold; color: #82ad2b; text-decoration:none; font-size: 11px; }
192
+ div.tagsinput input { width:80px; margin:0px; font-family: helvetica; font-size: 13px; border:1px solid transparent; padding:5px; background: transparent; color: #000; outline:0px; margin-right:5px; margin-bottom:5px; }
193
+ div.tagsinput div { display:block; float: left; }
194
+ .tags_clear { clear: both; width: 100%; height: 0px; }
195
+ .not_valid {background: #FBD8DB !important; color: #90111A !important;}
196
 
197
  .wpgae-container__warning{
198
  padding: 10px 20px;
204
  margin-bottom: .8em;
205
  }
206
 
207
+
208
+
209
+ .wpgae-alert-new{
210
  width: 100%;
211
  padding: 0 12px;
212
  border-left: 4px solid #4b8813;
214
  box-shadow: 0 1px 2px rgba(0,0,0,.2);
215
  }
216
 
217
+ .wpgae-alert{
218
+ width: 100%;
219
+ padding: 0 12px;
220
+ border-left: 4px solid #929eaa;
221
+ background: #fff;
222
+ box-shadow: 0 1px 2px rgba(0,0,0,.2);
223
+ }
224
 
225
+ .wpga_meta {
226
+ min-height: 320px;
227
+ }
228
+ .wpgae_event_form_fields {
229
+ line-height: 28px;
230
+ height: 45px;
231
+ }
232
+ .wpga_meta label {
233
+ display: inline-block;
234
+ float: left;
235
+ clear: left;
236
+ width: 115px;
237
+ text-align: left;
238
+ margin-right: 10px;
239
+ font-size: 15px;
240
+ height: 28px;
241
+ }
242
+ .wpga_meta input {
243
+ display: inline-block;
244
+ float: left;
245
+ height: 28px;
246
+ padding-left: 4px;
247
+ }
248
 
249
+ .wpga_meta input[type=checkbox]{
250
+ height: 15px;
251
+ top: 12px;
252
+ }
253
 
 
 
 
 
 
 
 
 
 
254
 
255
+ .wpga_meta select {
256
+ display: inline-block;
257
+ float: left;
258
+ height: 28px;
259
  }
260
 
261
+ #wpgae_form_buttons {
262
+ clear: both;
263
+ display: block;
264
+ }
265
+
266
+ #wpgae_form_buttons .delete {
267
+ color: #fff;
268
+ background-color: #dc3545;
269
+ border-color: #dc3545;
270
+ }
271
+
272
+ #wpgae_form_buttons input[type=submit] {
273
+ float: right;
274
+ }
275
+
276
+
277
+ .ga_events_sidebar {
278
+ float:right;
279
+ width: 250px;
280
+ margin-top:52px;
281
+ margin-right: 30px;
282
+ }
283
+
284
+ .wpcta {
285
+ text-align: center;
286
+ }
287
+
288
+ .ga_events_banner li {
289
+ list-style-type: none !important;
290
+ font-size: 14px;
291
+ }
292
+
293
+ .ga_events_banner li i {
294
+ margin-right: 5px;
295
+ }
296
+
297
+ .ga_events_banner th {
298
+ text-align: center;
299
+ font-size: 19px;
300
+ background-color: #32373c;
301
+ color: white !important;
302
+ }
303
+
304
+
305
+ .ga_events_banner form {
306
+ background-color: #96D0B5;
307
+ padding: 0px !important;
308
+ }
309
+
310
+ .ga_events_banner .features td{
311
+ padding: 0px 10px !important;
312
+ }
313
+
314
+ .ga_events_banner .button-large {
315
+ font-size: 17px;
316
+ line-height: 30px;
317
+ height: 32px;
318
+ }
319
+
320
+ .ga_events_banner form .form-content {
321
+ padding: 10px 0 10px 3%;
322
+ }
323
+
324
+ .ga_events_banner form .clear {
325
+ display: block !important;
326
+ width: 100% !important;
327
+ background-color: #22636A;
328
+ padding: 10px 0 10px;
329
+ }
330
+
331
+ .ga_events_banner form .btn-subscribe {
332
+ display: block;
333
+ margin: auto;
334
+ }
335
+
336
+ #ga_events_options {
337
+ float: left;
338
+ width: 560px;
339
+ }
340
+
341
+ .plugin-title a[href^="https://wpflow.com/upgrade"]{
342
+ color: #F7691D !important;
343
+ }
344
+ .plugin-title a[href^="https://wpflow.com/upgrade"]:hover {
345
+ color: #cf471c !important;
346
+ }
347
+
348
+ a[href="admin.php?page=wp-google-analytics-events-upgrade"] {
349
+ color: #F7691D !important;
350
+ }
351
+
352
+ a[href="admin.php?page=wp-google-analytics-events-upgrade"]:hover {
353
+ color: #cf471c !important;
354
+ }
355
+
356
+
357
  .ga_events_top {
358
  clear: both;
359
  }
360
 
361
 
362
  .ga_events_featurebox {
363
+ width: 370px;
364
  min-height: 252px;
365
  background-color: white;
366
  display: inline-block;
css/third-party/jquery.modal.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .blocker{position:fixed;top:0;right:0;bottom:0;left:0;width:100%;height:100%;overflow:auto;z-index:1;padding:20px;box-sizing:border-box;background-color:#000;background-color:rgba(0,0,0,0.75);text-align:center}.blocker:before{content:"";display:inline-block;height:100%;vertical-align:middle;margin-right:-0.05em}.blocker.behind{background-color:transparent}.modal{display:none;vertical-align:middle;position:relative;z-index:2;max-width:500px;box-sizing:border-box;width:90%;background:#fff;padding:15px 30px;-webkit-border-radius:8px;-moz-border-radius:8px;-o-border-radius:8px;-ms-border-radius:8px;border-radius:8px;-webkit-box-shadow:0 0 10px #000;-moz-box-shadow:0 0 10px #000;-o-box-shadow:0 0 10px #000;-ms-box-shadow:0 0 10px #000;box-shadow:0 0 10px #000;text-align:left}.modal a.close-modal{position:absolute;top:-12.5px;right:-12.5px;display:block;width:30px;height:30px;text-indent:-9999px;background-size:contain;background-repeat:no-repeat;background-position:center center;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAAAXNSR0IArs4c6QAAA3hJREFUaAXlm8+K00Acx7MiCIJH/yw+gA9g25O49SL4AO3Bp1jw5NvktC+wF88qevK4BU97EmzxUBCEolK/n5gp3W6TTJPfpNPNF37MNsl85/vN/DaTmU6PknC4K+pniqeKJ3k8UnkvDxXJzzy+q/yaxxeVHxW/FNHjgRSeKt4rFoplzaAuHHDBGR2eS9G54reirsmienDCTRt7xwsp+KAoEmt9nLaGitZxrBbPFNaGfPloGw2t4JVamSt8xYW6Dg1oCYo3Yv+rCGViV160oMkcd8SYKnYV1Nb1aEOjCe6L5ZOiLfF120EjWhuBu3YIZt1NQmujnk5F4MgOpURzLfAwOBSTmzp3fpDxuI/pabxpqOoz2r2HLAb0GMbZKlNV5/Hg9XJypguryA7lPF5KMdTZQzHjqxNPhWhzIuAruOl1eNqKEx1tSh5rfbxdw7mOxCq4qS68ZTjKS1YVvilu559vWvFHhh4rZrdyZ69Vmpgdj8fJbDZLJpNJ0uv1cnr/gjrUhQMuI+ANjyuwftQ0bbL6Erp0mM/ny8Fg4M3LtdRxgMtKl3jwmIHVxYXChFy94/Rmpa/pTbNUhstKV+4Rr8lLQ9KlUvJKLyG8yvQ2s9SBy1Jb7jV5a0yapfF6apaZLjLLcWtd4sNrmJUMHyM+1xibTjH82Zh01TNlhsrOhdKTe00uAzZQmN6+KW+sDa/JD2PSVQ873m29yf+1Q9VDzfEYlHi1G5LKBBWZbtEsHbFwb1oYDwr1ZiF/2bnCSg1OBE/pfr9/bWx26UxJL3ONPISOLKUvQza0LZUxSKyjpdTGa/vDEr25rddbMM0Q3O6Lx3rqFvU+x6UrRKQY7tyrZecmD9FODy8uLizTmilwNj0kraNcAJhOp5aGVwsAGD5VmJBrWWbJSgWT9zrzWepQF47RaGSiKfeGx6Szi3gzmX/HHbihwBser4B9UJYpFBNX4R6vTn3VQnez0SymnrHQMsRYGTr1dSk34ljRqS/EMd2pLQ8YBp3a1PLfcqCpo8gtHkZFHKkTX6fs3MY0blKnth66rKCnU0VRGu37ONrQaA4eZDFtWAu2fXj9zjFkxTBOo8F7t926gTp/83Kyzzcy2kZD6xiqxTYnHLRFm3vHiRSwNSjkz3hoIzo8lCKWUlg/YtGs7tObunDAZfpDLbfEI15zsEIY3U/x/gHHc/G1zltnAgAAAABJRU5ErkJggg==')}.modal-spinner{display:none;position:fixed;top:50%;left:50%;transform:translateY(-50%) translateX(-50%);padding:12px 16px;border-radius:5px;background-color:#111;height:20px}.modal-spinner>div{border-radius:100px;background-color:#fff;height:20px;width:2px;margin:0 1px;display:inline-block;-webkit-animation:sk-stretchdelay 1.2s infinite ease-in-out;animation:sk-stretchdelay 1.2s infinite ease-in-out}.modal-spinner .rect2{-webkit-animation-delay:-1.1s;animation-delay:-1.1s}.modal-spinner .rect3{-webkit-animation-delay:-1.0s;animation-delay:-1.0s}.modal-spinner .rect4{-webkit-animation-delay:-0.9s;animation-delay:-0.9s}@-webkit-keyframes sk-stretchdelay{0%,40%,100%{-webkit-transform:scaleY(0.5)}20%{-webkit-transform:scaleY(1.0)}}@keyframes sk-stretchdelay{0%,40%,100%{transform:scaleY(0.5);-webkit-transform:scaleY(0.5)}20%{transform:scaleY(1.0);-webkit-transform:scaleY(1.0)}}
ga-scroll-event.php CHANGED
@@ -1,245 +1,456 @@
1
  <?php
 
2
  /*
3
- Plugin Name: WP Google Analytics Events
4
- Plugin URI: http://wpflow.com
5
- Description: Adds the Google Analytics code to your website and enables you to send events on scroll or click.
6
- Version: 2.5.5
7
- Author: Yuval Oren
8
- Author URI: http://wpflow.com
9
- License: GPLv2
10
- */
11
-
12
- /* Copyright 2013 Yuval Oren (email : yuval@pinewise.com)
13
- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
14
- This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15
- You should have received a copy of the GNU General Public License
16
- along with this program; if not, write to the Free Software
17
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
- */
19
- error_reporting(E_ERROR | E_PARSE);
20
-
21
- include( dirname( __FILE__ ) . '/includes/notice.php' );
22
- if ( function_exists( 'ga_events_set_review_trigger_date' ) ) {
23
- register_activation_hook( __FILE__, 'ga_events_set_review_trigger_date' );
24
- }
25
- /**
26
- * Set Trigger Date.
27
- *
28
- * @since 1.0.0
29
  */
30
- function ga_events_set_review_trigger_date() {
31
- $triggerreview = mktime(0, 0, 0, date('m') , date('d') + 30 , date('Y'));
32
- if ( ! get_option( 'ga_events_activation_date')) {
33
- add_option( 'ga_events_activation_date', $triggerreview, '', 'yes' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
- }
36
 
37
- $plugin_path = plugin_dir_path(__FILE__);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
- require_once('includes/functions.php');
40
- require_once(plugin_dir_path(__FILE__) ."/includes/admin.php");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
 
42
 
 
 
43
 
 
 
44
 
45
- /*
46
- * Plugin Activation
47
- */
48
 
 
 
49
 
 
50
 
 
 
 
 
51
 
52
- register_activation_hook( __FILE__, 'ga_events_install' );
53
- register_deactivation_hook( __FILE__, 'ga_events_deactivate' );
54
 
 
55
 
 
 
 
 
56
 
 
57
 
58
- function ga_events_install() {
59
- $ga_events_options = array(
60
- 'id' => '',
61
- 'exclude_snippet' => '0',
62
- 'universal' => '1',
63
- 'anonymizeip' => '0',
64
- 'advanced' => '0',
65
- 'divs' => array(array(id => '',type =>'', action => '', cat => '', label => '', interaction => 0, value => '')),
66
- 'click' => array(array(id => '',type =>'', action => '', cat => '', label => '', interaction => 0, value => ''))
67
- );
68
- if (!get_option('ga_events_options')) {
69
- update_option( 'ga_events_options', $ga_events_options );
70
  }
71
 
72
- wpgae_reactivate_notice();
73
 
74
- }
75
 
76
- function ga_events_deactivate() {
77
 
78
- }
79
- /*
80
- * Init
81
- */
82
 
83
- add_action('init','ga_events_scripts');
 
 
84
 
85
- function ga_events_scripts() {
86
- wp_enqueue_script('jquery');
87
- wp_enqueue_script('scrolldepth',plugins_url( '/js/ga-scroll-events.js', __FILE__) , array('jquery'), '2.5.3', false);
88
- }
89
 
90
- add_action( 'plugins_loaded', 'ga_events_setup');
 
 
91
 
92
- function ga_events_setup() {
93
- add_action( 'wp_head', 'ga_events_header', 100 );
94
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
 
 
96
 
97
- function ga_events_header() {
98
- $options = get_option('ga_events_options');
99
- $id = $options['id'];
100
- $domain = $_SERVER['SERVER_NAME'];
101
- if (!isset($options['exclude_snippet']) || $options['exclude_snippet'] != '1' ) {
102
- if (isset($options['universal']) && $options['universal']) { ?>
103
- <script>
104
- if (typeof ga === 'undefined') {
105
- (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
106
- (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
107
- m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
108
- })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
109
-
110
- <?php echo (isset($options['anonymizeip']) && $options['anonymizeip']) ? "ga('create','$id', '$domain', {anonymizeIp: true});" : "ga('create','$id', '$domain');";?>
111
- ga('send', 'pageview');
112
- }
113
- </script> <?php
114
- } else {
115
- ?> <script type='text/javascript'>
116
- if (typeof _gaq === 'undefined') {
117
- var _gaq = _gaq || [];
118
- <?php echo "_gaq.push(['_setAccount', '$id']);"; ?>
119
- <?php if (isset($options['anonymizeip']) && $options['anonymizeip']) echo "_gaq.push (['_gat._anonymizeIp'])"; ?>
120
- _gaq.push(['_setAllowLinker', true]);
121
- _gaq.push(['_trackPageview']);
122
-
123
- (function() {
124
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
125
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
126
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
127
- })();
128
- }
129
-
130
- </script> <?php
131
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  }
133
- }
134
 
135
- add_action( 'wp_footer', 'ga_events_footer', 100 );
 
136
 
137
- function ga_events_footer() {
138
- $options = get_option('ga_events_options');
139
- $divs = $options['divs'];
140
- $click = $options['click'];
141
- $universal = $options['universal'];
142
- $gtm = $options['gtm'];
143
- $gst = $options['gst'];
144
 
145
- if ($universal == ""){
146
- $universal = 0;
 
 
 
 
 
147
  }
148
 
149
- if ($gtm == ""){
150
- $gtm = 0;
151
- }
152
 
153
- if ($gst == ""){
154
- $gst = 0;
155
- }
156
- echo "
157
- <!-- BEGIN: wpflow ga events array -->
158
- <script>
159
-
160
- jQuery(document).ready(function() {
161
- if(typeof scroll_events == 'undefined') {
162
- return;
163
- }
164
- scroll_events.bind_events( {
165
- universal: ".$universal.",
166
- gtm:".$gtm.",
167
- gst:".$gst.",
168
-
169
- scroll_elements: [";
170
- $i = 0;
171
- if (is_array($divs)){
172
- foreach ($divs as $div) {
173
- if ($i == 0) {
174
- echo ga_events_get_selector($div);
175
- }else{
176
- echo ",".ga_events_get_selector($div);
177
- }
178
- $i++;
179
- }
180
- }
181
-
182
- echo "],
183
- click_elements: [";
184
- $i = 0;
185
- if (is_array($click)){
186
- foreach ($click as $cl) {
187
- if ($i == 0) {
188
- echo ga_events_get_selector($cl);
189
- }else{
190
- echo ",".ga_events_get_selector($cl);
191
- }
192
- $i++;
193
- }
194
- }
195
- echo "],
196
- });
197
- });
198
-
199
- </script>
200
- <!-- END: wpflow ga events array -->";
201
 
 
 
 
202
 
203
- }
 
 
204
 
205
- add_filter( 'plugin_action_links', 'ga_events_action_link', 10, 5 );
206
- function ga_events_action_link( $actions, $plugin_file ) {
207
- static $plugin;
208
- if (!isset($plugin))
209
- $plugin = plugin_basename(__FILE__);
210
- if ($plugin == $plugin_file) {
211
- $upgrade = array('upgrade' => '<a href="https://wpflow.com/upgrade/">' . __('Upgrade', 'General') . '</a>');
212
- $settings = array('settings' => '<a href="admin.php?page=wp-google-analytics-events">' . __('Settings', 'General') . '</a>');
213
-
214
- $actions = array_merge($upgrade, $actions);
215
- $actions = array_merge($settings, $actions);
216
- }
217
-
218
- return $actions;
219
- }
220
 
221
- function ga_events_get_selector($element) {
222
- $options = get_option('ga_events_options');
223
- if ($element[0]){
224
- $selector = '{';
225
- if($element[1] =='advanced'){
226
- $selector .= "'select':'".$element[0]."',";
227
- }else{
228
- $selector = "{'select':'";
229
- $selector .= ($element[1] =='class') ? '.':'#';
230
- $selector .= str_replace(' ','',$element[0])."',";
231
- }
232
- $selector .= "'category':'".$element[2]."',";
233
- $selector .= "'action':'".$element[3]."',";
234
- $selector .= "'label':'".$element[4]."',";
235
- $selector .= "'bounce':'".$element[5]."',";
236
- $selector .= "'evalue':'".$element[6]."'";
237
- $selector .= '}';
238
- return $selector;
239
- }else{
240
- return '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  }
242
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  }
244
 
245
- ?>
 
 
 
 
1
  <?php
2
+
3
  /*
4
+ Plugin Name: WP Google Analytics Events
5
+ Plugin URI: http://wpflow.com
6
+ Description: Adds the Google Analytics code to your website and enables you to send events on scroll or click.
7
+ Version: 2.6.0
8
+ Author: PineWise
9
+ Author URI: http://wpflow.com
10
+ License: GPLv2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  */
12
+
13
+ defined('ABSPATH') or die('Direct access not allowed!');
14
+
15
+ /* ------------------------------------------------------------------------ *
16
+ * Setup
17
+ * ------------------------------------------------------------------------ */
18
+
19
+ // Script debugging
20
+ define('GAE_SCRIPT_DEBUG',
21
+ false);
22
+
23
+ // Paths
24
+ define('GAE_PLUGIN_PATH',
25
+ plugin_dir_path(__FILE__));
26
+ define('GAE_PLUGIN_URL',
27
+ plugin_dir_url(__FILE__));
28
+
29
+ // Current version number
30
+ if (!defined('GA_EVENTS_VERSION'))
31
+ define('GA_EVENTS_VERSION',
32
+ '2.6.0');
33
+
34
+ // Dependencies
35
+
36
+ require_once(GAE_PLUGIN_PATH . '/include/Activation.php');
37
+
38
+ // Activation hook
39
+ register_activation_hook(__FILE__,
40
+ array('GAEActivation', 'start_activation'));
41
+
42
+
43
+ /* ------------------------------------------------------------------------ *
44
+ * Main plugin class
45
+ * ------------------------------------------------------------------------ */
46
+ if (!class_exists('GaEvents')) {
47
+
48
+ class GAEvents
49
+ {
50
+
51
+ function __construct()
52
+ {
53
+ if (is_admin()) {
54
+ $this->init_hooks();
55
+ $this->do_settings();
56
+ $this->load_admin_scripts();
57
+ $this->load_admin_styles();
58
+ include( dirname( __FILE__ ) . '/include/notice.php' );
59
+
60
+
61
+ }
62
+ require_once(GAE_PLUGIN_PATH . '/include/Snippets.php');
63
+ $this->include_snippet();
64
+ $this->load_front_end_scripts();
65
  }
 
66
 
67
+ function init_hooks()
68
+ {
69
+ require_once(GAE_PLUGIN_PATH . '/include/EventClasses.php');
70
+ require_once(GAE_PLUGIN_PATH . '/include/Settings.php');
71
+
72
+ add_action('init', 'WPGAEGClickEvent::wpgae_register_click_event_post_type');
73
+ add_action('init', 'WPGAEGScrollEvent::wpgae_register_scroll_event_post_type');
74
+
75
+ add_action('wp_ajax_wpflow_add_event', 'wpflow_event_ajax_handler');
76
+ add_action('wp_ajax_wpflow_edit_event', 'wpflow_event_ajax_handler');
77
+ add_action('wp_ajax_wpflow_delete_event', 'wpflow_event_ajax_handler');
78
+ function wpflow_event_ajax_handler()
79
+ {
80
+ /**
81
+ * The Ajax Handler for the plugin.
82
+ * Note that all metadata updates through the save_post hook and not showing here.
83
+ */
84
+ // Handle the ajax request
85
+
86
+ check_ajax_referer('wpflow_add_event', "ajax_nonce", true);
87
+
88
+ if (isset($_POST["action"]) && $_POST["action"] == "wpflow_add_event") {
89
+ if (!isset($_POST['wpgae_type'])) {
90
+ wp_die("wpgae_type cannot be empty");
91
+ }
92
+
93
+ $post_type = sanitize_text_field($_POST['wpgae_type']);
94
+ $postarr = array(
95
+ 'post_type' => $post_type,
96
+ 'post_status' => 'publish'
97
+ );
98
+
99
+ $post_id = wp_insert_post($postarr);
100
+ } else if (isset($_POST["action"]) && $_POST["action"] == "wpflow_delete_event") {
101
+ $post = wp_delete_post(intval($_POST["event_id"]), true);
102
+ WPGAEGeneralEvent::update_cache_by_post_type($post->post_type);
103
+ } else if (isset($_POST["action"]) && $_POST["action"] == "wpflow_edit_event") {
104
+ if (isset($_POST["event_id"]) && $_POST["event_id"]) {
105
+ $post_id = get_post(intval($_POST["event_id"]));
106
+ wp_update_post($post_id);
107
+ }
108
+ }
109
 
110
+ wp_die(); // All ajax handlers die when finished
111
+ }
112
+
113
+ function validateClickAndScrollForm($post_data)
114
+ {
115
+ /**
116
+ * Event Tracking rules -
117
+ * 1. Selector and Type cannot be empty - plugin restriction
118
+ * 2. Event Category and action cannot be empty - Google Analytics restrictions
119
+ * 3. Value can either be set to a number or not set at all
120
+ * 4. If the selector is not of type advanced, no spaces or . or # are allowed
121
+ */
122
+ $form_issues = array();
123
+
124
+ if (array_key_exists("wpgae_event_selector", $post_data) && $post_data["wpgae_event_selector"] != "") {
125
+ if (!array_key_exists("wpgae_event_type", $post_data) || $post_data["wpgae_event_type"] != "advanced") {
126
+ if ($post_data["wpgae_event_selector"] != sanitize_html_class($post_data["wpgae_event_selector"])) {
127
+ array_push($form_issues, 'Cannot use non alphabetical or numerical values other than "_" and "-" when
128
+ Selector is set to Class or Id');
129
+ }
130
+ }
131
+ } else {
132
+ array_push($form_issues, "Selector cannot be empty");
133
+ }
134
+ if (sizeof($form_issues) > 0) {
135
+ wp_send_json_error($form_issues);
136
+ wp_die();
137
+ }
138
+ }
139
 
140
+ add_action('wp_ajax_wpflow_get_event_json', 'wpflow_get_event_json_callback');
141
 
142
+ function wpflow_get_event_json_callback()
143
+ {
144
 
145
+ // retrieve post_id, and sanitize it to enhance security
146
+ $post_id = intval($_POST['post_id']);
147
 
148
+ // Check if the input was a valid integer
149
+ if ($post_id == 0) {
 
150
 
151
+ $response['error'] = 'true';
152
+ $response['result'] = 'Invalid Input';
153
 
154
+ } else {
155
 
156
+ // get the post
157
+ $thispost = get_post($post_id);
158
+ // check if post exists
159
+ if (!is_object($thispost)) {
160
 
161
+ $response['error'] = 'true';
162
+ $response['result'] = 'There is no post with the ID ' . $post_id;
163
 
164
+ } else {
165
 
166
+ $post_meta = get_post_meta($thispost->ID);
167
+ $response["meta"] = $post_meta;
168
+ $response['error'] = 'false';
169
+ $response['result'] = wpautop($thispost->post_content);
170
 
171
+ }
172
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  }
174
 
175
+ wp_send_json($response);
176
 
177
+ }
178
 
179
+ }
180
 
 
 
 
 
181
 
182
+ function do_settings()
183
+ {
184
+ $settings_instance = new GAESettings();
185
 
186
+ // Handle import options button from general settings
187
+ add_action('admin_init',
188
+ array($settings_instance, 'upgrade_settings'));
 
189
 
190
+ // Handle import options button from general settings
191
+ add_action('admin_init',
192
+ array($settings_instance, 'ga_events_import_settings'));
193
 
194
+ // Handle export options button from general settings
195
+ add_action('admin_init',
196
+ array($settings_instance, 'ga_events_download_settings'));
197
+
198
+ // add plugin menu
199
+ add_action('admin_menu',
200
+ array($settings_instance, 'ga_events_menu'));
201
+
202
+ // Initialise plugin options
203
+ add_action('admin_init',
204
+ array($settings_instance, 'ga_events_initialize_plugin_options'));
205
+
206
+ // Display settings link next to plugin listing on plugins page
207
+ $plugin = plugin_basename(__FILE__);
208
+ add_filter("plugin_action_links_$plugin",
209
+ array($settings_instance, 'plugin_add_settings_link'));
210
 
211
+ // Add Ajax functionality for the admin UI
212
+ add_action('wp_ajax_wpflow_update', 'wpflow_ajax_update_handler');
213
 
214
+ function wpflow_ajax_update_handler()
215
+ {
216
+ // Handle the ajax request
217
+ check_ajax_referer('wpflow-nounce');
218
+ wp_die(); // All ajax handlers die when finished
219
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  }
221
+
222
+ function load_admin_scripts()
223
+ {
224
+
225
+ $ga_options = get_option('ga_events_options');
226
+ $debug_mode = isset($ga_options['script_debug_mode']) ? $ga_options['script_debug_mode'] : '0';
227
+
228
+
229
+ // This condition need to be checked in localize_placeholder function too!
230
+ if (GAE_SCRIPT_DEBUG || $debug_mode) {
231
+ add_action('admin_enqueue_scripts',
232
+ array($this, 'enqueue_admin_scripts_debug'));
233
+ } else {
234
+ add_action('admin_enqueue_scripts',
235
+ array($this, 'enqueue_admin_scripts'));
236
+ }
237
  }
 
238
 
239
+ function load_front_end_scripts()
240
+ {
241
 
242
+ $ga_options = get_option('ga_events_options');
243
+ $debug_mode = isset($ga_options['script_debug_mode']) ? $ga_options['script_debug_mode'] : '0';
 
 
 
 
 
244
 
245
+ if (GAE_SCRIPT_DEBUG || $debug_mode == '1') {
246
+ add_action('wp_enqueue_scripts',
247
+ array($this, 'enqueue_front_end_scripts_debug'));
248
+ } else {
249
+ add_action('wp_enqueue_scripts',
250
+ array($this, 'enqueue_front_end_scripts'));
251
+ }
252
  }
253
 
254
+ function load_admin_styles()
255
+ {
 
256
 
257
+ add_action('admin_enqueue_scripts',
258
+ array($this, 'enqueue_admin_styles'));
259
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
 
261
+ /* --------------------------------------------------------------------- *
262
+ * Custom Post Types
263
+ * --------------------------------------------------------------------- */
264
 
265
+ /* --------------------------------------------------------------------- *
266
+ * Register and enqueue admin scripts
267
+ * --------------------------------------------------------------------- */
268
 
269
+ function enqueue_admin_scripts($hook)
270
+ {
271
+ if (strpos($hook, "wp-google-analytics-events") == false) {
272
+ return;
273
+ }
 
 
 
 
 
 
 
 
 
 
274
 
275
+ wp_register_script('admin_bundle',
276
+ GAE_PLUGIN_URL . 'js/dist/admin-scripts-min.js',
277
+ array('jquery', 'jquery-ui-tooltip'),
278
+ true);
279
+
280
+ // Localize plugin options in database for use in main JS script
281
+ wp_localize_script('admin_bundle',
282
+ 'ga_options',
283
+ get_option('ga_events_options'));
284
+
285
+
286
+ wp_enqueue_script('admin_bundle');
287
+
288
+ $wpflow_nonce = wp_create_nonce('wpflow-nounce');
289
+ wp_localize_script('admin_bundle', 'wpflow_ajax', array(
290
+ 'ajax_url' => admin_url('admin-ajax.php'),
291
+ 'nonce' => $wpflow_nonce, // It is common practice to comma after
292
+ ));
293
+
294
+ }
295
+
296
+ /* --------------------------------------------------------------------- *
297
+ * Register and enqueue admin scripts - DEBUGGING!
298
+ * --------------------------------------------------------------------- */
299
+
300
+ function enqueue_admin_scripts_debug($hook)
301
+ {
302
+ if (strpos($hook, "wp-google-analytics-events") == false) {
303
+ return;
304
+ }
305
+ // Localize plugin options in database for use in main JS script
306
+ wp_localize_script('gae_mapper',
307
+ 'ga_options',
308
+ get_option('ga_events_options'));
309
+
310
+ // Needed for the admin UI
311
+ wp_enqueue_script('jquery_modal',
312
+ GAE_PLUGIN_URL . 'js/third-party/jquery.modal.min.js',
313
+ array('jquery'),
314
+ false);
315
+
316
+ wp_enqueue_script('jquery_form_validator',
317
+ GAE_PLUGIN_URL . 'js/third-party/jquery.form-validator.min.js',
318
+ array('jquery'),
319
+ false);
320
+
321
+ // Admin JS
322
+ wp_enqueue_script('admin_js',
323
+ GAE_PLUGIN_URL . 'js/admin.js',
324
+ array('jquery', 'jquery-ui-tooltip'),
325
+ '1.0',
326
+ true);
327
+
328
+ // Ajax for settings
329
+ wp_enqueue_script('ajax_settings_js',
330
+ GAE_PLUGIN_URL . 'js/ajax-settings.js',
331
+ array('jquery'),
332
+ '1.0',
333
+ false);
334
+
335
+ $wpflow_nonce = wp_create_nonce('wpflow-nounce');
336
+
337
+ wp_localize_script('ajax_settings_js', 'wpflow_ajax', array(
338
+ 'ajax_url' => admin_url('admin-ajax.php'),
339
+ 'nonce' => $wpflow_nonce, // It is common practice to comma after
340
+ ));
341
+
342
+ }
343
+
344
+ function enqueue_front_end_scripts()
345
+ {
346
+
347
+ // Get plugin options from the database. Needed for conditional enqueueing
348
+ $ga_options = get_option('ga_events_options');
349
+
350
+ /* --------------------------------------------------------------- *
351
+ * Register frontend scripts
352
+ * ---------------------------------------------------------------- */
353
+
354
+ wp_register_script('ga_events_frontend_bundle',
355
+ GAE_PLUGIN_URL . 'js/dist/frontend-scripts-min.js',
356
+ array('jquery'),
357
+ '1.0',
358
+ true);
359
+
360
+ // Localize plugin options in database for use in main JS script
361
+ wp_localize_script('ga_events_frontend_bundle',
362
+ 'ga_options',
363
+ prepare_ga_options_for_frontend());
364
+
365
+ /* ------------------------------------------------------------- *
366
+ * Enqueue frontend scripts
367
+ * -------------------------------------------------------------- */
368
+
369
+ wp_enqueue_script('ga_events_frontend_bundle');
370
+ }
371
+
372
+ function enqueue_front_end_scripts_debug()
373
+ {
374
+
375
+ // Get plugin options from the database. Needed for conditional enqueueing
376
+ $ga_options = get_option('ga_events_options');
377
+
378
+ /* --------------------------------------------------------------------- *
379
+ * Register frontend scripts
380
+ * --------------------------------------------------------------------- */
381
+
382
+ wp_register_script('ga_events_main_script',
383
+ GAE_PLUGIN_URL . 'js/main.js',
384
+ array('jquery'),
385
+ '1.0',
386
+ false);
387
+
388
+ // Localize plugin options in database for use in main JS script
389
+ wp_localize_script('ga_events_main_script',
390
+ 'ga_options',
391
+ prepare_ga_options_for_frontend());
392
+
393
+ /* --------------------------------------------------------------------- *
394
+ * Enqueue frontend scripts
395
+ * --------------------------------------------------------------------- */
396
+
397
+ // Tracking is disabled for selected roles so we load tracking
398
+ wp_enqueue_script('ga_events_main_script');
399
  }
400
 
401
+ function enqueue_admin_styles($hook)
402
+ {
403
+ if (strpos($hook, "wp-google-analytics-events") == false) {
404
+ return;
405
+ }
406
+ wp_enqueue_style('wpgae_font_awesome',
407
+ '//maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css');
408
+
409
+ wp_enqueue_style('wpgae_admin_styles',
410
+ GAE_PLUGIN_URL . 'css/style.css',
411
+ array('wpgae_font_awesome'));
412
+
413
+ wp_enqueue_style('wpgae_jquery_modal_styles',
414
+ GAE_PLUGIN_URL . 'css/third-party/jquery.modal.min.css');
415
+ }
416
+
417
+ function include_snippet()
418
+ {
419
+ add_action('wp_head',
420
+ array('GAESnippets', 'add_snippet_to_header'),
421
+ 0);
422
+ }
423
+
424
+
425
+ function isAdvancedModeOn()
426
+ {
427
+ $wpgae_options = get_option('ga_events_options');
428
+ if (isset($wpgae_options['advanced']) && $wpgae_options["advanced"] == 1) {
429
+ return true;
430
+ }
431
+ return false;
432
+
433
+ }
434
+ }
435
+
436
+ /*
437
+ * Remove sensitive data from the frontend
438
+ */
439
+ function prepare_ga_options_for_frontend()
440
+ {
441
+ $sensitive_options = array("script_debug_mode");
442
+ $ga_options = get_option('ga_events_options');
443
+ foreach ($sensitive_options as $key_to_remove) {
444
+ if (array_key_exists($key_to_remove, $ga_options)) {
445
+ unset($ga_options[$key_to_remove]);
446
+ }
447
+ }
448
+ return $ga_options;
449
+ }
450
  }
451
 
452
+
453
+
454
+
455
+ $wpgae = new GaEvents();
456
+
icon-128x128.png DELETED
Binary file
icon-256x256.png DELETED
Binary file
images/WPGAE_Logo-177x78.png CHANGED
Binary file
images/menu-icon.png ADDED
Binary file
include/Activation.php ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class GAEActivation
4
+ {
5
+
6
+ // intial values for plugin options. NB strings used for boolean values
7
+ // for good reason
8
+ private static $default_options = array(
9
+ 'link_clicks_delay' => '120',
10
+ 'gtm' => '0',
11
+ 'anonymizeip' => '0',
12
+ 'advanced' => '0',
13
+ 'script_debug_mode' => '1',
14
+ 'snippet_type' => 'gst',
15
+ 'tracking_id' => '',
16
+ 'gtm_id' => '',
17
+ 'domain' => '',
18
+ // Roles for which tracking is disabled
19
+ 'scroll_elements' => array(),
20
+ 'click_elements' => array(),
21
+ );
22
+
23
+ public static function start_activation()
24
+ {
25
+ // Decide whether to upgrade from previous version
26
+ if (GA_EVENTS_VERSION !== get_option('GA_EVENTS_version') && false !== get_option('ga_events_options')) {
27
+ self::GA_EVENTS_upgrade();
28
+ } else {
29
+ self::initialize_options();
30
+ }
31
+ }
32
+
33
+ private static function initialize_options()
34
+ {
35
+
36
+ update_option('GA_EVENTS_version',
37
+ GA_EVENTS_VERSION);
38
+
39
+ if (!get_option('ga_events_options')) {
40
+ update_option('ga_events_options',
41
+ self::$default_options);
42
+ }
43
+
44
+ $triggerreview = mktime(0, 0, 0, date('m') , date('d') + 10 , date('Y'));
45
+ update_option( 'ga_events_activation_date', $triggerreview, '', 'yes' );
46
+
47
+ wpgae_reactivate_notice();
48
+ }
49
+
50
+ public static function GA_EVENTS_upgrade()
51
+ {
52
+ $existing_values = get_option('ga_events_options');
53
+ $installed_version = get_option('GA_EVENTS_version');
54
+ if (!isset($installed_version)) {
55
+ $installed_version == "0.0.0";
56
+ }
57
+
58
+
59
+ if (version_compare(GA_EVENTS_VERSION, $installed_version) > 0) {
60
+ if (version_compare("2.6.0", $installed_version) > 0) {
61
+ $updated = static::version_2_6_0_upgrade($existing_values);
62
+ }
63
+ }
64
+
65
+ // last value in array_merge overwrites others
66
+ if (isset($updated)) {
67
+ // last value in array_merge overwrites others
68
+ update_option('ga_events_options',
69
+ $updated);
70
+ }
71
+ update_option('GA_EVENTS_version',
72
+ GA_EVENTS_VERSION);
73
+ }
74
+
75
+ private static function version_2_6_0_upgrade($existing_values)
76
+ {
77
+ // Conditionally determine the desired snippet type based on existing
78
+ // values
79
+ $default_snippet = 'universal';
80
+
81
+ if (array_key_exists("exclude_snippet", $existing_values) && $existing_values['exclude_snippet'] == 1) { // The "include_snippet" value is misleading
82
+ $default_snippet = 'none';
83
+ }
84
+
85
+ if (array_key_exists("gst", $existing_values) && $existing_values['gst'] == 1) {
86
+ $default_snippet = 'none';
87
+ }
88
+
89
+ if (array_key_exists("gtm", $existing_values) && $existing_values['gtm'] == 1) {
90
+ $default_snippet = 'none';
91
+ }
92
+
93
+ if ((!array_key_exists("universal", $existing_values) || $existing_values['universal'] == 0) && (!array_key_exists("include_snippet", $existing_values) || $existing_values['include_snippet'] == 0) && (!array_key_exists("gst", $existing_values) || $existing_values['gst']) == 0 && (!array_key_exists("gtm", $existing_values) || $existing_values['gtm'] == 0)) {
94
+ $default_snippet = 'legacy';
95
+ }
96
+
97
+ // New key=>value pairs for options array
98
+ $new_options = array(
99
+ 'snippet_type' => $default_snippet,
100
+ 'gtm_id' => '',
101
+ );
102
+
103
+ // We need to modify click and scroll options to associative array on update
104
+ $keys = array('selector', 'type', 'category', 'action', 'label', 'bounce', 'value');
105
+ if (array_key_exists("click", $existing_values)) {
106
+ foreach ($existing_values['click'] as &$click_item) {
107
+ // We need a way to migrate the old settings which are sub optimal.
108
+ // That is why we are doing the migration this way
109
+ $new_click_array = array();
110
+ for ($i = 0; $i < sizeof($keys); $i++) {
111
+ if (isset($click_item[$i])) {
112
+ $new_click_array[$keys[$i]] = $click_item[$i];
113
+ }
114
+ }
115
+ $click_item = $new_click_array;
116
+ }
117
+ }
118
+
119
+ if (array_key_exists("divs", $existing_values)) {
120
+ foreach ($existing_values['divs'] as &$scroll_item) {
121
+ $new_scroll_array = array();
122
+ for ($i = 0; $i < sizeof($keys); $i++) {
123
+ if (isset($scroll_item[$i])) {
124
+ $new_scroll_array[$keys[$i]] = $scroll_item[$i];
125
+ }
126
+ }
127
+ $scroll_item = $new_scroll_array;
128
+ }
129
+ }
130
+
131
+ $updated = array(
132
+ 'anonymizeip' => static::assign_if_set('anonymizeip', $existing_values),
133
+ 'advanced' => static::assign_if_set('advanced', $existing_values),
134
+ 'snippet_type' => $default_snippet,
135
+ 'tracking_id' => static::assign_if_set('id', $existing_values),
136
+ 'gtm_id' => '',
137
+ 'domain' => static::assign_if_set('domain', $existing_values),
138
+ 'click_elements' => array(),
139
+ 'scroll_elements' => array(),
140
+ 'script_debug_mode' => '1'
141
+ );
142
+
143
+ $updated["link_clicks_delay"] = array_key_exists("link_clicks_delay", $existing_values) ? $existing_values["link_clicks_delay"] : 120;
144
+
145
+
146
+ if (isset($existing_values["click"])) {
147
+ $click_events = WPGAEGClickEvent::convert_and_save_cached_settings($existing_values["click"]);
148
+ if (isset($click_events)) {
149
+ $updated["click_elements"] = WPGAEGClickEvent::prepare_cache_settings();
150
+ }
151
+ }
152
+
153
+ if (isset($existing_values["divs"])) {
154
+ $scroll_elements = WPGAEGScrollEvent::convert_and_save_cached_settings($existing_values["divs"]);
155
+ if (isset($scroll_elements)) {
156
+ $updated["scroll_elements"] = WPGAEGScrollEvent::prepare_cache_settings();
157
+ }
158
+ }
159
+
160
+ return $updated;
161
+ }
162
+
163
+ protected static function assign_if_set($param, $the_array)
164
+ {
165
+ return array_key_exists($param, $the_array) && !empty($the_array[$param]) ? $the_array[$param] : "";
166
+ }
167
+ }
include/EventClasses.php ADDED
@@ -0,0 +1,322 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPGAEGeneralEvent {
4
+ protected static $my_options;
5
+ protected static $wpgae_post_type;
6
+ protected static $wpgae_post_columns;
7
+ protected $event;
8
+
9
+
10
+ public function create_event() {
11
+ $postarr = array(
12
+ 'post_type' => $this->post_type,
13
+ 'post_status' => 'publish'
14
+ );
15
+
16
+ $post_id = wp_insert_post($postarr);
17
+ foreach($this->event as $key=> $value) {
18
+ if (array_key_exists("value", $value)) {
19
+ update_post_meta(
20
+ $post_id,
21
+ $key,
22
+ $value["value"]
23
+ );
24
+ } else if ($value["type"] == "checkbox") {
25
+ update_post_meta(
26
+ $post_id,
27
+ $key,
28
+ false
29
+ );
30
+ }
31
+ }
32
+
33
+ }
34
+ public static function get_wpgae_post_type() {
35
+ return static::$wpgae_post_type;
36
+ }
37
+ public static function get_wpgae_post_columns() {
38
+ return static::$wpgae_post_columns;
39
+ }
40
+
41
+ public static function get_posts() {
42
+ return get_posts(array(
43
+ 'post_type' => static::get_wpgae_post_type(),
44
+ 'post_status' => 'publish',
45
+ 'numberposts' => -1
46
+ // 'order' => 'ASC'
47
+ ));
48
+ }
49
+ public static function save_event($post_id) {
50
+ foreach(static::get_wpgae_post_columns() as $key=> $value) {
51
+ if (array_key_exists($key, $_POST)) {
52
+ update_post_meta(
53
+ $post_id,
54
+ $key,
55
+ $_POST[$key]
56
+ );
57
+ } else if ($value["type"] == "checkbox") {
58
+ update_post_meta(
59
+ $post_id,
60
+ $key,
61
+ false
62
+ );
63
+ }
64
+ }
65
+ static::set_cache_settings();
66
+ }
67
+
68
+
69
+ public static function update_cached_options($new_settings) {
70
+ $plugin_options = get_option( 'ga_events_options' );
71
+ $plugin_options[static::$my_options] = $new_settings;
72
+ update_option('ga_events_options', $plugin_options);
73
+ }
74
+
75
+ public static function prepare_cache_settings() {
76
+ $cached = array();
77
+ $posts = $tracking_entries = static::get_posts();
78
+
79
+ foreach($posts as $post) {
80
+ $event = array();
81
+ $post_id = $post->ID;
82
+ $post_meta = get_post_meta($post_id);
83
+ foreach(static::get_wpgae_post_columns() as $key=> $value) {
84
+ if (array_key_exists("settings", $value)) {
85
+ $setting = $value["settings"];
86
+ if (array_key_exists($key, $post_meta)) {
87
+ $event[$setting] = $post_meta[$key][0];
88
+ }
89
+ }
90
+ }
91
+ if (array_key_exists("name", $event)) {
92
+ array_push($cached, $event);
93
+ }
94
+ }
95
+ return $cached;
96
+ }
97
+
98
+ public static function set_cache_settings() {
99
+ $cached = static::prepare_cache_settings();
100
+ if (sizeof($cached) > 0 ) {
101
+ static::update_cached_options($cached);
102
+ }
103
+ }
104
+
105
+ static public function deletePostsById($post_ids)
106
+ {
107
+ $posts_to_delete = array_map('sanitize_key', $post_ids);
108
+ // Todo: Make sure that we have permisssion to do so
109
+ foreach($posts_to_delete as $post) {
110
+ wp_delete_post($post, true);
111
+ }
112
+ static::set_cache_settings();
113
+ }
114
+
115
+ static public function delete_all_event_posts() {
116
+ $posts = static::get_posts();
117
+ $post_ids = array();
118
+ foreach($posts as $post) {
119
+ array_push($post_ids, $post->ID);
120
+ }
121
+ static::deletePostsById($post_ids);
122
+ }
123
+
124
+ static public function update_cache_by_post_type($post_type)
125
+ {
126
+ foreach (get_declared_classes() as $class) {
127
+ if (is_subclass_of($class, WPGAEGeneralEvent::class)) {
128
+ if ($post_type == $class::get_wpgae_post_type()) {
129
+ $class::set_cache_settings();
130
+ }
131
+ }
132
+ }
133
+ }
134
+ }
135
+
136
+
137
+ class WPGAEGClickEvent extends WPGAEGeneralEvent{
138
+ protected $event;
139
+ protected static $keys = array('selector', 'type', 'category', 'action', 'label', 'bounce', 'value');
140
+ protected static $my_options = "click_elements";
141
+ protected static $wpgae_post_type = "wpgae_click_event";
142
+ protected static $wpgae_post_columns = array (
143
+ '_wpgae_click_selector_meta_key' => array('title' => 'Selector', 'type' => 'input', "settings"=> "name"),
144
+ '_wpgae_click_type_meta_key' => array('title' => 'Type', 'type' => 'input', "settings"=> "type"),
145
+ '_wpgae_click_category_meta_key' => array('title' => 'Event Category', 'type' => 'input', "settings"=> "category"),
146
+ '_wpgae_click_action_meta_key' => array('title' => 'Event Action', 'type' => 'input', "settings"=> "action"),
147
+ '_wpgae_click_label_meta_key' => array('title' => 'Event Label', 'type' => 'input', "settings"=> "label"),
148
+ '_wpgae_click_value_meta_key' => array('title' => 'Event Value', 'type' => 'input', "settings"=> "value"),
149
+ '_wpgae_click_bounce_meta_key' => array('title' => 'Non-Interaction', 'type' => 'input', "settings"=> "bounce"),
150
+ );
151
+
152
+ function __construct($event_array)
153
+ {
154
+ // Create an instance of the class based off of the post columns static object.
155
+ $this->post_type = static::$wpgae_post_type;
156
+ $this->event = static::$wpgae_post_columns;
157
+ if (array_key_exists("selector", $event_array) && isset($event_array["selector"])) {
158
+ $this->event["_wpgae_click_selector_meta_key"]["value"] = $event_array["selector"];
159
+ }
160
+ if (array_key_exists("type", $event_array) && isset($event_array["type"])) {
161
+ $this->event["_wpgae_click_type_meta_key"]["value"] = $event_array["type"];
162
+ }
163
+ if (array_key_exists("category", $event_array) && isset($event_array["category"])) {
164
+ $this->event["_wpgae_click_category_meta_key"]["value"] = $event_array["category"];
165
+ }
166
+ if (array_key_exists("action", $event_array) && isset($event_array["action"])) {
167
+ $this->event["_wpgae_click_action_meta_key"]["value"] = $event_array["action"];
168
+ }
169
+ if (array_key_exists("label", $event_array) && isset($event_array["label"])) {
170
+ $this->event["_wpgae_click_label_meta_key"]["value"] = $event_array["label"];
171
+ }
172
+ if (array_key_exists("value", $event_array) && isset($event_array["value"])) {
173
+ $this->event["_wpgae_click_value_meta_key"]["value"] = $event_array["value"];
174
+ }
175
+ if (array_key_exists("bounce", $event_array) && isset($event_array["bounce"])) {
176
+ $this->event["_wpgae_click_bounce_meta_key"]["value"] = $event_array["bounce"];
177
+ }
178
+
179
+ }
180
+
181
+ static function convert_and_save_cached_settings($cached) {
182
+ if (sizeof($cached) > 0) {
183
+ foreach($cached as $event) {
184
+ if (array_key_exists("selector", $event) && isset($event["selector"]) && $event["selector"] != "") {
185
+ if (strpos($event['selector'], "&#039;") !== false) {
186
+ $event['selector'] = str_replace("&#039;", '"', $event['selector']);
187
+ }
188
+ $new_event = new WPGAEGClickEvent($event);
189
+ $new_event->create_event();
190
+ }
191
+ }
192
+ return static::prepare_cache_settings();
193
+ }
194
+ }
195
+
196
+ static function wpgae_register_click_event_post_type()
197
+ {
198
+ $labels = array(
199
+ 'name' => 'Click Tracking',
200
+ 'singular_name' => 'Click Event',
201
+ 'add_new' => 'Add New',
202
+ 'add_new_item' => 'Add New Click Event',
203
+ 'edit_item' => 'Edit Click Event',
204
+ 'new_item' => 'New Click Event',
205
+ 'all_items' => 'Click Tracking',
206
+ 'view_item' => 'View Click Event',
207
+ 'search_items' => 'Search Click Events',
208
+ 'not_found' => 'No Click Events found',
209
+ 'not_found_in_trash' => 'No Click Events found in Trash',
210
+ 'parent_item_colon' => '',
211
+ 'menu_name' => 'Click Events'
212
+ );
213
+
214
+ $args = array(
215
+ 'labels' => $labels,
216
+ 'public' => false,
217
+ 'publicly_queryable' => false,
218
+ 'show_ui' => false,
219
+ 'show_in_menu' => false,
220
+ 'query_var' => true,
221
+ 'rewrite' => array('slug' => 'click-event'),
222
+ 'capability_type' => 'post',
223
+ 'has_archive' => true,
224
+ 'hierarchical' => false,
225
+ 'menu_position' => null,
226
+ 'supports' => false
227
+ );
228
+ register_post_type('wpgae_click_event', $args);
229
+
230
+ add_action('save_post_wpgae_click_event', 'WPGAEGClickEvent::save_event');
231
+ }
232
+ }
233
+
234
+ class WPGAEGScrollEvent extends WPGAEGeneralEvent{
235
+ protected $event;
236
+ protected static $keys = array('selector', 'type', 'category', 'action', 'label', 'bounce', 'value');
237
+ protected static $my_options = "scroll_elements";
238
+ protected static $wpgae_post_type = "wpgae_scroll_event";
239
+ protected static $wpgae_post_columns = array (
240
+ '_wpgae_scroll_selector_meta_key' => array('title' => 'Selector', 'type' => 'input', "settings"=> "name"),
241
+ '_wpgae_scroll_type_meta_key' => array('title' => 'Type', 'type' => 'input', "settings"=> "type"),
242
+ '_wpgae_scroll_category_meta_key' => array('title' => 'Event Category', 'type' => 'input', "settings"=> "category"),
243
+ '_wpgae_scroll_action_meta_key' => array('title' => 'Event Action', 'type' => 'input', "settings"=> "action"),
244
+ '_wpgae_scroll_label_meta_key' => array('title' => 'Event Label', 'type' => 'input', "settings"=> "label"),
245
+ '_wpgae_scroll_value_meta_key' => array('title' => 'Event Value', 'type' => 'input', "settings"=> "value"),
246
+ '_wpgae_scroll_bounce_meta_key' => array('title' => 'Non-Interaction', 'type' => 'input', "settings"=> "bounce"),
247
+ );
248
+
249
+ function __construct($event_array)
250
+ {
251
+ // Create an instance of the class based off of the post columns static object.
252
+ $this->post_type = static::$wpgae_post_type;
253
+ $this->event = static::$wpgae_post_columns;
254
+ if (array_key_exists("selector", $event_array) && isset($event_array["selector"])) {
255
+ $this->event["_wpgae_scroll_selector_meta_key"]["value"] = $event_array["selector"];
256
+ }
257
+ if (array_key_exists("type", $event_array) && isset($event_array["type"])) {
258
+ $this->event["_wpgae_scroll_type_meta_key"]["value"] = $event_array["type"];
259
+ }
260
+ if (array_key_exists("category", $event_array) && isset($event_array["category"])) {
261
+ $this->event["_wpgae_scroll_category_meta_key"]["value"] = $event_array["category"];
262
+ }
263
+ if (array_key_exists("action", $event_array) && isset($event_array["action"])) {
264
+ $this->event["_wpgae_scroll_action_meta_key"]["value"] = $event_array["action"];
265
+ }
266
+ if (array_key_exists("label", $event_array) && isset($event_array["label"])) {
267
+ $this->event["_wpgae_scroll_label_meta_key"]["value"] = $event_array["label"];
268
+ }
269
+ if (array_key_exists("value", $event_array) && isset($event_array["value"])) {
270
+ $this->event["_wpgae_scroll_value_meta_key"]["value"] = $event_array["value"];
271
+ }
272
+ if (array_key_exists("bounce", $event_array) && isset($event_array["bounce"])) {
273
+ $this->event["_wpgae_scroll_bounce_meta_key"]["value"] = $event_array["bounce"];
274
+ }
275
+
276
+ }
277
+ static function convert_and_save_cached_settings($cached) {
278
+ if (sizeof($cached) > 0) {
279
+ foreach($cached as $event) {
280
+ $new_event = new WPGAEGScrollEvent($event);
281
+ $new_event->create_event();
282
+ }
283
+ return static::prepare_cache_settings();
284
+ }
285
+ }
286
+
287
+ static function wpgae_register_scroll_event_post_type()
288
+ {
289
+ $labels = array(
290
+ 'name' => 'Scroll Tracking',
291
+ 'singular_name' => 'Scroll Event',
292
+ 'add_new' => 'Add New',
293
+ 'add_new_item' => 'Add New Scroll Event',
294
+ 'edit_item' => 'Edit Scroll Event',
295
+ 'new_item' => 'New Scroll Event',
296
+ 'all_items' => 'Scroll Tracking',
297
+ 'view_item' => 'View Scroll Event',
298
+ 'search_items' => 'Search Scroll Events',
299
+ 'not_found' => 'No Scroll Events found',
300
+ 'not_found_in_trash' => 'No Scroll Events found in Trash',
301
+ 'parent_item_colon' => '',
302
+ 'menu_name' => 'Scroll Events'
303
+ );
304
+
305
+ $args = array(
306
+ 'labels' => $labels,
307
+ 'public' => false,
308
+ 'publicly_queryable' => false,
309
+ 'show_ui' => false,
310
+ 'show_in_menu' => false,
311
+ 'query_var' => true,
312
+ 'rewrite' => array('slug' => 'scroll-event'),
313
+ 'capability_type' => 'post',
314
+ 'has_archive' => true,
315
+ 'hierarchical' => false,
316
+ 'menu_position' => null,
317
+ 'supports' => false
318
+ );
319
+ register_post_type('wpgae_scroll_event', $args);
320
+ add_action('save_post_wpgae_scroll_event', 'WPGAEGScrollEvent::save_event');
321
+ }
322
+ }
include/Settings.php ADDED
@@ -0,0 +1,619 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined( 'ABSPATH' ) or die( 'Direct access not allowed!' );
3
+
4
+ class GAESettings {
5
+
6
+ function upgrade_settings() {
7
+ $installed_version = get_option('GA_EVENTS_version');
8
+ if (!isset($installed_version) || $installed_version != GA_EVENTS_VERSION) {
9
+ GAEActivation::start_activation();
10
+ }
11
+ }
12
+
13
+ /* ------------------------------------------------------------------------ *
14
+ * Menu Section
15
+ * ------------------------------------------------------------------------ */
16
+
17
+ function ga_events_menu() {
18
+
19
+ add_menu_page( 'WP Google Analytics Settings',
20
+ 'WP GA Events',
21
+ 'manage_options',
22
+ 'wp-google-analytics-events',
23
+ array( $this, 'ga_events_render_settings_page' ), // callback
24
+ GAE_PLUGIN_URL . 'images/menu-icon.png'
25
+ );
26
+
27
+ add_submenu_page( 'wp-google-analytics-events',
28
+ 'General Settings',
29
+ 'General Settings',
30
+ 'manage_options',
31
+ 'wp-google-analytics-events',
32
+ array( $this, 'ga_events_render_settings_page' ) );
33
+
34
+ add_submenu_page( 'wp-google-analytics-events',
35
+ 'Click Tracking',
36
+ 'Click Tracking',
37
+ 'manage_options',
38
+ 'wp-google-analytics-events-click',
39
+ array( $this, 'ga_events_render_settings_page' ) );
40
+
41
+ add_submenu_page( 'wp-google-analytics-events',
42
+ 'Scroll Tracking',
43
+ 'Scroll Tracking',
44
+ 'manage_options',
45
+ 'wp-google-analytics-events-scroll',
46
+ array( $this, 'ga_events_render_settings_page' ) );
47
+
48
+ add_submenu_page( 'wp-google-analytics-events',
49
+ "Getting Started Guide",
50
+ "Getting Started Guide",
51
+ 'manage_options',
52
+ 'wp-google-analytics-events-getstarted',
53
+ array( $this, 'ga_events_render_settings_page' ) );
54
+
55
+ add_submenu_page( 'wp-google-analytics-events',
56
+ "What's New",
57
+ "What's New",
58
+ 'manage_options',
59
+ 'wp-google-analytics-events-whatsnew',
60
+ array( $this, 'ga_events_render_settings_page' ) );
61
+
62
+ add_submenu_page('wp-google-analytics-events','Upgrade','Upgrade Now', 'manage_options', 'wp-google-analytics-events-upgrade', 'ga_events_settings_page' );
63
+
64
+ }
65
+
66
+
67
+
68
+ function ga_events_render_settings_page() {
69
+ ?>
70
+ <div class="wrap ga_main">
71
+ <h2>WP Google Analytics Events</h2>
72
+ <?php
73
+ // Determine which tab we are on
74
+ $active_page = isset( $_GET[ 'page' ] ) ? $_GET[ 'page' ] : 'wp-google-analytics-events';
75
+ ?>
76
+ <h2 class="nav-tab-wrapper">
77
+ <!-- General Settings -->
78
+ <a href="?page=wp-google-analytics-events" class="nav-tab <?php echo $active_page == 'wp-google-analytics-events' ? 'nav-tab-active' : ''; ?>">General Settings</a>
79
+
80
+ <!-- Click tracking -->
81
+ <a href="?page=wp-google-analytics-events-click" class="nav-tab <?php echo $active_page == 'wp-google-analytics-events-click' ? 'nav-tab-active' : ''; ?>">Click Tracking</a>
82
+
83
+ <!-- Scroll tracking -->
84
+ <a href="?page=wp-google-analytics-events-scroll" class="nav-tab <?php echo $active_page == 'wp-google-analytics-events-scroll' ? 'nav-tab-active' : ''; ?>">Scroll Tracking</a>
85
+
86
+ <!-- Getting Started Guide -->
87
+ <a href="?page=wp-google-analytics-events-getstarted" class="nav-tab <?php echo $active_page == 'wp-google-analytics-events-getstarted' ? 'nav-tab-active' : ''; ?>">Getting Started Guide</a>
88
+
89
+ <!-- What's new -->
90
+ <a href="?page=wp-google-analytics-events-whatsnew&wpgae_whatsnew_notify=2" class="nav-tab <?php echo $active_page == 'wp-google-analytics-events-whatsnew' ? 'nav-tab-active' : ''; ?>">What's New</a>
91
+
92
+ <!-- Plugin Support -->
93
+ <a href="https://wordpress.org/support/plugin/wp-google-analytics-events/" target="_blank" class="nav-tab">Plugin Support</a>
94
+ </h2>
95
+
96
+
97
+ <?php echo $active_page == 'wp-google-analytics-events' ? "<form id='ga_events_options' method='post' action='options.php'>" : ''; ?>
98
+
99
+ <?php
100
+ settings_fields( 'ga_events_options_group' );
101
+
102
+ if ( $active_page == 'wp-google-analytics-events-click' ) {
103
+ if ( file_exists( GAE_PLUGIN_PATH . '/templates/click-elements-input-table.php' ) ) {
104
+ include GAE_PLUGIN_PATH . '/templates/click-elements-input-table.php';
105
+ }
106
+ } else if ( $active_page == 'wp-google-analytics-events-scroll' ) {
107
+ if ( file_exists( GAE_PLUGIN_PATH . '/templates/scroll-elements-input-table.php' ) ) {
108
+ include GAE_PLUGIN_PATH . '/templates/scroll-elements-input-table.php';
109
+ }
110
+ } else if ( $active_page == 'wp-google-analytics-events-getstarted' ) {
111
+ do_settings_sections( 'ga_events_getstarted' );
112
+ } else if ( $active_page == 'wp-google-analytics-events-whatsnew' ) {
113
+ do_settings_sections( 'ga_events_whatsnew' );
114
+ } else {
115
+
116
+ do_settings_sections( 'ga_events_options_group' );
117
+ }
118
+
119
+ // Save button on Genral Settings tab
120
+ if ( $active_page == 'wp-google-analytics-events' ) {
121
+ submit_button();
122
+ }
123
+
124
+ // use non-ajax on click tracking page - disabled
125
+ if ( $active_page == 'wp-google-analytics-events-click' ) {
126
+ //submit_button();
127
+ }
128
+ ?>
129
+
130
+ <?php echo $active_page == 'wp-google-analytics-events' ? "</form>" : '';
131
+ // Save button on Genral Settings tab
132
+ if ( $active_page == 'wp-google-analytics-events' ) {
133
+ ?>
134
+ <div class="settings_content">
135
+ <form action="" method="post" enctype="multipart/form-data">
136
+ <a href="#" class="btn_close"><img src="<?php echo GAE_PLUGIN_URL ?>images/close.png"></a>
137
+ <input type="file" name="ga_settings_import">
138
+ <input type="hidden" name="ga_events_action" value="import_settings" />
139
+ <?php
140
+ wp_nonce_field( 'ga_events_import_nonce',
141
+ 'ga_events_import_nonce' );
142
+ ?>
143
+ <input type="submit" name="set_settings">
144
+ </form>
145
+ </div>
146
+
147
+ <div class="wrap ga_events_banner ga_events_sidebar">
148
+ <!-- <div class="wrap ga_events_sidebar">-->
149
+ <table class="form-table widefat" >
150
+ <thead>
151
+ <th>Need More Features?</th>
152
+ </thead>
153
+ <tbody>
154
+ <tr class="features">
155
+ <td>
156
+ <ul>
157
+ <li><i class="fa fa-check-square-o fa-lg"></i><strong>Link Tracking</strong></li>
158
+ <li title="Dynamic Event Data"><i class="fa fa-check-square-o fa-lg"></i><strong>Placeholders</strong></li>
159
+ <li><i class="fa fa-check-square-o fa-lg"></i><strong>Track your Self-Hosted Media video and audio</strong></li>
160
+ <li><i class="fa fa-check-square-o fa-lg"></i><strong>YouTube Video Tracking</strong></li>
161
+ <li><i class="fa fa-check-square-o fa-lg"></i><strong>Vimeo Video support</strong></li>
162
+ <li><i class="fa fa-check-square-o fa-lg"></i><strong>Allow non-admin users to manage the plugin</strong></li>
163
+ <li><i class="fa fa-check-square-o fa-lg"></i><strong>HTML Tag support</strong></li>
164
+ <li><i class="fa fa-check-square-o fa-lg"></i><strong>Access to our Pro Support Team</strong></li>
165
+ </ul>
166
+ </td>
167
+ </tr>
168
+ <tr class="tfoot">
169
+ <td>
170
+ <div class="wpcta">
171
+ <a class="button-primary button-large" target="_blank" href="https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=genreal">
172
+ <span class="btn-title ">
173
+ Upgrade Now
174
+ </span>
175
+ </a>
176
+ </div>
177
+ </td>
178
+ </tr>
179
+ </tbody>
180
+ </table>
181
+
182
+ </div>
183
+ <?php } ?>
184
+ <?php
185
+ }
186
+
187
+
188
+ /* ------------------------------------------------------------------------ *
189
+ * Setting Registration
190
+ * ------------------------------------------------------------------------ */
191
+
192
+ function ga_events_initialize_plugin_options() {
193
+
194
+ register_setting( 'ga_events_options_group',
195
+ 'ga_events_options',
196
+ array( $this, 'update_settings_callback' ) );
197
+
198
+ /* ------------------------------------------------------------------------ *
199
+ * Settings sections
200
+ * ------------------------------------------------------------------------ */
201
+
202
+ add_settings_section( 'ga_events_main',
203
+ 'WP Google Analytics Events Settings',
204
+ array( $this, 'ga_events_section_text' ),
205
+ 'ga_events_options_group' );
206
+
207
+ add_settings_section( 'ga_events_getstarted_section',
208
+ "",
209
+ array( $this, 'ga_events_getstarted_section_content' ),
210
+ 'ga_events_getstarted' );
211
+
212
+ add_settings_section( 'ga_events_whatsnew_section',
213
+ "",
214
+ array( $this, 'ga_events_whatsnew_section_content' ),
215
+ 'ga_events_whatsnew' );
216
+
217
+ /* ------------------------------------------------------------------------ *
218
+ * Settings Fields
219
+ * ------------------------------------------------------------------------ */
220
+
221
+ // GA id field
222
+ add_settings_field( 'ga_events_id',
223
+ '',
224
+ array( $this, 'ga_events_tracking_id_input' ), // Rendering callback
225
+ 'ga_events_options_group', // page name
226
+ 'ga_events_main' ); // section name
227
+ // Domain field
228
+ add_settings_field( 'ga_events_domain',
229
+ '',
230
+ array( $this, 'ga_events_setting_domain_input' ), // Callback
231
+ 'ga_events_options_group',
232
+ 'ga_events_main' );
233
+
234
+ // Anonymize IP checkbox
235
+ add_settings_field( 'ga_events_anonymizeip',
236
+ '',
237
+ array($this, 'ga_events_setting_anon_input'),
238
+ 'ga_events_options_group',
239
+ 'ga_events_main' );
240
+
241
+ // Snippet type select menu input
242
+ add_settings_field( 'ga_events_snippet_type',
243
+ '',
244
+ array($this, 'ga_events_setting_snippet_type_input'),
245
+ 'ga_events_options_group',
246
+ 'ga_events_main' );
247
+
248
+ // GTM ID input
249
+ add_settings_field( 'ga_events_gtm_id',
250
+ '',
251
+ array($this, 'ga_events_setting_gtm_id_input'),
252
+ 'ga_events_options_group',
253
+ 'ga_events_main' );
254
+
255
+
256
+ // Advanced options checkbox
257
+ add_settings_field( 'ga_events_advanced',
258
+ '',
259
+ array($this, 'ga_events_setting_adv_input'),
260
+ 'ga_events_options_group',
261
+ 'ga_events_main' );
262
+
263
+ // Script debug mode
264
+ add_settings_field( 'ga_events_script_debug_mode',
265
+ '',
266
+ array($this, 'ga_events_setting_script_debug_mode_input'),
267
+ 'ga_events_options_group',
268
+ 'ga_events_main' );
269
+
270
+ // Export settings
271
+ add_settings_field( 'ga_events_download_settings',
272
+ '',
273
+ array($this, 'ga_events_settings_download'),
274
+ 'ga_events_options_group',
275
+ 'ga_events_main' );
276
+
277
+ // Import settings
278
+ add_settings_field( 'ga_events_upload_settings',
279
+ '',
280
+ array($this, 'ga_events_settings_upload'),
281
+ 'ga_events_options_group', // needed?
282
+ 'ga_events_main' );
283
+
284
+ // Let settings callback know we're on general settings page
285
+ add_settings_field( 'ga_events_confirm_general_settings_page',
286
+ '',
287
+ array($this, 'ga_events_settings_confirm_general_settings_page'),
288
+ 'ga_events_options_group', // needed?
289
+ 'ga_events_main' );
290
+
291
+ }
292
+
293
+ function update_settings_callback( $input ) {
294
+
295
+ // Very useful for debugging
296
+ // error_log( print_r( $input,
297
+ // true ) );
298
+
299
+ $options = get_option( 'ga_events_options' );
300
+ $updated = $options;
301
+
302
+ // Loop through each of the incoming options
303
+ foreach ( $input as $key => $value ) {
304
+
305
+ if ( isset( $input[ $key ] ) ) {
306
+
307
+ // Sanitize input
308
+ $updated[ $key ] = $this->strip_tags_deep( $input[ $key ] );
309
+ }
310
+ }
311
+ // This code is only run if we are on the general settins page
312
+ // otherwise these settings would get updated by changes on other
313
+ // pages as we only have one callback covering all the settings pages
314
+ if ( isset( $input[ 'which_page' ] ) && $input[ 'which_page' ] == 'general-settings' ) {
315
+
316
+
317
+ // The case of the empty checkboxes - anonymize ip
318
+ if ( ! isset( $input[ 'anonymizeip' ] ) ) {
319
+ $updated[ 'anonymizeip' ] = '0';
320
+ }
321
+
322
+ // The case of the empty checkboxes - advanced mode
323
+ if ( ! isset( $input[ 'advanced' ] ) ) {
324
+ $updated[ 'advanced' ] = '0';
325
+ }
326
+
327
+ // The case of the empty checkboxes - script debug mode
328
+ if ( ! isset( $input[ 'script_debug_mode' ] ) ) {
329
+ $updated[ 'script_debug_mode' ] = '0';
330
+ }
331
+
332
+ }
333
+
334
+ // Remove page identifier
335
+ unset( $updated[ 'which_page' ] );
336
+
337
+ // Return new modified options array
338
+ return $updated;
339
+ }
340
+
341
+ /* ------------------------------------------------------------------------ *
342
+ * Section Callbacks
343
+ * ------------------------------------------------------------------------ */
344
+
345
+ function ga_events_section_text() {
346
+ ?>
347
+ <a href='http://wpflow.com/documentation/'>Need Help?</a>
348
+ <span style='margin-left:8px;'>
349
+ <a href='https://wordpress.org/support/plugin/wp-google-analytics-events/'>Support</a>
350
+ </span>
351
+ <?php
352
+ }
353
+
354
+ function ga_events_clicks_section_text() {
355
+ ?>
356
+ <p>Click Events</p>
357
+ <?php
358
+ }
359
+
360
+ function ga_events_scrolls_section_text() {
361
+ ?>
362
+ <p>Scroll Events</p>
363
+ <?php
364
+ }
365
+
366
+ function ga_events_getstarted_section_content() {
367
+ if ( file_exists( GAE_PLUGIN_PATH . '/templates/getting-started-guide-section.php' ) ) {
368
+ include GAE_PLUGIN_PATH . '/templates/getting-started-guide-section.php';
369
+ }
370
+ }
371
+
372
+ function ga_events_whatsnew_section_content() {
373
+ if ( file_exists( GAE_PLUGIN_PATH . '/templates/whats-new-section-content.php' ) ) {
374
+ include GAE_PLUGIN_PATH . '/templates/whats-new-section-content.php';
375
+ }
376
+ }
377
+
378
+ /* ------------------------------------------------------------------------ *
379
+ * Field Callbacks
380
+ * ------------------------------------------------------------------------ */
381
+
382
+ // General Settings page begins
383
+
384
+ function ga_events_tracking_id_input() {
385
+ // Read the social options collection.
386
+ $options = get_option( 'ga_events_options' );
387
+
388
+ // Make sure the element is defined in the options. If not, set an empty string.
389
+ $id = isset( $options[ 'tracking_id' ] ) ? $options[ 'tracking_id' ] : '';
390
+
391
+ // Output HTML
392
+ ?>
393
+ <label>Google Analytics Tracking ID</label><input name='ga_events_options[tracking_id]' type='text' value="<?php echo $id; ?>" />
394
+ <?php
395
+ }
396
+
397
+ function ga_events_setting_domain_input() {
398
+ $options = get_option( 'ga_events_options' );
399
+ $domain = isset( $options[ 'domain' ] ) ? $options[ 'domain' ] : '';
400
+ echo "<label>Domain (optional)</label>";
401
+
402
+ echo "<input id='domain' name='ga_events_options[domain]' type='text' value='$domain' />";
403
+ }
404
+
405
+ function ga_events_setting_anon_input() {
406
+ $options = get_option( 'ga_events_options' );
407
+ $value = isset( $options[ 'anonymizeip' ] ) ? $options[ 'anonymizeip' ] : '0';
408
+ echo "<label>IP Anonymization </i>" . $this->ga_tooltip( 'Tell Google Analytics not to log IP Addresses. Requires code snippet to be selected (but not GTM container).' ) . "</label>";
409
+
410
+ echo "<input id='anonymizeip' name='ga_events_options[anonymizeip]' type='checkbox' value='1' " . checked( $value,
411
+ 1,
412
+ false ) . " />";
413
+ }
414
+
415
+ function ga_events_setting_snippet_type_input() {
416
+
417
+ $options = get_option( 'ga_events_options' );
418
+
419
+ /*
420
+ * TO DO Needs testing with upgrade
421
+ * Should have been set in upgrade function in wp-google-analytics-events.php
422
+ */
423
+ $defaultOption = isset( $options[ 'snippet_type' ] ) ? $options[ 'snippet_type' ] : 'none';
424
+ echo "<label>Snippet type to add: " . $this->ga_tooltip( 'The Google Analytics snippet to add if any.' ) . "</label>";
425
+ ?>
426
+ <select id="snippet_type" name='ga_events_options[snippet_type]'>
427
+ <option value="gtm" <?php selected($defaultOption, 'gtm') ?>>Google Tag Manager Container</option>
428
+ <option value="gst" <?php selected($defaultOption, 'gst') ?>>Global Site Tag (gtag.js)</option>
429
+ <option value="universal" <?php selected($defaultOption, 'universal') ?>>Universal (analytics.js)</option>
430
+ <option value="legacy" <?php selected($defaultOption, 'legacy') ?>>Legacy (ga.js)</option>
431
+ <option value='none' <?php selected($defaultOption, 'none') ?>>None</option>
432
+ </select>
433
+ <?php
434
+ }
435
+
436
+ function ga_events_setting_gtm_id_input() {
437
+ $options = get_option( 'ga_events_options' );
438
+ $gtm_id = isset( $options[ 'gtm_id' ] ) ? $options[ 'gtm_id' ] : '';
439
+ echo "<label>Google Tag Manager Container ID" . $this->ga_tooltip( 'Your GTM container ID, which you can get from your GTM account' ) . "</label>";
440
+ echo "<input id='gtm_id' name='ga_events_options[gtm_id]' type='text' value='$gtm_id' />";
441
+ }
442
+
443
+ function ga_events_setting_adv_input() {
444
+ $options = get_option( 'ga_events_options' );
445
+ $value = isset( $options[ 'advanced' ] ) ? $options[ 'advanced' ] : '0';
446
+ echo "<label>Advanced Mode " . $this->ga_tooltip( 'Enable Advanced Selectors' ) . "</label>";
447
+ echo "<input id='advanced' name='ga_events_options[advanced]' type='checkbox' value='1' " . checked( $value,
448
+ '1',
449
+ false ) . " />";
450
+ }
451
+
452
+ function ga_events_setting_script_debug_mode_input() {
453
+ $options = get_option( 'ga_events_options' );
454
+ $value = isset( $options[ 'script_debug_mode' ] ) ? $options[ 'script_debug_mode' ] : '0';
455
+ echo "<label>Support Friendly Scripts " . $this->ga_tooltip( 'Uncheck for script minimization' ) . "</label>";
456
+ echo "<input id='script_debug_mode' name='ga_events_options[script_debug_mode]' type='checkbox' value='1' " . checked( $value,
457
+ '1',
458
+ false ) . " />";
459
+ }
460
+
461
+ function ga_events_settings_download() {
462
+ echo '<a class="button" href="http://' . $_SERVER[ "HTTP_HOST" ] . $_SERVER[ "REQUEST_URI" ] . '&download=1">Export settings</a>';
463
+ }
464
+
465
+ function ga_events_settings_upload() {
466
+ echo '<a href="#" class="button btn_upload">Import settings</a>';
467
+ }
468
+
469
+ function ga_events_settings_confirm_general_settings_page() {
470
+ ?>
471
+ <input type="hidden" name='ga_events_options[which_page]' value="general-settings">
472
+ <?php
473
+ }
474
+
475
+ // General settings page ends
476
+ // What's new section
477
+ function ga_events_setting_whatsnew_input() {
478
+
479
+ // Currently not used
480
+ }
481
+
482
+ // Callback for adding settings link next to listing on plugins page
483
+ function plugin_add_settings_link( $links ) {
484
+ $upgrade = '<a target="_blank" href="https://wpflow.com/upgrade?utm_source=wpadmin&utm_medium=link&utm_campaign=plugin-settings"">' . __('Upgrade', 'General') . '</a>';
485
+ $settings_link = '<a href="admin.php?page=wp-google-analytics-events">' . __( 'Settings' ) . '</a>';
486
+ array_unshift( $links,
487
+ $settings_link );
488
+ array_unshift( $links,
489
+ $upgrade );
490
+ return $links;
491
+ }
492
+
493
+ /* ------------------------------------------------------------------------ *
494
+ * Helpers
495
+ * ------------------------------------------------------------------------ */
496
+
497
+ function ga_events_download_settings() {
498
+
499
+ if ( isset( $_GET[ 'download' ] ) && isset( $_GET[ 'page' ] ) ) {
500
+ if ( $_GET[ 'page' ] == 'wp-google-analytics-events' ) {
501
+ $options = get_option( 'ga_events_options' );
502
+ // the version number currently has its own option in db. Un comment below if needed.
503
+ //$options[ 'GA_EVENTS_version' ] = get_option( 'GA_EVENTS_version' );
504
+ $settings = json_encode( $options );
505
+
506
+ nocache_headers();
507
+ header( 'Content-Type: application/json; charset=utf-8' );
508
+ header( 'Content-Disposition: attachment; filename=ga-events-pro-settings-export-' . date( 'm-d-Y' ) . '.json' );
509
+ header( "Expires: 0" );
510
+
511
+ echo $settings;
512
+ exit;
513
+ }
514
+ }
515
+ }
516
+
517
+ function ga_events_import_settings() {
518
+
519
+ if ( empty( $_POST[ 'ga_events_action' ] ) || 'import_settings' != $_POST[ 'ga_events_action' ] ) {
520
+ return;
521
+ }
522
+
523
+ if ( ! wp_verify_nonce( $_POST[ 'ga_events_import_nonce' ],
524
+ 'ga_events_import_nonce' ) ) {
525
+ return;
526
+ }
527
+
528
+ $temp = explode( '.',
529
+ $_FILES[ 'ga_settings_import' ][ 'name' ] );
530
+ $extension = end( $temp );
531
+
532
+ if ( $extension != 'json' ) {
533
+ wp_die( __( 'Please upload a valid .json file' ) );
534
+ }
535
+
536
+ $import_file = $_FILES[ 'ga_settings_import' ][ 'tmp_name' ];
537
+
538
+ if ( empty( $import_file ) ) {
539
+ wp_die( __( 'Please upload a file to import' ) );
540
+ }
541
+
542
+ // Retrieve the settings from the file and convert the json object to an array.
543
+ $settings = json_decode( file_get_contents( $import_file ),
544
+ true );
545
+
546
+
547
+ WPGAEGClickEvent::delete_all_event_posts();
548
+ WPGAEGScrollEvent::delete_all_event_posts();
549
+
550
+
551
+ if (isset($settings["click_elements"])) {
552
+ $new_click_elements = $settings["click_elements"];
553
+ foreach($new_click_elements as &$item) {
554
+ $item["selector"] = $item["name"];
555
+ unset($item["name"]);
556
+ }
557
+ $click_elements = WPGAEGClickEvent::convert_and_save_cached_settings($new_click_elements);
558
+ }
559
+
560
+ if (isset($settings["scroll_elements"])) {
561
+ $new_scroll_elements = $settings["scroll_elements"];
562
+ foreach($new_scroll_elements as &$item) {
563
+ $item["selector"] = $item["name"];
564
+ unset($item["name"]);
565
+ }
566
+ $scroll_elements = WPGAEGScrollEvent::convert_and_save_cached_settings($new_scroll_elements);
567
+ }
568
+ // die(var_dump($settings));
569
+ update_option( 'ga_events_options',
570
+ $settings );
571
+
572
+ wp_safe_redirect( admin_url( 'admin.php?page=wp-google-analytics-events' ) );
573
+ exit;
574
+ }
575
+
576
+ function ga_tooltip( $content = '' ) {
577
+ $html = '<span class="ga-tooltip" title="' . $content . '"></span>';
578
+ return $html;
579
+ }
580
+
581
+ function createCheckbox( $name, $id, $value, $label, $isChecked = false ) {
582
+ $html = '<input type="checkbox" id="' . $id . '" name="' . $name . '" value="' . $value . '" ';
583
+ $html .= $isChecked ? 'checked>' : '>';
584
+ $html .= $label . '&nbsp&nbsp&nbsp&nbsp';
585
+ return $html;
586
+ }
587
+
588
+ function is_selected( $value, $stored ) {
589
+ if ( $stored == $value ) {
590
+ return "selected";
591
+ }
592
+ return "";
593
+ }
594
+
595
+ function create_dropdown( $name, $id, $options = array(), $selected = 'unknown' ) {
596
+ $html = '';
597
+ if ( ! empty( $options ) ) {
598
+ $html .= "<select id='$id' name='$name'>";
599
+
600
+ foreach ( $options as $key => $value ) {
601
+ $html .= $selected == $key ? "<option selected value='$key' >$value</option>" : "<option value='$key' >$value</option>";
602
+ }
603
+
604
+ $html .= "</select>";
605
+ }
606
+ return $html;
607
+ }
608
+
609
+ function strip_tags_deep( $value ) {
610
+ $value = is_array( $value ) ?
611
+ array_map( array( $this, 'strip_tags_deep' ),
612
+ $value ) :
613
+ strip_tags( $value );
614
+
615
+ return $value;
616
+ }
617
+
618
+ }
619
+
include/Snippets.php ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class GAESnippets {
4
+
5
+ static function add_google_tag_manager_container() {
6
+ $options = get_option( 'ga_events_options' );
7
+ $gtm_id = isset( $options[ 'gtm_id' ] ) ? $options[ 'gtm_id' ] : '';
8
+
9
+ echo <<<EOF
10
+ <!-- Google Tag Manager -->
11
+ <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
12
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
13
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
14
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
15
+ })(window,document,'script','dataLayer','$gtm_id');</script>
16
+ <!-- End Google Tag Manager -->
17
+
18
+ EOF;
19
+ // TODO discuss this implementtion with Yuval as it requires theme modification
20
+ add_action( 'wp_after_body',
21
+ 'add_google_tag_manager_noscript' );
22
+ }
23
+
24
+ static function add_google_tag_manager_noscript() {
25
+
26
+ // This part is for running GA without JS on page. However this plugin requires JS, so the snippet is strictly redundant, although GA detetcts its absence
27
+ echo <<<EOF
28
+ <!-- Google Tag Manager (noscript) -->
29
+ <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-WPTPJ6G"
30
+ height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
31
+ <!-- End Google Tag Manager (noscript) -->
32
+ EOF;
33
+ }
34
+
35
+ static function add_global_site_tag() {
36
+ $options = get_option( 'ga_events_options' );
37
+ $id = $options[ 'tracking_id' ];
38
+ $anonymize_ip = $options[ 'anonymizeip' ];
39
+ $anonymize_ip_string = (isset($anonymize_ip) && $anonymize_ip) ? "{ 'anonymize_ip': true }" : "{ 'anonymize_ip': false }";
40
+ echo <<<EOF
41
+ <!-- Global site tag (gtag.js) - Google Analytics -->
42
+ <script async src="https://www.googletagmanager.com/gtag/js?id=$id"></script>
43
+ <script>
44
+ window.dataLayer = window.dataLayer || [];
45
+ function gtag() {
46
+ dataLayer.push(arguments);
47
+ }
48
+ gtag('js', new Date());
49
+
50
+ gtag('config', '$id', $anonymize_ip_string );
51
+ </script>
52
+
53
+ EOF;
54
+ }
55
+
56
+ static function add_universal_tag() {
57
+ $options = get_option( 'ga_events_options' );
58
+
59
+ $id = $options[ 'tracking_id' ];
60
+ if ( isset( $options[ 'domain' ] ) && $options[ 'domain' ] != "" ) {
61
+ $domain = $options[ 'domain' ];
62
+ } else {
63
+ $domain = 'auto';
64
+ }
65
+ $ga_create_call = (isset( $options[ 'anonymizeip' ] ) && $options[ 'anonymizeip' ]) ? "ga('create','$id', '$domain', {anonymizeIp: true});" : "ga('create','$id', '$domain');";
66
+
67
+ echo <<<EOF
68
+ <script>
69
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
70
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
71
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
72
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
73
+ $ga_create_call
74
+ ga('send', 'pageview');
75
+ </script>
76
+
77
+ EOF;
78
+ }
79
+
80
+ static function add_legacy_tag() {
81
+ // Legacy at time of writing means the ga.js api
82
+ $options = get_option( 'ga_events_options' );
83
+
84
+ $id = $options[ 'tracking_id' ];
85
+ if ( isset( $options[ 'domain' ] ) && $options[ 'domain' ] != "" ) {
86
+ $domain = $options[ 'domain' ];
87
+ } else {
88
+ $domain = 'auto';
89
+ }
90
+ if ( $domain == 'auto' ) {
91
+ $domain = $_SERVER[ 'SERVER_NAME' ];
92
+ }
93
+ $anon = (isset( $options[ 'anonymizeip' ] ) && $options[ 'anonymizeip' ]) ? "_gaq.push (['_gat._anonymizeIp'])" : "";
94
+
95
+ echo <<<EOF
96
+ <script type='text/javascript'>
97
+ var _gaq = _gaq || [];
98
+ _gaq.push(['_setAccount', '$id']);
99
+ $anon
100
+ _gaq.push(['_setAllowLinker', true]);
101
+ _gaq.push(['_trackPageview']);
102
+
103
+ (function() {
104
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
105
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
106
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
107
+ })();
108
+ </script>
109
+
110
+ EOF;
111
+ }
112
+
113
+ /*
114
+ * Insert tracking snippet of type chosen by user
115
+ */
116
+
117
+ static function add_snippet_to_header() {
118
+ $options = get_option( 'ga_events_options' );
119
+ $snippet_type = $options[ 'snippet_type' ];
120
+
121
+ // Add snippet based on snippet_type in options
122
+ switch ( $snippet_type ) {
123
+ case 'gtm':
124
+ self::add_google_tag_manager_container();
125
+ break;
126
+ case 'gst':
127
+ self::add_global_site_tag();
128
+ break;
129
+ case 'universal':
130
+ self::add_universal_tag();
131
+ break;
132
+ case 'legacy':
133
+ self::add_legacy_tag();
134
+ break;
135
+ }
136
+ }
137
+
138
+ }
include/TrackingTable.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if( ! class_exists( 'WP_List_Table' ) ) {
4
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
5
+ }
6
+
7
+
8
+ class WPGAE_Tracking_Table extends WP_List_Table {
9
+
10
+ protected $wpgae_post_type;
11
+ protected $wpgae_post_columns;
12
+ protected $wpgae_first_column;
13
+
14
+
15
+ function get_columns(){
16
+ $columns = array();
17
+ $columns['cb'] = '<input type="checkbox" />';
18
+ foreach($this->wpgae_post_columns as $key => $value) {
19
+ $columns[$key] = $value["title"];
20
+ }
21
+ return $columns;
22
+ }
23
+
24
+ function getData() {
25
+ if (isset($_POST["s"]) && $_POST["s"] != "") {
26
+ $meta_query = array(
27
+ 'relation' => 'OR'
28
+ );
29
+
30
+ foreach($this->wpgae_post_columns as $key => $value) {
31
+ $entry = array(
32
+ 'key' => $key,
33
+ 'value' => $_POST["s"],
34
+ 'compare' => 'LIKE'
35
+ );
36
+ array_push($meta_query, $entry);
37
+ }
38
+
39
+ $tracking_entries = get_posts(array(
40
+ 'post_type' => $this->wpgae_post_type,
41
+ 'post_status' => 'publish',
42
+ 'numberposts' => -1,
43
+ 'meta_query' => $meta_query
44
+ // 'order' => 'ASC'
45
+ ));
46
+
47
+
48
+ if (isset($tracking_entries)) {
49
+ return $tracking_entries;
50
+ }
51
+ }
52
+ else {
53
+ $tracking_entries = get_posts(array(
54
+ 'post_type' => $this->wpgae_post_type,
55
+ 'post_status' => 'publish',
56
+ 'numberposts' => -1
57
+ // 'order' => 'ASC'
58
+ ));
59
+
60
+ if (isset($tracking_entries)) {
61
+ return $tracking_entries;
62
+ }
63
+ }
64
+ }
65
+
66
+ function getColumnData($post, $column_name) {
67
+ if ($column_name == "cb") {
68
+ return column_cb($post);
69
+ }
70
+ // Todo - can we optimize this so we query the post meta just once?
71
+ $post_meta = get_post_meta($post->ID);
72
+ if (isset($post_meta[$column_name]) && isset($post_meta[$column_name][0])) {
73
+ $column_data = $post_meta[$column_name][0];
74
+ $column_type = $this->wpgae_post_columns[$column_name]["type"];
75
+ if ($column_type == "checkbox") {
76
+ return $column_data ? "<i class='far fa-check-square' style='font-style: normal;font-family:FontAwesome'></i>": "";
77
+ }
78
+ return $column_data;
79
+ } else {
80
+ return "";
81
+ }
82
+ }
83
+
84
+ function column_cb($item) {
85
+ return sprintf(
86
+ '<input type="checkbox" name="wpgae_event[]" value="%s" />', $item->ID
87
+ );
88
+ }
89
+
90
+ function prepare_items() {
91
+ $columns = $this->get_columns();
92
+ $hidden = array();
93
+ $sortable = array();
94
+ $this->_column_headers = array($columns, $hidden, $sortable, $this->wpgae_first_column);
95
+ $this->items = $this->getData();
96
+
97
+ $this->process_bulk_action();
98
+ }
99
+
100
+ function column_default( $item, $column_name ) {
101
+ if (array_key_exists($column_name, $this->wpgae_post_columns)) {
102
+ return $this->getColumnData($item, $column_name);
103
+ }
104
+ return print_r( $item, true ) ; //Show the whole array for troubleshooting purposes
105
+ }
106
+ //
107
+ function get_bulk_actions() {
108
+ $actions = array(
109
+ 'delete' => 'Delete'
110
+ );
111
+ return $actions;
112
+ }
113
+
114
+ function process_bulk_action() {
115
+ if ( isset( $_POST['_wpnonce'] ) && ! empty( $_POST['_wpnonce'] ) ) {
116
+ $nonce = filter_input( INPUT_POST, '_wpnonce', FILTER_SANITIZE_STRING );
117
+ $action = 'bulk-' . $this->_args['plural'];
118
+
119
+ if ( ! wp_verify_nonce( $nonce, $action ) )
120
+ wp_die( 'Nope, not this time' );
121
+ }
122
+ $action = $this->current_action();
123
+
124
+ if ($action == "delete") {
125
+ $posts = isset( $_POST['wpgae_event'] ) ? (array) $_POST['wpgae_event'] : array();
126
+ global $wpgae;
127
+ WPGAEGeneralEvent::deletePostsById($posts);
128
+ }
129
+
130
+ }
131
+ }
include/ga-events-pro-settings-default.json ADDED
@@ -0,0 +1 @@
 
1
+ {"link_clicks_delay":"0","gtm":"0","anonymizeip":"0","advanced":"0","script_debug_mode":"0","snippet_type":"universal","tracking_id":"","license":"","status":"","gtm_id":"","domain":"","excluded_roles":[],"nofollow_links":[],"scroll_elements":[],"click_elements":[],"youtube_videos":[],"vimeo_videos":[],"permitted_roles":["administrator"],"link_tracking":{"track_links":"0","type":"all","class":""}}
include/install.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function ga_events_install() {
3
+
4
+ // intial values for plugin options
5
+ $ga_events_options = array(
6
+ 'link_clicks_delay' => 120,
7
+ 'gtm' => false,
8
+ 'anonymizeip' => false,
9
+ 'advanced' => false,
10
+ 'snippet_type' => 'universal',
11
+ 'id' => '',
12
+ 'status' => '',
13
+ 'gtm_id' => '',
14
+ 'domain' => '',
15
+ // Roles for which tracking is disabled
16
+ 'scroll_track_elements' => array(),
17
+ 'click_track_elements' => array(),
18
+ // Roles with permission to modify plugin options
19
+ 'roles' => array( 'administrator' ),
20
+ );
21
+ }
{includes → include}/notice.php RENAMED
@@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) {
13
  }
14
 
15
  function whatsnew_admin_notice__success() {
16
-
17
  global $current_user;
18
  $user_id = $current_user->ID;
19
  $was_ignored = get_user_meta($user_id, 'wpgae_whatsnew_ignore_notice', true);
@@ -25,18 +25,18 @@ function whatsnew_admin_notice__success() {
25
  $active_page = isset( $_GET[ 'page' ] ) ? '&page='.esc_html( $_GET[ 'page' ] ): '';
26
  printf(__('<a href="%s" style="float:right;">Close</a>'), '?wpgae_whatsnew_notify=1'.$active_page);
27
 
28
-
29
  echo "</p></div>";
30
- }
31
  }
32
  add_action( 'admin_notices', 'whatsnew_admin_notice__success' );
33
 
34
  function wpgae_whatsnew_notify() {
35
  global $current_user;
36
- $user_id = $current_user->ID;
37
- /* If user clicks to ignore the notice, add that to their user meta */
38
- if ( isset($_GET['wpgae_whatsnew_notify']) && '1' == $_GET['wpgae_whatsnew_notify'] ) {
39
- update_user_meta($user_id, 'wpgae_whatsnew_ignore_notice', true);
40
  }
41
  }
42
  add_action('admin_init', 'wpgae_whatsnew_notify');
@@ -44,18 +44,20 @@ add_action('admin_init', 'wpgae_whatsnew_notify');
44
 
45
  /*
46
  Upon plugin activation, reset 'wpgae_whatsnew_ignore_notice' for all admin users.
47
- * This functions was called inside ga_events_install funtion.
48
  */
49
  function wpgae_reactivate_notice(){
50
 
51
  $args = array(
52
- 'role' => 'administrator'
53
  );
54
-
55
  $admins = get_users($args);
56
-
57
  foreach ($admins as $user) {
58
  update_user_meta($user->ID, 'wpgae_whatsnew_ignore_notice', false);
 
 
59
  }
60
  }
61
 
@@ -83,65 +85,65 @@ if ( ! function_exists( 'ga_events_review_notice' ) ) {
83
  $installed = ( ! empty( $actdate ) ? $actdate : '999999999999999' );
84
  if ( $installed <= $today ) {
85
  // Make sure we're on the plugins page.
86
- // If the user hasn't already dismissed our alert,
87
- // Output the activation banner.
88
- $nag_admin_dismiss_url = 'plugins.php?ga_events_review_dismiss=0';
89
- $user_meta = get_user_meta( $user_id, 'ga_events_review_dismiss' );
90
- if ( empty($user_meta) && current_user_can( 'manage_options' ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  ?>
92
- <div class="update-nag">
93
-
94
- <style>
95
- div.review {
96
- position: relative;
97
- margin-left: 35px;
98
- height: 80px;
99
- display:block;
100
- }
101
- div.review span.ga-events-icon {
102
- color: white;
103
- position: absolute;
104
- left: -30px;
105
- /*padding: 9px;*/
106
- /*top: -8px;*/
107
- }
108
- div.review strong {
109
- color: #66BB6A;
110
- }
111
- div.review a.dismiss {
112
- float: right;
113
- text-decoration: none;
114
- color: #000000;
115
- }
116
- .review a {
117
- color:#ED494D;
118
- }
119
- .ga-events-notice-text {
120
- display: inline-block;
121
- margin-left: 170px;
122
- margin-top: 24px;
123
- }
124
-
125
- </style>
126
- <?php
127
- // For testing purposes
128
- //echo '<p>Today = ' . $today . '</p>';
129
- //echo '<p>Installed = ' . $installed . '</p>';
130
- ?>
131
-
132
- <div class="review">
133
  <span class="ga-events-icon">
134
  <img src="<?php echo plugins_url( 'images/WPGAE_Logo-177x78.png', dirname(__FILE__)) ?>">
135
  </span>
136
  <span class="ga-events-notice-text">
137
- <?php echo wp_kses( sprintf( __( 'Thank you for using <strong>' . $plugin_name . '</strong>? We would love to hear about <a href="https://wpflow.com/contact">your experience</a> with the plugin. Need more features? <a href="https://wpflow.com/upgrade" target="_blank">Upgrade Now</a> to unlock.', 'ga_events_text' ), esc_url( $donate_url ), esc_url( $review_url ) ), array( 'strong' => array(), 'a' => array( 'href' => array(), 'target' => array() ) ) ); ?>
138
  </span>
139
- <a href="<?php echo admin_url( $nag_admin_dismiss_url ); ?>" class="dismiss"><span class="dashicons dashicons-dismiss"></span></a>
140
- </div>
141
-
142
  </div>
143
 
144
- <?php }
 
 
145
  }
146
  }
147
  }
13
  }
14
 
15
  function whatsnew_admin_notice__success() {
16
+
17
  global $current_user;
18
  $user_id = $current_user->ID;
19
  $was_ignored = get_user_meta($user_id, 'wpgae_whatsnew_ignore_notice', true);
25
  $active_page = isset( $_GET[ 'page' ] ) ? '&page='.esc_html( $_GET[ 'page' ] ): '';
26
  printf(__('<a href="%s" style="float:right;">Close</a>'), '?wpgae_whatsnew_notify=1'.$active_page);
27
 
28
+
29
  echo "</p></div>";
30
+ }
31
  }
32
  add_action( 'admin_notices', 'whatsnew_admin_notice__success' );
33
 
34
  function wpgae_whatsnew_notify() {
35
  global $current_user;
36
+ $user_id = $current_user->ID;
37
+ /* If user clicks to ignore the notice, add that to their user meta */
38
+ if ( isset($_GET['wpgae_whatsnew_notify']) && '1' == $_GET['wpgae_whatsnew_notify'] ) {
39
+ update_user_meta($user_id, 'wpgae_whatsnew_ignore_notice', true);
40
  }
41
  }
42
  add_action('admin_init', 'wpgae_whatsnew_notify');
44
 
45
  /*
46
  Upon plugin activation, reset 'wpgae_whatsnew_ignore_notice' for all admin users.
47
+ * This functions was called inside ga_events_install funtion.
48
  */
49
  function wpgae_reactivate_notice(){
50
 
51
  $args = array(
52
+ 'role' => 'administrator'
53
  );
54
+
55
  $admins = get_users($args);
56
+
57
  foreach ($admins as $user) {
58
  update_user_meta($user->ID, 'wpgae_whatsnew_ignore_notice', false);
59
+ delete_user_meta( $user->ID, 'ga_events_review_dismiss', "true" );
60
+
61
  }
62
  }
63
 
85
  $installed = ( ! empty( $actdate ) ? $actdate : '999999999999999' );
86
  if ( $installed <= $today ) {
87
  // Make sure we're on the plugins page.
88
+ // If the user hasn't already dismissed our alert,
89
+ // Output the activation banner.
90
+ $nag_admin_dismiss_url = 'plugins.php?ga_events_review_dismiss=0';
91
+ $user_meta = get_user_meta( $user_id, 'ga_events_review_dismiss' );
92
+ if ( empty($user_meta) && current_user_can( 'manage_options' ) ) {
93
+ ?>
94
+ <div class="update-nag">
95
+
96
+ <style>
97
+ div.review {
98
+ position: relative;
99
+ margin-left: 35px;
100
+ height: 80px;
101
+ display:block;
102
+ }
103
+ div.review span.ga-events-icon {
104
+ color: white;
105
+ position: absolute;
106
+ left: -30px;
107
+ /*padding: 9px;*/
108
+ /*top: -8px;*/
109
+ }
110
+ div.review strong {
111
+ color: #66BB6A;
112
+ }
113
+ div.review a.dismiss {
114
+ float: right;
115
+ text-decoration: none;
116
+ color: #000000;
117
+ }
118
+ .review a {
119
+ color:#ED494D;
120
+ }
121
+ .ga-events-notice-text {
122
+ display: inline-block;
123
+ margin-left: 170px;
124
+ margin-top: 24px;
125
+ }
126
+
127
+ </style>
128
+ <?php
129
+ // For testing purposes
130
+ //echo '<p>Today = ' . $today . '</p>';
131
+ //echo '<p>Installed = ' . $installed . '</p>';
132
  ?>
133
+
134
+ <div class="review">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  <span class="ga-events-icon">
136
  <img src="<?php echo plugins_url( 'images/WPGAE_Logo-177x78.png', dirname(__FILE__)) ?>">
137
  </span>
138
  <span class="ga-events-notice-text">
139
+ <?php echo wp_kses( sprintf( __( 'Thank you for using <strong>' . $plugin_name . '</strong>? We would love to hear about <a href="https://wpflow.com/contact">your experience</a> with the plugin. Need more features? <a href="https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=anotice" target="_blank">Upgrade Now</a> to unlock.', 'ga_events_text' ), esc_url( $donate_url ), esc_url( $review_url ) ), array( 'strong' => array(), 'a' => array( 'href' => array(), 'target' => array() ) ) ); ?>
140
  </span>
141
+ <a href="<?php echo admin_url( $nag_admin_dismiss_url ); ?>" class="dismiss"><span class="dashicons dashicons-dismiss"></span></a>
 
 
142
  </div>
143
 
144
+ </div>
145
+
146
+ <?php }
147
  }
148
  }
149
  }
include/saved-snippets.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+
5
+ function ga_events_get_settings(){
6
+ $options = get_option('ga_events_options');
7
+ $current = json_encode($options);
8
+
9
+ return $current;
10
+ }
11
+
12
+ /*
13
+ * Define shortcode for scroll events
14
+ */
15
+
16
+ function ga_events_short_scroll( $attr, $content ) {
17
+
18
+ $cat = isset( $attr[ 'cat' ] ) ? $attr[ 'cat' ] : 'Default Category';
19
+ $action = isset( $attr[ 'action' ] ) ? $attr[ 'action' ] : 'Default Action';
20
+ $label = isset( $attr[ 'label' ] ) ? $attr[ 'label' ] : 'Default Label';
21
+ $bounce = isset( $attr[ 'bounce' ] ) ? $attr[ 'bounce' ] : 'false';
22
+ $evalue = isset( $attr[ 'evalue' ] ) ? $attr[ 'evalue' ] : '';
23
+
24
+ if ( ! empty( $content ) ) {
25
+ $new_content = add_class_to_element( $content, 'scrollevent', $cat, $action, $label, $bounce, $evalue );
26
+ return $new_content;
27
+ }
28
+ }
29
+
30
+ add_shortcode( 'scrollevent', 'ga_events_short_scroll' );
31
+
32
+ /*
33
+ * Define shortcode for click events
34
+ */
35
+
36
+ function ga_events_short_click( $attr, $content ) {
37
+
38
+ $cat = isset( $attr[ 'cat' ] ) ? $attr[ 'cat' ] : 'Default Category';
39
+ $action = isset( $attr[ 'action' ] ) ? $attr[ 'action' ] : 'Default Action';
40
+ $label = isset( $attr[ 'label' ] ) ? $attr[ 'label' ] : 'Default Label';
41
+ $bounce = isset( $attr[ 'bounce' ] ) ? $attr[ 'bounce' ] : 'false';
42
+ $evalue = isset( $attr[ 'evalue' ] ) ? $attr[ 'evalue' ] : '';
43
+
44
+
45
+
46
+ if ( ! empty( $content ) ) {
47
+ $new_content = add_class_to_element( $content, 'clickevent', $cat, $action, $label, $bounce, $evalue );
48
+ return $new_content;
49
+ }
50
+ }
51
+
52
+ add_shortcode( 'clickevent', 'ga_events_short_click' );
53
+
54
+ ;
includes/admin.php DELETED
@@ -1,715 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * Plugin Admin Settings
5
- */
6
-
7
-
8
- add_action( 'admin_menu', 'ga_events_menu');
9
-
10
- function ga_events_menu() {
11
- add_menu_page('WP Google Analytics Settings','WP GA Events','manage_options', 'wp-google-analytics-events', 'ga_events_settings_page', plugins_url( 'images/icon.png', dirname(__FILE__)));
12
- add_submenu_page('wp-google-analytics-events','General Settings','General Settings', 'manage_options', 'wp-google-analytics-events' , 'ga_events_settings_page' );
13
- add_submenu_page('wp-google-analytics-events','Click Tracking','Click Tracking', 'manage_options', 'wp-google-analytics-events-click' , 'ga_events_settings_page' );
14
- add_submenu_page('wp-google-analytics-events','Scroll Tracking','Scroll Tracking', 'manage_options', 'wp-google-analytics-events-scroll' , 'ga_events_settings_page' );
15
- add_submenu_page('wp-google-analytics-events','Getting Started Guide','Getting Started Guide', 'manage_options', 'wp-google-analytics-events-started' , 'ga_events_settings_page' );
16
- add_submenu_page('wp-google-analytics-events',"What's New","What's New", 'manage_options', 'wp-google-analytics-events-whatsnew' , 'ga_events_settings_page' );
17
- add_submenu_page('wp-google-analytics-events','Upgrade','Upgrade Now', 'manage_options', 'wp-google-analytics-events-upgrade', 'ga_events_settings_page' );
18
- }
19
-
20
- function ga_events_settings_page() {
21
- $active_page = isset( $_GET[ 'page' ] ) ? $_GET[ 'page' ] : 'wp-google-analytics-events';
22
- $wpgae_main_class = "ga_main_full_width";
23
- $show_sidebar = false;
24
- if ($active_page == 'wp-google-analytics-events') {
25
- $wpgae_main_class= "ga_main_general_width";
26
- $show_sidebar = true;
27
- }
28
- ?>
29
- <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
30
- <div id="ga_mainwrap">
31
- <div id="ga_main" class="wrap <?php echo $wpgae_main_class; ?>">
32
- <?php screen_icon( 'plugins' ); ?>
33
- <h2>WP Google Analytics Events</h2>
34
-
35
- <h2 class="nav-tab-wrapper">
36
- <a href="?page=wp-google-analytics-events" class="nav-tab <?php echo $active_page == 'wp-google-analytics-events' ? 'nav-tab-active' : ''; ?>">General Settings</a>
37
- <a href="?page=wp-google-analytics-events-click" class="nav-tab <?php echo $active_page == 'wp-google-analytics-events-click' ? 'nav-tab-active' : ''; ?>">Click Tracking</a>
38
- <a href="?page=wp-google-analytics-events-scroll" class="nav-tab <?php echo $active_page == 'wp-google-analytics-events-scroll' ? 'nav-tab-active' : ''; ?>">Scroll Tracking</a>
39
- <a href="?page=wp-google-analytics-events-started" class="nav-tab <?php echo $active_page == 'wp-google-analytics-events-started' ? 'nav-tab-active' : ''; ?>"><i class="fa fa-question-circle ga-events-help"></i> Getting Started Guide</a>
40
- <a href="?page=wp-google-analytics-events-whatsnew&wpgae_whatsnew_notify=1" class="nav-tab <?php echo $active_page == 'wp-google-analytics-events-whatsnew' ? 'nav-tab-active' : ''; ?>"><i class="fa fa-question-circle ga-events-help"></i> What's New</a>
41
- <a href="https://wordpress.org/support/plugin/wp-google-analytics-events/" class="nav-tab" target="_blank"><i class="fa fa-question-circle ga-events-help"></i>Plugin Support</a>
42
- </h2>
43
- <?php
44
- if ($active_page == 'wp-google-analytics-events-started') {
45
- do_settings_sections('ga_events_started');
46
-
47
- }
48
- else if ($active_page == 'wp-google-analytics-events-whatsnew') {
49
- do_settings_sections('ga_events_whatsnew');
50
- }
51
- else {
52
- ?>
53
-
54
- <form id="ga-events-settings-form" method="post" action='options.php'>
55
- <?php settings_fields('ga_events_options'); ?>
56
- <?php
57
- if ($active_page == 'wp-google-analytics-events-click') {
58
- do_settings_sections('ga_events_click');
59
- } else if ($active_page == 'wp-google-analytics-events-scroll') {
60
- do_settings_sections('ga_events_scroll');
61
- }else {
62
- do_settings_sections('ga_events');
63
- }
64
- ?>
65
-
66
- <?php
67
- if ($active_page == 'wp-google-analytics-events') {
68
- ?>
69
- <input class="button-primary" type="submit" name="submit" value="Save Changes" />
70
- <?php
71
- }
72
- ?>
73
- </form>
74
- <div class="settings_content">
75
- <form action="" method="post" enctype="multipart/form-data">
76
- <a href="#" class="btn_close"><img src="<?=plugins_url( 'images/close.png', dirname(__FILE__))?>"></a>
77
- <input type="file" name="settings">
78
- <input type="submit" name="set_settings">
79
- </form>
80
- </div>
81
- </div>
82
- <?php
83
- if ($show_sidebar) {
84
- ?>
85
- <div class="wrap ga_events_banner ga_events_sidebar">
86
- <table class="form-table widefat" >
87
- <thead>
88
- <th>Need More Features?</th>
89
- </thead>
90
- <tbody>
91
- <tr class="features">
92
- <td>
93
- <ul>
94
- <li><i class="fa fa-check-square-o fa-lg"></i><strong>Link Tracking</strong></li>
95
- <li title="Dynamic Event Data"><i class="fa fa-check-square-o fa-lg"></i><strong>Placeholders</strong></li>
96
- <li><i class="fa fa-check-square-o fa-lg"></i><strong>Track your Self-Hosted Media video and audio</strong></li>
97
- <li><i class="fa fa-check-square-o fa-lg"></i><strong>YouTube Video Tracking</strong></li>
98
- <li><i class="fa fa-check-square-o fa-lg"></i><strong>Vimeo Video support</strong></li>
99
- <li><i class="fa fa-check-square-o fa-lg"></i><strong>Allow non-admin users to manage the plugin</strong></li>
100
- <li><i class="fa fa-check-square-o fa-lg"></i><strong>HTML Tag support</strong></li>
101
- <li><i class="fa fa-check-square-o fa-lg"></i><strong>Access to our Pro Support Team</strong></li>
102
- </ul>
103
- </td>
104
- </tr>
105
- <tr class="tfoot">
106
- <td>
107
- <div class="wpcta">
108
- <a class="button-primary button-large" target="_blank" href="https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=genreal">
109
- <span class="btn-title ">
110
- Upgrade Now
111
- </span>
112
- </a>
113
- </div>
114
- </td>
115
- </tr>
116
- </tbody>
117
- </table>
118
-
119
- </div>
120
- <?php } else {
121
- ?>
122
- <div class="wrap ga_events_banner ga_events_top">
123
- <div class="ga_events_featurebox ga_events_box_general">
124
- <div class="ga_events_box_title">
125
- <span>
126
- Become a Pro
127
- </span>
128
- </div>
129
- <div class="ga_events_box_body">
130
- <ul class="ga_events_box_list">
131
- <li>
132
- <div class="ga_events_box_li_icon">
133
- <img src="<?php echo plugins_url( 'images/icon_block.png', dirname(__FILE__)) ?>" />
134
- </div>
135
- <div class="ga_events_box_li_content">
136
- <span class="ga_events_box_li_title">Link Tracking</span>
137
- <span class="ga_events_box_li_txt">Automatically track any link on your website</span>
138
- </div>
139
- </li>
140
- <li>
141
- <div class="ga_events_box_li_icon">
142
- <img src="<?php echo plugins_url( 'images/icon_block.png', dirname(__FILE__)) ?>" />
143
- </div>
144
- <div class="ga_events_box_li_content">
145
- <span class="ga_events_box_li_title">Placeholder Variables</span>
146
- <span class="ga_events_box_li_txt">Include dynamic information in your events</span>
147
- </div>
148
- </li>
149
- <li>
150
- <div class="ga_events_box_li_icon">
151
- <img src="<?php echo plugins_url( 'images/icon_block.png', dirname(__FILE__)) ?>" />
152
- </div>
153
- <div class="ga_events_box_li_content">
154
- <span class="ga_events_box_li_title">User Permissions</span>
155
- <span class="ga_events_box_li_txt">Allow non Administrators to manage the plugin</span>
156
- </div>
157
- </li>
158
- </ul>
159
- </div>
160
- <div>
161
- <a class="btn" href="https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=btng">Go Pro</a>
162
- </div>
163
- </div>
164
- <div class="ga_events_featurebox ga_events_box_video">
165
- <div class="ga_events_box_title">
166
- <span>
167
- Track Videos like a Pro
168
- </span>
169
- </div>
170
- <div class="ga_events_box_body">
171
- <ul class="ga_events_box_list">
172
- <li>
173
- <div class="ga_events_box_li_icon">
174
- <img src="<?php echo plugins_url( 'images/icon_lock.png', dirname(__FILE__)) ?>" />
175
- </div>
176
- <div class="ga_events_box_li_content">
177
- <span class="ga_events_box_li_title">Self-Hosted Media - Track Audio and Video</span>
178
- <span class="ga_events_box_li_txt">Track all video play/stop events and create
179
- smarter segments on how people watch your content.</span>
180
- </div>
181
- </li>
182
- <li>
183
- <div class="ga_events_box_li_icon" style="margin-top:10px">
184
- <img src="<?php echo plugins_url( 'images/icon_lock.png', dirname(__FILE__)) ?>" />
185
- </div>
186
- <div class="ga_events_box_li_content" style="margin-top:10px">
187
- <span class="ga_events_box_li_title">YouTube and Vimeo Video support</span>
188
- <span class="ga_events_box_li_txt">We also support YouTube and Vimeo</span>
189
- </div>
190
- </li>
191
- </ul>
192
- </div>
193
- <a class="btn" href="https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=btnv">Go Premium</a>
194
- </div>
195
- <div class="ga_events_featurebox ga_events_box_support">
196
- <div class="ga_events_box_title">
197
- <span>
198
- Product Support
199
- </span>
200
- </div>
201
- <div class="ga_events_box_body">
202
- <ul class="ga_events_box_list">
203
- <li>
204
- <div class="ga_events_box_li_content">
205
- <span class="ga_events_box_li_title" style="margin-left:40px;">Premium Support</span>
206
- <span class="ga_events_box_li_txt" style="margin-left:40px;">Direct super-fast help from our dedicated support team</span>
207
- </div>
208
- </li>
209
- </ul>
210
- </div>
211
- <a class="btn" href="https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=btns">Get Pro Support</a>
212
- </div>
213
- </div>
214
- <?php } ?>
215
- </div> <!-- END #ga_mainwrap ->
216
- <?php
217
- } ?>
218
-
219
-
220
- <?php
221
-
222
- echo "<script>
223
- jQuery('.remove').click(function (event) {
224
- event.preventDefault();
225
- jQuery(this).closest('tr').remove();
226
- });
227
- jQuery('.add').click(function (event) {
228
- event.preventDefault();
229
- });
230
- </script>
231
- ";
232
- }
233
-
234
- function wpgae_load_custom_wp_admin_style() {
235
- wp_register_style( 'wpgae-font-awesome', '//maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css' );
236
- wp_register_style( 'custom_wp_admin_css', plugins_url('css/style.css', dirname(__FILE__)), array('wpgae-font-awesome'));
237
- wp_enqueue_style( 'custom_wp_admin_css' );
238
-
239
- $params = array(
240
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
241
- 'advaced' => $advanced,
242
- 'ajaxnonce' => wp_create_nonce('wpgae_nonce_CRX0XDPfqe5dd3P')
243
- );
244
- wp_register_script( 'wpgae-ajax', plugins_url('js/ajax.js', dirname(__FILE__)) , array('jquery') );
245
- wp_localize_script( 'wpgae-ajax', 'wpgae_ajax', $params);
246
-
247
- wp_enqueue_script( 'admin-init', plugins_url('js/admin.js', dirname(__FILE__)) , array('jquery','jquery-ui-tooltip','wpgae-ajax'), null, true );
248
- }
249
-
250
- add_action( 'admin_enqueue_scripts', 'wpgae_load_custom_wp_admin_style' );
251
-
252
- add_action('admin_init', 'ga_events_admin_init');
253
-
254
- function ga_events_admin_init() {
255
- if(isset($_GET['download']) && isset($_GET['page'])){
256
- if ($_GET['page'] == 'wp-google-analytics-events') {
257
- ga_events_file();
258
- }
259
- }
260
-
261
- if(isset($_POST['set_settings'])){
262
- ga_events_upload_settings($_FILES);
263
- }
264
-
265
-
266
- register_setting('ga_events_options','ga_events_options','ga_events_validate');
267
- add_settings_section('ga_events_main','WP Google Analytics Events Settings', 'ga_events_gs_section_text','ga_events');
268
- add_settings_section('ga_events_click_section','', 'ga_events_click_section_text','ga_events_click');
269
- add_settings_section('ga_events_scroll_section','', 'ga_events_scroll_section_text','ga_events_scroll');
270
- add_settings_section('ga_events_started_section','Getting Started Guide', 'ga_events_gs_section_text','ga_events_started');
271
- add_settings_section('ga_events_whatsnew_section','', 'ga_events_whatsnew_section_content','ga_events_whatsnew');
272
- add_settings_field('ga_events_id', '','ga_events_setting_input','ga_events','ga_events_main');
273
- add_settings_field('ga_events_exclude_snippet', '','ga_events_setting_snippet_input','ga_events','ga_events_main');
274
- add_settings_field('ga_events_gtm', '', 'ga_events_setting_gtm_input', 'ga_events', 'ga_events_main');
275
- add_settings_field('ga_events_gst', '', 'ga_events_setting_gst_input', 'ga_events', 'ga_events_main');
276
- add_settings_field('ga_events_universal', '','ga_events_setting_uni_input','ga_events','ga_events_main');
277
- add_settings_field('ga_events_anonymizeip', '','ga_events_setting_anon_input','ga_events','ga_events_main');
278
- add_settings_field('ga_events_advanced', '','ga_events_setting_adv_input','ga_events','ga_events_main');
279
- add_settings_field('ga_events_divs', '','ga_events_setting_divs_input','ga_events_scroll','ga_events_scroll_section');
280
- add_settings_field('ga_events_started', '','ga_events_setting_started','ga_events_started','ga_events_started_section');
281
- add_settings_field('ga_events_click', '','ga_events_setting_click_input','ga_events_click','ga_events_click_section');
282
- add_settings_field('ga_events_sidebar', '','ga_events_setting_sidebar','ga_events','ga_events_main');
283
- add_settings_field('ga_events_download_settings', '','ga_events_settings_download','ga_events','ga_events_main');
284
- add_settings_field('ga_events_upload_settings', '','ga_events_settings_upload','ga_events','ga_events_main');
285
-
286
-
287
- }
288
-
289
- function ga_events_gs_section_text() {
290
- echo "<br><a style='margin-left:8px;' href='https://wpflow.com/knowledgebase/basic-configuration/' target='_blank'>Plugin Documentation</a>";
291
- }
292
- function ga_events_click_section_text() {
293
- echo "<br><a style='margin-left:8px;' href='https://wpflow.com/knowledgebase/use-wp-google-analytics-events-click-tracking-tab/' target='_blank'>Plugin Documentation</a>";
294
- }
295
-
296
- function ga_events_scroll_section_text() {
297
- echo "<br><a style='margin-left:8px;' href='https://wpflow.com/knowledgebase/scroll-tracking/' target='_blank'>Plugin Documentation</a>";
298
- }
299
-
300
- function ga_events_whatsnew_section_content() {
301
- ob_start(); ?>
302
- <div class="wpgae-container wpgae-container__warning">
303
- <h3><span class="dashicons dashicons-flag"></span> What's New (1)</h3>
304
- <div id="wpgae-warnings">
305
- <p></p>
306
- <div class="container" id="wpgae-warnings-active">
307
- <div class="wpgae-alert-holder">
308
- <div class="wpgae-alert">
309
- <p>Global Site Tag code support. Google recently added the new Global Site Tag feature, and made it the default tracking code. If you migrated to this new code, check the relevant option in the General Settings tab.
310
- </div>
311
- </div>
312
- <div class="wpgae-alert-holder">
313
- <div class="wpgae-alert">
314
- <p>The admin UI got a little update - We started working with ajax forms. These changes solve a problem that some of the users had with adding a long list of events.</p>
315
- </div>
316
- </div>
317
- <div class="wpgae-alert-holder">
318
- <div class="wpgae-alert">
319
- <p>We added the value field to click and scroll events. This used to be a Pro version feature and now it is part of this plugin as well.</p>
320
- </div>
321
- </div>
322
- <div class="wpgae-alert-holder">
323
- <div class="wpgae-alert">
324
- <p>We added support for the <strong>Google Tag Manager</strong>.
325
- <br>This feature requires some preparation on the Google Tag Manager side so make sure to <a target="_blank" href="https://wpflow.com/knowledgebase/google-tag-manager-support/">check out the video guide</a>.</p>
326
- </div>
327
- </div>
328
- </div>
329
- <div class="container" id="wpgae-warnings-dismissed">
330
- </div>
331
- </div>
332
- </div>
333
- <?php
334
- $content = ob_get_clean();
335
- echo $content;
336
- }
337
-
338
- function ga_events_setting_started() {
339
- echo '
340
- <h2>Getting Started Guide</h2>
341
- <form action="https://www.getdrip.com/forms/4588171/submissions" method="post" data-drip-embedded-form="4588171">
342
- <div style="background:white; line-height:20px; padding: 5px 15px 15px 15px;
343
- font-size: 15px; max-width:600px;">
344
-
345
- <h3 style="margin-top: 10px;" data-drip-attribute="headline">Want to learn more about event tracking?</h3>
346
- <div data-drip-attribute="description">Now that you installed the plugin, we want to help you get everything up and running.&nbsp;<br />
347
- <br>Join our short email course and get started with event tracking.</div>
348
- <div style="margin-top:10px;">
349
- <label for="fields[first_name]">First Name</label><br />
350
- <input type="text" name="fields[first_name]" value="" />
351
- </div>
352
- <div>
353
- <label style="margin-top:10px;"for="fields[email]">Email Address:</label><br />
354
- <input type="email" name="fields[email]" value="" />
355
- </div>
356
- <div>
357
- <input style="margin-top:15px;" class="button-primary" type="submit" name="submit" value="Get Started" data-drip-attribute="sign-up-button" />
358
- </div>
359
- </div>
360
- </form>';
361
- }
362
-
363
- function ga_events_setting_input() {
364
- $options = get_option('ga_events_options');
365
- $id = $options['id'];
366
- echo "<label>Google Analytics Identifier</label>";
367
- echo "<span class='ga_intable'><input class='inputs' id='id' name='ga_events_options[id]' type='text' value='$id' /></span>";
368
-
369
- }
370
-
371
-
372
- function ga_events_setting_snippet_input() {
373
- $options = get_option('ga_events_options');
374
- $id = $options['exclude_snippet'];
375
- echo "<label>Don't add the GA tracking code ".ga_tooltip('Useful if you already have the code snippet loaded by a different plugin')."</label>";
376
- echo "<span class='ga_intable'><input id='snippet' name='ga_events_options[exclude_snippet]' type='checkbox' value='1' " . checked( $id , 1,false) . " /></span>";
377
-
378
- }
379
-
380
- function ga_events_setting_gtm_input() {
381
- $options = get_option('ga_events_options');
382
- if (isset($options['gtm'])) {
383
- $id = $options['gtm'];
384
- } else {
385
- $id = 0;
386
- }
387
- echo "<label >I'm using the Google Tag Manager " . ga_tooltip('Make sure to configure on the GTM side as well') . " </label>";
388
-
389
- echo "<input style='margin-left: 5px;' id='gtm' name='ga_events_options[gtm]' type='checkbox' value='1' " . checked($id, 1, false) . " />";
390
- echo "<a style='margin-left: 5px;' href='https://wpflow.com/knowledgebase/google-tag-manager-support/' target='_blank'>Read More...</a>";
391
- }
392
-
393
- function ga_events_setting_gst_input() {
394
- $options = get_option('ga_events_options');
395
- if (isset($options['gst'])) {
396
- $id = $options['gst'];
397
- } else {
398
- $id = 0;
399
- }
400
- echo "<label >I'm using the Global Site Tags code " . ga_tooltip('Support for the Global Site Tag - Not to be confused with the Google Tag Manager') . " </label>";
401
- echo "<input style='margin-left: 5px;' id='gst' name='ga_events_options[gst]' type='checkbox' value='1' " . checked($id, 1, false) . " />";
402
- }
403
-
404
- function ga_events_setting_uni_input() {
405
- $options = get_option('ga_events_options');
406
- $id = $options['universal'];
407
- echo "<label>Universal Tracking Code</label>";
408
- echo "<span class='ga_intable'><input id='universal' name='ga_events_options[universal]' type='checkbox' value='1' " . checked( $id , 1,false) . " /></span>";
409
- }
410
-
411
- function ga_events_setting_anon_input() {
412
- $options = get_option('ga_events_options');
413
- $id = $options['anonymizeip'];
414
- echo "<label>IP Anonymization".ga_tooltip('Tell Google Analytics not to log IP Addresses. Requires code snippet to be checked')."</label>";
415
- echo "<span class='ga_intable'><input id='anonymizeip' name='ga_events_options[anonymizeip]' type='checkbox' value='1' " . checked( $id , 1,false) . " /></span>";
416
- }
417
-
418
- function ga_events_setting_adv_input() {
419
- $options = get_option('ga_events_options');
420
- $id = $options['advanced'];
421
- echo "<label>Advanced Mode ".ga_tooltip('Enable Advanced Selectors')."</label>";
422
- echo "<span class='ga_intable'><input id='advanced' name='ga_events_options[advanced]' type='checkbox' value='1' " . checked( $id , 1,false) . " /></span>";
423
- }
424
-
425
- function ga_events_settings_download(){
426
- echo '<a class="button" href="http://'.$_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] .'&download=1">Export settings</a>';
427
- }
428
-
429
- function ga_events_settings_upload(){
430
- echo '<a href="#" class="button btn_upload">Import settings</a>';
431
- }
432
-
433
- function ga_events_setting_divs_input() {
434
- $options = get_option('ga_events_options');
435
- $divs= $options['divs'];
436
-
437
- $menu_options = array(
438
- 'id' => 'id',
439
- 'class' => 'class',
440
- );
441
-
442
- if(is_advanced_mode()){
443
- $menu_options['advanced'] = 'advanced'; // if enabled, add 'avanced' on the menu
444
- }
445
-
446
- $type='divs';
447
-
448
- echo "<table id='ga-events-inputs' class='widefat inputs inner_table divs_table' data-name='divs'><thead><th>Element Name</th><th>Type</th><th>Event Category</th><th>Event Action</th><th>Event Label</th><th>Event Value</th><th>Non-Interaction</th><th></th></thead><tbody>";
449
- if (!($divs[0][0]) && !($divs[0][1])){
450
- $name = "ga_events_options[$type][0][1]";
451
- $type_menu = createDropdown($name, $type, $menu_options,'id');
452
-
453
- echo "<tr>";
454
- echo "<td data-title='Element Name'><input id='divs' name='ga_events_options[divs][0][0]' type='text' value='".$divs[0][0]."' /></td>";
455
- echo "<td data-title='Type'>$type_menu</td>";
456
- echo "<td data-title='Event Category'><input id='divs' name='ga_events_options[divs][0][2]' type='text' value='".$divs[0][2]."' /></td>";
457
- echo "<td data-title='Event Action'><input id='divs' name='ga_events_options[divs][0][3]' type='text' value='".$divs[0][3]."' /></td>";
458
- echo "<td data-title='Event Label'><input id='divs' name='ga_events_options[divs][0][4]' type='text' value='".$divs[0][4]."' /></td>";
459
-
460
- echo "<td data-title='Event Value'><input id='click' name='ga_events_options[divs][0][6]' type='number' value='".$divs[0][6]."' /></td>";
461
-
462
- echo "<td data-title='Non-Interaction'><select id='".$type."' name='ga_events_options[".$type."][$i][5]'>";
463
- if ($divs[$i][5] == 'true') {
464
- echo "<option selected value='true' >true</option><option value='false'>false</option></select></td>";
465
- } else {
466
- echo "<option value='true' >true</option><option selected value='false'>false</option></select></td>";
467
- }
468
- echo "<td><a class='btn-add' href='#'>Add</a></td>";
469
- echo "</tr>";
470
-
471
- }else{
472
- for ($i = 0; $i < sizeof($divs)+1; $i++){
473
- $name = "ga_events_options[$type][$i][1]";
474
- $selected = $divs[$i][1];
475
- $type_menu = createDropdown($name, $type, $menu_options, $selected);
476
- echo "<tr>";
477
- echo "<td data-title='Element Name'><input id='divs' name='ga_events_options[divs][$i][0] type='text' value='".$divs[$i][0]."' /></td>";
478
- echo "<td data-title='Type'>$type_menu</td>";
479
- echo "<td data-title='Event Category'><input id='divs' name='ga_events_options[divs][$i][2]' type='text' value='".$divs[$i][2]."' /></td>";
480
- echo "<td data-title='Event Action'><input id='divs' name='ga_events_options[divs][$i][3]' type='text' value='".$divs[$i][3]."' /></td>";
481
- echo "<td data-title='Event Label'><input id='divs' name='ga_events_options[divs][$i][4]' type='text' value='".$divs[$i][4]."' /></td>";
482
- echo "<td data-title='Event Value'><input id='click' name='ga_events_options[divs][$i][6]' type='number' value='".$divs[$i][6]."' /></td>";
483
- echo "<td data-title='Non-Interaction'><select id='".$type."' name='ga_events_options[".$type."][$i][5]'>";
484
- if ($divs[$i][5] == 'true') {
485
- echo "<option selected value='true' >true</option><option value='false'>false</option></select></td>";
486
- } else {
487
- echo "<option value='true' >true</option><option selected value='false'>false</option></select></td>";
488
- }
489
-
490
- if($divs[$i][0] || $divs[$i][1]){
491
- echo "<td><a class='btn-update' href=''><i class='fa fa-floppy-o' title='Update' aria-hidden='true'></i></a></td>";
492
- echo "<td><a class='btn-remove' href=''><i class='fa fa-times' title='Remove' aria-hidden='true'></i></a></td>";
493
- }else{
494
- echo "<td><a class='btn-add' href='#'>Add</a></td>";
495
- }
496
-
497
- echo "</tr>";
498
-
499
- }
500
-
501
- }
502
- echo "</tbody></table>";
503
- }
504
-
505
-
506
- function ga_events_setting_click_input() {
507
- $options = get_option('ga_events_options');
508
- $click = $options['click'];
509
- $divs= $options['click'];
510
-
511
- $menu_options = array(
512
- 'id' => 'id',
513
- 'class' => 'class',
514
- );
515
-
516
- if(is_advanced_mode()){
517
- $menu_options['advanced'] = 'advanced'; // if enabled, add 'avanced' on the menu
518
- }
519
-
520
- $type='click';
521
-
522
-
523
- echo "<table id='ga-events-inputs' class='widefat inputs inner_table click_table' data-name='click'><thead><th>Element Name</th><th>Type</th><th>Event Category</th><th>Event Action</th><th>Event Label</th><th>Event Value</th><th>Non-Interaction</th><th></th></thead><tbody>";
524
- if (!($click[0][0]) && !($click[0][1])){
525
- $name = "ga_events_options[click][0][1]";
526
- $type_menu = createDropdown($name, $type, $menu_options,'id');
527
-
528
- echo "<tr>";
529
- echo "<td data-title='Element Name'><input id='click' name='ga_events_options[click][0][0]' type='text' value='".$click[0][0]."' /></td>";
530
- echo "<td data-title='Type'>$type_menu</td>";
531
- echo "<td data-title='Event Category'><input id='click' name='ga_events_options[click][0][2]' type='text' value='".$click[0][2]."' /></td>";
532
- echo "<td data-title='Event Action'><input id='click' name='ga_events_options[click][0][3]' type='text' value='".$click[0][3]."' /></td>";
533
- echo "<td data-title='Event Label'><input id='click' name='ga_events_options[click][0][4]' type='text' value='".$click[0][4]."' /></td>";
534
-
535
- echo "<td data-title='Event Value'><input id='click' name='ga_events_options[click][0][6]' type='number' value='".$click[0][6]."' /></td>";
536
-
537
- echo "<td data-title='Non-Interaction'><select id='".$type."' name='ga_events_options[".$type."][$i][5]'>";
538
- if ($divs[$i][5] == 'true') {
539
- echo "<option selected value='true' >true</option><option value='false'>false</option></select></td>";
540
- } else {
541
- echo "<option value='true' >true</option><option selected value='false'>false</option></select></td>";
542
- }
543
-
544
-
545
- echo "<td><a class='btn-add' href='#'>Add</a></td>";
546
- echo "</tr>";
547
-
548
- }else{
549
- for ($i = 0; $i < sizeof($click)+1; $i++){
550
- $name = "ga_events_options[click][$i][1]";
551
- $selected = $click[$i][1];
552
- $type_menu = createDropdown($name, $type, $menu_options, $selected);
553
-
554
- echo "<tr>";
555
- echo "<td data-title='Element Name'><input id='divs' name='ga_events_options[click][$i][0]' type='text' value='".$click[$i][0]."' /></td>";
556
- echo "<td data-title='Type'>$type_menu</td>";
557
- echo "<td data-title='Event Category'><input id='click' name='ga_events_options[click][$i][2]' type='text' value='".$click[$i][2]."' /></td>";
558
- echo "<td data-title='Event Action'><input id='click' name='ga_events_options[click][$i][3]' type='text' value='".$click[$i][3]."' /></td>";
559
- echo "<td data-title='Event Label'><input id='click' name='ga_events_options[click][$i][4]' type='text' value='".$click[$i][4]."' /></td>";
560
-
561
- echo "<td data-title='Event Value'><input id='click' name='ga_events_options[click][$i][6]' type='number' value='".$click[$i][6]."' /></td>";
562
-
563
- echo "<td data-title='Non-Interaction'><select id='".$type."' name='ga_events_options[".$type."][$i][5]'>";
564
- if ($divs[$i][5] == 'true') {
565
- echo "<option selected value='true' >true</option><option value='false'>false</option></select></td>";
566
- }
567
- else {
568
- echo "<option value='true' >true</option><option selected value='false'>false</option></select></td>";
569
- }
570
-
571
-
572
- if($click[$i][0] || $click[$i][1]){
573
- echo "<td><a class='btn-update' href=''><i class='fa fa-floppy-o' title='Update' aria-hidden='true'></i></a></td>";
574
- echo "<td><a class='btn-remove' href=''><i class='fa fa-times' title='Remove' aria-hidden='true'></i></a></td>";
575
- }else{
576
- echo "<td><a class='btn-add' href='#'>Add</a></td>";
577
- }
578
-
579
- echo "</tr>";
580
-
581
- }
582
-
583
- }
584
- echo "</tbody></table>";
585
-
586
-
587
- }
588
-
589
- function ga_events_setting_sidebar(){
590
- }
591
-
592
- function ga_events_validate($form){
593
-
594
- $options = get_option('ga_events_options');
595
- $updated = $options;
596
-
597
- if( array_key_exists('divs', $form)) {
598
-
599
- $updated['divs'] = array();
600
- $divFields = array_values($form['divs']); //force array index to start with 0
601
- for ($i = 0, $j = 0; $i< sizeof($divFields); $i++){
602
- if ($divFields[$i][0]){
603
- $updated['divs'][$j] = cleanEventFeilds($divFields[$i]);
604
- $j++;
605
- }
606
- }
607
- }
608
- else if(array_key_exists('click', $form)) {
609
- $updated['click'] = array();
610
- $clickFields = array_values($form['click']); //force array index to start with 0
611
- for ($i = 0, $j = 0; $i< sizeof($clickFields); $i++){
612
- if ($clickFields[$i][0]){
613
- $updated['click'][$j] = cleanEventFeilds($clickFields[$i]);
614
- $j++;
615
- }
616
- }
617
- }
618
- else {
619
- $updated['id'] = $form['id'];
620
- $updated['exclude_snippet'] = $form['exclude_snippet'];
621
- $updated['universal'] = $form['universal'];
622
- $updated['anonymizeip'] = $form['anonymizeip'];
623
- $updated['advanced'] = $form['advanced'];
624
- $updated['gtm'] = $form['gtm'];
625
- $updated['gst'] = $form['gst'];
626
- }
627
-
628
- return $updated;
629
- }
630
-
631
-
632
- add_action('admin_footer', 'ga_events_admin_footer');
633
-
634
- function ga_events_admin_footer() {
635
- ?>
636
- <script>
637
- jQuery('body').on('click','a[href="admin.php?page=wp-google-analytics-events-upgrade"]', function (e) {
638
- e.preventDefault();
639
- window.open('https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=nav', '_blank');
640
- });
641
- </script>
642
- <?php
643
- }
644
-
645
-
646
- function ga_events_get_settings(){
647
- $options = get_option('ga_events_options');
648
- $current = json_encode($options);
649
- return $current;
650
- }
651
-
652
- function ga_events_upload_settings($file){
653
- $uploadedfile = $file['settings'];
654
- if($uploadedfile['type'] != 'application/octet-stream'){
655
- ga_event_popup();
656
- return;
657
- }
658
- $content = file_get_contents($uploadedfile["tmp_name"]);
659
- ga_event_get_content($content);
660
- }
661
-
662
- function ga_event_get_content($content){
663
- if(!$current = json_decode($content,true)){
664
- ga_event_popup();
665
- return;
666
- }
667
- if (!array_key_exists('id', $current) && !array_key_exists('domain', $current)) {
668
- ga_event_popup();
669
- return;
670
- }
671
- update_option( 'ga_events_options', $current );
672
-
673
- }
674
- function ga_event_popup(){
675
- echo "<dev class='popup'>";
676
- echo '<h1>Wrong file format <a href="#" class="btn_close_popup"><img src="'.plugins_url( 'images/close.png', dirname(__FILE__)).'"></a></h1>';
677
- echo "</dev>";
678
- }
679
- function ga_events_file(){
680
- header("Content-type: text/plain");
681
- header("Content-Disposition: attachment; filename='settings.ini'");
682
- echo ga_events_get_settings();
683
- exit();
684
- }
685
-
686
- function cleanEventFeilds($arr) {
687
- if('advanced' == $arr[1]){
688
- $arr[0] = str_replace("'",'"',$arr[0]);
689
- }else{
690
- $arr[0] = str_replace("'","",$arr[0]);
691
- }
692
-
693
- for ($i = 1; $i < sizeof($arr); $i++) {
694
- $arr[$i] = esc_html($arr[$i]);
695
- }
696
- return $arr;
697
- }
698
-
699
- function cleanAjaxFeilds($data) {
700
- $newData = array();
701
-
702
- foreach( $data as $key => $value ) {
703
-
704
- $newData[$key] = htmlspecialchars( stripslashes($value) ,ENT_QUOTES, 'UTF-8');
705
- }
706
-
707
- return $newData;
708
- }
709
-
710
- function ga_tooltip($content = '') {
711
- $html = '<span class="ga-tooltip" title="'.$content.'"></span>';
712
- return $html;
713
- }
714
-
715
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/functions.php DELETED
@@ -1,285 +0,0 @@
1
- <?php
2
-
3
- add_action("wp_ajax_add_wpgae_event", "add_wpgae_event_action");
4
-
5
- function add_wpgae_event_action() {
6
-
7
- check_ajax_referer( 'wpgae_nonce_CRX0XDPfqe5dd3P', 'security' );
8
-
9
- $response = array();
10
- $response['success'] = false;
11
-
12
- $event = strtolower ( sanitize_text_field( $_POST['event'] ) );
13
-
14
- $input = stripslashes($_POST['input']);
15
- $decoded = json_decode($input);
16
-
17
- if( isValidEvent($event) ) {
18
- $response = ajax_add($event, $decoded);
19
- }
20
-
21
-
22
- echo json_encode($response);
23
- die();
24
- }
25
-
26
- /*
27
- description:
28
- function to add new tracking on both click and scroll event
29
- TODO: create separate function for each event when inputs needed will no
30
- longer the same
31
- param:
32
- $data array
33
- return:
34
- array
35
- */
36
- function ajax_add($event, $data){
37
-
38
- $options = get_option('ga_events_options');
39
- $response = array();
40
-
41
- $cleanData = cleanAjaxFeilds($data);
42
- $newEntry = extractEventData($event, $cleanData);
43
-
44
- if (!isset($options[$event])) {
45
- $options[$event] = array();
46
- }
47
-
48
- array_push($options[$event], $newEntry);
49
- if (sizeof($options[$event][0][0]) == 0 && sizeof($options[$event][0][1]) == 0) {
50
- array_shift($options[$event]);
51
- }
52
-
53
-
54
- //Remove sanitizing for adding
55
- remove_filter( "sanitize_option_ga_events_options", "ga_events_validate" );
56
-
57
- $response['success'] = update_option( 'ga_events_options', $options );
58
-
59
- return $response;
60
- }
61
-
62
-
63
- add_action("wp_ajax_update_wpgae_event", "update_wpgae_event_action");
64
-
65
- function update_wpgae_event_action() {
66
-
67
- check_ajax_referer( 'wpgae_nonce_CRX0XDPfqe5dd3P', 'security' );
68
-
69
- $response = array();
70
- $response['success'] = false;
71
-
72
- $event = strtolower ( sanitize_text_field( $_POST['event'] ) );
73
-
74
- $index = intval( $_POST['index'] );
75
-
76
- //index should not be null or empty and non-negative, 0 should be treated as int and not boolean false
77
- if ( ( !$index && $index != 0 ) || $index < 0 ) {
78
- $event = 'INVALID';
79
- }
80
-
81
- $input = stripslashes($_POST['input']);
82
- $decoded = json_decode($input);
83
-
84
- if( isValidEvent($event) ) {
85
- $response = ajax_update($event, $index, $decoded);
86
- }
87
-
88
- echo json_encode($response);
89
- die();
90
- }
91
-
92
- function ajax_update($event, $index, $data){
93
-
94
- $options = get_option('ga_events_options');
95
- $response = array();
96
- $cleanData = cleanAjaxFeilds($data);
97
- $newEvent = extractEventData($event, $cleanData);
98
-
99
- $options[$event][$index] = $newEvent;
100
-
101
- //Remove sanitizing for updating
102
- remove_filter( "sanitize_option_ga_events_options", "ga_events_validate" );
103
-
104
- $response['success'] = update_option( 'ga_events_options', $options );
105
- return $response;
106
- }
107
-
108
- add_action("wp_ajax_remove_wpgae_event", "remove_wpgae_event_action");
109
- function remove_wpgae_event_action() {
110
-
111
- check_ajax_referer( 'wpgae_nonce_CRX0XDPfqe5dd3P', 'security' );
112
-
113
- $response = array();
114
- $response['success'] = false;
115
- $event = strtolower ( sanitize_text_field( $_POST['event'] ) );
116
- $index = intval( $_POST['index'] );
117
-
118
- //index should not be null and non-negative, 0 should be treated as int and not boolean false
119
- if ( ( !$index && $index != 0 ) || $index < 0 ) {
120
- $event = 'INVALID';
121
- }
122
-
123
- if( isValidEvent($event) ) {
124
- $response = ajax_remove($event,$index);
125
- }
126
-
127
- echo json_encode($response);
128
- die();
129
- }
130
-
131
- function ajax_remove($event, $index){
132
- $options = get_option('ga_events_options');
133
- $response = array();
134
-
135
-
136
- unset($options[$event][$index]);
137
- $options[$event] = array_values(array_filter($options[$event])); //re-index array
138
-
139
- //Remove sanitizing for adding
140
- remove_filter( "sanitize_option_ga_events_options", "ga_events_validate" );
141
-
142
- $response['success'] = update_option( 'ga_events_options', $options );
143
- return $response;
144
- }
145
-
146
- function isValidEvent($input){
147
-
148
- $valid = array('click','divs','youtube','vimeo');
149
-
150
- return in_array($input, $valid);
151
- }
152
-
153
- function extractEventData($event, $data){
154
-
155
- $extracted = array();
156
- switch ($event) {
157
- case 'click':
158
- $extracted = array(
159
- $data['name'],
160
- $data['type'],
161
- $data['category'],
162
- $data['action'],
163
- $data['label'],
164
- $data['interaction'],
165
- $data['value']
166
- );
167
- break;
168
- case 'divs':
169
- $extracted = array(
170
- $data['name'],
171
- $data['type'],
172
- $data['category'],
173
- $data['action'],
174
- $data['label'],
175
- $data['interaction'],
176
- $data['value'],
177
- // $data['tracktime'],
178
- //$data['time']
179
-
180
- );
181
- break;
182
- case 'youtube':
183
- $extracted = array(
184
- 'title' => $data['title'],
185
- 'id' => $data['id'],
186
- 'id_type' => $data['type'],
187
- 'play' => $data['play'],
188
- 'pause' => $data['pause'],
189
- 'end' => $data['end'],
190
- 'quality' => $data['quality']
191
- );
192
- break;
193
- case 'vimeo':
194
- $extracted = array(
195
- 'title' => $data['title'],
196
- 'id' => $data['id'],
197
- 'id_type' => $data['type'],
198
- 'play' => $data['play'],
199
- 'pause' => $data['pause'],
200
- 'end' => $data['end'],
201
- 'skip' => $data['skip']
202
- );
203
- break;
204
-
205
- default:
206
- // do nothing
207
- break;
208
- }
209
- return $extracted;
210
- }
211
-
212
- function doLog($text){
213
- // open log file
214
- $filename = "event.log";
215
- $fh = fopen($filename, "a") or die("Could not open log file.");
216
- fwrite($fh, date("d-m-Y, H:i")." - $text\n") or die("Could not write file!");
217
- fclose($fh);
218
- }
219
-
220
-
221
- function migrateOptions() {
222
- $current_options = get_option('ga_events_options');
223
- $new_options = array();
224
- $new_options['id'] = $current_options['id'];
225
- $new_options['exclude_snippet'] = $current_options['exclude_snippet'];
226
- $new_options['universal'] = $current_options['universal'];
227
- $new_options['events'] = array();
228
- for ($i=0; $i < sizeof($current_options['divs']); $i++) {
229
- $current_option = $current_options['divs'][$i];
230
- $event = new Event('scroll', $current_option[0], $current_option[1], $current_option[2], $current_option[3], $current_option[4]);
231
- array_push($new_options['events'], $event->getEventArray() );
232
- }
233
-
234
- for ($i=0; $i < sizeof($current_options['click']); $i++) {
235
- $current_option = $current_options['click'][$i];
236
- $event = new Event('click', $current_option[0], $current_option[1], $current_option[2], $current_option[3], $current_option[4]);
237
- array_push($new_options['events'], $event->getEventArray() );
238
- }
239
-
240
- update_option('ga_events_options', $new_options);
241
- // print(var_dump($new_options));
242
- }
243
-
244
-
245
- function isOptionMigrationRequired(){
246
- $current_options = get_option('ga_events_options');
247
- if (array_key_exists('divs', $current_options) || array_key_exists('clicks', $current_options)) {
248
- return true;
249
- }
250
- return false;
251
- }
252
-
253
- function is_advanced_mode(){
254
- $ga_events_options = get_option( 'ga_events_options' );
255
- return $ga_events_options['advanced'];
256
- }
257
-
258
- function is_advanced_type($type){
259
- return 'advanced' == $type;
260
- }
261
-
262
- function createDropdown($name, $id, $options = array(), $selected = 'unknown'){
263
- $html = '';
264
- if(!empty($options)){
265
- $html .= "<select id='$id' name='$name'>";
266
-
267
- if(!in_array($selected, $options)){
268
- // even advanced mode is off, 'avanced' should still be accepted as valid option
269
- if('advanced' == $selected){
270
- $options['advanced'] = 'advanced';
271
- }else{
272
- $selected = reset($options); // set first element's key to be default
273
- }
274
- }
275
-
276
- foreach ($options as $key => $value){
277
- $html .= $selected == $key ? "<option selected value='$key' >$value</option>":"<option value='$key' >$value</option>";
278
- }
279
-
280
- $html .= "</select>";
281
- }
282
- return $html;
283
- }
284
-
285
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/admin.js CHANGED
@@ -1,100 +1,162 @@
1
- if (document.location.href.indexOf("wp-google-analytics-events") > -1) {
2
-
3
- jQuery.widget.bridge('gaetooltip', jQuery.ui.tooltip);
4
-
5
- jQuery('.ga-tooltip').gaetooltip({
6
- position: {
7
- my: "left bottom-10", at: "right top", collision: "none"
8
- }
9
- });
10
-
11
- jQuery('.remove').click(function (event) {
12
- event.preventDefault();
13
- jQuery(this).closest('tr').remove();
14
- });
15
-
16
- jQuery('.btn_upload').on('click', function (e) {
17
- jQuery('.settings_content').slideDown();
18
- e.preventDefault();
19
- });
20
-
21
- jQuery('.btn_close').on('click', function (e) {
22
- jQuery('.settings_content').slideUp();
23
- e.preventDefault();
24
- });
25
-
26
- jQuery('.popup').on('click', function (e) {
27
- jQuery('.popup').slideUp();
28
- e.preventDefault();
29
- });
30
-
31
- if (jQuery('#snippet').is(":checked")) {
32
- jQuery('#anonymizeip')[0].checked = false;
33
- jQuery('#anonymizeip').attr("disabled", true);
34
- }
35
-
36
- jQuery('#snippet').change(function () {
37
- if (this.checked) {
38
- jQuery('#anonymizeip')[0].checked = false;
39
- jQuery('#anonymizeip').attr("disabled", true);
40
- } else {
41
- jQuery('#anonymizeip').removeAttr("disabled");
42
- }
43
- });
44
-
45
- jQuery('#advanced:checkbox').change(function () {
46
- var checked = jQuery(this).is(':checked');
47
- if (checked) {
48
- if (!confirm('Advanced mode allows you to use jQuery selectors for click and scroll events. Enabling this feature and creating advanced events could cause errors on your site if misconfigured. \n\nAre you sure? ')) {
49
- jQuery(this).removeAttr('checked');
50
- }
51
- }
52
- });
53
-
54
- if (jQuery('#gtm').is(":checked")) {
55
- jQuery('#anonymizeip')[0].checked = false;
56
- jQuery('#anonymizeip').attr("disabled", true);
57
- jQuery('#snippet')[0].checked = true;
58
- jQuery('#snippet').attr("disabled", true);
59
- jQuery('#gst')[0].checked = false;
60
- jQuery('#gst').attr("disabled", true);
61
- }
62
-
63
- if (jQuery('#gst').is(":checked")) {
64
- jQuery('#anonymizeip')[0].checked = false;
65
- jQuery('#anonymizeip').attr("disabled", true);
66
- jQuery('#snippet')[0].checked = true;
67
- jQuery('#snippet').attr("disabled", true);
68
- jQuery('#gtm')[0].checked = false;
69
- jQuery('#gtm').attr("disabled", true);
70
- }
71
-
72
- jQuery('#gtm').change(function () {
73
- if (this.checked) {
74
- jQuery('#anonymizeip')[0].checked = false;
75
- jQuery('#anonymizeip').attr("disabled", true);
76
- jQuery('#snippet')[0].checked = true;
77
- jQuery('#snippet').attr("disabled", true);
78
- jQuery('#gst')[0].checked = false;
79
- jQuery('#gst').attr("disabled", true);
80
- } else {
81
- jQuery('#anonymizeip').removeAttr("disabled");
82
- jQuery('#snippet').removeAttr("disabled");
83
- jQuery('#gst').attr("disabled", false);
84
- }
85
- });
86
- jQuery('#gst').change(function () {
87
- if (this.checked) {
88
- jQuery('#anonymizeip')[0].checked = false;
89
- jQuery('#anonymizeip').attr("disabled", true);
90
- jQuery('#snippet')[0].checked = true;
91
- jQuery('#snippet').attr("disabled", true);
92
- jQuery('#gtm')[0].checked = false;
93
- jQuery('#gtm').attr("disabled", true);
94
- } else {
95
- jQuery('#anonymizeip').removeAttr("disabled");
96
- jQuery('#snippet').removeAttr("disabled");
97
- jQuery('#gtm').attr("disabled", false);
98
- }
99
- });
100
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Created with IntelliJ IDEA.
3
+ * User: yuval
4
+ * Date: 2/25/15
5
+ * Time: 1:08 PM
6
+ * To change this template use File | Settings | File Templates.
7
+ */
8
+
9
+ jQuery(document).ready(function($){
10
+
11
+ var snippet_type = $('#snippet_type');
12
+ var anonymizeip = $('#anonymizeip');
13
+ var anonymizeip_checkbox = $('#anonymizeip')[0];
14
+ var gtm_id = $('#gtm_id');
15
+ var script_debug_mode_input = $('#script_debug_mode');
16
+
17
+ // Helpers to avoid repetition
18
+ function disable_element(el){
19
+ el.attr("disabled", true);
20
+ }
21
+
22
+ function enable_element(el){
23
+ el.removeAttr("disabled");
24
+ }
25
+
26
+ function set_checked_value(el, bool){
27
+ el.checked = bool;
28
+ }
29
+
30
+ // set up tooltips
31
+ $.widget.bridge('gaetooltip', $.ui.tooltip);
32
+
33
+ $('.ga-tooltip').gaetooltip({position: {
34
+ my: "left bottom-10",
35
+ at: "right top",
36
+ collision: "none"
37
+ }
38
+ });
39
+
40
+
41
+ $('.btn_upload').on('click', function (e){
42
+ $('.settings_content').slideDown();
43
+ e.preventDefault();
44
+ });
45
+
46
+ $('.btn_close').on('click', function (e){
47
+ $('.settings_content').slideUp();
48
+ e.preventDefault();
49
+ });
50
+
51
+ $('.popup').on('click', function (e){
52
+ $('.popup').slideUp();
53
+ e.preventDefault();
54
+ });
55
+
56
+
57
+ /*
58
+ * The following section deals with the snippet type options in the admin UI
59
+ */
60
+
61
+ // If page loads and snippet type is 'none' or 'gtm', disable anonymize IP checkbox
62
+ if (snippet_type.val()=== 'none' || snippet_type.val()=== 'gtm'){
63
+ set_checked_value(anonymizeip_checkbox, false);
64
+ disable_element(anonymizeip);
65
+ }
66
+
67
+ // If page loads and snippet_type is 'gtm', enable gtm_id
68
+ if (snippet_type.val()=== 'gtm'){
69
+ enable_element(gtm_id);
70
+ } else {
71
+ disable_element(gtm_id);
72
+ }
73
+
74
+ // When the snippet type option is changed
75
+ snippet_type.change(function (){
76
+ // Store current value
77
+ var val = $(this).val();
78
+
79
+ // If 'none' is selected, disable anonymize zip checkbox and ?
80
+ if (val === 'none' || val === 'gtm'){
81
+ set_checked_value(anonymizeip_checkbox, false);
82
+ disable_element(anonymizeip);
83
+ } else {
84
+ enable_element(anonymizeip);
85
+ }
86
+
87
+ // If gtm snippet is selected
88
+ if (val === 'gtm'){
89
+ enable_element(gtm_id);
90
+ } else {
91
+ disable_element(gtm_id);
92
+ }
93
+ });
94
+
95
+ // Snippet section ends
96
+
97
+ // The following section deals with the import settings functinality in
98
+ // general settings
99
+ $('.btn_upload').on('click', function (e){
100
+ $('.settings_content').slideDown();
101
+ e.preventDefault();
102
+ });
103
+
104
+ $('.btn_close').on('click', function (e){
105
+ $('.settings_content').slideUp();
106
+ e.preventDefault();
107
+ });
108
+
109
+ $('.popup').on('click', function (e){
110
+ $('.popup').slideUp();
111
+ e.preventDefault();
112
+ });
113
+
114
+ // import section ends
115
+
116
+ // Disable checkbox for admin options management permission
117
+ $('input[name="ga_events_options[permitted_roles][]"][value="administrator"]').css({'pointer-events': 'none',
118
+ 'opacity': 0.5}).prop('checked', true);
119
+
120
+ $('.divs-istracktime:checkbox').change(function (){
121
+ var checkbox = $(this);
122
+ var checked = checkbox.is(':checked');
123
+ var index = checkbox.data('track');
124
+ var trackValue = "#track-elem" + index;
125
+ var eventValue = "#eventValue" + index;
126
+ if (checked){
127
+ $(trackValue).show();
128
+ $(eventValue).attr("disabled", true);
129
+ } else {
130
+ $(trackValue).hide();
131
+ $(eventValue).removeAttr("disabled");
132
+ }
133
+
134
+ });
135
+
136
+ $('#empty-istracktime:checkbox').change(function (){
137
+ var checkbox = $(this);
138
+ var checked = checkbox.is(':checked');
139
+ var trackValue = "#empty-trackelem";
140
+ var eventValue = "#empty-eventValue";
141
+ if (checked){
142
+ $(trackValue).show();
143
+ $(eventValue).attr("disabled", true);
144
+ } else {
145
+ $(trackValue).hide();
146
+ $(eventValue).removeAttr("disabled");
147
+ }
148
+
149
+ });
150
+
151
+ $('.divs-istracktime').trigger('change');
152
+
153
+ function isUrlValid(url){
154
+ return /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(url);
155
+ }
156
+
157
+
158
+ jQuery('body').on('click','a[href="admin.php?page=wp-google-analytics-events-upgrade"]', function (e) {
159
+ e.preventDefault();
160
+ window.open('https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=nav', '_blank');
161
+ });
162
+ });
js/ajax-settings.js ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*global
2
+ $, wpflow_ajax, jslint, alert
3
+ */
4
+ var gaeAjax = ( function ( $ ) {
5
+
6
+ $(document).ready( function ( $ ) {
7
+
8
+ // Handle twitter bootstrap modals
9
+ if (typeof $.fn.modal.noConflict !== "undefined") {
10
+ var bootstrapModal = $.fn.modal.noConflict();
11
+ }
12
+
13
+ // Form Submit
14
+ $.validate();
15
+ $(".wpgae-event-form").on('submit', submitEventForm);
16
+ // Populate and Show the edit event modal
17
+ $(".ga_main .edit a").click(openAndPoplulateEventModal);
18
+ // Populate and Show the Delete event modal
19
+ $(".ga_main .delete a").click(openAndPoplulateEventModal);
20
+ });
21
+
22
+
23
+ function openAndPoplulateEventModal(e) {
24
+ e.preventDefault();
25
+ var id_post = $(this).attr('id');
26
+ var modalId = "#" + $(this).data("action");
27
+ $.ajax({
28
+ type: 'POST',
29
+ url: wpflow_ajax.ajax_url,
30
+ data: {
31
+ 'post_id': id_post,
32
+ 'action': 'wpflow_get_event_json'
33
+ },
34
+ success: function (result) {
35
+ $(modalId).modal();
36
+ populateMetaEditForm(modalId, result.meta);
37
+ $(modalId + " #event_id").val(id_post);
38
+ },
39
+ error: function () {
40
+ alert("Error updating event");
41
+ }
42
+ });
43
+ }
44
+
45
+ function submitEventForm(e) {
46
+ e.preventDefault();
47
+ var form = $(this);
48
+
49
+ $.ajax({
50
+ type: "post",
51
+ url: wpflow_ajax.ajax_url,
52
+ data: form.serialize(),
53
+ success: function (data) {
54
+ window.location.reload();
55
+ }
56
+ });
57
+ }
58
+
59
+ function populateMetaEditForm(modal, meta) {
60
+ if (typeof meta !== "undefined") {
61
+ for (var input in meta) {
62
+ if (meta.hasOwnProperty(input)) {
63
+ if ($(modal + " #" + input).is(":checkbox")) {
64
+ if (meta[input][0] === "true") {
65
+ $(modal + " #" + input).attr("checked", true);
66
+ } else {
67
+ $(modal + " #" + input).removeAttr("checked", false);
68
+ }
69
+ } else {
70
+ $(modal + " #" + input).val(meta[input][0]);
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ } )( jQuery );
77
+
78
+
79
+
80
+
81
+
82
+
83
+
js/ajax.js DELETED
@@ -1,194 +0,0 @@
1
- jQuery(document).ready( function() {
2
-
3
- function getInputValue(trObj, tdIndex, fieldType, fieldIndex) {
4
- fieldIndex = typeof fieldIndex !== 'undefined' ? fieldIndex : 0;
5
- var fieldObj = trObj.find('td').eq(tdIndex).find(fieldType)[fieldIndex];
6
- if(fieldType === 'input[type="checkbox"]'){
7
-
8
- return fieldObj.checked ? 1:0;
9
-
10
- }
11
- return fieldObj.value;
12
- }
13
-
14
- function getNewRow(event, index, advanced) {
15
- advanced = typeof advanced !== 'undefined' ? advanced : 0;
16
-
17
- var html = "<tr>"; //start row
18
- switch (event) {
19
- case "click":
20
- html+="<td><input type='text' value=''/></td>";
21
- html+="<td><select>\n\
22
- <option selected value='id'>id</option>\n\
23
- <option value='class'>class</option>";
24
- if(advanced){
25
- html+="<option value='advanced'>advanced</option>";
26
- }
27
- html+="</select></td>";
28
- html+="<td><input type='text' value=''/></td>\n\
29
- <td><input type='text' value=''/></td>\n\
30
- <td><input type='text' value=''/></td>\n\
31
- <td><input type='number' value=''/></td>\n\
32
- <td><select id='click'>\n\
33
- <option selected value='true'>true</option>\n\
34
- <option value='false'>false</option>\n\
35
- </select></td>";
36
- break;
37
- case "divs":
38
- html+="<td><input type='text' value=''/></td>";
39
- html+="<td><select>\n\
40
- <option selected value='id'>id</option>\n\
41
- <option value='class'>class</option>";
42
- if(advanced){
43
- html+="<option value='advanced'>advanced</option>";
44
- }
45
- html+="</select></td>";
46
-
47
- html+="<td><input type='text' value=''/></td>\n\
48
- <td><input type='text' value=''/></td>\n\
49
- <td><input type='text' value=''/></td>\n\
50
- <td><input type='number' value=''/></td>\n\
51
- <td><select id='divs'>\n\
52
- <option selected value='true'>true</option>\n\
53
- <option value='false'>false</option>\n\
54
- </select></td>";
55
- break;
56
-
57
- default:
58
- break;
59
- }
60
-
61
-
62
- html+="<td><a class='btn-add' href='#'>Add</a></td></tr>"; //end row
63
-
64
- return html;
65
- }
66
-
67
-
68
- function getEventData(tr, event) {
69
-
70
- var data = {};
71
-
72
- switch (event) {
73
- case "click":
74
- data['name'] = getInputValue(tr, 0, 'input');
75
- data['type'] = getInputValue(tr, 1, 'select');
76
- data['category'] = getInputValue(tr, 2, 'input');
77
- data['action'] = getInputValue(tr, 3, 'input');
78
- data['label'] = getInputValue(tr, 4, 'input');
79
- data['value'] = getInputValue(tr, 5, 'input');
80
- data['interaction'] = getInputValue(tr, 6, 'select');
81
- break;
82
-
83
- case "divs":
84
- data['name'] = getInputValue(tr, 0, 'input');
85
- data['type'] = getInputValue(tr, 1, 'select');
86
- data['category'] = getInputValue(tr, 2, 'input');
87
- data['action'] = getInputValue(tr, 3, 'input');
88
- data['label'] = getInputValue(tr, 4, 'input');
89
- data['value'] = getInputValue(tr, 5, 'input');
90
- data['interaction'] = getInputValue(tr, 6, 'select');
91
- break;
92
- default:
93
- break;
94
- }
95
- return JSON.stringify(data);
96
- }
97
-
98
-
99
- jQuery(document).on('click', '.btn-remove', function (event) {
100
- event.preventDefault();
101
- var button = jQuery(this);
102
- var tr = button.closest('tr');
103
- var tbody = tr.closest('tbody');
104
- var table = tbody.closest('table');
105
- var tblName = table.data('name');
106
-
107
- var index = tr.index();
108
-
109
- var input = getEventData(tr, tblName);
110
-
111
-
112
- jQuery.ajax({
113
- type: "post",
114
- dataType: "json",
115
- url: wpgae_ajax.ajaxurl,
116
- data: {
117
- action: 'remove_wpgae_event',
118
- security: wpgae_ajax.ajaxnonce,
119
- event: tblName,
120
- index: index
121
- },
122
- success: function (response) {
123
- if (response.success) {
124
- tr.remove();
125
- }
126
- }
127
- });
128
- });
129
-
130
- jQuery(document).on('click', '.btn-add', function (event) {
131
-
132
- event.preventDefault();
133
- var button = jQuery(this);
134
- var tr = button.closest('tr');
135
- var tbody = tr.closest('tbody');
136
- var table = tbody.closest('table');
137
- var tblName = table.data('name');
138
- var index = tr.index();
139
- var input = getEventData(tr, tblName);
140
-
141
- var newRow = getNewRow(tblName, index, wpgae_ajax.advanced);
142
- var removeBtn = "<td><a class='btn-remove' href='#'><i class='fa fa-times' title='Remove' aria-hidden='true'></i></a></td>";
143
-
144
- jQuery.ajax({
145
- type: "post",
146
- dataType: "json",
147
- url: wpgae_ajax.ajaxurl,
148
- data: {
149
- action: 'add_wpgae_event',
150
- security: wpgae_ajax.ajaxnonce,
151
- event: tblName,
152
- input: input
153
- },
154
- success: function (response) {
155
- if (response.success) {
156
- tbody.append(newRow);
157
- button.closest('td').after(removeBtn);
158
- button.html("<i class='fa fa-floppy-o' title='Update' aria-hidden='true'></i>");
159
- button.attr('class', 'btn-update');
160
- }
161
- }
162
- });
163
- });
164
-
165
- jQuery(document).on('click', '.btn-update', function (event) {
166
- event.preventDefault();
167
- var button = jQuery(this);
168
- var tr = button.closest('tr');
169
- var tbody = tr.closest('tbody');
170
- var table = tbody.closest('table');
171
- var tblName = table.data('name');
172
-
173
- var index = tr.index();
174
-
175
- var input = getEventData(tr, tblName);
176
- jQuery(this).hide();
177
- var self = this;
178
- jQuery.ajax({
179
- type: "post",
180
- dataType: "json",
181
- url: wpgae_ajax.ajaxurl,
182
- data: {
183
- action: 'update_wpgae_event',
184
- security: wpgae_ajax.ajaxnonce,
185
- event: tblName,
186
- index: index,
187
- input: input
188
- },
189
- success: function (response) {
190
- jQuery(self).show();
191
- }
192
- });
193
- });
194
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/dist/admin-scripts-min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e,t){"function"==typeof define&&define.amd?define(["jquery"],function(e){return t(e)}):"object"==typeof module&&module.exports?module.exports=t(require("jquery")):t(e.jQuery)}(this,function(e){!function(e,t,i){function a(e,t){this.$form=e,this.$input=t,this.reset(),t.on("change paste",this.reset.bind(this))}var n=function(){return!1},o=null,r={numHalted:0,haltValidation:function(t){this.numHalted++,e.formUtils.haltValidation=!0,t.unbind("submit",n).bind("submit",n).find('*[type="submit"]').addClass("disabled").attr("disabled","disabled")},unHaltValidation:function(t){this.numHalted--,0===this.numHalted&&(e.formUtils.haltValidation=!1,t.unbind("submit",n).find('*[type="submit"]').removeClass("disabled").removeAttr("disabled","disabled"))}};a.prototype.reset=function(){this.haltedFormValidation=!1,this.hasRun=!1,this.isRunning=!1,this.result=void 0},a.prototype.run=function(e,t){return"keyup"===e?null:this.isRunning?(o=e,this.haltedFormValidation||(r.haltValidation(),this.haltedFormValidation=!0),null):this.hasRun?this.result:(o=e,r.haltValidation(this.$form),this.haltedFormValidation=!0,this.isRunning=!0,this.$input.attr("disabled","disabled").addClass("async-validation"),this.$form.addClass("async-validation"),t(function(e){this.done(e)}.bind(this)),null)},a.prototype.done=function(e){this.result=e,this.hasRun=!0,this.isRunning=!1,this.$input.removeAttr("disabled").removeClass("async-validation"),this.$form.removeClass("async-validation"),this.haltedFormValidation&&(r.unHaltValidation(this.$form),"submit"===o?this.$form.trigger("submit"):this.$input.trigger("validation.revalidate"))},a.loadInstance=function(e,t,i){var n,o=t.get(0);return o.asyncValidators||(o.asyncValidators={}),o.asyncValidators[e]?n=o.asyncValidators[e]:(n=new a(i,t),o.asyncValidators[e]=n),n},e.formUtils=e.extend(e.formUtils||{},{asyncValidation:function(e,t,i){return this.warn("Use of deprecated function $.formUtils.asyncValidation, use $.formUtils.addAsyncValidator() instead"),a.loadInstance(e,t,i)},addAsyncValidator:function(t){var i=e.extend({},t),n=i.validatorFunction;i.async=!0,i.validatorFunction=function(e,t,o,r,s,l){return a.loadInstance(this.name,t,s).run(l,function(a){n.apply(i,[a,e,t,o,r,s,l])})},this.addValidator(i)}}),e(t).bind("validatorsLoaded formValidationSetup",function(t,i){i||(i=e("form")),i.find("[data-validation]").each(function(){var t=e(this);t.valAttr("async",!1),e.each(e.split(t.attr("data-validation")),function(i,a){var n=e.formUtils.validators["validate_"+a];n&&n.async&&t.valAttr("async","yes")})})})}(e,window),function(e,t){"use strict";function i(t){t&&"custom"===t.errorMessagePosition&&"function"==typeof t.errorMessageCustom&&(e.formUtils.warn("Use of deprecated function errorMessageCustom, use config.submitErrorMessageCallback instead"),t.submitErrorMessageCallback=function(e,i){t.errorMessageCustom(e,t.language.errorTitle,i,t)})}function a(t){if(t.errorMessagePosition&&"object"==typeof t.errorMessagePosition){e.formUtils.warn("Deprecated use of config parameter errorMessagePosition, use config.submitErrorMessageCallback instead");var i=t.errorMessagePosition;t.errorMessagePosition="top",t.submitErrorMessageCallback=function(){return i}}}function n(t){var i={se:"sv",cz:"cs",dk:"da"};if(t.lang in i){var a=i[t.lang];e.formUtils.warn('Deprecated use of lang code "'+t.lang+'" use "'+a+'" instead'),t.lang=a}}e.fn.validateForm=function(t,i){return e.formUtils.warn("Use of deprecated function $.validateForm, use $.isValid instead"),this.isValid(t,i,!0)},e(window).on("formValidationPluginInit",function(e,t){n(t),i(t),a(t)}).on("validatorsLoaded formValidationSetup",function(t,i){i||(i=e("form")),function(t){var i=t.find("[data-validation-if-checked]");i.length&&e.formUtils.warn('Detected use of attribute "data-validation-if-checked" which is deprecated. Use "data-validation-depends-on" provided by module "logic"'),i.on("beforeValidation",function(){var i=e(this),a=i.valAttr("if-checked"),n=e('input[name="'+a+'"]',t),o=n.is(":checked"),r=(e.formUtils.getValue(n)||"").toString(),s=i.valAttr("if-checked-value");(!o||s&&s!==r)&&i.valAttr("skipped",!0)})}(i)})}(e),function(e){"use strict";var t={resolveErrorMessage:function(e,t,i,a,n){var o=a.validationErrorMsgAttribute+"-"+i.replace("validate_",""),r=e.attr(o);return r||((r=e.attr(a.validationErrorMsgAttribute))||((r="function"!=typeof t.errorMessageKey?n[t.errorMessageKey]:n[t.errorMessageKey(a)])||(r=t.errorMessage))),r},getParentContainer:function(t){if(t.valAttr("error-msg-container"))return e(t.valAttr("error-msg-container"));var i=t.parent();return"checkbox"===t.attr("type")&&t.closest(".checkbox").length?i=t.closest(".checkbox").parent():"radio"===t.attr("type")&&t.closest(".radio").length&&(i=t.closest(".radio").parent()),i.closest(".input-group").length&&(i=i.closest(".input-group").parent()),i},applyInputErrorStyling:function(e,t){e.addClass(t.errorElementClass).removeClass(t.successElementClass),this.getParentContainer(e).addClass(t.inputParentClassOnError).removeClass(t.inputParentClassOnSuccess),""!==t.borderColorOnError&&e.css("border-color",t.borderColorOnError)},applyInputSuccessStyling:function(e,t){e.addClass(t.successElementClass),this.getParentContainer(e).addClass(t.inputParentClassOnSuccess)},removeInputStylingAndMessage:function(e,i){e.removeClass(i.successElementClass).removeClass(i.errorElementClass).css("border-color","");var a=t.getParentContainer(e);if(a.removeClass(i.inputParentClassOnError).removeClass(i.inputParentClassOnSuccess),"function"==typeof i.inlineErrorMessageCallback){var n=i.inlineErrorMessageCallback(e,!1,i);n&&n.html("")}else a.find("."+i.errorMessageClass).remove()},removeAllMessagesAndStyling:function(i,a){if("function"==typeof a.submitErrorMessageCallback){var n=a.submitErrorMessageCallback(i,!1,a);n&&n.html("")}else i.find("."+a.errorMessageClass+".alert").remove();i.find("."+a.errorElementClass+",."+a.successElementClass).each(function(){t.removeInputStylingAndMessage(e(this),a)})},setInlineMessage:function(t,i,a){this.applyInputErrorStyling(t,a);var n,o=document.getElementById(t.attr("name")+"_err_msg"),r=!1,s=function(a){e.formUtils.$win.trigger("validationErrorDisplay",[t,a]),a.html(i)},l=function(){var o=!1;r.find("."+a.errorMessageClass).each(function(){if(this.inputReferer===t[0])return o=e(this),!1}),o?i?s(o):o.remove():""!==i&&(n=e('<div class="'+a.errorMessageClass+' alert"></div>'),s(n),n[0].inputReferer=t[0],r.prepend(n))};if(o)e.formUtils.warn("Using deprecated element reference "+o.id),r=e(o),l();else if("function"==typeof a.inlineErrorMessageCallback){if(!(r=a.inlineErrorMessageCallback(t,i,a)))return;l()}else{var d=this.getParentContainer(t);0===(n=d.find("."+a.errorMessageClass+".help-block")).length&&(n=e("<span></span>").addClass("help-block").addClass(a.errorMessageClass)).appendTo(d),s(n)}},setMessageInTopOfForm:function(t,i,a,n){var o='<div class="{errorMessageClass} alert alert-danger"><strong>{errorTitle}</strong><ul>{fields}</ul></div>',r=!1;if("function"!=typeof a.submitErrorMessageCallback||(r=a.submitErrorMessageCallback(t,i,a))){var s={errorTitle:n.errorTitle,fields:"",errorMessageClass:a.errorMessageClass};e.each(i,function(e,t){s.fields+="<li>"+t+"</li>"}),e.each(s,function(e,t){o=o.replace("{"+e+"}",t)}),r?r.html(o):t.children().eq(0).before(e(o))}}};e.formUtils=e.extend(e.formUtils||{},{dialogs:t})}(e),function(e,t,i){"use strict";var a=0;e.fn.validateOnBlur=function(t,i){var a=this,n=this.find("*[data-validation]");return n.each(function(){var n=e(this);if(n.is("[type=radio]")){var o=a.find('[type=radio][name="'+n.attr("name")+'"]');o.bind("blur.validation",function(){n.validateInputOnBlur(t,i,!0,"blur")}),i.validateCheckboxRadioOnClick&&o.bind("click.validation",function(){n.validateInputOnBlur(t,i,!0,"click")})}}),n.bind("blur.validation",function(){e(this).validateInputOnBlur(t,i,!0,"blur")}),i.validateCheckboxRadioOnClick&&this.find("input[type=checkbox][data-validation],input[type=radio][data-validation]").bind("click.validation",function(){e(this).validateInputOnBlur(t,i,!0,"click")}),this},e.fn.validateOnEvent=function(t,i){if(0!==this.length)return("FORM"===this[0].nodeName?this.find("*[data-validation-event]"):this).each(function(){var a=e(this),n=a.valAttr("event");n&&a.unbind(n+".validation").bind(n+".validation",function(a){9!==(a||{}).keyCode&&e(this).validateInputOnBlur(t,i,!0,n)})}),this},e.fn.showHelpOnFocus=function(t){return t||(t="data-validation-help"),this.find("textarea,input").each(function(){var i=e(this),n="jquery_form_help_"+ ++a,o=i.attr(t);i.removeClass("has-help-text").unbind("focus.help").unbind("blur.help"),o&&i.addClass("has-help-txt").bind("focus.help",function(){var t=i.parent().find("."+n);0===t.length&&(t=e("<span />").addClass(n).addClass("help").addClass("help-block").text(o).hide(),i.after(t)),t.fadeIn()}).bind("blur.help",function(){e(this).parent().find("."+n).fadeOut("slow")})}),this},e.fn.validate=function(t,i,a){var n=e.extend({},e.formUtils.LANG,a||{});this.each(function(){var a=e(this),o=(a.closest("form").get(0)||{}).validationConfig||e.formUtils.defaultConfig();a.one("validation",function(e,i){"function"==typeof t&&t(i,this,e)}),a.validateInputOnBlur(n,e.extend({},o,i||{}),!0)})},e.fn.willPostponeValidation=function(){return(this.valAttr("suggestion-nr")||this.valAttr("postpone")||this.hasClass("hasDatepicker"))&&!t.postponedValidation},e.fn.validateInputOnBlur=function(i,a,n,o){if(e.formUtils.eventType=o,this.willPostponeValidation()){var r=this,s=this.valAttr("postpone")||200;return t.postponedValidation=function(){r.validateInputOnBlur(i,a,n,o),t.postponedValidation=!1},setTimeout(function(){t.postponedValidation&&t.postponedValidation()},s),this}i=e.extend({},e.formUtils.LANG,i||{}),e.formUtils.dialogs.removeInputStylingAndMessage(this,a);var l=this,d=l.closest("form"),u=e.formUtils.validateInput(l,i,a,d,o),c=function(){l.validateInputOnBlur(i,a,!1,"blur.revalidated")};return"blur"===o&&l.unbind("validation.revalidate",c).one("validation.revalidate",c),n&&l.removeKeyUpValidation(),u.shouldChangeDisplay&&(u.isValid?e.formUtils.dialogs.applyInputSuccessStyling(l,a):e.formUtils.dialogs.setInlineMessage(l,u.errorMsg,a)),!u.isValid&&n&&l.validateOnKeyUp(i,a),this},e.fn.validateOnKeyUp=function(t,i){return this.each(function(){var a=e(this);a.valAttr("has-keyup-event")||a.valAttr("has-keyup-event","true").bind("keyup.validation",function(e){9!==e.keyCode&&a.validateInputOnBlur(t,i,!1,"keyup")})}),this},e.fn.removeKeyUpValidation=function(){return this.each(function(){e(this).valAttr("has-keyup-event",!1).unbind("keyup.validation")}),this},e.fn.valAttr=function(e,t){return void 0===t?this.attr("data-validation-"+e):!1===t||null===t?this.removeAttr("data-validation-"+e):(e=e.length>0?"-"+e:"",this.attr("data-validation"+e,t))},e.fn.isValid=function(t,i,a){if(e.formUtils.isLoadingModules){var n=this;return setTimeout(function(){n.isValid(t,i,a)},200),null}i=e.extend({},e.formUtils.defaultConfig(),i||{}),t=e.extend({},e.formUtils.LANG,t||{}),a=!1!==a,e.formUtils.errorDisplayPreventedWhenHalted&&(delete e.formUtils.errorDisplayPreventedWhenHalted,a=!1);var o=function(t,n){e.inArray(t,s)<0&&s.push(t),l.push(n),n.valAttr("current-error",t),a&&e.formUtils.dialogs.applyInputErrorStyling(n,i)},r=[],s=[],l=[],d=this;if(a&&e.formUtils.dialogs.removeAllMessagesAndStyling(d,i),d.find("input,textarea,select").filter(':not([type="submit"],[type="button"])').each(function(){var a=e(this),n=a.attr("type"),s="radio"===n||"checkbox"===n,l=a.attr("name");if(!function(t,a){return"submit"===a||"button"===a||"reset"===a||e.inArray(t,i.ignore||[])>-1}(l,n)&&(!s||e.inArray(l,r)<0)){s&&r.push(l);var u=e.formUtils.validateInput(a,t,i,d,"submit");u.isValid?u.isValid&&u.shouldChangeDisplay&&(a.valAttr("current-error",!1),e.formUtils.dialogs.applyInputSuccessStyling(a,i)):o(u.errorMsg,a)}}),"function"==typeof i.onValidate){var u=i.onValidate(d);e.isArray(u)?e.each(u,function(e,t){o(t.message,t.element)}):u&&u.element&&u.message&&o(u.message,u.element)}return e.formUtils.isValidatingEntireForm=!1,l.length>0&&a&&("top"===i.errorMessagePosition?e.formUtils.dialogs.setMessageInTopOfForm(d,s,i,t):e.each(l,function(t,a){e.formUtils.dialogs.setInlineMessage(a,a.valAttr("current-error"),i)}),i.scrollToTopOnError&&e.formUtils.$win.scrollTop(d.offset().top-20)),!a&&e.formUtils.haltValidation&&(e.formUtils.errorDisplayPreventedWhenHalted=!0),0===l.length&&!e.formUtils.haltValidation},e.fn.restrictLength=function(t){return new e.formUtils.lengthRestriction(this,t),this},e.fn.addSuggestions=function(t){var i=!1;return this.find("input").each(function(){var a=e(this);(i=e.split(a.attr("data-suggestions"))).length>0&&!a.hasClass("has-suggestions")&&(e.formUtils.suggest(a,i,t),a.addClass("has-suggestions"))}),this}}(e,window),function(e){"use strict";e.formUtils=e.extend(e.formUtils||{},{isLoadingModules:!1,loadedModules:{},registerLoadedModule:function(t){this.loadedModules[e.trim(t).toLowerCase()]=!0},hasLoadedModule:function(t){return e.trim(t).toLowerCase()in this.loadedModules},loadModules:function(t,i,a){if(e.formUtils.isLoadingModules)setTimeout(function(){e.formUtils.loadModules(t,i,a)},100);else{var n=function(t,i){var n=e.split(t),o=n.length,r=function(){0===--o&&(e.formUtils.isLoadingModules=!1,"function"==typeof a&&a())};o>0&&(e.formUtils.isLoadingModules=!0);var s="?_="+(new Date).getTime(),l=document.getElementsByTagName("head")[0]||document.getElementsByTagName("body")[0];e.each(n,function(t,a){if(0===(a=e.trim(a)).length||e.formUtils.hasLoadedModule(a))r();else{var n=i+a+(".js"===a.slice(-3)?"":".js"),o=document.createElement("SCRIPT");"function"==typeof define&&define.amd?require([n+(".dev.js"===n.slice(-7)?s:"")],r):(o.type="text/javascript",o.onload=r,o.src=n+(".dev.js"===n.slice(-7)?s:""),o.onerror=function(){e.formUtils.warn("Unable to load form validation module "+n,!0),r()},o.onreadystatechange=function(){"complete"!==this.readyState&&"loaded"!==this.readyState||(r(),this.onload=null,this.onreadystatechange=null)},l.appendChild(o))}})};if(i)n(t,i);else{var o=function(){var i=!1;return e('script[src*="form-validator"]').each(function(){if(!(this.src.split("form-validator")[1].split("node_modules").length>1))return"/"===(i=this.src.substr(0,this.src.lastIndexOf("/"))+"/")&&(i=""),!1}),!1!==i&&(n(t,i),!0)};o()||e(function(){o()||"function"==typeof a&&a()})}}}})}(e),function(e){"use strict";e.split=function(t,i,a){a=void 0===a||!0===a;var n=new RegExp("[,|"+(a?"\\s":"")+"-]\\s*","g");if("function"!=typeof i){if(!t)return[];var o=[];return e.each(t.split(i||n),function(t,i){(i=e.trim(i)).length&&o.push(i)}),o}t&&e.each(t.split(n),function(t,a){if((a=e.trim(a)).length)return i(a,t)})},e.validate=function(t){var i=e.extend(e.formUtils.defaultConfig(),{form:"form",validateOnEvent:!1,validateOnBlur:!0,validateCheckboxRadioOnClick:!0,showHelpOnFocus:!0,addSuggestions:!0,modules:"",onModulesLoaded:null,language:!1,onSuccess:!1,onError:!1,onElementValidate:!1});if(t=e.extend(i,t||{}),e(window).trigger("formValidationPluginInit",[t]),t.lang&&"en"!==t.lang){var a="lang/"+t.lang+".js";t.modules+=t.modules.length?","+a:a}e(t.form).each(function(i,a){a.validationConfig=t;var n=e(a);n.trigger("formValidationSetup",[n,t]),n.find(".has-help-txt").unbind("focus.validation").unbind("blur.validation"),n.removeClass("has-validation-callback").unbind("submit.validation").unbind("reset.validation").find("input[data-validation],textarea[data-validation]").unbind("blur.validation"),n.bind("submit.validation",function(i){var a=e(this),n=function(){return i.stopImmediatePropagation(),!1};if(e.formUtils.haltValidation)return n();if(e.formUtils.isLoadingModules)return setTimeout(function(){a.trigger("submit.validation")},200),n();var o=a.isValid(t.language,t);return e.formUtils.haltValidation?n():o&&"function"==typeof t.onSuccess?!1===t.onSuccess(a)?n():void 0:o||"function"!=typeof t.onError?!!o||n():(t.onError(a),n())}).bind("reset.validation",function(){e.formUtils.dialogs.removeAllMessagesAndStyling(n,t)}).addClass("has-validation-callback"),t.showHelpOnFocus&&n.showHelpOnFocus(),t.addSuggestions&&n.addSuggestions(),t.validateOnBlur&&(n.validateOnBlur(t.language,t),n.bind("html5ValidationAttrsFound",function(){n.validateOnBlur(t.language,t)})),t.validateOnEvent&&n.validateOnEvent(t.language,t)}),""!==t.modules&&e.formUtils.loadModules(t.modules,null,function(){"function"==typeof t.onModulesLoaded&&t.onModulesLoaded();var i="string"==typeof t.form?e(t.form):t.form;e.formUtils.$win.trigger("validatorsLoaded",[i,t])})}}(e),function(e,t){"use strict";var i=e(t);e.formUtils=e.extend(e.formUtils||{},{$win:i,defaultConfig:function(){return{ignore:[],errorElementClass:"error",successElementClass:"valid",borderColorOnError:"#b94a48",errorMessageClass:"form-error",validationRuleAttribute:"data-validation",validationErrorMsgAttribute:"data-validation-error-msg",errorMessagePosition:"inline",errorMessageTemplate:{container:'<div class="{errorMessageClass} alert alert-danger">{messages}</div>',messages:"<strong>{errorTitle}</strong><ul>{fields}</ul>",field:"<li>{msg}</li>"},scrollToTopOnError:!0,dateFormat:"yyyy-mm-dd",addValidClassOnAll:!1,decimalSeparator:".",inputParentClassOnError:"has-error",inputParentClassOnSuccess:"has-success",validateHiddenInputs:!1,inlineErrorMessageCallback:!1,submitErrorMessageCallback:!1}},validators:{},sanitizers:{},_events:{load:[],valid:[],invalid:[]},haltValidation:!1,addValidator:function(e){var t=0===e.name.indexOf("validate_")?e.name:"validate_"+e.name;void 0===e.validateOnKeyUp&&(e.validateOnKeyUp=!0),this.validators[t]=e},addSanitizer:function(e){this.sanitizers[e.name]=e},warn:function(e,i){"console"in t?"function"==typeof t.console.warn?t.console.warn(e):"function"==typeof t.console.log&&t.console.log(e):i&&alert(e)},getValue:function(e,t){var i=t?t.find(e):e;if(i.length>0){var a=i.eq(0).attr("type");return"radio"===a||"checkbox"===a?i.filter(":checked").val()||"":i.val()||""}return!1},validateInput:function(t,i,a,n,o){a=a||e.formUtils.defaultConfig(),i=i||e.formUtils.LANG,n.length||(n=t.parent());var r=this.getValue(t);t.valAttr("skipped",!1).one("beforeValidation",function(){(t.attr("disabled")||!t.is(":visible")&&!a.validateHiddenInputs)&&t.valAttr("skipped",1)}).trigger("beforeValidation",[r,i,a]);var s="true"===t.valAttr("optional"),l=!r&&s,d=t.attr(a.validationRuleAttribute),u=!0,c="",f={isValid:!0,shouldChangeDisplay:!0,errorMsg:""};if(!d||l||t.valAttr("skipped"))return f.shouldChangeDisplay=a.addValidClassOnAll,f;var h=t.valAttr("ignore");return h&&e.each(h.split(""),function(e,t){r=r.replace(new RegExp("\\"+t,"g"),"")}),e.split(d,function(s){0!==s.indexOf("validate_")&&(s="validate_"+s);var l=e.formUtils.validators[s];if(!l)throw new Error('Using undefined validator "'+s+'". Maybe you have forgotten to load the module that "'+s+'" belongs to?');if("validate_checkbox_group"===s&&(t=n.find('[name="'+t.attr("name")+'"]:eq(0)')),("keyup"!==o||l.validateOnKeyUp)&&(u=l.validatorFunction(r,t,a,i,n,o)),!u)return a.validateOnBlur&&t.validateOnKeyUp(i,a),c=e.formUtils.dialogs.resolveErrorMessage(t,l,s,a,i),!1}),!1===u?(t.trigger("validation",!1),f.errorMsg=c,f.isValid=!1,f.shouldChangeDisplay=!0):null===u?f.shouldChangeDisplay=!1:(t.trigger("validation",!0),f.shouldChangeDisplay=!0),"function"==typeof a.onElementValidate&&null!==c&&a.onElementValidate(f.isValid,t,n,c),t.trigger("afterValidation",[f,o]),f},parseDate:function(t,i,a){var n,o,r,s,l=i.replace(/[a-zA-Z]/gi,"").substring(0,1),d="^",u=i.split(l||null);if(e.each(u,function(e,t){d+=(e>0?"\\"+l:"")+"(\\d{"+t.length+"})"}),d+="$",a){var c=[];e.each(t.split(l),function(e,t){1===t.length&&(t="0"+t),c.push(t)}),t=c.join(l)}if(null===(n=t.match(new RegExp(d))))return!1;var f=function(t,i,a){for(var n=0;n<i.length;n++)if(i[n].substring(0,1)===t)return e.formUtils.parseDateInt(a[n+1]);return-1};return r=f("m",u,n),o=f("d",u,n),s=f("y",u,n),!(2===r&&o>28&&(s%4!=0||s%100==0&&s%400!=0)||2===r&&o>29&&(s%4==0||s%100!=0&&s%400==0)||r>12||0===r)&&!(this.isShortMonth(r)&&o>30||!this.isShortMonth(r)&&o>31||0===o)&&[s,r,o]},parseDateInt:function(e){return 0===e.indexOf("0")&&(e=e.replace("0","")),parseInt(e,10)},isShortMonth:function(e){return e%2==0&&e<7||e%2!=0&&e>7},lengthRestriction:function(t,i){var a=parseInt(i.text(),10),n=0,o=function(){var e=t.val().length;if(e>a){var o=t.scrollTop();t.val(t.val().substring(0,a)),t.scrollTop(o)}(n=a-e)<0&&(n=0),i.text(n)};e(t).bind("keydown keyup keypress focus blur",o).bind("cut paste",function(){setTimeout(o,100)}),e(document).bind("ready",o)},numericRangeCheck:function(t,i){var a=e.split(i),n=parseInt(i.substr(3),10);return 1===a.length&&-1===i.indexOf("min")&&-1===i.indexOf("max")&&(a=[i,i]),2===a.length&&(t<parseInt(a[0],10)||t>parseInt(a[1],10))?["out",a[0],a[1]]:0===i.indexOf("min")&&t<n?["min",n]:0===i.indexOf("max")&&t>n?["max",n]:["ok"]},_numSuggestionElements:0,_selectedSuggestion:null,_previousTypedVal:null,suggest:function(t,a,n){var o={css:{maxHeight:"150px",background:"#FFF",lineHeight:"150%",textDecoration:"underline",overflowX:"hidden",overflowY:"auto",border:"#CCC solid 1px",borderTop:"none",cursor:"pointer"},activeSuggestionCSS:{background:"#E9E9E9"}},r=function(e,t){var i=t.offset();e.css({width:t.outerWidth(),left:i.left+"px",top:i.top+t.outerHeight()+"px"})};n&&e.extend(o,n),o.css.position="absolute",o.css["z-index"]=9999,t.attr("autocomplete","off"),0===this._numSuggestionElements&&i.bind("resize",function(){e(".jquery-form-suggestions").each(function(){var t=e(this),i=t.attr("data-suggest-container");r(t,e(".suggestions-"+i).eq(0))})}),this._numSuggestionElements++;var s=function(t){var i=t.valAttr("suggestion-nr");e.formUtils._selectedSuggestion=null,e.formUtils._previousTypedVal=null,e(".jquery-form-suggestion-"+i).fadeOut("fast")};return t.data("suggestions",a).valAttr("suggestion-nr",this._numSuggestionElements).unbind("focus.suggest").bind("focus.suggest",function(){e(this).trigger("keyup"),e.formUtils._selectedSuggestion=null}).unbind("keyup.suggest").bind("keyup.suggest",function(){var i=e(this),a=[],n=e.trim(i.val()).toLocaleLowerCase();if(n!==e.formUtils._previousTypedVal){e.formUtils._previousTypedVal=n;var l=!1,d=i.valAttr("suggestion-nr"),u=e(".jquery-form-suggestion-"+d);if(u.scrollTop(0),""!==n){var c=n.length>2;e.each(i.data("suggestions"),function(e,t){var i=t.toLocaleLowerCase();return i===n?(a.push("<strong>"+t+"</strong>"),l=!0,!1):void((0===i.indexOf(n)||c&&i.indexOf(n)>-1)&&a.push(t.replace(new RegExp(n,"gi"),"<strong>$&</strong>")))})}l||0===a.length&&u.length>0?u.hide():a.length>0&&0===u.length?(u=e("<div></div>").css(o.css).appendTo("body"),t.addClass("suggestions-"+d),u.attr("data-suggest-container",d).addClass("jquery-form-suggestions").addClass("jquery-form-suggestion-"+d)):a.length>0&&!u.is(":visible")&&u.show(),a.length>0&&n.length!==a[0].length&&(r(u,i),u.html(""),e.each(a,function(t,a){e("<div></div>").append(a).css({overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",padding:"5px"}).addClass("form-suggest-element").appendTo(u).click(function(){i.focus(),i.val(e(this).text()),i.trigger("change"),s(i)})}))}}).unbind("keydown.validation").bind("keydown.validation",function(t){var i,a,n=t.keyCode?t.keyCode:t.which,r=e(this);if(13===n&&null!==e.formUtils._selectedSuggestion){if(i=r.valAttr("suggestion-nr"),(a=e(".jquery-form-suggestion-"+i)).length>0){var l=a.find("div").eq(e.formUtils._selectedSuggestion).text();r.val(l),r.trigger("change"),s(r),t.preventDefault()}}else{i=r.valAttr("suggestion-nr");var d=(a=e(".jquery-form-suggestion-"+i)).children();if(d.length>0&&e.inArray(n,[38,40])>-1){38===n?(null===e.formUtils._selectedSuggestion?e.formUtils._selectedSuggestion=d.length-1:e.formUtils._selectedSuggestion--,e.formUtils._selectedSuggestion<0&&(e.formUtils._selectedSuggestion=d.length-1)):40===n&&(null===e.formUtils._selectedSuggestion?e.formUtils._selectedSuggestion=0:e.formUtils._selectedSuggestion++,e.formUtils._selectedSuggestion>d.length-1&&(e.formUtils._selectedSuggestion=0));var u=a.innerHeight(),c=a.scrollTop(),f=a.children().eq(0).outerHeight()*e.formUtils._selectedSuggestion;return(f<c||f>c+u)&&a.scrollTop(f),d.removeClass("active-suggestion").css("background","none").eq(e.formUtils._selectedSuggestion).addClass("active-suggestion").css(o.activeSuggestionCSS),t.preventDefault(),!1}}}).unbind("blur.suggest").bind("blur.suggest",function(){s(e(this))}),t},LANG:{errorTitle:"Form submission failed!",requiredField:"This is a required field",requiredFields:"You have not answered all required fields",badTime:"You have not given a correct time",badEmail:"You have not given a correct e-mail address",badTelephone:"You have not given a correct phone number",badSecurityAnswer:"You have not given a correct answer to the security question",badDate:"You have not given a correct date",lengthBadStart:"The input value must be between ",lengthBadEnd:" characters",lengthTooLongStart:"The input value is longer than ",lengthTooShortStart:"The input value is shorter than ",notConfirmed:"Input values could not be confirmed",badDomain:"Incorrect domain value",badUrl:"The input value is not a correct URL",badCustomVal:"The input value is incorrect",andSpaces:" and spaces ",badInt:"The input value was not a correct number",badSecurityNumber:"Your social security number was incorrect",badUKVatAnswer:"Incorrect UK VAT Number",badUKNin:"Incorrect UK NIN",badUKUtr:"Incorrect UK UTR Number",badStrength:"The password isn't strong enough",badNumberOfSelectedOptionsStart:"You have to choose at least ",badNumberOfSelectedOptionsEnd:" answers",badAlphaNumeric:"The input value can only contain alphanumeric characters ",badAlphaNumericExtra:" and ",wrongFileSize:"The file you are trying to upload is too large (max %s)",wrongFileType:"Only files of type %s is allowed",groupCheckedRangeStart:"Please choose between ",groupCheckedTooFewStart:"Please choose at least ",groupCheckedTooManyStart:"Please choose a maximum of ",groupCheckedEnd:" item(s)",badCreditCard:"The credit card number is not correct",badCVV:"The CVV number was not correct",wrongFileDim:"Incorrect image dimensions,",imageTooTall:"the image can not be taller than",imageTooWide:"the image can not be wider than",imageTooSmall:"the image was too small",min:"min",max:"max",imageRatioNotAccepted:"Image ratio is not be accepted",badBrazilTelephoneAnswer:"The phone number entered is invalid",badBrazilCEPAnswer:"The CEP entered is invalid",badBrazilCPFAnswer:"The CPF entered is invalid",badPlPesel:"The PESEL entered is invalid",badPlNip:"The NIP entered is invalid",badPlRegon:"The REGON entered is invalid",badreCaptcha:"Please confirm that you are not a bot",passwordComplexityStart:"Password must contain at least ",passwordComplexitySeparator:", ",passwordComplexityUppercaseInfo:" uppercase letter(s)",passwordComplexityLowercaseInfo:" lowercase letter(s)",passwordComplexitySpecialCharsInfo:" special character(s)",passwordComplexityNumericCharsInfo:" numeric character(s)",passwordComplexityEnd:"."}})}(e,window),function(e){e.formUtils.addValidator({name:"email",validatorFunction:function(t){var i=t.toLowerCase().split("@"),a=i[0],n=i[1];if(a&&n){if(0===a.indexOf('"')){var o=a.length;if((a=a.replace(/\"/g,"")).length!==o-2)return!1}return e.formUtils.validators.validate_domain.validatorFunction(i[1])&&0!==a.indexOf(".")&&"."!==a.substring(a.length-1,a.length)&&-1===a.indexOf("..")&&!/[^\w\+\.\-\#\-\_\~\!\$\&\'\(\)\*\+\,\;\=\:]/.test(a)}return!1},errorMessage:"",errorMessageKey:"badEmail"}),e.formUtils.addValidator({name:"domain",validatorFunction:function(e){return e.length>0&&e.length<=253&&!/[^a-zA-Z0-9]/.test(e.slice(-2))&&!/[^a-zA-Z0-9]/.test(e.substr(0,1))&&!/[^a-zA-Z0-9\.\-]/.test(e)&&1===e.split("..").length&&e.split(".").length>1},errorMessage:"",errorMessageKey:"badDomain"}),e.formUtils.addValidator({name:"required",validatorFunction:function(t,i,a,n,o){switch(i.attr("type")){case"checkbox":return i.is(":checked");case"radio":return o.find('input[name="'+i.attr("name")+'"]').filter(":checked").length>0;default:return""!==e.trim(t)}},errorMessage:"",errorMessageKey:function(e){return"top"===e.errorMessagePosition||"function"==typeof e.errorMessagePosition?"requiredFields":"requiredField"}}),e.formUtils.addValidator({name:"length",validatorFunction:function(t,i,a,n){var o=i.valAttr("length"),r=i.attr("type");if(void 0===o)return alert('Please add attribute "data-validation-length" to '+i[0].nodeName+" named "+i.attr("name")),!0;var s,l="file"===r&&void 0!==i.get(0).files?i.get(0).files.length:t.length,d=e.formUtils.numericRangeCheck(l,o);switch(d[0]){case"out":this.errorMessage=n.lengthBadStart+o+n.lengthBadEnd,s=!1;break;case"min":this.errorMessage=n.lengthTooShortStart+d[1]+n.lengthBadEnd,s=!1;break;case"max":this.errorMessage=n.lengthTooLongStart+d[1]+n.lengthBadEnd,s=!1;break;default:s=!0}return s},errorMessage:"",errorMessageKey:""}),e.formUtils.addValidator({name:"url",validatorFunction:function(t){if(/^(https?|ftp):\/\/((((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|\[|\]|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(t)){var i=t.split("://")[1],a=i.indexOf("/");return a>-1&&(i=i.substr(0,a)),e.formUtils.validators.validate_domain.validatorFunction(i)}return!1},errorMessage:"",errorMessageKey:"badUrl"}),e.formUtils.addValidator({name:"number",validatorFunction:function(e,t,i){if(""!==e){var a,n,o=t.valAttr("allowing")||"",r=t.valAttr("decimal-separator")||i.decimalSeparator,s=!1,l=t.valAttr("step")||"",d=!1;if((t.attr("data-sanitize")||"").match(/(^|[\s])numberFormat([\s]|$)/i)){if(!window.numeral)throw new ReferenceError("The data-sanitize value numberFormat cannot be used without the numeral library. Please see Data Validation in http://www.formvalidator.net for more information.");e.length&&(e=String(numeral().unformat(e)))}if(-1===o.indexOf("number")&&(o+=",number"),-1===o.indexOf("negative")&&0===e.indexOf("-"))return!1;if(o.indexOf("range")>-1&&(a=parseFloat(o.substring(o.indexOf("[")+1,o.indexOf(";"))),n=parseFloat(o.substring(o.indexOf(";")+1,o.indexOf("]"))),s=!0),""!==l&&(d=!0),","===r){if(e.indexOf(".")>-1)return!1;e=e.replace(",",".")}if(""===e.replace(/[0-9-]/g,"")&&(!s||e>=a&&e<=n)&&(!d||e%l==0))return!0;if(o.indexOf("float")>-1&&null!==e.match(new RegExp("^([0-9-]+)\\.([0-9]+)$"))&&(!s||e>=a&&e<=n)&&(!d||e%l==0))return!0}return!1},errorMessage:"",errorMessageKey:"badInt"}),e.formUtils.addValidator({name:"alphanumeric",validatorFunction:function(t,i,a,n){var o="^([a-zA-Z0-9",r="]+)$",s=i.valAttr("allowing"),l="",d=!1;if(s){l=o+s+r;var u=s.replace(/\\/g,"");u.indexOf(" ")>-1&&(d=!0,u=u.replace(" ",""),u+=n.andSpaces||e.formUtils.LANG.andSpaces),n.badAlphaNumericAndExtraAndSpaces&&n.badAlphaNumericAndExtra?this.errorMessage=d?n.badAlphaNumericAndExtraAndSpaces+u:n.badAlphaNumericAndExtra+u+n.badAlphaNumericExtra:this.errorMessage=n.badAlphaNumeric+n.badAlphaNumericExtra+u}else l=o+r,this.errorMessage=n.badAlphaNumeric;return new RegExp(l).test(t)},errorMessage:"",errorMessageKey:""}),e.formUtils.addValidator({name:"custom",validatorFunction:function(e,t){return new RegExp(t.valAttr("regexp")).test(e)},errorMessage:"",errorMessageKey:"badCustomVal"}),e.formUtils.addValidator({name:"date",validatorFunction:function(t,i,a){var n=i.valAttr("format")||a.dateFormat||"yyyy-mm-dd",o="false"===i.valAttr("require-leading-zero");return!1!==e.formUtils.parseDate(t,n,o)},errorMessage:"",errorMessageKey:"badDate"}),e.formUtils.addValidator({name:"checkbox_group",validatorFunction:function(t,i,a,n,o){var r=!0,s=i.attr("name"),l=e('input[type=checkbox][name^="'+s+'"]',o),d=l.filter(":checked").length,u=i.valAttr("qty");if(void 0===u){var c=i.get(0).nodeName;alert('Attribute "data-validation-qty" is missing from '+c+" named "+i.attr("name"))}var f=e.formUtils.numericRangeCheck(d,u);switch(f[0]){case"out":this.errorMessage=n.groupCheckedRangeStart+u+n.groupCheckedEnd,r=!1;break;case"min":this.errorMessage=n.groupCheckedTooFewStart+f[1]+(n.groupCheckedTooFewEnd||n.groupCheckedEnd),r=!1;break;case"max":this.errorMessage=n.groupCheckedTooManyStart+f[1]+(n.groupCheckedTooManyEnd||n.groupCheckedEnd),r=!1;break;default:r=!0}if(!r){var h=function(){l.unbind("click",h),l.filter("*[data-validation]").validateInputOnBlur(n,a,!1,"blur")};l.bind("click",h)}return r}})}(e)}),function(e){"object"==typeof module&&"object"==typeof module.exports?e(require("jquery"),window,document):e(jQuery,window,document)}(function(e,t,i,a){var n=[],o=function(){return n.length?n[n.length-1]:null},r=function(){var e,t=!1;for(e=n.length-1;e>=0;e--)n[e].$blocker&&(n[e].$blocker.toggleClass("current",!t).toggleClass("behind",t),t=!0)};e.modal=function(t,i){var a,r;if(this.$body=e("body"),this.options=e.extend({},e.modal.defaults,i),this.options.doFade=!isNaN(parseInt(this.options.fadeDuration,10)),this.$blocker=null,this.options.closeExisting)for(;e.modal.isActive();)e.modal.close();if(n.push(this),t.is("a"))if(r=t.attr("href"),this.anchor=t,/^#/.test(r)){if(this.$elm=e(r),1!==this.$elm.length)return null;this.$body.append(this.$elm),this.open()}else this.$elm=e("<div>"),this.$body.append(this.$elm),a=function(e,t){t.elm.remove()},this.showSpinner(),t.trigger(e.modal.AJAX_SEND),e.get(r).done(function(i){if(e.modal.isActive()){t.trigger(e.modal.AJAX_SUCCESS);var n=o();n.$elm.empty().append(i).on(e.modal.CLOSE,a),n.hideSpinner(),n.open(),t.trigger(e.modal.AJAX_COMPLETE)}}).fail(function(){t.trigger(e.modal.AJAX_FAIL),o().hideSpinner(),n.pop(),t.trigger(e.modal.AJAX_COMPLETE)});else this.$elm=t,this.anchor=t,this.$body.append(this.$elm),this.open()},e.modal.prototype={constructor:e.modal,open:function(){var t=this;this.block(),this.anchor.blur(),this.options.doFade?setTimeout(function(){t.show()},this.options.fadeDuration*this.options.fadeDelay):this.show(),e(i).off("keydown.modal").on("keydown.modal",function(e){var t=o();27===e.which&&t.options.escapeClose&&t.close()}),this.options.clickClose&&this.$blocker.click(function(t){t.target===this&&e.modal.close()})},close:function(){n.pop(),this.unblock(),this.hide(),e.modal.isActive()||e(i).off("keydown.modal")},block:function(){this.$elm.trigger(e.modal.BEFORE_BLOCK,[this._ctx()]),this.$body.css("overflow","hidden"),this.$blocker=e('<div class="'+this.options.blockerClass+' blocker current"></div>').appendTo(this.$body),r(),this.options.doFade&&this.$blocker.css("opacity",0).animate({opacity:1},this.options.fadeDuration),this.$elm.trigger(e.modal.BLOCK,[this._ctx()])},unblock:function(t){!t&&this.options.doFade?this.$blocker.fadeOut(this.options.fadeDuration,this.unblock.bind(this,!0)):(this.$blocker.children().appendTo(this.$body),this.$blocker.remove(),this.$blocker=null,r(),e.modal.isActive()||this.$body.css("overflow",""))},show:function(){this.$elm.trigger(e.modal.BEFORE_OPEN,[this._ctx()]),this.options.showClose&&(this.closeButton=e('<a href="#close-modal" rel="modal:close" class="close-modal '+this.options.closeClass+'">'+this.options.closeText+"</a>"),this.$elm.append(this.closeButton)),this.$elm.addClass(this.options.modalClass).appendTo(this.$blocker),this.options.doFade?this.$elm.css({opacity:0,display:"inline-block"}).animate({opacity:1},this.options.fadeDuration):this.$elm.css("display","inline-block"),this.$elm.trigger(e.modal.OPEN,[this._ctx()])},hide:function(){this.$elm.trigger(e.modal.BEFORE_CLOSE,[this._ctx()]),this.closeButton&&this.closeButton.remove();var t=this;this.options.doFade?this.$elm.fadeOut(this.options.fadeDuration,function(){t.$elm.trigger(e.modal.AFTER_CLOSE,[t._ctx()])}):this.$elm.hide(0,function(){t.$elm.trigger(e.modal.AFTER_CLOSE,[t._ctx()])}),this.$elm.trigger(e.modal.CLOSE,[this._ctx()])},showSpinner:function(){this.options.showSpinner&&(this.spinner=this.spinner||e('<div class="'+this.options.modalClass+'-spinner"></div>').append(this.options.spinnerHtml),this.$body.append(this.spinner),this.spinner.show())},hideSpinner:function(){this.spinner&&this.spinner.remove()},_ctx:function(){return{elm:this.$elm,$elm:this.$elm,$blocker:this.$blocker,options:this.options}}},e.modal.close=function(t){if(e.modal.isActive()){t&&t.preventDefault();var i=o();return i.close(),i.$elm}},e.modal.isActive=function(){return n.length>0},e.modal.getCurrent=o,e.modal.defaults={closeExisting:!0,escapeClose:!0,clickClose:!0,closeText:"Close",closeClass:"",modalClass:"modal",blockerClass:"jquery-modal",spinnerHtml:'<div class="rect1"></div><div class="rect2"></div><div class="rect3"></div><div class="rect4"></div>',showSpinner:!0,showClose:!0,fadeDuration:null,fadeDelay:1},e.modal.BEFORE_BLOCK="modal:before-block",e.modal.BLOCK="modal:block",e.modal.BEFORE_OPEN="modal:before-open",e.modal.OPEN="modal:open",e.modal.BEFORE_CLOSE="modal:before-close",e.modal.CLOSE="modal:close",e.modal.AFTER_CLOSE="modal:after-close",e.modal.AJAX_SEND="modal:ajax:send",e.modal.AJAX_SUCCESS="modal:ajax:success",e.modal.AJAX_FAIL="modal:ajax:fail",e.modal.AJAX_COMPLETE="modal:ajax:complete",e.fn.modal=function(t){return 1===this.length&&new e.modal(this,t),this},e(i).on("click.modal",'a[rel~="modal:close"]',e.modal.close),e(i).on("click.modal",'a[rel~="modal:open"]',function(t){t.preventDefault(),e(this).modal()})}),jQuery(document).ready(function(e){var t=e("#snippet_type"),i=e("#anonymizeip"),a=e("#anonymizeip")[0],n=e("#gtm_id");e("#script_debug_mode");function o(e){e.attr("disabled",!0)}function r(e){e.removeAttr("disabled")}function s(e,t){e.checked=t}e.widget.bridge("gaetooltip",e.ui.tooltip),e(".ga-tooltip").gaetooltip({position:{my:"left bottom-10",at:"right top",collision:"none"}}),e(".btn_upload").on("click",function(t){e(".settings_content").slideDown(),t.preventDefault()}),e(".btn_close").on("click",function(t){e(".settings_content").slideUp(),t.preventDefault()}),e(".popup").on("click",function(t){e(".popup").slideUp(),t.preventDefault()}),"none"!==t.val()&&"gtm"!==t.val()||(s(a,!1),o(i)),"gtm"===t.val()?r(n):o(n),t.change(function(){var t=e(this).val();"none"===t||"gtm"===t?(s(a,!1),o(i)):r(i),"gtm"===t?r(n):o(n)}),e(".btn_upload").on("click",function(t){e(".settings_content").slideDown(),t.preventDefault()}),e(".btn_close").on("click",function(t){e(".settings_content").slideUp(),t.preventDefault()}),e(".popup").on("click",function(t){e(".popup").slideUp(),t.preventDefault()}),e('input[name="ga_events_options[permitted_roles][]"][value="administrator"]').css({"pointer-events":"none",opacity:.5}).prop("checked",!0),e(".divs-istracktime:checkbox").change(function(){var t=e(this),i=t.is(":checked"),a=t.data("track"),n="#track-elem"+a,o="#eventValue"+a;i?(e(n).show(),e(o).attr("disabled",!0)):(e(n).hide(),e(o).removeAttr("disabled"))}),e("#empty-istracktime:checkbox").change(function(){e(this).is(":checked")?(e("#empty-trackelem").show(),e("#empty-eventValue").attr("disabled",!0)):(e("#empty-trackelem").hide(),e("#empty-eventValue").removeAttr("disabled"))}),e(".divs-istracktime").trigger("change"),jQuery("body").on("click",'a[href="admin.php?page=wp-google-analytics-events-upgrade"]',function(e){e.preventDefault(),window.open("https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=nav","_blank")})});var gaeAjax=function(e){function t(t){t.preventDefault();var i=e(this).attr("id"),a="#"+e(this).data("action");e.ajax({type:"POST",url:wpflow_ajax.ajax_url,data:{post_id:i,action:"wpflow_get_event_json"},success:function(t){e(a).modal(),function(t,i){if(void 0!==i)for(var a in i)i.hasOwnProperty(a)&&(e(t+" #"+a).is(":checkbox")?"true"===i[a][0]?e(t+" #"+a).attr("checked",!0):e(t+" #"+a).removeAttr("checked",!1):e(t+" #"+a).val(i[a][0]))}(a,t.meta),e(a+" #event_id").val(i)},error:function(){alert("Error updating event")}})}function i(t){t.preventDefault();var i=e(this);e.ajax({type:"post",url:wpflow_ajax.ajax_url,data:i.serialize(),success:function(e){window.location.reload()}})}e(document).ready(function(e){if(void 0!==e.fn.modal.noConflict)e.fn.modal.noConflict();e.validate(),e(".wpgae-event-form").on("submit",i),e(".ga_main .edit a").click(t),e(".ga_main .delete a").click(t)})}(jQuery);
js/dist/admin-scripts.js ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** File generated by Grunt -- do not modify
2
+ * JQUERY-FORM-VALIDATOR
3
+ *
4
+ * @version 2.3.79
5
+ * @website http://formvalidator.net/
6
+ * @author Victor Jonsson, http://victorjonsson.se
7
+ * @license MIT
8
+ */
9
+ !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof module&&module.exports?module.exports=b(require("jquery")):b(a.jQuery)}(this,function(a){!function(a,b,c){function d(a,b){this.$form=a,this.$input=b,this.reset(),b.on("change paste",this.reset.bind(this))}var e=function(){return!1},f=null,g={numHalted:0,haltValidation:function(b){this.numHalted++,a.formUtils.haltValidation=!0,b.unbind("submit",e).bind("submit",e).find('*[type="submit"]').addClass("disabled").attr("disabled","disabled")},unHaltValidation:function(b){this.numHalted--,0===this.numHalted&&(a.formUtils.haltValidation=!1,b.unbind("submit",e).find('*[type="submit"]').removeClass("disabled").removeAttr("disabled","disabled"))}};d.prototype.reset=function(){this.haltedFormValidation=!1,this.hasRun=!1,this.isRunning=!1,this.result=c},d.prototype.run=function(a,b){return"keyup"===a?null:this.isRunning?(f=a,this.haltedFormValidation||(g.haltValidation(),this.haltedFormValidation=!0),null):this.hasRun?this.result:(f=a,g.haltValidation(this.$form),this.haltedFormValidation=!0,this.isRunning=!0,this.$input.attr("disabled","disabled").addClass("async-validation"),this.$form.addClass("async-validation"),b(function(a){this.done(a)}.bind(this)),null)},d.prototype.done=function(a){this.result=a,this.hasRun=!0,this.isRunning=!1,this.$input.removeAttr("disabled").removeClass("async-validation"),this.$form.removeClass("async-validation"),this.haltedFormValidation&&(g.unHaltValidation(this.$form),"submit"===f?this.$form.trigger("submit"):this.$input.trigger("validation.revalidate"))},d.loadInstance=function(a,b,c){var e,f=b.get(0);return f.asyncValidators||(f.asyncValidators={}),f.asyncValidators[a]?e=f.asyncValidators[a]:(e=new d(c,b),f.asyncValidators[a]=e),e},a.formUtils=a.extend(a.formUtils||{},{asyncValidation:function(a,b,c){return this.warn("Use of deprecated function $.formUtils.asyncValidation, use $.formUtils.addAsyncValidator() instead"),d.loadInstance(a,b,c)},addAsyncValidator:function(b){var c=a.extend({},b),e=c.validatorFunction;c.async=!0,c.validatorFunction=function(a,b,f,g,h,i){var j=d.loadInstance(this.name,b,h);return j.run(i,function(d){e.apply(c,[d,a,b,f,g,h,i])})},this.addValidator(c)}}),a(b).bind("validatorsLoaded formValidationSetup",function(b,c){c||(c=a("form")),c.find("[data-validation]").each(function(){var b=a(this);b.valAttr("async",!1),a.each(a.split(b.attr("data-validation")),function(c,d){var e=a.formUtils.validators["validate_"+d];e&&e.async&&b.valAttr("async","yes")})})})}(a,window),function(a,b){"use strict";function c(b){b&&"custom"===b.errorMessagePosition&&"function"==typeof b.errorMessageCustom&&(a.formUtils.warn("Use of deprecated function errorMessageCustom, use config.submitErrorMessageCallback instead"),b.submitErrorMessageCallback=function(a,c){b.errorMessageCustom(a,b.language.errorTitle,c,b)})}function d(b){if(b.errorMessagePosition&&"object"==typeof b.errorMessagePosition){a.formUtils.warn("Deprecated use of config parameter errorMessagePosition, use config.submitErrorMessageCallback instead");var c=b.errorMessagePosition;b.errorMessagePosition="top",b.submitErrorMessageCallback=function(){return c}}}function e(b){var c=b.find("[data-validation-if-checked]");c.length&&a.formUtils.warn('Detected use of attribute "data-validation-if-checked" which is deprecated. Use "data-validation-depends-on" provided by module "logic"'),c.on("beforeValidation",function(){var c=a(this),d=c.valAttr("if-checked"),e=a('input[name="'+d+'"]',b),f=e.is(":checked"),g=(a.formUtils.getValue(e)||"").toString(),h=c.valAttr("if-checked-value");(!f||h&&h!==g)&&c.valAttr("skipped",!0)})}function f(b){var c={se:"sv",cz:"cs",dk:"da"};if(b.lang in c){var d=c[b.lang];a.formUtils.warn('Deprecated use of lang code "'+b.lang+'" use "'+d+'" instead'),b.lang=d}}a.fn.validateForm=function(b,c){return a.formUtils.warn("Use of deprecated function $.validateForm, use $.isValid instead"),this.isValid(b,c,!0)},a(window).on("formValidationPluginInit",function(a,b){f(b),c(b),d(b)}).on("validatorsLoaded formValidationSetup",function(b,c){c||(c=a("form")),e(c)})}(a),function(a){"use strict";var b={resolveErrorMessage:function(a,b,c,d,e){var f=d.validationErrorMsgAttribute+"-"+c.replace("validate_",""),g=a.attr(f);return g||(g=a.attr(d.validationErrorMsgAttribute),g||(g="function"!=typeof b.errorMessageKey?e[b.errorMessageKey]:e[b.errorMessageKey(d)],g||(g=b.errorMessage))),g},getParentContainer:function(b){if(b.valAttr("error-msg-container"))return a(b.valAttr("error-msg-container"));var c=b.parent();return"checkbox"===b.attr("type")&&b.closest(".checkbox").length?c=b.closest(".checkbox").parent():"radio"===b.attr("type")&&b.closest(".radio").length&&(c=b.closest(".radio").parent()),c.closest(".input-group").length&&(c=c.closest(".input-group").parent()),c},applyInputErrorStyling:function(a,b){a.addClass(b.errorElementClass).removeClass(b.successElementClass),this.getParentContainer(a).addClass(b.inputParentClassOnError).removeClass(b.inputParentClassOnSuccess),""!==b.borderColorOnError&&a.css("border-color",b.borderColorOnError)},applyInputSuccessStyling:function(a,b){a.addClass(b.successElementClass),this.getParentContainer(a).addClass(b.inputParentClassOnSuccess)},removeInputStylingAndMessage:function(a,c){a.removeClass(c.successElementClass).removeClass(c.errorElementClass).css("border-color","");var d=b.getParentContainer(a);if(d.removeClass(c.inputParentClassOnError).removeClass(c.inputParentClassOnSuccess),"function"==typeof c.inlineErrorMessageCallback){var e=c.inlineErrorMessageCallback(a,!1,c);e&&e.html("")}else d.find("."+c.errorMessageClass).remove()},removeAllMessagesAndStyling:function(c,d){if("function"==typeof d.submitErrorMessageCallback){var e=d.submitErrorMessageCallback(c,!1,d);e&&e.html("")}else c.find("."+d.errorMessageClass+".alert").remove();c.find("."+d.errorElementClass+",."+d.successElementClass).each(function(){b.removeInputStylingAndMessage(a(this),d)})},setInlineMessage:function(b,c,d){this.applyInputErrorStyling(b,d);var e,f=document.getElementById(b.attr("name")+"_err_msg"),g=!1,h=function(d){a.formUtils.$win.trigger("validationErrorDisplay",[b,d]),d.html(c)},i=function(){var f=!1;g.find("."+d.errorMessageClass).each(function(){if(this.inputReferer===b[0])return f=a(this),!1}),f?c?h(f):f.remove():""!==c&&(e=a('<div class="'+d.errorMessageClass+' alert"></div>'),h(e),e[0].inputReferer=b[0],g.prepend(e))};if(f)a.formUtils.warn("Using deprecated element reference "+f.id),g=a(f),i();else if("function"==typeof d.inlineErrorMessageCallback){if(g=d.inlineErrorMessageCallback(b,c,d),!g)return;i()}else{var j=this.getParentContainer(b);e=j.find("."+d.errorMessageClass+".help-block"),0===e.length&&(e=a("<span></span>").addClass("help-block").addClass(d.errorMessageClass),e.appendTo(j)),h(e)}},setMessageInTopOfForm:function(b,c,d,e){var f='<div class="{errorMessageClass} alert alert-danger"><strong>{errorTitle}</strong><ul>{fields}</ul></div>',g=!1;if("function"!=typeof d.submitErrorMessageCallback||(g=d.submitErrorMessageCallback(b,c,d))){var h={errorTitle:e.errorTitle,fields:"",errorMessageClass:d.errorMessageClass};a.each(c,function(a,b){h.fields+="<li>"+b+"</li>"}),a.each(h,function(a,b){f=f.replace("{"+a+"}",b)}),g?g.html(f):b.children().eq(0).before(a(f))}}};a.formUtils=a.extend(a.formUtils||{},{dialogs:b})}(a),function(a,b,c){"use strict";var d=0;a.fn.validateOnBlur=function(b,c){var d=this,e=this.find("*[data-validation]");return e.each(function(){var e=a(this);if(e.is("[type=radio]")){var f=d.find('[type=radio][name="'+e.attr("name")+'"]');f.bind("blur.validation",function(){e.validateInputOnBlur(b,c,!0,"blur")}),c.validateCheckboxRadioOnClick&&f.bind("click.validation",function(){e.validateInputOnBlur(b,c,!0,"click")})}}),e.bind("blur.validation",function(){a(this).validateInputOnBlur(b,c,!0,"blur")}),c.validateCheckboxRadioOnClick&&this.find("input[type=checkbox][data-validation],input[type=radio][data-validation]").bind("click.validation",function(){a(this).validateInputOnBlur(b,c,!0,"click")}),this},a.fn.validateOnEvent=function(b,c){if(0!==this.length){var d="FORM"===this[0].nodeName?this.find("*[data-validation-event]"):this;return d.each(function(){var d=a(this),e=d.valAttr("event");e&&d.unbind(e+".validation").bind(e+".validation",function(d){9!==(d||{}).keyCode&&a(this).validateInputOnBlur(b,c,!0,e)})}),this}},a.fn.showHelpOnFocus=function(b){return b||(b="data-validation-help"),this.find("textarea,input").each(function(){var c=a(this),e="jquery_form_help_"+ ++d,f=c.attr(b);c.removeClass("has-help-text").unbind("focus.help").unbind("blur.help"),f&&c.addClass("has-help-txt").bind("focus.help",function(){var b=c.parent().find("."+e);0===b.length&&(b=a("<span />").addClass(e).addClass("help").addClass("help-block").text(f).hide(),c.after(b)),b.fadeIn()}).bind("blur.help",function(){a(this).parent().find("."+e).fadeOut("slow")})}),this},a.fn.validate=function(b,c,d){var e=a.extend({},a.formUtils.LANG,d||{});this.each(function(){var d=a(this),f=d.closest("form").get(0)||{},g=f.validationConfig||a.formUtils.defaultConfig();d.one("validation",function(a,c){"function"==typeof b&&b(c,this,a)}),d.validateInputOnBlur(e,a.extend({},g,c||{}),!0)})},a.fn.willPostponeValidation=function(){return(this.valAttr("suggestion-nr")||this.valAttr("postpone")||this.hasClass("hasDatepicker"))&&!b.postponedValidation},a.fn.validateInputOnBlur=function(c,d,e,f){if(a.formUtils.eventType=f,this.willPostponeValidation()){var g=this,h=this.valAttr("postpone")||200;return b.postponedValidation=function(){g.validateInputOnBlur(c,d,e,f),b.postponedValidation=!1},setTimeout(function(){b.postponedValidation&&b.postponedValidation()},h),this}c=a.extend({},a.formUtils.LANG,c||{}),a.formUtils.dialogs.removeInputStylingAndMessage(this,d);var i=this,j=i.closest("form"),k=a.formUtils.validateInput(i,c,d,j,f),l=function(){i.validateInputOnBlur(c,d,!1,"blur.revalidated")};return"blur"===f&&i.unbind("validation.revalidate",l).one("validation.revalidate",l),e&&i.removeKeyUpValidation(),k.shouldChangeDisplay&&(k.isValid?a.formUtils.dialogs.applyInputSuccessStyling(i,d):a.formUtils.dialogs.setInlineMessage(i,k.errorMsg,d)),!k.isValid&&e&&i.validateOnKeyUp(c,d),this},a.fn.validateOnKeyUp=function(b,c){return this.each(function(){var d=a(this);d.valAttr("has-keyup-event")||d.valAttr("has-keyup-event","true").bind("keyup.validation",function(a){9!==a.keyCode&&d.validateInputOnBlur(b,c,!1,"keyup")})}),this},a.fn.removeKeyUpValidation=function(){return this.each(function(){a(this).valAttr("has-keyup-event",!1).unbind("keyup.validation")}),this},a.fn.valAttr=function(a,b){return b===c?this.attr("data-validation-"+a):b===!1||null===b?this.removeAttr("data-validation-"+a):(a=a.length>0?"-"+a:"",this.attr("data-validation"+a,b))},a.fn.isValid=function(b,c,d){if(a.formUtils.isLoadingModules){var e=this;return setTimeout(function(){e.isValid(b,c,d)},200),null}c=a.extend({},a.formUtils.defaultConfig(),c||{}),b=a.extend({},a.formUtils.LANG,b||{}),d=d!==!1,a.formUtils.errorDisplayPreventedWhenHalted&&(delete a.formUtils.errorDisplayPreventedWhenHalted,d=!1);var f=function(b,e){a.inArray(b,h)<0&&h.push(b),i.push(e),e.valAttr("current-error",b),d&&a.formUtils.dialogs.applyInputErrorStyling(e,c)},g=[],h=[],i=[],j=this,k=function(b,d){return"submit"===d||"button"===d||"reset"===d||a.inArray(b,c.ignore||[])>-1};if(d&&a.formUtils.dialogs.removeAllMessagesAndStyling(j,c),j.find("input,textarea,select").filter(':not([type="submit"],[type="button"])').each(function(){var d=a(this),e=d.attr("type"),h="radio"===e||"checkbox"===e,i=d.attr("name");if(!k(i,e)&&(!h||a.inArray(i,g)<0)){h&&g.push(i);var l=a.formUtils.validateInput(d,b,c,j,"submit");l.isValid?l.isValid&&l.shouldChangeDisplay&&(d.valAttr("current-error",!1),a.formUtils.dialogs.applyInputSuccessStyling(d,c)):f(l.errorMsg,d)}}),"function"==typeof c.onValidate){var l=c.onValidate(j);a.isArray(l)?a.each(l,function(a,b){f(b.message,b.element)}):l&&l.element&&l.message&&f(l.message,l.element)}return a.formUtils.isValidatingEntireForm=!1,i.length>0&&d&&("top"===c.errorMessagePosition?a.formUtils.dialogs.setMessageInTopOfForm(j,h,c,b):a.each(i,function(b,d){a.formUtils.dialogs.setInlineMessage(d,d.valAttr("current-error"),c)}),c.scrollToTopOnError&&a.formUtils.$win.scrollTop(j.offset().top-20)),!d&&a.formUtils.haltValidation&&(a.formUtils.errorDisplayPreventedWhenHalted=!0),0===i.length&&!a.formUtils.haltValidation},a.fn.restrictLength=function(b){return new a.formUtils.lengthRestriction(this,b),this},a.fn.addSuggestions=function(b){var c=!1;return this.find("input").each(function(){var d=a(this);c=a.split(d.attr("data-suggestions")),c.length>0&&!d.hasClass("has-suggestions")&&(a.formUtils.suggest(d,c,b),d.addClass("has-suggestions"))}),this}}(a,window),function(a){"use strict";a.formUtils=a.extend(a.formUtils||{},{isLoadingModules:!1,loadedModules:{},registerLoadedModule:function(b){this.loadedModules[a.trim(b).toLowerCase()]=!0},hasLoadedModule:function(b){return a.trim(b).toLowerCase()in this.loadedModules},loadModules:function(b,c,d){if(a.formUtils.isLoadingModules)return void setTimeout(function(){a.formUtils.loadModules(b,c,d)},100);var e=function(b,c){var e=a.split(b),f=e.length,g=function(){f--,0===f&&(a.formUtils.isLoadingModules=!1,"function"==typeof d&&d())};f>0&&(a.formUtils.isLoadingModules=!0);var h="?_="+(new Date).getTime(),i=document.getElementsByTagName("head")[0]||document.getElementsByTagName("body")[0];a.each(e,function(b,d){if(d=a.trim(d),0===d.length||a.formUtils.hasLoadedModule(d))g();else{var e=c+d+(".js"===d.slice(-3)?"":".js"),f=document.createElement("SCRIPT");"function"==typeof define&&define.amd?require([e+(".dev.js"===e.slice(-7)?h:"")],g):(f.type="text/javascript",f.onload=g,f.src=e+(".dev.js"===e.slice(-7)?h:""),f.onerror=function(){a.formUtils.warn("Unable to load form validation module "+e,!0),g()},f.onreadystatechange=function(){"complete"!==this.readyState&&"loaded"!==this.readyState||(g(),this.onload=null,this.onreadystatechange=null)},i.appendChild(f))}})};if(c)e(b,c);else{var f=function(){var c=!1;return a('script[src*="form-validator"]').each(function(){var a=this.src.split("form-validator")[1].split("node_modules").length>1;if(!a)return c=this.src.substr(0,this.src.lastIndexOf("/"))+"/","/"===c&&(c=""),!1}),c!==!1&&(e(b,c),!0)};f()||a(function(){var a=f();a||"function"==typeof d&&d()})}}})}(a),function(a){"use strict";a.split=function(b,c,d){d=void 0===d||d===!0;var e="[,|"+(d?"\\s":"")+"-]\\s*",f=new RegExp(e,"g");if("function"!=typeof c){if(!b)return[];var g=[];return a.each(b.split(c?c:f),function(b,c){c=a.trim(c),c.length&&g.push(c)}),g}b&&a.each(b.split(f),function(b,d){if(d=a.trim(d),d.length)return c(d,b)})},a.validate=function(b){var c=a.extend(a.formUtils.defaultConfig(),{form:"form",validateOnEvent:!1,validateOnBlur:!0,validateCheckboxRadioOnClick:!0,showHelpOnFocus:!0,addSuggestions:!0,modules:"",onModulesLoaded:null,language:!1,onSuccess:!1,onError:!1,onElementValidate:!1});if(b=a.extend(c,b||{}),a(window).trigger("formValidationPluginInit",[b]),b.lang&&"en"!==b.lang){var d="lang/"+b.lang+".js";b.modules+=b.modules.length?","+d:d}a(b.form).each(function(c,d){d.validationConfig=b;var e=a(d);e.trigger("formValidationSetup",[e,b]),e.find(".has-help-txt").unbind("focus.validation").unbind("blur.validation"),e.removeClass("has-validation-callback").unbind("submit.validation").unbind("reset.validation").find("input[data-validation],textarea[data-validation]").unbind("blur.validation"),e.bind("submit.validation",function(c){var d=a(this),e=function(){return c.stopImmediatePropagation(),!1};if(a.formUtils.haltValidation)return e();if(a.formUtils.isLoadingModules)return setTimeout(function(){d.trigger("submit.validation")},200),e();var f=d.isValid(b.language,b);if(a.formUtils.haltValidation)return e();if(!f||"function"!=typeof b.onSuccess)return f||"function"!=typeof b.onError?!!f||e():(b.onError(d),e());var g=b.onSuccess(d);return g===!1?e():void 0}).bind("reset.validation",function(){a.formUtils.dialogs.removeAllMessagesAndStyling(e,b)}).addClass("has-validation-callback"),b.showHelpOnFocus&&e.showHelpOnFocus(),b.addSuggestions&&e.addSuggestions(),b.validateOnBlur&&(e.validateOnBlur(b.language,b),e.bind("html5ValidationAttrsFound",function(){e.validateOnBlur(b.language,b)})),b.validateOnEvent&&e.validateOnEvent(b.language,b)}),""!==b.modules&&a.formUtils.loadModules(b.modules,null,function(){"function"==typeof b.onModulesLoaded&&b.onModulesLoaded();var c="string"==typeof b.form?a(b.form):b.form;a.formUtils.$win.trigger("validatorsLoaded",[c,b])})}}(a),function(a,b){"use strict";var c=a(b);a.formUtils=a.extend(a.formUtils||{},{$win:c,defaultConfig:function(){return{ignore:[],errorElementClass:"error",successElementClass:"valid",borderColorOnError:"#b94a48",errorMessageClass:"form-error",validationRuleAttribute:"data-validation",validationErrorMsgAttribute:"data-validation-error-msg",errorMessagePosition:"inline",errorMessageTemplate:{container:'<div class="{errorMessageClass} alert alert-danger">{messages}</div>',messages:"<strong>{errorTitle}</strong><ul>{fields}</ul>",field:"<li>{msg}</li>"},scrollToTopOnError:!0,dateFormat:"yyyy-mm-dd",addValidClassOnAll:!1,decimalSeparator:".",inputParentClassOnError:"has-error",inputParentClassOnSuccess:"has-success",validateHiddenInputs:!1,inlineErrorMessageCallback:!1,submitErrorMessageCallback:!1}},validators:{},sanitizers:{},_events:{load:[],valid:[],invalid:[]},haltValidation:!1,addValidator:function(a){var b=0===a.name.indexOf("validate_")?a.name:"validate_"+a.name;void 0===a.validateOnKeyUp&&(a.validateOnKeyUp=!0),this.validators[b]=a},addSanitizer:function(a){this.sanitizers[a.name]=a},warn:function(a,c){"console"in b?"function"==typeof b.console.warn?b.console.warn(a):"function"==typeof b.console.log&&b.console.log(a):c&&alert(a)},getValue:function(a,b){var c=b?b.find(a):a;if(c.length>0){var d=c.eq(0).attr("type");return"radio"===d||"checkbox"===d?c.filter(":checked").val()||"":c.val()||""}return!1},validateInput:function(b,c,d,e,f){d=d||a.formUtils.defaultConfig(),c=c||a.formUtils.LANG,e.length||(e=b.parent());var g=this.getValue(b);b.valAttr("skipped",!1).one("beforeValidation",function(){(b.attr("disabled")||!b.is(":visible")&&!d.validateHiddenInputs)&&b.valAttr("skipped",1)}).trigger("beforeValidation",[g,c,d]);var h="true"===b.valAttr("optional"),i=!g&&h,j=b.attr(d.validationRuleAttribute),k=!0,l="",m={isValid:!0,shouldChangeDisplay:!0,errorMsg:""};if(!j||i||b.valAttr("skipped"))return m.shouldChangeDisplay=d.addValidClassOnAll,m;var n=b.valAttr("ignore");return n&&a.each(n.split(""),function(a,b){g=g.replace(new RegExp("\\"+b,"g"),"")}),a.split(j,function(h){0!==h.indexOf("validate_")&&(h="validate_"+h);var i=a.formUtils.validators[h];if(!i)throw new Error('Using undefined validator "'+h+'". Maybe you have forgotten to load the module that "'+h+'" belongs to?');if("validate_checkbox_group"===h&&(b=e.find('[name="'+b.attr("name")+'"]:eq(0)')),("keyup"!==f||i.validateOnKeyUp)&&(k=i.validatorFunction(g,b,d,c,e,f)),!k)return d.validateOnBlur&&b.validateOnKeyUp(c,d),l=a.formUtils.dialogs.resolveErrorMessage(b,i,h,d,c),!1}),k===!1?(b.trigger("validation",!1),m.errorMsg=l,m.isValid=!1,m.shouldChangeDisplay=!0):null===k?m.shouldChangeDisplay=!1:(b.trigger("validation",!0),m.shouldChangeDisplay=!0),"function"==typeof d.onElementValidate&&null!==l&&d.onElementValidate(m.isValid,b,e,l),b.trigger("afterValidation",[m,f]),m},parseDate:function(b,c,d){var e,f,g,h,i=c.replace(/[a-zA-Z]/gi,"").substring(0,1),j="^",k=c.split(i||null);if(a.each(k,function(a,b){j+=(a>0?"\\"+i:"")+"(\\d{"+b.length+"})"}),j+="$",d){var l=[];a.each(b.split(i),function(a,b){1===b.length&&(b="0"+b),l.push(b)}),b=l.join(i)}if(e=b.match(new RegExp(j)),null===e)return!1;var m=function(b,c,d){for(var e=0;e<c.length;e++)if(c[e].substring(0,1)===b)return a.formUtils.parseDateInt(d[e+1]);return-1};return g=m("m",k,e),f=m("d",k,e),h=m("y",k,e),!(2===g&&f>28&&(h%4!==0||h%100===0&&h%400!==0)||2===g&&f>29&&(h%4===0||h%100!==0&&h%400===0)||g>12||0===g)&&(!(this.isShortMonth(g)&&f>30||!this.isShortMonth(g)&&f>31||0===f)&&[h,g,f])},parseDateInt:function(a){return 0===a.indexOf("0")&&(a=a.replace("0","")),parseInt(a,10)},isShortMonth:function(a){return a%2===0&&a<7||a%2!==0&&a>7},lengthRestriction:function(b,c){var d=parseInt(c.text(),10),e=0,f=function(){var a=b.val().length;if(a>d){var f=b.scrollTop();b.val(b.val().substring(0,d)),b.scrollTop(f)}e=d-a,e<0&&(e=0),c.text(e)};a(b).bind("keydown keyup keypress focus blur",f).bind("cut paste",function(){setTimeout(f,100)}),a(document).bind("ready",f)},numericRangeCheck:function(b,c){var d=a.split(c),e=parseInt(c.substr(3),10);return 1===d.length&&c.indexOf("min")===-1&&c.indexOf("max")===-1&&(d=[c,c]),2===d.length&&(b<parseInt(d[0],10)||b>parseInt(d[1],10))?["out",d[0],d[1]]:0===c.indexOf("min")&&b<e?["min",e]:0===c.indexOf("max")&&b>e?["max",e]:["ok"]},_numSuggestionElements:0,_selectedSuggestion:null,_previousTypedVal:null,suggest:function(b,d,e){var f={css:{maxHeight:"150px",background:"#FFF",lineHeight:"150%",textDecoration:"underline",overflowX:"hidden",overflowY:"auto",border:"#CCC solid 1px",borderTop:"none",cursor:"pointer"},activeSuggestionCSS:{background:"#E9E9E9"}},g=function(a,b){var c=b.offset();a.css({width:b.outerWidth(),left:c.left+"px",top:c.top+b.outerHeight()+"px"})};e&&a.extend(f,e),f.css.position="absolute",f.css["z-index"]=9999,b.attr("autocomplete","off"),0===this._numSuggestionElements&&c.bind("resize",function(){a(".jquery-form-suggestions").each(function(){var b=a(this),c=b.attr("data-suggest-container");g(b,a(".suggestions-"+c).eq(0))})}),this._numSuggestionElements++;var h=function(b){var c=b.valAttr("suggestion-nr");a.formUtils._selectedSuggestion=null,a.formUtils._previousTypedVal=null,a(".jquery-form-suggestion-"+c).fadeOut("fast")};return b.data("suggestions",d).valAttr("suggestion-nr",this._numSuggestionElements).unbind("focus.suggest").bind("focus.suggest",function(){a(this).trigger("keyup"),a.formUtils._selectedSuggestion=null}).unbind("keyup.suggest").bind("keyup.suggest",function(){var c=a(this),d=[],e=a.trim(c.val()).toLocaleLowerCase();if(e!==a.formUtils._previousTypedVal){a.formUtils._previousTypedVal=e;var i=!1,j=c.valAttr("suggestion-nr"),k=a(".jquery-form-suggestion-"+j);if(k.scrollTop(0),""!==e){var l=e.length>2;a.each(c.data("suggestions"),function(a,b){var c=b.toLocaleLowerCase();return c===e?(d.push("<strong>"+b+"</strong>"),i=!0,!1):void((0===c.indexOf(e)||l&&c.indexOf(e)>-1)&&d.push(b.replace(new RegExp(e,"gi"),"<strong>$&</strong>")))})}i||0===d.length&&k.length>0?k.hide():d.length>0&&0===k.length?(k=a("<div></div>").css(f.css).appendTo("body"),b.addClass("suggestions-"+j),k.attr("data-suggest-container",j).addClass("jquery-form-suggestions").addClass("jquery-form-suggestion-"+j)):d.length>0&&!k.is(":visible")&&k.show(),d.length>0&&e.length!==d[0].length&&(g(k,c),k.html(""),a.each(d,function(b,d){a("<div></div>").append(d).css({overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",padding:"5px"}).addClass("form-suggest-element").appendTo(k).click(function(){c.focus(),c.val(a(this).text()),c.trigger("change"),h(c)})}))}}).unbind("keydown.validation").bind("keydown.validation",function(b){var c,d,e=b.keyCode?b.keyCode:b.which,g=a(this);if(13===e&&null!==a.formUtils._selectedSuggestion){if(c=g.valAttr("suggestion-nr"),d=a(".jquery-form-suggestion-"+c),d.length>0){var i=d.find("div").eq(a.formUtils._selectedSuggestion).text();g.val(i),g.trigger("change"),h(g),b.preventDefault()}}else{c=g.valAttr("suggestion-nr"),d=a(".jquery-form-suggestion-"+c);var j=d.children();if(j.length>0&&a.inArray(e,[38,40])>-1){38===e?(null===a.formUtils._selectedSuggestion?a.formUtils._selectedSuggestion=j.length-1:a.formUtils._selectedSuggestion--,a.formUtils._selectedSuggestion<0&&(a.formUtils._selectedSuggestion=j.length-1)):40===e&&(null===a.formUtils._selectedSuggestion?a.formUtils._selectedSuggestion=0:a.formUtils._selectedSuggestion++,a.formUtils._selectedSuggestion>j.length-1&&(a.formUtils._selectedSuggestion=0));var k=d.innerHeight(),l=d.scrollTop(),m=d.children().eq(0).outerHeight(),n=m*a.formUtils._selectedSuggestion;return(n<l||n>l+k)&&d.scrollTop(n),j.removeClass("active-suggestion").css("background","none").eq(a.formUtils._selectedSuggestion).addClass("active-suggestion").css(f.activeSuggestionCSS),b.preventDefault(),!1}}}).unbind("blur.suggest").bind("blur.suggest",function(){h(a(this))}),b},LANG:{errorTitle:"Form submission failed!",requiredField:"This is a required field",requiredFields:"You have not answered all required fields",badTime:"You have not given a correct time",badEmail:"You have not given a correct e-mail address",badTelephone:"You have not given a correct phone number",badSecurityAnswer:"You have not given a correct answer to the security question",badDate:"You have not given a correct date",lengthBadStart:"The input value must be between ",lengthBadEnd:" characters",lengthTooLongStart:"The input value is longer than ",lengthTooShortStart:"The input value is shorter than ",notConfirmed:"Input values could not be confirmed",badDomain:"Incorrect domain value",badUrl:"The input value is not a correct URL",badCustomVal:"The input value is incorrect",andSpaces:" and spaces ",badInt:"The input value was not a correct number",badSecurityNumber:"Your social security number was incorrect",badUKVatAnswer:"Incorrect UK VAT Number",badUKNin:"Incorrect UK NIN",badUKUtr:"Incorrect UK UTR Number",badStrength:"The password isn't strong enough",badNumberOfSelectedOptionsStart:"You have to choose at least ",badNumberOfSelectedOptionsEnd:" answers",badAlphaNumeric:"The input value can only contain alphanumeric characters ",badAlphaNumericExtra:" and ",wrongFileSize:"The file you are trying to upload is too large (max %s)",wrongFileType:"Only files of type %s is allowed",groupCheckedRangeStart:"Please choose between ",groupCheckedTooFewStart:"Please choose at least ",groupCheckedTooManyStart:"Please choose a maximum of ",groupCheckedEnd:" item(s)",badCreditCard:"The credit card number is not correct",badCVV:"The CVV number was not correct",wrongFileDim:"Incorrect image dimensions,",imageTooTall:"the image can not be taller than",imageTooWide:"the image can not be wider than",imageTooSmall:"the image was too small",min:"min",max:"max",imageRatioNotAccepted:"Image ratio is not be accepted",badBrazilTelephoneAnswer:"The phone number entered is invalid",badBrazilCEPAnswer:"The CEP entered is invalid",badBrazilCPFAnswer:"The CPF entered is invalid",badPlPesel:"The PESEL entered is invalid",badPlNip:"The NIP entered is invalid",badPlRegon:"The REGON entered is invalid",badreCaptcha:"Please confirm that you are not a bot",passwordComplexityStart:"Password must contain at least ",passwordComplexitySeparator:", ",passwordComplexityUppercaseInfo:" uppercase letter(s)",passwordComplexityLowercaseInfo:" lowercase letter(s)",passwordComplexitySpecialCharsInfo:" special character(s)",passwordComplexityNumericCharsInfo:" numeric character(s)",passwordComplexityEnd:"."}})}(a,window),function(a){a.formUtils.addValidator({name:"email",validatorFunction:function(b){var c=b.toLowerCase().split("@"),d=c[0],e=c[1];if(d&&e){if(0===d.indexOf('"')){var f=d.length;if(d=d.replace(/\"/g,""),d.length!==f-2)return!1}return a.formUtils.validators.validate_domain.validatorFunction(c[1])&&0!==d.indexOf(".")&&"."!==d.substring(d.length-1,d.length)&&d.indexOf("..")===-1&&!/[^\w\+\.\-\#\-\_\~\!\$\&\'\(\)\*\+\,\;\=\:]/.test(d)}return!1},errorMessage:"",errorMessageKey:"badEmail"}),a.formUtils.addValidator({name:"domain",validatorFunction:function(a){return a.length>0&&a.length<=253&&!/[^a-zA-Z0-9]/.test(a.slice(-2))&&!/[^a-zA-Z0-9]/.test(a.substr(0,1))&&!/[^a-zA-Z0-9\.\-]/.test(a)&&1===a.split("..").length&&a.split(".").length>1},errorMessage:"",errorMessageKey:"badDomain"}),a.formUtils.addValidator({name:"required",validatorFunction:function(b,c,d,e,f){switch(c.attr("type")){case"checkbox":return c.is(":checked");case"radio":return f.find('input[name="'+c.attr("name")+'"]').filter(":checked").length>0;default:return""!==a.trim(b)}},errorMessage:"",errorMessageKey:function(a){return"top"===a.errorMessagePosition||"function"==typeof a.errorMessagePosition?"requiredFields":"requiredField"}}),a.formUtils.addValidator({name:"length",validatorFunction:function(b,c,d,e){var f=c.valAttr("length"),g=c.attr("type");if(void 0===f)return alert('Please add attribute "data-validation-length" to '+c[0].nodeName+" named "+c.attr("name")),!0;var h,i="file"===g&&void 0!==c.get(0).files?c.get(0).files.length:b.length,j=a.formUtils.numericRangeCheck(i,f);switch(j[0]){case"out":this.errorMessage=e.lengthBadStart+f+e.lengthBadEnd,h=!1;break;case"min":this.errorMessage=e.lengthTooShortStart+j[1]+e.lengthBadEnd,h=!1;break;case"max":this.errorMessage=e.lengthTooLongStart+j[1]+e.lengthBadEnd,h=!1;break;default:h=!0}return h},errorMessage:"",errorMessageKey:""}),a.formUtils.addValidator({name:"url",validatorFunction:function(b){var c=/^(https?|ftp):\/\/((((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|\[|\]|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;if(c.test(b)){var d=b.split("://")[1],e=d.indexOf("/");return e>-1&&(d=d.substr(0,e)),a.formUtils.validators.validate_domain.validatorFunction(d)}return!1},errorMessage:"",errorMessageKey:"badUrl"}),a.formUtils.addValidator({name:"number",validatorFunction:function(a,b,c){if(""!==a){var d,e,f=b.valAttr("allowing")||"",g=b.valAttr("decimal-separator")||c.decimalSeparator,h=!1,i=b.valAttr("step")||"",j=!1,k=b.attr("data-sanitize")||"",l=k.match(/(^|[\s])numberFormat([\s]|$)/i);if(l){if(!window.numeral)throw new ReferenceError("The data-sanitize value numberFormat cannot be used without the numeral library. Please see Data Validation in http://www.formvalidator.net for more information.");a.length&&(a=String(numeral().unformat(a)))}if(f.indexOf("number")===-1&&(f+=",number"),f.indexOf("negative")===-1&&0===a.indexOf("-"))return!1;if(f.indexOf("range")>-1&&(d=parseFloat(f.substring(f.indexOf("[")+1,f.indexOf(";"))),e=parseFloat(f.substring(f.indexOf(";")+1,f.indexOf("]"))),h=!0),""!==i&&(j=!0),","===g){if(a.indexOf(".")>-1)return!1;a=a.replace(",",".")}if(""===a.replace(/[0-9-]/g,"")&&(!h||a>=d&&a<=e)&&(!j||a%i===0))return!0;if(f.indexOf("float")>-1&&null!==a.match(new RegExp("^([0-9-]+)\\.([0-9]+)$"))&&(!h||a>=d&&a<=e)&&(!j||a%i===0))return!0}return!1},errorMessage:"",errorMessageKey:"badInt"}),a.formUtils.addValidator({name:"alphanumeric",validatorFunction:function(b,c,d,e){var f="^([a-zA-Z0-9",g="]+)$",h=c.valAttr("allowing"),i="",j=!1;if(h){i=f+h+g;var k=h.replace(/\\/g,"");k.indexOf(" ")>-1&&(j=!0,k=k.replace(" ",""),k+=e.andSpaces||a.formUtils.LANG.andSpaces),e.badAlphaNumericAndExtraAndSpaces&&e.badAlphaNumericAndExtra?j?this.errorMessage=e.badAlphaNumericAndExtraAndSpaces+k:this.errorMessage=e.badAlphaNumericAndExtra+k+e.badAlphaNumericExtra:this.errorMessage=e.badAlphaNumeric+e.badAlphaNumericExtra+k;
10
+ }else i=f+g,this.errorMessage=e.badAlphaNumeric;return new RegExp(i).test(b)},errorMessage:"",errorMessageKey:""}),a.formUtils.addValidator({name:"custom",validatorFunction:function(a,b){var c=new RegExp(b.valAttr("regexp"));return c.test(a)},errorMessage:"",errorMessageKey:"badCustomVal"}),a.formUtils.addValidator({name:"date",validatorFunction:function(b,c,d){var e=c.valAttr("format")||d.dateFormat||"yyyy-mm-dd",f="false"===c.valAttr("require-leading-zero");return a.formUtils.parseDate(b,e,f)!==!1},errorMessage:"",errorMessageKey:"badDate"}),a.formUtils.addValidator({name:"checkbox_group",validatorFunction:function(b,c,d,e,f){var g=!0,h=c.attr("name"),i=a('input[type=checkbox][name^="'+h+'"]',f),j=i.filter(":checked").length,k=c.valAttr("qty");if(void 0===k){var l=c.get(0).nodeName;alert('Attribute "data-validation-qty" is missing from '+l+" named "+c.attr("name"))}var m=a.formUtils.numericRangeCheck(j,k);switch(m[0]){case"out":this.errorMessage=e.groupCheckedRangeStart+k+e.groupCheckedEnd,g=!1;break;case"min":this.errorMessage=e.groupCheckedTooFewStart+m[1]+(e.groupCheckedTooFewEnd||e.groupCheckedEnd),g=!1;break;case"max":this.errorMessage=e.groupCheckedTooManyStart+m[1]+(e.groupCheckedTooManyEnd||e.groupCheckedEnd),g=!1;break;default:g=!0}if(!g){var n=function(){i.unbind("click",n),i.filter("*[data-validation]").validateInputOnBlur(e,d,!1,"blur")};i.bind("click",n)}return g}})}(a)});
11
+
12
+ /*
13
+ A simple jQuery modal (http://github.com/kylefox/jquery-modal)
14
+ Version 0.9.1
15
+ */
16
+ !function(o){"object"==typeof module&&"object"==typeof module.exports?o(require("jquery"),window,document):o(jQuery,window,document)}(function(o,t,i,e){var s=[],l=function(){return s.length?s[s.length-1]:null},n=function(){var o,t=!1;for(o=s.length-1;o>=0;o--)s[o].$blocker&&(s[o].$blocker.toggleClass("current",!t).toggleClass("behind",t),t=!0)};o.modal=function(t,i){var e,n;if(this.$body=o("body"),this.options=o.extend({},o.modal.defaults,i),this.options.doFade=!isNaN(parseInt(this.options.fadeDuration,10)),this.$blocker=null,this.options.closeExisting)for(;o.modal.isActive();)o.modal.close();if(s.push(this),t.is("a"))if(n=t.attr("href"),this.anchor=t,/^#/.test(n)){if(this.$elm=o(n),1!==this.$elm.length)return null;this.$body.append(this.$elm),this.open()}else this.$elm=o("<div>"),this.$body.append(this.$elm),e=function(o,t){t.elm.remove()},this.showSpinner(),t.trigger(o.modal.AJAX_SEND),o.get(n).done(function(i){if(o.modal.isActive()){t.trigger(o.modal.AJAX_SUCCESS);var s=l();s.$elm.empty().append(i).on(o.modal.CLOSE,e),s.hideSpinner(),s.open(),t.trigger(o.modal.AJAX_COMPLETE)}}).fail(function(){t.trigger(o.modal.AJAX_FAIL);var i=l();i.hideSpinner(),s.pop(),t.trigger(o.modal.AJAX_COMPLETE)});else this.$elm=t,this.anchor=t,this.$body.append(this.$elm),this.open()},o.modal.prototype={constructor:o.modal,open:function(){var t=this;this.block(),this.anchor.blur(),this.options.doFade?setTimeout(function(){t.show()},this.options.fadeDuration*this.options.fadeDelay):this.show(),o(i).off("keydown.modal").on("keydown.modal",function(o){var t=l();27===o.which&&t.options.escapeClose&&t.close()}),this.options.clickClose&&this.$blocker.click(function(t){t.target===this&&o.modal.close()})},close:function(){s.pop(),this.unblock(),this.hide(),o.modal.isActive()||o(i).off("keydown.modal")},block:function(){this.$elm.trigger(o.modal.BEFORE_BLOCK,[this._ctx()]),this.$body.css("overflow","hidden"),this.$blocker=o('<div class="'+this.options.blockerClass+' blocker current"></div>').appendTo(this.$body),n(),this.options.doFade&&this.$blocker.css("opacity",0).animate({opacity:1},this.options.fadeDuration),this.$elm.trigger(o.modal.BLOCK,[this._ctx()])},unblock:function(t){!t&&this.options.doFade?this.$blocker.fadeOut(this.options.fadeDuration,this.unblock.bind(this,!0)):(this.$blocker.children().appendTo(this.$body),this.$blocker.remove(),this.$blocker=null,n(),o.modal.isActive()||this.$body.css("overflow",""))},show:function(){this.$elm.trigger(o.modal.BEFORE_OPEN,[this._ctx()]),this.options.showClose&&(this.closeButton=o('<a href="#close-modal" rel="modal:close" class="close-modal '+this.options.closeClass+'">'+this.options.closeText+"</a>"),this.$elm.append(this.closeButton)),this.$elm.addClass(this.options.modalClass).appendTo(this.$blocker),this.options.doFade?this.$elm.css({opacity:0,display:"inline-block"}).animate({opacity:1},this.options.fadeDuration):this.$elm.css("display","inline-block"),this.$elm.trigger(o.modal.OPEN,[this._ctx()])},hide:function(){this.$elm.trigger(o.modal.BEFORE_CLOSE,[this._ctx()]),this.closeButton&&this.closeButton.remove();var t=this;this.options.doFade?this.$elm.fadeOut(this.options.fadeDuration,function(){t.$elm.trigger(o.modal.AFTER_CLOSE,[t._ctx()])}):this.$elm.hide(0,function(){t.$elm.trigger(o.modal.AFTER_CLOSE,[t._ctx()])}),this.$elm.trigger(o.modal.CLOSE,[this._ctx()])},showSpinner:function(){this.options.showSpinner&&(this.spinner=this.spinner||o('<div class="'+this.options.modalClass+'-spinner"></div>').append(this.options.spinnerHtml),this.$body.append(this.spinner),this.spinner.show())},hideSpinner:function(){this.spinner&&this.spinner.remove()},_ctx:function(){return{elm:this.$elm,$elm:this.$elm,$blocker:this.$blocker,options:this.options}}},o.modal.close=function(t){if(o.modal.isActive()){t&&t.preventDefault();var i=l();return i.close(),i.$elm}},o.modal.isActive=function(){return s.length>0},o.modal.getCurrent=l,o.modal.defaults={closeExisting:!0,escapeClose:!0,clickClose:!0,closeText:"Close",closeClass:"",modalClass:"modal",blockerClass:"jquery-modal",spinnerHtml:'<div class="rect1"></div><div class="rect2"></div><div class="rect3"></div><div class="rect4"></div>',showSpinner:!0,showClose:!0,fadeDuration:null,fadeDelay:1},o.modal.BEFORE_BLOCK="modal:before-block",o.modal.BLOCK="modal:block",o.modal.BEFORE_OPEN="modal:before-open",o.modal.OPEN="modal:open",o.modal.BEFORE_CLOSE="modal:before-close",o.modal.CLOSE="modal:close",o.modal.AFTER_CLOSE="modal:after-close",o.modal.AJAX_SEND="modal:ajax:send",o.modal.AJAX_SUCCESS="modal:ajax:success",o.modal.AJAX_FAIL="modal:ajax:fail",o.modal.AJAX_COMPLETE="modal:ajax:complete",o.fn.modal=function(t){return 1===this.length&&new o.modal(this,t),this},o(i).on("click.modal",'a[rel~="modal:close"]',o.modal.close),o(i).on("click.modal",'a[rel~="modal:open"]',function(t){t.preventDefault(),o(this).modal()})});
17
+
18
+ /**
19
+ * Created with IntelliJ IDEA.
20
+ * User: yuval
21
+ * Date: 2/25/15
22
+ * Time: 1:08 PM
23
+ * To change this template use File | Settings | File Templates.
24
+ */
25
+
26
+ jQuery(document).ready(function($){
27
+
28
+ var snippet_type = $('#snippet_type');
29
+ var anonymizeip = $('#anonymizeip');
30
+ var anonymizeip_checkbox = $('#anonymizeip')[0];
31
+ var gtm_id = $('#gtm_id');
32
+ var script_debug_mode_input = $('#script_debug_mode');
33
+
34
+ // Helpers to avoid repetition
35
+ function disable_element(el){
36
+ el.attr("disabled", true);
37
+ }
38
+
39
+ function enable_element(el){
40
+ el.removeAttr("disabled");
41
+ }
42
+
43
+ function set_checked_value(el, bool){
44
+ el.checked = bool;
45
+ }
46
+
47
+ // set up tooltips
48
+ $.widget.bridge('gaetooltip', $.ui.tooltip);
49
+
50
+ $('.ga-tooltip').gaetooltip({position: {
51
+ my: "left bottom-10",
52
+ at: "right top",
53
+ collision: "none"
54
+ }
55
+ });
56
+
57
+
58
+ $('.btn_upload').on('click', function (e){
59
+ $('.settings_content').slideDown();
60
+ e.preventDefault();
61
+ });
62
+
63
+ $('.btn_close').on('click', function (e){
64
+ $('.settings_content').slideUp();
65
+ e.preventDefault();
66
+ });
67
+
68
+ $('.popup').on('click', function (e){
69
+ $('.popup').slideUp();
70
+ e.preventDefault();
71
+ });
72
+
73
+
74
+ /*
75
+ * The following section deals with the snippet type options in the admin UI
76
+ */
77
+
78
+ // If page loads and snippet type is 'none' or 'gtm', disable anonymize IP checkbox
79
+ if (snippet_type.val()=== 'none' || snippet_type.val()=== 'gtm'){
80
+ set_checked_value(anonymizeip_checkbox, false);
81
+ disable_element(anonymizeip);
82
+ }
83
+
84
+ // If page loads and snippet_type is 'gtm', enable gtm_id
85
+ if (snippet_type.val()=== 'gtm'){
86
+ enable_element(gtm_id);
87
+ } else {
88
+ disable_element(gtm_id);
89
+ }
90
+
91
+ // When the snippet type option is changed
92
+ snippet_type.change(function (){
93
+ // Store current value
94
+ var val = $(this).val();
95
+
96
+ // If 'none' is selected, disable anonymize zip checkbox and ?
97
+ if (val === 'none' || val === 'gtm'){
98
+ set_checked_value(anonymizeip_checkbox, false);
99
+ disable_element(anonymizeip);
100
+ } else {
101
+ enable_element(anonymizeip);
102
+ }
103
+
104
+ // If gtm snippet is selected
105
+ if (val === 'gtm'){
106
+ enable_element(gtm_id);
107
+ } else {
108
+ disable_element(gtm_id);
109
+ }
110
+ });
111
+
112
+ // Snippet section ends
113
+
114
+ // The following section deals with the import settings functinality in
115
+ // general settings
116
+ $('.btn_upload').on('click', function (e){
117
+ $('.settings_content').slideDown();
118
+ e.preventDefault();
119
+ });
120
+
121
+ $('.btn_close').on('click', function (e){
122
+ $('.settings_content').slideUp();
123
+ e.preventDefault();
124
+ });
125
+
126
+ $('.popup').on('click', function (e){
127
+ $('.popup').slideUp();
128
+ e.preventDefault();
129
+ });
130
+
131
+ // import section ends
132
+
133
+ // Disable checkbox for admin options management permission
134
+ $('input[name="ga_events_options[permitted_roles][]"][value="administrator"]').css({'pointer-events': 'none',
135
+ 'opacity': 0.5}).prop('checked', true);
136
+
137
+ $('.divs-istracktime:checkbox').change(function (){
138
+ var checkbox = $(this);
139
+ var checked = checkbox.is(':checked');
140
+ var index = checkbox.data('track');
141
+ var trackValue = "#track-elem" + index;
142
+ var eventValue = "#eventValue" + index;
143
+ if (checked){
144
+ $(trackValue).show();
145
+ $(eventValue).attr("disabled", true);
146
+ } else {
147
+ $(trackValue).hide();
148
+ $(eventValue).removeAttr("disabled");
149
+ }
150
+
151
+ });
152
+
153
+ $('#empty-istracktime:checkbox').change(function (){
154
+ var checkbox = $(this);
155
+ var checked = checkbox.is(':checked');
156
+ var trackValue = "#empty-trackelem";
157
+ var eventValue = "#empty-eventValue";
158
+ if (checked){
159
+ $(trackValue).show();
160
+ $(eventValue).attr("disabled", true);
161
+ } else {
162
+ $(trackValue).hide();
163
+ $(eventValue).removeAttr("disabled");
164
+ }
165
+
166
+ });
167
+
168
+ $('.divs-istracktime').trigger('change');
169
+
170
+ function isUrlValid(url){
171
+ return /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(url);
172
+ }
173
+
174
+
175
+ jQuery('body').on('click','a[href="admin.php?page=wp-google-analytics-events-upgrade"]', function (e) {
176
+ e.preventDefault();
177
+ window.open('https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=nav', '_blank');
178
+ });
179
+ });
180
+
181
+ /*global
182
+ $, wpflow_ajax, jslint, alert
183
+ */
184
+ var gaeAjax = ( function ( $ ) {
185
+
186
+ $(document).ready( function ( $ ) {
187
+
188
+ // Handle twitter bootstrap modals
189
+ if (typeof $.fn.modal.noConflict !== "undefined") {
190
+ var bootstrapModal = $.fn.modal.noConflict();
191
+ }
192
+
193
+ // Form Submit
194
+ $.validate();
195
+ $(".wpgae-event-form").on('submit', submitEventForm);
196
+ // Populate and Show the edit event modal
197
+ $(".ga_main .edit a").click(openAndPoplulateEventModal);
198
+ // Populate and Show the Delete event modal
199
+ $(".ga_main .delete a").click(openAndPoplulateEventModal);
200
+ });
201
+
202
+
203
+ function openAndPoplulateEventModal(e) {
204
+ e.preventDefault();
205
+ var id_post = $(this).attr('id');
206
+ var modalId = "#" + $(this).data("action");
207
+ $.ajax({
208
+ type: 'POST',
209
+ url: wpflow_ajax.ajax_url,
210
+ data: {
211
+ 'post_id': id_post,
212
+ 'action': 'wpflow_get_event_json'
213
+ },
214
+ success: function (result) {
215
+ $(modalId).modal();
216
+ populateMetaEditForm(modalId, result.meta);
217
+ $(modalId + " #event_id").val(id_post);
218
+ },
219
+ error: function () {
220
+ alert("Error updating event");
221
+ }
222
+ });
223
+ }
224
+
225
+ function submitEventForm(e) {
226
+ e.preventDefault();
227
+ var form = $(this);
228
+
229
+ $.ajax({
230
+ type: "post",
231
+ url: wpflow_ajax.ajax_url,
232
+ data: form.serialize(),
233
+ success: function (data) {
234
+ window.location.reload();
235
+ }
236
+ });
237
+ }
238
+
239
+ function populateMetaEditForm(modal, meta) {
240
+ if (typeof meta !== "undefined") {
241
+ for (var input in meta) {
242
+ if (meta.hasOwnProperty(input)) {
243
+ if ($(modal + " #" + input).is(":checkbox")) {
244
+ if (meta[input][0] === "true") {
245
+ $(modal + " #" + input).attr("checked", true);
246
+ } else {
247
+ $(modal + " #" + input).removeAttr("checked", false);
248
+ }
249
+ } else {
250
+ $(modal + " #" + input).val(meta[input][0]);
251
+ }
252
+ }
253
+ }
254
+ }
255
+ }
256
+ } )( jQuery );
257
+
258
+
259
+
260
+
261
+
262
+
263
+
js/dist/frontend-scripts-min.js ADDED
@@ -0,0 +1 @@
 
1
+ var gaeMapper=function(){if("undefined"!=typeof ga_options){function e(e){var t="";return"class"===e.type?t+=".":"id"===e.type&&(t+="#"),t+=e.name}for(var t=[],a=ga_options.click_elements,n=0;n<a.length;n++){var o=a[n];newClickElement={},newClickElement.data={select:e(o),category:o.category,action:o.action,label:o.label,bounce:parseInt(o.non_interaction),evalue:o.value,link_click_delay:parseInt(ga_options.link_clicks_delay),universal:parseInt(ga_options.universal)},newClickElement.selector=newClickElement.data.select,t.push(newClickElement)}var r=[];return ga_options.scroll_elements.forEach(function(t){r.push({select:e(t),category:t.category,action:t.action,label:t.label,bounce:parseInt(t.non_interaction),evalue:t.value})}),{clickElementsFromDB:t,scrollElementsFromDB:r,advancedMode:ga_options.advanced,link_clicks_delay:ga_options.link_clicks_delay,snippet_type:ga_options.snippet_type,scriptDebugMode:ga_options.script_debug_mode}}}();gaEventsMain=function(e){"use strict";var t;function a(){for(var t=e(window).height(),a=e(document).scrollTop(),o=0;o<gaeMapper.scrollElementsFromDB.length;o++)if(!gaeMapper.scrollElementsFromDB[o].sent){var r=e(gaeMapper.scrollElementsFromDB[o].select);gaeMapper.scrollElementsFromDB[o].offset=r.offset(),gaeMapper.scrollElementsFromDB[o].offset&&a+t>=gaeMapper.scrollElementsFromDB[o].offset.top+r.height()&&(n(gaeMapper.scrollElementsFromDB[o].category,gaeMapper.scrollElementsFromDB[o].action,gaeMapper.scrollElementsFromDB[o].label,gaeMapper.scrollElementsFromDB[o].bounce,gaeMapper.scrollElementsFromDB[o].evalue),gaeMapper.scrollElementsFromDB[o].sent=!0)}}e(document).ready(function(){gaeMapper.clickElementsFromDB.forEach(function(t){e("body").on("click",t.selector,t.data,o)}),e(window).on("scroll",a)});var n=function(e,a,n,o,r){if(void 0===t)if("undefined"!=typeof ga)t=ga;else if("undefined"!=typeof _gaq)t=_gaq;else if("function"==typeof __gaTracker)t=__gaTracker;else if("function"==typeof gaplusu)t=gaplusu;else if("gtm"!==gaeMapper.snippet_type&&"undefined"==typeof dataLayer)return;e=e||"uncategorized",a=a||"",n=n||"";var l=r||"",i=o||!1;"gtm"==gaeMapper.snippet_type||"undefined"!=typeof dataLayer&&"undefined"==typeof gtag?dataLayer.push({event:"WPGAE",eventCategory:e,eventAction:a,eventLabel:n,eventValue:l,nonInteraction:i}):"gst"==gaeMapper.snippet_type||"undefined"!=typeof gtag?gtag("event",a,{event_category:e,event_label:n,value:l,non_interaction:i}):"universal"==gaeMapper.snippet_type||"undefined"!=typeof ga||"function"==typeof __gaTracker?l?t("send","event",e,a,n,l,{nonInteraction:i}):t("send","event",e,a,n,{nonInteraction:i}):"legacy"!=gaeMapper.snippet_type&&"undefined"==typeof _gaq||t.push(["_trackEvent",e,a,n,l,i])},o=function(e){if(n(e.data.category,e.data.action,e.data.label,e.data.bounce,e.data.evalue,this),void 0!==e.data.link_click_delay&&e.data.link_click_delay>0&&void 0!==e.target.href&&"A"==e.target.nodeName){e.preventDefault();var t,a=!1;e.target.target&&"_blank"===e.target.target.trim()&&(a=!0),a&&(t=window.open("","_blank"));var o=r(e);void 0!==o&&""!==o?window.location.hash=o:setTimeout(function(){a?t.location.href=e.target.href:window.location=e.target.href},parseInt(gaeMapper.link_clicks_delay))}},r=function(t){var a="";return 0===(a="A"!==t.target.tagName?e(t.target).parents("a").attr("href"):e(t.target).attr("href")).indexOf("#")?a:""}}(jQuery);
js/dist/frontend-scripts.js ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Main GA Events Plugin function
3
+ *
4
+ * TO DO: all variables with gaeMapper. prefix can be declared at top of function
5
+ * and have prefix removed thereafter. Although for now it could be helpful to
6
+ * keep prefix to make it obvious which values need to eventually be accessed
7
+ * directly from localized values.
8
+ *
9
+ * Exposes track_event, click_event
10
+ *
11
+ * Global: TO DO
12
+ */
13
+ var gaeMapper = (function () {
14
+
15
+ // Make sure options are present globally
16
+ if (typeof ga_options !== "undefined") {
17
+
18
+ /*
19
+ * We temporarily need to be able to create a selector of type id or class
20
+ * from the existing DB options.
21
+ *
22
+ * Eventually we will probably update the backend to store the selector as an
23
+ * option within the associative "click" (or otherwise named) array
24
+ *
25
+ * @param {sequential array}
26
+ */
27
+ function makeSelector(click_option) {
28
+ var selector = "";
29
+ if (click_option.type === 'class') {
30
+ selector += '.';
31
+ } else if (click_option.type === 'id') {
32
+ selector += '#';
33
+ }
34
+
35
+ selector += click_option.name;
36
+ return selector;
37
+ }
38
+
39
+ // Click elements from DB section begins
40
+ // TO DO clean up this code a bit to make it more like the scroll elements
41
+ // from DB section
42
+ var clickElementsFromDB = [];
43
+
44
+ var click_elements_from_options = ga_options.click_elements;
45
+ for (var i = 0; i < click_elements_from_options.length; i++) {
46
+
47
+ var clicked = click_elements_from_options[i];
48
+ newClickElement = {};
49
+
50
+
51
+ newClickElement.data = {
52
+ "select": makeSelector(clicked),
53
+ "category": clicked.category,
54
+ "action": clicked.action,
55
+ "label": clicked.label,
56
+ "bounce": parseInt(clicked.non_interaction),
57
+ "evalue": clicked.value, // "value" in DB. Change in project?
58
+ "link_click_delay": parseInt(ga_options.link_clicks_delay),
59
+ "universal": parseInt(ga_options.universal)
60
+ };
61
+
62
+ // NB was unescapeChars(select) (from original js file)
63
+ newClickElement.selector = newClickElement.data.select;
64
+ clickElementsFromDB.push(newClickElement);
65
+ }
66
+
67
+ // Click elements from DB section ends
68
+
69
+ // Scrollelements from DB section begins
70
+
71
+ var scroll_elements_from_options = ga_options.scroll_elements;
72
+ var scrollElementsFromDB = [];
73
+
74
+ // NB these will be assigned meaningful names in backend eventually
75
+ scroll_elements_from_options.forEach(function (el) {
76
+ scrollElementsFromDB.push({
77
+ "select": makeSelector(el),
78
+ "category": el.category,
79
+ "action": el.action,
80
+ "label": el.label,
81
+ "bounce": parseInt(el.non_interaction),
82
+ "evalue": el.value // "value" in DB. Change in project?
83
+ });
84
+ });
85
+
86
+ // Scrollelements from DB section ends
87
+
88
+ // Expose modified properties to global scope
89
+ return {
90
+
91
+ // From ga_options
92
+ clickElementsFromDB: clickElementsFromDB,
93
+ scrollElementsFromDB: scrollElementsFromDB,
94
+ advancedMode: ga_options.advanced,
95
+ link_clicks_delay: ga_options.link_clicks_delay,
96
+ snippet_type: ga_options.snippet_type,
97
+ scriptDebugMode: ga_options.script_debug_mode,
98
+ }
99
+
100
+
101
+ } // end if
102
+
103
+ })();
104
+
105
+
106
+ gaEventsMain = (function ($) {
107
+
108
+ "use strict";
109
+
110
+ // This is the tracking element.
111
+ // It could already have been created by another plugin.
112
+ var ga_element;
113
+
114
+ $(document).ready(function () {
115
+
116
+ // TO DO: This needs to be conditional on non-excluded roles!
117
+ // (Another export from mapper is probably the best way to get these
118
+ // at the current stage.)
119
+ applyBindings();
120
+ });
121
+
122
+ /*
123
+ * Apply bindings from values stored in DB
124
+ */
125
+ function applyBindings() {
126
+
127
+ // Bind click events stored in DB to the DOM body
128
+ // "clicked is the data which gets passed to the click_event function
129
+ // "selector" is the id or class of the element clicked
130
+ gaeMapper.clickElementsFromDB.forEach(function (el) {
131
+
132
+ $('body').on('click', el.selector, el.data, click_event);
133
+ });
134
+
135
+ // Bind scroll events stored in the DB to the window
136
+ $(window).on('scroll', bindScrollEventsFromDB);
137
+ }
138
+
139
+ /**
140
+ * Binds Scroll events from DB
141
+ *
142
+ * @returns {undefined}
143
+ */
144
+ function bindScrollEventsFromDB() {
145
+
146
+ // TO DO this code can be simplified a lot. May be better to use
147
+ // $('element').scroll()
148
+
149
+ var ga_window = $(window).height();
150
+ var ga_scroll_top = $(document).scrollTop();
151
+
152
+ for (var i = 0; i < gaeMapper.scrollElementsFromDB.length; i++) {
153
+
154
+ if (!gaeMapper.scrollElementsFromDB[i].sent) {
155
+
156
+ // NB was unescapeChars( gaeMapper.scrollElementsFromDB[i].select)
157
+ var $select = $(gaeMapper.scrollElementsFromDB[i].select);
158
+ gaeMapper.scrollElementsFromDB[i].offset = $select.offset();
159
+
160
+ if (gaeMapper.scrollElementsFromDB[i].offset && ga_scroll_top + ga_window >= gaeMapper.scrollElementsFromDB[i].offset.top + $select.height()) {
161
+ track_event(gaeMapper.scrollElementsFromDB[i].category, gaeMapper.scrollElementsFromDB[i].action, gaeMapper.scrollElementsFromDB[i].label, gaeMapper.scrollElementsFromDB[i].bounce, gaeMapper.scrollElementsFromDB[i].evalue);
162
+
163
+ gaeMapper.scrollElementsFromDB[i].sent = true;
164
+ }
165
+ }
166
+ }
167
+ } // End of bindScrollEvents
168
+
169
+ /*
170
+ * The main function for tracking events
171
+ *
172
+ * Param data types currently under review
173
+ *
174
+ * @param {string} category
175
+ * @param {string} action
176
+ * @param {string} label
177
+ * @param {bool} bounce
178
+ * @param {string}? evalue
179
+ * @returns {undefined}
180
+ */
181
+ var track_event = function (category, action, label, bounce, evalue) {
182
+
183
+ if (typeof ga_element === "undefined") {
184
+ if (typeof ga !== 'undefined') {
185
+ ga_element = ga;
186
+ } else if (typeof _gaq !== 'undefined') {
187
+ ga_element = _gaq;
188
+ } else if (typeof __gaTracker === "function") {
189
+ ga_element = __gaTracker;
190
+ } else if (typeof gaplusu === "function") {
191
+ ga_element = gaplusu;
192
+ } else if (gaeMapper.snippet_type !== 'gtm' && typeof dataLayer === "undefined") {
193
+ return;
194
+ }
195
+ }
196
+
197
+ var event_category = !category ? 'uncategorized' : category;
198
+ category = event_category;
199
+
200
+ var event_action = !action ? '' : action;
201
+ action = event_action;
202
+
203
+ var event_label = !label ? '' : label;
204
+ label = event_label;
205
+
206
+ var event_value = !evalue ? '' : evalue;
207
+ var event_bounce = !bounce ? false : bounce;
208
+
209
+ // Push data from event to relevant API
210
+ if (gaeMapper.snippet_type == 'gtm' || ( typeof dataLayer !== 'undefined' && typeof gtag === "undefined" )) {
211
+ dataLayer.push({
212
+ 'event': 'WPGAE',
213
+ 'eventCategory': category,
214
+ 'eventAction': action,
215
+ 'eventLabel': label,
216
+ 'eventValue': event_value,
217
+ 'nonInteraction': event_bounce
218
+ });
219
+ }
220
+
221
+ // We might want to call the tracking APIs as well as pushing to the data layer
222
+ // in which case this should be if rather than else if
223
+ else if (gaeMapper.snippet_type == 'gst' || typeof gtag != 'undefined') {
224
+ gtag('event', action, {
225
+ // Event parameters
226
+ 'event_category': category, 'event_label': label, 'value': event_value, 'non_interaction': event_bounce
227
+ });
228
+ } else if (gaeMapper.snippet_type == 'universal' || typeof ga != 'undefined' || (typeof __gaTracker === "function")) {
229
+ if (event_value) {
230
+ ga_element('send', 'event', category, action, label, event_value, {'nonInteraction': event_bounce});
231
+ } else {
232
+ ga_element('send', 'event', category, action, label, {'nonInteraction': event_bounce});
233
+ }
234
+ } else if (gaeMapper.snippet_type == 'legacy' || typeof _gaq != 'undefined') {
235
+ ga_element.push(['_trackEvent', category, action, label, event_value, event_bounce]);
236
+ }
237
+ }; // End of track_event function
238
+
239
+ /**
240
+ * Click event function
241
+ *
242
+ * @param {event} event
243
+ * @returns {undefined}
244
+ */
245
+ var click_event = function (event) {
246
+
247
+ track_event(event.data.category, event.data.action, event.data.label, event.data.bounce, event.data.evalue, this);
248
+
249
+ if (typeof event.data.link_click_delay !== 'undefined' && event.data.link_click_delay > 0 && typeof event.target.href !== 'undefined' && event.target.nodeName == "A") {
250
+ event.preventDefault();
251
+ var openInNewTab = false;
252
+ if (event.target.target) {
253
+ if (event.target.target.trim() === "_blank") {
254
+ openInNewTab = true;
255
+ }
256
+ }
257
+ var w;
258
+ if (openInNewTab) {
259
+ w = window.open('', '_blank');
260
+ }
261
+
262
+ var hash = isJustHashLink(event);
263
+ if (typeof hash !== "undefined" && hash !== "") {
264
+ window.location.hash = hash;
265
+ } else {
266
+ setTimeout(function () {
267
+ if (openInNewTab) {
268
+ w.location.href = event.target.href;
269
+ } else {
270
+ window.location = event.target.href;
271
+ }
272
+ }, parseInt(gaeMapper.link_clicks_delay));
273
+ }
274
+ }
275
+
276
+
277
+ }; // End of click event function
278
+ var isJustHashLink = function ( event ) {
279
+ var url = "";
280
+ if ( event.target.tagName !== "A" ) {
281
+ url = $( event.target ).parents( "a" ).attr( "href" );
282
+ } else {
283
+ url = $( event.target ).attr( "href" );
284
+ }
285
+ if ( url.indexOf( "#" ) === 0 ) {
286
+ return url;
287
+ }
288
+ return "";
289
+ };
290
+
291
+ })(jQuery);
js/ga-scroll-events.js DELETED
@@ -1,170 +0,0 @@
1
- /*!
2
- * WP Googel Analytics Events | v2.5.5
3
- * Copyright (c) 2013 Yuval Oren (@yuvalo)
4
- * License: GPLv2
5
- */
6
-
7
- /*jslint indent: 4 */
8
- /*global $, jQuery, document, window, _gaq*/
9
-
10
- var scroll_events = (function ($) {
11
- "use strict";
12
-
13
- var scroll_elements = [];
14
- var click_elements = [];
15
- var universal = 0;
16
- var gtm = 0;
17
- var gst = 0;
18
- var ga_element;
19
-
20
- var track_event = function (category, action, label, universal, bounce, evalue ){
21
- var event_category = !category ? '' : category;
22
- var event_action = !action ? '' : action;
23
- var event_label = !label ? '' : label;
24
- var event_bounce = bounce === "true" ? true : false;
25
- var event_value = !evalue ? false : evalue;
26
-
27
- if( typeof ga_element === "undefined" ){
28
- if( typeof ga !== 'undefined' ){
29
- ga_element = ga;
30
- }
31
- else if( typeof _gaq !== 'undefined' ){
32
- ga_element = _gaq;
33
- }
34
- else if( typeof __gaTracker === "function" ){
35
- ga_element = __gaTracker;
36
- } else if (!gtm && !gst){
37
- return;
38
- }
39
- }
40
-
41
- if (gtm) {
42
- dataLayer.push({
43
- 'event': 'WPGAE',
44
- 'eventCategory': category,
45
- 'eventAction': action,
46
- 'eventLabel': label,
47
- 'eventValue': event_value,
48
- 'nonInteraction': event_bounce
49
- });
50
- } else if (gst) {
51
- gtag('event', action, {
52
- // Event parameters
53
- 'event_category': category,
54
- 'event_label': label,
55
- 'value': event_value,
56
- 'non_interaction': event_bounce
57
- });
58
- } else if( universal ){
59
- // ga_element('send','event', category, action, label);
60
- if (event_value) {
61
- ga_element('send','event', category, action, label, event_value,{'nonInteraction': event_bounce});
62
- }else{
63
- ga_element('send','event', category, action, label, {'nonInteraction': event_bounce});
64
- }
65
-
66
-
67
- }
68
- else {
69
- // ga_element.push(['_trackEvent',category, action, label]);
70
- if (event_value) {
71
- ga_element.push( ['_trackEvent',category, action, label, event_value, event_bounce] );
72
- } else {
73
- ga_element.push( ['_trackEvent',category, action, label,, event_bounce] );
74
- }
75
- }
76
-
77
- };
78
-
79
- var click_event = function( event ){
80
-
81
- track_event(event.data.category, event.data.action, event.data.label, event.data.universal, event.data.bounce, event.data.evalue);
82
- var hasHref = event.currentTarget.href;
83
- var hrefTarget = event.currentTarget.target;
84
- if (hasHref && hasHref !== "") {
85
- event.preventDefault();
86
- if (hrefTarget.trim() === "_blank") {
87
- var w = window.open('', '_blank');
88
- w.location.href = hasHref;
89
- } else if(hasHref !== window.location.href) {
90
- setTimeout(function () {
91
- window.location = hasHref;
92
- }, 100);
93
- }
94
- }
95
- };
96
-
97
- var unescapeChars = function (text) {
98
-
99
- var map = {
100
- '&amp;': '&',
101
- '&lt;': '<',
102
- '&gt;': '>',
103
- '&quot;': '"',
104
- '\"': '"',
105
- '&#039;': "'"
106
- };
107
-
108
- if (typeof text != 'string') {
109
-
110
- var cleanObj;
111
-
112
- // if param text is non-string (assuming JSON object), we convert it first to string
113
- cleanObj = JSON.stringify(text);
114
-
115
- // we replace other chars
116
- cleanObj.replace(/&lt;|&gt;|&quot;|'&#039;/gi, function (m) {
117
- return map[m];
118
- });
119
-
120
- // convert it back to JSON obj
121
- cleanObj = JSON.parse(cleanObj);
122
- return cleanObj;
123
- }else{
124
- return text.replace(/&lt;|&gt;|&quot;|'&#039;/gi, function (m) {
125
- return map[m];
126
- });
127
- }
128
-
129
- return ''; //fallback
130
- };
131
-
132
-
133
- return {
134
- bind_events : function (settings) {
135
- scroll_elements = settings.scroll_elements;
136
- click_elements = settings.click_elements;
137
- universal = settings.universal;
138
- gtm = settings.gtm;
139
- gst = settings.gst;
140
-
141
- var i;
142
- for (i = 0; i < click_elements.length; i++) {
143
- var clicked = click_elements[i];
144
- var selector = unescapeChars(clicked.select);
145
-
146
- clicked.universal = universal;
147
- //$(selector).on('click', clicked, click_event);
148
- $('body').on('click', selector, clicked, click_event);
149
- }
150
-
151
-
152
-
153
- $(window).scroll(function () {
154
- var ga_window = $(window).height();
155
- var ga_scroll_top = $(document).scrollTop();
156
- var i;
157
- for (i = 0; i < scroll_elements.length; i++) {
158
- if (!scroll_elements[i].sent) {
159
- scroll_elements[i].offset = $( unescapeChars( scroll_elements[i].select) ).offset();
160
- if (scroll_elements[i].offset && ga_scroll_top + ga_window >= scroll_elements[i].offset.top + $(scroll_elements[i].select).height()) {
161
- track_event(scroll_elements[i].category, scroll_elements[i].action, scroll_elements[i].label, universal, scroll_elements[i].bounce, scroll_elements[i].evalue);
162
- scroll_elements[i].sent = true;
163
- }
164
- }
165
- }
166
- });
167
- }
168
- };
169
-
170
- }(jQuery));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/gae-mapper.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Script which maps DB values provided by wp_localize_script
3
+ * to values used in v2 scripts.
4
+ * Eventually the values provided by wp_localize script will be used directly
5
+ *
6
+ * Global: ga_options, TO DO
7
+ */
8
+
9
+
10
+
js/main.js CHANGED
@@ -1,8 +1,291 @@
1
- /*global $, jQuery, document, window*/
2
-
3
- jQuery('document').ready(function (){
4
- jQuery('#the-list').on('click', '.edit-event', function (e) {
5
- e.preventDefault();
6
- jQuery('#event-dialog').dialog();
7
- });
8
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Main GA Events Plugin function
3
+ *
4
+ * TO DO: all variables with gaeMapper. prefix can be declared at top of function
5
+ * and have prefix removed thereafter. Although for now it could be helpful to
6
+ * keep prefix to make it obvious which values need to eventually be accessed
7
+ * directly from localized values.
8
+ *
9
+ * Exposes track_event, click_event
10
+ *
11
+ * Global: TO DO
12
+ */
13
+ var gaeMapper = (function () {
14
+
15
+ // Make sure options are present globally
16
+ if (typeof ga_options !== "undefined") {
17
+
18
+ /*
19
+ * We temporarily need to be able to create a selector of type id or class
20
+ * from the existing DB options.
21
+ *
22
+ * Eventually we will probably update the backend to store the selector as an
23
+ * option within the associative "click" (or otherwise named) array
24
+ *
25
+ * @param {sequential array}
26
+ */
27
+ function makeSelector(click_option) {
28
+ var selector = "";
29
+ if (click_option.type === 'class') {
30
+ selector += '.';
31
+ } else if (click_option.type === 'id') {
32
+ selector += '#';
33
+ }
34
+
35
+ selector += click_option.name;
36
+ return selector;
37
+ }
38
+
39
+ // Click elements from DB section begins
40
+ // TO DO clean up this code a bit to make it more like the scroll elements
41
+ // from DB section
42
+ var clickElementsFromDB = [];
43
+
44
+ var click_elements_from_options = ga_options.click_elements;
45
+ for (var i = 0; i < click_elements_from_options.length; i++) {
46
+
47
+ var clicked = click_elements_from_options[i];
48
+ newClickElement = {};
49
+
50
+
51
+ newClickElement.data = {
52
+ "select": makeSelector(clicked),
53
+ "category": clicked.category,
54
+ "action": clicked.action,
55
+ "label": clicked.label,
56
+ "bounce": parseInt(clicked.non_interaction),
57
+ "evalue": clicked.value, // "value" in DB. Change in project?
58
+ "link_click_delay": parseInt(ga_options.link_clicks_delay),
59
+ "universal": parseInt(ga_options.universal)
60
+ };
61
+
62
+ // NB was unescapeChars(select) (from original js file)
63
+ newClickElement.selector = newClickElement.data.select;
64
+ clickElementsFromDB.push(newClickElement);
65
+ }
66
+
67
+ // Click elements from DB section ends
68
+
69
+ // Scrollelements from DB section begins
70
+
71
+ var scroll_elements_from_options = ga_options.scroll_elements;
72
+ var scrollElementsFromDB = [];
73
+
74
+ // NB these will be assigned meaningful names in backend eventually
75
+ scroll_elements_from_options.forEach(function (el) {
76
+ scrollElementsFromDB.push({
77
+ "select": makeSelector(el),
78
+ "category": el.category,
79
+ "action": el.action,
80
+ "label": el.label,
81
+ "bounce": parseInt(el.non_interaction),
82
+ "evalue": el.value // "value" in DB. Change in project?
83
+ });
84
+ });
85
+
86
+ // Scrollelements from DB section ends
87
+
88
+ // Expose modified properties to global scope
89
+ return {
90
+
91
+ // From ga_options
92
+ clickElementsFromDB: clickElementsFromDB,
93
+ scrollElementsFromDB: scrollElementsFromDB,
94
+ advancedMode: ga_options.advanced,
95
+ link_clicks_delay: ga_options.link_clicks_delay,
96
+ snippet_type: ga_options.snippet_type,
97
+ scriptDebugMode: ga_options.script_debug_mode,
98
+ }
99
+
100
+
101
+ } // end if
102
+
103
+ })();
104
+
105
+
106
+ gaEventsMain = (function ($) {
107
+
108
+ "use strict";
109
+
110
+ // This is the tracking element.
111
+ // It could already have been created by another plugin.
112
+ var ga_element;
113
+
114
+ $(document).ready(function () {
115
+
116
+ // TO DO: This needs to be conditional on non-excluded roles!
117
+ // (Another export from mapper is probably the best way to get these
118
+ // at the current stage.)
119
+ applyBindings();
120
+ });
121
+
122
+ /*
123
+ * Apply bindings from values stored in DB
124
+ */
125
+ function applyBindings() {
126
+
127
+ // Bind click events stored in DB to the DOM body
128
+ // "clicked is the data which gets passed to the click_event function
129
+ // "selector" is the id or class of the element clicked
130
+ gaeMapper.clickElementsFromDB.forEach(function (el) {
131
+
132
+ $('body').on('click', el.selector, el.data, click_event);
133
+ });
134
+
135
+ // Bind scroll events stored in the DB to the window
136
+ $(window).on('scroll', bindScrollEventsFromDB);
137
+ }
138
+
139
+ /**
140
+ * Binds Scroll events from DB
141
+ *
142
+ * @returns {undefined}
143
+ */
144
+ function bindScrollEventsFromDB() {
145
+
146
+ // TO DO this code can be simplified a lot. May be better to use
147
+ // $('element').scroll()
148
+
149
+ var ga_window = $(window).height();
150
+ var ga_scroll_top = $(document).scrollTop();
151
+
152
+ for (var i = 0; i < gaeMapper.scrollElementsFromDB.length; i++) {
153
+
154
+ if (!gaeMapper.scrollElementsFromDB[i].sent) {
155
+
156
+ // NB was unescapeChars( gaeMapper.scrollElementsFromDB[i].select)
157
+ var $select = $(gaeMapper.scrollElementsFromDB[i].select);
158
+ gaeMapper.scrollElementsFromDB[i].offset = $select.offset();
159
+
160
+ if (gaeMapper.scrollElementsFromDB[i].offset && ga_scroll_top + ga_window >= gaeMapper.scrollElementsFromDB[i].offset.top + $select.height()) {
161
+ track_event(gaeMapper.scrollElementsFromDB[i].category, gaeMapper.scrollElementsFromDB[i].action, gaeMapper.scrollElementsFromDB[i].label, gaeMapper.scrollElementsFromDB[i].bounce, gaeMapper.scrollElementsFromDB[i].evalue);
162
+
163
+ gaeMapper.scrollElementsFromDB[i].sent = true;
164
+ }
165
+ }
166
+ }
167
+ } // End of bindScrollEvents
168
+
169
+ /*
170
+ * The main function for tracking events
171
+ *
172
+ * Param data types currently under review
173
+ *
174
+ * @param {string} category
175
+ * @param {string} action
176
+ * @param {string} label
177
+ * @param {bool} bounce
178
+ * @param {string}? evalue
179
+ * @returns {undefined}
180
+ */
181
+ var track_event = function (category, action, label, bounce, evalue) {
182
+
183
+ if (typeof ga_element === "undefined") {
184
+ if (typeof ga !== 'undefined') {
185
+ ga_element = ga;
186
+ } else if (typeof _gaq !== 'undefined') {
187
+ ga_element = _gaq;
188
+ } else if (typeof __gaTracker === "function") {
189
+ ga_element = __gaTracker;
190
+ } else if (typeof gaplusu === "function") {
191
+ ga_element = gaplusu;
192
+ } else if (gaeMapper.snippet_type !== 'gtm' && typeof dataLayer === "undefined") {
193
+ return;
194
+ }
195
+ }
196
+
197
+ var event_category = !category ? 'uncategorized' : category;
198
+ category = event_category;
199
+
200
+ var event_action = !action ? '' : action;
201
+ action = event_action;
202
+
203
+ var event_label = !label ? '' : label;
204
+ label = event_label;
205
+
206
+ var event_value = !evalue ? '' : evalue;
207
+ var event_bounce = !bounce ? false : bounce;
208
+
209
+ // Push data from event to relevant API
210
+ if (gaeMapper.snippet_type == 'gtm' || ( typeof dataLayer !== 'undefined' && typeof gtag === "undefined" )) {
211
+ dataLayer.push({
212
+ 'event': 'WPGAE',
213
+ 'eventCategory': category,
214
+ 'eventAction': action,
215
+ 'eventLabel': label,
216
+ 'eventValue': event_value,
217
+ 'nonInteraction': event_bounce
218
+ });
219
+ }
220
+
221
+ // We might want to call the tracking APIs as well as pushing to the data layer
222
+ // in which case this should be if rather than else if
223
+ else if (gaeMapper.snippet_type == 'gst' || typeof gtag != 'undefined') {
224
+ gtag('event', action, {
225
+ // Event parameters
226
+ 'event_category': category, 'event_label': label, 'value': event_value, 'non_interaction': event_bounce
227
+ });
228
+ } else if (gaeMapper.snippet_type == 'universal' || typeof ga != 'undefined' || (typeof __gaTracker === "function")) {
229
+ if (event_value) {
230
+ ga_element('send', 'event', category, action, label, event_value, {'nonInteraction': event_bounce});
231
+ } else {
232
+ ga_element('send', 'event', category, action, label, {'nonInteraction': event_bounce});
233
+ }
234
+ } else if (gaeMapper.snippet_type == 'legacy' || typeof _gaq != 'undefined') {
235
+ ga_element.push(['_trackEvent', category, action, label, event_value, event_bounce]);
236
+ }
237
+ }; // End of track_event function
238
+
239
+ /**
240
+ * Click event function
241
+ *
242
+ * @param {event} event
243
+ * @returns {undefined}
244
+ */
245
+ var click_event = function (event) {
246
+
247
+ track_event(event.data.category, event.data.action, event.data.label, event.data.bounce, event.data.evalue, this);
248
+
249
+ if (typeof event.data.link_click_delay !== 'undefined' && event.data.link_click_delay > 0 && typeof event.target.href !== 'undefined' && event.target.nodeName == "A") {
250
+ event.preventDefault();
251
+ var openInNewTab = false;
252
+ if (event.target.target) {
253
+ if (event.target.target.trim() === "_blank") {
254
+ openInNewTab = true;
255
+ }
256
+ }
257
+ var w;
258
+ if (openInNewTab) {
259
+ w = window.open('', '_blank');
260
+ }
261
+
262
+ var hash = isJustHashLink(event);
263
+ if (typeof hash !== "undefined" && hash !== "") {
264
+ window.location.hash = hash;
265
+ } else {
266
+ setTimeout(function () {
267
+ if (openInNewTab) {
268
+ w.location.href = event.target.href;
269
+ } else {
270
+ window.location = event.target.href;
271
+ }
272
+ }, parseInt(gaeMapper.link_clicks_delay));
273
+ }
274
+ }
275
+
276
+
277
+ }; // End of click event function
278
+ var isJustHashLink = function ( event ) {
279
+ var url = "";
280
+ if ( event.target.tagName !== "A" ) {
281
+ url = $( event.target ).parents( "a" ).attr( "href" );
282
+ } else {
283
+ url = $( event.target ).attr( "href" );
284
+ }
285
+ if ( url.indexOf( "#" ) === 0 ) {
286
+ return url;
287
+ }
288
+ return "";
289
+ };
290
+
291
+ })(jQuery);
js/third-party/jquery.form-validator.min.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ /** File generated by Grunt -- do not modify
2
+ * JQUERY-FORM-VALIDATOR
3
+ *
4
+ * @version 2.3.79
5
+ * @website http://formvalidator.net/
6
+ * @author Victor Jonsson, http://victorjonsson.se
7
+ * @license MIT
8
+ */
9
+ !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof module&&module.exports?module.exports=b(require("jquery")):b(a.jQuery)}(this,function(a){!function(a,b,c){function d(a,b){this.$form=a,this.$input=b,this.reset(),b.on("change paste",this.reset.bind(this))}var e=function(){return!1},f=null,g={numHalted:0,haltValidation:function(b){this.numHalted++,a.formUtils.haltValidation=!0,b.unbind("submit",e).bind("submit",e).find('*[type="submit"]').addClass("disabled").attr("disabled","disabled")},unHaltValidation:function(b){this.numHalted--,0===this.numHalted&&(a.formUtils.haltValidation=!1,b.unbind("submit",e).find('*[type="submit"]').removeClass("disabled").removeAttr("disabled","disabled"))}};d.prototype.reset=function(){this.haltedFormValidation=!1,this.hasRun=!1,this.isRunning=!1,this.result=c},d.prototype.run=function(a,b){return"keyup"===a?null:this.isRunning?(f=a,this.haltedFormValidation||(g.haltValidation(),this.haltedFormValidation=!0),null):this.hasRun?this.result:(f=a,g.haltValidation(this.$form),this.haltedFormValidation=!0,this.isRunning=!0,this.$input.attr("disabled","disabled").addClass("async-validation"),this.$form.addClass("async-validation"),b(function(a){this.done(a)}.bind(this)),null)},d.prototype.done=function(a){this.result=a,this.hasRun=!0,this.isRunning=!1,this.$input.removeAttr("disabled").removeClass("async-validation"),this.$form.removeClass("async-validation"),this.haltedFormValidation&&(g.unHaltValidation(this.$form),"submit"===f?this.$form.trigger("submit"):this.$input.trigger("validation.revalidate"))},d.loadInstance=function(a,b,c){var e,f=b.get(0);return f.asyncValidators||(f.asyncValidators={}),f.asyncValidators[a]?e=f.asyncValidators[a]:(e=new d(c,b),f.asyncValidators[a]=e),e},a.formUtils=a.extend(a.formUtils||{},{asyncValidation:function(a,b,c){return this.warn("Use of deprecated function $.formUtils.asyncValidation, use $.formUtils.addAsyncValidator() instead"),d.loadInstance(a,b,c)},addAsyncValidator:function(b){var c=a.extend({},b),e=c.validatorFunction;c.async=!0,c.validatorFunction=function(a,b,f,g,h,i){var j=d.loadInstance(this.name,b,h);return j.run(i,function(d){e.apply(c,[d,a,b,f,g,h,i])})},this.addValidator(c)}}),a(b).bind("validatorsLoaded formValidationSetup",function(b,c){c||(c=a("form")),c.find("[data-validation]").each(function(){var b=a(this);b.valAttr("async",!1),a.each(a.split(b.attr("data-validation")),function(c,d){var e=a.formUtils.validators["validate_"+d];e&&e.async&&b.valAttr("async","yes")})})})}(a,window),function(a,b){"use strict";function c(b){b&&"custom"===b.errorMessagePosition&&"function"==typeof b.errorMessageCustom&&(a.formUtils.warn("Use of deprecated function errorMessageCustom, use config.submitErrorMessageCallback instead"),b.submitErrorMessageCallback=function(a,c){b.errorMessageCustom(a,b.language.errorTitle,c,b)})}function d(b){if(b.errorMessagePosition&&"object"==typeof b.errorMessagePosition){a.formUtils.warn("Deprecated use of config parameter errorMessagePosition, use config.submitErrorMessageCallback instead");var c=b.errorMessagePosition;b.errorMessagePosition="top",b.submitErrorMessageCallback=function(){return c}}}function e(b){var c=b.find("[data-validation-if-checked]");c.length&&a.formUtils.warn('Detected use of attribute "data-validation-if-checked" which is deprecated. Use "data-validation-depends-on" provided by module "logic"'),c.on("beforeValidation",function(){var c=a(this),d=c.valAttr("if-checked"),e=a('input[name="'+d+'"]',b),f=e.is(":checked"),g=(a.formUtils.getValue(e)||"").toString(),h=c.valAttr("if-checked-value");(!f||h&&h!==g)&&c.valAttr("skipped",!0)})}function f(b){var c={se:"sv",cz:"cs",dk:"da"};if(b.lang in c){var d=c[b.lang];a.formUtils.warn('Deprecated use of lang code "'+b.lang+'" use "'+d+'" instead'),b.lang=d}}a.fn.validateForm=function(b,c){return a.formUtils.warn("Use of deprecated function $.validateForm, use $.isValid instead"),this.isValid(b,c,!0)},a(window).on("formValidationPluginInit",function(a,b){f(b),c(b),d(b)}).on("validatorsLoaded formValidationSetup",function(b,c){c||(c=a("form")),e(c)})}(a),function(a){"use strict";var b={resolveErrorMessage:function(a,b,c,d,e){var f=d.validationErrorMsgAttribute+"-"+c.replace("validate_",""),g=a.attr(f);return g||(g=a.attr(d.validationErrorMsgAttribute),g||(g="function"!=typeof b.errorMessageKey?e[b.errorMessageKey]:e[b.errorMessageKey(d)],g||(g=b.errorMessage))),g},getParentContainer:function(b){if(b.valAttr("error-msg-container"))return a(b.valAttr("error-msg-container"));var c=b.parent();return"checkbox"===b.attr("type")&&b.closest(".checkbox").length?c=b.closest(".checkbox").parent():"radio"===b.attr("type")&&b.closest(".radio").length&&(c=b.closest(".radio").parent()),c.closest(".input-group").length&&(c=c.closest(".input-group").parent()),c},applyInputErrorStyling:function(a,b){a.addClass(b.errorElementClass).removeClass(b.successElementClass),this.getParentContainer(a).addClass(b.inputParentClassOnError).removeClass(b.inputParentClassOnSuccess),""!==b.borderColorOnError&&a.css("border-color",b.borderColorOnError)},applyInputSuccessStyling:function(a,b){a.addClass(b.successElementClass),this.getParentContainer(a).addClass(b.inputParentClassOnSuccess)},removeInputStylingAndMessage:function(a,c){a.removeClass(c.successElementClass).removeClass(c.errorElementClass).css("border-color","");var d=b.getParentContainer(a);if(d.removeClass(c.inputParentClassOnError).removeClass(c.inputParentClassOnSuccess),"function"==typeof c.inlineErrorMessageCallback){var e=c.inlineErrorMessageCallback(a,!1,c);e&&e.html("")}else d.find("."+c.errorMessageClass).remove()},removeAllMessagesAndStyling:function(c,d){if("function"==typeof d.submitErrorMessageCallback){var e=d.submitErrorMessageCallback(c,!1,d);e&&e.html("")}else c.find("."+d.errorMessageClass+".alert").remove();c.find("."+d.errorElementClass+",."+d.successElementClass).each(function(){b.removeInputStylingAndMessage(a(this),d)})},setInlineMessage:function(b,c,d){this.applyInputErrorStyling(b,d);var e,f=document.getElementById(b.attr("name")+"_err_msg"),g=!1,h=function(d){a.formUtils.$win.trigger("validationErrorDisplay",[b,d]),d.html(c)},i=function(){var f=!1;g.find("."+d.errorMessageClass).each(function(){if(this.inputReferer===b[0])return f=a(this),!1}),f?c?h(f):f.remove():""!==c&&(e=a('<div class="'+d.errorMessageClass+' alert"></div>'),h(e),e[0].inputReferer=b[0],g.prepend(e))};if(f)a.formUtils.warn("Using deprecated element reference "+f.id),g=a(f),i();else if("function"==typeof d.inlineErrorMessageCallback){if(g=d.inlineErrorMessageCallback(b,c,d),!g)return;i()}else{var j=this.getParentContainer(b);e=j.find("."+d.errorMessageClass+".help-block"),0===e.length&&(e=a("<span></span>").addClass("help-block").addClass(d.errorMessageClass),e.appendTo(j)),h(e)}},setMessageInTopOfForm:function(b,c,d,e){var f='<div class="{errorMessageClass} alert alert-danger"><strong>{errorTitle}</strong><ul>{fields}</ul></div>',g=!1;if("function"!=typeof d.submitErrorMessageCallback||(g=d.submitErrorMessageCallback(b,c,d))){var h={errorTitle:e.errorTitle,fields:"",errorMessageClass:d.errorMessageClass};a.each(c,function(a,b){h.fields+="<li>"+b+"</li>"}),a.each(h,function(a,b){f=f.replace("{"+a+"}",b)}),g?g.html(f):b.children().eq(0).before(a(f))}}};a.formUtils=a.extend(a.formUtils||{},{dialogs:b})}(a),function(a,b,c){"use strict";var d=0;a.fn.validateOnBlur=function(b,c){var d=this,e=this.find("*[data-validation]");return e.each(function(){var e=a(this);if(e.is("[type=radio]")){var f=d.find('[type=radio][name="'+e.attr("name")+'"]');f.bind("blur.validation",function(){e.validateInputOnBlur(b,c,!0,"blur")}),c.validateCheckboxRadioOnClick&&f.bind("click.validation",function(){e.validateInputOnBlur(b,c,!0,"click")})}}),e.bind("blur.validation",function(){a(this).validateInputOnBlur(b,c,!0,"blur")}),c.validateCheckboxRadioOnClick&&this.find("input[type=checkbox][data-validation],input[type=radio][data-validation]").bind("click.validation",function(){a(this).validateInputOnBlur(b,c,!0,"click")}),this},a.fn.validateOnEvent=function(b,c){if(0!==this.length){var d="FORM"===this[0].nodeName?this.find("*[data-validation-event]"):this;return d.each(function(){var d=a(this),e=d.valAttr("event");e&&d.unbind(e+".validation").bind(e+".validation",function(d){9!==(d||{}).keyCode&&a(this).validateInputOnBlur(b,c,!0,e)})}),this}},a.fn.showHelpOnFocus=function(b){return b||(b="data-validation-help"),this.find("textarea,input").each(function(){var c=a(this),e="jquery_form_help_"+ ++d,f=c.attr(b);c.removeClass("has-help-text").unbind("focus.help").unbind("blur.help"),f&&c.addClass("has-help-txt").bind("focus.help",function(){var b=c.parent().find("."+e);0===b.length&&(b=a("<span />").addClass(e).addClass("help").addClass("help-block").text(f).hide(),c.after(b)),b.fadeIn()}).bind("blur.help",function(){a(this).parent().find("."+e).fadeOut("slow")})}),this},a.fn.validate=function(b,c,d){var e=a.extend({},a.formUtils.LANG,d||{});this.each(function(){var d=a(this),f=d.closest("form").get(0)||{},g=f.validationConfig||a.formUtils.defaultConfig();d.one("validation",function(a,c){"function"==typeof b&&b(c,this,a)}),d.validateInputOnBlur(e,a.extend({},g,c||{}),!0)})},a.fn.willPostponeValidation=function(){return(this.valAttr("suggestion-nr")||this.valAttr("postpone")||this.hasClass("hasDatepicker"))&&!b.postponedValidation},a.fn.validateInputOnBlur=function(c,d,e,f){if(a.formUtils.eventType=f,this.willPostponeValidation()){var g=this,h=this.valAttr("postpone")||200;return b.postponedValidation=function(){g.validateInputOnBlur(c,d,e,f),b.postponedValidation=!1},setTimeout(function(){b.postponedValidation&&b.postponedValidation()},h),this}c=a.extend({},a.formUtils.LANG,c||{}),a.formUtils.dialogs.removeInputStylingAndMessage(this,d);var i=this,j=i.closest("form"),k=a.formUtils.validateInput(i,c,d,j,f),l=function(){i.validateInputOnBlur(c,d,!1,"blur.revalidated")};return"blur"===f&&i.unbind("validation.revalidate",l).one("validation.revalidate",l),e&&i.removeKeyUpValidation(),k.shouldChangeDisplay&&(k.isValid?a.formUtils.dialogs.applyInputSuccessStyling(i,d):a.formUtils.dialogs.setInlineMessage(i,k.errorMsg,d)),!k.isValid&&e&&i.validateOnKeyUp(c,d),this},a.fn.validateOnKeyUp=function(b,c){return this.each(function(){var d=a(this);d.valAttr("has-keyup-event")||d.valAttr("has-keyup-event","true").bind("keyup.validation",function(a){9!==a.keyCode&&d.validateInputOnBlur(b,c,!1,"keyup")})}),this},a.fn.removeKeyUpValidation=function(){return this.each(function(){a(this).valAttr("has-keyup-event",!1).unbind("keyup.validation")}),this},a.fn.valAttr=function(a,b){return b===c?this.attr("data-validation-"+a):b===!1||null===b?this.removeAttr("data-validation-"+a):(a=a.length>0?"-"+a:"",this.attr("data-validation"+a,b))},a.fn.isValid=function(b,c,d){if(a.formUtils.isLoadingModules){var e=this;return setTimeout(function(){e.isValid(b,c,d)},200),null}c=a.extend({},a.formUtils.defaultConfig(),c||{}),b=a.extend({},a.formUtils.LANG,b||{}),d=d!==!1,a.formUtils.errorDisplayPreventedWhenHalted&&(delete a.formUtils.errorDisplayPreventedWhenHalted,d=!1);var f=function(b,e){a.inArray(b,h)<0&&h.push(b),i.push(e),e.valAttr("current-error",b),d&&a.formUtils.dialogs.applyInputErrorStyling(e,c)},g=[],h=[],i=[],j=this,k=function(b,d){return"submit"===d||"button"===d||"reset"===d||a.inArray(b,c.ignore||[])>-1};if(d&&a.formUtils.dialogs.removeAllMessagesAndStyling(j,c),j.find("input,textarea,select").filter(':not([type="submit"],[type="button"])').each(function(){var d=a(this),e=d.attr("type"),h="radio"===e||"checkbox"===e,i=d.attr("name");if(!k(i,e)&&(!h||a.inArray(i,g)<0)){h&&g.push(i);var l=a.formUtils.validateInput(d,b,c,j,"submit");l.isValid?l.isValid&&l.shouldChangeDisplay&&(d.valAttr("current-error",!1),a.formUtils.dialogs.applyInputSuccessStyling(d,c)):f(l.errorMsg,d)}}),"function"==typeof c.onValidate){var l=c.onValidate(j);a.isArray(l)?a.each(l,function(a,b){f(b.message,b.element)}):l&&l.element&&l.message&&f(l.message,l.element)}return a.formUtils.isValidatingEntireForm=!1,i.length>0&&d&&("top"===c.errorMessagePosition?a.formUtils.dialogs.setMessageInTopOfForm(j,h,c,b):a.each(i,function(b,d){a.formUtils.dialogs.setInlineMessage(d,d.valAttr("current-error"),c)}),c.scrollToTopOnError&&a.formUtils.$win.scrollTop(j.offset().top-20)),!d&&a.formUtils.haltValidation&&(a.formUtils.errorDisplayPreventedWhenHalted=!0),0===i.length&&!a.formUtils.haltValidation},a.fn.restrictLength=function(b){return new a.formUtils.lengthRestriction(this,b),this},a.fn.addSuggestions=function(b){var c=!1;return this.find("input").each(function(){var d=a(this);c=a.split(d.attr("data-suggestions")),c.length>0&&!d.hasClass("has-suggestions")&&(a.formUtils.suggest(d,c,b),d.addClass("has-suggestions"))}),this}}(a,window),function(a){"use strict";a.formUtils=a.extend(a.formUtils||{},{isLoadingModules:!1,loadedModules:{},registerLoadedModule:function(b){this.loadedModules[a.trim(b).toLowerCase()]=!0},hasLoadedModule:function(b){return a.trim(b).toLowerCase()in this.loadedModules},loadModules:function(b,c,d){if(a.formUtils.isLoadingModules)return void setTimeout(function(){a.formUtils.loadModules(b,c,d)},100);var e=function(b,c){var e=a.split(b),f=e.length,g=function(){f--,0===f&&(a.formUtils.isLoadingModules=!1,"function"==typeof d&&d())};f>0&&(a.formUtils.isLoadingModules=!0);var h="?_="+(new Date).getTime(),i=document.getElementsByTagName("head")[0]||document.getElementsByTagName("body")[0];a.each(e,function(b,d){if(d=a.trim(d),0===d.length||a.formUtils.hasLoadedModule(d))g();else{var e=c+d+(".js"===d.slice(-3)?"":".js"),f=document.createElement("SCRIPT");"function"==typeof define&&define.amd?require([e+(".dev.js"===e.slice(-7)?h:"")],g):(f.type="text/javascript",f.onload=g,f.src=e+(".dev.js"===e.slice(-7)?h:""),f.onerror=function(){a.formUtils.warn("Unable to load form validation module "+e,!0),g()},f.onreadystatechange=function(){"complete"!==this.readyState&&"loaded"!==this.readyState||(g(),this.onload=null,this.onreadystatechange=null)},i.appendChild(f))}})};if(c)e(b,c);else{var f=function(){var c=!1;return a('script[src*="form-validator"]').each(function(){var a=this.src.split("form-validator")[1].split("node_modules").length>1;if(!a)return c=this.src.substr(0,this.src.lastIndexOf("/"))+"/","/"===c&&(c=""),!1}),c!==!1&&(e(b,c),!0)};f()||a(function(){var a=f();a||"function"==typeof d&&d()})}}})}(a),function(a){"use strict";a.split=function(b,c,d){d=void 0===d||d===!0;var e="[,|"+(d?"\\s":"")+"-]\\s*",f=new RegExp(e,"g");if("function"!=typeof c){if(!b)return[];var g=[];return a.each(b.split(c?c:f),function(b,c){c=a.trim(c),c.length&&g.push(c)}),g}b&&a.each(b.split(f),function(b,d){if(d=a.trim(d),d.length)return c(d,b)})},a.validate=function(b){var c=a.extend(a.formUtils.defaultConfig(),{form:"form",validateOnEvent:!1,validateOnBlur:!0,validateCheckboxRadioOnClick:!0,showHelpOnFocus:!0,addSuggestions:!0,modules:"",onModulesLoaded:null,language:!1,onSuccess:!1,onError:!1,onElementValidate:!1});if(b=a.extend(c,b||{}),a(window).trigger("formValidationPluginInit",[b]),b.lang&&"en"!==b.lang){var d="lang/"+b.lang+".js";b.modules+=b.modules.length?","+d:d}a(b.form).each(function(c,d){d.validationConfig=b;var e=a(d);e.trigger("formValidationSetup",[e,b]),e.find(".has-help-txt").unbind("focus.validation").unbind("blur.validation"),e.removeClass("has-validation-callback").unbind("submit.validation").unbind("reset.validation").find("input[data-validation],textarea[data-validation]").unbind("blur.validation"),e.bind("submit.validation",function(c){var d=a(this),e=function(){return c.stopImmediatePropagation(),!1};if(a.formUtils.haltValidation)return e();if(a.formUtils.isLoadingModules)return setTimeout(function(){d.trigger("submit.validation")},200),e();var f=d.isValid(b.language,b);if(a.formUtils.haltValidation)return e();if(!f||"function"!=typeof b.onSuccess)return f||"function"!=typeof b.onError?!!f||e():(b.onError(d),e());var g=b.onSuccess(d);return g===!1?e():void 0}).bind("reset.validation",function(){a.formUtils.dialogs.removeAllMessagesAndStyling(e,b)}).addClass("has-validation-callback"),b.showHelpOnFocus&&e.showHelpOnFocus(),b.addSuggestions&&e.addSuggestions(),b.validateOnBlur&&(e.validateOnBlur(b.language,b),e.bind("html5ValidationAttrsFound",function(){e.validateOnBlur(b.language,b)})),b.validateOnEvent&&e.validateOnEvent(b.language,b)}),""!==b.modules&&a.formUtils.loadModules(b.modules,null,function(){"function"==typeof b.onModulesLoaded&&b.onModulesLoaded();var c="string"==typeof b.form?a(b.form):b.form;a.formUtils.$win.trigger("validatorsLoaded",[c,b])})}}(a),function(a,b){"use strict";var c=a(b);a.formUtils=a.extend(a.formUtils||{},{$win:c,defaultConfig:function(){return{ignore:[],errorElementClass:"error",successElementClass:"valid",borderColorOnError:"#b94a48",errorMessageClass:"form-error",validationRuleAttribute:"data-validation",validationErrorMsgAttribute:"data-validation-error-msg",errorMessagePosition:"inline",errorMessageTemplate:{container:'<div class="{errorMessageClass} alert alert-danger">{messages}</div>',messages:"<strong>{errorTitle}</strong><ul>{fields}</ul>",field:"<li>{msg}</li>"},scrollToTopOnError:!0,dateFormat:"yyyy-mm-dd",addValidClassOnAll:!1,decimalSeparator:".",inputParentClassOnError:"has-error",inputParentClassOnSuccess:"has-success",validateHiddenInputs:!1,inlineErrorMessageCallback:!1,submitErrorMessageCallback:!1}},validators:{},sanitizers:{},_events:{load:[],valid:[],invalid:[]},haltValidation:!1,addValidator:function(a){var b=0===a.name.indexOf("validate_")?a.name:"validate_"+a.name;void 0===a.validateOnKeyUp&&(a.validateOnKeyUp=!0),this.validators[b]=a},addSanitizer:function(a){this.sanitizers[a.name]=a},warn:function(a,c){"console"in b?"function"==typeof b.console.warn?b.console.warn(a):"function"==typeof b.console.log&&b.console.log(a):c&&alert(a)},getValue:function(a,b){var c=b?b.find(a):a;if(c.length>0){var d=c.eq(0).attr("type");return"radio"===d||"checkbox"===d?c.filter(":checked").val()||"":c.val()||""}return!1},validateInput:function(b,c,d,e,f){d=d||a.formUtils.defaultConfig(),c=c||a.formUtils.LANG,e.length||(e=b.parent());var g=this.getValue(b);b.valAttr("skipped",!1).one("beforeValidation",function(){(b.attr("disabled")||!b.is(":visible")&&!d.validateHiddenInputs)&&b.valAttr("skipped",1)}).trigger("beforeValidation",[g,c,d]);var h="true"===b.valAttr("optional"),i=!g&&h,j=b.attr(d.validationRuleAttribute),k=!0,l="",m={isValid:!0,shouldChangeDisplay:!0,errorMsg:""};if(!j||i||b.valAttr("skipped"))return m.shouldChangeDisplay=d.addValidClassOnAll,m;var n=b.valAttr("ignore");return n&&a.each(n.split(""),function(a,b){g=g.replace(new RegExp("\\"+b,"g"),"")}),a.split(j,function(h){0!==h.indexOf("validate_")&&(h="validate_"+h);var i=a.formUtils.validators[h];if(!i)throw new Error('Using undefined validator "'+h+'". Maybe you have forgotten to load the module that "'+h+'" belongs to?');if("validate_checkbox_group"===h&&(b=e.find('[name="'+b.attr("name")+'"]:eq(0)')),("keyup"!==f||i.validateOnKeyUp)&&(k=i.validatorFunction(g,b,d,c,e,f)),!k)return d.validateOnBlur&&b.validateOnKeyUp(c,d),l=a.formUtils.dialogs.resolveErrorMessage(b,i,h,d,c),!1}),k===!1?(b.trigger("validation",!1),m.errorMsg=l,m.isValid=!1,m.shouldChangeDisplay=!0):null===k?m.shouldChangeDisplay=!1:(b.trigger("validation",!0),m.shouldChangeDisplay=!0),"function"==typeof d.onElementValidate&&null!==l&&d.onElementValidate(m.isValid,b,e,l),b.trigger("afterValidation",[m,f]),m},parseDate:function(b,c,d){var e,f,g,h,i=c.replace(/[a-zA-Z]/gi,"").substring(0,1),j="^",k=c.split(i||null);if(a.each(k,function(a,b){j+=(a>0?"\\"+i:"")+"(\\d{"+b.length+"})"}),j+="$",d){var l=[];a.each(b.split(i),function(a,b){1===b.length&&(b="0"+b),l.push(b)}),b=l.join(i)}if(e=b.match(new RegExp(j)),null===e)return!1;var m=function(b,c,d){for(var e=0;e<c.length;e++)if(c[e].substring(0,1)===b)return a.formUtils.parseDateInt(d[e+1]);return-1};return g=m("m",k,e),f=m("d",k,e),h=m("y",k,e),!(2===g&&f>28&&(h%4!==0||h%100===0&&h%400!==0)||2===g&&f>29&&(h%4===0||h%100!==0&&h%400===0)||g>12||0===g)&&(!(this.isShortMonth(g)&&f>30||!this.isShortMonth(g)&&f>31||0===f)&&[h,g,f])},parseDateInt:function(a){return 0===a.indexOf("0")&&(a=a.replace("0","")),parseInt(a,10)},isShortMonth:function(a){return a%2===0&&a<7||a%2!==0&&a>7},lengthRestriction:function(b,c){var d=parseInt(c.text(),10),e=0,f=function(){var a=b.val().length;if(a>d){var f=b.scrollTop();b.val(b.val().substring(0,d)),b.scrollTop(f)}e=d-a,e<0&&(e=0),c.text(e)};a(b).bind("keydown keyup keypress focus blur",f).bind("cut paste",function(){setTimeout(f,100)}),a(document).bind("ready",f)},numericRangeCheck:function(b,c){var d=a.split(c),e=parseInt(c.substr(3),10);return 1===d.length&&c.indexOf("min")===-1&&c.indexOf("max")===-1&&(d=[c,c]),2===d.length&&(b<parseInt(d[0],10)||b>parseInt(d[1],10))?["out",d[0],d[1]]:0===c.indexOf("min")&&b<e?["min",e]:0===c.indexOf("max")&&b>e?["max",e]:["ok"]},_numSuggestionElements:0,_selectedSuggestion:null,_previousTypedVal:null,suggest:function(b,d,e){var f={css:{maxHeight:"150px",background:"#FFF",lineHeight:"150%",textDecoration:"underline",overflowX:"hidden",overflowY:"auto",border:"#CCC solid 1px",borderTop:"none",cursor:"pointer"},activeSuggestionCSS:{background:"#E9E9E9"}},g=function(a,b){var c=b.offset();a.css({width:b.outerWidth(),left:c.left+"px",top:c.top+b.outerHeight()+"px"})};e&&a.extend(f,e),f.css.position="absolute",f.css["z-index"]=9999,b.attr("autocomplete","off"),0===this._numSuggestionElements&&c.bind("resize",function(){a(".jquery-form-suggestions").each(function(){var b=a(this),c=b.attr("data-suggest-container");g(b,a(".suggestions-"+c).eq(0))})}),this._numSuggestionElements++;var h=function(b){var c=b.valAttr("suggestion-nr");a.formUtils._selectedSuggestion=null,a.formUtils._previousTypedVal=null,a(".jquery-form-suggestion-"+c).fadeOut("fast")};return b.data("suggestions",d).valAttr("suggestion-nr",this._numSuggestionElements).unbind("focus.suggest").bind("focus.suggest",function(){a(this).trigger("keyup"),a.formUtils._selectedSuggestion=null}).unbind("keyup.suggest").bind("keyup.suggest",function(){var c=a(this),d=[],e=a.trim(c.val()).toLocaleLowerCase();if(e!==a.formUtils._previousTypedVal){a.formUtils._previousTypedVal=e;var i=!1,j=c.valAttr("suggestion-nr"),k=a(".jquery-form-suggestion-"+j);if(k.scrollTop(0),""!==e){var l=e.length>2;a.each(c.data("suggestions"),function(a,b){var c=b.toLocaleLowerCase();return c===e?(d.push("<strong>"+b+"</strong>"),i=!0,!1):void((0===c.indexOf(e)||l&&c.indexOf(e)>-1)&&d.push(b.replace(new RegExp(e,"gi"),"<strong>$&</strong>")))})}i||0===d.length&&k.length>0?k.hide():d.length>0&&0===k.length?(k=a("<div></div>").css(f.css).appendTo("body"),b.addClass("suggestions-"+j),k.attr("data-suggest-container",j).addClass("jquery-form-suggestions").addClass("jquery-form-suggestion-"+j)):d.length>0&&!k.is(":visible")&&k.show(),d.length>0&&e.length!==d[0].length&&(g(k,c),k.html(""),a.each(d,function(b,d){a("<div></div>").append(d).css({overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",padding:"5px"}).addClass("form-suggest-element").appendTo(k).click(function(){c.focus(),c.val(a(this).text()),c.trigger("change"),h(c)})}))}}).unbind("keydown.validation").bind("keydown.validation",function(b){var c,d,e=b.keyCode?b.keyCode:b.which,g=a(this);if(13===e&&null!==a.formUtils._selectedSuggestion){if(c=g.valAttr("suggestion-nr"),d=a(".jquery-form-suggestion-"+c),d.length>0){var i=d.find("div").eq(a.formUtils._selectedSuggestion).text();g.val(i),g.trigger("change"),h(g),b.preventDefault()}}else{c=g.valAttr("suggestion-nr"),d=a(".jquery-form-suggestion-"+c);var j=d.children();if(j.length>0&&a.inArray(e,[38,40])>-1){38===e?(null===a.formUtils._selectedSuggestion?a.formUtils._selectedSuggestion=j.length-1:a.formUtils._selectedSuggestion--,a.formUtils._selectedSuggestion<0&&(a.formUtils._selectedSuggestion=j.length-1)):40===e&&(null===a.formUtils._selectedSuggestion?a.formUtils._selectedSuggestion=0:a.formUtils._selectedSuggestion++,a.formUtils._selectedSuggestion>j.length-1&&(a.formUtils._selectedSuggestion=0));var k=d.innerHeight(),l=d.scrollTop(),m=d.children().eq(0).outerHeight(),n=m*a.formUtils._selectedSuggestion;return(n<l||n>l+k)&&d.scrollTop(n),j.removeClass("active-suggestion").css("background","none").eq(a.formUtils._selectedSuggestion).addClass("active-suggestion").css(f.activeSuggestionCSS),b.preventDefault(),!1}}}).unbind("blur.suggest").bind("blur.suggest",function(){h(a(this))}),b},LANG:{errorTitle:"Form submission failed!",requiredField:"This is a required field",requiredFields:"You have not answered all required fields",badTime:"You have not given a correct time",badEmail:"You have not given a correct e-mail address",badTelephone:"You have not given a correct phone number",badSecurityAnswer:"You have not given a correct answer to the security question",badDate:"You have not given a correct date",lengthBadStart:"The input value must be between ",lengthBadEnd:" characters",lengthTooLongStart:"The input value is longer than ",lengthTooShortStart:"The input value is shorter than ",notConfirmed:"Input values could not be confirmed",badDomain:"Incorrect domain value",badUrl:"The input value is not a correct URL",badCustomVal:"The input value is incorrect",andSpaces:" and spaces ",badInt:"The input value was not a correct number",badSecurityNumber:"Your social security number was incorrect",badUKVatAnswer:"Incorrect UK VAT Number",badUKNin:"Incorrect UK NIN",badUKUtr:"Incorrect UK UTR Number",badStrength:"The password isn't strong enough",badNumberOfSelectedOptionsStart:"You have to choose at least ",badNumberOfSelectedOptionsEnd:" answers",badAlphaNumeric:"The input value can only contain alphanumeric characters ",badAlphaNumericExtra:" and ",wrongFileSize:"The file you are trying to upload is too large (max %s)",wrongFileType:"Only files of type %s is allowed",groupCheckedRangeStart:"Please choose between ",groupCheckedTooFewStart:"Please choose at least ",groupCheckedTooManyStart:"Please choose a maximum of ",groupCheckedEnd:" item(s)",badCreditCard:"The credit card number is not correct",badCVV:"The CVV number was not correct",wrongFileDim:"Incorrect image dimensions,",imageTooTall:"the image can not be taller than",imageTooWide:"the image can not be wider than",imageTooSmall:"the image was too small",min:"min",max:"max",imageRatioNotAccepted:"Image ratio is not be accepted",badBrazilTelephoneAnswer:"The phone number entered is invalid",badBrazilCEPAnswer:"The CEP entered is invalid",badBrazilCPFAnswer:"The CPF entered is invalid",badPlPesel:"The PESEL entered is invalid",badPlNip:"The NIP entered is invalid",badPlRegon:"The REGON entered is invalid",badreCaptcha:"Please confirm that you are not a bot",passwordComplexityStart:"Password must contain at least ",passwordComplexitySeparator:", ",passwordComplexityUppercaseInfo:" uppercase letter(s)",passwordComplexityLowercaseInfo:" lowercase letter(s)",passwordComplexitySpecialCharsInfo:" special character(s)",passwordComplexityNumericCharsInfo:" numeric character(s)",passwordComplexityEnd:"."}})}(a,window),function(a){a.formUtils.addValidator({name:"email",validatorFunction:function(b){var c=b.toLowerCase().split("@"),d=c[0],e=c[1];if(d&&e){if(0===d.indexOf('"')){var f=d.length;if(d=d.replace(/\"/g,""),d.length!==f-2)return!1}return a.formUtils.validators.validate_domain.validatorFunction(c[1])&&0!==d.indexOf(".")&&"."!==d.substring(d.length-1,d.length)&&d.indexOf("..")===-1&&!/[^\w\+\.\-\#\-\_\~\!\$\&\'\(\)\*\+\,\;\=\:]/.test(d)}return!1},errorMessage:"",errorMessageKey:"badEmail"}),a.formUtils.addValidator({name:"domain",validatorFunction:function(a){return a.length>0&&a.length<=253&&!/[^a-zA-Z0-9]/.test(a.slice(-2))&&!/[^a-zA-Z0-9]/.test(a.substr(0,1))&&!/[^a-zA-Z0-9\.\-]/.test(a)&&1===a.split("..").length&&a.split(".").length>1},errorMessage:"",errorMessageKey:"badDomain"}),a.formUtils.addValidator({name:"required",validatorFunction:function(b,c,d,e,f){switch(c.attr("type")){case"checkbox":return c.is(":checked");case"radio":return f.find('input[name="'+c.attr("name")+'"]').filter(":checked").length>0;default:return""!==a.trim(b)}},errorMessage:"",errorMessageKey:function(a){return"top"===a.errorMessagePosition||"function"==typeof a.errorMessagePosition?"requiredFields":"requiredField"}}),a.formUtils.addValidator({name:"length",validatorFunction:function(b,c,d,e){var f=c.valAttr("length"),g=c.attr("type");if(void 0===f)return alert('Please add attribute "data-validation-length" to '+c[0].nodeName+" named "+c.attr("name")),!0;var h,i="file"===g&&void 0!==c.get(0).files?c.get(0).files.length:b.length,j=a.formUtils.numericRangeCheck(i,f);switch(j[0]){case"out":this.errorMessage=e.lengthBadStart+f+e.lengthBadEnd,h=!1;break;case"min":this.errorMessage=e.lengthTooShortStart+j[1]+e.lengthBadEnd,h=!1;break;case"max":this.errorMessage=e.lengthTooLongStart+j[1]+e.lengthBadEnd,h=!1;break;default:h=!0}return h},errorMessage:"",errorMessageKey:""}),a.formUtils.addValidator({name:"url",validatorFunction:function(b){var c=/^(https?|ftp):\/\/((((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|\[|\]|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;if(c.test(b)){var d=b.split("://")[1],e=d.indexOf("/");return e>-1&&(d=d.substr(0,e)),a.formUtils.validators.validate_domain.validatorFunction(d)}return!1},errorMessage:"",errorMessageKey:"badUrl"}),a.formUtils.addValidator({name:"number",validatorFunction:function(a,b,c){if(""!==a){var d,e,f=b.valAttr("allowing")||"",g=b.valAttr("decimal-separator")||c.decimalSeparator,h=!1,i=b.valAttr("step")||"",j=!1,k=b.attr("data-sanitize")||"",l=k.match(/(^|[\s])numberFormat([\s]|$)/i);if(l){if(!window.numeral)throw new ReferenceError("The data-sanitize value numberFormat cannot be used without the numeral library. Please see Data Validation in http://www.formvalidator.net for more information.");a.length&&(a=String(numeral().unformat(a)))}if(f.indexOf("number")===-1&&(f+=",number"),f.indexOf("negative")===-1&&0===a.indexOf("-"))return!1;if(f.indexOf("range")>-1&&(d=parseFloat(f.substring(f.indexOf("[")+1,f.indexOf(";"))),e=parseFloat(f.substring(f.indexOf(";")+1,f.indexOf("]"))),h=!0),""!==i&&(j=!0),","===g){if(a.indexOf(".")>-1)return!1;a=a.replace(",",".")}if(""===a.replace(/[0-9-]/g,"")&&(!h||a>=d&&a<=e)&&(!j||a%i===0))return!0;if(f.indexOf("float")>-1&&null!==a.match(new RegExp("^([0-9-]+)\\.([0-9]+)$"))&&(!h||a>=d&&a<=e)&&(!j||a%i===0))return!0}return!1},errorMessage:"",errorMessageKey:"badInt"}),a.formUtils.addValidator({name:"alphanumeric",validatorFunction:function(b,c,d,e){var f="^([a-zA-Z0-9",g="]+)$",h=c.valAttr("allowing"),i="",j=!1;if(h){i=f+h+g;var k=h.replace(/\\/g,"");k.indexOf(" ")>-1&&(j=!0,k=k.replace(" ",""),k+=e.andSpaces||a.formUtils.LANG.andSpaces),e.badAlphaNumericAndExtraAndSpaces&&e.badAlphaNumericAndExtra?j?this.errorMessage=e.badAlphaNumericAndExtraAndSpaces+k:this.errorMessage=e.badAlphaNumericAndExtra+k+e.badAlphaNumericExtra:this.errorMessage=e.badAlphaNumeric+e.badAlphaNumericExtra+k;
10
+ }else i=f+g,this.errorMessage=e.badAlphaNumeric;return new RegExp(i).test(b)},errorMessage:"",errorMessageKey:""}),a.formUtils.addValidator({name:"custom",validatorFunction:function(a,b){var c=new RegExp(b.valAttr("regexp"));return c.test(a)},errorMessage:"",errorMessageKey:"badCustomVal"}),a.formUtils.addValidator({name:"date",validatorFunction:function(b,c,d){var e=c.valAttr("format")||d.dateFormat||"yyyy-mm-dd",f="false"===c.valAttr("require-leading-zero");return a.formUtils.parseDate(b,e,f)!==!1},errorMessage:"",errorMessageKey:"badDate"}),a.formUtils.addValidator({name:"checkbox_group",validatorFunction:function(b,c,d,e,f){var g=!0,h=c.attr("name"),i=a('input[type=checkbox][name^="'+h+'"]',f),j=i.filter(":checked").length,k=c.valAttr("qty");if(void 0===k){var l=c.get(0).nodeName;alert('Attribute "data-validation-qty" is missing from '+l+" named "+c.attr("name"))}var m=a.formUtils.numericRangeCheck(j,k);switch(m[0]){case"out":this.errorMessage=e.groupCheckedRangeStart+k+e.groupCheckedEnd,g=!1;break;case"min":this.errorMessage=e.groupCheckedTooFewStart+m[1]+(e.groupCheckedTooFewEnd||e.groupCheckedEnd),g=!1;break;case"max":this.errorMessage=e.groupCheckedTooManyStart+m[1]+(e.groupCheckedTooManyEnd||e.groupCheckedEnd),g=!1;break;default:g=!0}if(!g){var n=function(){i.unbind("click",n),i.filter("*[data-validation]").validateInputOnBlur(e,d,!1,"blur")};i.bind("click",n)}return g}})}(a)});
js/third-party/jquery.modal.min.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ /*
2
+ A simple jQuery modal (http://github.com/kylefox/jquery-modal)
3
+ Version 0.9.1
4
+ */
5
+ !function(o){"object"==typeof module&&"object"==typeof module.exports?o(require("jquery"),window,document):o(jQuery,window,document)}(function(o,t,i,e){var s=[],l=function(){return s.length?s[s.length-1]:null},n=function(){var o,t=!1;for(o=s.length-1;o>=0;o--)s[o].$blocker&&(s[o].$blocker.toggleClass("current",!t).toggleClass("behind",t),t=!0)};o.modal=function(t,i){var e,n;if(this.$body=o("body"),this.options=o.extend({},o.modal.defaults,i),this.options.doFade=!isNaN(parseInt(this.options.fadeDuration,10)),this.$blocker=null,this.options.closeExisting)for(;o.modal.isActive();)o.modal.close();if(s.push(this),t.is("a"))if(n=t.attr("href"),this.anchor=t,/^#/.test(n)){if(this.$elm=o(n),1!==this.$elm.length)return null;this.$body.append(this.$elm),this.open()}else this.$elm=o("<div>"),this.$body.append(this.$elm),e=function(o,t){t.elm.remove()},this.showSpinner(),t.trigger(o.modal.AJAX_SEND),o.get(n).done(function(i){if(o.modal.isActive()){t.trigger(o.modal.AJAX_SUCCESS);var s=l();s.$elm.empty().append(i).on(o.modal.CLOSE,e),s.hideSpinner(),s.open(),t.trigger(o.modal.AJAX_COMPLETE)}}).fail(function(){t.trigger(o.modal.AJAX_FAIL);var i=l();i.hideSpinner(),s.pop(),t.trigger(o.modal.AJAX_COMPLETE)});else this.$elm=t,this.anchor=t,this.$body.append(this.$elm),this.open()},o.modal.prototype={constructor:o.modal,open:function(){var t=this;this.block(),this.anchor.blur(),this.options.doFade?setTimeout(function(){t.show()},this.options.fadeDuration*this.options.fadeDelay):this.show(),o(i).off("keydown.modal").on("keydown.modal",function(o){var t=l();27===o.which&&t.options.escapeClose&&t.close()}),this.options.clickClose&&this.$blocker.click(function(t){t.target===this&&o.modal.close()})},close:function(){s.pop(),this.unblock(),this.hide(),o.modal.isActive()||o(i).off("keydown.modal")},block:function(){this.$elm.trigger(o.modal.BEFORE_BLOCK,[this._ctx()]),this.$body.css("overflow","hidden"),this.$blocker=o('<div class="'+this.options.blockerClass+' blocker current"></div>').appendTo(this.$body),n(),this.options.doFade&&this.$blocker.css("opacity",0).animate({opacity:1},this.options.fadeDuration),this.$elm.trigger(o.modal.BLOCK,[this._ctx()])},unblock:function(t){!t&&this.options.doFade?this.$blocker.fadeOut(this.options.fadeDuration,this.unblock.bind(this,!0)):(this.$blocker.children().appendTo(this.$body),this.$blocker.remove(),this.$blocker=null,n(),o.modal.isActive()||this.$body.css("overflow",""))},show:function(){this.$elm.trigger(o.modal.BEFORE_OPEN,[this._ctx()]),this.options.showClose&&(this.closeButton=o('<a href="#close-modal" rel="modal:close" class="close-modal '+this.options.closeClass+'">'+this.options.closeText+"</a>"),this.$elm.append(this.closeButton)),this.$elm.addClass(this.options.modalClass).appendTo(this.$blocker),this.options.doFade?this.$elm.css({opacity:0,display:"inline-block"}).animate({opacity:1},this.options.fadeDuration):this.$elm.css("display","inline-block"),this.$elm.trigger(o.modal.OPEN,[this._ctx()])},hide:function(){this.$elm.trigger(o.modal.BEFORE_CLOSE,[this._ctx()]),this.closeButton&&this.closeButton.remove();var t=this;this.options.doFade?this.$elm.fadeOut(this.options.fadeDuration,function(){t.$elm.trigger(o.modal.AFTER_CLOSE,[t._ctx()])}):this.$elm.hide(0,function(){t.$elm.trigger(o.modal.AFTER_CLOSE,[t._ctx()])}),this.$elm.trigger(o.modal.CLOSE,[this._ctx()])},showSpinner:function(){this.options.showSpinner&&(this.spinner=this.spinner||o('<div class="'+this.options.modalClass+'-spinner"></div>').append(this.options.spinnerHtml),this.$body.append(this.spinner),this.spinner.show())},hideSpinner:function(){this.spinner&&this.spinner.remove()},_ctx:function(){return{elm:this.$elm,$elm:this.$elm,$blocker:this.$blocker,options:this.options}}},o.modal.close=function(t){if(o.modal.isActive()){t&&t.preventDefault();var i=l();return i.close(),i.$elm}},o.modal.isActive=function(){return s.length>0},o.modal.getCurrent=l,o.modal.defaults={closeExisting:!0,escapeClose:!0,clickClose:!0,closeText:"Close",closeClass:"",modalClass:"modal",blockerClass:"jquery-modal",spinnerHtml:'<div class="rect1"></div><div class="rect2"></div><div class="rect3"></div><div class="rect4"></div>',showSpinner:!0,showClose:!0,fadeDuration:null,fadeDelay:1},o.modal.BEFORE_BLOCK="modal:before-block",o.modal.BLOCK="modal:block",o.modal.BEFORE_OPEN="modal:before-open",o.modal.OPEN="modal:open",o.modal.BEFORE_CLOSE="modal:before-close",o.modal.CLOSE="modal:close",o.modal.AFTER_CLOSE="modal:after-close",o.modal.AJAX_SEND="modal:ajax:send",o.modal.AJAX_SUCCESS="modal:ajax:success",o.modal.AJAX_FAIL="modal:ajax:fail",o.modal.AJAX_COMPLETE="modal:ajax:complete",o.fn.modal=function(t){return 1===this.length&&new o.modal(this,t),this},o(i).on("click.modal",'a[rel~="modal:close"]',o.modal.close),o(i).on("click.modal",'a[rel~="modal:open"]',function(t){t.preventDefault(),o(this).modal()})});
main-plugin-file-sketch.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ defined( 'ABSPATH' ) or die( 'Direct access not allowed!' );
4
+
5
+ if ( ! class_exists( 'GaEvents' ) ) {
6
+
7
+ class GaEvents {
8
+
9
+ function ga_events_install() {
10
+
11
+ // intial values for plugin options
12
+ $ga_events_options = array(
13
+ 'link_clicks_delay' => 0,
14
+ 'gtm' => false,
15
+ 'anonymizeip' => false,
16
+ 'advanced' => false,
17
+ 'snippet_type' => 'universal',
18
+ 'id' => '',
19
+ 'license' => '',
20
+ 'status' => '',
21
+ 'gtm_id' => '',
22
+ 'domain' => '',
23
+ // Roles for which tracking is disabled
24
+ 'excluded_roles' => array(),
25
+ 'nofollow_links' => array(),
26
+ 'scroll_track_elements' => array(),
27
+ 'click_track_elements' => array(),
28
+ 'youtube_videos' => array(),
29
+ 'vimeo_videos' => array(),
30
+ // Roles with permission to modify plugin options
31
+ 'roles' => array( 'administrator' ),
32
+ 'link_tracking' => array(
33
+ 'track' => false,
34
+ 'type' => "all",
35
+ 'class' => ''
36
+ ),
37
+ );
38
+ }
39
+
40
+ }
41
+ }
plugin-general-settings.png ADDED
Binary file
readme.txt CHANGED
@@ -1,44 +1,59 @@
1
  === WP Google Analytics Events ===
2
  Contributors: yuvalo
3
  Tags: analytics, google, events, ga, google analytics, tracking
4
- Tested up to: 5.2.4
5
- Stable tag: 2.5.5
6
  License: GPLv2
7
  Requires at least: 3.0
8
 
9
  Track Google Analytics Events on your website - Enables you to send an event when a user Scrolls or Click an element on your website.
10
  == Description ==
11
- The WP Google Analytics Events plugin allows you to send events to Google Analytics when:
12
 
13
- 1. A user scrolls to a point of interest on your site
14
- 2. Clicking elements on the page, such as buttons or Ajax submit forms.
15
 
16
- For example, create a Google Analytics event when a visitor scrolled down and viewed your pricing table. Track Video Plays and banner clicks.
17
- Get to know what your visitors are doing on the website.
18
 
19
- And best of all - No Coding Required
 
20
 
 
 
21
 
22
- https://www.youtube.com/watch?v=5jKWlRiwKzU
23
 
24
- Events were introduced by Google Analytics to allow tracking of custom metrics that were not based on page views.
25
- Tracking events is usually done by writing JavaScript code, and that is not the WordPress way.
26
- We created this plugin, so you can use this feature without writing a line of code.
 
 
 
 
 
 
 
 
 
27
 
28
- There are many benefits for using events, and you can get very creative:
29
 
30
  1. Setting event-driven goals in Google Analytics
31
- 2. Tracking in page navigation
32
  3. Comparing call to action button performance
33
  4. Understanding what percentage of your visitors got to the end of an article
34
  5. Tracking contact form submissions
35
  6. Track Links
36
- 7. Google Tag Manager Support
37
-
38
 
39
- If you want to learn more about Event Tracking or how to use this plugin, visit our documentation page here -
40
-
41
- [Plugin Documentation](http://wpflow.com/documentation/ "Documentation")
 
 
 
 
 
 
42
 
43
 
44
  == Installation ==
@@ -85,11 +100,17 @@ If you are looking for more in-depth support, we encourage you to check out [WP
85
 
86
 
87
  == Screenshots ==
88
- 1. Plugin General Settings screenshot-3.png
89
- 2. Plugin Click Settings screenshot-4.png
90
- 3. Plugin Scroll Settings screenshot-5.png
91
- 2. Google Analytics real time events screenshot-2.png
 
92
  == Changelog ==
 
 
 
 
 
93
 
94
  = Version 2.5.5 =
95
  1. Fixed an admin panel conflict
1
  === WP Google Analytics Events ===
2
  Contributors: yuvalo
3
  Tags: analytics, google, events, ga, google analytics, tracking
4
+ Tested up to: 5.3
5
+ Stable tag: 2.6.0
6
  License: GPLv2
7
  Requires at least: 3.0
8
 
9
  Track Google Analytics Events on your website - Enables you to send an event when a user Scrolls or Click an element on your website.
10
  == Description ==
11
+ > "Analytics is about tracking the metrics that are critical to your business" - Lean Analytics
12
 
13
+ With WP Google Analytics Events, you don't have to write code to use Events in Google Analytics.
 
14
 
15
+ The plugin allows you to fire events whenever someone interacts or views elements on your website.
16
+ You can create a Google Analytics event when a visitor scrolls down and views your pricing table. Track video, banners, Call to Action buttons, email links, and more.
17
 
18
+ If you really want to know what people are doing on your website, the default options are limited when it comes to in-page tracking in Google Analytics.
19
+ Page tracking is not enough these days, and if you want to match measurable metrics for your KPIs, its necessary to use events.
20
 
21
+ Tracking events is usually done by writing JavaScript code, and that is not the WordPress way.
22
+ That's why we created WP Google Analytics Events, so you don't have to write elaborate code every time you want to learn something new about your visitors.
23
 
 
24
 
25
+ > **Become a Pro**
26
+ > WP Google Analytics Events Pro is the professional version of our plugin and adds more tracking capabilities:
27
+ >
28
+ > * One-Click Link Tracking
29
+ > * Placeholders to enrich your event data
30
+ > * Track Self-Hosted Media audio and video
31
+ > * YouTube and Vimeo support
32
+ > * Plugin Management permissions for teams
33
+ > * Access to our Pro support team
34
+ > [ ** Check out the Pro version** ](https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=wporg)
35
+
36
+ https://www.youtube.com/watch?v=5jKWlRiwKzU
37
 
38
+ Here are some of the things you can do with WP Google Analytics Events:
39
 
40
  1. Setting event-driven goals in Google Analytics
41
+ 2. Tracking in-page navigation
42
  3. Comparing call to action button performance
43
  4. Understanding what percentage of your visitors got to the end of an article
44
  5. Tracking contact form submissions
45
  6. Track Links
46
+ 7. We work along with Google Tag Manager and will allow you to do things it can't do out of the box.
 
47
 
48
+ ## Documentation
49
+ * [What is event tracking?](https://wpflow.com/what-is-google-analytics-event-tracking/)
50
+ * [Basic Configuration](https://wpflow.com/knowledgebase/basic-configuration/)
51
+ * [How To Use WP Google Analytics Events Click Tracking Tab](https://wpflow.com/knowledgebase/use-wp-google-analytics-events-click-tracking-tab/)
52
+ * [Scroll Tracking](https://wpflow.com/knowledgebase/scroll-tracking/)
53
+ * [Google Tag Manager Support](https://wpflow.com/knowledgebase/google-tag-manager-support/)
54
+ * [Advanced Mode](https://wpflow.com/knowledgebase/advanced-mode/)
55
+ * [Tracking Email and Telephone Links](https://wpflow.com/knowledgebase/can-track-mailto-tel-links-google-analytics/)
56
+ * [Tracking PDF Downloads](https://wpflow.com/knowledgebase/track-pdf-downloads/)
57
 
58
 
59
  == Installation ==
100
 
101
 
102
  == Screenshots ==
103
+ 1. Plugin General Settings screenshot-1.png
104
+ 2. Plugin Click Settings screenshot-2.png
105
+ 3. Plugin Scroll Settings screenshot-3.png
106
+ 2. Google Analytics real time events screenshot-4.png
107
+
108
  == Changelog ==
109
+ = Version 2.6.0 =
110
+ 1. Complete plugin rewrite
111
+ 2. New user interface for click and scroll tracking settings
112
+ 3. Better Google Analytics code snippet support
113
+ 5. Minify JavaScript option added
114
 
115
  = Version 2.5.5 =
116
  1. Fixed an admin panel conflict
screenshot-1.png DELETED
Binary file
screenshot-2.png DELETED
Binary file
screenshot-3.png DELETED
Binary file
screenshot-4.png DELETED
Binary file
screenshot-5.png DELETED
Binary file
scroll-tracking-page.png ADDED
Binary file
templates/click-elements-input-table.php ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if( ! class_exists( 'WPGAE_Tracking_Table' ) ) {
3
+ require_once( GAE_PLUGIN_PATH . 'include/TrackingTable.php' );
4
+ }
5
+
6
+
7
+ class ClickTracking_Table extends WPGAE_Tracking_Table {
8
+ /** Class constructor */
9
+ public function __construct() {
10
+
11
+ parent::__construct( array(
12
+ 'singular' => __( 'ClickEvent', 'sp' ), //singular name of the listed records
13
+ 'plural' => __( 'ClickEvent', 'sp' ), //plural name of the listed records
14
+ 'ajax' => true //does this table support ajax?
15
+ ) );
16
+
17
+ $this->wpgae_post_type = WPGAEGClickEvent::get_wpgae_post_type();
18
+ $this->wpgae_post_columns = WPGAEGClickEvent::get_wpgae_post_columns();
19
+ $this->wpgae_first_column = "_wpgae_click_selector_meta_key";
20
+ }
21
+
22
+ function column__wpgae_click_selector_meta_key($item) {
23
+ $actions = array(
24
+ 'edit' => sprintf('<a id="%s" data-action="wpgae-edit-click-event" href="">Edit</a>',$item->ID),
25
+ 'delete' => sprintf('<a id="%s" data-action="wpgae-delete-click-event" href="">Delete</a>',$item->ID),
26
+ );
27
+
28
+ return sprintf('%1$s %2$s', $this->getColumnData($item, "_wpgae_click_selector_meta_key"), $this->row_actions($actions) );
29
+ }
30
+ }
31
+
32
+
33
+ $clickTracking = new ClickTracking_Table();
34
+ $wpgae_options = get_option('ga_events_options');
35
+
36
+ ?>
37
+ <div class="wrap">
38
+ <div id="icon-users" class="icon32"></div>
39
+ <h2>Click Tracking <a href="#wpgae-add-click-event" rel="modal:open" class="page-title-action">Add New</a></h2>
40
+ <?php
41
+ $clickTracking->prepare_items();
42
+ ?>
43
+ <form method="post">
44
+ <input type="hidden" name="page" value="my_list_test" />
45
+ <?php $clickTracking->search_box('search', 'search_id'); ?>
46
+ </form>
47
+ <form method="post">
48
+ <?php
49
+ $clickTracking->display();
50
+ ?>
51
+ </form>
52
+ </div>
53
+ <div class="wrap ga_events_banner ga_events_top">
54
+ <div class="ga_events_featurebox ga_events_box_general">
55
+ <div class="ga_events_box_title">
56
+ <span>
57
+ Become a Pro
58
+ </span>
59
+ </div>
60
+ <div class="ga_events_box_body">
61
+ <ul class="ga_events_box_list">
62
+ <li>
63
+ <div class="ga_events_box_li_icon">
64
+ <img src="<?php echo plugins_url( 'images/icon_block.png', dirname(__FILE__)) ?>" />
65
+ </div>
66
+ <div class="ga_events_box_li_content">
67
+ <span class="ga_events_box_li_title">Link Tracking</span>
68
+ <span class="ga_events_box_li_txt">Automatically track any link on your website</span>
69
+ </div>
70
+ </li>
71
+ <li>
72
+ <div class="ga_events_box_li_icon">
73
+ <img src="<?php echo plugins_url( 'images/icon_block.png', dirname(__FILE__)) ?>" />
74
+ </div>
75
+ <div class="ga_events_box_li_content">
76
+ <span class="ga_events_box_li_title">Placeholder Variables</span>
77
+ <span class="ga_events_box_li_txt">Include dynamic information in your events</span>
78
+ </div>
79
+ </li>
80
+ <li>
81
+ <div class="ga_events_box_li_icon">
82
+ <img src="<?php echo plugins_url( 'images/icon_block.png', dirname(__FILE__)) ?>" />
83
+ </div>
84
+ <div class="ga_events_box_li_content">
85
+ <span class="ga_events_box_li_title">User Permissions</span>
86
+ <span class="ga_events_box_li_txt">Allow non Administrators to manage the plugin</span>
87
+ </div>
88
+ </li>
89
+ </ul>
90
+ </div>
91
+ <div>
92
+ <a class="btn" target="_blank" href="https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=btng">Go Pro</a>
93
+ </div>
94
+ </div>
95
+ <div class="ga_events_featurebox ga_events_box_video">
96
+ <div class="ga_events_box_title">
97
+ <span>
98
+ Track Videos like a Pro
99
+ </span>
100
+ </div>
101
+ <div class="ga_events_box_body">
102
+ <ul class="ga_events_box_list">
103
+ <li>
104
+ <div class="ga_events_box_li_icon">
105
+ <img src="<?php echo plugins_url( 'images/icon_lock.png', dirname(__FILE__)) ?>" />
106
+ </div>
107
+ <div class="ga_events_box_li_content">
108
+ <span class="ga_events_box_li_title">YouTube Video Tracking</span>
109
+ <span class="ga_events_box_li_txt">Track all video play/stop events and make
110
+ smarter segments on how people watch your content.</span>
111
+ </div>
112
+ </li>
113
+ <li>
114
+ <div class="ga_events_box_li_icon" style="margin-top:10px">
115
+ <img src="<?php echo plugins_url( 'images/icon_lock.png', dirname(__FILE__)) ?>" />
116
+ </div>
117
+ <div class="ga_events_box_li_content" style="margin-top:10px">
118
+ <span class="ga_events_box_li_title">Vimeo Video support</span>
119
+ <span class="ga_events_box_li_txt">And yes, you can also track Vimeo videos</span>
120
+ </div>
121
+ </li>
122
+ </ul>
123
+ </div>
124
+ <a class="btn" target="_blank" href="https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=btnv">Go Premium</a>
125
+ </div>
126
+ <div class="ga_events_featurebox ga_events_box_support">
127
+ <div class="ga_events_box_title">
128
+ <span>
129
+ Product Support
130
+ </span>
131
+ </div>
132
+ <div class="ga_events_box_body">
133
+ <ul class="ga_events_box_list">
134
+ <li>
135
+ <div class="ga_events_box_li_content">
136
+ <span class="ga_events_box_li_title" style="margin-left:40px;">Premium Support</span>
137
+ <span class="ga_events_box_li_txt" style="margin-left:40px;">Direct super-fast help from our dedicated support team</span>
138
+ </div>
139
+ </li>
140
+ </ul>
141
+ </div>
142
+ <a class="btn" target="_blank" href="https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=btns">Get Pro Support</a>
143
+ </div>
144
+ </div>
145
+ <?php
146
+ require_once( GAE_PLUGIN_PATH . '/templates/click-tracking-modals.php' );
147
+
templates/click-tracking-modals.php ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ ?>
3
+ <!-- Modal HTML embedded directly into document -->
4
+ <div id="wpgae-add-click-event" class="modal">
5
+ <h2>Add Click Event</h2>
6
+ <form id="wpgae-add-event" class="wpgae-event-form">
7
+ <div>
8
+ <div class="postbox wpga_meta">
9
+ <div class="inside">
10
+ <div class="wpgae_event_form_fields">
11
+ <label for="_wpgae_click_selector_meta_key">Selector</label>
12
+ <input name="_wpgae_click_selector_meta_key" required id="_wpgae_click_selector_meta_key" class="postbox" value="">
13
+ </div>
14
+ <div class="wpgae_event_form_fields">
15
+ <label for="_wpgae_click_type_meta_key">Selector Type</label>
16
+ <select name="_wpgae_click_type_meta_key" id="_wpgae_click_type_meta_key">
17
+ <option value="id">id</option>
18
+ <option value="class">class</option>
19
+ <?php if (isset($wpgae_options['advanced']) && $wpgae_options["advanced"] == 1) {
20
+ ?>
21
+ <option value="advanced">advanced</option> ?>
22
+ <?php } ?>
23
+ </select>
24
+ </div>
25
+ <div class="wpgae_event_form_fields">
26
+ <label for="_wpgae_click_category_meta_key">Event Category</label>
27
+ <input name="_wpgae_click_category_meta_key" id="_wpgae_click_category_meta_key" class="postbox" value="">
28
+ </div>
29
+ <div class="wpgae_event_form_fields">
30
+ <label for="_wpgae_click_action_meta_key">Event Action</label>
31
+ <input name="_wpgae_click_action_meta_key" id="_wpgae_click_action_meta_key" class="postbox" value="">
32
+ </div>
33
+ <div class="wpgae_event_form_fields">
34
+ <label for="_wpgae_click_label_meta_key">Event Label</label>
35
+ <input name="_wpgae_click_label_meta_key" id="_wpgae_click_label_meta_key" class="postbox" value="">
36
+ </div>
37
+ <div class="wpgae_event_form_fields">
38
+ <label for="_wpgae_click_value_meta_key">Event Value</label>
39
+ <input name="_wpgae_click_value_meta_key" id="_wpgae_click_value_meta_key" class="postbox" type="number" value="" >
40
+ </div>
41
+ <div class="wpgae_event_form_fields">
42
+ <label for="_wpgae_click_bounce_meta_key">Non-Interaction</label>
43
+ <select name="_wpgae_click_bounce_meta_key" id="_wpgae_click_bounce_meta_key">
44
+ <option value="true" selected="true">true</option>
45
+ <option value="false">false</option>
46
+ </select>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <div id="wpgae_form_buttons">
52
+ <?php wp_nonce_field("wpflow_add_event", "ajax_nonce"); ?>
53
+ <input type="hidden" name="action" value="wpflow_add_event">
54
+ <input type="hidden" name="wpgae_type" value="wpgae_click_event">
55
+ <a class="button-secondary" href="#" rel="modal:close">Cancel</a>
56
+ <input type="submit" class="button-primary" value="Add Click Event">
57
+ </div>
58
+ </form>
59
+ </div>
60
+
61
+
62
+ <!-- Modal HTML embedded directly into document -->
63
+ <div id="wpgae-edit-click-event" class="modal">
64
+ <h2>Edit Click Event</h2>
65
+ <form id="wpgae-edit-event" class="wpgae-event-form">
66
+ <div>
67
+ <div class="wpga_meta postbox ">
68
+ <div class="inside">
69
+ <div class="wpgae_event_form_fields">
70
+ <label for="_wpgae_click_selector_meta_key">Selector</label>
71
+ <input name="_wpgae_click_selector_meta_key" required id="_wpgae_click_selector_meta_key" class="postbox" value="">
72
+ </div>
73
+ <div class="wpgae_event_form_fields">
74
+ <label for="_wpgae_click_type_meta_key">Selector Type</label>
75
+ <select name="_wpgae_click_type_meta_key" id="_wpgae_click_type_meta_key">
76
+ <option value="id">id</option>
77
+ <option value="class">class</option>
78
+ <?php if (isset($wpgae_options['advanced']) && $wpgae_options["advanced"] == 1) {
79
+ ?>
80
+ <option value="advanced">advanced</option>
81
+ <?php } ?>
82
+ </select>
83
+ </div>
84
+ <div class="wpgae_event_form_fields">
85
+ <label for="_wpgae_click_category_meta_key">Event Category</label>
86
+ <input name="_wpgae_click_category_meta_key" id="_wpgae_click_category_meta_key" class="postbox" value="">
87
+ </div>
88
+ <div class="wpgae_event_form_fields">
89
+ <label for="_wpgae_click_action_meta_key">Event Action</label>
90
+ <input name="_wpgae_click_action_meta_key" id="_wpgae_click_action_meta_key" class="postbox" value="">
91
+ </div>
92
+ <div class="wpgae_event_form_fields">
93
+ <label for="_wpgae_click_label_meta_key">Event Label</label>
94
+ <input name="_wpgae_click_label_meta_key" id="_wpgae_click_label_meta_key" class="postbox" value="">
95
+ </div>
96
+ <div class="wpgae_event_form_fields">
97
+ <label for="_wpgae_click_value_meta_key">Event Value</label>
98
+ <input name="_wpgae_click_value_meta_key" id="_wpgae_click_value_meta_key" class="postbox" type="number" value="">
99
+ </div>
100
+ <div class="wpgae_event_form_fields">
101
+ <label for="_wpgae_click_bounce_meta_key">Non-Interaction</label>
102
+ <select name="_wpgae_click_bounce_meta_key" id="_wpgae_click_bounce_meta_key">
103
+ <option value="true" selected="true">true</option>
104
+ <option value="false">false</option>
105
+ </select>
106
+ </div>
107
+ </div>
108
+ </div>
109
+ </div>
110
+ <div id="wpgae_form_buttons">
111
+ <?php wp_nonce_field("wpflow_add_event", "ajax_nonce"); ?>
112
+ <input type="hidden" name="action" value="wpflow_edit_event">
113
+ <input type="hidden" name="event_id" id="event_id" value="">
114
+ <a class="button-secondary" href="#" rel="modal:close">Cancel</a>
115
+ <input type="submit" class="button-primary" value="Save Click Event">
116
+ </div>
117
+ </form>
118
+ </div>
119
+
120
+ <!-- Modal HTML embedded directly into document -->
121
+ <div id="wpgae-delete-click-event" class="modal">
122
+ <h2>You are about to delete a Click Event</h2>
123
+ <form id="wpgae-delete-event" class="wpgae-event-form">
124
+ <div>
125
+ <div class="wpga_meta postbox ">
126
+ <div class="inside">
127
+ <fieldset disabled>
128
+ <div class="wpgae_event_form_fields">
129
+ <label for="wpgae_event_selector">Selector</label>
130
+ <input name="_wpgae_click_selector_meta_key" id="_wpgae_click_selector_meta_key" class="postbox" value="">
131
+ </div>
132
+ <div class="wpgae_event_form_fields">
133
+ <label for="_wpgae_click_type_meta_key">Selector Type</label>
134
+ <select name="_wpgae_click_type_meta_key" id="_wpgae_click_type_meta_key">
135
+ <option value="id">id</option>
136
+ <option value="class">class</option>
137
+ <?php if (isset($wpgae_options['advanced']) && $wpgae_options["advanced"] == 1) {
138
+ ?>
139
+ <option value="advanced">advanced</option>
140
+ <?php } ?>
141
+ </select>
142
+ </div>
143
+ <div class="wpgae_event_form_fields">
144
+ <label for="_wpgae_click_category_meta_key">Event Category</label>
145
+ <input name="_wpgae_click_category_meta_key" id="_wpgae_click_category_meta_key" class="postbox" value="">
146
+ </div>
147
+ <div class="wpgae_event_form_fields">
148
+ <label for="_wpgae_click_action_meta_key">Event Action</label>
149
+ <input name="_wpgae_click_action_meta_key" id="_wpgae_click_action_meta_key" class="postbox" value="">
150
+ </div>
151
+ <div class="wpgae_event_form_fields">
152
+ <label for="_wpgae_click_label_meta_key">Event Label</label>
153
+ <input name="_wpgae_click_label_meta_key" id="_wpgae_click_label_meta_key" class="postbox" value="">
154
+ </div>
155
+ <div class="wpgae_event_form_fields">
156
+ <label for="_wpgae_click_value_meta_key">Event Value</label>
157
+ <input name="_wpgae_click_value_meta_key" id="_wpgae_click_value_meta_key" class="postbox" type="number" value="">
158
+ </div>
159
+ <div class="wpgae_event_form_fields">
160
+ <label for="_wpgae_click_bounce_meta_key">Non-Interaction</label>
161
+ <select name="_wpgae_click_bounce_meta_key" id="_wpgae_click_bounce_meta_key">
162
+ <option value="true" selected="true">true</option>
163
+ <option value="false">false</option>
164
+ </select>
165
+ </div>
166
+ </fieldset>
167
+ </div>
168
+ </div>
169
+ </div>
170
+ <div id="wpgae_form_buttons">
171
+ <?php wp_nonce_field("wpflow_add_event", "ajax_nonce"); ?>
172
+ <input type="hidden" name="action" value="wpflow_delete_event">
173
+ <input type="hidden" name="event_id" id="event_id" value="">
174
+ <input type="submit" class="button button-large butotn-secondary delete" value="Delete Click Event">
175
+ <a class="button button-secondary button-large" href="#" rel="modal:close">Cancel</a>
176
+ </div>
177
+ </form>
178
+ </div>
179
+
templates/getting-started-guide-section.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <h2>Getting Started Guide</h2>
2
+ <form action="https://www.getdrip.com/forms/4588171/submissions" method="post" data-drip-embedded-form="4588171">
3
+ <div style="background:white; line-height:20px; padding: 5px 15px 15px 15px;
4
+ font-size: 15px; max-width:400px;">
5
+
6
+ <h3 style="margin-top: 10px;" data-drip-attribute="headline">Want to learn more about event tracking?</h3>
7
+ <div data-drip-attribute="description">Now that you installed the plugin, we want to help you get everything up and running.&nbsp;<br />
8
+ Join our short email course and get started with event tracking.</div>
9
+ <div>
10
+ <label style="margin-top:10px;"for="fields[email]">Email Address:</label><br />
11
+ <input type="email" name="fields[email]" value="" />
12
+ </div>
13
+ <div>
14
+ <input style="margin-top:15px;" class="button-primary" type="submit" name="submit" value="Get Started" data-drip-attribute="sign-up-button" />
15
+ </div>
16
+ </div>
17
+ </form>
templates/scroll-elements-input-table.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if( ! class_exists( 'WPGAE_Tracking_Table' ) ) {
3
+ require_once( GAE_PLUGIN_PATH . 'include/TrackingTable.php' );
4
+ }
5
+
6
+
7
+ class ScrollTracking_Table extends WPGAE_Tracking_Table {
8
+ /** Class constructor */
9
+ public function __construct() {
10
+
11
+ parent::__construct( array(
12
+ 'singular' => __( 'ScrollEvent', 'sp' ), //singular name of the listed records
13
+ 'plural' => __( 'ScrollEvent', 'sp' ), //plural name of the listed records
14
+ 'ajax' => true //does this table support ajax?
15
+ ));
16
+
17
+ $this->wpgae_post_type = WPGAEGScrollEvent::get_wpgae_post_type();
18
+ $this->wpgae_post_columns = WPGAEGScrollEvent::get_wpgae_post_columns();
19
+ $this->wpgae_first_column = "_wpgae_scroll_selector_meta_key";
20
+
21
+ }
22
+
23
+ function column__wpgae_scroll_selector_meta_key($item) {
24
+ $actions = array(
25
+ 'edit' => sprintf('<a id="%s" data-action="wpgae-edit-scroll-event" href="">Edit</a>',$item->ID),
26
+ 'delete' => sprintf('<a id="%s" data-action="wpgae-delete-scroll-event" href="">Delete</a>',$item->ID),
27
+ );
28
+
29
+ return sprintf('%1$s %2$s', $this->getColumnData($item, "_wpgae_scroll_selector_meta_key"), $this->row_actions($actions) );
30
+ }
31
+ }
32
+
33
+
34
+ $scrollTracking = new ScrollTracking_Table();
35
+ $wpgae_options = get_option('ga_events_options');
36
+
37
+ ?>
38
+ <div class="wrap">
39
+ <div id="icon-users" class="icon32"></div>
40
+ <h2>Scroll Tracking <a href="#wpgae-add-scroll-event" rel="modal:open" class="page-title-action">Add New</a></h2>
41
+ <?php
42
+ $scrollTracking->prepare_items();
43
+ ?>
44
+ <form method="post">
45
+ <input type="hidden" name="page" value="my_list_test" />
46
+ <?php $scrollTracking->search_box('search', 'search_id'); ?>
47
+ </form>
48
+ <form method="post">
49
+ <?php
50
+ $scrollTracking->display();
51
+ ?>
52
+ </form>
53
+ </div>
54
+ <div class="wrap ga_events_banner ga_events_top">
55
+ <div class="ga_events_featurebox ga_events_box_general">
56
+ <div class="ga_events_box_title">
57
+ <span>
58
+ Become a Pro
59
+ </span>
60
+ </div>
61
+ <div class="ga_events_box_body">
62
+ <ul class="ga_events_box_list">
63
+ <li>
64
+ <div class="ga_events_box_li_icon">
65
+ <img src="<?php echo plugins_url( 'images/icon_block.png', dirname(__FILE__)) ?>" />
66
+ </div>
67
+ <div class="ga_events_box_li_content">
68
+ <span class="ga_events_box_li_title">Link Tracking</span>
69
+ <span class="ga_events_box_li_txt">Automatically track any link on your website</span>
70
+ </div>
71
+ </li>
72
+ <li>
73
+ <div class="ga_events_box_li_icon">
74
+ <img src="<?php echo plugins_url( 'images/icon_block.png', dirname(__FILE__)) ?>" />
75
+ </div>
76
+ <div class="ga_events_box_li_content">
77
+ <span class="ga_events_box_li_title">Placeholder Variables</span>
78
+ <span class="ga_events_box_li_txt">Include dynamic information in your events</span>
79
+ </div>
80
+ </li>
81
+ <li>
82
+ <div class="ga_events_box_li_icon">
83
+ <img src="<?php echo plugins_url( 'images/icon_block.png', dirname(__FILE__)) ?>" />
84
+ </div>
85
+ <div class="ga_events_box_li_content">
86
+ <span class="ga_events_box_li_title">User Permissions</span>
87
+ <span class="ga_events_box_li_txt">Allow non Administrators to manage the plugin</span>
88
+ </div>
89
+ </li>
90
+ </ul>
91
+ </div>
92
+ <div>
93
+ <a class="btn" target="_blank" href="https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=btng">Go Pro</a>
94
+ </div>
95
+ </div>
96
+ <div class="ga_events_featurebox ga_events_box_video">
97
+ <div class="ga_events_box_title">
98
+ <span>
99
+ Track Videos like a Pro
100
+ </span>
101
+ </div>
102
+ <div class="ga_events_box_body">
103
+ <ul class="ga_events_box_list">
104
+ <li>
105
+ <div class="ga_events_box_li_icon">
106
+ <img src="<?php echo plugins_url( 'images/icon_lock.png', dirname(__FILE__)) ?>" />
107
+ </div>
108
+ <div class="ga_events_box_li_content">
109
+ <span class="ga_events_box_li_title">YouTube Video Tracking</span>
110
+ <span class="ga_events_box_li_txt">Track all video play/stop events and make
111
+ smarter segments on how people watch your content.</span>
112
+ </div>
113
+ </li>
114
+ <li>
115
+ <div class="ga_events_box_li_icon" style="margin-top:10px">
116
+ <img src="<?php echo plugins_url( 'images/icon_lock.png', dirname(__FILE__)) ?>" />
117
+ </div>
118
+ <div class="ga_events_box_li_content" style="margin-top:10px">
119
+ <span class="ga_events_box_li_title">Vimeo Video support</span>
120
+ <span class="ga_events_box_li_txt">And yes, you can also track Vimeo videos</span>
121
+ </div>
122
+ </li>
123
+ </ul>
124
+ </div>
125
+ <a class="btn" target="_blank" href="https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=btnv">Go Premium</a>
126
+ </div>
127
+ <div class="ga_events_featurebox ga_events_box_support">
128
+ <div class="ga_events_box_title">
129
+ <span>
130
+ Product Support
131
+ </span>
132
+ </div>
133
+ <div class="ga_events_box_body">
134
+ <ul class="ga_events_box_list">
135
+ <li>
136
+ <div class="ga_events_box_li_content">
137
+ <span class="ga_events_box_li_title" style="margin-left:40px;">Premium Support</span>
138
+ <span class="ga_events_box_li_txt" style="margin-left:40px;">Direct super-fast help from our dedicated support team</span>
139
+ </div>
140
+ </li>
141
+ </ul>
142
+ </div>
143
+ <a class="btn" target="_blank" href="https://wpflow.com/upgrade/?utm_source=wpadmin&utm_medium=banner&utm_campaign=btns">Get Pro Support</a>
144
+ </div>
145
+ </div>
146
+ <?php
147
+ require_once( GAE_PLUGIN_PATH . '/templates/scroll-tracking-modals.php' );
148
+
templates/scroll-tracking-modals.php ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ ?>
3
+ <!-- Modal HTML embedded directly into document -->
4
+ <div id="wpgae-add-scroll-event" class="modal">
5
+ <h2>Add Scroll Event</h2>
6
+ <form id="wpgae-add-event" class="wpgae-event-form">
7
+ <div>
8
+ <div class="postbox wpga_meta">
9
+ <div class="inside">
10
+ <div class="wpgae_event_form_fields">
11
+ <label for="_wpgae_scroll_selector_meta_key">Selector</label>
12
+ <input name="_wpgae_scroll_selector_meta_key" required id="_wpgae_scroll_selector_meta_key" class="postbox" value="">
13
+ </div>
14
+ <div class="wpgae_event_form_fields">
15
+ <label for="_wpgae_scroll_type_meta_key">Selector Type</label>
16
+ <select name="_wpgae_scroll_type_meta_key" id="_wpgae_scroll_type_meta_key">
17
+ <option value="id">id</option>
18
+ <option value="class">class</option>
19
+ <?php if (isset($wpgae_options['advanced']) && $wpgae_options["advanced"] == 1) {
20
+ ?>
21
+ <option value="advanced">advanced</option> ?>
22
+ <?php } ?>
23
+ </select>
24
+ </div>
25
+ <div class="wpgae_event_form_fields">
26
+ <label for="_wpgae_scroll_category_meta_key">Event Category</label>
27
+ <input name="_wpgae_scroll_category_meta_key" id="_wpgae_scroll_category_meta_key" class="postbox" value="">
28
+ </div>
29
+ <div class="wpgae_event_form_fields">
30
+ <label for="_wpgae_scroll_action_meta_key" >Event Action</label>
31
+ <input name="_wpgae_scroll_action_meta_key" id="_wpgae_scroll_action_meta_key" class="postbox" value="">
32
+ </div>
33
+ <div class="wpgae_event_form_fields">
34
+ <label for="_wpgae_scroll_label_meta_key">Event Label</label>
35
+ <input name="_wpgae_scroll_label_meta_key" id="_wpgae_scroll_label_meta_key" class="postbox" value="">
36
+ </div>
37
+ <div class="wpgae_event_form_fields">
38
+ <label for="_wpgae_scroll_value_meta_key">Event Value</label>
39
+ <input name="_wpgae_scroll_value_meta_key" id="_wpgae_scroll_value_meta_key" class="postbox" type="number" value="">
40
+ </div>
41
+ <div class="wpgae_event_form_fields">
42
+ <label for="_wpgae_scroll_bounce_meta_key">Non-Interaction</label>
43
+ <select name="_wpgae_scroll_bounce_meta_key" id="_wpgae_scroll_bounce_meta_key">
44
+ <option value="true" selected="true">true</option>
45
+ <option value="false">false</option>
46
+ </select>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <div id="wpgae_form_buttons">
52
+ <?php wp_nonce_field("wpflow_add_event", "ajax_nonce"); ?>
53
+ <input type="hidden" name="action" value="wpflow_add_event">
54
+ <input type="hidden" name="wpgae_type" value="wpgae_scroll_event">
55
+ <a class="button-secondary" href="#" rel="modal:close">Cancel</a>
56
+ <input type="submit" class="button-primary" value="Add Scroll Event">
57
+ </div>
58
+ </form>
59
+ </div>
60
+
61
+
62
+ <!-- Modal HTML embedded directly into document -->
63
+ <div id="wpgae-edit-scroll-event" class="modal">
64
+ <h2>Edit Scroll Event</h2>
65
+ <form id="wpgae-edit-event" class="wpgae-event-form">
66
+ <div>
67
+ <div class="wpga_meta postbox ">
68
+ <div class="inside">
69
+ <div class="wpgae_event_form_fields">
70
+ <label for="_wpgae_scroll_selector_meta_key">Selector</label>
71
+ <input name="_wpgae_scroll_selector_meta_key" required id="_wpgae_scroll_selector_meta_key" class="postbox" value="">
72
+ </div>
73
+ <div class="wpgae_event_form_fields">
74
+ <label for="_wpgae_scroll_type_meta_key">Selector Type</label>
75
+ <select name="_wpgae_scroll_type_meta_key" id="_wpgae_scroll_type_meta_key">
76
+ <option value="id">id</option>
77
+ <option value="class">class</option>
78
+ <?php if (isset($wpgae_options['advanced']) && $wpgae_options["advanced"] == 1) {
79
+ ?>
80
+ <option value="advanced">advanced</option>
81
+ <?php } ?>
82
+ </select>
83
+ </div>
84
+ <div class="wpgae_event_form_fields">
85
+ <label for="_wpgae_scroll_category_meta_key">Event Category</label>
86
+ <input name="_wpgae_scroll_category_meta_key" id="_wpgae_scroll_category_meta_key" class="postbox" value="">
87
+ </div>
88
+ <div class="wpgae_event_form_fields">
89
+ <label for="_wpgae_scroll_action_meta_key" >Event Action</label>
90
+ <input name="_wpgae_scroll_action_meta_key" id="_wpgae_scroll_action_meta_key" class="postbox" value="">
91
+ </div>
92
+ <div class="wpgae_event_form_fields">
93
+ <label for="_wpgae_scroll_label_meta_key">Event Label</label>
94
+ <input name="_wpgae_scroll_label_meta_key" id="_wpgae_scroll_label_meta_key" class="postbox" value="">
95
+ </div>
96
+ <div class="wpgae_event_form_fields">
97
+ <label for="_wpgae_scroll_value_meta_key">Event Value</label>
98
+ <input name="_wpgae_scroll_value_meta_key" id="_wpgae_scroll_value_meta_key" class="postbox" type="number" value="">
99
+ </div>
100
+ <div class="wpgae_event_form_fields">
101
+ <label for="_wpgae_scroll_bounce_meta_key">Non-Interaction</label>
102
+ <select name="_wpgae_scroll_bounce_meta_key" id="_wpgae_scroll_bounce_meta_key">
103
+ <option value="true" selected="true">true</option>
104
+ <option value="false">false</option>
105
+ </select>
106
+ </div>
107
+ </div>
108
+ </div>
109
+ </div>
110
+ <div id="wpgae_form_buttons">
111
+ <?php wp_nonce_field("wpflow_add_event", "ajax_nonce"); ?>
112
+ <input type="hidden" name="action" value="wpflow_edit_event">
113
+ <input type="hidden" name="event_id" id="event_id" value="">
114
+ <a class="button-secondary" href="#" rel="modal:close">Cancel</a>
115
+ <input type="submit" class="button-primary" value="Save Scroll Event">
116
+ </div>
117
+ </form>
118
+ </div>
119
+
120
+ <!-- Modal HTML embedded directly into document -->
121
+ <div id="wpgae-delete-scroll-event" class="modal">
122
+ <h2>You are about to delete a Scroll Event</h2>
123
+ <form id="wpgae-delete-event" class="wpgae-event-form">
124
+ <div>
125
+ <div class="wpga_meta postbox ">
126
+ <div class="inside">
127
+ <fieldset disabled>
128
+ <div class="wpgae_event_form_fields">
129
+ <label for="_wpgae_scroll_selector_meta_key">Selector</label>
130
+ <input name="_wpgae_scroll_selector_meta_key" id="_wpgae_scroll_selector_meta_key" class="postbox" value="">
131
+ </div>
132
+ <div class="wpgae_event_form_fields">
133
+ <label for="_wpgae_scroll_type_meta_key">Selector Type</label>
134
+ <select name="_wpgae_scroll_type_meta_key" id="_wpgae_scroll_type_meta_key">
135
+ <option value="id">id</option>
136
+ <option value="class">class</option>
137
+ <?php if (isset($wpgae_options['advanced']) && $wpgae_options["advanced"] == 1) {
138
+ ?>
139
+ <option value="advanced">advanced</option>
140
+ <?php } ?>
141
+ </select>
142
+ </div>
143
+ <div class="wpgae_event_form_fields">
144
+ <label for="_wpgae_scroll_category_meta_key">Event Category</label>
145
+ <input name="_wpgae_scroll_category_meta_key" id="_wpgae_scroll_category_meta_key" class="postbox" value="">
146
+ </div>
147
+ <div class="wpgae_event_form_fields">
148
+ <label for="_wpgae_scroll_action_meta_key" >Event Action</label>
149
+ <input name="_wpgae_scroll_action_meta_key" id="_wpgae_scroll_action_meta_key" class="postbox" value="">
150
+ </div>
151
+ <div class="wpgae_event_form_fields">
152
+ <label for="wpgae_event_label">Event Label</label>
153
+ <input name="wpgae_event_label" id="_wpgae_scroll_label_meta_key" class="postbox" value="">
154
+ </div>
155
+ <div class="wpgae_event_form_fields">
156
+ <label for="_wpgae_scroll_value_meta_key">Event Value</label>
157
+ <input name="_wpgae_scroll_value_meta_key" id="_wpgae_click_value_meta_key" class="postbox" type="number" value="">
158
+ </div>
159
+ <div class="wpgae_event_form_fields">
160
+ <label for="_wpgae_scroll_bounce_meta_key">Non-Interaction</label>
161
+ <select name="_wpgae_scroll_bounce_meta_key" id="_wpgae_scroll_bounce_meta_key">
162
+ <option value="true" selected="true">true</option>
163
+ <option value="false">false</option>
164
+ </select>
165
+ </div>
166
+ </fieldset>
167
+ </div>
168
+ </div>
169
+ </div>
170
+ <div id="wpgae_form_buttons">
171
+ <?php wp_nonce_field("wpflow_add_event", "ajax_nonce"); ?>
172
+ <input type="hidden" name="action" value="wpflow_delete_event">
173
+ <input type="hidden" name="event_id" id="event_id" value="">
174
+ <input type="submit" class="button button-large butotn-secondary delete" value="Delete Scroll Event">
175
+ <a class="button button-secondary button-large" href="#" rel="modal:close">Cancel</a>
176
+ </div>
177
+ </form>
178
+ </div>
179
+
templates/whats-new-section-content.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wpgae-container wpgae-container__warning">
2
+ <h3><span class="dashicons dashicons-flag"></span> What's New (2)</h3>
3
+ <div id="wpgae-warnings">
4
+ <p></p>
5
+ <div class="container" id="wpgae-warnings-active">
6
+ <div class="wpgae-alert-holder">
7
+ <div class="wpgae-alert-new">
8
+ <p>Plugin user interface redesign!
9
+ </div>
10
+ </div>
11
+ <div class="wpgae-alert-holder">
12
+ <div class="wpgae-alert-new">
13
+ <p>Better support for Google Analytics tracking code.
14
+ </div>
15
+ </div>
16
+ <div class="wpgae-alert-holder">
17
+ <div class="wpgae-alert">
18
+ <p>Global Site Tag code support. Google recently added the new Global Site Tag feature, and made it the default tracking code. If you migrated to this new code, check the relevant option in the General Settings tab.
19
+ </div>
20
+ </div>
21
+ <div class="wpgae-alert-holder">
22
+ <div class="wpgae-alert">
23
+ <p>The admin UI got a little update - We started working with ajax forms. These changes solve a problem that some of the users had with adding a long list of events.</p>
24
+ </div>
25
+ </div>
26
+ <div class="wpgae-alert-holder">
27
+ <div class="wpgae-alert">
28
+ <p>We added the value field to click and scroll events. This used to be a Pro version feature and now it is part of this plugin as well.</p>
29
+ </div>
30
+ </div>
31
+ <div class="wpgae-alert-holder">
32
+ <div class="wpgae-alert">
33
+ <p>We added support for the <strong>Google Tag Manager</strong>.
34
+ <br>This feature requires some preparation on the Google Tag Manager side so make sure to <a target="_blank" href="https://wpflow.com/knowledgebase/google-tag-manager-support/">check out the video guide</a>.</p>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ <div class="container" id="wpgae-warnings-dismissed">
39
+ </div>
40
+ </div>
41
+ </div>
uninstall.php CHANGED
@@ -1,6 +1,4 @@
1
  <?php
2
- if( !defined( 'WP_UNINSTALL_PLUGIN' ) )
3
- exit ();
4
 
5
- //delete_option( 'ga_scroll_events_install' );
6
- ?>
1
  <?php
 
 
2
 
3
+ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) )
4
+ exit();
wp-ga-events2.png CHANGED
Binary file