LearnPress – WordPress LMS Plugin - Version 2.1.3

Version Description

  • Fixed wrong notice outdated templates
  • Fixed issue when viewing order details in profile
  • Fixed course does not finish automatically when expired
  • Fixed translation issue with failed/passed strings
  • Improved admin course tabs
Download this release

Release Info

Developer leehld
Plugin Icon 128x128 LearnPress – WordPress LMS Plugin
Version 2.1.3
Comparing to
See all releases

Code changes from version 2.1.6.1 to 2.1.3

Files changed (77) hide show
  1. assets/css/admin/admin.css +18 -79
  2. assets/css/admin/admin.less +34 -108
  3. assets/css/admin/attributes.less +2 -3
  4. assets/css/admin/meta-box-course.css +141 -76
  5. assets/css/admin/meta-box-course.less +982 -914
  6. assets/css/admin/meta-box-order.css +44 -46
  7. assets/css/admin/meta-box-question.css +52 -0
  8. assets/css/learnpress.css +101 -434
  9. assets/css/learnpress.less +2152 -2532
  10. assets/js/admin/admin.js +2 -2
  11. assets/js/admin/attributes.js +1 -6
  12. assets/js/admin/course-editor.js +6 -6
  13. assets/js/admin/meta-box-course.js +102 -46
  14. assets/js/admin/meta-box-order.js +18 -37
  15. assets/js/admin/meta-box-quiz.js +1 -13
  16. assets/js/admin/settings.js +3 -29
  17. assets/js/frontend/bak.course-lesson.js +223 -0
  18. assets/js/frontend/bak.course-quiz.js +45 -0
  19. assets/js/frontend/bak.single-course.v2.js +245 -0
  20. assets/js/frontend/bak.single-quiz.js +731 -0
  21. assets/js/frontend/checkout.js +137 -139
  22. assets/js/frontend/course-filters.js +0 -146
  23. assets/js/frontend/course_coming_soon.js +28 -0
  24. assets/js/frontend/course_coming_soon.min.js +28 -0
  25. assets/js/frontend/learnpress.js +2 -1
  26. assets/js/frontend/lesson.js +6 -3
  27. assets/js/frontend/profile.js +552 -316
  28. assets/js/frontend/quiz.js +916 -922
  29. assets/js/frontend/single-course.js +24 -77
  30. assets/js/global.js +10 -35
  31. assets/js/global.min.js +2 -2
  32. assets/js/jquery.cropit.js +1207 -0
  33. assets/js/jquery.mb-comingsoon.js +346 -0
  34. assets/js/jquery.mb-comingsoon.min.js +1 -0
  35. assets/js/jquery.ocupload.js +277 -0
  36. inc/admin/class-lp-admin-ajax.php +1139 -1158
  37. inc/admin/class-lp-admin-menu.php +130 -152
  38. inc/admin/class-lp-admin.php +231 -232
  39. inc/admin/class-lp-meta-box-tabs.php +1 -2
  40. inc/admin/class-lp-profile.php +139 -0
  41. inc/admin/dashboard-statistics/class-lp-statistic-status.php +4 -4
  42. inc/admin/includes/class-markdown-parse.php +5 -7
  43. inc/admin/lp-admin-functions.php +2098 -2167
  44. inc/admin/meta-boxes/class-course-tabs-field.php +1 -1
  45. inc/admin/meta-boxes/class-curriculum-field.php +316 -0
  46. inc/admin/meta-boxes/class-meta-box-tabs.php +18 -0
  47. inc/admin/meta-boxes/class-quiz-questions-field.php +193 -193
  48. inc/admin/settings/class-lp-settings-checkout.php +80 -80
  49. inc/admin/settings/class-lp-settings-courses.php +175 -203
  50. inc/admin/settings/class-lp-settings-emails.php +21 -44
  51. inc/admin/settings/class-lp-settings-general.php +124 -134
  52. inc/admin/settings/class-lp-settings-pages.php +212 -212
  53. inc/admin/sub-menus/settings.php +0 -11
  54. inc/admin/sub-menus/tools.php +3 -3
  55. inc/admin/views/html-admin-notice-templates.php +39 -39
  56. inc/admin/views/meta-boxes/course/attributes.php +7 -0
  57. inc/admin/views/meta-boxes/course/curriculum.php +33 -33
  58. inc/admin/views/meta-boxes/course/loop-item.php +36 -56
  59. inc/admin/views/meta-boxes/course/loop-section.php +55 -26
  60. inc/admin/views/meta-boxes/course/review-logs.php +2 -2
  61. inc/admin/views/meta-boxes/order/actions.php +10 -33
  62. inc/admin/views/meta-boxes/order/details.php +12 -25
  63. inc/admin/views/meta-boxes/tabs.php +2 -13
  64. inc/admin/views/settings/emails/enrolled-course-admin.php +0 -76
  65. inc/admin/views/settings/emails/update-course.php +0 -50
  66. inc/admin/views/settings/emails/user-order-changed-status.php +0 -68
  67. inc/admin/views/settings/fields/course-permalink.php +13 -16
  68. inc/admin/views/settings/fields/image-size.php +21 -21
  69. inc/admin/views/settings/fields/title.php +2 -2
  70. inc/admin/views/settings/general.php +24 -24
  71. inc/attributes/lp-attributes-functions.php +5 -82
  72. inc/cart/class-lp-cart.php +663 -663
  73. inc/class-lp-ajax.php +655 -737
  74. inc/class-lp-assets.php +808 -816
  75. inc/class-lp-cache.php +634 -740
  76. inc/class-lp-emails.php +29 -35
  77. inc/class-lp-install.php +133 -658
assets/css/admin/admin.css CHANGED
@@ -4,30 +4,12 @@
4
  * @author ThimPress
5
  * @version 1.0
6
  */
7
- input:focus::-webkit-input-placeholder {
8
- color: transparent !important;
9
- }
10
- input:focus::-moz-placeholder {
11
- color: transparent !important;
12
- }
13
- input:focus:-moz-placeholder {
14
- color: transparent !important;
15
- }
16
  .rwmb-field {
17
  margin: 20px 0 20px 0;
18
  }
19
  .rwmb-field .rwmb-input .rwmb-label {
20
  margin-top: 0;
21
  }
22
- .rwmb-field .rwmb-input .description {
23
- margin-top: 5px;
24
- }
25
- .rwmb-field .rwmb-input .description.option-desc {
26
- font-weight: normal;
27
- margin: 8px 0 10px 24px;
28
- font-size: smaller;
29
- font-style: italic;
30
- }
31
  .lp-nav-tab-wrapper {
32
  border-bottom: 1px solid #ccc;
33
  margin: 0;
@@ -42,6 +24,19 @@ input:focus:-moz-placeholder {
42
  .learn-press-quick-add-page-inline > * {
43
  vertical-align: top;
44
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  #learn-press-admin-settings {
46
  /*input[name="learn_press_single_course_image_size[width]"],
47
  input[name="learn_press_single_course_image_size[height]"],
@@ -97,9 +92,6 @@ input:focus:-moz-placeholder {
97
  box-sizing: border-box;
98
  opacity: 0;
99
  }
100
- #learn-press-admin-settings .learn-press-settings-wrap input[name="learn_press_auto_redirect_message"] {
101
- width: 80%;
102
- }
103
  #learn-press-admin-settings .learn-press-settings-wrap:before {
104
  content: '';
105
  position: absolute;
@@ -116,18 +108,10 @@ input:focus:-moz-placeholder {
116
  #learn-press-admin-settings .learn-press-settings-wrap.ready {
117
  opacity: 1;
118
  }
119
- #learn-press-admin-settings .learn-press-settings-wrap #learn-press-reset-settings {
120
- float: right;
121
- opacity: 0.5;
122
- }
123
- #learn-press-admin-settings .learn-press-settings-wrap #learn-press-reset-settings:hover {
124
- opacity: 1;
125
- }
126
  #learn-press-admin-settings.no-subtabs .learn-press-settings-wrap {
127
  float: none;
128
  margin-left: 0;
129
  padding-left: 25px;
130
- padding-right: 25px;
131
  }
132
  #learn-press-admin-settings.no-subtabs .learn-press-settings-wrap:before {
133
  display: none;
@@ -169,40 +153,6 @@ input:focus:-moz-placeholder {
169
  #learn-press-admin-settings .lp-setting-field .lp-sign-times {
170
  font-size: 19px;
171
  }
172
- .learnpress_page_learn-press-settings .select2-result .select2-result-label {
173
- position: relative;
174
- }
175
- .learnpress_page_learn-press-settings .select2-result .select2-result-label:before {
176
- display: inline-block;
177
- border-bottom: 1px solid #23282d;
178
- width: 20px;
179
- position: absolute;
180
- top: 50%;
181
- left: 8px;
182
- }
183
- .learnpress_page_learn-press-settings .select2-result .select2-result-label:hover:before {
184
- border-color: #FFF;
185
- }
186
- .learnpress_page_learn-press-settings .select2-result.level-1 .select2-result-label {
187
- padding-left: 35px;
188
- }
189
- .learnpress_page_learn-press-settings .select2-result.level-1 .select2-result-label:before {
190
- content: '';
191
- }
192
- .learnpress_page_learn-press-settings .select2-result.level-2 .select2-result-label {
193
- padding-left: 60px;
194
- }
195
- .learnpress_page_learn-press-settings .select2-result.level-2 .select2-result-label:before {
196
- left: 35px;
197
- content: '';
198
- }
199
- .learnpress_page_learn-press-settings .select2-result.level-3 .select2-result-label {
200
- padding-left: 85px;
201
- }
202
- .learnpress_page_learn-press-settings .select2-result.level-3 .select2-result-label:before {
203
- left: 60px;
204
- content: '';
205
- }
206
  /* message box */
207
  #learn-press-message-box-block {
208
  position: fixed;
@@ -272,6 +222,9 @@ input:focus:-moz-placeholder {
272
  .meta_box_course_lesson_quiz li select {
273
  min-width: 250px;
274
  }
 
 
 
275
  .dashed-placeholder {
276
  border: 2px dashed #999;
277
  padding: 10px;
@@ -1510,8 +1463,7 @@ body.post-type-lp_question #question_answer_ .inside {
1510
  }
1511
  .post-type-lp_order #submitpost .misc-pub-section label {
1512
  display: block;
1513
- font-weight: 600;
1514
- margin-bottom: 8px;
1515
  }
1516
  #learn-press-order {
1517
  margin: 15px;
@@ -1867,7 +1819,7 @@ input.regular-text[id^="learn-press-emails"] {
1867
  margin: 0;
1868
  }
1869
  .learn-press-tabs .learn-press-tab-content > li {
1870
- padding: 0 20px 10px 20px;
1871
  float: left;
1872
  width: 100%;
1873
  margin-right: -100%;
@@ -1913,19 +1865,6 @@ input.regular-text[id^="learn-press-emails"] {
1913
  content: '';
1914
  display: block;
1915
  }
1916
- /* Metabox Widget */
1917
- #widgets-right .widgets-holder-wrap .rwmb-label {
1918
- margin-bottom: 5px;
1919
- }
1920
- #widgets-right .widgets-holder-wrap .rwmb-input input[type="text"] {
1921
- width: 100%;
1922
- }
1923
- #widgets-right .widgets-holder-wrap .description {
1924
- padding: 0;
1925
- margin-top: 5px;
1926
- font-size: small;
1927
- font-style: italic;
1928
- }
1929
  @keyframes learn-press-meta-box-tabs-initialize-animation {
1930
  0% {
1931
  opacity: 0;
4
  * @author ThimPress
5
  * @version 1.0
6
  */
 
 
 
 
 
 
 
 
 
7
  .rwmb-field {
8
  margin: 20px 0 20px 0;
9
  }
10
  .rwmb-field .rwmb-input .rwmb-label {
11
  margin-top: 0;
12
  }
 
 
 
 
 
 
 
 
 
13
  .lp-nav-tab-wrapper {
14
  border-bottom: 1px solid #ccc;
15
  margin: 0;
24
  .learn-press-quick-add-page-inline > * {
25
  vertical-align: top;
26
  }
27
+ .post-type-lp_course .column-price,
28
+ .post-type-lp_course .column-students {
29
+ width: 10%;
30
+ }
31
+ .post-type-lp_course #course_curriculum .curriculum-section-items .lp-item-empty td.section-item-input {
32
+ padding-left: 40px;
33
+ }
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]"],
92
  box-sizing: border-box;
93
  opacity: 0;
94
  }
 
 
 
95
  #learn-press-admin-settings .learn-press-settings-wrap:before {
96
  content: '';
97
  position: absolute;
108
  #learn-press-admin-settings .learn-press-settings-wrap.ready {
109
  opacity: 1;
110
  }
 
 
 
 
 
 
 
111
  #learn-press-admin-settings.no-subtabs .learn-press-settings-wrap {
112
  float: none;
113
  margin-left: 0;
114
  padding-left: 25px;
 
115
  }
116
  #learn-press-admin-settings.no-subtabs .learn-press-settings-wrap:before {
117
  display: none;
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;
222
  .meta_box_course_lesson_quiz li select {
223
  min-width: 250px;
224
  }
225
+ .description {
226
+ margin-top: 5px;
227
+ }
228
  .dashed-placeholder {
229
  border: 2px dashed #999;
230
  padding: 10px;
1463
  }
1464
  .post-type-lp_order #submitpost .misc-pub-section label {
1465
  display: block;
1466
+ font-weight: bold;
 
1467
  }
1468
  #learn-press-order {
1469
  margin: 15px;
1819
  margin: 0;
1820
  }
1821
  .learn-press-tabs .learn-press-tab-content > li {
1822
+ padding: 0 20px 0px 20px;
1823
  float: left;
1824
  width: 100%;
1825
  margin-right: -100%;
1865
  content: '';
1866
  display: block;
1867
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
1868
  @keyframes learn-press-meta-box-tabs-initialize-animation {
1869
  0% {
1870
  opacity: 0;
assets/css/admin/admin.less CHANGED
@@ -7,35 +7,12 @@
7
  // admin variables
8
  @primary-icon-color: #666666;
9
  @primary-icon-hover-color: #00a0d2;
10
-
11
- input:focus::-webkit-input-placeholder {
12
- color: transparent !important;
13
- }
14
-
15
- input:focus::-moz-placeholder {
16
- color: transparent !important;
17
- }
18
-
19
- input:focus:-moz-placeholder {
20
- color: transparent !important;
21
- }
22
-
23
  .rwmb-field {
24
  margin: 20px 0 20px 0;
25
- .rwmb-input {
26
- .rwmb-label {
27
- margin-top: 0;
28
- }
29
- .description {
30
- margin-top: 5px;
31
- &.option-desc {
32
- font-weight: normal;
33
- margin: 8px 0 10px 24px;
34
- font-size: smaller;
35
- font-style: italic;
36
- }
37
- }
38
- }
39
  }
40
 
41
  .lp-nav-tab-wrapper {
@@ -55,6 +32,29 @@ input:focus:-moz-placeholder {
55
  vertical-align: top;
56
  }
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  #learn-press-admin-settings {
59
  #learn_press_email_formats {
60
  margin-bottom: 10px;
@@ -98,9 +98,6 @@ input:focus:-moz-placeholder {
98
  width: 100%;
99
  box-sizing: border-box;
100
  opacity: 0;
101
- input[name="learn_press_auto_redirect_message"] {
102
- width: 80%;
103
- }
104
  &:before {
105
  content: '';
106
  position: absolute;
@@ -117,21 +114,12 @@ input:focus:-moz-placeholder {
117
  &.ready {
118
  opacity: 1;
119
  }
120
- #learn-press-reset-settings {
121
- float: right;
122
- opacity: 0.5;
123
- &:hover {
124
- opacity: 1;
125
- }
126
- }
127
  }
128
  &.no-subtabs {
129
  .learn-press-settings-wrap {
130
  float: none;
131
  margin-left: 0;
132
  padding-left: 25px;
133
- padding-right: 25px;
134
-
135
  &:before {
136
  display: none;
137
  }
@@ -189,53 +177,6 @@ input:focus:-moz-placeholder {
189
  }
190
  }
191
 
192
- .learnpress_page_learn-press-settings {
193
- .select2-result {
194
- .select2-result-label {
195
- position: relative;
196
- &:before {
197
- display: inline-block;
198
- border-bottom: 1px solid #23282d;
199
- width: 20px;
200
- position: absolute;
201
- top: 50%;
202
- left: 8px;
203
- }
204
- &:hover {
205
- &:before {
206
- border-color: #FFF;
207
- }
208
- }
209
- }
210
- &.level-1 {
211
- .select2-result-label {
212
- padding-left: 35px;
213
- &:before {
214
- content: '';
215
- }
216
- }
217
- }
218
- &.level-2 {
219
- .select2-result-label {
220
- padding-left: 60px;
221
- &:before {
222
- left: 35px;
223
- content: '';
224
- }
225
- }
226
- }
227
- &.level-3 {
228
- .select2-result-label {
229
- padding-left: 85px;
230
- &:before {
231
- left: 60px;
232
- content: '';
233
- }
234
- }
235
- }
236
- }
237
- }
238
-
239
  /* message box */
240
  #learn-press-message-box-block {
241
  position: fixed;
@@ -318,6 +259,10 @@ input:focus:-moz-placeholder {
318
  min-width: 250px;
319
  }
320
 
 
 
 
 
321
  .dashed-placeholder {
322
  border: 2px dashed #999;
323
  padding: 10px;
@@ -1810,8 +1755,7 @@ body.post-type-lp_question #question_answer_ .inside {
1810
 
1811
  .post-type-lp_order #submitpost .misc-pub-section label {
1812
  display: block;
1813
- font-weight: 600;
1814
- margin-bottom: 8px;
1815
  }
1816
 
1817
  #learn-press-order {
@@ -2214,7 +2158,7 @@ input.regular-text[id^="learn-press-emails"] {
2214
 
2215
  .learn-press-tab-content {
2216
  > li {
2217
- padding: 0 20px 10px 20px;
2218
  float: left;
2219
  width: 100%;
2220
  margin-right: -100%;
@@ -2271,24 +2215,6 @@ input.regular-text[id^="learn-press-emails"] {
2271
  }
2272
  }
2273
 
2274
- /* Metabox Widget */
2275
- #widgets-right .widgets-holder-wrap {
2276
- .rwmb-label {
2277
- margin-bottom: 5px;
2278
- }
2279
- .rwmb-input{
2280
- input[type="text"]{
2281
- width: 100%;
2282
- }
2283
- }
2284
- .description {
2285
- padding: 0;
2286
- margin-top: 5px;
2287
- font-size: small;
2288
- font-style: italic;
2289
- }
2290
- }
2291
-
2292
  @keyframes learn-press-meta-box-tabs-initialize-animation {
2293
  0% {
2294
  opacity: 0;
@@ -2347,4 +2273,4 @@ input.regular-text[id^="learn-press-emails"] {
2347
  100% {
2348
  opacity: 0;
2349
  }
2350
- }
7
  // admin variables
8
  @primary-icon-color: #666666;
9
  @primary-icon-hover-color: #00a0d2;
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  .rwmb-field {
11
  margin: 20px 0 20px 0;
12
+ }
13
+
14
+ .rwmb-field .rwmb-input .rwmb-label {
15
+ margin-top: 0;
 
 
 
 
 
 
 
 
 
 
16
  }
17
 
18
  .lp-nav-tab-wrapper {
32
  vertical-align: top;
33
  }
34
 
35
+ .post-type-lp_course {
36
+ & .column-price, & .column-students {
37
+ width: 10%;
38
+ }
39
+
40
+ #course_curriculum .curriculum-section-items .lp-item-empty td.section-item-input {
41
+ padding-left: 40px;
42
+ &.hover {
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 {
59
  #learn_press_email_formats {
60
  margin-bottom: 10px;
98
  width: 100%;
99
  box-sizing: border-box;
100
  opacity: 0;
 
 
 
101
  &:before {
102
  content: '';
103
  position: absolute;
114
  &.ready {
115
  opacity: 1;
116
  }
 
 
 
 
 
 
 
117
  }
118
  &.no-subtabs {
119
  .learn-press-settings-wrap {
120
  float: none;
121
  margin-left: 0;
122
  padding-left: 25px;
 
 
123
  &:before {
124
  display: none;
125
  }
177
  }
178
  }
179
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  /* message box */
181
  #learn-press-message-box-block {
182
  position: fixed;
259
  min-width: 250px;
260
  }
261
 
262
+ .description {
263
+ margin-top: 5px;
264
+ }
265
+
266
  .dashed-placeholder {
267
  border: 2px dashed #999;
268
  padding: 10px;
1755
 
1756
  .post-type-lp_order #submitpost .misc-pub-section label {
1757
  display: block;
1758
+ font-weight: bold;
 
1759
  }
1760
 
1761
  #learn-press-order {
2158
 
2159
  .learn-press-tab-content {
2160
  > li {
2161
+ padding: 0 20px 0px 20px;
2162
  float: left;
2163
  width: 100%;
2164
  margin-right: -100%;
2215
  }
2216
  }
2217
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2218
  @keyframes learn-press-meta-box-tabs-initialize-animation {
2219
  0% {
2220
  opacity: 0;
2273
  100% {
2274
  opacity: 0;
2275
  }
2276
+ }
assets/css/admin/attributes.less CHANGED
@@ -1,4 +1,4 @@
1
- .course-attributes {
2
  margin: 20px 0;
3
  .learn-press-attribute {
4
  border: 1px solid #DDD;
@@ -14,5 +14,4 @@
14
  border-top: 1px solid #DDD;
15
  }
16
  }
17
- }
18
-
1
+ .course-attributes{
2
  margin: 20px 0;
3
  .learn-press-attribute {
4
  border: 1px solid #DDD;
14
  border-top: 1px solid #DDD;
15
  }
16
  }
17
+ }
 
assets/css/admin/meta-box-course.css CHANGED
@@ -3,13 +3,6 @@
3
  .rwmb-duration-wrapper select {
4
  vertical-align: baseline;
5
  }
6
- #learn-press-toggle-course-results {
7
- display: block;
8
- margin-bottom: 10px;
9
- }
10
- #learn-press-toggle-course-results a {
11
- box-shadow: none;
12
- }
13
  .post-type-lp_course #postdivric,
14
  .post-type-lp_course #submitpost {
15
  visibility: hidden;
@@ -32,68 +25,65 @@
32
  font-size: 12px;
33
  font-style: italic;
34
  }
35
- #lp-course-curriculum {
 
 
 
36
  border: none;
37
  background-color: transparent;
38
- margin: 20px 0;
39
- }
40
- .post-type-lp_course .column-price,
41
- .post-type-lp_course .column-students {
42
- width: 10%;
43
- }
44
- .post-type-lp_course #lp-course-curriculum .curriculum-section-items .lp-item-empty td.section-item-input {
45
- padding-left: 40px;
46
  }
47
- .post-type-lp_course #lp-course-curriculum .curriculum-section-items .lp-item-empty td.section-item-input.hover {
48
- padding-left: 0;
49
- }
50
- .post-type-lp_course .type-lp_course.status-pending .row-actions .view {
51
  display: none;
52
  }
53
- #lp-course-curriculum .curriculum-heading {
 
 
 
 
54
  margin: 0 0 20px 0;
55
  padding: 10px 20px;
56
  background-color: #FFF;
57
  line-height: 1;
58
  border: 1px solid #DDD;
59
  }
60
- #lp-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
- #lp-course-curriculum .curriculum-heading .items-toggle {
68
  float: right;
69
  margin: -33px 7px 0 0;
70
  line-height: 1;
71
  box-shadow: none;
72
  }
73
- #lp-course-curriculum .curriculum-heading .items-toggle a {
74
  -webkit-box-shadow: none;
75
  -moz-box-shadow: none;
76
  box-shadow: none;
77
  font-size: 32px;
78
  }
79
- #lp-course-curriculum .curriculum-sections {
80
  margin: 0;
81
  background-color: #FFF;
82
  border-bottom: 1px solid #DDD;
83
  }
84
- #lp-course-curriculum .curriculum-section {
85
  margin: -1px 0 0 0;
86
  background-color: #FFF;
87
  border-bottom: 1px solid #DDD;
88
  position: relative;
89
  }
90
- #lp-course-curriculum .curriculum-section.ui-sortable-placeholder {
91
  background-image: url("../../images/stripe.png");
92
  visibility: visible !important;
93
  border: 1px solid #DDD;
94
  border-bottom: none;
95
  }
96
- #lp-course-curriculum .curriculum-section-head {
97
  border: 1px solid #DDD;
98
  background-color: #F9F9F9;
99
  border-bottom: none;
@@ -101,37 +91,37 @@
101
  color: #777;
102
  padding: 3px 20px;
103
  }
104
- #lp-course-curriculum .curriculum-section-head input {
105
  background-color: #F9F9F9;
106
  }
107
- #lp-course-curriculum .curriculum-section-head .lp-section-actions {
108
  float: right;
109
  margin: 14px 0;
110
  visibility: hidden;
111
  position: relative;
112
  }
113
- #lp-course-curriculum .curriculum-section:not(.lp-empty-section) .curriculum-section-head:hover .lp-section-actions {
114
  visibility: visible;
115
  }
116
- #lp-course-curriculum .curriculum-section .lp-section-actions a {
117
  vertical-align: middle;
118
  color: #666666;
119
  width: 24px;
120
  height: 24px;
121
  box-shadow: none;
122
  }
123
- #lp-course-curriculum .curriculum-section .lp-section-actions a[data-action="expand"] {
124
  line-height: 28px;
125
  }
126
- #lp-course-curriculum .curriculum-section .lp-section-actions a:before {
127
  width: 24px;
128
  height: 24px;
129
  font-size: 24px;
130
  }
131
- #lp-course-curriculum .curriculum-section .lp-section-actions a:hover {
132
  color: #00a0d2;
133
  }
134
- #lp-course-curriculum .curriculum-section .curriculum-section-head .lp-section-actions .move {
135
  cursor: url("../../../assets/images/openhand.cur") 7 5, default;
136
  position: absolute;
137
  right: -15px;
@@ -140,17 +130,17 @@
140
  background: url("../../../assets/images/grippy_large.png") right no-repeat;
141
  width: 20px;
142
  }
143
- #lp-course-curriculum .curriculum-section-content {
144
  border: 1px solid #DDD;
145
  padding: 20px;
146
  border-bottom-width: 0;
147
  width: 100%;
148
  box-sizing: border-box;
149
  }
150
- #lp-course-curriculum .curriculum-section.ui-sortable-helper {
151
  border-bottom: 1px solid #DDD;
152
  }
153
- #lp-course-curriculum .curriculum-section-head .lp-section-name {
154
  border: none;
155
  outline: none;
156
  box-shadow: none;
@@ -161,65 +151,65 @@
161
  padding: 0;
162
  height: 50px;
163
  }
164
- #lp-course-curriculum .curriculum-section-head .lp-section-name:focus {
165
  color: #444;
166
  }
167
- #lp-course-curriculum .curriculum-section.lp-empty-section .curriculum-section-content {
168
  _display: none;
169
  }
170
- #lp-course-curriculum .curriculum-section-items {
171
  border-collapse: collapse;
172
  width: 100%;
173
  }
174
- #lp-course-curriculum .curriculum-section-items .lp-section-item {
175
  border: 1px dashed #DDD;
176
  margin: -1px 0 0 0;
177
  padding: 5px 0;
178
  background-color: #FFF;
179
  }
180
- #lp-course-curriculum .curriculum-section-items .lp-section-item:nth-child(2n+1),
181
- #lp-course-curriculum .curriculum-section-items .lp-section-item:nth-child(2n+1) .section-item-input input {
182
  background-color: #FCFCFC;
183
  }
184
- #lp-course-curriculum .curriculum-section-items .lp-section-item .lp-item-actions {
185
  margin: 0;
186
  float: right;
187
  position: relative;
188
  }
189
- #lp-course-curriculum .curriculum-section-items .lp-section-item .lp-item-actions a {
190
  vertical-align: middle;
191
  color: #666;
192
  margin-top: -2px;
193
  box-shadow: none;
194
  }
195
- #lp-course-curriculum .curriculum-section-items .lp-section-item .lp-item-actions a:hover {
196
  color: #00a0d2;
197
  }
198
- #lp-course-curriculum .curriculum-section-items .lp-section-item[data-item_id=""] .lp-edit {
199
  display: none;
200
  }
201
- #lp-course-curriculum .curriculum-section-items .lp-section-item.lp-item-empty .lp-item-actions {
202
  display: none;
203
  }
204
- #lp-course-curriculum .lp-section-item.ui-sortable-placeholder {
205
  visibility: visible !important;
206
  }
207
- #lp-course-curriculum .lp-section-item.ui-sortable-placeholder td {
208
  background-image: url("../../../assets/images/stripe.png");
209
  border-bottom: none;
210
  }
211
- #lp-course-curriculum .lp-item-actions > * {
212
  visibility: hidden;
213
  }
214
- #lp-course-curriculum .item-bulk-actions {
215
  text-align: right;
216
  margin-top: 0;
217
  margin-bottom: 15px;
218
  }
219
- #lp-course-curriculum .lp-section-item:not(.lp-item-empty):hover .lp-item-actions > * {
220
  visibility: visible;
221
  }
222
- #lp-course-curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty) .item-checkbox {
223
  display: inline-block;
224
  height: 34px;
225
  border: none;
@@ -229,26 +219,26 @@
229
  cursor: url("../../../assets/images/openhand.cur") 7 5, default;
230
  visibility: visible;
231
  }
232
- #lp-course-curriculum .curriculum-section-items .lp-section-item .item-checkbox input {
233
  opacity: 0.4;
234
  }
235
- #lp-course-curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty):hover .item-checkbox input {
236
  opacity: 1;
237
  }
238
- #lp-course-curriculum .lp-item-lp_lesson .handle.learn-press-icon:before {
239
  content: "\e900";
240
  }
241
- #lp-course-curriculum .lp-item-lp_quiz .handle.learn-press-icon:before {
242
  content: "\e901";
243
  }
244
- #lp-course-curriculum .lp-section-item.lp-item-new .handle {
245
  color: #999;
246
  }
247
- #lp-course-curriculum .curriculum-section-items .lp-section-item:hover,
248
- #lp-course-curriculum .curriculum-section-items .lp-section-item:hover input.lp-item-name {
249
  background-color: #F9F9F9;
250
  }
251
- #lp-course-curriculum .lp-section-item .handle {
252
  width: 32px;
253
  height: 32px;
254
  display: inline-block;
@@ -258,10 +248,10 @@
258
  line-height: 32px;
259
  color: #00A0D2;
260
  }
261
- #lp-course-curriculum .lp-section-item.remove input.lp-item-name {
262
  color: #FF0000;
263
  }
264
- #lp-course-curriculum .lp-section-item input.lp-item-name {
265
  color: #777;
266
  border: none;
267
  box-shadow: none;
@@ -273,7 +263,7 @@
273
  overflow: hidden;
274
  white-space: nowrap;
275
  }
276
- #lp-course-curriculum .lp-section-describe {
277
  border: none;
278
  box-shadow: none;
279
  color: #999;
@@ -282,11 +272,11 @@
282
  float: left;
283
  padding-left: 0;
284
  }
285
- #lp-course-curriculum .curriculum-section-items .lp-section-item input.lp-item-name:focus,
286
- #lp-course-curriculum input:focus {
287
  color: #444;
288
  }
289
- #lp-course-curriculum .lp-section-item .section-item-icon {
290
  width: 32px;
291
  white-space: nowrap;
292
  }
@@ -302,13 +292,13 @@
302
  cursor: pointer;
303
  border: 1px solid transparent;
304
  }
305
- #lp-course-curriculum .lp-section-item .learn-press-icon.item-lp_quiz:before {
306
  content: "\f469";
307
  }
308
- #lp-course-curriculum .lp-section-item .learn-press-icon.item-lp_lesson:before {
309
  content: "\f330";
310
  }
311
- #lp-course-curriculum .lp-section-item td {
312
  height: 30px;
313
  }
314
  #poststuff .postbox-container {
@@ -483,14 +473,89 @@ tr.focus .learn-press-dropdown-item-types > span.learn-press-icon {
483
  .learn-press-dropdown-item-types li span.learn-press-icon.item-selected {
484
  color: #0085ba;
485
  }
486
- .learn-press-course-attributes {
487
- margin: 20px 0;
488
- }
489
  .post-type-lp_course #switch-course-tabs,
490
  .post-type-lp_course #toggle-meta-boxes {
491
  float: right;
492
  margin-left: 10px;
493
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494
  /*
495
  #lp-course-curriculum .lp-course-curriculum-toggle{
496
  padding: 0;
3
  .rwmb-duration-wrapper select {
4
  vertical-align: baseline;
5
  }
 
 
 
 
 
 
 
6
  .post-type-lp_course #postdivric,
7
  .post-type-lp_course #submitpost {
8
  visibility: hidden;
25
  font-size: 12px;
26
  font-style: italic;
27
  }
28
+ #learn-press-button-toggle-editor {
29
+ margin: 20px 0 0;
30
+ }
31
+ #course_curriculum {
32
  border: none;
33
  background-color: transparent;
 
 
 
 
 
 
 
 
34
  }
35
+ #course_curriculum .handlediv,
36
+ #course_curriculum .hndle {
 
 
37
  display: none;
38
  }
39
+ #course_curriculum .inside {
40
+ margin: 0;
41
+ padding: 0;
42
+ }
43
+ #course_curriculum .curriculum-heading {
44
  margin: 0 0 20px 0;
45
  padding: 10px 20px;
46
  background-color: #FFF;
47
  line-height: 1;
48
  border: 1px solid #DDD;
49
  }
50
+ #course_curriculum .curriculum-heading .description {
51
  font-weight: normal;
52
  color: #999;
53
  display: block;
54
  font-size: 90%;
55
  margin-top: 10px;
56
  }
57
+ #course_curriculum .curriculum-heading .items-toggle {
58
  float: right;
59
  margin: -33px 7px 0 0;
60
  line-height: 1;
61
  box-shadow: none;
62
  }
63
+ #course_curriculum .curriculum-heading .items-toggle a {
64
  -webkit-box-shadow: none;
65
  -moz-box-shadow: none;
66
  box-shadow: none;
67
  font-size: 32px;
68
  }
69
+ #course_curriculum .curriculum-sections {
70
  margin: 0;
71
  background-color: #FFF;
72
  border-bottom: 1px solid #DDD;
73
  }
74
+ #course_curriculum .curriculum-section {
75
  margin: -1px 0 0 0;
76
  background-color: #FFF;
77
  border-bottom: 1px solid #DDD;
78
  position: relative;
79
  }
80
+ #course_curriculum .curriculum-section.ui-sortable-placeholder {
81
  background-image: url("../../images/stripe.png");
82
  visibility: visible !important;
83
  border: 1px solid #DDD;
84
  border-bottom: none;
85
  }
86
+ #course_curriculum .curriculum-section-head {
87
  border: 1px solid #DDD;
88
  background-color: #F9F9F9;
89
  border-bottom: none;
91
  color: #777;
92
  padding: 3px 20px;
93
  }
94
+ #course_curriculum .curriculum-section-head input {
95
  background-color: #F9F9F9;
96
  }
97
+ #course_curriculum .curriculum-section-head .lp-section-actions {
98
  float: right;
99
  margin: 14px 0;
100
  visibility: hidden;
101
  position: relative;
102
  }
103
+ #course_curriculum .curriculum-section:not(.lp-empty-section) .curriculum-section-head:hover .lp-section-actions {
104
  visibility: visible;
105
  }
106
+ #course_curriculum .curriculum-section .lp-section-actions a {
107
  vertical-align: middle;
108
  color: #666666;
109
  width: 24px;
110
  height: 24px;
111
  box-shadow: none;
112
  }
113
+ #course_curriculum .curriculum-section .lp-section-actions a[data-action="expand"] {
114
  line-height: 28px;
115
  }
116
+ #course_curriculum .curriculum-section .lp-section-actions a:before {
117
  width: 24px;
118
  height: 24px;
119
  font-size: 24px;
120
  }
121
+ #course_curriculum .curriculum-section .lp-section-actions a:hover {
122
  color: #00a0d2;
123
  }
124
+ #course_curriculum .curriculum-section .curriculum-section-head .lp-section-actions .move {
125
  cursor: url("../../../assets/images/openhand.cur") 7 5, default;
126
  position: absolute;
127
  right: -15px;
130
  background: url("../../../assets/images/grippy_large.png") right no-repeat;
131
  width: 20px;
132
  }
133
+ #course_curriculum .curriculum-section-content {
134
  border: 1px solid #DDD;
135
  padding: 20px;
136
  border-bottom-width: 0;
137
  width: 100%;
138
  box-sizing: border-box;
139
  }
140
+ #course_curriculum .curriculum-section.ui-sortable-helper {
141
  border-bottom: 1px solid #DDD;
142
  }
143
+ #course_curriculum .curriculum-section-head .lp-section-name {
144
  border: none;
145
  outline: none;
146
  box-shadow: none;
151
  padding: 0;
152
  height: 50px;
153
  }
154
+ #course_curriculum .curriculum-section-head .lp-section-name:focus {
155
  color: #444;
156
  }
157
+ #course_curriculum .curriculum-section.lp-empty-section .curriculum-section-content {
158
  _display: none;
159
  }
160
+ #course_curriculum .curriculum-section-items {
161
  border-collapse: collapse;
162
  width: 100%;
163
  }
164
+ #course_curriculum .curriculum-section-items .lp-section-item {
165
  border: 1px dashed #DDD;
166
  margin: -1px 0 0 0;
167
  padding: 5px 0;
168
  background-color: #FFF;
169
  }
170
+ #course_curriculum .curriculum-section-items .lp-section-item:nth-child(2n+1),
171
+ #course_curriculum .curriculum-section-items .lp-section-item:nth-child(2n+1) .section-item-input input {
172
  background-color: #FCFCFC;
173
  }
174
+ #course_curriculum .curriculum-section-items .lp-section-item .lp-item-actions {
175
  margin: 0;
176
  float: right;
177
  position: relative;
178
  }
179
+ #course_curriculum .curriculum-section-items .lp-section-item .lp-item-actions a {
180
  vertical-align: middle;
181
  color: #666;
182
  margin-top: -2px;
183
  box-shadow: none;
184
  }
185
+ #course_curriculum .curriculum-section-items .lp-section-item .lp-item-actions a:hover {
186
  color: #00a0d2;
187
  }
188
+ #course_curriculum .curriculum-section-items .lp-section-item[data-item_id=""] .lp-edit {
189
  display: none;
190
  }
191
+ #course_curriculum .curriculum-section-items .lp-section-item.lp-item-empty .lp-item-actions {
192
  display: none;
193
  }
194
+ #course_curriculum .lp-section-item.ui-sortable-placeholder {
195
  visibility: visible !important;
196
  }
197
+ #course_curriculum .lp-section-item.ui-sortable-placeholder td {
198
  background-image: url("../../../assets/images/stripe.png");
199
  border-bottom: none;
200
  }
201
+ #course_curriculum .lp-item-actions > * {
202
  visibility: hidden;
203
  }
204
+ #course_curriculum .item-bulk-actions {
205
  text-align: right;
206
  margin-top: 0;
207
  margin-bottom: 15px;
208
  }
209
+ #course_curriculum .lp-section-item:not(.lp-item-empty):hover .lp-item-actions > * {
210
  visibility: visible;
211
  }
212
+ #course_curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty) .item-checkbox {
213
  display: inline-block;
214
  height: 34px;
215
  border: none;
219
  cursor: url("../../../assets/images/openhand.cur") 7 5, default;
220
  visibility: visible;
221
  }
222
+ #course_curriculum .curriculum-section-items .lp-section-item .item-checkbox input {
223
  opacity: 0.4;
224
  }
225
+ #course_curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty):hover .item-checkbox input {
226
  opacity: 1;
227
  }
228
+ #course_curriculum .lp-item-lp_lesson .handle.learn-press-icon:before {
229
  content: "\e900";
230
  }
231
+ #course_curriculum .lp-item-lp_quiz .handle.learn-press-icon:before {
232
  content: "\e901";
233
  }
234
+ #course_curriculum .lp-section-item.lp-item-new .handle {
235
  color: #999;
236
  }
237
+ #course_curriculum .curriculum-section-items .lp-section-item:hover,
238
+ #course_curriculum .curriculum-section-items .lp-section-item:hover input.lp-item-name {
239
  background-color: #F9F9F9;
240
  }
241
+ #course_curriculum .lp-section-item .handle {
242
  width: 32px;
243
  height: 32px;
244
  display: inline-block;
248
  line-height: 32px;
249
  color: #00A0D2;
250
  }
251
+ #course_curriculum .lp-section-item.remove input.lp-item-name {
252
  color: #FF0000;
253
  }
254
+ #course_curriculum .lp-section-item input.lp-item-name {
255
  color: #777;
256
  border: none;
257
  box-shadow: none;
263
  overflow: hidden;
264
  white-space: nowrap;
265
  }
266
+ #course_curriculum .lp-section-describe {
267
  border: none;
268
  box-shadow: none;
269
  color: #999;
272
  float: left;
273
  padding-left: 0;
274
  }
275
+ #course_curriculum .curriculum-section-items .lp-section-item input.lp-item-name:focus,
276
+ #course_curriculum input:focus {
277
  color: #444;
278
  }
279
+ #course_curriculum .lp-section-item .section-item-icon {
280
  width: 32px;
281
  white-space: nowrap;
282
  }
292
  cursor: pointer;
293
  border: 1px solid transparent;
294
  }
295
+ #course_curriculum .lp-section-item .learn-press-icon.item-lp_quiz:before {
296
  content: "\f469";
297
  }
298
+ #course_curriculum .lp-section-item .learn-press-icon.item-lp_lesson:before {
299
  content: "\f330";
300
  }
301
+ #course_curriculum .lp-section-item td {
302
  height: 30px;
303
  }
304
  #poststuff .postbox-container {
473
  .learn-press-dropdown-item-types li span.learn-press-icon.item-selected {
474
  color: #0085ba;
475
  }
 
 
 
476
  .post-type-lp_course #switch-course-tabs,
477
  .post-type-lp_course #toggle-meta-boxes {
478
  float: right;
479
  margin-left: 10px;
480
  }
481
+ .post-type-lp_course.enable-course-tabs #post-body-content {
482
+ margin-bottom: 0;
483
+ }
484
+ .post-type-lp_course.enable-course-tabs #normal-sortables .postbox {
485
+ _visibility: hidden;
486
+ float: left;
487
+ margin-right: -100%;
488
+ width: 100%;
489
+ box-sizing: border-box;
490
+ height: 0;
491
+ overflow: hidden;
492
+ border-width: 0;
493
+ }
494
+ .post-type-lp_course.enable-course-tabs #normal-sortables .postbox.active {
495
+ height: auto;
496
+ border-width: 1px;
497
+ }
498
+ .post-type-lp_course.enable-course-tabs #normal-sortables .postbox .handlediv,
499
+ .post-type-lp_course.enable-course-tabs #normal-sortables .postbox .hndle {
500
+ display: none;
501
+ }
502
+ .post-type-lp_course.enable-course-tabs #course-tabs {
503
+ background: #FFF;
504
+ padding: 10px;
505
+ margin-bottom: 0;
506
+ border: 1px solid #DDD;
507
+ border-bottom: none;
508
+ }
509
+ .post-type-lp_course.enable-course-tabs #course-tabs:after {
510
+ display: block;
511
+ clear: both;
512
+ content: '';
513
+ }
514
+ .post-type-lp_course.enable-course-tabs #course-tabs.ui-sortable:not(.ui-sortable-disabled) li.ui-sortable-handle {
515
+ position: relative;
516
+ }
517
+ .post-type-lp_course.enable-course-tabs #course-tabs.ui-sortable:not(.ui-sortable-disabled) li.ui-sortable-handle a {
518
+ border: 1px solid #ddd;
519
+ padding: 0px 5px;
520
+ margin: 0 5px;
521
+ color: #DDD;
522
+ background: #FFF;
523
+ }
524
+ .post-type-lp_course.enable-course-tabs #course-tabs.ui-sortable:not(.ui-sortable-disabled) li.ui-sortable-handle:after {
525
+ content: '';
526
+ position: absolute;
527
+ top: 0;
528
+ left: 0;
529
+ width: 100%;
530
+ height: 100%;
531
+ cursor: move;
532
+ }
533
+ .post-type-lp_course.enable-course-tabs #course-tabs li {
534
+ float: left;
535
+ margin-bottom: 0;
536
+ }
537
+ .post-type-lp_course.enable-course-tabs #course-tabs li a {
538
+ display: block;
539
+ padding: 0 15px 0 0;
540
+ text-decoration: none;
541
+ outline: none;
542
+ box-shadow: none;
543
+ }
544
+ .post-type-lp_course.enable-course-tabs #course-tabs li.active a {
545
+ font-weight: bold;
546
+ }
547
+ .post-type-lp_course.enable-course-tabs #course-tabs li#switch-course-metaboxes {
548
+ float: right;
549
+ }
550
+ .post-type-lp_course.enable-course-tabs #course-tabs li#switch-course-metaboxes #complete-reorder-course-tabs {
551
+ display: none;
552
+ }
553
+ .post-type-lp_course.enable-course-tabs #course-tabs li#switch-course-metaboxes a {
554
+ padding-right: 0;
555
+ color: #FF0000;
556
+ display: inline-block;
557
+ margin-left: 15px;
558
+ }
559
  /*
560
  #lp-course-curriculum .lp-course-curriculum-toggle{
561
  padding: 0;
assets/css/admin/meta-box-course.less CHANGED
@@ -1,915 +1,983 @@
1
- /* meta box course */
2
- .rwmb-duration-wrapper input[type="text"],
3
- .rwmb-duration-wrapper select {
4
- vertical-align: baseline;
5
- }
6
- #learn-press-toggle-course-results{
7
- display: block;margin-bottom:10px;
8
- a{box-shadow: none;}
9
- }
10
- .post-type-lp_course {
11
- #postdivric,
12
- #submitpost {
13
- visibility: hidden;
14
- }
15
- }
16
-
17
- #learn-press-review-message {
18
- margin-bottom: 10px;
19
- > h4 {
20
- margin: 0 0 10px 0;
21
- }
22
- > textarea {
23
- width: 100%;
24
- height: 100px;
25
- }
26
- .lp-pending-review-message {
27
- background: #c44;
28
- padding: 5px 10px;
29
- color: #FFF;
30
- margin: -10px -10px 10px;
31
- font-size: 12px;
32
- font-style: italic;
33
- }
34
- }
35
-
36
- #lp-course-curriculum {
37
- border: none;
38
- background-color: transparent;
39
- margin: 20px 0;
40
- }
41
-
42
- .post-type-lp_course {
43
- & .column-price, & .column-students {
44
- width: 10%;
45
- }
46
-
47
- #lp-course-curriculum .curriculum-section-items .lp-item-empty td.section-item-input {
48
- padding-left: 40px;
49
- &.hover {
50
- padding-left: 0;
51
- }
52
- }
53
-
54
- .type-lp_course {
55
-
56
- &.status-pending {
57
- .row-actions .view {
58
- display: none;
59
- }
60
- }
61
- }
62
-
63
- }
64
-
65
- #lp-course-curriculum .curriculum-heading {
66
- margin: 0 0 20px 0;
67
- padding: 10px 20px;
68
- background-color: #FFF;
69
- line-height: 1;
70
- border: 1px solid #DDD;
71
- }
72
-
73
- #lp-course-curriculum .curriculum-heading .description {
74
- font-weight: normal;
75
- color: #999;
76
- display: block;
77
- font-size: 90%;
78
- margin-top: 10px;;
79
- }
80
-
81
- #lp-course-curriculum .curriculum-heading .items-toggle {
82
- float: right;
83
- margin: -33px 7px 0 0;
84
- line-height: 1;
85
- box-shadow: none;
86
- }
87
-
88
- #lp-course-curriculum .curriculum-heading .items-toggle a {
89
- -webkit-box-shadow: none;
90
- -moz-box-shadow: none;
91
- box-shadow: none;
92
- font-size: 32px;
93
-
94
- }
95
-
96
- #lp-course-curriculum .curriculum-sections {
97
- margin: 0;
98
- background-color: #FFF;
99
- border-bottom: 1px solid #DDD;
100
- }
101
-
102
- #lp-course-curriculum .curriculum-section {
103
- margin: -1px 0 0 0;
104
- background-color: #FFF;
105
- border-bottom: 1px solid #DDD;
106
- position: relative;
107
- }
108
-
109
- #lp-course-curriculum .curriculum-section.ui-sortable-placeholder {
110
- background-image: url("../../images/stripe.png");
111
- visibility: visible !important;
112
- border: 1px solid #DDD;
113
- border-bottom: none;
114
- }
115
-
116
- #lp-course-curriculum .curriculum-section-head {
117
- border: 1px solid #DDD;
118
- background-color: #F9F9F9;
119
- border-bottom: none;
120
- margin: 0;
121
- color: #777;
122
- padding: 3px 20px;
123
- }
124
-
125
- #lp-course-curriculum .curriculum-section-head input {
126
- background-color: #F9F9F9;
127
- }
128
-
129
- #lp-course-curriculum .curriculum-section-head .lp-section-actions {
130
- float: right;
131
- margin: 14px 0;
132
- visibility: hidden;
133
- position: relative;
134
- }
135
-
136
- #lp-course-curriculum .curriculum-section:not(.lp-empty-section) .curriculum-section-head:hover .lp-section-actions {
137
- visibility: visible;
138
- }
139
-
140
- #lp-course-curriculum .curriculum-section .lp-section-actions a {
141
- vertical-align: middle;
142
- color: #666666;
143
- width: 24px;
144
- height: 24px;
145
- box-shadow: none;
146
- }
147
-
148
- #lp-course-curriculum .curriculum-section .lp-section-actions a[data-action="expand"] {
149
- line-height: 28px;
150
- }
151
-
152
- #lp-course-curriculum .curriculum-section .lp-section-actions a:before {
153
- width: 24px;
154
- height: 24px;
155
- font-size: 24px;
156
- }
157
-
158
- #lp-course-curriculum .curriculum-section .lp-section-actions a:hover {
159
- color: #00a0d2;
160
- }
161
-
162
- #lp-course-curriculum .curriculum-section .curriculum-section-head .lp-section-actions .move {
163
- cursor: url("../../../assets/images/openhand.cur") 7 5, default;
164
- position: absolute;
165
- right: -15px;
166
- height: 57px;
167
- top: -15px;
168
- background: url("../../../assets/images/grippy_large.png") right no-repeat;
169
- width: 20px;
170
- }
171
-
172
- #lp-course-curriculum .curriculum-section-content {
173
- border: 1px solid #DDD;
174
- padding: 20px;
175
- border-bottom-width: 0;
176
- width: 100%;
177
- box-sizing: border-box;
178
- }
179
-
180
- #lp-course-curriculum .curriculum-section.ui-sortable-helper {
181
- border-bottom: 1px solid #DDD;
182
- }
183
-
184
- #lp-course-curriculum .curriculum-section-head .lp-section-name {
185
- border: none;
186
- outline: none;
187
- box-shadow: none;
188
- font-size: 24px;
189
- color: #777;
190
- width: 70%;
191
- margin: 0;
192
- padding: 0;
193
- height: 50px;
194
- }
195
-
196
- #lp-course-curriculum .curriculum-section-head .lp-section-name:focus {
197
- color: #444;
198
- }
199
-
200
- #lp-course-curriculum .curriculum-section.lp-empty-section .curriculum-section-content {
201
- _display: none;
202
- }
203
-
204
- #lp-course-curriculum .curriculum-section-items {
205
- border-collapse: collapse;
206
- width: 100%;
207
- }
208
-
209
- #lp-course-curriculum .curriculum-section-items .lp-section-item {
210
- border: 1px dashed #DDD;
211
- margin: -1px 0 0 0;
212
- padding: 5px 0;
213
- background-color: #FFF;
214
- }
215
-
216
- #lp-course-curriculum .curriculum-section-items .lp-section-item:nth-child(2n+1),
217
- #lp-course-curriculum .curriculum-section-items .lp-section-item:nth-child(2n+1) .section-item-input input {
218
- background-color: #FCFCFC;
219
- }
220
-
221
- #lp-course-curriculum .curriculum-section-items .lp-section-item .lp-item-actions {
222
- margin: 0;
223
- float: right;
224
- position: relative;
225
- }
226
-
227
- #lp-course-curriculum .curriculum-section-items .lp-section-item .lp-item-actions a {
228
- vertical-align: middle;
229
- color: #666;
230
- margin-top: -2px;
231
- box-shadow: none;
232
- }
233
-
234
- #lp-course-curriculum .curriculum-section-items .lp-section-item .lp-item-actions a:hover {
235
- color: #00a0d2;
236
- }
237
-
238
- #lp-course-curriculum .curriculum-section-items .lp-section-item[data-item_id=""] .lp-edit {
239
- display: none;
240
- }
241
-
242
- #lp-course-curriculum .curriculum-section-items .lp-section-item.lp-item-empty .lp-item-actions {
243
- display: none;
244
- }
245
-
246
- #lp-course-curriculum .lp-section-item.ui-sortable-helper td {
247
-
248
- }
249
-
250
- #lp-course-curriculum .lp-section-item.ui-sortable-placeholder {
251
- visibility: visible !important;
252
- }
253
-
254
- #lp-course-curriculum .lp-section-item.ui-sortable-placeholder td {
255
- background-image: url("../../../assets/images/stripe.png");
256
- border-bottom: none;
257
- }
258
-
259
- #lp-course-curriculum .lp-item-actions > * {
260
- visibility: hidden;
261
- }
262
-
263
- #lp-course-curriculum .lp-item-actions > a {
264
- }
265
-
266
- #lp-course-curriculum .item-bulk-actions {
267
- text-align: right;
268
- margin-top: 0;
269
- margin-bottom: 15px;
270
- }
271
-
272
- #lp-course-curriculum .lp-section-item:not(.lp-item-empty):hover .lp-item-actions > * {
273
- visibility: visible;
274
- }
275
-
276
- #lp-course-curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty) .item-checkbox {
277
- display: inline-block;
278
- height: 34px;
279
- border: none;
280
- line-height: 32px;
281
- padding: 0 0 0 0;
282
- margin: 0 4px 0 10px;
283
- cursor: url("../../../assets/images/openhand.cur") 7 5, default;
284
- visibility: visible;
285
- }
286
-
287
- #lp-course-curriculum .curriculum-section-items .lp-section-item .item-checkbox input {
288
- opacity: 0.4;
289
- }
290
-
291
- #lp-course-curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty):hover .item-checkbox input {
292
- opacity: 1;
293
- }
294
-
295
- #lp-course-curriculum .lp-item-lp_lesson .handle.learn-press-icon:before {
296
- content: "\e900";
297
- }
298
-
299
- #lp-course-curriculum .lp-item-lp_quiz .handle.learn-press-icon:before {
300
- content: "\e901";
301
- }
302
-
303
- #lp-course-curriculum .lp-section-item.lp-item-new .handle {
304
- color: #999;
305
- }
306
-
307
- #lp-course-curriculum .curriculum-section-items .lp-section-item:hover,
308
- #lp-course-curriculum .curriculum-section-items .lp-section-item:hover input.lp-item-name {
309
- background-color: #F9F9F9;
310
- }
311
-
312
- #lp-course-curriculum .lp-section-item .handle {
313
- width: 32px;
314
- height: 32px;
315
- display: inline-block;
316
- vertical-align: middle;
317
- text-align: center;
318
- font-size: 18px;
319
- line-height: 32px;
320
- color: #00A0D2;
321
- }
322
-
323
- #lp-course-curriculum .lp-section-item.remove input.lp-item-name {
324
- color: #FF0000;
325
- }
326
-
327
- #lp-course-curriculum .lp-section-item.ui-sortable-helper {
328
-
329
- }
330
-
331
- #lp-course-curriculum .lp-section-item input.lp-item-name {
332
- color: #777;
333
- border: none;
334
- box-shadow: none;
335
- outline: none;
336
- font-size: 16px;
337
- width: 100%;
338
- vertical-align: middle;
339
- text-overflow: ellipsis;
340
- overflow: hidden;
341
- white-space: nowrap;
342
- }
343
-
344
- #lp-course-curriculum .lp-section-describe {
345
- border: none;
346
- box-shadow: none;
347
- color: #999;
348
- font-style: italic;
349
- width: 80%;
350
- float: left;
351
- padding-left: 0;
352
- }
353
-
354
- #lp-course-curriculum .curriculum-section-items .lp-section-item input.lp-item-name:focus,
355
- #lp-course-curriculum input:focus {
356
- color: #444;
357
- }
358
-
359
- #lp-course-curriculum .lp-section-item .section-item-icon {
360
- width: 32px;
361
- white-space: nowrap;
362
- }
363
-
364
- .lp-section-item .learn-press-icon {
365
- width: 32px;
366
- height: 32px;
367
- font-family: dashicons;
368
- display: inline-block;
369
- font-size: 20px;
370
- text-align: center;
371
- line-height: 32px;
372
- color: #DDD;
373
- cursor: pointer;
374
- border: 1px solid transparent;
375
- }
376
-
377
- #lp-course-curriculum .lp-section-item .learn-press-icon.item-lp_quiz:before {
378
- content: "\f469";
379
- }
380
-
381
- #lp-course-curriculum .lp-section-item .learn-press-icon.item-lp_lesson:before {
382
- content: "\f330";
383
- }
384
-
385
- #lp-course-curriculum .lp-section-item .learn-press-icon.item-selected,
386
- #lp-course-curriculum .lp-section-item[data-item_id=""] .learn-press-icon:hover {
387
- }
388
-
389
- #lp-course-curriculum .lp-section-item td {
390
- height: 30px;
391
- }
392
-
393
- #poststuff .postbox-container {
394
- position: relative;
395
- }
396
-
397
- #course_tabs .handlediv,
398
- #course_tabs .hndle,
399
- #course_tabs .rwmb-label {
400
- display: none;
401
- }
402
-
403
- #course_tabs .rwmb-input {
404
-
405
- }
406
-
407
- #course_tabs .inside {
408
- margin: 0;
409
- padding: 0;
410
- }
411
-
412
- #course_tabs .rwmb-course_tabs-wrapper {
413
- margin: 0;
414
- }
415
-
416
- #course_tabs {
417
- position: absolute;
418
- left: 0;
419
- right: 0;
420
- }
421
-
422
- #course_tabs.fixed {
423
- position: fixed;
424
- top: 30px;
425
- z-index: 10000;
426
- opacity: 0.5;
427
- left: 182px;
428
- right: 320px;
429
- }
430
-
431
- #course_tabs.fixed:hover {
432
- opacity: 1;
433
- }
434
-
435
- #course_tabs_placeholder {
436
- height: 41px;
437
- margin-bottom: 20px;
438
- }
439
-
440
- #poststuff h3#course-tabs-h3 {
441
- padding: 0;
442
- }
443
-
444
- #course-tabs-h3 > a {
445
- padding: 10px;
446
- display: inline-block;
447
- border-right: 1px solid #DDD;
448
- text-decoration: none;
449
- _color: #AAA;
450
- box-shadow: none;
451
- }
452
-
453
- .learn-press-review-logs {
454
- padding-bottom: 10px;
455
- .review-message {
456
- font-style: italic;
457
- font-size: 14px;
458
- margin: 10px 0;
459
- color: #999;
460
- }
461
- > li {
462
- border-bottom: 1px dashed #DDD;
463
- padding-bottom: 20px;
464
- margin-top: 20px;
465
- position: relative;
466
- &:after {
467
- content: '';
468
- display: block;
469
- clear: both;
470
- }
471
- }
472
- .review-user {
473
- width: 48px;
474
- float: left;
475
- img {
476
- max-width: 100%;
477
- height: auto;
478
- }
479
- > * {
480
- float: left;
481
- }
482
- }
483
- .review-index {
484
- width: 46px;
485
- font-weight: bold;
486
- position: absolute;
487
- bottom: -11px;
488
- left: 0;
489
- background-color: #FFF;
490
- text-align: center;
491
- border: 1px dashed #DDD;
492
- height: 20px;
493
- line-height: 20px;
494
- color: #CCC;
495
- }
496
- .review-content {
497
- margin-left: 68px;
498
- }
499
- > li .lp-label {
500
- font-size: 100%;
501
- margin-top: 20px;
502
- }
503
- }
504
-
505
- .rwmb-curriculum-wrapper .rwmb-label {
506
- display: none;
507
- }
508
-
509
- .rwmb-curriculum-wrapper .rwmb-input {
510
- width: auto !important;
511
- display: block;
512
- float: none;
513
- }
514
-
515
- .column-lp_course .row-actions {
516
- display: inline-block;
517
- margin-left: 10px;
518
- }
519
-
520
- .lp-modal-search li.selected {
521
- display: none;
522
- }
523
-
524
- .lp-search-items input[name="lp-item-name"] {
525
- width: 350px;
526
- }
527
-
528
- .lp-modal-search {
529
- background-color: #F5F5F5;
530
- color: #777;
531
- padding: 20px;
532
- height: 100%;
533
- }
534
-
535
- .lp-modal-search ul {
536
-
537
- }
538
-
539
- .lp-highlight-color {
540
- text-decoration: underline;
541
- color: #00a0d2;
542
- }
543
-
544
- .learn-press-dropdown-item-types {
545
- position: relative;
546
- > ul {
547
- display: none;
548
- position: absolute;
549
- top: 0px;
550
- z-index: 10;
551
- background: #FFF;
552
- border: 1px solid #DDD;
553
- left: 100%;
554
- margin-left: -1px;
555
- > li {
556
- margin: 0;
557
- display: table-cell;
558
- span {
559
- border-width: 0 !important;
560
- }
561
- }
562
- }
563
- }
564
-
565
- tr[data-item_id=""] .learn-press-dropdown-item-types:hover > ul,
566
- tr[data-item_id=""].focus .learn-press-dropdown-item-types > ul {
567
- display: inline-table;
568
- border-left-color: transparent;
569
- }
570
-
571
- .learn-press-dropdown-item-types:hover > span.learn-press-icon,
572
- tr.focus .learn-press-dropdown-item-types > span.learn-press-icon {
573
- background: #FFF;
574
- border-color: #DDD;
575
- z-index: 5;
576
- position: relative;
577
- }
578
-
579
- .learn-press-dropdown-item-types:hover > span.learn-press-icon:after {
580
- content: '';
581
- border-left: 1px solid #EEE;
582
- position: absolute;
583
- right: 0;
584
- display: inline-block;
585
- height: 20px;
586
- top: 50%;
587
- margin-top: -10px;
588
- }
589
-
590
- .learn-press-dropdown-item-types > span.learn-press-icon,
591
- .learn-press-dropdown-item-types li:hover span.learn-press-icon,
592
- .learn-press-dropdown-item-types li span.learn-press-icon.item-selected {
593
- color: #0085ba;
594
- }
595
-
596
- .learn-press-course-attributes {
597
- margin: 20px 0;
598
- .course-attribute-taxonomy {
599
- li {
600
-
601
- }
602
- }
603
- }
604
-
605
- .post-type-lp_course {
606
- #switch-course-tabs,
607
- #toggle-meta-boxes {
608
- float: right;
609
- margin-left: 10px;
610
- }
611
- }
612
-
613
- /*
614
- #lp-course-curriculum .lp-course-curriculum-toggle{
615
- padding: 0;
616
- margin: 0;
617
- float: right;
618
- }
619
- #lp-course-curriculum .lp-item-name{
620
- box-shadow: none;
621
- border-color: transparent;
622
- color: #BBB;
623
- }
624
- #lp-course-curriculum .lp-section-item:hover,
625
- #lp-course-curriculum .lp-section-item.hover{
626
- background-color: #F5F5F5;
627
- border-style: solid;
628
- }
629
- #lp-course-curriculum .lp-section-item.lp-item-lp_lesson .handle:after{
630
- content: "\f497";
631
- }
632
- #lp-course-curriculum .lp-section-item.lp-item-lp_quiz .handle:after{
633
- content: "\f130";
634
- }
635
- #lp-course-curriculum .lp-section-item:hover .lp-item-name,
636
- #lp-course-curriculum .lp-section-item.hover .lp-item-name{
637
- border: 1px solid #DDD;
638
- color: #32373c;
639
- }
640
- #lp-course-curriculum .lp-section-empty .lp-section-items{
641
- display: none;
642
- }
643
- #lp-course-curriculum .lp-section-item .lp-item-actions{
644
- float: right;
645
- margin-left: 5px;
646
- margin-top: 3px;
647
- }
648
- #lp-course-curriculum .lp-item-empty .lp-item-actions,
649
- #lp-course-curriculum .lp-section-empty .lp-section-head .lp-action,
650
- #lp-course-curriculum .lp-section-empty .lp-curriculum-section-content {
651
- display: none;
652
- }
653
- #lp-course-curriculum .lp-item-empty{
654
- cursor: default;
655
- }
656
- #lp-course-curriculum .lp-item-new{
657
- border-color: #00A0D2;
658
- }
659
- #lp-course-curriculum .lp-item-new .lp-item-name{
660
- border-color: #00A0D2;
661
- }
662
- #lp-course-curriculum .lp-section-head{
663
- padding: 0;
664
- }
665
- #lp-course-curriculum .lp-curriculum-section .lp-toggle i:before{
666
- content: '\f132';
667
- }
668
- #lp-course-curriculum .lp-curriculum-section.open .lp-toggle i:before{
669
- content: '\f460';
670
- }
671
- .lp-modal-search{
672
- position: absolute;
673
- background-color: #FFF;
674
- border: 1px solid #DDD;
675
- border-top: none;
676
- z-index: 9999;
677
- margin: -1px 0 0 1px;
678
- }
679
- .lp-modal-search ul{
680
- margin: 0;
681
- padding: 0;
682
- }
683
- .lp-modal-search ul li{
684
- list-style: none;
685
- padding: 5px;
686
- margin: 0;
687
- }
688
- .lp-modal-search li.highlighting,
689
- .lp-modal-search li:hover{
690
- background-color: #EAEAEA;
691
- cursor: pointer;
692
- }
693
- .lp-highlight-color{
694
- text-decoration: underline;
695
- }
696
- .lp-search-no-results{
697
- display: none;
698
- }
699
- .lp-curriculum-sections .ui-sortable-placeholder{
700
- visibility: visible !important;
701
- border: 2px dashed #DDD;
702
- }
703
- .lp-curriculum-sections .lp-sorting{
704
- height: auto !important;
705
- }
706
- */
707
- /*
708
-
709
- .lp-course-curriculum{}
710
- .lp-course-curriculum .lp-curriculum-sections{
711
-
712
- }
713
- .lp-course-curriculum .lp-curriculum-section{
714
- transition: opacity 0.25s;
715
- margin-bottom: 20px;
716
- border: 1px solid #DDD;
717
- }
718
- .lp-course-curriculum .lp-curriculum-section.lp-selected .lp-curriculum-section-content{
719
- background-color: #F5F5F5;
720
- }
721
- .lp-course-curriculum .lp-curriculum-section-content > p{
722
- display: inline-block;
723
- }
724
- .lp-course-curriculum .lp-curriculum-section.lp-selected > h3{
725
- _border-bottom: 1px solid #DDD;
726
- }
727
- .lp-course-curriculum .lp-curriculum-section > h3{
728
- padding: 10px ;
729
- margin: 0;
730
- background-color: #F5F5F5;
731
- height: 62px;
732
- position: relative;
733
- cursor: move;
734
- }
735
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-section-name-wrapper{
736
- top: 9px;
737
- }
738
- .lp-course-curriculum .lp-curriculum-section > h3 > span > input{
739
- border: 1px solid #DDD;
740
- border-radius: 3px;
741
- font-size: 24px;
742
- width: 100%;
743
- color: #777;
744
- }
745
- .lp-course-curriculum .lp-curriculum-section > h3 > span.lp-section-name-wrapper{
746
- position: absolute;
747
- display: inline-block;
748
- right: 137px;
749
- left: 71px;
750
- }
751
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-action{
752
- display: block;
753
- position: relative;
754
- height: 62px;
755
- width: 62px;
756
- border-left: 1px solid #DDD;
757
- -top: -8px;
758
- -right: -11px;
759
- cursor: pointer;
760
- float: right;
761
- }
762
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-sort{
763
- display: none;
764
- }
765
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-action .dashicons{
766
- font-size: 32px;
767
- width: 100%;
768
- height: 100%;
769
- line-height: 62px;
770
- color: #0073aa;
771
- }
772
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-action:hover .dashicons{
773
- color: #009ED7;
774
- }
775
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-toggle{
776
- _right: 62px;
777
- }
778
- .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-remove{
779
- _right: 124px;
780
- }
781
-
782
- .lp-course-curriculum .lp-curriculum-section.closed .lp-curriculum-section-content{
783
- display: none;
784
- }
785
-
786
- .lp-course-curriculum .sorting .ui-sortable-helper .lp-curriculum-section-content{
787
- display: none !important;
788
- }
789
- .lp-course-curriculum .sorting .ui-sortable-placeholder,
790
- .lp-section-items.sorting .ui-sortable-placeholder{
791
- border: 3px dashed #DDD;
792
- visibility: visible !important;
793
- position: relative;
794
- }
795
- .lp-course-curriculum .sorting .ui-sortable-placeholder:after,
796
- .lp-section-items.sorting .ui-sortable-placeholder:after{
797
- content: '';
798
- display: block;
799
- width: 0px;
800
- height: 0px;
801
- border: 28px solid transparent;
802
- border-left-color: #999;
803
- position: absolute;
804
- top: 0;
805
- left: -33px;
806
-
807
- }
808
-
809
- .lp-section-items.sorting .ui-sortable-placeholder:after{
810
- border-width: 15px;
811
- left: -20px;
812
- }
813
- .lp-curriculum-section-content{
814
- background-color: #F5F5F5;
815
- background-color: #FFF;
816
- _border-bottom: 2px dashed #DDD;
817
- padding: 20px;
818
- margin-bottom: 0px;
819
- border-top: 1px solid #DDD;
820
- }
821
- .lp-dynamic-form{
822
- position: absolute;
823
- padding: 0px;
824
- background-color: transparent;
825
- z-index: 210;
826
- height: 15px;
827
- overflow: hidden;
828
- }
829
- .lp-container-dropdown{
830
- height: 15px;
831
- vertical-align: top;
832
- }
833
- .lp-container-dropdown > a{
834
- background-image: none !important;
835
- background-color: #FFF !important;
836
- }
837
- .lp-container-dropdown.select2-drop-above > a{
838
- height: 3px;
839
- }
840
- .lp-select-dropdown{
841
- margin-top: -6px;
842
- }
843
- .lp-select-dropdown.select2-drop-above{
844
- padding-bottom: 0;
845
- }
846
-
847
- .lp-empty .lp-curriculum-section-content{
848
- display: none !important;
849
- }
850
-
851
- .lp-section-items{
852
- min-height: 20px;
853
-
854
-
855
- }
856
- .lp-section-items > li{
857
- padding: 5px;
858
- border:1px dashed #DDD;
859
- background-color: #FFF;
860
- cursor: move;
861
- position: relative;
862
- }
863
- .lp-section-items > li .lp-title{
864
- cursor: auto;
865
- padding: 3px 5px;
866
- border: 1px solid transparent;
867
- display: inline-block;
868
- width: 80%;
869
- -webkit-box-sizing: border-box;
870
- -moz-box-sizing: border-box;
871
- box-sizing: border-box;
872
-
873
- }
874
- .lp-section-items > li:hover .lp-title {
875
- border-color: #DDD;
876
- cursor: text;
877
- }
878
- .lp-section-items > li input{
879
- width: 70%;
880
- }
881
-
882
- .lp-section-items > li:hover{
883
- border-style: solid;
884
- }
885
- .lp-section-icon{
886
- position: absolute;
887
- top:0;
888
- left:0;
889
- width: 62px;
890
- height: 62px;
891
- line-height: 54px;
892
- border-right: 1px solid #DDD;
893
- text-align:center;
894
- }
895
- .lp-section-icon i{
896
- height: 60px;
897
- line-height: 60px;
898
- }
899
- .lp-course-curriculum .dashicons{
900
- vertical-align: middle;
901
- }
902
-
903
- .select2-drop.select2-drop-active{
904
- padding: 5px 10px;
905
- }
906
-
907
- .rwmb-course_lesson_quiz-wrapper .rwmb-label{ display: none;}
908
- .rwmb-course_lesson_quiz-wrapper .rwmb-input{ float: none; width: auto; display: block;}
909
-
910
- .lp-course-curriculum-toggle{
911
-
912
- }
913
- .lp-course-curriculum-toggle .expand{
914
- display: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
915
  }*/
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
+
587
+
588
+ .post-type-lp_course {
589
+ #switch-course-tabs,
590
+ #toggle-meta-boxes {
591
+ float: right;
592
+ margin-left: 10px;
593
+ }
594
+ &.enable-course-tabs {
595
+ #post-body-content {
596
+ margin-bottom: 0;
597
+ }
598
+ #normal-sortables {
599
+ .postbox {
600
+ _visibility: hidden;
601
+ float: left;
602
+ margin-right: -100%;
603
+ width: 100%;
604
+ box-sizing: border-box;
605
+ height: 0;
606
+ overflow: hidden;
607
+ border-width: 0;
608
+ &.active {
609
+ height: auto;
610
+ border-width: 1px;
611
+ }
612
+ .handlediv, .hndle {
613
+ display: none;
614
+ }
615
+ }
616
+ }
617
+ #course-tabs {
618
+ background: #FFF;
619
+ padding: 10px;
620
+ margin-bottom: 0;
621
+ border: 1px solid #DDD;
622
+ border-bottom: none;
623
+ &:after {
624
+ display: block;
625
+ clear: both;
626
+ content: '';
627
+ }
628
+ &.ui-sortable:not(.ui-sortable-disabled) {
629
+ li.ui-sortable-handle {
630
+ position: relative;
631
+ a {
632
+ border: 1px solid #ddd;
633
+ padding: 0px 5px;
634
+ margin: 0 5px;
635
+ color: #DDD;
636
+ background: #FFF;
637
+ }
638
+ &:after {
639
+ content: '';
640
+ position: absolute;
641
+ top: 0;
642
+ left: 0;
643
+ width: 100%;
644
+ height: 100%;
645
+ cursor: move;
646
+ }
647
+ }
648
+ }
649
+ li {
650
+ float: left;
651
+ margin-bottom: 0;
652
+ a {
653
+ display: block;
654
+ padding: 0 15px 0 0;
655
+ text-decoration: none;
656
+ outline: none;
657
+ box-shadow: none;
658
+ }
659
+ &.active {
660
+ a {
661
+ font-weight: bold;
662
+ }
663
+ }
664
+ }
665
+ li#switch-course-metaboxes {
666
+ float: right;
667
+ #complete-reorder-course-tabs {
668
+ display: none;
669
+ }
670
+ a {
671
+ padding-right: 0;
672
+ color: #FF0000;
673
+ display: inline-block;
674
+ margin-left: 15px;
675
+ }
676
+ }
677
+ }
678
+ }
679
+ }
680
+
681
+ /*
682
+ #lp-course-curriculum .lp-course-curriculum-toggle{
683
+ padding: 0;
684
+ margin: 0;
685
+ float: right;
686
+ }
687
+ #lp-course-curriculum .lp-item-name{
688
+ box-shadow: none;
689
+ border-color: transparent;
690
+ color: #BBB;
691
+ }
692
+ #lp-course-curriculum .lp-section-item:hover,
693
+ #lp-course-curriculum .lp-section-item.hover{
694
+ background-color: #F5F5F5;
695
+ border-style: solid;
696
+ }
697
+ #lp-course-curriculum .lp-section-item.lp-item-lp_lesson .handle:after{
698
+ content: "\f497";
699
+ }
700
+ #lp-course-curriculum .lp-section-item.lp-item-lp_quiz .handle:after{
701
+ content: "\f130";
702
+ }
703
+ #lp-course-curriculum .lp-section-item:hover .lp-item-name,
704
+ #lp-course-curriculum .lp-section-item.hover .lp-item-name{
705
+ border: 1px solid #DDD;
706
+ color: #32373c;
707
+ }
708
+ #lp-course-curriculum .lp-section-empty .lp-section-items{
709
+ display: none;
710
+ }
711
+ #lp-course-curriculum .lp-section-item .lp-item-actions{
712
+ float: right;
713
+ margin-left: 5px;
714
+ margin-top: 3px;
715
+ }
716
+ #lp-course-curriculum .lp-item-empty .lp-item-actions,
717
+ #lp-course-curriculum .lp-section-empty .lp-section-head .lp-action,
718
+ #lp-course-curriculum .lp-section-empty .lp-curriculum-section-content {
719
+ display: none;
720
+ }
721
+ #lp-course-curriculum .lp-item-empty{
722
+ cursor: default;
723
+ }
724
+ #lp-course-curriculum .lp-item-new{
725
+ border-color: #00A0D2;
726
+ }
727
+ #lp-course-curriculum .lp-item-new .lp-item-name{
728
+ border-color: #00A0D2;
729
+ }
730
+ #lp-course-curriculum .lp-section-head{
731
+ padding: 0;
732
+ }
733
+ #lp-course-curriculum .lp-curriculum-section .lp-toggle i:before{
734
+ content: '\f132';
735
+ }
736
+ #lp-course-curriculum .lp-curriculum-section.open .lp-toggle i:before{
737
+ content: '\f460';
738
+ }
739
+ .lp-modal-search{
740
+ position: absolute;
741
+ background-color: #FFF;
742
+ border: 1px solid #DDD;
743
+ border-top: none;
744
+ z-index: 9999;
745
+ margin: -1px 0 0 1px;
746
+ }
747
+ .lp-modal-search ul{
748
+ margin: 0;
749
+ padding: 0;
750
+ }
751
+ .lp-modal-search ul li{
752
+ list-style: none;
753
+ padding: 5px;
754
+ margin: 0;
755
+ }
756
+ .lp-modal-search li.highlighting,
757
+ .lp-modal-search li:hover{
758
+ background-color: #EAEAEA;
759
+ cursor: pointer;
760
+ }
761
+ .lp-highlight-color{
762
+ text-decoration: underline;
763
+ }
764
+ .lp-search-no-results{
765
+ display: none;
766
+ }
767
+ .lp-curriculum-sections .ui-sortable-placeholder{
768
+ visibility: visible !important;
769
+ border: 2px dashed #DDD;
770
+ }
771
+ .lp-curriculum-sections .lp-sorting{
772
+ height: auto !important;
773
+ }
774
+ */
775
+ /*
776
+
777
+ .lp-course-curriculum{}
778
+ .lp-course-curriculum .lp-curriculum-sections{
779
+
780
+ }
781
+ .lp-course-curriculum .lp-curriculum-section{
782
+ transition: opacity 0.25s;
783
+ margin-bottom: 20px;
784
+ border: 1px solid #DDD;
785
+ }
786
+ .lp-course-curriculum .lp-curriculum-section.lp-selected .lp-curriculum-section-content{
787
+ background-color: #F5F5F5;
788
+ }
789
+ .lp-course-curriculum .lp-curriculum-section-content > p{
790
+ display: inline-block;
791
+ }
792
+ .lp-course-curriculum .lp-curriculum-section.lp-selected > h3{
793
+ _border-bottom: 1px solid #DDD;
794
+ }
795
+ .lp-course-curriculum .lp-curriculum-section > h3{
796
+ padding: 10px ;
797
+ margin: 0;
798
+ background-color: #F5F5F5;
799
+ height: 62px;
800
+ position: relative;
801
+ cursor: move;
802
+ }
803
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-section-name-wrapper{
804
+ top: 9px;
805
+ }
806
+ .lp-course-curriculum .lp-curriculum-section > h3 > span > input{
807
+ border: 1px solid #DDD;
808
+ border-radius: 3px;
809
+ font-size: 24px;
810
+ width: 100%;
811
+ color: #777;
812
+ }
813
+ .lp-course-curriculum .lp-curriculum-section > h3 > span.lp-section-name-wrapper{
814
+ position: absolute;
815
+ display: inline-block;
816
+ right: 137px;
817
+ left: 71px;
818
+ }
819
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action{
820
+ display: block;
821
+ position: relative;
822
+ height: 62px;
823
+ width: 62px;
824
+ border-left: 1px solid #DDD;
825
+ -top: -8px;
826
+ -right: -11px;
827
+ cursor: pointer;
828
+ float: right;
829
+ }
830
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-sort{
831
+ display: none;
832
+ }
833
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action .dashicons{
834
+ font-size: 32px;
835
+ width: 100%;
836
+ height: 100%;
837
+ line-height: 62px;
838
+ color: #0073aa;
839
+ }
840
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action:hover .dashicons{
841
+ color: #009ED7;
842
+ }
843
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-toggle{
844
+ _right: 62px;
845
+ }
846
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-remove{
847
+ _right: 124px;
848
+ }
849
+
850
+ .lp-course-curriculum .lp-curriculum-section.closed .lp-curriculum-section-content{
851
+ display: none;
852
+ }
853
+
854
+ .lp-course-curriculum .sorting .ui-sortable-helper .lp-curriculum-section-content{
855
+ display: none !important;
856
+ }
857
+ .lp-course-curriculum .sorting .ui-sortable-placeholder,
858
+ .lp-section-items.sorting .ui-sortable-placeholder{
859
+ border: 3px dashed #DDD;
860
+ visibility: visible !important;
861
+ position: relative;
862
+ }
863
+ .lp-course-curriculum .sorting .ui-sortable-placeholder:after,
864
+ .lp-section-items.sorting .ui-sortable-placeholder:after{
865
+ content: '';
866
+ display: block;
867
+ width: 0px;
868
+ height: 0px;
869
+ border: 28px solid transparent;
870
+ border-left-color: #999;
871
+ position: absolute;
872
+ top: 0;
873
+ left: -33px;
874
+
875
+ }
876
+
877
+ .lp-section-items.sorting .ui-sortable-placeholder:after{
878
+ border-width: 15px;
879
+ left: -20px;
880
+ }
881
+ .lp-curriculum-section-content{
882
+ background-color: #F5F5F5;
883
+ background-color: #FFF;
884
+ _border-bottom: 2px dashed #DDD;
885
+ padding: 20px;
886
+ margin-bottom: 0px;
887
+ border-top: 1px solid #DDD;
888
+ }
889
+ .lp-dynamic-form{
890
+ position: absolute;
891
+ padding: 0px;
892
+ background-color: transparent;
893
+ z-index: 210;
894
+ height: 15px;
895
+ overflow: hidden;
896
+ }
897
+ .lp-container-dropdown{
898
+ height: 15px;
899
+ vertical-align: top;
900
+ }
901
+ .lp-container-dropdown > a{
902
+ background-image: none !important;
903
+ background-color: #FFF !important;
904
+ }
905
+ .lp-container-dropdown.select2-drop-above > a{
906
+ height: 3px;
907
+ }
908
+ .lp-select-dropdown{
909
+ margin-top: -6px;
910
+ }
911
+ .lp-select-dropdown.select2-drop-above{
912
+ padding-bottom: 0;
913
+ }
914
+
915
+ .lp-empty .lp-curriculum-section-content{
916
+ display: none !important;
917
+ }
918
+
919
+ .lp-section-items{
920
+ min-height: 20px;
921
+
922
+
923
+ }
924
+ .lp-section-items > li{
925
+ padding: 5px;
926
+ border:1px dashed #DDD;
927
+ background-color: #FFF;
928
+ cursor: move;
929
+ position: relative;
930
+ }
931
+ .lp-section-items > li .lp-title{
932
+ cursor: auto;
933
+ padding: 3px 5px;
934
+ border: 1px solid transparent;
935
+ display: inline-block;
936
+ width: 80%;
937
+ -webkit-box-sizing: border-box;
938
+ -moz-box-sizing: border-box;
939
+ box-sizing: border-box;
940
+
941
+ }
942
+ .lp-section-items > li:hover .lp-title {
943
+ border-color: #DDD;
944
+ cursor: text;
945
+ }
946
+ .lp-section-items > li input{
947
+ width: 70%;
948
+ }
949
+
950
+ .lp-section-items > li:hover{
951
+ border-style: solid;
952
+ }
953
+ .lp-section-icon{
954
+ position: absolute;
955
+ top:0;
956
+ left:0;
957
+ width: 62px;
958
+ height: 62px;
959
+ line-height: 54px;
960
+ border-right: 1px solid #DDD;
961
+ text-align:center;
962
+ }
963
+ .lp-section-icon i{
964
+ height: 60px;
965
+ line-height: 60px;
966
+ }
967
+ .lp-course-curriculum .dashicons{
968
+ vertical-align: middle;
969
+ }
970
+
971
+ .select2-drop.select2-drop-active{
972
+ padding: 5px 10px;
973
+ }
974
+
975
+ .rwmb-course_lesson_quiz-wrapper .rwmb-label{ display: none;}
976
+ .rwmb-course_lesson_quiz-wrapper .rwmb-input{ float: none; width: auto; display: block;}
977
+
978
+ .lp-course-curriculum-toggle{
979
+
980
+ }
981
+ .lp-course-curriculum-toggle .expand{
982
+ display: none;
983
  }*/
assets/css/admin/meta-box-order.css CHANGED
@@ -1,136 +1,133 @@
 
1
  /* admin order details */
2
  .column-order_date,
3
  .column-order_total,
4
  .column-order_status,
5
- .post-type-lp_order .column-title {
6
  width: 10%;
7
  }
8
- .post-type-lp_order .column-order_student {
9
  width: 12%;
10
  }
 
 
11
  #order_details .ui-sortable-handle,
12
  #order_details .handlediv {
13
  display: none !important;
14
  }
 
15
  #order_details .inside {
16
  padding: 20px;
17
  margin: 0;
18
  }
 
19
  #order_details .order-user-avatar {
20
  float: left;
21
  margin-right: 20px;
22
  }
 
23
  #order_details .order-user-meta {
24
  float: left;
25
  }
 
26
  #order_details .order-items table {
27
  width: 100%;
28
  border-collapse: collapse;
29
  margin-top: 20px;
30
  }
 
31
  #order_details .order-items table tr {
32
  border-bottom: 1px solid #EEE;
33
  }
 
34
  #order_details .order-items table thead th {
35
  height: 30px;
36
  text-align: left;
37
  font-size: 16px;
38
  padding: 15px 10px;
39
  }
 
40
  #order_details .order-items table td {
41
  padding: 15px 10px;
42
  font-size: 16px;
43
  }
 
44
  #order_details .order-items table .align-right {
45
  text-align: right;
46
  }
 
47
  #order_details .order-data {
48
  float: right;
49
  }
 
50
  #order_details .order-data {
51
  text-align: right;
52
  }
 
53
  #order_details .order-data .order-data-number {
54
  font-size: 24px;
55
  font-weight: bold;
56
  margin-bottom: 10px;
57
  }
 
58
  #order_details .order-data .order-data-date {
59
  font-size: 14px;
60
  font-style: italic;
61
  margin-bottom: 5px;
62
  }
 
63
  #order_details .order-data .order-data-payment-method {
64
  font-size: 16px;
65
  font-weight: bold;
66
  margin: 5px 0;
67
  }
 
68
  #order_details .order-data .order-data-status {
69
  border-radius: 3px;
70
  padding: 2px 5px;
71
  display: inline-block;
72
  color: #FFF;
73
  font-size: 12px;
 
74
  }
 
75
  #order_details .order-data .order-data-status.completed {
76
  background-color: #006400;
77
  }
 
78
  #order_details .order-data .order-data-status.pending {
79
  background-color: #CCCCCC;
80
  }
 
81
  #order_details .total {
82
  font-weight: bold;
83
  font-size: 16px;
84
  }
85
- #order_details .avatar-multiple-users{
 
86
  width: 120px;
87
- height: 120px;
88
- background: #F5F5F5;
89
- position: relative;
90
  }
91
- #order_details .avatar-multiple-users:before,
92
- #order_details .avatar-multiple-users:after{
93
- content: "\f110";
94
- width: 120px;
95
- height:120px;
96
- position: absolute;
97
- top:0;
98
- left: 0;
99
- font-family: dashicons;
100
- font-size: 58px;
101
- color: #a1adbb;
102
- text-align: center;
103
- line-height: 120px;
104
- }
105
- #order_details .avatar-multiple-users:before{
106
- font-size: 48px;
107
- left: -27px;
108
- color: #DEDEDE;
109
- }
110
- #order_details .avatar-multiple-users span:after{
111
- font-family: dashicons;
112
- content: "\f132";
113
- font-size: 32px;
114
- top: 0;
115
- position: absolute;
116
- width: 120px;
117
- height: 120px;
118
- text-align: center;
119
- line-height: 120px;
120
- left: 31px;
121
- color: #a1adbb;
122
- }
123
- #order_details .order-users > strong{
124
- font-weight: bold;
125
  }
126
- #order_details .order-users p{
127
- font-style: italic;
128
- margin: 5px 0 15px 0;
129
  }
130
- #order_details .payment-method-title{
131
- font-weight: bold;
 
 
132
  }
133
 
 
 
 
 
 
 
 
134
 
135
  .order-status-description {
136
  font-size: smaller;
@@ -142,10 +139,11 @@
142
  margin-top: 10px;
143
  border-radius: 3px;
144
  }
 
145
  .order-status-description:before {
146
  content: '';
147
  border: 5px solid transparent;
148
  border-bottom-color: #CEE8FF;
149
  position: absolute;
150
  top: -10px;
151
- }
1
+
2
  /* admin order details */
3
  .column-order_date,
4
  .column-order_total,
5
  .column-order_status,
6
+ .post-type-lp_order .column-title{
7
  width: 10%;
8
  }
9
+ .post-type-lp_order .column-order_student{
10
  width: 12%;
11
  }
12
+ .post-type-lpr_order #post-body-content,
13
+ .post-type-lpr_order #postbox-container-1,
14
  #order_details .ui-sortable-handle,
15
  #order_details .handlediv {
16
  display: none !important;
17
  }
18
+
19
  #order_details .inside {
20
  padding: 20px;
21
  margin: 0;
22
  }
23
+
24
  #order_details .order-user-avatar {
25
  float: left;
26
  margin-right: 20px;
27
  }
28
+
29
  #order_details .order-user-meta {
30
  float: left;
31
  }
32
+
33
  #order_details .order-items table {
34
  width: 100%;
35
  border-collapse: collapse;
36
  margin-top: 20px;
37
  }
38
+
39
  #order_details .order-items table tr {
40
  border-bottom: 1px solid #EEE;
41
  }
42
+
43
  #order_details .order-items table thead th {
44
  height: 30px;
45
  text-align: left;
46
  font-size: 16px;
47
  padding: 15px 10px;
48
  }
49
+
50
  #order_details .order-items table td {
51
  padding: 15px 10px;
52
  font-size: 16px;
53
  }
54
+
55
  #order_details .order-items table .align-right {
56
  text-align: right;
57
  }
58
+
59
  #order_details .order-data {
60
  float: right;
61
  }
62
+
63
  #order_details .order-data {
64
  text-align: right;
65
  }
66
+
67
  #order_details .order-data .order-data-number {
68
  font-size: 24px;
69
  font-weight: bold;
70
  margin-bottom: 10px;
71
  }
72
+
73
  #order_details .order-data .order-data-date {
74
  font-size: 14px;
75
  font-style: italic;
76
  margin-bottom: 5px;
77
  }
78
+
79
  #order_details .order-data .order-data-payment-method {
80
  font-size: 16px;
81
  font-weight: bold;
82
  margin: 5px 0;
83
  }
84
+
85
  #order_details .order-data .order-data-status {
86
  border-radius: 3px;
87
  padding: 2px 5px;
88
  display: inline-block;
89
  color: #FFF;
90
  font-size: 12px;
91
+
92
  }
93
+
94
  #order_details .order-data .order-data-status.completed {
95
  background-color: #006400;
96
  }
97
+
98
  #order_details .order-data .order-data-status.pending {
99
  background-color: #CCCCCC;
100
  }
101
+
102
  #order_details .total {
103
  font-weight: bold;
104
  font-size: 16px;
105
  }
106
+ /*************************************************************/
107
+ .post-type-lpr_order .column-title {
108
  width: 120px;
 
 
 
109
  }
110
+
111
+ .post-type-lpr_order .column-order_student {
112
+ width: 100px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  }
114
+
115
+ .post-type-lpr_order .column-order_date {
116
+ width: 150px;
117
  }
118
+
119
+ .post-type-lpr_order .column-order_total {
120
+ width: 100px;
121
+ text-align: right;
122
  }
123
 
124
+ .post-type-lpr_order .column-order_status {
125
+ width: 100px;
126
+ }
127
+ .post-type-lp_order #minor-publishing-actions,
128
+ .post-type-lp_order #submitdiv .handlediv{
129
+ display: none;
130
+ }
131
 
132
  .order-status-description {
133
  font-size: smaller;
139
  margin-top: 10px;
140
  border-radius: 3px;
141
  }
142
+
143
  .order-status-description:before {
144
  content: '';
145
  border: 5px solid transparent;
146
  border-bottom-color: #CEE8FF;
147
  position: absolute;
148
  top: -10px;
149
+ }
assets/css/admin/meta-box-question.css ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #question_settings select.lpr-question-types{
2
+ margin-left: 20px;
3
+ font-weight: normal;
4
+ display: none;
5
+ font-size: 12px;
6
+ padding: 0;
7
+ height: auto;
8
+ }
9
+ .lpr-question-option{
10
+ border: 1px solid #DDD;
11
+ border-collapse: collapse;
12
+ width: 100%;
13
+ border-bottom: none ;
14
+ position: relative;
15
+ }
16
+ .lpr-question-option{}
17
+ .lpr-question-option th,
18
+ .lpr-question-option td{
19
+ padding: 5px;
20
+ border: 1px solid #DDD;
21
+ }
22
+ .lpr-question-option thead{
23
+ background-color: #F5F5F5;
24
+ }
25
+ .lpr-question-option thead th{
26
+ text-align: left;
27
+ padding: 8px 5px;
28
+ border: 1px solid #DDD;
29
+ }
30
+ .lpr-question-option tbody{
31
+ position: relative;
32
+ }
33
+ .lpr-question-option tbody tr{
34
+ width: 100%;
35
+ background-color: #FFF;
36
+ }
37
+ .lpr-question-option tbody th{
38
+ text-align: left;
39
+ padding: 5px;
40
+ border: 1px solid #DDD;
41
+ width: 25%;
42
+ }
43
+ .lpr-question-option tbody tr.placeholder td{
44
+ border: 1px solid #DDD;
45
+ background-color: #DDD;
46
+ }
47
+ .lpr-question-option tbody tr.ui-sortable-helper{
48
+ left: 0;
49
+ }
50
+ .lpr-question-option input[type="text"] {
51
+ width: 100%;
52
+ }
assets/css/learnpress.css CHANGED
@@ -1,18 +1,3 @@
1
- /*
2
- - PROGRESS CIRCLE
3
- - Archive courses
4
- - Course Curriculum
5
- - BREADCRUMB
6
- - COURSE PROGRESS
7
- - COURSE TABS
8
- - POPUP STYLE
9
- - COURSE QUIZ
10
- - Form field
11
- - jAlerts
12
- - tooltip
13
- - fill in blank
14
- - Shortcode/Widgets
15
- */
16
  @font-face {
17
  font-family: 'lp-icons';
18
  src: url('../fonts/lp-icons.eot?f41nl');
@@ -168,20 +153,12 @@
168
  .learn-press-courses li.course .course-info > * {
169
  display: block;
170
  }
171
- .course-origin-price {
172
- text-decoration: line-through;
173
- padding-right: 5px;
174
- }
175
- .course-price {
176
- color: #54b551;
177
- }
178
  .learn-press-notice .button {
179
  float: right;
180
  }
181
  .learn-press-form {
182
  margin-bottom: 20px;
183
  }
184
- /* Course Curriculum */
185
  #learn-press-course-curriculum ul.curriculum-sections,
186
  #learn-press-course-curriculum ul.section-content {
187
  list-style: none;
@@ -233,7 +210,6 @@
233
  border-radius: 5px;
234
  vertical-align: middle;
235
  margin-left: 5px;
236
- font-size: 10px;
237
  }
238
  #learn-press-course-curriculum .section-header .meta .collapse:before {
239
  content: "\ea0b";
@@ -277,55 +253,6 @@
277
  #learn-press-course-curriculum .course-item .lp-icon {
278
  display: none;
279
  }
280
- #learn-press-course-curriculum .course-item .item-status {
281
- display: none;
282
- font-family: dashicons;
283
- -webkit-border-radius: 4px;
284
- -khtml-border-radius: 4px;
285
- -moz-border-radius: 4px;
286
- -ms-border-radius: 4px;
287
- -o-border-radius: 4px;
288
- border-radius: 4px;
289
- background: #DDD;
290
- color: #22b4ff;
291
- font-size: 18px;
292
- }
293
- #learn-press-course-curriculum .course-item .item-status:before {
294
- content: "\f177";
295
- }
296
- #learn-press-course-curriculum .course-item .item-status.item-status-started:before {
297
- content: "\f469";
298
- }
299
- #learn-press-course-curriculum .course-item .item-status.item-status-completed {
300
- background: #22b4ff;
301
- color: #FFF;
302
- }
303
- #learn-press-course-curriculum .course-item .item-status.item-status-completed:before {
304
- content: "\f147";
305
- }
306
- #learn-press-course-curriculum .course-item .item-status.item-status-passed {
307
- background: #22b4ff;
308
- color: #FFF;
309
- }
310
- #learn-press-course-curriculum .course-item .item-status.item-status-passed:before {
311
- content: "\f147";
312
- }
313
- #learn-press-course-curriculum .course-item .item-status.item-status-failed {
314
- background: #cc540d;
315
- color: #FFF;
316
- }
317
- #learn-press-course-curriculum .course-item .item-status.item-status-failed:before {
318
- content: "\f335";
319
- }
320
- #learn-press-course-curriculum .course-item .item-result {
321
- display: none;
322
- }
323
- #learn-press-course-curriculum .course-item.item-has-status .item-status {
324
- display: inline-block;
325
- }
326
- #learn-press-course-curriculum .course-item.item-has-result .item-result {
327
- display: inline-block;
328
- }
329
  #learn-press-course-curriculum .course-item.viewable {
330
  cursor: pointer;
331
  }
@@ -357,6 +284,18 @@
357
  height: 100%;
358
  content: '';
359
  }
 
 
 
 
 
 
 
 
 
 
 
 
360
  #learn-press-course-curriculum .course-item.focus {
361
  background: #ffb710;
362
  }
@@ -376,25 +315,12 @@
376
  #learn-press-course-curriculum .course-item-meta {
377
  display: block;
378
  line-height: 1;
 
379
  top: 15px;
380
  right: 15px;
381
  float: right;
382
  margin-top: 5px;
383
  }
384
- #learn-press-course-curriculum .course-item-meta .item-loop-meta-text {
385
- font-size: small;
386
- }
387
- #learn-press-course-curriculum .course-item-meta .item-loop-meta-text.item-final {
388
- color: #ffffff;
389
- background: #cc540d;
390
- padding: 3px 8px;
391
- -webkit-border-radius: 3px;
392
- -khtml-border-radius: 3px;
393
- -moz-border-radius: 3px;
394
- -ms-border-radius: 3px;
395
- -o-border-radius: 3px;
396
- border-radius: 3px;
397
- }
398
  .lp-icon {
399
  display: inline-block;
400
  font-family: 'lp-icons';
@@ -516,26 +442,6 @@
516
  .single-lp_course .learn-press-course-results-progress .percentage-sign {
517
  margin-left: 5px;
518
  }
519
- .single-lp_course .learn-press-course-results-progress .grade {
520
- font-size: 12px;
521
- font-weight: bold;
522
- background: #F5F5F5;
523
- padding: 2px 7px;
524
- -webkit-border-radius: 3px;
525
- -khtml-border-radius: 3px;
526
- -moz-border-radius: 3px;
527
- -ms-border-radius: 3px;
528
- -o-border-radius: 3px;
529
- border-radius: 3px;
530
- }
531
- .single-lp_course .learn-press-course-results-progress .grade.passed {
532
- color: #ffffff;
533
- background: #95e6f9;
534
- }
535
- .single-lp_course .learn-press-course-results-progress .grade.failed {
536
- color: #ffffff;
537
- background: #ff5425;
538
- }
539
  .single-lp_course .learn-press-course-results-progress:after {
540
  display: block;
541
  content: '';
@@ -636,24 +542,7 @@
636
  .learn-press-tabs .learn-press-tab-panel.active {
637
  display: block;
638
  }
639
- .learn-press-course-buttons a.button {
640
- display: inline-block;
641
- font-size: 16px;
642
- background: #1a1a1a;
643
- border: 0;
644
- border-radius: 2px;
645
- color: #fff;
646
- font-family: Montserrat, "Helvetica Neue", sans-serif;
647
- font-weight: 700;
648
- letter-spacing: 0.046875em;
649
- line-height: 1;
650
- padding: 0.84375em 0.875em 0.78125em;
651
- text-transform: uppercase;
652
- }
653
- .learn-press-course-buttons a.button:hover {
654
- background: #007acc;
655
- }
656
- /* POPUP STYLE */
657
  #popup_overlay {
658
  z-index: 10000000 !important;
659
  }
@@ -901,7 +790,7 @@ body.course-has-popup {
901
  height: 43px;
902
  line-height: 43px;
903
  background: #F5F5F5;
904
- margin-left: 10px;
905
  border: 1px solid #DDD;
906
  outline: none;
907
  }
@@ -1022,10 +911,6 @@ body.block-content #learn-press-block-content {
1022
  .quiz-intro {
1023
  list-style: none;
1024
  padding: 0;
1025
- margin-left: 0;
1026
- }
1027
- .quiz-intro li label {
1028
- display: inline-block;
1029
  }
1030
  .quiz-questions-list {
1031
  margin: 0 0 20px 0;
@@ -1037,95 +922,10 @@ body.block-content #learn-press-block-content {
1037
  }
1038
  .quiz-questions-list .question-title {
1039
  margin: 0 0 5px 0;
1040
- display: inline-block;
1041
- font-size: 14px;
1042
  }
1043
  .quiz-questions-list .current .question-title {
1044
  font-weight: bold;
1045
  }
1046
- .quiz-questions-list input[type="checkbox"],
1047
- .quiz-questions-list input[type="radio"] {
1048
- border: 1px solid #DDD;
1049
- display: inline-block;
1050
- -webkit-appearance: none;
1051
- width: 18px;
1052
- height: 18px;
1053
- position: relative;
1054
- }
1055
- .quiz-questions-list input[type="checkbox"]:checked:after,
1056
- .quiz-questions-list input[type="radio"]:checked:after {
1057
- content: '';
1058
- display: inline-block;
1059
- position: absolute;
1060
- }
1061
- .quiz-questions-list input[type="checkbox"]:checked:after {
1062
- border-bottom: 3px solid #00b9eb;
1063
- border-right: 1px solid #00b9eb;
1064
- -webkit-transform: rotate(14deg);
1065
- -moz-transform: rotate(14deg);
1066
- -ms-transform: rotate(14deg);
1067
- -o-transform: rotate(14deg);
1068
- transform: rotate(33deg);
1069
- width: 8px;
1070
- height: 16px;
1071
- top: -5px;
1072
- left: 5px;
1073
- }
1074
- .quiz-questions-list input[type="checkbox"]:disabled:after {
1075
- border-color: #DDD;
1076
- }
1077
- .quiz-questions-list input[type="radio"] {
1078
- -webkit-border-radius: 50%;
1079
- -moz-border-radius: 50%;
1080
- border-radius: 50%;
1081
- }
1082
- .quiz-questions-list input[type="radio"]:checked:after {
1083
- background: #00b9eb;
1084
- width: 8px;
1085
- height: 8px;
1086
- border-radius: 50%;
1087
- top: 50%;
1088
- left: 50%;
1089
- margin-left: -4px;
1090
- margin-top: -4px;
1091
- }
1092
- .quiz-questions-list input[type="radio"]:disabled:after {
1093
- background: #DDD;
1094
- }
1095
- .question-results .question-title:after {
1096
- font-family: dashicons;
1097
- font-size: 24px;
1098
- vertical-align: middle;
1099
- display: inline-block;
1100
- text-align: center;
1101
- margin-left: 5px;
1102
- }
1103
- .question-results.correct .question-title:after {
1104
- content: '\f147';
1105
- color: #00adff;
1106
- }
1107
- .question-results.skipped .question-title:after {
1108
- content: '\f534';
1109
- color: #c6c6c6;
1110
- }
1111
- .question-results.incorrect .question-title:after {
1112
- content: '\f335';
1113
- color: #ff5425;
1114
- }
1115
- .question-results.incorrect .user-answer-false .option-title {
1116
- text-decoration: line-through;
1117
- }
1118
- .question-results .answer-true {
1119
- color: #007acc;
1120
- }
1121
- .question-results .answer-true .option-title {
1122
- background: #fff9d8;
1123
- padding: 0 5px;
1124
- margin-left: -5px;
1125
- }
1126
- .question-results input {
1127
- vertical-align: middle;
1128
- }
1129
  .quiz-description .learn-press-question-title,
1130
  .question-content .learn-press-question-title {
1131
  margin-bottom: 20px;
@@ -1996,9 +1796,8 @@ body.block-content #learn-press-block-content {
1996
  .learn-press-message {
1997
  background: #F5F5F5;
1998
  border-left: 5px solid #00A0D2;
1999
- padding: 10px 20px 0px 20px;
2000
  margin-bottom: 20px;
2001
- overflow: hidden;
2002
  }
2003
  .learn-press-message button {
2004
  float: right;
@@ -2414,47 +2213,13 @@ body.profile-resizing {
2414
  #popup_container #popup_panel {
2415
  text-align: center;
2416
  }
2417
- .learn-press-auto-redirect-next-item {
2418
- display: none;
2419
- }
2420
- .learn-press-auto-redirect-next-item.active {
2421
- display: block;
2422
- }
2423
  .single-lp_course .course-summary .lp_course .entry-footer {
2424
  display: none;
2425
  }
2426
  .single-lp_course .learn-press-message {
2427
- position: relative;
2428
  clear: both;
2429
  margin-top: 25px;
2430
  }
2431
- .single-lp_course .learn-press-message .learn-press-countdown {
2432
- display: inline-block;
2433
- width: 1.5em;
2434
- height: 1.5em;
2435
- background: #cc540d;
2436
- text-align: center;
2437
- border-radius: 50%;
2438
- line-height: 1.5em;
2439
- font-size: 0.8em;
2440
- color: #fff;
2441
- }
2442
- .single-lp_course .learn-press-message .learnpress-dismiss-notice {
2443
- display: inline-block;
2444
- position: absolute;
2445
- right: 1em;
2446
- top: 50%;
2447
- -ms-transform: translateY(-50%);
2448
- -webkit-transform: translateY(-50%);
2449
- transform: translateY(-50%);
2450
- cursor: pointer;
2451
- }
2452
- .single-lp_course .learn-press-message .learnpress-dismiss-notice:before {
2453
- font-size: 1.2em;
2454
- color: red;
2455
- content: "\f153";
2456
- font-family: dashicons;
2457
- }
2458
  /* tooltip */
2459
  .learn-press-tooltip-bubble {
2460
  position: absolute;
@@ -2517,37 +2282,48 @@ body.content-item-only #learn-press-content-item.expand {
2517
  content: '-';
2518
  }
2519
  /*
2520
- .payment-method-form {
2521
- &.payment_method_authorizenet {
2522
- background: #f7f7f7;
2523
- border-radius: 5px;
2524
- -webkit-border-radius: 5px;
2525
- -moz-border-radius: 5px;
2526
- padding-top: 25px;
2527
- .row-fluid {
2528
- clear: both;
2529
- padding-bottom: 25px;
2530
- .span6 {
2531
- &:first-child {
2532
- width: 50%;
2533
- float: left;
2534
- label {
2535
- margin-left: 17px;
2536
- }
2537
- select, input {
2538
- margin-left: 10px;
2539
- }
2540
- }
2541
- select, input {
2542
- padding: 8px 0;
2543
- }
2544
- select.required {
2545
- color: #000;
2546
- }
2547
- }
2548
- }
2549
- }
2550
  }*/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2551
  .place-order-action {
2552
  margin-top: 20px;
2553
  }
@@ -2571,128 +2347,31 @@ body.content-item-only #learn-press-content-item.expand {
2571
  z-index: 10;
2572
  position: relative;
2573
  }
2574
- .table-orders .order-status.order-status-removed {
2575
- color: #FF0000;
2576
- }
2577
  /* Shortcode/Widgets */
2578
- .widget_lp-widget-popular-courses .course-meta-data > div,
2579
- .widget_lp-widget-recent-courses .course-meta-data > div,
2580
- .widget_lp-widget-featured-courses .course-meta-data > div {
2581
  display: inline-block;
2582
  }
2583
- .widget_lp-widget-popular-courses .course-meta-data > div:after,
2584
- .widget_lp-widget-recent-courses .course-meta-data > div:after,
2585
- .widget_lp-widget-featured-courses .course-meta-data > div:after {
2586
  content: '/';
2587
  }
2588
- .widget_lp-widget-popular-courses .course-meta-data > div:last-child:after,
2589
- .widget_lp-widget-recent-courses .course-meta-data > div:last-child:after,
2590
- .widget_lp-widget-featured-courses .course-meta-data > div:last-child:after {
2591
  content: '';
2592
  }
2593
- .widget_lp-widget-popular-courses .course-title,
2594
- .widget_lp-widget-recent-courses .course-title,
2595
- .widget_lp-widget-featured-courses .course-title {
2596
  margin: 5px 0;
2597
  }
2598
- .widget_lp-widget-popular-courses .course-entry,
2599
- .widget_lp-widget-recent-courses .course-entry,
2600
- .widget_lp-widget-featured-courses .course-entry {
2601
  margin-bottom: 20px;
2602
- border-bottom: 1px dashed #DDD;
2603
- padding-bottom: 20px;
2604
- }
2605
- .edit-course-item-link a {
2606
- font-size: 14px;
2607
- position: relative;
2608
- padding-left: 25px;
2609
- }
2610
- .edit-course-item-link a:after {
2611
- content: "\f464";
2612
- font-family: Dashicons;
2613
- font-size: 26px;
2614
- position: absolute;
2615
- bottom: 0;
2616
- line-height: 1;
2617
- left: 0;
2618
- }
2619
- .course-item-navigation {
2620
- border-top: 4px solid #333;
2621
- padding-top: 10px;
2622
- margin-top: 20px;
2623
- }
2624
- .course-item-navigation .nav-links .nav-link {
2625
- opacity: 1;
2626
- }
2627
- .course-item-navigation .nav-links .nav-link a {
2628
- opacity: 1;
2629
- }
2630
- .course-item-navigation .nav-links .nav-link a .meta-nav {
2631
- display: block;
2632
- text-transform: uppercase;
2633
- font-size: small;
2634
- color: #b9b9b9;
2635
- }
2636
- .course-item-navigation .nav-links .nav-link a .post-title {
2637
- opacity: 1;
2638
- }
2639
- .course-item-navigation .nav-links .nav-link.nav-previous {
2640
- float: left;
2641
- }
2642
- .course-item-navigation .nav-links .nav-link.nav-next {
2643
- float: right;
2644
- text-align: right;
2645
- }
2646
- .course-item-navigation .nav-links:after {
2647
- clear: both;
2648
- display: block;
2649
- content: '';
2650
- }
2651
- /* widget attributes */
2652
- .lp-course-attributes {
2653
- list-style: none;
2654
- margin-left: 0;
2655
- }
2656
- .lp-course-attributes li {
2657
- list-style: none;
2658
- margin-bottom: 10px;
2659
- }
2660
- .lp-course-attributes .lp-course-attribute-values {
2661
- list-style: none;
2662
- margin-left: 0;
2663
- }
2664
- .lp-course-attributes.course-attributes .lp-course-attribute-values li {
2665
- display: inline-block;
2666
- padding: 3px 8px;
2667
- background: #F0F0F0;
2668
- border-radius: 4px;
2669
- margin: 0 5px 5px 0;
2670
- }
2671
- .lp-course-attributes.course-filters .lp-course-attribute-values li a:before {
2672
- font-family: dashicons;
2673
- border-radius: 50%;
2674
- background: #DDD;
2675
- display: inline-block;
2676
- width: 16px;
2677
- height: 16px;
2678
- text-align: center;
2679
- line-height: 16px;
2680
- color: #FFF;
2681
- font-size: 16px;
2682
- vertical-align: middle;
2683
- margin-right: 5px;
2684
- content: '';
2685
- }
2686
- .lp-course-attributes.course-filters .lp-course-attribute-values li:hover a:before {
2687
- background: #4acfff;
2688
- }
2689
- .lp-course-attributes.course-filters .lp-course-attribute-values li.active a:before {
2690
- content: "\f147";
2691
- background: #4acfff;
2692
- }
2693
- .lp-course-attributes.course-filters .lp-course-attribute-values li.active:hover a:before {
2694
- content: "\f335";
2695
- background: #a20000;
2696
  }
2697
  @-moz-keyframes spin-12 {
2698
  0% {
@@ -2814,17 +2493,11 @@ body.content-item-only #learn-press-content-item.expand {
2814
  margin-left: 0;
2815
  }
2816
  }
2817
- /*
2818
  @media (max-width: 480px) {
2819
- .woocommerce {
2820
- .checkout_coupon {
2821
- .form-row {
2822
- width: 100%;
2823
- }
2824
- }
2825
- }
2826
- }
2827
- */
2828
  @media (max-width: 400px) {
2829
  .learn-press-courses li.course {
2830
  width: 100%;
@@ -2846,35 +2519,29 @@ body.content-item-only #learn-press-content-item.expand {
2846
  display: none;
2847
  }
2848
  }
2849
- /*
2850
  @media screen and (max-width: 615px) {
2851
- .payment-method-form {
2852
- &.payment_method_authorizenet {
2853
- .row-fluid {
2854
- padding-bottom: 15px;
2855
- .span6 {
2856
- &:first-child {
2857
- width: 100%;
2858
- margin-bottom: 15px;
2859
- }
2860
- label {
2861
- margin-left: 17px;
2862
- }
2863
- select, input {
2864
- margin-left: 10px;
2865
- }
2866
- select, input {
2867
- padding: 8px 0;
2868
- }
2869
- select.required {
2870
- color: #000;
2871
- }
2872
- #learn-press-authorizenet-payment-expmonth {
2873
- margin-bottom: 10px;
2874
- }
2875
- }
2876
- }
2877
- }
2878
- }
2879
- }
2880
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  @font-face {
2
  font-family: 'lp-icons';
3
  src: url('../fonts/lp-icons.eot?f41nl');
153
  .learn-press-courses li.course .course-info > * {
154
  display: block;
155
  }
 
 
 
 
 
 
 
156
  .learn-press-notice .button {
157
  float: right;
158
  }
159
  .learn-press-form {
160
  margin-bottom: 20px;
161
  }
 
162
  #learn-press-course-curriculum ul.curriculum-sections,
163
  #learn-press-course-curriculum ul.section-content {
164
  list-style: none;
210
  border-radius: 5px;
211
  vertical-align: middle;
212
  margin-left: 5px;
 
213
  }
214
  #learn-press-course-curriculum .section-header .meta .collapse:before {
215
  content: "\ea0b";
253
  #learn-press-course-curriculum .course-item .lp-icon {
254
  display: none;
255
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  #learn-press-course-curriculum .course-item.viewable {
257
  cursor: pointer;
258
  }
284
  height: 100%;
285
  content: '';
286
  }
287
+ #learn-press-course-curriculum .course-item.item-has-status .item-status {
288
+ display: inline-block;
289
+ background: #d6d6d6;
290
+ margin-left: 5px;
291
+ }
292
+ #learn-press-course-curriculum .course-item.item-has-status .item-status:before {
293
+ content: '\ea10';
294
+ color: #FFF;
295
+ }
296
+ #learn-press-course-curriculum .course-item.item-has-status.item-completed .item-status {
297
+ background: #95e6f9;
298
+ }
299
  #learn-press-course-curriculum .course-item.focus {
300
  background: #ffb710;
301
  }
315
  #learn-press-course-curriculum .course-item-meta {
316
  display: block;
317
  line-height: 1;
318
+ __position: absolute;
319
  top: 15px;
320
  right: 15px;
321
  float: right;
322
  margin-top: 5px;
323
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  .lp-icon {
325
  display: inline-block;
326
  font-family: 'lp-icons';
442
  .single-lp_course .learn-press-course-results-progress .percentage-sign {
443
  margin-left: 5px;
444
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  .single-lp_course .learn-press-course-results-progress:after {
446
  display: block;
447
  content: '';
542
  .learn-press-tabs .learn-press-tab-panel.active {
543
  display: block;
544
  }
545
+ /* POPUP */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
546
  #popup_overlay {
547
  z-index: 10000000 !important;
548
  }
790
  height: 43px;
791
  line-height: 43px;
792
  background: #F5F5F5;
793
+ margin: 0 10px;
794
  border: 1px solid #DDD;
795
  outline: none;
796
  }
911
  .quiz-intro {
912
  list-style: none;
913
  padding: 0;
 
 
 
 
914
  }
915
  .quiz-questions-list {
916
  margin: 0 0 20px 0;
922
  }
923
  .quiz-questions-list .question-title {
924
  margin: 0 0 5px 0;
 
 
925
  }
926
  .quiz-questions-list .current .question-title {
927
  font-weight: bold;
928
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
929
  .quiz-description .learn-press-question-title,
930
  .question-content .learn-press-question-title {
931
  margin-bottom: 20px;
1796
  .learn-press-message {
1797
  background: #F5F5F5;
1798
  border-left: 5px solid #00A0D2;
1799
+ padding: 10px 20px 10px 20px;
1800
  margin-bottom: 20px;
 
1801
  }
1802
  .learn-press-message button {
1803
  float: right;
2213
  #popup_container #popup_panel {
2214
  text-align: center;
2215
  }
 
 
 
 
 
 
2216
  .single-lp_course .course-summary .lp_course .entry-footer {
2217
  display: none;
2218
  }
2219
  .single-lp_course .learn-press-message {
 
2220
  clear: both;
2221
  margin-top: 25px;
2222
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2223
  /* tooltip */
2224
  .learn-press-tooltip-bubble {
2225
  position: absolute;
2282
  content: '-';
2283
  }
2284
  /*
2285
+ .sidebar-hide-btn, .sidebar-show-btn {
2286
+ cursor: pointer;
2287
+ width: 60px;
2288
+ height: 60px;
2289
+ display: inline-block;
2290
+ font-size: 34px;
2291
+ line-height: 60px;
2292
+ text-align: center;
2293
+ color: #FFF;
2294
+ position: absolute;
2295
+
2296
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2297
  }*/
2298
+ .payment-method-form.payment_method_authorizenet {
2299
+ background: #f7f7f7;
2300
+ border-radius: 5px;
2301
+ -webkit-border-radius: 5px;
2302
+ -moz-border-radius: 5px;
2303
+ padding-top: 25px;
2304
+ }
2305
+ .payment-method-form.payment_method_authorizenet .row-fluid {
2306
+ clear: both;
2307
+ padding-bottom: 25px;
2308
+ }
2309
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6:first-child {
2310
+ width: 50%;
2311
+ float: left;
2312
+ }
2313
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6:first-child label {
2314
+ margin-left: 17px;
2315
+ }
2316
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6:first-child select,
2317
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6:first-child input {
2318
+ margin-left: 10px;
2319
+ }
2320
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6 select,
2321
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6 input {
2322
+ padding: 8px 0;
2323
+ }
2324
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6 select.required {
2325
+ color: #000;
2326
+ }
2327
  .place-order-action {
2328
  margin-top: 20px;
2329
  }
2347
  z-index: 10;
2348
  position: relative;
2349
  }
 
 
 
2350
  /* Shortcode/Widgets */
2351
+ .recent-courses-widget .course-meta-data > div,
2352
+ .popular-courses-widget .course-meta-data > div,
2353
+ .featured-courses-widget .course-meta-data > div {
2354
  display: inline-block;
2355
  }
2356
+ .recent-courses-widget .course-meta-data > div:after,
2357
+ .popular-courses-widget .course-meta-data > div:after,
2358
+ .featured-courses-widget .course-meta-data > div:after {
2359
  content: '/';
2360
  }
2361
+ .recent-courses-widget .course-meta-data > div:last-child:after,
2362
+ .popular-courses-widget .course-meta-data > div:last-child:after,
2363
+ .featured-courses-widget .course-meta-data > div:last-child:after {
2364
  content: '';
2365
  }
2366
+ .recent-courses-widget .course-title,
2367
+ .popular-courses-widget .course-title,
2368
+ .featured-courses-widget .course-title {
2369
  margin: 5px 0;
2370
  }
2371
+ .recent-courses-widget .course-entry,
2372
+ .popular-courses-widget .course-entry,
2373
+ .featured-courses-widget .course-entry {
2374
  margin-bottom: 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2375
  }
2376
  @-moz-keyframes spin-12 {
2377
  0% {
2493
  margin-left: 0;
2494
  }
2495
  }
 
2496
  @media (max-width: 480px) {
2497
+ .woocommerce .checkout_coupon .form-row {
2498
+ width: 100%;
2499
+ }
2500
+ }
 
 
 
 
 
2501
  @media (max-width: 400px) {
2502
  .learn-press-courses li.course {
2503
  width: 100%;
2519
  display: none;
2520
  }
2521
  }
 
2522
  @media screen and (max-width: 615px) {
2523
+ .payment-method-form.payment_method_authorizenet .row-fluid {
2524
+ padding-bottom: 15px;
2525
+ }
2526
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6:first-child {
2527
+ width: 100%;
2528
+ margin-bottom: 15px;
2529
+ }
2530
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6 label {
2531
+ margin-left: 17px;
2532
+ }
2533
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6 select,
2534
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6 input {
2535
+ margin-left: 10px;
2536
+ }
2537
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6 select,
2538
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6 input {
2539
+ padding: 8px 0;
2540
+ }
2541
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6 select.required {
2542
+ color: #000;
2543
+ }
2544
+ .payment-method-form.payment_method_authorizenet .row-fluid .span6 #learn-press-authorizenet-payment-expmonth {
2545
+ margin-bottom: 10px;
2546
+ }
2547
+ }
 
 
 
 
 
assets/css/learnpress.less CHANGED
@@ -1,2532 +1,2152 @@
1
- /*
2
- - PROGRESS CIRCLE
3
- - Archive courses
4
- - Course Curriculum
5
- - BREADCRUMB
6
- - COURSE PROGRESS
7
- - COURSE TABS
8
- - POPUP STYLE
9
- - COURSE QUIZ
10
- - Form field
11
- - jAlerts
12
- - tooltip
13
- - fill in blank
14
- - Shortcode/Widgets
15
- */
16
-
17
- @icon-url: '../fonts/lp-icons';
18
- @font-face {
19
- font-family: 'lp-icons';
20
- src: url('@{icon-url}.eot?f41nl');
21
- src: url('@{icon-url}.eot?f41nl#iefix') format('embedded-opentype'),
22
- url('@{icon-url}.ttf?f41nl') format('truetype'),
23
- url('@{icon-url}.woff?f41nl') format('woff'),
24
- url('@{icon-url}.svg?f41nl#lp-icons') format('svg');
25
- font-weight: normal;
26
- font-style: normal;
27
- }
28
-
29
- [class^="lp-icon-"], [class*=" lp-icon-"] {
30
- /* use !important to prevent issues with browser extensions that change fonts */
31
- font-family: 'lp-icons' !important;
32
- speak: none;
33
- font-style: normal;
34
- font-weight: normal;
35
- font-variant: normal;
36
- text-transform: none;
37
- line-height: 1;
38
-
39
- /* Better Font Rendering =========== */
40
- -webkit-font-smoothing: antialiased;
41
- -moz-osx-font-smoothing: grayscale;
42
- }
43
-
44
- .lp-icon-file-text2:before {
45
- content: "\e926";
46
- }
47
-
48
- .lp-icon-file-picture:before {
49
- content: "\e927";
50
- }
51
-
52
- .lp-icon-file-music:before {
53
- content: "\e928";
54
- }
55
-
56
- .lp-icon-file-video:before {
57
- content: "\e92a";
58
- }
59
-
60
- .lp-icon-file-zip:before {
61
- content: "\e92b";
62
- }
63
-
64
- .lp-icon-paste:before {
65
- content: "\e92d";
66
- }
67
-
68
- .lp-icon-alarm:before {
69
- content: "\e950";
70
- }
71
-
72
- .lp-icon-cross:before {
73
- content: "\ea0f";
74
- }
75
-
76
- .lp-icon-checkmark:before {
77
- content: "\ea10";
78
- }
79
-
80
- .lp-icon-spinner2:before {
81
- content: "\e97b";
82
- }
83
-
84
- .lp-icon-plus:before {
85
- content: "\ea0a";
86
- }
87
-
88
- .lp-icon-minus:before {
89
- content: "\ea0b";
90
- }
91
-
92
- .clearfix() {
93
- display: block;
94
- content: '';
95
- clear: both;
96
- }
97
-
98
- .clearfix:after {
99
- display: block;
100
- content: '';
101
- clear: both;
102
- }
103
-
104
- .border-radius(@args) {
105
- -webkit-border-radius: @arguments;
106
- -khtml-border-radius: @arguments;
107
- -moz-border-radius: @arguments;
108
- -ms-border-radius: @arguments;
109
- -o-border-radius: @arguments;
110
- border-radius: @arguments;
111
- }
112
-
113
- .transform(@args) {
114
- -webkit-transform: @arguments;
115
- -khtml-transform: @arguments;
116
- -moz-transform: @arguments;
117
- -ms-transform: @arguments;
118
- -o-transform: @arguments;
119
- transform: @arguments;
120
- }
121
-
122
- .transition(@args) {
123
- -webkit-transition: @arguments;
124
- -khtml-transition: @arguments;
125
- -moz-transition: @arguments;
126
- -ms-transition: @arguments;
127
- -o-transition: @arguments;
128
- transition: @arguments;
129
- }
130
-
131
- .cross(@size: 30px, @border: 3px, @color: #000) {
132
- &:before,
133
- &:after {
134
- width: @border;
135
- background: @color;
136
- height: @size;
137
- content: '';
138
- display: inline-block;
139
- position: absolute;
140
- top: 0;
141
- left: (@size - @border) / 2;
142
- }
143
- &:before {
144
- .transform(rotate(-45deg));
145
- }
146
- &:after {
147
- .transform(rotate(45deg));
148
- }
149
- }
150
-
151
- .animation(@args) {
152
- -webkit-animation: @arguments;
153
- -moz-animation: @arguments;
154
- animation: @arguments;
155
- }
156
-
157
- .overlay-processing {
158
- &:before, &:after {
159
- content: '';
160
- display: block;
161
- position: fixed;
162
- top: 0;
163
- left: 0;
164
- width: 100%;
165
- height: 100%;
166
- z-index: 999999;
167
- }
168
- &:before {
169
- background: #000;
170
- opacity: 0.5;
171
- }
172
- &:after {
173
- background: #FFF;
174
- }
175
- }
176
-
177
- /* PROGRESS CIRCLE */
178
- .progress-circle(@size: 200px, @background: #DDD, @fill: #95e6f9, @initialize: 0, @inside-size: 170px, @inside-background: #FFF) {
179
- .progress-circle {
180
- width: @size;
181
- height: @size;
182
- border-radius: 50%;
183
- background-color: @background;
184
- position: relative;
185
- .background {
186
- content: "";
187
- position: absolute;
188
- border-radius: 50%;
189
- width: @size;
190
- height: @size;
191
- clip: rect(0, @size, @size, @size / 2);
192
- .fill {
193
- content: "";
194
- position: absolute;
195
- border-radius: 50%;
196
- width: @size;
197
- height: @size;
198
- clip: rect(0, @size / 2, @size, 0);
199
- background: @fill;
200
- transform: rotate(unit(@initialize*3.6, deg));
201
- }
202
- }
203
- &:after {
204
- content: '';
205
- width: @inside-size;
206
- height: @inside-size;
207
- background: @inside-background;
208
- .border-radius(50%);
209
- position: absolute;
210
- top: 50%;
211
- left: 50%;
212
- margin-top: -@inside-size / 2;
213
- margin-left: -@inside-size / 2;
214
- pointer-events: none;
215
- }
216
- .inside {
217
- position: absolute;
218
- width: 100%;
219
- height: 100%;
220
- line-height: @size;
221
- text-align: center;
222
- z-index: 10;
223
- }
224
- &.gt-50 {
225
- background-color: @fill;
226
- .background {
227
- clip: rect(0, @size/2, @size, 0);
228
- }
229
- .fill {
230
- clip: rect(0, @size, @size, @size/2);
231
- background: @background;
232
- }
233
- }
234
- }
235
- }
236
-
237
- .clearfix() {
238
- &:after {
239
- content: '';
240
- display: block;
241
- clear: both;
242
- }
243
- }
244
-
245
- .hide-if-js {
246
- display: none !important;
247
- }
248
-
249
- /* Archive courses */
250
- .learn-press-courses {
251
- list-style: none;
252
- clear: both;
253
- margin: 0 -30px 0 0;
254
- padding: 0;
255
- &:after {
256
- display: block;
257
- content: '';
258
- clear: both;
259
- }
260
- li.course {
261
- list-style-type: none;
262
- float: left;
263
- width: 23%;
264
- margin: 0 2% 30px 0;
265
- padding: 0;
266
- box-sizing: border-box;
267
- border: 1px solid #DDD;
268
- background: #FFF;
269
-
270
- .view-more {
271
- padding: 0 15px;
272
- text-decoration: none;
273
- box-shadow: none;
274
- }
275
-
276
- h3 {
277
- padding: 15px;
278
- margin: 0;
279
- font-size: 18px;
280
- line-height: 1.5;
281
- }
282
- .course-thumbnail {
283
- position: relative;
284
- img {
285
- max-width: 100%;
286
- height: auto;
287
- }
288
- &:after {
289
- content: '';
290
- position: absolute;
291
- width: 100%;
292
- height: 100%;
293
- left: 0;
294
- top: 0;
295
- }
296
- }
297
- .course-info {
298
- padding: 0 15px 15px;
299
- font-size: 14px;
300
- overflow: hidden;
301
- }
302
- .course-students {
303
- float: left;
304
- }
305
- .course-instructor {
306
- margin-bottom: 20px;
307
- }
308
- .course-origin-price {
309
- float: right;
310
- text-decoration: line-through;
311
- padding-right: 5px;
312
- }
313
- .course-price {
314
- float: right;
315
- color: rgb(84, 181, 81);
316
- }
317
- .course-info > * {
318
- display: block;
319
- }
320
- }
321
- }
322
-
323
- .course-origin-price {
324
- text-decoration: line-through;
325
- padding-right: 5px;
326
- }
327
-
328
- .course-price {
329
- color: rgb(84, 181, 81);
330
- }
331
-
332
- .learn-press-notice .button {
333
- float: right;
334
- }
335
-
336
- .learn-press-form {
337
- margin-bottom: 20px;
338
- }
339
-
340
- /* Course Curriculum */
341
-
342
- #learn-press-course-curriculum {
343
- ul.curriculum-sections,
344
- ul.section-content {
345
- list-style: none;
346
- margin: 0;
347
- padding: 0;
348
- background-color: #F5F5F5;
349
- li.section {
350
- list-style-type: none;
351
- }
352
- }
353
- .section-header {
354
- background-color: #EEE;
355
- margin: 0;
356
- padding: 20px 15px;
357
- border-top: 1px solid #FFF;
358
- position: relative;
359
- p {
360
- display: inline-block;
361
- font-weight: normal;
362
- font-style: italic;
363
- color: rgb(153, 153, 153);
364
- font-size: 14px;
365
- margin: 0;
366
- padding: 10px 0;
367
- text-transform: none;
368
- }
369
- &:hover {
370
- background: #DDD;
371
- }
372
- .meta {
373
- font-size: smaller;
374
- font-weight: normal;
375
- position: absolute;
376
- right: 15px;
377
- top: 20px;
378
- .collapse {
379
- display: inline-block;
380
- position: relative;
381
- font-family: 'lp-icons';
382
- background: #95e6f9;
383
- width: 24px;
384
- height: 24px;
385
- line-height: 24px;
386
- text-align: center;
387
- color: #FFF;
388
- border-radius: 5px;
389
- vertical-align: middle;
390
- margin-left: 5px;
391
- font-size: 10px;
392
- &:before {
393
- content: "\ea0b";
394
- margin: 0 auto;
395
- }
396
- &:hover {
397
- cursor: pointer;
398
- }
399
- &.plus {
400
- &:before {
401
- content: "\ea0a";
402
- }
403
- }
404
- }
405
- }
406
- }
407
- .course-item {
408
- margin: 0;
409
- list-style: none;
410
- padding: 10px 15px;
411
- border-top: 1px solid rgb(255, 255, 255);
412
- position: relative;
413
- .transition(background linear 0.5s);
414
- .lp-label-viewing,
415
- .lp-label-completed {
416
- display: none;
417
- }
418
- .course-item-title {
419
- display: block;
420
- box-shadow: none;
421
- text-align: justify;
422
- float: left;
423
- &:before {
424
- display: inline-block;
425
- font-size: 16px;
426
- margin-right: 10px;
427
- font-family: 'lp-icons';
428
- }
429
- }
430
- .lp-icon {
431
- display: none;
432
- }
433
- .item-status {
434
- display: none;
435
- font-family: dashicons;
436
- .border-radius(4px);
437
- background: #DDD;
438
- color: #22b4ff;
439
- font-size: 18px;
440
- &:before {
441
- content: "\f177";
442
- }
443
- &.item-status-viewed {
444
-
445
- }
446
- &.item-status-started {
447
- &:before {
448
- content: "\f469";
449
- }
450
- }
451
- &.item-status-completed {
452
- background: #22b4ff;
453
- color: #FFF;
454
- &:before {
455
- content: "\f147";
456
- }
457
- }
458
- &.item-status-passed {
459
- background: #22b4ff;
460
- color: #FFF;
461
- &:before {
462
- content: "\f147";
463
- }
464
- }
465
- &.item-status-failed {
466
- background: #cc540d;
467
- color: #FFF;
468
- &:before {
469
- content: "\f335";
470
- }
471
- }
472
- }
473
- .item-result {
474
- display: none;
475
- }
476
- &.item-has-status {
477
- .item-status {
478
- display: inline-block;
479
- }
480
- }
481
- &.item-has-result {
482
- .item-result {
483
- display: inline-block;
484
- }
485
- }
486
- &.viewable {
487
- cursor: pointer;
488
- &:hover {
489
- background: #e7ecfb;
490
- .transition(background linear 0s);
491
- }
492
- }
493
- &.course-lesson {
494
- .course-item-title {
495
- &:before {
496
- content: '\e926';
497
- }
498
- }
499
- }
500
- &.course-quiz {
501
- .course-item-title {
502
- &:before {
503
- content: '\e950';
504
- }
505
- }
506
- }
507
- &.item-current {
508
- background: #FFF;
509
- &:before {
510
- display: block;
511
- width: 3px;
512
- background: #95e6f9;
513
- position: absolute;
514
- left: 0;
515
- top: 0;
516
- height: 100%;
517
- content: '';
518
- }
519
- }
520
-
521
- &.focus {
522
- background: #ffb710;
523
- &.off {
524
- .transition(none);
525
- }
526
- }
527
- &:after {
528
- display: block;
529
- clear: both;
530
- content: '';
531
- }
532
- }
533
-
534
- .course-item-meta {
535
- display: block;
536
- line-height: 1;
537
- top: 15px;
538
- right: 15px;
539
- float: right;
540
- margin-top: 5px;
541
- .item-loop-meta-text {
542
- font-size: small;
543
- &.item-final {
544
- color: #ffffff;
545
- background: #cc540d;
546
- padding: 3px 8px;
547
- .border-radius(3px);
548
- }
549
- }
550
- }
551
- }
552
-
553
- .lp-icon {
554
- display: inline-block;
555
- font-family: 'lp-icons';
556
- background: #95e6f9;
557
- width: 24px;
558
- height: 24px;
559
- line-height: 24px;
560
- text-align: center;
561
- color: #FFF;
562
- border-radius: 5px;
563
- vertical-align: middle;
564
- &:before {
565
- width: 32px;
566
- height: 32px;
567
- }
568
-
569
- }
570
-
571
- .lp-label {
572
- display: inline-block;
573
- line-height: 24px;
574
- font-size: 78%;
575
- vertical-align: middle;
576
- color: #ffffff;
577
- padding: 0 10px;
578
- background: #DDD;
579
- height: 24px;
580
- .border-radius(4px);
581
- &.lp-label-viewing {
582
- background-color: rgb(57, 175, 255);
583
- }
584
- &.lp-label-completed {
585
- background-color: #39c7ce;
586
- }
587
- &.lp-label-lesson {
588
- background-color: #337ab7;
589
- }
590
- &.lp-label-quiz {
591
- background-color: #53658c;
592
- }
593
- &.lp-label-preview {
594
- background-color: #02a7ce;
595
- }
596
- }
597
-
598
- .learn-press-content-protected-message {
599
- border: 3px solid #ff8484;
600
- background: #FFF;
601
- padding: 20px;
602
- color: #ff8484;
603
- margin: 10px 0;
604
- border-radius: 6px;
605
- .icon {
606
- position: relative;
607
- display: inline-block;
608
- width: 30px;
609
- height: 30px;
610
- margin-right: 10px;
611
- vertical-align: middle;
612
- .cross(30px, 3px, #ff8484);
613
- }
614
- }
615
-
616
- /** BREADCRUMB */
617
- .learn-press-breadcrumb {
618
- margin-bottom: 20px;
619
- }
620
-
621
- /** COURSE PROGRESS **/
622
- .single-lp_course {
623
- .learn-press-course-results-progress {
624
- margin-bottom: 40px;
625
- .items-progress {
626
- float: left;
627
- width: 68%;
628
- margin-right: 2%;
629
- clear: left;
630
- }
631
- .lp-course-progress-heading {
632
- margin-bottom: 10px;
633
- }
634
- .course-progress {
635
- float: left;
636
- width: 30%;
637
- }
638
- .number, .percentage-sign {
639
- display: inline-block;
640
- vertical-align: bottom;
641
- line-height: 1;
642
- font-size: 25px;
643
- }
644
- .percentage-sign {
645
- margin-left: 5px;
646
- }
647
- .grade {
648
- font-size: 12px;
649
- font-weight: bold;
650
- background: #F5F5F5;
651
- padding: 2px 7px;
652
- .border-radius(3px);
653
- &.in-progress {
654
-
655
- }
656
- &.passed {
657
- color: #ffffff;
658
- background: #95e6f9;
659
- }
660
- &.failed {
661
- color: #ffffff;
662
- background: #ff5425;
663
- }
664
- }
665
- &:after {
666
- display: block;
667
- content: '';
668
- clear: both;
669
- }
670
- }
671
- }
672
-
673
- .lp-course-progress {
674
- position: relative;
675
- .lp-progress-bar {
676
- height: 15px;
677
- background: #DDD;
678
- margin: 10px 0 15px 0;
679
- overflow: hidden;
680
- .border-radius(3px);
681
- .lp-progress-value {
682
- width: 50%;
683
- height: 15px;
684
- background: #95e6f9;
685
- }
686
- }
687
- .lp-passing-conditional {
688
- left: 0%;
689
- position: absolute;
690
- height: 25px;
691
- top: -5px;
692
- margin-left: -5px;
693
- cursor: pointer;
694
- &:before,
695
- &:after {
696
- content: '';
697
- display: inline-block;
698
- border: 5px solid transparent;
699
- left: 0;
700
- position: absolute;
701
- }
702
- &:before {
703
- border-top-color: #DDD;
704
- }
705
- &:after {
706
- border-bottom-color: #DDD;
707
- bottom: 0;
708
- }
709
- }
710
- }
711
-
712
- #learn-press-content-item {
713
- border: 1px solid #DDD;
714
- display: none;
715
-
716
- }
717
-
718
- /** COURSE TABS **/
719
- .learn-press-tabs {
720
- .learn-press-nav-tabs {
721
- list-style: none;
722
- padding: 0;
723
- margin: 0 0 20px 0;
724
- border-bottom: 1px solid #DDD;
725
- .learn-press-nav-tab {
726
- list-style-type: none;
727
- float: left;
728
- margin-bottom: -1px;
729
- position: relative;
730
- a {
731
- display: inline-block;
732
- padding: 10px 15px;
733
- outline: none;
734
- box-shadow: none;
735
- color: #686868;
736
- border-bottom: 1px solid #DDD;
737
- }
738
- &.active {
739
- border-bottom: 4px solid #007acc;
740
- a {
741
- color: #007acc;
742
- border-bottom: none;
743
- margin-bottom: -4px;
744
- }
745
- }
746
- &.active:after {
747
- position: absolute;
748
- width: 100%;
749
- border-bottom: 1px solid #FFF;
750
- bottom: -1px;
751
- content: '';
752
- }
753
- }
754
- &:hover {
755
-
756
- }
757
- &:after {
758
- content: '';
759
- display: block;
760
- clear: both;
761
- }
762
- }
763
- .learn-press-tab-panel {
764
- display: none;
765
- margin-bottom: 20px;
766
- &.active {
767
- display: block;
768
- }
769
- }
770
- }
771
-
772
- .learn-press-block-content-mixin(@w) {
773
- &:before {
774
- width: (@w);
775
- height: (@w);
776
- margin-left: -(@w/2);
777
- margin-top: -(@w/2); /*-76px;*/
778
- -webkit-clip-path: polygon(0px @w, @w @w, @w @w/2, @w/2 @w/2, @w/2 0, 0 0);
779
- }
780
-
781
- span {
782
- clip: rect(0, @w+4, @w/2+2, @w/2+2);
783
- width: @w+4;
784
- height: @w+4;
785
- margin-left: -(@w/2+2);
786
- margin-top: -(@w/2+2);
787
- &:before {
788
- width: @w+4;
789
- height: @w+4;
790
- }
791
- }
792
- }
793
-
794
- .learn-press-course-buttons {
795
-
796
- a.button {
797
- display: inline-block;
798
- font-size: 16px;
799
- background: #1a1a1a;
800
- border: 0;
801
- border-radius: 2px;
802
- color: #fff;
803
- font-family: Montserrat, "Helvetica Neue", sans-serif;
804
- font-weight: 700;
805
- letter-spacing: 0.046875em;
806
- line-height: 1;
807
- padding: 0.84375em 0.875em 0.78125em;
808
- text-transform: uppercase;
809
-
810
- &:hover {
811
- background: #007acc;
812
- }
813
- }
814
- }
815
-
816
- /* POPUP STYLE */
817
-
818
- #popup_overlay {
819
- z-index: 10000000 !important;
820
- }
821
-
822
- #popup_container {
823
- z-index: 10000001 !important;
824
- }
825
-
826
- body.course-has-popup {
827
- overflow: hidden;
828
- }
829
-
830
- #course-curriculum-popup {
831
- position: fixed;
832
- top: 0;
833
- left: 0;
834
- right: 0;
835
- bottom: 0;
836
- background: #000;
837
- z-index: 999999;
838
- * {
839
- box-sizing: border-box;
840
- }
841
- #popup-sidebar {
842
- float: left;
843
- width: 350px;
844
- position: absolute;
845
- top: 60px;
846
- bottom: 0;
847
- overflow: auto;
848
- background: #FFF;
849
- border-right: 1px solid #DDD;
850
- .course-curriculum-title {
851
- display: none;
852
- }
853
- .curriculum-sections {
854
- margin: 0;
855
- font-size: smaller;
856
- }
857
- .learn-press-course-results-progress {
858
- padding: 15px 20px;
859
- margin-bottom: 0;
860
- .items-progress, .course-progress {
861
- width: 100%;
862
- margin: 0 !important;
863
- }
864
- }
865
- }
866
- #popup-main {
867
- position: absolute;
868
- top: 0;
869
- left: 350px;
870
- right: 0;
871
- bottom: 0;
872
- background: #FFF;
873
- #popup-header {
874
- position: absolute;
875
- top: 0;
876
- left: -350px;
877
- right: 0;
878
- height: 60px;
879
- background: #cc540d;
880
- border-bottom: 1px solid #ab4a10;
881
- .popup-menu {
882
- position: absolute;
883
- height: 60px;
884
- width: 350px;
885
- border-right: 1px solid #ab4a10;
886
- }
887
- .popup-close,
888
- .sidebar-hide-btn,
889
- .sidebar-show-btn {
890
- width: 59px;
891
- height: 59px;
892
- position: absolute;
893
- top: 0;
894
- cursor: pointer;
895
- font-size: 34px;
896
- line-height: 60px;
897
- text-align: center;
898
- color: #FFF;
899
- &:hover {
900
- background: #b34c10;
901
- }
902
- }
903
- .sidebar-hide-btn {
904
- left: 0;
905
- }
906
- .sidebar-show-btn {
907
- position: relative;
908
- margin-left: -20px;
909
- margin-right: 20px;
910
- }
911
- .popup-close {
912
- right: 0px;
913
- &:before,
914
- &:after {
915
- content: '';
916
- border-top: 3px solid #FFF;
917
- width: 30px;
918
- display: inline-block;
919
- position: absolute;
920
- top: 29px;
921
- left: 17px;
922
- }
923
- &:before {
924
- -webkit-transform: rotate(45deg);
925
- }
926
- &:after {
927
- -webkit-transform: rotate(-45deg);
928
- }
929
- &:hover {
930
- background: #b34c10;
931
- &:before, &:after {
932
- border-color: #FFF;
933
- }
934
- }
935
- }
936
- .popup-title {
937
- margin: 0 0 0 350px;
938
- height: 60px;
939
- line-height: 60px;
940
- padding: 0 20px;
941
- color: #FFF;
942
- position: relative;
943
- }
944
-
945
- }
946
- #popup-content {
947
- position: absolute;
948
- top: 60px;
949
- bottom: 50px;
950
- left: 0;
951
- right: 0;
952
- overflow: auto;
953
- transition: top linear 0.25s, bottom linear 0.25s;
954
-
955
- #popup-content-inner {
956
- margin: 20px 40px;
957
- }
958
- }
959
- #popup-footer {
960
- position: absolute;
961
- bottom: 0;
962
- left: 0;
963
- right: 0;
964
- height: 50px;
965
- background: #F5F5F5;
966
- border-top: 1px solid #DDD;
967
- .footer-control {
968
- display: block;
969
- height: 50px;
970
- line-height: 50px;
971
- padding: 0 20px;
972
- background: #FFF;
973
- &.prev-item {
974
- float: left;
975
- }
976
- &.next-item {
977
- float: right;
978
- }
979
- }
980
- }
981
- #popup-header, #popup-footer {
982
- transition: opacity linear 0.25s;
983
- }
984
- &.expand {
985
- position: fixed;
986
- left: 0;
987
- padding: 0 20%;
988
- top: 0;
989
- bottom: 0;
990
- #popup-header,
991
- #popup-footer {
992
- opacity: 0;
993
- }
994
- #popup-content {
995
- top: 0;
996
- bottom: 0;
997
- }
998
- }
999
- }
1000
- iframe {
1001
- position: absolute;
1002
- top: 0;
1003
- left: 0;
1004
- height: 100%;
1005
- width: 100%;
1006
- border: none;
1007
- margin: 0;
1008
- background: #FFF;
1009
- }
1010
- }
1011
-
1012
- .learn-press-content-item-title {
1013
- margin-bottom: 20px;
1014
- border-bottom: 2px solid #DDD;
1015
- padding-bottom: 20px;
1016
- &.content-item-quiz-title {
1017
- h4 {
1018
- float: left;
1019
- font-size: 24px;
1020
- margin-bottom: 0;
1021
- }
1022
- .quiz-countdown {
1023
- float: right;
1024
- position: relative;
1025
- min-width: 100px;
1026
- background: #F5F5F5;
1027
- text-align: center;
1028
- font-size: 18px;
1029
- &:after, &:before {
1030
- padding: 0 10px;
1031
- height: 3px;
1032
- position: absolute;
1033
- bottom: -3px;
1034
- background: #000;
1035
- content: '';
1036
- left: 0;
1037
- }
1038
- &:before {
1039
- width: 100%;
1040
- }
1041
- &:after {
1042
- background: #00adff;
1043
- padding: 0;
1044
- }
1045
- &.warning-time-over {
1046
- &:after {
1047
- background: #FF0000;
1048
- }
1049
- }
1050
- .countdown {
1051
-
1052
- }
1053
- }
1054
- .clearfix();
1055
- }
1056
- .lp-expand {
1057
- float: right;
1058
- width: 43px;
1059
- height: 43px;
1060
- line-height: 43px;
1061
- background: #F5F5F5;
1062
- margin-left: 10px;
1063
- border: 1px solid #DDD;
1064
- outline: none;
1065
- }
1066
- }
1067
-
1068
- .learn-press-content-item-summary {
1069
- /*padding: 20px;
1070
- border-top: 1px solid #DDD;*/
1071
- margin-bottom: 30px;
1072
- .quiz-question-title {
1073
- margin-bottom: 20px;
1074
- }
1075
- .learn-press-question-explanation, .learn-press-question-hint {
1076
- background: #F5F5F5;
1077
- padding: 15px 20px;
1078
- font-style: italic;
1079
- margin-bottom: 20px;
1080
- .hint-title, .explanation-title {
1081
- font-style: normal;
1082
- }
1083
- }
1084
- }
1085
-
1086
- .button-finish-quiz {
1087
- float: right;
1088
- }
1089
-
1090
- .learnpress form.purchase-course {
1091
- margin-bottom: 20px;
1092
- }
1093
-
1094
- #learn-press-block-content {
1095
- display: none;
1096
- width: 100%;
1097
- height: 100%;
1098
- background: fade(#FFF, 25%);
1099
- position: fixed;
1100
- z-index: 99999999;
1101
- top: 0;
1102
- left: 0;
1103
- &:before, &:after, span {
1104
- position: absolute;
1105
- .border-radius(50%);
1106
- left: 50%;
1107
- top: 50%;
1108
- box-sizing: border-box;
1109
- }
1110
- &:before {
1111
- content: '';
1112
- border: 2px solid #000;
1113
- z-index: 10;
1114
- .animation(spin-13 1.5s infinite);
1115
- }
1116
- &:after {
1117
- z-index: 0;
1118
- content: '';
1119
- border: 10px solid #000000;
1120
- margin-left: -80px;
1121
- margin-top: -80px;
1122
- width: 160px;
1123
- height: 160px;
1124
- opacity: 0;
1125
- }
1126
- span {
1127
- z-index: 20;
1128
- .animation(spin-12 1.5s infinite);
1129
- &:before {
1130
- content: '';
1131
- border: 6px solid #95e6f9;
1132
- position: absolute;
1133
- .border-radius(50%);
1134
- box-sizing: border-box;
1135
- }
1136
- }
1137
-
1138
- .learn-press-block-content-mixin(80px);
1139
- }
1140
-
1141
- body.block-content {
1142
- #learn-press-block-content {
1143
- display: block;
1144
- }
1145
- }
1146
-
1147
- /* COURSE QUIZ */
1148
- .quiz-buttons {
1149
- margin-bottom: 20px;
1150
- clear: both;
1151
- }
1152
-
1153
- .quiz-intro {
1154
- list-style: none;
1155
- padding: 0;
1156
- margin-left: 0;
1157
- li label {
1158
- display: inline-block;
1159
- }
1160
- }
1161
-
1162
- .quiz-questions-list {
1163
- margin: 0 0 20px 0;
1164
- padding: 0;
1165
- list-style-position: inside;
1166
- li {
1167
- margin: 0 0 10px 0;
1168
- }
1169
- .question-title {
1170
- margin: 0 0 5px 0;
1171
- display: inline-block;
1172
- font-size: 14px;
1173
- }
1174
- .current {
1175
- .question-title {
1176
- font-weight: bold;
1177
- }
1178
- }
1179
- input[type="checkbox"], input[type="radio"] {
1180
- border: 1px solid #DDD;
1181
- display: inline-block;
1182
- -webkit-appearance: none;
1183
- width: 18px;
1184
- height: 18px;
1185
- position: relative;
1186
- &:checked {
1187
- &:after {
1188
- content: '';
1189
- display: inline-block;
1190
- position: absolute;
1191
- }
1192
- }
1193
- }
1194
- input[type="checkbox"]:checked {
1195
- &:after {
1196
- border-bottom: 3px solid #00b9eb;
1197
- border-right: 1px solid #00b9eb;
1198
- -webkit-transform: rotate(14deg);
1199
- -moz-transform: rotate(14deg);
1200
- -ms-transform: rotate(14deg);
1201
- -o-transform: rotate(14deg);
1202
- transform: rotate(33deg);
1203
- width: 8px;
1204
- height: 16px;
1205
-
1206
- top: -5px;
1207
- left: 5px;
1208
- }
1209
- }
1210
- input[type="checkbox"] {
1211
- &:disabled {
1212
- &:after {
1213
- border-color: #DDD;
1214
- }
1215
- }
1216
- }
1217
- input[type="radio"] {
1218
- -webkit-border-radius: 50%;
1219
- -moz-border-radius: 50%;
1220
- border-radius: 50%;
1221
- &:checked {
1222
- &:after {
1223
- background: #00b9eb;
1224
- width: 8px;
1225
- height: 8px;
1226
- border-radius: 50%;
1227
- top: 50%;
1228
- left: 50%;
1229
- margin-left: -4px;
1230
- margin-top: -4px;
1231
- }
1232
- }
1233
- &:disabled {
1234
- &:after {
1235
- background: #DDD;
1236
- }
1237
- }
1238
- }
1239
- }
1240
-
1241
- .question-results {
1242
- .question-title {
1243
- &:after {
1244
- font-family: dashicons;
1245
- font-size: 24px;
1246
- vertical-align: middle;
1247
- display: inline-block;
1248
- text-align: center;
1249
- margin-left: 5px;
1250
- }
1251
- }
1252
- &.correct {
1253
- .question-title {
1254
- &:after {
1255
- content: '\f147';
1256
- color: #00adff;
1257
- }
1258
- }
1259
- }
1260
- &.skipped {
1261
- .question-title {
1262
- &:after {
1263
- content: '\f534';
1264
- color: #c6c6c6;
1265
- }
1266
- }
1267
- }
1268
- &.incorrect {
1269
- .question-title {
1270
- &:after {
1271
- content: '\f335';
1272
- color: #ff5425;
1273
- }
1274
- }
1275
- .user-answer-false {
1276
- .option-title {
1277
- text-decoration: line-through;
1278
- }
1279
- }
1280
- }
1281
- .answer-true {
1282
- color: #007acc;
1283
- .option-title {
1284
- background: #fff9d8;
1285
- padding: 0 5px;
1286
- margin-left: -5px;
1287
- }
1288
- }
1289
- input {
1290
- vertical-align: middle;
1291
- }
1292
- }
1293
-
1294
- .quiz-description,
1295
- .question-content {
1296
- .learn-press-question-title {
1297
- margin-bottom: 20px;
1298
- }
1299
- }
1300
-
1301
- .quiz-countdown {
1302
- float: right;
1303
- position: relative;
1304
- min-width: 150px;
1305
- background: #F5F5F5;
1306
- text-align: center;
1307
- font-size: 18px;
1308
- padding: 5px 0;
1309
- }
1310
-
1311
- #quiz-countdown {
1312
- .progress-circle {
1313
- overflow: hidden;
1314
- box-shadow: 0 0 3px #bdbdbd inset;
1315
- .inside {
1316
- line-height: 1;
1317
- .countdown {
1318
- font-size: 48px;
1319
- color: #087998;
1320
- _text-shadow: 1px 1px #8ee5fd;
1321
- margin-top: 110px;
1322
- }
1323
- p {
1324
- margin: 10px 0 0 0;
1325
- color: #DDD;
1326
- }
1327
- }
1328
- &:after {
1329
- background: #00b9eb;
1330
- box-shadow: 0 0 6px #097a98;
1331
- }
1332
- }
1333
- }
1334
-
1335
- #quiz-progress {
1336
- .progress-circle(@size: 200px, @background: #DDD, @fill: #FF0000, @initialize: 0%, @inside-size: 170px, @inside-background: #FFF);
1337
- }
1338
-
1339
- .quiz-result {
1340
- .quiz-result-mark {
1341
- .progress-circle();
1342
- margin-bottom: 20px;
1343
- }
1344
- .quiz-result-summary {
1345
- margin-bottom: 20px;
1346
- max-width: 500px;
1347
- .quiz-result-field {
1348
- position: relative;
1349
- background: #F5F5F5;
1350
- color: #fff;
1351
- margin: 0 0 8px 0;
1352
- font-size: 12px;
1353
- padding: 5px 10px;
1354
- .border-radius(4px);
1355
- overflow: hidden;
1356
-
1357
- span, span:after, &:before {
1358
- display: block;
1359
- position: absolute;
1360
- top: 0;
1361
- left: 0;
1362
- height: 100%;
1363
- content: attr(data-text);
1364
- color: #FFF;
1365
- white-space: nowrap;
1366
- overflow: hidden;
1367
- padding: 3px 10px;
1368
- background: transparent;
1369
- transition: width 0.5s;
1370
- }
1371
- &:before {
1372
- content: '';
1373
- padding: 0;
1374
- }
1375
- span {
1376
- padding: 0;
1377
- }
1378
- span:after {
1379
- margin: 3px 10px;
1380
- padding: 0;
1381
- width: 100%;
1382
- }
1383
- &.correct {
1384
- background: #22b4ff;
1385
- }
1386
- &.wrong {
1387
- background: #ff5425;
1388
- }
1389
- &.empty {
1390
- color: #656D6D;
1391
- }
1392
- }
1393
- }
1394
- p.quiz-result-time {
1395
- margin: 0 0 10px 0;
1396
- }
1397
- .quiz-grade {
1398
- p {
1399
- margin: 0 0 10px 0;
1400
- span {
1401
- font-weight: bold;
1402
- &.passed {
1403
- color: #22b4ff;
1404
- }
1405
- &.failed {
1406
- color: #ff5425;
1407
- }
1408
- }
1409
- }
1410
- }
1411
- }
1412
-
1413
- .element-data-percent-loop (@i) when (@i <= 100) {
1414
- .single-quiz .quiz-result-field[data-value="@{i}"]:before,
1415
- .single-quiz .quiz-result-field[data-value="@{i}"] span,
1416
- #quiz-countdown[data-value="@{i}"]:after {
1417
- width: ~"@{i}%";
1418
- }
1419
- .element-data-percent-loop(@i + 1);
1420
- }
1421
-
1422
- .element-data-percent-loop (0);
1423
-
1424
- /* QUESTION */
1425
- .learn-press-question-options {
1426
- list-style: none;
1427
- margin: 0 0 20px 0;
1428
- padding: 0;
1429
- > li.answer-option {
1430
- font-size: 16px;
1431
- background: #F5F5F5;
1432
- margin-bottom: 20px;
1433
- position: relative;
1434
- .border-radius(4px);
1435
- > label {
1436
- display: block;
1437
- input[type="checkbox"], input[type="radio"] {
1438
- border: 0;
1439
- -webkit-appearance: initial;
1440
- width: 30px;
1441
- height: 30px;
1442
- background: #fff;
1443
- border-radius: 4px;
1444
- outline: none;
1445
- position: absolute;
1446
- top: 10px;
1447
- left: 15px;
1448
- margin: 0;
1449
- &:checked:before {
1450
- content: '';
1451
- border: 4px solid #00b9eb;
1452
- display: inline-block;
1453
- width: 10px;
1454
- height: 15px;
1455
- border-top: none;
1456
- border-left: none;
1457
- position: absolute;
1458
- top: 3px;
1459
- left: 8px;
1460
- box-sizing: content-box;
1461
- .transform(rotate(36deg));
1462
- }
1463
- &:checked + p {
1464
- font-weight: bold;
1465
- background: #00b9eb;
1466
- color: #FFF;
1467
- }
1468
- }
1469
- input[type="checkbox"][disabled], input[type="radio"][disabled] {
1470
- opacity: 1;
1471
- }
1472
- input[type="radio"] {
1473
- .border-radius(50%);
1474
- }
1475
- p {
1476
- min-height: 50px;
1477
- padding: 5px 20px 5px 60px;
1478
- margin: 0;
1479
- box-sizing: border-box;
1480
- line-height: 1.5;
1481
- &.single-lines {
1482
- padding: 0 20px 0 60px;
1483
- line-height: 50px; /* middle */
1484
- }
1485
- }
1486
- }
1487
- label p {
1488
- .border-radius(4px);
1489
- }
1490
- &.answer-true label p {
1491
- background: #00b9eb;
1492
- color: #FFF;
1493
- }
1494
- &:hover label p {
1495
- background: #D4D4D4;
1496
- cursor: pointer;
1497
- }
1498
- &.user-answer-false {
1499
- background: #F5F5F5;
1500
- > label {
1501
- input[type="checkbox"] + p, input[type="radio"] + p {
1502
- text-decoration: line-through;
1503
- color: #FF0000;
1504
- background: #F5F5F5;
1505
- }
1506
- }
1507
- }
1508
- }
1509
- .answer-option-result {
1510
- label {
1511
- p {
1512
- display: inline-block;
1513
- margin: 0;
1514
- font-size: smaller;
1515
- }
1516
- input[disabled] {
1517
- opacity: 1;
1518
- }
1519
- }
1520
- }
1521
- }
1522
-
1523
- .learnpress-content {
1524
- margin-bottom: 20px;
1525
- }
1526
-
1527
- .course-meta {
1528
- margin-bottom: 20px;
1529
- .course-origin-price {
1530
- padding-right: 5px;
1531
- text-decoration: line-through;
1532
- }
1533
- .course-price {
1534
- font-weight: bold;
1535
- }
1536
-
1537
- }
1538
-
1539
- /** MESSAGE */
1540
- .learn-press-message {
1541
- background: #F5F5F5;
1542
- border-left: 5px solid #00A0D2;
1543
- padding: 10px 20px 0px 20px;
1544
- margin-bottom: 20px;
1545
- overflow: hidden;
1546
- button {
1547
- float: right;
1548
- }
1549
- p {
1550
- margin-bottom: 10px;
1551
- }
1552
- &:after {
1553
- clear: both;
1554
- content: '';
1555
- display: block;
1556
- }
1557
- &.notice {
1558
- border-left-color: #b3d20a;
1559
- }
1560
- &.error {
1561
- border-left-color: #b81c23;
1562
- }
1563
- ul {
1564
- list-style-type: none;
1565
- }
1566
- }
1567
-
1568
- /**/
1569
- .learn-press-checkout-comment,
1570
- .learn-press-checkout-payment {
1571
- margin-bottom: 20px;
1572
- }
1573
-
1574
- .learn-press-checkout-payment {
1575
- .payment-methods {
1576
- list-style: none;
1577
- margin: 0;
1578
- }
1579
- }
1580
-
1581
- /* COURSE QUIZ */
1582
- .single-quiz {
1583
- .quiz-questions-list {
1584
- padding: 0;
1585
- }
1586
- .quiz-intro {
1587
- list-style: none;
1588
- padding: 10px 20px;
1589
- background: #F5F5F5;
1590
- margin: 0 0 20px 0;
1591
- }
1592
- h4 {
1593
- margin-bottom: 10px;
1594
- font-size: 18px;
1595
- }
1596
- }
1597
-
1598
- .learn-press-tooltip {
1599
- font-size: 20px;
1600
- display: inline-block;
1601
- vertical-align: middle;
1602
- background: #0f4956;
1603
- cursor: pointer;
1604
- line-height: 1;
1605
- width: 10px;
1606
- height: 10px;
1607
- border-radius: 50%;
1608
- font-weight: 700;
1609
- position: relative;
1610
- &:before {
1611
- content: "?";
1612
- font-size: 7px;
1613
- color: white;
1614
- position: absolute;
1615
- top: 2px;
1616
- left: 3px;
1617
- }
1618
- }
1619
-
1620
- /* Form field */
1621
- .lp-form-field-wrap {
1622
- list-style: none;
1623
- margin: 0 0 20px 0;
1624
- .lp-form-field {
1625
- list-style: none;
1626
- margin: 0 0 20px 0;
1627
- .lp-form-field-label {
1628
- display: block;
1629
- font-weight: bold;
1630
- margin-bottom: 5px;
1631
- }
1632
- .lp-form-field-input .description {
1633
- font-size: smaller;
1634
- font-style: italic;
1635
- margin-top: 5px;
1636
- }
1637
- .lp-field-error-message {
1638
- color: #FF0000;
1639
- }
1640
- }
1641
- }
1642
-
1643
- .learn-press-user-profile {
1644
-
1645
- .lp-edit-profile {
1646
- &:after {
1647
- .clearfix();
1648
- }
1649
- }
1650
- .user-basic-info {
1651
- p {
1652
- margin-top: 10px;
1653
- }
1654
- }
1655
- .learn-press-tabs {
1656
- list-style: none;
1657
- margin: 30px 0 20px;
1658
- border-bottom: 1px solid #DDD;
1659
- & > li {
1660
- float: left;
1661
- list-style-type: none;
1662
- margin-bottom: -1px;
1663
- & > a {
1664
- display: inline-block;
1665
- padding: 10px 15px;
1666
- outline: none;
1667
- box-shadow: none;
1668
- color: #686868;
1669
- border-bottom: 1px solid #DDD;
1670
- }
1671
- &.current {
1672
- border-bottom: 4px solid #007acc;
1673
- a {
1674
- color: #007acc;
1675
- margin-bottom: -4px;
1676
- }
1677
- }
1678
- }
1679
- }
1680
- .learn-press-subtabs {
1681
- & > li {
1682
- display: inline-block;
1683
- margin-right: 10px;
1684
- &.current {
1685
- font-weight: bold;
1686
- }
1687
- }
1688
- }
1689
- .learn-press-subtab-content {
1690
- display: none;
1691
- margin-bottom: 20px;
1692
- &.current {
1693
- display: block;
1694
- }
1695
- li.course {
1696
- h3 {
1697
- padding-bottom: 10px;
1698
- }
1699
- }
1700
- .profile-courses {
1701
- list-style-type: none;
1702
- .learn-press-course-results-progress {
1703
- padding: 0 15px 15px 15px;
1704
- margin: 0;
1705
- }
1706
- }
1707
- }
1708
- button.learn-press-course-wishlist {
1709
- display: block;
1710
- }
1711
-
1712
- .user-profile-edit-form {
1713
-
1714
- .info-field {
1715
- margin-bottom: 20px;
1716
- }
1717
-
1718
- .description {
1719
- margin-top: 5px;
1720
- }
1721
-
1722
- .user-profile-picture {
1723
- clear: both;
1724
- .picture, .change-picture {
1725
- display: inline-block;
1726
- }
1727
- .change-picture {
1728
- .description {
1729
- margin: 0 0 10px 0;
1730
- }
1731
- }
1732
- img {
1733
- float: left;
1734
- margin-right: 20px;
1735
- }
1736
- &:after {
1737
- .clearfix();
1738
- }
1739
- }
1740
-
1741
- .profile-field-name {
1742
- font-weight: bold;
1743
- margin-bottom: 10px;
1744
- }
1745
-
1746
- .change-password {
1747
- margin-bottom: 10px;
1748
- }
1749
-
1750
- #user_profile_password_form {
1751
- input {
1752
- margin-bottom: 20px;
1753
- }
1754
- .description {
1755
- margin-top: -15px;
1756
- }
1757
- }
1758
-
1759
- }
1760
- .update-profile {
1761
- border-top: 2px solid #DDD;
1762
- padding-top: 20px;
1763
- }
1764
- .learn-press-subtab-content {
1765
- display: block;
1766
- }
1767
- #lp-user-edit-avatar {
1768
- .moxie-shim {
1769
- display: none;
1770
- }
1771
- .lp-form-field-avatar {
1772
- float: left;
1773
- }
1774
- #lp-avatar-actions {
1775
- margin: 20px 0;
1776
- }
1777
- }
1778
- .lp-avatar-preview {
1779
- position: relative;
1780
- float: left;
1781
- background-color: #DDD;
1782
- .profile-picture {
1783
- float: left;
1784
- margin-right: -100%;
1785
- width: 100%;
1786
- img {
1787
- width: 100%;
1788
- height: 100%;
1789
- border-radius: 0;
1790
- }
1791
- &.profile-avatar-hidden {
1792
- display: none;
1793
- }
1794
- }
1795
- .lp-avatar-preview-actions {
1796
- position: absolute;
1797
- top: 50%;
1798
- width: 100%;
1799
- margin-top: -14px;
1800
- text-align: center;
1801
- a {
1802
- text-decoration: none;
1803
- font-size: 12px;
1804
- background: #FFF;
1805
- display: inline-block;
1806
- box-shadow: none;
1807
- padding: 5px 10px;
1808
- }
1809
- }
1810
- .lp-avatar-upload-progress {
1811
- position: absolute;
1812
- height: 10px;
1813
- background: #FFF;
1814
- top: 50%;
1815
- margin-top: -5px;
1816
- left: 10px;
1817
- right: 10px;
1818
- display: none;
1819
- .lp-avatar-upload-progress-value {
1820
- width: 0;
1821
- height: 10px;
1822
- background: #563d7c;
1823
- }
1824
- }
1825
- .lp-avatar-upload-error {
1826
- display: none;
1827
- }
1828
- .lp-avatar-preview-actions {
1829
- display: none;
1830
- }
1831
- &:hover {
1832
- .lp-avatar-preview-actions {
1833
- display: block;
1834
- }
1835
- }
1836
- &.uploading, &.upload-error {
1837
- .lp-avatar-preview-actions {
1838
- display: none;
1839
- }
1840
- .lp-avatar-upload-progress {
1841
- display: block;
1842
- }
1843
- &:before {
1844
- position: absolute;
1845
- width: 100%;
1846
- height: 100%;
1847
- background: #FFF;
1848
- opacity: 0.4;
1849
- content: '';
1850
- }
1851
- }
1852
- &.upload-error {
1853
- .lp-avatar-upload-error {
1854
- display: block;
1855
- }
1856
- }
1857
- &.croping {
1858
- .lp-avatar-preview-actions {
1859
- display: none;
1860
- }
1861
- .lp-avatar-crop-image {
1862
- position: absolute;
1863
- top: 0;
1864
- left: 0;
1865
- width: 100%;
1866
- height: 100%;
1867
- background: #000;
1868
- overflow: hidden;
1869
- img {
1870
- max-width: inherit;
1871
- cursor: move;
1872
- }
1873
- .lp-crop-controls {
1874
- position: absolute;
1875
- bottom: 0;
1876
- width: 100%;
1877
- height: 30px;
1878
- .lp-zoom {
1879
- position: absolute;
1880
- height: 10px;
1881
- bottom: 10px;
1882
- left: 10px;
1883
- right: 30px;
1884
- background: #563d7a;
1885
- .ui-slider {
1886
- position: absolute;
1887
- left: 0;
1888
- right: 10px;
1889
- height: 100%;
1890
- .ui-slider-handle {
1891
- display: inline-block;
1892
- width: 10px;
1893
- height: 14px;
1894
- background: #FFF;
1895
- position: absolute;
1896
- margin-top: -2px;
1897
- border: 1px solid #563d7a;
1898
- box-shadow: none;
1899
- outline: none;
1900
- cursor: ew-resize;
1901
- }
1902
- }
1903
- }
1904
- .lp-cancel-upload {
1905
- text-decoration: none;
1906
- position: absolute;
1907
- bottom: 5px;
1908
- right: 5px;
1909
- box-shadow: none;
1910
- }
1911
- &:before {
1912
- position: absolute;
1913
- height: 30px;
1914
- width: 100%;
1915
- content: '';
1916
- background: #FFF;
1917
- opacity: 0.4;
1918
- }
1919
- }
1920
- }
1921
- }
1922
- &:after {
1923
- .clearfix();
1924
- }
1925
- }
1926
- }
1927
-
1928
- body {
1929
- &.profile-dragging {
1930
- cursor: move !important;
1931
- }
1932
- &.profile-resizing {
1933
- cursor: ew-resize !important;
1934
- }
1935
- }
1936
-
1937
- .learn-press-pagination {
1938
- text-align: center;
1939
- ul {
1940
- list-style: disc;
1941
- & > li {
1942
- display: inline-block;
1943
- span {
1944
- display: inline-block;
1945
- padding: 0 10px;
1946
- border: 1px solid #DDD;
1947
- background-color: #F5F5F5;
1948
- }
1949
- a {
1950
- display: inline-block;
1951
- padding: 0 10px;
1952
- border: 1px solid #DDD;
1953
- background-color: #FFF;
1954
- }
1955
- }
1956
- }
1957
- }
1958
-
1959
- .learn-press-become-teacher-form {
1960
- ul {
1961
- list-style: none;
1962
- padding: 0;
1963
- li {
1964
- margin-bottom: 20px;
1965
- }
1966
- }
1967
- }
1968
-
1969
- /* jAlerts */
1970
- #popup_container {
1971
- background: #FFF;
1972
-
1973
- #popup_title {
1974
- padding: 10px 20px;
1975
- background: #18B6C7;
1976
- color: #FFF;
1977
- font-size: 18px;
1978
- margin: 0;
1979
- }
1980
-
1981
- #popup_content {
1982
- padding: 20px;
1983
- #popup_message {
1984
- margin-bottom: 20px;
1985
- }
1986
- }
1987
-
1988
- #popup_panel {
1989
- text-align: center;
1990
- }
1991
- }
1992
-
1993
- .learn-press-auto-redirect-next-item {
1994
- display: none;
1995
-
1996
- &.active {
1997
- display: block;
1998
- }
1999
- }
2000
-
2001
- .single-lp_course {
2002
- .course-summary {
2003
- .lp_course {
2004
- .entry-footer {
2005
- display: none;
2006
- }
2007
- }
2008
- }
2009
- .learn-press-message {
2010
- position: relative;
2011
- clear: both;
2012
- margin-top: 25px;
2013
-
2014
- .learn-press-countdown {
2015
- display: inline-block;
2016
- width: 1.5em;
2017
- height: 1.5em;
2018
- background: #cc540d;
2019
- text-align: center;
2020
- border-radius: 50%;
2021
- line-height: 1.5em;
2022
- font-size: 0.8em;
2023
- color: #fff;
2024
- }
2025
- .learnpress-dismiss-notice {
2026
- display: inline-block;
2027
- position: absolute;
2028
- right: 1em;
2029
- top: 50%;
2030
- -ms-transform: translateY(-50%);
2031
- -webkit-transform: translateY(-50%);
2032
- transform: translateY(-50%);
2033
- cursor: pointer;
2034
-
2035
- &:before {
2036
- font-size: 1.2em;
2037
- color: red;
2038
- content: "\f153";
2039
- font-family: dashicons;
2040
- }
2041
- }
2042
-
2043
- }
2044
-
2045
- }
2046
-
2047
- /* tooltip */
2048
- .learn-press-tooltip-bubble {
2049
- position: absolute;
2050
- background: rgba(26, 26, 26, 0.9);
2051
- color: #ffffff;
2052
- padding: 8px 10px;
2053
- font-size: 12px;
2054
- z-index: 9999999;
2055
- line-height: 1;
2056
- border-radius: 3px;
2057
- }
2058
-
2059
- /* fill in blank */
2060
- input.blank-fill-correct {
2061
- width: auto;
2062
- }
2063
-
2064
- body.content-item-only {
2065
- background: #FFF;
2066
- opacity: 0;
2067
- .learn-press-content-item-only {
2068
- position: fixed;
2069
- z-index: 9999999;
2070
- left: 0;
2071
- top: 0;
2072
- width: 100%;
2073
- height: 100%;
2074
- background: #FFF;
2075
- overflow: auto;
2076
- padding: 20px;
2077
- margin: 0;
2078
- }
2079
-
2080
- #learn-press-content-item {
2081
- border: none;
2082
- display: block;
2083
- transition: max-width linear 0.25s;
2084
- margin: 0 auto;
2085
- max-width: 1000px;
2086
- width: 90%;
2087
- &.expand {
2088
- max-width: 1200px;
2089
- }
2090
- }
2091
- }
2092
-
2093
- .lp-group-heading-title {
2094
- &.toggle-off, &.toggle-on {
2095
- cursor: pointer;
2096
- .toggle-icon {
2097
- display: inline-block;
2098
- font-size: larger;
2099
- line-height: 1;
2100
- font-weight: bold;
2101
- margin-left: 5px;
2102
- &:before {
2103
- content: '+';
2104
- }
2105
- }
2106
- }
2107
- &.toggle-on {
2108
- .toggle-icon {
2109
- &:before {
2110
- content: '-';
2111
- }
2112
- }
2113
- }
2114
- }
2115
-
2116
- /*
2117
- .payment-method-form {
2118
- &.payment_method_authorizenet {
2119
- background: #f7f7f7;
2120
- border-radius: 5px;
2121
- -webkit-border-radius: 5px;
2122
- -moz-border-radius: 5px;
2123
- padding-top: 25px;
2124
- .row-fluid {
2125
- clear: both;
2126
- padding-bottom: 25px;
2127
- .span6 {
2128
- &:first-child {
2129
- width: 50%;
2130
- float: left;
2131
- label {
2132
- margin-left: 17px;
2133
- }
2134
- select, input {
2135
- margin-left: 10px;
2136
- }
2137
- }
2138
- select, input {
2139
- padding: 8px 0;
2140
- }
2141
- select.required {
2142
- color: #000;
2143
- }
2144
- }
2145
- }
2146
- }
2147
- }*/
2148
-
2149
- .place-order-action {
2150
- margin-top: 20px;
2151
- }
2152
-
2153
- .woocommerce {
2154
- form .form-row {
2155
- &.validate-email, &.validate-phone {
2156
- width: 100% !important;
2157
- }
2158
- }
2159
-
2160
- .checkout_coupon {
2161
- .form-row-last {
2162
- input.button {
2163
- padding: 13px 10px !important;
2164
- }
2165
- }
2166
- }
2167
- }
2168
-
2169
- .learn-press-search-course-form {
2170
- margin-bottom: 20px;
2171
- input.search-course-input[name="s"] {
2172
- margin-right: -200px;
2173
- width: 100%;
2174
- }
2175
- .search-course-button {
2176
- vertical-align: middle;
2177
- float: right;
2178
- z-index: 10;
2179
- position: relative;
2180
- }
2181
- }
2182
-
2183
- .table-orders {
2184
- .order-status {
2185
- &.order-status-removed {
2186
- color: #FF0000;
2187
- }
2188
- }
2189
- }
2190
-
2191
- /* Shortcode/Widgets */
2192
- .widget_lp-widget-popular-courses, .widget_lp-widget-recent-courses, .widget_lp-widget-featured-courses {
2193
- .course-meta-data {
2194
- > div {
2195
- display: inline-block;
2196
- &:after {
2197
- content: '/';
2198
- }
2199
- &:last-child:after {
2200
- content: '';
2201
- }
2202
- }
2203
-
2204
- }
2205
- .course-title {
2206
- margin: 5px 0;
2207
- }
2208
- .course-entry {
2209
- margin-bottom: 20px;
2210
- border-bottom: 1px dashed #DDD;
2211
- padding-bottom: 20px;
2212
- }
2213
- }
2214
-
2215
- .edit-course-item-link {
2216
- a {
2217
- font-size: 14px;
2218
- position: relative;
2219
- padding-left: 25px;
2220
- &:after {
2221
- content: "\f464";
2222
- font-family: Dashicons;
2223
- font-size: 26px;
2224
- position: absolute;
2225
- bottom: 0;
2226
- line-height: 1;
2227
- left: 0;
2228
- }
2229
- }
2230
- }
2231
-
2232
- .course-item-navigation {
2233
- border-top: 4px solid #333;
2234
- padding-top: 10px;
2235
- margin-top: 20px;
2236
- .nav-links {
2237
- .nav-link {
2238
- opacity: 1;
2239
- a {
2240
- opacity: 1;
2241
- .meta-nav {
2242
- display: block;
2243
- text-transform: uppercase;
2244
- font-size: small;
2245
- color: #b9b9b9;
2246
- }
2247
- .post-title {
2248
- opacity: 1;
2249
- }
2250
- }
2251
- &.nav-previous {
2252
- float: left;
2253
- }
2254
- &.nav-next {
2255
- float: right;
2256
- text-align: right;
2257
- }
2258
- }
2259
- &:after {
2260
- clear: both;
2261
- display: block;
2262
- content: '';
2263
- }
2264
- }
2265
- }
2266
-
2267
- /* widget attributes */
2268
- .lp-course-attributes {
2269
- list-style: none;
2270
- margin-left: 0;
2271
- li {
2272
- list-style: none;
2273
- margin-bottom: 10px;
2274
- }
2275
- .lp-course-attribute-values {
2276
- list-style: none;
2277
- margin-left: 0;
2278
- }
2279
- &.course-attributes {
2280
- .lp-course-attribute-values {
2281
- li {
2282
- display: inline-block;
2283
- padding: 3px 8px;
2284
- background: #F0F0F0;
2285
- border-radius: 4px;
2286
- margin: 0 5px 5px 0;
2287
- }
2288
- }
2289
- }
2290
- &.course-filters {
2291
- .lp-course-attribute-values {
2292
- li {
2293
- a:before {
2294
- font-family: dashicons;
2295
- border-radius: 50%;
2296
- background: #DDD;
2297
- display: inline-block;
2298
- width: 16px;
2299
- height: 16px;
2300
- text-align: center;
2301
- line-height: 16px;
2302
- color: #FFF;
2303
- font-size: 16px;
2304
- vertical-align: middle;
2305
- margin-right: 5px;
2306
- content: '';
2307
- }
2308
- &:hover a:before {
2309
- background: #4acfff;
2310
- }
2311
- }
2312
- li.active {
2313
- a:before {
2314
- content: "\f147";
2315
- background: #4acfff;
2316
- }
2317
- &:hover a:before {
2318
- content: "\f335";
2319
- background: #a20000;
2320
- }
2321
- }
2322
- }
2323
- }
2324
- }
2325
-
2326
- @-moz-keyframes spin-12 {
2327
- 0% {
2328
- -moz-transform: rotate(0deg) translate(0px);
2329
- }
2330
- 100% {
2331
- -moz-transform: rotate(360deg) translate(0px);
2332
- }
2333
- }
2334
-
2335
- @-webkit-keyframes spin-12 {
2336
- 0% {
2337
- -webkit-transform: rotate(0deg) translate(0px);
2338
- }
2339
- 100% {
2340
- -webkit-transform: rotate(360deg) translate(0px);
2341
- }
2342
- }
2343
-
2344
- @keyframes spin-12 {
2345
- 0% {
2346
- -webkit-transform: rotate(0deg) translate(0px);
2347
- transform: rotate(0deg) translate(0px);
2348
- }
2349
- 100% {
2350
- -webkit-transform: rotate(360deg) translate(0px);
2351
- transform: rotate(360deg) translate(0px);
2352
- }
2353
- }
2354
-
2355
- @-moz-keyframes spin-13 {
2356
- 100% {
2357
- -moz-transform: rotate(0deg) translate(0px);
2358
- }
2359
- 0% {
2360
- -moz-transform: rotate(360deg) translate(0px);
2361
- }
2362
- }
2363
-
2364
- @-webkit-keyframes spin-13 {
2365
- 0% {
2366
- -webkit-transform: rotate(0deg) translate(0px);
2367
- }
2368
- 100% {
2369
- -webkit-transform: rotate(360deg) translate(0px);
2370
- }
2371
- }
2372
-
2373
- @keyframes spin-13 {
2374
- 100% {
2375
- -webkit-transform: rotate(0deg) translate(0px);
2376
- transform: rotate(0deg) translate(0px);
2377
- }
2378
- 0% {
2379
- -webkit-transform: rotate(360deg) translate(0px);
2380
- transform: rotate(360deg) translate(0px);
2381
- }
2382
- }
2383
-
2384
- @media screen and (max-width: 1250px) {
2385
- .single-lp_course .learn-press-course-results-progress {
2386
- .items-progress, .course-progress {
2387
- float: none;
2388
- width: 100%;
2389
- }
2390
- .items-progress {
2391
- margin-bottom: 50px;
2392
- }
2393
- }
2394
- }
2395
-
2396
- @media screen and (max-width: 768px) {
2397
- #learn-press-block-content {
2398
- .learn-press-block-content-mixin(60px);
2399
- }
2400
-
2401
- .learn-press-course-results-progress {
2402
- .items-progress, .course-progress {
2403
- width: 100%;
2404
- margin-right: 0;
2405
- }
2406
- }
2407
-
2408
- }
2409
-
2410
- @media (min-width: 992px) {
2411
- .learn-press-courses {
2412
- li.course {
2413
- &:nth-child(4n+1) {
2414
- clear: left;
2415
- }
2416
- }
2417
- }
2418
- }
2419
-
2420
- @media (max-width: 992px) {
2421
- .learn-press-courses {
2422
- margin: 0;
2423
- }
2424
- }
2425
-
2426
- @media (max-width: 992px) and (min-width: 600px ) {
2427
-
2428
- .learn-press-courses {
2429
- li.course {
2430
- width: 31.33%;
2431
- margin: 0 2% 30px 0;
2432
- /* padding: 0 20px; */
2433
- &:nth-child(3n+1) {
2434
- clear: left;
2435
- margin-left: 0;
2436
- }
2437
- }
2438
- }
2439
-
2440
- }
2441
-
2442
- @media (max-width: 600px) and (min-width: 400px ) {
2443
-
2444
- .learn-press-courses {
2445
- li.course {
2446
- width: 48%;
2447
- margin: 0 2% 30px 0;
2448
- /* padding: 0 20px; */
2449
- &:nth-child(2n+1) {
2450
- clear: left;
2451
- margin-left: 0;
2452
- }
2453
- }
2454
- }
2455
-
2456
- }
2457
-
2458
- /*
2459
- @media (max-width: 480px) {
2460
- .woocommerce {
2461
- .checkout_coupon {
2462
- .form-row {
2463
- width: 100%;
2464
- }
2465
- }
2466
- }
2467
- }
2468
- */
2469
- @media (max-width: 400px) {
2470
-
2471
- .learn-press-courses {
2472
- li.course {
2473
- width: 100%;
2474
- margin: 0 0 30px 0;
2475
- clear: left;
2476
- }
2477
- }
2478
-
2479
- }
2480
-
2481
- @media (max-width: 350px) {
2482
- #course-curriculum-popup #popup-sidebar {
2483
- width: 100%;
2484
- }
2485
- }
2486
-
2487
- /* full width with twentysixteen theme */
2488
- @media screen and (min-width: 61.5625em) {
2489
- body.single-lp_course {
2490
- article.lp_course {
2491
- .entry-content {
2492
- width: 100%;
2493
- }
2494
- .entry-footer {
2495
- display: none;
2496
- }
2497
- }
2498
- }
2499
- }
2500
-
2501
- /*
2502
- @media screen and (max-width: 615px) {
2503
- .payment-method-form {
2504
- &.payment_method_authorizenet {
2505
- .row-fluid {
2506
- padding-bottom: 15px;
2507
- .span6 {
2508
- &:first-child {
2509
- width: 100%;
2510
- margin-bottom: 15px;
2511
- }
2512
- label {
2513
- margin-left: 17px;
2514
- }
2515
- select, input {
2516
- margin-left: 10px;
2517
- }
2518
- select, input {
2519
- padding: 8px 0;
2520
- }
2521
- select.required {
2522
- color: #000;
2523
- }
2524
- #learn-press-authorizenet-payment-expmonth {
2525
- margin-bottom: 10px;
2526
- }
2527
- }
2528
- }
2529
- }
2530
- }
2531
- }
2532
- */
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 10px 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
@@ -655,7 +655,7 @@ lprHook.addAction('lpr_admin_quiz_question_html', _lprAdminQuestionHTML);
655
  parse_json : function (response) {
656
  if (typeof reposnse == 'object') return response;
657
  try {
658
- var m = response.match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/)
659
 
660
  if (m && m[1]) {
661
  response = JSON.parse(m[1])
@@ -1123,8 +1123,8 @@ jQuery(document).ready(function ($) {
1123
  id = url.getQueryVar('tab');
1124
  $li.addClass('active').siblings().removeClass('active');
1125
  $el.find('#meta-box-tab-' + id).addClass('active').siblings().removeClass('active');
1126
- $el.find('input[name="learn-press-meta-box-tab"]').val(id);
1127
  LP.setUrl(url);
 
1128
  //$(window).scrollTop($box.offset().top - 120);
1129
  });
1130
  $el.data('metaBoxTabs', tabs);
655
  parse_json : function (response) {
656
  if (typeof reposnse == 'object') return response;
657
  try {
658
+ var m = response.match(/<!-- LP_AJAX_START -->(.*)<!-- LP_AJAX_END -->/)
659
 
660
  if (m && m[1]) {
661
  response = JSON.parse(m[1])
1123
  id = url.getQueryVar('tab');
1124
  $li.addClass('active').siblings().removeClass('active');
1125
  $el.find('#meta-box-tab-' + id).addClass('active').siblings().removeClass('active');
 
1126
  LP.setUrl(url);
1127
+ console.log(id)
1128
  //$(window).scrollTop($box.offset().top - 120);
1129
  });
1130
  $el.data('metaBoxTabs', tabs);
assets/js/admin/attributes.js CHANGED
@@ -81,12 +81,7 @@
81
  })
82
  .on('click', '#save-attributes', saveAttributesEvent)
83
  .on('keyup.addNewAttributeValueEvent', '.select2-input', addNewAttributeValueEvent);
84
-
85
- var $courseAttributes = $('.course-attribute-values') ;
86
-
87
- if ($courseAttributes.length) {
88
- $courseAttributes.select2(select2Options);
89
- }
90
 
91
  });
92
  })(jQuery);
81
  })
82
  .on('click', '#save-attributes', saveAttributesEvent)
83
  .on('keyup.addNewAttributeValueEvent', '.select2-input', addNewAttributeValueEvent);
84
+ $('.course-attribute-values').select2(select2Options);
 
 
 
 
 
85
 
86
  });
87
  })(jQuery);
assets/js/admin/course-editor.js CHANGED
@@ -34,7 +34,7 @@
34
  },
35
  render : function () {
36
  this.$editor = this.template('course-editor');
37
- var $curriculum = this.$editor.find('#lp-course-curriculum');
38
  this.model.sections.forEach(function (section) {
39
  var $section = this._createSection(section);
40
  $curriculum.append($section);
@@ -69,8 +69,8 @@
69
  axis : 'y',
70
  handle : '.section-item-move',
71
  connectWith: '.section-items',
72
- stop : function (e, ui) {
73
- if (!ui.item.hasClass('ui-draggable')) {
74
  return;
75
  }
76
  var temp_id = parseInt($(this).closest('.course-section').data('temp_id')),
@@ -88,7 +88,7 @@
88
  $section.find('.section-content-types li').draggable({
89
  revert : 'invalid',
90
  connectToSortable: '.section-items',
91
- helper : function () {
92
 
93
  var $helper = $(this).clone();
94
  $helper.get(0).className = 'ui-draggable ui-draggable-handle course-section-item';
@@ -99,7 +99,7 @@
99
  accept: '.dashicons',
100
  drop : function (e, ui) {
101
 
102
- if (!xxx.check(10)) {
103
  //return;
104
  }
105
 
@@ -149,7 +149,7 @@
149
  this.model.sections.add(section);
150
 
151
  var $section = this._createSection(section);
152
- this.$editor.find('#lp-course-curriculum').append($section);
153
  $section.find('.section-name').focus();
154
  },
155
  _showContentTypes: function (e) {
34
  },
35
  render : function () {
36
  this.$editor = this.template('course-editor');
37
+ var $curriculum = this.$editor.find('#course-curriculum');
38
  this.model.sections.forEach(function (section) {
39
  var $section = this._createSection(section);
40
  $curriculum.append($section);
69
  axis : 'y',
70
  handle : '.section-item-move',
71
  connectWith: '.section-items',
72
+ stop: function(e, ui){
73
+ if(!ui.item.hasClass('ui-draggable')){
74
  return;
75
  }
76
  var temp_id = parseInt($(this).closest('.course-section').data('temp_id')),
88
  $section.find('.section-content-types li').draggable({
89
  revert : 'invalid',
90
  connectToSortable: '.section-items',
91
+ helper : function(){
92
 
93
  var $helper = $(this).clone();
94
  $helper.get(0).className = 'ui-draggable ui-draggable-handle course-section-item';
99
  accept: '.dashicons',
100
  drop : function (e, ui) {
101
 
102
+ if(!xxx.check(10)){
103
  //return;
104
  }
105
 
149
  this.model.sections.add(section);
150
 
151
  var $section = this._createSection(section);
152
+ this.$editor.find('#course-curriculum').append($section);
153
  $section.find('.section-name').focus();
154
  },
155
  _showContentTypes: function (e) {
assets/js/admin/meta-box-course.js CHANGED
@@ -30,7 +30,7 @@
30
  'keyup' : 'processKeyEvents',
31
  'click .lp-section-item .lp-remove' : '_removeItem',
32
  'click .lp-toggle' : 'toggleSection',
33
- 'click .curriculum-heading .items-toggle a' : 'toggleSections',
34
  'keyup input.no-submit' : 'onEnterInput',
35
  'update input.no-submit' : 'onEnterInput',
36
  'keydown' : 'preventSubmit',
@@ -45,8 +45,7 @@
45
  'click .learn-press-dropdown-item-types > li a' : '_changeItemType',
46
  'change .lp-item-name ' : '_updateItem',
47
  'focus .lp-item-name' : '_focusItem',
48
- 'blur .lp-item-name' : '_blurItem',
49
- 'click #learn-press-toggle-course-results' : '_toggleCourseResults'
50
  },
51
  removeSectionIds : [],
52
  removeItemIds : [],
@@ -67,13 +66,6 @@
67
  $('#course_curriculum.postbox').removeClass('closed');
68
 
69
  },
70
- _toggleCourseResults : function (e) {
71
- e.preventDefault();
72
- var $a = $(e.target),
73
- click = $a.data('click');
74
- $a.html($a.data(click));
75
- $a.attr('data-click', click == 'advanced' ? 'basic' : 'advanced');
76
- },
77
  _focusItem : function (e) {
78
  $(e.target).closest('tr').removeClass('focus');
79
  },
@@ -153,7 +145,7 @@
153
  ///////////
154
  var $chkPayment = $('input[name="_lp_payment"]').on('click', function () {
155
  var toggle = !($(this).is(':checked'));
156
- $('.lp-course-price-field').toggleClass('hide-if-js', toggle);
157
  $('.lp-course-required-enroll').toggleClass('hide-if-js', !toggle);
158
  if (toggle) {
159
  $('.lp-course-sale_start-field').addClass('hide');
@@ -250,6 +242,7 @@
250
  }
251
 
252
 
 
253
  $(document)
254
  .on('keyup', '.lp-modal-search input[name="lp-item-name"]', this.searchItem)
255
  .on('click change', '.lp-modal-search input[type="checkbox"]', this.toggleAddItemButtonState)
@@ -259,7 +252,17 @@
259
  .on('change', 'input[name="learn-press-submit-for-review"]', this.toggleMessage);
260
 
261
  $('input[name="learn_press_submit_course_notice_reviewer"]').trigger('change');
262
-
 
 
 
 
 
 
 
 
 
 
263
  },
264
  toggleMessage : function (e) {
265
  if (e.target.checked) {
@@ -290,22 +293,22 @@
290
  return this.checked
291
  }).length )
292
  ? (
293
- $checkbox.closest('.curriculum-section-content')
 
 
 
 
 
 
 
 
 
294
  .find('.item-bulk-actions button')
295
- .removeAttr('disabled')
296
- .removeClass('hide-if-js')
297
  .map(function () {
298
  var $b = $(this);
299
- $b.attr('data-action') == 'cancel' ? $b.removeClass('hide-if-js') : $b.html($b.attr('data-title') + ' (+' + len + ')').show()
300
- })
301
- )
302
- : $checkbox.closest('.curriculum-section-content')
303
- .find('.item-bulk-actions button')
304
- .hide()
305
- .map(function () {
306
- var $b = $(this);
307
- $b.attr('data-action') == 'cancel' ? $b.hide() : $b.html($b.attr('data-title')).hide()
308
- });
309
  $checkbox.closest('.lp-section-item').toggleClass('remove', e.target.checked);
310
  if (len == $all.length) {
311
  $checkAll.attr('checked', 'checked')
@@ -572,11 +575,10 @@
572
  e.preventDefault();
573
  var $target = $(e.target);
574
  if ($target.attr('data-action') == 'expand') {
575
- this.$('.curriculum-section:not(.lp-empty-section) .curriculum-section-content').slideDown();
576
  } else {
577
- this.$('.curriculum-section:not(.lp-empty-section) .curriculum-section-content').slideUp();
578
  }
579
- $target.addClass('hide-if-js').siblings('a').removeClass('hide-if-js');
580
  },
581
  getSelectedItems : function () {
582
  return this.$('.lp-section-item[data-item_id]').map(function () {
@@ -1423,7 +1425,7 @@
1423
  return false;
1424
  } else {
1425
  }*/
1426
- }).attr('novalidate', 'true');
1427
  $('#learn-press-notice-check').change(function () {
1428
  var that = this,
1429
  $review = $('textarea[name="review_message"]').prop('disabled', !this.checked),
@@ -1442,22 +1444,6 @@
1442
  });
1443
  });
1444
 
1445
- function _toggleCourseResults(click) {
1446
-
1447
- }
1448
-
1449
- $(document).on('click.learn-press-toggle-course-results', '#learn-press-toggle-course-results a', function (e) {
1450
- e.preventDefault();
1451
- var $a = $(this),
1452
- click = $a.data('click');
1453
- $a.html($a.data(click));
1454
- $a.data('click', click == 'advanced' ? 'basic' : 'advanced');
1455
- $a.closest('.rwmb-input').children('label:gt(1)').toggle(click != 'advanced');
1456
- $a.parent().remove();
1457
- });
1458
- if ($.inArray($('input[name="_lp_course_result"]:checked').val(), ['', 'evaluate_lesson', 'evaluate_final_quiz']) != -1) {
1459
- $('#learn-press-toggle-course-results').closest('.rwmb-input').children('label:gt(1)').hide();
1460
- }
1461
 
1462
  function canSubmit() {
1463
  if ((opts.current_user_type == 'admin') || !opts.required_review || (opts.course_status == 'publish' && opts.enable_edit_published)) {
@@ -1475,10 +1461,80 @@
1475
  }
1476
  $('#course_curriculum-sortables').sortable('disable');
1477
 
 
 
 
 
1478
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1479
  }
1480
 
1481
  $(document)
1482
- .ready(_ready);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1483
  })
1484
  (jQuery);
30
  'keyup' : 'processKeyEvents',
31
  'click .lp-section-item .lp-remove' : '_removeItem',
32
  'click .lp-toggle' : 'toggleSection',
33
+ 'click .lp-course-curriculum-toggle a' : 'toggleSections',
34
  'keyup input.no-submit' : 'onEnterInput',
35
  'update input.no-submit' : 'onEnterInput',
36
  'keydown' : 'preventSubmit',
45
  'click .learn-press-dropdown-item-types > li a' : '_changeItemType',
46
  'change .lp-item-name ' : '_updateItem',
47
  'focus .lp-item-name' : '_focusItem',
48
+ 'blur .lp-item-name' : '_blurItem'
 
49
  },
50
  removeSectionIds : [],
51
  removeItemIds : [],
66
  $('#course_curriculum.postbox').removeClass('closed');
67
 
68
  },
 
 
 
 
 
 
 
69
  _focusItem : function (e) {
70
  $(e.target).closest('tr').removeClass('focus');
71
  },
145
  ///////////
146
  var $chkPayment = $('input[name="_lp_payment"]').on('click', function () {
147
  var toggle = !($(this).is(':checked'));
148
+ $('.lp-course-price-field').toggleClass('hide-if-js', toggle).attr('xxx', Math.random());
149
  $('.lp-course-required-enroll').toggleClass('hide-if-js', !toggle);
150
  if (toggle) {
151
  $('.lp-course-sale_start-field').addClass('hide');
242
  }
243
 
244
 
245
+
246
  $(document)
247
  .on('keyup', '.lp-modal-search input[name="lp-item-name"]', this.searchItem)
248
  .on('click change', '.lp-modal-search input[type="checkbox"]', this.toggleAddItemButtonState)
252
  .on('change', 'input[name="learn-press-submit-for-review"]', this.toggleMessage);
253
 
254
  $('input[name="learn_press_submit_course_notice_reviewer"]').trigger('change');
255
+ $(window).scroll(function () {
256
+ return;
257
+ var $holder = $('#course_tabs_placeholder'),
258
+ $tabs = $('#course_tabs'),
259
+ top = $holder.offset().top;
260
+ if ($(window).scrollTop() > top) {
261
+ $tabs.css('width', $tabs.width()).addClass('fixed');
262
+ } else {
263
+ $tabs.css('width', '').removeClass('fixed');
264
+ }
265
+ });
266
  },
267
  toggleMessage : function (e) {
268
  if (e.target.checked) {
293
  return this.checked
294
  }).length )
295
  ? (
296
+ $checkbox.closest('.curriculum-section-content')
297
+ .find('.item-bulk-actions button')
298
+ .removeAttr('disabled')
299
+ .removeClass('hide-if-js')
300
+ .map(function () {
301
+ var $b = $(this);
302
+ $b.attr('data-action') == 'cancel' ? $b.removeClass('hide-if-js') : $b.html($b.attr('data-title') + ' (+' + len + ')').show()
303
+ })
304
+ )
305
+ : $checkbox.closest('.curriculum-section-content')
306
  .find('.item-bulk-actions button')
307
+ .hide()
 
308
  .map(function () {
309
  var $b = $(this);
310
+ $b.attr('data-action') == 'cancel' ? $b.hide() : $b.html($b.attr('data-title')).hide()
311
+ });
 
 
 
 
 
 
 
 
312
  $checkbox.closest('.lp-section-item').toggleClass('remove', e.target.checked);
313
  if (len == $all.length) {
314
  $checkAll.attr('checked', 'checked')
575
  e.preventDefault();
576
  var $target = $(e.target);
577
  if ($target.attr('data-action') == 'expand') {
578
+ this.$('.curriculum-section:not(.lp-empty-section) .lp-curriculum-section-content').slideDown();
579
  } else {
580
+ this.$('.curriculum-section:not(.lp-empty-section) .lp-curriculum-section-content').slideUp();
581
  }
 
582
  },
583
  getSelectedItems : function () {
584
  return this.$('.lp-section-item[data-item_id]').map(function () {
1425
  return false;
1426
  } else {
1427
  }*/
1428
+ });
1429
  $('#learn-press-notice-check').change(function () {
1430
  var that = this,
1431
  $review = $('textarea[name="review_message"]').prop('disabled', !this.checked),
1444
  });
1445
  });
1446
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1447
 
1448
  function canSubmit() {
1449
  if ((opts.current_user_type == 'admin') || !opts.required_review || (opts.course_status == 'publish' && opts.enable_edit_published)) {
1461
  }
1462
  $('#course_curriculum-sortables').sortable('disable');
1463
 
1464
+ if (LP_Settings.enable_course_tabs == 'yes') {
1465
+ meta_boxes_to_tabs();
1466
+ }
1467
+ }
1468
 
1469
+ function meta_boxes_to_tabs() {
1470
+ var $tabWrapper = $('#course-tabs'),
1471
+ requestedTab = window.location.href.getQueryVar('tab');
1472
+ $('#normal-sortables .postbox:visible').each(function () {
1473
+ var $tabContent = $(this).removeClass('closed');
1474
+ $tabWrapper.append('<li><a data-tab="' + $tabContent.attr('id') + '" href="">' + $tabContent.find('.ui-sortable-handle').text() + '</a></li>');
1475
+ if (!requestedTab) {
1476
+ requestedTab = $tabContent.attr('id');
1477
+ }
1478
+ });
1479
+ $(document).on('click', '#course-tabs :not(#switch-course-metaboxes) a', function () {
1480
+ var $tab = $(this),
1481
+ id = $tab.data('tab'),
1482
+ url = window.location.href;
1483
+
1484
+ $('#' + id + '.postbox').addClass('active').siblings('.active').removeClass('active');
1485
+ $tab.parent().addClass('active').siblings().removeClass('active');
1486
+ url = url.removeQueryVar('tab').addQueryVar('tab', id);
1487
+ LP.setUrl(url);
1488
+ $('#course-tab').val(id);
1489
+ $(window).trigger('scroll');
1490
+ return false;
1491
+ })
1492
+ /*.on('click', '#switch-course-metaboxes', function () {
1493
+ var url = window.location.href;
1494
+ url = url.removeQueryVar('tab').addQueryVar('switch-course-tab', 'off');
1495
+ LP.reload(url);
1496
+ });*/
1497
+ $('#course-tabs [data-tab="' + requestedTab + '"]').trigger('click');
1498
  }
1499
 
1500
  $(document)
1501
+ .ready(_ready)
1502
+ .on('click', '.items-toggle a', _toggleSectionsHandler)
1503
+ .on('click', '#toggle-meta-boxes', function (e) {
1504
+ e.preventDefault();
1505
+ var $boxes = $('#normal-sortables .postbox:visible'),
1506
+ show = $boxes.first().hasClass('closed');
1507
+ // We do not want wp run ajax for each meta box
1508
+ $boxes.filter(':lt(' + ($boxes.length - 1) + ')').toggleClass('closed', !show);
1509
+
1510
+ // Tell wp api update meta box states by trigger click event in the last item
1511
+ $boxes.last().toggleClass('closed', show).find('.handlediv').trigger('click');
1512
+ }).on('click', '#reorder-course-tabs', function (e) {
1513
+ e.preventDefault();
1514
+ $(this).hide();
1515
+ $('#complete-reorder-course-tabs').show();
1516
+ $('#course-tabs').sortable({
1517
+ axis : 'x',
1518
+ items : 'li:not(#switch-course-metaboxes)',
1519
+ update: function (e, ui) {
1520
+ var tab = ui.item.find('a').data('tab'),
1521
+ $prev = ui.item.prev(),
1522
+ $next = ui.item.next();
1523
+ if ($prev.length) {
1524
+ $('#' + tab + '.postbox').insertAfter($('#' + $prev.find('a').data('tab') + '.postbox'));
1525
+ } else {
1526
+ $('#' + tab + '.postbox').insertBefore($('#' + $next.find('a').data('tab') + '.postbox'));
1527
+
1528
+ }
1529
+ }
1530
+ }).sortable('enable');
1531
+ }).on('click', '#complete-reorder-course-tabs', function (e) {
1532
+ e.preventDefault();
1533
+ $(this).hide();
1534
+ $('#reorder-course-tabs').show();
1535
+ $('#course-tabs').sortable('disable');
1536
+ })
1537
+
1538
+
1539
  })
1540
  (jQuery);
assets/js/admin/meta-box-order.js CHANGED
@@ -14,38 +14,19 @@
14
  _.bindAll(this, 'resetModal', 'updateModal', '_updateDescription');
15
  LP.Hook.addAction('learn_press_message_box_before_resize', this.resetModal);
16
  LP.Hook.addAction('learn_press_message_box_resize', this.updateModal);
17
-
18
- var $selectUsers = this.$('#order-customer');
19
- if ($selectUsers.attr('multiple') == 'multiple') {
20
- $selectUsers.select2({
21
- width: $('#minor-publishing .misc-pub-section').innerWidth() - 20
22
- });
23
- }
24
- var $add_new_h2 = $('body.post-type-lp_order').find('.page-title-action, .add-new-h2'),
25
- $add_h2 = $('<a href="post-new.php?post_type=lp_order&multi-users=yes" class="page-title-action add-new-h2">Add order multiple users</a>');
26
- $add_h2
27
- .insertAfter($add_new_h2);
28
-
29
- $('select[name="order-status"]').on('init change', function () {
30
- var $sel = $(this),
31
- $sec = $('.order-action-section'),
32
- status = $sel.data('status');
33
- console.log(status, $sel.val())
34
- $sec.toggleClass('hide-if-js', status != $sel.val());
35
- }).trigger('init');
36
-
37
-
38
  $(document).on('learn_press_modal_search_items_response', this.addItem2);
39
  this.userSuggest();
40
  },
41
  _updateDescription: function (e) {
42
  var $sel = $(e.target),
43
  $option = $sel.find('option:selected');
44
- $sel.siblings('.description').hide().html($option.attr('data-desc'))
45
- .removeClass(function (c, d) {
46
- var m = d.match(/(lp-.*)\s?/);
47
- return m ? m[0] : '';
48
- }).addClass($option.val()).show();
 
 
49
  },
50
  userSuggest : function () {
51
  var id = ( typeof current_site_id !== 'undefined' ) ? '&site_id=' + current_site_id : '';
@@ -82,7 +63,7 @@
82
  updateModal : function ($app) {
83
  this.$('#learn-press-courses-result').css('height', '').css('overflow', '');
84
  },
85
- showFormItems : function (type) {
86
  var $form = LP.ModalSearchItems({
87
  template : 'tmpl-learn-press-search-items',
88
  type : 'lp_course',
@@ -97,22 +78,22 @@
97
 
98
  },
99
  _addItem : function (e) {
100
- this.showFormItems('lp_course', 'add-lp_course')
101
  // var $form = $('#learn-press-modal-add-order-courses');
102
  // if ($form.length == 0) {
103
  // $form = $(wp.template('learn-press-modal-add-order-courses')());
104
  // }
105
  // LP.MessageBox.show($form);
106
  },
107
- addItem2 : function (e, $view, $items) {
108
- var that = this;
109
- var selected = $items; //$form.find('li:visible input:checked'),
110
  if (e.ctrlKey) {
111
  //return true;
112
  }
113
  var ids = [];
114
  selected.each(function () {
115
- ids.push($(this).data('id'));
116
  });
117
 
118
  $.ajax({
@@ -135,17 +116,17 @@
135
  $order_table.find('.order-subtotal').html(response.order_data.subtotal_html);
136
  $order_table.find('.order-total').html(response.order_data.total_html);
137
 
138
- selected.each(function () {
139
- console.log($(this));
140
- $(this).remove();
141
- });
142
  $no_item.addClass('hide-if-js');
143
  }
144
  }
145
  });
146
 
147
  return false;
148
- // restart sortable
149
  // _makeListSortable();
150
  },
151
  addItem : function (e, ids) {
14
  _.bindAll(this, 'resetModal', 'updateModal', '_updateDescription');
15
  LP.Hook.addAction('learn_press_message_box_before_resize', this.resetModal);
16
  LP.Hook.addAction('learn_press_message_box_resize', this.updateModal);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  $(document).on('learn_press_modal_search_items_response', this.addItem2);
18
  this.userSuggest();
19
  },
20
  _updateDescription: function (e) {
21
  var $sel = $(e.target),
22
  $option = $sel.find('option:selected');
23
+ $sel.siblings('.description').fadeOut('fast', function () {
24
+ $(this).html($option.attr('data-desc'))
25
+ .removeClass(function (c, d) {
26
+ var m = d.match(/(lp-.*)\s?/);
27
+ return m ? m[0] : '';
28
+ }).addClass($option.val()).fadeIn('fast');
29
+ });
30
  },
31
  userSuggest : function () {
32
  var id = ( typeof current_site_id !== 'undefined' ) ? '&site_id=' + current_site_id : '';
63
  updateModal : function ($app) {
64
  this.$('#learn-press-courses-result').css('height', '').css('overflow', '');
65
  },
66
+ showFormItems : function ( type ) {
67
  var $form = LP.ModalSearchItems({
68
  template : 'tmpl-learn-press-search-items',
69
  type : 'lp_course',
78
 
79
  },
80
  _addItem : function (e) {
81
+ this.showFormItems('lp_course','add-lp_course')
82
  // var $form = $('#learn-press-modal-add-order-courses');
83
  // if ($form.length == 0) {
84
  // $form = $(wp.template('learn-press-modal-add-order-courses')());
85
  // }
86
  // LP.MessageBox.show($form);
87
  },
88
+ addItem2 : function (e, $view, $items) {
89
+ var that = this;
90
+ var selected = $items; //$form.find('li:visible input:checked'),
91
  if (e.ctrlKey) {
92
  //return true;
93
  }
94
  var ids = [];
95
  selected.each(function () {
96
+ ids.push( $(this).data('id') );
97
  });
98
 
99
  $.ajax({
116
  $order_table.find('.order-subtotal').html(response.order_data.subtotal_html);
117
  $order_table.find('.order-total').html(response.order_data.total_html);
118
 
119
+ selected.each(function () {
120
+ console.log($(this));
121
+ $(this).remove();
122
+ });
123
  $no_item.addClass('hide-if-js');
124
  }
125
  }
126
  });
127
 
128
  return false;
129
+ // restart sortable
130
  // _makeListSortable();
131
  },
132
  addItem : function (e, ids) {
assets/js/admin/meta-box-quiz.js CHANGED
@@ -283,18 +283,6 @@
283
  }
284
  $el.find('span').html(t);
285
  }).filter(':checked').trigger('change');
286
-
287
- $('input[name="_lp_show_hide_question"]').change(function () {
288
- var t = $('input[name="_lp_show_hide_question"]:checked').val(),
289
- $el = $('label[for="_lp_show_result"]'),
290
- passing_grade = $('input[name="_lp_show_result"]');
291
- if( t === 'show' ){
292
- $el.closest('.rwmb-field').show();
293
- } else {
294
- $el.closest('.rwmb-field').hide();
295
- }
296
- $el.find('span').html(t);
297
- }).filter(':checked').trigger('change');
298
  });
299
 
300
  return;
@@ -327,4 +315,4 @@
327
 
328
  $doc.ready(_ready);
329
 
330
- })(jQuery)
283
  }
284
  $el.find('span').html(t);
285
  }).filter(':checked').trigger('change');
 
 
 
 
 
 
 
 
 
 
 
 
286
  });
287
 
288
  return;
315
 
316
  $doc.ready(_ready);
317
 
318
+ })(jQuery)
assets/js/admin/settings.js CHANGED
@@ -168,23 +168,12 @@
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
- }).on('change update', '#learn_press_auto_redirect_next_lesson', function (e) {
175
- var $depend = $('#learn_press_auto_redirect_message, #learn_press_auto_redirect_time').closest('tr');
176
- $depend.toggleClass('hide-if-js', !e.target.checked);
177
- }).on('change', '.learn-press-single-course-permalink input[type="radio"]', function () {
178
- var $check = $(this),
179
- $row = $check.closest('.learn-press-single-course-permalink');
180
- if ($row.hasClass('custom-base')) {
181
- $row.find('input[type="text"]').prop('readonly', false);
182
- } else {
183
- $row.siblings('.custom-base').find('input[type="text"]').prop('readonly', true);
184
- }
185
  });
186
 
187
- $('#learn_press_required_review, #learn_press_auto_redirect_next_lesson').trigger('update');
188
  $('#learn-press-admin-settings').on('click', '.nav-tab, .subsubsub > li > a', function (e) {
189
  e.preventDefault();
190
  var redirect = $(this).attr('href'),
@@ -206,28 +195,13 @@
206
  window.location.href = redirect;
207
  }
208
  });
 
209
  if ($('#learn-press-admin-settings .subsubsub').length) {
210
  $('#learn-press-admin-settings').removeClass('no-subtabs');
211
  }
212
  $('.learn-press-settings-wrap').addClass('ready')
213
- .on('click', '#learn-press-reset-settings', function () {
214
- if (!confirm($(this).data('text'))) {
215
- return false;
216
- }
217
- });
218
-
219
  // hold current settings to know if user changed anything
220
  oldData = $('#mainform').serialize();
221
-
222
- (function () {
223
- $('.learn-press-dropdown-pages').each(function () {
224
- var $sel = $(this);
225
- $sel.css('width', $sel.width() + 50).find('option').each(function () {
226
- $(this).html($(this).html().replace(/&nbsp;&nbsp;&nbsp;/g, ''));
227
- });
228
- $sel.select2();
229
- });
230
- })();
231
  }
232
 
233
  $doc.ready(_ready);
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'),
195
  window.location.href = redirect;
196
  }
197
  });
198
+
199
  if ($('#learn-press-admin-settings .subsubsub').length) {
200
  $('#learn-press-admin-settings').removeClass('no-subtabs');
201
  }
202
  $('.learn-press-settings-wrap').addClass('ready')
 
 
 
 
 
 
203
  // hold current settings to know if user changed anything
204
  oldData = $('#mainform').serialize();
 
 
 
 
 
 
 
 
 
 
205
  }
206
 
207
  $doc.ready(_ready);
assets/js/frontend/bak.course-lesson.js ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function ($) {
2
+ "use strict";
3
+ return;
4
+ $.LP_Course_Item = function () {
5
+
6
+ }
7
+ $.LP_Course_Item.Model = Backbone.Model.extend({
8
+ url : function () {
9
+ return this.rootUrl
10
+ },
11
+ rootUrl : '',
12
+ initialize: function (data) {
13
+ this.rootUrl = data.rootUrl;
14
+ },
15
+ load : function (callback) {
16
+ var that = this,
17
+ _completed = function (response, success) {
18
+ var $html = $(response || ''),
19
+ $lesson = $html.find('#learn-press-course-lesson');
20
+ if ($lesson.length == 0) {
21
+ $lesson = $('<div id="learn-press-course-lesson" />');
22
+ }
23
+ if (LP.Hook.applyFilters('learn_press_update_item_content', $lesson, that) !== false) {
24
+ that.set('content', $lesson);
25
+ $(document).trigger('learn_press_course_item_content_replaced', $lesson, that);
26
+ $('.course-item.item-current')
27
+ .removeClass('item-current');
28
+ $('.course-item.course-item-' + that.get('id'))
29
+ .addClass('item-current');
30
+ }
31
+ $.isFunction(callback) && callback.call(that, response);
32
+ };
33
+ $.ajax({
34
+ url : this.url(),
35
+ dataType: 'html',
36
+ success : function (response) {
37
+ _completed(response, true);
38
+ },
39
+ error : function () {
40
+ _completed('', false)
41
+ }
42
+ });
43
+ },
44
+ complete : function (args) {
45
+ var that = this;
46
+ args = $.extend({
47
+ data : null,
48
+ success: null
49
+ }, args || {});
50
+ LP.ajax({
51
+ dataType: 'html',
52
+ action : 'complete_lesson',
53
+ data : $.extend({
54
+ id: this.get('id')
55
+ }, args.data || {}),
56
+ success : function (response) {
57
+ response = LP.parseJSON(response);
58
+ $.isFunction(args.success) && args.success.call(that, $.extend(response, {id: that.get('id')}))
59
+ }
60
+ });
61
+ return;
62
+ $.ajax({
63
+ url : '',
64
+ dataType: 'html',
65
+ data : $.extend({
66
+ action: 'learnpress_complete_lesson',
67
+ id : this.get('id')
68
+ }, args.data || {}),
69
+ success : function (response) {
70
+ response = LP.parseJSON(response);
71
+ $.isFunction(args.success) && args.success.call(that, $.extend(response, {id: that.get('id')}))
72
+ }
73
+ })
74
+ }
75
+ });
76
+
77
+ $.LP_Course_Item.View = Backbone.View.extend({
78
+ el : '#learn-press-course-lesson',
79
+ events : {
80
+ 'click .complete-lesson-button': '_completeLesson'
81
+ },
82
+ initialize : function () {
83
+ _.bindAll(this, 'updateItem', '_completeLesson');
84
+ this.model.on('change', this.updateItem, this);
85
+
86
+ if (LP.Hook.applyFilters('learn_press_before_load_item', this) !== false) {
87
+ if (this.model.get('id') /*&& this.$('input[name="learn-press-lesson-viewing"]').val() != this.model.get('id')*/) {
88
+ if (this.model.get('content') == 'no-cache') {
89
+ this.updateItem();
90
+ } else {
91
+ this.model.load();
92
+ }
93
+ } else if (this.model.get('content')) {
94
+ LP.Hook.doAction('learn_press_item_content_loaded', this.model.get('content'), this);
95
+ }
96
+ }
97
+ },
98
+ updateItem : function () {
99
+ var $content = this.model.get('content');
100
+ this.$el.replaceWith($content);
101
+ this.setElement($content.show());
102
+ var url = LP.Hook.applyFilters('learn_press_set_item_url', this.model.get('rootUrl'), this);
103
+ if (url) {
104
+ LP.setUrl(url);
105
+ }
106
+ $content.closest('#learn-press-content-item').show();
107
+ LP.Hook.doAction('learn_press_item_content_loaded', $content, this);
108
+ },
109
+ _autoNextItem : function (item, delay) {
110
+ var $link = this.$('.course-item-next a[data-id="' + item + '"]');
111
+ if (!$link.length) {
112
+ return;
113
+ }
114
+ var duration = 3,
115
+ $span = $('<span>Auto next in ' + duration + 's</span>').insertAfter(this.$('.complete-lesson-button'));
116
+ setInterval(function () {
117
+ duration--;
118
+ $span.html('Auto next in ' + duration + 's');
119
+ if (duration == 0) {
120
+ $link.trigger('click')
121
+ }
122
+ }, 1000);
123
+ },
124
+ _completeLesson: function (e) {
125
+ var that = this;
126
+ this.model.complete({
127
+ data : $(e.target).data(),
128
+ success: function (response) {
129
+ response = LP.Hook.applyFilters('learn_press_user_complete_lesson_response', response);
130
+ if (response.next_item) {
131
+ //that._autoNextItem(response.next_item, 3);
132
+ }
133
+ LP.Hook.doAction('learn_press_user_completed_lesson', response, that);
134
+ }
135
+ });
136
+ }
137
+ });
138
+ $.LP_Course_Item.Collection = Backbone.Collection.extend({
139
+ model : $.LP_Course_Item.Model,
140
+ current : 0,
141
+ lastLoaded: null,
142
+
143
+ initialize: function () {
144
+ var that = this;
145
+ _.bindAll(this, 'initItems', 'loadItem');
146
+ this.initItems();
147
+ },
148
+ initItems : function () {
149
+ var that = this;
150
+ $('.section-content .course-item').each(function () {
151
+ var $li = $(this),
152
+ $link = $li.find('a'),
153
+ id = parseInt($link.attr('data-id')),
154
+ args = {
155
+ id : id,
156
+ nonce : {
157
+ complete: $link.attr('data-complete-nonce')
158
+ },
159
+ rootUrl: $link.attr('href'),
160
+ type : $li.data('type')
161
+ };
162
+ if ($li.hasClass('item-current')) {
163
+ that.current = id;
164
+ //args.content = $('#learn-press-course-lesson')
165
+ }
166
+ var model = new $.LP_Course_Item.Model(args);
167
+ that.add(model);
168
+ });
169
+
170
+ },
171
+ loadItem : function (item, link) {
172
+
173
+ if ($.isNumeric(item)) {
174
+ item = this.findWhere({id: item});
175
+ } else if ($.type(item) == 'string') {
176
+ item = this.findWhere({rootUrl: item});
177
+ } else {
178
+
179
+ }
180
+ if (LP.Hook.applyFilters('learn_press_load_item_content', true, item, link) !== false) {
181
+ if (item) {
182
+ if (this.view) {
183
+ this.view.undelegateEvents();
184
+ //this.view.model.set('content', this.view.$el);
185
+ $('.course-item.item-current')
186
+ .removeClass('item-current');
187
+ $('.course-item.course-item-' + item.get('id'))
188
+ .addClass('item-current');
189
+ }
190
+ if (link) {
191
+ item.set('rootUrl', link);
192
+ item.rootUrl = link;
193
+ }
194
+ this.view = new $.LP_Course_Item.View({model: item});
195
+ }
196
+ }
197
+ }
198
+ });
199
+
200
+ $.LP_Course_Item_List_View = Backbone.View.extend({
201
+ model : $.LP_Course_Item.Collection,
202
+ el : 'body',
203
+ events : {
204
+ 'click .section-content .course-item a': '_loadItem',
205
+ 'click .course-item-nav a' : '_loadItem'
206
+ },
207
+ initialize: function (args) {
208
+ _.bindAll(this, '_loadItem');
209
+ },
210
+ _loadItem : function (e) {
211
+ e.preventDefault();
212
+ var $item = $(e.target).closest('a'),
213
+ id = parseInt($item.attr('data-id')),
214
+ link = $item.attr('href');
215
+ var item = id ? id : link;
216
+ if (this.lastLoaded == item) {
217
+ return;
218
+ }
219
+ this.model.loadItem(item, link);
220
+ }
221
+ });
222
+
223
+ })(jQuery);
assets/js/frontend/bak.course-quiz.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Quiz functions
3
+ *
4
+ * @author ThimPress
5
+ * @version 1.1
6
+ */
7
+ if (typeof LP == 'undefined') {
8
+ window.LP = {};
9
+ }
10
+ ;(function ($, bb, _) {
11
+ var Quiz = function (args) {
12
+ this.model = new Quiz.Model(args);
13
+ this.view = new Quiz.View({
14
+ model: this.model
15
+ });
16
+ }, Questions = bb.Collection.extend({
17
+ initialize: function () {
18
+ console.log(this.length)
19
+ }
20
+ });
21
+ Quiz.View = bb.View.extend({
22
+ initialize: function () {
23
+ LP.log('Quiz.View.initialize');
24
+ }
25
+ });
26
+ Quiz.Model = bb.Model.extend({
27
+ questions : null,
28
+ initialize: function () {
29
+ this.questions = new Questions();
30
+ this.questions.add(_.values(this.get('questions')));
31
+ }
32
+ });
33
+ $.extend(LP, {
34
+ Quiz : Quiz,
35
+ $quiz : null,
36
+ _initQuiz: function (args) {
37
+ if (!this.$quiz || this.$quiz.model.get('id') != args.id) {
38
+ delete this.$quiz;
39
+ this.$quiz = new Quiz(args);
40
+ }
41
+ return this.$quiz;
42
+ }
43
+ });
44
+ })(jQuery, Backbone, _);
45
+
assets/js/frontend/bak.single-course.v2.js ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Single course JS
3
+ *
4
+ * @requires jQuery, Backbone
5
+ */
6
+ ;(function ($) {
7
+
8
+ window.LP_V2 = true;
9
+ if (typeof jQuery == 'undefined' || typeof Backbone == 'undefined') {
10
+ console.log('Error');
11
+ return;
12
+ }
13
+
14
+ if (typeof LP == 'undefined') {
15
+ window.LP = {};
16
+ }
17
+
18
+ $.extend(LP, {
19
+ Views: {},
20
+ Model: {}
21
+ });
22
+
23
+ var CourseModel,
24
+ CourseView,
25
+ CourseItem,
26
+ CourseItems;
27
+
28
+ CourseItem = LP.CourseItem = Backbone.Model.extend({
29
+ $doc : false,
30
+ initialize : function () {
31
+ this.$doc = $(document);
32
+ this.on('change', this.onChange);
33
+ _.bindAll(this, 'itemLoaded');
34
+ },
35
+ onChange : function (a, b) {
36
+ var that = this,
37
+ data = {
38
+ item: this
39
+ };
40
+ if (a.changed['current'] !== undefined) {
41
+ $.extend(data, {
42
+ key : 'current',
43
+ value: a.changed['current']
44
+ });
45
+ this.get('el').find('.lp-label-viewing').toggle(a.changed['current']);
46
+ if (this.onChangeCurrent(data) !== false && a.changed['current']) {
47
+ if (that.get('content')) {
48
+ that.itemLoaded.apply(that, [that.get('content')])
49
+ } else {
50
+ if (that.get('type') == 'lp_lesson') {
51
+ $.ajax({
52
+ url : that.get('url'),
53
+ dataType: 'html',
54
+ success : that.itemLoaded
55
+ });
56
+ } else {
57
+ that.itemLoaded()
58
+ }
59
+ }
60
+ }
61
+ }
62
+ },
63
+ onChangeCurrent: function (data) {
64
+ return this.$doc.triggerHandler('learn_press_item_current_changed', data)
65
+ },
66
+ isCurrent : function () {
67
+ return this.get('current') == true;
68
+ },
69
+ itemLoaded : function (response) {
70
+ var $html = $(response);
71
+ this.set('content', response);
72
+ switch (this.get('type')) {
73
+ case 'lp_lesson':
74
+ var $content = $html.find('#learn-press-content-item').html();
75
+ $('#learn-press-content-item').html($content).show();
76
+ break;
77
+ case 'lp_quiz':
78
+ var data = this.$doc.triggerHandler('learn_press_item_redirect_url', {
79
+ url : this.get('url'),
80
+ item: this
81
+ });
82
+ if (data !== false) {
83
+ if (data == undefined || data.redirect == undefined) {
84
+ data.redirect = this.get('url');
85
+ }
86
+ LP.reload(data.redirect);
87
+ }
88
+ break;
89
+ default:
90
+ this._trigger('learn_press_item_' + this.get('type') + '_loaded', {html: $html, item: this});
91
+ }
92
+ try {
93
+ window.wp.mediaelement.initialize();
94
+ } catch (e) {
95
+ }
96
+ this.$doc.triggerHandler('learn_press_item_loaded', {html: $html, item: this});
97
+ },
98
+ _trigger : function () {
99
+ var args = [];
100
+ for (var i = 0, n = arguments.length; i < n; i++) {
101
+ args.push(arguments[i]);
102
+ }
103
+ return this.$doc.triggerHandler.apply(this.$doc[0], args);
104
+ }
105
+ });
106
+
107
+ CourseItems = LP.CourseItems = Backbone.Collection.extend({
108
+ getCurrent: function () {
109
+ var item = this.findWhere({current: true});
110
+ return item;
111
+ },
112
+ setCurrent: function (item) {
113
+ if (!item instanceof CourseItem) {
114
+ item = this.findWhere({id: item});
115
+ }
116
+ this.map(function (item) {
117
+ if (item.get('current')) {
118
+ item.set('current', false);
119
+ }
120
+ });
121
+ if (item) {
122
+ item.set('current', true);
123
+ var _r = $(document).triggerHandler('learn_press_set_course_url', {url: item.get('url')});
124
+ if (_r !== false) {
125
+ if (_r == undefined) {
126
+ _r = item.get('url')
127
+ }
128
+ try {
129
+ LP.setUrl(_r);
130
+ } catch (e) {
131
+ }
132
+ }
133
+ }
134
+ }
135
+ });
136
+
137
+ CourseModel = LP.CourseModel = Backbone.Model.extend({
138
+ items : new CourseItems(),
139
+ initialize: function (args) {
140
+ this.parseItems(args);
141
+ },
142
+ parseItems: function (args) {
143
+ var $items = $('.course-curriculum .course-item');
144
+ _.forEach(args.items, function (item, i) {
145
+ item.el = $items.filter('.course-item-' + item.id);
146
+ this.items.add(new CourseItem(item));
147
+ }, this);
148
+ }
149
+ });
150
+
151
+ CourseView = LP.CourseView = Backbone.View.extend({
152
+ el : 'body',
153
+ events : {
154
+ 'click .button-load-item' : '_loadItem',
155
+ 'click .course-item-nav a': '_loadItemNav',
156
+ 'click .finish-course' : '_finishCourse'
157
+ },
158
+ initialize : function () {
159
+ _.bindAll(this, '_itemChanged', '_itemLoaded');
160
+ this.initEvents();
161
+ this.initCurrent();
162
+ },
163
+ initEvents : function () {
164
+ $(document)
165
+ .on('learn_press_item_current_changed', this._itemChanged)
166
+ .on('learn_press_item_loaded', this._itemLoaded)
167
+
168
+ },
169
+ initCurrent : function () {
170
+ var current = this.model.items.getCurrent();
171
+ if (!current) {
172
+ return;
173
+ }
174
+ current.itemLoaded($("html").html());
175
+ },
176
+ _itemChanged : function (e, data) {
177
+ var that = this;
178
+ switch (data.key) {
179
+ case 'current':
180
+ if (data.value == true) {
181
+ if (data.item.get('type') == 'lp_quiz') {
182
+ data.callback && data.callback();
183
+ return;
184
+ }
185
+ $('#learn-press-content-item').addClass('loading');
186
+ LP.toElement('#learn-press-content-item', {
187
+ delay : 0,
188
+ duration: 0,
189
+ callback: function () {
190
+
191
+ }
192
+ });
193
+ }
194
+ }
195
+ },
196
+ _itemLoaded : function (e, data) {
197
+ $('.course-description-heading, .course-description').hide();
198
+ $('#learn-press-content-item').removeClass('loading');
199
+ return data;
200
+ },
201
+ _loadItem : function (e) {
202
+ e.preventDefault();
203
+ var $tag = $(e.target).closest('.button-load-item');
204
+ if (!$tag.is('a')) {
205
+ return false;
206
+ }
207
+ var id = parseInt($tag.data('id')),
208
+ type = $tag.closest('.course-item').data('type'),
209
+ $item = this.model.items.findWhere({id: id});
210
+ if (!$item) {
211
+ return false;
212
+ }
213
+ if ($item.isCurrent()) {
214
+ return false;
215
+ }
216
+ this.model.items.setCurrent($item);
217
+ },
218
+ _loadItemNav : function (e) {
219
+ e.preventDefault();
220
+
221
+ var id = $(e.target).attr('data-id'),
222
+ $item = this.$('.section-content a.button-load-item[data-id="' + id + '"]');
223
+ $item.trigger('click');
224
+ },
225
+ _finishCourse: function (e) {
226
+
227
+ },
228
+ loadItem : function (item) {
229
+ },
230
+ extend : function (obj) {
231
+ for (var i in obj) {
232
+ this[i] = obj[i];
233
+ }
234
+ return this;
235
+ }
236
+ });
237
+
238
+ $(document).ready(function () {
239
+ if (typeof SingleCourse_Params != 'undefined') {
240
+ LP.Views.Course = new CourseView({
241
+ model: new CourseModel(SingleCourse_Params)
242
+ });
243
+ }
244
+ })
245
+ })(jQuery);
assets/js/frontend/bak.single-quiz.js ADDED
@@ -0,0 +1,731 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ if (typeof LP == 'undefined') var LP = {};
2
+ (function ($) {
3
+ "use strict";
4
+ return;
5
+ var LP_Model_Quiz = window.LP_Model_Quiz = Backbone.Model.extend({
6
+ defaults : {
7
+ //question_id: 0
8
+ },
9
+ data : null,
10
+ view : false,
11
+ url : function () {
12
+ },
13
+ urlRoot : '',
14
+ questions : null,
15
+ initialize : function () {
16
+
17
+ this.createQuestionsList();
18
+
19
+ },
20
+ createQuestionsList: function () {
21
+ this.questions = new LP_Collection_Questions();
22
+ _.each(this.get('questions'), function (args, i) {
23
+ var $model = new LP_Model_Question($.extend({
24
+ quiz_id: this.get('id'),
25
+ user_id: this.get('user_id'),
26
+ }, args));
27
+ $model.urlRoot = this.get('ajaxurl');
28
+ $model.view = this.view;
29
+ this.questions.add($model);
30
+ }, this);
31
+ },
32
+ next : function (callback) {
33
+ if (!this.isLast()) {
34
+ var next_id = this.findNext(),
35
+ question = this.questions.findWhere({id: next_id}),
36
+ that = this;
37
+ question.submit({
38
+ data : {
39
+ save_id : that.get('question_id'),
40
+ question_answer: this.view.$('form').serializeJSON(),
41
+ time_remaining : that.get('time_remaining')
42
+ },
43
+ complete: function () {
44
+ that.set('question_id', next_id);
45
+ $.isFunction(callback) && callback.apply(that);
46
+ LP.Hook.doAction('learn_press_next_question', next_id, that);
47
+ }
48
+ });
49
+ }
50
+ },
51
+ prev : function (callback) {
52
+ if (!this.isFirst()) {
53
+ var prev_id = this.findPrev(),
54
+ question = this.questions.findWhere({id: prev_id}),
55
+ that = this;
56
+ //if (!question.get('content')) {
57
+ question.submit({
58
+ data : {
59
+ save_id : that.get('question_id'),
60
+ question_answer: this.view.$('form').serializeJSON(),
61
+ time_remaining : that.get('time_remaining')
62
+ },
63
+ complete: function () {
64
+ that.set('question_id', prev_id);
65
+ $.isFunction(callback) && callback.apply(that);
66
+ LP.Hook.doAction('learn_press_previous_question', prev_id, that);
67
+ }
68
+ });
69
+
70
+ }
71
+ },
72
+ select : function (id, callback) {
73
+ var question = this.questions.findWhere({id: id}),
74
+ that = this;
75
+ question && question.submit({
76
+ data : {
77
+ save_id : that.get('question_id'),
78
+ question_answer: this.view.$('form').serializeJSON(), //$('input, select, textarea', this.view.$('form')).toJSON(),
79
+ time_remaining : that.get('time_remaining')
80
+ },
81
+ complete: function (response) {
82
+ that.set('question_id', id);
83
+ $.isFunction(callback) && callback.apply(that, [response])
84
+ }
85
+ });
86
+ },
87
+ getQuestionPosition: function (question_id) {
88
+ question_id = question_id || this.get('question_id');
89
+ return _.indexOf(this.getIds(), question_id);
90
+ },
91
+ countQuestions : function () {
92
+ return this.questions.length;
93
+ },
94
+ isLast : function (question_id) {
95
+ question_id = question_id || this.get('question_id');
96
+ return this.getQuestionPosition(question_id) == (this.countQuestions() - 1);
97
+ },
98
+ isFirst : function (question_id) {
99
+ question_id = question_id || this.get('question_id');
100
+ return this.getQuestionPosition(question_id) == 0;
101
+ },
102
+ findNext : function (question_id) {
103
+ question_id = question_id || this.get('question_id');
104
+ var ids = this.getIds(),
105
+ pos = this.getQuestionPosition(question_id);
106
+ pos++;
107
+ if (typeof ids[pos] == 'undefined') return false;
108
+ return ids[pos];
109
+ },
110
+ findPrev : function (question_id) {
111
+ question_id = question_id || this.get('question_id');
112
+ var ids = this.getIds(),
113
+ pos = this.getQuestionPosition(question_id);
114
+ pos--;
115
+ if (typeof ids[pos] == 'undefined') return false;
116
+ return ids[pos];
117
+ },
118
+ current : function () {
119
+ return this.questions.findWhere({id: parseInt(this.get('question_id'))});
120
+ },
121
+ getIds : function () {
122
+ return $.map(this.get('questions'), function (i, v) {
123
+ return parseInt(i.id)
124
+ });
125
+ }
126
+ });
127
+
128
+ var LP_Model_Question = window.LP_Model_Question = Backbone.Model.extend({
129
+ defaults : {
130
+ //question_id: 0
131
+ },
132
+ data : null,
133
+ view : false,
134
+ url : function () {
135
+ return this.urlRoot;
136
+ },
137
+ urlRoot : '',
138
+ initialize: function () {
139
+ },
140
+ element : function () {
141
+ return $(this.get('content'));
142
+ },
143
+ submit : function (args) {
144
+ var that = this;
145
+ args = $.extend({
146
+ complete: null,
147
+ data : {}
148
+ }, args || {});
149
+ this.fetch({
150
+ data : $.extend({
151
+ action : 'learnpress_load_quiz_question',
152
+ user_id : this.get('user_id'),
153
+ quiz_id : this.get('quiz_id'),
154
+ question_id: this.get('id')
155
+ }, args.data || {}),
156
+ complete: (function (e) {
157
+ var response = LP.parseJSON(e.responseText);
158
+ if (response.result == 'success') {
159
+ //if (!that.get('content')) {
160
+ that.set(response.question);
161
+ if (response.permalink) {
162
+ LP.setUrl(response.permalink);
163
+ }
164
+ //}
165
+ $.isFunction(args.complete) && args.complete.call(that, response);
166
+ }
167
+ })
168
+ });
169
+ },
170
+ check : function (args) {
171
+ var that = this;
172
+ if ($.isFunction(args)) {
173
+ args = {
174
+ complete: args
175
+ }
176
+ } else {
177
+ args = $.extend({
178
+ complete: null,
179
+ data : {}
180
+ }, args || {});
181
+ }
182
+ LP.doAjax({
183
+ data : $.extend({
184
+ 'lp-ajax' : 'check-question',
185
+ user_id : this.get('user_id'),
186
+ quiz_id : this.get('quiz_id'),
187
+ question_id : this.get('id'),
188
+ save_id : this.get('id'),
189
+ question_answer: $('form#learn-press-quiz-question').serializeJSON()
190
+ }, args.data || {}),
191
+ success: function (response, raw) {
192
+ that.set('checked', response.checked);
193
+ $.isFunction(args.complete) && args.complete.call(that, response)
194
+ }
195
+ })
196
+ }
197
+ });
198
+
199
+ var LP_Collection_Questions = window.LP_Collection_Questions = Backbone.Collection.extend({
200
+ url : 'admin-ajax.php',
201
+ model: LP_Model_Question
202
+ });
203
+
204
+ var LP_View_Quiz = window.LP_View_Quiz = Backbone.View.extend({
205
+ model : {},
206
+ events : {
207
+ 'click .button-start-quiz' : '_startQuiz',
208
+ 'click .button-finish-quiz' : '_finishQuiz',
209
+ 'click .button-retake-quiz' : '_retakeQuiz',
210
+ 'click .next-question' : '_nextQuestion',
211
+ 'click .prev-question' : '_prevQuestion',
212
+ 'click .check-question' : '_checkQuestion',
213
+ 'click .quiz-questions-list li a': '_selectQuestion',
214
+ 'click .hint-question' : '_hintQuestion',
215
+ 'click .explain-question' : '_explainQuestion'
216
+ },
217
+ el : '.single-quiz',
218
+ isRendered : false,
219
+ $buttons : {},
220
+ initialize : function (model) {
221
+ this.model = model;
222
+ this.model.view = this;
223
+ this.listenTo(this.model, 'change:question_id', this.changeQuestion);
224
+ this.listenTo(this.model, 'change', this.render);
225
+ this.listenTo(this.model, 'change', this.updateCountdown);
226
+
227
+ LP.Hook
228
+ .addAction('learn_press_check_question', function (response, that) {
229
+ that.updateAnswer.apply(that, [response]);
230
+ })
231
+ .addAction('learn_press_update_question_content', function ($newQuestion, $oldQuestion, that) {
232
+ var $current = that.model.current();
233
+ setTimeout(function () {
234
+ if ($current.get('checked')) {
235
+ that.updateAnswer.apply(that, [{checked: $current.get('checked'), result: 'success'}]);
236
+ }
237
+ }, 100)
238
+
239
+ });
240
+ _.bindAll(this, 'render', '_timeOver', '_checkQuestion', '_hintQuestion', 'updateAnswer', 'updateCountdown');
241
+
242
+ this._create();
243
+ this.render();
244
+ this.updateCountdown(true);
245
+ },
246
+ _create : function () {
247
+ this.$buttons = {
248
+ start : this.$('.button-start-quiz'),
249
+ finish : this.$('.button-finish-quiz'),
250
+ retake : this.$('.button-retake-quiz'),
251
+ next : this.$('.next-question'),
252
+ prev : this.$('.prev-question'),
253
+ check : this.$('.check-question'),
254
+ hint : this.$('.hint-question'),
255
+ explain: this.$('.explain-question'),
256
+ };
257
+ if (this.model.get('status') == 'started') {
258
+ this.initCountdown();
259
+
260
+ var $current = this.model.current();
261
+ if ($current) {
262
+ $current.set({
263
+ content: $('#learn-press-quiz-question .question-' + $current.get('id'))
264
+ });
265
+ this._updateQuestion($current.element());
266
+ }
267
+ }
268
+ var that = this;
269
+ this.setButtonsState();
270
+ },
271
+ changeQuestion : function () {
272
+ var $current = this.model.current();
273
+ if ($current) {
274
+ this._updateQuestion($current.element());
275
+ }
276
+ },
277
+ updateCountdown : function (force) {
278
+ if (!this.model.hasChanged('status') && !force) {
279
+ return;
280
+ }
281
+ if (this.model.get('status') == 'started') {
282
+ if (!this.$countdown) {
283
+ this.initCountdown();
284
+ }
285
+ this.$countdown.backward_timer('start');
286
+ }
287
+ },
288
+ render : function () {
289
+ if (!this.model.hasChanged('question_id') && !this.model.hasChanged('status')) {
290
+ //return;
291
+ }
292
+ var $question = this.model.current();
293
+
294
+ this.setButtonsState();
295
+ switch (this.model.get('status')) {
296
+ case 'started':
297
+ this.$('.quiz-intro').remove();
298
+ this.$('.quiz-countdown').removeClass('hide-if-js');
299
+ }
300
+ if ($question && this.model.get('status') == 'started') {
301
+ this.$('form[name="learn-press-quiz-question"]').html($question.get('content'));
302
+ this.$('#learn-press-quiz-questions li[data-id="' + $question.get('id') + '"]')
303
+ .addClass('current')
304
+ .siblings('.current').removeClass('current');
305
+ }
306
+
307
+ this.isRendered = true;
308
+ this.$el.css('visibility', 'visible');
309
+ },
310
+ setButtonsState : function () {
311
+ var hidden = 'hide-if-js',
312
+ current = this.model.current();
313
+ switch (this.model.get('status').toLowerCase()) {
314
+ case 'completed':
315
+ this.$buttons.start.addClass(hidden);
316
+ this.$buttons.finish.addClass(hidden);
317
+ this.$buttons.check.addClass(hidden);
318
+ this.$buttons.retake.removeClass(hidden);
319
+ break;
320
+ case 'started':
321
+ this.$buttons.start.addClass(hidden);
322
+ this.$buttons.finish.removeClass(hidden);
323
+ this.$buttons.retake.addClass(hidden);
324
+
325
+ if (this.model.countQuestions() <= 1) {
326
+ this.$buttons.next.addClass(hidden);
327
+ this.$buttons.prev.addClass(hidden);
328
+ } else {
329
+ this.$buttons.next.removeClass(hidden);
330
+ this.$buttons.prev.removeClass(hidden);
331
+ if (this.model.isLast()) {
332
+ this.$buttons.next.addClass(hidden);
333
+ this.$buttons.finish.filter('[data-area="nav"]').removeClass(hidden);
334
+ } else {
335
+ this.$buttons.finish.filter('[data-area="nav"]').addClass(hidden);
336
+ }
337
+ if (this.model.isFirst()) {
338
+ this.$buttons.prev.addClass(hidden);
339
+ }
340
+ }
341
+ if (current && current.get('check_answer')) {
342
+ this.$buttons.check.removeClass(hidden);
343
+ } else {
344
+ this.$buttons.check.addClass(hidden);
345
+ }
346
+ if (current && current.get('hint')) {
347
+ this.$buttons.hint.removeClass(hidden);
348
+ } else {
349
+ this.$buttons.hint.addClass(hidden);
350
+ }
351
+ if (current && current.get('explanation')) {
352
+ this.$buttons.explain.removeClass(hidden);
353
+ } else {
354
+ this.$buttons.explain.addClass(hidden);
355
+ }
356
+ break;
357
+ default:
358
+ this.$buttons.next.addClass(hidden);
359
+ this.$buttons.prev.addClass(hidden);
360
+ this.$buttons.start.removeClass(hidden);
361
+ this.$buttons.finish.addClass(hidden);
362
+ this.$buttons.retake.addClass(hidden);
363
+ this.$('.quiz-questions .qq.current').removeClass('current');
364
+ }
365
+
366
+ },
367
+ startQuiz : function (args) {
368
+ this.block_page();
369
+ args = $.extend({
370
+ complete: false
371
+ }, args || {});
372
+
373
+ var that = this,
374
+ data = $.extend({
375
+ 'lp-ajax': 'start-quiz',
376
+ quiz_id : this.model.get('id'),
377
+ nonce : this.model.get('nonce')
378
+ }, args.data || {});
379
+ LP.doAjax({
380
+ url : window.location.href,
381
+ data : data,
382
+ success: function (response, raw) {
383
+ LP.MessageBox.hide();
384
+ var response = LP.Hook.applyFilters('learn_press_start_quiz_results', response, that);
385
+ if (response.result == 'success') {
386
+ that.model.current().set(response.question);
387
+ that.model.set({status: response.data.status, question_id: response.question.id});
388
+ LP.setUrl(response.question.permalink);
389
+ }
390
+ $.isFunction(args.complete) && args.complete.call(that, response)
391
+ }
392
+ });
393
+ },
394
+ finishQuiz : function (args) {
395
+ this.pause();
396
+ this.block_page();
397
+ args = $.extend({
398
+ complete: false
399
+ }, args || {});
400
+
401
+ var that = this,
402
+ data = $.extend({
403
+ 'lp-ajax': 'finish-quiz',
404
+ quiz_id : this.model.get('id'),
405
+ nonce : this.model.get('nonce')
406
+ }, args.data || {});
407
+ LP.doAjax({
408
+ data : data,
409
+ success: function (response) {
410
+ var callbackReturn = undefined;
411
+ $.isFunction(args.complete) && ( callbackReturn = args.complete.call(LP.Quiz, response) );
412
+ LP.Hook.doAction('learn_press_finish_quiz', that.model.get('id'), that);
413
+ LP.MessageBox.show(single_quiz_localize.finished_quiz, {
414
+ autohide: 2000,
415
+ onHide : function () {
416
+ if (callbackReturn && callbackReturn.redirect) {
417
+ LP.reload(callbackReturn.redirect);
418
+ } else if (callbackReturn == undefined && response.redirect) {
419
+ LP.reload(response.redirect);
420
+ }
421
+ }
422
+ });
423
+ }
424
+ });
425
+ },
426
+ retakeQuiz : function (args) {
427
+ this.block_page();
428
+ args = $.extend({
429
+ complete: false
430
+ }, args || {});
431
+
432
+ var that = this,
433
+ data = $.extend({
434
+ 'lp-ajax': 'retake-quiz',
435
+ quiz_id : this.model.get('id'),
436
+ nonce : this.model.get('nonce')
437
+ }, args.data || {});
438
+ LP.doAjax({
439
+ data : data,
440
+ success: function (response, raw) {
441
+ LP.MessageBox.hide();
442
+ if (response.result == 'success') {
443
+ $.isFunction(args.complete) && args.complete.call(LP.Quiz, response);
444
+ LP.MessageBox.show(single_quiz_localize.retaken_quiz, {
445
+ autohide: 2000,
446
+ onHide : function () {
447
+ LP.reload(response.redirect);
448
+ }
449
+ });
450
+ } else {
451
+ LP.alert(response.message);
452
+ }
453
+ }
454
+ });
455
+ },
456
+ updateAnswer : function (response) {
457
+ if (!response || response.result != 'success') {
458
+ return;
459
+ }
460
+ var $current = this.model.current(),
461
+ $content = $($current.get('content'));
462
+ switch ($current.get('type')) {
463
+ case 'true_or_false':
464
+ case 'single_choice':
465
+ case 'multi_choice':
466
+ $.each(response.checked, function (k, v) {
467
+ var $input = $content.find('input[value="' + v.value + '"]'),
468
+ $li = $input.closest('li').removeClass('answer-true user-answer-false');
469
+ if (v.is_true == 'yes') {
470
+ $li.addClass('answer-true')
471
+ }
472
+ if (response.answered) {
473
+ if (typeof response.answered == 'string') {
474
+ if (response.answered == v.value) {
475
+ $input.prop('checked', true);
476
+ }
477
+ } else if ($.inArray(v.value, response.answered) != -1) {
478
+ $input.prop('checked', true);
479
+ }
480
+ }
481
+ if ($input.is(':checked') && v.is_true == 'yes') {
482
+ } else {
483
+ $li.addClass('user-answer-false');
484
+ }
485
+
486
+ });
487
+ $content.addClass('checked').find('input, select, textarea').prop('disabled', true);
488
+ $current.set({
489
+ content: $content
490
+ });
491
+ }
492
+ //LP.Hook.doAction('learn_press_check_question', response, $current);
493
+ this.render();
494
+ },
495
+ _checkQuestion : function () {
496
+ if (LP.Hook.applyFilters('learn_press_before_check_question', true, this) !== false) {
497
+ var that = this;
498
+ this.$buttons.next.prop('disabled', true);
499
+ this.$buttons.prev.prop('disabled', true);
500
+ this.$buttons.finish.prop('disabled', true);
501
+ this.$buttons.check.prop('disabled', true);
502
+ this.pause();
503
+ this.block_page();
504
+ this.model.current().check({
505
+ complete: function (response) {
506
+ that.$buttons.next.prop('disabled', false);
507
+ that.$buttons.prev.prop('disabled', false);
508
+ that.$buttons.finish.prop('disabled', false);
509
+ that.$buttons.check.prop('disabled', false);
510
+ LP.Hook.doAction('learn_press_check_question', response, that);
511
+ that.resume();
512
+ },
513
+ data : {nonce: this.model.get('nonce')}
514
+ });
515
+ }
516
+ },
517
+ _hintQuestion : function (e) {
518
+ e.preventDefault();
519
+ var current = this.model.current();
520
+ if (current && current.get('hint')) {
521
+ $('#learn-press-question-hint-' + current.get('id')).toggleClass('hide-if-js')
522
+ }
523
+
524
+ },
525
+ _explainQuestion: function (e) {
526
+ e.preventDefault();
527
+ var current = this.model.current();
528
+ if (current && current.get('explanation')) {
529
+ $('#learn-press-question-explanation-' + current.get('id')).toggleClass('hide-if-js')
530
+ }
531
+
532
+ },
533
+ _nextQuestion : function () {
534
+ if (LP.Hook.applyFilters('learn_press_before_next_question', true, this) !== false) {
535
+ var that = this;
536
+ this.$buttons.next.prop('disabled', true);
537
+ this.$buttons.prev.prop('disabled', true);
538
+ this.$buttons.finish.prop('disabled', true);
539
+ this.pause();
540
+ this.block_page();
541
+ this.model.next(function () {
542
+ that.$buttons.next.prop('disabled', false);
543
+ that.$buttons.prev.prop('disabled', false);
544
+ that.$buttons.finish.prop('disabled', false);
545
+ });
546
+ }
547
+ },
548
+ _prevQuestion : function () {
549
+ if (LP.Hook.applyFilters('learn_press_before_prev_question', true, this) !== false) {
550
+ var that = this;
551
+ this.$buttons.next.prop('disabled', true);
552
+ this.$buttons.prev.prop('disabled', true);
553
+ this.$buttons.finish.prop('disabled', true);
554
+ this.pause();
555
+ this.block_page();
556
+ this.model.prev(function () {
557
+ that.$buttons.next.prop('disabled', false);
558
+ that.$buttons.prev.prop('disabled', false);
559
+ that.$buttons.finish.prop('disabled', false);
560
+ });
561
+ }
562
+ },
563
+ _selectQuestion : function (e) {
564
+ e.preventDefault();
565
+ var that = this,
566
+ id = $(e.target).closest('.learn-press-question-wrap').data('id');
567
+ if (this.model.get('status') != 'started') {
568
+ return false;
569
+ }
570
+ if (LP.Hook.applyFilters('learn_press_before_select_question', true, that) !== false) {
571
+ this.pause();
572
+ this.$buttons.next.prop('disabled', true);
573
+ this.$buttons.prev.prop('disabled', true);
574
+ this.$buttons.finish.prop('disabled', true);
575
+ this.pause();
576
+ this.model.select(id, function (response) {
577
+ LP.Hook.doAction('learn_press_selected_question', id, that);
578
+ that.$buttons.next.prop('disabled', false);
579
+ that.$buttons.prev.prop('disabled', false);
580
+ that.$buttons.finish.prop('disabled', false);
581
+ });
582
+ }
583
+ },
584
+ _getNonce : function (field) {
585
+ return this.$('input#' + field + '-nonce').val();
586
+ },
587
+ _startQuiz : function () {
588
+ var that = this;
589
+ if (LP.Hook.applyFilters('learn_press_before_start_quiz', true, that) !== false) {
590
+ that.$buttons.next.prop('disabled', true);
591
+ that.$buttons.prev.prop('disabled', true);
592
+ that.$buttons.finish.prop('disabled', true);
593
+ LP.MessageBox.blockUI();
594
+ that.startQuiz({
595
+ complete: function (response) {
596
+ LP.MessageBox.hide();
597
+ if (response.message) {
598
+ LP.alert(response.message, function () {
599
+ if (response.redirect) {
600
+ LP.reload(response.redirect)
601
+ }
602
+ });
603
+ } else {
604
+ if (response.redirect) {
605
+ LP.reload(response.redirect)
606
+ }
607
+ }
608
+ that.$buttons.next.prop('disabled', false);
609
+ that.$buttons.prev.prop('disabled', false);
610
+ that.$buttons.finish.prop('disabled', false);
611
+ LP.Hook.doAction('learn_press_start_quiz', response, that);
612
+ }
613
+ });
614
+ }
615
+ },
616
+ _retakeQuiz : function () {
617
+ var that = this;
618
+ if (LP.Hook.applyFilters('learn_press_before_retake_quiz', true, that) !== false) {
619
+ LP.confirm(single_quiz_localize.confirm_retake_quiz, function (confirm) {
620
+ if (!confirm) {
621
+ return;
622
+ }
623
+ that.$buttons.retake.prop('disabled', true);
624
+ LP.MessageBox.blockUI();
625
+ that.retakeQuiz({
626
+ complete: function (response) {
627
+ LP.MessageBox.hide();
628
+ LP.Hook.doAction('learn_press_user_retaken_quiz', response, that);
629
+ }
630
+ });
631
+ })
632
+ }
633
+ },
634
+ _finishQuiz : function () {
635
+ var that = this;
636
+ if (LP.Hook.applyFilters('learn_press_before_finish_quiz', true, that) !== false) {
637
+ LP.confirm(single_quiz_localize.confirm_finish_quiz, function (confirm) {
638
+ if (!confirm) {
639
+ return;
640
+ }
641
+ that.$buttons.next.prop('disabled', true);
642
+ that.$buttons.prev.prop('disabled', true);
643
+ that.$buttons.finish.prop('disabled', true);
644
+ LP.MessageBox.blockUI();
645
+ that.finishQuiz({
646
+ data : {
647
+ save_id : that.model.get('question_id'),
648
+ question_answer: that.$('form').serializeJSON(),
649
+ time_remaining : that.model.get('time_remaining')
650
+ },
651
+ complete: function (response) {
652
+ LP.MessageBox.hide();
653
+ LP.Hook.doAction('learn_press_user_finished_quiz', response, that);
654
+ }
655
+ });
656
+ });
657
+ }
658
+ },
659
+ _updateQuestion : function ($newQuestion) {
660
+ var $container = this.$('.quiz-question-content form'),
661
+ $oldQuestion = $container.find('.learn-press-question-wrap');
662
+ if ($oldQuestion.length) {
663
+ $oldQuestion.replaceWith($newQuestion);
664
+ } else {
665
+ $container.append($newQuestion);
666
+ }
667
+ LP.Hook.doAction('learn_press_update_question_content', $newQuestion, $oldQuestion, this);
668
+ LP.setUrl($newQuestion.find('input[name="learn-press-question-permalink"]').val());
669
+
670
+ },
671
+ initCountdown : function () {
672
+ var that = this,
673
+ $countdown = this.$countdown;
674
+ if (!$countdown) {
675
+ this.$countdown = $("#quiz-countdown-value");
676
+ this.$countdown.backward_timer({
677
+ seconds : parseInt(this.model.get('time_remaining')),
678
+ format : that.model.get('time_format'),
679
+ on_exhausted: function (timer) {
680
+ that._timeOver(timer)
681
+ },
682
+ on_tick : function (timer) {
683
+ var color = (timer.seconds_left <= 5) ? "#F00" : "";
684
+ if (color) timer.target.css('color', color);
685
+ //that.model.set('time_remaining', timer.seconds_left);
686
+ }
687
+ });
688
+ }
689
+ },
690
+ pause : function () {
691
+ this.$countdown.backward_timer('cancel');
692
+ },
693
+ resume : function () {
694
+ this.$countdown.backward_timer('start');
695
+ },
696
+ loadPage : function (url) {
697
+ url = url || window.location.href;
698
+ window.location.href = url;
699
+ },
700
+ _timeOver : function (timer) {
701
+ timer.target.css('color', '#F00');
702
+ LP.MessageBox.blockUI(single_quiz_localize.quiz_time_is_over_message);
703
+ this.finishQuiz({
704
+ complete: function (response) {
705
+ LP.MessageBox.hide();
706
+ if (response.redirect) {
707
+ LP.reload(response.redirect);
708
+ }
709
+ }
710
+ });
711
+ },
712
+ block_page : function () {
713
+ //this.$el.block_ui();
714
+ },
715
+ unblock_page : function () {
716
+ //this.$el.unblock_ui();
717
+ }
718
+ });
719
+ LP.Quiz = {
720
+ init: function (data) {
721
+ var model = new LP_Model_Quiz(data);
722
+ new LP_View_Quiz(model);
723
+ }
724
+ }
725
+
726
+
727
+ $(document).ready(function () {
728
+ var json = JSON.stringify(single_quiz_params);
729
+ LP.Quiz.init(single_quiz_params);
730
+ })
731
+ })(jQuery);
assets/js/frontend/checkout.js CHANGED
@@ -1,140 +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-place-order'),
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
- LP.blockContent();
88
- $.ajax({
89
- url : LP_Settings.siteurl + '/?lp-ajax=checkout',
90
- dataType: 'html',
91
- data : $form.serialize(),
92
- type : 'post',
93
- success : function (response) {
94
- response = LP.parseJSON(response);
95
- if (response.result === 'fail') {
96
- var $error = '';
97
- if (!response.messages) {
98
- if (response.code && response.code == 30) {
99
- LP.Checkout.showErrors('<div class="learn-press-error">' + learn_press_js_localize.invalid_field + '</div>');
100
- } else {
101
- LP.Checkout.showErrors('<div class="learn-press-error">' + learn_press_js_localize.unknown_error + '</div>');
102
- }
103
- } else {
104
- LP.Checkout.showErrors(response.messages);
105
- }
106
-
107
- } else if (response.result === 'success') {
108
- if (response.redirect) {
109
- $place_order.val('Redirecting');
110
- LP.reload(response.redirect);
111
- return;
112
- }
113
- }
114
- $place_order.val(text);
115
- $place_order.prop('disabled', false);
116
- LP.unblockContent();
117
- },
118
- error : function (jqXHR, textStatus, errorThrown) {
119
- LP.Checkout.showErrors('<div class="learn-press-error">' + errorThrown + '</div>');
120
- $place_order.val(text);
121
- $place_order.prop('disabled', false);
122
- LP.unblockContent();
123
- }
124
- });
125
- }
126
- return false;
127
- },
128
- showErrors : function (messages) {
129
- $('.learn-press-error, .learn-press-notice, .learn-press-message').remove();
130
- this.$form.prepend(messages);
131
- $('html, body').animate({
132
- scrollTop: ( LP.Checkout.$form.offset().top - 100 )
133
- }, 1000);
134
- $(document).trigger('learnpress_checkout_error');
135
- }
136
- };
137
- $(document).ready(function () {
138
- LP.Checkout.init();
139
- });
140
  })(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/course-filters.js DELETED
@@ -1,146 +0,0 @@
1
- ;(function ($) {
2
- "use strict";
3
- $.fn.courseFilters = function (options) {
4
- return $.each(this, function () {
5
- var defaults = {
6
- attribute_operator: 'and',
7
- value_operator : 'and',
8
- ajax_filter : 1,
9
- button_filter : 1
10
- },
11
- $widget = $(this),
12
- widgetID = $widget.attr('id'),
13
- filterUrl = window.location.href.addQueryVar('course-filter', 'yes'),
14
- oldFilterUrl = filterUrl,
15
- $buttonFilter = $widget.find('.lp-button-filter'),
16
- $buttonReset = $widget.find('.lp-button-reset-filter');
17
- options = $.extend({}, defaults, options || {});
18
-
19
- filterUrl = filterUrl
20
- .addQueryVar('attribute_operator', options.attribute_operator)
21
- .addQueryVar('value_operator', options.value_operator);
22
- function addAttribute(attribute, value) {
23
- var attributes = filterUrl.getQueryVar(attribute);
24
- if (!attributes) {
25
- attributes = value;
26
- } else {
27
- if (attributes.indexOf(value) == -1) {
28
- attributes += ',' + value;
29
- }
30
- }
31
- filterUrl = filterUrl.addQueryVar(attribute, attributes);
32
- return filterUrl;
33
- }
34
-
35
- function removeAttribute(attribute, value) {
36
- var attributes = filterUrl.getQueryVar(attribute);
37
- if (attributes) {
38
- attributes = attributes.replace(value, '').split(',').filter(function (a, b) {
39
- return a + '' !== '';
40
- }).join(',');
41
- if (attributes) {
42
- filterUrl = filterUrl.addQueryVar(attribute, attributes);
43
- } else {
44
- filterUrl = filterUrl.removeQueryVar(attribute);
45
- }
46
- }
47
- return filterUrl;
48
- }
49
-
50
- function hasFiltered() {
51
- return $('#' + widgetID + ' .lp-course-attribute-values li.active').length;
52
- }
53
-
54
- function validateUrl(url) {
55
- // remove paged in query
56
- url = url.replace(/\/page\/[0-9]+/, '').removeQueryVar('paged');
57
- return url;
58
- }
59
-
60
- function doFilter() {
61
- filterUrl = validateUrl(filterUrl);
62
- if (oldFilterUrl == filterUrl) {
63
- return;
64
- }
65
- var useAjax = $widget.find('.lp-course-attributes.course-filters').data('ajax') == 'yes';
66
- if (useAjax) {
67
- LP.setUrl(filterUrl);
68
- LP.blockContent();
69
- $.ajax({
70
- url : filterUrl,
71
- success: function (res) {
72
- var $html = $(res).contents(),
73
- $newContent = $html.find('.entry-content'),
74
- $newWidget = $html.find('#' + widgetID);
75
- $('.entry-content').replaceWith($newContent);
76
- $('#' + widgetID).replaceWith($newWidget);
77
- LP.unblockContent();
78
- }
79
- });
80
- } else {
81
- LP.reload(filterUrl);
82
- }
83
- oldFilterUrl = filterUrl;
84
- $buttonFilter.prop('disabled', true);
85
- }
86
-
87
- function toggleControls() {
88
- filterUrl = validateUrl(filterUrl);
89
- var url = filterUrl;
90
- if (!hasFiltered()) {
91
- url = url
92
- .removeQueryVar('attribute_operator')
93
- .removeQueryVar('value_operator')
94
- .removeQueryVar('course-filter');
95
- }
96
- if ($buttonFilter.length == 0) {
97
- doFilter();
98
- } else {
99
- if (filterUrl == oldFilterUrl) {
100
- $buttonFilter.prop('disabled', true);
101
- } else {
102
- $buttonFilter.prop('disabled', false);
103
- }
104
- $buttonReset.prop('disabled', !hasFiltered());
105
- }
106
- LP.setUrl(url);
107
- }
108
-
109
- if ($buttonFilter.length) {
110
- $buttonFilter.off('click').on('click', function () {
111
- doFilter()
112
- })
113
- }
114
- $buttonReset.off('click').on('click', function () {
115
- $('#' + widgetID + ' .lp-course-attribute-values li.active a').each(function () {
116
- var $this = $(this),
117
- $li = $this.parent(),
118
- $attribute = $li.closest('.lp-course-attribute-values').parent(),
119
- attribute = $attribute.data('attribute'),
120
- value = $li.data('value');
121
- $li.removeClass('active');
122
- filterUrl = filterUrl.removeQueryVar(attribute);
123
- });
124
- $(this).prop('disabled', true);
125
- toggleControls();
126
- })
127
- $(document)
128
- .off('click', '#' + widgetID + ' .lp-course-attribute-values a')
129
- .on('click', '#' + widgetID + ' .lp-course-attribute-values a', function (e) {
130
- e.preventDefault();
131
- var $this = $(this),
132
- $li = $this.parent(),
133
- $attribute = $li.closest('.lp-course-attribute-values').parent(),
134
- attribute = $attribute.data('attribute'),
135
- value = $li.data('value');
136
- $li.toggleClass('active');
137
- if ($li.hasClass('active')) {
138
- filterUrl = addAttribute(attribute, value);
139
- } else {
140
- filterUrl = removeAttribute(attribute, value);
141
- }
142
- toggleControls();
143
- });
144
- });
145
- }
146
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/js/frontend/course_coming_soon.js ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ( function ( $ ) {
2
+ $.fn.lp_course_countdown = function () {
3
+ var countdowns = this;
4
+
5
+ for ( var i = 0; i < countdowns.length; i++ ) {
6
+ var _countdown = $( countdowns[i] ),
7
+ speed = _countdown.attr( 'data-speed' ),
8
+ // gmt = _countdown.attr( 'data-gmt' ),
9
+ time = _countdown.attr( 'data-time' ),
10
+ showtext = _countdown.attr( 'data-showtext' )
11
+ expiryDate = new Date( time ),
12
+ gmt = -expiryDate.getTimezoneOffset() / 60;
13
+
14
+ var options = {
15
+ expiryDate: expiryDate,
16
+ speed: speed ? speed : 500,
17
+ gmt: parseFloat( gmt ),
18
+ showText: parseInt( showtext ),
19
+ };
20
+ _countdown.mbComingsoon( options );
21
+ }
22
+ }
23
+
24
+ $( document ).ready( function () {
25
+ $( '.learnpress-course-coming-soon' ).lp_course_countdown();
26
+ } );
27
+
28
+ } )( jQuery );
assets/js/frontend/course_coming_soon.min.js ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ( function ( $ ) {
2
+ $.fn.lp_course_countdown = function () {
3
+ var countdowns = this;
4
+
5
+ for ( var i = 0; i < countdowns.length; i++ ) {
6
+ var _countdown = $( countdowns[i] ),
7
+ speed = _countdown.attr( 'data-speed' ),
8
+ // gmt = _countdown.attr( 'data-gmt' ),
9
+ time = _countdown.attr( 'data-time' ),
10
+ showtext = _countdown.attr( 'data-showtext' )
11
+ expiryDate = new Date( time ),
12
+ gmt = -expiryDate.getTimezoneOffset() / 60;
13
+
14
+ var options = {
15
+ expiryDate: expiryDate,
16
+ speed: speed ? speed : 500,
17
+ gmt: parseFloat( gmt ),
18
+ showText: parseInt( showtext ),
19
+ };
20
+ _countdown.mbComingsoon( options );
21
+ }
22
+ }
23
+
24
+ $( document ).ready( function () {
25
+ $( '.learnpress-course-coming-soon' ).lp_course_countdown();
26
+ } );
27
+
28
+ } )( jQuery );
assets/js/frontend/learnpress.js CHANGED
@@ -22,7 +22,7 @@
22
  window.location.href = url;
23
  },
24
  parseJSON : function (data) {
25
- var m = data.match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/);
26
  try {
27
  if (m) {
28
  data = $.parseJSON(m[1]);
@@ -30,6 +30,7 @@
30
  data = $.parseJSON(data);
31
  }
32
  } catch (e) {
 
33
  data = {};
34
  }
35
  return data;
22
  window.location.href = url;
23
  },
24
  parseJSON : function (data) {
25
+ var m = data.match(/<!-- LP_AJAX_START -->(.*)<!-- LP_AJAX_END -->/);
26
  try {
27
  if (m) {
28
  data = $.parseJSON(m[1]);
30
  data = $.parseJSON(data);
31
  }
32
  } catch (e) {
33
+ LP.log(e);
34
  data = {};
35
  }
36
  return data;
assets/js/frontend/lesson.js CHANGED
@@ -42,7 +42,7 @@
42
  security = $button.data('security'),
43
  $item = $button.closest('.course-item');
44
  windowTarget.LP.blockContent();
45
- /*return;
46
  this.complete({
47
  security : security,
48
  course_id : this.model.get('courseId'),
@@ -55,7 +55,10 @@
55
  item.$el.removeClass('focus off');
56
  }, 3000, item);
57
 
58
-
 
 
 
59
  windowTarget.LP.setUrl(that.model.get('permalink'));
60
  var data = response.course_result;
61
  data.messageType = 'update-course';
@@ -63,7 +66,7 @@
63
  }
64
  windowTarget.LP.unblockContent();
65
  }
66
- });*/
67
  },
68
  complete : function (args) {
69
  var that = this;
42
  security = $button.data('security'),
43
  $item = $button.closest('.course-item');
44
  windowTarget.LP.blockContent();
45
+ return;
46
  this.complete({
47
  security : security,
48
  course_id : this.model.get('courseId'),
55
  item.$el.removeClass('focus off');
56
  }, 3000, item);
57
 
58
+ /*that.$('.learn-press-course-results-progress').replaceWith($(response.html.progress));
59
+ $section.find('.section-header').replaceWith($(response.html.section_header));
60
+ that.$('.learn-press-course-buttons').replaceWith($(response.html.buttons));
61
+ that.currentItem.set('content', $(response.html.content))*/
62
  windowTarget.LP.setUrl(that.model.get('permalink'));
63
  var data = response.course_result;
64
  data.messageType = 'update-course';
66
  }
67
  windowTarget.LP.unblockContent();
68
  }
69
+ });
70
  },
71
  complete : function (args) {
72
  var that = this;
assets/js/frontend/profile.js CHANGED
@@ -1,316 +1,552 @@
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
- })(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,923 +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
- $.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
- var qlenght = this.model.questions.length;
717
- this.model.questions.forEach(function (m) {
718
- var $content = m.get('response');
719
- if (!$content) {
720
- return;
721
- }
722
- var $question = '';
723
- if( qlenght === 1 ) {
724
- var $question = jQuery('#'+$content.attr('id')+' .quiz-question-content').clone().hide();
725
- } else {
726
- var $question = $content.find('.quiz-question-content').clone().hide();
727
- }
728
- $form.append($question);
729
- });
730
- $form.find('input[name="security"]').val(args.security);
731
- $form.find('input[name="lp-ajax"]').val(args.action);
732
- var extraArgs = _.omit(args, ['security', 'action']);
733
- _.forEach(extraArgs, function (v, k) {
734
- $form.append('<input type="hidden" name="' + k + '" value="' + v + '" />');
735
- });
736
- $form.submit();
737
- },
738
- _confirm : function (localize, onYes, onNo) {
739
- var that = this,
740
- loc = this.localized[localize] || {},
741
- message = loc.message || '',
742
- title = loc.title || '';
743
- windowTarget.jConfirm(message, title, function (confirm) {
744
- if (confirm && $.isFunction(onYes)) {
745
- onYes.call(that);
746
- } else if ($.isFunction(onNo)) {
747
- onNo.call(that);
748
- }
749
- });
750
- },
751
- _startQuiz : function (e) {
752
- var that = this,
753
- $button = $(e.target);
754
- windowTarget.LP.Hook.doAction('learn_press_before_start_quiz', this);
755
- this._submit($button.data());
756
- return false;
757
- },
758
- _finishQuiz : function (e) {
759
- var that = this,
760
- $button = $(e.target);
761
- e.preventDefault();
762
- if (typeof e.originalEvent === 'undefined') {
763
- windowTarget.LP.Hook.doAction('learn_press_before_finish_quiz', this);
764
- that._submit($.extend($button.data(), {auto_finish: 'yes'}));
765
- } else {
766
- this._confirm('confirm_finish_quiz', function () {
767
- windowTarget.LP.Hook.doAction('learn_press_before_finish_quiz', this);
768
- that._submit($button.data());
769
- });
770
- }
771
- return false;
772
- },
773
- _doFinishQuiz : function (security) {
774
- var that = this;
775
- LP.Hook.doAction('learn_press_before_finish_quiz', that.currentItem, that);
776
- that.finishQuiz({
777
- security : security,
778
- beforeSend: windowTarget.LP.blockContent(),
779
- callback : function (response, item) {
780
- windowTarget.LP.unblockContent();
781
- that.$('#learn-press-content-item').html(response.html.content);
782
- windowTarget.LP.setUrl(that.model.get('permalink'));
783
- var data = response.course_result;
784
- data.messageType = 'update-course';
785
- LP.sendMessage(data, windowTarget);
786
- }
787
- });
788
- },
789
- _retakeQuiz : function (e) {
790
- e.preventDefault();
791
- var that = this,
792
- $button = $(e.target);
793
- this._confirm('confirm_retake_quiz', function () {
794
- LP.Hook.doAction('learn_press_before_retake_quiz', this);
795
- that._submit($button.data());
796
- });
797
- return false;
798
- },
799
-
800
- complete : function (args) {
801
- var that = this;
802
- args = $.extend({
803
- context : null,
804
- callback: null,
805
- format : 'json'
806
- }, this.toJSON(), args || {});
807
- var data = {};
808
-
809
- // Omit unwanted fields
810
- _.forEach(args, function (v, k) {
811
- if (($.inArray(k, ['content', 'current', 'title', 'url']) == -1) && !$.isFunction(v)) {
812
- data[k] = v;
813
- }
814
- ;
815
- });
816
- LP.ajax({
817
- url : this.get('url'),
818
- action : 'complete-item',
819
- data : data,
820
- dataType: 'json',
821
- success : function (response) {
822
- ///response = LP.parseJSON(response);
823
- LP.Hook.doAction('learn_press_course_item_completed', response, that);
824
- response = LP.Hook.applyFilters('learn_press_course_item_complete_response', response, that);
825
- $.isFunction(args.callback) && args.callback.call(args.context, response, that);
826
- }
827
- });
828
- },
829
- startQuiz : function (args) {
830
- var args = $.extend({
831
- course_id: this.model.get('courseId'),
832
- quiz_id : this.model.get('id'),
833
- security : null
834
- }, args || {});
835
- var data = this._validateObject(args), that = this;
836
- LP.ajax({
837
- url : this.model.get('url'),
838
- action : 'start-quiz',
839
- data : data,
840
- dataType: 'json',
841
- success : function (response) {
842
- $.isFunction(args.callback) && args.callback.call(args.context, response, that);
843
- }
844
- });
845
- },
846
- finishQuiz : function (args) {
847
- var args = $.extend({
848
- course_id: this.model.get('courseId'),
849
- quiz_id : this.model.get('id'),
850
- security : null
851
- }, args || {});
852
- var data = this._validateObject(args), that = this;
853
- data = LP.Hook.applyFilters('learn_press_finish_quiz_data', data);
854
- var beforeSend = args.beforeSend || function () {
855
- };
856
- LP.ajax({
857
- url : this.model.get('url'),
858
- action : 'finish-quiz',
859
- data : data,
860
- dataType : 'json',
861
- beforeSend: beforeSend,
862
- success : function (response) {
863
- windowTarget.LP.unblockContent();
864
- $.isFunction(args.callback) && args.callback.call(args.context, response, that);
865
- }
866
- });
867
- },
868
- retakeQuiz : function (args) {
869
- var args = $.extend({
870
- course_id: this.model.get('courseId'),
871
- quiz_id : this.model.get('id'),
872
- security : null
873
- }, args || {});
874
- var data = this._validateObject(args), that = this;
875
- LP.ajax({
876
- url : this.model.get('url'),
877
- action : 'retake-quiz',
878
- data : data,
879
- dataType : 'json',
880
- beforeSend: function () {
881
- windowTarget.LP.blockContent();
882
- },
883
- success : function (response) {
884
- windowTarget.LP.unblockContent();
885
- $.isFunction(args.callback) && args.callback.call(args.context, response, that);
886
- }
887
- });
888
- },
889
- _click_nav_link: function ( e ) {
890
- e.preventDefault();
891
- var $button = $(e.target);
892
- var lesson_id = '';
893
- if($button.prop("tagName").toLowerCase()!='a'){
894
- lesson_id = $button.parent().attr('data-id');
895
- } else {
896
- lesson_id = $($button).attr('data-id');
897
- }
898
- $(windowTarget.document).find('.course-item.course-item-'+lesson_id+'.viewable').trigger('click');
899
- },
900
- _toJSON : function () {
901
- // call parent method
902
- var json = Course_Item.__super__.toJSON.apply(this, arguments);
903
- },
904
- _validateObject: function (obj) {
905
- var ret = {};
906
- for (var i in obj) {
907
- if (!$.isFunction(obj[i])) {
908
- ret[i] = obj[i];
909
- }
910
- }
911
- return ret;
912
- }
913
- });
914
-
915
- window.LP_Quiz = Quiz;
916
- $(document).ready(function () {
917
- if (typeof LP_Quiz_Params != 'undefined') {
918
- window.$LP_Quiz = new LP_Quiz($.extend({course: LP.$LP_Course}, LP_Quiz_Params));
919
- }
920
- windowTarget.LP.unblockContent();
921
- });
922
-
923
  })(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/frontend/single-course.js CHANGED
@@ -44,13 +44,6 @@ if (typeof LearnPress === 'undefined') {
44
  },
45
  _changeCurrent : function (m) {
46
 
47
- },
48
- get : function () {
49
- var val = Course_Item.__super__.get.apply(this, arguments);
50
- if (arguments[0] == 'url') {
51
- val = LP_Course_Params.root_url + val;
52
- }
53
- return val;
54
  },
55
  request : function (args) {
56
  var that = this;
@@ -282,7 +275,9 @@ if (typeof LearnPress === 'undefined') {
282
  LP.Hook.addAction('learn_press_receive_message', this.receiveMessage);
283
  if (typeof localStorage != 'undefined') {
284
  var expanded = localStorage.getItem("lp-item-expanded");
285
- if (expanded == 'yes') {
 
 
286
  this.expand(true);
287
  }
288
  }
@@ -301,43 +296,24 @@ if (typeof LearnPress === 'undefined') {
301
  sections = {},
302
  $progress = this.$('.course-progress').find('.number, .percentage-sign'),
303
  $itemProgress = this.$('.items-progress').find('.number, .percentage-sign');
304
-
305
- if ($progress.length == 0) {
306
- return;
307
- }
308
-
309
- $progress[0].childNodes[0].nodeValue = parseInt(data.results);
310
-
311
- this.$('.course-progress .lp-progress-value').width(parseInt(data.results) + '%');
312
  data.items && data.items.forEach(function (item) {
313
- var $item = this.$('.course-item.course-item-' + item.id),
314
- $status = $item.find('.item-status'),
315
- statusClass = ($status[0].className + '').replace(/(item-status-[^\s]*)/g, '').trim();
316
  if (!sections[item.section_id]) {
317
  sections[item.section_id] = [0, 0];
318
  }
319
- if (item.status) {
320
- statusClass += ' item-status-' + item.status;
321
- }
322
  if (item.status === 'completed') {
 
323
  $item.addClass('item-has-status item-completed');
 
324
  } else if (item.status) {
325
  $item.addClass('item-has-status').removeClass('item-completed');
326
  } else {
327
  $item.removeClass('item-has-status').removeClass('item-completed');
328
  }
329
-
330
  if (item.type === 'lp_quiz') {
331
- $item.find('.item-result').html(LP.Hook.applyFilters('item_result_text', item.results));
332
- }
333
- $status[0].className = statusClass;
334
- if ($.inArray(item.status, ['completed', 'failed', 'passed']) != -1) {
335
- sections[item.section_id][1]++;
336
- }
337
- if (item.status && item.status != 'viewed') {
338
- $item.addClass('item-has-result');
339
- } else {
340
- $item.removeClass('item-has-result');
341
  }
342
  sections[item.section_id][0]++;
343
  }, this);
@@ -348,18 +324,11 @@ if (typeof LearnPress === 'undefined') {
348
  if (!data) {
349
  return;
350
  }
351
- itemsCompleted += data[1];
352
  $section.find('.section-header span.step').html(LP.Hook.applyFilters('section_header_span_text', data[1] + '/' + data[0]));
353
  });
354
  $itemProgress.eq(0).html(data.completed_items_text.replace('%d', itemsCompleted).replace('%d', itemsCount));
355
  var passingCondition = parseInt(this.$('.course-progress .lp-course-progress').data('passing-condition'));
356
- if (data.grade) {
357
- var $grade = this.$('.grade').html(data.grade_html),
358
- gradeClass = $grade[0].className.replace(/passed|failed|in-progress/, '') + ' ' + data.grade;
359
- $grade[0].className = gradeClass;
360
- }
361
  this.$('.button-finish-course').toggleClass('hide-if-js', !(data.results >= passingCondition));
362
-
363
  if (data.setUrl) {
364
  LP.setUrl(data.setUrl);
365
  }
@@ -396,6 +365,7 @@ if (typeof LearnPress === 'undefined') {
396
  if (localStorage) {
397
  localStorage.setItem("lp-item-expanded", expand ? 'yes' : 'no');
398
  }
 
399
  },
400
  _initHooks : function () {
401
  LP.Hook.addAction('learn_press_update_item_content', this.updateItemContent);
@@ -409,26 +379,19 @@ if (typeof LearnPress === 'undefined') {
409
  that.$('.course-item.item-current .button-load-item').trigger('click', {force: true});
410
  }, 500);
411
  },
412
- _getItemId : function (el) {
413
- var id = el.hasClass('button-load-item') ? el.data('id') : el.find('.button-load-item').data('id');
414
- if (!id) {
415
- id = el.hasClass('lp-label-preview') ? el.closest('.course-item').find('.button-load-item').data('id') : 0;
416
- }
417
- return id;
418
- },
419
  _loadItem : function (e, f) {
420
  e.preventDefault();
421
  var that = this,
422
  $target = $(e.target),
423
- id = this._getItemId($target);
424
  f = f || {force: false};
425
  if (!id || this.itemLoading) {
426
- return;
427
  }
428
  if ($target.closest('.course-item').hasClass('item-current') && !f.force) {
429
  return;
430
  }
431
- this.blockContent();
432
  if (this.currentItem) {
433
  var $iframe = this.currentItem.get('content');
434
  $iframe && $iframe.detach();
@@ -436,7 +399,7 @@ if (typeof LearnPress === 'undefined') {
436
  this.itemLoading = id;
437
  this.currentItem = this.model.getItem(id);
438
  this.showPopup();
439
- var $content = this.currentItem.get('content'),
440
  isNew = !($content && $content.length);
441
  if (!$content) {
442
  $content = $('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen />');
@@ -706,15 +669,9 @@ if (typeof LearnPress === 'undefined') {
706
 
707
  this.curriculumPlaceholder.insertAfter($curriculum);
708
  $curriculum.appendTo(this.$('#popup-sidebar'));
709
- //$('html, body').each(function () {
710
- // var $root = $(this).addClass('block-content'),
711
- // dataOverflow = $root.attr('overflow'),
712
- // overflow = dataOverflow != undefined ? dataOverflow : $root.css('overflow');
713
- // $root.css('overflow', 'hidden').attr('overflow', overflow);
714
- //})
715
- LP.blockContent();
716
  $(".sidebar-show-btn").hide();
717
- $(document).on('learn_press_unblock_content', this.hideScrollBar);
718
  },
719
  _closePopup : function (e) {
720
  e.preventDefault();
@@ -724,18 +681,8 @@ if (typeof LearnPress === 'undefined') {
724
  this.progressPlaceholder.replaceWith(this.$('.learn-press-course-results-progress'));
725
  this.undelegateEvents();
726
  this.remove();
727
-
728
- /*var $root = $(this).removeClass('block-content'),
729
- overflow = $root.attr('overflow');
730
- $root.css('overflow', overflow).removeAttr('overflow');*/
731
- LP.unblockContent();
732
- $('html, body').css('overflow', '');
733
- $(document).off('focusin').trigger('learn_press_popup_course_remove').unbind('learn_press_unblock_content', this.hideScrollBar);
734
- },
735
- hideScrollBar : function () {
736
- $('html, body').each(function () {
737
- var $root = $(this).css('overflow', 'hidden');
738
- })
739
  },
740
  _closeSidebar : function (e) {
741
  e.preventDefault();
@@ -752,12 +699,12 @@ if (typeof LearnPress === 'undefined') {
752
  _loadItem : function (e) {
753
  var $iframe = $('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen />').src($(e.target).attr('href') + '?content-item-only=yes');
754
  this.$('#popup-content-inner').html($iframe);
755
- /*return '';
756
- e.preventDefault();
757
- $.ajax({
758
- url : $(e.target).attr('href'),
759
- success: this._ajaxLoadItemSuccess
760
- });*/
761
  },
762
  _ajaxLoadItemSuccess: function (response) {
763
  this.$('#popup-content-inner').html($(response).contents().find('.lp_course'));
44
  },
45
  _changeCurrent : function (m) {
46
 
 
 
 
 
 
 
 
47
  },
48
  request : function (args) {
49
  var that = this;
275
  LP.Hook.addAction('learn_press_receive_message', this.receiveMessage);
276
  if (typeof localStorage != 'undefined') {
277
  var expanded = localStorage.getItem("lp-item-expanded");
278
+ if (expanded=='yes') {
279
+ console.log('xxx:', expanded);
280
+
281
  this.expand(true);
282
  }
283
  }
296
  sections = {},
297
  $progress = this.$('.course-progress').find('.number, .percentage-sign'),
298
  $itemProgress = this.$('.items-progress').find('.number, .percentage-sign');
299
+ $progress.eq(0).html(parseInt(data.results));
300
+ this.$('.lp-progress-value').width(parseInt(data.results) + '%');
 
 
 
 
 
 
301
  data.items && data.items.forEach(function (item) {
302
+ var $item = this.$('.course-item.course-item-' + item.id);
 
 
303
  if (!sections[item.section_id]) {
304
  sections[item.section_id] = [0, 0];
305
  }
 
 
 
306
  if (item.status === 'completed') {
307
+ itemsCompleted++;
308
  $item.addClass('item-has-status item-completed');
309
+ sections[item.section_id][1]++;
310
  } else if (item.status) {
311
  $item.addClass('item-has-status').removeClass('item-completed');
312
  } else {
313
  $item.removeClass('item-has-status').removeClass('item-completed');
314
  }
 
315
  if (item.type === 'lp_quiz') {
316
+ $item.find('.item-result').html(LP.Hook.applyFilters('item_result_text', item.results + '%'));
 
 
 
 
 
 
 
 
 
317
  }
318
  sections[item.section_id][0]++;
319
  }, this);
324
  if (!data) {
325
  return;
326
  }
 
327
  $section.find('.section-header span.step').html(LP.Hook.applyFilters('section_header_span_text', data[1] + '/' + data[0]));
328
  });
329
  $itemProgress.eq(0).html(data.completed_items_text.replace('%d', itemsCompleted).replace('%d', itemsCount));
330
  var passingCondition = parseInt(this.$('.course-progress .lp-course-progress').data('passing-condition'));
 
 
 
 
 
331
  this.$('.button-finish-course').toggleClass('hide-if-js', !(data.results >= passingCondition));
 
332
  if (data.setUrl) {
333
  LP.setUrl(data.setUrl);
334
  }
365
  if (localStorage) {
366
  localStorage.setItem("lp-item-expanded", expand ? 'yes' : 'no');
367
  }
368
+ console.log(localStorage.getItem("lp-item-expanded"));
369
  },
370
  _initHooks : function () {
371
  LP.Hook.addAction('learn_press_update_item_content', this.updateItemContent);
379
  that.$('.course-item.item-current .button-load-item').trigger('click', {force: true});
380
  }, 500);
381
  },
 
 
 
 
 
 
 
382
  _loadItem : function (e, f) {
383
  e.preventDefault();
384
  var that = this,
385
  $target = $(e.target),
386
+ id = $target.hasClass('button-load-item') ? $target.data('id') : $target.find('.button-load-item').data('id');
387
  f = f || {force: false};
388
  if (!id || this.itemLoading) {
389
+ return;
390
  }
391
  if ($target.closest('.course-item').hasClass('item-current') && !f.force) {
392
  return;
393
  }
394
+ this.blockContent();
395
  if (this.currentItem) {
396
  var $iframe = this.currentItem.get('content');
397
  $iframe && $iframe.detach();
399
  this.itemLoading = id;
400
  this.currentItem = this.model.getItem(id);
401
  this.showPopup();
402
+ var $content = this.currentItem.get('content'),
403
  isNew = !($content && $content.length);
404
  if (!$content) {
405
  $content = $('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen />');
669
 
670
  this.curriculumPlaceholder.insertAfter($curriculum);
671
  $curriculum.appendTo(this.$('#popup-sidebar'));
672
+
673
+ $('body').css({overflow: 'hidden'});
 
 
 
 
 
674
  $(".sidebar-show-btn").hide();
 
675
  },
676
  _closePopup : function (e) {
677
  e.preventDefault();
681
  this.progressPlaceholder.replaceWith(this.$('.learn-press-course-results-progress'));
682
  this.undelegateEvents();
683
  this.remove();
684
+ $(document).off('focusin');
685
+ $('body').css('overflow', '').trigger('learn_press_popup_course_remove');
 
 
 
 
 
 
 
 
 
 
686
  },
687
  _closeSidebar : function (e) {
688
  e.preventDefault();
699
  _loadItem : function (e) {
700
  var $iframe = $('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen />').src($(e.target).attr('href') + '?content-item-only=yes');
701
  this.$('#popup-content-inner').html($iframe);
702
+ return '';
703
+ e.preventDefault();
704
+ $.ajax({
705
+ url : $(e.target).attr('href'),
706
+ success: this._ajaxLoadItemSuccess
707
+ });
708
  },
709
  _ajaxLoadItemSuccess: function (response) {
710
  this.$('#popup-content-inner').html($(response).contents().find('.lp_course'));
assets/js/global.js CHANGED
@@ -143,8 +143,6 @@ if (typeof window.LP == 'undefined') {
143
  };
144
  String.prototype.addQueryVar = function (name, value) {
145
  var url = this;
146
- var m = url.split('#');
147
- url = m[0];
148
  if (name.match(/\[/)) {
149
  url += url.match(/\?/) ? '&' : '?';
150
  url += name + '=' + value;
@@ -156,16 +154,14 @@ if (typeof window.LP == 'undefined') {
156
  url += name + '=' + value;
157
  }
158
  }
159
- return url + (m[1] ? '#' + m[1] : '');
160
  };
161
  String.prototype.removeQueryVar = function (name) {
162
  var url = this;
163
- var m = url.split('#');
164
- url = m[0];
165
  name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
166
  var regex = new RegExp("[\\?&]" + name + "([\[][^=]*)?=([^&#]*)", 'g');
167
  url = url.replace(regex, '');
168
- return url + (m[1] ? '#' + m[1] : '');
169
  };
170
 
171
  if ($.isEmptyObject("") == false) {
@@ -557,14 +553,14 @@ if (typeof window.LP == 'undefined') {
557
  },
558
 
559
  parseResponse: function (response, type) {
560
- var m = response.match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/);
561
  if (m) {
562
  response = m[1];
563
  }
564
  return (type || "json") == "json" ? this.parseJSON(response) : response;
565
  },
566
  parseJSON : function (data) {
567
- var m = data.match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/);
568
  try {
569
  if (m) {
570
  data = $.parseJSON(m[1]);
@@ -572,6 +568,7 @@ if (typeof window.LP == 'undefined') {
572
  data = $.parseJSON(data);
573
  }
574
  } catch (e) {
 
575
  data = {};
576
  }
577
  return data;
@@ -726,38 +723,16 @@ if (typeof window.LP == 'undefined') {
726
  if ($('#learn-press-block-content').length == 0) {
727
  $(LP.template('learn-press-template-block-content', {})).appendTo($('body'));
728
  }
729
- LP.hideMainScrollbar().addClass('block-content');
730
- $(document).trigger('learn_press_block_content');
 
731
  },
732
  unblockContent: function () {
733
  setTimeout(function () {
734
- LP.showMainScrollbar().removeClass('block-content');
735
- $(document).trigger('learn_press_unblock_content');
736
- }, 350);
737
- },
738
- hideMainScrollbar: function (el) {
739
- if (!el) {
740
- el = 'html, body';
741
- }
742
- var $el = $(el);
743
- $el.each(function () {
744
- var $root = $(this),
745
- overflow = $root.css('overflow');
746
- $root.css('overflow', 'hidden').attr('overflow', overflow);
747
- });
748
- return $el;
749
- },
750
- showMainScrollbar: function (el) {
751
- if (!el) {
752
- el = 'html, body';
753
- }
754
- var $el = $(el);
755
- $el.each(function () {
756
- var $root = $(this),
757
  overflow = $root.attr('overflow');
758
  $root.css('overflow', overflow).removeAttr('overflow');
759
- });
760
- return $el;
761
  },
762
  template : _.memoize(function (id, data) {
763
  var compiled,
143
  };
144
  String.prototype.addQueryVar = function (name, value) {
145
  var url = this;
 
 
146
  if (name.match(/\[/)) {
147
  url += url.match(/\?/) ? '&' : '?';
148
  url += name + '=' + value;
154
  url += name + '=' + value;
155
  }
156
  }
157
+ return url;
158
  };
159
  String.prototype.removeQueryVar = function (name) {
160
  var url = this;
 
 
161
  name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
162
  var regex = new RegExp("[\\?&]" + name + "([\[][^=]*)?=([^&#]*)", 'g');
163
  url = url.replace(regex, '');
164
+ return url;
165
  };
166
 
167
  if ($.isEmptyObject("") == false) {
553
  },
554
 
555
  parseResponse: function (response, type) {
556
+ var m = response.match(/<!-- LP_AJAX_START -->(.*)<!-- LP_AJAX_END -->/);
557
  if (m) {
558
  response = m[1];
559
  }
560
  return (type || "json") == "json" ? this.parseJSON(response) : response;
561
  },
562
  parseJSON : function (data) {
563
+ var m = data.match(/<!-- LP_AJAX_START -->(.*)<!-- LP_AJAX_END -->/);
564
  try {
565
  if (m) {
566
  data = $.parseJSON(m[1]);
568
  data = $.parseJSON(data);
569
  }
570
  } catch (e) {
571
+ LP.log(e);
572
  data = {};
573
  }
574
  return data;
723
  if ($('#learn-press-block-content').length == 0) {
724
  $(LP.template('learn-press-template-block-content', {})).appendTo($('body'));
725
  }
726
+ var $root = $('body').addClass('block-content'),
727
+ overflow = $root.css('overflow');
728
+ $root.css('overflow', 'hidden').attr('overflow', overflow);
729
  },
730
  unblockContent: function () {
731
  setTimeout(function () {
732
+ var $root = $('body, html').removeClass('block-content'),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
733
  overflow = $root.attr('overflow');
734
  $root.css('overflow', overflow).removeAttr('overflow');
735
+ }, 350);
 
736
  },
737
  template : _.memoize(function (id, data) {
738
  var compiled,
assets/js/global.min.js CHANGED
@@ -395,7 +395,7 @@ if (typeof window.LP == "undefined") {
395
  }
396
  window.location.href = url
397
  }, parseJSON : function (data) {
398
- var m = data.match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/);
399
  try {
400
  if (m) {
401
  data = $.parseJSON(m[1])
@@ -408,7 +408,7 @@ if (typeof window.LP == "undefined") {
408
  }
409
  return data
410
  }, parseResponse : function (response, type) {
411
- var m = response.match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/);
412
  if (m) {
413
  response = m[1]
414
  }
395
  }
396
  window.location.href = url
397
  }, parseJSON : function (data) {
398
+ var m = data.match(/<!-- LP_AJAX_START -->(.*)<!-- LP_AJAX_END -->/);
399
  try {
400
  if (m) {
401
  data = $.parseJSON(m[1])
408
  }
409
  return data
410
  }, parseResponse : function (response, type) {
411
+ var m = response.match(/<!-- LP_AJAX_START -->(.*)<!-- LP_AJAX_END -->/);
412
  if (m) {
413
  response = m[1]
414
  }
assets/js/jquery.cropit.js ADDED
@@ -0,0 +1,1207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! cropit - v0.5.1 <https://github.com/scottcheng/cropit> */
2
+ (function webpackUniversalModuleDefinition(root, factory) {
3
+ if(typeof exports === 'object' && typeof module === 'object')
4
+ module.exports = factory(require("jquery"));
5
+ else if(typeof define === 'function' && define.amd)
6
+ define(["jquery"], factory);
7
+ else if(typeof exports === 'object')
8
+ exports["cropit"] = factory(require("jquery"));
9
+ else
10
+ root["cropit"] = factory(root["jQuery"]);
11
+ })(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {
12
+ return /******/ (function(modules) { // webpackBootstrap
13
+ /******/ // The module cache
14
+ /******/ var installedModules = {};
15
+
16
+ /******/ // The require function
17
+ /******/ function __webpack_require__(moduleId) {
18
+
19
+ /******/ // Check if module is in cache
20
+ /******/ if(installedModules[moduleId])
21
+ /******/ return installedModules[moduleId].exports;
22
+
23
+ /******/ // Create a new module (and put it into the cache)
24
+ /******/ var module = installedModules[moduleId] = {
25
+ /******/ exports: {},
26
+ /******/ id: moduleId,
27
+ /******/ loaded: false
28
+ /******/ };
29
+
30
+ /******/ // Execute the module function
31
+ /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
32
+
33
+ /******/ // Flag the module as loaded
34
+ /******/ module.loaded = true;
35
+
36
+ /******/ // Return the exports of the module
37
+ /******/ return module.exports;
38
+ /******/ }
39
+
40
+
41
+ /******/ // expose the modules object (__webpack_modules__)
42
+ /******/ __webpack_require__.m = modules;
43
+
44
+ /******/ // expose the module cache
45
+ /******/ __webpack_require__.c = installedModules;
46
+
47
+ /******/ // __webpack_public_path__
48
+ /******/ __webpack_require__.p = "";
49
+
50
+ /******/ // Load entry module and return exports
51
+ /******/ return __webpack_require__(0);
52
+ /******/ })
53
+ /************************************************************************/
54
+ /******/ ([
55
+ /* 0 */
56
+ /***/ function(module, exports, __webpack_require__) {
57
+
58
+ var _slice = Array.prototype.slice;
59
+
60
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
61
+
62
+ var _jquery = __webpack_require__(1);
63
+
64
+ var _jquery2 = _interopRequireDefault(_jquery);
65
+
66
+ var _cropit = __webpack_require__(2);
67
+
68
+ var _cropit2 = _interopRequireDefault(_cropit);
69
+
70
+ var _constants = __webpack_require__(4);
71
+
72
+ var _utils = __webpack_require__(6);
73
+
74
+ var applyOnEach = function applyOnEach($el, callback) {
75
+ return $el.each(function () {
76
+ var cropit = _jquery2['default'].data(this, _constants.PLUGIN_KEY);
77
+
78
+ if (!cropit) {
79
+ return;
80
+ }
81
+ callback(cropit);
82
+ });
83
+ };
84
+
85
+ var callOnFirst = function callOnFirst($el, method, options) {
86
+ var cropit = $el.first().data(_constants.PLUGIN_KEY);
87
+
88
+ if (!cropit || !_jquery2['default'].isFunction(cropit[method])) {
89
+ return null;
90
+ }
91
+ return cropit[method](options);
92
+ };
93
+
94
+ var methods = {
95
+ init: function init(options) {
96
+ return this.each(function () {
97
+ // Only instantiate once per element
98
+ if (_jquery2['default'].data(this, _constants.PLUGIN_KEY)) {
99
+ return;
100
+ }
101
+
102
+ var cropit = new _cropit2['default'](_jquery2['default'], this, options);
103
+ _jquery2['default'].data(this, _constants.PLUGIN_KEY, cropit);
104
+ });
105
+ },
106
+
107
+ destroy: function destroy() {
108
+ return this.each(function () {
109
+ _jquery2['default'].removeData(this, _constants.PLUGIN_KEY);
110
+ });
111
+ },
112
+
113
+ isZoomable: function isZoomable() {
114
+ return callOnFirst(this, 'isZoomable');
115
+ },
116
+
117
+ 'export': function _export(options) {
118
+ return callOnFirst(this, 'getCroppedImageData', options);
119
+ }
120
+ };
121
+
122
+ var delegate = function delegate($el, fnName) {
123
+ return applyOnEach($el, function (cropit) {
124
+ cropit[fnName]();
125
+ });
126
+ };
127
+
128
+ var prop = function prop($el, name, value) {
129
+ if ((0, _utils.exists)(value)) {
130
+ return applyOnEach($el, function (cropit) {
131
+ cropit[name] = value;
132
+ });
133
+ } else {
134
+ var cropit = $el.first().data(_constants.PLUGIN_KEY);
135
+ return cropit[name];
136
+ }
137
+ };
138
+
139
+ _jquery2['default'].fn.cropit = function (method) {
140
+ if (methods[method]) {
141
+ return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
142
+ } else if (['imageState', 'imageSrc', 'offset', 'previewSize', 'imageSize', 'zoom', 'initialZoom', 'exportZoom', 'minZoom', 'maxZoom'].indexOf(method) >= 0) {
143
+ return prop.apply(undefined, [this].concat(_slice.call(arguments)));
144
+ } else if (['rotateCW', 'rotateCCW', 'disable', 'reenable'].indexOf(method) >= 0) {
145
+ return delegate.apply(undefined, [this].concat(_slice.call(arguments)));
146
+ } else {
147
+ return methods.init.apply(this, arguments);
148
+ }
149
+ };
150
+
151
+ /***/ },
152
+ /* 1 */
153
+ /***/ function(module, exports) {
154
+
155
+ module.exports = __WEBPACK_EXTERNAL_MODULE_1__;
156
+
157
+ /***/ },
158
+ /* 2 */
159
+ /***/ function(module, exports, __webpack_require__) {
160
+
161
+ Object.defineProperty(exports, '__esModule', {
162
+ value: true
163
+ });
164
+
165
+ var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
166
+
167
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
168
+
169
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
170
+
171
+ var _jquery = __webpack_require__(1);
172
+
173
+ var _jquery2 = _interopRequireDefault(_jquery);
174
+
175
+ var _Zoomer = __webpack_require__(3);
176
+
177
+ var _Zoomer2 = _interopRequireDefault(_Zoomer);
178
+
179
+ var _constants = __webpack_require__(4);
180
+
181
+ var _options = __webpack_require__(5);
182
+
183
+ var _utils = __webpack_require__(6);
184
+
185
+ var Cropit = (function () {
186
+ function Cropit(jQuery, element, options) {
187
+ _classCallCheck(this, Cropit);
188
+
189
+ this.$el = (0, _jquery2['default'])(element);
190
+
191
+ var defaults = (0, _options.loadDefaults)(this.$el);
192
+ this.options = _jquery2['default'].extend({}, defaults, options);
193
+
194
+ this.init();
195
+ }
196
+
197
+ _createClass(Cropit, [{
198
+ key: 'init',
199
+ value: function init() {
200
+ var _this = this;
201
+
202
+ this.image = new Image();
203
+ this.preImage = new Image();
204
+ this.image.onload = this.onImageLoaded.bind(this);
205
+ this.preImage.onload = this.onPreImageLoaded.bind(this);
206
+ this.image.onerror = this.preImage.onerror = function () {
207
+ _this.onImageError.call(_this, _constants.ERRORS.IMAGE_FAILED_TO_LOAD);
208
+ };
209
+
210
+ this.$preview = this.options.$preview.css('position', 'relative');
211
+ this.$fileInput = this.options.$fileInput.attr({ accept: 'image/*' });
212
+ this.$zoomSlider = this.options.$zoomSlider.attr({ min: 0, max: 1, step: 0.01 });
213
+
214
+ this.previewSize = {
215
+ width: this.options.width || this.$preview.innerWidth(),
216
+ height: this.options.height || this.$preview.innerHeight()
217
+ };
218
+
219
+ this.$image = (0, _jquery2['default'])('<img />').addClass(_constants.CLASS_NAMES.PREVIEW_IMAGE).attr('alt', '').css({
220
+ transformOrigin: 'top left',
221
+ webkitTransformOrigin: 'top left',
222
+ willChange: 'transform'
223
+ });
224
+ this.$imageContainer = (0, _jquery2['default'])('<div />').addClass(_constants.CLASS_NAMES.PREVIEW_IMAGE_CONTAINER).css({
225
+ position: 'absolute',
226
+ overflow: 'hidden',
227
+ left: 0,
228
+ top: 0,
229
+ width: '100%',
230
+ height: '100%'
231
+ }).append(this.$image);
232
+ this.$preview.append(this.$imageContainer);
233
+
234
+ if (this.options.imageBackground) {
235
+ if (_jquery2['default'].isArray(this.options.imageBackgroundBorderWidth)) {
236
+ this.bgBorderWidthArray = this.options.imageBackgroundBorderWidth;
237
+ } else {
238
+ this.bgBorderWidthArray = [0, 1, 2, 3].map(function () {
239
+ return _this.options.imageBackgroundBorderWidth;
240
+ });
241
+ }
242
+
243
+ this.$bg = (0, _jquery2['default'])('<img />').addClass(_constants.CLASS_NAMES.PREVIEW_BACKGROUND).attr('alt', '').css({
244
+ position: 'relative',
245
+ left: this.bgBorderWidthArray[3],
246
+ top: this.bgBorderWidthArray[0],
247
+ transformOrigin: 'top left',
248
+ webkitTransformOrigin: 'top left',
249
+ willChange: 'transform'
250
+ });
251
+ this.$bgContainer = (0, _jquery2['default'])('<div />').addClass(_constants.CLASS_NAMES.PREVIEW_BACKGROUND_CONTAINER).css({
252
+ position: 'absolute',
253
+ zIndex: 0,
254
+ top: -this.bgBorderWidthArray[0],
255
+ right: -this.bgBorderWidthArray[1],
256
+ bottom: -this.bgBorderWidthArray[2],
257
+ left: -this.bgBorderWidthArray[3]
258
+ }).append(this.$bg);
259
+ if (this.bgBorderWidthArray[0] > 0) {
260
+ this.$bgContainer.css('overflow', 'hidden');
261
+ }
262
+ this.$preview.prepend(this.$bgContainer);
263
+ }
264
+
265
+ this.initialZoom = this.options.initialZoom;
266
+
267
+ this.imageLoaded = false;
268
+
269
+ this.moveContinue = false;
270
+
271
+ this.zoomer = new _Zoomer2['default']();
272
+
273
+ if (this.options.allowDragNDrop) {
274
+ _jquery2['default'].event.props.push('dataTransfer');
275
+ }
276
+
277
+ this.bindListeners();
278
+
279
+ if (this.options.imageState && this.options.imageState.src) {
280
+ this.loadImage(this.options.imageState.src);
281
+ }
282
+ }
283
+ }, {
284
+ key: 'bindListeners',
285
+ value: function bindListeners() {
286
+ this.$fileInput.on('change.cropit', this.onFileChange.bind(this));
287
+ this.$imageContainer.on(_constants.EVENTS.PREVIEW, this.onPreviewEvent.bind(this));
288
+ this.$zoomSlider.on(_constants.EVENTS.ZOOM_INPUT, this.onZoomSliderChange.bind(this));
289
+
290
+ if (this.options.allowDragNDrop) {
291
+ this.$imageContainer.on('dragover.cropit dragleave.cropit', this.onDragOver.bind(this));
292
+ this.$imageContainer.on('drop.cropit', this.onDrop.bind(this));
293
+ }
294
+ }
295
+ }, {
296
+ key: 'unbindListeners',
297
+ value: function unbindListeners() {
298
+ this.$fileInput.off('change.cropit');
299
+ this.$imageContainer.off(_constants.EVENTS.PREVIEW);
300
+ this.$imageContainer.off('dragover.cropit dragleave.cropit drop.cropit');
301
+ this.$zoomSlider.off(_constants.EVENTS.ZOOM_INPUT);
302
+ }
303
+ }, {
304
+ key: 'onFileChange',
305
+ value: function onFileChange(e) {
306
+ this.options.onFileChange(e);
307
+
308
+ if (this.$fileInput.get(0).files) {
309
+ this.loadFile(this.$fileInput.get(0).files[0]);
310
+ }
311
+ }
312
+ }, {
313
+ key: 'loadFile',
314
+ value: function loadFile(file) {
315
+ var fileReader = new FileReader();
316
+ if (file && file.type.match('image')) {
317
+ fileReader.readAsDataURL(file);
318
+ fileReader.onload = this.onFileReaderLoaded.bind(this);
319
+ fileReader.onerror = this.onFileReaderError.bind(this);
320
+ } else if (file) {
321
+ this.onFileReaderError();
322
+ }
323
+ }
324
+ }, {
325
+ key: 'onFileReaderLoaded',
326
+ value: function onFileReaderLoaded(e) {
327
+ this.loadImage(e.target.result);
328
+ }
329
+ }, {
330
+ key: 'onFileReaderError',
331
+ value: function onFileReaderError() {
332
+ this.options.onFileReaderError();
333
+ }
334
+ }, {
335
+ key: 'onDragOver',
336
+ value: function onDragOver(e) {
337
+ e.preventDefault();
338
+ e.dataTransfer.dropEffect = 'copy';
339
+ this.$preview.toggleClass(_constants.CLASS_NAMES.DRAG_HOVERED, e.type === 'dragover');
340
+ }
341
+ }, {
342
+ key: 'onDrop',
343
+ value: function onDrop(e) {
344
+ var _this2 = this;
345
+
346
+ e.preventDefault();
347
+ e.stopPropagation();
348
+
349
+ var files = Array.prototype.slice.call(e.dataTransfer.files, 0);
350
+ files.some(function (file) {
351
+ if (!file.type.match('image')) {
352
+ return false;
353
+ }
354
+
355
+ _this2.loadFile(file);
356
+ return true;
357
+ });
358
+
359
+ this.$preview.removeClass(_constants.CLASS_NAMES.DRAG_HOVERED);
360
+ }
361
+ }, {
362
+ key: 'loadImage',
363
+ value: function loadImage(imageSrc) {
364
+ var _this3 = this;
365
+
366
+ if (!imageSrc) {
367
+ return;
368
+ }
369
+
370
+ this.options.onImageLoading();
371
+ this.setImageLoadingClass();
372
+
373
+ if (imageSrc.indexOf('data') === 0) {
374
+ this.preImage.src = imageSrc;
375
+ } else {
376
+ var xhr = new XMLHttpRequest();
377
+ xhr.onload = function (e) {
378
+ if (e.target.status >= 300) {
379
+ _this3.onImageError.call(_this3, _constants.ERRORS.IMAGE_FAILED_TO_LOAD);
380
+ return;
381
+ }
382
+
383
+ _this3.loadFile(e.target.response);
384
+ };
385
+ xhr.open('GET', imageSrc);
386
+ xhr.responseType = 'blob';
387
+ xhr.send();
388
+ }
389
+ }
390
+ }, {
391
+ key: 'onPreImageLoaded',
392
+ value: function onPreImageLoaded() {
393
+ if (this.shouldRejectImage({
394
+ imageWidth: this.preImage.width,
395
+ imageHeight: this.preImage.height,
396
+ previewSize: this.previewSize,
397
+ maxZoom: this.options.maxZoom,
398
+ exportZoom: this.options.exportZoom,
399
+ smallImage: this.options.smallImage
400
+ })) {
401
+ this.onImageError(_constants.ERRORS.SMALL_IMAGE);
402
+ if (this.image.src) {
403
+ this.setImageLoadedClass();
404
+ }
405
+ return;
406
+ }
407
+
408
+ this.image.src = this.preImage.src;
409
+ }
410
+ }, {
411
+ key: 'onImageLoaded',
412
+ value: function onImageLoaded() {
413
+ this.rotation = 0;
414
+ this.setupZoomer(this.options.imageState && this.options.imageState.zoom || this._initialZoom);
415
+ if (this.options.imageState && this.options.imageState.offset) {
416
+ this.offset = this.options.imageState.offset;
417
+ } else {
418
+ this.centerImage();
419
+ }
420
+
421
+ this.options.imageState = {};
422
+
423
+ this.$image.attr('src', this.image.src);
424
+ if (this.options.imageBackground) {
425
+ this.$bg.attr('src', this.image.src);
426
+ }
427
+
428
+ this.setImageLoadedClass();
429
+
430
+ this.imageLoaded = true;
431
+
432
+ this.options.onImageLoaded();
433
+ }
434
+ }, {
435
+ key: 'onImageError',
436
+ value: function onImageError() {
437
+ this.options.onImageError.apply(this, arguments);
438
+ this.removeImageLoadingClass();
439
+ }
440
+ }, {
441
+ key: 'setImageLoadingClass',
442
+ value: function setImageLoadingClass() {
443
+ this.$preview.removeClass(_constants.CLASS_NAMES.IMAGE_LOADED).addClass(_constants.CLASS_NAMES.IMAGE_LOADING);
444
+ }
445
+ }, {
446
+ key: 'setImageLoadedClass',
447
+ value: function setImageLoadedClass() {
448
+ this.$preview.removeClass(_constants.CLASS_NAMES.IMAGE_LOADING).addClass(_constants.CLASS_NAMES.IMAGE_LOADED);
449
+ }
450
+ }, {
451
+ key: 'removeImageLoadingClass',
452
+ value: function removeImageLoadingClass() {
453
+ this.$preview.removeClass(_constants.CLASS_NAMES.IMAGE_LOADING);
454
+ }
455
+ }, {
456
+ key: 'getEventPosition',
457
+ value: function getEventPosition(e) {
458
+ if (e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0]) {
459
+ e = e.originalEvent.touches[0];
460
+ }
461
+ if (e.clientX && e.clientY) {
462
+ return { x: e.clientX, y: e.clientY };
463
+ }
464
+ }
465
+ }, {
466
+ key: 'onPreviewEvent',
467
+ value: function onPreviewEvent(e) {
468
+ if (!this.imageLoaded) {
469
+ return;
470
+ }
471
+
472
+ this.moveContinue = false;
473
+ this.$imageContainer.off(_constants.EVENTS.PREVIEW_MOVE);
474
+
475
+ if (e.type === 'mousedown' || e.type === 'touchstart') {
476
+ this.origin = this.getEventPosition(e);
477
+ this.moveContinue = true;
478
+ this.$imageContainer.on(_constants.EVENTS.PREVIEW_MOVE, this.onMove.bind(this));
479
+ } else {
480
+ (0, _jquery2['default'])(document.body).focus();
481
+ }
482
+
483
+ e.stopPropagation();
484
+ return false;
485
+ }
486
+ }, {
487
+ key: 'onMove',
488
+ value: function onMove(e) {
489
+ var eventPosition = this.getEventPosition(e);
490
+
491
+ if (this.moveContinue && eventPosition) {
492
+ this.offset = {
493
+ x: this.offset.x + eventPosition.x - this.origin.x,
494
+ y: this.offset.y + eventPosition.y - this.origin.y
495
+ };
496
+ }
497
+
498
+ this.origin = eventPosition;
499
+
500
+ e.stopPropagation();
501
+ return false;
502
+ }
503
+ }, {
504
+ key: 'fixOffset',
505
+ value: function fixOffset(offset) {
506
+ if (!this.imageLoaded) {
507
+ return offset;
508
+ }
509
+
510
+ var ret = { x: offset.x, y: offset.y };
511
+
512
+ if (!this.options.freeMove) {
513
+ if (this.imageWidth * this.zoom >= this.previewSize.width) {
514
+ ret.x = Math.min(0, Math.max(ret.x, this.previewSize.width - this.imageWidth * this.zoom));
515
+ } else {
516
+ ret.x = Math.max(0, Math.min(ret.x, this.previewSize.width - this.imageWidth * this.zoom));
517
+ }
518
+
519
+ if (this.imageHeight * this.zoom >= this.previewSize.height) {
520
+ ret.y = Math.min(0, Math.max(ret.y, this.previewSize.height - this.imageHeight * this.zoom));
521
+ } else {
522
+ ret.y = Math.max(0, Math.min(ret.y, this.previewSize.height - this.imageHeight * this.zoom));
523
+ }
524
+ }
525
+
526
+ ret.x = (0, _utils.round)(ret.x);
527
+ ret.y = (0, _utils.round)(ret.y);
528
+
529
+ return ret;
530
+ }
531
+ }, {
532
+ key: 'centerImage',
533
+ value: function centerImage() {
534
+ if (!this.image.width || !this.image.height || !this.zoom) {
535
+ return;
536
+ }
537
+
538
+ this.offset = {
539
+ x: (this.previewSize.width - this.imageWidth * this.zoom) / 2,
540
+ y: (this.previewSize.height - this.imageHeight * this.zoom) / 2
541
+ };
542
+ }
543
+ }, {
544
+ key: 'onZoomSliderChange',
545
+ value: function onZoomSliderChange() {
546
+ if (!this.imageLoaded) {
547
+ return;
548
+ }
549
+
550
+ this.zoomSliderPos = Number(this.$zoomSlider.val());
551
+ var newZoom = this.zoomer.getZoom(this.zoomSliderPos);
552
+ if (newZoom === this.zoom) {
553
+ return;
554
+ }
555
+ this.zoom = newZoom;
556
+ }
557
+ }, {
558
+ key: 'enableZoomSlider',
559
+ value: function enableZoomSlider() {
560
+ this.$zoomSlider.removeAttr('disabled');
561
+ this.options.onZoomEnabled();
562
+ }
563
+ }, {
564
+ key: 'disableZoomSlider',
565
+ value: function disableZoomSlider() {
566
+ this.$zoomSlider.attr('disabled', true);
567
+ this.options.onZoomDisabled();
568
+ }
569
+ }, {
570
+ key: 'setupZoomer',
571
+ value: function setupZoomer(zoom) {
572
+ this.zoomer.setup({
573
+ imageSize: this.imageSize,
574
+ previewSize: this.previewSize,
575
+ exportZoom: this.options.exportZoom,
576
+ maxZoom: this.options.maxZoom,
577
+ minZoom: this.options.minZoom,
578
+ smallImage: this.options.smallImage
579
+ });
580
+ this.zoom = (0, _utils.exists)(zoom) ? zoom : this._zoom;
581
+
582
+ if (this.isZoomable()) {
583
+ this.enableZoomSlider();
584
+ } else {
585
+ this.disableZoomSlider();
586
+ }
587
+ }
588
+ }, {
589
+ key: 'fixZoom',
590
+ value: function fixZoom(zoom) {
591
+ return this.zoomer.fixZoom(zoom);
592
+ }
593
+ }, {
594
+ key: 'isZoomable',
595
+ value: function isZoomable() {
596
+ return this.zoomer.isZoomable();
597
+ }
598
+ }, {
599
+ key: 'renderImage',
600
+ value: function renderImage() {
601
+ var transformation = '\n translate(' + this.rotatedOffset.x + 'px, ' + this.rotatedOffset.y + 'px)\n scale(' + this.zoom + ')\n rotate(' + this.rotation + 'deg)';
602
+
603
+ this.$image.css({
604
+ transform: transformation,
605
+ webkitTransform: transformation
606
+ });
607
+ if (this.options.imageBackground) {
608
+ this.$bg.css({
609
+ transform: transformation,
610
+ webkitTransform: transformation
611
+ });
612
+ }
613
+ }
614
+ }, {
615
+ key: 'rotateCW',
616
+ value: function rotateCW() {
617
+ if (this.shouldRejectImage({
618
+ imageWidth: this.image.height,
619
+ imageHeight: this.image.width,
620
+ previewSize: this.previewSize,
621
+ maxZoom: this.options.maxZoom,
622
+ exportZoom: this.options.exportZoom,
623
+ smallImage: this.options.smallImage
624
+ })) {
625
+ this.rotation = (this.rotation + 180) % 360;
626
+ } else {
627
+ this.rotation = (this.rotation + 90) % 360;
628
+ }
629
+ }
630
+ }, {
631
+ key: 'rotateCCW',
632
+ value: function rotateCCW() {
633
+ if (this.shouldRejectImage({
634
+ imageWidth: this.image.height,
635
+ imageHeight: this.image.width,
636
+ previewSize: this.previewSize,
637
+ maxZoom: this.options.maxZoom,
638
+ exportZoom: this.options.exportZoom,
639
+ smallImage: this.options.smallImage
640
+ })) {
641
+ this.rotation = (this.rotation + 180) % 360;
642
+ } else {
643
+ this.rotation = (this.rotation + 270) % 360;
644
+ }
645
+ }
646
+ }, {
647
+ key: 'shouldRejectImage',
648
+ value: function shouldRejectImage(_ref) {
649
+ var imageWidth = _ref.imageWidth;
650
+ var imageHeight = _ref.imageHeight;
651
+ var previewSize = _ref.previewSize;
652
+ var maxZoom = _ref.maxZoom;
653
+ var exportZoom = _ref.exportZoom;
654
+ var smallImage = _ref.smallImage;
655
+
656
+ if (smallImage !== 'reject') {
657
+ return false;
658
+ }
659
+
660
+ return imageWidth * maxZoom < previewSize.width * exportZoom || imageHeight * maxZoom < previewSize.height * exportZoom;
661
+ }
662
+ }, {
663
+ key: 'getCroppedImageData',
664
+ value: function getCroppedImageData(exportOptions) {
665
+ if (!this.image.src) {
666
+ return;
667
+ }
668
+
669
+ var exportDefaults = {
670
+ type: 'image/png',
671
+ quality: 0.75,
672
+ originalSize: false,
673
+ fillBg: '#fff'
674
+ };
675
+ exportOptions = _jquery2['default'].extend({}, exportDefaults, exportOptions);
676
+
677
+ var exportZoom = exportOptions.originalSize ? 1 / this.zoom : this.options.exportZoom;
678
+
679
+ var zoomedSize = {
680
+ width: this.zoom * exportZoom * this.image.width,
681
+ height: this.zoom * exportZoom * this.image.height
682
+ };
683
+
684
+ var canvas = (0, _jquery2['default'])('<canvas />').attr({
685
+ width: this.previewSize.width * exportZoom,
686
+ height: this.previewSize.height * exportZoom
687
+ }).get(0);
688
+ var canvasContext = canvas.getContext('2d');
689
+
690
+ if (exportOptions.type === 'image/jpeg') {
691
+ canvasContext.fillStyle = exportOptions.fillBg;
692
+ canvasContext.fillRect(0, 0, canvas.width, canvas.height);
693
+ }
694
+
695
+ canvasContext.translate(this.rotatedOffset.x * exportZoom, this.rotatedOffset.y * exportZoom);
696
+ canvasContext.rotate(this.rotation * Math.PI / 180);
697
+ canvasContext.drawImage(this.image, 0, 0, zoomedSize.width, zoomedSize.height);
698
+
699
+ return canvas.toDataURL(exportOptions.type, exportOptions.quality);
700
+ }
701
+ }, {
702
+ key: 'disable',
703
+ value: function disable() {
704
+ this.unbindListeners();
705
+ this.disableZoomSlider();
706
+ this.$el.addClass(_constants.CLASS_NAMES.DISABLED);
707
+ }
708
+ }, {
709
+ key: 'reenable',
710
+ value: function reenable() {
711
+ this.bindListeners();
712
+ this.enableZoomSlider();
713
+ this.$el.removeClass(_constants.CLASS_NAMES.DISABLED);
714
+ }
715
+ }, {
716
+ key: '$',
717
+ value: function $(selector) {
718
+ if (!this.$el) {
719
+ return null;
720
+ }
721
+ return this.$el.find(selector);
722
+ }
723
+ }, {
724
+ key: 'offset',
725
+ set: function (position) {
726
+ if (!position || !(0, _utils.exists)(position.x) || !(0, _utils.exists)(position.y)) {
727
+ return;
728
+ }
729
+
730
+ this._offset = this.fixOffset(position);
731
+ this.renderImage();
732
+
733
+ this.options.onOffsetChange(position);
734
+ },
735
+ get: function () {
736
+ return this._offset;
737
+ }
738
+ }, {
739
+ key: 'zoom',
740
+ set: function (newZoom) {
741
+ newZoom = this.fixZoom(newZoom);
742
+
743
+ if (this.imageLoaded) {
744
+ var oldZoom = this.zoom;
745
+
746
+ var newX = this.previewSize.width / 2 - (this.previewSize.width / 2 - this.offset.x) * newZoom / oldZoom;
747
+ var newY = this.previewSize.height / 2 - (this.previewSize.height / 2 - this.offset.y) * newZoom / oldZoom;
748
+
749
+ this._zoom = newZoom;
750
+ this.offset = { x: newX, y: newY }; // Triggers renderImage()
751
+ } else {
752
+ this._zoom = newZoom;
753
+ }
754
+
755
+ this.zoomSliderPos = this.zoomer.getSliderPos(this.zoom);
756
+ this.$zoomSlider.val(this.zoomSliderPos);
757
+
758
+ this.options.onZoomChange(newZoom);
759
+ },
760
+ get: function () {
761
+ return this._zoom;
762
+ }
763
+ }, {
764
+ key: 'rotatedOffset',
765
+ get: function () {
766
+ return {
767
+ x: this.offset.x + (this.rotation === 90 ? this.image.height * this.zoom : 0) + (this.rotation === 180 ? this.image.width * this.zoom : 0),
768
+ y: this.offset.y + (this.rotation === 180 ? this.image.height * this.zoom : 0) + (this.rotation === 270 ? this.image.width * this.zoom : 0)
769
+ };
770
+ }
771
+ }, {
772
+ key: 'rotation',
773
+ set: function (newRotation) {
774
+ this._rotation = newRotation;
775
+
776
+ if (this.imageLoaded) {
777
+ // Change in image size may lead to change in zoom range
778
+ this.setupZoomer();
779
+ }
780
+ },
781
+ get: function () {
782
+ return this._rotation;
783
+ }
784
+ }, {
785
+ key: 'imageState',
786
+ get: function () {
787
+ return {
788
+ src: this.image.src,
789
+ offset: this.offset,
790
+ zoom: this.zoom
791
+ };
792
+ }
793
+ }, {
794
+ key: 'imageSrc',
795
+ get: function () {
796
+ return this.image.src;
797
+ },
798
+ set: function (imageSrc) {
799
+ this.loadImage(imageSrc);
800
+ }
801
+ }, {
802
+ key: 'imageWidth',
803
+ get: function () {
804
+ return this.rotation % 180 === 0 ? this.image.width : this.image.height;
805
+ }
806
+ }, {
807
+ key: 'imageHeight',
808
+ get: function () {
809
+ return this.rotation % 180 === 0 ? this.image.height : this.image.width;
810
+ }
811
+ }, {
812
+ key: 'imageSize',
813
+ get: function () {
814
+ return {
815
+ width: this.imageWidth,
816
+ height: this.imageHeight
817
+ };
818
+ }
819
+ }, {
820
+ key: 'initialZoom',
821
+ get: function () {
822
+ return this.options.initialZoom;
823
+ },
824
+ set: function (initialZoomOption) {
825
+ this.options.initialZoom = initialZoomOption;
826
+ if (initialZoomOption === 'min') {
827
+ this._initialZoom = 0; // Will be fixed when image loads
828
+ } else if (initialZoomOption === 'image') {
829
+ this._initialZoom = 1;
830
+ } else {
831
+ this._initialZoom = 0;
832
+ }
833
+ }
834
+ }, {
835
+ key: 'exportZoom',
836
+ get: function () {
837
+ return this.options.exportZoom;
838
+ },
839
+ set: function (exportZoom) {
840
+ this.options.exportZoom = exportZoom;
841
+ this.setupZoomer();
842
+ }
843
+ }, {
844
+ key: 'minZoom',
845
+ get: function () {
846
+ return this.options.minZoom;
847
+ },
848
+ set: function (minZoom) {
849
+ this.options.minZoom = minZoom;
850
+ this.setupZoomer();
851
+ }
852
+ }, {
853
+ key: 'maxZoom',
854
+ get: function () {
855
+ return this.options.maxZoom;
856
+ },
857
+ set: function (maxZoom) {
858
+ this.options.maxZoom = maxZoom;
859
+ this.setupZoomer();
860
+ }
861
+ }, {
862
+ key: 'previewSize',
863
+ get: function () {
864
+ return this._previewSize;
865
+ },
866
+ set: function (size) {
867
+ if (!size || size.width <= 0 || size.height <= 0) {
868
+ return;
869
+ }
870
+
871
+ this._previewSize = {
872
+ width: size.width,
873
+ height: size.height
874
+ };
875
+ this.$preview.innerWidth(this.previewSize.width).innerHeight(this.previewSize.height);
876
+
877
+ if (this.imageLoaded) {
878
+ this.setupZoomer();
879
+ }
880
+ }
881
+ }]);
882
+
883
+ return Cropit;
884
+ })();
885
+
886
+ exports['default'] = Cropit;
887
+ module.exports = exports['default'];
888
+
889
+ /***/ },
890
+ /* 3 */
891
+ /***/ function(module, exports) {
892
+
893
+ Object.defineProperty(exports, '__esModule', {
894
+ value: true
895
+ });
896
+
897
+ var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
898
+
899
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
900
+
901
+ var Zoomer = (function () {
902
+ function Zoomer() {
903
+ _classCallCheck(this, Zoomer);
904
+
905
+ this.minZoom = this.maxZoom = 1;
906
+ }
907
+
908
+ _createClass(Zoomer, [{
909
+ key: 'setup',
910
+ value: function setup(_ref) {
911
+ var imageSize = _ref.imageSize;
912
+ var previewSize = _ref.previewSize;
913
+ var exportZoom = _ref.exportZoom;
914
+ var maxZoom = _ref.maxZoom;
915
+ var minZoom = _ref.minZoom;
916
+ var smallImage = _ref.smallImage;
917
+
918
+ var widthRatio = previewSize.width / imageSize.width;
919
+ var heightRatio = previewSize.height / imageSize.height;
920
+
921
+ if (minZoom === 'fit') {
922
+ this.minZoom = Math.min(widthRatio, heightRatio);
923
+ } else {
924
+ this.minZoom = Math.max(widthRatio, heightRatio);
925
+ }
926
+
927
+ if (smallImage === 'allow') {
928
+ this.minZoom = Math.min(this.minZoom, 1);
929
+ }
930
+
931
+ this.maxZoom = Math.max(this.minZoom, maxZoom / exportZoom);
932
+ }
933
+ }, {
934
+ key: 'getZoom',
935
+ value: function getZoom(sliderPos) {
936
+ if (!this.minZoom || !this.maxZoom) {
937
+ return null;
938
+ }
939
+
940
+ return sliderPos * (this.maxZoom - this.minZoom) + this.minZoom;
941
+ }
942
+ }, {
943
+ key: 'getSliderPos',
944
+ value: function getSliderPos(zoom) {
945
+ if (!this.minZoom || !this.maxZoom) {
946
+ return null;
947
+ }
948
+
949
+ if (this.minZoom === this.maxZoom) {
950
+ return 0;
951
+ } else {
952
+ return (zoom - this.minZoom) / (this.maxZoom - this.minZoom);
953
+ }
954
+ }
955
+ }, {
956
+ key: 'isZoomable',
957
+ value: function isZoomable() {
958
+ if (!this.minZoom || !this.maxZoom) {
959
+ return null;
960
+ }
961
+
962
+ return this.minZoom !== this.maxZoom;
963
+ }
964
+ }, {
965
+ key: 'fixZoom',
966
+ value: function fixZoom(zoom) {
967
+ return Math.max(this.minZoom, Math.min(this.maxZoom, zoom));
968
+ }
969
+ }]);
970
+
971
+ return Zoomer;
972
+ })();
973
+
974
+ exports['default'] = Zoomer;
975
+ module.exports = exports['default'];
976
+
977
+ /***/ },
978
+ /* 4 */
979
+ /***/ function(module, exports) {
980
+
981
+ Object.defineProperty(exports, '__esModule', {
982
+ value: true
983
+ });
984
+ var PLUGIN_KEY = 'cropit';
985
+
986
+ exports.PLUGIN_KEY = PLUGIN_KEY;
987
+ var CLASS_NAMES = {
988
+ PREVIEW: 'cropit-preview',
989
+ PREVIEW_IMAGE_CONTAINER: 'cropit-preview-image-container',
990
+ PREVIEW_IMAGE: 'cropit-preview-image',
991
+ PREVIEW_BACKGROUND_CONTAINER: 'cropit-preview-background-container',
992
+ PREVIEW_BACKGROUND: 'cropit-preview-background',
993
+ FILE_INPUT: 'cropit-image-input',
994
+ ZOOM_SLIDER: 'cropit-image-zoom-input',
995
+
996
+ DRAG_HOVERED: 'cropit-drag-hovered',
997
+ IMAGE_LOADING: 'cropit-image-loading',
998
+ IMAGE_LOADED: 'cropit-image-loaded',
999
+ DISABLED: 'cropit-disabled'
1000
+ };
1001
+
1002
+ exports.CLASS_NAMES = CLASS_NAMES;
1003
+ var ERRORS = {
1004
+ IMAGE_FAILED_TO_LOAD: { code: 0, message: 'Image failed to load.' },
1005
+ SMALL_IMAGE: { code: 1, message: 'Image is too small.' }
1006
+ };
1007
+
1008
+ exports.ERRORS = ERRORS;
1009
+ var eventName = function eventName(events) {
1010
+ return events.map(function (e) {
1011
+ return '' + e + '.cropit';
1012
+ }).join(' ');
1013
+ };
1014
+ var EVENTS = {
1015
+ PREVIEW: eventName(['mousedown', 'mouseup', 'mouseleave', 'touchstart', 'touchend', 'touchcancel', 'touchleave']),
1016
+ PREVIEW_MOVE: eventName(['mousemove', 'touchmove']),
1017
+ ZOOM_INPUT: eventName(['mousemove', 'touchmove', 'change'])
1018
+ };
1019
+ exports.EVENTS = EVENTS;
1020
+
1021
+ /***/ },
1022
+ /* 5 */
1023
+ /***/ function(module, exports, __webpack_require__) {
1024
+
1025
+ Object.defineProperty(exports, '__esModule', {
1026
+ value: true
1027
+ });
1028
+
1029
+ var _constants = __webpack_require__(4);
1030
+
1031
+ var options = {
1032
+ elements: [{
1033
+ name: '$preview',
1034
+ description: 'The HTML element that displays image preview.',
1035
+ defaultSelector: '.' + _constants.CLASS_NAMES.PREVIEW
1036
+ }, {
1037
+ name: '$fileInput',
1038
+ description: 'File input element.',
1039
+ defaultSelector: 'input.' + _constants.CLASS_NAMES.FILE_INPUT
1040
+ }, {
1041
+ name: '$zoomSlider',
1042
+ description: 'Range input element that controls image zoom.',
1043
+ defaultSelector: 'input.' + _constants.CLASS_NAMES.ZOOM_SLIDER
1044
+ }].map(function (o) {
1045
+ o.type = 'jQuery element';
1046
+ o['default'] = '$imageCropper.find(\'' + o.defaultSelector + '\')';
1047
+ return o;
1048
+ }),
1049
+
1050
+ values: [{
1051
+ name: 'width',
1052
+ type: 'number',
1053
+ description: 'Width of image preview in pixels. If set, it will override the CSS property.',
1054
+ 'default': null
1055
+ }, {
1056
+ name: 'height',
1057
+ type: 'number',
1058
+ description: 'Height of image preview in pixels. If set, it will override the CSS property.',
1059
+ 'default': null
1060
+ }, {
1061
+ name: 'imageBackground',
1062
+ type: 'boolean',
1063
+ description: 'Whether or not to display the background image beyond the preview area.',
1064
+ 'default': false
1065
+ }, {
1066
+ name: 'imageBackgroundBorderWidth',
1067
+ type: 'array or number',
1068
+ description: 'Width of background image border in pixels.\n The four array elements specify the width of background image width on the top, right, bottom, left side respectively.\n The background image beyond the width will be hidden.\n If specified as a number, border with uniform width on all sides will be applied.',
1069
+ 'default': [0, 0, 0, 0]
1070
+ }, {
1071
+ name: 'exportZoom',
1072
+ type: 'number',
1073
+ description: 'The ratio between the desired image size to export and the preview size.\n For example, if the preview size is `300px * 200px`, and `exportZoom = 2`, then\n the exported image size will be `600px * 400px`.\n This also affects the maximum zoom level, since the exported image cannot be zoomed to larger than its original size.',
1074
+ 'default': 1
1075
+ }, {
1076
+ name: 'allowDragNDrop',
1077
+ type: 'boolean',
1078
+ description: 'When set to true, you can load an image by dragging it from local file browser onto the preview area.',
1079
+ 'default': true
1080
+ }, {
1081
+ name: 'minZoom',
1082
+ type: 'string',
1083
+ description: 'This options decides the minimal zoom level of the image.\n If set to `\'fill\'`, the image has to fill the preview area, i.e. both width and height must not go smaller than the preview area.\n If set to `\'fit\'`, the image can shrink further to fit the preview area, i.e. at least one of its edges must not go smaller than the preview area.',
1084
+ 'default': 'fill'
1085
+ }, {
1086
+ name: 'maxZoom',
1087
+ type: 'number',
1088
+ description: 'Determines how big the image can be zoomed. E.g. if set to 1.5, the image can be zoomed to 150% of its original size.',
1089
+ 'default': 1
1090
+ }, {
1091
+ name: 'initialZoom',
1092
+ type: 'string',
1093
+ description: 'Determines the zoom when an image is loaded.\n When set to `\'min\'`, image is zoomed to the smallest when loaded.\n When set to `\'image\'`, image is zoomed to 100% when loaded.',
1094
+ 'default': 'min'
1095
+ }, {
1096
+ name: 'freeMove',
1097
+ type: 'boolean',
1098
+ description: 'When set to true, you can freely move the image instead of being bound to the container borders',
1099
+ 'default': false
1100
+ }, {
1101
+ name: 'smallImage',
1102
+ type: 'string',
1103
+ description: 'When set to `\'reject\'`, `onImageError` would be called when cropit loads an image that is smaller than the container.\n When set to `\'allow\'`, images smaller than the container can be zoomed down to its original size, overiding `minZoom` option.\n When set to `\'stretch\'`, the minimum zoom of small images would follow `minZoom` option.',
1104
+ 'default': 'reject'
1105
+ }],
1106
+
1107
+ callbacks: [{
1108
+ name: 'onFileChange',
1109
+ description: 'Called when user selects a file in the select file input.',
1110
+ params: [{
1111
+ name: 'event',
1112
+ type: 'object',
1113
+ description: 'File change event object'
1114
+ }]
1115
+ }, {
1116
+ name: 'onFileReaderError',
1117
+ description: 'Called when `FileReader` encounters an error while loading the image file.'
1118
+ }, {
1119
+ name: 'onImageLoading',
1120
+ description: 'Called when image starts to be loaded.'
1121
+ }, {
1122
+ name: 'onImageLoaded',
1123
+ description: 'Called when image is loaded.'
1124
+ }, {
1125
+ name: 'onImageError',
1126
+ description: 'Called when image cannot be loaded.',
1127
+ params: [{
1128
+ name: 'error',
1129
+ type: 'object',
1130
+ description: 'Error object.'
1131
+ }, {
1132
+ name: 'error.code',
1133
+ type: 'number',
1134
+ description: 'Error code. `0` means generic image loading failure. `1` means image is too small.'
1135
+ }, {
1136
+ name: 'error.message',
1137
+ type: 'string',
1138
+ description: 'A message explaining the error.'
1139
+ }]
1140
+ }, {
1141
+ name: 'onZoomEnabled',
1142
+ description: 'Called when image the zoom slider is enabled.'
1143
+ }, {
1144
+ name: 'onZoomDisabled',
1145
+ description: 'Called when image the zoom slider is disabled.'
1146
+ }, {
1147
+ name: 'onZoomChange',
1148
+ description: 'Called when zoom changes.',
1149
+ params: [{
1150
+ name: 'zoom',
1151
+ type: 'number',
1152
+ description: 'New zoom.'
1153
+ }]
1154
+ }, {
1155
+ name: 'onOffsetChange',
1156
+ description: 'Called when image offset changes.',
1157
+ params: [{
1158
+ name: 'offset',
1159
+ type: 'object',
1160
+ description: 'New offset, with `x` and `y` values.'
1161
+ }]
1162
+ }].map(function (o) {
1163
+ o.type = 'function';return o;
1164
+ })
1165
+ };
1166
+
1167
+ var loadDefaults = function loadDefaults($el) {
1168
+ var defaults = {};
1169
+ if ($el) {
1170
+ options.elements.forEach(function (o) {
1171
+ defaults[o.name] = $el.find(o.defaultSelector);
1172
+ });
1173
+ }
1174
+ options.values.forEach(function (o) {
1175
+ defaults[o.name] = o['default'];
1176
+ });
1177
+ options.callbacks.forEach(function (o) {
1178
+ defaults[o.name] = function () {};
1179
+ });
1180
+
1181
+ return defaults;
1182
+ };
1183
+
1184
+ exports.loadDefaults = loadDefaults;
1185
+ exports['default'] = options;
1186
+
1187
+ /***/ },
1188
+ /* 6 */
1189
+ /***/ function(module, exports) {
1190
+
1191
+ Object.defineProperty(exports, '__esModule', {
1192
+ value: true
1193
+ });
1194
+ var exists = function exists(v) {
1195
+ return typeof v !== 'undefined';
1196
+ };
1197
+
1198
+ exports.exists = exists;
1199
+ var round = function round(x) {
1200
+ return +(Math.round(x * 100) + 'e-2');
1201
+ };
1202
+ exports.round = round;
1203
+
1204
+ /***/ }
1205
+ /******/ ])
1206
+ });
1207
+ ;
assets/js/jquery.mb-comingsoon.js ADDED
@@ -0,0 +1,346 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**************************************************************************
2
+ *------------------------ COMINGSOON COUNTER 1.1 ------------------------
3
+ * ========================================================================
4
+ * Copyright 2014 Bruno Milgiaretti http://www.sisteminterattivi.org
5
+ * Licensed under MIT http://opensource.org/licenses/MIT
6
+ * ========================================================================
7
+ Usage:
8
+ Constructor:
9
+ $(selector).mbComingsoon(expiryDate Date or String) Expiry date of counter
10
+ $(selector).mbComingsoon(options plain Object) options: {
11
+ expiryDate: Date, //Expiry Date required
12
+ interval: Number, //Update interval in milliseconds (default = 1000))
13
+ localization: {
14
+ days: "days", //Localize labels of counter
15
+ hours: "hours",
16
+ minutes: "minutes",
17
+ seconds: "seconds"
18
+ }
19
+ callBack: Function //Function executed on expiry or if espired
20
+ }
21
+ Methds:
22
+ .mbComingSoon('start') // start counter
23
+ .mbComingSoon('stop') // stop counter
24
+ .mbComingSoon(options) // change options
25
+
26
+ Note: Max time that the counter can display is 999 days 23h 59' 59". If time is greater hours, minutes and seconds will be displayed
27
+ correctly, but days will be 999 until decrease under this quota.
28
+ */
29
+
30
+ (function ($) {
31
+ // Class Definition
32
+ var MbComingsoon;
33
+ MbComingsoon = function (date, element, localization, speed, callBack, gmt, showText) {
34
+ this.$el = $(element);
35
+ this.gmt = gmt;
36
+ this.showText = showText;
37
+ this.end = date;
38
+ this.active = false;
39
+ this.interval = 1000;
40
+ this.speed = speed;
41
+ if (jQuery.isFunction(callBack))
42
+ this.callBack = callBack;
43
+ else
44
+ this.callBack = null;
45
+ this.localization = {days: "days", hours: "hours", minutes: "minutes", seconds: "seconds"};
46
+ $.extend(this.localization, this.localization, localization);
47
+
48
+ }
49
+
50
+ MbComingsoon.prototype = {
51
+ // Returns an object containing counter data
52
+ getCounterNumbers: function () {
53
+ var result = {
54
+ days : {
55
+ tens : 0,
56
+ units : 0,
57
+ hundreds: 0
58
+ },
59
+ hours : {
60
+ tens : 0,
61
+ units: 0
62
+ },
63
+ minutes: {
64
+ tens : 0,
65
+ units: 0
66
+ },
67
+ seconds: {
68
+ tens : 0,
69
+ units: 0
70
+ }
71
+ }, millday = 1000 * 60 * 60 * 24,
72
+ millhour = 1000 * 60 * 60,
73
+ millminutes = 1000 * 60,
74
+ millseconds = 1000,
75
+ rest = 0
76
+ ;
77
+
78
+ var now = new Date();
79
+ var time_gmt = now.getTimezoneOffset() / 60 + this.gmt;
80
+ var diff = this.end.getTime() - now.getTime() - (time_gmt * 60 * 60000);
81
+ // CountDown expired !!
82
+ if (diff <= 0)
83
+ return result;
84
+
85
+ // Max number of days is 99 (i will expand in future versions)
86
+ var days = Math.min(Math.floor(diff / millday), 999);
87
+ rest = diff % millday;
88
+
89
+ result.days.hundreds = Math.floor(days / 100);
90
+ var dayrest = days % 100;
91
+ result.days.tens = Math.floor(dayrest / 10);
92
+ result.days.units = dayrest % 10;
93
+
94
+ var hours = Math.floor(rest / millhour);
95
+ rest = rest % millhour;
96
+ result.hours.tens = Math.floor(hours / 10);
97
+ result.hours.units = hours % 10;
98
+
99
+ var minutes = Math.floor(rest / millminutes);
100
+ rest = rest % millminutes;
101
+ result.minutes.tens = Math.floor(minutes / 10);
102
+ result.minutes.units = minutes % 10;
103
+
104
+ var seconds = Math.floor(rest / 1000);
105
+ result.seconds.tens = Math.floor(seconds / 10);
106
+ result.seconds.units = seconds % 10;
107
+ return result;
108
+ },
109
+ // If changed update a part (day, hours, minutes, seconds) of counter
110
+ updatePart : function (part) {
111
+ var cn = this.getCounterNumbers();
112
+ var $part = $('.' + part, this.$el);
113
+ if (part == 'days') {
114
+ this.setDayHundreds(cn.days.hundreds > 0);
115
+ if ($part.find('.number.hundreds.show').html() != cn[part].hundreds) {
116
+ var $n1 = $('.n1.hundreds', $part);
117
+ var $n2 = $('.n2.hundreds', $part);
118
+ this.scrollNumber($n1, $n2, cn[part].hundreds);
119
+ }
120
+ }
121
+ if ($part.find('.number.tens.show').html() != cn[part].tens) {
122
+ var $n1 = $('.n1.tens', $part);
123
+ var $n2 = $('.n2.tens', $part);
124
+ this.scrollNumber($n1, $n2, cn[part].tens);
125
+
126
+ }
127
+ if ($part.find('.number.units.show').html() != cn[part].units) {
128
+ var $n1 = $('.n1.units', $part);
129
+ var $n2 = $('.n2.units', $part);
130
+ this.scrollNumber($n1, $n2, cn[part].units);
131
+ }
132
+ // Only forn day part update hundreds
133
+ },
134
+ // True if countdown is expired
135
+ timeOut : function () {
136
+ var now = new Date()
137
+ var time_gmt = now.getTimezoneOffset() / 60 + this.gmt;
138
+ var diff = this.end.getTime() - now.getTime() - (time_gmt * 60 * 60000);
139
+ if (diff <= 0)
140
+ return true;
141
+ return false;
142
+ },
143
+ setDayHundreds : function (action) {
144
+ if (action)
145
+ $('.counter.days', this.$el).addClass('with-hundreds');
146
+ else
147
+ $('.counter.days', this.$el).removeClass('with-hundreds');
148
+ },
149
+ // Update entire counter
150
+ updateCounter : function () {
151
+ this.updatePart('days');
152
+ this.updatePart('hours');
153
+ this.updatePart('minutes');
154
+ this.updatePart('seconds');
155
+ if (this.timeOut()) {
156
+ this.active = false;
157
+ if (this.callBack)
158
+ this.callBack(this);
159
+ }
160
+ },
161
+ localize : function (localization) {
162
+ if ($.isPlainObject(localization))
163
+ $.extend(this.localization, this.localization, localization);
164
+ $('.days', this.$el).siblings('.counter-caption').text(this.localization.days);
165
+ $('.hours', this.$el).siblings('.counter-caption').text(this.localization.hours);
166
+ $('.minutes', this.$el).siblings('.counter-caption').text(this.localization.minutes);
167
+ $('.seconds', this.$el).siblings('.counter-caption').text(this.localization.seconds);
168
+ },
169
+ // Start automatic update (interval in milliseconds)
170
+ start : function (interval) {
171
+ if (interval)
172
+ this.interval = interval;
173
+ var i = this.interval;
174
+ this.active = true;
175
+ var me = this;
176
+ setTimeout(function () {
177
+ me.updateCounter();
178
+ if (me.active)
179
+ me.start();
180
+ }, i);
181
+ },
182
+ // Stop automatic update
183
+ stop : function () {
184
+ this.active = false;
185
+ },
186
+ // Animation of a single
187
+ scrollNumber : function ($n1, $n2, value) {
188
+ if ($n1.hasClass('show')) {
189
+ $n2.removeClass('hidden-down')
190
+ .css('top', '-100%')
191
+ .text(value)
192
+ .stop()
193
+ .animate({ top: 0 }, this.speed, function () {
194
+ $n2.addClass('show');
195
+ });
196
+ $n1.stop().animate({ top: "100%" }, this.speed, function () {
197
+ $n1.removeClass('show')
198
+ .addClass('hidden-down');
199
+ });
200
+ } else {
201
+ $n1.removeClass('hidden-down')
202
+ .css('top', '-100%')
203
+ .text(value)
204
+ .stop()
205
+ .animate({ top: 0 }, this.speed, function () {
206
+ $n1.addClass('show');
207
+ });
208
+ $n2.stop().animate({ top: "100%" }, this.speed, function () {
209
+ $n2.removeClass('show')
210
+ .addClass('hidden-down');
211
+ });
212
+ }
213
+ }
214
+ }
215
+
216
+ // jQuery plugin
217
+ jQuery.fn.mbComingsoon = function (opt) {
218
+ var defaults = {
219
+ interval : 1000,
220
+ callBack : null,
221
+ localization: { days: "days", hours: "hours", minutes: "minutes", seconds: "seconds" },
222
+ speed : 500,
223
+ gmt : 0,
224
+ showText : 1
225
+ }
226
+ var options = {};
227
+
228
+ var content = ' <div class="counter-group" id="myCounter">' +
229
+ ' <div class="counter-block">' +
230
+ ' <div class="counter days">' +
231
+ ' <div class="number show n1 hundreds">0</div>' +
232
+ ' <div class="number show n1 tens">0</div>' +
233
+ ' <div class="number show n1 units">0</div>' +
234
+ ' <div class="number hidden-up n2 hundreds">0</div>' +
235
+ ' <div class="number hidden-up n2 tens">0</div>' +
236
+ ' <div class="number hidden-up n2 units">0</div>' +
237
+ ' </div>' +
238
+ ' <div class="counter-caption">days</div>' +
239
+ ' </div>' +
240
+ ' <div class="counter-block">' +
241
+ ' <div class="counter hours">' +
242
+ ' <div class="number show n1 tens">0</div>' +
243
+ ' <div class="number show n1 units">0</div>' +
244
+ ' <div class="number hidden-up n2 tens">0</div>' +
245
+ ' <div class="number hidden-up n2 units">0</div>' +
246
+ ' </div>' +
247
+ ' <div class="counter-caption">hours</div>' +
248
+ ' </div>' +
249
+ ' <div class="counter-block">' +
250
+ ' <div class="counter minutes">' +
251
+ ' <div class="number show n1 tens">0</div>' +
252
+ ' <div class="number show n1 units">0</div>' +
253
+ ' <div class="number hidden-up n2 tens">0</div>' +
254
+ ' <div class="number hidden-up n2 units">0</div>' +
255
+ ' </div>' +
256
+ ' <div class="counter-caption">minutes</div>' +
257
+ ' </div>' +
258
+ ' <div class="counter-block">' +
259
+ ' <div class="counter seconds">' +
260
+ ' <div class="number show n1 tens">0</div>' +
261
+ ' <div class="number show n1 units">0</div>' +
262
+ ' <div class="number hidden-up n2 tens">0</div>' +
263
+ ' <div class="number hidden-up n2 units">0</div>' +
264
+ ' </div>' +
265
+ ' <div class="counter-caption">seconds</div>' +
266
+ ' </div>' +
267
+ ' </div>';
268
+ var content_notext = ' <div class="counter-group" id="myCounter">' +
269
+ ' <div class="counter-block">' +
270
+ ' <div class="counter days">' +
271
+ ' <div class="number show n1 hundreds">0</div>' +
272
+ ' <div class="number show n1 tens">0</div>' +
273
+ ' <div class="number show n1 units">0</div>' +
274
+ ' <div class="number hidden-up n2 hundreds">0</div>' +
275
+ ' <div class="number hidden-up n2 tens">0</div>' +
276
+ ' <div class="number hidden-up n2 units">0</div>' +
277
+ ' </div>' +
278
+ ' </div>' +
279
+ ' <div class="counter-block">' +
280
+ ' <div class="counter hours">' +
281
+ ' <div class="number show n1 tens">0</div>' +
282
+ ' <div class="number show n1 units">0</div>' +
283
+ ' <div class="number hidden-up n2 tens">0</div>' +
284
+ ' <div class="number hidden-up n2 units">0</div>' +
285
+ ' </div>' +
286
+ ' </div>' +
287
+ ' <div class="counter-block">' +
288
+ ' <div class="counter minutes">' +
289
+ ' <div class="number show n1 tens">0</div>' +
290
+ ' <div class="number show n1 units">0</div>' +
291
+ ' <div class="number hidden-up n2 tens">0</div>' +
292
+ ' <div class="number hidden-up n2 units">0</div>' +
293
+ ' </div>' +
294
+ ' </div>' +
295
+ ' <div class="counter-block">' +
296
+ ' <div class="counter seconds">' +
297
+ ' <div class="number show n1 tens">0</div>' +
298
+ ' <div class="number show n1 units">0</div>' +
299
+ ' <div class="number hidden-up n2 tens">0</div>' +
300
+ ' <div class="number hidden-up n2 units">0</div>' +
301
+ ' </div>' +
302
+ ' </div>' +
303
+ ' </div>';
304
+ return this.each(function () {
305
+ var $this = $(this);
306
+ var data = $this.data('mbComingsoon');
307
+ if (!data) {
308
+ if (opt instanceof Date)
309
+ options.expiryDate = opt;
310
+ else if ($.isPlainObject(opt))
311
+ $.extend(options, defaults, opt);
312
+ else if (typeof opt == "string")
313
+ options.expiryDate = new Date(opt);
314
+ if (!options.expiryDate)
315
+ throw new Error('Expiry date is required!');
316
+
317
+ data = new MbComingsoon(options.expiryDate, $this, options.localization, options.speed, options.callBack, options.gmt, options.showText);
318
+ if (options.showText) {
319
+ $this.html(content);
320
+ } else {
321
+ $this.html(content_notext);
322
+ }
323
+ data.localize();
324
+ data.start();
325
+ } else if (opt == 'start')
326
+ data.start();
327
+ else if (opt == 'stop')
328
+ data.stop();
329
+ else if ($.isPlainObject(opt)) {
330
+ if (opt.expiryDate instanceof Date)
331
+ data.end = opt.expiryDate;
332
+ if ($.isNumeric(opt.interval))
333
+ data.interval = opt.interval;
334
+ if ($.isNumeric(opt.gmt))
335
+ data.gmt = opt.gmt;
336
+ if ($.isNumeric(opt.showText))
337
+ data.showText = opt.showText;
338
+ if ($.isFunction(opt.callBack))
339
+ data.callBack = opt.callBack;
340
+ if ($.isPlainObject(opt.localization))
341
+ this.localize(opt.localization);
342
+ }
343
+ })
344
+ }
345
+
346
+ })(jQuery)
assets/js/jquery.mb-comingsoon.min.js ADDED
@@ -0,0 +1 @@
 
1
+ (function(e){var t;t=function(t,n,r,i,s,o,u){this.$el=e(n);this.gmt=o;this.showText=u;this.end=t;this.active=false;this.interval=1e3;this.speed=i;if(jQuery.isFunction(s))this.callBack=s;else this.callBack=null;this.localization={days:"days",hours:"hours",minutes:"minutes",seconds:"seconds"};e.extend(this.localization,this.localization,r)};t.prototype={getCounterNumbers:function(){var e={days:{tens:0,units:0,hundreds:0},hours:{tens:0,units:0},minutes:{tens:0,units:0},seconds:{tens:0,units:0}},t=1e3*60*60*24,n=1e3*60*60,r=1e3*60,i=1e3,s=0;var o=new Date;var u=o.getTimezoneOffset()/60+this.gmt;var a=this.end.getTime()-o.getTime()-u*60*6e4;if(a<=0)return e;var f=Math.min(Math.floor(a/t),999);s=a%t;e.days.hundreds=Math.floor(f/100);var l=f%100;e.days.tens=Math.floor(l/10);e.days.units=l%10;var c=Math.floor(s/n);s=s%n;e.hours.tens=Math.floor(c/10);e.hours.units=c%10;var h=Math.floor(s/r);s=s%r;e.minutes.tens=Math.floor(h/10);e.minutes.units=h%10;var p=Math.floor(s/1e3);e.seconds.tens=Math.floor(p/10);e.seconds.units=p%10;return e},updatePart:function(t){var n=this.getCounterNumbers();var r=e("."+t,this.$el);if(t=="days"){this.setDayHundreds(n.days.hundreds>0);if(r.find(".number.hundreds.show").html()!=n[t].hundreds){var i=e(".n1.hundreds",r);var s=e(".n2.hundreds",r);this.scrollNumber(i,s,n[t].hundreds)}}if(r.find(".number.tens.show").html()!=n[t].tens){var i=e(".n1.tens",r);var s=e(".n2.tens",r);this.scrollNumber(i,s,n[t].tens)}if(r.find(".number.units.show").html()!=n[t].units){var i=e(".n1.units",r);var s=e(".n2.units",r);this.scrollNumber(i,s,n[t].units)}},timeOut:function(){var e=new Date;var t=e.getTimezoneOffset()/60+this.gmt;var n=this.end.getTime()-e.getTime()-t*60*6e4;if(n<=0)return true;return false},setDayHundreds:function(t){if(t)e(".counter.days",this.$el).addClass("with-hundreds");else e(".counter.days",this.$el).removeClass("with-hundreds")},updateCounter:function(){this.updatePart("days");this.updatePart("hours");this.updatePart("minutes");this.updatePart("seconds");if(this.timeOut()){this.active=false;if(this.callBack)this.callBack(this)}},localize:function(t){if(e.isPlainObject(t))e.extend(this.localization,this.localization,t);e(".days",this.$el).siblings(".counter-caption").text(this.localization.days);e(".hours",this.$el).siblings(".counter-caption").text(this.localization.hours);e(".minutes",this.$el).siblings(".counter-caption").text(this.localization.minutes);e(".seconds",this.$el).siblings(".counter-caption").text(this.localization.seconds)},start:function(e){if(e)this.interval=e;var t=this.interval;this.active=true;var n=this;setTimeout(function(){n.updateCounter();if(n.active)n.start()},t)},stop:function(){this.active=false},scrollNumber:function(e,t,n){if(e.hasClass("show")){t.removeClass("hidden-down").css("top","-100%").text(n).stop().animate({top:0},this.speed,function(){t.addClass("show")});e.stop().animate({top:"100%"},this.speed,function(){e.removeClass("show").addClass("hidden-down")})}else{e.removeClass("hidden-down").css("top","-100%").text(n).stop().animate({top:0},this.speed,function(){e.addClass("show")});t.stop().animate({top:"100%"},this.speed,function(){t.removeClass("show").addClass("hidden-down")})}}};jQuery.fn.mbComingsoon=function(n){var r={interval:1e3,callBack:null,localization:{days:"days",hours:"hours",minutes:"minutes",seconds:"seconds"},speed:500,gmt:0,showText:1};var i={};var s=' <div class="counter-group" id="myCounter">'+' <div class="counter-block">'+' <div class="counter days">'+' <div class="number show n1 hundreds">0</div>'+' <div class="number show n1 tens">0</div>'+' <div class="number show n1 units">0</div>'+' <div class="number hidden-up n2 hundreds">0</div>'+' <div class="number hidden-up n2 tens">0</div>'+' <div class="number hidden-up n2 units">0</div>'+" </div>"+' <div class="counter-caption">days</div>'+" </div>"+' <div class="counter-block">'+' <div class="counter hours">'+' <div class="number show n1 tens">0</div>'+' <div class="number show n1 units">0</div>'+' <div class="number hidden-up n2 tens">0</div>'+' <div class="number hidden-up n2 units">0</div>'+" </div>"+' <div class="counter-caption">hours</div>'+" </div>"+' <div class="counter-block">'+' <div class="counter minutes">'+' <div class="number show n1 tens">0</div>'+' <div class="number show n1 units">0</div>'+' <div class="number hidden-up n2 tens">0</div>'+' <div class="number hidden-up n2 units">0</div>'+" </div>"+' <div class="counter-caption">minutes</div>'+" </div>"+' <div class="counter-block">'+' <div class="counter seconds">'+' <div class="number show n1 tens">0</div>'+' <div class="number show n1 units">0</div>'+' <div class="number hidden-up n2 tens">0</div>'+' <div class="number hidden-up n2 units">0</div>'+" </div>"+' <div class="counter-caption">seconds</div>'+" </div>"+" </div>";var o=' <div class="counter-group" id="myCounter">'+' <div class="counter-block">'+' <div class="counter days">'+' <div class="number show n1 hundreds">0</div>'+' <div class="number show n1 tens">0</div>'+' <div class="number show n1 units">0</div>'+' <div class="number hidden-up n2 hundreds">0</div>'+' <div class="number hidden-up n2 tens">0</div>'+' <div class="number hidden-up n2 units">0</div>'+" </div>"+" </div>"+' <div class="counter-block">'+' <div class="counter hours">'+' <div class="number show n1 tens">0</div>'+' <div class="number show n1 units">0</div>'+' <div class="number hidden-up n2 tens">0</div>'+' <div class="number hidden-up n2 units">0</div>'+" </div>"+" </div>"+' <div class="counter-block">'+' <div class="counter minutes">'+' <div class="number show n1 tens">0</div>'+' <div class="number show n1 units">0</div>'+' <div class="number hidden-up n2 tens">0</div>'+' <div class="number hidden-up n2 units">0</div>'+" </div>"+" </div>"+' <div class="counter-block">'+' <div class="counter seconds">'+' <div class="number show n1 tens">0</div>'+' <div class="number show n1 units">0</div>'+' <div class="number hidden-up n2 tens">0</div>'+' <div class="number hidden-up n2 units">0</div>'+" </div>"+" </div>"+" </div>";return this.each(function(){var u=e(this);var a=u.data("mbComingsoon");if(!a){if(n instanceof Date)i.expiryDate=n;else if(e.isPlainObject(n))e.extend(i,r,n);else if(typeof n=="string")i.expiryDate=new Date(n);if(!i.expiryDate)throw new Error("Expiry date is required!");a=new t(i.expiryDate,u,i.localization,i.speed,i.callBack,i.gmt,i.showText);if(i.showText){u.html(s)}else{u.html(o)}a.localize();a.start()}else if(n=="start")a.start();else if(n=="stop")a.stop();else if(e.isPlainObject(n)){if(n.expiryDate instanceof Date)a.end=n.expiryDate;if(e.isNumeric(n.interval))a.interval=n.interval;if(e.isNumeric(n.gmt))a.gmt=n.gmt;if(e.isNumeric(n.showText))a.showText=n.showText;if(e.isFunction(n.callBack))a.callBack=n.callBack;if(e.isPlainObject(n.localization))this.localize(n.localization)}})}})(jQuery)
assets/js/jquery.ocupload.js ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ One Click Upload - jQuery Plugin
3
+ --------------------------------
4
+
5
+ Copyright (c) 2008 Michael Mitchell - http://www.michaelmitchell.co.nz
6
+ Copyright (c) 2011 Andrey Fedoseev <andrey.fedoseev@gmail.com> -
7
+ http://andreyfedoseev.name
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in
17
+ all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
+ THE SOFTWARE.
26
+
27
+ */
28
+
29
+ (function ($) {
30
+ $.fn.upload = function (options) {
31
+ /** Merge the user's options with our defaults */
32
+ options = $.extend({
33
+ name: 'file',
34
+ enctype: 'multipart/form-data',
35
+ action: '',
36
+ autoSubmit: true,
37
+ onSubmit: function () {},
38
+ onComplete: function () {},
39
+ onSelect: function () {},
40
+ params: {}
41
+ }, options);
42
+
43
+ return new $.ocupload(this, options);
44
+ };
45
+
46
+ $.ocupload = function (element, options) {
47
+ /** Fix scope problems */
48
+ var self = this;
49
+
50
+ /** A unique id so we can find our elements later */
51
+ var id = new Date().getTime().toString().substr(8);
52
+
53
+ /** Upload iframe */
54
+ var iframe = $("<iframe></iframe>", {
55
+ id: "iframe" + id,
56
+ name: "iframe" + id
57
+ }).css({
58
+ display: "none"
59
+ });
60
+
61
+ /** Form */
62
+ var form = $("<form></form>", {
63
+ method: "post",
64
+ enctype: options.enctype,
65
+ action: options.action,
66
+ target: "iframe" + id
67
+ }).css({
68
+ margin: 0,
69
+ padding: 0
70
+ });
71
+
72
+ /** Get cursor type from the object ocupload was assigned to */
73
+ /** TODO: Add parameter to init? cursor: auto, cursor: pointer etc */
74
+ var element_cursor = element.css('cursor');
75
+
76
+ /** File Input */
77
+ var input = $("<input>", {
78
+ name: options.name,
79
+ "type": "file"
80
+ }).css({
81
+ position: 'absolute',
82
+ display: 'block',
83
+ cursor: element_cursor,
84
+ opacity: 0
85
+ });
86
+
87
+ /** Put everything together */
88
+
89
+ element.wrap("<div></div>");
90
+ form.append(input);
91
+ element.after(form);
92
+ element.after(iframe);
93
+
94
+ /** Find the container and make it nice and snug */
95
+ var container = element.parent().css({
96
+ position: 'relative',
97
+ height: element.outerHeight() + 'px',
98
+ width: element.outerWidth() + 'px',
99
+ overflow: 'hidden',
100
+ cursor: element_cursor,
101
+ margin: 0,
102
+ padding: 0
103
+ });
104
+
105
+ /** Get input dimensions so we can put it in the right place */
106
+ var input_height = input.outerHeight(element.outerHeight());
107
+ var input_width = input.outerWidth(element.outerWidth());
108
+ input.css({
109
+ margin: "0",
110
+ padding: "0",
111
+ top: "0",
112
+ left: "0"
113
+ });
114
+
115
+ /** Move the input with the mouse to make sure it get clicked! */
116
+ container.mousemove(function (e) {
117
+ input.css({
118
+ top: e.pageY - container.offset().top - (input_height / 2) + 'px',
119
+ left: e.pageX - container.offset().left - input_width + 30 + 'px'
120
+ });
121
+ });
122
+
123
+ function onChange() {
124
+ /** Do something when a file is selected. */
125
+ self.onSelect();
126
+
127
+ /** Submit the form automaticly after selecting the file */
128
+ if (self.autoSubmit) {
129
+ self.submit();
130
+ }
131
+ }
132
+
133
+ /** Watch for file selection */
134
+ input.change(onChange);
135
+
136
+ /** Methods */
137
+ $.extend(this, {
138
+ autoSubmit: true,
139
+ onSubmit: options.onSubmit,
140
+ onComplete: options.onComplete,
141
+ onSelect: options.onSelect,
142
+
143
+ /** get filename */
144
+ filename: function () {
145
+ return input.attr('value');
146
+ },
147
+
148
+ /** get/set params */
149
+ params: function (params) {
150
+ params = params ? params : false;
151
+ if (params) {
152
+ options.params = $.extend(options.params, params);
153
+ }
154
+ else {
155
+ return options.params;
156
+ }
157
+ },
158
+
159
+ /** get/set name */
160
+ name: function (name) {
161
+ name = name ? name : false;
162
+ if (name) {
163
+ input.attr('name', value);
164
+ }
165
+ else {
166
+ return input.attr('name');
167
+ }
168
+ },
169
+
170
+ /** get/set action */
171
+ action: function (action) {
172
+ action = action ? action : false;
173
+ if (action) {
174
+ form.attr('action', action);
175
+ }
176
+ else {
177
+ return form.attr('action');
178
+ }
179
+ },
180
+
181
+ /** get/set enctype */
182
+ enctype: function (enctype) {
183
+ enctype = enctype ? enctype : false;
184
+ if (enctype) {
185
+ form.attr('enctype', enctype);
186
+ }
187
+ else {
188
+ return form.attr('enctype');
189
+ }
190
+ },
191
+
192
+ /** set options */
193
+ set: function (obj, value) {
194
+ value = value ? value : false;
195
+ function option(action, value) {
196
+ switch (action) {
197
+ case 'name':
198
+ self.name(value);
199
+ break;
200
+ case 'action':
201
+ self.action(value);
202
+ break;
203
+ case 'enctype':
204
+ self.enctype(value);
205
+ break;
206
+ case 'params':
207
+ self.params(value);
208
+ break;
209
+ case 'autoSubmit':
210
+ self.autoSubmit = value;
211
+ break;
212
+ case 'onSubmit':
213
+ self.onSubmit = value;
214
+ break;
215
+ case 'onComplete':
216
+ self.onComplete = value;
217
+ break;
218
+ case 'onSelect':
219
+ self.onSelect = value;
220
+ break;
221
+ default:
222
+ throw new Error('[jQuery.ocupload.set] \'' + action + '\' is ' +
223
+ 'an invalid option.');
224
+ }
225
+ }
226
+
227
+ if (value) {
228
+ option(obj, value);
229
+ }
230
+ else {
231
+ $.each(obj,
232
+ function (key, value) {
233
+ option(key, value);
234
+ });
235
+ }
236
+ },
237
+
238
+ /** Submit the form */
239
+ submit: function () {
240
+ /** Do something before we upload */
241
+ this.onSubmit();
242
+
243
+ /** add additional parameters before sending */
244
+ $.each(options.params, function (key, value) {
245
+ field = form.find("input:hidden[name='" + key + "']");
246
+ if (!field.length) {
247
+ field = $('<input type="hidden">').attr("name",
248
+ key).appendTo(form);
249
+ }
250
+ field.val(value);
251
+ });
252
+
253
+ /** Submit the actual form */
254
+ form.submit();
255
+
256
+ /** Do something after we are finished uploading */
257
+ iframe.unbind().load(function () {
258
+ /** Get a response from the server in plain text */
259
+ var myFrame = document.getElementById(iframe.attr('name'));
260
+ var response = $(myFrame.contentWindow.document.body).text();
261
+
262
+ /** Do something on complete */
263
+ self.onComplete(response);
264
+ //done :D
265
+
266
+ // Reset file input field
267
+ input.wrap("<div></div>");
268
+ var wrapper = input.parent();
269
+ input = $(wrapper.html());
270
+ input.change(onChange);
271
+ wrapper.replaceWith(input);
272
+
273
+ });
274
+ }
275
+ });
276
+ };
277
+ })(jQuery);
inc/admin/class-lp-admin-ajax.php CHANGED
@@ -1,1158 +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
- 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(
67
- __CLASS__,
68
- '_modal_search_items_exclude'
69
- ), 10, 4 );
70
- add_filter( 'learn_press_modal_search_items_not_found', array(
71
- __CLASS__,
72
- '_modal_search_items_not_found'
73
- ), 10, 2 );
74
- do_action( 'learn_press_admin_ajax_load', __CLASS__ );
75
- }
76
-
77
- public static function load_chart() {
78
- if ( !class_exists( '' ) ) {
79
- require_once LP_PLUGIN_PATH . '/inc/admin/sub-menus/statistics.php';
80
- }
81
- LP_Admin_Submenu_Statistic::instance()->load_chart();
82
- }
83
-
84
- public static function search_course() {
85
- global $wpdb;
86
- $sql = "SELECT ID id, post_title text "
87
- . " FROM {$wpdb->posts} "
88
- . " WHERE post_type='lp_course' "
89
- . " AND post_status in ('publish') "
90
- . " AND post_title like %s";
91
- if ( current_user_can( LP_TEACHER_ROLE ) ) {
92
- $user_id = learn_press_get_current_user_id();
93
- $sql .= " AND post_author=" . intval( $user_id ) . " ";
94
- }
95
- $s = '%' . filter_input( INPUT_GET, 'q' ) . '%';
96
- $query = $wpdb->prepare( $sql, $s );
97
- $items = $wpdb->get_results( $query );
98
- $data = array( 'items' => $items );
99
- echo json_encode( $data );
100
- exit();
101
- }
102
-
103
- public static function search_course_category() {
104
- global $wpdb;
105
- $sql = "SELECT `t`.`term_id` as `id`, "
106
- . " `t`.`name` `text` "
107
- . " FROM {$wpdb->terms} t "
108
- . " INNER JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id AND taxonomy='course_category' "
109
- . " WHERE `t`.`name` LIKE %s";
110
- $s = '%' . filter_input( INPUT_GET, 'q' ) . '%';
111
- $query = $wpdb->prepare( $sql, $s );
112
- $items = $wpdb->get_results( $query );
113
- $data = array( 'items' => $items );
114
- echo json_encode( $data );
115
- exit();
116
- }
117
-
118
- public static function remove_course_items() {
119
- $id = learn_press_get_request( 'id' );
120
- if ( $id ) {
121
- global $wpdb;
122
- $in_clause = array_fill( 0, sizeof( $id ), '%d' );
123
- $in_clause = "IN(" . join( ",", $in_clause ) . ")";
124
- echo $wpdb->prepare( "
125
- DELETE FROM {$wpdb->prefix}learnpress_section_items
126
- WHERE section_item_id $in_clause
127
- ", $id );
128
- $wpdb->query(
129
- $wpdb->prepare( "
130
- DELETE FROM {$wpdb->prefix}learnpress_section_items
131
- WHERE section_item_id $in_clause
132
- ", $id )
133
- );
134
- }
135
- die();
136
- }
137
-
138
- public static function search_users() {
139
- if ( !current_user_can( 'edit_lp_orders' ) ) {
140
- die( - 1 );
141
- }
142
-
143
- $term = stripslashes( $_GET['term'] );
144
-
145
- if ( empty( $term ) ) {
146
- die();
147
- }
148
-
149
- $found_customers = array();
150
-
151
- add_action( 'pre_user_query', array( __CLASS__, 'json_search_customer_name' ) );
152
-
153
- $customers_query = new WP_User_Query( apply_filters( 'learn_press_search_customers_query', array(
154
- 'fields' => 'all',
155
- 'orderby' => 'display_name',
156
- 'search' => '*' . $term . '*',
157
- 'search_columns' => array( 'ID', 'user_login', 'user_email', 'user_nicename' )
158
- ) ) );
159
-
160
- remove_action( 'pre_user_query', array( __CLASS__, 'json_search_customer_name' ) );
161
-
162
- $customers = $customers_query->get_results();
163
-
164
- if ( !empty( $customers ) ) {
165
- foreach ( $customers as $customer ) {
166
- $found_customers[] = array(
167
- 'label' => $customer->display_name . ' (#' . $customer->ID . ' &ndash; ' . sanitize_email( $customer->user_email ) . ')',
168
- 'value' => $customer->ID
169
- );
170
- }
171
- }
172
-
173
- echo json_encode( $found_customers );
174
- die();
175
- }
176
-
177
- public static function json_search_customer_name( $query ) {
178
- global $wpdb;
179
-
180
- $term = stripslashes( $_GET['term'] );
181
- if ( method_exists( $wpdb, 'esc_like' ) ) {
182
- $term = $wpdb->esc_like( $term );
183
- } else {
184
- $term = like_escape( $term );
185
- }
186
-
187
- $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' ) ";
188
- $query->query_where .= $wpdb->prepare( " OR user_name.meta_value LIKE %s ", '%' . $term . '%' );
189
- }
190
-
191
- public static function dismiss_notice() {
192
- $context = learn_press_get_request( 'context' );
193
- $transient = learn_press_get_request( 'transient' );
194
-
195
- if ( $context ) {
196
- if ( $transient >= 0 ) {
197
- set_transient( 'learn_press_dismiss_notice_' . $context, 'off', $transient ? $transient : DAY_IN_SECONDS * 7 );
198
- } else {
199
- update_option( 'learn_press_dismiss_notice_' . $context, 'off' );
200
- }
201
- }
202
- die();
203
- }
204
-
205
- public static function _modal_search_items_not_found( $message, $type ) {
206
- switch ( $type ) {
207
- case 'lp_lesson':
208
- $message = __( 'There are no available lessons for this course, please use ', 'learnpress' );
209
- $message .= '<a target="_blank" href="' . admin_url( 'post-new.php?post_type=lp_lesson' ) . '">' . esc_html__( 'Adding New Item.', 'learnpress' ) . '</a>';
210
- break;
211
- case 'lp_quiz':
212
- $message = __( 'There are no available quizzes for this course, please use ', 'learnpress' );
213
- $message .= '<a target="_blank" href="' . admin_url( 'post-new.php?post_type=lp_quiz' ) . '">' . esc_html__( 'Adding New Item.', 'learnpress' ) . '</a>';
214
- break;
215
- case 'lp_question':
216
- $message = __( 'There are no available questions for this quiz, please use ', 'learnpress' );
217
- $message .= '<a target="_blank" href="' . admin_url( 'post-new.php?post_type=lp_question' ) . '">' . esc_html__( 'Adding New Item.', 'learnpress' ) . '</a>';
218
- break;
219
- }
220
-
221
- return $message;
222
- }
223
-
224
- /**
225
- * Filter to exclude the items has already added to it's parent.
226
- * Each item only use one time
227
- *
228
- * @param $exclude
229
- * @param $type
230
- * @param string $context
231
- * @param null $context_id
232
- *
233
- * @return array
234
- */
235
- public static function _modal_search_items_exclude( $exclude, $type, $context = '', $context_id = null ) {
236
- global $wpdb;
237
- $used_items = array();
238
- switch ( $type ) {
239
- case 'lp_lesson':
240
- case 'lp_quiz':
241
- $query = $wpdb->prepare( "
242
- SELECT item_id
243
- FROM {$wpdb->prefix}learnpress_section_items si
244
- INNER JOIN {$wpdb->prefix}learnpress_sections s ON s.section_id = si.section_id
245
- INNER JOIN {$wpdb->posts} p ON p.ID = s.section_course_id
246
- WHERE %d
247
- AND p.post_type = %s
248
- ", 1, LP_COURSE_CPT );
249
- $used_items = $wpdb->get_col( $query );
250
- break;
251
- case 'lp_question':
252
- $query = $wpdb->prepare( "
253
- SELECT question_id
254
- FROM {$wpdb->prefix}learnpress_quiz_questions
255
- INNER JOIN {$wpdb->posts} q ON q.ID = qq.quiz_id
256
- WHERE %d
257
- AND q.post_type = %s
258
- ", 1, LP_QUIZ_CPT );
259
- $used_items = $wpdb->get_col( $query );
260
- break;
261
-
262
- }
263
- if ( $used_items && $exclude ) {
264
- $exclude = array_merge( $exclude, $used_items );
265
- } else if ( $used_items ) {
266
- $exclude = $used_items;
267
- }
268
-
269
- return array_unique( $exclude );
270
- }
271
-
272
- public static function add_item_to_section() {
273
- global $wpdb;
274
- $section = learn_press_get_request( 'section' );
275
- if ( !$section ) {
276
- wp_die( __( 'Error', 'learnpress' ) );
277
- }
278
- $items = (array) learn_press_get_request( 'item' );
279
- if ( !$items ) {
280
- $max_order = $wpdb->get_var( $wpdb->prepare( "SELECT max() FROM {$wpdb}learnpress_section_items WHERE section_id = %d", $section ) );
281
- foreach ( $items as $item ) {
282
-
283
- }
284
- }
285
- }
286
-
287
- public static function modal_search_items() {
288
- global $wpdb;
289
-
290
- $user = learn_press_get_current_user();
291
- $term = (string) ( stripslashes( learn_press_get_request( 'term' ) ) );
292
- $type = (string) ( stripslashes( learn_press_get_request( 'type' ) ) );
293
- $context = (string) ( stripslashes( learn_press_get_request( 'context' ) ) );
294
- $context_id = (string) ( stripslashes( learn_press_get_request( 'context_id' ) ) );
295
- $exclude = array();
296
-
297
- if ( !empty( $_GET['exclude'] ) ) {
298
- $exclude = array_map( 'intval', $_GET['exclude'] );
299
- }
300
- $exclude = array_unique( (array) apply_filters( 'learn_press_modal_search_items_exclude', $exclude, $type, $context, $context_id ) );
301
- $exclude = array_map( 'intval', $exclude );
302
- $args = array(
303
- 'post_type' => array( $type ),
304
- 'posts_per_page' => - 1,
305
- 'post_status' => 'publish',
306
- 'order' => 'ASC',
307
- 'orderby' => 'parent title',
308
- 'exclude' => $exclude
309
- );
310
- if ( !$user->is_admin() ) {
311
- $args['author'] = $user->id;
312
- }
313
-
314
- if ( $context && $context_id ) {
315
- switch ( $context ) {
316
- /**
317
- * If is search lesson/quiz for course only search the items of course's author
318
- */
319
- case 'course-items':
320
- if ( get_post_type( $context_id ) == 'lp_course' ) {
321
- $args['author'] = get_post_field( 'post_author', $context_id );
322
- }
323
- break;
324
- /**
325
- * If is search question for quiz only search the items of course's author
326
- */
327
- case 'quiz-items':
328
- if ( get_post_type( $context_id ) == 'lp_quiz' ) {
329
- $args['author'] = get_post_field( 'post_author', $context_id );
330
- }
331
- break;
332
- }
333
- }
334
- if ( $term ) {
335
- $args['s'] = $term;
336
- }
337
-
338
- $posts = get_posts( $args );
339
- $found_items = array();
340
-
341
- if ( !empty( $posts ) ) {
342
- foreach ( $posts as $post ) {
343
- $found_items[$post->ID] = $post;
344
- $found_items[$post->ID]->post_title = !empty( $post->post_title ) ? $post->post_title : sprintf( '(%s)', __( 'Untitled', 'learnpress' ) );
345
- }
346
- }
347
-
348
- ob_start();
349
- if ( $found_items ) {
350
- foreach ( $found_items as $id => $item ) {
351
- printf( '
352
- <li class="" data-id="%1$d" data-type="%3$s" data-text="%2$s">
353
- <label>
354
- <input type="checkbox" value="%1$d">
355
- <span class="lp-item-text">%2$s</span>
356
- </label>
357
- </li>
358
- ', $id, esc_attr( $item->post_title ), $item->post_type );
359
- }
360
- } else {
361
- echo '<li>' . apply_filters( 'learn_press_modal_search_items_not_found', __( 'No item found', 'learnpress' ), $type ) . '</li>';
362
- }
363
-
364
- $item_object = $type ? get_post_type_object( $type ) : '';
365
- $post_type = $context_id ? get_post_type_object( get_post_type( $context_id ) ) : '';
366
- $response = array(
367
- 'html' => ob_get_clean(),
368
- 'data' => $found_items,
369
- '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>'
370
- );
371
- $dismiss_notice = 'learnpress_notice_' . $item_object->name . '_' . $user->id;
372
- $dismiss_notice = get_transient( $dismiss_notice );
373
- if ( $dismiss_notice || $item_object->name === 'lp_course' ) { // Check lp_course to hidden notice in order post
374
- unset( $response['notices'] );
375
- }
376
-
377
- learn_press_send_json( $response );
378
- }
379
-
380
- public static function remove_quiz_question() {
381
- global $wpdb;
382
- $quiz_id = learn_press_get_request( 'quiz_id' );
383
- $question_id = learn_press_get_request( 'question_id' );
384
- if ( !wp_verify_nonce( learn_press_get_request( 'remove-nonce' ), 'remove_quiz_question' ) ) {
385
- wp_die( __( 'Error', 'learnpress' ) );
386
- }
387
- $query = $wpdb->prepare( "
388
- DELETE FROM {$wpdb->prefix}learnpress_quiz_questions
389
- WHERE quiz_id = %d
390
- AND question_id = %d
391
- ", $quiz_id, $question_id );
392
- $wpdb->query( $query );
393
-
394
- // trigger change user memorize question types
395
- $user_id = get_current_user_id();
396
- $type = get_post_meta( $question_id, '_lp_type', true );
397
- if ( $type ) {
398
- $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
399
- $question_types = !$question_types ? array() : $question_types;
400
- $counter = !empty ( $question_types[$type] ) && $question_types[$type] ? absint( $question_types[$type] ) : 0;
401
- $question_types[$type] = $counter ? $counter -- : 0;
402
- update_user_meta( $user_id, '_learn_press_memorize_question_types', $question_types );
403
- }
404
- // end trigger change user memorize question types
405
- die();
406
- }
407
-
408
- public static function search_questions() {
409
- global $wpdb;
410
-
411
- $quiz_id = learn_press_get_request( 'quiz_id' );
412
- $user = learn_press_get_current_user();
413
- if ( !$user->is_admin() && get_post_field( 'post_author', $quiz_id ) != get_current_user_id() ) {
414
- wp_die( __( 'You have no permission to access this section.', 'learnpress' ) );
415
- }
416
- $term = (string) ( stripslashes( learn_press_get_request( 'term' ) ) );
417
- $exclude = array();
418
-
419
- if ( !empty( $_GET['exclude'] ) ) {
420
- $exclude = array_map( 'intval', $_GET['exclude'] );
421
- }
422
-
423
- $added = $wpdb->get_col(
424
- $wpdb->prepare( "
425
- SELECT question_id
426
- FROM {$wpdb->prefix}learnpress_quiz_questions
427
- WHERE %d
428
- ", 1 )
429
- );
430
- if ( $added ) {
431
- $exclude = array_merge( $exclude, $added );
432
- $exclude = array_unique( $exclude );
433
- }
434
-
435
- $args = array(
436
- 'post_type' => array( 'lp_question' ),
437
- 'posts_per_page' => - 1,
438
- 'post_status' => 'publish',
439
- 'order' => 'ASC',
440
- 'orderby' => 'parent title',
441
- 'exclude' => $exclude
442
- );
443
- if ( !$user->is_admin() ) {
444
- $args['author'] = $user->id;
445
- }
446
- if ( $term ) {
447
- $args['s'] = $term;
448
- }
449
- $posts = get_posts( $args );
450
- $found_questions = array();
451
-
452
- if ( !empty( $posts ) ) {
453
- foreach ( $posts as $post ) {
454
- $found_questions[$post->ID] = !empty( $post->post_title ) ? $post->post_title : sprintf( '(%s)', __( 'Untitled', 'learnpress' ) );
455
- }
456
- }
457
-
458
- ob_start();
459
- if ( $found_questions ) {
460
- foreach ( $found_questions as $id => $question ) {
461
- printf( '
462
- <li class="" data-id="%1$d" data-type="" data-text="%2$s">
463
- <label>
464
- <input type="checkbox" value="%1$d">
465
- <span class="lp-item-text">%2$s</span>
466
- </label>
467
- </li>
468
- ', $id, $question );
469
- }
470
- } else {
471
- echo '<li>' . __( 'No questions found', 'learnpress' ) . '</li>';
472
- }
473
-
474
- $response = array(
475
- 'html' => ob_get_clean(),
476
- 'data' => $found_questions,
477
- 'args' => $args
478
- );
479
- learn_press_send_json( $response );
480
- }
481
-
482
- public static function plugin_action() {
483
- $url = learn_press_get_request( 'url' );
484
- ob_start();
485
- wp_remote_get( $url );
486
- ob_get_clean();
487
- echo wp_remote_get( admin_url( 'admin.php?page=learn-press-addons&tab=installed' ) );
488
- die();
489
- }
490
-
491
- /**
492
- * Remove an item from order
493
- */
494
- public static function remove_order_item() {
495
- // ensure that user has permission
496
- if ( !current_user_can( 'edit_lp_orders' ) ) {
497
- die( __( 'Permission denied', 'learnpress' ) );
498
- }
499
-
500
- // verify nonce
501
- $nonce = learn_press_get_request( 'remove_nonce' );
502
- if ( !wp_verify_nonce( $nonce, 'remove_order_item' ) ) {
503
- die( __( 'Check nonce failed', 'learnpress' ) );
504
- }
505
-
506
- // validate order
507
- $order_id = learn_press_get_request( 'order_id' );
508
- if ( !is_numeric( $order_id ) || get_post_type( $order_id ) != 'lp_order' ) {
509
- die( __( 'Order invalid', 'learnpress' ) );
510
- }
511
-
512
- // validate item
513
- $item_id = learn_press_get_request( 'item_id' );
514
- $post = get_post( learn_press_get_order_item_meta( $item_id, '_course_id' ) );
515
- if ( !$post || ( 'lp_course' !== $post->post_type ) ) {
516
- die( __( 'Course invalid', 'learnpress' ) );
517
- }
518
-
519
- learn_press_remove_order_item( $item_id );
520
-
521
- $order_data = learn_press_update_order_items( $order_id );
522
- $currency_symbol = learn_press_get_currency_symbol( $order_data['currency'] );
523
- $order_data['subtotal_html'] = learn_press_format_price( $order_data['subtotal'], $currency_symbol );
524
- $order_data['total_html'] = learn_press_format_price( $order_data['total'], $currency_symbol );
525
-
526
-
527
- learn_press_send_json(
528
- array(
529
- 'result' => 'success',
530
- 'order_data' => $order_data
531
- )
532
- );
533
- }
534
-
535
- /**
536
- * Add new course to order
537
- */
538
- public static function add_item_to_order() {
539
-
540
- // ensure that user has permission
541
- if ( !current_user_can( 'edit_lp_orders' ) ) {
542
- die( __( 'Permission denied', 'learnpress' ) );
543
- }
544
-
545
- // verify nonce
546
- // $nonce = learn_press_get_request( 'nonce' );
547
- // if ( !wp_verify_nonce( $nonce, 'add_item_to_order' ) ) {
548
- // die( __( 'Check nonce failed', 'learnpress' ) );
549
- // }
550
-
551
- // validate order
552
- $order_id = learn_press_get_request( 'order_id' );
553
- if ( !is_numeric( $order_id ) || get_post_type( $order_id ) != 'lp_order' ) {
554
- die( __( 'Order invalid', 'learnpress' ) );
555
- }
556
-
557
- // validate item
558
- $item_ids = learn_press_get_request( 'item_id' );
559
- $item_html = '';
560
- $order_data = array();
561
- // $order = learn_press_get_order( $order_id );
562
-
563
- // echo '<pre>'.print_r($item_ids, true).'</pre>';
564
- // exit(''.__LINE__);
565
- foreach ( $item_ids as $item_id ):
566
- $post = get_post( $item_id );
567
- if ( !$post || ( 'lp_course' !== $post->post_type ) ) {
568
- continue;
569
- // die( __( 'Course invalid', 'learnpress' ) );
570
- }
571
- $course = learn_press_get_course( $post->ID );
572
- $item = array(
573
- 'course_id' => $course->id,
574
- 'name' => $course->get_title(),
575
- 'quantity' => 1,
576
- 'subtotal' => $course->get_price(),
577
- 'total' => $course->get_price()
578
- );
579
-
580
- // Add item
581
- $item_id = learn_press_add_order_item( $order_id, array(
582
- 'order_item_name' => $item['name']
583
- ) );
584
-
585
- $item['id'] = $item_id;
586
-
587
- // Add item meta
588
- if ( $item_id ) {
589
- $item = apply_filters( 'learn_press_ajax_order_item', $item );
590
-
591
- learn_press_add_order_item_meta( $item_id, '_course_id', $item['course_id'] );
592
- learn_press_add_order_item_meta( $item_id, '_quantity', $item['quantity'] );
593
- learn_press_add_order_item_meta( $item_id, '_subtotal', $item['subtotal'] );
594
- learn_press_add_order_item_meta( $item_id, '_total', $item['total'] );
595
-
596
- do_action( 'learn_press_ajax_add_order_item_meta', $item );
597
- }
598
-
599
- $order_data = learn_press_update_order_items( $order_id );
600
- $currency_symbol = learn_press_get_currency_symbol( $order_data['currency'] );
601
- $order_data['subtotal_html'] = learn_press_format_price( $order_data['subtotal'], $currency_symbol );
602
- $order_data['total_html'] = learn_press_format_price( $order_data['total'], $currency_symbol );
603
-
604
- ob_start();
605
- include learn_press_get_admin_view( 'meta-boxes/order/order-item.php' );
606
- $item_html .= ob_get_clean();
607
- endforeach;
608
-
609
-
610
- learn_press_send_json(
611
- array(
612
- 'result' => 'success',
613
- 'item_html' => $item_html,
614
- 'order_data' => $order_data
615
- )
616
- );
617
- }
618
-
619
- public static function search_courses() {
620
- $nonce = learn_press_get_request( 'nonce' );
621
- if ( !wp_verify_nonce( $nonce, 'search_item_term' ) ) {
622
- LP_Debug::exception( __( 'Verify nonce failed', 'learnpress' ) );
623
- }
624
-
625
- $term = learn_press_get_request( 'term' );
626
- $exclude = learn_press_get_request( 'exclude' );
627
-
628
- $posts = learn_press_get_all_courses(
629
- array(
630
- 'term' => $term,
631
- 'exclude' => $exclude
632
- )
633
- );
634
- $found_courses = array();
635
- if ( !empty( $posts ) ) {
636
- foreach ( $posts as $post ) {
637
- $found_courses[$post] = array(
638
- 'title' => get_the_title( $post ),
639
- 'permalink' => get_the_permalink( $post )
640
- );
641
- }
642
- }
643
-
644
- $found_courses = apply_filters( 'learn_press_json_search_found_courses', $found_courses );
645
-
646
- learn_press_send_json( $found_courses );
647
- }
648
-
649
- public static function remove_course_section() {
650
- $id = learn_press_get_request( 'id' );
651
- if ( $id ) {
652
- global $wpdb;
653
- $query = $wpdb->prepare( "
654
- DELETE FROM {$wpdb->prefix}learnpress_section_items
655
- WHERE section_id = %d
656
- ", $id );
657
- $wpdb->query( $query );
658
- learn_press_reset_auto_increment( 'learnpress_section_items' );
659
- $query = $wpdb->prepare( "
660
- DELETE FROM {$wpdb->prefix}learnpress_sections
661
- WHERE section_id = %d
662
- ", $id );
663
- $wpdb->query( $query );
664
- learn_press_reset_auto_increment( 'learnpress_sections' );
665
- }
666
- die();
667
- }
668
-
669
- public static function toggle_lesson_preview() {
670
- $id = learn_press_get_request( 'lesson_id' );
671
- if ( get_post_type( $id ) == 'lp_lesson' && wp_verify_nonce( learn_press_get_request( 'nonce' ), 'learn-press-toggle-lesson-preview' ) ) {
672
- $previewable = learn_press_get_request( 'previewable' );
673
- if ( is_null( $previewable ) ) {
674
- $previewable = '0';
675
- }
676
- update_post_meta( $id, '_lp_preview', $previewable );
677
- }
678
- die();
679
- }
680
-
681
- public static function add_new_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
- LP_Lesson_Post_Type::create_default_meta( $item_id );
691
- $item = get_post( $item_id );
692
- $response['post'] = $item;
693
- $response['post']->edit_link = get_edit_post_link( $item_id );
694
- }
695
- }
696
- learn_press_send_json( $response );
697
- }
698
-
699
- public static function quick_add_item() {
700
- $post_type = learn_press_get_request( 'type' );
701
- $post_title = learn_press_get_request( 'name' );
702
- $response = array();
703
- if ( $post_type && $post_title ) {
704
- $args = compact( 'post_title', 'post_type' );
705
- $args['post_status'] = 'publish';
706
- $item_id = wp_insert_post( $args );
707
- if ( $item_id ) {
708
- $item = get_post( $item_id );
709
- $response['post'] = $item;
710
- $response['html'] = sprintf( '<li class="" data-id="%1$d" data-type="%2$s" data-text="%3$s">
711
- <label>
712
- <input type="checkbox" value="%1$d">
713
- <span class="lp-item-text">%3$s</span>
714
- </label>
715
- </li>', $item->ID, $item->post_type, $item->post_title );
716
- }
717
- }
718
- learn_press_send_json( $response );
719
- }
720
-
721
- public static function update_editor_hidden() {
722
- if ( $id = learn_press_get_request( 'course_id' ) ) {
723
- if ( learn_press_get_request( 'is_hidden' ) ) {
724
- update_post_meta( $id, '_lp_editor_hidden', 'yes' );
725
- } else {
726
- delete_post_meta( $id, '_lp_editor_hidden' );
727
- }
728
- }
729
- learn_press_send_json( $_POST );
730
- }
731
-
732
- public static function update_quiz_question_state() {
733
- $hidden = learn_press_get_request( 'hidden' );
734
- $post = learn_press_get_request( 'quiz_id' );
735
- update_post_meta( $post, '_admin_hidden_questions', $hidden );
736
- die();
737
- }
738
-
739
- public static function update_curriculum_section_state() {
740
- $hidden = learn_press_get_request( 'hidden' );
741
- $post = learn_press_get_request( 'course_id' );
742
- update_post_meta( $post, '_admin_hidden_sections', $hidden );
743
- die();
744
- }
745
-
746
- /**
747
- * Create a new page with the title passed via $_REQUEST
748
- */
749
- public static function create_page() {
750
- $page_name = !empty( $_REQUEST['page_name'] ) ? $_REQUEST['page_name'] : '';
751
- $response = array();
752
- if ( $page_name ) {
753
- $args = array(
754
- 'post_type' => 'page',
755
- 'post_title' => $page_name,
756
- 'post_status' => 'publish'
757
- );
758
- $page_id = wp_insert_post( $args );
759
-
760
- if ( $page_id ) {
761
- $response['page'] = get_page( $page_id );
762
- $html = learn_press_pages_dropdown( '', '', array( 'echo' => false ) );
763
- preg_match_all( '!value=\"([0-9]+)\"!', $html, $matches );
764
- $response['positions'] = $matches[1];
765
- $response['html'] = '<a href="' . get_edit_post_link( $page_id ) . '" target="_blank">' . __( 'Edit Page', 'learnpress' ) . '</a>&nbsp;';
766
- $response['html'] .= '<a href="' . get_permalink( $page_id ) . '" target="_blank">' . __( 'View Page', 'learnpress' ) . '</a>';
767
- } else {
768
- $response['error'] = __( 'Error! Create page failed. Please try again!', 'learnpress' );
769
- }
770
- } else {
771
- $response['error'] = __( 'Empty page name!', 'learnpress' );
772
- }
773
- learn_press_send_json( $response );
774
- die();
775
- }
776
-
777
- public static function add_quiz_question() {
778
- global $post;
779
- $id = learn_press_get_request( 'id' );
780
- $quiz_id = learn_press_get_request( 'quiz_id' );
781
- $type = learn_press_get_request( 'type' );
782
- $name = learn_press_get_request( 'name' );
783
- $user_id = get_current_user_id();
784
- $response = array(
785
- 'id' => $id
786
- );
787
- $post = get_post( $quiz_id );
788
- setup_postdata( $post );
789
- if ( !$id ) {
790
- $args_item = array(
791
- 'post_title' => $name,
792
- 'post_type' => LP_QUESTION_CPT,
793
- 'post_status' => 'publish'
794
- );
795
- $args_item = apply_filters( 'learnpress_quiz_insert_item_args', $args_item, $quiz_id );
796
- $id = wp_insert_post( $args_item );
797
- if ( $id ) {
798
- add_post_meta( $id, '_lp_type', $type );
799
- }
800
- $response['id'] = $id;
801
- }
802
- if ( $id && $quiz_id ) {
803
- global $wpdb;
804
- $max_order = $wpdb->get_var( $wpdb->prepare( "SELECT max(question_order) FROM {$wpdb->prefix}learnpress_quiz_questions WHERE quiz_id = %d", $quiz_id ) );
805
- $wpdb->insert(
806
- $wpdb->prefix . 'learnpress_quiz_questions',
807
- array(
808
- 'quiz_id' => $quiz_id,
809
- 'question_id' => $id,
810
- 'question_order' => $max_order + 1
811
- ),
812
- array( '%d', '%d', '%d' )
813
- );
814
- ob_start();
815
- $question = LP_Question_Factory::get_question( $id );
816
- learn_press_admin_view( 'meta-boxes/quiz/question.php', array( 'question' => $question ) );
817
- $response['html'] = ob_get_clean();
818
-
819
- // trigger change user memorize question types
820
- $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
821
- $question_types = !$question_types ? array() : $question_types;
822
- $type = get_post_meta( $id, '_lp_type', true );
823
- $question_types[$type] = !empty ( $question_types[$type] ) ? absint( $question_types[$type] ) + 1 : 1;
824
- update_user_meta( $user_id, '_learn_press_memorize_question_types', $question_types );
825
- // end trigger change user memorize question types
826
- }
827
- learn_press_send_json( $response );
828
- die();
829
- }
830
-
831
- public static function convert_question_type() {
832
- if ( ( $from = learn_press_get_request( 'from' ) ) && ( $to = learn_press_get_request( 'to' ) ) && $question_id = learn_press_get_request( 'question_id' ) ) {
833
- $data = array();
834
- parse_str( $_POST['data'], $data );
835
-
836
- do_action( 'learn_press_convert_question_type', $question_id, $from, $to, $data );
837
- $question = LP_Question_Factory::get_question( $question_id, array( 'type' => $to ) );
838
-
839
- // trigger change user memorize question types
840
- $user_id = get_current_user_id();
841
- $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
842
- $question_types[$from] = !empty( $question_types[$from] ) && $question_types[$from] ? absint( $question_types[$from] ) - 1 : 0;
843
- $question_types[$to] = !empty( $question_types[$to] ) && $question_types[$to] ? absint( $question_types[$to] ) + 1 : 1;
844
- update_user_meta( $user_id, '_learn_press_memorize_question_types', $question_types );
845
- // end trigger change user memorize question types
846
- if ( 'auto-draft' === $question->post->post_status ) {
847
- $question->answers = $question->get_default_answers( false );
848
- }
849
- learn_press_send_json(
850
- array(
851
- 'html' => $question->admin_interface( array( 'echo' => false ) ),
852
- 'icon' => $question->get_icon()
853
- )
854
- );
855
- } else {
856
- //throw new Exception( __( 'Convert question type must be specify the id, source and destination type', 'learnpress' ) );
857
- throw new Exception( __( 'Something went wrong! Please try again or ask <a href="https://wordpress.org/support/">support forums</a>.', 'learnpress' ) );
858
- }
859
- die();
860
- }
861
-
862
- /*******************************************************************************************************/
863
-
864
- /**
865
- * Install sample data or dismiss the notice depending on user's option
866
- */
867
- public static function install_sample_data() {
868
- $yes = !empty( $_REQUEST['yes'] ) ? $_REQUEST['yes'] : '';
869
- $response = array( 'result' => 'fail' );
870
- $retry_button = sprintf( '<a href="" class="button yes" data-action="yes">%s</a>', __( 'Try again!', 'learnpress' ) );
871
- $dismiss_button = sprintf( '<a href="" class="button disabled no" data-action="no">%s</a>', __( 'Cancel', 'learnpress' ) );
872
- $buttons = sprintf( '<p>%s %s</p>', $retry_button, $dismiss_button );
873
- if ( 'no' == $yes ) {
874
- set_transient( 'learn_press_install_sample_data', 'off', 12 * HOUR_IN_SECONDS );
875
- } else {
876
- $result = array( 'status' => 'activate' );//learn_press_install_and_active_add_on( 'learnpress-import-export' );
877
- if ( 'activate' == $result['status'] ) {
878
- // copy dummy-data.xml to import folder of the add-on
879
- lpie_mkdir( lpie_import_path() );
880
- if ( file_exists( lpie_import_path() ) ) {
881
- $import_source = LP_PLUGIN_PATH . '/dummy-data/dummy-data.xml';
882
- $file = 'dummy-data-' . time() . '.xml';
883
- $copy = lpie_import_path() . '/' . $file;
884
- copy( $import_source, $copy );
885
- if ( file_exists( $copy ) ) {
886
- $url = admin_url( 'admin-ajax.php?page=learn_press_import_export&tab=import-course' );
887
- $postdata = array(
888
- 'step' => 2,
889
- 'action' => 'learn_press_import',
890
- 'import-file' => 'import/' . $file,
891
- 'nonce' => wp_create_nonce( 'lpie-import-file' ),
892
- 'x' => 1
893
- );
894
- $response['url'] = $url = $url . '&' . http_build_query( $postdata ) . "\n";
895
- $response['result'] = 'success';
896
- $response['message'] = sprintf( '<p>%s <a href="edit.php?post_type=lp_course">%s</a> </p>', __( 'Import sample data successes.', 'learnpress' ), __( 'View courses', 'learnpress' ) );
897
- }
898
- }
899
- if ( $response['result'] == 'fail' ) {
900
- $response['message'] = sprintf( '<p>%s</p>%s', __( 'Import sample data failed. Please try again!.', 'learnpress' ), $buttons );
901
- }
902
- } else {
903
- $response['result'] = 'fail';
904
- $response['message'] = sprintf( '<p>%s</p>', __( 'Unknown error when installing/activating Import/Export addon. Please try again!', 'learnpress' ) ) . $buttons;
905
- }
906
- }
907
- learn_press_send_json( $response );
908
- die();
909
- }
910
-
911
- /**
912
- * Activate a bundle of add-ons, if an add-on is not installed then install it first
913
- */
914
- public static function bundle_activate_add_ons() {
915
- global $learn_press_add_ons;
916
- include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); //for plugins_api..
917
- $response = array( 'addons' => array() );
918
-
919
- if ( !current_user_can( 'activate_plugins' ) ) {
920
- $response['error'] = __( 'You do not have sufficient permissions to deactivate plugins for this site.', 'learnpress' );
921
- } else {
922
-
923
- $add_ons = $learn_press_add_ons['bundle_activate'];
924
-
925
- if ( $add_ons ) {
926
- foreach ( $add_ons as $slug ) {
927
- $response['addons'][$slug] = learn_press_install_and_active_add_on( $slug );
928
- }
929
- }
930
- }
931
- learn_press_send_json( $response );
932
- }
933
-
934
- /**
935
- * Activate a bundle of add-ons, if an add-on is not installed then install it first
936
- */
937
- public static function bundle_activate_add_on() {
938
- $response = array();
939
- include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); //for plugins_api..
940
- if ( !current_user_can( 'activate_plugins' ) ) {
941
- $response['error'] = __( 'You do not have sufficient permissions to deactivate plugins for this site.', 'learnpress' );
942
- } else {
943
- $slug = !empty( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : null;
944
- $response[$slug] = learn_press_install_and_active_add_on( $slug );
945
- }
946
- learn_press_send_json( $response );
947
- }
948
-
949
- public static function plugin_install() {
950
- $plugin_name = !empty( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
951
- $response = learn_press_install_add_on( $plugin_name );
952
- learn_press_send_json( $response );
953
- die();
954
- }
955
-
956
- public static function update_add_on_status() {
957
- $plugin = !empty( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
958
- $t = !empty( $_REQUEST['t'] ) ? $_REQUEST['t'] : '';
959
- $response = array();
960
- if ( !current_user_can( 'activate_plugins' ) ) {
961
- $response['error'] = __( 'You do not have sufficient permissions to deactivate plugins for this site.', 'learnpress' );
962
- }
963
- if ( $plugin && $t ) {
964
- if ( $t == 'activate' ) {
965
- activate_plugin( $plugin, false, is_network_admin() );
966
- } else {
967
- deactivate_plugins( $plugin, false, is_network_admin() );
968
- }
969
- $is_activate = is_plugin_active( $plugin );
970
- $response['status'] = $is_activate ? 'activate' : 'deactivate';
971
-
972
- }
973
- wp_send_json( $response );
974
- die();
975
- }
976
-
977
- /**
978
- * Output the image to browser with text and params passed via $_GET
979
- */
980
- public static function dummy_image() {
981
- $text = !empty( $_REQUEST['text'] ) ? $_REQUEST['text'] : '';
982
- learn_press_text_image( $text, $_GET );
983
- die();
984
- }
985
-
986
- /**
987
- * Get edit|view link of a page
988
- */
989
- public static function get_page_permalink() {
990
- $page_id = !empty( $_REQUEST['page_id'] ) ? $_REQUEST['page_id'] : '';
991
- ?>
992
- <a href="<?php echo get_edit_post_link( $page_id ); ?>" target="_blank"><?php _e( 'Edit Page', 'learnpress' ); ?></a>
993
- <a href="<?php echo get_permalink( $page_id ); ?>" target="_blank"><?php _e( 'View Page', 'learnpress' ); ?></a>
994
- <?php
995
- die();
996
- }
997
-
998
-
999
- /**
1000
- *
1001
- */
1002
- public function custom_stats() {
1003
- $from = !empty( $_REQUEST['from'] ) ? $_REQUEST['from'] : 0;
1004
- $to = !empty( $_REQUEST['to'] ) ? $_REQUEST['to'] : 0;
1005
- $date_diff = strtotime( $to ) - strtotime( $from );
1006
- if ( $date_diff <= 0 || $from == 0 || $to == 0 ) {
1007
- die();
1008
- }
1009
- learn_press_process_chart( learn_press_get_chart_students( $to, 'days', floor( $date_diff / ( 60 * 60 * 24 ) ) + 1 ) );
1010
- die();
1011
- }
1012
-
1013
- /**
1014
- * Quick add lesson with only title
1015
- */
1016
- public static function quick_add_lesson() {
1017
-
1018
- $lesson_title = $_POST['lesson_title'];
1019
-
1020
- $new_lesson = array(
1021
- 'post_title' => wp_strip_all_tags( $lesson_title ),
1022
- 'post_type' => LP_LESSON_CPT,
1023
- 'post_status' => 'publish'
1024
- );
1025
-
1026
- wp_insert_post( $new_lesson );
1027
-
1028
- $args = array(
1029
- 'numberposts' => 1,
1030
- 'post_type' => LP_LESSON_CPT,
1031
- 'post_status' => 'publish'
1032
- );
1033
- $lesson = wp_get_recent_posts( $args );
1034
- $lesson_id = $lesson[0]['ID'];
1035
- $data = array(
1036
- 'id' => $lesson_id,
1037
- 'title' => $lesson_title
1038
- );
1039
- wp_send_json( $data );
1040
- die;
1041
- }
1042
-
1043
- /**
1044
- * Add a new quiz with the title only
1045
- */
1046
- public static function quick_add_quiz() {
1047
- $quiz_title = $_POST['quiz_title'];
1048
-
1049
- $new_quiz = array(
1050
- 'post_title' => wp_strip_all_tags( $quiz_title ),
1051
- 'post_type' => LP_QUIZ_CPT,
1052
- 'post_status' => 'publish'
1053
- );
1054
-
1055
- wp_insert_post( $new_quiz );
1056
-
1057
- $args = array(
1058
- 'numberposts' => 1,
1059
- 'post_type' => LP_QUIZ_CPT,
1060
- 'post_status' => 'publish'
1061
- );
1062
- $quiz = wp_get_recent_posts( $args );
1063
- $quiz_id = $quiz[0]['ID'];
1064
- $data = array(
1065
- 'id' => $quiz_id,
1066
- 'title' => $quiz_title
1067
- );
1068
- wp_send_json( $data );
1069
- die;
1070
- }
1071
-
1072
- public static function be_teacher() {
1073
- $user_id = get_current_user_id();
1074
- $be_teacher = new WP_User( $user_id );
1075
- $be_teacher->set_role( LP_TEACHER_ROLE );
1076
- die;
1077
- }
1078
-
1079
- public static function ignore_setting_up() {
1080
- update_option( '_lpr_ignore_setting_up', 1, true );
1081
- die;
1082
- }
1083
-
1084
- public static function duplicate_course() {
1085
- if ( empty( $_POST['course_id'] ) || empty( $_POST['_nonce'] ) || !wp_verify_nonce( $_POST['_nonce'], 'lp-duplicate-course' ) ) {
1086
- return;
1087
- }
1088
- global $wpdb;
1089
- $course_id = absint( $_POST['course_id'] );
1090
- $force = !empty( $_POST['content'] ) && $_POST['content'] ? true : false;
1091
-
1092
- $results = array(
1093
- 'redirect' => admin_url( 'edit.php?post_type=' . LP_COURSE_CPT )
1094
- );
1095
- $new_course_id = learn_press_duplicate_course( $course_id, $force );
1096
- if ( is_wp_error( $course_id ) ) {
1097
- LP_Admin_Notice::add_redirect( $course_id->get_error_message(), 'error' );
1098
- } else {
1099
- LP_Admin_Notice::add_redirect( sprintf( '<strong>%s</strong> %s', get_the_title( $course_id ), __( ' course has duplicated', 'learnpress' ) ), 'updated' );
1100
- $results['redirect'] = admin_url( 'post.php?post=' . $new_course_id . '&action=edit' );
1101
- }
1102
-
1103
- wp_send_json( $results );
1104
- die();
1105
- }
1106
-
1107
- public static function duplicate_question() {
1108
- if ( empty( $_POST['_nonce'] ) || !wp_verify_nonce( $_POST['_nonce'], 'duplicate-question' ) ) {
1109
- return;
1110
- }
1111
- global $wpdb;
1112
- $question_id = learn_press_get_request( 'question-id' );
1113
- $quiz_id = learn_press_get_request( 'quiz-id' );
1114
- $user_id = learn_press_get_current_user_id();
1115
-
1116
- $new_question_id = learn_press_duplicate_question( $question_id, $quiz_id );
1117
- if ( !is_wp_error( $new_question_id ) ) {
1118
- ob_start();
1119
- $question = LP_Question_Factory::get_question( $new_question_id );
1120
- $post = get_post( $quiz_id );
1121
- setup_postdata( $post );
1122
- _learn_press_setup_question( $new_question_id );
1123
- learn_press_admin_view( 'meta-boxes/quiz/question.php', array( 'question' => $question ) );
1124
- $response['html'] = ob_get_clean();
1125
-
1126
- // trigger change user memorize question types
1127
- $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
1128
- $question_types = !$question_types ? array() : $question_types;
1129
- $type = get_post_meta( $new_question_id, '_lp_type', true );
1130
- $question_types[$type] = !empty ( $question_types[$type] ) ? absint( $question_types[$type] ) + 1 : 1;
1131
- update_user_meta( $user_id, '_learn_press_memorize_question_types', $question_types );
1132
- // end trigger change user memorize question types
1133
- learn_press_send_json( $response );
1134
-
1135
-
1136
- die();
1137
- }
1138
- }
1139
-
1140
- public static function remove_notice_popup() {
1141
-
1142
- if ( isset( $_POST['action'] ) && $_POST['action'] === 'learnpress_remove_notice_popup'
1143
- && isset( $_POST['slug'] ) && !empty( $_POST['slug'] )
1144
- && isset( $_POST['user'] ) && !empty( $_POST['user'] )
1145
- ) {
1146
-
1147
- $slug = 'learnpress_notice_' . $_POST['slug'] . '_' . $_POST['user'];
1148
-
1149
- set_transient( $slug, true, 30 * DAY_IN_SECONDS );
1150
- }
1151
-
1152
- wp_die();
1153
-
1154
- }
1155
-
1156
- }
1157
- }
1158
- LP_Admin_Ajax::init();
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-menu.php CHANGED
@@ -1,153 +1,131 @@
1
- <?php
2
- /**
3
- * Setup menus in WP admin.
4
- *
5
- * @author ThimPress
6
- * @package LearnPress
7
- * @version 1.0
8
- */
9
-
10
- if ( !defined( 'ABSPATH' ) ) {
11
- exit; // Exit if accessed directly
12
- }
13
-
14
- /**
15
- * Class LP_Admin_Menu
16
- */
17
- class LP_Admin_Menu {
18
- protected $_submenu = null;
19
-
20
- /**
21
- * LP_Admin_Menu Construct
22
- */
23
- public function __construct() {
24
- // admin menu
25
- add_action( 'admin_menu', array( $this, 'admin_menu' ) );
26
- add_action( 'admin_menu', array( $this, 'notify_new_course' ) );
27
- add_action( 'init', array( $this, 'menu_content' ) );
28
- add_action( 'init', 'learn_press_admin_update_settings', 1000 );
29
- if ( apply_filters( 'learn_press_show_admin_bar_courses_page', true ) ) {
30
- add_action( 'admin_bar_menu', array( $this, 'admin_bar_menus' ), 50 );
31
- }
32
-
33
- // auto include file for admin page
34
- // example: slug = learn_press_settings -> file = inc/admin/sub-menus/settings.php
35
- $page = !empty ( $_REQUEST['page'] ) ? $_REQUEST['page'] : null;
36
- if ( $page ) {
37
- if ( strpos( $page, 'learn-press-' ) !== false ) {
38
- $file = preg_replace( '!^learn-press-!', '', $page );
39
- $file = str_replace( '_', '-', $file );
40
- if ( file_exists( $file = LP_PLUGIN_PATH . "/inc/admin/sub-menus/{$file}.php" ) ) {
41
- $this->_submenu = require_once $file;
42
- }
43
- }
44
- }
45
- }
46
-
47
- public function admin_bar_menus( $wp_admin_bar ) {
48
- if ( !is_admin() || !is_user_logged_in() ) {
49
- return;
50
- }
51
-
52
- if ( !is_user_member_of_blog() && !is_super_admin() ) {
53
- return;
54
- }
55
-
56
- if ( get_option( 'page_on_front' ) == learn_press_get_page_id( 'courses' ) ) {
57
- return;
58
- }
59
-
60
- $wp_admin_bar->add_node( array(
61
- 'parent' => 'site-name',
62
- 'id' => 'courses-page',
63
- 'title' => __( 'View Courses', 'learnpress' ),
64
- 'href' => learn_press_get_page_link( 'courses' )
65
- ) );
66
- }
67
-
68
- /**
69
- * Register for menu for admin
70
- */
71
- public function admin_menu() {
72
- $capacity = 'edit_' . LP_COURSE_CPT . 's';
73
- add_menu_page(
74
- __( 'Learning Management System', 'learnpress' ),
75
- __( 'LearnPress', 'learnpress' ),
76
- $capacity,
77
- 'learn_press',
78
- '',
79
- 'dashicons-welcome-learn-more',
80
- '3.14'
81
- );
82
-
83
- $menu_items = array(
84
- 'statistics' => array(
85
- 'learn_press',
86
- __( 'Statistics', 'learnpress' ),
87
- __( 'Statistics', 'learnpress' ),
88
- $capacity,
89
- 'learn-press-statistics',
90
- array( $this, 'menu_page' )
91
- ),
92
- 'addons' => array(
93
- 'learn_press',
94
- __( 'Add-ons', 'learnpress' ),
95
- __( 'Add-ons', 'learnpress' ),
96
- 'manage_options',
97
- 'learn-press-addons',
98
- 'learn_press_addons_page'
99
- ),
100
- 'settings' => array(
101
- 'learn_press',
102
- __( 'Settings', 'learnpress' ),
103
- __( 'Settings', 'learnpress' ),
104
- 'manage_options',
105
- 'learn-press-settings',
106
- 'learn_press_settings_page'
107
- ),
108
- 'tools' => array(
109
- 'learn_press',
110
- __( 'Tools', 'learnpress' ),
111
- __( 'Tools', 'learnpress' ),
112
- 'manage_options',
113
- 'learn-press-tools',
114
- 'learn_press_tools_page'
115
- )
116
- );
117
-
118
- // Third-party can be add more items
119
- $menu_items = apply_filters( 'learn_press_menu_items', $menu_items );
120
-
121
- if ( $menu_items ) foreach ( $menu_items as $item ) {
122
- call_user_func_array( 'add_submenu_page', $item );
123
- }
124
- }
125
-
126
- /*
127
- * Notify an administrator with pending courses
128
- */
129
- public function notify_new_course() {
130
- global $menu;
131
- $current_user = wp_get_current_user();
132
- if ( !in_array( 'administrator', $current_user->roles ) ) {
133
- return;
134
- }
135
- $count_courses = wp_count_posts( LP_COURSE_CPT );
136
- $awaiting_mod = $count_courses->pending;
137
- $menu['3.14'][0] .= " <span class='awaiting-mod count-$awaiting_mod'><span class='pending-count'>" . number_format_i18n( $awaiting_mod ) . "</span></span>";
138
- }
139
-
140
- public function menu_page() {
141
- if ( $this->_submenu ) {
142
- $this->_submenu->display();
143
- }
144
- }
145
-
146
- public function menu_content() {
147
- if ( !function_exists( 'learn_press_admin_update_settings' ) ) {
148
- remove_action( 'init', 'learn_press_admin_update_settings', 1000 );
149
- }
150
- }
151
- }
152
-
153
  return new LP_Admin_Menu();
1
+ <?php
2
+ /**
3
+ * Setup menus in WP admin.
4
+ *
5
+ * @author ThimPress
6
+ * @package LearnPress
7
+ * @version 1.0
8
+ */
9
+
10
+ if ( !defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly
12
+ }
13
+
14
+ /**
15
+ * Class LP_Admin_Menu
16
+ */
17
+ class LP_Admin_Menu {
18
+ protected $_submenu = null;
19
+
20
+ /**
21
+ * LP_Admin_Menu Construct
22
+ */
23
+ public function __construct() {
24
+ // admin menu
25
+ add_action( 'admin_menu', array( $this, 'admin_menu' ) );
26
+ add_action( 'admin_menu', array( $this, 'notify_new_course' ) );
27
+ add_action( 'init', array( $this, 'menu_content' ) );
28
+ add_action( 'init', 'learn_press_admin_update_settings', 1000 );
29
+
30
+ // auto include file for admin page
31
+ // example: slug = learn_press_settings -> file = inc/admin/sub-menus/settings.php
32
+ $page = !empty ( $_REQUEST['page'] ) ? $_REQUEST['page'] : null;
33
+ if ( $page ) {
34
+ if ( strpos( $page, 'learn-press-' ) !== false ) {
35
+ $file = preg_replace( '!^learn-press-!', '', $page );
36
+ $file = str_replace( '_', '-', $file );
37
+ if ( file_exists( $file = LP_PLUGIN_PATH . "/inc/admin/sub-menus/{$file}.php" ) ) {
38
+ $this->_submenu = require_once $file;
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Register for menu for admin
46
+ */
47
+ public function admin_menu() {
48
+ $capacity = 'edit_' . LP_COURSE_CPT . 's';
49
+ add_menu_page(
50
+ __( 'Learning Management System', 'learnpress' ),
51
+ __( 'LearnPress', 'learnpress' ),
52
+ $capacity,
53
+ 'learn_press',
54
+ '',
55
+ 'dashicons-welcome-learn-more',
56
+ '3.14'
57
+ );
58
+
59
+ $menu_items = array(
60
+ 'statistics' => array(
61
+ 'learn_press',
62
+ __( 'Statistics', 'learnpress' ),
63
+ __( 'Statistics', 'learnpress' ),
64
+ $capacity,
65
+ 'learn-press-statistics',
66
+ array( $this, 'menu_page' )
67
+ ),
68
+ 'addons' => array(
69
+ 'learn_press',
70
+ __( 'Add-ons', 'learnpress' ),
71
+ __( 'Add-ons', 'learnpress' ),
72
+ 'manage_options',
73
+ 'learn-press-addons',
74
+ 'learn_press_addons_page'
75
+ ),
76
+ 'settings' => array(
77
+ 'learn_press',
78
+ __( 'Settings', 'learnpress' ),
79
+ __( 'Settings', 'learnpress' ),
80
+ 'manage_options',
81
+ 'learn-press-settings',
82
+ 'learn_press_settings_page'
83
+ ),
84
+ 'tools' => array(
85
+ 'learn_press',
86
+ __( 'Tools', 'learnpress' ),
87
+ __( 'Tools', 'learnpress' ),
88
+ 'manage_options',
89
+ 'learn-press-tools',
90
+ 'learn_press_tools_page'
91
+ )
92
+ );
93
+
94
+ // Third-party can be add more items
95
+ $menu_items = apply_filters( 'learn_press_menu_items', $menu_items );
96
+
97
+ if ( $menu_items ) foreach ( $menu_items as $item ) {
98
+ call_user_func_array( 'add_submenu_page', $item );
99
+ }
100
+
101
+ //add_submenu_page( 'tools.php', __( 'Database tools', 'learnpress' ), __( 'LearnPress', 'learnpress' ), 'manage_options', 'learn_press_tools', 'learn_press_tools_page' );
102
+ }
103
+
104
+ /*
105
+ * Notify an administrator with pending courses
106
+ */
107
+ public function notify_new_course() {
108
+ global $menu;
109
+ $current_user = wp_get_current_user();
110
+ if ( !in_array( 'administrator', $current_user->roles ) ) {
111
+ return;
112
+ }
113
+ $count_courses = wp_count_posts( LP_COURSE_CPT );
114
+ $awaiting_mod = $count_courses->pending;
115
+ $menu['3.14'][0] .= " <span class='awaiting-mod count-$awaiting_mod'><span class='pending-count'>" . number_format_i18n( $awaiting_mod ) . "</span></span>";
116
+ }
117
+
118
+ public function menu_page() {
119
+ if ( $this->_submenu ) {
120
+ $this->_submenu->display();
121
+ }
122
+ }
123
+
124
+ public function menu_content() {
125
+ if ( !function_exists( 'learn_press_admin_update_settings' ) ) {
126
+ remove_action( 'init', 'learn_press_admin_update_settings', 1000 );
127
+ }
128
+ }
129
+ }
130
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  return new LP_Admin_Menu();
inc/admin/class-lp-admin.php CHANGED
@@ -1,233 +1,232 @@
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_detect_outdated_template() ) {
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
- //crazy tu
218
- // Common function used in admin
219
- include_once( 'lp-admin-functions.php' );
220
- // Admin actions
221
- include_once( 'lp-admin-actions.php' );
222
- //Ajax Class
223
- include_once( 'class-lp-admin-ajax.php' );
224
- // Admin menu
225
- include_once( 'class-lp-admin-menu.php' );
226
-
227
- include_once( 'class-lp-meta-box-tabs.php' );
228
-
229
- }
230
- }
231
-
232
- new LP_Admin();
233
  }
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_detect_outdated_template() ) {
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
+ include_once( 'class-lp-meta-box-tabs.php' );
227
+
228
+ }
229
+ }
230
+
231
+ new LP_Admin();
 
232
  }
inc/admin/class-lp-meta-box-tabs.php CHANGED
@@ -49,8 +49,7 @@ if ( !class_exists( 'LP_Meta_Box_Tabs' ) ) {
49
  */
50
  public function add_tab_arg( $url ) {
51
  if ( array_key_exists( 'learn-press-meta-box-tab', $_REQUEST ) && !empty( $_REQUEST['learn-press-meta-box-tab'] ) ) {
52
- $url = remove_query_arg('tab', $url );
53
- $url = add_query_arg( 'tab', $_REQUEST['learn-press-meta-box-tab'], $url );
54
  }
55
  return $url;
56
  }
49
  */
50
  public function add_tab_arg( $url ) {
51
  if ( array_key_exists( 'learn-press-meta-box-tab', $_REQUEST ) && !empty( $_REQUEST['learn-press-meta-box-tab'] ) ) {
52
+ $m = add_query_arg( 'tab', $_REQUEST['learn-press-meta-box-tab'], $url );
 
53
  }
54
  return $url;
55
  }
inc/admin/class-lp-profile.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit; // Exit if accessed directly
4
+ }
5
+
6
+ if ( ! class_exists( 'LP_Profile' ) ) {
7
+ /**
8
+ * Class LP_Profile
9
+ */
10
+ class LP_Profile {
11
+ /**
12
+ * Constructor
13
+ */
14
+ public function __construct() {
15
+ add_filter( 'learn_press_profile_methods', array( $this, 'learn_press_profile_method' ) );
16
+ // add_action( 'wp_loaded', array( $this, 'learn_press_process_profile' ) );
17
+ add_action( 'learn_press_before_profile_content', array( $this, 'learn_press_add_tabs_scripts' ) );
18
+ add_action( 'learn_press_add_profile_tab', array( $this, 'learn_press_add_profile_tab' ) );
19
+ add_filter( 'learn_press_user_info_tab_content', array( $this, 'learn_press_user_info_tab_content' ), 10, 2 );
20
+ add_filter( 'learn_press_user_courses_tab_content', array( $this, 'learn_press_user_courses_tab_content' ), 10, 2 );
21
+ add_filter( 'learn_press_user_quizzes_tab_content', array( $this, 'learn_press_user_quizzes_tab_content' ), 10, 2 );
22
+ add_action( 'learn_press_enrolled_course_after_title', array( $this, 'end_title_content' ), 10, 2 );
23
+ }
24
+
25
+ /**
26
+ * Process profile
27
+ */
28
+ public function learn_press_process_profile() {
29
+ if ( learn_press_has_profile_method() ) {
30
+ if ( learn_press_get_profile_page_id() == 0 ) {
31
+ $profile = array(
32
+ 'post_title' => 'Profile',
33
+ 'post_content' => '[learn_press_profile]',
34
+ 'post_type' => 'page',
35
+ 'post_status' => 'publish',
36
+ );
37
+ $profile_page_id = wp_insert_post( $profile );
38
+ update_post_meta( $profile_page_id, '_lpr_is_profile_page', 1 );
39
+ }
40
+ } else {
41
+ wp_delete_post( learn_press_get_profile_page_id(), true );
42
+ }
43
+ }
44
+
45
+ /*
46
+ * Profile methods
47
+ */
48
+ public function learn_press_profile_method( $methods ) {
49
+ $methods['lpr_profile'] = __( 'LearnPress Profile', 'learnpress' );
50
+
51
+ return $methods;
52
+ }
53
+
54
+ /*
55
+ * Enqueue jquery ui scripts
56
+ */
57
+ public function learn_press_add_tabs_scripts() {
58
+ /*wp_enqueue_style( 'lpr-jquery-ui-css', LP_CSS_URL . 'jquery-ui.css' );
59
+ wp_enqueue_script( 'lpr-jquery-ui-js', LP_JS_URL . 'jquery-ui.js', array( 'jquery' ), '', false );*/
60
+ }
61
+
62
+ /*
63
+ * Add profile tab
64
+ */
65
+ public function learn_press_add_profile_tab( $user ) {
66
+ $content = '';
67
+ $tabs = apply_filters(
68
+ 'learn_press_profile_tabs',
69
+ array(
70
+ 10 => array(
71
+ 'tab_id' => 'user_info',
72
+ 'tab_name' => __( 'User Information', 'learnpress' ),
73
+ 'tab_content' => apply_filters( 'learn_press_user_info_tab_content', $content, $user )
74
+ ),
75
+ 20 => array(
76
+ 'tab_id' => 'user_courses',
77
+ 'tab_name' => __( 'Courses', 'learnpress' ),
78
+ 'tab_content' => apply_filters( 'learn_press_user_courses_tab_content', $content, $user )
79
+ )/*,
80
+ 30 => array(
81
+ 'tab_id' => 'user_quizzes',
82
+ 'tab_name' => __( 'Quiz Results', 'learnpress' ),
83
+ 'tab_content' => apply_filters( 'learn_press_user_quizzes_tab_content', $content, $user )
84
+ )*/
85
+ ),
86
+ $user
87
+ );
88
+ ksort( $tabs );
89
+ echo '<ul>';
90
+ foreach ( $tabs as $tab ) {
91
+ echo '<li><a href="#' . $tab['tab_id'] . '">' . $tab['tab_name'] . '</a></li>';
92
+ }
93
+ echo '</ul>';
94
+ foreach ( $tabs as $tab ) {
95
+ echo '<div id="' . $tab['tab_id'] . '">' . $tab['tab_content'] . '</div>';
96
+ }
97
+ }
98
+
99
+ /*
100
+ * Add content for user information tab
101
+ */
102
+ public function learn_press_user_info_tab_content( $content, $user ) {
103
+ ob_start();
104
+ learn_press_get_template( 'profile/user-info.php', array( 'user' => $user ) );
105
+ $content .= ob_get_clean();
106
+ return $content;
107
+ }
108
+
109
+ /*
110
+ * Add content for user courses tab
111
+ */
112
+ public function learn_press_user_courses_tab_content( $content, $user ) {
113
+ ob_start();
114
+ learn_press_get_template( 'profile/user-courses.php', array( 'user' => $user ) );
115
+ $content .= ob_get_clean();
116
+ return $content;
117
+ }
118
+
119
+
120
+ /*
121
+ * Add content for user quiz results tab
122
+ */
123
+ public function learn_press_user_quizzes_tab_content( $content, $user ) {
124
+ ob_start();
125
+ learn_press_get_template( 'profile/user-quizzes.php', array( 'content' => $content, 'user' => $user ) );
126
+ $content .= ob_get_clean();
127
+ return $content;
128
+ }
129
+
130
+ public function end_title_content( $course, $user ) {
131
+ if ( learn_press_user_has_passed_course( $course->ID, $user->ID ) ) {
132
+ _e( '<span class="course-status passed">Passed</span>', 'learnpress' );
133
+ } else {
134
+
135
+ }
136
+ }
137
+ }
138
+ new LP_Profile;
139
+ }
inc/admin/dashboard-statistics/class-lp-statistic-status.php CHANGED
@@ -12,15 +12,15 @@ if ( !class_exists( 'LP_Statistic_Status' ) ) :
12
  * @since 2.0
13
  */
14
  public static function render() {
15
- $order_statuses = learn_press_get_order_statuses(true, true);
16
  $eduma_data = self::get_eduma_info( 14058034 );
 
17
  $specific_statuses = array( 'lp-completed', 'lp-failed', 'lp-on-hold' );
18
- foreach ( $order_statuses as $status ) {
19
  if ( !in_array( $status, $specific_statuses ) ) {
20
  $specific_statuses[] = $status;
21
  }
22
  }
23
- $counts = learn_press_count_orders( array( 'status' => $specific_statuses ) );
24
  ?>
25
  <ul class="learnpress-statistic-status">
26
  <li class="full-width">
@@ -37,7 +37,7 @@ if ( !class_exists( 'LP_Statistic_Status' ) ) :
37
  if ( !$status_object ) {
38
  continue;
39
  }
40
- $count = $counts[$status];
41
  ?>
42
  <li>
43
  <?php if ( $count ): ?>
12
  * @since 2.0
13
  */
14
  public static function render() {
15
+ $order_statuses = learn_press_get_register_order_statuses();
16
  $eduma_data = self::get_eduma_info( 14058034 );
17
+ $xx = array_keys( $order_statuses );
18
  $specific_statuses = array( 'lp-completed', 'lp-failed', 'lp-on-hold' );
19
+ foreach ( $xx as $status ) {
20
  if ( !in_array( $status, $specific_statuses ) ) {
21
  $specific_statuses[] = $status;
22
  }
23
  }
 
24
  ?>
25
  <ul class="learnpress-statistic-status">
26
  <li class="full-width">
37
  if ( !$status_object ) {
38
  continue;
39
  }
40
+ $count = count( learn_press_get_orders( array( 'post_status' => $status ) ) );
41
  ?>
42
  <li>
43
  <?php if ( $count ): ?>
inc/admin/includes/class-markdown-parse.php CHANGED
@@ -239,7 +239,7 @@ class Markdown_Parser {
239
  var $predef_titles = array();
240
 
241
 
242
- function __construct() {
243
  #
244
  # Constructor function. Initialize appropriate member variables.
245
  #
@@ -1691,7 +1691,7 @@ class MarkdownExtra_Parser extends Markdown_Parser {
1691
  var $predef_abbr = array();
1692
 
1693
 
1694
- function __construct() {
1695
  #
1696
  # Constructor function. Initialize the parser object.
1697
  #
@@ -1717,7 +1717,7 @@ class MarkdownExtra_Parser extends Markdown_Parser {
1717
  "doAbbreviations" => 70,
1718
  );
1719
 
1720
- parent::__construct();
1721
  }
1722
 
1723
 
@@ -2268,15 +2268,13 @@ class MarkdownExtra_Parser extends Markdown_Parser {
2268
  if ($matches[3] == '-' && preg_match('{^- }', $matches[1]))
2269
  return $matches[0];
2270
  $level = $matches[3]{0} == '=' ? 1 : 2;
2271
- $id =& $matches[2];
2272
- $attr = $this->_doHeaders_attr($id);
2273
  $block = "<h$level$attr>".$this->runSpanGamut($matches[1])."</h$level>";
2274
  return "\n" . $this->hashBlock($block) . "\n\n";
2275
  }
2276
  function _doHeaders_callback_atx($matches) {
2277
  $level = strlen($matches[1]);
2278
- $id =& $matches[3];
2279
- $attr = $this->_doHeaders_attr($id);
2280
  $block = "<h$level$attr>".$this->runSpanGamut($matches[2])."</h$level>";
2281
  return "\n" . $this->hashBlock($block) . "\n\n";
2282
  }
239
  var $predef_titles = array();
240
 
241
 
242
+ function Markdown_Parser() {
243
  #
244
  # Constructor function. Initialize appropriate member variables.
245
  #
1691
  var $predef_abbr = array();
1692
 
1693
 
1694
+ function MarkdownExtra_Parser() {
1695
  #
1696
  # Constructor function. Initialize the parser object.
1697
  #
1717
  "doAbbreviations" => 70,
1718
  );
1719
 
1720
+ parent::Markdown_Parser();
1721
  }
1722
 
1723
 
2268
  if ($matches[3] == '-' && preg_match('{^- }', $matches[1]))
2269
  return $matches[0];
2270
  $level = $matches[3]{0} == '=' ? 1 : 2;
2271
+ $attr = $this->_doHeaders_attr($id =& $matches[2]);
 
2272
  $block = "<h$level$attr>".$this->runSpanGamut($matches[1])."</h$level>";
2273
  return "\n" . $this->hashBlock($block) . "\n\n";
2274
  }
2275
  function _doHeaders_callback_atx($matches) {
2276
  $level = strlen($matches[1]);
2277
+ $attr = $this->_doHeaders_attr($id =& $matches[3]);
 
2278
  $block = "<h$level$attr>".$this->runSpanGamut($matches[2])."</h$level>";
2279
  return "\n" . $this->hashBlock($block) . "\n\n";
2280
  }
inc/admin/lp-admin-functions.php CHANGED
@@ -1,2167 +1,2098 @@
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
-
31
- return apply_filters( 'learn_press_admin_view', $view, $name );
32
- }
33
-
34
- /**
35
- * Find a full path of a view and display the content in admin
36
- *
37
- * @param $name
38
- * @param array $args
39
- * @param bool|false $include_once
40
- * @param bool
41
- *
42
- * @return bool
43
- */
44
- function learn_press_admin_view( $name, $args = array(), $include_once = false, $return = false ) {
45
- $view = learn_press_get_admin_view( $name, !empty( $args['plugin_file'] ) ? $args['plugin_file'] : null );
46
- if ( file_exists( $view ) ) {
47
- ob_start();
48
- // extract parameters as local variables if passed
49
- is_array( $args ) && extract( $args );
50
- do_action( 'learn_press_before_display_admin_view', $name, $args );
51
- if ( $include_once ) {
52
- include_once $view;
53
- } else {
54
- include $view;
55
- }
56
- do_action( 'learn_press_after_display_admin_view', $name, $args );
57
- $output = ob_get_clean();
58
- if ( !$return ) {
59
- echo $output;
60
- }
61
-
62
- return $return ? $output : true;
63
- }
64
-
65
- return false;
66
- }
67
-
68
- /**
69
- * List all pages as a dropdown with "Add New Page" option
70
- *
71
- * @param $name
72
- * @param bool|false $selected
73
- * @param array $args
74
- *
75
- * @return mixed|string
76
- */
77
- function learn_press_pages_dropdown( $name, $selected = false, $args = array() ) {
78
- $id = null;
79
- $class = null;
80
- $css = null;
81
- $before = array(
82
- 'add_new_page' => __( '[ Add a new page ]', 'learnpress' )
83
- );
84
- $after = null;
85
- $echo = true;
86
- $allow_create = true;
87
- is_array( $args ) && extract( $args );
88
-
89
- if ( empty( $id ) ) {
90
- $id = $name;
91
- }
92
- $args = array(
93
- 'name' => $name,
94
- 'id' => $id,
95
- 'sort_column' => 'menu_order',
96
- 'sort_order' => 'ASC',
97
- 'show_option_none' => __( 'Select Page', 'learnpress' ),
98
- 'class' => $class,
99
- 'echo' => false,
100
- 'selected' => $selected,
101
- 'allow_create' => true
102
- );
103
- $output = wp_dropdown_pages( $args );
104
- $replace = "";
105
-
106
- $class .= 'learn-press-dropdown-pages';
107
-
108
- if ( $class ) {
109
- $replace .= ' class="' . $class . '"';
110
- }
111
- if ( $css ) {
112
- $replace .= ' style="' . $css . '"';
113
- }
114
-
115
- $replace .= ' data-selected="' . $selected . '"';
116
- $replace .= " data-placeholder='" . __( 'Select a page&hellip;', 'learnpress' ) . "' id=";
117
- $output = str_replace( ' id=', $replace, $output );
118
- if ( $before ) {
119
- $before_output = array();
120
- foreach ( $before as $v => $l ) {
121
- $before_output[] = sprintf( '<option value="%s">%s</option>', $v, $l );
122
- }
123
- $before_output = join( "\n", $before_output );
124
- $output = preg_replace( '!(<option class=".*" value="[0-9]+".*>.*</option>)!', $before_output . "\n$1", $output, 1 );
125
- }
126
- if ( $allow_create ) {
127
- ob_start(); ?>
128
- <button class="button button-quick-add-page" data-id="<?php echo $id; ?>" type="button"><?php _e( 'Create', 'learnpress' ); ?></button>
129
- <p class="learn-press-quick-add-page-inline <?php echo $id; ?> hide-if-js">
130
- <input type="text" placeholder="<?php esc_attr_e( 'New page title', 'learnpress' ); ?>" />
131
- <button class="button" type="button"><?php esc_html_e( 'Ok [Enter]', 'learnpress' ); ?></button>
132
- <a href=""><?php _e( 'Cancel [ESC]', 'learnpress' ); ?></a>
133
- </p>
134
- <p class="learn-press-quick-add-page-actions <?php echo $id; ?><?php echo $selected ? '' : ' hide-if-js'; ?>">
135
- <a class="edit-page" href="<?php echo get_edit_post_link( $selected ); ?>" target="_blank"><?php _e( 'Edit Page', 'learnpress' ); ?></a>
136
- <a class="view-page" href="<?php echo get_permalink( $selected ); ?>" target="_blank"><?php _e( 'View Page', 'learnpress' ); ?></a>
137
- </p>
138
- <?php $output .= ob_get_clean();
139
- }
140
- if ( $echo ) {
141
- echo $output;
142
- }
143
-
144
- return $output;
145
- }
146
-
147
- /**
148
- * List all registered question types into dropdown
149
- *
150
- * @param array
151
- *
152
- * @return string
153
- */
154
- function learn_press_dropdown_question_types( $args = array() ) {
155
- $args = wp_parse_args(
156
- $args,
157
- array(
158
- 'name' => 'learn-press-dropdown-question-types',
159
- 'id' => '',
160
- 'class' => '',
161
- 'selected' => '',
162
- 'echo' => true
163
- )
164
- );
165
- if ( !$args['id'] ) {
166
- $args['id'] = $args['name'];
167
- }
168
- $args['class'] = 'lp-dropdown-question-types' . ( $args['class'] ? ' ' . $args['class'] : '' );
169
- $types = learn_press_question_types();
170
- $output = sprintf( '<select name="%s" id="%s" class="%s"%s>', $args['name'], $args['id'], $args['class'], $args['selected'] ? 'data-selected="' . $args['selected'] . '"' : '' );
171
- foreach ( $types as $slug => $name ) {
172
- $output .= sprintf( '<option value="%s"%s>%s</option>', $slug, selected( $slug == $args['selected'], true, false ), $name );
173
- }
174
- $output .= '</select>';
175
- if ( $args['echo'] ) {
176
- echo $output;
177
- }
178
-
179
- return $output;
180
- }
181
-
182
- /**
183
- * List all registered question types into dropdown
184
- *
185
- * @param array
186
- *
187
- * @return string
188
- */
189
- function learn_press_field_question_duration( $args = array(), $question ) {
190
- global $post;
191
- $duration_type = get_post_meta( $post->ID, "_lp_duration_type", true );
192
- $value = get_post_meta( $question->id, '_question_duration', true );
193
-
194
- $wrap_class = 'learn-press-question-duration';
195
- if ( 'questions_duration' !== $duration_type ) {
196
- $wrap_class .= ' hide';
197
- }
198
- $args = wp_parse_args(
199
- $args,
200
- array(
201
- 'name' => 'learn_press_question[' . $question->id . '][duration]',
202
- 'id' => 'learn-press-question-duration-' . $question->id,
203
- 'class' => 'learn-press-question-duration',
204
- 'selected' => '',
205
- 'echo' => true,
206
- 'value' => 0,
207
- 'step' => 1,
208
- 'min' => 0,
209
- 'placeholder' => __( 'Minutes', 'learnpress' ),
210
- )
211
- );
212
- $args['value'] = $value;
213
-
214
- if ( !$args['id'] ) {
215
- $args['id'] = $args['name'];
216
- }
217
-
218
- return '<span class="' . esc_attr( $wrap_class ) . '">' . sprintf(
219
- '<input type="number" class="%s" name="%s" id="%s" value="%s" step="%s" min="%s" max="%s" placeholder="%s"/>',
220
- $args['class'],
221
- $args['name'],
222
- empty( $args['clone'] ) ? $args['id'] : '',
223
- $args['value'],
224
- $args['step'],
225
- $args['min'],
226
- !empty( $args['max'] ) ? $args['max'] : '',
227
- $args['placeholder']
228
- ) . $args['placeholder'] . '</span>';
229
- }
230
-
231
- /**
232
- * Displays email formats support into a dropdown
233
- *
234
- * @param array $args
235
- *
236
- * @return string
237
- */
238
- function learn_press_email_formats_dropdown( $args = array() ) {
239
- $args = wp_parse_args(
240
- $args,
241
- array(
242
- 'name' => 'learn-press-dropdown-email-formats',
243
- 'id' => '',
244
- 'class' => '',
245
- 'selected' => '',
246
- 'echo' => true
247
- )
248
- );
249
- $formats = array(
250
- //'text_message' => __( 'Text message', 'learnpress' ),
251
- 'plain_text' => __( 'Plain text', 'learnpress' ),
252
- 'html' => __( 'HTML', 'learnpress' ),
253
- //'multipart' => __( 'Multipart', 'learnpress' )
254
- );
255
- $output = sprintf( '<select name="%s" id="%s" class="%s" %s>', $args['name'], $args['id'], $args['class'], '' );
256
- foreach ( $formats as $name => $text ) {
257
- $output .= sprintf( '<option value="%s" %s>%s</option>', $name, selected( $args['selected'] == $name, true, false ), $text ) . "\n";
258
- }
259
- $output .= '</select>';
260
-
261
- if ( $args['echo'] ) {
262
- echo $output;
263
- }
264
-
265
- return $output;
266
- }
267
-
268
- /**************************************************/
269
- /**************************************************/
270
- /**************************************************/
271
-
272
- /**
273
- * Translate javascript text
274
- */
275
- function learn_press_admin_localize_script() {
276
- if ( defined( 'LP_DOING_AJAX' ) || !is_admin() ) {
277
- return;
278
- }
279
- $translate = array(
280
- 'quizzes_is_not_available' => __( 'Quiz is not available', 'learnpress' ),
281
- 'lessons_is_not_available' => __( 'Lesson is not available', 'learnpress' ),
282
- 'duplicate_course' => array(
283
- 'title' => __( 'Duplicate course', 'learnpress' ),
284
- 'message' => __( 'Duplicate course curriculum?', 'learnpress' )
285
- ),
286
- 'duplicate_question' => array(
287
- 'title' => __( 'Duplicate Question', 'learnpress' ),
288
- 'message' => __( 'Do you want to duplicate this question?', 'learnpress' )
289
- ),
290
- 'remove_question' => __( 'Do you want to remove this question from quiz?', 'learnpress' ),
291
- 'nonces' => array(
292
- 'duplicate_question' => wp_create_nonce( 'duplicate-question' )
293
- )
294
- );
295
- LP_Assets::add_localize( $translate );
296
- }
297
-
298
- add_action( 'init', 'learn_press_admin_localize_script' );
299
-
300
- /**
301
- * Default admin settings pages
302
- *
303
- * @return mixed
304
- */
305
- function learn_press_settings_tabs_array() {
306
- $tabs = array(
307
- 'general' => __( 'General', 'learnpress' ),
308
- 'courses' => __( 'Courses', 'learnpress' ),
309
- 'pages' => __( 'Pages', 'learnpress' ),
310
- 'payments' => __( 'Payments', 'learnpress' ),
311
- 'checkout' => __( 'Checkout', 'learnpress' ),
312
- //'profile' => __( 'Profile', 'learnpress' ),
313
- 'emails' => __( 'Emails', 'learnpress' )
314
- );
315
-
316
- return apply_filters( 'learn_press_settings_tabs_array', $tabs );
317
- }
318
-
319
- /**
320
- * Count number of orders between to dates
321
- *
322
- * @param string
323
- * @param int
324
- *
325
- * @return int
326
- */
327
- function learn_press_get_order_by_time( $by, $time ) {
328
- global $wpdb;
329
- $user_id = get_current_user_id();
330
-
331
- $y = date( 'Y', $time );
332
- $m = date( 'm', $time );
333
- $d = date( 'd', $time );
334
- switch ( $by ) {
335
- case 'days':
336
- $orders = $wpdb->get_var(
337
- $wpdb->prepare(
338
- "SELECT COUNT(*)
339
- FROM $wpdb->posts AS p
340
- INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
341
- WHERE p.post_author = %d
342
- AND p.post_type = %s
343
- AND p.post_status = %s
344
- AND m.meta_key = %s
345
- AND m.meta_value = %s
346
- AND YEAR(p.post_date) = %s AND MONTH(p.post_date) = %s AND DAY(p.post_date) = %s",
347
- $user_id, LP_ORDER_CPT, 'publish', '_learn_press_transaction_status', 'completed', $y, $m, $d
348
- )
349
- );
350
- break;
351
- case 'months':
352
- $orders = $wpdb->get_var(
353
- $wpdb->prepare(
354
- "SELECT COUNT(*)
355
- FROM $wpdb->posts AS p
356
- INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
357
- WHERE p.post_author = %d
358
- AND p.post_type = %s
359
- AND p.post_status = %s
360
- AND m.meta_key = %s
361
- AND m.meta_value = %s
362
- AND YEAR(p.post_date) = %s AND MONTH(p.post_date) = %s",
363
- $user_id, LP_ORDER_CPT, 'publish', '_learn_press_transaction_status', 'completed', $y, $m
364
- )
365
- );
366
- break;
367
- }
368
-
369
- return $orders;
370
- }
371
-
372
- /**
373
- * Count number of orders by status
374
- *
375
- * @param string Status of the orders
376
- *
377
- * @return int
378
- */
379
- function learn_press_get_courses_by_status( $status ) {
380
- global $wpdb;
381
- $user_id = get_current_user_id();
382
- $courses = $wpdb->get_var(
383
- $wpdb->prepare(
384
- "SELECT COUNT(*)
385
- FROM $wpdb->posts
386
- WHERE post_author = %d
387
- AND post_type = %s
388
- AND post_status = %s",
389
- $user_id, LP_COURSE_CPT, $status
390
- )
391
- );
392
-
393
- return $courses;
394
- }
395
-
396
- /**
397
- * Count number of orders by price
398
- *
399
- * @param string
400
- *
401
- * @return int
402
- */
403
- function learn_press_get_courses_by_price( $fee ) {
404
- global $wpdb;
405
- $user_id = get_current_user_id();
406
- $courses = $wpdb->get_var(
407
- $wpdb->prepare(
408
- "SELECT COUNT(*)
409
- FROM $wpdb->posts AS p
410
- INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
411
- WHERE p.post_author = %d
412
- AND p.post_type = %s
413
- AND p.post_status IN (%s, %s)
414
- AND m.meta_key = %s
415
- AND m.meta_value = %s",
416
- $user_id, LP_COURSE_CPT, 'publish', 'pending', '_lpr_course_payment', $fee
417
- )
418
- );
419
-
420
- return $courses;
421
- }
422
-
423
- /**
424
- * Get data about students to render in chart
425
- *
426
- * @param null $from
427
- * @param null $by
428
- * @param $time_ago
429
- *
430
- * @return array
431
- */
432
- function learn_press_get_chart_students( $from = null, $by = null, $time_ago ) {
433
- $labels = array();
434
- $datasets = array();
435
- if ( is_null( $from ) ) {
436
- $from = current_time( 'mysql' );
437
- }
438
- // $by: days, months or years
439
- if ( is_null( $by ) ) {
440
- $by = 'days';
441
- }
442
- switch ( $by ) {
443
- case 'days':
444
- $date_format = 'M d';
445
- break;
446
- case 'months':
447
- $date_format = 'M Y';
448
- break;
449
- case 'years':
450
- $date_format = 'Y';
451
- break;
452
- }
453
-
454
- for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
455
- $labels[] = date( $date_format, strtotime( "$i $by", strtotime( $from ) ) );
456
- $datasets[0]['data'][] = learn_press_get_order_by_time( $by, strtotime( "$i $by", strtotime( $from ) ) );
457
- }
458
- $colors = learn_press_get_admin_colors();
459
- $datasets[0]['fillColor'] = 'rgba(255,255,255,0.1)';
460
- $datasets[0]['strokeColor'] = $colors[0];
461
- $datasets[0]['pointColor'] = $colors[0];
462
- $datasets[0]['pointStrokeColor'] = $colors[2];
463
- $datasets[0]['pointHighlightFill'] = $colors[2];
464
- $datasets[0]['pointHighlightStroke'] = $colors[0];
465
-
466
- return array(
467
- 'labels' => $labels,
468
- 'datasets' => $datasets
469
- );
470
- }
471
-
472
- /**
473
- * Get data about students to render in chart
474
- *
475
- * @param null $from
476
- * @param null $by
477
- * @param $time_ago
478
- *
479
- * @return array
480
- */
481
- function learn_press_get_chart_users( $from = null, $by = null, $time_ago ) {
482
- global $wpdb;
483
-
484
- $labels = array();
485
- $datasets = array();
486
- if ( is_null( $from ) ) {
487
- $from = current_time( 'mysql' );
488
- }
489
- if ( is_null( $by ) ) {
490
- $by = 'days';
491
- }
492
- $results = array(
493
- 'all' => array(),
494
- 'instructors' => array()
495
- );
496
- $from_time = is_numeric( $from ) ? $from : strtotime( $from );
497
-
498
- switch ( $by ) {
499
- case 'days':
500
- $date_format = 'M d Y';
501
- $_from = - $time_ago + 1;
502
- $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
503
- $_to = date( 'Y-m-d', $from_time );
504
- $_sql_format = '%Y-%m-%d';
505
- $_key_format = 'Y-m-d';
506
- break;
507
- case 'months':
508
- $date_format = 'M Y';
509
- $_from = - $time_ago + 1;
510
- $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
511
- $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
512
- $_to = date( 'Y-m-' . $days, $from_time );
513
- $_sql_format = '%Y-%m';
514
- $_key_format = 'Y-m';
515
- break;
516
- case 'years':
517
- $date_format = 'Y';
518
- $_from = - $time_ago + 1;
519
- $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
520
- $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
521
- $_to = date( 'Y-12-' . $days, $from_time );
522
- $_sql_format = '%Y';
523
- $_key_format = 'Y';
524
-
525
- break;
526
- }
527
- $query = $wpdb->prepare( "
528
- SELECT count(u.ID) as c, DATE_FORMAT( u.user_registered, %s) as d
529
- FROM {$wpdb->users} u
530
- WHERE 1
531
- GROUP BY d
532
- HAVING d BETWEEN %s AND %s
533
- ORDER BY d ASC
534
- ", $_sql_format, $_from, $_to );
535
- if ( $_results = $wpdb->get_results( $query ) ) {
536
- foreach ( $_results as $k => $v ) {
537
- $results['all'][$v->d] = $v;
538
- }
539
- }
540
- $query = $wpdb->prepare( "
541
- SELECT count(u.ID) as c, DATE_FORMAT( u.user_registered, %s) as d
542
- FROM {$wpdb->users} u
543
- 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 )
544
- WHERE 1
545
- GROUP BY d
546
- HAVING d BETWEEN %s AND %s
547
- ORDER BY d ASC
548
- ", $_sql_format, 'wp_capabilities', '%' . $wpdb->esc_like( 's:13:"administrator"' ) . '%', '%' . $wpdb->esc_like( 's:10:"lp_teacher"' ) . '%', $_from, $_to );
549
-
550
- if ( $_results = $wpdb->get_results( $query ) ) {
551
- foreach ( $_results as $k => $v ) {
552
- $results['instructors'][$v->d] = $v;
553
- }
554
- }
555
- for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
556
- $date = strtotime( "$i $by", $from_time );
557
- $labels[] = date( $date_format, $date );
558
- $key = date( $_key_format, $date );
559
-
560
- $all = !empty( $results['all'][$key] ) ? $results['all'][$key]->c : 0;
561
- $instructors = !empty( $results['instructors'][$key] ) ? $results['instructors'][$key]->c : 0;
562
-
563
- $datasets[0]['data'][] = $all;
564
- $datasets[1]['data'][] = $instructors;
565
- $datasets[2]['data'][] = $all - $instructors;
566
- }
567
-
568
- $dataset_params = array(
569
- array(
570
- 'color1' => 'rgba(47, 167, 255, %s)',
571
- 'color2' => '#FFF',
572
- 'label' => __( 'All', 'learnpress' )
573
- ),
574
- array(
575
- 'color1' => 'rgba(212, 208, 203, %s)',
576
- 'color2' => '#FFF',
577
- 'label' => __( 'Instructors', 'learnpress' )
578
- ),
579
- array(
580
- 'color1' => 'rgba(234, 199, 155, %s)',
581
- 'color2' => '#FFF',
582
- 'label' => __( 'Students', 'learnpress' )
583
- )
584
- );
585
-
586
- foreach ( $dataset_params as $k => $v ) {
587
- $datasets[$k]['fillColor'] = sprintf( $v['color1'], '0.2' );
588
- $datasets[$k]['strokeColor'] = sprintf( $v['color1'], '1' );
589
- $datasets[$k]['pointColor'] = sprintf( $v['color1'], '1' );
590
- $datasets[$k]['pointStrokeColor'] = $v['color2'];
591
- $datasets[$k]['pointHighlightFill'] = $v['color2'];
592
- $datasets[$k]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
593
- $datasets[$k]['label'] = $v['label'];
594
- }
595
-
596
- return array(
597
- 'labels' => $labels,
598
- 'datasets' => $datasets,
599
- 'sql' => $query
600
- );
601
- }
602
-
603
-
604
- /**
605
- * Get data about students to render in chart
606
- *
607
- * @param null $from
608
- * @param null $by
609
- * @param $time_ago
610
- *
611
- * @return array
612
- */
613
- function learn_press_get_chart_courses( $from = null, $by = null, $time_ago ) {
614
- global $wpdb;
615
-
616
- $labels = array();
617
- $datasets = array();
618
- if ( is_null( $from ) ) {
619
- $from = current_time( 'mysql' );
620
- }
621
- if ( is_null( $by ) ) {
622
- $by = 'days';
623
- }
624
- $results = array(
625
- 'all' => array(),
626
- 'public' => array(),
627
- 'pending' => array(),
628
- 'free' => array(),
629
- 'paid' => array()
630
- );
631
- $from_time = is_numeric( $from ) ? $from : strtotime( $from );
632
-
633
- switch ( $by ) {
634
- case 'days':
635
- $date_format = 'M d Y';
636
- $_from = - $time_ago + 1;
637
- $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
638
- $_to = date( 'Y-m-d', $from_time );
639
- $_sql_format = '%Y-%m-%d';
640
- $_key_format = 'Y-m-d';
641
- break;
642
- case 'months':
643
- $date_format = 'M Y';
644
- $_from = - $time_ago + 1;
645
- $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
646
- $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
647
- $_to = date( 'Y-m-' . $days, $from_time );
648
- $_sql_format = '%Y-%m';
649
- $_key_format = 'Y-m';
650
- break;
651
- case 'years':
652
- $date_format = 'Y';
653
- $_from = - $time_ago + 1;
654
- $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
655
- $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
656
- $_to = date( 'Y-12-' . $days, $from_time );
657
- $_sql_format = '%Y';
658
- $_key_format = 'Y';
659
-
660
- break;
661
- }
662
-
663
- $query_where = '';
664
- if ( current_user_can( LP_TEACHER_ROLE ) ) {
665
- $user_id = learn_press_get_current_user_id();
666
- $query_where .= $wpdb->prepare( " AND c.post_author=%d ", $user_id );
667
- }
668
-
669
- $query = $wpdb->prepare( "
670
- SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
671
- FROM {$wpdb->posts} c
672
- WHERE 1
673
- {$query_where}
674
- AND c.post_status IN('publish', 'pending') AND c.post_type = %s
675
- GROUP BY d
676
- HAVING d BETWEEN %s AND %s
677
- ORDER BY d ASC
678
- ", $_sql_format, 'lp_course', $_from, $_to );
679
- if ( $_results = $wpdb->get_results( $query ) ) {
680
- foreach ( $_results as $k => $v ) {
681
- $results['all'][$v->d] = $v;
682
- }
683
- }
684
- $query = $wpdb->prepare( "
685
- SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
686
- FROM {$wpdb->posts} c
687
- WHERE 1
688
- {$query_where}
689
- AND c.post_status = %s AND c.post_type = %s
690
- GROUP BY d
691
- HAVING d BETWEEN %s AND %s
692
- ORDER BY d ASC
693
- ", $_sql_format, 'publish', 'lp_course', $_from, $_to );
694
- if ( $_results = $wpdb->get_results( $query ) ) {
695
- foreach ( $_results as $k => $v ) {
696
- $results['publish'][$v->d] = $v;
697
- }
698
- }
699
-
700
- $query = $wpdb->prepare( "
701
- SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
702
- FROM {$wpdb->posts} c
703
- INNER JOIN {$wpdb->postmeta} cm ON cm.post_id = c.ID AND cm.meta_key = %s AND cm.meta_value = %s
704
- WHERE 1
705
- {$query_where}
706
- AND c.post_status = %s AND c.post_type = %s
707
- GROUP BY d
708
- HAVING d BETWEEN %s AND %s
709
- ORDER BY d ASC
710
- ", $_sql_format, '_lp_payment', 'yes', 'publish', 'lp_course', $_from, $_to );
711
- if ( $_results = $wpdb->get_results( $query ) ) {
712
- foreach ( $_results as $k => $v ) {
713
- $results['paid'][$v->d] = $v;
714
- }
715
- }
716
-
717
- for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
718
- $date = strtotime( "$i $by", $from_time );
719
- $labels[] = date( $date_format, $date );
720
- $key = date( $_key_format, $date );
721
-
722
- $all = !empty( $results['all'][$key] ) ? $results['all'][$key]->c : 0;
723
- $publish = !empty( $results['publish'][$key] ) ? $results['publish'][$key]->c : 0;
724
- $paid = !empty( $results['paid'][$key] ) ? $results['paid'][$key]->c : 0;
725
-
726
- $datasets[0]['data'][] = $all;
727
- $datasets[1]['data'][] = $publish;
728
- $datasets[2]['data'][] = $all - $publish;
729
- $datasets[3]['data'][] = $paid;
730
- $datasets[4]['data'][] = $all - $paid;
731
- }
732
-
733
- $dataset_params = array(
734
- array(
735
- 'color1' => 'rgba(47, 167, 255, %s)',
736
- 'color2' => '#FFF',
737
- 'label' => __( 'All', 'learnpress' )
738
- ),
739
- array(
740
- 'color1' => 'rgba(212, 208, 203, %s)',
741
- 'color2' => '#FFF',
742
- 'label' => __( 'Publish', 'learnpress' )
743
- ),
744
- array(
745
- 'color1' => 'rgba(234, 199, 155, %s)',
746
- 'color2' => '#FFF',
747
- 'label' => __( 'Pending', 'learnpress' )
748
- ),
749
- array(
750
- 'color1' => 'rgba(234, 199, 155, %s)',
751
- 'color2' => '#FFF',
752
- 'label' => __( 'Paid', 'learnpress' )
753
- ),
754
- array(
755
- 'color1' => 'rgba(234, 199, 155, %s)',
756
- 'color2' => '#FFF',
757
- 'label' => __( 'Free', 'learnpress' )
758
- )
759
- );
760
-
761
- foreach ( $dataset_params as $k => $v ) {
762
- $datasets[$k]['fillColor'] = sprintf( $v['color1'], '0.2' );
763
- $datasets[$k]['strokeColor'] = sprintf( $v['color1'], '1' );
764
- $datasets[$k]['pointColor'] = sprintf( $v['color1'], '1' );
765
- $datasets[$k]['pointStrokeColor'] = $v['color2'];
766
- $datasets[$k]['pointHighlightFill'] = $v['color2'];
767
- $datasets[$k]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
768
- $datasets[$k]['label'] = $v['label'];
769
- }
770
-
771
- return array(
772
- 'labels' => $labels,
773
- 'datasets' => $datasets,
774
- 'sql' => $query
775
- );
776
- }
777
-
778
-
779
- /**
780
- * Get data about students to render in chart
781
- *
782
- * @param null $from
783
- * @param null $by
784
- * @param $time_ago
785
- *
786
- * @return array
787
- */
788
- function learn_press_get_chart_orders( $from = null, $by = null, $time_ago ) {
789
- global $wpdb;
790
- // var_dump( current_user_can(LP_TEACHER_ROLE) );
791
- // exit();
792
- $report_sales_by = learn_press_get_request( 'report_sales_by' );
793
- $course_id = learn_press_get_request( 'course_id' );
794
- $cat_id = learn_press_get_request( 'cat_id' );
795
-
796
- $labels = array();
797
- $datasets = array();
798
- if ( is_null( $from ) ) {
799
- $from = current_time( 'mysql' );
800
- }
801
- if ( is_null( $by ) ) {
802
- $by = 'days';
803
- }
804
- $results = array(
805
- 'all' => array(),
806
- 'completed' => array(),
807
- 'pending' => array()
808
- );
809
- $from_time = is_numeric( $from ) ? $from : strtotime( $from );
810
-
811
- switch ( $by ) {
812
- case 'days':
813
- $date_format = 'M d Y';
814
- $_from = - $time_ago + 1;
815
- $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
816
- $_to = date( 'Y-m-d', $from_time );
817
- $_sql_format = '%Y-%m-%d';
818
- $_key_format = 'Y-m-d';
819
- break;
820
- case 'months':
821
- $date_format = 'M Y';
822
- $_from = - $time_ago + 1;
823
- $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
824
- $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
825
- $_to = date( 'Y-m-' . $days, $from_time );
826
- $_sql_format = '%Y-%m';
827
- $_key_format = 'Y-m';
828
- break;
829
- case 'years':
830
- $date_format = 'Y';
831
- $_from = - $time_ago + 1;
832
- $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
833
- $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
834
- $_to = date( 'Y-12-' . $days, $from_time );
835
- $_sql_format = '%Y';
836
- $_key_format = 'Y';
837
-
838
- break;
839
- }
840
-
841
- $query_join = '';
842
- $query_where = '';
843
- if ( 'course' === $report_sales_by ) {
844
- $sql_join .= " INNER JOIN `{$wpdb->prefix}learnpress_order_items` `lpoi` "
845
- . " ON o.ID=lpoi.order_id "
846
- . " INNER JOIN {$wpdb->prefix}learnpress_order_itemmeta loim "
847
- . " ON lpoi.order_item_id=loim.learnpress_order_item_id "
848
- . " AND loim.meta_key='_course_id' "
849
- . " AND CAST(loim.meta_value AS SIGNED)=%d ";
850
- if ( current_user_can( LP_TEACHER_ROLE ) ) {
851
- $user_id = learn_press_get_current_user_id();
852
- $sql_join .= $wpdb->prepare( " AND CAST(loim.meta_value AS SIGNED) IN "
853
- . " ( "
854
- . " SELECT ID FROM {$wpdb->posts} p WHERE p.ID = CAST(loim.meta_value AS SIGNED) AND `post_author`=" . intval( $user_id )
855
- . " ) " );
856
- }
857
- $query_join .= $wpdb->prepare( $sql_join, $course_id );
858
-
859
- } elseif ( 'category' === $report_sales_by ) {
860
- $sql_join .= " INNER JOIN `{$wpdb->prefix}learnpress_order_items` `lpoi` "
861
- . " ON o.ID=lpoi.order_id "
862
- . " INNER JOIN {$wpdb->prefix}learnpress_order_itemmeta loim "
863
- . " ON lpoi.order_item_id=loim.learnpress_order_item_id "
864
- . " AND loim.meta_key='_course_id' "
865
- . " AND CAST(loim.meta_value AS SIGNED) IN("
866
- //sub query
867
- . " SELECT tr.object_id "
868
- . " FROM wp_term_taxonomy tt INNER JOIN wp_term_relationships tr "
869
- . " ON tt.term_taxonomy_id = tr.term_taxonomy_id AND tt.taxonomy='course_category' "
870
- . " WHERE tt.term_id=%d)";
871
- $query_join .= $wpdb->prepare( $sql_join, $cat_id );
872
- }
873
- if ( current_user_can( LP_TEACHER_ROLE ) ) {
874
- $user_id = learn_press_get_current_user_id();
875
- $query_where .= $wpdb->prepare( " AND o.ID IN( SELECT oi.order_id
876
- FROM lptest.{$wpdb->prefix}learnpress_order_items oi
877
- inner join {$wpdb->prefix}learnpress_order_itemmeta oim
878
- on oi.order_item_id = oim.learnpress_order_item_id
879
- and oim.meta_key='_course_id'
880
- and cast(oim.meta_value as SIGNED) IN (
881
- SELECT sp.ID FROM {$wpdb->prefix}posts sp WHERE sp.post_author=%d and sp.ID=cast(oim.meta_value as SIGNED)
882
- )
883
- ) ", $user_id );
884
- }
885
-
886
- $query = $wpdb->prepare( "
887
- SELECT count(o.ID) as c, DATE_FORMAT( o.post_date, %s) as d
888
- FROM {$wpdb->posts} o {$query_join}
889
- WHERE 1 {$query_where}
890
- AND o.post_status IN('lp-completed') AND o.post_type = %s
891
- GROUP BY d
892
- HAVING d BETWEEN %s AND %s
893
- ORDER BY d ASC
894
- ", $_sql_format, 'lp_order', $_from, $_to );
895
- // echo $query;
896
- if ( $_results = $wpdb->get_results( $query ) ) {
897
- foreach ( $_results as $k => $v ) {
898
- // $results['all'][$v->d] = $v;
899
- $results['completed'][$v->d] = $v;
900
- }
901
- }
902
-
903
- $query = $wpdb->prepare( "
904
- SELECT count(o.ID) as c, DATE_FORMAT( o.post_date, %s) as d
905
- FROM {$wpdb->posts} o {$query_join}
906
- WHERE 1 {$query_where}
907
- AND o.post_status IN('lp-pending', 'lp-processing') AND o.post_type = %s
908
- GROUP BY d
909
- HAVING d BETWEEN %s AND %s
910
- ORDER BY d ASC
911
- ", $_sql_format, 'lp_order', $_from, $_to );
912
- // echo $query;
913
- if ( $_results = $wpdb->get_results( $query ) ) {
914
- foreach ( $_results as $k => $v ) {
915
- // $results['completed'][$v->d] = $v;
916
- $results['pending'][$v->d] = $v;
917
- }
918
- }
919
-
920
-
921
- for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
922
- $date = strtotime( "$i $by", $from_time );
923
- $labels[] = date( $date_format, $date );
924
- $key = date( $_key_format, $date );
925
-
926
- $completed = !empty( $results['completed'][$key] ) ? $results['completed'][$key]->c : 0;
927
- $pending = !empty( $results['pending'][$key] ) ? $results['pending'][$key]->c : 0;
928
- $all = $completed + $pending;
929
-
930
- $datasets[0]['data'][] = $all;
931
- $datasets[1]['data'][] = $completed;
932
- $datasets[2]['data'][] = $pending;
933
- }
934
-
935
- $dataset_params = array(
936
- array(
937
- 'color1' => 'rgba(47, 167, 255, %s)',
938
- 'color2' => '#FFF',
939
- 'label' => __( 'All', 'learnpress' )
940
- ),
941
- array(
942
- 'color1' => 'rgba(212, 208, 203, %s)',
943
- 'color2' => '#FFF',
944
- 'label' => __( 'Completed', 'learnpress' )
945
- ),
946
- array(
947
- 'color1' => 'rgba(234, 199, 155, %s)',
948
- 'color2' => '#FFF',
949
- 'label' => __( 'Pending', 'learnpress' )
950
- )
951
- );
952
-
953
- foreach ( $dataset_params as $k => $v ) {
954
- $datasets[$k]['fillColor'] = sprintf( $v['color1'], '0.2' );
955
- $datasets[$k]['strokeColor'] = sprintf( $v['color1'], '1' );
956
- $datasets[$k]['pointColor'] = sprintf( $v['color1'], '1' );
957
- $datasets[$k]['pointStrokeColor'] = $v['color2'];
958
- $datasets[$k]['pointHighlightFill'] = $v['color2'];
959
- $datasets[$k]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
960
- $datasets[$k]['label'] = $v['label'];
961
- }
962
-
963
- return array(
964
- 'labels' => $labels,
965
- 'datasets' => $datasets,
966
- 'sql' => $query
967
- );
968
- }
969
-
970
- /**
971
- * Get data about courses to render in the chart
972
- * @return array
973
- */
974
- function learn_press_get_chart_courses2() {
975
- $labels = array(
976
- __( 'Pending Courses / Publish Courses', 'learnpress' ),
977
- __( 'Free Courses / Priced Courses', 'learnpress' )
978
- );
979
- $datasets = array();
980
- $datasets[0]['data'] = array(
981
- learn_press_get_courses_by_status( 'pending' ),
982
- learn_press_get_courses_by_price( 'free' )
983
- );
984
- $datasets[1]['data'] = array(
985
- learn_press_get_courses_by_status( 'publish' ),
986
- learn_press_get_courses_by_price( 'not_free' )
987
- );
988
-
989
- $colors = learn_press_get_admin_colors();
990
- $datasets[0]['fillColor'] = $colors[1];
991
- $datasets[0]['strokeColor'] = $colors[1];
992
- $datasets[1]['fillColor'] = $colors[3];
993
- $datasets[1]['strokeColor'] = $colors[3];
994
-
995
- return array(
996
- 'labels' => $labels,
997
- 'datasets' => $datasets
998
- );
999
- }
1000
-
1001
- /**
1002
- * Get colors setting up by admin user
1003
- * @return array
1004
- */
1005
- function learn_press_get_admin_colors() {
1006
- $admin_color = get_user_meta( get_current_user_id(), 'admin_color', true );
1007
- global $_wp_admin_css_colors;
1008
- $colors = array();
1009
- if ( !empty( $_wp_admin_css_colors[$admin_color]->colors ) ) {
1010
- $colors = $_wp_admin_css_colors[$admin_color]->colors;
1011
- }
1012
- if ( empty ( $colors[0] ) ) {
1013
- $colors[0] = '#000000';
1014
- }
1015
- if ( empty ( $colors[2] ) ) {
1016
- $colors[2] = '#00FF00';
1017
- }
1018
-
1019
- return $colors;
1020
- }
1021
-
1022
- /**
1023
- * Convert an array to json format and print out to browser
1024
- *
1025
- * @param array $chart
1026
- */
1027
- function learn_press_process_chart( $chart = array() ) {
1028
- $data = json_encode(
1029
- array(
1030
- 'labels' => $chart['labels'],
1031
- 'datasets' => $chart['datasets']
1032
- )
1033
- );
1034
- echo $data;
1035
- }
1036
-
1037
- /**
1038
- * Print out the configuration for admin chart
1039
- */
1040
- function learn_press_config_chart() {
1041
- $colors = learn_press_get_admin_colors();
1042
- $config = array(
1043
- 'scaleShowGridLines' => true,
1044
- 'scaleGridLineColor' => "#777",
1045
- 'scaleGridLineWidth' => 0.3,
1046
- 'scaleFontColor' => "#444",
1047
- 'scaleLineColor' => $colors[0],
1048
- 'bezierCurve' => true,
1049
- 'bezierCurveTension' => 0.2,
1050
- 'pointDotRadius' => 5,
1051
- 'pointDotStrokeWidth' => 5,
1052
- 'pointHitDetectionRadius' => 20,
1053
- 'datasetStroke' => true,
1054
- 'responsive' => true,
1055
- 'tooltipFillColor' => $colors[2],
1056
- 'tooltipFontColor' => "#eee",
1057
- 'tooltipCornerRadius' => 0,
1058
- 'tooltipYPadding' => 10,
1059
- 'tooltipXPadding' => 10,
1060
- 'barDatasetSpacing' => 10,
1061
- 'barValueSpacing' => 200
1062
-
1063
- );
1064
- echo json_encode( $config );
1065
- }
1066
-
1067
- function set_post_order_in_admin( $wp_query ) {
1068
- global $pagenow;
1069
- if ( isset( $_GET['post_type'] ) ) {
1070
- $post_type = $_GET['post_type'];
1071
- } else {
1072
- $post_type = '';
1073
- }
1074
- if ( is_admin() && 'edit.php' == $pagenow && $post_type == LP_COURSE_CPT && !isset( $_GET['orderby'] ) ) {
1075
- $wp_query->set( 'orderby', 'date' );
1076
- $wp_query->set( 'order', 'DSC' );
1077
- }
1078
- }
1079
-
1080
- add_filter( 'pre_get_posts', 'set_post_order_in_admin' );
1081
- /**
1082
- * Add actions to the list of the course. e.g: Duplicate link
1083
- *
1084
- * @param $actions
1085
- *
1086
- * @return mixed
1087
- */
1088
- function learn_press_add_row_action_link( $actions ) {
1089
- global $post;
1090
- if ( LP_COURSE_CPT == $post->post_type ) {
1091
- $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 ) );
1092
- $duplicate_link = array(
1093
- array(
1094
- 'link' => $duplicate_link,
1095
- 'title' => __( 'Duplicate this course', 'learnpress' ),
1096
- 'class' => 'lp-duplicate-course'
1097
- )
1098
- );
1099
- $links = apply_filters( 'learn_press_row_action_links', $duplicate_link );
1100
- if ( count( $links ) > 1 ) {
1101
- $drop_down = array( '<ul class="lpr-row-action-dropdown">' );
1102
- foreach ( $links as $link ) {
1103
- $drop_down[] = '<li>' . sprintf( '<a href="%s" class="%s">%s</a>', $link['link'], $link['class'], $link['title'] ) . '</li>';
1104
- };
1105
- $drop_down[] = '</ul>';
1106
- $link = sprintf( '<div class="lpr-row-actions"><a href="%s">%s</a>%s</div>', 'javascript: void(0);', __( 'Course', 'learnpress' ), join( "\n", $drop_down ) );
1107
- } else {
1108
- $link = array_shift( $links );
1109
- $link = sprintf( '<a href="%s" class="%s">%s</a>', $link['link'], $link['class'], $link['title'] );
1110
- }
1111
- $actions['lpr-course-row-action'] = $link;
1112
- } else if ( LP_QUIZ_CPT === $post->post_type ) {
1113
- unset( $actions['view'] );
1114
- $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 ) );
1115
- $link = sprintf( '<a href="%s" class="lp-duplicate-lesson">%s</a>', $url, __( 'Duplicate this quiz', 'learnpress' ) );
1116
- $actions['lpr-course-row-action'] = $link;
1117
- } else if ( LP_QUESTION_CPT === $post->post_type ) {
1118
- unset( $actions['view'] );
1119
- $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 ) );
1120
- $link = sprintf( '<a href="%s" class="lp-duplicate-lesson">%s</a>', $url, __( 'Duplicate this question', 'learnpress' ) );
1121
- $actions['lpr-course-row-action'] = $link;
1122
- } else if ( LP_LESSON_CPT === $post->post_type ) {
1123
- unset( $actions['view'] );
1124
- $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 ) );
1125
- $link = sprintf( '<a href="%s" class="lp-duplicate-lesson">%s</a>', $url, __( 'Duplicate this lesson', 'learnpress' ) );
1126
- $actions['lpr-course-row-action'] = $link;
1127
- }
1128
-
1129
- return $actions;
1130
- }
1131
-
1132
- add_filter( 'post_row_actions', 'learn_press_add_row_action_link' );
1133
- add_filter( 'page_row_actions', 'learn_press_add_row_action_link' );
1134
-
1135
- function learn_press_copy_post_meta( $from_id, $to_id ) {
1136
- global $wpdb;
1137
- $course_meta = $wpdb->get_results(
1138
- $wpdb->prepare( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id = %d", $from_id )
1139
- );
1140
- if ( count( $course_meta ) != 0 ) {
1141
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
1142
- $sql_query_sel = array();
1143
-
1144
- foreach ( $course_meta as $meta ) {
1145
- $meta_key = $meta->meta_key;
1146
- $meta_value = addslashes( $meta->meta_value );
1147
-
1148
- $sql_query_sel[] = "SELECT {$to_id}, '$meta_key', '$meta_value'";
1149
- }
1150
-
1151
- $sql_query .= implode( " UNION ALL ", $sql_query_sel );
1152
- $wpdb->query( $sql_query );
1153
- }
1154
- }
1155
-
1156
- /**
1157
- * Duplicate a course when user hit "Duplicate" button
1158
- *
1159
- * @author TuNN
1160
- */
1161
- function learn_press_process_duplicate_action() {
1162
-
1163
- $wp_list_table = _get_list_table( 'WP_Posts_List_Table' );
1164
- $action = $wp_list_table->current_action();
1165
-
1166
- if ( isset( $_REQUEST['action'] ) && $action == 'lp-duplicate-course' ) {
1167
- // current is not usefully because this feature using ajax action
1168
- $post_id = isset( $_REQUEST['post'] ) ? $_REQUEST['post'] : 0;
1169
- $nonce = !empty( $_REQUEST['nonce'] ) ? $_REQUEST['nonce'] : '';
1170
- if ( !wp_verify_nonce( $nonce, 'lp-duplicate-' . $post_id ) ) {
1171
- wp_die( __( 'Error', 'learnpress' ) );
1172
- }
1173
- if ( $post_id && is_array( $post_id ) ) {
1174
- $post_id = array_shift( $post_id );
1175
- }
1176
- // check for post is exists
1177
- if ( !( $post_id && $post = get_post( $post_id ) ) ) {
1178
- wp_die( __( 'Oops! The course does not exist.', 'learnpress' ) );
1179
- }
1180
- // ensure that user can create course
1181
- if ( !current_user_can( 'edit_posts' ) ) {
1182
- wp_die( __( 'Sorry! You have not permission to duplicate this course.', 'learnpress' ) );
1183
- }
1184
-
1185
- // assign course to current user
1186
- $current_user = wp_get_current_user();
1187
- $new_course_author = $current_user->ID;
1188
-
1189
- // setup course data
1190
- $new_course_title = $post->post_title . ' - Copy';
1191
- $args = array(
1192
- 'comment_status' => $post->comment_status,
1193
- 'ping_status' => $post->ping_status,
1194
- 'post_author' => $new_course_author,
1195
- 'post_content' => $post->post_content,
1196
- 'post_excerpt' => $post->post_excerpt,
1197
- 'post_name' => $post->post_name,
1198
- 'post_parent' => $post->post_parent,
1199
- 'post_password' => $post->post_password,
1200
- 'post_status' => 'draft',
1201
- 'post_title' => $new_course_title,
1202
- 'post_type' => $post->post_type,
1203
- 'to_ping' => $post->to_ping,
1204
- 'menu_order' => $post->menu_order
1205
- );
1206
- // insert new course and get it ID
1207
- $new_post_id = wp_insert_post( $args );
1208
-
1209
- if ( !$new_post_id ) {
1210
- LP_Admin_Notice::add_redirect( __( '<p>Sorry! Duplicate course failed!</p>', 'learnpress' ) );
1211
- wp_redirect( admin_url( 'edit.php?post_type=lp_course' ) );
1212
- exit();
1213
- }
1214
- // assign related tags/categories to new course
1215
- $taxonomies = get_object_taxonomies( $post->post_type );
1216
- foreach ( $taxonomies as $taxonomy ) {
1217
- $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
1218
- wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false );
1219
- }
1220
-
1221
- // duplicate course data
1222
- global $wpdb;
1223
- //learn_press_copy_post_meta( $post_id, $new_post_id );
1224
-
1225
- $query = $wpdb->prepare( "
1226
- SELECT *
1227
- FROM {$wpdb->prefix}learnpress_sections s
1228
- INNER JOIN {$wpdb->posts} c ON c.ID = s.section_course_id
1229
- WHERE c.ID = %d
1230
- ", $post->ID );
1231
- if ( $sections = $wpdb->get_results( $query ) ) {
1232
- foreach ( $sections as $section ) {
1233
- $new_section_id = $wpdb->insert(
1234
- $wpdb->prefix . 'learnpress_sections',
1235
- array(
1236
- 'section_name' => $section->section_name,
1237
- 'section_course_id' => $new_post_id,
1238
- 'section_order' => $section->section_order,
1239
- 'section_description' => $section->section_description
1240
- ),
1241
- array( '%s', '%d', '%d', '%s' )
1242
- );
1243
- if ( $new_section_id ) {
1244
- $query = $wpdb->prepare( "
1245
- SELECT i.*
1246
- FROM {$wpdb->posts} i
1247
- INNER JOIN {$wpdb->prefix}learnpress_sections s ON i.item_id = i.ID
1248
- WHERE s.section_id = %d
1249
- ", $section->section_id );
1250
- if ( $items = $wpdb->get_results( $query ) ) {
1251
- foreach ( $items as $item ) {
1252
- $item_args = (array) $item;
1253
- unset(
1254
- $item_args['ID'],
1255
- $item_args['post_author'],
1256
- $item_args['post_date'],
1257
- $item_args['post_date_gmt'],
1258
- $item_args['post_modified'],
1259
- $item_args['post_modified_gmt'],
1260
- $item_args['comment_count']
1261
- );
1262
- $new_item_id = $wpdb->insert(
1263
- $wpdb->posts,
1264
- $item_args
1265
- );
1266
- }
1267
- }
1268
- }
1269
- }
1270
- }
1271
- LP_Admin_Notice::add_redirect( __( '<p>Course duplicated.</p>', 'learnpress' ) );
1272
- wp_redirect( admin_url( "post.php?post={$new_post_id}&action=edit" ) );
1273
- die();
1274
- }
1275
-
1276
- // duplicate action
1277
- $action = !empty( $_REQUEST['lp-action'] ) ? $_REQUEST['lp-action'] : '';
1278
- $actions = array(
1279
- 'lp-duplicate-question',
1280
- 'lp-duplicate-lesson',
1281
- 'lp-duplicate-quiz'
1282
- );
1283
- if ( !in_array( $action, $actions ) ) {
1284
- return;
1285
- }
1286
-
1287
- $post_id = !empty ( $_REQUEST['post'] ) ? $_REQUEST['post'] : 0;
1288
- $nonce = !empty( $_REQUEST['nonce'] ) ? $_REQUEST['nonce'] : '';
1289
- if ( !$post_id || !wp_verify_nonce( $nonce, 'lp-duplicate-' . $post_id ) ) {
1290
- return;
1291
- }
1292
- // only duplicate question. not assign any data
1293
- $new_post_id = 0;
1294
- if ( $action === 'lp-duplicate-question' ) {
1295
- $new_post_id = learn_press_duplicate_question( $post_id );
1296
- $post_type = LP_QUESTION_CPT;
1297
- $error = __( 'Sorry! Duplicate question failed!', 'learnpress' );
1298
- $success = __( 'Question duplicated.', 'learnpress' );
1299
- } else if ( $action === 'lp-duplicate-lesson' ) {
1300
- $new_post_id = learn_press_duplicate_lesson( $post_id );
1301
- $post_type = LP_LESSON_CPT;
1302
- $error = __( 'Sorry! Duplicate lesson failed!', 'learnpress' );
1303
- $success = __( 'Lesson duplicated.', 'learnpress' );
1304
- } else if ( $action === 'lp-duplicate-quiz' ) {
1305
- $new_post_id = learn_press_duplicate_quiz( $post_id );
1306
- $post_type = LP_QUIZ_CPT;
1307
- $error = __( 'Sorry! Duplicate quiz failed!', 'learnpress' );
1308
- $success = __( 'Quiz duplicated.', 'learnpress' );
1309
- }
1310
-
1311
- if ( !$new_post_id ) {
1312
- return;
1313
- }
1314
- $redirect = 0;
1315
- if ( is_wp_error( $new_post_id ) ) {
1316
- LP_Admin_Notice::add_redirect( $error, 'error' );
1317
- $redirect = admin_url( 'edit.php?post_type=' . $post_type );
1318
- } else {
1319
- LP_Admin_Notice::add_redirect( $success, 'updated' );
1320
- $redirect = admin_url( 'post.php?post=' . $new_post_id . '&action=edit' );
1321
- }
1322
-
1323
- if ( $redirect ) {
1324
- wp_safe_redirect( $redirect );
1325
- exit();
1326
- }
1327
- }
1328
-
1329
- add_action( 'load-edit.php', 'learn_press_process_duplicate_action' );
1330
-
1331
- /**
1332
- * Install a plugin
1333
- *
1334
- * @param string $plugin_name
1335
- *
1336
- * @return array
1337
- */
1338
- function learn_press_install_add_on( $plugin_name ) {
1339
- require_once( LP_PLUGIN_PATH . '/inc/admin/class-lp-upgrader.php' );
1340
- $upgrader = new LP_Upgrader();
1341
- global $wp_filesystem;
1342
- $response = array();
1343
-
1344
- $package = 'http://thimpress.com/lprepo/' . $plugin_name . '.zip';
1345
-
1346
- $package = $upgrader->download_package( $package );
1347
- if ( is_wp_error( $package ) ) {
1348
- $response['error'] = $package;
1349
- } else {
1350
- $working_dir = $upgrader->unpack_package( $package, true, $plugin_name );
1351
- if ( is_wp_error( $working_dir ) ) {
1352
- $response['error'] = $working_dir;
1353
- } else {
1354
-
1355
- $wp_upgrader = new WP_Upgrader();
1356
- $options = array(
1357
- 'source' => $working_dir,
1358
- 'destination' => WP_PLUGIN_DIR,
1359
- 'clear_destination' => false, // Do not overwrite files.
1360
- 'clear_working' => true,
1361
- 'hook_extra' => array(
1362
- 'type' => 'plugin',
1363
- 'action' => 'install'
1364
- )
1365
- );
1366
- //$response = array();
1367
- $result = $wp_upgrader->install_package( $options );
1368
-
1369
- if ( is_wp_error( $result ) ) {
1370
- $response['error'] = $result;
1371
- } else {
1372
- $response = $result;
1373
- $response['text'] = __( 'Installed', 'learnpress' );
1374
- }
1375
- }
1376
- }
1377
-
1378
- return $response;
1379
- }
1380
-
1381
- function learn_press_accept_become_a_teacher() {
1382
- $action = !empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
1383
- $user_id = !empty( $_REQUEST['user_id'] ) ? $_REQUEST['user_id'] : '';
1384
- if ( !$action || !$user_id || ( $action != 'accept-to-be-teacher' ) ) {
1385
- return;
1386
- }
1387
-
1388
- if ( !learn_press_user_maybe_is_a_teacher( $user_id ) ) {
1389
- $be_teacher = new WP_User( $user_id );
1390
- $be_teacher->set_role( LP_TEACHER_ROLE );
1391
- delete_transient( 'learn_press_become_teacher_sent_' . $user_id );
1392
- do_action( 'learn_press_user_become_a_teacher', $user_id );
1393
- $redirect = add_query_arg( 'become-a-teacher-accepted', 'yes' );
1394
- $redirect = remove_query_arg( 'action', $redirect );
1395
- wp_redirect( $redirect );
1396
- }
1397
- }
1398
-
1399
- add_action( 'plugins_loaded', 'learn_press_accept_become_a_teacher' );
1400
-
1401
- function learn_press_user_become_a_teacher_notice() {
1402
- if ( $user_id = learn_press_get_request( 'user_id' ) && learn_press_get_request( 'become-a-teacher-accepted' ) == 'yes' ) {
1403
- $user = new WP_User( $user_id );
1404
- ?>
1405
- <div class="updated">
1406
- <p><?php printf( __( 'The user %s has become a teacher', 'learnpress' ), $user->user_login ); ?></p>
1407
- </div>
1408
- <?php
1409
- }
1410
- }
1411
-
1412
- add_action( 'admin_notices', 'learn_press_user_become_a_teacher_notice' );
1413
-
1414
- /**
1415
- * Check to see if a plugin is already installed or not
1416
- *
1417
- * @param $plugin
1418
- *
1419
- * @return bool
1420
- */
1421
- function learn_press_is_plugin_install( $plugin ) {
1422
- $installed_plugins = get_plugins();
1423
-
1424
- return isset( $installed_plugins[$plugin] );
1425
- }
1426
-
1427
- /**
1428
- * Get plugin file that contains the information from slug
1429
- *
1430
- * @param $slug
1431
- *
1432
- * @return mixed
1433
- */
1434
- function learn_press_plugin_basename_from_slug( $slug ) {
1435
- $keys = array_keys( get_plugins() );
1436
- foreach ( $keys as $key ) {
1437
- if ( preg_match( '|^' . $slug . '/|', $key ) ) {
1438
- return $key;
1439
- }
1440
- }
1441
-
1442
- return $slug;
1443
- }
1444
-
1445
- function learn_press_one_click_install_sample_data_notice() {
1446
- $courses = get_posts(
1447
- array(
1448
- 'post_type' => LP_COURSE_CPT,
1449
- 'post_status' => 'any'
1450
- )
1451
- );
1452
- if ( ( 0 == sizeof( $courses ) ) && ( 'off' != get_transient( 'learn_press_install_sample_data' ) ) ) {
1453
- printf(
1454
- '<div class="updated" id="learn-press-install-sample-data-notice">
1455
- <div class="install-sample-data-notice">
1456
- <p>%s</p>
1457
- <p>%s <strong>%s</strong> %s
1458
- <p><a href="" class="button yes" data-action="yes">%s</a> <a href="" class="button disabled no" data-action="no">%s</a></p>
1459
- </div>
1460
- <div class="install-sample-data-loading">
1461
- <p>Importing...</p>
1462
- </div>
1463
- </div>',
1464
- __( 'You haven\'t got any courses yet! Would you like to import sample data?', 'learnpress' ),
1465
- __( 'If yes, it requires to install addon name', 'learnpress' ),
1466
- __( 'LearnPress Import/Export', 'learnpress' ),
1467
- __( 'but don\'t worry because it is completely automated.', 'learnpress' ),
1468
- __( 'Import now', 'learnpress' ),
1469
- __( 'No, thanks!', 'learnpress' )
1470
- );
1471
- }
1472
- }
1473
-
1474
- //add_action( 'admin_notices', 'learn_press_one_click_install_sample_data_notice' );
1475
-
1476
- function learn_press_request_query( $vars = array() ) {
1477
- global $typenow, $wp_query, $wp_post_statuses;
1478
- if ( LP_ORDER_CPT === $typenow ) {
1479
- // Status
1480
- if ( !isset( $vars['post_status'] ) ) {
1481
- $post_statuses = learn_press_get_order_statuses();
1482
-
1483
- foreach ( $post_statuses as $status => $value ) {
1484
- if ( isset( $wp_post_statuses[$status] ) && false === $wp_post_statuses[$status]->show_in_admin_all_list ) {
1485
- unset( $post_statuses[$status] );
1486
- }
1487
- }
1488
-
1489
- $vars['post_status'] = array_keys( $post_statuses );
1490
-
1491
- }
1492
- }
1493
-
1494
- return $vars;
1495
- }
1496
-
1497
- add_filter( 'request', 'learn_press_request_query', 0 );
1498
-
1499
- function _learn_press_reset_course_data() {
1500
- if ( empty( $_REQUEST['reset-course-data'] ) ) {
1501
- return false;
1502
- }
1503
- learn_press_reset_course_data( intval( $_REQUEST['reset-course-data'] ) );
1504
- wp_redirect( remove_query_arg( 'reset-course-data' ) );
1505
- }
1506
-
1507
- add_action( 'init', '_learn_press_reset_course_data' );
1508
-
1509
- /***********************/
1510
- function learn_press_admin_section_loop_item_class( $item, $section ) {
1511
- $classes = array(
1512
- 'lp-section-item'
1513
- );
1514
- $classes[] = 'lp-item-' . $item->post_type;
1515
- if ( !absint( $item->ID ) ) {
1516
- $classes[] = 'lp-item-empty lp-item-new focus';
1517
- }
1518
- $classes = apply_filters( 'learn_press_section_loop_item_class', $classes, $item, $section );
1519
- if ( $classes ) {
1520
- echo 'class="' . join( ' ', $classes ) . '"';
1521
- }
1522
-
1523
- return $classes;
1524
- }
1525
-
1526
- function learn_press_disable_checked_ontop( $args ) {
1527
-
1528
- if ( 'course_category' == $args['taxonomy'] ) {
1529
- $args['checked_ontop'] = false;
1530
- }
1531
-
1532
- return $args;
1533
- }
1534
-
1535
- add_filter( 'wp_terms_checklist_args', 'learn_press_disable_checked_ontop' );
1536
-
1537
- function learn_press_output_admin_template() {
1538
- learn_press_admin_view( 'admin-template.php' );
1539
- }
1540
-
1541
- add_action( 'admin_print_scripts', 'learn_press_output_admin_template' );
1542
-
1543
- function learn_press_output_screen_id() {
1544
- $screen = get_current_screen();
1545
- if ( $screen ) {
1546
- echo "<div style=\"position:fixed;top: 0; left:0; z-index: 99999999; background-color:#FFF;padding:4px;\">" . $screen->id . "</div>";
1547
- }
1548
- }
1549
-
1550
- //add_action( 'admin_head', 'learn_press_output_screen_id' );
1551
-
1552
- function learn_press_get_screens() {
1553
- $screen_id = sanitize_title( __( 'LearnPress', 'learnpress' ) );
1554
- $screens = array(
1555
- 'toplevel_page_' . $screen_id,
1556
- $screen_id . '_page_learn-press-statistics',
1557
- $screen_id . '_page_learn-press-addons',
1558
- $screen_id . '_page_learn-press-settings',
1559
- $screen_id . '_page_learn-press-tools'
1560
- );
1561
- foreach ( array( LP_COURSE_CPT, LP_LESSON_CPT, LP_QUIZ_CPT, LP_QUESTION_CPT, LP_ORDER_CPT ) as $post_type ) {
1562
- $screens[] = 'edit-' . $post_type;
1563
- $screens[] = $post_type;
1564
- }
1565
-
1566
- return apply_filters( 'learn_press_screen_ids', $screens );
1567
- }
1568
-
1569
- function learn_press_get_admin_pages() {
1570
- return apply_filters(
1571
- 'learn_press_admin_pages',
1572
- array(
1573
- 'learn-press-settings',
1574
- 'learn-press-settings'
1575
- )
1576
- );
1577
- }
1578
-
1579
- function learn_press_is_post_type_screen( $post_type, $union = 'OR' ) {
1580
- if ( is_array( $post_type ) ) {
1581
- $return = null;
1582
- foreach ( $post_type as $_post_type ) {
1583
- $check = learn_press_is_post_type_screen( $_post_type );
1584
- if ( $union == 'OR' && $check ) {
1585
- return true;
1586
- }
1587
- if ( $return == null ) {
1588
- $return = $check;
1589
- } else {
1590
- $return = $return && $check;
1591
- }
1592
- if ( $union !== 'OR' ) {
1593
- return $return;
1594
- }
1595
- }
1596
-
1597
- return $return;
1598
- }
1599
- $screen = get_current_screen();
1600
- if ( !$screen ) {
1601
- return;
1602
- }
1603
- $screen_id = $screen->id;
1604
-
1605
- return in_array( $screen_id, array( $post_type, "edit-{$post_type}" ) );
1606
- }
1607
-
1608
- function learn_press_get_notice_dismiss( $context, $type = 'transient' ) {
1609
- if ( $type == 'transient' ) {
1610
- return get_transient( 'learn_press_dismiss_notice_' . $context );
1611
- }
1612
-
1613
- return get_option( 'learn_press_dismiss_notice_' . $context );
1614
- }
1615
-
1616
- if ( !function_exists( 'learn_press_course_insert_section' ) ) {
1617
-
1618
- function learn_press_course_insert_section( $section = array() ) {
1619
- global $wpdb;
1620
- $section = wp_parse_args(
1621
- $section,
1622
- array(
1623
- 'section_name' => '',
1624
- 'section_course_id' => 0,
1625
- 'section_order' => 0,
1626
- 'section_description' => ''
1627
- )
1628
- );
1629
- $section = stripslashes_deep( $section );
1630
- extract( $section );
1631
-
1632
- $insert_data = compact( 'section_name', 'section_course_id', 'section_order', 'section_description' );
1633
- $wpdb->insert(
1634
- $wpdb->learnpress_sections,
1635
- $insert_data,
1636
- array( '%s', '%d', '%d' )
1637
- );
1638
-
1639
- return $wpdb->insert_id;
1640
- }
1641
-
1642
- }
1643
-
1644
- if ( !function_exists( 'learn_press_course_insert_section_item' ) ) {
1645
-
1646
- function learn_press_course_insert_section_item( $item_data = array() ) {
1647
- global $wpdb;
1648
- $wpdb->insert(
1649
- $wpdb->learnpress_section_items,
1650
- array(
1651
- 'section_id' => $item_data['section_id'],
1652
- 'item_id' => $item_data['item_id'],
1653
- 'item_order' => $item_data['item_order'],
1654
- 'item_type' => $item_data['item_type']
1655
- ),
1656
- array(
1657
- '%d',
1658
- '%d',
1659
- '%d',
1660
- '%s',
1661
- )
1662
- );
1663
-
1664
- return $wpdb->insert_id;
1665
- }
1666
-
1667
- }
1668
-
1669
- if ( !function_exists( 'learn_press_duplicate_post' ) ) {
1670
-
1671
- function learn_press_duplicate_post( $post_id = null, $args = array(), $meta = true ) {
1672
- $post = get_post( $post_id );
1673
- if ( !$post ) {
1674
- return;
1675
- }
1676
- $defalts = array(
1677
- 'comment_status' => $post->comment_status,
1678
- 'ping_status' => $post->ping_status,
1679
- 'post_author' => get_current_user_id(),
1680
- 'post_content' => $post->post_content,
1681
- 'post_excerpt' => $post->post_excerpt,
1682
- 'post_parent' => $post->post_parent,
1683
- 'post_password' => $post->post_password,
1684
- 'post_status' => 'draft',
1685
- 'post_title' => $post->post_title . ' - Copy',
1686
- 'post_type' => $post->post_type,
1687
- 'to_ping' => $post->to_ping,
1688
- 'menu_order' => $post->menu_order
1689
- );
1690
- $args = wp_parse_args( $args, $defalts );
1691
- $new_post_id = wp_insert_post( $args );
1692
- if ( !is_wp_error( $new_post_id ) && $meta ) {
1693
- learn_press_duplicate_post_meta( $post_id, $new_post_id );
1694
- // assign related tags/categories to new course
1695
- $taxonomies = get_object_taxonomies( $post->post_type );
1696
- foreach ( $taxonomies as $taxonomy ) {
1697
- $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
1698
- wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false );
1699
- }
1700
- }
1701
-
1702
- return apply_filters( 'learn_press_duplicate_post', $new_post_id, $post_id );
1703
- }
1704
- }
1705
-
1706
- if ( !function_exists( 'learn_press_duplicate_post_meta' ) ) {
1707
- /**
1708
- * duplicate all post meta just in two SQL queries
1709
- */
1710
- function learn_press_duplicate_post_meta( $old_post_id, $new_post_id, $excerpt = array() ) {
1711
- global $wpdb;
1712
- $post_meta_infos = $wpdb->get_results( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$old_post_id" );
1713
- if ( count( $post_meta_infos ) != 0 ) {
1714
- $excerpt = array_merge( array( '_edit_lock', '_edit_last' ), $excerpt );
1715
- $excerpt = apply_filters( 'learn_press_excerpt_duplicate_post_meta', $excerpt, $old_post_id, $new_post_id );
1716
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
1717
- $sql_query_sel = array();
1718
- foreach ( $post_meta_infos as $meta ) {
1719
- if ( in_array( $meta->meta_key, $excerpt ) ) {
1720
- continue;
1721
- }
1722
- if ( $meta->meta_key === '_lp_course_author' ) {
1723
- $meta->meta_value = get_current_user_id();
1724
- }
1725
- $meta_key = $meta->meta_key;
1726
- $meta_value = addslashes( $meta->meta_value );
1727
- $sql_query_sel[] = "SELECT $new_post_id, '$meta_key', '$meta_value'";
1728
- }
1729
- $sql_query .= implode( " UNION ALL ", $sql_query_sel );
1730
- $wpdb->query( $sql_query );
1731
- }
1732
- }
1733
-
1734
- }
1735
-
1736
- add_filter( 'learn_press_question_types', 'learn_press_sort_questions', 99 );
1737
- if ( !function_exists( 'learn_press_sort_questions' ) ) {
1738
- function learn_press_sort_questions( $types ) {
1739
- $user_id = get_current_user_id();
1740
- $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
1741
- if ( !empty( $question_types ) ) {
1742
- $sort = array();
1743
- // re-sort array descending
1744
- arsort( $question_types );
1745
- $new_types = array();
1746
- $ktypes = array_keys( $types );
1747
-
1748
- for ( $i = 0; $i < count( $ktypes ) - 1; $i ++ ) {
1749
- $max = $i;
1750
- if ( !isset( $question_types[$ktypes[$i]] ) ) {
1751
- $question_types[$ktypes[$i]] = 0;
1752
- }
1753
- for ( $j = $i + 1; $j < count( $ktypes ); $j ++ ) {
1754
- if ( isset( $question_types[$ktypes[$j]], $question_types[$ktypes[$max]] )
1755
- && $question_types[$ktypes[$j]] > $question_types[$ktypes[$max]]
1756
- ) {
1757
- $max = $j;
1758
- }
1759
- }
1760
- $tmp = $ktypes[$i];
1761
- $ktypes[$i] = $ktypes[$max];
1762
- $ktypes[$max] = $tmp;
1763
- }
1764
- $ktypes = array_flip( $ktypes );
1765
- $types = array_merge( $ktypes, $types );
1766
- }
1767
-
1768
- return $types;
1769
- }
1770
- }
1771
-
1772
- if ( !function_exists( 'learn_press_duplicate_course' ) ) {
1773
-
1774
- function learn_press_duplicate_course( $course_id = null, $force = true ) {
1775
- if ( !function_exists( '_learn_press_get_course_curriculum' ) ) {
1776
- require_once LP_PLUGIN_PATH . 'inc/lp-init.php';
1777
- }
1778
- global $wpdb;
1779
-
1780
- if ( $course_id && is_array( $course_id ) ) {
1781
- $course_id = array_shift( $course_id );
1782
- }
1783
- // check for post is exists
1784
- if ( !$course_id || !( $post = get_post( $course_id ) ) ) {
1785
- return new WP_Error( __( '<p>Op! The course does not exist</p>', 'learnpress' ) );
1786
- } else {
1787
- // ensure that user can create course
1788
- if ( !current_user_can( 'edit_posts' ) ) {
1789
- return new WP_Error( __( '<p>Sorry! You have not permission to duplicate this course</p>', 'learnpress' ) );
1790
- } else {
1791
- // duplicate course
1792
- $new_course_id = learn_press_duplicate_post( $course_id );
1793
- if ( !$new_course_id || is_wp_error( $new_course_id ) ) {
1794
- return new WP_Error( __( '<p>Sorry! Duplicate course failed!</p>', 'learnpress' ) );
1795
- } else {
1796
- $curriculums = _learn_press_get_course_curriculum( $course_id );
1797
- foreach ( $curriculums as $section_id => $section ) {
1798
- $new_section_id = learn_press_course_insert_section( array(
1799
- 'section_name' => $section->section_name,
1800
- 'section_course_id' => $new_course_id,
1801
- 'section_order' => $section->section_order,
1802
- 'section_description' => $section->section_description
1803
- ) );
1804
-
1805
- if ( $section->items ) {
1806
- foreach ( $section->items as $item ) {
1807
- // duplicate item
1808
- if ( $force && $item->post_type === LP_QUIZ_CPT ) {
1809
- $item_id = learn_press_duplicate_quiz( $item->ID, array( 'post_status' => 'publish' ) );
1810
- } else {
1811
- $item_id = learn_press_duplicate_post( $item->ID, array( 'post_status' => 'publish' ) );
1812
- }
1813
- if ( $force ) {
1814
- $section_item_id = learn_press_course_insert_section_item( array(
1815
- 'section_id' => $new_section_id,
1816
- 'item_id' => $item_id,
1817
- 'item_order' => $item->item_order,
1818
- 'item_type' => $item->item_type
1819
- ) );
1820
- }
1821
- }
1822
- }
1823
- }
1824
-
1825
- return $new_course_id;
1826
- }
1827
- }
1828
- }
1829
- }
1830
-
1831
- }
1832
-
1833
- if ( !function_exists( 'learn_press_duplicate_question' ) ) {
1834
-
1835
- function learn_press_duplicate_question( $question_id = null, $quiz_id = null ) {
1836
- if ( !$question_id || !get_post( $question_id ) ) {
1837
- return new WP_Error( sprintf( __( 'Question id %s is not exists.', 'learnpress' ), $question_id ) );
1838
- }
1839
- if ( $quiz_id && !get_post( $quiz_id ) ) {
1840
- return new WP_Error( sprintf( __( 'Quiz id %s is not exists.', 'learnpress' ), $quiz_id ) );
1841
- }
1842
-
1843
- global $wpdb;
1844
- $new_question_id = learn_press_duplicate_post( $question_id );
1845
- if ( $quiz_id ) {
1846
- // learnpress_quiz_questions
1847
- $sql = $wpdb->prepare( "
1848
- SELECT * FROM $wpdb->learnpress_quiz_questions WHERE quiz_id = %d AND question_id = %d
1849
- ", $quiz_id, $question_id );
1850
- $quiz_question_data = $wpdb->get_row( $sql );
1851
- $max_order = $wpdb->get_var( $wpdb->prepare( "SELECT max(question_order) FROM {$wpdb->prefix}learnpress_quiz_questions WHERE quiz_id = %d", $quiz_id ) );
1852
-
1853
- if ( $quiz_question_data ) {
1854
- $wpdb->insert(
1855
- $wpdb->learnpress_quiz_questions,
1856
- array(
1857
- 'quiz_id' => $quiz_id,
1858
- 'question_id' => $new_question_id,
1859
- 'question_order' => $max_order + 1,
1860
- 'params' => $quiz_question_data->params
1861
- ),
1862
- array(
1863
- '%d',
1864
- '%d',
1865
- '%d',
1866
- '%s'
1867
- )
1868
- );
1869
- }
1870
- }
1871
- // learnpress_question_answers
1872
- $sql = $wpdb->prepare( "
1873
- SELECT * FROM $wpdb->learnpress_question_answers WHERE question_id = %d
1874
- ", $question_id );
1875
- $question_answers = $wpdb->get_results( $sql );
1876
- if ( $question_answers ) {
1877
- foreach ( $question_answers as $q_a ) {
1878
- $wpdb->insert(
1879
- $wpdb->learnpress_question_answers,
1880
- array(
1881
- 'question_id' => $new_question_id,
1882
- 'answer_data' => $q_a->answer_data,
1883
- 'answer_order' => $q_a->answer_order
1884
- ),
1885
- array(
1886
- '%d',
1887
- '%s',
1888
- '%s'
1889
- )
1890
- );
1891
- }
1892
- }
1893
-
1894
- return $new_question_id;
1895
- }
1896
-
1897
- }
1898
-
1899
- if ( !function_exists( 'learn_press_duplicate_quiz' ) ) {
1900
-
1901
- function learn_press_duplicate_quiz( $quiz_id = null, $args = array() ) {
1902
- global $wpdb;
1903
- $new_quiz_id = learn_press_duplicate_post( $quiz_id, $args, true );
1904
- $quiz = LP_Quiz::get_quiz( $quiz_id );
1905
- $questions = $quiz->get_questions();
1906
- if ( $questions ) {
1907
- $questions = array_keys( $questions );
1908
- foreach ( $questions as $question_id ) {
1909
- $new_question_id = learn_press_duplicate_post( $question_id );
1910
- // learnpress_quiz_questions
1911
- $sql = $wpdb->prepare( "
1912
- SELECT * FROM $wpdb->learnpress_quiz_questions WHERE quiz_id = %d AND question_id = %d
1913
- ", $quiz_id, $question_id );
1914
- $quiz_question_data = $wpdb->get_row( $sql );
1915
- if ( $quiz_question_data ) {
1916
- $wpdb->insert(
1917
- $wpdb->learnpress_quiz_questions,
1918
- array(
1919
- 'quiz_id' => $new_quiz_id,
1920
- 'question_id' => $new_question_id,
1921
- 'question_order' => $quiz_question_data->question_order,
1922
- 'params' => $quiz_question_data->params
1923
- ),
1924
- array(
1925
- '%d',
1926
- '%d',
1927
- '%d',
1928
- '%s'
1929
- )
1930
- );
1931
- }
1932
- // learnpress_question_answers
1933
- $sql = $wpdb->prepare( "
1934
- SELECT * FROM $wpdb->learnpress_question_answers WHERE question_id = %d
1935
- ", $question_id );
1936
- $question_answers = $wpdb->get_results( $sql );
1937
- if ( $question_answers ) {
1938
- foreach ( $question_answers as $q_a ) {
1939
- $wpdb->insert(
1940
- $wpdb->learnpress_question_answers,
1941
- array(
1942
- 'question_id' => $new_question_id,
1943
- 'answer_data' => $q_a->answer_data,
1944
- 'answer_order' => $q_a->answer_order
1945
- ),
1946
- array(
1947
- '%d',
1948
- '%s',
1949
- '%s'
1950
- )
1951
- );
1952
- }
1953
- }
1954
- }
1955
- }
1956
-
1957
- return $new_quiz_id;
1958
- }
1959
-
1960
- }
1961
-
1962
- /**
1963
- * Get number version of a template file
1964
- *
1965
- * @param $file
1966
- *
1967
- * @return string
1968
- */
1969
- function learn_press_get_file_version( $file ) {
1970
- if ( !file_exists( $file ) ) {
1971
- return '';
1972
- }
1973
- $fp = fopen( $file, 'r' );
1974
- $file_data = fread( $fp, 8192 );
1975
- fclose( $fp );
1976
- $file_data = str_replace( "\r", "\n", $file_data );
1977
- $version = '';
1978
- if ( preg_match( '/^[ \t\/*#@]*' . preg_quote( '@version', '/' ) . '(.*)$/mi', $file_data, $match ) && $match[1] ) {
1979
- $version = _cleanup_header_comment( $match[1] );
1980
- }
1981
-
1982
- return $version;
1983
- }
1984
-
1985
- /**
1986
- * Get list of template files are overwritten in the theme
1987
- *
1988
- * @param bool $check
1989
- *
1990
- * @return array|bool
1991
- */
1992
- function learn_press_get_theme_templates( $check = false ) {
1993
- $template_folder = learn_press_template_path();
1994
- $template_path = LP_PLUGIN_PATH . '/templates/';
1995
- $template_dir = get_template_directory();
1996
- $stylesheet_dir = get_stylesheet_directory();
1997
- $t_folder = basename( $template_dir );
1998
- $s_folder = basename( $stylesheet_dir );
1999
-
2000
- $found_files = array( $t_folder => array(), $s_folder => array() );
2001
- $outdated_templates = false;
2002
-
2003
- $scanned_files = learn_press_scan_template_files( $template_path );
2004
- foreach ( $scanned_files as $file ) {
2005
- $theme_folder = '';
2006
-
2007
- if ( file_exists( $stylesheet_dir . '/' . $file ) ) {
2008
- $theme_file = $stylesheet_dir . '/' . $file;
2009
- $theme_folder = $s_folder;
2010
- } elseif ( file_exists( $stylesheet_dir . '/' . $template_folder . '/' . $file ) ) {
2011
- $theme_file = $stylesheet_dir . '/' . $template_folder . '/' . $file;
2012
- $theme_folder = $s_folder;
2013
- } elseif ( file_exists( $template_dir . '/' . $file ) ) {
2014
- $theme_file = $template_dir . '/' . $file;
2015
- $theme_folder = $t_folder;
2016
- } elseif ( file_exists( $template_dir . '/' . $template_folder . '/' . $file ) ) {
2017
- $theme_file = $template_dir . '/' . $template_folder . '/' . $file;
2018
- $theme_folder = $t_folder;
2019
- } else {
2020
- $theme_file = false;
2021
- }
2022
-
2023
- if ( !empty( $theme_file ) ) {
2024
- $core_version = learn_press_get_file_version( $template_path . $file );
2025
- $theme_version = learn_press_get_file_version( $theme_file );
2026
-
2027
- if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) {
2028
- if ( !$outdated_templates ) {
2029
- $outdated_templates = true;
2030
- }
2031
- $found_files[$theme_folder][] = array(
2032
- str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ),
2033
- $theme_version ? $theme_version : '-',
2034
- $core_version,
2035
- true
2036
- );
2037
- } else {
2038
- $found_files[$theme_folder][] = array(
2039
- str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ),
2040
- $theme_version ? $theme_version : '?',
2041
- $core_version ? $core_version : '?',
2042
- null
2043
- );
2044
- }
2045
- }
2046
- if ( $check && $outdated_templates ) {
2047
- return $outdated_templates;
2048
- }
2049
- }
2050
- if ( sizeof( $found_files ) > 1 ) {
2051
- $found_files = array_merge( $found_files[$t_folder], $found_files[$s_folder] );
2052
- } else {
2053
- $found_files = reset( $found_files );
2054
- }
2055
-
2056
- return $check ? $outdated_templates : $found_files;
2057
- }
2058
-
2059
- function learn_press_detect_outdated_template() {
2060
- $template_folder = learn_press_template_path();
2061
- $template_path = LP_PLUGIN_PATH . '/templates/';
2062
- $template_dir = get_template_directory();
2063
- $stylesheet_dir = get_stylesheet_directory();
2064
- $scanned_files = learn_press_scan_template_files( $template_path );
2065
- $parent_item = 0;
2066
- $child_item = 0;
2067
-
2068
- foreach ( $scanned_files as $file ) {
2069
- $theme_file = false;
2070
- $cradle = '';
2071
-
2072
- if ( $stylesheet_dir == $template_dir ) { // Parent theme
2073
- if ( file_exists( $template_dir . '/' . $file ) ) {
2074
- $theme_file = $template_dir . '/' . $file;
2075
- $cradle = 'parent';
2076
- } elseif ( file_exists( $template_dir . '/' . $template_folder . '/' . $file ) ) {
2077
- $theme_file = $template_dir . '/' . $template_folder . '/' . $file;
2078
- $cradle = 'parent';
2079
- }
2080
- } else { // Child Theme
2081
- if ( file_exists( $stylesheet_dir . '/' . $file ) ) {
2082
- $theme_file = $stylesheet_dir . '/' . $file;
2083
- $cradle = 'child';
2084
- } elseif ( file_exists( $stylesheet_dir . '/' . $template_folder . '/' . $file ) ) {
2085
- $theme_file = $stylesheet_dir . '/' . $template_folder . '/' . $file;
2086
- $cradle = 'child';
2087
- } elseif ( file_exists( $template_dir . '/' . $file ) ) {
2088
- $theme_file = $template_dir . '/' . $file;
2089
- $cradle = 'parent';
2090
- } elseif ( file_exists( $template_dir . '/' . $template_folder . '/' . $file ) ) {
2091
- $theme_file = $template_dir . '/' . $template_folder . '/' . $file;
2092
- $cradle = 'parent';
2093
- }
2094
- }
2095
-
2096
- if ( !empty( $theme_file ) ) {
2097
- $core_version = learn_press_get_file_version( $template_path . $file );
2098
- $theme_version = learn_press_get_file_version( $theme_file );
2099
-
2100
- if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) {
2101
- if ( $cradle == 'parent' ) {
2102
- $parent_item ++;
2103
- } else {
2104
- $child_item ++;
2105
- }
2106
- }
2107
- }
2108
- }
2109
- if ( !empty( $child_item ) || !empty( $parent_item ) ) {
2110
-
2111
- return array(
2112
- 'parent_item' => $parent_item,
2113
- 'child_item' => $child_item
2114
- );
2115
- }
2116
-
2117
- return false;
2118
- }
2119
-
2120
- function learn_press_scan_template_files( $template_path ) {
2121
-
2122
- $files = @scandir( $template_path );
2123
- $result = array();
2124
-
2125
- if ( !empty( $files ) ) {
2126
- foreach ( $files as $key => $value ) {
2127
- if ( !in_array( $value, array( ".", "..", 'index.php', 'index.html' ) ) ) {
2128
- if ( is_dir( $template_path . '/' . $value ) ) {
2129
- $sub_files = learn_press_scan_template_files( $template_path . '/' . $value );
2130
- foreach ( $sub_files as $sub_file ) {
2131
- $result[] = $value . '/' . $sub_file;
2132
- }
2133
- } else {
2134
- $result[] = $value;
2135
- }
2136
- }
2137
- }
2138
- }
2139
-
2140
- return $result;
2141
- }
2142
-
2143
- if ( !function_exists( 'learn_press_duplicate_lesson' ) ) {
2144
-
2145
- function learn_press_duplicate_lesson( $lesson_id = null ) {
2146
- return learn_press_duplicate_post( $lesson_id );
2147
- }
2148
-
2149
- }
2150
-
2151
- function learn_press_get_default_section( $section = null ) {
2152
- if ( !$section ) {
2153
- $section = new stdClass();
2154
- }
2155
- foreach ( array(
2156
- 'section_id' => null,
2157
- 'section_name' => '',
2158
- 'section_course_id' => null,
2159
- 'section_order' => null,
2160
- 'section_description' => ''
2161
- ) as $k => $v ) {
2162
- if ( !property_exists( $section, $k ) ) {
2163
- $section->{$k} = $v;
2164
- }
2165
- }
2166
- return $section;
2167
- }
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_detect_outdated_template() {
2005
+ $template_folder = learn_press_template_path();
2006
+ $template_path = LP_PLUGIN_PATH . '/templates/';
2007
+ $template_dir = get_template_directory();
2008
+ $stylesheet_dir = get_stylesheet_directory();
2009
+ $scanned_files = learn_press_scan_template_files( $template_path );
2010
+ $parent_item = 0;
2011
+ $child_item = 0;
2012
+
2013
+ foreach ( $scanned_files as $file ) {
2014
+ $theme_file = false;
2015
+ $cradle = '';
2016
+
2017
+ if ( $stylesheet_dir == $template_dir ) { // Parent theme
2018
+ if ( file_exists( $template_dir . '/' . $file ) ) {
2019
+ $theme_file = $template_dir . '/' . $file;
2020
+ $cradle = 'parent';
2021
+ }
2022
+ elseif ( file_exists( $template_dir . '/' . $template_folder . '/' . $file ) ) {
2023
+ $theme_file = $template_dir . '/' . $template_folder . '/' . $file;
2024
+ $cradle = 'parent';
2025
+ }
2026
+ }
2027
+ else { // Child Theme
2028
+ if ( file_exists( $stylesheet_dir . '/' . $file ) ) {
2029
+ $theme_file = $stylesheet_dir . '/' . $file;
2030
+ $cradle = 'child';
2031
+ }
2032
+ elseif ( file_exists( $stylesheet_dir . '/' . $template_folder . '/' . $file ) ) {
2033
+ $theme_file = $stylesheet_dir . '/' . $template_folder . '/' . $file;
2034
+ $cradle = 'child';
2035
+ }
2036
+ elseif ( file_exists( $template_dir . '/' . $file ) ) {
2037
+ $theme_file = $template_dir . '/' . $file;
2038
+ $cradle = 'parent';
2039
+ }
2040
+ elseif ( file_exists( $template_dir . '/' . $template_folder . '/' . $file ) ) {
2041
+ $theme_file = $template_dir . '/' . $template_folder . '/' . $file;
2042
+ $cradle = 'parent';
2043
+ }
2044
+ }
2045
+
2046
+ if ( !empty( $theme_file ) ) {
2047
+ $core_version = learn_press_get_file_version( $template_path . $file );
2048
+ $theme_version = learn_press_get_file_version( $theme_file );
2049
+
2050
+ if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) {
2051
+ if ( $cradle == 'parent' ) {
2052
+ $parent_item ++;
2053
+ }
2054
+ else {
2055
+ $child_item ++;
2056
+ }
2057
+ }
2058
+ }
2059
+ }
2060
+ if ( !empty( $child_item ) || !empty( $parent_item ) ) {
2061
+
2062
+ return array(
2063
+ 'parent_item' => $parent_item,
2064
+ 'child_item' => $child_item
2065
+ );
2066
+ }
2067
+ return false;
2068
+ }
2069
+
2070
+ function learn_press_scan_template_files( $template_path ) {
2071
+
2072
+ $files = @scandir( $template_path );
2073
+ $result = array();
2074
+
2075
+ if ( !empty( $files ) ) {
2076
+ foreach ( $files as $key => $value ) {
2077
+ if ( !in_array( $value, array( ".", "..", 'index.php', 'index.html' ) ) ) {
2078
+ if ( is_dir( $template_path . '/' . $value ) ) {
2079
+ $sub_files = learn_press_scan_template_files( $template_path . '/' . $value );
2080
+ foreach ( $sub_files as $sub_file ) {
2081
+ $result[] = $value . '/' . $sub_file;
2082
+ }
2083
+ } else {
2084
+ $result[] = $value;
2085
+ }
2086
+ }
2087
+ }
2088
+ }
2089
+ return $result;
2090
+ }
2091
+
2092
+ if ( !function_exists( 'learn_press_duplicate_lesson' ) ) {
2093
+
2094
+ function learn_press_duplicate_lesson( $lesson_id = null ) {
2095
+ return learn_press_duplicate_post( $lesson_id );
2096
+ }
2097
+
2098
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/meta-boxes/class-course-tabs-field.php CHANGED
@@ -11,7 +11,7 @@ if ( !class_exists( 'RWMB_Course_Tabs_Field' ) ) {
11
  * @class RWMB_Course_lesson_Quiz_Field
12
  */
13
  class RWMB_Course_Tabs_Field extends RWMB_Field {
14
- public static function html( $meta, $field ) {
15
  ob_start();
16
  learn_press_admin_view( 'meta-boxes/course/tabs.php' );
17
  return ob_get_clean();
11
  * @class RWMB_Course_lesson_Quiz_Field
12
  */
13
  class RWMB_Course_Tabs_Field extends RWMB_Field {
14
+ public static function html() {
15
  ob_start();
16
  learn_press_admin_view( 'meta-boxes/course/tabs.php' );
17
  return ob_get_clean();
inc/admin/meta-boxes/class-curriculum-field.php ADDED
@@ -0,0 +1,316 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Prevent loading this file directly
3
+ defined( 'ABSPATH' ) || exit;
4
+
5
+ if ( !class_exists( 'RWMB_Curriculum_Field' ) ) {
6
+ /**
7
+ * Thim Theme
8
+ *
9
+ * Manage Course, Lesson, Quiz
10
+ *
11
+ * @class RWMB_Course_lesson_Quiz_Field
12
+ */
13
+ class RWMB_Curriculum_Field extends RWMB_Field {
14
+ /**
15
+ * Enqueue scripts and styles
16
+ *
17
+ * @return void
18
+ */
19
+ public static function admin_enqueue_scripts() {
20
+
21
+ LP_Assets::enqueue_script( 'learn-press-modal-search-items' );
22
+ LP_Assets::add_localize(
23
+ array(
24
+ 'confirm_remove_section_lesson' => __( 'Do you want to remove this lesson permanently?', 'learnpress' ),
25
+ 'confirm_remove_section_quiz' => __( 'Do you want to remove this quiz permanently?', 'learnpress' ),
26
+ 'confirm_remove_section' => __( 'Do you want to remove this section permanently?', 'learnpress' ),
27
+ 'add_new_quiz' => __( 'New quiz added', 'learnpress' ),
28
+ 'add_new_lesson' => __( 'New lesson added', 'learnpress' ),
29
+ 'add_new_section' => __( 'New section added', 'learnpress' ),
30
+ 'remove_section_lesson' => __( 'The lesson removed', 'learnpress' ),
31
+ 'remove_section_quiz' => __( 'The quiz removed', 'learnpress' ),
32
+ 'remove_section' => __( 'The section removed', 'learnpress' ),
33
+ 'section_ordered' => __( 'The ordering completed', 'learnpress' ),
34
+ 'add_lesson_to_section' => __( 'Lesson added to section completed!', 'learnpress' ),
35
+ 'add_quiz_to_section' => __( 'Quiz added to section completed!', 'learnpress' ),
36
+ 'update_lesson_quiz' => __( '%s updated', 'learnpress' ),
37
+ 'quick_edit_name' => __( 'Click to quick edit name', 'learnpress' ),
38
+ 'save_course' => __( 'Save Course', 'learnpress' ),
39
+ 'submit_course_review' => __( 'Submit for Review', 'learnpress' )
40
+ ), null, 'learn-press-mb-course'
41
+ );
42
+ }
43
+
44
+ /**
45
+ * Get field HTML
46
+ *
47
+ * @param mixed $meta
48
+ * @param array $field
49
+ *
50
+ * @return string
51
+ */
52
+ public static function html( $meta, $field ) {
53
+ global $post;
54
+ $course = LP_Course::get_course( $post );
55
+ $view = learn_press_get_admin_view( 'meta-boxes/course/curriculum.php' );
56
+ ob_start();
57
+ include $view;
58
+ return ob_get_clean();
59
+ }
60
+
61
+ /**
62
+ * Normalize parameters for field
63
+ *
64
+ * @param array $field
65
+ *
66
+ * @return array
67
+ */
68
+ public static function normalize_field( $field ) {
69
+ $field = wp_parse_args( $field, array(
70
+ 'size' => 30,
71
+ 'datalist' => false,
72
+ 'placeholder' => '',
73
+ ) );
74
+
75
+ return $field;
76
+ }
77
+
78
+ /**
79
+ * Create datalist, if any
80
+ *
81
+ * @param array $field
82
+ *
83
+ * @return array
84
+ */
85
+ public static function datalist_html( $field ) {
86
+ if ( !$field['datalist'] ) {
87
+ return '';
88
+ }
89
+
90
+ $datalist = $field['datalist'];
91
+ $html = sprintf(
92
+ '<datalist id="%s">',
93
+ $datalist['id']
94
+ );
95
+
96
+ foreach ( $datalist['options'] as $option ) {
97
+ $html .= sprintf( '<option value="%s"></option>', $option );
98
+ }
99
+
100
+ $html .= '</datalist>';
101
+
102
+ return $html;
103
+ }
104
+
105
+ /**
106
+ * Save meta value
107
+ * If field is cloneable, value is saved as a single entry in DB
108
+ * Otherwise value is saved as multiple entries (for backward compatibility)
109
+ *
110
+ * TODO: A good way to ALWAYS save values in single entry in DB, while maintaining backward compatibility
111
+ *
112
+ * @param $new
113
+ * @param $old
114
+ * @param $post_id
115
+ * @param $field
116
+ */
117
+ public static function save( $new, $old, $post_id, $field ) {
118
+
119
+ if ( empty( $new ) ) {
120
+ delete_post_meta( $post_id, $field['id'] );
121
+ } else {
122
+ $new = array_values( $new );
123
+ for ( $n = count( $new ), $i = $n - 1; $i >= 0; $i -- ) {
124
+ if ( !$new[$i]['name'] ) unset( $new[$i] );
125
+ }
126
+ $new = array_values( $new );
127
+ update_post_meta( $post_id, $field['id'], $new );
128
+ }
129
+ }
130
+
131
+ public static function add_actions() {
132
+ // Do same actions as file field
133
+ parent::add_actions();
134
+
135
+ /*add_action( 'wp_ajax_lpr_quick_add', array( __CLASS__, 'quick_add' ) );
136
+ add_action( 'wp_ajax_lpr_update_course_curriculum', array( __CLASS__, 'update_course_curriculum' ) );
137
+ add_action( 'wp_ajax_lpr_quick_edit_lesson_quiz_name', array( __CLASS__, 'quick_edit_lesson_quiz_name' ) );
138
+ add_action( 'wp_ajax_lpr_update_section_state', array( __CLASS__, 'update_section_state' ) );
139
+ add_action( 'wp_ajax_lpr_remove_lesson_quiz', array( __CLASS__, 'remove_lesson_quiz' ) );*/
140
+
141
+ ///add_action( 'save_post', array( __CLASS__, 'update_course_curriculum' ) );
142
+ add_filter( 'learn_press_loop_section_buttons', array( __CLASS__, 'add_section_buttons' ) );
143
+ //add_filter( 'learn_press_after_section_content', array( __CLASS__, 'section_options' ) );
144
+ }
145
+
146
+ public static function add_section_buttons( $buttons ) {
147
+ $buttons = array_merge(
148
+ $buttons,
149
+ array(
150
+ array(
151
+ 'id' => 'add-lesson',
152
+ 'text' => __( 'Add Lesson', 'learnpress' ),
153
+ 'attr' => 'data-action="add-lesson" data-type="lp_lesson"'
154
+ ),
155
+ array(
156
+ 'id' => 'add-quiz',
157
+ 'text' => __( 'Add Quiz', 'learnpress' ),
158
+ 'attr' => 'data-action="add-quiz" data-type="lp_quiz"'
159
+ )
160
+ )
161
+ );
162
+ return $buttons;
163
+ }
164
+
165
+ public static function section_options() {
166
+ ?>
167
+ <table class="form-table">
168
+ <tr>
169
+ <th>
170
+ <?php _e( 'Using final quiz', 'learnpress' ); ?>
171
+ </th>
172
+ <td>
173
+ <input type="checkbox" />
174
+
175
+ <p class="description"><?php _e( 'User must be complete the final quiz to finish a section.', 'learnpress' ); ?></p>
176
+
177
+ </td>
178
+ </tr>
179
+ </table>
180
+ <?php
181
+ }
182
+
183
+ public static function remove_lesson_quiz() {
184
+ $lesson_quiz_id = $_POST['lesson_quiz_id'];
185
+ delete_post_meta( $lesson_quiz_id, '_lpr_course' );
186
+ update_post_meta( $lesson_quiz_id, '_lpr_course', 0 );
187
+ }
188
+
189
+ public static function update_section_state() {
190
+ $post_id = $_POST['post_id'];
191
+ $section = $_POST['section'];
192
+ update_post_meta( $post_id, '_lpr_course_section_state', $section );
193
+ die();
194
+ }
195
+
196
+ public static function quick_add() {
197
+ //ob_end_flush();
198
+ echo '__LP_JSON__';
199
+ $name = isset( $_POST['name'] ) ? $_POST['name'] : null;
200
+ $type = isset( $_POST['type'] ) ? $_POST['type'] : null;
201
+ $course_id = isset( $_POST['course_id'] ) ? $_POST['course_id'] : null;
202
+ $post = false;
203
+ if ( $name && $type ) {
204
+ $post_id = wp_insert_post(
205
+ array(
206
+ 'post_title' => $name,
207
+ 'post_type' => $type == 'lesson' ? LP_LESSON_CPT : LP_QUIZ_CPT,
208
+ 'post_status' => 'publish'
209
+ )
210
+ );
211
+ if ( $post_id ) {
212
+ $post = get_post( $post_id );
213
+ if ( $course_id ) {
214
+ update_post_meta( $post_id, '_lpr_course', $course_id );
215
+ }
216
+ }
217
+ }
218
+ wp_send_json( $post );
219
+ die();
220
+ }
221
+
222
+ public static function quick_edit_lesson_quiz_name() {
223
+ $id = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : 0;
224
+ echo '__LP_JSON__';
225
+ if ( $id ) {
226
+ $name = $_POST['name'];
227
+ $slug = sanitize_title( $name );
228
+ $post_id = wp_update_post(
229
+ array(
230
+ 'ID' => $id,
231
+ 'post_title' => $name,
232
+ 'post_name' => $slug
233
+ )
234
+ );
235
+ if ( $post_id ) {
236
+ wp_send_json( get_post( $post_id ) );
237
+ }
238
+ }
239
+
240
+ }
241
+
242
+ public static function update_course_curriculum() {
243
+
244
+ $is_ajax = false;
245
+ if ( !empty( $_REQUEST['action'] ) && 'lpr_update_course_curriculum' == $_REQUEST['action'] ) {
246
+ $course_id = isset( $_POST['course_id'] ) ? intval( $_POST['course_id'] ) : 0;
247
+ $is_ajax = true;
248
+ } else {
249
+ if ( LP_COURSE_CPT != get_post_type() ) return;
250
+ global $post;
251
+ $course_id = $post->ID;
252
+ }
253
+ $meta_key = isset( $_POST['meta_key'] ) ? $_POST['meta_key'] : '_lpr_course_lesson_quiz';
254
+ $metadata = isset( $_POST['_lpr_course_lesson_quiz'] ) ? $_POST['_lpr_course_lesson_quiz'] : false;
255
+ if ( !$course_id ) {
256
+ echo '__LP_JSON__';
257
+ wp_send_json(
258
+ array(
259
+ 'message' => __( 'The course is empty', 'learnpress' )
260
+ )
261
+ );
262
+ }
263
+
264
+ $metadata = apply_filters( 'learn_press_course_curriculum', $metadata, $course_id );
265
+ update_post_meta( $course_id, $meta_key, $metadata );
266
+ do_action( 'learn_press_update_course_curriculum', $course_id, $metadata );
267
+
268
+ //
269
+ global $wpdb;
270
+ if ( $metadata ) foreach ( $metadata as $section ) {
271
+ if ( !empty( $section['lesson_quiz'] ) && $lesson_quiz = $section['lesson_quiz'] ) {
272
+ $query = $wpdb->prepare( "
273
+ DELETE FROM {$wpdb->postmeta}
274
+ WHERE meta_key = %s
275
+ AND ( meta_value = %d OR meta_value = %d OR meta_value = %s )
276
+ AND post_id IN(" . join( ',', $lesson_quiz ) . ")
277
+ ", '_lpr_course', $course_id, 0, '' );
278
+
279
+ $wpdb->query( $query );
280
+
281
+ $query = "INSERT INTO {$wpdb->postmeta}(`post_id`, `meta_key`, `meta_value`) VALUES";
282
+ $query_values = array();
283
+ foreach ( $lesson_quiz as $id ) {
284
+ $query_values[] = $wpdb->prepare( "(%d, %s, %d)", $id, '_lpr_course', $course_id );
285
+ }
286
+ $query .= join( ",", $query_values );
287
+ $wpdb->query( $query );
288
+ }
289
+ }
290
+ if ( !$is_ajax ) return;
291
+ wp_send_json(
292
+ array(
293
+ 'message' => __( 'Success', 'learnpress' )
294
+ )
295
+ );
296
+ }
297
+
298
+ public static function meta( $post_id, $saved, $field ) {
299
+ $meta = get_post_meta( $post_id, $field['id'], true );
300
+
301
+ // Use $field['std'] only when the meta box hasn't been saved (i.e. the first time we run)
302
+ $meta = ( !$saved && '' === $meta || array() === $meta ) ? $field['std'] : $meta;
303
+
304
+ // Escape attributes for non-wysiwyg fields
305
+ if ( 'wysiwyg' !== $field['type'] ) {
306
+ //$meta = is_array( $meta ) ? array_map( 'esc_attr', $meta ) : esc_attr( $meta );
307
+ }
308
+
309
+ return $meta;
310
+ }
311
+
312
+ public static function cleanHeader() {
313
+
314
+ }
315
+ }
316
+ }
inc/admin/meta-boxes/class-meta-box-tabs.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Prevent loading this file directly
3
+ defined( 'ABSPATH' ) || exit;
4
+
5
+ if ( !class_exists( 'RWMB_Meta_Box_Tabs_Field' ) ) {
6
+ /**
7
+ * Thim Theme
8
+ *
9
+ * Manage Course, Lesson, Quiz
10
+ *
11
+ * @class RWMB_Course_lesson_Quiz_Field
12
+ */
13
+ class RWMB_Meta_Box_Tabs_Field extends RWMB_Field {
14
+ public static function html() {
15
+ echo 'xxxxxxxxxxxxxx';
16
+ }
17
+ }
18
+ }
inc/admin/meta-boxes/class-quiz-questions-field.php CHANGED
@@ -1,194 +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
- }
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
  }
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,81 +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' => __( '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();
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-courses.php CHANGED
@@ -1,204 +1,176 @@
1
- <?php
2
-
3
- /**
4
- * Class LP_Settings_Courses
5
- */
6
- class LP_Settings_Courses extends LP_Settings_Base {
7
- public function __construct() {
8
- $this->id = 'courses';
9
- $this->text = __( 'Courses', 'learnpress' );
10
-
11
- parent::__construct();
12
- }
13
-
14
- public function _get_sections() {
15
- $sections = array(
16
- 'general' => array(
17
- 'id' => 'general',
18
- 'title' => __( 'General', 'learnpress' )
19
- )
20
- );
21
-
22
- return $sections = apply_filters( 'learn_press_settings_sections_' . $this->id, $sections );
23
- }
24
-
25
- public function save() {
26
- parent::save();
27
- $course_permalink = $_POST['learn_press_course_base'];
28
- if ( $course_permalink == 'custom' ) {
29
- $course_permalink = trim( $_POST['course_permalink_structure'], '/' );
30
-
31
- if ( '%course_category%' == $course_permalink ) {
32
- $course_permalink = _x( 'courses', 'slug', 'learnpress' ) . '/' . $course_permalink;
33
- }
34
-
35
- $course_permalink = '/' . $course_permalink;
36
- update_option( 'learn_press_course_base_type', 'custom' );
37
-
38
- } else {
39
- delete_option( 'learn_press_course_base_type' );
40
- }
41
-
42
- $course_base = untrailingslashit( $course_permalink );
43
-
44
- update_option( 'learn_press_course_base', $course_base );
45
-
46
- $courses_page_id = learn_press_get_page_id( 'courses' );
47
- $courses_permalink = ( $courses_page_id > 0 && get_post( $courses_page_id ) ) ? get_page_uri( $courses_page_id ) : _x( 'courses', 'default-slug', 'learnpress' );
48
-
49
- if ( $courses_page_id && trim( $course_base, '/' ) === $courses_permalink ) {
50
- update_option( 'learn_press_use_verbose_page_rules', 'yes' );
51
- } else {
52
- delete_option( 'learn_press_use_verbose_page_rules' );
53
- }
54
- }
55
-
56
- public function output() {
57
- $view = learn_press_get_admin_view( 'settings/courses.php' );
58
- require_once $view;
59
- }
60
-
61
- public function get_settings() {
62
-
63
- $generate_course_thumbnail = get_option( 'learn_press_generate_course_thumbnail' ) ? get_option( 'learn_press_generate_course_thumbnail' ) : 'no';
64
-
65
- return apply_filters(
66
- 'learn_press_courses_settings',
67
- array(
68
- array(
69
- 'title' => __( 'Courses Page', 'learnpress' ),
70
- 'id' => $this->get_field_name( 'courses_page_id' ),
71
- 'default' => '',
72
- 'type' => 'pages-dropdown'
73
- ),
74
- array(
75
- 'title' => __( 'Course category base', 'learnpress' ),
76
- 'id' => $this->get_field_name( 'course_category_base' ),
77
- 'default' => 'course-category',
78
- 'type' => 'text'
79
- ),
80
- array(
81
- 'title' => __( 'Course tag base', 'learnpress' ),
82
- 'id' => $this->get_field_name( 'course_tag_base' ),
83
- 'default' => 'course-tag',
84
- 'type' => 'text'
85
- ),
86
- array(
87
- 'title' => __( 'Review course before publish', 'learnpress' ),
88
- 'desc' => __( 'The course needs to be reviewed by admin before it can be published.', 'learnpress' ),
89
- 'id' => $this->get_field_name( 'required_review' ),
90
- 'default' => 'yes',
91
- 'type' => 'checkbox'
92
- ),
93
- array(
94
- 'title' => __( 'Enable edit published course', 'learnpress' ),
95
- 'desc' => __( 'Allow instructors to edit the course that are published without review.<br /> If this option is disabled, the course status will be changed to Pending Review when the instructor update course.', 'learnpress' ),
96
- 'id' => $this->get_field_name( 'enable_edit_published' ),
97
- 'default' => 'yes',
98
- 'type' => 'checkbox'
99
- ),
100
- // Removed from 2.1.4
101
- /*array(
102
- 'title' => __( 'Show list of question in quiz', 'learnpress' ),
103
- 'desc' => __( 'Show/Hide list questions in quiz.', 'learnpress' ),
104
- 'id' => $this->get_field_name( 'disable_question_in_quiz' ),
105
- 'default' => 'yes',
106
- 'type' => 'checkbox'
107
- ),*/
108
- /* Temporary remove from 2.1.4
109
- array(
110
- 'title' => __( 'Auto redirect next lesson', 'learnpress' ),
111
- 'desc' => __( 'Redirect to the next lesson after completed the lesson', 'learnpress' ),
112
- 'id' => $this->get_field_name( 'auto_redirect_next_lesson' ),
113
- 'default' => 'no',
114
- 'type' => 'checkbox'
115
- ),
116
- array(
117
- 'title' => __( 'Time delay redirect', 'learnpress' ),
118
- 'desc' => __( 'The item will be redirected after certain amount of time, unit: seconds (s)', 'learnpress' ),
119
- 'id' => $this->get_field_name( 'auto_redirect_time' ),
120
- 'default' => '3',
121
- 'type' => 'number',
122
- 'custom_attributes' => array(
123
- 'min' => '0'
124
- )
125
- ),
126
- array(
127
- 'title' => __( 'Auto redirect message ', 'learnpress' ),
128
- 'desc' => '',
129
- 'id' => $this->get_field_name( 'auto_redirect_message' ),
130
- 'default' => 'Redirecting to the next item ... ',
131
- 'type' => 'text'
132
- ),*/
133
- array(
134
- 'title' => __( 'Archive', 'learnpress' ),
135
- 'type' => 'title'
136
- ),
137
- array(
138
- 'title' => __( 'Courses limit', 'learnpress' ),
139
- 'desc' => __( 'Number of courses displayed per page.', 'learnpress' ),
140
- 'id' => $this->get_field_name( 'archive_course_limit' ),
141
- 'default' => '10',
142
- 'type' => 'number',
143
- 'custom_attributes' => array(
144
- 'min' => '1'
145
- )
146
- ),
147
- array(
148
- 'title' => __( 'Course thumbnail', 'learnpress' ),
149
- 'type' => 'title'
150
- ),
151
- array(
152
- 'title' => __( 'Extra thumbnail', 'learnpress' ),
153
- 'id' => $this->get_field_name( 'generate_course_thumbnail' ),
154
- 'default' => 'yes',
155
- 'type' => 'checkbox',
156
- 'desc' => __( 'Turn on/off courses extra thumbnail', 'learnpress' ),
157
- ),
158
- array(
159
- 'title' => __( 'Single course', 'learnpress' ),
160
- 'id' => $this->get_field_name( 'single_course_image_size' ),
161
- 'default' => array( 800, 450, 'yes' ),
162
- 'type' => 'image-size',
163
- 'class' => 'single-course-thumbnail' . ( ( $generate_course_thumbnail == 'no' ) ? ' hide-if-js' : '' )
164
- ),
165
- array(
166
- 'title' => __( 'Courses page', 'learnpress' ),
167
- 'id' => $this->get_field_name( 'course_thumbnail_image_size' ),
168
- 'default' => array( 400, 250, 'yes' ),
169
- 'type' => 'image-size',
170
- 'class' => 'archive-course-thumbnail' . ( ( $generate_course_thumbnail == 'no' ) ? ' hide-if-js' : '' )
171
- ),
172
- array(
173
- 'title' => __( 'Single course permalink', 'learnpress' ),
174
- 'type' => 'title'
175
- ),
176
- array(
177
- 'title' => __( 'Single course permalink', 'learnpress' ),
178
- 'type' => 'course-permalink',
179
- 'default' => ''
180
- ),
181
- array(
182
- 'title' => __( 'Course item slug', 'learnpress' ),
183
- 'type' => 'title'
184
- ),
185
- array(
186
- 'title' => __( 'Lesson', 'learnpress' ),
187
- 'type' => 'text',
188
- 'id' => $this->get_field_name( 'lesson_slug' ),
189
- 'desc' => __( sprintf( '%s/course/sample-course/<code>lessons</code>/sample-lesson/', home_url() ), 'learnpress' ),
190
- 'default' => 'lessons'
191
- ),
192
- array(
193
- 'title' => __( 'Quiz', 'learnpress' ),
194
- 'type' => 'text',
195
- 'id' => $this->get_field_name( 'quiz_slug' ),
196
- 'desc' => __( sprintf( '%s/course/sample-course/<code>quizzes</code>/sample-lesson/', home_url() ), 'learnpress' ),
197
- 'default' => 'quizzes'
198
- )
199
- )
200
- );
201
- }
202
- }
203
-
204
  return new LP_Settings_Courses();
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Settings_Courses
5
+ */
6
+ class LP_Settings_Courses extends LP_Settings_Base {
7
+ public function __construct() {
8
+ $this->id = 'courses';
9
+ $this->text = __( 'Courses', 'learnpress' );
10
+
11
+ parent::__construct();
12
+ }
13
+
14
+ public function _get_sections() {
15
+ $sections = array(
16
+ 'general' => array(
17
+ 'id' => 'general',
18
+ 'title' => __( 'General', 'learnpress' )
19
+ )
20
+ );
21
+ return $sections = apply_filters( 'learn_press_settings_sections_' . $this->id, $sections );
22
+ }
23
+
24
+ public function save() {
25
+ parent::save();
26
+ $course_permalink = $_POST['learn_press_course_base'];
27
+ update_option( 'learn_press_course_base_type', $course_permalink );
28
+ if ( $course_permalink == 'custom' ) {
29
+ $course_permalink = trim( $_POST['course_permalink_structure'], '/' );
30
+
31
+ if ( '%course_category%' == $course_permalink ) {
32
+ $course_permalink = _x( 'courses', 'slug', 'learnpress' ) . '/' . $course_permalink;
33
+ }
34
+
35
+ $course_permalink = '/' . $course_permalink;
36
+ } elseif ( empty( $course_permalink ) ) {
37
+ $course_permalink = false;
38
+ }
39
+
40
+ $course_base = untrailingslashit( $course_permalink );
41
+
42
+ update_option( 'learn_press_course_base', $course_base );
43
+
44
+ $courses_page_id = learn_press_get_page_id( 'courses' );
45
+ $courses_permalink = ( $courses_page_id > 0 && get_post( $courses_page_id ) ) ? get_page_uri( $courses_page_id ) : _x( 'courses', 'default-slug', 'learnpress' );
46
+
47
+ if ( $courses_page_id && trim( $course_base, '/' ) === $courses_permalink ) {
48
+ update_option( 'learn_press_use_verbose_page_rules', 'yes' );
49
+ } else {
50
+ delete_option( 'learn_press_use_verbose_page_rules' );
51
+ }
52
+ }
53
+
54
+ public function output() {
55
+ $view = learn_press_get_admin_view( 'settings/courses.php' );
56
+ require_once $view;
57
+ }
58
+
59
+ public function get_settings() {
60
+
61
+ $generate_course_thumbnail = get_option( 'learn_press_generate_course_thumbnail' ) ? get_option( 'learn_press_generate_course_thumbnail' ) : 'no';
62
+
63
+ return apply_filters(
64
+ 'learn_press_courses_settings',
65
+ array(
66
+ array(
67
+ 'title' => __( 'Courses Page', 'learnpress' ),
68
+ 'id' => $this->get_field_name( 'courses_page_id' ),
69
+ 'default' => '',
70
+ 'type' => 'pages-dropdown'
71
+ ),
72
+ array(
73
+ 'title' => __( 'Course category base', 'learnpress' ),
74
+ 'id' => $this->get_field_name( 'course_category_base' ),
75
+ 'default' => 'course-category',
76
+ 'type' => 'text'
77
+ ),
78
+ array(
79
+ 'title' => __( 'Course tag base', 'learnpress' ),
80
+ 'id' => $this->get_field_name( 'course_tag_base' ),
81
+ 'default' => 'course-tag',
82
+ 'type' => 'text'
83
+ ),
84
+ array(
85
+ 'title' => __( 'Review course before publish', 'learnpress' ),
86
+ 'desc' => __( 'The course needs to be reviewed by admin before it can be published.', 'learnpress' ),
87
+ 'id' => $this->get_field_name( 'required_review' ),
88
+ 'default' => 'yes',
89
+ 'type' => 'checkbox'
90
+ ),
91
+ array(
92
+ 'title' => __( 'Enable edit published course', 'learnpress' ),
93
+ 'desc' => __( 'Allow instructors to edit the course that are published without review.<br /> If this option is disabled, the course status will be changed to Pending Review when the instructor update course.', 'learnpress' ),
94
+ 'id' => $this->get_field_name( 'enable_edit_published' ),
95
+ 'default' => 'yes',
96
+ 'type' => 'checkbox'
97
+ ),
98
+ array(
99
+ 'title' => __( 'Show list of question in quiz', 'learnpress' ),
100
+ 'desc' => __( 'Show/Hide list questions in quiz.', 'learnpress' ),
101
+ 'id' => $this->get_field_name( 'disable_question_in_quiz' ),
102
+ 'default' => 'yes',
103
+ 'type' => 'checkbox'
104
+ ),
105
+ array(
106
+ 'title' => __( 'Archive', 'learnpress' ),
107
+ 'type' => 'title'
108
+ ),
109
+ array(
110
+ 'title' => __( 'Courses limit', 'learnpress' ),
111
+ 'desc' => __( 'Number of courses displayed per page.', 'learnpress' ),
112
+ 'id' => $this->get_field_name( 'archive_course_limit' ),
113
+ 'default' => '10',
114
+ 'type' => 'number',
115
+ 'custom_attributes' => array(
116
+ 'min' => '1'
117
+ )
118
+ ),
119
+ array(
120
+ 'title' => __( 'Course thumbnail', 'learnpress' ),
121
+ 'type' => 'title'
122
+ ),
123
+ array(
124
+ 'title' => __( 'Extra thumbnail', 'learnpress' ),
125
+ 'id' => $this->get_field_name( 'generate_course_thumbnail' ),
126
+ 'default' => 'yes',
127
+ 'type' => 'checkbox',
128
+ 'desc' => __( 'Turn on/off courses extra thumbnail', 'learnpress' ),
129
+ ),
130
+ array(
131
+ 'title' => __( 'Single course', 'learnpress' ),
132
+ 'id' => $this->get_field_name( 'single_course_image_size' ),
133
+ 'default' => array( 800, 450, 'yes' ),
134
+ 'type' => 'image-size',
135
+ 'class' => 'single-course-thumbnail' . ( ( $generate_course_thumbnail == 'no' ) ? ' hide-if-js' : '' )
136
+ ),
137
+ array(
138
+ 'title' => __( 'Courses page', 'learnpress' ),
139
+ 'id' => $this->get_field_name( 'course_thumbnail_image_size' ),
140
+ 'default' => array( 400, 250, 'yes' ),
141
+ 'type' => 'image-size',
142
+ 'class' => 'archive-course-thumbnail' . ( ( $generate_course_thumbnail == 'no' ) ? ' hide-if-js' : '' )
143
+ ),
144
+ array(
145
+ 'title' => __( 'Single course permalink', 'learnpress' ),
146
+ 'type' => 'title'
147
+ ),
148
+ array(
149
+ 'title' => __( 'Single course permalink', 'learnpress' ),
150
+ 'type' => 'course-permalink',
151
+ 'default' => ''
152
+ ),
153
+ array(
154
+ 'title' => __( 'Course item slug', 'learnpress' ),
155
+ 'type' => 'title'
156
+ ),
157
+ array(
158
+ 'title' => __( 'Lesson', 'learnpress' ),
159
+ 'type' => 'text',
160
+ 'id' => $this->get_field_name( 'lesson_slug' ),
161
+ 'desc' => __( sprintf( '%s/course/sample-course/<code>lessons</code>/sample-lesson/', home_url() ), 'learnpress' ),
162
+ 'default' => 'lessons'
163
+ ),
164
+ array(
165
+ 'title' => __( 'Quiz', 'learnpress' ),
166
+ 'type' => 'text',
167
+ 'id' => $this->get_field_name( 'quiz_slug' ),
168
+ 'desc' => __( sprintf( '%s/course/sample-course/<code>quizzes</code>/sample-lesson/', home_url() ), 'learnpress' ),
169
+ 'default' => 'quizzes'
170
+ )
171
+ )
172
+ );
173
+ }
174
+ }
175
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  return new LP_Settings_Courses();
inc/admin/settings/class-lp-settings-emails.php CHANGED
@@ -7,7 +7,7 @@
7
  * @package LearnPress/Classes
8
  * @version 1.0
9
  */
10
- if ( ! defined( 'ABSPATH' ) ) {
11
  exit; // Exit if accessed directly
12
  }
13
 
@@ -20,7 +20,7 @@ class LP_Settings_Emails extends LP_Settings_Base {
20
  /**
21
  * Constructor
22
  */
23
- public function __construct () {
24
  $this->id = 'emails';
25
  $this->text = __( 'Emails', 'learnpress' );
26
  parent::__construct();
@@ -31,7 +31,7 @@ class LP_Settings_Emails extends LP_Settings_Base {
31
  *
32
  * @return mixed
33
  */
34
- public function get_sections () {
35
 
36
  $emails = LP_Emails::instance()->emails;
37
 
@@ -39,14 +39,13 @@ class LP_Settings_Emails extends LP_Settings_Base {
39
  'general' => array( 'id' => 'general', 'title' => __( 'General options', 'learnpress' ) )
40
  );
41
 
42
- if ( $emails ) {
43
  foreach ( $emails as $email ) {
44
- $sections[ $email->id ] = array(
45
  'id' => $email->id,
46
  'title' => $email->title
47
  );
48
  }
49
- }
50
 
51
  /* $sections = array(
52
  'general' => __( 'General options', 'learnpress' ),
@@ -56,14 +55,13 @@ class LP_Settings_Emails extends LP_Settings_Base {
56
  'enrolled_course' => __( 'Enrolled course', 'learnpress' ),
57
  'passed_course' => __( 'Passed course', 'learnpress' ),
58
  ); */
59
-
60
  return $sections = apply_filters( 'learn_press_settings_sections_' . $this->id, $sections );
61
  }
62
 
63
  /**
64
  * @param $default_message
65
  */
66
- public function message_editor ( $default_message ) {
67
  $settings = LP()->settings;
68
  $content = stripslashes( $settings->get( $this->section['id'] . '.message', $default_message ) );
69
  $editor_id = 'email_message';
@@ -76,100 +74,80 @@ class LP_Settings_Emails extends LP_Settings_Base {
76
  );
77
  }
78
 
79
- public function get_email_class ( $id ) {
80
  $emails = LP_Emails::instance()->emails;
81
- if ( $emails ) {
82
  foreach ( $emails as $email ) {
83
  if ( $email->id == $id ) {
84
  return $email;
85
  }
86
  }
87
- }
88
-
89
  return false;
90
  }
91
 
92
  /**
93
  *
94
  */
95
- public function output_section_general () {
96
  $view = learn_press_get_admin_view( 'settings/emails/general.php' );
97
  include_once $view;
98
  }
99
 
100
- public function output_section_new_course () {
101
  if ( $email = $this->get_email_class( 'new_course' ) ) {
102
  $email->admin_options( $this );
103
  }
104
  }
105
 
106
- public function output_section_user_order_completed () {
107
  if ( $email = $this->get_email_class( 'user_order_completed' ) ) {
108
  $email->admin_options( $this );
109
  }
110
  }
111
 
112
- public function output_section_user_order_changed_status () {
113
- if ( $email = $this->get_email_class( 'user_order_changed_status' ) ) {
114
- $email->admin_options( $this );
115
- }
116
- }
117
-
118
- public function output_section_rejected_course () {
119
  if ( $email = $this->get_email_class( 'rejected_course' ) ) {
120
  $email->admin_options( $this );
121
  }
122
  }
123
 
124
- public function output_section_new_order () {
125
  if ( $email = $this->get_email_class( 'new_order' ) ) {
126
  $email->admin_options( $this );
127
  }
128
  }
129
 
130
- public function output_section_new_order_customer () {
131
  if ( $email = $this->get_email_class( 'new_order_customer' ) ) {
132
  $email->admin_options( $this );
133
  }
134
  }
135
 
136
- public function output_section_published_course () {
137
  if ( $email = $this->get_email_class( 'published_course' ) ) {
138
  $email->admin_options( $this );
139
  }
140
  }
141
 
142
- public function output_section_enrolled_course () {
143
  if ( $email = $this->get_email_class( 'enrolled_course' ) ) {
144
  $email->admin_options( $this );
145
  }
146
  }
147
 
148
- public function output_section_enrolled_course_admin () {
149
- if ( $email = $this->get_email_class( 'enrolled_course_admin' ) ) {
150
- $email->admin_options( $this );
151
- }
152
- }
153
-
154
- public function output_section_finished_course () {
155
  if ( $email = $this->get_email_class( 'finished_course' ) ) {
156
  $email->admin_options( $this );
157
  }
158
  }
159
 
160
- public function output_section_update_course () {
161
- if ( $email = $this->get_email_class( 'update_course' ) ) {
162
- $email->admin_options( $this );
163
- }
164
- }
165
-
166
- public function output_section_become_an_instructor () {
167
  if ( $email = $this->get_email_class( 'become_an_instructor' ) ) {
168
  $email->admin_options( $this );
169
  }
170
  }
171
 
172
- public function get_settings () {
173
  return apply_filters(
174
  'learn_press_email_settings', array(
175
  array(
@@ -183,11 +161,10 @@ class LP_Settings_Emails extends LP_Settings_Base {
183
  );
184
  }
185
 
186
- public static function instance () {
187
- if ( ! self::$_instance ) {
188
  self::$_instance = new self();
189
  }
190
-
191
  return self::$_instance;
192
  }
193
  }
7
  * @package LearnPress/Classes
8
  * @version 1.0
9
  */
10
+ if ( !defined( 'ABSPATH' ) ) {
11
  exit; // Exit if accessed directly
12
  }
13
 
20
  /**
21
  * Constructor
22
  */
23
+ public function __construct() {
24
  $this->id = 'emails';
25
  $this->text = __( 'Emails', 'learnpress' );
26
  parent::__construct();
31
  *
32
  * @return mixed
33
  */
34
+ public function get_sections() {
35
 
36
  $emails = LP_Emails::instance()->emails;
37
 
39
  'general' => array( 'id' => 'general', 'title' => __( 'General options', 'learnpress' ) )
40
  );
41
 
42
+ if ( $emails )
43
  foreach ( $emails as $email ) {
44
+ $sections[$email->id] = array(
45
  'id' => $email->id,
46
  'title' => $email->title
47
  );
48
  }
 
49
 
50
  /* $sections = array(
51
  'general' => __( 'General options', 'learnpress' ),
55
  'enrolled_course' => __( 'Enrolled course', 'learnpress' ),
56
  'passed_course' => __( 'Passed course', 'learnpress' ),
57
  ); */
 
58
  return $sections = apply_filters( 'learn_press_settings_sections_' . $this->id, $sections );
59
  }
60
 
61
  /**
62
  * @param $default_message
63
  */
64
+ public function message_editor( $default_message ) {
65
  $settings = LP()->settings;
66
  $content = stripslashes( $settings->get( $this->section['id'] . '.message', $default_message ) );
67
  $editor_id = 'email_message';
74
  );
75
  }
76
 
77
+ public function get_email_class( $id ) {
78
  $emails = LP_Emails::instance()->emails;
79
+ if ( $emails )
80
  foreach ( $emails as $email ) {
81
  if ( $email->id == $id ) {
82
  return $email;
83
  }
84
  }
 
 
85
  return false;
86
  }
87
 
88
  /**
89
  *
90
  */
91
+ public function output_section_general() {
92
  $view = learn_press_get_admin_view( 'settings/emails/general.php' );
93
  include_once $view;
94
  }
95
 
96
+ public function output_section_new_course() {
97
  if ( $email = $this->get_email_class( 'new_course' ) ) {
98
  $email->admin_options( $this );
99
  }
100
  }
101
 
102
+ public function output_section_user_order_completed() {
103
  if ( $email = $this->get_email_class( 'user_order_completed' ) ) {
104
  $email->admin_options( $this );
105
  }
106
  }
107
 
108
+ public function output_section_rejected_course() {
 
 
 
 
 
 
109
  if ( $email = $this->get_email_class( 'rejected_course' ) ) {
110
  $email->admin_options( $this );
111
  }
112
  }
113
 
114
+ public function output_section_new_order() {
115
  if ( $email = $this->get_email_class( 'new_order' ) ) {
116
  $email->admin_options( $this );
117
  }
118
  }
119
 
120
+ public function output_section_new_order_customer() {
121
  if ( $email = $this->get_email_class( 'new_order_customer' ) ) {
122
  $email->admin_options( $this );
123
  }
124
  }
125
 
126
+ public function output_section_published_course() {
127
  if ( $email = $this->get_email_class( 'published_course' ) ) {
128
  $email->admin_options( $this );
129
  }
130
  }
131
 
132
+ public function output_section_enrolled_course() {
133
  if ( $email = $this->get_email_class( 'enrolled_course' ) ) {
134
  $email->admin_options( $this );
135
  }
136
  }
137
 
138
+ public function output_section_finished_course() {
 
 
 
 
 
 
139
  if ( $email = $this->get_email_class( 'finished_course' ) ) {
140
  $email->admin_options( $this );
141
  }
142
  }
143
 
144
+ public function output_section_become_an_instructor() {
 
 
 
 
 
 
145
  if ( $email = $this->get_email_class( 'become_an_instructor' ) ) {
146
  $email->admin_options( $this );
147
  }
148
  }
149
 
150
+ public function get_settings() {
151
  return apply_filters(
152
  'learn_press_email_settings', array(
153
  array(
161
  );
162
  }
163
 
164
+ public static function instance() {
165
+ if ( !self::$_instance ) {
166
  self::$_instance = new self();
167
  }
 
168
  return self::$_instance;
169
  }
170
  }
inc/admin/settings/class-lp-settings-general.php CHANGED
@@ -1,135 +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' => __( '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
- array(
88
- 'title' => __( 'Logout', 'learnpress' ),
89
- 'type' => 'title'
90
- ),
91
- array(
92
- 'title' => __( 'Redirect to page', 'learnpress' ),
93
- 'id' => $this->get_field_name( 'logout_redirect_page_id' ),
94
- 'default' => '',
95
- 'type' => 'pages-dropdown'
96
- ),
97
- )
98
- );
99
- }
100
-
101
- private function _get_currency_options() {
102
- $currencies = array();
103
-
104
- if ( $payment_currencies = learn_press_get_payment_currencies() )
105
- foreach ( $payment_currencies as $code => $symbol ) {
106
- $currencies[$code] = $symbol;
107
- }
108
-
109
- return $currencies;
110
- }
111
-
112
- private function _get_currency_positions() {
113
- $positions = array();
114
- foreach ( learn_press_currency_positions() as $pos => $text ) {
115
- switch ( $pos ) {
116
- case 'left':
117
- $text = sprintf( '%s ( %s%s )', $text, learn_press_get_currency_symbol(), '69.99' );
118
- break;
119
- case 'right':
120
- $text = sprintf( '%s ( %s%s )', $text, '69.99', learn_press_get_currency_symbol() );
121
- break;
122
- case 'left_with_space':
123
- $text = sprintf( '%s ( %s %s )', $text, learn_press_get_currency_symbol(), '69.99' );
124
- break;
125
- case 'right_with_space':
126
- $text = sprintf( '%s ( %s %s )', $text, '69.99', learn_press_get_currency_symbol() );
127
- break;
128
- }
129
- $positions[$pos] = $text;
130
- }
131
- return $positions;
132
- }
133
- }
134
-
135
  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,213 +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' => __( '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
- ), $this
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();
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/sub-menus/settings.php CHANGED
@@ -54,7 +54,6 @@ function learn_press_settings_page() {
54
  <?php do_action( 'learn_press_settings_' . $current_tab ); ?>
55
  <p>
56
  <button class="button button-primary"><?php _e( 'Save settings', 'learnpress' ); ?></button>
57
- <a class="button" href="<?php echo wp_nonce_url( add_query_arg( 'reset', 'yes' ), 'learn-press-reset-settings' ); ?>" id="learn-press-reset-settings" data-text="<?php esc_attr_e( 'Do you want to restore all settings to default?', 'learnpress' ); ?>"><?php _e( 'Reset', 'learnpress' ); ?></a>
58
  </p>
59
  <?php wp_nonce_field( 'learn_press_settings', 'learn_press_settings_nonce' ); ?>
60
  </div>
@@ -86,16 +85,6 @@ function learn_press_admin_update_settings() {
86
  }
87
  }
88
 
89
- if ( learn_press_get_request( 'reset' ) == 'yes' && wp_verify_nonce( learn_press_get_request( '_wpnonce' ), 'learn-press-reset-settings' ) ) {
90
- global $wpdb;
91
- $sql = "
92
- DELETE FROM {$wpdb->options} WHERE option_name LIKE %s
93
- ";
94
- $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( 'learn_press_' ) . '%' ) );
95
- wp_redirect( remove_query_arg( array( 'reset', '_wpnonce' ) ) );
96
- exit();
97
- }
98
-
99
  if ( !empty( $_POST ) ) {
100
  // Check if our nonce is set.
101
  if ( !isset( $_POST['learn_press_settings_nonce'] ) ) {
54
  <?php do_action( 'learn_press_settings_' . $current_tab ); ?>
55
  <p>
56
  <button class="button button-primary"><?php _e( 'Save settings', 'learnpress' ); ?></button>
 
57
  </p>
58
  <?php wp_nonce_field( 'learn_press_settings', 'learn_press_settings_nonce' ); ?>
59
  </div>
85
  }
86
  }
87
 
 
 
 
 
 
 
 
 
 
 
88
  if ( !empty( $_POST ) ) {
89
  // Check if our nonce is set.
90
  if ( !isset( $_POST['learn_press_settings_nonce'] ) ) {
inc/admin/sub-menus/tools.php CHANGED
@@ -130,7 +130,7 @@ if ( !function_exists( 'learn_press_remove_data' ) ) {
130
  delete_option( 'learnpress_version' );
131
 
132
  LP_Admin_Notice::add( __( 'All courses, lessons, quizzes and questions have been removed', 'learnpress' ), 'updated', '', true );
133
- wp_redirect( admin_url( 'admin.php?page=learn-press-tools&learn-press-remove-data=1' ) );
134
  exit();
135
  }
136
  }
@@ -197,8 +197,8 @@ if ( !function_exists( 'learn_press_remove_old_data' ) ) {
197
 
198
  LP_Admin_Notice::add( __( 'Outdated data from version less than 1.0 have been removed', 'learnpress' ), 'updated', '', true );
199
  //flush_rewrite_rules();
200
- // header('Location: '.admin_url( 'admin.php?page=learn-press-tools' ));
201
- wp_redirect( admin_url( 'admin.php?page=learn-press-tools' ) );
202
  exit();
203
  }
204
  }
130
  delete_option( 'learnpress_version' );
131
 
132
  LP_Admin_Notice::add( __( 'All courses, lessons, quizzes and questions have been removed', 'learnpress' ), 'updated', '', true );
133
+ wp_redirect( admin_url( 'admin.php?page=learn_press_tools&learn-press-remove-data=1' ) );
134
  exit();
135
  }
136
  }
197
 
198
  LP_Admin_Notice::add( __( 'Outdated data from version less than 1.0 have been removed', 'learnpress' ), 'updated', '', true );
199
  //flush_rewrite_rules();
200
+ // header('Location: '.admin_url( 'admin.php?page=learn_press_tools' ));
201
+ wp_redirect( admin_url( 'admin.php?page=learn_press_tools' ) );
202
  exit();
203
  }
204
  }
inc/admin/views/html-admin-notice-templates.php CHANGED
@@ -1,39 +1,39 @@
1
- <?php
2
-
3
- if ( !defined( 'ABSPATH' ) ) {
4
- exit;
5
- }
6
-
7
- if ( learn_press_get_user_option( 'hide-notice-template-files' ) == 'yes' ) {
8
- return;
9
- }
10
- $template_dir = get_template_directory();
11
- $stylesheet_dir = get_stylesheet_directory();
12
- $cradle = learn_press_detect_outdated_template();
13
- $theme = wp_get_theme();
14
- $theme_name = array();
15
-
16
- if ( $template_dir === $stylesheet_dir ) {
17
- $theme_name[] = $theme['Name'];
18
- } else {
19
- if ( $cradle['parent_item'] ) {
20
- $theme_name[] = $parent = $theme->__get( 'parent_theme' );
21
- }
22
- if ( $cradle['child_item'] ) {
23
- $theme_name[] = $theme['Name'];
24
- }
25
- }
26
- $theme_name = implode( ' & ', $theme_name );
27
-
28
-
29
- ?>
30
- <div id="message" class="learn-press-message notice notice-warning">
31
- <p>
32
- <?php printf( __( 'Your theme <strong>(%s)</strong> contains outdated copies of some LearnPress template files.', 'learnpress' ), esc_html( $theme_name ) ); ?></p>
33
- <p>
34
- <?php _e( 'These files may need updating to ensure they are compatible with the current version of LearnPress. You can see which files are affected from the system status page. If in doubt, check with the author of the theme.', 'learnpress' ); ?></p>
35
- <p>
36
- <a class="button" href="<?php echo esc_url( admin_url( 'admin.php?page=learn-press-tools&tab=templates' ) ); ?>"><?php _e( 'View list of outdated templates', 'learnpress' ); ?></a>
37
- </p>
38
- <a href="<?php echo esc_url( add_query_arg( 'lp-hide-notice', 'template-files', learn_press_get_current_url() ) ); ?>" class="learn-press-admin-notice-dismiss"></a>
39
- </div>
1
+ <?php
2
+
3
+ if ( !defined( 'ABSPATH' ) ) {
4
+ exit;
5
+ }
6
+
7
+ if ( learn_press_get_user_option( 'hide-notice-template-files' ) == 'yes' ) {
8
+ return;
9
+ }
10
+ $template_dir = get_template_directory();
11
+ $stylesheet_dir = get_stylesheet_directory();
12
+ $cradle = learn_press_detect_outdated_template();
13
+ $theme = wp_get_theme();
14
+ $theme_name = array();
15
+
16
+ if ( $template_dir === $stylesheet_dir ) {
17
+ $theme_name[] = $theme['Name'];
18
+ } else {
19
+ if ( $cradle['parent_item'] ) {
20
+ $theme_name[] = $parent = $theme->__get( 'parent_theme' );
21
+ }
22
+ if ( $cradle['child_item'] ) {
23
+ $theme_name[] = $theme['Name'];
24
+ }
25
+ }
26
+ $theme_name = implode( ' & ', $theme_name );
27
+
28
+
29
+ ?>
30
+ <div id="message" class="learn-press-message notice notice-warning">
31
+ <p>
32
+ <?php printf( __( 'Your theme <strong>(%s)</strong> contains outdated copies of some LearnPress template files.', 'learnpress' ), esc_html( $theme_name ) ); ?></p>
33
+ <p>
34
+ <?php _e( 'These files may need updating to ensure they are compatible with the current version of LearnPress. You can see which files are affected from the system status page. If in doubt, check with the author of the theme.', 'learnpress' ); ?></p>
35
+ <p>
36
+ <a class="button" href="<?php echo esc_url( admin_url( 'admin.php?page=learn-press-tools&tab=templates' ) ); ?>"><?php _e( 'View list of outdated templates', 'learnpress' ); ?></a>
37
+ </p>
38
+ <a href="<?php echo esc_url( add_query_arg( 'lp-hide-notice', 'template-files', learn_press_get_current_url() ) ); ?>" class="learn-press-admin-notice-dismiss"></a>
39
+ </div>
inc/admin/views/meta-boxes/course/attributes.php CHANGED
@@ -33,6 +33,13 @@ $postId = $post ? $post->ID : 0;
33
  </ul>
34
 
35
  <button class="button button-primary" type="button" id="save-attributes"><?php _e( 'Save attributes', 'learnpres' ); ?></button>
 
 
 
 
 
 
 
36
  <?php
37
  } else {
38
  printf( '<p class="description">%s <a class="button button-primary" href="%s">%s</a></p>',
33
  </ul>
34
 
35
  <button class="button button-primary" type="button" id="save-attributes"><?php _e( 'Save attributes', 'learnpres' ); ?></button>
36
+ <script type="text/javascript">
37
+ jQuery(function($){
38
+ $.fn.select2.locales.en.formatNoMatches = function(){
39
+ return "xya";
40
+ }
41
+ })
42
+ </script>
43
  <?php
44
  } else {
45
  printf( '<p class="description">%s <a class="button button-primary" href="%s">%s</a></p>',
inc/admin/views/meta-boxes/course/curriculum.php CHANGED
@@ -4,41 +4,41 @@ $course_sections = $course->get_curriculum();
4
  $hidden_sections = (array) get_post_meta( $post->ID, '_admin_hidden_sections', true );
5
  ?>
6
  <div id="lp-course-curriculum" class="lp-course-curriculum">
7
- <h3 class="curriculum-heading">
8
- <?php _e( 'Curriculum', 'learnpress' ); ?>
9
- <span class="description"><?php _e( 'Outline your course and add content with sections, lessons and quizzes.', 'learnpress' ); ?></span>
10
 
11
- <p align="right" class="items-toggle">
12
- <a href="" data-action="expand" class="dashicons dashicons-arrow-down<?php echo !sizeof( $hidden_sections ) ? ' hide-if-js' : ''; ?>" title="<?php _e( 'Expand All', 'learnpress' ); ?>"></a>
13
- <a href="" data-action="collapse" class="dashicons dashicons-arrow-up<?php echo sizeof( $hidden_sections ) ? ' hide-if-js' : ''; ?>" title="<?php _e( 'Collapse All', 'learnpress' ); ?>"></a>
14
- </p>
15
- </h3>
16
- <!---->
17
- <ul class="curriculum-sections">
18
- <?php
19
- if ( $course_sections ):
20
- foreach ( $course_sections as $k => $section ):
21
 
22
- $content_items = '';
23
 
24
- if ( $section->items ):
25
- foreach ( $section->items as $item ):
26
- $loop_item_view = learn_press_get_admin_view( 'meta-boxes/course/loop-item.php' );
27
- ob_start();
28
- include $loop_item_view;
29
- $content_items .= "\n" . ob_get_clean();
30
- endforeach;
31
- endif;
32
 
33
- include learn_press_get_admin_view( 'meta-boxes/course/loop-section.php' );
34
- endforeach;
35
- unset( $content_items );
36
- endif;
37
- if ( !empty( $section ) )
38
- foreach ( get_object_vars( $section ) as $k => $v ) {
39
- $section->{$k} = null;
40
- }
41
- include learn_press_get_admin_view( 'meta-boxes/course/loop-section.php' );
42
- ?>
43
- </ul>
44
  </div>
4
  $hidden_sections = (array) get_post_meta( $post->ID, '_admin_hidden_sections', true );
5
  ?>
6
  <div id="lp-course-curriculum" class="lp-course-curriculum">
7
+ <h3 class="curriculum-heading">
8
+ <?php _e( 'Curriculum', 'learnpress' ); ?>
9
+ <span class="description"><?php _e( 'Outline your course and add content with sections, lessons and quizzes.', 'learnpress' ); ?></span>
10
 
11
+ <p align="right" class="items-toggle">
12
+ <a href="" data-action="expand" class="dashicons dashicons-arrow-down<?php echo!sizeof( $hidden_sections ) ? ' hide-if-js' : ''; ?>" title="<?php _e( 'Expand All', 'learnpress' ); ?>"></a>
13
+ <a href="" data-action="collapse" class="dashicons dashicons-arrow-up<?php echo sizeof( $hidden_sections ) ? ' hide-if-js' : ''; ?>" title="<?php _e( 'Collapse All', 'learnpress' ); ?>"></a>
14
+ </p>
15
+ </h3>
16
+ <!---->
17
+ <ul class="curriculum-sections">
18
+ <?php
19
+ if ( $course_sections ):
20
+ foreach ( $course_sections as $k => $section ):
21
 
22
+ $content_items = '';
23
 
24
+ if ( $section->items ):
25
+ foreach ( $section->items as $item ):
26
+ $loop_item_view = learn_press_get_admin_view( 'meta-boxes/course/loop-item.php' );
27
+ ob_start();
28
+ include $loop_item_view;
29
+ $content_items .= "\n" . ob_get_clean();
30
+ endforeach;
31
+ endif;
32
 
33
+ include learn_press_get_admin_view( 'meta-boxes/course/loop-section.php' );
34
+ endforeach;
35
+ unset( $content_items );
36
+ endif;
37
+ if ( !empty( $section ) )
38
+ foreach ( get_object_vars( $section ) as $k => $v ) {
39
+ $section->{$k} = null;
40
+ }
41
+ include learn_press_get_admin_view( 'meta-boxes/course/loop-section.php' );
42
+ ?>
43
+ </ul>
44
  </div>
inc/admin/views/meta-boxes/course/loop-item.php CHANGED
@@ -5,74 +5,54 @@
5
  * @package Admin/Views
6
  */
7
  if ( !isset( $section ) ) {
8
- $section = null;
9
  }
10
  $section_item_id = !empty( $item->section_item_id ) ? $item->section_item_id : null;
11
- $item_id = !empty( $item->item_id ) ? $item->item_id : null;
12
- $group_name = '_lp_curriculum[__SECTION__][items][' . ( $section_item_id ? $section_item_id : '__ITEM__' ) . ']';
13
- $support_types = learn_press_course_get_support_item_types();
14
 
15
- //$post_item = $item_id ? get_post( $item_id ) : learn_press_post_object( array( 'post_type' => LP_LESSON_CPT ) );
16
- //if($post_item) {
17
- // foreach ( get_object_vars( $post_item ) as $prop => $value ) {
18
- // $item->{$prop} = $value;
19
- // }
20
- //}
21
  if ( !empty( $support_types[$item->post_type] ) ) {
22
- $item_selected = $item->post_type;
23
  } else {
24
- $item_selected = key( $support_types );
25
  }
26
  ?>
27
 
28
  <?php do_action( 'learn_press_admin_before_section_loop_item', $item, $section ); ?>
29
 
30
- <tr <?php learn_press_admin_section_loop_item_class( $item, $section ); ?>
31
- data-text="<?php echo esc_attr( $item->post_title ); ?>"
32
- data-item_id="<?php echo $item_id; ?>"
33
- data-section_item_id="<?php echo $section_item_id; ?>"
34
- data-type="<?php echo $item->post_type; ?>">
35
- <?php do_action( 'learn_press_admin_begin_section_item', $item, $section ); ?>
36
- <td class="section-item-icon">
37
- <div class="learn-press-dropdown-item-types">
38
- <span class="learn-press-icon item-<?php echo $item->post_type; ?>" data-type="<?php echo $item->post_type; ?>"></span>
39
- <ul>
40
- <?php foreach ( $support_types as $_type => $text ) { ?>
41
- <li>
42
- <span
43
- class="learn-press-icon<?php echo $_type == $item_selected ? ' item-selected' : ''; ?> item-<?php echo $_type; ?>"
44
- data-content="<?php echo sprintf( __( 'Switch to %s', 'learnpress' ), $text ); ?>"
45
- data-type="<?php echo $_type; ?>">
46
- </span>
47
- </li>
48
- <?php } ?>
49
- </ul>
50
- </div>
51
- </td>
52
- <td class="section-item-input">
53
- <input type="text"
54
- autocomplete="off"
55
- name="<?php echo $group_name; ?>[name]"
56
- class="lp-item-name no-submit"
57
- data-field="item-name"
58
- value="<?php echo esc_attr( $item->post_title ); ?>"
59
- placeholder="<?php _e( 'Add new item here and press Enter', 'learnpress' ); ?>" />
60
- <input type="hidden" name="<?php echo $group_name; ?>[old_name]" value="<?php echo esc_attr( $item->post_title ); ?>" />
61
- <input type="hidden" name="<?php echo $group_name; ?>[item_id]" value="<?php echo $item_id; ?>" />
62
- <input type="hidden" name="<?php echo $group_name; ?>[section_item_id]" value="<?php echo $section_item_id; ?>" />
63
- <input type="hidden" class="lp-item-type" name="<?php echo $group_name; ?>[post_type]" value="<?php echo $item->post_type; ?>" />
64
- </td>
65
- <td class="section-item-actions">
66
- <p class="lp-item-actions lp-button-actions">
67
- <?php do_action( 'learn_press_admin_begin_section_item_actions', $item, $section ); ?>
68
- <a href="<?php echo absint( $item_id ) ? get_edit_post_link( $item_id ) : '{{data.edit_link}}'; ?>" class="lp-item-action lp-edit dashicons dashicons-edit" target="_blank"></a>
69
- <a href="" class="lp-item-action lp-remove dashicons dashicons-trash" data-confirm-remove="<?php _e( 'Are you sure you want to remove this item?', 'learnpress' ); ?>"></a>
70
  <span class="item-checkbox">
71
  <input type="checkbox" value="<?php echo $section_item_id; ?>" />
72
  <a class="dashicons dashicons-menu"></a>
73
  </span>
74
- <?php do_action( 'learn_press_admin_end_section_item_actions', $item, $section ); ?>
75
- </p>
76
- </td>
77
- <?php do_action( 'learn_press_admin_end_section_item', $item, $section ); ?>
78
  </tr>
5
  * @package Admin/Views
6
  */
7
  if ( !isset( $section ) ) {
8
+ $section = null;
9
  }
10
  $section_item_id = !empty( $item->section_item_id ) ? $item->section_item_id : null;
11
+ $item_id = !empty( $item->item_id ) ? $item->item_id : null;
12
+ $group_name = '_lp_curriculum[__SECTION__][items][' . ( $section_item_id ? $section_item_id : '__ITEM__' ) . ']';
 
13
 
14
+ $support_types = learn_press_course_get_support_item_types();
 
 
 
 
 
15
  if ( !empty( $support_types[$item->post_type] ) ) {
16
+ $item_selected = $item->post_type;
17
  } else {
18
+ $item_selected = key( $support_types );
19
  }
20
  ?>
21
 
22
  <?php do_action( 'learn_press_admin_before_section_loop_item', $item, $section ); ?>
23
 
24
+ <tr <?php learn_press_admin_section_loop_item_class( $item, $section ); ?> data-text="<?php echo esc_attr( $item->post_title ); ?>" data-item_id="<?php echo $item_id; ?>" data-section_item_id="<?php echo $section_item_id; ?>" data-type="<?php echo $item->post_type; ?>">
25
+ <?php do_action( 'learn_press_admin_begin_section_item', $item, $section ); ?>
26
+ <td class="section-item-icon">
27
+ <div class="learn-press-dropdown-item-types">
28
+ <span class="learn-press-icon item-<?php echo $item->post_type; ?>" data-type="<?php echo $item->post_type; ?>"></span>
29
+ <ul>
30
+ <?php foreach ( $support_types as $_type => $text ) { ?>
31
+ <li>
32
+ <span class="learn-press-icon<?php echo $_type == $item_selected ? ' item-selected' : ''; ?> item-<?php echo $_type; ?>" data-content="<?php echo sprintf( __( 'Switch to %s', 'learnpress' ), $text ); ?>" data-type="<?php echo $_type; ?>"></span>
33
+ </li>
34
+ <?php } ?>
35
+ </ul>
36
+ </div>
37
+ </td>
38
+ <td class="section-item-input">
39
+ <input type="text" autocomplete="off" name="<?php echo $group_name; ?>[name]" class="lp-item-name no-submit" data-field="item-name" value="<?php echo esc_attr( $item->post_title ); ?>" placeholder="<?php _e( 'Add new item here and press Enter', 'learnpress' ); ?>" />
40
+ <input type="hidden" name="<?php echo $group_name; ?>[old_name]" value="<?php echo esc_attr( $item->post_title ); ?>" />
41
+ <input type="hidden" name="<?php echo $group_name; ?>[item_id]" value="<?php echo $item_id; ?>" />
42
+ <input type="hidden" name="<?php echo $group_name; ?>[section_item_id]" value="<?php echo $section_item_id; ?>" />
43
+ <input type="hidden" class="lp-item-type" name="<?php echo $group_name; ?>[post_type]" value="<?php echo $item->post_type; ?>" />
44
+ </td>
45
+ <td class="section-item-actions">
46
+ <p class="lp-item-actions lp-button-actions">
47
+ <?php do_action( 'learn_press_admin_begin_section_item_actions', $item, $section ); ?>
48
+ <a href="<?php echo absint( $item_id ) ? get_edit_post_link( $item_id ) : '{{data.edit_link}}'; ?>" class="lp-item-action lp-edit dashicons dashicons-edit" target="_blank"><?php _e( '', 'learnpress' ); ?></a>
49
+ <a href="" class="lp-item-action lp-remove dashicons dashicons-trash" data-confirm-remove="<?php _e( 'Are you sure you want to remove this item?', 'learnpress' ); ?>"><?php _e( '', 'learnpress' ); ?></a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  <span class="item-checkbox">
51
  <input type="checkbox" value="<?php echo $section_item_id; ?>" />
52
  <a class="dashicons dashicons-menu"></a>
53
  </span>
54
+ <?php do_action( 'learn_press_admin_end_section_item_actions', $item, $section ); ?>
55
+ </p>
56
+ </td>
57
+ <?php do_action( 'learn_press_admin_end_section_item', $item, $section ); ?>
58
  </tr>
inc/admin/views/meta-boxes/course/loop-section.php CHANGED
@@ -7,8 +7,15 @@
7
  * @param $section_name
8
  * @param $content_items
9
  */
10
-
11
- $section = learn_press_get_default_section( isset( $section ) ? $section : null );
 
 
 
 
 
 
 
12
  $is_hidden = $section->section_id && is_array( $hidden_sections ) && in_array( $section->section_id, $hidden_sections );
13
 
14
  $class = array(
@@ -22,46 +29,68 @@ if ( $is_hidden ) {
22
  }
23
  ?>
24
  <li class="<?php echo join( ' ', $class ); ?>" data-id="<?php echo $section ? $section->section_id : ''; ?>">
25
- <h3 class="curriculum-section-head">
26
- <input name="_lp_curriculum[__SECTION__][name]" type="text" data-field="section-name" placeholder="<?php _e( 'Enter section name and hit enter', 'learnpress' ); ?>" class="lp-section-name no-submit" value="<?php echo esc_attr( $section->section_name ); ?>" />
27
- <p class="lp-section-actions lp-button-actions">
28
- <a href="" data-action="expand" class="dashicons dashicons-arrow-down<?php echo $is_hidden ? '' : ' hide-if-js'; ?>" title="<?php _e( 'Expand', 'learnpress' ); ?>"></a>
29
- <a href="" data-action="collapse" class="dashicons dashicons-arrow-up<?php echo !$is_hidden ? '' : ' hide-if-js'; ?>" title="<?php _e( 'Collapse', 'learnpress' ); ?>"></a>
30
- <a href="" data-action="remove" class="dashicons dashicons-trash" data-confirm-remove="<?php _e( 'Are you sure you want to remove this section?', 'learnpress' ); ?>"></a>
31
- <a href="" class="move"></a>
32
- </p>
33
- </h3>
34
- <div class="curriculum-section-content<?php echo $is_hidden ? ' hide-if-js' : ''; ?>">
35
- <div class="item-bulk-actions">
36
- <input name="_lp_curriculum[__SECTION__][description]" class="lp-section-describe" type="text" value="<?php echo esc_attr( $section->section_description ); ?>" placeholder="<?php _e( 'Describe about this section', 'learnpress' ); ?>" />
37
- <button class="button hide-if-js" type="button" data-action="delete" data-title="<?php _e( 'Remove', 'learnpress' ); ?>" data-confirm-remove="<?php _e( 'Are you sure you want to remove these items from section?', 'learnpress' ); ?>"><?php _e( 'Remove', 'learnpress' ); ?></button>
 
 
 
 
 
 
 
 
38
  <span class="button lp-check-items">
39
  <input class="lp-check-all-items" data-action="check-all" type="checkbox" />
40
  </span>
41
- </div>
42
- <table class="curriculum-section-items">
43
  <?php echo isset( $content_items ) ? $content_items : ''; ?>
44
  <?php
45
  $item = learn_press_post_object( array( 'post_type' => LP_LESSON_CPT ) );
46
  ?>
47
  <?php learn_press_admin_view( 'meta-boxes/course/loop-item.php', array( 'item' => $item ) ); ?>
48
 
49
- </table>
50
  <?php do_action( 'learn_press_after_section_items', $section ); ?>
51
  <?php if ( $buttons = apply_filters( 'learn_press_loop_section_buttons', array() ) ): ?>
52
- <br />
53
- <div class="lp-add-buttons">
54
-
 
 
 
 
 
 
 
 
 
 
 
 
55
  <?php foreach ( learn_press_section_item_types() as $slug => $name ) { ?>
56
  <?php if ( apply_filters( 'learn_press_button_type_select_items', true, $slug ) ) { ?>
57
- <button class="button" type="button" data-action="add-<?php echo $slug; ?>" data-type="<?php echo $slug; ?>">
58
  <?php echo sprintf( __( 'Select %s', 'learnpress' ), $name ); ?>
59
- </button>
60
  <?php } ?>
61
  <?php } ?>
62
-
63
- </div>
 
 
64
  <?php endif; ?>
65
  <?php do_action( 'learn_press_after_section_content', $section ); ?>
66
- </div>
67
  </li>
7
  * @param $section_name
8
  * @param $content_items
9
  */
10
+ if ( empty( $section ) ) {
11
+ $section = (object) array(
12
+ 'section_id' => null,
13
+ 'section_name' => '',
14
+ 'section_course_id' => null,
15
+ 'section_order' => null,
16
+ 'section_description' => ''
17
+ );
18
+ }
19
  $is_hidden = $section->section_id && is_array( $hidden_sections ) && in_array( $section->section_id, $hidden_sections );
20
 
21
  $class = array(
29
  }
30
  ?>
31
  <li class="<?php echo join( ' ', $class ); ?>" data-id="<?php echo $section ? $section->section_id : ''; ?>">
32
+ <h3 class="curriculum-section-head">
33
+ <input name="_lp_curriculum[__SECTION__][name]" type="text" data-field="section-name" placeholder="<?php _e( 'Enter section name and hit enter', 'learnpress' ); ?>" class="lp-section-name no-submit" value="<?php echo esc_attr( $section->section_name ); ?>" />
34
+ <p class="lp-section-actions lp-button-actions">
35
+ <a href="" data-action="expand" class="dashicons dashicons-arrow-down<?php echo $is_hidden ? '' : ' hide-if-js'; ?>" title="<?php _e( 'Expand', 'learnpress' ); ?>"></a>
36
+ <a href="" data-action="collapse" class="dashicons dashicons-arrow-up<?php echo !$is_hidden ? '' : ' hide-if-js'; ?>" title="<?php _e( 'Collapse', 'learnpress' ); ?>"></a>
37
+ <a href="" data-action="remove" class="dashicons dashicons-trash" data-confirm-remove="<?php _e( 'Are you sure you want to remove this section?', 'learnpress' ); ?>"><?php _e( '', 'learnpress' ); ?></a>
38
+ <a href="" class="move"></a>
39
+ </p>
40
+ </h3>
41
+ <div class="curriculum-section-content<?php echo $is_hidden ? ' hide-if-js' : ''; ?>">
42
+ <div class="item-bulk-actions">
43
+ <input name="_lp_curriculum[__SECTION__][description]" class="lp-section-describe" type="text" value="<?php echo esc_attr( $section->section_description ); ?>" placeholder="<?php _e( 'Describe about this section', 'learnpress' ); ?>" />
44
+ <button class="button hide-if-js" type="button" data-action="delete" data-title="<?php _e( 'Remove', 'learnpress' ); ?>" data-confirm-remove="<?php _e( 'Are you sure you want to remove these items from section?', 'learnpress' ); ?>"><?php _e( 'Remove', 'learnpress' ); ?></button>
45
+ <!--
46
+ <button class="button" type="button" data-action="delete-forever" disabled="disabled" data-title="<?php _e( 'Delete Forever', 'learnpress' ); ?>"><?php _e( 'Delete Forever', 'learnpress' ); ?></button>
47
+
48
+ <button class="button hide-if-js" type="button" data-action="cancel"><?php _e( 'Cancel', 'learnpress' ); ?></button>-->
49
+ <!--<div class="button lp-check-all-items">
50
+ <input type="checkbox" class="" />
51
+ <span>&dtrif;</span>
52
+ </div>-->
53
  <span class="button lp-check-items">
54
  <input class="lp-check-all-items" data-action="check-all" type="checkbox" />
55
  </span>
56
+ </div>
57
+ <table class="curriculum-section-items">
58
  <?php echo isset( $content_items ) ? $content_items : ''; ?>
59
  <?php
60
  $item = learn_press_post_object( array( 'post_type' => LP_LESSON_CPT ) );
61
  ?>
62
  <?php learn_press_admin_view( 'meta-boxes/course/loop-item.php', array( 'item' => $item ) ); ?>
63
 
64
+ </table>
65
  <?php do_action( 'learn_press_after_section_items', $section ); ?>
66
  <?php if ( $buttons = apply_filters( 'learn_press_loop_section_buttons', array() ) ): ?>
67
+ <br />
68
+ <div class="lp-add-buttons">
69
+ <!--<input type="text" class="regular-text no-submit" name="lp-new-item-name" placeholder="<?php _e( 'Add new lesson or quiz and press Enter', 'learnpress' ); ?>" />
70
+ <div class="button lp-button-dropdown lp-button-add-item disabled">
71
+ <span class="lp-dropdown-label lp-add-new-item"><?php _e( 'Add New', 'learnpress' ); ?></span>
72
+ <span class="lp-dropdown-arrow">+</span>
73
+ <ul class="lp-dropdown-items">
74
+ <?php foreach ( learn_press_section_item_types() as $slug => $name ) { ?>
75
+ <li>
76
+ <a href="" data-type="<?php echo $slug; ?>"><?php echo $name; ?></a>
77
+ </li>
78
+ <?php } ?>
79
+ </ul>
80
+ </div>
81
+ <?php _e( '-OR-', 'learnpress' ); ?>-->
82
  <?php foreach ( learn_press_section_item_types() as $slug => $name ) { ?>
83
  <?php if ( apply_filters( 'learn_press_button_type_select_items', true, $slug ) ) { ?>
84
+ <button class="button" type="button" data-action="add-<?php echo $slug; ?>" data-type="<?php echo $slug; ?>">
85
  <?php echo sprintf( __( 'Select %s', 'learnpress' ), $name ); ?>
86
+ </button>
87
  <?php } ?>
88
  <?php } ?>
89
+ <!--<button class="button " id="add-quiz" type="button" data-action="add-quiz" data-type="lp_quiz">
90
+ <?php _e( 'Select Quizzes', 'learnpress' ); ?>
91
+ </button>-->
92
+ </div>
93
  <?php endif; ?>
94
  <?php do_action( 'learn_press_after_section_content', $section ); ?>
95
+ </div>
96
  </li>
inc/admin/views/meta-boxes/course/review-logs.php CHANGED
@@ -12,11 +12,11 @@ $index = $total_reviews;
12
  <?php if ( $total_reviews ) { ?>
13
  <ul class="learn-press-review-logs clearfix">
14
  <?php foreach ( $reviews as $review ) { ?>
15
- <?php $user = LP_User_Factory::get_user( $review->user_id ); ?>
16
  <li>
17
  <div class="review-index">#<?php echo $index --; ?></div>
18
  <div class="review-user">
19
- <span class="user-avatar"><?php echo $user->get_profile_picture(); ?></span>
20
  </div>
21
  <div class="review-content">
22
  <strong class="user-nicename"><?php echo learn_press_get_profile_display_name( $user ); ?></strong>
12
  <?php if ( $total_reviews ) { ?>
13
  <ul class="learn-press-review-logs clearfix">
14
  <?php foreach ( $reviews as $review ) { ?>
15
+ <?php $user = get_userdata( $review->user_id ); ?>
16
  <li>
17
  <div class="review-index">#<?php echo $index --; ?></div>
18
  <div class="review-user">
19
+ <span class="user-avatar"><?php echo get_avatar( $review->user_id ); ?></span>
20
  </div>
21
  <div class="review-content">
22
  <strong class="user-nicename"><?php echo learn_press_get_profile_display_name( $user ); ?></strong>
inc/admin/views/meta-boxes/order/actions.php CHANGED
@@ -3,7 +3,6 @@ global $post, $action;
3
  $post_type = $post->post_type;
4
  $post_type_object = get_post_type_object( $post_type );
5
  $can_publish = current_user_can( $post_type_object->cap->publish_posts );
6
- $is_multiple =
7
 
8
  $datef = __( 'M j, Y @ H:i' );
9
  if ( 0 != $post->ID ) {
@@ -34,7 +33,7 @@ if ( 0 != $post->ID ) {
34
  <label>
35
  <?php _e( 'Order status', 'learnpress' ); ?>
36
  </label>
37
- <select name="order-status" data-status="<?php echo 'lp-' . $order->get_status(); ?>">
38
  <?php
39
  $statuses = learn_press_get_order_statuses();
40
  foreach ( $statuses as $status => $status_name ) {
@@ -42,7 +41,6 @@ if ( 0 != $post->ID ) {
42
  }
43
  ?>
44
  </select>
45
-
46
  <div class="description order-status-description">
47
  <?php if ( $order->get_status() == 'auto-draft' ) {
48
  echo _learn_press_get_order_status_description( 'lp-pending' );
@@ -50,13 +48,6 @@ if ( 0 != $post->ID ) {
50
  <?php echo _learn_press_get_order_status_description( 'lp-' . $order->get_status() ); ?>
51
  </div>
52
  </div>
53
- <div class="misc-pub-section hide-if-js order-action-section">
54
- <label for="trigger-order-action">
55
- <input type="checkbox" name="trigger-order-action" id="trigger-order-action" value="yes" />
56
- <?php _e( 'Trigger order status action', 'learnpress' ); ?>
57
- </label>
58
- <p class="description"><?php esc_attr_e( 'Check this option to force an action to be triggered. Normally, an action only is triggered after changing to an another action.', 'learnpress' ); ?></p>
59
- </div>
60
 
61
  <div class="misc-pub-section">
62
  <label>
@@ -66,29 +57,15 @@ if ( 0 != $post->ID ) {
66
  <input name="order-customer" type="text" class="wp-suggest-user ui-autocomplete-input" id="admin-email" data-autocomplete-type="search" data-autocomplete-field="user_email" autocomplete="off">
67
  -->
68
  <?php
69
- if ( $order->is_multi_users() ) {
70
- $order->dropdown_users();
71
- ?>
72
- <input type="hidden" name="multi-users" value="yes" />
73
- <?php
74
- wp_enqueue_style( 'select2', RWMB_CSS_URL . 'select2/select2.css' );
75
- wp_enqueue_script( 'select2', RWMB_JS_URL . 'select2/select2.min.js' );
76
- } else {
77
- wp_dropdown_users(
78
- array(
79
- 'show_option_none' => __( '[Guest]', 'learnpress' ),
80
- 'name' => 'order-customer',
81
- 'id' => null,
82
- 'selected' => $order->get_user( 'ID' )
83
- )
84
- );
85
- }
86
- if ( $order->get_status() == 'auto-draft' && !$order->is_multi_users() ) {
87
- ?>
88
- --
89
- <a href="<?php echo add_query_arg( 'multi-users', 'yes' ); ?>"><?php _e( 'Multiple users', 'learnpress' ); ?></a>
90
- <?php
91
- }
92
  // }else{
93
  // echo $order->get_customer_name();
94
  // }
3
  $post_type = $post->post_type;
4
  $post_type_object = get_post_type_object( $post_type );
5
  $can_publish = current_user_can( $post_type_object->cap->publish_posts );
 
6
 
7
  $datef = __( 'M j, Y @ H:i' );
8
  if ( 0 != $post->ID ) {
33
  <label>
34
  <?php _e( 'Order status', 'learnpress' ); ?>
35
  </label>
36
+ <select name="order-status">
37
  <?php
38
  $statuses = learn_press_get_order_statuses();
39
  foreach ( $statuses as $status => $status_name ) {
41
  }
42
  ?>
43
  </select>
 
44
  <div class="description order-status-description">
45
  <?php if ( $order->get_status() == 'auto-draft' ) {
46
  echo _learn_press_get_order_status_description( 'lp-pending' );
48
  <?php echo _learn_press_get_order_status_description( 'lp-' . $order->get_status() ); ?>
49
  </div>
50
  </div>
 
 
 
 
 
 
 
51
 
52
  <div class="misc-pub-section">
53
  <label>
57
  <input name="order-customer" type="text" class="wp-suggest-user ui-autocomplete-input" id="admin-email" data-autocomplete-type="search" data-autocomplete-field="user_email" autocomplete="off">
58
  -->
59
  <?php
60
+ // if($order->get_status() =='' || $order->has_status('pending') ) {
61
+ wp_dropdown_users(
62
+ array(
63
+ 'show_option_none' => __( '[Guest]', 'learnpress' ),
64
+ 'name' => 'order-customer',
65
+ 'id' => null,
66
+ 'selected' => $order->get_user( 'ID' )
67
+ )
68
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  // }else{
70
  // echo $order->get_customer_name();
71
  // }
inc/admin/views/meta-boxes/order/details.php CHANGED
@@ -18,32 +18,19 @@ global $post;
18
  </div>
19
  <div class="order-user-data clearfix">
20
  <div class="order-user-avatar">
21
- <?php if ( $order->is_multi_users() ) { ?>
22
- <div class="avatar-multiple-users">
23
- <span></span>
24
- </div>
25
- <?php } else { ?>
26
- <?php echo get_avatar( $order->get_user( 'ID' ), 120 ); ?>
27
- <?php } ?>
28
  </div>
29
  <div class="order-user-meta">
30
- <?php if ( $order->is_multi_users() ) { ?>
31
- <div class="order-users">
32
- <strong><?php _e( 'Customers', 'learnpress' ); ?></strong>
33
- <p><?php $order->print_users(); ?></p>
34
- </div>
35
- <?php } else { ?>
36
- <div class="user-display-name">
37
- <?php echo $order->get_customer_name(); ?>
38
- </div>
39
- <div class="user-email">
40
- <?php $user_email = $order->get_user( 'user_email' );
41
- echo empty( $user_email ) ? '' : $user_email; ?>
42
- </div>
43
- <div class="user-ip-address">
44
- <?php echo $order->user_ip_address; ?>
45
- </div>
46
- <?php } ?>
47
  <?php if ( $title = $order->get_payment_method_title() ) { ?>
48
  <div class="payment-method-title">
49
  <?php echo $order->order_total == 0 ? $title : sprintf( __( 'Pay via <strong>%s</strong>', 'learnpress' ), $title ); ?>
@@ -103,7 +90,7 @@ global $post;
103
  <?php if ( $note = get_the_excerpt() ) { ?>
104
  <br />
105
  <h3><?php _e( 'Customer Note', 'learnpress' ); ?></h3>
106
- <p class="order-note description"><?php echo $note; ?></p>
107
  <?php } ?>
108
  </div>
109
  <script type="text/html" id="tmpl-learn-press-modal-add-order-courses">
18
  </div>
19
  <div class="order-user-data clearfix">
20
  <div class="order-user-avatar">
21
+ <?php echo get_avatar( $order->get_user( 'ID' ), 120 ); ?>
 
 
 
 
 
 
22
  </div>
23
  <div class="order-user-meta">
24
+ <div class="user-display-name">
25
+ <?php echo $order->get_customer_name(); ?>
26
+ </div>
27
+ <div class="user-email">
28
+ <?php $user_email = $order->get_user( 'user_email' );
29
+ echo empty( $user_email ) ? '' : $user_email; ?>
30
+ </div>
31
+ <div class="user-ip-address">
32
+ <?php echo $order->user_ip_address; ?>
33
+ </div>
 
 
 
 
 
 
 
34
  <?php if ( $title = $order->get_payment_method_title() ) { ?>
35
  <div class="payment-method-title">
36
  <?php echo $order->order_total == 0 ? $title : sprintf( __( 'Pay via <strong>%s</strong>', 'learnpress' ), $title ); ?>
90
  <?php if ( $note = get_the_excerpt() ) { ?>
91
  <br />
92
  <h3><?php _e( 'Customer Note', 'learnpress' ); ?></h3>
93
+ <p class="order-note description"><?php echo $note;?></p>
94
  <?php } ?>
95
  </div>
96
  <script type="text/html" id="tmpl-learn-press-modal-add-order-courses">
inc/admin/views/meta-boxes/tabs.php CHANGED
@@ -55,9 +55,6 @@ $current_tab = !empty( $_REQUEST['tab'] ) ? $_REQUEST['tab'] : '';
55
  );
56
  $remove_meta_boxes[] = $metabox;
57
  }
58
- if ( empty( $tab['title'] ) ) {
59
- continue;
60
- }
61
  if ( empty( $tab['id'] ) ) {
62
  $tab['id'] = sanitize_title( $tab['title'] );
63
  }
@@ -76,9 +73,6 @@ $current_tab = !empty( $_REQUEST['tab'] ) ? $_REQUEST['tab'] : '';
76
  <ul class="learn-press-tab-content" data-text="<?php esc_attr_e( 'Initializing...', 'learnpress' ); ?>">
77
  <?php
78
  foreach ( $tabs as $tab ) {
79
- if ( empty( $tab['title'] ) ) {
80
- continue;
81
- }
82
  echo '<li id="meta-box-tab-' . $tab['id'] . '" class="' . $tab['id'] . ( is_array( $current_tab ) && $current_tab['id'] == $tab['id'] ? ' active' : '' ) . '">';
83
  if ( !empty( $tab['content'] ) ) {
84
  echo $tab['content'];
@@ -90,17 +84,12 @@ $current_tab = !empty( $_REQUEST['tab'] ) ? $_REQUEST['tab'] : '';
90
  echo '</li>';
91
  }
92
  if ( !empty( $remove_meta_boxes ) ) {
93
- $contexts = array( 'normal', 'side', 'advanced' );
94
  foreach ( $remove_meta_boxes as $meta_box ) {
95
  if ( $meta_box instanceof RW_Meta_Box ) {
96
  $mbox = $meta_box->meta_box;
97
  foreach ( $mbox['post_types'] as $page ) {
98
- foreach ( $contexts as $context ) {
99
- remove_meta_box( $mbox['id'], $page, $context );
100
- if ( !empty( $wp_meta_boxes[$page][$context]['sorted'][$mbox['id']] ) ) {
101
- $wp_meta_boxes[$page][$context]['sorted'][$mbox['id']] = false;
102
- }
103
- }
104
  }
105
  } else {
106
 
55
  );
56
  $remove_meta_boxes[] = $metabox;
57
  }
 
 
 
58
  if ( empty( $tab['id'] ) ) {
59
  $tab['id'] = sanitize_title( $tab['title'] );
60
  }
73
  <ul class="learn-press-tab-content" data-text="<?php esc_attr_e( 'Initializing...', 'learnpress' ); ?>">
74
  <?php
75
  foreach ( $tabs as $tab ) {
 
 
 
76
  echo '<li id="meta-box-tab-' . $tab['id'] . '" class="' . $tab['id'] . ( is_array( $current_tab ) && $current_tab['id'] == $tab['id'] ? ' active' : '' ) . '">';
77
  if ( !empty( $tab['content'] ) ) {
78
  echo $tab['content'];
84
  echo '</li>';
85
  }
86
  if ( !empty( $remove_meta_boxes ) ) {
 
87
  foreach ( $remove_meta_boxes as $meta_box ) {
88
  if ( $meta_box instanceof RW_Meta_Box ) {
89
  $mbox = $meta_box->meta_box;
90
  foreach ( $mbox['post_types'] as $page ) {
91
+ remove_meta_box( $mbox['id'], $page, $mbox['context'] );
92
+ $wp_meta_boxes[$page][$mbox['context']]['sorted'][$mbox['id']] = false;
 
 
 
 
93
  }
94
  } else {
95
 
inc/admin/views/settings/emails/enrolled-course-admin.php DELETED
@@ -1,76 +0,0 @@
1
- <?php
2
- /**
3
- * Display general settings for emails
4
- *
5
- * @author ThimPress
6
- * @package LearnPress/Admin/Views/Emails
7
- * @version 1.0
8
- */
9
- if ( !defined( 'ABSPATH' ) ) {
10
- exit; // Exit if accessed directly
11
- }
12
-
13
- $settings = LP()->settings;
14
- ?>
15
- <h3><?php _e( 'Send mail for admins & instructors ', 'learnpress' ); ?></h3>
16
- <p class="description">
17
- <?php _e( 'Send this email to admins & instructor when the course is enrolled.', 'learnpress' ); ?>
18
- </p>
19
- <table class="form-table">
20
- <tbody>
21
- <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
22
- <tr>
23
- <th scope="row">
24
- <label for="learn-press-emails-enrolled-course-enable"><?php _e( 'Enable', 'learnpress' ); ?></label></th>
25
- <td>
26
- <input type="hidden" name="<?php echo $settings_class->get_field_name( 'emails_enrolled_course_admin[enable]' ); ?>" value="no" />
27
- <input id="learn-press-emails-enrolled-course-enable" type="checkbox" name="<?php echo $settings_class->get_field_name( 'emails_enrolled_course_admin[enable]' ); ?>" value="yes" <?php checked( $settings->get( 'emails_enrolled_course_admin.enable' ) == 'yes' ); ?> />
28
- </td>
29
- </tr>
30
- <tr>
31
- <th scope="row">
32
- <label for="learn-press-emails-enrolled-course-send-admins"><?php _e( 'Send Admins', 'learnpress' ); ?></label></th>
33
- <td>
34
- <input type="hidden" name="<?php echo $settings_class->get_field_name( 'emails_enrolled_course_admin[send_admins]' ); ?>" value="no" />
35
- <input id="learn-press-emails-enrolled-course-send-admins" type="checkbox" name="<?php echo $settings_class->get_field_name( 'emails_enrolled_course_admin[send_admins]' ); ?>" value="yes" <?php checked( $settings->get( 'emails_enrolled_course_admin.send_admins' ) == 'yes' ); ?> />
36
- </td>
37
- </tr>
38
- <?php do_action( 'learn_press_before_subject_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings, $settings_class ); ?>
39
- <tr>
40
- <th scope="row">
41
- <label for="learn-press-emails-enrolled-course-subject"><?php _e( 'Subject', 'learnpress' ); ?></label></th>
42
- <td>
43
- <input id="learn-press-emails-enrolled-course-subject" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_enrolled_course_admin[subject]' ); ?>" value="<?php echo $settings->get( 'emails_enrolled_course_admin.subject', $this->default_subject ); ?>" />
44
-
45
- <p class="description">
46
- <?php printf( __( 'Email subject , default: <code>%s</code>', 'learnpress' ), $this->default_subject ); ?>
47
- </p>
48
- </td>
49
- </tr>
50
- <tr>
51
- <th scope="row">
52
- <label for="learn-press-emails-enrolled-course-heading"><?php _e( 'Heading', 'learnpress' ); ?></label></th>
53
- <td>
54
- <input id="learn-press-emails-enrolled-course-heading" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_enrolled_course_admin[heading]' ); ?>" value="<?php echo $settings->get( 'emails_enrolled_course_admin.heading', $this->default_heading ); ?>" />
55
-
56
- <p class="description">
57
- <?php printf( __( 'Email heading, default: <code>%s</code>', 'learnpress' ), $this->default_heading ); ?>
58
- </p>
59
- </td>
60
- </tr>
61
- <!--
62
- <tr>
63
- <th scope="row">
64
- <label for="learn-press-emails-enrolled-course-email-format"><?php _e( 'Email format', 'learnpress' ); ?></label>
65
- </th>
66
- <td>
67
- <?php learn_press_email_formats_dropdown( array( 'name' => $settings_class->get_field_name( 'emails_enrolled_course_admin[email_format]' ), 'id' => 'learn_press_email_formats', 'selected' => $settings->get( 'emails_enrolled_course_admin.email_format' ) ) ); ?>
68
- </td>
69
- </tr>-->
70
- <?php
71
- $view = learn_press_get_admin_view( 'settings/emails/email-template.php' );
72
- include_once $view;
73
- ?>
74
- <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
75
- </tbody>
76
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/views/settings/emails/update-course.php DELETED
@@ -1,50 +0,0 @@
1
- <?php
2
- /**
3
- * Display general settings for emails
4
- *
5
- * @author ThimPress
6
- * @package LearnPress/Admin/Views/Emails
7
- * @version 1.0
8
- */
9
- if ( !defined( 'ABSPATH' ) ) {
10
- exit; // Exit if accessed directly
11
- }
12
-
13
- $settings = LP()->settings;
14
- ?>
15
- <h3><?php _e( 'Update course', 'learnpress' ); ?></h3>
16
- <p class="description">
17
- <?php _e( 'Send this email to users have purchased when the course is updated.', 'learnpress' ); ?>
18
- </p>
19
- <table class="form-table">
20
- <tbody>
21
- <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
22
- <tr>
23
- <th scope="row">
24
- <label for="learn-press-emails-updated-course-subject"><?php _e( 'Subject', 'learnpress' ); ?></label></th>
25
- <td>
26
- <input id="learn-press-emails-updated-course-subject" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_update_course[subject]' ); ?>" value="<?php echo $settings->get( 'emails_update_course.subject', $this->default_subject ); ?>" />
27
-
28
- <p class="description">
29
- <?php printf( __( 'Email subject , default: <code>%s</code>', 'learnpress' ), $this->default_subject ); ?>
30
- </p>
31
- </td>
32
- </tr>
33
- <tr>
34
- <th scope="row">
35
- <label for="learn-press-emails-updated-course-heading"><?php _e( 'Heading', 'learnpress' ); ?></label></th>
36
- <td>
37
- <input id="learn-press-emails-updated-course-heading" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_update_course[heading]' ); ?>" value="<?php echo $settings->get( 'emails_update_course.heading', $this->default_heading ); ?>" />
38
-
39
- <p class="description">
40
- <?php printf( __( 'Email heading, default: <code>%s</code>', 'learnpress' ), $this->default_heading ); ?>
41
- </p>
42
- </td>
43
- </tr>
44
- <?php
45
- $view = learn_press_get_admin_view( 'settings/emails/email-template.php' );
46
- include_once $view;
47
- ?>
48
- <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
49
- </tbody>
50
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/views/settings/emails/user-order-changed-status.php DELETED
@@ -1,68 +0,0 @@
1
- <?php
2
- /**
3
- * Display general settings for emails
4
- *
5
- * @author ThimPress
6
- * @package LearnPress/Admin/Views/Emails
7
- * @version 1.0
8
- */
9
- if ( !defined( 'ABSPATH' ) ) {
10
- exit; // Exit if accessed directly
11
- }
12
-
13
- $settings = LP()->settings;
14
- ?>
15
- <h3><?php _e( 'User order changed status', 'learnpress' ); ?></h3>
16
- <p class="description">
17
- <?php _e( 'Send email to user when the order is changed status.', 'learnpress' ); ?>
18
- </p>
19
- <table class="form-table">
20
- <tbody>
21
- <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
22
- <tr>
23
- <th scope="row">
24
- <label for="learn-press-emails-new-order-enable"><?php _e( 'Enable', 'learnpress' ); ?></label></th>
25
- <td>
26
- <input type="hidden" name="<?php echo $settings_class->get_field_name( 'emails_user_order_changed_status[enable]' ); ?>" value="no" />
27
- <input id="learn-press-emails-new-order-enable" type="checkbox" name="<?php echo $settings_class->get_field_name( 'emails_user_order_changed_status[enable]' ); ?>" value="yes" <?php checked( $settings->get( 'emails_user_order_changed_status.enable' ) == 'yes' ); ?>" />
28
- </td>
29
- </tr>
30
- <tr>
31
- <th scope="row">
32
- <label for="learn-press-emails-new-order-subject"><?php _e( 'Subject', 'learnpress' ); ?></label></th>
33
- <td>
34
- <?php $default = $this->default_subject; ?>
35
- <input id="learn-press-emails-new-order-subject" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_user_order_changed_status[subject]' ); ?>" value="<?php echo $settings->get( 'emails_user_order_changed_status.subject', $default ); ?>" />
36
-
37
- <p class="description">
38
- <?php printf( __( 'Email subject, default: <code>%s</code>', 'learnpress' ), $default ); ?>
39
- </p>
40
- </td>
41
- </tr>
42
- <tr>
43
- <th scope="row">
44
- <label for="learn-press-emails-new-order-heading"><?php _e( 'Heading', 'learnpress' ); ?></label></th>
45
- <td>
46
- <?php $default = $this->default_heading; ?>
47
- <input id="learn-press-emails-new-order-heading" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_user_order_changed_status[heading]' ); ?>" value="<?php echo $settings->get( 'emails_user_order_changed_status.heading', $default ); ?>" />
48
-
49
- <p class="description">
50
- <?php printf( __( 'Email heading, default: <code>%s</code>', 'learnpress' ), $default ); ?>
51
- </p>
52
- </td>
53
- </tr>
54
- <!--<tr>
55
- <th scope="row">
56
- <label for="learn-press-emails-new-order-email-format"><?php _e( 'Email format', 'learnpress' ); ?></label>
57
- </th>
58
- <td>
59
- <?php learn_press_email_formats_dropdown( array( 'name' => $settings_class->get_field_name( 'emails_user_order_changed_status[email_format]' ), 'id' => 'learn_press_email_formats', 'selected' => $settings->get( 'emails_user_order_changed_status.email_format', $default ) ) ); ?>
60
- </td>
61
- </tr>-->
62
- <?php
63
- $view = learn_press_get_admin_view( 'settings/emails/email-template.php' );
64
- include_once $view;
65
- ?>
66
- <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
67
- </tbody>
68
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/views/settings/fields/course-permalink.php CHANGED
@@ -14,12 +14,12 @@ $courses_page_id = learn_press_get_page_id( 'courses' );
14
  $base_slug = urldecode( ( $courses_page_id > 0 && get_post( $courses_page_id ) ) ? get_page_uri( $courses_page_id ) : _x( 'courses', 'default-slug', 'learnpress' ) );
15
  $course_base = _x( 'course', 'default-slug', 'learnpress' );
16
 
17
- /*if ( !$course_permalink ) {
18
  global $wpdb;
19
- if ( $wpdb->get_results( $wpdb->prepare( "SELECT count(option_id) FROM {$wpdb->options} WHERE option_name = %s", 'learn_press_course_base' ) ) == 0 ) {
20
  //$course_permalink = '/courses';
21
  }
22
- }*/
23
  $structures = array(
24
  0 => array(
25
  'value' => '',
@@ -43,19 +43,17 @@ $structures = array(
43
  )
44
  );
45
 
 
46
  $base_type = get_option( 'learn_press_course_base_type' );
47
- $is_custom = ( $base_type == 'custom' && $course_permalink != '' );
48
-
49
  ?>
50
  <?php foreach ( $structures as $k => $structure ): ?>
51
- <tr class="learn-press-single-course-permalink<?php if ( $k == 2 || $k == 3 ) {
52
- echo ' learn-press-courses-page-id';
53
- echo !$courses_page_id ? ' hide-if-js' : '';
54
- }; ?>">
55
  <th>
56
  <?php
57
- $is_checked = ( $course_permalink == '' && $structure['value'] == '' ) || ( $structure['value'] == trailingslashit( $course_permalink ) );
58
- $is_checked = checked( $is_checked, true, false );
59
  if ( $is_custom && $is_checked ) {
60
  $is_custom = false;
61
  }
@@ -70,17 +68,16 @@ $is_custom = ( $base_type == 'custom' && $course_permalink != '' );
70
  </td>
71
  </tr>
72
  <?php endforeach; ?>
73
- <tr class="learn-press-single-course-permalink custom-base">
74
  <th>
75
  <label>
76
- <input name="<?php echo $this->get_field_name( "course_base" ); ?>" id="learn_press_custom_permalink" type="radio" value="custom" <?php checked( $is_custom, true ); ?> />
77
  <?php _e( 'Custom Base', 'learnpress' ); ?>
78
  </label>
79
  </th>
80
  <td>
81
- <input name="course_permalink_structure" id="course_permalink_structure" <?php if ( !$is_custom ) {
82
- echo 'readonly="readonly"';
83
- } ?> type="text" value="<?php if($course_permalink) echo esc_attr( trailingslashit( $course_permalink ) ); ?>" class="regular-text code" />
84
  <p class="description"><?php _e( 'Enter a custom base to use. A base <strong>must</strong> be set or WordPress will use default values instead.', 'learnpress' ); ?></p>
85
  </td>
86
  </tr>
14
  $base_slug = urldecode( ( $courses_page_id > 0 && get_post( $courses_page_id ) ) ? get_page_uri( $courses_page_id ) : _x( 'courses', 'default-slug', 'learnpress' ) );
15
  $course_base = _x( 'course', 'default-slug', 'learnpress' );
16
 
17
+ if( !$course_permalink ){
18
  global $wpdb;
19
+ if( $wpdb->get_results( $wpdb->prepare( "SELECT count(option_id) FROM {$wpdb->options} WHERE option_name = %s", 'learn_press_course_base' ) ) == 0 ){
20
  //$course_permalink = '/courses';
21
  }
22
+ }
23
  $structures = array(
24
  0 => array(
25
  'value' => '',
43
  )
44
  );
45
 
46
+ $is_custom = true;
47
  $base_type = get_option( 'learn_press_course_base_type' );
 
 
48
  ?>
49
  <?php foreach ( $structures as $k => $structure ): ?>
50
+ <tr<?php if ( $k == 2 || $k == 3 ) {
51
+ echo ' class="learn-press-courses-page-id';
52
+ echo !$courses_page_id ? ' hide-if-js"' : '""';
53
+ }; ?> >
54
  <th>
55
  <?php
56
+ $is_checked = checked( ( $course_permalink == '' && $structure['value'] == '' ) || ( $structure['value'] == trailingslashit( $course_permalink ) ), true, false );
 
57
  if ( $is_custom && $is_checked ) {
58
  $is_custom = false;
59
  }
68
  </td>
69
  </tr>
70
  <?php endforeach; ?>
71
+ <tr>
72
  <th>
73
  <label>
74
+ <input name="<?php echo $this->get_field_name( "course_base" ); ?>" id="learn_press_custom_permalink" type="radio" value="custom" <?php checked( $is_custom || ( $base_type == 'custom' ), true ); ?> />
75
  <?php _e( 'Custom Base', 'learnpress' ); ?>
76
  </label>
77
  </th>
78
  <td>
79
+ <input name="course_permalink_structure" id="course_permalink_structure" type="text" value="<?php echo esc_attr( $course_permalink ); ?>" class="regular-text code" />
80
+
 
81
  <p class="description"><?php _e( 'Enter a custom base to use. A base <strong>must</strong> be set or WordPress will use default values instead.', 'learnpress' ); ?></p>
82
  </td>
83
  </tr>
inc/admin/views/settings/fields/image-size.php CHANGED
@@ -1,22 +1,22 @@
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>
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"><h3 class="lp-group-title"><?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/attributes/lp-attributes-functions.php CHANGED
@@ -19,20 +19,10 @@ function learn_press_get_attributes() {
19
  * @return array|int|WP_Error
20
  */
21
  function learn_press_get_attribute_terms( $attribute ) {
22
- $terms = array();
23
- if ( is_array( $attribute ) ) {
24
- foreach ( $attribute as $attr ) {
25
- $_terms = learn_press_get_attribute_terms( $attr );
26
- if ( is_array( $terms ) ) {
27
- $terms = array_merge( $terms, $_terms );
28
- }
29
- }
30
- } else {
31
- if ( is_numeric( $attribute ) && !is_wp_error( $term = get_term( $attribute, LP_COURSE_ATTRIBUTE ) ) ) {
32
- $attribute = $term->slug;
33
- }
34
- $terms = get_terms( sprintf( '%s-%s', LP_COURSE_ATTRIBUTE, $attribute ), array( 'hide_empty' => false ) );
35
  }
 
36
  return $terms;
37
  }
38
 
@@ -55,21 +45,10 @@ function learn_press_delete_attribute_terms( $attribute ) {
55
  return $deleted_terms;
56
  }
57
 
58
- /**
59
- * @param $course_id
60
- *
61
- * @return mixed
62
- */
63
  function learn_press_get_course_attributes( $course_id ) {
64
  return get_post_meta( $course_id, '_lp_attributes', true );
65
  }
66
 
67
- /**
68
- * @param $name
69
- * @param $taxonomy
70
- *
71
- * @return array|bool|WP_Error
72
- */
73
  function learn_press_add_course_attribute_value( $name, $taxonomy ) {
74
 
75
  if ( !$name || term_exists( $name, $taxonomy ) ) {
@@ -83,11 +62,6 @@ function learn_press_add_course_attribute_value( $name, $taxonomy ) {
83
  return $new_value;
84
  }
85
 
86
- /**
87
- * @param $name
88
- *
89
- * @return array|bool|WP_Error
90
- */
91
  function learn_press_add_course_attribute( $name ) {
92
 
93
  if ( !$name || term_exists( $name, LP_COURSE_ATTRIBUTE ) ) {
@@ -98,12 +72,6 @@ function learn_press_add_course_attribute( $name ) {
98
  return $new_value;
99
  }
100
 
101
- /**
102
- * @param $course_id
103
- * @param $taxonomy
104
- *
105
- * @return bool|mixed|void
106
- */
107
  function learn_press_add_attribute_to_course( $course_id, $taxonomy ) {
108
  if ( !$term = get_term_by( 'slug', $taxonomy, LP_COURSE_ATTRIBUTE ) ) {
109
  return false;
@@ -123,53 +91,8 @@ function learn_press_add_attribute_to_course( $course_id, $taxonomy ) {
123
  return $attribute;
124
  }
125
 
126
- /**
127
- * @param WP_Query $q
128
- */
129
- add_filter( 'pre_get_posts', function ( $q ) {
130
- global $lp_tax_query;
131
- if ( empty( $_REQUEST['course-filter'] ) ) {
132
- return;
133
- }
134
-
135
- if ( !$q->is_main_query() ) {
136
- return;
137
- }
138
- if ( LP_COURSE_CPT != $q->get( 'post_type' ) ) {
139
- return $q;
140
- }
141
-
142
- if ( $attribute_taxonomies = learn_press_get_attributes() ) {
143
- $attribute_operator = 'and' === strtolower( learn_press_get_request( 'attribute_operator' ) ) ? 'AND' : 'OR';
144
- $value_operator = 'and' === strtolower( learn_press_get_request( 'value_operator' ) ) ? 'AND' : 'IN';
145
- $tax_query = array(
146
- 'relation' => $attribute_operator
147
- );
148
- foreach ( $attribute_taxonomies as $tax ) {
149
- $attribute = $tax->slug;
150
- $taxonomy = LP_COURSE_ATTRIBUTE . '-' . $attribute;
151
- $filter_terms = !empty( $_GET['filter_' . $attribute] ) ? explode( ',', $_GET['filter_' . $attribute] ) : array();
152
-
153
-
154
- if ( empty( $filter_terms ) || !taxonomy_exists( $taxonomy ) ) {
155
- continue;
156
- }
157
-
158
- $tax_query[] = array(
159
- 'taxonomy' => $taxonomy,
160
- 'field' => 'slug',
161
- 'terms' => $filter_terms,
162
- 'operator' => $value_operator,
163
- 'include_children' => false,
164
- );
165
- }
166
- $lp_tax_query = $tax_query;
167
- $q->set( 'tax_query', $tax_query );
168
- }
169
- return $q;
170
- }, 1000 );
171
-
172
  /**
173
  * Register widgets
174
  */
175
- LP_Widget::register( array( 'course-attributes', 'course-filters' ) );
 
19
  * @return array|int|WP_Error
20
  */
21
  function learn_press_get_attribute_terms( $attribute ) {
22
+ if ( is_numeric( $attribute ) && !is_wp_error( $term = get_term( $attribute, LP_COURSE_ATTRIBUTE ) ) ) {
23
+ $attribute = $term->slug;
 
 
 
 
 
 
 
 
 
 
 
24
  }
25
+ $terms = get_terms( sprintf( '%s-%s', LP_COURSE_ATTRIBUTE, $attribute ), array( 'hide_empty' => false ) );
26
  return $terms;
27
  }
28
 
45
  return $deleted_terms;
46
  }
47
 
 
 
 
 
 
48
  function learn_press_get_course_attributes( $course_id ) {
49
  return get_post_meta( $course_id, '_lp_attributes', true );
50
  }
51
 
 
 
 
 
 
 
52
  function learn_press_add_course_attribute_value( $name, $taxonomy ) {
53
 
54
  if ( !$name || term_exists( $name, $taxonomy ) ) {
62
  return $new_value;
63
  }
64
 
 
 
 
 
 
65
  function learn_press_add_course_attribute( $name ) {
66
 
67
  if ( !$name || term_exists( $name, LP_COURSE_ATTRIBUTE ) ) {
72
  return $new_value;
73
  }
74
 
 
 
 
 
 
 
75
  function learn_press_add_attribute_to_course( $course_id, $taxonomy ) {
76
  if ( !$term = get_term_by( 'slug', $taxonomy, LP_COURSE_ATTRIBUTE ) ) {
77
  return false;
91
  return $attribute;
92
  }
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  /**
95
  * Register widgets
96
  */
97
+ LP_Widget::register( 'course-attributes' );
98
+ LP_Widget::register( 'course-filters' );
inc/cart/class-lp-cart.php CHANGED
@@ -1,664 +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.', '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();
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,738 +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
- '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
-
64
- return;
65
- }
66
- if ( learn_press_get_request( 'format' ) == 'html' ) {
67
- return;
68
- }
69
- learn_press_send_json( $result );
70
- }
71
-
72
- public static function upload_user_avatar () {
73
- $file = $_FILES['lp-upload-avatar'];
74
- $upload_dir = learn_press_user_profile_picture_upload_dir();
75
-
76
- add_filter( 'upload_dir', array( __CLASS__, '_user_avatar_upload_dir' ), 10000 );
77
-
78
- $result = wp_handle_upload( $file,
79
- array(
80
- 'test_form' => false
81
- )
82
- );
83
-
84
- remove_filter( 'upload_dir', array( __CLASS__, '_user_avatar_upload_dir' ), 10000 );
85
- if ( is_array( $result ) ) {
86
- $result['name'] = $upload_dir['subdir'] . '/' . basename( $result['file'] );
87
- unset( $result['file'] );
88
- } else {
89
- $result = array(
90
- 'error' => __( 'Upload profile avatar error.', 'learnpress' )
91
- );
92
- }
93
- learn_press_send_json( $result );
94
- }
95
-
96
- public static function _user_avatar_upload_dir ( $dir ) {
97
- $dir = learn_press_user_profile_picture_upload_dir();
98
-
99
- return $dir;
100
- }
101
-
102
- /**
103
- * Become a teacher
104
- */
105
- public static function _request_become_a_teacher () {
106
- $response = learn_press_process_become_a_teacher_form(
107
- array(
108
- 'name' => learn_press_get_request( 'bat_name' ),
109
- 'email' => learn_press_get_request( 'bat_email' ),
110
- 'phone' => learn_press_get_request( 'bat_phone' )
111
- )
112
- );
113
- learn_press_send_json( $response );
114
- }
115
-
116
- /**
117
- * Checkout process
118
- *
119
- * @return array|mixed|void
120
- */
121
- public static function _request_checkout () {
122
- return LP()->checkout->process_checkout_handler();
123
- }
124
-
125
- /**
126
- * Enroll course
127
- *
128
- * @return bool
129
- * @throws Exception
130
- */
131
- public static function _request_enroll_course () {
132
- $course_id = learn_press_get_request( 'enroll-course' );
133
- if ( ! $course_id ) {
134
- throw new Exception( __( 'Invalid course', 'learnpress' ) );
135
- }
136
- $insert_id = LP()->user->enroll( $course_id );
137
-
138
- $response = array(
139
- 'result' => 'fail',
140
- 'redirect' => apply_filters( 'learn_press_enroll_course_failure_redirect_url', get_the_permalink( $course_id ) )
141
- );
142
-
143
- if ( $insert_id ) {
144
- $response['result'] = 'success';
145
- $response['redirect'] = apply_filters( 'learn_press_enrolled_course_redirect_url', get_the_permalink( $course_id ) );
146
- $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 );
147
- learn_press_add_message( $message );
148
- } else {
149
- $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 );
150
- learn_press_add_message( $message, 'error' );
151
- }
152
- if ( learn_press_is_ajax() ) {
153
- learn_press_send_json( $response );
154
- }
155
-
156
- if ( $response['redirect'] ) {
157
- wp_redirect( $response['redirect'] );
158
- exit();
159
- }
160
-
161
- return false;
162
- }
163
-
164
- /**
165
- * Request login in checkout process
166
- *
167
- * @return array
168
- */
169
- public static function _request_checkout_login () {
170
- $result = array(
171
- 'result' => 'success'
172
- );
173
- ob_start();
174
- if ( empty( $_REQUEST['user_login'] ) ) {
175
- $result['result'] = 'fail';
176
- learn_press_add_message( __( 'Please enter username', 'learnpress' ), 'error' );
177
- }
178
- if ( empty( $_REQUEST['user_password'] ) ) {
179
- $result['result'] = 'fail';
180
- learn_press_add_message( __( 'Please enter password', 'learnpress' ), 'error' );
181
- }
182
- if ( $result['result'] == 'success' ) {
183
- $creds = array();
184
- $creds['user_login'] = $_REQUEST['user_login'];
185
- $creds['user_password'] = $_REQUEST['user_password'];
186
- $creds['remember'] = true;
187
- $user = wp_signon( $creds, false );
188
- if ( is_wp_error( $user ) ) {
189
- $result['result'] = 'fail';
190
- learn_press_add_message( $user->get_error_message(), 'error' );
191
- } else {
192
- $result['redirect'] = learn_press_get_page_link( 'checkout' );
193
- }
194
- }
195
- learn_press_print_notices();
196
- $messages = ob_get_clean();
197
- if ( $result['result'] == 'fail' ) {
198
- $result['messages'] = $messages;
199
- }
200
-
201
- return $result;
202
- }
203
-
204
- /**
205
- * Request login in profile
206
- */
207
- public static function _request_login () {
208
- $data_str = learn_press_get_request( 'data' );
209
- $data = null;
210
- if ( $data_str ) {
211
- parse_str( $data_str, $data );
212
- }
213
-
214
- $user = wp_signon(
215
- array(
216
- 'user_login' => $data['log'],
217
- 'user_password' => $data['pwd'],
218
- 'remember' => isset( $data['rememberme'] ) ? $data['rememberme'] : false,
219
- ),
220
- is_ssl()
221
- );
222
-
223
- $error = is_wp_error( $user );
224
- $return = array(
225
- 'result' => $error ? 'error' : 'success',
226
- 'redirect' => ( ! $error && ! empty( $data['redirect_to'] ) ) ? $data['redirect_to'] : ''
227
- );
228
- if ( $error ) {
229
- $return['message'] = learn_press_get_message( $user->get_error_message() ? $user->get_error_message() : __( 'Please enter your username and/or password', 'learnpress' ) );
230
- } else {
231
- wp_set_current_user( $user->ID );
232
- $next = learn_press_get_request( 'next' );
233
- if ( $next == 'enroll-course' ) {
234
- $user = new LP_User( $user->ID );
235
- $checkout = false;
236
- if ( $cart_items = LP()->cart->get_items() ) {
237
- foreach ( $cart_items as $item ) {
238
- if ( $user->has_enrolled_course( $item['item_id'] ) ) {
239
- $checkout = $item['item_id'];
240
- } elseif ( $user->has_purchased_course( $item['item_id'] ) ) {
241
- $checkout = $item['item_id'];
242
- $user->enroll( $item['item_id'] );
243
- }
244
- if ( $checkout ) {
245
- LP()->cart->remove_item( $checkout );
246
- $return['redirect'] = get_the_permalink( $checkout );
247
- learn_press_add_message( sprintf( __( 'Welcome back, %s. You\'ve already enrolled this course', 'learnpress' ), $user->user->display_name ) );
248
- break;
249
- }
250
- }
251
- }
252
- if ( $checkout === false ) {
253
- add_filter( 'learn_press_checkout_success_result', '_learn_press_checkout_auto_enroll_free_course', 10, 2 );
254
- $checkout = LP()->checkout()->process_checkout();
255
- } else {
256
- }
257
-
258
- return;
259
- }
260
- $return['message'] = learn_press_get_message( sprintf( __( 'Welcome back, %s! Redirecting...', 'learnpress' ), learn_press_get_profile_display_name( $user ) ) );
261
- }
262
- learn_press_send_json( $return );
263
- }
264
-
265
- /**
266
- * Request add-to-cart a course
267
- */
268
- public static function _request_add_to_cart () {
269
- $cart = learn_press_get_cart();
270
- $course_id = learn_press_get_request( 'purchase-course' );
271
-
272
- $cart->add_to_cart( $course_id );
273
- $return = array(
274
- 'result' => 'success',
275
- 'redirect' => learn_press_get_checkout_url()
276
- );
277
- if ( learn_press_is_ajax() ) {
278
- learn_press_send_json( $return );
279
- } else {
280
- wp_redirect( $return['redirect'] );
281
- }
282
- }
283
-
284
- /**
285
- * Request finish course
286
- */
287
- public static function _request_finish_course () {
288
- $nonce = learn_press_get_request( 'security' );
289
- $course_id = absint( learn_press_get_request( 'id' ) );
290
- $user = learn_press_get_current_user();
291
-
292
- $course = LP_Course::get_course( $course_id );
293
-
294
- $nonce_action = sprintf( 'learn-press-finish-course-%d-%d', $course_id, $user->id );
295
- if ( ! $user->id || ! $course || ! wp_verify_nonce( $nonce, $nonce_action ) ) {
296
- wp_die( __( 'Access denied!', 'learnpress' ) );
297
- }
298
-
299
- $finished = $user->finish_course( $course_id );
300
-
301
- $response = array();
302
-
303
- if ( $finished ) {
304
- learn_press_add_message( sprintf( __( 'You have finished this course "%s"', 'learnpress' ), $course->get_title() ) );
305
- $response['redirect'] = get_the_permalink( $course_id );
306
-
307
- $response['result'] = 'success';
308
- } else {
309
- $response['message'] = __( 'Error! You cannot finish this course. Please contact your administrator for more information.', 'learnpress' );
310
- $response['result'] = 'error';
311
- }
312
-
313
- learn_press_send_json( $response );
314
- }
315
-
316
- /**
317
- * Request complete an item
318
- */
319
- public static function _request_complete_item () {
320
- $user = learn_press_get_current_user();
321
- $id = learn_press_get_request( 'id' );
322
- $course_id = ! empty( $_REQUEST['course_id'] ) ? $_REQUEST['course_id'] : get_the_ID();
323
- $type = learn_press_get_request( 'type' );
324
- $security = learn_press_get_request( 'security' );
325
- $response = array();
326
- if ( ! wp_verify_nonce( $security, sprintf( 'complete-item-%d-%d-%d', $user->id, $course_id, $id ) ) ) {
327
- $response['result'] = 'fail';
328
- $response['message'] = __( 'Bad request!', 'learnpress' );
329
- } else {
330
- if ( $type == 'lp_lesson' ) {
331
- $results = $user->complete_lesson( $id, $course_id );
332
-
333
- if ( is_wp_error( $results ) ) {
334
- learn_press_add_message( __( 'Error while completing lesson.', 'learnpress' ) );
335
- } elseif ( $results !== false ) {
336
-
337
- $message = __( 'You have completed lesson', 'learnpress' );
338
- $auto_next = LP()->settings->get( 'auto_redirect_next_lesson' );
339
- $time = LP()->settings->get( 'auto_redirect_time' );
340
- $time = absint( $time );
341
-
342
- if ( $auto_next === 'yes' ) {
343
- ob_start();
344
- ?>
345
- <script type="text/javascript">
346
-
347
- 'use strict';
348
-
349
- (function ($) {
350
-
351
- $(document).ready(function () {
352
-
353
- var $nextItem = $('.button-load-item', '#lp-navigation .nav-next'),
354
- $message = $('.learn-press-auto-redirect-next-item'),
355
- time = <?php echo esc_js( $time ); ?>;
356
-
357
- if ($nextItem.length) {
358
-
359
- time = !parseInt(time) ? 0 : parseInt(time);
360
-
361
- if (!time) {
362
- $nextItem.trigger('click');
363
- }
364
- else {
365
- if ($message.length) {
366
-
367
- $message.addClass('active');
368
-
369
- var $count = $('.learn-press-countdown', $message),
370
- interval = setInterval(function () {
371
-
372
- if (time <= 1) {
373
- clearInterval(interval);
374
- $nextItem.trigger('click');
375
- }
376
- else {
377
- $count.text(--time);
378
- }
379
-
380
- }, 1000);
381
-
382
- $('.learnpress-dismiss-notice', $message).on('click', function () {
383
-
384
- clearInterval(interval);
385
-
386
- $message.hide(200, function () {
387
- $(this).remove();
388
- });
389
-
390
- });
391
- }
392
- }
393
-
394
- }
395
- });
396
-
397
- })(jQuery);
398
- </script>
399
- <?php
400
- $message .= ob_get_contents();
401
- ob_get_clean();
402
- }
403
- learn_press_add_message( $message );
404
-
405
- }
406
-
407
- } else {
408
- do_action( 'learn_press_user_request_complete_item', $_REQUEST );
409
- }
410
- }
411
- wp_redirect( learn_press_get_current_url() );
412
- die();
413
- }
414
-
415
- /**
416
- * Request load item content
417
- */
418
- public static function _request_load_item () {
419
- global $wpdb;
420
- $user = learn_press_get_current_user();
421
- $item_id = learn_press_get_request( 'id' );
422
- $course_id = get_the_ID();
423
- // Ensure that user can view course item
424
- $can_view_item = $user->can( 'view-item', $item_id, $course_id );
425
- if ( $can_view_item ) {
426
- // Update user item if it's not updated
427
- if ( ! $user->get_item_status( $item_id, $course_id ) ) {
428
- $item_type = learn_press_get_request( 'type' );
429
- if ( ! $item_type ) {
430
- $item_type = get_post_type( $item_id );
431
- }
432
- if ( apply_filters( 'learn_press_insert_user_item_data', true, $item_id, $course_id ) && $can_view_item != 'preview' ) {
433
- $insert = $wpdb->insert(
434
- $wpdb->prefix . 'learnpress_user_items',
435
- apply_filters(
436
- 'learn_press_user_item_data',
437
- array(
438
- 'user_id' => get_current_user_id(),
439
- 'item_id' => learn_press_get_request( 'id' ),
440
- 'item_type' => $item_type,
441
- 'start_time' => $item_type == 'lp_lesson' ? current_time( 'mysql' ) : '0000-00-00 00:00:00',
442
- 'end_time' => '0000-00-00 00:00:00',
443
- 'status' => $item_type == 'lp_lesson' ? 'started' : 'viewed',
444
- 'ref_id' => $course_id,
445
- 'ref_type' => 'lp_course',
446
- 'parent_id' => $user->get_course_history_id( $course_id )
447
- )
448
- ),
449
- array(
450
- '%d',
451
- '%d',
452
- '%s',
453
- '%s',
454
- '%s',
455
- '%s',
456
- '%d',
457
- '%s'
458
- )
459
- );
460
- print_r( $wpdb );
461
- $user_item_id = $wpdb->insert_id;
462
- }
463
- }
464
- // display content item
465
- learn_press_get_template( 'single-course/content-item.php' );
466
- } else {
467
- // display message
468
- learn_press_get_template( 'singe-course/content-protected.php' );
469
- }
470
- die();
471
- }
472
-
473
- /**
474
- * die();
475
- * Student take course
476
- * @return void
477
- */
478
- public static function take_course () {
479
- $payment_method = ! empty( $_POST['payment_method'] ) ? $_POST['payment_method'] : '';
480
- $course_id = ! empty( $_POST['course_id'] ) ? intval( $_POST['course_id'] ) : false;
481
- do_action( 'learn_press_take_course', $course_id, $payment_method );
482
- }
483
-
484
- /**
485
- * Load quiz question
486
- */
487
- public static function load_quiz_question () {
488
- $quiz_id = ! empty( $_REQUEST['quiz_id'] ) ? absint( $_REQUEST['quiz_id'] ) : 0;
489
- $question_id = ! empty( $_REQUEST['question_id'] ) ? absint( $_REQUEST['question_id'] ) : 0;
490
- $user_id = ! empty( $_REQUEST['user_id'] ) ? absint( $_REQUEST['user_id'] ) : 0;
491
- global $quiz;
492
- $quiz = LP_Quiz::get_quiz( $quiz_id );
493
- LP()->quiz = $quiz;
494
- do_action( 'learn_press_load_quiz_question', $question_id, $quiz_id, $user_id );
495
- $user = learn_press_get_current_user();
496
- if ( $user->id != $user_id ) {
497
- learn_press_send_json(
498
- array(
499
- 'result' => 'error',
500
- 'message' => __( 'Load question error. Try again!', 'learnpress' )
501
- )
502
- );
503
- }
504
- if ( ! $quiz_id || ! $question_id ) {
505
- learn_press_send_json(
506
- array(
507
- 'result' => 'error',
508
- 'message' => __( 'Something is wrong. Try again!', 'learnpress' )
509
- )
510
- );
511
- }
512
- if ( $question = LP_Question_Factory::get_question( $question_id ) ) {
513
- $quiz->current_question = $question;
514
-
515
- ob_start();
516
- if ( $progress = $user->get_quiz_progress( $quiz->id ) ) {
517
- learn_press_update_user_quiz_meta( $progress->history_id, 'current_question', $question_id );
518
- }
519
- $question_answers = $user->get_question_answers( $quiz->id, $question_id );
520
- $question->render( array( 'answered' => $question_answers ) );
521
-
522
- $content = ob_get_clean();
523
- learn_press_send_json(
524
- apply_filters( 'learn_press_load_quiz_question_result_data', array(
525
- 'result' => 'success',
526
- 'permalink' => learn_press_get_user_question_url( $quiz_id, $question_id ),
527
- 'question' => array(
528
- 'content' => $content
529
- )
530
- )
531
- )
532
- );
533
- }
534
- }
535
-
536
- /**
537
- * Finish quiz
538
- */
539
- public static function finish_quiz () {
540
- $user = learn_press_get_current_user();
541
- $quiz_id = learn_press_get_request( 'quiz_id' );
542
- $user->finish_quiz( $quiz_id );
543
- $response = array(
544
- 'redirect' => get_the_permalink( $quiz_id )
545
- );
546
- learn_press_send_json( $response );
547
- }
548
-
549
- /**
550
- * Retake a quiz
551
- */
552
- public static function retake_quiz () {
553
- die( __FUNCTION__ );
554
- // verify nonce
555
- if ( ! wp_verify_nonce( learn_press_get_request( 'nonce' ), 'retake-quiz' ) ) {
556
- learn_press_send_json(
557
- array(
558
- 'result' => 'fail',
559
- 'message' => __( 'Something went wrong. Please try again!', 'learnpress' )
560
- )
561
- );
562
- }
563
- $quiz_id = learn_press_get_request( 'quiz_id' );
564
- $user = learn_press_get_current_user();
565
- $response = $user->retake_quiz( $quiz_id );
566
- learn_press_send_json( $response );
567
- }
568
-
569
- /**
570
- * Load lesson content
571
- */
572
- public static function load_lesson_content () {
573
- learn_press_debug( $_REQUEST );
574
- global $post;
575
- $lesson_id = $_POST['lesson_id'];
576
- $title = get_the_title( $lesson_id );
577
- $post = get_post( $lesson_id );
578
- $content = $post->post_content;
579
- $content = apply_filters( 'the_content', $content );
580
- printf(
581
- '<h3>%s</h3>
582
- %s
583
- <button class="complete-lesson-button">Complete Lesson</button>',
584
- $title,
585
- $content
586
- );
587
- die;
588
- }
589
-
590
- /**
591
- * Complete lesson
592
- */
593
- public static function complete_lesson () {
594
- $nonce = learn_press_get_request( 'nonce' );
595
- $item_id = learn_press_get_request( 'id' );
596
- $course_id = learn_press_get_request( 'course_id' );
597
- $post = get_post( $item_id );
598
- $user = learn_press_get_current_user();
599
- $course = LP_Course::get_course( $course_id );
600
- $response = array(
601
- 'result' => 'success'
602
- );
603
- $nonce_action = sprintf( 'learn-press-complete-%s-%d-%d-%d', $post->post_type, $post->ID, $course->id, $user->id );
604
- // security check
605
- if ( ! $post || ( $post && ! wp_verify_nonce( $nonce, $nonce_action ) ) ) {
606
- $response['result'] = 'error';
607
- $response['message'] = __( 'Error! Invalid lesson or security checked failure', 'learnpress' );
608
- }
609
-
610
- if ( $response['result'] == 'success' ) {
611
- $result = $user->complete_lesson( $item_id );
612
- if ( ! is_wp_error( $result ) ) {
613
- $can_finish = $user->can_finish_course( $course_id );
614
- $response['button_text'] = '<span class="dashicons dashicons-yes"></span>' . __( 'Completed', 'learnpress' );
615
- $response['course_result'] = round( $result * 100, 0 );
616
- $response['can_finish'] = $can_finish;
617
- $response['next_item'] = $course->get_next_item( $item_id );
618
-
619
- ob_start();
620
- if ( $can_finish ) {
621
- learn_press_display_message( __( 'Congratulations! You have completed this lesson and you can finish course.', 'learnpress' ) );
622
- } else {
623
- learn_press_display_message( __( 'Congratulations! You have completed this lesson.', 'learnpress' ) );
624
- }
625
- $response['message'] = ob_get_clean();
626
- } else {
627
- ob_start();
628
- learn_press_display_message( $result->get_error_message() );
629
- $response['message'] = ob_get_clean();
630
- $response['result'] = 'fail';
631
- }
632
- }
633
- learn_press_send_json( $response );
634
- }
635
-
636
- /**
637
- * Retake course action
638
- */
639
- public static function _request_retake_course () {
640
- $security = learn_press_get_request( 'security' );
641
- $course_id = learn_press_get_request( 'course_id' );
642
- $user = learn_press_get_current_user();
643
- $course = LP_Course::get_course( $course_id );
644
- $response = array(
645
- 'result' => 'error'
646
- );
647
- $security_action = sprintf( 'learn-press-retake-course-%d-%d', $course->id, $user->id );
648
- // security check
649
- if ( ! wp_verify_nonce( $security, $security_action ) ) {
650
- $response['message'] = __( 'Error! Invalid lesson or security checked failure', 'learnpress' );
651
- } else {
652
- if ( $user->can( 'retake-course', $course_id ) ) {
653
- if ( ! $result = $user->retake_course( $course_id ) ) {
654
- $response['message'] = __( 'Error!', 'learnpress' );
655
- } else {
656
- learn_press_add_message( sprintf( __( 'You have retaken course "%s"', 'learnpress' ), $course->get_title() ) );
657
- $response['result'] = 'success';
658
- $response['redirect'] = apply_filters( 'learn_press_retake_course_redirect', add_query_arg( 'retaken-course', $course_id, get_the_permalink( $course_id ) ) );
659
- }
660
- } else {
661
- $result['message'] = __( 'Error! You can not retake course', 'learnpress' );
662
- }
663
- }
664
- learn_press_send_json( $response );
665
- }
666
-
667
- public static function start_quiz () {
668
- $quiz_id = ! empty( $_REQUEST['quiz_id'] ) ? absint( $_REQUEST['quiz_id'] ) : 0;
669
- if ( ! $quiz_id ) {
670
- learn_press_send_json(
671
- array(
672
- 'result' => 'error',
673
- 'message' => __( 'The quiz ID is empty', 'learnpress' )
674
- )
675
- );
676
- }
677
- global $quiz;
678
-
679
- $quiz = LP_Quiz::get_quiz( $quiz_id );
680
-
681
- if ( ! $quiz->id || $quiz->id != $quiz_id ) {
682
- learn_press_send_json(
683
- array(
684
- 'result' => 'error',
685
- 'message' => __( 'Something is wrong! Please try again', 'learnpress' )
686
- )
687
- );
688
- }
689
- $user = learn_press_get_current_user();
690
- if ( $quiz->is_require_enrollment() && $user->is( 'guest' ) ) {
691
- learn_press_send_json(
692
- array(
693
- 'result' => 'error',
694
- 'message' => __( 'Please login to take this quiz', 'learnpress' )
695
- )
696
- );
697
- }
698
- $user->set_quiz( $quiz );
699
-
700
- switch ( strtolower( $user->get_quiz_status() ) ) {
701
- case 'completed':
702
- learn_press_send_json(
703
- array(
704
- 'result' => 'error',
705
- 'message' => __( 'You have completed this quiz', 'learnpress' ),
706
- 'data' => $user->get_quiz_result()
707
- )
708
- );
709
- break;
710
- case 'started':
711
- learn_press_send_json(
712
- array(
713
- 'result' => 'error',
714
- 'message' => __( 'You have started this quiz', 'learnpress' ),
715
- 'data' => array(
716
- 'status' => $user->get_quiz_status()
717
- )
718
- )
719
- );
720
- break;
721
- default:
722
- $result = $user->start_quiz();
723
- $current_question = ! empty( $result['current_question'] ) ? $result['current_question'] : $user->get_current_question_id( $quiz_id );
724
- learn_press_send_json(
725
- array(
726
- 'result' => 'success',
727
- 'data' => $result,
728
- 'question_url' => learn_press_get_user_question_url( $quiz_id, $current_question ),
729
- 'question_content' => LP_Question_Factory::fetch_question_content( $current_question )
730
- )
731
- );
732
- }
733
- die();
734
- }
735
- }
736
- }
737
- // Call class
738
  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,817 +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.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
- $ver = LEARNPRESS_VERSION;
207
-
208
- // global
209
- $scripts->add( 'learn-press-global', $default_path . 'js/global' . $suffix . '.js', $deps, $ver, 1 );
210
- $scripts->add( 'learn-press-jalerts', $default_path . 'js/jquery.alert' . $suffix . '.js', $deps, $ver, 1 );
211
-
212
- // frontend
213
- $scripts->add( 'learn-press-js', $default_path . 'js/frontend/learnpress' . $suffix . '.js', $deps, $ver, 1 );
214
- $scripts->add( 'learn-press-single-course', $default_path . 'js/frontend/single-course' . $suffix . '.js', $deps, $ver, 1 );
215
- $scripts->add( 'learn-press-course-quiz', $default_path . 'js/frontend/quiz' . $suffix . '.js', $deps, $ver, 1 );
216
- $scripts->add( 'learn-press-course-lesson', $default_path . 'js/frontend/lesson' . $suffix . '.js', $deps, $ver, 1 );
217
- $scripts->add( 'learn-press-enroll', $default_path . 'js/frontend/enroll' . $suffix . '.js', $deps, $ver, 1 );
218
- $scripts->add( 'learn-press-timer', $default_path . 'js/jquery.timer' . $suffix . '.js', $deps, $ver, 1 );
219
- $scripts->add( 'learn-press-checkout', $default_path . 'js/frontend/checkout' . $suffix . '.js', $deps, $ver, 1 );
220
- $scripts->add( 'learn-press-become-teacher', $default_path . 'js/frontend/become-teacher' . $suffix . '.js', $deps, $ver, 1 );
221
- $scripts->add( 'learn-press-profile', $default_path . 'js/frontend/profile' . $suffix . '.js', array( 'jquery', 'backbone', 'utils', 'plupload', 'jquery-ui-slider', 'jquery-ui-draggable' ), $ver, 1 );
222
-
223
- // admin
224
- $scripts->add( 'learn-press-admin', $default_path . 'js/admin/admin' . $suffix . '.js', $deps, $ver, 1 );
225
- $scripts->add( 'learn-press-admin-settings', $default_path . 'js/admin/settings' . $suffix . '.js', $deps, $ver, 1 );
226
- $scripts->add( 'learn-press-mb-question', $default_path . 'js/admin/meta-box-question' . $suffix . '.js', $deps, $ver, 1 );
227
- $scripts->add( 'learn-press-mb-course', $default_path . 'js/admin/meta-box-course' . $suffix . '.js', $deps, $ver, 1 );
228
- $scripts->add( 'learn-press-mb-quiz', $default_path . 'js/admin/meta-box-quiz' . $suffix . '.js', $deps, $ver, 1 );
229
- $scripts->add( 'learn-press-mb-order', $default_path . 'js/admin/meta-box-order' . $suffix . '.js', $deps, $ver, 1 );
230
- $scripts->add( 'learn-press-modal-search-items', $default_path . 'js/admin/modal-search-items' . $suffix . '.js', array( 'learn-press-global' ), $ver, 1 );
231
- $scripts->add( 'learn-press-order', $default_path . 'js/admin/meta-box-order' . $suffix . '.js', $deps, $ver, 1 );
232
- //$scripts->add( 'learn-press-statistics-select2', '/' . LP_WP_CONTENT . '/plugins/learnpress/inc/libraries/meta-box/js/select2/select2.min.js', $deps, false, 1 );
233
-
234
- $scripts->add( 'learn-press-select2', '/' . LP_WP_CONTENT . '/plugins/learnpress/inc/libraries/meta-box/js/select2/select2.min.js', $deps, $ver, 1 );
235
-
236
- // upgrade
237
- $scripts->add( 'learn-press-upgrade', '/' . LP_WP_CONTENT . '/plugins/learnpress/inc/updates/09/script' . $suffix . '.js', $deps, $ver, 1 );
238
-
239
- do_action_ref_array( 'learn_press_add_default_scripts', array( $scripts, $default_path, $suffix, $deps ) );
240
- }
241
-
242
- /**
243
- * Load default styles
244
- *
245
- * @param WP_Styles $styles
246
- */
247
- public static function default_styles( &$styles ) {
248
- if ( !defined( 'LEARNPRESS_VERSION' ) ) {
249
- define( 'LEARNPRESS_VERSION', '2.1.1' );
250
- }
251
-
252
- $develop_src = false !== strpos( LEARNPRESS_VERSION, '-src' );
253
-
254
- if ( !defined( 'SCRIPT_DEBUG' ) ) {
255
- define( 'SCRIPT_DEBUG', $develop_src );
256
- }
257
- if ( !$guessurl = site_url() ) {
258
- $guessed_url = true;
259
- $guessurl = wp_guess_url();
260
- }
261
- $default_dirs = array( '/wp-admin/css/', '/wp-includes/css/' );
262
- $styles->base_url = $guessurl;
263
- $styles->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : '';
264
- $styles->default_version = get_bloginfo( 'version' );
265
- $styles->default_dirs[] = $default_dirs;
266
-
267
- self::add_default_styles( $styles );
268
- }
269
-
270
- /**
271
- * @param WP_Styles $styles
272
- */
273
- public static function add_default_styles( &$styles ) {
274
- $default_path = plugins_url( 'learnpress/assets/' );
275
- $suffix = '';
276
- $deps = array( 'dashicons' );
277
- $ver = LEARNPRESS_VERSION;
278
- // global
279
- $styles->add( 'learn-press-global', $default_path . 'css/global' . $suffix . '.css', $deps, $ver );
280
-
281
- // admin
282
- $styles->add( 'learn-press-admin', $default_path . 'css/admin/admin' . $suffix . '.css', null, $ver );
283
- $styles->add( 'learn-press-jquery.ui.datepicker', $default_path . 'css/admin/jquery.ui.datepicker' . $suffix . '.css', null, $ver );
284
- $styles->add( 'learn-press-jquery.ui.theme', $default_path . 'css/admin/jquery.ui.theme' . $suffix . '.css', null, $ver );
285
- $styles->add( 'learn-press-jquery.ui.core', $default_path . 'css/admin/jquery.ui.core' . $suffix . '.css', null, $ver );
286
- $styles->add( 'learn-press-jquery.ui.slider', $default_path . 'css/admin/jquery.ui.slider' . $suffix . '.css', null, $ver );
287
- $styles->add( 'learn-press-mb-course', $default_path . 'css/admin/meta-box-course' . $suffix . '.css', null, $ver );
288
- //$styles->add( 'learn-press-mb-question', $default_path . 'css/admin/meta-box-question' . $suffix . '.css', null, $ver );
289
- $styles->add( 'learn-press-mb-order', $default_path . 'css/admin/meta-box-order' . $suffix . '.css', null, $ver );
290
- $styles->add( 'learn-press-jalerts', $default_path . 'css/jalert' . $suffix . '.css', null, $ver );
291
- //$styles->add( 'learn-press-statistics-select2', '/' . LP_WP_CONTENT . '/plugins/learnpress/inc/libraries/meta-box/css/select2/select2.css' );
292
- $styles->add( 'learn-press-select2', '/' . LP_WP_CONTENT . '/plugins/learnpress/inc/libraries/meta-box/css/select2/select2.css' );
293
-
294
-
295
- // frontend
296
- $styles->add( 'learn-press-style', $default_path . 'css/learnpress.css', $deps, $ver );
297
- do_action_ref_array( 'learn_press_add_default_styles', array( $styles, $default_path, $suffix ) );
298
-
299
- }
300
-
301
- /**
302
- * register script
303
- *
304
- * @param string $handle
305
- * @param string $src
306
- * @param array $deps
307
- * @param string $version
308
- * @param boolean $in_footer
309
- */
310
- public static function add_script( $handle, $src, $deps = array( 'jquery' ), $version = LEARNPRESS_VERSION, $in_footer = true ) {
311
- self::$scripts[] = $handle;
312
- wp_register_script( $handle, $src, $deps, $version, $in_footer );
313
- }
314
-
315
- /**
316
- * register style
317
- *
318
- * @param string $handle
319
- * @param string $src
320
- * @param array $deps
321
- * @param string $version
322
- * @param string $media
323
- */
324
- public static function add_style( $handle, $src, $deps = array(), $version = LEARNPRESS_VERSION, $media = 'all' ) {
325
- self::$styles[] = $handle;
326
- wp_register_style( $handle, $src, $deps, $version, $media );
327
- }
328
-
329
- /**
330
- * enqueue script
331
- *
332
- * @param string $handle
333
- * @param string $src
334
- * @param array $deps
335
- * @param string $version
336
- * @param boolean $in_footer
337
- */
338
- public static function enqueue_script( $handle, $src = '', $deps = array( 'jquery' ), $version = LEARNPRESS_VERSION, $in_footer = true ) {
339
- global $wp_scripts;
340
-
341
- if ( is_array( $handle ) ) {
342
- foreach ( $handle as $_handle ) {
343
- self::enqueue_script( $_handle, $src, $deps, $version, $in_footer );
344
- }
345
- } else {
346
- if ( !in_array( $handle, self::$scripts ) && $src ) {
347
- self::add_script( $handle, $src, $deps, $version, $in_footer );
348
- }
349
- self::$_enqueue_scripts[$handle] = func_get_args();
350
- if ( $deps ) {
351
- foreach ( $deps as $dep ) {
352
- self::add_script_concat( $dep );
353
- }
354
- }
355
- self::add_script_concat( $handle );
356
- }
357
- }
358
-
359
- /**
360
- * @param $handle
361
- */
362
- public static function add_script_concat( $handle ) {
363
- global $wp_scripts;
364
- if ( !$wp_scripts ) {
365
- return;
366
- }
367
- if ( empty( $wp_scripts->lp_script_concat ) ) {
368
- $wp_scripts->lp_script_concat = array();
369
- }
370
- if ( strpos( $handle, 'learn-press-' ) !== false ) {
371
- $concat = str_replace( 'learn-press-', '', $handle );
372
- if ( !in_array( $concat, $wp_scripts->lp_script_concat ) ) {
373
- $wp_scripts->lp_script_concat[] = $concat;
374
- }
375
- }
376
- }
377
-
378
- /**
379
- * @param $handle
380
- */
381
- public static function add_style_concat( $handle ) {
382
- global $wp_styles;
383
- if ( !$wp_styles ) {
384
- return;
385
- }
386
- if ( empty( $wp_styles->lp_style_concat ) ) {
387
- $wp_styles->lp_style_concat = array();
388
- }
389
- if ( strpos( $handle, 'learn-press-' ) !== false ) {
390
- $concat = str_replace( 'learn-press-', '', $handle );
391
- if ( !in_array( $concat, $wp_styles->lp_style_concat ) ) {
392
- $wp_styles->lp_style_concat[] = $concat;
393
- }
394
- }
395
- }
396
-
397
- /**
398
- * enqueue style
399
- *
400
- * @param string $handle
401
- * @param string $src
402
- * @param array $deps
403
- * @param string $version
404
- * @param string $media
405
- */
406
- public static function enqueue_style( $handle, $src = '', $deps = array(), $version = LEARNPRESS_VERSION, $media = 'all' ) {
407
- if ( is_array( $handle ) ) {
408
- foreach ( $handle as $_handle ) {
409
- self::enqueue_style( $_handle, $src, $deps, $version, $media );
410
- }
411
- } else {
412
- if ( !in_array( $handle, self::$styles ) && $src ) {
413
- self::add_style( $handle, $src, $deps, $version, $media );
414
- }
415
- self::$_enqueue_styles[$handle] = func_get_args();
416
- if ( $deps ) {
417
- foreach ( $deps as $dep ) {
418
- self::add_style_concat( $dep );
419
- }
420
- }
421
- self::add_style_concat( $handle );
422
- }
423
- }
424
-
425
- /**
426
- * add translate text
427
- *
428
- * @param string
429
- * @param array $localize
430
- * @param string
431
- */
432
- public static function add_localize( $key, $localize = null, $handle = '' ) {
433
- if ( !$handle ) {
434
- $handle = is_admin() ? 'learn-press-admin' : 'learn-press-js';
435
- }
436
- if ( empty( self::$wp_localize_scripts[$handle] ) ) {
437
- self::$wp_localize_scripts[$handle] = array();
438
- }
439
- if ( is_array( $key ) ) {
440
- self::$wp_localize_scripts[$handle] = array_merge( self::$wp_localize_scripts[$handle], $key );
441
- } elseif ( is_string( $key ) && strlen( $key ) ) {
442
- self::$wp_localize_scripts[$handle][$key] = $localize;
443
- }
444
- }
445
-
446
- /**
447
- * Add js param
448
- *
449
- * @param string
450
- * @param array
451
- * @param string
452
- * @param $name
453
- */
454
- public static function add_param( $key, $param = null, $handle = 'learn-press-js', $name = null ) {
455
- if ( !$handle ) {
456
- $handle = 'learn-press-js';
457
- }
458
- if ( is_array( $handle ) ) {
459
- foreach ( $handle as $h ) {
460
- self::add_param( $key, $param, $h, $name );
461
- }
462
- return;
463
- }
464
- if ( empty( $name ) ) {
465
- $name = $handle;
466
- }
467
- if ( empty( self::$wp_params[$handle] ) ) {
468
- self::$wp_params[$handle] = array( $name => array() );
469
- }
470
- if ( empty( self::$wp_params[$handle][$name] ) ) {
471
- self::$wp_params[$handle][$name] = array();
472
- }
473
-
474
- if ( is_array( $key ) ) {
475
- self::$wp_params[$handle][$name] = array_merge( self::$wp_params[$handle][$name], $key );
476
- } elseif ( is_string( $key ) && strlen( $key ) ) {
477
- self::$wp_params[$handle][$name][$key] = $param;
478
- }
479
- }
480
-
481
- public static function add_var( $name, $value, $handle = 'learn-press-global' ) {
482
- if ( is_array( $handle ) ) {
483
- foreach ( $handle as $h ) {
484
- self::add_var( $name, $value, $h );
485
- }
486
- return;
487
- }
488
- if ( empty( self::$js_vars[$handle] ) ) {
489
- self::$js_vars[$handle] = array();
490
- }
491
- self::$js_vars[$handle][$name] = $value;
492
- }
493
-
494
- /**
495
- * @param $code
496
- * @param string $handle
497
- */
498
- public static function add_script_tag( $code, $handle = '' ) {
499
- if ( empty( self::$wp_script_codes[$handle] ) ) {
500
- self::$wp_script_codes[$handle] = '';
501
- }
502
- self::$wp_script_codes[$handle] .= preg_replace( '!</?script(.*)>!', '', $code );
503
- }
504
-
505
- /**
506
- * wp_assets
507
- */
508
- public static function wp_assets() {
509
- do_action( 'learn_press_print_assets', is_admin() );
510
- }
511
-
512
- /**
513
- * localize_printed_scripts
514
- */
515
- public static function localize_printed_scripts() {
516
- $has_localized = !empty( self::$localized );
517
- $has_params = !empty( self::$param_printed );
518
- $has_vars = !empty( self::$js_vars );
519
- if ( $has_localized || $has_params || $has_vars ) {
520
- echo "<script type='text/javascript'>\n"; // CDATA and type='text/javascript' is not needed for HTML 5
521
- echo "/* <![CDATA[ */\n";
522
- if ( $has_localized ) {
523
- if ( self::$wp_localize_scripts ) {
524
- echo "\n/* LearnPress Localized */\n";
525
- foreach ( self::$localized as $handle => $src ) {
526
- if ( !empty( self::$wp_localize_scripts[$handle] ) ) {
527
- $name = str_replace( '-', '_', $handle ) . '_localize';
528
- echo "var {$name} = " . json_encode( self::$wp_localize_scripts[$handle] ) . ";\n";
529
- }
530
- }
531
- }
532
- }
533
-
534
- if ( $has_params ) {
535
- $groups = array();
536
-
537
- foreach ( self::$param_printed as $handle ) {
538
- if ( !empty( self::$wp_params[$handle] ) ) {
539
- foreach ( self::$wp_params[$handle] as $name => $value ) {
540
- $name = str_replace( '-', '_', $name );
541
- $value = (array) ( $value );
542
- if ( empty( $groups[$name] ) ) {
543
- $groups[$name] = $value;
544
- } else {
545
- $groups[$name] = array_merge( $groups[$name], $value );
546
- }
547
- }
548
- }
549
- }
550
- //print_r($groups);
551
- if ( $groups ) {
552
- echo "\n/* LearnPress Params */\n";
553
- foreach ( $groups as $name => $code ) {
554
- echo "var {$name} = " . wp_json_encode( $code ) . ";\n";
555
- }
556
- }
557
- }
558
-
559
-
560
- if ( $has_localized ) {
561
- if ( self::$js_vars ) {
562
- echo "\n/* Custom vars */\n";
563
- $abort = array();
564
- foreach ( self::$localized as $handle => $src ) {
565
- if ( !empty( self::$js_vars[$handle] ) ) {
566
- foreach ( self::$js_vars[$handle] as $name => $var ) {
567
- if ( in_array( $name, $abort ) ) {
568
- continue;
569
- }
570
- $abort[] = $name;
571
- echo "var {$name} = " . maybe_serialize( $var ) . ";\n";
572
- }
573
- }
574
- }
575
- }
576
- if ( self::$wp_script_codes ) {
577
- echo "\n/* LearnPress Custom Scripts */\n ( typeof jQuery != 'undefined' ) && jQuery(function($){\n";
578
- foreach ( self::$localized as $handle => $src ) {
579
- if ( !empty( self::$wp_script_codes[$handle] ) ) {
580
- echo( self::$wp_script_codes[$handle] );
581
- }
582
- }
583
- echo "\n});\n";
584
- }
585
- }
586
-
587
- echo "/* ]]> */\n";
588
- echo "</script>\n";
589
- }
590
- }
591
-
592
- public static function remove_script( $handle ) {
593
- if ( isset( self::$_enqueue_scripts[$handle] ) ) {
594
- unset( self::$_enqueue_scripts[$handle] );
595
- }
596
- wp_deregister_script( $handle );
597
- }
598
-
599
- public static function remove_style( $handle ) {
600
- if ( isset( self::$_enqueue_styles[$handle] ) ) {
601
- unset( self::$_enqueue_styles[$handle] );
602
- }
603
- wp_deregister_style( $handle );
604
-
605
- }
606
-
607
- /**
608
- * _enqueue_scripts
609
- */
610
- public static function _enqueue_scripts() {
611
- do_action( 'learn_press_enqueue_scripts', __CLASS__ );
612
- if ( strpos( current_action(), 'enqueue_scripts' ) === false ) {
613
- return;
614
- }
615
- if ( !empty( self::$_enqueue_scripts ) ) {
616
- foreach ( self::$_enqueue_scripts as $handle => $args ) {
617
- call_user_func_array( 'wp_enqueue_script', array( $handle ) );
618
- }
619
- }
620
- if ( !empty( self::$_enqueue_styles ) ) {
621
- foreach ( self::$_enqueue_styles as $handle => $args ) {
622
- call_user_func_array( 'wp_enqueue_style', array( $handle ) );
623
- }
624
- }
625
- }
626
-
627
- /**
628
- * Do not load script
629
- */
630
- public function unload_script_tag( $tag, $handle, $src ) {
631
- if ( strpos( $handle, 'learn-press-' ) !== false && strpos( $src, '/learnpress/' ) !== false ) {
632
- return false;
633
- }
634
- return $tag;
635
- }
636
-
637
- /**
638
- * include_script_file
639
- */
640
- public function include_script_file() {
641
- global $wp_scripts, $compress_scripts;
642
-
643
- $zip = $compress_scripts ? 1 : 0;
644
- if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP )
645
- $zip = 'gzip';
646
-
647
- if ( !empty( $wp_scripts->lp_script_concat ) && $concat = join( ',', $wp_scripts->lp_script_concat ) ) {
648
- if ( !empty( $wp_scripts->print_code ) ) {
649
- echo "\n<script type='text/javascript'>\n";
650
- echo "/* <![CDATA[ */\n"; // not needed in HTML 5
651
- echo $wp_scripts->print_code;
652
- echo "/* ]]> */\n";
653
- echo "</script>\n";
654
- }
655
-
656
- $concat = str_split( $concat, 128 );
657
- $concat = 'load%5B%5D=' . implode( '&load%5B%5D=', $concat );
658
-
659
- $src = get_site_url() . "/" . LP_WP_CONTENT . "/plugins/learnpress/assets/load-scripts.php?" . $concat . "&c={$zip}&ver=" . $wp_scripts->default_version;
660
- echo "<script type='text/javascript' src='" . esc_attr( $src ) . "'></script>\n";
661
- }
662
-
663
- if ( !empty( $wp_scripts->print_html ) )
664
- echo $wp_scripts->print_html;
665
- }
666
-
667
- /**
668
- * include_stylesheet_file
669
- */
670
- public function include_stylesheet_file() {
671
-
672
- if ( did_action( 'learn_press_included_style_file' ) ) {
673
- return;
674
- }
675
-
676
- global $compress_css;
677
-
678
- $wp_styles = wp_styles();
679
-
680
- $zip = $compress_css ? 1 : 0;
681
- if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP )
682
- $zip = 'gzip';
683
-
684
- if ( !empty( $wp_styles->lp_style_concat ) && $concat = join( ',', $wp_styles->lp_style_concat ) ) {
685
- $dir = $wp_styles->text_direction;
686
- $ver = $wp_styles->default_version;
687
-
688
- $concat = str_split( $concat, 128 );
689
- $concat = 'load%5B%5D=' . implode( '&load%5B%5D=', $concat );
690
-
691
- $href = get_site_url() . "/" . LP_WP_CONTENT . "/plugins/learnpress/assets/load-styles.php?" . $concat . "&c={$zip}&ver=" . $ver;
692
- echo "<link rel='stylesheet' href='" . esc_attr( $href ) . "' type='text/css' media='all' />\n";
693
-
694
- if ( !empty( $wp_styles->print_code ) ) {
695
- echo "<style type='text/css'>\n";
696
- echo $wp_styles->print_code;
697
- echo "\n</style>\n";
698
- }
699
- }
700
-
701
- if ( !empty( $wp_styles->print_html ) )
702
- echo $wp_styles->print_html;
703
- do_action( 'learn_press_included_style_file' );
704
- }
705
-
706
- /**
707
- * Load assets
708
- */
709
- public function load_scripts() {
710
- $user = learn_press_get_course_user();
711
- if ( is_admin() ) {
712
- global $pagenow;
713
- $screen = get_current_screen();
714
- $screen_id = $screen->id;
715
- $page_id = !empty( $_REQUEST['page'] ) ? $_REQUEST['page'] : '';
716
- self::enqueue_style( 'learn-press-admin' );
717
- if ( in_array( $screen_id, learn_press_get_screens() ) || in_array( $page_id, learn_press_get_admin_pages() ) ) {
718
- self::enqueue_style( 'learn-press-global' );
719
- self::enqueue_style( 'learn-press-jquery.ui.datepicker' );
720
- self::enqueue_style( 'learn-press-jquery.ui.theme' );
721
- self::enqueue_style( 'learn-press-jquery.ui.core' );
722
- self::enqueue_style( 'learn-press-jquery.ui.slider' );
723
- self::enqueue_style( 'learn-press-icons' );
724
- self::enqueue_script( 'learn-press-global' );
725
- self::enqueue_script( 'learn-press-admin' );
726
- }
727
-
728
- foreach ( array( 'lp_course', 'lp_order', 'lp_quiz', 'lp_lesson', 'lp_question' ) as $post_type ) {
729
- if ( learn_press_is_post_type_screen( $post_type ) ) {
730
- $type = str_replace( 'lp_', '', $post_type );
731
- self::enqueue_style( "learn-press-mb-{$type}" );
732
- self::enqueue_script( "learn-press-mb-{$type}" );
733
- }
734
- }
735
-
736
- if ( learn_press_is_post_type_screen( array( 'lp_quiz' ) ) ) {
737
- self::enqueue_style( 'learn-press-mb-question' );
738
- self::enqueue_script( 'learn-press-mb-question' );
739
- }
740
-
741
- if ( learn_press_is_post_type_screen( array( 'lp_course', 'lp_quiz', 'lp_order' ) ) ) {
742
- self::enqueue_style( 'learn-press-modal-search-items' );
743
- self::enqueue_script( 'learn-press-modal-search-items' );
744
- }
745
-
746
- if ( $screen_id === 'learnpress_page_learn-press-settings' || $screen_id === 'dashboard' ) {
747
- LP_Assets::enqueue_style( 'learn-press-admin' );
748
- LP_Assets::enqueue_style( 'learn-press-select2' );
749
-
750
- LP_Assets::enqueue_script( 'learn-press-select2' );
751
- LP_Assets::enqueue_script( 'learn-press-admin-settings', LP()->plugin_url( 'assets/js/admin/settings.js' ) );
752
- }
753
-
754
- if ( $pagenow === 'edit.php' && $screen_id === 'edit-lp_course' ) {
755
- LP_Assets::enqueue_script( 'learn-press-duplicate-course', LP()->plugin_url( 'assets/js/admin/duplicate-course.js' ) );
756
- }
757
-
758
- if ( $pagenow === 'post.php' && $screen_id === 'lp_quiz' ) {
759
- self::enqueue_style( 'learn-press-jalerts' );
760
- self::enqueue_script( 'learn-press-jalerts' );
761
- }
762
-
763
- if ( 'learnpress_page_learn-press-statistics' === $screen_id ) {
764
- self::enqueue_script( 'learn-press-statistics-select2' );
765
- self::enqueue_style( 'learn-press-statistics-select2' );
766
- }
767
- do_action( 'learn_press_admin_load_scripts' );
768
- return;
769
- }
770
-
771
- // global
772
- self::enqueue_style( 'learn-press-icon' );
773
- self::enqueue_style( 'learn-press-jalerts' );
774
-
775
- // frontend
776
- if ( LP()->settings->get( 'load_css' ) == 'yes' || LP()->settings->get( 'load_css' ) == '' ) {
777
- self::enqueue_style( 'learn-press-style' );
778
- }
779
- self::enqueue_script( 'learn-press-jalerts' );
780
- self::enqueue_script( 'learn-press-global' );
781
- self::enqueue_script( 'learn-press-js' );
782
- if ( learn_press_is_course() ) {
783
- self::enqueue_script( 'learn-press-single-course' );
784
- self::enqueue_script( 'learn-press-course-quiz' );
785
- self::enqueue_script( 'learn-press-course-lesson' );
786
- if ( !$user->has_course_status( null, array( 'enrolled', 'finished' ) ) ) {
787
- self::enqueue_script( 'learn-press-enroll' );
788
- }
789
- }
790
- if ( learn_press_is_checkout() ) {
791
- self::enqueue_script( 'learn-press-checkout' );
792
- }
793
- self::enqueue_script( 'learn-press-become-teacher' );
794
-
795
- if ( learn_press_is_profile() ) {
796
- // Localize the script with new data
797
- $translation_array = array(
798
- 'confim_pass_not_match' => __( 'Password and confirmation password do not match', 'learnpress' ),
799
- 'msg_field_is_required' => __( 'This field is required', 'learnpress' )
800
- );
801
- wp_localize_script( 'learn-press-profile', 'lp_profile_translation', $translation_array );
802
-
803
-
804
- self::add_param( 'avatar_size', learn_press_get_avatar_thumb_size(), 'learn-press-profile', 'LP_Settings' );
805
-
806
- self::enqueue_script( 'learn-press-profile' );
807
- }
808
- do_action( 'learn_press_load_scripts' );
809
- }
810
-
811
- public static function url( $file = '' ) {
812
- return LP_PLUGIN_URL . "assets/{$file}";
813
- }
814
- }
815
-
816
- // Call class
817
  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-cache.php CHANGED
@@ -1,740 +1,634 @@
1
- <?php
2
-
3
- /**
4
- * Class LP_Cache
5
- *
6
- * Cache helper using functions of WP Cache with default group is learnpress
7
- *
8
- * @since 1.1
9
- */
10
- if ( !defined( 'ABSPATH' ) ) {
11
- exit;
12
- }
13
-
14
- class LP_Cache {
15
-
16
- /**
17
- * @var array
18
- */
19
- //protected static $_data = array();
20
-
21
- /**
22
- * @var string
23
- */
24
- protected static $_group = 'learnpress';
25
-
26
- /**
27
- * @var string
28
- */
29
- protected static $_quiz_status = 'user-quiz-status';
30
-
31
- /**
32
- * @var string
33
- */
34
- protected static $_lesson_status = 'user-lesson-status';
35
-
36
- /**
37
- * @var string
38
- */
39
- protected static $_count_retaken_quiz = 'user-count-retaken-quiz';
40
-
41
- /**
42
- * @var string
43
- */
44
- protected static $_completed_lessons = 'user-completed-lessons';
45
-
46
- /**
47
- * @var string
48
- */
49
- protected static $_evaluate_course_by_lesson = 'user-evaluate-course-by-lesson';
50
-
51
- /**
52
- * @var string
53
- */
54
- protected static $_user_completed_items = 'user-completed-items';
55
-
56
- /**
57
- * @var string
58
- */
59
- protected static $_user_enrolled_courses = 'user-enrolled-courses';
60
-
61
- /**
62
- * @var string
63
- */
64
- protected static $_user_finished_courses = 'user-finished-courses';
65
-
66
- /**
67
- * @var string
68
- */
69
- protected static $_user_course_info = 'user-course-info';
70
-
71
- /**
72
- * @var string
73
- */
74
- protected static $_course_curriculum = 'course-curriculum';
75
-
76
- /**
77
- * @var string
78
- */
79
- protected static $_course_item_statuses = 'course-item-statuses';
80
-
81
- /**
82
- * @var string
83
- */
84
- protected static $_quiz_questions = 'quiz-questions';
85
-
86
- /**
87
- * @var string
88
- */
89
- protected static $_quiz_results = 'quiz-results';
90
-
91
- /**
92
- * @var string
93
- */
94
- protected static $_quiz_params = 'quiz-params';
95
-
96
- /**
97
- * @var string
98
- */
99
- protected static $_post_names = 'post-names';
100
-
101
- /**
102
- * @var string
103
- */
104
- protected static $_user_course_order = 'user-course-order';
105
-
106
- /**
107
- * @var string
108
- */
109
- protected static $_user_profile_orders = 'user-profile-orders';
110
-
111
- /**
112
- * @var string
113
- */
114
- protected static $_user_item_id = 'user-item-id';
115
-
116
- /**
117
- * @var string
118
- */
119
- protected static $_quiz_history = 'user-quiz-history';
120
-
121
- /**
122
- * @var string
123
- */
124
- protected static $_quiz_grade = 'quiz-grade';
125
-
126
- /**
127
- * Set data to cache
128
- *
129
- * @param int|string $key
130
- * @param mixed $value
131
- * @param int $expire
132
- * @param int|string $group
133
- *
134
- * @return mixed
135
- */
136
- public static function set( $key, $value, $expire = 0, $group = 'learnpress' ) {
137
- return wp_cache_set( $key, $value, $group, $expire );
138
- }
139
-
140
- /**
141
- * Get data from cache
142
- *
143
- * @param int|string $key
144
- * @param boolean $force
145
- * @param $found
146
- * @param int|string $group
147
- *
148
- * @return bool|mixed
149
- */
150
- public static function get( $key, $force = false, &$found = 0, $group = 'learnpress' ) {
151
- return wp_cache_get( $key, $group, $force, $found );
152
- }
153
-
154
- /**
155
- * Helper function to set user quiz status to cache
156
- *
157
- * @param string $key
158
- * @param mixed $value
159
- *
160
- * @return array|bool|mixed
161
- */
162
- public static function set_quiz_status( $key, $value = false ) {
163
- if ( is_array( $key ) || is_object( $key ) ) {
164
- return wp_cache_set( self::$_quiz_status, $key, self::$_group );
165
- } else {
166
- return self::_set_cache( self::$_quiz_status, $key, $value );
167
- }
168
- }
169
-
170
- /**
171
- * Helper function to get user quiz status from cache
172
- *
173
- * @param bool|string $key
174
- * @param mixed $def
175
- *
176
- * @return array|bool|mixed
177
- */
178
- public static function get_quiz_status( $key = false, $def = false ) {
179
- return self::_get_cache( self::$_quiz_status, $key, $def );
180
- }
181
-
182
- /**
183
- * Helper function to set user lesson status to cache
184
- *
185
- * @param string $key
186
- * @param mixed $value
187
- *
188
- * @return array|bool|mixed
189
- */
190
- public static function set_lesson_status( $key, $value ) {
191
- return self::_set_cache( self::$_lesson_status, $key, $value );
192
- }
193
-
194
- /**
195
- * Helper function to get user lesson status from cache
196
- *
197
- * @param bool|string $key
198
- * @param mixed $def
199
- *
200
- * @return array|bool|mixed
201
- */
202
- public static function get_lesson_status( $key = false, $def = false ) {
203
- return self::_get_cache( self::$_lesson_status, $key, $def );
204
- }
205
-
206
- /**
207
- * Helper function to set user lesson status to cache
208
- *
209
- * @param string $key_or_value
210
- * @param mixed $value
211
- *
212
- * @return array|bool|mixed
213
- */
214
- public static function set_quiz_history( $key_or_value, $value = false ) {
215
- if ( func_num_args() == 1 ) {
216
- wp_cache_set( self::$_quiz_history, $key_or_value, self::$_group );
217
- return $key_or_value;
218
- }
219
- return self::_set_cache( self::$_quiz_history, $key_or_value, $value );
220
- }
221
-
222
- /**
223
- * Helper function to get user lesson status from cache
224
- *
225
- * @param bool|string $key
226
- * @param mixed $def
227
- *
228
- * @return array|bool|mixed
229
- */
230
- public static function get_quiz_history( $key = false, $def = false ) {
231
- return self::_get_cache( self::$_quiz_history, $key, $def );
232
- }
233
-
234
- /**
235
- * Helper function to set user lesson status to cache
236
- *
237
- * @param string $key
238
- * @param mixed $value
239
- *
240
- * @return array|bool|mixed
241
- */
242
- public static function set_count_retaken_quiz( $key, $value ) {
243
- return self::_set_cache( self::$_count_retaken_quiz, $key, $value );
244
- }
245
-
246
- /**
247
- * Helper function to get user lesson status from cache
248
- *
249
- * @param bool|string $key
250
- * @param mixed $def
251
- *
252
- * @return array|bool|mixed
253
- */
254
- public static function get_count_retaken_quiz( $key = false, $def = false ) {
255
- return self::_get_cache( self::$_count_retaken_quiz, $key, $def );
256
- }
257
-
258
- /**
259
- * Helper function to set user lesson status to cache
260
- *
261
- * @param string $key
262
- * @param mixed $value
263
- *
264
- * @return array|bool|mixed
265
- */
266
- public static function set_completed_lessons( $key, $value ) {
267
- return self::_set_cache( self::$_completed_lessons, $key, $value );
268
- }
269
-
270
- /**
271
- * Helper function to get user lesson status from cache
272
- *
273
- * @param bool|string $key
274
- * @param mixed $def
275
- *
276
- * @return array|bool|mixed
277
- */
278
- public static function get_completed_lessons( $key = false, $def = false ) {
279
- return self::_get_cache( self::$_completed_lessons, $key, $def );
280
- }
281
-
282
- /**
283
- * Helper function to set user lesson status to cache
284
- *
285
- * @param string $key
286
- * @param mixed $value
287
- *
288
- * @return array|bool|mixed
289
- */
290
- public static function set_evaluate_course_by_lesson( $key, $value ) {
291
- return self::_set_cache( self::$_evaluate_course_by_lesson, $key, $value );
292
- }
293
-
294
- /**
295
- * Helper function to get user lesson status from cache
296
- *
297
- * @param bool|string $key
298
- * @param mixed $def
299
- *
300
- * @return array|bool|mixed
301
- */
302
- public static function get_evaluate_course_by_lesson( $key = false, $def = false ) {
303
- return self::_get_cache( self::$_evaluate_course_by_lesson, $key, $def );
304
- }
305
-
306
- /**
307
- * Helper function to set user lesson status to cache
308
- *
309
- * @param string $key_or_value
310
- * @param mixed $value
311
- *
312
- * @return array|bool|mixed
313
- */
314
- public static function set_completed_items( $key_or_value, $value = false ) {
315
- //return self::_set_cache( 'user-completed-items', $key, $value );
316
- if ( func_num_args() == 1 ) {
317
- wp_cache_set( self::$_user_completed_items, $key_or_value, self::$_group );
318
- return $key_or_value;
319
- }
320
- return self::_set_cache( self::$_user_completed_items, $key_or_value, $value );
321
- }
322
-
323
- /**
324
- * Helper function to get user lesson status from cache
325
- *
326
- * @param bool|string $key
327
- * @param mixed $def
328
- *
329
- * @return array|bool|mixed
330
- */
331
- public static function get_completed_items( $key = false, $def = false ) {
332
- return self::_get_cache( self::$_user_completed_items, $key, $def );
333
- }
334
-
335
- /**
336
- * @param $key_or_value
337
- * @param $value
338
- *
339
- * @return array|bool|mixed
340
- */
341
- public static function set_enrolled_courses( $key_or_value, $value = false ) {
342
- if ( func_num_args() == 1 ) {
343
- wp_cache_set( self::$_user_enrolled_courses, $key_or_value, self::$_group );
344
- return $key_or_value;
345
- }
346
- return self::_set_cache( self::$_user_enrolled_courses, $key_or_value, $value );
347
- }
348
-
349
- /**
350
- * @param bool $key
351
- * @param bool $def
352
- *
353
- * @return array|bool|mixed
354
- */
355
- public static function get_enrolled_courses( $key = false, $def = false ) {
356
- return self::_get_cache( self::$_user_enrolled_courses, $key, $def );
357
- }
358
-
359
- /**
360
- * Set cache for user's course information
361
- *
362
- * @param $key_or_value
363
- * @param bool $value
364
- *
365
- * @return array|bool|mixed
366
- */
367
- public static function set_finished_courses( $key_or_value, $value = false ) {
368
- if ( func_num_args() == 1 ) {
369
- wp_cache_set( self::$_user_finished_courses, $key_or_value, self::$_group );
370
- return $key_or_value;
371
- }
372
- return self::_set_cache( self::$_user_finished_courses, $key_or_value, $value );
373
- }
374
-
375
- /**
376
- * @param bool $key
377
- * @param bool $def
378
- *
379
- * @return array|bool|mixed
380
- */
381
- public static function get_finished_courses( $key = false, $def = false ) {
382
- return self::_get_cache( self::$_user_finished_courses, $key, $def );
383
- }
384
-
385
- /**
386
- * @param $key_or_value
387
- * @param bool $value
388
- *
389
- * @return array|bool|mixed
390
- */
391
- public static function set_course_info( $key_or_value, $value = false ) {
392
- if ( func_num_args() == 1 ) {
393
- wp_cache_set( self::$_user_course_info, $key_or_value, self::$_group );
394
- return $key_or_value;
395
- }
396
- return self::_set_cache( self::$_user_course_info, $key_or_value, $value );
397
- }
398
-
399
- /**
400
- * @param bool $key
401
- * @param bool $def
402
- *
403
- * @return array|bool|mixed
404
- */
405
- public static function get_course_info( $key = false, $def = false ) {
406
- return self::_get_cache( self::$_user_course_info, $key, $def );
407
- }
408
-
409
- /**
410
- * @param $key_or_value
411
- * @param bool $value
412
- *
413
- * @return array|bool|mixed
414
- */
415
- public static function set_course_curriculum( $key_or_value, $value = false ) {
416
- if ( func_num_args() == 1 ) {
417
- wp_cache_set( self::$_course_curriculum, $key_or_value, self::$_group );
418
- return $key_or_value;
419
- }
420
- return self::_set_cache( self::$_course_curriculum, $key_or_value, $value );
421
- }
422
-
423
- /**
424
- * @param bool $key
425
- * @param bool $def
426
- *
427
- * @return array|bool|mixed
428
- */
429
- public static function get_course_curriculum( $key = false, $def = false ) {
430
- return self::_get_cache( self::$_course_curriculum, $key, $def );
431
- }
432
-
433
- /**
434
- * @param $key_or_value
435
- * @param bool $value
436
- *
437
- * @return array|bool|mixed
438
- */
439
- public static function set_item_statuses( $key_or_value, $value = false ) {
440
- if ( func_num_args() == 1 ) {
441
- wp_cache_set( self::$_course_item_statuses, $key_or_value, self::$_group );
442
- return $key_or_value;
443
- }
444
- return self::_set_cache( self::$_course_item_statuses, $key_or_value, $value );
445
- }
446
-
447
- /**
448
- * @param bool $key
449
- * @param bool $def
450
- *
451
- * @return array|bool|mixed
452
- */
453
- public static function get_item_statuses( $key = false, $def = false ) {
454
- return self::_get_cache( self::$_course_item_statuses, $key, $def );
455
- }
456
-
457
- /**
458
- * @param $key_or_value
459
- * @param bool $value
460
- *
461
- * @return array|bool|mixed
462
- */
463
- public static function set_quiz_questions( $key_or_value, $value = false ) {
464
- if ( func_num_args() == 1 ) {
465
- wp_cache_set( self::$_quiz_questions, $key_or_value, self::$_group );
466
- return $key_or_value;
467
- }
468
- return self::_set_cache( self::$_quiz_questions, $key_or_value, $value );
469
- }
470
-
471
- /**
472
- * @param bool $key
473
- * @param bool $def
474
- *
475
- * @return array|bool|mixed
476
- */
477
- public static function get_quiz_questions( $key = false, $def = false ) {
478
- return self::_get_cache( self::$_quiz_questions, $key, $def );
479
- }
480
-
481
- /**
482
- * @param $key_or_value
483
- * @param bool $value
484
- *
485
- * @return array|bool|mixed
486
- */
487
- public static function set_quiz_results( $key_or_value, $value = false ) {
488
- if ( func_num_args() == 1 ) {
489
- wp_cache_set( self::$_quiz_results, $key_or_value, self::$_group );
490
- return $key_or_value;
491
- }
492
- return self::_set_cache( self::$_quiz_results, $key_or_value, $value );
493
- }
494
-
495
-
496
- /**
497
- * @param bool $key
498
- * @param bool $def
499
- *
500
- * @return array|bool|mixed
501
- */
502
- public static function get_quiz_results( $key = false, $def = false ) {
503
- return self::_get_cache( self::$_quiz_results, $key, $def );
504
- }
505
-
506
- /**
507
- * @param $key_or_value
508
- * @param bool $value
509
- *
510
- * @return array|bool|mixed
511
- */
512
- public static function set_quiz_params( $key_or_value, $value = false ) {
513
- if ( func_num_args() == 1 ) {
514
- wp_cache_set( self::$_quiz_params, $key_or_value, self::$_group );
515
- return $key_or_value;
516
- }
517
- return self::_set_cache( self::$_quiz_params, $key_or_value, $value );
518
- }
519
-
520
- /**
521
- * @param bool $key
522
- * @param bool $def
523
- *
524
- * @return array|bool|mixed
525
- */
526
- public static function get_quiz_params( $key = false, $def = false ) {
527
- return self::_get_cache( self::$_quiz_params, $key, $def );
528
- }
529
-
530
- /**
531
- * @param $key_or_value
532
- * @param bool $value
533
- *
534
- * @return array|bool|mixed
535
- */
536
- public static function set_post_names( $key_or_value, $value = false ) {
537
- if ( func_num_args() == 1 ) {
538
- wp_cache_set( self::$_post_names, $key_or_value, self::$_group );
539
- return $key_or_value;
540
- }
541
- return self::_set_cache( self::$_post_names, $key_or_value, $value );
542
- }
543
-
544
- /**
545
- * @param bool $key
546
- * @param bool $def
547
- *
548
- * @return array|bool|mixed
549
- */
550
- public static function get_post_names( $key = false, $def = false ) {
551
- return self::_get_cache( self::$_post_names, $key, $def );
552
- }
553
-
554
- /**
555
- * @param $key_or_value
556
- * @param bool $value
557
- *
558
- * @return array|bool|mixed
559
- */
560
- public static function set_user_course_order( $key_or_value, $value = false ) {
561
- if ( func_num_args() == 1 ) {
562
- wp_cache_set( self::$_user_course_order, $key_or_value, self::$_group );
563
- return $key_or_value;
564
- }
565
- return self::_set_cache( self::$_user_course_order, $key_or_value, $value );
566
- }
567
-
568
- /**
569
- * @param bool $key
570
- * @param bool $def
571
- *
572
- * @return array|bool|mixed
573
- */
574
- public static function get_user_course_order( $key = false, $def = false ) {
575
- return self::_get_cache( self::$_user_course_order, $key, $def );
576
- }
577
-
578
-
579
- /**
580
- * @param $key_or_value
581
- * @param bool $value
582
- *
583
- * @return array|bool|mixed
584
- */
585
- public static function set_user_profile_orders( $key_or_value, $value = false ) {
586
- if ( func_num_args() == 1 ) {
587
- wp_cache_set( self::$_user_profile_orders, $key_or_value, self::$_group );
588
- return $key_or_value;
589
- }
590
- return self::_set_cache( self::$_user_profile_orders, $key_or_value, $value );
591
- }
592
-
593
- /**
594
- * @param bool $key
595
- * @param bool $def
596
- *
597
- * @return array|bool|mixed
598
- */
599
- public static function get_user_profile_orders( $key = false, $def = false ) {
600
- return self::_get_cache( self::$_user_profile_orders, $key, $def );
601
- }
602
-
603
- /**
604
- * @param $key_or_value
605
- * @param bool $value
606
- *
607
- * @return array|bool|mixed
608
- */
609
- public static function set_user_item_id( $key_or_value, $value = false ) {
610
- if ( func_num_args() == 1 ) {
611
- wp_cache_set( self::$_user_item_id, $key_or_value, self::$_group );
612
- return $key_or_value;
613
- }
614
- return self::_set_cache( self::$_user_item_id, $key_or_value, $value );
615
- }
616
-
617
- /**
618
- * @param bool $key
619
- * @param bool $def
620
- *
621
- * @return array|bool|mixed
622
- */
623
- public static function get_user_item_id( $key = false, $def = false ) {
624
- return self::_get_cache( self::$_user_item_id, $key, $def );
625
- }
626
-
627
- /**
628
- * @param bool $key
629
- * @param bool $def
630
- *
631
- * @return array|bool|mixed
632
- */
633
- public static function get_quiz_grade( $key = false, $def = false ) {
634
- return self::_get_cache( self::$_quiz_grade, $key, $def );
635
- }
636
-
637
- /**
638
- * @param $key_or_value
639
- * @param bool $value
640
- *
641
- * @return array|bool|mixed
642
- */
643
- public static function set_quiz_grade( $key_or_value, $value = false ) {
644
- if ( func_num_args() == 1 ) {
645
- wp_cache_set( self::$_quiz_grade, $key_or_value, self::$_group );
646
- return $key_or_value;
647
- }
648
- return self::_set_cache( self::$_quiz_grade, $key_or_value, $value );
649
- }
650
-
651
- /**
652
- * Flush cache by sections or LP group
653
- *
654
- * @param string|array $section
655
- */
656
- public static function flush( $section = '' ) {
657
- $func_args = func_get_args();
658
- if ( func_num_args() > 1 ) {
659
- foreach ( $func_args as $arg ) {
660
- self::flush( $arg );
661
- }
662
- return;
663
- }
664
- if ( $section ) {
665
- if ( is_string( $section ) ) {
666
- wp_cache_set( $section, '', self::$_group );
667
- } else {
668
- foreach ( (array) $section as $sec ) {
669
- self::flush( $sec );
670
- }
671
- }
672
- } else {
673
- try {
674
- $reflection = new ReflectionClass( "LP_Cache" );
675
- $staticProperties = $reflection->getStaticProperties();
676
- foreach ( $staticProperties as $key => $value ) {
677
- if ( in_array( $key, array( '_group' ) ) ) {
678
- continue;
679
- }
680
- wp_cache_delete( $value, self::$_group );
681
- }
682
- } catch ( Exception $ex ) {
683
- }
684
- }
685
- }
686
-
687
- public static function cache_flush( $url ) {
688
- return add_query_arg( 'cache-flush', microtime( true ), $url );
689
- }
690
-
691
- /**
692
- * @param int|string $key
693
- * @param int|string $field
694
- * @param mixed $value
695
- *
696
- * @return array|bool|mixed
697
- */
698
- private static function _set_cache( $key, $field, $value ) {
699
- $cached = wp_cache_get( $key, self::$_group );
700
- if ( !is_array( $cached ) ) {
701
- $cached = array();
702
- }
703
- $cached[$field] = $value;
704
- wp_cache_set( $key, $cached, self::$_group );
705
- return $cached;
706
- }
707
-
708
- /**
709
- * @param $key
710
- * @param bool $field
711
- * @param mixed $def
712
- *
713
- * @return array|bool|mixed
714
- */
715
- private static function _get_cache( $key, $field = false, $def = false ) {
716
- $cached = wp_cache_get( $key, self::$_group );
717
- if ( is_array( $cached ) && $field ) {
718
- $return = array_key_exists( $field, $cached ) ? $cached[$field] : false;
719
- } else {
720
- $return = $cached;
721
- }
722
- return ( $return || $def === false ) ? $return : $def;
723
- }
724
-
725
- public static function init() {
726
- /*try {
727
- self::flush();
728
- } catch ( Exception $ex ) {
729
-
730
- }
731
- add_action( 'init', array( __CLASS__, 'redirect' ) );*/
732
- }
733
-
734
- public static function redirect() {
735
- if ( !empty( $_REQUEST['cache-flush'] ) ) {
736
- }
737
- }
738
- }
739
-
740
- LP_Cache::init();
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Cache
5
+ *
6
+ * Cache helper using functions of WP Cache with default group is learnpress
7
+ *
8
+ * @since 1.1
9
+ */
10
+ if ( !defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ }
13
+
14
+ class LP_Cache {
15
+
16
+ /**
17
+ * @var array
18
+ */
19
+ protected static $_data = array();
20
+
21
+ /**
22
+ * @var string
23
+ */
24
+ protected static $_group = 'learnpress';
25
+
26
+ /**
27
+ * @var string
28
+ */
29
+ protected static $_quiz_status = 'user-quiz-status';
30
+
31
+ /**
32
+ * @var string
33
+ */
34
+ protected static $_lesson_status = 'user-lesson-status';
35
+
36
+ /**
37
+ * @var string
38
+ */
39
+ protected static $_count_retaken_quiz = 'user-count-retaken-quiz';
40
+
41
+ /**
42
+ * @var string
43
+ */
44
+ protected static $_completed_lessons = 'user-completed-lessons';
45
+
46
+ /**
47
+ * @var string
48
+ */
49
+ protected static $_evaluate_course_by_lesson = 'user-evaluate-course-by-lesson';
50
+
51
+ /**
52
+ * @var string
53
+ */
54
+ protected static $_quiz_history = 'user-quiz-history';
55
+
56
+ /**
57
+ * Set data to cache
58
+ *
59
+ * @param int|string $key
60
+ * @param mixed $value
61
+ * @param int $expire
62
+ * @param int|string $group
63
+ *
64
+ * @return mixed
65
+ */
66
+ public static function set( $key, $value, $expire = 0, $group = 'learnpress' ) {
67
+ return wp_cache_set( $key, $value, $group, $expire );
68
+ }
69
+
70
+ /**
71
+ * Get data from cache
72
+ *
73
+ * @param int|string $key
74
+ * @param boolean $force
75
+ * @param $found
76
+ * @param int|string $group
77
+ *
78
+ * @return bool|mixed
79
+ */
80
+ public static function get( $key, $force = false, &$found = 0, $group = 'learnpress' ) {
81
+ return wp_cache_get( $key, $group, $force, $found );
82
+ }
83
+
84
+ /**
85
+ * Helper function to set user quiz status to cache
86
+ *
87
+ * @param string $key
88
+ * @param mixed $value
89
+ *
90
+ * @return array|bool|mixed
91
+ */
92
+ public static function set_quiz_status( $key, $value = false ) {
93
+ if ( is_array( $key ) || is_object( $key ) ) {
94
+ return wp_cache_set( self::$_quiz_status, $key, self::$_group );
95
+ } else {
96
+ return self::_set_cache( self::$_quiz_status, $key, $value );
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Helper function to get user quiz status from cache
102
+ *
103
+ * @param bool|string $key
104
+ * @param mixed $def
105
+ *
106
+ * @return array|bool|mixed
107
+ */
108
+ public static function get_quiz_status( $key = false, $def = false ) {
109
+ return self::_get_cache( self::$_quiz_status, $key, $def );
110
+ }
111
+
112
+ /**
113
+ * Helper function to set user lesson status to cache
114
+ *
115
+ * @param string $key
116
+ * @param mixed $value
117
+ *
118
+ * @return array|bool|mixed
119
+ */
120
+ public static function set_lesson_status( $key, $value ) {
121
+ return self::_set_cache( self::$_lesson_status, $key, $value );
122
+ }
123
+
124
+ /**
125
+ * Helper function to get user lesson status from cache
126
+ *
127
+ * @param bool|string $key
128
+ * @param mixed $def
129
+ *
130
+ * @return array|bool|mixed
131
+ */
132
+ public static function get_lesson_status( $key = false, $def = false ) {
133
+ return self::_get_cache( self::$_lesson_status, $key, $def );
134
+ }
135
+
136
+ /**
137
+ * Helper function to set user lesson status to cache
138
+ *
139
+ * @param string $key_or_value
140
+ * @param mixed $value
141
+ *
142
+ * @return array|bool|mixed
143
+ */
144
+ public static function set_quiz_history( $key_or_value, $value = false ) {
145
+ if ( func_num_args() == 1 ) {
146
+ wp_cache_set( self::$_quiz_history, $key_or_value, self::$_group );
147
+ return $key_or_value;
148
+ }
149
+ return self::_set_cache( self::$_quiz_history, $key_or_value, $value );
150
+ }
151
+
152
+ /**
153
+ * Helper function to get user lesson status from cache
154
+ *
155
+ * @param bool|string $key
156
+ * @param mixed $def
157
+ *
158
+ * @return array|bool|mixed
159
+ */
160
+ public static function get_quiz_history( $key = false, $def = false ) {
161
+ return self::_get_cache( self::$_quiz_history, $key, $def );
162
+ }
163
+
164
+ /**
165
+ * Helper function to set user lesson status to cache
166
+ *
167
+ * @param string $key
168
+ * @param mixed $value
169
+ *
170
+ * @return array|bool|mixed
171
+ */
172
+ public static function set_count_retaken_quiz( $key, $value ) {
173
+ return self::_set_cache( self::$_count_retaken_quiz, $key, $value );
174
+ }
175
+
176
+ /**
177
+ * Helper function to get user lesson status from cache
178
+ *
179
+ * @param bool|string $key
180
+ * @param mixed $def
181
+ *
182
+ * @return array|bool|mixed
183
+ */
184
+ public static function get_count_retaken_quiz( $key = false, $def = false ) {
185
+ return self::_get_cache( self::$_count_retaken_quiz, $key, $def );
186
+ }
187
+
188
+ /**
189
+ * Helper function to set user lesson status to cache
190
+ *
191
+ * @param string $key
192
+ * @param mixed $value
193
+ *
194
+ * @return array|bool|mixed
195
+ */
196
+ public static function set_completed_lessons( $key, $value ) {
197
+ return self::_set_cache( self::$_completed_lessons, $key, $value );
198
+ }
199
+
200
+ /**
201
+ * Helper function to get user lesson status from cache
202
+ *
203
+ * @param bool|string $key
204
+ * @param mixed $def
205
+ *
206
+ * @return array|bool|mixed
207
+ */
208
+ public static function get_completed_lessons( $key = false, $def = false ) {
209
+ return self::_get_cache( self::$_completed_lessons, $key, $def );
210
+ }
211
+
212
+ /**
213
+ * Helper function to set user lesson status to cache
214
+ *
215
+ * @param string $key
216
+ * @param mixed $value
217
+ *
218
+ * @return array|bool|mixed
219
+ */
220
+ public static function set_evaluate_course_by_lesson( $key, $value ) {
221
+ return self::_set_cache( self::$_evaluate_course_by_lesson, $key, $value );
222
+ }
223
+
224
+ /**
225
+ * Helper function to get user lesson status from cache
226
+ *
227
+ * @param bool|string $key
228
+ * @param mixed $def
229
+ *
230
+ * @return array|bool|mixed
231
+ */
232
+ public static function get_evaluate_course_by_lesson( $key = false, $def = false ) {
233
+ return self::_get_cache( self::$_evaluate_course_by_lesson, $key, $def );
234
+ }
235
+
236
+ /**
237
+ * Helper function to set user lesson status to cache
238
+ *
239
+ * @param string $key_or_value
240
+ * @param mixed $value
241
+ *
242
+ * @return array|bool|mixed
243
+ */
244
+ public static function set_completed_items( $key_or_value, $value = false ) {
245
+ //return self::_set_cache( 'user-completed-items', $key, $value );
246
+ if ( func_num_args() == 1 ) {
247
+ wp_cache_set( 'user-completed-items', $key_or_value, self::$_group );
248
+ return $key_or_value;
249
+ }
250
+ return self::_set_cache( 'user-completed-items', $key_or_value, $value );
251
+ }
252
+
253
+ /**
254
+ * Helper function to get user lesson status from cache
255
+ *
256
+ * @param bool|string $key
257
+ * @param mixed $def
258
+ *
259
+ * @return array|bool|mixed
260
+ */
261
+ public static function get_completed_items( $key = false, $def = false ) {
262
+ return self::_get_cache( 'user-completed-items', $key, $def );
263
+ }
264
+
265
+ /**
266
+ * @param $key_or_value
267
+ * @param $value
268
+ *
269
+ * @return array|bool|mixed
270
+ */
271
+ public static function set_enrolled_courses( $key_or_value, $value ) {
272
+ if ( func_num_args() == 1 ) {
273
+ wp_cache_set( 'user-enrolled-courses', $key_or_value, self::$_group );
274
+ return $key_or_value;
275
+ }
276
+ return self::_set_cache( 'user-enrolled-courses', $key_or_value, $value );
277
+ }
278
+
279
+ /**
280
+ * @param bool $key
281
+ * @param bool $def
282
+ *
283
+ * @return array|bool|mixed
284
+ */
285
+ public static function get_enrolled_courses( $key = false, $def = false ) {
286
+ return self::_get_cache( 'user-enrolled-courses', $key, $def );
287
+ }
288
+
289
+ /**
290
+ * Set cache for user's course information
291
+ *
292
+ * @param $key_or_value
293
+ * @param bool $value
294
+ *
295
+ * @return array|bool|mixed
296
+ */
297
+ public static function set_finished_courses( $key_or_value, $value = false ) {
298
+ if ( func_num_args() == 1 ) {
299
+ wp_cache_set( 'user-finished-courses', $key_or_value, self::$_group );
300
+ return $key_or_value;
301
+ }
302
+ return self::_set_cache( 'user-finished-courses', $key_or_value, $value );
303
+ }
304
+
305
+ /**
306
+ * @param bool $key
307
+ * @param bool $def
308
+ *
309
+ * @return array|bool|mixed
310
+ */
311
+ public static function get_finished_courses( $key = false, $def = false ) {
312
+ return self::_get_cache( 'user-finished-courses', $key, $def );
313
+ }
314
+
315
+ /**
316
+ * @param $key_or_value
317
+ * @param bool $value
318
+ *
319
+ * @return array|bool|mixed
320
+ */
321
+ public static function set_course_info( $key_or_value, $value = false ) {
322
+ if ( func_num_args() == 1 ) {
323
+ wp_cache_set( 'user-course-info', $key_or_value, self::$_group );
324
+ return $key_or_value;
325
+ }
326
+ return self::_set_cache( 'user-course-info', $key_or_value, $value );
327
+ }
328
+
329
+ /**
330
+ * @param bool $key
331
+ * @param bool $def
332
+ *
333
+ * @return array|bool|mixed
334
+ */
335
+ public static function get_course_info( $key = false, $def = false ) {
336
+ return self::_get_cache( 'user-course-info', $key, $def );
337
+ }
338
+
339
+ /**
340
+ * @param $key_or_value
341
+ * @param bool $value
342
+ *
343
+ * @return array|bool|mixed
344
+ */
345
+ public static function set_course_curriculum( $key_or_value, $value = false ) {
346
+ if ( func_num_args() == 1 ) {
347
+ wp_cache_set( 'course-curriculum', $key_or_value, self::$_group );
348
+ return $key_or_value;
349
+ }
350
+ return self::_set_cache( 'course-curriculum', $key_or_value, $value );
351
+ }
352
+
353
+ /**
354
+ * @param bool $key
355
+ * @param bool $def
356
+ *
357
+ * @return array|bool|mixed
358
+ */
359
+ public static function get_course_curriculum( $key = false, $def = false ) {
360
+ return self::_get_cache( 'course-curriculum', $key, $def );
361
+ }
362
+
363
+ /**
364
+ * @param $key_or_value
365
+ * @param bool $value
366
+ *
367
+ * @return array|bool|mixed
368
+ */
369
+ public static function set_item_statuses( $key_or_value, $value = false ) {
370
+ if ( func_num_args() == 1 ) {
371
+ wp_cache_set( 'course-item-statuses', $key_or_value, self::$_group );
372
+ return $key_or_value;
373
+ }
374
+ return self::_set_cache( 'course-item-statuses', $key_or_value, $value );
375
+ }
376
+
377
+ /**
378
+ * @param bool $key
379
+ * @param bool $def
380
+ *
381
+ * @return array|bool|mixed
382
+ */
383
+ public static function get_item_statuses( $key = false, $def = false ) {
384
+ return self::_get_cache( 'course-item-statuses', $key, $def );
385
+ }
386
+
387
+ /**
388
+ * @param $key_or_value
389
+ * @param bool $value
390
+ *
391
+ * @return array|bool|mixed
392
+ */
393
+ public static function set_quiz_questions( $key_or_value, $value = false ) {
394
+ if ( func_num_args() == 1 ) {
395
+ wp_cache_set( 'quiz-questions', $key_or_value, self::$_group );
396
+ return $key_or_value;
397
+ }
398
+ return self::_set_cache( 'quiz-questions', $key_or_value, $value );
399
+ }
400
+
401
+ /**
402
+ * @param bool $key
403
+ * @param bool $def
404
+ *
405
+ * @return array|bool|mixed
406
+ */
407
+ public static function get_quiz_questions( $key = false, $def = false ) {
408
+ return self::_get_cache( 'quiz-questions', $key, $def );
409
+ }
410
+
411
+ /**
412
+ * @param $key_or_value
413
+ * @param bool $value
414
+ *
415
+ * @return array|bool|mixed
416
+ */
417
+ public static function set_quiz_results( $key_or_value, $value = false ) {
418
+ if ( func_num_args() == 1 ) {
419
+ wp_cache_set( 'quiz-results', $key_or_value, self::$_group );
420
+ return $key_or_value;
421
+ }
422
+ return self::_set_cache( 'quiz-results', $key_or_value, $value );
423
+ }
424
+
425
+ /**
426
+ * @param bool $key
427
+ * @param bool $def
428
+ *
429
+ * @return array|bool|mixed
430
+ */
431
+ public static function get_quiz_results( $key = false, $def = false ) {
432
+ return self::_get_cache( 'quiz-results', $key, $def );
433
+ }
434
+
435
+ /**
436
+ * @param $key_or_value
437
+ * @param bool $value
438
+ *
439
+ * @return array|bool|mixed
440
+ */
441
+ public static function set_quiz_params( $key_or_value, $value = false ) {
442
+ if ( func_num_args() == 1 ) {
443
+ wp_cache_set( 'quiz-params', $key_or_value, self::$_group );
444
+ return $key_or_value;
445
+ }
446
+ return self::_set_cache( 'quiz-params', $key_or_value, $value );
447
+ }
448
+
449
+ /**
450
+ * @param bool $key
451
+ * @param bool $def
452
+ *
453
+ * @return array|bool|mixed
454
+ */
455
+ public static function get_quiz_params( $key = false, $def = false ) {
456
+ return self::_get_cache( 'quiz-params', $key, $def );
457
+ }
458
+
459
+ /**
460
+ * @param $key_or_value
461
+ * @param bool $value
462
+ *
463
+ * @return array|bool|mixed
464
+ */
465
+ public static function set_post_names( $key_or_value, $value = false ) {
466
+ if ( func_num_args() == 1 ) {
467
+ wp_cache_set( 'post-names', $key_or_value, self::$_group );
468
+ return $key_or_value;
469
+ }
470
+ return self::_set_cache( 'post-names', $key_or_value, $value );
471
+ }
472
+
473
+ /**
474
+ * @param bool $key
475
+ * @param bool $def
476
+ *
477
+ * @return array|bool|mixed
478
+ */
479
+ public static function get_post_names( $key = false, $def = false ) {
480
+ return self::_get_cache( 'post-names', $key, $def );
481
+ }
482
+
483
+ /**
484
+ * @param $key_or_value
485
+ * @param bool $value
486
+ *
487
+ * @return array|bool|mixed
488
+ */
489
+ public static function set_user_course_order( $key_or_value, $value = false ) {
490
+ if ( func_num_args() == 1 ) {
491
+ wp_cache_set( 'user-course-order', $key_or_value, self::$_group );
492
+ return $key_or_value;
493
+ }
494
+ return self::_set_cache( 'user-course-order', $key_or_value, $value );
495
+ }
496
+
497
+ /**
498
+ * @param bool $key
499
+ * @param bool $def
500
+ *
501
+ * @return array|bool|mixed
502
+ */
503
+ public static function get_user_course_order( $key = false, $def = false ) {
504
+ return self::_get_cache( 'user-course-order', $key, $def );
505
+ }
506
+
507
+ /**
508
+ * @param $key_or_value
509
+ * @param bool $value
510
+ *
511
+ * @return array|bool|mixed
512
+ */
513
+ public static function set_user_profile_orders( $key_or_value, $value = false ) {
514
+ if ( func_num_args() == 1 ) {
515
+ wp_cache_set( 'user-profile-orders', $key_or_value, self::$_group );
516
+ return $key_or_value;
517
+ }
518
+ return self::_set_cache( 'user-profile-orders', $key_or_value, $value );
519
+ }
520
+
521
+ /**
522
+ * @param bool $key
523
+ * @param bool $def
524
+ *
525
+ * @return array|bool|mixed
526
+ */
527
+ public static function get_user_profile_orders( $key = false, $def = false ) {
528
+ return self::_get_cache( 'user-profile-orders', $key, $def );
529
+ }
530
+
531
+ /**
532
+ * @param $key_or_value
533
+ * @param bool $value
534
+ *
535
+ * @return array|bool|mixed
536
+ */
537
+ public static function set_user_item_id( $key_or_value, $value = false ) {
538
+ if ( func_num_args() == 1 ) {
539
+ wp_cache_set( 'user-item-id', $key_or_value, self::$_group );
540
+ return $key_or_value;
541
+ }
542
+ return self::_set_cache( 'user-item-id', $key_or_value, $value );
543
+ }
544
+
545
+ /**
546
+ * @param bool $key
547
+ * @param bool $def
548
+ *
549
+ * @return array|bool|mixed
550
+ */
551
+ public static function get_user_item_id( $key = false, $def = false ) {
552
+ return self::_get_cache( 'user-item-id', $key, $def );
553
+ }
554
+
555
+ /**
556
+ * Flush cache by sections or LP group
557
+ *
558
+ * @param string|array $section
559
+ */
560
+ public static function flush( $section = '' ) {
561
+ $func_args = func_get_args();
562
+ if ( func_num_args() > 1 ) {
563
+ foreach ( $func_args as $arg ) {
564
+ self::flush( $arg );
565
+ }
566
+ return;
567
+ }
568
+ if ( $section ) {
569
+ if ( is_string( $section ) ) {
570
+ wp_cache_set( $section, '', self::$_group );
571
+ } else {
572
+ foreach ( (array) $section as $sec ) {
573
+ self::flush( $sec );
574
+ }
575
+ }
576
+ } else {
577
+ global $wp_object_cache;
578
+
579
+
580
+ if ( @$cache = $wp_object_cache->cache ) {
581
+ if ( !empty( $cache[self::$_group] ) ) {
582
+ unset( $cache[self::$_group] );
583
+ $wp_object_cache->cache = $cache;
584
+ }
585
+ if ( is_callable( array( $wp_object_cache, 'get_mc' ) ) ) {
586
+ $group = self::$_group;
587
+ foreach ( $wp_object_cache->mc as $bucket => $mc ) {
588
+ if ( $bucket !== $group ) {
589
+ continue;
590
+ }
591
+ if ( $wp_object_cache->reset_generation( $bucket ) === false ) {
592
+ $mc->flush();
593
+ $wp_object_cache->reset_generation( $bucket );
594
+ }
595
+ }
596
+ }
597
+ }
598
+ }
599
+ }
600
+
601
+ /**
602
+ * @param int|string $key
603
+ * @param int|string $field
604
+ * @param mixed $value
605
+ *
606
+ * @return array|bool|mixed
607
+ */
608
+ private static function _set_cache( $key, $field, $value ) {
609
+ $cached = wp_cache_get( $key, self::$_group );
610
+ if ( !is_array( $cached ) ) {
611
+ $cached = array();
612
+ }
613
+ $cached[$field] = $value;
614
+ wp_cache_set( $key, $cached, self::$_group );
615
+ return $cached;
616
+ }
617
+
618
+ /**
619
+ * @param $key
620
+ * @param bool $field
621
+ * @param mixed $def
622
+ *
623
+ * @return array|bool|mixed
624
+ */
625
+ private static function _get_cache( $key, $field = false, $def = false ) {
626
+ $cached = wp_cache_get( $key, self::$_group );
627
+ if ( is_array( $cached ) && $field ) {
628
+ $return = !array_key_exists( $field, $cached ) ? $cached[$field] : false;
629
+ } else {
630
+ $return = $cached;
631
+ }
632
+ return $return ? $return : $def;
633
+ }
634
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/class-lp-emails.php CHANGED
@@ -7,7 +7,7 @@
7
  * @package LearnPress/Classes
8
  * @version 1.0
9
  */
10
- if ( ! defined( 'ABSPATH' ) ) {
11
  exit;
12
  }
13
 
@@ -27,46 +27,42 @@ class LP_Emails {
27
  * @static
28
  * @return LP_Emails instance
29
  */
30
- public static function instance () {
31
  if ( is_null( self::$_instance ) ) {
32
  self::$_instance = new self();
33
  self::init_email_notifications();
34
  }
35
-
36
  return self::$_instance;
37
  }
38
 
39
  /**
40
  * @version 1.0
41
  */
42
- public function __clone () {
43
  _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'learnpress' ), '1.0' );
44
  }
45
 
46
  /**
47
  * @version 1.0
48
  */
49
- public function __wakeup () {
50
  _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'learnpress' ), '1.0' );
51
  }
52
 
53
- public function __construct () {
54
  if ( did_action( 'learn_press_emails_init' ) ) {
55
  return;
56
  }
57
  LP()->_include( 'emails/class-lp-email.php' );
58
- $this->emails['LP_Email_New_Order'] = include( 'emails/class-lp-email-new-order.php' );
59
- $this->emails['LP_Email_New_Order_Customer'] = include( 'emails/class-lp-email-new-order-customer.php' );
60
- $this->emails['LP_Email_User_Order_Completed'] = include( 'emails/class-lp-email-user-order-completed.php' );
61
- $this->emails['LP_Email_User_Order_Changed_Status'] = include( 'emails/class-lp-email-user-order-changed-status.php' );
62
- $this->emails['LP_Email_New_Course'] = include( 'emails/class-lp-email-new-course.php' );
63
- $this->emails['LP_Email_Rejected_Course'] = include( 'emails/class-lp-email-rejected-course.php' );
64
- $this->emails['LP_Email_Published_Course'] = include( 'emails/class-lp-email-published-course.php' );
65
- $this->emails['LP_Email_Enrolled_Course'] = include( 'emails/class-lp-email-enrolled-course.php' );
66
- $this->emails['LP_Email_Enrolled_Course_Admin'] = include( 'emails/class-lp-email-enrolled-course-admin.php' );
67
- $this->emails['LP_Email_Finished_Course'] = include( 'emails/class-lp-email-finished-course.php' );
68
- $this->emails['LP_Email_Update_Course'] = include( 'emails/class-lp-email-update-course.php' );
69
- $this->emails['LP_Email_Become_An_Instructor'] = include( 'emails/class-lp-email-become-an-instructor.php' );
70
 
71
  add_action( 'learn_press_course_submit_for_reviewer_notification', array( $this, 'review_course' ), 10, 2 );
72
  add_action( 'learn_press_course_submit_rejected_notification', array( $this, 'course_rejected' ), 10, 2 );
@@ -82,33 +78,32 @@ class LP_Emails {
82
  do_action( 'learn_press_emails_init', $this );
83
  }
84
 
85
- public function email_header ( $heading, $return = false ) {
86
  ob_start();
87
  learn_press_get_template( 'emails/email-header.php', array( 'email_heading' => $heading ) );
88
  $header = ob_get_clean();
89
- if ( ! $return ) {
90
  echo $header;
91
  } else {
92
  return $header;
93
  }
94
  }
95
 
96
- public function email_footer ( $footer_text, $return = false ) {
97
  ob_start();
98
  learn_press_get_template( 'emails/email-footer.php', array( 'footer_text' => $footer_text ) );
99
  $footer = ob_get_clean();
100
- if ( ! $return ) {
101
  echo $footer;
102
  } else {
103
  return $footer;
104
  }
105
  }
106
 
107
- public static function send_email () {
108
  self::instance();
109
  $args = func_get_args();
110
  do_action_ref_array( current_filter() . '_notification', $args );
111
-
112
  return isset( $args[0] ) ? $args[0] : null;
113
  }
114
 
@@ -118,29 +113,29 @@ class LP_Emails {
118
  * @param $course_id
119
  * @param $user
120
  */
121
- public function review_course ( $course_id, $user ) {
122
  $mail = $this->emails['LP_Email_New_Course'];
123
  $mail->trigger( $course_id, $user );
124
  }
125
 
126
- public function course_rejected ( $course_id ) {
127
  $course_user = learn_press_get_user( get_post_field( 'post_author', $course_id ) );
128
- if ( ! $course_user->is_admin() ) {
129
  $mail = $this->emails['LP_Email_Rejected_Course'];
130
  $mail->trigger( $course_id );
131
  }
132
  }
133
 
134
- public function course_approved ( $course_id, $user ) {
135
  $course_user = learn_press_get_user( get_post_field( 'post_author', $course_id ) );
136
- if ( ! $course_user->is_admin() ) {
137
  $mail = $this->emails['LP_Email_Published_Course'];
138
  $mail->trigger( $course_id, $user );
139
  }
140
  }
141
 
142
- public function finish_course ( $course_id, $user_id, $result ) {
143
- if ( ! $user = learn_press_get_user( $user_id ) ) {
144
  return;
145
  }
146
  $mail = $this->emails['LP_Email_Finished_Course'];
@@ -155,21 +150,20 @@ class LP_Emails {
155
  *
156
  * @return array
157
  */
158
- public function customer_new_order ( $result, $order_id ) {
159
  $mail = $this->emails['LP_Email_New_Order_Customer'];
160
  $mail->trigger( $order_id );
161
-
162
  return $result;
163
  }
164
 
165
- public function become_an_teacher ( $user_id, $role, $old_role ) {
166
  if ( $role === LP_TEACHER_ROLE ) {
167
  $mail = $this->emails['LP_Email_Become_An_Instructor'];
168
  $mail->trigger( $user_id );
169
  }
170
  }
171
 
172
- public static function init_email_notifications () {
173
  $actions = apply_filters(
174
  'learn_press_email_actions',
175
  array(
7
  * @package LearnPress/Classes
8
  * @version 1.0
9
  */
10
+ if ( !defined( 'ABSPATH' ) ) {
11
  exit;
12
  }
13
 
27
  * @static
28
  * @return LP_Emails instance
29
  */
30
+ public static function instance() {
31
  if ( is_null( self::$_instance ) ) {
32
  self::$_instance = new self();
33
  self::init_email_notifications();
34
  }
 
35
  return self::$_instance;
36
  }
37
 
38
  /**
39
  * @version 1.0
40
  */
41
+ public function __clone() {
42
  _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'learnpress' ), '1.0' );
43
  }
44
 
45
  /**
46
  * @version 1.0
47
  */
48
+ public function __wakeup() {
49
  _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'learnpress' ), '1.0' );
50
  }
51
 
52
+ public function __construct() {
53
  if ( did_action( 'learn_press_emails_init' ) ) {
54
  return;
55
  }
56
  LP()->_include( 'emails/class-lp-email.php' );
57
+ $this->emails['LP_Email_New_Order'] = include( 'emails/class-lp-email-new-order.php' );
58
+ $this->emails['LP_Email_New_Order_Customer'] = include( 'emails/class-lp-email-new-order-customer.php' );
59
+ $this->emails['LP_Email_User_Order_Completed'] = include( 'emails/class-lp-email-user-order-completed.php' );
60
+ $this->emails['LP_Email_New_Course'] = include( 'emails/class-lp-email-new-course.php' );
61
+ $this->emails['LP_Email_Rejected_Course'] = include( 'emails/class-lp-email-rejected-course.php' );
62
+ $this->emails['LP_Email_Published_Course'] = include( 'emails/class-lp-email-published-course.php' );
63
+ $this->emails['LP_Email_Enrolled_Course'] = include( 'emails/class-lp-email-enrolled-course.php' );
64
+ $this->emails['LP_Email_Finished_Course'] = include( 'emails/class-lp-email-finished-course.php' );
65
+ $this->emails['LP_Email_Become_An_Instructor'] = include( 'emails/class-lp-email-become-an-instructor.php' );
 
 
 
66
 
67
  add_action( 'learn_press_course_submit_for_reviewer_notification', array( $this, 'review_course' ), 10, 2 );
68
  add_action( 'learn_press_course_submit_rejected_notification', array( $this, 'course_rejected' ), 10, 2 );
78
  do_action( 'learn_press_emails_init', $this );
79
  }
80
 
81
+ public function email_header( $heading, $return = false ) {
82
  ob_start();
83
  learn_press_get_template( 'emails/email-header.php', array( 'email_heading' => $heading ) );
84
  $header = ob_get_clean();
85
+ if ( !$return ) {
86
  echo $header;
87
  } else {
88
  return $header;
89
  }
90
  }
91
 
92
+ public function email_footer( $footer_text, $return = false ) {
93
  ob_start();
94
  learn_press_get_template( 'emails/email-footer.php', array( 'footer_text' => $footer_text ) );
95
  $footer = ob_get_clean();
96
+ if ( !$return ) {
97
  echo $footer;
98
  } else {
99
  return $footer;
100
  }
101
  }
102
 
103
+ public static function send_email() {
104
  self::instance();
105
  $args = func_get_args();
106
  do_action_ref_array( current_filter() . '_notification', $args );
 
107
  return isset( $args[0] ) ? $args[0] : null;
108
  }
109
 
113
  * @param $course_id
114
  * @param $user
115
  */
116
+ public function review_course( $course_id, $user ) {
117
  $mail = $this->emails['LP_Email_New_Course'];
118
  $mail->trigger( $course_id, $user );
119
  }
120
 
121
+ public function course_rejected( $course_id ) {
122
  $course_user = learn_press_get_user( get_post_field( 'post_author', $course_id ) );
123
+ if ( !$course_user->is_admin() ) {
124
  $mail = $this->emails['LP_Email_Rejected_Course'];
125
  $mail->trigger( $course_id );
126
  }
127
  }
128
 
129
+ public function course_approved( $course_id, $user ) {
130
  $course_user = learn_press_get_user( get_post_field( 'post_author', $course_id ) );
131
+ if ( !$course_user->is_admin() ) {
132
  $mail = $this->emails['LP_Email_Published_Course'];
133
  $mail->trigger( $course_id, $user );
134
  }
135
  }
136
 
137
+ public function finish_course( $course_id, $user_id, $result ) {
138
+ if ( !$user = learn_press_get_user( $user_id ) ) {
139
  return;
140
  }
141
  $mail = $this->emails['LP_Email_Finished_Course'];
150
  *
151
  * @return array
152
  */
153
+ public function customer_new_order( $result, $order_id ) {
154
  $mail = $this->emails['LP_Email_New_Order_Customer'];
155
  $mail->trigger( $order_id );
 
156
  return $result;
157
  }
158
 
159
+ public function become_an_teacher( $user_id, $role, $old_role ) {
160
  if ( $role === LP_TEACHER_ROLE ) {
161
  $mail = $this->emails['LP_Email_Become_An_Instructor'];
162
  $mail->trigger( $user_id );
163
  }
164
  }
165
 
166
+ public static function init_email_notifications() {
167
  $actions = apply_filters(
168
  'learn_press_email_actions',
169
  array(
inc/class-lp-install.php CHANGED
@@ -1,658 +1,658 @@
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
- learn_press_delete_user_option( 'hide-notice-template-files' );
190
-
191
- // Fix for WP 4.7
192
- if ( did_action( 'admin_init' ) ) {
193
- self::_auto_update();
194
- } else {
195
- add_action( 'admin_init', array( __CLASS__, '_auto_update' ), - 15 );
196
- }
197
- }
198
-
199
- private static function _create_cron_jobs() {
200
- wp_clear_scheduled_hook( 'learn_press_cleanup_sessions' );
201
- wp_schedule_event( time(), apply_filters( 'learn_press_cleanup_session_recurrence', 'twicedaily' ), 'learn_press_cleanup_sessions' );
202
- }
203
-
204
- public static function _auto_update() {
205
- self::get_update_versions();
206
- self::update();
207
- }
208
-
209
- public static function _search_page( $type, $types ) {
210
- static $pages = array();
211
- if ( empty( $pages[$type] ) ) {
212
- global $wpdb;
213
- $in_types = array_fill( 0, sizeof( $types ), '%s' );
214
- $args = array( '_learn_press_page' );
215
- $args = array_merge( $args, $types );
216
- $args[] = 'publish';
217
- $query = $wpdb->prepare( "
218
- SELECT ID, pm.meta_value as type
219
- FROM {$wpdb->posts} p
220
- INNER JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID AND pm.meta_key = %s AND pm.meta_value IN(" . join( ',', $in_types ) . ")
221
- WHERE p.post_status = %s
222
- ", $args );
223
- if ( $rows = $wpdb->get_results( $query ) ) {
224
- foreach ( $rows as $row ) {
225
- $pages[$row->type] = $row->ID;
226
- }
227
- }
228
- }
229
-
230
- $page_id = !empty( $pages[$type] ) ? $pages[$type] : 0;
231
-
232
- return $page_id;
233
- }
234
-
235
- /**
236
- * Remove learnpress page if total of learn page > 10
237
- * @global type $wpdb
238
- * @return type
239
- */
240
- public static function _remove_pages() {
241
- global $wpdb;
242
- $sql = 'SELECT * '
243
- . ' FROM ' . $wpdb->posts . ' p INNER JOIN ' . $wpdb->postmeta . ' pm '
244
- . ' ON p.ID=pm.post_id AND pm.meta_key="_learn_press_page" AND p.post_type="page";';
245
- $ids = $wpdb->get_col( $sql );
246
- $count_ids = count( $ids );
247
- if ( $count_ids < 10 ) {
248
- return $ids;
249
- }
250
- $q = $wpdb->prepare( "
251
- DELETE FROM p, pm
252
- USING {$wpdb->posts} AS p LEFT JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id AND p.post_type IN('page')
253
- WHERE %d AND p.post_status='publish' AND p.ID IN(" . implode( ',', $ids ) . ")
254
- ", 1 );
255
-
256
- $wpdb->query( $q );
257
-
258
- $pages = self::$_pages;
259
- foreach ( $pages as $page ) {
260
- delete_option( "learn_press_{$page}_page_id" );
261
- }
262
- sleep( 5 );
263
- return array();
264
-
265
- }
266
-
267
- public static function create_pages() {
268
- global $wpdb;
269
- $created_page = self::_remove_pages();
270
-
271
- if ( !empty( $created_page ) ) {
272
- return;
273
- }
274
-
275
- $pages = self::$_pages;
276
- foreach ( $pages as $page ) {
277
- $page_id = get_option( "learn_press_{$page}_page_id" );
278
- if ( $page_id && get_post_type( $page_id ) == 'page' && get_post_status( $page_id ) == 'publish' ) {
279
- continue;
280
- }
281
- $page_id = self::_search_page( $page, $pages );
282
- if ( !$page_id ) {
283
- // Check if page has already existed
284
- switch ( $page ) {
285
- case 'courses':
286
- $_lpr_settings_pages = (array) get_option( '_lpr_settings_pages' );
287
-
288
- if ( !empty( $_lpr_settings_pages['general'] ) ) {
289
- if ( !empty( $_lpr_settings_pages['general']['courses_page_id'] ) ) {
290
- $page_id = $_lpr_settings_pages['general']['courses_page_id'];
291
- }
292
- }
293
- break;
294
- case 'profile':
295
- $_lpr_settings_general = (array) get_option( '_lpr_settings_general' );
296
- if ( !empty( $_lpr_settings_general['set_page'] ) && $_lpr_settings_general['set_page'] == 'lpr_profile' ) {
297
- $page_id = $wpdb->get_var(
298
- $wpdb->prepare( "
299
- SELECT ID
300
- FROM $wpdb->posts p
301
- INNER JOIN $wpdb->postmeta pm ON p.ID = pm.post_id AND pm.meta_key = %s AND pm.meta_value = %d
302
- ", '_lpr_is_profile_page', 1 )
303
- );
304
- }
305
- break;
306
- }
307
-
308
- if ( !$page_id ) {
309
- $inserted = wp_insert_post(
310
- array(
311
- 'post_title' => 'LP ' . ucwords( str_replace( '_', ' ', $page ) ),
312
- 'post_status' => 'publish',
313
- 'post_type' => 'page',
314
- 'comment_status' => 'closed'
315
- )
316
- );
317
- if ( $inserted ) {
318
- $page_id = $inserted;
319
- }
320
- }
321
- }
322
- if ( $page_id ) {
323
- update_option( "learn_press_{$page}_page_id", $page_id );
324
- update_post_meta( $page_id, '_learn_press_page', $page );
325
- }
326
- }
327
- flush_rewrite_rules();
328
- }
329
-
330
- public static function create_files() {
331
- $upload_dir = wp_upload_dir();
332
- $files = array(
333
- array(
334
- 'base' => LP_LOG_PATH,
335
- 'file' => '.htaccess',
336
- 'content' => 'deny from all'
337
- ),
338
- array(
339
- 'base' => LP_LOG_PATH,
340
- 'file' => 'index.html',
341
- 'content' => ''
342
- )
343
- );
344
-
345
- foreach ( $files as $file ) {
346
- if ( wp_mkdir_p( $file['base'] ) && !file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
347
- if ( $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ) ) {
348
- fwrite( $file_handle, $file['content'] );
349
- fclose( $file_handle );
350
- }
351
- }
352
- }
353
- }
354
-
355
- private function _is_old_version() {
356
- if ( is_null( self::$_is_old_version ) ) {
357
- $is_old_version = get_transient( 'learn_press_is_old_version' );
358
-
359
- if ( empty( $is_old_version ) ) {
360
- if ( !get_option( 'learnpress_db_version' ) ||
361
- get_posts(
362
- array(
363
- 'post_type' => 'lpr_course',
364
- 'post_status' => 'any',
365
- 'posts_per_page' => 1
366
- )
367
- )
368
- ) {
369
- $is_old_version = 'yes';
370
- }
371
- if ( empty( $is_old_version ) ) {
372
- $is_old_version = 'no';
373
- }
374
- set_transient( 'learn_press_is_old_version', $is_old_version );
375
- }
376
- self::$_is_old_version = $is_old_version == 'yes';
377
- }
378
- return self::$_is_old_version;
379
- }
380
-
381
- /**
382
- * Find if there is any old course and did not upgrade
383
- * If a course has got a meta key like _learn_press_upgraded that means it is not upgraded
384
- *
385
- * @return mixed
386
- */
387
- private static function _has_old_posts() {
388
- global $wpdb;
389
- $query = $wpdb->prepare( "
390
- SELECT DISTINCT p.ID, pm.meta_value as upgraded
391
- FROM {$wpdb->posts} p
392
- LEFT JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID AND pm.meta_key = %s
393
- WHERE post_type = %s
394
- HAVING upgraded IS NULL
395
- LIMIT 0, 1
396
- ", '_learn_press_upgraded', 'lpr_course' );
397
- return $wpdb->get_row( $query );
398
- }
399
-
400
- private static function _has_new_table() {
401
- global $wpdb;
402
- $query = $wpdb->prepare( "
403
- SELECT COUNT(*)
404
- FROM information_schema.tables
405
- WHERE table_schema = %s
406
- AND table_name LIKE %s
407
- ", DB_NAME, '%learnpress_sections%' );
408
- return $wpdb->get_var( $query ) ? true : false;
409
- }
410
-
411
- private static function _need_to_update() {
412
- return self::_has_old_posts() || self::_has_old_teacher_role();
413
- }
414
-
415
- private static function _has_old_teacher_role() {
416
- global $wpdb;
417
- $query = $wpdb->prepare( "
418
- SELECT um.*
419
- FROM {$wpdb->users} u
420
- INNER JOIN {$wpdb->usermeta} um ON um.user_id = u.ID AND um.meta_key = %s
421
- WHERE um.meta_value LIKE %s
422
- LIMIT 0, 1
423
- ", 'wp_capabilities', '%"lpr_teacher"%' );
424
- return $wpdb->get_results( $query );
425
- }
426
-
427
- private static function _has_new_posts() {
428
- $new_post = get_posts(
429
- array(
430
- 'post_type' => 'lp_course',
431
- 'post_status' => 'any',
432
- 'posts_per_page' => 1
433
- )
434
- );
435
- return sizeof( $new_post ) > 0;
436
- }
437
-
438
- public static function update() {
439
- $learnpress_db_version = get_option( 'learnpress_db_version' );
440
-
441
- foreach ( self::$_update_files as $version => $updater ) {
442
- if ( version_compare( $learnpress_db_version, $version, '<' ) ) {
443
- @include( LP_PLUGIN_PATH . '/inc/updates/' . $updater );
444
- self::update_db_version( $version );
445
- }
446
- }
447
-
448
- self::update_db_version();
449
- self::update_version();
450
- }
451
-
452
- public static function update_db_version( $version = null ) {
453
- delete_option( 'learnpress_db_version' );
454
- update_option( 'learnpress_db_version', is_null( $version ) ? LEARNPRESS_VERSION : $version );
455
- }
456
-
457
- public static function update_version( $version = null ) {
458
-
459
- delete_option( 'learnpress_version' );
460
- update_option( 'learnpress_version', is_null( $version ) ? LEARNPRESS_VERSION : $version );
461
- }
462
-
463
- private static function _create_options() {
464
- include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-base.php';
465
- $settings_classes = array(
466
- 'LP_Settings_General' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-general.php',
467
- 'LP_Settings_Courses' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-courses.php',
468
- 'LP_Settings_Pages' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-pages.php',
469
- 'LP_Settings_Checkout' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-checkout.php',
470
- 'LP_Settings_Profile' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-profile.php',
471
- 'LP_Settings_Emails' => include_once LP_PLUGIN_PATH . '/inc/admin/settings/class-lp-settings-emails.php'
472
- );
473
- foreach ( $settings_classes as $c => $class ) {
474
- if ( !is_object( $class ) ) {
475
- $class = @new $c();
476
- }
477
- if ( is_callable( array( $class, 'get_settings' ) ) ) {
478
- $options = $class->get_settings();
479
- foreach ( $options as $option ) {
480
- if ( isset( $option['default'] ) && isset( $option['id'] ) ) {
481
- $autoload = isset( $option['autoload'] ) ? (bool) $option['autoload'] : true;
482
- $value = get_option( $option['id'], $option['default'] );
483
- update_option( $option['id'], $value, '', ( $autoload ? 'yes' : 'no' ) );
484
- }
485
- }
486
- }
487
- }
488
- $custom_options = array(
489
- 'learn_press_course_base_type' => 'custom',
490
- 'learn_press_paypal_email' => get_option( 'admin_email' ),
491
- 'learn_press_paypal_enable' => 'yes',
492
- '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";}',
493
- 'learn_press_checkout_endpoints' => 'a:1:{s:17:"lp_order_received";s:17:"lp-order-received";}'
494
- );
495
- foreach ( $custom_options as $option_name => $option_value ) {
496
- if ( !get_option( $option_name ) ) {
497
- update_option( $option_name, maybe_unserialize( $option_value ), 'yes' );
498
- }
499
- }
500
- update_option( 'learn_press_install', 'yes');
501
- }
502
-
503
- private static function _create_tables() {
504
- global $wpdb;
505
-
506
- $wpdb->hide_errors();
507
-
508
- require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
509
- $schema = self::_get_schema();
510
- if ( $schema ) {
511
- dbDelta( $schema );
512
- }
513
- LP_Debug::instance()->add( 'create_table' );
514
- }
515
-
516
- private static function _get_schema() {
517
- global $wpdb;
518
-
519
- $collate = '';
520
-
521
- if ( $wpdb->has_cap( 'collation' ) ) {
522
- if ( !empty( $wpdb->charset ) ) {
523
- $collate .= "DEFAULT CHARACTER SET $wpdb->charset";
524
- }
525
- if ( !empty( $wpdb->collate ) ) {
526
- $collate .= " COLLATE $wpdb->collate";
527
- }
528
- }
529
-
530
- $table = $wpdb->prefix . 'learnpress_order_itemmeta';
531
- $query = '';
532
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
533
- $query .= "
534
- CREATE TABLE {$wpdb->prefix}learnpress_order_itemmeta (
535
- meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
536
- learnpress_order_item_id bigint(20) unsigned NOT NULL DEFAULT '0',
537
- meta_key varchar(45) NOT NULL DEFAULT '',
538
- meta_value longtext NOT NULL,
539
- PRIMARY KEY (meta_id)
540
- ) $collate;";
541
- }
542
- $table = $wpdb->prefix . 'learnpress_order_items';
543
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
544
- $query .= "
545
- CREATE TABLE {$wpdb->prefix}learnpress_order_items (
546
- order_item_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
547
- order_item_name longtext NOT NULL,
548
- order_id bigint(20) unsigned NOT NULL DEFAULT '0',
549
- PRIMARY KEY (order_item_id)
550
- ) $collate;";
551
- }
552
- $table = $wpdb->prefix . 'learnpress_question_answers';
553
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
554
- $query .= "
555
- CREATE TABLE {$wpdb->prefix}learnpress_question_answers (
556
- question_answer_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
557
- question_id bigint(20) unsigned NOT NULL DEFAULT '0',
558
- answer_data text NOT NULL,
559
- answer_order bigint(20) unsigned NOT NULL DEFAULT '0',
560
- PRIMARY KEY (question_answer_id)
561
- ) $collate;";
562
- }
563
- $table = $wpdb->prefix . 'learnpress_quiz_questions';
564
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
565
- $query .= "
566
- CREATE TABLE {$wpdb->prefix}learnpress_quiz_questions (
567
- quiz_question_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
568
- quiz_id bigint(20) unsigned NOT NULL DEFAULT '0',
569
- question_id bigint(20) unsigned NOT NULL DEFAULT '0',
570
- question_order bigint(20) unsigned NOT NULL DEFAULT '1',
571
- params longtext NULL,
572
- PRIMARY KEY (quiz_question_id)
573
- ) $collate;";
574
- }
575
- $table = $wpdb->prefix . 'learnpress_review_logs';
576
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
577
- $query .= "
578
- CREATE TABLE {$wpdb->prefix}learnpress_review_logs (
579
- review_log_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
580
- course_id bigint(20) unsigned NOT NULL DEFAULT '0',
581
- user_id bigint(20) unsigned NOT NULL DEFAULT '0',
582
- message text NOT NULL,
583
- date datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
584
- status varchar(45) NOT NULL DEFAULT '',
585
- user_type varchar(45) NOT NULL DEFAULT '',
586
- PRIMARY KEY (review_log_id)
587
- ) $collate;";
588
- }
589
- $table = $wpdb->prefix . 'learnpress_section_items';
590
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
591
- $query .= "
592
- CREATE TABLE {$wpdb->prefix}learnpress_section_items (
593
- section_item_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
594
- section_id bigint(20) unsigned NOT NULL DEFAULT '0',
595
- item_id bigint(20) unsigned NOT NULL DEFAULT '0',
596
- item_order bigint(20) unsigned NOT NULL DEFAULT '0',
597
- item_type varchar(45),
598
- PRIMARY KEY (section_item_id)
599
- ) $collate;";
600
- }
601
- $table = $wpdb->prefix . 'learnpress_sections';
602
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
603
- $query .= "
604
- CREATE TABLE {$wpdb->prefix}learnpress_sections (
605
- section_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
606
- section_name varchar(255) NOT NULL DEFAULT '',
607
- section_course_id bigint(20) unsigned NOT NULL DEFAULT '0',
608
- section_order bigint(5) unsigned NOT NULL DEFAULT '0',
609
- section_description longtext NOT NULL,
610
- PRIMARY KEY (section_id)
611
- ) $collate;";
612
- }
613
- $table = $wpdb->prefix . 'learnpress_sessions';
614
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
615
- $query .= "
616
- CREATE TABLE {$wpdb->prefix}learnpress_sessions (
617
- session_id bigint(20) NOT NULL AUTO_INCREMENT,
618
- session_key char(32) NOT NULL,
619
- session_value longtext NOT NULL,
620
- session_expiry bigint(20) NOT NULL,
621
- UNIQUE KEY session_id (session_id),
622
- PRIMARY KEY (session_key)
623
- ) $collate;";
624
- }
625
- $table = $wpdb->prefix . 'learnpress_user_items';
626
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
627
- $query .= "
628
- CREATE TABLE {$wpdb->prefix}learnpress_user_items (
629
- user_item_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
630
- user_id bigint(20) unsigned NOT NULL DEFAULT '0',
631
- item_id bigint(20) unsigned NOT NULL DEFAULT '0',
632
- start_time datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
633
- end_time datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
634
- item_type varchar(45) NOT NULL DEFAULT '',
635
- status varchar(45) NOT NULL DEFAULT '',
636
- ref_id bigint(20) unsigned NOT NULL DEFAULT '0',
637
- ref_type varchar(45) DEFAULT '',
638
- parent_id bigint(20) unsigned NOT NULL DEFAULT '0',
639
- PRIMARY KEY (user_item_id)
640
- ) $collate;";
641
- }
642
- $table = $wpdb->prefix . 'learnpress_user_itemmeta';
643
- if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
644
- $query .= "
645
- CREATE TABLE {$wpdb->prefix}learnpress_user_itemmeta (
646
- meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
647
- learnpress_user_item_id bigint(20) unsigned NOT NULL,
648
- meta_key varchar(45) NOT NULL DEFAULT '',
649
- meta_value text NOT NULL,
650
- PRIMARY KEY (meta_id)
651
- ) $collate;
652
- ";
653
- }
654
- return $query;
655
- }
656
- }
657
-
658
- 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