LearnPress – WordPress LMS Plugin - Version 2.1.1

Version Description

  • Added options to change value of lessons/quizzes in course item permalink
  • Improved edit profile page
  • Improved permalink for lesson/quiz
  • Improved some options
  • Improved some sections in admin
  • Fixed "Preview change" button show 404 page
  • Fixed question show randomly when starting quiz
  • Fixed username contains spacing
Download this release

Release Info

Developer tunnhn
Plugin Icon 128x128 LearnPress – WordPress LMS Plugin
Version 2.1.1
Comparing to
See all releases

Code changes from version 2.1.0 to 2.1.1

Files changed (42) hide show
  1. assets/css/admin/admin.css +41 -20
  2. assets/css/admin/admin.less +40 -16
  3. assets/css/admin/meta-box-course.css +1 -0
  4. assets/css/admin/meta-box-course.less +980 -979
  5. assets/css/learnpress-course-coming-soon.css +0 -330
  6. assets/css/learnpress.css +230 -178
  7. assets/css/learnpress.less +2152 -2106
  8. assets/js/admin/admin.js +29 -5
  9. assets/js/admin/meta-box-course.js +1 -2
  10. assets/js/admin/settings.js +5 -0
  11. assets/js/frontend/checkout.js +137 -131
  12. assets/js/frontend/profile.js +552 -276
  13. assets/js/frontend/quiz.js +916 -904
  14. assets/js/global.js +1 -25
  15. inc/admin/class-lp-admin-ajax.php +1139 -1139
  16. inc/admin/class-lp-admin.php +230 -228
  17. inc/admin/lp-admin-functions.php +2032 -2029
  18. inc/admin/meta-boxes/class-quiz-questions-field.php +193 -200
  19. inc/admin/settings/class-lp-settings-checkout.php +80 -87
  20. inc/admin/settings/class-lp-settings-general.php +124 -131
  21. inc/admin/settings/class-lp-settings-pages.php +212 -202
  22. inc/admin/views/settings/emails/_email-template.php +10 -2
  23. inc/admin/views/settings/emails/email-template.php +10 -2
  24. inc/admin/views/settings/fields/image-size.php +21 -20
  25. inc/admin/views/settings/fields/title.php +2 -2
  26. inc/admin/views/settings/general.php +24 -24
  27. inc/cart/class-lp-cart.php +663 -653
  28. inc/class-lp-ajax.php +655 -624
  29. inc/class-lp-assets.php +808 -803
  30. inc/class-lp-autoloader.php +5 -5
  31. inc/class-lp-install.php +656 -657
  32. inc/class-lp-page-controller.php +429 -387
  33. inc/class-lp-session-handler.php +357 -358
  34. inc/class-lp-shortcodes.php +374 -371
  35. inc/course/lp-course-functions.php +788 -774
  36. inc/custom-post-types/course.php +1563 -1566
  37. inc/debug.php +8 -0
  38. inc/emails/class-lp-email-become-an-instructor.php +21 -21
  39. inc/gateways/class-lp-gateways.php +84 -83
  40. inc/lp-add-on-functions.php +28 -8
  41. inc/lp-constants.php +1 -1
  42. inc/lp-core-functions.php +0 -2183
assets/css/admin/admin.css CHANGED
@@ -34,6 +34,21 @@
34
  .post-type-lp_course #course_curriculum .curriculum-section-items .lp-item-empty td.section-item-input.hover {
35
  padding-left: 0;
36
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  #learn-press-admin-settings #learn_press_email_formats {
38
  margin-bottom: 10px;
39
  }
@@ -105,25 +120,39 @@
105
  display: none;
106
  }
107
  #learn-press-admin-settings input[type="radio"] {
108
- margin: 0;
109
  }
110
  #learn-press-admin-settings label {
111
  line-height: 1;
112
  }
113
- #learn-press-admin-settings input[name="learn_press_single_course_image_size[width]"],
114
- #learn-press-admin-settings input[name="learn_press_single_course_image_size[height]"],
115
- #learn-press-admin-settings input[name="learn_press_course_thumbnail_image_size[width]"],
116
- #learn-press-admin-settings input[name="learn_press_course_thumbnail_image_size[height]"] {
117
- margin-top: -4px;
118
- }
119
- #learn-press-admin-settings input[name="learn_press_single_course_image_size[crop]"],
120
- #learn-press-admin-settings input[name="learn_press_course_thumbnail_image_size[crop]"] {
121
- margin-top: 3px;
122
- }
123
  #learn-press-admin-settings input[name="learn_press_course_base"] {
124
  margin-top: 3px;
125
  margin-right: 3px;
126
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  /* message box */
128
  #learn-press-message-box-block {
129
  position: fixed;
@@ -352,7 +381,6 @@ li.quick_quiz {
352
  .learnpress-advertis-admin .learnpress-controls {
353
  position: absolute;
354
  bottom: 30px;
355
- left: 0;
356
  right: 0;
357
  height: 50px;
358
  -ms-transform: translateY(-50%);
@@ -1545,13 +1573,6 @@ input.regular-text[id^="learn-press-emails"] {
1545
  width: 100px;
1546
  text-align: left;
1547
  }
1548
- #learn-press-admin-settings .form-table th {
1549
- padding: 20px 10px 20px 0 !important;
1550
- }
1551
- #learn-press-admin-settings input,
1552
- #learn-press-admin-settings select {
1553
- vertical-align: top;
1554
- }
1555
  #learn_press_dashboard_widget .rss-widget ul li {
1556
  margin-bottom: 10px !important;
1557
  }
@@ -1634,7 +1655,7 @@ input.regular-text[id^="learn-press-emails"] {
1634
  width: 50%;
1635
  }
1636
  .lp-template-overrides #learn-press-no-templates td p {
1637
- color: #FF0000;
1638
  }
1639
  @-webkit-keyframes lp-spinner {
1640
  0% {
34
  .post-type-lp_course #course_curriculum .curriculum-section-items .lp-item-empty td.section-item-input.hover {
35
  padding-left: 0;
36
  }
37
+ .post-type-lp_course .type-lp_course.status-pending .row-actions .view {
38
+ display: none;
39
+ }
40
+ #learn-press-admin-settings {
41
+ /*input[name="learn_press_single_course_image_size[width]"],
42
+ input[name="learn_press_single_course_image_size[height]"],
43
+ input[name="learn_press_course_thumbnail_image_size[width]"],
44
+ input[name="learn_press_course_thumbnail_image_size[height]"] {
45
+ margin-top: -4px;
46
+ }
47
+ input[name="learn_press_single_course_image_size[crop]"],
48
+ input[name="learn_press_course_thumbnail_image_size[crop]"] {
49
+ margin-top: 3px;
50
+ }*/
51
+ }
52
  #learn-press-admin-settings #learn_press_email_formats {
53
  margin-bottom: 10px;
54
  }
120
  display: none;
121
  }
122
  #learn-press-admin-settings input[type="radio"] {
123
+ margin: 0 !important;
124
  }
125
  #learn-press-admin-settings label {
126
  line-height: 1;
127
  }
 
 
 
 
 
 
 
 
 
 
128
  #learn-press-admin-settings input[name="learn_press_course_base"] {
129
  margin-top: 3px;
130
  margin-right: 3px;
131
  }
132
+ #learn-press-admin-settings .lp-group-title {
133
+ padding: 0 0 10px;
134
+ border-bottom: 3px solid #563d7c;
135
+ display: inline-block;
136
+ margin: 0;
137
+ }
138
+ #learn-press-admin-settings input[type="text"],
139
+ #learn-press-admin-settings input[type="email"],
140
+ #learn-press-admin-settings input[type="number"],
141
+ #learn-press-admin-settings input[type="tel"],
142
+ #learn-press-admin-settings input[type="password"],
143
+ #learn-press-admin-settings select {
144
+ vertical-align: top;
145
+ }
146
+ #learn-press-admin-settings input[type="checkbox"] {
147
+ opacity: 1;
148
+ }
149
+ #learn-press-admin-settings .lp-setting-field span {
150
+ vertical-align: top;
151
+ line-height: 24px;
152
+ }
153
+ #learn-press-admin-settings .lp-setting-field .lp-sign-times {
154
+ font-size: 19px;
155
+ }
156
  /* message box */
157
  #learn-press-message-box-block {
158
  position: fixed;
381
  .learnpress-advertis-admin .learnpress-controls {
382
  position: absolute;
383
  bottom: 30px;
 
384
  right: 0;
385
  height: 50px;
386
  -ms-transform: translateY(-50%);
1573
  width: 100px;
1574
  text-align: left;
1575
  }
 
 
 
 
 
 
 
1576
  #learn_press_dashboard_widget .rss-widget ul li {
1577
  margin-bottom: 10px !important;
1578
  }
1655
  width: 50%;
1656
  }
1657
  .lp-template-overrides #learn-press-no-templates td p {
1658
+ color: #0073aa;
1659
  }
1660
  @-webkit-keyframes lp-spinner {
1661
  0% {
assets/css/admin/admin.less CHANGED
@@ -43,6 +43,16 @@
43
  padding-left: 0;
44
  }
45
  }
 
 
 
 
 
 
 
 
 
 
46
  }
47
 
48
  #learn-press-admin-settings {
@@ -119,12 +129,12 @@
119
  }
120
  }
121
  input[type="radio"] {
122
- margin: 0;
123
  }
124
  label {
125
  line-height: 1;
126
  }
127
- input[name="learn_press_single_course_image_size[width]"],
128
  input[name="learn_press_single_course_image_size[height]"],
129
  input[name="learn_press_course_thumbnail_image_size[width]"],
130
  input[name="learn_press_course_thumbnail_image_size[height]"] {
@@ -133,12 +143,38 @@
133
  input[name="learn_press_single_course_image_size[crop]"],
134
  input[name="learn_press_course_thumbnail_image_size[crop]"] {
135
  margin-top: 3px;
136
- }
137
 
138
  input[name="learn_press_course_base"] {
139
  margin-top: 3px;
140
  margin-right: 3px;
141
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  }
143
 
144
  /* message box */
@@ -406,7 +442,6 @@ li.quiz, li.lesson, li.quick_lesson, li.quick_quiz {
406
 
407
  position: absolute;
408
  bottom: 30px;
409
- left: 0;
410
  right: 0;
411
  height: 50px;
412
  -ms-transform: translateY(-50%);
@@ -504,7 +539,6 @@ li.quiz, li.lesson, li.quick_lesson, li.quick_quiz {
504
  text-decoration: none;
505
  content: attr(data-text-disable);
506
  }
507
-
508
  .lp-search-addon {
509
  margin: 0;
510
  width: 280px;
@@ -1847,16 +1881,6 @@ input.regular-text[id^="learn-press-emails"] {
1847
  text-align: left;
1848
  }
1849
 
1850
- #learn-press-admin-settings .form-table th {
1851
- padding: 20px 10px 20px 0 !important;
1852
- }
1853
-
1854
- #learn-press-admin-settings {
1855
- input, select {
1856
- vertical-align: top;
1857
- }
1858
- }
1859
-
1860
  #learn_press_dashboard_widget {
1861
  .rss-widget {
1862
  ul {
@@ -1948,7 +1972,7 @@ input.regular-text[id^="learn-press-emails"] {
1948
  width: 50%;
1949
  }
1950
  #learn-press-no-templates td p {
1951
- color: #FF0000;
1952
  }
1953
  }
1954
 
43
  padding-left: 0;
44
  }
45
  }
46
+
47
+ .type-lp_course {
48
+
49
+ &.status-pending {
50
+ .row-actions .view {
51
+ display: none;
52
+ }
53
+ }
54
+ }
55
+
56
  }
57
 
58
  #learn-press-admin-settings {
129
  }
130
  }
131
  input[type="radio"] {
132
+ margin: 0 !important;
133
  }
134
  label {
135
  line-height: 1;
136
  }
137
+ /*input[name="learn_press_single_course_image_size[width]"],
138
  input[name="learn_press_single_course_image_size[height]"],
139
  input[name="learn_press_course_thumbnail_image_size[width]"],
140
  input[name="learn_press_course_thumbnail_image_size[height]"] {
143
  input[name="learn_press_single_course_image_size[crop]"],
144
  input[name="learn_press_course_thumbnail_image_size[crop]"] {
145
  margin-top: 3px;
146
+ }*/
147
 
148
  input[name="learn_press_course_base"] {
149
  margin-top: 3px;
150
  margin-right: 3px;
151
  }
152
+ .lp-group-title {
153
+ padding: 0 0 10px;
154
+ border-bottom: 3px solid #563d7c;
155
+ display: inline-block;
156
+ margin: 0;
157
+ }
158
+ input[type="text"],
159
+ input[type="email"],
160
+ input[type="number"],
161
+ input[type="tel"],
162
+ input[type="password"],
163
+ select {
164
+ vertical-align: top;
165
+ }
166
+ input[type="checkbox"] {
167
+ opacity: 1;
168
+ }
169
+ .lp-setting-field{
170
+ span{
171
+ vertical-align: top;
172
+ line-height: 24px;
173
+ }
174
+ .lp-sign-times{
175
+ font-size: 19px;
176
+ }
177
+ }
178
  }
179
 
180
  /* message box */
442
 
443
  position: absolute;
444
  bottom: 30px;
 
445
  right: 0;
446
  height: 50px;
447
  -ms-transform: translateY(-50%);
539
  text-decoration: none;
540
  content: attr(data-text-disable);
541
  }
 
542
  .lp-search-addon {
543
  margin: 0;
544
  width: 280px;
1881
  text-align: left;
1882
  }
1883
 
 
 
 
 
 
 
 
 
 
 
1884
  #learn_press_dashboard_widget {
1885
  .rss-widget {
1886
  ul {
1972
  width: 50%;
1973
  }
1974
  #learn-press-no-templates td p {
1975
+ color: #0073aa;
1976
  }
1977
  }
1978
 
assets/css/admin/meta-box-course.css CHANGED
@@ -404,6 +404,7 @@
404
  .rwmb-curriculum-wrapper .rwmb-input {
405
  width: auto !important;
406
  display: block;
 
407
  }
408
  .column-lp_course .row-actions {
409
  display: inline-block;
404
  .rwmb-curriculum-wrapper .rwmb-input {
405
  width: auto !important;
406
  display: block;
407
+ float: none;
408
  }
409
  .column-lp_course .row-actions {
410
  display: inline-block;
assets/css/admin/meta-box-course.less CHANGED
@@ -1,980 +1,981 @@
1
- /* meta box course */
2
- .rwmb-duration-wrapper input[type="text"],
3
- .rwmb-duration-wrapper select {
4
- vertical-align: baseline;
5
- }
6
-
7
- .post-type-lp_course {
8
- #postdivric,
9
- #submitpost {
10
- visibility: hidden;
11
- }
12
- }
13
-
14
- #learn-press-review-message {
15
- margin-bottom: 10px;
16
- > h4 {
17
- margin: 0 0 10px 0;
18
- }
19
- > textarea {
20
- width: 100%;
21
- height: 100px;
22
- }
23
- .lp-pending-review-message {
24
- background: #c44;
25
- padding: 5px 10px;
26
- color: #FFF;
27
- margin: -10px -10px 10px;
28
- font-size: 12px;
29
- font-style: italic;
30
- }
31
- }
32
-
33
- #learn-press-button-toggle-editor {
34
- margin: 20px 0 0;
35
- }
36
-
37
- #course_curriculum {
38
- border: none;
39
- background-color: transparent;
40
- }
41
-
42
- #course_curriculum .handlediv,
43
- #course_curriculum .hndle {
44
- display: none;
45
- }
46
-
47
- #course_curriculum .inside {
48
- margin: 0;
49
- padding: 0;
50
- }
51
-
52
- #course_curriculum .curriculum-heading {
53
- margin: 0 0 20px 0;
54
- padding: 10px 20px;
55
- background-color: #FFF;
56
- line-height: 1;
57
- border: 1px solid #DDD;
58
- }
59
-
60
- #course_curriculum .curriculum-heading .description {
61
- font-weight: normal;
62
- color: #999;
63
- display: block;
64
- font-size: 90%;
65
- margin-top: 10px;;
66
- }
67
-
68
- #course_curriculum .curriculum-heading .items-toggle {
69
- float: right;
70
- margin: -33px 7px 0 0;
71
- line-height: 1;
72
- box-shadow: none;
73
- }
74
-
75
- #course_curriculum .curriculum-heading .items-toggle a {
76
- -webkit-box-shadow: none;
77
- -moz-box-shadow: none;
78
- box-shadow: none;
79
- font-size: 32px;
80
-
81
- }
82
-
83
- #course_curriculum .curriculum-sections {
84
- margin: 0;
85
- background-color: #FFF;
86
- border-bottom: 1px solid #DDD;
87
- }
88
-
89
- #course_curriculum .curriculum-section {
90
- margin: -1px 0 0 0;
91
- background-color: #FFF;
92
- border-bottom: 1px solid #DDD;
93
- position: relative;
94
- }
95
-
96
- #course_curriculum .curriculum-section.ui-sortable-placeholder {
97
- background-image: url("../../images/stripe.png");
98
- visibility: visible !important;
99
- border: 1px solid #DDD;
100
- border-bottom: none;
101
- }
102
-
103
- #course_curriculum .curriculum-section-head {
104
- border: 1px solid #DDD;
105
- background-color: #F9F9F9;
106
- border-bottom: none;
107
- margin: 0;
108
- color: #777;
109
- padding: 3px 20px;
110
- }
111
-
112
- #course_curriculum .curriculum-section-head input {
113
- background-color: #F9F9F9;
114
- }
115
-
116
- #course_curriculum .curriculum-section-head .lp-section-actions {
117
- float: right;
118
- margin: 14px 0;
119
- visibility: hidden;
120
- position: relative;
121
- }
122
-
123
- #course_curriculum .curriculum-section:not(.lp-empty-section) .curriculum-section-head:hover .lp-section-actions {
124
- visibility: visible;
125
- }
126
-
127
- #course_curriculum .curriculum-section .lp-section-actions a {
128
- vertical-align: middle;
129
- color: #666666;
130
- width: 24px;
131
- height: 24px;
132
- box-shadow: none;
133
- }
134
-
135
- #course_curriculum .curriculum-section .lp-section-actions a[data-action="expand"] {
136
- line-height: 28px;
137
- }
138
-
139
- #course_curriculum .curriculum-section .lp-section-actions a:before {
140
- width: 24px;
141
- height: 24px;
142
- font-size: 24px;
143
- }
144
-
145
- #course_curriculum .curriculum-section .lp-section-actions a:hover {
146
- color: #00a0d2;
147
- }
148
-
149
- #course_curriculum .curriculum-section .curriculum-section-head .lp-section-actions .move {
150
- cursor: url("../../../assets/images/openhand.cur") 7 5, default;
151
- position: absolute;
152
- right: -15px;
153
- height: 57px;
154
- top: -15px;
155
- background: url("../../../assets/images/grippy_large.png") right no-repeat;
156
- width: 20px;
157
- }
158
-
159
- #course_curriculum .curriculum-section-content {
160
- border: 1px solid #DDD;
161
- padding: 20px;
162
- border-bottom-width: 0;
163
- width: 100%;
164
- box-sizing: border-box;
165
- }
166
-
167
- #course_curriculum .curriculum-section.ui-sortable-helper {
168
- border-bottom: 1px solid #DDD;
169
- }
170
-
171
- #course_curriculum .curriculum-section-head .lp-section-name {
172
- border: none;
173
- outline: none;
174
- box-shadow: none;
175
- font-size: 24px;
176
- color: #777;
177
- width: 70%;
178
- margin: 0;
179
- padding: 0;
180
- height: 50px;
181
- }
182
-
183
- #course_curriculum .curriculum-section-head .lp-section-name:focus {
184
- color: #444;
185
- }
186
-
187
- #course_curriculum .curriculum-section.lp-empty-section .curriculum-section-content {
188
- _display: none;
189
- }
190
-
191
- #course_curriculum .curriculum-section-items {
192
- border-collapse: collapse;
193
- width: 100%;
194
- }
195
-
196
- #course_curriculum .curriculum-section-items .lp-section-item {
197
- border: 1px dashed #DDD;
198
- margin: -1px 0 0 0;
199
- padding: 5px 0;
200
- background-color: #FFF;
201
- }
202
-
203
- #course_curriculum .curriculum-section-items .lp-section-item:nth-child(2n+1),
204
- #course_curriculum .curriculum-section-items .lp-section-item:nth-child(2n+1) .section-item-input input {
205
- background-color: #FCFCFC;
206
- }
207
-
208
- #course_curriculum .curriculum-section-items .lp-section-item .lp-item-actions {
209
- margin: 0;
210
- float: right;
211
- position: relative;
212
- }
213
-
214
- #course_curriculum .curriculum-section-items .lp-section-item .lp-item-actions a {
215
- vertical-align: middle;
216
- color: #666;
217
- margin-top: -2px;
218
- box-shadow: none;
219
- }
220
-
221
- #course_curriculum .curriculum-section-items .lp-section-item .lp-item-actions a:hover {
222
- color: #00a0d2;
223
- }
224
-
225
- #course_curriculum .curriculum-section-items .lp-section-item[data-item_id=""] .lp-edit {
226
- display: none;
227
- }
228
-
229
- #course_curriculum .curriculum-section-items .lp-section-item.lp-item-empty .lp-item-actions {
230
- display: none;
231
- }
232
-
233
- #course_curriculum .lp-section-item.ui-sortable-helper td {
234
-
235
- }
236
-
237
- #course_curriculum .lp-section-item.ui-sortable-placeholder {
238
- visibility: visible !important;
239
- }
240
-
241
- #course_curriculum .lp-section-item.ui-sortable-placeholder td {
242
- background-image: url("../../../assets/images/stripe.png");
243
- border-bottom: none;
244
- }
245
-
246
- #course_curriculum .lp-item-actions > * {
247
- visibility: hidden;
248
- }
249
-
250
- #course_curriculum .lp-item-actions > a {
251
- }
252
-
253
- #course_curriculum .item-bulk-actions {
254
- text-align: right;
255
- margin-top: 0;
256
- margin-bottom: 15px;
257
- }
258
-
259
- #course_curriculum .lp-section-item:not(.lp-item-empty):hover .lp-item-actions > * {
260
- visibility: visible;
261
- }
262
-
263
- #course_curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty) .item-checkbox {
264
- display: inline-block;
265
- height: 34px;
266
- border: none;
267
- line-height: 32px;
268
- padding: 0 0 0 0;
269
- margin: 0 4px 0 10px;
270
- cursor: url("../../../assets/images/openhand.cur") 7 5, default;
271
- visibility: visible;
272
- }
273
-
274
- #course_curriculum .curriculum-section-items .lp-section-item .item-checkbox input {
275
- opacity: 0.4;
276
- }
277
-
278
- #course_curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty):hover .item-checkbox input {
279
- opacity: 1;
280
- }
281
-
282
- #course_curriculum .lp-item-lp_lesson .handle.learn-press-icon:before {
283
- content: "\e900";
284
- }
285
-
286
- #course_curriculum .lp-item-lp_quiz .handle.learn-press-icon:before {
287
- content: "\e901";
288
- }
289
-
290
- #course_curriculum .lp-section-item.lp-item-new .handle {
291
- color: #999;
292
- }
293
-
294
- #course_curriculum .curriculum-section-items .lp-section-item:hover,
295
- #course_curriculum .curriculum-section-items .lp-section-item:hover input.lp-item-name {
296
- background-color: #F9F9F9;
297
- }
298
-
299
- #course_curriculum .lp-section-item .handle {
300
- width: 32px;
301
- height: 32px;
302
- display: inline-block;
303
- vertical-align: middle;
304
- text-align: center;
305
- font-size: 18px;
306
- line-height: 32px;
307
- color: #00A0D2;
308
- }
309
-
310
- #course_curriculum .lp-section-item.remove input.lp-item-name {
311
- color: #FF0000;
312
- }
313
-
314
- #course_curriculum .lp-section-item.ui-sortable-helper {
315
-
316
- }
317
-
318
- #course_curriculum .lp-section-item input.lp-item-name {
319
- color: #777;
320
- border: none;
321
- box-shadow: none;
322
- outline: none;
323
- font-size: 16px;
324
- width: 100%;
325
- vertical-align: middle;
326
- text-overflow: ellipsis;
327
- overflow: hidden;
328
- white-space: nowrap;
329
- }
330
-
331
- #course_curriculum .lp-section-describe {
332
- border: none;
333
- box-shadow: none;
334
- color: #999;
335
- font-style: italic;
336
- width: 80%;
337
- float: left;
338
- padding-left: 0;
339
- }
340
-
341
- #course_curriculum .curriculum-section-items .lp-section-item input.lp-item-name:focus,
342
- #course_curriculum input:focus {
343
- color: #444;
344
- }
345
-
346
- #course_curriculum .lp-section-item .section-item-icon {
347
- width: 32px;
348
- white-space: nowrap;
349
- }
350
-
351
- .lp-section-item .learn-press-icon {
352
- width: 32px;
353
- height: 32px;
354
- font-family: dashicons;
355
- display: inline-block;
356
- font-size: 20px;
357
- text-align: center;
358
- line-height: 32px;
359
- color: #DDD;
360
- cursor: pointer;
361
- border: 1px solid transparent;
362
- }
363
-
364
- #course_curriculum .lp-section-item .learn-press-icon.item-lp_quiz:before {
365
- content: "\f469";
366
- }
367
-
368
- #course_curriculum .lp-section-item .learn-press-icon.item-lp_lesson:before {
369
- content: "\f330";
370
- }
371
-
372
- #course_curriculum .lp-section-item .learn-press-icon.item-selected,
373
- #course_curriculum .lp-section-item[data-item_id=""] .learn-press-icon:hover {
374
- }
375
-
376
- #course_curriculum .lp-section-item td {
377
- height: 30px;
378
- }
379
-
380
- #poststuff .postbox-container {
381
- position: relative;
382
- }
383
-
384
- #course_tabs .handlediv,
385
- #course_tabs .hndle,
386
- #course_tabs .rwmb-label {
387
- display: none;
388
- }
389
-
390
- #course_tabs .rwmb-input {
391
-
392
- }
393
-
394
- #course_tabs .inside {
395
- margin: 0;
396
- padding: 0;
397
- }
398
-
399
- #course_tabs .rwmb-course_tabs-wrapper {
400
- margin: 0;
401
- }
402
-
403
- #course_tabs {
404
- position: absolute;
405
- left: 0;
406
- right: 0;
407
- }
408
-
409
- #course_tabs.fixed {
410
- position: fixed;
411
- top: 30px;
412
- z-index: 10000;
413
- opacity: 0.5;
414
- left: 182px;
415
- right: 320px;
416
- }
417
-
418
- #course_tabs.fixed:hover {
419
- opacity: 1;
420
- }
421
-
422
- #course_tabs_placeholder {
423
- height: 41px;
424
- margin-bottom: 20px;
425
- }
426
-
427
- #poststuff h3#course-tabs-h3 {
428
- padding: 0;
429
- }
430
-
431
- #course-tabs-h3 > a {
432
- padding: 10px;
433
- display: inline-block;
434
- border-right: 1px solid #DDD;
435
- text-decoration: none;
436
- _color: #AAA;
437
- box-shadow: none;
438
- }
439
-
440
- .learn-press-review-logs {
441
- padding-bottom: 10px;
442
- .review-message {
443
- font-style: italic;
444
- font-size: 14px;
445
- margin: 10px 0;
446
- color: #999;
447
- }
448
- > li {
449
- border-bottom: 1px dashed #DDD;
450
- padding-bottom: 20px;
451
- margin-top: 20px;
452
- position: relative;
453
- &:after {
454
- content: '';
455
- display: block;
456
- clear: both;
457
- }
458
- }
459
- .review-user {
460
- width: 48px;
461
- float: left;
462
- img {
463
- max-width: 100%;
464
- height: auto;
465
- }
466
- > * {
467
- float: left;
468
- }
469
- }
470
- .review-index {
471
- width: 46px;
472
- font-weight: bold;
473
- position: absolute;
474
- bottom: -11px;
475
- left: 0;
476
- background-color: #FFF;
477
- text-align: center;
478
- border: 1px dashed #DDD;
479
- height: 20px;
480
- line-height: 20px;
481
- color: #CCC;
482
- }
483
- .review-content {
484
- margin-left: 68px;
485
- }
486
- > li .lp-label {
487
- font-size: 100%;
488
- margin-top: 20px;
489
- }
490
- }
491
-
492
- .rwmb-curriculum-wrapper .rwmb-label {
493
- display: none;
494
- }
495
-
496
- .rwmb-curriculum-wrapper .rwmb-input {
497
- width: auto !important;
498
- display: block;
499
- }
500
-
501
- .column-lp_course .row-actions {
502
- display: inline-block;
503
- margin-left: 10px;
504
- }
505
-
506
- .lp-modal-search li.selected {
507
- display: none;
508
- }
509
-
510
- .lp-search-items input[name="lp-item-name"] {
511
- width: 350px;
512
- }
513
-
514
- .lp-modal-search {
515
- background-color: #F5F5F5;
516
- color: #777;
517
- padding: 20px;
518
- height: 100%;
519
- }
520
-
521
- .lp-modal-search ul {
522
-
523
- }
524
-
525
- .lp-highlight-color {
526
- text-decoration: underline;
527
- color: #00a0d2;
528
- }
529
-
530
- .learn-press-dropdown-item-types {
531
- position: relative;
532
- }
533
-
534
- .learn-press-dropdown-item-types > ul {
535
- display: none;
536
- position: absolute;
537
- top: 0px;
538
- z-index: 10;
539
- background: #FFF;
540
- border: 1px solid #DDD;
541
- left: 100%;
542
- margin-left: -1px;
543
- }
544
-
545
- .learn-press-dropdown-item-types > ul > li {
546
- margin: 0;
547
- display: table-cell;
548
- }
549
-
550
- .learn-press-dropdown-item-types > ul > li span {
551
- border-width: 0 !important;
552
- }
553
-
554
- tr[data-item_id=""] .learn-press-dropdown-item-types:hover > ul,
555
- tr[data-item_id=""].focus .learn-press-dropdown-item-types > ul {
556
- display: inline-table;
557
- border-left-color: transparent;
558
- }
559
-
560
- .learn-press-dropdown-item-types:hover > span.learn-press-icon,
561
- tr.focus .learn-press-dropdown-item-types > span.learn-press-icon {
562
- background: #FFF;
563
- border-color: #DDD;
564
- z-index: 5;
565
- position: relative;
566
- }
567
-
568
- .learn-press-dropdown-item-types:hover > span.learn-press-icon:after {
569
- content: '';
570
- border-left: 1px solid #EEE;
571
- position: absolute;
572
- right: 0;
573
- display: inline-block;
574
- height: 20px;
575
- top: 50%;
576
- margin-top: -10px;
577
- }
578
-
579
- .learn-press-dropdown-item-types > span.learn-press-icon,
580
- .learn-press-dropdown-item-types li:hover span.learn-press-icon,
581
- .learn-press-dropdown-item-types li span.learn-press-icon.item-selected {
582
- color: #0085ba;
583
- }
584
-
585
- .post-type-lp_course {
586
- #switch-course-tabs,
587
- #toggle-meta-boxes {
588
- float: right;
589
- margin-left: 10px;
590
- }
591
- &.enable-course-tabs {
592
- #post-body-content {
593
- margin-bottom: 0;
594
- }
595
- #normal-sortables {
596
- .postbox {
597
- _visibility: hidden;
598
- float: left;
599
- margin-right: -100%;
600
- width: 100%;
601
- box-sizing: border-box;
602
- height: 0;
603
- overflow: hidden;
604
- border-width: 0;
605
- &.active {
606
- height: auto;
607
- border-width: 1px;
608
- }
609
- .handlediv, .hndle {
610
- display: none;
611
- }
612
- }
613
- }
614
- #course-tabs {
615
- background: #FFF;
616
- padding: 10px;
617
- margin-bottom: 0;
618
- border: 1px solid #DDD;
619
- border-bottom: none;
620
- &:after {
621
- display: block;
622
- clear: both;
623
- content: '';
624
- }
625
- &.ui-sortable:not(.ui-sortable-disabled) {
626
- li.ui-sortable-handle {
627
- position: relative;
628
- a{
629
- border: 1px solid #ddd;
630
- padding: 0px 5px;
631
- margin: 0 5px;
632
- color: #DDD;
633
- background: #FFF;
634
- }
635
- &:after {
636
- content: '';
637
- position: absolute;
638
- top: 0;
639
- left: 0;
640
- width: 100%;
641
- height: 100%;
642
- cursor: move;
643
- }
644
- }
645
- }
646
- li {
647
- float: left;
648
- margin-bottom: 0;
649
- a {
650
- display: block;
651
- padding: 0 15px 0 0;
652
- text-decoration: none;
653
- outline: none;
654
- box-shadow: none;
655
- }
656
- &.active {
657
- a {
658
- font-weight: bold;
659
- }
660
- }
661
- }
662
- li#switch-course-metaboxes {
663
- float: right;
664
- #complete-reorder-course-tabs {
665
- display: none;
666
- }
667
- a {
668
- padding-right: 0;
669
- color: #FF0000;
670
- display: inline-block;
671
- margin-left: 15px;
672
- }
673
- }
674
- }
675
- }
676
- }
677
-
678
- /*
679
- #lp-course-curriculum .lp-course-curriculum-toggle{
680
- padding: 0;
681
- margin: 0;
682
- float: right;
683
- }
684
- #lp-course-curriculum .lp-item-name{
685
- box-shadow: none;
686
- border-color: transparent;
687
- color: #BBB;
688
- }
689
- #lp-course-curriculum .lp-section-item:hover,
690
- #lp-course-curriculum .lp-section-item.hover{
691
- background-color: #F5F5F5;
692
- border-style: solid;
693
- }
694
- #lp-course-curriculum .lp-section-item.lp-item-lp_lesson .handle:after{
695
- content: "\f497";
696
- }
697
- #lp-course-curriculum .lp-section-item.lp-item-lp_quiz .handle:after{
698
- content: "\f130";
699
- }
700
- #lp-course-curriculum .lp-section-item:hover .lp-item-name,
701
- #lp-course-curriculum .lp-section-item.hover .lp-item-name{
702
- border: 1px solid #DDD;
703
- color: #32373c;
704
- }
705
- #lp-course-curriculum .lp-section-empty .lp-section-items{
706
- display: none;
707
- }
708
- #lp-course-curriculum .lp-section-item .lp-item-actions{
709
- float: right;
710
- margin-left: 5px;
711
- margin-top: 3px;
712
- }
713
- #lp-course-curriculum .lp-item-empty .lp-item-actions,
714
- #lp-course-curriculum .lp-section-empty .lp-section-head .lp-action,
715
- #lp-course-curriculum .lp-section-empty .lp-curriculum-section-content {
716
- display: none;
717
- }
718
- #lp-course-curriculum .lp-item-empty{
719
- cursor: default;
720
- }
721
- #lp-course-curriculum .lp-item-new{
722
- border-color: #00A0D2;
723
- }
724
- #lp-course-curriculum .lp-item-new .lp-item-name{
725
- border-color: #00A0D2;
726
- }
727
- #lp-course-curriculum .lp-section-head{
728
- padding: 0;
729
- }
730
- #lp-course-curriculum .lp-curriculum-section .lp-toggle i:before{
731
- content: '\f132';
732
- }
733
- #lp-course-curriculum .lp-curriculum-section.open .lp-toggle i:before{
734
- content: '\f460';
735
- }
736
- .lp-modal-search{
737
- position: absolute;
738
- background-color: #FFF;
739
- border: 1px solid #DDD;
740
- border-top: none;
741
- z-index: 9999;
742
- margin: -1px 0 0 1px;
743
- }
744
- .lp-modal-search ul{
745
- margin: 0;
746
- padding: 0;
747
- }
748
- .lp-modal-search ul li{
749
- list-style: none;
750
- padding: 5px;
751
- margin: 0;
752
- }
753
- .lp-modal-search li.highlighting,
754
- .lp-modal-search li:hover{
755
- background-color: #EAEAEA;
756
- cursor: pointer;
757
- }
758
- .lp-highlight-color{
759
- text-decoration: underline;
760
- }
761
- .lp-search-no-results{
762
- display: none;
763
- }
764
- .lp-curriculum-sections .ui-sortable-placeholder{
765
- visibility: visible !important;
766
- border: 2px dashed #DDD;
767
- }
768
- .lp-curriculum-sections .lp-sorting{
769
- height: auto !important;
770
- }
771
- */
772
- /*
773
-
774
- .lp-course-curriculum{}
775
- .lp-course-curriculum .lp-curriculum-sections{
776
-
777
- }
778
- .lp-course-curriculum .lp-curriculum-section{
779
- transition: opacity 0.25s;
780
- margin-bottom: 20px;
781
- border: 1px solid #DDD;
782
- }
783
- .lp-course-curriculum .lp-curriculum-section.lp-selected .lp-curriculum-section-content{
784
- background-color: #F5F5F5;
785
- }
786
- .lp-course-curriculum .lp-curriculum-section-content > p{
787
- display: inline-block;
788
- }
789
- .lp-course-curriculum .lp-curriculum-section.lp-selected > h3{
790
- _border-bottom: 1px solid #DDD;
791
- }
792
- .lp-course-curriculum .lp-curriculum-section > h3{
793
- padding: 10px ;
794
- margin: 0;
795
- background-color: #F5F5F5;
796
- height: 62px;
797
- position: relative;
798
- cursor: move;
799
- }
800
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-section-name-wrapper{
801
- top: 9px;
802
- }
803
- .lp-course-curriculum .lp-curriculum-section > h3 > span > input{
804
- border: 1px solid #DDD;
805
- border-radius: 3px;
806
- font-size: 24px;
807
- width: 100%;
808
- color: #777;
809
- }
810
- .lp-course-curriculum .lp-curriculum-section > h3 > span.lp-section-name-wrapper{
811
- position: absolute;
812
- display: inline-block;
813
- right: 137px;
814
- left: 71px;
815
- }
816
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-action{
817
- display: block;
818
- position: relative;
819
- height: 62px;
820
- width: 62px;
821
- border-left: 1px solid #DDD;
822
- -top: -8px;
823
- -right: -11px;
824
- cursor: pointer;
825
- float: right;
826
- }
827
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-sort{
828
- display: none;
829
- }
830
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-action .dashicons{
831
- font-size: 32px;
832
- width: 100%;
833
- height: 100%;
834
- line-height: 62px;
835
- color: #0073aa;
836
- }
837
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-action:hover .dashicons{
838
- color: #009ED7;
839
- }
840
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-toggle{
841
- _right: 62px;
842
- }
843
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-remove{
844
- _right: 124px;
845
- }
846
-
847
- .lp-course-curriculum .lp-curriculum-section.closed .lp-curriculum-section-content{
848
- display: none;
849
- }
850
-
851
- .lp-course-curriculum .sorting .ui-sortable-helper .lp-curriculum-section-content{
852
- display: none !important;
853
- }
854
- .lp-course-curriculum .sorting .ui-sortable-placeholder,
855
- .lp-section-items.sorting .ui-sortable-placeholder{
856
- border: 3px dashed #DDD;
857
- visibility: visible !important;
858
- position: relative;
859
- }
860
- .lp-course-curriculum .sorting .ui-sortable-placeholder:after,
861
- .lp-section-items.sorting .ui-sortable-placeholder:after{
862
- content: '';
863
- display: block;
864
- width: 0px;
865
- height: 0px;
866
- border: 28px solid transparent;
867
- border-left-color: #999;
868
- position: absolute;
869
- top: 0;
870
- left: -33px;
871
-
872
- }
873
-
874
- .lp-section-items.sorting .ui-sortable-placeholder:after{
875
- border-width: 15px;
876
- left: -20px;
877
- }
878
- .lp-curriculum-section-content{
879
- background-color: #F5F5F5;
880
- background-color: #FFF;
881
- _border-bottom: 2px dashed #DDD;
882
- padding: 20px;
883
- margin-bottom: 0px;
884
- border-top: 1px solid #DDD;
885
- }
886
- .lp-dynamic-form{
887
- position: absolute;
888
- padding: 0px;
889
- background-color: transparent;
890
- z-index: 210;
891
- height: 15px;
892
- overflow: hidden;
893
- }
894
- .lp-container-dropdown{
895
- height: 15px;
896
- vertical-align: top;
897
- }
898
- .lp-container-dropdown > a{
899
- background-image: none !important;
900
- background-color: #FFF !important;
901
- }
902
- .lp-container-dropdown.select2-drop-above > a{
903
- height: 3px;
904
- }
905
- .lp-select-dropdown{
906
- margin-top: -6px;
907
- }
908
- .lp-select-dropdown.select2-drop-above{
909
- padding-bottom: 0;
910
- }
911
-
912
- .lp-empty .lp-curriculum-section-content{
913
- display: none !important;
914
- }
915
-
916
- .lp-section-items{
917
- min-height: 20px;
918
-
919
-
920
- }
921
- .lp-section-items > li{
922
- padding: 5px;
923
- border:1px dashed #DDD;
924
- background-color: #FFF;
925
- cursor: move;
926
- position: relative;
927
- }
928
- .lp-section-items > li .lp-title{
929
- cursor: auto;
930
- padding: 3px 5px;
931
- border: 1px solid transparent;
932
- display: inline-block;
933
- width: 80%;
934
- -webkit-box-sizing: border-box;
935
- -moz-box-sizing: border-box;
936
- box-sizing: border-box;
937
-
938
- }
939
- .lp-section-items > li:hover .lp-title {
940
- border-color: #DDD;
941
- cursor: text;
942
- }
943
- .lp-section-items > li input{
944
- width: 70%;
945
- }
946
-
947
- .lp-section-items > li:hover{
948
- border-style: solid;
949
- }
950
- .lp-section-icon{
951
- position: absolute;
952
- top:0;
953
- left:0;
954
- width: 62px;
955
- height: 62px;
956
- line-height: 54px;
957
- border-right: 1px solid #DDD;
958
- text-align:center;
959
- }
960
- .lp-section-icon i{
961
- height: 60px;
962
- line-height: 60px;
963
- }
964
- .lp-course-curriculum .dashicons{
965
- vertical-align: middle;
966
- }
967
-
968
- .select2-drop.select2-drop-active{
969
- padding: 5px 10px;
970
- }
971
-
972
- .rwmb-course_lesson_quiz-wrapper .rwmb-label{ display: none;}
973
- .rwmb-course_lesson_quiz-wrapper .rwmb-input{ float: none; width: auto; display: block;}
974
-
975
- .lp-course-curriculum-toggle{
976
-
977
- }
978
- .lp-course-curriculum-toggle .expand{
979
- display: none;
 
980
  }*/
1
+ /* meta box course */
2
+ .rwmb-duration-wrapper input[type="text"],
3
+ .rwmb-duration-wrapper select {
4
+ vertical-align: baseline;
5
+ }
6
+
7
+ .post-type-lp_course {
8
+ #postdivric,
9
+ #submitpost {
10
+ visibility: hidden;
11
+ }
12
+ }
13
+
14
+ #learn-press-review-message {
15
+ margin-bottom: 10px;
16
+ > h4 {
17
+ margin: 0 0 10px 0;
18
+ }
19
+ > textarea {
20
+ width: 100%;
21
+ height: 100px;
22
+ }
23
+ .lp-pending-review-message {
24
+ background: #c44;
25
+ padding: 5px 10px;
26
+ color: #FFF;
27
+ margin: -10px -10px 10px;
28
+ font-size: 12px;
29
+ font-style: italic;
30
+ }
31
+ }
32
+
33
+ #learn-press-button-toggle-editor {
34
+ margin: 20px 0 0;
35
+ }
36
+
37
+ #course_curriculum {
38
+ border: none;
39
+ background-color: transparent;
40
+ }
41
+
42
+ #course_curriculum .handlediv,
43
+ #course_curriculum .hndle {
44
+ display: none;
45
+ }
46
+
47
+ #course_curriculum .inside {
48
+ margin: 0;
49
+ padding: 0;
50
+ }
51
+
52
+ #course_curriculum .curriculum-heading {
53
+ margin: 0 0 20px 0;
54
+ padding: 10px 20px;
55
+ background-color: #FFF;
56
+ line-height: 1;
57
+ border: 1px solid #DDD;
58
+ }
59
+
60
+ #course_curriculum .curriculum-heading .description {
61
+ font-weight: normal;
62
+ color: #999;
63
+ display: block;
64
+ font-size: 90%;
65
+ margin-top: 10px;;
66
+ }
67
+
68
+ #course_curriculum .curriculum-heading .items-toggle {
69
+ float: right;
70
+ margin: -33px 7px 0 0;
71
+ line-height: 1;
72
+ box-shadow: none;
73
+ }
74
+
75
+ #course_curriculum .curriculum-heading .items-toggle a {
76
+ -webkit-box-shadow: none;
77
+ -moz-box-shadow: none;
78
+ box-shadow: none;
79
+ font-size: 32px;
80
+
81
+ }
82
+
83
+ #course_curriculum .curriculum-sections {
84
+ margin: 0;
85
+ background-color: #FFF;
86
+ border-bottom: 1px solid #DDD;
87
+ }
88
+
89
+ #course_curriculum .curriculum-section {
90
+ margin: -1px 0 0 0;
91
+ background-color: #FFF;
92
+ border-bottom: 1px solid #DDD;
93
+ position: relative;
94
+ }
95
+
96
+ #course_curriculum .curriculum-section.ui-sortable-placeholder {
97
+ background-image: url("../../images/stripe.png");
98
+ visibility: visible !important;
99
+ border: 1px solid #DDD;
100
+ border-bottom: none;
101
+ }
102
+
103
+ #course_curriculum .curriculum-section-head {
104
+ border: 1px solid #DDD;
105
+ background-color: #F9F9F9;
106
+ border-bottom: none;
107
+ margin: 0;
108
+ color: #777;
109
+ padding: 3px 20px;
110
+ }
111
+
112
+ #course_curriculum .curriculum-section-head input {
113
+ background-color: #F9F9F9;
114
+ }
115
+
116
+ #course_curriculum .curriculum-section-head .lp-section-actions {
117
+ float: right;
118
+ margin: 14px 0;
119
+ visibility: hidden;
120
+ position: relative;
121
+ }
122
+
123
+ #course_curriculum .curriculum-section:not(.lp-empty-section) .curriculum-section-head:hover .lp-section-actions {
124
+ visibility: visible;
125
+ }
126
+
127
+ #course_curriculum .curriculum-section .lp-section-actions a {
128
+ vertical-align: middle;
129
+ color: #666666;
130
+ width: 24px;
131
+ height: 24px;
132
+ box-shadow: none;
133
+ }
134
+
135
+ #course_curriculum .curriculum-section .lp-section-actions a[data-action="expand"] {
136
+ line-height: 28px;
137
+ }
138
+
139
+ #course_curriculum .curriculum-section .lp-section-actions a:before {
140
+ width: 24px;
141
+ height: 24px;
142
+ font-size: 24px;
143
+ }
144
+
145
+ #course_curriculum .curriculum-section .lp-section-actions a:hover {
146
+ color: #00a0d2;
147
+ }
148
+
149
+ #course_curriculum .curriculum-section .curriculum-section-head .lp-section-actions .move {
150
+ cursor: url("../../../assets/images/openhand.cur") 7 5, default;
151
+ position: absolute;
152
+ right: -15px;
153
+ height: 57px;
154
+ top: -15px;
155
+ background: url("../../../assets/images/grippy_large.png") right no-repeat;
156
+ width: 20px;
157
+ }
158
+
159
+ #course_curriculum .curriculum-section-content {
160
+ border: 1px solid #DDD;
161
+ padding: 20px;
162
+ border-bottom-width: 0;
163
+ width: 100%;
164
+ box-sizing: border-box;
165
+ }
166
+
167
+ #course_curriculum .curriculum-section.ui-sortable-helper {
168
+ border-bottom: 1px solid #DDD;
169
+ }
170
+
171
+ #course_curriculum .curriculum-section-head .lp-section-name {
172
+ border: none;
173
+ outline: none;
174
+ box-shadow: none;
175
+ font-size: 24px;
176
+ color: #777;
177
+ width: 70%;
178
+ margin: 0;
179
+ padding: 0;
180
+ height: 50px;
181
+ }
182
+
183
+ #course_curriculum .curriculum-section-head .lp-section-name:focus {
184
+ color: #444;
185
+ }
186
+
187
+ #course_curriculum .curriculum-section.lp-empty-section .curriculum-section-content {
188
+ _display: none;
189
+ }
190
+
191
+ #course_curriculum .curriculum-section-items {
192
+ border-collapse: collapse;
193
+ width: 100%;
194
+ }
195
+
196
+ #course_curriculum .curriculum-section-items .lp-section-item {
197
+ border: 1px dashed #DDD;
198
+ margin: -1px 0 0 0;
199
+ padding: 5px 0;
200
+ background-color: #FFF;
201
+ }
202
+
203
+ #course_curriculum .curriculum-section-items .lp-section-item:nth-child(2n+1),
204
+ #course_curriculum .curriculum-section-items .lp-section-item:nth-child(2n+1) .section-item-input input {
205
+ background-color: #FCFCFC;
206
+ }
207
+
208
+ #course_curriculum .curriculum-section-items .lp-section-item .lp-item-actions {
209
+ margin: 0;
210
+ float: right;
211
+ position: relative;
212
+ }
213
+
214
+ #course_curriculum .curriculum-section-items .lp-section-item .lp-item-actions a {
215
+ vertical-align: middle;
216
+ color: #666;
217
+ margin-top: -2px;
218
+ box-shadow: none;
219
+ }
220
+
221
+ #course_curriculum .curriculum-section-items .lp-section-item .lp-item-actions a:hover {
222
+ color: #00a0d2;
223
+ }
224
+
225
+ #course_curriculum .curriculum-section-items .lp-section-item[data-item_id=""] .lp-edit {
226
+ display: none;
227
+ }
228
+
229
+ #course_curriculum .curriculum-section-items .lp-section-item.lp-item-empty .lp-item-actions {
230
+ display: none;
231
+ }
232
+
233
+ #course_curriculum .lp-section-item.ui-sortable-helper td {
234
+
235
+ }
236
+
237
+ #course_curriculum .lp-section-item.ui-sortable-placeholder {
238
+ visibility: visible !important;
239
+ }
240
+
241
+ #course_curriculum .lp-section-item.ui-sortable-placeholder td {
242
+ background-image: url("../../../assets/images/stripe.png");
243
+ border-bottom: none;
244
+ }
245
+
246
+ #course_curriculum .lp-item-actions > * {
247
+ visibility: hidden;
248
+ }
249
+
250
+ #course_curriculum .lp-item-actions > a {
251
+ }
252
+
253
+ #course_curriculum .item-bulk-actions {
254
+ text-align: right;
255
+ margin-top: 0;
256
+ margin-bottom: 15px;
257
+ }
258
+
259
+ #course_curriculum .lp-section-item:not(.lp-item-empty):hover .lp-item-actions > * {
260
+ visibility: visible;
261
+ }
262
+
263
+ #course_curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty) .item-checkbox {
264
+ display: inline-block;
265
+ height: 34px;
266
+ border: none;
267
+ line-height: 32px;
268
+ padding: 0 0 0 0;
269
+ margin: 0 4px 0 10px;
270
+ cursor: url("../../../assets/images/openhand.cur") 7 5, default;
271
+ visibility: visible;
272
+ }
273
+
274
+ #course_curriculum .curriculum-section-items .lp-section-item .item-checkbox input {
275
+ opacity: 0.4;
276
+ }
277
+
278
+ #course_curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty):hover .item-checkbox input {
279
+ opacity: 1;
280
+ }
281
+
282
+ #course_curriculum .lp-item-lp_lesson .handle.learn-press-icon:before {
283
+ content: "\e900";
284
+ }
285
+
286
+ #course_curriculum .lp-item-lp_quiz .handle.learn-press-icon:before {
287
+ content: "\e901";
288
+ }
289
+
290
+ #course_curriculum .lp-section-item.lp-item-new .handle {
291
+ color: #999;
292
+ }
293
+
294
+ #course_curriculum .curriculum-section-items .lp-section-item:hover,
295
+ #course_curriculum .curriculum-section-items .lp-section-item:hover input.lp-item-name {
296
+ background-color: #F9F9F9;
297
+ }
298
+
299
+ #course_curriculum .lp-section-item .handle {
300
+ width: 32px;
301
+ height: 32px;
302
+ display: inline-block;
303
+ vertical-align: middle;
304
+ text-align: center;
305
+ font-size: 18px;
306
+ line-height: 32px;
307
+ color: #00A0D2;
308
+ }
309
+
310
+ #course_curriculum .lp-section-item.remove input.lp-item-name {
311
+ color: #FF0000;
312
+ }
313
+
314
+ #course_curriculum .lp-section-item.ui-sortable-helper {
315
+
316
+ }
317
+
318
+ #course_curriculum .lp-section-item input.lp-item-name {
319
+ color: #777;
320
+ border: none;
321
+ box-shadow: none;
322
+ outline: none;
323
+ font-size: 16px;
324
+ width: 100%;
325
+ vertical-align: middle;
326
+ text-overflow: ellipsis;
327
+ overflow: hidden;
328
+ white-space: nowrap;
329
+ }
330
+
331
+ #course_curriculum .lp-section-describe {
332
+ border: none;
333
+ box-shadow: none;
334
+ color: #999;
335
+ font-style: italic;
336
+ width: 80%;
337
+ float: left;
338
+ padding-left: 0;
339
+ }
340
+
341
+ #course_curriculum .curriculum-section-items .lp-section-item input.lp-item-name:focus,
342
+ #course_curriculum input:focus {
343
+ color: #444;
344
+ }
345
+
346
+ #course_curriculum .lp-section-item .section-item-icon {
347
+ width: 32px;
348
+ white-space: nowrap;
349
+ }
350
+
351
+ .lp-section-item .learn-press-icon {
352
+ width: 32px;
353
+ height: 32px;
354
+ font-family: dashicons;
355
+ display: inline-block;
356
+ font-size: 20px;
357
+ text-align: center;
358
+ line-height: 32px;
359
+ color: #DDD;
360
+ cursor: pointer;
361
+ border: 1px solid transparent;
362
+ }
363
+
364
+ #course_curriculum .lp-section-item .learn-press-icon.item-lp_quiz:before {
365
+ content: "\f469";
366
+ }
367
+
368
+ #course_curriculum .lp-section-item .learn-press-icon.item-lp_lesson:before {
369
+ content: "\f330";
370
+ }
371
+
372
+ #course_curriculum .lp-section-item .learn-press-icon.item-selected,
373
+ #course_curriculum .lp-section-item[data-item_id=""] .learn-press-icon:hover {
374
+ }
375
+
376
+ #course_curriculum .lp-section-item td {
377
+ height: 30px;
378
+ }
379
+
380
+ #poststuff .postbox-container {
381
+ position: relative;
382
+ }
383
+
384
+ #course_tabs .handlediv,
385
+ #course_tabs .hndle,
386
+ #course_tabs .rwmb-label {
387
+ display: none;
388
+ }
389
+
390
+ #course_tabs .rwmb-input {
391
+
392
+ }
393
+
394
+ #course_tabs .inside {
395
+ margin: 0;
396
+ padding: 0;
397
+ }
398
+
399
+ #course_tabs .rwmb-course_tabs-wrapper {
400
+ margin: 0;
401
+ }
402
+
403
+ #course_tabs {
404
+ position: absolute;
405
+ left: 0;
406
+ right: 0;
407
+ }
408
+
409
+ #course_tabs.fixed {
410
+ position: fixed;
411
+ top: 30px;
412
+ z-index: 10000;
413
+ opacity: 0.5;
414
+ left: 182px;
415
+ right: 320px;
416
+ }
417
+
418
+ #course_tabs.fixed:hover {
419
+ opacity: 1;
420
+ }
421
+
422
+ #course_tabs_placeholder {
423
+ height: 41px;
424
+ margin-bottom: 20px;
425
+ }
426
+
427
+ #poststuff h3#course-tabs-h3 {
428
+ padding: 0;
429
+ }
430
+
431
+ #course-tabs-h3 > a {
432
+ padding: 10px;
433
+ display: inline-block;
434
+ border-right: 1px solid #DDD;
435
+ text-decoration: none;
436
+ _color: #AAA;
437
+ box-shadow: none;
438
+ }
439
+
440
+ .learn-press-review-logs {
441
+ padding-bottom: 10px;
442
+ .review-message {
443
+ font-style: italic;
444
+ font-size: 14px;
445
+ margin: 10px 0;
446
+ color: #999;
447
+ }
448
+ > li {
449
+ border-bottom: 1px dashed #DDD;
450
+ padding-bottom: 20px;
451
+ margin-top: 20px;
452
+ position: relative;
453
+ &:after {
454
+ content: '';
455
+ display: block;
456
+ clear: both;
457
+ }
458
+ }
459
+ .review-user {
460
+ width: 48px;
461
+ float: left;
462
+ img {
463
+ max-width: 100%;
464
+ height: auto;
465
+ }
466
+ > * {
467
+ float: left;
468
+ }
469
+ }
470
+ .review-index {
471
+ width: 46px;
472
+ font-weight: bold;
473
+ position: absolute;
474
+ bottom: -11px;
475
+ left: 0;
476
+ background-color: #FFF;
477
+ text-align: center;
478
+ border: 1px dashed #DDD;
479
+ height: 20px;
480
+ line-height: 20px;
481
+ color: #CCC;
482
+ }
483
+ .review-content {
484
+ margin-left: 68px;
485
+ }
486
+ > li .lp-label {
487
+ font-size: 100%;
488
+ margin-top: 20px;
489
+ }
490
+ }
491
+
492
+ .rwmb-curriculum-wrapper .rwmb-label {
493
+ display: none;
494
+ }
495
+
496
+ .rwmb-curriculum-wrapper .rwmb-input {
497
+ width: auto !important;
498
+ display: block;
499
+ float: none;
500
+ }
501
+
502
+ .column-lp_course .row-actions {
503
+ display: inline-block;
504
+ margin-left: 10px;
505
+ }
506
+
507
+ .lp-modal-search li.selected {
508
+ display: none;
509
+ }
510
+
511
+ .lp-search-items input[name="lp-item-name"] {
512
+ width: 350px;
513
+ }
514
+
515
+ .lp-modal-search {
516
+ background-color: #F5F5F5;
517
+ color: #777;
518
+ padding: 20px;
519
+ height: 100%;
520
+ }
521
+
522
+ .lp-modal-search ul {
523
+
524
+ }
525
+
526
+ .lp-highlight-color {
527
+ text-decoration: underline;
528
+ color: #00a0d2;
529
+ }
530
+
531
+ .learn-press-dropdown-item-types {
532
+ position: relative;
533
+ }
534
+
535
+ .learn-press-dropdown-item-types > ul {
536
+ display: none;
537
+ position: absolute;
538
+ top: 0px;
539
+ z-index: 10;
540
+ background: #FFF;
541
+ border: 1px solid #DDD;
542
+ left: 100%;
543
+ margin-left: -1px;
544
+ }
545
+
546
+ .learn-press-dropdown-item-types > ul > li {
547
+ margin: 0;
548
+ display: table-cell;
549
+ }
550
+
551
+ .learn-press-dropdown-item-types > ul > li span {
552
+ border-width: 0 !important;
553
+ }
554
+
555
+ tr[data-item_id=""] .learn-press-dropdown-item-types:hover > ul,
556
+ tr[data-item_id=""].focus .learn-press-dropdown-item-types > ul {
557
+ display: inline-table;
558
+ border-left-color: transparent;
559
+ }
560
+
561
+ .learn-press-dropdown-item-types:hover > span.learn-press-icon,
562
+ tr.focus .learn-press-dropdown-item-types > span.learn-press-icon {
563
+ background: #FFF;
564
+ border-color: #DDD;
565
+ z-index: 5;
566
+ position: relative;
567
+ }
568
+
569
+ .learn-press-dropdown-item-types:hover > span.learn-press-icon:after {
570
+ content: '';
571
+ border-left: 1px solid #EEE;
572
+ position: absolute;
573
+ right: 0;
574
+ display: inline-block;
575
+ height: 20px;
576
+ top: 50%;
577
+ margin-top: -10px;
578
+ }
579
+
580
+ .learn-press-dropdown-item-types > span.learn-press-icon,
581
+ .learn-press-dropdown-item-types li:hover span.learn-press-icon,
582
+ .learn-press-dropdown-item-types li span.learn-press-icon.item-selected {
583
+ color: #0085ba;
584
+ }
585
+
586
+ .post-type-lp_course {
587
+ #switch-course-tabs,
588
+ #toggle-meta-boxes {
589
+ float: right;
590
+ margin-left: 10px;
591
+ }
592
+ &.enable-course-tabs {
593
+ #post-body-content {
594
+ margin-bottom: 0;
595
+ }
596
+ #normal-sortables {
597
+ .postbox {
598
+ _visibility: hidden;
599
+ float: left;
600
+ margin-right: -100%;
601
+ width: 100%;
602
+ box-sizing: border-box;
603
+ height: 0;
604
+ overflow: hidden;
605
+ border-width: 0;
606
+ &.active {
607
+ height: auto;
608
+ border-width: 1px;
609
+ }
610
+ .handlediv, .hndle {
611
+ display: none;
612
+ }
613
+ }
614
+ }
615
+ #course-tabs {
616
+ background: #FFF;
617
+ padding: 10px;
618
+ margin-bottom: 0;
619
+ border: 1px solid #DDD;
620
+ border-bottom: none;
621
+ &:after {
622
+ display: block;
623
+ clear: both;
624
+ content: '';
625
+ }
626
+ &.ui-sortable:not(.ui-sortable-disabled) {
627
+ li.ui-sortable-handle {
628
+ position: relative;
629
+ a{
630
+ border: 1px solid #ddd;
631
+ padding: 0px 5px;
632
+ margin: 0 5px;
633
+ color: #DDD;
634
+ background: #FFF;
635
+ }
636
+ &:after {
637
+ content: '';
638
+ position: absolute;
639
+ top: 0;
640
+ left: 0;
641
+ width: 100%;
642
+ height: 100%;
643
+ cursor: move;
644
+ }
645
+ }
646
+ }
647
+ li {
648
+ float: left;
649
+ margin-bottom: 0;
650
+ a {
651
+ display: block;
652
+ padding: 0 15px 0 0;
653
+ text-decoration: none;
654
+ outline: none;
655
+ box-shadow: none;
656
+ }
657
+ &.active {
658
+ a {
659
+ font-weight: bold;
660
+ }
661
+ }
662
+ }
663
+ li#switch-course-metaboxes {
664
+ float: right;
665
+ #complete-reorder-course-tabs {
666
+ display: none;
667
+ }
668
+ a {
669
+ padding-right: 0;
670
+ color: #FF0000;
671
+ display: inline-block;
672
+ margin-left: 15px;
673
+ }
674
+ }
675
+ }
676
+ }
677
+ }
678
+
679
+ /*
680
+ #lp-course-curriculum .lp-course-curriculum-toggle{
681
+ padding: 0;
682
+ margin: 0;
683
+ float: right;
684
+ }
685
+ #lp-course-curriculum .lp-item-name{
686
+ box-shadow: none;
687
+ border-color: transparent;
688
+ color: #BBB;
689
+ }
690
+ #lp-course-curriculum .lp-section-item:hover,
691
+ #lp-course-curriculum .lp-section-item.hover{
692
+ background-color: #F5F5F5;
693
+ border-style: solid;
694
+ }
695
+ #lp-course-curriculum .lp-section-item.lp-item-lp_lesson .handle:after{
696
+ content: "\f497";
697
+ }
698
+ #lp-course-curriculum .lp-section-item.lp-item-lp_quiz .handle:after{
699
+ content: "\f130";
700
+ }
701
+ #lp-course-curriculum .lp-section-item:hover .lp-item-name,
702
+ #lp-course-curriculum .lp-section-item.hover .lp-item-name{
703
+ border: 1px solid #DDD;
704
+ color: #32373c;
705
+ }
706
+ #lp-course-curriculum .lp-section-empty .lp-section-items{
707
+ display: none;
708
+ }
709
+ #lp-course-curriculum .lp-section-item .lp-item-actions{
710
+ float: right;
711
+ margin-left: 5px;
712
+ margin-top: 3px;
713
+ }
714
+ #lp-course-curriculum .lp-item-empty .lp-item-actions,
715
+ #lp-course-curriculum .lp-section-empty .lp-section-head .lp-action,
716
+ #lp-course-curriculum .lp-section-empty .lp-curriculum-section-content {
717
+ display: none;
718
+ }
719
+ #lp-course-curriculum .lp-item-empty{
720
+ cursor: default;
721
+ }
722
+ #lp-course-curriculum .lp-item-new{
723
+ border-color: #00A0D2;
724
+ }
725
+ #lp-course-curriculum .lp-item-new .lp-item-name{
726
+ border-color: #00A0D2;
727
+ }
728
+ #lp-course-curriculum .lp-section-head{
729
+ padding: 0;
730
+ }
731
+ #lp-course-curriculum .lp-curriculum-section .lp-toggle i:before{
732
+ content: '\f132';
733
+ }
734
+ #lp-course-curriculum .lp-curriculum-section.open .lp-toggle i:before{
735
+ content: '\f460';
736
+ }
737
+ .lp-modal-search{
738
+ position: absolute;
739
+ background-color: #FFF;
740
+ border: 1px solid #DDD;
741
+ border-top: none;
742
+ z-index: 9999;
743
+ margin: -1px 0 0 1px;
744
+ }
745
+ .lp-modal-search ul{
746
+ margin: 0;
747
+ padding: 0;
748
+ }
749
+ .lp-modal-search ul li{
750
+ list-style: none;
751
+ padding: 5px;
752
+ margin: 0;
753
+ }
754
+ .lp-modal-search li.highlighting,
755
+ .lp-modal-search li:hover{
756
+ background-color: #EAEAEA;
757
+ cursor: pointer;
758
+ }
759
+ .lp-highlight-color{
760
+ text-decoration: underline;
761
+ }
762
+ .lp-search-no-results{
763
+ display: none;
764
+ }
765
+ .lp-curriculum-sections .ui-sortable-placeholder{
766
+ visibility: visible !important;
767
+ border: 2px dashed #DDD;
768
+ }
769
+ .lp-curriculum-sections .lp-sorting{
770
+ height: auto !important;
771
+ }
772
+ */
773
+ /*
774
+
775
+ .lp-course-curriculum{}
776
+ .lp-course-curriculum .lp-curriculum-sections{
777
+
778
+ }
779
+ .lp-course-curriculum .lp-curriculum-section{
780
+ transition: opacity 0.25s;
781
+ margin-bottom: 20px;
782
+ border: 1px solid #DDD;
783
+ }
784
+ .lp-course-curriculum .lp-curriculum-section.lp-selected .lp-curriculum-section-content{
785
+ background-color: #F5F5F5;
786
+ }
787
+ .lp-course-curriculum .lp-curriculum-section-content > p{
788
+ display: inline-block;
789
+ }
790
+ .lp-course-curriculum .lp-curriculum-section.lp-selected > h3{
791
+ _border-bottom: 1px solid #DDD;
792
+ }
793
+ .lp-course-curriculum .lp-curriculum-section > h3{
794
+ padding: 10px ;
795
+ margin: 0;
796
+ background-color: #F5F5F5;
797
+ height: 62px;
798
+ position: relative;
799
+ cursor: move;
800
+ }
801
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-section-name-wrapper{
802
+ top: 9px;
803
+ }
804
+ .lp-course-curriculum .lp-curriculum-section > h3 > span > input{
805
+ border: 1px solid #DDD;
806
+ border-radius: 3px;
807
+ font-size: 24px;
808
+ width: 100%;
809
+ color: #777;
810
+ }
811
+ .lp-course-curriculum .lp-curriculum-section > h3 > span.lp-section-name-wrapper{
812
+ position: absolute;
813
+ display: inline-block;
814
+ right: 137px;
815
+ left: 71px;
816
+ }
817
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action{
818
+ display: block;
819
+ position: relative;
820
+ height: 62px;
821
+ width: 62px;
822
+ border-left: 1px solid #DDD;
823
+ -top: -8px;
824
+ -right: -11px;
825
+ cursor: pointer;
826
+ float: right;
827
+ }
828
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-sort{
829
+ display: none;
830
+ }
831
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action .dashicons{
832
+ font-size: 32px;
833
+ width: 100%;
834
+ height: 100%;
835
+ line-height: 62px;
836
+ color: #0073aa;
837
+ }
838
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action:hover .dashicons{
839
+ color: #009ED7;
840
+ }
841
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-toggle{
842
+ _right: 62px;
843
+ }
844
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-remove{
845
+ _right: 124px;
846
+ }
847
+
848
+ .lp-course-curriculum .lp-curriculum-section.closed .lp-curriculum-section-content{
849
+ display: none;
850
+ }
851
+
852
+ .lp-course-curriculum .sorting .ui-sortable-helper .lp-curriculum-section-content{
853
+ display: none !important;
854
+ }
855
+ .lp-course-curriculum .sorting .ui-sortable-placeholder,
856
+ .lp-section-items.sorting .ui-sortable-placeholder{
857
+ border: 3px dashed #DDD;
858
+ visibility: visible !important;
859
+ position: relative;
860
+ }
861
+ .lp-course-curriculum .sorting .ui-sortable-placeholder:after,
862
+ .lp-section-items.sorting .ui-sortable-placeholder:after{
863
+ content: '';
864
+ display: block;
865
+ width: 0px;
866
+ height: 0px;
867
+ border: 28px solid transparent;
868
+ border-left-color: #999;
869
+ position: absolute;
870
+ top: 0;
871
+ left: -33px;
872
+
873
+ }
874
+
875
+ .lp-section-items.sorting .ui-sortable-placeholder:after{
876
+ border-width: 15px;
877
+ left: -20px;
878
+ }
879
+ .lp-curriculum-section-content{
880
+ background-color: #F5F5F5;
881
+ background-color: #FFF;
882
+ _border-bottom: 2px dashed #DDD;
883
+ padding: 20px;
884
+ margin-bottom: 0px;
885
+ border-top: 1px solid #DDD;
886
+ }
887
+ .lp-dynamic-form{
888
+ position: absolute;
889
+ padding: 0px;
890
+ background-color: transparent;
891
+ z-index: 210;
892
+ height: 15px;
893
+ overflow: hidden;
894
+ }
895
+ .lp-container-dropdown{
896
+ height: 15px;
897
+ vertical-align: top;
898
+ }
899
+ .lp-container-dropdown > a{
900
+ background-image: none !important;
901
+ background-color: #FFF !important;
902
+ }
903
+ .lp-container-dropdown.select2-drop-above > a{
904
+ height: 3px;
905
+ }
906
+ .lp-select-dropdown{
907
+ margin-top: -6px;
908
+ }
909
+ .lp-select-dropdown.select2-drop-above{
910
+ padding-bottom: 0;
911
+ }
912
+
913
+ .lp-empty .lp-curriculum-section-content{
914
+ display: none !important;
915
+ }
916
+
917
+ .lp-section-items{
918
+ min-height: 20px;
919
+
920
+
921
+ }
922
+ .lp-section-items > li{
923
+ padding: 5px;
924
+ border:1px dashed #DDD;
925
+ background-color: #FFF;
926
+ cursor: move;
927
+ position: relative;
928
+ }
929
+ .lp-section-items > li .lp-title{
930
+ cursor: auto;
931
+ padding: 3px 5px;
932
+ border: 1px solid transparent;
933
+ display: inline-block;
934
+ width: 80%;
935
+ -webkit-box-sizing: border-box;
936
+ -moz-box-sizing: border-box;
937
+ box-sizing: border-box;
938
+
939
+ }
940
+ .lp-section-items > li:hover .lp-title {
941
+ border-color: #DDD;
942
+ cursor: text;
943
+ }
944
+ .lp-section-items > li input{
945
+ width: 70%;
946
+ }
947
+
948
+ .lp-section-items > li:hover{
949
+ border-style: solid;
950
+ }
951
+ .lp-section-icon{
952
+ position: absolute;
953
+ top:0;
954
+ left:0;
955
+ width: 62px;
956
+ height: 62px;
957
+ line-height: 54px;
958
+ border-right: 1px solid #DDD;
959
+ text-align:center;
960
+ }
961
+ .lp-section-icon i{
962
+ height: 60px;
963
+ line-height: 60px;
964
+ }
965
+ .lp-course-curriculum .dashicons{
966
+ vertical-align: middle;
967
+ }
968
+
969
+ .select2-drop.select2-drop-active{
970
+ padding: 5px 10px;
971
+ }
972
+
973
+ .rwmb-course_lesson_quiz-wrapper .rwmb-label{ display: none;}
974
+ .rwmb-course_lesson_quiz-wrapper .rwmb-input{ float: none; width: auto; display: block;}
975
+
976
+ .lp-course-curriculum-toggle{
977
+
978
+ }
979
+ .lp-course-curriculum-toggle .expand{
980
+ display: none;
981
  }*/
assets/css/learnpress-course-coming-soon.css DELETED
@@ -1,330 +0,0 @@
1
- .counter-group {
2
- margin: 30px auto;
3
- display: inline-block;
4
- }
5
-
6
- .counter-group:before,
7
- .counter-group:after {
8
- content: " ";
9
- display: table;
10
- }
11
-
12
- .counter-group:after {
13
- clear: both;
14
- }
15
-
16
- .counter-block {
17
- float: left;
18
- margin-right: 20px;
19
- }
20
-
21
- .counter-block .counter {
22
- position: relative;
23
- width: 100px;
24
- height: 50px;
25
- overflow: hidden;
26
- font-weight: 700;
27
- }
28
-
29
- .counter-block .counter .number {
30
- padding: 1%;
31
- width: 46%;
32
- height: 98%;
33
- background-color: #fff;
34
- color: #444;
35
- position: absolute;
36
- font-size: 40px;
37
- line-height: 50px;
38
- top: -10000px;
39
- text-align: center;
40
- }
41
-
42
- .counter-block .counter .number.tens {
43
- left: 0;
44
- }
45
-
46
- .counter-block .counter .number.units {
47
- left: 50%;
48
- }
49
-
50
- .counter-block .counter .number.hundreds {
51
- display: none;
52
- }
53
-
54
- .counter-block .counter .number.show {
55
- top: 0;
56
- z-index: 2;
57
- }
58
-
59
- .counter-block .counter .number.hidden-down {
60
- top: 100%;
61
- }
62
-
63
- .counter-block .counter .number.hidden-up {
64
- top: -100%;
65
- z-index: 100;
66
- }
67
-
68
- .counter-block .counter.with-hundreds {
69
- width: 300px;
70
- }
71
-
72
- .counter-block .counter.with-hundreds .number {
73
- width: 30.66%;
74
- }
75
-
76
- .counter-block .counter.with-hundreds .number.tens {
77
- left: 33.33%;
78
- }
79
-
80
- .counter-block .counter.with-hundreds .number.units {
81
- left: 66.66%;
82
- }
83
-
84
- .counter-block .counter.with-hundreds .number.hundreds {
85
- display: block;
86
- left: 0;
87
- }
88
-
89
- .counter-block .counter-caption {
90
- font-size: 100%;
91
- text-align: center;
92
- }
93
-
94
- .ob_discount {
95
- background: none repeat scroll 0 0 #000000;
96
- border-radius: 3px;
97
- height: 10px;
98
- width: 100%;
99
- clear: both;
100
- max-width: 300px;
101
- }
102
-
103
- .ob_sale {
104
- background: none repeat scroll 0 0 #CCCCCC;
105
- border-radius: 2px;
106
- height: 10px;
107
- }
108
-
109
- /*Product Categories*/
110
- /*Shortcode*/
111
- .ob_shortcode.woocommerce ul.products li.product {
112
- width: auto;
113
- }
114
- .ob_shortcode .ob_discount {
115
- width: 100%
116
- }
117
- .ob_shortcode .counter-block .counter .number {
118
- font-size: 19px;
119
- height: auto;
120
- line-height: 19px;
121
- padding: 0;
122
- }
123
- .ob_shortcode .counter-block .counter {
124
- height: 19px;
125
- line-height: 19px;
126
- margin: 0 auto;
127
- width: 44px;
128
- }
129
- .ob_shortcode .counter-block .counter.with-hundreds {
130
- width: 66px;
131
- }
132
- .ob_shortcode .counter-group {
133
- margin: 10px auto;
134
- }
135
- .ob_shortcode .counter-block {
136
- margin-right: 5px;
137
- }
138
- .ob_shortcode .counter-block .counter-caption {
139
- font-size: 13px;
140
- text-transform: capitalize;
141
- }
142
- /*Widget*/
143
- .ob_widget.woocommerce ul.products li.product {
144
- width: auto;
145
- }
146
- .ob_widget .ob_discount {
147
- width: 100%
148
- }
149
- .ob_widget .counter-block .counter .number {
150
- font-size: 19px;
151
- height: auto;
152
- line-height: 19px;
153
- padding: 0;
154
- }
155
- .ob_widget .counter-block .counter {
156
- height: 19px;
157
- line-height: 19px;
158
- margin: 0;
159
- width: 40px;
160
- }
161
- .ob_widget .counter-block .counter.with-hundreds {
162
- width: 60px;
163
- }
164
- .ob_widget .counter-group {
165
- margin: 10px auto;
166
- }
167
- .ob_widget .counter-block {
168
- margin-right: 0;
169
- }
170
- .ob_widget .counter-block .counter-caption {
171
- font-size: 10px;
172
- text-transform: capitalize;
173
- }
174
- /*Categories*/
175
- /*Widget*/
176
- .ob_categories.woocommerce ul.products li.product {
177
- width: 200px;
178
- }
179
- .ob_categories .ob_discount {
180
- width: 100%
181
- }
182
- .ob_categories .counter-block .counter .number {
183
- font-size: 19px;
184
- height: auto;
185
- line-height: 19px;
186
- padding: 0;
187
- margin: 0;
188
- }
189
- .ob_categories .counter-block .counter {
190
- height: 15px;
191
- height: 19px;
192
- line-height: 19px;
193
- margin: 0 auto;
194
- width: 44px;
195
- }
196
- .ob_categories .counter-block .counter.with-hundreds {
197
- width: 66px;
198
- }
199
- .ob_categories .counter-group {
200
- margin: 10px auto;
201
- }
202
- .ob_categories .counter-block {
203
- margin-right: 0;
204
- }
205
- .ob_categories .counter-block .counter-caption {
206
- font-size: 13px;
207
- text-transform: capitalize;
208
- }
209
- /*Detail*/
210
- .widget_product_detail .counter-block .counter .number {
211
- width: 29px;
212
- margin: 0;
213
- padding: 0;
214
- }
215
- .widget_product_detail .counter-block .counter {
216
- width: 61px;
217
- }
218
- .widget_product_detail .counter-block .counter.with-hundreds {
219
- width: 91px;
220
- }
221
- .ob_categories {
222
- min-width: 200px;
223
- }
224
- .ob_product_avariable_detail:not(:first-child) {
225
- display: none;
226
- }
227
- @media (max-width: 992px) {
228
- .counter-group {
229
- margin: 10px auto;
230
- }
231
- .counter-block {
232
- margin-right: 10px;
233
- }
234
- .counter-block .counter {
235
- width: 120px;
236
- height: 100px;
237
- overflow: hidden;
238
- font-weight: 700;
239
- }
240
- .counter-block .counter.with-hundreds {
241
- width: 180px;
242
- }
243
- .counter-block .counter .number {
244
- font-size: 78px;
245
- line-height: 90px;
246
- }
247
- .counter-block .counter-caption {
248
- font-size: 100%;
249
- }
250
- /*Detail*/
251
- .widget_product_detail .counter-block .counter .number {
252
- width: 45px;
253
- }
254
- .widget_product_detail .counter-block .counter {
255
- width: 95px;
256
- }
257
- }
258
-
259
- @media (max-width: 768px) {
260
- .counter-group {
261
- margin: 0 auto;
262
- }
263
- .counter-block {
264
- margin-right: 8px;
265
- }
266
- .counter-block .counter {
267
- width: 96px;
268
- height: 80px;
269
- }
270
- .counter-block .counter.with-hundreds {
271
- width: 144px;
272
- }
273
- .counter-block .counter .number {
274
- font-size: 78px;
275
- line-height: 72px;
276
- }
277
- .counter-block .counter.with-hundreds {
278
- width: 144px;
279
- }
280
- .counter-block .counter-caption {
281
- font-size: 85%;
282
- }
283
- }
284
-
285
- @media (max-width: 480px) {
286
- .counter-block .counter {
287
- width: 61px;
288
- height: 52px;
289
- }
290
- .counter-block .counter .number {
291
- font-size: 55px;
292
- line-height: 50px;
293
- }
294
- .counter-block .counter.with-hundreds {
295
- width: 91px;
296
- }
297
- .counter-block .counter-caption {
298
- font-size: 70%;
299
- }
300
- .widget_product_detail .counter-block .counter {
301
- width: 70px;
302
- }
303
- .widget_product_detail .counter-block .counter .number {
304
- font-size: 40px;
305
- width: 31px;
306
- }
307
- }
308
-
309
- .ob_wrapper {
310
- clear: both;
311
- }
312
- /*Fix short code on revolution slider*/
313
- .ob_shortcode > ul.shortcode_products li {
314
- visibility: visible;
315
- }
316
- code.thim-position-code {
317
- background: #FFD1B6;
318
- font-size: smaller;
319
- font-style: italic;
320
- color: #FFF;
321
- padding: 2px 5px;
322
- white-space: nowrap;
323
- margin: 0 3px 0 0;
324
- position: relative;
325
- z-index: 999;
326
- display: block;
327
- }
328
- .thim-countdown{
329
- clear: both;
330
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/learnpress.css CHANGED
@@ -104,6 +104,11 @@
104
  border: 1px solid #DDD;
105
  background: #FFF;
106
  }
 
 
 
 
 
107
  .learn-press-courses li.course h3 {
108
  padding: 15px;
109
  margin: 0;
@@ -1858,10 +1863,37 @@ body.block-content #learn-press-block-content {
1858
  top: 2px;
1859
  left: 3px;
1860
  }
1861
- .learn-press-user-profile {
1862
- /** STYLE PROFILE **/
1863
- /* Change Picture Menu */
1864
- /** upload-crop box **/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1865
  }
1866
  .learn-press-user-profile .user-basic-info p {
1867
  margin-top: 10px;
@@ -1891,128 +1923,247 @@ body.block-content #learn-press-block-content {
1891
  color: #007acc;
1892
  margin-bottom: -4px;
1893
  }
1894
- .learn-press-user-profile .learn-press-tabs-wrapper-x .learn-press-subtabs > li {
1895
  display: inline-block;
1896
  margin-right: 10px;
1897
  }
1898
- .learn-press-user-profile .learn-press-tabs-wrapper-x .learn-press-subtabs > li.current {
1899
  font-weight: bold;
1900
  }
1901
- .learn-press-user-profile .learn-press-tabs-wrapper-x .learn-press-subtab-content {
1902
  display: none;
 
1903
  }
1904
- .learn-press-user-profile .learn-press-tabs-wrapper-x .learn-press-subtab-content.current {
1905
  display: block;
1906
  }
1907
- .learn-press-user-profile .learn-press-tabs-wrapper-x .learn-press-subtab-content li.course h3 {
1908
  padding-bottom: 10px;
1909
  }
1910
- .learn-press-user-profile .learn-press-tabs-wrapper-x .learn-press-subtab-content .profile-courses {
1911
  list-style-type: none;
1912
  }
1913
- .learn-press-user-profile .learn-press-tabs-wrapper-x .learn-press-subtab-content .profile-courses .learn-press-course-results-progress {
1914
  padding: 0 15px 15px 15px;
1915
  margin: 0;
1916
  }
1917
- .learn-press-user-profile .learn-press-tabs-wrapper-x button.learn-press-course-wishlist {
1918
  display: block;
1919
  }
1920
- .learn-press-user-profile #lp-menu-change-picture {
1921
- list-style: none;
1922
  }
1923
- .learn-press-user-profile #lp-menu-change-picture .lp-label-change-picture {
1924
- display: block;
1925
- color: blueviolet;
1926
- padding: 2px 10px;
1927
- border: solid 1px gray;
1928
- cursor: pointer;
1929
  }
1930
- .learn-press-user-profile #lp-menu-change-picture .dropdown {
 
 
 
 
1931
  display: inline-block;
1932
  }
1933
- .learn-press-user-profile #lp-menu-change-picture .dropdown:hover .dropdown-menu {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1934
  display: block;
1935
  }
1936
- .learn-press-user-profile #lp-menu-change-picture .dropdown .dropdown-menu {
1937
  display: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1938
  position: absolute;
1939
- list-style: none;
1940
- margin: 0 !important;
1941
- padding: 0;
1942
- background-color: #F5F5F5;
1943
  }
1944
- .learn-press-user-profile #lp-menu-change-picture .dropdown .dropdown-menu li {
1945
- display: block;
1946
- cursor: pointer;
1947
- border: solid 1px #999999;
1948
- border-bottom: none;
1949
- padding: 3px 10px;
 
1950
  }
1951
- .learn-press-user-profile #lp-menu-change-picture .dropdown .dropdown-menu li:hover {
1952
- color: blue;
1953
- background-color: lightblue;
 
 
 
 
 
 
1954
  }
1955
- .learn-press-user-profile #lp-menu-change-picture .dropdown .dropdown-menu li:last-child {
1956
- border-bottom: solid 1px #999999;
 
 
1957
  }
1958
- .learn-press-user-profile #lp-menu-change-picture .dropdown .dropdown-menu li.lp-menu-item-selected {
1959
- background: royalblue;
1960
  }
1961
- .learn-press-user-profile #lp-profile_picture_type {
1962
  display: none;
1963
  }
1964
- .learn-press-user-profile #lpbox-upload-crop-profile-picture {
 
 
 
 
1965
  display: none;
1966
- border: solid 1px gray;
1967
- padding: 10px;
1968
- max-width: 500px;
1969
- background-color: ghostwhite;
1970
  }
1971
- .learn-press-user-profile #lpbox-upload-crop-profile-picture .lpbox-title {
1972
- font-size: 20px;
 
1973
  }
1974
- .learn-press-user-profile #lpbox-upload-crop-profile-picture .image-editor {
1975
- width: 300px;
1976
- float: left;
 
 
 
 
 
1977
  }
1978
- .learn-press-user-profile #lpbox-upload-crop-profile-picture .image-editor .cropit-preview {
1979
- background-color: #f8f8f8;
1980
- background-size: cover;
1981
- border: 1px solid #ccc;
1982
- border-radius: 3px;
1983
- margin-top: 7px;
1984
- width: 252px;
1985
- height: 252px;
1986
  }
1987
- .learn-press-user-profile #lpbox-upload-crop-profile-picture .image-editor .cropit-preview .cropit-preview-image-container {
 
 
 
 
 
 
 
 
 
 
1988
  cursor: move;
1989
  }
1990
- .learn-press-user-profile #lpbox-upload-crop-profile-picture .image-editor .cropit-preview .cropit-preview-image-container .cropit-preview-image {
1991
- max-width: none;
1992
- max-height: none;
 
 
1993
  }
1994
- .learn-press-user-profile #lpbox-upload-crop-profile-picture .image-editor .image-editor-btn {
1995
- margin: 10px auto;
1996
- text-align: center !important;
 
 
 
 
1997
  }
1998
- .learn-press-user-profile #lpbox-upload-crop-profile-picture .image-editor .image-editor-btn .input {
1999
- display: inline-block !important;
 
 
 
2000
  }
2001
- .learn-press-user-profile #lpbox-upload-crop-profile-picture .image-editor .cropit-preview {
2002
- margin: 0 auto;
 
 
 
 
 
 
 
 
 
2003
  }
2004
- .learn-press-user-profile #lpbox-upload-crop-profile-picture .image-editor-sidebar-right {
2005
- width: 150px;
2006
- float: left;
 
 
 
2007
  }
2008
- .learn-press-user-profile #lpbox-upload-crop-profile-picture .image-editor-sidebar-right a {
 
 
 
 
 
 
 
 
2009
  display: block;
2010
- text-align: center;
2011
- margin: 10px 0;
2012
  }
2013
- .learn-press-user-profile #lpbox-upload-crop-profile-picture .image-editor-sidebar-right .dashicons {
2014
- line-height: 1.5;
2015
- margin-right: 5px;
 
 
 
 
 
 
 
2016
  }
2017
  .learn-press-pagination {
2018
  text-align: center;
@@ -2062,15 +2213,6 @@ body.block-content #learn-press-block-content {
2062
  #popup_container #popup_panel {
2063
  text-align: center;
2064
  }
2065
- .single-lp_course .course-summary .course-students {
2066
- padding-top: 10px;
2067
- }
2068
- .single-lp_course .course-summary .course-students-list .students-list-title {
2069
- float: left;
2070
- }
2071
- .single-lp_course .course-summary .course-students-list .filter-students {
2072
- float: right;
2073
- }
2074
  .single-lp_course .course-summary .lp_course .entry-footer {
2075
  display: none;
2076
  }
@@ -2078,50 +2220,6 @@ body.block-content #learn-press-block-content {
2078
  clear: both;
2079
  margin-top: 25px;
2080
  }
2081
- .course-students-list {
2082
- margin-top: 10px;
2083
- margin-bottom: 15px;
2084
- }
2085
- .course-students-list .students {
2086
- clear: both;
2087
- }
2088
- .course-students-list .students .user-info {
2089
- margin-bottom: 15px;
2090
- }
2091
- .course-students-list .students li {
2092
- margin-right: 10px;
2093
- }
2094
- .course-students-list .students li.user-login {
2095
- display: block;
2096
- width: 100%;
2097
- float: left;
2098
- }
2099
- .course-students-list .students li .user-info {
2100
- position: relative;
2101
- float: left;
2102
- width: 150px;
2103
- }
2104
- .course-students-list .students li .user-info a {
2105
- position: absolute;
2106
- margin-left: 5px;
2107
- bottom: 0;
2108
- }
2109
- .course-students-list .students li .learn-press-course-results-progress {
2110
- width: 80%;
2111
- float: left;
2112
- margin-top: -15px;
2113
- margin-bottom: 5px;
2114
- }
2115
- .course-students-list .students li .learn-press-course-results-progress .course-progress {
2116
- width: 100%;
2117
- }
2118
- .course-students-list .students li .learn-press-course-results-progress .course-progress .lp-course-progress {
2119
- margin-top: -5px;
2120
- }
2121
- .course-students-list .additional-students {
2122
- clear: both;
2123
- margin-bottom: 0;
2124
- }
2125
  /* tooltip */
2126
  .learn-press-tooltip-bubble {
2127
  position: absolute;
@@ -2197,52 +2295,6 @@ body.content-item-only #learn-press-content-item.expand {
2197
 
2198
 
2199
  }*/
2200
- .user-profile-edit-form .info-field {
2201
- margin-bottom: 20px;
2202
- }
2203
- .user-profile-edit-form .description {
2204
- margin-top: 5px;
2205
- }
2206
- .user-profile-edit-form .user-profile-picture {
2207
- clear: both;
2208
- }
2209
- .user-profile-edit-form .user-profile-picture .picture,
2210
- .user-profile-edit-form .user-profile-picture .change-picture {
2211
- display: inline-block;
2212
- }
2213
- .user-profile-edit-form .user-profile-picture .change-picture .description {
2214
- margin: 0 0 10px 0;
2215
- }
2216
- .user-profile-edit-form .user-profile-picture img {
2217
- float: left;
2218
- margin-right: 20px;
2219
- }
2220
- .user-profile-edit-form .user-profile-picture:after {
2221
- display: block;
2222
- content: '';
2223
- clear: both;
2224
- }
2225
- .user-profile-edit-form .user-profile-picture:after:after {
2226
- content: '';
2227
- display: block;
2228
- clear: both;
2229
- }
2230
- .user-profile-edit-form .profile-field-name {
2231
- font-weight: bold;
2232
- margin-bottom: 10px;
2233
- }
2234
- .user-profile-edit-form .change-password {
2235
- margin-bottom: 10px;
2236
- }
2237
- .user-profile-edit-form #user_profile_password_form input {
2238
- margin-bottom: 20px;
2239
- }
2240
- .user-profile-edit-form #user_profile_password_form .description {
2241
- margin-top: -15px;
2242
- }
2243
- .user-profile-edit-form .update-profile {
2244
- margin-top: 20px;
2245
- }
2246
  .payment-method-form.payment_method_authorizenet {
2247
  background: #f7f7f7;
2248
  border-radius: 5px;
104
  border: 1px solid #DDD;
105
  background: #FFF;
106
  }
107
+ .learn-press-courses li.course .view-more {
108
+ padding: 0 15px;
109
+ text-decoration: none;
110
+ box-shadow: none;
111
+ }
112
  .learn-press-courses li.course h3 {
113
  padding: 15px;
114
  margin: 0;
1863
  top: 2px;
1864
  left: 3px;
1865
  }
1866
+ /* Form field */
1867
+ .lp-form-field-wrap {
1868
+ list-style: none;
1869
+ margin: 0 0 20px 0;
1870
+ }
1871
+ .lp-form-field-wrap .lp-form-field {
1872
+ list-style: none;
1873
+ margin: 0 0 20px 0;
1874
+ }
1875
+ .lp-form-field-wrap .lp-form-field .lp-form-field-label {
1876
+ display: block;
1877
+ font-weight: bold;
1878
+ margin-bottom: 5px;
1879
+ }
1880
+ .lp-form-field-wrap .lp-form-field .lp-form-field-input .description {
1881
+ font-size: smaller;
1882
+ font-style: italic;
1883
+ margin-top: 5px;
1884
+ }
1885
+ .lp-form-field-wrap .lp-form-field .lp-field-error-message {
1886
+ color: #FF0000;
1887
+ }
1888
+ .learn-press-user-profile .lp-edit-profile:after {
1889
+ display: block;
1890
+ content: '';
1891
+ clear: both;
1892
+ }
1893
+ .learn-press-user-profile .lp-edit-profile:after:after {
1894
+ content: '';
1895
+ display: block;
1896
+ clear: both;
1897
  }
1898
  .learn-press-user-profile .user-basic-info p {
1899
  margin-top: 10px;
1923
  color: #007acc;
1924
  margin-bottom: -4px;
1925
  }
1926
+ .learn-press-user-profile .learn-press-subtabs > li {
1927
  display: inline-block;
1928
  margin-right: 10px;
1929
  }
1930
+ .learn-press-user-profile .learn-press-subtabs > li.current {
1931
  font-weight: bold;
1932
  }
1933
+ .learn-press-user-profile .learn-press-subtab-content {
1934
  display: none;
1935
+ margin-bottom: 20px;
1936
  }
1937
+ .learn-press-user-profile .learn-press-subtab-content.current {
1938
  display: block;
1939
  }
1940
+ .learn-press-user-profile .learn-press-subtab-content li.course h3 {
1941
  padding-bottom: 10px;
1942
  }
1943
+ .learn-press-user-profile .learn-press-subtab-content .profile-courses {
1944
  list-style-type: none;
1945
  }
1946
+ .learn-press-user-profile .learn-press-subtab-content .profile-courses .learn-press-course-results-progress {
1947
  padding: 0 15px 15px 15px;
1948
  margin: 0;
1949
  }
1950
+ .learn-press-user-profile button.learn-press-course-wishlist {
1951
  display: block;
1952
  }
1953
+ .learn-press-user-profile .user-profile-edit-form .info-field {
1954
+ margin-bottom: 20px;
1955
  }
1956
+ .learn-press-user-profile .user-profile-edit-form .description {
1957
+ margin-top: 5px;
 
 
 
 
1958
  }
1959
+ .learn-press-user-profile .user-profile-edit-form .user-profile-picture {
1960
+ clear: both;
1961
+ }
1962
+ .learn-press-user-profile .user-profile-edit-form .user-profile-picture .picture,
1963
+ .learn-press-user-profile .user-profile-edit-form .user-profile-picture .change-picture {
1964
  display: inline-block;
1965
  }
1966
+ .learn-press-user-profile .user-profile-edit-form .user-profile-picture .change-picture .description {
1967
+ margin: 0 0 10px 0;
1968
+ }
1969
+ .learn-press-user-profile .user-profile-edit-form .user-profile-picture img {
1970
+ float: left;
1971
+ margin-right: 20px;
1972
+ }
1973
+ .learn-press-user-profile .user-profile-edit-form .user-profile-picture:after {
1974
+ display: block;
1975
+ content: '';
1976
+ clear: both;
1977
+ }
1978
+ .learn-press-user-profile .user-profile-edit-form .user-profile-picture:after:after {
1979
+ content: '';
1980
+ display: block;
1981
+ clear: both;
1982
+ }
1983
+ .learn-press-user-profile .user-profile-edit-form .profile-field-name {
1984
+ font-weight: bold;
1985
+ margin-bottom: 10px;
1986
+ }
1987
+ .learn-press-user-profile .user-profile-edit-form .change-password {
1988
+ margin-bottom: 10px;
1989
+ }
1990
+ .learn-press-user-profile .user-profile-edit-form #user_profile_password_form input {
1991
+ margin-bottom: 20px;
1992
+ }
1993
+ .learn-press-user-profile .user-profile-edit-form #user_profile_password_form .description {
1994
+ margin-top: -15px;
1995
+ }
1996
+ .learn-press-user-profile .update-profile {
1997
+ border-top: 2px solid #DDD;
1998
+ padding-top: 20px;
1999
+ }
2000
+ .learn-press-user-profile .learn-press-subtab-content {
2001
  display: block;
2002
  }
2003
+ .learn-press-user-profile #lp-user-edit-avatar .moxie-shim {
2004
  display: none;
2005
+ }
2006
+ .learn-press-user-profile #lp-user-edit-avatar .lp-form-field-avatar {
2007
+ float: left;
2008
+ }
2009
+ .learn-press-user-profile #lp-user-edit-avatar #lp-avatar-actions {
2010
+ margin: 20px 0;
2011
+ }
2012
+ .learn-press-user-profile .lp-avatar-preview {
2013
+ position: relative;
2014
+ float: left;
2015
+ background-color: #DDD;
2016
+ }
2017
+ .learn-press-user-profile .lp-avatar-preview .profile-picture {
2018
+ float: left;
2019
+ margin-right: -100%;
2020
+ width: 100%;
2021
+ }
2022
+ .learn-press-user-profile .lp-avatar-preview .profile-picture img {
2023
+ width: 100%;
2024
+ height: 100%;
2025
+ border-radius: 0;
2026
+ }
2027
+ .learn-press-user-profile .lp-avatar-preview .profile-picture.profile-avatar-hidden {
2028
+ display: none;
2029
+ }
2030
+ .learn-press-user-profile .lp-avatar-preview .lp-avatar-preview-actions {
2031
  position: absolute;
2032
+ top: 50%;
2033
+ width: 100%;
2034
+ margin-top: -14px;
2035
+ text-align: center;
2036
  }
2037
+ .learn-press-user-profile .lp-avatar-preview .lp-avatar-preview-actions a {
2038
+ text-decoration: none;
2039
+ font-size: 12px;
2040
+ background: #FFF;
2041
+ display: inline-block;
2042
+ box-shadow: none;
2043
+ padding: 5px 10px;
2044
  }
2045
+ .learn-press-user-profile .lp-avatar-preview .lp-avatar-upload-progress {
2046
+ position: absolute;
2047
+ height: 10px;
2048
+ background: #FFF;
2049
+ top: 50%;
2050
+ margin-top: -5px;
2051
+ left: 10px;
2052
+ right: 10px;
2053
+ display: none;
2054
  }
2055
+ .learn-press-user-profile .lp-avatar-preview .lp-avatar-upload-progress .lp-avatar-upload-progress-value {
2056
+ width: 0;
2057
+ height: 10px;
2058
+ background: #563d7c;
2059
  }
2060
+ .learn-press-user-profile .lp-avatar-preview .lp-avatar-upload-error {
2061
+ display: none;
2062
  }
2063
+ .learn-press-user-profile .lp-avatar-preview .lp-avatar-preview-actions {
2064
  display: none;
2065
  }
2066
+ .learn-press-user-profile .lp-avatar-preview:hover .lp-avatar-preview-actions {
2067
+ display: block;
2068
+ }
2069
+ .learn-press-user-profile .lp-avatar-preview.uploading .lp-avatar-preview-actions,
2070
+ .learn-press-user-profile .lp-avatar-preview.upload-error .lp-avatar-preview-actions {
2071
  display: none;
 
 
 
 
2072
  }
2073
+ .learn-press-user-profile .lp-avatar-preview.uploading .lp-avatar-upload-progress,
2074
+ .learn-press-user-profile .lp-avatar-preview.upload-error .lp-avatar-upload-progress {
2075
+ display: block;
2076
  }
2077
+ .learn-press-user-profile .lp-avatar-preview.uploading:before,
2078
+ .learn-press-user-profile .lp-avatar-preview.upload-error:before {
2079
+ position: absolute;
2080
+ width: 100%;
2081
+ height: 100%;
2082
+ background: #FFF;
2083
+ opacity: 0.4;
2084
+ content: '';
2085
  }
2086
+ .learn-press-user-profile .lp-avatar-preview.upload-error .lp-avatar-upload-error {
2087
+ display: block;
2088
+ }
2089
+ .learn-press-user-profile .lp-avatar-preview.croping .lp-avatar-preview-actions {
2090
+ display: none;
 
 
 
2091
  }
2092
+ .learn-press-user-profile .lp-avatar-preview.croping .lp-avatar-crop-image {
2093
+ position: absolute;
2094
+ top: 0;
2095
+ left: 0;
2096
+ width: 100%;
2097
+ height: 100%;
2098
+ background: #000;
2099
+ overflow: hidden;
2100
+ }
2101
+ .learn-press-user-profile .lp-avatar-preview.croping .lp-avatar-crop-image img {
2102
+ max-width: inherit;
2103
  cursor: move;
2104
  }
2105
+ .learn-press-user-profile .lp-avatar-preview.croping .lp-avatar-crop-image .lp-crop-controls {
2106
+ position: absolute;
2107
+ bottom: 0;
2108
+ width: 100%;
2109
+ height: 30px;
2110
  }
2111
+ .learn-press-user-profile .lp-avatar-preview.croping .lp-avatar-crop-image .lp-crop-controls .lp-zoom {
2112
+ position: absolute;
2113
+ height: 10px;
2114
+ bottom: 10px;
2115
+ left: 10px;
2116
+ right: 30px;
2117
+ background: #563d7a;
2118
  }
2119
+ .learn-press-user-profile .lp-avatar-preview.croping .lp-avatar-crop-image .lp-crop-controls .lp-zoom .ui-slider {
2120
+ position: absolute;
2121
+ left: 0;
2122
+ right: 10px;
2123
+ height: 100%;
2124
  }
2125
+ .learn-press-user-profile .lp-avatar-preview.croping .lp-avatar-crop-image .lp-crop-controls .lp-zoom .ui-slider .ui-slider-handle {
2126
+ display: inline-block;
2127
+ width: 10px;
2128
+ height: 14px;
2129
+ background: #FFF;
2130
+ position: absolute;
2131
+ margin-top: -2px;
2132
+ border: 1px solid #563d7a;
2133
+ box-shadow: none;
2134
+ outline: none;
2135
+ cursor: ew-resize;
2136
  }
2137
+ .learn-press-user-profile .lp-avatar-preview.croping .lp-avatar-crop-image .lp-crop-controls .lp-cancel-upload {
2138
+ text-decoration: none;
2139
+ position: absolute;
2140
+ bottom: 5px;
2141
+ right: 5px;
2142
+ box-shadow: none;
2143
  }
2144
+ .learn-press-user-profile .lp-avatar-preview.croping .lp-avatar-crop-image .lp-crop-controls:before {
2145
+ position: absolute;
2146
+ height: 30px;
2147
+ width: 100%;
2148
+ content: '';
2149
+ background: #FFF;
2150
+ opacity: 0.4;
2151
+ }
2152
+ .learn-press-user-profile .lp-avatar-preview:after {
2153
  display: block;
2154
+ content: '';
2155
+ clear: both;
2156
  }
2157
+ .learn-press-user-profile .lp-avatar-preview:after:after {
2158
+ content: '';
2159
+ display: block;
2160
+ clear: both;
2161
+ }
2162
+ body.profile-dragging {
2163
+ cursor: move !important;
2164
+ }
2165
+ body.profile-resizing {
2166
+ cursor: ew-resize !important;
2167
  }
2168
  .learn-press-pagination {
2169
  text-align: center;
2213
  #popup_container #popup_panel {
2214
  text-align: center;
2215
  }
 
 
 
 
 
 
 
 
 
2216
  .single-lp_course .course-summary .lp_course .entry-footer {
2217
  display: none;
2218
  }
2220
  clear: both;
2221
  margin-top: 25px;
2222
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2223
  /* tooltip */
2224
  .learn-press-tooltip-bubble {
2225
  position: absolute;
2295
 
2296
 
2297
  }*/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2298
  .payment-method-form.payment_method_authorizenet {
2299
  background: #f7f7f7;
2300
  border-radius: 5px;
assets/css/learnpress.less CHANGED
@@ -1,2106 +1,2152 @@
1
- @icon-url: '../fonts/lp-icons';
2
- @font-face {
3
- font-family: 'lp-icons';
4
- src: url('@{icon-url}.eot?f41nl');
5
- src: url('@{icon-url}.eot?f41nl#iefix') format('embedded-opentype'),
6
- url('@{icon-url}.ttf?f41nl') format('truetype'),
7
- url('@{icon-url}.woff?f41nl') format('woff'),
8
- url('@{icon-url}.svg?f41nl#lp-icons') format('svg');
9
- font-weight: normal;
10
- font-style: normal;
11
- }
12
-
13
- [class^="lp-icon-"], [class*=" lp-icon-"] {
14
- /* use !important to prevent issues with browser extensions that change fonts */
15
- font-family: 'lp-icons' !important;
16
- speak: none;
17
- font-style: normal;
18
- font-weight: normal;
19
- font-variant: normal;
20
- text-transform: none;
21
- line-height: 1;
22
-
23
- /* Better Font Rendering =========== */
24
- -webkit-font-smoothing: antialiased;
25
- -moz-osx-font-smoothing: grayscale;
26
- }
27
-
28
- .lp-icon-file-text2:before {
29
- content: "\e926";
30
- }
31
-
32
- .lp-icon-file-picture:before {
33
- content: "\e927";
34
- }
35
-
36
- .lp-icon-file-music:before {
37
- content: "\e928";
38
- }
39
-
40
- .lp-icon-file-video:before {
41
- content: "\e92a";
42
- }
43
-
44
- .lp-icon-file-zip:before {
45
- content: "\e92b";
46
- }
47
-
48
- .lp-icon-paste:before {
49
- content: "\e92d";
50
- }
51
-
52
- .lp-icon-alarm:before {
53
- content: "\e950";
54
- }
55
-
56
- .lp-icon-cross:before {
57
- content: "\ea0f";
58
- }
59
-
60
- .lp-icon-checkmark:before {
61
- content: "\ea10";
62
- }
63
-
64
- .lp-icon-spinner2:before {
65
- content: "\e97b";
66
- }
67
-
68
- .lp-icon-plus:before {
69
- content: "\ea0a";
70
- }
71
-
72
- .lp-icon-minus:before {
73
- content: "\ea0b";
74
- }
75
-
76
- .clearfix() {
77
- display: block;
78
- content: '';
79
- clear: both;
80
- }
81
-
82
- .clearfix:after {
83
- display: block;
84
- content: '';
85
- clear: both;
86
- }
87
-
88
- .border-radius(@args) {
89
- -webkit-border-radius: @arguments;
90
- -khtml-border-radius: @arguments;
91
- -moz-border-radius: @arguments;
92
- -ms-border-radius: @arguments;
93
- -o-border-radius: @arguments;
94
- border-radius: @arguments;
95
- }
96
-
97
- .transform(@args) {
98
- -webkit-transform: @arguments;
99
- -khtml-transform: @arguments;
100
- -moz-transform: @arguments;
101
- -ms-transform: @arguments;
102
- -o-transform: @arguments;
103
- transform: @arguments;
104
- }
105
-
106
- .transition(@args) {
107
- -webkit-transition: @arguments;
108
- -khtml-transition: @arguments;
109
- -moz-transition: @arguments;
110
- -ms-transition: @arguments;
111
- -o-transition: @arguments;
112
- transition: @arguments;
113
- }
114
-
115
- .cross(@size: 30px, @border: 3px, @color: #000) {
116
- &:before,
117
- &:after {
118
- width: @border;
119
- background: @color;
120
- height: @size;
121
- content: '';
122
- display: inline-block;
123
- position: absolute;
124
- top: 0;
125
- left: (@size - @border) / 2;
126
- }
127
- &:before {
128
- .transform(rotate(-45deg));
129
- }
130
- &:after {
131
- .transform(rotate(45deg));
132
- }
133
- }
134
-
135
- .animation(@args) {
136
- -webkit-animation: @arguments;
137
- -moz-animation: @arguments;
138
- animation: @arguments;
139
- }
140
-
141
- .overlay-processing {
142
- &:before, &:after {
143
- content: '';
144
- display: block;
145
- position: fixed;
146
- top: 0;
147
- left: 0;
148
- width: 100%;
149
- height: 100%;
150
- z-index: 999999;
151
- }
152
- &:before {
153
- background: #000;
154
- opacity: 0.5;
155
- }
156
- &:after {
157
- background: #FFF;
158
- }
159
- }
160
-
161
- /* PROGRESS CIRCLE */
162
- .progress-circle(@size: 200px, @background: #DDD, @fill: #95e6f9, @initialize: 0, @inside-size: 170px, @inside-background: #FFF) {
163
- .progress-circle {
164
- width: @size;
165
- height: @size;
166
- border-radius: 50%;
167
- background-color: @background;
168
- position: relative;
169
- .background {
170
- content: "";
171
- position: absolute;
172
- border-radius: 50%;
173
- width: @size;
174
- height: @size;
175
- clip: rect(0, @size, @size, @size / 2);
176
- .fill {
177
- content: "";
178
- position: absolute;
179
- border-radius: 50%;
180
- width: @size;
181
- height: @size;
182
- clip: rect(0, @size / 2, @size, 0);
183
- background: @fill;
184
- transform: rotate(unit(@initialize*3.6, deg));
185
- }
186
- }
187
- &:after {
188
- content: '';
189
- width: @inside-size;
190
- height: @inside-size;
191
- background: @inside-background;
192
- .border-radius(50%);
193
- position: absolute;
194
- top: 50%;
195
- left: 50%;
196
- margin-top: -@inside-size / 2;
197
- margin-left: -@inside-size / 2;
198
- pointer-events: none;
199
- }
200
- .inside {
201
- position: absolute;
202
- width: 100%;
203
- height: 100%;
204
- line-height: @size;
205
- text-align: center;
206
- z-index: 10;
207
- }
208
- &.gt-50 {
209
- background-color: @fill;
210
- .background {
211
- clip: rect(0, @size/2, @size, 0);
212
- }
213
- .fill {
214
- clip: rect(0, @size, @size, @size/2);
215
- background: @background;
216
- }
217
- }
218
- }
219
- }
220
-
221
- .clearfix() {
222
- &:after {
223
- content: '';
224
- display: block;
225
- clear: both;
226
- }
227
- }
228
-
229
- .hide-if-js {
230
- display: none !important;
231
- }
232
-
233
- /* Archive courses */
234
- .learn-press-courses {
235
- list-style: none;
236
- clear: both;
237
- margin: 0 -30px 0 0;
238
- padding: 0;
239
- &:after {
240
- display: block;
241
- content: '';
242
- clear: both;
243
- }
244
- li.course {
245
- list-style-type: none;
246
- float: left;
247
- width: 23%;
248
- margin: 0 2% 30px 0;
249
- padding: 0;
250
- box-sizing: border-box;
251
- border: 1px solid #DDD;
252
- background: #FFF;
253
- h3 {
254
- padding: 15px;
255
- margin: 0;
256
- font-size: 18px;
257
- line-height: 1.5;
258
- }
259
- .course-thumbnail {
260
- position: relative;
261
- img {
262
- max-width: 100%;
263
- height: auto;
264
- }
265
- &:after {
266
- content: '';
267
- position: absolute;
268
- width: 100%;
269
- height: 100%;
270
- left: 0;
271
- top: 0;
272
- }
273
- }
274
- .course-info {
275
- padding: 0 15px 15px;
276
- font-size: 14px;
277
- overflow: hidden;
278
- }
279
- .course-students {
280
- float: left;
281
- }
282
- .course-instructor {
283
- margin-bottom: 20px;
284
- }
285
- .course-origin-price {
286
- float: right;
287
- text-decoration: line-through;
288
- padding-right: 5px;
289
- }
290
- .course-price {
291
- float: right;
292
- color: rgb(84, 181, 81);
293
- }
294
- .course-info > * {
295
- display: block;
296
- }
297
- }
298
- }
299
-
300
- .learn-press-notice .button {
301
- float: right;
302
- }
303
-
304
- .learn-press-form {
305
- margin-bottom: 20px;
306
- }
307
-
308
- //
309
-
310
- #learn-press-course-curriculum {
311
- ul.curriculum-sections,
312
- ul.section-content {
313
- list-style: none;
314
- margin: 0;
315
- padding: 0;
316
- background-color: #F5F5F5;
317
- li.section {
318
- list-style-type: none;
319
- }
320
- }
321
- .section-header {
322
- background-color: #EEE;
323
- margin: 0;
324
- padding: 20px 15px;
325
- border-top: 1px solid #FFF;
326
- position: relative;
327
- p {
328
- display: inline-block;
329
- font-weight: normal;
330
- font-style: italic;
331
- color: rgb(153, 153, 153);
332
- font-size: 14px;
333
- margin: 0;
334
- padding: 10px 0;
335
- text-transform: none;
336
- }
337
- &:hover {
338
- background: #DDD;
339
- }
340
- .meta {
341
- font-size: smaller;
342
- font-weight: normal;
343
- position: absolute;
344
- right: 15px;
345
- top: 20px;
346
- .collapse {
347
- display: inline-block;
348
- position: relative;
349
- font-family: 'lp-icons';
350
- background: #95e6f9;
351
- width: 24px;
352
- height: 24px;
353
- line-height: 24px;
354
- text-align: center;
355
- color: #FFF;
356
- border-radius: 5px;
357
- vertical-align: middle;
358
- margin-left: 5px;
359
- &:before {
360
- content: "\ea0b";
361
- margin: 0 auto;
362
- }
363
- &:hover {
364
- cursor: pointer;
365
- }
366
- &.plus {
367
- &:before {
368
- content: "\ea0a";
369
- }
370
- }
371
- }
372
- }
373
- }
374
- .course-item {
375
- margin: 0;
376
- list-style: none;
377
- padding: 10px 15px;
378
- border-top: 1px solid rgb(255, 255, 255);
379
- position: relative;
380
- .transition(background linear 0.5s);
381
- .lp-label-viewing,
382
- .lp-label-completed {
383
- display: none;
384
- }
385
- .course-item-title {
386
- display: block;
387
- box-shadow: none;
388
- text-align: justify;
389
- float: left;
390
- &:before {
391
- display: inline-block;
392
- font-size: 16px;
393
- margin-right: 10px;
394
- font-family: 'lp-icons';
395
- }
396
- }
397
- .lp-icon {
398
- display: none;
399
- }
400
- &.viewable {
401
- cursor: pointer;
402
- &:hover {
403
- background: #e7ecfb;
404
- .transition(background linear 0s);
405
- }
406
- }
407
- &.course-lesson {
408
- .course-item-title {
409
- &:before {
410
- content: '\e926';
411
- }
412
- }
413
- }
414
- &.course-quiz {
415
- .course-item-title {
416
- &:before {
417
- content: '\e950';
418
- }
419
- }
420
- }
421
- &.item-current {
422
- background: #FFF;
423
- &:before {
424
- display: block;
425
- width: 3px;
426
- background: #95e6f9;
427
- position: absolute;
428
- left: 0;
429
- top: 0;
430
- height: 100%;
431
- content: '';
432
- }
433
- }
434
- &.item-has-status .item-status {
435
- display: inline-block;
436
- background: #d6d6d6;
437
- margin-left: 5px;
438
- &:before {
439
- content: '\ea10';
440
- color: #FFF;
441
- }
442
- }
443
- &.item-has-status.item-completed {
444
- .item-status {
445
- background: #95e6f9;
446
- }
447
- }
448
- &.focus {
449
- background: #ffb710;
450
- &.off {
451
- .transition(none);
452
- }
453
- }
454
- &:after {
455
- display: block;
456
- clear: both;
457
- content: '';
458
- }
459
- }
460
-
461
- .course-item-meta {
462
- display: block;
463
- line-height: 1;
464
- __position: absolute;
465
- top: 15px;
466
- right: 15px;
467
- float: right;
468
- margin-top: 5px;
469
- }
470
- }
471
-
472
- .lp-icon {
473
- display: inline-block;
474
- font-family: 'lp-icons';
475
- background: #95e6f9;
476
- width: 24px;
477
- height: 24px;
478
- line-height: 24px;
479
- text-align: center;
480
- color: #FFF;
481
- border-radius: 5px;
482
- vertical-align: middle;
483
- &:before {
484
- width: 32px;
485
- height: 32px;
486
- }
487
-
488
- }
489
-
490
- .lp-label {
491
- display: inline-block;
492
- line-height: 24px;
493
- font-size: 78%;
494
- vertical-align: middle;
495
- color: #ffffff;
496
- padding: 0 10px;
497
- background: #DDD;
498
- height: 24px;
499
- .border-radius(4px);
500
- &.lp-label-viewing {
501
- background-color: rgb(57, 175, 255);
502
- }
503
- &.lp-label-completed {
504
- background-color: #39c7ce;
505
- }
506
- &.lp-label-lesson {
507
- background-color: #337ab7;
508
- }
509
- &.lp-label-quiz {
510
- background-color: #53658c;
511
- }
512
- &.lp-label-preview {
513
- background-color: #02a7ce;
514
- }
515
- }
516
-
517
- .learn-press-content-protected-message {
518
- border: 3px solid #ff8484;
519
- background: #FFF;
520
- padding: 20px;
521
- color: #ff8484;
522
- margin: 10px 0;
523
- border-radius: 6px;
524
- .icon {
525
- position: relative;
526
- display: inline-block;
527
- width: 30px;
528
- height: 30px;
529
- margin-right: 10px;
530
- vertical-align: middle;
531
- .cross(30px, 3px, #ff8484);
532
- }
533
- }
534
-
535
- /** BREADCRUMB */
536
- .learn-press-breadcrumb {
537
- margin-bottom: 20px;
538
- }
539
-
540
- /** COURSE PROGRESS **/
541
- .single-lp_course {
542
- .learn-press-course-results-progress {
543
- margin-bottom: 40px;
544
- .items-progress {
545
- float: left;
546
- width: 68%;
547
- margin-right: 2%;
548
- clear: left;
549
- }
550
- .lp-course-progress-heading {
551
- margin-bottom: 10px;
552
- }
553
- .course-progress {
554
- float: left;
555
- width: 30%;
556
- }
557
- .number, .percentage-sign {
558
- display: inline-block;
559
- vertical-align: bottom;
560
- line-height: 1;
561
- font-size: 25px;
562
- }
563
- .percentage-sign {
564
- margin-left: 5px;
565
- }
566
- &:after {
567
- display: block;
568
- content: '';
569
- clear: both;
570
- }
571
- }
572
- }
573
-
574
- .lp-course-progress {
575
- position: relative;
576
- .lp-progress-bar {
577
- height: 15px;
578
- background: #DDD;
579
- margin: 10px 0 15px 0;
580
- overflow: hidden;
581
- .border-radius(3px);
582
- .lp-progress-value {
583
- width: 50%;
584
- height: 15px;
585
- background: #95e6f9;
586
- }
587
- }
588
- .lp-passing-conditional {
589
- left: 0%;
590
- position: absolute;
591
- height: 25px;
592
- top: -5px;
593
- margin-left: -5px;
594
- cursor: pointer;
595
- &:before,
596
- &:after {
597
- content: '';
598
- display: inline-block;
599
- border: 5px solid transparent;
600
- left: 0;
601
- position: absolute;
602
- }
603
- &:before {
604
- border-top-color: #DDD;
605
- }
606
- &:after {
607
- border-bottom-color: #DDD;
608
- bottom: 0;
609
- }
610
- }
611
- }
612
-
613
- #learn-press-content-item {
614
- border: 1px solid #DDD;
615
- display: none;
616
-
617
- }
618
-
619
- /** COURSE TABS **/
620
- .learn-press-tabs {
621
- .learn-press-nav-tabs {
622
- list-style: none;
623
- padding: 0;
624
- margin: 0 0 20px 0;
625
- border-bottom: 1px solid #DDD;
626
- .learn-press-nav-tab {
627
- list-style-type: none;
628
- float: left;
629
- margin-bottom: -1px;
630
- position: relative;
631
- a {
632
- display: inline-block;
633
- padding: 10px 15px;
634
- outline: none;
635
- box-shadow: none;
636
- color: #686868;
637
- border-bottom: 1px solid #DDD;
638
- }
639
- &.active {
640
- border-bottom: 4px solid #007acc;
641
- a {
642
- color: #007acc;
643
- border-bottom: none;
644
- margin-bottom: -4px;
645
- }
646
- }
647
- &.active:after {
648
- position: absolute;
649
- width: 100%;
650
- border-bottom: 1px solid #FFF;
651
- bottom: -1px;
652
- content: '';
653
- }
654
- }
655
- &:hover {
656
-
657
- }
658
- &:after {
659
- content: '';
660
- display: block;
661
- clear: both;
662
- }
663
- }
664
- .learn-press-tab-panel {
665
- display: none;
666
- margin-bottom: 20px;
667
- &.active {
668
- display: block;
669
- }
670
- }
671
- }
672
-
673
- .learn-press-block-content-mixin(@w) {
674
- &:before {
675
- width: (@w);
676
- height: (@w);
677
- margin-left: -(@w/2);
678
- margin-top: -(@w/2); /*-76px;*/
679
- -webkit-clip-path: polygon(0px @w, @w @w, @w @w/2, @w/2 @w/2, @w/2 0, 0 0);
680
- }
681
-
682
- span {
683
- clip: rect(0, @w+4, @w/2+2, @w/2+2);
684
- width: @w+4;
685
- height: @w+4;
686
- margin-left: -(@w/2+2);
687
- margin-top: -(@w/2+2);
688
- &:before {
689
- width: @w+4;
690
- height: @w+4;
691
- }
692
- }
693
- }
694
-
695
- /* POPUP */
696
-
697
- #popup_overlay {
698
- z-index: 10000000 !important;
699
- }
700
-
701
- #popup_container {
702
- z-index: 10000001 !important;
703
- }
704
-
705
- body.course-has-popup {
706
- overflow: hidden;
707
- }
708
-
709
- #course-curriculum-popup {
710
- position: fixed;
711
- top: 0;
712
- left: 0;
713
- right: 0;
714
- bottom: 0;
715
- background: #000;
716
- z-index: 999999;
717
- * {
718
- box-sizing: border-box;
719
- }
720
- #popup-sidebar {
721
- float: left;
722
- width: 350px;
723
- position: absolute;
724
- top: 60px;
725
- bottom: 0;
726
- overflow: auto;
727
- background: #FFF;
728
- border-right: 1px solid #DDD;
729
- .course-curriculum-title {
730
- display: none;
731
- }
732
- .curriculum-sections {
733
- margin: 0;
734
- font-size: smaller;
735
- }
736
- .learn-press-course-results-progress {
737
- padding: 15px 20px;
738
- margin-bottom: 0;
739
- .items-progress, .course-progress {
740
- width: 100%;
741
- margin: 0 !important;
742
- }
743
- }
744
- }
745
- #popup-main {
746
- position: absolute;
747
- top: 0;
748
- left: 350px;
749
- right: 0;
750
- bottom: 0;
751
- background: #FFF;
752
- #popup-header {
753
- position: absolute;
754
- top: 0;
755
- left: -350px;
756
- right: 0;
757
- height: 60px;
758
- background: #cc540d;
759
- border-bottom: 1px solid #ab4a10;
760
- .popup-menu {
761
- position: absolute;
762
- height: 60px;
763
- width: 350px;
764
- border-right: 1px solid #ab4a10;
765
- }
766
- .popup-close,
767
- .sidebar-hide-btn,
768
- .sidebar-show-btn {
769
- width: 59px;
770
- height: 59px;
771
- position: absolute;
772
- top: 0;
773
- cursor: pointer;
774
- font-size: 34px;
775
- line-height: 60px;
776
- text-align: center;
777
- color: #FFF;
778
- &:hover {
779
- background: #b34c10;
780
- }
781
- }
782
- .sidebar-hide-btn {
783
- left: 0;
784
- }
785
- .sidebar-show-btn {
786
- position: relative;
787
- margin-left: -20px;
788
- margin-right: 20px;
789
- }
790
- .popup-close {
791
- right: 0px;
792
- &:before,
793
- &:after {
794
- content: '';
795
- border-top: 3px solid #FFF;
796
- width: 30px;
797
- display: inline-block;
798
- position: absolute;
799
- top: 29px;
800
- left: 17px;
801
- }
802
- &:before {
803
- -webkit-transform: rotate(45deg);
804
- }
805
- &:after {
806
- -webkit-transform: rotate(-45deg);
807
- }
808
- &:hover {
809
- background: #b34c10;
810
- &:before, &:after {
811
- border-color: #FFF;
812
- }
813
- }
814
- }
815
- .popup-title {
816
- margin: 0 0 0 350px;
817
- height: 60px;
818
- line-height: 60px;
819
- padding: 0 20px;
820
- color: #FFF;
821
- position: relative;
822
- }
823
-
824
- }
825
- #popup-content {
826
- position: absolute;
827
- top: 60px;
828
- bottom: 50px;
829
- left: 0;
830
- right: 0;
831
- overflow: auto;
832
- transition: top linear 0.25s, bottom linear 0.25s;
833
-
834
- #popup-content-inner {
835
- margin: 20px 40px;
836
- }
837
- }
838
- #popup-footer {
839
- position: absolute;
840
- bottom: 0;
841
- left: 0;
842
- right: 0;
843
- height: 50px;
844
- background: #F5F5F5;
845
- border-top: 1px solid #DDD;
846
- .footer-control {
847
- display: block;
848
- height: 50px;
849
- line-height: 50px;
850
- padding: 0 20px;
851
- background: #FFF;
852
- &.prev-item {
853
- float: left;
854
- }
855
- &.next-item {
856
- float: right;
857
- }
858
- }
859
- }
860
- #popup-header, #popup-footer {
861
- transition: opacity linear 0.25s;
862
- }
863
- &.expand {
864
- position: fixed;
865
- left: 0;
866
- padding: 0 20%;
867
- top: 0;
868
- bottom: 0;
869
- #popup-header,
870
- #popup-footer {
871
- opacity: 0;
872
- }
873
- #popup-content {
874
- top: 0;
875
- bottom: 0;
876
- }
877
- }
878
- }
879
- iframe {
880
- position: absolute;
881
- top: 0;
882
- left: 0;
883
- height: 100%;
884
- width: 100%;
885
- border: none;
886
- margin: 0;
887
- background: #FFF;
888
- }
889
- }
890
-
891
- .learn-press-content-item-title {
892
- margin-bottom: 20px;
893
- border-bottom: 2px solid #DDD;
894
- padding-bottom: 20px;
895
- &.content-item-quiz-title {
896
- h4 {
897
- float: left;
898
- font-size: 24px;
899
- margin-bottom: 0;
900
- }
901
- .quiz-countdown {
902
- float: right;
903
- position: relative;
904
- min-width: 100px;
905
- background: #F5F5F5;
906
- text-align: center;
907
- font-size: 18px;
908
- &:after, &:before {
909
- padding: 0 10px;
910
- height: 3px;
911
- position: absolute;
912
- bottom: -3px;
913
- background: #000;
914
- content: '';
915
- left: 0;
916
- }
917
- &:before {
918
- width: 100%;
919
- }
920
- &:after {
921
- background: #00adff;
922
- padding: 0;
923
- }
924
- &.warning-time-over {
925
- &:after {
926
- background: #FF0000;
927
- }
928
- }
929
- .countdown {
930
-
931
- }
932
- }
933
- .clearfix();
934
- }
935
- .lp-expand {
936
- float: right;
937
- width: 43px;
938
- height: 43px;
939
- line-height: 43px;
940
- background: #F5F5F5;
941
- margin: 0 10px;
942
- border: 1px solid #DDD;
943
- outline: none;
944
- }
945
- }
946
-
947
- .learn-press-content-item-summary {
948
- /*padding: 20px;
949
- border-top: 1px solid #DDD;*/
950
- margin-bottom: 30px;
951
- .quiz-question-title {
952
- margin-bottom: 20px;
953
- }
954
- .learn-press-question-explanation, .learn-press-question-hint {
955
- background: #F5F5F5;
956
- padding: 15px 20px;
957
- font-style: italic;
958
- margin-bottom: 20px;
959
- .hint-title, .explanation-title {
960
- font-style: normal;
961
- }
962
- }
963
- }
964
-
965
- .button-finish-quiz {
966
- float: right;
967
- }
968
-
969
- .learnpress form.purchase-course {
970
- margin-bottom: 20px;
971
- }
972
-
973
- #learn-press-block-content {
974
- display: none;
975
- width: 100%;
976
- height: 100%;
977
- background: fade(#FFF, 25%);
978
- position: fixed;
979
- z-index: 99999999;
980
- top: 0;
981
- left: 0;
982
- &:before, &:after, span {
983
- position: absolute;
984
- .border-radius(50%);
985
- left: 50%;
986
- top: 50%;
987
- box-sizing: border-box;
988
- }
989
- &:before {
990
- content: '';
991
- border: 2px solid #000;
992
- z-index: 10;
993
- .animation(spin-13 1.5s infinite);
994
- }
995
- &:after {
996
- z-index: 0;
997
- content: '';
998
- border: 10px solid #000000;
999
- margin-left: -80px;
1000
- margin-top: -80px;
1001
- width: 160px;
1002
- height: 160px;
1003
- opacity: 0;
1004
- }
1005
- span {
1006
- z-index: 20;
1007
- .animation(spin-12 1.5s infinite);
1008
- &:before {
1009
- content: '';
1010
- border: 6px solid #95e6f9;
1011
- position: absolute;
1012
- .border-radius(50%);
1013
- box-sizing: border-box;
1014
- }
1015
- }
1016
-
1017
- .learn-press-block-content-mixin(80px);
1018
- }
1019
-
1020
- body.block-content {
1021
- #learn-press-block-content {
1022
- display: block;
1023
- }
1024
- }
1025
-
1026
- /* COURSE QUIZ */
1027
- //.single-quiz {
1028
- .quiz-buttons {
1029
- margin-bottom: 20px;
1030
- clear: both;
1031
- }
1032
-
1033
- .quiz-intro {
1034
- list-style: none;
1035
- padding: 0;
1036
- }
1037
-
1038
- .quiz-questions-list {
1039
- margin: 0 0 20px 0;
1040
- padding: 0;
1041
- list-style-position: inside;
1042
- li {
1043
- margin: 0 0 10px 0;
1044
- }
1045
- .question-title {
1046
- margin: 0 0 5px 0;
1047
- }
1048
- .current {
1049
- .question-title {
1050
- font-weight: bold;
1051
- }
1052
- }
1053
- }
1054
-
1055
- .quiz-description,
1056
- .question-content {
1057
- .learn-press-question-title {
1058
- margin-bottom: 20px;
1059
- }
1060
- }
1061
-
1062
- .quiz-countdown {
1063
- float: right;
1064
- position: relative;
1065
- min-width: 150px;
1066
- background: #F5F5F5;
1067
- text-align: center;
1068
- font-size: 18px;
1069
- padding: 5px 0;
1070
- }
1071
-
1072
- #quiz-countdown {
1073
- //.progress-circle(@initialize: 100%, @size: 260px, @inside-size: 200px);
1074
- .progress-circle {
1075
- overflow: hidden;
1076
- box-shadow: 0 0 3px #bdbdbd inset;
1077
- .inside {
1078
- line-height: 1;
1079
- .countdown {
1080
- font-size: 48px;
1081
- color: #087998;
1082
- _text-shadow: 1px 1px #8ee5fd;
1083
- margin-top: 110px;
1084
- }
1085
- p {
1086
- margin: 10px 0 0 0;
1087
- color: #DDD;
1088
- }
1089
- }
1090
- &:after {
1091
- background: #00b9eb;
1092
- box-shadow: 0 0 6px #097a98;
1093
- }
1094
- }
1095
- }
1096
-
1097
- #quiz-progress {
1098
- .progress-circle(@size: 200px, @background: #DDD, @fill: #FF0000, @initialize: 0%, @inside-size: 170px, @inside-background: #FFF);
1099
- }
1100
-
1101
- .quiz-result {
1102
- .quiz-result-mark {
1103
- .progress-circle();
1104
- margin-bottom: 20px;
1105
- }
1106
- .quiz-result-summary {
1107
- margin-bottom: 20px;
1108
- max-width: 500px;
1109
- .quiz-result-field {
1110
- position: relative;
1111
- background: #F5F5F5;
1112
- color: #fff;
1113
- margin: 0 0 8px 0;
1114
- font-size: 12px;
1115
- padding: 5px 10px;
1116
- .border-radius(4px);
1117
- overflow: hidden;
1118
-
1119
- span, span:after, &:before {
1120
- display: block;
1121
- position: absolute;
1122
- top: 0;
1123
- left: 0;
1124
- height: 100%;
1125
- content: attr(data-text);
1126
- color: #FFF;
1127
- white-space: nowrap;
1128
- overflow: hidden;
1129
- padding: 3px 10px;
1130
- background: transparent;
1131
- transition: width 0.5s;
1132
- }
1133
- &:before {
1134
- content: '';
1135
- padding: 0;
1136
- }
1137
- span {
1138
- padding: 0;
1139
- }
1140
- span:after {
1141
- margin: 3px 10px;
1142
- padding: 0;
1143
- width: 100%;
1144
- }
1145
- &.correct {
1146
- background: #22b4ff;
1147
- }
1148
- &.wrong {
1149
- background: #ff5425;
1150
- }
1151
- &.empty {
1152
- color: #656D6D;
1153
- }
1154
- }
1155
- }
1156
- p.quiz-result-time {
1157
- margin: 0 0 10px 0;
1158
- }
1159
- .quiz-grade {
1160
- p {
1161
- margin: 0 0 10px 0;
1162
- span {
1163
- font-weight: bold;
1164
- &.passed {
1165
- color: #22b4ff;
1166
- }
1167
- &.failed {
1168
- color: #ff5425;
1169
- }
1170
- }
1171
- }
1172
- }
1173
- }
1174
-
1175
- .element-data-percent-loop (@i) when (@i <= 100) {
1176
- .single-quiz .quiz-result-field[data-value="@{i}"]:before,
1177
- .single-quiz .quiz-result-field[data-value="@{i}"] span,
1178
- #quiz-countdown[data-value="@{i}"]:after {
1179
- width: ~"@{i}%";
1180
- }
1181
- .element-data-percent-loop(@i + 1);
1182
- }
1183
-
1184
- .element-data-percent-loop (0);
1185
-
1186
- /* QUESTION */
1187
- .learn-press-question-options {
1188
- list-style: none;
1189
- margin: 0 0 20px 0;
1190
- padding: 0;
1191
- > li.answer-option {
1192
- font-size: 16px;
1193
- background: #F5F5F5;
1194
- margin-bottom: 20px;
1195
- position: relative;
1196
- .border-radius(4px);
1197
- > label {
1198
- display: block;
1199
- input[type="checkbox"], input[type="radio"] {
1200
- border: 0;
1201
- -webkit-appearance: initial;
1202
- width: 30px;
1203
- height: 30px;
1204
- background: #fff;
1205
- border-radius: 4px;
1206
- outline: none;
1207
- position: absolute;
1208
- top: 10px;
1209
- left: 15px;
1210
- margin: 0;
1211
- &:checked:before {
1212
- content: '';
1213
- border: 4px solid #00b9eb;
1214
- display: inline-block;
1215
- width: 10px;
1216
- height: 15px;
1217
- border-top: none;
1218
- border-left: none;
1219
- position: absolute;
1220
- top: 3px;
1221
- left: 8px;
1222
- box-sizing: content-box;
1223
- .transform(rotate(36deg));
1224
- }
1225
- &:checked + p {
1226
- font-weight: bold;
1227
- background: #00b9eb;
1228
- color: #FFF;
1229
- }
1230
- }
1231
- input[type="checkbox"][disabled], input[type="radio"][disabled] {
1232
- opacity: 1;
1233
- }
1234
- input[type="radio"] {
1235
- .border-radius(50%);
1236
- }
1237
- p {
1238
- min-height: 50px;
1239
- padding: 5px 20px 5px 60px;
1240
- margin: 0;
1241
- box-sizing: border-box;
1242
- line-height: 1.5;
1243
- &.single-lines {
1244
- padding: 0 20px 0 60px;
1245
- line-height: 50px; /* middle */
1246
- }
1247
- }
1248
- }
1249
- label p {
1250
- .border-radius(4px);
1251
- }
1252
- &.answer-true label p {
1253
- background: #00b9eb;
1254
- color: #FFF;
1255
- }
1256
- &:hover label p {
1257
- background: #D4D4D4;
1258
- cursor: pointer;
1259
- }
1260
- &.user-answer-false {
1261
- background: #F5F5F5;
1262
- > label {
1263
- input[type="checkbox"] + p, input[type="radio"] + p {
1264
- text-decoration: line-through;
1265
- color: #FF0000;
1266
- background: #F5F5F5;
1267
- }
1268
- }
1269
- }
1270
- }
1271
- .answer-option-result {
1272
- label {
1273
- p {
1274
- display: inline-block;
1275
- margin: 0;
1276
- font-size: smaller;
1277
- }
1278
- input[disabled] {
1279
- opacity: 1;
1280
- }
1281
- }
1282
- }
1283
- }
1284
-
1285
- .learnpress-content {
1286
- margin-bottom: 20px;
1287
- }
1288
-
1289
- .course-meta {
1290
- margin-bottom: 20px;
1291
- .course-origin-price {
1292
- padding-right: 5px;
1293
- text-decoration: line-through;
1294
- }
1295
- .course-price {
1296
- font-weight: bold;
1297
- }
1298
-
1299
- }
1300
-
1301
- /** MESSAGE */
1302
- .learn-press-message {
1303
- background: #F5F5F5;
1304
- border-left: 5px solid #00A0D2;
1305
- padding: 10px 20px 1px 20px;
1306
- margin-bottom: 20px;
1307
- button {
1308
- float: right;
1309
- }
1310
- p {
1311
- margin-bottom: 10px;
1312
- }
1313
- &:after {
1314
- clear: both;
1315
- content: '';
1316
- display: block;
1317
- }
1318
- &.notice {
1319
- border-left-color: #b3d20a;
1320
- }
1321
- &.error {
1322
- border-left-color: #b81c23;
1323
- }
1324
- ul {
1325
- list-style-type: none;
1326
- }
1327
- }
1328
-
1329
- /**/
1330
- .learn-press-checkout-comment,
1331
- .learn-press-checkout-payment {
1332
- margin-bottom: 20px;
1333
- }
1334
-
1335
- .learn-press-checkout-payment {
1336
- .payment-methods {
1337
- list-style: none;
1338
- margin: 0;
1339
- }
1340
- }
1341
-
1342
- /* COURSE QUIZ */
1343
- .single-quiz {
1344
- .quiz-questions-list {
1345
- padding: 0;
1346
- }
1347
- .quiz-intro {
1348
- list-style: none;
1349
- padding: 10px 20px;
1350
- background: #F5F5F5;
1351
- margin: 0 0 20px 0;
1352
- }
1353
- h4 {
1354
- margin-bottom: 10px;
1355
- font-size: 18px;
1356
- }
1357
- }
1358
-
1359
- .learn-press-tooltip {
1360
- font-size: 20px;
1361
- display: inline-block;
1362
- vertical-align: middle;
1363
- background: #0f4956;
1364
- cursor: pointer;
1365
- line-height: 1;
1366
- width: 10px;
1367
- height: 10px;
1368
- border-radius: 50%;
1369
- font-weight: 700;
1370
- position: relative;
1371
- &:before {
1372
- content: "?";
1373
- font-size: 7px;
1374
- color: white;
1375
- position: absolute;
1376
- top: 2px;
1377
- left: 3px;
1378
- }
1379
- }
1380
-
1381
- .learn-press-user-profile {
1382
- .user-basic-info {
1383
- p {
1384
- margin-top: 10px;
1385
- }
1386
- }
1387
- .learn-press-tabs {
1388
- list-style: none;
1389
- margin: 30px 0 20px;
1390
- border-bottom: 1px solid #DDD;
1391
- & > li {
1392
- float: left;
1393
- list-style-type: none;
1394
- margin-bottom: -1px;
1395
- & > a {
1396
- display: inline-block;
1397
- padding: 10px 15px;
1398
- outline: none;
1399
- box-shadow: none;
1400
- color: #686868;
1401
- border-bottom: 1px solid #DDD;
1402
- }
1403
- &.current {
1404
- border-bottom: 4px solid #007acc;
1405
- a {
1406
- color: #007acc;
1407
- margin-bottom: -4px;
1408
- }
1409
- }
1410
- }
1411
- }
1412
- .learn-press-tabs-wrapper-x {
1413
- .learn-press-subtabs {
1414
- & > li {
1415
- display: inline-block;
1416
- margin-right: 10px;
1417
- &.current {
1418
- font-weight: bold;
1419
- }
1420
- }
1421
- }
1422
- .learn-press-subtab-content {
1423
- display: none;
1424
- &.current {
1425
- display: block;
1426
- }
1427
- li.course {
1428
- h3 {
1429
- padding-bottom: 10px;
1430
- }
1431
- }
1432
- .profile-courses {
1433
- list-style-type: none;
1434
- .learn-press-course-results-progress {
1435
- padding: 0 15px 15px 15px;
1436
- margin: 0;
1437
- }
1438
- }
1439
- }
1440
- button.learn-press-course-wishlist {
1441
- display: block;
1442
- }
1443
- }
1444
-
1445
- /** STYLE PROFILE **/
1446
- /* Change Picture Menu */
1447
- #lp-menu-change-picture {
1448
- list-style: none;
1449
- .lp-label-change-picture {
1450
- display: block;
1451
- color: blueviolet;
1452
- padding: 2px 10px;
1453
- border: solid 1px gray;
1454
- cursor: pointer;
1455
- }
1456
- .dropdown {
1457
- display: inline-block;
1458
- &:hover {
1459
- .dropdown-menu {
1460
- display: block;
1461
- }
1462
- }
1463
- .dropdown-menu {
1464
- display: none;
1465
- position: absolute;
1466
- list-style: none;
1467
- margin: 0 !important;
1468
- padding: 0;
1469
- background-color: #F5F5F5;
1470
- li {
1471
- display: block;
1472
- cursor: pointer;
1473
- border: solid 1px #999999;
1474
- border-bottom: none;
1475
- padding: 3px 10px;
1476
- &:hover{
1477
- color: blue;
1478
- background-color: lightblue;
1479
- }
1480
- &:last-child {
1481
- border-bottom: solid 1px #999999;
1482
- }
1483
- &.lp-menu-item-selected {
1484
- background: royalblue;
1485
- }
1486
- }
1487
- }
1488
- }
1489
- }
1490
-
1491
- #lp-profile_picture_type {
1492
- display: none;
1493
- }
1494
-
1495
- /** upload-crop box **/
1496
-
1497
- #lpbox-upload-crop-profile-picture {
1498
- display:none;
1499
- border: solid 1px gray;
1500
- padding: 10px;
1501
- max-width: 500px;
1502
- background-color: ghostwhite;
1503
- .lpbox-title {
1504
- font-size: 20px;
1505
- }
1506
- .image-editor {
1507
- width:300px;
1508
- float:left;
1509
-
1510
- .cropit-preview {
1511
- background-color: #f8f8f8;
1512
- background-size: cover;
1513
- border: 1px solid #ccc;
1514
- border-radius: 3px;
1515
- margin-top: 7px;
1516
- width: 252px;
1517
- height: 252px;
1518
- .cropit-preview-image-container {
1519
- cursor: move;
1520
- .cropit-preview-image {
1521
- max-width: none;
1522
- max-height: none;
1523
- }
1524
- }
1525
-
1526
- }
1527
- .image-editor-btn {
1528
- margin: 10px auto;
1529
- text-align: center !important;
1530
- .input {
1531
- display:inline-block !important;
1532
- }
1533
- }
1534
- .cropit-preview {
1535
- margin: 0 auto;
1536
- }
1537
- }
1538
- .image-editor-sidebar-right {
1539
- width:150px;
1540
- float:left;
1541
- a {
1542
- display:block;
1543
- text-align:center;
1544
- margin: 10px 0;
1545
- }
1546
- .dashicons {
1547
- line-height: 1.5;
1548
- margin-right:5px;
1549
- }
1550
- }
1551
- }
1552
- }
1553
-
1554
- .learn-press-pagination {
1555
- text-align: center;
1556
- ul {
1557
- list-style: disc;
1558
- & > li {
1559
- display: inline-block;
1560
- span {
1561
- display: inline-block;
1562
- padding: 0 10px;
1563
- border: 1px solid #DDD;
1564
- background-color: #F5F5F5;
1565
- }
1566
- a {
1567
- display: inline-block;
1568
- padding: 0 10px;
1569
- border: 1px solid #DDD;
1570
- background-color: #FFF;
1571
- }
1572
- }
1573
- }
1574
- }
1575
-
1576
- .learn-press-become-teacher-form {
1577
- ul {
1578
- list-style: none;
1579
- padding: 0;
1580
- li {
1581
- margin-bottom: 20px;
1582
- }
1583
- }
1584
- }
1585
-
1586
- /* jAlerts */
1587
- #popup_container {
1588
- background: #FFF;
1589
-
1590
- #popup_title {
1591
- padding: 10px 20px;
1592
- background: #18B6C7;
1593
- color: #FFF;
1594
- font-size: 18px;
1595
- margin: 0;
1596
- }
1597
-
1598
- #popup_content {
1599
- padding: 20px;
1600
- #popup_message {
1601
- margin-bottom: 20px;
1602
- }
1603
- }
1604
-
1605
- #popup_panel {
1606
- text-align: center;
1607
- }
1608
- }
1609
-
1610
- .single-lp_course {
1611
- .course-summary {
1612
- .course-students {
1613
- padding-top: 10px;
1614
- }
1615
- .course-students-list {
1616
- .students-list-title {
1617
- float: left;
1618
- }
1619
- .filter-students {
1620
- float: right;
1621
- }
1622
- }
1623
- .lp_course {
1624
- .entry-footer {
1625
- display: none;
1626
- }
1627
- }
1628
- }
1629
- .learn-press-message {
1630
- clear: both;
1631
- margin-top: 25px;
1632
- }
1633
- }
1634
-
1635
- .course-students-list {
1636
- margin-top: 10px;
1637
- margin-bottom: 15px;
1638
- .students {
1639
- clear: both;
1640
- .user-info {
1641
- margin-bottom: 15px;
1642
- }
1643
- li {
1644
- margin-right: 10px;
1645
- &.user-login {
1646
- display: block;
1647
- width: 100%;
1648
- float: left;
1649
- }
1650
- .user-info {
1651
- position: relative;
1652
- float: left;
1653
- width: 150px;
1654
- a {
1655
- position: absolute;
1656
- margin-left: 5px;
1657
- bottom: 0;
1658
- }
1659
- }
1660
- .learn-press-course-results-progress {
1661
- width: 80%;
1662
- float: left;
1663
- margin-top: -15px;
1664
- margin-bottom: 5px;
1665
- .course-progress {
1666
- width: 100%;
1667
- .lp-course-progress {
1668
- margin-top: -5px;
1669
- }
1670
- }
1671
- }
1672
- }
1673
- }
1674
- .additional-students {
1675
- clear: both;
1676
- margin-bottom: 0;
1677
- }
1678
- }
1679
-
1680
- /* tooltip */
1681
- .learn-press-tooltip-bubble {
1682
- position: absolute;
1683
- background: rgba(26, 26, 26, 0.9);
1684
- color: #ffffff;
1685
- padding: 8px 10px;
1686
- font-size: 12px;
1687
- z-index: 9999999;
1688
- line-height: 1;
1689
- border-radius: 3px;
1690
- }
1691
-
1692
- /* fill in blank */
1693
- input.blank-fill-correct {
1694
- width: auto;
1695
- }
1696
-
1697
- body.content-item-only {
1698
- background: #FFF;
1699
- opacity: 0;
1700
- .learn-press-content-item-only {
1701
- position: fixed;
1702
- z-index: 9999999;
1703
- left: 0;
1704
- top: 0;
1705
- width: 100%;
1706
- height: 100%;
1707
- background: #FFF;
1708
- overflow: auto;
1709
- padding: 20px;
1710
- margin: 0;
1711
- }
1712
-
1713
- #learn-press-content-item {
1714
- border: none;
1715
- display: block;
1716
- transition: max-width linear 0.25s;
1717
- margin: 0 auto;
1718
- max-width: 1000px;
1719
- width: 90%;
1720
- &.expand {
1721
- max-width: 1200px;
1722
- }
1723
- }
1724
- }
1725
-
1726
- .lp-group-heading-title {
1727
- &.toggle-off, &.toggle-on {
1728
- cursor: pointer;
1729
- .toggle-icon {
1730
- display: inline-block;
1731
- font-size: larger;
1732
- line-height: 1;
1733
- font-weight: bold;
1734
- margin-left: 5px;
1735
- &:before {
1736
- content: '+';
1737
- }
1738
- }
1739
- }
1740
- &.toggle-on {
1741
- .toggle-icon {
1742
- &:before {
1743
- content: '-';
1744
- }
1745
- }
1746
- }
1747
- }
1748
-
1749
- /*
1750
- .sidebar-hide-btn, .sidebar-show-btn {
1751
- cursor: pointer;
1752
- width: 60px;
1753
- height: 60px;
1754
- display: inline-block;
1755
- font-size: 34px;
1756
- line-height: 60px;
1757
- text-align: center;
1758
- color: #FFF;
1759
- position: absolute;
1760
-
1761
-
1762
- }*/
1763
-
1764
- .user-profile-edit-form {
1765
- .info-field {
1766
- margin-bottom: 20px;
1767
- }
1768
-
1769
- .description {
1770
- margin-top: 5px;
1771
- }
1772
-
1773
- .user-profile-picture {
1774
- clear: both;
1775
- .picture, .change-picture {
1776
- display: inline-block;
1777
- }
1778
- .change-picture {
1779
- .description {
1780
- margin: 0 0 10px 0;
1781
- }
1782
- }
1783
- img {
1784
- float: left;
1785
- margin-right: 20px;
1786
- }
1787
- &:after {
1788
- .clearfix();
1789
- }
1790
- }
1791
-
1792
- .profile-field-name {
1793
- font-weight: bold;
1794
- margin-bottom: 10px;
1795
- }
1796
-
1797
- .change-password {
1798
- margin-bottom: 10px;
1799
- }
1800
-
1801
- #user_profile_password_form {
1802
- input {
1803
- margin-bottom: 20px;
1804
- }
1805
- .description {
1806
- margin-top: -15px;
1807
- }
1808
- }
1809
-
1810
- .update-profile {
1811
- margin-top: 20px;
1812
- }
1813
- }
1814
-
1815
- .payment-method-form {
1816
- &.payment_method_authorizenet {
1817
- background: #f7f7f7;
1818
- border-radius: 5px;
1819
- -webkit-border-radius: 5px;
1820
- -moz-border-radius: 5px;
1821
- padding-top: 25px;
1822
- .row-fluid {
1823
- clear: both;
1824
- padding-bottom: 25px;
1825
- .span6 {
1826
- &:first-child {
1827
- width: 50%;
1828
- float: left;
1829
- label {
1830
- margin-left: 17px;
1831
- }
1832
- select, input {
1833
- margin-left: 10px;
1834
- }
1835
- }
1836
- select, input {
1837
- padding: 8px 0;
1838
- }
1839
- select.required {
1840
- color: #000;
1841
- }
1842
- }
1843
- }
1844
- }
1845
- }
1846
-
1847
- .place-order-action {
1848
- margin-top: 20px;
1849
- }
1850
-
1851
- .woocommerce {
1852
- form .form-row {
1853
- &.validate-email, &.validate-phone {
1854
- width: 100% !important;
1855
- }
1856
- }
1857
-
1858
- .checkout_coupon {
1859
- .form-row-last {
1860
- input.button {
1861
- padding: 13px 10px !important;
1862
- }
1863
- }
1864
- }
1865
- }
1866
-
1867
- .learn-press-search-course-form {
1868
- margin-bottom: 20px;
1869
- input.search-course-input[name="s"] {
1870
- margin-right: -200px;
1871
- width: 100%;
1872
- }
1873
- .search-course-button {
1874
- vertical-align: middle;
1875
- float: right;
1876
- z-index: 10;
1877
- position: relative;
1878
- }
1879
- }
1880
-
1881
- /* Shortcode/Widgets */
1882
- .recent-courses-widget, .popular-courses-widget, .featured-courses-widget {
1883
- .course-meta-data {
1884
- > div {
1885
- display: inline-block;
1886
- &:after {
1887
- content: '/';
1888
- }
1889
- &:last-child:after {
1890
- content: '';
1891
- }
1892
- }
1893
-
1894
- }
1895
- .course-title {
1896
- margin: 5px 0;
1897
- }
1898
- .course-entry {
1899
- margin-bottom: 20px;
1900
- }
1901
- }
1902
-
1903
- @-moz-keyframes spin-12 {
1904
- 0% {
1905
- -moz-transform: rotate(0deg) translate(0px);
1906
- }
1907
- 100% {
1908
- -moz-transform: rotate(360deg) translate(0px);
1909
- }
1910
- }
1911
-
1912
- @-webkit-keyframes spin-12 {
1913
- 0% {
1914
- -webkit-transform: rotate(0deg) translate(0px);
1915
- }
1916
- 100% {
1917
- -webkit-transform: rotate(360deg) translate(0px);
1918
- }
1919
- }
1920
-
1921
- @keyframes spin-12 {
1922
- 0% {
1923
- -webkit-transform: rotate(0deg) translate(0px);
1924
- transform: rotate(0deg) translate(0px);
1925
- }
1926
- 100% {
1927
- -webkit-transform: rotate(360deg) translate(0px);
1928
- transform: rotate(360deg) translate(0px);
1929
- }
1930
- }
1931
-
1932
- @-moz-keyframes spin-13 {
1933
- 100% {
1934
- -moz-transform: rotate(0deg) translate(0px);
1935
- }
1936
- 0% {
1937
- -moz-transform: rotate(360deg) translate(0px);
1938
- }
1939
- }
1940
-
1941
- @-webkit-keyframes spin-13 {
1942
- 0% {
1943
- -webkit-transform: rotate(0deg) translate(0px);
1944
- }
1945
- 100% {
1946
- -webkit-transform: rotate(360deg) translate(0px);
1947
- }
1948
- }
1949
-
1950
- @keyframes spin-13 {
1951
- 100% {
1952
- -webkit-transform: rotate(0deg) translate(0px);
1953
- transform: rotate(0deg) translate(0px);
1954
- }
1955
- 0% {
1956
- -webkit-transform: rotate(360deg) translate(0px);
1957
- transform: rotate(360deg) translate(0px);
1958
- }
1959
- }
1960
-
1961
- @media screen and (max-width: 1250px) {
1962
- .single-lp_course .learn-press-course-results-progress {
1963
- .items-progress, .course-progress {
1964
- float: none;
1965
- width: 100%;
1966
- }
1967
- .items-progress {
1968
- margin-bottom: 50px;
1969
- }
1970
- }
1971
- }
1972
-
1973
- @media screen and (max-width: 768px) {
1974
- #learn-press-block-content {
1975
- .learn-press-block-content-mixin(60px);
1976
- }
1977
-
1978
- .learn-press-course-results-progress {
1979
- .items-progress, .course-progress {
1980
- width: 100%;
1981
- margin-right: 0;
1982
- }
1983
- }
1984
-
1985
- }
1986
-
1987
- @media (min-width: 992px) {
1988
- .learn-press-courses {
1989
- li.course {
1990
- &:nth-child(4n+1) {
1991
- clear: left;
1992
- }
1993
- }
1994
- }
1995
- }
1996
-
1997
- @media (max-width: 992px) {
1998
- .learn-press-courses {
1999
- margin: 0;
2000
- }
2001
- }
2002
-
2003
- @media (max-width: 992px) and (min-width: 600px ) {
2004
-
2005
- .learn-press-courses {
2006
- li.course {
2007
- width: 31.33%;
2008
- margin: 0 2% 30px 0;
2009
- /* padding: 0 20px; */
2010
- &:nth-child(3n+1) {
2011
- clear: left;
2012
- margin-left: 0;
2013
- }
2014
- }
2015
- }
2016
-
2017
- }
2018
-
2019
- @media (max-width: 600px) and (min-width: 400px ) {
2020
-
2021
- .learn-press-courses {
2022
- li.course {
2023
- width: 48%;
2024
- margin: 0 2% 30px 0;
2025
- /* padding: 0 20px; */
2026
- &:nth-child(2n+1) {
2027
- clear: left;
2028
- margin-left: 0;
2029
- }
2030
- }
2031
- }
2032
-
2033
- }
2034
-
2035
- @media (max-width: 480px) {
2036
- .woocommerce {
2037
- .checkout_coupon {
2038
- .form-row {
2039
- width: 100%;
2040
- }
2041
- }
2042
- }
2043
- }
2044
-
2045
- @media (max-width: 400px) {
2046
-
2047
- .learn-press-courses {
2048
- li.course {
2049
- width: 100%;
2050
- margin: 0 0 30px 0;
2051
- clear: left;
2052
- }
2053
- }
2054
-
2055
- }
2056
-
2057
- @media (max-width: 350px) {
2058
- #course-curriculum-popup #popup-sidebar {
2059
- width: 100%;
2060
- }
2061
- }
2062
-
2063
- /* full width with twentysixteen theme */
2064
- @media screen and (min-width: 61.5625em) {
2065
- body.single-lp_course {
2066
- article.lp_course {
2067
- .entry-content {
2068
- width: 100%;
2069
- }
2070
- .entry-footer {
2071
- display: none;
2072
- }
2073
- }
2074
- }
2075
- }
2076
-
2077
- @media screen and (max-width: 615px) {
2078
- .payment-method-form {
2079
- &.payment_method_authorizenet {
2080
- .row-fluid {
2081
- padding-bottom: 15px;
2082
- .span6 {
2083
- &:first-child {
2084
- width: 100%;
2085
- margin-bottom: 15px;
2086
- }
2087
- label {
2088
- margin-left: 17px;
2089
- }
2090
- select, input {
2091
- margin-left: 10px;
2092
- }
2093
- select, input {
2094
- padding: 8px 0;
2095
- }
2096
- select.required {
2097
- color: #000;
2098
- }
2099
- #learn-press-authorizenet-payment-expmonth {
2100
- margin-bottom: 10px;
2101
- }
2102
- }
2103
- }
2104
- }
2105
- }
2106
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @icon-url: '../fonts/lp-icons';
2
+ @font-face {
3
+ font-family: 'lp-icons';
4
+ src: url('@{icon-url}.eot?f41nl');
5
+ src: url('@{icon-url}.eot?f41nl#iefix') format('embedded-opentype'),
6
+ url('@{icon-url}.ttf?f41nl') format('truetype'),
7
+ url('@{icon-url}.woff?f41nl') format('woff'),
8
+ url('@{icon-url}.svg?f41nl#lp-icons') format('svg');
9
+ font-weight: normal;
10
+ font-style: normal;
11
+ }
12
+
13
+ [class^="lp-icon-"], [class*=" lp-icon-"] {
14
+ /* use !important to prevent issues with browser extensions that change fonts */
15
+ font-family: 'lp-icons' !important;
16
+ speak: none;
17
+ font-style: normal;
18
+ font-weight: normal;
19
+ font-variant: normal;
20
+ text-transform: none;
21
+ line-height: 1;
22
+
23
+ /* Better Font Rendering =========== */
24
+ -webkit-font-smoothing: antialiased;
25
+ -moz-osx-font-smoothing: grayscale;
26
+ }
27
+
28
+ .lp-icon-file-text2:before {
29
+ content: "\e926";
30
+ }
31
+
32
+ .lp-icon-file-picture:before {
33
+ content: "\e927";
34
+ }
35
+
36
+ .lp-icon-file-music:before {
37
+ content: "\e928";
38
+ }
39
+
40
+ .lp-icon-file-video:before {
41
+ content: "\e92a";
42
+ }
43
+
44
+ .lp-icon-file-zip:before {
45
+ content: "\e92b";
46
+ }
47
+
48
+ .lp-icon-paste:before {
49
+ content: "\e92d";
50
+ }
51
+
52
+ .lp-icon-alarm:before {
53
+ content: "\e950";
54
+ }
55
+
56
+ .lp-icon-cross:before {
57
+ content: "\ea0f";
58
+ }
59
+
60
+ .lp-icon-checkmark:before {
61
+ content: "\ea10";
62
+ }
63
+
64
+ .lp-icon-spinner2:before {
65
+ content: "\e97b";
66
+ }
67
+
68
+ .lp-icon-plus:before {
69
+ content: "\ea0a";
70
+ }
71
+
72
+ .lp-icon-minus:before {
73
+ content: "\ea0b";
74
+ }
75
+
76
+ .clearfix() {
77
+ display: block;
78
+ content: '';
79
+ clear: both;
80
+ }
81
+
82
+ .clearfix:after {
83
+ display: block;
84
+ content: '';
85
+ clear: both;
86
+ }
87
+
88
+ .border-radius(@args) {
89
+ -webkit-border-radius: @arguments;
90
+ -khtml-border-radius: @arguments;
91
+ -moz-border-radius: @arguments;
92
+ -ms-border-radius: @arguments;
93
+ -o-border-radius: @arguments;
94
+ border-radius: @arguments;
95
+ }
96
+
97
+ .transform(@args) {
98
+ -webkit-transform: @arguments;
99
+ -khtml-transform: @arguments;
100
+ -moz-transform: @arguments;
101
+ -ms-transform: @arguments;
102
+ -o-transform: @arguments;
103
+ transform: @arguments;
104
+ }
105
+
106
+ .transition(@args) {
107
+ -webkit-transition: @arguments;
108
+ -khtml-transition: @arguments;
109
+ -moz-transition: @arguments;
110
+ -ms-transition: @arguments;
111
+ -o-transition: @arguments;
112
+ transition: @arguments;
113
+ }
114
+
115
+ .cross(@size: 30px, @border: 3px, @color: #000) {
116
+ &:before,
117
+ &:after {
118
+ width: @border;
119
+ background: @color;
120
+ height: @size;
121
+ content: '';
122
+ display: inline-block;
123
+ position: absolute;
124
+ top: 0;
125
+ left: (@size - @border) / 2;
126
+ }
127
+ &:before {
128
+ .transform(rotate(-45deg));
129
+ }
130
+ &:after {
131
+ .transform(rotate(45deg));
132
+ }
133
+ }
134
+
135
+ .animation(@args) {
136
+ -webkit-animation: @arguments;
137
+ -moz-animation: @arguments;
138
+ animation: @arguments;
139
+ }
140
+
141
+ .overlay-processing {
142
+ &:before, &:after {
143
+ content: '';
144
+ display: block;
145
+ position: fixed;
146
+ top: 0;
147
+ left: 0;
148
+ width: 100%;
149
+ height: 100%;
150
+ z-index: 999999;
151
+ }
152
+ &:before {
153
+ background: #000;
154
+ opacity: 0.5;
155
+ }
156
+ &:after {
157
+ background: #FFF;
158
+ }
159
+ }
160
+
161
+ /* PROGRESS CIRCLE */
162
+ .progress-circle(@size: 200px, @background: #DDD, @fill: #95e6f9, @initialize: 0, @inside-size: 170px, @inside-background: #FFF) {
163
+ .progress-circle {
164
+ width: @size;
165
+ height: @size;
166
+ border-radius: 50%;
167
+ background-color: @background;
168
+ position: relative;
169
+ .background {
170
+ content: "";
171
+ position: absolute;
172
+ border-radius: 50%;
173
+ width: @size;
174
+ height: @size;
175
+ clip: rect(0, @size, @size, @size / 2);
176
+ .fill {
177
+ content: "";
178
+ position: absolute;
179
+ border-radius: 50%;
180
+ width: @size;
181
+ height: @size;
182
+ clip: rect(0, @size / 2, @size, 0);
183
+ background: @fill;
184
+ transform: rotate(unit(@initialize*3.6, deg));
185
+ }
186
+ }
187
+ &:after {
188
+ content: '';
189
+ width: @inside-size;
190
+ height: @inside-size;
191
+ background: @inside-background;
192
+ .border-radius(50%);
193
+ position: absolute;
194
+ top: 50%;
195
+ left: 50%;
196
+ margin-top: -@inside-size / 2;
197
+ margin-left: -@inside-size / 2;
198
+ pointer-events: none;
199
+ }
200
+ .inside {
201
+ position: absolute;
202
+ width: 100%;
203
+ height: 100%;
204
+ line-height: @size;
205
+ text-align: center;
206
+ z-index: 10;
207
+ }
208
+ &.gt-50 {
209
+ background-color: @fill;
210
+ .background {
211
+ clip: rect(0, @size/2, @size, 0);
212
+ }
213
+ .fill {
214
+ clip: rect(0, @size, @size, @size/2);
215
+ background: @background;
216
+ }
217
+ }
218
+ }
219
+ }
220
+
221
+ .clearfix() {
222
+ &:after {
223
+ content: '';
224
+ display: block;
225
+ clear: both;
226
+ }
227
+ }
228
+
229
+ .hide-if-js {
230
+ display: none !important;
231
+ }
232
+
233
+ /* Archive courses */
234
+ .learn-press-courses {
235
+ list-style: none;
236
+ clear: both;
237
+ margin: 0 -30px 0 0;
238
+ padding: 0;
239
+ &:after {
240
+ display: block;
241
+ content: '';
242
+ clear: both;
243
+ }
244
+ li.course {
245
+ list-style-type: none;
246
+ float: left;
247
+ width: 23%;
248
+ margin: 0 2% 30px 0;
249
+ padding: 0;
250
+ box-sizing: border-box;
251
+ border: 1px solid #DDD;
252
+ background: #FFF;
253
+
254
+ .view-more {
255
+ padding: 0 15px;
256
+ text-decoration: none;
257
+ box-shadow: none;
258
+ }
259
+
260
+ h3 {
261
+ padding: 15px;
262
+ margin: 0;
263
+ font-size: 18px;
264
+ line-height: 1.5;
265
+ }
266
+ .course-thumbnail {
267
+ position: relative;
268
+ img {
269
+ max-width: 100%;
270
+ height: auto;
271
+ }
272
+ &:after {
273
+ content: '';
274
+ position: absolute;
275
+ width: 100%;
276
+ height: 100%;
277
+ left: 0;
278
+ top: 0;
279
+ }
280
+ }
281
+ .course-info {
282
+ padding: 0 15px 15px;
283
+ font-size: 14px;
284
+ overflow: hidden;
285
+ }
286
+ .course-students {
287
+ float: left;
288
+ }
289
+ .course-instructor {
290
+ margin-bottom: 20px;
291
+ }
292
+ .course-origin-price {
293
+ float: right;
294
+ text-decoration: line-through;
295
+ padding-right: 5px;
296
+ }
297
+ .course-price {
298
+ float: right;
299
+ color: rgb(84, 181, 81);
300
+ }
301
+ .course-info > * {
302
+ display: block;
303
+ }
304
+ }
305
+ }
306
+
307
+ .learn-press-notice .button {
308
+ float: right;
309
+ }
310
+
311
+ .learn-press-form {
312
+ margin-bottom: 20px;
313
+ }
314
+
315
+ //
316
+
317
+ #learn-press-course-curriculum {
318
+ ul.curriculum-sections,
319
+ ul.section-content {
320
+ list-style: none;
321
+ margin: 0;
322
+ padding: 0;
323
+ background-color: #F5F5F5;
324
+ li.section {
325
+ list-style-type: none;
326
+ }
327
+ }
328
+ .section-header {
329
+ background-color: #EEE;
330
+ margin: 0;
331
+ padding: 20px 15px;
332
+ border-top: 1px solid #FFF;
333
+ position: relative;
334
+ p {
335
+ display: inline-block;
336
+ font-weight: normal;
337
+ font-style: italic;
338
+ color: rgb(153, 153, 153);
339
+ font-size: 14px;
340
+ margin: 0;
341
+ padding: 10px 0;
342
+ text-transform: none;
343
+ }
344
+ &:hover {
345
+ background: #DDD;
346
+ }
347
+ .meta {
348
+ font-size: smaller;
349
+ font-weight: normal;
350
+ position: absolute;
351
+ right: 15px;
352
+ top: 20px;
353
+ .collapse {
354
+ display: inline-block;
355
+ position: relative;
356
+ font-family: 'lp-icons';
357
+ background: #95e6f9;
358
+ width: 24px;
359
+ height: 24px;
360
+ line-height: 24px;
361
+ text-align: center;
362
+ color: #FFF;
363
+ border-radius: 5px;
364
+ vertical-align: middle;
365
+ margin-left: 5px;
366
+ &:before {
367
+ content: "\ea0b";
368
+ margin: 0 auto;
369
+ }
370
+ &:hover {
371
+ cursor: pointer;
372
+ }
373
+ &.plus {
374
+ &:before {
375
+ content: "\ea0a";
376
+ }
377
+ }
378
+ }
379
+ }
380
+ }
381
+ .course-item {
382
+ margin: 0;
383
+ list-style: none;
384
+ padding: 10px 15px;
385
+ border-top: 1px solid rgb(255, 255, 255);
386
+ position: relative;
387
+ .transition(background linear 0.5s);
388
+ .lp-label-viewing,
389
+ .lp-label-completed {
390
+ display: none;
391
+ }
392
+ .course-item-title {
393
+ display: block;
394
+ box-shadow: none;
395
+ text-align: justify;
396
+ float: left;
397
+ &:before {
398
+ display: inline-block;
399
+ font-size: 16px;
400
+ margin-right: 10px;
401
+ font-family: 'lp-icons';
402
+ }
403
+ }
404
+ .lp-icon {
405
+ display: none;
406
+ }
407
+ &.viewable {
408
+ cursor: pointer;
409
+ &:hover {
410
+ background: #e7ecfb;
411
+ .transition(background linear 0s);
412
+ }
413
+ }
414
+ &.course-lesson {
415
+ .course-item-title {
416
+ &:before {
417
+ content: '\e926';
418
+ }
419
+ }
420
+ }
421
+ &.course-quiz {
422
+ .course-item-title {
423
+ &:before {
424
+ content: '\e950';
425
+ }
426
+ }
427
+ }
428
+ &.item-current {
429
+ background: #FFF;
430
+ &:before {
431
+ display: block;
432
+ width: 3px;
433
+ background: #95e6f9;
434
+ position: absolute;
435
+ left: 0;
436
+ top: 0;
437
+ height: 100%;
438
+ content: '';
439
+ }
440
+ }
441
+ &.item-has-status .item-status {
442
+ display: inline-block;
443
+ background: #d6d6d6;
444
+ margin-left: 5px;
445
+ &:before {
446
+ content: '\ea10';
447
+ color: #FFF;
448
+ }
449
+ }
450
+ &.item-has-status.item-completed {
451
+ .item-status {
452
+ background: #95e6f9;
453
+ }
454
+ }
455
+ &.focus {
456
+ background: #ffb710;
457
+ &.off {
458
+ .transition(none);
459
+ }
460
+ }
461
+ &:after {
462
+ display: block;
463
+ clear: both;
464
+ content: '';
465
+ }
466
+ }
467
+
468
+ .course-item-meta {
469
+ display: block;
470
+ line-height: 1;
471
+ __position: absolute;
472
+ top: 15px;
473
+ right: 15px;
474
+ float: right;
475
+ margin-top: 5px;
476
+ }
477
+ }
478
+
479
+ .lp-icon {
480
+ display: inline-block;
481
+ font-family: 'lp-icons';
482
+ background: #95e6f9;
483
+ width: 24px;
484
+ height: 24px;
485
+ line-height: 24px;
486
+ text-align: center;
487
+ color: #FFF;
488
+ border-radius: 5px;
489
+ vertical-align: middle;
490
+ &:before {
491
+ width: 32px;
492
+ height: 32px;
493
+ }
494
+
495
+ }
496
+
497
+ .lp-label {
498
+ display: inline-block;
499
+ line-height: 24px;
500
+ font-size: 78%;
501
+ vertical-align: middle;
502
+ color: #ffffff;
503
+ padding: 0 10px;
504
+ background: #DDD;
505
+ height: 24px;
506
+ .border-radius(4px);
507
+ &.lp-label-viewing {
508
+ background-color: rgb(57, 175, 255);
509
+ }
510
+ &.lp-label-completed {
511
+ background-color: #39c7ce;
512
+ }
513
+ &.lp-label-lesson {
514
+ background-color: #337ab7;
515
+ }
516
+ &.lp-label-quiz {
517
+ background-color: #53658c;
518
+ }
519
+ &.lp-label-preview {
520
+ background-color: #02a7ce;
521
+ }
522
+ }
523
+
524
+ .learn-press-content-protected-message {
525
+ border: 3px solid #ff8484;
526
+ background: #FFF;
527
+ padding: 20px;
528
+ color: #ff8484;
529
+ margin: 10px 0;
530
+ border-radius: 6px;
531
+ .icon {
532
+ position: relative;
533
+ display: inline-block;
534
+ width: 30px;
535
+ height: 30px;
536
+ margin-right: 10px;
537
+ vertical-align: middle;
538
+ .cross(30px, 3px, #ff8484);
539
+ }
540
+ }
541
+
542
+ /** BREADCRUMB */
543
+ .learn-press-breadcrumb {
544
+ margin-bottom: 20px;
545
+ }
546
+
547
+ /** COURSE PROGRESS **/
548
+ .single-lp_course {
549
+ .learn-press-course-results-progress {
550
+ margin-bottom: 40px;
551
+ .items-progress {
552
+ float: left;
553
+ width: 68%;
554
+ margin-right: 2%;
555
+ clear: left;
556
+ }
557
+ .lp-course-progress-heading {
558
+ margin-bottom: 10px;
559
+ }
560
+ .course-progress {
561
+ float: left;
562
+ width: 30%;
563
+ }
564
+ .number, .percentage-sign {
565
+ display: inline-block;
566
+ vertical-align: bottom;
567
+ line-height: 1;
568
+ font-size: 25px;
569
+ }
570
+ .percentage-sign {
571
+ margin-left: 5px;
572
+ }
573
+ &:after {
574
+ display: block;
575
+ content: '';
576
+ clear: both;
577
+ }
578
+ }
579
+ }
580
+
581
+ .lp-course-progress {
582
+ position: relative;
583
+ .lp-progress-bar {
584
+ height: 15px;
585
+ background: #DDD;
586
+ margin: 10px 0 15px 0;
587
+ overflow: hidden;
588
+ .border-radius(3px);
589
+ .lp-progress-value {
590
+ width: 50%;
591
+ height: 15px;
592
+ background: #95e6f9;
593
+ }
594
+ }
595
+ .lp-passing-conditional {
596
+ left: 0%;
597
+ position: absolute;
598
+ height: 25px;
599
+ top: -5px;
600
+ margin-left: -5px;
601
+ cursor: pointer;
602
+ &:before,
603
+ &:after {
604
+ content: '';
605
+ display: inline-block;
606
+ border: 5px solid transparent;
607
+ left: 0;
608
+ position: absolute;
609
+ }
610
+ &:before {
611
+ border-top-color: #DDD;
612
+ }
613
+ &:after {
614
+ border-bottom-color: #DDD;
615
+ bottom: 0;
616
+ }
617
+ }
618
+ }
619
+
620
+ #learn-press-content-item {
621
+ border: 1px solid #DDD;
622
+ display: none;
623
+
624
+ }
625
+
626
+ /** COURSE TABS **/
627
+ .learn-press-tabs {
628
+ .learn-press-nav-tabs {
629
+ list-style: none;
630
+ padding: 0;
631
+ margin: 0 0 20px 0;
632
+ border-bottom: 1px solid #DDD;
633
+ .learn-press-nav-tab {
634
+ list-style-type: none;
635
+ float: left;
636
+ margin-bottom: -1px;
637
+ position: relative;
638
+ a {
639
+ display: inline-block;
640
+ padding: 10px 15px;
641
+ outline: none;
642
+ box-shadow: none;
643
+ color: #686868;
644
+ border-bottom: 1px solid #DDD;
645
+ }
646
+ &.active {
647
+ border-bottom: 4px solid #007acc;
648
+ a {
649
+ color: #007acc;
650
+ border-bottom: none;
651
+ margin-bottom: -4px;
652
+ }
653
+ }
654
+ &.active:after {
655
+ position: absolute;
656
+ width: 100%;
657
+ border-bottom: 1px solid #FFF;
658
+ bottom: -1px;
659
+ content: '';
660
+ }
661
+ }
662
+ &:hover {
663
+
664
+ }
665
+ &:after {
666
+ content: '';
667
+ display: block;
668
+ clear: both;
669
+ }
670
+ }
671
+ .learn-press-tab-panel {
672
+ display: none;
673
+ margin-bottom: 20px;
674
+ &.active {
675
+ display: block;
676
+ }
677
+ }
678
+ }
679
+
680
+ .learn-press-block-content-mixin(@w) {
681
+ &:before {
682
+ width: (@w);
683
+ height: (@w);
684
+ margin-left: -(@w/2);
685
+ margin-top: -(@w/2); /*-76px;*/
686
+ -webkit-clip-path: polygon(0px @w, @w @w, @w @w/2, @w/2 @w/2, @w/2 0, 0 0);
687
+ }
688
+
689
+ span {
690
+ clip: rect(0, @w+4, @w/2+2, @w/2+2);
691
+ width: @w+4;
692
+ height: @w+4;
693
+ margin-left: -(@w/2+2);
694
+ margin-top: -(@w/2+2);
695
+ &:before {
696
+ width: @w+4;
697
+ height: @w+4;
698
+ }
699
+ }
700
+ }
701
+
702
+ /* POPUP */
703
+
704
+ #popup_overlay {
705
+ z-index: 10000000 !important;
706
+ }
707
+
708
+ #popup_container {
709
+ z-index: 10000001 !important;
710
+ }
711
+
712
+ body.course-has-popup {
713
+ overflow: hidden;
714
+ }
715
+
716
+ #course-curriculum-popup {
717
+ position: fixed;
718
+ top: 0;
719
+ left: 0;
720
+ right: 0;
721
+ bottom: 0;
722
+ background: #000;
723
+ z-index: 999999;
724
+ * {
725
+ box-sizing: border-box;
726
+ }
727
+ #popup-sidebar {
728
+ float: left;
729
+ width: 350px;
730
+ position: absolute;
731
+ top: 60px;
732
+ bottom: 0;
733
+ overflow: auto;
734
+ background: #FFF;
735
+ border-right: 1px solid #DDD;
736
+ .course-curriculum-title {
737
+ display: none;
738
+ }
739
+ .curriculum-sections {
740
+ margin: 0;
741
+ font-size: smaller;
742
+ }
743
+ .learn-press-course-results-progress {
744
+ padding: 15px 20px;
745
+ margin-bottom: 0;
746
+ .items-progress, .course-progress {
747
+ width: 100%;
748
+ margin: 0 !important;
749
+ }
750
+ }
751
+ }
752
+ #popup-main {
753
+ position: absolute;
754
+ top: 0;
755
+ left: 350px;
756
+ right: 0;
757
+ bottom: 0;
758
+ background: #FFF;
759
+ #popup-header {
760
+ position: absolute;
761
+ top: 0;
762
+ left: -350px;
763
+ right: 0;
764
+ height: 60px;
765
+ background: #cc540d;
766
+ border-bottom: 1px solid #ab4a10;
767
+ .popup-menu {
768
+ position: absolute;
769
+ height: 60px;
770
+ width: 350px;
771
+ border-right: 1px solid #ab4a10;
772
+ }
773
+ .popup-close,
774
+ .sidebar-hide-btn,
775
+ .sidebar-show-btn {
776
+ width: 59px;
777
+ height: 59px;
778
+ position: absolute;
779
+ top: 0;
780
+ cursor: pointer;
781
+ font-size: 34px;
782
+ line-height: 60px;
783
+ text-align: center;
784
+ color: #FFF;
785
+ &:hover {
786
+ background: #b34c10;
787
+ }
788
+ }
789
+ .sidebar-hide-btn {
790
+ left: 0;
791
+ }
792
+ .sidebar-show-btn {
793
+ position: relative;
794
+ margin-left: -20px;
795
+ margin-right: 20px;
796
+ }
797
+ .popup-close {
798
+ right: 0px;
799
+ &:before,
800
+ &:after {
801
+ content: '';
802
+ border-top: 3px solid #FFF;
803
+ width: 30px;
804
+ display: inline-block;
805
+ position: absolute;
806
+ top: 29px;
807
+ left: 17px;
808
+ }
809
+ &:before {
810
+ -webkit-transform: rotate(45deg);
811
+ }
812
+ &:after {
813
+ -webkit-transform: rotate(-45deg);
814
+ }
815
+ &:hover {
816
+ background: #b34c10;
817
+ &:before, &:after {
818
+ border-color: #FFF;
819
+ }
820
+ }
821
+ }
822
+ .popup-title {
823
+ margin: 0 0 0 350px;
824
+ height: 60px;
825
+ line-height: 60px;
826
+ padding: 0 20px;
827
+ color: #FFF;
828
+ position: relative;
829
+ }
830
+
831
+ }
832
+ #popup-content {
833
+ position: absolute;
834
+ top: 60px;
835
+ bottom: 50px;
836
+ left: 0;
837
+ right: 0;
838
+ overflow: auto;
839
+ transition: top linear 0.25s, bottom linear 0.25s;
840
+
841
+ #popup-content-inner {
842
+ margin: 20px 40px;
843
+ }
844
+ }
845
+ #popup-footer {
846
+ position: absolute;
847
+ bottom: 0;
848
+ left: 0;
849
+ right: 0;
850
+ height: 50px;
851
+ background: #F5F5F5;
852
+ border-top: 1px solid #DDD;
853
+ .footer-control {
854
+ display: block;
855
+ height: 50px;
856
+ line-height: 50px;
857
+ padding: 0 20px;
858
+ background: #FFF;
859
+ &.prev-item {
860
+ float: left;
861
+ }
862
+ &.next-item {
863
+ float: right;
864
+ }
865
+ }
866
+ }
867
+ #popup-header, #popup-footer {
868
+ transition: opacity linear 0.25s;
869
+ }
870
+ &.expand {
871
+ position: fixed;
872
+ left: 0;
873
+ padding: 0 20%;
874
+ top: 0;
875
+ bottom: 0;
876
+ #popup-header,
877
+ #popup-footer {
878
+ opacity: 0;
879
+ }
880
+ #popup-content {
881
+ top: 0;
882
+ bottom: 0;
883
+ }
884
+ }
885
+ }
886
+ iframe {
887
+ position: absolute;
888
+ top: 0;
889
+ left: 0;
890
+ height: 100%;
891
+ width: 100%;
892
+ border: none;
893
+ margin: 0;
894
+ background: #FFF;
895
+ }
896
+ }
897
+
898
+ .learn-press-content-item-title {
899
+ margin-bottom: 20px;
900
+ border-bottom: 2px solid #DDD;
901
+ padding-bottom: 20px;
902
+ &.content-item-quiz-title {
903
+ h4 {
904
+ float: left;
905
+ font-size: 24px;
906
+ margin-bottom: 0;
907
+ }
908
+ .quiz-countdown {
909
+ float: right;
910
+ position: relative;
911
+ min-width: 100px;
912
+ background: #F5F5F5;
913
+ text-align: center;
914
+ font-size: 18px;
915
+ &:after, &:before {
916
+ padding: 0 10px;
917
+ height: 3px;
918
+ position: absolute;
919
+ bottom: -3px;
920
+ background: #000;
921
+ content: '';
922
+ left: 0;
923
+ }
924
+ &:before {
925
+ width: 100%;
926
+ }
927
+ &:after {
928
+ background: #00adff;
929
+ padding: 0;
930
+ }
931
+ &.warning-time-over {
932
+ &:after {
933
+ background: #FF0000;
934
+ }
935
+ }
936
+ .countdown {
937
+
938
+ }
939
+ }
940
+ .clearfix();
941
+ }
942
+ .lp-expand {
943
+ float: right;
944
+ width: 43px;
945
+ height: 43px;
946
+ line-height: 43px;
947
+ background: #F5F5F5;
948
+ margin: 0 10px;
949
+ border: 1px solid #DDD;
950
+ outline: none;
951
+ }
952
+ }
953
+
954
+ .learn-press-content-item-summary {
955
+ /*padding: 20px;
956
+ border-top: 1px solid #DDD;*/
957
+ margin-bottom: 30px;
958
+ .quiz-question-title {
959
+ margin-bottom: 20px;
960
+ }
961
+ .learn-press-question-explanation, .learn-press-question-hint {
962
+ background: #F5F5F5;
963
+ padding: 15px 20px;
964
+ font-style: italic;
965
+ margin-bottom: 20px;
966
+ .hint-title, .explanation-title {
967
+ font-style: normal;
968
+ }
969
+ }
970
+ }
971
+
972
+ .button-finish-quiz {
973
+ float: right;
974
+ }
975
+
976
+ .learnpress form.purchase-course {
977
+ margin-bottom: 20px;
978
+ }
979
+
980
+ #learn-press-block-content {
981
+ display: none;
982
+ width: 100%;
983
+ height: 100%;
984
+ background: fade(#FFF, 25%);
985
+ position: fixed;
986
+ z-index: 99999999;
987
+ top: 0;
988
+ left: 0;
989
+ &:before, &:after, span {
990
+ position: absolute;
991
+ .border-radius(50%);
992
+ left: 50%;
993
+ top: 50%;
994
+ box-sizing: border-box;
995
+ }
996
+ &:before {
997
+ content: '';
998
+ border: 2px solid #000;
999
+ z-index: 10;
1000
+ .animation(spin-13 1.5s infinite);
1001
+ }
1002
+ &:after {
1003
+ z-index: 0;
1004
+ content: '';
1005
+ border: 10px solid #000000;
1006
+ margin-left: -80px;
1007
+ margin-top: -80px;
1008
+ width: 160px;
1009
+ height: 160px;
1010
+ opacity: 0;
1011
+ }
1012
+ span {
1013
+ z-index: 20;
1014
+ .animation(spin-12 1.5s infinite);
1015
+ &:before {
1016
+ content: '';
1017
+ border: 6px solid #95e6f9;
1018
+ position: absolute;
1019
+ .border-radius(50%);
1020
+ box-sizing: border-box;
1021
+ }
1022
+ }
1023
+
1024
+ .learn-press-block-content-mixin(80px);
1025
+ }
1026
+
1027
+ body.block-content {
1028
+ #learn-press-block-content {
1029
+ display: block;
1030
+ }
1031
+ }
1032
+
1033
+ /* COURSE QUIZ */
1034
+ //.single-quiz {
1035
+ .quiz-buttons {
1036
+ margin-bottom: 20px;
1037
+ clear: both;
1038
+ }
1039
+
1040
+ .quiz-intro {
1041
+ list-style: none;
1042
+ padding: 0;
1043
+ }
1044
+
1045
+ .quiz-questions-list {
1046
+ margin: 0 0 20px 0;
1047
+ padding: 0;
1048
+ list-style-position: inside;
1049
+ li {
1050
+ margin: 0 0 10px 0;
1051
+ }
1052
+ .question-title {
1053
+ margin: 0 0 5px 0;
1054
+ }
1055
+ .current {
1056
+ .question-title {
1057
+ font-weight: bold;
1058
+ }
1059
+ }
1060
+ }
1061
+
1062
+ .quiz-description,
1063
+ .question-content {
1064
+ .learn-press-question-title {
1065
+ margin-bottom: 20px;
1066
+ }
1067
+ }
1068
+
1069
+ .quiz-countdown {
1070
+ float: right;
1071
+ position: relative;
1072
+ min-width: 150px;
1073
+ background: #F5F5F5;
1074
+ text-align: center;
1075
+ font-size: 18px;
1076
+ padding: 5px 0;
1077
+ }
1078
+
1079
+ #quiz-countdown {
1080
+ //.progress-circle(@initialize: 100%, @size: 260px, @inside-size: 200px);
1081
+ .progress-circle {
1082
+ overflow: hidden;
1083
+ box-shadow: 0 0 3px #bdbdbd inset;
1084
+ .inside {
1085
+ line-height: 1;
1086
+ .countdown {
1087
+ font-size: 48px;
1088
+ color: #087998;
1089
+ _text-shadow: 1px 1px #8ee5fd;
1090
+ margin-top: 110px;
1091
+ }
1092
+ p {
1093
+ margin: 10px 0 0 0;
1094
+ color: #DDD;
1095
+ }
1096
+ }
1097
+ &:after {
1098
+ background: #00b9eb;
1099
+ box-shadow: 0 0 6px #097a98;
1100
+ }
1101
+ }
1102
+ }
1103
+
1104
+ #quiz-progress {
1105
+ .progress-circle(@size: 200px, @background: #DDD, @fill: #FF0000, @initialize: 0%, @inside-size: 170px, @inside-background: #FFF);
1106
+ }
1107
+
1108
+ .quiz-result {
1109
+ .quiz-result-mark {
1110
+ .progress-circle();
1111
+ margin-bottom: 20px;
1112
+ }
1113
+ .quiz-result-summary {
1114
+ margin-bottom: 20px;
1115
+ max-width: 500px;
1116
+ .quiz-result-field {
1117
+ position: relative;
1118
+ background: #F5F5F5;
1119
+ color: #fff;
1120
+ margin: 0 0 8px 0;
1121
+ font-size: 12px;
1122
+ padding: 5px 10px;
1123
+ .border-radius(4px);
1124
+ overflow: hidden;
1125
+
1126
+ span, span:after, &:before {
1127
+ display: block;
1128
+ position: absolute;
1129
+ top: 0;
1130
+ left: 0;
1131
+ height: 100%;
1132
+ content: attr(data-text);
1133
+ color: #FFF;
1134
+ white-space: nowrap;
1135
+ overflow: hidden;
1136
+ padding: 3px 10px;
1137
+ background: transparent;
1138
+ transition: width 0.5s;
1139
+ }
1140
+ &:before {
1141
+ content: '';
1142
+ padding: 0;
1143
+ }
1144
+ span {
1145
+ padding: 0;
1146
+ }
1147
+ span:after {
1148
+ margin: 3px 10px;
1149
+ padding: 0;
1150
+ width: 100%;
1151
+ }
1152
+ &.correct {
1153
+ background: #22b4ff;
1154
+ }
1155
+ &.wrong {
1156
+ background: #ff5425;
1157
+ }
1158
+ &.empty {
1159
+ color: #656D6D;
1160
+ }
1161
+ }
1162
+ }
1163
+ p.quiz-result-time {
1164
+ margin: 0 0 10px 0;
1165
+ }
1166
+ .quiz-grade {
1167
+ p {
1168
+ margin: 0 0 10px 0;
1169
+ span {
1170
+ font-weight: bold;
1171
+ &.passed {
1172
+ color: #22b4ff;
1173
+ }
1174
+ &.failed {
1175
+ color: #ff5425;
1176
+ }
1177
+ }
1178
+ }
1179
+ }
1180
+ }
1181
+
1182
+ .element-data-percent-loop (@i) when (@i <= 100) {
1183
+ .single-quiz .quiz-result-field[data-value="@{i}"]:before,
1184
+ .single-quiz .quiz-result-field[data-value="@{i}"] span,
1185
+ #quiz-countdown[data-value="@{i}"]:after {
1186
+ width: ~"@{i}%";
1187
+ }
1188
+ .element-data-percent-loop(@i + 1);
1189
+ }
1190
+
1191
+ .element-data-percent-loop (0);
1192
+
1193
+ /* QUESTION */
1194
+ .learn-press-question-options {
1195
+ list-style: none;
1196
+ margin: 0 0 20px 0;
1197
+ padding: 0;
1198
+ > li.answer-option {
1199
+ font-size: 16px;
1200
+ background: #F5F5F5;
1201
+ margin-bottom: 20px;
1202
+ position: relative;
1203
+ .border-radius(4px);
1204
+ > label {
1205
+ display: block;
1206
+ input[type="checkbox"], input[type="radio"] {
1207
+ border: 0;
1208
+ -webkit-appearance: initial;
1209
+ width: 30px;
1210
+ height: 30px;
1211
+ background: #fff;
1212
+ border-radius: 4px;
1213
+ outline: none;
1214
+ position: absolute;
1215
+ top: 10px;
1216
+ left: 15px;
1217
+ margin: 0;
1218
+ &:checked:before {
1219
+ content: '';
1220
+ border: 4px solid #00b9eb;
1221
+ display: inline-block;
1222
+ width: 10px;
1223
+ height: 15px;
1224
+ border-top: none;
1225
+ border-left: none;
1226
+ position: absolute;
1227
+ top: 3px;
1228
+ left: 8px;
1229
+ box-sizing: content-box;
1230
+ .transform(rotate(36deg));
1231
+ }
1232
+ &:checked + p {
1233
+ font-weight: bold;
1234
+ background: #00b9eb;
1235
+ color: #FFF;
1236
+ }
1237
+ }
1238
+ input[type="checkbox"][disabled], input[type="radio"][disabled] {
1239
+ opacity: 1;
1240
+ }
1241
+ input[type="radio"] {
1242
+ .border-radius(50%);
1243
+ }
1244
+ p {
1245
+ min-height: 50px;
1246
+ padding: 5px 20px 5px 60px;
1247
+ margin: 0;
1248
+ box-sizing: border-box;
1249
+ line-height: 1.5;
1250
+ &.single-lines {
1251
+ padding: 0 20px 0 60px;
1252
+ line-height: 50px; /* middle */
1253
+ }
1254
+ }
1255
+ }
1256
+ label p {
1257
+ .border-radius(4px);
1258
+ }
1259
+ &.answer-true label p {
1260
+ background: #00b9eb;
1261
+ color: #FFF;
1262
+ }
1263
+ &:hover label p {
1264
+ background: #D4D4D4;
1265
+ cursor: pointer;
1266
+ }
1267
+ &.user-answer-false {
1268
+ background: #F5F5F5;
1269
+ > label {
1270
+ input[type="checkbox"] + p, input[type="radio"] + p {
1271
+ text-decoration: line-through;
1272
+ color: #FF0000;
1273
+ background: #F5F5F5;
1274
+ }
1275
+ }
1276
+ }
1277
+ }
1278
+ .answer-option-result {
1279
+ label {
1280
+ p {
1281
+ display: inline-block;
1282
+ margin: 0;
1283
+ font-size: smaller;
1284
+ }
1285
+ input[disabled] {
1286
+ opacity: 1;
1287
+ }
1288
+ }
1289
+ }
1290
+ }
1291
+
1292
+ .learnpress-content {
1293
+ margin-bottom: 20px;
1294
+ }
1295
+
1296
+ .course-meta {
1297
+ margin-bottom: 20px;
1298
+ .course-origin-price {
1299
+ padding-right: 5px;
1300
+ text-decoration: line-through;
1301
+ }
1302
+ .course-price {
1303
+ font-weight: bold;
1304
+ }
1305
+
1306
+ }
1307
+
1308
+ /** MESSAGE */
1309
+ .learn-press-message {
1310
+ background: #F5F5F5;
1311
+ border-left: 5px solid #00A0D2;
1312
+ padding: 10px 20px 1px 20px;
1313
+ margin-bottom: 20px;
1314
+ button {
1315
+ float: right;
1316
+ }
1317
+ p {
1318
+ margin-bottom: 10px;
1319
+ }
1320
+ &:after {
1321
+ clear: both;
1322
+ content: '';
1323
+ display: block;
1324
+ }
1325
+ &.notice {
1326
+ border-left-color: #b3d20a;
1327
+ }
1328
+ &.error {
1329
+ border-left-color: #b81c23;
1330
+ }
1331
+ ul {
1332
+ list-style-type: none;
1333
+ }
1334
+ }
1335
+
1336
+ /**/
1337
+ .learn-press-checkout-comment,
1338
+ .learn-press-checkout-payment {
1339
+ margin-bottom: 20px;
1340
+ }
1341
+
1342
+ .learn-press-checkout-payment {
1343
+ .payment-methods {
1344
+ list-style: none;
1345
+ margin: 0;
1346
+ }
1347
+ }
1348
+
1349
+ /* COURSE QUIZ */
1350
+ .single-quiz {
1351
+ .quiz-questions-list {
1352
+ padding: 0;
1353
+ }
1354
+ .quiz-intro {
1355
+ list-style: none;
1356
+ padding: 10px 20px;
1357
+ background: #F5F5F5;
1358
+ margin: 0 0 20px 0;
1359
+ }
1360
+ h4 {
1361
+ margin-bottom: 10px;
1362
+ font-size: 18px;
1363
+ }
1364
+ }
1365
+
1366
+ .learn-press-tooltip {
1367
+ font-size: 20px;
1368
+ display: inline-block;
1369
+ vertical-align: middle;
1370
+ background: #0f4956;
1371
+ cursor: pointer;
1372
+ line-height: 1;
1373
+ width: 10px;
1374
+ height: 10px;
1375
+ border-radius: 50%;
1376
+ font-weight: 700;
1377
+ position: relative;
1378
+ &:before {
1379
+ content: "?";
1380
+ font-size: 7px;
1381
+ color: white;
1382
+ position: absolute;
1383
+ top: 2px;
1384
+ left: 3px;
1385
+ }
1386
+ }
1387
+
1388
+ /* Form field */
1389
+ .lp-form-field-wrap {
1390
+ list-style: none;
1391
+ margin: 0 0 20px 0;
1392
+ .lp-form-field {
1393
+ list-style: none;
1394
+ margin: 0 0 20px 0;
1395
+ .lp-form-field-label {
1396
+ display: block;
1397
+ font-weight: bold;
1398
+ margin-bottom: 5px;
1399
+ }
1400
+ .lp-form-field-input .description {
1401
+ font-size: smaller;
1402
+ font-style: italic;
1403
+ margin-top: 5px;
1404
+ }
1405
+ .lp-field-error-message {
1406
+ color: #FF0000;
1407
+ }
1408
+ }
1409
+ }
1410
+
1411
+ .learn-press-user-profile {
1412
+
1413
+ .lp-edit-profile {
1414
+ &:after {
1415
+ .clearfix();
1416
+ }
1417
+ }
1418
+ .user-basic-info {
1419
+ p {
1420
+ margin-top: 10px;
1421
+ }
1422
+ }
1423
+ .learn-press-tabs {
1424
+ list-style: none;
1425
+ margin: 30px 0 20px;
1426
+ border-bottom: 1px solid #DDD;
1427
+ & > li {
1428
+ float: left;
1429
+ list-style-type: none;
1430
+ margin-bottom: -1px;
1431
+ & > a {
1432
+ display: inline-block;
1433
+ padding: 10px 15px;
1434
+ outline: none;
1435
+ box-shadow: none;
1436
+ color: #686868;
1437
+ border-bottom: 1px solid #DDD;
1438
+ }
1439
+ &.current {
1440
+ border-bottom: 4px solid #007acc;
1441
+ a {
1442
+ color: #007acc;
1443
+ margin-bottom: -4px;
1444
+ }
1445
+ }
1446
+ }
1447
+ }
1448
+ .learn-press-subtabs {
1449
+ & > li {
1450
+ display: inline-block;
1451
+ margin-right: 10px;
1452
+ &.current {
1453
+ font-weight: bold;
1454
+ }
1455
+ }
1456
+ }
1457
+ .learn-press-subtab-content {
1458
+ display: none;
1459
+ margin-bottom: 20px;
1460
+ &.current {
1461
+ display: block;
1462
+ }
1463
+ li.course {
1464
+ h3 {
1465
+ padding-bottom: 10px;
1466
+ }
1467
+ }
1468
+ .profile-courses {
1469
+ list-style-type: none;
1470
+ .learn-press-course-results-progress {
1471
+ padding: 0 15px 15px 15px;
1472
+ margin: 0;
1473
+ }
1474
+ }
1475
+ }
1476
+ button.learn-press-course-wishlist {
1477
+ display: block;
1478
+ }
1479
+
1480
+ .user-profile-edit-form {
1481
+
1482
+ .info-field {
1483
+ margin-bottom: 20px;
1484
+ }
1485
+
1486
+ .description {
1487
+ margin-top: 5px;
1488
+ }
1489
+
1490
+ .user-profile-picture {
1491
+ clear: both;
1492
+ .picture, .change-picture {
1493
+ display: inline-block;
1494
+ }
1495
+ .change-picture {
1496
+ .description {
1497
+ margin: 0 0 10px 0;
1498
+ }
1499
+ }
1500
+ img {
1501
+ float: left;
1502
+ margin-right: 20px;
1503
+ }
1504
+ &:after {
1505
+ .clearfix();
1506
+ }
1507
+ }
1508
+
1509
+ .profile-field-name {
1510
+ font-weight: bold;
1511
+ margin-bottom: 10px;
1512
+ }
1513
+
1514
+ .change-password {
1515
+ margin-bottom: 10px;
1516
+ }
1517
+
1518
+ #user_profile_password_form {
1519
+ input {
1520
+ margin-bottom: 20px;
1521
+ }
1522
+ .description {
1523
+ margin-top: -15px;
1524
+ }
1525
+ }
1526
+
1527
+
1528
+ }
1529
+ .update-profile{
1530
+ border-top: 2px solid #DDD;
1531
+ padding-top: 20px;
1532
+ }
1533
+ .learn-press-subtab-content {
1534
+ display: block;
1535
+ }
1536
+ #lp-user-edit-avatar {
1537
+ .moxie-shim {
1538
+ display: none;
1539
+ }
1540
+ .lp-form-field-avatar{
1541
+ float: left;
1542
+ }
1543
+ #lp-avatar-actions{
1544
+ margin: 20px 0;
1545
+ }
1546
+ }
1547
+ .lp-avatar-preview {
1548
+ position: relative;
1549
+ float: left;
1550
+ background-color: #DDD;
1551
+ .profile-picture {
1552
+ float: left;
1553
+ margin-right: -100%;
1554
+ width: 100%;
1555
+ img {
1556
+ width: 100%;
1557
+ height: 100%;
1558
+ border-radius: 0;
1559
+ }
1560
+ &.profile-avatar-hidden {
1561
+ display: none;
1562
+ }
1563
+ }
1564
+ .lp-avatar-preview-actions {
1565
+ position: absolute;
1566
+ top: 50%;
1567
+ width: 100%;
1568
+ margin-top: -14px;
1569
+ text-align: center;
1570
+ a {
1571
+ text-decoration: none;
1572
+ font-size: 12px;
1573
+ background: #FFF;
1574
+ display: inline-block;
1575
+ box-shadow: none;
1576
+ padding: 5px 10px;
1577
+ }
1578
+ }
1579
+ .lp-avatar-upload-progress {
1580
+ position: absolute;
1581
+ height: 10px;
1582
+ background: #FFF;
1583
+ top: 50%;
1584
+ margin-top: -5px;
1585
+ left: 10px;
1586
+ right: 10px;
1587
+ display: none;
1588
+ .lp-avatar-upload-progress-value {
1589
+ width: 0;
1590
+ height: 10px;
1591
+ background: #563d7c;
1592
+ }
1593
+ }
1594
+ .lp-avatar-upload-error {
1595
+ display: none;
1596
+ }
1597
+ .lp-avatar-preview-actions {
1598
+ display: none;
1599
+ }
1600
+ &:hover {
1601
+ .lp-avatar-preview-actions {
1602
+ display: block;
1603
+ }
1604
+ }
1605
+ &.uploading, &.upload-error {
1606
+ .lp-avatar-preview-actions {
1607
+ display: none;
1608
+ }
1609
+ .lp-avatar-upload-progress {
1610
+ display: block;
1611
+ }
1612
+ &:before {
1613
+ position: absolute;
1614
+ width: 100%;
1615
+ height: 100%;
1616
+ background: #FFF;
1617
+ opacity: 0.4;
1618
+ content: '';
1619
+ }
1620
+ }
1621
+ &.upload-error {
1622
+ .lp-avatar-upload-error {
1623
+ display: block;
1624
+ }
1625
+ }
1626
+
1627
+ &.croping {
1628
+ .lp-avatar-preview-actions {
1629
+ display: none;
1630
+ }
1631
+ .lp-avatar-crop-image {
1632
+ position: absolute;
1633
+ top: 0;
1634
+ left: 0;
1635
+ width: 100%;
1636
+ height: 100%;
1637
+ background: #000;
1638
+ overflow: hidden;
1639
+ img {
1640
+ max-width: inherit;
1641
+ cursor: move;
1642
+ }
1643
+ .lp-crop-controls {
1644
+ position: absolute;
1645
+ bottom: 0;
1646
+ width: 100%;
1647
+ height: 30px;
1648
+ .lp-zoom {
1649
+ position: absolute;
1650
+ height: 10px;
1651
+ bottom: 10px;
1652
+ left: 10px;
1653
+ right: 30px;
1654
+ background: #563d7a;
1655
+ .ui-slider {
1656
+ position: absolute;
1657
+ left: 0;
1658
+ right: 10px;
1659
+ height: 100%;
1660
+ .ui-slider-handle {
1661
+ display: inline-block;
1662
+ width: 10px;
1663
+ height: 14px;
1664
+ background: #FFF;
1665
+ position: absolute;
1666
+ margin-top: -2px;
1667
+ border: 1px solid #563d7a;
1668
+ box-shadow: none;
1669
+ outline: none;
1670
+ cursor: ew-resize;
1671
+ }
1672
+ }
1673
+ }
1674
+ .lp-cancel-upload {
1675
+ text-decoration: none;
1676
+ position: absolute;
1677
+ bottom: 5px;
1678
+ right: 5px;
1679
+ box-shadow: none;
1680
+ }
1681
+ &:before {
1682
+ position: absolute;
1683
+ height: 30px;
1684
+ width: 100%;
1685
+ content: '';
1686
+ background: #FFF;
1687
+ opacity: 0.4;
1688
+ }
1689
+ }
1690
+ }
1691
+ }
1692
+ &:after {
1693
+ .clearfix();
1694
+ }
1695
+ }
1696
+ }
1697
+
1698
+ body {
1699
+ &.profile-dragging {
1700
+ cursor: move !important;
1701
+ }
1702
+ &.profile-resizing {
1703
+ cursor: ew-resize !important;
1704
+ }
1705
+ }
1706
+
1707
+ .learn-press-pagination {
1708
+ text-align: center;
1709
+ ul {
1710
+ list-style: disc;
1711
+ & > li {
1712
+ display: inline-block;
1713
+ span {
1714
+ display: inline-block;
1715
+ padding: 0 10px;
1716
+ border: 1px solid #DDD;
1717
+ background-color: #F5F5F5;
1718
+ }
1719
+ a {
1720
+ display: inline-block;
1721
+ padding: 0 10px;
1722
+ border: 1px solid #DDD;
1723
+ background-color: #FFF;
1724
+ }
1725
+ }
1726
+ }
1727
+ }
1728
+
1729
+ .learn-press-become-teacher-form {
1730
+ ul {
1731
+ list-style: none;
1732
+ padding: 0;
1733
+ li {
1734
+ margin-bottom: 20px;
1735
+ }
1736
+ }
1737
+ }
1738
+
1739
+ /* jAlerts */
1740
+ #popup_container {
1741
+ background: #FFF;
1742
+
1743
+ #popup_title {
1744
+ padding: 10px 20px;
1745
+ background: #18B6C7;
1746
+ color: #FFF;
1747
+ font-size: 18px;
1748
+ margin: 0;
1749
+ }
1750
+
1751
+ #popup_content {
1752
+ padding: 20px;
1753
+ #popup_message {
1754
+ margin-bottom: 20px;
1755
+ }
1756
+ }
1757
+
1758
+ #popup_panel {
1759
+ text-align: center;
1760
+ }
1761
+ }
1762
+
1763
+ .single-lp_course {
1764
+ .course-summary {
1765
+ .lp_course {
1766
+ .entry-footer {
1767
+ display: none;
1768
+ }
1769
+ }
1770
+ }
1771
+ .learn-press-message {
1772
+ clear: both;
1773
+ margin-top: 25px;
1774
+ }
1775
+ }
1776
+
1777
+ /* tooltip */
1778
+ .learn-press-tooltip-bubble {
1779
+ position: absolute;
1780
+ background: rgba(26, 26, 26, 0.9);
1781
+ color: #ffffff;
1782
+ padding: 8px 10px;
1783
+ font-size: 12px;
1784
+ z-index: 9999999;
1785
+ line-height: 1;
1786
+ border-radius: 3px;
1787
+ }
1788
+
1789
+ /* fill in blank */
1790
+ input.blank-fill-correct {
1791
+ width: auto;
1792
+ }
1793
+
1794
+ body.content-item-only {
1795
+ background: #FFF;
1796
+ opacity: 0;
1797
+ .learn-press-content-item-only {
1798
+ position: fixed;
1799
+ z-index: 9999999;
1800
+ left: 0;
1801
+ top: 0;
1802
+ width: 100%;
1803
+ height: 100%;
1804
+ background: #FFF;
1805
+ overflow: auto;
1806
+ padding: 20px;
1807
+ margin: 0;
1808
+ }
1809
+
1810
+ #learn-press-content-item {
1811
+ border: none;
1812
+ display: block;
1813
+ transition: max-width linear 0.25s;
1814
+ margin: 0 auto;
1815
+ max-width: 1000px;
1816
+ width: 90%;
1817
+ &.expand {
1818
+ max-width: 1200px;
1819
+ }
1820
+ }
1821
+ }
1822
+
1823
+ .lp-group-heading-title {
1824
+ &.toggle-off, &.toggle-on {
1825
+ cursor: pointer;
1826
+ .toggle-icon {
1827
+ display: inline-block;
1828
+ font-size: larger;
1829
+ line-height: 1;
1830
+ font-weight: bold;
1831
+ margin-left: 5px;
1832
+ &:before {
1833
+ content: '+';
1834
+ }
1835
+ }
1836
+ }
1837
+ &.toggle-on {
1838
+ .toggle-icon {
1839
+ &:before {
1840
+ content: '-';
1841
+ }
1842
+ }
1843
+ }
1844
+ }
1845
+
1846
+ /*
1847
+ .sidebar-hide-btn, .sidebar-show-btn {
1848
+ cursor: pointer;
1849
+ width: 60px;
1850
+ height: 60px;
1851
+ display: inline-block;
1852
+ font-size: 34px;
1853
+ line-height: 60px;
1854
+ text-align: center;
1855
+ color: #FFF;
1856
+ position: absolute;
1857
+
1858
+
1859
+ }*/
1860
+
1861
+ .payment-method-form {
1862
+ &.payment_method_authorizenet {
1863
+ background: #f7f7f7;
1864
+ border-radius: 5px;
1865
+ -webkit-border-radius: 5px;
1866
+ -moz-border-radius: 5px;
1867
+ padding-top: 25px;
1868
+ .row-fluid {
1869
+ clear: both;
1870
+ padding-bottom: 25px;
1871
+ .span6 {
1872
+ &:first-child {
1873
+ width: 50%;
1874
+ float: left;
1875
+ label {
1876
+ margin-left: 17px;
1877
+ }
1878
+ select, input {
1879
+ margin-left: 10px;
1880
+ }
1881
+ }
1882
+ select, input {
1883
+ padding: 8px 0;
1884
+ }
1885
+ select.required {
1886
+ color: #000;
1887
+ }
1888
+ }
1889
+ }
1890
+ }
1891
+ }
1892
+
1893
+ .place-order-action {
1894
+ margin-top: 20px;
1895
+ }
1896
+
1897
+ .woocommerce {
1898
+ form .form-row {
1899
+ &.validate-email, &.validate-phone {
1900
+ width: 100% !important;
1901
+ }
1902
+ }
1903
+
1904
+ .checkout_coupon {
1905
+ .form-row-last {
1906
+ input.button {
1907
+ padding: 13px 10px !important;
1908
+ }
1909
+ }
1910
+ }
1911
+ }
1912
+
1913
+ .learn-press-search-course-form {
1914
+ margin-bottom: 20px;
1915
+ input.search-course-input[name="s"] {
1916
+ margin-right: -200px;
1917
+ width: 100%;
1918
+ }
1919
+ .search-course-button {
1920
+ vertical-align: middle;
1921
+ float: right;
1922
+ z-index: 10;
1923
+ position: relative;
1924
+ }
1925
+ }
1926
+
1927
+ /* Shortcode/Widgets */
1928
+ .recent-courses-widget, .popular-courses-widget, .featured-courses-widget {
1929
+ .course-meta-data {
1930
+ > div {
1931
+ display: inline-block;
1932
+ &:after {
1933
+ content: '/';
1934
+ }
1935
+ &:last-child:after {
1936
+ content: '';
1937
+ }
1938
+ }
1939
+
1940
+ }
1941
+ .course-title {
1942
+ margin: 5px 0;
1943
+ }
1944
+ .course-entry {
1945
+ margin-bottom: 20px;
1946
+ }
1947
+ }
1948
+
1949
+ @-moz-keyframes spin-12 {
1950
+ 0% {
1951
+ -moz-transform: rotate(0deg) translate(0px);
1952
+ }
1953
+ 100% {
1954
+ -moz-transform: rotate(360deg) translate(0px);
1955
+ }
1956
+ }
1957
+
1958
+ @-webkit-keyframes spin-12 {
1959
+ 0% {
1960
+ -webkit-transform: rotate(0deg) translate(0px);
1961
+ }
1962
+ 100% {
1963
+ -webkit-transform: rotate(360deg) translate(0px);
1964
+ }
1965
+ }
1966
+
1967
+ @keyframes spin-12 {
1968
+ 0% {
1969
+ -webkit-transform: rotate(0deg) translate(0px);
1970
+ transform: rotate(0deg) translate(0px);
1971
+ }
1972
+ 100% {
1973
+ -webkit-transform: rotate(360deg) translate(0px);
1974
+ transform: rotate(360deg) translate(0px);
1975
+ }
1976
+ }
1977
+
1978
+ @-moz-keyframes spin-13 {
1979
+ 100% {
1980
+ -moz-transform: rotate(0deg) translate(0px);
1981
+ }
1982
+ 0% {
1983
+ -moz-transform: rotate(360deg) translate(0px);
1984
+ }
1985
+ }
1986
+
1987
+ @-webkit-keyframes spin-13 {
1988
+ 0% {
1989
+ -webkit-transform: rotate(0deg) translate(0px);
1990
+ }
1991
+ 100% {
1992
+ -webkit-transform: rotate(360deg) translate(0px);
1993
+ }
1994
+ }
1995
+
1996
+ @keyframes spin-13 {
1997
+ 100% {
1998
+ -webkit-transform: rotate(0deg) translate(0px);
1999
+ transform: rotate(0deg) translate(0px);
2000
+ }
2001
+ 0% {
2002
+ -webkit-transform: rotate(360deg) translate(0px);
2003
+ transform: rotate(360deg) translate(0px);
2004
+ }
2005
+ }
2006
+
2007
+ @media screen and (max-width: 1250px) {
2008
+ .single-lp_course .learn-press-course-results-progress {
2009
+ .items-progress, .course-progress {
2010
+ float: none;
2011
+ width: 100%;
2012
+ }
2013
+ .items-progress {
2014
+ margin-bottom: 50px;
2015
+ }
2016
+ }
2017
+ }
2018
+
2019
+ @media screen and (max-width: 768px) {
2020
+ #learn-press-block-content {
2021
+ .learn-press-block-content-mixin(60px);
2022
+ }
2023
+
2024
+ .learn-press-course-results-progress {
2025
+ .items-progress, .course-progress {
2026
+ width: 100%;
2027
+ margin-right: 0;
2028
+ }
2029
+ }
2030
+
2031
+ }
2032
+
2033
+ @media (min-width: 992px) {
2034
+ .learn-press-courses {
2035
+ li.course {
2036
+ &:nth-child(4n+1) {
2037
+ clear: left;
2038
+ }
2039
+ }
2040
+ }
2041
+ }
2042
+
2043
+ @media (max-width: 992px) {
2044
+ .learn-press-courses {
2045
+ margin: 0;
2046
+ }
2047
+ }
2048
+
2049
+ @media (max-width: 992px) and (min-width: 600px ) {
2050
+
2051
+ .learn-press-courses {
2052
+ li.course {
2053
+ width: 31.33%;
2054
+ margin: 0 2% 30px 0;
2055
+ /* padding: 0 20px; */
2056
+ &:nth-child(3n+1) {
2057
+ clear: left;
2058
+ margin-left: 0;
2059
+ }
2060
+ }
2061
+ }
2062
+
2063
+ }
2064
+
2065
+ @media (max-width: 600px) and (min-width: 400px ) {
2066
+
2067
+ .learn-press-courses {
2068
+ li.course {
2069
+ width: 48%;
2070
+ margin: 0 2% 30px 0;
2071
+ /* padding: 0 20px; */
2072
+ &:nth-child(2n+1) {
2073
+ clear: left;
2074
+ margin-left: 0;
2075
+ }
2076
+ }
2077
+ }
2078
+
2079
+ }
2080
+
2081
+ @media (max-width: 480px) {
2082
+ .woocommerce {
2083
+ .checkout_coupon {
2084
+ .form-row {
2085
+ width: 100%;
2086
+ }
2087
+ }
2088
+ }
2089
+ }
2090
+
2091
+ @media (max-width: 400px) {
2092
+
2093
+ .learn-press-courses {
2094
+ li.course {
2095
+ width: 100%;
2096
+ margin: 0 0 30px 0;
2097
+ clear: left;
2098
+ }
2099
+ }
2100
+
2101
+ }
2102
+
2103
+ @media (max-width: 350px) {
2104
+ #course-curriculum-popup #popup-sidebar {
2105
+ width: 100%;
2106
+ }
2107
+ }
2108
+
2109
+ /* full width with twentysixteen theme */
2110
+ @media screen and (min-width: 61.5625em) {
2111
+ body.single-lp_course {
2112
+ article.lp_course {
2113
+ .entry-content {
2114
+ width: 100%;
2115
+ }
2116
+ .entry-footer {
2117
+ display: none;
2118
+ }
2119
+ }
2120
+ }
2121
+ }
2122
+
2123
+ @media screen and (max-width: 615px) {
2124
+ .payment-method-form {
2125
+ &.payment_method_authorizenet {
2126
+ .row-fluid {
2127
+ padding-bottom: 15px;
2128
+ .span6 {
2129
+ &:first-child {
2130
+ width: 100%;
2131
+ margin-bottom: 15px;
2132
+ }
2133
+ label {
2134
+ margin-left: 17px;
2135
+ }
2136
+ select, input {
2137
+ margin-left: 10px;
2138
+ }
2139
+ select, input {
2140
+ padding: 8px 0;
2141
+ }
2142
+ select.required {
2143
+ color: #000;
2144
+ }
2145
+ #learn-press-authorizenet-payment-expmonth {
2146
+ margin-bottom: 10px;
2147
+ }
2148
+ }
2149
+ }
2150
+ }
2151
+ }
2152
+ }
assets/js/admin/admin.js CHANGED
@@ -82,7 +82,12 @@
82
 
83
  function _ready() {
84
  LP_Admin.init();
85
- $(document).on('click', '.learn-press-add-ons .plugin-action-buttons a:not(.lp-not-ajax)', function (e) {
 
 
 
 
 
86
  e.preventDefault();
87
  var $plugin = $(this).closest('.plugin-card');
88
  if ($(this).hasClass('button-working')) {
@@ -466,7 +471,11 @@ lprHook.addAction('lpr_admin_quiz_question_html', _lprAdminQuestionHTML);
466
  })
467
  })
468
  .lprFancyCheckbox();
469
- $('#learn-press-add-ons-wrap').on('click', '.plugin-action-buttons a:not(.lp-not-ajax)', function (evt) {
 
 
 
 
470
  evt.preventDefault();
471
  var $link = $(this), action = $link.data('action');
472
  if (!action) return;
@@ -1033,8 +1042,7 @@ jQuery(document).ready(function ($) {
1033
 
1034
  $(document).ready( function() {
1035
 
1036
- /* Search Addon & Theme */
1037
-
1038
  var $wrapAddon = $('#learn-press-add-ons-wrap'),
1039
  $addOnClone = $wrapAddon.clone(true);
1040
 
@@ -1072,7 +1080,7 @@ jQuery(document).ready(function ($) {
1072
  }
1073
  });
1074
 
1075
- /* Count for plugin */
1076
  $('.learnpress-count-addon', $wrapFreeAddon).text($('.plugin-card-learnpress:not(.lp-addon-hidden)', $wrapFreeAddon).length);
1077
  $('.learnpress-count-addon', $wrapPremium).text($('.plugin-card-learnpress:not(.lp-addon-hidden)', $wrapPremium).length);
1078
 
@@ -1086,6 +1094,22 @@ jQuery(document).ready(function ($) {
1086
  }, 100);
1087
  });
1088
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1089
  });
1090
 
1091
  $(window).load( function () {
82
 
83
  function _ready() {
84
  LP_Admin.init();
85
+ $(document).on('click', '.plugin-action-buttons a', function (e) {
86
+
87
+ if ( $(e.target).closest( '.learnpress-premium-plugin' ).length ) {
88
+ return;
89
+ }
90
+
91
  e.preventDefault();
92
  var $plugin = $(this).closest('.plugin-card');
93
  if ($(this).hasClass('button-working')) {
471
  })
472
  })
473
  .lprFancyCheckbox();
474
+ $('#learn-press-add-ons-wrap').on('click', '.plugin-action-buttons a', function (evt) {
475
+
476
+ if ( $(evt.target).closest( '.learnpress-premium-plugin' ).length ) {
477
+ return;
478
+ }
479
  evt.preventDefault();
480
  var $link = $(this), action = $link.data('action');
481
  if (!action) return;
1042
 
1043
  $(document).ready( function() {
1044
 
1045
+ // Search Add-ons & Theme
 
1046
  var $wrapAddon = $('#learn-press-add-ons-wrap'),
1047
  $addOnClone = $wrapAddon.clone(true);
1048
 
1080
  }
1081
  });
1082
 
1083
+ // Count for plugin
1084
  $('.learnpress-count-addon', $wrapFreeAddon).text($('.plugin-card-learnpress:not(.lp-addon-hidden)', $wrapFreeAddon).length);
1085
  $('.learnpress-count-addon', $wrapPremium).text($('.plugin-card-learnpress:not(.lp-addon-hidden)', $wrapPremium).length);
1086
 
1094
  }, 100);
1095
  });
1096
 
1097
+ // Hidden Button Preview In Course When Course Status Is Pending
1098
+ var $bodyCourse = $('.post-type-lp_course');
1099
+
1100
+ if ( $bodyCourse.length ) {
1101
+
1102
+ var $minorPubish = $('#minor-publishing', $bodyCourse),
1103
+ $postPreview = $('#post-preview', $minorPubish),
1104
+ $postStatus = $('#hidden_post_status', $minorPubish),
1105
+ postStatus = $postStatus.val();
1106
+
1107
+ if ( postStatus && postStatus === 'pending' ) {
1108
+ $postPreview.hide();
1109
+ }
1110
+ }
1111
+
1112
+
1113
  });
1114
 
1115
  $(window).load( function () {
assets/js/admin/meta-box-course.js CHANGED
@@ -1459,8 +1459,7 @@
1459
  if (!opts.pending_review) {
1460
  return true;
1461
  }
1462
- //|| (opts.current_user == opts.edited_user && opts.user_type != 'admin'));
1463
- //(opts.current_user == opts.edited_user && opts.user_type != 'admin' && opts.course_status != 'publish');
1464
  return false;
1465
  }
1466
 
1459
  if (!opts.pending_review) {
1460
  return true;
1461
  }
1462
+
 
1463
  return false;
1464
  }
1465
 
assets/js/admin/settings.js CHANGED
@@ -168,7 +168,12 @@
168
  } else if (e.keyCode == 27 && e.type == 'keydown') {
169
  $(this).siblings('a').trigger('click')
170
  }
 
 
 
171
  });
 
 
172
  $('#learn-press-admin-settings').on('click', '.nav-tab, .subsubsub > li > a', function (e) {
173
  e.preventDefault();
174
  var redirect = $(this).attr('href'),
168
  } else if (e.keyCode == 27 && e.type == 'keydown') {
169
  $(this).siblings('a').trigger('click')
170
  }
171
+ }).on('change update', '#learn_press_required_review', function(e){
172
+ var $depend = $('input[name="learn_press_enable_edit_published"]').closest('tr');
173
+ $depend.toggleClass('hide-if-js', !e.target.checked).find('input[type="checkbox"]').prop('disabled', !e.target.checked)
174
  });
175
+
176
+ $('#learn_press_required_review').trigger('update');
177
  $('#learn-press-admin-settings').on('click', '.nav-tab, .subsubsub > li > a', function (e) {
178
  e.preventDefault();
179
  var redirect = $(this).attr('href'),
assets/js/frontend/checkout.js CHANGED
@@ -1,132 +1,138 @@
1
- if (typeof window.LP === 'undefined') {
2
- window.LP = {};
3
- }
4
- ;
5
- (function ($) {
6
- "use strict";
7
- LP.reload = function (url) {
8
- if (!url) {
9
- url = window.location.href;
10
- }
11
- window.location.href = url;
12
- };
13
- LP.Checkout = {
14
- $form : null,
15
- init : function () {
16
- var $doc = $(document);
17
- this.$form = $('form[name="lp-checkout"]');
18
- $doc.on('click', 'input[name="payment_method"]', this.selectPaymentMethod);
19
- $doc.on('click', '#learn-press-checkout-login-button', this.login);
20
-
21
- $('input[name="payment_method"]:checked').trigger('click');
22
- this.$form.on('submit', this.doCheckout);
23
- },
24
- selectPaymentMethod: function () {
25
- var methodId = $(this).attr('id'),
26
- checkoutButton = $('#learn-press-checkout-place-order'),
27
- isError = false;
28
- if ($('.payment-methods input.input-radio').length > 1) {
29
- var $paymentForm = $('div.payment-method-form.' + methodId);
30
-
31
- if ($(this).is(':checked')) {
32
- $('div.payment-method-form').filter(':visible').slideUp(250);
33
- $(this).parents('li:first').find('.payment-method-form.' + methodId).slideDown(250);
34
- }
35
- } else {
36
- $('div.payment-method-form').show();
37
- }
38
- isError = $('div.payment-method-form:visible').find('input[name="' + methodId + '-error"]').val() == 'yes';
39
- if (isError) {
40
- checkoutButton.attr('disabled', 'disabled');
41
- } else {
42
- checkoutButton.removeAttr('disabled');
43
- }
44
- var order_button_text = $(this).data('order_button_text');
45
- if (order_button_text) {
46
- checkoutButton.val(order_button_text);
47
- } else {
48
- checkoutButton.val(checkoutButton.data('value'));
49
- }
50
- },
51
- login : function () {
52
- var $form = $(this.form);
53
- if ($form.triggerHandler('checkout_login') !== false) {
54
- $.ajax({
55
- url : LP_Settings.siteurl + '/?lp-ajax=checkout-login',
56
- dataType: 'html',
57
- data : $form.serialize(),
58
- type : 'post',
59
- success : function (response) {
60
- response = LP.parseJSON(response);
61
- if (response.result === 'fail') {
62
- if (response.messages) {
63
- LP.Checkout.showErrors(response.messages);
64
- } else {
65
- LP.Checkout.showErrors('<div class="learn-press-error">Unknown error!</div>');
66
- }
67
- } else {
68
- if (response.redirect) {
69
- window.location.href = response.redirect;
70
- }
71
- }
72
- }
73
- });
74
- }
75
- return false;
76
- },
77
- doCheckout : function () {
78
- var $form = $(this),
79
- $place_order = $form.find('#learn-press-checkout'),
80
- processing_text = $place_order.attr('data-processing-text'),
81
- text = $place_order.attr('value');
82
- if ($form.triggerHandler('learn_press_checkout_place_order') !== false && $form.triggerHandler('learn_press_checkout_place_order_' + $('#order_review').find('input[name=payment_method]:checked').val()) !== false) {
83
- if (processing_text) {
84
- $place_order.val(processing_text);
85
- }
86
- $place_order.prop('disabled', true);
87
- $.ajax({
88
- url : LP_Settings.siteurl + '/?lp-ajax=checkout',
89
- dataType: 'html',
90
- data : $form.serialize(),
91
- type : 'post',
92
- success : function (response) {
93
- response = LP.parseJSON(response);
94
- if (response.result === 'fail') {
95
- if (response.messages) {
96
- LP.Checkout.showErrors(response.messages);
97
- } else {
98
- LP.Checkout.showErrors('<div class="learn-press-error">Unknown error!</div>');
99
- }
100
- } else if (response.result === 'success') {
101
- if (response.redirect) {
102
- $place_order.val('Redirecting');
103
- LP.reload(response.redirect);
104
- return;
105
- }
106
- }
107
- $place_order.val(text);
108
- $place_order.prop('disabled', false);
109
- },
110
- error : function (jqXHR, textStatus, errorThrown) {
111
- LP.Checkout.showErrors('<div class="learn-press-error">' + errorThrown + '</div>');
112
- $place_order.val(text);
113
- $place_order.prop('disabled', false);
114
-
115
- }
116
- });
117
- }
118
- return false;
119
- },
120
- showErrors : function (messages) {
121
- $('.learn-press-error, .learn-press-notice, .learn-press-message').remove();
122
- this.$form.prepend(messages);
123
- $('html, body').animate({
124
- scrollTop: ( LP.Checkout.$form.offset().top - 100 )
125
- }, 1000);
126
- $(document).trigger('learnpress_checkout_error');
127
- }
128
- };
129
- $(document).ready(function () {
130
- LP.Checkout.init();
131
- });
 
 
 
 
 
 
132
  })(jQuery);
1
+ if (typeof window.LP === 'undefined') {
2
+ window.LP = {};
3
+ }
4
+ ;
5
+ (function ($) {
6
+ "use strict";
7
+ LP.reload = function (url) {
8
+ if (!url) {
9
+ url = window.location.href;
10
+ }
11
+ window.location.href = url;
12
+ };
13
+ LP.Checkout = {
14
+ $form : null,
15
+ init : function () {
16
+ var $doc = $(document);
17
+ this.$form = $('form[name="lp-checkout"]');
18
+ $doc.on('click', 'input[name="payment_method"]', this.selectPaymentMethod);
19
+ $doc.on('click', '#learn-press-checkout-login-button', this.login);
20
+
21
+ $('input[name="payment_method"]:checked').trigger('click');
22
+ this.$form.on('submit', this.doCheckout);
23
+ },
24
+ selectPaymentMethod: function () {
25
+ var methodId = $(this).attr('id'),
26
+ checkoutButton = $('#learn-press-checkout-place-order'),
27
+ isError = false;
28
+ if ($('.payment-methods input.input-radio').length > 1) {
29
+ var $paymentForm = $('div.payment-method-form.' + methodId);
30
+
31
+ if ($(this).is(':checked')) {
32
+ $('div.payment-method-form').filter(':visible').slideUp(250);
33
+ $(this).parents('li:first').find('.payment-method-form.' + methodId).slideDown(250);
34
+ }
35
+ } else {
36
+ $('div.payment-method-form').show();
37
+ }
38
+ isError = $('div.payment-method-form:visible').find('input[name="' + methodId + '-error"]').val() == 'yes';
39
+ if (isError) {
40
+ checkoutButton.attr('disabled', 'disabled');
41
+ } else {
42
+ checkoutButton.removeAttr('disabled');
43
+ }
44
+ var order_button_text = $(this).data('order_button_text');
45
+ if (order_button_text) {
46
+ checkoutButton.val(order_button_text);
47
+ } else {
48
+ checkoutButton.val(checkoutButton.data('value'));
49
+ }
50
+ },
51
+ login : function () {
52
+ var $form = $(this.form);
53
+ if ($form.triggerHandler('checkout_login') !== false) {
54
+ $.ajax({
55
+ url : LP_Settings.siteurl + '/?lp-ajax=checkout-login',
56
+ dataType: 'html',
57
+ data : $form.serialize(),
58
+ type : 'post',
59
+ success : function (response) {
60
+ response = LP.parseJSON(response);
61
+ if (response.result === 'fail') {
62
+ if (response.messages) {
63
+ LP.Checkout.showErrors(response.messages);
64
+ } else {
65
+ LP.Checkout.showErrors('<div class="learn-press-error">Unknown error!</div>');
66
+ }
67
+ } else {
68
+ if (response.redirect) {
69
+ window.location.href = response.redirect;
70
+ }
71
+ }
72
+ }
73
+ });
74
+ }
75
+ return false;
76
+ },
77
+ doCheckout : function () {
78
+ var $form = $(this),
79
+ $place_order = $form.find('#learn-press-checkout'),
80
+ processing_text = $place_order.attr('data-processing-text'),
81
+ text = $place_order.attr('value');
82
+ if ($form.triggerHandler('learn_press_checkout_place_order') !== false && $form.triggerHandler('learn_press_checkout_place_order_' + $('#order_review').find('input[name=payment_method]:checked').val()) !== false) {
83
+ if (processing_text) {
84
+ $place_order.val(processing_text);
85
+ }
86
+ $place_order.prop('disabled', true);
87
+ $.ajax({
88
+ url : LP_Settings.siteurl + '/?lp-ajax=checkout',
89
+ dataType: 'html',
90
+ data : $form.serialize(),
91
+ type : 'post',
92
+ success : function (response) {
93
+ response = LP.parseJSON(response);
94
+ if (response.result === 'fail') {
95
+ var $error = '';
96
+ if (!response.messages) {
97
+ if (response.code && response.code == 30) {
98
+ LP.Checkout.showErrors('<div class="learn-press-error">' + learn_press_js_localize.invalid_field + '</div>');
99
+ } else {
100
+ LP.Checkout.showErrors('<div class="learn-press-error">' + learn_press_js_localize.unknown_error + '</div>');
101
+ }
102
+ } else {
103
+ LP.Checkout.showErrors(response.messages);
104
+ }
105
+
106
+ } else if (response.result === 'success') {
107
+ if (response.redirect) {
108
+ $place_order.val('Redirecting');
109
+ LP.reload(response.redirect);
110
+ return;
111
+ }
112
+ }
113
+ $place_order.val(text);
114
+ $place_order.prop('disabled', false);
115
+ },
116
+ error : function (jqXHR, textStatus, errorThrown) {
117
+ LP.Checkout.showErrors('<div class="learn-press-error">' + errorThrown + '</div>');
118
+ $place_order.val(text);
119
+ $place_order.prop('disabled', false);
120
+
121
+ }
122
+ });
123
+ }
124
+ return false;
125
+ },
126
+ showErrors : function (messages) {
127
+ $('.learn-press-error, .learn-press-notice, .learn-press-message').remove();
128
+ this.$form.prepend(messages);
129
+ $('html, body').animate({
130
+ scrollTop: ( LP.Checkout.$form.offset().top - 100 )
131
+ }, 1000);
132
+ $(document).trigger('learnpress_checkout_error');
133
+ }
134
+ };
135
+ $(document).ready(function () {
136
+ LP.Checkout.init();
137
+ });
138
  })(jQuery);
assets/js/frontend/profile.js CHANGED
@@ -1,276 +1,552 @@
1
- ;(function ($) {
2
- 'use strict';
3
- $(document).ready(function () {
4
- $('#user_profile_password_form input').attr('disabled', 'disabled');
5
- $(document).on('click', '.table-orders .cancel-order', function (e) {
6
- e.preventDefault();
7
- var _this = $(this),
8
- _href = _this.attr('href');
9
- LP.alert(learn_press_js_localize.confirm_cancel_order, function (confirm) {
10
- if (confirm) {
11
- window.location.href = _href;
12
- }
13
- });
14
- return false;
15
- });
16
-
17
- $(document).on('submit', '#learn-press-form-login', function (e) {
18
- var $form = $(this),
19
- data = $form.serialize();
20
- $form.find('.learn-press-error, .learn-press-notice, .learn-press-message').fadeOut();
21
- $form.find('input').attr('disabled', true);
22
- LP.doAjax({
23
- data : {
24
- 'lp-ajax': 'login',
25
- data : data
26
- },
27
- success: function (response, raw) {
28
- LP.showMessages(response.message, $form, 'LOGIN_ERROR');
29
- if (response.result == 'error') {
30
- $form.find('input').attr('disabled', false);
31
- $('#learn-press-form-login input[type="text"]').focus();
32
- }
33
- if (response.redirect) {
34
- LP.reload(response.redirect);
35
- }
36
- },
37
- error : function () {
38
- LP.showMessages('', $form, 'LOGIN_ERROR');
39
- $form.find('input').attr('disabled', false);
40
- $('#learn-press-form-login input[type="text"]').focus();
41
- }
42
- });
43
- return false;
44
- });
45
-
46
- $('#learn-press-toggle-password').click(function (e) {
47
- e.preventDefault();
48
- var $el = $('#user_profile_password_form');
49
- if ($el.hasClass('hide-if-js')) {
50
- $el.removeClass('hide-if-js').hide();
51
- }
52
- $el.slideToggle(function () {
53
- $el.find('input').attr('disabled', !$el.is(':visible'));
54
- });
55
- });
56
-
57
- $('#learn-press-form-login input[type="text"]').focus();
58
- /**
59
- * Show hide dropdown menu
60
- */
61
- $('.user-profile-edit-form').on('change', 'select[name="profile_picture_type"]', function () {
62
- var avata_type = $(this).val();
63
- $('.profile-avatar-hidden, .profile-avatar-current' ).each(function () {
64
- $(this).toggleClass('hide-if-js', $(this).hasClass('avatar-'+avata_type) );
65
- });
66
- $('.menu-item-use-gravatar, .menu-item-use-picture' ).each(function () {
67
- $(this).toggleClass('lp-menu-item-selected', $(this).hasClass('menu-item-use-'+avata_type));
68
- });
69
- });
70
-
71
- $('#lp-menu-change-picture .menu-item-use-gravatar').click( function(event){
72
- $('#lp-profile_picture_type').val('gravatar').trigger('change');
73
- $('#lpbox-upload-crop-profile-picture').slideUp();
74
- });
75
-
76
- $('#lp-menu-change-picture .menu-item-use-picture').click( function(event){
77
- var current_picture = $('#lp-user-profile-picture-data').attr('data-current');
78
- if( !current_picture ){
79
- // $('#lp-button-choose-file').trigger('click');
80
- $('#lpbox-upload-crop-profile-picture').slideDown();
81
- } else {
82
- $('#lp-profile_picture_type').val('picture').trigger('change');
83
- $('#lpbox-upload-crop-profile-picture').slideUp();
84
- }
85
- });
86
-
87
- $('#lp-menu-change-picture .menu-item-upload-picture').click( function(event){
88
- // $('#lp-button-choose-file').trigger('click');
89
- $('#lpbox-upload-crop-profile-picture').slideDown();
90
- });
91
-
92
- $('#lp-ocupload-picture').upload(
93
- {
94
- 'name':'image',
95
- params:{from:'profile','action':'update','sub_action':'upload_avatar'},
96
- 'onSubmit':function(){
97
- LP.blockContent();
98
- },
99
- 'onComplete':function(response){
100
- response = LP.parseJSON(response);
101
- console.log(response);
102
- if( response.return && response.avatar_tmp ) {
103
- /* Load Image in to crop */
104
- $('.image-editor').cropit('imageSrc',response.avatar_tmp);
105
- $('.image-editor').attr('avatar-filename',response.avatar_tmp_filename);
106
- $('#lpbox-upload-crop-profile-picture').slideDown();
107
- LP.unblockContent();
108
- $('body, html').css('overflow','visible');
109
- $('.user-profile-picture.info-field .learn-press-message').remove();
110
- var message = '<div class="learn-press-message success"><p>'+response.message+'</p></div>';
111
- $('.user-profile-picture.info-field').prepend(message);
112
- } else if ( !response.return ){
113
- $('.image-editor').cropit('imageSrc','');
114
- $('.image-editor').attr('avatar-filename','');
115
- LP.unblockContent();
116
- $('body, html').css('overflow','visible');
117
- $('.user-profile-picture.info-field .learn-press-message').remove();
118
- var message = '<div class="learn-press-message error"><p>'+response.message+'</p></div>';
119
- $('.user-profile-picture.info-field').prepend(message);
120
-
121
- }
122
- }
123
- }
124
- );
125
-
126
- $('#lp-button-choose-file').click(function(event){
127
- event.preventDefault();
128
- $('#lp-ocupload-picture').parent().find('form input[name="image"]').trigger('click');
129
- });
130
-
131
- $('#lpbox-upload-crop-profile-picture .image-editor').cropit();
132
-
133
-
134
- $('#lp-button-apply-changes').click(function (event) {
135
- event.preventDefault();
136
- var zoom = $('.image-editor').cropit('zoom');
137
- var offset = $('.image-editor').cropit('offset');
138
- var avatar_filename = $('.image-editor').attr('avatar-filename');
139
- var datas = {
140
- from:'profile',
141
- 'action':'update',
142
- 'sub_action':'crop_avatar',
143
- 'avatar_filename':avatar_filename,
144
- 'zoom':zoom,
145
- 'offset':offset
146
- };
147
- /** Create avatar, thumbnail and update picture option **/
148
- $.ajax({
149
- url : LP.getUrl(),
150
- dataType: 'html',
151
- data : datas,
152
- type : 'post',
153
- beforeSend: function(){
154
- LP.blockContent();
155
- },
156
- success : function (response) {
157
- response = LP.parseJSON(response);
158
- var avatar_url = response.avatar_url;
159
- $('.profile-picture.avatar-gravatar img').attr( 'src', avatar_url );
160
- $('#lp-profile_picture_type').val('picture').trigger('change');
161
- $('#lpbox-upload-crop-profile-picture').slideUp();
162
- LP.unblockContent();
163
- $('body, html').css('overflow','visible');
164
- $('.user-profile-picture.info-field .learn-press-message').remove();
165
- $('.user-profile-picture.info-field').prepend(response.message);
166
- }
167
- });
168
- return;
169
- });
170
-
171
- $('#lp-button-cancel-changes').click(function (event) {
172
- event.preventDefault();
173
- $('#lpbox-upload-crop-profile-picture').slideUp();
174
- });
175
-
176
- $('#learn-press-user-profile-edit-form form#your-profile input[name="submit"]').on('click', function(event){
177
- event.preventDefault();
178
- var check_form = true;
179
- var check_focus = false;
180
- /**
181
- * VALIDATE FORM
182
- */
183
- // console.log( '' === $('#your-profile #nickname' ).val());
184
- if ('' === $('#your-profile #nickname').val()) {
185
- if (0 === $('#your-profile #nickname').next('span.error').length) {
186
- $('<span class="error">'+lp_profile_translation.msg_field_is_required+'</span>').insertAfter($('#your-profile #nickname'));
187
- }
188
- check_form = false;
189
- //document.getElementById('nickname').focus();
190
- $('#your-profile #nickname').focus();
191
- check_focus = true;
192
- } else {
193
- $('#your-profile #nickname').next('span.error').remove();
194
- }
195
-
196
- if ('' !== $('#your-profile #pass0').val()) {
197
- if ('' === $('#your-profile #pass1').val()) {
198
- if (0 === $('#your-profile #pass1').next('span.error').length) {
199
- $('<span class="error">'+lp_profile_translation.msg_field_is_required+'</span>').insertAfter($('#your-profile #pass1'));
200
- }
201
- check_form = false;
202
- if (!check_focus) {
203
- $('#your-profile #pass1').focus();
204
- check_focus = true;
205
- }
206
- } else {
207
- $('#your-profile #pass1').next('span.error').remove();
208
- }
209
-
210
- if ('' === $('#your-profile #pass2').val()) {
211
- if (0 === $('#your-profile #pass2').next('span.error').length) {
212
- $('<span class="error">'+lp_profile_translation.msg_field_is_required+'</span>').insertAfter($('#your-profile #pass2'));
213
- }
214
- check_form = false;
215
- if ( !check_focus ) {
216
- $('#your-profile #pass2').focus();
217
- check_focus = true;
218
- }
219
- } else {
220
- $(this.pass2).next('span.error').remove();
221
- }
222
- }
223
- if (check_form) {
224
- // $('#learn-press-user-profile-edit-form form#your-profile').submit();
225
- var datas = $('#learn-press-user-profile-edit-form form#your-profile').serializeArray();
226
- $.ajax({
227
- url : LP.getUrl(),
228
- dataType: 'html',
229
- data : datas,
230
- type : 'post',
231
- beforeSend: function(){
232
- LP.blockContent();
233
- },
234
- success : function (response) {
235
- response = LP.parseJSON(response);
236
- $('#your-profile #pass0, #your-profile #pass1, #your-profile #pass2').val('');
237
- $('#user_profile_password_form').slideUp();
238
- LP.unblockContent();
239
- $('body, html').css('overflow','visible');
240
- $('.user-profile-picture.info-field .learn-press-message').remove();
241
- $('.user-profile-picture.info-field').prepend(response.message);
242
- $('html, body').animate({
243
- scrollTop: $('.user-profile-picture.info-field .learn-press-message').offset().top-100
244
- }, 500);
245
- }
246
- });
247
- }
248
- });
249
-
250
- $('#learn-press-user-profile-edit-form #your-profile input#nickname').on('change',function(){
251
- if(''===$(this).val()){
252
- if(0 === $(this).next('span.error').length){;
253
- $('<span class="error">'+lp_profile_translation.msg_field_is_required+'</span>').insertAfter($(this));
254
- }
255
- } else {
256
- $(this).next('span.error').remove();
257
- }
258
- });
259
-
260
- $('#learn-press-user-profile-edit-form #your-profile input#pass1').on('change',function(){
261
-
262
- });
263
-
264
- $('#learn-press-user-profile-edit-form #your-profile input#pass2').on('keyup',function(){
265
- var pass1 = $('#your-profile input#pass1').val();
266
- if( pass1 !== $(this).val() ){
267
- if(0 === $(this).next('span.error').length){;
268
- $('<span class="error">'+lp_profile_translation.confim_pass_not_match+'</span>').insertAfter($(this));
269
- }
270
- } else {
271
- $(this).next('span.error').remove();
272
- }
273
- });
274
-
275
- });
276
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function ($) {
2
+ 'use strict';
3
+
4
+ var UserProfile = function (args) {
5
+ this.view = new UserProfile.View({
6
+ model: new UserProfile.Model(args)
7
+ });
8
+ }
9
+
10
+ UserProfile.View = Backbone.View.extend({
11
+ events : {
12
+ 'click #lp-remove-upload-photo': '_removePhoto',
13
+ 'click #lp-upload-photo' : '_upload',
14
+ 'click .lp-cancel-upload' : '_cancel'
15
+ },
16
+ el : '#lp-user-profile-form',
17
+ uploader : null,
18
+ initialize : function () {
19
+ console.log()
20
+ _.bindAll(this, 'filesAdded', 'uploadProgress', 'uploadError', 'fileUploaded', 'crop');
21
+ this._getUploader();
22
+ },
23
+ _removePhoto : function (e) {
24
+ e.preventDefault();
25
+ this.$('.profile-picture').toggle().filter('.profile-avatar-current').remove();
26
+ this.$('#lp-remove-upload-photo').hide();
27
+ this.$('#submit').prop('disabled', false);
28
+ },
29
+ _upload : function (e) {
30
+ e.preventDefault();
31
+ },
32
+ _cancel : function (e) {
33
+ e.preventDefault();
34
+ this.$crop && this.$crop.remove();
35
+ this.$('.lp-avatar-preview').removeClass('croping');
36
+ },
37
+ filesAdded : function (up, files) {
38
+ var that = this;
39
+ up.files.splice(0, up.files.length - 1);
40
+ that.$('.lp-avatar-preview').addClass('uploading');
41
+ that.$('.lp-avatar-upload-progress-value').width(0);
42
+ that.uploader.start();
43
+ },
44
+ uploadProgress: function (up, file) {
45
+ this.$('.lp-avatar-upload-progress-value').css('width', file.percent + "%");
46
+ },
47
+ uploadError : function (up, err) {
48
+ this.$('.lp-avatar-preview').addClass('upload-error').removeClass('uploading');
49
+ this.$('.lp-avatar-upload-error').html(err);
50
+ },
51
+ fileUploaded : function (up, file, info) {
52
+ this.$('.lp-avatar-preview').removeClass('upload-error').removeClass('uploading');
53
+ var that = this,
54
+ response = LP.parseJSON(info.response);
55
+ if (response.url) {
56
+ this.avatar = response.url;
57
+ $("<img/>") // Make in memory copy of image to avoid css issues
58
+ .attr("src", response.url)
59
+ .load(function () {
60
+ that.model.set($.extend(response, {
61
+ width : this.width,
62
+ height: this.height
63
+ }));
64
+ that.crop()
65
+ });
66
+ }
67
+ },
68
+ crop : function () {
69
+ this.model.set('r', Math.random())
70
+ new UserProfile.Crop(this);
71
+ this.$('#submit').prop('disabled', false);
72
+ },
73
+ _getUploader : function () {
74
+ if (this.uploader) {
75
+ return this.uploader;
76
+ }
77
+ this.uploader = new plupload.Uploader({
78
+ runtimes : 'html5,flash,silverlight,html4',
79
+ browse_button : 'lp-upload-photo',
80
+ container : $('#lp-user-edit-avatar').get(0),
81
+ url : LP_Settings.ajax.addQueryVar('action', 'learnpress_upload-user-avatar'),
82
+ filters : {
83
+ max_file_size: '10mb',
84
+ mime_types : [
85
+ {title: "Image", extensions: "png,jpg,bmp,gif"}
86
+ ]
87
+ },
88
+ file_data_name: 'lp-upload-avatar',
89
+ init : {
90
+ PostInit : function () {
91
+ },
92
+ FilesAdded : this.filesAdded,
93
+ UploadProgress: this.uploadProgress,
94
+ FileUploaded : this.fileUploaded,
95
+ Error : this.uploadError
96
+ }
97
+ });
98
+ this.uploader.init();
99
+ return this.uploader;
100
+ }
101
+ });
102
+ UserProfile.Model = Backbone.Model.extend({});
103
+ UserProfile.Crop = function ($view) {
104
+ var self = this,
105
+ data = $view.model.toJSON(),
106
+ $crop = $(LP.template('tmpl-crop-user-avatar')(data));
107
+ $crop.appendTo($view.$('.lp-avatar-preview').addClass('croping'));
108
+ $view.$crop = $crop;
109
+ var $img = $crop.find('img'),
110
+ wx = 0,
111
+ hx = 0,
112
+ lx = 0,
113
+ tx = 0,
114
+ nw = 0,
115
+ nh = 0;
116
+ this.initCrop = function () {
117
+ var r1 = data.viewWidth / data.viewHeight,
118
+ r2 = data.width / data.height;
119
+
120
+ if (r1 >= r2) {
121
+ wx = data.viewWidth;
122
+ hx = data.height * data.viewWidth / data.width;
123
+ lx = 0;
124
+ tx = -(hx - data.viewHeight) / 2
125
+ } else {
126
+ hx = data.viewHeight;
127
+ wx = data.width * data.viewHeight / data.height;
128
+ tx = 0;
129
+ lx = -(wx - data.viewWidth) / 2;
130
+ }
131
+ nw = wx;
132
+ nh = hx;
133
+ $img.draggable({
134
+ drag: function (e, ui) {
135
+ if (ui.position.left > 0) {
136
+ ui.position.left = 0;
137
+ }
138
+ if (ui.position.top > 0) {
139
+ ui.position.top = 0;
140
+ }
141
+ var xx = data.viewWidth - nw,
142
+ yy = data.viewHeight - nh;
143
+ if (xx > ui.position.left) {
144
+ ui.position.left = xx;
145
+ }
146
+ if (yy > ui.position.top) {
147
+ ui.position.top = yy;
148
+ }
149
+ $(document.body).addClass('profile-dragging');
150
+ },
151
+ stop: function (e, ui) {
152
+ lx = parseInt($img.css('left'));
153
+ tx = parseInt($img.css('top'));
154
+ dd = (Math.abs(lx) + data.viewWidth / 2) / nw;
155
+ bb = (Math.abs(tx) + data.viewHeight / 2) / nh;
156
+ self.update({
157
+ width : nw,
158
+ height: nh,
159
+ top : tx,
160
+ left : lx
161
+ });
162
+ $(document.body).removeClass('profile-dragging');
163
+ }
164
+ });
165
+ var dd = (Math.abs(lx) + data.viewWidth / 2) / wx,
166
+ bb = (Math.abs(tx) + data.viewHeight / 2) / hx;
167
+ $crop.find('.lp-zoom > div').slider({
168
+ create: function () {
169
+ self.update({
170
+ width : wx,
171
+ height: hx,
172
+ top : tx,
173
+ left : lx
174
+ });
175
+ },
176
+ slide : function (e, ui) {
177
+ nw = wx + (ui.value / 100) * data.width * 2;
178
+ nh = hx + (ui.value / 100) * data.height * 2;
179
+ var nl = data.viewWidth / 2 - (nw * dd),// parseInt((data.viewWidth - nw) / 2),
180
+ nt = data.viewHeight / 2 - nh * bb;//parseInt((data.viewHeight - nh) / 2);
181
+ if (nl > 0) {
182
+ nl = 0;
183
+ }
184
+ if (nt > 0) {
185
+ nt = 0;
186
+ }
187
+ var xx = parseInt(data.viewWidth - nw),
188
+ yy = parseInt(data.viewHeight - nh);
189
+ if (xx > nl) {
190
+ nl = lx = xx;
191
+ }
192
+ if (yy > nt) {
193
+ nt = tx = yy;
194
+ }
195
+ self.update({
196
+ width : nw,
197
+ height: nh,
198
+ top : nt,
199
+ left : nl
200
+ });
201
+ $(document.body).addClass('profile-resizing');
202
+ },
203
+ stop: function(){
204
+ $(document.body).removeClass('profile-resizing');
205
+ }
206
+ });
207
+ }
208
+ this.update = function (args) {
209
+ $img.css({
210
+ width : args.width,
211
+ height: args.height,
212
+ top : args.top,
213
+ left : args.left
214
+ });
215
+ var r = args.width / data.width,
216
+ left = parseInt(Math.abs(args.left / r)),
217
+ top = parseInt(Math.abs(args.top / r)),
218
+ right = left + parseInt(data.viewWidth / r),
219
+ bottom = top + parseInt(data.viewHeight / r);
220
+ var cropData = $.extend(args, {
221
+ width : data.viewWidth,
222
+ height: data.viewHeight,
223
+ r : r,
224
+ points: [left, top, right, bottom].join(',')
225
+ });
226
+ $crop.find('input[name^="lp-user-avatar-crop"]').each(function () {
227
+ var $input = $(this),
228
+ name = $input.data('name');
229
+ if (name != 'name') {
230
+ $input.val(cropData[name]);
231
+ }
232
+ });
233
+ }
234
+ this.initCrop();
235
+ }
236
+
237
+
238
+ $(document).on('submit', '#learn-press-form-login', function (e) {
239
+ var $form = $(this),
240
+ data = $form.serialize();
241
+ $form.find('.learn-press-error, .learn-press-notice, .learn-press-message').fadeOut();
242
+ $form.find('input').attr('disabled', true);
243
+ LP.doAjax({
244
+ data : {
245
+ 'lp-ajax': 'login',
246
+ data : data
247
+ },
248
+ success: function (response, raw) {
249
+ LP.showMessages(response.message, $form, 'LOGIN_ERROR');
250
+ if (response.result == 'error') {
251
+ $form.find('input').attr('disabled', false);
252
+ $('#learn-press-form-login input[type="text"]').focus();
253
+ }
254
+ if (response.redirect) {
255
+ LP.reload(response.redirect);
256
+ }
257
+ },
258
+ error : function () {
259
+ LP.showMessages('', $form, 'LOGIN_ERROR');
260
+ $form.find('input').attr('disabled', false);
261
+ $('#learn-press-form-login input[type="text"]').focus();
262
+ }
263
+ });
264
+ return false;
265
+ });
266
+
267
+ $(document).on('click', '.table-orders .cancel-order', function (e) {
268
+ e.preventDefault();
269
+ var _this = $(this),
270
+ _href = _this.attr('href');
271
+ LP.alert(learn_press_js_localize.confirm_cancel_order, function (confirm) {
272
+ if (confirm) {
273
+ window.location.href = _href;
274
+ }
275
+ });
276
+ return false;
277
+ });
278
+ $(document).ready(function () {
279
+ var $form = $('#lp-user-profile-form form'),
280
+ oldData = $form.serialize(),
281
+ timer = null,
282
+ $passwordForm = $form.find('#lp-profile-edit-password-form');
283
+
284
+ function _checkData() {
285
+ return $form.serialize() != oldData;
286
+ }
287
+
288
+ function _timerCallback() {
289
+ $form.find('#submit').prop('disabled', !_checkData());
290
+ }
291
+
292
+ if ($passwordForm.length == 0) {
293
+ $form.on('keyup change', 'input, textarea, select', function () {
294
+ timer && clearTimeout(timer);
295
+ timer = setTimeout(_timerCallback, 300);
296
+ });
297
+ } else {
298
+ $passwordForm.on('change keyup', 'input', function (e) {
299
+ var $target = $(e.target),
300
+ targetName = $target.attr('name'),
301
+ $oldPass = $form.find('#pass0'),
302
+ $newPass = $form.find('#pass1'),
303
+ $confirmPass = $form.find('#pass2'),
304
+ match = !(($newPass.val() || $confirmPass.val()) && $newPass.val() != $confirmPass.val());
305
+ $form.find('#lp-password-not-match').toggleClass('hide-if-js', match);
306
+ $form.find('#submit').prop('disabled', !match || !$oldPass.val() || !$newPass.val() || !$confirmPass.val());
307
+ });
308
+ }
309
+ // avatar
310
+ new UserProfile({
311
+ viewWidth : parseInt(LP_Settings.avatar_size['width']),
312
+ viewHeight: parseInt(LP_Settings.avatar_size['height'])
313
+ });
314
+ });
315
+
316
+ return;
317
+ $(document).on('click', '#lp-remove-upload-photo', function () {
318
+
319
+
320
+ $('#learn-press-toggle-password').click(function (e) {
321
+ e.preventDefault();
322
+ var $el = $('#user_profile_password_form');
323
+ if ($el.hasClass('hide-if-js')) {
324
+ $el.removeClass('hide-if-js').hide();
325
+ }
326
+ $el.slideToggle(function () {
327
+ $el.find('input').attr('disabled', !$el.is(':visible'));
328
+ });
329
+ });
330
+
331
+ $('#learn-press-form-login input[type="text"]').focus();
332
+ /**
333
+ * Show hide dropdown menu
334
+ */
335
+ $('.user-profile-edit-form').on('change', 'select[name="profile_picture_type"]', function () {
336
+ var avata_type = $(this).val();
337
+ $('.profile-avatar-hidden, .profile-avatar-current').each(function () {
338
+ $(this).toggleClass('hide-if-js', $(this).hasClass('avatar-' + avata_type));
339
+ });
340
+ $('.menu-item-use-gravatar, .menu-item-use-picture').each(function () {
341
+ $(this).toggleClass('lp-menu-item-selected', $(this).hasClass('menu-item-use-' + avata_type));
342
+ });
343
+ });
344
+
345
+ $('#lp-menu-change-picture .menu-item-use-gravatar').click(function (event) {
346
+ $('#lp-profile_picture_type').val('gravatar').trigger('change');
347
+ $('#lpbox-upload-crop-profile-picture').slideUp();
348
+ });
349
+
350
+ $('#lp-menu-change-picture .menu-item-use-picture').click(function (event) {
351
+ var current_picture = $('#lp-user-profile-picture-data').attr('data-current');
352
+ if (!current_picture) {
353
+ // $('#lp-button-choose-file').trigger('click');
354
+ $('#lpbox-upload-crop-profile-picture').slideDown();
355
+ } else {
356
+ $('#lp-profile_picture_type').val('picture').trigger('change');
357
+ $('#lpbox-upload-crop-profile-picture').slideUp();
358
+ }
359
+ });
360
+
361
+ $('#lp-menu-change-picture .menu-item-upload-picture').click(function (event) {
362
+ // $('#lp-button-choose-file').trigger('click');
363
+ $('#lpbox-upload-crop-profile-picture').slideDown();
364
+ });
365
+
366
+ $('#lp-ocupload-picture').upload(
367
+ {
368
+ 'name' : 'image',
369
+ params : {from: 'profile', 'action': 'update', 'sub_action': 'upload_avatar'},
370
+ 'onSubmit' : function () {
371
+ LP.blockContent();
372
+ },
373
+ 'onComplete': function (response) {
374
+ response = LP.parseJSON(response);
375
+ console.log(response);
376
+ if (response.return && response.avatar_tmp) {
377
+ /* Load Image in to crop */
378
+ $('.image-editor').cropit('imageSrc', response.avatar_tmp);
379
+ $('.image-editor').attr('avatar-filename', response.avatar_tmp_filename);
380
+ $('#lpbox-upload-crop-profile-picture').slideDown();
381
+ LP.unblockContent();
382
+ $('body, html').css('overflow', 'visible');
383
+ $('.user-profile-picture.info-field .learn-press-message').remove();
384
+ var message = '<div class="learn-press-message success"><p>' + response.message + '</p></div>';
385
+ $('.user-profile-picture.info-field').prepend(message);
386
+ } else if (!response.return) {
387
+ $('.image-editor').cropit('imageSrc', '');
388
+ $('.image-editor').attr('avatar-filename', '');
389
+ LP.unblockContent();
390
+ $('body, html').css('overflow', 'visible');
391
+ $('.user-profile-picture.info-field .learn-press-message').remove();
392
+ var message = '<div class="learn-press-message error"><p>' + response.message + '</p></div>';
393
+ $('.user-profile-picture.info-field').prepend(message);
394
+
395
+ }
396
+ }
397
+ }
398
+ );
399
+
400
+ $('#lp-button-choose-file').click(function (event) {
401
+ event.preventDefault();
402
+ $('#lp-ocupload-picture').parent().find('form input[name="image"]').trigger('click');
403
+ });
404
+
405
+ $('#lpbox-upload-crop-profile-picture .image-editor').cropit();
406
+
407
+
408
+ $('#lp-button-apply-changes').click(function (event) {
409
+ event.preventDefault();
410
+ var zoom = $('.image-editor').cropit('zoom');
411
+ var offset = $('.image-editor').cropit('offset');
412
+ var avatar_filename = $('.image-editor').attr('avatar-filename');
413
+ var datas = {
414
+ from : 'profile',
415
+ 'action' : 'update',
416
+ 'sub_action' : 'crop_avatar',
417
+ 'avatar_filename': avatar_filename,
418
+ 'zoom' : zoom,
419
+ 'offset' : offset
420
+ };
421
+ /** Create avatar, thumbnail and update picture option **/
422
+ $.ajax({
423
+ url : LP.getUrl(),
424
+ dataType : 'html',
425
+ data : datas,
426
+ type : 'post',
427
+ beforeSend: function () {
428
+ LP.blockContent();
429
+ },
430
+ success : function (response) {
431
+ response = LP.parseJSON(response);
432
+ var avatar_url = response.avatar_url;
433
+ $('.profile-picture.avatar-gravatar img').attr('src', avatar_url);
434
+ $('#lp-profile_picture_type').val('picture').trigger('change');
435
+ $('#lpbox-upload-crop-profile-picture').slideUp();
436
+ LP.unblockContent();
437
+ $('body, html').css('overflow', 'visible');
438
+ $('.user-profile-picture.info-field .learn-press-message').remove();
439
+ $('.user-profile-picture.info-field').prepend(response.message);
440
+ }
441
+ });
442
+ return;
443
+ });
444
+
445
+ $('#lp-button-cancel-changes').click(function (event) {
446
+ event.preventDefault();
447
+ $('#lpbox-upload-crop-profile-picture').slideUp();
448
+ });
449
+
450
+ $('#learn-press-user-profile-edit-form form#your-profile input[name="submit"]').on('click', function (event) {
451
+ event.preventDefault();
452
+ var check_form = true;
453
+ var check_focus = false;
454
+ /**
455
+ * VALIDATE FORM
456
+ */
457
+ // console.log( '' === $('#your-profile #nickname' ).val());
458
+ if ('' === $('#your-profile #nickname').val()) {
459
+ if (0 === $('#your-profile #nickname').next('span.error').length) {
460
+ $('<span class="error">' + lp_profile_translation.msg_field_is_required + '</span>').insertAfter($('#your-profile #nickname'));
461
+ }
462
+ check_form = false;
463
+ //document.getElementById('nickname').focus();
464
+ $('#your-profile #nickname').focus();
465
+ check_focus = true;
466
+ } else {
467
+ $('#your-profile #nickname').next('span.error').remove();
468
+ }
469
+
470
+ if ('' !== $('#your-profile #pass0').val()) {
471
+ if ('' === $('#your-profile #pass1').val()) {
472
+ if (0 === $('#your-profile #pass1').next('span.error').length) {
473
+ $('<span class="error">' + lp_profile_translation.msg_field_is_required + '</span>').insertAfter($('#your-profile #pass1'));
474
+ }
475
+ check_form = false;
476
+ if (!check_focus) {
477
+ $('#your-profile #pass1').focus();
478
+ check_focus = true;
479
+ }
480
+ } else {
481
+ $('#your-profile #pass1').next('span.error').remove();
482
+ }
483
+
484
+ if ('' === $('#your-profile #pass2').val()) {
485
+ if (0 === $('#your-profile #pass2').next('span.error').length) {
486
+ $('<span class="error">' + lp_profile_translation.msg_field_is_required + '</span>').insertAfter($('#your-profile #pass2'));
487
+ }
488
+ check_form = false;
489
+ if (!check_focus) {
490
+ $('#your-profile #pass2').focus();
491
+ check_focus = true;
492
+ }
493
+ } else {
494
+ $(this.pass2).next('span.error').remove();
495
+ }
496
+ }
497
+ if (check_form) {
498
+ // $('#learn-press-user-profile-edit-form form#your-profile').submit();
499
+ var datas = $('#learn-press-user-profile-edit-form form#your-profile').serializeArray();
500
+ $.ajax({
501
+ url : LP.getUrl(),
502
+ dataType : 'html',
503
+ data : datas,
504
+ type : 'post',
505
+ beforeSend: function () {
506
+ LP.blockContent();
507
+ },
508
+ success : function (response) {
509
+ response = LP.parseJSON(response);
510
+ $('#your-profile #pass0, #your-profile #pass1, #your-profile #pass2').val('');
511
+ $('#user_profile_password_form').slideUp();
512
+ LP.unblockContent();
513
+ $('body, html').css('overflow', 'visible');
514
+ $('.user-profile-picture.info-field .learn-press-message').remove();
515
+ $('.user-profile-picture.info-field').prepend(response.message);
516
+ $('html, body').animate({
517
+ scrollTop: $('.user-profile-picture.info-field .learn-press-message').offset().top - 100
518
+ }, 500);
519
+ }
520
+ });
521
+ }
522
+ });
523
+
524
+ $('#learn-press-user-profile-edit-form #your-profile input#nickname').on('change', function () {
525
+ if ('' === $(this).val()) {
526
+ if (0 === $(this).next('span.error').length) {
527
+ ;
528
+ $('<span class="error">' + lp_profile_translation.msg_field_is_required + '</span>').insertAfter($(this));
529
+ }
530
+ } else {
531
+ $(this).next('span.error').remove();
532
+ }
533
+ });
534
+
535
+ $('#learn-press-user-profile-edit-form #your-profile input#pass1').on('change', function () {
536
+
537
+ });
538
+
539
+ $('#learn-press-user-profile-edit-form #your-profile input#pass2').on('keyup', function () {
540
+ var pass1 = $('#your-profile input#pass1').val();
541
+ if (pass1 !== $(this).val()) {
542
+ if (0 === $(this).next('span.error').length) {
543
+ ;
544
+ $('<span class="error">' + lp_profile_translation.confim_pass_not_match + '</span>').insertAfter($(this));
545
+ }
546
+ } else {
547
+ $(this).next('span.error').remove();
548
+ }
549
+ });
550
+
551
+ });
552
+ })(jQuery);
assets/js/frontend/quiz.js CHANGED
@@ -1,905 +1,917 @@
1
- /**
2
- * Single Quiz functions
3
- *
4
- * @author ThimPress
5
- * @package LearnPress/JS
6
- * @version 1.1
7
- */
8
- ;(function ($) {
9
-
10
- var Quiz = function (args) {
11
- this.model = new Quiz.Model(args);
12
- this.view = new Quiz.View({
13
- model: this.model
14
- });
15
- this.destroy = function () {
16
- this.model.questions.forEach(function (m) {
17
- try {
18
- m instanceof Model_Question ? (
19
- // prevent trigger 'sync' action
20
- m.set('id', null),
21
- m.destroy()
22
- ) : false;
23
- } catch (ex) {
24
- console.log(ex);
25
- }
26
- });
27
- this.model.set('id', null);
28
- this.model.destroy();
29
- this.view.destroy();
30
- this.view.undelegateEvents();
31
- };
32
- }, Model_Question, List_Questions, windowTarget = parent.window || window;
33
-
34
- Quiz.Model_Question = Model_Question = Backbone.Model.extend({
35
- defaults : {
36
- //question_id: 0
37
- },
38
- data : null,
39
- view : false,
40
- url : function () {
41
- return this.urlRoot;
42
- },
43
- urlRoot : function () {
44
- return 'abc';
45
- },
46
- initialize: function () {
47
- },
48
- element : function () {
49
- return $(this.get('content'));
50
- },
51
- submit : function (args) {
52
- var that = this;
53
- args = $.extend({
54
- complete: null,
55
- data : {}
56
- }, args || {});
57
- this.fetch({
58
- data : $.extend({
59
- action : 'learnpress_load_quiz_question',
60
- user_id : this.get('user_id'),
61
- quiz_id : this.get('quiz_id'),
62
- question_id: this.get('id')
63
- }, args.data || {}),
64
- complete: (function (e) {
65
- var response = LP.parseJSON(e.responseText);
66
- if (response.result == 'success') {
67
- //if (!that.get('content')) {
68
- that.set(response.question);
69
- if (response.permalink) {
70
- LP.setUrl(response.permalink);
71
- }
72
- //}
73
- $.isFunction(args.complete) && args.complete.call(that, response);
74
- }
75
- })
76
- });
77
- },
78
- check : function (args) {
79
- var that = this;
80
- if ($.isFunction(args)) {
81
- args = {
82
- complete: args
83
- }
84
- } else {
85
- args = $.extend({
86
- complete: null,
87
- data : {}
88
- }, args || {});
89
- }
90
- LP.doAjax({
91
- data : $.extend({
92
- 'lp-ajax' : 'check-question',
93
- question_id: this.get('id')
94
- //question_answer: $('form#learn-press-quiz-question').serializeJSON()
95
- }, args.data || {}),
96
- dataType: 'html',
97
- success : function (response, raw) {
98
- var $content = that.get('response');
99
- if ($content) {
100
- $content.find('.learn-press-question-options').replaceWith($(response).filter('.learn-press-question-options'));
101
- }
102
- that.set({checked: 'yes', response: $content});
103
- $.isFunction(args.complete) && args.complete.call(that, response);
104
- }
105
- });
106
- },
107
- showHint : function (args) {
108
- var that = this;
109
- LP.doAjax({
110
- data : $.extend({
111
- 'lp-ajax' : 'get-question-hint',
112
- user_id : this.get('user_id'),
113
- quiz_id : this.get('quiz_id'),
114
- question_id : this.get('id'),
115
- question_answer: $('form#learn-press-quiz-question').serializeJSON()
116
- }, args.data || {}),
117
- success: function (response, raw) {
118
- that.set('checked', response.checked);
119
- $.isFunction(args.complete) && args.complete.call(that, response);
120
- }
121
- });
122
- }
123
- });
124
- /**
125
- * List Questions
126
- */
127
- Quiz.List_Questions = List_Questions = Backbone.Collection.extend({
128
- url : 'admin-ajax.php',
129
- urlRoot : function () {
130
- return '';
131
- },
132
- len : 0,
133
- model : Model_Question,
134
- initialize : function () {
135
- this.on('add', function (model) {
136
- this.listenTo(model, 'change', this.onChange);
137
- this.listenTo(model, 'change:hasShowedHint', this.onChangedHint);
138
- this.listenTo(model, 'change:checked', function (a) {
139
- if (a.changed['checked'] && a.changed['checked'] === 'yes') {
140
- var $dom = a.get('response');
141
- if ($dom) $dom.find('.button-check-answer').attr('disabled', true);
142
- }
143
- }, this);
144
- model.set('index', this.len++);
145
- }, this);
146
- this.on('change:view', function () {
147
- this.questions.view = this.get('view');
148
- });
149
-
150
- },
151
- onChangedHint: function (a, b) {
152
-
153
- },
154
- onChange : function (a, b) {
155
-
156
- if (a.changed['current']) {
157
- if (a.get('current') !== 'yes') {
158
-
159
- } else {
160
- this.current = a;
161
- for (var i = 0; i < this.length; i++) {
162
- var e = this.at(i);
163
- if (e.get('id') == a.get('id')) {
164
- $('.question-' + e.get('id')).toggleClass('current', true);
165
- continue;
166
- }
167
- if (e.get('current') != 'yes') {
168
- continue;
169
- }
170
- this.stopListening(e, 'change', this.onChange);
171
- e.set('current', 'no');
172
- this.listenTo(e, 'change', this.onChange);
173
- $('.question-' + e.get('id')).toggleClass('current', false)
174
- }
175
- try {
176
- this.view.updateUrl();
177
- } catch (e) {
178
- }
179
- }
180
- }
181
- }
182
- });
183
-
184
- Quiz.Model = Backbone.Model.extend({
185
- _args : null,
186
- questions : null,
187
- initialize : function (args) {
188
- _.bindAll(this, 'getQuizData');
189
- this._args = args || {};
190
- this.on('change:view', function () {
191
- this.questions.view = this.get('view');
192
- });
193
- this._initQuestions();
194
- this.set('remainingTime', args.totalTime - args.userTime);
195
- LP.Hook.addFilter('learn_press_finish_quiz_data', this.getQuizData);
196
-
197
- this.prepareQuestion( {delayTime: this.delayTime} )
198
- },
199
- _initQuestions : function () {
200
- this.questions = new List_Questions();
201
- _.forEach(this._args.questions, function (q) {
202
- this.questions.add(q);
203
- }, this);
204
- if (this.questions.length && !this.current()) {
205
- this.questions.at(0).set('current', 'yes');
206
- }
207
- },
208
- _secondsToDHMS : function (t) {
209
- var d = Math.floor(t / (24 * 3600)), t = t - d * 24 * 3600, h = Math.floor(t / 3600), t = t - h * 3600, m = Math.floor(t / 60), s = Math.floor(t - m * 60);
210
- return {d: d, h: h, m: m, s: s}
211
- },
212
- getRemainingTime : function (format) {
213
- var t = this.get('remainingTime');
214
- if (format == 'dhms') {
215
- t = this._secondsToDHMS(t);
216
- }
217
- return t;
218
- },
219
- getTotalTime : function (format) {
220
- var t = this.get('totalTime');
221
- if (format == 'dhms') {
222
- t = this._secondsToDHMS(t);
223
- }
224
- return t;
225
- },
226
- getUserTime : function (format) {
227
- var t = this.get('userTime');
228
- if (format == 'dhms') {
229
- t = this._secondsToDHMS(t);
230
- }
231
- return t;
232
- },
233
- inc : function (seconds) {
234
- var userTime = this.get('userTime') + (seconds || 1);
235
- var t = {
236
- userTime : userTime,
237
- remainingTime: Math.max(this.get('totalTime') - userTime, 0)
238
- };
239
- this.set(t);
240
- return t;
241
- },
242
- decr : function (seconds) {
243
- var userTime = this.get('userTime') - (seconds || 1);
244
- var t = {
245
- userTime : userTime,
246
- remainingTime: Math.max(this.get('totalTime') - userTime, 0)
247
- };
248
- this.set(t);
249
- return t;
250
- },
251
- fetchCurrent : function (callback) {
252
- var current = this.getCurrent(),
253
- that = this;
254
- if (!current) {
255
- return;
256
- }
257
- LP.Hook.doAction('learn_press_before_fetch_question', current.get('id'), that);
258
- $.ajax({
259
- url : current.get('url'),
260
- dataType: 'html',
261
- success : function (response) {
262
- that.set('response', response);
263
- $.isFunction(callback) && callback(response, that);
264
- }
265
- });
266
- },
267
- next : function (callback, args) {
268
- var next = this.findNext(),
269
- that = this,
270
- id = 0;
271
- if (!next) {
272
- return;
273
- }
274
- id = parseInt(next.get('id'));
275
- LP.Hook.doAction('learn_press_before_next_question', id, that);
276
- this.select(id, function (args) {
277
- LP.Hook.doAction('learn_press_previous_question', id, that);
278
- callback && callback.apply(null, arguments);
279
- }, args);
280
- },
281
- prev : function (callback, args) {
282
- var prev = this.findPrev(),
283
- that = this,
284
- id = 0;
285
- if (!prev) {
286
- return;
287
- }
288
- id = prev.get('id');
289
- LP.Hook.doAction('learn_press_before_previous_question', id, that);
290
- this.select(id, function () {
291
- LP.Hook.doAction('learn_press_previous_question', id, that);
292
- callback && callback.apply(null, arguments);
293
- }, args);
294
- },
295
- select : function (id, callback, args) {
296
- var question = this.questions.findWhere({id: parseInt(id)}),
297
- that = this,
298
- loadedCallback = function () {
299
- $.isFunction(callback) && callback(question, that);
300
- LP.Hook.doAction('learn_press_select_question', question, that);
301
- };
302
- if (!question) {
303
- return;
304
- }
305
- if (question.get('current') === 'yes') {
306
- windowTarget.LP.unblockContent();
307
- return;
308
- }
309
- LP.Hook.doAction('learn_press_before_select_question', question, that);
310
- question.set('current', 'yes');
311
- if (question.get('response')) {
312
- loadedCallback();
313
- } else {
314
- $.ajax({
315
- url : question.get('url'),
316
- data : $.extend({
317
- id : question.get('id'),
318
- data : $('form[name="quiz-question-content"]').serialize(),
319
- 'lp-ajax': 'fetch-question'
320
- }, args || {}),
321
- dataType: 'html',
322
- success : function (response) {
323
- var $html = $(response).contents().find('.learn-press-content-item-summary');
324
- question.set('response', $html);
325
- loadedCallback();
326
- }
327
- });
328
- }
329
-
330
- /* Prepare next question & prev question */
331
- this.prepareQuestion(args)
332
- },
333
- prepareQuestion : function (args) {
334
-
335
- var next = this.findNext(),
336
- prev = this.findPrev();
337
-
338
- if (next) {
339
- this.prepareResponse(parseInt(next.get('id')), args);
340
- }
341
- if (prev) {
342
- this.prepareResponse(parseInt(prev.get('id')), args);
343
- }
344
- },
345
- prepareResponse : function (id, args) {
346
-
347
- var question = this.questions.findWhere({id: parseInt(id)});
348
-
349
- if (question.get('response')) {
350
- return;
351
- }
352
-
353
- $.ajax({
354
- url : question.get('url'),
355
- data : $.extend({
356
- id : question.get('id'),
357
- data : $('form[name="quiz-question-content"]').serialize(),
358
- 'lp-ajax': 'fetch-question'
359
- }, args || {}),
360
- dataType: 'html',
361
- success : function (response) {
362
- var $html = $(response).contents().find('.learn-press-content-item-summary');
363
- question.set('response', $html);
364
- }
365
- });
366
- },
367
- getQuestionPosition : function (question_id) {
368
- question_id = question_id || this.get('question_id');
369
- return _.indexOf(this.getIds(), question_id);
370
- },
371
- countQuestions : function () {
372
- return this.questions.length;
373
- },
374
- isLast : function (question_id) {
375
- question_id = question_id || this.getCurrent('id');
376
- var q = this.questions.findWhere({id: parseInt(question_id)});
377
- return q ? q.get('index') == this.questions.length - 1 : false;
378
- },
379
- isFirst : function (question_id) {
380
- question_id = question_id || this.getCurrent('id');
381
- var q = this.questions.findWhere({id: parseInt(question_id)});
382
- return q ? q.get('index') == 0 : false;
383
- },
384
- findNext : function (question_id) {
385
- question_id = question_id || this.getCurrent('id');
386
- var q = this.questions.findWhere({id: parseInt(question_id)}),
387
- next = false;
388
- if (q) {
389
- var index = q.get('index');
390
- next = this.questions.at(index + 1);
391
- }
392
- return next;
393
- },
394
- findPrev : function (question_id) {
395
- question_id = question_id || this.getCurrent('id');
396
- var q = this.questions.findWhere({id: parseInt(question_id)}),
397
- prev = false;
398
- if (q) {
399
- var index = q.get('index');
400
- prev = this.questions.at(index - 1);
401
- }
402
- return prev;
403
- },
404
- getCurrent : function (_field, _default) {
405
- var current = this.current(),
406
- r = _default;
407
- if (current) {
408
- r = current.get(_field);
409
- }
410
- return r;
411
- },
412
- current : function (create) {
413
- var current = this.questions.findWhere({current: 'yes'});
414
- if (!current && create) {
415
- current = new Model_Question();
416
- }
417
- return current;
418
- },
419
- getIds : function () {
420
- return $.map(this.get('questions'), function (i, v) {
421
- return parseInt(i.id);
422
- });
423
- },
424
- showHint : function (callback, args) {
425
- this.current().showHint({
426
- complete: callback,
427
- data : this.getRequestParams(args)
428
- });
429
- },
430
- checkAnswer : function (callback, args) {
431
- if (!args) {
432
- args = {};
433
- }
434
- args.question_answer = this.getQuestionAnswerData(this.current());
435
- this.current().check({
436
- complete: callback,
437
- data : this.getRequestParams(args)
438
- });
439
- },
440
- getRequestParams : function (args) {
441
- var defaults = LP.Hook.applyFilters('learn_press_request_quiz_params', {
442
- quiz_id : this.get('id'),
443
- user_id : this.get('user_id'),
444
- course_id: this.get('courseId')
445
- });
446
-
447
- return $.extend(defaults, args || {});
448
- },
449
- getQuestion : function (thing) {
450
- var question = false;
451
- if ($.isNumeric(thing)) {
452
- question = this.questions.findWhere({id: parseInt(thing)});
453
- } else if ($.isPlainObject(thing)) {
454
- question = this.questions.findWhere(thing);
455
- } else if ($.type(thing) == 'undefined' || $.type(thing) == null) {
456
- question = this.current();
457
- } else if (thing instanceof Model_Question) {
458
- question = thing;
459
- }
460
- return question;
461
- },
462
- getQuizData : function (data) {
463
- data.answers = {};
464
- this.questions.forEach(function (model) {
465
- data.answers[model.get('id')] = this.getQuestionAnswerData(model);
466
- }, this);
467
- return data;
468
- },
469
- getQuestionAnswerData: function (question) {
470
- question = this.getQuestion(question);
471
- if (!question) {
472
- return undefined;
473
- }
474
- var $html = question.get('response'),
475
- answer = {},
476
- $form = $('<form />');
477
- if ($html) {
478
- var $content = $html.find('.quiz-question-content');
479
- $form.html($content.clone());
480
- answer = $form.serializeJSON();
481
- }
482
- return LP.Hook.applyFilters('learn_press_question_answer_data', answer, $form, question, this);
483
- }
484
- });
485
- Quiz.View = Backbone.View.extend({
486
- el : function () {
487
- return 'body';
488
- },
489
- events : {
490
- 'click .button-prev-question' : '_prevQuestion',
491
- 'click .button-next-question' : '_nextQuestion',
492
- 'click .button-hint' : '_showHint',
493
- 'click .button-check-answer' : '_checkAnswer',
494
- 'click .quiz-questions-list .question-title': '_selectQuestion',
495
- 'click .button-start-quiz' : '_startQuiz',
496
- 'click .button-finish-quiz' : '_finishQuiz',
497
- 'click .button-retake-quiz' : '_retakeQuiz',
498
- 'click .button-complete-item' : '_completeItem',
499
- 'click #lp-navigation .nav-link a' : '_click_nav_link'
500
- },
501
- timeout : 0,
502
- delayTimeout : 0,
503
- delayTime : 0,
504
- localized : null,
505
- initialize : function () {
506
- _.bindAll(this, 'pause', '_onTick', 'itemUrl', '_loadQuestionCompleted', '_checkAnswerCompleted', '_checkAnswer', '_onDestroy', 'destroy');
507
- LP.Hook.addAction('learn_press_before_finish_quiz', this.destroy);
508
- LP.Hook.addFilter('learn_press_get_current_item_url', this.itemUrl);
509
- this.model.current(true).set('response', this.$('.learn-press-content-item-summary'));
510
- this.model.set('view', this);
511
- this.model.on('destroy', this._onDestroy);
512
- this._initCountDown();
513
- this.updateButtons();
514
- this.windowTarget = windowTarget;
515
- this.localized = window.learn_press_single_course_localize || {};
516
- $(document).ready(function () {
517
- $(window).trigger('load');
518
- $(document).trigger('resize');
519
- });
520
- },
521
- _initCountDown : function () {
522
- if (this.model.get('status') != 'started' || this.model.get('totalTime') <= 0) {
523
- return;
524
- }
525
- this.updateCountdown();
526
- setTimeout($.proxy(function () {
527
- this.$('.quiz-countdown').removeClass('hide-if-js');
528
- this.start();
529
- }, this), 500);
530
- },
531
- _addLeadingZero : function (n) {
532
- return n < 10 ? "0" + n : "" + n;
533
- },
534
- _onDestroy : function () {
535
- this.pause();
536
- },
537
- _onTick : function () {
538
- this.timeout && clearTimeout(this.timeout);
539
- var timer = this.model.inc();
540
- this.updateCountdown();
541
-
542
- if (timer.remainingTime == 0) {
543
- LP.Hook.doAction('learn_press_quiz_timeout', this);
544
- this.$('.button-finish-quiz').trigger('click');
545
- return;
546
- }
547
- this.timeout = setTimeout(this._onTick, 1000);
548
- },
549
-
550
- _prevQuestion : function (e) {
551
- e.preventDefault();
552
- var delayTime = this.delayTime;
553
- this._beforeFetchQuestion();
554
- this.model.prev(this._loadQuestionCompleted, {delayTime: delayTime});
555
- },
556
- _nextQuestion : function (e) {
557
- e.preventDefault();
558
- var delayTime = this.delayTime;
559
- this._beforeFetchQuestion();
560
- this.model.next(this._loadQuestionCompleted, {delayTime: delayTime});
561
-
562
- },
563
- _selectQuestion : function (e) {
564
- e.preventDefault();
565
- if (this.model.get('status') == 'started') {
566
- var id = $(e.target).closest('li').attr('data-id'),
567
- delayTime = this.delayTime;
568
- if (this.model.current().get('id') == id) {
569
- return;
570
- }
571
- this._beforeFetchQuestion();
572
- this.model.select(id, this._loadQuestionCompleted, {delayTime: delayTime});
573
- }
574
- },
575
- _beforeFetchQuestion : function () {
576
- windowTarget.LP.blockContent();
577
- this.pause();
578
- this.incrDelay(true);
579
- this.model.current(true).set('response', this.$('.learn-press-content-item-summary'));
580
- },
581
- _loadQuestionCompleted: function (question, model) {
582
- var loaded = model.get('loaded'),
583
- $newElement = question.get('response'),
584
- $oldElement = this.$('.learn-press-content-item-summary');
585
- $newElement.show().insertAfter($oldElement);
586
- $oldElement.detach();
587
- if (this.model.get('show-list')) {
588
- $newElement.find('.lp-group-heading-title').addClass('active');
589
- $newElement.find('.lp-group-content-wrap').removeClass('hide-if-js');
590
- }
591
- this.updateButtons();
592
- if (model.getCurrent('hasShowedHint') === 'yes') {
593
- this.$('.button-hint').attr('disabled', true);
594
- this.$('.question-hint-content').removeClass('hide-if-js');
595
- } else {
596
- this.$('.button-hint').attr('disabled', false);
597
- this.$('.question-hint-content').addClass('hide-if-js');
598
- }
599
- this.start();
600
- $(window).trigger('load');
601
- $(document).trigger('resize');
602
- windowTarget.LP.setUrl(question.get('url'));
603
- windowTarget.LP.unblockContent();
604
- },
605
- _showHint : function (e) {
606
- e.preventDefault();
607
- this.model.current().set('hasShowedHint', 'yes');
608
- this.$('.button-hint').attr('disabled', true);
609
- this.$('.learn-press-question-hint').removeClass('hide-if-js');
610
- },
611
- _showHintCompleted : function (response) {
612
- windowTarget.LP.unblockContent();
613
- },
614
- _checkAnswer : function (e) {
615
- e.preventDefault();
616
- var that = this,
617
- $button = $(e.target),
618
- security = $button.data('security');
619
- windowTarget.LP.blockContent();
620
- this.pause();
621
- this.model.checkAnswer(this._checkAnswerCompleted, $button.data());
622
- },
623
- _checkAnswerCompleted : function (question) {
624
- this.start();
625
- this.$('.button-check-answer, .button-hint').hide();
626
- windowTarget.LP.unblockContent();
627
- },
628
- updateButtons : function () {
629
- if (this.model.get('status') === 'started') {
630
- this.$('.button-prev-question').toggleClass('hide-if-js', this.model.isFirst());
631
- this.$('.button-next-question').toggleClass('hide-if-js', this.model.isLast());
632
- var current = this.model.current();
633
- if (current) {
634
- this.$('.button-check-answer').toggleClass('hide-if-js', current.get('hasCheckAnswer') !== 'yes');
635
- this.$('.button-hint').toggleClass('hide-if-js', current.get('hasHint') !== 'yes');
636
- }
637
- }
638
- },
639
- start : function () {
640
- if (this.model.get('status') != 'started' || this.model.get('totalTime') <= 0) {
641
- return;
642
- }
643
- this.delayTimeout && clearTimeout(this.delayTimeout);
644
- this._onTick();
645
- },
646
- pause : function () {
647
- this.timeout && clearTimeout(this.timeout);
648
- },
649
- incrDelay : function (t) {
650
- if (t) {
651
- this.delayTime = 0;
652
- }
653
- this.delayTimeout && clearTimeout(this.delayTimeout);
654
- this.delayTime++;
655
- this.delayTimeout = setTimeout($.proxy(function () {
656
- this.incrDelay();
657
- }, this), 990);
658
- },
659
- updateCountdown : function () {
660
- var totalTime = this.model.getTotalTime('dhms'),
661
- remainingTime = this.model.getRemainingTime('dhms'),
662
- strTime = [];
663
- if (totalTime.d) {
664
- strTime.push(this._addLeadingZero(remainingTime.d));
665
- }
666
- if (totalTime.h) {
667
- strTime.push(this._addLeadingZero(remainingTime.h));
668
- }
669
- strTime.push(this._addLeadingZero(remainingTime.m));
670
- strTime.push(this._addLeadingZero(remainingTime.s));
671
- var t = parseInt(this.model.get('remainingTime') / this.model.get('totalTime') * 100);// * 360;
672
- this.$('.quiz-countdown').attr('data-value', t).attr('data-' + this.model.get('id'), 100).toggleClass('warning-time-over', t < 10).find('.countdown').html(strTime.join(':'));
673
- },
674
- itemUrl : function (url, item) {
675
- if (item.get('id') == this.model.get('id')) {
676
- var questionName = this.model.getCurrent('name'), reg;
677
- if (questionName && this.model.get('status') !== 'completed') {
678
- reg = new RegExp('!' + questionName + '/?$!', '');
679
- if (!url.match(reg)) {
680
- url = url.replace(/\/$/, '') + '/' + questionName + '/';
681
- }
682
- }
683
-
684
- }
685
- return url;
686
- },
687
- destroy : function () {
688
- this.pause();
689
- LP.Hook.removeAction('learn_press_before_finish_quiz');
690
- LP.Hook.removeFilter('learn_press_get_current_item_url');
691
- },
692
- /********************************/
693
- _submit : function (args) {
694
- var data = {};
695
- data = this.model.getQuizData(data);
696
-
697
- args = $.extend({
698
- security: '',
699
- action : ''
700
- }, args || {});
701
- windowTarget.LP.blockContent();
702
- LP.Hook.doAction('learn_press_before_start_quiz', this.currentItem, this);
703
- var $form = this.$('form.quiz-buttons');
704
- this.model.questions.forEach(function (m) {
705
- var $content = m.get('response');
706
- if (!$content) {
707
- return;
708
- }
709
- var $question = $content.find('.quiz-question-content').clone().hide();
710
- $form.append($question);
711
- });
712
- $form.find('input[name="security"]').val(args.security);
713
- $form.find('input[name="lp-ajax"]').val(args.action);
714
- var extraArgs = _.omit(args, ['security', 'action']);
715
- _.forEach(extraArgs, function (v, k) {
716
- $form.append('<input type="hidden" name="' + k + '" value="' + v + '" />');
717
- });
718
- $form.submit();
719
- },
720
- _confirm : function (localize, onYes, onNo) {
721
- var that = this,
722
- loc = this.localized[localize] || {},
723
- message = loc.message || '',
724
- title = loc.title || '';
725
- windowTarget.jConfirm(message, title, function (confirm) {
726
- if (confirm && $.isFunction(onYes)) {
727
- onYes.call(that);
728
- } else if ($.isFunction(onNo)) {
729
- onNo.call(that);
730
- }
731
- });
732
- },
733
- _startQuiz : function (e) {
734
- var that = this,
735
- $button = $(e.target);
736
- windowTarget.LP.Hook.doAction('learn_press_before_start_quiz', this);
737
- this._submit($button.data());
738
- return false;
739
- },
740
- _finishQuiz : function (e) {
741
- var that = this,
742
- $button = $(e.target);
743
- e.preventDefault();
744
- if (typeof e.originalEvent === 'undefined') {
745
- windowTarget.LP.Hook.doAction('learn_press_before_finish_quiz', this);
746
- that._submit($.extend($button.data(), {auto_finish: 'yes'}));
747
- } else {
748
- this._confirm('confirm_finish_quiz', function () {
749
- windowTarget.LP.Hook.doAction('learn_press_before_finish_quiz', this);
750
- that._submit($button.data());
751
- });
752
- }
753
- return false;
754
- },
755
- _doFinishQuiz : function (security) {
756
- var that = this;
757
- LP.Hook.doAction('learn_press_before_finish_quiz', that.currentItem, that);
758
- that.finishQuiz({
759
- security : security,
760
- beforeSend: windowTarget.LP.blockContent(),
761
- callback : function (response, item) {
762
- windowTarget.LP.unblockContent();
763
- that.$('#learn-press-content-item').html(response.html.content);
764
- windowTarget.LP.setUrl(that.model.get('permalink'));
765
- var data = response.course_result;
766
- data.messageType = 'update-course';
767
- LP.sendMessage(data, windowTarget);
768
- }
769
- });
770
- },
771
- _retakeQuiz : function (e) {
772
- e.preventDefault();
773
- var that = this,
774
- $button = $(e.target);
775
- this._confirm('confirm_retake_quiz', function () {
776
- LP.Hook.doAction('learn_press_before_retake_quiz', this);
777
- that._submit($button.data());
778
- });
779
- return false;
780
- },
781
-
782
- complete : function (args) {
783
- var that = this;
784
- args = $.extend({
785
- context : null,
786
- callback: null,
787
- format : 'json'
788
- }, this.toJSON(), args || {});
789
- var data = {};
790
-
791
- // Omit unwanted fields
792
- _.forEach(args, function (v, k) {
793
- if (($.inArray(k, ['content', 'current', 'title', 'url']) == -1) && !$.isFunction(v)) {
794
- data[k] = v;
795
- }
796
- ;
797
- });
798
- LP.ajax({
799
- url : this.get('url'),
800
- action : 'complete-item',
801
- data : data,
802
- dataType: 'json',
803
- success : function (response) {
804
- ///response = LP.parseJSON(response);
805
- LP.Hook.doAction('learn_press_course_item_completed', response, that);
806
- response = LP.Hook.applyFilters('learn_press_course_item_complete_response', response, that);
807
- $.isFunction(args.callback) && args.callback.call(args.context, response, that);
808
- }
809
- });
810
- },
811
- startQuiz : function (args) {
812
- var args = $.extend({
813
- course_id: this.model.get('courseId'),
814
- quiz_id : this.model.get('id'),
815
- security : null
816
- }, args || {});
817
- var data = this._validateObject(args), that = this;
818
- LP.ajax({
819
- url : this.model.get('url'),
820
- action : 'start-quiz',
821
- data : data,
822
- dataType: 'json',
823
- success : function (response) {
824
- $.isFunction(args.callback) && args.callback.call(args.context, response, that);
825
- }
826
- });
827
- },
828
- finishQuiz : function (args) {
829
- var args = $.extend({
830
- course_id: this.model.get('courseId'),
831
- quiz_id : this.model.get('id'),
832
- security : null
833
- }, args || {});
834
- var data = this._validateObject(args), that = this;
835
- data = LP.Hook.applyFilters('learn_press_finish_quiz_data', data);
836
- var beforeSend = args.beforeSend || function () {
837
- };
838
- LP.ajax({
839
- url : this.model.get('url'),
840
- action : 'finish-quiz',
841
- data : data,
842
- dataType : 'json',
843
- beforeSend: beforeSend,
844
- success : function (response) {
845
- windowTarget.LP.unblockContent();
846
- $.isFunction(args.callback) && args.callback.call(args.context, response, that);
847
- }
848
- });
849
- },
850
- retakeQuiz : function (args) {
851
- var args = $.extend({
852
- course_id: this.model.get('courseId'),
853
- quiz_id : this.model.get('id'),
854
- security : null
855
- }, args || {});
856
- var data = this._validateObject(args), that = this;
857
- LP.ajax({
858
- url : this.model.get('url'),
859
- action : 'retake-quiz',
860
- data : data,
861
- dataType : 'json',
862
- beforeSend: function () {
863
- windowTarget.LP.blockContent();
864
- },
865
- success : function (response) {
866
- windowTarget.LP.unblockContent();
867
- $.isFunction(args.callback) && args.callback.call(args.context, response, that);
868
- }
869
- });
870
- },
871
- _click_nav_link: function ( e ) {
872
- e.preventDefault();
873
- var $button = $(e.target);
874
- var lesson_id = '';
875
- if($button.prop("tagName").toLowerCase()!='a'){
876
- lesson_id = $button.parent().attr('data-id');
877
- } else {
878
- lesson_id = $($button).attr('data-id');
879
- }
880
- $(windowTarget.document).find('.course-item.course-item-'+lesson_id+'.viewable').trigger('click');
881
- },
882
- _toJSON : function () {
883
- // call parent method
884
- var json = Course_Item.__super__.toJSON.apply(this, arguments);
885
- },
886
- _validateObject: function (obj) {
887
- var ret = {};
888
- for (var i in obj) {
889
- if (!$.isFunction(obj[i])) {
890
- ret[i] = obj[i];
891
- }
892
- }
893
- return ret;
894
- }
895
- });
896
-
897
- window.LP_Quiz = Quiz;
898
- $(document).ready(function () {
899
- if (typeof LP_Quiz_Params != 'undefined') {
900
- window.$LP_Quiz = new LP_Quiz($.extend({course: LP.$LP_Course}, LP_Quiz_Params));
901
- }
902
- windowTarget.LP.unblockContent();
903
- });
904
-
 
 
 
 
 
 
 
 
 
 
 
 
905
  })(jQuery);
1
+ /**
2
+ * Single Quiz functions
3
+ *
4
+ * @author ThimPress
5
+ * @package LearnPress/JS
6
+ * @version 1.1
7
+ */
8
+ ;(function ($) {
9
+
10
+ var Quiz = function (args) {
11
+ this.model = new Quiz.Model(args);
12
+ this.view = new Quiz.View({
13
+ model: this.model
14
+ });
15
+ this.destroy = function () {
16
+ this.model.questions.forEach(function (m) {
17
+ try {
18
+ m instanceof Model_Question ? (
19
+ // prevent trigger 'sync' action
20
+ m.set('id', null),
21
+ m.destroy()
22
+ ) : false;
23
+ } catch (ex) {
24
+ console.log(ex);
25
+ }
26
+ });
27
+ this.model.set('id', null);
28
+ this.model.destroy();
29
+ this.view.destroy();
30
+ this.view.undelegateEvents();
31
+ };
32
+ }, Model_Question, List_Questions, windowTarget = parent.window || window;
33
+
34
+ Quiz.Model_Question = Model_Question = Backbone.Model.extend({
35
+ defaults : {
36
+ //question_id: 0
37
+ },
38
+ data : null,
39
+ view : false,
40
+ url : function () {
41
+ return this.urlRoot;
42
+ },
43
+ urlRoot : function () {
44
+ return 'abc';
45
+ },
46
+ initialize: function () {
47
+ },
48
+ element : function () {
49
+ return $(this.get('content'));
50
+ },
51
+ submit : function (args) {
52
+ var that = this;
53
+ args = $.extend({
54
+ complete: null,
55
+ data : {}
56
+ }, args || {});
57
+ this.fetch({
58
+ data : $.extend({
59
+ action : 'learnpress_load_quiz_question',
60
+ user_id : this.get('user_id'),
61
+ quiz_id : this.get('quiz_id'),
62
+ question_id: this.get('id')
63
+ }, args.data || {}),
64
+ complete: (function (e) {
65
+ var response = LP.parseJSON(e.responseText);
66
+ if (response.result == 'success') {
67
+ //if (!that.get('content')) {
68
+ that.set(response.question);
69
+ if (response.permalink) {
70
+ LP.setUrl(response.permalink);
71
+ }
72
+ //}
73
+ $.isFunction(args.complete) && args.complete.call(that, response);
74
+ }
75
+ })
76
+ });
77
+ },
78
+ check : function (args) {
79
+ var that = this;
80
+ if ($.isFunction(args)) {
81
+ args = {
82
+ complete: args
83
+ }
84
+ } else {
85
+ args = $.extend({
86
+ complete: null,
87
+ data : {}
88
+ }, args || {});
89
+ }
90
+ LP.doAjax({
91
+ data : $.extend({
92
+ 'lp-ajax' : 'check-question',
93
+ question_id: this.get('id')
94
+ //question_answer: $('form#learn-press-quiz-question').serializeJSON()
95
+ }, args.data || {}),
96
+ dataType: 'html',
97
+ success : function (response, raw) {
98
+ var $content = that.get('response');
99
+ if ($content) {
100
+ $content.find('.learn-press-question-options').replaceWith($(response).filter('.learn-press-question-options'));
101
+ }
102
+ that.set({checked: 'yes', response: $content});
103
+ $.isFunction(args.complete) && args.complete.call(that, response);
104
+ }
105
+ });
106
+ },
107
+ showHint : function (args) {
108
+ var that = this;
109
+ LP.doAjax({
110
+ data : $.extend({
111
+ 'lp-ajax' : 'get-question-hint',
112
+ user_id : this.get('user_id'),
113
+ quiz_id : this.get('quiz_id'),
114
+ question_id : this.get('id'),
115
+ question_answer: $('form#learn-press-quiz-question').serializeJSON()
116
+ }, args.data || {}),
117
+ success: function (response, raw) {
118
+ that.set('checked', response.checked);
119
+ $.isFunction(args.complete) && args.complete.call(that, response);
120
+ }
121
+ });
122
+ }
123
+ });
124
+ /**
125
+ * List Questions
126
+ */
127
+ Quiz.List_Questions = List_Questions = Backbone.Collection.extend({
128
+ url : 'admin-ajax.php',
129
+ urlRoot : function () {
130
+ return '';
131
+ },
132
+ len : 0,
133
+ model : Model_Question,
134
+ initialize : function () {
135
+ this.on('add', function (model) {
136
+ this.listenTo(model, 'change', this.onChange);
137
+ this.listenTo(model, 'change:hasShowedHint', this.onChangedHint);
138
+ this.listenTo(model, 'change:checked', function (a) {
139
+ if (a.changed['checked'] && a.changed['checked'] === 'yes') {
140
+ var $dom = a.get('response');
141
+ if ($dom) $dom.find('.button-check-answer').attr('disabled', true);
142
+ }
143
+ }, this);
144
+ model.set('index', this.len++);
145
+ }, this);
146
+ this.on('change:view', function () {
147
+ this.questions.view = this.get('view');
148
+ });
149
+
150
+ },
151
+ onChangedHint: function (a, b) {
152
+
153
+ },
154
+ onChange : function (a, b) {
155
+
156
+ if (a.changed['current']) {
157
+ if (a.get('current') !== 'yes') {
158
+
159
+ } else {
160
+ this.current = a;
161
+ for (var i = 0; i < this.length; i++) {
162
+ var e = this.at(i);
163
+ if (e.get('id') == a.get('id')) {
164
+ $('.question-' + e.get('id')).toggleClass('current', true);
165
+ continue;
166
+ }
167
+ if (e.get('current') != 'yes') {
168
+ continue;
169
+ }
170
+ this.stopListening(e, 'change', this.onChange);
171
+ e.set('current', 'no');
172
+ this.listenTo(e, 'change', this.onChange);
173
+ $('.question-' + e.get('id')).toggleClass('current', false)
174
+ }
175
+ try {
176
+ this.view.updateUrl();
177
+ } catch (e) {
178
+ }
179
+ }
180
+ }
181
+ }
182
+ });
183
+
184
+ Quiz.Model = Backbone.Model.extend({
185
+ _args : null,
186
+ questions : null,
187
+ initialize : function (args) {
188
+ _.bindAll(this, 'getQuizData');
189
+ this._args = args || {};
190
+ this.on('change:view', function () {
191
+ this.questions.view = this.get('view');
192
+ });
193
+ this._initQuestions();
194
+ this.set('remainingTime', args.totalTime - args.userTime);
195
+ LP.Hook.addFilter('learn_press_finish_quiz_data', this.getQuizData);
196
+
197
+ this.prepareQuestion( {delayTime: this.delayTime} )
198
+ },
199
+ _initQuestions : function () {
200
+ this.questions = new List_Questions();
201
+ _.forEach(this._args.questions, function (q) {
202
+ this.questions.add(q);
203
+ }, this);
204
+ if (this.questions.length && !this.current()) {
205
+ this.questions.at(0).set('current', 'yes');
206
+ }
207
+ },
208
+ _secondsToDHMS : function (t) {
209
+ var d = Math.floor(t / (24 * 3600)), t = t - d * 24 * 3600, h = Math.floor(t / 3600), t = t - h * 3600, m = Math.floor(t / 60), s = Math.floor(t - m * 60);
210
+ return {d: d, h: h, m: m, s: s}
211
+ },
212
+ getRemainingTime : function (format) {
213
+ var t = this.get('remainingTime');
214
+ if (format == 'dhms') {
215
+ t = this._secondsToDHMS(t);
216
+ }
217
+ return t;
218
+ },
219
+ getTotalTime : function (format) {
220
+ var t = this.get('totalTime');
221
+ if (format == 'dhms') {
222
+ t = this._secondsToDHMS(t);
223
+ }
224
+ return t;
225
+ },
226
+ getUserTime : function (format) {
227
+ var t = this.get('userTime');
228
+ if (format == 'dhms') {
229
+ t = this._secondsToDHMS(t);
230
+ }
231
+ return t;
232
+ },
233
+ inc : function (seconds) {
234
+ var userTime = this.get('userTime') + (seconds || 1);
235
+ var t = {
236
+ userTime : userTime,
237
+ remainingTime: Math.max(this.get('totalTime') - userTime, 0)
238
+ };
239
+ this.set(t);
240
+ return t;
241
+ },
242
+ decr : function (seconds) {
243
+ var userTime = this.get('userTime') - (seconds || 1);
244
+ var t = {
245
+ userTime : userTime,
246
+ remainingTime: Math.max(this.get('totalTime') - userTime, 0)
247
+ };
248
+ this.set(t);
249
+ return t;
250
+ },
251
+ fetchCurrent : function (callback) {
252
+ var current = this.getCurrent(),
253
+ that = this;
254
+ if (!current) {
255
+ return;
256
+ }
257
+ LP.Hook.doAction('learn_press_before_fetch_question', current.get('id'), that);
258
+ $.ajax({
259
+ url : current.get('url'),
260
+ dataType: 'html',
261
+ success : function (response) {
262
+ that.set('response', response);
263
+ $.isFunction(callback) && callback(response, that);
264
+ }
265
+ });
266
+ },
267
+ next : function (callback, args) {
268
+ var next = this.findNext(),
269
+ that = this,
270
+ id = 0;
271
+ if (!next) {
272
+ return;
273
+ }
274
+ id = parseInt(next.get('id'));
275
+ LP.Hook.doAction('learn_press_before_next_question', id, that);
276
+ this.select(id, function (args) {
277
+ LP.Hook.doAction('learn_press_previous_question', id, that);
278
+ callback && callback.apply(null, arguments);
279
+ }, args);
280
+ },
281
+ prev : function (callback, args) {
282
+ var prev = this.findPrev(),
283
+ that = this,
284
+ id = 0;
285
+ if (!prev) {
286
+ return;
287
+ }
288
+ id = prev.get('id');
289
+ LP.Hook.doAction('learn_press_before_previous_question', id, that);
290
+ this.select(id, function () {
291
+ LP.Hook.doAction('learn_press_previous_question', id, that);
292
+ callback && callback.apply(null, arguments);
293
+ }, args);
294
+ },
295
+ select : function (id, callback, args) {
296
+ var question = this.questions.findWhere({id: parseInt(id)}),
297
+ that = this,
298
+ loadedCallback = function () {
299
+ $.isFunction(callback) && callback(question, that);
300
+ LP.Hook.doAction('learn_press_select_question', question, that);
301
+ };
302
+ if (!question) {
303
+ return;
304
+ }
305
+ if (question.get('current') === 'yes') {
306
+ windowTarget.LP.unblockContent();
307
+ return;
308
+ }
309
+ LP.Hook.doAction('learn_press_before_select_question', question, that);
310
+ question.set('current', 'yes');
311
+ if (question.get('response')) {
312
+ loadedCallback();
313
+ $.ajax({
314
+ url : question.get('url'),
315
+ data : $.extend({
316
+ id : question.get('id'),
317
+ 'lp-ajax': 'fetch-question',
318
+ 'lp-update-current-question': true
319
+ }, args || {}),
320
+ dataType: 'html'
321
+ });
322
+ } else {
323
+ $.ajax({
324
+ url : question.get('url'),
325
+ data : $.extend({
326
+ id : question.get('id'),
327
+ data : $('form[name="quiz-question-content"]').serialize(),
328
+ 'lp-ajax': 'fetch-question'
329
+ }, args || {}),
330
+ dataType: 'html',
331
+ success : function (response) {
332
+ var $html = $(response).contents().find('.learn-press-content-item-summary');
333
+ question.set('response', $html);
334
+ loadedCallback();
335
+ }
336
+ });
337
+ }
338
+
339
+ /* Prepare next question & prev question */
340
+ this.prepareQuestion(args)
341
+ },
342
+ prepareQuestion : function (args) {
343
+
344
+ var next = this.findNext(),
345
+ prev = this.findPrev();
346
+
347
+ if (next) {
348
+ this.prepareResponse(parseInt(next.get('id')), args);
349
+ }
350
+ if (prev) {
351
+ this.prepareResponse(parseInt(prev.get('id')), args);
352
+ }
353
+ },
354
+ prepareResponse : function (id, args) {
355
+
356
+ var question = this.questions.findWhere({id: parseInt(id)}),
357
+ currentQuestion = this.current();
358
+
359
+ if (question.get('response')) {
360
+ return;
361
+ }
362
+
363
+ $.ajax({
364
+ url : question.get('url'),
365
+ data : $.extend({
366
+ id : question.get('id'),
367
+ data : $('form[name="quiz-question-content"]').serialize(),
368
+ 'lp-ajax': 'fetch-question',
369
+ 'lp-current-question': currentQuestion.get('id')
370
+
371
+ }, args || {}),
372
+ dataType: 'html',
373
+ success : function (response) {
374
+ var $html = $(response).contents().find('.learn-press-content-item-summary');
375
+ question.set('response', $html);
376
+ }
377
+ });
378
+ },
379
+ getQuestionPosition : function (question_id) {
380
+ question_id = question_id || this.get('question_id');
381
+ return _.indexOf(this.getIds(), question_id);
382
+ },
383
+ countQuestions : function () {
384
+ return this.questions.length;
385
+ },
386
+ isLast : function (question_id) {
387
+ question_id = question_id || this.getCurrent('id');
388
+ var q = this.questions.findWhere({id: parseInt(question_id)});
389
+ return q ? q.get('index') == this.questions.length - 1 : false;
390
+ },
391
+ isFirst : function (question_id) {
392
+ question_id = question_id || this.getCurrent('id');
393
+ var q = this.questions.findWhere({id: parseInt(question_id)});
394
+ return q ? q.get('index') == 0 : false;
395
+ },
396
+ findNext : function (question_id) {
397
+ question_id = question_id || this.getCurrent('id');
398
+ var q = this.questions.findWhere({id: parseInt(question_id)}),
399
+ next = false;
400
+ if (q) {
401
+ var index = q.get('index');
402
+ next = this.questions.at(index + 1);
403
+ }
404
+ return next;
405
+ },
406
+ findPrev : function (question_id) {
407
+ question_id = question_id || this.getCurrent('id');
408
+ var q = this.questions.findWhere({id: parseInt(question_id)}),
409
+ prev = false;
410
+ if (q) {
411
+ var index = q.get('index');
412
+ prev = this.questions.at(index - 1);
413
+ }
414
+ return prev;
415
+ },
416
+ getCurrent : function (_field, _default) {
417
+ var current = this.current(),
418
+ r = _default;
419
+ if (current) {
420
+ r = current.get(_field);
421
+ }
422
+ return r;
423
+ },
424
+ current : function (create) {
425
+ var current = this.questions.findWhere({current: 'yes'});
426
+ if (!current && create) {
427
+ current = new Model_Question();
428
+ }
429
+ return current;
430
+ },
431
+ getIds : function () {
432
+ return $.map(this.get('questions'), function (i, v) {
433
+ return parseInt(i.id);
434
+ });
435
+ },
436
+ showHint : function (callback, args) {
437
+ this.current().showHint({
438
+ complete: callback,
439
+ data : this.getRequestParams(args)
440
+ });
441
+ },
442
+ checkAnswer : function (callback, args) {
443
+ if (!args) {
444
+ args = {};
445
+ }
446
+ args.question_answer = this.getQuestionAnswerData(this.current());
447
+ this.current().check({
448
+ complete: callback,
449
+ data : this.getRequestParams(args)
450
+ });
451
+ },
452
+ getRequestParams : function (args) {
453
+ var defaults = LP.Hook.applyFilters('learn_press_request_quiz_params', {
454
+ quiz_id : this.get('id'),
455
+ user_id : this.get('user_id'),
456
+ course_id: this.get('courseId')
457
+ });
458
+
459
+ return $.extend(defaults, args || {});
460
+ },
461
+ getQuestion : function (thing) {
462
+ var question = false;
463
+ if ($.isNumeric(thing)) {
464
+ question = this.questions.findWhere({id: parseInt(thing)});
465
+ } else if ($.isPlainObject(thing)) {
466
+ question = this.questions.findWhere(thing);
467
+ } else if ($.type(thing) == 'undefined' || $.type(thing) == null) {
468
+ question = this.current();
469
+ } else if (thing instanceof Model_Question) {
470
+ question = thing;
471
+ }
472
+ return question;
473
+ },
474
+ getQuizData : function (data) {
475
+ data.answers = {};
476
+ this.questions.forEach(function (model) {
477
+ data.answers[model.get('id')] = this.getQuestionAnswerData(model);
478
+ }, this);
479
+ return data;
480
+ },
481
+ getQuestionAnswerData: function (question) {
482
+ question = this.getQuestion(question);
483
+ if (!question) {
484
+ return undefined;
485
+ }
486
+ var $html = question.get('response'),
487
+ answer = {},
488
+ $form = $('<form />');
489
+ if ($html) {
490
+ var $content = $html.find('.quiz-question-content');
491
+ $form.html($content.clone());
492
+ answer = $form.serializeJSON();
493
+ }
494
+ return LP.Hook.applyFilters('learn_press_question_answer_data', answer, $form, question, this);
495
+ }
496
+ });
497
+ Quiz.View = Backbone.View.extend({
498
+ el : function () {
499
+ return 'body';
500
+ },
501
+ events : {
502
+ 'click .button-prev-question' : '_prevQuestion',
503
+ 'click .button-next-question' : '_nextQuestion',
504
+ 'click .button-hint' : '_showHint',
505
+ 'click .button-check-answer' : '_checkAnswer',
506
+ 'click .quiz-questions-list .question-title': '_selectQuestion',
507
+ 'click .button-start-quiz' : '_startQuiz',
508
+ 'click .button-finish-quiz' : '_finishQuiz',
509
+ 'click .button-retake-quiz' : '_retakeQuiz',
510
+ 'click .button-complete-item' : '_completeItem',
511
+ 'click #lp-navigation .nav-link a' : '_click_nav_link'
512
+ },
513
+ timeout : 0,
514
+ delayTimeout : 0,
515
+ delayTime : 0,
516
+ localized : null,
517
+ initialize : function () {
518
+ _.bindAll(this, 'pause', '_onTick', 'itemUrl', '_loadQuestionCompleted', '_checkAnswerCompleted', '_checkAnswer', '_onDestroy', 'destroy');
519
+ LP.Hook.addAction('learn_press_before_finish_quiz', this.destroy);
520
+ LP.Hook.addFilter('learn_press_get_current_item_url', this.itemUrl);
521
+ this.model.current(true).set('response', this.$('.learn-press-content-item-summary'));
522
+ this.model.set('view', this);
523
+ this.model.on('destroy', this._onDestroy);
524
+ this._initCountDown();
525
+ this.updateButtons();
526
+ this.windowTarget = windowTarget;
527
+ this.localized = window.learn_press_single_course_localize || {};
528
+ $(document).ready(function () {
529
+ $(window).trigger('load');
530
+ $(document).trigger('resize');
531
+ });
532
+ },
533
+ _initCountDown : function () {
534
+ if (this.model.get('status') != 'started' || this.model.get('totalTime') <= 0) {
535
+ return;
536
+ }
537
+ this.updateCountdown();
538
+ setTimeout($.proxy(function () {
539
+ this.$('.quiz-countdown').removeClass('hide-if-js');
540
+ this.start();
541
+ }, this), 500);
542
+ },
543
+ _addLeadingZero : function (n) {
544
+ return n < 10 ? "0" + n : "" + n;
545
+ },
546
+ _onDestroy : function () {
547
+ this.pause();
548
+ },
549
+ _onTick : function () {
550
+ this.timeout && clearTimeout(this.timeout);
551
+ var timer = this.model.inc();
552
+ this.updateCountdown();
553
+
554
+ if (timer.remainingTime == 0) {
555
+ LP.Hook.doAction('learn_press_quiz_timeout', this);
556
+ this.$('.button-finish-quiz').trigger('click');
557
+ return;
558
+ }
559
+ this.timeout = setTimeout(this._onTick, 1000);
560
+ },
561
+
562
+ _prevQuestion : function (e) {
563
+ e.preventDefault();
564
+ var delayTime = this.delayTime;
565
+ this._beforeFetchQuestion();
566
+ this.model.prev(this._loadQuestionCompleted, {delayTime: delayTime});
567
+ },
568
+ _nextQuestion : function (e) {
569
+ e.preventDefault();
570
+ var delayTime = this.delayTime;
571
+ this._beforeFetchQuestion();
572
+ this.model.next(this._loadQuestionCompleted, {delayTime: delayTime});
573
+
574
+ },
575
+ _selectQuestion : function (e) {
576
+ e.preventDefault();
577
+ if (this.model.get('status') == 'started') {
578
+ var id = $(e.target).closest('li').attr('data-id'),
579
+ delayTime = this.delayTime;
580
+ if (this.model.current().get('id') == id) {
581
+ return;
582
+ }
583
+ this._beforeFetchQuestion();
584
+ this.model.select(id, this._loadQuestionCompleted, {delayTime: delayTime});
585
+ }
586
+ },
587
+ _beforeFetchQuestion : function () {
588
+ windowTarget.LP.blockContent();
589
+ this.pause();
590
+ this.incrDelay(true);
591
+ this.model.current(true).set('response', this.$('.learn-press-content-item-summary'));
592
+ },
593
+ _loadQuestionCompleted: function (question, model) {
594
+ var loaded = model.get('loaded'),
595
+ $newElement = question.get('response'),
596
+ $oldElement = this.$('.learn-press-content-item-summary');
597
+ $newElement.show().insertAfter($oldElement);
598
+ $oldElement.detach();
599
+ if (this.model.get('show-list')) {
600
+ $newElement.find('.lp-group-heading-title').addClass('active');
601
+ $newElement.find('.lp-group-content-wrap').removeClass('hide-if-js');
602
+ }
603
+ this.updateButtons();
604
+ if (model.getCurrent('hasShowedHint') === 'yes') {
605
+ this.$('.button-hint').attr('disabled', true);
606
+ this.$('.question-hint-content').removeClass('hide-if-js');
607
+ } else {
608
+ this.$('.button-hint').attr('disabled', false);
609
+ this.$('.question-hint-content').addClass('hide-if-js');
610
+ }
611
+ this.start();
612
+ $(window).trigger('load');
613
+ $(document).trigger('resize');
614
+ windowTarget.LP.setUrl(question.get('url'));
615
+ windowTarget.LP.unblockContent();
616
+ },
617
+ _showHint : function (e) {
618
+ e.preventDefault();
619
+ this.model.current().set('hasShowedHint', 'yes');
620
+ this.$('.button-hint').attr('disabled', true);
621
+ this.$('.learn-press-question-hint').removeClass('hide-if-js');
622
+ },
623
+ _showHintCompleted : function (response) {
624
+ windowTarget.LP.unblockContent();
625
+ },
626
+ _checkAnswer : function (e) {
627
+ e.preventDefault();
628
+ var that = this,
629
+ $button = $(e.target),
630
+ security = $button.data('security');
631
+ windowTarget.LP.blockContent();
632
+ this.pause();
633
+ this.model.checkAnswer(this._checkAnswerCompleted, $button.data());
634
+ },
635
+ _checkAnswerCompleted : function (question) {
636
+ this.start();
637
+ this.$('.button-check-answer, .button-hint').hide();
638
+ windowTarget.LP.unblockContent();
639
+ },
640
+ updateButtons : function () {
641
+ if (this.model.get('status') === 'started') {
642
+ this.$('.button-prev-question').toggleClass('hide-if-js', this.model.isFirst());
643
+ this.$('.button-next-question').toggleClass('hide-if-js', this.model.isLast());
644
+ var current = this.model.current();
645
+ if (current) {
646
+ this.$('.button-check-answer').toggleClass('hide-if-js', current.get('hasCheckAnswer') !== 'yes');
647
+ this.$('.button-hint').toggleClass('hide-if-js', current.get('hasHint') !== 'yes');
648
+ }
649
+ }
650
+ },
651
+ start : function () {
652
+ if (this.model.get('status') != 'started' || this.model.get('totalTime') <= 0) {
653
+ return;
654
+ }
655
+ this.delayTimeout && clearTimeout(this.delayTimeout);
656
+ this._onTick();
657
+ },
658
+ pause : function () {
659
+ this.timeout && clearTimeout(this.timeout);
660
+ },
661
+ incrDelay : function (t) {
662
+ if (t) {
663
+ this.delayTime = 0;
664
+ }
665
+ this.delayTimeout && clearTimeout(this.delayTimeout);
666
+ this.delayTime++;
667
+ this.delayTimeout = setTimeout($.proxy(function () {
668
+ this.incrDelay();
669
+ }, this), 990);
670
+ },
671
+ updateCountdown : function () {
672
+ var totalTime = this.model.getTotalTime('dhms'),
673
+ remainingTime = this.model.getRemainingTime('dhms'),
674
+ strTime = [];
675
+ if (totalTime.d) {
676
+ strTime.push(this._addLeadingZero(remainingTime.d));
677
+ }
678
+ if (totalTime.h) {
679
+ strTime.push(this._addLeadingZero(remainingTime.h));
680
+ }
681
+ strTime.push(this._addLeadingZero(remainingTime.m));
682
+ strTime.push(this._addLeadingZero(remainingTime.s));
683
+ var t = parseInt(this.model.get('remainingTime') / this.model.get('totalTime') * 100);// * 360;
684
+ this.$('.quiz-countdown').attr('data-value', t).attr('data-' + this.model.get('id'), 100).toggleClass('warning-time-over', t < 10).find('.countdown').html(strTime.join(':'));
685
+ },
686
+ itemUrl : function (url, item) {
687
+ if (item.get('id') == this.model.get('id')) {
688
+ var questionName = this.model.getCurrent('name'), reg;
689
+ if (questionName && this.model.get('status') !== 'completed') {
690
+ reg = new RegExp('!' + questionName + '/?$!', '');
691
+ if (!url.match(reg)) {
692
+ url = url.replace(/\/$/, '') + '/' + questionName + '/';
693
+ }
694
+ }
695
+
696
+ }
697
+ return url;
698
+ },
699
+ destroy : function () {
700
+ this.pause();
701
+ LP.Hook.removeAction('learn_press_before_finish_quiz');
702
+ LP.Hook.removeFilter('learn_press_get_current_item_url');
703
+ },
704
+ /********************************/
705
+ _submit : function (args) {
706
+ var data = {};
707
+ data = this.model.getQuizData(data);
708
+
709
+ args = $.extend({
710
+ security: '',
711
+ action : ''
712
+ }, args || {});
713
+ windowTarget.LP.blockContent();
714
+ LP.Hook.doAction('learn_press_before_start_quiz', this.currentItem, this);
715
+ var $form = this.$('form.quiz-buttons');
716
+ this.model.questions.forEach(function (m) {
717
+ var $content = m.get('response');
718
+ if (!$content) {
719
+ return;
720
+ }
721
+ var $question = $content.find('.quiz-question-content').clone().hide();
722
+ $form.append($question);
723
+ });
724
+ $form.find('input[name="security"]').val(args.security);
725
+ $form.find('input[name="lp-ajax"]').val(args.action);
726
+ var extraArgs = _.omit(args, ['security', 'action']);
727
+ _.forEach(extraArgs, function (v, k) {
728
+ $form.append('<input type="hidden" name="' + k + '" value="' + v + '" />');
729
+ });
730
+ $form.submit();
731
+ },
732
+ _confirm : function (localize, onYes, onNo) {
733
+ var that = this,
734
+ loc = this.localized[localize] || {},
735
+ message = loc.message || '',
736
+ title = loc.title || '';
737
+ windowTarget.jConfirm(message, title, function (confirm) {
738
+ if (confirm && $.isFunction(onYes)) {
739
+ onYes.call(that);
740
+ } else if ($.isFunction(onNo)) {
741
+ onNo.call(that);
742
+ }
743
+ });
744
+ },
745
+ _startQuiz : function (e) {
746
+ var that = this,
747
+ $button = $(e.target);
748
+ windowTarget.LP.Hook.doAction('learn_press_before_start_quiz', this);
749
+ this._submit($button.data());
750
+ return false;
751
+ },
752
+ _finishQuiz : function (e) {
753
+ var that = this,
754
+ $button = $(e.target);
755
+ e.preventDefault();
756
+ if (typeof e.originalEvent === 'undefined') {
757
+ windowTarget.LP.Hook.doAction('learn_press_before_finish_quiz', this);
758
+ that._submit($.extend($button.data(), {auto_finish: 'yes'}));
759
+ } else {
760
+ this._confirm('confirm_finish_quiz', function () {
761
+ windowTarget.LP.Hook.doAction('learn_press_before_finish_quiz', this);
762
+ that._submit($button.data());
763
+ });
764
+ }
765
+ return false;
766
+ },
767
+ _doFinishQuiz : function (security) {
768
+ var that = this;
769
+ LP.Hook.doAction('learn_press_before_finish_quiz', that.currentItem, that);
770
+ that.finishQuiz({
771
+ security : security,
772
+ beforeSend: windowTarget.LP.blockContent(),
773
+ callback : function (response, item) {
774
+ windowTarget.LP.unblockContent();
775
+ that.$('#learn-press-content-item').html(response.html.content);
776
+ windowTarget.LP.setUrl(that.model.get('permalink'));
777
+ var data = response.course_result;
778
+ data.messageType = 'update-course';
779
+ LP.sendMessage(data, windowTarget);
780
+ }
781
+ });
782
+ },
783
+ _retakeQuiz : function (e) {
784
+ e.preventDefault();
785
+ var that = this,
786
+ $button = $(e.target);
787
+ this._confirm('confirm_retake_quiz', function () {
788
+ LP.Hook.doAction('learn_press_before_retake_quiz', this);
789
+ that._submit($button.data());
790
+ });
791
+ return false;
792
+ },
793
+
794
+ complete : function (args) {
795
+ var that = this;
796
+ args = $.extend({
797
+ context : null,
798
+ callback: null,
799
+ format : 'json'
800
+ }, this.toJSON(), args || {});
801
+ var data = {};
802
+
803
+ // Omit unwanted fields
804
+ _.forEach(args, function (v, k) {
805
+ if (($.inArray(k, ['content', 'current', 'title', 'url']) == -1) && !$.isFunction(v)) {
806
+ data[k] = v;
807
+ }
808
+ ;
809
+ });
810
+ LP.ajax({
811
+ url : this.get('url'),
812
+ action : 'complete-item',
813
+ data : data,
814
+ dataType: 'json',
815
+ success : function (response) {
816
+ ///response = LP.parseJSON(response);
817
+ LP.Hook.doAction('learn_press_course_item_completed', response, that);
818
+ response = LP.Hook.applyFilters('learn_press_course_item_complete_response', response, that);
819
+ $.isFunction(args.callback) && args.callback.call(args.context, response, that);
820
+ }
821
+ });
822
+ },
823
+ startQuiz : function (args) {
824
+ var args = $.extend({
825
+ course_id: this.model.get('courseId'),
826
+ quiz_id : this.model.get('id'),
827
+ security : null
828
+ }, args || {});
829
+ var data = this._validateObject(args), that = this;
830
+ LP.ajax({
831
+ url : this.model.get('url'),
832
+ action : 'start-quiz',
833
+ data : data,
834
+ dataType: 'json',
835
+ success : function (response) {
836
+ $.isFunction(args.callback) && args.callback.call(args.context, response, that);
837
+ }
838
+ });
839
+ },
840
+ finishQuiz : function (args) {
841
+ var args = $.extend({
842
+ course_id: this.model.get('courseId'),
843
+ quiz_id : this.model.get('id'),
844
+ security : null
845
+ }, args || {});
846
+ var data = this._validateObject(args), that = this;
847
+ data = LP.Hook.applyFilters('learn_press_finish_quiz_data', data);
848
+ var beforeSend = args.beforeSend || function () {
849
+ };
850
+ LP.ajax({
851
+ url : this.model.get('url'),
852
+ action : 'finish-quiz',
853
+ data : data,
854
+ dataType : 'json',
855
+ beforeSend: beforeSend,
856
+ success : function (response) {
857
+ windowTarget.LP.unblockContent();
858
+ $.isFunction(args.callback) && args.callback.call(args.context, response, that);
859
+ }
860
+ });
861
+ },
862
+ retakeQuiz : function (args) {
863
+ var args = $.extend({
864
+ course_id: this.model.get('courseId'),
865
+ quiz_id : this.model.get('id'),
866
+ security : null
867
+ }, args || {});
868
+ var data = this._validateObject(args), that = this;
869
+ LP.ajax({
870
+ url : this.model.get('url'),
871
+ action : 'retake-quiz',
872
+ data : data,
873
+ dataType : 'json',
874
+ beforeSend: function () {
875
+ windowTarget.LP.blockContent();
876
+ },
877
+ success : function (response) {
878
+ windowTarget.LP.unblockContent();
879
+ $.isFunction(args.callback) && args.callback.call(args.context, response, that);
880
+ }
881
+ });
882
+ },
883
+ _click_nav_link: function ( e ) {
884
+ e.preventDefault();
885
+ var $button = $(e.target);
886
+ var lesson_id = '';
887
+ if($button.prop("tagName").toLowerCase()!='a'){
888
+ lesson_id = $button.parent().attr('data-id');
889
+ } else {
890
+ lesson_id = $($button).attr('data-id');
891
+ }
892
+ $(windowTarget.document).find('.course-item.course-item-'+lesson_id+'.viewable').trigger('click');
893
+ },
894
+ _toJSON : function () {
895
+ // call parent method
896
+ var json = Course_Item.__super__.toJSON.apply(this, arguments);
897
+ },
898
+ _validateObject: function (obj) {
899
+ var ret = {};
900
+ for (var i in obj) {
901
+ if (!$.isFunction(obj[i])) {
902
+ ret[i] = obj[i];
903
+ }
904
+ }
905
+ return ret;
906
+ }
907
+ });
908
+
909
+ window.LP_Quiz = Quiz;
910
+ $(document).ready(function () {
911
+ if (typeof LP_Quiz_Params != 'undefined') {
912
+ window.$LP_Quiz = new LP_Quiz($.extend({course: LP.$LP_Course}, LP_Quiz_Params));
913
+ }
914
+ windowTarget.LP.unblockContent();
915
+ });
916
+
917
  })(jQuery);
assets/js/global.js CHANGED
@@ -749,7 +749,7 @@ if (typeof window.LP == 'undefined') {
749
  };
750
  return data ? tmpl(data) : tmpl;
751
  }, function (a, b) {
752
- return JSON.stringify(b);
753
  }),
754
  alert : function (localize, callback) {
755
  var title = '',
@@ -984,30 +984,6 @@ if (typeof window.LP == 'undefined') {
984
  }
985
  });
986
 
987
- var filter = 'all',
988
- user_process = $('.course-summary .course-students-list .students-enrolled'),
989
- additional_student = $('.course-summary .additional-students');
990
- $('#students-list-filter').change(function () {
991
- var filter = ($(this)).val();
992
-
993
- if (filter == 'all') {
994
- user_process.css('display', 'inline-block');
995
- additional_student.css('display', 'block');
996
- }
997
- else {
998
- additional_student.css('display', 'none');
999
- $.each(user_process, function () {
1000
- if (!$(this).hasClass(filter)) {
1001
- $(this).css('display', 'none');
1002
- } else {
1003
- $(this).css('display', 'inline-block');
1004
- }
1005
- });
1006
- }
1007
- }
1008
- );
1009
-
1010
-
1011
  //$(window).on("message onmessage", LP.receiveMessage, false);
1012
  window.addEventListener("message", LP.receiveMessage, false);
1013
  });
749
  };
750
  return data ? tmpl(data) : tmpl;
751
  }, function (a, b) {
752
+ return a + '-' + JSON.stringify(b);
753
  }),
754
  alert : function (localize, callback) {
755
  var title = '',
984
  }
985
  });
986
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
987
  //$(window).on("message onmessage", LP.receiveMessage, false);
988
  window.addEventListener("message", LP.receiveMessage, false);
989
  });
inc/admin/class-lp-admin-ajax.php CHANGED
@@ -1,1139 +1,1139 @@
1
- <?php
2
-
3
- if ( !defined( 'ABSPATH' ) ) {
4
- exit; // Exit if accessed directly
5
- }
6
- if ( !class_exists( 'LP_Admin_Ajax' ) ) {
7
-
8
- /**
9
- * Class LP_Admin_Ajax
10
- */
11
- class LP_Admin_Ajax {
12
- /**
13
- * Add action ajax
14
- */
15
- public static function init() {
16
- $ajaxEvents = array(
17
- 'create_page' => false,
18
- 'add_quiz_question' => false,
19
- 'convert_question_type' => false,
20
- 'update_quiz_question_state' => false,
21
- 'update_editor_hidden' => false,
22
- 'update_curriculum_section_state' => false,
23
- 'quick_add_item' => false,
24
- 'add_new_item' => false,
25
- 'toggle_lesson_preview' => false,
26
- 'remove_course_items' => false,
27
- 'search_courses' => false,
28
- 'add_item_to_order' => false,
29
- 'remove_order_item' => false,
30
- 'plugin_action' => false,
31
- 'search_questions' => false,
32
- 'remove_quiz_question' => false,
33
- 'modal_search_items' => false,
34
- 'add_item_to_section' => false,
35
- 'remove_course_section' => false,
36
- 'dismiss_notice' => false,
37
- 'search_users' => false,
38
- 'load_chart' => false,
39
- 'search_course' => false,
40
- 'search_course_category' => false,
41
- /////////////
42
- 'quick_add_lesson' => false,
43
- 'quick_add_quiz' => false,
44
- 'be_teacher' => false,
45
- 'custom_stats' => false,
46
- 'ignore_setting_up' => false,
47
- 'get_page_permalink' => false,
48
- 'dummy_image' => false,
49
- 'update_add_on_status' => false,
50
- 'plugin_install' => false,
51
- 'bundle_activate_add_ons' => false,
52
- 'install_sample_data' => false,
53
- // Duplicate Course
54
- 'duplicate_course' => false,
55
- 'duplicate_question' => false,
56
- // Remove Notice
57
- 'remove_notice_popup' => false
58
-
59
-
60
- );
61
- foreach ( $ajaxEvents as $ajaxEvent => $nopriv ) {
62
- add_action( 'wp_ajax_learnpress_' . $ajaxEvent, array( __CLASS__, $ajaxEvent ) );
63
- // enable for non-logged in users
64
- if ( $nopriv ) {
65
- add_action( 'wp_ajax_nopriv_learnpress_' . $ajaxEvent, array( __CLASS__, $ajaxEvent ) );
66
- }
67
- }
68
- add_filter( 'learn_press_modal_search_items_exclude', array( __CLASS__, '_modal_search_items_exclude' ), 10, 4 );
69
- add_filter( 'learn_press_modal_search_items_not_found', array( __CLASS__, '_modal_search_items_not_found' ), 10, 2 );
70
- do_action( 'learn_press_admin_ajax_load', __CLASS__ );
71
- }
72
-
73
- public static function load_chart() {
74
- if ( !class_exists( '' ) ) {
75
- require_once LP_PLUGIN_PATH . '/inc/admin/sub-menus/statistics.php';
76
- }
77
- LP_Admin_Submenu_Statistic::instance()->load_chart();
78
- }
79
-
80
- public static function search_course() {
81
- global $wpdb;
82
- $sql = "SELECT ID id, post_title text "
83
- . " FROM {$wpdb->posts} "
84
- . " WHERE post_type='lp_course' "
85
- . " AND post_status in ('publish') "
86
- . " AND post_title like %s";
87
- if ( current_user_can( LP_TEACHER_ROLE ) ) {
88
- $user_id = learn_press_get_current_user_id();
89
- $sql .= " AND post_author=" . intval( $user_id ) . " ";
90
- }
91
- $s = '%' . filter_input( INPUT_GET, 'q' ) . '%';
92
- $query = $wpdb->prepare( $sql, $s );
93
- $items = $wpdb->get_results( $query );
94
- $data = array( 'items' => $items );
95
- echo json_encode( $data );
96
- exit();
97
- }
98
-
99
- public static function search_course_category() {
100
- global $wpdb;
101
- $sql = "SELECT `t`.`term_id` as `id`, "
102
- . " `t`.`name` `text` "
103
- . " FROM {$wpdb->terms} t "
104
- . " INNER JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id AND taxonomy='course_category' "
105
- . " WHERE `t`.`name` LIKE %s";
106
- $s = '%' . filter_input( INPUT_GET, 'q' ) . '%';
107
- $query = $wpdb->prepare( $sql, $s );
108
- $items = $wpdb->get_results( $query );
109
- $data = array( 'items' => $items );
110
- echo json_encode( $data );
111
- exit();
112
- }
113
-
114
- public static function remove_course_items() {
115
- $id = learn_press_get_request( 'id' );
116
- if ( $id ) {
117
- global $wpdb;
118
- $in_clause = array_fill( 0, sizeof( $id ), '%d' );
119
- $in_clause = "IN(" . join( ",", $in_clause ) . ")";
120
- echo $wpdb->prepare( "
121
- DELETE FROM {$wpdb->prefix}learnpress_section_items
122
- WHERE section_item_id $in_clause
123
- ", $id );
124
- $wpdb->query(
125
- $wpdb->prepare( "
126
- DELETE FROM {$wpdb->prefix}learnpress_section_items
127
- WHERE section_item_id $in_clause
128
- ", $id )
129
- );
130
- }
131
- die();
132
- }
133
-
134
- public static function search_users() {
135
- if ( !current_user_can( 'edit_lp_orders' ) ) {
136
- die( - 1 );
137
- }
138
-
139
- $term = stripslashes( $_GET['term'] );
140
-
141
- if ( empty( $term ) ) {
142
- die();
143
- }
144
-
145
- $found_customers = array();
146
-
147
- add_action( 'pre_user_query', array( __CLASS__, 'json_search_customer_name' ) );
148
-
149
- $customers_query = new WP_User_Query( apply_filters( 'learn_press_search_customers_query', array(
150
- 'fields' => 'all',
151
- 'orderby' => 'display_name',
152
- 'search' => '*' . $term . '*',
153
- 'search_columns' => array( 'ID', 'user_login', 'user_email', 'user_nicename' )
154
- ) ) );
155
-
156
- remove_action( 'pre_user_query', array( __CLASS__, 'json_search_customer_name' ) );
157
-
158
- $customers = $customers_query->get_results();
159
-
160
- if ( !empty( $customers ) ) {
161
- foreach ( $customers as $customer ) {
162
- $found_customers[] = array(
163
- 'label' => $customer->display_name . ' (#' . $customer->ID . ' &ndash; ' . sanitize_email( $customer->user_email ) . ')',
164
- 'value' => $customer->ID
165
- );
166
- }
167
- }
168
-
169
- echo json_encode( $found_customers );
170
- die();
171
- }
172
-
173
- public static function json_search_customer_name( $query ) {
174
- global $wpdb;
175
-
176
- $term = stripslashes( $_GET['term'] );
177
- if ( method_exists( $wpdb, 'esc_like' ) ) {
178
- $term = $wpdb->esc_like( $term );
179
- } else {
180
- $term = like_escape( $term );
181
- }
182
-
183
- $query->query_from .= " INNER JOIN {$wpdb->usermeta} AS user_name ON {$wpdb->users}.ID = user_name.user_id AND ( user_name.meta_key = 'first_name' OR user_name.meta_key = 'last_name' ) ";
184
- $query->query_where .= $wpdb->prepare( " OR user_name.meta_value LIKE %s ", '%' . $term . '%' );
185
- }
186
-
187
- public static function dismiss_notice() {
188
- $context = learn_press_get_request( 'context' );
189
- $transient = learn_press_get_request( 'transient' );
190
-
191
- if ( $context ) {
192
- if ( $transient >= 0 ) {
193
- set_transient( 'learn_press_dismiss_notice_' . $context, 'off', $transient ? $transient : DAY_IN_SECONDS * 7 );
194
- } else {
195
- update_option( 'learn_press_dismiss_notice_' . $context, 'off' );
196
- }
197
- }
198
- die();
199
- }
200
-
201
- public static function _modal_search_items_not_found( $message, $type ) {
202
- switch ( $type ) {
203
- case 'lp_lesson':
204
- $message = __( 'There are no available lessons for this course, please use ', 'learnpress' );
205
- $message .= '<a target="_blank" href="' . admin_url( 'post-new.php?post_type=lp_lesson' ) . '">' . esc_html__( 'Adding New Item.', 'learnpress' ) . '</a>';
206
- break;
207
- case 'lp_quiz':
208
- $message = __( 'There are no available quizzes for this course, please use ', 'learnpress' );
209
- $message .= '<a target="_blank" href="' . admin_url( 'post-new.php?post_type=lp_quiz' ) . '">' . esc_html__( 'Adding New Item.', 'learnpress' ) . '</a>';
210
- break;
211
- case 'lp_question':
212
- $message = __( 'There are no available questions for this quiz, please use ', 'learnpress' );
213
- $message .= '<a target="_blank" href="' . admin_url( 'post-new.php?post_type=lp_question' ) . '">' . esc_html__( 'Adding New Item.', 'learnpress' ) . '</a>';
214
- break;
215
- }
216
- return $message;
217
- }
218
-
219
- public static function _modal_search_items_exclude( $exclude, $type, $context = '', $context_id = null ) {
220
- global $wpdb;
221
- $exclude2 = array();
222
- $user = learn_press_get_current_user();
223
- switch ( $type ) {
224
- case 'lp_lesson':
225
- case 'lp_quiz':
226
- $query = $wpdb->prepare( "
227
- SELECT item_id
228
- FROM {$wpdb->prefix}learnpress_section_items
229
- WHERE %d
230
- ", 1 );
231
- $exclude2 = $wpdb->get_col( $query );
232
- if ( ( $context == 'course' ) && ( get_post_type( $context_id ) == 'lp_course' ) ) {
233
- $course_author = get_post_field( 'post_author', $context_id );
234
- }
235
- break;
236
- case 'lp_question':
237
- $query = $wpdb->prepare( "
238
- SELECT question_id
239
- FROM {$wpdb->prefix}learnpress_quiz_questions
240
- WHERE %d
241
- ", 1 );
242
- $exclude2 = $wpdb->get_col( $query );
243
- break;
244
-
245
- }
246
- if ( $exclude2 && $exclude ) {
247
- $exclude = array_merge( $exclude, $exclude2 );
248
- } else if ( $exclude2 ) {
249
- $exclude = $exclude2;
250
- }
251
- return $exclude;
252
- }
253
-
254
- public static function add_item_to_section() {
255
- global $wpdb;
256
- $section = learn_press_get_request( 'section' );
257
- if ( !$section ) {
258
- wp_die( __( 'Error', 'learnpress' ) );
259
- }
260
- $items = (array) learn_press_get_request( 'item' );
261
- if ( !$items ) {
262
- $max_order = $wpdb->get_var( $wpdb->prepare( "SELECT max() FROM {$wpdb}learnpress_section_items WHERE section_id = %d", $section ) );
263
- foreach ( $items as $item ) {
264
-
265
- }
266
- }
267
- }
268
-
269
- public static function modal_search_items() {
270
- global $wpdb;
271
-
272
- $user = learn_press_get_current_user();
273
- $term = (string) ( stripslashes( learn_press_get_request( 'term' ) ) );
274
- $type = (string) ( stripslashes( learn_press_get_request( 'type' ) ) );
275
- $context = (string) ( stripslashes( learn_press_get_request( 'context' ) ) );
276
- $context_id = (string) ( stripslashes( learn_press_get_request( 'context_id' ) ) );
277
- $exclude = array();
278
-
279
- if ( !empty( $_GET['exclude'] ) ) {
280
- $exclude = array_map( 'intval', $_GET['exclude'] );
281
- }
282
- $exclude = array_unique( (array) apply_filters( 'learn_press_modal_search_items_exclude', $exclude, $type, $context, $context_id ) );
283
- $exclude = array_map( 'intval', $exclude );
284
- $args = array(
285
- 'post_type' => array( $type ),
286
- 'posts_per_page' => - 1,
287
- 'post_status' => 'publish',
288
- 'order' => 'ASC',
289
- 'orderby' => 'parent title',
290
- 'exclude' => $exclude
291
- );
292
- if ( !$user->is_admin() ) {
293
- $args['author'] = $user->id;
294
- }
295
-
296
- if ( $context && $context_id ) {
297
- switch ( $context ) {
298
- /**
299
- * If is search lesson/quiz for course only search the items of course's author
300
- */
301
- case 'course-items':
302
- if ( get_post_type( $context_id ) == 'lp_course' ) {
303
- $args['author'] = get_post_field( 'post_author', $context_id );
304
- }
305
- break;
306
- /**
307
- * If is search question for quiz only search the items of course's author
308
- */
309
- case 'quiz-items':
310
- if ( get_post_type( $context_id ) == 'lp_quiz' ) {
311
- $args['author'] = get_post_field( 'post_author', $context_id );
312
- }
313
- break;
314
- }
315
- }
316
- if ( $term ) {
317
- $args['s'] = $term;
318
- }
319
-
320
- $posts = get_posts( $args );
321
- $found_items = array();
322
-
323
- if ( !empty( $posts ) ) {
324
- foreach ( $posts as $post ) {
325
- $found_items[$post->ID] = $post;
326
- $found_items[$post->ID]->post_title = !empty( $post->post_title ) ? $post->post_title : sprintf( '(%s)', __( 'Untitled', 'learnpress' ) );
327
- }
328
- }
329
-
330
- ob_start();
331
- if ( $found_items ) {
332
- foreach ( $found_items as $id => $item ) {
333
- printf( '
334
- <li class="" data-id="%1$d" data-type="%3$s" data-text="%2$s">
335
- <label>
336
- <input type="checkbox" value="%1$d">
337
- <span class="lp-item-text">%2$s</span>
338
- </label>
339
- </li>
340
- ', $id, esc_attr( $item->post_title ), $item->post_type );
341
- }
342
- } else {
343
- echo '<li>' . apply_filters( 'learn_press_modal_search_items_not_found', __( 'No item found', 'learnpress' ), $type ) . '</li>';
344
- }
345
-
346
- $item_object = $type ? get_post_type_object( $type ) : '';
347
- $post_type = $context_id ? get_post_type_object( get_post_type( $context_id ) ) : '';
348
- $response = array(
349
- 'html' => ob_get_clean(),
350
- 'data' => $found_items,
351
- 'notices' => '<div class="learnpress-search-notices notice notice-warning" data-post-type="' . esc_attr( $item_object->name ) . '" data-user="' . esc_attr( $user->id ) . '">' . sprintf( '<p>' . __( 'A ', 'learnpress' ) . '<span style="text-transform: lowercase;">%s</span>' . __( ' is just used for only one ', 'learnpress' ) . '<span style="text-transform: lowercase;">%s</span></p>', $item_object->labels->singular_name, $post_type->labels->singular_name ) . '<a class="learnpress-dismiss-notice"></a></div>'
352
- );
353
- $dismiss_notice = 'learnpress_notice_' . $item_object->name . '_' . $user->id;
354
- $dismiss_notice = get_transient( $dismiss_notice );
355
- if ( $dismiss_notice || $item_object->name === 'lp_course' ) { // Check lp_course to hidden notice in order post
356
- unset( $response['notices'] );
357
- }
358
-
359
- learn_press_send_json( $response );
360
- }
361
-
362
- public static function remove_quiz_question() {
363
- global $wpdb;
364
- $quiz_id = learn_press_get_request( 'quiz_id' );
365
- $question_id = learn_press_get_request( 'question_id' );
366
- if ( !wp_verify_nonce( learn_press_get_request( 'remove-nonce' ), 'remove_quiz_question' ) ) {
367
- wp_die( __( 'Error', 'learnpress' ) );
368
- }
369
- $query = $wpdb->prepare( "
370
- DELETE FROM {$wpdb->prefix}learnpress_quiz_questions
371
- WHERE quiz_id = %d
372
- AND question_id = %d
373
- ", $quiz_id, $question_id );
374
- $wpdb->query( $query );
375
-
376
- // trigger change user memorize question types
377
- $user_id = get_current_user_id();
378
- $type = get_post_meta( $question_id, '_lp_type', true );
379
- if ( $type ) {
380
- $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
381
- $question_types = !$question_types ? array() : $question_types;
382
- $counter = !empty ( $question_types[$type] ) && $question_types[$type] ? absint( $question_types[$type] ) : 0;
383
- $question_types[$type] = $counter ? $counter -- : 0;
384
- update_user_meta( $user_id, '_learn_press_memorize_question_types', $question_types );
385
- }
386
- // end trigger change user memorize question types
387
- die();
388
- }
389
-
390
- public static function search_questions() {
391
- global $wpdb;
392
-
393
- $quiz_id = learn_press_get_request( 'quiz_id' );
394
- $user = learn_press_get_current_user();
395
- if ( !$user->is_admin() && get_post_field( 'post_author', $quiz_id ) != get_current_user_id() ) {
396
- wp_die( __( 'You have no permission to access this section.', 'learnpress' ) );
397
- }
398
- $term = (string) ( stripslashes( learn_press_get_request( 'term' ) ) );
399
- $exclude = array();
400
-
401
- if ( !empty( $_GET['exclude'] ) ) {
402
- $exclude = array_map( 'intval', $_GET['exclude'] );
403
- }
404
-
405
- $added = $wpdb->get_col(
406
- $wpdb->prepare( "
407
- SELECT question_id
408
- FROM {$wpdb->prefix}learnpress_quiz_questions
409
- WHERE %d
410
- ", 1 )
411
- );
412
- if ( $added ) {
413
- $exclude = array_merge( $exclude, $added );
414
- $exclude = array_unique( $exclude );
415
- }
416
-
417
- $args = array(
418
- 'post_type' => array( 'lp_question' ),
419
- 'posts_per_page' => - 1,
420
- 'post_status' => 'publish',
421
- 'order' => 'ASC',
422
- 'orderby' => 'parent title',
423
- 'exclude' => $exclude
424
- );
425
- if ( !$user->is_admin() ) {
426
- $args['author'] = $user->id;
427
- }
428
- if ( $term ) {
429
- $args['s'] = $term;
430
- }
431
- $posts = get_posts( $args );
432
- $found_questions = array();
433
-
434
- if ( !empty( $posts ) ) {
435
- foreach ( $posts as $post ) {
436
- $found_questions[$post->ID] = !empty( $post->post_title ) ? $post->post_title : sprintf( '(%s)', __( 'Untitled', 'learnpress' ) );
437
- }
438
- }
439
-
440
- ob_start();
441
- if ( $found_questions ) {
442
- foreach ( $found_questions as $id => $question ) {
443
- printf( '
444
- <li class="" data-id="%1$d" data-type="" data-text="%2$s">
445
- <label>
446
- <input type="checkbox" value="%1$d">
447
- <span class="lp-item-text">%2$s</span>
448
- </label>
449
- </li>
450
- ', $id, $question );
451
- }
452
- } else {
453
- echo '<li>' . __( 'No questions found', 'learnpress' ) . '</li>';
454
- }
455
-
456
- $response = array(
457
- 'html' => ob_get_clean(),
458
- 'data' => $found_questions,
459
- 'args' => $args
460
- );
461
- learn_press_send_json( $response );
462
- }
463
-
464
- public static function plugin_action() {
465
- $url = learn_press_get_request( 'url' );
466
- ob_start();
467
- wp_remote_get( $url );
468
- ob_get_clean();
469
- echo wp_remote_get( admin_url( 'admin.php?page=learn-press-addons&tab=installed' ) );
470
- die();
471
- }
472
-
473
- /**
474
- * Remove an item from order
475
- */
476
- public static function remove_order_item() {
477
- // ensure that user has permission
478
- if ( !current_user_can( 'edit_lp_orders' ) ) {
479
- die( __( 'Permission denied', 'learnpress' ) );
480
- }
481
-
482
- // verify nonce
483
- $nonce = learn_press_get_request( 'remove_nonce' );
484
- if ( !wp_verify_nonce( $nonce, 'remove_order_item' ) ) {
485
- die( __( 'Check nonce failed', 'learnpress' ) );
486
- }
487
-
488
- // validate order
489
- $order_id = learn_press_get_request( 'order_id' );
490
- if ( !is_numeric( $order_id ) || get_post_type( $order_id ) != 'lp_order' ) {
491
- die( __( 'Order invalid', 'learnpress' ) );
492
- }
493
-
494
- // validate item
495
- $item_id = learn_press_get_request( 'item_id' );
496
- $post = get_post( learn_press_get_order_item_meta( $item_id, '_course_id' ) );
497
- if ( !$post || ( 'lp_course' !== $post->post_type ) ) {
498
- die( __( 'Course invalid', 'learnpress' ) );
499
- }
500
-
501
- learn_press_remove_order_item( $item_id );
502
-
503
- $order_data = learn_press_update_order_items( $order_id );
504
- $currency_symbol = learn_press_get_currency_symbol( $order_data['currency'] );
505
- $order_data['subtotal_html'] = learn_press_format_price( $order_data['subtotal'], $currency_symbol );
506
- $order_data['total_html'] = learn_press_format_price( $order_data['total'], $currency_symbol );
507
-
508
-
509
- learn_press_send_json(
510
- array(
511
- 'result' => 'success',
512
- 'order_data' => $order_data
513
- )
514
- );
515
- }
516
-
517
- /**
518
- * Add new course to order
519
- */
520
- public static function add_item_to_order() {
521
-
522
- // ensure that user has permission
523
- if ( !current_user_can( 'edit_lp_orders' ) ) {
524
- die( __( 'Permission denied', 'learnpress' ) );
525
- }
526
-
527
- // verify nonce
528
- // $nonce = learn_press_get_request( 'nonce' );
529
- // if ( !wp_verify_nonce( $nonce, 'add_item_to_order' ) ) {
530
- // die( __( 'Check nonce failed', 'learnpress' ) );
531
- // }
532
-
533
- // validate order
534
- $order_id = learn_press_get_request( 'order_id' );
535
- if ( !is_numeric( $order_id ) || get_post_type( $order_id ) != 'lp_order' ) {
536
- die( __( 'Order invalid', 'learnpress' ) );
537
- }
538
-
539
- // validate item
540
- $item_ids = learn_press_get_request( 'item_id' );
541
- $item_html = '';
542
- $order_data = array();
543
- // $order = learn_press_get_order( $order_id );
544
-
545
- // echo '<pre>'.print_r($item_ids, true).'</pre>';
546
- // exit(''.__LINE__);
547
- foreach ( $item_ids as $item_id ):
548
- $post = get_post( $item_id );
549
- if ( !$post || ( 'lp_course' !== $post->post_type ) ) {
550
- continue;
551
- // die( __( 'Course invalid', 'learnpress' ) );
552
- }
553
- $course = learn_press_get_course( $post->ID );
554
- $item = array(
555
- 'course_id' => $course->id,
556
- 'name' => $course->get_title(),
557
- 'quantity' => 1,
558
- 'subtotal' => $course->get_price(),
559
- 'total' => $course->get_price()
560
- );
561
-
562
- // Add item
563
- $item_id = learn_press_add_order_item( $order_id, array(
564
- 'order_item_name' => $item['name']
565
- ) );
566
-
567
- $item['id'] = $item_id;
568
-
569
- // Add item meta
570
- if ( $item_id ) {
571
- $item = apply_filters( 'learn_press_ajax_order_item', $item );
572
-
573
- learn_press_add_order_item_meta( $item_id, '_course_id', $item['course_id'] );
574
- learn_press_add_order_item_meta( $item_id, '_quantity', $item['quantity'] );
575
- learn_press_add_order_item_meta( $item_id, '_subtotal', $item['subtotal'] );
576
- learn_press_add_order_item_meta( $item_id, '_total', $item['total'] );
577
-
578
- do_action( 'learn_press_ajax_add_order_item_meta', $item );
579
- }
580
-
581
- $order_data = learn_press_update_order_items( $order_id );
582
- $currency_symbol = learn_press_get_currency_symbol( $order_data['currency'] );
583
- $order_data['subtotal_html'] = learn_press_format_price( $order_data['subtotal'], $currency_symbol );
584
- $order_data['total_html'] = learn_press_format_price( $order_data['total'], $currency_symbol );
585
-
586
- ob_start();
587
- include learn_press_get_admin_view( 'meta-boxes/order/order-item.php' );
588
- $item_html .= ob_get_clean();
589
- endforeach;
590
-
591
-
592
- learn_press_send_json(
593
- array(
594
- 'result' => 'success',
595
- 'item_html' => $item_html,
596
- 'order_data' => $order_data
597
- )
598
- );
599
- }
600
-
601
- public static function search_courses() {
602
- $nonce = learn_press_get_request( 'nonce' );
603
- if ( !wp_verify_nonce( $nonce, 'search_item_term' ) ) {
604
- LP_Debug::exception( __( 'Verify nonce failed', 'learnpress' ) );
605
- }
606
-
607
- $term = learn_press_get_request( 'term' );
608
- $exclude = learn_press_get_request( 'exclude' );
609
-
610
- $posts = learn_press_get_all_courses(
611
- array(
612
- 'term' => $term,
613
- 'exclude' => $exclude
614
- )
615
- );
616
- $found_courses = array();
617
- if ( !empty( $posts ) ) {
618
- foreach ( $posts as $post ) {
619
- $found_courses[$post] = array(
620
- 'title' => get_the_title( $post ),
621
- 'permalink' => get_the_permalink( $post )
622
- );
623
- }
624
- }
625
-
626
- $found_courses = apply_filters( 'learn_press_json_search_found_courses', $found_courses );
627
-
628
- learn_press_send_json( $found_courses );
629
- }
630
-
631
- public static function remove_course_section() {
632
- $id = learn_press_get_request( 'id' );
633
- if ( $id ) {
634
- global $wpdb;
635
- $query = $wpdb->prepare( "
636
- DELETE FROM {$wpdb->prefix}learnpress_section_items
637
- WHERE section_id = %d
638
- ", $id );
639
- $wpdb->query( $query );
640
- learn_press_reset_auto_increment( 'learnpress_section_items' );
641
- $query = $wpdb->prepare( "
642
- DELETE FROM {$wpdb->prefix}learnpress_sections
643
- WHERE section_id = %d
644
- ", $id );
645
- $wpdb->query( $query );
646
- learn_press_reset_auto_increment( 'learnpress_sections' );
647
- }
648
- die();
649
- }
650
-
651
- public static function toggle_lesson_preview() {
652
- $id = learn_press_get_request( 'lesson_id' );
653
- if ( get_post_type( $id ) == 'lp_lesson' && wp_verify_nonce( learn_press_get_request( 'nonce' ), 'learn-press-toggle-lesson-preview' ) ) {
654
- $previewable = learn_press_get_request( 'previewable' );
655
- if ( is_null( $previewable ) ) {
656
- $previewable = '0';
657
- }
658
- update_post_meta( $id, '_lp_preview', $previewable );
659
- }
660
- die();
661
- }
662
-
663
- public static function add_new_item() {
664
- $post_type = learn_press_get_request( 'type' );
665
- $post_title = learn_press_get_request( 'name' );
666
- $response = array();
667
- if ( $post_type && $post_title ) {
668
- $args = compact( 'post_title', 'post_type' );
669
- $args['post_status'] = 'publish';
670
- $item_id = wp_insert_post( $args );
671
- if ( $item_id ) {
672
- LP_Lesson_Post_Type::create_default_meta( $item_id );
673
- $item = get_post( $item_id );
674
- $response['post'] = $item;
675
- $response['post']->edit_link = get_edit_post_link( $item_id );
676
- }
677
- }
678
- learn_press_send_json( $response );
679
- }
680
-
681
- public static function quick_add_item() {
682
- $post_type = learn_press_get_request( 'type' );
683
- $post_title = learn_press_get_request( 'name' );
684
- $response = array();
685
- if ( $post_type && $post_title ) {
686
- $args = compact( 'post_title', 'post_type' );
687
- $args['post_status'] = 'publish';
688
- $item_id = wp_insert_post( $args );
689
- if ( $item_id ) {
690
- $item = get_post( $item_id );
691
- $response['post'] = $item;
692
- $response['html'] = sprintf( '<li class="" data-id="%1$d" data-type="%2$s" data-text="%3$s">
693
- <label>
694
- <input type="checkbox" value="%1$d">
695
- <span class="lp-item-text">%3$s</span>
696
- </label>
697
- </li>', $item->ID, $item->post_type, $item->post_title );
698
- }
699
- }
700
- learn_press_send_json( $response );
701
- }
702
-
703
- public static function update_editor_hidden() {
704
- if ( $id = learn_press_get_request( 'course_id' ) ) {
705
- if ( learn_press_get_request( 'is_hidden' ) ) {
706
- update_post_meta( $id, '_lp_editor_hidden', 'yes' );
707
- } else {
708
- delete_post_meta( $id, '_lp_editor_hidden' );
709
- }
710
- }
711
- learn_press_send_json( $_POST );
712
- }
713
-
714
- public static function update_quiz_question_state() {
715
- $hidden = learn_press_get_request( 'hidden' );
716
- $post = learn_press_get_request( 'quiz_id' );
717
- update_post_meta( $post, '_admin_hidden_questions', $hidden );
718
- die();
719
- }
720
-
721
- public static function update_curriculum_section_state() {
722
- $hidden = learn_press_get_request( 'hidden' );
723
- $post = learn_press_get_request( 'course_id' );
724
- update_post_meta( $post, '_admin_hidden_sections', $hidden );
725
- die();
726
- }
727
-
728
- /**
729
- * Create a new page with the title passed via $_REQUEST
730
- */
731
- public static function create_page() {
732
- $page_name = !empty( $_REQUEST['page_name'] ) ? $_REQUEST['page_name'] : '';
733
- $response = array();
734
- if ( $page_name ) {
735
- $args = array(
736
- 'post_type' => 'page',
737
- 'post_title' => $page_name,
738
- 'post_status' => 'publish'
739
- );
740
- $page_id = wp_insert_post( $args );
741
-
742
- if ( $page_id ) {
743
- $response['page'] = get_page( $page_id );
744
- $html = learn_press_pages_dropdown( '', '', array( 'echo' => false ) );
745
- preg_match_all( '!value=\"([0-9]+)\"!', $html, $matches );
746
- $response['positions'] = $matches[1];
747
- $response['html'] = '<a href="' . get_edit_post_link( $page_id ) . '" target="_blank">' . __( 'Edit Page', 'learnpress' ) . '</a>&nbsp;';
748
- $response['html'] .= '<a href="' . get_permalink( $page_id ) . '" target="_blank">' . __( 'View Page', 'learnpress' ) . '</a>';
749
- } else {
750
- $response['error'] = __( 'Error! Create page failed. Please try again!', 'learnpress' );
751
- }
752
- } else {
753
- $response['error'] = __( 'Empty page name!', 'learnpress' );
754
- }
755
- learn_press_send_json( $response );
756
- die();
757
- }
758
-
759
- public static function add_quiz_question() {
760
- global $post;
761
- $id = learn_press_get_request( 'id' );
762
- $quiz_id = learn_press_get_request( 'quiz_id' );
763
- $type = learn_press_get_request( 'type' );
764
- $name = learn_press_get_request( 'name' );
765
- $user_id = get_current_user_id();
766
- $response = array(
767
- 'id' => $id
768
- );
769
- $post = get_post( $quiz_id );
770
- setup_postdata( $post );
771
- if ( !$id ) {
772
- $id = wp_insert_post(
773
- array(
774
- 'post_title' => $name,
775
- 'post_type' => LP_QUESTION_CPT,
776
- 'post_status' => 'publish'
777
- )
778
- );
779
- if ( $id ) {
780
- add_post_meta( $id, '_lp_type', $type );
781
- }
782
- $response['id'] = $id;
783
- }
784
- if ( $id && $quiz_id ) {
785
- global $wpdb;
786
- $max_order = $wpdb->get_var( $wpdb->prepare( "SELECT max(question_order) FROM {$wpdb->prefix}learnpress_quiz_questions WHERE quiz_id = %d", $quiz_id ) );
787
- $wpdb->insert(
788
- $wpdb->prefix . 'learnpress_quiz_questions',
789
- array(
790
- 'quiz_id' => $quiz_id,
791
- 'question_id' => $id,
792
- 'question_order' => $max_order + 1
793
- ),
794
- array( '%d', '%d', '%d' )
795
- );
796
- ob_start();
797
- $question = LP_Question_Factory::get_question( $id );
798
- learn_press_admin_view( 'meta-boxes/quiz/question.php', array( 'question' => $question ) );
799
- $response['html'] = ob_get_clean();
800
-
801
- // trigger change user memorize question types
802
- $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
803
- $question_types = !$question_types ? array() : $question_types;
804
- $type = get_post_meta( $id, '_lp_type', true );
805
- $question_types[$type] = !empty ( $question_types[$type] ) ? absint( $question_types[$type] ) + 1 : 1;
806
- update_user_meta( $user_id, '_learn_press_memorize_question_types', $question_types );
807
- // end trigger change user memorize question types
808
- }
809
- learn_press_send_json( $response );
810
- die();
811
- }
812
-
813
- public static function convert_question_type() {
814
- if ( ( $from = learn_press_get_request( 'from' ) ) && ( $to = learn_press_get_request( 'to' ) ) && $question_id = learn_press_get_request( 'question_id' ) ) {
815
- $data = array();
816
- parse_str( $_POST['data'], $data );
817
-
818
- do_action( 'learn_press_convert_question_type', $question_id, $from, $to, $data );
819
- $question = LP_Question_Factory::get_question( $question_id, array( 'type' => $to ) );
820
-
821
- // trigger change user memorize question types
822
- $user_id = get_current_user_id();
823
- $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
824
- $question_types[$from] = !empty( $question_types[$from] ) && $question_types[$from] ? absint( $question_types[$from] ) - 1 : 0;
825
- $question_types[$to] = !empty( $question_types[$to] ) && $question_types[$to] ? absint( $question_types[$to] ) + 1 : 1;
826
- update_user_meta( $user_id, '_learn_press_memorize_question_types', $question_types );
827
- // end trigger change user memorize question types
828
-
829
- learn_press_send_json(
830
- array(
831
- 'html' => $question->admin_interface( array( 'echo' => false ) ),
832
- 'icon' => $question->get_icon()
833
- )
834
- );
835
- } else {
836
- //throw new Exception( __( 'Convert question type must be specify the id, source and destination type', 'learnpress' ) );
837
- throw new Exception( __( 'Something went wrong! Please try again or ask <a href="https://wordpress.org/support/">support forums</a>.', 'learnpress' ) );
838
- }
839
- die();
840
- }
841
-
842
- /*******************************************************************************************************/
843
-
844
- /**
845
- * Install sample data or dismiss the notice depending on user's option
846
- */
847
- public static function install_sample_data() {
848
- $yes = !empty( $_REQUEST['yes'] ) ? $_REQUEST['yes'] : '';
849
- $response = array( 'result' => 'fail' );
850
- $retry_button = sprintf( '<a href="" class="button yes" data-action="yes">%s</a>', __( 'Try again!', 'learnpress' ) );
851
- $dismiss_button = sprintf( '<a href="" class="button disabled no" data-action="no">%s</a>', __( 'Cancel', 'learnpress' ) );
852
- $buttons = sprintf( '<p>%s %s</p>', $retry_button, $dismiss_button );
853
- if ( 'no' == $yes ) {
854
- set_transient( 'learn_press_install_sample_data', 'off', 12 * HOUR_IN_SECONDS );
855
- } else {
856
- $result = array( 'status' => 'activate' );//learn_press_install_and_active_add_on( 'learnpress-import-export' );
857
- if ( 'activate' == $result['status'] ) {
858
- // copy dummy-data.xml to import folder of the add-on
859
- lpie_mkdir( lpie_import_path() );
860
- if ( file_exists( lpie_import_path() ) ) {
861
- $import_source = LP_PLUGIN_PATH . '/dummy-data/dummy-data.xml';
862
- $file = 'dummy-data-' . time() . '.xml';
863
- $copy = lpie_import_path() . '/' . $file;
864
- copy( $import_source, $copy );
865
- if ( file_exists( $copy ) ) {
866
- $url = admin_url( 'admin-ajax.php?page=learn_press_import_export&tab=import-course' );
867
- $postdata = array(
868
- 'step' => 2,
869
- 'action' => 'learn_press_import',
870
- 'import-file' => 'import/' . $file,
871
- 'nonce' => wp_create_nonce( 'lpie-import-file' ),
872
- 'x' => 1
873
- );
874
- $response['url'] = $url = $url . '&' . http_build_query( $postdata ) . "\n";
875
- $response['result'] = 'success';
876
- $response['message'] = sprintf( '<p>%s <a href="edit.php?post_type=lp_course">%s</a> </p>', __( 'Import sample data successes.', 'learnpress' ), __( 'View courses', 'learnpress' ) );
877
- }
878
- }
879
- if ( $response['result'] == 'fail' ) {
880
- $response['message'] = sprintf( '<p>%s</p>%s', __( 'Import sample data failed. Please try again!.', 'learnpress' ), $buttons );
881
- }
882
- } else {
883
- $response['result'] = 'fail';
884
- $response['message'] = sprintf( '<p>%s</p>', __( 'Unknown error when installing/activating Import/Export addon. Please try again!', 'learnpress' ) ) . $buttons;
885
- }
886
- }
887
- learn_press_send_json( $response );
888
- die();
889
- }
890
-
891
- /**
892
- * Activate a bundle of add-ons, if an add-on is not installed then install it first
893
- */
894
- public static function bundle_activate_add_ons() {
895
- global $learn_press_add_ons;
896
- include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); //for plugins_api..
897
- $response = array( 'addons' => array() );
898
-
899
- if ( !current_user_can( 'activate_plugins' ) ) {
900
- $response['error'] = __( 'You do not have sufficient permissions to deactivate plugins for this site.', 'learnpress' );
901
- } else {
902
-
903
- $add_ons = $learn_press_add_ons['bundle_activate'];
904
-
905
- if ( $add_ons ) {
906
- foreach ( $add_ons as $slug ) {
907
- $response['addons'][$slug] = learn_press_install_and_active_add_on( $slug );
908
- }
909
- }
910
- }
911
- learn_press_send_json( $response );
912
- }
913
-
914
- /**
915
- * Activate a bundle of add-ons, if an add-on is not installed then install it first
916
- */
917
- public static function bundle_activate_add_on() {
918
- $response = array();
919
- include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); //for plugins_api..
920
- if ( !current_user_can( 'activate_plugins' ) ) {
921
- $response['error'] = __( 'You do not have sufficient permissions to deactivate plugins for this site.', 'learnpress' );
922
- } else {
923
- $slug = !empty( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : null;
924
- $response[$slug] = learn_press_install_and_active_add_on( $slug );
925
- }
926
- learn_press_send_json( $response );
927
- }
928
-
929
- public static function plugin_install() {
930
- $plugin_name = !empty( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
931
- $response = learn_press_install_add_on( $plugin_name );
932
- learn_press_send_json( $response );
933
- die();
934
- }
935
-
936
- public static function update_add_on_status() {
937
- $plugin = !empty( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
938
- $t = !empty( $_REQUEST['t'] ) ? $_REQUEST['t'] : '';
939
- $response = array();
940
- if ( !current_user_can( 'activate_plugins' ) ) {
941
- $response['error'] = __( 'You do not have sufficient permissions to deactivate plugins for this site.', 'learnpress' );
942
- }
943
- if ( $plugin && $t ) {
944
- if ( $t == 'activate' ) {
945
- activate_plugin( $plugin, false, is_network_admin() );
946
- } else {
947
- deactivate_plugins( $plugin, false, is_network_admin() );
948
- }
949
- $is_activate = is_plugin_active( $plugin );
950
- $response['status'] = $is_activate ? 'activate' : 'deactivate';
951
-
952
- }
953
- wp_send_json( $response );
954
- die();
955
- }
956
-
957
- /**
958
- * Output the image to browser with text and params passed via $_GET
959
- */
960
- public static function dummy_image() {
961
- $text = !empty( $_REQUEST['text'] ) ? $_REQUEST['text'] : '';
962
- learn_press_text_image( $text, $_GET );
963
- die();
964
- }
965
-
966
- /**
967
- * Get edit|view link of a page
968
- */
969
- public static function get_page_permalink() {
970
- $page_id = !empty( $_REQUEST['page_id'] ) ? $_REQUEST['page_id'] : '';
971
- ?>
972
- <a href="<?php echo get_edit_post_link( $page_id ); ?>" target="_blank"><?php _e( 'Edit Page', 'learnpress' ); ?></a>
973
- <a href="<?php echo get_permalink( $page_id ); ?>" target="_blank"><?php _e( 'View Page', 'learnpress' ); ?></a>
974
- <?php
975
- die();
976
- }
977
-
978
-
979
- /**
980
- *
981
- */
982
- public function custom_stats() {
983
- $from = !empty( $_REQUEST['from'] ) ? $_REQUEST['from'] : 0;
984
- $to = !empty( $_REQUEST['to'] ) ? $_REQUEST['to'] : 0;
985
- $date_diff = strtotime( $to ) - strtotime( $from );
986
- if ( $date_diff <= 0 || $from == 0 || $to == 0 ) {
987
- die();
988
- }
989
- learn_press_process_chart( learn_press_get_chart_students( $to, 'days', floor( $date_diff / ( 60 * 60 * 24 ) ) + 1 ) );
990
- die();
991
- }
992
-
993
- /**
994
- * Quick add lesson with only title
995
- */
996
- public static function quick_add_lesson() {
997
-
998
- $lesson_title = $_POST['lesson_title'];
999
-
1000
- $new_lesson = array(
1001
- 'post_title' => wp_strip_all_tags( $lesson_title ),
1002
- 'post_type' => LP_LESSON_CPT,
1003
- 'post_status' => 'publish'
1004
- );
1005
-
1006
- wp_insert_post( $new_lesson );
1007
-
1008
- $args = array(
1009
- 'numberposts' => 1,
1010
- 'post_type' => LP_LESSON_CPT,
1011
- 'post_status' => 'publish'
1012
- );
1013
- $lesson = wp_get_recent_posts( $args );
1014
- $lesson_id = $lesson[0]['ID'];
1015
- $data = array(
1016
- 'id' => $lesson_id,
1017
- 'title' => $lesson_title
1018
- );
1019
- wp_send_json( $data );
1020
- die;
1021
- }
1022
-
1023
- /**
1024
- * Add a new quiz with the title only
1025
- */
1026
- public static function quick_add_quiz() {
1027
- $quiz_title = $_POST['quiz_title'];
1028
-
1029
- $new_quiz = array(
1030
- 'post_title' => wp_strip_all_tags( $quiz_title ),
1031
- 'post_type' => LP_QUIZ_CPT,
1032
- 'post_status' => 'publish'
1033
- );
1034
-
1035
- wp_insert_post( $new_quiz );
1036
-
1037
- $args = array(
1038
- 'numberposts' => 1,
1039
- 'post_type' => LP_QUIZ_CPT,
1040
- 'post_status' => 'publish'
1041
- );
1042
- $quiz = wp_get_recent_posts( $args );
1043
- $quiz_id = $quiz[0]['ID'];
1044
- $data = array(
1045
- 'id' => $quiz_id,
1046
- 'title' => $quiz_title
1047
- );
1048
- wp_send_json( $data );
1049
- die;
1050
- }
1051
-
1052
- public static function be_teacher() {
1053
- $user_id = get_current_user_id();
1054
- $be_teacher = new WP_User( $user_id );
1055
- $be_teacher->set_role( LP_TEACHER_ROLE );
1056
- die;
1057
- }
1058
-
1059
- public static function ignore_setting_up() {
1060
- update_option( '_lpr_ignore_setting_up', 1, true );
1061
- die;
1062
- }
1063
-
1064
- public static function duplicate_course() {
1065
- if ( empty( $_POST['course_id'] ) || empty( $_POST['_nonce'] ) || !wp_verify_nonce( $_POST['_nonce'], 'lp-duplicate-course' ) ) {
1066
- return;
1067
- }
1068
- global $wpdb;
1069
- $course_id = absint( $_POST['course_id'] );
1070
- $force = !empty( $_POST['content'] ) && $_POST['content'] ? true : false;
1071
-
1072
- $results = array(
1073
- 'redirect' => admin_url( 'edit.php?post_type=' . LP_COURSE_CPT )
1074
- );
1075
- $new_course_id = learn_press_duplicate_course( $course_id, $force );
1076
- if ( is_wp_error( $course_id ) ) {
1077
- LP_Admin_Notice::add_redirect( $course_id->get_error_message(), 'error' );
1078
- } else {
1079
- LP_Admin_Notice::add_redirect( sprintf( '<strong>%s</strong> %s', get_the_title( $course_id ), __( ' course has duplicated', 'learnpress' ) ), 'updated' );
1080
- $results['redirect'] = admin_url( 'post.php?post=' . $new_course_id . '&action=edit' );
1081
- }
1082
-
1083
- wp_send_json( $results );
1084
- die();
1085
- }
1086
-
1087
- public static function duplicate_question() {
1088
- if ( empty( $_POST['_nonce'] ) || !wp_verify_nonce( $_POST['_nonce'], 'duplicate-question' ) ) {
1089
- return;
1090
- }
1091
- global $wpdb;
1092
- $question_id = learn_press_get_request( 'question-id' );
1093
- $quiz_id = learn_press_get_request( 'quiz-id' );
1094
- $user_id = learn_press_get_current_user_id();
1095
-
1096
- $new_question_id = learn_press_duplicate_question( $question_id, $quiz_id );
1097
- if ( !is_wp_error( $new_question_id ) ) {
1098
- ob_start();
1099
- $question = LP_Question_Factory::get_question( $new_question_id );
1100
- $post = get_post( $quiz_id );
1101
- setup_postdata( $post );
1102
- _learn_press_setup_question( $new_question_id );
1103
- learn_press_admin_view( 'meta-boxes/quiz/question.php', array( 'question' => $question ) );
1104
- $response['html'] = ob_get_clean();
1105
-
1106
- // trigger change user memorize question types
1107
- $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
1108
- $question_types = !$question_types ? array() : $question_types;
1109
- $type = get_post_meta( $new_question_id, '_lp_type', true );
1110
- $question_types[$type] = !empty ( $question_types[$type] ) ? absint( $question_types[$type] ) + 1 : 1;
1111
- update_user_meta( $user_id, '_learn_press_memorize_question_types', $question_types );
1112
- // end trigger change user memorize question types
1113
- learn_press_send_json( $response );
1114
-
1115
-
1116
- die();
1117
- }
1118
- }
1119
-
1120
- public static function remove_notice_popup() {
1121
-
1122
- if ( isset( $_POST['action'] ) && $_POST['action'] === 'learnpress_remove_notice_popup'
1123
- && isset( $_POST['slug'] ) && !empty( $_POST['slug'] )
1124
- && isset( $_POST['user'] ) && !empty( $_POST['user'] )
1125
- ) {
1126
-
1127
- $slug = 'learnpress_notice_' . $_POST['slug'] . '_' . $_POST['user'];
1128
-
1129
- set_transient( $slug, true, 30 * DAY_IN_SECONDS );
1130
- }
1131
-
1132
- wp_die();
1133
-
1134
- }
1135
-
1136
- }
1137
- }
1138
- LP_Admin_Ajax::init();
1139
-
1
+ <?php
2
+
3
+ if ( !defined( 'ABSPATH' ) ) {
4
+ exit; // Exit if accessed directly
5
+ }
6
+ if ( !class_exists( 'LP_Admin_Ajax' ) ) {
7
+
8
+ /**
9
+ * Class LP_Admin_Ajax
10
+ */
11
+ class LP_Admin_Ajax {
12
+ /**
13
+ * Add action ajax
14
+ */
15
+ public static function init() {
16
+ $ajaxEvents = array(
17
+ 'create_page' => false,
18
+ 'add_quiz_question' => false,
19
+ 'convert_question_type' => false,
20
+ 'update_quiz_question_state' => false,
21
+ 'update_editor_hidden' => false,
22
+ 'update_curriculum_section_state' => false,
23
+ 'quick_add_item' => false,
24
+ 'add_new_item' => false,
25
+ 'toggle_lesson_preview' => false,
26
+ 'remove_course_items' => false,
27
+ 'search_courses' => false,
28
+ 'add_item_to_order' => false,
29
+ 'remove_order_item' => false,
30
+ 'plugin_action' => false,
31
+ 'search_questions' => false,
32
+ 'remove_quiz_question' => false,
33
+ 'modal_search_items' => false,
34
+ 'add_item_to_section' => false,
35
+ 'remove_course_section' => false,
36
+ 'dismiss_notice' => false,
37
+ 'search_users' => false,
38
+ 'load_chart' => false,
39
+ 'search_course' => false,
40
+ 'search_course_category' => false,
41
+ /////////////
42
+ 'quick_add_lesson' => false,
43
+ 'quick_add_quiz' => false,
44
+ 'be_teacher' => false,
45
+ 'custom_stats' => false,
46
+ 'ignore_setting_up' => false,
47
+ 'get_page_permalink' => false,
48
+ 'dummy_image' => false,
49
+ 'update_add_on_status' => false,
50
+ 'plugin_install' => false,
51
+ 'bundle_activate_add_ons' => false,
52
+ 'install_sample_data' => false,
53
+ // Duplicate Course
54
+ 'duplicate_course' => false,
55
+ 'duplicate_question' => false,
56
+ // Remove Notice
57
+ 'remove_notice_popup' => false
58
+ );
59
+ foreach ( $ajaxEvents as $ajaxEvent => $nopriv ) {
60
+ add_action( 'wp_ajax_learnpress_' . $ajaxEvent, array( __CLASS__, $ajaxEvent ) );
61
+ // enable for non-logged in users
62
+ if ( $nopriv ) {
63
+ add_action( 'wp_ajax_nopriv_learnpress_' . $ajaxEvent, array( __CLASS__, $ajaxEvent ) );
64
+ }
65
+ }
66
+ add_filter( 'learn_press_modal_search_items_exclude', array( __CLASS__, '_modal_search_items_exclude' ), 10, 4 );
67
+ add_filter( 'learn_press_modal_search_items_not_found', array( __CLASS__, '_modal_search_items_not_found' ), 10, 2 );
68
+ do_action( 'learn_press_admin_ajax_load', __CLASS__ );
69
+ }
70
+
71
+ public static function load_chart() {
72
+ if ( !class_exists( '' ) ) {
73
+ require_once LP_PLUGIN_PATH . '/inc/admin/sub-menus/statistics.php';
74
+ }
75
+ LP_Admin_Submenu_Statistic::instance()->load_chart();
76
+ }
77
+
78
+ public static function search_course() {
79
+ global $wpdb;
80
+ $sql = "SELECT ID id, post_title text "
81
+ . " FROM {$wpdb->posts} "
82
+ . " WHERE post_type='lp_course' "
83
+ . " AND post_status in ('publish') "
84
+ . " AND post_title like %s";
85
+ if ( current_user_can( LP_TEACHER_ROLE ) ) {
86
+ $user_id = learn_press_get_current_user_id();
87
+ $sql .= " AND post_author=" . intval( $user_id ) . " ";
88
+ }
89
+ $s = '%' . filter_input( INPUT_GET, 'q' ) . '%';
90
+ $query = $wpdb->prepare( $sql, $s );
91
+ $items = $wpdb->get_results( $query );
92
+ $data = array( 'items' => $items );
93
+ echo json_encode( $data );
94
+ exit();
95
+ }
96
+
97
+ public static function search_course_category() {
98
+ global $wpdb;
99
+ $sql = "SELECT `t`.`term_id` as `id`, "
100
+ . " `t`.`name` `text` "
101
+ . " FROM {$wpdb->terms} t "
102
+ . " INNER JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id AND taxonomy='course_category' "
103
+ . " WHERE `t`.`name` LIKE %s";
104
+ $s = '%' . filter_input( INPUT_GET, 'q' ) . '%';
105
+ $query = $wpdb->prepare( $sql, $s );
106
+ $items = $wpdb->get_results( $query );
107
+ $data = array( 'items' => $items );
108
+ echo json_encode( $data );
109
+ exit();
110
+ }
111
+
112
+ public static function remove_course_items() {
113
+ $id = learn_press_get_request( 'id' );
114
+ if ( $id ) {
115
+ global $wpdb;
116
+ $in_clause = array_fill( 0, sizeof( $id ), '%d' );
117
+ $in_clause = "IN(" . join( ",", $in_clause ) . ")";
118
+ echo $wpdb->prepare( "
119
+ DELETE FROM {$wpdb->prefix}learnpress_section_items
120
+ WHERE section_item_id $in_clause
121
+ ", $id );
122
+ $wpdb->query(
123
+ $wpdb->prepare( "
124
+ DELETE FROM {$wpdb->prefix}learnpress_section_items
125
+ WHERE section_item_id $in_clause
126
+ ", $id )
127
+ );
128
+ }
129
+ die();
130
+ }
131
+
132
+ public static function search_users() {
133
+ if ( !current_user_can( 'edit_lp_orders' ) ) {
134
+ die( - 1 );
135
+ }
136
+
137
+ $term = stripslashes( $_GET['term'] );
138
+
139
+ if ( empty( $term ) ) {
140
+ die();
141
+ }
142
+
143
+ $found_customers = array();
144
+
145
+ add_action( 'pre_user_query', array( __CLASS__, 'json_search_customer_name' ) );
146
+
147
+ $customers_query = new WP_User_Query( apply_filters( 'learn_press_search_customers_query', array(
148
+ 'fields' => 'all',
149
+ 'orderby' => 'display_name',
150
+ 'search' => '*' . $term . '*',
151
+ 'search_columns' => array( 'ID', 'user_login', 'user_email', 'user_nicename' )
152
+ ) ) );
153
+
154
+ remove_action( 'pre_user_query', array( __CLASS__, 'json_search_customer_name' ) );
155
+
156
+ $customers = $customers_query->get_results();
157
+
158
+ if ( !empty( $customers ) ) {
159
+ foreach ( $customers as $customer ) {
160
+ $found_customers[] = array(
161
+ 'label' => $customer->display_name . ' (#' . $customer->ID . ' &ndash; ' . sanitize_email( $customer->user_email ) . ')',
162
+ 'value' => $customer->ID
163
+ );
164
+ }
165
+ }
166
+
167
+ echo json_encode( $found_customers );
168
+ die();
169
+ }
170
+
171
+ public static function json_search_customer_name( $query ) {
172
+ global $wpdb;
173
+
174
+ $term = stripslashes( $_GET['term'] );
175
+ if ( method_exists( $wpdb, 'esc_like' ) ) {
176
+ $term = $wpdb->esc_like( $term );
177
+ } else {
178
+ $term = like_escape( $term );
179
+ }
180
+
181
+ $query->query_from .= " INNER JOIN {$wpdb->usermeta} AS user_name ON {$wpdb->users}.ID = user_name.user_id AND ( user_name.meta_key = 'first_name' OR user_name.meta_key = 'last_name' ) ";
182
+ $query->query_where .= $wpdb->prepare( " OR user_name.meta_value LIKE %s ", '%' . $term . '%' );
183
+ }
184
+
185
+ public static function dismiss_notice() {
186
+ $context = learn_press_get_request( 'context' );
187
+ $transient = learn_press_get_request( 'transient' );
188
+
189
+ if ( $context ) {
190
+ if ( $transient >= 0 ) {
191
+ set_transient( 'learn_press_dismiss_notice_' . $context, 'off', $transient ? $transient : DAY_IN_SECONDS * 7 );
192
+ } else {
193
+ update_option( 'learn_press_dismiss_notice_' . $context, 'off' );
194
+ }
195
+ }
196
+ die();
197
+ }
198
+
199
+ public static function _modal_search_items_not_found( $message, $type ) {
200
+ switch ( $type ) {
201
+ case 'lp_lesson':
202
+ $message = __( 'There are no available lessons for this course, please use ', 'learnpress' );
203
+ $message .= '<a target="_blank" href="' . admin_url( 'post-new.php?post_type=lp_lesson' ) . '">' . esc_html__( 'Adding New Item.', 'learnpress' ) . '</a>';
204
+ break;
205
+ case 'lp_quiz':
206
+ $message = __( 'There are no available quizzes for this course, please use ', 'learnpress' );
207
+ $message .= '<a target="_blank" href="' . admin_url( 'post-new.php?post_type=lp_quiz' ) . '">' . esc_html__( 'Adding New Item.', 'learnpress' ) . '</a>';
208
+ break;
209
+ case 'lp_question':
210
+ $message = __( 'There are no available questions for this quiz, please use ', 'learnpress' );
211
+ $message .= '<a target="_blank" href="' . admin_url( 'post-new.php?post_type=lp_question' ) . '">' . esc_html__( 'Adding New Item.', 'learnpress' ) . '</a>';
212
+ break;
213
+ }
214
+ return $message;
215
+ }
216
+
217
+ public static function _modal_search_items_exclude( $exclude, $type, $context = '', $context_id = null ) {
218
+ global $wpdb;
219
+ $exclude2 = array();
220
+ $user = learn_press_get_current_user();
221
+ switch ( $type ) {
222
+ case 'lp_lesson':
223
+ case 'lp_quiz':
224
+ $query = $wpdb->prepare( "
225
+ SELECT item_id
226
+ FROM {$wpdb->prefix}learnpress_section_items
227
+ WHERE %d
228
+ ", 1 );
229
+ $exclude2 = $wpdb->get_col( $query );
230
+ if ( ( $context == 'course' ) && ( get_post_type( $context_id ) == 'lp_course' ) ) {
231
+ $course_author = get_post_field( 'post_author', $context_id );
232
+ }
233
+ break;
234
+ case 'lp_question':
235
+ $query = $wpdb->prepare( "
236
+ SELECT question_id
237
+ FROM {$wpdb->prefix}learnpress_quiz_questions
238
+ WHERE %d
239
+ ", 1 );
240
+ $exclude2 = $wpdb->get_col( $query );
241
+ break;
242
+
243
+ }
244
+ if ( $exclude2 && $exclude ) {
245
+ $exclude = array_merge( $exclude, $exclude2 );
246
+ } else if ( $exclude2 ) {
247
+ $exclude = $exclude2;
248
+ }
249
+ return $exclude;
250
+ }
251
+
252
+ public static function add_item_to_section() {
253
+ global $wpdb;
254
+ $section = learn_press_get_request( 'section' );
255
+ if ( !$section ) {
256
+ wp_die( __( 'Error', 'learnpress' ) );
257
+ }
258
+ $items = (array) learn_press_get_request( 'item' );
259
+ if ( !$items ) {
260
+ $max_order = $wpdb->get_var( $wpdb->prepare( "SELECT max() FROM {$wpdb}learnpress_section_items WHERE section_id = %d", $section ) );
261
+ foreach ( $items as $item ) {
262
+
263
+ }
264
+ }
265
+ }
266
+
267
+ public static function modal_search_items() {
268
+ global $wpdb;
269
+
270
+ $user = learn_press_get_current_user();
271
+ $term = (string) ( stripslashes( learn_press_get_request( 'term' ) ) );
272
+ $type = (string) ( stripslashes( learn_press_get_request( 'type' ) ) );
273
+ $context = (string) ( stripslashes( learn_press_get_request( 'context' ) ) );
274
+ $context_id = (string) ( stripslashes( learn_press_get_request( 'context_id' ) ) );
275
+ $exclude = array();
276
+
277
+ if ( !empty( $_GET['exclude'] ) ) {
278
+ $exclude = array_map( 'intval', $_GET['exclude'] );
279
+ }
280
+ $exclude = array_unique( (array) apply_filters( 'learn_press_modal_search_items_exclude', $exclude, $type, $context, $context_id ) );
281
+ $exclude = array_map( 'intval', $exclude );
282
+ $args = array(
283
+ 'post_type' => array( $type ),
284
+ 'posts_per_page' => - 1,
285
+ 'post_status' => 'publish',
286
+ 'order' => 'ASC',
287
+ 'orderby' => 'parent title',
288
+ 'exclude' => $exclude
289
+ );
290
+ if ( !$user->is_admin() ) {
291
+ $args['author'] = $user->id;
292
+ }
293
+
294
+ if ( $context && $context_id ) {
295
+ switch ( $context ) {
296
+ /**
297
+ * If is search lesson/quiz for course only search the items of course's author
298
+ */
299
+ case 'course-items':
300
+ if ( get_post_type( $context_id ) == 'lp_course' ) {
301
+ $args['author'] = get_post_field( 'post_author', $context_id );
302
+ }
303
+ break;
304
+ /**
305
+ * If is search question for quiz only search the items of course's author
306
+ */
307
+ case 'quiz-items':
308
+ if ( get_post_type( $context_id ) == 'lp_quiz' ) {
309
+ $args['author'] = get_post_field( 'post_author', $context_id );
310
+ }
311
+ break;
312
+ }
313
+ }
314
+ if ( $term ) {
315
+ $args['s'] = $term;
316
+ }
317
+
318
+ $posts = get_posts( $args );
319
+ $found_items = array();
320
+
321
+ if ( !empty( $posts ) ) {
322
+ foreach ( $posts as $post ) {
323
+ $found_items[$post->ID] = $post;
324
+ $found_items[$post->ID]->post_title = !empty( $post->post_title ) ? $post->post_title : sprintf( '(%s)', __( 'Untitled', 'learnpress' ) );
325
+ }
326
+ }
327
+
328
+ ob_start();
329
+ if ( $found_items ) {
330
+ foreach ( $found_items as $id => $item ) {
331
+ printf( '
332
+ <li class="" data-id="%1$d" data-type="%3$s" data-text="%2$s">
333
+ <label>
334
+ <input type="checkbox" value="%1$d">
335
+ <span class="lp-item-text">%2$s</span>
336
+ </label>
337
+ </li>
338
+ ', $id, esc_attr( $item->post_title ), $item->post_type );
339
+ }
340
+ } else {
341
+ echo '<li>' . apply_filters( 'learn_press_modal_search_items_not_found', __( 'No item found', 'learnpress' ), $type ) . '</li>';
342
+ }
343
+
344
+ $item_object = $type ? get_post_type_object( $type ) : '';
345
+ $post_type = $context_id ? get_post_type_object( get_post_type( $context_id ) ) : '';
346
+ $response = array(
347
+ 'html' => ob_get_clean(),
348
+ 'data' => $found_items,
349
+ 'notices' => '<div class="learnpress-search-notices notice notice-warning" data-post-type="' . esc_attr( $item_object->name ) . '" data-user="' . esc_attr( $user->id ) . '">' . sprintf( '<p>' . __( 'A ', 'learnpress' ) . '<span style="text-transform: lowercase;">%s</span>' . __( ' is just used for only one ', 'learnpress' ) . '<span style="text-transform: lowercase;">%s</span></p>', $item_object->labels->singular_name, $post_type->labels->singular_name ) . '<a class="learnpress-dismiss-notice"></a></div>'
350
+ );
351
+ $dismiss_notice = 'learnpress_notice_' . $item_object->name . '_' . $user->id;
352
+ $dismiss_notice = get_transient( $dismiss_notice );
353
+ if ( $dismiss_notice || $item_object->name === 'lp_course' ) { // Check lp_course to hidden notice in order post
354
+ unset( $response['notices'] );
355
+ }
356
+
357
+ learn_press_send_json( $response );
358
+ }
359
+
360
+ public static function remove_quiz_question() {
361
+ global $wpdb;
362
+ $quiz_id = learn_press_get_request( 'quiz_id' );
363
+ $question_id = learn_press_get_request( 'question_id' );
364
+ if ( !wp_verify_nonce( learn_press_get_request( 'remove-nonce' ), 'remove_quiz_question' ) ) {
365
+ wp_die( __( 'Error', 'learnpress' ) );
366
+ }
367
+ $query = $wpdb->prepare( "
368
+ DELETE FROM {$wpdb->prefix}learnpress_quiz_questions
369
+ WHERE quiz_id = %d
370
+ AND question_id = %d
371
+ ", $quiz_id, $question_id );
372
+ $wpdb->query( $query );
373
+
374
+ // trigger change user memorize question types
375
+ $user_id = get_current_user_id();
376
+ $type = get_post_meta( $question_id, '_lp_type', true );
377
+ if ( $type ) {
378
+ $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
379
+ $question_types = !$question_types ? array() : $question_types;
380
+ $counter = !empty ( $question_types[$type] ) && $question_types[$type] ? absint( $question_types[$type] ) : 0;
381
+ $question_types[$type] = $counter ? $counter -- : 0;
382
+ update_user_meta( $user_id, '_learn_press_memorize_question_types', $question_types );
383
+ }
384
+ // end trigger change user memorize question types
385
+ die();
386
+ }
387
+
388
+ public static function search_questions() {
389
+ global $wpdb;
390
+
391
+ $quiz_id = learn_press_get_request( 'quiz_id' );
392
+ $user = learn_press_get_current_user();
393
+ if ( !$user->is_admin() && get_post_field( 'post_author', $quiz_id ) != get_current_user_id() ) {
394
+ wp_die( __( 'You have no permission to access this section.', 'learnpress' ) );
395
+ }
396
+ $term = (string) ( stripslashes( learn_press_get_request( 'term' ) ) );
397
+ $exclude = array();
398
+
399
+ if ( !empty( $_GET['exclude'] ) ) {
400
+ $exclude = array_map( 'intval', $_GET['exclude'] );
401
+ }
402
+
403
+ $added = $wpdb->get_col(
404
+ $wpdb->prepare( "
405
+ SELECT question_id
406
+ FROM {$wpdb->prefix}learnpress_quiz_questions
407
+ WHERE %d
408
+ ", 1 )
409
+ );
410
+ if ( $added ) {
411
+ $exclude = array_merge( $exclude, $added );
412
+ $exclude = array_unique( $exclude );
413
+ }
414
+
415
+ $args = array(
416
+ 'post_type' => array( 'lp_question' ),
417
+ 'posts_per_page' => - 1,
418
+ 'post_status' => 'publish',
419
+ 'order' => 'ASC',
420
+ 'orderby' => 'parent title',
421
+ 'exclude' => $exclude
422
+ );
423
+ if ( !$user->is_admin() ) {
424
+ $args['author'] = $user->id;
425
+ }
426
+ if ( $term ) {
427
+ $args['s'] = $term;
428
+ }
429
+ $posts = get_posts( $args );
430
+ $found_questions = array();
431
+
432
+ if ( !empty( $posts ) ) {
433
+ foreach ( $posts as $post ) {
434
+ $found_questions[$post->ID] = !empty( $post->post_title ) ? $post->post_title : sprintf( '(%s)', __( 'Untitled', 'learnpress' ) );
435
+ }
436
+ }
437
+
438
+ ob_start();
439
+ if ( $found_questions ) {
440
+ foreach ( $found_questions as $id => $question ) {
441
+ printf( '
442
+ <li class="" data-id="%1$d" data-type="" data-text="%2$s">
443
+ <label>
444
+ <input type="checkbox" value="%1$d">
445
+ <span class="lp-item-text">%2$s</span>
446
+ </label>
447
+ </li>
448
+ ', $id, $question );
449
+ }
450
+ } else {
451
+ echo '<li>' . __( 'No questions found', 'learnpress' ) . '</li>';
452
+ }
453
+
454
+ $response = array(
455
+ 'html' => ob_get_clean(),
456
+ 'data' => $found_questions,
457
+ 'args' => $args
458
+ );
459
+ learn_press_send_json( $response );
460
+ }
461
+
462
+ public static function plugin_action() {
463
+ $url = learn_press_get_request( 'url' );
464
+ ob_start();
465
+ wp_remote_get( $url );
466
+ ob_get_clean();
467
+ echo wp_remote_get( admin_url( 'admin.php?page=learn-press-addons&tab=installed' ) );
468
+ die();
469
+ }
470
+
471
+ /**
472
+ * Remove an item from order
473
+ */
474
+ public static function remove_order_item() {
475
+ // ensure that user has permission
476
+ if ( !current_user_can( 'edit_lp_orders' ) ) {
477
+ die( __( 'Permission denied', 'learnpress' ) );
478
+ }
479
+
480
+ // verify nonce
481
+ $nonce = learn_press_get_request( 'remove_nonce' );
482
+ if ( !wp_verify_nonce( $nonce, 'remove_order_item' ) ) {
483
+ die( __( 'Check nonce failed', 'learnpress' ) );
484
+ }
485
+
486
+ // validate order
487
+ $order_id = learn_press_get_request( 'order_id' );
488
+ if ( !is_numeric( $order_id ) || get_post_type( $order_id ) != 'lp_order' ) {
489
+ die( __( 'Order invalid', 'learnpress' ) );
490
+ }
491
+
492
+ // validate item
493
+ $item_id = learn_press_get_request( 'item_id' );
494
+ $post = get_post( learn_press_get_order_item_meta( $item_id, '_course_id' ) );
495
+ if ( !$post || ( 'lp_course' !== $post->post_type ) ) {
496
+ die( __( 'Course invalid', 'learnpress' ) );
497
+ }
498
+
499
+ learn_press_remove_order_item( $item_id );
500
+
501
+ $order_data = learn_press_update_order_items( $order_id );
502
+ $currency_symbol = learn_press_get_currency_symbol( $order_data['currency'] );
503
+ $order_data['subtotal_html'] = learn_press_format_price( $order_data['subtotal'], $currency_symbol );
504
+ $order_data['total_html'] = learn_press_format_price( $order_data['total'], $currency_symbol );
505
+
506
+
507
+ learn_press_send_json(
508
+ array(
509
+ 'result' => 'success',
510
+ 'order_data' => $order_data
511
+ )
512
+ );
513
+ }
514
+
515
+ /**
516
+ * Add new course to order
517
+ */
518
+ public static function add_item_to_order() {
519
+
520
+ // ensure that user has permission
521
+ if ( !current_user_can( 'edit_lp_orders' ) ) {
522
+ die( __( 'Permission denied', 'learnpress' ) );
523
+ }
524
+
525
+ // verify nonce
526
+ // $nonce = learn_press_get_request( 'nonce' );
527
+ // if ( !wp_verify_nonce( $nonce, 'add_item_to_order' ) ) {
528
+ // die( __( 'Check nonce failed', 'learnpress' ) );
529
+ // }
530
+
531
+ // validate order
532
+ $order_id = learn_press_get_request( 'order_id' );
533
+ if ( !is_numeric( $order_id ) || get_post_type( $order_id ) != 'lp_order' ) {
534
+ die( __( 'Order invalid', 'learnpress' ) );
535
+ }
536
+
537
+ // validate item
538
+ $item_ids = learn_press_get_request( 'item_id' );
539
+ $item_html = '';
540
+ $order_data = array();
541
+ // $order = learn_press_get_order( $order_id );
542
+
543
+ // echo '<pre>'.print_r($item_ids, true).'</pre>';
544
+ // exit(''.__LINE__);
545
+ foreach ( $item_ids as $item_id ):
546
+ $post = get_post( $item_id );
547
+ if ( !$post || ( 'lp_course' !== $post->post_type ) ) {
548
+ continue;
549
+ // die( __( 'Course invalid', 'learnpress' ) );
550
+ }
551
+ $course = learn_press_get_course( $post->ID );
552
+ $item = array(
553
+ 'course_id' => $course->id,
554
+ 'name' => $course->get_title(),
555
+ 'quantity' => 1,
556
+ 'subtotal' => $course->get_price(),
557
+ 'total' => $course->get_price()
558
+ );
559
+
560
+ // Add item
561
+ $item_id = learn_press_add_order_item( $order_id, array(
562
+ 'order_item_name' => $item['name']
563
+ ) );
564
+
565
+ $item['id'] = $item_id;
566
+
567
+ // Add item meta
568
+ if ( $item_id ) {
569
+ $item = apply_filters( 'learn_press_ajax_order_item', $item );
570
+
571
+ learn_press_add_order_item_meta( $item_id, '_course_id', $item['course_id'] );
572
+ learn_press_add_order_item_meta( $item_id, '_quantity', $item['quantity'] );
573
+ learn_press_add_order_item_meta( $item_id, '_subtotal', $item['subtotal'] );
574
+ learn_press_add_order_item_meta( $item_id, '_total', $item['total'] );
575
+
576
+ do_action( 'learn_press_ajax_add_order_item_meta', $item );
577
+ }
578
+
579
+ $order_data = learn_press_update_order_items( $order_id );
580
+ $currency_symbol = learn_press_get_currency_symbol( $order_data['currency'] );
581
+ $order_data['subtotal_html'] = learn_press_format_price( $order_data['subtotal'], $currency_symbol );
582
+ $order_data['total_html'] = learn_press_format_price( $order_data['total'], $currency_symbol );
583
+
584
+ ob_start();
585
+ include learn_press_get_admin_view( 'meta-boxes/order/order-item.php' );
586
+ $item_html .= ob_get_clean();
587
+ endforeach;
588
+
589
+
590
+ learn_press_send_json(
591
+ array(
592
+ 'result' => 'success',
593
+ 'item_html' => $item_html,
594
+ 'order_data' => $order_data
595
+ )
596
+ );
597
+ }
598
+
599
+ public static function search_courses() {
600
+ $nonce = learn_press_get_request( 'nonce' );
601
+ if ( !wp_verify_nonce( $nonce, 'search_item_term' ) ) {
602
+ LP_Debug::exception( __( 'Verify nonce failed', 'learnpress' ) );
603
+ }
604
+
605
+ $term = learn_press_get_request( 'term' );
606
+ $exclude = learn_press_get_request( 'exclude' );
607
+
608
+ $posts = learn_press_get_all_courses(
609
+ array(
610
+ 'term' => $term,
611
+ 'exclude' => $exclude
612
+ )
613
+ );
614
+ $found_courses = array();
615
+ if ( !empty( $posts ) ) {
616
+ foreach ( $posts as $post ) {
617
+ $found_courses[$post] = array(
618
+ 'title' => get_the_title( $post ),
619
+ 'permalink' => get_the_permalink( $post )
620
+ );
621
+ }
622
+ }
623
+
624
+ $found_courses = apply_filters( 'learn_press_json_search_found_courses', $found_courses );
625
+
626
+ learn_press_send_json( $found_courses );
627
+ }
628
+
629
+ public static function remove_course_section() {
630
+ $id = learn_press_get_request( 'id' );
631
+ if ( $id ) {
632
+ global $wpdb;
633
+ $query = $wpdb->prepare( "
634
+ DELETE FROM {$wpdb->prefix}learnpress_section_items
635
+ WHERE section_id = %d
636
+ ", $id );
637
+ $wpdb->query( $query );
638
+ learn_press_reset_auto_increment( 'learnpress_section_items' );
639
+ $query = $wpdb->prepare( "
640
+ DELETE FROM {$wpdb->prefix}learnpress_sections
641
+ WHERE section_id = %d
642
+ ", $id );
643
+ $wpdb->query( $query );
644
+ learn_press_reset_auto_increment( 'learnpress_sections' );
645
+ }
646
+ die();
647
+ }
648
+
649
+ public static function toggle_lesson_preview() {
650
+ $id = learn_press_get_request( 'lesson_id' );
651
+ if ( get_post_type( $id ) == 'lp_lesson' && wp_verify_nonce( learn_press_get_request( 'nonce' ), 'learn-press-toggle-lesson-preview' ) ) {
652
+ $previewable = learn_press_get_request( 'previewable' );
653
+ if ( is_null( $previewable ) ) {
654
+ $previewable = '0';
655
+ }
656
+ update_post_meta( $id, '_lp_preview', $previewable );
657
+ }
658
+ die();
659
+ }
660
+
661
+ public static function add_new_item() {
662
+ $post_type = learn_press_get_request( 'type' );
663
+ $post_title = learn_press_get_request( 'name' );
664
+ $response = array();
665
+ if ( $post_type && $post_title ) {
666
+ $args = compact( 'post_title', 'post_type' );
667
+ $args['post_status'] = 'publish';
668
+ $item_id = wp_insert_post( $args );
669
+ if ( $item_id ) {
670
+ LP_Lesson_Post_Type::create_default_meta( $item_id );
671
+ $item = get_post( $item_id );
672
+ $response['post'] = $item;
673
+ $response['post']->edit_link = get_edit_post_link( $item_id );
674
+ }
675
+ }
676
+ learn_press_send_json( $response );
677
+ }
678
+
679
+ public static function quick_add_item() {
680
+ $post_type = learn_press_get_request( 'type' );
681
+ $post_title = learn_press_get_request( 'name' );
682
+ $response = array();
683
+ if ( $post_type && $post_title ) {
684
+ $args = compact( 'post_title', 'post_type' );
685
+ $args['post_status'] = 'publish';
686
+ $item_id = wp_insert_post( $args );
687
+ if ( $item_id ) {
688
+ $item = get_post( $item_id );
689
+ $response['post'] = $item;
690
+ $response['html'] = sprintf( '<li class="" data-id="%1$d" data-type="%2$s" data-text="%3$s">
691
+ <label>
692
+ <input type="checkbox" value="%1$d">
693
+ <span class="lp-item-text">%3$s</span>
694
+ </label>
695
+ </li>', $item->ID, $item->post_type, $item->post_title );
696
+ }
697
+ }
698
+ learn_press_send_json( $response );
699
+ }
700
+
701
+ public static function update_editor_hidden() {
702
+ if ( $id = learn_press_get_request( 'course_id' ) ) {
703
+ if ( learn_press_get_request( 'is_hidden' ) ) {
704
+ update_post_meta( $id, '_lp_editor_hidden', 'yes' );
705
+ } else {
706
+ delete_post_meta( $id, '_lp_editor_hidden' );
707
+ }
708
+ }
709
+ learn_press_send_json( $_POST );
710
+ }
711
+
712
+ public static function update_quiz_question_state() {
713
+ $hidden = learn_press_get_request( 'hidden' );
714
+ $post = learn_press_get_request( 'quiz_id' );
715
+ update_post_meta( $post, '_admin_hidden_questions', $hidden );
716
+ die();
717
+ }
718
+
719
+ public static function update_curriculum_section_state() {
720
+ $hidden = learn_press_get_request( 'hidden' );
721
+ $post = learn_press_get_request( 'course_id' );
722
+ update_post_meta( $post, '_admin_hidden_sections', $hidden );
723
+ die();
724
+ }
725
+
726
+ /**
727
+ * Create a new page with the title passed via $_REQUEST
728
+ */
729
+ public static function create_page() {
730
+ $page_name = !empty( $_REQUEST['page_name'] ) ? $_REQUEST['page_name'] : '';
731
+ $response = array();
732
+ if ( $page_name ) {
733
+ $args = array(
734
+ 'post_type' => 'page',
735
+ 'post_title' => $page_name,
736
+ 'post_status' => 'publish'
737
+ );
738
+ $page_id = wp_insert_post( $args );
739
+
740
+ if ( $page_id ) {
741
+ $response['page'] = get_page( $page_id );
742
+ $html = learn_press_pages_dropdown( '', '', array( 'echo' => false ) );
743
+ preg_match_all( '!value=\"([0-9]+)\"!', $html, $matches );
744
+ $response['positions'] = $matches[1];
745
+ $response['html'] = '<a href="' . get_edit_post_link( $page_id ) . '" target="_blank">' . __( 'Edit Page', 'learnpress' ) . '</a>&nbsp;';
746
+ $response['html'] .= '<a href="' . get_permalink( $page_id ) . '" target="_blank">' . __( 'View Page', 'learnpress' ) . '</a>';
747
+ } else {
748
+ $response['error'] = __( 'Error! Create page failed. Please try again!', 'learnpress' );
749
+ }
750
+ } else {
751
+ $response['error'] = __( 'Empty page name!', 'learnpress' );
752
+ }
753
+ learn_press_send_json( $response );
754
+ die();
755
+ }
756
+
757
+ public static function add_quiz_question() {
758
+ global $post;
759
+ $id = learn_press_get_request( 'id' );
760
+ $quiz_id = learn_press_get_request( 'quiz_id' );
761
+ $type = learn_press_get_request( 'type' );
762
+ $name = learn_press_get_request( 'name' );
763
+ $user_id = get_current_user_id();
764
+ $response = array(
765
+ 'id' => $id
766
+ );
767
+ $post = get_post( $quiz_id );
768
+ setup_postdata( $post );
769
+ if ( !$id ) {
770
+ $id = wp_insert_post(
771
+ array(
772
+ 'post_title' => $name,
773
+ 'post_type' => LP_QUESTION_CPT,
774
+ 'post_status' => 'publish'
775
+ )
776
+ );
777
+ if ( $id ) {
778
+ add_post_meta( $id, '_lp_type', $type );
779
+ }
780
+ $response['id'] = $id;
781
+ }
782
+ if ( $id && $quiz_id ) {
783
+ global $wpdb;
784
+ $max_order = $wpdb->get_var( $wpdb->prepare( "SELECT max(question_order) FROM {$wpdb->prefix}learnpress_quiz_questions WHERE quiz_id = %d", $quiz_id ) );
785
+ $wpdb->insert(
786
+ $wpdb->prefix . 'learnpress_quiz_questions',
787
+ array(
788
+ 'quiz_id' => $quiz_id,
789
+ 'question_id' => $id,
790
+ 'question_order' => $max_order + 1
791
+ ),
792
+ array( '%d', '%d', '%d' )
793
+ );
794
+ ob_start();
795
+ $question = LP_Question_Factory::get_question( $id );
796
+ learn_press_admin_view( 'meta-boxes/quiz/question.php', array( 'question' => $question ) );
797
+ $response['html'] = ob_get_clean();
798
+
799
+ // trigger change user memorize question types
800
+ $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
801
+ $question_types = !$question_types ? array() : $question_types;
802
+ $type = get_post_meta( $id, '_lp_type', true );
803
+ $question_types[$type] = !empty ( $question_types[$type] ) ? absint( $question_types[$type] ) + 1 : 1;
804
+ update_user_meta( $user_id, '_learn_press_memorize_question_types', $question_types );
805
+ // end trigger change user memorize question types
806
+ }
807
+ learn_press_send_json( $response );
808
+ die();
809
+ }
810
+
811
+ public static function convert_question_type() {
812
+ if ( ( $from = learn_press_get_request( 'from' ) ) && ( $to = learn_press_get_request( 'to' ) ) && $question_id = learn_press_get_request( 'question_id' ) ) {
813
+ $data = array();
814
+ parse_str( $_POST['data'], $data );
815
+
816
+ do_action( 'learn_press_convert_question_type', $question_id, $from, $to, $data );
817
+ $question = LP_Question_Factory::get_question( $question_id, array( 'type' => $to ) );
818
+
819
+ // trigger change user memorize question types
820
+ $user_id = get_current_user_id();
821
+ $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
822
+ $question_types[$from] = !empty( $question_types[$from] ) && $question_types[$from] ? absint( $question_types[$from] ) - 1 : 0;
823
+ $question_types[$to] = !empty( $question_types[$to] ) && $question_types[$to] ? absint( $question_types[$to] ) + 1 : 1;
824
+ update_user_meta( $user_id, '_learn_press_memorize_question_types', $question_types );
825
+ // end trigger change user memorize question types
826
+ if('auto-draft'=== $question->post->post_status){
827
+ $question->answers = $question->get_default_answers(false);
828
+ }
829
+ learn_press_send_json(
830
+ array(
831
+ 'html' => $question->admin_interface( array( 'echo' => false ) ),
832
+ 'icon' => $question->get_icon()
833
+ )
834
+ );
835
+ } else {
836
+ //throw new Exception( __( 'Convert question type must be specify the id, source and destination type', 'learnpress' ) );
837
+ throw new Exception( __( 'Something went wrong! Please try again or ask <a href="https://wordpress.org/support/">support forums</a>.', 'learnpress' ) );
838
+ }
839
+ die();
840
+ }
841
+
842
+ /*******************************************************************************************************/
843
+
844
+ /**
845
+ * Install sample data or dismiss the notice depending on user's option
846
+ */
847
+ public static function install_sample_data() {
848
+ $yes = !empty( $_REQUEST['yes'] ) ? $_REQUEST['yes'] : '';
849
+ $response = array( 'result' => 'fail' );
850
+ $retry_button = sprintf( '<a href="" class="button yes" data-action="yes">%s</a>', __( 'Try again!', 'learnpress' ) );
851
+ $dismiss_button = sprintf( '<a href="" class="button disabled no" data-action="no">%s</a>', __( 'Cancel', 'learnpress' ) );
852
+ $buttons = sprintf( '<p>%s %s</p>', $retry_button, $dismiss_button );
853
+ if ( 'no' == $yes ) {
854
+ set_transient( 'learn_press_install_sample_data', 'off', 12 * HOUR_IN_SECONDS );
855
+ } else {
856
+ $result = array( 'status' => 'activate' );//learn_press_install_and_active_add_on( 'learnpress-import-export' );
857
+ if ( 'activate' == $result['status'] ) {
858
+ // copy dummy-data.xml to import folder of the add-on
859
+ lpie_mkdir( lpie_import_path() );
860
+ if ( file_exists( lpie_import_path() ) ) {
861
+ $import_source = LP_PLUGIN_PATH . '/dummy-data/dummy-data.xml';
862
+ $file = 'dummy-data-' . time() . '.xml';
863
+ $copy = lpie_import_path() . '/' . $file;
864
+ copy( $import_source, $copy );
865
+ if ( file_exists( $copy ) ) {
866
+ $url = admin_url( 'admin-ajax.php?page=learn_press_import_export&tab=import-course' );
867
+ $postdata = array(
868
+ 'step' => 2,
869
+ 'action' => 'learn_press_import',
870
+ 'import-file' => 'import/' . $file,
871
+ 'nonce' => wp_create_nonce( 'lpie-import-file' ),
872
+ 'x' => 1
873
+ );
874
+ $response['url'] = $url = $url . '&' . http_build_query( $postdata ) . "\n";
875
+ $response['result'] = 'success';
876
+ $response['message'] = sprintf( '<p>%s <a href="edit.php?post_type=lp_course">%s</a> </p>', __( 'Import sample data successes.', 'learnpress' ), __( 'View courses', 'learnpress' ) );
877
+ }
878
+ }
879
+ if ( $response['result'] == 'fail' ) {
880
+ $response['message'] = sprintf( '<p>%s</p>%s', __( 'Import sample data failed. Please try again!.', 'learnpress' ), $buttons );
881
+ }
882
+ } else {
883
+ $response['result'] = 'fail';
884
+ $response['message'] = sprintf( '<p>%s</p>', __( 'Unknown error when installing/activating Import/Export addon. Please try again!', 'learnpress' ) ) . $buttons;
885
+ }
886
+ }
887
+ learn_press_send_json( $response );
888
+ die();
889
+ }
890
+
891
+ /**
892
+ * Activate a bundle of add-ons, if an add-on is not installed then install it first
893
+ */
894
+ public static function bundle_activate_add_ons() {
895
+ global $learn_press_add_ons;
896
+ include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); //for plugins_api..
897
+ $response = array( 'addons' => array() );
898
+
899
+ if ( !current_user_can( 'activate_plugins' ) ) {
900
+ $response['error'] = __( 'You do not have sufficient permissions to deactivate plugins for this site.', 'learnpress' );
901
+ } else {
902
+
903
+ $add_ons = $learn_press_add_ons['bundle_activate'];
904
+
905
+ if ( $add_ons ) {
906
+ foreach ( $add_ons as $slug ) {
907
+ $response['addons'][$slug] = learn_press_install_and_active_add_on( $slug );
908
+ }
909
+ }
910
+ }
911
+ learn_press_send_json( $response );
912
+ }
913
+
914
+ /**
915
+ * Activate a bundle of add-ons, if an add-on is not installed then install it first
916
+ */
917
+ public static function bundle_activate_add_on() {
918
+ $response = array();
919
+ include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); //for plugins_api..
920
+ if ( !current_user_can( 'activate_plugins' ) ) {
921
+ $response['error'] = __( 'You do not have sufficient permissions to deactivate plugins for this site.', 'learnpress' );
922
+ } else {
923
+ $slug = !empty( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : null;
924
+ $response[$slug] = learn_press_install_and_active_add_on( $slug );
925
+ }
926
+ learn_press_send_json( $response );
927
+ }
928
+
929
+ public static function plugin_install() {
930
+ $plugin_name = !empty( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
931
+ $response = learn_press_install_add_on( $plugin_name );
932
+ learn_press_send_json( $response );
933
+ die();
934
+ }
935
+
936
+ public static function update_add_on_status() {
937
+ $plugin = !empty( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
938
+ $t = !empty( $_REQUEST['t'] ) ? $_REQUEST['t'] : '';
939
+ $response = array();
940
+ if ( !current_user_can( 'activate_plugins' ) ) {
941
+ $response['error'] = __( 'You do not have sufficient permissions to deactivate plugins for this site.', 'learnpress' );
942
+ }
943
+ if ( $plugin && $t ) {
944
+ if ( $t == 'activate' ) {
945
+ activate_plugin( $plugin, false, is_network_admin() );
946
+ } else {
947
+ deactivate_plugins( $plugin, false, is_network_admin() );
948
+ }
949
+ $is_activate = is_plugin_active( $plugin );
950
+ $response['status'] = $is_activate ? 'activate' : 'deactivate';
951
+
952
+ }
953
+ wp_send_json( $response );
954
+ die();
955
+ }
956
+
957
+ /**
958
+ * Output the image to browser with text and params passed via $_GET
959
+ */
960
+ public static function dummy_image() {
961
+ $text = !empty( $_REQUEST['text'] ) ? $_REQUEST['text'] : '';
962
+ learn_press_text_image( $text, $_GET );
963
+ die();
964
+ }
965
+
966
+ /**
967
+ * Get edit|view link of a page
968
+ */
969
+ public static function get_page_permalink() {
970
+ $page_id = !empty( $_REQUEST['page_id'] ) ? $_REQUEST['page_id'] : '';
971
+ ?>
972
+ <a href="<?php echo get_edit_post_link( $page_id ); ?>" target="_blank"><?php _e( 'Edit Page', 'learnpress' ); ?></a>
973
+ <a href="<?php echo get_permalink( $page_id ); ?>" target="_blank"><?php _e( 'View Page', 'learnpress' ); ?></a>
974
+ <?php
975
+ die();
976
+ }
977
+
978
+
979
+ /**
980
+ *
981
+ */
982
+ public function custom_stats() {
983
+ $from = !empty( $_REQUEST['from'] ) ? $_REQUEST['from'] : 0;
984
+ $to = !empty( $_REQUEST['to'] ) ? $_REQUEST['to'] : 0;
985
+ $date_diff = strtotime( $to ) - strtotime( $from );
986
+ if ( $date_diff <= 0 || $from == 0 || $to == 0 ) {
987
+ die();
988
+ }
989
+ learn_press_process_chart( learn_press_get_chart_students( $to, 'days', floor( $date_diff / ( 60 * 60 * 24 ) ) + 1 ) );
990
+ die();
991
+ }
992
+
993
+ /**
994
+ * Quick add lesson with only title
995
+ */
996
+ public static function quick_add_lesson() {
997
+
998
+ $lesson_title = $_POST['lesson_title'];
999
+
1000
+ $new_lesson = array(
1001
+ 'post_title' => wp_strip_all_tags( $lesson_title ),
1002
+ 'post_type' => LP_LESSON_CPT,
1003
+ 'post_status' => 'publish'
1004
+ );
1005
+
1006
+ wp_insert_post( $new_lesson );
1007
+
1008
+ $args = array(
1009
+ 'numberposts' => 1,
1010
+ 'post_type' => LP_LESSON_CPT,
1011
+ 'post_status' => 'publish'
1012
+ );
1013
+ $lesson = wp_get_recent_posts( $args );
1014
+ $lesson_id = $lesson[0]['ID'];
1015
+ $data = array(
1016
+ 'id' => $lesson_id,
1017
+ 'title' => $lesson_title
1018
+ );
1019
+ wp_send_json( $data );
1020
+ die;
1021
+ }
1022
+
1023
+ /**
1024
+ * Add a new quiz with the title only
1025
+ */
1026
+ public static function quick_add_quiz() {
1027
+ $quiz_title = $_POST['quiz_title'];
1028
+
1029
+ $new_quiz = array(
1030
+ 'post_title' => wp_strip_all_tags( $quiz_title ),
1031
+ 'post_type' => LP_QUIZ_CPT,
1032
+ 'post_status' => 'publish'
1033
+ );
1034
+
1035
+ wp_insert_post( $new_quiz );
1036
+
1037
+ $args = array(
1038
+ 'numberposts' => 1,
1039
+ 'post_type' => LP_QUIZ_CPT,
1040
+ 'post_status' => 'publish'
1041
+ );
1042
+ $quiz = wp_get_recent_posts( $args );
1043
+ $quiz_id = $quiz[0]['ID'];
1044
+ $data = array(
1045
+ 'id' => $quiz_id,
1046
+ 'title' => $quiz_title
1047
+ );
1048
+ wp_send_json( $data );
1049
+ die;
1050
+ }
1051
+
1052
+ public static function be_teacher() {
1053
+ $user_id = get_current_user_id();
1054
+ $be_teacher = new WP_User( $user_id );
1055
+ $be_teacher->set_role( LP_TEACHER_ROLE );
1056
+ die;
1057
+ }
1058
+
1059
+ public static function ignore_setting_up() {
1060
+ update_option( '_lpr_ignore_setting_up', 1, true );
1061
+ die;
1062
+ }
1063
+
1064
+ public static function duplicate_course() {
1065
+ if ( empty( $_POST['course_id'] ) || empty( $_POST['_nonce'] ) || !wp_verify_nonce( $_POST['_nonce'], 'lp-duplicate-course' ) ) {
1066
+ return;
1067
+ }
1068
+ global $wpdb;
1069
+ $course_id = absint( $_POST['course_id'] );
1070
+ $force = !empty( $_POST['content'] ) && $_POST['content'] ? true : false;
1071
+
1072
+ $results = array(
1073
+ 'redirect' => admin_url( 'edit.php?post_type=' . LP_COURSE_CPT )
1074
+ );
1075
+ $new_course_id = learn_press_duplicate_course( $course_id, $force );
1076
+ if ( is_wp_error( $course_id ) ) {
1077
+ LP_Admin_Notice::add_redirect( $course_id->get_error_message(), 'error' );
1078
+ } else {
1079
+ LP_Admin_Notice::add_redirect( sprintf( '<strong>%s</strong> %s', get_the_title( $course_id ), __( ' course has duplicated', 'learnpress' ) ), 'updated' );
1080
+ $results['redirect'] = admin_url( 'post.php?post=' . $new_course_id . '&action=edit' );
1081
+ }
1082
+
1083
+ wp_send_json( $results );
1084
+ die();
1085
+ }
1086
+
1087
+ public static function duplicate_question() {
1088
+ if ( empty( $_POST['_nonce'] ) || !wp_verify_nonce( $_POST['_nonce'], 'duplicate-question' ) ) {
1089
+ return;
1090
+ }
1091
+ global $wpdb;
1092
+ $question_id = learn_press_get_request( 'question-id' );
1093
+ $quiz_id = learn_press_get_request( 'quiz-id' );
1094
+ $user_id = learn_press_get_current_user_id();
1095
+
1096
+ $new_question_id = learn_press_duplicate_question( $question_id, $quiz_id );
1097
+ if ( !is_wp_error( $new_question_id ) ) {
1098
+ ob_start();
1099
+ $question = LP_Question_Factory::get_question( $new_question_id );
1100
+ $post = get_post( $quiz_id );
1101
+ setup_postdata( $post );
1102
+ _learn_press_setup_question( $new_question_id );
1103
+ learn_press_admin_view( 'meta-boxes/quiz/question.php', array( 'question' => $question ) );
1104
+ $response['html'] = ob_get_clean();
1105
+
1106
+ // trigger change user memorize question types
1107
+ $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
1108
+ $question_types = !$question_types ? array() : $question_types;
1109
+ $type = get_post_meta( $new_question_id, '_lp_type', true );
1110
+ $question_types[$type] = !empty ( $question_types[$type] ) ? absint( $question_types[$type] ) + 1 : 1;
1111
+ update_user_meta( $user_id, '_learn_press_memorize_question_types', $question_types );
1112
+ // end trigger change user memorize question types
1113
+ learn_press_send_json( $response );
1114
+
1115
+
1116
+ die();
1117
+ }
1118
+ }
1119
+
1120
+ public static function remove_notice_popup() {
1121
+
1122
+ if ( isset( $_POST['action'] ) && $_POST['action'] === 'learnpress_remove_notice_popup'
1123
+ && isset( $_POST['slug'] ) && !empty( $_POST['slug'] )
1124
+ && isset( $_POST['user'] ) && !empty( $_POST['user'] )
1125
+ ) {
1126
+
1127
+ $slug = 'learnpress_notice_' . $_POST['slug'] . '_' . $_POST['user'];
1128
+
1129
+ set_transient( $slug, true, 30 * DAY_IN_SECONDS );
1130
+ }
1131
+
1132
+ wp_die();
1133
+
1134
+ }
1135
+
1136
+ }
1137
+ }
1138
+ LP_Admin_Ajax::init();
1139
+
inc/admin/class-lp-admin.php CHANGED
@@ -1,229 +1,231 @@
1
- <?php
2
- /**
3
- * @author ThimPress
4
- * @package LearnPress/Admin/Classes
5
- * @version 1.0
6
- */
7
- if ( !defined( 'ABSPATH' ) ) {
8
- exit; // Exit if accessed directly
9
- }
10
-
11
- if ( !class_exists( 'LP_Admin' ) ) {
12
- /**
13
- * Class LP_Admin
14
- */
15
- class LP_Admin {
16
- /**
17
- * Constructor
18
- */
19
- public function __construct() {
20
- $this->includes();
21
- add_action( 'admin_print_scripts', array( $this, 'plugin_js_settings' ) );
22
- add_action( 'template_redirect', array( $this, '_redirect' ) );
23
- add_action( 'delete_user', array( $this, 'delete_user_data' ) );
24
- add_action( 'delete_user_form', array( $this, 'delete_user_form' ) );
25
- add_action( 'wp_ajax_learn_press_rated', array( $this, 'rated' ) );
26
- add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
27
-
28
- add_action( 'admin_notices', array( $this, 'notice_outdated_templates' ) );
29
- add_action( 'admin_notices', array( $this, 'notice_setup_page' ) );
30
- add_action( 'admin_notices', array( $this, 'notice_required_permalink' ) );
31
-
32
- }
33
-
34
- public function notice_required_permalink() {
35
-
36
- if ( current_user_can( 'manage_options' ) ) {
37
-
38
- if ( !get_option( 'permalink_structure' ) ) {
39
- learn_press_add_notice( sprintf( __( 'LearnPress requires permalink option <strong>Post name</strong> is enabled. Please enable it <a href="%s">here</a> to ensure that all functions work properly.', 'learnpress' ), admin_url( 'options-permalink.php' ) ), 'error' );
40
- }
41
- }
42
- }
43
-
44
- public function notice_setup_page() {
45
-
46
- $args = array(
47
- array(
48
- 'name_option' => 'learn_press_profile_page_id',
49
- 'id' => 'lp-admin-warning-profile',
50
- 'title' => __( 'Profile Page', 'learnpress' ),
51
- 'url' => admin_url( 'admin.php?page=learn-press-settings&tab=pages' )
52
- ),
53
- array(
54
- 'name_option' => 'learn_press_checkout_page_id',
55
- 'id' => 'lp-admin-warning-checkout',
56
- 'title' => __( 'Checkout Page', 'learnpress' ),
57
- 'url' => admin_url( 'admin.php?page=learn-press-settings&tab=checkout' )
58
- ),
59
- );
60
-
61
- if ( current_user_can( 'manage_options' ) ) {
62
-
63
- $notice = esc_html__( 'The following required page(s) are currently missing: ', 'learnpress' );
64
- $count = 0;
65
- $pages = array();
66
-
67
- foreach ( $args as $key => $arg ) {
68
- $item_page_id = get_option( $arg['name_option'] );
69
- $item_transient = get_transient( $arg['id'] );
70
- $item_page = get_post( $item_page_id );
71
-
72
- if ( empty( $item_transient ) && ( empty( $item_page_id ) || empty( $item_page ) ) ) {
73
- $count ++;
74
- $pages[] = array(
75
- 'url' => $arg['url'],
76
- 'title' => $arg['title']
77
- );
78
-
79
- }
80
- }
81
-
82
- foreach ( $pages as $key => $page ) {
83
- if ( $key == ( $count - 1 ) && $count != 1 ) {
84
- $notice .= esc_html__( ' and ', 'learnpress' );
85
- }
86
- $notice .= __( wp_kses( '<a href="' . $page['url'] . '">' . $page['title'] . '</a>', array( 'a' => array( 'href' => array() ) ) ), 'learnpress' );
87
- }
88
-
89
-
90
- $notice .= '.' . esc_html__( ' Please click to the link to set it up, ensure all functions work properly.', 'learnpress' );
91
-
92
- return $count ? learn_press_add_notice( $notice, 'error' ) : '';
93
- }
94
- return '';
95
-
96
- }
97
-
98
- public function notice_outdated_templates() {
99
- $page = '';
100
- $tab = '';
101
- if ( !empty( $_REQUEST['page'] ) ) {
102
- $page = $_REQUEST['page'];
103
- }
104
-
105
- if ( !empty( $_REQUEST['tab'] ) ) {
106
- $tab = $_REQUEST['tab'];
107
- }
108
-
109
- if ( $page == 'learn-press-tools' && $tab == 'templates' ) {
110
- return;
111
- }
112
-
113
- if ( learn_press_get_theme_templates( true ) ) {
114
- learn_press_admin_view( 'html-admin-notice-templates' );
115
- }
116
- }
117
-
118
- public function rated() {
119
- update_option( 'learn_press_message_user_rated', 'yes' );
120
- die();
121
- }
122
-
123
- public function admin_footer_text( $footer_text ) {
124
- $current_screen = get_current_screen();
125
- $pages = learn_press_get_screens();
126
- if ( isset( $current_screen->id ) && apply_filters( 'learn_press_display_admin_footer_text', in_array( $current_screen->id, $pages ) ) ) {
127
- if ( !get_option( 'learn_press_message_user_rated' ) ) {
128
- $footer_text = sprintf( __( 'If you like <strong>LearnPress</strong> please leave us a %s&#9733;&#9733;&#9733;&#9733;&#9733;%s rating. A huge thanks in advance!', 'learnpress' ), '<a href="https://wordpress.org/support/plugin/learnpress/reviews/?filter=5#postform" target="_blank" class="lp-rating-link" data-rated="' . esc_attr__( 'Thanks :)', 'learnpress' ) . '">', '</a>' );
129
- ob_start(); ?>
130
- <script type="text/javascript">
131
- var $ratingLink = $('a.lp-rating-link').click(function (e) {
132
- $.ajax({
133
- url : '<?php echo admin_url( 'admin-ajax.php' );?>',
134
- data : {
135
- action: 'learn_press_rated'
136
- },
137
- success: function () {
138
- $ratingLink.parent().html($ratingLink.data('rated'));
139
- }
140
- });
141
- });
142
- </script>
143
- <?php
144
- $code = ob_get_clean();
145
- LP_Assets::add_script_tag( $code, '__all' );
146
- } else {
147
- }
148
- }
149
- return $footer_text;
150
- }
151
-
152
- function delete_user_form() {
153
- // What should be displayed here?
154
- }
155
-
156
- /**
157
- * Delete records related user being deleted in other tables
158
- *
159
- * @param int $user_id
160
- */
161
- function delete_user_data( $user_id ) {
162
- learn_press_delete_user_data( $user_id );
163
- }
164
-
165
- /**
166
- * Output common js settings in admin
167
- *
168
- * @since 0.9.4
169
- */
170
- public function plugin_js_settings() {
171
- static $did = false;
172
- if ( $did || !is_admin() ) return;
173
- $js = array(
174
- 'ajax' => admin_url( 'admin-ajax.php' ),
175
- 'plugin_url' => learn_press_plugin_url(),
176
- 'siteurl' => home_url(),
177
- 'localize' => array(
178
- 'button_ok' => __( 'OK', 'learnpress' ),
179
- 'button_cancel' => __( 'Cancel', 'learnpress' ),
180
- 'button_yes' => __( 'Yes', 'learnpress' ),
181
- 'button_no' => __( 'No', 'learnpress' )
182
- )
183
- );
184
- LP_Assets::add_param( $js, false, 'learn-press-global', 'LP_Settings' );
185
- if ( LP_Settings::instance()->get( 'debug' ) == 'yes' ) {
186
- LP_Assets::add_var( 'LEARN_PRESS_DEBUG', 'true', '__all' );
187
- }
188
- $did = true;
189
- }
190
-
191
- /**
192
- * Redirect to admin settings page
193
- */
194
- public function _redirect() {
195
- $page = isset( $_GET['page'] ) ? $_GET['page'] : '';
196
- if ( 'learn_press_settings' == $page ) {
197
- $current_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : '';
198
- $tabs = learn_press_settings_tabs_array();
199
-
200
- if ( !$current_tab || ( $tabs && empty( $tabs[$current_tab] ) ) ) {
201
- if ( $tabs ) {
202
- $tab_keys = array_keys( $tabs );
203
- $current_tab = reset( $tab_keys );
204
- wp_redirect( admin_url( 'options-general.php?page=learn_press_settings&tab=' . $current_tab ) );
205
- exit();
206
- }
207
- }
208
- }
209
- }
210
-
211
- /**
212
- * Include all classes and functions used for admin
213
- */
214
- public function includes() {
215
- // Common function used in admin
216
- include_once( 'lp-admin-functions.php' );
217
- // Admin actions
218
- include_once( 'lp-admin-actions.php' );
219
- //Ajax Class
220
- include_once( 'class-lp-admin-ajax.php' );
221
- // Admin menu
222
- include_once( 'class-lp-admin-menu.php' );
223
-
224
-
225
- }
226
- }
227
-
228
- new LP_Admin();
 
 
229
  }
1
+ <?php
2
+ /**
3
+ * @author ThimPress
4
+ * @package LearnPress/Admin/Classes
5
+ * @version 1.0
6
+ */
7
+ if ( !defined( 'ABSPATH' ) ) {
8
+ exit; // Exit if accessed directly
9
+ }
10
+
11
+ if ( !class_exists( 'LP_Admin' ) ) {
12
+ /**
13
+ * Class LP_Admin
14
+ */
15
+ class LP_Admin {
16
+ /**
17
+ * Constructor
18
+ */
19
+ public function __construct() {
20
+ $this->includes();
21
+ add_action( 'admin_print_scripts', array( $this, 'plugin_js_settings' ) );
22
+ add_action( 'template_redirect', array( $this, '_redirect' ) );
23
+ add_action( 'delete_user', array( $this, 'delete_user_data' ) );
24
+ add_action( 'delete_user_form', array( $this, 'delete_user_form' ) );
25
+ add_action( 'wp_ajax_learn_press_rated', array( $this, 'rated' ) );
26
+ add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
27
+
28
+ add_action( 'admin_notices', array( $this, 'notice_outdated_templates' ) );
29
+ add_action( 'admin_notices', array( $this, 'notice_setup_page' ) );
30
+ add_action( 'admin_notices', array( $this, 'notice_required_permalink' ) );
31
+
32
+ }
33
+
34
+ public function notice_required_permalink() {
35
+
36
+ if ( current_user_can( 'manage_options' ) ) {
37
+
38
+ if ( !get_option( 'permalink_structure' ) ) {
39
+ learn_press_add_notice( sprintf( __( 'LearnPress requires permalink option <strong>Post name</strong> is enabled. Please enable it <a href="%s">here</a> to ensure that all functions work properly.', 'learnpress' ), admin_url( 'options-permalink.php' ) ), 'error' );
40
+ }
41
+ }
42
+ }
43
+
44
+ public function notice_setup_page() {
45
+
46
+ $args = array(
47
+ array(
48
+ 'name_option' => 'learn_press_profile_page_id',
49
+ 'id' => 'lp-admin-warning-profile',
50
+ 'title' => __( 'Profile Page', 'learnpress' ),
51
+ 'url' => admin_url( 'admin.php?page=learn-press-settings&tab=pages' )
52
+ ),
53
+ array(
54
+ 'name_option' => 'learn_press_checkout_page_id',
55
+ 'id' => 'lp-admin-warning-checkout',
56
+ 'title' => __( 'Checkout Page', 'learnpress' ),
57
+ 'url' => admin_url( 'admin.php?page=learn-press-settings&tab=checkout' )
58
+ ),
59
+ );
60
+
61
+ if ( current_user_can( 'manage_options' ) ) {
62
+
63
+ $notice = esc_html__( 'The following required page(s) are currently missing: ', 'learnpress' );
64
+ $count = 0;
65
+ $pages = array();
66
+
67
+ foreach ( $args as $key => $arg ) {
68
+ $item_page_id = get_option( $arg['name_option'] );
69
+ $item_transient = get_transient( $arg['id'] );
70
+ $item_page = get_post( $item_page_id );
71
+
72
+ if ( empty( $item_transient ) && ( empty( $item_page_id ) || empty( $item_page ) ) ) {
73
+ $count ++;
74
+ $pages[] = array(
75
+ 'url' => $arg['url'],
76
+ 'title' => $arg['title']
77
+ );
78
+
79
+ }
80
+ }
81
+
82
+ foreach ( $pages as $key => $page ) {
83
+ if ( $key == ( $count - 1 ) && $count != 1 ) {
84
+ $notice .= esc_html__( ' and ', 'learnpress' );
85
+ }
86
+ $notice .= __( wp_kses( '<a href="' . $page['url'] . '">' . $page['title'] . '</a>', array( 'a' => array( 'href' => array() ) ) ), 'learnpress' );
87
+ }
88
+
89
+
90
+ $notice .= '.' . esc_html__( ' Please click to the link to set it up, ensure all functions work properly.', 'learnpress' );
91
+
92
+ return $count ? learn_press_add_notice( $notice, 'error' ) : '';
93
+ }
94
+ return '';
95
+
96
+ }
97
+
98
+ public function notice_outdated_templates() {
99
+ if ( current_user_can( 'manage_options' ) ) {
100
+ $page = '';
101
+ $tab = '';
102
+ if ( !empty( $_REQUEST['page'] ) ) {
103
+ $page = $_REQUEST['page'];
104
+ }
105
+
106
+ if ( !empty( $_REQUEST['tab'] ) ) {
107
+ $tab = $_REQUEST['tab'];
108
+ }
109
+
110
+ if ( $page == 'learn-press-tools' && $tab == 'templates' ) {
111
+ return;
112
+ }
113
+
114
+ if ( learn_press_get_theme_templates( true ) ) {
115
+ learn_press_admin_view( 'html-admin-notice-templates' );
116
+ }
117
+ }
118
+ }
119
+
120
+ public function rated() {
121
+ update_option( 'learn_press_message_user_rated', 'yes' );
122
+ die();
123
+ }
124
+
125
+ public function admin_footer_text( $footer_text ) {
126
+ $current_screen = get_current_screen();
127
+ $pages = learn_press_get_screens();
128
+ if ( isset( $current_screen->id ) && apply_filters( 'learn_press_display_admin_footer_text', in_array( $current_screen->id, $pages ) ) ) {
129
+ if ( !get_option( 'learn_press_message_user_rated' ) ) {
130
+ $footer_text = sprintf( __( 'If you like <strong>LearnPress</strong> please leave us a %s&#9733;&#9733;&#9733;&#9733;&#9733;%s rating. A huge thanks in advance!', 'learnpress' ), '<a href="https://wordpress.org/support/plugin/learnpress/reviews/?filter=5#postform" target="_blank" class="lp-rating-link" data-rated="' . esc_attr__( 'Thanks :)', 'learnpress' ) . '">', '</a>' );
131
+ ob_start(); ?>
132
+ <script type="text/javascript">
133
+ var $ratingLink = $('a.lp-rating-link').click(function (e) {
134
+ $.ajax({
135
+ url : '<?php echo admin_url( 'admin-ajax.php' );?>',
136
+ data : {
137
+ action: 'learn_press_rated'
138
+ },
139
+ success: function () {
140
+ $ratingLink.parent().html($ratingLink.data('rated'));
141
+ }
142
+ });
143
+ });
144
+ </script>
145
+ <?php
146
+ $code = ob_get_clean();
147
+ LP_Assets::add_script_tag( $code, '__all' );
148
+ } else {
149
+ }
150
+ }
151
+ return $footer_text;
152
+ }
153
+
154
+ function delete_user_form() {
155
+ // What should be displayed here?
156
+ }
157
+
158
+ /**
159
+ * Delete records related user being deleted in other tables
160
+ *
161
+ * @param int $user_id
162
+ */
163
+ function delete_user_data( $user_id ) {
164
+ learn_press_delete_user_data( $user_id );
165
+ }
166
+
167
+ /**
168
+ * Output common js settings in admin
169
+ *
170
+ * @since 0.9.4
171
+ */
172
+ public function plugin_js_settings() {
173
+ static $did = false;
174
+ if ( $did || !is_admin() ) return;
175
+ $js = array(
176
+ 'ajax' => admin_url( 'admin-ajax.php' ),
177
+ 'plugin_url' => learn_press_plugin_url(),
178
+ 'siteurl' => home_url(),
179
+ 'localize' => array(
180
+ 'button_ok' => __( 'OK', 'learnpress' ),
181
+ 'button_cancel' => __( 'Cancel', 'learnpress' ),
182
+ 'button_yes' => __( 'Yes', 'learnpress' ),
183
+ 'button_no' => __( 'No', 'learnpress' )
184
+ )
185
+ );
186
+ LP_Assets::add_param( $js, false, 'learn-press-global', 'LP_Settings' );
187
+ if ( LP_Settings::instance()->get( 'debug' ) == 'yes' ) {
188
+ LP_Assets::add_var( 'LEARN_PRESS_DEBUG', 'true', '__all' );
189
+ }
190
+ $did = true;
191
+ }
192
+
193
+ /**
194
+ * Redirect to admin settings page
195
+ */
196
+ public function _redirect() {
197
+ $page = isset( $_GET['page'] ) ? $_GET['page'] : '';
198
+ if ( 'learn_press_settings' == $page ) {
199
+ $current_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : '';
200
+ $tabs = learn_press_settings_tabs_array();
201
+
202
+ if ( !$current_tab || ( $tabs && empty( $tabs[$current_tab] ) ) ) {
203
+ if ( $tabs ) {
204
+ $tab_keys = array_keys( $tabs );
205
+ $current_tab = reset( $tab_keys );
206
+ wp_redirect( admin_url( 'options-general.php?page=learn_press_settings&tab=' . $current_tab ) );
207
+ exit();
208
+ }
209
+ }
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Include all classes and functions used for admin
215
+ */
216
+ public function includes() {
217
+ // Common function used in admin
218
+ include_once( 'lp-admin-functions.php' );
219
+ // Admin actions
220
+ include_once( 'lp-admin-actions.php' );
221
+ //Ajax Class
222
+ include_once( 'class-lp-admin-ajax.php' );
223
+ // Admin menu
224
+ include_once( 'class-lp-admin-menu.php' );
225
+
226
+
227
+ }
228
+ }
229
+
230
+ new LP_Admin();
231
  }
inc/admin/lp-admin-functions.php CHANGED
@@ -1,2029 +1,2032 @@
1
- <?php
2
- /**
3
- * Common functions used for admin
4
- *
5
- * @package LearnPress
6
- * @author ThimPress
7
- * @version 1.0
8
- */
9
-
10
- if ( !defined( 'ABSPATH' ) ) {
11
- exit;
12
- }
13
- /**
14
- * Get html view path for admin to display
15
- *
16
- * @param $name
17
- * @param $plugin_file
18
- *
19
- * @return mixed
20
- */
21
- function learn_press_get_admin_view( $name, $plugin_file = null ) {
22
- if ( !preg_match( '/\.(.*)$/', $name ) ) {
23
- $name .= '.php';
24
- }
25
- if ( $plugin_file ) {
26
- $view = dirname( $plugin_file ) . '/inc/admin/views/' . $name;
27
- } else {
28
- $view = LP()->plugin_path( 'inc/admin/views/' . $name );
29
- }
30
- return apply_filters( 'learn_press_admin_view', $view, $name );
31
- }
32
-
33
- /**
34
- * Find a full path of a view and display the content in admin
35
- *
36
- * @param $name
37
- * @param array $args
38
- * @param bool|false $include_once
39
- * @param bool
40
- *
41
- * @return bool
42
- */
43
- function learn_press_admin_view( $name, $args = array(), $include_once = false, $return = false ) {
44
- $view = learn_press_get_admin_view( $name, !empty( $args['plugin_file'] ) ? $args['plugin_file'] : null );
45
- if ( file_exists( $view ) ) {
46
- ob_start();
47
- // extract parameters as local variables if passed
48
- is_array( $args ) && extract( $args );
49
- do_action( 'learn_press_before_display_admin_view', $name, $args );
50
- if ( $include_once ) {
51
- include_once $view;
52
- } else {
53
- include $view;
54
- }
55
- do_action( 'learn_press_after_display_admin_view', $name, $args );
56
- $output = ob_get_clean();
57
- if ( !$return ) {
58
- echo $output;
59
- }
60
- return $return ? $output : true;
61
- }
62
- return false;
63
- }
64
-
65
- /**
66
- * List all pages as a dropdown with "Add New Page" option
67
- *
68
- * @param $name
69
- * @param bool|false $selected
70
- * @param array $args
71
- *
72
- * @return mixed|string
73
- */
74
- function learn_press_pages_dropdown( $name, $selected = false, $args = array() ) {
75
- $id = null;
76
- $class = null;
77
- $css = null;
78
- $before = array(
79
- 'add_new_page' => __( '[ Add a new page ]', 'learnpress' )
80
- );
81
- $after = null;
82
- $echo = true;
83
- $allow_create = true;
84
- is_array( $args ) && extract( $args );
85
-
86
- if ( empty( $id ) ) {
87
- $id = $name;
88
- }
89
- $args = array(
90
- 'name' => $name,
91
- 'id' => $id,
92
- 'sort_column' => 'menu_order',
93
- 'sort_order' => 'ASC',
94
- 'show_option_none' => __( 'Select Page', 'learnpress' ),
95
- 'class' => $class,
96
- 'echo' => false,
97
- 'selected' => $selected,
98
- 'allow_create' => true
99
- );
100
- $output = wp_dropdown_pages( $args );
101
- $replace = "";
102
-
103
- $class .= 'learn-press-dropdown-pages';
104
-
105
- if ( $class ) {
106
- $replace .= ' class="' . $class . '"';
107
- }
108
- if ( $css ) {
109
- $replace .= ' style="' . $css . '"';
110
- }
111
-
112
- $replace .= ' data-selected="' . $selected . '"';
113
- $replace .= " data-placeholder='" . __( 'Select a page&hellip;', 'learnpress' ) . "' id=";
114
- $output = str_replace( ' id=', $replace, $output );
115
- if ( $before ) {
116
- $before_output = array();
117
- foreach ( $before as $v => $l ) {
118
- $before_output[] = sprintf( '<option value="%s">%s</option>', $v, $l );
119
- }
120
- $before_output = join( "\n", $before_output );
121
- $output = preg_replace( '!(<option class=".*" value="[0-9]+".*>.*</option>)!', $before_output . "\n$1", $output, 1 );
122
- }
123
- if ( $allow_create ) {
124
- ob_start(); ?>
125
- <button class="button button-quick-add-page" data-id="<?php echo $id; ?>" type="button"><?php _e( 'Create', 'learnpress' ); ?></button>
126
- <p class="learn-press-quick-add-page-inline <?php echo $id; ?> hide-if-js">
127
- <input type="text" placeholder="<?php esc_attr_e( 'New page title', 'learnpress' ); ?>" />
128
- <button class="button" type="button"><?php esc_html_e( 'Ok [Enter]', 'learnpress' ); ?></button>
129
- <a href=""><?php _e( 'Cancel [ESC]', 'learnpress' ); ?></a>
130
- </p>
131
- <p class="learn-press-quick-add-page-actions <?php echo $id; ?><?php echo $selected ? '' : ' hide-if-js'; ?>">
132
- <a class="edit-page" href="<?php echo get_edit_post_link( $selected ); ?>" target="_blank"><?php _e( 'Edit Page', 'learnpress' ); ?></a>
133
- <a class="view-page" href="<?php echo get_permalink( $selected ); ?>" target="_blank"><?php _e( 'View Page', 'learnpress' ); ?></a>
134
- </p>
135
- <?php $output .= ob_get_clean();
136
- }
137
- if ( $echo ) {
138
- echo $output;
139
- }
140
-
141
- return $output;
142
- }
143
-
144
- /**
145
- * List all registered question types into dropdown
146
- *
147
- * @param array
148
- *
149
- * @return string
150
- */
151
- function learn_press_dropdown_question_types( $args = array() ) {
152
- $args = wp_parse_args(
153
- $args,
154
- array(
155
- 'name' => 'learn-press-dropdown-question-types',
156
- 'id' => '',
157
- 'class' => '',
158
- 'selected' => '',
159
- 'echo' => true
160
- )
161
- );
162
- if ( !$args['id'] ) {
163
- $args['id'] = $args['name'];
164
- }
165
- $args['class'] = 'lp-dropdown-question-types' . ( $args['class'] ? ' ' . $args['class'] : '' );
166
- $types = learn_press_question_types();
167
- $output = sprintf( '<select name="%s" id="%s" class="%s"%s>', $args['name'], $args['id'], $args['class'], $args['selected'] ? 'data-selected="' . $args['selected'] . '"' : '' );
168
- foreach ( $types as $slug => $name ) {
169
- $output .= sprintf( '<option value="%s"%s>%s</option>', $slug, selected( $slug == $args['selected'], true, false ), $name );
170
- }
171
- $output .= '</select>';
172
- if ( $args['echo'] ) {
173
- echo $output;
174
- }
175
- return $output;
176
- }
177
-
178
- /**
179
- * List all registered question types into dropdown
180
- *
181
- * @param array
182
- *
183
- * @return string
184
- */
185
- function learn_press_field_question_duration( $args = array(), $question ) {
186
- global $post;
187
- $duration_type = get_post_meta( $post->ID, "_lp_duration_type", true );
188
- $value = get_post_meta( $question->id, '_question_duration', true );
189
-
190
- $wrap_class = 'learn-press-question-duration';
191
- if ( 'questions_duration' !== $duration_type ) {
192
- $wrap_class .= ' hide';
193
- }
194
- $args = wp_parse_args(
195
- $args,
196
- array(
197
- 'name' => 'learn_press_question[' . $question->id . '][duration]',
198
- 'id' => 'learn-press-question-duration-' . $question->id,
199
- 'class' => 'learn-press-question-duration',
200
- 'selected' => '',
201
- 'echo' => true,
202
- 'value' => 0,
203
- 'step' => 1,
204
- 'min' => 0,
205
- 'placeholder' => __( 'Minutes', 'learnpress' ),
206
- )
207
- );
208
- $args['value'] = $value;
209
-
210
- if ( !$args['id'] ) {
211
- $args['id'] = $args['name'];
212
- }
213
-
214
- return '<span class="' . esc_attr( $wrap_class ) . '">' . sprintf(
215
- '<input type="number" class="%s" name="%s" id="%s" value="%s" step="%s" min="%s" max="%s" placeholder="%s"/>',
216
- $args['class'],
217
- $args['name'],
218
- empty( $args['clone'] ) ? $args['id'] : '',
219
- $args['value'],
220
- $args['step'],
221
- $args['min'],
222
- !empty( $args['max'] ) ? $args['max'] : '',
223
- $args['placeholder']
224
- ) . $args['placeholder'] . '</span>';
225
- }
226
-
227
- /**
228
- * Displays email formats support into a dropdown
229
- *
230
- * @param array $args
231
- *
232
- * @return string
233
- */
234
- function learn_press_email_formats_dropdown( $args = array() ) {
235
- $args = wp_parse_args(
236
- $args,
237
- array(
238
- 'name' => 'learn-press-dropdown-email-formats',
239
- 'id' => '',
240
- 'class' => '',
241
- 'selected' => '',
242
- 'echo' => true
243
- )
244
- );
245
- $formats = array(
246
- //'text_message' => __( 'Text message', 'learnpress' ),
247
- 'plain_text' => __( 'Plain text', 'learnpress' ),
248
- 'html' => __( 'HTML', 'learnpress' ),
249
- //'multipart' => __( 'Multipart', 'learnpress' )
250
- );
251
- $output = sprintf( '<select name="%s" id="%s" class="%s" %s>', $args['name'], $args['id'], $args['class'], '' );
252
- foreach ( $formats as $name => $text ) {
253
- $output .= sprintf( '<option value="%s" %s>%s</option>', $name, selected( $args['selected'] == $name, true, false ), $text ) . "\n";
254
- }
255
- $output .= '</select>';
256
-
257
- if ( $args['echo'] ) echo $output;
258
- return $output;
259
- }
260
-
261
- /**************************************************/
262
- /**************************************************/
263
- /**************************************************/
264
-
265
- /**
266
- * Translate javascript text
267
- */
268
- function learn_press_admin_localize_script() {
269
- if ( defined( 'LP_DOING_AJAX' ) || !is_admin() ) return;
270
- $translate = array(
271
- 'quizzes_is_not_available' => __( 'Quiz is not available', 'learnpress' ),
272
- 'lessons_is_not_available' => __( 'Lesson is not available', 'learnpress' ),
273
- 'duplicate_course' => array(
274
- 'title' => __( 'Duplicate course', 'learnpress' ),
275
- 'message' => __( 'Duplicate course curriculum?', 'learnpress' )
276
- ),
277
- 'duplicate_question' => array(
278
- 'title' => __( 'Duplicate Question', 'learnpress' ),
279
- 'message' => __( 'Do you want to duplicate this question?', 'learnpress' )
280
- ),
281
- 'remove_question' => __( 'Do you want to remove this question from quiz?', 'learnpress' ),
282
- 'nonces' => array(
283
- 'duplicate_question' => wp_create_nonce( 'duplicate-question' )
284
- )
285
- );
286
- LP_Assets::add_localize( $translate );
287
- }
288
-
289
- add_action( 'init', 'learn_press_admin_localize_script' );
290
-
291
- /**
292
- * Default admin settings pages
293
- *
294
- * @return mixed
295
- */
296
- function learn_press_settings_tabs_array() {
297
- $tabs = array(
298
- 'general' => __( 'General', 'learnpress' ),
299
- 'courses' => __( 'Courses', 'learnpress' ),
300
- 'pages' => __( 'Pages', 'learnpress' ),
301
- 'payments' => __( 'Payments', 'learnpress' ),
302
- 'checkout' => __( 'Checkout', 'learnpress' ),
303
- //'profile' => __( 'Profile', 'learnpress' ),
304
- 'emails' => __( 'Emails', 'learnpress' )
305
- );
306
- return apply_filters( 'learn_press_settings_tabs_array', $tabs );
307
- }
308
-
309
- /**
310
- * Count number of orders between to dates
311
- *
312
- * @param string
313
- * @param int
314
- *
315
- * @return int
316
- */
317
- function learn_press_get_order_by_time( $by, $time ) {
318
- global $wpdb;
319
- $user_id = get_current_user_id();
320
-
321
- $y = date( 'Y', $time );
322
- $m = date( 'm', $time );
323
- $d = date( 'd', $time );
324
- switch ( $by ) {
325
- case 'days':
326
- $orders = $wpdb->get_var(
327
- $wpdb->prepare(
328
- "SELECT COUNT(*)
329
- FROM $wpdb->posts AS p
330
- INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
331
- WHERE p.post_author = %d
332
- AND p.post_type = %s
333
- AND p.post_status = %s
334
- AND m.meta_key = %s
335
- AND m.meta_value = %s
336
- AND YEAR(p.post_date) = %s AND MONTH(p.post_date) = %s AND DAY(p.post_date) = %s",
337
- $user_id, LP_ORDER_CPT, 'publish', '_learn_press_transaction_status', 'completed', $y, $m, $d
338
- )
339
- );
340
- break;
341
- case 'months':
342
- $orders = $wpdb->get_var(
343
- $wpdb->prepare(
344
- "SELECT COUNT(*)
345
- FROM $wpdb->posts AS p
346
- INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
347
- WHERE p.post_author = %d
348
- AND p.post_type = %s
349
- AND p.post_status = %s
350
- AND m.meta_key = %s
351
- AND m.meta_value = %s
352
- AND YEAR(p.post_date) = %s AND MONTH(p.post_date) = %s",
353
- $user_id, LP_ORDER_CPT, 'publish', '_learn_press_transaction_status', 'completed', $y, $m
354
- )
355
- );
356
- break;
357
- }
358
- return $orders;
359
- }
360
-
361
- /**
362
- * Count number of orders by status
363
- *
364
- * @param string Status of the orders
365
- *
366
- * @return int
367
- */
368
- function learn_press_get_courses_by_status( $status ) {
369
- global $wpdb;
370
- $user_id = get_current_user_id();
371
- $courses = $wpdb->get_var(
372
- $wpdb->prepare(
373
- "SELECT COUNT(*)
374
- FROM $wpdb->posts
375
- WHERE post_author = %d
376
- AND post_type = %s
377
- AND post_status = %s",
378
- $user_id, LP_COURSE_CPT, $status
379
- )
380
- );
381
- return $courses;
382
- }
383
-
384
- /**
385
- * Count number of orders by price
386
- *
387
- * @param string
388
- *
389
- * @return int
390
- */
391
- function learn_press_get_courses_by_price( $fee ) {
392
- global $wpdb;
393
- $user_id = get_current_user_id();
394
- $courses = $wpdb->get_var(
395
- $wpdb->prepare(
396
- "SELECT COUNT(*)
397
- FROM $wpdb->posts AS p
398
- INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
399
- WHERE p.post_author = %d
400
- AND p.post_type = %s
401
- AND p.post_status IN (%s, %s)
402
- AND m.meta_key = %s
403
- AND m.meta_value = %s",
404
- $user_id, LP_COURSE_CPT, 'publish', 'pending', '_lpr_course_payment', $fee
405
- )
406
- );
407
- return $courses;
408
- }
409
-
410
- /**
411
- * Get data about students to render in chart
412
- *
413
- * @param null $from
414
- * @param null $by
415
- * @param $time_ago
416
- *
417
- * @return array
418
- */
419
- function learn_press_get_chart_students( $from = null, $by = null, $time_ago ) {
420
- $labels = array();
421
- $datasets = array();
422
- if ( is_null( $from ) ) {
423
- $from = current_time( 'mysql' );
424
- }
425
- // $by: days, months or years
426
- if ( is_null( $by ) ) {
427
- $by = 'days';
428
- }
429
- switch ( $by ) {
430
- case 'days':
431
- $date_format = 'M d';
432
- break;
433
- case 'months':
434
- $date_format = 'M Y';
435
- break;
436
- case 'years':
437
- $date_format = 'Y';
438
- break;
439
- }
440
-
441
- for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
442
- $labels[] = date( $date_format, strtotime( "$i $by", strtotime( $from ) ) );
443
- $datasets[0]['data'][] = learn_press_get_order_by_time( $by, strtotime( "$i $by", strtotime( $from ) ) );
444
- }
445
- $colors = learn_press_get_admin_colors();
446
- $datasets[0]['fillColor'] = 'rgba(255,255,255,0.1)';
447
- $datasets[0]['strokeColor'] = $colors[0];
448
- $datasets[0]['pointColor'] = $colors[0];
449
- $datasets[0]['pointStrokeColor'] = $colors[2];
450
- $datasets[0]['pointHighlightFill'] = $colors[2];
451
- $datasets[0]['pointHighlightStroke'] = $colors[0];
452
- return array(
453
- 'labels' => $labels,
454
- 'datasets' => $datasets
455
- );
456
- }
457
-
458
- /**
459
- * Get data about students to render in chart
460
- *
461
- * @param null $from
462
- * @param null $by
463
- * @param $time_ago
464
- *
465
- * @return array
466
- */
467
- function learn_press_get_chart_users( $from = null, $by = null, $time_ago ) {
468
- global $wpdb;
469
-
470
- $labels = array();
471
- $datasets = array();
472
- if ( is_null( $from ) ) {
473
- $from = current_time( 'mysql' );
474
- }
475
- if ( is_null( $by ) ) {
476
- $by = 'days';
477
- }
478
- $results = array(
479
- 'all' => array(),
480
- 'instructors' => array()
481
- );
482
- $from_time = is_numeric( $from ) ? $from : strtotime( $from );
483
-
484
- switch ( $by ) {
485
- case 'days':
486
- $date_format = 'M d Y';
487
- $_from = - $time_ago + 1;
488
- $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
489
- $_to = date( 'Y-m-d', $from_time );
490
- $_sql_format = '%Y-%m-%d';
491
- $_key_format = 'Y-m-d';
492
- break;
493
- case 'months':
494
- $date_format = 'M Y';
495
- $_from = - $time_ago + 1;
496
- $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
497
- $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
498
- $_to = date( 'Y-m-' . $days, $from_time );
499
- $_sql_format = '%Y-%m';
500
- $_key_format = 'Y-m';
501
- break;
502
- case 'years':
503
- $date_format = 'Y';
504
- $_from = - $time_ago + 1;
505
- $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
506
- $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
507
- $_to = date( 'Y-12-' . $days, $from_time );
508
- $_sql_format = '%Y';
509
- $_key_format = 'Y';
510
-
511
- break;
512
- }
513
- $query = $wpdb->prepare( "
514
- SELECT count(u.ID) as c, DATE_FORMAT( u.user_registered, %s) as d
515
- FROM {$wpdb->users} u
516
- WHERE 1
517
- GROUP BY d
518
- HAVING d BETWEEN %s AND %s
519
- ORDER BY d ASC
520
- ", $_sql_format, $_from, $_to );
521
- if ( $_results = $wpdb->get_results( $query ) ) {
522
- foreach ( $_results as $k => $v ) {
523
- $results['all'][$v->d] = $v;
524
- }
525
- }
526
- $query = $wpdb->prepare( "
527
- SELECT count(u.ID) as c, DATE_FORMAT( u.user_registered, %s) as d
528
- FROM {$wpdb->users} u
529
- INNER JOIN {$wpdb->usermeta} um ON um.user_id = u.ID AND um.meta_key = %s AND ( um.meta_value LIKE %s OR um.meta_value LIKE %s )
530
- WHERE 1
531
- GROUP BY d
532
- HAVING d BETWEEN %s AND %s
533
- ORDER BY d ASC
534
- ", $_sql_format, 'wp_capabilities', '%' . $wpdb->esc_like( 's:13:"administrator"' ) . '%', '%' . $wpdb->esc_like( 's:10:"lp_teacher"' ) . '%', $_from, $_to );
535
-
536
- if ( $_results = $wpdb->get_results( $query ) ) {
537
- foreach ( $_results as $k => $v ) {
538
- $results['instructors'][$v->d] = $v;
539
- }
540
- }
541
- for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
542
- $date = strtotime( "$i $by", $from_time );
543
- $labels[] = date( $date_format, $date );
544
- $key = date( $_key_format, $date );
545
-
546
- $all = !empty( $results['all'][$key] ) ? $results['all'][$key]->c : 0;
547
- $instructors = !empty( $results['instructors'][$key] ) ? $results['instructors'][$key]->c : 0;
548
-
549
- $datasets[0]['data'][] = $all;
550
- $datasets[1]['data'][] = $instructors;
551
- $datasets[2]['data'][] = $all - $instructors;
552
- }
553
-
554
- $dataset_params = array(
555
- array(
556
- 'color1' => 'rgba(47, 167, 255, %s)',
557
- 'color2' => '#FFF',
558
- 'label' => __( 'All', 'learnpress' )
559
- ),
560
- array(
561
- 'color1' => 'rgba(212, 208, 203, %s)',
562
- 'color2' => '#FFF',
563
- 'label' => __( 'Instructors', 'learnpress' )
564
- ),
565
- array(
566
- 'color1' => 'rgba(234, 199, 155, %s)',
567
- 'color2' => '#FFF',
568
- 'label' => __( 'Students', 'learnpress' )
569
- )
570
- );
571
-
572
- foreach ( $dataset_params as $k => $v ) {
573
- $datasets[$k]['fillColor'] = sprintf( $v['color1'], '0.2' );
574
- $datasets[$k]['strokeColor'] = sprintf( $v['color1'], '1' );
575
- $datasets[$k]['pointColor'] = sprintf( $v['color1'], '1' );
576
- $datasets[$k]['pointStrokeColor'] = $v['color2'];
577
- $datasets[$k]['pointHighlightFill'] = $v['color2'];
578
- $datasets[$k]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
579
- $datasets[$k]['label'] = $v['label'];
580
- }
581
-
582
- return array(
583
- 'labels' => $labels,
584
- 'datasets' => $datasets,
585
- 'sql' => $query
586
- );
587
- }
588
-
589
-
590
- /**
591
- * Get data about students to render in chart
592
- *
593
- * @param null $from
594
- * @param null $by
595
- * @param $time_ago
596
- *
597
- * @return array
598
- */
599
- function learn_press_get_chart_courses( $from = null, $by = null, $time_ago ) {
600
- global $wpdb;
601
-
602
- $labels = array();
603
- $datasets = array();
604
- if ( is_null( $from ) ) {
605
- $from = current_time( 'mysql' );
606
- }
607
- if ( is_null( $by ) ) {
608
- $by = 'days';
609
- }
610
- $results = array(
611
- 'all' => array(),
612
- 'public' => array(),
613
- 'pending' => array(),
614
- 'free' => array(),
615
- 'paid' => array()
616
- );
617
- $from_time = is_numeric( $from ) ? $from : strtotime( $from );
618
-
619
- switch ( $by ) {
620
- case 'days':
621
- $date_format = 'M d Y';
622
- $_from = - $time_ago + 1;
623
- $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
624
- $_to = date( 'Y-m-d', $from_time );
625
- $_sql_format = '%Y-%m-%d';
626
- $_key_format = 'Y-m-d';
627
- break;
628
- case 'months':
629
- $date_format = 'M Y';
630
- $_from = - $time_ago + 1;
631
- $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
632
- $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
633
- $_to = date( 'Y-m-' . $days, $from_time );
634
- $_sql_format = '%Y-%m';
635
- $_key_format = 'Y-m';
636
- break;
637
- case 'years':
638
- $date_format = 'Y';
639
- $_from = - $time_ago + 1;
640
- $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
641
- $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
642
- $_to = date( 'Y-12-' . $days, $from_time );
643
- $_sql_format = '%Y';
644
- $_key_format = 'Y';
645
-
646
- break;
647
- }
648
-
649
- $query_where = '';
650
- if ( current_user_can( LP_TEACHER_ROLE ) ) {
651
- $user_id = learn_press_get_current_user_id();
652
- $query_where .= $wpdb->prepare( " AND c.post_author=%d ", $user_id );
653
- }
654
-
655
- $query = $wpdb->prepare( "
656
- SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
657
- FROM {$wpdb->posts} c
658
- WHERE 1
659
- {$query_where}
660
- AND c.post_status IN('publish', 'pending') AND c.post_type = %s
661
- GROUP BY d
662
- HAVING d BETWEEN %s AND %s
663
- ORDER BY d ASC
664
- ", $_sql_format, 'lp_course', $_from, $_to );
665
- if ( $_results = $wpdb->get_results( $query ) ) {
666
- foreach ( $_results as $k => $v ) {
667
- $results['all'][$v->d] = $v;
668
- }
669
- }
670
- $query = $wpdb->prepare( "
671
- SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
672
- FROM {$wpdb->posts} c
673
- WHERE 1
674
- {$query_where}
675
- AND c.post_status = %s AND c.post_type = %s
676
- GROUP BY d
677
- HAVING d BETWEEN %s AND %s
678
- ORDER BY d ASC
679
- ", $_sql_format, 'publish', 'lp_course', $_from, $_to );
680
- if ( $_results = $wpdb->get_results( $query ) ) {
681
- foreach ( $_results as $k => $v ) {
682
- $results['publish'][$v->d] = $v;
683
- }
684
- }
685
-
686
- $query = $wpdb->prepare( "
687
- SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
688
- FROM {$wpdb->posts} c
689
- INNER JOIN {$wpdb->postmeta} cm ON cm.post_id = c.ID AND cm.meta_key = %s AND cm.meta_value = %s
690
- WHERE 1
691
- {$query_where}
692
- AND c.post_status = %s AND c.post_type = %s
693
- GROUP BY d
694
- HAVING d BETWEEN %s AND %s
695
- ORDER BY d ASC
696
- ", $_sql_format, '_lp_payment', 'yes', 'publish', 'lp_course', $_from, $_to );
697
- if ( $_results = $wpdb->get_results( $query ) ) {
698
- foreach ( $_results as $k => $v ) {
699
- $results['paid'][$v->d] = $v;
700
- }
701
- }
702
-
703
- for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
704
- $date = strtotime( "$i $by", $from_time );
705
- $labels[] = date( $date_format, $date );
706
- $key = date( $_key_format, $date );
707
-
708
- $all = !empty( $results['all'][$key] ) ? $results['all'][$key]->c : 0;
709
- $publish = !empty( $results['publish'][$key] ) ? $results['publish'][$key]->c : 0;
710
- $paid = !empty( $results['paid'][$key] ) ? $results['paid'][$key]->c : 0;
711
-
712
- $datasets[0]['data'][] = $all;
713
- $datasets[1]['data'][] = $publish;
714
- $datasets[2]['data'][] = $all - $publish;
715
- $datasets[3]['data'][] = $paid;
716
- $datasets[4]['data'][] = $all - $paid;
717
- }
718
-
719
- $dataset_params = array(
720
- array(
721
- 'color1' => 'rgba(47, 167, 255, %s)',
722
- 'color2' => '#FFF',
723
- 'label' => __( 'All', 'learnpress' )
724
- ),
725
- array(
726
- 'color1' => 'rgba(212, 208, 203, %s)',
727
- 'color2' => '#FFF',
728
- 'label' => __( 'Publish', 'learnpress' )
729
- ),
730
- array(
731
- 'color1' => 'rgba(234, 199, 155, %s)',
732
- 'color2' => '#FFF',
733
- 'label' => __( 'Pending', 'learnpress' )
734
- ),
735
- array(
736
- 'color1' => 'rgba(234, 199, 155, %s)',
737
- 'color2' => '#FFF',
738
- 'label' => __( 'Paid', 'learnpress' )
739
- ),
740
- array(
741
- 'color1' => 'rgba(234, 199, 155, %s)',
742
- 'color2' => '#FFF',
743
- 'label' => __( 'Free', 'learnpress' )
744
- )
745
- );
746
-
747
- foreach ( $dataset_params as $k => $v ) {
748
- $datasets[$k]['fillColor'] = sprintf( $v['color1'], '0.2' );
749
- $datasets[$k]['strokeColor'] = sprintf( $v['color1'], '1' );
750
- $datasets[$k]['pointColor'] = sprintf( $v['color1'], '1' );
751
- $datasets[$k]['pointStrokeColor'] = $v['color2'];
752
- $datasets[$k]['pointHighlightFill'] = $v['color2'];
753
- $datasets[$k]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
754
- $datasets[$k]['label'] = $v['label'];
755
- }
756
-
757
- return array(
758
- 'labels' => $labels,
759
- 'datasets' => $datasets,
760
- 'sql' => $query
761
- );
762
- }
763
-
764
-
765
- /**
766
- * Get data about students to render in chart
767
- *
768
- * @param null $from
769
- * @param null $by
770
- * @param $time_ago
771
- *
772
- * @return array
773
- */
774
- function learn_press_get_chart_orders( $from = null, $by = null, $time_ago ) {
775
- global $wpdb;
776
- // var_dump( current_user_can(LP_TEACHER_ROLE) );
777
- // exit();
778
- $report_sales_by = learn_press_get_request( 'report_sales_by' );
779
- $course_id = learn_press_get_request( 'course_id' );
780
- $cat_id = learn_press_get_request( 'cat_id' );
781
-
782
- $labels = array();
783
- $datasets = array();
784
- if ( is_null( $from ) ) {
785
- $from = current_time( 'mysql' );
786
- }
787
- if ( is_null( $by ) ) {
788
- $by = 'days';
789
- }
790
- $results = array(
791
- 'all' => array(),
792
- 'completed' => array(),
793
- 'pending' => array()
794
- );
795
- $from_time = is_numeric( $from ) ? $from : strtotime( $from );
796
-
797
- switch ( $by ) {
798
- case 'days':
799
- $date_format = 'M d Y';
800
- $_from = - $time_ago + 1;
801
- $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
802
- $_to = date( 'Y-m-d', $from_time );
803
- $_sql_format = '%Y-%m-%d';
804
- $_key_format = 'Y-m-d';
805
- break;
806
- case 'months':
807
- $date_format = 'M Y';
808
- $_from = - $time_ago + 1;
809
- $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
810
- $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
811
- $_to = date( 'Y-m-' . $days, $from_time );
812
- $_sql_format = '%Y-%m';
813
- $_key_format = 'Y-m';
814
- break;
815
- case 'years':
816
- $date_format = 'Y';
817
- $_from = - $time_ago + 1;
818
- $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
819
- $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
820
- $_to = date( 'Y-12-' . $days, $from_time );
821
- $_sql_format = '%Y';
822
- $_key_format = 'Y';
823
-
824
- break;
825
- }
826
-
827
- $query_join = '';
828
- $query_where = '';
829
- if ( 'course' === $report_sales_by ) {
830
- $sql_join .= " INNER JOIN `{$wpdb->prefix}learnpress_order_items` `lpoi` "
831
- . " ON o.ID=lpoi.order_id "
832
- . " INNER JOIN {$wpdb->prefix}learnpress_order_itemmeta loim "
833
- . " ON lpoi.order_item_id=loim.learnpress_order_item_id "
834
- . " AND loim.meta_key='_course_id' "
835
- . " AND CAST(loim.meta_value AS SIGNED)=%d ";
836
- if ( current_user_can( LP_TEACHER_ROLE ) ) {
837
- $user_id = learn_press_get_current_user_id();
838
- $sql_join .= $wpdb->prepare( " AND CAST(loim.meta_value AS SIGNED) IN "
839
- . " ( "
840
- . " SELECT ID FROM {$wpdb->posts} p WHERE p.ID = CAST(loim.meta_value AS SIGNED) AND `post_author`=" . intval( $user_id )
841
- . " ) " );
842
- }
843
- $query_join .= $wpdb->prepare( $sql_join, $course_id );
844
-
845
- } elseif ( 'category' === $report_sales_by ) {
846
- $sql_join .= " INNER JOIN `{$wpdb->prefix}learnpress_order_items` `lpoi` "
847
- . " ON o.ID=lpoi.order_id "
848
- . " INNER JOIN {$wpdb->prefix}learnpress_order_itemmeta loim "
849
- . " ON lpoi.order_item_id=loim.learnpress_order_item_id "
850
- . " AND loim.meta_key='_course_id' "
851
- . " AND CAST(loim.meta_value AS SIGNED) IN("
852
- //sub query
853
- . " SELECT tr.object_id "
854
- . " FROM wp_term_taxonomy tt INNER JOIN wp_term_relationships tr "
855
- . " ON tt.term_taxonomy_id = tr.term_taxonomy_id AND tt.taxonomy='course_category' "
856
- . " WHERE tt.term_id=%d)";
857
- $query_join .= $wpdb->prepare( $sql_join, $cat_id );
858
- }
859
- if ( current_user_can( LP_TEACHER_ROLE ) ) {
860
- $user_id = learn_press_get_current_user_id();
861
- $query_where .= $wpdb->prepare( " AND o.ID IN( SELECT oi.order_id
862
- FROM lptest.{$wpdb->prefix}learnpress_order_items oi
863
- inner join {$wpdb->prefix}learnpress_order_itemmeta oim
864
- on oi.order_item_id = oim.learnpress_order_item_id
865
- and oim.meta_key='_course_id'
866
- and cast(oim.meta_value as SIGNED) IN (
867
- SELECT sp.ID FROM {$wpdb->prefix}posts sp WHERE sp.post_author=%d and sp.ID=cast(oim.meta_value as SIGNED)
868
- )
869
- ) ", $user_id );
870
- }
871
-
872
- $query = $wpdb->prepare( "
873
- SELECT count(o.ID) as c, DATE_FORMAT( o.post_date, %s) as d
874
- FROM {$wpdb->posts} o {$query_join}
875
- WHERE 1 {$query_where}
876
- AND o.post_status IN('lp-completed') AND o.post_type = %s
877
- GROUP BY d
878
- HAVING d BETWEEN %s AND %s
879
- ORDER BY d ASC
880
- ", $_sql_format, 'lp_order', $_from, $_to );
881
- // echo $query;
882
- if ( $_results = $wpdb->get_results( $query ) ) {
883
- foreach ( $_results as $k => $v ) {
884
- // $results['all'][$v->d] = $v;
885
- $results['completed'][$v->d] = $v;
886
- }
887
- }
888
-
889
- $query = $wpdb->prepare( "
890
- SELECT count(o.ID) as c, DATE_FORMAT( o.post_date, %s) as d
891
- FROM {$wpdb->posts} o {$query_join}
892
- WHERE 1 {$query_where}
893
- AND o.post_status IN('lp-pending', 'lp-processing') AND o.post_type = %s
894
- GROUP BY d
895
- HAVING d BETWEEN %s AND %s
896
- ORDER BY d ASC
897
- ", $_sql_format, 'lp_order', $_from, $_to );
898
- // echo $query;
899
- if ( $_results = $wpdb->get_results( $query ) ) {
900
- foreach ( $_results as $k => $v ) {
901
- // $results['completed'][$v->d] = $v;
902
- $results['pending'][$v->d] = $v;
903
- }
904
- }
905
-
906
-
907
- for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
908
- $date = strtotime( "$i $by", $from_time );
909
- $labels[] = date( $date_format, $date );
910
- $key = date( $_key_format, $date );
911
-
912
- $completed = !empty( $results['completed'][$key] ) ? $results['completed'][$key]->c : 0;
913
- $pending = !empty( $results['pending'][$key] ) ? $results['pending'][$key]->c : 0;
914
- $all = $completed + $pending;
915
-
916
- $datasets[0]['data'][] = $all;
917
- $datasets[1]['data'][] = $completed;
918
- $datasets[2]['data'][] = $pending;
919
- }
920
-
921
- $dataset_params = array(
922
- array(
923
- 'color1' => 'rgba(47, 167, 255, %s)',
924
- 'color2' => '#FFF',
925
- 'label' => __( 'All', 'learnpress' )
926
- ),
927
- array(
928
- 'color1' => 'rgba(212, 208, 203, %s)',
929
- 'color2' => '#FFF',
930
- 'label' => __( 'Completed', 'learnpress' )
931
- ),
932
- array(
933
- 'color1' => 'rgba(234, 199, 155, %s)',
934
- 'color2' => '#FFF',
935
- 'label' => __( 'Pending', 'learnpress' )
936
- )
937
- );
938
-
939
- foreach ( $dataset_params as $k => $v ) {
940
- $datasets[$k]['fillColor'] = sprintf( $v['color1'], '0.2' );
941
- $datasets[$k]['strokeColor'] = sprintf( $v['color1'], '1' );
942
- $datasets[$k]['pointColor'] = sprintf( $v['color1'], '1' );
943
- $datasets[$k]['pointStrokeColor'] = $v['color2'];
944
- $datasets[$k]['pointHighlightFill'] = $v['color2'];
945
- $datasets[$k]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
946
- $datasets[$k]['label'] = $v['label'];
947
- }
948
-
949
- return array(
950
- 'labels' => $labels,
951
- 'datasets' => $datasets,
952
- 'sql' => $query
953
- );
954
- }
955
-
956
- /**
957
- * Get data about courses to render in the chart
958
- * @return array
959
- */
960
- function learn_press_get_chart_courses2() {
961
- $labels = array( __( 'Pending Courses / Publish Courses', 'learnpress' ), __( 'Free Courses / Priced Courses', 'learnpress' ) );
962
- $datasets = array();
963
- $datasets[0]['data'] = array( learn_press_get_courses_by_status( 'pending' ), learn_press_get_courses_by_price( 'free' ) );
964
- $datasets[1]['data'] = array( learn_press_get_courses_by_status( 'publish' ), learn_press_get_courses_by_price( 'not_free' ) );
965
-
966
- $colors = learn_press_get_admin_colors();
967
- $datasets[0]['fillColor'] = $colors[1];
968
- $datasets[0]['strokeColor'] = $colors[1];
969
- $datasets[1]['fillColor'] = $colors[3];
970
- $datasets[1]['strokeColor'] = $colors[3];
971
- return array(
972
- 'labels' => $labels,
973
- 'datasets' => $datasets
974
- );
975
- }
976
-
977
- /**
978
- * Get colors setting up by admin user
979
- * @return array
980
- */
981
- function learn_press_get_admin_colors() {
982
- $admin_color = get_user_meta( get_current_user_id(), 'admin_color', true );
983
- global $_wp_admin_css_colors;
984
- $colors = array();
985
- if ( !empty( $_wp_admin_css_colors[$admin_color]->colors ) ) {
986
- $colors = $_wp_admin_css_colors[$admin_color]->colors;
987
- }
988
- if ( empty ( $colors[0] ) ) {
989
- $colors[0] = '#000000';
990
- }
991
- if ( empty ( $colors[2] ) ) {
992
- $colors[2] = '#00FF00';
993
- }
994
- return $colors;
995
- }
996
-
997
- /**
998
- * Convert an array to json format and print out to browser
999
- *
1000
- * @param array $chart
1001
- */
1002
- function learn_press_process_chart( $chart = array() ) {
1003
- $data = json_encode(
1004
- array(
1005
- 'labels' => $chart['labels'],
1006
- 'datasets' => $chart['datasets']
1007
- )
1008
- );
1009
- echo $data;
1010
- }
1011
-
1012
- /**
1013
- * Print out the configuration for admin chart
1014
- */
1015
- function learn_press_config_chart() {
1016
- $colors = learn_press_get_admin_colors();
1017
- $config = array(
1018
- 'scaleShowGridLines' => true,
1019
- 'scaleGridLineColor' => "#777",
1020
- 'scaleGridLineWidth' => 0.3,
1021
- 'scaleFontColor' => "#444",
1022
- 'scaleLineColor' => $colors[0],
1023
- 'bezierCurve' => true,
1024
- 'bezierCurveTension' => 0.2,
1025
- 'pointDotRadius' => 5,
1026
- 'pointDotStrokeWidth' => 5,
1027
- 'pointHitDetectionRadius' => 20,
1028
- 'datasetStroke' => true,
1029
- 'responsive' => true,
1030
- 'tooltipFillColor' => $colors[2],
1031
- 'tooltipFontColor' => "#eee",
1032
- 'tooltipCornerRadius' => 0,
1033
- 'tooltipYPadding' => 10,
1034
- 'tooltipXPadding' => 10,
1035
- 'barDatasetSpacing' => 10,
1036
- 'barValueSpacing' => 200
1037
-
1038
- );
1039
- echo json_encode( $config );
1040
- }
1041
-
1042
- function set_post_order_in_admin( $wp_query ) {
1043
- global $pagenow;
1044
- if ( isset( $_GET['post_type'] ) ) {
1045
- $post_type = $_GET['post_type'];
1046
- } else $post_type = '';
1047
- if ( is_admin() && 'edit.php' == $pagenow && $post_type == LP_COURSE_CPT && !isset( $_GET['orderby'] ) ) {
1048
- $wp_query->set( 'orderby', 'date' );
1049
- $wp_query->set( 'order', 'DSC' );
1050
- }
1051
- }
1052
-
1053
- add_filter( 'pre_get_posts', 'set_post_order_in_admin' );
1054
- /**
1055
- * Add actions to the list of the course. e.g: Duplicate link
1056
- *
1057
- * @param $actions
1058
- *
1059
- * @return mixed
1060
- */
1061
- function learn_press_add_row_action_link( $actions ) {
1062
- global $post;
1063
- if ( LP_COURSE_CPT == $post->post_type ) {
1064
- $duplicate_link = admin_url( 'edit.php?post_type=lp_course&action=lp-duplicate-course&post=' . $post->ID . '&nonce=' . wp_create_nonce( 'lp-duplicate-' . $post->ID ) );
1065
- $duplicate_link = array(
1066
- array(
1067
- 'link' => $duplicate_link,
1068
- 'title' => __( 'Duplicate this course', 'learnpress' ),
1069
- 'class' => 'lp-duplicate-course'
1070
- )
1071
- );
1072
- $links = apply_filters( 'learn_press_row_action_links', $duplicate_link );
1073
- if ( count( $links ) > 1 ) {
1074
- $drop_down = array( '<ul class="lpr-row-action-dropdown">' );
1075
- foreach ( $links as $link ) {
1076
- $drop_down[] = '<li>' . sprintf( '<a href="%s" class="%s">%s</a>', $link['link'], $link['class'], $link['title'] ) . '</li>';
1077
- };
1078
- $drop_down[] = '</ul>';
1079
- $link = sprintf( '<div class="lpr-row-actions"><a href="%s">%s</a>%s</div>', 'javascript: void(0);', __( 'Course', 'learnpress' ), join( "\n", $drop_down ) );
1080
- } else {
1081
- $link = array_shift( $links );
1082
- $link = sprintf( '<a href="%s" class="%s">%s</a>', $link['link'], $link['class'], $link['title'] );
1083
- }
1084
- $actions['lpr-course-row-action'] = $link;
1085
- } else if ( LP_QUIZ_CPT === $post->post_type ) {
1086
- unset( $actions['view'] );
1087
- $url = admin_url( 'edit.php?post_type=' . LP_QUIZ_CPT . '&lp-action=lp-duplicate-quiz&post=' . $post->ID . '&nonce=' . wp_create_nonce( 'lp-duplicate-' . $post->ID ) );
1088
- $link = sprintf( '<a href="%s" class="lp-duplicate-lesson">%s</a>', $url, __( 'Duplicate this quiz', 'learnpress' ) );
1089
- $actions['lpr-course-row-action'] = $link;
1090
- } else if ( LP_QUESTION_CPT === $post->post_type ) {
1091
- unset( $actions['view'] );
1092
- $url = admin_url( 'edit.php?post_type=' . LP_QUESTION_CPT . '&lp-action=lp-duplicate-question&post=' . $post->ID . '&nonce=' . wp_create_nonce( 'lp-duplicate-' . $post->ID ) );
1093
- $link = sprintf( '<a href="%s" class="lp-duplicate-lesson">%s</a>', $url, __( 'Duplicate this question', 'learnpress' ) );
1094
- $actions['lpr-course-row-action'] = $link;
1095
- } else if ( LP_LESSON_CPT === $post->post_type ) {
1096
- unset( $actions['view'] );
1097
- $url = admin_url( 'edit.php?post_type=' . LP_LESSON_CPT . '&lp-action=lp-duplicate-lesson&post=' . $post->ID . '&nonce=' . wp_create_nonce( 'lp-duplicate-' . $post->ID ) );
1098
- $link = sprintf( '<a href="%s" class="lp-duplicate-lesson">%s</a>', $url, __( 'Duplicate this lesson', 'learnpress' ) );
1099
- $actions['lpr-course-row-action'] = $link;
1100
- }
1101
- return $actions;
1102
- }
1103
-
1104
- add_filter( 'post_row_actions', 'learn_press_add_row_action_link' );
1105
- add_filter( 'page_row_actions', 'learn_press_add_row_action_link' );
1106
-
1107
- function learn_press_copy_post_meta( $from_id, $to_id ) {
1108
- global $wpdb;
1109
- $course_meta = $wpdb->get_results(
1110
- $wpdb->prepare( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id = %d", $from_id )
1111
- );
1112
- if ( count( $course_meta ) != 0 ) {
1113
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
1114
- $sql_query_sel = array();
1115
-
1116
- foreach ( $course_meta as $meta ) {
1117
- $meta_key = $meta->meta_key;
1118
- $meta_value = addslashes( $meta->meta_value );
1119
-
1120
- $sql_query_sel[] = "SELECT {$to_id}, '$meta_key', '$meta_value'";
1121
- }
1122
-
1123
- $sql_query .= implode( " UNION ALL ", $sql_query_sel );
1124
- $wpdb->query( $sql_query );
1125
- }
1126
- }
1127
-
1128
- /**
1129
- * Duplicate a course when user hit "Duplicate" button
1130
- *
1131
- * @author TuNN
1132
- */
1133
- function learn_press_process_duplicate_action() {
1134
-
1135
- $wp_list_table = _get_list_table( 'WP_Posts_List_Table' );
1136
- $action = $wp_list_table->current_action();
1137
-
1138
- if ( isset( $_REQUEST['action'] ) && $action == 'lp-duplicate-course' ) {
1139
- // current is not usefully because this feature using ajax action
1140
- $post_id = isset( $_REQUEST['post'] ) ? $_REQUEST['post'] : 0;
1141
- $nonce = !empty( $_REQUEST['nonce'] ) ? $_REQUEST['nonce'] : '';
1142
- if ( !wp_verify_nonce( $nonce, 'lp-duplicate-' . $post_id ) ) {
1143
- wp_die( __( 'Error', 'learnpress' ) );
1144
- }
1145
- if ( $post_id && is_array( $post_id ) ) {
1146
- $post_id = array_shift( $post_id );
1147
- }
1148
- // check for post is exists
1149
- if ( !( $post_id && $post = get_post( $post_id ) ) ) {
1150
- wp_die( __( 'Oops! The course does not exist.', 'learnpress' ) );
1151
- }
1152
- // ensure that user can create course
1153
- if ( !current_user_can( 'edit_posts' ) ) {
1154
- wp_die( __( 'Sorry! You have not permission to duplicate this course.', 'learnpress' ) );
1155
- }
1156
-
1157
- // assign course to current user
1158
- $current_user = wp_get_current_user();
1159
- $new_course_author = $current_user->ID;
1160
-
1161
- // setup course data
1162
- $new_course_title = $post->post_title . ' - Copy';
1163
- $args = array(
1164
- 'comment_status' => $post->comment_status,
1165
- 'ping_status' => $post->ping_status,
1166
- 'post_author' => $new_course_author,
1167
- 'post_content' => $post->post_content,
1168
- 'post_excerpt' => $post->post_excerpt,
1169
- 'post_name' => $post->post_name,
1170
- 'post_parent' => $post->post_parent,
1171
- 'post_password' => $post->post_password,
1172
- 'post_status' => 'draft',
1173
- 'post_title' => $new_course_title,
1174
- 'post_type' => $post->post_type,
1175
- 'to_ping' => $post->to_ping,
1176
- 'menu_order' => $post->menu_order
1177
- );
1178
-
1179
- // insert new course and get it ID
1180
- $new_post_id = wp_insert_post( $args );
1181
-
1182
- if ( !$new_post_id ) {
1183
- LP_Admin_Notice::add_redirect( __( '<p>Sorry! Duplicate course failed!</p>', 'learnpress' ) );
1184
- wp_redirect( admin_url( 'edit.php?post_type=lp_course' ) );
1185
- exit();
1186
- }
1187
- // assign related tags/categories to new course
1188
- $taxonomies = get_object_taxonomies( $post->post_type );
1189
- foreach ( $taxonomies as $taxonomy ) {
1190
- $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
1191
- wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false );
1192
- }
1193
-
1194
- // duplicate course data
1195
- global $wpdb;
1196
- //learn_press_copy_post_meta( $post_id, $new_post_id );
1197
-
1198
- $query = $wpdb->prepare( "
1199
- SELECT *
1200
- FROM {$wpdb->prefix}learnpress_sections s
1201
- INNER JOIN {$wpdb->posts} c ON c.ID = s.section_course_id
1202
- WHERE c.ID = %d
1203
- ", $post->ID );
1204
- if ( $sections = $wpdb->get_results( $query ) ) {
1205
- foreach ( $sections as $section ) {
1206
- $new_section_id = $wpdb->insert(
1207
- $wpdb->prefix . 'learnpress_sections',
1208
- array(
1209
- 'section_name' => $section->section_name,
1210
- 'section_course_id' => $new_post_id,
1211
- 'section_order' => $section->section_order,
1212
- 'section_description' => $section->section_description
1213
- ),
1214
- array( '%s', '%d', '%d', '%s' )
1215
- );
1216
- if ( $new_section_id ) {
1217
- $query = $wpdb->prepare( "
1218
- SELECT i.*
1219
- FROM {$wpdb->posts} i
1220
- INNER JOIN {$wpdb->prefix}learnpress_sections s ON i.item_id = i.ID
1221
- WHERE s.section_id = %d
1222
- ", $section->section_id );
1223
- if ( $items = $wpdb->get_results( $query ) ) {
1224
- foreach ( $items as $item ) {
1225
- $item_args = (array) $item;
1226
- unset(
1227
- $item_args['ID'],
1228
- $item_args['post_author'],
1229
- $item_args['post_date'],
1230
- $item_args['post_date_gmt'],
1231
- $item_args['post_modified'],
1232
- $item_args['post_modified_gmt'],
1233
- $item_args['comment_count']
1234
- );
1235
- $new_item_id = $wpdb->insert(
1236
- $wpdb->posts,
1237
- $item_args
1238
- );
1239
- }
1240
- }
1241
- }
1242
- }
1243
- }
1244
- LP_Admin_Notice::add_redirect( __( '<p>Course duplicated.</p>', 'learnpress' ) );
1245
- wp_redirect( admin_url( "post.php?post={$new_post_id}&action=edit" ) );
1246
- die();
1247
- }
1248
-
1249
- // duplicate action
1250
- $action = !empty( $_REQUEST['lp-action'] ) ? $_REQUEST['lp-action'] : '';
1251
- $actions = array(
1252
- 'lp-duplicate-question',
1253
- 'lp-duplicate-lesson',
1254
- 'lp-duplicate-quiz'
1255
- );
1256
- if ( !in_array( $action, $actions ) ) {
1257
- return;
1258
- }
1259
-
1260
- $post_id = !empty ( $_REQUEST['post'] ) ? $_REQUEST['post'] : 0;
1261
- $nonce = !empty( $_REQUEST['nonce'] ) ? $_REQUEST['nonce'] : '';
1262
- if ( !$post_id || !wp_verify_nonce( $nonce, 'lp-duplicate-' . $post_id ) ) return;
1263
- // only duplicate question. not assign any data
1264
- $new_post_id = 0;
1265
- if ( $action === 'lp-duplicate-question' ) {
1266
- $new_post_id = learn_press_duplicate_question( $post_id );
1267
- $post_type = LP_QUESTION_CPT;
1268
- $error = __( 'Sorry! Duplicate question failed!', 'learnpress' );
1269
- $success = __( 'Question duplicated.', 'learnpress' );
1270
- } else if ( $action === 'lp-duplicate-lesson' ) {
1271
- $new_post_id = learn_press_duplicate_lesson( $post_id );
1272
- $post_type = LP_LESSON_CPT;
1273
- $error = __( 'Sorry! Duplicate lesson failed!', 'learnpress' );
1274
- $success = __( 'Lesson duplicated.', 'learnpress' );
1275
- } else if ( $action === 'lp-duplicate-quiz' ) {
1276
- $new_post_id = learn_press_duplicate_quiz( $post_id );
1277
- $post_type = LP_QUIZ_CPT;
1278
- $error = __( 'Sorry! Duplicate quiz failed!', 'learnpress' );
1279
- $success = __( 'Quiz duplicated.', 'learnpress' );
1280
- }
1281
-
1282
- if ( !$new_post_id ) return;
1283
- $redirect = 0;
1284
- if ( is_wp_error( $new_post_id ) ) {
1285
- LP_Admin_Notice::add_redirect( $error, 'error' );
1286
- $redirect = admin_url( 'edit.php?post_type=' . $post_type );
1287
- } else {
1288
- LP_Admin_Notice::add_redirect( $success, 'updated' );
1289
- $redirect = admin_url( 'post.php?post=' . $new_post_id . '&action=edit' );
1290
- }
1291
-
1292
- if ( $redirect ) {
1293
- wp_safe_redirect( $redirect );
1294
- exit();
1295
- }
1296
- }
1297
-
1298
- add_action( 'load-edit.php', 'learn_press_process_duplicate_action' );
1299
-
1300
- /**
1301
- * Install a plugin
1302
- *
1303
- * @param string $plugin_name
1304
- *
1305
- * @return array
1306
- */
1307
- function learn_press_install_add_on( $plugin_name ) {
1308
- require_once( LP_PLUGIN_PATH . '/inc/admin/class-lp-upgrader.php' );
1309
- $upgrader = new LP_Upgrader();
1310
- global $wp_filesystem;
1311
- $response = array();
1312
-
1313
- $package = 'http://thimpress.com/lprepo/' . $plugin_name . '.zip';
1314
-
1315
- $package = $upgrader->download_package( $package );
1316
- if ( is_wp_error( $package ) ) {
1317
- $response['error'] = $package;
1318
- } else {
1319
- $working_dir = $upgrader->unpack_package( $package, true, $plugin_name );
1320
- if ( is_wp_error( $working_dir ) ) {
1321
- $response['error'] = $working_dir;
1322
- } else {
1323
-
1324
- $wp_upgrader = new WP_Upgrader();
1325
- $options = array(
1326
- 'source' => $working_dir,
1327
- 'destination' => WP_PLUGIN_DIR,
1328
- 'clear_destination' => false, // Do not overwrite files.
1329
- 'clear_working' => true,
1330
- 'hook_extra' => array(
1331
- 'type' => 'plugin',
1332
- 'action' => 'install'
1333
- )
1334
- );
1335
- //$response = array();
1336
- $result = $wp_upgrader->install_package( $options );
1337
-
1338
- if ( is_wp_error( $result ) ) {
1339
- $response['error'] = $result;
1340
- } else {
1341
- $response = $result;
1342
- $response['text'] = __( 'Installed', 'learnpress' );
1343
- }
1344
- }
1345
- }
1346
- return $response;
1347
- }
1348
-
1349
- function learn_press_accept_become_a_teacher() {
1350
- $action = !empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
1351
- $user_id = !empty( $_REQUEST['user_id'] ) ? $_REQUEST['user_id'] : '';
1352
- if ( !$action || !$user_id || ( $action != 'accept-to-be-teacher' ) ) return;
1353
-
1354
- if ( !learn_press_user_maybe_is_a_teacher( $user_id ) ) {
1355
- $be_teacher = new WP_User( $user_id );
1356
- $be_teacher->set_role( LP_TEACHER_ROLE );
1357
- delete_transient( 'learn_press_become_teacher_sent_' . $user_id );
1358
- do_action( 'learn_press_user_become_a_teacher', $user_id );
1359
- $redirect = add_query_arg( 'become-a-teacher-accepted', 'yes' );
1360
- $redirect = remove_query_arg( 'action', $redirect );
1361
- wp_redirect( $redirect );
1362
- }
1363
- }
1364
-
1365
- add_action( 'plugins_loaded', 'learn_press_accept_become_a_teacher' );
1366
-
1367
- function learn_press_user_become_a_teacher_notice() {
1368
- if ( $user_id = learn_press_get_request( 'user_id' ) && learn_press_get_request( 'become-a-teacher-accepted' ) == 'yes' ) {
1369
- $user = new WP_User( $user_id );
1370
- ?>
1371
- <div class="updated">
1372
- <p><?php printf( __( 'The user %s has become a teacher', 'learnpress' ), $user->user_login ); ?></p>
1373
- </div>
1374
- <?php
1375
- }
1376
- }
1377
-
1378
- add_action( 'admin_notices', 'learn_press_user_become_a_teacher_notice' );
1379
-
1380
- /**
1381
- * Check to see if a plugin is already installed or not
1382
- *
1383
- * @param $plugin
1384
- *
1385
- * @return bool
1386
- */
1387
- function learn_press_is_plugin_install( $plugin ) {
1388
- $installed_plugins = get_plugins();
1389
- return isset( $installed_plugins[$plugin] );
1390
- }
1391
-
1392
- /**
1393
- * Get plugin file that contains the information from slug
1394
- *
1395
- * @param $slug
1396
- *
1397
- * @return mixed
1398
- */
1399
- function learn_press_plugin_basename_from_slug( $slug ) {
1400
- $keys = array_keys( get_plugins() );
1401
- foreach ( $keys as $key ) {
1402
- if ( preg_match( '|^' . $slug . '/|', $key ) ) {
1403
- return $key;
1404
- }
1405
- }
1406
- return $slug;
1407
- }
1408
-
1409
- function learn_press_one_click_install_sample_data_notice() {
1410
- $courses = get_posts(
1411
- array(
1412
- 'post_type' => LP_COURSE_CPT,
1413
- 'post_status' => 'any'
1414
- )
1415
- );
1416
- if ( ( 0 == sizeof( $courses ) ) && ( 'off' != get_transient( 'learn_press_install_sample_data' ) ) ) {
1417
- printf(
1418
- '<div class="updated" id="learn-press-install-sample-data-notice">
1419
- <div class="install-sample-data-notice">
1420
- <p>%s</p>
1421
- <p>%s <strong>%s</strong> %s
1422
- <p><a href="" class="button yes" data-action="yes">%s</a> <a href="" class="button disabled no" data-action="no">%s</a></p>
1423
- </div>
1424
- <div class="install-sample-data-loading">
1425
- <p>Importing...</p>
1426
- </div>
1427
- </div>',
1428
- __( 'You haven\'t got any courses yet! Would you like to import sample data?', 'learnpress' ),
1429
- __( 'If yes, it requires to install addon name', 'learnpress' ),
1430
- __( 'LearnPress Import/Export', 'learnpress' ),
1431
- __( 'but don\'t worry because it is completely automated.', 'learnpress' ),
1432
- __( 'Import now', 'learnpress' ),
1433
- __( 'No, thanks!', 'learnpress' )
1434
- );
1435
- }
1436
- }
1437
-
1438
- //add_action( 'admin_notices', 'learn_press_one_click_install_sample_data_notice' );
1439
-
1440
- function learn_press_request_query( $vars = array() ) {
1441
- global $typenow, $wp_query, $wp_post_statuses;
1442
- if ( LP_ORDER_CPT === $typenow ) {
1443
- // Status
1444
- if ( !isset( $vars['post_status'] ) ) {
1445
- $post_statuses = learn_press_get_order_statuses();
1446
-
1447
- foreach ( $post_statuses as $status => $value ) {
1448
- if ( isset( $wp_post_statuses[$status] ) && false === $wp_post_statuses[$status]->show_in_admin_all_list ) {
1449
- unset( $post_statuses[$status] );
1450
- }
1451
- }
1452
-
1453
- $vars['post_status'] = array_keys( $post_statuses );
1454
-
1455
- }
1456
- }
1457
- return $vars;
1458
- }
1459
-
1460
- add_filter( 'request', 'learn_press_request_query' );
1461
-
1462
- function _learn_press_reset_course_data() {
1463
- if ( empty( $_REQUEST['reset-course-data'] ) ) {
1464
- return false;
1465
- }
1466
- learn_press_reset_course_data( intval( $_REQUEST['reset-course-data'] ) );
1467
- wp_redirect( remove_query_arg( 'reset-course-data' ) );
1468
- }
1469
-
1470
- add_action( 'init', '_learn_press_reset_course_data' );
1471
-
1472
- /***********************/
1473
- function learn_press_admin_section_loop_item_class( $item, $section ) {
1474
- $classes = array(
1475
- 'lp-section-item'
1476
- );
1477
- $classes[] = 'lp-item-' . $item->post_type;
1478
- if ( !absint( $item->ID ) ) {
1479
- $classes[] = 'lp-item-empty lp-item-new focus';
1480
- }
1481
- $classes = apply_filters( 'learn_press_section_loop_item_class', $classes, $item, $section );
1482
- if ( $classes ) echo 'class="' . join( ' ', $classes ) . '"';
1483
- return $classes;
1484
- }
1485
-
1486
- function learn_press_disable_checked_ontop( $args ) {
1487
-
1488
- if ( 'course_category' == $args['taxonomy'] ) {
1489
- $args['checked_ontop'] = false;
1490
- }
1491
-
1492
- return $args;
1493
- }
1494
-
1495
- add_filter( 'wp_terms_checklist_args', 'learn_press_disable_checked_ontop' );
1496
-
1497
- function learn_press_output_admin_template() {
1498
- learn_press_admin_view( 'admin-template.php' );
1499
- }
1500
-
1501
- add_action( 'admin_print_scripts', 'learn_press_output_admin_template' );
1502
-
1503
- function learn_press_output_screen_id() {
1504
- $screen = get_current_screen();
1505
- if ( $screen ) {
1506
- echo "<div style=\"position:fixed;top: 0; left:0; z-index: 99999999; background-color:#FFF;padding:4px;\">" . $screen->id . "</div>";
1507
- }
1508
- }
1509
-
1510
- //add_action( 'admin_head', 'learn_press_output_screen_id' );
1511
-
1512
- function learn_press_get_screens() {
1513
- $screen_id = sanitize_title( __( 'LearnPress', 'learnpress' ) );
1514
- $screens = array(
1515
- 'toplevel_page_' . $screen_id,
1516
- $screen_id . '_page_learn-press-statistics',
1517
- $screen_id . '_page_learn-press-addons',
1518
- $screen_id . '_page_learn-press-settings',
1519
- $screen_id . '_page_learn-press-tools'
1520
- );
1521
- foreach ( array( LP_COURSE_CPT, LP_LESSON_CPT, LP_QUIZ_CPT, LP_QUESTION_CPT, LP_ORDER_CPT ) as $post_type ) {
1522
- $screens[] = 'edit-' . $post_type;
1523
- $screens[] = $post_type;
1524
- }
1525
-
1526
- return apply_filters( 'learn_press_screen_ids', $screens );
1527
- }
1528
-
1529
- function learn_press_get_admin_pages() {
1530
- return apply_filters(
1531
- 'learn_press_admin_pages',
1532
- array(
1533
- 'learn-press-settings',
1534
- 'learn-press-settings'
1535
- )
1536
- );
1537
- }
1538
-
1539
- function learn_press_is_post_type_screen( $post_type, $union = 'OR' ) {
1540
- if ( is_array( $post_type ) ) {
1541
- $return = null;
1542
- foreach ( $post_type as $_post_type ) {
1543
- $check = learn_press_is_post_type_screen( $_post_type );
1544
- if ( $union == 'OR' && $check ) {
1545
- return true;
1546
- }
1547
- if ( $return == null ) {
1548
- $return = $check;
1549
- } else {
1550
- $return = $return && $check;
1551
- }
1552
- if ( $union !== 'OR' ) {
1553
- return $return;
1554
- }
1555
- }
1556
- return $return;
1557
- }
1558
- $screen = get_current_screen();
1559
- if ( !$screen ) {
1560
- return;
1561
- }
1562
- $screen_id = $screen->id;
1563
- return in_array( $screen_id, array( $post_type, "edit-{$post_type}" ) );
1564
- }
1565
-
1566
- function learn_press_get_notice_dismiss( $context, $type = 'transient' ) {
1567
- if ( $type == 'transient' ) {
1568
- return get_transient( 'learn_press_dismiss_notice_' . $context );
1569
- }
1570
- return get_option( 'learn_press_dismiss_notice_' . $context );
1571
- }
1572
-
1573
- if ( !function_exists( 'learn_press_course_insert_section' ) ) {
1574
-
1575
- function learn_press_course_insert_section( $section = array() ) {
1576
- global $wpdb;
1577
- $section = wp_parse_args(
1578
- $section,
1579
- array(
1580
- 'section_name' => '',
1581
- 'section_course_id' => 0,
1582
- 'section_order' => 0,
1583
- 'section_description' => ''
1584
- )
1585
- );
1586
- $section = stripslashes_deep( $section );
1587
- extract( $section );
1588
-
1589
- $insert_data = compact( 'section_name', 'section_course_id', 'section_order', 'section_description' );
1590
- $wpdb->insert(
1591
- $wpdb->learnpress_sections,
1592
- $insert_data,
1593
- array( '%s', '%d', '%d' )
1594
- );
1595
-
1596
- return $wpdb->insert_id;
1597
- }
1598
-
1599
- }
1600
-
1601
- if ( !function_exists( 'learn_press_course_insert_section_item' ) ) {
1602
-
1603
- function learn_press_course_insert_section_item( $item_data = array() ) {
1604
- global $wpdb;
1605
- $wpdb->insert(
1606
- $wpdb->learnpress_section_items,
1607
- array(
1608
- 'section_id' => $item_data['section_id'],
1609
- 'item_id' => $item_data['item_id'],
1610
- 'item_order' => $item_data['item_order'],
1611
- 'item_type' => $item_data['item_type']
1612
- ),
1613
- array(
1614
- '%d',
1615
- '%d',
1616
- '%d',
1617
- '%s',
1618
- )
1619
- );
1620
- return $wpdb->insert_id;
1621
- }
1622
-
1623
- }
1624
-
1625
- if ( !function_exists( 'learn_press_duplicate_post' ) ) {
1626
-
1627
- function learn_press_duplicate_post( $post_id = null, $args = array(), $meta = true ) {
1628
- $post = get_post( $post_id );
1629
- if ( !$post ) return;
1630
- $defalts = array(
1631
- 'comment_status' => $post->comment_status,
1632
- 'ping_status' => $post->ping_status,
1633
- 'post_author' => get_current_user_id(),
1634
- 'post_content' => $post->post_content,
1635
- 'post_excerpt' => $post->post_excerpt,
1636
- 'post_parent' => $post->post_parent,
1637
- 'post_password' => $post->post_password,
1638
- 'post_status' => 'draft',
1639
- 'post_title' => $post->post_title . ' - Copy',
1640
- 'post_type' => $post->post_type,
1641
- 'to_ping' => $post->to_ping,
1642
- 'menu_order' => $post->menu_order
1643
- );
1644
- $args = wp_parse_args( $args, $defalts );
1645
- $new_post_id = wp_insert_post( $args );
1646
-
1647
- if ( !is_wp_error( $new_post_id ) && $meta ) {
1648
- learn_press_duplicate_post_meta( $post_id, $new_post_id );
1649
- // assign related tags/categories to new course
1650
- $taxonomies = get_object_taxonomies( $post->post_type );
1651
- foreach ( $taxonomies as $taxonomy ) {
1652
- $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
1653
- wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false );
1654
- }
1655
- }
1656
- return apply_filters( 'learn_press_duplicate_post', $new_post_id, $post_id );
1657
- }
1658
- }
1659
-
1660
- if ( !function_exists( 'learn_press_duplicate_post_meta' ) ) {
1661
- /**
1662
- * duplicate all post meta just in two SQL queries
1663
- */
1664
- function learn_press_duplicate_post_meta( $old_post_id, $new_post_id, $excerpt = array() ) {
1665
- global $wpdb;
1666
- $post_meta_infos = $wpdb->get_results( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$old_post_id" );
1667
- if ( count( $post_meta_infos ) != 0 ) {
1668
- $excerpt = array_merge( array( '_edit_lock', '_edit_last' ), $excerpt );
1669
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
1670
- $sql_query_sel = array();
1671
- foreach ( $post_meta_infos as $meta ) {
1672
- if ( in_array( $meta->meta_value, $excerpt ) ) {
1673
- continue;
1674
- }
1675
- $meta_key = $meta->meta_key;
1676
- $meta_value = addslashes( $meta->meta_value );
1677
- $sql_query_sel[] = "SELECT $new_post_id, '$meta_key', '$meta_value'";
1678
- }
1679
- $sql_query .= implode( " UNION ALL ", $sql_query_sel );
1680
- $wpdb->query( $sql_query );
1681
- }
1682
- }
1683
-
1684
- }
1685
-
1686
- add_filter( 'learn_press_question_types', 'learn_press_sort_questions', 99 );
1687
- if ( !function_exists( 'learn_press_sort_questions' ) ) {
1688
- function learn_press_sort_questions( $types ) {
1689
- $user_id = get_current_user_id();
1690
- $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
1691
- if ( !empty( $question_types ) ) {
1692
- $sort = array();
1693
- // re-sort array descending
1694
- arsort( $question_types );
1695
- $new_types = array();
1696
- $ktypes = array_keys( $types );
1697
-
1698
- for ( $i = 0; $i < count( $ktypes ) - 1; $i ++ ) {
1699
- $max = $i;
1700
- if ( !isset( $question_types[$ktypes[$i]] ) ) {
1701
- $question_types[$ktypes[$i]] = 0;
1702
- }
1703
- for ( $j = $i + 1; $j < count( $ktypes ); $j ++ ) {
1704
- if ( isset( $question_types[$ktypes[$j]], $question_types[$ktypes[$max]] )
1705
- && $question_types[$ktypes[$j]] > $question_types[$ktypes[$max]]
1706
- ) {
1707
- $max = $j;
1708
- }
1709
- }
1710
- $tmp = $ktypes[$i];
1711
- $ktypes[$i] = $ktypes[$max];
1712
- $ktypes[$max] = $tmp;
1713
- }
1714
- $ktypes = array_flip( $ktypes );
1715
- $types = array_merge( $ktypes, $types );
1716
- }
1717
- return $types;
1718
- }
1719
- }
1720
-
1721
- if ( !function_exists( 'learn_press_duplicate_course' ) ) {
1722
-
1723
- function learn_press_duplicate_course( $course_id = null, $force = true ) {
1724
- if ( !function_exists( '_learn_press_get_course_curriculum' ) ) {
1725
- require_once LP_PLUGIN_PATH . 'inc/lp-init.php';
1726
- }
1727
- global $wpdb;
1728
-
1729
- if ( $course_id && is_array( $course_id ) ) {
1730
- $course_id = array_shift( $course_id );
1731
- }
1732
- // check for post is exists
1733
- if ( !$course_id || !( $post = get_post( $course_id ) ) ) {
1734
- return new WP_Error( __( '<p>Op! The course does not exist</p>', 'learnpress' ) );
1735
- } else {
1736
- // ensure that user can create course
1737
- if ( !current_user_can( 'edit_posts' ) ) {
1738
- return new WP_Error( __( '<p>Sorry! You have not permission to duplicate this course</p>', 'learnpress' ) );
1739
- } else {
1740
- // duplicate course
1741
- $new_course_id = learn_press_duplicate_post( $course_id );
1742
- if ( !$new_course_id || is_wp_error( $new_course_id ) ) {
1743
- return new WP_Error( __( '<p>Sorry! Duplicate course failed!</p>', 'learnpress' ) );
1744
- } else {
1745
- $curriculums = _learn_press_get_course_curriculum( $course_id );
1746
- foreach ( $curriculums as $section_id => $section ) {
1747
- $new_section_id = learn_press_course_insert_section( array(
1748
- 'section_name' => $section->section_name,
1749
- 'section_course_id' => $new_course_id,
1750
- 'section_order' => $section->section_order,
1751
- 'section_description' => $section->section_description
1752
- ) );
1753
-
1754
- if ( $section->items ) {
1755
- foreach ( $section->items as $item ) {
1756
- // duplicate item
1757
- if ( $force && $item->post_type === LP_QUIZ_CPT ) {
1758
- $item_id = learn_press_duplicate_quiz( $item->ID, array( 'post_status' => 'publish' ) );
1759
- } else {
1760
- $item_id = learn_press_duplicate_post( $item->ID, array( 'post_status' => 'publish' ) );
1761
- }
1762
- if ( $force ) {
1763
- $section_item_id = learn_press_course_insert_section_item( array(
1764
- 'section_id' => $new_section_id,
1765
- 'item_id' => $item_id,
1766
- 'item_order' => $item->item_order,
1767
- 'item_type' => $item->item_type
1768
- ) );
1769
- }
1770
- }
1771
- }
1772
- }
1773
- return $new_course_id;
1774
- }
1775
- }
1776
- }
1777
- }
1778
-
1779
- }
1780
-
1781
- if ( !function_exists( 'learn_press_duplicate_question' ) ) {
1782
-
1783
- function learn_press_duplicate_question( $question_id = null, $quiz_id = null ) {
1784
- if ( !$question_id || !get_post( $question_id ) ) {
1785
- return new WP_Error( sprintf( __( 'Question id %s is not exists.', 'learnpress' ), $question_id ) );
1786
- }
1787
- if ( $quiz_id && !get_post( $quiz_id ) ) {
1788
- return new WP_Error( sprintf( __( 'Quiz id %s is not exists.', 'learnpress' ), $quiz_id ) );
1789
- }
1790
-
1791
- global $wpdb;
1792
- $new_question_id = learn_press_duplicate_post( $question_id );
1793
- if ( $quiz_id ) {
1794
- // learnpress_quiz_questions
1795
- $sql = $wpdb->prepare( "
1796
- SELECT * FROM $wpdb->learnpress_quiz_questions WHERE quiz_id = %d AND question_id = %d
1797
- ", $quiz_id, $question_id );
1798
- $quiz_question_data = $wpdb->get_row( $sql );
1799
- $max_order = $wpdb->get_var( $wpdb->prepare( "SELECT max(question_order) FROM {$wpdb->prefix}learnpress_quiz_questions WHERE quiz_id = %d", $quiz_id ) );
1800
-
1801
- if ( $quiz_question_data ) {
1802
- $wpdb->insert(
1803
- $wpdb->learnpress_quiz_questions,
1804
- array(
1805
- 'quiz_id' => $quiz_id,
1806
- 'question_id' => $new_question_id,
1807
- 'question_order' => $max_order + 1,
1808
- 'params' => $quiz_question_data->params
1809
- ),
1810
- array(
1811
- '%d',
1812
- '%d',
1813
- '%d',
1814
- '%s'
1815
- )
1816
- );
1817
- }
1818
- }
1819
- // learnpress_question_answers
1820
- $sql = $wpdb->prepare( "
1821
- SELECT * FROM $wpdb->learnpress_question_answers WHERE question_id = %d
1822
- ", $question_id );
1823
- $question_answers = $wpdb->get_results( $sql );
1824
- if ( $question_answers ) {
1825
- foreach ( $question_answers as $q_a ) {
1826
- $wpdb->insert(
1827
- $wpdb->learnpress_question_answers,
1828
- array(
1829
- 'question_id' => $new_question_id,
1830
- 'answer_data' => $q_a->answer_data,
1831
- 'answer_order' => $q_a->answer_order
1832
- ),
1833
- array(
1834
- '%d',
1835
- '%s',
1836
- '%s'
1837
- )
1838
- );
1839
- }
1840
- }
1841
-
1842
- return $new_question_id;
1843
- }
1844
-
1845
- }
1846
-
1847
- if ( !function_exists( 'learn_press_duplicate_quiz' ) ) {
1848
-
1849
- function learn_press_duplicate_quiz( $quiz_id = null, $args = array() ) {
1850
- global $wpdb;
1851
- $new_quiz_id = learn_press_duplicate_post( $quiz_id, $args, true );
1852
- $quiz = LP_Quiz::get_quiz( $quiz_id );
1853
- $questions = $quiz->get_questions();
1854
- if ( $questions ) {
1855
- $questions = array_keys( $questions );
1856
- foreach ( $questions as $question_id ) {
1857
- $new_question_id = learn_press_duplicate_post( $question_id );
1858
- // learnpress_quiz_questions
1859
- $sql = $wpdb->prepare( "
1860
- SELECT * FROM $wpdb->learnpress_quiz_questions WHERE quiz_id = %d AND question_id = %d
1861
- ", $quiz_id, $question_id );
1862
- $quiz_question_data = $wpdb->get_row( $sql );
1863
- if ( $quiz_question_data ) {
1864
- $wpdb->insert(
1865
- $wpdb->learnpress_quiz_questions,
1866
- array(
1867
- 'quiz_id' => $new_quiz_id,
1868
- 'question_id' => $new_question_id,
1869
- 'question_order' => $quiz_question_data->question_order,
1870
- 'params' => $quiz_question_data->params
1871
- ),
1872
- array(
1873
- '%d',
1874
- '%d',
1875
- '%d',
1876
- '%s'
1877
- )
1878
- );
1879
- }
1880
- // learnpress_question_answers
1881
- $sql = $wpdb->prepare( "
1882
- SELECT * FROM $wpdb->learnpress_question_answers WHERE question_id = %d
1883
- ", $question_id );
1884
- $question_answers = $wpdb->get_results( $sql );
1885
- if ( $question_answers ) {
1886
- foreach ( $question_answers as $q_a ) {
1887
- $wpdb->insert(
1888
- $wpdb->learnpress_question_answers,
1889
- array(
1890
- 'question_id' => $new_question_id,
1891
- 'answer_data' => $q_a->answer_data,
1892
- 'answer_order' => $q_a->answer_order
1893
- ),
1894
- array(
1895
- '%d',
1896
- '%s',
1897
- '%s'
1898
- )
1899
- );
1900
- }
1901
- }
1902
- }
1903
- }
1904
-
1905
- return $new_quiz_id;
1906
- }
1907
-
1908
- }
1909
-
1910
- /**
1911
- * Get number version of a template file
1912
- *
1913
- * @param $file
1914
- *
1915
- * @return string
1916
- */
1917
- function learn_press_get_file_version( $file ) {
1918
- if ( !file_exists( $file ) ) {
1919
- return '';
1920
- }
1921
- $fp = fopen( $file, 'r' );
1922
- $file_data = fread( $fp, 8192 );
1923
- fclose( $fp );
1924
- $file_data = str_replace( "\r", "\n", $file_data );
1925
- $version = '';
1926
- if ( preg_match( '/^[ \t\/*#@]*' . preg_quote( '@version', '/' ) . '(.*)$/mi', $file_data, $match ) && $match[1] )
1927
- $version = _cleanup_header_comment( $match[1] );
1928
- return $version;
1929
- }
1930
-
1931
- /**
1932
- * Get list of template files are overwritten in the theme
1933
- *
1934
- * @param bool $check
1935
- *
1936
- * @return array|bool
1937
- */
1938
- function learn_press_get_theme_templates( $check = false ) {
1939
- $template_folder = learn_press_template_path();
1940
- $template_path = LP_PLUGIN_PATH . '/templates/';
1941
- $template_dir = get_template_directory();
1942
- $stylesheet_dir = get_stylesheet_directory();
1943
- $t_folder = basename( $template_dir );
1944
- $s_folder = basename( $stylesheet_dir );
1945
-
1946
- $found_files = array( $t_folder => array(), $s_folder => array() );
1947
- $outdated_templates = false;
1948
-
1949
- $scanned_files = learn_press_scan_template_files( $template_path );
1950
- foreach ( $scanned_files as $file ) {
1951
- $theme_folder = '';
1952
-
1953
- if ( file_exists( $stylesheet_dir . '/' . $file ) ) {
1954
- $theme_file = $stylesheet_dir . '/' . $file;
1955
- $theme_folder = $s_folder;
1956
- } elseif ( file_exists( $stylesheet_dir . '/' . $template_folder . '/' . $file ) ) {
1957
- $theme_file = $stylesheet_dir . '/' . $template_folder . '/' . $file;
1958
- $theme_folder = $s_folder;
1959
- } elseif ( file_exists( $template_dir . '/' . $file ) ) {
1960
- $theme_file = $template_dir . '/' . $file;
1961
- $theme_folder = $t_folder;
1962
- } elseif ( file_exists( $template_dir . '/' . $template_folder . '/' . $file ) ) {
1963
- $theme_file = $template_dir . '/' . $template_folder . '/' . $file;
1964
- $theme_folder = $t_folder;
1965
- } else {
1966
- $theme_file = false;
1967
- }
1968
-
1969
- if ( !empty( $theme_file ) ) {
1970
- $core_version = learn_press_get_file_version( $template_path . $file );
1971
- $theme_version = learn_press_get_file_version( $theme_file );
1972
-
1973
- if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) {
1974
- if ( !$outdated_templates ) {
1975
- $outdated_templates = true;
1976
- }
1977
- $found_files[$theme_folder][] = array(
1978
- str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ),
1979
- $theme_version ? $theme_version : '-',
1980
- $core_version,
1981
- true
1982
- );
1983
- } else {
1984
- $found_files[$theme_folder][] = array(
1985
- str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ),
1986
- $theme_version ? $theme_version : '?',
1987
- $core_version ? $core_version : '?',
1988
- null
1989
- );
1990
- }
1991
- }
1992
- if ( $check && $outdated_templates ) {
1993
- return $outdated_templates;
1994
- }
1995
- }
1996
- $found_files = array_merge( $found_files[$t_folder], $found_files[$s_folder] );
1997
-
1998
- return $check ? $outdated_templates : $found_files;
1999
- }
2000
-
2001
- function learn_press_scan_template_files( $template_path ) {
2002
-
2003
- $files = @scandir( $template_path );
2004
- $result = array();
2005
-
2006
- if ( !empty( $files ) ) {
2007
- foreach ( $files as $key => $value ) {
2008
- if ( !in_array( $value, array( ".", "..", 'index.php', 'index.html' ) ) ) {
2009
- if ( is_dir( $template_path . '/' . $value ) ) {
2010
- $sub_files = learn_press_scan_template_files( $template_path . '/' . $value );
2011
- foreach ( $sub_files as $sub_file ) {
2012
- $result[] = $value . '/' . $sub_file;
2013
- }
2014
- } else {
2015
- $result[] = $value;
2016
- }
2017
- }
2018
- }
2019
- }
2020
- return $result;
2021
- }
2022
-
2023
- if ( !function_exists( 'learn_press_duplicate_lesson' ) ) {
2024
-
2025
- function learn_press_duplicate_lesson( $lesson_id = null ) {
2026
- return learn_press_duplicate_post( $lesson_id );
2027
- }
2028
-
2029
- }
 
 
 
1
+ <?php
2
+ /**
3
+ * Common functions used for admin
4
+ *
5
+ * @package LearnPress
6
+ * @author ThimPress
7
+ * @version 1.0
8
+ */
9
+
10
+ if ( !defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ }
13
+ /**
14
+ * Get html view path for admin to display
15
+ *
16
+ * @param $name
17
+ * @param $plugin_file
18
+ *
19
+ * @return mixed
20
+ */
21
+ function learn_press_get_admin_view( $name, $plugin_file = null ) {
22
+ if ( !preg_match( '/\.(.*)$/', $name ) ) {
23
+ $name .= '.php';
24
+ }
25
+ if ( $plugin_file ) {
26
+ $view = dirname( $plugin_file ) . '/inc/admin/views/' . $name;
27
+ } else {
28
+ $view = LP()->plugin_path( 'inc/admin/views/' . $name );
29
+ }
30
+ return apply_filters( 'learn_press_admin_view', $view, $name );
31
+ }
32
+
33
+ /**
34
+ * Find a full path of a view and display the content in admin
35
+ *
36
+ * @param $name
37
+ * @param array $args
38
+ * @param bool|false $include_once
39
+ * @param bool
40
+ *
41
+ * @return bool
42
+ */
43
+ function learn_press_admin_view( $name, $args = array(), $include_once = false, $return = false ) {
44
+ $view = learn_press_get_admin_view( $name, !empty( $args['plugin_file'] ) ? $args['plugin_file'] : null );
45
+ if ( file_exists( $view ) ) {
46
+ ob_start();
47
+ // extract parameters as local variables if passed
48
+ is_array( $args ) && extract( $args );
49
+ do_action( 'learn_press_before_display_admin_view', $name, $args );
50
+ if ( $include_once ) {
51
+ include_once $view;
52
+ } else {
53
+ include $view;
54
+ }
55
+ do_action( 'learn_press_after_display_admin_view', $name, $args );
56
+ $output = ob_get_clean();
57
+ if ( !$return ) {
58
+ echo $output;
59
+ }
60
+ return $return ? $output : true;
61
+ }
62
+ return false;
63
+ }
64
+
65
+ /**
66
+ * List all pages as a dropdown with "Add New Page" option
67
+ *
68
+ * @param $name
69
+ * @param bool|false $selected
70
+ * @param array $args
71
+ *
72
+ * @return mixed|string
73
+ */
74
+ function learn_press_pages_dropdown( $name, $selected = false, $args = array() ) {
75
+ $id = null;
76
+ $class = null;
77
+ $css = null;
78
+ $before = array(
79
+ 'add_new_page' => __( '[ Add a new page ]', 'learnpress' )
80
+ );
81
+ $after = null;
82
+ $echo = true;
83
+ $allow_create = true;
84
+ is_array( $args ) && extract( $args );
85
+
86
+ if ( empty( $id ) ) {
87
+ $id = $name;
88
+ }
89
+ $args = array(
90
+ 'name' => $name,
91
+ 'id' => $id,
92
+ 'sort_column' => 'menu_order',
93
+ 'sort_order' => 'ASC',
94
+ 'show_option_none' => __( 'Select Page', 'learnpress' ),
95
+ 'class' => $class,
96
+ 'echo' => false,
97
+ 'selected' => $selected,
98
+ 'allow_create' => true
99
+ );
100
+ $output = wp_dropdown_pages( $args );
101
+ $replace = "";
102
+
103
+ $class .= 'learn-press-dropdown-pages';
104
+
105
+ if ( $class ) {
106
+ $replace .= ' class="' . $class . '"';
107
+ }
108
+ if ( $css ) {
109
+ $replace .= ' style="' . $css . '"';
110
+ }
111
+
112
+ $replace .= ' data-selected="' . $selected . '"';
113
+ $replace .= " data-placeholder='" . __( 'Select a page&hellip;', 'learnpress' ) . "' id=";
114
+ $output = str_replace( ' id=', $replace, $output );
115
+ if ( $before ) {
116
+ $before_output = array();
117
+ foreach ( $before as $v => $l ) {
118
+ $before_output[] = sprintf( '<option value="%s">%s</option>', $v, $l );
119
+ }
120
+ $before_output = join( "\n", $before_output );
121
+ $output = preg_replace( '!(<option class=".*" value="[0-9]+".*>.*</option>)!', $before_output . "\n$1", $output, 1 );
122
+ }
123
+ if ( $allow_create ) {
124
+ ob_start(); ?>
125
+ <button class="button button-quick-add-page" data-id="<?php echo $id; ?>" type="button"><?php _e( 'Create', 'learnpress' ); ?></button>
126
+ <p class="learn-press-quick-add-page-inline <?php echo $id; ?> hide-if-js">
127
+ <input type="text" placeholder="<?php esc_attr_e( 'New page title', 'learnpress' ); ?>" />
128
+ <button class="button" type="button"><?php esc_html_e( 'Ok [Enter]', 'learnpress' ); ?></button>
129
+ <a href=""><?php _e( 'Cancel [ESC]', 'learnpress' ); ?></a>
130
+ </p>
131
+ <p class="learn-press-quick-add-page-actions <?php echo $id; ?><?php echo $selected ? '' : ' hide-if-js'; ?>">
132
+ <a class="edit-page" href="<?php echo get_edit_post_link( $selected ); ?>" target="_blank"><?php _e( 'Edit Page', 'learnpress' ); ?></a>
133
+ <a class="view-page" href="<?php echo get_permalink( $selected ); ?>" target="_blank"><?php _e( 'View Page', 'learnpress' ); ?></a>
134
+ </p>
135
+ <?php $output .= ob_get_clean();
136
+ }
137
+ if ( $echo ) {
138
+ echo $output;
139
+ }
140
+
141
+ return $output;
142
+ }
143
+
144
+ /**
145
+ * List all registered question types into dropdown
146
+ *
147
+ * @param array
148
+ *
149
+ * @return string
150
+ */
151
+ function learn_press_dropdown_question_types( $args = array() ) {
152
+ $args = wp_parse_args(
153
+ $args,
154
+ array(
155
+ 'name' => 'learn-press-dropdown-question-types',
156
+ 'id' => '',
157
+ 'class' => '',
158
+ 'selected' => '',
159
+ 'echo' => true
160
+ )
161
+ );
162
+ if ( !$args['id'] ) {
163
+ $args['id'] = $args['name'];
164
+ }
165
+ $args['class'] = 'lp-dropdown-question-types' . ( $args['class'] ? ' ' . $args['class'] : '' );
166
+ $types = learn_press_question_types();
167
+ $output = sprintf( '<select name="%s" id="%s" class="%s"%s>', $args['name'], $args['id'], $args['class'], $args['selected'] ? 'data-selected="' . $args['selected'] . '"' : '' );
168
+ foreach ( $types as $slug => $name ) {
169
+ $output .= sprintf( '<option value="%s"%s>%s</option>', $slug, selected( $slug == $args['selected'], true, false ), $name );
170
+ }
171
+ $output .= '</select>';
172
+ if ( $args['echo'] ) {
173
+ echo $output;
174
+ }
175
+ return $output;
176
+ }
177
+
178
+ /**
179
+ * List all registered question types into dropdown
180
+ *
181
+ * @param array
182
+ *
183
+ * @return string
184
+ */
185
+ function learn_press_field_question_duration( $args = array(), $question ) {
186
+ global $post;
187
+ $duration_type = get_post_meta( $post->ID, "_lp_duration_type", true );
188
+ $value = get_post_meta( $question->id, '_question_duration', true );
189
+
190
+ $wrap_class = 'learn-press-question-duration';
191
+ if ( 'questions_duration' !== $duration_type ) {
192
+ $wrap_class .= ' hide';
193
+ }
194
+ $args = wp_parse_args(
195
+ $args,
196
+ array(
197
+ 'name' => 'learn_press_question[' . $question->id . '][duration]',
198
+ 'id' => 'learn-press-question-duration-' . $question->id,
199
+ 'class' => 'learn-press-question-duration',
200
+ 'selected' => '',
201
+ 'echo' => true,
202
+ 'value' => 0,
203
+ 'step' => 1,
204
+ 'min' => 0,
205
+ 'placeholder' => __( 'Minutes', 'learnpress' ),
206
+ )
207
+ );
208
+ $args['value'] = $value;
209
+
210
+ if ( !$args['id'] ) {
211
+ $args['id'] = $args['name'];
212
+ }
213
+
214
+ return '<span class="' . esc_attr( $wrap_class ) . '">' . sprintf(
215
+ '<input type="number" class="%s" name="%s" id="%s" value="%s" step="%s" min="%s" max="%s" placeholder="%s"/>',
216
+ $args['class'],
217
+ $args['name'],
218
+ empty( $args['clone'] ) ? $args['id'] : '',
219
+ $args['value'],
220
+ $args['step'],
221
+ $args['min'],
222
+ !empty( $args['max'] ) ? $args['max'] : '',
223
+ $args['placeholder']
224
+ ) . $args['placeholder'] . '</span>';
225
+ }
226
+
227
+ /**
228
+ * Displays email formats support into a dropdown
229
+ *
230
+ * @param array $args
231
+ *
232
+ * @return string
233
+ */
234
+ function learn_press_email_formats_dropdown( $args = array() ) {
235
+ $args = wp_parse_args(
236
+ $args,
237
+ array(
238
+ 'name' => 'learn-press-dropdown-email-formats',
239
+ 'id' => '',
240
+ 'class' => '',
241
+ 'selected' => '',
242
+ 'echo' => true
243
+ )
244
+ );
245
+ $formats = array(
246
+ //'text_message' => __( 'Text message', 'learnpress' ),
247
+ 'plain_text' => __( 'Plain text', 'learnpress' ),
248
+ 'html' => __( 'HTML', 'learnpress' ),
249
+ //'multipart' => __( 'Multipart', 'learnpress' )
250
+ );
251
+ $output = sprintf( '<select name="%s" id="%s" class="%s" %s>', $args['name'], $args['id'], $args['class'], '' );
252
+ foreach ( $formats as $name => $text ) {
253
+ $output .= sprintf( '<option value="%s" %s>%s</option>', $name, selected( $args['selected'] == $name, true, false ), $text ) . "\n";
254
+ }
255
+ $output .= '</select>';
256
+
257
+ if ( $args['echo'] ) echo $output;
258
+ return $output;
259
+ }
260
+
261
+ /**************************************************/
262
+ /**************************************************/
263
+ /**************************************************/
264
+
265
+ /**
266
+ * Translate javascript text
267
+ */
268
+ function learn_press_admin_localize_script() {
269
+ if ( defined( 'LP_DOING_AJAX' ) || !is_admin() ) return;
270
+ $translate = array(
271
+ 'quizzes_is_not_available' => __( 'Quiz is not available', 'learnpress' ),
272
+ 'lessons_is_not_available' => __( 'Lesson is not available', 'learnpress' ),
273
+ 'duplicate_course' => array(
274
+ 'title' => __( 'Duplicate course', 'learnpress' ),
275
+ 'message' => __( 'Duplicate course curriculum?', 'learnpress' )
276
+ ),
277
+ 'duplicate_question' => array(
278
+ 'title' => __( 'Duplicate Question', 'learnpress' ),
279
+ 'message' => __( 'Do you want to duplicate this question?', 'learnpress' )
280
+ ),
281
+ 'remove_question' => __( 'Do you want to remove this question from quiz?', 'learnpress' ),
282
+ 'nonces' => array(
283
+ 'duplicate_question' => wp_create_nonce( 'duplicate-question' )
284
+ )
285
+ );
286
+ LP_Assets::add_localize( $translate );
287
+ }
288
+
289
+ add_action( 'init', 'learn_press_admin_localize_script' );
290
+
291
+ /**
292
+ * Default admin settings pages
293
+ *
294
+ * @return mixed
295
+ */
296
+ function learn_press_settings_tabs_array() {
297
+ $tabs = array(
298
+ 'general' => __( 'General', 'learnpress' ),
299
+ 'courses' => __( 'Courses', 'learnpress' ),
300
+ 'pages' => __( 'Pages', 'learnpress' ),
301
+ 'payments' => __( 'Payments', 'learnpress' ),
302
+ 'checkout' => __( 'Checkout', 'learnpress' ),
303
+ //'profile' => __( 'Profile', 'learnpress' ),
304
+ 'emails' => __( 'Emails', 'learnpress' )
305
+ );
306
+ return apply_filters( 'learn_press_settings_tabs_array', $tabs );
307
+ }
308
+
309
+ /**
310
+ * Count number of orders between to dates
311
+ *
312
+ * @param string
313
+ * @param int
314
+ *
315
+ * @return int
316
+ */
317
+ function learn_press_get_order_by_time( $by, $time ) {
318
+ global $wpdb;
319
+ $user_id = get_current_user_id();
320
+
321
+ $y = date( 'Y', $time );
322
+ $m = date( 'm', $time );
323
+ $d = date( 'd', $time );
324
+ switch ( $by ) {
325
+ case 'days':
326
+ $orders = $wpdb->get_var(
327
+ $wpdb->prepare(
328
+ "SELECT COUNT(*)
329
+ FROM $wpdb->posts AS p
330
+ INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
331
+ WHERE p.post_author = %d
332
+ AND p.post_type = %s
333
+ AND p.post_status = %s
334
+ AND m.meta_key = %s
335
+ AND m.meta_value = %s
336
+ AND YEAR(p.post_date) = %s AND MONTH(p.post_date) = %s AND DAY(p.post_date) = %s",
337
+ $user_id, LP_ORDER_CPT, 'publish', '_learn_press_transaction_status', 'completed', $y, $m, $d
338
+ )
339
+ );
340
+ break;
341
+ case 'months':
342
+ $orders = $wpdb->get_var(
343
+ $wpdb->prepare(
344
+ "SELECT COUNT(*)
345
+ FROM $wpdb->posts AS p
346
+ INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
347
+ WHERE p.post_author = %d
348
+ AND p.post_type = %s
349
+ AND p.post_status = %s
350
+ AND m.meta_key = %s
351
+ AND m.meta_value = %s
352
+ AND YEAR(p.post_date) = %s AND MONTH(p.post_date) = %s",
353
+ $user_id, LP_ORDER_CPT, 'publish', '_learn_press_transaction_status', 'completed', $y, $m
354
+ )
355
+ );
356
+ break;
357
+ }
358
+ return $orders;
359
+ }
360
+
361
+ /**
362
+ * Count number of orders by status
363
+ *
364
+ * @param string Status of the orders
365
+ *
366
+ * @return int
367
+ */
368
+ function learn_press_get_courses_by_status( $status ) {
369
+ global $wpdb;
370
+ $user_id = get_current_user_id();
371
+ $courses = $wpdb->get_var(
372
+ $wpdb->prepare(
373
+ "SELECT COUNT(*)
374
+ FROM $wpdb->posts
375
+ WHERE post_author = %d
376
+ AND post_type = %s
377
+ AND post_status = %s",
378
+ $user_id, LP_COURSE_CPT, $status
379
+ )
380
+ );
381
+ return $courses;
382
+ }
383
+
384
+ /**
385
+ * Count number of orders by price
386
+ *
387
+ * @param string
388
+ *
389
+ * @return int
390
+ */
391
+ function learn_press_get_courses_by_price( $fee ) {
392
+ global $wpdb;
393
+ $user_id = get_current_user_id();
394
+ $courses = $wpdb->get_var(
395
+ $wpdb->prepare(
396
+ "SELECT COUNT(*)
397
+ FROM $wpdb->posts AS p
398
+ INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
399
+ WHERE p.post_author = %d
400
+ AND p.post_type = %s
401
+ AND p.post_status IN (%s, %s)
402
+ AND m.meta_key = %s
403
+ AND m.meta_value = %s",
404
+ $user_id, LP_COURSE_CPT, 'publish', 'pending', '_lpr_course_payment', $fee
405
+ )
406
+ );
407
+ return $courses;
408
+ }
409
+
410
+ /**
411
+ * Get data about students to render in chart
412
+ *
413
+ * @param null $from
414
+ * @param null $by
415
+ * @param $time_ago
416
+ *
417
+ * @return array
418
+ */
419
+ function learn_press_get_chart_students( $from = null, $by = null, $time_ago ) {
420
+ $labels = array();
421
+ $datasets = array();
422
+ if ( is_null( $from ) ) {
423
+ $from = current_time( 'mysql' );
424
+ }
425
+ // $by: days, months or years
426
+ if ( is_null( $by ) ) {
427
+ $by = 'days';
428
+ }
429
+ switch ( $by ) {
430
+ case 'days':
431
+ $date_format = 'M d';
432
+ break;
433
+ case 'months':
434
+ $date_format = 'M Y';
435
+ break;
436
+ case 'years':
437
+ $date_format = 'Y';
438
+ break;
439
+ }
440
+
441
+ for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
442
+ $labels[] = date( $date_format, strtotime( "$i $by", strtotime( $from ) ) );
443
+ $datasets[0]['data'][] = learn_press_get_order_by_time( $by, strtotime( "$i $by", strtotime( $from ) ) );
444
+ }
445
+ $colors = learn_press_get_admin_colors();
446
+ $datasets[0]['fillColor'] = 'rgba(255,255,255,0.1)';
447
+ $datasets[0]['strokeColor'] = $colors[0];
448
+ $datasets[0]['pointColor'] = $colors[0];
449
+ $datasets[0]['pointStrokeColor'] = $colors[2];
450
+ $datasets[0]['pointHighlightFill'] = $colors[2];
451
+ $datasets[0]['pointHighlightStroke'] = $colors[0];
452
+ return array(
453
+ 'labels' => $labels,
454
+ 'datasets' => $datasets
455
+ );
456
+ }
457
+
458
+ /**
459
+ * Get data about students to render in chart
460
+ *
461
+ * @param null $from
462
+ * @param null $by
463
+ * @param $time_ago
464
+ *
465
+ * @return array
466
+ */
467
+ function learn_press_get_chart_users( $from = null, $by = null, $time_ago ) {
468
+ global $wpdb;
469
+
470
+ $labels = array();
471
+ $datasets = array();
472
+ if ( is_null( $from ) ) {
473
+ $from = current_time( 'mysql' );
474
+ }
475
+ if ( is_null( $by ) ) {
476
+ $by = 'days';
477
+ }
478
+ $results = array(
479
+ 'all' => array(),
480
+ 'instructors' => array()
481
+ );
482
+ $from_time = is_numeric( $from ) ? $from : strtotime( $from );
483
+
484
+ switch ( $by ) {
485
+ case 'days':
486
+ $date_format = 'M d Y';
487
+ $_from = - $time_ago + 1;
488
+ $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
489
+ $_to = date( 'Y-m-d', $from_time );
490
+ $_sql_format = '%Y-%m-%d';
491
+ $_key_format = 'Y-m-d';
492
+ break;
493
+ case 'months':
494
+ $date_format = 'M Y';
495
+ $_from = - $time_ago + 1;
496
+ $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
497
+ $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
498
+ $_to = date( 'Y-m-' . $days, $from_time );
499
+ $_sql_format = '%Y-%m';
500
+ $_key_format = 'Y-m';
501
+ break;
502
+ case 'years':
503
+ $date_format = 'Y';
504
+ $_from = - $time_ago + 1;
505
+ $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
506
+ $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
507
+ $_to = date( 'Y-12-' . $days, $from_time );
508
+ $_sql_format = '%Y';
509
+ $_key_format = 'Y';
510
+
511
+ break;
512
+ }
513
+ $query = $wpdb->prepare( "
514
+ SELECT count(u.ID) as c, DATE_FORMAT( u.user_registered, %s) as d
515
+ FROM {$wpdb->users} u
516
+ WHERE 1
517
+ GROUP BY d
518
+ HAVING d BETWEEN %s AND %s
519
+ ORDER BY d ASC
520
+ ", $_sql_format, $_from, $_to );
521
+ if ( $_results = $wpdb->get_results( $query ) ) {
522
+ foreach ( $_results as $k => $v ) {
523
+ $results['all'][$v->d] = $v;
524
+ }
525
+ }
526
+ $query = $wpdb->prepare( "
527
+ SELECT count(u.ID) as c, DATE_FORMAT( u.user_registered, %s) as d
528
+ FROM {$wpdb->users} u
529
+ INNER JOIN {$wpdb->usermeta} um ON um.user_id = u.ID AND um.meta_key = %s AND ( um.meta_value LIKE %s OR um.meta_value LIKE %s )
530
+ WHERE 1
531
+ GROUP BY d
532
+ HAVING d BETWEEN %s AND %s
533
+ ORDER BY d ASC
534
+ ", $_sql_format, 'wp_capabilities', '%' . $wpdb->esc_like( 's:13:"administrator"' ) . '%', '%' . $wpdb->esc_like( 's:10:"lp_teacher"' ) . '%', $_from, $_to );
535
+
536
+ if ( $_results = $wpdb->get_results( $query ) ) {
537
+ foreach ( $_results as $k => $v ) {
538
+ $results['instructors'][$v->d] = $v;
539
+ }
540
+ }
541
+ for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
542
+ $date = strtotime( "$i $by", $from_time );
543
+ $labels[] = date( $date_format, $date );
544
+ $key = date( $_key_format, $date );
545
+
546
+ $all = !empty( $results['all'][$key] ) ? $results['all'][$key]->c : 0;
547
+ $instructors = !empty( $results['instructors'][$key] ) ? $results['instructors'][$key]->c : 0;
548
+
549
+ $datasets[0]['data'][] = $all;
550
+ $datasets[1]['data'][] = $instructors;
551
+ $datasets[2]['data'][] = $all - $instructors;
552
+ }
553
+
554
+ $dataset_params = array(
555
+ array(
556
+ 'color1' => 'rgba(47, 167, 255, %s)',
557
+ 'color2' => '#FFF',
558
+ 'label' => __( 'All', 'learnpress' )
559
+ ),
560
+ array(
561
+ 'color1' => 'rgba(212, 208, 203, %s)',
562
+ 'color2' => '#FFF',
563
+ 'label' => __( 'Instructors', 'learnpress' )
564
+ ),
565
+ array(
566
+ 'color1' => 'rgba(234, 199, 155, %s)',
567
+ 'color2' => '#FFF',
568
+ 'label' => __( 'Students', 'learnpress' )
569
+ )
570
+ );
571
+
572
+ foreach ( $dataset_params as $k => $v ) {
573
+ $datasets[$k]['fillColor'] = sprintf( $v['color1'], '0.2' );
574
+ $datasets[$k]['strokeColor'] = sprintf( $v['color1'], '1' );
575
+ $datasets[$k]['pointColor'] = sprintf( $v['color1'], '1' );
576
+ $datasets[$k]['pointStrokeColor'] = $v['color2'];
577
+ $datasets[$k]['pointHighlightFill'] = $v['color2'];
578
+ $datasets[$k]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
579
+ $datasets[$k]['label'] = $v['label'];
580
+ }
581
+
582
+ return array(
583
+ 'labels' => $labels,
584
+ 'datasets' => $datasets,
585
+ 'sql' => $query
586
+ );
587
+ }
588
+
589
+
590
+ /**
591
+ * Get data about students to render in chart
592
+ *
593
+ * @param null $from
594
+ * @param null $by
595
+ * @param $time_ago
596
+ *
597
+ * @return array
598
+ */
599
+ function learn_press_get_chart_courses( $from = null, $by = null, $time_ago ) {
600
+ global $wpdb;
601
+
602
+ $labels = array();
603
+ $datasets = array();
604
+ if ( is_null( $from ) ) {
605
+ $from = current_time( 'mysql' );
606
+ }
607
+ if ( is_null( $by ) ) {
608
+ $by = 'days';
609
+ }
610
+ $results = array(
611
+ 'all' => array(),
612
+ 'public' => array(),
613
+ 'pending' => array(),
614
+ 'free' => array(),
615
+ 'paid' => array()
616
+ );
617
+ $from_time = is_numeric( $from ) ? $from : strtotime( $from );
618
+
619
+ switch ( $by ) {
620
+ case 'days':
621
+ $date_format = 'M d Y';
622
+ $_from = - $time_ago + 1;
623
+ $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
624
+ $_to = date( 'Y-m-d', $from_time );
625
+ $_sql_format = '%Y-%m-%d';
626
+ $_key_format = 'Y-m-d';
627
+ break;
628
+ case 'months':
629
+ $date_format = 'M Y';
630
+ $_from = - $time_ago + 1;
631
+ $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
632
+ $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
633
+ $_to = date( 'Y-m-' . $days, $from_time );
634
+ $_sql_format = '%Y-%m';
635
+ $_key_format = 'Y-m';
636
+ break;
637
+ case 'years':
638
+ $date_format = 'Y';
639
+ $_from = - $time_ago + 1;
640
+ $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
641
+ $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
642
+ $_to = date( 'Y-12-' . $days, $from_time );
643
+ $_sql_format = '%Y';
644
+ $_key_format = 'Y';
645
+
646
+ break;
647
+ }
648
+
649
+ $query_where = '';
650
+ if ( current_user_can( LP_TEACHER_ROLE ) ) {
651
+ $user_id = learn_press_get_current_user_id();
652
+ $query_where .= $wpdb->prepare( " AND c.post_author=%d ", $user_id );
653
+ }
654
+
655
+ $query = $wpdb->prepare( "
656
+ SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
657
+ FROM {$wpdb->posts} c
658
+ WHERE 1
659
+ {$query_where}
660
+ AND c.post_status IN('publish', 'pending') AND c.post_type = %s
661
+ GROUP BY d
662
+ HAVING d BETWEEN %s AND %s
663
+ ORDER BY d ASC
664
+ ", $_sql_format, 'lp_course', $_from, $_to );
665
+ if ( $_results = $wpdb->get_results( $query ) ) {
666
+ foreach ( $_results as $k => $v ) {
667
+ $results['all'][$v->d] = $v;
668
+ }
669
+ }
670
+ $query = $wpdb->prepare( "
671
+ SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
672
+ FROM {$wpdb->posts} c
673
+ WHERE 1
674
+ {$query_where}
675
+ AND c.post_status = %s AND c.post_type = %s
676
+ GROUP BY d
677
+ HAVING d BETWEEN %s AND %s
678
+ ORDER BY d ASC
679
+ ", $_sql_format, 'publish', 'lp_course', $_from, $_to );
680
+ if ( $_results = $wpdb->get_results( $query ) ) {
681
+ foreach ( $_results as $k => $v ) {
682
+ $results['publish'][$v->d] = $v;
683
+ }
684
+ }
685
+
686
+ $query = $wpdb->prepare( "
687
+ SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
688
+ FROM {$wpdb->posts} c
689
+ INNER JOIN {$wpdb->postmeta} cm ON cm.post_id = c.ID AND cm.meta_key = %s AND cm.meta_value = %s
690
+ WHERE 1
691
+ {$query_where}
692
+ AND c.post_status = %s AND c.post_type = %s
693
+ GROUP BY d
694
+ HAVING d BETWEEN %s AND %s
695
+ ORDER BY d ASC
696
+ ", $_sql_format, '_lp_payment', 'yes', 'publish', 'lp_course', $_from, $_to );
697
+ if ( $_results = $wpdb->get_results( $query ) ) {
698
+ foreach ( $_results as $k => $v ) {
699
+ $results['paid'][$v->d] = $v;
700
+ }
701
+ }
702
+
703
+ for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
704
+ $date = strtotime( "$i $by", $from_time );
705
+ $labels[] = date( $date_format, $date );
706
+ $key = date( $_key_format, $date );
707
+
708
+ $all = !empty( $results['all'][$key] ) ? $results['all'][$key]->c : 0;
709
+ $publish = !empty( $results['publish'][$key] ) ? $results['publish'][$key]->c : 0;
710
+ $paid = !empty( $results['paid'][$key] ) ? $results['paid'][$key]->c : 0;
711
+
712
+ $datasets[0]['data'][] = $all;
713
+ $datasets[1]['data'][] = $publish;
714
+ $datasets[2]['data'][] = $all - $publish;
715
+ $datasets[3]['data'][] = $paid;
716
+ $datasets[4]['data'][] = $all - $paid;
717
+ }
718
+
719
+ $dataset_params = array(
720
+ array(
721
+ 'color1' => 'rgba(47, 167, 255, %s)',
722
+ 'color2' => '#FFF',
723
+ 'label' => __( 'All', 'learnpress' )
724
+ ),
725
+ array(
726
+ 'color1' => 'rgba(212, 208, 203, %s)',
727
+ 'color2' => '#FFF',
728
+ 'label' => __( 'Publish', 'learnpress' )
729
+ ),
730
+ array(
731
+ 'color1' => 'rgba(234, 199, 155, %s)',
732
+ 'color2' => '#FFF',
733
+ 'label' => __( 'Pending', 'learnpress' )
734
+ ),
735
+ array(
736
+ 'color1' => 'rgba(234, 199, 155, %s)',
737
+ 'color2' => '#FFF',
738
+ 'label' => __( 'Paid', 'learnpress' )
739
+ ),
740
+ array(
741
+ 'color1' => 'rgba(234, 199, 155, %s)',
742
+ 'color2' => '#FFF',
743
+ 'label' => __( 'Free', 'learnpress' )
744
+ )
745
+ );
746
+
747
+ foreach ( $dataset_params as $k => $v ) {
748
+ $datasets[$k]['fillColor'] = sprintf( $v['color1'], '0.2' );
749
+ $datasets[$k]['strokeColor'] = sprintf( $v['color1'], '1' );
750
+ $datasets[$k]['pointColor'] = sprintf( $v['color1'], '1' );
751
+ $datasets[$k]['pointStrokeColor'] = $v['color2'];
752
+ $datasets[$k]['pointHighlightFill'] = $v['color2'];
753
+ $datasets[$k]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
754
+ $datasets[$k]['label'] = $v['label'];
755
+ }
756
+
757
+ return array(
758
+ 'labels' => $labels,
759
+ 'datasets' => $datasets,
760
+ 'sql' => $query
761
+ );
762
+ }
763
+
764
+
765
+ /**
766
+ * Get data about students to render in chart
767
+ *
768
+ * @param null $from
769
+ * @param null $by
770
+ * @param $time_ago
771
+ *
772
+ * @return array
773
+ */
774
+ function learn_press_get_chart_orders( $from = null, $by = null, $time_ago ) {
775
+ global $wpdb;
776
+ // var_dump( current_user_can(LP_TEACHER_ROLE) );
777
+ // exit();
778
+ $report_sales_by = learn_press_get_request( 'report_sales_by' );
779
+ $course_id = learn_press_get_request( 'course_id' );
780
+ $cat_id = learn_press_get_request( 'cat_id' );
781
+
782
+ $labels = array();
783
+ $datasets = array();
784
+ if ( is_null( $from ) ) {
785
+ $from = current_time( 'mysql' );
786
+ }
787
+ if ( is_null( $by ) ) {
788
+ $by = 'days';
789
+ }
790
+ $results = array(
791
+ 'all' => array(),
792
+ 'completed' => array(),
793
+ 'pending' => array()
794
+ );
795
+ $from_time = is_numeric( $from ) ? $from : strtotime( $from );
796
+
797
+ switch ( $by ) {
798
+ case 'days':
799
+ $date_format = 'M d Y';
800
+ $_from = - $time_ago + 1;
801
+ $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
802
+ $_to = date( 'Y-m-d', $from_time );
803
+ $_sql_format = '%Y-%m-%d';
804
+ $_key_format = 'Y-m-d';
805
+ break;
806
+ case 'months':
807
+ $date_format = 'M Y';
808
+ $_from = - $time_ago + 1;
809
+ $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
810
+ $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
811
+ $_to = date( 'Y-m-' . $days, $from_time );
812
+ $_sql_format = '%Y-%m';
813
+ $_key_format = 'Y-m';
814
+ break;
815
+ case 'years':
816
+ $date_format = 'Y';
817
+ $_from = - $time_ago + 1;
818
+ $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
819
+ $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
820
+ $_to = date( 'Y-12-' . $days, $from_time );
821
+ $_sql_format = '%Y';
822
+ $_key_format = 'Y';
823
+
824
+ break;
825
+ }
826
+
827
+ $query_join = '';
828
+ $query_where = '';
829
+ if ( 'course' === $report_sales_by ) {
830
+ $sql_join .= " INNER JOIN `{$wpdb->prefix}learnpress_order_items` `lpoi` "
831
+ . " ON o.ID=lpoi.order_id "
832
+ . " INNER JOIN {$wpdb->prefix}learnpress_order_itemmeta loim "
833
+ . " ON lpoi.order_item_id=loim.learnpress_order_item_id "
834
+ . " AND loim.meta_key='_course_id' "
835
+ . " AND CAST(loim.meta_value AS SIGNED)=%d ";
836
+ if ( current_user_can( LP_TEACHER_ROLE ) ) {
837
+ $user_id = learn_press_get_current_user_id();
838
+ $sql_join .= $wpdb->prepare( " AND CAST(loim.meta_value AS SIGNED) IN "
839
+ . " ( "
840
+ . " SELECT ID FROM {$wpdb->posts} p WHERE p.ID = CAST(loim.meta_value AS SIGNED) AND `post_author`=" . intval( $user_id )
841
+ . " ) " );
842
+ }
843
+ $query_join .= $wpdb->prepare( $sql_join, $course_id );
844
+
845
+ } elseif ( 'category' === $report_sales_by ) {
846
+ $sql_join .= " INNER JOIN `{$wpdb->prefix}learnpress_order_items` `lpoi` "
847
+ . " ON o.ID=lpoi.order_id "
848
+ . " INNER JOIN {$wpdb->prefix}learnpress_order_itemmeta loim "
849
+ . " ON lpoi.order_item_id=loim.learnpress_order_item_id "
850
+ . " AND loim.meta_key='_course_id' "
851
+ . " AND CAST(loim.meta_value AS SIGNED) IN("
852
+ //sub query
853
+ . " SELECT tr.object_id "
854
+ . " FROM wp_term_taxonomy tt INNER JOIN wp_term_relationships tr "
855
+ . " ON tt.term_taxonomy_id = tr.term_taxonomy_id AND tt.taxonomy='course_category' "
856
+ . " WHERE tt.term_id=%d)";
857
+ $query_join .= $wpdb->prepare( $sql_join, $cat_id );
858
+ }
859
+ if ( current_user_can( LP_TEACHER_ROLE ) ) {
860
+ $user_id = learn_press_get_current_user_id();
861
+ $query_where .= $wpdb->prepare( " AND o.ID IN( SELECT oi.order_id
862
+ FROM lptest.{$wpdb->prefix}learnpress_order_items oi
863
+ inner join {$wpdb->prefix}learnpress_order_itemmeta oim
864
+ on oi.order_item_id = oim.learnpress_order_item_id
865
+ and oim.meta_key='_course_id'
866
+ and cast(oim.meta_value as SIGNED) IN (
867
+ SELECT sp.ID FROM {$wpdb->prefix}posts sp WHERE sp.post_author=%d and sp.ID=cast(oim.meta_value as SIGNED)
868
+ )
869
+ ) ", $user_id );
870
+ }
871
+
872
+ $query = $wpdb->prepare( "
873
+ SELECT count(o.ID) as c, DATE_FORMAT( o.post_date, %s) as d
874
+ FROM {$wpdb->posts} o {$query_join}
875
+ WHERE 1 {$query_where}
876
+ AND o.post_status IN('lp-completed') AND o.post_type = %s
877
+ GROUP BY d
878
+ HAVING d BETWEEN %s AND %s
879
+ ORDER BY d ASC
880
+ ", $_sql_format, 'lp_order', $_from, $_to );
881
+ // echo $query;
882
+ if ( $_results = $wpdb->get_results( $query ) ) {
883
+ foreach ( $_results as $k => $v ) {
884
+ // $results['all'][$v->d] = $v;
885
+ $results['completed'][$v->d] = $v;
886
+ }
887
+ }
888
+
889
+ $query = $wpdb->prepare( "
890
+ SELECT count(o.ID) as c, DATE_FORMAT( o.post_date, %s) as d
891
+ FROM {$wpdb->posts} o {$query_join}
892
+ WHERE 1 {$query_where}
893
+ AND o.post_status IN('lp-pending', 'lp-processing') AND o.post_type = %s
894
+ GROUP BY d
895
+ HAVING d BETWEEN %s AND %s
896
+ ORDER BY d ASC
897
+ ", $_sql_format, 'lp_order', $_from, $_to );
898
+ // echo $query;
899
+ if ( $_results = $wpdb->get_results( $query ) ) {
900
+ foreach ( $_results as $k => $v ) {
901
+ // $results['completed'][$v->d] = $v;
902
+ $results['pending'][$v->d] = $v;
903
+ }
904
+ }
905
+
906
+
907
+ for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
908
+ $date = strtotime( "$i $by", $from_time );
909
+ $labels[] = date( $date_format, $date );
910
+ $key = date( $_key_format, $date );
911
+
912
+ $completed = !empty( $results['completed'][$key] ) ? $results['completed'][$key]->c : 0;
913
+ $pending = !empty( $results['pending'][$key] ) ? $results['pending'][$key]->c : 0;
914
+ $all = $completed + $pending;
915
+
916
+ $datasets[0]['data'][] = $all;
917
+ $datasets[1]['data'][] = $completed;
918
+ $datasets[2]['data'][] = $pending;
919
+ }
920
+
921
+ $dataset_params = array(
922
+ array(
923
+ 'color1' => 'rgba(47, 167, 255, %s)',
924
+ 'color2' => '#FFF',
925
+ 'label' => __( 'All', 'learnpress' )
926
+ ),
927
+ array(
928
+ 'color1' => 'rgba(212, 208, 203, %s)',
929
+ 'color2' => '#FFF',
930
+ 'label' => __( 'Completed', 'learnpress' )
931
+ ),
932
+ array(
933
+ 'color1' => 'rgba(234, 199, 155, %s)',
934
+ 'color2' => '#FFF',
935
+ 'label' => __( 'Pending', 'learnpress' )
936
+ )
937
+ );
938
+
939
+ foreach ( $dataset_params as $k => $v ) {
940
+ $datasets[$k]['fillColor'] = sprintf( $v['color1'], '0.2' );
941
+ $datasets[$k]['strokeColor'] = sprintf( $v['color1'], '1' );
942
+ $datasets[$k]['pointColor'] = sprintf( $v['color1'], '1' );
943
+ $datasets[$k]['pointStrokeColor'] = $v['color2'];
944
+ $datasets[$k]['pointHighlightFill'] = $v['color2'];
945
+ $datasets[$k]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
946
+ $datasets[$k]['label'] = $v['label'];
947
+ }
948
+
949
+ return array(
950
+ 'labels' => $labels,
951
+ 'datasets' => $datasets,
952
+ 'sql' => $query
953
+ );
954
+ }
955
+
956
+ /**
957
+ * Get data about courses to render in the chart
958
+ * @return array
959
+ */
960
+ function learn_press_get_chart_courses2() {
961
+ $labels = array( __( 'Pending Courses / Publish Courses', 'learnpress' ), __( 'Free Courses / Priced Courses', 'learnpress' ) );
962
+ $datasets = array();
963
+ $datasets[0]['data'] = array( learn_press_get_courses_by_status( 'pending' ), learn_press_get_courses_by_price( 'free' ) );
964
+ $datasets[1]['data'] = array( learn_press_get_courses_by_status( 'publish' ), learn_press_get_courses_by_price( 'not_free' ) );
965
+
966
+ $colors = learn_press_get_admin_colors();
967
+ $datasets[0]['fillColor'] = $colors[1];
968
+ $datasets[0]['strokeColor'] = $colors[1];
969
+ $datasets[1]['fillColor'] = $colors[3];
970
+ $datasets[1]['strokeColor'] = $colors[3];
971
+ return array(
972
+ 'labels' => $labels,
973
+ 'datasets' => $datasets
974
+ );
975
+ }
976
+
977
+ /**
978
+ * Get colors setting up by admin user
979
+ * @return array
980
+ */
981
+ function learn_press_get_admin_colors() {
982
+ $admin_color = get_user_meta( get_current_user_id(), 'admin_color', true );
983
+ global $_wp_admin_css_colors;
984
+ $colors = array();
985
+ if ( !empty( $_wp_admin_css_colors[$admin_color]->colors ) ) {
986
+ $colors = $_wp_admin_css_colors[$admin_color]->colors;
987
+ }
988
+ if ( empty ( $colors[0] ) ) {
989
+ $colors[0] = '#000000';
990
+ }
991
+ if ( empty ( $colors[2] ) ) {
992
+ $colors[2] = '#00FF00';
993
+ }
994
+ return $colors;
995
+ }
996
+
997
+ /**
998
+ * Convert an array to json format and print out to browser
999
+ *
1000
+ * @param array $chart
1001
+ */
1002
+ function learn_press_process_chart( $chart = array() ) {
1003
+ $data = json_encode(
1004
+ array(
1005
+ 'labels' => $chart['labels'],
1006
+ 'datasets' => $chart['datasets']
1007
+ )
1008
+ );
1009
+ echo $data;
1010
+ }
1011
+
1012
+ /**
1013
+ * Print out the configuration for admin chart
1014
+ */
1015
+ function learn_press_config_chart() {
1016
+ $colors = learn_press_get_admin_colors();
1017
+ $config = array(
1018
+ 'scaleShowGridLines' => true,
1019
+ 'scaleGridLineColor' => "#777",
1020
+ 'scaleGridLineWidth' => 0.3,
1021
+ 'scaleFontColor' => "#444",
1022
+ 'scaleLineColor' => $colors[0],
1023
+ 'bezierCurve' => true,
1024
+ 'bezierCurveTension' => 0.2,
1025
+ 'pointDotRadius' => 5,
1026
+ 'pointDotStrokeWidth' => 5,
1027
+ 'pointHitDetectionRadius' => 20,
1028
+ 'datasetStroke' => true,
1029
+ 'responsive' => true,
1030
+ 'tooltipFillColor' => $colors[2],
1031
+ 'tooltipFontColor' => "#eee",
1032
+ 'tooltipCornerRadius' => 0,
1033
+ 'tooltipYPadding' => 10,
1034
+ 'tooltipXPadding' => 10,
1035
+ 'barDatasetSpacing' => 10,
1036
+ 'barValueSpacing' => 200
1037
+
1038
+ );
1039
+ echo json_encode( $config );
1040
+ }
1041
+
1042
+ function set_post_order_in_admin( $wp_query ) {
1043
+ global $pagenow;
1044
+ if ( isset( $_GET['post_type'] ) ) {
1045
+ $post_type = $_GET['post_type'];
1046
+ } else $post_type = '';
1047
+ if ( is_admin() && 'edit.php' == $pagenow && $post_type == LP_COURSE_CPT && !isset( $_GET['orderby'] ) ) {
1048
+ $wp_query->set( 'orderby', 'date' );
1049
+ $wp_query->set( 'order', 'DSC' );
1050
+ }
1051
+ }
1052
+
1053
+ add_filter( 'pre_get_posts', 'set_post_order_in_admin' );
1054
+ /**
1055
+ * Add actions to the list of the course. e.g: Duplicate link
1056
+ *
1057
+ * @param $actions
1058
+ *
1059
+ * @return mixed
1060
+ */
1061
+ function learn_press_add_row_action_link( $actions ) {
1062
+ global $post;
1063
+ if ( LP_COURSE_CPT == $post->post_type ) {
1064
+ $duplicate_link = admin_url( 'edit.php?post_type=lp_course&action=lp-duplicate-course&post=' . $post->ID . '&nonce=' . wp_create_nonce( 'lp-duplicate-' . $post->ID ) );
1065
+ $duplicate_link = array(
1066
+ array(
1067
+ 'link' => $duplicate_link,
1068
+ 'title' => __( 'Duplicate this course', 'learnpress' ),
1069
+ 'class' => 'lp-duplicate-course'
1070
+ )
1071
+ );
1072
+ $links = apply_filters( 'learn_press_row_action_links', $duplicate_link );
1073
+ if ( count( $links ) > 1 ) {
1074
+ $drop_down = array( '<ul class="lpr-row-action-dropdown">' );
1075
+ foreach ( $links as $link ) {
1076
+ $drop_down[] = '<li>' . sprintf( '<a href="%s" class="%s">%s</a>', $link['link'], $link['class'], $link['title'] ) . '</li>';
1077
+ };
1078
+ $drop_down[] = '</ul>';
1079
+ $link = sprintf( '<div class="lpr-row-actions"><a href="%s">%s</a>%s</div>', 'javascript: void(0);', __( 'Course', 'learnpress' ), join( "\n", $drop_down ) );
1080
+ } else {
1081
+ $link = array_shift( $links );
1082
+ $link = sprintf( '<a href="%s" class="%s">%s</a>', $link['link'], $link['class'], $link['title'] );
1083
+ }
1084
+ $actions['lpr-course-row-action'] = $link;
1085
+ } else if ( LP_QUIZ_CPT === $post->post_type ) {
1086
+ unset( $actions['view'] );
1087
+ $url = admin_url( 'edit.php?post_type=' . LP_QUIZ_CPT . '&lp-action=lp-duplicate-quiz&post=' . $post->ID . '&nonce=' . wp_create_nonce( 'lp-duplicate-' . $post->ID ) );
1088
+ $link = sprintf( '<a href="%s" class="lp-duplicate-lesson">%s</a>', $url, __( 'Duplicate this quiz', 'learnpress' ) );
1089
+ $actions['lpr-course-row-action'] = $link;
1090
+ } else if ( LP_QUESTION_CPT === $post->post_type ) {
1091
+ unset( $actions['view'] );
1092
+ $url = admin_url( 'edit.php?post_type=' . LP_QUESTION_CPT . '&lp-action=lp-duplicate-question&post=' . $post->ID . '&nonce=' . wp_create_nonce( 'lp-duplicate-' . $post->ID ) );
1093
+ $link = sprintf( '<a href="%s" class="lp-duplicate-lesson">%s</a>', $url, __( 'Duplicate this question', 'learnpress' ) );
1094
+ $actions['lpr-course-row-action'] = $link;
1095
+ } else if ( LP_LESSON_CPT === $post->post_type ) {
1096
+ unset( $actions['view'] );
1097
+ $url = admin_url( 'edit.php?post_type=' . LP_LESSON_CPT . '&lp-action=lp-duplicate-lesson&post=' . $post->ID . '&nonce=' . wp_create_nonce( 'lp-duplicate-' . $post->ID ) );
1098
+ $link = sprintf( '<a href="%s" class="lp-duplicate-lesson">%s</a>', $url, __( 'Duplicate this lesson', 'learnpress' ) );
1099
+ $actions['lpr-course-row-action'] = $link;
1100
+ }
1101
+ return $actions;
1102
+ }
1103
+
1104
+ add_filter( 'post_row_actions', 'learn_press_add_row_action_link' );
1105
+ add_filter( 'page_row_actions', 'learn_press_add_row_action_link' );
1106
+
1107
+ function learn_press_copy_post_meta( $from_id, $to_id ) {
1108
+ global $wpdb;
1109
+ $course_meta = $wpdb->get_results(
1110
+ $wpdb->prepare( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id = %d", $from_id )
1111
+ );
1112
+ if ( count( $course_meta ) != 0 ) {
1113
+ $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
1114
+ $sql_query_sel = array();
1115
+
1116
+ foreach ( $course_meta as $meta ) {
1117
+ $meta_key = $meta->meta_key;
1118
+ $meta_value = addslashes( $meta->meta_value );
1119
+
1120
+ $sql_query_sel[] = "SELECT {$to_id}, '$meta_key', '$meta_value'";
1121
+ }
1122
+
1123
+ $sql_query .= implode( " UNION ALL ", $sql_query_sel );
1124
+ $wpdb->query( $sql_query );
1125
+ }
1126
+ }
1127
+
1128
+ /**
1129
+ * Duplicate a course when user hit "Duplicate" button
1130
+ *
1131
+ * @author TuNN
1132
+ */
1133
+ function learn_press_process_duplicate_action() {
1134
+
1135
+ $wp_list_table = _get_list_table( 'WP_Posts_List_Table' );
1136
+ $action = $wp_list_table->current_action();
1137
+
1138
+ if ( isset( $_REQUEST['action'] ) && $action == 'lp-duplicate-course' ) {
1139
+ // current is not usefully because this feature using ajax action
1140
+ $post_id = isset( $_REQUEST['post'] ) ? $_REQUEST['post'] : 0;
1141
+ $nonce = !empty( $_REQUEST['nonce'] ) ? $_REQUEST['nonce'] : '';
1142
+ if ( !wp_verify_nonce( $nonce, 'lp-duplicate-' . $post_id ) ) {
1143
+ wp_die( __( 'Error', 'learnpress' ) );
1144
+ }
1145
+ if ( $post_id && is_array( $post_id ) ) {
1146
+ $post_id = array_shift( $post_id );
1147
+ }
1148
+ // check for post is exists
1149
+ if ( !( $post_id && $post = get_post( $post_id ) ) ) {
1150
+ wp_die( __( 'Oops! The course does not exist.', 'learnpress' ) );
1151
+ }
1152
+ // ensure that user can create course
1153
+ if ( !current_user_can( 'edit_posts' ) ) {
1154
+ wp_die( __( 'Sorry! You have not permission to duplicate this course.', 'learnpress' ) );
1155
+ }
1156
+
1157
+ // assign course to current user
1158
+ $current_user = wp_get_current_user();
1159
+ $new_course_author = $current_user->ID;
1160
+
1161
+ // setup course data
1162
+ $new_course_title = $post->post_title . ' - Copy';
1163
+ $args = array(
1164
+ 'comment_status' => $post->comment_status,
1165
+ 'ping_status' => $post->ping_status,
1166
+ 'post_author' => $new_course_author,
1167
+ 'post_content' => $post->post_content,
1168
+ 'post_excerpt' => $post->post_excerpt,
1169
+ 'post_name' => $post->post_name,
1170
+ 'post_parent' => $post->post_parent,
1171
+ 'post_password' => $post->post_password,
1172
+ 'post_status' => 'draft',
1173
+ 'post_title' => $new_course_title,
1174
+ 'post_type' => $post->post_type,
1175
+ 'to_ping' => $post->to_ping,
1176
+ 'menu_order' => $post->menu_order
1177
+ );
1178
+
1179
+ // insert new course and get it ID
1180
+ $new_post_id = wp_insert_post( $args );
1181
+
1182
+ if ( !$new_post_id ) {
1183
+ LP_Admin_Notice::add_redirect( __( '<p>Sorry! Duplicate course failed!</p>', 'learnpress' ) );
1184
+ wp_redirect( admin_url( 'edit.php?post_type=lp_course' ) );
1185
+ exit();
1186
+ }
1187
+ // assign related tags/categories to new course
1188
+ $taxonomies = get_object_taxonomies( $post->post_type );
1189
+ foreach ( $taxonomies as $taxonomy ) {
1190
+ $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
1191
+ wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false );
1192
+ }
1193
+
1194
+ // duplicate course data
1195
+ global $wpdb;
1196
+ //learn_press_copy_post_meta( $post_id, $new_post_id );
1197
+
1198
+ $query = $wpdb->prepare( "
1199
+ SELECT *
1200
+ FROM {$wpdb->prefix}learnpress_sections s
1201
+ INNER JOIN {$wpdb->posts} c ON c.ID = s.section_course_id
1202
+ WHERE c.ID = %d
1203
+ ", $post->ID );
1204
+ if ( $sections = $wpdb->get_results( $query ) ) {
1205
+ foreach ( $sections as $section ) {
1206
+ $new_section_id = $wpdb->insert(
1207
+ $wpdb->prefix . 'learnpress_sections',
1208
+ array(
1209
+ 'section_name' => $section->section_name,
1210
+ 'section_course_id' => $new_post_id,
1211
+ 'section_order' => $section->section_order,
1212
+ 'section_description' => $section->section_description
1213
+ ),
1214
+ array( '%s', '%d', '%d', '%s' )
1215
+ );
1216
+ if ( $new_section_id ) {
1217
+ $query = $wpdb->prepare( "
1218
+ SELECT i.*
1219
+ FROM {$wpdb->posts} i
1220
+ INNER JOIN {$wpdb->prefix}learnpress_sections s ON i.item_id = i.ID
1221
+ WHERE s.section_id = %d
1222
+ ", $section->section_id );
1223
+ if ( $items = $wpdb->get_results( $query ) ) {
1224
+ foreach ( $items as $item ) {
1225
+ $item_args = (array) $item;
1226
+ unset(
1227
+ $item_args['ID'],
1228
+ $item_args['post_author'],
1229
+ $item_args['post_date'],
1230
+ $item_args['post_date_gmt'],
1231
+ $item_args['post_modified'],
1232
+ $item_args['post_modified_gmt'],
1233
+ $item_args['comment_count']
1234
+ );
1235
+ $new_item_id = $wpdb->insert(
1236
+ $wpdb->posts,
1237
+ $item_args
1238
+ );
1239
+ }
1240
+ }
1241
+ }
1242
+ }
1243
+ }
1244
+ LP_Admin_Notice::add_redirect( __( '<p>Course duplicated.</p>', 'learnpress' ) );
1245
+ wp_redirect( admin_url( "post.php?post={$new_post_id}&action=edit" ) );
1246
+ die();
1247
+ }
1248
+
1249
+ // duplicate action
1250
+ $action = !empty( $_REQUEST['lp-action'] ) ? $_REQUEST['lp-action'] : '';
1251
+ $actions = array(
1252
+ 'lp-duplicate-question',
1253
+ 'lp-duplicate-lesson',
1254
+ 'lp-duplicate-quiz'
1255
+ );
1256
+ if ( !in_array( $action, $actions ) ) {
1257
+ return;
1258
+ }
1259
+
1260
+ $post_id = !empty ( $_REQUEST['post'] ) ? $_REQUEST['post'] : 0;
1261
+ $nonce = !empty( $_REQUEST['nonce'] ) ? $_REQUEST['nonce'] : '';
1262
+ if ( !$post_id || !wp_verify_nonce( $nonce, 'lp-duplicate-' . $post_id ) ) return;
1263
+ // only duplicate question. not assign any data
1264
+ $new_post_id = 0;
1265
+ if ( $action === 'lp-duplicate-question' ) {
1266
+ $new_post_id = learn_press_duplicate_question( $post_id );
1267
+ $post_type = LP_QUESTION_CPT;
1268
+ $error = __( 'Sorry! Duplicate question failed!', 'learnpress' );
1269
+ $success = __( 'Question duplicated.', 'learnpress' );
1270
+ } else if ( $action === 'lp-duplicate-lesson' ) {
1271
+ $new_post_id = learn_press_duplicate_lesson( $post_id );
1272
+ $post_type = LP_LESSON_CPT;
1273
+ $error = __( 'Sorry! Duplicate lesson failed!', 'learnpress' );
1274
+ $success = __( 'Lesson duplicated.', 'learnpress' );
1275
+ } else if ( $action === 'lp-duplicate-quiz' ) {
1276
+ $new_post_id = learn_press_duplicate_quiz( $post_id );
1277
+ $post_type = LP_QUIZ_CPT;
1278
+ $error = __( 'Sorry! Duplicate quiz failed!', 'learnpress' );
1279
+ $success = __( 'Quiz duplicated.', 'learnpress' );
1280
+ }
1281
+
1282
+ if ( !$new_post_id ) return;
1283
+ $redirect = 0;
1284
+ if ( is_wp_error( $new_post_id ) ) {
1285
+ LP_Admin_Notice::add_redirect( $error, 'error' );
1286
+ $redirect = admin_url( 'edit.php?post_type=' . $post_type );
1287
+ } else {
1288
+ LP_Admin_Notice::add_redirect( $success, 'updated' );
1289
+ $redirect = admin_url( 'post.php?post=' . $new_post_id . '&action=edit' );
1290
+ }
1291
+
1292
+ if ( $redirect ) {
1293
+ wp_safe_redirect( $redirect );
1294
+ exit();
1295
+ }
1296
+ }
1297
+
1298
+ add_action( 'load-edit.php', 'learn_press_process_duplicate_action' );
1299
+
1300
+ /**
1301
+ * Install a plugin
1302
+ *
1303
+ * @param string $plugin_name
1304
+ *
1305
+ * @return array
1306
+ */
1307
+ function learn_press_install_add_on( $plugin_name ) {
1308
+ require_once( LP_PLUGIN_PATH . '/inc/admin/class-lp-upgrader.php' );
1309
+ $upgrader = new LP_Upgrader();
1310
+ global $wp_filesystem;
1311
+ $response = array();
1312
+
1313
+ $package = 'http://thimpress.com/lprepo/' . $plugin_name . '.zip';
1314
+
1315
+ $package = $upgrader->download_package( $package );
1316
+ if ( is_wp_error( $package ) ) {
1317
+ $response['error'] = $package;
1318
+ } else {
1319
+ $working_dir = $upgrader->unpack_package( $package, true, $plugin_name );
1320
+ if ( is_wp_error( $working_dir ) ) {
1321
+ $response['error'] = $working_dir;
1322
+ } else {
1323
+
1324
+ $wp_upgrader = new WP_Upgrader();
1325
+ $options = array(
1326
+ 'source' => $working_dir,
1327
+ 'destination' => WP_PLUGIN_DIR,
1328
+ 'clear_destination' => false, // Do not overwrite files.
1329
+ 'clear_working' => true,
1330
+ 'hook_extra' => array(
1331
+ 'type' => 'plugin',
1332
+ 'action' => 'install'
1333
+ )
1334
+ );
1335
+ //$response = array();
1336
+ $result = $wp_upgrader->install_package( $options );
1337
+
1338
+ if ( is_wp_error( $result ) ) {
1339
+ $response['error'] = $result;
1340
+ } else {
1341
+ $response = $result;
1342
+ $response['text'] = __( 'Installed', 'learnpress' );
1343
+ }
1344
+ }
1345
+ }
1346
+ return $response;
1347
+ }
1348
+
1349
+ function learn_press_accept_become_a_teacher() {
1350
+ $action = !empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
1351
+ $user_id = !empty( $_REQUEST['user_id'] ) ? $_REQUEST['user_id'] : '';
1352
+ if ( !$action || !$user_id || ( $action != 'accept-to-be-teacher' ) ) return;
1353
+
1354
+ if ( !learn_press_user_maybe_is_a_teacher( $user_id ) ) {
1355
+ $be_teacher = new WP_User( $user_id );
1356
+ $be_teacher->set_role( LP_TEACHER_ROLE );
1357
+ delete_transient( 'learn_press_become_teacher_sent_' . $user_id );
1358
+ do_action( 'learn_press_user_become_a_teacher', $user_id );
1359
+ $redirect = add_query_arg( 'become-a-teacher-accepted', 'yes' );
1360
+ $redirect = remove_query_arg( 'action', $redirect );
1361
+ wp_redirect( $redirect );
1362
+ }
1363
+ }
1364
+
1365
+ add_action( 'plugins_loaded', 'learn_press_accept_become_a_teacher' );
1366
+
1367
+ function learn_press_user_become_a_teacher_notice() {
1368
+ if ( $user_id = learn_press_get_request( 'user_id' ) && learn_press_get_request( 'become-a-teacher-accepted' ) == 'yes' ) {
1369
+ $user = new WP_User( $user_id );
1370
+ ?>
1371
+ <div class="updated">
1372
+ <p><?php printf( __( 'The user %s has become a teacher', 'learnpress' ), $user->user_login ); ?></p>
1373
+ </div>
1374
+ <?php
1375
+ }
1376
+ }
1377
+
1378
+ add_action( 'admin_notices', 'learn_press_user_become_a_teacher_notice' );
1379
+
1380
+ /**
1381
+ * Check to see if a plugin is already installed or not
1382
+ *
1383
+ * @param $plugin
1384
+ *
1385
+ * @return bool
1386
+ */
1387
+ function learn_press_is_plugin_install( $plugin ) {
1388
+ $installed_plugins = get_plugins();
1389
+ return isset( $installed_plugins[$plugin] );
1390
+ }
1391
+
1392
+ /**
1393
+ * Get plugin file that contains the information from slug
1394
+ *
1395
+ * @param $slug
1396
+ *
1397
+ * @return mixed
1398
+ */
1399
+ function learn_press_plugin_basename_from_slug( $slug ) {
1400
+ $keys = array_keys( get_plugins() );
1401
+ foreach ( $keys as $key ) {
1402
+ if ( preg_match( '|^' . $slug . '/|', $key ) ) {
1403
+ return $key;
1404
+ }
1405
+ }
1406
+ return $slug;
1407
+ }
1408
+
1409
+ function learn_press_one_click_install_sample_data_notice() {
1410
+ $courses = get_posts(
1411
+ array(
1412
+ 'post_type' => LP_COURSE_CPT,
1413
+ 'post_status' => 'any'
1414
+ )
1415
+ );
1416
+ if ( ( 0 == sizeof( $courses ) ) && ( 'off' != get_transient( 'learn_press_install_sample_data' ) ) ) {
1417
+ printf(
1418
+ '<div class="updated" id="learn-press-install-sample-data-notice">
1419
+ <div class="install-sample-data-notice">
1420
+ <p>%s</p>
1421
+ <p>%s <strong>%s</strong> %s
1422
+ <p><a href="" class="button yes" data-action="yes">%s</a> <a href="" class="button disabled no" data-action="no">%s</a></p>
1423
+ </div>
1424
+ <div class="install-sample-data-loading">
1425
+ <p>Importing...</p>
1426
+ </div>
1427
+ </div>',
1428
+ __( 'You haven\'t got any courses yet! Would you like to import sample data?', 'learnpress' ),
1429
+ __( 'If yes, it requires to install addon name', 'learnpress' ),
1430
+ __( 'LearnPress Import/Export', 'learnpress' ),
1431
+ __( 'but don\'t worry because it is completely automated.', 'learnpress' ),
1432
+ __( 'Import now', 'learnpress' ),
1433
+ __( 'No, thanks!', 'learnpress' )
1434
+ );
1435
+ }
1436
+ }
1437
+
1438
+ //add_action( 'admin_notices', 'learn_press_one_click_install_sample_data_notice' );
1439
+
1440
+ function learn_press_request_query( $vars = array() ) {
1441
+ global $typenow, $wp_query, $wp_post_statuses;
1442
+ if ( LP_ORDER_CPT === $typenow ) {
1443
+ // Status
1444
+ if ( !isset( $vars['post_status'] ) ) {
1445
+ $post_statuses = learn_press_get_order_statuses();
1446
+
1447
+ foreach ( $post_statuses as $status => $value ) {
1448
+ if ( isset( $wp_post_statuses[$status] ) && false === $wp_post_statuses[$status]->show_in_admin_all_list ) {
1449
+ unset( $post_statuses[$status] );
1450
+ }
1451
+ }
1452
+
1453
+ $vars['post_status'] = array_keys( $post_statuses );
1454
+
1455
+ }
1456
+ }
1457
+ return $vars;
1458
+ }
1459
+
1460
+ add_filter( 'request', 'learn_press_request_query', 0 );
1461
+
1462
+ function _learn_press_reset_course_data() {
1463
+ if ( empty( $_REQUEST['reset-course-data'] ) ) {
1464
+ return false;
1465
+ }
1466
+ learn_press_reset_course_data( intval( $_REQUEST['reset-course-data'] ) );
1467
+ wp_redirect( remove_query_arg( 'reset-course-data' ) );
1468
+ }
1469
+
1470
+ add_action( 'init', '_learn_press_reset_course_data' );
1471
+
1472
+ /***********************/
1473
+ function learn_press_admin_section_loop_item_class( $item, $section ) {
1474
+ $classes = array(
1475
+ 'lp-section-item'
1476
+ );
1477
+ $classes[] = 'lp-item-' . $item->post_type;
1478
+ if ( !absint( $item->ID ) ) {
1479
+ $classes[] = 'lp-item-empty lp-item-new focus';
1480
+ }
1481
+ $classes = apply_filters( 'learn_press_section_loop_item_class', $classes, $item, $section );
1482
+ if ( $classes ) echo 'class="' . join( ' ', $classes ) . '"';
1483
+ return $classes;
1484
+ }
1485
+
1486
+ function learn_press_disable_checked_ontop( $args ) {
1487
+
1488
+ if ( 'course_category' == $args['taxonomy'] ) {
1489
+ $args['checked_ontop'] = false;
1490
+ }
1491
+
1492
+ return $args;
1493
+ }
1494
+
1495
+ add_filter( 'wp_terms_checklist_args', 'learn_press_disable_checked_ontop' );
1496
+
1497
+ function learn_press_output_admin_template() {
1498
+ learn_press_admin_view( 'admin-template.php' );
1499
+ }
1500
+
1501
+ add_action( 'admin_print_scripts', 'learn_press_output_admin_template' );
1502
+
1503
+ function learn_press_output_screen_id() {
1504
+ $screen = get_current_screen();
1505
+ if ( $screen ) {
1506
+ echo "<div style=\"position:fixed;top: 0; left:0; z-index: 99999999; background-color:#FFF;padding:4px;\">" . $screen->id . "</div>";
1507
+ }
1508
+ }
1509
+
1510
+ //add_action( 'admin_head', 'learn_press_output_screen_id' );
1511
+
1512
+ function learn_press_get_screens() {
1513
+ $screen_id = sanitize_title( __( 'LearnPress', 'learnpress' ) );
1514
+ $screens = array(
1515
+ 'toplevel_page_' . $screen_id,
1516
+ $screen_id . '_page_learn-press-statistics',
1517
+ $screen_id . '_page_learn-press-addons',
1518
+ $screen_id . '_page_learn-press-settings',
1519
+ $screen_id . '_page_learn-press-tools'
1520
+ );
1521
+ foreach ( array( LP_COURSE_CPT, LP_LESSON_CPT, LP_QUIZ_CPT, LP_QUESTION_CPT, LP_ORDER_CPT ) as $post_type ) {
1522
+ $screens[] = 'edit-' . $post_type;
1523
+ $screens[] = $post_type;
1524
+ }
1525
+
1526
+ return apply_filters( 'learn_press_screen_ids', $screens );
1527
+ }
1528
+
1529
+ function learn_press_get_admin_pages() {
1530
+ return apply_filters(
1531
+ 'learn_press_admin_pages',
1532
+ array(
1533
+ 'learn-press-settings',
1534
+ 'learn-press-settings'
1535
+ )
1536
+ );
1537
+ }
1538
+
1539
+ function learn_press_is_post_type_screen( $post_type, $union = 'OR' ) {
1540
+ if ( is_array( $post_type ) ) {
1541
+ $return = null;
1542
+ foreach ( $post_type as $_post_type ) {
1543
+ $check = learn_press_is_post_type_screen( $_post_type );
1544
+ if ( $union == 'OR' && $check ) {
1545
+ return true;
1546
+ }
1547
+ if ( $return == null ) {
1548
+ $return = $check;
1549
+ } else {
1550
+ $return = $return && $check;
1551
+ }
1552
+ if ( $union !== 'OR' ) {
1553
+ return $return;
1554
+ }
1555
+ }
1556
+ return $return;
1557
+ }
1558
+ $screen = get_current_screen();
1559
+ if ( !$screen ) {
1560
+ return;
1561
+ }
1562
+ $screen_id = $screen->id;
1563
+ return in_array( $screen_id, array( $post_type, "edit-{$post_type}" ) );
1564
+ }
1565
+
1566
+ function learn_press_get_notice_dismiss( $context, $type = 'transient' ) {
1567
+ if ( $type == 'transient' ) {
1568
+ return get_transient( 'learn_press_dismiss_notice_' . $context );
1569
+ }
1570
+ return get_option( 'learn_press_dismiss_notice_' . $context );
1571
+ }
1572
+
1573
+ if ( !function_exists( 'learn_press_course_insert_section' ) ) {
1574
+
1575
+ function learn_press_course_insert_section( $section = array() ) {
1576
+ global $wpdb;
1577
+ $section = wp_parse_args(
1578
+ $section,
1579
+ array(
1580
+ 'section_name' => '',
1581
+ 'section_course_id' => 0,
1582
+ 'section_order' => 0,
1583
+ 'section_description' => ''
1584
+ )
1585
+ );
1586
+ $section = stripslashes_deep( $section );
1587
+ extract( $section );
1588
+
1589
+ $insert_data = compact( 'section_name', 'section_course_id', 'section_order', 'section_description' );
1590
+ $wpdb->insert(
1591
+ $wpdb->learnpress_sections,
1592
+ $insert_data,
1593
+ array( '%s', '%d', '%d' )
1594
+ );
1595
+
1596
+ return $wpdb->insert_id;
1597
+ }
1598
+
1599
+ }
1600
+
1601
+ if ( !function_exists( 'learn_press_course_insert_section_item' ) ) {
1602
+
1603
+ function learn_press_course_insert_section_item( $item_data = array() ) {
1604
+ global $wpdb;
1605
+ $wpdb->insert(
1606
+ $wpdb->learnpress_section_items,
1607
+ array(
1608
+ 'section_id' => $item_data['section_id'],
1609
+ 'item_id' => $item_data['item_id'],
1610
+ 'item_order' => $item_data['item_order'],
1611
+ 'item_type' => $item_data['item_type']
1612
+ ),
1613
+ array(
1614
+ '%d',
1615
+ '%d',
1616
+ '%d',
1617
+ '%s',
1618
+ )
1619
+ );
1620
+ return $wpdb->insert_id;
1621
+ }
1622
+
1623
+ }
1624
+
1625
+ if ( !function_exists( 'learn_press_duplicate_post' ) ) {
1626
+
1627
+ function learn_press_duplicate_post( $post_id = null, $args = array(), $meta = true ) {
1628
+ $post = get_post( $post_id );
1629
+ if ( !$post ) return;
1630
+ $defalts = array(
1631
+ 'comment_status' => $post->comment_status,
1632
+ 'ping_status' => $post->ping_status,
1633
+ 'post_author' => get_current_user_id(),
1634
+ 'post_content' => $post->post_content,
1635
+ 'post_excerpt' => $post->post_excerpt,
1636
+ 'post_parent' => $post->post_parent,
1637
+ 'post_password' => $post->post_password,
1638
+ 'post_status' => 'draft',
1639
+ 'post_title' => $post->post_title . ' - Copy',
1640
+ 'post_type' => $post->post_type,
1641
+ 'to_ping' => $post->to_ping,
1642
+ 'menu_order' => $post->menu_order
1643
+ );
1644
+ $args = wp_parse_args( $args, $defalts );
1645
+ $new_post_id = wp_insert_post( $args );
1646
+
1647
+ if ( !is_wp_error( $new_post_id ) && $meta ) {
1648
+ learn_press_duplicate_post_meta( $post_id, $new_post_id );
1649
+ // assign related tags/categories to new course
1650
+ $taxonomies = get_object_taxonomies( $post->post_type );
1651
+ foreach ( $taxonomies as $taxonomy ) {
1652
+ $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
1653
+ wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false );
1654
+ }
1655
+ }
1656
+ return apply_filters( 'learn_press_duplicate_post', $new_post_id, $post_id );
1657
+ }
1658
+ }
1659
+
1660
+ if ( !function_exists( 'learn_press_duplicate_post_meta' ) ) {
1661
+ /**
1662
+ * duplicate all post meta just in two SQL queries
1663
+ */
1664
+ function learn_press_duplicate_post_meta( $old_post_id, $new_post_id, $excerpt = array() ) {
1665
+ global $wpdb;
1666
+ $post_meta_infos = $wpdb->get_results( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$old_post_id" );
1667
+ if ( count( $post_meta_infos ) != 0 ) {
1668
+ $excerpt = array_merge( array( '_edit_lock', '_edit_last' ), $excerpt );
1669
+ $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
1670
+ $sql_query_sel = array();
1671
+ foreach ( $post_meta_infos as $meta ) {
1672
+ if ( in_array( $meta->meta_value, $excerpt ) ) {
1673
+ continue;
1674
+ }
1675
+ $meta_key = $meta->meta_key;
1676
+ $meta_value = addslashes( $meta->meta_value );
1677
+ $sql_query_sel[] = "SELECT $new_post_id, '$meta_key', '$meta_value'";
1678
+ }
1679
+ $sql_query .= implode( " UNION ALL ", $sql_query_sel );
1680
+ $wpdb->query( $sql_query );
1681
+ }
1682
+ }
1683
+
1684
+ }
1685
+
1686
+ add_filter( 'learn_press_question_types', 'learn_press_sort_questions', 99 );
1687
+ if ( !function_exists( 'learn_press_sort_questions' ) ) {
1688
+ function learn_press_sort_questions( $types ) {
1689
+ $user_id = get_current_user_id();
1690
+ $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
1691
+ if ( !empty( $question_types ) ) {
1692
+ $sort = array();
1693
+ // re-sort array descending
1694
+ arsort( $question_types );
1695
+ $new_types = array();
1696
+ $ktypes = array_keys( $types );
1697
+
1698
+ for ( $i = 0; $i < count( $ktypes ) - 1; $i ++ ) {
1699
+ $max = $i;
1700
+ if ( !isset( $question_types[$ktypes[$i]] ) ) {
1701
+ $question_types[$ktypes[$i]] = 0;
1702
+ }
1703
+ for ( $j = $i + 1; $j < count( $ktypes ); $j ++ ) {
1704
+ if ( isset( $question_types[$ktypes[$j]], $question_types[$ktypes[$max]] )
1705
+ && $question_types[$ktypes[$j]] > $question_types[$ktypes[$max]]
1706
+ ) {
1707
+ $max = $j;
1708
+ }
1709
+ }
1710
+ $tmp = $ktypes[$i];
1711
+ $ktypes[$i] = $ktypes[$max];
1712
+ $ktypes[$max] = $tmp;
1713
+ }
1714
+ $ktypes = array_flip( $ktypes );
1715
+ $types = array_merge( $ktypes, $types );
1716
+ }
1717
+ return $types;
1718
+ }
1719
+ }
1720
+
1721
+ if ( !function_exists( 'learn_press_duplicate_course' ) ) {
1722
+
1723
+ function learn_press_duplicate_course( $course_id = null, $force = true ) {
1724
+ if ( !function_exists( '_learn_press_get_course_curriculum' ) ) {
1725
+ require_once LP_PLUGIN_PATH . 'inc/lp-init.php';
1726
+ }
1727
+ global $wpdb;
1728
+
1729
+ if ( $course_id && is_array( $course_id ) ) {
1730
+ $course_id = array_shift( $course_id );
1731
+ }
1732
+ // check for post is exists
1733
+ if ( !$course_id || !( $post = get_post( $course_id ) ) ) {
1734
+ return new WP_Error( __( '<p>Op! The course does not exist</p>', 'learnpress' ) );
1735
+ } else {
1736
+ // ensure that user can create course
1737
+ if ( !current_user_can( 'edit_posts' ) ) {
1738
+ return new WP_Error( __( '<p>Sorry! You have not permission to duplicate this course</p>', 'learnpress' ) );
1739
+ } else {
1740
+ // duplicate course
1741
+ $new_course_id = learn_press_duplicate_post( $course_id );
1742
+ if ( !$new_course_id || is_wp_error( $new_course_id ) ) {
1743
+ return new WP_Error( __( '<p>Sorry! Duplicate course failed!</p>', 'learnpress' ) );
1744
+ } else {
1745
+ $curriculums = _learn_press_get_course_curriculum( $course_id );
1746
+ foreach ( $curriculums as $section_id => $section ) {
1747
+ $new_section_id = learn_press_course_insert_section( array(
1748
+ 'section_name' => $section->section_name,
1749
+ 'section_course_id' => $new_course_id,
1750
+ 'section_order' => $section->section_order,
1751
+ 'section_description' => $section->section_description
1752
+ ) );
1753
+
1754
+ if ( $section->items ) {
1755
+ foreach ( $section->items as $item ) {
1756
+ // duplicate item
1757
+ if ( $force && $item->post_type === LP_QUIZ_CPT ) {
1758
+ $item_id = learn_press_duplicate_quiz( $item->ID, array( 'post_status' => 'publish' ) );
1759
+ } else {
1760
+ $item_id = learn_press_duplicate_post( $item->ID, array( 'post_status' => 'publish' ) );
1761
+ }
1762
+ if ( $force ) {
1763
+ $section_item_id = learn_press_course_insert_section_item( array(
1764
+ 'section_id' => $new_section_id,
1765
+ 'item_id' => $item_id,
1766
+ 'item_order' => $item->item_order,
1767
+ 'item_type' => $item->item_type
1768
+ ) );
1769
+ }
1770
+ }
1771
+ }
1772
+ }
1773
+ return $new_course_id;
1774
+ }
1775
+ }
1776
+ }
1777
+ }
1778
+
1779
+ }
1780
+
1781
+ if ( !function_exists( 'learn_press_duplicate_question' ) ) {
1782
+
1783
+ function learn_press_duplicate_question( $question_id = null, $quiz_id = null ) {
1784
+ if ( !$question_id || !get_post( $question_id ) ) {
1785
+ return new WP_Error( sprintf( __( 'Question id %s is not exists.', 'learnpress' ), $question_id ) );
1786
+ }
1787
+ if ( $quiz_id && !get_post( $quiz_id ) ) {
1788
+ return new WP_Error( sprintf( __( 'Quiz id %s is not exists.', 'learnpress' ), $quiz_id ) );
1789
+ }
1790
+
1791
+ global $wpdb;
1792
+ $new_question_id = learn_press_duplicate_post( $question_id );
1793
+ if ( $quiz_id ) {
1794
+ // learnpress_quiz_questions
1795
+ $sql = $wpdb->prepare( "
1796
+ SELECT * FROM $wpdb->learnpress_quiz_questions WHERE quiz_id = %d AND question_id = %d
1797
+ ", $quiz_id, $question_id );
1798
+ $quiz_question_data = $wpdb->get_row( $sql );
1799
+ $max_order = $wpdb->get_var( $wpdb->prepare( "SELECT max(question_order) FROM {$wpdb->prefix}learnpress_quiz_questions WHERE quiz_id = %d", $quiz_id ) );
1800
+
1801
+ if ( $quiz_question_data ) {
1802
+ $wpdb->insert(
1803
+ $wpdb->learnpress_quiz_questions,
1804
+ array(
1805
+ 'quiz_id' => $quiz_id,
1806
+ 'question_id' => $new_question_id,
1807
+ 'question_order' => $max_order + 1,
1808
+ 'params' => $quiz_question_data->params
1809
+ ),
1810
+ array(
1811
+ '%d',
1812
+ '%d',
1813
+ '%d',
1814
+ '%s'
1815
+ )
1816
+ );
1817
+ }
1818
+ }
1819
+ // learnpress_question_answers
1820
+ $sql = $wpdb->prepare( "
1821
+ SELECT * FROM $wpdb->learnpress_question_answers WHERE question_id = %d
1822
+ ", $question_id );
1823
+ $question_answers = $wpdb->get_results( $sql );
1824
+ if ( $question_answers ) {
1825
+ foreach ( $question_answers as $q_a ) {
1826
+ $wpdb->insert(
1827
+ $wpdb->learnpress_question_answers,
1828
+ array(
1829
+ 'question_id' => $new_question_id,
1830
+ 'answer_data' => $q_a->answer_data,
1831
+ 'answer_order' => $q_a->answer_order
1832
+ ),
1833
+ array(
1834
+ '%d',
1835
+ '%s',
1836
+ '%s'
1837
+ )
1838
+ );
1839
+ }
1840
+ }
1841
+
1842
+ return $new_question_id;
1843
+ }
1844
+
1845
+ }
1846
+
1847
+ if ( !function_exists( 'learn_press_duplicate_quiz' ) ) {
1848
+
1849
+ function learn_press_duplicate_quiz( $quiz_id = null, $args = array() ) {
1850
+ global $wpdb;
1851
+ $new_quiz_id = learn_press_duplicate_post( $quiz_id, $args, true );
1852
+ $quiz = LP_Quiz::get_quiz( $quiz_id );
1853
+ $questions = $quiz->get_questions();
1854
+ if ( $questions ) {
1855
+ $questions = array_keys( $questions );
1856
+ foreach ( $questions as $question_id ) {
1857
+ $new_question_id = learn_press_duplicate_post( $question_id );
1858
+ // learnpress_quiz_questions
1859
+ $sql = $wpdb->prepare( "
1860
+ SELECT * FROM $wpdb->learnpress_quiz_questions WHERE quiz_id = %d AND question_id = %d
1861
+ ", $quiz_id, $question_id );
1862
+ $quiz_question_data = $wpdb->get_row( $sql );
1863
+ if ( $quiz_question_data ) {
1864
+ $wpdb->insert(
1865
+ $wpdb->learnpress_quiz_questions,
1866
+ array(
1867
+ 'quiz_id' => $new_quiz_id,
1868
+ 'question_id' => $new_question_id,
1869
+ 'question_order' => $quiz_question_data->question_order,
1870
+ 'params' => $quiz_question_data->params
1871
+ ),
1872
+ array(
1873
+ '%d',
1874
+ '%d',
1875
+ '%d',
1876
+ '%s'
1877
+ )
1878
+ );
1879
+ }
1880
+ // learnpress_question_answers
1881
+ $sql = $wpdb->prepare( "
1882
+ SELECT * FROM $wpdb->learnpress_question_answers WHERE question_id = %d
1883
+ ", $question_id );
1884
+ $question_answers = $wpdb->get_results( $sql );
1885
+ if ( $question_answers ) {
1886
+ foreach ( $question_answers as $q_a ) {
1887
+ $wpdb->insert(
1888
+ $wpdb->learnpress_question_answers,
1889
+ array(
1890
+ 'question_id' => $new_question_id,
1891
+ 'answer_data' => $q_a->answer_data,
1892
+ 'answer_order' => $q_a->answer_order
1893
+ ),
1894
+ array(
1895
+ '%d',
1896
+ '%s',
1897
+ '%s'
1898
+ )
1899
+ );
1900
+ }
1901
+ }
1902
+ }
1903
+ }
1904
+
1905
+ return $new_quiz_id;
1906
+ }
1907
+
1908
+ }
1909
+
1910
+ /**
1911
+ * Get number version of a template file
1912
+ *
1913
+ * @param $file
1914
+ *
1915
+ * @return string
1916
+ */
1917
+ function learn_press_get_file_version( $file ) {
1918
+ if ( !file_exists( $file ) ) {
1919
+ return '';
1920
+ }
1921
+ $fp = fopen( $file, 'r' );
1922
+ $file_data = fread( $fp, 8192 );
1923
+ fclose( $fp );
1924
+ $file_data = str_replace( "\r", "\n", $file_data );
1925
+ $version = '';
1926
+ if ( preg_match( '/^[ \t\/*#@]*' . preg_quote( '@version', '/' ) . '(.*)$/mi', $file_data, $match ) && $match[1] )
1927
+ $version = _cleanup_header_comment( $match[1] );
1928
+ return $version;
1929
+ }
1930
+
1931
+ /**
1932
+ * Get list of template files are overwritten in the theme
1933
+ *
1934
+ * @param bool $check
1935
+ *
1936
+ * @return array|bool
1937
+ */
1938
+ function learn_press_get_theme_templates( $check = false ) {
1939
+ $template_folder = learn_press_template_path();
1940
+ $template_path = LP_PLUGIN_PATH . '/templates/';
1941
+ $template_dir = get_template_directory();
1942
+ $stylesheet_dir = get_stylesheet_directory();
1943
+ $t_folder = basename( $template_dir );
1944
+ $s_folder = basename( $stylesheet_dir );
1945
+
1946
+ $found_files = array( $t_folder => array(), $s_folder => array() );
1947
+ $outdated_templates = false;
1948
+
1949
+ $scanned_files = learn_press_scan_template_files( $template_path );
1950
+ foreach ( $scanned_files as $file ) {
1951
+ $theme_folder = '';
1952
+
1953
+ if ( file_exists( $stylesheet_dir . '/' . $file ) ) {
1954
+ $theme_file = $stylesheet_dir . '/' . $file;
1955
+ $theme_folder = $s_folder;
1956
+ } elseif ( file_exists( $stylesheet_dir . '/' . $template_folder . '/' . $file ) ) {
1957
+ $theme_file = $stylesheet_dir . '/' . $template_folder . '/' . $file;
1958
+ $theme_folder = $s_folder;
1959
+ } elseif ( file_exists( $template_dir . '/' . $file ) ) {
1960
+ $theme_file = $template_dir . '/' . $file;
1961
+ $theme_folder = $t_folder;
1962
+ } elseif ( file_exists( $template_dir . '/' . $template_folder . '/' . $file ) ) {
1963
+ $theme_file = $template_dir . '/' . $template_folder . '/' . $file;
1964
+ $theme_folder = $t_folder;
1965
+ } else {
1966
+ $theme_file = false;
1967
+ }
1968
+
1969
+ if ( !empty( $theme_file ) ) {
1970
+ $core_version = learn_press_get_file_version( $template_path . $file );
1971
+ $theme_version = learn_press_get_file_version( $theme_file );
1972
+
1973
+ if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) {
1974
+ if ( !$outdated_templates ) {
1975
+ $outdated_templates = true;
1976
+ }
1977
+ $found_files[$theme_folder][] = array(
1978
+ str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ),
1979
+ $theme_version ? $theme_version : '-',
1980
+ $core_version,
1981
+ true
1982
+ );
1983
+ } else {
1984
+ $found_files[$theme_folder][] = array(
1985
+ str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ),
1986
+ $theme_version ? $theme_version : '?',
1987
+ $core_version ? $core_version : '?',
1988
+ null
1989
+ );
1990
+ }
1991
+ }
1992
+ if ( $check && $outdated_templates ) {
1993
+ return $outdated_templates;
1994
+ }
1995
+ }
1996
+ if ( sizeof( $found_files ) > 1 ) {
1997
+ $found_files = array_merge( $found_files[$t_folder], $found_files[$s_folder] );
1998
+ } else {
1999
+ $found_files = reset( $found_files );
2000
+ }
2001
+ return $check ? $outdated_templates : $found_files;
2002
+ }
2003
+
2004
+ function learn_press_scan_template_files( $template_path ) {
2005
+
2006
+ $files = @scandir( $template_path );
2007
+ $result = array();
2008
+
2009
+ if ( !empty( $files ) ) {
2010
+ foreach ( $files as $key => $value ) {
2011
+ if ( !in_array( $value, array( ".", "..", 'index.php', 'index.html' ) ) ) {
2012
+ if ( is_dir( $template_path . '/' . $value ) ) {
2013
+ $sub_files = learn_press_scan_template_files( $template_path . '/' . $value );
2014
+ foreach ( $sub_files as $sub_file ) {
2015
+ $result[] = $value . '/' . $sub_file;
2016
+ }
2017
+ } else {
2018
+ $result[] = $value;
2019
+ }
2020
+ }
2021
+ }
2022
+ }
2023
+ return $result;
2024
+ }
2025
+
2026
+ if ( !function_exists( 'learn_press_duplicate_lesson' ) ) {
2027
+
2028
+ function learn_press_duplicate_lesson( $lesson_id = null ) {
2029
+ return learn_press_duplicate_post( $lesson_id );
2030
+ }
2031
+
2032
+ }
inc/admin/meta-boxes/class-quiz-questions-field.php CHANGED
@@ -1,201 +1,194 @@
1
- <?php
2
-
3
- // Prevent loading this file directly
4
- defined( 'ABSPATH' ) || exit;
5
- /**
6
- * Class RWMB_Quiz_Questions_Field
7
- *
8
- * @author ThimPress
9
- * @package LearnPress/Classes
10
- * @version 1.0
11
- * @extend RWMB_Field
12
- */
13
- if ( !class_exists( 'RWMB_Quiz_Questions_Field' ) ) {
14
-
15
- class RWMB_Quiz_Questions_Field extends RWMB_Field {
16
- /**
17
- * Construct
18
- */
19
- public function __construct() {
20
-
21
- }
22
-
23
- public static function admin_enqueue_scripts() {
24
- /*$q = new LP_Question();
25
- $q->admin_script();*/
26
- LP_Assets::enqueue_style( 'select2', RWMB_CSS_URL . 'select2/select2.css' );
27
- LP_Assets::enqueue_script( 'select2', RWMB_JS_URL . 'select2/select2.min.js' );
28
- LP_Assets::enqueue_script( 'learn-press-mb-quiz' );
29
- LP_Assets::enqueue_script( 'learn-press-modal-search-items' );
30
-
31
- }
32
-
33
- public static function add_actions() {
34
- // Do same actions as file field
35
- parent::add_actions();
36
-
37
- add_action( 'wp_ajax_lpr_quiz_question_add', array( __CLASS__, 'quiz_question_add' ) );
38
- add_action( 'wp_ajax_lpr_quiz_question_remove', array( __CLASS__, 'quiz_question_remove' ) );
39
- add_filter('learn_press_question_top_buttons', array(__CLASS__, 'filter_question_top_buttons'),10,3);
40
- }
41
-
42
- public static function filter_question_top_buttons( $buttons, $question ) {
43
- $buttons['duration'] = learn_press_field_question_duration(array(), $question);
44
- return $buttons;
45
- }
46
-
47
- public static function quiz_question_remove() {
48
- $question_id = isset( $_REQUEST['question_id'] ) ? $_REQUEST['question_id'] : null;
49
- $quiz_id = isset( $_REQUEST['quiz_id'] ) ? $_REQUEST['quiz_id'] : null;
50
-
51
- $questions = get_post_meta( $quiz_id, '_lpr_quiz_questions', true );
52
- if ( isset( $questions[$question_id] ) ) {
53
- unset( $questions[$question_id] );
54
- update_post_meta( $quiz_id, '_lpr_quiz_questions', $questions );
55
- }
56
- die();
57
- }
58
-
59
- public static function quiz_question_add() {
60
- $type = isset( $_REQUEST['type'] ) ? $_REQUEST['type'] : null;
61
- $text = isset( $_REQUEST['text'] ) ? $_REQUEST['text'] : null;
62
- $question_id = isset( $_REQUEST['question_id'] ) ? $_REQUEST['question_id'] : null;
63
- $question = LP_Question::instance( $question_id ? $question_id : $type );
64
- $json = array(
65
- 'success' => false
66
- );
67
- if ( $question ) {
68
- if ( !$question_id ) {
69
- $question->set( 'post_title', $text ? $text : 'Your question text here' );
70
- $question->set( 'post_type', LP_QUESTION_CPT );
71
- $question->set( 'post_status', 'publish' );
72
- }
73
-
74
-
75
- if ( ( $question_id = $question->store() ) && isset( $_POST['quiz_id'] ) && ( $quiz_id = $_POST['quiz_id'] ) ) {
76
- $quiz_questions = (array) get_post_meta( $quiz_id, '_lpr_quiz_questions', true );
77
- $quiz_questions[$question_id] = array( 'toggle' => 0 );
78
- update_post_meta( $quiz_id, '_lpr_quiz_questions', $quiz_questions );
79
- }
80
- ob_start();
81
- $question->admin_interface();
82
- $json['html'] = ob_get_clean();
83
- $json['success'] = true;
84
- $json['question'] = get_post( $question_id );
85
- } else {
86
- $json['msg'] = __( 'Can not create a question', 'learnpress' );
87
- }
88
- wp_send_json( $json );
89
- die();
90
- }
91
-
92
- public static function save_quiz_questions( $post_id ) {
93
- learn_press_debug($_POST);
94
- die();
95
- static $has_updated;
96
- $questions = isset( $_POST[LP_QUESTION_CPT] ) ? $_POST[LP_QUESTION_CPT] : null;
97
- if ( !$questions ) return;
98
- $postmeta = array();
99
-
100
- // prevent infinite loop with save_post action
101
- if ( $has_updated ) return;
102
- $has_updated = true;
103
-
104
- foreach ( $questions as $question_id => $options ) {
105
- $question = LP_Question::instance( $question_id );
106
- if ( $question ) {
107
- $question_id = $question->save_post_action();
108
- if ( $question_id ) {
109
- $postmeta[$question_id] = array( 'toggle' => $options['toggle'] );
110
- if ( !empty( $options['type'] ) ) {
111
- $post_data = get_post_meta( $question_id, '_lpr_question', true );
112
- $post_data['type'] = $options['type'];
113
- update_post_meta( $question_id, '_lpr_question', $post_data );
114
- }
115
- }
116
- }
117
- }
118
-
119
- update_post_meta( $post_id, '_lpr_quiz_questions', $postmeta );
120
- }
121
-
122
- public static function html( $meta, $field ) {
123
- ob_start();
124
- $view = learn_press_get_admin_view( 'meta-boxes/quiz/questions.php' );
125
- include $view;
126
- return ob_get_clean();
127
- }
128
-
129
- public static function save( $new, $old, $post_id, $field ) {
130
- global $wpdb, $post;
131
- //LP_Debug::instance()->add( __CLASS__ . '::' . __FUNCTION__ . '(' . join( ',', func_get_args() ) . ')' );
132
- $questions = learn_press_get_request( 'learn_press_question' );
133
- /*if( $all_questions = LP_Quiz::get_quiz( $post->ID )->get_questions() ){
134
- $all_questions = array_keys( $all_questions );
135
- }*/
136
- // Get all ids of questions stored
137
- $remove_ids = $wpdb->get_col(
138
- $wpdb->prepare("
139
- SELECT question_id
140
- FROM {$wpdb->prefix}learnpress_quiz_questions
141
- WHERE quiz_id = %d
142
- ", $post->ID )
143
- );
144
-
145
- // delete all questions stored
146
- $query = $wpdb->prepare("
147
- DELETE
148
- FROM {$wpdb->prefix}learnpress_quiz_questions
149
- WHERE quiz_id = %d
150
- ", $post->ID, 1 );
151
- $wpdb->query( $query );
152
- learn_press_reset_auto_increment( 'learnpress_quiz_questions' );
153
- do_action( 'learn_press_remove_quiz_questions', $remove_ids, $post->ID );
154
- if( ! $questions ){
155
- return;
156
- }
157
- $titles = learn_press_get_request( 'learn-press-question-name' );
158
- $values = array();
159
- $order = 1;
160
-
161
- // update the title of questions and save all data
162
- foreach( $questions as $id => $data ){
163
- $question = LP_Question_Factory::get_question($id );
164
- if( ! empty( $titles[ $id ] ) ){
165
- $wpdb->update(
166
- $wpdb->posts,
167
- array(
168
- 'post_title' => stripslashes( $titles[ $id ] )
169
- ),
170
- array(
171
- 'ID' => $id
172
- ),
173
- array( '%s' )
174
- );
175
- }
176
- $question->save( $data );
177
-
178
-
179
- $insert_data = apply_filters(
180
- 'learn_press_quiz_question_insert_data',
181
- array(
182
- 'question_id' => $id,
183
- 'quiz_id' => $post->ID,
184
- 'params' => ''
185
- )
186
- );
187
- $values[] = $wpdb->prepare( "(%d, %d, %s, %d)", $insert_data['quiz_id'], $insert_data['question_id'], isset( $insert_data['param'] ) ? $insert_data['param'] : '', $order++ );
188
- update_post_meta($id, '_question_duration', $data['duration']);
189
- }
190
-
191
- $query = "
192
- INSERT INTO {$wpdb->learnpress_quiz_questions}(`quiz_id`, `question_id`, `params`, `question_order`)
193
- VALUES " . join(',', $values) . "
194
- ";
195
- $wpdb->query( $query );
196
- do_action( 'learn_press_insert_quiz_questions', $questions, $post->ID );
197
- }
198
- }
199
-
200
- //add_action( 'save_post', array( 'RWMB_Quiz_Questions_Field', 'save_quiz_questions' ), 1000000 );
201
  }
1
+ <?php
2
+
3
+ // Prevent loading this file directly
4
+ defined( 'ABSPATH' ) || exit;
5
+ /**
6
+ * Class RWMB_Quiz_Questions_Field
7
+ *
8
+ * @author ThimPress
9
+ * @package LearnPress/Classes
10
+ * @version 1.0
11
+ * @extend RWMB_Field
12
+ */
13
+ if ( !class_exists( 'RWMB_Quiz_Questions_Field' ) ) {
14
+
15
+ class RWMB_Quiz_Questions_Field extends RWMB_Field {
16
+ /**
17
+ * Construct
18
+ */
19
+ public function __construct() {
20
+
21
+ }
22
+
23
+ public static function admin_enqueue_scripts() {
24
+ /*$q = new LP_Question();
25
+ $q->admin_script();*/
26
+ LP_Assets::enqueue_style( 'select2', RWMB_CSS_URL . 'select2/select2.css' );
27
+ LP_Assets::enqueue_script( 'select2', RWMB_JS_URL . 'select2/select2.min.js' );
28
+ LP_Assets::enqueue_script( 'learn-press-mb-quiz' );
29
+ LP_Assets::enqueue_script( 'learn-press-modal-search-items' );
30
+
31
+ }
32
+
33
+ public static function add_actions() {
34
+ // Do same actions as file field
35
+ parent::add_actions();
36
+
37
+ add_action( 'wp_ajax_lpr_quiz_question_add', array( __CLASS__, 'quiz_question_add' ) );
38
+ add_action( 'wp_ajax_lpr_quiz_question_remove', array( __CLASS__, 'quiz_question_remove' ) );
39
+ }
40
+
41
+ public static function quiz_question_remove() {
42
+ $question_id = isset( $_REQUEST['question_id'] ) ? $_REQUEST['question_id'] : null;
43
+ $quiz_id = isset( $_REQUEST['quiz_id'] ) ? $_REQUEST['quiz_id'] : null;
44
+
45
+ $questions = get_post_meta( $quiz_id, '_lpr_quiz_questions', true );
46
+ if ( isset( $questions[$question_id] ) ) {
47
+ unset( $questions[$question_id] );
48
+ update_post_meta( $quiz_id, '_lpr_quiz_questions', $questions );
49
+ }
50
+ die();
51
+ }
52
+
53
+ public static function quiz_question_add() {
54
+ $type = isset( $_REQUEST['type'] ) ? $_REQUEST['type'] : null;
55
+ $text = isset( $_REQUEST['text'] ) ? $_REQUEST['text'] : null;
56
+ $question_id = isset( $_REQUEST['question_id'] ) ? $_REQUEST['question_id'] : null;
57
+ $question = LP_Question::instance( $question_id ? $question_id : $type );
58
+ $json = array(
59
+ 'success' => false
60
+ );
61
+ if ( $question ) {
62
+ if ( !$question_id ) {
63
+ $question->set( 'post_title', $text ? $text : 'Your question text here' );
64
+ $question->set( 'post_type', LP_QUESTION_CPT );
65
+ $question->set( 'post_status', 'publish' );
66
+ }
67
+
68
+
69
+ if ( ( $question_id = $question->store() ) && isset( $_POST['quiz_id'] ) && ( $quiz_id = $_POST['quiz_id'] ) ) {
70
+ $quiz_questions = (array) get_post_meta( $quiz_id, '_lpr_quiz_questions', true );
71
+ $quiz_questions[$question_id] = array( 'toggle' => 0 );
72
+ update_post_meta( $quiz_id, '_lpr_quiz_questions', $quiz_questions );
73
+ }
74
+ ob_start();
75
+ $question->admin_interface();
76
+ $json['html'] = ob_get_clean();
77
+ $json['success'] = true;
78
+ $json['question'] = get_post( $question_id );
79
+ } else {
80
+ $json['msg'] = __( 'Can not create a question', 'learnpress' );
81
+ }
82
+ wp_send_json( $json );
83
+ die();
84
+ }
85
+
86
+ public static function save_quiz_questions( $post_id ) {
87
+ learn_press_debug($_POST);
88
+ die();
89
+ static $has_updated;
90
+ $questions = isset( $_POST[LP_QUESTION_CPT] ) ? $_POST[LP_QUESTION_CPT] : null;
91
+ if ( !$questions ) return;
92
+ $postmeta = array();
93
+
94
+ // prevent infinite loop with save_post action
95
+ if ( $has_updated ) return;
96
+ $has_updated = true;
97
+
98
+ foreach ( $questions as $question_id => $options ) {
99
+ $question = LP_Question::instance( $question_id );
100
+ if ( $question ) {
101
+ $question_id = $question->save_post_action();
102
+ if ( $question_id ) {
103
+ $postmeta[$question_id] = array( 'toggle' => $options['toggle'] );
104
+ if ( !empty( $options['type'] ) ) {
105
+ $post_data = get_post_meta( $question_id, '_lpr_question', true );
106
+ $post_data['type'] = $options['type'];
107
+ update_post_meta( $question_id, '_lpr_question', $post_data );
108
+ }
109
+ }
110
+ }
111
+ }
112
+
113
+ update_post_meta( $post_id, '_lpr_quiz_questions', $postmeta );
114
+ }
115
+
116
+ public static function html( $meta, $field ) {
117
+ ob_start();
118
+ $view = learn_press_get_admin_view( 'meta-boxes/quiz/questions.php' );
119
+ include $view;
120
+ return ob_get_clean();
121
+ }
122
+
123
+ public static function save( $new, $old, $post_id, $field ) {
124
+ global $wpdb, $post;
125
+ //LP_Debug::instance()->add( __CLASS__ . '::' . __FUNCTION__ . '(' . join( ',', func_get_args() ) . ')' );
126
+ $questions = learn_press_get_request( 'learn_press_question' );
127
+ /*if( $all_questions = LP_Quiz::get_quiz( $post->ID )->get_questions() ){
128
+ $all_questions = array_keys( $all_questions );
129
+ }*/
130
+ // Get all ids of questions stored
131
+ $remove_ids = $wpdb->get_col(
132
+ $wpdb->prepare("
133
+ SELECT question_id
134
+ FROM {$wpdb->prefix}learnpress_quiz_questions
135
+ WHERE quiz_id = %d
136
+ ", $post->ID )
137
+ );
138
+
139
+ // delete all questions stored
140
+ $query = $wpdb->prepare("
141
+ DELETE
142
+ FROM {$wpdb->prefix}learnpress_quiz_questions
143
+ WHERE quiz_id = %d
144
+ ", $post->ID, 1 );
145
+ $wpdb->query( $query );
146
+ learn_press_reset_auto_increment( 'learnpress_quiz_questions' );
147
+ do_action( 'learn_press_remove_quiz_questions', $remove_ids, $post->ID );
148
+ if( ! $questions ){
149
+ return;
150
+ }
151
+ $titles = learn_press_get_request( 'learn-press-question-name' );
152
+ $values = array();
153
+ $order = 1;
154
+
155
+ // update the title of questions and save all data
156
+ foreach( $questions as $id => $data ){
157
+ $question = LP_Question_Factory::get_question($id );
158
+ if( ! empty( $titles[ $id ] ) ){
159
+ $wpdb->update(
160
+ $wpdb->posts,
161
+ array(
162
+ 'post_title' => stripslashes( $titles[ $id ] )
163
+ ),
164
+ array(
165
+ 'ID' => $id
166
+ ),
167
+ array( '%s' )
168
+ );
169
+ }
170
+ $question->save( $data );
171
+
172
+
173
+ $insert_data = apply_filters(
174
+ 'learn_press_quiz_question_insert_data',
175
+ array(
176
+ 'question_id' => $id,
177
+ 'quiz_id' => $post->ID,
178
+ 'params' => ''
179
+ )
180
+ );
181
+ $values[] = $wpdb->prepare( "(%d, %d, %s, %d)", $insert_data['quiz_id'], $insert_data['question_id'], isset( $insert_data['param'] ) ? $insert_data['param'] : '', $order++ );
182
+ }
183
+
184
+ $query = "
185
+ INSERT INTO {$wpdb->learnpress_quiz_questions}(`quiz_id`, `question_id`, `params`, `question_order`)
186
+ VALUES " . join(',', $values) . "
187
+ ";
188
+ $wpdb->query( $query );
189
+ do_action( 'learn_press_insert_quiz_questions', $questions, $post->ID );
190
+ }
191
+ }
192
+
193
+ //add_action( 'save_post', array( 'RWMB_Quiz_Questions_Field', 'save_quiz_questions' ), 1000000 );
 
 
 
 
 
 
 
194
  }
inc/admin/settings/class-lp-settings-checkout.php CHANGED
@@ -1,88 +1,81 @@
1
- <?php
2
-
3
- /**
4
- * Class LP_Settings_Checkout
5
- *
6
- * @author ThimPress
7
- * @package LearnPress/Admin/Classes/Settings
8
- * @version 1.0
9
- */
10
-
11
- if ( !defined( 'ABSPATH' ) ) {
12
- exit; // Exit if accessed directly
13
- }
14
-
15
- class LP_Settings_Checkout extends LP_Settings_Base {
16
-
17
- /**
18
- * Constructor
19
- */
20
- public function __construct() {
21
- $this->id = 'checkout';
22
- $this->text = __( 'Checkout', 'learnpress' );
23
-
24
- parent::__construct();
25
- }
26
-
27
- /**
28
- * Tab's sections
29
- *
30
- * @return mixed
31
- */
32
- public function get_sections() {
33
- $sections = array(
34
- 'general' => array(
35
- 'id' => 'general',
36
- 'title' => __( 'General', 'learnpress' )
37
- )
38
- );
39
- return $sections = apply_filters( 'learn_press_settings_sections_' . $this->id, $sections );
40
- }
41
-
42
- public function output_section_general() {
43
- $view = learn_press_get_admin_view( 'settings/checkout.php' );
44
- include_once $view;
45
- }
46
-
47
- public function get_settings() {
48
- return apply_filters(
49
- 'learn_press_checkout_settings',
50
- array(
51
- array(
52
- 'title' => __( 'No checkout Free course', 'learnpress' ),
53
- 'desc' => __( 'Check this option to allow user to enroll course immediately without adding to cart.', 'learnpress' ),
54
- 'id' => $this->get_field_name( 'no_checkout_free_course' ),
55
- 'default' => 'yes',
56
- 'type' => 'checkbox'
57
- ),
58
- array(
59
- 'title' => __( 'Disable auto enroll', 'learnpress' ),
60
- 'desc' => __( 'Disable auto enroll a user after they buy a course.', 'learnpress' ),
61
- 'id' => $this->get_field_name( 'disable_auto_enroll' ),
62
- 'default' => 'no',
63
- 'type' => 'checkbox'
64
- ),
65
- array(
66
- 'title' => __( 'Checkout page', 'learnpress' ),
67
- 'id' => $this->get_field_name( 'checkout_page_id' ),
68
- 'default' => '',
69
- 'type' => 'pages-dropdown'
70
- ),
71
- array(
72
- 'title' => __( 'Checkout Endpoints', 'learnpress' ),
73
- 'type' => 'title'
74
- ),
75
- array(
76
- 'title' => __( 'Order received', 'learnpress' ),
77
- 'id' => $this->get_field_name( 'checkout_endpoints[lp_order_received]' ),
78
- 'default' => 'lp-order-received',
79
- 'type' => 'text'
80
- ),
81
- ),
82
- $this
83
- );
84
- }
85
- }
86
-
87
- //
88
  return new LP_Settings_Checkout();
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Settings_Checkout
5
+ *
6
+ * @author ThimPress
7
+ * @package LearnPress/Admin/Classes/Settings
8
+ * @version 1.0
9
+ */
10
+
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit; // Exit if accessed directly
13
+ }
14
+
15
+ class LP_Settings_Checkout extends LP_Settings_Base {
16
+
17
+ /**
18
+ * Constructor
19
+ */
20
+ public function __construct() {
21
+ $this->id = 'checkout';
22
+ $this->text = __( 'Checkout', 'learnpress' );
23
+
24
+ parent::__construct();
25
+ }
26
+
27
+ /**
28
+ * Tab's sections
29
+ *
30
+ * @return mixed
31
+ */
32
+ public function get_sections() {
33
+ $sections = array(
34
+ 'general' => array(
35
+ 'id' => 'general',
36
+ 'title' => __( 'General', 'learnpress' )
37
+ )
38
+ );
39
+ return $sections = apply_filters( 'learn_press_settings_sections_' . $this->id, $sections );
40
+ }
41
+
42
+ public function output_section_general() {
43
+ $view = learn_press_get_admin_view( 'settings/checkout.php' );
44
+ include_once $view;
45
+ }
46
+
47
+ public function get_settings() {
48
+ return apply_filters(
49
+ 'learn_press_checkout_settings',
50
+ array(
51
+ array(
52
+ 'title' => __( 'Auto enroll', 'learnpress' ),
53
+ 'desc' => __( 'Auto enroll a user after they buy a course.', 'learnpress' ),
54
+ 'id' => $this->get_field_name( 'auto_enroll' ),
55
+ 'default' => 'yes',
56
+ 'type' => 'checkbox'
57
+ ),
58
+ array(
59
+ 'title' => __( 'Checkout page', 'learnpress' ),
60
+ 'id' => $this->get_field_name( 'checkout_page_id' ),
61
+ 'default' => '',
62
+ 'type' => 'pages-dropdown'
63
+ ),
64
+ array(
65
+ 'title' => __( 'Checkout Endpoints', 'learnpress' ),
66
+ 'type' => 'title'
67
+ ),
68
+ array(
69
+ 'title' => __( 'Order received', 'learnpress' ),
70
+ 'id' => $this->get_field_name( 'checkout_endpoints[lp_order_received]' ),
71
+ 'default' => 'lp-order-received',
72
+ 'type' => 'text'
73
+ ),
74
+ ),
75
+ $this
76
+ );
77
+ }
78
+ }
79
+
80
+ //
 
 
 
 
 
 
 
81
  return new LP_Settings_Checkout();
inc/admin/settings/class-lp-settings-general.php CHANGED
@@ -1,132 +1,125 @@
1
- <?php
2
-
3
- /**
4
- * Class LP_Settings_General
5
- *
6
- * @author ThimPress
7
- * @package LearnPress/Admin/Settings/Classes
8
- * @version 1.0
9
- */
10
- class LP_Settings_General extends LP_Settings_Base {
11
- /**
12
- * Construct
13
- */
14
- public function __construct() {
15
- $this->id = 'general';
16
- $this->text = __( 'General', 'learnpress' );
17
- //add_action( 'learn_press_settings_general', array( $this, 'output' ) );
18
- //add_action( 'learn_press_settings_save_general', array( $this, 'save' ) );
19
- parent::__construct();
20
- }
21
-
22
- public function output() {
23
- $view = learn_press_get_admin_view( 'settings/general.php' );
24
- include_once $view;
25
- }
26
-
27
- public function get_settings() {
28
- return apply_filters(
29
- 'learn_press_general_settings',
30
- array(
31
- array(
32
- 'title' => __( 'Instructors registration', 'learnpress' ),
33
- 'desc' => __( 'Create option for instructors registration.', 'learnpress' ),
34
- 'id' => $this->get_field_name( 'instructor_registration' ),
35
- 'default' => 'no',
36
- 'type' => 'checkbox'
37
- ),
38
- array(
39
- 'title' => __( 'Auto update post name', 'learnpress' ),
40
- 'desc' => __( 'The post\'s name will update along with the title when changes title of lesson or quiz in course curriculum or question in quiz<br />The permalink also is changed, therefore uncheck this if you don\'t want to change the permalink', 'learnpress' ),
41
- 'id' => $this->get_field_name( 'auto_update_post_name' ),
42
- 'default' => 'no',
43
- 'type' => 'checkbox'
44
- ),
45
- array(
46
- 'title' => __( 'Currency', 'learnpress' ),
47
- 'id' => $this->get_field_name( 'currency' ),
48
- 'default' => 'USD',
49
- 'type' => 'select',
50
- 'options' => $this->_get_currency_options()
51
- ),
52
- array(
53
- 'title' => __( 'Currency position', 'learnpress' ),
54
- 'id' => $this->get_field_name( 'currency_pos' ),
55
- 'default' => 'left',
56
- 'type' => 'select',
57
- 'options' => $this->_get_currency_positions()
58
- ),
59
- array(
60
- 'title' => __( 'Thousands Separator', 'learnpress' ),
61
- 'id' => $this->get_field_name( 'thousands_separator' ),
62
- 'default' => ',',
63
- 'type' => 'text',
64
- 'options' => $this->_get_currency_positions()
65
- ),
66
- array(
67
- 'title' => __( 'Decimals Separator', 'learnpress' ),
68
- 'id' => $this->get_field_name( 'decimals_separator' ),
69
- 'default' => '.',
70
- 'type' => 'text',
71
- 'options' => $this->_get_currency_positions()
72
- ),
73
- array(
74
- 'title' => __( 'Number of Decimals', 'learnpress' ),
75
- 'id' => $this->get_field_name( 'number_of_decimals' ),
76
- 'default' => '2',
77
- 'type' => 'number',
78
- 'options' => $this->_get_currency_positions()
79
- ),
80
- array(
81
- 'title' => __( 'Load css', 'learnpress' ),
82
- 'id' => $this->get_field_name( 'load_css' ),
83
- 'default' => 'yes',
84
- 'type' => 'checkbox',
85
- 'desc' => __( 'Load default stylesheet for LearnPress', 'learnpress' )
86
- ),
87
- array(
88
- 'title' => __( 'Debug mode', 'learnpress' ),
89
- 'id' => $this->get_field_name( 'debug' ),
90
- 'default' => 'yes',
91
- 'type' => 'checkbox',
92
- 'desc' => __( 'Turn on/off debug mode for developer', 'learnpress' )
93
- )
94
- )
95
- );
96
- }
97
-
98
- private function _get_currency_options() {
99
- $currencies = array();
100
-
101
- if ( $payment_currencies = learn_press_get_payment_currencies() )
102
- foreach ( $payment_currencies as $code => $symbol ) {
103
- $currencies[$code] = $symbol;
104
- }
105
-
106
- return $currencies;
107
- }
108
-
109
- private function _get_currency_positions() {
110
- $positions = array();
111
- foreach ( learn_press_currency_positions() as $pos => $text ) {
112
- switch ( $pos ) {
113
- case 'left':
114
- $text = sprintf( '%s ( %s%s )', $text, learn_press_get_currency_symbol(), '69.99' );
115
- break;
116
- case 'right':
117
- $text = sprintf( '%s ( %s%s )', $text, '69.99', learn_press_get_currency_symbol() );
118
- break;
119
- case 'left_with_space':
120
- $text = sprintf( '%s ( %s %s )', $text, learn_press_get_currency_symbol(), '69.99' );
121
- break;
122
- case 'right_with_space':
123
- $text = sprintf( '%s ( %s %s )', $text, '69.99', learn_press_get_currency_symbol() );
124
- break;
125
- }
126
- $positions[$pos] = $text;
127
- }
128
- return $positions;
129
- }
130
- }
131
-
132
  return new LP_Settings_General();
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Settings_General
5
+ *
6
+ * @author ThimPress
7
+ * @package LearnPress/Admin/Settings/Classes
8
+ * @version 1.0
9
+ */
10
+ class LP_Settings_General extends LP_Settings_Base {
11
+ /**
12
+ * Construct
13
+ */
14
+ public function __construct() {
15
+ $this->id = 'general';
16
+ $this->text = __( 'General', 'learnpress' );
17
+ //add_action( 'learn_press_settings_general', array( $this, 'output' ) );
18
+ //add_action( 'learn_press_settings_save_general', array( $this, 'save' ) );
19
+ parent::__construct();
20
+ }
21
+
22
+ public function output() {
23
+ $view = learn_press_get_admin_view( 'settings/general.php' );
24
+ include_once $view;
25
+ }
26
+
27
+ public function get_settings() {
28
+ return apply_filters(
29
+ 'learn_press_general_settings',
30
+ array(
31
+ array(
32
+ 'title' => __( 'Instructors registration', 'learnpress' ),
33
+ 'desc' => __( 'Create option for instructors registration.', 'learnpress' ),
34
+ 'id' => $this->get_field_name( 'instructor_registration' ),
35
+ 'default' => 'no',
36
+ 'type' => 'checkbox'
37
+ ),
38
+ array(
39
+ 'title' => __( 'Currency', 'learnpress' ),
40
+ 'id' => $this->get_field_name( 'currency' ),
41
+ 'default' => 'USD',
42
+ 'type' => 'select',
43
+ 'options' => $this->_get_currency_options()
44
+ ),
45
+ array(
46
+ 'title' => __( 'Currency position', 'learnpress' ),
47
+ 'id' => $this->get_field_name( 'currency_pos' ),
48
+ 'default' => 'left',
49
+ 'type' => 'select',
50
+ 'options' => $this->_get_currency_positions()
51
+ ),
52
+ array(
53
+ 'title' => __( 'Thousands Separator', 'learnpress' ),
54
+ 'id' => $this->get_field_name( 'thousands_separator' ),
55
+ 'default' => ',',
56
+ 'type' => 'text',
57
+ 'options' => $this->_get_currency_positions()
58
+ ),
59
+ array(
60
+ 'title' => __( 'Decimals Separator', 'learnpress' ),
61
+ 'id' => $this->get_field_name( 'decimals_separator' ),
62
+ 'default' => '.',
63
+ 'type' => 'text',
64
+ 'options' => $this->_get_currency_positions()
65
+ ),
66
+ array(
67
+ 'title' => __( 'Number of Decimals', 'learnpress' ),
68
+ 'id' => $this->get_field_name( 'number_of_decimals' ),
69
+ 'default' => '2',
70
+ 'type' => 'number',
71
+ 'options' => $this->_get_currency_positions()
72
+ ),
73
+ array(
74
+ 'title' => __( 'Load css', 'learnpress' ),
75
+ 'id' => $this->get_field_name( 'load_css' ),
76
+ 'default' => 'yes',
77
+ 'type' => 'checkbox',
78
+ 'desc' => __( 'Load default stylesheet for LearnPress', 'learnpress' )
79
+ ),
80
+ array(
81
+ 'title' => __( 'Debug mode', 'learnpress' ),
82
+ 'id' => $this->get_field_name( 'debug' ),
83
+ 'default' => 'yes',
84
+ 'type' => 'checkbox',
85
+ 'desc' => __( 'Turn on/off debug mode for developer', 'learnpress' )
86
+ )
87
+ )
88
+ );
89
+ }
90
+
91
+ private function _get_currency_options() {
92
+ $currencies = array();
93
+
94
+ if ( $payment_currencies = learn_press_get_payment_currencies() )
95
+ foreach ( $payment_currencies as $code => $symbol ) {
96
+ $currencies[$code] = $symbol;
97
+ }
98
+
99
+ return $currencies;
100
+ }
101
+
102
+ private function _get_currency_positions() {
103
+ $positions = array();
104
+ foreach ( learn_press_currency_positions() as $pos => $text ) {
105
+ switch ( $pos ) {
106
+ case 'left':
107
+ $text = sprintf( '%s ( %s%s )', $text, learn_press_get_currency_symbol(), '69.99' );
108
+ break;
109
+ case 'right':
110
+ $text = sprintf( '%s ( %s%s )', $text, '69.99', learn_press_get_currency_symbol() );
111
+ break;
112
+ case 'left_with_space':
113
+ $text = sprintf( '%s ( %s %s )', $text, learn_press_get_currency_symbol(), '69.99' );
114
+ break;
115
+ case 'right_with_space':
116
+ $text = sprintf( '%s ( %s %s )', $text, '69.99', learn_press_get_currency_symbol() );
117
+ break;
118
+ }
119
+ $positions[$pos] = $text;
120
+ }
121
+ return $positions;
122
+ }
123
+ }
124
+
 
 
 
 
 
 
 
125
  return new LP_Settings_General();
inc/admin/settings/class-lp-settings-pages.php CHANGED
@@ -1,203 +1,213 @@
1
- <?php
2
-
3
- /**
4
- * Class LP_Settings_Pages
5
- */
6
- class LP_Settings_Pages extends LP_Settings_Base {
7
- public function __construct() {
8
- $this->id = 'pages';
9
- $this->text = __( 'Pages', 'learnpress' );
10
-
11
- parent::__construct();
12
- }
13
-
14
- public function get_sections() {
15
- $sections = array(
16
- 'profile' => array(
17
- 'id' => 'profile',
18
- 'title' => __( 'Profile', 'learnpress' )
19
- ),
20
- 'quiz' => array(
21
- 'id' => 'quiz',
22
- 'title' => __( 'Quiz', 'learnpress' )
23
- ),
24
- 'become_a_teacher' => array(
25
- 'id' => 'become_a_teacher',
26
- 'title' => __( 'Become a teacher', 'learnpress' )
27
- )
28
- );
29
- return $sections = apply_filters( 'learn_press_settings_sections_' . $this->id, $sections );
30
- }
31
-
32
- public function get_settings() {
33
-
34
- $display_name = array(
35
- 'nice' => esc_html__('Nicename','learnpress'),
36
- 'first' => esc_html__('First name','learnpress'),
37
- 'last' => esc_html__('Last name','learnpress'),
38
- 'nick' => esc_html__('Nickname','learnpress'),
39
- 'firstlast' => esc_html__('First name + Last name','learnpress'),
40
- 'lastfirst' => esc_html__('Last name + First name','learnpress'),
41
-
42
- );
43
-
44
- return apply_filters(
45
- 'learn_press_page_settings',
46
- array(
47
- array( 'section' => 'profile' ),
48
- array(
49
- 'title' => __( 'Profile', 'learnpress' ),
50
- 'id' => $this->get_field_name( 'profile_page_id' ),
51
- 'default' => '',
52
- 'type' => 'pages-dropdown'
53
- ),
54
-
55
- array(
56
- 'title' => __( 'Add link to admin bar', 'learnpress' ),
57
- 'id' => $this->get_field_name( 'admin_bar_link' ),
58
- 'default' => 'yes',
59
- 'type' => 'checkbox'
60
- ),
61
- array(
62
- 'title' => __( 'Text link', 'learnpress' ),
63
- 'id' => $this->get_field_name( 'admin_bar_link_text' ),
64
- 'default' => '',
65
- 'type' => 'text',
66
- 'placeholder' => __( 'Default: View Course Profile', 'learnpress' ),
67
- 'class' => 'regular-text'
68
- ),
69
- array(
70
- 'title' => __( 'Target link', 'learnpress' ),
71
- 'id' => $this->get_field_name( 'admin_bar_link_target' ),
72
- 'default' => 'yes',
73
- 'type' => 'select',
74
- 'options' => array(
75
- '_self' => __( 'Self', 'learnpress' ),
76
- '_blank' => __( 'New window', 'learnpress' )
77
- )
78
- ),
79
- array(
80
- 'title' => __( 'Courses limit', 'learnpress' ),
81
- 'id' => $this->get_field_name( 'profile_courses_limit' ),
82
- 'default' => '10',
83
- 'type' => 'number',
84
- 'min' => 1
85
- ),
86
- /*array(
87
- 'title' => __( 'Access level', 'learnpress' ),
88
- 'id' => $this->get_field_name( 'profile_access_level' ),
89
- 'default' => 'private',
90
- 'type' => 'select',
91
- 'options' => array(
92
- 'private' => __( 'Private (Only account own)', 'learnpress' ),
93
- 'public' => __( 'Public', 'learnpress' )
94
- )
95
- ),*/
96
- array(
97
- 'title' => __( 'Endpoints', 'learnpress' ),
98
- 'type' => 'title'
99
- ),
100
- array(
101
- 'title' => __( 'Tab Courses', 'learnpress' ),
102
- 'id' => $this->get_field_name( 'profile_endpoints[profile-courses]' ),
103
- 'default' => 'courses',
104
- 'type' => 'text',
105
- 'placeholder' => '',
106
- 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[profile/admin/courses]</code>', __( 'Example link is', 'learnpress' ) )
107
- ),
108
- array(
109
- 'title' => __( 'Tab Quizzes', 'learnpress' ),
110
- 'id' => $this->get_field_name( 'profile_endpoints[profile-quizzes]' ),
111
- 'default' => 'quizzes',
112
- 'type' => 'text',
113
- 'placeholder' => '',
114
- 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[profile/admin/quizzes]</code>', __( 'Example link is', 'learnpress' ) )
115
- ),
116
- array(
117
- 'title' => __( 'Tab Orders', 'learnpress' ),
118
- 'id' => $this->get_field_name( 'profile_endpoints[profile-orders]' ),
119
- 'default' => 'orders',
120
- 'type' => 'text',
121
- 'placeholder' => '',
122
- 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[profile/admin/orders]</code>', __( 'Example link is', 'learnpress' ) )
123
- ),
124
- array(
125
- 'title' => __( 'View order', 'learnpress' ),
126
- 'id' => $this->get_field_name( 'profile_endpoints[profile-order-details]' ),
127
- 'default' => 'order-details',
128
- 'type' => 'text',
129
- 'placeholder' => '',
130
- 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[profile/admin/order-details/123]</code>', __( 'Example link is', 'learnpress' ) )
131
- ),
132
- array(
133
- 'title' => __( 'Profile picture', 'learnpress' ),
134
- 'type' => 'title'
135
- ),
136
- array(
137
- 'title' => __( 'Thumbnail size', 'learnpress' ),
138
- 'id' => $this->get_field_name( 'profile_picture_thumbnail_size' ),
139
- 'default' => array( 150, 150, 'yes' ),
140
- 'type' => 'image-size'
141
- ),
142
- array( 'section' => 'quiz' ),
143
- array(
144
- 'title' => __( 'Endpoints', 'learnpress' ),
145
- 'type' => 'title'
146
- ),
147
- array(
148
- 'title' => __( 'Results', 'learnpress' ),
149
- 'id' => $this->get_field_name( 'quiz_endpoints[results]' ),
150
- 'default' => 'results',
151
- 'type' => 'text',
152
- 'placeholder' => '',
153
- 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[quizzes/sample-quiz/results]</code>', __( 'Example link is', 'learnpress' ) )
154
- ),
155
- array( 'section' => 'become_a_teacher' ),
156
- array(
157
- 'title' => __( 'Become a teacher', 'learnpress' ),
158
- 'id' => $this->get_field_name( 'become_a_teacher_page_id' ),
159
- 'default' => '',
160
- 'type' => 'pages-dropdown'
161
- )
162
- )
163
- );
164
- }
165
-
166
- public function _get_settings( $section ) {
167
- $settings = $this->get_settings();
168
- $get = false;
169
- $return = array();
170
- foreach ( $settings as $k => $v ) {
171
- if ( !empty( $v['section'] ) ) {
172
- if ( $get ) {
173
- break;
174
- }
175
- if ( $v['section'] == $section ) {
176
- $get = true;
177
- continue;
178
- }
179
- }
180
- if ( $get ) {
181
- $return[] = $v;
182
- }
183
- }
184
- return $return;
185
- }
186
-
187
- public function output_section_profile() {
188
- $view = learn_press_get_admin_view( 'settings/pages/profile.php' );
189
- require_once $view;
190
- }
191
-
192
- public function output_section_quiz() {
193
- $view = learn_press_get_admin_view( 'settings/pages/quiz.php' );
194
- require_once $view;
195
- }
196
-
197
- public function output_section_become_a_teacher() {
198
- $view = learn_press_get_admin_view( 'settings/pages/become-a-teacher.php' );
199
- require_once $view;
200
- }
201
- }
202
-
 
 
 
 
 
 
 
 
 
 
203
  return new LP_Settings_Pages();
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Settings_Pages
5
+ */
6
+ class LP_Settings_Pages extends LP_Settings_Base {
7
+ public function __construct() {
8
+ $this->id = 'pages';
9
+ $this->text = __( 'Pages', 'learnpress' );
10
+
11
+ parent::__construct();
12
+ }
13
+
14
+ public function get_sections() {
15
+ $sections = array(
16
+ 'profile' => array(
17
+ 'id' => 'profile',
18
+ 'title' => __( 'Profile', 'learnpress' )
19
+ ),
20
+ 'quiz' => array(
21
+ 'id' => 'quiz',
22
+ 'title' => __( 'Quiz', 'learnpress' )
23
+ ),
24
+ 'become_a_teacher' => array(
25
+ 'id' => 'become_a_teacher',
26
+ 'title' => __( 'Become a teacher', 'learnpress' )
27
+ )
28
+ );
29
+ return $sections = apply_filters( 'learn_press_settings_sections_' . $this->id, $sections );
30
+ }
31
+
32
+ public function get_settings() {
33
+
34
+ $display_name = array(
35
+ 'nice' => esc_html__( 'Nicename', 'learnpress' ),
36
+ 'first' => esc_html__( 'First name', 'learnpress' ),
37
+ 'last' => esc_html__( 'Last name', 'learnpress' ),
38
+ 'nick' => esc_html__( 'Nickname', 'learnpress' ),
39
+ 'firstlast' => esc_html__( 'First name + Last name', 'learnpress' ),
40
+ 'lastfirst' => esc_html__( 'Last name + First name', 'learnpress' ),
41
+
42
+ );
43
+
44
+ return apply_filters(
45
+ 'learn_press_page_settings',
46
+ array(
47
+ array( 'section' => 'profile' ),
48
+ array(
49
+ 'title' => __( 'General', 'learnpress' ),
50
+ 'type' => 'title'
51
+ ),
52
+ array(
53
+ 'title' => __( 'Profile', 'learnpress' ),
54
+ 'id' => $this->get_field_name( 'profile_page_id' ),
55
+ 'default' => '',
56
+ 'type' => 'pages-dropdown'
57
+ ),
58
+
59
+ array(
60
+ 'title' => __( 'Add link to admin bar', 'learnpress' ),
61
+ 'id' => $this->get_field_name( 'admin_bar_link' ),
62
+ 'default' => 'yes',
63
+ 'type' => 'checkbox'
64
+ ),
65
+ array(
66
+ 'title' => __( 'Text link', 'learnpress' ),
67
+ 'id' => $this->get_field_name( 'admin_bar_link_text' ),
68
+ 'default' => '',
69
+ 'type' => 'text',
70
+ 'placeholder' => __( 'Default: View Course Profile', 'learnpress' ),
71
+ 'class' => 'regular-text'
72
+ ),
73
+ array(
74
+ 'title' => __( 'Target link', 'learnpress' ),
75
+ 'id' => $this->get_field_name( 'admin_bar_link_target' ),
76
+ 'default' => 'yes',
77
+ 'type' => 'select',
78
+ 'options' => array(
79
+ '_self' => __( 'Self', 'learnpress' ),
80
+ '_blank' => __( 'New window', 'learnpress' )
81
+ )
82
+ ),
83
+ array(
84
+ 'title' => __( 'Courses limit', 'learnpress' ),
85
+ 'id' => $this->get_field_name( 'profile_courses_limit' ),
86
+ 'default' => '10',
87
+ 'type' => 'number',
88
+ 'min' => 1
89
+ ),
90
+ /*array(
91
+ 'title' => __( 'Access level', 'learnpress' ),
92
+ 'id' => $this->get_field_name( 'profile_access_level' ),
93
+ 'default' => 'private',
94
+ 'type' => 'select',
95
+ 'options' => array(
96
+ 'private' => __( 'Private (Only account own)', 'learnpress' ),
97
+ 'public' => __( 'Public', 'learnpress' )
98
+ )
99
+ ),*/
100
+ array(
101
+ 'title' => __( 'Page slug', 'learnpress' ),
102
+ 'type' => 'title'
103
+ ),
104
+ array(
105
+ 'title' => __( 'Courses', 'learnpress' ),
106
+ 'id' => $this->get_field_name( 'profile_endpoints[profile-courses]' ),
107
+ 'default' => 'courses',
108
+ 'type' => 'text',
109
+ 'placeholder' => '',
110
+ 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[profile/admin/courses]</code>', __( 'Example link is', 'learnpress' ) )
111
+ ),
112
+ array(
113
+ 'title' => __( 'Quizzes', 'learnpress' ),
114
+ 'id' => $this->get_field_name( 'profile_endpoints[profile-quizzes]' ),
115
+ 'default' => 'quizzes',
116
+ 'type' => 'text',
117
+ 'placeholder' => '',
118
+ 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[profile/admin/quizzes]</code>', __( 'Example link is', 'learnpress' ) )
119
+ ),
120
+ array(
121
+ 'title' => __( 'Orders', 'learnpress' ),
122
+ 'id' => $this->get_field_name( 'profile_endpoints[profile-orders]' ),
123
+ 'default' => 'orders',
124
+ 'type' => 'text',
125
+ 'placeholder' => '',
126
+ 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[profile/admin/orders]</code>', __( 'Example link is', 'learnpress' ) )
127
+ ),
128
+ array(
129
+ 'title' => __( 'View order', 'learnpress' ),
130
+ 'id' => $this->get_field_name( 'profile_endpoints[profile-order-details]' ),
131
+ 'default' => 'order-details',
132
+ 'type' => 'text',
133
+ 'placeholder' => '',
134
+ 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[profile/admin/order-details/123]</code>', __( 'Example link is', 'learnpress' ) )
135
+ ),
136
+ array(
137
+ 'title' => __( 'User avatar', 'learnpress' ),
138
+ 'type' => 'title'
139
+ ),
140
+ array(
141
+ 'title' => __( 'Ratio', 'learnpress' ),
142
+ 'id' => $this->get_field_name( 'profile_picture_thumbnail_size' ),
143
+ 'default' => array( 150, 150, 'yes' ),
144
+ 'type' => 'image-size'
145
+ ),
146
+ /*array(
147
+ 'title' => __( 'Crop', 'learnpress' ),
148
+ 'id' => $this->get_field_name( 'profile_picture_crop' ),
149
+ 'default' => 'yes',
150
+ 'type' => 'checkbox'
151
+ ),*/
152
+ array( 'section' => 'quiz' ),
153
+ array(
154
+ 'title' => __( 'Endpoints', 'learnpress' ),
155
+ 'type' => 'title'
156
+ ),
157
+ array(
158
+ 'title' => __( 'Results', 'learnpress' ),
159
+ 'id' => $this->get_field_name( 'quiz_endpoints[results]' ),
160
+ 'default' => 'results',
161
+ 'type' => 'text',
162
+ 'placeholder' => '',
163
+ 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[quizzes/sample-quiz/results]</code>', __( 'Example link is', 'learnpress' ) )
164
+ ),
165
+ array( 'section' => 'become_a_teacher' ),
166
+ array(
167
+ 'title' => __( 'Become a teacher', 'learnpress' ),
168
+ 'id' => $this->get_field_name( 'become_a_teacher_page_id' ),
169
+ 'default' => '',
170
+ 'type' => 'pages-dropdown'
171
+ )
172
+ )
173
+ );
174
+ }
175
+
176
+ public function _get_settings( $section ) {
177
+ $settings = $this->get_settings();
178
+ $get = false;
179
+ $return = array();
180
+ foreach ( $settings as $k => $v ) {
181
+ if ( !empty( $v['section'] ) ) {
182
+ if ( $get ) {
183
+ break;
184
+ }
185
+ if ( $v['section'] == $section ) {
186
+ $get = true;
187
+ continue;
188
+ }
189
+ }
190
+ if ( $get ) {
191
+ $return[] = $v;
192
+ }
193
+ }
194
+ return $return;
195
+ }
196
+
197
+ public function output_section_profile() {
198
+ $view = learn_press_get_admin_view( 'settings/pages/profile.php' );
199
+ require_once $view;
200
+ }
201
+
202
+ public function output_section_quiz() {
203
+ $view = learn_press_get_admin_view( 'settings/pages/quiz.php' );
204
+ require_once $view;
205
+ }
206
+
207
+ public function output_section_become_a_teacher() {
208
+ $view = learn_press_get_admin_view( 'settings/pages/become-a-teacher.php' );
209
+ require_once $view;
210
+ }
211
+ }
212
+
213
  return new LP_Settings_Pages();
inc/admin/views/settings/emails/_email-template.php CHANGED
@@ -20,12 +20,20 @@
20
  $local_file = $this->get_theme_template_file( $template );
21
  $template_file = $this->template_base . $template;
22
  $template_dir = learn_press_template_path();
 
 
 
 
 
 
 
 
23
  ?>
24
  <div class="template <?php echo $template_type == 'html' ? $template_type . ' multipart' : 'plain_text'; ?>">
25
 
26
  <?php if ( file_exists( $local_file ) ): ?>
27
  <p class="description">
28
- <?php printf( __( 'This template has been overridden by your theme and can be found in: <code>%s</code>. Please open the file in an editor program to edit', 'learnpress' ), 'yourtheme/' . $template_dir . '/' . $template ); ?>
29
  </p>
30
  <?php else: ?>
31
 
@@ -52,7 +60,7 @@
52
  <h4><?php echo wp_kses_post( $title ); ?></h4>
53
 
54
  <p class="description">
55
- <?php printf( __( 'This template has been overridden by your theme and can be found in: <code>%s</code>.', 'learnpress' ), 'yourtheme/' . $template_dir . '/' . $template ); ?>
56
  </p>
57
  <p>
58
  <?php if ( is_writable( $local_file ) ) : ?>
20
  $local_file = $this->get_theme_template_file( $template );
21
  $template_file = $this->template_base . $template;
22
  $template_dir = learn_press_template_path();
23
+
24
+ $theme_dir = get_template_directory();
25
+ $stylesheet_dir = get_stylesheet_directory();
26
+
27
+ if ( $theme_dir != $stylesheet_dir ) {
28
+ $theme_dir = $stylesheet_dir;
29
+ }
30
+ $theme_folder = basename( $theme_dir );
31
  ?>
32
  <div class="template <?php echo $template_type == 'html' ? $template_type . ' multipart' : 'plain_text'; ?>">
33
 
34
  <?php if ( file_exists( $local_file ) ): ?>
35
  <p class="description">
36
+ <?php printf( __( 'This template has been overridden by your theme and can be found in: <code>%s</code>. Please open the file in an editor program to edit', 'learnpress' ), $theme_folder . '/' . $template_dir . '/' . $template ); ?>
37
  </p>
38
  <?php else: ?>
39
 
60
  <h4><?php echo wp_kses_post( $title ); ?></h4>
61
 
62
  <p class="description">
63
+ <?php printf( __( 'This template has been overridden by your theme and can be found in: <code>%s</code>.', 'learnpress' ), $theme_folder . '/' . $template_dir . '/' . $template ); ?>
64
  </p>
65
  <p>
66
  <?php if ( is_writable( $local_file ) ) : ?>
inc/admin/views/settings/emails/email-template.php CHANGED
@@ -35,13 +35,21 @@ $email_format = $settings->get( 'emails_' . $this->id . '.email_format', 'plain_
35
  $content_plain = stripslashes( $settings->get( 'emails_' . $this->id . '.email_content_plain', file_get_contents( $template_file ) ) );
36
 
37
  $has_local_file = file_exists( $local_file );
 
 
 
 
 
 
 
 
38
  ?>
39
  <div class="<?php echo join( ' ', $classes ); ?>">
40
 
41
  <?php if ( $has_local_file ): ?>
42
  <textarea rows="10" style="width: 90%;" readonly="readonly"><?php echo stripslashes( file_get_contents( $local_file ) ); ?></textarea>
43
  <p class="description">
44
- <?php printf( __( 'This template has been overridden by your theme and can be found in: <code>%s</code>. Please open the file in an editor program to edit', 'learnpress' ), 'yourtheme/' . $template_dir . '/' . $template ); ?>
45
  </p>
46
  <?php endif; ?>
47
  <div class="<?php echo $has_local_file ? 'hide-if-js' : ''; ?>">
@@ -74,7 +82,7 @@ $email_format = $settings->get( 'emails_' . $this->id . '.email_format', 'plain_
74
  </ol>
75
  <?php endif; ?>
76
  <p class="description">
77
- <?php printf( __( 'To override and edit this email template copy <code>%s</code> to your theme folder: <code>%s</code>.', 'learnpress' ), plugin_basename( $template_file ), 'yourtheme/' . $template_dir . '/' . $template ); ?>
78
  </p>
79
  <?php endif; ?>
80
  </div>
35
  $content_plain = stripslashes( $settings->get( 'emails_' . $this->id . '.email_content_plain', file_get_contents( $template_file ) ) );
36
 
37
  $has_local_file = file_exists( $local_file );
38
+
39
+ $theme_dir = get_template_directory();
40
+ $stylesheet_dir = get_stylesheet_directory();
41
+
42
+ if ( $theme_dir != $stylesheet_dir ) {
43
+ $theme_dir = $stylesheet_dir;
44
+ }
45
+ $theme_folder = basename( $theme_dir );
46
  ?>
47
  <div class="<?php echo join( ' ', $classes ); ?>">
48
 
49
  <?php if ( $has_local_file ): ?>
50
  <textarea rows="10" style="width: 90%;" readonly="readonly"><?php echo stripslashes( file_get_contents( $local_file ) ); ?></textarea>
51
  <p class="description">
52
+ <?php printf( __( 'This template has been overridden by your theme and can be found in: <code>%s</code>. <br />Please open the file in an editor program to edit', 'learnpress' ), $theme_folder . '/' . $template_dir . '/' . $template ); ?>
53
  </p>
54
  <?php endif; ?>
55
  <div class="<?php echo $has_local_file ? 'hide-if-js' : ''; ?>">
82
  </ol>
83
  <?php endif; ?>
84
  <p class="description">
85
+ <?php printf( __( 'To override and edit this email template copy <code>%s</code> to your theme folder: <code>%s</code>.', 'learnpress' ), plugin_basename( $template_file ), $theme_folder . '/' . $template_dir . '/' . $template ); ?>
86
  </p>
87
  <?php endif; ?>
88
  </div>
inc/admin/views/settings/fields/image-size.php CHANGED
@@ -1,21 +1,22 @@
1
- <?php
2
- if ( empty( $options['default'] ) ) {
3
- $options['default'] = array( null, null, null );
4
- }
5
- ?>
6
-
7
- <tr class="<?php echo $options['class'] ? $options['class'] : ''; ?>">
8
- <th scope="row" class="titledesc"><?php echo esc_html( $options['title'] ) ?></th>
9
- <td>
10
- <input type="text" size="4" name="<?php echo $options['id']; ?>[width]" value="<?php echo $this->get_option( $options['id'] . '.width', $options['default'][0] ); ?>" placeholder="" />
11
- &times;
12
- <input type="text" size="4" name="<?php echo $options['id']; ?>[height]" value="<?php echo $this->get_option( $options['id'] . '.height', $options['default'][1] ); ?>" placeholder="" />
13
- <?php _e( 'px', 'learnpress' ); ?>
14
- &nbsp;&nbsp;&nbsp;
15
- <input type="hidden" name="<?php echo $options['id']; ?>[crop]" value="no" />
16
- <label>
17
- <input type="checkbox" name="<?php echo $options['id']; ?>[crop]" value="yes" <?php checked( $this->get_option( $options['id'] . '.crop', $options['default'][2] ) == 'yes' ); ?> />
18
- <?php _e( 'Crop?', 'learn_pres' ); ?>
19
- </label>
20
- </td>
 
21
  </tr>
1
+ <?php
2
+ if ( empty( $options['default'] ) ) {
3
+ $options['default'] = array( null, null, null );
4
+ }
5
+ ?>
6
+ <tr>
7
+ <th scope="row" class="titledesc"><?php echo esc_html( $options['title'] ) ?></th>
8
+ <td>
9
+ <div class="lp-setting-field lp-setting-field-image-size">
10
+ <input type="text" size="4" name="<?php echo $options['id']; ?>[width]" value="<?php echo $this->get_option( $options['id'] . '.width', $options['default'][0] ); ?>" placeholder="" />
11
+ <span class="lp-sign-times">&times;</span>
12
+ <input type="text" size="4" name="<?php echo $options['id']; ?>[height]" value="<?php echo $this->get_option( $options['id'] . '.height', $options['default'][1] ); ?>" placeholder="" />
13
+ <span><?php _e( 'px', 'learnpress' ); ?></span>
14
+ <span class="lp-sign-times">&nbsp;&nbsp;&nbsp;</span>
15
+ <input type="hidden" name="<?php echo $options['id']; ?>[crop]" value="no" />
16
+ <!--<label>
17
+ <input type="checkbox" name="<?php echo $options['id']; ?>[crop]" value="yes" <?php checked( $this->get_option( $options['id'] . '.crop', $options['default'][2] ) == 'yes' ); ?> />
18
+ <?php _e( 'Crop?', 'learn_pres' ); ?>
19
+ </label>-->
20
+ </div>
21
+ </td>
22
  </tr>
inc/admin/views/settings/fields/title.php CHANGED
@@ -1,3 +1,3 @@
1
- <tr class="header-form">
2
- <th colspan="2" style="padding: 0;"><h3 style="padding: 0; margin: 0;"><?php echo esc_html( $options['title'] ) ?></h3></th>
3
  </tr>
1
+ <tr class="header-form">
2
+ <th colspan="2"><h3 class="lp-group-title"><?php echo esc_html( $options['title'] ) ?></h3></th>
3
  </tr>
inc/admin/views/settings/general.php CHANGED
@@ -1,24 +1,24 @@
1
- <?php
2
- /**
3
- * Display html for general settings
4
- *
5
- * @author ThimPress
6
- * @package LearnPress/Admin/Views
7
- * @version 1.0
8
- */
9
-
10
- if ( !defined( 'ABSPATH' ) ) {
11
- exit; // Exit if accessed directly
12
- }
13
-
14
- $settings = LP()->settings;
15
- ?>
16
-
17
- <table class="form-table">
18
- <tbody>
19
- <?php
20
- do_action( 'learn_press_before_general_settings_fields', $settings );
21
- $this->output_settings();
22
- ?>
23
- </tbody>
24
- </table>
1
+ <?php
2
+ /**
3
+ * Display html for general settings
4
+ *
5
+ * @author ThimPress
6
+ * @package LearnPress/Admin/Views
7
+ * @version 1.0
8
+ */
9
+
10
+ if ( !defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly
12
+ }
13
+
14
+ $settings = LP()->settings;
15
+ ?>
16
+
17
+ <table class="form-table">
18
+ <tbody>
19
+ <?php
20
+ do_action( 'learn_press_before_general_settings_fields', $settings );
21
+ $this->output_settings();
22
+ ?>
23
+ </tbody>
24
+ </table>
inc/cart/class-lp-cart.php CHANGED
@@ -1,654 +1,664 @@
1
- <?php
2
-
3
- /**
4
- * Class LP_Cart
5
- *
6
- * Simple Cart object for now. Maybe need to expand later
7
- *
8
- * @author ThimPress
9
- * @package LearnPress/Classes
10
- * @version 1.0
11
- */
12
-
13
- defined( 'ABSPATH' ) || exit();
14
-
15
- class LP_Cart {
16
-
17
- /**
18
- * Unique instance of LP_Cart
19
- *
20
- * @var LP_Cart object
21
- */
22
- private static $instance = false;
23
-
24
- /**
25
- * Hold the content of the cart
26
- *
27
- * @var array
28
- */
29
- protected $_cart_content = array();
30
-
31
- /**
32
- * Key of cart content stored in session
33
- *
34
- * @var string
35
- */
36
- protected $_cart_session_key = 'cart';
37
-
38
- /**
39
- * Constructor
40
- */
41
- public function __construct() {
42
- if ( !is_array( $this->_cart_content = learn_press_session_get( $this->_cart_session_key ) ) ) {
43
- $this->_cart_content = $this->get_default_cart_content();
44
- }
45
-
46
- $remove_items = array();
47
- if ( !empty( $this->_cart_content['items'] ) ) {
48
- foreach ( $this->_cart_content['items'] as $k => $item ) {
49
- if ( empty( $item['item_id'] ) || !get_post( $item['item_id'] ) ) {
50
- $remove_items[] = $item['item_id'];
51
- }
52
- }
53
- }
54
- if ( $remove_items ) {
55
- foreach ( $remove_items as $item_id ) {
56
- $this->remove_item( $item_id );
57
- }
58
- }
59
- LP_Request_Handler::register( 'add-course-to-cart', array( $this, 'add_to_cart' ), 20 );
60
- LP_Request_Handler::register( 'remove-cart-item', array( $this, 'remove_item' ), 20 );
61
-
62
- add_action( 'learn_press_add_to_cart', array( $this, 'calculate_totals' ), 10 );
63
- add_action( 'wp', array( $this, 'maybe_set_cart_cookies' ), 99 ); // Set cookies
64
- add_action( 'shutdown', array( $this, 'maybe_set_cart_cookies' ), 0 ); // Set cookies before shutdown and ob flushing
65
- add_action( 'wp_loaded', array( $this, 'init' ) );
66
- }
67
-
68
- function init() {
69
- $this->get_cart_from_session();
70
- }
71
-
72
- public function __get( $key ) {
73
- $return = null;
74
- if ( !isset( $this->{$key} ) ) {
75
- switch ( $key ) {
76
- case 'subtotal':
77
- $this->subtotal = floatval( $this->_cart_content['subtotal'] );
78
- break;
79
- case 'total':
80
- $this->total = floatval( $this->_cart_content['total'] );
81
- }
82
- }
83
- if ( isset( $this->{$key} ) ) {
84
- $return = $this->{$key};
85
- }
86
- return $return;
87
- }
88
-
89
- public function maybe_set_cart_cookies() {
90
- if ( !headers_sent()/* && did_action( 'wp_loaded' )*/ ) {
91
- $this->set_cart_cookies( !$this->is_empty() );
92
- }
93
- }
94
-
95
- private function set_cart_cookies( $set = true ) {
96
- if ( $set ) {
97
- learn_press_setcookie( 'learn_press_items_in_cart', 1 );
98
- $this->get_cart_for_session();
99
- } elseif ( isset( $_COOKIE['learn_press_items_in_cart'] ) ) {
100
- learn_press_setcookie( 'learn_press_items_in_cart', 0, time() - HOUR_IN_SECONDS );
101
- }
102
- do_action( 'learn_press_set_cart_cookies', $set );
103
- }
104
-
105
- public function get_cart_for_session() {
106
- $cart_session = array();
107
-
108
- if ( $this->get_cart() ) {
109
- foreach ( $this->get_cart() as $key => $values ) {
110
- $cart_session[$key] = $values;
111
- unset( $cart_session[$key]['data'] ); // Unset product object
112
- }
113
- }
114
-
115
- return $cart_session;
116
- }
117
-
118
- public function get_cart() {
119
- if ( !did_action( 'wp_loaded' ) ) {
120
- _doing_it_wrong( __FUNCTION__, __( 'Get cart should not be called before the wp_loaded action.', 'woocommerce' ), '2.3' );
121
- }
122
- if ( !did_action( 'learn_press_cart_loaded_from_session' ) ) {
123
- $this->get_cart_from_session();
124
- }
125
- return array_filter( (array) $this->_cart_content );
126
- }
127
-
128
- /**
129
- * Add course to cart
130
- *
131
- * @param int $course_id
132
- * @param int $quantity
133
- * @param array
134
- */
135
- public function add_to_cart( $course_id, $quantity = 1, $item_data = array() ) {
136
-
137
- $course = learn_press_get_course( $course_id );
138
- // course is not purchasable
139
- if ( !$course->is_purchasable() ) {
140
- learn_press_display_message( __( 'Sorry! This course is not purchasable.', 'learnpress' ) );
141
- if ( $redirect = apply_filter( 'learn_press_course_is_not_purchasable_redirect', get_the_permalink( $course_id ), $course_id ) ) {
142
- wp_redirect( $redirect );
143
- exit();
144
- }
145
- return;
146
- }
147
-
148
- /**
149
- * Generate course information and stores into session
150
- * for redirection if needed then we can remove it immediately
151
- */
152
- $quantity = apply_filters( 'learn_press_purchase_course_quantity', $quantity, $course_id );
153
- $price = $course->is_free() ? 0 : $course->get_price();
154
- /*$course_info = apply_filters( 'learn_press_purchase_course_info', array(
155
- 'item_id' => $course_id,
156
- 'quantity' => $quantity,
157
- 'subtotal' => $price * $quantity,
158
- 'total' => $price * $quantity,
159
- 'data' => apply_filters( 'learn_press_purchase_course_info_data', $_REQUEST )
160
- )
161
- );*/
162
-
163
- $this->_cart_content['items'][$course_id] = apply_filters( 'learn_press_add_cart_item', array(
164
- 'item_id' => $course_id,
165
- 'quantity' => $quantity,
166
- 'subtotal' => $price * $quantity,
167
- 'total' => $price * $quantity,
168
- 'data' => $item_data
169
- )
170
- );
171
-
172
- if ( did_action( 'wp' ) ) {
173
- $this->set_cart_cookies( true );
174
- }
175
-
176
- do_action( 'learn_press_add_to_cart', $course_id, $quantity, $item_data, $this );
177
-
178
- return;
179
-
180
- if ( !learn_press_is_enable_cart() ) {
181
- $this->empty_cart();
182
- }
183
- $course = learn_press_get_course( $course_id );
184
-
185
- /*
186
- if ( !empty( $this->_cart_content['items'][$course_id] ) ) {
187
- $quantity += $this->_cart_content['items'][$course_id]['quantity'];
188
- }*/
189
- if ( !$course->is_purchasable() ) {
190
- learn_press_add_message( __( 'Sorry! This course is not purchasable.', 'learnpress' ) );
191
- wp_redirect( get_the_permalink( $course_id ) );
192
- exit();
193
- }
194
-
195
- $quantity = 1;
196
- $price = $course->is_free() ? 0 : $course->get_price();
197
- $this->_cart_content['items'][$course_id] = apply_filters( 'learn_press_add_cart_item', array(
198
- 'item_id' => $course_id,
199
- 'quantity' => $quantity,
200
- 'subtotal' => $price * $quantity,
201
- 'total' => $price * $quantity,
202
- 'data' => $item_data
203
- )
204
- );
205
-
206
- learn_press_session_set( $this->_cart_session_key, $this->_cart_content );
207
-
208
- $this->set_cart_cookies( !$this->is_empty() );
209
-
210
- do_action( 'learn_press_add_to_cart', $course_id, $quantity, $item_data, $this );
211
- $button = '';
212
-
213
- // if the course is FREE and no require checkout screen
214
- if ( LP()->settings->get( 'no_checkout_free_course' ) == 'yes' && $this->total == 0 ) {
215
- if ( !is_user_logged_in() ) {
216
- $redirect = learn_press_get_page_link( 'profile' );
217
- if ( !$redirect ) {
218
- $redirect = wp_login_url();
219
- } else {
220
- $redirect = add_query_arg( 'next', 'enroll-course', $redirect );
221
- }
222
- learn_press_add_message( __( 'Please login to continue process.', 'learnpress' ) );
223
- $checkout_results['redirect'] = apply_filters( 'learn_press_no_checkout_free_course_redirect', $redirect );
224
- } else {
225
- add_filter( 'learn_press_checkout_success_result', '_learn_press_checkout_auto_enroll_free_course', 10, 2 );
226
- $checkout_results = LP_Checkout::instance()->process_checkout();
227
- }
228
- $redirect = $checkout_results['redirect'];
229
- /*if ( learn_press_is_ajax() ) {
230
- learn_press_send_json(
231
- $checkout_results
232
- );
233
- } else {
234
- wp_redirect( $checkout_results['redirect'] );
235
- exit();
236
- }*/
237
- } else {
238
- if ( learn_press_is_enable_cart() ) {
239
- if ( LP()->settings->get( 'redirect_after_add' ) == 'yes' ) {
240
- $redirect = learn_press_get_page_link( 'cart' );
241
- if ( !$redirect ) {
242
- learn_press_add_message( sprintf( __( 'Cart page is not setting up.', 'learnpress' ) ) );
243
- $redirect = learn_press_get_current_url();
244
- } else {
245
- $button = sprintf( '<a href="%s">%s</a>', get_the_permalink( $course_id ), __( 'Back to class', 'learnpress' ) );
246
- }
247
- } else {
248
- $redirect = get_the_permalink( $course_id );
249
- if ( !learn_press_get_page_link( 'cart' ) ) {
250
- learn_press_add_message( sprintf( __( 'Checkout page is not setting up.', 'learnpress' ) ) );
251
- } else {
252
- $button = sprintf( '<a href="%s">%s</a>', learn_press_get_page_link( 'cart' ), __( 'View cart', 'learnpress' ) );
253
- }
254
- }
255
- learn_press_add_message( sprintf( __( '<strong>%s</strong> has been added to your cart. %s', 'learnpress' ), get_the_title( $course_id ), $button ) );
256
-
257
- } else {
258
- $redirect = learn_press_get_page_link( 'checkout' );
259
- if ( !$redirect ) {
260
- learn_press_add_message( sprintf( __( 'Checkout page is not setting up.', 'learnpress' ) ) );
261
- $redirect = learn_press_get_current_url();
262
- }
263
- }
264
- }
265
-
266
- $redirect = apply_filters( 'learn_press_add_to_cart_redirect', $redirect, $course_id );
267
-
268
- if ( learn_press_is_ajax() ) {
269
- learn_press_send_json(
270
- array(
271
- 'redirect' => $redirect,
272
- 'result' => 'success',
273
- 'messages' => learn_press_get_notices( true )
274
- )
275
- );
276
- } else {
277
- wp_redirect( $redirect );
278
- die();
279
- }
280
- }
281
-
282
- /**
283
- * Checks to see if there is an item in cart
284
- *
285
- * @param $item_id
286
- *
287
- * @return bool
288
- */
289
- public function has_item( $item_id ) {
290
- return isset( $this->_cart_content['items'][$item_id] );
291
- }
292
-
293
- /**
294
- * Get an item in cart
295
- *
296
- * @param $item_id
297
- *
298
- * @return bool
299
- */
300
- public function get_item( $item_id ) {
301
- return $this->has_item( $item_id ) ? $this->_cart_content['items'][$item_id] : null;
302
- }
303
-
304
- /**
305
- * Remove an item from cart
306
- *
307
- * @param $item_id
308
- *
309
- * @return bool
310
- */
311
- public function remove_item( $item_id ) {
312
- if ( isset( $this->_cart_content['items'][$item_id] ) ) {
313
-
314
- do_action( 'learn_press_remove_cart_item', $item_id, $this );
315
-
316
- unset( $this->_cart_content['items'][$item_id] );
317
-
318
- do_action( 'learn_press_cart_item_removed', $item_id, $this );
319
-
320
- $this->calculate_totals();
321
-
322
- return true;
323
- }
324
-
325
- return false;
326
- }
327
-
328
- /**
329
- * Re-calculate cart totals and update data to session
330
- */
331
- public function calculate_totals() {
332
- $subtotal = 0;
333
-
334
- if ( !empty( $this->_cart_content['items'] ) && $items = $this->_cart_content['items'] ) {
335
- foreach ( $items as $item_id => $item ) {
336
- $course = learn_press_get_course( $item_id );
337
- if ( $course ) {
338
- $_subtotal = $course->get_price() * $item['quantity'];
339
- }
340
- $this->_cart_content['items'][$item_id]['subtotal'] = $_subtotal;
341
- $this->_cart_content['items'][$item_id]['total'] = $_subtotal;
342
- $subtotal += $_subtotal;
343
- }
344
-
345
- }
346
- $this->_cart_content['subtotal'] = $subtotal;
347
- $this->_cart_content['total'] = $subtotal;
348
- $this->update_session();
349
- }
350
-
351
- /**
352
- * Update cart content to session
353
- */
354
- public function update_session() {
355
- learn_press_session_set( $this->_cart_session_key, $this->_cart_content );
356
- }
357
-
358
- /**
359
- * Get cart id
360
- *
361
- * @return mixed
362
- */
363
- public function get_cart_id() {
364
- return !empty( $_SESSION['learn_press_cart']['cart_id'] ) ? $_SESSION['learn_press_cart']['cart_id'] : 0;
365
- }
366
-
367
- /**
368
- * Get all items from cart
369
- *
370
- * @return mixed
371
- */
372
- public function get_items() {
373
- if ( !did_action( 'learn_press_get_cart_from_session' ) ) {
374
- $this->get_cart_from_session();
375
- }
376
- return !empty( $this->_cart_content['items'] ) ? $this->_cart_content['items'] : array();
377
- }
378
-
379
- /**
380
- * Load cart content data from session
381
- *
382
- * @param bool $force
383
- */
384
- public function get_cart_from_session( $force = false ) {
385
- if ( !did_action( 'learn_press_get_cart_from_session' ) || $force ) {
386
- $this->_cart_content = learn_press_session_get( $this->_cart_session_key );
387
- do_action( 'learn_press_get_cart_from_session' );
388
- }
389
- }
390
-
391
- /**
392
- * Get cart sub-total
393
- *
394
- * @return mixed
395
- */
396
- public function get_subtotal() {
397
-
398
- $subtotal = learn_press_format_price( $this->_cart_content['subtotal'], true );
399
- return apply_filters( 'learn_press_get_cart_subtotal', $subtotal, $this->get_cart_id() );
400
- }
401
-
402
- /**
403
- * Get cart total
404
- *
405
- * @return mixed
406
- */
407
- public function get_total() {
408
- $subtotal = $this->get_subtotal();
409
- $total = $subtotal;
410
- return apply_filters( 'learn_press_get_cart_total', $total, $this->get_cart_id() );
411
- }
412
-
413
- /**
414
- * Generate unique cart id
415
- *
416
- * @return string
417
- */
418
- public function generate_cart_id() {
419
- return md5( time() );
420
- }
421
-
422
- /**
423
- * Return sub-total of cart content
424
- *
425
- * @param $course
426
- * @param int $quantity
427
- *
428
- * @return mixed|void
429
- */
430
- public function get_item_subtotal( $course, $quantity = 1 ) {
431
- $price = $course->get_price();
432
- $row_price = $price * $quantity;
433
- $course_subtotal = learn_press_format_price( $row_price, true );
434
- return apply_filters( 'learn_press_cart_item_subtotal', $course_subtotal, $course, $quantity, $this );
435
- }
436
-
437
- /**
438
- * Clean all items from cart
439
- *
440
- * @return $this
441
- */
442
- public function empty_cart() {
443
-
444
- do_action( 'learn_press_before_empty_cart' );
445
-
446
- learn_press_session_set( $this->_cart_session_key, $this->get_default_cart_content() );
447
-
448
- $this->get_cart_from_session( true );
449
-
450
- do_action( 'learn_press_emptied_cart' );
451
-
452
- return $this;
453
- }
454
-
455
- /**
456
- * Check if cart is empty or not
457
- *
458
- * @return bool
459
- */
460
- public function is_empty() {
461
- return sizeof( $this->get_items() ) === 0; //!$this->_cart_content['items'];
462
- }
463
-
464
- /**
465
- * Return cart content
466
- *
467
- * @return array|mixed|void
468
- */
469
- public function get_cart_content() {
470
- return $this->_cart_content;
471
- }
472
-
473
- public function get_default_cart_content() {
474
- return apply_filters( 'learn_press_default_cart_content', array(
475
- 'items' => array(),
476
- 'subtotal' => 0,
477
- 'total' => 0
478
- )
479
- );
480
- }
481
-
482
- /**
483
- * Get checkout url for checkout page
484
- * Return default url of checkout page
485
- *
486
- * @return mixed
487
- */
488
- public function get_checkout_url() {
489
- $checkout_url = learn_press_get_page_link( 'checkout' );
490
- return apply_filters( 'learn_press_get_checkout_url', $checkout_url );
491
- }
492
-
493
- /**
494
- * Checks if need to payment
495
- * Return true if cart total greater than 0
496
- *
497
- * @return mixed|void
498
- */
499
- public function needs_payment() {
500
- return apply_filters( 'learn_press_cart_needs_payment', $this->total > 0, $this );
501
- }
502
-
503
- /**
504
- * Process action for purchase course button
505
- *
506
- * @param $course_id
507
- */
508
- public function purchase_course_handler( $course_id ) {
509
-
510
- do_action( 'learn_press_before_purchase_course_handler', $course_id, $this );
511
-
512
- if ( apply_filters( 'learn_press_purchase_single_course', true ) ) {
513
- $this->empty_cart();
514
- }
515
- $this->add_to_cart( $course_id, 1, $_POST );
516
- $redirect = learn_press_get_checkout_url();
517
- $has_checkout = $redirect ? true : false;
518
- $need_checkout = $this->needs_payment();
519
-
520
- // In case the course is FREE and "No checkout free course" is turn off
521
- if ( !$need_checkout ) {
522
- $user = learn_press_get_current_user();
523
- if ( !$user->has_purchased_course( $course_id )/* || $user->has_finished_course( $course_id ) */ ) {
524
- require_once LP_PLUGIN_PATH . '/inc/gateways/class-lp-gateway-none.php';
525
- $checkout = learn_press_get_checkout( array( 'payment_method' => new LP_Gateway_None() ) );
526
-
527
- /**
528
- * + Auto enroll
529
- */
530
- add_filter( 'learn_press_checkout_success_result', '_learn_press_checkout_success_result', 10, 2 );
531
- $results = $checkout->process_checkout();
532
- remove_filter( 'learn_press_checkout_success_result', '_learn_press_checkout_success_result', 10 );
533
- }/* else {
534
- if ( $user->has_finished_course( $course_id ) ) {
535
- learn_press_add_message( __( 'You have already finished course', 'learnpress' ) );
536
- } else {
537
- learn_press_add_message( __( 'You have already enrolled course', 'learnpress' ) );
538
- }
539
- }*/
540
- } else {
541
-
542
- // Checkout page is not setting up
543
- if ( !$has_checkout ) {
544
- learn_press_add_message( __( 'Checkout page is not setup', 'learnpress' ), 'error' );
545
- } else {
546
- wp_redirect( apply_filters( 'learn_press_checkout_redirect', $redirect ) );
547
- exit();
548
- }
549
-
550
- }
551
- return;
552
- }
553
-
554
- /**
555
- * Destroy cart instance
556
- */
557
- public function destroy() {
558
-
559
- }
560
-
561
-
562
- /**
563
- * Get unique instance of LP_Cart object
564
- *
565
- * @return LP_Cart|mixed
566
- */
567
- public static function instance() {
568
- if ( !self::$instance ) {
569
- self::$instance = new self();
570
- }
571
- return self::$instance;
572
- }
573
- }
574
-
575
- /**
576
- * Return LP_Cart object instance
577
- *
578
- * @return mixed
579
- */
580
- function learn_press_get_cart() {
581
- return LP()->cart;
582
- }
583
-
584
- /**
585
- * Get description for cart by join all item titles into one
586
- *
587
- * @return string
588
- */
589
- function learn_press_get_cart_description() {
590
- $items = LP()->cart->get_items();
591
- $description = array();
592
- if ( $items ) {
593
- foreach ( $items as $item ) {
594
- $description[] = apply_filters( 'learn_press_cart_item_description', get_the_title( $item['item_id'] ) );
595
- }
596
- }
597
- return apply_filters( 'learn_press_cart_description', join( ', ', $description ) );
598
- }
599
-
600
- function learn_press_get_cart_course_url() {
601
- $products = learn_press_get_cart( 'products' );
602
- $return = '';
603
- if ( $products ) {
604
- foreach ( $products as $prop ) {
605
- $return = get_permalink( $prop['id'] );
606
- break;
607
- }
608
- }
609
- return apply_filters( 'learn_press_cart_course_url', $return );
610
- }
611
-
612
- /**
613
- * Return total of cart
614
- *
615
- * @return mixed
616
- */
617
- function learn_press_get_cart_total() {
618
- return LP()->cart->total;
619
- }
620
-
621
-
622
- function learn_press_clear_cart_after_payment() {
623
- global $wp;
624
-
625
- if ( !empty( $wp->query_vars['lp-order-received'] ) ) {
626
-
627
- $order_id = absint( $wp->query_vars['lp-order-received'] );
628
- $order_key = isset( $_GET['key'] ) ? $_GET['key'] : '';
629
-
630
- if ( $order_id > 0 && ( $order = learn_press_get_order( $order_id ) ) ) {
631
- if ( $order->order_key === $order_key ) {
632
- LP()->cart->empty_cart();
633
- }
634
- }
635
- }
636
-
637
- if ( LP()->session->order_awaiting_payment > 0 ) {
638
- $order = learn_press_get_order( LP()->session->order_awaiting_payment );
639
-
640
- if ( $order && $order->id > 0 ) {
641
- if ( !$order->has_status( array( 'failed', 'pending', 'cancelled' ) ) ) {
642
- LP()->cart->empty_cart();
643
- LP()->session->order_awaiting_payment = null;
644
- }
645
- }
646
- }
647
- }
648
-
649
- add_action( 'get_header', 'learn_press_clear_cart_after_payment' );
650
-
651
-
652
-
653
-
 
 
 
 
 
 
 
 
 
 
654
  //learn_press_get_cart_description();
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Cart
5
+ *
6
+ * Simple Cart object for now. Maybe need to expand later
7
+ *
8
+ * @author ThimPress
9
+ * @package LearnPress/Classes
10
+ * @version 1.0
11
+ */
12
+
13
+ defined( 'ABSPATH' ) || exit();
14
+
15
+ class LP_Cart {
16
+
17
+ /**
18
+ * Unique instance of LP_Cart
19
+ *
20
+ * @var LP_Cart object
21
+ */
22
+ private static $instance = false;
23
+
24
+ /**
25
+ * Hold the content of the cart
26
+ *
27
+ * @var array
28
+ */
29
+ protected $_cart_content = array();
30
+
31
+ /**
32
+ * Key of cart content stored in session
33
+ *
34
+ * @var string
35
+ */
36
+ protected $_cart_session_key = 'cart';
37
+
38
+ /**
39
+ * Constructor
40
+ */
41
+ public function __construct() {
42
+ if ( !is_array( $this->_cart_content = learn_press_session_get( $this->_cart_session_key ) ) ) {
43
+ $this->_cart_content = $this->get_default_cart_content();
44
+ }
45
+
46
+ $remove_items = array();
47
+ if ( !empty( $this->_cart_content['items'] ) ) {
48
+ foreach ( $this->_cart_content['items'] as $k => $item ) {
49
+ if ( empty( $item['item_id'] ) || !get_post( $item['item_id'] ) ) {
50
+ $remove_items[] = $item['item_id'];
51
+ }
52
+ }
53
+ }
54
+ if ( $remove_items ) {
55
+ foreach ( $remove_items as $item_id ) {
56
+ $this->remove_item( $item_id );
57
+ }
58
+ }
59
+ LP_Request_Handler::register( 'add-course-to-cart', array( $this, 'add_to_cart' ), 20 );
60
+ LP_Request_Handler::register( 'remove-cart-item', array( $this, 'remove_item' ), 20 );
61
+
62
+ add_action( 'learn_press_add_to_cart', array( $this, 'calculate_totals' ), 10 );
63
+ add_action( 'wp', array( $this, 'maybe_set_cart_cookies' ), 99 ); // Set cookies
64
+ add_action( 'shutdown', array( $this, 'maybe_set_cart_cookies' ), 0 ); // Set cookies before shutdown and ob flushing
65
+ add_action( 'wp_loaded', array( $this, 'init' ) );
66
+ }
67
+
68
+ function init() {
69
+ $this->get_cart_from_session();
70
+ }
71
+
72
+ public function __get( $key ) {
73
+ $return = null;
74
+ if ( !isset( $this->{$key} ) ) {
75
+ switch ( $key ) {
76
+ case 'subtotal':
77
+ $this->subtotal = floatval( $this->_cart_content['subtotal'] );
78
+ break;
79
+ case 'total':
80
+ $this->total = floatval( $this->_cart_content['total'] );
81
+ }
82
+ }
83
+ if ( isset( $this->{$key} ) ) {
84
+ $return = $this->{$key};
85
+ }
86
+ return $return;
87
+ }
88
+
89
+ public function maybe_set_cart_cookies() {
90
+ if ( !headers_sent()/* && did_action( 'wp_loaded' )*/ ) {
91
+ $this->set_cart_cookies( !$this->is_empty() );
92
+ }
93
+ }
94
+
95
+ private function set_cart_cookies( $set = true ) {
96
+ if ( $set ) {
97
+ learn_press_setcookie( 'learn_press_items_in_cart', 1 );
98
+ $this->get_cart_for_session();
99
+ } elseif ( isset( $_COOKIE['learn_press_items_in_cart'] ) ) {
100
+ learn_press_setcookie( 'learn_press_items_in_cart', 0, time() - HOUR_IN_SECONDS );
101
+ }
102
+ do_action( 'learn_press_set_cart_cookies', $set );
103
+ }
104
+
105
+ public function get_cart_for_session() {
106
+ $cart_session = array();
107
+
108
+ if ( $this->get_cart() ) {
109
+ foreach ( $this->get_cart() as $key => $values ) {
110
+ $cart_session[$key] = $values;
111
+ unset( $cart_session[$key]['data'] ); // Unset product object
112
+ }
113
+ }
114
+
115
+ return $cart_session;
116
+ }
117
+
118
+ public function get_cart() {
119
+ if ( !did_action( 'wp_loaded' ) ) {
120
+ _doing_it_wrong( __FUNCTION__, __( 'Get cart should not be called before the wp_loaded action.', 'learnpress' ), '2.3' );
121
+ }
122
+ if ( !did_action( 'learn_press_cart_loaded_from_session' ) ) {
123
+ $this->get_cart_from_session();
124
+ }
125
+ return array_filter( (array) $this->_cart_content );
126
+ }
127
+
128
+ /**
129
+ * Add course to cart
130
+ *
131
+ * @param int $course_id
132
+ * @param int $quantity
133
+ * @param array
134
+ */
135
+ public function add_to_cart( $course_id, $quantity = 1, $item_data = array() ) {
136
+
137
+ $course = learn_press_get_course( $course_id );
138
+ // course is not purchasable
139
+ if ( !$course->is_purchasable() ) {
140
+ learn_press_display_message( __( 'Sorry! This course is not purchasable.', 'learnpress' ) );
141
+ if ( $redirect = apply_filter( 'learn_press_course_is_not_purchasable_redirect', get_the_permalink( $course_id ), $course_id ) ) {
142
+ wp_redirect( $redirect );
143
+ exit();
144
+ }
145
+ return;
146
+ }
147
+
148
+ /**
149
+ * Generate course information and stores into session
150
+ * for redirection if needed then we can remove it immediately
151
+ */
152
+ $quantity = apply_filters( 'learn_press_purchase_course_quantity', $quantity, $course_id );
153
+ $price = $course->is_free() ? 0 : $course->get_price();
154
+ /*$course_info = apply_filters( 'learn_press_purchase_course_info', array(
155
+ 'item_id' => $course_id,
156
+ 'quantity' => $quantity,
157
+ 'subtotal' => $price * $quantity,
158
+ 'total' => $price * $quantity,
159
+ 'data' => apply_filters( 'learn_press_purchase_course_info_data', $_REQUEST )
160
+ )
161
+ );*/
162
+
163
+ $this->_cart_content['items'][$course_id] = apply_filters( 'learn_press_add_cart_item', array(
164
+ 'item_id' => $course_id,
165
+ 'quantity' => $quantity,
166
+ 'subtotal' => $price * $quantity,
167
+ 'total' => $price * $quantity,
168
+ 'data' => $item_data
169
+ )
170
+ );
171
+
172
+ if ( did_action( 'wp' ) ) {
173
+ $this->set_cart_cookies( true );
174
+ }
175
+
176
+ do_action( 'learn_press_add_to_cart', $course_id, $quantity, $item_data, $this );
177
+
178
+ return;
179
+
180
+ if ( !learn_press_is_enable_cart() ) {
181
+ $this->empty_cart();
182
+ }
183
+ $course = learn_press_get_course( $course_id );
184
+
185
+ /*
186
+ if ( !empty( $this->_cart_content['items'][$course_id] ) ) {
187
+ $quantity += $this->_cart_content['items'][$course_id]['quantity'];
188
+ }*/
189
+ if ( !$course->is_purchasable() ) {
190
+ learn_press_add_message( __( 'Sorry! This course is not purchasable.', 'learnpress' ) );
191
+ wp_redirect( get_the_permalink( $course_id ) );
192
+ exit();
193
+ }
194
+
195
+ $quantity = 1;
196
+ $price = $course->is_free() ? 0 : $course->get_price();
197
+ $this->_cart_content['items'][$course_id] = apply_filters( 'learn_press_add_cart_item', array(
198
+ 'item_id' => $course_id,
199
+ 'quantity' => $quantity,
200
+ 'subtotal' => $price * $quantity,
201
+ 'total' => $price * $quantity,
202
+ 'data' => $item_data
203
+ )
204
+ );
205
+
206
+ learn_press_session_set( $this->_cart_session_key, $this->_cart_content );
207
+
208
+ $this->set_cart_cookies( !$this->is_empty() );
209
+
210
+ do_action( 'learn_press_add_to_cart', $course_id, $quantity, $item_data, $this );
211
+ $button = '';
212
+
213
+ // if the course is FREE and no require checkout screen
214
+
215
+ /*
216
+ if ( LP()->settings->get( 'no_checkout_free_course' ) == 'yes' && $this->total == 0 ) {
217
+ if ( !is_user_logged_in() ) {
218
+ $redirect = learn_press_get_page_link( 'profile' );
219
+ if ( !$redirect ) {
220
+ $redirect = wp_login_url();
221
+ } else {
222
+ $redirect = add_query_arg( 'next', 'enroll-course', $redirect );
223
+ }
224
+ learn_press_add_message( __( 'Please login to continue process.', 'learnpress' ) );
225
+ $checkout_results['redirect'] = apply_filters( 'learn_press_no_checkout_free_course_redirect', $redirect );
226
+ } else {
227
+ add_filter( 'learn_press_checkout_success_result', '_learn_press_checkout_auto_enroll_free_course', 10, 2 );
228
+ $checkout_results = LP_Checkout::instance()->process_checkout();
229
+ }
230
+ $redirect = $checkout_results['redirect'];
231
+ // if ( is_lp_ajax() ) {
232
+ // learn_press_send_json(
233
+ // $checkout_results
234
+ // );
235
+ // } else {
236
+ // wp_redirect( $checkout_results['redirect'] );
237
+ // exit();
238
+ // }
239
+ }
240
+
241
+ else {
242
+
243
+ */
244
+
245
+ if ( learn_press_is_enable_cart() ) {
246
+ if ( LP()->settings->get( 'redirect_after_add' ) == 'yes' ) {
247
+ $redirect = learn_press_get_page_link( 'cart' );
248
+ if ( !$redirect ) {
249
+ learn_press_add_message( sprintf( __( 'Cart page is not setting up.', 'learnpress' ) ) );
250
+ $redirect = learn_press_get_current_url();
251
+ } else {
252
+ $button = sprintf( '<a href="%s">%s</a>', get_the_permalink( $course_id ), __( 'Back to class', 'learnpress' ) );
253
+ }
254
+ } else {
255
+ $redirect = get_the_permalink( $course_id );
256
+ if ( !learn_press_get_page_link( 'cart' ) ) {
257
+ learn_press_add_message( sprintf( __( 'Checkout page is not setting up.', 'learnpress' ) ) );
258
+ } else {
259
+ $button = sprintf( '<a href="%s">%s</a>', learn_press_get_page_link( 'cart' ), __( 'View cart', 'learnpress' ) );
260
+ }
261
+ }
262
+ learn_press_add_message( sprintf( __( '<strong>%s</strong> has been added to your cart. %s', 'learnpress' ), get_the_title( $course_id ), $button ) );
263
+
264
+ } else {
265
+ $redirect = learn_press_get_page_link( 'checkout' );
266
+ if ( !$redirect ) {
267
+ learn_press_add_message( sprintf( __( 'Checkout page is not setting up.', 'learnpress' ) ) );
268
+ $redirect = learn_press_get_current_url();
269
+ }
270
+ }
271
+
272
+ /*
273
+ }
274
+ */
275
+
276
+ $redirect = apply_filters( 'learn_press_add_to_cart_redirect', $redirect, $course_id );
277
+
278
+ if ( learn_press_is_ajax() ) {
279
+ learn_press_send_json(
280
+ array(
281
+ 'redirect' => $redirect,
282
+ 'result' => 'success',
283
+ 'messages' => learn_press_get_notices( true )
284
+ )
285
+ );
286
+ } else {
287
+ wp_redirect( $redirect );
288
+ die();
289
+ }
290
+ }
291
+
292
+ /**
293
+ * Checks to see if there is an item in cart
294
+ *
295
+ * @param $item_id
296
+ *
297
+ * @return bool
298
+ */
299
+ public function has_item( $item_id ) {
300
+ return isset( $this->_cart_content['items'][$item_id] );
301
+ }
302
+
303
+ /**
304
+ * Get an item in cart
305
+ *
306
+ * @param $item_id
307
+ *
308
+ * @return bool
309
+ */
310
+ public function get_item( $item_id ) {
311
+ return $this->has_item( $item_id ) ? $this->_cart_content['items'][$item_id] : null;
312
+ }
313
+
314
+ /**
315
+ * Remove an item from cart
316
+ *
317
+ * @param $item_id
318
+ *
319
+ * @return bool
320
+ */
321
+ public function remove_item( $item_id ) {
322
+ if ( isset( $this->_cart_content['items'][$item_id] ) ) {
323
+
324
+ do_action( 'learn_press_remove_cart_item', $item_id, $this );
325
+
326
+ unset( $this->_cart_content['items'][$item_id] );
327
+
328
+ do_action( 'learn_press_cart_item_removed', $item_id, $this );
329
+
330
+ $this->calculate_totals();
331
+
332
+ return true;
333
+ }
334
+
335
+ return false;
336
+ }
337
+
338
+ /**
339
+ * Re-calculate cart totals and update data to session
340
+ */
341
+ public function calculate_totals() {
342
+ $subtotal = 0;
343
+
344
+ if ( !empty( $this->_cart_content['items'] ) && $items = $this->_cart_content['items'] ) {
345
+ foreach ( $items as $item_id => $item ) {
346
+ $course = learn_press_get_course( $item_id );
347
+ if ( $course ) {
348
+ $_subtotal = $course->get_price() * $item['quantity'];
349
+ }
350
+ $this->_cart_content['items'][$item_id]['subtotal'] = $_subtotal;
351
+ $this->_cart_content['items'][$item_id]['total'] = $_subtotal;
352
+ $subtotal += $_subtotal;
353
+ }
354
+
355
+ }
356
+ $this->_cart_content['subtotal'] = $subtotal;
357
+ $this->_cart_content['total'] = $subtotal;
358
+ $this->update_session();
359
+ }
360
+
361
+ /**
362
+ * Update cart content to session
363
+ */
364
+ public function update_session() {
365
+ learn_press_session_set( $this->_cart_session_key, $this->_cart_content );
366
+ }
367
+
368
+ /**
369
+ * Get cart id
370
+ *
371
+ * @return mixed
372
+ */
373
+ public function get_cart_id() {
374
+ return !empty( $_SESSION['learn_press_cart']['cart_id'] ) ? $_SESSION['learn_press_cart']['cart_id'] : 0;
375
+ }
376
+
377
+ /**
378
+ * Get all items from cart
379
+ *
380
+ * @return mixed
381
+ */
382
+ public function get_items() {
383
+ if ( !did_action( 'learn_press_get_cart_from_session' ) ) {
384
+ $this->get_cart_from_session();
385
+ }
386
+ return !empty( $this->_cart_content['items'] ) ? $this->_cart_content['items'] : array();
387
+ }
388
+
389
+ /**
390
+ * Load cart content data from session
391
+ *
392
+ * @param bool $force
393
+ */
394
+ public function get_cart_from_session( $force = false ) {
395
+ if ( !did_action( 'learn_press_get_cart_from_session' ) || $force ) {
396
+ $this->_cart_content = learn_press_session_get( $this->_cart_session_key );
397
+ do_action( 'learn_press_get_cart_from_session' );
398
+ }
399
+ }
400
+
401
+ /**
402
+ * Get cart sub-total
403
+ *
404
+ * @return mixed
405
+ */
406
+ public function get_subtotal() {
407
+
408
+ $subtotal = learn_press_format_price( $this->_cart_content['subtotal'], true );
409
+ return apply_filters( 'learn_press_get_cart_subtotal', $subtotal, $this->get_cart_id() );
410
+ }
411
+
412
+ /**
413
+ * Get cart total
414
+ *
415
+ * @return mixed
416
+ */
417
+ public function get_total() {
418
+ $subtotal = $this->get_subtotal();
419
+ $total = $subtotal;
420
+ return apply_filters( 'learn_press_get_cart_total', $total, $this->get_cart_id() );
421
+ }
422
+
423
+ /**
424
+ * Generate unique cart id
425
+ *
426
+ * @return string
427
+ */
428
+ public function generate_cart_id() {
429
+ return md5( time() );
430
+ }
431
+
432
+ /**
433
+ * Return sub-total of cart content
434
+ *
435
+ * @param $course
436
+ * @param int $quantity
437
+ *
438
+ * @return mixed|void
439
+ */
440
+ public function get_item_subtotal( $course, $quantity = 1 ) {
441
+ $price = $course->get_price();
442
+ $row_price = $price * $quantity;
443
+ $course_subtotal = learn_press_format_price( $row_price, true );
444
+ return apply_filters( 'learn_press_cart_item_subtotal', $course_subtotal, $course, $quantity, $this );
445
+ }
446
+
447
+ /**
448
+ * Clean all items from cart
449
+ *
450
+ * @return $this
451
+ */
452
+ public function empty_cart() {
453
+
454
+ do_action( 'learn_press_before_empty_cart' );
455
+
456
+ learn_press_session_set( $this->_cart_session_key, $this->get_default_cart_content() );
457
+
458
+ $this->get_cart_from_session( true );
459
+
460
+ do_action( 'learn_press_emptied_cart' );
461
+
462
+ return $this;
463
+ }
464
+
465
+ /**
466
+ * Check if cart is empty or not
467
+ *
468
+ * @return bool
469
+ */
470
+ public function is_empty() {
471
+ return sizeof( $this->get_items() ) === 0; //!$this->_cart_content['items'];
472
+ }
473
+
474
+ /**
475
+ * Return cart content
476
+ *
477
+ * @return array|mixed|void
478
+ */
479
+ public function get_cart_content() {
480
+ return $this->_cart_content;
481
+ }
482
+
483
+ public function get_default_cart_content() {
484
+ return apply_filters( 'learn_press_default_cart_content', array(
485
+ 'items' => array(),
486
+ 'subtotal' => 0,
487
+ 'total' => 0
488
+ )
489
+ );
490
+ }
491
+
492
+ /**
493
+ * Get checkout url for checkout page
494
+ * Return default url of checkout page
495
+ *
496
+ * @return mixed
497
+ */
498
+ public function get_checkout_url() {
499
+ $checkout_url = learn_press_get_page_link( 'checkout' );
500
+ return apply_filters( 'learn_press_get_checkout_url', $checkout_url );
501
+ }
502
+
503
+ /**
504
+ * Checks if need to payment
505
+ * Return true if cart total greater than 0
506
+ *
507
+ * @return mixed|void
508
+ */
509
+ public function needs_payment() {
510
+ return apply_filters( 'learn_press_cart_needs_payment', $this->total > 0, $this );
511
+ }
512
+
513
+ /**
514
+ * Process action for purchase course button
515
+ *
516
+ * @param $course_id
517
+ */
518
+ public function purchase_course_handler( $course_id ) {
519
+
520
+ do_action( 'learn_press_before_purchase_course_handler', $course_id, $this );
521
+
522
+ if ( apply_filters( 'learn_press_purchase_single_course', true ) ) {
523
+ $this->empty_cart();
524
+ }
525
+ $this->add_to_cart( $course_id, 1, $_POST );
526
+ $redirect = learn_press_get_checkout_url();
527
+ $has_checkout = $redirect ? true : false;
528
+ $need_checkout = $this->needs_payment();
529
+
530
+ // In case the course is FREE and "No checkout free course" is turn off
531
+ if ( !$need_checkout ) {
532
+ $user = learn_press_get_current_user();
533
+ if ( !$user->has_purchased_course( $course_id )/* || $user->has_finished_course( $course_id ) */ ) {
534
+ require_once LP_PLUGIN_PATH . '/inc/gateways/class-lp-gateway-none.php';
535
+ $checkout = learn_press_get_checkout( array( 'payment_method' => new LP_Gateway_None() ) );
536
+
537
+ /**
538
+ * + Auto enroll
539
+ */
540
+ add_filter( 'learn_press_checkout_success_result', '_learn_press_checkout_success_result', 10, 2 );
541
+ $results = $checkout->process_checkout();
542
+ remove_filter( 'learn_press_checkout_success_result', '_learn_press_checkout_success_result', 10 );
543
+ }/* else {
544
+ if ( $user->has_finished_course( $course_id ) ) {
545
+ learn_press_add_message( __( 'You have already finished course', 'learnpress' ) );
546
+ } else {
547
+ learn_press_add_message( __( 'You have already enrolled course', 'learnpress' ) );
548
+ }
549
+ }*/
550
+ } else {
551
+
552
+ // Checkout page is not setting up
553
+ if ( !$has_checkout ) {
554
+ learn_press_add_message( __( 'Checkout page is not setup', 'learnpress' ), 'error' );
555
+ } else {
556
+ wp_redirect( apply_filters( 'learn_press_checkout_redirect', $redirect ) );
557
+ exit();
558
+ }
559
+
560
+ }
561
+ return;
562
+ }
563
+
564
+ /**
565
+ * Destroy cart instance
566
+ */
567
+ public function destroy() {
568
+
569
+ }
570
+
571
+
572
+ /**
573
+ * Get unique instance of LP_Cart object
574
+ *
575
+ * @return LP_Cart|mixed
576
+ */
577
+ public static function instance() {
578
+ if ( !self::$instance ) {
579
+ self::$instance = new self();
580
+ }
581
+ return self::$instance;
582
+ }
583
+ }
584
+
585
+ /**
586
+ * Return LP_Cart object instance
587
+ *
588
+ * @return mixed
589
+ */
590
+ function learn_press_get_cart() {
591
+ return LP()->cart;
592
+ }
593
+
594
+ /**
595
+ * Get description for cart by join all item titles into one
596
+ *
597
+ * @return string
598
+ */
599
+ function learn_press_get_cart_description() {
600
+ $items = LP()->cart->get_items();
601
+ $description = array();
602
+ if ( $items ) {
603
+ foreach ( $items as $item ) {
604
+ $description[] = apply_filters( 'learn_press_cart_item_description', get_the_title( $item['item_id'] ) );
605
+ }
606
+ }
607
+ return apply_filters( 'learn_press_cart_description', join( ', ', $description ) );
608
+ }
609
+
610
+ function learn_press_get_cart_course_url() {
611
+ $products = learn_press_get_cart( 'products' );
612
+ $return = '';
613
+ if ( $products ) {
614
+ foreach ( $products as $prop ) {
615
+ $return = get_permalink( $prop['id'] );
616
+ break;
617
+ }
618
+ }
619
+ return apply_filters( 'learn_press_cart_course_url', $return );
620
+ }
621
+
622
+ /**
623
+ * Return total of cart
624
+ *
625
+ * @return mixed
626
+ */
627
+ function learn_press_get_cart_total() {
628
+ return LP()->cart->total;
629
+ }
630
+
631
+
632
+ function learn_press_clear_cart_after_payment() {
633
+ global $wp;
634
+
635
+ if ( !empty( $wp->query_vars['lp-order-received'] ) ) {
636
+
637
+ $order_id = absint( $wp->query_vars['lp-order-received'] );
638
+ $order_key = isset( $_GET['key'] ) ? $_GET['key'] : '';
639
+
640
+ if ( $order_id > 0 && ( $order = learn_press_get_order( $order_id ) ) ) {
641
+ if ( $order->order_key === $order_key ) {
642
+ LP()->cart->empty_cart();
643
+ }
644
+ }
645
+ }
646
+
647
+ if ( LP()->session->order_awaiting_payment > 0 ) {
648
+ $order = learn_press_get_order( LP()->session->order_awaiting_payment );
649
+
650
+ if ( $order && $order->id > 0 ) {
651
+ if ( !$order->has_status( array( 'failed', 'pending', 'cancelled' ) ) ) {
652
+ LP()->cart->empty_cart();
653
+ LP()->session->order_awaiting_payment = null;
654
+ }
655
+ }
656
+ }
657
+ }
658
+
659
+ add_action( 'get_header', 'learn_press_clear_cart_after_payment' );
660
+
661
+
662
+
663
+
664
  //learn_press_get_cart_description();
inc/class-lp-ajax.php CHANGED
@@ -1,625 +1,656 @@
1
- <?php
2
-
3
- if ( !defined( 'ABSPATH' ) ) {
4
- exit; // Exit if accessed directly
5
- }
6
-
7
- if ( !class_exists( 'LP_AJAX' ) ) {
8
- /**
9
- * Class LP_AJAX
10
- */
11
- class LP_AJAX {
12
- /**
13
- * Init common ajax events
14
- */
15
- public static function init() {
16
- $ajaxEvents = array(
17
- 'load_quiz_question' => true,
18
- 'load_prev_question' => false,
19
- 'load_next_question' => false,
20
- 'finish_quiz' => true,
21
- 'retake_quiz' => true, // anonymous user can retake quiz
22
- 'take_free_course' => false,
23
- 'load_lesson_content' => false,
24
- 'load_next_lesson' => false,
25
- 'load_prev_lesson' => false,
26
- 'finish_course' => false,
27
- 'not_going' => false,
28
- 'take_course' => true,
29
- 'start_quiz' => true,
30
- 'fetch_question' => true
31
- );
32
-
33
- foreach ( $ajaxEvents as $ajax_event => $nopriv ) {
34
- add_action( 'wp_ajax_learnpress_' . $ajax_event, array( __CLASS__, $ajax_event ) );
35
-
36
- if ( $nopriv ) {
37
- add_action( 'wp_ajax_nopriv_learnpress_' . $ajax_event, array( __CLASS__, $ajax_event ) );
38
- }
39
- }
40
-
41
- LP_Request_Handler::register( 'lp-ajax', array( __CLASS__, 'do_ajax' ) );
42
- }
43
-
44
- /**
45
- * Do ajax if there is a 'lp-ajax' in $_REQUEST
46
- *
47
- * @param $var
48
- */
49
- public static function do_ajax( $var ) {
50
- if ( !defined( 'LP_DOING_AJAX' ) ) {
51
- define( 'LP_DOING_AJAX', true );
52
- }
53
- LP_Gateways::instance()->get_available_payment_gateways();
54
- $result = false;
55
- $method = preg_replace( '/[-]+/', '_', $var );
56
- $callback = array( __CLASS__, '_request_' . $method );
57
- if ( is_callable( $callback ) ) {
58
- $result = call_user_func( $callback );
59
- } elseif ( has_action( 'learn_press_ajax_handler_' . $var ) ) {
60
- do_action( 'learn_press_ajax_handler_' . $var );
61
- return;
62
- }
63
- if ( learn_press_get_request( 'format' ) == 'html' ) {
64
- return;
65
- }
66
- learn_press_send_json( $result );
67
- }
68
-
69
- /**
70
- * Become a teacher
71
- */
72
- public static function _request_become_a_teacher() {
73
- $response = learn_press_process_become_a_teacher_form(
74
- array(
75
- 'name' => learn_press_get_request( 'bat_name' ),
76
- 'email' => learn_press_get_request( 'bat_email' ),
77
- 'phone' => learn_press_get_request( 'bat_phone' )
78
- )
79
- );
80
- learn_press_send_json( $response );
81
- }
82
-
83
- /**
84
- * Checkout process
85
- *
86
- * @return array|mixed|void
87
- */
88
- public static function _request_checkout() {
89
- return LP()->checkout->process_checkout_handler();
90
- }
91
-
92
- /**
93
- * Enroll course
94
- *
95
- * @return bool
96
- * @throws Exception
97
- */
98
- public static function _request_enroll_course() {
99
- $course_id = learn_press_get_request( 'enroll-course' );
100
- if ( !$course_id ) {
101
- throw new Exception( __( 'Invalid course', 'learnpress' ) );
102
- }
103
- $insert_id = LP()->user->enroll( $course_id );
104
-
105
- $response = array(
106
- 'result' => 'fail',
107
- 'redirect' => apply_filters( 'learn_press_enroll_course_failure_redirect_url', get_the_permalink( $course_id ) )
108
- );
109
-
110
- if ( $insert_id ) {
111
- $response['result'] = 'success';
112
- $response['redirect'] = apply_filters( 'learn_press_enrolled_course_redirect_url', get_the_permalink( $course_id ) );
113
- $message = apply_filters( 'learn_press_enrolled_course_message', sprintf( __( 'You have enrolled in this course <strong>%s</strong>', 'learnpress' ), get_the_title( $course_id ) ), $course_id, LP()->user->id );
114
- learn_press_add_message( $message );
115
- } else {
116
- $message = apply_filters( 'learn_press_enroll_course_failed_message', sprintf( __( 'Sorry! The course <strong>%s</strong> you want to enroll has failed! Please contact site\'s administrator for more information.', 'learnpress' ), get_the_title( $course_id ) ), $course_id, LP()->user->id );
117
- learn_press_add_message( $message, 'error' );
118
- }
119
- if ( learn_press_is_ajax() ) {
120
- learn_press_send_json( $response );
121
- }
122
-
123
- if ( $response['redirect'] ) {
124
- wp_redirect( $response['redirect'] );
125
- exit();
126
- }
127
- return false;
128
- }
129
-
130
- /**
131
- * Request login in checkout process
132
- *
133
- * @return array
134
- */
135
- public static function _request_checkout_login() {
136
- $result = array(
137
- 'result' => 'success'
138
- );
139
- ob_start();
140
- if ( empty( $_REQUEST['user_login'] ) ) {
141
- $result['result'] = 'fail';
142
- learn_press_add_message( __( 'Please enter username', 'learnpress' ), 'error' );
143
- }
144
- if ( empty( $_REQUEST['user_password'] ) ) {
145
- $result['result'] = 'fail';
146
- learn_press_add_message( __( 'Please enter password', 'learnpress' ), 'error' );
147
- }
148
- if ( $result['result'] == 'success' ) {
149
- $creds = array();
150
- $creds['user_login'] = $_REQUEST['user_login'];
151
- $creds['user_password'] = $_REQUEST['user_password'];
152
- $creds['remember'] = true;
153
- $user = wp_signon( $creds, false );
154
- if ( is_wp_error( $user ) ) {
155
- $result['result'] = 'fail';
156
- learn_press_add_message( $user->get_error_message(), 'error' );
157
- } else {
158
- $result['redirect'] = learn_press_get_page_link( 'checkout' );
159
- }
160
- }
161
- learn_press_print_notices();
162
- $messages = ob_get_clean();
163
- if ( $result['result'] == 'fail' ) {
164
- $result['messages'] = $messages;
165
- }
166
- return $result;
167
- }
168
-
169
- /**
170
- * Request login in profile
171
- */
172
- public static function _request_login() {
173
- $data_str = learn_press_get_request( 'data' );
174
- $data = null;
175
- if ( $data_str ) {
176
- parse_str( $data_str, $data );
177
- }
178
-
179
- $user = wp_signon(
180
- array(
181
- 'user_login' => $data['log'],
182
- 'user_password' => $data['pwd'],
183
- 'remember' => isset( $data['rememberme'] ) ? $data['rememberme'] : false,
184
- ),
185
- is_ssl()
186
- );
187
-
188
- $error = is_wp_error( $user );
189
- $return = array(
190
- 'result' => $error ? 'error' : 'success',
191
- 'redirect' => ( !$error && !empty( $data['redirect_to'] ) ) ? $data['redirect_to'] : ''
192
- );
193
- if ( $error ) {
194
- $return['message'] = learn_press_get_message( $user->get_error_message() ? $user->get_error_message() : __( 'Please enter your username and/or password', 'learnpress' ) );
195
- } else {
196
- wp_set_current_user( $user->ID );
197
- $next = learn_press_get_request( 'next' );
198
- if ( $next == 'enroll-course' ) {
199
- $user = new LP_User( $user->ID );
200
- $checkout = false;
201
- if ( $cart_items = LP()->cart->get_items() ) {
202
- foreach ( $cart_items as $item ) {
203
- if ( $user->has_enrolled_course( $item['item_id'] ) ) {
204
- $checkout = $item['item_id'];
205
- } elseif ( $user->has_purchased_course( $item['item_id'] ) ) {
206
- $checkout = $item['item_id'];
207
- $user->enroll( $item['item_id'] );
208
- }
209
- if ( $checkout ) {
210
- LP()->cart->remove_item( $checkout );
211
- $return['redirect'] = get_the_permalink( $checkout );
212
- learn_press_add_message( sprintf( __( 'Welcome back, %s. You\'ve already enrolled this course', 'learnpress' ), $user->user->display_name ) );
213
- break;
214
- }
215
- }
216
- }
217
- if ( $checkout === false ) {
218
- add_filter( 'learn_press_checkout_success_result', '_learn_press_checkout_auto_enroll_free_course', 10, 2 );
219
- $checkout = LP()->checkout()->process_checkout();
220
- } else {
221
- }
222
- return;
223
- }
224
- $return['message'] = learn_press_get_message( sprintf( __( 'Welcome back, %s! Redirecting...', 'learnpress' ), learn_press_get_profile_display_name( $user ) ) );
225
- }
226
- learn_press_send_json( $return );
227
- }
228
-
229
- /**
230
- * Request add-to-cart a course
231
- */
232
- public static function _request_add_to_cart() {
233
- $cart = learn_press_get_cart();
234
- $course_id = learn_press_get_request( 'purchase-course' );
235
-
236
- $cart->add_to_cart( $course_id );
237
- $return = array(
238
- 'result' => 'success',
239
- 'redirect' => learn_press_get_checkout_url()
240
- );
241
- if ( learn_press_is_ajax() ) {
242
- learn_press_send_json( $return );
243
- } else {
244
- wp_redirect( $return['redirect'] );
245
- }
246
- }
247
-
248
- /**
249
- * Request finish course
250
- */
251
- public static function _request_finish_course() {
252
- $nonce = learn_press_get_request( 'security' );
253
- $course_id = absint( learn_press_get_request( 'id' ) );
254
- $user = learn_press_get_current_user();
255
-
256
- $course = LP_Course::get_course( $course_id );
257
-
258
- $nonce_action = sprintf( 'learn-press-finish-course-%d-%d', $course_id, $user->id );
259
- if ( !$user->id || !$course || !wp_verify_nonce( $nonce, $nonce_action ) ) {
260
- wp_die( __( 'Access denied!', 'learnpress' ) );
261
- }
262
-
263
- $finished = $user->finish_course( $course_id );
264
-
265
- $response = array();
266
-
267
- if ( $finished ) {
268
- learn_press_add_message( sprintf( __( 'You have finished this course "%s"', 'learnpress' ), $course->get_title() ) );
269
- $response['redirect'] = get_the_permalink( $course_id );
270
-
271
- $response['result'] = 'success';
272
- } else {
273
- $response['message'] = __( 'Error! You cannot finish this course. Please contact your administrator for more information.', 'learnpress' );
274
- $response['result'] = 'error';
275
- }
276
-
277
- learn_press_send_json( $response );
278
- }
279
-
280
- /**
281
- * Request complete an item
282
- */
283
- public static function _request_complete_item() {
284
- $user = learn_press_get_current_user();
285
- $id = learn_press_get_request( 'id' );
286
- $course_id = !empty( $_REQUEST['course_id'] ) ? $_REQUEST['course_id'] : get_the_ID();
287
- $type = learn_press_get_request( 'type' );
288
- $security = learn_press_get_request( 'security' );
289
- $response = array();
290
- if ( !wp_verify_nonce( $security, sprintf( 'complete-item-%d-%d-%d', $user->id, $course_id, $id ) ) ) {
291
- $response['result'] = 'fail';
292
- $response['message'] = __( 'Bad request!', 'learnpress' );
293
- } else {
294
- if ( $type == 'lp_lesson' ) {
295
- $results = $user->complete_lesson( $id, $course_id );
296
- if ( is_wp_error( $results ) ) {
297
- learn_press_add_message( __( 'Error while completing lesson.', 'learnpress' ) );
298
- } elseif ( $results !== false ) {
299
- learn_press_add_message( __( 'You have completed lesson.', 'learnpress' ) );
300
- }
301
- } else {
302
- do_action( 'learn_press_user_request_complete_item', $_REQUEST );
303
- }
304
- }
305
- wp_redirect( learn_press_get_current_url() );
306
- die();
307
- }
308
-
309
- /**
310
- * Request load item content
311
- */
312
- public static function _request_load_item() {
313
- global $wpdb;
314
- $user = learn_press_get_current_user();
315
- $item_id = learn_press_get_request( 'id' );
316
- $course_id = get_the_ID();
317
- // Ensure that user can view course item
318
- $can_view_item = $user->can( 'view-item', $item_id, $course_id );
319
- if ( $can_view_item ) {
320
- // Update user item if it's not updated
321
- if ( !$user->get_item_status( $item_id, $course_id ) ) {
322
- $item_type = learn_press_get_request( 'type' );
323
- if ( !$item_type ) {
324
- $item_type = get_post_type( $item_id );
325
- }
326
- if ( apply_filters( 'learn_press_insert_user_item_data', true, $item_id, $course_id ) && $can_view_item != 'preview' ) {
327
- $insert = $wpdb->insert(
328
- $wpdb->prefix . 'learnpress_user_items',
329
- apply_filters(
330
- 'learn_press_user_item_data',
331
- array(
332
- 'user_id' => get_current_user_id(),
333
- 'item_id' => learn_press_get_request( 'id' ),
334
- 'item_type' => $item_type,
335
- 'start_time' => $item_type == 'lp_lesson' ? current_time( 'mysql' ) : '0000-00-00 00:00:00',
336
- 'end_time' => '0000-00-00 00:00:00',
337
- 'status' => $item_type == 'lp_lesson' ? 'started' : 'viewed',
338
- 'ref_id' => $course_id,
339
- 'ref_type' => 'lp_course',
340
- 'parent_id' => $user->get_course_history_id( $course_id )
341
- )
342
- ),
343
- array(
344
- '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%s'
345
- )
346
- );
347
- print_r( $wpdb );
348
- $user_item_id = $wpdb->insert_id;
349
- }
350
- }
351
- // display content item
352
- learn_press_get_template( 'single-course/content-item.php' );
353
- } else {
354
- // display message
355
- learn_press_get_template( 'singe-course/content-protected.php' );
356
- }
357
- die();
358
- }
359
-
360
- /**
361
- * die();
362
- * Student take course
363
- * @return void
364
- */
365
- public static function take_course() {
366
- $payment_method = !empty( $_POST['payment_method'] ) ? $_POST['payment_method'] : '';
367
- $course_id = !empty( $_POST['course_id'] ) ? intval( $_POST['course_id'] ) : false;
368
- do_action( 'learn_press_take_course', $course_id, $payment_method );
369
- }
370
-
371
- /**
372
- * Load quiz question
373
- */
374
- public static function load_quiz_question() {
375
- $quiz_id = !empty( $_REQUEST['quiz_id'] ) ? absint( $_REQUEST['quiz_id'] ) : 0;
376
- $question_id = !empty( $_REQUEST['question_id'] ) ? absint( $_REQUEST['question_id'] ) : 0;
377
- $user_id = !empty( $_REQUEST['user_id'] ) ? absint( $_REQUEST['user_id'] ) : 0;
378
- global $quiz;
379
- $quiz = LP_Quiz::get_quiz( $quiz_id );
380
- LP()->quiz = $quiz;
381
- do_action( 'learn_press_load_quiz_question', $question_id, $quiz_id, $user_id );
382
- $user = learn_press_get_current_user();
383
- if ( $user->id != $user_id ) {
384
- learn_press_send_json(
385
- array(
386
- 'result' => 'error',
387
- 'message' => __( 'Load question error. Try again!', 'learnpress' )
388
- )
389
- );
390
- }
391
- if ( !$quiz_id || !$question_id ) {
392
- learn_press_send_json(
393
- array(
394
- 'result' => 'error',
395
- 'message' => __( 'Something is wrong. Try again!', 'learnpress' )
396
- )
397
- );
398
- }
399
- if ( $question = LP_Question_Factory::get_question( $question_id ) ) {
400
- $quiz->current_question = $question;
401
-
402
- ob_start();
403
- if ( $progress = $user->get_quiz_progress( $quiz->id ) ) {
404
- learn_press_update_user_quiz_meta( $progress->history_id, 'current_question', $question_id );
405
- }
406
- $question_answers = $user->get_question_answers( $quiz->id, $question_id );
407
- $question->render( array( 'answered' => $question_answers ) );
408
-
409
- $content = ob_get_clean();
410
- learn_press_send_json(
411
- apply_filters( 'learn_press_load_quiz_question_result_data', array(
412
- 'result' => 'success',
413
- 'permalink' => learn_press_get_user_question_url( $quiz_id, $question_id ),
414
- 'question' => array(
415
- 'content' => $content
416
- )
417
- )
418
- )
419
- );
420
- }
421
- }
422
-
423
- /**
424
- * Finish quiz
425
- */
426
- public static function finish_quiz() {
427
- $user = learn_press_get_current_user();
428
- $quiz_id = learn_press_get_request( 'quiz_id' );
429
- $user->finish_quiz( $quiz_id );
430
- $response = array(
431
- 'redirect' => get_the_permalink( $quiz_id )
432
- );
433
- learn_press_send_json( $response );
434
- }
435
-
436
- /**
437
- * Retake a quiz
438
- */
439
- public static function retake_quiz() {
440
- die( __FUNCTION__ );
441
- // verify nonce
442
- if ( !wp_verify_nonce( learn_press_get_request( 'nonce' ), 'retake-quiz' ) ) {
443
- learn_press_send_json(
444
- array(
445
- 'result' => 'fail',
446
- 'message' => __( 'Something went wrong. Please try again!', 'learnpress' )
447
- )
448
- );
449
- }
450
- $quiz_id = learn_press_get_request( 'quiz_id' );
451
- $user = learn_press_get_current_user();
452
- $response = $user->retake_quiz( $quiz_id );
453
- learn_press_send_json( $response );
454
- }
455
-
456
- /**
457
- * Load lesson content
458
- */
459
- public static function load_lesson_content() {
460
- learn_press_debug( $_REQUEST );
461
- global $post;
462
- $lesson_id = $_POST['lesson_id'];
463
- $title = get_the_title( $lesson_id );
464
- $post = get_post( $lesson_id );
465
- $content = $post->post_content;
466
- $content = apply_filters( 'the_content', $content );
467
- printf(
468
- '<h3>%s</h3>
469
- %s
470
- <button class="complete-lesson-button">Complete Lesson</button>',
471
- $title,
472
- $content
473
- );
474
- die;
475
- }
476
-
477
- /**
478
- * Complete lesson
479
- */
480
- public static function complete_lesson() {
481
- $nonce = learn_press_get_request( 'nonce' );
482
- $item_id = learn_press_get_request( 'id' );
483
- $course_id = learn_press_get_request( 'course_id' );
484
- $post = get_post( $item_id );
485
- $user = learn_press_get_current_user();
486
- $course = LP_Course::get_course( $course_id );
487
- $response = array(
488
- 'result' => 'success'
489
- );
490
- $nonce_action = sprintf( 'learn-press-complete-%s-%d-%d-%d', $post->post_type, $post->ID, $course->id, $user->id );
491
- // security check
492
- if ( !$post || ( $post && !wp_verify_nonce( $nonce, $nonce_action ) ) ) {
493
- $response['result'] = 'error';
494
- $response['message'] = __( 'Error! Invalid lesson or security checked failure', 'learnpress' );
495
- }
496
-
497
- if ( $response['result'] == 'success' ) {
498
- $result = $user->complete_lesson( $item_id );
499
- if ( !is_wp_error( $result ) ) {
500
- $can_finish = $user->can_finish_course( $course_id );
501
- $response['button_text'] = '<span class="dashicons dashicons-yes"></span>' . __( 'Completed', 'learnpress' );
502
- $response['course_result'] = round( $result * 100, 0 );
503
- $response['can_finish'] = $can_finish;
504
- $response['next_item'] = $course->get_next_item( $item_id );
505
-
506
- ob_start();
507
- if ( $can_finish ) {
508
- learn_press_display_message( __( 'Congratulations! You have completed this lesson and you can finish course.', 'learnpress' ) );
509
- } else {
510
- learn_press_display_message( __( 'Congratulations! You have completed this lesson.', 'learnpress' ) );
511
- }
512
- $response['message'] = ob_get_clean();
513
- } else {
514
- ob_start();
515
- learn_press_display_message( $result->get_error_message() );
516
- $response['message'] = ob_get_clean();
517
- $response['result'] = 'fail';
518
- }
519
- }
520
- learn_press_send_json( $response );
521
- }
522
-
523
- /**
524
- * Retake course action
525
- */
526
- public static function _request_retake_course() {
527
- $security = learn_press_get_request( 'security' );
528
- $course_id = learn_press_get_request( 'course_id' );
529
- $user = learn_press_get_current_user();
530
- $course = LP_Course::get_course( $course_id );
531
- $response = array(
532
- 'result' => 'error'
533
- );
534
- $security_action = sprintf( 'learn-press-retake-course-%d-%d', $course->id, $user->id );
535
- // security check
536
- if ( !wp_verify_nonce( $security, $security_action ) ) {
537
- $response['message'] = __( 'Error! Invalid lesson or security checked failure', 'learnpress' );
538
- } else {
539
- if ( $user->can( 'retake-course', $course_id ) ) {
540
- if ( !$result = $user->retake_course( $course_id ) ) {
541
- $response['message'] = __( 'Error!', 'learnpress' );
542
- } else {
543
- learn_press_add_message( sprintf( __( 'You have retaken course "%s"', 'learnpress' ), $course->get_title() ) );
544
- $response['result'] = 'success';
545
- $response['redirect'] = apply_filters( 'learn_press_retake_course_redirect', add_query_arg( 'retaken-course', $course_id, get_the_permalink( $course_id ) ) );
546
- }
547
- } else {
548
- $result['message'] = __( 'Error! You can not retake course', 'learnpress' );
549
- }
550
- }
551
- learn_press_send_json( $response );
552
- }
553
-
554
- public static function start_quiz() {
555
- $quiz_id = !empty( $_REQUEST['quiz_id'] ) ? absint( $_REQUEST['quiz_id'] ) : 0;
556
- if ( !$quiz_id ) {
557
- learn_press_send_json(
558
- array(
559
- 'result' => 'error',
560
- 'message' => __( 'The quiz ID is empty', 'learnpress' )
561
- )
562
- );
563
- }
564
- global $quiz;
565
-
566
- $quiz = LP_Quiz::get_quiz( $quiz_id );
567
-
568
- if ( !$quiz->id || $quiz->id != $quiz_id ) {
569
- learn_press_send_json(
570
- array(
571
- 'result' => 'error',
572
- 'message' => __( 'Something is wrong! Please try again', 'learnpress' )
573
- )
574
- );
575
- }
576
- $user = learn_press_get_current_user();
577
- if ( $quiz->is_require_enrollment() && $user->is( 'guest' ) ) {
578
- learn_press_send_json(
579
- array(
580
- 'result' => 'error',
581
- 'message' => __( 'Please login to take this quiz', 'learnpress' )
582
- )
583
- );
584
- }
585
- $user->set_quiz( $quiz );
586
-
587
- switch ( strtolower( $user->get_quiz_status() ) ) {
588
- case 'completed':
589
- learn_press_send_json(
590
- array(
591
- 'result' => 'error',
592
- 'message' => __( 'You have completed this quiz', 'learnpress' ),
593
- 'data' => $user->get_quiz_result()
594
- )
595
- );
596
- break;
597
- case 'started':
598
- learn_press_send_json(
599
- array(
600
- 'result' => 'error',
601
- 'message' => __( 'You have started this quiz', 'learnpress' ),
602
- 'data' => array(
603
- 'status' => $user->get_quiz_status()
604
- )
605
- )
606
- );
607
- break;
608
- default:
609
- $result = $user->start_quiz();
610
- $current_question = !empty( $result['current_question'] ) ? $result['current_question'] : $user->get_current_question_id( $quiz_id );
611
- learn_press_send_json(
612
- array(
613
- 'result' => 'success',
614
- 'data' => $result,
615
- 'question_url' => learn_press_get_user_question_url( $quiz_id, $current_question ),
616
- 'question_content' => LP_Question_Factory::fetch_question_content( $current_question )
617
- )
618
- );
619
- }
620
- die();
621
- }
622
- }
623
- }
624
- // Call class
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
625
  LP_AJAX::init();
1
+ <?php
2
+
3
+ if ( !defined( 'ABSPATH' ) ) {
4
+ exit; // Exit if accessed directly
5
+ }
6
+
7
+ if ( !class_exists( 'LP_AJAX' ) ) {
8
+ /**
9
+ * Class LP_AJAX
10
+ */
11
+ class LP_AJAX {
12
+ /**
13
+ * Init common ajax events
14
+ */
15
+ public static function init() {
16
+ $ajaxEvents = array(
17
+ 'load_quiz_question' => true,
18
+ 'load_prev_question' => false,
19
+ 'load_next_question' => false,
20
+ 'finish_quiz' => true,
21
+ 'retake_quiz' => true, // anonymous user can retake quiz
22
+ 'take_free_course' => false,
23
+ 'load_lesson_content' => false,
24
+ 'load_next_lesson' => false,
25
+ 'load_prev_lesson' => false,
26
+ 'finish_course' => false,
27
+ 'not_going' => false,
28
+ 'take_course' => true,
29
+ 'start_quiz' => true,
30
+ 'fetch_question' => true,
31
+ 'upload-user-avatar' => false
32
+ );
33
+
34
+ foreach ( $ajaxEvents as $ajax_event => $nopriv ) {
35
+ $ajax_func = preg_replace( '/-/', '_', $ajax_event );
36
+ add_action( 'wp_ajax_learnpress_' . $ajax_event, array( __CLASS__, $ajax_func ) );
37
+
38
+ if ( $nopriv ) {
39
+ add_action( 'wp_ajax_nopriv_learnpress_' . $ajax_event, array( __CLASS__, $ajax_func ) );
40
+ }
41
+ }
42
+
43
+ LP_Request_Handler::register( 'lp-ajax', array( __CLASS__, 'do_ajax' ) );
44
+ }
45
+
46
+ /**
47
+ * Do ajax if there is a 'lp-ajax' in $_REQUEST
48
+ *
49
+ * @param $var
50
+ */
51
+ public static function do_ajax( $var ) {
52
+ if ( !defined( 'LP_DOING_AJAX' ) ) {
53
+ define( 'LP_DOING_AJAX', true );
54
+ }
55
+ LP_Gateways::instance()->get_available_payment_gateways();
56
+ $result = false;
57
+ $method = preg_replace( '/[-]+/', '_', $var );
58
+ $callback = array( __CLASS__, '_request_' . $method );
59
+ if ( is_callable( $callback ) ) {
60
+ $result = call_user_func( $callback );
61
+ } elseif ( has_action( 'learn_press_ajax_handler_' . $var ) ) {
62
+ do_action( 'learn_press_ajax_handler_' . $var );
63
+ return;
64
+ }
65
+ if ( learn_press_get_request( 'format' ) == 'html' ) {
66
+ return;
67
+ }
68
+ learn_press_send_json( $result );
69
+ }
70
+
71
+ public static function upload_user_avatar() {
72
+ $file = $_FILES['lp-upload-avatar'];
73
+ $upload_dir = learn_press_user_profile_picture_upload_dir();
74
+
75
+ add_filter( 'upload_dir', array( __CLASS__, '_user_avatar_upload_dir' ), 10000 );
76
+
77
+ $result = wp_handle_upload( $file,
78
+ array(
79
+ 'test_form' => false
80
+ )
81
+ );
82
+
83
+ remove_filter( 'upload_dir', array( __CLASS__, '_user_avatar_upload_dir' ), 10000 );
84
+ if ( is_array( $result ) ) {
85
+ $result['name'] = $upload_dir['subdir'] . '/' . basename( $result['file'] );
86
+ unset( $result['file'] );
87
+ } else {
88
+ $result = array(
89
+ 'error' => __( 'Upload profile avatar error.', 'learnpress' )
90
+ );
91
+ }
92
+ learn_press_send_json( $result );
93
+ }
94
+
95
+ public static function _user_avatar_upload_dir( $dir ) {
96
+ $dir = learn_press_user_profile_picture_upload_dir();
97
+ return $dir;
98
+ }
99
+
100
+ /**
101
+ * Become a teacher
102
+ */
103
+ public static function _request_become_a_teacher() {
104
+ $response = learn_press_process_become_a_teacher_form(
105
+ array(
106
+ 'name' => learn_press_get_request( 'bat_name' ),
107
+ 'email' => learn_press_get_request( 'bat_email' ),
108
+ 'phone' => learn_press_get_request( 'bat_phone' )
109
+ )
110
+ );
111
+ learn_press_send_json( $response );
112
+ }
113
+
114
+ /**
115
+ * Checkout process
116
+ *
117
+ * @return array|mixed|void
118
+ */
119
+ public static function _request_checkout() {
120
+ return LP()->checkout->process_checkout_handler();
121
+ }
122
+
123
+ /**
124
+ * Enroll course
125
+ *
126
+ * @return bool
127
+ * @throws Exception
128
+ */
129
+ public static function _request_enroll_course() {
130
+ $course_id = learn_press_get_request( 'enroll-course' );
131
+ if ( !$course_id ) {
132
+ throw new Exception( __( 'Invalid course', 'learnpress' ) );
133
+ }
134
+ $insert_id = LP()->user->enroll( $course_id );
135
+
136
+ $response = array(
137
+ 'result' => 'fail',
138
+ 'redirect' => apply_filters( 'learn_press_enroll_course_failure_redirect_url', get_the_permalink( $course_id ) )
139
+ );
140
+
141
+ if ( $insert_id ) {
142
+ $response['result'] = 'success';
143
+ $response['redirect'] = apply_filters( 'learn_press_enrolled_course_redirect_url', get_the_permalink( $course_id ) );
144
+ $message = apply_filters( 'learn_press_enrolled_course_message', sprintf( __( 'You have enrolled in this course <strong>%s</strong>', 'learnpress' ), get_the_title( $course_id ) ), $course_id, LP()->user->id );
145
+ learn_press_add_message( $message );
146
+ } else {
147
+ $message = apply_filters( 'learn_press_enroll_course_failed_message', sprintf( __( 'Sorry! The course <strong>%s</strong> you want to enroll has failed! Please contact site\'s administrator for more information.', 'learnpress' ), get_the_title( $course_id ) ), $course_id, LP()->user->id );
148
+ learn_press_add_message( $message, 'error' );
149
+ }
150
+ if ( learn_press_is_ajax() ) {
151
+ learn_press_send_json( $response );
152
+ }
153
+
154
+ if ( $response['redirect'] ) {
155
+ wp_redirect( $response['redirect'] );
156
+ exit();
157
+ }
158
+ return false;
159
+ }
160
+
161
+ /**
162
+ * Request login in checkout process
163
+ *
164
+ * @return array
165
+ */
166
+ public static function _request_checkout_login() {
167
+ $result = array(
168
+ 'result' => 'success'
169
+ );
170
+ ob_start();
171
+ if ( empty( $_REQUEST['user_login'] ) ) {
172
+ $result['result'] = 'fail';
173
+ learn_press_add_message( __( 'Please enter username', 'learnpress' ), 'error' );
174
+ }
175
+ if ( empty( $_REQUEST['user_password'] ) ) {
176
+ $result['result'] = 'fail';
177
+ learn_press_add_message( __( 'Please enter password', 'learnpress' ), 'error' );
178
+ }
179
+ if ( $result['result'] == 'success' ) {
180
+ $creds = array();
181
+ $creds['user_login'] = $_REQUEST['user_login'];
182
+ $creds['user_password'] = $_REQUEST['user_password'];
183
+ $creds['remember'] = true;
184
+ $user = wp_signon( $creds, false );
185
+ if ( is_wp_error( $user ) ) {
186
+ $result['result'] = 'fail';
187
+ learn_press_add_message( $user->get_error_message(), 'error' );
188
+ } else {
189
+ $result['redirect'] = learn_press_get_page_link( 'checkout' );
190
+ }
191
+ }
192
+ learn_press_print_notices();
193
+ $messages = ob_get_clean();
194
+ if ( $result['result'] == 'fail' ) {
195
+ $result['messages'] = $messages;
196
+ }
197
+ return $result;
198
+ }
199
+
200
+ /**
201
+ * Request login in profile
202
+ */
203
+ public static function _request_login() {
204
+ $data_str = learn_press_get_request( 'data' );
205
+ $data = null;
206
+ if ( $data_str ) {
207
+ parse_str( $data_str, $data );
208
+ }
209
+
210
+ $user = wp_signon(
211
+ array(
212
+ 'user_login' => $data['log'],
213
+ 'user_password' => $data['pwd'],
214
+ 'remember' => isset( $data['rememberme'] ) ? $data['rememberme'] : false,
215
+ ),
216
+ is_ssl()
217
+ );
218
+
219
+ $error = is_wp_error( $user );
220
+ $return = array(
221
+ 'result' => $error ? 'error' : 'success',
222
+ 'redirect' => ( !$error && !empty( $data['redirect_to'] ) ) ? $data['redirect_to'] : ''
223
+ );
224
+ if ( $error ) {
225
+ $return['message'] = learn_press_get_message( $user->get_error_message() ? $user->get_error_message() : __( 'Please enter your username and/or password', 'learnpress' ) );
226
+ } else {
227
+ wp_set_current_user( $user->ID );
228
+ $next = learn_press_get_request( 'next' );
229
+ if ( $next == 'enroll-course' ) {
230
+ $user = new LP_User( $user->ID );
231
+ $checkout = false;
232
+ if ( $cart_items = LP()->cart->get_items() ) {
233
+ foreach ( $cart_items as $item ) {
234
+ if ( $user->has_enrolled_course( $item['item_id'] ) ) {
235
+ $checkout = $item['item_id'];
236
+ } elseif ( $user->has_purchased_course( $item['item_id'] ) ) {
237
+ $checkout = $item['item_id'];
238
+ $user->enroll( $item['item_id'] );
239
+ }
240
+ if ( $checkout ) {
241
+ LP()->cart->remove_item( $checkout );
242
+ $return['redirect'] = get_the_permalink( $checkout );
243
+ learn_press_add_message( sprintf( __( 'Welcome back, %s. You\'ve already enrolled this course', 'learnpress' ), $user->user->display_name ) );
244
+ break;
245
+ }
246
+ }
247
+ }
248
+ if ( $checkout === false ) {
249
+ add_filter( 'learn_press_checkout_success_result', '_learn_press_checkout_auto_enroll_free_course', 10, 2 );
250
+ $checkout = LP()->checkout()->process_checkout();
251
+ } else {
252
+ }
253
+ return;
254
+ }
255
+ $return['message'] = learn_press_get_message( sprintf( __( 'Welcome back, %s! Redirecting...', 'learnpress' ), learn_press_get_profile_display_name( $user ) ) );
256
+ }
257
+ learn_press_send_json( $return );
258
+ }
259
+
260
+ /**
261
+ * Request add-to-cart a course
262
+ */
263
+ public static function _request_add_to_cart() {
264
+ $cart = learn_press_get_cart();
265
+ $course_id = learn_press_get_request( 'purchase-course' );
266
+
267
+ $cart->add_to_cart( $course_id );
268
+ $return = array(
269
+ 'result' => 'success',
270
+ 'redirect' => learn_press_get_checkout_url()
271
+ );
272
+ if ( learn_press_is_ajax() ) {
273
+ learn_press_send_json( $return );
274
+ } else {
275
+ wp_redirect( $return['redirect'] );
276
+ }
277
+ }
278
+
279
+ /**
280
+ * Request finish course
281
+ */
282
+ public static function _request_finish_course() {
283
+ $nonce = learn_press_get_request( 'security' );
284
+ $course_id = absint( learn_press_get_request( 'id' ) );
285
+ $user = learn_press_get_current_user();
286
+
287
+ $course = LP_Course::get_course( $course_id );
288
+
289
+ $nonce_action = sprintf( 'learn-press-finish-course-%d-%d', $course_id, $user->id );
290
+ if ( !$user->id || !$course || !wp_verify_nonce( $nonce, $nonce_action ) ) {
291
+ wp_die( __( 'Access denied!', 'learnpress' ) );
292
+ }
293
+
294
+ $finished = $user->finish_course( $course_id );
295
+
296
+ $response = array();
297
+
298
+ if ( $finished ) {
299
+ learn_press_add_message( sprintf( __( 'You have finished this course "%s"', 'learnpress' ), $course->get_title() ) );
300
+ $response['redirect'] = get_the_permalink( $course_id );
301
+
302
+ $response['result'] = 'success';
303
+ } else {
304
+ $response['message'] = __( 'Error! You cannot finish this course. Please contact your administrator for more information.', 'learnpress' );
305
+ $response['result'] = 'error';
306
+ }
307
+
308
+ learn_press_send_json( $response );
309
+ }
310
+
311
+ /**
312
+ * Request complete an item
313
+ */
314
+ public static function _request_complete_item() {
315
+ $user = learn_press_get_current_user();
316
+ $id = learn_press_get_request( 'id' );
317
+ $course_id = !empty( $_REQUEST['course_id'] ) ? $_REQUEST['course_id'] : get_the_ID();
318
+ $type = learn_press_get_request( 'type' );
319
+ $security = learn_press_get_request( 'security' );
320
+ $response = array();
321
+ if ( !wp_verify_nonce( $security, sprintf( 'complete-item-%d-%d-%d', $user->id, $course_id, $id ) ) ) {
322
+ $response['result'] = 'fail';
323
+ $response['message'] = __( 'Bad request!', 'learnpress' );
324
+ } else {
325
+ if ( $type == 'lp_lesson' ) {
326
+ $results = $user->complete_lesson( $id, $course_id );
327
+ if ( is_wp_error( $results ) ) {
328
+ learn_press_add_message( __( 'Error while completing lesson.', 'learnpress' ) );
329
+ } elseif ( $results !== false ) {
330
+ learn_press_add_message( __( 'You have completed lesson.', 'learnpress' ) );
331
+ }
332
+ } else {
333
+ do_action( 'learn_press_user_request_complete_item', $_REQUEST );
334
+ }
335
+ }
336
+ wp_redirect( learn_press_get_current_url() );
337
+ die();
338
+ }
339
+
340
+ /**
341
+ * Request load item content
342
+ */
343
+ public static function _request_load_item() {
344
+ global $wpdb;
345
+ $user = learn_press_get_current_user();
346
+ $item_id = learn_press_get_request( 'id' );
347
+ $course_id = get_the_ID();
348
+ // Ensure that user can view course item
349
+ $can_view_item = $user->can( 'view-item', $item_id, $course_id );
350
+ if ( $can_view_item ) {
351
+ // Update user item if it's not updated
352
+ if ( !$user->get_item_status( $item_id, $course_id ) ) {
353
+ $item_type = learn_press_get_request( 'type' );
354
+ if ( !$item_type ) {
355
+ $item_type = get_post_type( $item_id );
356
+ }
357
+ if ( apply_filters( 'learn_press_insert_user_item_data', true, $item_id, $course_id ) && $can_view_item != 'preview' ) {
358
+ $insert = $wpdb->insert(
359
+ $wpdb->prefix . 'learnpress_user_items',
360
+ apply_filters(
361
+ 'learn_press_user_item_data',
362
+ array(
363
+ 'user_id' => get_current_user_id(),
364
+ 'item_id' => learn_press_get_request( 'id' ),
365
+ 'item_type' => $item_type,
366
+ 'start_time' => $item_type == 'lp_lesson' ? current_time( 'mysql' ) : '0000-00-00 00:00:00',
367
+ 'end_time' => '0000-00-00 00:00:00',
368
+ 'status' => $item_type == 'lp_lesson' ? 'started' : 'viewed',
369
+ 'ref_id' => $course_id,
370
+ 'ref_type' => 'lp_course',
371
+ 'parent_id' => $user->get_course_history_id( $course_id )
372
+ )
373
+ ),
374
+ array(
375
+ '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%s'
376
+ )
377
+ );
378
+ print_r( $wpdb );
379
+ $user_item_id = $wpdb->insert_id;
380
+ }
381
+ }
382
+ // display content item
383
+ learn_press_get_template( 'single-course/content-item.php' );
384
+ } else {
385
+ // display message
386
+ learn_press_get_template( 'singe-course/content-protected.php' );
387
+ }
388
+ die();
389
+ }
390
+
391
+ /**
392
+ * die();
393
+ * Student take course
394
+ * @return void
395
+ */
396
+ public static function take_course() {
397
+ $payment_method = !empty( $_POST['payment_method'] ) ? $_POST['payment_method'] : '';
398
+ $course_id = !empty( $_POST['course_id'] ) ? intval( $_POST['course_id'] ) : false;
399
+ do_action( 'learn_press_take_course', $course_id, $payment_method );
400
+ }
401
+
402
+ /**
403
+ * Load quiz question
404
+ */
405
+ public static function load_quiz_question() {
406
+ $quiz_id = !empty( $_REQUEST['quiz_id'] ) ? absint( $_REQUEST['quiz_id'] ) : 0;
407
+ $question_id = !empty( $_REQUEST['question_id'] ) ? absint( $_REQUEST['question_id'] ) : 0;
408
+ $user_id = !empty( $_REQUEST['user_id'] ) ? absint( $_REQUEST['user_id'] ) : 0;
409
+ global $quiz;
410
+ $quiz = LP_Quiz::get_quiz( $quiz_id );
411
+ LP()->quiz = $quiz;
412
+ do_action( 'learn_press_load_quiz_question', $question_id, $quiz_id, $user_id );
413
+ $user = learn_press_get_current_user();
414
+ if ( $user->id != $user_id ) {
415
+ learn_press_send_json(
416
+ array(
417
+ 'result' => 'error',
418
+ 'message' => __( 'Load question error. Try again!', 'learnpress' )
419
+ )
420
+ );
421
+ }
422
+ if ( !$quiz_id || !$question_id ) {
423
+ learn_press_send_json(
424
+ array(
425
+ 'result' => 'error',
426
+ 'message' => __( 'Something is wrong. Try again!', 'learnpress' )
427
+ )
428
+ );
429
+ }
430
+ if ( $question = LP_Question_Factory::get_question( $question_id ) ) {
431
+ $quiz->current_question = $question;
432
+
433
+ ob_start();
434
+ if ( $progress = $user->get_quiz_progress( $quiz->id ) ) {
435
+ learn_press_update_user_quiz_meta( $progress->history_id, 'current_question', $question_id );
436
+ }
437
+ $question_answers = $user->get_question_answers( $quiz->id, $question_id );
438
+ $question->render( array( 'answered' => $question_answers ) );
439
+
440
+ $content = ob_get_clean();
441
+ learn_press_send_json(
442
+ apply_filters( 'learn_press_load_quiz_question_result_data', array(
443
+ 'result' => 'success',
444
+ 'permalink' => learn_press_get_user_question_url( $quiz_id, $question_id ),
445
+ 'question' => array(
446
+ 'content' => $content
447
+ )
448
+ )
449
+ )
450
+ );
451
+ }
452
+ }
453
+
454
+ /**
455
+ * Finish quiz
456
+ */
457
+ public static function finish_quiz() {
458
+ $user = learn_press_get_current_user();
459
+ $quiz_id = learn_press_get_request( 'quiz_id' );
460
+ $user->finish_quiz( $quiz_id );
461
+ $response = array(
462
+ 'redirect' => get_the_permalink( $quiz_id )
463
+ );
464
+ learn_press_send_json( $response );
465
+ }
466
+
467
+ /**
468
+ * Retake a quiz
469
+ */
470
+ public static function retake_quiz() {
471
+ die( __FUNCTION__ );
472
+ // verify nonce
473
+ if ( !wp_verify_nonce( learn_press_get_request( 'nonce' ), 'retake-quiz' ) ) {
474
+ learn_press_send_json(
475
+ array(
476
+ 'result' => 'fail',
477
+ 'message' => __( 'Something went wrong. Please try again!', 'learnpress' )
478
+ )
479
+ );
480
+ }
481
+ $quiz_id = learn_press_get_request( 'quiz_id' );
482
+ $user = learn_press_get_current_user();
483
+ $response = $user->retake_quiz( $quiz_id );
484
+ learn_press_send_json( $response );
485
+ }
486
+
487
+ /**
488
+ * Load lesson content
489
+ */
490
+ public static function load_lesson_content() {
491
+ learn_press_debug( $_REQUEST );
492
+ global $post;
493
+ $lesson_id = $_POST['lesson_id'];
494
+ $title = get_the_title( $lesson_id );
495
+ $post = get_post( $lesson_id );
496
+ $content = $post->post_content;
497
+ $content = apply_filters( 'the_content', $content );
498
+ printf(
499
+ '<h3>%s</h3>
500
+ %s
501
+ <button class="complete-lesson-button">Complete Lesson</button>',
502
+ $title,
503
+ $content
504
+ );
505
+ die;
506
+ }
507
+
508
+ /**
509
+ * Complete lesson
510
+ */
511
+ public static function complete_lesson() {
512
+ $nonce = learn_press_get_request( 'nonce' );
513
+ $item_id = learn_press_get_request( 'id' );
514
+ $course_id = learn_press_get_request( 'course_id' );
515
+ $post = get_post( $item_id );
516
+ $user = learn_press_get_current_user();
517
+ $course = LP_Course::get_course( $course_id );
518
+ $response = array(
519
+ 'result' => 'success'
520
+ );
521
+ $nonce_action = sprintf( 'learn-press-complete-%s-%d-%d-%d', $post->post_type, $post->ID, $course->id, $user->id );
522
+ // security check
523
+ if ( !$post || ( $post && !wp_verify_nonce( $nonce, $nonce_action ) ) ) {
524
+ $response['result'] = 'error';
525
+ $response['message'] = __( 'Error! Invalid lesson or security checked failure', 'learnpress' );
526
+ }
527
+
528
+ if ( $response['result'] == 'success' ) {
529
+ $result = $user->complete_lesson( $item_id );
530
+ if ( !is_wp_error( $result ) ) {
531
+ $can_finish = $user->can_finish_course( $course_id );
532
+ $response['button_text'] = '<span class="dashicons dashicons-yes"></span>' . __( 'Completed', 'learnpress' );
533
+ $response['course_result'] = round( $result * 100, 0 );
534
+ $response['can_finish'] = $can_finish;
535
+ $response['next_item'] = $course->get_next_item( $item_id );
536
+
537
+ ob_start();
538
+ if ( $can_finish ) {
539
+ learn_press_display_message( __( 'Congratulations! You have completed this lesson and you can finish course.', 'learnpress' ) );
540
+ } else {
541
+ learn_press_display_message( __( 'Congratulations! You have completed this lesson.', 'learnpress' ) );
542
+ }
543
+ $response['message'] = ob_get_clean();
544
+ } else {
545
+ ob_start();
546
+ learn_press_display_message( $result->get_error_message() );
547
+ $response['message'] = ob_get_clean();
548
+ $response['result'] = 'fail';
549
+ }
550
+ }
551
+ learn_press_send_json( $response );
552
+ }
553
+
554
+ /**
555
+ * Retake course action
556
+ */
557
+ public static function _request_retake_course() {
558
+ $security = learn_press_get_request( 'security' );
559
+ $course_id = learn_press_get_request( 'course_id' );
560
+ $user = learn_press_get_current_user();
561
+ $course = LP_Course::get_course( $course_id );
562
+ $response = array(
563
+ 'result' => 'error'
564
+ );
565
+ $security_action = sprintf( 'learn-press-retake-course-%d-%d', $course->id, $user->id );
566
+ // security check
567
+ if ( !wp_verify_nonce( $security, $security_action ) ) {
568
+ $response['message'] = __( 'Error! Invalid lesson or security checked failure', 'learnpress' );
569
+ } else {
570
+ if ( $user->can( 'retake-course', $course_id ) ) {
571
+ if ( !$result = $user->retake_course( $course_id ) ) {
572
+ $response['message'] = __( 'Error!', 'learnpress' );
573
+ } else {
574
+ learn_press_add_message( sprintf( __( 'You have retaken course "%s"', 'learnpress' ), $course->get_title() ) );
575
+ $response['result'] = 'success';
576
+ $response['redirect'] = apply_filters( 'learn_press_retake_course_redirect', add_query_arg( 'retaken-course', $course_id, get_the_permalink( $course_id ) ) );
577
+ }
578
+ } else {
579
+ $result['message'] = __( 'Error! You can not retake course', 'learnpress' );
580
+ }
581
+ }
582
+ learn_press_send_json( $response );
583
+ }
584
+
585
+ public static function start_quiz() {
586
+ $quiz_id = !empty( $_REQUEST['quiz_id'] ) ? absint( $_REQUEST['quiz_id'] ) : 0;
587
+ if ( !$quiz_id ) {
588
+ learn_press_send_json(
589
+ array(
590
+ 'result' => 'error',
591
+ 'message' => __( 'The quiz ID is empty', 'learnpress' )
592
+ )
593
+ );
594
+ }
595
+ global $quiz;
596
+
597
+ $quiz = LP_Quiz::get_quiz( $quiz_id );
598
+
599
+ if ( !$quiz->id || $quiz->id != $quiz_id ) {
600
+ learn_press_send_json(
601
+ array(
602
+ 'result' => 'error',
603
+ 'message' => __( 'Something is wrong! Please try again', 'learnpress' )
604
+ )
605
+ );
606
+ }
607
+ $user = learn_press_get_current_user();
608
+ if ( $quiz->is_require_enrollment() && $user->is( 'guest' ) ) {
609
+ learn_press_send_json(
610
+ array(
611
+ 'result' => 'error',
612
+ 'message' => __( 'Please login to take this quiz', 'learnpress' )
613
+ )
614
+ );
615
+ }
616
+ $user->set_quiz( $quiz );
617
+
618
+ switch ( strtolower( $user->get_quiz_status() ) ) {
619
+ case 'completed':
620
+ learn_press_send_json(
621
+ array(
622
+ 'result' => 'error',
623
+ 'message' => __( 'You have completed this quiz', 'learnpress' ),
624
+ 'data' => $user->get_quiz_result()
625
+ )
626
+ );
627
+ break;
628
+ case 'started':
629
+ learn_press_send_json(
630
+ array(
631
+ 'result' => 'error',
632
+ 'message' => __( 'You have started this quiz', 'learnpress' ),
633
+ 'data' => array(
634
+ 'status' => $user->get_quiz_status()
635
+ )
636
+ )
637
+ );
638
+ break;
639
+ default:
640
+ $result = $user->start_quiz();
641
+ $current_question = !empty( $result['current_question'] ) ? $result['current_question'] : $user->get_current_question_id( $quiz_id );
642
+ learn_press_send_json(
643
+ array(
644
+ 'result' => 'success',
645
+ 'data' => $result,
646
+ 'question_url' => learn_press_get_user_question_url( $quiz_id, $current_question ),
647
+ 'question_content' => LP_Question_Factory::fetch_question_content( $current_question )
648
+ )
649
+ );
650
+ }
651
+ die();
652
+ }
653
+ }
654
+ }
655
+ // Call class
656
  LP_AJAX::init();
inc/class-lp-assets.php CHANGED
@@ -1,804 +1,809 @@
1
- <?php
2
-
3
- /**
4
- * Class LP_Assets
5
- *
6
- * @author ThimPress
7
- * @package LearnPress/Classes
8
- * @version 1.0
9
- */
10
-
11
- if ( !defined( 'ABSPATH' ) ) {
12
- exit; // Exit if accessed directly
13
- }
14
-
15
- class LP_Assets {
16
- /**
17
- * Styles
18
- *
19
- * @var array
20
- */
21
- protected static $styles = array();
22
-
23
- /**
24
- * Scripts
25
- *
26
- * @var array
27
- */
28
- protected static $scripts = array();
29
-
30
- /**
31
- * Localize scripts
32
- *
33
- * @var array
34
- */
35
- protected static $wp_localize_scripts = array();
36
-
37
- /**
38
- * Params
39
- *
40
- * @var array
41
- */
42
- protected static $wp_params = array();
43
-
44
- /**
45
- * @var array
46
- */
47
- protected static $wp_param_names = array();
48
-
49
- /**
50
- * @var array
51
- */
52
- protected static $wp_script_codes = array();
53
-
54
- /**
55
- * Localized flag
56
- *
57
- * @var bool
58
- */
59
- protected static $localized = array( '__all' => '' );
60
-
61
- /**
62
- * @var array
63
- */
64
- protected static $param_printed = array( '__all' );
65
-
66
- /**
67
- * @var int
68
- */
69
- protected static $id = 0;
70
-
71
- /**
72
- * @var array
73
- */
74
- protected static $_enqueue_scripts = array();
75
-
76
- /**
77
- * @var array
78
- */
79
- protected static $_enqueue_styles = array();
80
-
81
- /**
82
- * @var LP_Assets|null
83
- */
84
- protected static $_instance = null;
85
-
86
- /**
87
- * @var array
88
- */
89
- public static $registered = array();
90
-
91
- /**
92
- * @var array
93
- */
94
- protected static $js_vars = array();
95
-
96
- /**
97
- * Constructor
98
- */
99
- public function __construct() {
100
- self::$_instance = $this;
101
- self::init();
102
- }
103
-
104
- /**
105
- * Init Asset
106
- */
107
- public static function init() {
108
- $priory = 900;
109
- if ( !is_admin() ) {
110
- add_action( 'wp_enqueue_scripts', array( self::$_instance, 'load_scripts' ), $priory );
111
- add_action( 'wp_enqueue_scripts', array( self::$_instance, 'wp_assets' ), $priory );
112
- add_action( 'wp_print_footer_scripts', array( __CLASS__, 'localize_printed_scripts' ), $priory + 10 );
113
- add_action( 'wp_enqueue_scripts', array( __CLASS__, '_enqueue_scripts' ), $priory + 10 );
114
-
115
- } else {
116
- add_action( 'admin_enqueue_scripts', array( self::$_instance, 'load_scripts' ), $priory );
117
- add_action( 'admin_enqueue_scripts', array( self::$_instance, 'wp_assets' ), $priory );
118
- add_action( 'admin_print_footer_scripts', array( self::$_instance, 'localize_printed_scripts' ), $priory + 10 );
119
- add_action( 'admin_enqueue_scripts', array( __CLASS__, '_enqueue_scripts' ), $priory + 10 );
120
- }
121
- add_filter( 'script_loader_src', array( __CLASS__, 'script_localized' ), $priory + 5, 2 );
122
-
123
- /**
124
- * Check if action add_default_scripts has called then we need
125
- * to call method add_default_scripts directly to make scripts
126
- * work properly
127
- *
128
- * Fixed in ver 2.0.8
129
- */
130
- if ( did_action( 'add_default_scripts' ) ) {
131
- global $wp_scripts;
132
- if ( $wp_scripts ) {
133
- self::add_default_scripts( $wp_scripts );
134
- }
135
- } else {
136
- add_action( 'wp_default_scripts', array( __CLASS__, 'add_default_scripts' ) );
137
- }
138
-
139
- /**
140
- * Check if action wp_default_styles has called then we need
141
- * to call method add_default_styles directly to make styles
142
- * work properly
143
- *
144
- * Fixed in ver 2.0.8
145
- */
146
- if ( did_action( 'wp_default_styles' ) ) {
147
- global $wp_styles;
148
- if ( $wp_styles ) {
149
- self::add_default_styles( $wp_styles );
150
- }
151
- } else {
152
- add_action( 'wp_default_styles', array( __CLASS__, 'add_default_styles' ) );
153
- }
154
- if ( !defined( 'LP_DEBUG' ) || ( false == LP_DEBUG ) ) {
155
- add_filter( 'script_loader_tag', array( self::$_instance, 'unload_script_tag' ), $priory, 3 );
156
- add_filter( 'style_loader_tag', array( self::$_instance, 'unload_script_tag' ), $priory, 3 );
157
- add_action( 'wp_print_footer_scripts', array( self::$_instance, 'include_script_file' ), $priory );
158
- add_action( 'admin_print_footer_scripts', array( self::$_instance, 'include_script_file' ), $priory );
159
- add_action( 'wp_print_scripts', array( self::$_instance, 'include_stylesheet_file' ), $priory );
160
- add_action( 'admin_print_scripts', array( self::$_instance, 'include_stylesheet_file' ), $priory );
161
- }
162
- }
163
-
164
- public static function script_localized( $source, $handle ) {
165
- //if ( !empty( self::$wp_localize_scripts[$handle] ) ) {
166
- self::$localized[$handle] = $source;
167
- //}
168
- if ( !empty( self::$wp_params[$handle] ) ) {
169
- self::$param_printed[] = $handle;
170
- }
171
- return $source;
172
- }
173
-
174
- /**
175
- * Load default scripts
176
- *
177
- * @param $scripts
178
- */
179
- public static function default_scripts( &$scripts ) {
180
- if ( !defined( 'LEARNPRESS_VERSION' ) ) {
181
- define( 'LEARNPRESS_VERSION', '2.0' );
182
- }
183
-
184
- $develop_src = false !== strpos( LEARNPRESS_VERSION, '-src' );
185
-
186
- if ( !defined( 'SCRIPT_DEBUG' ) ) {
187
- define( 'SCRIPT_DEBUG', $develop_src );
188
- }
189
- if ( !$guessurl = site_url() ) {
190
- $guessed_url = true;
191
- $guessurl = wp_guess_url();
192
- }
193
- $default_dirs = array( '/wp-admin/js/', '/wp-includes/js/' );
194
- $scripts->base_url = $guessurl;
195
- $scripts->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : '';
196
- $scripts->default_version = get_bloginfo( 'version' );
197
- $scripts->default_dirs = $default_dirs;
198
- self::add_default_scripts( $scripts );
199
- }
200
-
201
- public static function add_default_scripts( &$scripts ) {
202
-
203
- $default_path = plugins_url( 'learnpress/assets/' );
204
- $suffix = '';
205
- $deps = array( 'jquery', 'backbone', 'utils' );
206
-
207
- // global
208
- $scripts->add( 'learn-press-global', $default_path . 'js/global' . $suffix . '.js', $deps, false, 1 );
209
- $scripts->add( 'learn-press-jalerts', $default_path . 'js/jquery.alert' . $suffix . '.js', $deps, false, 1 );
210
-
211
- // frontend
212
- $scripts->add( 'learn-press-js', $default_path . 'js/frontend/learnpress' . $suffix . '.js', $deps, false, 1 );
213
- $scripts->add( 'learn-press-single-course', $default_path . 'js/frontend/single-course' . $suffix . '.js', $deps, false, 1 );
214
- $scripts->add( 'learn-press-course-quiz', $default_path . 'js/frontend/quiz' . $suffix . '.js', $deps, false, 1 );
215
- $scripts->add( 'learn-press-course-lesson', $default_path . 'js/frontend/lesson' . $suffix . '.js', $deps, false, 1 );
216
- $scripts->add( 'learn-press-enroll', $default_path . 'js/frontend/enroll' . $suffix . '.js', $deps, false, 1 );
217
- $scripts->add( 'learn-press-timer', $default_path . 'js/jquery.timer' . $suffix . '.js', $deps, false, 1 );
218
- $scripts->add( 'learn-press-checkout', $default_path . 'js/frontend/checkout' . $suffix . '.js', $deps, false, 1 );
219
- $scripts->add( 'learn-press-become-teacher', $default_path . 'js/frontend/become-teacher' . $suffix . '.js', $deps, false, 1 );
220
- $scripts->add( 'learn-press-profile', $default_path . 'js/frontend/profile' . $suffix . '.js', $deps, false, 1 );
221
- $scripts->add( 'learn-press-jquery-cropit', $default_path . 'js/jquery.cropit' . $suffix . '.js', $deps, false, 1 );
222
- $scripts->add( 'learn-press-jquery-ocupload', $default_path . 'js/jquery.ocupload' . $suffix . '.js', $deps, false, 1 );
223
-
224
- // admin
225
- $scripts->add( 'learn-press-admin', $default_path . 'js/admin/admin' . $suffix . '.js', $deps, false, 1 );
226
- $scripts->add( 'learn-press-admin-settings', $default_path . 'js/admin/settings' . $suffix . '.js', $deps, false, 1 );
227
- $scripts->add( 'learn-press-mb-question', $default_path . 'js/admin/meta-box-question' . $suffix . '.js', $deps, false, 1 );
228
- $scripts->add( 'learn-press-mb-course', $default_path . 'js/admin/meta-box-course' . $suffix . '.js', $deps, false, 1 );
229
- $scripts->add( 'learn-press-mb-quiz', $default_path . 'js/admin/meta-box-quiz' . $suffix . '.js', $deps, false, 1 );
230
- $scripts->add( 'learn-press-mb-order', $default_path . 'js/admin/meta-box-order' . $suffix . '.js', $deps, false, 1 );
231
- $scripts->add( 'learn-press-modal-search-items', $default_path . 'js/admin/modal-search-items' . $suffix . '.js', array( 'learn-press-global' ), false, 1 );
232
- $scripts->add( 'learn-press-order', $default_path . 'js/admin/meta-box-order' . $suffix . '.js', $deps, false, 1 );
233
- $scripts->add( 'learn-press-statistics-select2', '/' . LP_WP_CONTENT . '/plugins/learnpress/inc/libraries/meta-box/js/select2/select2.min.js', $deps, false, 1 );
234
-
235
- // upgrade
236
- $scripts->add( 'learn-press-upgrade', '/' . LP_WP_CONTENT . '/plugins/learnpress/inc/updates/09/script' . $suffix . '.js', $deps, false, 1 );
237
-
238
- do_action_ref_array( 'learn_press_add_default_scripts', array( $scripts, $default_path, $suffix, $deps ) );
239
- }
240
-
241
- /**
242
- * Load default styles
243
- *
244
- * @param WP_Styles $styles
245
- */
246
- public static function default_styles( &$styles ) {
247
- if ( !defined( 'LEARNPRESS_VERSION' ) ) {
248
- define( 'LEARNPRESS_VERSION', '2.0' );
249
- }
250
-
251
- $develop_src = false !== strpos( LEARNPRESS_VERSION, '-src' );
252
-
253
- if ( !defined( 'SCRIPT_DEBUG' ) ) {
254
- define( 'SCRIPT_DEBUG', $develop_src );
255
- }
256
- if ( !$guessurl = site_url() ) {
257
- $guessed_url = true;
258
- $guessurl = wp_guess_url();
259
- }
260
- $default_dirs = array( '/wp-admin/css/', '/wp-includes/css/' );
261
- $styles->base_url = $guessurl;
262
- $styles->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : '';
263
- $styles->default_version = get_bloginfo( 'version' );
264
- $styles->default_dirs[] = $default_dirs;
265
-
266
- self::add_default_styles( $styles );
267
- }
268
-
269
- /**
270
- * @param WP_Styles $styles
271
- */
272
- public static function add_default_styles( &$styles ) {
273
- $default_path = plugins_url( 'learnpress/assets/' );
274
- $suffix = '';
275
- $deps = array( 'dashicons' );
276
- // global
277
- $styles->add( 'learn-press-global', $default_path . 'css/global' . $suffix . '.css', $deps );
278
-
279
- // admin
280
- $styles->add( 'learn-press-admin', $default_path . 'css/admin/admin' . $suffix . '.css' );
281
- $styles->add( 'learn-press-jquery.ui.datepicker', $default_path . 'css/admin/jquery.ui.datepicker' . $suffix . '.css' );
282
- $styles->add( 'learn-press-jquery.ui.theme', $default_path . 'css/admin/jquery.ui.theme' . $suffix . '.css' );
283
- $styles->add( 'learn-press-jquery.ui.core', $default_path . 'css/admin/jquery.ui.core' . $suffix . '.css' );
284
- $styles->add( 'learn-press-jquery.ui.slider', $default_path . 'css/admin/jquery.ui.slider' . $suffix . '.css' );
285
- $styles->add( 'learn-press-mb-course', $default_path . 'css/admin/meta-box-course' . $suffix . '.css' );
286
- $styles->add( 'learn-press-mb-question', $default_path . 'css/admin/meta-box-question' . $suffix . '.css' );
287
- $styles->add( 'learn-press-mb-order', $default_path . 'css/admin/meta-box-order' . $suffix . '.css' );
288
- $styles->add( 'learn-press-jalerts', $default_path . 'css/jalert' . $suffix . '.css' );
289
- $styles->add( 'learn-press-statistics-select2', '/' . LP_WP_CONTENT . '/plugins/learnpress/inc/libraries/meta-box/css/select2/select2.css' );
290
-
291
- // frontend
292
- $styles->add( 'learn-press-style', $default_path . 'css/learnpress.css', $deps );
293
- do_action_ref_array( 'learn_press_add_default_styles', array( $styles, $default_path, $suffix ) );
294
-
295
- }
296
-
297
- /**
298
- * register script
299
- *
300
- * @param string $handle
301
- * @param string $src
302
- * @param array $deps
303
- * @param string $version
304
- * @param boolean $in_footer
305
- */
306
- public static function add_script( $handle, $src, $deps = array( 'jquery' ), $version = LEARNPRESS_VERSION, $in_footer = true ) {
307
- self::$scripts[] = $handle;
308
- wp_register_script( $handle, $src, $deps, $version, $in_footer );
309
- }
310
-
311
- /**
312
- * register style
313
- *
314
- * @param string $handle
315
- * @param string $src
316
- * @param array $deps
317
- * @param string $version
318
- * @param string $media
319
- */
320
- public static function add_style( $handle, $src, $deps = array(), $version = LEARNPRESS_VERSION, $media = 'all' ) {
321
- self::$styles[] = $handle;
322
- wp_register_style( $handle, $src, $deps, $version, $media );
323
- }
324
-
325
- /**
326
- * enqueue script
327
- *
328
- * @param string $handle
329
- * @param string $src
330
- * @param array $deps
331
- * @param string $version
332
- * @param boolean $in_footer
333
- */
334
- public static function enqueue_script( $handle, $src = '', $deps = array( 'jquery' ), $version = LEARNPRESS_VERSION, $in_footer = true ) {
335
- global $wp_scripts;
336
-
337
- if ( is_array( $handle ) ) {
338
- foreach ( $handle as $_handle ) {
339
- self::enqueue_script( $_handle, $src, $deps, $version, $in_footer );
340
- }
341
- } else {
342
- if ( !in_array( $handle, self::$scripts ) && $src ) {
343
- self::add_script( $handle, $src, $deps, $version, $in_footer );
344
- }
345
- self::$_enqueue_scripts[$handle] = func_get_args();
346
- if ( $deps ) {
347
- foreach ( $deps as $dep ) {
348
- self::add_script_concat( $dep );
349
- }
350
- }
351
- self::add_script_concat( $handle );
352
- }
353
- }
354
-
355
- /**
356
- * @param $handle
357
- */
358
- public static function add_script_concat( $handle ) {
359
- global $wp_scripts;
360
- if ( !$wp_scripts ) {
361
- return;
362
- }
363
- if ( empty( $wp_scripts->lp_script_concat ) ) {
364
- $wp_scripts->lp_script_concat = array();
365
- }
366
- if ( strpos( $handle, 'learn-press-' ) !== false ) {
367
- $concat = str_replace( 'learn-press-', '', $handle );
368
- if ( !in_array( $concat, $wp_scripts->lp_script_concat ) ) {
369
- $wp_scripts->lp_script_concat[] = $concat;
370
- }
371
- }
372
- }
373
-
374
- /**
375
- * @param $handle
376
- */
377
- public static function add_style_concat( $handle ) {
378
- global $wp_styles;
379
- if ( !$wp_styles ) {
380
- return;
381
- }
382
- if ( empty( $wp_styles->lp_style_concat ) ) {
383
- $wp_styles->lp_style_concat = array();
384
- }
385
- if ( strpos( $handle, 'learn-press-' ) !== false ) {
386
- $concat = str_replace( 'learn-press-', '', $handle );
387
- if ( !in_array( $concat, $wp_styles->lp_style_concat ) ) {
388
- $wp_styles->lp_style_concat[] = $concat;
389
- }
390
- }
391
- }
392
-
393
- /**
394
- * enqueue style
395
- *
396
- * @param string $handle
397
- * @param string $src
398
- * @param array $deps
399
- * @param string $version
400
- * @param string $media
401
- */
402
- public static function enqueue_style( $handle, $src = '', $deps = array(), $version = LEARNPRESS_VERSION, $media = 'all' ) {
403
- if ( is_array( $handle ) ) {
404
- foreach ( $handle as $_handle ) {
405
- self::enqueue_style( $_handle, $src, $deps, $version, $media );
406
- }
407
- } else {
408
- if ( !in_array( $handle, self::$styles ) && $src ) {
409
- self::add_style( $handle, $src, $deps, $version, $media );
410
- }
411
- self::$_enqueue_styles[$handle] = func_get_args();
412
- if ( $deps ) {
413
- foreach ( $deps as $dep ) {
414
- self::add_style_concat( $dep );
415
- }
416
- }
417
- self::add_style_concat( $handle );
418
- }
419
- }
420
-
421
- /**
422
- * add translate text
423
- *
424
- * @param string
425
- * @param array $localize
426
- * @param string
427
- */
428
- public static function add_localize( $key, $localize = null, $handle = '' ) {
429
- if ( !$handle ) {
430
- $handle = is_admin() ? 'learn-press-admin' : 'learn-press-js';
431
- }
432
- if ( empty( self::$wp_localize_scripts[$handle] ) ) {
433
- self::$wp_localize_scripts[$handle] = array();
434
- }
435
- if ( is_array( $key ) ) {
436
- self::$wp_localize_scripts[$handle] = array_merge( self::$wp_localize_scripts[$handle], $key );
437
- } elseif ( is_string( $key ) && strlen( $key ) ) {
438
- self::$wp_localize_scripts[$handle][$key] = $localize;
439
- }
440
- }
441
-
442
- /**
443
- * Add js param
444
- *
445
- * @param string
446
- * @param array
447
- * @param string
448
- * @param $name
449
- */
450
- public static function add_param( $key, $param = null, $handle = 'learn-press-js', $name = null ) {
451
- if ( !$handle ) {
452
- $handle = 'learn-press-js';
453
- }
454
- if ( is_array( $handle ) ) {
455
- foreach ( $handle as $h ) {
456
- self::add_param( $key, $param, $h, $name );
457
- }
458
- return;
459
- }
460
- if ( empty( $name ) ) {
461
- $name = $handle;
462
- }
463
- if ( empty( self::$wp_params[$handle] ) ) {
464
- self::$wp_params[$handle] = array( $name => array() );
465
- }
466
- if ( empty( self::$wp_params[$handle][$name] ) ) {
467
- self::$wp_params[$handle][$name] = array();
468
- }
469
-
470
- if ( is_array( $key ) ) {
471
- self::$wp_params[$handle][$name] = array_merge( self::$wp_params[$handle][$name], $key );
472
- } elseif ( is_string( $key ) && strlen( $key ) ) {
473
- self::$wp_params[$handle][$name][$key] = $param;
474
- }
475
- }
476
-
477
- public static function add_var( $name, $value, $handle = 'learn-press-global' ) {
478
- if ( is_array( $handle ) ) {
479
- foreach ( $handle as $h ) {
480
- self::add_var( $name, $value, $h );
481
- }
482
- return;
483
- }
484
- if ( empty( self::$js_vars[$handle] ) ) {
485
- self::$js_vars[$handle] = array();
486
- }
487
- self::$js_vars[$handle][$name] = $value;
488
- }
489
-
490
- /**
491
- * @param $code
492
- * @param string $handle
493
- */
494
- public static function add_script_tag( $code, $handle = '' ) {
495
- if ( empty( self::$wp_script_codes[$handle] ) ) {
496
- self::$wp_script_codes[$handle] = '';
497
- }
498
- self::$wp_script_codes[$handle] .= preg_replace( '!</?script(.*)>!', '', $code );
499
- }
500
-
501
- /**
502
- * wp_assets
503
- */
504
- public static function wp_assets() {
505
- do_action( 'learn_press_print_assets', is_admin() );
506
- }
507
-
508
- /**
509
- * localize_printed_scripts
510
- */
511
- public static function localize_printed_scripts() {
512
- $has_localized = !empty( self::$localized );
513
- $has_params = !empty( self::$param_printed );
514
- $has_vars = !empty( self::$js_vars );
515
- if ( $has_localized || $has_params || $has_vars ) {
516
- echo "<script type='text/javascript'>\n"; // CDATA and type='text/javascript' is not needed for HTML 5
517
- echo "/* <![CDATA[ */\n";
518
- if ( $has_localized ) {
519
- if ( self::$wp_localize_scripts ) {
520
- echo "\n/* LearnPress Localized */\n";
521
- foreach ( self::$localized as $handle => $src ) {
522
- if ( !empty( self::$wp_localize_scripts[$handle] ) ) {
523
- $name = str_replace( '-', '_', $handle ) . '_localize';
524
- echo "var {$name} = " . json_encode( self::$wp_localize_scripts[$handle] ) . ";\n";
525
- }
526
- }
527
- }
528
- }
529
-
530
- if ( $has_params ) {
531
- $groups = array();
532
-
533
- foreach ( self::$param_printed as $handle ) {
534
- if ( !empty( self::$wp_params[$handle] ) ) {
535
- foreach ( self::$wp_params[$handle] as $name => $value ) {
536
- $name = str_replace( '-', '_', $name );
537
- $value = (array) ( $value );
538
- if ( empty( $groups[$name] ) ) {
539
- $groups[$name] = $value;
540
- } else {
541
- $groups[$name] = array_merge( $groups[$name], $value );
542
- }
543
- }
544
- }
545
- }
546
- //print_r($groups);
547
- if ( $groups ) {
548
- echo "\n/* LearnPress Params */\n";
549
- foreach ( $groups as $name => $code ) {
550
- echo "var {$name} = " . wp_json_encode( $code ) . ";\n";
551
- }
552
- }
553
- }
554
-
555
-
556
- if ( $has_localized ) {
557
- if ( self::$js_vars ) {
558
- echo "\n/* Custom vars */\n";
559
- $abort = array();
560
- foreach ( self::$localized as $handle => $src ) {
561
- if ( !empty( self::$js_vars[$handle] ) ) {
562
- foreach ( self::$js_vars[$handle] as $name => $var ) {
563
- if ( in_array( $name, $abort ) ) {
564
- continue;
565
- }
566
- $abort[] = $name;
567
- echo "var {$name} = " . maybe_serialize( $var ) . ";\n";
568
- }
569
- }
570
- }
571
- }
572
- if ( self::$wp_script_codes ) {
573
- echo "\n/* LearnPress Custom Scripts */\n ( typeof jQuery != 'undefined' ) && jQuery(function($){\n";
574
- foreach ( self::$localized as $handle => $src ) {
575
- if ( !empty( self::$wp_script_codes[$handle] ) ) {
576
- echo( self::$wp_script_codes[$handle] );
577
- }
578
- }
579
- echo "\n});\n";
580
- }
581
- }
582
-
583
- echo "/* ]]> */\n";
584
- echo "</script>\n";
585
- }
586
- }
587
-
588
- public static function remove_script( $handle ) {
589
- if ( isset( self::$_enqueue_scripts[$handle] ) ) {
590
- unset( self::$_enqueue_scripts[$handle] );
591
- }
592
- wp_deregister_script( $handle );
593
- }
594
-
595
- public static function remove_style( $handle ) {
596
- if ( isset( self::$_enqueue_styles[$handle] ) ) {
597
- unset( self::$_enqueue_styles[$handle] );
598
- }
599
- wp_deregister_style( $handle );
600
-
601
- }
602
-
603
- /**
604
- * _enqueue_scripts
605
- */
606
- public static function _enqueue_scripts() {
607
- do_action( 'learn_press_enqueue_scripts', __CLASS__ );
608
- if ( strpos( current_action(), 'enqueue_scripts' ) === false ) {
609
- return;
610
- }
611
- if ( !empty( self::$_enqueue_scripts ) ) {
612
- foreach ( self::$_enqueue_scripts as $handle => $args ) {
613
- call_user_func_array( 'wp_enqueue_script', array( $handle ) );
614
- }
615
- }
616
- if ( !empty( self::$_enqueue_styles ) ) {
617
- foreach ( self::$_enqueue_styles as $handle => $args ) {
618
- call_user_func_array( 'wp_enqueue_style', array( $handle ) );
619
- }
620
- }
621
- }
622
-
623
- /**
624
- * Do not load script
625
- */
626
- public function unload_script_tag( $tag, $handle, $src ) {
627
- if ( strpos( $handle, 'learn-press-' ) !== false && strpos( $src, '/learnpress/' ) !== false ) {
628
- return false;
629
- }
630
- return $tag;
631
- }
632
-
633
- /**
634
- * include_script_file
635
- */
636
- public function include_script_file() {
637
- global $wp_scripts, $compress_scripts;
638
-
639
- $zip = $compress_scripts ? 1 : 0;
640
- if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP )
641
- $zip = 'gzip';
642
-
643
- if ( !empty( $wp_scripts->lp_script_concat ) && $concat = join( ',', $wp_scripts->lp_script_concat ) ) {
644
- if ( !empty( $wp_scripts->print_code ) ) {
645
- echo "\n<script type='text/javascript'>\n";
646
- echo "/* <![CDATA[ */\n"; // not needed in HTML 5
647
- echo $wp_scripts->print_code;
648
- echo "/* ]]> */\n";
649
- echo "</script>\n";
650
- }
651
-
652
- $concat = str_split( $concat, 128 );
653
- $concat = 'load%5B%5D=' . implode( '&load%5B%5D=', $concat );
654
-
655
- $src = get_site_url() . "/" . LP_WP_CONTENT . "/plugins/learnpress/assets/load-scripts.php?" . $concat . "&c={$zip}&ver=" . $wp_scripts->default_version;
656
- echo "<script type='text/javascript' src='" . esc_attr( $src ) . "'></script>\n";
657
- }
658
-
659
- if ( !empty( $wp_scripts->print_html ) )
660
- echo $wp_scripts->print_html;
661
- }
662
-
663
- /**
664
- * include_stylesheet_file
665
- */
666
- public function include_stylesheet_file() {
667
-
668
- if ( did_action( 'learn_press_included_style_file' ) ) {
669
- return;
670
- }
671
-
672
- global $compress_css;
673
-
674
- $wp_styles = wp_styles();
675
-
676
- $zip = $compress_css ? 1 : 0;
677
- if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP )
678
- $zip = 'gzip';
679
-
680
- if ( !empty( $wp_styles->lp_style_concat ) && $concat = join( ',', $wp_styles->lp_style_concat ) ) {
681
- $dir = $wp_styles->text_direction;
682
- $ver = $wp_styles->default_version;
683
-
684
- $concat = str_split( $concat, 128 );
685
- $concat = 'load%5B%5D=' . implode( '&load%5B%5D=', $concat );
686
-
687
- $href = get_site_url() . "/" . LP_WP_CONTENT . "/plugins/learnpress/assets/load-styles.php?" . $concat . "&c={$zip}&ver=" . $ver;
688
- echo "<link rel='stylesheet' href='" . esc_attr( $href ) . "' type='text/css' media='all' />\n";
689
-
690
- if ( !empty( $wp_styles->print_code ) ) {
691
- echo "<style type='text/css'>\n";
692
- echo $wp_styles->print_code;
693
- echo "\n</style>\n";
694
- }
695
- }
696
-
697
- if ( !empty( $wp_styles->print_html ) )
698
- echo $wp_styles->print_html;
699
- do_action( 'learn_press_included_style_file' );
700
- }
701
-
702
- /**
703
- * Load assets
704
- */
705
- public function load_scripts() {
706
- $user = learn_press_get_course_user();
707
- if ( is_admin() ) {
708
- global $pagenow;
709
- $screen = get_current_screen();
710
- $screen_id = $screen->id;
711
- $page_id = !empty( $_REQUEST['page'] ) ? $_REQUEST['page'] : '';
712
- self::enqueue_style( 'learn-press-admin' );
713
- if ( in_array( $screen_id, learn_press_get_screens() ) || in_array( $page_id, learn_press_get_admin_pages() ) ) {
714
- self::enqueue_style( 'learn-press-global' );
715
- self::enqueue_style( 'learn-press-jquery.ui.datepicker' );
716
- self::enqueue_style( 'learn-press-jquery.ui.theme' );
717
- self::enqueue_style( 'learn-press-jquery.ui.core' );
718
- self::enqueue_style( 'learn-press-jquery.ui.slider' );
719
- self::enqueue_style( 'learn-press-icons' );
720
- self::enqueue_script( 'learn-press-global' );
721
- self::enqueue_script( 'learn-press-admin' );
722
- }
723
-
724
- foreach ( array( 'lp_course', 'lp_order', 'lp_quiz', 'lp_lesson', 'lp_question' ) as $post_type ) {
725
- if ( learn_press_is_post_type_screen( $post_type ) ) {
726
- $type = str_replace( 'lp_', '', $post_type );
727
- self::enqueue_style( "learn-press-mb-{$type}" );
728
- self::enqueue_script( "learn-press-mb-{$type}" );
729
- }
730
- }
731
-
732
- if ( learn_press_is_post_type_screen( array( 'lp_quiz' ) ) ) {
733
- self::enqueue_style( 'learn-press-mb-question' );
734
- self::enqueue_script( 'learn-press-mb-question' );
735
- }
736
-
737
- if ( learn_press_is_post_type_screen( array( 'lp_course', 'lp_quiz', 'lp_order' ) ) ) {
738
- self::enqueue_style( 'learn-press-modal-search-items' );
739
- self::enqueue_script( 'learn-press-modal-search-items' );
740
- }
741
-
742
- if ( $screen_id === 'learnpress_page_learn-press-settings' || $screen_id === 'dashboard' ) {
743
- LP_Assets::enqueue_style( 'learn-press-admin' );
744
- LP_Assets::enqueue_script( 'learn-press-admin-settings', LP()->plugin_url( 'assets/js/admin/settings.js' ) );
745
- }
746
-
747
- if ( $pagenow === 'edit.php' && $screen_id === 'edit-lp_course' ) {
748
- LP_Assets::enqueue_script( 'learn-press-duplicate-course', LP()->plugin_url( 'assets/js/admin/duplicate-course.js' ) );
749
- }
750
-
751
- if ( $pagenow === 'post.php' && $screen_id === 'lp_quiz' ) {
752
- self::enqueue_style( 'learn-press-jalerts' );
753
- self::enqueue_script( 'learn-press-jalerts' );
754
- }
755
-
756
- if ( 'learnpress_page_learn-press-statistics' === $screen_id ) {
757
- self::enqueue_script( 'learn-press-statistics-select2' );
758
- self::enqueue_style( 'learn-press-statistics-select2' );
759
- }
760
- do_action( 'learn_press_admin_load_scripts' );
761
- return;
762
- }
763
-
764
- // global
765
- self::enqueue_style( 'learn-press-icon' );
766
- self::enqueue_style( 'learn-press-jalerts' );
767
-
768
- // frontend
769
- if ( LP()->settings->get( 'load_css' ) == 'yes' || LP()->settings->get( 'load_css' ) == '' ) {
770
- self::enqueue_style( 'learn-press-style' );
771
- }
772
- self::enqueue_script( 'learn-press-jalerts' );
773
- self::enqueue_script( 'learn-press-global' );
774
- self::enqueue_script( 'learn-press-js' );
775
- if ( learn_press_is_course() ) {
776
- self::enqueue_script( 'learn-press-single-course' );
777
- self::enqueue_script( 'learn-press-course-quiz' );
778
- self::enqueue_script( 'learn-press-course-lesson' );
779
- if ( !$user->has_course_status( null, array( 'enrolled', 'finished' ) ) ) {
780
- self::enqueue_script( 'learn-press-enroll' );
781
- }
782
- }
783
- if ( learn_press_is_checkout() ) {
784
- self::enqueue_script( 'learn-press-checkout' );
785
- }
786
- self::enqueue_script( 'learn-press-become-teacher' );
787
-
788
- if ( learn_press_is_profile() ) {
789
- // Localize the script with new data
790
- $translation_array = array(
791
- 'confim_pass_not_match' => __( 'Password and confirmation password do not match', 'learnpress' ),
792
- 'msg_field_is_required' => __('This field is required','learnpress')
793
- );
794
- wp_localize_script( 'learn-press-profile', 'lp_profile_translation', $translation_array );
795
- self::enqueue_script( 'learn-press-profile' );
796
- self::enqueue_script( 'learn-press-jquery-cropit' );
797
- self::enqueue_script( 'learn-press-jquery-ocupload' );
798
- }
799
- do_action( 'learn_press_load_scripts' );
800
- }
801
- }
802
-
803
- // Call class
 
 
 
 
 
804
  return new LP_Assets();
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Assets
5
+ *
6
+ * @author ThimPress
7
+ * @package LearnPress/Classes
8
+ * @version 1.0
9
+ */
10
+
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit; // Exit if accessed directly
13
+ }
14
+
15
+ class LP_Assets {
16
+ /**
17
+ * Styles
18
+ *
19
+ * @var array
20
+ */
21
+ protected static $styles = array();
22
+
23
+ /**
24
+ * Scripts
25
+ *
26
+ * @var array
27
+ */
28
+ protected static $scripts = array();
29
+
30
+ /**
31
+ * Localize scripts
32
+ *
33
+ * @var array
34
+ */
35
+ protected static $wp_localize_scripts = array();
36
+
37
+ /**
38
+ * Params
39
+ *
40
+ * @var array
41
+ */
42
+ protected static $wp_params = array();
43
+
44
+ /**
45
+ * @var array
46
+ */
47
+ protected static $wp_param_names = array();
48
+
49
+ /**
50
+ * @var array
51
+ */
52
+ protected static $wp_script_codes = array();
53
+
54
+ /**
55
+ * Localized flag
56
+ *
57
+ * @var bool
58
+ */
59
+ protected static $localized = array( '__all' => '' );
60
+
61
+ /**
62
+ * @var array
63
+ */
64
+ protected static $param_printed = array( '__all' );
65
+
66
+ /**
67
+ * @var int
68
+ */
69
+ protected static $id = 0;
70
+
71
+ /**
72
+ * @var array
73
+ */
74
+ protected static $_enqueue_scripts = array();
75
+
76
+ /**
77
+ * @var array
78
+ */
79
+ protected static $_enqueue_styles = array();
80
+
81
+ /**
82
+ * @var LP_Assets|null
83
+ */
84
+ protected static $_instance = null;
85
+
86
+ /**
87
+ * @var array
88
+ */
89
+ public static $registered = array();
90
+
91
+ /**
92
+ * @var array
93
+ */
94
+ protected static $js_vars = array();
95
+
96
+ /**
97
+ * Constructor
98
+ */
99
+ public function __construct() {
100
+ self::$_instance = $this;
101
+ self::init();
102
+ }
103
+
104
+ /**
105
+ * Init Asset
106
+ */
107
+ public static function init() {
108
+ $priory = 900;
109
+ if ( !is_admin() ) {
110
+ add_action( 'wp_enqueue_scripts', array( self::$_instance, 'load_scripts' ), $priory );
111
+ add_action( 'wp_enqueue_scripts', array( self::$_instance, 'wp_assets' ), $priory );
112
+ add_action( 'wp_print_footer_scripts', array( __CLASS__, 'localize_printed_scripts' ), $priory + 10 );
113
+ add_action( 'wp_enqueue_scripts', array( __CLASS__, '_enqueue_scripts' ), $priory + 10 );
114
+
115
+ } else {
116
+ add_action( 'admin_enqueue_scripts', array( self::$_instance, 'load_scripts' ), $priory );
117
+ add_action( 'admin_enqueue_scripts', array( self::$_instance, 'wp_assets' ), $priory );
118
+ add_action( 'admin_print_footer_scripts', array( self::$_instance, 'localize_printed_scripts' ), $priory + 10 );
119
+ add_action( 'admin_enqueue_scripts', array( __CLASS__, '_enqueue_scripts' ), $priory + 10 );
120
+ }
121
+ add_filter( 'script_loader_src', array( __CLASS__, 'script_localized' ), $priory + 5, 2 );
122
+
123
+ /**
124
+ * Check if action add_default_scripts has called then we need
125
+ * to call method add_default_scripts directly to make scripts
126
+ * work properly
127
+ *
128
+ * Fixed in ver 2.0.8
129
+ */
130
+ if ( did_action( 'add_default_scripts' ) ) {
131
+ global $wp_scripts;
132
+ if ( $wp_scripts ) {
133
+ self::add_default_scripts( $wp_scripts );
134
+ }
135
+ } else {
136
+ add_action( 'wp_default_scripts', array( __CLASS__, 'add_default_scripts' ) );
137
+ }
138
+
139
+ /**
140
+ * Check if action wp_default_styles has called then we need
141
+ * to call method add_default_styles directly to make styles
142
+ * work properly
143
+ *
144
+ * Fixed in ver 2.0.8
145
+ */
146
+ if ( did_action( 'wp_default_styles' ) ) {
147
+ global $wp_styles;
148
+ if ( $wp_styles ) {
149
+ self::add_default_styles( $wp_styles );
150
+ }
151
+ } else {
152
+ add_action( 'wp_default_styles', array( __CLASS__, 'add_default_styles' ) );
153
+ }
154
+ if ( !defined( 'LP_DEBUG' ) || ( false == LP_DEBUG ) ) {
155
+ add_filter( 'script_loader_tag', array( self::$_instance, 'unload_script_tag' ), $priory, 3 );
156
+ add_filter( 'style_loader_tag', array( self::$_instance, 'unload_script_tag' ), $priory, 3 );
157
+ add_action( 'wp_print_footer_scripts', array( self::$_instance, 'include_script_file' ), $priory );
158
+ add_action( 'admin_print_footer_scripts', array( self::$_instance, 'include_script_file' ), $priory );
159
+ add_action( 'wp_print_scripts', array( self::$_instance, 'include_stylesheet_file' ), $priory );
160
+ add_action( 'admin_print_scripts', array( self::$_instance, 'include_stylesheet_file' ), $priory );
161
+ }
162
+ }
163
+
164
+ public static function script_localized( $source, $handle ) {
165
+ //if ( !empty( self::$wp_localize_scripts[$handle] ) ) {
166
+ self::$localized[$handle] = $source;
167
+ //}
168
+ if ( !empty( self::$wp_params[$handle] ) ) {
169
+ self::$param_printed[] = $handle;
170
+ }
171
+ return $source;
172
+ }
173
+
174
+ /**
175
+ * Load default scripts
176
+ *
177
+ * @param $scripts
178
+ */
179
+ public static function default_scripts( &$scripts ) {
180
+ if ( !defined( 'LEARNPRESS_VERSION' ) ) {
181
+ define( 'LEARNPRESS_VERSION', '2.1.1' );
182
+ }
183
+
184
+ $develop_src = false !== strpos( LEARNPRESS_VERSION, '-src' );
185
+
186
+ if ( !defined( 'SCRIPT_DEBUG' ) ) {
187
+ define( 'SCRIPT_DEBUG', $develop_src );
188
+ }
189
+ if ( !$guessurl = site_url() ) {
190
+ $guessed_url = true;
191
+ $guessurl = wp_guess_url();
192
+ }
193
+ $default_dirs = array( '/wp-admin/js/', '/wp-includes/js/' );
194
+ $scripts->base_url = $guessurl;
195
+ $scripts->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : '';
196
+ $scripts->default_version = get_bloginfo( 'version' );
197
+ $scripts->default_dirs = $default_dirs;
198
+ self::add_default_scripts( $scripts );
199
+ }
200
+
201
+ public static function add_default_scripts( &$scripts ) {
202
+
203
+ $default_path = plugins_url( 'learnpress/assets/' );
204
+ $suffix = '';
205
+ $deps = array( 'jquery', 'backbone', 'utils' );
206
+
207
+ // global
208
+ $scripts->add( 'learn-press-global', $default_path . 'js/global' . $suffix . '.js', $deps, false, 1 );
209
+ $scripts->add( 'learn-press-jalerts', $default_path . 'js/jquery.alert' . $suffix . '.js', $deps, false, 1 );
210
+
211
+ // frontend
212
+ $scripts->add( 'learn-press-js', $default_path . 'js/frontend/learnpress' . $suffix . '.js', $deps, false, 1 );
213
+ $scripts->add( 'learn-press-single-course', $default_path . 'js/frontend/single-course' . $suffix . '.js', $deps, false, 1 );
214
+ $scripts->add( 'learn-press-course-quiz', $default_path . 'js/frontend/quiz' . $suffix . '.js', $deps, false, 1 );
215
+ $scripts->add( 'learn-press-course-lesson', $default_path . 'js/frontend/lesson' . $suffix . '.js', $deps, false, 1 );
216
+ $scripts->add( 'learn-press-enroll', $default_path . 'js/frontend/enroll' . $suffix . '.js', $deps, false, 1 );
217
+ $scripts->add( 'learn-press-timer', $default_path . 'js/jquery.timer' . $suffix . '.js', $deps, false, 1 );
218
+ $scripts->add( 'learn-press-checkout', $default_path . 'js/frontend/checkout' . $suffix . '.js', $deps, false, 1 );
219
+ $scripts->add( 'learn-press-become-teacher', $default_path . 'js/frontend/become-teacher' . $suffix . '.js', $deps, false, 1 );
220
+ $scripts->add( 'learn-press-profile', $default_path . 'js/frontend/profile' . $suffix . '.js', array( 'jquery', 'backbone', 'utils', 'plupload', 'jquery-ui-slider', 'jquery-ui-draggable' ), false, 1 );
221
+ $scripts->add( 'learn-press-jquery-cropit', $default_path . 'js/jquery.cropit' . $suffix . '.js', $deps, false, 1 );
222
+ $scripts->add( 'learn-press-jquery-ocupload', $default_path . 'js/jquery.ocupload' . $suffix . '.js', $deps, false, 1 );
223
+
224
+ // admin
225
+ $scripts->add( 'learn-press-admin', $default_path . 'js/admin/admin' . $suffix . '.js', $deps, false, 1 );
226
+ $scripts->add( 'learn-press-admin-settings', $default_path . 'js/admin/settings' . $suffix . '.js', $deps, false, 1 );
227
+ $scripts->add( 'learn-press-mb-question', $default_path . 'js/admin/meta-box-question' . $suffix . '.js', $deps, false, 1 );
228
+ $scripts->add( 'learn-press-mb-course', $default_path . 'js/admin/meta-box-course' . $suffix . '.js', $deps, false, 1 );
229
+ $scripts->add( 'learn-press-mb-quiz', $default_path . 'js/admin/meta-box-quiz' . $suffix . '.js', $deps, false, 1 );
230
+ $scripts->add( 'learn-press-mb-order', $default_path . 'js/admin/meta-box-order' . $suffix . '.js', $deps, false, 1 );
231
+ $scripts->add( 'learn-press-modal-search-items', $default_path . 'js/admin/modal-search-items' . $suffix . '.js', array( 'learn-press-global' ), false, 1 );
232
+ $scripts->add( 'learn-press-order', $default_path . 'js/admin/meta-box-order' . $suffix . '.js', $deps, false, 1 );
233
+ $scripts->add( 'learn-press-statistics-select2', '/' . LP_WP_CONTENT . '/plugins/learnpress/inc/libraries/meta-box/js/select2/select2.min.js', $deps, false, 1 );
234
+
235
+ // upgrade
236
+ $scripts->add( 'learn-press-upgrade', '/' . LP_WP_CONTENT . '/plugins/learnpress/inc/updates/09/script' . $suffix . '.js', $deps, false, 1 );
237
+
238
+ do_action_ref_array( 'learn_press_add_default_scripts', array( $scripts, $default_path, $suffix, $deps ) );
239
+ }
240
+
241
+ /**
242
+ * Load default styles
243
+ *
244
+ * @param WP_Styles $styles
245
+ */
246
+ public static function default_styles( &$styles ) {
247
+ if ( !defined( 'LEARNPRESS_VERSION' ) ) {
248
+ define( 'LEARNPRESS_VERSION', '2.1.1' );
249
+ }
250
+
251
+ $develop_src = false !== strpos( LEARNPRESS_VERSION, '-src' );
252
+
253
+ if ( !defined( 'SCRIPT_DEBUG' ) ) {
254
+ define( 'SCRIPT_DEBUG', $develop_src );
255
+ }
256
+ if ( !$guessurl = site_url() ) {
257
+ $guessed_url = true;
258
+ $guessurl = wp_guess_url();
259
+ }
260
+ $default_dirs = array( '/wp-admin/css/', '/wp-includes/css/' );
261
+ $styles->base_url = $guessurl;
262
+ $styles->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : '';
263
+ $styles->default_version = get_bloginfo( 'version' );
264
+ $styles->default_dirs[] = $default_dirs;
265
+
266
+ self::add_default_styles( $styles );
267
+ }
268
+
269
+ /**
270
+ * @param WP_Styles $styles
271
+ */
272
+ public static function add_default_styles( &$styles ) {
273
+ $default_path = plugins_url( 'learnpress/assets/' );
274
+ $suffix = '';
275
+ $deps = array( 'dashicons' );
276
+ // global
277
+ $styles->add( 'learn-press-global', $default_path . 'css/global' . $suffix . '.css', $deps );
278
+
279
+ // admin
280
+ $styles->add( 'learn-press-admin', $default_path . 'css/admin/admin' . $suffix . '.css' );
281
+ $styles->add( 'learn-press-jquery.ui.datepicker', $default_path . 'css/admin/jquery.ui.datepicker' . $suffix . '.css' );
282
+ $styles->add( 'learn-press-jquery.ui.theme', $default_path . 'css/admin/jquery.ui.theme' . $suffix . '.css' );
283
+ $styles->add( 'learn-press-jquery.ui.core', $default_path . 'css/admin/jquery.ui.core' . $suffix . '.css' );
284
+ $styles->add( 'learn-press-jquery.ui.slider', $default_path . 'css/admin/jquery.ui.slider' . $suffix . '.css' );
285
+ $styles->add( 'learn-press-mb-course', $default_path . 'css/admin/meta-box-course' . $suffix . '.css' );
286
+ $styles->add( 'learn-press-mb-question', $default_path . 'css/admin/meta-box-question' . $suffix . '.css' );
287
+ $styles->add( 'learn-press-mb-order', $default_path . 'css/admin/meta-box-order' . $suffix . '.css' );
288
+ $styles->add( 'learn-press-jalerts', $default_path . 'css/jalert' . $suffix . '.css' );
289
+ $styles->add( 'learn-press-statistics-select2', '/' . LP_WP_CONTENT . '/plugins/learnpress/inc/libraries/meta-box/css/select2/select2.css' );
290
+
291
+ // frontend
292
+ $styles->add( 'learn-press-style', $default_path . 'css/learnpress.css', $deps );
293
+ do_action_ref_array( 'learn_press_add_default_styles', array( $styles, $default_path, $suffix ) );
294
+
295
+ }
296
+
297
+ /**
298
+ * register script
299
+ *
300
+ * @param string $handle
301
+ * @param string $src
302
+ * @param array $deps
303
+ * @param string $version
304
+ * @param boolean $in_footer
305
+ */
306
+ public static function add_script( $handle, $src, $deps = array( 'jquery' ), $version = LEARNPRESS_VERSION, $in_footer = true ) {
307
+ self::$scripts[] = $handle;
308
+ wp_register_script( $handle, $src, $deps, $version, $in_footer );
309
+ }
310
+
311
+ /**
312
+ * register style
313
+ *
314
+ * @param string $handle
315
+ * @param string $src
316
+ * @param array $deps
317
+ * @param string $version
318
+ * @param string $media
319
+ */
320
+ public static function add_style( $handle, $src, $deps = array(), $version = LEARNPRESS_VERSION, $media = 'all' ) {
321
+ self::$styles[] = $handle;
322
+ wp_register_style( $handle, $src, $deps, $version, $media );
323
+ }
324
+
325
+ /**
326
+ * enqueue script
327
+ *
328
+ * @param string $handle
329
+ * @param string $src
330
+ * @param array $deps
331
+ * @param string $version
332
+ * @param boolean $in_footer
333
+ */
334
+ public static function enqueue_script( $handle, $src = '', $deps = array( 'jquery' ), $version = LEARNPRESS_VERSION, $in_footer = true ) {
335
+ global $wp_scripts;
336
+
337
+ if ( is_array( $handle ) ) {
338
+ foreach ( $handle as $_handle ) {
339
+ self::enqueue_script( $_handle, $src, $deps, $version, $in_footer );
340
+ }
341
+ } else {
342
+ if ( !in_array( $handle, self::$scripts ) && $src ) {
343
+ self::add_script( $handle, $src, $deps, $version, $in_footer );
344
+ }
345
+ self::$_enqueue_scripts[$handle] = func_get_args();
346
+ if ( $deps ) {
347
+ foreach ( $deps as $dep ) {
348
+ self::add_script_concat( $dep );
349
+ }
350
+ }
351
+ self::add_script_concat( $handle );
352
+ }
353
+ }
354
+
355
+ /**
356
+ * @param $handle
357
+ */
358
+ public static function add_script_concat( $handle ) {
359
+ global $wp_scripts;
360
+ if ( !$wp_scripts ) {
361
+ return;
362
+ }
363
+ if ( empty( $wp_scripts->lp_script_concat ) ) {
364
+ $wp_scripts->lp_script_concat = array();
365
+ }
366
+ if ( strpos( $handle, 'learn-press-' ) !== false ) {
367
+ $concat = str_replace( 'learn-press-', '', $handle );
368
+ if ( !in_array( $concat, $wp_scripts->lp_script_concat ) ) {
369
+ $wp_scripts->lp_script_concat[] = $concat;
370
+ }
371
+ }
372
+ }
373
+
374
+ /**
375
+ * @param $handle
376
+ */
377
+ public static function add_style_concat( $handle ) {
378
+ global $wp_styles;
379
+ if ( !$wp_styles ) {
380
+ return;
381
+ }
382
+ if ( empty( $wp_styles->lp_style_concat ) ) {
383
+ $wp_styles->lp_style_concat = array();
384
+ }
385
+ if ( strpos( $handle, 'learn-press-' ) !== false ) {
386
+ $concat = str_replace( 'learn-press-', '', $handle );
387
+ if ( !in_array( $concat, $wp_styles->lp_style_concat ) ) {
388
+ $wp_styles->lp_style_concat[] = $concat;
389
+ }
390
+ }
391
+ }
392
+
393
+ /**
394
+ * enqueue style
395
+ *
396
+ * @param string $handle
397
+ * @param string $src
398
+ * @param array $deps
399
+ * @param string $version
400
+ * @param string $media
401
+ */
402
+ public static function enqueue_style( $handle, $src = '', $deps = array(), $version = LEARNPRESS_VERSION, $media = 'all' ) {
403
+ if ( is_array( $handle ) ) {
404
+ foreach ( $handle as $_handle ) {
405
+ self::enqueue_style( $_handle, $src, $deps, $version, $media );
406
+ }
407
+ } else {
408
+ if ( !in_array( $handle, self::$styles ) && $src ) {
409
+ self::add_style( $handle, $src, $deps, $version, $media );
410
+ }
411
+ self::$_enqueue_styles[$handle] = func_get_args();
412
+ if ( $deps ) {
413
+ foreach ( $deps as $dep ) {
414
+ self::add_style_concat( $dep );
415
+ }
416
+ }
417
+ self::add_style_concat( $handle );
418
+ }
419
+ }
420
+
421
+ /**
422
+ * add translate text
423
+ *
424
+ * @param string
425
+ * @param array $localize
426
+ * @param string
427
+ */
428
+ public static function add_localize( $key, $localize = null, $handle = '' ) {
429
+ if ( !$handle ) {
430
+ $handle = is_admin() ? 'learn-press-admin' : 'learn-press-js';
431
+ }
432
+ if ( empty( self::$wp_localize_scripts[$handle] ) ) {
433
+ self::$wp_localize_scripts[$handle] = array();
434
+ }
435
+ if ( is_array( $key ) ) {
436
+ self::$wp_localize_scripts[$handle] = array_merge( self::$wp_localize_scripts[$handle], $key );
437
+ } elseif ( is_string( $key ) && strlen( $key ) ) {
438
+ self::$wp_localize_scripts[$handle][$key] = $localize;
439
+ }
440
+ }
441
+
442
+ /**
443
+ * Add js param
444
+ *
445
+ * @param string
446
+ * @param array
447
+ * @param string
448
+ * @param $name
449
+ */
450
+ public static function add_param( $key, $param = null, $handle = 'learn-press-js', $name = null ) {
451
+ if ( !$handle ) {
452
+ $handle = 'learn-press-js';
453
+ }
454
+ if ( is_array( $handle ) ) {
455
+ foreach ( $handle as $h ) {
456
+ self::add_param( $key, $param, $h, $name );
457
+ }
458
+ return;
459
+ }
460
+ if ( empty( $name ) ) {
461
+ $name = $handle;
462
+ }
463
+ if ( empty( self::$wp_params[$handle] ) ) {
464
+ self::$wp_params[$handle] = array( $name => array() );
465
+ }
466
+ if ( empty( self::$wp_params[$handle][$name] ) ) {
467
+ self::$wp_params[$handle][$name] = array();
468
+ }
469
+
470
+ if ( is_array( $key ) ) {
471
+ self::$wp_params[$handle][$name] = array_merge( self::$wp_params[$handle][$name], $key );
472
+ } elseif ( is_string( $key ) && strlen( $key ) ) {
473
+ self::$wp_params[$handle][$name][$key] = $param;
474
+ }
475
+ }
476
+
477
+ public static function add_var( $name, $value, $handle = 'learn-press-global' ) {
478
+ if ( is_array( $handle ) ) {
479
+ foreach ( $handle as $h ) {
480
+ self::add_var( $name, $value, $h );
481
+ }
482
+ return;
483
+ }
484
+ if ( empty( self::$js_vars[$handle] ) ) {
485
+ self::$js_vars[$handle] = array();
486
+ }
487
+ self::$js_vars[$handle][$name] = $value;
488
+ }
489
+
490
+ /**
491
+ * @param $code
492
+ * @param string $handle
493
+ */
494
+ public static function add_script_tag( $code, $handle = '' ) {
495
+ if ( empty( self::$wp_script_codes[$handle] ) ) {
496
+ self::$wp_script_codes[$handle] = '';
497
+ }
498
+ self::$wp_script_codes[$handle] .= preg_replace( '!</?script(.*)>!', '', $code );
499
+ }
500
+
501
+ /**
502
+ * wp_assets
503
+ */
504
+ public static function wp_assets() {
505
+ do_action( 'learn_press_print_assets', is_admin() );
506
+ }
507
+
508
+ /**
509
+ * localize_printed_scripts
510
+ */
511
+ public static function localize_printed_scripts() {
512
+ $has_localized = !empty( self::$localized );
513
+ $has_params = !empty( self::$param_printed );
514
+ $has_vars = !empty( self::$js_vars );
515
+ if ( $has_localized || $has_params || $has_vars ) {
516
+ echo "<script type='text/javascript'>\n"; // CDATA and type='text/javascript' is not needed for HTML 5
517
+ echo "/* <![CDATA[ */\n";
518
+ if ( $has_localized ) {
519
+ if ( self::$wp_localize_scripts ) {
520
+ echo "\n/* LearnPress Localized */\n";
521
+ foreach ( self::$localized as $handle => $src ) {
522
+ if ( !empty( self::$wp_localize_scripts[$handle] ) ) {
523
+ $name = str_replace( '-', '_', $handle ) . '_localize';
524
+ echo "var {$name} = " . json_encode( self::$wp_localize_scripts[$handle] ) . ";\n";
525
+ }
526
+ }
527
+ }
528
+ }
529
+
530
+ if ( $has_params ) {
531
+ $groups = array();
532
+
533
+ foreach ( self::$param_printed as $handle ) {
534
+ if ( !empty( self::$wp_params[$handle] ) ) {
535
+ foreach ( self::$wp_params[$handle] as $name => $value ) {
536
+ $name = str_replace( '-', '_', $name );
537
+ $value = (array) ( $value );
538
+ if ( empty( $groups[$name] ) ) {
539
+ $groups[$name] = $value;
540
+ } else {
541
+ $groups[$name] = array_merge( $groups[$name], $value );
542
+ }
543
+ }
544
+ }
545
+ }
546
+ //print_r($groups);
547
+ if ( $groups ) {
548
+ echo "\n/* LearnPress Params */\n";
549
+ foreach ( $groups as $name => $code ) {
550
+ echo "var {$name} = " . wp_json_encode( $code ) . ";\n";
551
+ }
552
+ }
553
+ }
554
+
555
+
556
+ if ( $has_localized ) {
557
+ if ( self::$js_vars ) {
558
+ echo "\n/* Custom vars */\n";
559
+ $abort = array();
560
+ foreach ( self::$localized as $handle => $src ) {
561
+ if ( !empty( self::$js_vars[$handle] ) ) {
562
+ foreach ( self::$js_vars[$handle] as $name => $var ) {
563
+ if ( in_array( $name, $abort ) ) {
564
+ continue;
565
+ }
566
+ $abort[] = $name;
567
+ echo "var {$name} = " . maybe_serialize( $var ) . ";\n";
568
+ }
569
+ }
570
+ }
571
+ }
572
+ if ( self::$wp_script_codes ) {
573
+ echo "\n/* LearnPress Custom Scripts */\n ( typeof jQuery != 'undefined' ) && jQuery(function($){\n";
574
+ foreach ( self::$localized as $handle => $src ) {
575
+ if ( !empty( self::$wp_script_codes[$handle] ) ) {
576
+ echo( self::$wp_script_codes[$handle] );
577
+ }
578
+ }
579
+ echo "\n});\n";
580
+ }
581
+ }
582
+
583
+ echo "/* ]]> */\n";
584
+ echo "</script>\n";
585
+ }
586
+ }
587
+
588
+ public static function remove_script( $handle ) {
589
+ if ( isset( self::$_enqueue_scripts[$handle] ) ) {
590
+ unset( self::$_enqueue_scripts[$handle] );
591
+ }
592
+ wp_deregister_script( $handle );
593
+ }
594
+
595
+ public static function remove_style( $handle ) {
596
+ if ( isset( self::$_enqueue_styles[$handle] ) ) {
597
+ unset( self::$_enqueue_styles[$handle] );
598
+ }
599
+ wp_deregister_style( $handle );
600
+
601
+ }
602
+
603
+ /**
604
+ * _enqueue_scripts
605
+ */
606
+ public static function _enqueue_scripts() {
607
+ do_action( 'learn_press_enqueue_scripts', __CLASS__ );
608
+ if ( strpos( current_action(), 'enqueue_scripts' ) === false ) {
609
+ return;
610
+ }
611
+ if ( !empty( self::$_enqueue_scripts ) ) {
612
+ foreach ( self::$_enqueue_scripts as $handle => $args ) {
613
+ call_user_func_array( 'wp_enqueue_script', array( $handle ) );
614
+ }
615
+ }
616
+ if ( !empty( self::$_enqueue_styles ) ) {
617
+ foreach ( self::$_enqueue_styles as $handle => $args ) {
618
+ call_user_func_array( 'wp_enqueue_style', array( $handle ) );
619
+ }
620
+ }
621
+ }
622
+
623
+ /**
624
+ * Do not load script
625
+ */
626
+ public function unload_script_tag( $tag, $handle, $src ) {
627
+ if ( strpos( $handle, 'learn-press-' ) !== false && strpos( $src, '/learnpress/' ) !== false ) {
628
+ return false;
629
+ }
630
+ return $tag;
631
+ }
632
+
633
+ /**
634
+ * include_script_file
635
+ */
636
+ public function include_script_file() {
637
+ global $wp_scripts, $compress_scripts;
638
+
639
+ $zip = $compress_scripts ? 1 : 0;
640
+ if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP )
641
+ $zip = 'gzip';
642
+
643
+ if ( !empty( $wp_scripts->lp_script_concat ) && $concat = join( ',', $wp_scripts->lp_script_concat ) ) {
644
+ if ( !empty( $wp_scripts->print_code ) ) {
645
+ echo "\n<script type='text/javascript'>\n";
646
+ echo "/* <![CDATA[ */\n"; // not needed in HTML 5
647
+ echo $wp_scripts->print_code;
648
+ echo "/* ]]> */\n";
649
+ echo "</script>\n";
650
+ }
651
+
652
+ $concat = str_split( $concat, 128 );
653
+ $concat = 'load%5B%5D=' . implode( '&load%5B%5D=', $concat );
654
+
655
+ $src = get_site_url() . "/" . LP_WP_CONTENT . "/plugins/learnpress/assets/load-scripts.php?" . $concat . "&c={$zip}&ver=" . $wp_scripts->default_version;
656
+ echo "<script type='text/javascript' src='" . esc_attr( $src ) . "'></script>\n";
657
+ }
658
+
659
+ if ( !empty( $wp_scripts->print_html ) )
660
+ echo $wp_scripts->print_html;
661
+ }
662
+
663
+ /**
664
+ * include_stylesheet_file
665
+ */
666
+ public function include_stylesheet_file() {
667
+
668
+ if ( did_action( 'learn_press_included_style_file' ) ) {
669
+ return;
670
+ }
671
+
672
+ global $compress_css;
673
+
674
+ $wp_styles = wp_styles();
675
+
676
+ $zip = $compress_css ? 1 : 0;
677
+ if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP )
678
+ $zip = 'gzip';
679
+
680
+ if ( !empty( $wp_styles->lp_style_concat ) && $concat = join( ',', $wp_styles->lp_style_concat ) ) {
681
+ $dir = $wp_styles->text_direction;
682
+ $ver = $wp_styles->default_version;
683
+
684
+ $concat = str_split( $concat, 128 );
685
+ $concat = 'load%5B%5D=' . implode( '&load%5B%5D=', $concat );
686
+
687
+ $href = get_site_url() . "/" . LP_WP_CONTENT . "/plugins/learnpress/assets/load-styles.php?" . $concat . "&c={$zip}&ver=" . $ver;
688
+ echo "<link rel='stylesheet' href='" . esc_attr( $href ) . "' type='text/css' media='all' />\n";
689
+
690
+ if ( !empty( $wp_styles->print_code ) ) {
691
+ echo "<style type='text/css'>\n";
692
+ echo $wp_styles->print_code;
693
+ echo "\n</style>\n";
694
+ }
695
+ }
696
+
697
+ if ( !empty( $wp_styles->print_html ) )
698
+ echo $wp_styles->print_html;
699
+ do_action( 'learn_press_included_style_file' );
700
+ }
701
+
702
+ /**
703
+ * Load assets
704
+ */
705
+ public function load_scripts() {
706
+ $user = learn_press_get_course_user();
707
+ if ( is_admin() ) {
708
+ global $pagenow;
709
+ $screen = get_current_screen();
710
+ $screen_id = $screen->id;
711
+ $page_id = !empty( $_REQUEST['page'] ) ? $_REQUEST['page'] : '';
712
+ self::enqueue_style( 'learn-press-admin' );
713
+ if ( in_array( $screen_id, learn_press_get_screens() ) || in_array( $page_id, learn_press_get_admin_pages() ) ) {
714
+ self::enqueue_style( 'learn-press-global' );
715
+ self::enqueue_style( 'learn-press-jquery.ui.datepicker' );
716
+ self::enqueue_style( 'learn-press-jquery.ui.theme' );
717
+ self::enqueue_style( 'learn-press-jquery.ui.core' );
718
+ self::enqueue_style( 'learn-press-jquery.ui.slider' );
719
+ self::enqueue_style( 'learn-press-icons' );
720
+ self::enqueue_script( 'learn-press-global' );
721
+ self::enqueue_script( 'learn-press-admin' );
722
+ }
723
+
724
+ foreach ( array( 'lp_course', 'lp_order', 'lp_quiz', 'lp_lesson', 'lp_question' ) as $post_type ) {
725
+ if ( learn_press_is_post_type_screen( $post_type ) ) {
726
+ $type = str_replace( 'lp_', '', $post_type );
727
+ self::enqueue_style( "learn-press-mb-{$type}" );
728
+ self::enqueue_script( "learn-press-mb-{$type}" );
729
+ }
730
+ }
731
+
732
+ if ( learn_press_is_post_type_screen( array( 'lp_quiz' ) ) ) {
733
+ self::enqueue_style( 'learn-press-mb-question' );
734
+ self::enqueue_script( 'learn-press-mb-question' );
735
+ }
736
+
737
+ if ( learn_press_is_post_type_screen( array( 'lp_course', 'lp_quiz', 'lp_order' ) ) ) {
738
+ self::enqueue_style( 'learn-press-modal-search-items' );
739
+ self::enqueue_script( 'learn-press-modal-search-items' );
740
+ }
741
+
742
+ if ( $screen_id === 'learnpress_page_learn-press-settings' || $screen_id === 'dashboard' ) {
743
+ LP_Assets::enqueue_style( 'learn-press-admin' );
744
+ LP_Assets::enqueue_script( 'learn-press-admin-settings', LP()->plugin_url( 'assets/js/admin/settings.js' ) );
745
+ }
746
+
747
+ if ( $pagenow === 'edit.php' && $screen_id === 'edit-lp_course' ) {
748
+ LP_Assets::enqueue_script( 'learn-press-duplicate-course', LP()->plugin_url( 'assets/js/admin/duplicate-course.js' ) );
749
+ }
750
+
751
+ if ( $pagenow === 'post.php' && $screen_id === 'lp_quiz' ) {
752
+ self::enqueue_style( 'learn-press-jalerts' );
753
+ self::enqueue_script( 'learn-press-jalerts' );
754
+ }
755
+
756
+ if ( 'learnpress_page_learn-press-statistics' === $screen_id ) {
757
+ self::enqueue_script( 'learn-press-statistics-select2' );
758
+ self::enqueue_style( 'learn-press-statistics-select2' );
759
+ }
760
+ do_action( 'learn_press_admin_load_scripts' );
761
+ return;
762
+ }
763
+
764
+ // global
765
+ self::enqueue_style( 'learn-press-icon' );
766
+ self::enqueue_style( 'learn-press-jalerts' );
767
+
768
+ // frontend
769
+ if ( LP()->settings->get( 'load_css' ) == 'yes' || LP()->settings->get( 'load_css' ) == '' ) {
770
+ self::enqueue_style( 'learn-press-style' );
771
+ }
772
+ self::enqueue_script( 'learn-press-jalerts' );
773
+ self::enqueue_script( 'learn-press-global' );
774
+ self::enqueue_script( 'learn-press-js' );
775
+ if ( learn_press_is_course() ) {
776
+ self::enqueue_script( 'learn-press-single-course' );
777
+ self::enqueue_script( 'learn-press-course-quiz' );
778
+ self::enqueue_script( 'learn-press-course-lesson' );
779
+ if ( !$user->has_course_status( null, array( 'enrolled', 'finished' ) ) ) {
780
+ self::enqueue_script( 'learn-press-enroll' );
781
+ }
782
+ }
783
+ if ( learn_press_is_checkout() ) {
784
+ self::enqueue_script( 'learn-press-checkout' );
785
+ }
786
+ self::enqueue_script( 'learn-press-become-teacher' );
787
+
788
+ if ( learn_press_is_profile() ) {
789
+ // Localize the script with new data
790
+ $translation_array = array(
791
+ 'confim_pass_not_match' => __( 'Password and confirmation password do not match', 'learnpress' ),
792
+ 'msg_field_is_required' => __( 'This field is required', 'learnpress' )
793
+ );
794
+ wp_localize_script( 'learn-press-profile', 'lp_profile_translation', $translation_array );
795
+
796
+
797
+
798
+ self::add_param( 'avatar_size', learn_press_get_avatar_thumb_size(), 'learn-press-profile', 'LP_Settings' );
799
+
800
+ self::enqueue_script( 'learn-press-profile' );
801
+ self::enqueue_script( 'learn-press-jquery-cropit' );
802
+ self::enqueue_script( 'learn-press-jquery-ocupload' );
803
+ }
804
+ do_action( 'learn_press_load_scripts' );
805
+ }
806
+ }
807
+
808
+ // Call class
809
  return new LP_Assets();
inc/class-lp-autoloader.php CHANGED
@@ -76,18 +76,18 @@ class LP_Autoloader {
76
  $file = 'class-' . substr( str_replace( '_', '-', $class ), 5 ) . '.php';
77
  $path = $this->include_path . 'admin/meta-boxes/';
78
 
79
- } elseif ( strpos( $class, 'lp_statistic_' ) === 0 ) {
80
- $path = $this->include_path . 'admin/dashboard-statistics/';
81
- } else {
82
  $file = 'class-' . str_replace( '_', '-', $class ) . '.php';
83
  $path = dirname( __FILE__ ) . '/';
84
  if ( strpos( $class, 'lp_user' ) !== false || $class == 'lp_abstract_user' ) {
85
  $path .= 'user/';
86
  }
87
 
88
- if( ! file_exists( $path . $file ) ){
89
  $segs = explode( '_', $class );
90
- if( ! empty( $segs[1] ) ){
91
  $path .= $segs[1] . '/';
92
  }
93
  }
76
  $file = 'class-' . substr( str_replace( '_', '-', $class ), 5 ) . '.php';
77
  $path = $this->include_path . 'admin/meta-boxes/';
78
 
79
+ } elseif ( strpos( $class, 'lp_statistic_' ) === 0 ) {
80
+ $path = $this->include_path . 'admin/dashboard-statistics/';
81
+ } else {
82
  $file = 'class-' . str_replace( '_', '-', $class ) . '.php';
83
  $path = dirname( __FILE__ ) . '/';
84
  if ( strpos( $class, 'lp_user' ) !== false || $class == 'lp_abstract_user' ) {
85
  $path .= 'user/';
86
  }
87
 
88
+ if ( !file_exists( $path . $file ) ) {
89
  $segs = explode( '_', $class );
90
+ if ( !empty( $segs[1] ) ) {
91
  $path .= $segs[1] . '/';
92
  }
93
  }
inc/class-lp-install.php CHANGED
@@ -1,657 +1,656 @@
1
- <?php
2
- /**
3
- * Install and update functions
4
- *
5
- * @author ThimPress
6
- * @version 1.0
7
- * @see https://codex.wordpress.org/Creating_Tables_with_Plugins
8
- */
9
-
10
- /**
11
- * Prevent loading this file directly
12
- */
13
- defined( 'ABSPATH' ) || exit;
14
- define( 'LEARN_PRESS_UPDATE_DATABASE', true );
15
-
16
- /**
17
- * Class LP_Install
18
- */
19
- class LP_Install {
20
-
21
- /**
22
- * Hold the file for each update
23
- *
24
- * @var array
25
- */
26
- private static $_update_files = array();
27
-
28
- /**
29
- * @var null
30
- */
31
- private static $_is_old_version = null;
32
-
33
- /**
34
- * Default static pages used by LP
35
- *
36
- * @var array
37
- */
38
- private static $_pages = array( 'checkout', 'cart', 'profile', 'courses', 'become_a_teacher' );
39
-
40
- /**
41
- * Init
42
- */
43
- public static function init() {
44
- add_action( 'learn_press_activate', array( __CLASS__, 'install' ) );
45
- add_action( 'admin_init', array( __CLASS__, 'include_update' ), - 10 );
46
- add_action( 'admin_init', array( __CLASS__, 'update_from_09' ), 5 );
47
- add_action( 'admin_init', array( __CLASS__, 'check_version' ), 5 );
48
- add_action( 'admin_init', array( __CLASS__, 'db_update_notices' ), 5 );
49
- add_action( 'admin_init', array( __CLASS__, 'update_actions' ), 5 );
50
- add_action( 'wp_ajax_lp_repair_database', array( __CLASS__, 'repair_database' ) );
51
- add_action( 'wp_ajax_lp_rollback_database', array( __CLASS__, 'rollback_database' ) );
52
- add_action( 'wp_ajax_learn_press_hide_upgrade_notice', array( __CLASS__, 'hide_upgrade_notice' ) );
53
- add_action( 'admin_init', array( __CLASS__, 'upgrade_wizard' ) );
54
- add_action( 'admin_menu', array( __CLASS__, 'admin_menu' ) );
55
- }
56
-
57
- public static function include_update() {
58
- if ( !self::$_update_files ) {
59
- return;
60
- }
61
- $versions = array_keys( self::$_update_files );
62
- $latest_version = end( $versions );
63
- // Update LearnPress from 0.9.x to 1.0
64
- if ( version_compare( learn_press_get_current_version(), $latest_version, '=' ) ) {
65
- add_action( 'admin_notices', array( __CLASS__, 'hide_other_notices' ), - 100 );
66
- learn_press_include( 'updates/' . self::$_update_files[$latest_version] );
67
- }
68
- }
69
-
70
- public static function hide_other_notices() {
71
- //remove_action( 'admin_notices', 'learn_press_one_click_install_sample_data_notice' );
72
- }
73
-
74
- public static function update_from_09() {
75
-
76
- if ( !self::_has_new_table() || version_compare( LEARNPRESS_VERSION, get_option( 'learnpress_db_version' ), '>' ) ) {
77
- self::install();
78
- }
79
- if ( !get_option( 'learnpress_version' ) || !get_option( 'learn_press_currency' ) ) {
80
- self::_create_options();
81
- }
82
- $ask = get_transient( 'learn_press_upgrade_courses_ask_again' );
83
- if ( self::_need_to_update() ) {
84
- // Notify for administrator
85
- if ( empty( $ask ) && learn_press_current_user_is( 'administrator' ) ) {
86
- LP_Assets::enqueue_style( 'learn-press-upgrade', LP()->plugin_url( 'inc/updates/09/style.css' ) );
87
- LP_Assets::enqueue_script( 'learn-press-upgrade', LP()->plugin_url( 'inc/updates/09/script.js' ) );
88
- $upgrade_url = wp_nonce_url( admin_url( 'options-general.php?page=learn_press_upgrade_from_09' ), 'learn-press-upgrade-09' );
89
- $message = sprintf( '<p>%s</p>', __( 'It seems like you have updated LearnPress from an older version and there are some outdated courses or data that need to be upgraded.', 'learnpress' ) );
90
- $message .= sprintf( '<div id="learn-press-confirm-abort-upgrade-course"><p><label><input type="checkbox" id="learn-press-ask-again-abort-upgrade" /> %s</label></p><p><button href="" class="button disabled" data-action="yes">%s</button> <button href="" class="button" data-action="no">%s</button> </p></div>', __( 'Do not ask again.', 'learnpress' ), __( 'Ok', 'learnpress' ), __( 'Cancel', 'learnpress' ) );
91
- $message .= sprintf( '<p id="learn-press-upgrade-course-actions"><a href="%s" class="button" data-action="upgrade">%s</a>&nbsp;<button class="button disabled" data-action="abort">%s</button></p>', $upgrade_url, __( 'Upgrade now', 'learnpress' ), __( 'No, thank!', 'learnpress' ) );
92
-
93
- LP_Admin_Notice::add( $message, 'error' );
94
- }
95
-
96
- // Notify for instructor
97
- if ( learn_press_current_user_is( 'instructor' ) ) {
98
- LP_Admin_Notice::add( sprintf( '<p>%s</p>', __( 'LearnPress has upgraded and need to upgrade the database before you can work with it. Please notify the site administrator.', 'learnpress' ) ), 'error' );
99
- }
100
- }
101
- }
102
-
103
- public static function admin_menu() {
104
- add_dashboard_page( '', '', 'manage_options', 'learn_press_upgrade_from_09', '' );
105
- }
106
-
107
- public static function hide_upgrade_notice() {
108
- $ask_again = learn_press_get_request( 'ask_again' );
109
- $expiration = DAY_IN_SECONDS;
110
- if ( $ask_again == 'no' ) {
111
- $expiration = 0;
112
- }
113
- set_transient( 'learn_press_upgrade_courses_ask_again', $ask_again, $expiration );
114
- learn_press_send_json( array( 'result' => 'success', 'message' => sprintf( '<p>%s</p>', __( 'Thank you for using LearnPress', 'learnpress' ) ) ) );
115
- }
116
-
117
- public static function upgrade_wizard() {
118
- require_once LP_PLUGIN_PATH . '/inc/updates/_update-from-0.9.php';
119
- }
120
-
121
- /**
122
- * Auto get update patches from inc/updates path
123
- */
124
- public static function get_update_versions() {
125
-
126
- if ( !$patches = get_transient( 'learnpress_update_patches' ) ) {
127
- $patches = array();
128
- require_once ABSPATH . 'wp-admin/includes/file.php';
129
- if ( WP_Filesystem() ) {
130
- global $wp_filesystem;
131
-
132
- $list = $wp_filesystem->dirlist( LP_PLUGIN_PATH . '/inc/updates' );
133
- foreach ( $list as $file ) {
134
- if ( preg_match( '!learnpress-update-([0-9.]+).php!', $file['name'], $matches ) ) {
135
- $patches[$matches[1]] = $file['name'];
136
- }
137
- }
138
- }
139
- if ( $patches ) {
140
- ksort( $patches );
141
- self::$_update_files = $patches;
142
- }
143
- } else {
144
- self::$_update_files = $patches;
145
- }
146
- }
147
-
148
- /**
149
- * Check version
150
- */
151
- public static function check_version() {
152
- if ( !defined( 'IFRAME_REQUEST' ) && ( get_option( 'learnpress_version' ) != LP()->version ) ) {
153
- self::install();
154
- }
155
- }
156
-
157
- /**
158
- * Install update actions when user click update button
159
- */
160
- public static function update_actions() {
161
- if ( !empty( $_GET['upgrade_learnpress'] ) ) {
162
- self::update();
163
- }
164
- }
165
-
166
- /**
167
- * Check for new database version and show notice
168
- */
169
- public static function db_update_notices() {
170
- if ( get_option( 'learnpress_db_version' ) != LP()->version ) {
171
- }
172
- }
173
-
174
- public static function install() {
175
- global $wpdb;
176
- self::_create_options();
177
- self::_create_tables();
178
- self::_create_cron_jobs();
179
- self::create_files();
180
- self::create_files();
181
- self::create_pages();
182
-
183
- $sql = "DELETE a, b FROM $wpdb->options a, $wpdb->options b
184
- WHERE a.option_name LIKE %s
185
- AND a.option_name NOT LIKE %s
186
- AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
187
- AND b.option_value < %d";
188
- $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_transient_' ) . '%', $wpdb->esc_like( '_transient_timeout_' ) . '%', time() ) );
189
-
190
- // Fix for WP 4.7
191
- if ( did_action( 'admin_init' ) ) {
192
- self::_auto_update();
193
- } else {
194
- add_action( 'admin_init', array( __CLASS__, '_auto_update' ), - 15 );
195
- }
196
- }
197
-
198
- private static function _create_cron_jobs() {
199
- wp_clear_scheduled_hook( 'learn_press_cleanup_sessions' );
200
- wp_schedule_event( time(), apply_filters( 'learn_press_cleanup_session_recurrence', 'twicedaily' ), 'learn_press_cleanup_sessions' );
201
- }
202
-
203
- public static function _auto_update() {
204
- self::get_update_versions();
205
- self::update();
206
- }
207
-
208
- public static function _search_page( $type, $types ) {
209
- static $pages = array();
210
- if ( empty( $pages[$type] ) ) {
211
- global $wpdb;
212
- $in_types = array_fill( 0, sizeof( $types ), '%s' );
213
- $args = array( '_learn_press_page' );
214
- $args = array_merge( $args, $types );
215
- $args[] = 'publish';
216
- $query = $wpdb->prepare( "
217
- SELECT ID, pm.meta_value as type
218
- FROM {$wpdb->posts} p
219
- INNER JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID AND pm.meta_key = %s AND pm.meta_value IN(" . join( ',', $in_types ) . ")
220
- WHERE p.post_status = %s
221
- ", $args );
222
- if ( $rows = $wpdb->get_results( $query ) ) {
223
- foreach ( $rows as $row ) {
224
- $pages[$row->type] = $row->ID;
225
- }
226
- }
227
- }
228
-
229
- $page_id = !empty( $pages[$type] ) ? $pages[$type] : 0;
230
-
231
- return $page_id;
232
- }
233
-
234
- /**
235
- * Remove learnpress page if total of learn page > 10
236
- * @global type $wpdb
237
- * @return type
238
- */
239
- public static function _remove_pages() {
240
- global $wpdb;
241
- $sql = 'SELECT * '
242
- . ' FROM ' . $wpdb->posts . ' p INNER JOIN ' . $wpdb->postmeta . ' pm '
243
- . ' ON p.ID=pm.post_id AND pm.meta_key="_learn_press_page" AND p.post_type="page";';
244
- $ids = $wpdb->get_col( $sql );
245
- $count_ids = count( $ids );
246
- if ( $count_ids < 10 ) {
247
- return $ids;
248
- }
249
- $q = $wpdb->prepare( "
250
- DELETE FROM p, pm
251
- USING {$wpdb->posts} AS p LEFT JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id AND p.post_type IN('page')
252
- WHERE %d AND p.post_status='publish' AND p.ID IN(" . implode( ',', $ids ) . ")
253
- ", 1 );
254
-
255
- $wpdb->query( $q );
256
-
257
- $pages = self::$_pages;
258
- foreach ( $pages as $page ) {
259
- delete_option( "learn_press_{$page}_page_id" );
260
- }
261
- sleep( 5 );
262
- return array();
263
-
264
- }
265
-
266
- public static function create_pages() {
267
- global $wpdb;
268
- $created_page = self::_remove_pages();
269
-
270
- if ( !empty( $created_page ) ) {
271
- return;
272
- }
273
-
274
- $pages = self::$_pages;
275
- foreach ( $pages as $page ) {
276
- $page_id = get_option( "learn_press_{$page}_page_id" );
277
- if ( $page_id && get_post_type( $page_id ) == 'page' && get_post_status( $page_id ) == 'publish' ) {
278
- continue;
279
- }
280
- $page_id = self::_search_page( $page, $pages );
281
- if ( !$page_id ) {
282
- // Check if page has already existed
283
- switch ( $page ) {
284
- case 'courses':
285
- $_lpr_settings_pages = (array) get_option( '_lpr_settings_pages' );
286
-
287
- if ( !empty( $_lpr_settings_pages['general'] ) ) {
288
- if ( !empty( $_lpr_settings_pages['general']['courses_page_id'] ) ) {
289
- $page_id = $_lpr_settings_pages['general']['courses_page_id'];
290
- }
291
- }
292
- break;
293
- case 'profile':
294
- $_lpr_settings_general = (array) get_option( '_lpr_settings_general' );
295
- if ( !empty( $_lpr_settings_general['set_page'] ) && $_lpr_settings_general['set_page'] == 'lpr_profile' ) {
296
- $page_id = $wpdb->get_var(
297
- $wpdb->prepare( "
298
- SELECT ID
299
- FROM $wpdb->posts p
300
- INNER JOIN $wpdb->postmeta pm ON p.ID = pm.post_id AND pm.meta_key = %s AND pm.meta_value = %d
301
- ", '_lpr_is_profile_page', 1 )
302
- );
303
- }
304
- break;
305
- }
306
-
307
- if ( !$page_id ) {
308
- $inserted = wp_insert_post(
309
- array(
310
- 'post_title' => 'LP ' . ucwords( str_replace( '_', ' ', $page ) ),
311
- 'post_status' => 'publish',
312
- 'post_type' => 'page',
313
- 'comment_status' => 'closed'
314
- )
315
- );
316
- if ( $inserted ) {
317
- $page_id = $inserted;
318
- }
319
- }
320
- }
321
- if ( $page_id ) {
322
- update_option( "learn_press_{$page}_page_id", $page_id );
323
- update_post_meta( $page_id, '_learn_press_page', $page );
324
- }
325
- }
326
- flush_rewrite_rules();
327
- }
328
-
329
- public static function create_files() {
330
- $upload_dir = wp_upload_dir();
331
- $files = array(
332
- array(
333
- 'base' => LP_LOG_PATH,
334
- 'file' => '.htaccess',
335
- 'content' => 'deny from all'
336
- ),
337
- array(
338
- 'base' => LP_LOG_PATH,
339
- 'file' => 'index.html',
340
- 'content' => ''
341
- )
342
- );
343
-
344
- foreach ( $files as $file ) {
345
- if ( wp_mkdir_p( $file['base'] ) && !file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
346
- if ( $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ) ) {
347
- fwrite( $file_handle, $file['content'] );
348
- fclose( $file_handle );
349
- }
350
- }
351
- }
352
- }
353
-
354
- private function _is_old_version() {
355
- if ( is_null( self::$_is_old_version ) ) {
356
- $is_old_version = get_transient( 'learn_press_is_old_version' );
357
-
358
- if ( empty( $is_old_version ) ) {
359
- if ( !get_option( 'learnpress_db_version' ) ||
360
- get_posts(
361
- array(
362
- 'post_type' => 'lpr_course',
363
- 'post_status' => 'any',
364
- 'posts_per_page' => 1
365
- )
366
- )
367
- ) {
368
- $is_old_version = 'yes';
369
- }
370
- if ( empty( $is_old_version ) ) {
371
- $is_old_version = 'no';
372
- }
373
- set_transient( 'learn_press_is_old_version', $is_old_version );
374
- }
375
- self::$_is_old_version = $is_old_version == 'yes';
376
- }
377
- return self::$_is_old_version;
378
- }
379
-
380
- /**
381
- * Find if there is any old course and did not upgrade
382
- * If a course has got a meta key like _learn_press_upgraded that means it is not upgraded
383
- *
384
- * @return mixed
385
- */
386
- private static function _has_old_posts() {
387
- global $wpdb;
388
- $query = $wpdb->prepare( "
389
- SELECT DISTINCT p.ID, pm.meta_value as upgraded
390
- FROM {$wpdb->posts} p
391
- LEFT JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID AND pm.meta_key = %s
392
- WHERE post_type = %s
393
- HAVING upgraded IS NULL
394
- LIMIT 0, 1
395
- ", '_learn_press_upgraded', 'lpr_course' );
396
- return $wpdb->get_row( $query );
397
- }
398
-
399
- private static function _has_new_table() {
400
- global $wpdb;
401
- $query = $wpdb->prepare( "
402
- SELECT COUNT(*)
403
- FROM information_schema.tables
404
- WHERE table_schema = %s
405
- AND table_name LIKE %s
406
- ", DB_NAME, '%learnpress_sections%' );
407
- return $wpdb->get_var( $query ) ? true : false;
408
- }
409
-
410
- private static function _need_to_update() {
411
- return self::_has_old_posts() || self::_has_old_teacher_role();
412
- }
413
-
414
- private static function _has_old_teacher_role() {
415
- global $wpdb;
416
- $query = $wpdb->prepare( "
417
- SELECT um.*
418
- FROM {$wpdb->users} u
419
- INNER JOIN {$wpdb->usermeta} um ON um.user_id = u.ID AND um.meta_key = %s
420
- WHERE um.meta_value LIKE %s
421
- LIMIT 0, 1
422
- ", 'wp_capabilities', '%"lpr_teacher"%' );
423
- return $wpdb->get_results( $query );
424
- }
425
-
426
- private static function _has_new_posts() {
427
- $new_post = get_posts(
428
- array(
429
- 'post_type' => 'lp_course',
430
- 'post_status' => 'any',
431
- 'posts_per_page' => 1
432
- )
433
- );
434
- return sizeof( $new_post ) > 0;
435
- }
436
-
437
- public static function update() {
438
- $learnpress_db_version = get_option( 'learnpress_db_version' );
439
-
440
- foreach ( self::$_update_files as $version => $updater ) {
441
- if ( version_compare( $learnpress_db_version, $version, '<' ) ) {
442
- @include( LP_PLUGIN_PATH . '/inc/updates/' . $updater );
443
- self::update_db_version( $version );
444
- }
445
- }
446
-
447
- self::update_db_version();
448
- self::update_version();
449
- }
450
-
451
- public static function update_db_version( $version = null ) {
452
- delete_option( 'learnpress_db_version' );
453
- update_option( 'learnpress_db_version', is_null( $version ) ? LEARNPRESS_VERSION : $version );
454
- }
455
-
456
- public static function update_version( $version = null ) {
457
-
458
- delete_option( 'learnpress_version' );
459
- update_option( 'learnpress_version', is_null( $version ) ? LEARNPRESS_VERSION : $version );
460
- }
461
-
462
- private static function _create_options() {
463
- include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-base.php';
464
- $settings_classes = array(
465
- 'LP_Settings_General' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-general.php',
466
- 'LP_Settings_Courses' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-courses.php',
467
- 'LP_Settings_Pages' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-pages.php',
468
- 'LP_Settings_Checkout' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-checkout.php',
469
- 'LP_Settings_Profile' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-profile.php',
470
- 'LP_Settings_Emails' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-emails.php'
471
- );
472
- foreach ( $settings_classes as $c => $class ) {
473
- if ( !is_object( $class ) ) {
474
- $class = @new $c();
475
- }
476
- if ( is_callable( array( $class, 'get_settings' ) ) ) {
477
- $options = $class->get_settings();
478
- foreach ( $options as $option ) {
479
- if ( isset( $option['default'] ) && isset( $option['id'] ) ) {
480
- $autoload = isset( $option['autoload'] ) ? (bool) $option['autoload'] : true;
481
- $value = get_option( $option['id'], $option['default'] );
482
- update_option( $option['id'], $value, '', ( $autoload ? 'yes' : 'no' ) );
483
- }
484
- }
485
- }
486
- }
487
- $custom_options = array(
488
- 'learn_press_course_base_type' => 'custom',
489
- 'learn_press_paypal_email' => get_option( 'admin_email' ),
490
- 'learn_press_paypal_enable' => 'yes',
491
- 'learn_press_profile_endpoints' => 'a:4:{s:15:"profile-courses";s:7:"courses";s:15:"profile-quizzes";s:7:"quizzes";s:14:"profile-orders";s:6:"orders";s:21:"profile-order-details";s:13:"order-details";}',
492
- 'learn_press_checkout_endpoints' => 'a:1:{s:17:"lp_order_received";s:17:"lp-order-received";}'
493
- );
494
- foreach ( $custom_options as $option_name => $option_value ) {
495
- if ( !get_option( $option_name ) ) {
496
- update_option( $option_name, maybe_unserialize( $option_value ), 'yes' );
497
- }
498
- }
499
- set_transient( 'learn_press_install', 'yes', 24 * 3600 );
500
- }
501
-
502
- private static function _create_tables() {
503
- global $wpdb;
504
-
505
- $wpdb->hide_errors();
506
-
507
- require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
508
- $schema = self::_get_schema();
509
- if ( $schema ) {
510
- dbDelta( $schema );
511
- }
512
- LP_Debug::instance()->add( 'create_table' );
513
- }
514
-
515
- private static function _get_schema() {
516
- global $wpdb;
517
-
518
- $collate = '';
519
-
520
- if ( $wpdb->has_cap( 'collation' ) ) {
521
- if ( !empty( $wpdb->charset ) ) {
522
- $collate .= "DEFAULT CHARACTER SET $wpdb->charset";
523
- }
524
- if ( !empty( $wpdb->collate ) ) {
525
- $collate .= " COLLATE $wpdb->collate";
526
- }
527
- }
528
-
529
- $table = $wpdb->prefix . 'learnpress_order_itemmeta';
530
- $query = '';
531
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
532
- $query .= "
533
- CREATE TABLE {$wpdb->prefix}learnpress_order_itemmeta (
534
- meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
535
- learnpress_order_item_id bigint(20) unsigned NOT NULL DEFAULT '0',
536
- meta_key varchar(45) NOT NULL DEFAULT '',
537
- meta_value longtext NOT NULL,
538
- PRIMARY KEY (meta_id)
539
- ) $collate;";
540
- }
541
- $table = $wpdb->prefix . 'learnpress_order_items';
542
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
543
- $query .= "
544
- CREATE TABLE {$wpdb->prefix}learnpress_order_items (
545
- order_item_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
546
- order_item_name longtext NOT NULL,
547
- order_id bigint(20) unsigned NOT NULL DEFAULT '0',
548
- PRIMARY KEY (order_item_id)
549
- ) $collate;";
550
- }
551
- $table = $wpdb->prefix . 'learnpress_question_answers';
552
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
553
- $query .= "
554
- CREATE TABLE {$wpdb->prefix}learnpress_question_answers (
555
- question_answer_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
556
- question_id bigint(20) unsigned NOT NULL DEFAULT '0',
557
- answer_data text NOT NULL,
558
- answer_order bigint(20) unsigned NOT NULL DEFAULT '0',
559
- PRIMARY KEY (question_answer_id)
560
- ) $collate;";
561
- }
562
- $table = $wpdb->prefix . 'learnpress_quiz_questions';
563
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
564
- $query .= "
565
- CREATE TABLE {$wpdb->prefix}learnpress_quiz_questions (
566
- quiz_question_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
567
- quiz_id bigint(20) unsigned NOT NULL DEFAULT '0',
568
- question_id bigint(20) unsigned NOT NULL DEFAULT '0',
569
- question_order bigint(20) unsigned NOT NULL DEFAULT '1',
570
- params longtext NULL,
571
- PRIMARY KEY (quiz_question_id)
572
- ) $collate;";
573
- }
574
- $table = $wpdb->prefix . 'learnpress_review_logs';
575
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
576
- $query .= "
577
- CREATE TABLE {$wpdb->prefix}learnpress_review_logs (
578
- review_log_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
579
- course_id bigint(20) unsigned NOT NULL DEFAULT '0',
580
- user_id bigint(20) unsigned NOT NULL DEFAULT '0',
581
- message text NOT NULL,
582
- date datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
583
- status varchar(45) NOT NULL DEFAULT '',
584
- user_type varchar(45) NOT NULL DEFAULT '',
585
- PRIMARY KEY (review_log_id)
586
- ) $collate;";
587
- }
588
- $table = $wpdb->prefix . 'learnpress_section_items';
589
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
590
- $query .= "
591
- CREATE TABLE {$wpdb->prefix}learnpress_section_items (
592
- section_item_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
593
- section_id bigint(20) unsigned NOT NULL DEFAULT '0',
594
- item_id bigint(20) unsigned NOT NULL DEFAULT '0',
595
- item_order bigint(20) unsigned NOT NULL DEFAULT '0',
596
- item_type varchar(45),
597
- PRIMARY KEY (section_item_id)
598
- ) $collate;";
599
- }
600
- $table = $wpdb->prefix . 'learnpress_sections';
601
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
602
- $query .= "
603
- CREATE TABLE {$wpdb->prefix}learnpress_sections (
604
- section_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
605
- section_name varchar(255) NOT NULL DEFAULT '',
606
- section_course_id bigint(20) unsigned NOT NULL DEFAULT '0',
607
- section_order bigint(5) unsigned NOT NULL DEFAULT '0',
608
- section_description longtext NOT NULL,
609
- PRIMARY KEY (section_id)
610
- ) $collate;";
611
- }
612
- $table = $wpdb->prefix . 'learnpress_sessions';
613
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
614
- $query .= "
615
- CREATE TABLE {$wpdb->prefix}learnpress_sessions (
616
- session_id bigint(20) NOT NULL AUTO_INCREMENT,
617
- session_key char(32) NOT NULL,
618
- session_value longtext NOT NULL,
619
- session_expiry bigint(20) NOT NULL,
620
- UNIQUE KEY session_id (session_id),
621
- PRIMARY KEY (session_key)
622
- ) $collate;";
623
- }
624
- $table = $wpdb->prefix . 'learnpress_user_items';
625
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
626
- $query .= "
627
- CREATE TABLE {$wpdb->prefix}learnpress_user_items (
628
- user_item_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
629
- user_id bigint(20) unsigned NOT NULL DEFAULT '0',
630
- item_id bigint(20) unsigned NOT NULL DEFAULT '0',
631
- start_time datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
632
- end_time datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
633
- item_type varchar(45) NOT NULL DEFAULT '',
634
- status varchar(45) NOT NULL DEFAULT '',
635
- ref_id bigint(20) unsigned NOT NULL DEFAULT '0',
636
- ref_type varchar(45) DEFAULT '',
637
- parent_id bigint(20) unsigned NOT NULL DEFAULT '0',
638
- PRIMARY KEY (user_item_id)
639
- ) $collate;";
640
- }
641
- $table = $wpdb->prefix . 'learnpress_user_itemmeta';
642
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
643
- $query .= "
644
- CREATE TABLE {$wpdb->prefix}learnpress_user_itemmeta (
645
- meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
646
- learnpress_user_item_id bigint(20) unsigned NOT NULL,
647
- meta_key varchar(45) NOT NULL DEFAULT '',
648
- meta_value text NOT NULL,
649
- PRIMARY KEY (meta_id)
650
- ) $collate;
651
- ";
652
- }
653
- return $query;
654
- }
655
- }
656
-
657
- LP_Install::init();
1
+ <?php
2
+ /**
3
+ * Install and update functions
4
+ *
5
+ * @author ThimPress
6
+ * @version 1.0
7
+ * @see https://codex.wordpress.org/Creating_Tables_with_Plugins
8
+ */
9
+
10
+ /**
11
+ * Prevent loading this file directly
12
+ */
13
+ defined( 'ABSPATH' ) || exit;
14
+ define( 'LEARN_PRESS_UPDATE_DATABASE', true );
15
+
16
+ /**
17
+ * Class LP_Install
18
+ */
19
+ class LP_Install {
20
+
21
+ /**
22
+ * Hold the file for each update
23
+ *
24
+ * @var array
25
+ */
26
+ private static $_update_files = array();
27
+
28
+ /**
29
+ * @var null
30
+ */
31
+ private static $_is_old_version = null;
32
+
33
+ /**
34
+ * Default static pages used by LP
35
+ *
36
+ * @var array
37
+ */
38
+ private static $_pages = array( 'checkout', 'cart', 'profile', 'courses', 'become_a_teacher' );
39
+
40
+ /**
41
+ * Init
42
+ */
43
+ public static function init() {
44
+ add_action( 'learn_press_activate', array( __CLASS__, 'install' ) );
45
+ add_action( 'admin_init', array( __CLASS__, 'include_update' ), - 10 );
46
+ add_action( 'admin_init', array( __CLASS__, 'update_from_09' ), 5 );
47
+ add_action( 'admin_init', array( __CLASS__, 'check_version' ), 5 );
48
+ add_action( 'admin_init', array( __CLASS__, 'db_update_notices' ), 5 );
49
+ add_action( 'admin_init', array( __CLASS__, 'update_actions' ), 5 );
50
+ add_action( 'wp_ajax_lp_repair_database', array( __CLASS__, 'repair_database' ) );
51
+ add_action( 'wp_ajax_lp_rollback_database', array( __CLASS__, 'rollback_database' ) );
52
+ add_action( 'wp_ajax_learn_press_hide_upgrade_notice', array( __CLASS__, 'hide_upgrade_notice' ) );
53
+ add_action( 'admin_init', array( __CLASS__, 'upgrade_wizard' ) );
54
+ add_action( 'admin_menu', array( __CLASS__, 'admin_menu' ) );
55
+ }
56
+
57
+ public static function include_update() {
58
+ if ( !self::$_update_files ) {
59
+ return;
60
+ }
61
+ $versions = array_keys( self::$_update_files );
62
+ $latest_version = end( $versions );
63
+ // Update LearnPress from 0.9.x to 1.0
64
+ if ( version_compare( learn_press_get_current_version(), $latest_version, '=' ) ) {
65
+ add_action( 'admin_notices', array( __CLASS__, 'hide_other_notices' ), - 100 );
66
+ learn_press_include( 'updates/' . self::$_update_files[$latest_version] );
67
+ }
68
+ }
69
+
70
+ public static function hide_other_notices() {
71
+ //remove_action( 'admin_notices', 'learn_press_one_click_install_sample_data_notice' );
72
+ }
73
+
74
+ public static function update_from_09() {
75
+
76
+ if ( !self::_has_new_table() || version_compare( LEARNPRESS_VERSION, get_option( 'learnpress_db_version' ), '>' ) ) {
77
+ self::install();
78
+ }
79
+ if ( !get_option( 'learnpress_version' ) || !get_option( 'learn_press_currency' ) ) {
80
+ self::_create_options();
81
+ }
82
+ $ask = get_transient( 'learn_press_upgrade_courses_ask_again' );
83
+ if ( self::_need_to_update() ) {
84
+ // Notify for administrator
85
+ if ( empty( $ask ) && learn_press_current_user_is( 'administrator' ) ) {
86
+ LP_Assets::enqueue_style( 'learn-press-upgrade', LP()->plugin_url( 'inc/updates/09/style.css' ) );
87
+ LP_Assets::enqueue_script( 'learn-press-upgrade', LP()->plugin_url( 'inc/updates/09/script.js' ) );
88
+ $upgrade_url = wp_nonce_url( admin_url( 'options-general.php?page=learn_press_upgrade_from_09' ), 'learn-press-upgrade-09' );
89
+ $message = sprintf( '<p>%s</p>', __( 'It seems like you have updated LearnPress from an older version and there are some outdated courses or data that need to be upgraded.', 'learnpress' ) );
90
+ $message .= sprintf( '<div id="learn-press-confirm-abort-upgrade-course"><p><label><input type="checkbox" id="learn-press-ask-again-abort-upgrade" /> %s</label></p><p><button href="" class="button disabled" data-action="yes">%s</button> <button href="" class="button" data-action="no">%s</button> </p></div>', __( 'Do not ask again.', 'learnpress' ), __( 'Ok', 'learnpress' ), __( 'Cancel', 'learnpress' ) );
91
+ $message .= sprintf( '<p id="learn-press-upgrade-course-actions"><a href="%s" class="button" data-action="upgrade">%s</a>&nbsp;<button class="button disabled" data-action="abort">%s</button></p>', $upgrade_url, __( 'Upgrade now', 'learnpress' ), __( 'No, thank!', 'learnpress' ) );
92
+
93
+ LP_Admin_Notice::add( $message, 'error' );
94
+ }
95
+
96
+ // Notify for instructor
97
+ if ( learn_press_current_user_is( 'instructor' ) ) {
98
+ LP_Admin_Notice::add( sprintf( '<p>%s</p>', __( 'LearnPress has upgraded and need to upgrade the database before you can work with it. Please notify the site administrator.', 'learnpress' ) ), 'error' );
99
+ }
100
+ }
101
+ }
102
+
103
+ public static function admin_menu() {
104
+ add_dashboard_page( '', '', 'manage_options', 'learn_press_upgrade_from_09', '' );
105
+ }
106
+
107
+ public static function hide_upgrade_notice() {
108
+ $ask_again = learn_press_get_request( 'ask_again' );
109
+ $expiration = DAY_IN_SECONDS;
110
+ if ( $ask_again == 'no' ) {
111
+ $expiration = 0;
112
+ }
113
+ set_transient( 'learn_press_upgrade_courses_ask_again', $ask_again, $expiration );
114
+ learn_press_send_json( array( 'result' => 'success', 'message' => sprintf( '<p>%s</p>', __( 'Thank you for using LearnPress', 'learnpress' ) ) ) );
115
+ }
116
+
117
+ public static function upgrade_wizard() {
118
+ require_once LP_PLUGIN_PATH . '/inc/updates/_update-from-0.9.php';
119
+ }
120
+
121
+ /**
122
+ * Auto get update patches from inc/updates path
123
+ */
124
+ public static function get_update_versions() {
125
+
126
+ if ( !$patches = get_transient( 'learnpress_update_patches' ) ) {
127
+ $patches = array();
128
+ require_once ABSPATH . 'wp-admin/includes/file.php';
129
+ if ( WP_Filesystem() ) {
130
+ global $wp_filesystem;
131
+
132
+ $list = $wp_filesystem->dirlist( LP_PLUGIN_PATH . '/inc/updates' );
133
+ foreach ( $list as $file ) {
134
+ if ( preg_match( '!learnpress-update-([0-9.]+).php!', $file['name'], $matches ) ) {
135
+ $patches[$matches[1]] = $file['name'];
136
+ }
137
+ }
138
+ }
139
+ if ( $patches ) {
140
+ ksort( $patches );
141
+ self::$_update_files = $patches;
142
+ }
143
+ } else {
144
+ self::$_update_files = $patches;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Check version
150
+ */
151
+ public static function check_version() {
152
+ if ( !defined( 'IFRAME_REQUEST' ) && ( get_option( 'learnpress_version' ) != LP()->version ) ) {
153
+ self::install();
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Install update actions when user click update button
159
+ */
160
+ public static function update_actions() {
161
+ if ( !empty( $_GET['upgrade_learnpress'] ) ) {
162
+ self::update();
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Check for new database version and show notice
168
+ */
169
+ public static function db_update_notices() {
170
+ if ( get_option( 'learnpress_db_version' ) != LP()->version ) {
171
+ }
172
+ }
173
+
174
+ public static function install() {
175
+ global $wpdb;
176
+ self::_create_options();
177
+ self::_create_tables();
178
+ self::_create_cron_jobs();
179
+ self::create_files();
180
+ self::create_files();
181
+ self::create_pages();
182
+ $sql = "DELETE a, b FROM $wpdb->options a, $wpdb->options b
183
+ WHERE a.option_name LIKE %s
184
+ AND a.option_name NOT LIKE %s
185
+ AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
186
+ AND b.option_value < %d";
187
+ $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_transient_' ) . '%', $wpdb->esc_like( '_transient_timeout_' ) . '%', time() ) );
188
+
189
+ // Fix for WP 4.7
190
+ if ( did_action( 'admin_init' ) ) {
191
+ self::_auto_update();
192
+ } else {
193
+ add_action( 'admin_init', array( __CLASS__, '_auto_update' ), - 15 );
194
+ }
195
+ }
196
+
197
+ private static function _create_cron_jobs() {
198
+ wp_clear_scheduled_hook( 'learn_press_cleanup_sessions' );
199
+ wp_schedule_event( time(), apply_filters( 'learn_press_cleanup_session_recurrence', 'twicedaily' ), 'learn_press_cleanup_sessions' );
200
+ }
201
+
202
+ public static function _auto_update() {
203
+ self::get_update_versions();
204
+ self::update();
205
+ }
206
+
207
+ public static function _search_page( $type, $types ) {
208
+ static $pages = array();
209
+ if ( empty( $pages[$type] ) ) {
210
+ global $wpdb;
211
+ $in_types = array_fill( 0, sizeof( $types ), '%s' );
212
+ $args = array( '_learn_press_page' );
213
+ $args = array_merge( $args, $types );
214
+ $args[] = 'publish';
215
+ $query = $wpdb->prepare( "
216
+ SELECT ID, pm.meta_value as type
217
+ FROM {$wpdb->posts} p
218
+ INNER JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID AND pm.meta_key = %s AND pm.meta_value IN(" . join( ',', $in_types ) . ")
219
+ WHERE p.post_status = %s
220
+ ", $args );
221
+ if ( $rows = $wpdb->get_results( $query ) ) {
222
+ foreach ( $rows as $row ) {
223
+ $pages[$row->type] = $row->ID;
224
+ }
225
+ }
226
+ }
227
+
228
+ $page_id = !empty( $pages[$type] ) ? $pages[$type] : 0;
229
+
230
+ return $page_id;
231
+ }
232
+
233
+ /**
234
+ * Remove learnpress page if total of learn page > 10
235
+ * @global type $wpdb
236
+ * @return type
237
+ */
238
+ public static function _remove_pages() {
239
+ global $wpdb;
240
+ $sql = 'SELECT * '
241
+ . ' FROM ' . $wpdb->posts . ' p INNER JOIN ' . $wpdb->postmeta . ' pm '
242
+ . ' ON p.ID=pm.post_id AND pm.meta_key="_learn_press_page" AND p.post_type="page";';
243
+ $ids = $wpdb->get_col( $sql );
244
+ $count_ids = count( $ids );
245
+ if ( $count_ids < 10 ) {
246
+ return $ids;
247
+ }
248
+ $q = $wpdb->prepare( "
249
+ DELETE FROM p, pm
250
+ USING {$wpdb->posts} AS p LEFT JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id AND p.post_type IN('page')
251
+ WHERE %d AND p.post_status='publish' AND p.ID IN(" . implode( ',', $ids ) . ")
252
+ ", 1 );
253
+
254
+ $wpdb->query( $q );
255
+
256
+ $pages = self::$_pages;
257
+ foreach ( $pages as $page ) {
258
+ delete_option( "learn_press_{$page}_page_id" );
259
+ }
260
+ sleep( 5 );
261
+ return array();
262
+
263
+ }
264
+
265
+ public static function create_pages() {
266
+ global $wpdb;
267
+ $created_page = self::_remove_pages();
268
+
269
+ if ( !empty( $created_page ) ) {
270
+ return;
271
+ }
272
+
273
+ $pages = self::$_pages;
274
+ foreach ( $pages as $page ) {
275
+ $page_id = get_option( "learn_press_{$page}_page_id" );
276
+ if ( $page_id && get_post_type( $page_id ) == 'page' && get_post_status( $page_id ) == 'publish' ) {
277
+ continue;
278
+ }
279
+ $page_id = self::_search_page( $page, $pages );
280
+ if ( !$page_id ) {
281
+ // Check if page has already existed
282
+ switch ( $page ) {
283
+ case 'courses':
284
+ $_lpr_settings_pages = (array) get_option( '_lpr_settings_pages' );
285
+
286
+ if ( !empty( $_lpr_settings_pages['general'] ) ) {
287
+ if ( !empty( $_lpr_settings_pages['general']['courses_page_id'] ) ) {
288
+ $page_id = $_lpr_settings_pages['general']['courses_page_id'];
289
+ }
290
+ }
291
+ break;
292
+ case 'profile':
293
+ $_lpr_settings_general = (array) get_option( '_lpr_settings_general' );
294
+ if ( !empty( $_lpr_settings_general['set_page'] ) && $_lpr_settings_general['set_page'] == 'lpr_profile' ) {
295
+ $page_id = $wpdb->get_var(
296
+ $wpdb->prepare( "
297
+ SELECT ID
298
+ FROM $wpdb->posts p
299
+ INNER JOIN $wpdb->postmeta pm ON p.ID = pm.post_id AND pm.meta_key = %s AND pm.meta_value = %d
300
+ ", '_lpr_is_profile_page', 1 )
301
+ );
302
+ }
303
+ break;
304
+ }
305
+
306
+ if ( !$page_id ) {
307
+ $inserted = wp_insert_post(
308
+ array(
309
+ 'post_title' => 'LP ' . ucwords( str_replace( '_', ' ', $page ) ),
310
+ 'post_status' => 'publish',
311
+ 'post_type' => 'page',
312
+ 'comment_status' => 'closed'
313
+ )
314
+ );
315
+ if ( $inserted ) {
316
+ $page_id = $inserted;
317
+ }
318
+ }
319
+ }
320
+ if ( $page_id ) {
321
+ update_option( "learn_press_{$page}_page_id", $page_id );
322
+ update_post_meta( $page_id, '_learn_press_page', $page );
323
+ }
324
+ }
325
+ flush_rewrite_rules();
326
+ }
327
+
328
+ public static function create_files() {
329
+ $upload_dir = wp_upload_dir();
330
+ $files = array(
331
+ array(
332
+ 'base' => LP_LOG_PATH,
333
+ 'file' => '.htaccess',
334
+ 'content' => 'deny from all'
335
+ ),
336
+ array(
337
+ 'base' => LP_LOG_PATH,
338
+ 'file' => 'index.html',
339
+ 'content' => ''
340
+ )
341
+ );
342
+
343
+ foreach ( $files as $file ) {
344
+ if ( wp_mkdir_p( $file['base'] ) && !file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
345
+ if ( $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ) ) {
346
+ fwrite( $file_handle, $file['content'] );
347
+ fclose( $file_handle );
348
+ }
349
+ }
350
+ }
351
+ }
352
+
353
+ private function _is_old_version() {
354
+ if ( is_null( self::$_is_old_version ) ) {
355
+ $is_old_version = get_transient( 'learn_press_is_old_version' );
356
+
357
+ if ( empty( $is_old_version ) ) {
358
+ if ( !get_option( 'learnpress_db_version' ) ||
359
+ get_posts(
360
+ array(
361
+ 'post_type' => 'lpr_course',
362
+ 'post_status' => 'any',
363
+ 'posts_per_page' => 1
364
+ )
365
+ )
366
+ ) {
367
+ $is_old_version = 'yes';
368
+ }
369
+ if ( empty( $is_old_version ) ) {
370
+ $is_old_version = 'no';
371
+ }
372
+ set_transient( 'learn_press_is_old_version', $is_old_version );
373
+ }
374
+ self::$_is_old_version = $is_old_version == 'yes';
375
+ }
376
+ return self::$_is_old_version;
377
+ }
378
+
379
+ /**
380
+ * Find if there is any old course and did not upgrade
381
+ * If a course has got a meta key like _learn_press_upgraded that means it is not upgraded
382
+ *
383
+ * @return mixed
384
+ */
385
+ private static function _has_old_posts() {
386
+ global $wpdb;
387
+ $query = $wpdb->prepare( "
388
+ SELECT DISTINCT p.ID, pm.meta_value as upgraded
389
+ FROM {$wpdb->posts} p
390
+ LEFT JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID AND pm.meta_key = %s
391
+ WHERE post_type = %s
392
+ HAVING upgraded IS NULL
393
+ LIMIT 0, 1
394
+ ", '_learn_press_upgraded', 'lpr_course' );
395
+ return $wpdb->get_row( $query );
396
+ }
397
+
398
+ private static function _has_new_table() {
399
+ global $wpdb;
400
+ $query = $wpdb->prepare( "
401
+ SELECT COUNT(*)
402
+ FROM information_schema.tables
403
+ WHERE table_schema = %s
404
+ AND table_name LIKE %s
405
+ ", DB_NAME, '%learnpress_sections%' );
406
+ return $wpdb->get_var( $query ) ? true : false;
407
+ }
408
+
409
+ private static function _need_to_update() {
410
+ return self::_has_old_posts() || self::_has_old_teacher_role();
411
+ }
412
+
413
+ private static function _has_old_teacher_role() {
414
+ global $wpdb;
415
+ $query = $wpdb->prepare( "
416
+ SELECT um.*
417
+ FROM {$wpdb->users} u
418
+ INNER JOIN {$wpdb->usermeta} um ON um.user_id = u.ID AND um.meta_key = %s
419
+ WHERE um.meta_value LIKE %s
420
+ LIMIT 0, 1
421
+ ", 'wp_capabilities', '%"lpr_teacher"%' );
422
+ return $wpdb->get_results( $query );
423
+ }
424
+
425
+ private static function _has_new_posts() {
426
+ $new_post = get_posts(
427
+ array(
428
+ 'post_type' => 'lp_course',
429
+ 'post_status' => 'any',
430
+ 'posts_per_page' => 1
431
+ )
432
+ );
433
+ return sizeof( $new_post ) > 0;
434
+ }
435
+
436
+ public static function update() {
437
+ $learnpress_db_version = get_option( 'learnpress_db_version' );
438
+
439
+ foreach ( self::$_update_files as $version => $updater ) {
440
+ if ( version_compare( $learnpress_db_version, $version, '<' ) ) {
441
+ @include( LP_PLUGIN_PATH . '/inc/updates/' . $updater );
442
+ self::update_db_version( $version );
443
+ }
444
+ }
445
+
446
+ self::update_db_version();
447
+ self::update_version();
448
+ }
449
+
450
+ public static function update_db_version( $version = null ) {
451
+ delete_option( 'learnpress_db_version' );
452
+ update_option( 'learnpress_db_version', is_null( $version ) ? LEARNPRESS_VERSION : $version );
453
+ }
454
+
455
+ public static function update_version( $version = null ) {
456
+
457
+ delete_option( 'learnpress_version' );
458
+ update_option( 'learnpress_version', is_null( $version ) ? LEARNPRESS_VERSION : $version );
459
+ }
460
+
461
+ private static function _create_options() {
462
+ include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-base.php';
463
+ $settings_classes = array(
464
+ 'LP_Settings_General' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-general.php',
465
+ 'LP_Settings_Courses' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-courses.php',
466
+ 'LP_Settings_Pages' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-pages.php',
467
+ 'LP_Settings_Checkout' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-checkout.php',
468
+ 'LP_Settings_Profile' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-profile.php',
469
+ 'LP_Settings_Emails' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-emails.php'
470
+ );
471
+ foreach ( $settings_classes as $c => $class ) {
472
+ if ( !is_object( $class ) ) {
473
+ $class = @new $c();
474
+ }
475
+ if ( is_callable( array( $class, 'get_settings' ) ) ) {
476
+ $options = $class->get_settings();
477
+ foreach ( $options as $option ) {
478
+ if ( isset( $option['default'] ) && isset( $option['id'] ) ) {
479
+ $autoload = isset( $option['autoload'] ) ? (bool) $option['autoload'] : true;
480
+ $value = get_option( $option['id'], $option['default'] );
481
+ update_option( $option['id'], $value, '', ( $autoload ? 'yes' : 'no' ) );
482
+ }
483
+ }
484
+ }
485
+ }
486
+ $custom_options = array(
487
+ 'learn_press_course_base_type' => 'custom',
488
+ 'learn_press_paypal_email' => get_option( 'admin_email' ),
489
+ 'learn_press_paypal_enable' => 'yes',
490
+ 'learn_press_profile_endpoints' => 'a:4:{s:15:"profile-courses";s:7:"courses";s:15:"profile-quizzes";s:7:"quizzes";s:14:"profile-orders";s:6:"orders";s:21:"profile-order-details";s:13:"order-details";}',
491
+ 'learn_press_checkout_endpoints' => 'a:1:{s:17:"lp_order_received";s:17:"lp-order-received";}'
492
+ );
493
+ foreach ( $custom_options as $option_name => $option_value ) {
494
+ if ( !get_option( $option_name ) ) {
495
+ update_option( $option_name, maybe_unserialize( $option_value ), 'yes' );
496
+ }
497
+ }
498
+ set_transient( 'learn_press_install', 'yes', 24 * 3600 );
499
+ }
500
+
501
+ private static function _create_tables() {
502
+ global $wpdb;
503
+
504
+ $wpdb->hide_errors();
505
+
506
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
507
+ $schema = self::_get_schema();
508
+ if ( $schema ) {
509
+ dbDelta( $schema );
510
+ }
511
+ LP_Debug::instance()->add( 'create_table' );
512
+ }
513
+
514
+ private static function _get_schema() {
515
+ global $wpdb;
516
+
517
+ $collate = '';
518
+
519
+ if ( $wpdb->has_cap( 'collation' ) ) {
520
+ if ( !empty( $wpdb->charset ) ) {
521
+ $collate .= "DEFAULT CHARACTER SET $wpdb->charset";
522
+ }
523
+ if ( !empty( $wpdb->collate ) ) {
524
+ $collate .= " COLLATE $wpdb->collate";
525
+ }
526
+ }
527
+
528
+ $table = $wpdb->prefix . 'learnpress_order_itemmeta';
529
+ $query = '';
530
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
531
+ $query .= "
532
+ CREATE TABLE {$wpdb->prefix}learnpress_order_itemmeta (
533
+ meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
534
+ learnpress_order_item_id bigint(20) unsigned NOT NULL DEFAULT '0',
535
+ meta_key varchar(45) NOT NULL DEFAULT '',
536
+ meta_value longtext NOT NULL,
537
+ PRIMARY KEY (meta_id)
538
+ ) $collate;";
539
+ }
540
+ $table = $wpdb->prefix . 'learnpress_order_items';
541
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
542
+ $query .= "
543
+ CREATE TABLE {$wpdb->prefix}learnpress_order_items (
544
+ order_item_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
545
+ order_item_name longtext NOT NULL,
546
+ order_id bigint(20) unsigned NOT NULL DEFAULT '0',
547
+ PRIMARY KEY (order_item_id)
548
+ ) $collate;";
549
+ }
550
+ $table = $wpdb->prefix . 'learnpress_question_answers';
551
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
552
+ $query .= "
553
+ CREATE TABLE {$wpdb->prefix}learnpress_question_answers (
554
+ question_answer_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
555
+ question_id bigint(20) unsigned NOT NULL DEFAULT '0',
556
+ answer_data text NOT NULL,
557
+ answer_order bigint(20) unsigned NOT NULL DEFAULT '0',
558
+ PRIMARY KEY (question_answer_id)
559
+ ) $collate;";
560
+ }
561
+ $table = $wpdb->prefix . 'learnpress_quiz_questions';
562
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
563
+ $query .= "
564
+ CREATE TABLE {$wpdb->prefix}learnpress_quiz_questions (
565
+ quiz_question_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
566
+ quiz_id bigint(20) unsigned NOT NULL DEFAULT '0',
567
+ question_id bigint(20) unsigned NOT NULL DEFAULT '0',
568
+ question_order bigint(20) unsigned NOT NULL DEFAULT '1',
569
+ params longtext NULL,
570
+ PRIMARY KEY (quiz_question_id)
571
+ ) $collate;";
572
+ }
573
+ $table = $wpdb->prefix . 'learnpress_review_logs';
574
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
575
+ $query .= "
576
+ CREATE TABLE {$wpdb->prefix}learnpress_review_logs (
577
+ review_log_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
578
+ course_id bigint(20) unsigned NOT NULL DEFAULT '0',
579
+ user_id bigint(20) unsigned NOT NULL DEFAULT '0',
580
+ message text NOT NULL,
581
+ date datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
582
+ status varchar(45) NOT NULL DEFAULT '',
583
+ user_type varchar(45) NOT NULL DEFAULT '',
584
+ PRIMARY KEY (review_log_id)
585
+ ) $collate;";
586
+ }
587
+ $table = $wpdb->prefix . 'learnpress_section_items';
588
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
589
+ $query .= "
590
+ CREATE TABLE {$wpdb->prefix}learnpress_section_items (
591
+ section_item_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
592
+ section_id bigint(20) unsigned NOT NULL DEFAULT '0',
593
+ item_id bigint(20) unsigned NOT NULL DEFAULT '0',
594
+ item_order bigint(20) unsigned NOT NULL DEFAULT '0',
595
+ item_type varchar(45),
596
+ PRIMARY KEY (section_item_id)
597
+ ) $collate;";
598
+ }
599
+ $table = $wpdb->prefix . 'learnpress_sections';
600
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
601
+ $query .= "
602
+ CREATE TABLE {$wpdb->prefix}learnpress_sections (
603
+ section_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
604
+ section_name varchar(255) NOT NULL DEFAULT '',
605
+ section_course_id bigint(20) unsigned NOT NULL DEFAULT '0',
606
+ section_order bigint(5) unsigned NOT NULL DEFAULT '0',
607
+ section_description longtext NOT NULL,
608
+ PRIMARY KEY (section_id)
609
+ ) $collate;";
610
+ }
611
+ $table = $wpdb->prefix . 'learnpress_sessions';
612
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
613
+ $query .= "
614
+ CREATE TABLE {$wpdb->prefix}learnpress_sessions (
615
+ session_id bigint(20) NOT NULL AUTO_INCREMENT,
616
+ session_key char(32) NOT NULL,
617
+ session_value longtext NOT NULL,
618
+ session_expiry bigint(20) NOT NULL,
619
+ UNIQUE KEY session_id (session_id),
620
+ PRIMARY KEY (session_key)
621
+ ) $collate;";
622
+ }
623
+ $table = $wpdb->prefix . 'learnpress_user_items';
624
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
625
+ $query .= "
626
+ CREATE TABLE {$wpdb->prefix}learnpress_user_items (
627
+ user_item_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
628
+ user_id bigint(20) unsigned NOT NULL DEFAULT '0',
629
+ item_id bigint(20) unsigned NOT NULL DEFAULT '0',
630
+ start_time datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
631
+ end_time datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
632
+ item_type varchar(45) NOT NULL DEFAULT '',
633
+ status varchar(45) NOT NULL DEFAULT '',
634
+ ref_id bigint(20) unsigned NOT NULL DEFAULT '0',
635
+ ref_type varchar(45) DEFAULT '',
636
+ parent_id bigint(20) unsigned NOT NULL DEFAULT '0',
637
+ PRIMARY KEY (user_item_id)
638
+ ) $collate;";
639
+ }
640
+ $table = $wpdb->prefix . 'learnpress_user_itemmeta';
641
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
642
+ $query .= "
643
+ CREATE TABLE {$wpdb->prefix}learnpress_user_itemmeta (
644
+ meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
645
+ learnpress_user_item_id bigint(20) unsigned NOT NULL,
646
+ meta_key varchar(45) NOT NULL DEFAULT '',
647
+ meta_value text NOT NULL,
648
+ PRIMARY KEY (meta_id)
649
+ ) $collate;
650
+ ";
651
+ }
652
+ return $query;
653
+ }
654
+ }
655
+
656
+ LP_Install::init();
 
inc/class-lp-page-controller.php CHANGED
@@ -1,387 +1,429 @@
1
- <?php
2
-
3
- /**
4
- * Class LP_Page_Controller
5
- */
6
- class LP_Page_Controller {
7
-
8
- /**
9
- * @var null
10
- */
11
- protected $queried_object = null;
12
-
13
- /**
14
- * @var null
15
- */
16
- protected static $_instance = null;
17
-
18
- /**
19
- * @var bool
20
- */
21
- protected $has_filter_content = false;
22
-
23
- protected $_filter_content_priority = 10000;
24
-
25
- protected $_origin_post = null;
26
-
27
- /**
28
- * LP_Page_Controller constructor.
29
- */
30
- public function __construct() {
31
- // Prevent duplicated actions
32
- if ( self::$_instance || is_admin() ) {
33
- return;
34
- }
35
- add_filter( 'template_include', array( $this, 'template_loader' ) );
36
- add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10 );
37
- //add_action( 'learn_press_before_template_part', array( $this, 'before_template_part' ), 10, 4 );
38
- add_shortcode( 'learn_press_archive_course', array( $this, 'archive_content' ) );
39
- }
40
-
41
- public function fix_global_post( $post, $query ) {
42
- global $post;
43
- //$post = $this->_origin_post;
44
-
45
-
46
- }
47
-
48
- /*public function before_template_part( $template_name, $template_path, $located, $args ) {
49
- if ( $this->has_filter_content && !in_array( $template_name, array( 'content-single-course.php' ) ) ) {
50
- remove_filter( 'the_content', array( $this, 'single_content' ), $this->_filter_content_priority );
51
- $this->has_filter_content = false;
52
- LP_Debug::instance()->add( 'remove filter content' );
53
- }
54
- }*/
55
-
56
- public function template_loader( $template ) {
57
- global $wp_query, $post;
58
- $file = '';
59
- $find = array();
60
- $theme_template = learn_press_template_path();
61
-
62
- /**
63
- * If is archive course page and a static page is used for displaying courses
64
- * we need to redirect it to the right page
65
- */
66
- if ( is_post_type_archive( 'lp_course' ) ) {
67
- if ( ( $page_id = learn_press_get_page_id( 'courses' ) ) && ( empty( $wp_query->queried_object_id ) || !empty( $wp_query->queried_object_id ) && $page_id != $wp_query->queried_object_id ) ) {
68
- $redirect = trailingslashit( learn_press_get_page_link( 'courses' ) );
69
- // Prevent loop redirect
70
- if ( $page_id != get_option( 'page_on_front' ) && !learn_press_is_current_url( $redirect ) ) {
71
- wp_redirect( $redirect );
72
- exit();
73
- }
74
- }
75
- }
76
-
77
- $queried_object_id = !empty( $wp_query->queried_object_id ) ? $wp_query->queried_object_id : 0;
78
- if ( ( $page_id = learn_press_get_page_id( 'taken_course_confirm' ) ) && is_page( $page_id ) && $page_id == $queried_object_id ) {
79
- if ( !learn_press_user_can_view_order( !empty( $_REQUEST['order_id'] ) ? $_REQUEST['order_id'] : 0 ) ) {
80
- learn_press_404_page();
81
- }
82
- $post->post_content = '[learn_press_confirm_order]';
83
- } elseif ( ( $page_id = learn_press_get_page_id( 'become_a_teacher' ) ) && is_page( $page_id ) && $page_id == $queried_object_id ) {
84
- $post->post_content = '[learn_press_become_teacher_form]';
85
- } else {
86
- if ( learn_press_is_courses() || learn_press_is_course_tag() || learn_press_is_course_category() || learn_press_is_search() ) {
87
- $file = 'archive-course.php';
88
- $find[] = $file;
89
- $find[] = "{$theme_template}/{$file}";
90
- } else {
91
- if ( learn_press_is_course() ) {
92
- $file = 'single-course.php';
93
- $find[] = $file;
94
- $find[] = "{$theme_template}/{$file}";
95
- }
96
- }
97
- }
98
- if ( $file ) {
99
- $template = locate_template( array_unique( $find ) );
100
- if ( !$template && !in_array( $file, array( 'single-course.php', 'archive-course.php' ) ) ) {
101
- $template = learn_press_plugin_path( 'templates/' ) . $file;
102
- }
103
- }
104
- if ( !$template ) {
105
- $template = get_page_template();
106
- if ( learn_press_is_course() ) {
107
- if ( is_single() ) {
108
- global $post;
109
- setup_postdata( $post );
110
- $this->_origin_post = $post;
111
- add_filter( 'the_content', array( $this, 'single_content' ), $this->_filter_content_priority );
112
- $this->has_filter_content = true;
113
- }
114
- } elseif ( learn_press_is_courses() || learn_press_is_course_tag() || learn_press_is_course_category() || learn_press_is_search() ) {
115
- add_action( 'the_post', array( $this, 'fix_global_post' ), 99, 2 );
116
- $this->template_loader2( $template );
117
- }
118
- }
119
- return $template;
120
- }
121
-
122
- public function archive_content() {
123
- ob_start();
124
- learn_press_get_template( 'content-archive-course.php' );
125
- return ob_get_clean();
126
- }
127
-
128
- public function template_loader2( $template ) {
129
- define( 'LEARNPRESS_IS_COURSES', learn_press_is_courses() );
130
- define( 'LEARNPRESS_IS_TAG', learn_press_is_course_tag() );
131
- define( 'LEARNPRESS_IS_CATEGORY', learn_press_is_course_category() );
132
- define( 'LEARNPRESS_IS_TAX', is_tax( get_object_taxonomies( 'lp_course' ) ) );
133
- define( 'LEARNPRESS_IS_SEARCH', learn_press_is_search() );
134
- if ( LEARNPRESS_IS_COURSES || LEARNPRESS_IS_TAG || LEARNPRESS_IS_CATEGORY || LEARNPRESS_IS_SEARCH || LEARNPRESS_IS_TAX ) {
135
-
136
- global $wp_query, $post;
137
- LP()->wp_query = clone( $wp_query );
138
- $template = get_page_template();
139
-
140
- $wp_query->posts_per_page = 1;
141
- $wp_query->nopaging = true;
142
- $wp_query->post_count = 1;
143
- // If we don't have a post, load an empty one
144
- if ( !empty( $this->queried_object ) ) {
145
- $wp_query->post = $this->queried_object;
146
- } elseif ( empty( $wp_query->post ) ) {
147
- $wp_query->post = new WP_Post( new stdClass() );
148
- } elseif ( $wp_query->post->post_type != 'page' ) {
149
- // Do not show content of post if it is not a page
150
- $wp_query->post->post_content = '';
151
- }
152
- $content = $wp_query->post->post_content;
153
-
154
- if ( !preg_match( '/\[learn_press_archive_course\s?(.*)\]/', $content ) ) {
155
- $content = $content . '[learn_press_archive_course]';//$this->archive_content();
156
- }
157
-
158
- $has_filter = false;
159
- if ( has_filter( 'the_content', 'wpautop' ) ) {
160
- $has_filter = true;
161
- remove_filter( 'the_content', 'wpautop' );
162
- }
163
- $content = do_shortcode( $content );
164
- if ( $has_filter ) {
165
- has_filter( 'the_content', 'wpautop' );
166
- }
167
- //if ( empty( $wp_query->post->ID ) ) {
168
- $wp_query->post->ID = 0;
169
- //}
170
- $wp_query->post->filter = 'raw';
171
- if ( learn_press_is_course_category() ) {
172
- $wp_query->post->post_title = single_term_title( '', false );//__( 'Course Category', 'learnpress' );
173
- }
174
-
175
- $wp_query->post->post_content = $content;
176
- $wp_query->posts = array( $wp_query->post );
177
- $wp_query->found_posts = 1;
178
- $wp_query->is_single = false;
179
- $wp_query->is_preview = false;
180
- $wp_query->is_page = false;
181
- $wp_query->is_archive = false;
182
- $wp_query->is_date = false;
183
- $wp_query->is_year = false;
184
- $wp_query->is_month = false;
185
- $wp_query->is_day = false;
186
- $wp_query->is_time = false;
187
- $wp_query->is_author = false;
188
- $wp_query->is_category = false;
189
- $wp_query->is_tag = false;
190
- $wp_query->is_tax = false;
191
- $wp_query->is_search = false;
192
- $wp_query->is_feed = false;
193
- $wp_query->is_comment_feed = false;
194
- $wp_query->is_trackback = false;
195
- $wp_query->is_home = false;
196
- $wp_query->is_404 = false;
197
- $wp_query->is_comments_popup = false;
198
- $wp_query->is_paged = false;
199
- $wp_query->is_admin = false;
200
- $wp_query->is_attachment = false;
201
- $wp_query->is_singular = false;
202
- $wp_query->is_posts_page = false;
203
- $wp_query->is_post_type_archive = false;
204
- }
205
- return $template;
206
- }
207
-
208
- /**
209
- * @param $content
210
- *
211
- * @return string
212
- */
213
- public function single_content( $content ) {
214
- // Should not effect if current post is not a LP Course
215
- if ( LP_COURSE_CPT != get_post_type() ) {
216
- return $content;
217
- }
218
- remove_filter( 'the_content', array( $this, 'single_content' ), $this->_filter_content_priority );
219
- add_filter( 'the_content', 'wpautop' );
220
- ob_start();
221
- learn_press_get_template( 'content-single-course.php' );
222
- $content = ob_get_clean();
223
- remove_filter( 'the_content', 'wpautop' );
224
- add_filter( 'the_content', array( $this, 'single_content' ), $this->_filter_content_priority );
225
- return $content;
226
- }
227
-
228
- /**
229
- * Controls WP displays the courses in a page which setup to display on homepage
230
- *
231
- * @param $q WP_Query
232
- *
233
- * @return WP_Query
234
- */
235
- public function pre_get_posts( $q ) {
236
-
237
- global $course;
238
-
239
- LP_Debug::instance()->add( $q, 'wp_query' );
240
-
241
- // We only want to affect the main query and not in admin
242
- if ( !$q->is_main_query() || is_admin() ) {
243
- return $q;
244
- }
245
- remove_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10 );
246
-
247
- $this->queried_object = !empty( $q->queried_object_id ) ? $q->queried_object : false;
248
-
249
- /**
250
- * If is single course content
251
- */
252
- if ( $q->get( 'post_type' ) == 'lp_course' && is_single() ) {
253
- global $post;
254
-
255
- /**
256
- * Added in LP 2.0.5 to fix issue in some cases course become 404
257
- * including case course link is valid but it also get 404 if
258
- * plugin WPML is installed
259
- */
260
- if ( !empty( $q->query_vars['p'] ) && LP_COURSE_CPT == get_post_type( $q->query_vars['p'] ) ) {
261
- $post = get_post( $q->query_vars['p'] );
262
- } else {
263
- $course_name = $q->get( 'lp_course' );
264
- $post = learn_press_get_post_by_name( $course_name, 'lp_course', true );
265
- }
266
-
267
- if ( !$post ) {
268
- LP_Debug::instance()->add( sprintf( '%s: File %s, line #%d', '404', __FILE__, __LINE__ ) );
269
- learn_press_404_page();
270
- }
271
- $course = learn_press_get_course( $post->ID );
272
- $item = null;
273
- $item_name = null;
274
- $item_object = null;
275
-
276
- if ( $course ) {
277
- LP()->global['course'] = $course;
278
- if ( $item_name = $q->get( 'lesson' ) ) {
279
- $item = learn_press_get_post_by_name( $item_name, 'lp_lesson', true );
280
- if ( $item ) {
281
- $item_object = LP_Lesson::get_lesson( $item->ID );
282
- }
283
- } elseif ( $item_name = $q->get( 'quiz' ) ) {
284
- $item = learn_press_get_post_by_name( $item_name, 'lp_quiz', true );
285
- if ( $item ) {
286
- $quiz = LP_Quiz::get_quiz( $item->ID );
287
- if ( $question_name = $q->get( 'question' ) ) {
288
- $question = learn_press_get_post_by_name( $question_name, 'lp_question', true );
289
- if ( !$question ) {
290
- LP_Debug::instance()->add( sprintf( '%s: File %s, line #%d', '404', __FILE__, __LINE__ ) );
291
- learn_press_404_page();
292
- } elseif ( !$quiz->has_question( $question->ID ) ) {
293
- LP_Debug::instance()->add( sprintf( '%s: File %s, line #%d', '404', __FILE__, __LINE__ ) );
294
- learn_press_404_page();
295
- } else {
296
- LP()->global['quiz-question'] = $question;
297
- }
298
- }
299
- $item_object = LP_Quiz::get_quiz( $item->ID );
300
- }
301
- }
302
- }
303
-
304
- if ( $item_name && !$item_object ) {
305
- LP_Debug::instance()->add( sprintf( '%s: File %s, line #%d', '404', __FILE__, __LINE__ ) );
306
- learn_press_404_page();
307
- } elseif ( $item_object && !$course->has( 'item', $item_object->id ) ) {
308
- LP_Debug::instance()->add( sprintf( '%s: File %s, line #%d', '404', __FILE__, __LINE__ ) );
309
- learn_press_404_page();
310
- } else {
311
- LP()->global['course-item'] = $item_object;
312
- }
313
- }
314
-
315
-
316
- /**
317
- * If current page is used for courses page
318
- */
319
- if ( $q->is_main_query() && $q->is_page() && ( $q->queried_object_id == ( $page_id = learn_press_get_page_id( 'courses' ) ) && $page_id ) ) {
320
- $q->set( 'post_type', 'lp_course' );
321
- $q->set( 'page', '' );
322
- $q->set( 'pagename', '' );
323
-
324
- $q->is_archive = true;
325
- $q->is_post_type_archive = true;
326
- $q->is_singular = false;
327
- $q->is_page = false;
328
- }
329
-
330
-
331
- if ( $q->is_home() && 'page' == get_option( 'show_on_front' ) && get_option( 'page_on_front' ) == learn_press_get_page_id( 'courses' ) ) {
332
- $_query = wp_parse_args( $q->query );
333
- if ( empty( $_query ) || !array_diff( array_keys( $_query ), array( 'preview', 'page', 'paged', 'cpage', 'orderby' ) ) ) {
334
- $q->is_page = true;
335
- $q->is_home = false;
336
- $q->set( 'page_id', get_option( 'page_on_front' ) );
337
- $q->set( 'post_type', 'lp_course' );
338
- }
339
-
340
- }
341
-
342
- /**
343
- * If current page is used for courses page and set as home-page
344
- */
345
- if ( $q->is_page() && 'page' == get_option( 'show_on_front' ) && $q->get( 'page_id' ) == learn_press_get_page_id( 'courses' ) && learn_press_get_page_id( 'courses' ) ) {
346
-
347
- $q->set( 'post_type', 'lp_course' );
348
- $q->set( 'page_id', '' );
349
- if ( isset( $q->query['paged'] ) ) {
350
- $q->set( 'paged', $q->query['paged'] );
351
- }
352
-
353
- global $wp_post_types;
354
-
355
- $course_page = get_post( learn_press_get_page_id( 'courses' ) );
356
- $this->queried_object = $course_page;
357
- $wp_post_types['lp_course']->ID = $course_page->ID;
358
- $wp_post_types['lp_course']->post_title = $course_page->post_title;
359
- $wp_post_types['lp_course']->post_name = $course_page->post_name;
360
- $wp_post_types['lp_course']->post_type = $course_page->post_type;
361
- $wp_post_types['lp_course']->ancestors = get_ancestors( $course_page->ID, $course_page->post_type );
362
-
363
- $q->is_singular = false;
364
- $q->is_post_type_archive = true;
365
- $q->is_archive = true;
366
- $q->is_page = true;
367
-
368
- }
369
-
370
- if ( ( learn_press_is_courses() || learn_press_is_course_category() ) && $limit = absint( LP()->settings->get( 'archive_course_limit' ) ) ) {
371
- $q->set( 'posts_per_page', $limit );
372
- }
373
-
374
- add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10 );
375
-
376
- return $q;
377
- }
378
-
379
- public static function instance() {
380
- if ( !self::$_instance ) {
381
- self::$_instance = new self();
382
- }
383
- return self::$_instance;
384
- }
385
- }
386
-
387
- LP_Page_Controller::instance();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Page_Controller
5
+ */
6
+ class LP_Page_Controller {
7
+
8
+ /**
9
+ * @var null
10
+ */
11
+ protected $queried_object = null;
12
+
13
+ /**
14
+ * @var null
15
+ */
16
+ protected static $_instance = null;
17
+
18
+ /**
19
+ * @var bool
20
+ */
21
+ protected $has_filter_content = false;
22
+
23
+ protected $_filter_content_priority = 10000;
24
+
25
+ protected $_origin_post = null;
26
+
27
+ /**
28
+ * LP_Page_Controller constructor.
29
+ */
30
+ public function __construct() {
31
+ // Prevent duplicated actions
32
+ if ( self::$_instance || is_admin() ) {
33
+ return;
34
+ }
35
+ add_filter( 'template_include', array( $this, 'template_loader' ) );
36
+ add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10 );
37
+ //add_action( 'learn_press_before_template_part', array( $this, 'before_template_part' ), 10, 4 );
38
+ add_shortcode( 'learn_press_archive_course', array( $this, 'archive_content' ) );
39
+ add_filter( 'request', array( $this, 'remove_course_post_format' ), 1 );
40
+ }
41
+
42
+ /**
43
+ * In preview mode, if there is a 'post_format' in query var
44
+ * wp check and replace our post-type to post. This make preview
45
+ * course item become 404
46
+ *
47
+ * @param $qv
48
+ *
49
+ * @return mixed
50
+ */
51
+ public function remove_course_post_format( $qv ) {
52
+ if ( !empty( $qv['post_type'] ) && LP_COURSE_CPT === $qv['post_type'] ) {
53
+ if ( !empty( $qv['post_format'] ) ) {
54
+ unset( $qv['post_format'] );
55
+ }
56
+ }
57
+ return $qv;
58
+ }
59
+
60
+ public function fix_global_post( $post, $query ) {
61
+ global $post;
62
+ //$post = $this->_origin_post;
63
+
64
+
65
+ }
66
+
67
+ /*public function before_template_part( $template_name, $template_path, $located, $args ) {
68
+ if ( $this->has_filter_content && !in_array( $template_name, array( 'content-single-course.php' ) ) ) {
69
+ remove_filter( 'the_content', array( $this, 'single_content' ), $this->_filter_content_priority );
70
+ $this->has_filter_content = false;
71
+ LP_Debug::instance()->add( 'remove filter content' );
72
+ }
73
+ }*/
74
+
75
+ public function template_loader( $template ) {
76
+ global $wp_query, $post;
77
+ $file = '';
78
+ $find = array();
79
+ $theme_template = learn_press_template_path();
80
+
81
+ /**
82
+ * If is archive course page and a static page is used for displaying courses
83
+ * we need to redirect it to the right page
84
+ */
85
+ if ( is_post_type_archive( 'lp_course' ) ) {
86
+ if ( ( $page_id = learn_press_get_page_id( 'courses' ) ) && ( empty( $wp_query->queried_object_id ) || !empty( $wp_query->queried_object_id ) && $page_id != $wp_query->queried_object_id ) ) {
87
+ $redirect = trailingslashit( learn_press_get_page_link( 'courses' ) );
88
+ // Prevent loop redirect
89
+ if ( $page_id != get_option( 'page_on_front' ) && !learn_press_is_current_url( $redirect ) ) {
90
+ wp_redirect( $redirect );
91
+ exit();
92
+ }
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Check if user is viewing a course's item but they do not have
98
+ * permission to view it
99
+ */
100
+ if ( learn_press_is_course() ) {
101
+ if ( !empty( LP()->global['course-item'] ) && $course_item = LP()->global['course-item'] ) {
102
+ $user = learn_press_get_current_user();
103
+ if ( !$user->can_view_item( $course_item->id ) ) {
104
+ wp_redirect( get_the_permalink() );
105
+ exit();
106
+ }
107
+ }
108
+ }
109
+
110
+ if ( learn_press_is_profile() ) {
111
+ $current_tab = learn_press_get_current_profile_tab( false );
112
+ if ( $current_tab && !learn_press_profile_tab_exists( $current_tab ) ) {
113
+ wp_redirect( learn_press_get_page_link( 'profile' ) );
114
+ exit();
115
+ }
116
+ }
117
+ $queried_object_id = !empty( $wp_query->queried_object_id ) ? $wp_query->queried_object_id : 0;
118
+ if ( ( $page_id = learn_press_get_page_id( 'taken_course_confirm' ) ) && is_page( $page_id ) && $page_id == $queried_object_id ) {
119
+ if ( !learn_press_user_can_view_order( !empty( $_REQUEST['order_id'] ) ? $_REQUEST['order_id'] : 0 ) ) {
120
+ learn_press_is_404();
121
+ }
122
+ $post->post_content = '[learn_press_confirm_order]';
123
+ } elseif ( ( $page_id = learn_press_get_page_id( 'become_a_teacher' ) ) && is_page( $page_id ) && $page_id == $queried_object_id ) {
124
+ $post->post_content = '[learn_press_become_teacher_form]';
125
+ } else {
126
+ if ( learn_press_is_courses() || learn_press_is_course_tag() || learn_press_is_course_category() || learn_press_is_search() ) {
127
+ $file = 'archive-course.php';
128
+ $find[] = $file;
129
+ $find[] = "{$theme_template}/{$file}";
130
+ } else {
131
+ if ( learn_press_is_course() ) {
132
+ $file = 'single-course.php';
133
+ $find[] = $file;
134
+ $find[] = "{$theme_template}/{$file}";
135
+ }
136
+ }
137
+ }
138
+ if ( $file ) {
139
+ $template = locate_template( array_unique( $find ) );
140
+ if ( !$template && !in_array( $file, array( 'single-course.php', 'archive-course.php' ) ) ) {
141
+ $template = learn_press_plugin_path( 'templates/' ) . $file;
142
+ }
143
+ }
144
+ if ( !$template ) {
145
+ $template = get_page_template();
146
+ if ( learn_press_is_course() ) {
147
+ if ( is_single() ) {
148
+ global $post;
149
+ setup_postdata( $post );
150
+ $this->_origin_post = $post;
151
+ add_filter( 'the_content', array( $this, 'single_content' ), $this->_filter_content_priority );
152
+ $this->has_filter_content = true;
153
+ }
154
+ } elseif ( learn_press_is_courses() || learn_press_is_course_tag() || learn_press_is_course_category() || learn_press_is_search() ) {
155
+ add_action( 'the_post', array( $this, 'fix_global_post' ), 99, 2 );
156
+ $this->template_loader2( $template );
157
+ }
158
+ }
159
+ return $template;
160
+ }
161
+
162
+ public function archive_content() {
163
+ ob_start();
164
+ learn_press_get_template( 'content-archive-course.php' );
165
+ return ob_get_clean();
166
+ }
167
+
168
+ public function template_loader2( $template ) {
169
+ define( 'LEARNPRESS_IS_COURSES', learn_press_is_courses() );
170
+ define( 'LEARNPRESS_IS_TAG', learn_press_is_course_tag() );
171
+ define( 'LEARNPRESS_IS_CATEGORY', learn_press_is_course_category() );
172
+ define( 'LEARNPRESS_IS_TAX', is_tax( get_object_taxonomies( 'lp_course' ) ) );
173
+ define( 'LEARNPRESS_IS_SEARCH', learn_press_is_search() );
174
+ if ( LEARNPRESS_IS_COURSES || LEARNPRESS_IS_TAG || LEARNPRESS_IS_CATEGORY || LEARNPRESS_IS_SEARCH || LEARNPRESS_IS_TAX ) {
175
+
176
+ global $wp_query, $post;
177
+ LP()->wp_query = clone( $wp_query );
178
+ $template = get_page_template();
179
+
180
+ $wp_query->posts_per_page = 1;
181
+ $wp_query->nopaging = true;
182
+ $wp_query->post_count = 1;
183
+ // If we don't have a post, load an empty one
184
+ if ( !empty( $this->queried_object ) ) {
185
+ $wp_query->post = $this->queried_object;
186
+ } elseif ( empty( $wp_query->post ) ) {
187
+ $wp_query->post = new WP_Post( new stdClass() );
188
+ } elseif ( $wp_query->post->post_type != 'page' ) {
189
+ // Do not show content of post if it is not a page
190
+ $wp_query->post->post_content = '';
191
+ }
192
+ $content = $wp_query->post->post_content;
193
+
194
+ if ( !preg_match( '/\[learn_press_archive_course\s?(.*)\]/', $content ) ) {
195
+ $content = $content . '[learn_press_archive_course]';//$this->archive_content();
196
+ }
197
+
198
+ $has_filter = false;
199
+ if ( has_filter( 'the_content', 'wpautop' ) ) {
200
+ $has_filter = true;
201
+ remove_filter( 'the_content', 'wpautop' );
202
+ }
203
+ $content = do_shortcode( $content );
204
+ if ( $has_filter ) {
205
+ has_filter( 'the_content', 'wpautop' );
206
+ }
207
+ //if ( empty( $wp_query->post->ID ) ) {
208
+ $wp_query->post->ID = 0;
209
+ //}
210
+ $wp_query->post->filter = 'raw';
211
+ if ( learn_press_is_course_category() ) {
212
+ $wp_query->post->post_title = single_term_title( '', false );//__( 'Course Category', 'learnpress' );
213
+ }
214
+
215
+ $wp_query->post->post_content = $content;
216
+ $wp_query->posts = array( $wp_query->post );
217
+ $wp_query->found_posts = 1;
218
+ $wp_query->is_single = false;
219
+ $wp_query->is_preview = false;
220
+ $wp_query->is_page = false;
221
+ $wp_query->is_archive = false;
222
+ $wp_query->is_date = false;
223
+ $wp_query->is_year = false;
224
+ $wp_query->is_month = false;
225
+ $wp_query->is_day = false;
226
+ $wp_query->is_time = false;
227
+ $wp_query->is_author = false;
228
+ $wp_query->is_category = false;
229
+ $wp_query->is_tag = false;
230
+ $wp_query->is_tax = false;
231
+ $wp_query->is_search = false;
232
+ $wp_query->is_feed = false;
233
+ $wp_query->is_comment_feed = false;
234
+ $wp_query->is_trackback = false;
235
+ $wp_query->is_home = false;
236
+ $wp_query->is_404 = false;
237
+ $wp_query->is_comments_popup = false;
238
+ $wp_query->is_paged = false;
239
+ $wp_query->is_admin = false;
240
+ $wp_query->is_attachment = false;
241
+ $wp_query->is_singular = false;
242
+ $wp_query->is_posts_page = false;
243
+ $wp_query->is_post_type_archive = false;
244
+ }
245
+ return $template;
246
+ }
247
+
248
+ /**
249
+ * @param $content
250
+ *
251
+ * @return string
252
+ */
253
+ public function single_content( $content ) {
254
+ // Should not effect if current post is not a LP Course
255
+ if ( LP_COURSE_CPT != get_post_type() ) {
256
+ return $content;
257
+ }
258
+ remove_filter( 'the_content', array( $this, 'single_content' ), $this->_filter_content_priority );
259
+ add_filter( 'the_content', 'wpautop' );
260
+ ob_start();
261
+ learn_press_get_template( 'content-single-course.php' );
262
+ $content = ob_get_clean();
263
+ remove_filter( 'the_content', 'wpautop' );
264
+ add_filter( 'the_content', array( $this, 'single_content' ), $this->_filter_content_priority );
265
+ return $content;
266
+ }
267
+
268
+ /**
269
+ * Controls WP displays the courses in a page which setup to display on homepage
270
+ *
271
+ * @param $q WP_Query
272
+ *
273
+ * @return WP_Query
274
+ */
275
+ public function pre_get_posts( $q ) {
276
+
277
+ global $course;
278
+
279
+ LP_Debug::instance()->add( $q, 'wp_query' );
280
+
281
+ // We only want to affect the main query and not in admin
282
+ if ( !$q->is_main_query() || is_admin() ) {
283
+ return $q;
284
+ }
285
+ remove_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10 );
286
+
287
+ $this->queried_object = !empty( $q->queried_object_id ) ? $q->queried_object : false;
288
+
289
+ /**
290
+ * If is single course content
291
+ */
292
+ if ( $q->get( 'post_type' ) == 'lp_course' && is_single() ) {
293
+ global $post;
294
+
295
+ /**
296
+ * Added in LP 2.0.5 to fix issue in some cases course become 404
297
+ * including case course link is valid but it also get 404 if
298
+ * plugin WPML is installed
299
+ */
300
+ if ( !empty( $q->query_vars['p'] ) && LP_COURSE_CPT == get_post_type( $q->query_vars['p'] ) ) {
301
+ $post = get_post( $q->query_vars['p'] );
302
+ } else {
303
+ $course_name = $q->get( 'lp_course' );
304
+ $post = learn_press_get_post_by_name( $course_name, 'lp_course', true );
305
+ }
306
+
307
+ if ( !$post ) {
308
+ LP_Debug::instance()->add( sprintf( '%s: File %s, line #%d', '404', __FILE__, __LINE__ ) );
309
+ learn_press_is_404();
310
+ return $q;
311
+ }
312
+ $course = learn_press_get_course( $post->ID );
313
+ $item = null;
314
+ $item_name = null;
315
+ $item_object = null;
316
+
317
+ if ( $course ) {
318
+ LP()->global['course'] = $course;
319
+ if ( $item_name = $q->get( 'lesson' ) ) {
320
+ $item = learn_press_get_post_by_name( $item_name, 'lp_lesson', true );
321
+ if ( $item ) {
322
+ $item_object = LP_Lesson::get_lesson( $item->ID );
323
+ }
324
+ } elseif ( $item_name = $q->get( 'quiz' ) ) {
325
+ $item = learn_press_get_post_by_name( $item_name, 'lp_quiz', true );
326
+ if ( $item ) {
327
+ $quiz = LP_Quiz::get_quiz( $item->ID );
328
+ if ( $question_name = $q->get( 'question' ) ) {
329
+ $question = learn_press_get_post_by_name( $question_name, 'lp_question', true );
330
+ if ( !$question ) {
331
+ LP_Debug::instance()->add( sprintf( '%s: File %s, line #%d', '404', __FILE__, __LINE__ ) );
332
+ learn_press_is_404();
333
+ } elseif ( !$quiz->has_question( $question->ID ) ) {
334
+ LP_Debug::instance()->add( sprintf( '%s: File %s, line #%d', '404', __FILE__, __LINE__ ) );
335
+ learn_press_is_404();
336
+ } else {
337
+ LP()->global['quiz-question'] = $question;
338
+ }
339
+ }
340
+ $item_object = LP_Quiz::get_quiz( $item->ID );
341
+ }
342
+ }
343
+ }
344
+
345
+ if ( $item_name && !$item_object ) {
346
+ LP_Debug::instance()->add( sprintf( '%s: File %s, line #%d', '404', __FILE__, __LINE__ ) );
347
+ learn_press_is_404();
348
+ } elseif ( $item_object && !$course->has( 'item', $item_object->id ) ) {
349
+ LP_Debug::instance()->add( sprintf( '%s: File %s, line #%d', '404', __FILE__, __LINE__ ) );
350
+ learn_press_is_404();
351
+ } else {
352
+ LP()->global['course-item'] = $item_object;
353
+ }
354
+ return $q;
355
+ }
356
+
357
+
358
+ /**
359
+ * If current page is used for courses page
360
+ */
361
+ if ( $q->is_main_query() && $q->is_page() && ( $q->queried_object_id == ( $page_id = learn_press_get_page_id( 'courses' ) ) && $page_id ) ) {
362
+ $q->set( 'post_type', 'lp_course' );
363
+ $q->set( 'page', '' );
364
+ $q->set( 'pagename', '' );
365
+
366
+ $q->is_archive = true;
367
+ $q->is_post_type_archive = true;
368
+ $q->is_singular = false;
369
+ $q->is_page = false;
370
+ }
371
+
372
+
373
+ if ( $q->is_home() && 'page' == get_option( 'show_on_front' ) && get_option( 'page_on_front' ) == learn_press_get_page_id( 'courses' ) ) {
374
+ $_query = wp_parse_args( $q->query );
375
+ if ( empty( $_query ) || !array_diff( array_keys( $_query ), array( 'preview', 'page', 'paged', 'cpage', 'orderby' ) ) ) {
376
+ $q->is_page = true;
377
+ $q->is_home = false;
378
+ $q->set( 'page_id', get_option( 'page_on_front' ) );
379
+ $q->set( 'post_type', 'lp_course' );
380
+ }
381
+
382
+ }
383
+
384
+ /**
385
+ * If current page is used for courses page and set as home-page
386
+ */
387
+ if ( $q->is_page() && 'page' == get_option( 'show_on_front' ) && $q->get( 'page_id' ) == learn_press_get_page_id( 'courses' ) && learn_press_get_page_id( 'courses' ) ) {
388
+
389
+ $q->set( 'post_type', 'lp_course' );
390
+ $q->set( 'page_id', '' );
391
+ if ( isset( $q->query['paged'] ) ) {
392
+ $q->set( 'paged', $q->query['paged'] );
393
+ }
394
+
395
+ global $wp_post_types;
396
+
397
+ $course_page = get_post( learn_press_get_page_id( 'courses' ) );
398
+ $this->queried_object = $course_page;
399
+ $wp_post_types['lp_course']->ID = $course_page->ID;
400
+ $wp_post_types['lp_course']->post_title = $course_page->post_title;
401
+ $wp_post_types['lp_course']->post_name = $course_page->post_name;
402
+ $wp_post_types['lp_course']->post_type = $course_page->post_type;
403
+ $wp_post_types['lp_course']->ancestors = get_ancestors( $course_page->ID, $course_page->post_type );
404
+
405
+ $q->is_singular = false;
406
+ $q->is_post_type_archive = true;
407
+ $q->is_archive = true;
408
+ $q->is_page = true;
409
+
410
+ }
411
+
412
+ if ( ( learn_press_is_courses() || learn_press_is_course_category() ) && $limit = absint( LP()->settings->get( 'archive_course_limit' ) ) ) {
413
+ $q->set( 'posts_per_page', $limit );
414
+ }
415
+
416
+ add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10 );
417
+
418
+ return $q;
419
+ }
420
+
421
+ public static function instance() {
422
+ if ( !self::$_instance ) {
423
+ self::$_instance = new self();
424
+ }
425
+ return self::$_instance;
426
+ }
427
+ }
428
+
429
+ LP_Page_Controller::instance();
inc/class-lp-session-handler.php CHANGED
@@ -1,359 +1,358 @@
1
- <?php
2
-
3
- /**
4
- * Class LP_Session_Handler
5
- */
6
- class LP_Session_Handler {
7
-
8
- /**
9
- * @var int $_customer_id
10
- */
11
- protected $_customer_id;
12
-
13
- /**
14
- * @var array $_data
15
- */
16
- protected $_data = array();
17
-
18
- /**
19
- * @var bool $_changed
20
- */
21
- protected $_changed = false;
22
-
23
- /**
24
- * @var string cookie name
25
- */
26
- private $_cookie;
27
-
28
- /**
29
- * @var string session expiration timestamp
30
- */
31
- private $_session_expiration;
32
-
33
- /**
34
- * $var bool Bool based on whether a cookie exists
35
- */
36
- private $_has_cookie = false;
37
-
38
- /**
39
- * @var string Custom session table name
40
- */
41
- private $_table;
42
-
43
- /**
44
- * @var null
45
- */
46
- private static $_instance = null;
47
-
48
- /**
49
- * __get function.
50
- *
51
- * @param mixed $key
52
- *
53
- * @return mixed
54
- */
55
- public function __get( $key ) {
56
- return $this->get( $key );
57
- }
58
-
59
- /**
60
- * __set function.
61
- *
62
- * @param mixed $key
63
- * @param mixed $value
64
- */
65
- public function __set( $key, $value ) {
66
- $this->set( $key, $value );
67
- }
68
-
69
- /**
70
- * __isset function.
71
- *
72
- * @param mixed $key
73
- *
74
- * @return bool
75
- */
76
- public function __isset( $key ) {
77
- return isset( $this->_data[sanitize_key( $key )] );
78
- }
79
-
80
- /**
81
- * __unset function.
82
- *
83
- * @param mixed $key
84
- */
85
- public function __unset( $key ) {
86
- if ( isset( $this->_data[$key] ) ) {
87
- unset( $this->_data[$key] );
88
- $this->_changed = true;
89
- }
90
- }
91
-
92
- public function __construct() {
93
- global $wpdb;
94
-
95
- $this->_cookie = 'wp_learn_press_session_' . COOKIEHASH;
96
- $this->_table = $wpdb->prefix . 'learnpress_sessions';
97
-
98
- if ( $cookie = $this->get_session_cookie() ) {
99
- $this->_customer_id = $cookie[0];
100
- $this->_session_expiration = $cookie[1];
101
- $this->_has_cookie = true;
102
- if ( time() > $this->_session_expiration - HOUR_IN_SECONDS ) {
103
- $this->set_session_expiration();
104
- $this->update_session_timestamp( $this->_customer_id, $this->_session_expiration );
105
- }
106
-
107
- } else {
108
- $this->set_session_expiration();
109
- $this->_customer_id = $this->generate_customer_id();
110
-
111
- }
112
- $this->_data = $this->get_session_data();
113
-
114
- add_action( 'learn_press_set_cart_cookies', array( $this, 'set_customer_session_cookie' ), 10 );
115
- add_action( 'learn_press_cleanup_sessions', array( $this, 'cleanup_sessions' ), 10 );
116
- add_action( 'shutdown', array( $this, 'save_data' ), 20 );
117
- add_action( 'wp_logout', array( $this, 'destroy_session' ) );
118
-
119
- if ( !is_user_logged_in() ) {
120
- //add_filter( 'nonce_user_logged_out', array( $this, 'nonce_user_logged_out' ) );
121
- }
122
- }
123
-
124
- public function set_customer_session_cookie( $set ) {
125
- if ( $set ) {
126
- // Set/renew our cookie
127
- $to_hash = $this->_customer_id . '|' . $this->_session_expiration;
128
- $cookie_hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) );
129
- $cookie_value = $this->_customer_id . '||' . $this->_session_expiration . '||' . $cookie_hash;
130
- $this->_has_cookie = true;
131
-
132
- // Set the cookie
133
- learn_press_setcookie( $this->_cookie, $cookie_value, $this->_session_expiration, apply_filters( 'learn_press_session_use_secure_cookie', false ) );
134
- }
135
- }
136
-
137
- public function has_session() {
138
- return isset( $_COOKIE[$this->_cookie] ) || $this->_has_cookie || is_user_logged_in();
139
- }
140
-
141
- public function set_session_expiration() {
142
- $this->_session_expiration = time() + intval( apply_filters( 'learn_press_session_expiration', 60 * 60 * 48 ) );
143
- }
144
-
145
- public function generate_customer_id() {
146
- if ( is_user_logged_in() ) {
147
- return get_current_user_id();
148
- } else {
149
- require_once( ABSPATH . 'wp-includes/class-phpass.php' );
150
- $hasher = new PasswordHash( 12, false );
151
- return md5( $hasher->get_random_bytes( 32 ) );
152
- }
153
- }
154
-
155
- public function get_session_cookie() {
156
-
157
- if ( empty( $_COOKIE[$this->_cookie] ) || !is_string( $_COOKIE[$this->_cookie] ) ) {
158
-
159
-
160
- return false;
161
- }
162
-
163
- list( $customer_id, $session_expiration, $cookie_hash ) = explode( '||', $_COOKIE[$this->_cookie] );
164
-
165
-
166
- $to_hash = $customer_id . '|' . $session_expiration;
167
- $hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) );
168
-
169
- if ( empty( $cookie_hash ) || !hash_equals( $hash, $cookie_hash ) ) {
170
- return false;
171
- }
172
-
173
- return array( $customer_id, $session_expiration, $cookie_hash );
174
- }
175
-
176
- public function get_session_data() {
177
- return $this->has_session() ? (array) $this->get_session( $this->_customer_id, array() ) : array();
178
- }
179
-
180
- public function get_cache_prefix( $group = LP_SESSION_CACHE_GROUP ) {
181
- // Get cache key - uses cache key wc_orders_cache_prefix to invalidate when needed
182
- $prefix = wp_cache_get( 'learn_press_' . $group . '_cache_prefix', $group );
183
-
184
- if ( false === $prefix ) {
185
- $prefix = 1;
186
- wp_cache_set( 'learn_press_' . $group . '_cache_prefix', $prefix, $group );
187
- }
188
-
189
- return 'learn_press_cache_' . $prefix . '_';
190
- }
191
-
192
- /**
193
- * Increment group cache prefix (invalidates cache).
194
- *
195
- * @param string $group
196
- */
197
- public function incr_cache_prefix( $group ) {
198
- wp_cache_incr( 'learn_press_' . $group . '_cache_prefix', 1, $group );
199
- }
200
-
201
-
202
- public function save_data() {
203
-
204
- if ( $this->_changed && $this->has_session() ) {
205
- global $wpdb;
206
-
207
- $wpdb->replace(
208
- $this->_table,
209
- array(
210
- 'session_key' => $this->_customer_id,
211
- 'session_value' => maybe_serialize( $this->_data ),
212
- 'session_expiry' => $this->_session_expiration
213
- ),
214
- array(
215
- '%s',
216
- '%s',
217
- '%d'
218
- )
219
- );
220
-
221
- // Set cache
222
- wp_cache_set( $this->get_cache_prefix() . $this->_customer_id, $this->_data, LP_SESSION_CACHE_GROUP, $this->_session_expiration - time() );
223
-
224
- // Mark session clean after saving
225
- $this->_changed = false;
226
- }
227
-
228
- }
229
-
230
- public function destroy_session() {
231
- // Clear cookie
232
- learn_press_setcookie( $this->_cookie, '', time() - YEAR_IN_SECONDS, apply_filters( 'learn_press_session_secure_cookie', false ) );
233
-
234
- $this->delete_session( $this->_customer_id );
235
-
236
- // Clear cart
237
- learn_press_session_set( 'cart', '' );
238
-
239
- // Clear data
240
- $this->_data = array();
241
- $this->_changed = false;
242
- $this->_customer_id = $this->generate_customer_id();
243
- }
244
-
245
- public function nonce_user_logged_out( $uid ) {
246
- return $this->has_session() && $this->_customer_id ? $this->_customer_id : $uid;
247
- }
248
-
249
- public function cleanup_sessions() {
250
- global $wpdb;
251
-
252
- if ( !defined( 'WP_SETUP_CONFIG' ) && !defined( 'WP_INSTALLING' ) ) {
253
-
254
- // Delete expired sessions
255
- $wpdb->query( $wpdb->prepare( "DELETE FROM $this->_table WHERE session_expiry < %d", time() ) );
256
-
257
- // Invalidate cache
258
- $this->incr_cache_prefix( LP_SESSION_CACHE_GROUP );
259
- }
260
- }
261
-
262
- public function get_session( $customer_id, $default = false ) {
263
- global $wpdb;
264
-
265
- if ( defined( 'WP_SETUP_CONFIG' ) ) {
266
- return false;
267
- }
268
-
269
- // Try get it from the cache, it will return false if not present or if object cache not in use
270
- $value = wp_cache_get( $this->get_cache_prefix() . $customer_id, LP_SESSION_CACHE_GROUP );
271
- ///echo "KEY:" . $this->get_cache_prefix() . $customer_id . "]";
272
- if ( false === $value ) {
273
- $q = $wpdb->prepare( "SELECT session_value FROM $this->_table WHERE session_key = %s", $customer_id );
274
- $value = $wpdb->get_var( $q );
275
- if ( is_null( $value ) ) {
276
- $value = $default;
277
- }
278
-
279
- wp_cache_add( $this->get_cache_prefix() . $customer_id, $value, LP_SESSION_CACHE_GROUP, $this->_session_expiration - time() );
280
- }
281
-
282
- return maybe_unserialize( $value );
283
- }
284
-
285
- public function delete_session( $customer_id ) {
286
- global $wpdb;
287
-
288
- wp_cache_delete( $this->get_cache_prefix() . $customer_id, LP_SESSION_CACHE_GROUP );
289
-
290
- $wpdb->delete(
291
- $this->_table,
292
- array(
293
- 'session_key' => $customer_id
294
- )
295
- );
296
- }
297
-
298
- public function update_session_timestamp( $customer_id, $timestamp ) {
299
- global $wpdb;
300
-
301
- $wpdb->update(
302
- $this->_table,
303
- array(
304
- 'session_expiry' => $timestamp
305
- ),
306
- array(
307
- 'session_key' => $customer_id
308
- ),
309
- array(
310
- '%d'
311
- )
312
- );
313
- }
314
-
315
- public function get( $key, $default = null ) {
316
- $key = sanitize_key( $key );
317
- return isset( $this->_data[$key] ) ? maybe_unserialize( $this->_data[$key] ) : $default;
318
- }
319
-
320
- public function set( $key, $value ) {
321
- if ( $value !== $this->get( $key ) ) {
322
- $this->_data[sanitize_key( $key )] = maybe_serialize( $value );
323
- $this->_changed = true;
324
- }
325
- }
326
-
327
- public function get_customer_id() {
328
- return $this->_customer_id;
329
- }
330
-
331
- public static function instance() {
332
- if ( !self::$_instance ) {
333
- self::$_instance = new self();
334
- }
335
- return self::$_instance;
336
- }
337
- }
338
-
339
- /**
340
- * @param $key
341
- * @param null $default
342
- *
343
- * @return array|string
344
- */
345
- function learn_press_session_get( $key, $default = null ) {
346
- return LP_Session_Handler::instance()->get( $key, $default );
347
- }
348
-
349
- /**
350
- * @param $key
351
- * @param $value
352
- */
353
- function learn_press_session_set( $key, $value ) {
354
- return LP_Session_Handler::instance()->set( $key, $value );
355
- }
356
-
357
- function learn_press_session_remove( $key ) {
358
-
359
  }
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Session_Handler
5
+ */
6
+ class LP_Session_Handler {
7
+
8
+ /**
9
+ * @var int $_customer_id
10
+ */
11
+ protected $_customer_id;
12
+
13
+ /**
14
+ * @var array $_data
15
+ */
16
+ protected $_data = array();
17
+
18
+ /**
19
+ * @var bool $_changed
20
+ */
21
+ protected $_changed = false;
22
+
23
+ /**
24
+ * @var string cookie name
25
+ */
26
+ private $_cookie;
27
+
28
+ /**
29
+ * @var string session expiration timestamp
30
+ */
31
+ private $_session_expiration;
32
+
33
+ /**
34
+ * $var bool Bool based on whether a cookie exists
35
+ */
36
+ private $_has_cookie = false;
37
+
38
+ /**
39
+ * @var string Custom session table name
40
+ */
41
+ private $_table;
42
+
43
+ /**
44
+ * @var null
45
+ */
46
+ private static $_instance = null;
47
+
48
+ /**
49
+ * __get function.
50
+ *
51
+ * @param mixed $key
52
+ *
53
+ * @return mixed
54
+ */
55
+ public function __get( $key ) {
56
+ return $this->get( $key );
57
+ }
58
+
59
+ /**
60
+ * __set function.
61
+ *
62
+ * @param mixed $key
63
+ * @param mixed $value
64
+ */
65
+ public function __set( $key, $value ) {
66
+ $this->set( $key, $value );
67
+ }
68
+
69
+ /**
70
+ * __isset function.
71
+ *
72
+ * @param mixed $key
73
+ *
74
+ * @return bool
75
+ */
76
+ public function __isset( $key ) {
77
+ return isset( $this->_data[sanitize_key( $key )] );
78
+ }
79
+
80
+ /**
81
+ * __unset function.
82
+ *
83
+ * @param mixed $key
84
+ */
85
+ public function __unset( $key ) {
86
+ if ( isset( $this->_data[$key] ) ) {
87
+ unset( $this->_data[$key] );
88
+ $this->_changed = true;
89
+ }
90
+ }
91
+
92
+ public function __construct() {
93
+ global $wpdb;
94
+
95
+ $this->_cookie = 'wp_learn_press_session_' . COOKIEHASH;
96
+ $this->_table = $wpdb->prefix . 'learnpress_sessions';
97
+
98
+ if ( $cookie = $this->get_session_cookie() ) {
99
+ $this->_customer_id = $cookie[0];
100
+ $this->_session_expiration = $cookie[1];
101
+ $this->_has_cookie = true;
102
+ if ( time() > $this->_session_expiration - HOUR_IN_SECONDS ) {
103
+ $this->set_session_expiration();
104
+ $this->update_session_timestamp( $this->_customer_id, $this->_session_expiration );
105
+ }
106
+
107
+ } else {
108
+ $this->set_session_expiration();
109
+ $this->_customer_id = $this->generate_customer_id();
110
+
111
+ }
112
+ $this->_data = $this->get_session_data();
113
+
114
+ add_action( 'learn_press_set_cart_cookies', array( $this, 'set_customer_session_cookie' ), 10 );
115
+ add_action( 'learn_press_cleanup_sessions', array( $this, 'cleanup_sessions' ), 10 );
116
+ add_action( 'shutdown', array( $this, 'save_data' ), 20 );
117
+ add_action( 'wp_logout', array( $this, 'destroy_session' ) );
118
+
119
+ if ( !is_user_logged_in() ) {
120
+ //add_filter( 'nonce_user_logged_out', array( $this, 'nonce_user_logged_out' ) );
121
+ }
122
+ }
123
+
124
+ public function set_customer_session_cookie( $set ) {
125
+ if ( $set ) {
126
+ // Set/renew our cookie
127
+ $to_hash = $this->_customer_id . '|' . $this->_session_expiration;
128
+ $cookie_hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) );
129
+ $cookie_value = $this->_customer_id . '||' . $this->_session_expiration . '||' . $cookie_hash;
130
+ $this->_has_cookie = true;
131
+
132
+ // Set the cookie
133
+ learn_press_setcookie( $this->_cookie, $cookie_value, $this->_session_expiration, apply_filters( 'learn_press_session_use_secure_cookie', false ) );
134
+ }
135
+ }
136
+
137
+ public function has_session() {
138
+ return isset( $_COOKIE[$this->_cookie] ) || $this->_has_cookie || is_user_logged_in();
139
+ }
140
+
141
+ public function set_session_expiration() {
142
+ $this->_session_expiration = time() + intval( apply_filters( 'learn_press_session_expiration', 60 * 60 * 48 ) );
143
+ }
144
+
145
+ public function generate_customer_id() {
146
+ if ( is_user_logged_in() ) {
147
+ return get_current_user_id();
148
+ } else {
149
+ require_once( ABSPATH . 'wp-includes/class-phpass.php' );
150
+ $hasher = new PasswordHash( 12, false );
151
+ return md5( $hasher->get_random_bytes( 32 ) );
152
+ }
153
+ }
154
+
155
+ public function get_session_cookie() {
156
+
157
+ if ( empty( $_COOKIE[$this->_cookie] ) || !is_string( $_COOKIE[$this->_cookie] ) ) {
158
+
159
+
160
+ return false;
161
+ }
162
+
163
+ list( $customer_id, $session_expiration, $cookie_hash ) = explode( '||', $_COOKIE[$this->_cookie] );
164
+
165
+
166
+ $to_hash = $customer_id . '|' . $session_expiration;
167
+ $hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) );
168
+
169
+ if ( empty( $cookie_hash ) || !hash_equals( $hash, $cookie_hash ) ) {
170
+ return false;
171
+ }
172
+
173
+ return array( $customer_id, $session_expiration, $cookie_hash );
174
+ }
175
+
176
+ public function get_session_data() {
177
+ return $this->has_session() ? (array) $this->get_session( $this->_customer_id, array() ) : array();
178
+ }
179
+
180
+ public function get_cache_prefix( $group = LP_SESSION_CACHE_GROUP ) {
181
+ $prefix = wp_cache_get( 'learn_press_' . $group . '_cache_prefix', $group );
182
+
183
+ if ( false === $prefix ) {
184
+ $prefix = 1;
185
+ wp_cache_set( 'learn_press_' . $group . '_cache_prefix', $prefix, $group );
186
+ }
187
+
188
+ return 'learn_press_cache_' . $prefix . '_';
189
+ }
190
+
191
+ /**
192
+ * Increment group cache prefix (invalidates cache).
193
+ *
194
+ * @param string $group
195
+ */
196
+ public function incr_cache_prefix( $group ) {
197
+ wp_cache_incr( 'learn_press_' . $group . '_cache_prefix', 1, $group );
198
+ }
199
+
200
+
201
+ public function save_data() {
202
+
203
+ if ( $this->_changed && $this->has_session() ) {
204
+ global $wpdb;
205
+
206
+ $wpdb->replace(
207
+ $this->_table,
208
+ array(
209
+ 'session_key' => $this->_customer_id,
210
+ 'session_value' => maybe_serialize( $this->_data ),
211
+ 'session_expiry' => $this->_session_expiration
212
+ ),
213
+ array(
214
+ '%s',
215
+ '%s',
216
+ '%d'
217
+ )
218
+ );
219
+
220
+ // Set cache
221
+ wp_cache_set( $this->get_cache_prefix() . $this->_customer_id, $this->_data, LP_SESSION_CACHE_GROUP, $this->_session_expiration - time() );
222
+
223
+ // Mark session clean after saving
224
+ $this->_changed = false;
225
+ }
226
+
227
+ }
228
+
229
+ public function destroy_session() {
230
+ // Clear cookie
231
+ learn_press_setcookie( $this->_cookie, '', time() - YEAR_IN_SECONDS, apply_filters( 'learn_press_session_secure_cookie', false ) );
232
+
233
+ $this->delete_session( $this->_customer_id );
234
+
235
+ // Clear cart
236
+ learn_press_session_set( 'cart', '' );
237
+
238
+ // Clear data
239
+ $this->_data = array();
240
+ $this->_changed = false;
241
+ $this->_customer_id = $this->generate_customer_id();
242
+ }
243
+
244
+ public function nonce_user_logged_out( $uid ) {
245
+ return $this->has_session() && $this->_customer_id ? $this->_customer_id : $uid;
246
+ }
247
+
248
+ public function cleanup_sessions() {
249
+ global $wpdb;
250
+
251
+ if ( !defined( 'WP_SETUP_CONFIG' ) && !defined( 'WP_INSTALLING' ) ) {
252
+
253
+ // Delete expired sessions
254
+ $wpdb->query( $wpdb->prepare( "DELETE FROM $this->_table WHERE session_expiry < %d", time() ) );
255
+
256
+ // Invalidate cache
257
+ $this->incr_cache_prefix( LP_SESSION_CACHE_GROUP );
258
+ }
259
+ }
260
+
261
+ public function get_session( $customer_id, $default = false ) {
262
+ global $wpdb;
263
+
264
+ if ( defined( 'WP_SETUP_CONFIG' ) ) {
265
+ return false;
266
+ }
267
+
268
+ // Try get it from the cache, it will return false if not present or if object cache not in use
269
+ $value = wp_cache_get( $this->get_cache_prefix() . $customer_id, LP_SESSION_CACHE_GROUP );
270
+ ///echo "KEY:" . $this->get_cache_prefix() . $customer_id . "]";
271
+ if ( false === $value ) {
272
+ $q = $wpdb->prepare( "SELECT session_value FROM $this->_table WHERE session_key = %s", $customer_id );
273
+ $value = $wpdb->get_var( $q );
274
+ if ( is_null( $value ) ) {
275
+ $value = $default;
276
+ }
277
+
278
+ wp_cache_add( $this->get_cache_prefix() . $customer_id, $value, LP_SESSION_CACHE_GROUP, $this->_session_expiration - time() );
279
+ }
280
+
281
+ return maybe_unserialize( $value );
282
+ }
283
+
284
+ public function delete_session( $customer_id ) {
285
+ global $wpdb;
286
+
287
+ wp_cache_delete( $this->get_cache_prefix() . $customer_id, LP_SESSION_CACHE_GROUP );
288
+
289
+ $wpdb->delete(
290
+ $this->_table,
291
+ array(
292
+ 'session_key' => $customer_id
293
+ )
294
+ );
295
+ }
296
+
297
+ public function update_session_timestamp( $customer_id, $timestamp ) {
298
+ global $wpdb;
299
+
300
+ $wpdb->update(
301
+ $this->_table,
302
+ array(
303
+ 'session_expiry' => $timestamp
304
+ ),
305
+ array(
306
+ 'session_key' => $customer_id
307
+ ),
308
+ array(
309
+ '%d'
310
+ )
311
+ );
312
+ }
313
+
314
+ public function get( $key, $default = null ) {
315
+ $key = sanitize_key( $key );
316
+ return isset( $this->_data[$key] ) ? maybe_unserialize( $this->_data[$key] ) : $default;
317
+ }
318
+
319
+ public function set( $key, $value ) {
320
+ if ( $value !== $this->get( $key ) ) {
321
+ $this->_data[sanitize_key( $key )] = maybe_serialize( $value );
322
+ $this->_changed = true;
323
+ }
324
+ }
325
+
326
+ public function get_customer_id() {
327
+ return $this->_customer_id;
328
+ }
329
+
330
+ public static function instance() {
331
+ if ( !self::$_instance ) {
332
+ self::$_instance = new self();
333
+ }
334
+ return self::$_instance;
335
+ }
336
+ }
337
+
338
+ /**
339
+ * @param $key
340
+ * @param null $default
341
+ *
342
+ * @return array|string
343
+ */
344
+ function learn_press_session_get( $key, $default = null ) {
345
+ return LP_Session_Handler::instance()->get( $key, $default );
346
+ }
347
+
348
+ /**
349
+ * @param $key
350
+ * @param $value
351
+ */
352
+ function learn_press_session_set( $key, $value ) {
353
+ return LP_Session_Handler::instance()->set( $key, $value );
354
+ }
355
+
356
+ function learn_press_session_remove( $key ) {
357
+
 
358
  }
inc/class-lp-shortcodes.php CHANGED
@@ -1,372 +1,375 @@
1
- <?php
2
- /**
3
- * @author ThimPress
4
- * @package LearnPress/Shortcodes
5
- * @version 1.0
6
- */
7
-
8
- if ( !defined( 'ABSPATH' ) ) {
9
- exit;
10
- }
11
-
12
- /**
13
- * LP_Shortcodes class
14
- */
15
- class LP_Shortcodes {
16
- /**
17
- * Init shortcodes
18
- */
19
- public static function init() {
20
- $shortcodes = array(
21
- 'learn_press_confirm_order' => __CLASS__ . '::confirm_order',
22
- 'learn_press_profile' => __CLASS__ . '::profile',
23
- 'learn_press_become_teacher_form' => __CLASS__ . '::become_teacher_form',
24
- 'learn_press_login_form' => __CLASS__ . '::login_form',
25
- 'learn_press_checkout' => __CLASS__ . '::checkout',
26
- );
27
-
28
- foreach ( $shortcodes as $shortcode => $function ) {
29
- add_shortcode( apply_filters( "{$shortcode}_shortcode_tag", $shortcode ), $function );
30
- }
31
-
32
- add_action( 'template_redirect', array( __CLASS__, 'auto_shortcode' ) );
33
- }
34
-
35
- public static function auto_shortcode( $template ) {
36
- if ( is_page() ) {
37
- global $post, $wp_query, $wp;
38
- $page_id = !empty( $wp_query->queried_object_id ) ?
39
- $wp_query->queried_object_id :
40
- ( !empty( $wp_query->query_vars['page_id'] ) ? $wp_query->query_vars['page_id'] : - 1 );
41
- if ( $page_id == learn_press_get_page_id( 'checkout' ) ) {
42
- if ( !preg_match( '/\[learn_press_checkout\s?(.*)\]/', $post->post_content ) ) {
43
- $post->post_content .= '[learn_press_checkout]';
44
- }
45
- } elseif ( $page_id == learn_press_get_page_id( 'profile' ) ) {
46
- if ( empty( $wp->query_vars['user'] ) ) {
47
- $current_user = wp_get_current_user();
48
- if ( !empty( $current_user->user_login ) ) {
49
- $redirect = learn_press_get_endpoint_url( '', $current_user->user_login, learn_press_get_page_link( 'profile' ) );
50
- if ( $redirect && !learn_press_is_current_url( $redirect ) ) {
51
- wp_redirect( $redirect );
52
- die();
53
- }
54
- } else {
55
- if ( !preg_match( '/\[learn_press_login_form\s?(.*)\]/', $post->post_content ) ) {
56
- if ( !empty( $_REQUEST['redirect_to'] ) ) {
57
- $redirect = $_REQUEST['redirect_to'];
58
- } else {
59
- $redirect = '';
60
- }
61
- $post->post_content .= '[learn_press_login_form redirect="' . esc_attr( $redirect ) . '"]';
62
- }
63
- }
64
- } else {
65
- $query = array();
66
- parse_str( $wp->matched_query, $query );
67
- if ( empty( $query['view'] ) ) {
68
- wp_redirect( learn_press_user_profile_link( $wp->query_vars['user'] ) );
69
- die();
70
- }
71
- if ( $query ) {
72
- $profile_endpoints = (array) LP()->settings->get( 'profile_endpoints' );
73
- $endpoints = array_keys( $profile_endpoints );
74
- foreach ( $query as $k => $v ) {
75
- if ( ( $k == 'view' ) ) {
76
- if ( !$v ) {
77
- $v = reset( $profile_endpoints );
78
- }
79
- if ( !in_array( $v, apply_filters( 'learn_press_profile_tab_endpoints', $profile_endpoints ) ) ) {
80
- learn_press_404_page();
81
- }
82
- }
83
- if ( !empty( $v ) ) {
84
- $wp->query_vars[$k] = $v;
85
- }
86
- }
87
- }
88
- if ( !preg_match( '/\[learn_press_profile\s?(.*)\]/', $post->post_content ) ) {
89
- $post->post_content .= '[learn_press_profile]';
90
- }
91
- }
92
-
93
- } elseif ( $page_id == learn_press_get_page_id( 'become_a_teacher' ) ) {
94
- if ( !preg_match( '/\[learn_press_become_teacher_form\s?(.*)\]/', $post->post_content ) ) {
95
- $post->post_content .= '[learn_press_become_teacher_form]';
96
- }
97
- }
98
-
99
- do_action( 'learn_press_auto_shortcode', $post, $template );
100
- }
101
- return $template;
102
- }
103
-
104
- public static function _login_form_bottom( $content, $args ) {
105
- if ( !( !empty( $args['context'] ) && $args['context'] == 'learn-press-login' ) ) {
106
- return;
107
- }
108
- }
109
-
110
- public static function wrapper_shortcode( $content ) {
111
- ob_start();
112
- learn_press_print_messages();
113
- $html = ob_get_clean();
114
- return '<div class="learnpress">' . $html . $content . '</div>';
115
- }
116
-
117
- /**
118
- * Checkout form
119
- *
120
- * @param array
121
- *
122
- * @return string
123
- */
124
- public static function checkout( $atts ) {
125
- global $wp;
126
- ob_start();
127
-
128
- if ( isset( $wp->query_vars['lp-order-received'] ) ) {
129
-
130
- self::order_received( $wp->query_vars['lp-order-received'] );
131
-
132
- } else {
133
- $cart = learn_press_get_checkout_cart();
134
- // Check cart has contents
135
- if ( $cart->is_empty() ) {
136
- learn_press_get_template( 'cart/empty-cart.php', array( 'checkout' => LP()->checkout() ) );
137
- } else {
138
- learn_press_get_template( 'checkout/form.php', array( 'checkout' => LP()->checkout() ) );
139
- }
140
- }
141
- return self::wrapper_shortcode( ob_get_clean() );
142
- }
143
-
144
- private static function order_received( $order_id = 0 ) {
145
-
146
- learn_press_print_notices();
147
-
148
- $order = false;
149
-
150
- // Get the order
151
- $order_id = absint( $order_id );
152
- $order_key = !empty( $_GET['key'] ) ? $_GET['key'] : '';
153
-
154
- if ( $order_id > 0 && ( $order = learn_press_get_order( $order_id ) ) && $order->post->post_status != 'trash' ) {
155
- if ( $order->order_key != $order_key )
156
- unset( $order );
157
- } else {
158
- learn_press_display_message( __( 'Invalid order!', 'learnpress' ), 'error' );
159
- return;
160
- }
161
-
162
- LP()->session->order_awaiting_payment = null;
163
-
164
- learn_press_get_template( 'checkout/order-received.php', array( 'order' => $order ) );
165
- }
166
-
167
- /**
168
- * Shortcode content for "Confirm Order" page
169
- *
170
- * @param array $atts
171
- *
172
- * @return string
173
- */
174
- public static function confirm_order( $atts = null ) {
175
- $atts = shortcode_atts(
176
- array(
177
- 'order_id' => !empty( $_REQUEST['order_id'] ) ? intval( $_REQUEST['order_id'] ) : 0
178
- ),
179
- $atts
180
- );
181
-
182
- $order_id = null;
183
-
184
- extract( $atts );
185
- ob_start();
186
-
187
- $order = learn_press_get_order( $order_id );
188
-
189
- if ( $order ) {
190
- learn_press_get_template( 'order/confirm.php', array( 'order' => $order ) );
191
- }
192
-
193
- return self::wrapper_shortcode( ob_get_clean() );
194
- }
195
-
196
- /**
197
- * Display a form let the user can be join as a teacher
198
- *
199
- * @param array|null
200
- *
201
- * @return string
202
- */
203
- public static function become_teacher_form( $atts ) {
204
- $user = learn_press_get_current_user();
205
- $message = '';
206
- $code = 0;
207
-
208
- if ( !is_user_logged_in() ) {
209
- $message = __( "Please login to fill in this form.", 'learnpress' );
210
- $code = 1;
211
- } elseif ( in_array( LP_TEACHER_ROLE, $user->user->roles ) ) {
212
- $message = __( "You are a teacher now.", 'learnpress' );
213
- $code = 2;
214
- } elseif ( get_transient( 'learn_press_become_teacher_sent_' . $user->id ) == 'yes' ) {
215
- $message = __( 'Your request has been sent! We will get in touch with you soon!', 'learnpress' );
216
- $code = 3;
217
- } elseif ( learn_press_user_maybe_is_a_teacher() ) {
218
- $message = __( 'Your role is allowed to create a course.', 'learnpress' );
219
- $code = 4;
220
- }
221
-
222
- if ( !apply_filters( 'learn_press_become_a_teacher_display_form', true, $code, $message ) ) {
223
- return;
224
- }
225
-
226
- $atts = shortcode_atts(
227
- array(
228
- 'method' => 'post',
229
- 'action' => '',
230
- 'title' => __( 'Become a Teacher', 'learnpress' ),
231
- 'description' => __( 'Fill in your information and send us to become a teacher.', 'learnpress' ),
232
- 'submit_button_text' => __( 'Submit', 'learnpress' ),
233
- 'submit_button_process_text' => __( 'Processing', 'learnpress' )
234
- ),
235
- $atts
236
- );
237
- $fields = array(
238
- 'bat_name' => array(
239
- 'title' => __( 'Name', 'learnpress' ),
240
- 'type' => 'text',
241
- 'placeholder' => __( 'Your name', 'learnpress' ),
242
- 'def' => $user->display_name
243
- ),
244
- 'bat_email' => array(
245
- 'title' => __( 'Email', 'learnpress' ),
246
- 'type' => 'email',
247
- 'placeholder' => __( 'Your email address', 'learnpress' ),
248
- 'def' => $user->user_email
249
- ),
250
- 'bat_phone' => array(
251
- 'title' => __( 'Phone', 'learnpress' ),
252
- 'type' => 'text',
253
- 'placeholder' => __( 'Your phone number', 'learnpress' )
254
- )
255
- );
256
- $fields = apply_filters( 'learn_press_become_teacher_form_fields', $fields );
257
- ob_start();
258
- $args = array_merge(
259
- array(
260
- 'fields' => $fields,
261
- 'code' => $code,
262
- 'message' => $message
263
- ),
264
- $atts
265
- );
266
- learn_press_get_template( 'global/become-teacher-form.php', $args );
267
-
268
- $html = ob_get_clean();
269
-
270
- LP_Assets::enqueue_script( 'become-teacher' );
271
-
272
- return self::wrapper_shortcode( $html );
273
- }
274
-
275
- public static function profile() {
276
- global $wp_query, $wp;
277
- if ( isset( $wp_query->query['user'] ) ) {
278
- $user = get_user_by( 'login', urldecode( $wp_query->query['user'] ) );
279
- } else {
280
- $user = get_user_by( 'id', get_current_user_id() );
281
- }
282
- $output = '';
283
-
284
- ob_start();
285
- if ( !$user ) {
286
- if ( empty( $wp_query->query['user'] ) ) {
287
- //learn_press_get_template( 'profile/private-area.php' );
288
- } else {
289
- learn_press_display_message( sprintf( __( 'The user %s is not available!', 'learnpress' ), $wp_query->query['user'] ), 'error' );
290
- }
291
-
292
- } else {
293
-
294
- $user = LP_User_Factory::get_user( $user->ID );
295
- $tabs = learn_press_user_profile_tabs( $user );
296
- if ( !empty( $wp->query_vars['view'] ) ) {
297
- $current = $wp->query_vars['view'];
298
- } else {
299
- $tab_keys = array_keys( $tabs );
300
- $current = reset( $tab_keys );
301
- }
302
- $_REQUEST['tab'] = $current;
303
- $_POST['tab'] = $current;
304
- $_GET['tab'] = $current;
305
- if ( !learn_press_current_user_can_view_profile_section( $current, $user ) ) {
306
- learn_press_get_template( 'profile/private-area.php' );
307
- } else {
308
- if ( !empty( $tabs ) && !empty( $tabs[$current] ) ) :
309
- learn_press_get_template( 'profile/index.php',
310
- array(
311
- 'user' => $user,
312
- 'tabs' => $tabs,
313
- 'current' => $current
314
- )
315
- );
316
- else:
317
- if ( $wp->query_vars['view'] == LP()->settings->get( 'profile_endpoints.profile-order-details' ) ) {
318
- /*
319
- $current_user = wp_get_current_user();
320
- if ( $wp_query->query_vars['user'] != $current_user->user_login ) {
321
- learn_press_get_template( 'profile/private-area.php' );
322
- return;
323
- }*/
324
- $order_id = 0;
325
- if ( !empty( $wp->query_vars['id'] ) ) {
326
- $order_id = $wp->query_vars['id'];
327
- }
328
- $order = learn_press_get_order( $order_id );
329
- if ( !$order ) {
330
- learn_press_display_message( __( 'Invalid order!', 'learnpress' ), 'error' );
331
- } else {
332
- learn_press_get_template( 'profile/order-details.php',
333
- array(
334
- 'user' => $user,
335
- 'order' => $order
336
- )
337
- );
338
- }
339
- }
340
- endif;
341
- }
342
- }
343
- $output .= ob_get_clean();
344
-
345
- return self::wrapper_shortcode( $output );
346
- }
347
-
348
- static function login_form( $atts, $content = '' ) {
349
- $atts = shortcode_atts(
350
- array(
351
- 'redirect' => ''
352
- ),
353
- $atts
354
- );
355
- add_filter( 'login_form_bottom', array( __CLASS__, 'login_form_bottom' ), 10, 2 );
356
- return self::wrapper_shortcode( learn_press_get_template_content( 'profile/login-form.php', $atts ) );
357
- }
358
-
359
- public static function login_form_bottom( $html, $args ) {
360
- ob_start();
361
- ?>
362
- <p>
363
- <a href="<?php echo wp_lostpassword_url();?>"><?php _e( 'Forgot password?', 'learnpress' ); ?></a>
364
- &nbsp;|&nbsp;
365
- <a href="<?php echo wp_registration_url();?>"><?php _e( 'Create new account', 'learnpress' ); ?></a>
366
- </p>
367
- <?php $html .= ob_get_clean();
368
- return $html;
369
- }
370
- }
371
-
 
 
 
372
  LP_Shortcodes::init();
1
+ <?php
2
+ /**
3
+ * @author ThimPress
4
+ * @package LearnPress/Shortcodes
5
+ * @version 1.0
6
+ */
7
+
8
+ if ( !defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ }
11
+
12
+ /**
13
+ * LP_Shortcodes class
14
+ */
15
+ class LP_Shortcodes {
16
+ /**
17
+ * Init shortcodes
18
+ */
19
+ public static function init() {
20
+ $shortcodes = array(
21
+ 'learn_press_confirm_order' => __CLASS__ . '::confirm_order',
22
+ 'learn_press_profile' => __CLASS__ . '::profile',
23
+ 'learn_press_become_teacher_form' => __CLASS__ . '::become_teacher_form',
24
+ 'learn_press_login_form' => __CLASS__ . '::login_form',
25
+ 'learn_press_checkout' => __CLASS__ . '::checkout',
26
+ );
27
+
28
+ foreach ( $shortcodes as $shortcode => $function ) {
29
+ add_shortcode( apply_filters( "{$shortcode}_shortcode_tag", $shortcode ), $function );
30
+ }
31
+
32
+ add_action( 'template_redirect', array( __CLASS__, 'auto_shortcode' ) );
33
+ }
34
+
35
+ public static function auto_shortcode( $template ) {
36
+ if ( is_page() ) {
37
+ global $post, $wp_query, $wp;
38
+ $page_id = !empty( $wp_query->queried_object_id ) ?
39
+ $wp_query->queried_object_id :
40
+ ( !empty( $wp_query->query_vars['page_id'] ) ? $wp_query->query_vars['page_id'] : - 1 );
41
+ if ( $page_id == learn_press_get_page_id( 'checkout' ) ) {
42
+ if ( !preg_match( '/\[learn_press_checkout\s?(.*)\]/', $post->post_content ) ) {
43
+ $post->post_content .= '[learn_press_checkout]';
44
+ }
45
+ } elseif ( $page_id == learn_press_get_page_id( 'profile' ) ) {
46
+ if ( empty( $wp->query_vars['user'] ) ) {
47
+ $current_user = wp_get_current_user();
48
+ if ( !empty( $current_user->user_login ) ) {
49
+ $redirect = learn_press_get_endpoint_url( '', $current_user->user_login, learn_press_get_page_link( 'profile' ) );
50
+ if ( $redirect && !learn_press_is_current_url( $redirect ) ) {
51
+ wp_redirect( $redirect );
52
+ die();
53
+ }
54
+ } else {
55
+ if ( !preg_match( '/\[learn_press_login_form\s?(.*)\]/', $post->post_content ) ) {
56
+ if ( !empty( $_REQUEST['redirect_to'] ) ) {
57
+ $redirect = $_REQUEST['redirect_to'];
58
+ } else {
59
+ $redirect = '';
60
+ }
61
+ $post->post_content .= '[learn_press_login_form redirect="' . esc_attr( $redirect ) . '"]';
62
+ }
63
+ }
64
+ } else {
65
+ $query = array();
66
+ parse_str( $wp->matched_query, $query );
67
+ if ( empty( $query['view'] ) ) {
68
+ $redirect = learn_press_user_profile_link( $wp->query_vars['user'] );
69
+
70
+ if ( !empty($redirect ) ) {
71
+ wp_redirect( $redirect );
72
+ die();
73
+ }
74
+
75
+ }
76
+ if ( $query ) {
77
+ $profile_endpoints = (array) LP()->settings->get( 'profile_endpoints' );
78
+ $endpoints = array_keys( $profile_endpoints );
79
+ foreach ( $query as $k => $v ) {
80
+ if ( ( $k == 'view' ) ) {
81
+ if ( !$v ) {
82
+ $v = reset( $profile_endpoints );
83
+ }
84
+ if ( !in_array( $v, apply_filters( 'learn_press_profile_tab_endpoints', $profile_endpoints ) ) ) {
85
+ learn_press_is_404();
86
+ }
87
+ }
88
+ if ( !empty( $v ) ) {
89
+ $wp->query_vars[$k] = $v;
90
+ }
91
+ }
92
+ }
93
+ if ( !preg_match( '/\[learn_press_profile\s?(.*)\]/', $post->post_content ) ) {
94
+ $post->post_content .= '[learn_press_profile]';
95
+ }
96
+ }
97
+
98
+ } elseif ( $page_id == learn_press_get_page_id( 'become_a_teacher' ) ) {
99
+ if ( !preg_match( '/\[learn_press_become_teacher_form\s?(.*)\]/', $post->post_content ) ) {
100
+ $post->post_content .= '[learn_press_become_teacher_form]';
101
+ }
102
+ }
103
+
104
+ do_action( 'learn_press_auto_shortcode', $post, $template );
105
+ }
106
+ return $template;
107
+ }
108
+
109
+ public static function _login_form_bottom( $content, $args ) {
110
+ if ( !( !empty( $args['context'] ) && $args['context'] == 'learn-press-login' ) ) {
111
+ return;
112
+ }
113
+ }
114
+
115
+ public static function wrapper_shortcode( $content ) {
116
+ ob_start();
117
+ learn_press_print_messages();
118
+ $html = ob_get_clean();
119
+ return '<div class="learnpress">' . $html . $content . '</div>';
120
+ }
121
+
122
+ /**
123
+ * Checkout form
124
+ *
125
+ * @param array
126
+ *
127
+ * @return string
128
+ */
129
+ public static function checkout( $atts ) {
130
+ global $wp;
131
+ ob_start();
132
+
133
+ if ( isset( $wp->query_vars['lp-order-received'] ) ) {
134
+
135
+ self::order_received( $wp->query_vars['lp-order-received'] );
136
+
137
+ } else {
138
+ $cart = learn_press_get_checkout_cart();
139
+ // Check cart has contents
140
+ if ( $cart->is_empty() ) {
141
+ learn_press_get_template( 'cart/empty-cart.php', array( 'checkout' => LP()->checkout() ) );
142
+ } else {
143
+ learn_press_get_template( 'checkout/form.php', array( 'checkout' => LP()->checkout() ) );
144
+ }
145
+ }
146
+ return self::wrapper_shortcode( ob_get_clean() );
147
+ }
148
+
149
+ private static function order_received( $order_id = 0 ) {
150
+
151
+ learn_press_print_notices();
152
+
153
+ $order = false;
154
+
155
+ // Get the order
156
+ $order_id = absint( $order_id );
157
+ $order_key = !empty( $_GET['key'] ) ? $_GET['key'] : '';
158
+
159
+ if ( $order_id > 0 && ( $order = learn_press_get_order( $order_id ) ) && $order->post->post_status != 'trash' ) {
160
+ if ( $order->order_key != $order_key )
161
+ unset( $order );
162
+ } else {
163
+ learn_press_display_message( __( 'Invalid order!', 'learnpress' ), 'error' );
164
+ return;
165
+ }
166
+
167
+ LP()->session->order_awaiting_payment = null;
168
+
169
+ learn_press_get_template( 'checkout/order-received.php', array( 'order' => $order ) );
170
+ }
171
+
172
+ /**
173
+ * Shortcode content for "Confirm Order" page
174
+ *
175
+ * @param array $atts
176
+ *
177
+ * @return string
178
+ */
179
+ public static function confirm_order( $atts = null ) {
180
+ $atts = shortcode_atts(
181
+ array(
182
+ 'order_id' => !empty( $_REQUEST['order_id'] ) ? intval( $_REQUEST['order_id'] ) : 0
183
+ ),
184
+ $atts
185
+ );
186
+
187
+ $order_id = null;
188
+
189
+ extract( $atts );
190
+ ob_start();
191
+
192
+ $order = learn_press_get_order( $order_id );
193
+
194
+ if ( $order ) {
195
+ learn_press_get_template( 'order/confirm.php', array( 'order' => $order ) );
196
+ }
197
+
198
+ return self::wrapper_shortcode( ob_get_clean() );
199
+ }
200
+
201
+ /**
202
+ * Display a form let the user can be join as a teacher
203
+ *
204
+ * @param array|null
205
+ *
206
+ * @return string
207
+ */
208
+ public static function become_teacher_form( $atts ) {
209
+ $user = learn_press_get_current_user();
210
+ $message = '';
211
+ $code = 0;
212
+
213
+ if ( !is_user_logged_in() ) {
214
+ $message = __( "Please login to fill in this form.", 'learnpress' );
215
+ $code = 1;
216
+ } elseif ( in_array( LP_TEACHER_ROLE, $user->user->roles ) ) {
217
+ $message = __( "You are a teacher now.", 'learnpress' );
218
+ $code = 2;
219
+ } elseif ( get_transient( 'learn_press_become_teacher_sent_' . $user->id ) == 'yes' ) {
220
+ $message = __( 'Your request has been sent! We will get in touch with you soon!', 'learnpress' );
221
+ $code = 3;
222
+ } elseif ( learn_press_user_maybe_is_a_teacher() ) {
223
+ $message = __( 'Your role is allowed to create a course.', 'learnpress' );
224
+ $code = 4;
225
+ }
226
+
227
+ if ( !apply_filters( 'learn_press_become_a_teacher_display_form', true, $code, $message ) ) {
228
+ return;
229
+ }
230
+
231
+ $atts = shortcode_atts(
232
+ array(
233
+ 'method' => 'post',
234
+ 'action' => '',
235
+ 'title' => __( 'Become a Teacher', 'learnpress' ),
236
+ 'description' => __( 'Fill in your information and send us to become a teacher.', 'learnpress' ),
237
+ 'submit_button_text' => __( 'Submit', 'learnpress' ),
238
+ 'submit_button_process_text' => __( 'Processing', 'learnpress' )
239
+ ),
240
+ $atts
241
+ );
242
+ $fields = array(
243
+ 'bat_name' => array(
244
+ 'title' => __( 'Name', 'learnpress' ),
245
+ 'type' => 'text',
246
+ 'placeholder' => __( 'Your name', 'learnpress' ),
247
+ 'def' => $user->display_name
248
+ ),
249
+ 'bat_email' => array(
250
+ 'title' => __( 'Email', 'learnpress' ),
251
+ 'type' => 'email',
252
+ 'placeholder' => __( 'Your email address', 'learnpress' ),
253
+ 'def' => $user->user_email
254
+ ),
255
+ 'bat_phone' => array(
256
+ 'title' => __( 'Phone', 'learnpress' ),
257
+ 'type' => 'text',
258
+ 'placeholder' => __( 'Your phone number', 'learnpress' )
259
+ )
260
+ );
261
+ $fields = apply_filters( 'learn_press_become_teacher_form_fields', $fields );
262
+ ob_start();
263
+ $args = array_merge(
264
+ array(
265
+ 'fields' => $fields,
266
+ 'code' => $code,
267
+ 'message' => $message
268
+ ),
269
+ $atts
270
+ );
271
+ learn_press_get_template( 'global/become-teacher-form.php', $args );
272
+
273
+ $html = ob_get_clean();
274
+
275
+ LP_Assets::enqueue_script( 'become-teacher' );
276
+
277
+ return self::wrapper_shortcode( $html );
278
+ }
279
+
280
+ public static function profile() {
281
+ global $wp_query, $wp;
282
+ if ( isset( $wp_query->query['user'] ) ) {
283
+ $user = get_user_by( 'login', urldecode( $wp_query->query['user'] ) );
284
+ } else {
285
+ $user = get_user_by( 'id', get_current_user_id() );
286
+ }
287
+ $output = '';
288
+
289
+ ob_start();
290
+ if ( !$user ) {
291
+ if ( empty( $wp_query->query['user'] ) ) {
292
+
293
+ } else {
294
+ learn_press_display_message( sprintf( __( 'The user %s is not available!', 'learnpress' ), $wp_query->query['user'] ), 'error' );
295
+ }
296
+
297
+ } else {
298
+ $user = LP_User_Factory::get_user( $user->ID );
299
+ $tabs = learn_press_user_profile_tabs( $user );
300
+ if ( !empty( $wp->query_vars['view'] ) ) {
301
+ $current = $wp->query_vars['view'];
302
+ }else{
303
+ $current = '';
304
+ }
305
+ if ( empty( $tabs[$current] ) ) {
306
+ $tab_keys = array_keys( $tabs );
307
+ $current = reset( $tab_keys );
308
+ }
309
+ $_REQUEST['tab'] = $current;
310
+ $_POST['tab'] = $current;
311
+ $_GET['tab'] = $current;
312
+
313
+ if ( !learn_press_current_user_can_view_profile_section( $current, $user ) ) {
314
+ learn_press_get_template( 'profile/private-area.php' );
315
+ } else {
316
+ if ( !empty( $tabs ) && !empty( $tabs[$current] ) ) :
317
+ learn_press_get_template( 'profile/index.php',
318
+ array(
319
+ 'user' => $user,
320
+ 'tabs' => $tabs,
321
+ 'current' => $current
322
+ )
323
+ );
324
+ else:
325
+ if ( $wp->query_vars['view'] == LP()->settings->get( 'profile_endpoints.profile-order-details' ) ) {
326
+ $order_id = 0;
327
+ if ( !empty( $wp->query_vars['id'] ) ) {
328
+ $order_id = $wp->query_vars['id'];
329
+ }
330
+ $order = learn_press_get_order( $order_id );
331
+ if ( !$order ) {
332
+ learn_press_display_message( __( 'Invalid order!', 'learnpress' ), 'error' );
333
+ } else {
334
+ learn_press_get_template( 'profile/order-details.php',
335
+ array(
336
+ 'user' => $user,
337
+ 'order' => $order
338
+ )
339
+ );
340
+ }
341
+ }
342
+ endif;
343
+ }
344
+ }
345
+ $output .= ob_get_clean();
346
+
347
+ return self::wrapper_shortcode( $output );
348
+ }
349
+
350
+ static function login_form( $atts, $content = '' ) {
351
+ $atts = shortcode_atts(
352
+ array(
353
+ 'redirect' => ''
354
+ ),
355
+ $atts
356
+ );
357
+ add_filter( 'login_form_bottom', array( __CLASS__, 'login_form_bottom' ), 10, 2 );
358
+ return self::wrapper_shortcode( learn_press_get_template_content( 'profile/login-form.php', $atts ) );
359
+ }
360
+
361
+ public
362
+ static function login_form_bottom( $html, $args ) {
363
+ ob_start();
364
+ ?>
365
+ <p>
366
+ <a href="<?php echo wp_lostpassword_url(); ?>"><?php _e( 'Forgot password?', 'learnpress' ); ?></a>
367
+ &nbsp;|&nbsp;
368
+ <a href="<?php echo wp_registration_url(); ?>"><?php _e( 'Create new account', 'learnpress' ); ?></a>
369
+ </p>
370
+ <?php $html .= ob_get_clean();
371
+ return $html;
372
+ }
373
+ }
374
+
375
  LP_Shortcodes::init();
inc/course/lp-course-functions.php CHANGED
@@ -1,775 +1,789 @@
1
- <?php
2
- /**
3
- * Common functions to manipulate with course, lesson, quiz, questions, etc...
4
- *
5
- * @author ThimPress
6
- * @package LearnPress/Functions
7
- * @version 1.0
8
- */
9
-
10
- if ( !defined( 'ABSPATH' ) ) {
11
- exit; // Exit if accessed directly
12
- }
13
-
14
- /**
15
- * @param $the_course
16
- *
17
- * @return LP_Course|mixed
18
- */
19
- function learn_press_get_course( $the_course = false ) {
20
- return $the_course ? LP_Course::get_course( $the_course ) : LP()->global['course'];
21
- }
22
-
23
- function learn_press_get_quiz( $the_quiz ) {
24
- return LP_Quiz::get_quiz( $the_quiz );
25
- }
26
-
27
- /**
28
- * print out class for quiz body
29
- *
30
- * @param null $class
31
- *
32
- * @return bool
33
- */
34
- function learn_press_quiz_class( $class = null ) {
35
- $item = LP()->global['course-item'];
36
- $user = LP()->user;
37
-
38
- if ( !$item ) {
39
- return false;
40
- }
41
-
42
- $quiz = LP_Quiz::get_quiz( $item->ID );
43
-
44
- if ( $class && is_string( $class ) ) {
45
- $class = explode( ' ', $class );
46
- } elseif ( !$class ) {
47
- $class = array();
48
- }
49
-
50
- $class[] = "single-quiz";
51
-
52
- if ( $status = $user->get_quiz_status( $quiz->id ) ) {
53
- $class[] = 'quiz-' . $status;
54
- }
55
-
56
- if ( $quiz->has( 'questions' ) ) {
57
- $class[] = 'has-questions';
58
- }
59
-
60
- $class[] = 'clearfix';
61
-
62
- $class = array_unique( $class );
63
-
64
- post_class( join( ' ', $class ) );
65
- }
66
-
67
- /**
68
- * Get the courses that a item is assigned to
69
- *
70
- * @param $item
71
- *
72
- * @return mixed
73
- */
74
- function learn_press_get_item_courses( $item ) {
75
- global $wpdb;
76
- $query = $wpdb->prepare( "
77
- SELECT c.*
78
- FROM {$wpdb->posts} c
79
- INNER JOIN {$wpdb->learnpress_sections} s ON c.ID = s.section_course_id
80
- INNER JOIN {$wpdb->learnpress_section_items} si ON si.section_id = s.section_id
81
- WHERE si.item_id = %d
82
- ", $item );
83
- return $wpdb->get_results( $query );
84
- }
85
-
86
- /**
87
- * Get the quizzes that a question is assigned to
88
- *
89
- * @param $question_id
90
- *
91
- * @return mixed
92
- */
93
- function learn_press_get_question_quizzes( $question_id ) {
94
- global $wpdb;
95
- $query = $wpdb->prepare( "
96
- SELECT q.*
97
- FROM {$wpdb->posts} q
98
- INNER JOIN {$wpdb->prefix}learnpress_quiz_questions qq ON q.ID = qq.quiz_id
99
- WHERE qq.question_id = %d
100
- ", $question_id );
101
- return $wpdb->get_results( $query );
102
- }
103
-
104
- function learn_press_course_post_type_link( $permalink, $post ) {
105
- if ( $post->post_type !== 'lp_course' ) {
106
- return $permalink;
107
- }
108
-
109
- // Abort early if the placeholder rewrite tag isn't in the generated URL
110
- if ( false === strpos( $permalink, '%' ) ) {
111
- return $permalink;
112
- }
113
-
114
- // Get the custom taxonomy terms in use by this post
115
- $terms = get_the_terms( $post->ID, 'course_category' );
116
-
117
- if ( !empty( $terms ) ) {
118
- usort( $terms, '_usort_terms_by_ID' ); // order by ID
119
-
120
- $category_object = apply_filters( 'learn_press_course_post_type_link_course_category', $terms[0], $terms, $post );
121
- $category_object = get_term( $category_object, 'course_category' );
122
- $course_category = $category_object->slug;
123
-
124
- if ( $parent = $category_object->parent ) {
125
- $ancestors = get_ancestors( $category_object->term_id, 'course_category' );
126
- foreach ( $ancestors as $ancestor ) {
127
- $ancestor_object = get_term( $ancestor, 'course_category' );
128
- $course_category = $ancestor_object->slug . '/' . $course_category;
129
- }
130
- }
131
- } else {
132
- // If no terms are assigned to this post, use a string instead (can't leave the placeholder there)
133
- $course_category = _x( 'uncategorized', 'slug', 'learnpress' );
134
- }
135
-
136
- $find = array(
137
- '%year%',
138
- '%monthnum%',
139
- '%day%',
140
- '%hour%',
141
- '%minute%',
142
- '%second%',
143
- '%post_id%',
144
- '%category%',
145
- '%course_category%'
146
- );
147
-
148
- $replace = array(
149
- date_i18n( 'Y', strtotime( $post->post_date ) ),
150
- date_i18n( 'm', strtotime( $post->post_date ) ),
151
- date_i18n( 'd', strtotime( $post->post_date ) ),
152
- date_i18n( 'H', strtotime( $post->post_date ) ),
153
- date_i18n( 'i', strtotime( $post->post_date ) ),
154
- date_i18n( 's', strtotime( $post->post_date ) ),
155
- $post->ID,
156
- $course_category,
157
- $course_category
158
- );
159
-
160
- $permalink = str_replace( $find, $replace, $permalink );
161
-
162
- return $permalink;
163
- }
164
-
165
- add_filter( 'post_type_link', 'learn_press_course_post_type_link', 10, 2 );
166
-
167
- /**
168
- * Get the final quiz for a course if it is existing
169
- *
170
- * @param $course_id
171
- *
172
- * @return mixed
173
- * @throws Exception
174
- */
175
- function learn_press_get_final_quiz( $course_id ) {
176
- $course = LP_Course::get_course( $course_id );
177
- if ( !$course ) {
178
- throw new Exception( sprintf( __( 'The course %d does not exists', 'learnpress' ), $course_id ) );
179
- }
180
- $course_items = $course->get_curriculum_items();
181
- $final = false;
182
- if ( $course_items ) {
183
- $end = end( $course_items );
184
- if ( $end->post_type == LP_QUIZ_CPT ) {
185
- $final = $end->ID;
186
- }
187
- }
188
- return apply_filters( 'learn_press_course_final_quiz', $final, $course_id );
189
- }
190
-
191
- function learn_press_item_meta_format( $item, $nonce = '' ) {
192
- if ( current_theme_supports( 'post-formats' ) ) {
193
- $format = get_post_format( $item );
194
- if ( false === $format ) {
195
- $format = 'standard';
196
- }
197
-
198
- //return false to hide post format
199
- if ( $format = apply_filters( 'learn_press_course_item_format', $format, $item ) ) {
200
- //printf( '<span class="lp-label lp-label-format lp-label-format-%s">%s</span>', $format, ucfirst( $format ) );
201
- printf( '<label for="post-format-0" class="post-format-icon post-format-%s" title="%s"></label>', $format, ucfirst( $format ) );
202
- } else {
203
- echo $nonce;
204
- }
205
- }
206
- }
207
-
208
- function learn_press_course_item_format_exclude( $format, $item ) {
209
- if ( get_post_type( $item ) != LP_LESSON_CPT || ( $format == 'standard' ) ) {
210
- $format = false;
211
- }
212
- return $format;
213
- }
214
-
215
- //add_filter( 'learn_press_course_item_format', 'learn_press_course_item_format_exclude', 5, 2 );
216
- /*******************************************************/
217
- /*******************************************************/
218
-
219
- /**
220
- * Get curriculum of a course
221
- *
222
- * @version 1.0
223
- *
224
- * @param $course_id
225
- *
226
- * @return mixed
227
- */
228
- function learn_press_get_course_curriculum( $course_id ) {
229
- $course = LP_Course::get_course( $course_id );
230
- return $course->get_curriculum();
231
- }
232
-
233
- /**
234
- * Verify course access
235
- *
236
- * @param int $course_id
237
- * @param int $user_id
238
- *
239
- * @return boolean
240
- */
241
- function learn_press_is_enrolled_course( $course_id = null, $user_id = null ) {
242
- //_deprecated_function( __FUNCTION__, '1.0', 'LP_User -> has_enrolled_course');
243
- if ( $course = LP_Course::get_course( $course_id ) && $user = learn_press_get_user( $user_id ) ) {
244
- return $user->has_enrolled_course( $course_id );
245
- }
246
- return false;
247
- }
248
-
249
- /**
250
- * Detect if a course is free or not
251
- *
252
- * @param null $course_id
253
- *
254
- * @return bool
255
- */
256
- function learn_press_is_free_course( $course_id = null ) {
257
- if ( !$course_id ) {
258
- $course_id = get_the_ID();
259
- }
260
- return learn_press_get_course( $course_id )->is_free();
261
- }
262
-
263
- /**
264
- * get current status of user's course
265
- *
266
- * @author Tunn
267
- *
268
- * @param int $user_id
269
- * @param int $course_id
270
- *
271
- * @return string
272
- */
273
- function learn_press_get_user_course_status( $user_id = null, $course_id = null ) {
274
- //_deprecated_function( __FUNCTION__, '1.0', 'LP_User() -> get_course_status');
275
- if ( $course = LP_Course::get_course( $course_id ) && $user = learn_press_get_user( $user_id ) ) {
276
- return $user->get_course_status( $course_id );
277
- }
278
- return false;
279
- }
280
-
281
-
282
- /**
283
- * Check to see if user can view a lesson or not
284
- *
285
- * @since 0.9.5
286
- *
287
- * @param int $lesson_id
288
- * @param int $course_id
289
- * @param int $user_id
290
- *
291
- * @return boolean
292
- */
293
- function learn_press_user_can_view_lesson( $lesson_id, $course_id = 0, $user_id = null ) {
294
- if ( $user_id ) {
295
- $user = learn_press_get_user( $user_id );
296
- } else {
297
- $user = LP()->user;
298
- }
299
- return $user ? $user->can( 'view-lesson', $lesson_id, $course_id ) : false;
300
- }
301
-
302
- /**
303
- * Check to see if user can view a quiz or not
304
- *
305
- * @param int $quiz_id
306
- * @param int $course_id
307
- * @param int $user_id
308
- *
309
- * @return boolean
310
- */
311
- function learn_press_user_can_view_quiz( $quiz_id = null, $course_id = 0, $user_id = null ) {
312
- if ( $user_id ) {
313
- $user = learn_press_get_user( $user_id );
314
- } else {
315
- $user = LP()->user;
316
- }
317
- return $user ? $user->can( 'view-quiz', $quiz_id, $course_id ) : false;
318
- }
319
-
320
- /**
321
- * Get course setting is enroll required or public
322
- *
323
- * @since 0.9.5
324
- *
325
- * @param int $course_id
326
- *
327
- * @return boolean
328
- */
329
- function learn_press_course_enroll_required( $course_id = null ) {
330
- $course_id = learn_press_get_course_id( $course_id );
331
-
332
- $required = ( 'yes' == get_post_meta( $course_id, '_lpr_course_enrolled_require', true ) );
333
- return apply_filters( 'learn_press_course_enroll_required', $required, $course_id );
334
- }
335
-
336
- /**
337
- * Checks to see that an user has finished a lesson or not yet
338
- * Function return the ID of a course if the user has completed a lesson
339
- * Otherwise, return false
340
- *
341
- * @author TuNguyen
342
- *
343
- * @param null $lesson_id
344
- * @param null $user_id
345
- *
346
- * @return mixed
347
- */
348
- function learn_press_user_has_completed_lesson( $lesson_id = null, $user_id = null ) {
349
-
350
- _deprecated_function( __FUNCTION__, '1.0', 'LP_User() -> has_completed_quiz' );
351
- if ( $user = learn_press_get_user( $user_id ) ) {
352
- return $user->has_completed_quiz( $lesson_id );
353
- }
354
- return false;
355
-
356
- $lesson_id = learn_press_get_lesson_id( $lesson_id );
357
- if ( !$user_id ) $user_id = get_current_user_id();
358
-
359
- $completed_lessons = get_user_meta( $user_id, '_lpr_lesson_completed', true );
360
-
361
- if ( !$completed_lessons ) return false;
362
- foreach ( $completed_lessons as $courses ) {
363
- if ( is_array( $courses ) && in_array( $lesson_id, $courses ) ) {
364
- return true;
365
- }
366
- }
367
- return false;
368
- }
369
-
370
- /**
371
- * Short function to check if a lesson id is not passed to a function
372
- * then try to get it from $_REQUEST
373
- *
374
- * @param null $lesson_id
375
- *
376
- * @return int|null
377
- */
378
- function learn_press_get_lesson_id( $lesson_id = null ) {
379
- if ( !$lesson_id ) {
380
- $lesson_id = !empty( $_REQUEST['lesson'] ) ? $_REQUEST['lesson'] : 0;
381
- }
382
- return $lesson_id;
383
- }
384
-
385
- function learn_press_get_all_courses( $args = array() ) {
386
- $term = '';
387
- $exclude = '';
388
- is_array( $args ) && extract( $args );
389
- $args = array(
390
- 'post_type' => array( 'lp_course' ),
391
- 'post_status' => 'publish',
392
- 'posts_per_page' => - 1,
393
- 's' => $term,
394
- 'fields' => 'ids',
395
- 'exclude' => $exclude
396
- );
397
- $args = apply_filters( 'learn_press_get_courses_args', $args );
398
- $posts = get_posts( $args );
399
- return apply_filters( 'learn_press_get_courses', $posts, $args );
400
- }
401
-
402
- function learn_press_search_post_excerpt( $where = '' ) {
403
- global $wp_the_query, $wpdb;
404
-
405
- if ( empty( $wp_the_query->query_vars['s'] ) )
406
- return $where;
407
-
408
- $where = preg_replace(
409
- "/post_title\s+LIKE\s*(\'\%[^\%]+\%\')/",
410
- "post_title LIKE $1) OR ({$wpdb->posts}.post_excerpt LIKE $1", $where );
411
-
412
- return $where;
413
- }
414
-
415
- //add_filter( 'posts_where', 'learn_press_search_post_excerpt' );
416
-
417
- /**
418
- * Return true if a course is required review before submit
419
- *
420
- * @param null $course_id
421
- * @param null $user_id
422
- *
423
- * @return bool
424
- */
425
- function learn_press_course_is_required_review( $course_id = null, $user_id = null ) {
426
- if ( !$user_id ) {
427
- $user_id = get_current_user_id();
428
- }
429
- if ( !$course_id ) {
430
- global $post;
431
- $course_id = $post->ID;
432
- }
433
- if ( get_post_type( $course_id ) != 'lp_course' ) {
434
- return false;
435
- }
436
-
437
- $user = learn_press_get_user( $user_id );
438
- if ( $user->is_admin() || ( ( $user_course = learn_press_get_user( get_post_field( 'post_author', $course_id ) ) ) && $user_course->is_admin() ) ) {
439
- return false;
440
- }
441
-
442
- $required_review = LP()->settings->get( 'required_review' ) == 'yes';
443
- $enable_edit_published = LP()->settings->get( 'enable_edit_published' ) == 'yes';
444
- $is_publish = get_post_status( $course_id ) == 'publish';
445
-
446
- return !( ( !$required_review ) || ( $required_review && $enable_edit_published && $is_publish ) );
447
- }
448
-
449
- function learn_press_get_course_user( $course_id = null ) {
450
- if ( !$course_id ) {
451
- $course_id = get_the_ID();
452
- }
453
- return learn_press_get_user( get_post_field( 'post_author', $course_id ) );
454
- }
455
-
456
- /**
457
- * Get item types support in course curriculum
458
- *
459
- * @return mixed|null|void
460
- */
461
- function learn_press_course_get_support_item_types() {
462
- $types = array();
463
- if ( !empty( $GLOBALS['learn_press_course_support_item_types'] ) ) {
464
- $types = $GLOBALS['learn_press_course_support_item_types'];
465
- }
466
- return $types;
467
- }
468
-
469
- function learn_press_course_add_support_item_type() {
470
- if ( empty( $GLOBALS['learn_press_course_support_item_types'] ) ) {
471
- $GLOBALS['learn_press_course_support_item_types'] = array();
472
- }
473
- if ( func_num_args() == 1 && is_array( func_get_arg( 0 ) ) ) {
474
- foreach ( func_get_arg( 0 ) as $type => $label ) {
475
- learn_press_course_add_support_item_type( $type, $label );
476
- }
477
- } else if ( func_num_args() == 2 ) {
478
- $GLOBALS['learn_press_course_support_item_types'][func_get_arg( 0 )] = func_get_arg( 1 );
479
- }
480
- }
481
-
482
- learn_press_course_add_support_item_type(
483
- array(
484
- 'lp_lesson' => __( 'Lesson', 'learnpress' ),
485
- 'lp_quiz' => __( 'Quiz', 'learnpress' )
486
- )
487
- );
488
-
489
- function learn_press_get_course_id() {
490
- $course_id = false;
491
- if ( learn_press_is_course() ) {
492
- $course_id = get_the_ID();
493
- }
494
- return $course_id;
495
- }
496
-
497
- function learn_press_course_item() {
498
-
499
- }
500
-
501
- function learn_press_get_the_course() {
502
- static $course;
503
- if ( !$course ) {
504
- $course_id = get_the_ID();
505
- if ( get_post_type( $course ) == LP_COURSE_CPT ) {
506
- $course = LP_Course::get_course( $course_id );
507
- }
508
- }
509
- if ( !$course ) {
510
- return new LP_Course( 0 );
511
- }
512
- return $course;
513
- }
514
-
515
- function learn_press_get_user_question_answer( $args = '' ) {
516
- $args = wp_parse_args(
517
- $args,
518
- array(
519
- 'question_id' => 0,
520
- 'history_id' => 0,
521
- 'quiz_id' => 0,
522
- 'course_id' => 0,
523
- 'user_id' => get_current_user_id()
524
- )
525
- );
526
- $answered = null;
527
- if ( $args['history_id'] ) {
528
- $user_meta = learn_press_get_user_item_meta( $args['history_id'], 'question_answers', true );
529
- if ( $user_meta && array_key_exists( $args['question_id'], $user_meta ) ) {
530
- $answered = $user_meta[$args['question_id']];
531
- }
532
- } elseif ( $args['quiz_id'] && $args['course_id'] ) {
533
- $user = learn_press_get_user( $args['user_id'] );
534
- $history = $user->get_quiz_results( $args['quiz_id'], $args['course_id'] );
535
- if ( $history ) {
536
- $user_meta = learn_press_get_user_item_meta( $history->history_id, 'question_answers', true );
537
- if ( $user_meta && array_key_exists( $args['question_id'], $user_meta ) ) {
538
- $answered = $user_meta[$args['question_id']];
539
- }
540
- }
541
- }
542
- return $answered;
543
- }
544
-
545
- require_once LP_PLUGIN_PATH . "/inc/lp-init.php";
546
-
547
- function need_to_updating() {
548
- ob_start();
549
- learn_press_display_message( 'This function need to updating' );
550
- return ob_get_clean();
551
- }
552
-
553
- /* filter section item single course */
554
- function learn_press_get_course_sections() {
555
- return apply_filters( 'learn_press_get_course_sections', array(
556
- 'lp_lesson',
557
- 'lp_quiz'
558
- ) );
559
- }
560
-
561
- function lean_press_get_course_sections() {
562
- _deprecated_function( __FUNCTION__, '2.1', 'learn_press_get_course_sections' );
563
- return learn_press_get_course_sections();
564
- }
565
-
566
- if ( !function_exists( 'learn_press_get_course_item_url' ) ) {
567
- function learn_press_get_course_item_url( $course_id = null, $item_id = null ) {
568
- $course = learn_press_get_course( $course_id );
569
- return $course->get_item_link( $item_id );
570
- }
571
- }
572
-
573
- if ( !function_exists( 'learn_press_get_sample_link_course_item_url' ) ) {
574
-
575
- function learn_press_get_sample_link_course_item_url( $item_id = null) {
576
-
577
- if ( !$item_id ) {
578
- return;
579
- }
580
-
581
- $permalink = get_the_permalink( $item_id );
582
- $course_page_id = get_option( 'learn_press_courses_page_id' );
583
-
584
- if ( !empty($course_page_id) && get_post( $course_page_id ) != false ) {
585
-
586
- $post_types = get_post_types( null, 'objects' );
587
- $item_type = get_post_type( $item_id );
588
- $permalink = trailingslashit( get_the_permalink( $course_page_id ) );
589
- $course_slug = basename( $permalink );
590
- $permalink = str_replace( $course_slug, 'course/sample-course', $permalink );
591
- $post_name = get_post_field( 'post_name', $item_id );
592
- $prefix = preg_replace( '!^/!', '', trailingslashit( $post_types[$item_type]->rewrite['slug'] ) );
593
-
594
- if ( '' != get_option( 'permalink_structure' ) && get_post_status( $course_page_id ) != 'draft' ) {
595
- $permalink .= $prefix . $post_name;
596
- }
597
- else {
598
- $key = preg_replace( '!lp_!', '', get_post_type( $item_id ) );
599
- $permalink = add_query_arg( array( $key => $post_name ), $permalink );
600
- }
601
- }
602
- return $permalink;
603
-
604
- }
605
- }
606
-
607
- if ( !function_exists( 'learn_press_get_nav_course_item_url' ) ) {
608
- function learn_press_get_nav_course_item_url( $course_id = null, $item_id = null, $content_only = false ) {
609
- $course = learn_press_get_course( $course_id );
610
- $curriculum_items = maybe_unserialize( $course->post->curriculum_items );
611
- $index = array_search( $item_id, $curriculum_items );
612
- $return = array( 'back' => '', 'next' => '' );
613
- if ( is_array( $curriculum_items ) ) {
614
- if ( array_key_exists( $index - 1, $curriculum_items ) ) {
615
- $back_item = get_post( $curriculum_items[$index - 1] );
616
- $return['back'] = array(
617
- 'id' => $back_item->ID,
618
- 'link' => $course->get_item_link( $curriculum_items[$index - 1] ),
619
- 'title' => $back_item->post_title,
620
- );
621
- if ( $content_only ) {
622
- $return['back']['link'] .= '?content-item-only=yes';
623
- }
624
- }
625
- if ( array_key_exists( $index + 1, $curriculum_items ) ) {
626
- $next_item = get_post( $curriculum_items[$index + 1] );
627
- $return['next'] = array(
628
- 'id' => $next_item->ID,
629
- 'link' => $course->get_item_link( $curriculum_items[$index + 1] ),
630
- 'title' => $next_item->post_title,
631
- );
632
- if ( $content_only ) {
633
- $return['next']['link'] .= '?content-item-only=yes';
634
- }
635
- }
636
- }
637
- return $return;
638
- }
639
- }
640
-
641
- if ( !function_exists( 'learn_press_get_nav_course_item' ) ) {
642
- function learn_press_get_nav_course_item( $course_id = null, $item_id = null, $content_only = false ) {
643
- $nav = learn_press_get_nav_course_item_url( $course_id, $item_id, $content_only );
644
- $nav_html = '
645
- <nav id="lp-navigation" class="navigation post-navigation" role="navigation">
646
- <h2 class="screen-reader-text">' . __( 'Course item navigation', 'learnpress' ) . '</h2>
647
- <div class="nav-links">';
648
- if ( isset( $nav['back']['link'] ) ) {
649
- $nav_html .=
650
- '<div class="nav-previous nav-link">
651
- <a class="course-item-title button-load-item js-action" data-id="' . esc_attr( $nav['back']['id'] ) . '" '
652
- . 'href="' . esc_attr( $nav['back']['link'] ) . '" rel="prev">'
653
- . '<span class="meta-nav" aria-hidden="true">' . __( 'Previous', 'learnpress' ) . '</span> <span class="screen-reader-text">' . __( 'Previous post:', 'learnpress' ) . '</span> <span class="post-title">' . $nav['back']['title'] . '</span></a>
654
- </div>';
655
- }
656
- if ( isset( $nav['next']['link'] ) ) {
657
- $nav_html .=
658
- '<div class="nav-next nav-link">
659
- <a class="course-item-title button-load-item js-action" data-id="' . esc_attr( $nav['next']['id'] ) . '" '
660
- . 'href="' . esc_attr( $nav['next']['link'] ) . '" rel="next">'
661
- . '<span class="meta-nav" aria-hidden="true">' . __( 'Next', 'learnpress' ) . '</span> <span class="screen-reader-text">' . __( 'Next post:', 'learnpress' ) . '</span> <span class="post-title">' . $nav['next']['title'] . '</span></a>
662
- </div>
663
- ';
664
- }
665
- $nav_html .= '
666
- </div>
667
- </nav>
668
- ';
669
- echo $nav_html;
670
- }
671
- }
672
- /**
673
- * Update url lesson & quiz in admin page
674
- */
675
-
676
- if ( !function_exists( 'learn_press_get_item_course_id' ) ) {
677
-
678
- function learn_press_get_item_course_id( $post_id , $post_type ) {
679
-
680
- global $wpdb;
681
-
682
- /**
683
- * Get Course id by Quiz post_id
684
- *
685
- * @global type $wpdb
686
- *
687
- * @param type $post_id
688
- *
689
- * @return $course_id
690
- */
691
- if ( $post_type == LP_QUIZ_CPT ) {
692
- $query = $wpdb->prepare( "SELECT section.section_course_id FROM {$wpdb->learnpress_sections} AS section"
693
- . " INNER JOIN {$wpdb->learnpress_section_items} AS item ON item.section_id = section.section_id"
694
- . " INNER JOIN {$wpdb->posts} AS course ON course.ID = section.section_course_id"
695
- . " WHERE course.post_type = %s"
696
- . " AND course.post_status = %s"
697
- . " AND item.item_type = %s"
698
- . " AND item.item_id = %d"
699
- . " LIMIT 1", LP_COURSE_CPT, 'publish', LP_QUIZ_CPT, $post_id );
700
-
701
- return apply_filters( 'learn_press_get_quiz_course_id', absint( $wpdb->get_var( $query ) ), $post_id );
702
- }
703
-
704
- /**
705
- * Get Course id by Lesson post_id
706
- *
707
- * @global type $wpdb
708
- *
709
- * @param type $post_id
710
- *
711
- * @return $course_id
712
- */
713
-
714
- if ( $post_type == LP_LESSON_CPT ) {
715
-
716
- $query = $wpdb->prepare( "SELECT section.section_course_id FROM {$wpdb->learnpress_sections} AS section"
717
- . " INNER JOIN {$wpdb->learnpress_section_items} AS item ON item.section_id = section.section_id"
718
- . " INNER JOIN {$wpdb->posts} AS course ON course.ID = section.section_course_id"
719
- . " WHERE course.post_type = %s"
720
- . " AND course.post_status = %s"
721
- . " AND item.item_type = %s"
722
- . " AND item.item_id = %d"
723
- . " LIMIT 1", LP_COURSE_CPT, 'publish', LP_LESSON_CPT, $post_id );
724
-
725
- return apply_filters( 'learn_press_get_lesson_course_id', absint( $wpdb->get_var( $query ) ), $post_id );
726
-
727
- }
728
-
729
- }
730
- }
731
-
732
- add_filter('get_sample_permalink', 'learn_press_item_sample_permalink', 10, 5);
733
-
734
- if ( !function_exists( 'learn_press_item_sample_permalink' ) ) {
735
-
736
- function learn_press_item_sample_permalink( $permalink, $post_id, $title, $name, $post ){
737
-
738
- if ( $post->post_type !== LP_QUIZ_CPT && $post->post_type !== LP_LESSON_CPT) {
739
- return $permalink;
740
- }
741
-
742
- $permalink = str_replace( '/' .$post->post_name, '/%pagename%' , $permalink );
743
- return $permalink;
744
- }
745
-
746
- }
747
-
748
- add_filter( 'post_type_link', 'learn_press_quiz_permalink', 10, 2 );
749
-
750
- if ( !function_exists( 'learn_press_quiz_permalink' ) ) {
751
-
752
- function learn_press_quiz_permalink( $permalink, $post ) {
753
-
754
- if( !empty(LP()->global['item_permalinks'][$post->ID])){
755
- return LP()->global['item_permalinks'][$post->ID];
756
- }
757
- remove_filter( 'post_type_link', 'learn_press_quiz_permalink', 10);
758
-
759
- if ( $post->post_type !== LP_QUIZ_CPT && $post->post_type !== LP_LESSON_CPT) {
760
- return $permalink;
761
- }
762
-
763
- $course_id = learn_press_get_item_course_id( $post->ID, $post->post_type );
764
- if ( $course_id ) {
765
- $permalink = learn_press_get_course_item_url( $course_id, $post->ID );
766
- }
767
- else {
768
-
769
- $permalink = learn_press_get_sample_link_course_item_url( $post->ID );
770
- }
771
- LP()->global['item_permalinks'][$post->ID] = $permalink;
772
- add_filter( 'post_type_link', 'learn_press_quiz_permalink', 10, 2 );
773
- return $permalink;
774
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
775
  }
1
+ <?php
2
+ /**
3
+ * Common functions to manipulate with course, lesson, quiz, questions, etc...
4
+ *
5
+ * @author ThimPress
6
+ * @package LearnPress/Functions
7
+ * @version 1.0
8
+ */
9
+
10
+ if ( !defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly
12
+ }
13
+
14
+ /**
15
+ * @param $the_course
16
+ *
17
+ * @return LP_Course|mixed
18
+ */
19
+ function learn_press_get_course( $the_course = false ) {
20
+ return $the_course ? LP_Course::get_course( $the_course ) : LP()->global['course'];
21
+ }
22
+
23
+ function learn_press_get_quiz( $the_quiz ) {
24
+ return LP_Quiz::get_quiz( $the_quiz );
25
+ }
26
+
27
+ /**
28
+ * print out class for quiz body
29
+ *
30
+ * @param null $class
31
+ *
32
+ * @return bool
33
+ */
34
+ function learn_press_quiz_class( $class = null ) {
35
+ $item = LP()->global['course-item'];
36
+ $user = LP()->user;
37
+
38
+ if ( !$item ) {
39
+ return false;
40
+ }
41
+
42
+ $quiz = LP_Quiz::get_quiz( $item->ID );
43
+
44
+ if ( $class && is_string( $class ) ) {
45
+ $class = explode( ' ', $class );
46
+ } elseif ( !$class ) {
47
+ $class = array();
48
+ }
49
+
50
+ $class[] = "single-quiz";
51
+
52
+ if ( $status = $user->get_quiz_status( $quiz->id ) ) {
53
+ $class[] = 'quiz-' . $status;
54
+ }
55
+
56
+ if ( $quiz->has( 'questions' ) ) {
57
+ $class[] = 'has-questions';
58
+ }
59
+
60
+ $class[] = 'clearfix';
61
+
62
+ $class = array_unique( $class );
63
+
64
+ post_class( join( ' ', $class ) );
65
+ }
66
+
67
+ /**
68
+ * Get the courses that a item is assigned to
69
+ *
70
+ * @param $item
71
+ *
72
+ * @return mixed
73
+ */
74
+ function learn_press_get_item_courses( $item ) {
75
+ global $wpdb;
76
+ $query = $wpdb->prepare( "
77
+ SELECT c.*
78
+ FROM {$wpdb->posts} c
79
+ INNER JOIN {$wpdb->learnpress_sections} s ON c.ID = s.section_course_id
80
+ INNER JOIN {$wpdb->learnpress_section_items} si ON si.section_id = s.section_id
81
+ WHERE si.item_id = %d
82
+ ", $item );
83
+ return $wpdb->get_results( $query );
84
+ }
85
+
86
+ /**
87
+ * Get the quizzes that a question is assigned to
88
+ *
89
+ * @param $question_id
90
+ *
91
+ * @return mixed
92
+ */
93
+ function learn_press_get_question_quizzes( $question_id ) {
94
+ global $wpdb;
95
+ $query = $wpdb->prepare( "
96
+ SELECT q.*
97
+ FROM {$wpdb->posts} q
98
+ INNER JOIN {$wpdb->prefix}learnpress_quiz_questions qq ON q.ID = qq.quiz_id
99
+ WHERE qq.question_id = %d
100
+ ", $question_id );
101
+ return $wpdb->get_results( $query );
102
+ }
103
+
104
+ function _learn_press_usort_terms_by_ID( $terms ) {
105
+ $version = get_bloginfo('version');
106
+ if( version_compare ($version, '4.7', '>=') ){
107
+ $terms = wp_list_sort($terms, 'term_id');
108
+ }else{
109
+ usort( $terms, '_usort_terms_by_ID' );
110
+ }
111
+ return $terms;
112
+ }
113
+
114
+ function learn_press_course_post_type_link( $permalink, $post ) {
115
+ if ( $post->post_type !== 'lp_course' ) {
116
+ return $permalink;
117
+ }
118
+
119
+ // Abort early if the placeholder rewrite tag isn't in the generated URL
120
+ if ( false === strpos( $permalink, '%' ) ) {
121
+ return $permalink;
122
+ }
123
+
124
+ // Get the custom taxonomy terms in use by this post
125
+ $terms = get_the_terms( $post->ID, 'course_category' );
126
+
127
+ if ( !empty( $terms ) ) {
128
+ $terms = _learn_press_usort_terms_by_ID( $terms ); // order by ID
129
+ $category_object = apply_filters( 'learn_press_course_post_type_link_course_category', $terms[0], $terms, $post );
130
+ $category_object = get_term( $category_object, 'course_category' );
131
+ $course_category = $category_object->slug;
132
+
133
+ if ( $parent = $category_object->parent ) {
134
+ $ancestors = get_ancestors( $category_object->term_id, 'course_category' );
135
+ foreach ( $ancestors as $ancestor ) {
136
+ $ancestor_object = get_term( $ancestor, 'course_category' );
137
+ $course_category = $ancestor_object->slug . '/' . $course_category;
138
+ }
139
+ }
140
+ } else {
141
+ // If no terms are assigned to this post, use a string instead (can't leave the placeholder there)
142
+ $course_category = _x( 'uncategorized', 'slug', 'learnpress' );
143
+ }
144
+
145
+ $find = array(
146
+ '%year%',
147
+ '%monthnum%',
148
+ '%day%',
149
+ '%hour%',
150
+ '%minute%',
151
+ '%second%',
152
+ '%post_id%',
153
+ '%category%',
154
+ '%course_category%'
155
+ );
156
+
157
+ $replace = array(
158
+ date_i18n( 'Y', strtotime( $post->post_date ) ),
159
+ date_i18n( 'm', strtotime( $post->post_date ) ),
160
+ date_i18n( 'd', strtotime( $post->post_date ) ),
161
+ date_i18n( 'H', strtotime( $post->post_date ) ),
162
+ date_i18n( 'i', strtotime( $post->post_date ) ),
163
+ date_i18n( 's', strtotime( $post->post_date ) ),
164
+ $post->ID,
165
+ $course_category,
166
+ $course_category
167
+ );
168
+
169
+ $permalink = str_replace( $find, $replace, $permalink );
170
+
171
+ return $permalink;
172
+ }
173
+
174
+ add_filter( 'post_type_link', 'learn_press_course_post_type_link', 10, 2 );
175
+
176
+ /**
177
+ * Get the final quiz for a course if it is existing
178
+ *
179
+ * @param $course_id
180
+ *
181
+ * @return mixed
182
+ * @throws Exception
183
+ */
184
+ function learn_press_get_final_quiz( $course_id ) {
185
+ $course = LP_Course::get_course( $course_id );
186
+ if ( !$course ) {
187
+ throw new Exception( sprintf( __( 'The course %d does not exists', 'learnpress' ), $course_id ) );
188
+ }
189
+ $course_items = $course->get_curriculum_items();
190
+ $final = false;
191
+ if ( $course_items ) {
192
+ $end = end( $course_items );
193
+ if ( $end->post_type == LP_QUIZ_CPT ) {
194
+ $final = $end->ID;
195
+ }
196
+ }
197
+ return apply_filters( 'learn_press_course_final_quiz', $final, $course_id );
198
+ }
199
+
200
+ function learn_press_item_meta_format( $item, $nonce = '' ) {
201
+ if ( current_theme_supports( 'post-formats' ) ) {
202
+ $format = get_post_format( $item );
203
+ if ( false === $format ) {
204
+ $format = 'standard';
205
+ }
206
+
207
+ //return false to hide post format
208
+ if ( $format = apply_filters( 'learn_press_course_item_format', $format, $item ) ) {
209
+ //printf( '<span class="lp-label lp-label-format lp-label-format-%s">%s</span>', $format, ucfirst( $format ) );
210
+ printf( '<label for="post-format-0" class="post-format-icon post-format-%s" title="%s"></label>', $format, ucfirst( $format ) );
211
+ } else {
212
+ echo $nonce;
213
+ }
214
+ }
215
+ }
216
+
217
+ function learn_press_course_item_format_exclude( $format, $item ) {
218
+ if ( get_post_type( $item ) != LP_LESSON_CPT || ( $format == 'standard' ) ) {
219
+ $format = false;
220
+ }
221
+ return $format;
222
+ }
223
+
224
+ //add_filter( 'learn_press_course_item_format', 'learn_press_course_item_format_exclude', 5, 2 );
225
+ /*******************************************************/
226
+ /*******************************************************/
227
+
228
+ /**
229
+ * Get curriculum of a course
230
+ *
231
+ * @version 1.0
232
+ *
233
+ * @param $course_id
234
+ *
235
+ * @return mixed
236
+ */
237
+ function learn_press_get_course_curriculum( $course_id ) {
238
+ $course = LP_Course::get_course( $course_id );
239
+ return $course->get_curriculum();
240
+ }
241
+
242
+ /**
243
+ * Verify course access
244
+ *
245
+ * @param int $course_id
246
+ * @param int $user_id
247
+ *
248
+ * @return boolean
249
+ */
250
+ function learn_press_is_enrolled_course( $course_id = null, $user_id = null ) {
251
+ //_deprecated_function( __FUNCTION__, '1.0', 'LP_User -> has_enrolled_course');
252
+ if ( $course = LP_Course::get_course( $course_id ) && $user = learn_press_get_user( $user_id ) ) {
253
+ return $user->has_enrolled_course( $course_id );
254
+ }
255
+ return false;
256
+ }
257
+
258
+ /**
259
+ * Detect if a course is free or not
260
+ *
261
+ * @param null $course_id
262
+ *
263
+ * @return bool
264
+ */
265
+ function learn_press_is_free_course( $course_id = null ) {
266
+ if ( !$course_id ) {
267
+ $course_id = get_the_ID();
268
+ }
269
+ return learn_press_get_course( $course_id )->is_free();
270
+ }
271
+
272
+ /**
273
+ * get current status of user's course
274
+ *
275
+ * @author Tunn
276
+ *
277
+ * @param int $user_id
278
+ * @param int $course_id
279
+ *
280
+ * @return string
281
+ */
282
+ function learn_press_get_user_course_status( $user_id = null, $course_id = null ) {
283
+ //_deprecated_function( __FUNCTION__, '1.0', 'LP_User() -> get_course_status');
284
+ if ( $course = LP_Course::get_course( $course_id ) && $user = learn_press_get_user( $user_id ) ) {
285
+ return $user->get_course_status( $course_id );
286
+ }
287
+ return false;
288
+ }
289
+
290
+
291
+ /**
292
+ * Check to see if user can view a lesson or not
293
+ *
294
+ * @since 0.9.5
295
+ *
296
+ * @param int $lesson_id
297
+ * @param int $course_id
298
+ * @param int $user_id
299
+ *
300
+ * @return boolean
301
+ */
302
+ function learn_press_user_can_view_lesson( $lesson_id, $course_id = 0, $user_id = null ) {
303
+ if ( $user_id ) {
304
+ $user = learn_press_get_user( $user_id );
305
+ } else {
306
+ $user = LP()->user;
307
+ }
308
+ return $user ? $user->can( 'view-lesson', $lesson_id, $course_id ) : false;
309
+ }
310
+
311
+ /**
312
+ * Check to see if user can view a quiz or not
313
+ *
314
+ * @param int $quiz_id
315
+ * @param int $course_id
316
+ * @param int $user_id
317
+ *
318
+ * @return boolean
319
+ */
320
+ function learn_press_user_can_view_quiz( $quiz_id = null, $course_id = 0, $user_id = null ) {
321
+ if ( $user_id ) {
322
+ $user = learn_press_get_user( $user_id );
323
+ } else {
324
+ $user = LP()->user;
325
+ }
326
+ return $user ? $user->can( 'view-quiz', $quiz_id, $course_id ) : false;
327
+ }
328
+
329
+ /**
330
+ * Get course setting is enroll required or public
331
+ *
332
+ * @since 0.9.5
333
+ *
334
+ * @param int $course_id
335
+ *
336
+ * @return boolean
337
+ */
338
+ function learn_press_course_enroll_required( $course_id = null ) {
339
+ $course_id = learn_press_get_course_id( $course_id );
340
+
341
+ $required = ( 'yes' == get_post_meta( $course_id, '_lpr_course_enrolled_require', true ) );
342
+ return apply_filters( 'learn_press_course_enroll_required', $required, $course_id );
343
+ }
344
+
345
+ /**
346
+ * Checks to see that an user has finished a lesson or not yet
347
+ * Function return the ID of a course if the user has completed a lesson
348
+ * Otherwise, return false
349
+ *
350
+ * @author TuNguyen
351
+ *
352
+ * @param null $lesson_id
353
+ * @param null $user_id
354
+ *
355
+ * @return mixed
356
+ */
357
+ function learn_press_user_has_completed_lesson( $lesson_id = null, $user_id = null ) {
358
+
359
+ _deprecated_function( __FUNCTION__, '1.0', 'LP_User() -> has_completed_quiz' );
360
+ if ( $user = learn_press_get_user( $user_id ) ) {
361
+ return $user->has_completed_quiz( $lesson_id );
362
+ }
363
+ return false;
364
+
365
+ $lesson_id = learn_press_get_lesson_id( $lesson_id );
366
+ if ( !$user_id ) $user_id = get_current_user_id();
367
+
368
+ $completed_lessons = get_user_meta( $user_id, '_lpr_lesson_completed', true );
369
+
370
+ if ( !$completed_lessons ) return false;
371
+ foreach ( $completed_lessons as $courses ) {
372
+ if ( is_array( $courses ) && in_array( $lesson_id, $courses ) ) {
373
+ return true;
374
+ }
375
+ }
376
+ return false;
377
+ }
378
+
379
+ /**
380
+ * Short function to check if a lesson id is not passed to a function
381
+ * then try to get it from $_REQUEST
382
+ *
383
+ * @param null $lesson_id
384
+ *
385
+ * @return int|null
386
+ */
387
+ function learn_press_get_lesson_id( $lesson_id = null ) {
388
+ if ( !$lesson_id ) {
389
+ $lesson_id = !empty( $_REQUEST['lesson'] ) ? $_REQUEST['lesson'] : 0;
390
+ }
391
+ return $lesson_id;
392
+ }
393
+
394
+ function learn_press_get_all_courses( $args = array() ) {
395
+ $term = '';
396
+ $exclude = '';
397
+ is_array( $args ) && extract( $args );
398
+ $args = array(
399
+ 'post_type' => array( 'lp_course' ),
400
+ 'post_status' => 'publish',
401
+ 'posts_per_page' => - 1,
402
+ 's' => $term,
403
+ 'fields' => 'ids',
404
+ 'exclude' => $exclude
405
+ );
406
+ $args = apply_filters( 'learn_press_get_courses_args', $args );
407
+ $posts = get_posts( $args );
408
+ return apply_filters( 'learn_press_get_courses', $posts, $args );
409
+ }
410
+
411
+ function learn_press_search_post_excerpt( $where = '' ) {
412
+ global $wp_the_query, $wpdb;
413
+
414
+ if ( empty( $wp_the_query->query_vars['s'] ) )
415
+ return $where;
416
+
417
+ $where = preg_replace(
418
+ "/post_title\s+LIKE\s*(\'\%[^\%]+\%\')/",
419
+ "post_title LIKE $1) OR ({$wpdb->posts}.post_excerpt LIKE $1", $where );
420
+
421
+ return $where;
422
+ }
423
+
424
+ //add_filter( 'posts_where', 'learn_press_search_post_excerpt' );
425
+
426
+ /**
427
+ * Return true if a course is required review before submit
428
+ *
429
+ * @param null $course_id
430
+ * @param null $user_id
431
+ *
432
+ * @return bool
433
+ */
434
+ function learn_press_course_is_required_review( $course_id = null, $user_id = null ) {
435
+ if ( !$user_id ) {
436
+ $user_id = get_current_user_id();
437
+ }
438
+ if ( !$course_id ) {
439
+ global $post;
440
+ $course_id = $post->ID;
441
+ }
442
+ if ( get_post_type( $course_id ) != 'lp_course' ) {
443
+ return false;
444
+ }
445
+
446
+ $user = learn_press_get_user( $user_id );
447
+ if ( $user->is_admin() || ( ( $user_course = learn_press_get_user( get_post_field( 'post_author', $course_id ) ) ) && $user_course->is_admin() ) ) {
448
+ return false;
449
+ }
450
+
451
+ $required_review = LP()->settings->get( 'required_review' ) == 'yes';
452
+ $enable_edit_published = LP()->settings->get( 'enable_edit_published' ) == 'yes';
453
+ $is_publish = get_post_status( $course_id ) == 'publish';
454
+
455
+ return !( ( !$required_review ) || ( $required_review && $enable_edit_published && $is_publish ) );
456
+ }
457
+
458
+ function learn_press_get_course_user( $course_id = null ) {
459
+ if ( !$course_id ) {
460
+ $course_id = get_the_ID();
461
+ }
462
+ return learn_press_get_user( get_post_field( 'post_author', $course_id ) );
463
+ }
464
+
465
+ /**
466
+ * Get item types support in course curriculum
467
+ *
468
+ * @return mixed|null|void
469
+ */
470
+ function learn_press_course_get_support_item_types() {
471
+ $types = array();
472
+ if ( !empty( $GLOBALS['learn_press_course_support_item_types'] ) ) {
473
+ $types = $GLOBALS['learn_press_course_support_item_types'];
474
+ }
475
+ return $types;
476
+ }
477
+
478
+ function learn_press_course_add_support_item_type() {
479
+ if ( empty( $GLOBALS['learn_press_course_support_item_types'] ) ) {
480
+ $GLOBALS['learn_press_course_support_item_types'] = array();
481
+ }
482
+ if ( func_num_args() == 1 && is_array( func_get_arg( 0 ) ) ) {
483
+ foreach ( func_get_arg( 0 ) as $type => $label ) {
484
+ learn_press_course_add_support_item_type( $type, $label );
485
+ }
486
+ } else if ( func_num_args() == 2 ) {
487
+ $GLOBALS['learn_press_course_support_item_types'][func_get_arg( 0 )] = func_get_arg( 1 );
488
+ }
489
+ }
490
+
491
+ learn_press_course_add_support_item_type(
492
+ array(
493
+ 'lp_lesson' => __( 'Lesson', 'learnpress' ),
494
+ 'lp_quiz' => __( 'Quiz', 'learnpress' )
495
+ )
496
+ );
497
+
498
+ function learn_press_get_course_id() {
499
+ $course_id = false;
500
+ if ( learn_press_is_course() ) {
501
+ $course_id = get_the_ID();
502
+ }
503
+ return $course_id;
504
+ }
505
+
506
+ function learn_press_course_item() {
507
+
508
+ }
509
+
510
+ function learn_press_get_the_course() {
511
+ static $course;
512
+ if ( !$course ) {
513
+ $course_id = get_the_ID();
514
+ if ( get_post_type( $course ) == LP_COURSE_CPT ) {
515
+ $course = LP_Course::get_course( $course_id );
516
+ }
517
+ }
518
+ if ( !$course ) {
519
+ return new LP_Course( 0 );
520
+ }
521
+ return $course;
522
+ }
523
+
524
+ function learn_press_get_user_question_answer( $args = '' ) {
525
+ $args = wp_parse_args(
526
+ $args,
527
+ array(
528
+ 'question_id' => 0,
529
+ 'history_id' => 0,
530
+ 'quiz_id' => 0,
531
+ 'course_id' => 0,
532
+ 'user_id' => get_current_user_id()
533
+ )
534
+ );
535
+ $answered = null;
536
+ if ( $args['history_id'] ) {
537
+ $user_meta = learn_press_get_user_item_meta( $args['history_id'], 'question_answers', true );
538
+ if ( $user_meta && array_key_exists( $args['question_id'], $user_meta ) ) {
539
+ $answered = $user_meta[$args['question_id']];
540
+ }
541
+ } elseif ( $args['quiz_id'] && $args['course_id'] ) {
542
+ $user = learn_press_get_user( $args['user_id'] );
543
+ $history = $user->get_quiz_results( $args['quiz_id'], $args['course_id'] );
544
+ if ( $history ) {
545
+ $user_meta = learn_press_get_user_item_meta( $history->history_id, 'question_answers', true );
546
+ if ( $user_meta && array_key_exists( $args['question_id'], $user_meta ) ) {
547
+ $answered = $user_meta[$args['question_id']];
548
+ }
549
+ }
550
+ }
551
+ return $answered;
552
+ }
553
+
554
+ require_once LP_PLUGIN_PATH . "/inc/lp-init.php";
555
+
556
+ function need_to_updating() {
557
+ ob_start();
558
+ learn_press_display_message( 'This function need to updating' );
559
+ return ob_get_clean();
560
+ }
561
+
562
+ /* filter section item single course */
563
+ function learn_press_get_course_sections() {
564
+ return apply_filters( 'learn_press_get_course_sections', array(
565
+ 'lp_lesson',
566
+ 'lp_quiz'
567
+ ) );
568
+ }
569
+
570
+ function lean_press_get_course_sections() {
571
+ _deprecated_function( __FUNCTION__, '2.1', 'learn_press_get_course_sections' );
572
+ return learn_press_get_course_sections();
573
+ }
574
+
575
+ if ( !function_exists( 'learn_press_get_course_item_url' ) ) {
576
+ function learn_press_get_course_item_url( $course_id = null, $item_id = null ) {
577
+ $course = learn_press_get_course( $course_id );
578
+ return $course->get_item_link( $item_id );
579
+ }
580
+ }
581
+
582
+ if ( !function_exists( 'learn_press_get_sample_link_course_item_url' ) ) {
583
+
584
+ function learn_press_get_sample_link_course_item_url( $item_id = null) {
585
+
586
+ if ( !$item_id ) {
587
+ return;
588
+ }
589
+
590
+ $permalink = get_the_permalink( $item_id );
591
+ $course_page_id = get_option( 'learn_press_courses_page_id' );
592
+
593
+ if ( !empty($course_page_id) && get_post( $course_page_id ) != false ) {
594
+
595
+ $post_types = get_post_types( null, 'objects' );
596
+ $item_type = get_post_type( $item_id );
597
+ $permalink = trailingslashit( get_the_permalink( $course_page_id ) );
598
+ $course_slug = basename( $permalink );
599
+ $permalink = str_replace( $course_slug, 'course/sample-course', $permalink );
600
+ $post_name = get_post_field( 'post_name', $item_id );
601
+ $prefix = preg_replace( '!^/!', '', trailingslashit( $post_types[$item_type]->rewrite['slug'] ) );
602
+
603
+ if ( '' != get_option( 'permalink_structure' ) && get_post_status( $course_page_id ) != 'draft' ) {
604
+
605
+ // $permalink .= $prefix . $post_name;
606
+ $permalink = $post_name;
607
+
608
+ }
609
+ else {
610
+ $key = preg_replace( '!lp_!', '', get_post_type( $item_id ) );
611
+ $permalink = add_query_arg( array( $key => $post_name ), $permalink );
612
+ }
613
+ }
614
+ return $permalink;
615
+
616
+ }
617
+ }
618
+
619
+ if ( !function_exists( 'learn_press_get_nav_course_item_url' ) ) {
620
+ function learn_press_get_nav_course_item_url( $course_id = null, $item_id = null, $content_only = false ) {
621
+ $course = learn_press_get_course( $course_id );
622
+ $curriculum_items = maybe_unserialize( $course->post->curriculum_items );
623
+ $index = array_search( $item_id, $curriculum_items );
624
+ $return = array( 'back' => '', 'next' => '' );
625
+ if ( is_array( $curriculum_items ) ) {
626
+ if ( array_key_exists( $index - 1, $curriculum_items ) ) {
627
+ $back_item = get_post( $curriculum_items[$index - 1] );
628
+ $return['back'] = array(
629
+ 'id' => $back_item->ID,
630
+ 'link' => $course->get_item_link( $curriculum_items[$index - 1] ),
631
+ 'title' => $back_item->post_title,
632
+ );
633
+ if ( $content_only ) {
634
+ $return['back']['link'] .= '?content-item-only=yes';
635
+ }
636
+ }
637
+ if ( array_key_exists( $index + 1, $curriculum_items ) ) {
638
+ $next_item = get_post( $curriculum_items[$index + 1] );
639
+ $return['next'] = array(
640
+ 'id' => $next_item->ID,
641
+ 'link' => $course->get_item_link( $curriculum_items[$index + 1] ),
642
+ 'title' => $next_item->post_title,
643
+ );
644
+ if ( $content_only ) {
645
+ $return['next']['link'] .= '?content-item-only=yes';
646
+ }
647
+ }
648
+ }
649
+ return $return;
650
+ }
651
+ }
652
+
653
+ if ( !function_exists( 'learn_press_get_nav_course_item' ) ) {
654
+ function learn_press_get_nav_course_item( $course_id = null, $item_id = null, $content_only = false ) {
655
+ $nav = learn_press_get_nav_course_item_url( $course_id, $item_id, $content_only );
656
+ $nav_html = '
657
+ <nav id="lp-navigation" class="navigation post-navigation" role="navigation">
658
+ <h2 class="screen-reader-text">' . __( 'Course item navigation', 'learnpress' ) . '</h2>
659
+ <div class="nav-links">';
660
+ if ( isset( $nav['back']['link'] ) ) {
661
+ $nav_html .=
662
+ '<div class="nav-previous nav-link">
663
+ <a class="course-item-title button-load-item js-action" data-id="' . esc_attr( $nav['back']['id'] ) . '" '
664
+ . 'href="' . esc_attr( $nav['back']['link'] ) . '" rel="prev">'
665
+ . '<span class="meta-nav" aria-hidden="true">' . __( 'Previous', 'learnpress' ) . '</span> <span class="screen-reader-text">' . __( 'Previous post:', 'learnpress' ) . '</span> <span class="post-title">' . $nav['back']['title'] . '</span></a>
666
+ </div>';
667
+ }
668
+ if ( isset( $nav['next']['link'] ) ) {
669
+ $nav_html .=
670
+ '<div class="nav-next nav-link">
671
+ <a class="course-item-title button-load-item js-action" data-id="' . esc_attr( $nav['next']['id'] ) . '" '
672
+ . 'href="' . esc_attr( $nav['next']['link'] ) . '" rel="next">'
673
+ . '<span class="meta-nav" aria-hidden="true">' . __( 'Next', 'learnpress' ) . '</span> <span class="screen-reader-text">' . __( 'Next post:', 'learnpress' ) . '</span> <span class="post-title">' . $nav['next']['title'] . '</span></a>
674
+ </div>
675
+ ';
676
+ }
677
+ $nav_html .= '
678
+ </div>
679
+ </nav>
680
+ ';
681
+ echo $nav_html;
682
+ }
683
+ }
684
+ /**
685
+ * Update url lesson & quiz in admin page
686
+ */
687
+
688
+ if ( !function_exists( 'learn_press_get_item_course_id' ) ) {
689
+
690
+ function learn_press_get_item_course_id( $post_id , $post_type ) {
691
+
692
+ global $wpdb;
693
+
694
+ /**
695
+ * Get Course id by Quiz post_id
696
+ *
697
+ * @global type $wpdb
698
+ *
699
+ * @param type $post_id
700
+ *
701
+ * @return $course_id
702
+ */
703
+ if ( $post_type == LP_QUIZ_CPT ) {
704
+ $query = $wpdb->prepare( "SELECT section.section_course_id FROM {$wpdb->learnpress_sections} AS section"
705
+ . " INNER JOIN {$wpdb->learnpress_section_items} AS item ON item.section_id = section.section_id"
706
+ . " INNER JOIN {$wpdb->posts} AS course ON course.ID = section.section_course_id"
707
+ . " WHERE course.post_type = %s"
708
+ . " AND course.post_status = %s"
709
+ . " AND item.item_type = %s"
710
+ . " AND item.item_id = %d"
711
+ . " LIMIT 1", LP_COURSE_CPT, 'publish', LP_QUIZ_CPT, $post_id );
712
+
713
+ return apply_filters( 'learn_press_get_quiz_course_id', absint( $wpdb->get_var( $query ) ), $post_id );
714
+ }
715
+
716
+ /**
717
+ * Get Course id by Lesson post_id
718
+ *
719
+ * @global type $wpdb
720
+ *
721
+ * @param type $post_id
722
+ *
723
+ * @return $course_id
724
+ */
725
+
726
+ if ( $post_type == LP_LESSON_CPT ) {
727
+
728
+ $query = $wpdb->prepare( "SELECT section.section_course_id FROM {$wpdb->learnpress_sections} AS section"
729
+ . " INNER JOIN {$wpdb->learnpress_section_items} AS item ON item.section_id = section.section_id"
730
+ . " INNER JOIN {$wpdb->posts} AS course ON course.ID = section.section_course_id"
731
+ . " WHERE course.post_type = %s"
732
+ . " AND course.post_status = %s"
733
+ . " AND item.item_type = %s"
734
+ . " AND item.item_id = %d"
735
+ . " LIMIT 1", LP_COURSE_CPT, 'publish', LP_LESSON_CPT, $post_id );
736
+
737
+ return apply_filters( 'learn_press_get_lesson_course_id', absint( $wpdb->get_var( $query ) ), $post_id );
738
+
739
+ }
740
+
741
+ }
742
+ }
743
+
744
+ add_filter('get_sample_permalink', 'learn_press_item_sample_permalink', 10, 5);
745
+
746
+ if ( !function_exists( 'learn_press_item_sample_permalink' ) ) {
747
+
748
+ function learn_press_item_sample_permalink( $permalink, $post_id, $title, $name, $post ){
749
+
750
+ if ( $post->post_type !== LP_QUIZ_CPT && $post->post_type !== LP_LESSON_CPT) {
751
+ return $permalink;
752
+ }
753
+
754
+ // $permalink = str_replace( $post->post_name, '%pagename%' , $permalink );
755
+ $permalink[0] = str_replace( $post->post_name, '%pagename%' , $permalink[0] );
756
+
757
+ return $permalink;
758
+ }
759
+
760
+ }
761
+
762
+ add_filter( 'post_type_link', 'learn_press_quiz_permalink', 10, 2 );
763
+
764
+ if ( !function_exists( 'learn_press_quiz_permalink' ) ) {
765
+
766
+ function learn_press_quiz_permalink( $permalink, $post ) {
767
+
768
+ if( !empty(LP()->global['item_permalinks'][$post->ID])){
769
+ return LP()->global['item_permalinks'][$post->ID];
770
+ }
771
+ remove_filter( 'post_type_link', 'learn_press_quiz_permalink', 10);
772
+
773
+ if ( $post->post_type !== LP_QUIZ_CPT && $post->post_type !== LP_LESSON_CPT) {
774
+ return $permalink;
775
+ }
776
+
777
+ $course_id = learn_press_get_item_course_id( $post->ID, $post->post_type );
778
+ if ( $course_id ) {
779
+ $permalink = learn_press_get_course_item_url( $course_id, $post->ID );
780
+ }
781
+ else {
782
+
783
+ $permalink = learn_press_get_sample_link_course_item_url( $post->ID );
784
+ }
785
+ LP()->global['item_permalinks'][$post->ID] = $permalink;
786
+ add_filter( 'post_type_link', 'learn_press_quiz_permalink', 10, 2 );
787
+ return $permalink;
788
+ }
789
  }
inc/custom-post-types/course.php CHANGED
@@ -1,1566 +1,1563 @@
1
- <?php
2
-
3
- if ( !defined( 'ABSPATH' ) ) {
4
- exit; // Exit if accessed directly
5
- }
6
- if ( !class_exists( 'LP_Course_Post_Type' ) ) {
7
- // class LP_Course_Post_Type
8
- final class LP_Course_Post_Type extends LP_Abstract_Post_Type {
9
- /**
10
- * New version of course editor
11
- *
12
- * @var bool
13
- */
14
- protected static $_VER2 = false;
15
-
16
- /**
17
- * @var null
18
- */
19
- protected static $_instance = null;
20
-
21
- protected static $_enable_review = true;
22
-
23
- /**
24
- * Constructor
25
- *
26
- * @param string
27
- */
28
- public function __construct( $post_type ) {
29
- parent::__construct( $post_type );
30
-
31
- // Map origin methods to another method
32
- $this
33
- ->add_map_method( 'save', 'update_course', false )
34
- ->add_map_method( 'save', 'before_save_curriculum', false )
35
- ->add_map_method( 'before_delete', 'delete_course_sections' );
36
-
37
- add_action( 'edit_form_after_editor', array( $this, 'toggle_editor_button' ), - 10 );
38
-
39
- add_action( 'load-post.php', array( $this, 'post_actions' ) );
40
- add_action( 'init', array( $this, 'register_taxonomy' ) );
41
- add_action( 'init', array( $this, 'init_course' ) );
42
-
43
- add_filter( 'get_edit_post_link', array( $this, 'add_course_tab_arg' ) );
44
- if ( self::$_enable_review ) {
45
- add_action( 'post_submitbox_start', array( $this, 'post_review_message_box' ) );
46
- }
47
-
48
- // filter
49
- add_filter( "rwmb__lpr_course_price_html", array( $this, 'currency_symbol' ), 5, 3 );
50
-
51
- if ( self::$_VER2 ) {
52
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_script' ) );
53
- add_action( 'admin_print_scripts', array( $this, 'course_editor' ) );
54
- }
55
-
56
- }
57
-
58
- public function add_course_tab_arg( $m ) {
59
- if ( array_key_exists( '_lp_curriculum', $_POST ) && !empty( $_POST['course-tab'] ) ) {
60
- $m = add_query_arg( 'tab', $_POST['course-tab'], $m );
61
- }
62
- return $m;
63
- }
64
-
65
- /**
66
- * Load meta box course curriculum outside wp postbox to ensure
67
- * that it always on the top
68
- *
69
- * @since 2.0.9
70
- */
71
- public function curriculum_editor() {
72
- global $wp_meta_boxes, $post;
73
- if ( get_post_type() != 'lp_course' ) {
74
- return;
75
- }
76
- if ( empty( $wp_meta_boxes['lp_course'] ) ) {
77
- return;
78
- }
79
- if ( empty( $wp_meta_boxes['lp_course']['normal'] ) ) {
80
- return;
81
- }
82
- if ( empty( $wp_meta_boxes['lp_course']['normal']['high'] ) ) {
83
- return;
84
- }
85
- if ( empty( $wp_meta_boxes['lp_course']['normal']['high']['course_curriculum'] ) ) {
86
- return;
87
- }
88
- if ( empty( $screen ) )
89
- $screen = get_current_screen();
90
- elseif ( is_string( $screen ) )
91
- $screen = convert_to_screen( $screen );
92
-
93
- $page = $screen->id;
94
- // backup origin metaboxes data
95
- $wp_meta_boxes_origin = $wp_meta_boxes;
96
-
97
- $sorted = get_user_option( "meta-box-order_$page" );
98
- if ( !empty( $sorted ) ) {
99
- foreach ( $sorted as $context => $ids ) {
100
- if ( strpos( $ids, 'course_curriculum' ) !== false ) {
101
- $ids = explode( ',', $ids );
102
- $pos = array_search( 'course_curriculum', $ids );
103
- unset( $ids[$pos] );
104
- $sorted[$context] = join( ',', $ids );
105
- update_user_option( get_current_user_id(), "meta-box-order_$page", $sorted, true );
106
- break;
107
- }
108
- }
109
- }
110
- // keep course curriculum only and call do_meta_boxes to render it content
111
- $wp_meta_boxes = array(
112
- 'lp_course' => array(
113
- 'course_curriculum' => array(
114
- 'high' => array(
115
- 'course_curriculum' => $wp_meta_boxes['lp_course']['normal']['high']['course_curriculum']
116
- )
117
- )
118
- )
119
- );
120
- do_meta_boxes( null, 'course_curriculum', $post );
121
-
122
- // restore origin metaboxes registered
123
- $wp_meta_boxes = $wp_meta_boxes_origin;
124
-
125
- // but no need course curriculum anymore
126
- unset( $wp_meta_boxes['lp_course']['normal']['high']['course_curriculum'] );
127
- //learn_press_debug($wp_meta_boxes['lp_course']);
128
- if ( $sorted = get_user_option( "meta-box-order_$page" ) ) {
129
- foreach ( $sorted as $box_context => $ids ) {
130
- foreach ( explode( ',', $ids ) as $id ) {
131
- if ( $id && 'dashboard_browser_nag' !== $id ) {
132
- add_meta_box( $id, null, null, $screen, $box_context, 'sorted' );
133
- }
134
- }
135
- }
136
- }
137
-
138
- //learn_press_debug($wp_meta_boxes['lp_course']);
139
-
140
- if ( learn_press_get_user_option( 'course-tabs' ) == 'yes' ) {
141
- ?>
142
- <ul id="course-tabs">
143
- <li id="switch-course-metaboxes">
144
- <!--<a href="" id="reorder-course-tabs"><?php _e( 'Reorder', 'learnpress' ); ?></a>
145
- <a href="" id="complete-reorder-course-tabs"><?php _e( 'Ok', 'learnpress' ); ?></a>-->
146
- <a href="<?php echo add_query_arg( 'switch-course-tabs', 'off', get_edit_post_link() ); ?>"><?php _e( 'Switch to meta boxes', 'learnpress' ); ?></a>
147
- </li>
148
- </ul>
149
- <input type="hidden" id="course-tab" name="course-tab" value="<?php echo !empty( $_REQUEST['tab'] ) ? $_REQUEST['tab'] : ''; ?>" />
150
-
151
- <?php
152
- } else {
153
- if ( learn_press_get_user_option( 'hide-notice-switch-course-tabs' ) != 'yes' ) {
154
- ?>
155
- <div class="message updated learn-press-message">
156
- <p><?php _e( 'Would you like to see the meta boxes in tabs style?', 'learnpress' ); ?></p>
157
- <p>
158
- <a class="button" href="<?php echo add_query_arg( 'switch-course-tabs', 'on', get_edit_post_link() ); ?>"><?php _e( 'Switch meta boxes to tabs', 'learnpress' ); ?></a>
159
- <a class="button" href="<?php echo add_query_arg( 'lp-hide-notice', 'switch-course-tabs', get_edit_post_link() ); ?>"><?php _e( 'Hide', 'learnpress' ); ?></a>
160
- </p>
161
- <?php printf( '<a href="%s" class="learn-press-admin-notice-dismiss"></a>', add_query_arg( 'lp-hide-notice', 'switch-course-tabs', get_edit_post_link() ) ); ?>
162
- </div>
163
- <?php
164
- }
165
- ?>
166
- <a id="toggle-meta-boxes" href=""><?php _e( 'Toggle', 'learnpress' ); ?></a>
167
- <a id="switch-course-tabs" href="<?php echo add_query_arg( 'switch-course-tabs', 'on', get_edit_post_link() ); ?>"><?php _e( 'Switch to tabs', 'learnpress' ); ?></a>
168
- <?php
169
- }
170
- }
171
-
172
- public function init_course() {
173
- if ( $toggle = learn_press_get_request( 'switch-course-tabs' ) ) {
174
- if ( $toggle == 'off' ) {
175
- learn_press_delete_user_option( 'course-tabs' );
176
- } elseif ( $toggle == 'on' ) {
177
- learn_press_update_user_option( 'course-tabs', 'yes' );
178
- }
179
-
180
- $link = get_edit_post_link( learn_press_get_request( 'post' ), 'redirect' );
181
- wp_redirect( $link );
182
- exit();
183
- }
184
-
185
- add_action( 'edit_form_after_editor', array( $this, 'curriculum_editor' ), 10 );
186
- if ( learn_press_get_user_option( 'course-tabs' ) == 'yes' ) {
187
- LP_Assets::add_param( 'enable_course_tabs', 'yes', '__all', 'LP_Settings' );
188
- add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
189
- }
190
- }
191
-
192
- public function admin_body_class( $classes ) {
193
- $classes .= ' enable-course-tabs';
194
- return $classes;
195
- }
196
-
197
- public function register_taxonomy() {
198
- $settings = LP()->settings;
199
- $category_base = $settings->get( 'course_category_base' );
200
- register_taxonomy( 'course_category', array( LP_COURSE_CPT ),
201
- array(
202
- 'label' => __( 'Course Categories', 'learnpress' ),
203
- 'labels' => array(
204
- 'name' => __( 'Course Categories', 'learnpress' ),
205
- 'menu_name' => __( 'Category', 'learnpress' ),
206
- 'singular_name' => __( 'Category', 'learnpress' ),
207
- 'add_new_item' => __( 'Add New Course Category', 'learnpress' ),
208
- 'all_items' => __( 'All Categories', 'learnpress' )
209
- ),
210
- 'query_var' => true,
211
- 'public' => true,
212
- 'hierarchical' => true,
213
- 'show_ui' => true,
214
- 'show_in_menu' => 'learn_press',
215
- 'show_admin_column' => true,
216
- 'show_in_admin_bar' => true,
217
- 'show_in_nav_menus' => true,
218
- 'rewrite' => array(
219
- 'slug' => empty( $category_base ) ? _x( 'course-category', 'slug', 'learnpress' ) : $category_base,
220
- 'hierarchical' => true,
221
- 'with_front' => false
222
- ),
223
- )
224
- );
225
-
226
- $tag_base = $settings->get( 'course_tag_base' );
227
- register_taxonomy( 'course_tag', array( LP_COURSE_CPT ),
228
- array(
229
- 'labels' => array(
230
- 'name' => __( 'Course Tags', 'learnpress' ),
231
- 'singular_name' => __( 'Tag', 'learnpress' ),
232
- 'search_items' => __( 'Search Course Tags', 'learnpress' ),
233
- 'popular_items' => __( 'Popular Course Tags', 'learnpress' ),
234
- 'all_items' => __( 'All Course Tags', 'learnpress' ),
235
- 'parent_item' => null,
236
- 'parent_item_colon' => null,
237
- 'edit_item' => __( 'Edit Course Tag', 'learnpress' ),
238
- 'update_item' => __( 'Update Course Tag', 'learnpress' ),
239
- 'add_new_item' => __( 'Add New Course Tag', 'learnpress' ),
240
- 'new_item_name' => __( 'New Course Tag Name', 'learnpress' ),
241
- 'separate_items_with_commas' => __( 'Separate tags with commas', 'learnpress' ),
242
- 'add_or_remove_items' => __( 'Add or remove tags', 'learnpress' ),
243
- 'choose_from_most_used' => __( 'Choose from the most used tags', 'learnpress' ),
244
- 'menu_name' => __( 'Tags', 'learnpress' ),
245
- ),
246
- 'public' => true,
247
- 'hierarchical' => false,
248
- 'show_ui' => true,
249
- 'show_in_menu' => 'learn_press',
250
- 'update_count_callback' => '_update_post_term_count',
251
- 'query_var' => true,
252
- 'rewrite' => array(
253
- 'slug' => empty( $tag_base ) ? _x( 'course-tag', 'slug', 'learnpress' ) : $tag_base,
254
- 'with_front' => false
255
- ),
256
- )
257
- );
258
- }
259
-
260
- public function update_course( $course_id ) {
261
- global $wpdb;
262
- $course_origin_author = get_post_field( 'post_author', $course_id );
263
-
264
- if ( !empty( $_POST['_lp_course_author'] ) ) {
265
- $wpdb->update(
266
- $wpdb->posts,
267
- array( 'post_author' => $_POST['_lp_course_author'] ),
268
- array( 'ID' => $course_id )
269
- );
270
- } elseif ( !( $course_author = get_post_meta( $course_id, '_lp_course_author', true ) ) || !get_user_by( 'id', $course_author ) ) {
271
- update_post_meta( $course_id, '_lp_course_author', $course_author );
272
- $_POST['_lp_course_author'] = $_REQUEST['_lp_course_author'] = $course_origin_author;
273
- }
274
- }
275
-
276
- function admin_script() {
277
- global $post_type;
278
- if ( $post_type != 'lp_course' ) {
279
- return;
280
- }
281
- wp_enqueue_script( 'course-editor', LP()->js( 'admin/course-editor' ), array( 'jquery', 'backbone', 'wp-util', 'jquery-ui-sortable' ) );
282
- wp_enqueue_style( 'course-editor', LP()->css( 'admin/course-editor' ) );
283
-
284
- }
285
-
286
- function course_editor() {
287
- global $post_type;
288
- if ( $post_type != 'lp_course' ) {
289
- return;
290
- }
291
- learn_press_admin_view( 'meta-boxes/course/editor' );
292
- }
293
-
294
- /**
295
- * Delete all questions assign to quiz being deleted
296
- *
297
- * @param $post_id
298
- */
299
- public function delete_course_sections( $post_id ) {
300
- global $wpdb;
301
- // delete all items in section first
302
- $section_ids = $wpdb->get_col( $wpdb->prepare( "SELECT section_id FROM {$wpdb->prefix}learnpress_sections WHERE section_course_id = %d", $post_id ) );
303
- if ( $section_ids ) {
304
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}learnpress_section_items WHERE %d AND section_id IN(" . join( ',', $section_ids ) . ")", 1 ) );
305
- learn_press_reset_auto_increment( 'learnpress_section_items' );
306
-
307
- }
308
-
309
- // delete all sections
310
- $query = $wpdb->prepare( "
311
- DELETE FROM {$wpdb->prefix}learnpress_sections
312
- WHERE section_course_id = %d
313
- ", $post_id );
314
- $wpdb->query( $query );
315
- learn_press_reset_auto_increment( 'learnpress_sections' );
316
- }
317
-
318
-
319
- /**
320
- * Process request actions on post.php loaded
321
- */
322
- public function post_actions() {
323
- $post_id = learn_press_get_request( 'post_ID' );
324
- if ( empty( $post_id ) ) {
325
- $post_id = learn_press_get_request( 'post' );
326
- }
327
- if ( empty( $post_id ) ) {
328
- return;
329
- }
330
- if ( self::$_enable_review ) {
331
- if ( !empty( $_POST ) && learn_press_get_current_user()->is_instructor() && 'yes' == get_post_meta( $post_id, '_lp_submit_for_reviewer', true ) ) {
332
- LP_Admin_Notice::add_redirect( __( 'Sorry! You can not update a course while it is viewing!', 'learnpress' ), 'error' );
333
- wp_redirect( admin_url( 'post.php?post=' . $post_id . '&action=edit' ) );
334
- exit();
335
- }
336
- }
337
- $delete_log = learn_press_get_request( 'delete_log' );
338
- // ensure that user can do this
339
- if ( $delete_log && current_user_can( 'delete_others_lp_courses' ) ) {
340
- $nonce = learn_press_get_request( '_wpnonce' );
341
- if ( wp_verify_nonce( $nonce, 'delete_log_' . $post_id . '_' . $delete_log ) ) {
342
- global $wpdb;
343
- $table = $wpdb->prefix . 'learnpress_review_logs';
344
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) === $table ) {
345
- $wpdb->query(
346
- $wpdb->prepare( "
347
- DELETE FROM {$table}
348
- WHERE review_log_id = %d
349
- ", $delete_log )
350
- );
351
- }
352
- wp_redirect( admin_url( 'post.php?post=' . learn_press_get_request( 'post' ) . '&action=edit' ) );
353
- exit();
354
- }
355
- }
356
- }
357
-
358
- /**
359
- * Toggle course description editor
360
- *
361
- * @param $post
362
- */
363
- public function toggle_editor_button( $post ) {
364
- if ( $post->post_type == LP_COURSE_CPT ) {
365
- ?>
366
- <button class="button button-primary"
367
- data-hidden="<?php echo get_post_meta( $post->ID, '_lp_editor_hidden', true ); ?>" type="button"
368
- id="learn-press-button-toggle-editor"><?php _e( 'Toggle Course Content', 'learnpress' ); ?></button>
369
- <?php
370
- }
371
- }
372
-
373
- /**
374
- * Generate params for course used in admin
375
- *
376
- * @static
377
- * @return mixed
378
- */
379
- public
380
- function admin_params() {
381
- global $post;
382
- return apply_filters( 'learn_press_admin_course_params',
383
- array(
384
- 'id' => absint( $post->ID ),
385
- 'notice_empty_title' => __( 'Please enter the title of the course', 'learnpress' ),
386
- 'notice_empty_section' => __( 'Please add at least one section for the course', 'learnpress' ),
387
- 'notice_empty_section_name' => __( 'Please enter the title of the section', 'learnpress' ),
388
- 'notice_empty_price' => __( 'Please set a price for this course', 'learnpress' )
389
- )
390
- );
391
- }
392
-
393
- /**
394
- * Enqueue scripts
395
- *
396
- * @static
397
- */
398
- public
399
- function admin_scripts() {
400
- global $post;
401
-
402
- $user = learn_press_get_current_user();
403
- LP_Assets::add_localize(
404
- array(
405
- 'notice_remove_section_item' => __( 'Are you sure you want to remove this item?', 'learnpress' ),
406
- 'user_warning_course_publish_to_pending' => __( 'You course will become to Pending', 'learnpress' ),
407
- 'user_warning_can_not_submit_course' => __( 'Your course is pending for reviewing', 'learnpress' )
408
- ),
409
- null,
410
- 'learn-press-mb-course'
411
- );
412
- if ( get_post_type() == LP_COURSE_CPT && self::$_enable_review && !$this->_is_archive() ) {
413
- LP_Assets::add_param( 'required_review', LP()->settings->get( 'required_review' ) == 'yes', 'learn-press-mb-course', 'LP_Settings' );
414
- LP_Assets::add_param( 'enable_edit_published', LP()->settings->get( 'enable_edit_published' ) == 'yes', 'learn-press-mb-course', 'LP_Settings' );
415
- LP_Assets::add_param( 'course_status', get_post_status(), 'learn-press-mb-course', 'LP_Settings' );
416
- LP_Assets::add_param( 'edited_user', learn_press_get_current_user_id(), 'learn-press-mb-course', 'LP_Settings' );
417
- LP_Assets::add_param( 'current_user', $post->post_author, 'learn-press-mb-course', 'LP_Settings' );
418
- LP_Assets::add_param( 'current_user_type', $user->is_admin() ? 'admin' : 'instructor', 'learn-press-mb-course', 'LP_Settings' );
419
- LP_Assets::add_param( 'pending_review', get_post_meta( $post->ID, '_lp_submit_for_reviewer', true ) == 'yes', 'learn-press-mb-course', 'LP_Settings' );
420
-
421
- }
422
- if ( in_array( get_post_type(), array( LP_COURSE_CPT, LP_LESSON_CPT ) ) ) {
423
- wp_enqueue_script( 'jquery-caret', LP()->plugin_url( 'assets/js/jquery.caret.js', 'jquery' ) );
424
- wp_localize_script( 'lp-meta-boxes', 'lp_course_params', self::admin_params() );
425
- }
426
- }
427
-
428
- /**
429
- * Print js template
430
- */
431
- public
432
- function print_js_template() {
433
- if ( get_post_type() != LP_COURSE_CPT ) return;
434
- learn_press_admin_view( 'meta-boxes/course/js-template.php' );
435
- }
436
-
437
- public
438
- function currency_symbol( $input_html, $field, $sub_meta ) {
439
- return $input_html . '<span class="lpr-course-price-symbol">' . learn_press_get_currency_symbol() . '</span>';
440
- }
441
-
442
- /**
443
- * Register course post type
444
- */
445
- public
446
- function register() {
447
- $settings = LP_Settings::instance();
448
- $labels = array(
449
- 'name' => _x( 'Courses', 'Post Type General Name', 'learnpress' ),
450
- 'singular_name' => _x( 'Course', 'Post Type Singular Name', 'learnpress' ),
451
- 'menu_name' => __( 'Courses', 'learnpress' ),
452
- 'parent_item_colon' => __( 'Parent Item:', 'learnpress' ),
453
- 'all_items' => __( 'Courses', 'learnpress' ),
454
- 'view_item' => __( 'View Course', 'learnpress' ),
455
- 'add_new_item' => __( 'Add New Course', 'learnpress' ),
456
- 'add_new' => __( 'Add New', 'learnpress' ),
457
- 'edit_item' => __( 'Edit Course', 'learnpress' ),
458
- 'update_item' => __( 'Update Course', 'learnpress' ),
459
- 'search_items' => __( 'Search Courses', 'learnpress' ),
460
- 'not_found' => sprintf( __( 'You have not got any courses yet. Click <a href="%s">Add new</a> to start', 'learnpress' ), admin_url( 'post-new.php?post_type=lp_course' ) ),
461
- 'not_found_in_trash' => __( 'No course found in Trash', 'learnpress' )
462
- );
463
- $course_base = $settings->get( 'course_base' );
464
- $course_permalink = empty( $course_base ) ? _x( 'courses', 'slug', 'learnpress' ) : $course_base;
465
-
466
- $args = array(
467
- 'labels' => $labels,
468
- 'public' => true,
469
- 'query_var' => true,
470
- 'publicly_queryable' => true,
471
- 'show_ui' => true,
472
- 'has_archive' => 'courses',//( $page_id = learn_press_get_page_id( 'courses' ) ) && get_post( $page_id ) ? get_page_uri( $page_id ) : 'courses',
473
- 'capability_type' => LP_COURSE_CPT,
474
- 'map_meta_cap' => true,
475
- 'show_in_menu' => 'learn_press',
476
- 'show_in_admin_bar' => true,
477
- 'show_in_nav_menus' => true,
478
- 'taxonomies' => array( 'course_category', 'course_tag' ),
479
- 'supports' => array( 'title', 'editor', 'thumbnail', 'revisions', 'comments', 'excerpt' ),
480
- 'hierarchical' => false,
481
- 'rewrite' => $course_permalink ? array(
482
- 'slug' => untrailingslashit( $course_permalink ),
483
- 'with_front' => false
484
- ) : false
485
- );
486
- return $args;
487
- }
488
-
489
- /**
490
- * Add meta boxes to course post type page
491
- */
492
- public
493
- function add_meta_boxes() {
494
-
495
- $user = wp_get_current_user();
496
- //print_r($user);
497
-
498
- $post_type_object = get_post_type_object( LP_COURSE_CPT );
499
- //print_r($post_type_object);
500
-
501
- if ( !self::$_VER2 ) {
502
- new RW_Meta_Box( self::curriculum_meta_box() );
503
- }
504
-
505
- new RW_Meta_Box( self::settings_meta_box() );
506
- new RW_Meta_Box( self::assessment_meta_box() );
507
-
508
- new RW_Meta_Box( self::payment_meta_box() );
509
-
510
- if ( self::$_enable_review ) {
511
- $this->review_logs_meta_box();
512
- }
513
- //new RW_Meta_Box( self::video_meta_box() );
514
- if ( is_super_admin() ) {
515
- new RW_Meta_Box( self::author_meta_box() );
516
- }
517
- parent::add_meta_boxes();
518
- }
519
-
520
- /**
521
- * Course curriculum
522
- *
523
- * @return mixed|null|void
524
- */
525
- public
526
- static function curriculum_meta_box() {
527
- $prefix = '_lp_';
528
-
529
- $meta_box = array(
530
- 'id' => 'course_curriculum',
531
- 'title' => __( 'Curriculum', 'learnpress' ),
532
- 'priority' => 'high',
533
- 'pages' => array( LP_COURSE_CPT ),
534
- 'fields' => array(
535
- array(
536
- 'name' => __( 'Course Curriculum', 'learnpress' ),
537
- 'id' => "{$prefix}curriculum",
538
- 'type' => 'curriculum',
539
- 'desc' => '',
540
- ),
541
- )
542
- );
543
-
544
- return apply_filters( 'learn_press_course_curriculum_meta_box_args', $meta_box );
545
- }
546
-
547
- /**
548
- * Course settings
549
- *
550
- * @return mixed|null|void
551
- */
552
-
553
- public
554
- static function settings_meta_box() {
555
- $prefix = '_lp_';
556
-
557
- $meta_box = array(
558
- 'id' => 'course_settings',
559
- 'title' => __( 'General Settings', 'learnpress' ),
560
- 'pages' => array( LP_COURSE_CPT ),
561
- 'priority' => 'high',
562
- 'fields' => array(
563
- array(
564
- 'name' => __( 'Duration', 'learnpress' ),
565
- 'id' => "{$prefix}duration",
566
- 'type' => 'duration',
567
- 'desc' => __( 'The duration of the course (by weeks).', 'learnpress' ),
568
- 'std' => '10 weeks'
569
- ),
570
- array(
571
- 'name' => __( 'Maximum students', 'learnpress' ),
572
- 'id' => "{$prefix}max_students",
573
- 'type' => 'number',
574
- 'desc' => __( 'Maximum number of students who can enroll in this course.', 'learnpress' ),
575
- 'std' => 1000,
576
- ),
577
- array(
578
- 'name' => __( 'Students enrolled', 'learnpress' ),
579
- 'id' => "{$prefix}students",
580
- 'type' => 'number',
581
- 'desc' => __( 'How many students have taken this course.', 'learnpress' ),
582
- 'std' => 0,
583
- ),
584
- array(
585
- 'name' => __( 'Re-take course', 'learnpress' ),
586
- 'id' => "{$prefix}retake_count",
587
- 'type' => 'number',
588
- 'desc' => __( 'How many times the user can re-take this course. Set to 0 to disable.', 'learnpress' ),
589
- 'std' => 0,
590
- ),
591
- array(
592
- 'name' => __( 'Featured', 'learnpress' ),
593
- 'id' => "{$prefix}featured",
594
- 'type' => 'yes_no',
595
- 'desc' => __( 'Set course as featured.', 'learnpress' ),
596
- 'std' => 'no',
597
- )
598
- )
599
- );
600
-
601
- return apply_filters( 'learn_press_course_settings_meta_box_args', $meta_box );
602
- }
603
-
604
- /**
605
- * Course assessment
606
- *
607
- * @return mixed|null|void
608
- */
609
- public
610
- static function assessment_meta_box() {
611
- $post_id = learn_press_get_request( 'post' );
612
- $prefix = '_lp_';
613
- $course_result_desc = __( 'The method to assess the result of a student for a course.', 'learnpress' );
614
- if ( $post_id && get_post_meta( $post_id, '_lp_course_result', true ) == 'evaluate_final_quiz' && !get_post_meta( $post_id, '_lp_final_quiz', true ) ) {
615
- $course_result_desc .= __( '<br /><strong>Note! </strong>No final quiz in course, please add a final quiz', 'learnpress' );
616
- }
617
- $meta_box = array(
618
- 'id' => 'course_assessment',
619
- 'title' => __( 'Assessment', 'learnpress' ),
620
- 'priority' => 'high',
621
- 'pages' => array( LP_COURSE_CPT ),
622
- 'fields' => array(
623
- array(
624
- 'name' => __( 'Course result', 'learnpress' ),
625
- 'id' => "{$prefix}course_result",
626
- 'type' => 'radio',
627
- 'desc' => $course_result_desc,
628
- 'options' => array(
629
- 'evaluate_lesson' => __( 'Evaluate lessons', 'learnpress' ),
630
- 'evaluate_quizzes' => __( 'Evaluate result of quizzes', 'learnpress' ),
631
- 'evaluate_final_quiz' => __( 'Evaluate the result of the final quiz', 'learnpress' )
632
- ),
633
- 'std' => 'evaluate_lesson',
634
- ),
635
- array(
636
- 'name' => __( 'Passing condition value', 'learnpress' ),
637
- 'id' => "{$prefix}passing_condition",
638
- 'type' => 'number',
639
- 'min' => 1,
640
- 'max' => 100,
641
- 'desc' => __( 'The percentage of quiz result or lessons completed to finish the course.', 'learnpress' ),
642
- 'std' => 80,
643
- )
644
- )
645
- );
646
- return apply_filters( 'learn_press_course_assessment_metabox', $meta_box );
647
- }
648
-
649
- /**
650
- * Course payment
651
- *
652
- * @return mixed|null|void
653
- */
654
- public
655
- static function payment_meta_box() {
656
-
657
- $course_id = !empty( $_GET['post'] ) ? $_GET['post'] : 0;
658
- $prefix = '_lp_';
659
-
660
- $meta_box = array(
661
- 'id' => 'course_payment',
662
- 'title' => __( 'Payment Settings', 'learnpress' ),
663
- 'priority' => 'high',
664
- 'pages' => array( LP_COURSE_CPT ),
665
- 'fields' => array(
666
- array(
667
- 'name' => __( 'Course payment', 'learnpress' ),
668
- 'id' => "{$prefix}payment",
669
- 'type' => 'yes_no',
670
- 'desc' => __( '', 'learnpress' ),
671
- 'std' => 'no',
672
- 'class' => 'lp-course-payment-field'
673
- )
674
- )
675
- );
676
-
677
- $payment = get_post_meta( $course_id, '_lp_payment', true );
678
-
679
- if ( current_user_can( 'manage_options' ) ) {
680
- // $message = __( 'If free, this field is empty or set 0. (Only admin can edit this field)', 'learnpress' );
681
- $message = '';
682
- $price = get_post_meta( $course_id, '_lp_price', true );
683
- $sale_price = 0;
684
- $start_date = '';
685
- $end_date = '';
686
-
687
- if ( isset( $_GET['post'] ) ) {
688
- $course_id = $_GET['post'];
689
-
690
- if ( $payment != 'free' ) {
691
- $suggest_price = get_post_meta( $course_id, '_lp_suggestion_price', true );
692
- $course = get_post( $course_id );
693
-
694
- $author = get_userdata( $course->post_author ) ;
695
-
696
- if ( isset( $suggest_price ) && $author->roles[0] === 'lp_teacher' ) {
697
- $message = sprintf( __( 'This course is requires enrollment and the suggested price is <strong>%s</strong>', 'learnpress' ), learn_press_format_price( $suggest_price, true ) );
698
- $price = $suggest_price;
699
- }
700
-
701
- $sale_price = get_post_meta( $course_id, '_lp_sale_price', true );
702
- $start_date = get_post_meta( $course_id, '_lp_sale_start', true );
703
- $end_date = get_post_meta( $course_id, '_lp_sale_end', true );
704
- } else {
705
- $message = __( 'This course is free.', 'learnpress' );
706
- };
707
- }
708
- array_push(
709
- $meta_box['fields'],
710
- array(
711
- 'name' => __( 'Price', 'learnpress' ),
712
- 'id' => "{$prefix}price",
713
- 'type' => 'number',
714
- 'min' => 0.01,
715
- 'step' => 0.01,
716
- 'desc' => $message,
717
- 'std' => $price,
718
- 'class' => 'lp-course-price-field' . ( $payment != 'yes' ? ' hide-if-js' : '' )
719
- ),
720
- array(
721
- 'name' => __( 'Sale Price', 'learnpress' ),
722
- 'id' => "{$prefix}sale_price",
723
- 'type' => 'number',
724
- 'min' => 0,
725
- 'step' => 0.01,
726
- 'desc' => '<a href="#" id="' . $prefix . 'sale_price_schedule">' . __( 'Schedule', 'learnpress' ) . '</a>',
727
- 'std' => $sale_price,
728
- 'class' => 'lp-course-price-field lp-course-sale_price-field' . ( $payment != 'yes' ? ' hide-if-js' : '' )
729
- ),
730
- array(
731
- 'name' => __( 'Sale start date', 'learnpress' ),
732
- 'id' => "{$prefix}sale_start",
733
- 'type' => 'datetime',
734
- 'std' => $start_date,
735
- 'class' => 'lp-course-sale_start-field hide'
736
- ),
737
- array(
738
- 'name' => __( 'Sale end date', 'learnpress' ),
739
- 'id' => "{$prefix}sale_end",
740
- 'type' => 'datetime',
741
- 'desc' => '<a href="#" id="' . $prefix . 'sale_price_schedule_cancel">' . __( 'Cancel', 'learnpress' ) . '</a>',
742
- 'std' => $end_date,
743
- 'class' => 'lp-course-sale_end-field hide'
744
- )
745
- );
746
- } else {
747
- $price = get_post_meta( $course_id, '_lp_price', true );
748
- $meta_box['fields'][] = array(
749
- 'name' => __( 'Price set by Admin', 'learnpress' ),
750
- 'id' => "{$prefix}price",
751
- 'type' => 'html',
752
- 'class' => 'lp-course-price-field' . ( $payment != 'yes' ? ' hide-if-js' : '' ),
753
- 'html' => $price !== '' ? sprintf( '<strong>%s</strong>', learn_press_format_price( $price, true ) ) : __( 'Not set', 'learnpress' )
754
- );
755
- $meta_box['fields'][] = array(
756
- 'name' => __( 'Course Suggestion Price', 'learnpress' ),
757
- 'id' => "{$prefix}suggestion_price",
758
- 'type' => 'number',
759
- 'min' => 0,
760
- 'step' => 0.01,
761
- 'desc' => __( 'The course price you want to suggest for admin to set.', 'learnpress' ),
762
- 'class' => 'lp-course-price-field' . ( $payment != 'yes' ? ' hide-if-js' : '' ),
763
- 'std' => 0
764
- );
765
-
766
- }
767
- $meta_box['fields'] = array_merge(
768
- $meta_box['fields'],
769
- array(
770
- array(
771
- 'name' => __( 'Requires enroll', 'learnpress' ),
772
- 'id' => "{$prefix}required_enroll",
773
- 'type' => 'yes_no',
774
- 'desc' => __( 'Require users logged in to study or public to all.', 'learnpress' ),
775
- 'std' => 'yes',
776
- 'class' => 'lp-course-required-enroll' . ( ( $payment == 'yes' ) ? ' hide-if-js' : '' )
777
- )
778
- )
779
- );
780
- return apply_filters( 'learn_press_course_payment_meta_box_args', $meta_box );
781
- }
782
-
783
- /**
784
- * Course author
785
- *
786
- * @return mixed|null|void
787
- */
788
- public
789
- static function author_meta_box() {
790
-
791
- $prefix = '_lp_';
792
-
793
- $include = array();
794
- $role = array( 'administrator', 'lp_teacher' );
795
-
796
- $role = apply_filters( 'learn_press_course_author_role_meta_box', $role );
797
-
798
- foreach ( $role as $_role ) {
799
- $users_by_role = get_users( array( 'role' => $_role ) );
800
- if ( $users_by_role ) {
801
- foreach ( $users_by_role as $user ) {
802
- $include[$user->ID] = $user->user_login;
803
- }
804
- }
805
- }
806
-
807
- $meta_box = array(
808
- 'id' => 'course_authors',
809
- 'title' => __( 'Author Settings', 'learnpress' ),
810
- 'pages' => array( LP_COURSE_CPT ),
811
- 'priority' => 'default',
812
- 'fields' => array(
813
- array(
814
- 'name' => __( 'Author', 'learnpress' ),
815
- 'id' => "{$prefix}course_author",
816
- 'desc' => '',
817
- 'multiple' => false,
818
- 'allowClear' => false,
819
- 'type' => 'select_advanced',
820
- 'placeholder' => __( 'Select author', 'learnpress' ),
821
- 'options' => $include
822
- )
823
- )
824
- );
825
-
826
- return apply_filters( 'learn_press_course_author_meta_box', $meta_box );
827
-
828
- }
829
-
830
- /**
831
- * Course review logs
832
- *
833
- */
834
- public
835
- function review_logs_meta_box() {
836
- add_meta_box(
837
- 'review_logs',
838
- __( 'Review Logs', 'learnpress' ),
839
- array( $this, 'review_logs_content' ),
840
- LP_COURSE_CPT,
841
- 'normal',
842
- 'default'
843
- );
844
- }
845
-
846
- /**
847
- * Display view for listing logs
848
- *
849
- * @param $post
850
- */
851
- public
852
- function review_logs_content( $post ) {
853
- global $wpdb;
854
- $view_all = learn_press_get_request( 'view_all_review' );
855
- $table = $wpdb->prefix . 'learnpress_review_logs';
856
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) === $table ) {
857
- $query = $wpdb->prepare( "
858
- SELECT SQL_CALC_FOUND_ROWS *
859
- FROM {$wpdb->learnpress_review_logs}
860
- WHERE course_id = %d
861
- ORDER BY `date` DESC"
862
- . ( $view_all ? "" : " LIMIT 0, 10" ) . "
863
- ", $post->ID );
864
- $reviews = $wpdb->get_results( $query );
865
- $total_reviews = $wpdb->get_var( "SELECT FOUND_ROWS()" );
866
- $count_reviews = sizeof( $reviews );
867
-
868
- $view = learn_press_get_admin_view( 'meta-boxes/course/review-logs.php' );
869
- include $view;
870
- }
871
- }
872
-
873
- /**
874
- *
875
- */
876
- public
877
- function save() {
878
-
879
- }
880
-
881
- /**
882
- * Insert new section into database
883
- *
884
- * @param array $section
885
- *
886
- * @return array|mixed|string
887
- */
888
- private
889
- function _insert_section( $section = array() ) {
890
- global $wpdb;
891
- $section = wp_parse_args(
892
- $section,
893
- array(
894
- 'section_name' => '',
895
- 'section_course_id' => 0,
896
- 'section_order' => 0,
897
- 'section_description' => ''
898
- )
899
- );
900
- $section = stripslashes_deep( $section );
901
- extract( $section );
902
-
903
- $insert_data = compact( 'section_name', 'section_course_id', 'section_order', 'section_description' );
904
- $wpdb->insert(
905
- $wpdb->learnpress_sections,
906
- $insert_data,
907
- array( '%s', '%d', '%d' )
908
- );
909
- $section['section_id'] = $wpdb->insert_id;
910
- return $section;
911
- }
912
-
913
- /**
914
- * @param array $item
915
- *
916
- * @return array
917
- */
918
- private
919
- function _insert_item( $item = array() ) {
920
- $_post = $this->_cleanPostData();
921
-
922
- $item_id = wp_insert_post(
923
- array(
924
- 'post_title' => $item['post_title'],
925
- 'post_type' => $item['post_type'],
926
- 'post_status' => 'publish'
927
- )
928
- );
929
- $item['ID'] = $item_id;
930
-
931
- $this->_resetPostData( $_post );
932
-
933
- return $item;
934
- }
935
-
936
- private
937
- function _cleanPostData() {
938
- $_post = $_POST;
939
- if ( $_POST ) {
940
- foreach ( $_POST as $k => $v ) {
941
- unset( $_POST[$k] );
942
- }
943
- }
944
- return $_post;
945
- }
946
-
947
- private
948
- function _resetPostData( $_post ) {
949
- if ( $_post ) {
950
- foreach ( $_post as $k => $v ) {
951
- $_POST[$k] = $v;
952
- }
953
- }
954
- return $_POST;
955
- }
956
-
957
- /*
958
- * Delete all sections in a course and reset auto increment
959
- */
960
- private
961
- function _reset_sections() {
962
- global $wpdb, $post;
963
-
964
- $wpdb->query(
965
- $wpdb->prepare( "
966
- DELETE FROM si
967
- USING {$wpdb->learnpress_section_items} si
968
- INNER JOIN {$wpdb->learnpress_sections} s ON s.section_id = si.section_id
969
- INNER JOIN {$wpdb->posts} p ON p.ID = s.section_course_id
970
- WHERE p.ID = %d
971
- ", $post->ID )
972
- );
973
- $wpdb->query( "
974
- ALTER TABLE {$wpdb->learnpress_section_items} AUTO_INCREMENT = 1
975
- " );
976
-
977
- $wpdb->query(
978
- $wpdb->prepare( "
979
- DELETE FROM {$wpdb->learnpress_sections}
980
- WHERE section_course_id = %d
981
- ", $post->ID )
982
- );
983
- $wpdb->query( "
984
- ALTER TABLE {$wpdb->learnpress_sections} AUTO_INCREMENT = 1
985
- " );
986
- }
987
-
988
- public
989
- function _save() {
990
- global $wpdb, $post;
991
-
992
- $preview = filter_input( INPUT_POST, 'wp-preview', FILTER_SANITIZE_STRING );
993
-
994
- if ( 'dopreview' == $preview && 'draft' == $post->post_status ) {
995
- learn_press_add_message( __( 'Course Curriculum only appear if course is saved', 'learnpress' ), $type );
996
- }
997
-
998
- $this->_reset_sections();
999
-
1000
- if ( !empty( $_REQUEST['_lp_curriculum'] ) && 'dopreview' !== $preview ) {
1001
- $section_order = 0;
1002
- $query_update = array();
1003
- $update_ids = array();
1004
- $query_insert = array();
1005
- foreach ( $_REQUEST['_lp_curriculum'] as $section_id => $_section ) {
1006
- $section_id = 0;
1007
- // section items
1008
- $items = $_section['items'];
1009
- $item_order = 0;
1010
- $insert = false;
1011
- $sql_section_items = array();
1012
- if ( !empty( $items ) ) {
1013
- foreach ( $items as $section_item_id => $_item ) {
1014
-
1015
- // abort the item has not got a name
1016
- if ( !$_item['name'] )
1017
- continue;
1018
- $insert = true;
1019
-
1020
- $item_id = $_item['item_id'];
1021
-
1022
- // if item has not got the ID then insert a new one
1023
- if ( !$item_id ) {
1024
- $item = $this->_insert_item(
1025
- array(
1026
- 'post_title' => $_item['name'],
1027
- 'post_type' => $_item['post_type'],
1028
- )
1029
- );
1030
- $item_id = $item['ID'];
1031
- } else { // Otherwise, update existing
1032
- if ( strcmp( $_item['name'], $_item['old_name'] ) !== 0 ) {
1033
- $query_update[] = 'WHEN ' . $_item['item_id'] . ' THEN \'' . $_item['name'] . '\'';
1034
- $update_ids[] = $_item['item_id'];
1035
- $update_data = array(
1036
- 'ID' => $_item['item_id'],
1037
- 'post_title' => $_item['name']
1038
- );
1039
- if ( LP()->settings->get( 'auto_update_post_name' ) == 'yes' ) {
1040
- $update_data['post_name'] = sanitize_title( $_item['name'] );
1041
- }
1042
- // prevent update the meta of course for the items when update items
1043
- $_post = $this->_cleanPostData();
1044
- wp_update_post( $update_data );
1045
- $this->_resetPostData( $_post );
1046
- }
1047
- $item_id = $_item['item_id'];
1048
- }
1049
- $sql_section_items[] = $wpdb->prepare( "(%d, %d, %d, %s)", - 9999999, $item_id, ++ $item_order, $_item['post_type'] );
1050
- }
1051
- }
1052
-
1053
- if ( $insert || ( !$insert && ( !empty( $_section['name'] ) || empty( $items ) ) ) ) {
1054
- $section = array(
1055
- 'section_name' => !empty( $_section['name'] ) ? $_section['name'] : '',
1056
- 'section_course_id' => $post->ID,
1057
- 'section_order' => ++ $section_order,
1058
- 'section_description' => $_section['description'],
1059
- 'items' => array()
1060
- );
1061
-
1062
- if ( !$section_id ) {
1063
- $section = $this->_insert_section( $section );
1064
- $section_id = $section['section_id'];
1065
- }
1066
- $sections[$section_id] = $section;
1067
- foreach ( $sql_section_items as $section_item ) {
1068
- $query_insert[] = str_replace( - 9999999, $section_id, $section_item );
1069
- }
1070
- }
1071
- }
1072
- if ( $query_insert ) {
1073
- $query_insert = "
1074
- INSERT INTO {$wpdb->learnpress_section_items}(`section_id`, `item_id`, `item_order`, `item_type`)
1075
- VALUES " . join( ', ', $query_insert ) . "
1076
- ";
1077
- $wpdb->query( $query_insert );
1078
- }
1079
- if ( $query_update ) {
1080
- $query_update = "
1081
- UPDATE {$wpdb->posts}
1082
- SET
1083
- `post_title` = CASE `ID` " . join( ' ', $query_update ) . " END
1084
- WHERE
1085
- ID IN (" . join( ',', $update_ids ) . ")
1086
- ";
1087
- $wpdb->query( $query_update );
1088
- }
1089
- }
1090
- }
1091
-
1092
- private
1093
- function _update_final_quiz() {
1094
- global $post;
1095
- $final_quiz = false;
1096
-
1097
- if ( learn_press_get_request( '_lp_course_result' ) == 'evaluate_final_quiz' ) {
1098
- if ( $final_quiz = learn_press_get_final_quiz( $post->ID ) ) {
1099
- update_post_meta( $post->ID, '_lp_final_quiz', $final_quiz );
1100
- } else {
1101
- delete_post_meta( $post->ID, '_lp_final_quiz' );
1102
- }
1103
- } else {
1104
- delete_post_meta( $post->ID, '_lp_final_quiz' );
1105
- }
1106
- do_action( 'learn_press_update_final_quiz', $final_quiz, $post->ID );
1107
- return $final_quiz;
1108
- }
1109
-
1110
- private
1111
- function _send_mail() {
1112
- if ( !LP()->user->is_instructor() ) return;
1113
- $mail = LP()->mail;
1114
-
1115
- }
1116
-
1117
- private
1118
- function _review_log() {
1119
- global $wpdb, $post;
1120
- $user = learn_press_get_current_user();
1121
- $action = '';
1122
- $old_status = $post->post_status;
1123
- $new_status = get_post_status( $post->ID );
1124
- $required_review = LP()->settings->get( 'required_review' ) == 'yes';
1125
- $enable_edit_published = LP()->settings->get( 'enable_edit_published' ) == 'yes';
1126
-
1127
- $submit_for_review = learn_press_get_request( 'learn-press-submit-for-review' ) == 'yes' || ( ( !$required_review || $enable_edit_published ) );
1128
- // If course is submitted by administrator
1129
- if ( $user->is_admin() ) {
1130
- if ( $old_status != $new_status ) {
1131
- if ( $new_status == 'publish' ) {
1132
- $action = 'approved';
1133
- } elseif ( $new_status != 'publish' ) {
1134
- $action = 'rejected';
1135
- }
1136
- delete_post_meta( $post->ID, '_lp_submit_for_reviewer', 'yes' );
1137
- }
1138
- } elseif ( $user->is_instructor() ) { // Course is submitted by instructor
1139
-
1140
- if ( $enable_edit_published && ( $old_status == $new_status && $new_status == 'publish' ) ) {
1141
- $submit_for_review = false;
1142
- }
1143
- if ( ( $submit_for_review || ( $old_status != $new_status ) ) && $post->post_status != 'auto-draft' ) {
1144
- $action = 'for_reviewer';
1145
- update_post_meta( $post->ID, '_lp_submit_for_reviewer', 'yes' );
1146
- }
1147
- }
1148
- $message = learn_press_get_request( 'review-message' );
1149
- if ( !$action && !$message ) {
1150
- return;
1151
- }
1152
-
1153
- switch ( $action ) {
1154
- case 'approved':
1155
- if ( !$message ) {
1156
- $message = __( 'Course has approved by Reviewer', 'learnpress' );
1157
- }
1158
- break;
1159
- case 'rejected':
1160
- if ( !$message ) {
1161
- $message = __( 'Course has rejected by Reviewer', 'learnpress' );
1162
- }
1163
- break;
1164
- case 'for_reviewer':
1165
- if ( !$message ) {
1166
- $message = sprintf( __( 'Course has submitted by %s', 'learnpress' ), learn_press_get_profile_display_name( $user ) );
1167
- }
1168
- break;
1169
- default:
1170
- if ( !$message ) {
1171
- $message = __( 'Course has updated by Reviewer', 'learnpress' );
1172
- }
1173
- }
1174
- if ( apply_filters( 'learn_press_review_log_message', $message, $post->ID, $user->id ) ) {
1175
- $table = $wpdb->prefix . 'learnpress_review_logs';
1176
- $wpdb->insert(
1177
- $table,
1178
- array(
1179
- 'course_id' => $post->ID,
1180
- 'user_id' => $user->id,
1181
- 'message' => $message,
1182
- 'date' => current_time( 'mysql' ),
1183
- 'status' => $new_status,
1184
- 'user_type' => $user->is_admin() ? 'reviewer' : 'instructor'
1185
- ),
1186
- array( '%d', '%d', '%s', '%s', '%s', '%s' )
1187
- );
1188
- do_action( 'learn_press_update_review_log', $wpdb->insert_id, $post->ID, $user->id );
1189
- }
1190
- if ( $action ) {
1191
- do_action( "learn_press_course_submit_{$action}", $post->ID, $user );
1192
- }
1193
-
1194
- return;
1195
-
1196
- if ( !$action ) {
1197
- return;
1198
- }
1199
-
1200
- /*if ( !$required_review || ( $required_review && $enable_edit_published ) ) {
1201
- return;
1202
- }*/
1203
-
1204
- $user = LP()->user;
1205
- $message = learn_press_get_request( 'review_message' );
1206
-
1207
- if ( !$message && !$user->is_instructor() && get_post_status( $post->ID ) == 'publish' ) {
1208
- $message = __( 'Your course has been published', 'learnpress' );
1209
- }
1210
- if ( apply_filters( 'learn_press_review_log_message', $message, $post->ID, $user->id ) ) {
1211
- $table = $wpdb->prefix . 'learnpress_review_logs';
1212
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) === $table ) {
1213
- $query = $wpdb->prepare( "
1214
- INSERT INTO {$wpdb->learnpress_review_logs}(`course_id`, `user_id`, `message`, `date`, `status`, `user_type`)
1215
- VALUES(%d, %d, %s, %s, %s, %s)
1216
- ", $post->ID, $user->id, $message, current_time( 'mysql' ), get_post_status( $post->ID ), $user->is_instructor() ? 'instructor' : 'reviewer' );
1217
- $wpdb->query( $query );
1218
- do_action( 'learn_press_update_review_log', $wpdb->insert_id, $post->ID, $user->id );
1219
- }
1220
- }
1221
- if ( $action == 'learn_press_course_submit_for_instructor' ) {
1222
- if ( get_post_status( $post->ID ) == 'publish' ) {
1223
- do_action( 'learn_press_course_submit_approved', $post->ID, $user );
1224
- } else {
1225
- do_action( 'learn_press_course_submit_rejected', $post->ID, $user );
1226
- }
1227
- } else {
1228
- do_action( $action, $post->ID, $user );
1229
- }
1230
- }
1231
-
1232
- public
1233
- function before_save_curriculum() {
1234
-
1235
- global $post, $pagenow;
1236
-
1237
- // Ensure that we are editing course in admin side
1238
-
1239
- if ( ( $pagenow != 'post.php' ) || ( get_post_type() != LP_COURSE_CPT ) ) {
1240
- return;
1241
- }
1242
-
1243
- remove_action( 'save_post', array( $this, 'before_save_curriculum' ), 1 );
1244
- //remove_action( 'rwmb_course_curriculum_before_save_post', array( $this, 'before_save_curriculum' ) );
1245
-
1246
- $user = LP()->user;
1247
- $required_review = LP()->settings->get( 'required_review' ) == 'yes';
1248
- $enable_edit_published = LP()->settings->get( 'enable_edit_published' ) == 'yes';
1249
-
1250
- if ( $user->is_instructor() && $required_review && !$enable_edit_published ) {
1251
- wp_update_post(
1252
- array(
1253
- 'ID' => $post->ID,
1254
- 'post_status' => 'pending'
1255
- ),
1256
- array( '%d', '%s' )
1257
- );
1258
-
1259
- }
1260
-
1261
- $new_status = get_post_status( $post->ID );
1262
- $old_status = get_post_meta( $post->ID, '_lp_course_status', true );
1263
-
1264
- $this->_save();
1265
- $this->_update_final_quiz();
1266
-
1267
- if ( $new_status != $old_status ) {
1268
- do_action( 'learn_press_transition_course_status', $new_status, $old_status, $post->ID );
1269
- update_post_meta( $post->ID, '_lp_course_status', $new_status );
1270
- }
1271
-
1272
- $this->_review_log();
1273
- delete_post_meta( $post->ID, '_lp_curriculum' );
1274
- //add_action( 'rwmb_course_curriculum_before_save_post', array( $this, 'before_save_curriculum' ) );
1275
- }
1276
-
1277
- public
1278
- static function enqueue_scripts() {
1279
-
1280
- }
1281
-
1282
- /**
1283
- * Add columns to admin manage course page
1284
- *
1285
- * @param array $columns
1286
- *
1287
- * @return array
1288
- */
1289
- public
1290
- function columns_head( $columns ) {
1291
- $user = wp_get_current_user();
1292
- if ( in_array( 'lp_teacher', $user->roles ) ) {
1293
- unset( $columns['author'] );
1294
- }
1295
- $keys = array_keys( $columns );
1296
- $values = array_values( $columns );
1297
- $pos = array_search( 'title', $keys );
1298
- if ( $pos !== false ) {
1299
- array_splice( $keys, $pos + 1, 0, array( 'author', 'sections', 'students', 'price' ) );
1300
- array_splice( $values, $pos + 1, 0, array(
1301
- __( 'Author', 'learnpress' ),
1302
- __( 'Content', 'learnpress' ),
1303
- __( 'Students', 'learnpress' ),
1304
- __( 'Price', 'learnpress' ) ) );
1305
- $columns = array_combine( $keys, $values );
1306
- } else {
1307
- $columns['author'] = __( 'Author', 'learnpress' );
1308
- $columns['sections'] = __( 'Content', 'learnpress' );
1309
- $columns['students'] = __( 'Students', 'learnpress' );
1310
- $columns['price'] = __( 'Price', 'learnpress' );
1311
- }
1312
-
1313
- $columns['taxonomy-course_category'] = __( 'Categories', 'learnpress' );
1314
- return $columns;
1315
- }
1316
-
1317
- /**
1318
- * Print content for custom column
1319
- *
1320
- * @param string
1321
- * @param int
1322
- */
1323
- public
1324
- function columns_content( $column, $post_id = 0 ) {
1325
- global $post;
1326
- $course = LP_Course::get_course( $post->ID );
1327
- switch ( $column ) {
1328
-
1329
- case 'sections':
1330
- $sections = $course->get_curriculum();
1331
- if ( $sections ) {
1332
- $items = $course->get_curriculum_items( array( 'group' => true ) );
1333
- $count_sections = sizeof( $sections );
1334
- $count_lessons = sizeof( $items['lessons'] );
1335
- $count_quizzes = sizeof( $items['quizzes'] );
1336
- $output = sprintf( _nx( '%d section', '%d sections', $count_sections, 'learnpress' ), $count_sections );
1337
- $output .= ' (';
1338
- if ( $count_lessons ) {
1339
- $output .= sprintf( _nx( '%d lesson', '%d lessons', $count_lessons, 'learnpress' ), $count_lessons );
1340
- } else {
1341
- $output .= __( "0 lesson", 'learnpress' );
1342
- }
1343
- $output .= ', ';
1344
- if ( $count_quizzes ) {
1345
- $output .= sprintf( _nx( '%d quiz', '%d quizzes', $count_quizzes, 'learnpress' ), $count_quizzes );
1346
- } else {
1347
- $output .= __( "0 quiz", 'learnpress' );
1348
- }
1349
- $output .= ')';
1350
- echo $output;
1351
- } else {
1352
- _e( 'No content', 'learnpress' );
1353
- }
1354
- break;
1355
- case 'price':
1356
- $price = get_post_meta( $post->ID, '_lp_price', true );
1357
- $is_paid = get_post_meta( $post->ID, '_lp_payment', true );
1358
- if ( ( $is_paid === 'yes' ) && $price ) {
1359
- echo sprintf( '<a href="%s">%s</a>', add_query_arg( 'filter_price', $price ), learn_press_format_price( get_post_meta( $post->ID, '_lp_price', true ), true ) );
1360
- } else {
1361
- echo sprintf( '<a href="%s">%s</a>', add_query_arg( 'filter_price', 0 ), __( 'Free', 'learnpress' ) );
1362
- }
1363
- break;
1364
- case 'students' :
1365
- echo '<span class=lp-label-counter>' . count( $course->get_students_list( true ) ) . '</span>';
1366
-
1367
- }
1368
- }
1369
-
1370
- /**
1371
- * Log the messages between admin and instructor
1372
- */
1373
- public
1374
- function post_review_message_box() {
1375
- global $post;
1376
-
1377
- if ( get_post_type( $post->ID ) != 'lp_course' ) {
1378
- return false;
1379
- }
1380
-
1381
- //$user = learn_press_get_current_user();
1382
- $course_user = learn_press_get_user( get_post_field( 'post_author', $post->ID ) );
1383
-
1384
- if ( $course_user->is_admin() ) {
1385
- return;
1386
- }
1387
-
1388
- $required_review = LP()->settings->get( 'required_review' ) == 'yes';
1389
- //$enable_edit_published = LP()->settings->get( 'enable_edit_published' ) == 'yes';
1390
- //$is_publish = get_post_status( $post->ID ) == 'publish';
1391
-
1392
- if ( !$required_review ) {
1393
- return;
1394
- }
1395
- /*if( $enable_edit_published ){
1396
- return;
1397
- }*/
1398
-
1399
-
1400
- learn_press_admin_view( 'meta-boxes/course/review-log' );
1401
- }
1402
-
1403
- public
1404
- function posts_fields( $fields ) {
1405
- if ( !$this->_is_archive() ) {
1406
- return $fields;
1407
- }
1408
-
1409
- $fields = " DISTINCT " . $fields;
1410
- if ( ( $this->_get_orderby() == 'price' ) || ( $this->_get_search() ) ) {
1411
- $fields .= ', pm_price.meta_value as course_price';
1412
- }
1413
- return $fields;
1414
- }
1415
-
1416
- /**
1417
- * @param $join
1418
- *
1419
- * @return string
1420
- */
1421
- public
1422
- function posts_join_paged( $join ) {
1423
- if ( !$this->_is_archive() ) {
1424
- return $join;
1425
- }
1426
- global $wpdb;
1427
- $join .= " LEFT JOIN {$wpdb->postmeta} pm_price ON pm_price.post_id = {$wpdb->posts}.ID AND pm_price.meta_key = '_lp_price'";
1428
-
1429
- return $join;
1430
- }
1431
-
1432
- /**
1433
- * @param $where
1434
- *
1435
- * @return mixed|string
1436
- */
1437
- public
1438
- function posts_where_paged( $where ) {
1439
- if ( !$this->_is_archive() ) {
1440
- return $where;
1441
- }
1442
- global $wpdb;
1443
- if ( array_key_exists( 'filter_price', $_REQUEST ) ) {
1444
- if ( $_REQUEST['filter_price'] == 0 ) {
1445
- $where .= " AND ( pm_price.meta_value IS NULL || pm_price.meta_value = 0 )";
1446
- } else {
1447
- $where .= $wpdb->prepare( " AND ( pm_price.meta_value = %s )", $_REQUEST['filter_price'] );
1448
- }
1449
- }
1450
-
1451
- return $where;
1452
- }
1453
-
1454
- /**
1455
- * @param $order_by_statement
1456
- *
1457
- * @return string
1458
- */
1459
- public
1460
- function posts_orderby( $order_by_statement ) {
1461
- if ( !$this->_is_archive() ) {
1462
- return $order_by_statement;
1463
- }
1464
- switch ( $this->_get_orderby() ) {
1465
- case 'price':
1466
- $order_by_statement = "pm_price.meta_value {$_GET['order']}";
1467
- }
1468
- return $order_by_statement;
1469
- }
1470
-
1471
- /**
1472
- * @param $columns
1473
- *
1474
- * @return mixed
1475
- */
1476
- public
1477
- function sortable_columns( $columns ) {
1478
- $columns['author'] = 'author';
1479
- $columns['price'] = 'price';
1480
-
1481
- return $columns;
1482
- }
1483
-
1484
- private
1485
- function _is_archive() {
1486
- global $pagenow, $post_type;
1487
- if ( !is_admin() || ( $pagenow != 'edit.php' ) || ( LP_COURSE_CPT != $post_type ) ) {
1488
- return false;
1489
- }
1490
- return true;
1491
- }
1492
-
1493
- private
1494
- function _get_orderby() {
1495
- return isset( $_REQUEST['orderby'] ) ? $_REQUEST['orderby'] : '';
1496
- }
1497
-
1498
- private
1499
- function _get_search() {
1500
- return isset( $_REQUEST['s'] ) ? $_REQUEST['s'] : false;
1501
- }
1502
-
1503
- /**
1504
- * Course video
1505
- * @return mixed|null|void
1506
- */
1507
- public
1508
- static function video_meta_box() {
1509
- $prefix = '_lp_';
1510
- $meta_box = array(
1511
- 'id' => 'course_video',
1512
- 'title' => __( 'Course Video', 'learnpress' ),
1513
- 'pages' => array( LP_COURSE_CPT ),
1514
- 'priority' => 'high',
1515
- 'fields' => array(
1516
- array(
1517
- 'name' => __( 'Video ID', 'learnpress' ),
1518
- 'id' => "{$prefix}video_id",
1519
- 'type' => 'text',
1520
- 'desc' => __( 'The id of Youtube or Vimeo video', 'learnpress' ),
1521
- 'std' => ''
1522
- ),
1523
- array(
1524
- 'name' => __( 'Video Type', 'learnpress' ),
1525
- 'id' => "{$prefix}video_type",
1526
- 'type' => 'select',
1527
- 'desc' => __( 'Chose video type', 'learnpress' ),
1528
- 'std' => 'youtube',
1529
- 'options' => array(
1530
- 'youtube' => __( 'Youtube', 'learnpress' ),
1531
- 'vimeo' => __( 'Vimeo', 'learnpress' )
1532
- )
1533
- ),
1534
- array(
1535
- 'name' => __( 'Embed width', 'learnpress' ),
1536
- 'id' => "{$prefix}video_embed_width",
1537
- 'type' => 'number',
1538
- 'desc' => __( 'Set width of embed', 'learnpress' ),
1539
- 'std' => '560'
1540
- ),
1541
- array(
1542
- 'name' => __( 'Embed height', 'learnpress' ),
1543
- 'id' => "{$prefix}video_embed_height",
1544
- 'type' => 'number',
1545
- 'desc' => __( 'Set height of embed', 'learnpress' ),
1546
- 'std' => '315'
1547
- ),
1548
- )
1549
- );
1550
-
1551
- return apply_filters( 'learn_press_course_video_meta_box_args', $meta_box );
1552
- }
1553
-
1554
-
1555
- public
1556
- static function instance() {
1557
- if ( !self::$_instance ) {
1558
- self::$_instance = new self( LP_COURSE_CPT );
1559
- }
1560
- return self::$_instance;
1561
- }
1562
- } // end LP_Course_Post_Type
1563
-
1564
- $course_post_type = LP_Course_Post_Type::instance();
1565
- //$course_post_type->add_meta_box( 'course-editor', 'dfgdfgfdg', 'course_editor', 'advanced', 'default' );
1566
- }
1
+ <?php
2
+
3
+ if ( !defined( 'ABSPATH' ) ) {
4
+ exit; // Exit if accessed directly
5
+ }
6
+ if ( !class_exists( 'LP_Course_Post_Type' ) ) {
7
+ // class LP_Course_Post_Type
8
+ final class LP_Course_Post_Type extends LP_Abstract_Post_Type {
9
+ /**
10
+ * New version of course editor
11
+ *
12
+ * @var bool
13
+ */
14
+ protected static $_VER2 = false;
15
+
16
+ /**
17
+ * @var null
18
+ */
19
+ protected static $_instance = null;
20
+
21
+ protected static $_enable_review = true;
22
+
23
+ /**
24
+ * Constructor
25
+ *
26
+ * @param string
27
+ */
28
+ public function __construct( $post_type ) {
29
+ parent::__construct( $post_type );
30
+
31
+ // Map origin methods to another method
32
+ $this
33
+ ->add_map_method( 'save', 'update_course', false )
34
+ ->add_map_method( 'save', 'before_save_curriculum', false )
35
+ ->add_map_method( 'before_delete', 'delete_course_sections' );
36
+
37
+ add_action( 'edit_form_after_editor', array( $this, 'toggle_editor_button' ), - 10 );
38
+
39
+ add_action( 'load-post.php', array( $this, 'post_actions' ) );
40
+ add_action( 'init', array( $this, 'register_taxonomy' ) );
41
+ add_action( 'init', array( $this, 'init_course' ) );
42
+
43
+ add_filter( 'get_edit_post_link', array( $this, 'add_course_tab_arg' ) );
44
+ if ( self::$_enable_review ) {
45
+ add_action( 'post_submitbox_start', array( $this, 'post_review_message_box' ) );
46
+ }
47
+
48
+ // filter
49
+ add_filter( "rwmb__lpr_course_price_html", array( $this, 'currency_symbol' ), 5, 3 );
50
+
51
+ if ( self::$_VER2 ) {
52
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_script' ) );
53
+ add_action( 'admin_print_scripts', array( $this, 'course_editor' ) );
54
+ }
55
+
56
+ }
57
+
58
+ public function add_course_tab_arg( $m ) {
59
+ if ( array_key_exists( '_lp_curriculum', $_POST ) && !empty( $_POST['course-tab'] ) ) {
60
+ $m = add_query_arg( 'tab', $_POST['course-tab'], $m );
61
+ }
62
+ return $m;
63
+ }
64
+
65
+ /**
66
+ * Load meta box course curriculum outside wp postbox to ensure
67
+ * that it always on the top
68
+ *
69
+ * @since 2.0.9
70
+ */
71
+ public function curriculum_editor() {
72
+ global $wp_meta_boxes, $post;
73
+ if ( get_post_type() != 'lp_course' ) {
74
+ return;
75
+ }
76
+ if ( empty( $wp_meta_boxes['lp_course'] ) ) {
77
+ return;
78
+ }
79
+ if ( empty( $wp_meta_boxes['lp_course']['normal'] ) ) {
80
+ return;
81
+ }
82
+ if ( empty( $wp_meta_boxes['lp_course']['normal']['high'] ) ) {
83
+ return;
84
+ }
85
+ if ( empty( $wp_meta_boxes['lp_course']['normal']['high']['course_curriculum'] ) ) {
86
+ return;
87
+ }
88
+ if ( empty( $screen ) )
89
+ $screen = get_current_screen();
90
+ elseif ( is_string( $screen ) )
91
+ $screen = convert_to_screen( $screen );
92
+
93
+ $page = $screen->id;
94
+ // backup origin metaboxes data
95
+ $wp_meta_boxes_origin = $wp_meta_boxes;
96
+
97
+ $sorted = get_user_option( "meta-box-order_$page" );
98
+ if ( !empty( $sorted ) ) {
99
+ foreach ( $sorted as $context => $ids ) {
100
+ if ( strpos( $ids, 'course_curriculum' ) !== false ) {
101
+ $ids = explode( ',', $ids );
102
+ $pos = array_search( 'course_curriculum', $ids );
103
+ unset( $ids[$pos] );
104
+ $sorted[$context] = join( ',', $ids );
105
+ update_user_option( get_current_user_id(), "meta-box-order_$page", $sorted, true );
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ // keep course curriculum only and call do_meta_boxes to render it content
111
+ $wp_meta_boxes = array(
112
+ 'lp_course' => array(
113
+ 'course_curriculum' => array(
114
+ 'high' => array(
115
+ 'course_curriculum' => $wp_meta_boxes['lp_course']['normal']['high']['course_curriculum']
116
+ )
117
+ )
118
+ )
119
+ );
120
+ do_meta_boxes( null, 'course_curriculum', $post );
121
+
122
+ // restore origin metaboxes registered
123
+ $wp_meta_boxes = $wp_meta_boxes_origin;
124
+
125
+ // but no need course curriculum anymore
126
+ unset( $wp_meta_boxes['lp_course']['normal']['high']['course_curriculum'] );
127
+ //learn_press_debug($wp_meta_boxes['lp_course']);
128
+ if ( $sorted = get_user_option( "meta-box-order_$page" ) ) {
129
+ foreach ( $sorted as $box_context => $ids ) {
130
+ foreach ( explode( ',', $ids ) as $id ) {
131
+ if ( $id && 'dashboard_browser_nag' !== $id ) {
132
+ add_meta_box( $id, null, null, $screen, $box_context, 'sorted' );
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ //learn_press_debug($wp_meta_boxes['lp_course']);
139
+
140
+ if ( learn_press_get_user_option( 'course-tabs' ) == 'yes' ) {
141
+ ?>
142
+ <ul id="course-tabs">
143
+ <li id="switch-course-metaboxes">
144
+ <!--<a href="" id="reorder-course-tabs"><?php _e( 'Reorder', 'learnpress' ); ?></a>
145
+ <a href="" id="complete-reorder-course-tabs"><?php _e( 'Ok', 'learnpress' ); ?></a>-->
146
+ <a href="<?php echo add_query_arg( 'switch-course-tabs', 'off', get_edit_post_link() ); ?>"><?php _e( 'Switch to meta boxes', 'learnpress' ); ?></a>
147
+ </li>
148
+ </ul>
149
+ <input type="hidden" id="course-tab" name="course-tab" value="<?php echo !empty( $_REQUEST['tab'] ) ? $_REQUEST['tab'] : ''; ?>" />
150
+
151
+ <?php
152
+ } else {
153
+ if ( learn_press_get_user_option( 'hide-notice-switch-course-tabs' ) != 'yes' ) {
154
+ ?>
155
+ <div class="message updated learn-press-message">
156
+ <p><?php _e( 'Would you like to see the meta boxes in tabs style?', 'learnpress' ); ?></p>
157
+ <p>
158
+ <a class="button" href="<?php echo add_query_arg( 'switch-course-tabs', 'on', get_edit_post_link() ); ?>"><?php _e( 'Switch meta boxes to tabs', 'learnpress' ); ?></a>
159
+ <a class="button" href="<?php echo add_query_arg( 'lp-hide-notice', 'switch-course-tabs', get_edit_post_link() ); ?>"><?php _e( 'Hide', 'learnpress' ); ?></a>
160
+ </p>
161
+ <?php printf( '<a href="%s" class="learn-press-admin-notice-dismiss"></a>', add_query_arg( 'lp-hide-notice', 'switch-course-tabs', get_edit_post_link() ) ); ?>
162
+ </div>
163
+ <?php
164
+ }
165
+ ?>
166
+ <a id="toggle-meta-boxes" href=""><?php _e( 'Toggle', 'learnpress' ); ?></a>
167
+ <a id="switch-course-tabs" href="<?php echo add_query_arg( 'switch-course-tabs', 'on', get_edit_post_link() ); ?>"><?php _e( 'Switch to tabs', 'learnpress' ); ?></a>
168
+ <?php
169
+ }
170
+ }
171
+
172
+ public function init_course() {
173
+ if ( $toggle = learn_press_get_request( 'switch-course-tabs' ) ) {
174
+ if ( $toggle == 'off' ) {
175
+ learn_press_delete_user_option( 'course-tabs' );
176
+ } elseif ( $toggle == 'on' ) {
177
+ learn_press_update_user_option( 'course-tabs', 'yes' );
178
+ }
179
+
180
+ $link = get_edit_post_link( learn_press_get_request( 'post' ), 'redirect' );
181
+ wp_redirect( $link );
182
+ exit();
183
+ }
184
+
185
+ add_action( 'edit_form_after_editor', array( $this, 'curriculum_editor' ), 10 );
186
+ if ( learn_press_get_user_option( 'course-tabs' ) == 'yes' ) {
187
+ LP_Assets::add_param( 'enable_course_tabs', 'yes', '__all', 'LP_Settings' );
188
+ add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
189
+ }
190
+ }
191
+
192
+ public function admin_body_class( $classes ) {
193
+ $classes .= ' enable-course-tabs';
194
+ return $classes;
195
+ }
196
+
197
+ public function register_taxonomy() {
198
+ $settings = LP()->settings;
199
+ $category_base = $settings->get( 'course_category_base' );
200
+ register_taxonomy( 'course_category', array( LP_COURSE_CPT ),
201
+ array(
202
+ 'label' => __( 'Course Categories', 'learnpress' ),
203
+ 'labels' => array(
204
+ 'name' => __( 'Course Categories', 'learnpress' ),
205
+ 'menu_name' => __( 'Category', 'learnpress' ),
206
+ 'singular_name' => __( 'Category', 'learnpress' ),
207
+ 'add_new_item' => __( 'Add New Course Category', 'learnpress' ),
208
+ 'all_items' => __( 'All Categories', 'learnpress' )
209
+ ),
210
+ 'query_var' => true,
211
+ 'public' => true,
212
+ 'hierarchical' => true,
213
+ 'show_ui' => true,
214
+ 'show_in_menu' => 'learn_press',
215
+ 'show_admin_column' => true,
216
+ 'show_in_admin_bar' => true,
217
+ 'show_in_nav_menus' => true,
218
+ 'rewrite' => array(
219
+ 'slug' => empty( $category_base ) ? _x( 'course-category', 'slug', 'learnpress' ) : $category_base,
220
+ 'hierarchical' => true,
221
+ 'with_front' => false
222
+ ),
223
+ )
224
+ );
225
+
226
+ $tag_base = $settings->get( 'course_tag_base' );
227
+ register_taxonomy( 'course_tag', array( LP_COURSE_CPT ),
228
+ array(
229
+ 'labels' => array(
230
+ 'name' => __( 'Course Tags', 'learnpress' ),
231
+ 'singular_name' => __( 'Tag', 'learnpress' ),
232
+ 'search_items' => __( 'Search Course Tags', 'learnpress' ),
233
+ 'popular_items' => __( 'Popular Course Tags', 'learnpress' ),
234
+ 'all_items' => __( 'All Course Tags', 'learnpress' ),
235
+ 'parent_item' => null,
236
+ 'parent_item_colon' => null,
237
+ 'edit_item' => __( 'Edit Course Tag', 'learnpress' ),
238
+ 'update_item' => __( 'Update Course Tag', 'learnpress' ),
239
+ 'add_new_item' => __( 'Add New Course Tag', 'learnpress' ),
240
+ 'new_item_name' => __( 'New Course Tag Name', 'learnpress' ),
241
+ 'separate_items_with_commas' => __( 'Separate tags with commas', 'learnpress' ),
242
+ 'add_or_remove_items' => __( 'Add or remove tags', 'learnpress' ),
243
+ 'choose_from_most_used' => __( 'Choose from the most used tags', 'learnpress' ),
244
+ 'menu_name' => __( 'Tags', 'learnpress' ),
245
+ ),
246
+ 'public' => true,
247
+ 'hierarchical' => false,
248
+ 'show_ui' => true,
249
+ 'show_in_menu' => 'learn_press',
250
+ 'update_count_callback' => '_update_post_term_count',
251
+ 'query_var' => true,
252
+ 'rewrite' => array(
253
+ 'slug' => empty( $tag_base ) ? _x( 'course-tag', 'slug', 'learnpress' ) : $tag_base,
254
+ 'with_front' => false
255
+ ),
256
+ )
257
+ );
258
+ }
259
+
260
+ public function update_course( $course_id ) {
261
+ global $wpdb;
262
+ $course_origin_author = get_post_field( 'post_author', $course_id );
263
+
264
+ if ( !empty( $_POST['_lp_course_author'] ) ) {
265
+ $wpdb->update(
266
+ $wpdb->posts,
267
+ array( 'post_author' => $_POST['_lp_course_author'] ),
268
+ array( 'ID' => $course_id )
269
+ );
270
+ } elseif ( !( $course_author = get_post_meta( $course_id, '_lp_course_author', true ) ) || !get_user_by( 'id', $course_author ) ) {
271
+ update_post_meta( $course_id, '_lp_course_author', $course_author );
272
+ $_POST['_lp_course_author'] = $_REQUEST['_lp_course_author'] = $course_origin_author;
273
+ }
274
+ }
275
+
276
+ function admin_script() {
277
+ global $post_type;
278
+ if ( $post_type != 'lp_course' ) {
279
+ return;
280
+ }
281
+ wp_enqueue_script( 'course-editor', LP()->js( 'admin/course-editor' ), array( 'jquery', 'backbone', 'wp-util', 'jquery-ui-sortable' ) );
282
+ wp_enqueue_style( 'course-editor', LP()->css( 'admin/course-editor' ) );
283
+
284
+ }
285
+
286
+ function course_editor() {
287
+ global $post_type;
288
+ if ( $post_type != 'lp_course' ) {
289
+ return;
290
+ }
291
+ learn_press_admin_view( 'meta-boxes/course/editor' );
292
+ }
293
+
294
+ /**
295
+ * Delete all questions assign to quiz being deleted
296
+ *
297
+ * @param $post_id
298
+ */
299
+ public function delete_course_sections( $post_id ) {
300
+ global $wpdb;
301
+ // delete all items in section first
302
+ $section_ids = $wpdb->get_col( $wpdb->prepare( "SELECT section_id FROM {$wpdb->prefix}learnpress_sections WHERE section_course_id = %d", $post_id ) );
303
+ if ( $section_ids ) {
304
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}learnpress_section_items WHERE %d AND section_id IN(" . join( ',', $section_ids ) . ")", 1 ) );
305
+ learn_press_reset_auto_increment( 'learnpress_section_items' );
306
+
307
+ }
308
+
309
+ // delete all sections
310
+ $query = $wpdb->prepare( "
311
+ DELETE FROM {$wpdb->prefix}learnpress_sections
312
+ WHERE section_course_id = %d
313
+ ", $post_id );
314
+ $wpdb->query( $query );
315
+ learn_press_reset_auto_increment( 'learnpress_sections' );
316
+ }
317
+
318
+
319
+ /**
320
+ * Process request actions on post.php loaded
321
+ */
322
+ public function post_actions() {
323
+ $post_id = learn_press_get_request( 'post_ID' );
324
+ if ( empty( $post_id ) ) {
325
+ $post_id = learn_press_get_request( 'post' );
326
+ }
327
+ if ( empty( $post_id ) ) {
328
+ return;
329
+ }
330
+ if ( self::$_enable_review ) {
331
+ if ( !empty( $_POST ) && learn_press_get_current_user()->is_instructor() && 'yes' == get_post_meta( $post_id, '_lp_submit_for_reviewer', true ) ) {
332
+ LP_Admin_Notice::add_redirect( __( 'Sorry! You can not update a course while it is viewing!', 'learnpress' ), 'error' );
333
+ wp_redirect( admin_url( 'post.php?post=' . $post_id . '&action=edit' ) );
334
+ exit();
335
+ }
336
+ }
337
+ $delete_log = learn_press_get_request( 'delete_log' );
338
+ // ensure that user can do this
339
+ if ( $delete_log && current_user_can( 'delete_others_lp_courses' ) ) {
340
+ $nonce = learn_press_get_request( '_wpnonce' );
341
+ if ( wp_verify_nonce( $nonce, 'delete_log_' . $post_id . '_' . $delete_log ) ) {
342
+ global $wpdb;
343
+ $table = $wpdb->prefix . 'learnpress_review_logs';
344
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) === $table ) {
345
+ $wpdb->query(
346
+ $wpdb->prepare( "
347
+ DELETE FROM {$table}
348
+ WHERE review_log_id = %d
349
+ ", $delete_log )
350
+ );
351
+ }
352
+ wp_redirect( admin_url( 'post.php?post=' . learn_press_get_request( 'post' ) . '&action=edit' ) );
353
+ exit();
354
+ }
355
+ }
356
+ }
357
+
358
+ /**
359
+ * Toggle course description editor
360
+ *
361
+ * @param $post
362
+ */
363
+ public function toggle_editor_button( $post ) {
364
+ if ( $post->post_type == LP_COURSE_CPT ) {
365
+ ?>
366
+ <button class="button button-primary"
367
+ data-hidden="<?php echo get_post_meta( $post->ID, '_lp_editor_hidden', true ); ?>" type="button"
368
+ id="learn-press-button-toggle-editor"><?php _e( 'Toggle Course Content', 'learnpress' ); ?></button>
369
+ <?php
370
+ }
371
+ }
372
+
373
+ /**
374
+ * Generate params for course used in admin
375
+ *
376
+ * @static
377
+ * @return mixed
378
+ */
379
+ public
380
+ function admin_params() {
381
+ global $post;
382
+ return apply_filters( 'learn_press_admin_course_params',
383
+ array(
384
+ 'id' => absint( $post->ID ),
385
+ 'notice_empty_title' => __( 'Please enter the title of the course', 'learnpress' ),
386
+ 'notice_empty_section' => __( 'Please add at least one section for the course', 'learnpress' ),
387
+ 'notice_empty_section_name' => __( 'Please enter the title of the section', 'learnpress' ),
388
+ 'notice_empty_price' => __( 'Please set a price for this course', 'learnpress' )
389
+ )
390
+ );
391
+ }
392
+
393
+ /**
394
+ * Enqueue scripts
395
+ *
396
+ * @static
397
+ */
398
+ public
399
+ function admin_scripts() {
400
+ global $post;
401
+
402
+ $user = learn_press_get_current_user();
403
+ LP_Assets::add_localize(
404
+ array(
405
+ 'notice_remove_section_item' => __( 'Are you sure you want to remove this item?', 'learnpress' ),
406
+ 'user_warning_course_publish_to_pending' => __( 'You course will become to Pending', 'learnpress' ),
407
+ 'user_warning_can_not_submit_course' => __( 'Your course is pending for reviewing', 'learnpress' )
408
+ ),
409
+ null,
410
+ 'learn-press-mb-course'
411
+ );
412
+ if ( get_post_type() == LP_COURSE_CPT && self::$_enable_review && !$this->_is_archive() ) {
413
+ LP_Assets::add_param( 'required_review', LP()->settings->get( 'required_review' ) == 'yes', 'learn-press-mb-course', 'LP_Settings' );
414
+ LP_Assets::add_param( 'enable_edit_published', LP()->settings->get( 'enable_edit_published' ) == 'yes', 'learn-press-mb-course', 'LP_Settings' );
415
+ LP_Assets::add_param( 'course_status', get_post_status(), 'learn-press-mb-course', 'LP_Settings' );
416
+ LP_Assets::add_param( 'edited_user', learn_press_get_current_user_id(), 'learn-press-mb-course', 'LP_Settings' );
417
+ LP_Assets::add_param( 'current_user', $post->post_author, 'learn-press-mb-course', 'LP_Settings' );
418
+ LP_Assets::add_param( 'current_user_type', $user->is_admin() ? 'admin' : 'instructor', 'learn-press-mb-course', 'LP_Settings' );
419
+ LP_Assets::add_param( 'pending_review', get_post_meta( $post->ID, '_lp_submit_for_reviewer', true ) == 'yes', 'learn-press-mb-course', 'LP_Settings' );
420
+
421
+ }
422
+ if ( in_array( get_post_type(), array( LP_COURSE_CPT, LP_LESSON_CPT ) ) ) {
423
+ wp_enqueue_script( 'jquery-caret', LP()->plugin_url( 'assets/js/jquery.caret.js', 'jquery' ) );
424
+ wp_localize_script( 'lp-meta-boxes', 'lp_course_params', self::admin_params() );
425
+ }
426
+ }
427
+
428
+ /**
429
+ * Print js template
430
+ */
431
+ public
432
+ function print_js_template() {
433
+ if ( get_post_type() != LP_COURSE_CPT ) return;
434
+ learn_press_admin_view( 'meta-boxes/course/js-template.php' );
435
+ }
436
+
437
+ public
438
+ function currency_symbol( $input_html, $field, $sub_meta ) {
439
+ return $input_html . '<span class="lpr-course-price-symbol">' . learn_press_get_currency_symbol() . '</span>';
440
+ }
441
+
442
+ /**
443
+ * Register course post type
444
+ */
445
+ public
446
+ function register() {
447
+ $settings = LP_Settings::instance();
448
+ $labels = array(
449
+ 'name' => _x( 'Courses', 'Post Type General Name', 'learnpress' ),
450
+ 'singular_name' => _x( 'Course', 'Post Type Singular Name', 'learnpress' ),
451
+ 'menu_name' => __( 'Courses', 'learnpress' ),
452
+ 'parent_item_colon' => __( 'Parent Item:', 'learnpress' ),
453
+ 'all_items' => __( 'Courses', 'learnpress' ),
454
+ 'view_item' => __( 'View Course', 'learnpress' ),
455
+ 'add_new_item' => __( 'Add New Course', 'learnpress' ),
456
+ 'add_new' => __( 'Add New', 'learnpress' ),
457
+ 'edit_item' => __( 'Edit Course', 'learnpress' ),
458
+ 'update_item' => __( 'Update Course', 'learnpress' ),
459
+ 'search_items' => __( 'Search Courses', 'learnpress' ),
460
+ 'not_found' => sprintf( __( 'You have not got any courses yet. Click <a href="%s">Add new</a> to start', 'learnpress' ), admin_url( 'post-new.php?post_type=lp_course' ) ),
461
+ 'not_found_in_trash' => __( 'No course found in Trash', 'learnpress' )
462
+ );
463
+ $course_base = $settings->get( 'course_base' );
464
+ $course_permalink = empty( $course_base ) ? _x( 'courses', 'slug', 'learnpress' ) : $course_base;
465
+
466
+ $args = array(
467
+ 'labels' => $labels,
468
+ 'public' => true,
469
+ 'query_var' => true,
470
+ 'publicly_queryable' => true,
471
+ 'show_ui' => true,
472
+ 'has_archive' => 'courses',//( $page_id = learn_press_get_page_id( 'courses' ) ) && get_post( $page_id ) ? get_page_uri( $page_id ) : 'courses',
473
+ 'capability_type' => LP_COURSE_CPT,
474
+ 'map_meta_cap' => true,
475
+ 'show_in_menu' => 'learn_press',
476
+ 'show_in_admin_bar' => true,
477
+ 'show_in_nav_menus' => true,
478
+ 'taxonomies' => array( 'course_category', 'course_tag' ),
479
+ 'supports' => array( 'title', 'editor', 'thumbnail', 'revisions', 'comments', 'excerpt' ),
480
+ 'hierarchical' => false,
481
+ 'rewrite' => $course_permalink ? array(
482
+ 'slug' => untrailingslashit( $course_permalink ),
483
+ 'with_front' => false
484
+ ) : false
485
+ );
486
+ return $args;
487
+ }
488
+
489
+ /**
490
+ * Add meta boxes to course post type page
491
+ */
492
+ public
493
+ function add_meta_boxes() {
494
+
495
+ $user = wp_get_current_user();
496
+ //print_r($user);
497
+
498
+ $post_type_object = get_post_type_object( LP_COURSE_CPT );
499
+ //print_r($post_type_object);
500
+
501
+ if ( !self::$_VER2 ) {
502
+ new RW_Meta_Box( self::curriculum_meta_box() );
503
+ }
504
+
505
+ new RW_Meta_Box( self::settings_meta_box() );
506
+ new RW_Meta_Box( self::assessment_meta_box() );
507
+
508
+ new RW_Meta_Box( self::payment_meta_box() );
509
+
510
+ if ( self::$_enable_review ) {
511
+ $this->review_logs_meta_box();
512
+ }
513
+ //new RW_Meta_Box( self::video_meta_box() );
514
+ if ( is_super_admin() ) {
515
+ new RW_Meta_Box( self::author_meta_box() );
516
+ }
517
+ parent::add_meta_boxes();
518
+ }
519
+
520
+ /**
521
+ * Course curriculum
522
+ *
523
+ * @return mixed|null|void
524
+ */
525
+ public
526
+ static function curriculum_meta_box() {
527
+ $prefix = '_lp_';
528
+
529
+ $meta_box = array(
530
+ 'id' => 'course_curriculum',
531
+ 'title' => __( 'Curriculum', 'learnpress' ),
532
+ 'priority' => 'high',
533
+ 'pages' => array( LP_COURSE_CPT ),
534
+ 'fields' => array(
535
+ array(
536
+ 'name' => __( 'Course Curriculum', 'learnpress' ),
537
+ 'id' => "{$prefix}curriculum",
538
+ 'type' => 'curriculum',
539
+ 'desc' => '',
540
+ ),
541
+ )
542
+ );
543
+
544
+ return apply_filters( 'learn_press_course_curriculum_meta_box_args', $meta_box );
545
+ }
546
+
547
+ /**
548
+ * Course settings
549
+ *
550
+ * @return mixed|null|void
551
+ */
552
+
553
+ public
554
+ static function settings_meta_box() {
555
+ $prefix = '_lp_';
556
+
557
+ $meta_box = array(
558
+ 'id' => 'course_settings',
559
+ 'title' => __( 'General Settings', 'learnpress' ),
560
+ 'pages' => array( LP_COURSE_CPT ),
561
+ 'priority' => 'high',
562
+ 'fields' => array(
563
+ array(
564
+ 'name' => __( 'Duration', 'learnpress' ),
565
+ 'id' => "{$prefix}duration",
566
+ 'type' => 'duration',
567
+ 'desc' => __( 'The duration of the course (by weeks).', 'learnpress' ),
568
+ 'std' => '10 weeks'
569
+ ),
570
+ array(
571
+ 'name' => __( 'Maximum students', 'learnpress' ),
572
+ 'id' => "{$prefix}max_students",
573
+ 'type' => 'number',
574
+ 'desc' => __( 'Maximum number of students who can enroll in this course.', 'learnpress' ),
575
+ 'std' => 1000,
576
+ ),
577
+ array(
578
+ 'name' => __( 'Students enrolled', 'learnpress' ),
579
+ 'id' => "{$prefix}students",
580
+ 'type' => 'number',
581
+ 'desc' => __( 'How many students have taken this course.', 'learnpress' ),
582
+ 'std' => 0,
583
+ ),
584
+ array(
585
+ 'name' => __( 'Re-take course', 'learnpress' ),
586
+ 'id' => "{$prefix}retake_count",
587
+ 'type' => 'number',
588
+ 'desc' => __( 'How many times the user can re-take this course. Set to 0 to disable.', 'learnpress' ),
589
+ 'std' => 0,
590
+ ),
591
+ array(
592
+ 'name' => __( 'Featured', 'learnpress' ),
593
+ 'id' => "{$prefix}featured",
594
+ 'type' => 'yes_no',
595
+ 'desc' => __( 'Set course as featured.', 'learnpress' ),
596
+ 'std' => 'no',
597
+ )
598
+ )
599
+ );
600
+
601
+ return apply_filters( 'learn_press_course_settings_meta_box_args', $meta_box );
602
+ }
603
+
604
+ /**
605
+ * Course assessment
606
+ *
607
+ * @return mixed|null|void
608
+ */
609
+ public
610
+ static function assessment_meta_box() {
611
+ $post_id = learn_press_get_request( 'post' );
612
+ $prefix = '_lp_';
613
+ $course_result_desc = __( 'The method to assess the result of a student for a course.', 'learnpress' );
614
+ if ( $post_id && get_post_meta( $post_id, '_lp_course_result', true ) == 'evaluate_final_quiz' && !get_post_meta( $post_id, '_lp_final_quiz', true ) ) {
615
+ $course_result_desc .= __( '<br /><strong>Note! </strong>No final quiz in course, please add a final quiz', 'learnpress' );
616
+ }
617
+ $meta_box = array(
618
+ 'id' => 'course_assessment',
619
+ 'title' => __( 'Assessment', 'learnpress' ),
620
+ 'priority' => 'high',
621
+ 'pages' => array( LP_COURSE_CPT ),
622
+ 'fields' => array(
623
+ array(
624
+ 'name' => __( 'Course result', 'learnpress' ),
625
+ 'id' => "{$prefix}course_result",
626
+ 'type' => 'radio',
627
+ 'desc' => $course_result_desc,
628
+ 'options' => array(
629
+ 'evaluate_lesson' => __( 'Evaluate lessons', 'learnpress' ),
630
+ 'evaluate_quizzes' => __( 'Evaluate result of quizzes', 'learnpress' ),
631
+ 'evaluate_final_quiz' => __( 'Evaluate the result of the final quiz', 'learnpress' )
632
+ ),
633
+ 'std' => 'evaluate_lesson',
634
+ ),
635
+ array(
636
+ 'name' => __( 'Passing condition value', 'learnpress' ),
637
+ 'id' => "{$prefix}passing_condition",
638
+ 'type' => 'number',
639
+ 'min' => 1,
640
+ 'max' => 100,
641
+ 'desc' => __( 'The percentage of quiz result or lessons completed to finish the course.', 'learnpress' ),
642
+ 'std' => 80,
643
+ )
644
+ )
645
+ );
646
+ return apply_filters( 'learn_press_course_assessment_metabox', $meta_box );
647
+ }
648
+
649
+ /**
650
+ * Course payment
651
+ *
652
+ * @return mixed|null|void
653
+ */
654
+ public
655
+ static function payment_meta_box() {
656
+
657
+ $course_id = !empty( $_GET['post'] ) ? $_GET['post'] : 0;
658
+ $prefix = '_lp_';
659
+
660
+ $meta_box = array(
661
+ 'id' => 'course_payment',
662
+ 'title' => __( 'Payment Settings', 'learnpress' ),
663
+ 'priority' => 'high',
664
+ 'pages' => array( LP_COURSE_CPT ),
665
+ 'fields' => array(
666
+ array(
667
+ 'name' => __( 'Course payment', 'learnpress' ),
668
+ 'id' => "{$prefix}payment",
669
+ 'type' => 'yes_no',
670
+ 'desc' => __( '', 'learnpress' ),
671
+ 'std' => 'no',
672
+ 'class' => 'lp-course-payment-field'
673
+ )
674
+ )
675
+ );
676
+
677
+ $payment = get_post_meta( $course_id, '_lp_payment', true );
678
+
679
+ if ( current_user_can( 'manage_options' ) ) {
680
+ // $message = __( 'If free, this field is empty or set 0. (Only admin can edit this field)', 'learnpress' );
681
+ $message = '';
682
+ $price = get_post_meta( $course_id, '_lp_price', true );
683
+ $sale_price = 0;
684
+ $start_date = '';
685
+ $end_date = '';
686
+
687
+ if ( isset( $_GET['post'] ) ) {
688
+ $course_id = $_GET['post'];
689
+
690
+ if ( $payment != 'free' ) {
691
+ $suggest_price = get_post_meta( $course_id, '_lp_suggestion_price', true );
692
+ $course = get_post( $course_id );
693
+
694
+ $author = get_userdata( $course->post_author ) ;
695
+
696
+ if ( isset( $suggest_price ) && $author->roles[0] === 'lp_teacher' ) {
697
+ $message = sprintf( __( 'This course is requires enrollment and the suggested price is <strong>%s</strong>', 'learnpress' ), learn_press_format_price( $suggest_price, true ) );
698
+ $price = $suggest_price;
699
+ }
700
+
701
+ $sale_price = get_post_meta( $course_id, '_lp_sale_price', true );
702
+ $start_date = get_post_meta( $course_id, '_lp_sale_start', true );
703
+ $end_date = get_post_meta( $course_id, '_lp_sale_end', true );
704
+ } else {
705
+ $message = __( 'This course is free.', 'learnpress' );
706
+ };
707
+ }
708
+ array_push(
709
+ $meta_box['fields'],
710
+ array(
711
+ 'name' => __( 'Price', 'learnpress' ),
712
+ 'id' => "{$prefix}price",
713
+ 'type' => 'number',
714
+ 'min' => 0.01,
715
+ 'step' => 0.01,
716
+ 'desc' => $message,
717
+ 'std' => $price,
718
+ 'class' => 'lp-course-price-field' . ( $payment != 'yes' ? ' hide-if-js' : '' )
719
+ ),
720
+ array(
721
+ 'name' => __( 'Sale Price', 'learnpress' ),
722
+ 'id' => "{$prefix}sale_price",
723
+ 'type' => 'number',
724
+ 'min' => 0,
725
+ 'step' => 0.01,
726
+ 'desc' => '<a href="#" id="' . $prefix . 'sale_price_schedule">' . __( 'Schedule', 'learnpress' ) . '</a>',
727
+ 'std' => $sale_price,
728
+ 'class' => 'lp-course-price-field lp-course-sale_price-field' . ( $payment != 'yes' ? ' hide-if-js' : '' )
729
+ ),
730
+ array(
731
+ 'name' => __( 'Sale start date', 'learnpress' ),
732
+ 'id' => "{$prefix}sale_start",
733
+ 'type' => 'datetime',
734
+ 'std' => $start_date,
735
+ 'class' => 'lp-course-sale_start-field hide'
736
+ ),
737
+ array(
738
+ 'name' => __( 'Sale end date', 'learnpress' ),
739
+ 'id' => "{$prefix}sale_end",
740
+ 'type' => 'datetime',
741
+ 'desc' => '<a href="#" id="' . $prefix . 'sale_price_schedule_cancel">' . __( 'Cancel', 'learnpress' ) . '</a>',
742
+ 'std' => $end_date,
743
+ 'class' => 'lp-course-sale_end-field hide'
744
+ )
745
+ );
746
+ } else {
747
+ $price = get_post_meta( $course_id, '_lp_price', true );
748
+ $meta_box['fields'][] = array(
749
+ 'name' => __( 'Price set by Admin', 'learnpress' ),
750
+ 'id' => "{$prefix}price",
751
+ 'type' => 'html',
752
+ 'class' => 'lp-course-price-field' . ( $payment != 'yes' ? ' hide-if-js' : '' ),
753
+ 'html' => $price !== '' ? sprintf( '<strong>%s</strong>', learn_press_format_price( $price, true ) ) : __( 'Not set', 'learnpress' )
754
+ );
755
+ $meta_box['fields'][] = array(
756
+ 'name' => __( 'Course Suggestion Price', 'learnpress' ),
757
+ 'id' => "{$prefix}suggestion_price",
758
+ 'type' => 'number',
759
+ 'min' => 0,
760
+ 'step' => 0.01,
761
+ 'desc' => __( 'The course price you want to suggest for admin to set.', 'learnpress' ),
762
+ 'class' => 'lp-course-price-field' . ( $payment != 'yes' ? ' hide-if-js' : '' ),
763
+ 'std' => 0
764
+ );
765
+
766
+ }
767
+ $meta_box['fields'] = array_merge(
768
+ $meta_box['fields'],
769
+ array(
770
+ array(
771
+ 'name' => __( 'Requires enroll', 'learnpress' ),
772
+ 'id' => "{$prefix}required_enroll",
773
+ 'type' => 'yes_no',
774
+ 'desc' => __( 'Require users logged in to study or public to all.', 'learnpress' ),
775
+ 'std' => 'yes',
776
+ 'class' => 'lp-course-required-enroll' . ( ( $payment == 'yes' ) ? ' hide-if-js' : '' )
777
+ )
778
+ )
779
+ );
780
+ return apply_filters( 'learn_press_course_payment_meta_box_args', $meta_box );
781
+ }
782
+
783
+ /**
784
+ * Course author
785
+ *
786
+ * @return mixed|null|void
787
+ */
788
+ public
789
+ static function author_meta_box() {
790
+
791
+ $prefix = '_lp_';
792
+
793
+ $include = array();
794
+ $role = array( 'administrator', 'lp_teacher' );
795
+
796
+ $role = apply_filters( 'learn_press_course_author_role_meta_box', $role );
797
+
798
+ foreach ( $role as $_role ) {
799
+ $users_by_role = get_users( array( 'role' => $_role ) );
800
+ if ( $users_by_role ) {
801
+ foreach ( $users_by_role as $user ) {
802
+ $include[$user->ID] = $user->user_login;
803
+ }
804
+ }
805
+ }
806
+
807
+ $meta_box = array(
808
+ 'id' => 'course_authors',
809
+ 'title' => __( 'Author Settings', 'learnpress' ),
810
+ 'pages' => array( LP_COURSE_CPT ),
811
+ 'priority' => 'default',
812
+ 'fields' => array(
813
+ array(
814
+ 'name' => __( 'Author', 'learnpress' ),
815
+ 'id' => "{$prefix}course_author",
816
+ 'desc' => '',
817
+ 'multiple' => false,
818
+ 'allowClear' => false,
819
+ 'type' => 'select_advanced',
820
+ 'placeholder' => __( 'Select author', 'learnpress' ),
821
+ 'options' => $include
822
+ )
823
+ )
824
+ );
825
+
826
+ return apply_filters( 'learn_press_course_author_meta_box', $meta_box );
827
+
828
+ }
829
+
830
+ /**
831
+ * Course review logs
832
+ *
833
+ */
834
+ public
835
+ function review_logs_meta_box() {
836
+ add_meta_box(
837
+ 'review_logs',
838
+ __( 'Review Logs', 'learnpress' ),
839
+ array( $this, 'review_logs_content' ),
840
+ LP_COURSE_CPT,
841
+ 'normal',
842
+ 'default'
843
+ );
844
+ }
845
+
846
+ /**
847
+ * Display view for listing logs
848
+ *
849
+ * @param $post
850
+ */
851
+ public
852
+ function review_logs_content( $post ) {
853
+ global $wpdb;
854
+ $view_all = learn_press_get_request( 'view_all_review' );
855
+ $table = $wpdb->prefix . 'learnpress_review_logs';
856
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) === $table ) {
857
+ $query = $wpdb->prepare( "
858
+ SELECT SQL_CALC_FOUND_ROWS *
859
+ FROM {$wpdb->learnpress_review_logs}
860
+ WHERE course_id = %d
861
+ ORDER BY `date` DESC"
862
+ . ( $view_all ? "" : " LIMIT 0, 10" ) . "
863
+ ", $post->ID );
864
+ $reviews = $wpdb->get_results( $query );
865
+ $total_reviews = $wpdb->get_var( "SELECT FOUND_ROWS()" );
866
+ $count_reviews = sizeof( $reviews );
867
+
868
+ $view = learn_press_get_admin_view( 'meta-boxes/course/review-logs.php' );
869
+ include $view;
870
+ }
871
+ }
872
+
873
+ /**
874
+ *
875
+ */
876
+ public
877
+ function save() {
878
+
879
+ }
880
+
881
+ /**
882
+ * Insert new section into database
883
+ *
884
+ * @param array $section
885
+ *
886
+ * @return array|mixed|string
887
+ */
888
+ private
889
+ function _insert_section( $section = array() ) {
890
+ global $wpdb;
891
+ $section = wp_parse_args(
892
+ $section,
893
+ array(
894
+ 'section_name' => '',
895
+ 'section_course_id' => 0,
896
+ 'section_order' => 0,
897
+ 'section_description' => ''
898
+ )
899
+ );
900
+ $section = stripslashes_deep( $section );
901
+ extract( $section );
902
+
903
+ $insert_data = compact( 'section_name', 'section_course_id', 'section_order', 'section_description' );
904
+ $wpdb->insert(
905
+ $wpdb->learnpress_sections,
906
+ $insert_data,
907
+ array( '%s', '%d', '%d' )
908
+ );
909
+ $section['section_id'] = $wpdb->insert_id;
910
+ return $section;
911
+ }
912
+
913
+ /**
914
+ * @param array $item
915
+ *
916
+ * @return array
917
+ */
918
+ private
919
+ function _insert_item( $item = array() ) {
920
+ $_post = $this->_cleanPostData();
921
+
922
+ $item_id = wp_insert_post(
923
+ array(
924
+ 'post_title' => $item['post_title'],
925
+ 'post_type' => $item['post_type'],
926
+ 'post_status' => 'publish'
927
+ )
928
+ );
929
+ $item['ID'] = $item_id;
930
+
931
+ $this->_resetPostData( $_post );
932
+
933
+ return $item;
934
+ }
935
+
936
+ private
937
+ function _cleanPostData() {
938
+ $_post = $_POST;
939
+ if ( $_POST ) {
940
+ foreach ( $_POST as $k => $v ) {
941
+ unset( $_POST[$k] );
942
+ }
943
+ }
944
+ return $_post;
945
+ }
946
+
947
+ private
948
+ function _resetPostData( $_post ) {
949
+ if ( $_post ) {
950
+ foreach ( $_post as $k => $v ) {
951
+ $_POST[$k] = $v;
952
+ }
953
+ }
954
+ return $_POST;
955
+ }
956
+
957
+ /*
958
+ * Delete all sections in a course and reset auto increment
959
+ */
960
+ private
961
+ function _reset_sections() {
962
+ global $wpdb, $post;
963
+
964
+ $wpdb->query(
965
+ $wpdb->prepare( "
966
+ DELETE FROM si
967
+ USING {$wpdb->learnpress_section_items} si
968
+ INNER JOIN {$wpdb->learnpress_sections} s ON s.section_id = si.section_id
969
+ INNER JOIN {$wpdb->posts} p ON p.ID = s.section_course_id
970
+ WHERE p.ID = %d
971
+ ", $post->ID )
972
+ );
973
+ $wpdb->query( "
974
+ ALTER TABLE {$wpdb->learnpress_section_items} AUTO_INCREMENT = 1
975
+ " );
976
+
977
+ $wpdb->query(
978
+ $wpdb->prepare( "
979
+ DELETE FROM {$wpdb->learnpress_sections}
980
+ WHERE section_course_id = %d
981
+ ", $post->ID )
982
+ );
983
+ $wpdb->query( "
984
+ ALTER TABLE {$wpdb->learnpress_sections} AUTO_INCREMENT = 1
985
+ " );
986
+ }
987
+
988
+ public
989
+ function _save() {
990
+ global $wpdb, $post;
991
+
992
+ $preview = filter_input( INPUT_POST, 'wp-preview', FILTER_SANITIZE_STRING );
993
+
994
+ if ( 'dopreview' == $preview && 'draft' == $post->post_status ) {
995
+ learn_press_add_message( __( 'Course Curriculum only appear if course is saved', 'learnpress' ), $type );
996
+ }
997
+
998
+ $this->_reset_sections();
999
+
1000
+ if ( !empty( $_REQUEST['_lp_curriculum'] ) && 'dopreview' !== $preview ) {
1001
+ $section_order = 0;
1002
+ $query_update = array();
1003
+ $update_ids = array();
1004
+ $query_insert = array();
1005
+ foreach ( $_REQUEST['_lp_curriculum'] as $section_id => $_section ) {
1006
+ $section_id = 0;
1007
+ // section items
1008
+ $items = $_section['items'];
1009
+ $item_order = 0;
1010
+ $insert = false;
1011
+ $sql_section_items = array();
1012
+ if ( !empty( $items ) ) {
1013
+ foreach ( $items as $section_item_id => $_item ) {
1014
+
1015
+ // abort the item has not got a name
1016
+ if ( !$_item['name'] )
1017
+ continue;
1018
+ $insert = true;
1019
+
1020
+ $item_id = $_item['item_id'];
1021
+
1022
+ // if item has not got the ID then insert a new one
1023
+ if ( !$item_id ) {
1024
+ $item = $this->_insert_item(
1025
+ array(
1026
+ 'post_title' => $_item['name'],
1027
+ 'post_type' => $_item['post_type'],
1028
+ )
1029
+ );
1030
+ $item_id = $item['ID'];
1031
+ } else { // Otherwise, update existing
1032
+ if ( strcmp( $_item['name'], $_item['old_name'] ) !== 0 ) {
1033
+ $query_update[] = 'WHEN ' . $_item['item_id'] . ' THEN \'' . $_item['name'] . '\'';
1034
+ $update_ids[] = $_item['item_id'];
1035
+ $update_data = array(
1036
+ 'ID' => $_item['item_id'],
1037
+ 'post_title' => $_item['name']
1038
+ );
1039
+ // prevent update the meta of course for the items when update items
1040
+ $_post = $this->_cleanPostData();
1041
+ wp_update_post( $update_data );
1042
+ $this->_resetPostData( $_post );
1043
+ }
1044
+ $item_id = $_item['item_id'];
1045
+ }
1046
+ $sql_section_items[] = $wpdb->prepare( "(%d, %d, %d, %s)", - 9999999, $item_id, ++ $item_order, $_item['post_type'] );
1047
+ }
1048
+ }
1049
+
1050
+ if ( $insert || ( !$insert && ( !empty( $_section['name'] ) || empty( $items ) ) ) ) {
1051
+ $section = array(
1052
+ 'section_name' => !empty( $_section['name'] ) ? $_section['name'] : '',
1053
+ 'section_course_id' => $post->ID,
1054
+ 'section_order' => ++ $section_order,
1055
+ 'section_description' => $_section['description'],
1056
+ 'items' => array()
1057
+ );
1058
+
1059
+ if ( !$section_id ) {
1060
+ $section = $this->_insert_section( $section );
1061
+ $section_id = $section['section_id'];
1062
+ }
1063
+ $sections[$section_id] = $section;
1064
+ foreach ( $sql_section_items as $section_item ) {
1065
+ $query_insert[] = str_replace( - 9999999, $section_id, $section_item );
1066
+ }
1067
+ }
1068
+ }
1069
+ if ( $query_insert ) {
1070
+ $query_insert = "
1071
+ INSERT INTO {$wpdb->learnpress_section_items}(`section_id`, `item_id`, `item_order`, `item_type`)
1072
+ VALUES " . join( ', ', $query_insert ) . "
1073
+ ";
1074
+ $wpdb->query( $query_insert );
1075
+ }
1076
+ if ( $query_update ) {
1077
+ $query_update = "
1078
+ UPDATE {$wpdb->posts}
1079
+ SET
1080
+ `post_title` = CASE `ID` " . join( ' ', $query_update ) . " END
1081
+ WHERE
1082
+ ID IN (" . join( ',', $update_ids ) . ")
1083
+ ";
1084
+ $wpdb->query( $query_update );
1085
+ }
1086
+ }
1087
+ }
1088
+
1089
+ private
1090
+ function _update_final_quiz() {
1091
+ global $post;
1092
+ $final_quiz = false;
1093
+
1094
+ if ( learn_press_get_request( '_lp_course_result' ) == 'evaluate_final_quiz' ) {
1095
+ if ( $final_quiz = learn_press_get_final_quiz( $post->ID ) ) {
1096
+ update_post_meta( $post->ID, '_lp_final_quiz', $final_quiz );
1097
+ } else {
1098
+ delete_post_meta( $post->ID, '_lp_final_quiz' );
1099
+ }
1100
+ } else {
1101
+ delete_post_meta( $post->ID, '_lp_final_quiz' );
1102
+ }
1103
+ do_action( 'learn_press_update_final_quiz', $final_quiz, $post->ID );
1104
+ return $final_quiz;
1105
+ }
1106
+
1107
+ private
1108
+ function _send_mail() {
1109
+ if ( !LP()->user->is_instructor() ) return;
1110
+ $mail = LP()->mail;
1111
+
1112
+ }
1113
+
1114
+ private
1115
+ function _review_log() {
1116
+ global $wpdb, $post;
1117
+ $user = learn_press_get_current_user();
1118
+ $action = '';
1119
+ $old_status = $post->post_status;
1120
+ $new_status = get_post_status( $post->ID );
1121
+ $required_review = LP()->settings->get( 'required_review' ) == 'yes';
1122
+ $enable_edit_published = LP()->settings->get( 'enable_edit_published' ) == 'yes';
1123
+
1124
+ $submit_for_review = learn_press_get_request( 'learn-press-submit-for-review' ) == 'yes' || ( ( !$required_review || $enable_edit_published ) );
1125
+ // If course is submitted by administrator
1126
+ if ( $user->is_admin() ) {
1127
+ if ( $old_status != $new_status ) {
1128
+ if ( $new_status == 'publish' ) {
1129
+ $action = 'approved';
1130
+ } elseif ( $new_status != 'publish' ) {
1131
+ $action = 'rejected';
1132
+ }
1133
+ delete_post_meta( $post->ID, '_lp_submit_for_reviewer', 'yes' );
1134
+ }
1135
+ } elseif ( $user->is_instructor() ) { // Course is submitted by instructor
1136
+
1137
+ if ( $enable_edit_published && ( $old_status == $new_status && $new_status == 'publish' ) ) {
1138
+ $submit_for_review = false;
1139
+ }
1140
+ if ( ( $submit_for_review || ( $old_status != $new_status ) ) && $post->post_status != 'auto-draft' ) {
1141
+ $action = 'for_reviewer';
1142
+ update_post_meta( $post->ID, '_lp_submit_for_reviewer', 'yes' );
1143
+ }
1144
+ }
1145
+ $message = learn_press_get_request( 'review-message' );
1146
+ if ( !$action && !$message ) {
1147
+ return;
1148
+ }
1149
+
1150
+ switch ( $action ) {
1151
+ case 'approved':
1152
+ if ( !$message ) {
1153
+ $message = __( 'Course has approved by Reviewer', 'learnpress' );
1154
+ }
1155
+ break;
1156
+ case 'rejected':
1157
+ if ( !$message ) {
1158
+ $message = __( 'Course has rejected by Reviewer', 'learnpress' );
1159
+ }
1160
+ break;
1161
+ case 'for_reviewer':
1162
+ if ( !$message ) {
1163
+ $message = sprintf( __( 'Course has submitted by %s', 'learnpress' ), learn_press_get_profile_display_name( $user ) );
1164
+ }
1165
+ break;
1166
+ default:
1167
+ if ( !$message ) {
1168
+ $message = __( 'Course has updated by Reviewer', 'learnpress' );
1169
+ }
1170
+ }
1171
+ if ( apply_filters( 'learn_press_review_log_message', $message, $post->ID, $user->id ) ) {
1172
+ $table = $wpdb->prefix . 'learnpress_review_logs';
1173
+ $wpdb->insert(
1174
+ $table,
1175
+ array(
1176
+ 'course_id' => $post->ID,
1177
+ 'user_id' => $user->id,
1178
+ 'message' => $message,
1179
+ 'date' => current_time( 'mysql' ),
1180
+ 'status' => $new_status,
1181
+ 'user_type' => $user->is_admin() ? 'reviewer' : 'instructor'
1182
+ ),
1183
+ array( '%d', '%d', '%s', '%s', '%s', '%s' )
1184
+ );
1185
+ do_action( 'learn_press_update_review_log', $wpdb->insert_id, $post->ID, $user->id );
1186
+ }
1187
+ if ( $action ) {
1188
+ do_action( "learn_press_course_submit_{$action}", $post->ID, $user );
1189
+ }
1190
+
1191
+ return;
1192
+
1193
+ if ( !$action ) {
1194
+ return;
1195
+ }
1196
+
1197
+ /*if ( !$required_review || ( $required_review && $enable_edit_published ) ) {
1198
+ return;
1199
+ }*/
1200
+
1201
+ $user = LP()->user;
1202
+ $message = learn_press_get_request( 'review_message' );
1203
+
1204
+ if ( !$message && !$user->is_instructor() && get_post_status( $post->ID ) == 'publish' ) {
1205
+ $message = __( 'Your course has been published', 'learnpress' );
1206
+ }
1207
+ if ( apply_filters( 'learn_press_review_log_message', $message, $post->ID, $user->id ) ) {
1208
+ $table = $wpdb->prefix . 'learnpress_review_logs';
1209
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) === $table ) {
1210
+ $query = $wpdb->prepare( "
1211
+ INSERT INTO {$wpdb->learnpress_review_logs}(`course_id`, `user_id`, `message`, `date`, `status`, `user_type`)
1212
+ VALUES(%d, %d, %s, %s, %s, %s)
1213
+ ", $post->ID, $user->id, $message, current_time( 'mysql' ), get_post_status( $post->ID ), $user->is_instructor() ? 'instructor' : 'reviewer' );
1214
+ $wpdb->query( $query );
1215
+ do_action( 'learn_press_update_review_log', $wpdb->insert_id, $post->ID, $user->id );
1216
+ }
1217
+ }
1218
+ if ( $action == 'learn_press_course_submit_for_instructor' ) {
1219
+ if ( get_post_status( $post->ID ) == 'publish' ) {
1220
+ do_action( 'learn_press_course_submit_approved', $post->ID, $user );
1221
+ } else {
1222
+ do_action( 'learn_press_course_submit_rejected', $post->ID, $user );
1223
+ }
1224
+ } else {
1225
+ do_action( $action, $post->ID, $user );
1226
+ }
1227
+ }
1228
+
1229
+ public
1230
+ function before_save_curriculum() {
1231
+
1232
+ global $post, $pagenow;
1233
+
1234
+ // Ensure that we are editing course in admin side
1235
+
1236
+ if ( ( $pagenow != 'post.php' ) || ( get_post_type() != LP_COURSE_CPT ) ) {
1237
+ return;
1238
+ }
1239
+
1240
+ remove_action( 'save_post', array( $this, 'before_save_curriculum' ), 1 );
1241
+ //remove_action( 'rwmb_course_curriculum_before_save_post', array( $this, 'before_save_curriculum' ) );
1242
+
1243
+ $user = LP()->user;
1244
+ $required_review = LP()->settings->get( 'required_review' ) == 'yes';
1245
+ $enable_edit_published = LP()->settings->get( 'enable_edit_published' ) == 'yes';
1246
+
1247
+ if ( $user->is_instructor() && $required_review && !$enable_edit_published ) {
1248
+ wp_update_post(
1249
+ array(
1250
+ 'ID' => $post->ID,
1251
+ 'post_status' => 'pending'
1252
+ ),
1253
+ array( '%d', '%s' )
1254
+ );
1255
+
1256
+ }
1257
+
1258
+ $new_status = get_post_status( $post->ID );
1259
+ $old_status = get_post_meta( $post->ID, '_lp_course_status', true );
1260
+
1261
+ $this->_save();
1262
+ $this->_update_final_quiz();
1263
+
1264
+ if ( $new_status != $old_status ) {
1265
+ do_action( 'learn_press_transition_course_status', $new_status, $old_status, $post->ID );
1266
+ update_post_meta( $post->ID, '_lp_course_status', $new_status );
1267
+ }
1268
+
1269
+ $this->_review_log();
1270
+ delete_post_meta( $post->ID, '_lp_curriculum' );
1271
+ //add_action( 'rwmb_course_curriculum_before_save_post', array( $this, 'before_save_curriculum' ) );
1272
+ }
1273
+
1274
+ public
1275
+ static function enqueue_scripts() {
1276
+
1277
+ }
1278
+
1279
+ /**
1280
+ * Add columns to admin manage course page
1281
+ *
1282
+ * @param array $columns
1283
+ *
1284
+ * @return array
1285
+ */
1286
+ public
1287
+ function columns_head( $columns ) {
1288
+ $user = wp_get_current_user();
1289
+ if ( in_array( 'lp_teacher', $user->roles ) ) {
1290
+ unset( $columns['author'] );
1291
+ }
1292
+ $keys = array_keys( $columns );
1293
+ $values = array_values( $columns );
1294
+ $pos = array_search( 'title', $keys );
1295
+ if ( $pos !== false ) {
1296
+ array_splice( $keys, $pos + 1, 0, array( 'author', 'sections', 'students', 'price' ) );
1297
+ array_splice( $values, $pos + 1, 0, array(
1298
+ __( 'Author', 'learnpress' ),
1299
+ __( 'Content', 'learnpress' ),
1300
+ __( 'Students', 'learnpress' ),
1301
+ __( 'Price', 'learnpress' ) ) );
1302
+ $columns = array_combine( $keys, $values );
1303
+ } else {
1304
+ $columns['author'] = __( 'Author', 'learnpress' );
1305
+ $columns['sections'] = __( 'Content', 'learnpress' );
1306
+ $columns['students'] = __( 'Students', 'learnpress' );
1307
+ $columns['price'] = __( 'Price', 'learnpress' );
1308
+ }
1309
+
1310
+ $columns['taxonomy-course_category'] = __( 'Categories', 'learnpress' );
1311
+ return $columns;
1312
+ }
1313
+
1314
+ /**
1315
+ * Print content for custom column
1316
+ *
1317
+ * @param string
1318
+ * @param int
1319
+ */
1320
+ public
1321
+ function columns_content( $column, $post_id = 0 ) {
1322
+ global $post;
1323
+ $course = LP_Course::get_course( $post->ID );
1324
+ switch ( $column ) {
1325
+
1326
+ case 'sections':
1327
+ $sections = $course->get_curriculum();
1328
+ if ( $sections ) {
1329
+ $items = $course->get_curriculum_items( array( 'group' => true ) );
1330
+ $count_sections = sizeof( $sections );
1331
+ $count_lessons = sizeof( $items['lessons'] );
1332
+ $count_quizzes = sizeof( $items['quizzes'] );
1333
+ $output = sprintf( _nx( '%d section', '%d sections', $count_sections, 'learnpress' ), $count_sections );
1334
+ $output .= ' (';
1335
+ if ( $count_lessons ) {
1336
+ $output .= sprintf( _nx( '%d lesson', '%d lessons', $count_lessons, 'learnpress' ), $count_lessons );
1337
+ } else {
1338
+ $output .= __( "0 lesson", 'learnpress' );
1339
+ }
1340
+ $output .= ', ';
1341
+ if ( $count_quizzes ) {
1342
+ $output .= sprintf( _nx( '%d quiz', '%d quizzes', $count_quizzes, 'learnpress' ), $count_quizzes );
1343
+ } else {
1344
+ $output .= __( "0 quiz", 'learnpress' );
1345
+ }
1346
+ $output .= ')';
1347
+ echo $output;
1348
+ } else {
1349
+ _e( 'No content', 'learnpress' );
1350
+ }
1351
+ break;
1352
+ case 'price':
1353
+ $price = get_post_meta( $post->ID, '_lp_price', true );
1354
+ $is_paid = get_post_meta( $post->ID, '_lp_payment', true );
1355
+ if ( ( $is_paid === 'yes' ) && $price ) {
1356
+ echo sprintf( '<a href="%s">%s</a>', add_query_arg( 'filter_price', $price ), learn_press_format_price( get_post_meta( $post->ID, '_lp_price', true ), true ) );
1357
+ } else {
1358
+ echo sprintf( '<a href="%s">%s</a>', add_query_arg( 'filter_price', 0 ), __( 'Free', 'learnpress' ) );
1359
+ }
1360
+ break;
1361
+ case 'students' :
1362
+ echo '<span class=lp-label-counter>' . count( $course->get_students_list( true ) ) . '</span>';
1363
+
1364
+ }
1365
+ }
1366
+
1367
+ /**
1368
+ * Log the messages between admin and instructor
1369
+ */
1370
+ public
1371
+ function post_review_message_box() {
1372
+ global $post;
1373
+
1374
+ if ( get_post_type( $post->ID ) != 'lp_course' ) {
1375
+ return false;
1376
+ }
1377
+
1378
+ //$user = learn_press_get_current_user();
1379
+ $course_user = learn_press_get_user( get_post_field( 'post_author', $post->ID ) );
1380
+
1381
+ if ( $course_user->is_admin() ) {
1382
+ return;
1383
+ }
1384
+
1385
+ $required_review = LP()->settings->get( 'required_review' ) == 'yes';
1386
+ //$enable_edit_published = LP()->settings->get( 'enable_edit_published' ) == 'yes';
1387
+ //$is_publish = get_post_status( $post->ID ) == 'publish';
1388
+
1389
+ if ( !$required_review ) {
1390
+ return;
1391
+ }
1392
+ /*if( $enable_edit_published ){
1393
+ return;
1394
+ }*/
1395
+
1396
+
1397
+ learn_press_admin_view( 'meta-boxes/course/review-log' );
1398
+ }
1399
+
1400
+ public
1401
+ function posts_fields( $fields ) {
1402
+ if ( !$this->_is_archive() ) {
1403
+ return $fields;
1404
+ }
1405
+
1406
+ $fields = " DISTINCT " . $fields;
1407
+ if ( ( $this->_get_orderby() == 'price' ) || ( $this->_get_search() ) ) {
1408
+ $fields .= ', pm_price.meta_value as course_price';
1409
+ }
1410
+ return $fields;
1411
+ }
1412
+
1413
+ /**
1414
+ * @param $join
1415
+ *
1416
+ * @return string
1417
+ */
1418
+ public
1419
+ function posts_join_paged( $join ) {
1420
+ if ( !$this->_is_archive() ) {
1421
+ return $join;
1422
+ }
1423
+ global $wpdb;
1424
+ $join .= " LEFT JOIN {$wpdb->postmeta} pm_price ON pm_price.post_id = {$wpdb->posts}.ID AND pm_price.meta_key = '_lp_price'";
1425
+
1426
+ return $join;
1427
+ }
1428
+
1429
+ /**
1430
+ * @param $where
1431
+ *
1432
+ * @return mixed|string
1433
+ */
1434
+ public
1435
+ function posts_where_paged( $where ) {
1436
+ if ( !$this->_is_archive() ) {
1437
+ return $where;
1438
+ }
1439
+ global $wpdb;
1440
+ if ( array_key_exists( 'filter_price', $_REQUEST ) ) {
1441
+ if ( $_REQUEST['filter_price'] == 0 ) {
1442
+ $where .= " AND ( pm_price.meta_value IS NULL || pm_price.meta_value = 0 )";
1443
+ } else {
1444
+ $where .= $wpdb->prepare( " AND ( pm_price.meta_value = %s )", $_REQUEST['filter_price'] );
1445
+ }
1446
+ }
1447
+
1448
+ return $where;
1449
+ }
1450
+
1451
+ /**
1452
+ * @param $order_by_statement
1453
+ *
1454
+ * @return string
1455
+ */
1456
+ public
1457
+ function posts_orderby( $order_by_statement ) {
1458
+ if ( !$this->_is_archive() ) {
1459
+ return $order_by_statement;
1460
+ }
1461
+ switch ( $this->_get_orderby() ) {
1462
+ case 'price':
1463
+ $order_by_statement = "pm_price.meta_value {$_GET['order']}";
1464
+ }
1465
+ return $order_by_statement;
1466
+ }
1467
+
1468
+ /**
1469
+ * @param $columns
1470
+ *
1471
+ * @return mixed
1472
+ */
1473
+ public
1474
+ function sortable_columns( $columns ) {
1475
+ $columns['author'] = 'author';
1476
+ $columns['price'] = 'price';
1477
+
1478
+ return $columns;
1479
+ }
1480
+
1481
+ private
1482
+ function _is_archive() {
1483
+ global $pagenow, $post_type;
1484
+ if ( !is_admin() || ( $pagenow != 'edit.php' ) || ( LP_COURSE_CPT != $post_type ) ) {
1485
+ return false;
1486
+ }
1487
+ return true;
1488
+ }
1489
+
1490
+ private
1491
+ function _get_orderby() {
1492
+ return isset( $_REQUEST['orderby'] ) ? $_REQUEST['orderby'] : '';
1493
+ }
1494
+
1495
+ private
1496
+ function _get_search() {
1497
+ return isset( $_REQUEST['s'] ) ? $_REQUEST['s'] : false;
1498
+ }
1499
+
1500
+ /**
1501
+ * Course video
1502
+ * @return mixed|null|void
1503
+ */
1504
+ public
1505
+ static function video_meta_box() {
1506
+ $prefix = '_lp_';
1507
+ $meta_box = array(
1508
+ 'id' => 'course_video',
1509
+ 'title' => __( 'Course Video', 'learnpress' ),
1510
+ 'pages' => array( LP_COURSE_CPT ),
1511
+ 'priority' => 'high',
1512
+ 'fields' => array(
1513
+ array(
1514
+ 'name' => __( 'Video ID', 'learnpress' ),
1515
+ 'id' => "{$prefix}video_id",
1516
+ 'type' => 'text',
1517
+ 'desc' => __( 'The id of Youtube or Vimeo video', 'learnpress' ),
1518
+ 'std' => ''
1519
+ ),
1520
+ array(
1521
+ 'name' => __( 'Video Type', 'learnpress' ),
1522
+ 'id' => "{$prefix}video_type",
1523
+ 'type' => 'select',
1524
+ 'desc' => __( 'Chose video type', 'learnpress' ),
1525
+ 'std' => 'youtube',
1526
+ 'options' => array(
1527
+ 'youtube' => __( 'Youtube', 'learnpress' ),
1528
+ 'vimeo' => __( 'Vimeo', 'learnpress' )
1529
+ )
1530
+ ),
1531
+ array(
1532
+ 'name' => __( 'Embed width', 'learnpress' ),
1533
+ 'id' => "{$prefix}video_embed_width",
1534
+ 'type' => 'number',
1535
+ 'desc' => __( 'Set width of embed', 'learnpress' ),
1536
+ 'std' => '560'
1537
+ ),
1538
+ array(
1539
+ 'name' => __( 'Embed height', 'learnpress' ),
1540
+ 'id' => "{$prefix}video_embed_height",
1541
+ 'type' => 'number',
1542
+ 'desc' => __( 'Set height of embed', 'learnpress' ),
1543
+ 'std' => '315'
1544
+ ),
1545
+ )
1546
+ );
1547
+
1548
+ return apply_filters( 'learn_press_course_video_meta_box_args', $meta_box );
1549
+ }
1550
+
1551
+
1552
+ public
1553
+ static function instance() {
1554
+ if ( !self::$_instance ) {
1555
+ self::$_instance = new self( LP_COURSE_CPT );
1556
+ }
1557
+ return self::$_instance;
1558
+ }
1559
+ } // end LP_Course_Post_Type
1560
+
1561
+ $course_post_type = LP_Course_Post_Type::instance();
1562
+ //$course_post_type->add_meta_box( 'course-editor', 'dfgdfgfdg', 'course_editor', 'advanced', 'default' );
1563
+ }
 
 
 
inc/debug.php CHANGED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Search regexp \'[a-z]+ - [a-z]+\'
4
+ */
5
+
6
+ /**
7
+ * use http://example.com?debug=yes to execute the code in this file
8
+ */
inc/emails/class-lp-email-become-an-instructor.php CHANGED
@@ -21,16 +21,16 @@ class LP_Email_Become_An_Instructor extends LP_Email {
21
  $this->default_subject = __( '[{site_title}] You have enrolled course ({course_name})', 'learnpress' );
22
  $this->default_heading = __( 'Become an instructor', 'learnpress' );
23
 
24
- $this->email_text_message_description = sprintf( '%s [course_id], [course_title], [course_url], [user_email], [user_name], [user_profile_url]', __( 'Shortcodes', 'learnpress' ) );
25
-
26
- $this->support_variables = array(
27
- '{{site_url}}',
28
- '{{site_title}}',
29
- '{{login_url}}',
30
- '{{email_heading}}',
31
- '{{user_email}}',
32
- '{{user_nicename}}'
33
- );
34
  parent::__construct();
35
  }
36
 
@@ -44,20 +44,20 @@ class LP_Email_Become_An_Instructor extends LP_Email {
44
  return;
45
  }
46
 
47
- $user = get_user_by( 'id', $user );
48
  $this->recipient = $user->user_email;
49
- $this->object = $this->get_common_template_data(
50
  $this->email_format == 'plain_text' ? 'plain' : 'html',
51
  array(
52
- 'site_url' => $user->id,
53
- 'site_title' => learn_press_get_profile_display_name( get_user_by( 'id', $user ) ),
54
- 'login_url' => wp_login_url(),
55
- 'user_nicename' => $user->user_nincename,
56
- 'user_email' => $user->user_email,
57
- 'email_heading' => $this->get_heading(),
58
- 'footer_text' => $this->get_footer_text(),
59
- 'site_title' => $this->get_blogname(),
60
- 'plain_text' => $format == 'plain',
61
  )
62
  );
63
 
21
  $this->default_subject = __( '[{site_title}] You have enrolled course ({course_name})', 'learnpress' );
22
  $this->default_heading = __( 'Become an instructor', 'learnpress' );
23
 
24
+ $this->email_text_message_description = sprintf( '%s [course_id], [course_title], [course_url], [user_email], [user_name], [user_profile_url]', __( 'Shortcodes', 'learnpress' ) );
25
+
26
+ $this->support_variables = array(
27
+ '{{site_url}}',
28
+ '{{site_title}}',
29
+ '{{login_url}}',
30
+ '{{email_heading}}',
31
+ '{{user_email}}',
32
+ '{{user_nicename}}'
33
+ );
34
  parent::__construct();
35
  }
36
 
44
  return;
45
  }
46
 
47
+ $user = get_user_by( 'id', $user );
48
  $this->recipient = $user->user_email;
49
+ $this->object = $this->get_common_template_data(
50
  $this->email_format == 'plain_text' ? 'plain' : 'html',
51
  array(
52
+ 'site_url' => $user->id,
53
+ 'site_title' => learn_press_get_profile_display_name( get_user_by( 'id', $user ) ),
54
+ 'login_url' => wp_login_url(),
55
+ 'user_nicename' => $user->user_nincename,
56
+ 'user_email' => $user->user_email,
57
+ 'email_heading' => $this->get_heading(),
58
+ 'footer_text' => $this->get_footer_text(),
59
+ 'site_title' => $this->get_blogname(),
60
+ 'plain_text' => $this->email_format == 'plain_text',
61
  )
62
  );
63
 
inc/gateways/class-lp-gateways.php CHANGED
@@ -1,84 +1,85 @@
1
- <?php
2
-
3
- /**
4
- * Class LP_Gateways
5
- *
6
- * @author ThimPress
7
- * @package LearnPress/Classes
8
- * @version 1.0
9
- */
10
-
11
- if ( !defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- class LP_Gateways {
16
-
17
- protected static $_instance = null;
18
-
19
- protected $payment_gateways = array();
20
-
21
- public function __construct() {
22
- $this->init();
23
- }
24
-
25
- public function init() {
26
- if ( !$this->payment_gateways ) {
27
- $gateways = array(
28
- 'paypal' => 'LP_Gateway_Paypal'
29
- );
30
- // Filter
31
- $gateways = apply_filters( 'learn_press_payment_method', $gateways );
32
- if ( $gateways ) {
33
- foreach ( $gateways as $k => $gateway ) {
34
- if ( is_string( $gateway ) && class_exists( $gateway ) ) {
35
- $gateway = new $gateway();
36
- }
37
- $this->payment_gateways[$k] = apply_filters( 'learn_press_payment_method_init', $gateway );
38
- }
39
- }
40
- }
41
- }
42
-
43
- public function get_gateways() {
44
- $gateways = array();
45
- if ( count( $this->payment_gateways ) ) foreach ( $this->payment_gateways as $gateway ) {
46
- if ( is_string( $gateway ) && class_exists( $gateway ) ) {
47
- $gateway = new $gateway();
48
- }
49
- if ( !is_object( $gateway ) ) {
50
- continue;
51
- }
52
- $gateways[$gateway->id] = $gateway;
53
- }
54
- return $gateways;
55
- }
56
-
57
- public function get_available_payment_gateways() {
58
- $this->init();
59
- $_available_gateways = array();
60
- foreach ( $this->payment_gateways as $slug => $gateway ) {
61
- // let custom addon can define how is enable/disable
62
- if ( apply_filters( 'learn_press_payment_gateway_available_' . $slug, false, $gateway ) ) {
63
- $_available_gateways[$slug] = $gateway;
64
- };
65
- }
66
-
67
- return apply_filters( 'learn_press_available_payment_gateways', $_available_gateways );
68
- }
69
-
70
- public function get_availabe_gateways() {
71
- return $this->payment_gateways;
72
- }
73
-
74
- /**
75
- * Ensure that only one instance of LP_Gateways is loaded
76
- * @return LP_Gateways|null
77
- */
78
- public static function instance() {
79
- if ( is_null( self::$_instance ) ) {
80
- self::$_instance = new self();
81
- }
82
- return self::$_instance;
83
- }
 
84
  }
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Gateways
5
+ *
6
+ * @author ThimPress
7
+ * @package LearnPress/Classes
8
+ * @version 1.0
9
+ */
10
+
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ class LP_Gateways {
16
+
17
+ protected static $_instance = null;
18
+
19
+ protected $payment_gateways = array();
20
+
21
+ public function __construct() {
22
+ $this->init();
23
+ }
24
+
25
+ public function init() {
26
+ // return;
27
+ if ( !$this->payment_gateways ) {
28
+ $gateways = array(
29
+ 'paypal' => 'LP_Gateway_Paypal'
30
+ );
31
+ // Filter
32
+ $gateways = apply_filters( 'learn_press_payment_method', $gateways );
33
+ if ( $gateways ) {
34
+ foreach ( $gateways as $k => $gateway ) {
35
+ if ( is_string( $gateway ) && class_exists( $gateway ) ) {
36
+ $gateway = new $gateway();
37
+ }
38
+ $this->payment_gateways[$k] = apply_filters( 'learn_press_payment_method_init', $gateway );
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ public function get_gateways() {
45
+ $gateways = array();
46
+ if ( count( $this->payment_gateways ) ) foreach ( $this->payment_gateways as $gateway ) {
47
+ if ( is_string( $gateway ) && class_exists( $gateway ) ) {
48
+ $gateway = new $gateway();
49
+ }
50
+ if ( !is_object( $gateway ) ) {
51
+ continue;
52
+ }
53
+ $gateways[$gateway->id] = $gateway;
54
+ }
55
+ return $gateways;
56
+ }
57
+
58
+ public function get_available_payment_gateways() {
59
+ $this->init();
60
+ $_available_gateways = array();
61
+ foreach ( $this->payment_gateways as $slug => $gateway ) {
62
+ // let custom addon can define how is enable/disable
63
+ if ( apply_filters( 'learn_press_payment_gateway_available_' . $slug, false, $gateway ) ) {
64
+ $_available_gateways[$slug] = $gateway;
65
+ };
66
+ }
67
+
68
+ return apply_filters( 'learn_press_available_payment_gateways', $_available_gateways );
69
+ }
70
+
71
+ public function get_availabe_gateways() {
72
+ return $this->payment_gateways;
73
+ }
74
+
75
+ /**
76
+ * Ensure that only one instance of LP_Gateways is loaded
77
+ * @return LP_Gateways|null
78
+ */
79
+ public static function instance() {
80
+ if ( is_null( self::$_instance ) ) {
81
+ self::$_instance = new self();
82
+ }
83
+ return self::$_instance;
84
+ }
85
  }
inc/lp-add-on-functions.php CHANGED
@@ -848,7 +848,11 @@ function learn_press_output_premium_add_ons_list($add_ons, $tab = '') {
848
  echo '<h2>'. __('Premium Add-ons', 'learnpress') .' (<span class="learnpress-count-addon">'. sizeof($add_ons) .'</span>) </h2>';
849
  echo '<ul class="learn-press-add-ons widefat ' . $tab . '">';
850
  foreach ( $add_ons as $file => $add_on ) {
851
- $add_on['permarklink'] .= '?ref=ThimPress&utm_source=lp-backend&utm_medium=lp-addondashboard';
 
 
 
 
852
  ?>
853
  <li class="plugin-card plugin-card-learnpress" id="learn-press-plugin-<?php echo $add_on['slug']; ?>">
854
  <div class="plugin-card-top">
@@ -943,7 +947,11 @@ function learn_press_output_related_themes_list_education( $add_ons, $tab ) {
943
  echo '<h2 class="learnpress-title">'. __('Education Support') .' (<span class="learnpress-count">'. sizeof($add_ons) .'</span>) </h2>';
944
  echo '<ul class="learn-press-add-ons widefat ' . $tab . '">';
945
  foreach ( $add_ons as $file => $add_on ) {
946
- $add_on['url'] .= '?ref=ThimPress&utm_source=lp-backend&utm_medium=lp-addondashboard';
 
 
 
 
947
  ?>
948
  <li class="plugin-card plugin-card-learnpress" id="learn-press-theme-<?php echo $add_on['id']; ?>">
949
  <div class="plugin-card-top">
@@ -978,10 +986,14 @@ function learn_press_output_related_themes_list_education( $add_ons, $tab ) {
978
  </div>
979
  <div class="theme-footer">
980
  <?php
981
- $demo = $add_on['attributes'][4];
982
- $demo['value'] .= '?ref=ThimPress&utm_source=lp-backend&utm_medium=lp-addondashboard';
 
 
 
 
983
  ?>
984
- <a class="button button-primary" href="<?php echo esc_url($add_on['url']); ?>"><?php echo __('Get it now for only ', 'learnpress') ?></a>
985
  <a class="button" href="<?php echo esc_url($demo['value']); ?>"><?php _e('View Demo', 'learnpress'); ?></a>
986
  <div class="theme-rating">
987
  <span class="">
@@ -1002,7 +1014,11 @@ function learn_press_output_related_themes_list_other( $add_ons, $tab ) {
1002
  echo '<h2 class="learnpress-title">'. __('Other') .' (<span class="learnpress-count">'. sizeof($add_ons) .'</span>) </h2>';
1003
  echo '<ul class="learn-press-add-ons widefat ' . $tab . '">';
1004
  foreach ( $add_ons as $file => $add_on ) {
1005
- $add_on['url'] .= '?ref=ThimPress&utm_source=lp-backend&utm_medium=lp-addondashboard';
 
 
 
 
1006
  ?>
1007
  <li class="plugin-card plugin-card-learnpress" id="learn-press-theme-<?php echo $add_on['id']; ?>">
1008
  <div class="plugin-card-top">
@@ -1038,9 +1054,13 @@ function learn_press_output_related_themes_list_other( $add_ons, $tab ) {
1038
  <div class="theme-footer">
1039
  <?php
1040
  $demo = $add_on['attributes'][4];
1041
- $demo['value'] .= '?ref=ThimPress&utm_source=lp-backend&utm_medium=lp-addondashboard';
 
 
 
 
1042
  ?>
1043
- <a class="button button-primary" href="<?php echo esc_url($add_on['url']); ?>"><?php echo __('Get it now for only ', 'learnpress') ?></a>
1044
  <a class="button" href="<?php echo esc_url($demo['value']); ?>"><?php _e('View Demo', 'learnpress'); ?></a>
1045
  <div class="theme-rating">
1046
  <span class="">
848
  echo '<h2>'. __('Premium Add-ons', 'learnpress') .' (<span class="learnpress-count-addon">'. sizeof($add_ons) .'</span>) </h2>';
849
  echo '<ul class="learn-press-add-ons widefat ' . $tab . '">';
850
  foreach ( $add_ons as $file => $add_on ) {
851
+ $add_on['permarklink'] = add_query_arg( array(
852
+ 'ref' => 'ThimPress',
853
+ 'utm_source' => 'lp-backend',
854
+ 'utm_medium' => 'lp-addondashboard'
855
+ ), $add_on['permarklink'] );
856
  ?>
857
  <li class="plugin-card plugin-card-learnpress" id="learn-press-plugin-<?php echo $add_on['slug']; ?>">
858
  <div class="plugin-card-top">
947
  echo '<h2 class="learnpress-title">'. __('Education Support') .' (<span class="learnpress-count">'. sizeof($add_ons) .'</span>) </h2>';
948
  echo '<ul class="learn-press-add-ons widefat ' . $tab . '">';
949
  foreach ( $add_ons as $file => $add_on ) {
950
+ $add_on['url'] = add_query_arg( array(
951
+ 'ref' => 'ThimPress',
952
+ 'utm_source' => 'lp-backend',
953
+ 'utm_medium' => 'lp-addondashboard'
954
+ ), $add_on['url'] );
955
  ?>
956
  <li class="plugin-card plugin-card-learnpress" id="learn-press-theme-<?php echo $add_on['id']; ?>">
957
  <div class="plugin-card-top">
986
  </div>
987
  <div class="theme-footer">
988
  <?php
989
+ $demo = $add_on['attributes'][4];
990
+ $demo['value'] = add_query_arg( array(
991
+ 'ref' => 'ThimPress',
992
+ 'utm_source' => 'lp-backend',
993
+ 'utm_medium' => 'lp-addondashboard'
994
+ ), $demo['value'] );
995
  ?>
996
+ <a class="button button-primary" href="<?php echo esc_url($add_on['url']); ?>"><?php echo __('Get it now', 'learnpress') ?></a>
997
  <a class="button" href="<?php echo esc_url($demo['value']); ?>"><?php _e('View Demo', 'learnpress'); ?></a>
998
  <div class="theme-rating">
999
  <span class="">
1014
  echo '<h2 class="learnpress-title">'. __('Other') .' (<span class="learnpress-count">'. sizeof($add_ons) .'</span>) </h2>';
1015
  echo '<ul class="learn-press-add-ons widefat ' . $tab . '">';
1016
  foreach ( $add_ons as $file => $add_on ) {
1017
+ $add_on['url'] = add_query_arg( array(
1018
+ 'ref' => 'ThimPress',
1019
+ 'utm_source' => 'lp-backend',
1020
+ 'utm_medium' => 'lp-addondashboard'
1021
+ ), $add_on['url'] );
1022
  ?>
1023
  <li class="plugin-card plugin-card-learnpress" id="learn-press-theme-<?php echo $add_on['id']; ?>">
1024
  <div class="plugin-card-top">
1054
  <div class="theme-footer">
1055
  <?php
1056
  $demo = $add_on['attributes'][4];
1057
+ $demo['value'] = add_query_arg( array(
1058
+ 'ref' => 'ThimPress',
1059
+ 'utm_source' => 'lp-backend',
1060
+ 'utm_medium' => 'lp-addondashboard'
1061
+ ), $demo['value'] );
1062
  ?>
1063
+ <a class="button button-primary" href="<?php echo esc_url($add_on['url']); ?>"><?php echo __('Get it now', 'learnpress') ?></a>
1064
  <a class="button" href="<?php echo esc_url($demo['value']); ?>"><?php _e('View Demo', 'learnpress'); ?></a>
1065
  <div class="theme-rating">
1066
  <span class="">
inc/lp-constants.php CHANGED
@@ -4,7 +4,7 @@
4
  */
5
  $upload_dir = wp_upload_dir();
6
  // version
7
- define( 'LEARNPRESS_VERSION', '2.1.0' );
8
 
9
  define( 'LP_WP_CONTENT', basename( WP_CONTENT_DIR ) );
10
 
4
  */
5
  $upload_dir = wp_upload_dir();
6
  // version
7
+ define( 'LEARNPRESS_VERSION', '2.1.1' );
8
 
9
  define( 'LP_WP_CONTENT', basename( WP_CONTENT_DIR ) );
10
 
inc/lp-core-functions.php CHANGED
@@ -1,2657 +1,2696 @@
1
- <?php
2
- /**
3
- * LearnPress Core Functions
4
- * Define common functions for both front-end and back-end
5
- *
6
- * @author ThimPress
7
- * @package LearnPress/Functions
8
- * @version 1.0
9
- */
10
-
11
- if ( !defined( 'ABSPATH' ) ) {
12
- exit; // Exit if accessed directly
13
- }
14
-
15
- function learn_press_get_post() {
16
- global $post;
17
- $post_id = !empty( $post ) ? $post->ID : 0;
18
- if ( empty( $post_id ) ) {
19
- $post_id = learn_press_get_request( 'post' );
20
- }
21
-
22
- if ( empty( $post_id ) ) {
23
- $post_id = learn_press_get_request( 'post_ID' );
24
- }
25
- return absint( $post_id );
26
- }
27
-
28
- /**
29
- * Get the LearnPress plugin url
30
- *
31
- * @param string $sub_dir
32
- *
33
- * @return string
34
- */
35
- function learn_press_plugin_url( $sub_dir = '' ) {
36
- return LP()->plugin_url( $sub_dir );
37
- }
38
-
39
- /**
40
- * Get the LearnPress plugin path.
41
- *
42
- * @param string $sub_dir
43
- *
44
- * @return string
45
- */
46
- function learn_press_plugin_path( $sub_dir = '' ) {
47
- return LP()->plugin_path( $sub_dir );
48
- }
49
-
50
- /**
51
- * Includes file base on LearnPress path
52
- *
53
- * @param $file
54
- * @param string $folder
55
- * @param bool $include_once
56
- *
57
- * @return bool
58
- */
59
- function learn_press_include( $file, $folder = 'inc', $include_once = true ) {
60
- if ( file_exists( $include = learn_press_plugin_path( "{$folder}/{$file}" ) ) ) {
61
- if ( $include_once ) {
62
- include_once $include;
63
- } else {
64
- include $include;
65
- }
66
- return true;
67
- }
68
- return false;
69
- }
70
-
71
- /**
72
- * Get current IP of the user
73
- *
74
- * @return mixed
75
- */
76
- function learn_press_get_ip() {
77
- //Just get the headers if we can or else use the SERVER global
78
- if ( function_exists( 'apache_request_headers' ) ) {
79
- $headers = apache_request_headers();
80
- } else {
81
- $headers = $_SERVER;
82
- }
83
- //Get the forwarded IP if it exists
84
- if ( array_key_exists( 'X-Forwarded-For', $headers ) &&
85
- (
86
- filter_var( $headers['X-Forwarded-For'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ||
87
- filter_var( $headers['X-Forwarded-For'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) )
88
- ) {
89
- $the_ip = $headers['X-Forwarded-For'];
90
- } elseif (
91
- array_key_exists( 'HTTP_X_FORWARDED_FOR', $headers ) &&
92
- (
93
- filter_var( $headers['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ||
94
- filter_var( $headers['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 )
95
- )
96
- ) {
97
- $the_ip = $headers['HTTP_X_FORWARDED_FOR'];
98
- } else {
99
- $the_ip = $_SERVER['REMOTE_ADDR'];
100
- }
101
-
102
- return esc_sql( $the_ip );
103
- }
104
-
105
- /**
106
- * Generate an unique string
107
- *
108
- * @param string $prefix
109
- *
110
- * @return mixed|void
111
- */
112
- function learn_press_uniqid( $prefix = '' ) {
113
- $hash = str_replace( '.', '', microtime( true ) . uniqid() );
114
- return apply_filters( 'learn_press_generate_unique_hash', $prefix . $hash, $prefix );
115
- }
116
-
117
- /**
118
- * Check to see if an endpoint is showing in current URL
119
- *
120
- * @param bool $endpoint
121
- *
122
- * @return bool
123
- */
124
- function learn_press_is_endpoint_url( $endpoint = false ) {
125
- global $wp;
126
-
127
- $endpoints = array();
128
-
129
- if ( $endpoint !== false ) {
130
- if ( !isset( $endpoints[$endpoint] ) ) {
131
- return false;
132
- } else {
133
- $endpoint_var = $endpoints[$endpoint];
134
- }
135
-
136
- return isset( $wp->query_vars[$endpoint_var] );
137
- } else {
138
- foreach ( $endpoints as $key => $value ) {
139
- if ( isset( $wp->query_vars[$key] ) ) {
140
- return true;
141
- }
142
- }
143
-
144
- return false;
145
- }
146
- }
147
-
148
- /**
149
- * Get current URL user is viewing
150
- *
151
- * @return string
152
- */
153
- function learn_press_get_current_url() {
154
- static $current_url;
155
- if ( !$current_url ) {
156
- $url = untrailingslashit( $_SERVER['REQUEST_URI'] );
157
- if ( !preg_match( '!^https?!', $url ) ) {
158
- $siteurl = trailingslashit( get_site_url() );
159
- $segs1 = explode( '/', $siteurl );
160
- $segs2 = explode( '/', $url );
161
- if ( $removed = array_intersect( $segs1, $segs2 ) ) {
162
- if ( $segs2 = array_diff( $segs2, $removed ) ) {
163
- $current_url = $siteurl . join( '/', $segs2 );
164
- if ( strpos( $current_url, '?' ) === false ) {
165
- $current_url = trailingslashit( $current_url );
166
- }
167
- }
168
- }
169
- }
170
- }
171
- return $current_url;
172
- }
173
-
174
- /**
175
- * Compares an url with current URL user is viewing
176
- *
177
- * @param $url
178
- *
179
- * @return bool
180
- */
181
- function learn_press_is_current_url( $url ) {
182
- $current_url = learn_press_get_current_url();
183
- return ( $current_url && $url ) && strcmp( $current_url, learn_press_sanitize_url( $url ) ) == 0;
184
- }
185
-
186
- /**
187
- * Remove unneeded characters in an URL
188
- *
189
- * @param $url
190
- * @param bool $trailingslashit
191
- *
192
- * @return string
193
- */
194
- function learn_press_sanitize_url( $url, $trailingslashit = true ) {
195
- if ( $url ) {
196
- preg_match( '!(https?://)?(.*)!', $url, $matches );
197
- $url_without_http = $matches[2];
198
- $url_without_http = preg_replace( '![/]+!', '/', $url_without_http );
199
- $url = $matches[1] . $url_without_http;
200
- return $trailingslashit ? trailingslashit( $url ) : untrailingslashit( $url );
201
- }
202
- return $url;
203
- }
204
-
205
- /**
206
- * Get all types of question supported
207
- *
208
- * @return mixed
209
- */
210
- function learn_press_question_types() {
211
- return LP_Question_Factory::get_types();
212
- }
213
-
214
- /**
215
- * Get human name of question's type by slug
216
- *
217
- * @param $slug
218
- *
219
- * @return mixed|void
220
- */
221
- function learn_press_question_name_from_slug( $slug ) {
222
- $types = learn_press_question_types();
223
- $name = !empty( $types[$slug] ) ? $types[$slug] : '';
224
- return apply_filters( 'learn_press_question_name_from_slug', $name, $slug );
225
- }
226
-
227
- /**
228
- * Get the post types which supported to insert into course's section
229
- *
230
- * @return mixed|void
231
- */
232
- function learn_press_section_item_types() {
233
- $types = array(
234
- 'lp_lesson' => __( 'Lesson', 'learnpress' ),
235
- 'lp_quiz' => __( 'Quiz', 'learnpress' )
236
- );
237
- return apply_filters( 'learn_press_section_item_types', $types );
238
- }
239
-
240
- /**
241
- * Enqueue js code to print out
242
- *
243
- * @param string $code
244
- * @param bool $script_tag - wrap code between <script> tag
245
- */
246
- function learn_press_enqueue_script( $code, $script_tag = false ) {
247
- global $learn_press_queued_js, $learn_press_queued_js_tag;
248
-
249
- if ( $script_tag ) {
250
- if ( empty( $learn_press_queued_js_tag ) ) {
251
- $learn_press_queued_js_tag = '';
252
- }
253
- $learn_press_queued_js_tag .= "\n" . $code . "\n";
254
- } else {
255
- if ( empty( $learn_press_queued_js ) ) {
256
- $learn_press_queued_js = '';
257
- }
258
-
259
- $learn_press_queued_js .= "\n" . $code . "\n";
260
- }
261
- }
262
-
263
- function learn_press_get_course_terms( $course_id, $taxonomy, $args = array() ) {
264
- if ( !taxonomy_exists( $taxonomy ) ) {
265
- return array();
266
- }
267
- // Support ordering by parent
268
- if ( !empty( $args['orderby'] ) && in_array( $args['orderby'], array( 'name_num', 'parent' ) ) ) {
269
- $fields = isset( $args['fields'] ) ? $args['fields'] : 'all';
270
- $orderby = $args['orderby'];
271
-
272
- // Unset for wp_get_post_terms
273
- unset( $args['orderby'] );
274
- unset( $args['fields'] );
275
-
276
- $terms = wp_get_post_terms( $course_id, $taxonomy, $args );
277
-
278
- switch ( $orderby ) {
279
- case 'name_num' :
280
- usort( $terms, '_learn_press_get_course_terms_name_num_usort_callback' );
281
- break;
282
- case 'parent' :
283
- usort( $terms, '_learn_press_get_course_terms_parent_usort_callback' );
284
- break;
285
- }
286
-
287
- switch ( $fields ) {
288
- case 'names' :
289
- $terms = wp_list_pluck( $terms, 'name' );
290
- break;
291
- case 'ids' :
292
- $terms = wp_list_pluck( $terms, 'term_id' );
293
- break;
294
- case 'slugs' :
295
- $terms = wp_list_pluck( $terms, 'slug' );
296
- break;
297
- }
298
- } elseif ( !empty( $args['orderby'] ) && $args['orderby'] === 'menu_order' ) {
299
- // wp_get_post_terms doesn't let us use custom sort order
300
- $args['include'] = wp_get_post_terms( $course_id, $taxonomy, array( 'fields' => 'ids' ) );
301
-
302
- if ( empty( $args['include'] ) ) {
303
- $terms = array();
304
- } else {
305
- // This isn't needed for get_terms
306
- unset( $args['orderby'] );
307
-
308
- // Set args for get_terms
309
- $args['menu_order'] = isset( $args['order'] ) ? $args['order'] : 'ASC';
310
- $args['hide_empty'] = isset( $args['hide_empty'] ) ? $args['hide_empty'] : 0;
311
- $args['fields'] = isset( $args['fields'] ) ? $args['fields'] : 'names';
312
-
313
- // Ensure slugs is valid for get_terms - slugs isn't supported
314
- $args['fields'] = $args['fields'] === 'slugs' ? 'id=>slug' : $args['fields'];
315
- $terms = get_terms( $taxonomy, $args );
316
- }
317
- } else {
318
- $terms = wp_get_post_terms( $course_id, $taxonomy, $args );
319
- }
320
-
321
- return apply_filters( 'learn_press_get_course_terms', $terms, $course_id, $taxonomy, $args );
322
- }
323
-
324
- function _learn_press_get_course_terms_name_num_usort_callback( $a, $b ) {
325
- if ( $a->name + 0 === $b->name + 0 ) {
326
- return 0;
327
- }
328
- return ( $a->name + 0 < $b->name + 0 ) ? - 1 : 1;
329
- }
330
-
331
- function _learn_press_get_course_terms_parent_usort_callback( $a, $b ) {
332
- if ( $a->parent === $b->parent ) {
333
- return 0;
334
- }
335
- return ( $a->parent < $b->parent ) ? 1 : - 1;
336
- }
337
-
338
-
339
- function learn_press_get_post_by_name( $name, $type, $single = true ) {
340
- $post_names = LP_Cache::get_post_names( false, array() );
341
- $post = false;
342
- if ( !empty( $post_names[$type][$name] ) ) {
343
- $post = get_post( $post_names[$type][$name] );
344
- }
345
- if ( !$post ) {
346
- global $wpdb;
347
- $query = $wpdb->prepare( "
348
- SELECT *
349
- FROM {$wpdb->posts}
350
- WHERE 1 AND post_name = %s
351
- ", $name );
352
-
353
- $query .= " AND post_type IN ('" . $type . "' )";
354
-
355
- if ( empty( $post_names[$type] ) ) {
356
- $post_names[$type] = array();
357
- }
358
- if ( $post = $wpdb->get_row( $query ) ) {
359
- //wp_cache_set( $post->ID, $post, 'posts' );
360
- }
361
-
362
- $post_names[$type][$name] = $post ? $post->ID : 0;
363
- LP_Cache::set_post_names( $post_names );
364
- }
365
- return $post ? get_post( $post_names[$type][$name] ) : false;
366
- }
367
-
368
- function learn_press_get_current_course() {
369
- return LP()->global['course'];
370
- }
371
-
372
- function learn_press_get_course_item_object( $post_type ) {
373
- switch ( $post_type ) {
374
- case 'lp_quiz':
375
- $class = 'LP_Quiz';
376
- break;
377
- case 'lp_lesson':
378
- $class = 'LP_Lesson';
379
- break;
380
- case 'lp_question':
381
- $class = 'LP_Question';
382
- }
383
- }
384
-
385
- //get_post_meta()
386
-
387
- /**
388
- * Print out js code in the queue
389
- */
390
- function learn_press_print_script() {
391
- global $learn_press_queued_js, $learn_press_queued_js_tag;
392
- if ( !empty( $learn_press_queued_js ) ) {
393
- ?>
394
- <!-- LearnPress JavaScript -->
395
- <script type="text/javascript">jQuery(function ($) {
396
- <?php
397
- // Sanitize
398
- $learn_press_queued_js = wp_check_invalid_utf8( $learn_press_queued_js );
399
- $learn_press_queued_js = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", $learn_press_queued_js );
400
- $learn_press_queued_js = str_replace( "\r", '', $learn_press_queued_js );
401
-
402
- echo $learn_press_queued_js;
403
- ?>
404
- });
405
- </script>
406
- <?php
407
- unset( $learn_press_queued_js );
408
- }
409
-
410
- if ( !empty( $learn_press_queued_js_tag ) ) {
411
- echo $learn_press_queued_js_tag;
412
- }
413
- }
414
-
415
- add_action( 'wp_footer', 'learn_press_print_script' );
416
- add_action( 'admin_footer', 'learn_press_print_script' );
417
-
418
- /* Advertise in page admin */
419
- if ( !function_exists( 'leanrpress_advertise_in_admin' ) ) {
420
-
421
- function leanrpress_advertise_in_admin() {
422
-
423
- $admin_post_type = array(
424
- 'lp_course',
425
- 'lp_lesson',
426
- 'lp_quiz',
427
- 'lp_question',
428
- 'lp_order'
429
- );
430
- $pages = array(
431
- 'learnpress_page_learn-press-statistics',
432
- 'learnpress_page_learn-press-settings',
433
- 'learnpress_page_learn-press-tools'
434
-
435
- );
436
- $themes_id = array(
437
- '14058034' => 'eduma',
438
- '17097658' => 'coach',
439
- '11797847' => 'lms'
440
- );
441
-
442
- $screen = get_current_screen();
443
-
444
- if ( ( in_array( $screen->post_type, $admin_post_type ) && $screen->base === 'edit' )
445
- || ( in_array( $screen->id, $pages ) )
446
- ) {
447
-
448
- $current_theme = wp_get_theme();
449
-
450
- // Get items education
451
- $list_themes = learn_press_related_theme();
452
-
453
- foreach ( $list_themes as $key => $theme ) {
454
-
455
- if ( !array_key_exists( $theme['id'], $themes_id ) || $themes_id[$theme['id']] === $current_theme->name ) {
456
- unset( $list_themes[$key] );
457
- }
458
- }
459
- shuffle( $list_themes );
460
- ?>
461
- <div id="learn-press-add-ons-wrap" class="learnpress-advertis-admin">
462
- <?php
463
- foreach ( $list_themes as $theme ) {
464
- $theme['url'] .= '?ref=ThimPress&utm_source=lp-backend&utm_medium=lp-addondashboard';
465
- $url_demo = $theme['attributes'][4]['value'] . '?ref=ThimPress&utm_source=lp-backend&utm_medium=lp-addondashboard';
466
-
467
- $theme['description'] = preg_replace( '/(?<=\S,)(?=\S)/', ' ', $theme['description'] );
468
- $theme['description'] = str_replace( "\n", ' ', $theme['description'] );
469
- $theme['description'] = explode( " ", $theme['description'] );
470
- $theme['description'] = array_splice( $theme['description'], 0, sizeof( $theme['description'] ) - 1 );
471
- $theme['description'] = implode( " ", $theme['description'] ) . " ...";
472
- ?>
473
- <div id="thimpress-<?php echo esc_attr( $theme['id'] ); ?>" class="item">
474
- <div class="theme-thumbnail">
475
- <a href="<?php echo esc_url( $theme['url'] ); ?>">
476
- <img src="<?php echo esc_url( $theme['previews']['landscape_preview']['landscape_url'] ) ?>" />
477
- </a>
478
- </div>
479
-
480
- <div class="theme-detail">
481
- <h2><a href="<?php echo esc_url( $theme['url'] ); ?>"><?php echo $theme['name']; ?></a></h2>
482
- <p class="learpress-description">
483
- <?php echo wp_kses_post( $theme['description'] ); ?>
484
- </p>
485
- <p class="theme-controls">
486
- <a href="<?php echo esc_url( $theme['url'] ); ?>" class="button button-primary" target="_blank"><?php _e( 'Get it now', 'learnpress' ); ?></a>
487
- <a href="<?php echo esc_url( $url_demo ); ?>" class="button" target="_blank"><?php _e( 'View Demo', 'learnpress' ); ?></a>
488
- </p>
489
- </div>
490
-
491
- </div>
492
- <?php
493
- }
494
- ?>
495
- </div>
496
- <?php
497
- }
498
-
499
- }
500
- }
501
-
502
- add_action( 'admin_footer', 'leanrpress_advertise_in_admin', - 10 );
503
-
504
- /**
505
- * @param string $str
506
- * @param int $lines
507
- */
508
- function learn_press_email_new_line( $lines = 1, $str = "\r\n" ) {
509
- echo str_repeat( $str, $lines );
510
- }
511
-
512
- if ( !function_exists( 'learn_press_is_ajax' ) ) {
513
-
514
- /**
515
- * is_ajax - Returns true when the page is loaded via ajax.
516
- *
517
- * @access public
518
- * @return bool
519
- */
520
- function learn_press_is_ajax() {
521
- return defined( 'LP_DOING_AJAX' ) && LP_DOING_AJAX;
522
- }
523
- }
524
-
525
- /**
526
- * Get page id from admin settings page
527
- *
528
- * @param string $name
529
- *
530
- * @return int
531
- */
532
- function learn_press_get_page_id( $name ) {
533
- return apply_filters( 'learn_press_get_page_id', LP_Settings::instance()->get( "{$name}_page_id", false ), $name );
534
- }
535
-
536
- /**
537
- * display the seconds in time format h:i:s
538
- *
539
- * @param $seconds
540
- * @param string $separator
541
- *
542
- * @return string
543
- */
544
- function learn_press_seconds_to_time( $seconds, $separator = ':' ) {
545
- return sprintf( "%02d%s%02d%s%02d", floor( $seconds / 3600 ), $separator, ( $seconds / 60 ) % 60, $separator, $seconds % 60 );
546
- }
547
-
548
- /**
549
- * Create an empty post object
550
- *
551
- * @version 1.0
552
- *
553
- * @param mixed
554
- *
555
- * @return mixed
556
- */
557
- function learn_press_post_object( $defaults = false ) {
558
- static $post_object = false;
559
- if ( !$post_object ) {
560
- global $wpdb;
561
- $post_object = new stdClass();
562
- foreach ( $wpdb->get_col( "DESC " . $wpdb->posts, 0 ) as $column_name ) {
563
- $post_object->{$column_name} = null;
564
- }
565
- }
566
- settype( $defaults, 'array' );
567
- foreach ( get_object_vars( $post_object ) as $k => $v ) {
568
- if ( array_key_exists( $k, $defaults ) ) {
569
- $post_object->{$k} = $defaults[$k];
570
- } else {
571
- $post_object->{$k} = '';
572
- }
573
- }
574
- return $post_object;
575
- }
576
-
577
- /***********************************************/
578
- /***** =================================== *****/
579
- /***** THE FUNCTIONS ABOVE FOR VERSION 1.0 *****/
580
- /***** =================================== *****/
581
- /***********************************************/
582
-
583
- /* nav */
584
- if ( !function_exists( 'learn_press_course_paging_nav' ) ) :
585
-
586
- /**
587
- * Display navigation to next/previous set of posts when applicable.
588
- *
589
- * @param array
590
- */
591
- function learn_press_course_paging_nav( $args = array() ) {
592
- learn_press_paging_nav(
593
- array(
594
- 'num_pages' => $GLOBALS['wp_query']->max_num_pages,
595
- 'wrapper_class' => 'navigation pagination'
596
- )
597
- );
598
- }
599
-
600
- endif;
601
-
602
- /* nav */
603
- if ( !function_exists( 'learn_press_paging_nav' ) ) :
604
-
605
- /**
606
- * Display navigation to next/previous set of posts when applicable.
607
- *
608
- * @param array
609
- */
610
- function learn_press_paging_nav( $args = array() ) {
611
-
612
- $args = wp_parse_args(
613
- $args,
614
- array(
615
- 'num_pages' => 0,
616
- 'paged' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1,
617
- 'wrapper_class' => 'learn-press-pagination',
618
- 'base' => false
619
- )
620
- );
621
- if ( $args['num_pages'] < 2 ) {
622
- return;
623
- }
624
- $paged = $args['paged'];
625
- $pagenum_link = html_entity_decode( $args['base'] === false ? get_pagenum_link() : $args['base'] );
626
-
627
- $query_args = array();
628
- $url_parts = explode( '?', $pagenum_link );
629
-
630
- if ( isset( $url_parts[1] ) ) {
631
- wp_parse_str( $url_parts[1], $query_args );
632
- }
633
-
634
- $pagenum_link = remove_query_arg( array_keys( $query_args ), $pagenum_link );
635
- $pagenum_link = trailingslashit( $pagenum_link ) . '%_%';
636
-
637
- $format = $GLOBALS['wp_rewrite']->using_index_permalinks() && !strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
638
- $format .= $GLOBALS['wp_rewrite']->using_permalinks() ? user_trailingslashit( 'page/%#%', 'paged' ) : '?paged=%#%';
639
-
640
- // Set up paginated links.
641
- $links = paginate_links( array(
642
- 'base' => $pagenum_link,
643
- 'format' => $format,
644
- 'total' => $args['num_pages'],
645
- 'current' => max( 1, $paged ),
646
- 'mid_size' => 1,
647
- 'add_args' => array_map( 'urlencode', $query_args ),
648
- 'prev_text' => __( '<', 'learnpress' ),
649
- 'next_text' => __( '>', 'learnpress' ),
650
- 'type' => 'list'
651
- ) );
652
-
653
- if ( $links ) :
654
- ?>
655
- <div class="<?php echo $args['wrapper_class']; ?>">
656
- <?php echo $links; ?>
657
- </div>
658
- <!-- .pagination -->
659
- <?php
660
- endif;
661
- }
662
-
663
- endif;
664
-
665
- /**
666
- * Get number of pages by rows and items per page
667
- *
668
- * @param $total
669
- * @param int $limit
670
- *
671
- * @return int
672
- */
673
- function learn_press_get_num_pages( $total, $limit = 10 ) {
674
- // added to ensure $limit is greater than 1
675
- $limit = $limit <= 0 ? 10 : $limit;
676
- if ( $total <= $limit ) {
677
- return 1;
678
- }
679
- $pages = absint( $total / $limit );
680
- if ( $total % $limit != 0 ) {
681
- $pages ++;
682
- }
683
- return $pages;
684
- }
685
-
686
- /**
687
- * Get text
688
- *
689
- * @param $status_id
690
- *
691
- * @return mixed
692
- */
693
- function learn_press_get_status_text( $status_id ) {
694
- switch ( $status_id ) {
695
- case 1:
696
- $text = 'pending';
697
- break;
698
- case 2:
699
- $text = 'complete';
700
- break;
701
- case - 1:
702
- $text = 'cancel';
703
- break;
704
- case - 2:
705
- $text = 'refund';
706
- break;
707
- default:
708
- $text = 'on-hold';
709
- }
710
-
711
- return $text;
712
- }
713
-
714
- // processing registration
715
-
716
-
717
- /*
718
- * Get LeanrPress current profile permalink
719
- */
720
-
721
- function learn_press_get_current_profile_link() {
722
- if ( !learn_press_has_profile_method() ) {
723
- return;
724
- }
725
- global $wp_rewrite;
726
- if ( empty( $wp_rewrite->permalink_structure ) ) {
727
- return;
728
- }
729
- $current_user = wp_get_current_user();
730
- $link = home_url( "/profile/$current_user->user_login" );
731
-
732
- return $link;
733
- }
734
-
735
- /*
736
- * Get LeanrPress profile permalink
737
- */
738
- function learn_press_get_profile_link( $link, $user_id, $course_id ) {
739
- ///_deprecated_function( __FUNCTION__, '1.0', 'learn_press_course_profile_link');
740
- return learn_press_course_profile_link( $course_id );
741
- }
742
-
743
- function learn_press_get_course_duration_support() {
744
- return apply_filters(
745
- 'learn_press_course_duration_support',
746
- array(
747
- 'minute' => __( 'Minute(s)' ),
748
- 'hour' => __( 'Hour(s)' ),
749
- 'day' => __( 'Day(s)' ),
750
- 'week' => __( 'Week(s)' )
751
- )
752
- );
753
- }
754
-
755
- function learn_press_human_time_to_seconds( $time, $default = '' ) {
756
- $duration = learn_press_get_course_duration_support();
757
- $duration_keys = array_keys( $duration );
758
- if ( preg_match_all( '!([0-9]+)\s*(' . join( '|', $duration_keys ) . ')?!', $time, $matches ) ) {
759
- $a1 = $matches[1][0];
760
- $a2 = in_array( $matches[2][0], $duration_keys ) ? $matches[2][0] : '';
761
- } else {
762
- $a1 = absint( $time );
763
- $a2 = '';
764
- }
765
- if ( $a2 ) {
766
- $b = array(
767
- 'minute' => 60,
768
- 'hour' => 3600,
769
- 'day' => 3600 * 24,
770
- 'week' => 3600 * 24 * 7
771
- );
772
- $a1 = $a1 * $b[$a2];
773
- }
774
- return $a1;
775
- }
776
-
777
- /**
778
- * Return profile link of an user from a course
779
- *
780
- * @param int $course_id
781
- *
782
- * @return mixed|void
783
- */
784
- function learn_press_course_profile_link( $course_id = 0 ) {
785
- $link = null;
786
- if ( !$course_id ) {
787
- $course_id = get_the_ID();
788
- }
789
- $course_author = false;
790
- if ( get_post( $course_id ) == 'lp_course' && $course_author = get_post_field( 'post_author', $course_id ) ) {
791
- $link = learn_press_user_profile_link( $course_author );
792
- }
793
- return apply_filters( 'learn_press_course_profile_link', $link, $course_id, $course_author );
794
- }
795
-
796
- /*
797
- * Course tabs
798
- */
799
- add_action( 'all_admin_notices', 'learn_press_admin_course_tabs' );
800
- function learn_press_admin_course_tabs() {
801
- if ( !is_admin() ) {
802
- return;
803
- }
804
- $admin_tabs = apply_filters(
805
- 'learn_press_admin_tabs_info',
806
- array(
807
-
808
- 10 => array(
809
- "link" => "edit.php?post_type=lp_course",
810
- "name" => __( "Courses", "learnpress" ),
811
- "id" => "edit-lp_course",
812
- ),
813
-
814
- 20 => array(
815
- "link" => "edit-tags.php?taxonomy=course_category&post_type=lp_course",
816
- "name" => __( "Categories", "learnpress" ),
817
- "id" => "edit-course_category",
818
- ),
819
- 30 => array(
820
- "link" => "edit-tags.php?taxonomy=course_tag&post_type=lp_course",
821
- "name" => __( "Tags", "learnpress" ),
822
- "id" => "edit-course_tag",
823
- ),
824
-
825
- )
826
- );
827
- ksort( $admin_tabs );
828
- $tabs = array();
829
- foreach ( $admin_tabs as $key => $value ) {
830
- array_push( $tabs, $key );
831
- }
832
- $pages = apply_filters(
833
- 'learn_press_admin_tabs_on_pages',
834
- array( 'edit-lp_course', 'edit-course_category', 'edit-course_tag', 'lp_course' )
835
- );
836
- $admin_tabs_on_page = array();
837
- foreach ( $pages as $page ) {
838
- $admin_tabs_on_page[$page] = $tabs;
839
- }
840
-
841
-
842
- $current_page_id = get_current_screen()->id;
843
- $current_user = wp_get_current_user();
844
- if ( !in_array( 'administrator', $current_user->roles ) ) {
845
- return;
846
- }
847
- if ( !empty( $admin_tabs_on_page[$current_page_id] ) && count( $admin_tabs_on_page[$current_page_id] ) ) {
848
- echo '<h2 class="nav-tab-wrapper lp-nav-tab-wrapper">';
849
- foreach ( $admin_tabs_on_page[$current_page_id] as $admin_tab_id ) {
850
-
851
- $class = ( $admin_tabs[$admin_tab_id]["id"] == $current_page_id ) ? "nav-tab nav-tab-active" : "nav-tab";
852
- echo '<a href="' . admin_url( $admin_tabs[$admin_tab_id]["link"] ) . '" class="' . $class . ' nav-tab-' . $admin_tabs[$admin_tab_id]["id"] . '">' . $admin_tabs[$admin_tab_id]["name"] . '</a>';
853
- }
854
- echo '</h2>';
855
- }
856
- }
857
-
858
- add_action( 'admin_footer', 'learn_press_show_menu' );
859
- function learn_press_show_menu() {
860
- if ( ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'lp_course' ) ) {
861
- ?>
862
- <script type="text/javascript">
863
- jQuery(window).load(function ($) {
864
- <?php
865
- if ( isset ( $_GET['taxonomy'] ) ) {
866
- ?>
867
- jQuery("body").removeClass("sticky-menu");
868
- jQuery("#toplevel_page_learn_press").addClass('wp-has-current-submenu wp-menu-open').removeClass('wp-not-current-submenu');
869
- jQuery("#toplevel_page_learn_press > a").addClass('wp-has-current-submenu wp-menu-open').removeClass('wp-not-current-submenu');
870
- <?php
871
- }
872
- ?>
873
- jQuery("#toplevel_page_learn_press .wp-first-item").addClass('current');
874
- });
875
- </script>
876
- <?php
877
- }
878
-
879
- if ( isset( $_GET['post_type'] ) ) {
880
- ?>
881
- <script type="text/javascript">
882
- (function ($) {
883
-
884
- var $lpMainMenu = $('#toplevel_page_learn_press'),
885
- href = 'edit.php?post_type=<?php echo $_GET['post_type']; ?>',
886
- $current = $('a[href="' + href + '"]', $lpMainMenu);
887
-
888
- if ($current.length) {
889
- $current.addClass('current');
890
- $current.parent('li').addClass('current');
891
- }
892
- })(jQuery)
893
- </script>
894
- <?php
895
-
896
- }
897
- }
898
-
899
- /**
900
- * Send email notification.
901
- *
902
- * @param string $to
903
- * @param string $action
904
- * @param array $vars
905
- *
906
- * @return mixed
907
- */
908
- function learn_press_send_mail( $to, $action, $vars ) {
909
-
910
- $email_settings = LP_Settings::instance( 'emails' );
911
- if ( !$email_settings->get( $action . '.enable' ) ) {
912
- return "The action {$action} doesnt support";
913
- }
914
- $user = get_user_by( 'email', $to );
915
- if ( in_array( 'administrator', $user->roles ) ) {
916
- //return;
917
- }
918
- // Set default template vars.
919
- $vars['log_in'] = apply_filters( 'learn_press_site_url', get_home_url() );
920
-
921
- // Send email.
922
- $email = new LP_Email();
923
- $email->set_action( $action );
924
- $email->parse_email( $vars );
925
- $email->add_recipient( $to );
926
-
927
- return $email->send();
928
- }
929
-
930
- /*
931
- * Send email notification when a course be published
932
- */
933
- function learn_press_publish_course( $new_status, $old_status, $post ) {
934
- if ( $old_status == 'pending' && $new_status == 'publish' && $post->post_type == 'lp_course' ) {
935
- $instructor = get_userdata( $post->post_author );
936
- $mail_to = $instructor->user_email;
937
- learn_press_send_mail(
938
- $mail_to,
939
- 'published_course',
940
- apply_filters(
941
- 'learn_press_vars_enrolled_course',
942
- array(
943
- 'user_name' => $instructor->display_name,
944
- 'course_name' => $post->post_title,
945
- 'course_link' => get_permalink( $post->ID )
946
- ),
947
- $post,
948
- $instructor
949
- )
950
- );
951
- }
952
- }
953
-
954
- add_action( 'transition_post_status', 'learn_press_publish_course', 10, 3 );
955
-
956
- /**
957
- * @param $user_id
958
- *
959
- * @return WP_Query
960
- */
961
- function learn_press_get_enrolled_courses( $user_id ) {
962
- return LP()->get_user( $user_id )->get( 'enrolled-courses' );
963
- }
964
-
965
- /**
966
- * @param $user_id
967
- *
968
- * @return WP_Query
969
- */
970
- function learn_press_get_own_courses( $user_id ) {
971
-
972
- $arr_query = array(
973
- 'post_type' => 'lp_course',
974
- 'author' => $user_id,
975
- 'post_status' => 'publish',
976
- 'ignore_sticky_posts' => true,
977
- 'posts_per_page' => - 1
978
- );
979
- $my_query = new WP_Query( $arr_query );
980
-
981
- return $my_query;
982
- }
983
-
984
-
985
- function learn_press_currency_positions() {
986
- return apply_filters(
987
- 'learn_press_currency_positions',
988
- array(
989
- 'left' => __( 'Left', 'learnpress' ),
990
- 'right' => __( 'Right', 'learnpress' ),
991
- 'left_with_space' => __( 'Left with space', 'learnpress' ),
992
- 'right_with_space' => __( 'Right with space', 'learnpress' )
993
-
994
- )
995
- );
996
- }
997
-
998
- /**
999
- * get the list of currencies with code and name
1000
- *
1001
- * @author ThimPress
1002
- * @return array
1003
- */
1004
- function learn_press_get_payment_currencies() {
1005
- $currencies = array(
1006
- 'AED' => 'United Arab Emirates Dirham (د.إ)',
1007
- 'AUD' => 'Australian Dollars ($)',
1008
- 'BDT' => 'Bangladeshi Taka (৳&nbsp;)',
1009
- 'BRL' => 'Brazilian Real (R$)',
1010
- 'BGN' => 'Bulgarian Lev (лв.)',
1011
- 'CAD' => 'Canadian Dollars ($)',
1012
- 'CLP' => 'Chilean Peso ($)',
1013
- 'CNY' => 'Chinese Yuan (¥)',
1014
- 'COP' => 'Colombian Peso ($)',
1015
- 'CZK' => 'Czech Koruna (Kč)',
1016
- 'DKK' => 'Danish Krone (kr.)',
1017
- 'DOP' => 'Dominican Peso (RD$)',
1018
- 'EUR' => 'Euros (€)',
1019
- 'HKD' => 'Hong Kong Dollar ($)',
1020
- 'HRK' => 'Croatia kuna (Kn)',
1021
- 'HUF' => 'Hungarian Forint (Ft)',
1022
- 'ISK' => 'Icelandic krona (Kr.)',
1023
- 'IDR' => 'Indonesia Rupiah (Rp)',
1024
- 'INR' => 'Indian Rupee (Rs.)',
1025
- 'NPR' => 'Nepali Rupee (Rs.)',
1026
- 'ILS' => 'Israeli Shekel (₪)',
1027
- 'JPY' => 'Japanese Yen (¥)',
1028
- 'KIP' => 'Lao Kip (₭)',
1029
- 'KRW' => 'South Korean Won (₩)',
1030
- 'MYR' => 'Malaysian Ringgits (RM)',
1031
- 'MXN' => 'Mexican Peso ($)',
1032
- 'NGN' => 'Nigerian Naira (₦)',
1033
- 'NOK' => 'Norwegian Krone (kr)',
1034
- 'NZD' => 'New Zealand Dollar ($)',
1035
- 'PYG' => 'Paraguayan Guaraní (₲)',
1036
- 'PHP' => 'Philippine Pesos (₱)',
1037
- 'PLN' => 'Polish Zloty (zł)',
1038
- 'GBP' => 'Pounds Sterling (£)',
1039
- 'RON' => 'Romanian Leu (lei)',
1040
- 'RUB' => 'Russian Ruble (руб.)',
1041
- 'SGD' => 'Singapore Dollar ($)',
1042
- 'ZAR' => 'South African rand (R)',
1043
- 'SEK' => 'Swedish Krona (kr)',
1044
- 'CHF' => 'Swiss Franc (CHF)',
1045
- 'TWD' => 'Taiwan New Dollars (NT$)',
1046
- 'THB' => 'Thai Baht (฿)',
1047
- 'TRY' => 'Turkish Lira (₺)',
1048
- 'USD' => 'US Dollars ($)',
1049
- 'VND' => 'Vietnamese Dong (₫)',
1050
- 'EGP' => 'Egyptian Pound (EGP)'
1051
- );
1052
-
1053
- return apply_filters( 'learn_press_get_payment_currencies', $currencies );
1054
- }
1055
-
1056
- function learn_press_get_currency() {
1057
- $currencies = learn_press_get_payment_currencies();
1058
- $currency_codes = array_keys( $currencies );
1059
- $currency = reset( $currency_codes );
1060
-
1061
- return apply_filters( 'learn_press_currency', LP_Settings::instance( 'general' )->get( 'currency', $currency ) );
1062
- }
1063
-
1064
- function learn_press_get_currency_symbol( $currency = '' ) {
1065
- if ( !$currency ) {
1066
- $currency = learn_press_get_currency();
1067
- }
1068
-
1069
- switch ( $currency ) {
1070
- case 'AED' :
1071
- $currency_symbol = 'د.إ';
1072
- break;
1073
- case 'AUD' :
1074
- case 'CAD' :
1075
- case 'CLP' :
1076
- case 'COP' :
1077
- case 'HKD' :
1078
- case 'MXN' :
1079
- case 'NZD' :
1080
- case 'SGD' :
1081
- case 'USD' :
1082
- $currency_symbol = '&#36;';
1083
- break;
1084
- case 'BDT':
1085
- $currency_symbol = '&#2547;&nbsp;';
1086
- break;
1087
- case 'BGN' :
1088
- $currency_symbol = '&#1083;&#1074;.';
1089
- break;
1090
- case 'BRL' :
1091
- $currency_symbol = '&#82;&#36;';
1092
- break;
1093
- case 'CHF' :
1094
- $currency_symbol = '&#67;&#72;&#70;';
1095
- break;
1096
- case 'CNY' :
1097
- case 'JPY' :
1098
- case 'RMB' :
1099
- $currency_symbol = '&yen;';
1100
- break;
1101
- case 'CZK' :
1102
- $currency_symbol = '&#75;&#269;';
1103
- break;
1104
- case 'DKK' :
1105
- $currency_symbol = 'kr.';
1106
- break;
1107
- case 'DOP' :
1108
- $currency_symbol = 'RD&#36;';
1109
- break;
1110
- case 'EGP' :
1111
- $currency_symbol = 'EGP';
1112
- break;
1113
- case 'EUR' :
1114
- $currency_symbol = '&euro;';
1115
- break;
1116
- case 'GBP' :
1117
- $currency_symbol = '&pound;';
1118
- break;
1119
- case 'HRK' :
1120
- $currency_symbol = 'Kn';
1121
- break;
1122
- case 'HUF' :
1123
- $currency_symbol = '&#70;&#116;';
1124
- break;
1125
- case 'IDR' :
1126
- $currency_symbol = 'Rp';
1127
- break;
1128
- case 'ILS' :
1129
- $currency_symbol = '&#8362;';
1130
- break;
1131
- case 'INR' :
1132
- $currency_symbol = 'Rs.';
1133
- break;
1134
- case 'ISK' :
1135
- $currency_symbol = 'Kr.';
1136
- break;
1137
- case 'KIP' :
1138
- $currency_symbol = '&#8365;';
1139
- break;
1140
- case 'KRW' :
1141
- $currency_symbol = '&#8361;';
1142
- break;
1143
- case 'MYR' :
1144
- $currency_symbol = '&#82;&#77;';
1145
- break;
1146
- case 'NGN' :
1147
- $currency_symbol = '&#8358;';
1148
- break;
1149
- case 'NOK' :
1150
- $currency_symbol = '&#107;&#114;';
1151
- break;
1152
- case 'NPR' :
1153
- $currency_symbol = 'Rs.';
1154
- break;
1155
- case 'PHP' :
1156
- $currency_symbol = '&#8369;';
1157
- break;
1158
- case 'PLN' :
1159
- $currency_symbol = '&#122;&#322;';
1160
- break;
1161
- case 'PYG' :
1162
- $currency_symbol = '&#8370;';
1163
- break;
1164
- case 'RON' :
1165
- $currency_symbol = 'lei';
1166
- break;
1167
- case 'RUB' :
1168
- $currency_symbol = '&#1088;&#1091;&#1073;.';
1169
- break;
1170
- case 'SEK' :
1171
- $currency_symbol = '&#107;&#114;';
1172
- break;
1173
- case 'THB' :
1174
- $currency_symbol = '&#3647;';
1175
- break;
1176
- case 'TRY' :
1177
- $currency_symbol = '&#8378;';
1178
- break;
1179
- case 'TWD' :
1180
- $currency_symbol = '&#78;&#84;&#36;';
1181
- break;
1182
- case 'UAH' :
1183
- $currency_symbol = '&#8372;';
1184
- break;
1185
- case 'VND' :
1186
- $currency_symbol = '&#8363;';
1187
- break;
1188
- case 'ZAR' :
1189
- $currency_symbol = '&#82;';
1190
- break;
1191
- default :
1192
- $currency_symbol = $currency;
1193
- break;
1194
- }
1195
-
1196
- return apply_filters( 'learn_press_currency_symbol', $currency_symbol, $currency );
1197
- }
1198
-
1199
- function learn_press_get_page_link( $key ) {
1200
- $page_id = LP()->settings->get( $key . '_page_id' );
1201
- if ( get_post_status( $page_id ) == 'publish' ) {
1202
- $link = apply_filters( 'learn_press_get_page_link', get_permalink( $page_id ), $page_id, $key );
1203
- } else {
1204
- $link = '';
1205
- }
1206
- return apply_filters( 'learn_press_get_page_' . $key . '_link', $link, $page_id );
1207
- }
1208
-
1209
-
1210
- /**
1211
- * get the ID of a course by order ID
1212
- *
1213
- * @param $order_id
1214
- *
1215
- * @return bool|mixed
1216
- */
1217
- function learn_press_get_course_by_order( $order_id ) {
1218
- $order_items = get_post_meta( $order_id, '_learn_press_order_items', true );
1219
-
1220
- if ( $order_items && $order_items->products ) {
1221
- $array_keys = array_keys( $order_items->products );
1222
-
1223
- return reset( $array_keys );
1224
- }
1225
-
1226
- return false;
1227
- }
1228
-
1229
-
1230
- function learn_press_seconds_to_weeks( $secs ) {
1231
- $secs = (int) $secs;
1232
- if ( $secs === 0 ) {
1233
- return false;
1234
- }
1235
- // variables for holding values
1236
- $mins = 0;
1237
- $hours = 0;
1238
- $days = 0;
1239
- $weeks = 0;
1240
- // calculations
1241
- if ( $secs >= 60 ) {
1242
- $mins = (int) ( $secs / 60 );
1243
- $secs = $secs % 60;
1244
- }
1245
- if ( $mins >= 60 ) {
1246
- $hours = (int) ( $mins / 60 );
1247
- $mins = $mins % 60;
1248
- }
1249
- if ( $hours >= 24 ) {
1250
- $days = (int) ( $hours / 24 );
1251
- $hours = $hours % 24;
1252
- }
1253
- if ( $days >= 7 ) {
1254
- $weeks = (int) ( $days / 7 );
1255
- $days = $days % 7;
1256
- }
1257
- // format result
1258
- $result = '';
1259
- if ( $weeks ) {
1260
- $result .= $weeks . ' ' . __( 'week(s)', 'learnpress' ) . ' ';
1261
- }
1262
-
1263
- if ( $days ) {
1264
- $result .= $days . ' ' . __( 'day(s)', 'learnpress' ) . ' ';
1265
- }
1266
-
1267
- if ( !$weeks ) {
1268
- if ( $hours ) {
1269
- $result .= $hours . ' ' . __( 'hour(s)', 'learnpress' ) . ' ';
1270
-
1271
- }
1272
- if ( $mins ) {
1273
- $result .= $mins . ' ' . __( 'min(s)', 'learnpress' ) . ' ';
1274
- }
1275
- }
1276
- $result = rtrim( $result );
1277
-
1278
- return $result;
1279
- }
1280
-
1281
- add_action( 'learn_press_frontend_action_retake_course', array( 'LP_AJAX', 'retake_course' ) );
1282
-
1283
- function learn_press_get_query_var( $var ) {
1284
- global $wp_query;
1285
-
1286
- $return = null;
1287
- if ( !empty( $wp_query->query_vars[$var] ) ) {
1288
- $return = $wp_query->query_vars[$var];
1289
- } elseif ( !empty( $_REQUEST[$var] ) ) {
1290
- $return = $_REQUEST[$var];
1291
- }
1292
-
1293
- return apply_filters( 'learn_press_query_var', $return, $var );
1294
- }
1295
-
1296
- ///////////////////////////////
1297
-
1298
-
1299
- function learn_press_course_lesson_permalink_friendly( $permalink, $lesson_id, $course_id ) {
1300
-
1301
- if ( '' != get_option( 'permalink_structure' ) ) {
1302
- if ( preg_match( '!\?lesson=([^\?\&]*)!', $permalink, $matches ) ) {
1303
- $permalink = preg_replace( '!/?\?lesson=([^\?\&]*)!', '/' . basename( get_permalink( $matches[1] ) ), untrailingslashit( $permalink ) );
1304
- }
1305
- }
1306
-
1307
- return $permalink;
1308
- }
1309
-
1310
- function learn_press_course_question_permalink_friendly( $permalink, $lesson_id, $course_id ) {
1311
-
1312
- if ( '' != get_option( 'permalink_structure' ) ) {
1313
- if ( preg_match( '!\?lesson=([^\?\&]*)!', $permalink, $matches ) ) {
1314
- $permalink = preg_replace( '!/?\?lesson=([^\?\&]*)!', '/' . basename( get_permalink( $matches[1] ) ), untrailingslashit( $permalink ) );
1315
- }
1316
- }
1317
-
1318
- return $permalink;
1319
- }
1320
-
1321
- add_filter( 'learn_press_course_lesson_permalink', 'learn_press_course_lesson_permalink_friendly', 10, 3 );
1322
-
1323
-
1324
- function learn_press_user_maybe_is_a_teacher( $user = null ) {
1325
- if ( !$user ) {
1326
- $user = learn_press_get_current_user();
1327
- } else if ( is_numeric( $user ) ) {
1328
- $user = learn_press_get_user( $user );
1329
- }
1330
- if ( !$user ) {
1331
- return false;
1332
- }
1333
- $role = in_array( 'administrator', $user->user->roles ) ? 'administrator' : false;
1334
- if ( !$role ) {
1335
- $role = in_array( 'lp_teacher', $user->user->roles ) ? 'lp_teacher' : false;
1336
- }
1337
- return apply_filters( 'learn_press_user_maybe_is_a_teacher', $role, $user->id );
1338
- }
1339
-
1340
- function learn_press_process_become_a_teacher_form( $args = null ) {
1341
- $user = learn_press_get_current_user();
1342
- $error = false;
1343
- $return = array(
1344
- 'result' => 'success'
1345
- );
1346
-
1347
- if ( !$error ) {
1348
-
1349
- $args = wp_parse_args(
1350
- $args,
1351
- array(
1352
- 'name' => null,
1353
- 'email' => null,
1354
- 'phone' => null
1355
- )
1356
- );
1357
-
1358
- $return['message'] = array();
1359
-
1360
- if ( !$args['name'] ) {
1361
- $return['message'][] = learn_press_get_message( __( 'Please enter your name', 'learnpress' ), 'error' );
1362
- $error = true;
1363
- }
1364
-
1365
- if ( !$args['email'] ) {
1366
- $return['message'][] = learn_press_get_message( __( 'Please enter your email address', 'learnpress' ), 'error' );
1367
- $error = true;
1368
- }
1369
- }
1370
- if ( !$error ) {
1371
- $to_email = array( get_option( 'admin_email' ) );
1372
- $message_headers = '';
1373
- $subject = __( 'Please moderate', 'learnpress' );
1374
- $notify_message = sprintf( __( 'The user <a href="%s">%s</a> wants to be a teacher.', 'learnpress' ) . "\r\n", admin_url( 'user-edit.php?user_id=' . $user->id ), $user->user_login ) . "\r\n";
1375
-
1376
- $notify_message .= sprintf( __( 'Name: %s', 'learnpress' ), $args['name'] ) . "\r\n";
1377
- $notify_message .= sprintf( __( 'Email: %s', 'learnpress' ), $args['email'] ) . "\r\n";
1378
- $notify_message .= sprintf( __( 'Phone: %s', 'learnpress' ), $args['phone'] ) . "\r\n";
1379
- $notify_message .= wp_specialchars_decode( sprintf( __( 'Accept: %s', 'learnpress' ), wp_nonce_url( admin_url( 'user-edit.php?user_id=' . $user->id ) . '&action=accept-to-be-teacher', 'accept-to-be-teacher' ) ) ) . "\r\n";
1380
- $args = array(
1381
- $to_email,
1382
- ( $subject ),
1383
- $notify_message,
1384
- $message_headers
1385
- );
1386
-
1387
- @call_user_func_array( 'wp_mail', $args );
1388
- $return['message'][] = learn_press_get_message( __( 'Your request has been sent! We will get in touch with you soon!', 'learnpress' ) );
1389
-
1390
- set_transient( 'learn_press_become_teacher_sent_' . $user->id, 'yes', HOUR_IN_SECONDS * 2 );
1391
- }
1392
- $return['result'] = $error ? 'error' : 'success';
1393
- return $return;
1394
- }
1395
-
1396
- function learn_press_become_teacher_sent( $user_id = 0 ) {
1397
- $sent = learn_press_user_maybe_is_a_teacher( $user_id );
1398
- if ( !$sent ) {
1399
- $sent = get_transient( 'learn_press_become_teacher_sent_' . $user_id ) == 'yes';
1400
- }
1401
- return $sent;
1402
- }
1403
-
1404
- function _learn_press_translate_user_roles( $translations, $text, $context, $domain ) {
1405
-
1406
- $plugin_domain = 'learnpress';
1407
-
1408
- $roles = array(
1409
- 'Instructor',
1410
- );
1411
-
1412
- if (
1413
- $context === 'User role'
1414
- && in_array( $text, $roles )
1415
- && $domain !== $plugin_domain
1416
- ) {
1417
- return translate_with_gettext_context( $text, $context, $plugin_domain );
1418
- }
1419
-
1420
- return $translations;
1421
- }
1422
-
1423
- add_filter( 'gettext_with_context', '_learn_press_translate_user_roles', 10, 4 );
1424
-
1425
- /**
1426
- * @param mixed
1427
- * @param string
1428
- * @param string
1429
- */
1430
- function learn_press_output_file( $data, $file, $path = null ) {
1431
- if ( !$path ) {
1432
- $path = LP_PLUGIN_PATH;
1433
- }
1434
- ob_start();
1435
- print_r( $data );
1436
- $output = ob_get_clean();
1437
- file_put_contents( $path . '/' . $file, $output );
1438
- }
1439
-
1440
- /**
1441
- * Modifies the statement $where to make the search works correct
1442
- *
1443
- * @param string
1444
- *
1445
- * @return string
1446
- */
1447
- function learn_press_posts_where_statement_search( $where ) {
1448
- //gets the global query var object
1449
- global $wp_query, $wpdb;
1450
-
1451
- /**
1452
- * Need to wrap this block into () in order to make it works correctly when filter by specific post type => maybe a bug :)
1453
- * from => ( wp_2_posts.post_status = 'publish' OR wp_2_posts.post_status = 'private') OR wp_2_terms.name LIKE '%s%'
1454
- * to => ( ( wp_2_posts.post_status = 'publish' OR wp_2_posts.post_status = 'private') OR wp_2_terms.name LIKE '%s%' )
1455
- */
1456
- $a = preg_match( '!(' . $wpdb->posts . '.post_status)!', $where );
1457
- $b = preg_match( '!(OR\s+' . $wpdb->terms . '.name LIKE \'%' . $wp_query->get( 's' ) . '%\')!', $where );
1458
-
1459
- if ( $a && $b ) {
1460
- // append ( to the start of the block
1461
- $where = preg_replace( '!(' . $wpdb->posts . '.post_status)!', '( $1', $where, 1 );
1462
-
1463
- // append ) to the end of the block
1464
- $where = preg_replace( '!(OR\s+' . $wpdb->terms . '.name LIKE \'%' . $wp_query->get( 's' ) . '%\')!', '$1 )', $where );
1465
- }
1466
- remove_filter( 'posts_where', 'learn_press_posts_where_statement_search', 99 );
1467
-
1468
- return $where;
1469
- }
1470
-
1471
- /**
1472
- * Filter post type for search function
1473
- * Only search lpr_course if see the param ref=course in request
1474
- *
1475
- * @param $q
1476
- */
1477
- function learn_press_filter_search( $q ) {
1478
- if ( $q->is_main_query() && $q->is_search() && ( !empty( $_REQUEST['ref'] ) && $_REQUEST['ref'] == 'course' ) ) {
1479
- $q->set( 'post_type', 'lp_course' );
1480
- add_filter( 'posts_where', 'learn_press_posts_where_statement_search', 99 );
1481
-
1482
- remove_filter( 'pre_get_posts', 'learn_press_filter_search', 99 );
1483
- }
1484
- }
1485
-
1486
- add_filter( 'pre_get_posts', 'learn_press_filter_search', 99 );
1487
-
1488
- /**
1489
- * Convert an object|array to json format and send it to the browser
1490
- *
1491
- * @param $data
1492
- */
1493
- function learn_press_send_json( $data ) {
1494
- echo '<!-- LP_AJAX_START -->';
1495
- @header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
1496
- echo wp_json_encode( $data );
1497
- echo '<!-- LP_AJAX_END -->';
1498
- die;
1499
- }
1500
-
1501
- /**
1502
- * Get data from request
1503
- *
1504
- * @param string
1505
- * @param mixed
1506
- * @param mixed
1507
- *
1508
- * @return mixed
1509
- */
1510
- function learn_press_get_request( $key, $default = null, $hash = null ) {
1511
- $return = $default;
1512
- if ( $hash ) {
1513
- if ( !empty( $hash[$key] ) ) {
1514
- $return = $hash[$key];
1515
- }
1516
- } else {
1517
- if ( !empty( $_POST[$key] ) ) {
1518
- $return = $_POST[$key];
1519
- } elseif ( !empty( $_GET[$key] ) ) {
1520
- $return = $_GET[$key];
1521
- } elseif ( !empty( $_REQUEST[$key] ) ) {
1522
- $return = $_REQUEST[$key];
1523
- }
1524
- }
1525
- return $return;
1526
- }
1527
-
1528
-
1529
- /**
1530
- * @return mixed|void
1531
- */
1532
- function is_learnpress() {
1533
- return apply_filters( 'is_learnpress', ( learn_press_is_course_archive() || learn_press_is_course_taxonomy() || learn_press_is_course() || learn_press_is_quiz() || learn_press_is_search() ) ? true : false );
1534
- }
1535
-
1536
- if ( !function_exists( 'learn_press_is_search' ) ) {
1537
- /**
1538
- * @return bool
1539
- */
1540
- function learn_press_is_search() {
1541
- return array_key_exists( 's', $_REQUEST ) && array_key_exists( 'ref', $_REQUEST ) && $_REQUEST['ref'] == 'course';
1542
- }
1543
- }
1544
-
1545
- if ( !function_exists( 'learn_press_is_courses' ) ) {
1546
-
1547
- /**
1548
- * Returns true when viewing the course type archive.
1549
- *
1550
- * @return bool
1551
- */
1552
- function learn_press_is_courses() {
1553
- return learn_press_is_course_archive();
1554
- }
1555
- }
1556
-
1557
-
1558
- if ( !function_exists( 'learn_press_is_course_archive' ) ) {
1559
-
1560
- /**
1561
- * Returns true when viewing the course type archive.
1562
- *
1563
- * @return bool
1564
- */
1565
- function learn_press_is_course_archive() {
1566
- global $wp_query;
1567
- $queried_object_id = !empty( $wp_query->queried_object ) ? $wp_query->queried_object : 0;
1568
- $is_courses = defined( 'LEARNPRESS_IS_COURSES' ) && LEARNPRESS_IS_COURSES;
1569
- $is_tag = defined( 'LEARNPRESS_IS_TAG' ) && LEARNPRESS_IS_TAG;
1570
- $is_category = defined( 'LEARNPRESS_IS_CATEGORY' ) && LEARNPRESS_IS_CATEGORY;
1571
- $page_id = learn_press_get_page_id( 'courses' );
1572
- return ( ( $is_courses || $is_category || $is_tag ) || is_post_type_archive( 'lp_course' ) || ( $page_id && ( $queried_object_id && is_page( $page_id ) ) ) ) ? true : false;
1573
- }
1574
- }
1575
-
1576
- if ( !function_exists( 'learn_press_is_course_taxonomy' ) ) {
1577
-
1578
- /**
1579
- * Returns true when viewing a course taxonomy archive.
1580
- *
1581
- * @return bool
1582
- */
1583
- function learn_press_is_course_taxonomy() {
1584
- return ( defined( 'LEARNPRESS_IS_TAX' ) && LEARNPRESS_IS_TAX ) || is_tax( get_object_taxonomies( 'lp_course' ) );
1585
- }
1586
- }
1587
-
1588
-
1589
- if ( !function_exists( 'learn_press_is_course_category' ) ) {
1590
-
1591
- /**
1592
- * Returns true when viewing a course category.
1593
- *
1594
- * @param string
1595
- *
1596
- * @return bool
1597
- */
1598
- function learn_press_is_course_category( $term = '' ) {
1599
- return ( defined( 'LEARNPRESS_IS_CATEGORY' ) && LEARNPRESS_IS_CATEGORY ) || is_tax( 'course_category', $term );
1600
- }
1601
- }
1602
-
1603
-
1604
- if ( !function_exists( 'learn_press_is_course_tag' ) ) {
1605
-
1606
- /**
1607
- * Returns true when viewing a course tag.
1608
- *
1609
- * @param string
1610
- *
1611
- * @return bool
1612
- */
1613
- function learn_press_is_course_tag( $term = '' ) {
1614
- return ( defined( 'LEARNPRESS_IS_TAG' ) && LEARNPRESS_IS_TAG ) || is_tax( 'course_tag', $term );
1615
- }
1616
- }
1617
-
1618
- if ( !function_exists( 'learn_press_is_course' ) ) {
1619
-
1620
- /**
1621
- * Returns true when viewing a single course.
1622
- *
1623
- * @return bool
1624
- */
1625
- function learn_press_is_course() {
1626
- return is_singular( array( 'lp_course' ) );
1627
- }
1628
- }
1629
-
1630
- if ( !function_exists( 'learn_press_is_quiz' ) ) {
1631
-
1632
- /**
1633
- * Returns true when viewing a single quiz.
1634
- *
1635
- * @return bool
1636
- */
1637
- function learn_press_is_quiz() {
1638
- return is_singular( array( LP_QUIZ_CPT ) );
1639
- }
1640
- }
1641
-
1642
- if ( !function_exists( 'learn_press_is_profile' ) ) {
1643
-
1644
- /**
1645
- * Returns true when viewing profile page.
1646
- *
1647
- * @return bool
1648
- */
1649
- function learn_press_is_profile() {
1650
- $profile = learn_press_get_page_id( 'profile' );
1651
- return is_page( $profile ) || apply_filters( 'learn_press_is_profile', false ) ? true : false;
1652
- }
1653
- }
1654
-
1655
- /**
1656
- * Return true if user is in checking out page
1657
- *
1658
- * @return bool
1659
- */
1660
- function learn_press_is_checkout() {
1661
- return is_page( learn_press_get_page_id( 'checkout' ) ) || apply_filters( 'learn_press_is_checkout', false ) ? true : false;
1662
- }
1663
-
1664
- /**
1665
- * Return register permalink
1666
- *
1667
- * @return mixed
1668
- */
1669
- function learn_press_get_register_url() {
1670
- return apply_filters( 'learn_press_register_url', wp_registration_url() );
1671
- }
1672
-
1673
- /**
1674
- * Add a new notice into queue
1675
- *
1676
- * @param string
1677
- * @param string
1678
- *
1679
- * @return mixed
1680
- */
1681
- function learn_press_add_notice( $message, $type = 'updated' ) {
1682
- LP_Admin_Notice::add( $message, $type );
1683
- }
1684
-
1685
- /**
1686
- * Set user's cookie
1687
- *
1688
- * @param $name
1689
- * @param $value
1690
- * @param int $expire
1691
- * @param bool $secure
1692
- */
1693
- function learn_press_setcookie( $name, $value, $expire = 0, $secure = false ) {
1694
- if ( !headers_sent() ) {
1695
- setcookie( $name, $value, $expire, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, $secure );
1696
- } elseif ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
1697
- headers_sent( $file, $line );
1698
- trigger_error( "{$name} cookie cannot be set - headers already sent by {$file} on line {$line}", E_USER_NOTICE );
1699
- }
1700
- }
1701
-
1702
- /**
1703
- * Clear cookie
1704
- *
1705
- * @param $name
1706
- */
1707
- function learn_press_remove_cookie( $name ) {
1708
- setcookie( $name, '', time() - YEAR_IN_SECONDS, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN );
1709
- if ( array_key_exists( $name, $_COOKIE ) ) {
1710
- unset( $_COOKIE[$name] );
1711
- }
1712
- }
1713
-
1714
- /**
1715
- * Display all notices from queue and clear queue if required
1716
- *
1717
- * @param bool|true $clear
1718
- */
1719
- function learn_press_print_notices( $clear = true ) {
1720
- if ( $notices = learn_press_session_get( 'notices' ) ) {
1721
- // Allow to reorder the position of notices
1722
- $notice_types = apply_filters( 'learn_press_notice_types', array( 'error', 'success', 'notice' ) );
1723
-
1724
- foreach ( $notice_types as $notice_type ) {
1725
- if ( !empty( $notices[$notice_type] ) ) {
1726
- learn_press_get_template( "notices/{$notice_type}.php", array(
1727
- 'messages' => $notices[$notice_type]
1728
- ) );
1729
- }
1730
- }
1731
-
1732
- // clear queue if required
1733
- if ( $clear ) {
1734
- learn_press_clear_notices();
1735
- }
1736
- }
1737
- }
1738
-
1739
- //add_filter( 'the_content', '_learn_press_print_notices', 1000 );
1740
-
1741
- /**
1742
- * Filter the login url so third-party can be customize
1743
- *
1744
- * @param null $redirect
1745
- *
1746
- * @return mixed
1747
- */
1748
- function learn_press_get_login_url( $redirect = null ) {
1749
- return apply_filters( 'learn_press_login_url', wp_login_url( $redirect ) );
1750
- }
1751
-
1752
- function _learn_press_get_login_url( $url ) {
1753
- if ( $profile_page = learn_press_get_page_link( 'profile' ) ) {
1754
- $a = parse_url( $url );
1755
- $url = $profile_page . ( !empty( $a['query'] ) ? '?' . $a['query'] : '' );
1756
- }
1757
- return $url;
1758
- }
1759
-
1760
- add_filter( 'learn_press_login_url', '_learn_press_get_login_url', 10 );
1761
-
1762
- function learn_press_get_endpoint_url( $name, $value, $url ) {
1763
- if ( !$url )
1764
- $url = get_permalink();
1765
-
1766
- // Map endpoint to options
1767
- $name = isset( LP()->query_vars[$name] ) ? LP()->query_vars[$name] : $name;
1768
-
1769
- if ( get_option( 'permalink_structure' ) ) {
1770
- if ( strstr( $url, '?' ) ) {
1771
- $query_string = '?' . parse_url( $url, PHP_URL_QUERY );
1772
- $url = current( explode( '?', $url ) );
1773
- } else {
1774
- $query_string = '';
1775
- }
1776
- $url = trailingslashit( $url ) . ( $name ? $name . '/' : '' ) . $value . $query_string;
1777
-
1778
- } else {
1779
- $url = add_query_arg( $name, $value, $url );
1780
- }
1781
-
1782
- return apply_filters( 'learn_press_get_endpoint_url', esc_url( $url ), $name, $value, $url );
1783
- }
1784
-
1785
- function learn_press_add_endpoints() {
1786
- if ( is_admin() ) {
1787
- /*
1788
- * Do not return even is admin because the endpoints will not effect while updating permalink
1789
- * fixed 2.0.6
1790
- */
1791
- //return;
1792
- }
1793
- if ( $endpoints = LP()->settings->get( 'checkout_endpoints' ) ) foreach ( $endpoints as $endpoint => $value ) {
1794
- $endpoint = preg_replace( '!_!', '-', $endpoint );
1795
- LP()->query_vars[$endpoint] = $value;
1796
-
1797
- add_rewrite_endpoint( $value, EP_PAGES );
1798
- }
1799
-
1800
- if ( $endpoints = LP()->settings->get( 'profile_endpoints' ) ) foreach ( $endpoints as $endpoint => $value ) {
1801
- $endpoint = preg_replace( '!_!', '-', $endpoint );
1802
- LP()->query_vars[$endpoint] = $value;
1803
- add_rewrite_endpoint( $value, EP_ROOT | EP_PAGES );
1804
- }
1805
-
1806
- if ( $endpoints = LP()->settings->get( 'quiz_endpoints' ) ) foreach ( $endpoints as $endpoint => $value ) {
1807
- $endpoint = preg_replace( '!_!', '-', $endpoint );
1808
- LP()->query_vars[$endpoint] = $value;
1809
- add_rewrite_endpoint( $value, EP_ROOT | EP_PAGES );
1810
- }
1811
- }
1812
-
1813
- add_action( 'init', 'learn_press_add_endpoints' );
1814
-
1815
- function learn_press_is_yes( $value ) {
1816
- return ( $value === 1 ) || ( $value === '1' ) || ( $value == 'yes' ) || ( $value == true ) || ( $value == 'on' );
1817
- }
1818
-
1819
- /**
1820
- * @param $value
1821
- *
1822
- * @return bool
1823
- */
1824
- function _is_false_value( $value ) {
1825
- if ( is_numeric( $value ) ) {
1826
- return $value == 0;
1827
- } elseif ( is_string( $value ) ) {
1828
- return ( empty( $value ) || is_null( $value ) || in_array( $value, array( 'no', 'off', 'false' ) ) );
1829
- }
1830
- return !!$value;
1831
- }
1832
-
1833
- function learn_press_do_parse_request( $parse, $q, $vars ) {
1834
- // lesson
1835
- $course_type = 'lp_course';
1836
- $post_types = get_post_types( '', 'objects' );
1837
-
1838
- $slug = preg_replace( '!^/!', '', $post_types[$course_type]->rewrite['slug'] );
1839
-
1840
- $current_url = learn_press_get_current_url();
1841
- $query_string = str_replace( trailingslashit( get_site_url() ), '', $current_url );
1842
- if ( preg_match( '!^' . $slug . '/([^/]*)/?(.*)?!', $query_string, $matches ) ) {
1843
- if ( !empty( $matches[2] ) ) {
1844
-
1845
- }
1846
- }
1847
- return true;
1848
- }
1849
-
1850
- //add_filter('parse_request', 'learn_press_do_parse_request', 100, 3);
1851
- function learn_press_parse_request() {
1852
- global $wp, $wp_rewrite;
1853
-
1854
- if ( !empty( $wp->query_vars['lp_course'] ) && strpos( $wp->query_vars['lp_course'], '/' ) !== false ) {
1855
- flush_rewrite_rules();
1856
- }
1857
-
1858
- if ( !empty( $wp->query_vars['course-query-string'] ) ) {
1859
- $segments = explode( '/', $wp->query_vars['course-query-string'] );
1860
- $segments = array_filter( $segments );
1861
- if ( $segments ) {
1862
- $ids = array();
1863
- $names = array();
1864
- foreach ( $segments as $segment ) {
1865
- if ( preg_match( '/^([0-9]+)/', $segment ) ) {
1866
- $post_args = explode( '-', $segment, 2 );
1867
- $ids[] = absint( $post_args[0] );
1868
- $names[] = $post_args[1];
1869
- }
1870
- }
1871
-
1872
- if ( sizeof( $ids ) ) {
1873
- global $wpdb;
1874
- $ids_format = array_fill( 0, sizeof( $ids ), '%d' );
1875
- $names_format = array_fill( 0, sizeof( $names ), '%s' );
1876
-
1877
- $query = $wpdb->prepare( "
1878
- SELECT ID, post_name, post_type
1879
- FROM {$wpdb->posts}
1880
- WHERE ID IN(" . join( ',', $ids_format ) . ")
1881
- AND post_name IN(" . join( ',', $names_format ) . ")
1882
- ORDER BY FIELD(ID, " . join( ',', $ids_format ) . ")
1883
- ", array_merge( $ids, $names, $ids ) );
1884
- if ( $items = $wpdb->get_results( $query ) ) {
1885
- $support_types = learn_press_course_get_support_item_types();
1886
- foreach ( $items as $item ) {
1887
- if ( in_array( $item->post_type, $support_types ) ) {
1888
- $wp->query_vars[$item->post_type] = $item->ID;
1889
- }
1890
- }
1891
- }
1892
- }
1893
- }
1894
- }
1895
-
1896
- // Map query vars to their keys, or get them if endpoints are not supported
1897
- foreach ( LP()->query_vars as $key => $var ) {
1898
- if ( isset( $_GET[$var] ) ) {
1899
- $wp->query_vars[$key] = $_GET[$var];
1900
- } elseif ( isset( $wp->query_vars[$var] ) ) {
1901
- $wp->query_vars[$key] = $wp->query_vars[$var];
1902
- }
1903
- }
1904
- }
1905
-
1906
- add_action( 'parse_request', 'learn_press_parse_request' );
1907
-
1908
- function learn_press_reset_auto_increment( $table ) {
1909
- global $wpdb;
1910
- $wpdb->query( $wpdb->prepare( "ALTER TABLE {$wpdb->prefix}$table AUTO_INCREMENT = %d", 1 ) );
1911
- }
1912
-
1913
- /**
1914
- * @param $handle
1915
- *
1916
- * @return string
1917
- */
1918
- function learn_press_get_log_file_path( $handle ) {
1919
- return trailingslashit( LP_LOG_PATH ) . $handle . '-' . sanitize_file_name( wp_hash( $handle ) ) . '.log';
1920
- }
1921
-
1922
- /**
1923
- * Get the cart object in checkout page
1924
- *
1925
- * @return mixed|null|void
1926
- */
1927
- function learn_press_get_checkout_cart() {
1928
- return apply_filters( 'learn_press_checkout_cart', LP()->cart );
1929
- }
1930
-
1931
- function learn_press_front_scripts() {
1932
- if ( is_admin() ) {
1933
- return;
1934
- }
1935
- $js = array(
1936
- 'ajax' => admin_url( 'admin-ajax.php' ),
1937
- 'plugin_url' => LP()->plugin_url(),
1938
- 'siteurl' => home_url(),
1939
- 'current_url' => learn_press_get_current_url(),
1940
- 'localize' => array(
1941
- 'button_ok' => __( 'OK', 'learnpress' ),
1942
- 'button_cancel' => __( 'Cancel', 'learnpress' ),
1943
- 'button_yes' => __( 'Yes', 'learnpress' ),
1944
- 'button_no' => __( 'No', 'learnpress' )
1945
- )
1946
- );
1947
- LP_Assets::add_var( 'LP_Settings', wp_json_encode( $js ), array( 'learn-press-single-course', 'learn-press-global' ) );
1948
- }
1949
-
1950
- add_action( 'wp_print_scripts', 'learn_press_front_scripts' );
1951
-
1952
- /**
1953
- * Auto insert new item to user_items table when user viewing a lesson
1954
- *
1955
- * @param $located
1956
- * @param $template_name
1957
- * @param $template_path
1958
- *
1959
- * @return mixed
1960
- */
1961
- function learn_press_add_user_item_if_needed( $located, $template_name, $template_path ) {
1962
- if ( $template_name == 'single-course/content-item-lp_lesson.php' ) {
1963
- $items = LP_Cache::get_item_statuses( false, array() );
1964
- $user_id = get_current_user_id();
1965
- $course_id = get_the_ID();
1966
- $course_item = LP()->global['course-item'];
1967
- if ( $course_id && $course_item && !empty( $items[$user_id . '-' . $course_id . '-' . $course_id] ) ) {
1968
- $key = sprintf( '%d-%d-%d', $user_id, $course_id, $course_item->ID );
1969
- if ( empty( $items[$key] ) || $items[$key] == '' ) {
1970
- global $wpdb;
1971
- $parent_id = $wpdb->get_var( $wpdb->prepare( "SELECT user_item_id FROM {$wpdb->prefix}learnpress_user_items WHERE user_id = %d AND item_id = %d", $user_id, $course_id ) );
1972
- learn_press_update_user_item_field(
1973
- array(
1974
- 'user_id' => $user_id,
1975
- 'item_id' => $course_item->ID,
1976
- 'start_time' => current_time( 'mysql' ),
1977
- 'item_type' => get_post_type( $course_item->ID ),
1978
- 'ref_type' => LP_COURSE_CPT,
1979
- 'status' => get_post_type( $course_item->ID ) == LP_LESSON_CPT ? 'started' : 'viewed',
1980
- 'ref_id' => $course_id,
1981
- 'parent_id' => $parent_id
1982
- )
1983
- );
1984
- }
1985
- }
1986
- }
1987
- return $located;
1988
- }
1989
-
1990
- //add_filter( 'learn_press_locate_template', 'learn_press_add_user_item_if_needed', 10, 3 );
1991
-
1992
- function learn_press_set_user_timezone() {
1993
- ?>
1994
- <script type="text/javascript">
1995
- (function (factory) {
1996
- if (typeof define === 'function' && define.amd) {
1997
- // AMD (Register as an anonymous module)
1998
- define(['jquery'], factory);
1999
- } else if (typeof exports === 'object') {
2000
- // Node/CommonJS
2001
- module.exports = factory(require('jquery'));
2002
- } else {
2003
- // Browser globals
2004
- factory(jQuery);
2005
- }
2006
- }(function ($) {
2007
-
2008
- var pluses = /\+/g;
2009
-
2010
- function encode(s) {
2011
- return config.raw ? s : encodeURIComponent(s);
2012
- }
2013
-
2014
- function decode(s) {
2015
- return config.raw ? s : decodeURIComponent(s);
2016
- }
2017
-
2018
- function stringifyCookieValue(value) {
2019
- return encode(config.json ? JSON.stringify(value) : String(value));
2020
- }
2021
-
2022
- function parseCookieValue(s) {
2023
- if (s.indexOf('"') === 0) {
2024
- // This is a quoted cookie as according to RFC2068, unescape...
2025
- s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
2026
- }
2027
-
2028
- try {
2029
- // Replace server-side written pluses with spaces.
2030
- // If we can't decode the cookie, ignore it, it's unusable.
2031
- // If we can't parse the cookie, ignore it, it's unusable.
2032
- s = decodeURIComponent(s.replace(pluses, ' '));
2033
- return config.json ? JSON.parse(s) : s;
2034
- } catch (e) {
2035
- }
2036
- }
2037
-
2038
- function read(s, converter) {
2039
- var value = config.raw ? s : parseCookieValue(s);
2040
- return $.isFunction(converter) ? converter(value) : value;
2041
- }
2042
-
2043
- var config = $.cookie = function (key, value, options) {
2044
-
2045
- // Write
2046
-
2047
- if (arguments.length > 1 && !$.isFunction(value)) {
2048
- options = $.extend({}, config.defaults, options);
2049
-
2050
- if (typeof options.expires === 'number') {
2051
- var days = options.expires, t = options.expires = new Date();
2052
- t.setMilliseconds(t.getMilliseconds() + days * 864e+5);
2053
- }
2054
-
2055
- return (document.cookie = [
2056
- encode(key), '=', stringifyCookieValue(value),
2057
- options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
2058
- options.path ? '; path=' + options.path : '',
2059
- options.domain ? '; domain=' + options.domain : '',
2060
- options.secure ? '; secure' : ''
2061
- ].join(''));
2062
- }
2063
-
2064
- // Read
2065
-
2066
- var result = key ? undefined : {},
2067
- // To prevent the for loop in the first place assign an empty array
2068
- // in case there are no cookies at all. Also prevents odd result when
2069
- // calling $.cookie().
2070
- cookies = document.cookie ? document.cookie.split('; ') : [],
2071
- i = 0,
2072
- l = cookies.length;
2073
-
2074
- for (; i < l; i++) {
2075
- var parts = cookies[i].split('='),
2076
- name = decode(parts.shift()),
2077
- cookie = parts.join('=');
2078
-
2079
- if (key === name) {
2080
- // If second argument (value) is a function it's a converter...
2081
- result = read(cookie, value);
2082
- break;
2083
- }
2084
-
2085
- // Prevent storing a cookie that we couldn't decode.
2086
- if (!key && (cookie = read(cookie)) !== undefined) {
2087
- result[name] = cookie;
2088
- }
2089
- }
2090
-
2091
- return result;
2092
- };
2093
-
2094
- config.defaults = {};
2095
-
2096
- $.removeCookie = function (key, options) {
2097
- // Must not alter options, thus extending a fresh object...
2098
- $.cookie(key, '', $.extend({}, options, {expires: -1}));
2099
- return !$.cookie(key);
2100
- };
2101
-
2102
- }));
2103
- jQuery.cookie('timezone', new Date().getTimezoneOffset());
2104
- </script>
2105
- <?php
2106
- }
2107
-
2108
- add_action( 'admin_head', 'learn_press_set_user_timezone' );
2109
-
2110
- function learn_press_user_time( $time, $format = 'timestamp' ) {
2111
- if ( is_string( $time ) ) {
2112
- $time = @strtotime( $time );
2113
- }
2114
- $time = $time + ( get_option( 'gmt_offset' ) - $_COOKIE['timezone'] / 60 ) * HOUR_IN_SECONDS;
2115
- switch ( $format ) {
2116
- case 'timestamp':
2117
- return $time;
2118
- default:
2119
- return date( 'Y-m-d H:i:s', $time );
2120
- }
2121
- }
2122
-
2123
- function learn_press_get_current_version() {
2124
- $data = get_plugin_data( LP_PLUGIN_FILE, $markup = true, $translate = true );
2125
- return $data['Version'];
2126
- }
2127
-
2128
- function learn_press_sanitize_json( $string ) {
2129
-
2130
- echo json_encode( $string );
2131
- return $string;
2132
- }
2133
-
2134
- function learn_press_get_current_profile_tab() {
2135
- global $wp_query;
2136
- $current = '';
2137
- if ( !empty( $_REQUEST['tab'] ) ) {
2138
- $current = $_REQUEST['tab'];
2139
- } else if ( !empty( $wp_query->query_vars['tab'] ) ) {
2140
- $current = $wp_query->query_vars['tab'];
2141
- } else {
2142
- if ( $tabs = learn_press_user_profile_tabs() ) {
2143
- $tab_keys = array_keys( $tabs );
2144
- $current = reset( $tab_keys );
2145
- }
2146
- }
2147
- return $current;
2148
- }
2149
-
2150
- /**
2151
- * Get user profile link
2152
- *
2153
- * @param int $user_id
2154
- * @param null $tab
2155
- *
2156
- * @return mixed|string|void
2157
- */
2158
- function learn_press_user_profile_link( $user_id = 0, $tab = null ) {
2159
- if ( !$user_id ) {
2160
- $user = get_user_by( 'id', get_current_user_id() );
2161
- } else {
2162
- if ( is_numeric( $user_id ) ) {
2163
- $user = get_user_by( 'id', $user_id );
2164
- } else {
2165
- $user = get_user_by( 'login', $user_id );
2166
- }
2167
- }
2168
-
2169
- if ( !$user ) {
2170
- return '';
2171
- }
2172
- global $wp_query;
2173
- $args = array(
2174
- 'user' => $user->user_login
2175
- );
2176
- if ( $tab ) {
2177
- $args['tab'] = $tab;
2178
- } else {
2179
- $args['tab'] = learn_press_get_current_profile_tab();
2180
- }
2181
- $args = array_map( '_learn_press_urlencode', $args );
2182
- $profile_link = trailingslashit( learn_press_get_page_link( 'profile' ) );
2183
- if ( $profile_link )