Polylang - Version 2.7.0.1

Version Description

Download this release

Release Info

Developer Chouby
Plugin Icon 128x128 Polylang
Version 2.7.0.1
Comparing to
See all releases

Code changes from version 2.7 to 2.7.0.1

modules/wizard/css/wizard.css ADDED
@@ -0,0 +1,950 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @charset "UTF-8";
2
+ body {
3
+ margin: 65px auto 24px;
4
+ box-shadow: none;
5
+ background: #f1f1f1;
6
+ padding: 0
7
+ }
8
+
9
+ #pll-logo {
10
+ border: 0;
11
+ margin: 0 0 24px;
12
+ padding: 0;
13
+ text-align: center;
14
+ font-family: Verdana;
15
+ font-size: 64px;
16
+ text-transform: uppercase;
17
+ color: #000;
18
+ line-height: normal;
19
+ }
20
+ #pll-logo a {
21
+ display: flex;
22
+ justify-content: center;
23
+ color: #000;
24
+ text-decoration: none;
25
+ }
26
+
27
+ #pll-logo img {
28
+ max-width: 100%;
29
+ margin-right: 16px;
30
+ }
31
+ .rtl #pll-logo img {
32
+ margin-right: 0;
33
+ margin-left: 16px;
34
+ }
35
+
36
+ .pll-wizard-footer {
37
+ text-align: center
38
+ }
39
+
40
+ .pll-wizard .select2-container {
41
+ text-align: left;
42
+ width: auto
43
+ }
44
+
45
+ .pll-wizard .hidden {
46
+ display: none
47
+ }
48
+
49
+ .pll-wizard-content {
50
+ box-shadow: 0 1px 3px rgba(0, 0, 0, .13);
51
+ padding: 2em;
52
+ margin: 0 0 20px;
53
+ background: #fff;
54
+ overflow: hidden;
55
+ zoom: 1;
56
+ text-align: left;
57
+ }
58
+ .rtl .pll-wizard-content{
59
+ text-align: right;
60
+ }
61
+
62
+ .pll-wizard-content h1,
63
+ .pll-wizard-content h2,
64
+ .pll-wizard-content h3,
65
+ .pll-wizard-content table {
66
+ margin: 0 0 20px;
67
+ border: 0;
68
+ padding: 0;
69
+ color: #666;
70
+ clear: none;
71
+ font-weight: 500
72
+ }
73
+
74
+ .pll-wizard-content p {
75
+ margin: 20px 0;
76
+ font-size: 1em;
77
+ line-height: 1.75em;
78
+ color: #666
79
+ }
80
+
81
+ .pll-wizard-content table {
82
+ font-size: 1em;
83
+ line-height: 1.75em;
84
+ color: #666;
85
+ width: 100%;
86
+ margin-top: 20px;
87
+ }
88
+ .pll-wizard-content table td span{
89
+ display: inline-block;
90
+ }
91
+
92
+ .pll-wizard-content table caption {
93
+ caption-side: bottom;
94
+ font-style: italic;
95
+ text-align: right;
96
+ }
97
+ .rtl .pll-wizard-content table caption {
98
+ text-align: left;
99
+ }
100
+
101
+ .pll-wizard-content table caption .icon-default-lang{
102
+ font-style: normal;
103
+ }
104
+
105
+ .pll-wizard-content a {
106
+ color: #a03f3f;
107
+ }
108
+
109
+ .pll-wizard-content a:focus,
110
+ .pll-wizard-content a:hover,
111
+ .pll-wizard-footer-links:hover {
112
+ color: #dd5454
113
+ }
114
+
115
+ .pll-wizard-content .pll-wizard-next-steps {
116
+ overflow: hidden;
117
+ margin: 0 0 24px;
118
+ padding-bottom: 2px
119
+ }
120
+
121
+ .pll-wizard-content .pll-wizard-next-steps h2 {
122
+ margin-bottom: 12px
123
+ }
124
+
125
+ .pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-first {
126
+ float: left;
127
+ width: 50%;
128
+ box-sizing: border-box
129
+ }
130
+
131
+ .pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-last {
132
+ float: right;
133
+ width: 50%;
134
+ box-sizing: border-box
135
+ }
136
+
137
+ .pll-wizard-content .pll-wizard-next-steps ul {
138
+ padding: 0 2em 0 0;
139
+ list-style: none outside;
140
+ margin: 0
141
+ }
142
+
143
+ .pll-wizard-content .pll-wizard-next-steps ul li a {
144
+ display: block;
145
+ padding: 0 0 .75em
146
+ }
147
+
148
+ .pll-wizard-content .pll-wizard-next-steps ul li a::before {
149
+ color: #82878c;
150
+ font: normal 20px/1 dashicons;
151
+ speak: none;
152
+ display: inline-block;
153
+ padding: 0 10px 0 0;
154
+ top: 1px;
155
+ position: relative;
156
+ text-decoration: none!important;
157
+ vertical-align: top
158
+ }
159
+
160
+ .pll-wizard-steps {
161
+ padding: 0 0 24px;
162
+ margin: 0;
163
+ list-style: none outside;
164
+ overflow: hidden;
165
+ color: #ccc;
166
+ width: 100%;
167
+ display: -webkit-inline-box;
168
+ display: -webkit-inline-flex;
169
+ display: inline-flex
170
+ }
171
+
172
+ .pll-wizard-steps li {
173
+ width: 100%;
174
+ float: left;
175
+ padding: 0 0 .8em;
176
+ margin: 0;
177
+ text-align: center;
178
+ position: relative;
179
+ border-bottom: 4px solid #ccc;
180
+ line-height: 1.4em
181
+ }
182
+
183
+ .pll-wizard-steps li a {
184
+ color: #a03f3f;
185
+ text-decoration: none;
186
+ padding: 1.5em;
187
+ margin: -1.5em;
188
+ position: relative;
189
+ z-index: 1
190
+ }
191
+
192
+ .pll-wizard-steps li a:focus,
193
+ .pll-wizard-steps li a:hover {
194
+ color: #dd5454;
195
+ text-decoration: underline
196
+ }
197
+
198
+ .pll-wizard-steps li::before {
199
+ content: "";
200
+ border: 4px solid #ccc;
201
+ border-radius: 100%;
202
+ width: 4px;
203
+ height: 4px;
204
+ position: absolute;
205
+ bottom: 0;
206
+ left: 50%;
207
+ margin-left: -6px;
208
+ margin-bottom: -8px;
209
+ background: #fff
210
+ }
211
+
212
+ .pll-wizard-steps li.active {
213
+ border-color: #a03f3f;
214
+ color: #a03f3f;
215
+ font-weight: 700
216
+ }
217
+
218
+ .pll-wizard-steps li.active::before {
219
+ border-color: #a03f3f
220
+ }
221
+
222
+ .pll-wizard-steps li.done {
223
+ border-color: #a03f3f;
224
+ color: #a03f3f
225
+ }
226
+
227
+ .pll-wizard-steps li.done::before {
228
+ border-color: #a03f3f;
229
+ background: #a03f3f
230
+ }
231
+
232
+ .pll-wizard .pll-wizard-actions {
233
+ overflow: hidden;
234
+ margin: 20px 0 0;
235
+ position: relative
236
+ }
237
+
238
+ .pll-wizard .pll-wizard-actions .button {
239
+ font-size: 16px;
240
+ font-weight: 300;
241
+ padding: 1em 2em;
242
+ line-height: 1em;
243
+ margin-right: .5em;
244
+ margin-bottom: 2px;
245
+ margin-top: 10px;
246
+ height: auto;
247
+ border-radius: 4px;
248
+ box-shadow: none;
249
+ min-width: auto;
250
+ border-color: #a03f3f;
251
+ color: #a03f3f;
252
+ }
253
+
254
+ .pll-wizard .pll-wizard-content .button {
255
+ border-color: #a03f3f;
256
+ color: #a03f3f;
257
+ }
258
+
259
+ .pll-wizard .pll-wizard-content .button-primary,
260
+ .pll-wizard .pll-wizard-actions .button-primary {
261
+ background-color: #a03f3f;
262
+ border-color: #a03f3f;
263
+ color: #fff;
264
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 0 #a03f3f;
265
+ text-shadow: 0 -1px 1px #a03f3f, 1px 0 1px #a03f3f, 0 1px 1px #a03f3f, -1px 0 1px #a03f3f;
266
+ margin: 0;
267
+ opacity: 1
268
+ }
269
+
270
+ .pll-wizard .pll-wizard-content .button-small .dashicons {
271
+ font-size: 15px;
272
+ height: auto;
273
+ vertical-align: middle;
274
+ }
275
+
276
+ .pll-wizard .button-primary:active,
277
+ .pll-wizard .button-primary:focus,
278
+ .pll-wizard input[type="checkbox"]:focus + label.button-primary,
279
+ .pll-wizard .button-primary:hover {
280
+ background: #dd5454;
281
+ border-color: #dd5454;
282
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 0 #dd5454
283
+ }
284
+ .pll-wizard .pll-wizard-actions .button-primary[disabled],
285
+ .pll-wizard .pll-wizard-actions .button-primary:disabled,
286
+ .pll-wizard .pll-wizard-actions .button-primary.disabled {
287
+ cursor: wait;
288
+ background-color: #bb5454 !important;
289
+ border-color: #bb5454 !important;
290
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 0 #bb5454 !important;
291
+ text-shadow: 0 -1px 1px #bb5454, 1px 0 1px #bb5454, 0 1px 1px #bb5454, -1px 0 1px #bb5454 !important;
292
+ color: #ffa3a3 !important;
293
+ }
294
+ .pll-wizard-content p:last-child {
295
+ margin-bottom: 0
296
+ }
297
+
298
+ .pll-wizard-footer-links {
299
+ font-size: .85em;
300
+ color: #7b7b7b;
301
+ margin: 1.18em auto;
302
+ display: inline-block;
303
+ text-align: center
304
+ }
305
+
306
+ .pll-wizard-services {
307
+ border: 1px solid #eee;
308
+ padding: 0;
309
+ margin: 0 0 1em;
310
+ list-style: none outside;
311
+ border-radius: 4px;
312
+ overflow: hidden
313
+ }
314
+
315
+ .pll-wizard-services p {
316
+ margin: 0 0 1em 0;
317
+ padding: 0;
318
+ font-size: 1em;
319
+ line-height: 1.5em
320
+ }
321
+
322
+ .pll-wizard-service-item {
323
+ display: -webkit-box;
324
+ display: -webkit-flex;
325
+ display: flex;
326
+ -webkit-flex-wrap: nowrap;
327
+ flex-wrap: nowrap;
328
+ -webkit-box-pack: justify;
329
+ -webkit-justify-content: space-between;
330
+ justify-content: space-between;
331
+ padding: 0;
332
+ border-bottom: 1px solid #eee;
333
+ color: #666;
334
+ -webkit-box-align: center;
335
+ -webkit-align-items: center;
336
+ align-items: center
337
+ }
338
+
339
+ .media-step .pll-wizard-service-item{
340
+ border: 0;
341
+ }
342
+
343
+ .media-step .pll-wizard-service-item:last-child{
344
+ display: block;
345
+ }
346
+
347
+ .media-step .pll-wizard-service-item .pll-wizard-service-enable{
348
+ padding-bottom: 0;
349
+ }
350
+
351
+ .pll-wizard-service-item:last-child {
352
+ border-bottom: 0
353
+ }
354
+
355
+ .pll-wizard-service-item .pll-wizard-service-name {
356
+ -webkit-flex-basis: 0;
357
+ flex-basis: 0;
358
+ min-width: 160px;
359
+ text-align: center;
360
+ font-weight: 700;
361
+ padding: 2em 0;
362
+ -webkit-align-self: stretch;
363
+ align-self: stretch;
364
+ display: -webkit-box;
365
+ display: -webkit-flex;
366
+ display: flex;
367
+ -webkit-box-align: baseline;
368
+ -webkit-align-items: baseline;
369
+ align-items: baseline
370
+ }
371
+
372
+ .pll-wizard-service-item .pll-wizard-service-name img {
373
+ max-width: 75px
374
+ }
375
+
376
+ .pll-wizard-service-item .pll-wizard-service-description {
377
+ -webkit-box-flex: 1;
378
+ -webkit-flex-grow: 1;
379
+ flex-grow: 1;
380
+ padding: 20px
381
+ }
382
+
383
+ .pll-wizard-service-item .pll-wizard-service-example {
384
+ padding: 0 20px 20px
385
+ }
386
+
387
+ .pll-wizard-service-item .pll-wizard-service-example p{
388
+ text-align: right;
389
+ }
390
+ .rtl .pll-wizard-service-item .pll-wizard-service-example p{
391
+ text-align: left;
392
+ }
393
+
394
+ .pll-wizard-service-item .pll-wizard-service-description p {
395
+ margin-bottom: 1em
396
+ }
397
+
398
+ .pll-wizard-service-item .pll-wizard-service-description p:last-child {
399
+ margin-bottom: 0
400
+ }
401
+
402
+ .pll-wizard-service-item .pll-wizard-service-description .pll-wizard-service-settings-description {
403
+ display: block;
404
+ font-style: italic;
405
+ color: #999
406
+ }
407
+
408
+ .pll-wizard-service-item .pll-wizard-service-enable {
409
+ -webkit-flex-basis: 0;
410
+ flex-basis: 0;
411
+ min-width: 75px;
412
+ text-align: center;
413
+ cursor: pointer;
414
+ padding: 2em 0;
415
+ position: relative;
416
+ max-height: 1.5em;
417
+ -webkit-align-self: flex-start;
418
+ align-self: flex-start;
419
+ -webkit-box-ordinal-group: 4;
420
+ -webkit-order: 3;
421
+ order: 3
422
+ }
423
+
424
+ .pll-wizard-service-item .pll-wizard-service-toggle {
425
+ position: relative
426
+ }
427
+
428
+ .pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox] {
429
+ position:absolute;
430
+ opacity: 0;
431
+ }
432
+
433
+ .pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox] + label {
434
+ position: relative;
435
+ display: inline-block;
436
+ width: 44px;
437
+ height: 20px;
438
+ border-radius: 10em;
439
+ cursor: pointer;
440
+ text-indent: -9999px;
441
+ }
442
+
443
+ .pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:focus + label {
444
+ border:1px dashed #777;
445
+ }
446
+
447
+ .pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox] + label::before,
448
+ .pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox] + label::after {
449
+ content: '';
450
+ position: absolute;
451
+ }
452
+
453
+ .pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox] + label::before {
454
+ left: 0;
455
+ top: 0;
456
+ width: 44px;
457
+ height: 20px;
458
+ background: #ddd;
459
+ border-radius: 10em;
460
+ transition: background-color .2s;
461
+ }
462
+
463
+ .pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox] + label::after {
464
+ width: 16px;
465
+ height: 16px;
466
+ transition: all .2s;
467
+ border-radius: 50%;
468
+ background: #fff;
469
+ margin: 2px;
470
+ top: 0;
471
+ left: 0;
472
+ }
473
+
474
+ .pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked + label::before {
475
+ background:#a03f3f;
476
+ }
477
+
478
+ .pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked + label::after {
479
+ right: 0;
480
+ left:auto;
481
+ }
482
+
483
+ .pll-wizard-service-item .pll-wizard-service-settings {
484
+ display: none;
485
+ margin-top: .75em;
486
+ margin-bottom: 0;
487
+ cursor: default
488
+ }
489
+
490
+ .pll-wizard-service-item .pll-wizard-service-settings.hide {
491
+ display: none
492
+ }
493
+
494
+ .pll-wizard-service-item.checked .pll-wizard-service-settings {
495
+ display: inline-block
496
+ }
497
+
498
+ .pll-wizard-service-item.checked .pll-wizard-service-settings.hide {
499
+ display: none
500
+ }
501
+
502
+ .pll-wizard-service-item.closed {
503
+ border-bottom: 0
504
+ }
505
+
506
+ .step {
507
+ text-align: center
508
+ }
509
+
510
+ .pll-wizard .button .dashicons{
511
+ vertical-align: middle;
512
+ }
513
+ .rtl .dashicons-arrow-right-alt2:before {
514
+ content: "\f341";
515
+ }
516
+ .pll-wizard .pll-wizard-actions .button:active,
517
+ .pll-wizard .pll-wizard-actions .button:focus,
518
+ .pll-wizard .pll-wizard-actions .button:hover {
519
+ box-shadow: none
520
+ }
521
+
522
+ .pll-wizard-next-steps {
523
+ border: 1px solid #eee;
524
+ border-radius: 4px;
525
+ list-style: none;
526
+ padding: 0
527
+ }
528
+
529
+ .pll-wizard-next-steps li {
530
+ padding: 0
531
+ }
532
+
533
+ .pll-wizard-next-steps .pll-wizard-next-step-item {
534
+ display: -webkit-box;
535
+ display: -webkit-flex;
536
+ display: flex;
537
+ border-top: 1px solid #eee
538
+ }
539
+
540
+ .pll-wizard-next-steps .pll-wizard-next-step-item.no-border,
541
+ .pll-wizard-next-steps .pll-wizard-next-step-item:first-child {
542
+ border-top: 0
543
+ }
544
+
545
+ .pll-wizard-next-steps .pll-wizard-next-step-description {
546
+ -webkit-box-flex: 1;
547
+ -webkit-flex-grow: 1;
548
+ flex-grow: 1;
549
+ margin: 1.5em
550
+ }
551
+
552
+ .pll-wizard-next-steps .pll-wizard-next-step-action {
553
+ -webkit-box-flex: 0;
554
+ -webkit-flex-grow: 0;
555
+ flex-grow: 0;
556
+ display: -webkit-box;
557
+ display: -webkit-flex;
558
+ display: flex;
559
+ -webkit-box-align: center;
560
+ -webkit-align-items: center;
561
+ align-items: center
562
+ }
563
+
564
+ .pll-wizard-next-steps .pll-wizard-next-step-action .button {
565
+ margin: 1em 1.5em
566
+ }
567
+
568
+ .pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-description,
569
+ .pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-actions,
570
+ .pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-action .button{
571
+ margin-top: 0;
572
+ }
573
+
574
+
575
+ .pll-wizard-next-steps p.next-step-heading {
576
+ margin: 0;
577
+ font-size: .95em;
578
+ font-weight: 400;
579
+ font-variant: all-petite-caps
580
+ }
581
+
582
+ .pll-wizard-next-steps p.next-step-extra-info {
583
+ margin: 0
584
+ }
585
+
586
+ .pll-wizard-next-steps h3.next-step-description {
587
+ margin: 0;
588
+ font-size: 16px;
589
+ font-weight: 600;
590
+ }
591
+
592
+ .pll-wizard-next-steps .pll-wizard-additional-steps {
593
+ border-top: 1px solid #eee;
594
+ }
595
+
596
+ .pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-next-step-description {
597
+ margin-bottom: 0
598
+ }
599
+
600
+ .pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions {
601
+ margin: 0 0 1.5em 0;
602
+ }
603
+
604
+ .pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button {
605
+ font-size: 15px;
606
+ margin: 1em 0 1em 1.5em;
607
+ }
608
+ .rtl .pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button {
609
+ margin: 1em 1.5em 1em 0;
610
+ }
611
+
612
+ .pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button::last-child {
613
+ margin-right: 1.5em;
614
+ }
615
+
616
+ .pll-wizard-content img{
617
+ max-width: 100%;
618
+ margin-right: 0.5em;
619
+ }
620
+ .rtl .pll-wizard-content img{
621
+ margin-left: 0.5em;
622
+ }
623
+
624
+ .pll-wizard-content .form-field label{
625
+ margin-bottom: 5px;
626
+ display: block;
627
+ }
628
+
629
+ .pll-wizard-content .form-field select{
630
+ padding: 3px;
631
+ }
632
+
633
+ .pll-wizard-content .languages-step select,
634
+ .pll-wizard-content .untranslated-contents-step select{
635
+ width: 100%;
636
+ }
637
+
638
+ .languages-step .form-field .button{
639
+ margin-left: 15px;
640
+ }
641
+ .languages-step .form-field .button > span{
642
+ margin-right: 0.3em;
643
+ }
644
+ .rtl .languages-step .form-field .button{
645
+ margin-left: 0;
646
+ margin-right: 15px;
647
+ }
648
+ .rtl .languages-step .form-field .button > span{
649
+ margin-left: 0.3em;
650
+ margin-right: 0;
651
+ }
652
+
653
+ .pll-wizard-content .languages-step .select-language-field{
654
+ display: flex;
655
+ }
656
+
657
+ .pll-wizard-content #languages{
658
+ display: none;
659
+ }
660
+ .pll-wizard-content #languages tr th:first-child{
661
+ width: 80%;
662
+ }
663
+ .pll-wizard-content #languages .dashicons{
664
+ color: #a03f3f;
665
+ }
666
+ .pll-wizard-content #languages img{
667
+ margin-right: 5px;
668
+ }
669
+ .pll-wizard-content .error{
670
+ color: #a03f3f;
671
+ font-weight: bold;
672
+ }
673
+ .pll-wizard-content #messages .error{
674
+ background: #fccfcf;
675
+ padding: 0.5rem;
676
+ border: 1px solid #a03f3f;
677
+ margin-bottom: 0.5rem;
678
+ }
679
+
680
+ .pll-wizard-content #slide-toggle{
681
+ position:absolute;
682
+ opacity: 0;
683
+ }
684
+
685
+ .pll-wizard-content #slide-toggle + label{
686
+ position:relative;
687
+ }
688
+ .pll-wizard-content #slide-toggle + label + span{
689
+ display: block;
690
+ }
691
+
692
+ .pll-wizard-content #slide-toggle + label .dashicons{
693
+ margin-right: 0.3em;
694
+ }
695
+ .rtl .pll-wizard-content #slide-toggle + label .dashicons{
696
+ margin-left: 0.3em;
697
+ margin-right: 0;
698
+ }
699
+ .pll-wizard-content #slide-toggle ~ #screenshot > img {
700
+ max-height: 500px;
701
+ margin-top: 10px;
702
+ -webkit-transition: all .5s cubic-bezier(0, 1, 0.5, 1);
703
+ transition: all .5s cubic-bezier(0, 1, 0.5, 1);
704
+ }
705
+ .pll-wizard-content #slide-toggle:checked ~ #screenshot > img {
706
+ max-height: 0;
707
+ }
708
+ .hide {
709
+ display: none;
710
+ }
711
+
712
+ input[type="text"].field-in-error,
713
+ input[type="password"].field-in-error,
714
+ input[type="checkbox"].field-in-error,
715
+ input[type="color"].field-in-error,
716
+ input[type="date"].field-in-error,
717
+ input[type="datetime"].field-in-error,
718
+ input[type="datetime-local"].field-in-error,
719
+ input[type="email"].field-in-error,
720
+ input[type="month"].field-in-error,
721
+ input[type="number"].field-in-error,
722
+ input[type="search"].field-in-error,
723
+ input[type="radio"].field-in-error,
724
+ input[type="tel"].field-in-error,
725
+ input[type="text"].field-in-error,
726
+ input[type="time"].field-in-error,
727
+ input[type="url"].field-in-error,
728
+ input[type="week"].field-in-error,
729
+ select.field-in-error,
730
+ textarea.field-in-error,
731
+ span.field-in-error,
732
+ .field-in-error{
733
+ border-color: #a03f3f;
734
+ }
735
+
736
+ input[type="text"].field-in-error:focus,
737
+ input[type="password"].field-in-error:focus,
738
+ input[type="checkbox"].field-in-error:focus,
739
+ input[type="color"].field-in-error:focus,
740
+ input[type="date"].field-in-error:focus,
741
+ input[type="datetime"].field-in-error:focus,
742
+ input[type="datetime-local"].field-in-error:focus,
743
+ input[type="email"].field-in-error:focus,
744
+ input[type="month"].field-in-error:focus,
745
+ input[type="number"].field-in-error:focus,
746
+ input[type="search"].field-in-error:focus,
747
+ input[type="radio"].field-in-error:focus,
748
+ input[type="tel"].field-in-error:focus,
749
+ input[type="text"].field-in-error:focus,
750
+ input[type="time"].field-in-error:focus,
751
+ input[type="url"].field-in-error:focus,
752
+ input[type="week"].field-in-error:focus,
753
+ select.field-in-error:focus,
754
+ textarea.field-in-error:focus,
755
+ span.field-in-error:focus,
756
+ .field-in-error:focus{
757
+ border: 1px solid #a03f3f;
758
+ box-shadow: 0 0 2px rgba(160, 63, 63, 0.8);
759
+ outline-color: #a03f3f;
760
+ outline-style: auto;
761
+ outline-width: thin;
762
+ }
763
+
764
+ /* override install styles by returning back to forms styles */
765
+ .form-table input.regular-text{
766
+ width: 25em;
767
+ }
768
+ .form-table input.field-in-error{
769
+ border-color: #a03f3f;
770
+ }
771
+ #pll-licenses-table td{
772
+ padding: 10px 9px;
773
+ }
774
+ #pll-licenses-table .license-valid td p{
775
+ min-width: 35em;
776
+ }
777
+ #pll-licenses-table .pll-deactivate-license{
778
+ margin: 0 0 0 20px;
779
+ }
780
+ .rtl #pll-licenses-table .pll-deactivate-license{
781
+ margin: 0 10px 0 0;
782
+ }
783
+ .pll-wizard-content .documentation {
784
+ padding: 24px 24px 0;
785
+ margin: 0 0 24px;
786
+ overflow: hidden;
787
+ background: #f5f5f5
788
+ }
789
+
790
+ .pll-wizard-content .documentation p {
791
+ padding: 0;
792
+ margin: 0 0 12px;
793
+ }
794
+ .documentation-container {
795
+ display: -webkit-box;
796
+ display: -webkit-flex;
797
+ display: flex;
798
+ justify-content: flex-end;
799
+ }
800
+
801
+ .documentation-container .documentation-button-container {
802
+ -webkit-box-flex: 0;
803
+ -webkit-flex-grow: 0;
804
+ flex-grow: 0;
805
+ }
806
+
807
+ .wc-setup .wc-setup-actions .button.documentation-button {
808
+ height: 42px;
809
+ padding: 0 1em;
810
+ margin: 0;
811
+ }
812
+ #dialog{
813
+ display: none;
814
+ }
815
+ .pll-wizard .ui-dialog.ui-widget-content{
816
+ max-height: none;
817
+ }
818
+ .pll-wizard .ui-dialog-title::before{
819
+ content: "\f534";
820
+ font-family: dashicons;
821
+ display: inline-block;
822
+ line-height: 1;
823
+ font-weight: 400;
824
+ font-style: normal;
825
+ speak: none;
826
+ text-decoration: inherit;
827
+ text-transform: none;
828
+ text-rendering: auto;
829
+ -webkit-font-smoothing: antialiased;
830
+ -moz-osx-font-smoothing: grayscale;
831
+ width: 20px;
832
+ height: 20px;
833
+ font-size: 20px;
834
+ vertical-align: middle;
835
+ text-align: center;
836
+ margin: 0 5px 5px 0;
837
+ transition: color 0.1s ease-in;
838
+ }
839
+ .rtl.pll-wizard .ui-dialog-title::before{
840
+ margin-right: 0;
841
+ margin-left: 5px;
842
+ }
843
+ .pll-wizard .ui-dialog ul{
844
+ list-style: disc;
845
+ padding-left: 20px;
846
+ }
847
+ .rtl.pll-wizard .ui-dialog ul{
848
+ padding-left: 0;
849
+ padding-right: 20px;
850
+ }
851
+ .pll-wizard li{
852
+ margin-bottom: 0;
853
+ }
854
+ #translations{
855
+ border-collapse: collapse;
856
+ }
857
+ #translations tbody:nth-child(odd){
858
+ background-color: #f9f9f9;
859
+ }
860
+ #translations.striped > tbody > :nth-child(odd) {
861
+ background-color: transparent; /* Override common WordPress style */
862
+ }
863
+ .pll-wizard-content mark{
864
+ background: transparent none;
865
+ }
866
+ .pll-wizard-content mark{
867
+ color: #7ad03a;
868
+ }
869
+ @media screen and (max-width: 782px) {
870
+ /* Override WordPress button css rules */
871
+ .languages-step .form-field .button{
872
+ font-size: 13px;
873
+ line-height: 26px;
874
+ height: 28px;
875
+ padding: 0 10px 1px;
876
+ vertical-align: top;
877
+ }
878
+
879
+ #pll-licenses-table .pll-deactivate-license{
880
+ margin: 10px 0 5px;
881
+ }
882
+ }
883
+ @media only screen and (max-width:620px) {
884
+ /* Override dialog width rule */
885
+ .ui-dialog{
886
+ width: 100% !important;
887
+ }
888
+
889
+ }
890
+ @media only screen and (max-width:500px) {
891
+ #pll-logo a,
892
+ .select-language-field{
893
+ flex-direction: column;
894
+ }
895
+ .select-language-field .action-buttons{
896
+ display: flex;
897
+ justify-content: flex-end;
898
+ }
899
+ .languages-step .form-field .button{
900
+ margin: 5px 0 0;
901
+ }
902
+ }
903
+ @media only screen and (max-width:400px) {
904
+ #pll-logo {
905
+ font-size: 56px;
906
+ }
907
+ .pll-wizard-steps {
908
+ display: none
909
+ }
910
+ .pll-wizard-service-item {
911
+ -webkit-flex-wrap: wrap;
912
+ flex-wrap: wrap
913
+ }
914
+ .pll-wizard-service-item .pll-wizard-service-enable {
915
+ -webkit-box-ordinal-group: 3;
916
+ -webkit-order: 2;
917
+ order: 2;
918
+ padding: 20px 0 0
919
+ }
920
+ .pll-wizard-service-item .pll-wizard-service-description {
921
+ -webkit-box-ordinal-group: 4;
922
+ -webkit-order: 3;
923
+ order: 3
924
+ }
925
+ .pll-wizard-service-item .pll-wizard-service-name {
926
+ padding: 20px 20px 0;
927
+ text-align: left;
928
+ -webkit-box-pack: justify!important;
929
+ -webkit-justify-content: space-between!important;
930
+ justify-content: space-between!important
931
+ }
932
+ .pll-wizard-service-item .pll-wizard-service-name img {
933
+ margin: 0
934
+ }
935
+ .pll-wizard-next-steps .pll-wizard-next-step-item {
936
+ -webkit-flex-wrap: wrap;
937
+ flex-wrap: wrap
938
+ }
939
+ .pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-description {
940
+ margin-bottom: 0
941
+ }
942
+ .pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-action p {
943
+ margin: 0
944
+ }
945
+ }
946
+ @media only screen and (max-width:360px) {
947
+ #pll-logo {
948
+ font-size: 48px;
949
+ }
950
+ }
modules/wizard/css/wizard.min.css ADDED
@@ -0,0 +1 @@
 
1
+ @charset "UTF-8";body{margin:65px auto 24px;box-shadow:none;background:#f1f1f1;padding:0}#pll-logo{border:0;margin:0 0 24px;padding:0;text-align:center;font-family:Verdana;font-size:64px;text-transform:uppercase;color:#000;line-height:normal}#pll-logo a{display:flex;justify-content:center;color:#000;text-decoration:none}#pll-logo img{max-width:100%;margin-right:16px}.rtl #pll-logo img{margin-right:0;margin-left:16px}.pll-wizard-footer{text-align:center}.pll-wizard .select2-container{text-align:left;width:auto}.pll-wizard .hidden{display:none}.pll-wizard-content{box-shadow:0 1px 3px rgba(0,0,0,.13);padding:2em;margin:0 0 20px;background:#fff;overflow:hidden;zoom:1;text-align:left}.rtl .pll-wizard-content{text-align:right}.pll-wizard-content h1,.pll-wizard-content h2,.pll-wizard-content h3,.pll-wizard-content table{margin:0 0 20px;border:0;padding:0;color:#666;clear:none;font-weight:500}.pll-wizard-content p{margin:20px 0;font-size:1em;line-height:1.75em;color:#666}.pll-wizard-content table{font-size:1em;line-height:1.75em;color:#666;width:100%;margin-top:20px}.pll-wizard-content table td span{display:inline-block}.pll-wizard-content table caption{caption-side:bottom;font-style:italic;text-align:right}.rtl .pll-wizard-content table caption{text-align:left}.pll-wizard-content table caption .icon-default-lang{font-style:normal}.pll-wizard-content a{color:#a03f3f}.pll-wizard-content a:focus,.pll-wizard-content a:hover,.pll-wizard-footer-links:hover{color:#dd5454}.pll-wizard-content .pll-wizard-next-steps{overflow:hidden;margin:0 0 24px;padding-bottom:2px}.pll-wizard-content .pll-wizard-next-steps h2{margin-bottom:12px}.pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-first{float:left;width:50%;box-sizing:border-box}.pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-last{float:right;width:50%;box-sizing:border-box}.pll-wizard-content .pll-wizard-next-steps ul{padding:0 2em 0 0;list-style:none outside;margin:0}.pll-wizard-content .pll-wizard-next-steps ul li a{display:block;padding:0 0 .75em}.pll-wizard-content .pll-wizard-next-steps ul li a::before{color:#82878c;font:normal 20px/1 dashicons;speak:none;display:inline-block;padding:0 10px 0 0;top:1px;position:relative;text-decoration:none!important;vertical-align:top}.pll-wizard-steps{padding:0 0 24px;margin:0;list-style:none outside;overflow:hidden;color:#ccc;width:100%;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex}.pll-wizard-steps li{width:100%;float:left;padding:0 0 .8em;margin:0;text-align:center;position:relative;border-bottom:4px solid #ccc;line-height:1.4em}.pll-wizard-steps li a{color:#a03f3f;text-decoration:none;padding:1.5em;margin:-1.5em;position:relative;z-index:1}.pll-wizard-steps li a:focus,.pll-wizard-steps li a:hover{color:#dd5454;text-decoration:underline}.pll-wizard-steps li::before{content:"";border:4px solid #ccc;border-radius:100%;width:4px;height:4px;position:absolute;bottom:0;left:50%;margin-left:-6px;margin-bottom:-8px;background:#fff}.pll-wizard-steps li.active{border-color:#a03f3f;color:#a03f3f;font-weight:700}.pll-wizard-steps li.active::before{border-color:#a03f3f}.pll-wizard-steps li.done{border-color:#a03f3f;color:#a03f3f}.pll-wizard-steps li.done::before{border-color:#a03f3f;background:#a03f3f}.pll-wizard .pll-wizard-actions{overflow:hidden;margin:20px 0 0;position:relative}.pll-wizard .pll-wizard-actions .button{font-size:16px;font-weight:300;padding:1em 2em;line-height:1em;margin-right:.5em;margin-bottom:2px;margin-top:10px;height:auto;border-radius:4px;box-shadow:none;min-width:auto;border-color:#a03f3f;color:#a03f3f}.pll-wizard .pll-wizard-content .button{border-color:#a03f3f;color:#a03f3f}.pll-wizard .pll-wizard-actions .button-primary,.pll-wizard .pll-wizard-content .button-primary{background-color:#a03f3f;border-color:#a03f3f;color:#fff;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a03f3f;text-shadow:0 -1px 1px #a03f3f,1px 0 1px #a03f3f,0 1px 1px #a03f3f,-1px 0 1px #a03f3f;margin:0;opacity:1}.pll-wizard .pll-wizard-content .button-small .dashicons{font-size:15px;height:auto;vertical-align:middle}.pll-wizard .button-primary:active,.pll-wizard .button-primary:focus,.pll-wizard .button-primary:hover,.pll-wizard input[type=checkbox]:focus+label.button-primary{background:#dd5454;border-color:#dd5454;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #dd5454}.pll-wizard .pll-wizard-actions .button-primary.disabled,.pll-wizard .pll-wizard-actions .button-primary:disabled,.pll-wizard .pll-wizard-actions .button-primary[disabled]{cursor:wait;background-color:#bb5454!important;border-color:#bb5454!important;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #bb5454!important;text-shadow:0 -1px 1px #bb5454,1px 0 1px #bb5454,0 1px 1px #bb5454,-1px 0 1px #bb5454!important;color:#ffa3a3!important}.pll-wizard-content p:last-child{margin-bottom:0}.pll-wizard-footer-links{font-size:.85em;color:#7b7b7b;margin:1.18em auto;display:inline-block;text-align:center}.pll-wizard-services{border:1px solid #eee;padding:0;margin:0 0 1em;list-style:none outside;border-radius:4px;overflow:hidden}.pll-wizard-services p{margin:0 0 1em 0;padding:0;font-size:1em;line-height:1.5em}.pll-wizard-service-item{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;padding:0;border-bottom:1px solid #eee;color:#666;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.media-step .pll-wizard-service-item{border:0}.media-step .pll-wizard-service-item:last-child{display:block}.media-step .pll-wizard-service-item .pll-wizard-service-enable{padding-bottom:0}.pll-wizard-service-item:last-child{border-bottom:0}.pll-wizard-service-item .pll-wizard-service-name{-webkit-flex-basis:0;flex-basis:0;min-width:160px;text-align:center;font-weight:700;padding:2em 0;-webkit-align-self:stretch;align-self:stretch;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:baseline;-webkit-align-items:baseline;align-items:baseline}.pll-wizard-service-item .pll-wizard-service-name img{max-width:75px}.pll-wizard-service-item .pll-wizard-service-description{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;padding:20px}.pll-wizard-service-item .pll-wizard-service-example{padding:0 20px 20px}.pll-wizard-service-item .pll-wizard-service-example p{text-align:right}.rtl .pll-wizard-service-item .pll-wizard-service-example p{text-align:left}.pll-wizard-service-item .pll-wizard-service-description p{margin-bottom:1em}.pll-wizard-service-item .pll-wizard-service-description p:last-child{margin-bottom:0}.pll-wizard-service-item .pll-wizard-service-description .pll-wizard-service-settings-description{display:block;font-style:italic;color:#999}.pll-wizard-service-item .pll-wizard-service-enable{-webkit-flex-basis:0;flex-basis:0;min-width:75px;text-align:center;cursor:pointer;padding:2em 0;position:relative;max-height:1.5em;-webkit-align-self:flex-start;align-self:flex-start;-webkit-box-ordinal-group:4;-webkit-order:3;order:3}.pll-wizard-service-item .pll-wizard-service-toggle{position:relative}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]{position:absolute;opacity:0}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label{position:relative;display:inline-block;width:44px;height:20px;border-radius:10em;cursor:pointer;text-indent:-9999px}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:focus+label{border:1px dashed #777}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label::after,.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label::before{content:'';position:absolute}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label::before{left:0;top:0;width:44px;height:20px;background:#ddd;border-radius:10em;transition:background-color .2s}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label::after{width:16px;height:16px;transition:all .2s;border-radius:50%;background:#fff;margin:2px;top:0;left:0}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked+label::before{background:#a03f3f}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked+label::after{right:0;left:auto}.pll-wizard-service-item .pll-wizard-service-settings{display:none;margin-top:.75em;margin-bottom:0;cursor:default}.pll-wizard-service-item .pll-wizard-service-settings.hide{display:none}.pll-wizard-service-item.checked .pll-wizard-service-settings{display:inline-block}.pll-wizard-service-item.checked .pll-wizard-service-settings.hide{display:none}.pll-wizard-service-item.closed{border-bottom:0}.step{text-align:center}.pll-wizard .button .dashicons{vertical-align:middle}.rtl .dashicons-arrow-right-alt2:before{content:"\f341"}.pll-wizard .pll-wizard-actions .button:active,.pll-wizard .pll-wizard-actions .button:focus,.pll-wizard .pll-wizard-actions .button:hover{box-shadow:none}.pll-wizard-next-steps{border:1px solid #eee;border-radius:4px;list-style:none;padding:0}.pll-wizard-next-steps li{padding:0}.pll-wizard-next-steps .pll-wizard-next-step-item{display:-webkit-box;display:-webkit-flex;display:flex;border-top:1px solid #eee}.pll-wizard-next-steps .pll-wizard-next-step-item.no-border,.pll-wizard-next-steps .pll-wizard-next-step-item:first-child{border-top:0}.pll-wizard-next-steps .pll-wizard-next-step-description{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;margin:1.5em}.pll-wizard-next-steps .pll-wizard-next-step-action{-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.pll-wizard-next-steps .pll-wizard-next-step-action .button{margin:1em 1.5em}.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-actions,.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-action .button,.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-description{margin-top:0}.pll-wizard-next-steps p.next-step-heading{margin:0;font-size:.95em;font-weight:400;font-variant:all-petite-caps}.pll-wizard-next-steps p.next-step-extra-info{margin:0}.pll-wizard-next-steps h3.next-step-description{margin:0;font-size:16px;font-weight:600}.pll-wizard-next-steps .pll-wizard-additional-steps{border-top:1px solid #eee}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-next-step-description{margin-bottom:0}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions{margin:0 0 1.5em 0}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button{font-size:15px;margin:1em 0 1em 1.5em}.rtl .pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button{margin:1em 1.5em 1em 0}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button::last-child{margin-right:1.5em}.pll-wizard-content img{max-width:100%;margin-right:.5em}.rtl .pll-wizard-content img{margin-left:.5em}.pll-wizard-content .form-field label{margin-bottom:5px;display:block}.pll-wizard-content .form-field select{padding:3px}.pll-wizard-content .languages-step select,.pll-wizard-content .untranslated-contents-step select{width:100%}.languages-step .form-field .button{margin-left:15px}.languages-step .form-field .button>span{margin-right:.3em}.rtl .languages-step .form-field .button{margin-left:0;margin-right:15px}.rtl .languages-step .form-field .button>span{margin-left:.3em;margin-right:0}.pll-wizard-content .languages-step .select-language-field{display:flex}.pll-wizard-content #languages{display:none}.pll-wizard-content #languages tr th:first-child{width:80%}.pll-wizard-content #languages .dashicons{color:#a03f3f}.pll-wizard-content #languages img{margin-right:5px}.pll-wizard-content .error{color:#a03f3f;font-weight:700}.pll-wizard-content #messages .error{background:#fccfcf;padding:.5rem;border:1px solid #a03f3f;margin-bottom:.5rem}.pll-wizard-content #slide-toggle{position:absolute;opacity:0}.pll-wizard-content #slide-toggle+label{position:relative}.pll-wizard-content #slide-toggle+label+span{display:block}.pll-wizard-content #slide-toggle+label .dashicons{margin-right:.3em}.rtl .pll-wizard-content #slide-toggle+label .dashicons{margin-left:.3em;margin-right:0}.pll-wizard-content #slide-toggle~#screenshot>img{max-height:500px;margin-top:10px;-webkit-transition:all .5s cubic-bezier(0,1,.5,1);transition:all .5s cubic-bezier(0,1,.5,1)}.pll-wizard-content #slide-toggle:checked~#screenshot>img{max-height:0}.hide{display:none}.field-in-error,input[type=checkbox].field-in-error,input[type=color].field-in-error,input[type=date].field-in-error,input[type=datetime-local].field-in-error,input[type=datetime].field-in-error,input[type=email].field-in-error,input[type=month].field-in-error,input[type=number].field-in-error,input[type=password].field-in-error,input[type=radio].field-in-error,input[type=search].field-in-error,input[type=tel].field-in-error,input[type=text].field-in-error,input[type=time].field-in-error,input[type=url].field-in-error,input[type=week].field-in-error,select.field-in-error,span.field-in-error,textarea.field-in-error{border-color:#a03f3f}.field-in-error:focus,input[type=checkbox].field-in-error:focus,input[type=color].field-in-error:focus,input[type=date].field-in-error:focus,input[type=datetime-local].field-in-error:focus,input[type=datetime].field-in-error:focus,input[type=email].field-in-error:focus,input[type=month].field-in-error:focus,input[type=number].field-in-error:focus,input[type=password].field-in-error:focus,input[type=radio].field-in-error:focus,input[type=search].field-in-error:focus,input[type=tel].field-in-error:focus,input[type=text].field-in-error:focus,input[type=time].field-in-error:focus,input[type=url].field-in-error:focus,input[type=week].field-in-error:focus,select.field-in-error:focus,span.field-in-error:focus,textarea.field-in-error:focus{border:1px solid #a03f3f;box-shadow:0 0 2px rgba(160,63,63,.8);outline-color:#a03f3f;outline-style:auto;outline-width:thin}.form-table input.regular-text{width:25em}.form-table input.field-in-error{border-color:#a03f3f}#pll-licenses-table td{padding:10px 9px}#pll-licenses-table .license-valid td p{min-width:35em}#pll-licenses-table .pll-deactivate-license{margin:0 0 0 20px}.rtl #pll-licenses-table .pll-deactivate-license{margin:0 10px 0 0}.pll-wizard-content .documentation{padding:24px 24px 0;margin:0 0 24px;overflow:hidden;background:#f5f5f5}.pll-wizard-content .documentation p{padding:0;margin:0 0 12px}.documentation-container{display:-webkit-box;display:-webkit-flex;display:flex;justify-content:flex-end}.documentation-container .documentation-button-container{-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0}.wc-setup .wc-setup-actions .button.documentation-button{height:42px;padding:0 1em;margin:0}#dialog{display:none}.pll-wizard .ui-dialog.ui-widget-content{max-height:none}.pll-wizard .ui-dialog-title::before{content:"\f534";font-family:dashicons;display:inline-block;line-height:1;font-weight:400;font-style:normal;speak:none;text-decoration:inherit;text-transform:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:20px;height:20px;font-size:20px;vertical-align:middle;text-align:center;margin:0 5px 5px 0;transition:color .1s ease-in}.rtl.pll-wizard .ui-dialog-title::before{margin-right:0;margin-left:5px}.pll-wizard .ui-dialog ul{list-style:disc;padding-left:20px}.rtl.pll-wizard .ui-dialog ul{padding-left:0;padding-right:20px}.pll-wizard li{margin-bottom:0}#translations{border-collapse:collapse}#translations tbody:nth-child(odd){background-color:#f9f9f9}#translations.striped>tbody>:nth-child(odd){background-color:transparent}.pll-wizard-content mark{background:transparent none}.pll-wizard-content mark{color:#7ad03a}@media screen and (max-width:782px){.languages-step .form-field .button{font-size:13px;line-height:26px;height:28px;padding:0 10px 1px;vertical-align:top}#pll-licenses-table .pll-deactivate-license{margin:10px 0 5px}}@media only screen and (max-width:620px){.ui-dialog{width:100%!important}}@media only screen and (max-width:500px){#pll-logo a,.select-language-field{flex-direction:column}.select-language-field .action-buttons{display:flex;justify-content:flex-end}.languages-step .form-field .button{margin:5px 0 0}}@media only screen and (max-width:400px){#pll-logo{font-size:56px}.pll-wizard-steps{display:none}.pll-wizard-service-item{-webkit-flex-wrap:wrap;flex-wrap:wrap}.pll-wizard-service-item .pll-wizard-service-enable{-webkit-box-ordinal-group:3;-webkit-order:2;order:2;padding:20px 0 0}.pll-wizard-service-item .pll-wizard-service-description{-webkit-box-ordinal-group:4;-webkit-order:3;order:3}.pll-wizard-service-item .pll-wizard-service-name{padding:20px 20px 0;text-align:left;-webkit-box-pack:justify!important;-webkit-justify-content:space-between!important;justify-content:space-between!important}.pll-wizard-service-item .pll-wizard-service-name img{margin:0}.pll-wizard-next-steps .pll-wizard-next-step-item{-webkit-flex-wrap:wrap;flex-wrap:wrap}.pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-description{margin-bottom:0}.pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-action p{margin:0}}@media only screen and (max-width:360px){#pll-logo{font-size:48px}}
modules/wizard/html-wizard-notice.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Displays the wizard notice content
5
+ *
6
+ * @since 2.7
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit; // Don't access directly.
11
+ };
12
+
13
+ $wizard_url = add_query_arg(
14
+ array(
15
+ 'page' => 'mlang_wizard',
16
+ ),
17
+ admin_url( 'admin.php' )
18
+ );
19
+ ?>
20
+ <p>
21
+ <strong>
22
+ <?php
23
+ printf(
24
+ /* translators: %s is the plugin name */
25
+ esc_html__( 'Welcome to %s', 'polylang' ),
26
+ esc_html( POLYLANG )
27
+ );
28
+ ?>
29
+ </strong>
30
+ <?php
31
+ echo ' &#8211; ';
32
+ esc_html_e( 'You&lsquo;re almost ready to translate your contents!', 'polylang' );
33
+ ?>
34
+ </p>
35
+ <p class="buttons">
36
+ <a
37
+ href="<?php echo esc_url( $wizard_url ); ?>"
38
+ class="button button-primary"
39
+ >
40
+ <?php esc_html_e( 'Run the Setup Wizard', 'polylang' ); ?>
41
+ </a>
42
+ <a
43
+ class="button button-secondary skip"
44
+ href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'pll-hide-notice', 'wizard' ), 'wizard', '_pll_notice_nonce' ) ); ?>"
45
+ >
46
+ <?php esc_html_e( 'Skip setup', 'polylang' ); ?>
47
+ </a>
48
+ </p>
modules/wizard/images/media-screen-rtl.png ADDED
Binary file
modules/wizard/images/media-screen.png ADDED
Binary file
modules/wizard/images/polylang-logo.png ADDED
Binary file
modules/wizard/js/languages-step.js ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( document ).ready(
2
+ function( $ ) {
3
+ var addLanguageForm = $( '.languages-step' ); // Form element.
4
+ var languageFields = $( '#language-fields' ); // Element where to append hidden fields for creating language.
5
+ var languagesTable = $( '#languages' ); // Table element contains languages list to create.
6
+ var languagesListTable = $( '#languages tbody' ); // Table rows with languages list to create.
7
+ var definedLanguagesListTable = $( '#defined-languages tbody' ); // Table rows with already defined languages list.
8
+ var languagesList = $( '#lang_list' ); // Select form element with predefined languages without already created languages.
9
+ var nextStepButton = $( '[name="save_step"]' ); // The button for continuing to the next step.
10
+ var messagesContainer = $( '#messages' ); // Element where to display error messages.
11
+ var languagesMap = new Map(); // Languages map object for managing the languages to create.
12
+ var dialog = $( '#dialog' ); // Dialog box for alerting the language selected has not been added to the list.
13
+
14
+ /**
15
+ * Add a language in the list to create it in Polylang settings
16
+ *
17
+ * @param {object} language The language object
18
+ */
19
+ function addLanguage( language ) {
20
+ // language properties come from the select dropdown which is built server side and well escaped.
21
+ var languageValueHtml = $( '<td />' ).text( language.text ).prepend( language.flagUrl );
22
+ var languageTrashIconHtml = $( '<td />' )
23
+ .append( // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
24
+ $( '<span />' )
25
+ .addClass( 'dashicons dashicons-trash' )
26
+ .attr( 'data-language', language.locale )
27
+ .append( // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
28
+ $( '<span />' )
29
+ .addClass( 'screen-reader-text' )
30
+ .text( pll_wizard_params.i18n_remove_language_icon )
31
+ )
32
+ );
33
+ var languageLineHtml = $( '<tr />' ).prepend( languageTrashIconHtml ).prepend( languageValueHtml );
34
+ var languageFieldHtml = $( '<input />' ).attr(
35
+ {
36
+ type: 'hidden',
37
+ name: 'languages[]'
38
+ }
39
+ ).val( language.locale );
40
+
41
+ languagesList.val( '' );
42
+ languagesList.selectmenu( 'refresh' ); // Refresh jQuery selectmenu widget after changing the value.
43
+
44
+ languagesMap.set( language.locale, language );
45
+
46
+ // see above how languageLineHtml is built.
47
+ languagesListTable.append( languageLineHtml ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
48
+ // Bind click event on trash icon.
49
+ languagesListTable.on(
50
+ 'click',
51
+ 'span[data-language=' + language.locale + ']',
52
+ function( event ) {
53
+ event.preventDefault();
54
+ // Remove line in languages table.
55
+ $( this ).parents( 'tr' ).remove();
56
+ // Remove input field.
57
+ languageField = languageFields.children( 'input[value=' + $( this ).data( 'language' ) + ']' ).remove();
58
+ // If there is no more languages hide languages table.
59
+ if ( languagesListTable.children().length <= 0 ) {
60
+ languagesTable.hide();
61
+ }
62
+ // Remove language from the Map.
63
+ languagesMap.delete( $( this ).data( 'language' ) );
64
+ // Hide error message.
65
+ hideError();
66
+ }
67
+ );
68
+ // see above how languageFieldHtml is built.
69
+ // Add hidden input field for posting the form.
70
+ languageFields.append( languageFieldHtml ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
71
+
72
+ }
73
+
74
+ /**
75
+ * Display an error message
76
+ *
77
+ * @param {string} message The message to display
78
+ */
79
+ function showError( message ) {
80
+ messagesContainer.empty();
81
+ messagesContainer.prepend( $( '<p/>' ).addClass( 'error' ).text( message ) );
82
+ }
83
+
84
+ /**
85
+ * Hide all error messages and fields in error
86
+ */
87
+ function hideError() {
88
+ messagesContainer.empty();
89
+ addLanguageForm.find( '.error' ).removeClass( 'error field-in-error' );
90
+ }
91
+
92
+ /**
93
+ * Style the field to indicate where the error is
94
+ *
95
+ * @param {object} field The jQuery element which is in error
96
+ */
97
+ function showFieldInError( field ) {
98
+ field.addClass( 'error field-in-error' );
99
+ }
100
+
101
+ /**
102
+ * Focus on a specific element
103
+ *
104
+ * @param {object} field The jQuery element which will be focused
105
+ */
106
+ function focusOnField( field ) {
107
+ field.focus();
108
+ }
109
+
110
+ /**
111
+ * Disable a specific button
112
+ *
113
+ * @param {object} button
114
+ */
115
+ function disableButton( button ){
116
+ button.prop( 'disabled', true );
117
+ // Because the button is disabled we need to add the value of the button to ensure it will pass in the request.
118
+ addLanguageForm.append( // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
119
+ $( '<input />' ).prop(
120
+ {
121
+ type: 'hidden',
122
+ name: button.prop( 'name' ),
123
+ value: button.prop( 'value' )
124
+ }
125
+ )
126
+ );
127
+ }
128
+
129
+ /**
130
+ * Remove error when a new selection is done in languages list.
131
+ */
132
+ languagesList.on(
133
+ 'selectmenuchange',
134
+ function() {
135
+ hideError();;
136
+ }
137
+ );
138
+ /**
139
+ * Bind click event on "Add language" button
140
+ */
141
+ $( '#add-language' ).on(
142
+ 'click',
143
+ function( event ) {
144
+ hideError();
145
+ var selectedOption = event.currentTarget.form.lang_list.options[event.currentTarget.form.lang_list.selectedIndex];
146
+ if ( '' !== selectedOption.value && ! languagesMap.has( selectedOption.value ) ) {
147
+ addLanguage(
148
+ {
149
+ locale: selectedOption.value,
150
+ text: selectedOption.innerText,
151
+ name: $( selectedOption ).data( 'language-name' ),
152
+ flagUrl: $( selectedOption ).data( 'flag-html' )
153
+ }
154
+ );
155
+ // Show table of languages.
156
+ languagesTable.show();
157
+ // Put back the focus on the select language field after clicking on "Add language button".
158
+ focusOnField( $( '#lang_list-button' ) );
159
+ } else {
160
+ var message = pll_wizard_params.i18n_no_language_selected;
161
+ if ( languagesMap.has( selectedOption.value ) ) {
162
+ message = pll_wizard_params.i18n_language_already_added;
163
+ }
164
+ showError( message );
165
+ showFieldInError( languagesList.next( 'span.ui-selectmenu-button' ) );
166
+ focusOnField( $( '#lang_list-button' ) );
167
+
168
+ }
169
+ }
170
+ );
171
+
172
+ /**
173
+ * Bind submit event on "add_lang" form
174
+ */
175
+ addLanguageForm.on(
176
+ 'submit',
177
+ function( event ) {
178
+ // Verify if there is at least one language.
179
+ var isLanguagesAlreadyDefined = definedLanguagesListTable.children().length > 0;
180
+ var selectedLanguage = $( '#lang_list' ).val();
181
+ if ( languagesMap.size <= 0 && ! isLanguagesAlreadyDefined ) {
182
+ if ( '' === selectedLanguage ) {
183
+ showError( pll_wizard_params.i18n_no_language_added );
184
+ showFieldInError( languagesList.next( 'span.ui-selectmenu-button' ) );
185
+ focusOnField( $( '#lang_list-button' ) );
186
+ } else {
187
+ showError( pll_wizard_params.i18n_add_language_needed );
188
+ showFieldInError( languagesList.next( 'span.ui-selectmenu-button' ) );
189
+ focusOnField( $( '#add-language' ) ); // Put the focus on the "Add language" button.
190
+ }
191
+ return false;
192
+ }
193
+ // Verify if the language has been added in the list otherwise display a dialog box to confirm what to do.
194
+ if ( '' !== selectedLanguage ) {
195
+ // Verify we don't add a duplicate language before opening the dialog box otherwise display an error message.
196
+ if ( ! languagesMap.has( selectedLanguage ) ) {
197
+ dialog.dialog( 'open' );
198
+ } else {
199
+ showError( pll_wizard_params.i18n_language_already_added );
200
+ showFieldInError( languagesList.next( 'span.ui-selectmenu-button' ) );
201
+ focusOnField( $( '#lang_list-button' ) );
202
+ }
203
+ return false;
204
+ }
205
+ disableButton( nextStepButton );
206
+ }
207
+ );
208
+
209
+ // Is there an error return by PHP ?
210
+ var searchParams = new URLSearchParams( document.location.search );
211
+ if ( searchParams.has( 'activate_error' ) ) {
212
+ // If the error code exists, display it.
213
+ if ( undefined !== pll_wizard_params[ searchParams.get( 'activate_error' ) ] ) {
214
+ showError( pll_wizard_params[ searchParams.get( 'activate_error' ) ] );
215
+ }
216
+ }
217
+
218
+ function confirmDialog( what ) {
219
+ switch ( what ) {
220
+ case 'yes':
221
+ var selectedOption = $( '#lang_list' ).children( ':selected' );
222
+ addLanguage(
223
+ {
224
+ locale: selectedOption[0].value,
225
+ text: selectedOption[0].innerText,
226
+ name: $( selectedOption ).data( 'language-name' ),
227
+ flagUrl: $( selectedOption ).data( 'flag-html' )
228
+ }
229
+ );
230
+ break;
231
+ case 'no':
232
+ // Empty select form field and submit again the form.
233
+ languagesList.val( '' );
234
+ break;
235
+ case 'ignore':
236
+ }
237
+ dialog.dialog( 'close' );
238
+ if ( 'ignore' === what ) {
239
+ focusOnField( $( '#lang_list-button' ) );
240
+ } else {
241
+ addLanguageForm.submit();
242
+ }
243
+ }
244
+
245
+ // Initialize dialog box in the case a langauge is selected but not added in the list.
246
+ dialog.dialog(
247
+ {
248
+ autoOpen: false,
249
+ modal: true,
250
+ draggable: false,
251
+ resizable: false,
252
+ title: pll_wizard_params.i18n_dialog_title,
253
+ minWidth: 600,
254
+ maxWidth: '100%',
255
+ open: function( event, ui ) {
256
+ // Change dialog box position for rtl language
257
+ if ( $( 'body' ).hasClass( 'rtl' ) ) {
258
+ $( this ).parent().css(
259
+ {
260
+ right: $( this ).parent().css( 'left' ),
261
+ left: 'auto'
262
+ }
263
+ );
264
+ }
265
+ // Display language name and flag information in dialog box.
266
+ $( this ).find( '#dialog-language' ).text( $( '#lang_list' ).children( ':selected' )[0].innerText );
267
+ $( this ).find( '#dialog-language-flag' ).empty().prepend( $( '#lang_list' ).children( ':selected' ).data( 'flag-html' ) );
268
+ },
269
+ buttons: [
270
+ {
271
+ text: pll_wizard_params.i18n_dialog_yes_button,
272
+ click: function( event ) {
273
+ confirmDialog( 'yes' );
274
+ }
275
+ },
276
+ {
277
+ text: pll_wizard_params.i18n_dialog_no_button,
278
+ click: function( event ) {
279
+ confirmDialog( 'no' );
280
+ }
281
+ },
282
+ {
283
+ text: pll_wizard_params.i18n_dialog_ignore_button,
284
+ click: function( event ) {
285
+ confirmDialog( 'ignore' );
286
+ }
287
+ }
288
+ ]
289
+ }
290
+ )
291
+ }
292
+ );
modules/wizard/js/languages-step.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function(a){var e=a(".languages-step"),n=a("#language-fields"),t=a("#languages"),l=a("#languages tbody"),i=a("#defined-languages tbody"),r=a("#lang_list"),d=a('[name="save_step"]'),s=a("#messages"),o=new Map,g=a("#dialog");function u(e){var i=a("<td />").text(e.text).prepend(e.flagUrl),d=a("<td />").append(a("<span />").addClass("dashicons dashicons-trash").attr("data-language",e.locale).append(a("<span />").addClass("screen-reader-text").text(pll_wizard_params.i18n_remove_language_icon))),s=a("<tr />").prepend(d).prepend(i),g=a("<input />").attr({type:"hidden",name:"languages[]"}).val(e.locale);r.val(""),r.selectmenu("refresh"),o.set(e.locale,e),l.append(s),l.on("click","span[data-language="+e.locale+"]",function(e){e.preventDefault(),a(this).parents("tr").remove(),languageField=n.children("input[value="+a(this).data("language")+"]").remove(),l.children().length<=0&&t.hide(),o.delete(a(this).data("language")),c()}),n.append(g)}function p(e){s.empty(),s.prepend(a("<p/>").addClass("error").text(e))}function c(){s.empty(),e.find(".error").removeClass("error field-in-error")}function _(a){a.addClass("error field-in-error")}function m(a){a.focus()}r.on("selectmenuchange",function(){c()}),a("#add-language").on("click",function(e){c();var n=e.currentTarget.form.lang_list.options[e.currentTarget.form.lang_list.selectedIndex];if(""===n.value||o.has(n.value)){var l=pll_wizard_params.i18n_no_language_selected;o.has(n.value)&&(l=pll_wizard_params.i18n_language_already_added),p(l),_(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))}else u({locale:n.value,text:n.innerText,name:a(n).data("language-name"),flagUrl:a(n).data("flag-html")}),t.show(),m(a("#lang_list-button"))}),e.on("submit",function(n){var t,l=i.children().length>0,s=a("#lang_list").val();return o.size<=0&&!l?(""===s?(p(pll_wizard_params.i18n_no_language_added),_(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))):(p(pll_wizard_params.i18n_add_language_needed),_(r.next("span.ui-selectmenu-button")),m(a("#add-language"))),!1):""!==s?(o.has(s)?(p(pll_wizard_params.i18n_language_already_added),_(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))):g.dialog("open"),!1):((t=d).prop("disabled",!0),void e.append(a("<input />").prop({type:"hidden",name:t.prop("name"),value:t.prop("value")})))});var h=new URLSearchParams(document.location.search);function f(n){switch(n){case"yes":var t=a("#lang_list").children(":selected");u({locale:t[0].value,text:t[0].innerText,name:a(t).data("language-name"),flagUrl:a(t).data("flag-html")});break;case"no":r.val("")}g.dialog("close"),"ignore"===n?m(a("#lang_list-button")):e.submit()}h.has("activate_error")&&void 0!==pll_wizard_params[h.get("activate_error")]&&p(pll_wizard_params[h.get("activate_error")]),g.dialog({autoOpen:!1,modal:!0,draggable:!1,resizable:!1,title:pll_wizard_params.i18n_dialog_title,minWidth:600,maxWidth:"100%",open:function(e,n){a("body").hasClass("rtl")&&a(this).parent().css({right:a(this).parent().css("left"),left:"auto"}),a(this).find("#dialog-language").text(a("#lang_list").children(":selected")[0].innerText),a(this).find("#dialog-language-flag").empty().prepend(a("#lang_list").children(":selected").data("flag-html"))},buttons:[{text:pll_wizard_params.i18n_dialog_yes_button,click:function(a){f("yes")}},{text:pll_wizard_params.i18n_dialog_no_button,click:function(a){f("no")}},{text:pll_wizard_params.i18n_dialog_ignore_button,click:function(a){f("ignore")}}]})});
modules/wizard/view-wizard-page.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Displays the wizard
5
+ *
6
+ * @since 2.7
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit; // Don't access directly.
11
+ };
12
+ $admin_body_class = array( 'pll-wizard', 'wp-core-ui' );
13
+ if ( is_rtl() ) {
14
+ $admin_body_class[] = 'rtl';
15
+ }
16
+ ?>
17
+ <!DOCTYPE html>
18
+ <html <?php language_attributes(); ?>>
19
+ <head>
20
+ <meta name="viewport" content="width=device-width" />
21
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
22
+ <title>
23
+ <?php
24
+ printf(
25
+ /* translators: %s is the plugin name */
26
+ esc_html__( '%s &rsaquo; Setup', 'polylang' ),
27
+ esc_html( POLYLANG )
28
+ );
29
+ ?>
30
+ </title>
31
+ <script type="text/javascript">
32
+ var ajaxurl = '<?php echo esc_url( admin_url( 'admin-ajax.php', 'relative' ) ); ?>';
33
+ </script>
34
+ <?php do_action( 'admin_enqueue_scripts' ); ?>
35
+ <?php wp_print_scripts( $this->steps[ $this->step ]['scripts'] ); ?>
36
+ <?php wp_print_styles( array_merge( $this->styles, $this->steps[ $this->step ]['styles'] ) ); ?>
37
+ <?php do_action( 'admin_head' ); ?>
38
+ </head>
39
+ <body class="<?php echo join( ' ', array_map( 'sanitize_key', $admin_body_class ) ); ?>">
40
+ <h1 id="pll-logo">
41
+ <a href="https://polylang.pro/" class="title">
42
+ <span><img src="<?php echo esc_url( plugins_url( '/modules/wizard/images/polylang-logo.png', POLYLANG_FILE ) ); ?>" /></span>
43
+ <?php echo esc_html( POLYLANG ); ?>
44
+ </a>
45
+ </h1>
46
+ <ol class="pll-wizard-steps">
47
+ <?php
48
+ foreach ( $this->steps as $step_key => $step ) {
49
+ $is_completed = array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true );
50
+
51
+ if ( $step_key === $this->step ) {
52
+ ?>
53
+ <li class="active"><?php echo esc_html( $step['name'] ); ?></li>
54
+ <?php
55
+ } elseif ( $is_completed ) {
56
+ ?>
57
+ <li class="done">
58
+ <a
59
+ href="<?php echo esc_url( add_query_arg( 'step', $step_key, remove_query_arg( 'activate_error' ) ) ); ?>"
60
+ >
61
+ <?php echo esc_html( $step['name'] ); ?>
62
+ </a>
63
+ </li>
64
+ <?php
65
+ } else {
66
+ ?>
67
+ <li><?php echo esc_html( $step['name'] ); ?></li>
68
+ <?php
69
+ }
70
+ }
71
+ ?>
72
+ </ol>
73
+ <div class="pll-wizard-content">
74
+ <form method="post" class="<?php echo esc_attr( "{$this->step}-step" ); ?>">
75
+ <?php
76
+ wp_nonce_field( 'pll-wizard', '_pll_nonce' );
77
+
78
+ if ( ! empty( $this->steps[ $this->step ]['view'] ) ) {
79
+ call_user_func( $this->steps[ $this->step ]['view'], $this );
80
+ }
81
+ ?>
82
+ <?php if ( 'last' !== $this->step ) : ?>
83
+ <p class="pll-wizard-actions step">
84
+ <button
85
+ type="submit"
86
+ class="button-primary button button-large button-next"
87
+ value="continue"
88
+ name="save_step"
89
+ >
90
+ <?php esc_html_e( 'Continue', 'polylang' ); ?><span class="dashicons dashicons-arrow-right-alt2"></span>
91
+ </button>
92
+ </p>
93
+ <?php endif; ?>
94
+ </form>
95
+ </div>
96
+ <div class="pll-wizard-footer">
97
+ <?php if ( 'last' !== $this->step ) : ?>
98
+ <a
99
+ class="pll-wizard-footer-links"
100
+ href="<?php echo esc_url( admin_url() ); ?>"
101
+ >
102
+ <?php esc_html_e( 'Not right now', 'polylang' ); ?>
103
+ </a>
104
+ <?php endif; ?>
105
+ </div>
106
+ </body>
107
+ </html>
modules/wizard/view-wizard-step-home-page.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Displays the wizard home page step
5
+ *
6
+ * @since 2.7
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit; // Don't access directly.
11
+ };
12
+
13
+ $languages = $this->model->get_languages_list();
14
+ $default_language = count( $languages ) > 0 ? $this->options['default_lang'] : null;
15
+ $home_page_id = get_option( 'page_on_front' );
16
+ $translations = $this->model->post->get_translations( $home_page_id );
17
+ $untranslated_languages = array();
18
+ $home_page = $home_page_id > 0 ? get_post( $home_page_id ) : null;
19
+ $home_page_language = $this->model->post->get_language( $home_page_id );
20
+
21
+ foreach ( $languages as $language ) {
22
+ if ( ! $this->model->post->get( $home_page_id, $language ) ) {
23
+ $untranslated_languages[] = $language;
24
+ }
25
+ }
26
+ ?>
27
+ <input type="hidden" name="home_page" value="<?php echo esc_attr( $home_page->ID ); ?>" />
28
+ <input type="hidden" name="home_page_title" value="<?php echo esc_attr( $home_page->post_title ); ?>" />
29
+ <?php if ( false !== $home_page_language ) : ?>
30
+ <input type="hidden" name="home_page_language" value="<?php echo esc_attr( $home_page_language->slug ); ?>" />
31
+ <?php endif; ?>
32
+ <h2><?php esc_html_e( 'Homepage', 'polylang' ); ?></h2>
33
+ <p>
34
+ <?php
35
+ printf(
36
+ /* translators: %s is the post title of the front page */
37
+ esc_html__( 'You defined this page as your static homepage: %s.', 'polylang' ),
38
+ '<strong>' . esc_html( $home_page->post_title ) . '</strong>'
39
+ );
40
+ ?>
41
+ <br />
42
+ <?php
43
+ printf(
44
+ /* translators: %s is the language of the front page ( flag, native name and locale ) */
45
+ esc_html__( 'Its language is : %s.', 'polylang' ),
46
+ $home_page_language->flag . ' <strong>' . esc_html( $home_page_language->name ) . ' ' . esc_html( $home_page_language->locale ) . '</strong>' //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
47
+ )
48
+ ?>
49
+ <br />
50
+ <?php esc_html_e( 'For your site to work correctly, this page must be translated in all available languages.', 'polylang' ); ?>
51
+ </p>
52
+ <p>
53
+ <?php esc_html_e( 'After the pages is created, it is up to you to put the translated content in each page linked to each language.', 'polylang' ); ?>
54
+ </p>
55
+ <?php if ( $translations ) : ?>
56
+ <table id="translated-languages" class="striped">
57
+ <thead>
58
+ <tr>
59
+ <th><?php esc_html_e( 'Your static homepage is already translated in', 'polylang' ); ?></th>
60
+ </tr>
61
+ </thead>
62
+ <tbody>
63
+ <?php
64
+ foreach ( array_keys( $translations ) as $lang ) {
65
+ $language = $this->model->get_language( $lang );
66
+ ?>
67
+ <tr>
68
+ <td>
69
+ <?php
70
+ echo $language->flag; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
71
+ echo ' ' . esc_html( $language->name ) . ' ' . esc_html( $language->locale ) . ' ';
72
+ ?>
73
+ <?php if ( $language->slug === $default_language ) : ?>
74
+ <span class="icon-default-lang">
75
+ <span class="screen-reader-text">
76
+ <?php esc_html_e( 'Default language', 'polylang' ); ?>
77
+ </span>
78
+ </span>
79
+ <?php endif; ?>
80
+ <input type="hidden" name="translated_languages[]" value="<?php echo esc_attr( $language->slug ); ?>" />
81
+ </td>
82
+ </tr>
83
+ <?php
84
+ }
85
+ ?>
86
+ </tbody>
87
+ </table>
88
+ <?php endif; ?>
89
+ <table id="untranslated-languages" class="striped">
90
+ <?php if ( ! is_null( $default_language ) ) : ?>
91
+ <caption><span class="icon-default-lang"></span> <?php esc_html_e( 'Default language', 'polylang' ); ?></caption>
92
+ <?php endif; ?>
93
+ <thead>
94
+ <?php if ( count( $untranslated_languages ) >= 1 ) : ?>
95
+ <tr>
96
+ <th><?php esc_html_e( 'We are going to prepare this page in', 'polylang' ); ?></th>
97
+ </tr>
98
+ <?php elseif ( false !== $home_page_language && count( $untranslated_languages ) <= 0 ) : ?>
99
+ <tr>
100
+ <th>
101
+ <span class="dashicons dashicons-info"></span>
102
+ <?php esc_html_e( 'One language is well defined and assigned to your home page.', 'polylang' ); ?>
103
+ </th>
104
+ </tr>
105
+ <tr>
106
+ <td><?php esc_html_e( "If you add a new language, don't forget to translate your homepage.", 'polylang' ); ?></td>
107
+ </tr>
108
+ <?php endif; ?>
109
+ </thead>
110
+ <tbody>
111
+ <?php
112
+ foreach ( $untranslated_languages as $lg ) {
113
+ ?>
114
+ <tr>
115
+ <td>
116
+ <?php
117
+ echo $lg->flag; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
118
+ echo ' ' . esc_html( $lg->name ) . ' ' . esc_html( $lg->locale ) . ' ';
119
+ ?>
120
+ <?php if ( $lg->slug === $default_language ) : ?>
121
+ <span class="icon-default-lang">
122
+ <span class="screen-reader-text">
123
+ <?php esc_html_e( 'Default language', 'polylang' ); ?>
124
+ </span>
125
+ </span>
126
+ <?php endif; ?>
127
+ <input type="hidden" name="untranslated_languages[]" value="<?php echo esc_attr( $lg->slug ); ?>" />
128
+ </td>
129
+ </tr>
130
+ <?php
131
+ }
132
+ ?>
133
+ </tbody>
134
+ </table>
modules/wizard/view-wizard-step-languages.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Displays the wizard languages step
5
+ *
6
+ * @since 2.7
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit; // Don't access directly.
11
+ };
12
+
13
+ $existing_languages = $this->model->get_languages_list();
14
+ $default_language = count( $existing_languages ) > 0 ? $this->options['default_lang'] : null;
15
+
16
+ $languages_list = array_diff_key(
17
+ PLL_Settings::get_predefined_languages(),
18
+ wp_list_pluck( $existing_languages, 'locale', 'locale' )
19
+ );
20
+ ?>
21
+ <div id="language-fields"></div>
22
+ <p class="languages-setup">
23
+ <?php esc_html_e( 'This wizard will help you configure your Polylang settings, and get you started quickly with your multilingual website.', 'polylang' ); ?>
24
+ </p>
25
+ <p class="languages-setup">
26
+ <?php esc_html_e( 'First we are going to define the languages that you will use on your website.', 'polylang' ); ?>
27
+ </p>
28
+ <h2><?php esc_html_e( 'Languages', 'polylang' ); ?></h2>
29
+ <div id="messages">
30
+ </div>
31
+ <div class="form-field">
32
+ <label for="lang_list"><?php esc_html_e( 'Select a language to be added', 'polylang' ); ?></label>
33
+ <div class="select-language-field">
34
+ <select name="lang_list" id="lang_list">
35
+ <option value=""></option>
36
+ <?php
37
+ foreach ( $languages_list as $lg ) {
38
+ // To set flag base64 encoded for predefined languages as user defined languages.
39
+ $lg['flag_code'] = $lg['flag'];
40
+ $language = new PLL_Language( $lg );
41
+ $language->set_flag();
42
+ printf(
43
+ '<option value="%1$s" data-flag-html="%3$s" data-language-name="%2$s" >%2$s - %1$s</option>' . "\n",
44
+ esc_attr( $language->locale ),
45
+ esc_html( $language->name ),
46
+ esc_html( $language->flag )
47
+ );
48
+ }
49
+ ?>
50
+ </select>
51
+ <div class="action-buttons">
52
+ <button type="button"
53
+ class="button-primary button"
54
+ value="<?php esc_attr_e( 'Add new language', 'polylang' ); ?>"
55
+ id="add-language"
56
+ name="add-language"
57
+ >
58
+ <span class="dashicons dashicons-plus"></span><?php esc_html_e( 'Add new language', 'polylang' ); ?>
59
+ </button>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ <table id="languages" class="striped">
64
+ <thead>
65
+ <tr>
66
+ <th><?php esc_html_e( 'Language', 'polylang' ); ?></th>
67
+ <th><?php esc_html_e( 'Remove', 'polylang' ); ?></th>
68
+ </tr>
69
+ </thead>
70
+ <tbody>
71
+ </tbody>
72
+ </table>
73
+ <table id="defined-languages" class="striped<?php echo empty( $existing_languages ) ? ' hide' : ''; ?>">
74
+ <?php if ( ! is_null( $default_language ) ) : ?>
75
+ <caption><span class="icon-default-lang"></span> <?php esc_html_e( 'Default language', 'polylang' ); ?></caption>
76
+ <?php endif; ?>
77
+ <thead>
78
+ <tr>
79
+ <th><?php esc_html_e( 'Languages already defined', 'polylang' ); ?></th>
80
+ </tr>
81
+ </thead>
82
+ <tbody>
83
+ <?php
84
+ foreach ( $existing_languages as $lg ) {
85
+ printf(
86
+ '<tr><td>%3$s<span>%2$s - %1$s</span> %4$s</td></tr>' . "\n",
87
+ esc_attr( $lg->locale ),
88
+ esc_html( $lg->name ),
89
+ $lg->flag, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
90
+ $default_language === $lg->slug ? ' <span class="icon-default-lang"><span class="screen-reader-text">' . esc_html__( 'Default language', 'polylang' ) . '</span></span>' : ''
91
+ );
92
+ }
93
+ ?>
94
+ </tbody>
95
+ </table>
96
+
97
+ <div id="dialog">
98
+ <p>
99
+ <?php
100
+ printf(
101
+ /* translators: %1$s: is a language flag image, %2$s: is a language native name */
102
+ esc_html__( 'You selected %1$s %2$s but you didn\'t add it to the list before continuing to the next step.', 'polylang' ),
103
+ '<span id="dialog-language-flag"></span>',
104
+ '<strong id="dialog-language"></strong>'
105
+ );
106
+ ?>
107
+ </p>
108
+ <p>
109
+ <?php esc_html_e( 'Do you want to add this language before continuing to the next step?', 'polylang' ); ?>
110
+ </p>
111
+ <ul>
112
+ <li>
113
+ <?php
114
+ printf(
115
+ /* translators: %s: is the translated label of the 'Yes' button */
116
+ esc_html__( '%s: add this language and continue to the next step', 'polylang' ),
117
+ '<strong>' . esc_html__( 'Yes', 'polylang' ) . '</strong >'
118
+ );
119
+ ?>
120
+ </li>
121
+ <li>
122
+ <?php
123
+ printf(
124
+ /* translators: %s: is the translated label of the 'No' button */
125
+ esc_html__( "%s: don't add this language and continue to the next step", 'polylang' ),
126
+ '<strong>' . esc_html__( 'No', 'polylang' ) . '</strong >'
127
+ );
128
+ ?>
129
+ </li>
130
+ <li>
131
+ <?php
132
+ printf(
133
+ /* translators: %s: is the translated label of the 'Ignore' button */
134
+ esc_html__( '%s: stay at this step', 'polylang' ),
135
+ '<strong>' . esc_html__( 'Ignore', 'polylang' ) . '</strong >'
136
+ );
137
+ ?>
138
+ </li>
139
+ </ul>
140
+ </div>
modules/wizard/view-wizard-step-last.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Displays the wizard last step
5
+ *
6
+ * @since 2.7
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit; // Don't access directly.
11
+ };
12
+
13
+ ?>
14
+ <h2><?php esc_html_e( "You're ready to translate your contents!", 'polylang' ); ?></h2>
15
+
16
+ <div class="documentation">
17
+ <p><?php esc_html_e( "You're now able to translate your contents such as posts, pages, categories and tags. You can learn how to use Polylang by reading the documentation.", 'polylang' ); ?></p>
18
+ <div class="documentation-container">
19
+ <p class="pll-wizard-actions step documentation-button-container">
20
+ <a
21
+ class="button button-primary button-large documentation-button"
22
+ href="<?php echo esc_url( 'https://polylang.pro/doc-category/getting-started/' ); ?>"
23
+ target="blank"
24
+ >
25
+ <?php esc_html_e( 'Read documentation', 'polylang' ); ?>
26
+ </a>
27
+ </p>
28
+ </div>
29
+ </div>
30
+
31
+ <ul class="pll-wizard-next-steps">
32
+ <li class="pll-wizard-next-step-item">
33
+ <div class="pll-wizard-next-step-description">
34
+ <p class="next-step-heading"><?php esc_html_e( 'Next step', 'polylang' ); ?></p>
35
+ <h3 class="next-step-description"><?php esc_html_e( 'Create menus', 'polylang' ); ?></h3>
36
+ <p class="next-step-extra-info">
37
+ <?php esc_html_e( 'To get your website ready, there are still two steps you need to perform manually: add menus in each language, and add a language switcher to allow your visitors to select their preferred language.', 'polylang' ); ?>
38
+ </p>
39
+ </div>
40
+ <div class="pll-wizard-next-step-action">
41
+ <p class="pll-wizard-actions step">
42
+ <a class="button button-primary button-large" href="<?php echo esc_url( 'https://polylang.pro/doc/create-menus/' ); ?>">
43
+ <?php esc_html_e( 'Read documentation', 'polylang' ); ?>
44
+ </a>
45
+ </p>
46
+ </div>
47
+ </li>
48
+ <li class="pll-wizard-next-step-item">
49
+ <div class="pll-wizard-next-step-description">
50
+ <p class="next-step-heading"><?php esc_html_e( 'Next step', 'polylang' ); ?></p>
51
+ <h3 class="next-step-description"><?php esc_html_e( 'Translate some pages', 'polylang' ); ?></h3>
52
+ <p class="next-step-extra-info"><?php esc_html_e( "You're ready to translate the posts on your website.", 'polylang' ); ?></p>
53
+ </div>
54
+ <div class="pll-wizard-next-step-action">
55
+ <p class="pll-wizard-actions step">
56
+ <a class="button button-large" href="<?php echo esc_url( admin_url( 'edit.php?post_type=page' ) ); ?>">
57
+ <?php esc_html_e( 'View pages', 'polylang' ); ?>
58
+ </a>
59
+ </p>
60
+ </div>
61
+ </li>
62
+ <?php if ( ! defined( 'POLYLANG_PRO' ) && ! defined( 'WOOCOMMERCE_VERSION' ) ) : ?>
63
+ <li class="pll-wizard-next-step-item">
64
+ <div class="pll-wizard-next-step-description">
65
+ <p class="next-step-heading"><?php esc_html_e( 'Polylang Pro', 'polylang' ); ?></p>
66
+ <h3 class="next-step-description"><?php esc_html_e( 'Upgrade to Polylang Pro', 'polylang' ); ?></h3>
67
+ <p class="next-step-extra-info">
68
+ <?php esc_html_e( 'Thank you for activating Polylang. If you want more advanced features - duplication, synchronization, REST API support, integration with other plugins, etc. - or further help provided by our Premium support, we recommend you upgrade to Polylang Pro.', 'polylang' ); ?>
69
+ </p>
70
+ </div>
71
+ <div class="pll-wizard-next-step-action">
72
+ <p class="pll-wizard-actions step">
73
+ <a class="button button-primary button-large" href="<?php echo esc_url( 'https://polylang.pro/downloads/polylang-pro/' ); ?>">
74
+ <?php esc_html_e( 'Buy now', 'polylang' ); ?>
75
+ </a>
76
+ </p>
77
+ </div>
78
+ </li>
79
+ <?php endif; ?>
80
+ <?php if ( ! defined( 'POLYLANG_PRO' ) && defined( 'WOOCOMMERCE_VERSION' ) && ! defined( 'PLLWC_VERSION' ) ) : ?>
81
+ <li class="pll-wizard-next-step-item">
82
+ <div class="pll-wizard-next-step-description">
83
+ <p class="next-step-heading"><?php esc_html_e( 'WooCommerce', 'polylang' ); ?></p>
84
+ <h3 class="next-step-description"><?php esc_html_e( 'Purchase Polylang Business Pack', 'polylang' ); ?></h3>
85
+ <p class="next-step-extra-info">
86
+ <?php
87
+ printf(
88
+ /* translators: %s is the name of Polylang Business Pack product */
89
+ esc_html__( 'We have noticed that you are using Polylang with WooCommerce. To ensure a better compatibility, we recommend you use %s which includes both Polylang Pro and Polylang For WooCommerce.', 'polylang' ),
90
+ '<strong>' . esc_html__( 'Polylang Business Pack', 'polylang' ) . '</strong>'
91
+ );
92
+ ?>
93
+ </p>
94
+ </div>
95
+ <div class="pll-wizard-next-step-action">
96
+ <p class="pll-wizard-actions step">
97
+ <a class="button button-primary button-large" href="<?php echo esc_url( 'https://polylang.pro/downloads/polylang-for-woocommerce/' ); ?>">
98
+ <?php esc_html_e( 'Buy now', 'polylang' ); ?>
99
+ </a>
100
+ </p>
101
+ </div>
102
+ </li>
103
+ <?php endif; ?>
104
+ <li class="pll-wizard-additional-steps">
105
+ <div class="pll-wizard-next-step-action">
106
+ <p class="pll-wizard-actions step">
107
+ <a class="button button-large" href="<?php echo esc_url( admin_url() ); ?>">
108
+ <?php esc_html_e( 'Return to the Dashboard', 'polylang' ); ?>
109
+ </a>
110
+ </p>
111
+ </div>
112
+ </li>
113
+ </ul>
modules/wizard/view-wizard-step-licenses.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Displays the wizard licenses step
5
+ *
6
+ * @since 2.7
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit; // Don't access directly.
11
+ };
12
+
13
+ $licenses = apply_filters( 'pll_settings_licenses', array() );
14
+ $is_error = isset( $_GET['activate_error'] ) && 'i18n_license_key_error' === sanitize_key( $_GET['activate_error'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
15
+ ?>
16
+ <p>
17
+ <?php esc_html_e( 'You are using plugins which require a license key.', 'polylang' ); ?>
18
+ <?php echo esc_html( _n( 'Please enter your license key:', 'Please enter your license keys:', count( $licenses ), 'polylang' ) ); ?>
19
+ </p>
20
+ <h2><?php esc_html_e( 'Licenses', 'polylang' ); ?></h2>
21
+ <div id="messages">
22
+ <?php if ( $is_error ) : ?>
23
+ <p class="error"><?php esc_html_e( 'There is an error with a license key.', 'polylang' ); ?></p>
24
+ <?php endif; ?>
25
+ </div>
26
+ <div class="form-field">
27
+ <table id="pll-licenses-table" class="form-table">
28
+ <tbody>
29
+ <?php
30
+ foreach ( $licenses as $license ) {
31
+ // Escaping is already done in get_form_field method.
32
+ echo $license->get_form_field(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
33
+ }
34
+ ?>
35
+ </tbody>
36
+ </table>
37
+ </div>
modules/wizard/view-wizard-step-media.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Displays the wizard media step
5
+ *
6
+ * @since 2.7
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit; // Don't access directly.
11
+ };
12
+
13
+ $default_options = PLL_Install::get_default_options();
14
+ $options = wp_parse_args( get_option( 'polylang' ), $default_options );
15
+ $media_support = $options['media_support'];
16
+
17
+ $help_screenshot = '/modules/wizard/images/media-screen' . ( is_rtl() ? '-rtl' : '' ) . '.png';
18
+
19
+ ?>
20
+ <h2><?php esc_html_e( 'Media', 'polylang' ); ?></h2>
21
+ <p>
22
+ <?php esc_html_e( 'Polylang allows you to translate the text attached to your media, for example the title, the alternative text, the caption, or the description.', 'polylang' ); ?>
23
+ <?php esc_html_e( 'When you translate a media, the file is not duplicated on your disk, however you will see one entry per language in the media library.', 'polylang' ); ?>
24
+ <?php esc_html_e( 'When you want to insert media in a post, only the media in the language of the current post will be displayed.', 'polylang' ); ?>
25
+ </p>
26
+ <p>
27
+ <?php esc_html_e( 'You must activate media translation if you want to translate the title, the alternative text, the caption, or the description. Otherwise you can safely deactivate it.', 'polylang' ); ?>
28
+ </p>
29
+ <ul class="pll-wizard-services">
30
+ <li class="pll-wizard-service-item">
31
+ <div class="pll-wizard-service-enable">
32
+ <span class="pll-wizard-service-toggle">
33
+ <input
34
+ id="pll-wizard-service-media"
35
+ type="checkbox"
36
+ name="media_support"
37
+ value="yes" <?php checked( $media_support ); ?>
38
+ />
39
+ <label for="pll-wizard-service-media" />
40
+ </span>
41
+ </div>
42
+ <div class="pll-wizard-service-description">
43
+ <p>
44
+ <?php esc_html_e( 'Allow Polylang translate media', 'polylang' ); ?>
45
+ </p>
46
+ </div>
47
+ </li>
48
+ <li class="pll-wizard-service-item">
49
+ <div class="pll-wizard-service-example">
50
+ <p>
51
+ <input id="slide-toggle" type="checkbox" checked="checked">
52
+ <label for="slide-toggle" class="button button-primary button-small">
53
+ <span class="dashicons dashicons-visibility"></span><?php esc_html_e( 'Help', 'polylang' ); ?>
54
+ </label>
55
+ <span id="screenshot">
56
+ <img src="<?php echo esc_url_raw( esc_url( plugins_url( $help_screenshot, POLYLANG_FILE ) ) ); ?>" />
57
+ </span>
58
+ </p>
59
+ </div>
60
+ </li>
61
+ </ul>
modules/wizard/view-wizard-step-untranslated-contents.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Displays the wizard unstranslated content step
5
+ *
6
+ * @since 2.7
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit; // Don't access directly.
11
+ };
12
+
13
+ $languages_list = $this->model->get_languages_list();
14
+ $default_language = ! empty( $languages_list ) ? $this->options['default_lang'] : '';
15
+ ?>
16
+ <h2><?php esc_html_e( 'Content without language', 'polylang' ); ?></h2>
17
+ <p>
18
+ <?php esc_html_e( 'There are posts, pages, categories or tags without language.', 'polylang' ); ?><br />
19
+ <?php esc_html_e( 'For your site to work correctly, you need to assign a language to all your contents.', 'polylang' ); ?><br />
20
+ <?php esc_html_e( 'The selected language below will be applied to all your content without an assigned language.', 'polylang' ); ?>
21
+ </p>
22
+ <div class="form-field">
23
+ <label for="lang_list"><?php esc_html_e( 'Choose the language to be assigned', 'polylang' ); ?></label>
24
+ <select name="language" id="lang_list">
25
+ <?php
26
+ foreach ( $languages_list as $lg ) {
27
+ printf(
28
+ '<option value="%1$s" data-flag-html="%3$s" data-language-name="%2$s"%4$s>%2$s - %1$s</option>' . "\n",
29
+ esc_attr( $lg->locale ),
30
+ esc_html( $lg->name ),
31
+ esc_html( $lg->flag ),
32
+ $lg->slug === $default_language ? ' selected="selected"' : ''
33
+ );
34
+ }
35
+ ?>
36
+ </select>
37
+ </div>
modules/wizard/wizard.php ADDED
@@ -0,0 +1,784 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Main class for Polylang wizard.
4
+ *
5
+ * @since 2.7
6
+ */
7
+ class PLL_Wizard {
8
+ /**
9
+ * Reference to PLL_Model object
10
+ *
11
+ * @var object $model
12
+ */
13
+ protected $model;
14
+
15
+ /**
16
+ * Reference to Polylang options array
17
+ *
18
+ * @var array $options
19
+ */
20
+ protected $options;
21
+
22
+ /**
23
+ * List of steps
24
+ *
25
+ * @var array $steps
26
+ */
27
+ protected $steps = array();
28
+
29
+ /**
30
+ * List of WordPress CSS file handles
31
+ *
32
+ * @var array $styles
33
+ */
34
+ protected $styles = array();
35
+
36
+ /**
37
+ * Constructor
38
+ *
39
+ * @param object $polylang Reference to Polylang global object.
40
+ * @since 2.7
41
+ */
42
+ public function __construct( &$polylang ) {
43
+ $this->options = &$polylang->options;
44
+ $this->model = &$polylang->model;
45
+
46
+ // Display Wizard page before any other action to ensure displaying it outside the WordPress admin context.
47
+ // Hooked on admin_init with priority 40 to ensure PLL_Wizard_Pro is corretly initialized.
48
+ add_action( 'admin_init', array( $this, 'setup_wizard_page' ), 40 );
49
+ // Add Wizard submenu.
50
+ add_filter( 'pll_settings_tabs', array( $this, 'settings_tabs' ), 10, 1 );
51
+ // Add filter to select screens where to display the notice.
52
+ add_filter( 'pll_can_display_notice', array( $this, 'can_display_notice' ), 10, 2 );
53
+
54
+ // Default steps.
55
+ add_filter( 'pll_wizard_steps', array( $this, 'add_step_licenses' ), 100 );
56
+ add_filter( 'pll_wizard_steps', array( $this, 'add_step_languages' ), 200 );
57
+ add_filter( 'pll_wizard_steps', array( $this, 'add_step_media' ), 300 );
58
+ add_filter( 'pll_wizard_steps', array( $this, 'add_step_untranslated_contents' ), 400 );
59
+ add_filter( 'pll_wizard_steps', array( $this, 'add_step_home_page' ), 500 );
60
+ add_filter( 'pll_wizard_steps', array( $this, 'add_step_last' ), 999 );
61
+ }
62
+
63
+ /**
64
+ * Save an activation transient when Polylang is activating to redirect to the wizard
65
+ *
66
+ * @param bool $network_wide if activated for all sites in the network.
67
+ * @since 2.7
68
+ */
69
+ public static function start_wizard( $network_wide ) {
70
+ $options = get_option( 'polylang' );
71
+
72
+ if ( wp_doing_ajax() || $network_wide || ! empty( $options ) ) {
73
+ return;
74
+ }
75
+ set_transient( 'pll_activation_redirect', 1, 30 );
76
+ }
77
+
78
+ /**
79
+ * Redirect to the wizard depending on the context
80
+ *
81
+ * @since 2.7
82
+ */
83
+ public function redirect_to_wizard() {
84
+ if ( get_transient( 'pll_activation_redirect' ) ) {
85
+ $do_redirect = true;
86
+ if ( ( isset( $_GET['page'] ) && 'mlang_wizard' === sanitize_key( $_GET['page'] ) || isset( $_GET['activate-multi'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
87
+ delete_transient( 'pll_activation_redirect' );
88
+ $do_redirect = false;
89
+ }
90
+
91
+ if ( $do_redirect ) {
92
+ wp_safe_redirect(
93
+ esc_url_raw(
94
+ add_query_arg(
95
+ array(
96
+ 'page' => 'mlang_wizard',
97
+ ),
98
+ admin_url( 'admin.php' )
99
+ )
100
+ )
101
+ );
102
+ exit;
103
+ }
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Add an admin Polylang submenu to access the wizard
109
+ *
110
+ * @param array $tabs Submenus list.
111
+ * @return array Submenus list updated.
112
+ * @since 2.7
113
+ */
114
+ public function settings_tabs( $tabs ) {
115
+ $tabs['wizard'] = __( 'Setup', 'polylang' );
116
+ return $tabs;
117
+ }
118
+
119
+ /**
120
+ * Return if the media step is displayable
121
+ *
122
+ * @param array $languages List of language objects.
123
+ * @return bool
124
+ * @since 2.7
125
+ */
126
+ public function is_media_step_displayable( $languages ) {
127
+ $media = array();
128
+ // If there is no language or only one the media step is displayable.
129
+ if ( ! $languages || count( $languages ) < 2 ) {
130
+ return true;
131
+ }
132
+ foreach ( $languages as $language ) {
133
+ $media[ $language->slug ] = $this->model->count_posts(
134
+ $language,
135
+ array(
136
+ 'post_type' => array( 'attachment' ),
137
+ 'post_status' => 'inherit',
138
+ )
139
+ );
140
+ }
141
+ return count( array_filter( $media ) ) === 0;
142
+ }
143
+
144
+ /**
145
+ * Check if the licenses step is displayable
146
+ *
147
+ * @return bool
148
+ * @since 2.7
149
+ */
150
+ public function is_licenses_step_displayable() {
151
+ $licenses = apply_filters( 'pll_settings_licenses', array() );
152
+ return count( $licenses ) > 0;
153
+ }
154
+
155
+ /**
156
+ * Setup the wizard page
157
+ *
158
+ * @since 2.7
159
+ */
160
+ public function setup_wizard_page() {
161
+
162
+ PLL_Admin_Notices::add_notice( 'wizard', $this->wizard_notice() );
163
+
164
+ $this->redirect_to_wizard();
165
+ if ( ! Polylang::is_wizard() ) {
166
+ return;
167
+ }
168
+ if ( ! current_user_can( 'manage_options' ) ) {
169
+ wp_die( esc_html__( 'Sorry, you are not allowed to manage options for this site.', 'polylang' ) );
170
+ }
171
+
172
+ // Enqueue scripts and styles especially for the wizard.
173
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
174
+
175
+ $this->steps = apply_filters( 'pll_wizard_steps', $this->steps );
176
+ $step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : false; // phpcs:ignore WordPress.Security.NonceVerification
177
+
178
+ $this->step = $step && array_key_exists( $step, $this->steps ) ? $step : current( array_keys( $this->steps ) );
179
+
180
+ $languages = $this->model->get_languages_list();
181
+
182
+ if ( count( $languages ) === 0 && ! in_array( $this->step, array( 'licenses', 'languages' ) ) ) {
183
+ wp_safe_redirect( esc_url_raw( $this->get_step_link( 'languages' ) ) );
184
+ exit;
185
+ }
186
+
187
+ if ( count( $languages ) > 0 && $this->model->get_objects_with_no_lang( 1 ) && ! in_array( $this->step, array( 'licenses', 'languages', 'media', 'untranslated-contents' ) ) ) {
188
+ wp_safe_redirect( esc_url_raw( $this->get_step_link( 'untranslated-contents' ) ) );
189
+ exit;
190
+ }
191
+
192
+ // Call the handler of the step for going to the next step.
193
+ // Be careful nonce verification with check_admin_referer must be done in each handler.
194
+ if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
195
+ call_user_func( $this->steps[ $this->step ]['handler'] );
196
+ }
197
+
198
+ $this->display_wizard_page();
199
+ // Ensure nothing is done after including the page.
200
+ exit;
201
+ }
202
+
203
+ /**
204
+ * Adds some admin screens where to display the wizard notice
205
+ *
206
+ * @param bool $can_display_notice Whether the notice can be displayed.
207
+ * @param string $notice The notice name.
208
+ * @return bool
209
+ * @since 2.7
210
+ */
211
+ public function can_display_notice( $can_display_notice, $notice ) {
212
+ if ( ! $can_display_notice && 'wizard' === $notice ) {
213
+ $screen = get_current_screen();
214
+ $can_display_notice = in_array(
215
+ $screen->base,
216
+ array(
217
+ 'edit',
218
+ 'upload',
219
+ 'options-general',
220
+ )
221
+ );
222
+ }
223
+ return $can_display_notice;
224
+ }
225
+
226
+ /**
227
+ * Return html code of the wizard notice
228
+ *
229
+ * @since 2.7
230
+ */
231
+ public function wizard_notice() {
232
+ ob_start();
233
+ include PLL_MODULES_INC . '/wizard/html-wizard-notice.php';
234
+ return ob_get_clean();
235
+ }
236
+
237
+ /**
238
+ * Display the wizard page
239
+ *
240
+ * @since 2.7
241
+ */
242
+ public function display_wizard_page() {
243
+ set_current_screen();
244
+ include PLL_MODULES_INC . '/wizard/view-wizard-page.php';
245
+ }
246
+
247
+ /**
248
+ * Enqueue scripts and styles for the wizard
249
+ *
250
+ * @since 2.7
251
+ */
252
+ public function enqueue_scripts() {
253
+ wp_enqueue_style( 'polylang_admin', plugins_url( '/css/admin' . $this->get_suffix() . '.css', POLYLANG_FILE ), array(), POLYLANG_VERSION );
254
+ wp_enqueue_style( 'pll-wizard', plugins_url( '/modules/wizard/css/wizard' . $this->get_suffix() . '.css', POLYLANG_FILE ), array( 'dashicons', 'install', 'common', 'forms' ), POLYLANG_VERSION );
255
+
256
+ $this->styles = array( 'polylang_admin', 'pll-wizard' );
257
+ }
258
+
259
+ /**
260
+ * Get the suffix to enqueue non minified files in a Debug context
261
+ *
262
+ * @return string Empty when SCRIPT_DEBUG equal to true
263
+ * otherwise .min
264
+ * @since 2.7
265
+ */
266
+ public function get_suffix() {
267
+ return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
268
+ }
269
+
270
+ /**
271
+ * Get the URL for the step's screen.
272
+ *
273
+ * @param string $step slug (default: current step).
274
+ * @return string URL for the step if it exists.
275
+ * Empty string on failure.
276
+ * @since 2.7
277
+ */
278
+ public function get_step_link( $step = '' ) {
279
+ if ( ! $step ) {
280
+ $step = $this->step;
281
+ }
282
+
283
+ $keys = array_keys( $this->steps );
284
+
285
+ $step_index = array_search( $step, $keys, true );
286
+ if ( false === $step_index ) {
287
+ return '';
288
+ }
289
+
290
+ return add_query_arg( 'step', $keys[ $step_index ], remove_query_arg( 'activate_error' ) );
291
+ }
292
+
293
+ /**
294
+ * Get the URL for the next step's screen.
295
+ *
296
+ * @param string $step slug (default: current step).
297
+ * @return string URL for next step if a next step exists.
298
+ * Admin URL if it's the last step.
299
+ * Empty string on failure.
300
+ * @since 2.7
301
+ */
302
+ public function get_next_step_link( $step = '' ) {
303
+ if ( ! $step ) {
304
+ $step = $this->step;
305
+ }
306
+
307
+ $keys = array_keys( $this->steps );
308
+ if ( end( $keys ) === $step ) {
309
+ return admin_url();
310
+ }
311
+
312
+ $step_index = array_search( $step, $keys, true );
313
+ if ( false === $step_index ) {
314
+ return '';
315
+ }
316
+
317
+ return add_query_arg( 'step', $keys[ $step_index + 1 ], remove_query_arg( 'activate_error' ) );
318
+ }
319
+
320
+ /**
321
+ * Add licenses step to the wizard
322
+ *
323
+ * @param array $steps List of steps.
324
+ * @return array List of steps updated.
325
+ * @since 2.7
326
+ */
327
+ public function add_step_licenses( $steps ) {
328
+ // Add ajax action on deactivate button in licenses step.
329
+ add_action( 'wp_ajax_pll_deactivate_license', array( $this, 'deactivate_license' ) );
330
+
331
+ wp_enqueue_script( 'pll_admin', plugins_url( '/js/admin' . $this->get_suffix() . '.js', POLYLANG_FILE ), array( 'jquery', 'jquery-ui-selectmenu' ), POLYLANG_VERSION, true );
332
+ if ( $this->is_licenses_step_displayable() ) {
333
+ $steps['licenses'] = array(
334
+ 'name' => __( 'Licenses', 'polylang' ),
335
+ 'view' => array( $this, 'display_step_licenses' ),
336
+ 'handler' => array( $this, 'save_step_licenses' ),
337
+ 'scripts' => array( 'pll_admin' ), // Polylang admin script used by deactivate license button.
338
+ 'styles' => array(),
339
+ );
340
+ }
341
+ return $steps;
342
+ }
343
+
344
+ /**
345
+ * Display the languages step form
346
+ *
347
+ * @since 2.7
348
+ */
349
+ public function display_step_licenses() {
350
+ include PLL_MODULES_INC . '/wizard/view-wizard-step-licenses.php';
351
+ }
352
+
353
+ /**
354
+ * Execute the languages step
355
+ *
356
+ * @since 2.7
357
+ */
358
+ public function save_step_licenses() {
359
+ check_admin_referer( 'pll-wizard', '_pll_nonce' );
360
+
361
+ $redirect = $this->get_next_step_link();
362
+ $licenses = apply_filters( 'pll_settings_licenses', array() );
363
+
364
+ foreach ( $licenses as $license ) {
365
+ if ( ! empty( $_POST['licenses'][ $license->id ] ) ) {
366
+ $updated_license = $license->activate_license( sanitize_key( $_POST['licenses'][ $license->id ] ) );
367
+ if ( ! empty( $updated_license->license_data ) && false === $updated_license->license_data->success ) {
368
+ // Stay on this step with an error.
369
+ $redirect = add_query_arg(
370
+ array(
371
+ 'step' => $this->step,
372
+ 'activate_error' => 'i18n_license_key_error',
373
+ )
374
+ );
375
+ }
376
+ }
377
+ }
378
+
379
+ wp_safe_redirect( esc_url_raw( $redirect ) );
380
+ exit;
381
+ }
382
+
383
+ /**
384
+ * Ajax method to deactivate a license
385
+ *
386
+ * @since 2.7
387
+ */
388
+ public function deactivate_license() {
389
+ check_ajax_referer( 'pll-wizard', '_pll_nonce' );
390
+
391
+ if ( ! current_user_can( 'manage_options' ) ) {
392
+ wp_die( -1 );
393
+ }
394
+
395
+ if ( ! isset( $_POST['id'] ) ) {
396
+ wp_die( 0 );
397
+ }
398
+
399
+ $id = substr( sanitize_text_field( wp_unslash( $_POST['id'] ) ), 11 );
400
+ $licenses = apply_filters( 'pll_settings_licenses', array() );
401
+ $license = $licenses[ $id ];
402
+ $license->deactivate_license();
403
+
404
+ wp_send_json(
405
+ array(
406
+ 'id' => $id,
407
+ 'html' => $license->get_form_field(),
408
+ )
409
+ );
410
+ }
411
+
412
+ /**
413
+ * Add languages step to the wizard
414
+ *
415
+ * @param array $steps List of steps.
416
+ * @return array List of steps updated.
417
+ * @since 2.7
418
+ */
419
+ public function add_step_languages( $steps ) {
420
+ wp_enqueue_script( 'pll-wizard-language-choice', plugins_url( '/js/admin' . $this->get_suffix() . '.js', POLYLANG_FILE ), array( 'jquery', 'jquery-ui-selectmenu' ), POLYLANG_VERSION, true );
421
+ wp_register_script( 'pll-wizard-languages', plugins_url( '/modules/wizard/js/languages-step' . $this->get_suffix() . '.js', POLYLANG_FILE ), array( 'jquery', 'jquery-ui-dialog' ), POLYLANG_VERSION, true );
422
+ wp_localize_script(
423
+ 'pll-wizard-languages',
424
+ 'pll_wizard_params',
425
+ array(
426
+ 'i18n_no_language_selected' => __( 'You need to select a language to be added.', 'polylang' ),
427
+ 'i18n_language_already_added' => __( 'You already added this language.', 'polylang' ),
428
+ 'i18n_no_language_added' => __( 'You need to add at least one language.', 'polylang' ),
429
+ 'i18n_add_language_needed' => __( 'You selected a language, however, to be able to continue, you need to add it.', 'polylang' ),
430
+ 'i18n_pll_add_language' => __( 'Impossible to add the language.', 'polylang' ),
431
+ 'i18n_pll_invalid_locale' => __( 'Enter a valid WordPress locale', 'polylang' ),
432
+ 'i18n_pll_invalid_slug' => __( 'The language code contains invalid characters', 'polylang' ),
433
+ 'i18n_pll_non_unique_slug' => __( 'The language code must be unique', 'polylang' ),
434
+ 'i18n_pll_invalid_name' => __( 'The language must have a name', 'polylang' ),
435
+ 'i18n_pll_invalid_flag' => __( 'The flag does not exist', 'polylang' ),
436
+ 'i18n_dialog_title' => __( "A language wasn't added.", 'polylang' ),
437
+ 'i18n_dialog_yes_button' => __( 'Yes', 'polylang' ),
438
+ 'i18n_dialog_no_button' => __( 'No', 'polylang' ),
439
+ 'i18n_dialog_ignore_button' => __( 'Ignore', 'polylang' ),
440
+ 'i18n_remove_language_icon' => __( 'Remove this language', 'polylang' ),
441
+ )
442
+ );
443
+ wp_enqueue_script( 'pll-wizard-languages' );
444
+ wp_enqueue_style( 'pll-wizard-selectmenu', plugins_url( '/css/selectmenu' . $this->get_suffix() . '.css', POLYLANG_FILE ), array( 'dashicons', 'install', 'common', 'wp-jquery-ui-dialog' ), POLYLANG_VERSION );
445
+ $steps['languages'] = array(
446
+ 'name' => __( 'Languages', 'polylang' ),
447
+ 'view' => array( $this, 'display_step_languages' ),
448
+ 'handler' => array( $this, 'save_step_languages' ),
449
+ 'scripts' => array( 'pll-wizard-languages', 'pll-wizard-language-choice' ),
450
+ 'styles' => array( 'pll-wizard-selectmenu' ),
451
+ );
452
+ return $steps;
453
+ }
454
+
455
+ /**
456
+ * Display the languages step form
457
+ *
458
+ * @since 2.7
459
+ */
460
+ public function display_step_languages() {
461
+ include PLL_MODULES_INC . '/wizard/view-wizard-step-languages.php';
462
+ }
463
+
464
+ /**
465
+ * Execute the languages step
466
+ *
467
+ * @since 2.7
468
+ */
469
+ public function save_step_languages() {
470
+ check_admin_referer( 'pll-wizard', '_pll_nonce' );
471
+
472
+ $existing_languages = $this->model->get_languages_list();
473
+
474
+ $all_languages = include PLL_SETTINGS_INC . '/languages.php';
475
+ $languages = isset( $_POST['languages'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['languages'] ) ) : false;
476
+ $saved_languages = array();
477
+
478
+ // If there is no language added or defined.
479
+ if ( empty( $languages ) && empty( $existing_languages ) ) {
480
+ // Stay on this step with an error.
481
+ wp_safe_redirect(
482
+ esc_url_raw(
483
+ add_query_arg(
484
+ array(
485
+ 'step' => $this->step,
486
+ 'activate_error' => 'i18n_no_language_added',
487
+ )
488
+ )
489
+ )
490
+ );
491
+ exit;
492
+ }
493
+
494
+ // Otherwise process the languages to add or skip the step if no language has been added.
495
+ if ( ! empty( $languages ) ) {
496
+ require_once ABSPATH . 'wp-admin/includes/translation-install.php';
497
+ // Remove duplicate values.
498
+ $languages = array_unique( $languages );
499
+ // For each language add it in Polylang settings.
500
+ foreach ( $languages as $locale ) {
501
+ $saved_languages = $all_languages[ $locale ];
502
+
503
+ $saved_languages['slug'] = $saved_languages['code'];
504
+ $saved_languages['rtl'] = (int) ( 'rtl' === $saved_languages['dir'] );
505
+ $saved_languages['term_group'] = 0; // Default term_group.
506
+
507
+ $language_added = $this->model->add_language( $saved_languages );
508
+
509
+ if ( $language_added instanceof WP_Error && array_key_exists( 'pll_non_unique_slug', $language_added->errors ) ) {
510
+ // Get the slug from the locale : lowercase and dash instead of underscore.
511
+ $saved_languages['slug'] = strtolower( str_replace( '_', '-', $saved_languages['locale'] ) );
512
+ $language_added = $this->model->add_language( $saved_languages );
513
+ }
514
+
515
+ if ( $language_added instanceof WP_Error ) {
516
+ // Stay on this step with an error.
517
+ $error_keys = array_keys( $language_added->errors );
518
+ wp_safe_redirect(
519
+ esc_url_raw(
520
+ add_query_arg(
521
+ array(
522
+ 'step' => $this->step,
523
+ 'activate_error' => 'i18n_' . reset( $error_keys ),
524
+ )
525
+ )
526
+ )
527
+ );
528
+ exit;
529
+ }
530
+ if ( 'en_US' !== $locale ) {
531
+ wp_download_language_pack( $locale );
532
+ }
533
+ }
534
+ }
535
+ wp_safe_redirect( esc_url_raw( $this->get_next_step_link() ) );
536
+ exit;
537
+ }
538
+
539
+ /**
540
+ * Add media step to the wizard
541
+ * Add media step to the wizard
542
+ *
543
+ * @param array $steps List of steps.
544
+ * @return array List of steps updated.
545
+ * @since 2.7
546
+ */
547
+ public function add_step_media( $steps ) {
548
+ $languages = $this->model->get_languages_list();
549
+
550
+ if ( $this->is_media_step_displayable( $languages ) ) {
551
+ $steps['media'] = array(
552
+ 'name' => __( 'Media', 'polylang' ),
553
+ 'view' => array( $this, 'display_step_media' ),
554
+ 'handler' => array( $this, 'save_step_media' ),
555
+ 'scripts' => array(),
556
+ 'styles' => array(),
557
+ );
558
+ }
559
+ return $steps;
560
+ }
561
+
562
+ /**
563
+ * Display the media step form
564
+ *
565
+ * @since 2.7
566
+ */
567
+ public function display_step_media() {
568
+ include PLL_MODULES_INC . '/wizard/view-wizard-step-media.php';
569
+ }
570
+
571
+ /**
572
+ * Execute the media step
573
+ *
574
+ * @since 2.7
575
+ */
576
+ public function save_step_media() {
577
+ check_admin_referer( 'pll-wizard', '_pll_nonce' );
578
+
579
+ $media_support = isset( $_POST['media_support'] ) ? sanitize_key( $_POST['media_support'] ) === 'yes' : false;
580
+
581
+ $this->options['media_support'] = $media_support;
582
+
583
+ update_option( 'polylang', $this->options );
584
+
585
+ wp_safe_redirect( esc_url_raw( $this->get_next_step_link() ) );
586
+ exit;
587
+ }
588
+
589
+ /**
590
+ * Add untranslated contents step to the wizard
591
+ *
592
+ * @param array $steps List of steps.
593
+ * @return array List of steps updated.
594
+ * @since 2.7
595
+ */
596
+ public function add_step_untranslated_contents( $steps ) {
597
+ if ( ! $this->model->get_languages_list() || $this->model->get_objects_with_no_lang( 1 ) ) {
598
+ wp_enqueue_script( 'pll-wizard-language-choice', plugins_url( '/js/admin' . $this->get_suffix() . '.js', POLYLANG_FILE ), array( 'jquery', 'jquery-ui-selectmenu' ), POLYLANG_VERSION, true );
599
+ wp_enqueue_style( 'pll-wizard-selectmenu', plugins_url( '/css/selectmenu' . $this->get_suffix() . '.css', POLYLANG_FILE ), array( 'dashicons', 'install', 'common' ), POLYLANG_VERSION );
600
+ $steps['untranslated-contents'] = array(
601
+ 'name' => __( 'Content', 'polylang' ),
602
+ 'view' => array( $this, 'display_step_untranslated_contents' ),
603
+ 'handler' => array( $this, 'save_step_untranslated_contents' ),
604
+ 'scripts' => array( 'pll-wizard-language-choice' ),
605
+ 'styles' => array( 'pll-wizard-selectmenu' ),
606
+ );
607
+ }
608
+ return $steps;
609
+ }
610
+
611
+ /**
612
+ * Display the untranslated contents step form
613
+ *
614
+ * @since 2.7
615
+ */
616
+ public function display_step_untranslated_contents() {
617
+ include PLL_MODULES_INC . '/wizard/view-wizard-step-untranslated-contents.php';
618
+ }
619
+
620
+ /**
621
+ * Execute the untranslated contents step
622
+ *
623
+ * @since 2.7
624
+ */
625
+ public function save_step_untranslated_contents() {
626
+ check_admin_referer( 'pll-wizard', '_pll_nonce' );
627
+
628
+ $lang = isset( $_POST['language'] ) ? sanitize_text_field( wp_unslash( $_POST['language'] ) ) : false;
629
+
630
+ if ( empty( $lang ) ) {
631
+ $lang = $this->options['default_lang'];
632
+ }
633
+
634
+ $language = $this->model->get_language( $lang );
635
+
636
+ while ( $nolang = $this->model->get_objects_with_no_lang( 1000 ) ) {
637
+ if ( ! empty( $nolang['posts'] ) ) {
638
+ $this->model->set_language_in_mass( 'post', $nolang['posts'], $language->slug );
639
+ }
640
+ if ( ! empty( $nolang['terms'] ) ) {
641
+ $this->model->set_language_in_mass( 'term', $nolang['terms'], $language->slug );
642
+ }
643
+ }
644
+
645
+ wp_safe_redirect( esc_url_raw( $this->get_next_step_link() ) );
646
+ exit;
647
+ }
648
+
649
+ /**
650
+ * Add home page step to the wizard
651
+ *
652
+ * @param array $steps List of steps.
653
+ * @return array List of steps updated.
654
+ * @since 2.7
655
+ */
656
+ public function add_step_home_page( $steps ) {
657
+ $languages = $this->model->get_languages_list();
658
+ $home_page_id = get_option( 'page_on_front' );
659
+
660
+ $translations = $this->model->post->get_translations( $home_page_id );
661
+
662
+ if ( $home_page_id > 0 && ( ! $languages || count( $languages ) === 1 || count( $translations ) !== count( $languages ) ) ) {
663
+ $steps['home-page'] = array(
664
+ 'name' => __( 'Homepage', 'polylang' ),
665
+ 'view' => array( $this, 'display_step_home_page' ),
666
+ 'handler' => array( $this, 'save_step_home_page' ),
667
+ 'scripts' => array(),
668
+ 'styles' => array(),
669
+ );
670
+ }
671
+ return $steps;
672
+ }
673
+
674
+ /**
675
+ * Display the home page step form
676
+ *
677
+ * @since 2.7
678
+ */
679
+ public function display_step_home_page() {
680
+ include PLL_MODULES_INC . '/wizard/view-wizard-step-home-page.php';
681
+ }
682
+
683
+ /**
684
+ * Execute the home page step
685
+ *
686
+ * @since 2.7
687
+ */
688
+ public function save_step_home_page() {
689
+ check_admin_referer( 'pll-wizard', '_pll_nonce' );
690
+
691
+ $languages = $this->model->get_languages_list();
692
+
693
+ $default_language = count( $languages ) > 0 ? $this->options['default_lang'] : null;
694
+ $home_page = isset( $_POST['home_page'] ) ? sanitize_key( $_POST['home_page'] ) : false;
695
+ $home_page_title = isset( $_POST['home_page_title'] ) ? sanitize_text_field( wp_unslash( $_POST['home_page_title'] ) ) : esc_html__( 'Homepage', 'polylang' );
696
+ $home_page_language = isset( $_POST['home_page_language'] ) ? sanitize_key( $_POST['home_page_language'] ) : false;
697
+
698
+ $untranslated_languages = isset( $_POST['untranslated_languages'] ) ? array_map( 'sanitize_key', $_POST['untranslated_languages'] ) : array();
699
+
700
+ call_user_func(
701
+ apply_filters( 'pll_wizard_create_home_page_translations', array( $this, 'create_home_page_translations' ) ),
702
+ $default_language,
703
+ $home_page,
704
+ $home_page_title,
705
+ $home_page_language,
706
+ $untranslated_languages
707
+ );
708
+
709
+ $this->model->clean_languages_cache();
710
+
711
+ wp_safe_redirect( esc_url_raw( $this->get_next_step_link() ) );
712
+ exit;
713
+ }
714
+
715
+ /**
716
+ * Create home page translations for each language defined.
717
+ *
718
+ * @since 2.7
719
+ *
720
+ * @param string $default_language slug of the default language; null if no default language is defined.
721
+ * @param int $home_page post_id of the home page if it's defined, false otherwise.
722
+ * @param string $home_page_title home page title if it's defined, 'Homepage' otherwise.
723
+ * @param string $home_page_language slug of the home page if it's defined, false otherwise.
724
+ * @param array $untranslated_languages array of languages which needs to have a home page translated.
725
+ */
726
+ public function create_home_page_translations( $default_language, $home_page, $home_page_title, $home_page_language, $untranslated_languages ) {
727
+ $translations = $this->model->post->get_translations( $home_page );
728
+
729
+ foreach ( $untranslated_languages as $language ) {
730
+ $language_properties = $this->model->get_language( $language );
731
+ $id = wp_insert_post(
732
+ array(
733
+ 'post_title' => $home_page_title . ' - ' . $language_properties->name,
734
+ 'post_type' => 'page',
735
+ 'post_status' => 'publish',
736
+ )
737
+ );
738
+ $translations[ $language ] = $id;
739
+ pll_set_post_language( $id, $language );
740
+ }
741
+ pll_save_post_translations( $translations );
742
+ }
743
+
744
+ /**
745
+ * Add last step to the wizard
746
+ *
747
+ * @param array $steps List of steps.
748
+ * @return array List of steps updated.
749
+ * @since 2.7
750
+ */
751
+ public function add_step_last( $steps ) {
752
+ $steps['last'] = array(
753
+ 'name' => __( 'Ready!', 'polylang' ),
754
+ 'view' => array( $this, 'display_step_last' ),
755
+ 'handler' => array( $this, 'save_step_last' ),
756
+ 'scripts' => array(),
757
+ 'styles' => array(),
758
+ );
759
+ return $steps;
760
+ }
761
+
762
+ /**
763
+ * Display the last step form
764
+ *
765
+ * @since 2.7
766
+ */
767
+ public function display_step_last() {
768
+ // We ran the wizard once. So we can dismiss its notice.
769
+ PLL_Admin_Notices::dismiss( 'wizard' );
770
+ include PLL_MODULES_INC . '/wizard/view-wizard-step-last.php';
771
+ }
772
+
773
+ /**
774
+ * Execute the last step
775
+ *
776
+ * @since 2.7
777
+ */
778
+ public function save_step_last() {
779
+ check_admin_referer( 'pll-wizard', '_pll_nonce' );
780
+
781
+ wp_safe_redirect( esc_url_raw( $this->get_next_step_link() ) );
782
+ exit;
783
+ }
784
+ }
polylang.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  Plugin Name: Polylang
5
  Plugin URI: https://polylang.pro
6
- Version: 2.7
7
  Author: WP SYNTEX
8
  Author uri: https://polylang.pro
9
  Description: Adds multilingual capability to WordPress
@@ -51,7 +51,7 @@ if ( defined( 'POLYLANG_BASENAME' ) ) {
51
  }
52
  } else {
53
  // Go on loading the plugin
54
- define( 'POLYLANG_VERSION', '2.7' );
55
  define( 'PLL_MIN_WP_VERSION', '4.9' );
56
  define( 'PLL_MIN_PHP_VERSION', '5.6' );
57
 
3
  /**
4
  Plugin Name: Polylang
5
  Plugin URI: https://polylang.pro
6
+ Version: 2.7.0.1
7
  Author: WP SYNTEX
8
  Author uri: https://polylang.pro
9
  Description: Adds multilingual capability to WordPress
51
  }
52
  } else {
53
  // Go on loading the plugin
54
+ define( 'POLYLANG_VERSION', '2.7.0.1' );
55
  define( 'PLL_MIN_WP_VERSION', '4.9' );
56
  define( 'PLL_MIN_PHP_VERSION', '5.6' );
57
 
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: multilingual, bilingual, translate, translation, language, multilanguage,
5
  Requires at least: 4.9
6
  Tested up to: 5.4
7
  Requires PHP: 5.6
8
- Stable tag: 2.7
9
  License: GPLv3 or later
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
11
 
5
  Requires at least: 4.9
6
  Tested up to: 5.4
7
  Requires PHP: 5.6
8
+ Stable tag: 2.7.0.1
9
  License: GPLv3 or later
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
11