LearnPress – WordPress LMS Plugin - Version 1.0

Version Description

  • Enhanced performance and capacity to extends more features with new database structure
  • Enable purchase multiple courses with Cart
  • Checkout process
  • Option purchase FREE course without cart and checkout proccess
  • Option add course to cart using AJAX
  • Support static pages: Cart, Checkout, Profile, Archive Courses
  • Custom slug for pages with Wordpress Endpoint
  • Review order after do checkout
  • Emails system with capacity to overwtire as templates
  • New UI/UX for admin and frontend
  • Capacity to compatible with more themes
  • Custom permalink for course tag, archive courses, single course pages
  • Custom size of course thumbnail
  • Ability to add new order manually in admin
  • Improved add-ons page
Download this release

Release Info

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

Version 1.0

Files changed (143) hide show
  1. README.md +136 -0
  2. assets/css/admin/admin.css +1314 -0
  3. assets/css/admin/meta-box-course.css +738 -0
  4. assets/css/admin/meta-box-order.css +130 -0
  5. assets/css/admin/meta-box-question.css +65 -0
  6. assets/css/global-style.css +115 -0
  7. assets/css/icons.css +36 -0
  8. assets/css/learnpress-0.9.x.css +476 -0
  9. assets/css/learnpress.css +897 -0
  10. assets/css/select2/select2-spinner.gif +0 -0
  11. assets/css/select2/select2.css +732 -0
  12. assets/css/select2/select2.png +0 -0
  13. assets/css/select2/select2x2.png +0 -0
  14. assets/css/select2/spinner.gif +0 -0
  15. assets/css/timer.css +0 -0
  16. assets/css/tipsy.css +25 -0
  17. assets/css/toastr.css +197 -0
  18. assets/fonts/Sumana-Regular.ttf +0 -0
  19. assets/fonts/icomoon.eot +0 -0
  20. assets/fonts/icomoon.svg +14 -0
  21. assets/fonts/icomoon.ttf +0 -0
  22. assets/fonts/icomoon.woff +0 -0
  23. assets/images/ajax-loader.gif +0 -0
  24. assets/images/ajaxload.gif +0 -0
  25. assets/images/animation.gif +0 -0
  26. assets/images/grippy_large.png +0 -0
  27. assets/images/icon-128x128.png +0 -0
  28. assets/images/multiple-choice.png +0 -0
  29. assets/images/openhand.cur +0 -0
  30. assets/images/question.png +0 -0
  31. assets/images/single-choice.png +0 -0
  32. assets/images/spinner.gif +0 -0
  33. assets/images/stripe.png +0 -0
  34. assets/images/true-false.png +0 -0
  35. assets/js/admin/admin.js +825 -0
  36. assets/js/admin/meta-box-course.js +1397 -0
  37. assets/js/admin/meta-box-order.js +170 -0
  38. assets/js/admin/meta-box-question.js +422 -0
  39. assets/js/admin/meta-box-quiz.js +268 -0
  40. assets/js/admin/modal-search-items.js +144 -0
  41. assets/js/admin/question.min.js +21 -0
  42. assets/js/admin/settings.js +91 -0
  43. assets/js/admin/statistic.js +195 -0
  44. assets/js/chart.min.js +10 -0
  45. assets/js/frontend/add-to-cart.js +24 -0
  46. assets/js/frontend/checkout.js +123 -0
  47. assets/js/frontend/course-lesson.js +202 -0
  48. assets/js/frontend/enroll.js +65 -0
  49. assets/js/frontend/learnpress.js +72 -0
  50. assets/js/frontend/single-course.js +196 -0
  51. assets/js/frontend/single-quiz.js +731 -0
  52. assets/js/global.js +670 -0
  53. assets/js/global.min.js +38 -0
  54. assets/js/jquery.alert.js +210 -0
  55. assets/js/jquery.appear.js +102 -0
  56. assets/js/jquery.caret.js +79 -0
  57. assets/js/jquery.timer.js +84 -0
  58. assets/js/jquery.tipsy.js +258 -0
  59. assets/js/learnpress.js +602 -0
  60. assets/js/toJSON.js +100 -0
  61. changelog.md +114 -0
  62. dummy-data/dummy-data.xml +1453 -0
  63. dummy-data/learnpress-how-to-use-learnpress.xml +1373 -0
  64. inc/abstracts/abstract-lp-assets.php +262 -0
  65. inc/admin/class-lp-admin-ajax.php +947 -0
  66. inc/admin/class-lp-admin-assets.php +55 -0
  67. inc/admin/class-lp-admin-menu.php +121 -0
  68. inc/admin/class-lp-admin-notice.php +87 -0
  69. inc/admin/class-lp-admin-settings.php +204 -0
  70. inc/admin/class-lp-admin.php +81 -0
  71. inc/admin/class-lp-email.php +100 -0
  72. inc/admin/class-lp-plugin-install-list-table.php +489 -0
  73. inc/admin/class-lp-profile.php +139 -0
  74. inc/admin/class-lp-upgrader.php +176 -0
  75. inc/admin/includes/class-markdown-parse.php +2932 -0
  76. inc/admin/includes/class-readme-parse.php +329 -0
  77. inc/admin/lp-admin-functions.php +1283 -0
  78. inc/admin/meta-boxes/class-course-tabs-field.php +20 -0
  79. inc/admin/meta-boxes/class-curriculum-field.php +333 -0
  80. inc/admin/meta-boxes/class-question-field.php +73 -0
  81. inc/admin/meta-boxes/class-quiz-questions-field.php +194 -0
  82. inc/admin/pointers/pointers.php +74 -0
  83. inc/admin/settings/class-lp-settings-base.php +272 -0
  84. inc/admin/settings/class-lp-settings-checkout.php +107 -0
  85. inc/admin/settings/class-lp-settings-courses.php +144 -0
  86. inc/admin/settings/class-lp-settings-emails.php +158 -0
  87. inc/admin/settings/class-lp-settings-general.php +131 -0
  88. inc/admin/settings/class-lp-settings-pages.php +174 -0
  89. inc/admin/settings/class-lp-settings-payments.php +101 -0
  90. inc/admin/settings/class-lp-settings-profile.php +48 -0
  91. inc/admin/sub-menus/add-ons.php +62 -0
  92. inc/admin/sub-menus/settings.php +104 -0
  93. inc/admin/sub-menus/statistics.php +253 -0
  94. inc/admin/views/admin-notice.php +13 -0
  95. inc/admin/views/admin-template.php +17 -0
  96. inc/admin/views/meta-boxes/course/curriculum.php +77 -0
  97. inc/admin/views/meta-boxes/course/js-template.php +116 -0
  98. inc/admin/views/meta-boxes/course/loop-item.php +50 -0
  99. inc/admin/views/meta-boxes/course/loop-section.php +95 -0
  100. inc/admin/views/meta-boxes/course/review-log.php +103 -0
  101. inc/admin/views/meta-boxes/course/review-logs.php +43 -0
  102. inc/admin/views/meta-boxes/course/tabs.php +23 -0
  103. inc/admin/views/meta-boxes/order/actions.php +98 -0
  104. inc/admin/views/meta-boxes/order/details.php +107 -0
  105. inc/admin/views/meta-boxes/order/order-item.php +16 -0
  106. inc/admin/views/meta-boxes/question/footer.php +7 -0
  107. inc/admin/views/meta-boxes/question/header.php +27 -0
  108. inc/admin/views/meta-boxes/question/multi-choice-options.php +65 -0
  109. inc/admin/views/meta-boxes/question/none.php +16 -0
  110. inc/admin/views/meta-boxes/question/single-choice-options.php +72 -0
  111. inc/admin/views/meta-boxes/quiz/js-template.php +45 -0
  112. inc/admin/views/meta-boxes/quiz/question.php +42 -0
  113. inc/admin/views/meta-boxes/quiz/questions.php +50 -0
  114. inc/admin/views/settings/checkout.php +82 -0
  115. inc/admin/views/settings/courses.php +154 -0
  116. inc/admin/views/settings/emails/become-a-teacher-request.php +48 -0
  117. inc/admin/views/settings/emails/email-template.php +94 -0
  118. inc/admin/views/settings/emails/enrolled-course.php +63 -0
  119. inc/admin/views/settings/emails/finished-course.php +63 -0
  120. inc/admin/views/settings/emails/general.php +55 -0
  121. inc/admin/views/settings/emails/new-course.php +81 -0
  122. inc/admin/views/settings/emails/new-order.php +81 -0
  123. inc/admin/views/settings/emails/published-course.php +63 -0
  124. inc/admin/views/settings/emails/rejected-course.php +67 -0
  125. inc/admin/views/settings/fields/checkbox.php +45 -0
  126. inc/admin/views/settings/fields/course-permalink.php +83 -0
  127. inc/admin/views/settings/fields/html.php +15 -0
  128. inc/admin/views/settings/fields/image-size.php +20 -0
  129. inc/admin/views/settings/fields/pages-dropdown.php +8 -0
  130. inc/admin/views/settings/fields/select.php +34 -0
  131. inc/admin/views/settings/fields/text.php +33 -0
  132. inc/admin/views/settings/fields/textarea.php +30 -0
  133. inc/admin/views/settings/fields/title.php +3 -0
  134. inc/admin/views/settings/general.php +105 -0
  135. inc/admin/views/settings/pages/become-a-teacher.php +24 -0
  136. inc/admin/views/settings/pages/profile.php +24 -0
  137. inc/admin/views/settings/pages/quiz.php +24 -0
  138. inc/admin/views/settings/payments.php +107 -0
  139. inc/admin/views/settings/profile.php +35 -0
  140. inc/admin/views/settings/setting-field.php +121 -0
  141. inc/admin/views/statistics/courses.php +58 -0
  142. inc/admin/views/statistics/orders.php +56 -0
  143. inc/admin/views/statistics/users.php +32 -0
README.md ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [![Stories in Ready](https://badge.waffle.io/LearnPress/LearnPress.svg?label=ready&title=Ready)](http://waffle.io/LearnPress/LearnPress)
2
+
3
+ <a href="http://thimpress.com/learnpress" target="_blank">LearnPress</a> is a comprehensive WordPress LMS Plugin for WordPress. This WordPress LMS Plugin can be used to easily create & sell courses online. Each course curriculum can be made with lessons & quizzes which can be managed with easy-to-use user interface, we really made it for lazy people.
4
+
5
+ [youtube https://www.youtube.com/watch?v=rRWPl5-Hb4k&hd=1&&cc_load_policy=1]
6
+
7
+ **LearnPress LMS Plugin works with your theme**
8
+ We create LearnPress LMS Plugin to work with any WordPress themes.
9
+
10
+ Here are some WordPress Themes designed to work with LearnPress: [Education WordPress Theme](http://themeforest.net/item/education-wordpress-theme-education-wp/14058034 "Education WordPress Theme") and [LMS WordPress theme](http://themeforest.net/item/lms-wordpress-theme-elearning-wp/11797847 "LMS WordPress Theme"). More will coming soon.
11
+
12
+
13
+ **LearnPress Support WordPress Multisites**
14
+
15
+ **LearnPress features**
16
+ *Create course*
17
+ LearnPress LMS Plugin provide an excellent user interface to create a course with options you need. You can find it easy to make a full curriculum layout as well as edit and maintain it.
18
+ You can also export course and import to other website which also using LearnPress. We will provide the feature allow you to import course from other WordPress LMS plugins soon.
19
+
20
+ *Manage course*
21
+ With the course you've created, you can share it, manage it, watch statistic about number of student, its trend, etc.
22
+
23
+ *Sell course*
24
+ LearnPress is free but it still allow you to sell courses you create with support many billing method such as paypal, woocommerce, stripe, etc.
25
+
26
+ *Communicate with your students*
27
+ With BuddyPress support, LearnPress will help you to communicate with your student or instructor via WordPress forum. Learning is not only on your own. Study, make friends and have fun.
28
+
29
+ *LearnPress provide a bunch of add-on*
30
+ Add-on is used to providing extra features for LearnPress and you can also write it.
31
+
32
+ <a href="http://docs.thimpress.com/learnpress" target="_blank">LearnPress WordPress LMS Plugin Documentation</a>
33
+
34
+ **LearnPress is free and always will be**
35
+ Education should be free and we want you to bring it to as many people as you can. Therefore, we create LearnPress as a tool for you to create course and share it. We'll continue developing it as long as we can and make it better and better.
36
+
37
+ **LearnPress is actively developed**
38
+ We are developing and improving LearnPress day by day and bringing new features to you cos we want LearnPress to become the best WordPress plugin in LMS.
39
+
40
+ **Free add-ons for LearnPress WordPress LMS Plugin:**
41
+
42
+ - [LearnPress Wishlist](https://wordpress.org/plugins/learnpress-wishlist) - add courses to a wishlist for students.
43
+ - [LearnPress Course Review](https://wordpress.org/plugins/learnpress-course-review) - review course for enrolled students.
44
+ - [LearnPress Import/Export](https://wordpress.org/plugins/learnpress-import-export) - export or import course or courses out-of-box.
45
+ - [LearnPress Prerequisites Courses](https://wordpress.org/plugins/learnpress-prerequisites-courses) - require student to pass some courses in order to enroll other course.
46
+ - [LearnPress bbPress Integration](https://wordpress.org/plugins/learnpress-bbpress) - add bbPress Forum support for LearnPress WordPress LMS Plugin.
47
+ - [LearnPress BuddyPress Integration](https://wordpress.org/plugins/learnpress-buddypress) - add BuddyPress support for LearnPress WordPress LMS Plugin.
48
+
49
+ **Premium add-ons for LearnPress WordPress LMS Plugin:**
50
+
51
+ - [Certificates add-on for LearnPress](http://thimpress.com/shop/certificates-add-on-for-learnpress/) - adding drag & drop certificates builder as well as selecting designed certificate for each LMS course, your student will get particular certificate when they finished a course.
52
+ - [Co-instructors add-on for LearnPress](http://thimpress.com/shop/co-instructors-add-on-for-learnpress/) - multiple instructors support for each LMS course.
53
+ - [Collections add-on for LearnPress](http://thimpress.com/shop/collections-add-on-for-learnpress/) - making LMS courses collection by selecting number of courses, this is helpful if you want to combine multiple LMS courses into a collection for a group of skills.
54
+ - [Stripe Payment method for LearnPress](http://thimpress.com/shop/stripe-add-on-for-learnpress/) - Stripe payment method for LearnPress WordPress LMS Plugin.
55
+ - [WooCommerce add-on for LearnPress](http://thimpress.com/shop/woocommerce-add-on-for-learnpress/) - using WooCommerce as payment gateway for LearnPrss WordPress LMS Plugin.
56
+
57
+ **WordPress LMS Plugin - LearnPress ROADMAP:**
58
+
59
+ - Payment Method support (first priority)
60
+ - Authorize.net
61
+ - Google Checkout
62
+ - Amazon Payments
63
+ - Dwolla
64
+ - Braintree
65
+ - Samurai by FeeFighters
66
+ - WePay
67
+ - 2Checkout
68
+ - Assignment
69
+ - Gradebook
70
+ - Paid MemberShip Pro
71
+ - Events
72
+ - myCRED integration
73
+ - Share Grade
74
+ - BadgeOS
75
+ - Content Drip
76
+ - Manually reset quiz for retake
77
+ - Create quiz from randoms questions in question bank
78
+ - Attachment restriction for lesson
79
+ - Mathjax support
80
+ - Presentation support (maybe support SlideShare)
81
+ - Show enrolled user
82
+ - Student ranks
83
+ - REST API for mobile app
84
+ - No distraction mode (when doing quiz)
85
+ - Report/feedback about a question/quiz/lesson
86
+ - Commission for payment method
87
+ - Instructor's note
88
+ - Private message from Admin to teacher
89
+ - Group payment
90
+ - Announcement (come up with email)
91
+
92
+ Any suggestions for this WordPress LMS Plugin? Send us <a href="http://thimpress.com/learnpress-suggestion/" target="_blank">here.</a>
93
+
94
+
95
+ ##Installation
96
+
97
+ **From your WordPress dashboard**
98
+ 1. Visit 'Plugin > Add new'.
99
+ 2. Search for 'LearnPress'.
100
+ 3. Activate LearnPress from your Plugins page.
101
+
102
+ **From WordPress.org**
103
+ 1. Search, select and download LearnPress.
104
+ 2. Activate the plugin through the 'Plugins' menu in WordPress Dashboard.
105
+
106
+ ##Frequently Asked Questions
107
+
108
+ **What is LearnPress ?**
109
+ LearnPress is a plugin to create a LMS website, to spread out course, or sell course.
110
+
111
+ **Where can I find LearnPress documentation and user guides?**
112
+ If you want to use LearnPress to build a Learning Management Website, please refer to our user guides in <a href="http://docs.thimpress.com/learnpress/" target="_blank">LearnPress official site.</a>
113
+ And if you want to extending or theming LearnPress, see our <a href="https://github.com/LearnPress/LearnPress/wiki">Wiki</a>
114
+
115
+ **Where can I get support or talk to other users?**
116
+ If you get troubles when using LearnPress you can ask for help on the LearnPres Support Forum
117
+
118
+ For help with premium add-ons, use our helpdesk.
119
+
120
+ **Where can I ask for new features or suggest ideas or themes for LearnPress?**
121
+ You can send us your ideas through form <a href="http://thimpress.com/learnpress-suggestion/" target="_blank">here.</a>here
122
+
123
+ **Where can I report bugs or contribute to the project?**
124
+ You can also report bugs on LearnPress Support Forum or LearnPress <a href="https://github.com/LearnPress/LearnPress/issues" target="_blank">Github Repository</a>.
125
+
126
+ **Where can I find the REST API documentation?**
127
+ We will provide documentation about LearnPress REST API really soon.
128
+
129
+ **LearnPress is great, can I contribute to it?**
130
+ Yes, you can and we appreciate it. Join in our <a href="https://github.com/LearnPress/LearnPress" target="_blank">Github Repository</a>.
131
+
132
+ **LearnPress Translation project**
133
+ https://www.transifex.com/projects/p/learnpress/
134
+
135
+ **Other note**
136
+ <a href="http://docs.thimpress.com/learnpress" target="_blank">Documentation</a> is available in ThimPress site.
assets/css/admin/admin.css ADDED
@@ -0,0 +1,1314 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Define all styles for admin side
3
+ *
4
+ * @author ThimPress
5
+ * @version 1.0
6
+ */
7
+ .lp-nav-tab-wrapper {
8
+ border-bottom: 1px solid #ccc;
9
+ margin: 0;
10
+ padding: 9px 15px 0 0;
11
+ line-height: inherit;
12
+ }
13
+ .learn-press-quick-add-page-inline{
14
+ display: inline-block;
15
+ vertical-align: top;
16
+ margin: 0 !important;
17
+ }
18
+ .learn-press-quick-add-page-inline > *{
19
+ vertical-align: top;
20
+ }
21
+ .post-type-lp_course .column-price{
22
+ width: 10%;
23
+ }
24
+ /* message box */
25
+ #learn-press-message-box-block{
26
+ position: fixed;
27
+ top: 0;
28
+ left: 0;
29
+ right: 0;
30
+ bottom: 0;
31
+ background-color: #000;
32
+ z-index: 99999;
33
+ opacity: 0.8;
34
+ }
35
+ #learn-press-message-box-window{
36
+ position: fixed;
37
+ top: 0;
38
+ bottom: 0;
39
+ left: 0;
40
+ right: 0;
41
+ z-index: 100000;
42
+ color: #FFF;
43
+ text-align: center;
44
+ }
45
+ #message-box-wrap{
46
+ margin: 0 auto;
47
+ /* text-align: center; */
48
+ display: inline-block;
49
+ text-align: left;
50
+ max-width: 70%;
51
+ }
52
+ .message-box-title{
53
+ color: #FFF;
54
+ margin: 0 0 40px 0;
55
+ font-size: 34px;
56
+ }
57
+ .message-box-content{
58
+ font-size: 16px;
59
+ line-height: 1.5;
60
+ }
61
+ .message-box-animation{
62
+ background-image: url("../../images/animation.gif");
63
+ width: 220px;
64
+ height: 20px;
65
+ margin: 20px 0 0;
66
+ }
67
+ .message-box-buttons{
68
+ margin: 20px 0 0;
69
+ border-top: 1px solid #929292;
70
+ padding-top: 20px;
71
+ }
72
+ .message-box-button{
73
+ margin-right: 10px !important;
74
+ }
75
+
76
+ .post-type-lp_lesson .column-format .lp-label{
77
+ font-size: 100%;
78
+ }
79
+ /*********************************/
80
+ .hide {
81
+ display: none;
82
+ }
83
+
84
+ .handle.dashicons {
85
+ cursor: move;
86
+ margin-right: 10px;
87
+ }
88
+
89
+ .meta_box_remove .dashicons {
90
+ text-decoration: initial;
91
+ }
92
+
93
+ .meta_box_course_lesson_quiz li input,
94
+ .meta_box_course_lesson_quiz li select {
95
+ min-width: 250px;
96
+ }
97
+
98
+ .rwmb-meta-box label {
99
+ color: #222;
100
+ font-weight: bold;
101
+ display: block;
102
+ margin: 16px 0;
103
+ }
104
+
105
+ .description {
106
+ margin-top: 5px;
107
+ }
108
+
109
+ .dashed-placeholder {
110
+ border: 2px dashed #999;
111
+ padding: 10px;
112
+ }
113
+
114
+ .learn-press-admin-notice-dismiss:before{
115
+ font-family: dashicons;
116
+ content: '\f335';
117
+ width: 20px;
118
+ height: 20px;
119
+ display: inline-block;
120
+ background-color: #FFFFFF;
121
+ border-radius: 50%;
122
+ line-height: 20px;
123
+ text-align: center;
124
+ box-shadow: 0px 0px 1px 1px #F1F1F1;
125
+ font-size: 18px;
126
+ vertical-align: middle;
127
+ float: right;
128
+ }
129
+ /**
130
+ * Course Metabox
131
+ */
132
+ li.quiz, li.lesson, li.quick_lesson, li.quick_quiz {
133
+ margin-left: 30px;
134
+ }
135
+
136
+ .wp-core-ui .meta_box_add_section,
137
+ .wp-core-ui .meta_box_add_lesson,
138
+ .wp-core-ui .meta_box_add_quiz,
139
+ .wp-core-ui .meta_box_quick_add_lesson,
140
+ .wp-core-ui .meta_box_quick_add_quiz {
141
+ margin-right: 10px;
142
+ }
143
+ .column-taxonomy-course_category{
144
+ width: 15%;
145
+ }
146
+ /**/
147
+ #lpr-block {
148
+ position: fixed;
149
+ top: 0;
150
+ left: 0;
151
+ right: 0;
152
+ bottom: 0;
153
+ background-color: #000;
154
+ display: none;
155
+ z-index: 200;
156
+ opacity: 0.2;
157
+ }
158
+
159
+ .lpr-quick-add-form {
160
+ background-color: #FFF;
161
+ padding: 5px;
162
+ position: absolute;
163
+ z-index: 210;
164
+ border: 1px solid #DDD;
165
+ }
166
+
167
+ .lpr-quick-add-form input {
168
+ font-size: 15px;
169
+ border-radius: 3px;
170
+ border: 1px solid #DDD;
171
+ width: 350px;
172
+ }
173
+
174
+ .lpr-quick-add-form input,
175
+ .lpr-quick-add-form select {
176
+ vertical-align: top;
177
+ }
178
+
179
+ .lpr-quick-add-form .lpr-ajaxload {
180
+ display: none;
181
+ background: url(../../images/spinner.gif) no-repeat center;
182
+ width: 30px;
183
+ color: #FFF;
184
+ margin-top: 6px;
185
+ }
186
+
187
+ .lpr-quick-add-form.working .lpr-ajaxload {
188
+ display: inline-block;
189
+ }
190
+
191
+ .lpr-quick-add-form.working button {
192
+ display: none;
193
+ }
194
+
195
+ .post-type-lpr_question .lpr-question-option-label {
196
+ display: none;
197
+ }
198
+
199
+ #lpr-question-options-wrap {
200
+ margin-top: 8px;
201
+ }
202
+
203
+ .lpr-question tr.lpr-disabled .dashicons-trash,
204
+ .lpr-question tr.lpr-disabled .dashicons-sort {
205
+ display: none;
206
+ }
207
+
208
+ /*
209
+ * Add on page
210
+ */
211
+
212
+ .lpr-add-ons-wrapper .add-on-info {
213
+ width: 65%;
214
+ display: inline-block;
215
+ }
216
+
217
+ .lpr-add-ons-wrapper .add-on-action {
218
+ float: right;
219
+ }
220
+
221
+ .lpr-add-ons-wrapper .add-on-action a {
222
+ text-decoration: none;
223
+ padding: 20px;
224
+ height: 80px;
225
+ width: 100px;
226
+ background: #EBEBEB;
227
+ margin-right: 100px;
228
+ }
229
+
230
+ .lpr-add-ons-wrapper .add-on-action .add-on-enabled {
231
+ text-align: center;
232
+ margin: 40px;
233
+ }
234
+
235
+ .lpr-add-ons-wrapper .add-on-action .add-on-disabled {
236
+ text-align: center;
237
+ margin: 40px;
238
+ }
239
+
240
+ .lpr-add-ons-wrapper .add-on-action a:hover {
241
+ text-decoration: none;
242
+ content: attr(data-text-disable);
243
+ }
244
+
245
+ .learn-press-add-ons{
246
+ margin: 20px 0 0;
247
+ }
248
+ .learn-press-add-ons:after{
249
+ display: block;
250
+ clear: both;
251
+ content: '';
252
+ }
253
+ .learn-press-add-ons > li{
254
+ /*float: left;*/
255
+ /*width: 25%;*/
256
+ /*position: relative;*/
257
+ }
258
+ .learn-press-add-ons > li .add-on-inner{
259
+ margin: 0 20px 40px 20px;
260
+ border: 1px solid #DDD;
261
+ border-radius: 10px;
262
+ overflow: hidden;
263
+ }
264
+ .learn-press-add-ons > li .add-on-thumbnail{
265
+ position: relative;
266
+ overflow: hidden;
267
+ border-bottom: 1px solid #E3E3E3;
268
+ }
269
+ .learn-press-add-ons > li .add-on-thumbnail img{
270
+ width: 100%;
271
+ height: auto;
272
+ vertical-align: top;
273
+ }
274
+ .learn-press-add-ons > li .add-on-thumbnail .add-on-overlay{
275
+ position: absolute;
276
+ left: 0;
277
+ right: 0;
278
+ height: 100%;
279
+ top: 0;
280
+ -webkit-transition: all 0.25s ;
281
+ background-color: #ADE6FF;
282
+ opacity: 0;
283
+ }
284
+ .learn-press-add-ons > li .add-on-thumbnail .add-on-description{
285
+ position: absolute;
286
+ left: 20px;
287
+ right: 20px;
288
+ bottom: 0;
289
+ -webkit-transition: all 0.25s ;
290
+ color: #444;
291
+ opacity: 0;
292
+ }
293
+ .learn-press-add-ons > li:hover .add-on-overlay{
294
+ opacity: 0.3;
295
+ }
296
+ .learn-press-add-ons > li:hover .add-on-description{
297
+ opacity: 1;
298
+ }
299
+ .learn-press-add-ons > li .add-on-info{
300
+ min-height: 80px;
301
+ padding: 20px;
302
+ background-color: #F5F5F5;
303
+ border-top: 1px solid #FFF;
304
+ }
305
+ .learn-press-add-ons > li .add-on-info > h3{
306
+ margin-top: 0;
307
+ }
308
+ .learn-press-add-ons > li .add-on-actions{
309
+ position: absolute;
310
+ bottom: 43px;
311
+ }
312
+ .learn-press-add-ons > li .add-on-actions .add-on-state{
313
+ font-size: 36px;
314
+ vertical-align: top;
315
+ display: none;
316
+ margin-top: -8px;
317
+ color: #05B3FF;
318
+ margin-left: -9px;
319
+ }
320
+ .learn-press-add-ons > li .add-on-actions .add-on-state.change{
321
+ display: inline-block;
322
+ }
323
+ .learn-press-add-ons .plugin-card-top{
324
+ min-height: 180px;
325
+ }
326
+ .learn-press-add-ons .button.spinner{
327
+ background: url(../../images/spinner.gif) no-repeat 4px !important;
328
+ padding-left: 30px;
329
+ visibility: visible;
330
+ width: auto;
331
+ }
332
+ .learn-press-add-ons .action-links > span{
333
+ display: block;
334
+ text-align: right;
335
+ font-style: italic;
336
+ }
337
+ .learn-press-add-ons .action-links > span.enabled{
338
+ color: #7ad03a;
339
+ }
340
+ .learn-press-add-ons .action-links > span.disabled{
341
+ color: #FF0000;
342
+ }
343
+ .learn-press-add-ons .plugin-icon img{
344
+ max-width: 100%;
345
+ }
346
+ #learn-press-bundle-activate-add-ons.spinner{
347
+ float: left !important;
348
+ }
349
+ .learn-press-add-ons .plugin-version{
350
+ font-weight: bold;
351
+ }
352
+ #learn-press-add-ons-wrap #name{
353
+ width: 30%;
354
+ }
355
+
356
+ @media (max-width: 1280px) {
357
+ .learn-press-add-ons > li{
358
+ width: 33.33%;
359
+ }
360
+ }
361
+ @media (max-width: 768px) {
362
+ .learn-press-add-ons > li{
363
+ width: 50%;
364
+ }
365
+ }
366
+ @media (max-width: 480px) {
367
+ .learn-press-add-ons > li{
368
+ width: 100%;
369
+ }
370
+ }
371
+ /**/
372
+
373
+ #lpr-quiz-questions-wrap .select2-container .select2-choice {
374
+ height: 29px;
375
+ padding-top: 3px;
376
+ font-size: 14px;
377
+ }
378
+
379
+ .post-title.column-title {
380
+ overflow: visible;
381
+ }
382
+
383
+ .lpr-row-actions {
384
+ display: inline-block;
385
+ position: relative;
386
+ }
387
+
388
+ .lpr-row-action-dropdown {
389
+ position: absolute;
390
+ top: 100%;
391
+ left: 0;
392
+ min-width: 150px;
393
+ background-color: #FFF;
394
+ border: 1px solid #DDD;
395
+ padding: 0;
396
+ margin: 0;
397
+ display: none;
398
+ }
399
+
400
+ .lpr-row-action-dropdown > li {
401
+ margin: 0;
402
+ }
403
+
404
+ .lpr-row-action-dropdown > li > a {
405
+ display: block;
406
+ padding: 5px;
407
+ }
408
+
409
+ .lpr-row-actions > a {
410
+ padding-right: 15px;
411
+ position: relative;
412
+ }
413
+
414
+ .lpr-row-actions > a:after {
415
+ width: 0;
416
+ height: 0;
417
+ border: 5px solid transparent;
418
+ border-top-color: #DDD;
419
+ content: '';
420
+ display: inline-block;
421
+ position: absolute;
422
+ right: 0;
423
+ top: 6px;
424
+ }
425
+
426
+ .lpr-row-actions:hover > ul {
427
+ display: block;
428
+ }
429
+
430
+ /* addons page */
431
+ #lpr-add-ons-wrapper {
432
+ }
433
+
434
+ #lpr-add-ons-wrapper .lpr-add-on-block {
435
+ border-bottom: 1px dashed #DDD;
436
+ padding-bottom: 20px;
437
+ width: 50%;
438
+ float: left;
439
+ margin-top: 20px;
440
+ }
441
+
442
+ #lpr-add-ons-wrapper .lpr-add-on-block:after {
443
+ content: '';
444
+ display: block;
445
+ clear: both;
446
+ }
447
+
448
+ #lpr-add-ons-wrapper .lpr-admin-thumbnail {
449
+ float: left;
450
+ width: 200px;
451
+ }
452
+
453
+ #lpr-add-ons-wrapper .lpr-admin-thumbnail img {
454
+ vertical-align: top;
455
+ }
456
+
457
+ #lpr-add-ons-wrapper .lpr-add-on-info {
458
+ margin-left: 220px;
459
+ margin-right: 20px;
460
+ }
461
+
462
+ #lpr-add-ons-wrapper .lpr-add-on-info > h3{
463
+ margin-top: 0;
464
+ }
465
+
466
+ #lpr-add-ons-wrapper .lpr-add-on-info > h3 > span {
467
+ display: inline-block;
468
+ padding: 0 5px;
469
+ background-color: #7AD3FA;
470
+ color: #FFF;
471
+ border-radius: 3px;
472
+ margin-left: 10px;
473
+ font-size: 12px;
474
+ vertical-align: top;
475
+ font-weight: normal;
476
+ }
477
+
478
+ #lpr-add-ons-wrapper .lpr-add-on-action {
479
+ float: right;
480
+ width: 100px;
481
+ }
482
+
483
+ /* toggle */
484
+ input.lpr-fancy-checkbox {
485
+ display: none;
486
+ }
487
+
488
+ .lpr-fancy-checkbox.tog {
489
+ border-radius: 20px;
490
+ box-shadow: inset 0 0 4px rgba(0, 0, 0, .6);
491
+ margin: 0 auto;
492
+ height: 19px;
493
+ width: 50px;
494
+ position: relative;
495
+ cursor: pointer;
496
+ font: 11px/18px arial;
497
+ background: #ccc;
498
+ -webkit-transition: all .2s ease;
499
+ -moz-transition: all .2s ease;
500
+ -o-transition: all .2s ease;
501
+ transition: all .2s ease;
502
+ display: inline-block !important;
503
+ }
504
+
505
+ .lpr-fancy-checkbox.tog:after {
506
+ content: '';
507
+ box-shadow: 0 2px 2px rgba(0, 0, 0, .6);
508
+ border-radius: 20px;
509
+ display: block;
510
+ height: 15px;
511
+ width: 15px;
512
+ background: #fff;
513
+ position: absolute;
514
+ top: 2px;
515
+ left: 2px;
516
+ -webkit-transition: all .2s ease;
517
+ -moz-transition: all .2s ease;
518
+ -o-transition: all .2s ease;
519
+ transition: all .2s ease;
520
+ }
521
+
522
+ .lpr-fancy-checkbox.tog:before {
523
+ content: 'OFF';
524
+ position: absolute;
525
+ right: 7px;
526
+ top: 1px;
527
+ color: #fff;
528
+ }
529
+
530
+ .lpr-fancy-checkbox.tog:hover:after {
531
+ left: 5px;
532
+ }
533
+
534
+ .lpr-fancy-checkbox.tog.on:before {
535
+ content: 'ON';
536
+ right: 28px;
537
+ }
538
+
539
+ .lpr-fancy-checkbox.tog.on {
540
+ background: #05B3FF;
541
+ }
542
+
543
+ .lpr-fancy-checkbox.tog.on:after {
544
+ left: 33px;
545
+ }
546
+
547
+ .lpr-fancy-checkbox.tog.on:hover:after {
548
+ left: 30px;
549
+ }
550
+
551
+ /**/
552
+ .clearfix:after {
553
+ display: block;
554
+ content: '';
555
+ clear: both;
556
+ }
557
+
558
+ .clear {
559
+ display: block;
560
+ clear: both;
561
+ height: 0;
562
+ }
563
+
564
+ /**********************************************************************/
565
+ /**********************************************************************/
566
+
567
+ .lp-list-options{
568
+ border: 1px solid #DDD;
569
+ border-collapse: collapse;
570
+ width: 100%;
571
+ }
572
+ .lp-list-option{
573
+
574
+ }
575
+ .lp-list-option.lp-list-option-empty td,
576
+ .lp-list-option.lp-list-option-empty th{
577
+ background-color: #FBE9E9;
578
+ }
579
+ .lp-list-option.lp-list-option-empty .lp-answer-check input,
580
+ .lp-list-option.lp-list-option-empty .lp-list-option-actions i{
581
+ display: none;
582
+ }
583
+ .lp-list-option .clm{
584
+
585
+ }
586
+ .lp-list-option .lp-item-checkbox{}
587
+ .lp-list-option .lp-item-name{}
588
+ .lp-list-option .lp-item-actions{}
589
+
590
+
591
+ .lp-list-options thead th{
592
+ border: 1px solid #FFF;
593
+ background-color: #EAEAEA;
594
+ padding: 10px;
595
+ text-align: left;
596
+
597
+ color: #00A0D2;
598
+
599
+ }
600
+ .lp-list-options tbody th,
601
+ .lp-list-options tbody td{
602
+ border: 1px solid #FFF;
603
+ padding: 10px 10px;
604
+ text-align: left;
605
+ background-color: #F5F5F5;
606
+ }
607
+ .lp-list-options .lp-answer-check{
608
+ width: 100px;
609
+ }
610
+ .lp-list-options tbody th input[type="text"],
611
+ .lp-list-options tbody td input[type="text"]{
612
+ width: 100%;
613
+ }
614
+ .lp-list-options .ui-sortable-placeholder{
615
+ visibility: visible !important;
616
+ }
617
+ .lp-list-options .ui-sortable-placeholder td{
618
+ background-image: url("../../images/stripe.png");
619
+ }
620
+ .lp-list-option .lp-answer-text{
621
+ color: #777;
622
+ background-color: transparent;
623
+ border-color: transparent;
624
+ box-shadow: none;
625
+ }
626
+ .lp-list-option .lp-answer-text:after{
627
+ font-family: dashicons;
628
+ content:'\f464';
629
+ }
630
+ .lp-list-option .lp-answer-text:focus,
631
+ .lp-list-option:hover .lp-answer-text{
632
+ box-shadow: none;
633
+ outline: none;
634
+ background-color: transparent;
635
+ border-color: transparent;
636
+ }
637
+ .lp-list-option:hover .lp-answer-text{
638
+ border-style: dashed;
639
+ }
640
+
641
+ .lp-list-option-actions{
642
+ cursor: pointer;
643
+ color: #00A0D2;
644
+ }
645
+ .lp-list-option-actions.lp-move-list-option{
646
+ cursor: move;
647
+ }
648
+ .lp-list-option-actions:hover{
649
+ color: #156077;
650
+ }
651
+ /* Question meta box */
652
+ #question_answer .rwmb-question-wrapper{
653
+ margin: 12px 0 0 0;
654
+ }
655
+
656
+ .question-bottom-actions > *{
657
+ vertical-align: baseline !important;
658
+ }
659
+
660
+ /* Quiz meta box */
661
+ body.post-type-lp_quiz #questions,
662
+ body.post-type-lp_question #question_answer_{
663
+ border: none;
664
+ box-shadow: none;
665
+ background-color: transparent;
666
+ }
667
+ body.post-type-lp_quiz #questions .handlediv,
668
+ body.post-type-lp_question #question_answer_ .handlediv{
669
+ display: none;
670
+ }
671
+ body.post-type-lp_quiz #questions .hndle,
672
+ body.post-type-lp_question #question_answer_ .hndle{
673
+ display: none;
674
+ }
675
+ body.post-type-lp_quiz #questions .inside,
676
+ body.post-type-lp_question #question_answer_ .inside{
677
+ padding: 0;
678
+ }
679
+ #questions .quiz-questions-heading{
680
+ margin: 0;
681
+ padding: 20px;
682
+ background-color: #FFF;
683
+ line-height: 1;
684
+ border: 1px solid #DDD;
685
+ }
686
+ #questions .quiz-questions-heading .questions-toggle{
687
+ float: right;
688
+ margin: 0;
689
+ line-height: 1;
690
+ }
691
+ #questions .quiz-questions-heading .questions-toggle a{
692
+ color: #DDD;
693
+ box-shadow: none;
694
+ }
695
+ #questions .quiz-questions-heading .questions-toggle a:hover{
696
+ color: #00a0d2;
697
+ }
698
+ #questions #learn-press-dropdown-questions{
699
+ display: inline-block;
700
+ position: relative;
701
+ }
702
+ #questions #learn-press-dropdown-questions > ul{
703
+ position: absolute;
704
+ top: 100%;
705
+ margin: 0;
706
+ padding: 0;
707
+ background-color: #FFF;
708
+ left: 0;
709
+ right: 0;
710
+ border: 1px solid #EEE;
711
+ border-top: none;
712
+ display: none;
713
+ z-index: 50;
714
+ }
715
+ #questions #learn-press-dropdown-questions > ul > li{
716
+ margin: 0;
717
+ }
718
+ #questions #learn-press-dropdown-questions > ul li > a{
719
+ display: block;
720
+ padding: 5px;
721
+ outline: none;
722
+ box-shadow: none;
723
+ }
724
+ #questions #learn-press-question-name{
725
+ font-size: 18px;
726
+ min-width: 350px;
727
+ margin: 0;
728
+ box-shadow: none;
729
+ border-color: #EEE;
730
+ color: #BBB;
731
+ vertical-align: middle;
732
+ }
733
+ #questions #learn-press-toggle-questions{
734
+ height: 32px;
735
+ vertical-align: top;
736
+ background-color: #FFF;
737
+ border: 1px solid #EEE;
738
+ width: 32px;
739
+ margin-left: -4px;
740
+ text-align: center;
741
+ font-size: 30px;
742
+ padding: 0;
743
+ color: #CCC;
744
+ border-left: none;
745
+ outline: none;
746
+ cursor: pointer;
747
+ }
748
+ #questions #learn-press-toggle-questions:hover{
749
+ color: #AAAAAA;
750
+ }
751
+ #questions #learn-press-button-add-question{
752
+ _vertical-align: middle;
753
+ }
754
+ #questions input[name="lp-new-question-name"]{
755
+
756
+ }
757
+ #questions .question-actions{
758
+ background-color: #FFF;
759
+ border: 1px solid #DDD;
760
+ padding: 10px;
761
+ display: inline-block;
762
+ margin-top: 20px;
763
+ position: relative;
764
+ z-index: 999;
765
+ }
766
+ #questions .quiz-question{
767
+ margin: -1px 0 0 0;
768
+ }
769
+ #questions .quiz-question .learn-press-question{
770
+ padding: 20px 20px 5px 20px;
771
+ background-color: #FFF;
772
+ border: 1px solid #DDD;
773
+ border-top: none;
774
+ }
775
+ #questions .quiz-question-head{
776
+ padding: 10px 20px;
777
+ border: 1px solid #DDD;
778
+ background-color: #F5F5F5;
779
+ position: relative;
780
+ }
781
+ #questions .quiz-question.is-hidden .quiz-question-head,
782
+ #questions .quiz-question.is-hidden .question-name{
783
+ background-color: #FFF;
784
+ }
785
+ #questions .quiz-question-head .quiz-question-actions{
786
+ float: right;
787
+ margin: 1px 0;
788
+ visibility: hidden;
789
+ padding-top: 2px;
790
+ }
791
+ #questions .quiz-question-head .quiz-question-actions a{
792
+ margin: 0 3px;
793
+ color: #DDD;
794
+ vertical-align: middle;
795
+ box-shadow: none;
796
+ }
797
+ #questions .quiz-question-head .quiz-question-actions a:hover{
798
+ color: #00a0d2;
799
+ }
800
+ #questions .quiz-question-head .quiz-question-actions a.move{
801
+ cursor: url("../../images/openhand.cur") 7 5, default;
802
+ position: absolute;
803
+ right: 0;
804
+ height: 50px;
805
+ top: 0;
806
+ background: url("../../images/grippy_large.png") left no-repeat;
807
+ width: 12px;
808
+ }
809
+ #questions .quiz-question-head:hover .quiz-question-actions{
810
+ visibility: visible;
811
+ }
812
+ #questions .quiz-question.ui-sortable-placeholder{
813
+ visibility: visible!important;
814
+ background-image: url("../../images/stripe.png");
815
+ border: 1px solid #DDD;
816
+ border-bottom: none;
817
+ }
818
+ #questions .question-name{
819
+ border: none;
820
+ box-shadow: none;
821
+ padding-left: 0;
822
+ width: 70%;
823
+ font-weight: bold;
824
+ color: #777;
825
+ vertical-align: middle;
826
+ background-color: #F5F5F5;
827
+ }
828
+ #questions .quiz-question-icon{
829
+ display: inline-block;
830
+ width: 25px;
831
+ height: 25px;
832
+ vertical-align: middle;
833
+ margin-right: 10px;
834
+ }
835
+ #questions .quiz-question-icon img{
836
+ max-width: 100%;
837
+ height: auto;
838
+ }
839
+ #questions #learn-press-dropdown-questions .added{
840
+ display: none;
841
+ }
842
+
843
+ .lpr-curriculum-section > h3 {
844
+ padding: 0 !important;
845
+ }
846
+
847
+ .lpr-curriculum-section > h3 .lpr-action {
848
+ top: 0;
849
+ right: 0;
850
+ }
851
+
852
+ .lpr-curriculum-section.lpr-empty > h3 {
853
+ cursor: default !important;
854
+ }
855
+
856
+ .lpr-curriculum-section.lpr-empty .lpr-action {
857
+ display: none !important;
858
+ }
859
+
860
+ .lpr-course-curriculum button span {
861
+ text-decoration: underline;
862
+ }
863
+ #learn-press-statistic{
864
+ margin-top: 20px;
865
+ }
866
+ .learn-press-chart {
867
+ position: relative;
868
+ }
869
+ .learn-press-chart canvas {
870
+ height: 70vh;
871
+ width: 100vw;
872
+ }
873
+ .chart-buttons form{
874
+ display: inline-block;
875
+ vertical-align: top;
876
+ }
877
+ .chart-buttons form input[type="text"]{
878
+ width: 105px;
879
+ font-size: 14px;
880
+ vertical-align: top;
881
+ margin: 0;
882
+ text-align: center;
883
+ font-weight: bold;
884
+ padding: 4px;
885
+ }
886
+ .chart-buttons form span{
887
+ display: inline-block;
888
+ vertical-align: middle;
889
+ font-weight: bold;
890
+ padding: 5px;
891
+ }
892
+ .learn-press-chart.loading:after{
893
+ content: '';
894
+ position: absolute;
895
+ top:0;
896
+ left: 0;
897
+ right: 0;
898
+ bottom: 0;
899
+ z-index: 10;
900
+ background: #FFF;
901
+ opacity: 0.5;
902
+ }
903
+ .chart-description{
904
+
905
+ }
906
+ .chart-description li{
907
+ display: inline-block;
908
+ margin-right: 15px;
909
+ }
910
+ .chart-description li:before{
911
+ content: '';
912
+ display: inline-block;
913
+ width: 10px;
914
+ height: 10px;
915
+ vertical-align: middle;
916
+ margin-right: 5px;
917
+ }
918
+ .chart-description li span{
919
+ display: inline-block;
920
+ vertical-align: middle;
921
+ font-weight: bold;
922
+ }
923
+ .chart-description li.all:before{
924
+ background: #2FA7FF;
925
+ }
926
+ .chart-description li.instructors:before{
927
+ background: #EAC79B;
928
+ }
929
+ .chart-description li.students:before{
930
+ background: #D4D0CB;
931
+ }
932
+ .lpr-stats-time {
933
+ text-align: center;
934
+ }
935
+
936
+ .lpr-hidden {
937
+ display: none;
938
+ }
939
+ #lpr-custom-time {
940
+ position: relative;
941
+ top: 4px;
942
+ }
943
+
944
+
945
+ /* block page */
946
+ #lpr-page-block{
947
+ position: fixed;
948
+ top: 0;
949
+ left: 0;
950
+ right: 0;
951
+ bottom: 0;
952
+ background-color: #000;
953
+ opacity: 0.5;
954
+ display: none;
955
+ z-index: 9999;
956
+ }
957
+
958
+ #form-quick-add-lesson-link{
959
+ position: absolute;
960
+ }
961
+
962
+ #_lpr_course_price_description>span {
963
+ font-weight: bold;
964
+ font-size: 15px;
965
+ }
966
+ .lpr-ignore, .lpr-ignore:hover {
967
+ color: #dd3d36;
968
+ }
969
+ .lpr-ignore:hover {
970
+ cursor: pointer;
971
+ }
972
+
973
+ .lpr-quick-add-page-inline,
974
+ .lpr-quick-actions-inline{
975
+ display: inline-block;
976
+ vertical-align: middle;
977
+ margin: 0 !important;
978
+ }
979
+
980
+ #lpr-toggle-quiz-mode{
981
+ background-color: #0077FF;
982
+ padding: 3px;
983
+ margin-left: 5px;
984
+ display: inline-block;
985
+ border-radius: 3px;
986
+ text-decoration: none;
987
+ color: #FFF;
988
+ }
989
+ .column-num_of_question{
990
+ width: 150px;
991
+ }
992
+
993
+ .lp-search-items input[name="lp-item-name"]{
994
+ width: 500px;
995
+ }
996
+ .lp-button-dropdown{
997
+ padding-left: 0 !important;
998
+ padding-right: 28px !important;
999
+ position: relative;
1000
+ z-index: 99998;
1001
+ }
1002
+ .lp-button-dropdown .lp-dropdown-label {
1003
+ padding-left: 10px;
1004
+ }
1005
+ .lp-button-dropdown .lp-dropdown-arrow{
1006
+ display: inline-block;
1007
+ /* width: 20px; */
1008
+ text-align: center;
1009
+ padding: 0 10px;
1010
+ position: absolute;
1011
+ top: -1px;
1012
+ bottom: -1px;
1013
+ }
1014
+ .lp-button-dropdown .lp-dropdown-items{
1015
+ position: absolute;
1016
+ margin: 0;
1017
+ /* width: 100%; */
1018
+ background-color: #FFF;
1019
+ top: 100%;
1020
+ margin-top: 1px;
1021
+ border: 1px solid #DDD;
1022
+ right: -1px;
1023
+ /* right: -1px; */
1024
+ width: 200px;
1025
+ z-index: 9999999;
1026
+ display: none;
1027
+ }
1028
+ .lp-button-dropdown .lp-dropdown-items li{
1029
+ margin: 0;
1030
+ }
1031
+ .lp-button-dropdown .lp-dropdown-items li a{
1032
+ display: block;
1033
+ padding: 10px;
1034
+ line-height: 1;
1035
+ text-decoration: none;
1036
+ outline: none;
1037
+ box-shadow: none;
1038
+ }
1039
+ .lp-button-dropdown .lp-dropdown-items li a:hover{
1040
+ background-color: #F5F5F5;
1041
+ }
1042
+ .lp-button-dropdown:not(.disabled) .lp-dropdown-arrow:hover + ul,
1043
+ .lp-button-dropdown:not(.disabled) ul:hover{
1044
+ display: block;
1045
+ }
1046
+ .curriculum-section.lp-empty-section {}
1047
+ .curriculum-section .lp-check-items,
1048
+ .curriculum-section .lp-check-items:hover{
1049
+ padding-left: 5px;
1050
+ padding-right: 12px;
1051
+ border-color: transparent;
1052
+ background: transparent;
1053
+ box-shadow: none;
1054
+ }
1055
+
1056
+ .column-format,
1057
+ .column-is_previewable,
1058
+ .column-taxonomy-question-tag{
1059
+ width: 10%;
1060
+ }
1061
+
1062
+ .learn-press-add-ons .plugin-card .install-now:before,
1063
+ .learn-press-add-ons .plugin-card .disable-now:before,
1064
+ .learn-press-add-ons .plugin-card .enable-now:before{
1065
+ margin: 3px 5px 0 -2px;
1066
+ display: inline-block;
1067
+ font: 400 20px/1 dashicons;
1068
+ /*speak: none;*/
1069
+ -webkit-font-smoothing: antialiased;
1070
+ -moz-osx-font-smoothing: grayscale;
1071
+ vertical-align: top;
1072
+ }
1073
+ .learn-press-add-ons .plugin-card .install-now:before {
1074
+ content: '\f106';
1075
+ color: #0073aa;
1076
+ }
1077
+ .learn-press-add-ons .plugin-card .disable-now:before {
1078
+ content: '\f147';
1079
+ color: #0073aa;
1080
+ }
1081
+ .learn-press-add-ons .plugin-card .enable-now:before {
1082
+ content: '\f335';
1083
+ color: #d54e21;
1084
+ }
1085
+ .learn-press-add-ons .plugin-card .disable-now:hover:before {
1086
+ content: '\f335';
1087
+ color: #d54e21;
1088
+ }
1089
+ .learn-press-add-ons .plugin-card .enable-now:hover:before {
1090
+ content: '\f147';
1091
+ color: #0073aa;
1092
+ }
1093
+ .learn-press-add-ons .plugin-card .button-working:before{
1094
+ content: '\f463' !important;
1095
+ -webkit-animation: lp-spinner 2s infinite linear;
1096
+ animation: lp-spinner 2s infinite linear;
1097
+ margin-right: 0;
1098
+ }
1099
+ .learn-press-add-ons .plugin-card .button-working span{
1100
+ display: none;
1101
+ }
1102
+ .lp-button-actions a{
1103
+ text-decoration: none;
1104
+ margin-left: 5px;
1105
+ }
1106
+
1107
+ .learn-press-quick-confirm{
1108
+ position: absolute;
1109
+ z-index: 9999;
1110
+ color: rgb(255, 255, 255);
1111
+ padding: 2px 8px;
1112
+ display: block;
1113
+ white-space: nowrap;
1114
+ left: -39.625px;
1115
+ top: 24px;
1116
+ background-color: #C90202;
1117
+ cursor: pointer;
1118
+ }
1119
+ .learn-press-quick-confirm:hover,
1120
+ .learn-press-quick-confirm:hover:before{
1121
+ background-color: #d73b00;
1122
+ }
1123
+ .learn-press-quick-confirm:before{
1124
+ content: '';
1125
+ display: block;
1126
+ position: absolute;
1127
+ /* border: 1px solid; */
1128
+ transform: rotate(45deg);
1129
+ width: 7px;
1130
+ height: 7px;
1131
+ top: -3px;
1132
+ background-color: #C90202;
1133
+ right: 7px;
1134
+ }
1135
+
1136
+ /* course */
1137
+ .wp-core-ui .meta_box_add_section,
1138
+ .wp-core-ui .meta_box_add_lesson {
1139
+ margin-right: 10px;
1140
+ }
1141
+
1142
+ .hide {
1143
+ display: none;
1144
+ }
1145
+
1146
+ .handle.dashicons {
1147
+ cursor: move;
1148
+ margin-right: 0;
1149
+ }
1150
+
1151
+ .meta_box_remove .dashicons {
1152
+ text-decoration: initial;
1153
+ }
1154
+
1155
+ .meta_box_course_lesson_quiz li input,
1156
+ .meta_box_course_lesson_quiz li select {
1157
+ min-width: 250px;
1158
+ }
1159
+
1160
+ .rwmb-meta-box label {
1161
+ color: #222;
1162
+ font-weight: bold;
1163
+ display: block;
1164
+ margin: 16px 0;
1165
+ }
1166
+
1167
+ .description {
1168
+ margin-top: 5px;
1169
+ }
1170
+
1171
+ .dashed-placeholder {
1172
+ border: 2px dashed #999;
1173
+ padding: 10px;
1174
+ }
1175
+ /*
1176
+ TuNN added 21 03 2015
1177
+ Modified 03 Apr 2015
1178
+ */
1179
+ /* Course Curriculumn meta box section*/
1180
+
1181
+ /************ version 1.0 **************/
1182
+
1183
+
1184
+ /* order */
1185
+ .post-type-lp_order #post-body-content,
1186
+ .post-type-lp_order #order_details .handlediv,
1187
+ .post-type-lp_order #order_details .hndle{
1188
+ display: none;
1189
+ }
1190
+ .post-type-lp_order #submitpost .misc-pub-section label{
1191
+ display: block;
1192
+ font-weight: bold;
1193
+ }
1194
+ #learn-press-order {
1195
+ margin: 15px;
1196
+ }
1197
+ #learn-press-order .order-data-number{
1198
+ font-size: 36px;
1199
+ padding: 0;
1200
+ margin-bottom: 20px;
1201
+ }
1202
+ #learn-press-order > h3{
1203
+ margin: 0 0 10px 0;
1204
+ padding: 0;
1205
+ }
1206
+ #learn-press-order .order-data-date,
1207
+ #learn-press-order .order-data-status,
1208
+ #learn-press-order .order-data-payment-method{
1209
+ font-size: 18px;
1210
+ padding: 0 0 10px 0;
1211
+ }
1212
+ #learn-press-order .user-display-name,
1213
+ #learn-press-order .user-email,
1214
+ #learn-press-order .user-ip-address{
1215
+ padding: 0;
1216
+ margin: 0 0 10px 0;
1217
+ }
1218
+ #learn-press-order .order-items table{
1219
+ border: 1px solid #DDD;
1220
+ border-collapse: collapse;
1221
+ width: 100%;
1222
+ }
1223
+ #learn-press-order .order-items table th,
1224
+ #learn-press-order .order-items table td{
1225
+ text-align: left;
1226
+ padding: 10px 15px;
1227
+ border: 1px solid #DDD;
1228
+ }
1229
+ #learn-press-install-sample-data-notice .install-sample-data-loading{
1230
+ display: none;
1231
+ }
1232
+ /* ios checkbox */
1233
+ .learn-press-checkbox{
1234
+ display: none !important;
1235
+ }
1236
+ .ios-ui-select{
1237
+ background: #dddddd;
1238
+ border: none !important;
1239
+ height: 18px;
1240
+ -webkit-border-radius: 9px;
1241
+ border-radius: 9px;
1242
+ width: 30px;
1243
+ -webkit-transition: all 0.3s ease-in-out;
1244
+ -moz-transition: all 0.3s ease-in-out;
1245
+ -ms-transition: all 0.3s ease-in-out;
1246
+ -o-transition: all 0.3s ease-in-out;
1247
+ transition: all 0.3s ease-in-out;
1248
+ -webkit-box-shadow: none;
1249
+ box-shadow: none;
1250
+ cursor: pointer;
1251
+ position: relative;
1252
+ display: inline-block;
1253
+ }
1254
+ .ios-ui-select.checked{
1255
+ -webkit-box-shadow: inset 0 0 0 18px #6ddc5f;
1256
+ box-shadow: inset 0 0 0 18px #6ddc5f;
1257
+ }
1258
+ .ios-ui-select.checked .inner{
1259
+ left: 13px;
1260
+ }
1261
+ .ios-ui-select .inner{
1262
+ width: 16px;
1263
+ height: 16px;
1264
+ position: absolute;
1265
+ top: 1px;
1266
+ left: 1px;
1267
+ -webkit-border-radius: 100%;
1268
+ border-radius: 100%;
1269
+ background: white;
1270
+ -webkit-transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
1271
+ -moz-transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
1272
+ -o-transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
1273
+ transition: all 350ms cubic-bezier(0, 0.89, 0.44, 1);
1274
+ -webkit-box-shadow: 0 1px 2px 0 rgba(0,0,0,0.2),0 3px 4px 0 rgba(0,0,0,0.1);
1275
+ box-shadow: 0 1px 2px 0 rgba(0,0,0,0.2),0 3px 4px 0 rgba(0,0,0,0.1);
1276
+ }
1277
+ .lp-label-counter{
1278
+ display: inline-block;
1279
+ /* padding: 5px; */
1280
+ line-height: 1;
1281
+ background-color: #0073AA;
1282
+ border-radius: 10px;
1283
+ height: 21px;
1284
+ line-height: 20px;
1285
+ text-align: center;
1286
+ min-width: 21px;
1287
+ color: #FFF;
1288
+ padding: 0 5px;
1289
+ }
1290
+ .column-num_of_question,
1291
+ .column-duration{
1292
+ width: 100px;
1293
+ text-align: left;
1294
+ }
1295
+ @-webkit-keyframes lp-spinner {
1296
+ 0% {
1297
+ -webkit-transform: rotate(0deg);
1298
+ transform: rotate(0deg);
1299
+ }
1300
+ 100% {
1301
+ -webkit-transform: rotate(359deg);
1302
+ transform: rotate(359deg);
1303
+ }
1304
+ }
1305
+ @keyframes lp-spinner {
1306
+ 0% {
1307
+ -webkit-transform: rotate(0deg);
1308
+ transform: rotate(0deg);
1309
+ }
1310
+ 100% {
1311
+ -webkit-transform: rotate(359deg);
1312
+ transform: rotate(359deg);
1313
+ }
1314
+ }
assets/css/admin/meta-box-course.css ADDED
@@ -0,0 +1,738 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .post-type-lp_course #postdivrich{
2
+ visibility: hidden;
3
+ }
4
+
5
+ #learn-press-review-message{
6
+ margin-bottom: 10px;
7
+ }
8
+ #learn-press-review-message > h4{
9
+ margin: 0 0 10px 0;
10
+ }
11
+ #learn-press-review-message > textarea{
12
+ width: 100%;
13
+ height: 100px;
14
+ }
15
+ #learn-press-button-toggle-editor{
16
+ margin: 20px 0 0;
17
+ }
18
+ #course_curriculum{
19
+ border: none;
20
+ background-color: transparent;
21
+ }
22
+ #course_curriculum .handlediv,
23
+ #course_curriculum .hndle{
24
+ display: none;
25
+ }
26
+ #course_curriculum .inside{
27
+ margin: 0;
28
+ padding: 0;
29
+ }
30
+ #course_curriculum .curriculum-heading{
31
+ margin: 0 0 20px 0;
32
+ padding: 10px 20px;
33
+ background-color: #FFF;
34
+ line-height: 1;
35
+ border: 1px solid #DDD;
36
+ }
37
+ #course_curriculum .curriculum-heading .description{
38
+ font-weight: normal;
39
+ color: #999;
40
+ display: block;
41
+ font-size: 90%;
42
+ margin-top: 10px;;
43
+ }
44
+ #course_curriculum .curriculum-heading .items-toggle{
45
+ float: right;
46
+ margin: -33px 7px 0 0;
47
+ line-height: 1;
48
+ box-shadow: none;
49
+ }
50
+ #course_curriculum .curriculum-heading .items-toggle a{
51
+ -webkit-box-shadow: none;
52
+ -moz-box-shadow: none;
53
+ box-shadow: none;
54
+ font-size: 32px;
55
+
56
+ }
57
+ #course_curriculum .curriculum-sections{
58
+ margin: 0;
59
+ background-color: #FFF;
60
+ border-bottom: 1px solid #DDD;
61
+ }
62
+ #course_curriculum .curriculum-section{
63
+ margin: -1px 0 0 0;
64
+ background-color: #FFF;
65
+ border-bottom: 1px solid #DDD;
66
+ position: relative;
67
+ }
68
+ #course_curriculum .curriculum-section.ui-sortable-placeholder{
69
+ background-image: url("../../images/stripe.png");
70
+ visibility: visible !important;
71
+ border: 1px solid #DDD;
72
+ border-bottom: none;
73
+ }
74
+ #course_curriculum .curriculum-section-head{
75
+ border: 1px solid #DDD;
76
+ background-color: #F9F9F9;
77
+ border-bottom: none;
78
+ margin: 0;
79
+ color: #777;
80
+ padding: 3px 20px;
81
+ }
82
+ #course_curriculum .curriculum-section-head input{
83
+ background-color: #F9F9F9;
84
+ }
85
+ #course_curriculum .curriculum-section-head .lp-section-actions{
86
+ float: right;
87
+ margin: 14px 0;
88
+ visibility: hidden;
89
+ position: relative;
90
+ }
91
+ #course_curriculum .curriculum-section:not(.lp-empty-section) .curriculum-section-head:hover .lp-section-actions{
92
+ visibility: visible;
93
+ }
94
+ #course_curriculum .curriculum-section .lp-section-actions a{
95
+ vertical-align: middle;
96
+ color: #DDD;
97
+ width: 24px;
98
+ height: 24px;
99
+ box-shadow: none;
100
+ }
101
+ #course_curriculum .curriculum-section .lp-section-actions a[data-action="expand"]{
102
+ line-height: 28px;
103
+ }
104
+ #course_curriculum .curriculum-section .lp-section-actions a:before{
105
+ width: 24px;
106
+ height: 24px;
107
+ font-size: 24px;
108
+ }
109
+ #course_curriculum .curriculum-section .lp-section-actions a:hover{
110
+ color: #00a0d2;
111
+ }
112
+ #course_curriculum .curriculum-section .curriculum-section-head .lp-section-actions .move{
113
+ cursor: url("../../../assets/images/openhand.cur") 7 5, default;
114
+ position: absolute;
115
+ right: -15px;
116
+ height: 57px;
117
+ top: -15px;
118
+ background: url("../../../assets/images/grippy_large.png") right no-repeat;
119
+ width: 20px;
120
+ }
121
+ #course_curriculum .curriculum-section-content{
122
+ border: 1px solid #DDD;
123
+ padding: 20px;
124
+ border-bottom-width: 0;
125
+ width: 100%;
126
+ box-sizing: border-box;
127
+ }
128
+ #course_curriculum .curriculum-section.ui-sortable-helper{
129
+ border-bottom: 1px solid #DDD;
130
+ }
131
+ #course_curriculum .curriculum-section-head .lp-section-name{
132
+ border: none;
133
+ outline: none;
134
+ box-shadow: none;
135
+ font-size: 24px;
136
+ color: #777;
137
+ width: 70%;
138
+ margin: 0;
139
+ padding: 0;
140
+ height: 50px;
141
+ }
142
+ #course_curriculum .curriculum-section-head .lp-section-name:focus{
143
+ color: #444;
144
+ }
145
+ #course_curriculum .curriculum-section.lp-empty-section .curriculum-section-content{
146
+ display: none;
147
+ }
148
+ #course_curriculum .curriculum-section-items{
149
+ border-collapse: collapse;
150
+ width: 100%;
151
+ }
152
+ #course_curriculum .curriculum-section-items .lp-section-item{
153
+ border: 1px dashed #DDD;
154
+ margin: -1px 0 0 0;
155
+ padding: 5px 0;
156
+ background-color: #FFF;
157
+ }
158
+ #course_curriculum .curriculum-section-items .lp-section-item:nth-child(2n+1),
159
+ #course_curriculum .curriculum-section-items .lp-section-item:nth-child(2n+1) .section-item-input input{
160
+ background-color: #FCFCFC;
161
+ }
162
+ #course_curriculum .curriculum-section-items .lp-section-item .lp-item-actions{
163
+ margin: 0;
164
+ float: right;
165
+ position: relative;
166
+ }
167
+ #course_curriculum .curriculum-section-items .lp-section-item .lp-item-actions a{
168
+ vertical-align: middle;
169
+ color: #DDD;
170
+ margin-top: -2px;
171
+ box-shadow: none;
172
+ }
173
+ #course_curriculum .curriculum-section-items .lp-section-item .lp-item-actions a:hover{
174
+ color: #00a0d2;
175
+ }
176
+ #course_curriculum .curriculum-section-items .lp-section-item[data-item_id=""] .lp-edit{
177
+ display: none;
178
+ }
179
+ #course_curriculum .curriculum-section-items .lp-section-item.lp-item-empty .lp-item-actions{
180
+ display: none;
181
+ }
182
+ #course_curriculum .lp-section-item.ui-sortable-helper td{
183
+
184
+ }
185
+ #course_curriculum .lp-section-item.ui-sortable-placeholder{
186
+ visibility: visible !important;
187
+ }
188
+ #course_curriculum .lp-section-item.ui-sortable-placeholder td{
189
+ background-image: url("../../../assets/images/stripe.png");
190
+ border-bottom: none;
191
+ }
192
+
193
+ #course_curriculum .lp-item-actions > *{
194
+ visibility: hidden;
195
+ }
196
+ #course_curriculum .lp-item-actions > a{}
197
+ #course_curriculum .item-bulk-actions{
198
+ text-align: right;
199
+ margin-top: 0;
200
+ margin-bottom: 15px;
201
+ }
202
+ #course_curriculum .lp-section-item:not(.lp-item-empty):hover .lp-item-actions > *{
203
+ visibility: visible;
204
+ }
205
+ #course_curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty) .item-checkbox{
206
+ display: inline-block;
207
+ height: 34px;
208
+ border: none;
209
+ line-height: 32px;
210
+ padding: 0 7px 0 0;
211
+ margin: 0 4px 0 10px;
212
+ cursor: url("../../../assets/images/openhand.cur") 7 5, default;
213
+ visibility: visible;
214
+ }
215
+ #course_curriculum .curriculum-section-items .lp-section-item .item-checkbox input{
216
+ opacity: 0.4;
217
+ }
218
+ #course_curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty):hover .item-checkbox{
219
+ background: url("../../../assets/images/grippy_large.png") right no-repeat;
220
+ }
221
+ #course_curriculum .curriculum-section-items .lp-section-item:not(.lp-item-empty):hover .item-checkbox input{
222
+ opacity: 1;
223
+ }
224
+ #course_curriculum .lp-item-lp_lesson .handle.learn-press-icon:before{
225
+ content: "\e900";
226
+ }
227
+ #course_curriculum .lp-item-lp_quiz .handle.learn-press-icon:before{
228
+ content: "\e901";
229
+ }
230
+ #course_curriculum .lp-section-item.lp-item-new .handle{
231
+ color: #999;
232
+ }
233
+ #course_curriculum .curriculum-section-items .lp-section-item:hover,
234
+ #course_curriculum .curriculum-section-items .lp-section-item:hover input.lp-item-name{
235
+ background-color: #F9F9F9;
236
+ }
237
+ #course_curriculum .lp-section-item .handle{
238
+ width: 32px;
239
+ height: 32px;
240
+ display: inline-block;
241
+ vertical-align: middle;
242
+ text-align: center;
243
+ font-size: 18px;
244
+ line-height: 32px;
245
+ color: #00A0D2;
246
+ }
247
+ #course_curriculum .lp-section-item.remove input.lp-item-name{
248
+ color: #FF0000;
249
+ }
250
+
251
+ #course_curriculum .lp-section-item.ui-sortable-helper{
252
+
253
+ }
254
+ #course_curriculum .lp-section-item input.lp-item-name {
255
+ color: #777;
256
+ border: none;
257
+ box-shadow: none;
258
+ outline: none;
259
+ font-size: 16px;
260
+ width: 100%;
261
+ vertical-align: middle;
262
+ }
263
+ #course_curriculum .lp-section-describe{
264
+ border: none;
265
+ box-shadow: none;
266
+ color: #999;
267
+ font-style: italic;
268
+ width: 60%;
269
+ float: left;
270
+ padding-left: 0;
271
+ }
272
+ #course_curriculum .curriculum-section-items .lp-section-item input.lp-item-name:focus,
273
+ #course_curriculum input:focus{
274
+ color: #444;
275
+ }
276
+ #course_curriculum .lp-section-item .section-item-icon{
277
+ width: 32px;
278
+ white-space: nowrap;
279
+ }
280
+ #course_curriculum .lp-section-item .learn-press-icon{
281
+ width: 32px;
282
+ height: 32px;
283
+ font-family: dashicons;
284
+ display: inline-block;
285
+ font-size: 20px;
286
+ text-align: center;
287
+ line-height: 32px;
288
+ color: #DDD;
289
+ cursor: pointer;
290
+ }
291
+ #course_curriculum .lp-section-item .learn-press-icon.item-lp_quiz:before{
292
+ content: "\f469";
293
+ }
294
+ #course_curriculum .lp-section-item .learn-press-icon.item-lp_lesson:before{
295
+ content: "\f330";
296
+ }
297
+ #course_curriculum .lp-section-item .learn-press-icon.item-selected,
298
+ #course_curriculum .lp-section-item[data-item_id=""] .learn-press-icon:hover{
299
+ color: #0085ba;
300
+ }
301
+ #course_curriculum .lp-section-item td{
302
+ height: 30px;
303
+ }
304
+ #poststuff .postbox-container{
305
+ position: relative;
306
+ }
307
+ #course_tabs .handlediv,
308
+ #course_tabs .hndle,
309
+ #course_tabs .rwmb-label{
310
+ display: none;
311
+ }
312
+ #course_tabs .rwmb-input{
313
+
314
+ }
315
+ #course_tabs .inside{
316
+ margin: 0;
317
+ padding: 0;
318
+ }
319
+ #course_tabs .rwmb-course_tabs-wrapper{
320
+ margin: 0;
321
+ }
322
+ #course_tabs{
323
+ position: absolute;
324
+ left: 0;
325
+ right: 0;
326
+ }
327
+ #course_tabs.fixed{
328
+ position: fixed;
329
+ top: 30px;
330
+ z-index: 10000;
331
+ opacity: 0.5;
332
+ left: 182px;
333
+ right: 320px;
334
+ }
335
+ #course_tabs.fixed:hover{
336
+ opacity: 1;
337
+ }
338
+ #course_tabs_placeholder{
339
+ height: 41px;
340
+ margin-bottom: 20px;
341
+ }
342
+ #poststuff h3#course-tabs-h3{
343
+ padding: 0;
344
+ }
345
+ #course-tabs-h3 > a{
346
+ padding: 10px;
347
+ display: inline-block;
348
+ border-right: 1px solid #DDD;
349
+ text-decoration: none;
350
+ _color: #AAA;
351
+ box-shadow: none;
352
+ }
353
+ .learn-press-review-logs{
354
+ padding-bottom: 10px;
355
+ }
356
+ .learn-press-review-logs > li{
357
+ border-bottom: 1px dashed #DDD;
358
+ padding-bottom: 20px;
359
+ margin-top: 20px;
360
+ position: relative;
361
+ }
362
+ .learn-press-review-logs > li:after{
363
+ content: '';
364
+ display: block;
365
+ clear: both;
366
+ }
367
+ .learn-press-review-logs .review-user{
368
+ width: 48px;
369
+ float: left;
370
+ }
371
+ .learn-press-review-logs .review-user img{
372
+ max-width: 100%;
373
+ height: auto;
374
+ }
375
+ .learn-press-review-logs .review-user > *{
376
+ float: left;
377
+ }
378
+ .learn-press-review-logs .user-nicename{
379
+
380
+ }
381
+ .learn-press-review-logs .review-index {
382
+ width: 46px;
383
+ font-weight: bold;
384
+ position: absolute;
385
+ bottom: -11px;
386
+ left: 0;
387
+ background-color: #FFF;
388
+ text-align: center;
389
+ border: 1px dashed #DDD;
390
+ height: 20px;
391
+ line-height: 20px;
392
+ color: #CCC;
393
+ }
394
+ .learn-press-review-logs .review-content {
395
+ margin-left: 68px;
396
+ }
397
+ .learn-press-review-logs .review-message{
398
+ font-style: italic;
399
+ font-size: 16px;
400
+ margin-top: 10px;
401
+ color: #999;
402
+ }
403
+ .learn-press-review-logs > li .lp-label{
404
+ font-size: 100%;
405
+ margin-top: 20px;
406
+ }
407
+
408
+ .rwmb-curriculum-wrapper .rwmb-label{display: none;}
409
+ .rwmb-curriculum-wrapper .rwmb-input{
410
+ width: auto !important;
411
+ display: block;
412
+ }
413
+ .column-lp_course .row-actions{
414
+ display: inline-block;
415
+ margin-left: 10px;
416
+ }
417
+ .lp-modal-search li.selected{
418
+ display: none;
419
+ }
420
+ .lp-search-items input[name="lp-item-name"]{
421
+ width: 350px;
422
+ }
423
+ .lp-modal-search{
424
+ background-color: #F5F5F5;
425
+ color: #777;
426
+ padding: 20px;
427
+ height: 100%;
428
+ }
429
+ .lp-modal-search ul{
430
+
431
+ }
432
+ .lp-highlight-color{
433
+ text-decoration: underline;
434
+ color: #00a0d2;
435
+ }
436
+ /*
437
+ #lp-course-curriculum .lp-course-curriculum-toggle{
438
+ padding: 0;
439
+ margin: 0;
440
+ float: right;
441
+ }
442
+ #lp-course-curriculum .lp-item-name{
443
+ box-shadow: none;
444
+ border-color: transparent;
445
+ color: #BBB;
446
+ }
447
+ #lp-course-curriculum .lp-section-item:hover,
448
+ #lp-course-curriculum .lp-section-item.hover{
449
+ background-color: #F5F5F5;
450
+ border-style: solid;
451
+ }
452
+ #lp-course-curriculum .lp-section-item.lp-item-lp_lesson .handle:after{
453
+ content: "\f497";
454
+ }
455
+ #lp-course-curriculum .lp-section-item.lp-item-lp_quiz .handle:after{
456
+ content: "\f130";
457
+ }
458
+ #lp-course-curriculum .lp-section-item:hover .lp-item-name,
459
+ #lp-course-curriculum .lp-section-item.hover .lp-item-name{
460
+ border: 1px solid #DDD;
461
+ color: #32373c;
462
+ }
463
+ #lp-course-curriculum .lp-section-empty .lp-section-items{
464
+ display: none;
465
+ }
466
+ #lp-course-curriculum .lp-section-item .lp-item-actions{
467
+ float: right;
468
+ margin-left: 5px;
469
+ margin-top: 3px;
470
+ }
471
+ #lp-course-curriculum .lp-item-empty .lp-item-actions,
472
+ #lp-course-curriculum .lp-section-empty .lp-section-head .lp-action,
473
+ #lp-course-curriculum .lp-section-empty .lp-curriculum-section-content {
474
+ display: none;
475
+ }
476
+ #lp-course-curriculum .lp-item-empty{
477
+ cursor: default;
478
+ }
479
+ #lp-course-curriculum .lp-item-new{
480
+ border-color: #00A0D2;
481
+ }
482
+ #lp-course-curriculum .lp-item-new .lp-item-name{
483
+ border-color: #00A0D2;
484
+ }
485
+ #lp-course-curriculum .lp-section-head{
486
+ padding: 0;
487
+ }
488
+ #lp-course-curriculum .lp-curriculum-section .lp-toggle i:before{
489
+ content: '\f132';
490
+ }
491
+ #lp-course-curriculum .lp-curriculum-section.open .lp-toggle i:before{
492
+ content: '\f460';
493
+ }
494
+ .lp-modal-search{
495
+ position: absolute;
496
+ background-color: #FFF;
497
+ border: 1px solid #DDD;
498
+ border-top: none;
499
+ z-index: 9999;
500
+ margin: -1px 0 0 1px;
501
+ }
502
+ .lp-modal-search ul{
503
+ margin: 0;
504
+ padding: 0;
505
+ }
506
+ .lp-modal-search ul li{
507
+ list-style: none;
508
+ padding: 5px;
509
+ margin: 0;
510
+ }
511
+ .lp-modal-search li.highlighting,
512
+ .lp-modal-search li:hover{
513
+ background-color: #EAEAEA;
514
+ cursor: pointer;
515
+ }
516
+ .lp-highlight-color{
517
+ text-decoration: underline;
518
+ }
519
+ .lp-search-no-results{
520
+ display: none;
521
+ }
522
+ .lp-curriculum-sections .ui-sortable-placeholder{
523
+ visibility: visible !important;
524
+ border: 2px dashed #DDD;
525
+ }
526
+ .lp-curriculum-sections .lp-sorting{
527
+ height: auto !important;
528
+ }
529
+ */
530
+ /*
531
+
532
+ .lp-course-curriculum{}
533
+ .lp-course-curriculum .lp-curriculum-sections{
534
+
535
+ }
536
+ .lp-course-curriculum .lp-curriculum-section{
537
+ transition: opacity 0.25s;
538
+ margin-bottom: 20px;
539
+ border: 1px solid #DDD;
540
+ }
541
+ .lp-course-curriculum .lp-curriculum-section.lp-selected .lp-curriculum-section-content{
542
+ background-color: #F5F5F5;
543
+ }
544
+ .lp-course-curriculum .lp-curriculum-section-content > p{
545
+ display: inline-block;
546
+ }
547
+ .lp-course-curriculum .lp-curriculum-section.lp-selected > h3{
548
+ _border-bottom: 1px solid #DDD;
549
+ }
550
+ .lp-course-curriculum .lp-curriculum-section > h3{
551
+ padding: 10px ;
552
+ margin: 0;
553
+ background-color: #F5F5F5;
554
+ height: 62px;
555
+ position: relative;
556
+ cursor: move;
557
+ }
558
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-section-name-wrapper{
559
+ top: 9px;
560
+ }
561
+ .lp-course-curriculum .lp-curriculum-section > h3 > span > input{
562
+ border: 1px solid #DDD;
563
+ border-radius: 3px;
564
+ font-size: 24px;
565
+ width: 100%;
566
+ color: #777;
567
+ }
568
+ .lp-course-curriculum .lp-curriculum-section > h3 > span.lp-section-name-wrapper{
569
+ position: absolute;
570
+ display: inline-block;
571
+ right: 137px;
572
+ left: 71px;
573
+ }
574
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action{
575
+ display: block;
576
+ position: relative;
577
+ height: 62px;
578
+ width: 62px;
579
+ border-left: 1px solid #DDD;
580
+ -top: -8px;
581
+ -right: -11px;
582
+ cursor: pointer;
583
+ float: right;
584
+ }
585
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-sort{
586
+ display: none;
587
+ }
588
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action .dashicons{
589
+ font-size: 32px;
590
+ width: 100%;
591
+ height: 100%;
592
+ line-height: 62px;
593
+ color: #0073aa;
594
+ }
595
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action:hover .dashicons{
596
+ color: #009ED7;
597
+ }
598
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-toggle{
599
+ _right: 62px;
600
+ }
601
+ .lp-course-curriculum .lp-curriculum-section > h3 .lp-action.lp-remove{
602
+ _right: 124px;
603
+ }
604
+
605
+ .lp-course-curriculum .lp-curriculum-section.closed .lp-curriculum-section-content{
606
+ display: none;
607
+ }
608
+
609
+ .lp-course-curriculum .sorting .ui-sortable-helper .lp-curriculum-section-content{
610
+ display: none !important;
611
+ }
612
+ .lp-course-curriculum .sorting .ui-sortable-placeholder,
613
+ .lp-section-items.sorting .ui-sortable-placeholder{
614
+ border: 3px dashed #DDD;
615
+ visibility: visible !important;
616
+ position: relative;
617
+ }
618
+ .lp-course-curriculum .sorting .ui-sortable-placeholder:after,
619
+ .lp-section-items.sorting .ui-sortable-placeholder:after{
620
+ content: '';
621
+ display: block;
622
+ width: 0px;
623
+ height: 0px;
624
+ border: 28px solid transparent;
625
+ border-left-color: #999;
626
+ position: absolute;
627
+ top: 0;
628
+ left: -33px;
629
+
630
+ }
631
+
632
+ .lp-section-items.sorting .ui-sortable-placeholder:after{
633
+ border-width: 15px;
634
+ left: -20px;
635
+ }
636
+ .lp-curriculum-section-content{
637
+ background-color: #F5F5F5;
638
+ background-color: #FFF;
639
+ _border-bottom: 2px dashed #DDD;
640
+ padding: 20px;
641
+ margin-bottom: 0px;
642
+ border-top: 1px solid #DDD;
643
+ }
644
+ .lp-dynamic-form{
645
+ position: absolute;
646
+ padding: 0px;
647
+ background-color: transparent;
648
+ z-index: 210;
649
+ height: 15px;
650
+ overflow: hidden;
651
+ }
652
+ .lp-container-dropdown{
653
+ height: 15px;
654
+ vertical-align: top;
655
+ }
656
+ .lp-container-dropdown > a{
657
+ background-image: none !important;
658
+ background-color: #FFF !important;
659
+ }
660
+ .lp-container-dropdown.select2-drop-above > a{
661
+ height: 3px;
662
+ }
663
+ .lp-select-dropdown{
664
+ margin-top: -6px;
665
+ }
666
+ .lp-select-dropdown.select2-drop-above{
667
+ padding-bottom: 0;
668
+ }
669
+
670
+ .lp-empty .lp-curriculum-section-content{
671
+ display: none !important;
672
+ }
673
+
674
+ .lp-section-items{
675
+ min-height: 20px;
676
+
677
+
678
+ }
679
+ .lp-section-items > li{
680
+ padding: 5px;
681
+ border:1px dashed #DDD;
682
+ background-color: #FFF;
683
+ cursor: move;
684
+ position: relative;
685
+ }
686
+ .lp-section-items > li .lp-title{
687
+ cursor: auto;
688
+ padding: 3px 5px;
689
+ border: 1px solid transparent;
690
+ display: inline-block;
691
+ width: 80%;
692
+ -webkit-box-sizing: border-box;
693
+ -moz-box-sizing: border-box;
694
+ box-sizing: border-box;
695
+
696
+ }
697
+ .lp-section-items > li:hover .lp-title {
698
+ border-color: #DDD;
699
+ cursor: text;
700
+ }
701
+ .lp-section-items > li input{
702
+ width: 70%;
703
+ }
704
+
705
+ .lp-section-items > li:hover{
706
+ border-style: solid;
707
+ }
708
+ .lp-section-icon{
709
+ position: absolute;
710
+ top:0;
711
+ left:0;
712
+ width: 62px;
713
+ height: 62px;
714
+ line-height: 54px;
715
+ border-right: 1px solid #DDD;
716
+ text-align:center;
717
+ }
718
+ .lp-section-icon i{
719
+ height: 60px;
720
+ line-height: 60px;
721
+ }
722
+ .lp-course-curriculum .dashicons{
723
+ vertical-align: middle;
724
+ }
725
+
726
+ .select2-drop.select2-drop-active{
727
+ padding: 5px 10px;
728
+ }
729
+
730
+ .rwmb-course_lesson_quiz-wrapper .rwmb-label{ display: none;}
731
+ .rwmb-course_lesson_quiz-wrapper .rwmb-input{ float: none; width: auto; display: block;}
732
+
733
+ .lp-course-curriculum-toggle{
734
+
735
+ }
736
+ .lp-course-curriculum-toggle .expand{
737
+ display: none;
738
+ }*/
assets/css/admin/meta-box-order.css ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ }
assets/css/admin/meta-box-question.css ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ }
53
+ .lp-modal-search{
54
+ background-color: #F5F5F5;
55
+ color: #777;
56
+ padding: 20px;
57
+ height: 100%;
58
+ }
59
+ .lp-modal-search ul{
60
+
61
+ }
62
+ .lp-highlight-color{
63
+ text-decoration: underline;
64
+ color: #00a0d2;
65
+ }
assets/css/global-style.css ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .button.loading{
2
+ }
3
+ .button.loading:after,
4
+ .button.added:after{
5
+ font-family: learnpress;
6
+ content: "\e902";
7
+ vertical-align: baseline;
8
+ line-height: 20px;
9
+ width: 20px;
10
+ text-align: center;
11
+ height: 20px;
12
+ display: inline-block;
13
+ margin-left: 10px;
14
+ font-weight: 400;
15
+ }
16
+ .button.added:after{
17
+ content: '\e903';
18
+ }
19
+ .button.loading:after{
20
+ -webkit-font-smoothing: antialiased;
21
+ -webkit-animation: spin 2s linear infinite;
22
+ -moz-animation: spin 2s linear infinite;
23
+ animation: spin 2s linear infinite;
24
+ }
25
+
26
+ .button.loading-before:before,
27
+ .button.added-before:before{
28
+ font-family: learnpress;
29
+ content: "\e902";
30
+ vertical-align: baseline;
31
+ line-height: 20px;
32
+ width: 20px;
33
+ text-align: center;
34
+ height: 20px;
35
+ display: inline-block;
36
+ margin-left: 10px;
37
+ font-weight: 400;
38
+ }
39
+ .button.added-before:before{
40
+ content: '\e903';
41
+ }
42
+ .button.loading-before:before{
43
+ -webkit-font-smoothing: antialiased;
44
+ -webkit-animation: spin 2s linear infinite;
45
+ -moz-animation: spin 2s linear infinite;
46
+ animation: spin 2s linear infinite;
47
+ }
48
+ .lp-ajaxload{
49
+ text-align: center;
50
+ height: auto;
51
+ overflow: hidden;
52
+ }
53
+ .lp-ajaxload:before{
54
+ font-family: dashicons;
55
+ content: "\f111";
56
+ -webkit-animation: form-press-spinner 2s infinite linear;
57
+ animation: learn-press-ajax-spinner 2s infinite linear;
58
+ color: #CECECE;
59
+ display: inline-block;
60
+ width: 38px;
61
+ height: 40px;
62
+ font-size: 40px;
63
+ position: relative;
64
+ line-height: 1;
65
+ }
66
+ #learn-press-modal-search-items{
67
+ background-color: #FFF;
68
+ overflow: auto;
69
+ width: 768px;
70
+ max-width: 100%;
71
+ color: #777;
72
+ }
73
+ #learn-press-modal-search-items header input{
74
+ width: 100%;
75
+ }
76
+ #learn-press-modal-search-items article{
77
+ overflow: auto;
78
+ margin: 20px 0;
79
+ }
80
+ #learn-press-modal-search-items article .lp-list-items{
81
+ margin: 0;
82
+ }
83
+ #learn-press-modal-search-items article .lp-list-items > li{
84
+ margin: 3px 0;
85
+ }
86
+ #learn-press-modal-search-items article .lp-list-items.lp-ajaxload > li{
87
+ display: none;
88
+ }
89
+ #learn-press-modal-search-items footer{
90
+
91
+ }
92
+
93
+ .modal-inner{
94
+ margin: 20px;
95
+ }
96
+ @-webkit-keyframes learn-press-ajax-spinner {
97
+ 0% {
98
+ -webkit-transform: rotate(0deg);
99
+ transform: rotate(0deg);
100
+ }
101
+ 100% {
102
+ -webkit-transform: rotate(359deg);
103
+ transform: rotate(359deg);
104
+ }
105
+ }
106
+ @keyframes learn-press-ajax-spinner {
107
+ 0% {
108
+ -webkit-transform: rotate(0deg);
109
+ transform: rotate(0deg);
110
+ }
111
+ 100% {
112
+ -webkit-transform: rotate(359deg);
113
+ transform: rotate(359deg);
114
+ }
115
+ }
assets/css/icons.css ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @font-face {
2
+ font-family: 'learnpress';
3
+ src:url('../fonts/icomoon.eot?ym8b3w');
4
+ src:url('../fonts/icomoon.eot?ym8b3w#iefix') format('embedded-opentype'),
5
+ url('../fonts/icomoon.ttf?ym8b3w') format('truetype'),
6
+ url('../fonts/icomoon.woff?ym8b3w') format('woff'),
7
+ url('../fonts/icomoon.svg?ym8b3w#icomoon') format('svg');
8
+ font-weight: normal;
9
+ font-style: normal;
10
+ }
11
+
12
+ [class^="learn-press-icon-"], [class*=" learn-press-icon-"], .learn-press-icon {
13
+ font-family: 'learnpress';
14
+ /*speak: none;*/
15
+ font-style: normal;
16
+ font-weight: normal;
17
+ font-variant: normal;
18
+ text-transform: none;
19
+ line-height: 1;
20
+
21
+ /* Better Font Rendering =========== */
22
+ -webkit-font-smoothing: antialiased;
23
+ -moz-osx-font-smoothing: grayscale;
24
+ }
25
+ .icon-checkmark:before {
26
+ content: "\e903";
27
+ }
28
+ .icon-books:before {
29
+ content: "\e900";
30
+ }
31
+ .icon-alarm:before {
32
+ content: "\e901";
33
+ }
34
+ .icon-spinner:before {
35
+ content: "\e902";
36
+ }
assets/css/learnpress-0.9.x.css ADDED
@@ -0,0 +1,476 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .clearfix:after {
2
+ display: block;
3
+ content: '';
4
+ clear: both;
5
+ }
6
+
7
+ .learnpress{
8
+
9
+ }
10
+
11
+ .learnpress h3{
12
+ font-size: 2.7rem;
13
+ line-height: 1.1852;
14
+ margin-top: 2.3704em;
15
+ margin-bottom: 1.1852em;
16
+ }
17
+
18
+ .learnpress .twentyfifteen .learnpress-content{
19
+ padding-left: 7.6923%;
20
+ padding-right: 7.6923%;
21
+ padding-top: 7.6923%;
22
+ margin-bottom: 7.6923%;
23
+ background: #fff;
24
+ box-shadow: 0 0 1px rgba(0,0,0,.15);
25
+ }
26
+ @media screen and (min-width: 59.6875em) {
27
+ .twentyfifteen .learnpress-content{
28
+ margin-left: 8.3333%;
29
+ margin-right: 8.3333%;
30
+ padding: 10%;
31
+ }
32
+ }
33
+ @media screen and (min-width: 38.75em) {
34
+ .twentyfifteen .learnpress-content {
35
+ margin-right: 7.6923%;
36
+ margin-left: 7.6923%;
37
+ margin-top: 8.3333%;
38
+ }
39
+ }
40
+ /***************************/
41
+
42
+ #course-header {
43
+
44
+ }
45
+
46
+ #course-header:after {
47
+ display: block;
48
+ content: '';
49
+ clear: both;
50
+ }
51
+
52
+ #course-main {
53
+ }
54
+
55
+ #course-main:after {
56
+ content: '';
57
+ display: block;
58
+ clear: both;
59
+ }
60
+
61
+ #course-desc {
62
+ width: 100%;
63
+ }
64
+
65
+ .course-info {
66
+ width: 75%;
67
+ float: left;
68
+ }
69
+
70
+ .course-getting, .course-related {
71
+ width: 25%;
72
+ float: right;
73
+ }
74
+
75
+ .course-free-button {
76
+
77
+ }
78
+
79
+ .learn-press {
80
+
81
+ }
82
+
83
+ .learn-press ul {
84
+ list-style: none;
85
+ }
86
+
87
+ /* Course */
88
+ .course-curriculum {
89
+
90
+ }
91
+
92
+ .course-curriculum .curriculum-sections {
93
+
94
+ }
95
+
96
+ .curriculum-sections .section {
97
+ overflow: hidden;
98
+ }
99
+
100
+ .curriculum-sections .section .section-header {
101
+ margin: 0 0 20px 0;
102
+ }
103
+
104
+ .curriculum-sections .section .section-header a {
105
+ outline: none;
106
+ font-size: 12px;
107
+ float: right;
108
+ }
109
+
110
+ .curriculum-sections .section-content {
111
+
112
+ }
113
+
114
+ .curriculum-sections .section-content .course-lesson,
115
+ .curriculum-sections .section-content .course-quiz {
116
+ margin: 0 0 10px 0;
117
+ }
118
+
119
+ .curriculum-sections .section-content .lesson-quiz-icon {
120
+ margin-right: 5px;
121
+ }
122
+
123
+ .curriculum-sections .section-content .course-lesson .lesson-quiz-icon:before,
124
+ .curriculum-sections .section-content .course-quiz .lesson-quiz-icon:before {
125
+ display: inline-block;
126
+ width: 25px;
127
+ height: 25px;
128
+ border-radius: 50%;
129
+ text-align: center;
130
+ line-height: 25px;
131
+ font-size: 12px;
132
+ color: #FFF;
133
+ background-color: #999;
134
+ vertical-align: middle;
135
+ }
136
+
137
+ .curriculum-sections .section-content .course-lesson .lesson-quiz-icon.lesson:before {
138
+ content: 'L';
139
+ }
140
+
141
+ .curriculum-sections .section-content .course-lesson.current .lesson-quiz-icon:before {
142
+ content: "\f177";
143
+ font-family: dashicons;
144
+ background-color: transparent;
145
+ color: #90DFFF;
146
+ font-size: 24px;
147
+ }
148
+
149
+ .curriculum-sections .section-content .course-quiz .lesson-quiz-icon.quiz:before {
150
+ content: 'Q';
151
+ }
152
+
153
+ .curriculum-sections .section-content .course-lesson.completed a,
154
+ .curriculum-sections .section-content .course-quiz.completed a {
155
+ text-decoration: line-through;
156
+ border-bottom: none;
157
+ }
158
+
159
+ .curriculum-sections .section-content .course-lesson.loading .lesson-quiz-icon:before {
160
+ content: '';
161
+ background: url(../images/ajaxload.gif) no-repeat center;
162
+ }
163
+
164
+ .course-content-lesson-nav,
165
+ .course-content-lesson-nav-text {
166
+ overflow: hidden;
167
+ }
168
+
169
+ .course-content-lesson-nav-text {
170
+ margin-top: 20px;
171
+ margin-bottom: 0;
172
+ text-transform: uppercase;
173
+ font-size: 12px;
174
+ font-weight: bold;
175
+ border-top: 1px dashed #e0e0e0;
176
+ padding-top: 20px;
177
+ }
178
+
179
+ .course-content-lesson-nav a {
180
+ }
181
+
182
+ .course-content-lesson-nav a.next-lesson,
183
+ .course-content-lesson-nav-text .next-lesson-text {
184
+ float: right;
185
+ }
186
+
187
+ #lesson-quiz-tooltip-container {
188
+ display: none;
189
+ visibility: hidden;
190
+ }
191
+
192
+ .lesson-quiz-tooltip {
193
+ font-size: 14px;
194
+ }
195
+
196
+ /* Single Quiz Pagge*/
197
+ .twentyfifteen .single-quiz {
198
+ padding-left: 10%;
199
+ padding-right: 10%;
200
+ padding-bottom: 10%;
201
+ }
202
+
203
+ .quiz-question-nav-buttons button {
204
+ _display: none;
205
+ }
206
+
207
+ .single-quiz .no-question {
208
+ font-size: 14px;
209
+ border: 1px solid #FFB6B6;
210
+ padding: 10px;
211
+ color: #FF7979;
212
+ }
213
+
214
+ .quiz-started .quiz-content, .quiz-completed .quiz-content {
215
+ display: none;
216
+ }
217
+
218
+ .quiz-question-nav {
219
+ margin-right: -250px;
220
+ float: left;
221
+ width: 100%;
222
+ }
223
+
224
+ .quiz-question-nav .lp-question-wrap {
225
+ margin-right: 200px;
226
+ }
227
+
228
+ .quiz-sidebar {
229
+ width: 230px;
230
+ float: right;
231
+ }
232
+
233
+ #quiz-countdown {
234
+ font-size: 48px;
235
+ text-align: center;
236
+ }
237
+
238
+ .quiz-countdown-text {
239
+ text-align: center;
240
+ margin: 10px;
241
+ line-height: 1.5;
242
+ }
243
+
244
+ .quiz-countdown-text span {
245
+ display: block;
246
+ }
247
+
248
+ .quiz-buttons {
249
+ text-align: center;
250
+ }
251
+
252
+ .quiz-questions > ul {
253
+ list-style: none;
254
+ margin: 20px 0;
255
+ }
256
+
257
+ .quiz-questions > ul li {
258
+ list-style: none;
259
+ margin: 0 0 15px 0;
260
+ font-size: 14px;
261
+ line-height: 1;
262
+ }
263
+
264
+ .quiz-questions > ul > li > h4 {
265
+ font-weight: normal;
266
+ }
267
+
268
+ .quiz-questions > ul li.current > h4 {
269
+ font-weight: bold;
270
+ }
271
+
272
+ .quiz-sidebar, .quiz-question-nav {
273
+ margin-top: 20px;
274
+ }
275
+
276
+ .button-finish-quiz {
277
+ display: none;
278
+ }
279
+
280
+ .quiz-started .button-finish-quiz {
281
+ display: inline;
282
+ }
283
+
284
+ .quiz-result {
285
+ margin-top: 20px;
286
+ float: left;
287
+ margin-right: -300px;
288
+ width: 100%;
289
+ }
290
+
291
+ .quiz-result .quiz-result-mark {
292
+ float: left;
293
+ width: 150px;
294
+ height: 150px;
295
+ background-color: #F5F5F5;
296
+ border-radius: 50%;
297
+ text-align: center;
298
+ box-sizing: border-box;
299
+ padding-top: 30px;
300
+ line-height: 1;
301
+
302
+ }
303
+
304
+ .quiz-result .quiz-result-mark .quiz-mark {
305
+ font-size: 60px;
306
+ display: block;
307
+ }
308
+
309
+ .quiz-result .quiz-result-mark .quiz-mark small {
310
+ font-size: 20px;
311
+ }
312
+
313
+ .quiz-result .quiz-result-summary {
314
+ float: left;
315
+ margin-left: 30px;
316
+ }
317
+
318
+ .quiz-result .quiz-result-summary .quiz-result-field {
319
+ margin: 0;
320
+ font-size: 14px;
321
+ }
322
+
323
+ .quiz-result .quiz-result-summary .quiz-result-field > label {
324
+ width: 100px;
325
+ display: inline-block;
326
+ }
327
+
328
+ .quiz-result .quiz-result-summary .quiz-result-field.correct {
329
+ color: #0066cc;
330
+ }
331
+
332
+ .quiz-result .quiz-result-summary .quiz-result-field.wrong {
333
+ color: #BC0B0B;
334
+ }
335
+
336
+ .quiz-result .quiz-result-summary .quiz-result-field.empty {
337
+ color: #869791;
338
+ }
339
+
340
+ #learn_press_payment_form {
341
+ display: none;
342
+ }
343
+
344
+ #learn_press_payment_form .learn_press_payment_form {
345
+ display: none;
346
+ }
347
+
348
+ #quiz-accordion > div {
349
+ height: auto !important;
350
+ }
351
+
352
+ @media screen and (max-width: 480px) {
353
+ .quiz-question-nav {
354
+ margin-right: 0;
355
+ float: none;
356
+ }
357
+
358
+ .quiz-sidebar {
359
+ width: 100%;
360
+ float: none;
361
+ }
362
+ }
363
+
364
+ .lpr-question-hint {
365
+ margin-top: 10px;
366
+ line-height: 1.5;
367
+ }
368
+
369
+ .lpr-question-hint .correct {
370
+ background: #CFE6FD;
371
+ }
372
+
373
+ .lpr-question-hint .wrong {
374
+ background: #FCCED3;
375
+ }
376
+
377
+ .learn-press .message {
378
+ border: 1px solid #90DFFF;
379
+ background-color: #DFF6FF;
380
+ padding: 10px;
381
+ font-size: 12px;
382
+ margin: 20px 0;
383
+ border-radius: 5px;
384
+ }
385
+
386
+ .learn-press .message.error {
387
+ border-color: #FF9090;
388
+ background-color: #FFDFDF;
389
+ }
390
+
391
+ /* jAlert */
392
+ #popup_container {
393
+ border: 1px solid rgb(221, 221, 221);
394
+ background-color: rgb(255, 255, 255);
395
+ min-width: 350px;
396
+ }
397
+
398
+ #popup_container #popup_title,
399
+ #popup_container #popup_content {
400
+ margin: 20px;
401
+ }
402
+
403
+ #popup_container #popup_message {
404
+ margin-bottom: 20px;
405
+ }
406
+
407
+ .lpr_course.has-post-thumbnail {
408
+ padding-top: 8.3333% !important;
409
+ }
410
+
411
+ #course_taken .course,
412
+ #course_made .course{
413
+ list-style: none;
414
+ }
415
+ #course_taken .course > li,
416
+ #course_made .course > li{
417
+ margin: 0 0 20px 0;
418
+ }
419
+ #course_taken .course-status{
420
+ font-size: 12px;
421
+ display: inline-block;
422
+ border-radius: 3px;
423
+ padding: 0 5px;
424
+ margin: 0 10px;
425
+ }
426
+ #course_taken .course-status.passed{
427
+ background-color: #90DFFF;
428
+ color: #FFF;
429
+ }
430
+ #user_quizzes:after {
431
+ content: "";
432
+ display: block;
433
+ clear: both;
434
+ }
435
+ .videoWrapper {
436
+ position: relative;
437
+ padding-bottom: 56.25%; /* 16:9 */
438
+ padding-top: 25px;
439
+ height: 0;
440
+ margin-bottom: 25px;
441
+ }
442
+ .videoWrapper iframe {
443
+ position: absolute;
444
+ top: 0;
445
+ left: 0;
446
+ width: 100%;
447
+ height: 100%;
448
+ }
449
+
450
+ .question-hint-title {
451
+
452
+ }
453
+
454
+ .question-hint-title:hover {
455
+ cursor: pointer;
456
+ }
457
+ .block-ui:before,
458
+ .block-ui:after{
459
+ position: absolute;
460
+ top: 0;
461
+ left: 0;
462
+ right: 0;
463
+ bottom: 0;
464
+ content: '';
465
+ }
466
+ .block-ui:before{
467
+ background-color: #E4E4E4;
468
+ opacity: 0.3;
469
+ }
470
+ .block-ui:after{
471
+ background: url(../images/ajax-loader.gif) no-repeat center;
472
+ }
473
+
474
+ .lpr_quiz {
475
+ visibility: hidden;
476
+ }
assets/css/learnpress.css ADDED
@@ -0,0 +1,897 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .clearfix:after {
2
+ display: block;
3
+ content: '';
4
+ clear: both;
5
+ }
6
+
7
+ .column-lp_course .row-actions,
8
+ .column-lp_quiz .row-actions {
9
+ display: inline-block;
10
+ margin-left: 10px;
11
+ }
12
+
13
+ .column-lp_course .row-actions a,
14
+ .column-lp_quiz .row-actions a {
15
+ color: #999;
16
+ }
17
+
18
+ /**/
19
+ /* message box */
20
+ #learn-press-message-box-block {
21
+ position: fixed;
22
+ top: 0;
23
+ left: 0;
24
+ right: 0;
25
+ bottom: 0;
26
+ background-color: #000;
27
+ z-index: 99999;
28
+ opacity: 0.8;
29
+ }
30
+
31
+ #learn-press-message-box-window {
32
+ position: fixed;
33
+ top: 0;
34
+ bottom: 0;
35
+ left: 0;
36
+ right: 0;
37
+ z-index: 100000;
38
+ color: #FFF;
39
+ text-align: center;
40
+ }
41
+
42
+ #message-box-wrap {
43
+ margin: 0 auto;
44
+ /* text-align: center; */
45
+ display: inline-block;
46
+ text-align: left;
47
+ max-width: 70%;
48
+ }
49
+
50
+ .message-box-title {
51
+ color: #FFF;
52
+ margin: 0 0 40px 0;
53
+ font-size: 34px;
54
+ }
55
+
56
+ .message-box-content {
57
+ font-size: 16px;
58
+ line-height: 1.5;
59
+ }
60
+
61
+ .message-box-animation {
62
+ background-image: url("../images/animation.gif");
63
+ width: 220px;
64
+ height: 20px;
65
+ margin: 20px 0 0;
66
+ }
67
+
68
+ .message-box-buttons {
69
+ margin: 20px 0 0;
70
+ border-top: 1px solid #929292;
71
+ padding-top: 20px;
72
+ }
73
+
74
+ .message-box-button {
75
+ margin-right: 10px !important;
76
+ background-color: #FFFFFF;
77
+ color: #999;
78
+ }
79
+
80
+ .message-box-button:hover {
81
+ background-color: #F5F5F5;
82
+ }
83
+
84
+ .lp-label {
85
+ display: inline-block;
86
+ padding: 3px 8px;
87
+ line-height: 1;
88
+ font-size: 65%;
89
+ vertical-align: baseline;
90
+ color: #FFF;
91
+ border-radius: 4px;
92
+ }
93
+
94
+ .lp-label-quiz {
95
+ background-color: #53658C;
96
+ }
97
+
98
+ .lp-label-preview {
99
+ background-color: #5cb85c;
100
+ }
101
+
102
+ .lp-label-viewing {
103
+ background-color: #39afff;
104
+ }
105
+
106
+ .lp-label-lesson {
107
+ background-color: #337ab7;
108
+ }
109
+
110
+ .lp-label-final {
111
+ background-color: #FF6161;
112
+ }
113
+
114
+ .lp-label-completed {
115
+ background-color: #39C7CE;
116
+ }
117
+
118
+ .lp-label-format {
119
+ background-color: #ccc416;
120
+ }
121
+
122
+ .lp-label-format-aside {
123
+ background-color: #ccc416;
124
+ }
125
+
126
+ .lp-label-format-image {
127
+ background-color: #ccc416;
128
+ }
129
+
130
+ .lp-label-format-video {
131
+ background-color: #ccc416;
132
+ }
133
+
134
+ .lp-label-format-quote {
135
+ background-color: #ccc416;
136
+ }
137
+
138
+ .lp-label-format-link {
139
+ background-color: #ccc416;
140
+ }
141
+
142
+ .lp-label-format-gallery {
143
+ background-color: #ccc416;
144
+ }
145
+
146
+ .lp-label-format-status {
147
+ background-color: #ccc416;
148
+ }
149
+
150
+ .lp-label-format-audio {
151
+ background-color: #ccc416;
152
+ }
153
+
154
+ .lp-label-format-chat {
155
+ background-color: #ccc416;
156
+ }
157
+
158
+ .course-item .lp-label-completed,
159
+ .course-item .lp-label-viewing {
160
+ display: none;
161
+ }
162
+
163
+ .course-item.item-completed .lp-label-completed,
164
+ .course-item.item-current .lp-label-viewing {
165
+ display: inline-block;
166
+ }
167
+
168
+ /**/
169
+ .learnpress {
170
+
171
+ }
172
+
173
+ .learnpress ul,
174
+ .learnpress li {
175
+ list-style: none;
176
+ }
177
+
178
+ .learnpress h3 {
179
+ font-size: 2.7rem;
180
+ line-height: 1.1852;
181
+ margin-top: 2.3704em;
182
+ margin-bottom: 1.1852em;
183
+ }
184
+
185
+ .learnpress .learnpress-content {
186
+ z-index: 100;
187
+ position: relative;
188
+ }
189
+
190
+ .learnpress .twentyfifteen .learnpress-content {
191
+ padding-left: 7.6923%;
192
+ padding-right: 7.6923%;
193
+ padding-top: 7.6923%;
194
+ margin-bottom: 7.6923%;
195
+ background: #fff;
196
+ box-shadow: 0 0 1px rgba(0, 0, 0, .15);
197
+ }
198
+
199
+ .learn-press-checkout-payment {
200
+
201
+ }
202
+
203
+ .payment-method-form {
204
+ display: none;
205
+ }
206
+
207
+ .learn-press-user-form {
208
+ float: left;
209
+ width: 50%;
210
+ box-sizing: border-box;
211
+ padding: 0 10px;
212
+ }
213
+
214
+ .learn-press-user-form .form-heading {
215
+ }
216
+
217
+ .learn-press-user-form .form-subheading {
218
+
219
+ }
220
+
221
+ .learn-press-user-form .form-content {
222
+
223
+ }
224
+
225
+ .learn-press-user-form .form-fields {
226
+
227
+ }
228
+
229
+ #learn-press-checkout-user-form {
230
+ margin: 0 -10px;
231
+ }
232
+
233
+ /* archive */
234
+ .learnpress .twentyfifteen .page-title {
235
+ margin: 0 0 30px 0;
236
+ }
237
+
238
+ .course-introduce {
239
+ margin: 20px 0 0 0;
240
+ }
241
+
242
+ .course-introduce .more-link {
243
+
244
+ }
245
+
246
+ .course-title,
247
+ .course-title h3 {
248
+ font-size: 18px;
249
+ }
250
+
251
+ .archive .lp_course {
252
+ }
253
+
254
+ /* pagination */
255
+ .learn-press-pagination {
256
+ text-align: center;
257
+ }
258
+
259
+ .learn-press-pagination ul > li {
260
+ display: inline-block;
261
+ }
262
+
263
+ .learn-press-pagination ul > li a,
264
+ .learn-press-pagination ul > li span {
265
+ display: inline-block;
266
+ padding: 0 10px;
267
+ border: 1px solid #DDD;
268
+ background-color: #F5F5F5;
269
+ }
270
+
271
+ .learn-press-pagination ul > li a {
272
+ background-color: #FFF;
273
+ }
274
+
275
+ .learn-press-breadcrumb {
276
+ margin: 0 0 20px 0;
277
+ }
278
+
279
+ /* course lesson nav */
280
+ .course-item-nav {
281
+ border-top: 1px dashed #DDD;
282
+ overflow: hidden;
283
+ margin: 20px 0;
284
+ padding-top: 10px;
285
+ }
286
+
287
+ .course-item-nav .course-item-prev > *,
288
+ .course-item-nav .course-item-next > * {
289
+ display: block;
290
+ }
291
+
292
+ .course-item-nav > div > span {
293
+ font-size: 70%;
294
+ text-transform: uppercase;
295
+ font-weight: bold;
296
+ }
297
+
298
+ .course-item-nav .course-item-prev {
299
+ float: left;
300
+ text-align: left;
301
+ }
302
+
303
+ .course-item-nav .course-item-next {
304
+ float: right;
305
+ text-align: right;
306
+ }
307
+
308
+ /* curriculum */
309
+ .section-header {
310
+ margin: 0 0 0 0;
311
+ padding: 10px 15px;
312
+ background-color: #EEE;
313
+ }
314
+
315
+ .section-header p {
316
+ display: inline-block;
317
+ font-weight: normal;
318
+ font-style: italic;
319
+ color: #999;
320
+ font-size: smaller;
321
+ margin: 0;
322
+ }
323
+
324
+ #learn-press-course-curriculum .section {
325
+ margin: 0 0 1px 0;
326
+ list-style: none;
327
+ }
328
+
329
+ #learn-press-course-curriculum .section-content {
330
+ margin: 0;
331
+ background-color: #F5F5F5;
332
+ }
333
+
334
+ #learn-press-course-curriculum .section .course-item {
335
+ margin: 0 0 0;
336
+ list-style: none;
337
+ padding: 10px 15px;
338
+ border-top: 1px solid #FFF;
339
+ }
340
+
341
+ #learn-press-course-curriculum .section .course-item-meta {
342
+ display: block;
343
+ float: right;
344
+ line-height: 1;
345
+ margin: 3px 0;
346
+ }
347
+
348
+ #learn-press-course-curriculum .section .course-item.section-empty {
349
+ background-color: #F5F5F5;
350
+ }
351
+
352
+ #learn-press-course-curriculum .section .course-item.section-empty .learn-press-message {
353
+ margin: 0;
354
+ }
355
+
356
+ /* QUIZ */
357
+ .single-quiz {
358
+
359
+ }
360
+
361
+ .single-quiz .quiz-summary-left {
362
+ float: left;
363
+ width: 100%;
364
+ padding-right: 320px;
365
+ }
366
+
367
+ .single-quiz .quiz-sidebar {
368
+ float: right;
369
+ width: 300px;
370
+ margin-left: -300px;
371
+ border: 2px solid #DDD;
372
+ padding: 20px;
373
+ }
374
+
375
+ .single-quiz.quiz-completed .quiz-questions-list .learn-press-question-title {
376
+ display: none;
377
+ }
378
+
379
+ .quiz-questions-list .current {
380
+ font-weight: bold;
381
+ }
382
+
383
+ .quiz-questions-list .current a:after {
384
+ display: inline-block;
385
+ background-color: #0066cc;
386
+ /* padding: 0px 8px; */
387
+ color: #FFF;
388
+ font-size: 70%;
389
+ border-radius: 50%;
390
+ content: '?';
391
+ /* margin-left: 10px; */
392
+ width: 20px;
393
+ height: 20px;
394
+ line-height: 20px;
395
+ text-align: center;
396
+ vertical-align: middle;
397
+ }
398
+
399
+ .quiz-countdown {
400
+ text-align: center;
401
+ }
402
+
403
+ .quiz-countdown #quiz-countdown-value {
404
+ font-size: 40px;
405
+ line-height: 1;
406
+ }
407
+
408
+ .quiz-countdown .quiz-countdown-label {
409
+ font-size: smaller;
410
+ font-style: italic;
411
+ color: #999;
412
+ }
413
+
414
+ .quiz-buttons {
415
+ text-align: center;
416
+ }
417
+
418
+ .quiz-result {
419
+ width: 100%;
420
+ }
421
+
422
+ .quiz-result .quiz-result-mark {
423
+ float: left;
424
+ width: 150px;
425
+ height: 150px;
426
+ background-color: #F5F5F5;
427
+ border-radius: 50%;
428
+ text-align: center;
429
+ box-sizing: border-box;
430
+ padding-top: 30px;
431
+ line-height: 1;
432
+
433
+ }
434
+
435
+ .quiz-result .quiz-result-mark .quiz-mark {
436
+ font-size: 60px;
437
+ display: block;
438
+ }
439
+
440
+ .quiz-result .quiz-result-mark .quiz-mark small {
441
+ font-size: 20px;
442
+ }
443
+
444
+ .quiz-result .quiz-result-summary {
445
+ float: left;
446
+ margin-left: 30px;
447
+ }
448
+
449
+ .quiz-result .quiz-result-summary .quiz-result-field {
450
+ margin: 0;
451
+ font-size: 14px;
452
+ }
453
+
454
+ .quiz-result .quiz-result-summary .quiz-result-field > label {
455
+ width: 100px;
456
+ display: inline-block;
457
+ }
458
+
459
+ .quiz-result .quiz-result-summary .quiz-result-field.correct {
460
+ color: #0066cc;
461
+ }
462
+
463
+ .quiz-result .quiz-result-summary .quiz-result-field.wrong {
464
+ color: #BC0B0B;
465
+ }
466
+
467
+ .quiz-result .quiz-result-summary .quiz-result-field.empty {
468
+ color: #869791;
469
+ }
470
+
471
+ .quiz-history {
472
+ font-size: 80%;
473
+ }
474
+
475
+ .quiz-history td {
476
+ padding: 10px;
477
+ }
478
+
479
+ .quiz-history-actions {
480
+ margin: 0;
481
+ }
482
+
483
+ /* profile */
484
+ #learn-press-user-profile {
485
+ overflow: hidden;
486
+ }
487
+
488
+ .learn-press-user-profile .user-info {
489
+ margin: 0 0 20px;
490
+ }
491
+
492
+ .learn-press-user-profile .user-basic-info {
493
+
494
+ }
495
+
496
+ .learn-press-user-profile .learn-press-tabs {
497
+ list-style: none;
498
+ margin: 0 0 20px;
499
+ padding-left: 5px;
500
+ border-bottom: 1px solid #DDD;
501
+ }
502
+
503
+ .learn-press-user-profile .learn-press-tabs > li {
504
+ float: left;
505
+ }
506
+
507
+ .learn-press-user-profile .learn-press-tabs > li > a {
508
+ box-shadow: none;
509
+ outline: none;
510
+ display: block;
511
+ border: none;
512
+ padding: 5px 10px;
513
+ }
514
+
515
+ .learn-press-user-profile .learn-press-tabs > li.current a {
516
+ background-color: #FFF;
517
+ border: 1px solid #DDD;
518
+ border-bottom-color: transparent;
519
+ z-index: 10;
520
+ margin-bottom: -1px;
521
+ }
522
+
523
+ .learn-press-tabs-wrapper {
524
+ margin: 0 0 20px;
525
+ }
526
+
527
+ .learn-press-user-profile .learn-press-tabs-wrapper > .learn-press-tab {
528
+ /*padding: 0;
529
+ float: left;
530
+ width: 100%;
531
+ margin-right: -100%;
532
+ visibility: hidden;*/
533
+ }
534
+
535
+ .learn-press-user-profile .entry-tab-inner {
536
+ }
537
+
538
+ .learn-press-user-profile .learn-press-tabs-wrapper {
539
+ /*float: left;
540
+ width: 100%;
541
+ padding-left: 170px;*/
542
+ }
543
+
544
+ .learn-press-user-profile .profile-content-left {
545
+ float: left;
546
+ margin-left: -100%;
547
+ margin-bottom: -100000px;
548
+ padding-bottom: 100000px;
549
+ background-color: #F5F5F5;
550
+ }
551
+
552
+ .profile-courses {
553
+ list-style: none;
554
+ }
555
+
556
+ .profile-courses > li {
557
+
558
+ }
559
+
560
+ .profile-courses > li > a {
561
+ }
562
+
563
+ .profile-courses-heading {
564
+ margin: 0 0 10px !important;
565
+ }
566
+
567
+ .learn-press-subtabs {
568
+ }
569
+
570
+ .learn-press-subtabs > li {
571
+ display: inline-block;
572
+ margin-right: 10px;
573
+ }
574
+
575
+ .learn-press-subtabs > li.current {
576
+ font-weight: bold;
577
+ }
578
+
579
+ .learn-press-subtab-content {
580
+ display: none;
581
+ }
582
+
583
+ .learn-press-subtab-content.current {
584
+ display: block;
585
+ }
586
+
587
+ .hide-if-js {
588
+ display: none;
589
+ }
590
+
591
+ /**/
592
+ .purchase-course .view-cart-button {
593
+
594
+ }
595
+
596
+ .learn-press-cart-table td,
597
+ .learn-press-cart-table th {
598
+ vertical-align: top;
599
+ }
600
+
601
+ .learn-press-cart-table .course-remove {
602
+ width: 40px;
603
+ }
604
+
605
+ .learn-press-cart-table .course-thumbnail {
606
+ width: 20%;
607
+ }
608
+
609
+ .learn-press-cart-table .course-price,
610
+ .learn-press-cart-table .course-total {
611
+ width: 15%;
612
+ }
613
+
614
+ /* notices */
615
+ .learn-press-notice,
616
+ .learn-press-message,
617
+ .learn-press-error {
618
+ list-style: none;
619
+ margin: 0 0 20px 0;
620
+ background-color: #F5F5F5;
621
+ padding: 8px 15px;
622
+ border-left: 5px solid;
623
+ }
624
+
625
+ .learn-press-notice {
626
+ border-color: #1e85be;
627
+ }
628
+
629
+ .learn-press-message {
630
+ border-color: #8fae1b;
631
+ }
632
+
633
+ .learn-press-error {
634
+ border-color: #b81c23;
635
+ }
636
+
637
+ .open-hand {
638
+ cursor: url("../../assets/images/openhand.cur") 7 5, default !important;
639
+ }
640
+
641
+ a .archive-course:hover {
642
+ cursor: pointer;
643
+ }
644
+
645
+ .archive-course {
646
+ border: 1px solid black;
647
+ display: table;
648
+ margin-bottom: 10px;
649
+ width: 100%;
650
+ }
651
+
652
+ .course-cover {
653
+ display: table-cell;
654
+ height: 100px;
655
+ width: 100px;
656
+ }
657
+
658
+ .course-detail {
659
+ display: table-cell;
660
+ vertical-align: top;
661
+ padding-left: 10px;
662
+ }
663
+
664
+ .course-title {
665
+ font-weight: bold;
666
+ }
667
+
668
+ .lp-button-dropdown {
669
+ padding-right: 28px !important;
670
+ position: relative;
671
+ z-index: 99998;
672
+ }
673
+
674
+ .lp-course-progress {
675
+ margin-right: 50px;
676
+ }
677
+
678
+ .lp-course-progress .lp-course-progress-heading {
679
+ margin: 0 0 40px 0;
680
+ }
681
+
682
+ .lp-course-progress .lp-progress-bar {
683
+ height: 20px;
684
+ background: #F5F5F5;
685
+ position: relative;
686
+ /* margin-right: 80px; */
687
+ float: left;
688
+ width: 100%;
689
+ margin-bottom: 50px;
690
+ -webkit-border-radius: 5px;
691
+ -moz-border-radius: 5px;
692
+ border-radius: 5px;
693
+ }
694
+
695
+ .lp-course-progress .lp-progress-value {
696
+ height: 20px;
697
+ background: #DDD;
698
+ position: absolute;
699
+ left: 0;
700
+ -webkit-transition: width 0.25s;
701
+ -moz-transition: width 0.25s;
702
+ -ms-transition: width 0.25s;
703
+ -o-transition: width 0.25s;
704
+ transition: width 0.25s;
705
+ -webkit-border-radius: 5px;
706
+ -moz-border-radius: 5px;
707
+ border-radius: 5px;;
708
+ }
709
+
710
+ .lp-course-progress .lp-progress-value > span,
711
+ .lp-course-progress .lp-passing-conditional span {
712
+ display: inline-block;
713
+ padding: 5px 10px;
714
+ font-size: small;
715
+ background: #DDD;
716
+ position: absolute;
717
+ right: 0;
718
+ top: -35px;
719
+ line-height: 1;
720
+ white-space: nowrap;
721
+ width: 50px;
722
+ text-align: center;
723
+ margin-right: -25px;
724
+ -webkit-border-radius: 3px;
725
+ -moz-border-radius: 3px;
726
+ border-radius: 3px;
727
+ }
728
+
729
+ .lp-course-progress .lp-progress-value > span:after,
730
+ .lp-course-progress .lp-passing-conditional span:after {
731
+ content: '';
732
+ display: block;
733
+ border: 6px solid #DDD;
734
+ position: absolute;
735
+ border-color: transparent;
736
+ border-top-color: #DDD;
737
+ bottom: -12px;
738
+ left: 50%;
739
+ margin-left: -6px;
740
+ }
741
+
742
+ .lp-course-progress .lp-passing-conditional span {
743
+ top: 30px;
744
+ margin-left: -25px;
745
+ }
746
+
747
+ .lp-course-progress .lp-passing-conditional span:after {
748
+ border-bottom-color: #DDD;
749
+ top: -12px;
750
+ left: 50%;
751
+ border-top-color: transparent;
752
+ bottom: auto;
753
+ }
754
+
755
+ .lp-course-progress .lp-progress-value.left > span {
756
+ left: 100%;
757
+ right: auto;
758
+ }
759
+
760
+ .lp-course-progress .lp-progress-value.left > span:after {
761
+ bottom: -4px;
762
+ transform: rotate(225deg);
763
+ left: -10px;
764
+ right: auto;
765
+ }
766
+
767
+ .lp-course-progress.passed .lp-progress-value {
768
+ background: #83D0FF;
769
+ -webkit-border-radius: 5px;
770
+ -moz-border-radius: 5px;
771
+ border-radius: 5px;
772
+ }
773
+
774
+ .lp-course-progress.passed .lp-progress-value > span {
775
+ background: #83D0FF;
776
+ }
777
+
778
+ .lp-course-progress.passed .lp-progress-value > span:after {
779
+ border-top-color: #83D0FF;
780
+ }
781
+
782
+ .lp-course-progress .lp-progress-total {
783
+ width: 50px;
784
+ float: right;
785
+ margin-right: -50px;
786
+ height: 20px;
787
+ font-size: small;
788
+ text-align: right;
789
+ line-height: 20px;
790
+ }
791
+
792
+ .lp-course-progress .lp-passing-conditional {
793
+ position: absolute;
794
+ height: 20px;
795
+ width: 1px;
796
+ background-color: #FF0000;
797
+ }
798
+
799
+ .lp-course-progress .lp-passing-conditional.right span {
800
+ right: 0;
801
+ }
802
+
803
+ .lp-course-progress .lp-passing-conditional.right span:after {
804
+ left: auto;
805
+ right: -10px;
806
+ border-left-color: transparent;
807
+ border-bottom-color: #DDD;
808
+ }
809
+
810
+ .quiz-questions-list .question-title {
811
+ font-weight: normal;
812
+ }
813
+
814
+ .question-results .question-title:after {
815
+ content: '';
816
+ display: inline-block;
817
+ font-family: dashicons;
818
+ vertical-align: middle;
819
+ font-size: 20px;
820
+ }
821
+
822
+ .question-results.correct .question-title:after {
823
+ content: "\f147";
824
+ }
825
+
826
+ .question-results.incorrect .question-title:after {
827
+ content: "\f335";
828
+ }
829
+
830
+ .question-results.skipped {
831
+ }
832
+
833
+ .complete-lesson-button.completed {
834
+
835
+ }
836
+
837
+ .learn-press-question-wrap {
838
+
839
+ }
840
+
841
+ .learn-press-question-wrap.checked li.answer-true {
842
+ background: #C4EBFF;
843
+ }
844
+
845
+ .learn-press-question-wrap.checked li.user-answer-false {
846
+ color: #FF0000;
847
+ }
848
+
849
+ /* jAlerts */
850
+ #popup_container {
851
+ background: #FFF;
852
+ }
853
+
854
+ #popup_title {
855
+ padding: 10px 20px;
856
+ background: #18B6C7;
857
+ color: #FFF;
858
+ }
859
+
860
+ #popup_content {
861
+ padding: 20px;
862
+ }
863
+
864
+ #popup_message {
865
+ margin-bottom: 20px;
866
+ }
867
+
868
+ .question-explanation-content,
869
+ .question-hint-content {
870
+ border: 1px solid #DDD;
871
+ padding: 20px;
872
+ background: #DDD;
873
+ margin-bottom: 20px;
874
+ }
875
+
876
+ .question-explanation-content:before,
877
+ .question-hint-content:before {
878
+ content: attr(data-title);
879
+ display: block;
880
+ font-weight: bold;
881
+ }
882
+
883
+ @media screen and (min-width: 59.6875em) {
884
+ .twentyfifteen .learnpress-content {
885
+ margin-left: 8.3333%;
886
+ margin-right: 8.3333%;
887
+ padding: 10%;
888
+ }
889
+ }
890
+
891
+ @media screen and (min-width: 38.75em) {
892
+ .twentyfifteen .learnpress-content {
893
+ margin-right: 7.6923%;
894
+ margin-left: 7.6923%;
895
+ margin-top: 8.3333%;
896
+ }
897
+ }
assets/css/select2/select2-spinner.gif ADDED
Binary file
assets/css/select2/select2.css ADDED
@@ -0,0 +1,732 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Version: 3.5.2 Timestamp: Sat Nov 1 14:43:36 EDT 2014
3
+ */
4
+ .select2-container {
5
+ margin: 0;
6
+ position: relative;
7
+ display: inline-block !important;
8
+ /* inline-block for ie7 */
9
+ zoom: 1;
10
+ *display: inline;
11
+ vertical-align: middle;
12
+ }
13
+
14
+ .select2-container,
15
+ .select2-drop,
16
+ .select2-search,
17
+ .select2-search input {
18
+ /*
19
+ Force border-box so that % widths fit the parent
20
+ container without overlap because of margin/padding.
21
+ More Info : http://www.quirksmode.org/css/box.html
22
+ */
23
+ -webkit-box-sizing: border-box; /* webkit */
24
+ -moz-box-sizing: border-box; /* firefox */
25
+ box-sizing: border-box; /* css3 */
26
+ }
27
+
28
+ .select2-container .select2-choice {
29
+ display: block;
30
+ height: 26px;
31
+ padding: 0 0 0 8px;
32
+ overflow: hidden;
33
+ position: relative;
34
+
35
+ border: 1px solid #aaa;
36
+ white-space: nowrap;
37
+ line-height: 26px;
38
+ color: #444;
39
+ text-decoration: none;
40
+
41
+ border-radius: 4px;
42
+
43
+ background-clip: padding-box;
44
+
45
+ -webkit-touch-callout: none;
46
+ -webkit-user-select: none;
47
+ -moz-user-select: none;
48
+ -ms-user-select: none;
49
+ user-select: none;
50
+
51
+ background-color: #fff;
52
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.5, #fff));
53
+ background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 50%);
54
+ background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 50%);
55
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
56
+ background-image: linear-gradient(to top, #eee 0%, #fff 50%);
57
+ }
58
+
59
+ html[dir="rtl"] .select2-container .select2-choice {
60
+ padding: 0 8px 0 0;
61
+ }
62
+
63
+ .select2-container.select2-drop-above .select2-choice {
64
+ border-bottom-color: #aaa;
65
+
66
+ border-radius: 0 0 4px 4px;
67
+
68
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.9, #fff));
69
+ background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 90%);
70
+ background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 90%);
71
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
72
+ background-image: linear-gradient(to bottom, #eee 0%, #fff 90%);
73
+ }
74
+
75
+ .select2-container.select2-allowclear .select2-choice .select2-chosen {
76
+ margin-right: 42px;
77
+ }
78
+
79
+ .select2-container .select2-choice > .select2-chosen {
80
+ margin-right: 26px;
81
+ display: block;
82
+ overflow: hidden;
83
+
84
+ white-space: nowrap;
85
+
86
+ text-overflow: ellipsis;
87
+ float: none;
88
+ width: auto;
89
+ }
90
+
91
+ html[dir="rtl"] .select2-container .select2-choice > .select2-chosen {
92
+ margin-left: 26px;
93
+ margin-right: 0;
94
+ }
95
+
96
+ .select2-container .select2-choice abbr {
97
+ display: none;
98
+ width: 12px;
99
+ height: 12px;
100
+ position: absolute;
101
+ right: 24px;
102
+ top: 8px;
103
+
104
+ font-size: 1px;
105
+ text-decoration: none;
106
+
107
+ border: 0;
108
+ background: url('select2.png') right top no-repeat;
109
+ cursor: pointer;
110
+ outline: 0;
111
+ }
112
+
113
+ .select2-container.select2-allowclear .select2-choice abbr {
114
+ display: inline-block;
115
+ }
116
+
117
+ .select2-container .select2-choice abbr:hover {
118
+ background-position: right -11px;
119
+ cursor: pointer;
120
+ }
121
+
122
+ .select2-drop-mask {
123
+ border: 0;
124
+ margin: 0;
125
+ padding: 0;
126
+ position: fixed;
127
+ left: 0;
128
+ top: 0;
129
+ min-height: 100%;
130
+ min-width: 100%;
131
+ height: auto;
132
+ width: auto;
133
+ opacity: 0;
134
+ z-index: 9998;
135
+ /* styles required for IE to work */
136
+ background-color: #fff;
137
+ filter: alpha(opacity=0);
138
+ }
139
+
140
+ .select2-drop {
141
+ width: 100%;
142
+ margin-top: -1px;
143
+ position: absolute;
144
+ z-index: 9999;
145
+ top: 100%;
146
+
147
+ background: #fff;
148
+ color: #000;
149
+ border: 1px solid #aaa;
150
+ border-top: 0;
151
+
152
+ border-radius: 0 0 4px 4px;
153
+
154
+ -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
155
+ box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
156
+ }
157
+
158
+ .select2-drop.select2-drop-above {
159
+ margin-top: 1px;
160
+ border-top: 1px solid #aaa;
161
+ border-bottom: 0;
162
+
163
+ border-radius: 4px 4px 0 0;
164
+
165
+ -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
166
+ box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
167
+ }
168
+
169
+ .select2-drop-active {
170
+ border: 1px solid #5897fb;
171
+ border-top: none;
172
+ }
173
+
174
+ .select2-drop.select2-drop-above.select2-drop-active {
175
+ border-top: 1px solid #5897fb;
176
+ }
177
+
178
+ .select2-drop-auto-width {
179
+ border-top: 1px solid #aaa;
180
+ width: auto;
181
+ }
182
+
183
+ .select2-drop-auto-width .select2-search {
184
+ padding-top: 4px;
185
+ }
186
+
187
+ .select2-container .select2-choice .select2-arrow {
188
+ display: inline-block;
189
+ width: 18px;
190
+ height: 100%;
191
+ position: absolute;
192
+ right: 0;
193
+ top: 0;
194
+
195
+ border-left: 1px solid #aaa;
196
+ border-radius: 0 4px 4px 0;
197
+
198
+ background-clip: padding-box;
199
+
200
+ background: #ccc;
201
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
202
+ background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
203
+ background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
204
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#cccccc', GradientType=0);
205
+ background-image: linear-gradient(to top, #ccc 0%, #eee 60%);
206
+ }
207
+
208
+ html[dir="rtl"] .select2-container .select2-choice .select2-arrow {
209
+ left: 0;
210
+ right: auto;
211
+
212
+ border-left: none;
213
+ border-right: 1px solid #aaa;
214
+ border-radius: 4px 0 0 4px;
215
+ }
216
+
217
+ .select2-container .select2-choice .select2-arrow b {
218
+ display: block;
219
+ width: 100%;
220
+ height: 100%;
221
+ background: url('select2.png') no-repeat 0 1px;
222
+ }
223
+
224
+ html[dir="rtl"] .select2-container .select2-choice .select2-arrow b {
225
+ background-position: 2px 1px;
226
+ }
227
+
228
+ .select2-search {
229
+ display: inline-block;
230
+ width: 100%;
231
+ min-height: 26px;
232
+ margin: 0;
233
+ padding-left: 4px;
234
+ padding-right: 4px;
235
+
236
+ position: relative;
237
+ z-index: 10000;
238
+
239
+ white-space: nowrap;
240
+ }
241
+
242
+ .select2-search input {
243
+ width: 100%;
244
+ height: auto !important;
245
+ min-height: 26px;
246
+ padding: 4px 20px 4px 5px;
247
+ margin: 0;
248
+
249
+ outline: 0;
250
+ font-family: sans-serif;
251
+ font-size: 1em;
252
+
253
+ border: 1px solid #aaa;
254
+ border-radius: 0;
255
+
256
+ -webkit-box-shadow: none;
257
+ box-shadow: none;
258
+
259
+ background: #fff url('select2.png') no-repeat 100% -22px;
260
+ background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
261
+ background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
262
+ background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
263
+ background: url('select2.png') no-repeat 100% -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
264
+ }
265
+
266
+ html[dir="rtl"] .select2-search input {
267
+ padding: 4px 5px 4px 20px;
268
+
269
+ background: #fff url('select2.png') no-repeat -37px -22px;
270
+ background: url('select2.png') no-repeat -37px -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
271
+ background: url('select2.png') no-repeat -37px -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
272
+ background: url('select2.png') no-repeat -37px -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
273
+ background: url('select2.png') no-repeat -37px -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
274
+ }
275
+
276
+ .select2-drop.select2-drop-above .select2-search input {
277
+ margin-top: 4px;
278
+ }
279
+
280
+ .select2-search input.select2-active {
281
+ background: #fff url('select2-spinner.gif') no-repeat 100%;
282
+ background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
283
+ background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
284
+ background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
285
+ background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
286
+ }
287
+
288
+ .select2-container-active .select2-choice,
289
+ .select2-container-active .select2-choices {
290
+ border: 1px solid #5897fb;
291
+ outline: none;
292
+
293
+ -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
294
+ box-shadow: 0 0 5px rgba(0, 0, 0, .3);
295
+ }
296
+
297
+ .select2-dropdown-open .select2-choice {
298
+ border-bottom-color: transparent;
299
+ -webkit-box-shadow: 0 1px 0 #fff inset;
300
+ box-shadow: 0 1px 0 #fff inset;
301
+
302
+ border-bottom-left-radius: 0;
303
+ border-bottom-right-radius: 0;
304
+
305
+ background-color: #eee;
306
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #fff), color-stop(0.5, #eee));
307
+ background-image: -webkit-linear-gradient(center bottom, #fff 0%, #eee 50%);
308
+ background-image: -moz-linear-gradient(center bottom, #fff 0%, #eee 50%);
309
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
310
+ background-image: linear-gradient(to top, #fff 0%, #eee 50%);
311
+ }
312
+
313
+ .select2-dropdown-open.select2-drop-above .select2-choice,
314
+ .select2-dropdown-open.select2-drop-above .select2-choices {
315
+ border: 1px solid #5897fb;
316
+ border-top-color: transparent;
317
+
318
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(0.5, #eee));
319
+ background-image: -webkit-linear-gradient(center top, #fff 0%, #eee 50%);
320
+ background-image: -moz-linear-gradient(center top, #fff 0%, #eee 50%);
321
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
322
+ background-image: linear-gradient(to bottom, #fff 0%, #eee 50%);
323
+ }
324
+
325
+ .select2-dropdown-open .select2-choice .select2-arrow {
326
+ background: transparent;
327
+ border-left: none;
328
+ filter: none;
329
+ }
330
+
331
+ html[dir="rtl"] .select2-dropdown-open .select2-choice .select2-arrow {
332
+ border-right: none;
333
+ }
334
+
335
+ .select2-dropdown-open .select2-choice .select2-arrow b {
336
+ background-position: -18px 1px;
337
+ }
338
+
339
+ html[dir="rtl"] .select2-dropdown-open .select2-choice .select2-arrow b {
340
+ background-position: -16px 1px;
341
+ }
342
+
343
+ .select2-hidden-accessible {
344
+ border: 0;
345
+ clip: rect(0 0 0 0);
346
+ height: 1px;
347
+ margin: -1px;
348
+ overflow: hidden;
349
+ padding: 0;
350
+ position: absolute;
351
+ width: 1px;
352
+ }
353
+
354
+ /* results */
355
+ .select2-results {
356
+ max-height: 200px;
357
+ padding: 0 0 0 4px;
358
+ margin: 4px 4px 4px 0;
359
+ position: relative;
360
+ overflow-x: hidden;
361
+ overflow-y: auto;
362
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
363
+ }
364
+
365
+ html[dir="rtl"] .select2-results {
366
+ padding: 0 4px 0 0;
367
+ margin: 4px 0 4px 4px;
368
+ }
369
+
370
+ .select2-results ul.select2-result-sub {
371
+ margin: 0;
372
+ padding-left: 0;
373
+ }
374
+
375
+ .select2-results li {
376
+ list-style: none;
377
+ display: list-item;
378
+ background-image: none;
379
+ }
380
+
381
+ .select2-results li.select2-result-with-children > .select2-result-label {
382
+ font-weight: bold;
383
+ }
384
+
385
+ .select2-results .select2-result-label {
386
+ padding: 3px 7px 4px;
387
+ margin: 0;
388
+ cursor: pointer;
389
+
390
+ min-height: 1em;
391
+
392
+ -webkit-touch-callout: none;
393
+ -webkit-user-select: none;
394
+ -moz-user-select: none;
395
+ -ms-user-select: none;
396
+ user-select: none;
397
+ }
398
+
399
+ .select2-results-dept-1 .select2-result-label {
400
+ padding-left: 20px
401
+ }
402
+
403
+ .select2-results-dept-2 .select2-result-label {
404
+ padding-left: 40px
405
+ }
406
+
407
+ .select2-results-dept-3 .select2-result-label {
408
+ padding-left: 60px
409
+ }
410
+
411
+ .select2-results-dept-4 .select2-result-label {
412
+ padding-left: 80px
413
+ }
414
+
415
+ .select2-results-dept-5 .select2-result-label {
416
+ padding-left: 100px
417
+ }
418
+
419
+ .select2-results-dept-6 .select2-result-label {
420
+ padding-left: 110px
421
+ }
422
+
423
+ .select2-results-dept-7 .select2-result-label {
424
+ padding-left: 120px
425
+ }
426
+
427
+ .select2-results .select2-highlighted {
428
+ background: #3875d7;
429
+ color: #fff;
430
+ }
431
+
432
+ .select2-results li em {
433
+ background: #feffde;
434
+ font-style: normal;
435
+ }
436
+
437
+ .select2-results .select2-highlighted em {
438
+ background: transparent;
439
+ }
440
+
441
+ .select2-results .select2-highlighted ul {
442
+ background: #fff;
443
+ color: #000;
444
+ }
445
+
446
+ .select2-results .select2-no-results,
447
+ .select2-results .select2-searching,
448
+ .select2-results .select2-ajax-error,
449
+ .select2-results .select2-selection-limit {
450
+ background: #f4f4f4;
451
+ display: list-item;
452
+ padding-left: 5px;
453
+ }
454
+
455
+ /*
456
+ disabled look for disabled choices in the results dropdown
457
+ */
458
+ .select2-results .select2-disabled.select2-highlighted {
459
+ color: #666;
460
+ background: #f4f4f4;
461
+ display: list-item;
462
+ cursor: default;
463
+ }
464
+
465
+ .select2-results .select2-disabled {
466
+ background: #f4f4f4;
467
+ display: list-item;
468
+ cursor: default;
469
+ }
470
+
471
+ .select2-results .select2-selected {
472
+ display: none;
473
+ }
474
+
475
+ .select2-more-results.select2-active {
476
+ background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%;
477
+ }
478
+
479
+ .select2-results .select2-ajax-error {
480
+ background: rgba(255, 50, 50, .2);
481
+ }
482
+
483
+ .select2-more-results {
484
+ background: #f4f4f4;
485
+ display: list-item;
486
+ }
487
+
488
+ /* disabled styles */
489
+
490
+ .select2-container.select2-container-disabled .select2-choice {
491
+ background-color: #f4f4f4;
492
+ background-image: none;
493
+ border: 1px solid #ddd;
494
+ cursor: default;
495
+ }
496
+
497
+ .select2-container.select2-container-disabled .select2-choice .select2-arrow {
498
+ background-color: #f4f4f4;
499
+ background-image: none;
500
+ border-left: 0;
501
+ }
502
+
503
+ .select2-container.select2-container-disabled .select2-choice abbr {
504
+ display: none;
505
+ }
506
+
507
+ /* multiselect */
508
+
509
+ .select2-container-multi .select2-choices {
510
+ height: auto !important;
511
+ height: 1%;
512
+ margin: 0;
513
+ padding: 0 5px 0 0;
514
+ position: relative;
515
+
516
+ border: 1px solid #aaa;
517
+ cursor: text;
518
+ overflow: hidden;
519
+
520
+ background-color: #fff;
521
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eee), color-stop(15%, #fff));
522
+ background-image: -webkit-linear-gradient(top, #eee 1%, #fff 15%);
523
+ background-image: -moz-linear-gradient(top, #eee 1%, #fff 15%);
524
+ background-image: linear-gradient(to bottom, #eee 1%, #fff 15%);
525
+ }
526
+
527
+ html[dir="rtl"] .select2-container-multi .select2-choices {
528
+ padding: 0 0 0 5px;
529
+ }
530
+
531
+ .select2-locked {
532
+ padding: 3px 5px 3px 5px !important;
533
+ }
534
+
535
+ .select2-container-multi .select2-choices {
536
+ min-height: 26px;
537
+ }
538
+
539
+ .select2-container-multi.select2-container-active .select2-choices {
540
+ border: 1px solid #5897fb;
541
+ outline: none;
542
+
543
+ -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
544
+ box-shadow: 0 0 5px rgba(0, 0, 0, .3);
545
+ }
546
+
547
+ .select2-container-multi .select2-choices li {
548
+ float: left;
549
+ list-style: none;
550
+ }
551
+
552
+ html[dir="rtl"] .select2-container-multi .select2-choices li {
553
+ float: right;
554
+ }
555
+
556
+ .select2-container-multi .select2-choices .select2-search-field {
557
+ margin: 0;
558
+ padding: 0;
559
+ white-space: nowrap;
560
+ }
561
+
562
+ .select2-container-multi .select2-choices .select2-search-field input {
563
+ padding: 5px;
564
+ margin: 1px 0;
565
+
566
+ font-family: sans-serif;
567
+ font-size: 100%;
568
+ color: #666;
569
+ outline: 0;
570
+ border: 0;
571
+ -webkit-box-shadow: none;
572
+ box-shadow: none;
573
+ background: transparent !important;
574
+ }
575
+
576
+ .select2-container-multi .select2-choices .select2-search-field input.select2-active {
577
+ background: #fff url('select2-spinner.gif') no-repeat 100% !important;
578
+ }
579
+
580
+ .select2-default {
581
+ color: #999 !important;
582
+ }
583
+
584
+ .select2-container-multi .select2-choices .select2-search-choice {
585
+ padding: 3px 5px 3px 18px;
586
+ margin: 3px 0 3px 5px;
587
+ position: relative;
588
+
589
+ line-height: 13px;
590
+ color: #333;
591
+ cursor: default;
592
+ border: 1px solid #aaaaaa;
593
+
594
+ border-radius: 3px;
595
+
596
+ -webkit-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
597
+ box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
598
+
599
+ background-clip: padding-box;
600
+
601
+ -webkit-touch-callout: none;
602
+ -webkit-user-select: none;
603
+ -moz-user-select: none;
604
+ -ms-user-select: none;
605
+ user-select: none;
606
+
607
+ background-color: #e4e4e4;
608
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0);
609
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));
610
+ background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
611
+ background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
612
+ background-image: linear-gradient(to bottom, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
613
+ }
614
+
615
+ html[dir="rtl"] .select2-container-multi .select2-choices .select2-search-choice {
616
+ margin: 3px 5px 3px 0;
617
+ padding: 3px 18px 3px 5px;
618
+ }
619
+
620
+ .select2-container-multi .select2-choices .select2-search-choice .select2-chosen {
621
+ cursor: default;
622
+ }
623
+
624
+ .select2-container-multi .select2-choices .select2-search-choice-focus {
625
+ background: #d4d4d4;
626
+ }
627
+
628
+ .select2-search-choice-close {
629
+ display: block;
630
+ width: 12px;
631
+ height: 13px;
632
+ position: absolute;
633
+ right: 3px;
634
+ top: 4px;
635
+
636
+ font-size: 1px;
637
+ outline: none;
638
+ background: url('select2.png') right top no-repeat;
639
+ }
640
+
641
+ html[dir="rtl"] .select2-search-choice-close {
642
+ right: auto;
643
+ left: 3px;
644
+ }
645
+
646
+ .select2-container-multi .select2-search-choice-close {
647
+ left: 3px;
648
+ }
649
+
650
+ html[dir="rtl"] .select2-container-multi .select2-search-choice-close {
651
+ left: auto;
652
+ right: 2px;
653
+ }
654
+
655
+ .select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {
656
+ background-position: right -11px;
657
+ }
658
+
659
+ .select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
660
+ background-position: right -11px;
661
+ }
662
+
663
+ /* disabled styles */
664
+ .select2-container-multi.select2-container-disabled .select2-choices {
665
+ background-color: #f4f4f4;
666
+ background-image: none;
667
+ border: 1px solid #ddd;
668
+ cursor: default;
669
+ }
670
+
671
+ .select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
672
+ padding: 3px 5px 3px 5px;
673
+ border: 1px solid #ddd;
674
+ background-image: none;
675
+ background-color: #f4f4f4;
676
+ }
677
+
678
+ .select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close {
679
+ display: none;
680
+ background: none;
681
+ }
682
+
683
+ /* end multiselect */
684
+
685
+ .select2-result-selectable .select2-match,
686
+ .select2-result-unselectable .select2-match {
687
+ text-decoration: underline;
688
+ }
689
+
690
+ .select2-offscreen, .select2-offscreen:focus {
691
+ clip: rect(0 0 0 0) !important;
692
+ width: 1px !important;
693
+ height: 1px !important;
694
+ border: 0 !important;
695
+ margin: 0 !important;
696
+ padding: 0 !important;
697
+ overflow: hidden !important;
698
+ position: absolute !important;
699
+ outline: 0 !important;
700
+ left: 0px !important;
701
+ top: 0px !important;
702
+ }
703
+
704
+ .select2-display-none {
705
+ display: none;
706
+ }
707
+
708
+ .select2-measure-scrollbar {
709
+ position: absolute;
710
+ top: -10000px;
711
+ left: -10000px;
712
+ width: 100px;
713
+ height: 100px;
714
+ overflow: scroll;
715
+ }
716
+
717
+ /* Retina-ize icons */
718
+
719
+ @media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 2dppx) {
720
+ .select2-search input,
721
+ .select2-search-choice-close,
722
+ .select2-container .select2-choice abbr,
723
+ .select2-container .select2-choice .select2-arrow b {
724
+ background-image: url('select2x2.png') !important;
725
+ background-repeat: no-repeat !important;
726
+ background-size: 60px 40px !important;
727
+ }
728
+
729
+ .select2-search input {
730
+ background-position: 100% -21px !important;
731
+ }
732
+ }
assets/css/select2/select2.png ADDED
Binary file
assets/css/select2/select2x2.png ADDED
Binary file
assets/css/select2/spinner.gif ADDED
Binary file
assets/css/timer.css ADDED
File without changes
assets/css/tipsy.css ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; }
2
+ .tipsy-inner { background-color: #000; color: #FFF; max-width: 200px; padding: 5px 8px 4px 8px; text-align: center; }
3
+
4
+ /* Rounded corners */
5
+ .tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
6
+
7
+ /* Uncomment for shadow */
8
+ /*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/
9
+
10
+ .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; }
11
+
12
+ /* Rules to colour arrows */
13
+ .tipsy-arrow-n { border-bottom-color: #000; }
14
+ .tipsy-arrow-s { border-top-color: #000; }
15
+ .tipsy-arrow-e { border-left-color: #000; }
16
+ .tipsy-arrow-w { border-right-color: #000; }
17
+
18
+ .tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; }
19
+ .tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
20
+ .tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
21
+ .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
22
+ .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
23
+ .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
24
+ .tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; }
25
+ .tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; }
assets/css/toastr.css ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .toast-title {
2
+ font-weight: bold;
3
+ }
4
+ .toast-message {
5
+ -ms-word-wrap: break-word;
6
+ word-wrap: break-word;
7
+ }
8
+ .toast-message a,
9
+ .toast-message label {
10
+ color: #ffffff;
11
+ }
12
+ .toast-message a:hover {
13
+ color: #cccccc;
14
+ text-decoration: none;
15
+ }
16
+ .toast-close-button {
17
+ position: relative;
18
+ right: -0.3em;
19
+ top: -0.3em;
20
+ float: right;
21
+ font-size: 20px;
22
+ font-weight: bold;
23
+ color: #ffffff;
24
+ -webkit-text-shadow: 0 1px 0 #ffffff;
25
+ text-shadow: 0 1px 0 #ffffff;
26
+ opacity: 0.8;
27
+ -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
28
+ filter: alpha(opacity=80);
29
+ }
30
+ .toast-close-button:hover,
31
+ .toast-close-button:focus {
32
+ color: #000000;
33
+ text-decoration: none;
34
+ cursor: pointer;
35
+ opacity: 0.4;
36
+ -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
37
+ filter: alpha(opacity=40);
38
+ }
39
+ /*Additional properties for button version
40
+ iOS requires the button element instead of an anchor tag.
41
+ If you want the anchor version, it requires `href="#"`.*/
42
+ button.toast-close-button {
43
+ padding: 0;
44
+ cursor: pointer;
45
+ background: transparent;
46
+ border: 0;
47
+ -webkit-appearance: none;
48
+ }
49
+ .toast-top-center {
50
+ top: 0;
51
+ right: 0;
52
+ width: 100%;
53
+ }
54
+ .toast-bottom-center {
55
+ bottom: 0;
56
+ right: 0;
57
+ width: 100%;
58
+ }
59
+ .toast-top-full-width {
60
+ top: 0;
61
+ right: 0;
62
+ width: 100%;
63
+ }
64
+ .toast-bottom-full-width {
65
+ bottom: 0;
66
+ right: 0;
67
+ width: 100%;
68
+ }
69
+ .toast-top-left {
70
+ top: 12px;
71
+ left: 12px;
72
+ }
73
+ .toast-top-right {
74
+ top: 12px;
75
+ right: 12px;
76
+ }
77
+ .toast-bottom-right {
78
+ right: 12px;
79
+ bottom: 12px;
80
+ }
81
+ .toast-bottom-left {
82
+ bottom: 12px;
83
+ left: 12px;
84
+ }
85
+ #toast-container {
86
+ position: fixed;
87
+ z-index: 999999;
88
+ /*overrides*/
89
+
90
+ }
91
+ #toast-container * {
92
+ -moz-box-sizing: border-box;
93
+ -webkit-box-sizing: border-box;
94
+ box-sizing: border-box;
95
+ }
96
+ #toast-container > div {
97
+ position: relative;
98
+ overflow: hidden;
99
+ margin: 0 0 6px;
100
+ padding: 15px 15px 15px 50px;
101
+ width: 300px;
102
+ -moz-border-radius: 3px 3px 3px 3px;
103
+ -webkit-border-radius: 3px 3px 3px 3px;
104
+ border-radius: 3px 3px 3px 3px;
105
+ background-position: 15px center;
106
+ background-repeat: no-repeat;
107
+ -moz-box-shadow: 0 0 12px #999999;
108
+ -webkit-box-shadow: 0 0 12px #999999;
109
+ box-shadow: 0 0 12px #999999;
110
+ color: #ffffff;
111
+ opacity: 0.8;
112
+ -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
113
+ filter: alpha(opacity=80);
114
+ }
115
+ #toast-container > :hover {
116
+ -moz-box-shadow: 0 0 12px #000000;
117
+ -webkit-box-shadow: 0 0 12px #000000;
118
+ box-shadow: 0 0 12px #000000;
119
+ opacity: 1;
120
+ -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
121
+ filter: alpha(opacity=100);
122
+ cursor: pointer;
123
+ }
124
+ #toast-container > .toast-info {
125
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important;
126
+ }
127
+ #toast-container > .toast-error {
128
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important;
129
+ }
130
+ #toast-container > .toast-success {
131
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important;
132
+ }
133
+ #toast-container > .toast-warning {
134
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important;
135
+ }
136
+ #toast-container.toast-top-center > div,
137
+ #toast-container.toast-bottom-center > div {
138
+ width: 300px;
139
+ margin: auto;
140
+ }
141
+ #toast-container.toast-top-full-width > div,
142
+ #toast-container.toast-bottom-full-width > div {
143
+ width: 96%;
144
+ margin: auto;
145
+ }
146
+ .toast {
147
+ background-color: #030303;
148
+ }
149
+ .toast-success {
150
+ background-color: #51a351;
151
+ }
152
+ .toast-error {
153
+ background-color: #bd362f;
154
+ }
155
+ .toast-info {
156
+ background-color: #2f96b4;
157
+ }
158
+ .toast-warning {
159
+ background-color: #f89406;
160
+ }
161
+ .toast-progress {
162
+ position: absolute;
163
+ left: 0;
164
+ bottom: 0;
165
+ height: 4px;
166
+ background-color: #000000;
167
+ opacity: 0.4;
168
+ -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
169
+ filter: alpha(opacity=40);
170
+ }
171
+ /*Responsive Design*/
172
+ @media all and (max-width: 240px) {
173
+ #toast-container > div {
174
+ padding: 8px 8px 8px 50px;
175
+ width: 11em;
176
+ }
177
+ #toast-container .toast-close-button {
178
+ right: -0.2em;
179
+ top: -0.2em;
180
+ }
181
+ }
182
+ @media all and (min-width: 241px) and (max-width: 480px) {
183
+ #toast-container > div {
184
+ padding: 8px 8px 8px 50px;
185
+ width: 18em;
186
+ }
187
+ #toast-container .toast-close-button {
188
+ right: -0.2em;
189
+ top: -0.2em;
190
+ }
191
+ }
192
+ @media all and (min-width: 481px) and (max-width: 768px) {
193
+ #toast-container > div {
194
+ padding: 15px 15px 15px 50px;
195
+ width: 25em;
196
+ }
197
+ }
assets/fonts/Sumana-Regular.ttf ADDED
Binary file
assets/fonts/icomoon.eot ADDED
Binary file
assets/fonts/icomoon.svg ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
+ <svg xmlns="http://www.w3.org/2000/svg">
4
+ <metadata>Generated by IcoMoon</metadata>
5
+ <defs>
6
+ <font id="icomoon" horiz-adv-x="1024">
7
+ <font-face units-per-em="1024" ascent="960" descent="-64" />
8
+ <missing-glyph horiz-adv-x="1024" />
9
+ <glyph unicode="&#x20;" horiz-adv-x="512" d="" />
10
+ <glyph unicode="&#xe900;" glyph-name="books" horiz-adv-x="1152" d="M224 832h-192c-17.6 0-32-14.4-32-32v-704c0-17.6 14.4-32 32-32h192c17.6 0 32 14.4 32 32v704c0 17.6-14.4 32-32 32zM192 640h-128v64h128v-64zM544 832h-192c-17.6 0-32-14.4-32-32v-704c0-17.6 14.4-32 32-32h192c17.6 0 32 14.4 32 32v704c0 17.6-14.4 32-32 32zM512 640h-128v64h128v-64zM765.088 782.52l-171.464-86.394c-15.716-7.918-22.096-27.258-14.178-42.976l287.978-571.548c7.918-15.718 27.258-22.098 42.976-14.178l171.464 86.392c15.716 7.92 22.096 27.26 14.178 42.974l-287.978 571.55c-7.92 15.718-27.26 22.1-42.976 14.18zM928 96c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 17.673 14.327 32 32 32s32-14.327 32-32z" />
11
+ <glyph unicode="&#xe901;" glyph-name="alarm" d="M512 832c-247.424 0-448-200.576-448-448s200.576-448 448-448 448 200.576 448 448-200.576 448-448 448zM512 24c-198.824 0-360 161.178-360 360 0 198.824 161.176 360 360 360 198.822 0 360-161.176 360-360 0-198.822-161.178-360-360-360zM934.784 672.826c16.042 28.052 25.216 60.542 25.216 95.174 0 106.040-85.96 192-192 192-61.818 0-116.802-29.222-151.92-74.596 131.884-27.236 245.206-105.198 318.704-212.578v0zM407.92 885.404c-35.116 45.374-90.102 74.596-151.92 74.596-106.040 0-192-85.96-192-192 0-34.632 9.174-67.122 25.216-95.174 73.5 107.38 186.822 185.342 318.704 212.578zM512 384v256h-64v-320h256v64z" />
12
+ <glyph unicode="&#xe902;" glyph-name="spinner10" d="M0.042 446.382l-0.022-0.004c0 0 0.012-0.090 0.028-0.222 0.11-3.878 0.55-7.676 1.322-11.352 0.204-1.746 0.428-3.66 0.674-5.774 0.222-1.886 0.46-3.914 0.718-6.078 0.374-2.566 0.77-5.292 1.19-8.176 0.856-5.746 1.8-12.124 2.908-18.958 1.348-6.446 2.804-13.414 4.364-20.864 0.71-3.718 1.776-7.504 2.786-11.406 1.024-3.89 2.078-7.894 3.16-12.004 0.566-2.042 1.040-4.132 1.708-6.208 0.656-2.074 1.32-4.176 1.988-6.3 1.348-4.234 2.726-8.566 4.136-12.988 0.352-1.106 0.708-2.21 1.064-3.324 0.408-1.102 0.814-2.208 1.226-3.316 0.826-2.218 1.658-4.458 2.502-6.714 1.696-4.496 3.422-9.078 5.18-13.742 1.968-4.566 3.97-9.214 6.004-13.934 1.018-2.348 2.044-4.714 3.078-7.098 1.048-2.376 2.27-4.704 3.408-7.074 2.322-4.714 4.678-9.496 7.062-14.332 2.47-4.786 5.208-9.512 7.846-14.328 1.336-2.398 2.68-4.808 4.028-7.23 1.368-2.41 2.902-4.75 4.356-7.14 2.95-4.738 5.93-9.524 8.934-14.348 12.64-18.894 26.676-37.566 42.21-55.278 15.712-17.578 32.726-34.25 50.692-49.602 18.18-15.136 37.264-28.902 56.726-41.114 19.604-12.036 39.644-22.312 59.376-31.144 5.004-2.040 9.964-4.062 14.878-6.066 2.462-0.972 4.868-2.032 7.336-2.918 2.47-0.868 4.93-1.734 7.376-2.594 4.898-1.684 9.678-3.468 14.484-4.992 4.832-1.43 9.604-2.844 14.312-4.242 2.356-0.672 4.66-1.426 7.004-2.012 2.346-0.574 4.676-1.14 6.986-1.704 4.606-1.118 9.142-2.214 13.604-3.296 4.5-0.868 8.926-1.722 13.27-2.558 2.166-0.41 4.31-0.82 6.434-1.222 1.062-0.2 2.118-0.398 3.166-0.598 1.060-0.148 2.118-0.292 3.166-0.442 4.192-0.582 8.292-1.152 12.3-1.71 1.998-0.274 3.972-0.546 5.922-0.816 1.946-0.286 3.904-0.378 5.814-0.57 3.822-0.336 7.544-0.664 11.164-0.98 3.616-0.304 7.104-0.688 10.526-0.738 0.23-0.008 0.452-0.016 0.682-0.026 0.614-34.812 29.008-62.846 63.968-62.846 0.542 0 1.080 0.028 1.62 0.042v-0.022c0 0 0.090 0.012 0.224 0.028 3.878 0.11 7.674 0.55 11.35 1.322 1.748 0.204 3.662 0.426 5.776 0.672 1.884 0.222 3.912 0.462 6.076 0.718 2.566 0.376 5.292 0.772 8.176 1.192 5.746 0.856 12.124 1.8 18.958 2.908 6.446 1.348 13.414 2.804 20.864 4.362 3.718 0.712 7.504 1.778 11.406 2.786 3.892 1.026 7.894 2.080 12.004 3.162 2.044 0.566 4.132 1.040 6.208 1.708 2.074 0.656 4.174 1.318 6.3 1.988 4.232 1.348 8.564 2.726 12.988 4.134 1.104 0.354 2.21 0.708 3.324 1.066 1.1 0.406 2.206 0.814 3.316 1.226 2.216 0.824 4.456 1.658 6.714 2.5 4.496 1.698 9.078 3.424 13.74 5.182 4.568 1.968 9.216 3.97 13.936 6.004 2.348 1.018 4.714 2.044 7.098 3.078 2.376 1.048 4.702 2.27 7.074 3.408 4.714 2.322 9.494 4.678 14.33 7.062 4.786 2.47 9.512 5.208 14.328 7.846 2.398 1.336 4.808 2.678 7.23 4.028 2.41 1.366 4.75 2.9 7.14 4.354 4.738 2.952 9.524 5.93 14.35 8.936 18.89 12.64 37.564 26.674 55.278 42.21 17.574 15.712 34.248 32.726 49.602 50.69 15.136 18.182 28.902 37.264 41.112 56.728 12.036 19.602 22.314 39.644 31.142 59.376 2.042 5.002 4.062 9.964 6.068 14.878 0.974 2.462 2.032 4.868 2.918 7.334 0.87 2.472 1.732 4.932 2.592 7.376 1.686 4.898 3.468 9.678 4.994 14.484 1.432 4.832 2.846 9.604 4.24 14.31 0.674 2.358 1.43 4.66 2.016 7.004 0.57 2.348 1.138 4.676 1.702 6.988 1.118 4.606 2.216 9.14 3.296 13.602 0.868 4.502 1.72 8.928 2.558 13.272 0.41 2.164 0.818 4.308 1.222 6.434 0.2 1.060 0.398 2.116 0.596 3.164 0.148 1.062 0.296 2.118 0.444 3.168 0.582 4.19 1.152 8.292 1.708 12.3 0.278 1.996 0.55 3.97 0.82 5.922 0.284 1.946 0.376 3.902 0.568 5.812 0.336 3.822 0.664 7.546 0.98 11.164 0.304 3.616 0.686 7.106 0.738 10.528 0.020 0.534 0.040 1.044 0.058 1.574 35.224 0.146 63.732 28.738 63.732 63.992 0 0.542-0.028 1.080-0.042 1.62h0.022c0 0-0.012 0.090-0.028 0.224-0.11 3.878-0.55 7.674-1.322 11.35-0.204 1.748-0.428 3.662-0.674 5.776-0.222 1.886-0.46 3.914-0.718 6.076-0.374 2.566-0.77 5.294-1.19 8.176-0.856 5.746-1.8 12.124-2.908 18.958-1.348 6.444-2.804 13.414-4.364 20.862-0.71 3.72-1.776 7.506-2.786 11.408-1.024 3.892-2.078 7.894-3.16 12.002-0.566 2.044-1.040 4.134-1.708 6.208-0.656 2.076-1.32 4.174-1.988 6.3-1.348 4.234-2.726 8.566-4.136 12.99-0.352 1.102-0.708 2.21-1.064 3.324-0.408 1.1-0.814 2.206-1.226 3.316-0.826 2.216-1.658 4.454-2.502 6.714-1.696 4.498-3.422 9.080-5.18 13.74-1.968 4.57-3.97 9.216-6.004 13.936-1.020 2.348-2.044 4.714-3.078 7.098-1.048 2.376-2.27 4.702-3.408 7.076-2.322 4.714-4.678 9.494-7.062 14.33-2.47 4.786-5.208 9.512-7.846 14.328-1.336 2.398-2.68 4.808-4.028 7.23-1.368 2.41-2.902 4.75-4.356 7.14-2.95 4.74-5.93 9.524-8.934 14.35-12.64 18.892-26.676 37.564-42.21 55.278-15.712 17.576-32.726 34.25-50.692 49.602-18.18 15.136-37.264 28.902-56.726 41.112-19.604 12.036-39.644 22.314-59.376 31.142-5.004 2.040-9.964 4.062-14.878 6.068-2.462 0.974-4.868 2.032-7.336 2.918-2.47 0.87-4.93 1.734-7.376 2.592-4.898 1.684-9.678 3.468-14.484 4.994-4.832 1.432-9.604 2.846-14.312 4.242-2.356 0.672-4.66 1.428-7.004 2.014-2.346 0.572-4.676 1.138-6.986 1.702-4.606 1.118-9.142 2.216-13.604 3.298-4.5 0.868-8.926 1.72-13.27 2.558-2.166 0.412-4.31 0.82-6.434 1.222-1.062 0.2-2.118 0.398-3.166 0.596-1.060 0.148-2.118 0.296-3.166 0.442-4.192 0.584-8.292 1.154-12.3 1.71-1.998 0.276-3.972 0.55-5.922 0.82-1.946 0.284-3.904 0.376-5.814 0.57-3.822 0.336-7.544 0.664-11.164 0.98-3.616 0.304-7.104 0.686-10.526 0.738-0.852 0.032-1.674 0.062-2.512 0.092-0.65 34.78-29.028 62.778-63.966 62.778-0.542 0-1.080-0.028-1.62-0.042l-0.002 0.022c0 0-0.090-0.012-0.222-0.028-3.878-0.11-7.676-0.55-11.352-1.322-1.748-0.204-3.662-0.426-5.776-0.672-1.884-0.222-3.912-0.462-6.076-0.718-2.566-0.376-5.292-0.772-8.176-1.192-5.746-0.856-12.124-1.8-18.958-2.908-6.446-1.348-13.414-2.804-20.864-4.362-3.718-0.712-7.504-1.778-11.406-2.786-3.892-1.026-7.894-2.080-12.004-3.162-2.044-0.566-4.132-1.040-6.208-1.708-2.074-0.656-4.174-1.318-6.3-1.988-4.232-1.348-8.564-2.726-12.988-4.134-1.104-0.354-2.21-0.708-3.324-1.066-1.1-0.406-2.206-0.814-3.316-1.226-2.216-0.824-4.456-1.658-6.714-2.5-4.496-1.698-9.078-3.424-13.74-5.182-4.568-1.968-9.216-3.97-13.936-6.004-2.348-1.018-4.714-2.044-7.098-3.078-2.376-1.048-4.702-2.27-7.074-3.408-4.714-2.322-9.494-4.678-14.33-7.062-4.786-2.47-9.512-5.208-14.328-7.846-2.398-1.336-4.808-2.678-7.23-4.028-2.41-1.366-4.75-2.9-7.14-4.354-4.738-2.952-9.524-5.93-14.35-8.936-18.89-12.64-37.564-26.674-55.278-42.21-17.574-15.712-34.248-32.726-49.602-50.69-15.136-18.182-28.902-37.264-41.112-56.728-12.036-19.602-22.314-39.644-31.142-59.376-2.042-5.002-4.062-9.964-6.068-14.878-0.974-2.462-2.032-4.868-2.918-7.334-0.87-2.472-1.732-4.932-2.592-7.376-1.686-4.898-3.468-9.678-4.994-14.484-1.432-4.832-2.846-9.604-4.24-14.31-0.674-2.358-1.43-4.66-2.016-7.004-0.57-2.348-1.138-4.676-1.702-6.988-1.118-4.606-2.216-9.14-3.296-13.602-0.868-4.502-1.72-8.928-2.558-13.272-0.41-2.164-0.818-4.308-1.222-6.434-0.2-1.060-0.398-2.116-0.596-3.164-0.148-1.062-0.296-2.118-0.444-3.168-0.582-4.19-1.152-8.292-1.708-12.3-0.278-1.996-0.55-3.97-0.82-5.922-0.284-1.946-0.376-3.902-0.568-5.812-0.336-3.822-0.664-7.546-0.98-11.164-0.304-3.616-0.686-7.106-0.738-10.528-0.020-0.548-0.040-1.076-0.058-1.62-34.376-1.112-61.902-29.304-61.902-63.946 0-0.542 0.028-1.078 0.042-1.618zM73.518 511.294c0.042 0.196 0.086 0.384 0.128 0.58 0.644 3.248 1.632 6.542 2.556 9.942 0.934 3.388 1.894 6.876 2.88 10.454 0.516 1.78 0.934 3.602 1.546 5.406 0.596 1.802 1.202 3.628 1.81 5.476 1.218 3.682 2.464 7.45 3.736 11.294 0.316 0.958 0.634 1.924 0.956 2.892 0.37 0.954 0.74 1.914 1.114 2.876 0.746 1.924 1.5 3.868 2.26 5.83 1.52 3.904 3.070 7.882 4.646 11.93 1.768 3.96 3.566 7.99 5.392 12.080 0.908 2.038 1.824 4.090 2.746 6.156 0.932 2.060 2.036 4.072 3.052 6.126 2.070 4.084 4.17 8.222 6.294 12.412 2.202 4.142 4.654 8.224 6.998 12.392 1.184 2.074 2.374 4.16 3.57 6.256 1.21 2.086 2.586 4.102 3.876 6.166 2.616 4.098 5.256 8.232 7.918 12.402 11.234 16.298 23.632 32.398 37.33 47.638 13.874 15.104 28.842 29.404 44.598 42.548 15.974 12.928 32.686 24.65 49.676 35.022 17.13 10.194 34.6 18.838 51.734 26.258 4.35 1.7 8.662 3.382 12.934 5.050 2.136 0.812 4.216 1.71 6.36 2.444 2.146 0.714 4.28 1.428 6.404 2.136 4.25 1.386 8.382 2.888 12.548 4.142 4.184 1.174 8.314 2.332 12.392 3.474 2.038 0.55 4.026 1.19 6.054 1.662 2.030 0.458 4.044 0.914 6.044 1.368 3.978 0.91 7.896 1.806 11.748 2.688 3.888 0.686 7.71 1.36 11.462 2.022 1.868 0.33 3.716 0.658 5.546 0.98 0.914 0.162 1.824 0.324 2.728 0.484 0.916 0.112 1.828 0.222 2.734 0.332 3.612 0.448 7.148 0.882 10.604 1.31 1.72 0.216 3.422 0.432 5.102 0.644 1.674 0.226 3.364 0.266 5.010 0.408 3.292 0.238 6.498 0.472 9.616 0.7 3.11 0.218 6.11 0.524 9.058 0.508 5.848 0.132 11.32 0.256 16.38 0.372 4.664-0.168 8.948-0.324 12.818-0.462 1.914-0.054 3.726-0.108 5.432-0.156 2.122-0.134 4.108-0.26 5.958-0.378 2.13-0.138 4.060-0.266 5.82-0.38 3.256-0.51 6.592-0.782 9.99-0.782 0.466 0 0.93 0.026 1.396 0.036 0.132-0.008 0.224-0.014 0.224-0.014v0.020c31.14 0.778 56.75 23.784 61.556 53.754 0.542-0.12 1.064-0.236 1.612-0.356 3.246-0.644 6.542-1.632 9.942-2.556 3.386-0.934 6.876-1.894 10.454-2.88 1.778-0.516 3.602-0.934 5.404-1.546 1.802-0.596 3.63-1.202 5.478-1.812 3.68-1.218 7.448-2.464 11.292-3.736 0.96-0.316 1.924-0.634 2.892-0.956 0.956-0.37 1.914-0.74 2.876-1.112 1.926-0.746 3.868-1.5 5.83-2.26 3.904-1.52 7.884-3.070 11.932-4.646 3.96-1.768 7.988-3.566 12.080-5.392 2.038-0.908 4.088-1.824 6.156-2.746 2.060-0.932 4.072-2.036 6.126-3.054 4.082-2.070 8.222-4.17 12.41-6.294 4.144-2.202 8.226-4.654 12.394-6.998 2.074-1.184 4.16-2.374 6.256-3.572 2.086-1.21 4.102-2.586 6.166-3.876 4.098-2.616 8.23-5.256 12.402-7.918 16.296-11.234 32.398-23.632 47.636-37.33 15.104-13.874 29.406-28.842 42.55-44.598 12.928-15.974 24.648-32.686 35.020-49.676 10.196-17.13 18.84-34.6 26.26-51.736 1.698-4.348 3.382-8.662 5.050-12.932 0.812-2.136 1.71-4.216 2.444-6.36 0.714-2.146 1.428-4.28 2.136-6.404 1.386-4.25 2.888-8.384 4.142-12.548 1.174-4.184 2.33-8.316 3.474-12.392 0.55-2.038 1.19-4.026 1.66-6.054 0.46-2.030 0.916-4.046 1.368-6.046 0.91-3.978 1.808-7.896 2.688-11.748 0.688-3.888 1.362-7.71 2.024-11.462 0.33-1.868 0.656-3.716 0.98-5.548 0.162-0.914 0.324-1.824 0.484-2.728 0.11-0.916 0.222-1.828 0.332-2.734 0.446-3.612 0.882-7.148 1.31-10.604 0.216-1.72 0.432-3.42 0.642-5.1 0.226-1.674 0.268-3.364 0.41-5.010 0.238-3.292 0.472-6.498 0.7-9.616 0.218-3.11 0.524-6.11 0.508-9.058 0.132-5.848 0.256-11.32 0.372-16.38-0.168-4.664-0.324-8.948-0.462-12.818-0.054-1.914-0.108-3.726-0.156-5.432-0.134-2.122-0.26-4.108-0.378-5.958-0.138-2.13-0.266-4.060-0.38-5.82-0.498-3.256-0.768-6.592-0.768-9.99 0-0.468 0.026-0.93 0.036-1.396-0.008-0.132-0.016-0.224-0.016-0.224h0.022c0.768-30.766 23.236-56.128 52.682-61.37-0.066-0.296-0.13-0.584-0.198-0.884-0.644-3.248-1.632-6.542-2.556-9.942-0.934-3.388-1.894-6.876-2.88-10.454-0.516-1.78-0.934-3.602-1.546-5.406-0.596-1.802-1.202-3.628-1.81-5.476-1.218-3.682-2.464-7.45-3.736-11.294-0.316-0.958-0.634-1.924-0.956-2.892-0.37-0.954-0.74-1.914-1.114-2.876-0.746-1.924-1.5-3.868-2.26-5.83-1.52-3.904-3.070-7.882-4.646-11.93-1.768-3.96-3.566-7.99-5.392-12.080-0.908-2.038-1.824-4.090-2.746-6.156-0.932-2.060-2.036-4.072-3.052-6.126-2.070-4.084-4.17-8.222-6.294-12.412-2.202-4.142-4.654-8.224-6.998-12.392-1.184-2.074-2.374-4.16-3.57-6.256-1.21-2.086-2.586-4.102-3.876-6.166-2.616-4.098-5.256-8.232-7.918-12.402-11.234-16.298-23.632-32.398-37.33-47.638-13.874-15.104-28.842-29.404-44.598-42.548-15.974-12.928-32.686-24.65-49.676-35.022-17.13-10.194-34.6-18.838-51.734-26.258-4.35-1.7-8.662-3.382-12.934-5.050-2.136-0.812-4.216-1.71-6.36-2.444-2.146-0.714-4.28-1.428-6.404-2.136-4.25-1.386-8.382-2.888-12.548-4.142-4.184-1.174-8.314-2.332-12.392-3.474-2.038-0.55-4.026-1.19-6.054-1.662-2.030-0.458-4.044-0.914-6.044-1.368-3.978-0.91-7.896-1.806-11.748-2.688-3.888-0.686-7.71-1.36-11.462-2.022-1.868-0.33-3.716-0.658-5.546-0.98-0.914-0.162-1.824-0.324-2.728-0.484-0.916-0.112-1.828-0.222-2.734-0.332-3.612-0.448-7.148-0.882-10.604-1.31-1.72-0.216-3.422-0.432-5.102-0.644-1.674-0.226-3.364-0.266-5.010-0.408-3.292-0.238-6.498-0.472-9.616-0.7-3.11-0.218-6.11-0.524-9.058-0.508-5.848-0.132-11.32-0.256-16.38-0.372-4.664 0.168-8.948 0.324-12.818 0.462-1.914 0.054-3.726 0.108-5.432 0.156-2.122 0.134-4.108 0.26-5.958 0.378-2.13 0.138-4.060 0.266-5.82 0.38-3.256 0.51-6.592 0.782-9.99 0.782-0.466 0-0.93-0.026-1.396-0.036-0.132 0.008-0.224 0.014-0.224 0.014v-0.020c-31.004-0.774-56.524-23.586-61.488-53.364-3.2 0.64-6.446 1.61-9.792 2.522-3.386 0.934-6.876 1.894-10.454 2.878-1.778 0.516-3.602 0.938-5.404 1.546-1.802 0.598-3.63 1.204-5.478 1.812-3.68 1.218-7.448 2.464-11.292 3.738-0.96 0.316-1.924 0.632-2.892 0.954-0.956 0.372-1.914 0.742-2.876 1.114-1.926 0.746-3.868 1.5-5.83 2.258-3.904 1.524-7.884 3.070-11.932 4.648-3.96 1.77-7.988 3.566-12.080 5.39-2.038 0.91-4.088 1.824-6.156 2.746-2.060 0.934-4.072 2.036-6.126 3.054-4.082 2.070-8.222 4.172-12.41 6.296-4.144 2.2-8.226 4.652-12.394 6.996-2.074 1.184-4.16 2.376-6.256 3.57-2.086 1.21-4.102 2.586-6.166 3.878-4.098 2.614-8.23 5.254-12.402 7.918-16.296 11.23-32.398 23.632-47.636 37.328-15.104 13.876-29.406 28.84-42.55 44.598-12.928 15.972-24.648 32.684-35.020 49.676-10.196 17.128-18.84 34.602-26.26 51.734-1.698 4.352-3.382 8.664-5.050 12.934-0.812 2.136-1.71 4.218-2.444 6.36-0.714 2.148-1.428 4.282-2.136 6.406-1.386 4.25-2.888 8.382-4.142 12.546-1.174 4.184-2.33 8.316-3.474 12.394-0.55 2.036-1.19 4.024-1.66 6.054-0.46 2.028-0.916 4.042-1.368 6.042-0.91 3.98-1.808 7.898-2.688 11.75-0.688 3.886-1.362 7.71-2.024 11.46-0.33 1.868-0.656 3.718-0.98 5.546-0.162 0.914-0.324 1.824-0.484 2.73-0.11 0.914-0.222 1.828-0.332 2.734-0.446 3.61-0.882 7.148-1.31 10.602-0.216 1.722-0.432 3.422-0.642 5.102-0.226 1.676-0.268 3.364-0.41 5.012-0.238 3.29-0.472 6.496-0.7 9.614-0.218 3.11-0.524 6.11-0.508 9.058-0.132 5.848-0.256 11.32-0.372 16.382 0.168 4.664 0.324 8.946 0.462 12.816 0.054 1.914 0.108 3.726 0.156 5.434 0.134 2.122 0.26 4.106 0.378 5.958 0.138 2.128 0.266 4.058 0.38 5.82 0.496 3.26 0.766 6.596 0.766 9.994 0 0.466-0.026 0.93-0.036 1.396 0.008 0.132 0.016 0.224 0.016 0.224h-0.022c-0.78 31.38-24.134 57.154-54.44 61.674z" />
13
+ <glyph unicode="&#xe903;" glyph-name="checkmark" d="M864 832l-480-480-224 224-160-160 384-384 640 640z" />
14
+ </font></defs></svg>
assets/fonts/icomoon.ttf ADDED
Binary file
assets/fonts/icomoon.woff ADDED
Binary file
assets/images/ajax-loader.gif ADDED
Binary file
assets/images/ajaxload.gif ADDED
Binary file
assets/images/animation.gif ADDED
Binary file
assets/images/grippy_large.png ADDED
Binary file
assets/images/icon-128x128.png ADDED
Binary file
assets/images/multiple-choice.png ADDED
Binary file
assets/images/openhand.cur ADDED
Binary file
assets/images/question.png ADDED
Binary file
assets/images/single-choice.png ADDED
Binary file
assets/images/spinner.gif ADDED
Binary file
assets/images/stripe.png ADDED
Binary file
assets/images/true-false.png ADDED
Binary file
assets/js/admin/admin.js ADDED
@@ -0,0 +1,825 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function($){
2
+ var LP_Admin = window.LP_Admin = {
3
+ init: function(){
4
+ var $doc = $(document);
5
+ $doc.on('click', '#learn-press-install-sample-data-notice a', this._importCourses )
6
+ .on('click', '.learn-press-admin-notice-dismiss', this._dismissNotice)
7
+ .on('click', '[data-remove-confirm]', this._confirm);
8
+ setTimeout(function() {
9
+ $('[data-remove-confirm]').each(function () {
10
+ console.log($(this))
11
+ })
12
+ }, 1000);
13
+ },
14
+ _confirm: function(e){
15
+ e.preventDefault();
16
+ return false;
17
+ },
18
+ _dismissNotice: function(e){
19
+
20
+ var $notice = $(e.target),
21
+ context = $notice.attr('data-context'),
22
+ transient = $notice.attr('data-transient');
23
+ if(context){
24
+ $.ajax({
25
+ url: LearnPress_Settings.ajax,
26
+ data: {
27
+ action: 'learnpress_dismiss_notice',
28
+ context: context,
29
+ transient: transient
30
+ },
31
+ success: function(response){
32
+ $notice.closest('.updated').fadeOut();
33
+ $notice.closest('.error').fadeOut();
34
+ }
35
+ });
36
+ return false;
37
+ }
38
+ },
39
+ _importCourses: function(e){
40
+ var $container = $('#learn-press-install-sample-data-notice'),
41
+ action = $(this).attr('data-action');
42
+ if( !action ){
43
+ return;
44
+ }
45
+ e.preventDefault();
46
+
47
+ if( action == 'yes' ) {
48
+ $container
49
+ .find('.install-sample-data-notice').slideUp()
50
+ .siblings('.install-sample-data-loading').slideDown()
51
+ }else{
52
+ $('#learn-press-install-sample-data-notice').fadeOut();
53
+ }
54
+ $.ajax({
55
+ url: ajaxurl,
56
+ dataType: 'html',
57
+ type: 'post',
58
+ data:{
59
+ action: 'learnpress_install_sample_data',
60
+ yes: action
61
+ },
62
+ success: function(response){
63
+ response = LearnPress.parseJSON(response);
64
+ if( response.url ){
65
+ $.ajax({
66
+ url: response.url,
67
+ success: function(){
68
+ $container
69
+ .find('.install-sample-data-notice').html(response.message).slideDown()
70
+ .siblings('.install-sample-data-loading').slideUp();
71
+ }
72
+ });
73
+ }else {
74
+ $container
75
+ .find('.install-sample-data-notice').html(response.message).slideDown()
76
+ .siblings('.install-sample-data-loading').slideUp();
77
+ }
78
+ }
79
+ })
80
+ }
81
+ }
82
+ var $doc = $(document);
83
+ function _ready(){
84
+ LP_Admin.init();
85
+ $(document).on('click', '.learn-press-add-ons .plugin-action-buttons a', function(e){
86
+ e.preventDefault();
87
+ var $plugin = $(this).closest('.plugin-card');
88
+ if( $(this).hasClass('button-working') ){
89
+ return;
90
+ }
91
+ $(this).addClass('button-working disabled');
92
+ $.ajax({
93
+ url: $(this).attr('href'),
94
+ data: {},
95
+ success: function(r){
96
+ $.ajax({
97
+ url: window.location.href,
98
+ success: function(r){
99
+ var $p = $(r).find('#'+$plugin.attr('id'));
100
+ if( $p.length ) {
101
+ $plugin.replaceWith($p)
102
+ }
103
+ }
104
+ })
105
+ }
106
+ });
107
+ });
108
+ var $sandbox_mode = $('#learn_press_paypal_sandbox_mode'),
109
+ $paypal_type = $('#learn_press_paypal_type');
110
+ $paypal_type.change(function(){
111
+ $('.learn_press_paypal_type_security').toggleClass( 'hide-if-js', 'security' != this.value );
112
+ });
113
+ $sandbox_mode.change(function(){
114
+ this.checked ? $('.sandbox input').removeAttr( 'readonly' ) : $('.sandbox input').attr( 'readonly', true );
115
+ });
116
+
117
+ $('#learn_press_paypal_enable').change(function(){
118
+ var $rows = $(this).closest('tr').siblings('tr');
119
+ if( this.checked ){
120
+ $rows.css("display", "");
121
+ }else{
122
+ $rows.css("display", "none");
123
+ }
124
+ }).trigger('change');
125
+
126
+ $('.learn-press-toggle-lesson-preview').on('change', function(){
127
+ $.ajax({
128
+ url: LearnPress_Settings.ajax,
129
+ data: {
130
+ action: 'learnpress_toggle_lesson_preview',
131
+ lesson_id: this.value,
132
+ previewable: this.checked ? 'yes' : 'no',
133
+ nonce: $(this).attr('data-nonce')
134
+ },
135
+ dataType: 'text',
136
+ success: function(response){
137
+ response = LearnPress.parseJSON(response);
138
+ }
139
+ });
140
+ });
141
+ }
142
+ $doc.ready(_ready);
143
+ })(jQuery);
144
+
145
+ /**
146
+ * Created by foobla on 3/10/2015.
147
+ */
148
+
149
+ if( typeof LearnPress == 'undefined' ) LearnPress = {};
150
+
151
+ jQuery(document).ready(function ($) {
152
+ $('.meta_box_edit').click(function (event) {
153
+ event.preventDefault();
154
+ LearnPress.log("haha");
155
+ var post_id = jQuery(this).closest('select').val();
156
+ var edit_link = jQuery('.meta_box_course_lesson_quiz').attr('site_url');
157
+ edit_link += "wp-admin/post.php?post=" + post_id + "&action=edit";
158
+ var new_window = window.open(edit_link);
159
+ LearnPress.log(post_id);
160
+ })
161
+ });
162
+
163
+ jQuery(document).ready(function ($) {
164
+ $("[name='lpr_settings[payment][method]']").click(function () {
165
+ $(".payments").css("display", "none");
166
+ var check = $(this).val();
167
+ $("[id*=" + check + "]").css("display", "");
168
+ });
169
+ $(".payments").css("display", "none");
170
+ var check = $("[name='lpr_settings[payment][method]']:checked").val();
171
+ $("[id*=" + check + "]").css("display", "");
172
+ });
173
+
174
+
175
+ jQuery(document).ready(function ($) {
176
+ $('#wp-admin-bar-be_teacher').click(function () {
177
+ $.ajax({
178
+ url : ajaxurl,
179
+ data : {
180
+ action: 'learnpress_be_teacher'
181
+ },
182
+ success: function () {
183
+ alert('You Are An Instructor Now');
184
+ setTimeout(function () {
185
+ location.reload();
186
+ }, 500);
187
+ }
188
+ })
189
+ });
190
+ });
191
+
192
+ jQuery(document).ready(function ($) {
193
+ $('.lpr-set-up').click(function (evt) {
194
+ evt.preventDefault();
195
+ var $link = $(this);
196
+ $.ajax({
197
+ url : ajaxurl,
198
+ data : {
199
+ action: 'learnpress_ignore_setting_up'
200
+ },
201
+ success: function () {
202
+ if( $link.attr('href') ){
203
+ window.location.href = $link.attr('href');
204
+ }else {
205
+ $('#lpr-setting-up').remove();
206
+ }
207
+ }
208
+ })
209
+ });
210
+ });
211
+
212
+ jQuery(document).ready(function ($){
213
+ var input = $('#_lpr_course_condition');
214
+ $('[name=_lpr_course_final]').change(function (){
215
+ if($('[value=yes]').is(':checked')){
216
+ input.prop('disabled', false);
217
+ } else {
218
+ input.prop('disabled', true);
219
+ }
220
+ })
221
+ });
222
+
223
+ jQuery(document).ready(function($){
224
+ $('#lpr-custom-time').submit(function(){
225
+ $.ajax({
226
+ url: ajaxurl,
227
+ data: $(this).serialize(),
228
+ success:function(response){
229
+ drawStudentsChart(response, config)
230
+ },
231
+ type: 'POST',
232
+ dataType: 'json'
233
+ })
234
+ return false;
235
+ })
236
+
237
+ return;
238
+ // admin notice install sample data
239
+
240
+
241
+ var $checked = null;
242
+ $checked = $('input[name="_lpr_course_enrolled_require"]').bind('click change', function () {
243
+
244
+ var payment_field = $('.lpr-course-payment-field').toggleClass('hide-if-js', !( $(this).val() != 'no' ));
245
+ if (payment_field.is(':visible')) {
246
+ $('input[name="_lpr_course_payment"]:checked', payment_field).trigger('change')
247
+ } else {
248
+ $('.lpr-course-price-field').addClass('hide-if-js');
249
+ }
250
+
251
+ });
252
+ $checked.filter(':checked').trigger('change');
253
+ if ($checked.length == 0) {
254
+ $('input[name="_lpr_course_enrolled_require"][value="yes"]').trigger('click');
255
+ }
256
+
257
+ $('input[name="_lpr_course_payment"]').bind('click change', function () {
258
+ $('.lpr-course-price-field').toggleClass('hide-if-js', !( $(this).val() != 'free' ) || ( $('input[name="_lpr_course_enrolled_require"]:checked').val() == 'no' ));
259
+ }).filter(':checked').trigger('change');
260
+
261
+ $checked.closest('.rwmb-field').removeClass('hide-if-js');
262
+
263
+ });
264
+
265
+ //javascript hook functions
266
+ var lprHook = {
267
+ hooks : {action: {}, filter: {}},
268
+ addAction : function (action, callable, priority, tag) {
269
+ lprHook.addHook('action', action, callable, priority, tag);
270
+ },
271
+ addFilter : function (action, callable, priority, tag) {
272
+ lprHook.addHook('filter', action, callable, priority, tag);
273
+ },
274
+ doAction : function (action) {
275
+ lprHook.doHook('action', action, arguments);
276
+ },
277
+ applyFilters: function (action) {
278
+ return lprHook.doHook('filter', action, arguments);
279
+ },
280
+ removeAction: function (action, tag) {
281
+ lprHook.removeHook('action', action, tag);
282
+ },
283
+ removeFilter: function (action, priority, tag) {
284
+ lprHook.removeHook('filter', action, priority, tag);
285
+ },
286
+ addHook : function (hookType, action, callable, priority, tag) {
287
+ if (undefined == lprHook.hooks[hookType][action]) {
288
+ lprHook.hooks[hookType][action] = [];
289
+ }
290
+ var hooks = lprHook.hooks[hookType][action];
291
+ if (undefined == tag) {
292
+ tag = action + '_' + hooks.length;
293
+ }
294
+ lprHook.hooks[hookType][action].push({tag: tag, callable: callable, priority: priority});
295
+ },
296
+ doHook : function (hookType, action, args) {
297
+
298
+ // splice args from object into array and remove first index which is the hook name
299
+ args = Array.prototype.slice.call(args, 1);
300
+
301
+ if (undefined != lprHook.hooks[hookType][action]) {
302
+ var hooks = lprHook.hooks[hookType][action], hook;
303
+ //sort by priority
304
+ hooks.sort(function (a, b) {
305
+ return a["priority"] - b["priority"]
306
+ });
307
+ for (var i = 0; i < hooks.length; i++) {
308
+ hook = hooks[i].callable;
309
+ if (typeof hook != 'function')
310
+ hook = window[hook];
311
+ if ('action' == hookType) {
312
+ hook.apply(null, args);
313
+ } else {
314
+ args[0] = hook.apply(null, args);
315
+ }
316
+ }
317
+ }
318
+ if ('filter' == hookType) {
319
+ return args[0];
320
+ }
321
+ },
322
+ removeHook : function (hookType, action, priority, tag) {
323
+ if (undefined != lprHook.hooks[hookType][action]) {
324
+ var hooks = lprHook.hooks[hookType][action];
325
+ for (var i = hooks.length - 1; i >= 0; i--) {
326
+ if ((undefined == tag || tag == hooks[i].tag) && (undefined == priority || priority == hooks[i].priority)) {
327
+ hooks.splice(i, 1);
328
+ }
329
+ }
330
+ }
331
+ }
332
+ };
333
+ //end of javascript hook functions
334
+
335
+ function _lprAdminQuestionHTML($dom, type) {
336
+ switch (type) {
337
+ case 'true_or_false':
338
+ $dom.lprTrueOrFalseQuestion();
339
+ break;
340
+ case 'multi_choice':
341
+ $dom.lprMultiChoiceQuestion();
342
+ break;
343
+ case 'single_choice':
344
+ $dom.lprSingleChoiceQuestion();
345
+ break;
346
+ }
347
+ }
348
+ lprHook.addAction('lpr_admin_question_html', _lprAdminQuestionHTML);
349
+ lprHook.addAction('lpr_admin_quiz_question_html', _lprAdminQuestionHTML);
350
+
351
+ ;
352
+ (function ($) {
353
+ var $doc = $(document),
354
+ $body = $(document.body);
355
+ $.fn.scrollTo = function(options){
356
+ return this.each(function(){
357
+ options = $.extend({
358
+ delay: 0,
359
+ offset: 0,
360
+ speed: 'slow'
361
+ }, options || {});
362
+
363
+ $('body')
364
+ .fadeIn( 0 )
365
+ .delay( options.delay )
366
+ .animate({
367
+ scrollTop: $(this).offset().top - options.offset
368
+ }, options.speed);
369
+
370
+ return this;
371
+ })
372
+ }
373
+
374
+
375
+ $.lprShowBlock = function ($form) {
376
+ var $block = $("#lpr-block");
377
+
378
+ if (!$block.get(0)) {
379
+ $block = $('<div id="lpr-block" />').appendTo($body).hide();
380
+ $block.click($.lprHideBlock);
381
+
382
+
383
+ }
384
+ $block.show().data('form', $form);
385
+
386
+ return $block;
387
+ }
388
+ $.lprHideBlock = function () {
389
+ var $block = $("#lpr-block");
390
+ if (!$block.get(0)) return;
391
+ $block.hide();
392
+ if ($block.data('form')) $block.data('form').hide();
393
+ $block.data('form', 0);
394
+ return $block;
395
+ }
396
+
397
+ $.fn.lprFancyCheckbox = function (options) {
398
+ var defaults = {
399
+ newElementClass : 'tog',
400
+ activeElementClass: 'on'
401
+ };
402
+ var options = $.extend(defaults, options);
403
+ this.each(function () {
404
+ //Assign the current checkbox to obj
405
+ var obj = $(this);
406
+ //Create new span element to be styled
407
+ var newObj = $('<div/>', {
408
+ 'id' : obj.attr('id'),
409
+ 'class': 'lpr-fancy-checkbox ' + options.newElementClass
410
+ }).insertAfter(this).data('input', this);
411
+ //Make sure pre-checked boxes are rendered as checked
412
+ if (obj.is(':checked')) {
413
+ newObj.addClass(options.activeElementClass);
414
+ }
415
+ obj.hide(); //Hide original checkbox
416
+ //Labels can be painful, let's fix that
417
+ if ($('[for=' + obj.attr('id') + ']').length) {
418
+
419
+ var label = $('[for=' + obj.attr('id') + ']');
420
+ label.click(function () {
421
+ newObj.trigger('click'); //Force the label to fire our element
422
+ return false;
423
+ });
424
+ }
425
+ //Attach a click handler
426
+ newObj.click(function () {
427
+ //Assign current clicked object
428
+ var obj = $(this);
429
+ //Check the current state of the checkbox
430
+ if (obj.hasClass(options.activeElementClass)) {
431
+ obj.removeClass(options.activeElementClass);
432
+ $(obj.data('input')).attr('checked', false).trigger('change');
433
+ } else {
434
+ obj.addClass(options.activeElementClass);
435
+ $(obj.data('input')).attr('checked', true).trigger('change');
436
+ }
437
+ //Kill the click function
438
+ return false;
439
+ });
440
+ });
441
+ }
442
+
443
+ $doc.ready(function () {
444
+ $body = $(document.body);
445
+
446
+ $('input.lpr-fancy-checkbox')
447
+ .on('change', function () {
448
+ var $chk = $(this),
449
+ state = $(this).data('state'),
450
+ checked = $(this).is(':checked');
451
+ $.ajax({
452
+ url: ajaxurl,
453
+ data: {
454
+ url: $chk.attr('data-url'),
455
+ plugin: $chk.attr('data-plugin'),
456
+ t: checked ? 'activate' : 'deactivate',
457
+ action: 'learnpress_update_add_on_status'
458
+ },
459
+ success: function(response){
460
+
461
+ $chk.attr('data-url', response.url)
462
+ .attr('state', response.status)
463
+
464
+ }
465
+ })
466
+ })
467
+ .lprFancyCheckbox();
468
+ $('#learn-press-add-ons-wrap').on('click', '.plugin-action-buttons a', function(evt){
469
+ evt.preventDefault();
470
+ var $link = $(this), action = $link.data('action');
471
+ if( ! action ) return;
472
+ $link.addClass('disabled spinner');
473
+ $.ajax({
474
+ url: $link.attr('href'),
475
+ dataType: 'html',
476
+ success: function(response){
477
+ if(action == 'install-now' || action == 'update-now' || action == 'active-now'){
478
+ if( $link.hasClass('thimpress') ){
479
+ response = LearnPress.parseJSON( response );
480
+ $link.removeClass( 'spinner' );
481
+ if( response.status == 'activate' ){
482
+ $link.addClass('disabled').html(response.status_text).removeAttr('href').removeAttr('data-action');
483
+ $('.addon-status', $link.closest('.action-links')).html(response.status_text).addClass('enabled');
484
+ }else{
485
+ $link.removeClass('disabled');
486
+ }
487
+ }
488
+ }
489
+ }
490
+ })
491
+ });
492
+
493
+ $('#learn-press-bundle-activate-add-ons').click(function(){
494
+ var $button = $(this);
495
+ $button.addClass('spinner').attr('disabled', 'disabled');
496
+ $.ajax({
497
+ url: ajaxurl,
498
+ data: {
499
+ action: 'learnpress_bundle_activate_add_ons'
500
+ },
501
+ dataType: 'html',
502
+ success: function(response){
503
+ response = LearnPress.parseJSON( response );
504
+ if( response.addons ){
505
+ for(var slug in response.addons ){
506
+ var plugin = response.addons[slug];
507
+ if( 'activate' == plugin.status ){
508
+ $('.plugin-card-'+slug).find('.install-now.thimpress, .active-now.thimpress').addClass('disabled').attr('href', '').html(plugin.status_text);
509
+ }else{
510
+
511
+ }
512
+ }
513
+ }
514
+ $button.removeClass('spinner').removeAttr('disabled');
515
+ }
516
+ })
517
+ });
518
+ (function() {
519
+ var boxes = $('.post-type-lpr_quiz, .post-type-lpr_course, .post-type-lpr_lesson, .post-type-lpr_question').find('#postbox-container-1');
520
+ if( !boxes.length ) return;
521
+ var $win = $(window),
522
+ $container = $('#poststuff'),
523
+ currentOffset = 0;
524
+ $(window).scroll(function () {
525
+ var container_height = $container.height(),
526
+ dir = $win.scrollTop() > currentOffset ? 'down' : 'up';
527
+ currentOffset = $win.scrollTop();
528
+
529
+ boxes.each(function(){
530
+ var $box = $(this),
531
+ box_height = $box.height(),
532
+ container_height = $container.height(),
533
+ max_scroll = container_height - box_height - 10,
534
+ scroll_top = $win.scrollTop(),
535
+ offset = ( scroll_top - $container.offset().top - $box.height() ) + $win.height();
536
+ if( max_scroll <= 0 ) return;
537
+ if( box_height < $win.height() ) offset = scroll_top - $container.offset().top + 50;
538
+ else{
539
+ if( offset >= max_scroll ) offset = max_scroll;
540
+ }
541
+ $box.css("margin-top", Math.max( 0, offset ) );
542
+ })
543
+ })
544
+ })();
545
+
546
+ $('.lpr-dropdown-pages').each( function(){
547
+ var $select = $(this),
548
+ $form = $select.siblings('.lpr-quick-add-page-inline'),
549
+ $actions = $select.siblings('.lpr-quick-actions-inline');
550
+ function add_page_to_all_dropdowns( response ){
551
+ var pos = $.inArray( response.page.ID.toString() + "", response.ordering );
552
+ $('.lpr-dropdown-pages').each(function() {
553
+ var $select = $(this),
554
+ $new_option = $('<option value="'+response.page.ID+'">'+response.page.post_title+'</option>')
555
+ if (pos == 0) {
556
+ $('option', $select).each(function () {
557
+ if (parseInt($(this).val())) {
558
+ $new_option.insertBefore($(this));
559
+ return false;
560
+ }
561
+ })
562
+ } else if (pos == response.ordering.length - 1) {
563
+ $select.append($new_option);
564
+ } else {
565
+ $new_option.insertAfter($('option[value="' + response.ordering[pos - 1] + '"]', $select));
566
+ }
567
+ });
568
+ }
569
+ $select.click(function(){
570
+ $select.data('value', this.value)
571
+ }).change(function(){
572
+ var option = $(this).val();
573
+ $actions.addClass('hide-if-js');
574
+ if( option == 'add_new_page'){
575
+ $form.removeClass('hide-if-js').find('input').val('').focus();
576
+ $(this).attr('disabled', true);
577
+ }else if( ! isNaN(option) ){
578
+ $.ajax({
579
+ url: ajaxurl,
580
+ data: {
581
+ action: 'learnpress_get_page_permalink',
582
+ page_id: option
583
+ },
584
+ success: function(response) {
585
+ if( response ) {
586
+ $actions.html(response).removeClass('hide-if-js')
587
+ }
588
+ },
589
+ dataType: 'html'
590
+ })
591
+ }
592
+ })//.trigger('change');
593
+ $form.on('keypress', 'input', function(evt){
594
+ if( evt.keyCode == 13 ){
595
+ evt.preventDefault();
596
+ $(this).siblings('button').trigger('click');
597
+ }
598
+ }).on('keydown', 'input', function(evt){
599
+ if( evt.keyCode == 27 ){
600
+ $(this).siblings('a').trigger('click');
601
+ }
602
+ });
603
+ $('button', $form).click(function(){
604
+ var $input = $(this).siblings('input');
605
+ if( ! $input.val().length ){
606
+ $input.focus();
607
+ return;
608
+ }
609
+ $form.block_ui();
610
+ $.ajax(ajaxurl, {
611
+ data: {
612
+ action: 'learnpress_create_page',
613
+ title: $input.val()
614
+ },
615
+ success:function( response ){
616
+ if(response.page){
617
+ add_page_to_all_dropdowns( response );
618
+ $select.removeAttr('disabled').val(response.page.ID);
619
+ $form.addClass('hide-if-js');
620
+ $actions.html(response.html).removeClass('hide-if-js');
621
+ }else{
622
+ alert(response.error);
623
+ $select.removeAttr('disabled').val( $select.data('value'));
624
+ if( $select.data('value') ) $actions.removeClass('hide-if-js');
625
+ }
626
+ $form.unblock_ui();
627
+ },
628
+ dataType: 'json',
629
+ type: 'post'
630
+ })
631
+ });
632
+ $('a', $form).click(function(evt){
633
+ evt.preventDefault();
634
+ $(this).parent().addClass('hide-if-js');
635
+ $select.removeAttr('disabled').val( $select.data('value') );
636
+ if( $select.data('value') ) $actions.removeClass('hide-if-js');
637
+ })
638
+ })
639
+
640
+ })
641
+
642
+ $.extend( LearnPress, {
643
+ parse_json: function(response){
644
+ if( typeof reposnse == 'object' ) return response;
645
+ try {
646
+ var m = response.match(/<!-- LP_AJAX_START -->(.*)<!-- LP_AJAX_END -->/)
647
+
648
+ if (m && m[1]) {
649
+ response = JSON.parse(m[1])
650
+ } else {
651
+ response = JSON.parse(response)
652
+ }
653
+ }catch(e){ response = false }
654
+ return response;
655
+ },
656
+ block_page: function(args){
657
+ var block_page = $( '#lpr-page-block' );
658
+ if( block_page.length == 0 ){
659
+ block_page = $( wp.template( 'page-block' )()).appendTo($body);
660
+ block_page.click($.proxy( function(){ this.unblock_page() }, this ));
661
+ }
662
+ args = $.extend( {
663
+ on_close: function () {
664
+
665
+ },
666
+ backgroundColor: undefined,
667
+ opacity: undefined
668
+ }, args || {} );
669
+ $.each(['backgroundColor', 'opacity'], function(){
670
+ block_page.css( this, args[this] );
671
+ })
672
+ block_page.data('args', args).show();
673
+ },
674
+ unblock_page: function(args){
675
+ args = $.extend( {
676
+
677
+ }, args || {} );
678
+ var block_page = $( '#lpr-page-block'),
679
+ stored_args = block_page.data('args');
680
+ block_page.hide();
681
+
682
+ if( stored_args ){
683
+ $.each(['backgroundColor', 'opacity'], function(){
684
+ block_page.css( this, '' );
685
+ });
686
+ $.isFunction(stored_args.on_close) && stored_args.on_close.call(block_page);
687
+ }
688
+ },
689
+ showLessonQuiz: function( pos, ed ){
690
+ var textNode = $(ed.selection.getNode()),
691
+ iframe = $('#content_ifr'),
692
+ form = $('#form-quick-add-lesson-link'),
693
+ offset = textNode.offset(),
694
+ iframe_offset = iframe.offset(),
695
+ range = ed.selection.getRng();
696
+ ed.execCommand('mceInsertContent', false,'<span id="learn_press_book_mark"></span>');
697
+ offset = $( '#learn_press_book_mark', textNode).position();
698
+ $( '#learn_press_book_mark', textNode).remove();
699
+ ed.selection.setRng(range);
700
+ if( form.length == 0 ){
701
+ form = $( wp.template('form-quick-add-lesson-link')()).css({zIndex: 99999}).appendTo($body);
702
+ $('select', form).select2({
703
+ width: 300,
704
+ containerCssClass: 'lpr-container-dropdown',
705
+ dropdownCssClass: 'lpr-select-dropdown'
706
+ })
707
+ .on('select2-close', function(){
708
+ $('#form-quick-add-lesson-link').hide();
709
+ tinyMCE.activeEditor.focus();
710
+ })
711
+ .on('select2-selecting', function(e){
712
+ var lesson_id = e.val;
713
+ if( !lesson_id ) return;
714
+ var ed = tinymce.activeEditor,
715
+ shortcode = '[quick_lesson_link id="'+lesson_id + '"]',
716
+ range = ed.selection.getRng();
717
+ range.startContainer.nodeValue = range.startContainer.nodeValue.replace(/@l/, '');
718
+ ed.selection.setCursorLocation( range.startContainer, range.startContainer.nodeValue.length )
719
+ ed.selection.setContent(shortcode)
720
+ $('#form-quick-add-lesson-link').hide();
721
+ });
722
+ }
723
+ form.css({
724
+ top: iframe_offset.top + offset.top,
725
+ left: iframe_offset.left + offset.left + 40
726
+ }).show();
727
+ $('select', form).select2('open');
728
+ }
729
+ });
730
+
731
+ $(document).ready(function(){
732
+ var $add_new_h2 = $('body.post-type-lpr_course').find('.page-title-action, .add-new-h2'),
733
+ $reset_h2 = $('<a href="" class="page-title-action add-new-h2">Reset</a>');
734
+
735
+ $reset_h2
736
+ .insertAfter($add_new_h2)
737
+ .click(function(evt){
738
+ evt.preventDefault();
739
+ var link = window.location.href.replace(/reset-course-data=([0-9]+)/, '');
740
+ link += '&reset-course-data=' + $('input#post_ID').val();
741
+ window.location.href = link;
742
+ });
743
+ })
744
+ })(jQuery)
745
+
746
+ ;(function() {
747
+ if( typeof tinymce == 'undefined' ){
748
+ return;
749
+ }
750
+ tinymce.PluginManager.add('embed', function( editor )
751
+ {
752
+ editor.addButton('embed', {
753
+ type: 'button',
754
+ text: 'Embed',
755
+ onclick: function(event) {
756
+ editor.windowManager.open({
757
+ title: 'Your video embed link',
758
+ body: [
759
+ {type: 'textbox', name: 'link', label: 'Your video embed link'}
760
+ ],
761
+ onsubmit: function(e) {
762
+ // Insert content when the window form is submitted
763
+ editor.insertContent('[embed_video link=' + e.data.link + ']');
764
+ }
765
+ });
766
+ }
767
+ });
768
+ });
769
+ })();
770
+
771
+ /* pointer.js */
772
+ jQuery(document).ready( function($) {
773
+ if( typeof lpPointer == 'undefined' ){
774
+ return;
775
+ }
776
+ learn_press_open_pointer(0);
777
+ function learn_press_open_pointer(i) {
778
+ pointer = lpPointer.pointers[i];
779
+ options = $.extend( pointer.options, {
780
+ close: function() {
781
+ $.post( ajaxurl, {
782
+ pointer: pointer.pointer_id,
783
+ action: 'dismiss-wp-pointer'
784
+ });
785
+ }
786
+ });
787
+
788
+ $(pointer.target).pointer( options ).pointer('open');
789
+ }
790
+ });
791
+
792
+ /* ui.js */
793
+ (function( $ ){
794
+ $.fn.extend({
795
+ iosCheckbox: function ( ) {
796
+ $(this).each(function (){
797
+ var $checkbox = $(this),
798
+ $ui = $("<div>",{class: 'ios-ui-select'}).append($("<div>",{class: 'inner'}));
799
+ if ($checkbox.is(":checked")){
800
+ $ui.addClass("checked");
801
+ }
802
+ $checkbox.after($ui)
803
+ .on('update', function(){
804
+ $ui.trigger('update')
805
+ })//.hide().appendTo($ui);
806
+ $ui.on('click update', function (){
807
+ $ui.toggleClass("checked");
808
+ $checkbox.prop('checked', $ui.hasClass("checked")).trigger('change')
809
+ });
810
+ });
811
+ }
812
+ });
813
+
814
+ $(document).ready(function(){
815
+ $('.learn-press-checkbox').iosCheckbox();
816
+
817
+ if ( typeof Switchery !== 'undefined' ) {
818
+ var elems = Array.prototype.slice.call( document.querySelectorAll('.rwmb-learnpress-switchbutton') );
819
+
820
+ elems.forEach(function(html) {
821
+ var switchery = new Switchery( html, { size: 'small' } );
822
+ });
823
+ }
824
+ });
825
+ })(jQuery);
assets/js/admin/meta-box-course.js ADDED
@@ -0,0 +1,1397 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;
2
+ (function ($) {
3
+ if (typeof LearnPress == 'undefined') {
4
+ LearnPress = {};
5
+ }
6
+ $(document).ready(function () {
7
+ if (typeof Backbone == 'undefined') return;
8
+ var LP_Curriculum_Model = window.LP_Curriculum_Model = Backbone.Model.extend({
9
+ defaults : {},
10
+ data : null,
11
+ view : false,
12
+ urlRoot : '',
13
+ initialize: function () {
14
+ },
15
+ removeItem: function (item) {
16
+ var items = this.get('selectedItems');
17
+ items = _.without(items, item);
18
+ this.set('selectedItems', items);
19
+ },
20
+ addItem : function (id) {
21
+ var items = this.get('selectedItems');
22
+ items.push(id);
23
+ this.set('selectedItems', items);
24
+ }
25
+ });
26
+
27
+ var LP_Curriculum_View = window.LP_Curriculum_View = Backbone.View.extend({
28
+ model : {},
29
+ events : {
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',
37
+ 'click .lp-add-buttons button' : 'sectionActionHandler',
38
+ 'click .lp-item-new .handle' : 'toggleItemType',
39
+ 'click .lp-button-add-item' : '_addNewItem',
40
+ 'click .item-bulk-actions button' : 'sectionBulkActions',
41
+ 'change .item-checkbox input' : 'toggleButtonBulkActions',
42
+ 'change .lp-check-items' : 'toggleButtonBulkActions',
43
+ 'click .lp-section-actions.lp-button-actions' : '_sectionActionHandler',
44
+ 'click .lp-section-item .section-item-icon span': '_changeItemType'
45
+ },
46
+ removeSectionIds : [],
47
+ removeItemIds : [],
48
+ el : '#lp-course-curriculum',
49
+ initialize : function (model) {
50
+ if (this.$el.length == 0) return;
51
+ this.model = model;
52
+ this.model.view = this;
53
+ this.listenTo(this.model, 'change', this.render);
54
+ this.render();
55
+ _.bindAll(this, 'render', 'searchItem', 'addItemsToSection', 'addItemToSection', 'addNewItem', 'toggleAddItemButtonState', 'getSelectedItems', '_sectionActionHandler', '_changeItemType');
56
+ this.initPage();
57
+ LearnPress.Hook.addAction('learn_press_message_box_before_resize', this.resetModalSearch)
58
+ LearnPress.Hook.addAction('learn_press_message_box_resize', this.updateModalSearch);
59
+ $(document).on('learn_press_modal_search_items_response', this.addItemsToSection);
60
+ LearnPress.Hook.addFilter('learn_press_modal_search_items_exclude', this.getSelectedItems);
61
+ },
62
+ _changeItemType : function (e) {
63
+ var $icon = $(e.target),
64
+ $row = $icon.closest('tr'),
65
+ type = $icon.attr('data-type'),
66
+ item_id = $row.attr('data-item_id');
67
+ if (item_id) {
68
+ alert('You can not change an existing item to other type')
69
+ } else {
70
+ $icon.addClass('item-selected').siblings().removeClass('item-selected');
71
+ $row.attr('data-type', type);
72
+ $row.find('input.lp-item-type').val(type);
73
+ }
74
+ },
75
+ updateModalSearch : function (height, $app) {
76
+ $('.lp-modal-search ul').css('height', height - 120).css('overflow', 'auto');
77
+ },
78
+ resetModalSearch : function ($app) {
79
+ $('.lp-modal-search ul').css('height', '').css('overflow', '')
80
+ },
81
+ initPage : function () {
82
+ var that = this;
83
+ this.$form = $('#post');
84
+ this.$form.on('submit', $.proxy(function (e) {
85
+ if ($(e.target).hasClass('no-submit')) {
86
+ return false;
87
+ }
88
+ return this.onSave()
89
+ }, this));
90
+ $('input[name="_lp_course_result"]').bind('click change', function () {
91
+ return;
92
+ if ($(this).val() == 'yes') {
93
+ $(this).closest('.rwmb-field').next().removeClass('hide-if-js');
94
+ } else {
95
+ $(this).closest('.rwmb-field').next().hide();
96
+ }
97
+ }).filter(":checked").trigger('change');
98
+
99
+ ///////////
100
+ var $chkPayment = $( 'input[name="_lp_payment"]').on('change', function(){
101
+ var toggle = this.value != 'yes';
102
+ $('.lp-course-price-field').toggleClass('hide-if-js', toggle).attr('xxx', Math.random());
103
+ $('.lp-course-required-enroll').toggleClass('hide-if-js', !toggle);
104
+ })
105
+ $chkPayment.filter(':checked').trigger('change');
106
+
107
+ if( $('input[name="_lp_course_result"]:checked').length == 0 ){
108
+ $('input[name="_lp_course_result"]').filter(function(){return this.value == 'evaluate_lesson';}).prop('checked', true)
109
+ }
110
+ /*
111
+ ;$('input[name="_lp_required_enroll"]').bind('click change', function () {
112
+ var payment_field = $('.lp-course-payment-field').toggleClass('hide-if-js', !( $(this).val() != 'no' ));
113
+ if (payment_field.is(':visible')) {
114
+ $('input[name="_lp_payment"]:checked', payment_field).trigger('change')
115
+ } else {
116
+ $('.lpr-course-price-field').addClass('hide-if-js');
117
+ }
118
+
119
+ });
120
+ $checked.filter(':checked').trigger('change');
121
+ if ($checked.length == 0) {
122
+ $('input[name="_lp_required_enroll"][value="yes"]').trigger('click');
123
+ }
124
+
125
+ $('input[name="_lp_payment"]').bind('click change', function () {
126
+ $('.lp-course-price-field').toggleClass('hide-if-js', !( $(this).val() != 'no' ) || ( $('input[name="_lp_required_enroll"]:checked').val() == 'no' ));
127
+ }).filter(':checked').trigger('change');
128
+
129
+ $checked.closest('.rwmb-field').removeClass('hide-if-js');*/
130
+ ////////////////
131
+
132
+ $(document).on('mouseover', '.lp-modal-search li', function () {
133
+ $(this).addClass('highlighting').siblings().removeClass('highlighting');
134
+ }).on('click', '.lp-modal-search li', function (e) {
135
+ e.keyCode = 13;
136
+ e.target = $(this).closest('.lp-section-item').find('.lp-item-name').get(0)
137
+ that.searchQuizFormKeyEvents(e);
138
+ });
139
+ this.$el
140
+ .on('focus', '.lp-item-name', function () {
141
+ that.$('.lp-section-item').removeClass('hover');
142
+ $(this).parent().addClass('hover')
143
+ })
144
+ .on('blur', '.lp-item-name', function () {
145
+ var $e = $(this);
146
+ setTimeout(function () {
147
+ var $item = $e.closest('.lp-section-item');
148
+ if (that.isShowing != 'searchQuizForm') {
149
+ $item.removeClass('hover');
150
+ }
151
+ if (($e.val() + '').length == 0) {
152
+ if ($item.hasClass('lp-item-new')) {
153
+ ///$item.remove();
154
+ } else {
155
+ $e.val($item.attr('data-text'));
156
+ }
157
+ }
158
+ }, 500);
159
+ });
160
+ this.$('.lp-curriculum-sections').sortable({
161
+ axis : 'y',
162
+ items : 'li:not(.lp-empty-section)',
163
+ handle: '.lp-section-icon',
164
+ start : function (e, ui) {
165
+ $('.lp-curriculum-section-content').css('display', 'none');
166
+ $(ui.item).addClass('lp-sorting');
167
+ },
168
+ stop : function (e, ui) {
169
+ $('.lp-curriculum-section-content').css('display', '');
170
+ $(ui.item).removeClass('lp-sorting');
171
+ }
172
+ });
173
+ this.$('.lp-curriculum-sections .lp-section-items').sortable({
174
+ axis : 'y',
175
+ items : 'li:not(.lp-item-empty)',
176
+ handle : '.lp-sort-item',
177
+ connectWith: '.lp-section-items'
178
+ });
179
+ if (this.$('.lp-curriculum-section-content:visible').length) {
180
+
181
+ }
182
+
183
+ $('#postbox-container-2').prepend($('#course_tabs'));
184
+ $('#course_tabs #course-tabs-h3 a').click(function (e) {
185
+ e.preventDefault();
186
+ var id = $(this).attr('href'),
187
+ $box = $(id);
188
+ $(window).scrollTop($box.offset().top - 120);
189
+ });
190
+ $('<div id="course_tabs_placeholder" />').insertAfter($('#course_tabs'));
191
+
192
+ $(document)
193
+ .on('keyup', '.lp-modal-search input[name="lp-item-name"]', this.searchItem)
194
+ .on('click change', '.lp-modal-search input[type="checkbox"]', this.toggleAddItemButtonState)
195
+ .on('click', '.lp-modal-search .lp-add-item', this.addItemsToSection)
196
+ .on('click', '.lp-modal-search .lp-add-new-item', this.addNewItem)
197
+ .on('change', 'input[name="learn_press_submit_course_notice_reviewer"]', this.updatePublishAction);
198
+
199
+ $('input[name="learn_press_submit_course_notice_reviewer"]').trigger('change');
200
+ $(window).scroll(function () {
201
+ return;
202
+ var $holder = $('#course_tabs_placeholder'),
203
+ $tabs = $('#course_tabs'),
204
+ top = $holder.offset().top;
205
+ if ($(window).scrollTop() > top) {
206
+ $tabs.css('width', $tabs.width()).addClass('fixed');
207
+ } else {
208
+ $tabs.css('width', '').removeClass('fixed');
209
+ }
210
+ });
211
+ },
212
+ updatePublishAction : function (e) {
213
+ if (e.target.checked) {
214
+ $('#publish').val(meta_box_course_localize.submit_course_review);
215
+ } else {
216
+ $('#publish').val(meta_box_course_localize.save_course);
217
+ }
218
+ },
219
+ toggleButtonBulkActions : function (e) {
220
+ var $checkbox = $(e.target),
221
+ $checkAll = $checkbox,
222
+ $all = $checkbox.closest('.curriculum-section-content').find('.lp-section-item:not(.lp-item-empty) .item-checkbox input'),
223
+ len;
224
+ if ($checkbox.attr('data-action') == 'check-all') {
225
+ $all.prop('checked', $checkbox.is(':checked')).trigger('change')
226
+ return;
227
+ } else {
228
+ $checkAll = $checkbox.closest('.curriculum-section-content').find('input.lp-check-all-items')
229
+ }
230
+ (len = $all.filter(function () {
231
+ return this.checked
232
+ }).length)
233
+ ? (
234
+ $checkbox.closest('.curriculum-section-content')
235
+ .find('.item-bulk-actions button')
236
+ .removeAttr('disabled')
237
+ .removeClass('hide-if-js')
238
+ .map(function () {
239
+ var $b = $(this);
240
+ $b.attr('data-action') == 'cancel' ? $b.removeClass('hide-if-js') : $b.html($b.attr('data-title') + ' (+' + len + ')').show()
241
+ })
242
+ )
243
+ : $checkbox.closest('.curriculum-section-content')
244
+ .find('.item-bulk-actions button')
245
+ .hide()
246
+ .map(function () {
247
+ var $b = $(this);
248
+ $b.attr('data-action') == 'cancel' ? $b.hide() : $b.html($b.attr('data-title')).hide()
249
+ });
250
+ $checkbox.closest('.lp-section-item').toggleClass('remove', e.target.checked);
251
+ if (len == $all.length) {
252
+ $checkAll.attr('checked', 'checked')
253
+ } else if (len == 0) {
254
+ $checkAll.removeAttr('checked')
255
+ }
256
+ },
257
+ sectionBulkActions : function (e) {
258
+ var $button = $(e.target),
259
+ $all = $button.closest('.item-bulk-actions').siblings('.curriculum-section-items').find('.lp-section-item'),
260
+ action = $button.attr('data-action');
261
+
262
+ switch (action) {
263
+ case 'delete':
264
+ case 'delete-forever':
265
+ var $items = $all.filter(function () {
266
+ return $(this).find('.item-checkbox input').is(':checked')
267
+ });
268
+ this.removeItem($items, true, function () {
269
+ $button.closest('.item-bulk-actions').find('button').map(function () {
270
+ var $b = $(this).html($(this).attr('data-title'));
271
+ ($.inArray($b.attr('data-action'), ['cancel', 'delete']) != -1) && $b.hide();
272
+ });
273
+ }, $button);
274
+ break;
275
+ case 'cancel':
276
+ $all.filter(function () {
277
+ return $(this).find('.item-checkbox input').removeAttr('checked').trigger('change');
278
+ })
279
+ /*.first()
280
+ .find('.item-checkbox input')
281
+ .trigger('change');*/
282
+ }
283
+ },
284
+ toggleItemType : function (e) {
285
+ var $item = $(e.target).closest('.lp-section-item'),
286
+ from = $item.attr('data-type'),
287
+ to = null;
288
+ if ($item.attr('data-item_id')) {
289
+ return;
290
+ }
291
+ if ($item.hasClass('lp-item-lp_lesson')) {
292
+ to = 'lp_quiz';
293
+ $item
294
+ .removeClass('lp-item-lp_lesson')
295
+ .addClass('lp-item-lp_quiz')
296
+ .attr('data-type', to)
297
+ .find('.lp-item-type').val(to);
298
+ } else {
299
+ to = 'lp_lesson';
300
+ $item
301
+ .removeClass('lp-item-lp_quiz')
302
+ .addClass('lp-item-lp_lesson')
303
+ .attr('data-type', to)
304
+ .find('.lp-item-type', to);
305
+ }
306
+ LearnPress.Hook.doAction('learn_press_change_section_item_type', from, to);
307
+ },
308
+ getPrevInput : function ($input) {
309
+ var $inputs = this.$('input.no-submit:visible'),
310
+ position = $inputs.index($input);
311
+ $prev = position == 0 ? $inputs.eq($inputs.length - 1) : $inputs.eq(position - 1);
312
+ return $prev;
313
+ },
314
+ getNextInput : function ($input) {
315
+ var $inputs = this.$('input.no-submit:visible'),
316
+ position = $inputs.index($input);
317
+ $next = position >= $inputs.length - 1 ? $inputs.eq(0) : $inputs.eq(position + 1);
318
+ return $next;
319
+ },
320
+ preventSubmit : function (e) {
321
+ var $input = $(e.target);
322
+ if ($input.hasClass('no-submit')) {
323
+ if (($input.val() + '').length >= 2) {
324
+ $input.closest('.lp-item-empty').removeClass('lp-item-empty');
325
+ $input.closest('.lp-empty-section').removeClass('lp-empty-section');
326
+ } else {
327
+ $input.closest('.lp-item-empty').addClass('lp-item-empty');
328
+ $input.closest('.lp-empty-section').addClass('lp-empty-section');
329
+ }
330
+ if (e.keyCode == 13) {
331
+ return false;
332
+ }
333
+ }
334
+ },
335
+ _addNewItem : function (e) {
336
+ e.preventDefault();
337
+ var that = this,
338
+ $target = $(e.target),
339
+ $section = $target.closest('.curriculum-section'),
340
+ $input = $section.find('input[name="lp-new-item-name"]'),
341
+ type = null;
342
+ if ($target.is('a')) {
343
+ type = $target.attr('data-type');
344
+ $target = $target.closest('.lp-button-add-item');
345
+ } else {
346
+ if (!$target.is('.lp-button-add-item')) {
347
+ $target = $target.closest('.lp-button-add-item');
348
+ }
349
+ type = $target.find('ul > li > a:first').attr('data-type');
350
+ }
351
+ if ($target.hasClass('disabled')) {
352
+ return;
353
+ }
354
+ if (($input.val() + '').length == 0) {
355
+ alert('Please enter item name');
356
+ $input.focus();
357
+ return;
358
+ }
359
+ $.ajax({
360
+ url : LearnPress_Settings.ajax,
361
+ data : {
362
+ action: 'learnpress_add_new_item',
363
+ name : $input.val(),
364
+ type : type
365
+ },
366
+ type : 'post',
367
+ dataType: 'html',
368
+ success : function (response) {
369
+ var json = LearnPress.parseJSON(response);
370
+ if (json.post && json.post.ID) {
371
+ $item = that.createItem({
372
+ id : json.post.ID,
373
+ type : json.post.post_type,
374
+ text : json.post.post_title,
375
+ edit_link: json.post.edit_link.replace('&amp;', '&')
376
+ });
377
+ if ($item) {
378
+ that.addItemToSection($item, $section);
379
+ }
380
+ $item.removeClass('lp-item-empty');
381
+ $input.val('').focus().trigger('keyup');
382
+ }
383
+ }
384
+ });
385
+ },
386
+ onEnterInput : function (e) {
387
+ var $input = $(e.target),
388
+ $item = $input.closest('.lp-section-item'),
389
+ $section = $item.length ? $item.closest('.curriculum-section') : $input.closest('.curriculum-section'),
390
+ value = $input.val(),
391
+ textLen = value.length,
392
+ type = $input.data('field');
393
+ if ($input.attr('name') == 'lp-new-item-name') {
394
+ LearnPress.log(textLen)
395
+ if (textLen > 0) {
396
+ $input.siblings('.lp-button-add-item').removeClass('disabled');
397
+ } else {
398
+ $input.siblings('.lp-button-add-item').addClass('disabled');
399
+ }
400
+ }
401
+ switch (e.keyCode) {
402
+ case 13:
403
+ if ($input.attr('name') == 'lp-new-item-name') {
404
+ $input.siblings('.lp-button-add-item').trigger('click')
405
+ return;
406
+ }
407
+ case 40:
408
+ var $next = this.getNextInput($input);
409
+ $next.focus();
410
+ break;
411
+ case 38:
412
+ var $prev = this.getPrevInput($input);
413
+ $prev.focus();
414
+ break;
415
+ case 8:
416
+ case 46:
417
+ if (type == 'section-name') {
418
+ if (textLen == 0 && $section.siblings().length) {
419
+ if ($input.attr('empty-value')) {
420
+ var $prev = this.getPrevInput($input);
421
+ $prev.focus();
422
+ $section.remove();
423
+ } else {
424
+ $input.attr('empty-value', 1);
425
+ }
426
+ } else {
427
+ $input.removeAttr('empty-value');
428
+ }
429
+ } else if (type == 'item-name') {
430
+ if (textLen == 0 && $item.siblings().length) {
431
+ if ($input.attr('empty-value')) {
432
+ var $prev = this.getPrevInput($input);
433
+ $prev.focus();
434
+ $item.remove();
435
+ } else {
436
+ $input.attr('empty-value', 1);
437
+ }
438
+ } else {
439
+ $input.removeAttr('empty-value');
440
+ }
441
+ }
442
+ break;
443
+ default:
444
+ if (type == 'section-name') {
445
+ var $nextSection = $section.next();
446
+
447
+ if ($nextSection.length == 0 && textLen >= 1) {
448
+ var $emptySection = this.createSection();
449
+
450
+ }
451
+ } else if (type == 'item-name') {
452
+ var $nextItem = $item.next();
453
+ if ($nextItem.length == 0 && textLen >= 1) {
454
+ var $emptyItem = this.createItem({type: 'lp_lesson'});
455
+ var $last = $section.find('.curriculum-section-items .lp-section-item:last');
456
+ $emptyItem.insertAfter($last);
457
+ }
458
+ }
459
+
460
+ }
461
+
462
+ },
463
+ getEmptySection : function () {
464
+ if (!this.$emptySection) {
465
+ this.createSection();
466
+ }
467
+ return this.$emptySection;
468
+ },
469
+ createSection : function () {
470
+ var tmpl = wp.template('curriculum-section');
471
+ this.$emptySection = $(tmpl({}));
472
+ this.$('.curriculum-sections').append(this.$emptySection);
473
+ return this.$emptySection;
474
+ },
475
+ createItem : function (args, $section) {
476
+ args = $.extend({
477
+ edit_link: 'post.php?post=' + args.id + '&action=edit'
478
+ }, args || {});
479
+ var tmpl = wp.template('section-item'),
480
+ $item = $(tmpl(args || {}));
481
+ $item = LearnPress.Hook.applyFilters('learn_press_create_new_item', $item, $section);
482
+ return $item;
483
+ },
484
+ needCreateNewSection : function () {
485
+
486
+ },
487
+ toggleSection : function (e) {
488
+ var $button = $(e.target),
489
+ $section = $button.closest('.lp-curriculum-section');
490
+ $section.find('.lp-curriculum-section-content').stop().slideToggle(function () {
491
+ if ($(this).is(':visible')) {
492
+ $(this).parent().addClass('open')
493
+ } else {
494
+ $(this).parent().removeClass('open')
495
+ }
496
+ });
497
+ },
498
+ toggleSections : function (e) {
499
+ e.preventDefault();
500
+ var $target = $(e.target);
501
+ if ($target.attr('data-action') == 'expand') {
502
+ this.$('.curriculum-section:not(.lp-empty-section) .lp-curriculum-section-content').slideDown();
503
+ } else {
504
+ this.$('.curriculum-section:not(.lp-empty-section) .lp-curriculum-section-content').slideUp();
505
+ }
506
+ },
507
+ getSelectedItems : function () {
508
+ return this.$('.lp-section-item[data-item_id]').map(function () {
509
+ return ($(this).attr('data-item_id'))
510
+ }).filter(function (i, c) {
511
+ return c > 0
512
+ }).get();
513
+ },
514
+ showFormItems : function (type, action, $button) {
515
+ var $form = LearnPress.ModalSearchItems({
516
+ template : 'tmpl-learn-press-search-items',
517
+ type : type,
518
+ section : $button.closest('.curriculum-section'),
519
+ context : 'course-items',
520
+ context_id: $('#post_ID').val(),
521
+ exclude : this.getSelectedItems()
522
+ });
523
+ LearnPress.MessageBox.show($form.$el);
524
+ $form.$el.find('header input').focus();
525
+ return;
526
+ if (type == 'lp_quiz') {
527
+ $form = $('#lp-modal-search-quiz');
528
+ if ($form.length == 0) {
529
+ $form = $(wp.template('lp-modal-search-quiz')());
530
+ }
531
+ } else {
532
+ $form = $('#lp-modal-search-lesson');
533
+ if ($form.length == 0) {
534
+ $form = $(wp.template('lp-modal-search-lesson')());
535
+ }
536
+ }
537
+
538
+ $form
539
+ .data('item_type', type)
540
+ .data('section', $button.closest('.curriculum-section')).removeClass('hide-if-js');
541
+ var selectedItems = this.getSelectedItems(),
542
+ unselectedItems = $form.find('li').filter(function () {
543
+ var id = parseInt($(this).data('id')),
544
+ selected = false;
545
+ if (id && $.inArray(id, selectedItems) == -1) {
546
+ $(this).removeClass('selected hide-if-js');
547
+ selected = false;
548
+ } else {
549
+ $(this).addClass('selected hide-if-js');
550
+ selected = true;
551
+ }
552
+ $(this).find('input[type="checkbox"]').removeAttr('checked');
553
+ return !selected;
554
+ });
555
+ LearnPress.MessageBox.show($form);
556
+ $form.find('[name="lp-item-name"]').focus();
557
+ $form.find('button.lp-add-item').html($form.find('button.lp-add-item').attr('data-text'));
558
+ if (unselectedItems.length) {
559
+ $form.find('.lp-search-no-results').hide();
560
+ } else {
561
+ $form.find('.lp-search-no-results').removeClass('hide-if-js');
562
+ }
563
+ LearnPress.Hook.doAction('learn_press_show_form_items', $form, action, $button, this);
564
+ },
565
+ sectionActionHandler : function (e) {
566
+ var that = this,
567
+ $button = $(e.target),
568
+ action = $button.data('action'),
569
+ type = $button.data('type'),
570
+ $form = null;
571
+ switch (action) {
572
+ case 'add-lp_quiz':
573
+ case 'add-lp_lesson':
574
+ this.showFormItems(type, action, $button);
575
+ break;
576
+ default:
577
+ LearnPress.Hook.doAction('learn_press_section_button_click', $button, action, this);
578
+ }
579
+ },
580
+ searchItem : function (e) {
581
+ var $input = $(e.target),
582
+ $form = $input.closest('.lp-modal-search'),
583
+ text = $input.val().replace(/\\q\?[\s]*/ig, ''),
584
+ $lis = $form.find('li:not(.lp-search-no-results):not(.selected)').addClass('hide-if-js'),
585
+ reg = new RegExp($.grep(text.split(/[\s]+/), function (a) {
586
+ return a.length
587
+ }).join('|'), "ig"),
588
+ found = 0;
589
+ LearnPress.log(text)
590
+ //if( text.length ) {
591
+ found = $lis.filter(function () {
592
+ var $el = $(this),
593
+ itemText = $el.data('text') + '',
594
+ ret = itemText.search(reg) >= 0;
595
+ if (ret) {
596
+ $el.find('.lp-item-text').html(itemText.replace(reg, "<i class=\"lp-highlight-color\">\$&</i>"));
597
+ } else {
598
+ $el.find('.lp-item-text').html(itemText);
599
+ }
600
+ return ret;
601
+ }).removeClass('hide-if-js').length;
602
+ /*}else{
603
+ found = $lis.removeClass('hide-if-js');
604
+ found.find('.lp-highlight-color').remove();
605
+ found = found.length
606
+ }*/
607
+ if (!found) {
608
+ $form.find('.lp-search-no-results').removeClass('hide-if-js');
609
+ } else {
610
+ $form.find('.lp-search-no-results').addClass('hide-if-js');
611
+ }
612
+ },
613
+ addItemsToSection : function (e, $view, $items) {
614
+ var that = this,
615
+ //$form = $(e.target).closest('.lp-modal-search'),
616
+ selected = $items, //$form.find('li:visible input:checked'),
617
+ $section = $view.options.section;
618
+ selected.each(function () {
619
+ var $li = $(this);//.closest('li').addClass('selected'),
620
+ args = $li.dataToJSON(),
621
+ $item = that.createItem(args, $section);
622
+ if ($item) {
623
+ that.addItemToSection($item, $section);
624
+ }
625
+ $li.remove();
626
+ });
627
+ /*
628
+ $.ajax({
629
+ url: LearnPress_Settings.ajax,
630
+ data: {
631
+ action: 'learn_press_add_item_to_section',
632
+ items: selected.map(function(){return $(this).dataToJSON()}).get(),
633
+ section: $section ? $section.attr('data-id') : 0
634
+ },
635
+ success: function(){
636
+
637
+ }
638
+ });*/
639
+
640
+ //$form.hide().appendTo($(document.body));
641
+ //LearnPress.MessageBox.hide();
642
+ },
643
+ addItemToSection : function ($item, $section) {
644
+ var $last = $section.find('.curriculum-section-items .lp-section-item:last');
645
+ $item.insertBefore($last);
646
+ $item.removeClass('lp-item-empty');
647
+ if (!parseInt($item.attr('data-item_id'))) {
648
+ $item.find('a[data-action="remove"]').hide();
649
+ }
650
+ this.model.addItem(parseInt($item.attr('data-id')));
651
+ LearnPress.Hook.doAction('learn_press_add_item_to_section', $item, $section);
652
+ },
653
+ addNewItem : function (e) {
654
+ var $form = $(e.target).closest('.lp-modal-search');
655
+ $.ajax({
656
+ url : LearnPress_Settings.ajax,
657
+ data : {
658
+ action: 'learnpress_quick_add_item',
659
+ name : $form.find('input[name="lp-item-name"]').val(),
660
+ type : $form.data('item_type') || 'lp_lesson'
661
+ },
662
+ type : 'post',
663
+ dataType: 'html',
664
+ success : function (response) {
665
+ var json = LearnPress.parseJSON(response);
666
+ if (json.html) {
667
+ var $item = $(json.html)
668
+ $form.find('ul').append($item);
669
+ $item.find('input[type="checkbox"]').attr('checked', true).trigger('change');
670
+ }
671
+ }
672
+ });
673
+ },
674
+ toggleAddItemButtonState: function (e) {
675
+ var $form = $(e.target).closest('.lp-modal-search'),
676
+ selected = $form.find('li input:checked'),
677
+ $button = $form.find('.lp-add-item');
678
+ if (selected.length) {
679
+ $button.removeAttr('disabled').html($button.attr('data-text') + ' (+' + selected.length + ')');
680
+ } else {
681
+ $button.attr('disabled', true).html($button.attr('data-text'));
682
+ }
683
+ },
684
+ onSave : function (evt) {
685
+ /*return;
686
+ var $title = $('#title'),
687
+ $curriculum = $('.lp-curriculum-section:not(.lp-section-empty)'),
688
+ is_error = false;
689
+ if (0 == $title.val().length) {
690
+ alert( lp_course_params.notice_empty_title );
691
+ $title.focus();
692
+ is_error = true;
693
+ } else if (0 == $curriculum.length) {
694
+ alert( lp_course_params.notice_empty_section );
695
+ $('.lp-curriculum-section .lp-section-name').focus();
696
+ is_error = true;
697
+ } else {
698
+ /*$curriculum.each(function () {
699
+ var $section = $('.lpr-section-name', this);
700
+ if (0 == $section.val().length) {
701
+ alert( lp_course_params.notice_empty_section_name );
702
+ $section.focus();
703
+ is_error = true;
704
+ return false;
705
+ }
706
+ });
707
+ }
708
+ if( $( 'input[name="_lpr_course_payment"]:checked').val() == 'not_free' && $('input[name="_lpr_course_price"]').val() <= 0 ){
709
+ alert( lp_course_params.notice_empty_price );
710
+ is_error = true;
711
+ $('input[name="_lpr_course_price"]').focus();
712
+ }
713
+ if (true == is_error) {
714
+ evt.preventDefault();
715
+ return false;
716
+ }
717
+ */
718
+ return this._prepareSections();
719
+ //return false
720
+ },
721
+ _prepareSections : function () {
722
+ var $sections = this.$form.find('.curriculum-section');
723
+ $sections.each(function (i, n) {
724
+ var $section = $(this),
725
+ $items = $section.find('.lp-section-item'),
726
+ $inputs = $('input[name*="__SECTION__"]', $section),
727
+ section_id = parseInt($section.attr('data-id'));
728
+ $inputs.each(function () {
729
+ var $input = $(this),
730
+ name = $input.attr('name');
731
+ name = name.replace(/__SECTION__/, section_id ? section_id : 'section-' + i);
732
+ $input.attr('name', name);
733
+ });
734
+ $items.each(function (j, l) {
735
+ $(this).find('input[name*="__ITEM__"]').each(function () {
736
+ var $input = $(this),
737
+ name = $input.attr('name');
738
+ name = name.replace(/__ITEM__/, 'item-' + j);
739
+ $input.attr('name', name);
740
+ });
741
+ });
742
+ });
743
+ if (this.removeItemIds) {
744
+ this.$form.append('<input type="hidden" name="_lp_remove_item_ids" value="' + this.removeItemIds.join(',') + '" />');
745
+ }
746
+ },
747
+ render : function () {
748
+
749
+ },
750
+ inputKeyPressEvent : function (e) {
751
+ if (this.isShowing && e.keyCode == 13) {
752
+ return false;
753
+ }
754
+ },
755
+ inputKeyDownEvent : function (e) {
756
+ var $input = $(e.target);
757
+ $input.attr('lastCode', e.keyCode);
758
+ $input.attr('caret', $input.caret());
759
+ },
760
+ processKeyEvents : function (e) {
761
+ var $target = $(e.target),
762
+ $section = $target.closest('.lp-curriculum-section'),
763
+ field = $target.attr('data-field'),
764
+ lastCode = $target.data('lastCode'),
765
+ keyCode = e.keyCode,
766
+ text = $target.val(),
767
+ caretPos = $target.attr('type') == 'text' ? $target.caret() : false,
768
+ caretLen = text.length,
769
+ that = this;
770
+ if (field == 'item-name') {
771
+ var $item = $target.closest('.lp-section-item');
772
+ if (text.match(/\\q\?/i) || this.isShowing == 'searchQuizForm') {
773
+ this.searchQuizForm($item);
774
+ }
775
+ if (text.match(/\\l\?/i)) {
776
+ this.searchLessonForm($item);
777
+ }
778
+ if (e.altKey) {
779
+ if (keyCode == 81) {
780
+ $target.closest('.lp-section-item').find('.handle.dashicons').removeClass('dashicons-media-document').addClass('dashicons-format-status');
781
+ $target.siblings('.lp-item-type').attr('value', 'lp_quiz');
782
+ } else if (keyCode == 76) {
783
+ $target.closest('.lp-section-item').find('.handle.dashicons').removeClass('dashicons-format-status').addClass('dashicons-media-document');
784
+ $target.siblings('.lp-item-type').attr('value', 'lp_lesson');
785
+ }
786
+ }
787
+ }
788
+ var xxx = true;
789
+ if (this.isShowing) {
790
+ xxx = this[this.isShowing + 'KeyEvents'] && this[this.isShowing + 'KeyEvents'].call(this, e);
791
+ }
792
+ if (xxx === false) return;
793
+ //[33 = page up, 34 = page down, 35 = end, 36 = home, 37 = left, 38 = up, 39 = right, 40 = down, 8 = backspace, enter = 13, 46 = del]
794
+ switch (keyCode) {
795
+ case 8: // backspace
796
+ case 46:
797
+ if (text.length == 0 && $target.data('keyRepeat') == 2) {
798
+ if (field == 'section-name') {
799
+
800
+ } else if (field == 'item-name') {
801
+ var $item = $target.closest('.lp-section-item').css('visibility', 'hidden');
802
+ var $inputs = this.$('.lp-item-name:visible'),
803
+ pos = $inputs.index($target);
804
+ if ($inputs.length == 1) {
805
+ $inputs.addClass('lp-item-empty');
806
+ break;
807
+ }
808
+ if (keyCode == 8) {
809
+ pos > 0 ? $inputs.eq(pos - 1).focus().caret($inputs.eq(pos - 1).val().length) : '';
810
+ } else {
811
+ pos < $inputs.length - 1 ? $inputs.eq(pos + 1).focus().caret(0) : '';
812
+ }
813
+ $item.remove();
814
+ }
815
+ }
816
+ break;
817
+ case 13: // enter
818
+
819
+ break;
820
+ case 33: // page up
821
+ case 34: // page down
822
+ case 35: // end
823
+ case 36: // home
824
+ case 37: // left
825
+ case 39: // right
826
+ break;
827
+ case 38: // up
828
+ case 40: // down
829
+ //if( this.isShowing ){
830
+ this[this.isShowing + 'KeyEvents'] && this[this.isShowing + 'KeyEvents'].call(this, e);
831
+ //}else {
832
+ var isDown = keyCode == 40;
833
+ var $inputs = this.$('.lp-section-name:visible, .lp-item-name:visible'),
834
+ pos = $inputs.index($target);
835
+ if (isDown) {
836
+ pos == $inputs.length - 1 ? $inputs.eq(0).focus() : $inputs.eq(pos + 1).focus();
837
+ } else {
838
+ pos == 0 ? $inputs.eq($inputs.length - 1).focus() : $inputs.eq(pos - 1).focus();
839
+ }
840
+ //}
841
+ break;
842
+ default:
843
+ if ($target.val().length > 0) {
844
+ if (field == 'section-name') {
845
+ $section.removeClass('lp-section-empty');
846
+ that.appendSection($section);
847
+ } else if (field == 'item-name') {
848
+ var $item = $target.closest('.lp-section-item').removeClass('lp-item-empty');
849
+ that.appendSectionItem($item);
850
+ }
851
+ }
852
+ }
853
+ if (lastCode == keyCode && text.length == 0) {
854
+ var keyRepeat = $target.data('keyRepeat');
855
+ if (!keyRepeat) {
856
+ keyCode = 1
857
+ }
858
+ $target.data('keyRepeat', keyRepeat + 1);
859
+ } else {
860
+ $target.data('keyRepeat', 1);
861
+ }
862
+
863
+ $target.data('lastCode', keyCode);
864
+
865
+ },
866
+ appendSection : function ($section) {
867
+ var that = this,
868
+ $sections = this.$('.lp-curriculum-section'),
869
+ $last = $sections.last();
870
+ if (!$last.hasClass('lp-section-empty')) {
871
+ this._createSection().insertAfter($last);
872
+ }
873
+ },
874
+ appendSectionItem : function ($item, $section) {
875
+ if (!$section) $section = $item.closest('.lp-curriculum-section');
876
+ var that = this,
877
+ $items = $section.find('.lp-section-item'),
878
+ $last = $items.last();
879
+ if (!$last.hasClass('lp-item-empty')) {
880
+ this._createItem().insertAfter($last);
881
+ }
882
+ },
883
+ searchQuizForm : function ($item) {
884
+ if (this.isShowing == 'searchQuizForm' && this.$modalQuizzes) {
885
+ var $input = $item.find('.lp-item-name'),
886
+ text = $input.val().replace(/\\q\?[\s]*/ig, ''),
887
+ $lis = this.$modalQuizzes.find('li:not(.lp-search-no-results):not(.selected)').addClass('hide-if-js'),
888
+ reg = new RegExp($.grep(text.split(/[\s]+/), function (a) {
889
+ return a.length
890
+ }).join('|'), "ig"),
891
+ found = 0;
892
+ if (text.length) {
893
+ found = $lis.filter(function () {
894
+ var $el = $(this),
895
+ itemText = $el.data('text'),
896
+ ret = itemText.search(reg) >= 0;
897
+ if (ret) {
898
+ $el.html(itemText.replace(reg, "<i class=\"lp-highlight-color\">\$&</i>"));
899
+ } else {
900
+ $el.html(itemText);
901
+ }
902
+ return ret;
903
+ }).removeClass('hide-if-js').length;
904
+ } else {
905
+ found = $lis.removeClass('hide-if-js').length;
906
+ }
907
+ if (!found) {
908
+ this.$modalQuizzes.find('.lp-search-no-results').removeClass('hide-if-js');
909
+ } else {
910
+ this.$modalQuizzes.find('.lp-search-no-results').addClass('hide-if-js');
911
+ }
912
+ return;
913
+ }
914
+ if (!this.$modalQuizzes) {
915
+ this.$modalQuizzes = $(wp.template('lp-modal-search-quiz')({}))
916
+ }
917
+ var $input = $item.find('.lp-item-name'),
918
+ position = $input.offset();
919
+
920
+ this.$modalQuizzes.insertAfter($input).css({
921
+ position: 'absolute',
922
+ //top: position.top + $input.outerHeight(),
923
+ left : $input.position().left,
924
+ width : $input.outerWidth() - 2
925
+ }).removeClass('hide-if-js');
926
+ if (this.$modalQuizzes.find('li:not(.lp-search-no-results):not(.selected)').length == 0) {
927
+ this.$modalQuizzes.find('li.lp-search-no-results').removeClass('hide-if-js');
928
+ }
929
+ this.isShowing = 'searchQuizForm';
930
+ },
931
+ searchQuizFormKeyEvents : function (e) {
932
+ return;
933
+ var $items = this.$modalQuizzes.find('li:visible:not(.lp-search-no-results)'),
934
+ $activeItem = $items.filter('.highlighting'),
935
+ $next = false;
936
+ switch (e.keyCode) {
937
+ case 38: // up
938
+ if ($activeItem.length) {
939
+ $next = $activeItem.prev();
940
+ }
941
+ if (!$next.length) {
942
+ $next = $items.last();
943
+ }
944
+ //.removeClass('highlighting');
945
+ $next.addClass('highlighting').siblings().removeClass('highlighting');
946
+ return false;
947
+ break;
948
+ case 40: // down
949
+ if ($activeItem.length) {
950
+ $next = $activeItem.next();
951
+ }
952
+ if (!$next.length) {
953
+ $next = $items.first();
954
+ }
955
+ //$activeItem.removeClass('highlighting');
956
+ $next.addClass('highlighting').siblings().removeClass('highlighting');
957
+ return false;
958
+ break;
959
+ case 13:
960
+ case 27:
961
+ this.isShowing = '';
962
+ if (e.keyCode == 13) {
963
+ var $input = $(e.target),
964
+ $item = $input.closest('.lp-section-item');
965
+ $input.val($activeItem.data('text'));
966
+ var id = $activeItem.attr('data-id'),
967
+ type = $activeItem.attr('data-type');
968
+ $item.removeClass('.lp-item-lp_lesson lp-item-empty lp-item-new').addClass('lp-item-' + type).attr({
969
+ 'data-type': type,
970
+ 'data-id' : id
971
+ })
972
+ } else {
973
+ $(e.target).val($(e.target).val().replace(/\\q\?[\s]*/ig, ''));
974
+ }
975
+ this.$modalQuizzes.hide();
976
+ e.preventDefault();
977
+ return false;
978
+ break;
979
+ }
980
+
981
+ },
982
+ searchLessonForm : function () {
983
+ alert('search lesson')
984
+ },
985
+ _getNextSection : function ($section, loop) {
986
+ var $nextSection = $section.next();
987
+ if ($nextSection.length == 0 && ((typeof loop == 'undefined') || (loop == true))) {
988
+ $nextSection = $section.parent().children().first();
989
+ }
990
+ return $nextSection;
991
+ },
992
+ _getPrevSection : function ($section, loop) {
993
+ var $prevSection = $section.prev();
994
+ if ($prevSection.length == 0 && ((typeof loop == 'undefined') || (loop == true))) {
995
+ $prevSection = $section.parent().children().last();
996
+ }
997
+ return $prevSection;
998
+ },
999
+ _createSection : function () {
1000
+ var sectionTemplate = wp.template('curriculum-section');
1001
+ return $(sectionTemplate({}));
1002
+ },
1003
+ _createItem : function () {
1004
+ var itemTemplate = wp.template('section-item');
1005
+ return $(itemTemplate({}));
1006
+ },
1007
+ _removeItem : function (e) {
1008
+ e.preventDefault();
1009
+ var $item = $(e.target).closest('.lp-section-item');
1010
+ this.removeItem($item, true, null, e.target);
1011
+ },
1012
+ removeItem : function ($items, b, callback, target) {
1013
+ if ($items.length == 0) return;
1014
+ var that = this,
1015
+ itemNames = $items.map(function () {
1016
+ return $(this).find('.lp-item-name').val()
1017
+ }).get().join('</p><p>+&nbsp;');
1018
+
1019
+ LearnPress.MessageBox.quickConfirm(target, {
1020
+ onOk : function (a) {
1021
+ var ids = [];
1022
+ a.items && a.items.each(function () {
1023
+ var $item = $(this),
1024
+ id = parseInt($item.attr('data-section_item_id')),
1025
+ type = $item.attr('data-type');
1026
+ $item.remove();
1027
+ if (id) {
1028
+ a.self.model.removeItem(id);
1029
+ ids.push(id);
1030
+ }
1031
+ });
1032
+ if (b) {
1033
+ a.self.removeItemDB(ids);
1034
+ }
1035
+ $.isFunction(callback) && callback.call();
1036
+ },
1037
+ onCancel: function (a) {
1038
+ a.items
1039
+ .each(function () {
1040
+ $(this).removeClass('remove').find('.item-checkbox input').prop('checked', false).trigger('change')
1041
+ })
1042
+ .closest('.curriculum-section')
1043
+ .find('.item-bulk-actions button')
1044
+ .map(function () {
1045
+ var $b = $(this);
1046
+ ($.inArray($b.attr('data-action'), ['cancel', 'delete']) != -1) && $b.hide();
1047
+ if ($b.attr('data-action') == 'delete') $b.html($b.attr('data-title'))
1048
+ });
1049
+ },
1050
+ data : {
1051
+ items: $items,
1052
+ self : this
1053
+ }
1054
+ });
1055
+ return;
1056
+ LearnPress.MessageBox.show(meta_box_course_localize.notice_remove_section_item + '<h4><p>+&nbsp;' + itemNames + '</p></h4>', {
1057
+ data : {
1058
+ items: $items,
1059
+ self : this
1060
+ },
1061
+ buttons: 'yesNo',
1062
+ events : {
1063
+ onNo : function (instance) {
1064
+ $items
1065
+ .each(function () {
1066
+ $(this).removeClass('remove').find('.item-checkbox input').prop('checked', false)
1067
+ })
1068
+ .closest('.curriculum-section')
1069
+ .find('.item-bulk-actions button')
1070
+ .map(function () {
1071
+ var $b = $(this);
1072
+ ($.inArray($b.attr('data-action'), ['cancel', 'delete']) != -1) && $b.hide();
1073
+ if ($b.attr('data-action') == 'delete') $b.html($b.attr('data-title'))
1074
+ });
1075
+ },
1076
+ onYes: function (instance) {
1077
+ var ids = [];
1078
+ instance.data.items && instance.data.items.each(function () {
1079
+ var $item = $(this),
1080
+ id = parseInt($item.attr('data-section_item_id')),
1081
+ type = $item.attr('data-type');
1082
+ $item.remove();
1083
+ if (id) {
1084
+ instance.data.self.model.removeItem(id);
1085
+ ids.push(id);
1086
+ }
1087
+ });
1088
+ if (b) {
1089
+ that.removeItemDB(ids);
1090
+ }
1091
+ $.isFunction(callback) && callback.call();
1092
+ }
1093
+ }
1094
+ })
1095
+ },
1096
+ removeItemDB : function (id) {
1097
+ $.ajax({
1098
+ url : LearnPress_Settings.ajax,
1099
+ data : {
1100
+ action: 'learnpress_remove_course_items',
1101
+ id : id
1102
+ },
1103
+ success: function (response) {
1104
+ LearnPress.log(response)
1105
+ }
1106
+ });
1107
+ },
1108
+ findItemsById : function (id) {
1109
+ if (!$.isArray(id)) {
1110
+ id = [parseInt(id)];
1111
+ } else {
1112
+ id = id.map(function (n) {
1113
+ return parseInt(n)
1114
+ });
1115
+ }
1116
+ return this.$('.lp-section-item').filter(function () {
1117
+ return $.inArray(parseInt($(this).attr('data-id')), id) != -1
1118
+ });
1119
+ },
1120
+ _sectionActionHandler : function (e) {
1121
+ var that = this,
1122
+ $button = $(e.target),
1123
+ action = $button.attr('data-action');
1124
+ switch (action) {
1125
+ case 'expand':
1126
+ $button
1127
+ .addClass('hide-if-js')
1128
+ .siblings('a[data-action="collapse"]')
1129
+ .removeClass('hide-if-js')
1130
+ .closest('.curriculum-section')
1131
+ .removeClass('is-hidden')
1132
+ .find('.curriculum-section-content').slideDown(function () {
1133
+ if (updateHiddenCurriculum().length == 0) {
1134
+
1135
+ }
1136
+ });
1137
+ break;
1138
+ case 'collapse':
1139
+ $button
1140
+ .addClass('hide-if-js')
1141
+ .siblings('a[data-action="expand"]')
1142
+ .removeClass('hide-if-js')
1143
+ .closest('.curriculum-section')
1144
+ .addClass('is-hidden')
1145
+ .find('.curriculum-section-content').slideUp(function () {
1146
+ updateHiddenCurriculum();
1147
+ });
1148
+ break;
1149
+ case 'remove':
1150
+ LearnPress.MessageBox.quickConfirm($button, {
1151
+ onOk: function (a) {
1152
+ var $section = $(a);
1153
+
1154
+ $.ajax({
1155
+ url : LearnPress_Settings.ajax,
1156
+ data : {
1157
+ action: 'learnpress_remove_course_section',
1158
+ id : $section.attr('data-id')
1159
+ },
1160
+ success: function () {
1161
+ $section.remove();
1162
+ }
1163
+ });
1164
+ },
1165
+ data: $button.closest('.curriculum-section')
1166
+ });
1167
+ break;
1168
+ LearnPress.MessageBox.show('Do you want to remove this section?', {
1169
+ buttons: 'yesNo',
1170
+ data : $button.closest('.curriculum-section'),
1171
+ events : {
1172
+ onYes: function (args) {
1173
+ var $section = $(args.data);
1174
+
1175
+ $.ajax({
1176
+ url : LearnPress_Settings.ajax,
1177
+ data : {
1178
+ action: 'learnpress_remove_course_section',
1179
+ id : $section.attr('data-id')
1180
+ },
1181
+ success: function () {
1182
+ $section.remove();
1183
+ }
1184
+ });
1185
+ }
1186
+ }
1187
+ })
1188
+ break;
1189
+ }
1190
+ if (action) {
1191
+ e.preventDefault();
1192
+ }
1193
+ }
1194
+ });
1195
+ var model = new LP_Curriculum_Model(LP_Curriculum_Settings),
1196
+ view = new LP_Curriculum_View(model);
1197
+
1198
+ LearnPress.$LP_Curriculum_Model = model;
1199
+ LearnPress.$LP_Curriculum_View = view;
1200
+ });
1201
+
1202
+ function updateHiddenCurriculum(hidden) {
1203
+ if (hidden == undefined) {
1204
+ hidden = [];
1205
+ var len = $('.curriculum-section-content').each(function () {
1206
+ if ($(this).is(':hidden')) {
1207
+ hidden.push($(this).parent().attr('data-id'));
1208
+ }
1209
+ }).length;
1210
+ if (hidden.length == len) {
1211
+ $('.lp-section-actions a[data-action="collapse"]')
1212
+ .addClass('hide-if-js')
1213
+ .siblings('a[data-action="expand"]')
1214
+ .removeClass('hide-if-js');
1215
+ }
1216
+ }
1217
+ if (hidden.length == 0) {
1218
+ $('.lp-section-actions a[data-action="collapse"]')
1219
+ .removeClass('hide-if-js')
1220
+ .siblings('a[data-action="expand"]')
1221
+ .addClass('hide-if-js');
1222
+ }
1223
+
1224
+ $.ajax({
1225
+ url : LearnPress_Settings.ajax,
1226
+ data : {
1227
+ action : 'learnpress_update_curriculum_section_state',
1228
+ course_id: $('#post_ID').val(),
1229
+ hidden : hidden
1230
+ },
1231
+ success: function () {
1232
+
1233
+ }
1234
+ });
1235
+ return hidden;
1236
+ }
1237
+
1238
+ function _removeSectionHandler() {
1239
+
1240
+ }
1241
+
1242
+ function _toggleSectionsHandler(e) {
1243
+ e.preventDefault();
1244
+ var action = $(this).attr('data-action');
1245
+ switch (action) {
1246
+ case 'expand':
1247
+ var $items = $('.curriculum-section-content'),
1248
+ len = $items.length, i = 0;
1249
+ $(this)
1250
+ .addClass('hide-if-js')
1251
+ .siblings('a[data-action="collapse"]')
1252
+ .removeClass('hide-if-js');
1253
+ $items
1254
+ .removeClass('is-hidden')
1255
+ .slideDown(function () {
1256
+ if (++i == len) {
1257
+ updateHiddenCurriculum([]);
1258
+ }
1259
+ });
1260
+ $items.siblings('.curriculum-section-head')
1261
+ .find('a[data-action]')
1262
+ .map(function () {
1263
+ var $a = $(this);
1264
+ switch ($a.attr('data-action')) {
1265
+ case 'collapse':
1266
+ $a.removeClass('hide-if-js');
1267
+ break;
1268
+ case 'expand':
1269
+ $a.addClass('hide-if-js');
1270
+ }
1271
+ });
1272
+ break;
1273
+ case 'collapse':
1274
+ var $items = $('.curriculum-section-content'),
1275
+ len = $items.length, i = 0,
1276
+ hidden = [];
1277
+ $(this)
1278
+ .addClass('hide-if-js')
1279
+ .siblings('a[data-action="expand"]')
1280
+ .removeClass('hide-if-js');
1281
+ $items
1282
+ .addClass('is-hidden')
1283
+ .slideUp(function () {
1284
+ hidden.push($(this).parent().attr('data-id'));
1285
+ if (++i == len) {
1286
+ updateHiddenCurriculum(hidden);
1287
+ }
1288
+ });
1289
+ $items.siblings('.curriculum-section-head')
1290
+ .find('a[data-action]')
1291
+ .map(function () {
1292
+ var $a = $(this);
1293
+ switch ($a.attr('data-action')) {
1294
+ case 'collapse':
1295
+ $a.addClass('hide-if-js');
1296
+ break;
1297
+ case 'expand':
1298
+ $a.removeClass('hide-if-js');
1299
+ }
1300
+ });
1301
+ break;
1302
+ }
1303
+ }
1304
+
1305
+ function _toggleEditorHandler(e) {
1306
+ if (e.type == '_click') {
1307
+ if ($(this).data('hidden') == 'yes') {
1308
+ $('#postdivrich').addClass('hide-if-js');
1309
+ }
1310
+ $('#postdivrich').css('visibility', 'visible');
1311
+ } else {
1312
+ var is_hidden = 'yes';
1313
+ if (!$('#postdivrich').toggleClass('hide-if-js').hasClass('hide-if-js')) {
1314
+ $(window).trigger('scroll');
1315
+ is_hidden = '';
1316
+ }
1317
+ ;
1318
+ $.ajax({
1319
+ url : LearnPress_Settings.ajax,
1320
+ type : 'post',
1321
+ data : {
1322
+ action : 'learnpress_update_editor_hidden',
1323
+ course_id: $('#post_ID').val(),
1324
+ is_hidden: is_hidden
1325
+ },
1326
+ success: function () {
1327
+
1328
+ }
1329
+ });
1330
+ }
1331
+ }
1332
+
1333
+ function _makeListSortable() {
1334
+ $('.curriculum-sections')
1335
+ .sortable({
1336
+ items : '.curriculum-section:not(.lp-empty-section)',
1337
+ handle: '.lp-section-actions a.move',
1338
+ axis : 'y'
1339
+ });
1340
+
1341
+ $('.curriculum-section-items > tbody')
1342
+ .sortable({
1343
+ items : '.lp-section-item:not(.lp-item-empty)',
1344
+ handle : '.item-checkbox',
1345
+ axis : 'y',
1346
+ connectWith: '.curriculum-section-items > tbody',
1347
+ helper : function (e, tr) {
1348
+ var $originals = tr.children();
1349
+ var $helper = tr.clone();
1350
+ $helper.children().each(function (index) {
1351
+ // Set helper cell sizes to match the original sizes
1352
+ $(this).width($originals.eq(index).width());
1353
+ });
1354
+
1355
+ $(tr).parent().append($helper);
1356
+
1357
+ return $helper;
1358
+ },
1359
+ start : function (e, ui) {
1360
+ var cellCount = 0;
1361
+ $('td, th', ui.helper).each(function () {
1362
+ var colspan = 1;
1363
+ var colspanAttr = $(this).attr('colspan');
1364
+ if (colspanAttr > 1) {
1365
+ colspan = colspanAttr;
1366
+ }
1367
+ cellCount += colspan;
1368
+ });
1369
+ ui.placeholder.html('<td colspan="' + cellCount + '">&nbsp;</td>');
1370
+ },
1371
+ sort : function (e, ui) {
1372
+ LearnPress.log(ui.helper.html())
1373
+ },
1374
+ stop : function (e, ui) {
1375
+ var $emptyItem = ui.item.parent().find('.lp-item-empty:last');
1376
+ LearnPress.log('empty:')
1377
+ LearnPress.log($emptyItem.get(0))
1378
+ LearnPress.log('next:')
1379
+ LearnPress.log($emptyItem.next().get(0))
1380
+ if ($emptyItem.next().is(ui.item.get(0))) {
1381
+ $emptyItem.insertAfter(ui.item);
1382
+ }
1383
+ }
1384
+ });
1385
+ }
1386
+
1387
+ function _ready() {
1388
+ $('#learn-press-button-toggle-editor').on('click _click', _toggleEditorHandler).trigger('_click');
1389
+
1390
+ _makeListSortable();
1391
+ }
1392
+
1393
+ $(document)
1394
+ .ready(_ready)
1395
+ .on('click', '.items-toggle a', _toggleSectionsHandler);
1396
+
1397
+ })(jQuery);
assets/js/admin/meta-box-order.js ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;
2
+ (function ($) {
3
+ var LP_Order_View = window.LP_Order_View = Backbone.View.extend({
4
+ el : 'body',
5
+ events : {
6
+ 'click #learn-press-add-order-item' : '_addItem',
7
+ 'click #learn-press-calculate-order-total' : 'calculateTotal',
8
+ 'click #learn-press-courses-result a[data-id]': 'addItem',
9
+ 'click .remove-order-item' : 'removeItem',
10
+ 'keyup #learn-press-search-item-term' : 'searchItems'
11
+ },
12
+ initialize: function () {
13
+ _.bindAll( this, 'resetModal', 'updateModal' );
14
+ LearnPress.Hook.addAction( 'learn_press_message_box_before_resize', this.resetModal);
15
+ LearnPress.Hook.addAction( 'learn_press_message_box_resize', this.updateModal);
16
+ this.userSuggest();
17
+ },
18
+ userSuggest: function(){
19
+ var id = ( typeof current_site_id !== 'undefined' ) ? '&site_id=' + current_site_id : '';
20
+ var position = { offset: '0, -1' };
21
+ if ( typeof isRtl !== 'undefined' && isRtl ) {
22
+ position.my = 'right top';
23
+ position.at = 'right bottom';
24
+ }
25
+ $( '.wp-suggest-user' ).each( function(){
26
+ var $this = $( this ),
27
+ autocompleteType = ( typeof $this.data( 'autocompleteType' ) !== 'undefined' ) ? $this.data( 'autocompleteType' ) : 'add',
28
+ autocompleteField = ( typeof $this.data( 'autocompleteField' ) !== 'undefined' ) ? $this.data( 'autocompleteField' ) : 'user_login';
29
+
30
+ $this.autocomplete({
31
+ source: LearnPress_Settings.ajax + '?action=learnpress_search_users&autocomplete_type=' + autocompleteType + '&autocomplete_field=' + autocompleteField + id,
32
+ delay: 500,
33
+ minLength: 2,
34
+ position: position,
35
+ open: function() {
36
+ $( this ).addClass( 'open' );
37
+ },
38
+ close: function() {
39
+ $( this ).removeClass( 'open' );
40
+ },
41
+ select: function(a, b){
42
+ LearnPress.log(a, b)
43
+ }
44
+ });
45
+ });
46
+ },
47
+ resetModal: function(height, $app){
48
+ this.$('#learn-press-courses-result').css('height', height - 120).css('overflow', 'auto');
49
+ },
50
+ updateModal: function($app){
51
+ this.$('#learn-press-courses-result').css('height', '').css('overflow', '')
52
+ },
53
+ _addItem : function (e) {
54
+ var $form = $('#learn-press-modal-add-order-courses');
55
+ if ($form.length == 0) {
56
+ $form = $(wp.template('learn-press-modal-add-order-courses')());
57
+ }
58
+ LearnPress.MessageBox.show($form);
59
+ },
60
+ addItem : function (e) {
61
+ var that = this,
62
+ $item = $(e.target);
63
+ if (e.ctrlKey) {
64
+ //return true;
65
+ }
66
+ $.ajax({
67
+ url : LearnPress_Settings.ajax,
68
+ data : {
69
+ action : 'learnpress_add_item_to_order',
70
+ order_id: parseInt($('input#post_ID').val()),
71
+ item_id : parseInt($item.attr('data-id')),
72
+ nonce : $('#learn-press-modal-add-order-courses').attr('data-nonce')
73
+ },
74
+ dataType: 'text',
75
+ type : 'post',
76
+ success : function (response) {
77
+ LearnPress.log(response);
78
+ response = LearnPress.parseJSON(response);
79
+ if (response.result == 'success') {
80
+ var $order_table = that.$('.order-items'),
81
+ $no_item = $order_table.find('.no-order-items');
82
+ $(response.item_html).insertBefore($no_item);
83
+ $order_table.find('.order-subtotal').html(response.order_data.subtotal_html);
84
+ $order_table.find('.order-total').html(response.order_data.total_html);
85
+
86
+ $item.remove();
87
+ $no_item.addClass('hide-if-js');
88
+ }
89
+ }
90
+ })
91
+
92
+ return false;
93
+ },
94
+ removeItem: function(e){
95
+ e.preventDefault();
96
+ var that = this,
97
+ $item = $(e.target).closest('tr'),
98
+ item_id = parseInt( $item.attr('data-item_id') );
99
+ if( !item_id ){
100
+ return;
101
+ }
102
+ $.ajax({
103
+ url: LearnPress_Settings.ajax,
104
+ data: {
105
+ action: 'learnpress_remove_order_item',
106
+ order_id: $('#post_ID').val(),
107
+ item_id: item_id,
108
+ remove_nonce: $item.attr('data-remove_nonce')
109
+ },
110
+ type: 'post',
111
+ dataType: 'text',
112
+ success: function(response){
113
+ response = LearnPress.parseJSON(response);
114
+ if(response.result == 'success'){
115
+ var $order_table = that.$('.order-items'),
116
+ $no_item = $order_table.find('.no-order-items'),
117
+ $other_items = $item.siblings().filter(function(){return !$(this).is($no_item)});
118
+ $order_table.find('.order-subtotal').html(response.order_data.subtotal_html);
119
+ $order_table.find('.order-total').html(response.order_data.total_html);
120
+ $item.remove();
121
+ $other_items.length == 0 && $no_item.removeClass('hide-if-js');
122
+ }
123
+ }
124
+ });
125
+ },
126
+ calculateTotal: function (e) {
127
+ LearnPress.log(e)
128
+ },
129
+ fetchResults : function (results) {
130
+ var $list = this.$('#learn-press-courses-result'),
131
+ $t = $list.find('li').filter(function () {
132
+ return $(this).hasClass('lp-search-no-results') ? true : $(this).remove() && false;
133
+ });
134
+ _.each(results, function (i, k) {
135
+ $('<li><a href="' + i.permalink + '" data-id="' + k + '">' + i.title + '</a></li>').insertBefore($t);
136
+ });
137
+ },
138
+ searchItems : function (e) {
139
+ var that = this,
140
+ $input = $(e.target),
141
+ timer = $input.data('timer'),
142
+ term = $input.val(),
143
+ _search = function () {
144
+ $.ajax({
145
+ url : LearnPress_Settings.ajax,
146
+ data : {
147
+ action: 'learnpress_search_courses',
148
+ nonce : $input.attr('data-nonce'),
149
+ term : term
150
+ },
151
+ type : 'get',
152
+ dataType: 'text',
153
+ success : function (response) {
154
+ response = LearnPress.parseJSON(response);
155
+ that.fetchResults(response);
156
+ }
157
+ });
158
+ };
159
+ timer && clearTimeout(timer);
160
+ if ((term + '').length >= 3) {
161
+ timer = setTimeout(_search, 250);
162
+ $input.data('timer', timer);
163
+ }
164
+ }
165
+ });
166
+
167
+ $(document).ready(function () {
168
+ new LP_Order_View();
169
+ });
170
+ })(jQuery);
assets/js/admin/meta-box-question.js ADDED
@@ -0,0 +1,422 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @author ThimPress
3
+ * @package LearnPress/Javascript
4
+ * @version 1.0
5
+ */
6
+ ;
7
+ if (typeof window.LearnPress == 'undefined') {
8
+ window.LearnPress = {};
9
+ }
10
+ ;(function ($) {
11
+ var $doc = $(document);
12
+ LearnPress.Hook.addFilter('before_add_question_option', function($el, args){
13
+ return true;
14
+ }).addAction('question_option_added', function($el){
15
+ //$el.find('input[type="text"]').focus();
16
+ })
17
+
18
+ LearnPress.Question = {
19
+ _getEmptyOption: function(question_id){
20
+ var $options = $('#learn-press-list-options-' + question_id + ' tbody .lp-list-option-empty');
21
+ return $options.length ? $options : false;
22
+ },
23
+ addOption : function (question_id, args) {
24
+ var $newOption = this._getEmptyOption(question_id);
25
+ args = $.extend({autoFocus: true}, args || {});
26
+ if( $newOption ){
27
+
28
+ }else {
29
+ var templateArgs = {
30
+ question_id: question_id,
31
+ text : '',
32
+ value : LearnPress.uniqueId()
33
+ },
34
+ tmpl = wp.template($('#learn-press-question-' + question_id).attr('data-type') + '-option'),
35
+ $list = $('#learn-press-list-options-' + question_id + ' tbody');
36
+ $newOption = $(tmpl(templateArgs));
37
+ if (LearnPress.Hook.applyFilters('before_add_question_option', $newOption, args) !== false) {
38
+ $list.append($newOption);
39
+ LearnPress.Hook.doAction('question_option_added', $newOption, args);
40
+ }
41
+ }
42
+ if($newOption && args.autoFocus){
43
+ $newOption.find('.lp-answer-text').focus();
44
+ }
45
+ },
46
+ removeOption: function(theOption){
47
+ var $theOption = null;
48
+ if($.type( theOption ) == 'integer' ){
49
+ $theOption = $('lp-list-option-'+theOption);
50
+ }else{
51
+ $theOption = $(theOption);
52
+ }
53
+ if( LearnPress.Hook.applyFilters('before_remove_question_option', true, $theOption) !== false ) {
54
+ $theOption.remove();
55
+ LearnPress.Hook.doAction('question_option_removed', $theOption);
56
+ }
57
+ },
58
+ addQuestion: function (args) {
59
+ args = $.extend({
60
+ id : 0,
61
+ type: null,
62
+ name: null
63
+ }, args);
64
+ if (!args.id && !args.type) {
65
+ alert('ERROR');
66
+ return;
67
+ }
68
+ var post_data = $.extend({
69
+ action: 'learnpress_add_question'
70
+ }, args);
71
+
72
+ post_data = LearnPress.Hook.applyFilters( 'LearnPress.add_question_post_data', post_data );
73
+
74
+ $.ajax({
75
+ url : LearnPress_Settings.ajax,
76
+ dataType: 'html',
77
+ type : 'post',
78
+ data : post_data,
79
+ success : function (response) {
80
+ response = LearnPress.parseJSON(response);
81
+ var $newQuestion = $(response.html);
82
+ $('#learn-press-list-questions').append($newQuestion);
83
+ LearnPress.Question._hideQuestion( args.id )
84
+ LearnPress.Hook.doAction( 'learn_press_add_quiz_question', $newQuestion, args);
85
+ }
86
+ });
87
+ },
88
+ _hideQuestion: function(question){
89
+ if($.type( question ) == 'number' ) {
90
+ question = $('#learn-press-dropdown-questions .question a[data-id="' + question + '"]').parent()
91
+ }
92
+ $(question).addClass('added');
93
+ },
94
+ _showQuestion: function(question){
95
+ if($.type( question ) == 'number' ) {
96
+ question = $('#learn-press-dropdown-questions .question a[data-id="' + question + '"]').parent()
97
+ }
98
+ $(question).removeClass('added');
99
+ }
100
+ };
101
+ function updateHiddenQuestions(hidden){
102
+ if( hidden == undefined ) {
103
+ hidden = [];
104
+ var len = $('.quiz-question-content').each(function () {
105
+ if ($(this).is(':hidden')) {
106
+ hidden.push($('.learn-press-question', this).attr('data-id'));
107
+ }
108
+ }).length;
109
+ if( hidden.length == 0 ){
110
+ $('.questions-toggle a[data-action="collapse"]')
111
+ .show()
112
+ .siblings('a[data-action="expand"]')
113
+ .hide();
114
+ }else if( hidden.length == len ){
115
+ $('.questions-toggle a[data-action="collapse"]')
116
+ .hide()
117
+ .siblings('a[data-action="expand"]')
118
+ .show();
119
+ }
120
+ }
121
+
122
+ $.ajax({
123
+ url: LearnPress_Settings.ajax,
124
+ data: {
125
+ action: 'learnpress_update_quiz_question_state',
126
+ quiz_id: $('#post_ID').val(),
127
+ hidden: hidden
128
+ },
129
+ success: function(){
130
+
131
+ }
132
+ });
133
+ return hidden;
134
+ }
135
+ LearnPress.sortableQuestionAnswers = function( $questions, args ){
136
+ args = $.extend({
137
+ stop: function(){}
138
+ }, args || {});
139
+ $questions.find('.lp-list-options tbody').sortable({
140
+ handle: '.lp-move-list-option',
141
+ axis: 'y',
142
+ start: function(e, ui){
143
+ var $heads = ui.item.parent().closest('table').find('tr > th');
144
+ ui.item.children().each(function(i){
145
+ $(this).css({
146
+ width: $heads.eq(i).outerWidth()
147
+ });
148
+ })
149
+ var $this = $(this),
150
+ cols = $this.find('tr:first').children().length;
151
+ $this.find('.ui-sortable-placeholder td:gt(0)').remove();
152
+ $this.find('.ui-sortable-placeholder td:eq(0)').attr('colspan', cols)
153
+ },
154
+ stop: function(e, ui){
155
+ $.isFunction( args.stop ) && args.stop.apply( this, [e, ui] );
156
+ }
157
+ });
158
+ }
159
+ function _ready() {
160
+ $('#learn-press-toggle-questions').on('click', function () {
161
+ $(this).siblings('ul').toggle();
162
+ });
163
+
164
+ $doc.on('click', '#learn-press-dropdown-questions ul li a', function (e) {
165
+ e.preventDefault();
166
+ LearnPress.Question.addQuestion({id: $(this).data('id')});
167
+ $(this).closest('ul').hide();
168
+ });
169
+
170
+ $('#learn-press-button-add-question').on('click', function () {
171
+ //LearnPress.Question.addQuestion({name: $('#learn-press-question-name').val(), type: 'true_or_false'});
172
+ });
173
+
174
+ $doc.on('click', '.add-question-option-button', function (e, data) {
175
+ var question_id = $(this).attr('data-id');
176
+ LearnPress.Question.addOption(question_id, data);
177
+ }).on('click', '.lp-remove-list-option', function () {
178
+ var $option = $(this).closest('tr');
179
+ LearnPress.MessageBox.quickConfirm( $('i', this), {
180
+ message: 'Are you sure you want to remove this option?',
181
+ onOk: function (a) {
182
+ LearnPress.Question.removeOption($option);
183
+ }
184
+ });
185
+ }).on('change', '.lp-dropdown-question-types', function(){
186
+ var $select = $(this),
187
+ $wrap = $select.closest('.learn-press-question'),
188
+ questionId = $wrap.data('id'),
189
+ from = $select.data('selected'),
190
+ to = this.value,
191
+ _do = function(){
192
+ LearnPress.MessageBox.blockUI();
193
+ $.ajax({
194
+ url: LearnPress_Settings.ajax,
195
+ type: 'post',
196
+ dataType: 'html',
197
+ data: {
198
+ action: 'learnpress_convert_question_type',
199
+ question_id: questionId,
200
+ from: from,
201
+ to: to,
202
+ data: $('#post').serialize()//$wrap.find('input, select, textarea').
203
+ },
204
+ success: function(response){
205
+ response = LearnPress.parseJSON(response);
206
+ var $newOptions = $(response.html),
207
+ $question = $('#learn-press-question-'+questionId),
208
+ $icon = $question.closest('.quiz-question').find('.quiz-question-icon img');
209
+ $question.replaceWith($newOptions);
210
+ if($icon.length){
211
+ $icon.replaceWith(response.icon)
212
+ }
213
+ LearnPress.Hook.doAction('learn_press_convert_question_type', questionId, from, to, $newOptions );
214
+ LearnPress.MessageBox.hide();
215
+ }
216
+ });
217
+ };
218
+
219
+ LearnPress.MessageBox.show( 'Are you sure you want to convert to new type?', {
220
+ buttons: 'yesNo',
221
+ events: {
222
+ onYes: function () {
223
+ _do();
224
+ },
225
+ onNo : function () {
226
+ //revert
227
+ $select.val(from);//find('option:selected').prop('selected', false).siblings('[value="' + from + '"]').prop('selected', true);
228
+ }
229
+ }
230
+ });
231
+ return;
232
+
233
+ }).on('click', '.questions-toggle a', function(e){
234
+ e.preventDefault();
235
+ var action = $(this).attr('data-action');
236
+ switch (action){
237
+ case 'expand':
238
+ var $items = $('.quiz-question'),
239
+ len = $items.length, i = 0;
240
+ $(this)
241
+ .hide()
242
+ .siblings('a[data-action="collapse"]')
243
+ .show();
244
+ $items
245
+ .removeClass('is-hidden')
246
+ .find('.quiz-question-content').slideDown(function(){
247
+ if(++i == len){
248
+ updateHiddenQuestions([]);
249
+ }
250
+ });
251
+ $items.find('a[data-action="collapse"]').show();
252
+ $items.find('a[data-action="expand"]').hide();
253
+ break;
254
+ case 'collapse':
255
+ var $items = $('.quiz-question'),
256
+ len = $items.length, i = 0,
257
+ hidden = [];
258
+ $(this)
259
+ .hide()
260
+ .siblings('a[data-action="expand"]')
261
+ .show();
262
+ $items
263
+ .addClass('is-hidden')
264
+ .find('.quiz-question-content').slideUp(function(){
265
+ hidden.push($('.learn-press-question', this).attr('data-id'));
266
+ if(++i == len){
267
+ updateHiddenQuestions(hidden);
268
+ }
269
+ });
270
+ $items.find('a[data-action="collapse"]').hide();
271
+ $items.find('a[data-action="expand"]').show();
272
+ break;
273
+ }
274
+ }).on('click', '.quiz-question-actions a', function(e){
275
+ var $link = $(this),
276
+ action = $link.attr('data-action');
277
+
278
+ switch (action){
279
+ case 'expand':
280
+ $(this)
281
+ .hide()
282
+ .siblings('a[data-action="collapse"]')
283
+ .show()
284
+ .closest('.quiz-question')
285
+ .removeClass('is-hidden')
286
+ .find('.quiz-question-content').slideDown(function(){
287
+ if( updateHiddenQuestions().length == 0 ){
288
+
289
+ }
290
+ });
291
+ break;
292
+ case 'collapse':
293
+ $(this)
294
+ .hide()
295
+ .siblings('a[data-action="expand"]')
296
+ .show()
297
+ .closest('.quiz-question')
298
+ .addClass('is-hidden')
299
+ .find('.quiz-question-content').slideUp(function(){
300
+ updateHiddenQuestions();
301
+ });
302
+ break;
303
+ case 'remove':
304
+ LearnPress.MessageBox.quickConfirm( $link, {
305
+ onOk: function(a){
306
+ var $question = $(a);
307
+ $.ajax({
308
+ url: $link.attr('href'),
309
+ /*data: {
310
+ action: 'learnpress_remove_quiz_question',
311
+ question_id: $question.attr('data-id'),
312
+ quiz_id: $('#post_ID').val()
313
+ },*/
314
+ success: function(){
315
+ $question.fadeOut(function(){$(this).remove()});
316
+ }
317
+ });
318
+ },
319
+ onCancel: function(a){
320
+
321
+ },
322
+ data: $(this).closest('.quiz-question')
323
+ });
324
+ break;
325
+ LearnPress.MessageBox.show( 'Do you want to remove this question from quiz?', {
326
+ buttons: 'yesNo',
327
+ data: $(this).closest('.quiz-question'),
328
+ events: {
329
+ onYes: function (instance) {
330
+ var $question = $(instance.data);
331
+ $.ajax({
332
+ url: $link.attr('href'),
333
+ /*data: {
334
+ action: 'learnpress_remove_quiz_question',
335
+ question_id: $question.attr('data-id'),
336
+ quiz_id: $('#post_ID').val()
337
+ },*/
338
+ success: function(){
339
+ $question.fadeOut(function(){$(this).remove()});
340
+ }
341
+ });
342
+ }
343
+ }
344
+ })
345
+ break;
346
+ //case 'edit':
347
+ //LearnPress.MessageBox.show('<iframe src="'+$(this).attr('href')+'" />');
348
+
349
+ }
350
+ if( action ){
351
+ e.preventDefault();
352
+ }
353
+ }).on('keydown', '.no-submit', function(e){
354
+ if(e.keyCode == 13) {
355
+ e.preventDefault();
356
+ LearnPress.log('no submit form');
357
+ }
358
+ }).on('change keyup', '.lp-answer-text', function(e){
359
+ var $input = $(this),
360
+ $option = $input.closest('.lp-list-option'),
361
+ value = $input.val()+'';
362
+ if(e.keyCode != 13){
363
+ switch (e.keyCode){
364
+ case 38:
365
+ case 40:
366
+ case 8:
367
+ case 46:
368
+ var pressed = $input.data('key-'+ e.keyCode) || 1;
369
+ LearnPress.log('pressed:'+pressed)
370
+ if(pressed > 1){
371
+ if(e.keyCode == 38){
372
+ ( $prev = $input.findPrev('.key-nav') ) && $prev.focus();
373
+ pressed = 0;
374
+ }else if(e.keyCode == 40){
375
+ ( $next = $input.findNext('.key-nav') ) && $next.focus();
376
+ pressed = 0;
377
+ }else if(e.keyCode == 8 && value.length == 0){
378
+ var $row = $input.closest('tr'),
379
+ $prev = $row.prev();
380
+ if( $prev.length ){
381
+ $prev.find('.lp-answer-text').focus();
382
+ $row.remove();
383
+ }
384
+ }else if(e.keyCode == 46 && value.length == 0){
385
+ var $row = $input.closest('tr'),
386
+ $next = $row.next();
387
+ if( !$next.hasClass('lp-list-option-empty') ){
388
+ $next.find('.lp-answer-text').focus();
389
+ $row.remove();
390
+ }
391
+ }
392
+ $input.data('key-'+ e.keyCode, 0 );
393
+ }else {
394
+ if( e.keyCode == 8 || e.keyCode == 46 ){
395
+ if( value.length == 0 ){
396
+ $input.data('key-' + e.keyCode, pressed + 1);
397
+ }
398
+ } else {
399
+ $input.data('key-' + e.keyCode, pressed + 1);
400
+ }
401
+ }
402
+ break;
403
+ }
404
+ if( value.length ){
405
+ $option.removeClass('lp-list-option-empty');
406
+ }else{
407
+ $option.addClass('lp-list-option-empty');
408
+ return;
409
+ }
410
+ }
411
+ var $wrap = $(this).closest('.learn-press-question'),
412
+ $button = $wrap.find('.add-question-option-button');
413
+ $button.trigger('click', {autoFocus: e.keyCode == 13});
414
+ });
415
+
416
+
417
+ }
418
+
419
+ $(document).ready(_ready);
420
+
421
+ })
422
+ (jQuery);
assets/js/admin/meta-box-quiz.js ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Created by Tu on 30/03/2015.
3
+ */
4
+ ;
5
+ (function ($) {
6
+
7
+ $(document).ready(function () {
8
+ if (typeof Backbone == 'undefined') return;
9
+ var LP_Quiz_Question_Model = window.LP_Quiz_Question_Model = Backbone.Model.extend({})
10
+
11
+ var LP_Quiz_Question_View = window.LP_Quiz_Question_View = Backbone.View.extend({
12
+ el : 'body',
13
+ events : {
14
+ 'click #learn-press-button-add-question': 'showListQuestions',
15
+ 'keyup #lp-modal-quiz-questions input[name="lp-item-name"]': 'searchItem',
16
+ 'click #lp-modal-quiz-questions input[type="checkbox"]': 'toggleAddItemButtonState',
17
+ 'change #lp-modal-quiz-questions input[type="checkbox"]': 'toggleAddItemButtonState',
18
+ 'click #lp-modal-quiz-questions .lp-add-item': 'addItemToQuiz',
19
+ 'keyup input[name="lp-new-question-name"]': 'toggleAddButtonState',
20
+ 'keydown .no-submit': 'preventSubmitForm',
21
+ 'click .lp-button-add-question': 'addNewItem'
22
+ },
23
+ initialize: function () {
24
+ $('#learn-press-list-questions').sortable({
25
+ handle: '.quiz-question-actions .move',
26
+ axis: 'y'
27
+ });
28
+ _.bindAll( this, 'addItemsToSection', 'getSelectedItems' );
29
+ LearnPress.Hook.addAction( 'learn_press_message_box_before_resize', this.resetModalSearch);
30
+ LearnPress.Hook.addAction( 'learn_press_message_box_resize', this.updateModalSearch);
31
+ LearnPress.Hook.addFilter( 'learn_press_modal_search_items_exclude', this.getSelectedItems );
32
+
33
+ $(document).on('learn_press_modal_search_items_response', this.addItemsToSection );
34
+ },
35
+ updateModalSearch: function(height, $app){
36
+ $('.lp-modal-search ul.lp-list-items').css('height', height - 120).css('overflow', 'auto');
37
+ },
38
+ resetModalSearch: function($app){
39
+ $('.lp-modal-search ul.lp-list-items').css('height', '').css('overflow', '')
40
+ },
41
+ toggleAddButtonState: function(e){
42
+ LearnPress.log(e.target.value)
43
+ if((e.target.value+'').length == 0){
44
+ $('.lp-button-add-question').addClass('disabled')
45
+ }else{
46
+ $('.lp-button-add-question').removeClass('disabled')
47
+ }
48
+ if(e.keyCode == 13){
49
+ $(e.target).siblings('.lp-button-add-question').trigger('click')
50
+ }
51
+ },
52
+ preventSubmitForm: function(e){
53
+ if(e.keyCode == 13){
54
+ return false;
55
+ }
56
+ },
57
+ showListQuestions: function(){
58
+ var $form = LearnPress.ModalSearchItems( {
59
+ template: 'tmpl-learn-press-search-items',
60
+ type: 'lp_question',
61
+ context: 'quiz-items',
62
+ context_id: $('#post_ID').val(),
63
+ exclude: this.getSelectedItems()
64
+ } );
65
+ LearnPress.MessageBox.show($form.$el);
66
+ $form.$el.find('header input').focus();
67
+
68
+ return;
69
+ var $form = $('#lp-modal-quiz-questions'),
70
+ $button = $form.find('.lp-add-item');
71
+ if ($form.length == 0) {
72
+ $form = $(wp.template('lp-modal-quiz-questions')());
73
+ }
74
+
75
+ LearnPress.MessageBox.show($form);
76
+ $form.find('[name="lp-item-name"]').focus().trigger('keyup');
77
+ $button.html($button.attr('data-text'));
78
+ },
79
+ searchItem: function(e){
80
+ var that = this,
81
+ $input = $(e.target);
82
+ if($input.val() == $input.data('search-term')){
83
+ return;
84
+ }
85
+ $input.data('search-term', $input.val() );
86
+ var $form = $input.closest('.lp-modal-search'),
87
+ text = $input.val().replace(/\\q\?[\s]*/ig, ''),
88
+ $button = $form.find('.lp-add-item'),
89
+ timer = $input.data('timer'),
90
+ _search = function(){
91
+ $.ajax({
92
+ url: LearnPress_Settings.ajax,
93
+ data: {
94
+ action: 'learnpress_search_questions',
95
+ quiz_id: $('#post_ID').val(),
96
+ term: text,
97
+ exclude: that.getAddedQuestions()
98
+ },
99
+ dataType: 'text',
100
+ success: function(response){
101
+ response = LearnPress.parseJSON(response);
102
+ LearnPress.log(response);
103
+ $form.find('.lp-list-items').html(response.html).removeClass('lp-ajaxload');
104
+ $(window).trigger('resize');
105
+ }
106
+ });
107
+ };
108
+ $form.find('.lp-list-items').html('').addClass('lp-ajaxload');
109
+ $button.html( $button.attr('data-text')).prop('disabled', true);
110
+ timer && clearTimeout(timer);
111
+ timer = setTimeout(_search, 300);
112
+ $input.data('timer', timer);
113
+ $(window).trigger('resize');
114
+
115
+ },
116
+ toggleAddItemButtonState: function(e){
117
+ var $form = $(e.target).closest('.lp-modal-search'),
118
+ selected = $form.find('.lp-list-items li:visible input:checked'),
119
+ $button = $form.find('.lp-add-item');
120
+ if( selected.length ){
121
+ $button.removeAttr('disabled').html($button.attr('data-text')+' (+'+selected.length+')');
122
+ }else{
123
+ $button.attr('disabled', true).html($button.attr('data-text'));
124
+ }
125
+ },
126
+ getSelectedItems: function( exclude ){
127
+ return this.$('.learn-press-question[data-id]').map(function(){return ($(this).attr('data-id'))}).filter(function(i, c){return c > 0}).get();
128
+ },
129
+ addItemsToSection: function(e, $view, $items) {
130
+ var that = this,
131
+ selected = $items;
132
+ selected.each(function () {
133
+ var $li = $(this);//.closest('li').addClass('selected'),
134
+ args = $li.dataToJSON();
135
+ that.addQuestion(args);
136
+ $li.remove();
137
+ });
138
+ },
139
+ addQuestion: function (args) {
140
+ args = $.extend({
141
+ id : 0,
142
+ type: null,
143
+ name: null
144
+ }, args);
145
+ if (!args.id && !args.type) {
146
+ alert('ERROR');
147
+ return;
148
+ }
149
+ var that = this,
150
+ post_data = $.extend({
151
+ action: 'learnpress_add_quiz_question',
152
+ quiz_id: $('#post_ID').val()
153
+ }, args);
154
+
155
+ post_data = LearnPress.Hook.applyFilters( 'LearnPress.add_question_post_data', post_data );
156
+
157
+ $.ajax({
158
+ url : LearnPress_Settings.ajax,
159
+ dataType: 'html',
160
+ type : 'post',
161
+ data : post_data,
162
+ success : function (response) {
163
+ response = LearnPress.parseJSON(response);
164
+ var $newQuestion = $(response.html);
165
+ $('#learn-press-list-questions').append($newQuestion);
166
+ that.$('#lp-modal-quiz-questions li[data-id="'+response.id+'"]').addClass('selected hide-if-js');
167
+ //LearnPress.Question._hideQuestion( args.id )
168
+ LearnPress.Hook.doAction( 'learn_press_add_quiz_question', $newQuestion, args);
169
+ }
170
+ });
171
+ },
172
+ addNewItem: function(e){
173
+ e.preventDefault();
174
+ var $target = $(e.target),
175
+ $form = $target.closest('.lp-modal-search'),
176
+ $input = this.$('input[name="lp-new-question-name"]'),
177
+ type = null;
178
+ if($target.is('a')){
179
+ type = $target.attr('data-type');
180
+ $target = $target.closest('.lp-button-add-question');
181
+ }else{
182
+ if(!$target.is('.lp-button-add-question')){
183
+ $target = $target.closest('.lp-button-add-question');
184
+ }
185
+ type = $target.find('ul > li > a:first').attr('data-type');
186
+ }
187
+ if($target.hasClass('disabled')){
188
+ return;
189
+ }
190
+ if( ($input.val()+'').length == 0 ){
191
+ alert('Please enter question name');
192
+ $input.focus();
193
+ return;
194
+ }
195
+ this.addQuestion({
196
+ type: type,
197
+ name: $input.val()
198
+ });
199
+ $input.focus().val('').trigger('keyup')
200
+ },
201
+ addItemToQuiz: function(e){
202
+ var that = this,
203
+ $form = $(e.target).closest('.lp-modal-search'),
204
+ selected = $form.find('li:visible input:checked'),
205
+ $section = $form.data('section');
206
+ selected.each(function(){
207
+ var $li = $(this).closest('li').addClass('selected'),
208
+ args = $li.dataToJSON();
209
+ /*$item = that.createItem( args, $section );
210
+ $item.removeClass('lp-item-empty');*/
211
+ that.addQuestion({id: $(this).val()});
212
+ });
213
+ $form.remove();
214
+ LearnPress.MessageBox.hide();
215
+ },
216
+ createItem: function(args, $section){
217
+ var tmpl = wp.template('quiz-question'),
218
+ $item = $(tmpl(args));
219
+ if( $section ) {
220
+ var $last = $section.find('.curriculum-section-items li:last');
221
+ $item.insertBefore($last);
222
+ }
223
+ return $item;
224
+ },
225
+ getAddedQuestions: function(){
226
+ var ids =
227
+ this.$('.learn-press-question')
228
+ .map(function(){
229
+ return parseInt($(this).attr('data-id'))
230
+ }).get();
231
+ return ids;
232
+ }
233
+ });
234
+
235
+ new LP_Quiz_Question_View(new LP_Quiz_Question_Model());
236
+ });
237
+
238
+ return
239
+ var $doc = $(document),
240
+ $body = $(document.body);
241
+
242
+ function addNewQuestion() {
243
+ var type = $('#lpr-quiz-question-type').val();
244
+ if (!type) {
245
+ // warning
246
+ return;
247
+ }
248
+ var data = {
249
+ action : 'lpr_quiz_question_add',
250
+ quiz_id: lpr_quiz_id,
251
+ type : type
252
+ };
253
+ $.post(ajaxurl, data, function (res) {
254
+ var $question = $(res)
255
+ $('#lpr-quiz-questions').append($question);
256
+ lprHook.doAction('lpr_admin_quiz_question_html', $question, type);
257
+
258
+ $('#lpr-quiz-question-type').val('')
259
+ }, 'text');
260
+ }
261
+
262
+ function _ready() {
263
+ $('#lpr-quiz-question-add').click(addNewQuestion);
264
+ }
265
+
266
+ $doc.ready(_ready);
267
+
268
+ })(jQuery)
assets/js/admin/modal-search-items.js ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*global jQuery, Backbone, _ */
2
+ ( function ($, Backbone, _) {
3
+ 'use strict';
4
+
5
+ LearnPress.ModalSearchItems = function (options) {
6
+ return new LearnPress.ModalSearchItems.View(options);
7
+ };
8
+
9
+ LearnPress.ModalSearchItems.View = Backbone.View.extend({
10
+ tagName : 'div',
11
+ id : 'learn-press-modal-search-items',
12
+ options : {
13
+ template: 'tmpl-learn-press-search-items',
14
+ type : ''
15
+ },
16
+ events : {
17
+ 'click .close-modal' : '_closeModal',
18
+ 'click .lp-add-item' : '_addItems',
19
+ 'keydown' : 'keyboardActions',
20
+ 'click input[type="checkbox"]': '_toggleAddItemButtonState'
21
+ },
22
+ searchTimer: null,
23
+ searchTerm: null,
24
+ initialize : function (options) {
25
+ var that = this;
26
+ this.options = options;
27
+ _.bindAll(this, 'render');
28
+ this.render();
29
+ LearnPress.Hook
30
+ .addAction('learn_press_message_box_before_resize', function () {
31
+ that.$('article').css('height', '');
32
+ })
33
+ .addAction('learn_press_message_box_resize', function (height, app) {
34
+ that.$('article').css({
35
+ height: height - 135
36
+ });
37
+ });
38
+ },
39
+ render : function () {
40
+ this.$el.attr({
41
+ tabindex: 0,
42
+ 'data-tmpl': this.options.template
43
+ }).append(LearnPress.template(this.options.template));
44
+
45
+ $(document.body).css({
46
+ 'overflow': 'hidden'
47
+ }).append(this.$el);
48
+ this.search({
49
+ exclude: this.options.exclude
50
+ });
51
+
52
+ $(document.body).trigger('learn_press_modal_search_items_loaded', this);
53
+ },
54
+ _toggleAddItemButtonState: function (e) {
55
+ var
56
+ $selected = this.$('li input:checked'),
57
+ $button = this.$('.lp-add-item');
58
+ if ($selected.length) {
59
+ $button.removeAttr('disabled').html($button.attr('data-text') + ' (+' + $selected.length + ')');
60
+ } else {
61
+ $button.attr('disabled', true).html($button.attr('data-text'));
62
+ }
63
+ },
64
+ _search : function () {
65
+
66
+ },
67
+ _fetchItems : function (response) {
68
+ this.$('article .lp-list-items').removeClass('lp-ajaxload').html(response.html);
69
+ LearnPress.log(response.html);
70
+ this.refreshModal();
71
+ $(document.body).trigger('learn_press_modal_search_items_fetch', this);
72
+ },
73
+ search : function (args) {
74
+ var that = this;
75
+ this.$('article ul').addClass('lp-ajaxload');
76
+ this.refreshModal();
77
+ args = $.extend({
78
+ term : '',
79
+ exclude: ''
80
+ }, args || {});
81
+ $.ajax({
82
+ url : LearnPress_Settings.ajax,
83
+ data : {
84
+ action : 'learnpress_modal_search_items',
85
+ type : this.options.type,
86
+ term : args.term,
87
+ exclude: args.exclude,
88
+ context: this.options.context,
89
+ context_id: this.options.context_id
90
+ },
91
+ type : 'get',
92
+ dataType: 'text',
93
+ success : function (response) {
94
+ response = LearnPress.parseJSON(response);
95
+ that._fetchItems(response);
96
+ }
97
+ })
98
+ },
99
+ _closeModal : function (e) {
100
+ e.preventDefault();
101
+ $(document.body).trigger('learn_press_modal_search_items_before_remove', this);
102
+ this.undelegateEvents();
103
+ $(document).off('focusin');
104
+ $(document.body).css({
105
+ 'overflow': 'auto'
106
+ });
107
+ this.remove();
108
+ LearnPress.MessageBox.hide();
109
+ $(document.body).trigger('learn_press_modal_search_items_removed', this);
110
+ },
111
+ _addItems : function (e) {
112
+ $(document.body).trigger('learn_press_modal_search_items_response', [this, this.getItems()]);
113
+ this.refreshModal(e);
114
+ },
115
+ refreshModal: function(e){
116
+ this._toggleAddItemButtonState(e);
117
+ $(window).trigger('resize.message-box');
118
+ },
119
+ getItems : function () {
120
+ return this.$('li input:checked').map(function(){return $(this).closest('li')});
121
+ },
122
+ keyboardActions : function (e) {
123
+ var that = this,
124
+ button = e.keyCode || e.which;
125
+ // Enter key
126
+ if (e.target.tagName && ( e.target.tagName.toLowerCase() === 'input' || e.target.tagName.toLowerCase() === 'textarea' ) && e.target.value != this.searchTerm ) {
127
+ this.searchTimer && clearTimeout(this.searchTimer);
128
+ this.searchTimer = setTimeout(function(){
129
+ that.search({
130
+ term: e.target.value,
131
+ exclude: LearnPress.Hook.applyFilters( 'learn_press_modal_search_items_exclude', that.options.exclude, that)
132
+ });
133
+ }, 300);
134
+ this.searchTerm = e.target.value;
135
+ }
136
+
137
+ // ESC key
138
+ if (27 === button) {
139
+ this._closeModal(e);
140
+ }
141
+ }
142
+ });
143
+
144
+ }(jQuery, Backbone, _));
assets/js/admin/question.min.js ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ if(typeof window.LearnPress=='undefined'){window.LearnPress={}};(function($){var $doc=$(document);LearnPress.Hook.addFilter('before_add_question_option',function($el,args){return !0}).addAction('question_option_added',function($el){})
2
+ LearnPress.Question={_getEmptyOption:function(question_id){var $options=$('#learn-press-list-options-'+question_id+' tbody .lp-list-option-empty');return $options.length?$options:!1},addOption:function(question_id,args){var $newOption=this._getEmptyOption(question_id);args=$.extend({autoFocus:!0},args||{});if($newOption){}else{var templateArgs={question_id:question_id,text:'',value:LearnPress.uniqueId()},tmpl=wp.template($('#learn-press-question-'+question_id).attr('data-type')+'-option'),$list=$('#learn-press-list-options-'+question_id+' tbody');$newOption=$(tmpl(templateArgs));if(LearnPress.Hook.applyFilters('before_add_question_option',$newOption,args)!==!1){$list.append($newOption);LearnPress.Hook.doAction('question_option_added',$newOption,args)}}
3
+ if($newOption&&args.autoFocus){$newOption.find('.lp-answer-text').focus()}},removeOption:function(theOption){var $theOption=null;if($.type(theOption)=='integer'){$theOption=$('lp-list-option-'+theOption)}else{$theOption=$(theOption)}
4
+ if(LearnPress.Hook.applyFilters('before_remove_question_option',!0,$theOption)!==!1){$theOption.remove();LearnPress.Hook.doAction('question_option_removed',$theOption)}},addQuestion:function(args){args=$.extend({id:0,type:null,name:null},args);if(!args.id&&!args.type){alert('ERROR');return}
5
+ var post_data=$.extend({action:'learnpress_add_question'},args);post_data=LearnPress.Hook.applyFilters('LearnPress.add_question_post_data',post_data);$.ajax({url:LearnPress_Settings.ajax,dataType:'html',type:'post',data:post_data,success:function(response){response=LearnPress.parseJSON(response);var $newQuestion=$(response.html);$('#learn-press-list-questions').append($newQuestion);LearnPress.Question._hideQuestion(args.id)
6
+ LearnPress.Hook.doAction('learn_press_add_quiz_question',$newQuestion,args)}})},_hideQuestion:function(question){if($.type(question)=='number'){question=$('#learn-press-dropdown-questions .question a[data-id="'+question+'"]').parent()}
7
+ $(question).addClass('added')},_showQuestion:function(question){if($.type(question)=='number'){question=$('#learn-press-dropdown-questions .question a[data-id="'+question+'"]').parent()}
8
+ $(question).removeClass('added')}};function updateHiddenQuestions(hidden){if(hidden==undefined){hidden=[];var len=$('.quiz-question-content').each(function(){if($(this).is(':hidden')){hidden.push($('.learn-press-question',this).attr('data-id'))}}).length;if(hidden.length==0){$('.questions-toggle a[data-action="collapse"]').show().siblings('a[data-action="expand"]').hide()}else if(hidden.length==len){$('.questions-toggle a[data-action="collapse"]').hide().siblings('a[data-action="expand"]').show()}}
9
+ $.ajax({url:LearnPress_Settings.ajax,data:{action:'learnpress_update_quiz_question_state',quiz_id:$('#post_ID').val(),hidden:hidden},success:function(){}});return hidden}
10
+ LearnPress.sortableQuestionAnswers=function($questions){$questions.find('.lp-list-options tbody').sortable({handle:'.lp-move-list-option',axis:'y',start:function(e,ui){var $heads=ui.item.parent().closest('table').find('tr > th');ui.item.children().each(function(i){$(this).css({width:$heads.eq(i).width()})})
11
+ var $this=$(this),cols=$this.find('tr:first').children().length;$this.find('.ui-sortable-placeholder td:gt(0)').remove();$this.find('.ui-sortable-placeholder td:eq(0)').attr('colspan',cols)},stop:function(){}})}
12
+ function _ready(){$('#learn-press-toggle-questions').on('click',function(){$(this).siblings('ul').toggle()});$doc.on('click','#learn-press-dropdown-questions ul li a',function(e){e.preventDefault();LearnPress.Question.addQuestion({id:$(this).data('id')});$(this).closest('ul').hide()});$('#learn-press-button-add-question').on('click',function(){});$doc.on('click','.add-question-option-button',function(e,data){var question_id=$(this).attr('data-id');LearnPress.Question.addOption(question_id,data)}).on('click','.lp-remove-list-option',function(){var $option=$(this).closest('tr');LearnPress.Question.removeOption($option)}).on('change','.lp-dropdown-question-types',function(){var $select=$(this),$wrap=$select.closest('.learn-press-question'),questionId=$wrap.data('id'),from=$select.data('selected'),to=this.value,_do=function(){LearnPress.MessageBox.blockUI();$.ajax({url:LearnPress_Settings.ajax,type:'post',dataType:'html',data:{action:'learnpress_convert_question_type',question_id:questionId,from:from,to:to,data:$('#post').serialize()},success:function(response){response=LearnPress.parseJSON(response);var $newOptions=$(response.html),$question=$('#learn-press-question-'+questionId),$icon=$question.closest('.quiz-question').find('.quiz-question-icon img');$question.replaceWith($newOptions);if($icon.length){$icon.replaceWith(response.icon)}
13
+ LearnPress.Hook.doAction('learn_press_convert_question_type',questionId,from,to,$newOptions);LearnPress.MessageBox.hide()}})};LearnPress.MessageBox.show('Are you sure you want to convert to new type?',{buttons:'yesNo',events:{onYes:function(){_do()},onNo:function(){$select.val(from)}}});return}).on('click','.questions-toggle a',function(e){e.preventDefault();var action=$(this).attr('data-action');switch(action){case 'expand':var $items=$('.quiz-question'),len=$items.length,i=0;$(this).hide().siblings('a[data-action="collapse"]').show();$items.removeClass('is-hidden').find('.quiz-question-content').slideDown(function(){if(++i==len){updateHiddenQuestions([])}});$items.find('a[data-action="collapse"]').show();$items.find('a[data-action="expand"]').hide();break;case 'collapse':var $items=$('.quiz-question'),len=$items.length,i=0,hidden=[];$(this).hide().siblings('a[data-action="expand"]').show();$items.addClass('is-hidden').find('.quiz-question-content').slideUp(function(){hidden.push($('.learn-press-question',this).attr('data-id'));if(++i==len){updateHiddenQuestions(hidden)}});$items.find('a[data-action="collapse"]').hide();$items.find('a[data-action="expand"]').show();break}}).on('click','.quiz-question-actions a',function(e){var $link=$(this),action=$link.attr('data-action');switch(action){case 'expand':$(this).hide().siblings('a[data-action="collapse"]').show().closest('.quiz-question').removeClass('is-hidden').find('.quiz-question-content').slideDown(function(){if(updateHiddenQuestions().length==0){}});break;case 'collapse':$(this).hide().siblings('a[data-action="expand"]').show().closest('.quiz-question').addClass('is-hidden').find('.quiz-question-content').slideUp(function(){updateHiddenQuestions()});break;case 'remove':LearnPress.MessageBox.show('Do you want to remove this question from quiz?',{buttons:'yesNo',data:$(this).closest('.quiz-question'),events:{onYes:function(instance){var $question=$(instance.data);$.ajax({url:$link.attr('href'),success:function(){$question.fadeOut(function(){$(this).remove()})}})}}})
14
+ break}
15
+ if(action){e.preventDefault()}}).on('keydown','.no-submit',function(e){if(e.keyCode==13){e.preventDefault();LearnPress.log('no submit form')}}).on('change keyup','.lp-answer-text',function(e){var $input=$(this),$option=$input.closest('.lp-list-option'),value=$input.val()+'';if(e.keyCode!=13){switch(e.keyCode){case 38:case 40:case 8:case 46:var pressed=$input.data('key-'+e.keyCode)||1;LearnPress.log('pressed:'+pressed)
16
+ if(pressed>1){if(e.keyCode==38){($prev=$input.findPrev('.key-nav'))&&$prev.focus();pressed=0}else if(e.keyCode==40){($next=$input.findNext('.key-nav'))&&$next.focus();pressed=0}else if(e.keyCode==8&&value.length==0){var $row=$input.closest('tr'),$prev=$row.prev();if($prev.length){$prev.find('.lp-answer-text').focus();$row.remove()}}else if(e.keyCode==46&&value.length==0){var $row=$input.closest('tr'),$next=$row.next();if(!$next.hasClass('lp-list-option-empty')){$next.find('.lp-answer-text').focus();$row.remove()}}
17
+ $input.data('key-'+e.keyCode,0)}else{if(e.keyCode==8||e.keyCode==46){if(value.length==0){$input.data('key-'+e.keyCode,pressed+1)}}else{$input.data('key-'+e.keyCode,pressed+1)}}
18
+ break}
19
+ if(value.length){$option.removeClass('lp-list-option-empty')}else{$option.addClass('lp-list-option-empty');return}}
20
+ var $wrap=$(this).closest('.learn-press-question'),$button=$wrap.find('.add-question-option-button');$button.trigger('click',{autoFocus:e.keyCode==13})})}
21
+ $(document).ready(_ready)})(jQuery)
assets/js/admin/settings.js ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function($){
2
+ var $doc = $(document);
3
+
4
+ function addPageToAllDropdowns( args ){
5
+ var position = $.inArray( args.ID + "", args.positions );
6
+ $('.learn-press-dropdown-pages').each(function() {
7
+ var $select = $(this),
8
+ $new_option = $('<option value="'+args.ID+'">'+args.name+'</option>')
9
+ if (position == 0) {
10
+ $('option', $select).each(function () {
11
+ if (parseInt($(this).val())) {
12
+ $new_option.insertBefore($(this));
13
+ return false;
14
+ }
15
+ })
16
+ } else if (position == args.positions.length - 1) {
17
+ $select.append($new_option);
18
+ } else {
19
+ $new_option.insertAfter($('option[value="' + args.positions[position - 1] + '"]', $select));
20
+ }
21
+ });
22
+ }
23
+
24
+ function _ready(){
25
+
26
+ $('.learn-press-dropdown-pages').each(function(){
27
+ $(this).change(function(){
28
+ var $select = $(this),
29
+ thisId = $select.attr('id'),
30
+ $actions = $select.siblings('.learn-press-quick-add-page-actions');
31
+
32
+ $actions.addClass('hide-if-js');
33
+ if( this.value != 'add_new_page' ){
34
+ if( parseInt(this.value) ){
35
+ $actions.find('a.edit-page').attr('href', 'post.php?post='+this.value+'&action=edit');
36
+ $actions.find('a.view-page').attr('href', LearnPress_Settings.siteurl + '?page_id='+this.value);
37
+ $actions.removeClass('hide-if-js');
38
+ $select.attr('data-selected', this.value);
39
+ }
40
+ return;
41
+ };
42
+ $select.attr('disabled', true);
43
+ $('.learn-press-quick-add-page-inline.'+thisId).removeClass('hide-if-js').find('input').focus().val('');
44
+ });
45
+ });
46
+
47
+ $doc.on('click', '.learn-press-quick-add-page-inline button', function(){
48
+ var $form = $(this).parent(),
49
+ $input = $form.find('input'),
50
+ $select = $form.siblings('select'),
51
+ page_name = $input.val();
52
+ if( ! page_name ){
53
+ alert( 'Please enter the name of page' );
54
+ $input.focus();
55
+ return;
56
+ }
57
+
58
+ $.ajax({
59
+ url: LearnPress_Settings.ajax,
60
+ data:{
61
+ action: 'learnpress_create_page',
62
+ page_name: page_name
63
+ },
64
+ type: 'post',
65
+ dataType: 'html',
66
+ success: function(response){
67
+ response = LearnPress.parseJSON(response);
68
+ if( response.page ){
69
+ addPageToAllDropdowns({
70
+ ID: response.page.ID,
71
+ name: response.page.post_title,
72
+ positions: response.positions
73
+ });
74
+ $select.val(response.page.ID).removeAttr('disabled').focus().trigger('change');
75
+ $form.addClass('hide-if-js');
76
+ }else if(response.error){
77
+ alert(response.error);
78
+ $select.removeAttr('disabled')
79
+ }
80
+
81
+ }
82
+ });
83
+ }).on('click', '.learn-press-quick-add-page-inline a', function(e){
84
+ e.preventDefault();
85
+ var $select = $(this).parent().addClass('hide-if-js').siblings('select');
86
+ $select.val( $select.attr('data-selected')).removeAttr('disabled').trigger('change');
87
+ })
88
+ }
89
+
90
+ $doc.ready(_ready);
91
+ })(jQuery);
assets/js/admin/statistic.js ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function ($) {
2
+ $.fn.LP_Chart_Line = function (data, config) {
3
+ return $.each(this, function () {
4
+ var $elem = $(this),
5
+ $canvas = $('<canvas />');
6
+ $elem.html('');
7
+ $canvas.appendTo($elem);
8
+ new Chart($canvas.get(0).getContext('2d')).Line(data, config);
9
+ });
10
+ //
11
+ }
12
+
13
+ $.fn.LP_Statistic_Users = function () {
14
+ return $.each(this, function () {
15
+ var $buttons = $('.chart-buttons button').on('click', function () {
16
+ var $button = $(this),
17
+ type = $button.data('type'),
18
+ from = '', to = '',
19
+ $container = $('#learn-press-chart');
20
+ $buttons.not(this).not('[data-type="user-custom-time"]').prop('disabled', false);
21
+ if (type == 'user-custom-time') {
22
+ from = $('#user-custom-time input[name="from"]').val();
23
+ to = $('#user-custom-time input[name="to"]').val();
24
+
25
+ if (from == '' || to == '') {
26
+ return false;
27
+ }
28
+ } else {
29
+ $button.prop('disabled', true)
30
+ }
31
+ $container.addClass('loading')
32
+ $.ajax({
33
+ url : 'admin-ajax.php',
34
+ data : {
35
+ action: 'learnpress_load_chart',
36
+ type : type,
37
+ range : [from, to]
38
+ },
39
+ dataType: 'text',
40
+ success : function (response) {
41
+ response = LearnPress.parseJSON(response);
42
+ $container.LP_Chart_Line(response, LP_Chart_Config);
43
+ $container.removeClass('loading');
44
+ console.log(response.sql)
45
+ }
46
+ });
47
+ return false;
48
+ }),
49
+ $inputs = $('.chart-buttons #user-custom-time input[type="text"]').change(function () {
50
+ var _valid_date = function () {
51
+ if (new Date($inputs[0].value) < new Date($inputs[1].value)) {
52
+ return true;
53
+ }
54
+ }
55
+ $buttons.filter('[data-type="user-custom-time"]').prop('disabled', $inputs.filter(function () {
56
+ return this.value == '';
57
+ }).get().length || !_valid_date());
58
+ })
59
+ });
60
+ }
61
+
62
+ $.fn.LP_Statistic_Courses = function () {
63
+ return $.each(this, function () {
64
+ var $buttons = $('.chart-buttons button').on('click', function () {
65
+ var $button = $(this),
66
+ type = $button.data('type'),
67
+ from = '', to = '',
68
+ $container = $('#learn-press-chart');
69
+ $buttons.not(this).not('[data-type="course-custom-time"]').prop('disabled', false);
70
+ if (type == 'course-custom-time') {
71
+ from = $('#course-custom-time input[name="from"]').val();
72
+ to = $('#course-custom-time input[name="to"]').val();
73
+
74
+ if (from == '' || to == '') {
75
+ return false;
76
+ }
77
+ } else {
78
+ $button.prop('disabled', true)
79
+ }
80
+ $container.addClass('loading')
81
+ $.ajax({
82
+ url : 'admin-ajax.php',
83
+ data : {
84
+ action: 'learnpress_load_chart',
85
+ type : type,
86
+ range : [from, to]
87
+ },
88
+ dataType: 'text',
89
+ success : function (response) {
90
+ response = LearnPress.parseJSON(response);
91
+ $container.LP_Chart_Line(response, LP_Chart_Config);
92
+ $container.removeClass('loading');
93
+ console.log(response.sql)
94
+ }
95
+ });
96
+ return false;
97
+ }),
98
+ $inputs = $('.chart-buttons #course-custom-time input[type="text"]').change(function () {
99
+ var _valid_date = function () {
100
+ if (new Date($inputs[0].value) < new Date($inputs[1].value)) {
101
+ return true;
102
+ }
103
+ }
104
+ $buttons.filter('[data-type="course-custom-time"]').prop('disabled', $inputs.filter(function () {
105
+ return this.value == '';
106
+ }).get().length || !_valid_date());
107
+ })
108
+ });
109
+ }
110
+
111
+ $.fn.LP_Statistic_Orders = function () {
112
+ return $.each(this, function () {
113
+ var $buttons = $('.chart-buttons button').on('click', function () {
114
+ var $button = $(this),
115
+ type = $button.data('type'),
116
+ from = '', to = '',
117
+ $container = $('#learn-press-chart');
118
+ $buttons.not(this).not('[data-type="order-custom-time"]').prop('disabled', false);
119
+ if (type == 'order-custom-time') {
120
+ from = $('#order-custom-time input[name="from"]').val();
121
+ to = $('#order-custom-time input[name="to"]').val();
122
+
123
+ if (from == '' || to == '') {
124
+ return false;
125
+ }
126
+ } else {
127
+ $button.prop('disabled', true)
128
+ }
129
+ $container.addClass('loading')
130
+ $.ajax({
131
+ url : 'admin-ajax.php',
132
+ data : {
133
+ action: 'learnpress_load_chart',
134
+ type : type,
135
+ range : [from, to]
136
+ },
137
+ dataType: 'text',
138
+ success : function (response) {
139
+ response = LearnPress.parseJSON(response);
140
+ $container.LP_Chart_Line(response, LP_Chart_Config);
141
+ $container.removeClass('loading');
142
+ console.log(response.sql)
143
+ }
144
+ });
145
+ return false;
146
+ }),
147
+ $inputs = $('.chart-buttons #order-custom-time input[type="text"]').change(function () {
148
+ var _valid_date = function () {
149
+ if (new Date($inputs[0].value) < new Date($inputs[1].value)) {
150
+ return true;
151
+ }
152
+ }
153
+ $buttons.filter('[data-type="order-custom-time"]').prop('disabled', $inputs.filter(function () {
154
+ return this.value == '';
155
+ }).get().length || !_valid_date());
156
+ })
157
+ });
158
+ }
159
+ ;
160
+ $(document).ready(function () {
161
+ if (typeof $.fn.datepicker != 'undefined') {
162
+ $(".date-picker").datepicker({
163
+ dateFormat: 'yy/mm/dd'
164
+ });
165
+ }
166
+ $('.learn-press-statistic-users').LP_Statistic_Users();
167
+ $('.learn-press-statistic-courses').LP_Statistic_Courses();
168
+ $('.learn-press-statistic-orders').LP_Statistic_Orders();
169
+ })
170
+ return;
171
+
172
+ var student_chart;
173
+ window.drawStudentsChart = drawStudentsChart = function (data, config) {
174
+ var $student_chart = $("#lpr-chart-students").clone().attr('style', '').removeAttr("width").removeAttr('height');
175
+ $("#lpr-chart-students").replaceWith($student_chart);
176
+ $student_chart = $student_chart[0].getContext("2d");
177
+ student_chart = new Chart($student_chart).Line(data, config);
178
+ }
179
+ if (typeof last_seven_days == 'undefined') return;
180
+ drawStudentsChart(last_seven_days, config);
181
+
182
+
183
+ var courses_chart;
184
+ window.drawCoursesChart = drawCoursesChart = function (data, config) {
185
+ var $courses_chart = $("#lpr-chart-courses").clone().attr('style', '').removeAttr("width").removeAttr('height');
186
+ $("#lpr-chart-courses").replaceWith($courses_chart);
187
+ $courses_chart = $courses_chart[0].getContext("2d");
188
+ courses_chart = new Chart($courses_chart).Bar(data, config);
189
+ }
190
+ if (typeof data == 'undefined') return;
191
+
192
+ drawCoursesChart(data, config);
193
+
194
+ })(jQuery);
195
+
assets/js/chart.min.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Chart.js
3
+ * http://chartjs.org/
4
+ * Version: 1.0.2
5
+ *
6
+ * Copyright 2015 Nick Downie
7
+ * Released under the MIT license
8
+ * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
9
+ */
10
+ (function(){"use strict";var t=this,i=t.Chart,e=function(t){this.canvas=t.canvas,this.ctx=t;var i=function(t,i){return t["offset"+i]?t["offset"+i]:document.defaultView.getComputedStyle(t).getPropertyValue(i)},e=this.width=i(t.canvas,"Width"),n=this.height=i(t.canvas,"Height");t.canvas.width=e,t.canvas.height=n;var e=this.width=t.canvas.width,n=this.height=t.canvas.height;return this.aspectRatio=this.width/this.height,s.retinaScale(this),this};e.defaults={global:{animation:!0,animationSteps:60,animationEasing:"easeOutQuart",showScale:!0,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleIntegersOnly:!0,scaleBeginAtZero:!1,scaleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",responsive:!1,maintainAspectRatio:!0,showTooltips:!0,customTooltips:!1,tooltipEvents:["mousemove","touchstart","touchmove","mouseout"],tooltipFillColor:"rgba(0,0,0,0.8)",tooltipFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipFontSize:14,tooltipFontStyle:"normal",tooltipFontColor:"#fff",tooltipTitleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipTitleFontSize:14,tooltipTitleFontStyle:"bold",tooltipTitleFontColor:"#fff",tooltipYPadding:6,tooltipXPadding:6,tooltipCaretSize:8,tooltipCornerRadius:6,tooltipXOffset:10,tooltipTemplate:"<%if (label){%><%=label%>: <%}%><%= value %>",multiTooltipTemplate:"<%= value %>",multiTooltipKeyBackground:"#fff",onAnimationProgress:function(){},onAnimationComplete:function(){}}},e.types={};var s=e.helpers={},n=s.each=function(t,i,e){var s=Array.prototype.slice.call(arguments,3);if(t)if(t.length===+t.length){var n;for(n=0;n<t.length;n++)i.apply(e,[t[n],n].concat(s))}else for(var o in t)i.apply(e,[t[o],o].concat(s))},o=s.clone=function(t){var i={};return n(t,function(e,s){t.hasOwnProperty(s)&&(i[s]=e)}),i},a=s.extend=function(t){return n(Array.prototype.slice.call(arguments,1),function(i){n(i,function(e,s){i.hasOwnProperty(s)&&(t[s]=e)})}),t},h=s.merge=function(){var t=Array.prototype.slice.call(arguments,0);return t.unshift({}),a.apply(null,t)},l=s.indexOf=function(t,i){if(Array.prototype.indexOf)return t.indexOf(i);for(var e=0;e<t.length;e++)if(t[e]===i)return e;return-1},r=(s.where=function(t,i){var e=[];return s.each(t,function(t){i(t)&&e.push(t)}),e},s.findNextWhere=function(t,i,e){e||(e=-1);for(var s=e+1;s<t.length;s++){var n=t[s];if(i(n))return n}},s.findPreviousWhere=function(t,i,e){e||(e=t.length);for(var s=e-1;s>=0;s--){var n=t[s];if(i(n))return n}},s.inherits=function(t){var i=this,e=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return i.apply(this,arguments)},s=function(){this.constructor=e};return s.prototype=i.prototype,e.prototype=new s,e.extend=r,t&&a(e.prototype,t),e.__super__=i.prototype,e}),c=s.noop=function(){},u=s.uid=function(){var t=0;return function(){return"chart-"+t++}}(),d=s.warn=function(t){window.console&&"function"==typeof window.console.warn&&console.warn(t)},p=s.amd="function"==typeof define&&define.amd,f=s.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},g=s.max=function(t){return Math.max.apply(Math,t)},m=s.min=function(t){return Math.min.apply(Math,t)},v=(s.cap=function(t,i,e){if(f(i)){if(t>i)return i}else if(f(e)&&e>t)return e;return t},s.getDecimalPlaces=function(t){return t%1!==0&&f(t)?t.toString().split(".")[1].length:0}),S=s.radians=function(t){return t*(Math.PI/180)},x=(s.getAngleFromPoint=function(t,i){var e=i.x-t.x,s=i.y-t.y,n=Math.sqrt(e*e+s*s),o=2*Math.PI+Math.atan2(s,e);return 0>e&&0>s&&(o+=2*Math.PI),{angle:o,distance:n}},s.aliasPixel=function(t){return t%2===0?0:.5}),y=(s.splineCurve=function(t,i,e,s){var n=Math.sqrt(Math.pow(i.x-t.x,2)+Math.pow(i.y-t.y,2)),o=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),a=s*n/(n+o),h=s*o/(n+o);return{inner:{x:i.x-a*(e.x-t.x),y:i.y-a*(e.y-t.y)},outer:{x:i.x+h*(e.x-t.x),y:i.y+h*(e.y-t.y)}}},s.calculateOrderOfMagnitude=function(t){return Math.floor(Math.log(t)/Math.LN10)}),C=(s.calculateScaleRange=function(t,i,e,s,n){var o=2,a=Math.floor(i/(1.5*e)),h=o>=a,l=g(t),r=m(t);l===r&&(l+=.5,r>=.5&&!s?r-=.5:l+=.5);for(var c=Math.abs(l-r),u=y(c),d=Math.ceil(l/(1*Math.pow(10,u)))*Math.pow(10,u),p=s?0:Math.floor(r/(1*Math.pow(10,u)))*Math.pow(10,u),f=d-p,v=Math.pow(10,u),S=Math.round(f/v);(S>a||a>2*S)&&!h;)if(S>a)v*=2,S=Math.round(f/v),S%1!==0&&(h=!0);else if(n&&u>=0){if(v/2%1!==0)break;v/=2,S=Math.round(f/v)}else v/=2,S=Math.round(f/v);return h&&(S=o,v=f/S),{steps:S,stepValue:v,min:p,max:p+S*v}},s.template=function(t,i){function e(t,i){var e=/\W/.test(t)?new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+t.replace(/[\r\t\n]/g," ").split("<%").join(" ").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split(" ").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');"):s[t]=s[t];return i?e(i):e}if(t instanceof Function)return t(i);var s={};return e(t,i)}),w=(s.generateLabels=function(t,i,e,s){var o=new Array(i);return labelTemplateString&&n(o,function(i,n){o[n]=C(t,{value:e+s*(n+1)})}),o},s.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:1==(t/=1)?1:(e||(e=.3),s<Math.abs(1)?(s=1,i=e/4):i=e/(2*Math.PI)*Math.asin(1/s),-(s*Math.pow(2,10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e)))},easeOutElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:1==(t/=1)?1:(e||(e=.3),s<Math.abs(1)?(s=1,i=e/4):i=e/(2*Math.PI)*Math.asin(1/s),s*Math.pow(2,-10*t)*Math.sin(2*(1*t-i)*Math.PI/e)+1)},easeInOutElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:2==(t/=.5)?1:(e||(e=.3*1.5),s<Math.abs(1)?(s=1,i=e/4):i=e/(2*Math.PI)*Math.asin(1/s),1>t?-.5*s*Math.pow(2,10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e):s*Math.pow(2,-10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e)*.5+1)},easeInBack:function(t){var i=1.70158;return 1*(t/=1)*t*((i+1)*t-i)},easeOutBack:function(t){var i=1.70158;return 1*((t=t/1-1)*t*((i+1)*t+i)+1)},easeInOutBack:function(t){var i=1.70158;return(t/=.5)<1?.5*t*t*(((i*=1.525)+1)*t-i):.5*((t-=2)*t*(((i*=1.525)+1)*t+i)+2)},easeInBounce:function(t){return 1-w.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?7.5625*t*t:2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*w.easeInBounce(2*t):.5*w.easeOutBounce(2*t-1)+.5}}),b=s.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),P=s.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),L=(s.animationLoop=function(t,i,e,s,n,o){var a=0,h=w[e]||w.linear,l=function(){a++;var e=a/i,r=h(e);t.call(o,r,e,a),s.call(o,r,e),i>a?o.animationFrame=b(l):n.apply(o)};b(l)},s.getRelativePosition=function(t){var i,e,s=t.originalEvent||t,n=t.currentTarget||t.srcElement,o=n.getBoundingClientRect();return s.touches?(i=s.touches[0].clientX-o.left,e=s.touches[0].clientY-o.top):(i=s.clientX-o.left,e=s.clientY-o.top),{x:i,y:e}},s.addEvent=function(t,i,e){t.addEventListener?t.addEventListener(i,e):t.attachEvent?t.attachEvent("on"+i,e):t["on"+i]=e}),k=s.removeEvent=function(t,i,e){t.removeEventListener?t.removeEventListener(i,e,!1):t.detachEvent?t.detachEvent("on"+i,e):t["on"+i]=c},F=(s.bindEvents=function(t,i,e){t.events||(t.events={}),n(i,function(i){t.events[i]=function(){e.apply(t,arguments)},L(t.chart.canvas,i,t.events[i])})},s.unbindEvents=function(t,i){n(i,function(i,e){k(t.chart.canvas,e,i)})}),R=s.getMaximumWidth=function(t){var i=t.parentNode;return i.clientWidth},T=s.getMaximumHeight=function(t){var i=t.parentNode;return i.clientHeight},A=(s.getMaximumSize=s.getMaximumWidth,s.retinaScale=function(t){var i=t.ctx,e=t.canvas.width,s=t.canvas.height;window.devicePixelRatio&&(i.canvas.style.width=e+"px",i.canvas.style.height=s+"px",i.canvas.height=s*window.devicePixelRatio,i.canvas.width=e*window.devicePixelRatio,i.scale(window.devicePixelRatio,window.devicePixelRatio))}),M=s.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},W=s.fontString=function(t,i,e){return i+" "+t+"px "+e},z=s.longestText=function(t,i,e){t.font=i;var s=0;return n(e,function(i){var e=t.measureText(i).width;s=e>s?e:s}),s},B=s.drawRoundedRectangle=function(t,i,e,s,n,o){t.beginPath(),t.moveTo(i+o,e),t.lineTo(i+s-o,e),t.quadraticCurveTo(i+s,e,i+s,e+o),t.lineTo(i+s,e+n-o),t.quadraticCurveTo(i+s,e+n,i+s-o,e+n),t.lineTo(i+o,e+n),t.quadraticCurveTo(i,e+n,i,e+n-o),t.lineTo(i,e+o),t.quadraticCurveTo(i,e,i+o,e),t.closePath()};e.instances={},e.Type=function(t,i,s){this.options=i,this.chart=s,this.id=u(),e.instances[this.id]=this,i.responsive&&this.resize(),this.initialize.call(this,t)},a(e.Type.prototype,{initialize:function(){return this},clear:function(){return M(this.chart),this},stop:function(){return P(this.animationFrame),this},resize:function(t){this.stop();var i=this.chart.canvas,e=R(this.chart.canvas),s=this.options.maintainAspectRatio?e/this.chart.aspectRatio:T(this.chart.canvas);return i.width=this.chart.width=e,i.height=this.chart.height=s,A(this.chart),"function"==typeof t&&t.apply(this,Array.prototype.slice.call(arguments,1)),this},reflow:c,render:function(t){return t&&this.reflow(),this.options.animation&&!t?s.animationLoop(this.draw,this.options.animationSteps,this.options.animationEasing,this.options.onAnimationProgress,this.options.onAnimationComplete,this):(this.draw(),this.options.onAnimationComplete.call(this)),this},generateLegend:function(){return C(this.options.legendTemplate,this)},destroy:function(){this.clear(),F(this,this.events);var t=this.chart.canvas;t.width=this.chart.width,t.height=this.chart.height,t.style.removeProperty?(t.style.removeProperty("width"),t.style.removeProperty("height")):(t.style.removeAttribute("width"),t.style.removeAttribute("height")),delete e.instances[this.id]},showTooltip:function(t,i){"undefined"==typeof this.activeElements&&(this.activeElements=[]);var o=function(t){var i=!1;return t.length!==this.activeElements.length?i=!0:(n(t,function(t,e){t!==this.activeElements[e]&&(i=!0)},this),i)}.call(this,t);if(o||i){if(this.activeElements=t,this.draw(),this.options.customTooltips&&this.options.customTooltips(!1),t.length>0)if(this.datasets&&this.datasets.length>1){for(var a,h,r=this.datasets.length-1;r>=0&&(a=this.datasets[r].points||this.datasets[r].bars||this.datasets[r].segments,h=l(a,t[0]),-1===h);r--);var c=[],u=[],d=function(){var t,i,e,n,o,a=[],l=[],r=[];return s.each(this.datasets,function(i){t=i.points||i.bars||i.segments,t[h]&&t[h].hasValue()&&a.push(t[h])}),s.each(a,function(t){l.push(t.x),r.push(t.y),c.push(s.template(this.options.multiTooltipTemplate,t)),u.push({fill:t._saved.fillColor||t.fillColor,stroke:t._saved.strokeColor||t.strokeColor})},this),o=m(r),e=g(r),n=m(l),i=g(l),{x:n>this.chart.width/2?n:i,y:(o+e)/2}}.call(this,h);new e.MultiTooltip({x:d.x,y:d.y,xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,xOffset:this.options.tooltipXOffset,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,titleTextColor:this.options.tooltipTitleFontColor,titleFontFamily:this.options.tooltipTitleFontFamily,titleFontStyle:this.options.tooltipTitleFontStyle,titleFontSize:this.options.tooltipTitleFontSize,cornerRadius:this.options.tooltipCornerRadius,labels:c,legendColors:u,legendColorBackground:this.options.multiTooltipKeyBackground,title:t[0].label,chart:this.chart,ctx:this.chart.ctx,custom:this.options.customTooltips}).draw()}else n(t,function(t){var i=t.tooltipPosition();new e.Tooltip({x:Math.round(i.x),y:Math.round(i.y),xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,caretHeight:this.options.tooltipCaretSize,cornerRadius:this.options.tooltipCornerRadius,text:C(this.options.tooltipTemplate,t),chart:this.chart,custom:this.options.customTooltips}).draw()},this);return this}},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)}}),e.Type.extend=function(t){var i=this,s=function(){return i.apply(this,arguments)};if(s.prototype=o(i.prototype),a(s.prototype,t),s.extend=e.Type.extend,t.name||i.prototype.name){var n=t.name||i.prototype.name,l=e.defaults[i.prototype.name]?o(e.defaults[i.prototype.name]):{};e.defaults[n]=a(l,t.defaults),e.types[n]=s,e.prototype[n]=function(t,i){var o=h(e.defaults.global,e.defaults[n],i||{});return new s(t,o,this)}}else d("Name not provided for this chart, so it hasn't been registered");return i},e.Element=function(t){a(this,t),this.initialize.apply(this,arguments),this.save()},a(e.Element.prototype,{initialize:function(){},restore:function(t){return t?n(t,function(t){this[t]=this._saved[t]},this):a(this,this._saved),this},save:function(){return this._saved=o(this),delete this._saved._saved,this},update:function(t){return n(t,function(t,i){this._saved[i]=this[i],this[i]=t},this),this},transition:function(t,i){return n(t,function(t,e){this[e]=(t-this._saved[e])*i+this._saved[e]},this),this},tooltipPosition:function(){return{x:this.x,y:this.y}},hasValue:function(){return f(this.value)}}),e.Element.extend=r,e.Point=e.Element.extend({display:!0,inRange:function(t,i){var e=this.hitDetectionRadius+this.radius;return Math.pow(t-this.x,2)+Math.pow(i-this.y,2)<Math.pow(e,2)},draw:function(){if(this.display){var t=this.ctx;t.beginPath(),t.arc(this.x,this.y,this.radius,0,2*Math.PI),t.closePath(),t.strokeStyle=this.strokeColor,t.lineWidth=this.strokeWidth,t.fillStyle=this.fillColor,t.fill(),t.stroke()}}}),e.Arc=e.Element.extend({inRange:function(t,i){var e=s.getAngleFromPoint(this,{x:t,y:i}),n=e.angle>=this.startAngle&&e.angle<=this.endAngle,o=e.distance>=this.innerRadius&&e.distance<=this.outerRadius;return n&&o},tooltipPosition:function(){var t=this.startAngle+(this.endAngle-this.startAngle)/2,i=(this.outerRadius-this.innerRadius)/2+this.innerRadius;return{x:this.x+Math.cos(t)*i,y:this.y+Math.sin(t)*i}},draw:function(t){var i=this.ctx;i.beginPath(),i.arc(this.x,this.y,this.outerRadius,this.startAngle,this.endAngle),i.arc(this.x,this.y,this.innerRadius,this.endAngle,this.startAngle,!0),i.closePath(),i.strokeStyle=this.strokeColor,i.lineWidth=this.strokeWidth,i.fillStyle=this.fillColor,i.fill(),i.lineJoin="bevel",this.showStroke&&i.stroke()}}),e.Rectangle=e.Element.extend({draw:function(){var t=this.ctx,i=this.width/2,e=this.x-i,s=this.x+i,n=this.base-(this.base-this.y),o=this.strokeWidth/2;this.showStroke&&(e+=o,s-=o,n+=o),t.beginPath(),t.fillStyle=this.fillColor,t.strokeStyle=this.strokeColor,t.lineWidth=this.strokeWidth,t.moveTo(e,this.base),t.lineTo(e,n),t.lineTo(s,n),t.lineTo(s,this.base),t.fill(),this.showStroke&&t.stroke()},height:function(){return this.base-this.y},inRange:function(t,i){return t>=this.x-this.width/2&&t<=this.x+this.width/2&&i>=this.y&&i<=this.base}}),e.Tooltip=e.Element.extend({draw:function(){var t=this.chart.ctx;t.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.xAlign="center",this.yAlign="above";var i=this.caretPadding=2,e=t.measureText(this.text).width+2*this.xPadding,s=this.fontSize+2*this.yPadding,n=s+this.caretHeight+i;this.x+e/2>this.chart.width?this.xAlign="left":this.x-e/2<0&&(this.xAlign="right"),this.y-n<0&&(this.yAlign="below");var o=this.x-e/2,a=this.y-n;if(t.fillStyle=this.fillColor,this.custom)this.custom(this);else{switch(this.yAlign){case"above":t.beginPath(),t.moveTo(this.x,this.y-i),t.lineTo(this.x+this.caretHeight,this.y-(i+this.caretHeight)),t.lineTo(this.x-this.caretHeight,this.y-(i+this.caretHeight)),t.closePath(),t.fill();break;case"below":a=this.y+i+this.caretHeight,t.beginPath(),t.moveTo(this.x,this.y+i),t.lineTo(this.x+this.caretHeight,this.y+i+this.caretHeight),t.lineTo(this.x-this.caretHeight,this.y+i+this.caretHeight),t.closePath(),t.fill()}switch(this.xAlign){case"left":o=this.x-e+(this.cornerRadius+this.caretHeight);break;case"right":o=this.x-(this.cornerRadius+this.caretHeight)}B(t,o,a,e,s,this.cornerRadius),t.fill(),t.fillStyle=this.textColor,t.textAlign="center",t.textBaseline="middle",t.fillText(this.text,o+e/2,a+s/2)}}}),e.MultiTooltip=e.Element.extend({initialize:function(){this.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.titleFont=W(this.titleFontSize,this.titleFontStyle,this.titleFontFamily),this.height=this.labels.length*this.fontSize+(this.labels.length-1)*(this.fontSize/2)+2*this.yPadding+1.5*this.titleFontSize,this.ctx.font=this.titleFont;var t=this.ctx.measureText(this.title).width,i=z(this.ctx,this.font,this.labels)+this.fontSize+3,e=g([i,t]);this.width=e+2*this.xPadding;var s=this.height/2;this.y-s<0?this.y=s:this.y+s>this.chart.height&&(this.y=this.chart.height-s),this.x>this.chart.width/2?this.x-=this.xOffset+this.width:this.x+=this.xOffset},getLineHeight:function(t){var i=this.y-this.height/2+this.yPadding,e=t-1;return 0===t?i+this.titleFontSize/2:i+(1.5*this.fontSize*e+this.fontSize/2)+1.5*this.titleFontSize},draw:function(){if(this.custom)this.custom(this);else{B(this.ctx,this.x,this.y-this.height/2,this.width,this.height,this.cornerRadius);var t=this.ctx;t.fillStyle=this.fillColor,t.fill(),t.closePath(),t.textAlign="left",t.textBaseline="middle",t.fillStyle=this.titleTextColor,t.font=this.titleFont,t.fillText(this.title,this.x+this.xPadding,this.getLineHeight(0)),t.font=this.font,s.each(this.labels,function(i,e){t.fillStyle=this.textColor,t.fillText(i,this.x+this.xPadding+this.fontSize+3,this.getLineHeight(e+1)),t.fillStyle=this.legendColorBackground,t.fillRect(this.x+this.xPadding,this.getLineHeight(e+1)-this.fontSize/2,this.fontSize,this.fontSize),t.fillStyle=this.legendColors[e].fill,t.fillRect(this.x+this.xPadding,this.getLineHeight(e+1)-this.fontSize/2,this.fontSize,this.fontSize)},this)}}}),e.Scale=e.Element.extend({initialize:function(){this.fit()},buildYLabels:function(){this.yLabels=[];for(var t=v(this.stepValue),i=0;i<=this.steps;i++)this.yLabels.push(C(this.templateString,{value:(this.min+i*this.stepValue).toFixed(t)}));this.yLabelWidth=this.display&&this.showLabels?z(this.ctx,this.font,this.yLabels):0},addXLabel:function(t){this.xLabels.push(t),this.valuesCount++,this.fit()},removeXLabel:function(){this.xLabels.shift(),this.valuesCount--,this.fit()},fit:function(){this.startPoint=this.display?this.fontSize:0,this.endPoint=this.display?this.height-1.5*this.fontSize-5:this.height,this.startPoint+=this.padding,this.endPoint-=this.padding;var t,i=this.endPoint-this.startPoint;for(this.calculateYRange(i),this.buildYLabels(),this.calculateXLabelRotation();i>this.endPoint-this.startPoint;)i=this.endPoint-this.startPoint,t=this.yLabelWidth,this.calculateYRange(i),this.buildYLabels(),t<this.yLabelWidth&&this.calculateXLabelRotation()},calculateXLabelRotation:function(){this.ctx.font=this.font;var t,i,e=this.ctx.measureText(this.xLabels[0]).width,s=this.ctx.measureText(this.xLabels[this.xLabels.length-1]).width;if(this.xScalePaddingRight=s/2+3,this.xScalePaddingLeft=e/2>this.yLabelWidth+10?e/2:this.yLabelWidth+10,this.xLabelRotation=0,this.display){var n,o=z(this.ctx,this.font,this.xLabels);this.xLabelWidth=o;for(var a=Math.floor(this.calculateX(1)-this.calculateX(0))-6;this.xLabelWidth>a&&0===this.xLabelRotation||this.xLabelWidth>a&&this.xLabelRotation<=90&&this.xLabelRotation>0;)n=Math.cos(S(this.xLabelRotation)),t=n*e,i=n*s,t+this.fontSize/2>this.yLabelWidth+8&&(this.xScalePaddingLeft=t+this.fontSize/2),this.xScalePaddingRight=this.fontSize/2,this.xLabelRotation++,this.xLabelWidth=n*o;this.xLabelRotation>0&&(this.endPoint-=Math.sin(S(this.xLabelRotation))*o+3)}else this.xLabelWidth=0,this.xScalePaddingRight=this.padding,this.xScalePaddingLeft=this.padding},calculateYRange:c,drawingArea:function(){return this.startPoint-this.endPoint},calculateY:function(t){var i=this.drawingArea()/(this.min-this.max);return this.endPoint-i*(t-this.min)},calculateX:function(t){var i=(this.xLabelRotation>0,this.width-(this.xScalePaddingLeft+this.xScalePaddingRight)),e=i/Math.max(this.valuesCount-(this.offsetGridLines?0:1),1),s=e*t+this.xScalePaddingLeft;return this.offsetGridLines&&(s+=e/2),Math.round(s)},update:function(t){s.extend(this,t),this.fit()},draw:function(){var t=this.ctx,i=(this.endPoint-this.startPoint)/this.steps,e=Math.round(this.xScalePaddingLeft);this.display&&(t.fillStyle=this.textColor,t.font=this.font,n(this.yLabels,function(n,o){var a=this.endPoint-i*o,h=Math.round(a),l=this.showHorizontalLines;t.textAlign="right",t.textBaseline="middle",this.showLabels&&t.fillText(n,e-10,a),0!==o||l||(l=!0),l&&t.beginPath(),o>0?(t.lineWidth=this.gridLineWidth,t.strokeStyle=this.gridLineColor):(t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor),h+=s.aliasPixel(t.lineWidth),l&&(t.moveTo(e,h),t.lineTo(this.width,h),t.stroke(),t.closePath()),t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor,t.beginPath(),t.moveTo(e-5,h),t.lineTo(e,h),t.stroke(),t.closePath()},this),n(this.xLabels,function(i,e){var s=this.calculateX(e)+x(this.lineWidth),n=this.calculateX(e-(this.offsetGridLines?.5:0))+x(this.lineWidth),o=this.xLabelRotation>0,a=this.showVerticalLines;0!==e||a||(a=!0),a&&t.beginPath(),e>0?(t.lineWidth=this.gridLineWidth,t.strokeStyle=this.gridLineColor):(t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor),a&&(t.moveTo(n,this.endPoint),t.lineTo(n,this.startPoint-3),t.stroke(),t.closePath()),t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor,t.beginPath(),t.moveTo(n,this.endPoint),t.lineTo(n,this.endPoint+5),t.stroke(),t.closePath(),t.save(),t.translate(s,o?this.endPoint+12:this.endPoint+8),t.rotate(-1*S(this.xLabelRotation)),t.font=this.font,t.textAlign=o?"right":"center",t.textBaseline=o?"middle":"top",t.fillText(i,0,0),t.restore()},this))}}),e.RadialScale=e.Element.extend({initialize:function(){this.size=m([this.height,this.width]),this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2},calculateCenterOffset:function(t){var i=this.drawingArea/(this.max-this.min);return(t-this.min)*i},update:function(){this.lineArc?this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2:this.setScaleSize(),this.buildYLabels()},buildYLabels:function(){this.yLabels=[];for(var t=v(this.stepValue),i=0;i<=this.steps;i++)this.yLabels.push(C(this.templateString,{value:(this.min+i*this.stepValue).toFixed(t)}))},getCircumference:function(){return 2*Math.PI/this.valuesCount},setScaleSize:function(){var t,i,e,s,n,o,a,h,l,r,c,u,d=m([this.height/2-this.pointLabelFontSize-5,this.width/2]),p=this.width,g=0;for(this.ctx.font=W(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),i=0;i<this.valuesCount;i++)t=this.getPointPosition(i,d),e=this.ctx.measureText(C(this.templateString,{value:this.labels[i]})).width+5,0===i||i===this.valuesCount/2?(s=e/2,t.x+s>p&&(p=t.x+s,n=i),t.x-s<g&&(g=t.x-s,a=i)):i<this.valuesCount/2?t.x+e>p&&(p=t.x+e,n=i):i>this.valuesCount/2&&t.x-e<g&&(g=t.x-e,a=i);l=g,r=Math.ceil(p-this.width),o=this.getIndexAngle(n),h=this.getIndexAngle(a),c=r/Math.sin(o+Math.PI/2),u=l/Math.sin(h+Math.PI/2),c=f(c)?c:0,u=f(u)?u:0,this.drawingArea=d-(u+c)/2,this.setCenterPoint(u,c)},setCenterPoint:function(t,i){var e=this.width-i-this.drawingArea,s=t+this.drawingArea;this.xCenter=(s+e)/2,this.yCenter=this.height/2},getIndexAngle:function(t){var i=2*Math.PI/this.valuesCount;return t*i-Math.PI/2},getPointPosition:function(t,i){var e=this.getIndexAngle(t);return{x:Math.cos(e)*i+this.xCenter,y:Math.sin(e)*i+this.yCenter}},draw:function(){if(this.display){var t=this.ctx;if(n(this.yLabels,function(i,e){if(e>0){var s,n=e*(this.drawingArea/this.steps),o=this.yCenter-n;if(this.lineWidth>0)if(t.strokeStyle=this.lineColor,t.lineWidth=this.lineWidth,this.lineArc)t.beginPath(),t.arc(this.xCenter,this.yCenter,n,0,2*Math.PI),t.closePath(),t.stroke();else{t.beginPath();for(var a=0;a<this.valuesCount;a++)s=this.getPointPosition(a,this.calculateCenterOffset(this.min+e*this.stepValue)),0===a?t.moveTo(s.x,s.y):t.lineTo(s.x,s.y);t.closePath(),t.stroke()}if(this.showLabels){if(t.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.showLabelBackdrop){var h=t.measureText(i).width;t.fillStyle=this.backdropColor,t.fillRect(this.xCenter-h/2-this.backdropPaddingX,o-this.fontSize/2-this.backdropPaddingY,h+2*this.backdropPaddingX,this.fontSize+2*this.backdropPaddingY)}t.textAlign="center",t.textBaseline="middle",t.fillStyle=this.fontColor,t.fillText(i,this.xCenter,o)}}},this),!this.lineArc){t.lineWidth=this.angleLineWidth,t.strokeStyle=this.angleLineColor;for(var i=this.valuesCount-1;i>=0;i--){if(this.angleLineWidth>0){var e=this.getPointPosition(i,this.calculateCenterOffset(this.max));t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(e.x,e.y),t.stroke(),t.closePath()}var s=this.getPointPosition(i,this.calculateCenterOffset(this.max)+5);t.font=W(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),t.fillStyle=this.pointLabelFontColor;var o=this.labels.length,a=this.labels.length/2,h=a/2,l=h>i||i>o-h,r=i===h||i===o-h;t.textAlign=0===i?"center":i===a?"center":a>i?"left":"right",t.textBaseline=r?"middle":l?"bottom":"top",t.fillText(this.labels[i],s.x,s.y)}}}}}),s.addEvent(window,"resize",function(){var t;return function(){clearTimeout(t),t=setTimeout(function(){n(e.instances,function(t){t.options.responsive&&t.resize(t.render,!0)})},50)}}()),p?define(function(){return e}):"object"==typeof module&&module.exports&&(module.exports=e),t.Chart=e,e.noConflict=function(){return t.Chart=i,e}}).call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleBeginAtZero:!0,scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,scaleShowHorizontalLines:!0,scaleShowVerticalLines:!0,barShowStroke:!0,barStrokeWidth:2,barValueSpacing:5,barDatasetSpacing:1,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].fillColor%>"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'};i.Type.extend({name:"Bar",defaults:s,initialize:function(t){var s=this.options;this.ScaleClass=i.Scale.extend({offsetGridLines:!0,calculateBarX:function(t,i,e){var n=this.calculateBaseWidth(),o=this.calculateX(e)-n/2,a=this.calculateBarWidth(t);return o+a*i+i*s.barDatasetSpacing+a/2},calculateBaseWidth:function(){return this.calculateX(1)-this.calculateX(0)-2*s.barValueSpacing},calculateBarWidth:function(t){var i=this.calculateBaseWidth()-(t-1)*s.barDatasetSpacing;return i/t}}),this.datasets=[],this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getBarsAtEvent(t):[];this.eachBars(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),this.BarClass=i.Rectangle.extend({strokeWidth:this.options.barStrokeWidth,showStroke:this.options.barShowStroke,ctx:this.chart.ctx}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,bars:[]};this.datasets.push(s),e.each(i.data,function(e,n){s.bars.push(new this.BarClass({value:e,label:t.labels[n],datasetLabel:i.label,strokeColor:i.strokeColor,fillColor:i.fillColor,highlightFill:i.highlightFill||i.fillColor,highlightStroke:i.highlightStroke||i.strokeColor}))},this)},this),this.buildScale(t.labels),this.BarClass.prototype.base=this.scale.endPoint,this.eachBars(function(t,i,s){e.extend(t,{width:this.scale.calculateBarWidth(this.datasets.length),x:this.scale.calculateBarX(this.datasets.length,s,i),y:this.scale.endPoint}),t.save()},this),this.render()},update:function(){this.scale.update(),e.each(this.activeElements,function(t){t.restore(["fillColor","strokeColor"])}),this.eachBars(function(t){t.save()}),this.render()},eachBars:function(t){e.each(this.datasets,function(i,s){e.each(i.bars,t,this,s)},this)},getBarsAtEvent:function(t){for(var i,s=[],n=e.getRelativePosition(t),o=function(t){s.push(t.bars[i])},a=0;a<this.datasets.length;a++)for(i=0;i<this.datasets[a].bars.length;i++)if(this.datasets[a].bars[i].inRange(n.x,n.y))return e.each(this.datasets,o),s;return s},buildScale:function(t){var i=this,s=function(){var t=[];return i.eachBars(function(i){t.push(i.value)}),t},n={templateString:this.options.scaleLabel,height:this.chart.height,width:this.chart.width,ctx:this.chart.ctx,textColor:this.options.scaleFontColor,fontSize:this.options.scaleFontSize,fontStyle:this.options.scaleFontStyle,fontFamily:this.options.scaleFontFamily,valuesCount:t.length,beginAtZero:this.options.scaleBeginAtZero,integersOnly:this.options.scaleIntegersOnly,calculateYRange:function(t){var i=e.calculateScaleRange(s(),t,this.fontSize,this.beginAtZero,this.integersOnly);e.extend(this,i)},xLabels:t,font:e.fontString(this.options.scaleFontSize,this.options.scaleFontStyle,this.options.scaleFontFamily),lineWidth:this.options.scaleLineWidth,lineColor:this.options.scaleLineColor,showHorizontalLines:this.options.scaleShowHorizontalLines,showVerticalLines:this.options.scaleShowVerticalLines,gridLineWidth:this.options.scaleShowGridLines?this.options.scaleGridLineWidth:0,gridLineColor:this.options.scaleShowGridLines?this.options.scaleGridLineColor:"rgba(0,0,0,0)",padding:this.options.showScale?0:this.options.barShowStroke?this.options.barStrokeWidth:0,showLabels:this.options.scaleShowLabels,display:this.options.showScale};this.options.scaleOverride&&e.extend(n,{calculateYRange:e.noop,steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}),this.scale=new this.ScaleClass(n)},addData:function(t,i){e.each(t,function(t,e){this.datasets[e].bars.push(new this.BarClass({value:t,label:i,x:this.scale.calculateBarX(this.datasets.length,e,this.scale.valuesCount+1),y:this.scale.endPoint,width:this.scale.calculateBarWidth(this.datasets.length),base:this.scale.endPoint,strokeColor:this.datasets[e].strokeColor,fillColor:this.datasets[e].fillColor}))},this),this.scale.addXLabel(i),this.update()},removeData:function(){this.scale.removeXLabel(),e.each(this.datasets,function(t){t.bars.shift()},this),this.update()},reflow:function(){e.extend(this.BarClass.prototype,{y:this.scale.endPoint,base:this.scale.endPoint});var t=e.extend({height:this.chart.height,width:this.chart.width});this.scale.update(t)},draw:function(t){var i=t||1;this.clear();this.chart.ctx;this.scale.draw(i),e.each(this.datasets,function(t,s){e.each(t.bars,function(t,e){t.hasValue()&&(t.base=this.scale.endPoint,t.transition({x:this.scale.calculateBarX(this.datasets.length,s,e),y:this.scale.calculateY(t.value),width:this.scale.calculateBarWidth(this.datasets.length)},i).draw())},this)},this)}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,percentageInnerCutout:50,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'};i.Type.extend({name:"Doughnut",defaults:s,initialize:function(t){this.segments=[],this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,this.SegmentArc=i.Arc.extend({ctx:this.chart.ctx,x:this.chart.width/2,y:this.chart.height/2}),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.calculateTotal(t),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({value:t.value,outerRadius:this.options.animateScale?0:this.outerRadius,innerRadius:this.options.animateScale?0:this.outerRadius/100*this.options.percentageInnerCutout,fillColor:t.color,highlightColor:t.highlight||t.color,showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,startAngle:1.5*Math.PI,circumference:this.options.animateRotate?0:this.calculateCircumference(t.value),label:t.label})),e||(this.reflow(),this.update())},calculateCircumference:function(t){return 2*Math.PI*(Math.abs(t)/this.total)},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=Math.abs(t.value)},this)},update:function(){this.calculateTotal(this.segments),e.each(this.activeElements,function(t){t.restore(["fillColor"])}),e.each(this.segments,function(t){t.save()}),this.render()},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,e.each(this.segments,function(t){t.update({outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout})},this)},draw:function(t){var i=t?t:1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.calculateCircumference(t.value),outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout},i),t.endAngle=t.startAngle+t.circumference,t.draw(),0===e&&(t.startAngle=1.5*Math.PI),e<this.segments.length-1&&(this.segments[e+1].startAngle=t.endAngle)},this)}}),i.types.Doughnut.extend({name:"Pie",defaults:e.merge(s,{percentageInnerCutout:0})})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,scaleShowHorizontalLines:!0,scaleShowVerticalLines:!0,bezierCurve:!0,bezierCurveTension:.4,pointDot:!0,pointDotRadius:4,pointDotStrokeWidth:1,pointHitDetectionRadius:20,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].strokeColor%>"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'};i.Type.extend({name:"Line",defaults:s,initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx,inRange:function(t){return Math.pow(t-this.x,2)<Math.pow(this.radius+this.hitDetectionRadius,2)}}),this.datasets=[],this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getPointsAtEvent(t):[];this.eachPoints(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,pointColor:i.pointColor,pointStrokeColor:i.pointStrokeColor,points:[]};this.datasets.push(s),e.each(i.data,function(e,n){s.points.push(new this.PointClass({value:e,label:t.labels[n],datasetLabel:i.label,strokeColor:i.pointStrokeColor,fillColor:i.pointColor,highlightFill:i.pointHighlightFill||i.pointColor,highlightStroke:i.pointHighlightStroke||i.pointStrokeColor}))},this),this.buildScale(t.labels),this.eachPoints(function(t,i){e.extend(t,{x:this.scale.calculateX(i),y:this.scale.endPoint}),t.save()},this)},this),this.render()},update:function(){this.scale.update(),e.each(this.activeElements,function(t){t.restore(["fillColor","strokeColor"])}),this.eachPoints(function(t){t.save()}),this.render()},eachPoints:function(t){e.each(this.datasets,function(i){e.each(i.points,t,this)},this)},getPointsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.datasets,function(t){e.each(t.points,function(t){t.inRange(s.x,s.y)&&i.push(t)})},this),i},buildScale:function(t){var s=this,n=function(){var t=[];return s.eachPoints(function(i){t.push(i.value)}),t},o={templateString:this.options.scaleLabel,height:this.chart.height,width:this.chart.width,ctx:this.chart.ctx,textColor:this.options.scaleFontColor,fontSize:this.options.scaleFontSize,fontStyle:this.options.scaleFontStyle,fontFamily:this.options.scaleFontFamily,valuesCount:t.length,beginAtZero:this.options.scaleBeginAtZero,integersOnly:this.options.scaleIntegersOnly,calculateYRange:function(t){var i=e.calculateScaleRange(n(),t,this.fontSize,this.beginAtZero,this.integersOnly);e.extend(this,i)},xLabels:t,font:e.fontString(this.options.scaleFontSize,this.options.scaleFontStyle,this.options.scaleFontFamily),lineWidth:this.options.scaleLineWidth,lineColor:this.options.scaleLineColor,showHorizontalLines:this.options.scaleShowHorizontalLines,showVerticalLines:this.options.scaleShowVerticalLines,gridLineWidth:this.options.scaleShowGridLines?this.options.scaleGridLineWidth:0,gridLineColor:this.options.scaleShowGridLines?this.options.scaleGridLineColor:"rgba(0,0,0,0)",padding:this.options.showScale?0:this.options.pointDotRadius+this.options.pointDotStrokeWidth,showLabels:this.options.scaleShowLabels,display:this.options.showScale};this.options.scaleOverride&&e.extend(o,{calculateYRange:e.noop,steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}),this.scale=new i.Scale(o)},addData:function(t,i){e.each(t,function(t,e){this.datasets[e].points.push(new this.PointClass({value:t,label:i,x:this.scale.calculateX(this.scale.valuesCount+1),y:this.scale.endPoint,strokeColor:this.datasets[e].pointStrokeColor,fillColor:this.datasets[e].pointColor}))},this),this.scale.addXLabel(i),this.update()},removeData:function(){this.scale.removeXLabel(),e.each(this.datasets,function(t){t.points.shift()},this),this.update()},reflow:function(){var t=e.extend({height:this.chart.height,width:this.chart.width});this.scale.update(t)},draw:function(t){var i=t||1;this.clear();var s=this.chart.ctx,n=function(t){return null!==t.value},o=function(t,i,s){return e.findNextWhere(i,n,s)||t},a=function(t,i,s){return e.findPreviousWhere(i,n,s)||t};this.scale.draw(i),e.each(this.datasets,function(t){var h=e.where(t.points,n);e.each(t.points,function(t,e){t.hasValue()&&t.transition({y:this.scale.calculateY(t.value),x:this.scale.calculateX(e)},i)},this),this.options.bezierCurve&&e.each(h,function(t,i){var s=i>0&&i<h.length-1?this.options.bezierCurveTension:0;t.controlPoints=e.splineCurve(a(t,h,i),t,o(t,h,i),s),t.controlPoints.outer.y>this.scale.endPoint?t.controlPoints.outer.y=this.scale.endPoint:t.controlPoints.outer.y<this.scale.startPoint&&(t.controlPoints.outer.y=this.scale.startPoint),t.controlPoints.inner.y>this.scale.endPoint?t.controlPoints.inner.y=this.scale.endPoint:t.controlPoints.inner.y<this.scale.startPoint&&(t.controlPoints.inner.y=this.scale.startPoint)},this),s.lineWidth=this.options.datasetStrokeWidth,s.strokeStyle=t.strokeColor,s.beginPath(),e.each(h,function(t,i){if(0===i)s.moveTo(t.x,t.y);else if(this.options.bezierCurve){var e=a(t,h,i);s.bezierCurveTo(e.controlPoints.outer.x,e.controlPoints.outer.y,t.controlPoints.inner.x,t.controlPoints.inner.y,t.x,t.y)}else s.lineTo(t.x,t.y)},this),s.stroke(),this.options.datasetFill&&h.length>0&&(s.lineTo(h[h.length-1].x,this.scale.endPoint),s.lineTo(h[0].x,this.scale.endPoint),s.fillStyle=t.fillColor,s.closePath(),s.fill()),e.each(h,function(t){t.draw()})},this)}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)",scaleBeginAtZero:!0,scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,scaleShowLine:!0,segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'};i.Type.extend({name:"PolarArea",defaults:s,initialize:function(t){this.segments=[],this.SegmentArc=i.Arc.extend({showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,ctx:this.chart.ctx,innerRadius:0,x:this.chart.width/2,y:this.chart.height/2}),this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,lineArc:!0,width:this.chart.width,height:this.chart.height,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,valuesCount:t.length}),this.updateScaleRange(t),this.scale.update(),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({fillColor:t.color,highlightColor:t.highlight||t.color,label:t.label,value:t.value,outerRadius:this.options.animateScale?0:this.scale.calculateCenterOffset(t.value),circumference:this.options.animateRotate?0:this.scale.getCircumference(),startAngle:1.5*Math.PI})),e||(this.reflow(),this.update())},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=t.value},this),this.scale.valuesCount=this.segments.length},updateScaleRange:function(t){var i=[];e.each(t,function(t){i.push(t.value)});var s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s,{size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2})},update:function(){this.calculateTotal(this.segments),e.each(this.segments,function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.updateScaleRange(this.segments),this.scale.update(),e.extend(this.scale,{xCenter:this.chart.width/2,yCenter:this.chart.height/2}),e.each(this.segments,function(t){t.update({outerRadius:this.scale.calculateCenterOffset(t.value)})},this)},draw:function(t){var i=t||1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.scale.getCircumference(),outerRadius:this.scale.calculateCenterOffset(t.value)},i),t.endAngle=t.startAngle+t.circumference,0===e&&(t.startAngle=1.5*Math.PI),e<this.segments.length-1&&(this.segments[e+1].startAngle=t.endAngle),t.draw()},this),this.scale.draw()}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers;i.Type.extend({name:"Radar",defaults:{scaleShowLine:!0,angleShowLineOut:!0,scaleShowLabels:!1,scaleBeginAtZero:!0,angleLineColor:"rgba(0,0,0,.1)",angleLineWidth:1,pointLabelFontFamily:"'Arial'",pointLabelFontStyle:"normal",pointLabelFontSize:10,pointLabelFontColor:"#666",pointDot:!0,pointDotRadius:3,pointDotStrokeWidth:1,pointHitDetectionRadius:20,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].strokeColor%>"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'},initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx}),this.datasets=[],this.buildScale(t),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getPointsAtEvent(t):[];this.eachPoints(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,pointColor:i.pointColor,pointStrokeColor:i.pointStrokeColor,points:[]};this.datasets.push(s),e.each(i.data,function(e,n){var o;this.scale.animation||(o=this.scale.getPointPosition(n,this.scale.calculateCenterOffset(e))),s.points.push(new this.PointClass({value:e,label:t.labels[n],datasetLabel:i.label,x:this.options.animation?this.scale.xCenter:o.x,y:this.options.animation?this.scale.yCenter:o.y,strokeColor:i.pointStrokeColor,fillColor:i.pointColor,highlightFill:i.pointHighlightFill||i.pointColor,highlightStroke:i.pointHighlightStroke||i.pointStrokeColor}))},this)},this),this.render()},eachPoints:function(t){e.each(this.datasets,function(i){e.each(i.points,t,this)},this)},getPointsAtEvent:function(t){var i=e.getRelativePosition(t),s=e.getAngleFromPoint({x:this.scale.xCenter,y:this.scale.yCenter},i),n=2*Math.PI/this.scale.valuesCount,o=Math.round((s.angle-1.5*Math.PI)/n),a=[];return(o>=this.scale.valuesCount||0>o)&&(o=0),s.distance<=this.scale.drawingArea&&e.each(this.datasets,function(t){a.push(t.points[o])}),a},buildScale:function(t){this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,angleLineColor:this.options.angleLineColor,angleLineWidth:this.options.angleShowLineOut?this.options.angleLineWidth:0,pointLabelFontColor:this.options.pointLabelFontColor,pointLabelFontSize:this.options.pointLabelFontSize,pointLabelFontFamily:this.options.pointLabelFontFamily,pointLabelFontStyle:this.options.pointLabelFontStyle,height:this.chart.height,width:this.chart.width,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,labels:t.labels,valuesCount:t.datasets[0].data.length}),this.scale.setScaleSize(),this.updateScaleRange(t.datasets),this.scale.buildYLabels()},updateScaleRange:function(t){var i=function(){var i=[];return e.each(t,function(t){t.data?i=i.concat(t.data):e.each(t.points,function(t){i.push(t.value)})}),i}(),s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s)},addData:function(t,i){this.scale.valuesCount++,e.each(t,function(t,e){var s=this.scale.getPointPosition(this.scale.valuesCount,this.scale.calculateCenterOffset(t));this.datasets[e].points.push(new this.PointClass({value:t,label:i,x:s.x,y:s.y,strokeColor:this.datasets[e].pointStrokeColor,fillColor:this.datasets[e].pointColor}))},this),this.scale.labels.push(i),this.reflow(),this.update()},removeData:function(){this.scale.valuesCount--,this.scale.labels.shift(),e.each(this.datasets,function(t){t.points.shift()},this),this.reflow(),this.update()},update:function(){this.eachPoints(function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.scale,{width:this.chart.width,height:this.chart.height,size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2}),this.updateScaleRange(this.datasets),this.scale.setScaleSize(),this.scale.buildYLabels()},draw:function(t){var i=t||1,s=this.chart.ctx;this.clear(),this.scale.draw(),e.each(this.datasets,function(t){e.each(t.points,function(t,e){t.hasValue()&&t.transition(this.scale.getPointPosition(e,this.scale.calculateCenterOffset(t.value)),i)},this),s.lineWidth=this.options.datasetStrokeWidth,s.strokeStyle=t.strokeColor,s.beginPath(),e.each(t.points,function(t,i){0===i?s.moveTo(t.x,t.y):s.lineTo(t.x,t.y)},this),s.closePath(),s.stroke(),s.fillStyle=t.fillColor,s.fill(),e.each(t.points,function(t){t.hasValue()&&t.draw()})},this)}})}.call(this);
assets/js/frontend/add-to-cart.js ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function($){
2
+ "use strict";
3
+ function _ready(){
4
+ $('form.purchase-course').submit(function(){
5
+ var $button = $('button.purchase-button', this),
6
+ $view_cart = $('.view-cart-button', this);
7
+ $button.removeClass('added').addClass('loading');
8
+ $.ajax({
9
+ url: $('input[name="_wp_http_referer"]', this).val() + '?lp-ajax=add-to-cart',
10
+ data: $(this).serialize(),
11
+ error: function(){
12
+ $button.removeClass('loading');
13
+ },
14
+ dataType: 'html',
15
+ success: function(response){
16
+ $button.addClass('added').removeClass('loading');
17
+ $view_cart.removeClass('hide-if-js');
18
+ }
19
+ });
20
+ return false;
21
+ });
22
+ }
23
+ $(document).ready(_ready);
24
+ })(jQuery);
assets/js/frontend/checkout.js ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ if (typeof window.LearnPress == 'undefined') {
2
+ window.LearnPress = {};
3
+ }
4
+ ;
5
+ (function ($) {
6
+ "use strict";
7
+ LearnPress.reload = function (url) {
8
+ if (!url) {
9
+ url = window.location.href;
10
+ }
11
+ window.location.href = url;
12
+ }
13
+ LearnPress.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
+ if ($('.payment-methods input.input-radio').length > 1) {
26
+ var $paymentForm = $('div.payment-method-form.' + $(this).attr('id'));
27
+ if ($(this).is(':checked') && !$paymentForm.is(':visible')) {
28
+ $('div.payment-method-form').filter(':visible').slideUp(250);
29
+
30
+ $('div.payment-method-form.' + $(this).attr('id')).slideDown(250);
31
+ }
32
+ } else {
33
+ $('div.payment-method-form ').show();
34
+ }
35
+
36
+ if ($(this).data('order_button_text')) {
37
+ $('#learn-press-checkout').val($('#learn-press-checkout').data('order_button_text'));
38
+ } else {
39
+ $('#learn-press-checkout').val($('#learn-press-checkout').data('value'));
40
+ }
41
+ },
42
+ login : function () {
43
+ var $form = $(this.form);
44
+ if ($form.triggerHandler('checkout_login') !== false) {
45
+ $.ajax({
46
+ url : LearnPress_Settings.siteurl +'/?lp-ajax=checkout-login',
47
+ dataType: 'html',
48
+ data : $form.serialize(),
49
+ type : 'post',
50
+ success : function (response) {
51
+ response = LearnPress.parseJSON(response);
52
+ if (response.result == 'fail') {
53
+ if (response.messages) {
54
+ LearnPress.Checkout.showErrors(response.messages);
55
+ } else {
56
+ LearnPress.Checkout.showErrors('<div class="learn-press-error">Unknown error!</div>');
57
+ }
58
+ } else {
59
+ if (response.redirect) {
60
+ window.location.href = response.redirect;
61
+ }
62
+ }
63
+ }
64
+ })
65
+ }
66
+ return false;
67
+ },
68
+ doCheckout : function () {
69
+ var $form = $(this),
70
+ $place_order = $form.find( '#learn-press-checkout'),
71
+ processing_text = $place_order.attr('data-processing-text'),
72
+ text = $place_order.attr('value');
73
+ 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) {
74
+ if( processing_text ){
75
+ $place_order.val(processing_text)
76
+ }
77
+ $place_order.prop('disabled', true);
78
+ $.ajax({
79
+ url : LearnPress_Settings.siteurl +'/lp-checkout/?lp-ajax=checkout',
80
+ dataType: 'html',
81
+ data : $form.serialize(),
82
+ type : 'post',
83
+ success : function (response) {
84
+ response = LearnPress.parseJSON(response);
85
+ if (response.result == 'fail') {
86
+ if (response.messages) {
87
+ LearnPress.Checkout.showErrors(response.messages);
88
+ } else {
89
+ LearnPress.Checkout.showErrors('<div class="learn-press-error">Unknown error!</div>');
90
+ }
91
+ } else if( response.result == 'success'){
92
+ if (response.redirect) {
93
+ $place_order.val('Redirecting')
94
+ LearnPress.reload(response.redirect);
95
+ return;
96
+ }
97
+ }
98
+ $place_order.val(text)
99
+ $place_order.prop('disabled', false);
100
+ },
101
+ error: function( jqXHR, textStatus, errorThrown ) {
102
+ LearnPress.Checkout.showErrors('<div class="learn-press-error">'+errorThrown+'</div>');
103
+ $place_order.val(text)
104
+ $place_order.prop('disabled', false)
105
+
106
+ }
107
+ })
108
+ }
109
+ return false;
110
+ },
111
+ showErrors : function (messages) {
112
+ $('.learn-press-error, .learn-press-notice, .learn-press-message').remove();
113
+ this.$form.prepend(messages);
114
+ $('html, body').animate({
115
+ scrollTop: ( LearnPress.Checkout.$form.offset().top - 100 )
116
+ }, 1000);
117
+ $(document).trigger('learnpress_checkout_error');
118
+ }
119
+ }
120
+ $(document).ready(function () {
121
+ LearnPress.Checkout.init()
122
+ });
123
+ })(jQuery);
assets/js/frontend/course-lesson.js ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function ($) {
2
+ "use strict";
3
+ $.LP_Course_Item = function () {
4
+
5
+ }
6
+ $.LP_Course_Item.Model = Backbone.Model.extend({
7
+ url : function () {
8
+ return this.rootUrl
9
+ },
10
+ rootUrl : '',
11
+ initialize: function (data) {
12
+ this.rootUrl = data.rootUrl;
13
+ },
14
+ load : function (callback) {
15
+ var that = this,
16
+ _completed = function (response, success) {
17
+ var $html = $(response || ''),
18
+ $lesson = $html.find('#learn-press-course-lesson');
19
+ if ($lesson.length == 0) {
20
+ $lesson = $('<div id="learn-press-course-lesson" />');
21
+ }
22
+ if (LearnPress.Hook.applyFilters('learn_press_update_item_content', $lesson, that) !== false) {
23
+ that.set('content', $lesson);
24
+ $(document).trigger('learn_press_course_item_content_replaced', $lesson, that);
25
+ $('.course-item.item-current')
26
+ .removeClass('item-current');
27
+ $('.course-item.course-item-' + that.get('id'))
28
+ .addClass('item-current');
29
+ }
30
+ $.isFunction(callback) && callback.call(that, response);
31
+ };
32
+ $.ajax({
33
+ url : this.url(),
34
+ dataType: 'html',
35
+ success : function (response) {
36
+ _completed(response, true);
37
+ },
38
+ error : function () {
39
+ _completed('', false)
40
+ }
41
+ })
42
+ },
43
+ complete : function (args) {
44
+ var that = this;
45
+ args = $.extend({
46
+ data : null,
47
+ success: null
48
+ }, args || {});
49
+ $.ajax({
50
+ url : LearnPress_Settings.ajax,
51
+ dataType: 'html',
52
+ data : $.extend({
53
+ action: 'learnpress_complete_lesson',
54
+ id : this.get('id')
55
+ }, args.data || {}),
56
+ success : function (response) {
57
+ response = LearnPress.parseJSON(response);
58
+ $.isFunction(args.success) && args.success.call(that, $.extend(response, {id: that.get('id')}))
59
+ }
60
+ })
61
+ }
62
+ });
63
+
64
+ $.LP_Course_Item.View = Backbone.View.extend({
65
+ el : '#learn-press-course-lesson',
66
+ events : {
67
+ 'click .complete-lesson-button': '_completeLesson'
68
+ },
69
+ initialize : function () {
70
+ _.bindAll(this, 'updateItem', '_completeLesson');
71
+ this.model.on('change', this.updateItem, this);
72
+
73
+ if (LearnPress.Hook.applyFilters('learn_press_before_load_item', this) !== false) {
74
+ if (this.model.get('id') && this.$('input[name="learn-press-lesson-viewing"]').val() != this.model.get('id')) {
75
+ if (this.model.get('content')) {
76
+ this.updateItem();
77
+ } else {
78
+ this.model.load();
79
+ }
80
+ } else if (this.model.get('content')) {
81
+ LearnPress.Hook.doAction('learn_press_item_content_loaded', this.model.get('content'), this);
82
+ }
83
+ }
84
+ },
85
+ updateItem : function () {
86
+ var $content = this.model.get('content');
87
+ this.$el.replaceWith($content);
88
+ this.setElement($content);
89
+ var url = LearnPress.Hook.applyFilters('learn_press_set_item_url', this.model.get('rootUrl'), this);
90
+ if (url) {
91
+ LearnPress.setUrl(url);
92
+ }
93
+ LearnPress.Hook.doAction('learn_press_item_content_loaded', $content, this);
94
+ },
95
+ _autoNextItem : function (item, delay) {
96
+ var $link = this.$('.course-item-next a[data-id="' + item + '"]');
97
+ if (!$link.length) {
98
+ return;
99
+ }
100
+ var duration = 3,
101
+ $span = $('<span>Auto next in ' + duration + 's</span>').insertAfter(this.$('.complete-lesson-button'));
102
+ setInterval(function () {
103
+ duration--;
104
+ $span.html('Auto next in ' + duration + 's');
105
+ if (duration == 0) {
106
+ $link.trigger('click')
107
+ }
108
+ }, 1000);
109
+ },
110
+ _completeLesson: function (e) {
111
+ var that = this;
112
+ this.model.complete({
113
+ data : $(e.target).data(),
114
+ success: function (response) {
115
+ response = LearnPress.Hook.applyFilters('learn_press_user_complete_lesson_response', response);
116
+ if (response.next_item) {
117
+ //that._autoNextItem(response.next_item, 3);
118
+ }
119
+ LearnPress.Hook.doAction('learn_press_user_completed_lesson', response, that);
120
+ }
121
+ });
122
+ }
123
+ });
124
+ $.LP_Course_Item.Collection = Backbone.Collection.extend({
125
+ model : $.LP_Course_Item.Model,
126
+ current : 0,
127
+ initialize: function () {
128
+ var that = this;
129
+ _.bindAll(this, 'initItems', 'loadItem');
130
+ this.initItems();
131
+ },
132
+ initItems : function () {
133
+ var that = this;
134
+ $('.section-content .course-item').each(function () {
135
+ var $li = $(this),
136
+ $link = $li.find('a'),
137
+ id = parseInt($link.attr('data-id')),
138
+ args = {
139
+ id : id,
140
+ nonce : {
141
+ complete: $link.attr('data-complete-nonce')
142
+ },
143
+ rootUrl: $link.attr('href'),
144
+ type : $li.data('type')
145
+ };
146
+ if ($li.hasClass('item-current')) {
147
+ that.current = id;
148
+ args.content = $('#learn-press-course-lesson')
149
+ }
150
+ var model = new $.LP_Course_Item.Model(args);
151
+ that.add(model);
152
+ });
153
+
154
+ },
155
+ loadItem : function (item, link) {
156
+
157
+ if ($.isNumeric(item)) {
158
+ item = this.findWhere({id: item});
159
+ } else if ($.type(item) == 'string') {
160
+ item = this.findWhere({rootUrl: item});
161
+ }
162
+ if (LearnPress.Hook.applyFilters('learn_press_load_item_content', true, item, link) !== false) {
163
+ if (item) {
164
+ if (this.view) {
165
+ this.view.undelegateEvents();
166
+ //this.view.model.set('content', this.view.$el);
167
+ $('.course-item.item-current')
168
+ .removeClass('item-current');
169
+ $('.course-item.course-item-' + item.get('id'))
170
+ .addClass('item-current');
171
+ }
172
+ if (link) {
173
+ item.set('rootUrl', link);
174
+ item.rootUrl = link;
175
+ }
176
+ this.view = new $.LP_Course_Item.View({model: item});
177
+ }
178
+ }
179
+ }
180
+ });
181
+
182
+ $.LP_Course_Item_List_View = Backbone.View.extend({
183
+ model : $.LP_Course_Item.Collection,
184
+ el : 'body',
185
+ events : {
186
+ 'click .section-content .course-item': '_loadItem',
187
+ 'click .course-item-nav a' : '_loadItem'
188
+ },
189
+ initialize: function (args) {
190
+ _.bindAll(this, '_loadItem');
191
+ //this.model.loadItem(this.model.current);
192
+ },
193
+ _loadItem : function (e) {
194
+ e.preventDefault();
195
+ var $item = $(e.target),
196
+ id = parseInt($item.attr('data-id')),
197
+ link = $item.attr('href');
198
+ this.model.loadItem(id ? id : link, link);
199
+ }
200
+ });
201
+
202
+ })(jQuery);
assets/js/frontend/enroll.js ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ if (typeof window.LearnPress == 'undefined') {
2
+ window.LearnPress = {};
3
+ }
4
+ ;
5
+ (function ($) {
6
+ "use strict";
7
+ LearnPress.Enroll = {
8
+ $form : null,
9
+ init : function () {
10
+ var $doc = $(document);
11
+ this.$form = $('form[name="enroll-course"]');
12
+ this.$form.on('submit', this.enroll);
13
+ },
14
+ enroll : function () {
15
+ var $form = $(this),
16
+ $button = $form.find('.button.enroll-button'),
17
+ course_id = $form.find('input[name="enroll-course"]').val();
18
+ if (!$button.hasClass('enrolled') && $form.triggerHandler('learn_press_enroll_course') !== false ) {
19
+ $button.removeClass('enrolled failed').addClass('loading');
20
+ $.ajax({
21
+ url : LearnPress.getUrl(),
22
+ dataType: 'html',
23
+ data : $form.serialize(),
24
+ type : 'post',
25
+ success : function (response) {
26
+ response = LearnPress.parseJSON(response);
27
+ if (response.result == 'fail') {
28
+ if( LearnPress.Hook.applyFilters( 'learn_press_user_enroll_course_failed', course_id ) !== false ) {
29
+ if (response.redirect) {
30
+ LearnPress.reload(response.redirect);
31
+ }
32
+ }
33
+ } else {
34
+ if( LearnPress.Hook.applyFilters( 'learn_press_user_enrolled_course', course_id ) !== false ) {
35
+ if (response.redirect) {
36
+ LearnPress.reload(response.redirect);
37
+ }
38
+ }
39
+ }
40
+ },
41
+ error: function( jqXHR, textStatus, errorThrown ) {
42
+ LearnPress.Hook.doAction( 'learn_press_user_enroll_course_failed', course_id );
43
+ $button.removeClass('loading').addClass('failed');
44
+ LearnPress.Enroll.showErrors('<div class="learn-press-error">'+errorThrown+'</div>');
45
+ }
46
+ })
47
+ }
48
+ return false;
49
+ },
50
+ showErrors : function (messages) {
51
+ this.removeErrors();
52
+ this.$form.prepend(messages);
53
+ $('html, body').animate({
54
+ scrollTop: ( LearnPress.Enroll.$form.offset().top - 100 )
55
+ }, 1000);
56
+ $(document.body).trigger('learn_press_enroll_error');
57
+ },
58
+ removeErrors: function(){
59
+ $('.learn-press-error, .learn-press-notice, .learn-press-message').remove();
60
+ }
61
+ }
62
+ $(document).ready(function () {
63
+ LearnPress.Enroll.init()
64
+ });
65
+ })(jQuery);
assets/js/frontend/learnpress.js ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @author ThimPress
3
+ * @package LearnPress/Javascript
4
+ * @version 1.0
5
+ */
6
+ ;if (typeof window.LearnPress == 'undefined') {
7
+ window.LearnPress = {};
8
+ }
9
+ ;(function ($) {
10
+ "use strict";
11
+ LearnPress = $.extend({
12
+ setUrl : function (url, title) {
13
+ history.pushState({}, title, url);
14
+ },
15
+ reload : function (url) {
16
+ if (!url) {
17
+ url = window.location.href;
18
+ }
19
+ window.location.href = url;
20
+ },
21
+ parseJSON: function (data) {
22
+ var m = data.match(/<!-- LP_AJAX_START -->(.*)<!-- LP_AJAX_END -->/);
23
+ try {
24
+ if (m) {
25
+ data = $.parseJSON(m[1]);
26
+ } else {
27
+ data = $.parseJSON(data);
28
+ }
29
+ } catch (e) {
30
+ LearnPress.log(e);
31
+ data = {};
32
+ }
33
+ return data;
34
+ },
35
+ toElement: function (element, args) {
36
+ args = $.extend({
37
+ delay : 300,
38
+ duration: 'slow',
39
+ offset : 50
40
+ }, args || {});
41
+ $('body, html')
42
+ .fadeIn(10)
43
+ .delay(args.delay)
44
+ .animate({
45
+ scrollTop: $(element).offset().top - args.offset
46
+ }, args.duration);
47
+ }
48
+ }, LearnPress);
49
+
50
+ $(document).on('submit', '#learn-press-form-login', function (e) {
51
+ LearnPress.doAjax({
52
+ data : {
53
+ 'lp-ajax': 'login',
54
+ data : $(this).serialize()
55
+ },
56
+ success: function (response, raw) {
57
+ if (response.message) {
58
+ LearnPress.alert(response.message, function () {
59
+ if (response.redirect) {
60
+ LearnPress.reload(response.redirect);
61
+ }
62
+ });
63
+ } else {
64
+ if (response.redirect) {
65
+ LearnPress.reload(response.redirect);
66
+ }
67
+ }
68
+ }
69
+ })
70
+ return false;
71
+ });
72
+ })(jQuery);
assets/js/frontend/single-course.js ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Single course functions
3
+ */
4
+ if (typeof LearnPress == 'undefined') {
5
+ window.LearnPress = {}
6
+ }
7
+ ;(function ($) {
8
+ "use strict";
9
+ LearnPress.Course = $.extend(
10
+ LearnPress.Course || {}, {
11
+ finish: function (data, callback) {
12
+ LearnPress.$Course && LearnPress.$Course.finishCourse({data: data, success: callback});
13
+ }
14
+ }
15
+ );
16
+ var LearnPress_View_Course = window.LearnPress_View_Course = Backbone.View.extend({
17
+ $doc : null,
18
+ $body : null,
19
+ courseItems : null,
20
+ courseItemsView : null,
21
+ el : '.course-summary',
22
+ events : {
23
+ //'click .curriculum-sections .section-content > li a': '_loadLesson',
24
+ //'click .course-item-nav a': '_loadLesson',
25
+ 'click #learn-press-finish-course': '_finishCourse'
26
+ },
27
+ initialize : function (args) {
28
+ this.courseItems = new $.LP_Course_Item.Collection();
29
+ this.courseItemsView = new $.LP_Course_Item_List_View({model: this.courseItems});
30
+
31
+ _.bindAll(this, '_finishCourse', '_sanitizeProgress', 'completeLesson');
32
+ this.$doc = $(document);
33
+ this.$body = $(document.body);
34
+ LearnPress.Hook.addFilter('learn_press_before_load_item', function ($view) {
35
+ LearnPress.MessageBox.blockUI();
36
+ if ($view.model.get('type') == 'lp_quiz') {
37
+ var redirect = LearnPress.Hook.applyFilters('learn_press_course_item_redirect_url', $('.course-item-' + $view.model.get('id') + ' a').prop('href'), $view);
38
+ if (redirect !== false) {
39
+ var win = window.open(redirect, '_blank');
40
+ try{win.focus();}catch(e){}
41
+ }
42
+ }
43
+ return true;
44
+ });
45
+ LearnPress.Hook
46
+ .addAction('learn_press_item_content_loaded', this.itemLoaded)
47
+ .addAction('learn_press_user_completed_lesson', this.completeLesson)
48
+ .addAction('learn_press_user_passed_course_condition', function () {
49
+ });
50
+
51
+ this._sanitizeProgress();
52
+
53
+
54
+ },
55
+ itemLoaded : function ($content, $view) {
56
+ LearnPress.toElement('#learn-press-course-lesson-heading');
57
+ LearnPress.MessageBox.hide();
58
+ },
59
+ completeLesson : function (response, that) {
60
+ if (response && response.result == 'success') {
61
+ var $button = this.$('.complete-lesson-button').addClass('completed').prop('disabled', true).html(response.button_text);
62
+ $('.course-item-' + response.id).addClass('item-completed');
63
+ if (response.course_result) {
64
+ if (response.can_finish) {
65
+ this.$('#learn-press-finish-course').removeClass('hide-if-js');
66
+ LearnPress.Hook.doAction('learn_press_user_passed_course_condition', response, this, that);
67
+ }
68
+ if (response.message) {
69
+ $(response.message).insertBefore($button);
70
+ }
71
+ this.updateProgress(response);
72
+ }
73
+ }
74
+ },
75
+ updateProgress : function (data) {
76
+ $('.lp-course-progress')
77
+ .attr({
78
+ 'data-value': data.course_result
79
+ })
80
+ this._sanitizeProgress();
81
+ },
82
+ _loadLesson : function (e) {
83
+ this.loadLesson($(e.target).attr('href'));
84
+ },
85
+ loadLesson : function (permalink, args) {
86
+ var that = this;
87
+ LearnPress.Hook.doAction('learn_press_before_load_lesson', permalink, this);
88
+ args = $.extend({
89
+ success: function () {
90
+ return true;
91
+ },
92
+ error : function () {
93
+ }
94
+ }, args || {})
95
+
96
+ $.ajax({
97
+ url : permalink,
98
+ success: function (response) {
99
+ var ret = true;
100
+ $.isFunction(args.success) && ( ret = args.success.call(this, response) );
101
+ if (ret === true) {
102
+ var $html = $(response),
103
+ $newLesson = $html.find('#learn-press-course-lesson-summary'),
104
+ $newHeading = $html.find('#learn-press-course-lesson-heading');
105
+
106
+ $('title').html($html.filter('title').text());
107
+ $('#learn-press-course-description-heading, #learn-press-course-lesson-heading').replaceWith($newHeading)
108
+ $('#learn-press-course-description, #learn-press-course-lesson-summary').replaceWith($newLesson);
109
+
110
+ LearnPress.Hook.doAction('learn_press_load_lesson_completed', permalink, that);
111
+ LearnPress.Hook.doAction('learn_press_lesson_content_loaded', $html, this);
112
+
113
+ }
114
+ },
115
+ error : function () {
116
+ // TODO: handle the error here
117
+ LearnPress.MessageBox.hide();
118
+ }
119
+ })
120
+ },
121
+ _finishCourse : function (e) {
122
+ var that = this,
123
+ $button = $(e.target),
124
+ data = $button.data();
125
+ data = LearnPress.Hook.applyFilters('learn_press_user_finish_course_data', data);
126
+ if (data && data.id) {
127
+ $button.prop('disabled', true);
128
+ this.finishCourse({
129
+ data : data,
130
+ success: function (response) {
131
+ LearnPress.Hook.applyFilters('learn_press_finish_course_params', response);
132
+
133
+ if (response && response.result == 'success') {
134
+ that.$('#learn-press-finish-course, .complete-lesson-button').remove();
135
+ LearnPress.Hook.doAction('learn_press_finish_course', response);
136
+ }
137
+ if (response.message) {
138
+ LearnPress.alert(response.message, function () {
139
+ if (response.redirect) {
140
+ LearnPress.reload(response.redirect);
141
+ }
142
+ });
143
+ } else {
144
+ if (response.redirect) {
145
+ LearnPress.reload(response.redirect);
146
+ }
147
+ }
148
+ }
149
+ });
150
+ }
151
+ },
152
+ finishCourse : function (args) {
153
+ args = args || {};
154
+ var _do = function (e) {
155
+ if (e) {
156
+ LearnPress.doAjax({
157
+ prefix : '',
158
+ data : data,
159
+ success: _success
160
+ });
161
+ }
162
+ },
163
+ _success = function (response) {
164
+ $.isFunction(args.success) && args.success.call(that, response);
165
+ },
166
+ that = this,
167
+ data = $.extend({
168
+ 'lp-ajax': 'finish_course'
169
+ }, args.data || {});
170
+ LearnPress.confirm(single_course_localize.confirm_finish_course, _do);
171
+ },
172
+ _sanitizeProgress: function () {
173
+ var $el = $('.lp-course-progress'),
174
+ $progress = $('.lp-progress-value', $el),
175
+ $passing = $('.lp-passing-conditional', $el),
176
+ value = parseFloat($el.attr('data-value')),
177
+ passing_condition = parseFloat($el.attr('data-passing-condition')),
178
+ _done = function () {
179
+ var progress = parseInt($progress.css('width')),
180
+ passing = parseInt($passing.css('left'));
181
+
182
+ if (value >= passing_condition) {
183
+ $el.addClass('passed');
184
+ }
185
+ };
186
+ $progress.css('width', value + '%').find('span span').html(value);
187
+ setTimeout(_done, 500);
188
+
189
+ }
190
+ });
191
+
192
+ $(document).ready(function () {
193
+ //LearnPress.Course.init( $(this), $(document.body) );
194
+ LearnPress.$Course = new LearnPress_View_Course();
195
+ });
196
+ })(jQuery);
assets/js/frontend/single-quiz.js ADDED
@@ -0,0 +1,731 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ if (typeof LearnPress == 'undefined') var LearnPress = {};
2
+ (function ($) {
3
+ "use strict";
4
+
5
+ var LearnPress_Model_Quiz = window.LearnPress_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 LearnPress_Collection_Questions();
22
+ _.each(this.get('questions'), function (args, i) {
23
+ var $model = new LearnPress_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').serialize(),
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
+ LearnPress.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').serialize(),
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
+ LearnPress.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').serialize(), //$('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 LearnPress_Model_Question = window.LearnPress_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 = LearnPress.parseJSON(e.responseText);
158
+ if (response.result == 'success') {
159
+ //if (!that.get('content')) {
160
+ that.set(response.question);
161
+ if (response.permalink) {
162
+ LearnPress.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
+ LearnPress.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').serialize()
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 LearnPress_Collection_Questions = window.LearnPress_Collection_Questions = Backbone.Collection.extend({
200
+ url : 'admin-ajax.php',
201
+ model: LearnPress_Model_Question
202
+ });
203
+
204
+ var LearnPress_View_Quiz = window.LearnPress_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
+ LearnPress.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
+ LearnPress.doAjax({
380
+ url : window.location.href,
381
+ data : data,
382
+ success: function (response, raw) {
383
+ LearnPress.MessageBox.hide();
384
+ var response = LearnPress.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
+ LearnPress.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
+ LearnPress.doAjax({
408
+ data : data,
409
+ success: function (response) {
410
+ var callbackReturn = undefined;
411
+ $.isFunction(args.complete) && ( callbackReturn = args.complete.call(LearnPress.Quiz, response) );
412
+ LearnPress.Hook.doAction('learn_press_finish_quiz', that.model.get('id'), that);
413
+ LearnPress.MessageBox.show(single_quiz_localize.finished_quiz, {
414
+ autohide: 2000,
415
+ onHide : function () {
416
+ if (callbackReturn && callbackReturn.redirect) {
417
+ LearnPress.reload(callbackReturn.redirect);
418
+ } else if (callbackReturn == undefined && response.redirect) {
419
+ LearnPress.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
+ LearnPress.doAjax({
439
+ data : data,
440
+ success: function (response, raw) {
441
+ LearnPress.MessageBox.hide();
442
+ if (response.result == 'success') {
443
+ $.isFunction(args.complete) && args.complete.call(LearnPress.Quiz, response);
444
+ LearnPress.MessageBox.show(single_quiz_localize.retaken_quiz, {
445
+ autohide: 2000,
446
+ onHide : function () {
447
+ LearnPress.reload(response.redirect);
448
+ }
449
+ });
450
+ } else {
451
+ LearnPress.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
+ //LearnPress.Hook.doAction('learn_press_check_question', response, $current);
493
+ this.render();
494
+ },
495
+ _checkQuestion : function () {
496
+ if (LearnPress.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
+ LearnPress.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 (LearnPress.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 (LearnPress.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 (LearnPress.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
+ LearnPress.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 (LearnPress.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
+ LearnPress.MessageBox.blockUI();
594
+ that.startQuiz({
595
+ complete: function (response) {
596
+ LearnPress.MessageBox.hide();
597
+ if (response.message) {
598
+ LearnPress.alert(response.message, function () {
599
+ if (response.redirect) {
600
+ LearnPress.reload(response.redirect)
601
+ }
602
+ });
603
+ } else {
604
+ if (response.redirect) {
605
+ LearnPress.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
+ LearnPress.Hook.doAction('learn_press_start_quiz', response, that);
612
+ }
613
+ });
614
+ }
615
+ },
616
+ _retakeQuiz : function () {
617
+ var that = this;
618
+ if (LearnPress.Hook.applyFilters('learn_press_before_retake_quiz', true, that) !== false) {
619
+ LearnPress.confirm(single_quiz_localize.confirm_retake_quiz, function (confirm) {
620
+ if (!confirm) {
621
+ return;
622
+ }
623
+ that.$buttons.retake.prop('disabled', true);
624
+ LearnPress.MessageBox.blockUI();
625
+ that.retakeQuiz({
626
+ complete: function (response) {
627
+ LearnPress.MessageBox.hide();
628
+ LearnPress.Hook.doAction('learn_press_user_retaken_quiz', response, that);
629
+ }
630
+ });
631
+ })
632
+ }
633
+ },
634
+ _finishQuiz : function () {
635
+ var that = this;
636
+ if (LearnPress.Hook.applyFilters('learn_press_before_finish_quiz', true, that) !== false) {
637
+ LearnPress.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
+ LearnPress.MessageBox.blockUI();
645
+ that.finishQuiz({
646
+ data : {
647
+ save_id : that.model.get('question_id'),
648
+ question_answer: that.$('form').serialize(),
649
+ time_remaining : that.model.get('time_remaining')
650
+ },
651
+ complete: function (response) {
652
+ LearnPress.MessageBox.hide();
653
+ LearnPress.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
+ LearnPress.Hook.doAction('learn_press_update_question_content', $newQuestion, $oldQuestion, this);
668
+ LearnPress.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
+ LearnPress.MessageBox.blockUI(single_quiz_localize.quiz_time_is_over_message);
703
+ this.finishQuiz({
704
+ complete: function (response) {
705
+ LearnPress.MessageBox.hide();
706
+ if (response.redirect) {
707
+ LearnPress.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
+ LearnPress.Quiz = {
720
+ init: function (data) {
721
+ var model = new LearnPress_Model_Quiz(data);
722
+ new LearnPress_View_Quiz(model);
723
+ }
724
+ }
725
+
726
+
727
+ $(document).ready(function () {
728
+ var json = JSON.stringify(single_quiz_params);
729
+ LearnPress.Quiz.init(single_quiz_params);
730
+ })
731
+ })(jQuery);
assets/js/global.js ADDED
@@ -0,0 +1,670 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Common functions/utils used in all page
3
+ */
4
+ if (typeof window.LearnPress == 'undefined') {
5
+ window.LearnPress = {};
6
+ }
7
+ ;
8
+ (function ($) {
9
+ $.fn.hasEvent = function (name) {
10
+ var events = $(this).data('events');
11
+ if (typeof events.LearnPress == 'undefined') {
12
+ return false;
13
+ }
14
+ for (i = 0; i < events.LearnPress.length; i++) {
15
+ if (events.LearnPress[i].namespace == name) {
16
+ return true;
17
+ }
18
+ }
19
+ return false;
20
+ }
21
+ $.fn.dataToJSON = function () {
22
+ var json = {};
23
+ $.each(this[0].attributes, function () {
24
+ var m = this.name.match(/^data-(.*)/);
25
+ if (m) {
26
+ json[m[1]] = this.value;
27
+ }
28
+ });
29
+ return json;
30
+ }
31
+ String.prototype.getQueryVar = function (name) {
32
+ name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
33
+ var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
34
+ results = regex.exec(this);
35
+ return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
36
+ }
37
+ String.prototype.addQueryVar = function (name, value) {
38
+ var url = this;
39
+ if (name.match(/\[/)) {
40
+ url += url.match(/\?/) ? '&' : '?';
41
+ url += name + '=' + value;
42
+ } else {
43
+ if ((url.indexOf('&' + name + '=') != -1) || (url.indexOf('?' + name + '=') != -1)) {
44
+ url = url.replace(new RegExp(name + "=([^&#]*)", 'g'), name + '=' + value);
45
+ } else {
46
+ url += url.match(/\?/) ? '&' : '?';
47
+ url += name + '=' + value;
48
+ }
49
+ }
50
+ return url;
51
+ }
52
+ String.prototype.removeQueryVar = function (name) {
53
+ var url = this;
54
+ name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
55
+ var regex = new RegExp("[\\?&]" + name + "([\[][^=]*)?=([^&#]*)", 'g');
56
+ url = url.replace(regex, '');
57
+ return url;
58
+ }
59
+
60
+ LearnPress.MessageBox = {
61
+ /*
62
+ *
63
+ */
64
+ $block : null,
65
+ $window : null,
66
+ events : {},
67
+ instances : [],
68
+ instance : null,
69
+ quickConfirm : function (elem, args) {
70
+ var $e = $(elem);
71
+ $('[learn-press-quick-confirm]').each(function () {
72
+ ( $ins = $(this).data('quick-confirm') ) && (console.log($ins), $ins.destroy() );
73
+ });
74
+ !$e.attr('learn-press-quick-confirm') && $e.attr('learn-press-quick-confirm', 'true').data('quick-confirm',
75
+ new (function (elem, args) {
76
+ var $elem = $(elem),
77
+ $div = $('<span class="learn-press-quick-confirm"></span>').insertAfter($elem), //($(document.body)),
78
+ offset = $(elem).position() || {left: 0, top: 0},
79
+ timerOut = null,
80
+ timerHide = null,
81
+ n = 3,
82
+ hide = function () {
83
+ $div.fadeOut('fast', function () {
84
+ $(this).remove();
85
+ $div.parent().css('position', '');
86
+ });
87
+ $elem.removeAttr('learn-press-quick-confirm').data('quick-confirm', undefined);
88
+ stop();
89
+ },
90
+ stop = function () {
91
+ timerHide && clearInterval(timerHide);
92
+ timerOut && clearInterval(timerOut);
93
+ },
94
+ start = function () {
95
+ timerOut = setInterval(function () {
96
+ if (--n == 0) {
97
+ hide.call($div[0]);
98
+ $.isFunction(args.onCancel) && args.onCancel(args.data);
99
+ stop();
100
+ }
101
+ $div.find('span').html(' (' + n + ')');
102
+ }, 1000);
103
+
104
+ timerHide = setInterval(function () {
105
+ if (!$elem.is(':visible') || $elem.css("visibility") == 'hidden') {
106
+ stop();
107
+ $div.remove();
108
+ $div.parent().css('position', '');
109
+ $.isFunction(args.onCancel) && args.onCancel(args.data);
110
+ }
111
+ }, 350);
112
+ };
113
+ args = $.extend({
114
+ message : '',
115
+ data : null,
116
+ onOk : null,
117
+ onCancel: null,
118
+ offset : {top: 0, left: 0}
119
+ }, args || {});
120
+ $div.html(args.message || $elem.attr('data-confirm-remove') || 'Are you sure?').append('<span> (' + n + ')</span>').css({});
121
+ $div.click(function () {
122
+ $.isFunction(args.onOk) && args.onOk(args.data);
123
+ hide();
124
+ }).hover(function () {
125
+ stop();
126
+ }, function () {
127
+ start();
128
+ });
129
+ //$div.parent().css('position', 'relative');
130
+ $div.css({
131
+ left: ( ( offset.left + $elem.outerWidth() ) - $div.outerWidth() ) + args.offset.left,
132
+ top : offset.top + $elem.outerHeight() + args.offset.top + 5
133
+ }).hide().fadeIn('fast');
134
+ start();
135
+
136
+ this.destroy = function () {
137
+ $div.remove();
138
+ $elem.removeAttr('learn-press-quick-confirm').data('quick-confirm', undefined);
139
+ ;
140
+ stop();
141
+ console.log('die');
142
+ };
143
+ })(elem, args)
144
+ );
145
+ },
146
+ show : function (message, args) {
147
+ //this.hide();
148
+ $.proxy(function () {
149
+ args = $.extend({
150
+ title : '',
151
+ buttons : '',
152
+ events : false,
153
+ autohide: false,
154
+ message : message,
155
+ data : false,
156
+ id : LearnPress.uniqueId(),
157
+ onHide : null
158
+ }, args || {});
159
+
160
+ this.instances.push(args)
161
+ this.instance = args;
162
+
163
+ var $doc = $(document),
164
+ $body = $(document.body);
165
+ if (!this.$block) {
166
+ this.$block = $('<div id="learn-press-message-box-block"></div>').appendTo($body);
167
+
168
+ }
169
+ if (!this.$window) {
170
+ this.$window = $('<div id="learn-press-message-box-window"><div id="message-box-wrap"></div> </div>').insertAfter(this.$block);
171
+ this.$window.click(function () {
172
+ })
173
+ }
174
+ //this.events = args.events || {};
175
+ this._createWindow(message, args.title, args.buttons);
176
+ this.$block.show();
177
+ this.$window.show().attr('instance', args.id);
178
+ $(window)
179
+ .bind('resize.message-box', $.proxy(this.update, this))
180
+ .bind('scroll.message-box', $.proxy(this.update, this));
181
+ this.update(true);
182
+ if (args.autohide) {
183
+ setTimeout(function () {
184
+ LearnPress.MessageBox.hide();
185
+ $.isFunction(args.onHide) && args.onHide.call(LearnPress.MessageBox, args);
186
+ }, args.autohide)
187
+ }
188
+ }, this)()
189
+ },
190
+ blockUI : function (message) {
191
+
192
+ message = (message !== false ? ( message ? message : 'Wait a moment' ) : '') + '<div class="message-box-animation"></div>';
193
+ this.show(message);
194
+ },
195
+ hide : function (delay, instance) {
196
+ if (instance) {
197
+ this._removeInstance(instance.id);
198
+ } else if (this.instance) {
199
+ this._removeInstance(this.instance.id);
200
+ }
201
+ if (this.instances.length == 0) {
202
+ if (this.$block) {
203
+ this.$block.hide();
204
+ }
205
+ if (this.$window) {
206
+ this.$window.hide();
207
+ }
208
+ $(window)
209
+ .unbind('resize.message-box', this.update)
210
+ .unbind('scroll.message-box', this.update);
211
+ } else {
212
+ if (this.instance) {
213
+ this._createWindow(this.instance.message, this.instance.title, this.instance.buttons)
214
+ }
215
+ }
216
+
217
+ },
218
+ update : function (force) {
219
+ var that = this,
220
+ $wrap = this.$window.find('#message-box-wrap'),
221
+ timer = $wrap.data('timer'),
222
+ _update = function () {
223
+ LearnPress.Hook.doAction('learn_press_message_box_before_resize', that);
224
+ var $content = $wrap.find('.message-box-content').css("height", "").css('overflow', 'hidden'),
225
+ width = $wrap.outerWidth(),
226
+ height = $wrap.outerHeight(),
227
+ contentHeight = $content.height(),
228
+ windowHeight = $(window).height(),
229
+ top = $wrap.offset().top;
230
+ if (contentHeight > windowHeight - 50) {
231
+ $content.css({
232
+ height: windowHeight - 50
233
+ });
234
+ height = $wrap.outerHeight()
235
+ } else {
236
+ $content.css("height", "").css('overflow', '');
237
+ }
238
+ $wrap.css({
239
+ marginTop: ( $(window).height() - height ) / 2
240
+ });
241
+ LearnPress.Hook.doAction('learn_press_message_box_resize', height, that);
242
+ };
243
+ if (force) _update();
244
+ timer && clearTimeout(timer);
245
+ timer = setTimeout(_update, 250);
246
+ },
247
+ _removeInstance: function (id) {
248
+ for (var i = 0; i < this.instances.length; i++) {
249
+ if (this.instances[i].id == id) {
250
+
251
+ this.instances.splice(i, 1);
252
+
253
+ var len = this.instances.length;
254
+ if (len) {
255
+ this.instance = this.instances[len - 1];
256
+ this.$window.attr('instance', this.instance.id)
257
+ } else {
258
+ this.instance = false;
259
+ this.$window.removeAttr('instance')
260
+ }
261
+ break;
262
+ }
263
+ }
264
+ },
265
+ _getInstance : function (id) {
266
+ for (var i = 0; i < this.instances.length; i++) {
267
+ if (this.instances[i].id == id) {
268
+ return this.instances[i];
269
+ break;
270
+ }
271
+ }
272
+ },
273
+ _createWindow : function (message, title, buttons) {
274
+ var $wrap = this.$window.find('#message-box-wrap').html('');
275
+ if (title) {
276
+ $wrap.append('<h3 class="message-box-title">' + title + '</h3>');
277
+ }
278
+ $wrap.append($('<div class="message-box-content"></div>').html(message));
279
+ if (buttons) {
280
+ var $buttons = $('<div class="message-box-buttons"></div>');
281
+ switch (buttons) {
282
+ case 'yesNo':
283
+ $buttons.append(this._createButton('Yes', 'yes'));
284
+ $buttons.append(this._createButton('No', 'no'));
285
+ break;
286
+ case 'okCancel':
287
+ $buttons.append(this._createButton('Ok', 'ok'));
288
+ $buttons.append(this._createButton('Cancel', 'cancel'));
289
+ break;
290
+ default:
291
+ $buttons.append(this._createButton('Ok', 'ok'));
292
+ }
293
+ $wrap.append($buttons);
294
+ }
295
+ },
296
+ _createButton : function (title, type) {
297
+ var $button = $('<button type="button" class="button message-box-button message-box-button-' + type + '">' + title + '</button>'),
298
+ callback = 'on' + ( type.substr(0, 1).toUpperCase() + type.substr(1) );
299
+ $button.data('callback', callback).click(function () {
300
+ var instance = $(this).data('instance'),
301
+ callback = instance.events[$(this).data('callback')];
302
+ if ($.type(callback) == 'function') {
303
+ if (callback.apply(LearnPress.MessageBox, [instance]) === false) {
304
+ return;
305
+ } else {
306
+ LearnPress.MessageBox.hide(null, instance);
307
+ }
308
+ } else {
309
+ LearnPress.MessageBox.hide(null, instance);
310
+ }
311
+ }).data('instance', this.instance);
312
+ return $button;
313
+ }
314
+ }
315
+ LearnPress.Hook = {
316
+ hooks : {action: {}, filter: {}},
317
+ addAction : function (action, callable, priority, tag) {
318
+ this.addHook('action', action, callable, priority, tag);
319
+ return this;
320
+ },
321
+ addFilter : function (action, callable, priority, tag) {
322
+ this.addHook('filter', action, callable, priority, tag);
323
+ return this;
324
+ },
325
+ doAction : function (action) {
326
+ this.doHook('action', action, arguments);
327
+ return this;
328
+ },
329
+ applyFilters: function (action) {
330
+ return this.doHook('filter', action, arguments);
331
+ },
332
+ removeAction: function (action, tag) {
333
+ this.removeHook('action', action, tag);
334
+ return this;
335
+ },
336
+ removeFilter: function (action, priority, tag) {
337
+ this.removeHook('filter', action, priority, tag);
338
+ return this;
339
+ },
340
+ addHook : function (hookType, action, callable, priority, tag) {
341
+ if (undefined == this.hooks[hookType][action]) {
342
+ this.hooks[hookType][action] = [];
343
+ }
344
+ var hooks = this.hooks[hookType][action];
345
+ if (undefined == tag) {
346
+ tag = action + '_' + hooks.length;
347
+ }
348
+ this.hooks[hookType][action].push({tag: tag, callable: callable, priority: priority});
349
+ return this;
350
+ },
351
+ doHook : function (hookType, action, args) {
352
+
353
+ // splice args from object into array and remove first index which is the hook name
354
+ args = Array.prototype.slice.call(args, 1);
355
+
356
+ if (undefined != this.hooks[hookType][action]) {
357
+ var hooks = this.hooks[hookType][action], hook;
358
+ //sort by priority
359
+ hooks.sort(function (a, b) {
360
+ return a["priority"] - b["priority"]
361
+ });
362
+ for (var i = 0; i < hooks.length; i++) {
363
+ hook = hooks[i].callable;
364
+ if (typeof hook != 'function')
365
+ hook = window[hook];
366
+ if ('action' == hookType) {
367
+ hook.apply(null, args);
368
+ } else {
369
+ args[0] = hook.apply(null, args);
370
+ }
371
+ }
372
+ }
373
+ if ('filter' == hookType) {
374
+ return args[0];
375
+ }
376
+ return this;
377
+ },
378
+ removeHook : function (hookType, action, priority, tag) {
379
+ if (undefined != this.hooks[hookType][action]) {
380
+ var hooks = this.hooks[hookType][action];
381
+ for (var i = hooks.length - 1; i >= 0; i--) {
382
+ if ((undefined == tag || tag == hooks[i].tag) && (undefined == priority || priority == hooks[i].priority)) {
383
+ hooks.splice(i, 1);
384
+ }
385
+ }
386
+ }
387
+ return this;
388
+ }
389
+ };
390
+ LearnPress = $.extend({
391
+ setUrl : function (url, title) {
392
+ history.pushState({}, title, url);
393
+ },
394
+ getUrl : function () {
395
+ return window.location.href;
396
+ },
397
+ addQueryVar : function (name, value, url) {
398
+ return (url == undefined ? window.location.href : url).addQueryVar(name, value);
399
+ },
400
+ removeQueryVar: function (name, url) {
401
+ return (url == undefined ? window.location.href : url).removeQueryVar(name);
402
+ },
403
+ reload : function (url) {
404
+ if (!url) {
405
+ url = window.location.href;
406
+ }
407
+ window.location.href = url;
408
+ },
409
+ parseJSON : function (data) {
410
+ var m = data.match(/<!-- LP_AJAX_START -->(.*)<!-- LP_AJAX_END -->/);
411
+ try {
412
+ if (m) {
413
+ data = $.parseJSON(m[1]);
414
+ } else {
415
+ data = $.parseJSON(data);
416
+ }
417
+ } catch (e) {
418
+ LearnPress.log(e);
419
+ data = {};
420
+ }
421
+ return data;
422
+ },
423
+ parseResponse : function (response, type) {
424
+ var m = response.match(/<!-- LP_AJAX_START -->(.*)<!-- LP_AJAX_END -->/);
425
+ if (m) {
426
+ response = m[1];
427
+ }
428
+ return ( type || 'json' ) == 'json' ? this.parseJSON(response) : response;
429
+ },
430
+ doAjax : function (args) {
431
+ var type = args.type || 'post',
432
+ dataType = args.dataType || 'json',
433
+ action = ( ( args.prefix == undefined ) || 'learnpress_') + args.action,
434
+ data = args.action ? $.extend(args.data, {action: action}) : args.data;
435
+
436
+ $.ajax({
437
+ data : data,
438
+ url : ( args.url || window.location.href ),
439
+ type : type,
440
+ dataType: 'html',
441
+ success : function (raw) {
442
+ var response = LearnPress.parseResponse(raw, dataType);
443
+ $.isFunction(args.success) && args.success(response, raw);
444
+ },
445
+ error : function () {
446
+ $.isFunction(args.error) && args.error.apply(null, LearnPress.funcArgs2Array());
447
+ }
448
+ });
449
+ },
450
+
451
+ funcArgs2Array: function (args) {
452
+ var arr = [];
453
+ for (var i = 0; i < args.length; i++) {
454
+ arr.push(args[i]);
455
+ }
456
+ return arr;
457
+ },
458
+ addFilter : function (action, callback) {
459
+ var $doc = $(document),
460
+ event = 'LearnPress.' + action;
461
+ $doc.on(event, callback);
462
+ LearnPress.log($doc.data('events'));
463
+ return this;
464
+ },
465
+ applyFilters : function () {
466
+ var $doc = $(document),
467
+ action = arguments[0],
468
+ args = this.funcArgs2Array(arguments);
469
+ if ($doc.hasEvent(action)) {
470
+ args[0] = 'LearnPress.' + action;
471
+ return $doc.triggerHandler.apply($doc, args);
472
+ }
473
+ return args[1];
474
+ },
475
+ addAction : function (action, callback) {
476
+ return this.addFilter(action, callback);
477
+ },
478
+ doAction : function () {
479
+ var $doc = $(document),
480
+ action = arguments[0],
481
+ args = this.funcArgs2Array(arguments);
482
+ if ($doc.hasEvent(action)) {
483
+ args[0] = 'LearnPress.' + action;
484
+ $doc.trigger.apply($doc, args);
485
+ }
486
+ },
487
+ toElement : function (element, args) {
488
+ if ($(element).length == 0) {
489
+ return;
490
+ }
491
+ args = $.extend({
492
+ delay : 300,
493
+ duration: 'slow',
494
+ offset : 50
495
+ }, args || {});
496
+ $('body, html')
497
+ .fadeIn(10)
498
+ .delay(args.delay)
499
+ .animate({
500
+ scrollTop: $(element).offset().top - args.offset
501
+ }, args.duration);
502
+ },
503
+ uniqueId : function (prefix, more_entropy) {
504
+ if (typeof prefix === 'undefined') {
505
+ prefix = '';
506
+ }
507
+
508
+ var retId;
509
+ var formatSeed = function (seed, reqWidth) {
510
+ seed = parseInt(seed, 10)
511
+ .toString(16); // to hex str
512
+ if (reqWidth < seed.length) { // so long we split
513
+ return seed.slice(seed.length - reqWidth);
514
+ }
515
+ if (reqWidth > seed.length) { // so short we pad
516
+ return Array(1 + (reqWidth - seed.length))
517
+ .join('0') + seed;
518
+ }
519
+ return seed;
520
+ };
521
+
522
+ // BEGIN REDUNDANT
523
+ if (!this.php_js) {
524
+ this.php_js = {};
525
+ }
526
+ // END REDUNDANT
527
+ if (!this.php_js.uniqidSeed) { // init seed with big random int
528
+ this.php_js.uniqidSeed = Math.floor(Math.random() * 0x75bcd15);
529
+ }
530
+ this.php_js.uniqidSeed++;
531
+
532
+ retId = prefix; // start with prefix, add current milliseconds hex string
533
+ retId += formatSeed(parseInt(new Date()
534
+ .getTime() / 1000, 10), 8);
535
+ retId += formatSeed(this.php_js.uniqidSeed, 5); // add seed hex string
536
+ if (more_entropy) {
537
+ // for more entropy we add a float lower to 10
538
+ retId += (Math.random() * 10)
539
+ .toFixed(8)
540
+ .toString();
541
+ }
542
+
543
+ return retId;
544
+ },
545
+ log : function () {
546
+ if (typeof LEARN_PRESS_DEBUG != 'undefined' && LEARN_PRESS_DEBUG && console) {
547
+ for (var i = 0, n = arguments.length; i < n; i++) {
548
+ console.log(arguments[i]);
549
+ }
550
+ }
551
+ },
552
+ template : _.memoize(function (id, data) {
553
+ var compiled,
554
+ options = {
555
+ evaluate : /<#([\s\S]+?)#>/g,
556
+ interpolate: /\{\{\{([\s\S]+?)\}\}\}/g,
557
+ escape : /\{\{([^\}]+?)\}\}(?!\})/g,
558
+ variable : 'data'
559
+ };
560
+
561
+ var tmpl = function (data) {
562
+ compiled = compiled || _.template($('#' + id).html(), null, options);
563
+ return compiled(data);
564
+ };
565
+ return data ? tmpl(data) : tmpl;
566
+ }, function (a, b) {
567
+ return JSON.stringify(b)
568
+ }),
569
+ alert : function (localize, callback) {
570
+ var title = '',
571
+ message = '';
572
+ if (typeof localize == 'string') {
573
+ message = localize;
574
+ } else {
575
+ if (typeof localize['title'] != 'undefined') {
576
+ title = localize['title'];
577
+ }
578
+ if (typeof localize['message'] != 'undefined') {
579
+ message = localize['message'];
580
+ }
581
+ }
582
+ $.alerts.alert(message, title, function (e) {
583
+ LearnPress._on_alert_hide();
584
+ callback && callback(e);
585
+ });
586
+ this._on_alert_show();
587
+ },
588
+ confirm : function (localize, callback) {
589
+ var title = '',
590
+ message = '';
591
+
592
+ if (typeof localize == 'string') {
593
+ message = localize;
594
+ } else {
595
+ if (typeof localize['title'] != 'undefined') {
596
+ title = localize['title'];
597
+ }
598
+ if (typeof localize['message'] != 'undefined') {
599
+ message = localize['message'];
600
+ }
601
+ }
602
+ $.alerts.confirm(message, title, function (e) {
603
+ LearnPress._on_alert_hide();
604
+ callback && callback(e);
605
+ });
606
+ this._on_alert_show();
607
+
608
+ },
609
+ _on_alert_show: function () {
610
+ var $container = $('#popup_container'),
611
+ $placeholder = $('<span id="popup_container_placeholder" />').insertAfter($container).data('xxx', $container);
612
+ $container.stop().css('top', '-=50').css('opacity', '0').animate({
613
+ top : '+=50',
614
+ opacity: 1
615
+ }, 250);
616
+ },
617
+ _on_alert_hide: function () {
618
+ var $holder = $("#popup_container_placeholder"),
619
+ $container = $holder.data('xxx');
620
+ if ($container) {
621
+ $container.replaceWith($holder);
622
+ }
623
+ $container.appendTo($(document.body))
624
+ $container.stop().animate({
625
+ top : '+=50',
626
+ opacity: 0
627
+ }, 250, function () {
628
+ $(this).remove()
629
+ })
630
+ }
631
+ }, LearnPress);
632
+
633
+ $.fn.findNext = function (selector) {
634
+ var $selector = $(selector),
635
+ $root = this.first(),
636
+ index = $selector.index($root),
637
+ $next = $selector.eq(index + 1);
638
+ return $next.length ? $next : false;
639
+ }
640
+
641
+ $.fn.findPrev = function (selector) {
642
+ var $selector = $(selector),
643
+ $root = this.first(),
644
+ index = $selector.index($root),
645
+ $prev = $selector.eq(index - 1);
646
+ return $prev.length ? $prev : false;
647
+ }
648
+
649
+ function __initSubtabs() {
650
+ $('.learn-press-subtabs').each(function () {
651
+ var $tabContainer = $(this),
652
+ $tabs = $tabContainer.find('a');
653
+ $tabs.click(function (e) {
654
+ var $tab = $(this),
655
+ $contentID = $tab.attr('href');
656
+ e.preventDefault();
657
+ $tab.parent().addClass('current').siblings().removeClass('current');
658
+ $($contentID).addClass('current').siblings().removeClass('current');
659
+ }).first().trigger('click');
660
+ })
661
+ }
662
+
663
+ $(document).ready(function () {
664
+ __initSubtabs();
665
+ });
666
+
667
+ $.alerts.overlayColor = '#000';
668
+ $.alerts.overlayOpacity = 0.5;
669
+
670
+ })(jQuery);
assets/js/global.min.js ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ if(typeof window.LearnPress=='undefined'){window.LearnPress={}};(function($){$.fn.hasEvent=function(name){var events=$(this).data('events');if(typeof events.LearnPress=='undefined'){return !1}
2
+ for(i=0;i<events.LearnPress.length;i++){if(events.LearnPress[i].namespace==name){return !0}}
3
+ return !1}
4
+ $.fn.dataToJSON=function(){var json={};$.each(this[0].attributes,function(){var m=this.name.match(/^data-(.*)/);if(m){json[m[1]]=this.value}});return json}
5
+ String.prototype.getQueryVar=function(name){name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"=([^&#]*)"),results=regex.exec(this);return results===null?"":decodeURIComponent(results[1].replace(/\+/g," "))}
6
+ String.prototype.addQueryVar=function(name,value){var url=this;if(name.match(/\[/)){url+=url.match(/\?/)?'&':'?';url+=name+'='+value}else{if((url.indexOf('&'+name+'=')!=-1)||(url.indexOf('?'+name+'=')!=-1)){url=url.replace(new RegExp(name+"=([^&#]*)",'g'),name+'='+value)}else{url+=url.match(/\?/)?'&':'?';url+=name+'='+value}}
7
+ return url}
8
+ String.prototype.removeQueryVar=function(name){var url=this;name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"([\[][^=]*)?=([^&#]*)",'g');url=url.replace(regex,'');return url}
9
+ LearnPress.MessageBox={$block:null,$window:null,events:{},instances:[],instance:null,show:function(message,args){$.proxy(function(){args=$.extend({title:'',buttons:'',events:!1,autohide:!1,message:message,data:!1,id:LearnPress.uniqueId(),onHide:null},args||{});this.instances.push(args)
10
+ this.instance=args;var $doc=$(document),$body=$(document.body);if(!this.$block){this.$block=$('<div id="learn-press-message-box-block"></div>').appendTo($body)}
11
+ if(!this.$window){this.$window=$('<div id="learn-press-message-box-window"><div id="message-box-wrap"></div> </div>').insertAfter(this.$block);this.$window.click(function(){})}
12
+ this._createWindow(message,args.title,args.buttons);this.$block.show();this.$window.show().attr('instance',args.id);$(window).bind('resize.message-box',$.proxy(this.update,this)).bind('scroll.message-box',$.proxy(this.update,this));this.update(!0);if(args.autohide){setTimeout(function(){LearnPress.MessageBox.hide();$.isFunction(args.onHide)&&args.onHide.call(LearnPress.MessageBox,args)},args.autohide)}},this)()},blockUI:function(message){message=(message!==!1?(message?message:'Wait a moment'):'')+'<div class="message-box-animation"></div>';this.show(message)},hide:function(delay,instance){if(instance){this._removeInstance(instance.id)}else{this._removeInstance(this.instance.id)}
13
+ if(this.instances.length==0){if(this.$block){this.$block.hide()}
14
+ if(this.$window){this.$window.hide()}
15
+ $(window).unbind('resize.message-box',this.update).unbind('scroll.message-box',this.update)}else{this._createWindow(this.instance.message,this.instance.title,this.instance.buttons)}},update:function(force){var that=this,$wrap=this.$window.find('#message-box-wrap'),timer=$wrap.data('timer'),_update=function(){LearnPress.Hook.doAction('learn_press_message_box_before_resize',that);var $content=$wrap.find('.message-box-content').css("height","").css('overflow','hidden'),width=$wrap.outerWidth(),height=$wrap.outerHeight(),contentHeight=$content.height(),windowHeight=$(window).height(),top=$wrap.offset().top;if(contentHeight>windowHeight-50){$content.css({height:windowHeight-50});height=$wrap.outerHeight()}else{$content.css("height","").css('overflow','')}
16
+ $wrap.css({marginTop:($(window).height()-height)/2});LearnPress.Hook.doAction('learn_press_message_box_resize',height,that)};if(force)_update();timer&&clearTimeout(timer);timer=setTimeout(_update,250)},_removeInstance:function(id){for(var i=0;i<this.instances.length;i++){if(this.instances[i].id==id){this.instances.splice(i,1);var len=this.instances.length;if(len){this.instance=this.instances[len-1];this.$window.attr('instance',this.instance.id)}else{this.instance=!1;this.$window.removeAttr('instance')}
17
+ break}}},_getInstance:function(id){for(var i=0;i<this.instances.length;i++){if(this.instances[i].id==id){return this.instances[i];break}}},_createWindow:function(message,title,buttons){var $wrap=this.$window.find('#message-box-wrap').html('');if(title){$wrap.append('<h3 class="message-box-title">'+title+'</h3>')}
18
+ $wrap.append($('<div class="message-box-content"></div>').html(message));if(buttons){var $buttons=$('<div class="message-box-buttons"></div>');switch(buttons){case 'yesNo':$buttons.append(this._createButton('Yes','yes'));$buttons.append(this._createButton('No','no'));break;case 'okCancel':$buttons.append(this._createButton('Ok','ok'));$buttons.append(this._createButton('Cancel','cancel'));break;default:$buttons.append(this._createButton('Ok','ok'))}
19
+ $wrap.append($buttons)}},_createButton:function(title,type){var $button=$('<button type="button" class="button message-box-button message-box-button-'+type+'">'+title+'</button>'),callback='on'+(type.substr(0,1).toUpperCase()+type.substr(1));$button.data('callback',callback).click(function(){var instance=$(this).data('instance'),callback=instance.events[$(this).data('callback')];if($.type(callback)=='function'){if(callback.apply(LearnPress.MessageBox,[instance])===!1){return}else{LearnPress.MessageBox.hide(null,instance)}}else{LearnPress.MessageBox.hide(null,instance)}}).data('instance',this.instance);return $button}}
20
+ LearnPress.Hook={hooks:{action:{},filter:{}},addAction:function(action,callable,priority,tag){this.addHook('action',action,callable,priority,tag);return this},addFilter:function(action,callable,priority,tag){this.addHook('filter',action,callable,priority,tag);return this},doAction:function(action){this.doHook('action',action,arguments);return this},applyFilters:function(action){return this.doHook('filter',action,arguments)},removeAction:function(action,tag){this.removeHook('action',action,tag);return this},removeFilter:function(action,priority,tag){this.removeHook('filter',action,priority,tag);return this},addHook:function(hookType,action,callable,priority,tag){if(undefined==this.hooks[hookType][action]){this.hooks[hookType][action]=[]}
21
+ var hooks=this.hooks[hookType][action];if(undefined==tag){tag=action+'_'+hooks.length}
22
+ this.hooks[hookType][action].push({tag:tag,callable:callable,priority:priority});return this},doHook:function(hookType,action,args){args=Array.prototype.slice.call(args,1);if(undefined!=this.hooks[hookType][action]){var hooks=this.hooks[hookType][action],hook;hooks.sort(function(a,b){return a.priority-b.priority});for(var i=0;i<hooks.length;i++){hook=hooks[i].callable;if(typeof hook!='function')
23
+ hook=window[hook];if('action'==hookType){hook.apply(null,args)}else{args[0]=hook.apply(null,args)}}}
24
+ if('filter'==hookType){return args[0]}
25
+ return this},removeHook:function(hookType,action,priority,tag){if(undefined!=this.hooks[hookType][action]){var hooks=this.hooks[hookType][action];for(var i=hooks.length-1;i>=0;i--){if((undefined==tag||tag==hooks[i].tag)&&(undefined==priority||priority==hooks[i].priority)){hooks.splice(i,1)}}}
26
+ return this}};LearnPress=$.extend({setUrl:function(url,title){history.pushState({},title,url)},getUrl:function(){return window.location.href},addQueryVar:function(name,value,url){return(url==undefined?window.location.href:url).addQueryVar(name,value)},removeQueryVar:function(name,url){return(url==undefined?window.location.href:url).removeQueryVar(name)},reload:function(url){if(!url){url=window.location.href}
27
+ window.location.href=url},parseJSON:function(data){var m=data.match(/<!-- LP_AJAX_START -->(.*)<!-- LP_AJAX_END -->/);try{if(m){data=$.parseJSON(m[1])}else{data=$.parseJSON(data)}}catch(e){LearnPress.log(e);data={}}
28
+ return data},funcArgs2Array:function(args){var arr=[];for(var i=0;i<args.length;i++){arr.push(args[i])}
29
+ return arr},addFilter:function(action,callback){var $doc=$(document),event='LearnPress.'+action;$doc.on(event,callback);LearnPress.log($doc.data('events'));return this},applyFilters:function(){var $doc=$(document),action=arguments[0],args=this.funcArgs2Array(arguments);if($doc.hasEvent(action)){args[0]='LearnPress.'+action;return $doc.triggerHandler.apply($doc,args)}
30
+ return args[1]},addAction:function(action,callback){return this.addFilter(action,callback)},doAction:function(){var $doc=$(document),action=arguments[0],args=this.funcArgs2Array(arguments);if($doc.hasEvent(action)){args[0]='LearnPress.'+action;$doc.trigger.apply($doc,args)}},toElement:function(element,args){if($(element).length==0){return}
31
+ args=$.extend({delay:300,duration:'slow',offset:50},args||{});$('body, html').fadeIn(10).delay(args.delay).animate({scrollTop:$(element).offset().top-args.offset},args.duration)},uniqueId:function(prefix,more_entropy){if(typeof prefix==='undefined'){prefix=''}
32
+ var retId;var formatSeed=function(seed,reqWidth){seed=parseInt(seed,10).toString(16);if(reqWidth<seed.length){return seed.slice(seed.length-reqWidth)}
33
+ if(reqWidth>seed.length){return Array(1+(reqWidth-seed.length)).join('0')+seed}
34
+ return seed};if(!this.php_js){this.php_js={}}
35
+ if(!this.php_js.uniqidSeed){this.php_js.uniqidSeed=Math.floor(Math.random()*0x75bcd15)}
36
+ this.php_js.uniqidSeed++;retId=prefix;retId+=formatSeed(parseInt(new Date().getTime()/1000,10),8);retId+=formatSeed(this.php_js.uniqidSeed,5);if(more_entropy){retId+=(Math.random()*10).toFixed(8).toString()}
37
+ return retId},log:function(){if(typeof LEARN_PRESS_DEBUG!='undefined'&&LEARN_PRESS_DEBUG&&console){for(var i=0,n=arguments.length;i<n;i++){console.log(arguments[i])}}},template:_.memoize(function(id,data){var compiled,options={evaluate:/<#([\s\S]+?)#>/g,interpolate:/\{\{\{([\s\S]+?)\}\}\}/g,escape:/\{\{([^\}]+?)\}\}(?!\})/g,variable:'data'};var tmpl=function(data){compiled=compiled||_.template($('#'+id).html(),null,options);return compiled(data)};return data?tmpl(data):tmpl},function(a,b){return JSON.stringify(b)})},LearnPress);$.fn.findNext=function(selector){var $selector=$(selector),$root=this.first(),index=$selector.index($root),$next=$selector.eq(index+1);return $next.length?$next:!1}
38
+ $.fn.findPrev=function(selector){var $selector=$(selector),$root=this.first(),index=$selector.index($root),$prev=$selector.eq(index-1);return $prev.length?$prev:!1}})(jQuery)
assets/js/jquery.alert.js ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function ($) {
2
+
3
+ $.alerts = {
4
+
5
+ // These properties can be read/written by accessing $.alerts.propertyName from your scripts at any time
6
+
7
+ verticalOffset : -75, // vertical offset of the dialog from center screen, in pixels
8
+ horizontalOffset : 0, // horizontal offset of the dialog from center screen, in pixels/
9
+ repositionOnResize: true, // re-centers the dialog on window resize
10
+ overlayOpacity : .01, // transparency level of overlay
11
+ overlayColor : '#FFF', // base color of overlay
12
+ draggable : true, // make the dialogs draggable (requires UI Draggables plugin)
13
+ okButton : '&nbsp;OK&nbsp;', // text for the OK button
14
+ cancelButton : '&nbsp;Cancel&nbsp;', // text for the Cancel button
15
+ dialogClass : null, // if specified, this class will be applied to all dialogs
16
+
17
+ // Public methods
18
+
19
+ alert: function (message, title, callback) {
20
+ if (title == null) title = 'Alert';
21
+ $.alerts._show(title, message, null, 'alert', function (result) {
22
+ if (callback) callback(result);
23
+ });
24
+ },
25
+
26
+ confirm: function (message, title, callback) {
27
+ if (title == null) title = 'Confirm';
28
+ $.alerts._show(title, message, null, 'confirm', function (result) {
29
+ if (callback) callback(result);
30
+ });
31
+ },
32
+
33
+ prompt: function (message, value, title, callback) {
34
+ if (title == null) title = 'Prompt';
35
+ $.alerts._show(title, message, value, 'prompt', function (result) {
36
+ if (callback) callback(result);
37
+ });
38
+ },
39
+
40
+ // Private methods
41
+
42
+ _show: function (title, msg, value, type, callback) {
43
+
44
+ $.alerts._hide();
45
+ $.alerts._overlay('show');
46
+
47
+ $("BODY").append(
48
+ '<div id="popup_container">' +
49
+ '<h1 id="popup_title"></h1>' +
50
+ '<div id="popup_content">' +
51
+ '<div id="popup_message"></div>' +
52
+ '</div>' +
53
+ '</div>');
54
+
55
+ if ($.alerts.dialogClass) $("#popup_container").addClass($.alerts.dialogClass);
56
+
57
+ // IE6 Fix
58
+ var pos = ($.browser.msie && parseInt($.browser.version) <= 6 ) ? 'absolute' : 'fixed';
59
+
60
+ $("#popup_container").css({
61
+ position: pos,
62
+ zIndex : 99999,
63
+ padding : 0,
64
+ margin : 0
65
+ });
66
+
67
+ $("#popup_title").text(title);
68
+ $("#popup_content").addClass(type);
69
+ $("#popup_message").text(msg);
70
+ $("#popup_message").html($("#popup_message").text().replace(/\n/g, '<br />'));
71
+
72
+ $("#popup_container").css({
73
+ minWidth: $("#popup_container").outerWidth(),
74
+ maxWidth: $("#popup_container").outerWidth()
75
+ });
76
+
77
+ $.alerts._reposition();
78
+ $.alerts._maintainPosition(true);
79
+
80
+ switch (type) {
81
+ case 'alert':
82
+ $("#popup_message").after('<div id="popup_panel"><input type="button" value="' + $.alerts.okButton + '" id="popup_ok" /></div>');
83
+ $("#popup_ok").click(function () {
84
+ $.alerts._hide();
85
+ callback(true);
86
+ });
87
+ $("#popup_ok").focus().keypress(function (e) {
88
+ if (e.keyCode == 13 || e.keyCode == 27) $("#popup_ok").trigger('click');
89
+ });
90
+ break;
91
+ case 'confirm':
92
+ $("#popup_message").after('<div id="popup_panel"><input type="button" value="' + $.alerts.okButton + '" id="popup_ok" /> <input type="button" value="' + $.alerts.cancelButton + '" id="popup_cancel" /></div>');
93
+ $("#popup_ok").click(function () {
94
+ $.alerts._hide();
95
+ if (callback) callback(true);
96
+ });
97
+ $("#popup_cancel").click(function () {
98
+ $.alerts._hide();
99
+ if (callback) callback(false);
100
+ });
101
+ $("#popup_ok").focus();
102
+ $("#popup_ok, #popup_cancel").keypress(function (e) {
103
+ if (e.keyCode == 13) $("#popup_ok").trigger('click');
104
+ if (e.keyCode == 27) $("#popup_cancel").trigger('click');
105
+ });
106
+ break;
107
+ case 'prompt':
108
+ $("#popup_message").append('<br /><input type="text" size="30" id="popup_prompt" />').after('<div id="popup_panel"><input type="button" value="' + $.alerts.okButton + '" id="popup_ok" /> <input type="button" value="' + $.alerts.cancelButton + '" id="popup_cancel" /></div>');
109
+ $("#popup_prompt").width($("#popup_message").width());
110
+ $("#popup_ok").click(function () {
111
+ var val = $("#popup_prompt").val();
112
+ $.alerts._hide();
113
+ if (callback) callback(val);
114
+ });
115
+ $("#popup_cancel").click(function () {
116
+ $.alerts._hide();
117
+ if (callback) callback(null);
118
+ });
119
+ $("#popup_prompt, #popup_ok, #popup_cancel").keypress(function (e) {
120
+ if (e.keyCode == 13) $("#popup_ok").trigger('click');
121
+ if (e.keyCode == 27) $("#popup_cancel").trigger('click');
122
+ });
123
+ if (value) $("#popup_prompt").val(value);
124
+ $("#popup_prompt").focus().select();
125
+ break;
126
+ }
127
+
128
+ // Make draggable
129
+ if ($.alerts.draggable) {
130
+ try {
131
+ $("#popup_container").draggable({ handle: $("#popup_title") });
132
+ $("#popup_title").css({ cursor: 'move' });
133
+ } catch (e) { /* requires jQuery UI draggables */
134
+ }
135
+ }
136
+ },
137
+
138
+ _hide: function () {
139
+ $("#popup_container").remove();
140
+ $.alerts._overlay('hide');
141
+ $.alerts._maintainPosition(false);
142
+ },
143
+
144
+ _overlay: function (status) {
145
+ switch (status) {
146
+ case 'show':
147
+ $.alerts._overlay('hide');
148
+ $("BODY").append('<div id="popup_overlay"></div>');
149
+ $("#popup_overlay").css({
150
+ position : 'absolute',
151
+ zIndex : 99998,
152
+ top : '0px',
153
+ left : '0px',
154
+ width : '100%',
155
+ height : $(document).height(),
156
+ background: $.alerts.overlayColor,
157
+ opacity : $.alerts.overlayOpacity
158
+ });
159
+ break;
160
+ case 'hide':
161
+ $("#popup_overlay").remove();
162
+ break;
163
+ }
164
+ },
165
+
166
+ _reposition: function () {
167
+ var top = (($(window).height() / 2) - ($("#popup_container").outerHeight() / 2)) + $.alerts.verticalOffset;
168
+ var left = (($(window).width() / 2) - ($("#popup_container").outerWidth() / 2)) + $.alerts.horizontalOffset;
169
+ if (top < 0) top = 0;
170
+ if (left < 0) left = 0;
171
+
172
+ // IE6 fix
173
+ if ($.browser.msie && parseInt($.browser.version) <= 6) top = top + $(window).scrollTop();
174
+
175
+ $("#popup_container").css({
176
+ top : top + 'px',
177
+ left: left + 'px'
178
+ });
179
+ $("#popup_overlay").height($(document).height());
180
+ },
181
+
182
+ _maintainPosition: function (status) {
183
+ if ($.alerts.repositionOnResize) {
184
+ switch (status) {
185
+ case true:
186
+ $(window).bind('resize', $.alerts._reposition);
187
+ break;
188
+ case false:
189
+ $(window).unbind('resize', $.alerts._reposition);
190
+ break;
191
+ }
192
+ }
193
+ }
194
+
195
+ }
196
+
197
+ // Shortuct functions
198
+ jAlert = function (message, title, callback) {
199
+ $.alerts.alert(message, title, callback);
200
+ }
201
+
202
+ jConfirm = function (message, title, callback) {
203
+ $.alerts.confirm(message, title, callback);
204
+ };
205
+
206
+ jPrompt = function (message, value, title, callback) {
207
+ $.alerts.prompt(message, value, title, callback);
208
+ };
209
+
210
+ })(jQuery);
assets/js/jquery.appear.js ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery appear plugin
3
+ *
4
+ * Copyright (c) 2012 Andrey Sidorov
5
+ * licensed under MIT license.
6
+ *
7
+ * https://github.com/morr/jquery.appear/
8
+ *
9
+ * Version: 0.3.3
10
+ */
11
+ (function ($) {
12
+ var selectors = [];
13
+
14
+ var check_binded = false;
15
+ var check_lock = false;
16
+ var defaults = {
17
+ interval : 250,
18
+ force_process: false
19
+ }
20
+ var $window = $(window);
21
+
22
+ var $prior_appeared;
23
+
24
+ function process() {
25
+ check_lock = false;
26
+ for (var index = 0; index < selectors.length; index++) {
27
+ var $appeared = $(selectors[index]).filter(function () {
28
+ return $(this).is(':appeared');
29
+ });
30
+
31
+ $appeared.trigger('appear', [$appeared]);
32
+
33
+ if ($prior_appeared) {
34
+ var $disappeared = $prior_appeared.not($appeared);
35
+ $disappeared.trigger('disappear', [$disappeared]);
36
+ }
37
+ $prior_appeared = $appeared;
38
+ }
39
+ }
40
+
41
+ // "appeared" custom filter
42
+ $.expr[':']['appeared'] = function (element) {
43
+ var $element = $(element);
44
+ if (!$element.is(':visible')) {
45
+ return false;
46
+ }
47
+
48
+ var window_left = $window.scrollLeft();
49
+ var window_top = $window.scrollTop();
50
+ var offset = $element.offset();
51
+ var left = offset.left;
52
+ var top = offset.top;
53
+
54
+ if (top + $element.height() >= window_top &&
55
+ top - ($element.data('appear-top-offset') || 0) <= window_top + $window.height() &&
56
+ left + $element.width() >= window_left &&
57
+ left - ($element.data('appear-left-offset') || 0) <= window_left + $window.width()) {
58
+ return true;
59
+ } else {
60
+ return false;
61
+ }
62
+ }
63
+
64
+ $.fn.extend({
65
+ // watching for element's appearance in browser viewport
66
+ appear: function (options) {
67
+ var opts = $.extend({}, defaults, options || {});
68
+ var selector = this.selector || this;
69
+ if (!check_binded) {
70
+ var on_check = function () {
71
+ if (check_lock) {
72
+ return;
73
+ }
74
+ check_lock = true;
75
+
76
+ setTimeout(process, opts.interval);
77
+ };
78
+
79
+ $(window).scroll(on_check).resize(on_check);
80
+ check_binded = true;
81
+ }
82
+
83
+ if (opts.force_process) {
84
+ setTimeout(process, opts.interval);
85
+ }
86
+ selectors.push(selector);
87
+ return $(selector);
88
+ }
89
+ });
90
+
91
+ $.extend({
92
+ // force elements's appearance check
93
+ force_appear: function () {
94
+ if (check_binded) {
95
+ process();
96
+ return true;
97
+ }
98
+ ;
99
+ return false;
100
+ }
101
+ });
102
+ })(jQuery);
assets/js/jquery.caret.js ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($) {
2
+ $.fn.caret = function(pos) {
3
+ var target = this[0];
4
+ var isContentEditable = target.contentEditable === 'true';
5
+ //get
6
+ if (arguments.length == 0) {
7
+ //HTML5
8
+ if (window.getSelection) {
9
+ //contenteditable
10
+ if (isContentEditable) {
11
+ target.focus();
12
+ var range1 = window.getSelection().getRangeAt(0),
13
+ range2 = range1.cloneRange();
14
+ range2.selectNodeContents(target);
15
+ range2.setEnd(range1.endContainer, range1.endOffset);
16
+ return range2.toString().length;
17
+ }
18
+ //textarea
19
+ return target.selectionStart;
20
+ }
21
+ //IE<9
22
+ if (document.selection) {
23
+ target.focus();
24
+ //contenteditable
25
+ if (isContentEditable) {
26
+ var range1 = document.selection.createRange(),
27
+ range2 = document.body.createTextRange();
28
+ range2.moveToElementText(target);
29
+ range2.setEndPoint('EndToEnd', range1);
30
+ return range2.text.length;
31
+ }
32
+ //textarea
33
+ var pos = 0,
34
+ range = target.createTextRange(),
35
+ range2 = document.selection.createRange().duplicate(),
36
+ bookmark = range2.getBookmark();
37
+ range.moveToBookmark(bookmark);
38
+ while (range.moveStart('character', -1) !== 0) pos++;
39
+ return pos;
40
+ }
41
+ // Addition for jsdom support
42
+ if (target.selectionStart)
43
+ return target.selectionStart;
44
+ //not supported
45
+ return 0;
46
+ }
47
+ //set
48
+ if (pos == -1)
49
+ pos = this[isContentEditable? 'text' : 'val']().length;
50
+ //HTML5
51
+ if (window.getSelection) {
52
+ //contenteditable
53
+ if (isContentEditable) {
54
+ target.focus();
55
+ window.getSelection().collapse(target.firstChild, pos);
56
+ }
57
+ //textarea
58
+ else
59
+ target.setSelectionRange(pos, pos);
60
+ }
61
+ //IE<9
62
+ else if (document.body.createTextRange) {
63
+ if (isContentEditable) {
64
+ var range = document.body.createTextRange();
65
+ range.moveToElementText(target);
66
+ range.moveStart('character', pos);
67
+ range.collapse(true);
68
+ range.select();
69
+ } else {
70
+ var range = target.createTextRange();
71
+ range.move('character', pos);
72
+ range.select();
73
+ }
74
+ }
75
+ if (!isContentEditable)
76
+ target.focus();
77
+ return this;
78
+ }
79
+ })(jQuery);
assets/js/jquery.timer.js ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function (e) {
2
+ e.backward_timer = function (t) {
3
+ var n = {seconds: 5, step: 1, format: "h%:m%:s%", value_setter: undefined, on_exhausted: function (e) {
4
+ }, on_tick : function (e) {
5
+ }}, r = this;
6
+ r.seconds_left = 0;
7
+ r.target = e(t);
8
+ r.timeout = undefined;
9
+ r.settings = {};
10
+ r.methods = {init : function (t) {
11
+ r.settings = e.extend({}, n, t);
12
+ if (r.settings.value_setter == undefined) {
13
+ if (r.target.is("input")) {
14
+ r.settings.value_setter = "val"
15
+ } else {
16
+ r.settings.value_setter = "text"
17
+ }
18
+ }
19
+ r.methods.reset()
20
+ }, start : function () {
21
+ if (r.timeout == undefined) {
22
+ var e = r.seconds_left == r.settings.seconds ? 0 : r.settings.step * 1e3;
23
+ setTimeout(r.methods._on_tick, e, e)
24
+ }
25
+ }, cancel : function () {
26
+ if (r.timeout != undefined) {
27
+ clearTimeout(r.timeout);
28
+ r.timeout = undefined
29
+ }
30
+ }, reset : function () {
31
+ r.seconds_left = r.settings.seconds;
32
+ r.methods._render_seconds()
33
+ }, _on_tick : function (e) {
34
+ if (e != 0) {
35
+ r.settings.on_tick(r)
36
+ }
37
+ r.methods._render_seconds();
38
+ if (r.seconds_left > 0) {
39
+ if (r.seconds_left < r.settings.step) {
40
+ var t = r.seconds_left
41
+ } else {
42
+ var t = r.settings.step
43
+ }
44
+ r.seconds_left -= t;
45
+ var n = t * 1e3;
46
+ r.timeout = setTimeout(r.methods._on_tick, n, n)
47
+ } else {
48
+ r.timeout = undefined;
49
+ r.settings.on_exhausted(r)
50
+ }
51
+ }, _render_seconds : function () {
52
+ var e = r.methods._seconds_to_dhms(r.seconds_left), t = r.settings.format;
53
+ if (t.indexOf("d%") !== -1) {
54
+ t = t.replace("d%", e.d).replace("h%", r.methods._check_leading_zero(e.h))
55
+ } else {
56
+ t = t.replace("h%", e.d * 24 + e.h)
57
+ }
58
+ t = t.replace("m%", r.methods._check_leading_zero(e.m)).replace("s%", r.methods._check_leading_zero(e.s));
59
+ r.target[r.settings.value_setter](t)
60
+ }, _seconds_to_dhms : function (e) {
61
+ var t = Math.floor(e / (24 * 3600)), e = e - t * 24 * 3600, n = Math.floor(e / 3600), e = e - n * 3600, r = Math.floor(e / 60), i = Math.floor(e - r * 60);
62
+ return{d: t, h: n, m: r, s: i}
63
+ }, _check_leading_zero: function (e) {
64
+ return e < 10 ? "0" + e : "" + e
65
+ }}
66
+ };
67
+ e.fn.backward_timer = function (t) {
68
+ var n = arguments;
69
+ return this.each(function () {
70
+ var r = e(this).data("backward_timer");
71
+ if (r == undefined) {
72
+ r = new e.backward_timer(this);
73
+ e(this).data("backward_timer", r)
74
+ }
75
+ if (r.methods[t]) {
76
+ return r.methods[t].apply(this, Array.prototype.slice.call(n, 1))
77
+ } else if (typeof t === "object" || !t) {
78
+ return r.methods.init.apply(this, n)
79
+ } else {
80
+ e.error("Method " + t + " does not exist on jQuery.backward_timer")
81
+ }
82
+ })
83
+ }
84
+ })(jQuery)
assets/js/jquery.tipsy.js ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // tipsy, facebook style tooltips for jquery
2
+ // version 1.0.0a
3
+ // (c) 2008-2010 jason frame [jason@onehackoranother.com]
4
+ // released under the MIT license
5
+
6
+ (function($) {
7
+
8
+ function maybeCall(thing, ctx) {
9
+ return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
10
+ };
11
+
12
+ function isElementInDOM(ele) {
13
+ while (ele = ele.parentNode) {
14
+ if (ele == document) return true;
15
+ }
16
+ return false;
17
+ };
18
+
19
+ function Tipsy(element, options) {
20
+ this.$element = $(element);
21
+ this.options = options;
22
+ this.enabled = true;
23
+ this.fixTitle();
24
+ };
25
+
26
+ Tipsy.prototype = {
27
+ show: function() {
28
+ var title = this.getTitle();
29
+ if (title && this.enabled) {
30
+ var $tip = this.tip();
31
+
32
+ $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
33
+ $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
34
+ $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body);
35
+
36
+ var pos = $.extend({}, this.$element.offset(), {
37
+ width: this.$element[0].offsetWidth,
38
+ height: this.$element[0].offsetHeight
39
+ });
40
+
41
+ var actualWidth = $tip[0].offsetWidth,
42
+ actualHeight = $tip[0].offsetHeight,
43
+ gravity = maybeCall(this.options.gravity, this.$element[0]);
44
+
45
+ var tp;
46
+ switch (gravity.charAt(0)) {
47
+ case 'n':
48
+ tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
49
+ break;
50
+ case 's':
51
+ tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
52
+ break;
53
+ case 'e':
54
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};
55
+ break;
56
+ case 'w':
57
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};
58
+ break;
59
+ }
60
+
61
+ if (gravity.length == 2) {
62
+ if (gravity.charAt(1) == 'w') {
63
+ tp.left = pos.left + pos.width / 2 - 15;
64
+ } else {
65
+ tp.left = pos.left + pos.width / 2 - actualWidth + 15;
66
+ }
67
+ }
68
+
69
+ $tip.css(tp).addClass('tipsy-' + gravity);
70
+ $tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
71
+ if (this.options.className) {
72
+ $tip.addClass(maybeCall(this.options.className, this.$element[0]));
73
+ }
74
+
75
+ if (this.options.fade) {
76
+ $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});
77
+ } else {
78
+ $tip.css({visibility: 'visible', opacity: this.options.opacity});
79
+ }
80
+ }
81
+ },
82
+
83
+ hide: function() {
84
+ if (this.options.fade) {
85
+ this.tip().stop().fadeOut(function() { $(this).remove(); });
86
+ } else {
87
+ this.tip().remove();
88
+ }
89
+ },
90
+
91
+ fixTitle: function() {
92
+ var $e = this.$element;
93
+ if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') {
94
+ $e.attr('original-title', $e.attr('title') || '').removeAttr('title');
95
+ }
96
+ },
97
+
98
+ getTitle: function() {
99
+ var title, $e = this.$element, o = this.options;
100
+ this.fixTitle();
101
+ var title, o = this.options;
102
+ if (typeof o.title == 'string') {
103
+ title = $e.attr(o.title == 'title' ? 'original-title' : o.title);
104
+ } else if (typeof o.title == 'function') {
105
+ title = o.title.call($e[0]);
106
+ }
107
+ title = ('' + title).replace(/(^\s*|\s*$)/, "");
108
+ return title || o.fallback;
109
+ },
110
+
111
+ tip: function() {
112
+ if (!this.$tip) {
113
+ this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>');
114
+ this.$tip.data('tipsy-pointee', this.$element[0]);
115
+ }
116
+ return this.$tip;
117
+ },
118
+
119
+ validate: function() {
120
+ if (!this.$element[0].parentNode) {
121
+ this.hide();
122
+ this.$element = null;
123
+ this.options = null;
124
+ }
125
+ },
126
+
127
+ enable: function() { this.enabled = true; },
128
+ disable: function() { this.enabled = false; },
129
+ toggleEnabled: function() { this.enabled = !this.enabled; }
130
+ };
131
+
132
+ $.fn.tipsy = function(options) {
133
+
134
+ if (options === true) {
135
+ return this.data('tipsy');
136
+ } else if (typeof options == 'string') {
137
+ var tipsy = this.data('tipsy');
138
+ if (tipsy) tipsy[options]();
139
+ return this;
140
+ }
141
+
142
+ options = $.extend({}, $.fn.tipsy.defaults, options);
143
+
144
+ function get(ele) {
145
+ var tipsy = $.data(ele, 'tipsy');
146
+ if (!tipsy) {
147
+ tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
148
+ $.data(ele, 'tipsy', tipsy);
149
+ }
150
+ return tipsy;
151
+ }
152
+
153
+ function enter() {
154
+ var tipsy = get(this);
155
+ tipsy.hoverState = 'in';
156
+ if (options.delayIn == 0) {
157
+ tipsy.show();
158
+ } else {
159
+ tipsy.fixTitle();
160
+ setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn);
161
+ }
162
+ };
163
+
164
+ function leave() {
165
+ var tipsy = get(this);
166
+ tipsy.hoverState = 'out';
167
+ if (options.delayOut == 0) {
168
+ tipsy.hide();
169
+ } else {
170
+ setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut);
171
+ }
172
+ };
173
+
174
+ if (!options.live) this.each(function() { get(this); });
175
+
176
+ if (options.trigger != 'manual') {
177
+ var binder = options.live ? 'live' : 'bind',
178
+ eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
179
+ eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
180
+ this[binder](eventIn, enter)[binder](eventOut, leave);
181
+ }
182
+
183
+ return this;
184
+
185
+ };
186
+
187
+ $.fn.tipsy.defaults = {
188
+ className: null,
189
+ delayIn: 0,
190
+ delayOut: 0,
191
+ fade: false,
192
+ fallback: '',
193
+ gravity: 'n',
194
+ html: false,
195
+ live: false,
196
+ offset: 0,
197
+ opacity: 0.8,
198
+ title: 'title',
199
+ trigger: 'hover'
200
+ };
201
+
202
+ $.fn.tipsy.revalidate = function() {
203
+ $('.tipsy').each(function() {
204
+ var pointee = $.data(this, 'tipsy-pointee');
205
+ if (!pointee || !isElementInDOM(pointee)) {
206
+ $(this).remove();
207
+ }
208
+ });
209
+ };
210
+
211
+ // Overwrite this method to provide options on a per-element basis.
212
+ // For example, you could store the gravity in a 'tipsy-gravity' attribute:
213
+ // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
214
+ // (remember - do not modify 'options' in place!)
215
+ $.fn.tipsy.elementOptions = function(ele, options) {
216
+ return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
217
+ };
218
+
219
+ $.fn.tipsy.autoNS = function() {
220
+ return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
221
+ };
222
+
223
+ $.fn.tipsy.autoWE = function() {
224
+ return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
225
+ };
226
+
227
+ /**
228
+ * yields a closure of the supplied parameters, producing a function that takes
229
+ * no arguments and is suitable for use as an autogravity function like so:
230
+ *
231
+ * @param margin (int) - distance from the viewable region edge that an
232
+ * element should be before setting its tooltip's gravity to be away
233
+ * from that edge.
234
+ * @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer
235
+ * if there are no viewable region edges effecting the tooltip's
236
+ * gravity. It will try to vary from this minimally, for example,
237
+ * if 'sw' is preferred and an element is near the right viewable
238
+ * region edge, but not the top edge, it will set the gravity for
239
+ * that element's tooltip to be 'se', preserving the southern
240
+ * component.
241
+ */
242
+ $.fn.tipsy.autoBounds = function(margin, prefer) {
243
+ return function() {
244
+ var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)},
245
+ boundTop = $(document).scrollTop() + margin,
246
+ boundLeft = $(document).scrollLeft() + margin,
247
+ $this = $(this);
248
+
249
+ if ($this.offset().top < boundTop) dir.ns = 'n';
250
+ if ($this.offset().left < boundLeft) dir.ew = 'w';
251
+ if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e';
252
+ if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's';
253
+
254
+ return dir.ns + (dir.ew ? dir.ew : '');
255
+ }
256
+ };
257
+
258
+ })(jQuery);
assets/js/learnpress.js ADDED
@@ -0,0 +1,602 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ if (typeof LearnPress == 'undefined') window.LearnPress = {};
2
+ ;
3
+ (function ($) {
4
+
5
+ $.fn.outerHTML = function () {
6
+ // IE, Chrome & Safari will comply with the non-standard outerHTML, all others (FF) will have a fall-back for cloning
7
+ return (!this.length) ? this : (this[0].outerHTML || (function (el) {
8
+ var div = document.createElement('div');
9
+ div.appendChild(el.cloneNode(true));
10
+ var contents = div.innerHTML;
11
+ div = null;
12
+ return $(contents);
13
+ })(this[0]));
14
+
15
+ }
16
+ $.extend(LearnPress, {
17
+ complete_lesson: function (lesson, user_id) {
18
+ $.ajax({
19
+ type : "POST",
20
+ dataType: 'html',
21
+ url : ajaxurl,
22
+ data : {
23
+ action : 'learnpress_complete_lesson',
24
+ lesson : lesson,
25
+ user_id: user_id
26
+ },
27
+ success : function (response) {
28
+ var response = LearnPress.parseJSON(response);
29
+ response = $(document).triggerHandler('learn_press_user_complete_lesson', response);
30
+ if(response.result == 'success'){
31
+ $('.course-item-' + lesson).addClass('item-completed');
32
+ }
33
+ if (response.url) {
34
+ LearnPress.reload(response.url)
35
+ } else {
36
+ LearnPress.reload();
37
+ }
38
+ }
39
+ })
40
+ },
41
+ retake_course : function (course_id, user_id) {
42
+ $.ajax({
43
+ type : 'POST',
44
+ url : '',
45
+ data : {
46
+ action : 'learn_press_retake_course',
47
+ course_id: course_id,
48
+ user_id : user_id
49
+ },
50
+ success: function (response) {
51
+ if (response) {
52
+ if (response.message) alert(response.message);
53
+ if (response.redirect)
54
+ LearnPress.reload(response.redirect)
55
+ }
56
+ }
57
+ });
58
+ },
59
+ finishCourse : function (course_id, callback) {
60
+ if (!confirm(confirm_finish_course.confirm_finish_course)) return;
61
+
62
+ LearnPress.doAjax({
63
+ action: 'finish_course_x',
64
+ data: {
65
+ xxx: 1,
66
+ yyy: 2
67
+ },
68
+ success: function(res){
69
+ console.log(res)
70
+ }
71
+ });
72
+ return;
73
+ $.ajax({
74
+ type : "POST",
75
+ url : window,
76
+ data : {
77
+ action : 'learnpress_finish_course',
78
+ course_id: course_id
79
+ },
80
+ success: function (response) {
81
+ if (response.result == 'success') {
82
+
83
+ }
84
+ $.isFunction( callback ) && callback(response);
85
+ LearnPress.Hook.doAction( 'learn_press_user_finish_course', course_id, response );
86
+ }
87
+ });
88
+ },
89
+
90
+ load_lesson: function (permalink, args) {
91
+ args = $.extend({
92
+ success: function () {
93
+ },
94
+ error : function () {
95
+ }
96
+ }, args || {})
97
+ $.ajax({
98
+ url : permalink,
99
+ success: function (response) {
100
+ var $response = $(response),
101
+ $new_lesson = $('.course-content', $response);
102
+ if ($new_lesson.length) {
103
+ $('.course-content').replaceWith($new_lesson);
104
+ $('title').html($response.filter('title').text());
105
+ $.isFunction(args.success) && args.success.call(this, response)
106
+ } else {
107
+ if (!( $.isFunction(args.error) && args.error.call(this, response) )) {
108
+ alert("UNKNOW ERROR")
109
+ }
110
+ }
111
+ }
112
+ })
113
+ }
114
+ });
115
+
116
+ var $doc = $(document),
117
+ $win = $(window);
118
+
119
+ function complete_lesson(event) {
120
+ event.preventDefault();
121
+ if (!confirm(learn_press_js_localize.confirm_complete_lesson)) return;
122
+ var lesson = $(this).attr('data-id');
123
+ LearnPress.complete_lesson(lesson);
124
+ }
125
+
126
+ function finish_course() {
127
+ var $button = $(this),
128
+ course_id = $button.data('id');
129
+ LearnPress.finish_course(course_id);
130
+ }
131
+
132
+ function retake_course() {
133
+ if (!confirm(learn_press_js_localize.confirm_retake_course)) return;
134
+ var $button = $(this),
135
+ course_id = $button.data('id');
136
+ LearnPress.retake_course(course_id);
137
+ }
138
+
139
+ function load_lesson(evt) {
140
+ return;
141
+ evt.preventDefault();
142
+ var $link = $(this),
143
+ $parent = $link.parent(),
144
+ permalink = $link.attr('href');
145
+ if (!$link.data('id')) return false;
146
+ if ($parent.hasClass('current')) return false;
147
+ if ($parent.hasClass('course-lesson')) {
148
+ $('.curriculum-sections .course-lesson.loading').removeClass('loading')
149
+ $parent.addClass('loading')
150
+ }
151
+ history.pushState({}, '', permalink);
152
+ LearnPress.load_lesson(permalink, {
153
+ success: function () {
154
+ $('.curriculum-sections .course-lesson.current').removeClass('current')
155
+ if ($parent.hasClass('course-lesson')) {
156
+ $parent.removeClass('loading');
157
+ $parent.addClass('current');
158
+ } else {
159
+ $('.curriculum-sections .course-lesson a[lesson-id="' + $link.data('id') + '"]').parent().addClass('current')
160
+ }
161
+ $('body, html').fadeIn(100).delay(300).animate({scrollTop: $('.course-content').offset().top - 50}, 'slow');
162
+ }
163
+ });
164
+ }
165
+
166
+ function _ready() {
167
+ /*$doc
168
+ .on('click', '.complete-lesson-button', complete_lesson)
169
+ .on('click', '#finish-course', finish_course)
170
+ .on('click', '#learn_press_retake_course', retake_course)
171
+ .on('click', '.course-content-lesson-nav a', load_lesson)
172
+ .on('click', '.section-content .course-lesson a', load_lesson);
173
+ */
174
+ $('.lesson-quiz-icon', '.section-content').each(function () {
175
+ var $target = $(this), $parent = $target.closest('li');
176
+ $target.tipsy({
177
+ title : function () {
178
+ var tip = undefined;
179
+ if ($parent.hasClass('completed')) {
180
+ tip = $('#lesson-quiz-tip-completed-' + $(this).next().data('id')).html();
181
+ } else if ($parent.hasClass('current')) {
182
+ tip = $('#lesson-quiz-tip-current-' + $(this).next().data('id')).html();
183
+ }
184
+ if (tip == undefined) {
185
+ tip = $('#lesson-quiz-tip-message-' + $(this).next().data('id')).html();
186
+ }
187
+ return tip;
188
+ },
189
+ gravity: 's',
190
+ fade : true,
191
+ html : true
192
+ })
193
+ });
194
+ }
195
+
196
+ $doc.ready(_ready);
197
+
198
+ })(jQuery);
199
+
200
+ ;
201
+ jQuery(document).ready(function ($) {
202
+ $('#clear_previous_submissions').click(function (event) {
203
+ event.preventDefault();
204
+ var $this = $(this);
205
+ var defaulttxt = $this.html();
206
+ $this.prepend('<i class="fa fa-spinner fa-spin">&nbsp;</i>');
207
+
208
+ $.ajax({
209
+ type : "POST",
210
+ url : ajaxurl,
211
+ data : {
212
+ action : 'clear_previous_submissions',
213
+ id : $this.attr('data-id'),
214
+ security: $this.attr('data-security')
215
+ },
216
+ cache : false,
217
+ success: function (html) {
218
+ $this.find('i').remove();
219
+ $this.html(html);
220
+ setTimeout(function () {
221
+ location.reload();
222
+ }, 3000);
223
+ }
224
+ });
225
+
226
+ });
227
+
228
+ $.ajaxSetup({cache: false});
229
+ $("#btn_roll").click(function () {
230
+ event.preventDefault();
231
+ var post_link = $(this).attr("rel");
232
+ $("#course_main").html("loading...");
233
+ $("#course_main").load(post_link);
234
+ return false;
235
+ });
236
+ });
237
+
238
+ jQuery(document).ready(function ($) {
239
+ $('.quiz-curriculum').click(function (event) {
240
+ event.preventDefault();
241
+
242
+ $.ajax({
243
+ type : "POST",
244
+ url : ajaxurl,
245
+ data : {
246
+ action: 'learnpress_list_quiz'
247
+ },
248
+ success: function (html) {
249
+ $('.course-content').html(html);
250
+ }
251
+ })
252
+ })
253
+ });
254
+
255
+ jQuery(document).ready(function ($) {
256
+ $('.list-quiz-question').click(function (event) {
257
+ event.preventDefault();
258
+ var $this = $(this);
259
+
260
+ $.ajax({
261
+ type : "POST",
262
+ url : ajaxurl,
263
+ data : {
264
+ action : 'learnpress_load_quiz_question',
265
+ course_id : $('.quiz-main').attr('course-id'),
266
+ quiz_id : window.quiz_id,
267
+ question_id: $this.attr('question-id')
268
+ },
269
+ success: function (html) {
270
+ $('.quiz-question').html(html);
271
+ $('.qq').removeClass('current');
272
+ var cl = ".qq:nth-child(" + $this.attr('question-index') + ")";
273
+ $(cl).addClass('current');
274
+ //$this.attr('question-id').addClass('active');
275
+
276
+ if (jQuery('.quiz-questions li').first().hasClass('current')) {
277
+ jQuery('.button-prev-question').addClass('hidden');
278
+ } else if ($('.button-prev-question').hasClass('hidden')) {
279
+ $('.button-prev-question').removeClass('hidden')
280
+ }
281
+
282
+
283
+ if (jQuery('.quiz-questions li').last().hasClass('current')) {
284
+ jQuery('.button-next-question').addClass('hidden');
285
+ } else if ($('.button-next-question').hasClass('hidden')) {
286
+ $('.button-next-question').removeClass('hidden');
287
+ }
288
+ }
289
+ });
290
+ });
291
+ });
292
+
293
+ jQuery(document).ready(function ($) {
294
+ $('.lesson_curriculum').click(function (event) {
295
+ event.preventDefault();
296
+ var $this = $(this);
297
+ var $url = $(this).attr('href');
298
+ var link = window.location.href;
299
+
300
+ $.ajax({
301
+ type : "POST",
302
+ url : $url, //ajaxurl,
303
+ data : {
304
+ action : 'learnpress_load_lesson_content',
305
+ lesson_id: $(this).attr('lesson-id')
306
+ },
307
+ success: function (html) {
308
+ LearnPress.log($url);
309
+ history.pushState({}, '', $url);
310
+ $('.course-content').html($('.course-content', html).html());
311
+ $('html, body').animate({scrollTop: $('.course-content').offset().top}, 'slow');
312
+ $('.button-prev-lesson').removeClass('hidden');
313
+ $('.button-complete-lesson').removeClass('hidden');
314
+ $('.button-next-lesson').removeClass('hidden');
315
+ $('.course-curriculum').find('.current').removeClass('current');
316
+ $this.addClass('current');
317
+ }
318
+ });
319
+ });
320
+ });
321
+
322
+ jQuery(document).ready(function ($) {
323
+ $('.button-finish-quiz').click(function ($event) {
324
+ return;
325
+ $event.preventDefault();
326
+ var $temp = jQuery(".question-form").serializeArray();
327
+ var $question_answer = 1;
328
+ if (0 < $temp.length) {
329
+ $question_answer = $temp[0].value;
330
+ }
331
+ var $question_id = jQuery('.quiz-questions').find('li.current a').attr('question-id');
332
+
333
+ $.ajax({
334
+ type : "POST",
335
+ url : ajaxurl,
336
+ data : {
337
+ action : 'learnpress_finish_quiz',
338
+ course_id : $('.quiz-main').attr('course-id'),
339
+ quiz_id : $(this).attr('quiz-id'),
340
+ question_id : $question_id,
341
+ question_answer: $question_answer
342
+ },
343
+ success: function (html) {
344
+ LearnPress.log(html);
345
+ location.reload(true);
346
+ }
347
+ })
348
+ })
349
+ });
350
+
351
+ jQuery(document).ready(function ($) {
352
+ $('#lpr-join-event').click(function (event) {
353
+ event.preventDefault();
354
+ var $this = $(this);
355
+
356
+ $.ajax({
357
+ type : "POST",
358
+ url : ajaxurl,
359
+ data : {
360
+ action : 'learnpress_join_event',
361
+ event_id: $(this).attr('event-id')
362
+ },
363
+ success: function (html) {
364
+ $this.html(html);
365
+ $this.removeAttr('id').attr('id', 'lpr-not-going');
366
+ }
367
+ });
368
+ });
369
+ });
370
+
371
+ jQuery(document).ready(function ($) {
372
+ $('#lpr-not-going').click(function (event) {
373
+ event.preventDefault();
374
+ var $this = $(this);
375
+
376
+ $.ajax({
377
+ type : "POST",
378
+ url : ajaxurl,
379
+ data : {
380
+ action : 'learnpress_not_going',
381
+ event_id: $(this).attr('event-id')
382
+ },
383
+ success: function (html) {
384
+ $this.html(html);
385
+ $this.removeAttr('id').attr('id', 'lpr-join-event');
386
+ }
387
+ });
388
+ });
389
+ });
390
+
391
+
392
+ jQuery(document).ready(function ($) {
393
+ $('.course-free-button').click(function (event) {
394
+ event.preventDefault();
395
+ var $this = $(this);
396
+ $.ajax({
397
+ type : "POST",
398
+ url : ajaxurl,
399
+ data : {
400
+ action : 'learnpress_take_free_course',
401
+ course_id: $this.attr('course-id')
402
+ },
403
+ success: function (html) {
404
+ if (html == 'not prerequisite') {
405
+ //jAlert('You have to complete prereqisite courses before taking this course');
406
+ $('.error-notice').html('You have to complete prereqisite courses before taking this course');
407
+ } else if (html == 'not logged in') {
408
+ $('.error-notice').html('You have to log in to take this course');
409
+ } else {
410
+ location.reload(true);
411
+ }
412
+ }
413
+ })
414
+ });
415
+
416
+ $('#myModal').on('shown.bs.modal', function () {
417
+ $('#myInput').focus()
418
+ })
419
+ });
420
+
421
+ jQuery(document).ready(function ($) {
422
+ $('.button-prev-lesson').on("click", function (event) {
423
+ event.preventDefault();
424
+ var $lesson_link = $('.course-curriculum').find('.current').parent().prevAll('.course-lesson').first().find('a').attr('href');
425
+ var $current = $('.course-curriculum').find('.current');
426
+
427
+ if ($lesson_link != '') {
428
+ window.location.replace($lesson_link);
429
+ } else {
430
+ $.ajax({
431
+ type : "POST",
432
+ url : ajaxurl,
433
+ data : {
434
+ action : 'learnpress_load_prev_lesson',
435
+ lesson_id: $('.course-curriculum').find('.current').parent().prevAll('.course-lesson').first().find('a').attr('lesson-id')
436
+ },
437
+ success: function (html) {
438
+ $('.course-content').html(html);
439
+ $current.removeClass('current');
440
+ $current.parent().prevAll('.course-lesson').first().find('a').addClass('current');
441
+ var $forum_link = $('.course-curriculum').find('.current').attr('data-link');
442
+ $('.button-forum').removeClass('hidden').attr('href', $forum_link);
443
+ }
444
+ })
445
+ }
446
+ });
447
+ });
448
+
449
+ jQuery(document).ready(function ($) {
450
+ $('.button-next-lesson').on("click", function (event) {
451
+ event.preventDefault();
452
+ var $lesson_link = $('.course-curriculum').find('.current').parent().nextAll('.course-lesson').first().find('a').attr('href');
453
+ var $current = $('.course-curriculum').find('.current');
454
+
455
+ if ($lesson_link != '') {
456
+ window.location.replace($lesson_link);
457
+ } else {
458
+ $.ajax({
459
+ type : "POST",
460
+ url : ajaxurl,
461
+ data : {
462
+ action : 'learnpress_load_next_lesson',
463
+ lesson_id: $('.course-curriculum').find('.current').parent().nextAll('.course-lesson').first().find('a').attr('lesson-id')
464
+ },
465
+ success: function (html) {
466
+ $('.course-content').html(html);
467
+ $current.removeClass('current');
468
+ $current.parent().nextAll('.course-lesson').first().find('a').addClass('current');
469
+ }
470
+ })
471
+ }
472
+ });
473
+ });
474
+
475
+
476
+ jQuery(document).ready(function ($) {
477
+
478
+ $('.button-finish-course').click(function (event) {
479
+ event.preventDefault();
480
+ var $this = $(this);
481
+ var $certi_link = $this.attr("certi_link");
482
+ LearnPress.log($certi_link);
483
+ $.ajax({
484
+ type : "POST",
485
+ url : ajaxurl,
486
+ data : {
487
+ action : 'learnpress_finish_course',
488
+ course_id: $this.attr('course-id')
489
+ },
490
+ success: function (html) {
491
+ LearnPress.log(html);
492
+ if (html == 'success') {
493
+ if ($certi_link) {
494
+ window.location.replace($certi_link);
495
+ } else {
496
+ jAlert('Congratulation ! You have finished this course.')
497
+ }
498
+ } else {
499
+ jAlert(html);
500
+ }
501
+ }
502
+ })
503
+ });
504
+
505
+ var $payment_form = $('form[name="learn_press_payment_form"]');
506
+ $('input[name="payment_method"]', $payment_form).click(function () {
507
+ var $this = $(this);
508
+ if ($this.is(":checked")) {
509
+ $this.closest('li').find('.learn_press_payment_form').slideDown();
510
+ $('.learn_press_payment_form', $this.closest('li').siblings()).slideUp();
511
+ }
512
+ });
513
+ $('#learn_press_take_course')
514
+ .click(function () {
515
+ var button = $(this),
516
+ payment_methods = $('input[name="payment_method"]', $payment_form),
517
+ take = false,
518
+ payment = payment_methods.filter(":checked").val();
519
+ if (0 == payment_methods.length) {
520
+ take = true;
521
+ } else if (1 == payment_methods.length) {
522
+ payment_methods.attr('checked', true);
523
+ take = true;
524
+ } else {
525
+ if ($payment_form.is(':visible')) {
526
+ if (!payment) {
527
+ alert(learn_press_js_localize.no_payment_method);
528
+ return;
529
+ } else {
530
+ take = true
531
+ }
532
+ } else {
533
+ $payment_form.show();
534
+ return;
535
+ }
536
+ }
537
+ if (!take) return;
538
+ $(this).html($(this).data('loading-text') || 'Processing').attr('disabled', true);
539
+ if ($payment_form.triggerHandler('learn_press_place_order') !== false && $payment_form.triggerHandler('learn_press_place_order_' + payment) !== false) {
540
+ var data = {
541
+ action : 'learnpress_take_course',
542
+ payment_method: payment_methods.filter(":checked").val(),
543
+ course_id : button.data('id'),
544
+ data : $payment_form.serialize()
545
+ }
546
+
547
+ $.ajax({
548
+ url : ajaxurl,
549
+ type : 'POST',
550
+ dataType: 'html',
551
+ data : $payment_form.serialize(),
552
+ success : function (res) {
553
+ var matches = res.match(/<!-- LP_AJAX_START -->(.*)<!-- LP_AJAX_END -->/),
554
+ message = '';
555
+ if (matches && matches[1]) {
556
+ var json = JSON.parse(matches[1]);
557
+ if (json) {
558
+ if (json.redirect && (json.result.toLowerCase() == 'success')) {
559
+ window.location.href = json.redirect;
560
+ return;
561
+ } else {
562
+ message = json.message
563
+ }
564
+ } else {
565
+ message = matches[1];
566
+ }
567
+ } else {
568
+ message = res
569
+ }
570
+ if (message) {
571
+ alert(message);
572
+ }
573
+ button.removeAttr('disabled').html(button.data('text'))
574
+ }
575
+ });
576
+ }
577
+ return false;
578
+ });
579
+ });
580
+
581
+ jQuery(document).ready(function ($) {
582
+ $('#wp-admin-bar-be_teacher').click(function () {
583
+ $.ajax({
584
+ url : ajaxurl,
585
+ data : {
586
+ action: 'learnpress_be_teacher'
587
+ },
588
+ success: function () {
589
+ alert(learn_press_js_localize.you_are_instructor_now);
590
+ setTimeout(function () {
591
+ location.reload();
592
+ }, 500);
593
+ }
594
+ })
595
+ });
596
+ });
597
+
598
+ // jQuery(document).ready(function ($) {
599
+ // $('#question-hint').on('click', function(){
600
+ // $('.question-hint-content').fadeToggle();
601
+ // });
602
+ // });
assets/js/toJSON.js ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($){
2
+ $.fn.toJSON = function(options){
3
+ options = $.extend({}, options);
4
+ var self = this,
5
+ json = {},
6
+ push_counters = {},
7
+ patterns = {
8
+ "validate": /^[a-zA-Z_\-][a-zA-Z0-9_\-]*(?:\[(?:\d*|[a-zA-Z0-9_\-]+)\])*$/,
9
+ "key": /[a-zA-Z0-9_\-]+|(?=\[\])/g,
10
+ "push": /^$/,
11
+ "fixed": /^\d+$/,
12
+ "named": /^[a-zA-Z0-9_\-]+$/
13
+ };
14
+ this.build = function(base, key, value){
15
+ base[key] = value;
16
+ return base;
17
+ };
18
+ this.push_counter = function(key){
19
+ if(push_counters[key] === undefined){
20
+ push_counters[key] = 0;
21
+ }
22
+ return push_counters[key]++;
23
+ };
24
+
25
+ $.each($(this).serializeArray(), function(){
26
+ //alert(this.name)
27
+ // skip invalid keys
28
+ if(!patterns.validate.test(this.name)){
29
+ return;
30
+ }
31
+ //alert(this.name)
32
+ var k,
33
+ keys = this.name.match(patterns.key),
34
+ merge = this.value,
35
+ reverse_key = this.name;
36
+ while((k = keys.pop()) !== undefined){
37
+ // adjust reverse_key
38
+ reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');
39
+ // push
40
+ if(k.match(patterns.push)){
41
+ var key = self.push_counter(reverse_key);
42
+ merge = self.build([], key, merge);
43
+ }
44
+ // fixed
45
+ else if(k.match(patterns.fixed)){
46
+ merge = self.build([], k, merge);
47
+ }
48
+
49
+ // named
50
+ else if(k.match(patterns.named)){
51
+ merge = self.build({}, k, merge);
52
+ }
53
+ }
54
+ json = $.extend(true, json, merge);
55
+ });
56
+ var trimObject = function(obj){
57
+ if(typeof obj == 'undefined') return ;
58
+ if(obj.constructor === Array){
59
+ obj.clean(null);
60
+ for(var i = 0; i < obj.length;i++) trimObject(obj[i]);
61
+ }else if(obj.constructor === Object){
62
+
63
+ for(var i in obj){
64
+ trimObject(obj[i]);
65
+ }
66
+ }
67
+
68
+ }
69
+ //trimObject(json);
70
+ return json;
71
+ };
72
+
73
+ jQuery.fn.serializeObject = function() {
74
+ var arrayData, objectData;
75
+ arrayData = this.serializeArray();
76
+ objectData = {};
77
+
78
+ $.each(arrayData, function() {
79
+ var value;
80
+
81
+ if (this.value != null) {
82
+ value = this.value;
83
+ } else {
84
+ value = '';
85
+ }
86
+
87
+ if (objectData[this.name] != null) {
88
+ if (!objectData[this.name].push) {
89
+ objectData[this.name] = [objectData[this.name]];
90
+ }
91
+
92
+ objectData[this.name].push(value);
93
+ } else {
94
+ objectData[this.name] = value;
95
+ }
96
+ });
97
+
98
+ return objectData;
99
+ };
100
+ })(jQuery);
changelog.md ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ **0.9.14**
2
+ - Fixed can not start a quiz for guest.
3
+ - Fixed course evaluation error and shows wrong message
4
+ - Added "preload icon" for quiz actions and question navigation
5
+ - Added option for instructors registration
6
+ - Updated default language file.
7
+
8
+ **0.9.13.1**
9
+ - Added lacked files.
10
+
11
+ **0.9.13**
12
+ - Fixed profile link problem.
13
+ - Fixed conflict with Woo payments add-on.
14
+ - Added shortcodes to display free courses, paid courses and newest courses.
15
+ - Added shortcodes to display course summary.
16
+ - Provided premium add-on assignments.
17
+ - Provided premium add-on gradebook.
18
+
19
+ **0.9.12**
20
+ - Support languages: Italian, Indonesian, German.
21
+
22
+ **0.9.11**
23
+ - Fixed resets all user settings back to default when re-active LearnPress.
24
+ - Fixed certificates trigger error "header already sent" when saving templates.
25
+ - Made translatable strings in javascript code.
26
+ - Fixed course review add-on error on PHP version 5.3.x.
27
+ - Fixed text domain error on translating plugin.
28
+
29
+ **0.9.10**
30
+ - Fixed bug: Template loader missing header and footer.
31
+ - Updated default language file.
32
+
33
+ **0.9.9**
34
+ - Fixed bug: Course price always showing "FREE" on category page.
35
+ - Updated language Polish.
36
+
37
+ **0.9.8**
38
+ - Fixed wrong placeholder in email settings.
39
+ - Updated addon Certificates for GUI and functions with more options
40
+ - Used Google Fonts instead of True Type Font (*.ttf)
41
+ - Color picker
42
+ - Text align (vertical and horizontal)
43
+ - Text rotation
44
+ - Text transform ( scale X and scale Y)
45
+ - More options to display the name of a user:
46
+ + User login
47
+ + User nice name
48
+ + Nickname
49
+ + First name
50
+ + Last name
51
+ + First name then Last name
52
+ + Last name then First name
53
+ - Support Dutch and French (special thank to Bart Kleijheeg and fxbenard)
54
+
55
+ **0.9.7**
56
+ Fixed wrong query of quizzes result in Profile.
57
+
58
+ **0.9.6**
59
+ - Fix translation textdomain error - Thank polischmen for your concern.
60
+ - Updated question hint
61
+ - Option to set course is public or enrolled require
62
+ - Certificates add-on:
63
+ - Add more fonts
64
+ - Option to display the full name with {firstname}=User first name and {lastname}=User last name
65
+ - Option to format date
66
+ - Created a sample Certificate when plugin is activated
67
+
68
+
69
+ **0.9.5**
70
+ - Added showing question answer and explaination feature
71
+ - Fixed bugs for addon Fill In Blank question
72
+ - Fixed bugs for addon Sorting Choice question
73
+ - Fixed bugs for addon Certificates
74
+ - Fixed bugs for addon WooCommerce Payment
75
+ - Prevent access to lesson directly by using permalink
76
+ - Random quiz questions addon (premium add-on)
77
+ - Content Drip addon (premium add-on)
78
+ - Support multi language
79
+
80
+ **0.9.4**
81
+ - Set up sample data for LearnPress
82
+ - Provided sorting question type (you can find it in premium add-on list)
83
+ - Provided fill in blank question type (we are uploading it to WordPress.org so if you cannot find it, wait for it to be available soon)
84
+ - Fixed bug profile template
85
+ - Updated LearnPress profile method
86
+
87
+ **0.9.3**
88
+ - Fix menu position problem (3.14).
89
+ - Fix bug shortcut key @l to insert lesson link when writing a lesson.
90
+ - Fix bug when add Lesson/Quiz into a section but it is not assigned to the course.
91
+ - List the addons from wordpress.org in addons page.
92
+ - Add new option into settings page lets to choose the page to display form "Become a teacher".
93
+ - Add shortcode to insert form "Become a teacher".
94
+ - Update lesson/quiz title also update its slug.
95
+ - Align review form to center of the page.
96
+ - Course review pagination.
97
+ - Provide related courses function.
98
+ - Support full width embed video.
99
+
100
+ **0.9.2**
101
+ - Update add-on management page.
102
+ - Add auto next lesson after complete a quiz feature.
103
+ - Fix course-review bugs.
104
+ - Fix bug on curriculum when use "shift + (" or "shift+&" ..... to edit Lesson title or Section title.
105
+ - Fix course result bug.
106
+ - Fix export/import addon - sometime the image is not imported.
107
+ - Fix bug show certificate after user finished a course.
108
+
109
+ **0.9.1**
110
+ The first beta release.
111
+
112
+ **Upgrade Notice**
113
+ *0.9.2*
114
+ We have changed directory structure and separated all out core add-ons to become independence plugins, so after upgrading version, if you face any add-ons problems, please completely delete the old version and re-install LearnPress. Thank!
dummy-data/dummy-data.xml ADDED
@@ -0,0 +1,1453 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <rss version="2.0"
3
+ xmlns:excerpt="http://wordpress.org/export/LPR_EXPORT_VER/excerpt/"
4
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
5
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
6
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
7
+ xmlns:wp="http://wordpress.org/export/LPR_EXPORT_VER/"
8
+ >
9
+ <channel>
10
+ <title>DEV LearnPress 1.0</title>
11
+ <link>http://localhost/foobla/learnpress/1.0</link>
12
+ <description>Just another WordPress site</description>
13
+ <pubDate>Sat, 09 Jan 2016 07:59:54 +0000</pubDate>
14
+ <language>en-US</language>
15
+ <wp:wxr_version>1.0</wp:wxr_version>
16
+ <wp:base_site_url>http://localhost/foobla/learnpress/1.0</wp:base_site_url>
17
+ <wp:base_blog_url>http://localhost/foobla/learnpress/1.0</wp:base_blog_url>
18
+ <wp:plugin_name>learnpress</wp:plugin_name>
19
+ <wp:plugin_version>1.0</wp:plugin_version>
20
+ <wp:author><wp:author_id>1</wp:author_id><wp:author_login>admin</wp:author_login><wp:author_email>tunnhn@gmail.com</wp:author_email><wp:author_display_name><![CDATA[admin]]></wp:author_display_name><wp:author_first_name><![CDATA[]]></wp:author_first_name><wp:author_last_name><![CDATA[]]></wp:author_last_name></wp:author>
21
+ <item>
22
+ <title>This is a new course</title>
23
+ <link>http://localhost/foobla/learnpress/1.0/dao-tao-cac-khoa-hoc-onine/this-is-a-new-course/</link>
24
+ <pubDate>Wed, 11 Nov 2015 10:45:53 +0000</pubDate>
25
+ <dc:creator><![CDATA[admin]]></dc:creator>
26
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/?post_type=lp_course&#038;p=873</guid>
27
+ <description></description>
28
+ <content:encoded><![CDATA[]]></content:encoded>
29
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
30
+ <wp:post_id>1511</wp:post_id>
31
+ <wp:post_date>2015-11-11 10:45:53</wp:post_date>
32
+ <wp:post_date_gmt>2015-11-11 10:45:53</wp:post_date_gmt>
33
+ <wp:comment_status>open</wp:comment_status>
34
+ <wp:ping_status>open</wp:ping_status>
35
+ <wp:post_name>this-is-a-new-course</wp:post_name>
36
+ <wp:status>publish</wp:status>
37
+ <wp:post_parent>0</wp:post_parent>
38
+ <wp:menu_order>0</wp:menu_order>
39
+ <wp:post_type>lp_course</wp:post_type>
40
+ <wp:post_password></wp:post_password>
41
+ <wp:post_author_id>1</wp:post_author_id>
42
+ <wp:is_sticky>0</wp:is_sticky>
43
+ <wp:postmeta>
44
+ <wp:meta_key>_edit_lock</wp:meta_key>
45
+ <wp:meta_value><![CDATA[1451441611:1]]></wp:meta_value>
46
+ </wp:postmeta> <wp:postmeta>
47
+ <wp:meta_key>_edit_last</wp:meta_key>
48
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
49
+ </wp:postmeta> <wp:postmeta>
50
+ <wp:meta_key>_lp_duration</wp:meta_key>
51
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
52
+ </wp:postmeta> <wp:postmeta>
53
+ <wp:meta_key>_lp_max_students</wp:meta_key>
54
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
55
+ </wp:postmeta> <wp:postmeta>
56
+ <wp:meta_key>_lp_students</wp:meta_key>
57
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
58
+ </wp:postmeta> <wp:postmeta>
59
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
60
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
61
+ </wp:postmeta> <wp:postmeta>
62
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
63
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
64
+ </wp:postmeta> <wp:postmeta>
65
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
66
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
67
+ </wp:postmeta> <wp:postmeta>
68
+ <wp:meta_key>_lp_payment</wp:meta_key>
69
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
70
+ </wp:postmeta> <wp:postmeta>
71
+ <wp:meta_key>_lpr_course_lesson_quiz</wp:meta_key>
72
+ <wp:meta_value><![CDATA[]]></wp:meta_value>
73
+ </wp:postmeta> <wp:postmeta>
74
+ <wp:meta_key>_lp_course_status</wp:meta_key>
75
+ <wp:meta_value><![CDATA[publish]]></wp:meta_value>
76
+ </wp:postmeta> <wp:postmeta>
77
+ <wp:meta_key>_lp_curriculum</wp:meta_key>
78
+ <wp:meta_value><![CDATA[a:1:{i:0;a:3:{s:4:"name";s:10:"Section #1";s:11:"description";s:0:"";s:5:"items";a:2:{i:614;a:5:{s:4:"name";s:18:"word wide web 2222";s:8:"old_name";s:13:"word wide web";s:7:"item_id";s:4:"1232";s:15:"section_item_id";s:3:"614";s:9:"post_type";s:9:"lp_lesson";}s:6:"item-1";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}}]]></wp:meta_value>
79
+ </wp:postmeta>
80
+ <wp:section>
81
+ <wp:section_id>207</wp:section_id>
82
+ <wp:section_name>Section #1</wp:section_name>
83
+ <wp:section_course_id>1511</wp:section_course_id>
84
+ <wp:section_order>1</wp:section_order>
85
+ <wp:section_description><![CDATA[]]></wp:section_description>
86
+ <wp:section_item>
87
+ <wp:section_id>207</wp:section_id>
88
+ <wp:item_id>1512</wp:item_id>
89
+ <wp:item_order>1</wp:item_order>
90
+ <wp:item_type>lp_lesson</wp:item_type>
91
+ </wp:section_item>
92
+ </wp:section>
93
+
94
+ </item><item>
95
+ <title>word wide web 2222</title>
96
+ <link>http://localhost/foobla/learnpress/1.0/lessons/wwwwwwwwwwwwwwwwwwww/</link>
97
+ <pubDate>Wed, 30 Dec 2015 02:06:58 +0000</pubDate>
98
+ <dc:creator><![CDATA[admin]]></dc:creator>
99
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/?post_type=lp_lesson&#038;p=1232</guid>
100
+ <description></description>
101
+ <content:encoded><![CDATA[]]></content:encoded>
102
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
103
+ <wp:post_id>1512</wp:post_id>
104
+ <wp:post_date>2015-12-30 02:06:58</wp:post_date>
105
+ <wp:post_date_gmt>2015-12-30 02:06:58</wp:post_date_gmt>
106
+ <wp:comment_status>closed</wp:comment_status>
107
+ <wp:ping_status>closed</wp:ping_status>
108
+ <wp:post_name>wwwwwwwwwwwwwwwwwwww</wp:post_name>
109
+ <wp:status>publish</wp:status>
110
+ <wp:post_parent>0</wp:post_parent>
111
+ <wp:menu_order>0</wp:menu_order>
112
+ <wp:post_type>lp_lesson</wp:post_type>
113
+ <wp:post_password></wp:post_password>
114
+ <wp:post_author_id>1</wp:post_author_id>
115
+ <wp:is_sticky>0</wp:is_sticky>
116
+ <wp:postmeta>
117
+ <wp:meta_key>_edit_lock</wp:meta_key>
118
+ <wp:meta_value><![CDATA[1451443416:1]]></wp:meta_value>
119
+ </wp:postmeta>
120
+ </item> <item>
121
+ <title>What should be here?</title>
122
+ <link>http://localhost/foobla/learnpress/1.0/dao-tao-cac-khoa-hoc-onine/what-should-be-here/</link>
123
+ <pubDate>Fri, 04 Dec 2015 07:08:08 +0000</pubDate>
124
+ <dc:creator><![CDATA[admin]]></dc:creator>
125
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/?post_type=lp_course&#038;p=908</guid>
126
+ <description></description>
127
+ <content:encoded><![CDATA[Phasellus accumsan cursus velit. Phasellus nec sem in justo pellentesque facilisis. Fusce vel dui. Integer tincidunt. Quisque id odio.
128
+
129
+ Sed hendrerit. Morbi mattis ullamcorper velit. Phasellus dolor. Sed libero. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.
130
+
131
+ Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. Phasellus tempus. Donec posuere vulputate arcu. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Sed a libero.
132
+
133
+ Nam eget dui. Quisque ut nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Nunc nec neque. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam.
134
+
135
+ Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Vestibulum fringilla pede sit amet augue. Etiam rhoncus.]]></content:encoded>
136
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
137
+ <wp:post_id>1513</wp:post_id>
138
+ <wp:post_date>2015-12-04 07:08:08</wp:post_date>
139
+ <wp:post_date_gmt>2015-12-04 07:08:08</wp:post_date_gmt>
140
+ <wp:comment_status>open</wp:comment_status>
141
+ <wp:ping_status>open</wp:ping_status>
142
+ <wp:post_name>what-should-be-here</wp:post_name>
143
+ <wp:status>publish</wp:status>
144
+ <wp:post_parent>0</wp:post_parent>
145
+ <wp:menu_order>0</wp:menu_order>
146
+ <wp:post_type>lp_course</wp:post_type>
147
+ <wp:post_password></wp:post_password>
148
+ <wp:post_author_id>1</wp:post_author_id>
149
+ <wp:is_sticky>0</wp:is_sticky>
150
+ <category domain="course_category" nicename="it" id="18" parent="0" description=" "><![CDATA[IT]]></category>
151
+ <category domain="course_category" nicename="software" id="19" parent="18" description=" "><![CDATA[Software]]></category>
152
+ <wp:postmeta>
153
+ <wp:meta_key>_edit_lock</wp:meta_key>
154
+ <wp:meta_value><![CDATA[1452319104:1]]></wp:meta_value>
155
+ </wp:postmeta> <wp:postmeta>
156
+ <wp:meta_key>_edit_last</wp:meta_key>
157
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
158
+ </wp:postmeta> <wp:postmeta>
159
+ <wp:meta_key>_admin_hidden_sections</wp:meta_key>
160
+ <wp:meta_value><![CDATA[a:5:{i:0;s:3:"132";i:1;s:3:"133";i:2;s:3:"134";i:3;s:3:"135";i:4;s:0:"";}]]></wp:meta_value>
161
+ </wp:postmeta> <wp:postmeta>
162
+ <wp:meta_key>_lpr_course_lesson_quiz</wp:meta_key>
163
+ <wp:meta_value><![CDATA[]]></wp:meta_value>
164
+ </wp:postmeta> <wp:postmeta>
165
+ <wp:meta_key>_lp_curriculum</wp:meta_key>
166
+ <wp:meta_value><![CDATA[a:6:{i:0;a:3:{s:4:"name";s:10:"Section #1";s:11:"description";s:33:"asd asd asdasd asdasd asdasd asda";s:5:"items";a:15:{i:615;a:5:{s:4:"name";s:12:"333333333333";s:8:"old_name";s:12:"333333333333";s:7:"item_id";s:4:"1146";s:15:"section_item_id";s:3:"615";s:9:"post_type";s:7:"lp_quiz";}i:616;a:5:{s:4:"name";s:18:"where are you now?";s:8:"old_name";s:18:"where are you now?";s:7:"item_id";s:4:"1148";s:15:"section_item_id";s:3:"616";s:9:"post_type";s:9:"lp_lesson";}i:617;a:5:{s:4:"name";s:21:"I am here, beside you";s:8:"old_name";s:21:"I am here, beside you";s:7:"item_id";s:4:"1149";s:15:"section_item_id";s:3:"617";s:9:"post_type";s:7:"lp_quiz";}i:618;a:5:{s:4:"name";s:9:"asdasdasd";s:8:"old_name";s:9:"asdasdasd";s:7:"item_id";s:4:"1143";s:15:"section_item_id";s:3:"618";s:9:"post_type";s:9:"lp_lesson";}i:619;a:5:{s:4:"name";s:9:"dsfsdfsdf";s:8:"old_name";s:9:"dsfsdfsdf";s:7:"item_id";s:4:"1144";s:15:"section_item_id";s:3:"619";s:9:"post_type";s:9:"lp_lesson";}i:620;a:5:{s:4:"name";s:8:"Lesson 1";s:8:"old_name";s:8:"Lesson 1";s:7:"item_id";s:4:"1139";s:15:"section_item_id";s:3:"620";s:9:"post_type";s:9:"lp_lesson";}i:621;a:5:{s:4:"name";s:8:"Lesson 2";s:8:"old_name";s:8:"Lesson 2";s:7:"item_id";s:4:"1140";s:15:"section_item_id";s:3:"621";s:9:"post_type";s:9:"lp_lesson";}i:622;a:5:{s:4:"name";s:8:"Lesson 3";s:8:"old_name";s:8:"Lesson 3";s:7:"item_id";s:4:"1142";s:15:"section_item_id";s:3:"622";s:9:"post_type";s:9:"lp_lesson";}i:623;a:5:{s:4:"name";s:17:"qqqqqqqqqqqqqqqqq";s:8:"old_name";s:17:"qqqqqqqqqqqqqqqqq";s:7:"item_id";s:4:"1153";s:15:"section_item_id";s:3:"623";s:9:"post_type";s:9:"lp_lesson";}i:624;a:5:{s:4:"name";s:10:"trau va bo";s:8:"old_name";s:10:"trau va bo";s:7:"item_id";s:4:"1154";s:15:"section_item_id";s:3:"624";s:9:"post_type";s:9:"lp_lesson";}i:625;a:5:{s:4:"name";s:19:"adasdasdasda asd as";s:8:"old_name";s:19:"adasdasdasda asd as";s:7:"item_id";s:4:"1164";s:15:"section_item_id";s:3:"625";s:9:"post_type";s:9:"lp_lesson";}i:626;a:5:{s:4:"name";s:19:"asd asda sdasdas da";s:8:"old_name";s:19:"asd asda sdasdas da";s:7:"item_id";s:4:"1165";s:15:"section_item_id";s:3:"626";s:9:"post_type";s:9:"lp_lesson";}i:627;a:5:{s:4:"name";s:16:"asdasdasdasdasda";s:8:"old_name";s:16:"asdasdasdasdasda";s:7:"item_id";s:4:"1166";s:15:"section_item_id";s:3:"627";s:9:"post_type";s:9:"lp_lesson";}i:628;a:5:{s:4:"name";s:18:"assasdasdasdasdasd";s:8:"old_name";s:18:"assasdasdasdasdasd";s:7:"item_id";s:4:"1167";s:15:"section_item_id";s:3:"628";s:9:"post_type";s:9:"lp_lesson";}s:7:"item-14";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}i:1;a:3:{s:4:"name";s:10:"Section #2";s:11:"description";s:49:"asdas das d asdas das asdasd asdas dasdas dasdasd";s:5:"items";a:5:{i:629;a:5:{s:4:"name";s:22:"How to create a course";s:8:"old_name";s:22:"How to create a course";s:7:"item_id";s:4:"1169";s:15:"section_item_id";s:3:"629";s:9:"post_type";s:9:"lp_lesson";}i:630;a:5:{s:4:"name";s:17:"What is your name";s:8:"old_name";s:17:"What is your name";s:7:"item_id";s:4:"1170";s:15:"section_item_id";s:3:"630";s:9:"post_type";s:9:"lp_lesson";}i:631;a:5:{s:4:"name";s:20:"My name is Tu Nguyen";s:8:"old_name";s:20:"My name is Tu Nguyen";s:7:"item_id";s:4:"1171";s:15:"section_item_id";s:3:"631";s:9:"post_type";s:9:"lp_lesson";}i:632;a:5:{s:4:"name";s:23:"sdfsdfsdf sdf sdf sdf s";s:8:"old_name";s:23:"sdfsdfsdf sdf sdf sdf s";s:7:"item_id";s:4:"1168";s:15:"section_item_id";s:3:"632";s:9:"post_type";s:7:"lp_quiz";}s:6:"item-4";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}i:2;a:3:{s:4:"name";s:10:"Section #3";s:11:"description";s:0:"";s:5:"items";a:2:{i:633;a:5:{s:4:"name";s:14:"sdfsd fsd fsdf";s:8:"old_name";s:14:"sdfsd fsd fsdf";s:7:"item_id";s:4:"1172";s:15:"section_item_id";s:3:"633";s:9:"post_type";s:7:"lp_quiz";}s:6:"item-1";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}i:3;a:3:{s:4:"name";s:10:"Section #4";s:11:"description";s:0:"";s:5:"items";a:2:{i:634;a:5:{s:4:"name";s:22:"sdf sdfsd fsdf sdfsd f";s:8:"old_name";s:22:"sdf sdfsd fsdf sdfsd f";s:7:"item_id";s:4:"1173";s:15:"section_item_id";s:3:"634";s:9:"post_type";s:7:"lp_quiz";}s:6:"item-1";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}i:4;a:3:{s:4:"name";s:10:"Section #5";s:11:"description";s:0:"";s:5:"items";a:6:{i:635;a:5:{s:4:"name";s:15:"happy new year!";s:8:"old_name";s:15:"happy new year!";s:7:"item_id";s:4:"1228";s:15:"section_item_id";s:3:"635";s:9:"post_type";s:9:"lp_lesson";}i:636;a:5:{s:4:"name";s:15:"happy new year!";s:8:"old_name";s:15:"happy new year!";s:7:"item_id";s:4:"1229";s:15:"section_item_id";s:3:"636";s:9:"post_type";s:9:"lp_lesson";}i:637;a:5:{s:4:"name";s:8:"Lesson 1";s:8:"old_name";s:8:"Lesson 1";s:7:"item_id";s:4:"1136";s:15:"section_item_id";s:3:"637";s:9:"post_type";s:9:"lp_lesson";}i:638;a:5:{s:4:"name";s:8:"Lesson 2";s:8:"old_name";s:8:"Lesson 2";s:7:"item_id";s:4:"1137";s:15:"section_item_id";s:3:"638";s:9:"post_type";s:9:"lp_lesson";}i:639;a:5:{s:4:"name";s:18:"oi troi oi la troi";s:8:"old_name";s:18:"oi troi oi la troi";s:7:"item_id";s:4:"1230";s:15:"section_item_id";s:3:"639";s:9:"post_type";s:9:"lp_lesson";}s:6:"item-5";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}i:5;a:3:{s:4:"name";s:10:"Section #6";s:11:"description";s:0:"";s:5:"items";a:4:{i:640;a:5:{s:4:"name";s:12:"333333333333";s:8:"old_name";s:12:"333333333333";s:7:"item_id";s:4:"1145";s:15:"section_item_id";s:3:"640";s:9:"post_type";s:9:"lp_lesson";}i:641;a:5:{s:4:"name";s:8:"44444444";s:8:"old_name";s:8:"44444444";s:7:"item_id";s:4:"1227";s:15:"section_item_id";s:3:"641";s:9:"post_type";s:9:"lp_lesson";}i:642;a:5:{s:4:"name";s:6:"cookie";s:8:"old_name";s:6:"cookie";s:7:"item_id";s:4:"1231";s:15:"section_item_id";s:3:"642";s:9:"post_type";s:9:"lp_lesson";}s:6:"item-3";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}}]]></wp:meta_value>
167
+ </wp:postmeta> <wp:postmeta>
168
+ <wp:meta_key>_lp_duration</wp:meta_key>
169
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
170
+ </wp:postmeta> <wp:postmeta>
171
+ <wp:meta_key>_lp_max_students</wp:meta_key>
172
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
173
+ </wp:postmeta> <wp:postmeta>
174
+ <wp:meta_key>_lp_students</wp:meta_key>
175
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
176
+ </wp:postmeta> <wp:postmeta>
177
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
178
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
179
+ </wp:postmeta> <wp:postmeta>
180
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
181
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
182
+ </wp:postmeta> <wp:postmeta>
183
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
184
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
185
+ </wp:postmeta> <wp:postmeta>
186
+ <wp:meta_key>_lp_payment</wp:meta_key>
187
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
188
+ </wp:postmeta> <wp:postmeta>
189
+ <wp:meta_key>_lp_course_status</wp:meta_key>
190
+ <wp:meta_value><![CDATA[publish]]></wp:meta_value>
191
+ </wp:postmeta> <wp:postmeta>
192
+ <wp:meta_key>_lp_course_result</wp:meta_key>
193
+ <wp:meta_value><![CDATA[evaluate_lesson]]></wp:meta_value>
194
+ </wp:postmeta> <wp:postmeta>
195
+ <wp:meta_key>_lp_required_enroll</wp:meta_key>
196
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
197
+ </wp:postmeta>
198
+ <wp:section>
199
+ <wp:section_id>208</wp:section_id>
200
+ <wp:section_name>Section #1</wp:section_name>
201
+ <wp:section_course_id>1513</wp:section_course_id>
202
+ <wp:section_order>1</wp:section_order>
203
+ <wp:section_description><![CDATA[asd asd asdasd asdasd asdasd asda]]></wp:section_description>
204
+ <wp:section_item>
205
+ <wp:section_id>208</wp:section_id>
206
+ <wp:item_id>1514</wp:item_id>
207
+ <wp:item_order>1</wp:item_order>
208
+ <wp:item_type>lp_quiz</wp:item_type>
209
+ </wp:section_item>
210
+ <wp:section_item>
211
+ <wp:section_id>208</wp:section_id>
212
+ <wp:item_id>1515</wp:item_id>
213
+ <wp:item_order>2</wp:item_order>
214
+ <wp:item_type>lp_lesson</wp:item_type>
215
+ </wp:section_item>
216
+ <wp:section_item>
217
+ <wp:section_id>208</wp:section_id>
218
+ <wp:item_id>1516</wp:item_id>
219
+ <wp:item_order>3</wp:item_order>
220
+ <wp:item_type>lp_quiz</wp:item_type>
221
+ </wp:section_item>
222
+ <wp:section_item>
223
+ <wp:section_id>208</wp:section_id>
224
+ <wp:item_id>1517</wp:item_id>
225
+ <wp:item_order>4</wp:item_order>
226
+ <wp:item_type>lp_lesson</wp:item_type>
227
+ </wp:section_item>
228
+ <wp:section_item>
229
+ <wp:section_id>208</wp:section_id>
230
+ <wp:item_id>1518</wp:item_id>
231
+ <wp:item_order>5</wp:item_order>
232
+ <wp:item_type>lp_lesson</wp:item_type>
233
+ </wp:section_item>
234
+ <wp:section_item>
235
+ <wp:section_id>208</wp:section_id>
236
+ <wp:item_id>1519</wp:item_id>
237
+ <wp:item_order>6</wp:item_order>
238
+ <wp:item_type>lp_lesson</wp:item_type>
239
+ </wp:section_item>
240
+ <wp:section_item>
241
+ <wp:section_id>208</wp:section_id>
242
+ <wp:item_id>1520</wp:item_id>
243
+ <wp:item_order>7</wp:item_order>
244
+ <wp:item_type>lp_lesson</wp:item_type>
245
+ </wp:section_item>
246
+ <wp:section_item>
247
+ <wp:section_id>208</wp:section_id>
248
+ <wp:item_id>1521</wp:item_id>
249
+ <wp:item_order>8</wp:item_order>
250
+ <wp:item_type>lp_lesson</wp:item_type>
251
+ </wp:section_item>
252
+ <wp:section_item>
253
+ <wp:section_id>208</wp:section_id>
254
+ <wp:item_id>1522</wp:item_id>
255
+ <wp:item_order>9</wp:item_order>
256
+ <wp:item_type>lp_lesson</wp:item_type>
257
+ </wp:section_item>
258
+ <wp:section_item>
259
+ <wp:section_id>208</wp:section_id>
260
+ <wp:item_id>1523</wp:item_id>
261
+ <wp:item_order>10</wp:item_order>
262
+ <wp:item_type>lp_lesson</wp:item_type>
263
+ </wp:section_item>
264
+ <wp:section_item>
265
+ <wp:section_id>208</wp:section_id>
266
+ <wp:item_id>1524</wp:item_id>
267
+ <wp:item_order>11</wp:item_order>
268
+ <wp:item_type>lp_lesson</wp:item_type>
269
+ </wp:section_item>
270
+ <wp:section_item>
271
+ <wp:section_id>208</wp:section_id>
272
+ <wp:item_id>1525</wp:item_id>
273
+ <wp:item_order>12</wp:item_order>
274
+ <wp:item_type>lp_lesson</wp:item_type>
275
+ </wp:section_item>
276
+ <wp:section_item>
277
+ <wp:section_id>208</wp:section_id>
278
+ <wp:item_id>1526</wp:item_id>
279
+ <wp:item_order>13</wp:item_order>
280
+ <wp:item_type>lp_lesson</wp:item_type>
281
+ </wp:section_item>
282
+ <wp:section_item>
283
+ <wp:section_id>208</wp:section_id>
284
+ <wp:item_id>1527</wp:item_id>
285
+ <wp:item_order>14</wp:item_order>
286
+ <wp:item_type>lp_lesson</wp:item_type>
287
+ </wp:section_item>
288
+ </wp:section>
289
+
290
+ <wp:section>
291
+ <wp:section_id>209</wp:section_id>
292
+ <wp:section_name>Section #2</wp:section_name>
293
+ <wp:section_course_id>1513</wp:section_course_id>
294
+ <wp:section_order>2</wp:section_order>
295
+ <wp:section_description><![CDATA[asdas das d asdas das asdasd asdas dasdas dasdasd]]></wp:section_description>
296
+ <wp:section_item>
297
+ <wp:section_id>209</wp:section_id>
298
+ <wp:item_id>1528</wp:item_id>
299
+ <wp:item_order>1</wp:item_order>
300
+ <wp:item_type>lp_lesson</wp:item_type>
301
+ </wp:section_item>
302
+ <wp:section_item>
303
+ <wp:section_id>209</wp:section_id>
304
+ <wp:item_id>1529</wp:item_id>
305
+ <wp:item_order>2</wp:item_order>
306
+ <wp:item_type>lp_lesson</wp:item_type>
307
+ </wp:section_item>
308
+ <wp:section_item>
309
+ <wp:section_id>209</wp:section_id>
310
+ <wp:item_id>1530</wp:item_id>
311
+ <wp:item_order>3</wp:item_order>
312
+ <wp:item_type>lp_lesson</wp:item_type>
313
+ </wp:section_item>
314
+ <wp:section_item>
315
+ <wp:section_id>209</wp:section_id>
316
+ <wp:item_id>1531</wp:item_id>
317
+ <wp:item_order>4</wp:item_order>
318
+ <wp:item_type>lp_quiz</wp:item_type>
319
+ </wp:section_item>
320
+ </wp:section>
321
+
322
+ <wp:section>
323
+ <wp:section_id>210</wp:section_id>
324
+ <wp:section_name>Section #3</wp:section_name>
325
+ <wp:section_course_id>1513</wp:section_course_id>
326
+ <wp:section_order>3</wp:section_order>
327
+ <wp:section_description><![CDATA[]]></wp:section_description>
328
+ <wp:section_item>
329
+ <wp:section_id>210</wp:section_id>
330
+ <wp:item_id>1532</wp:item_id>
331
+ <wp:item_order>1</wp:item_order>
332
+ <wp:item_type>lp_quiz</wp:item_type>
333
+ </wp:section_item>
334
+ </wp:section>
335
+
336
+ <wp:section>
337
+ <wp:section_id>211</wp:section_id>
338
+ <wp:section_name>Section #4</wp:section_name>
339
+ <wp:section_course_id>1513</wp:section_course_id>
340
+ <wp:section_order>4</wp:section_order>
341
+ <wp:section_description><![CDATA[]]></wp:section_description>
342
+ <wp:section_item>
343
+ <wp:section_id>211</wp:section_id>
344
+ <wp:item_id>1533</wp:item_id>
345
+ <wp:item_order>1</wp:item_order>
346
+ <wp:item_type>lp_quiz</wp:item_type>
347
+ </wp:section_item>
348
+ </wp:section>
349
+
350
+ <wp:section>
351
+ <wp:section_id>212</wp:section_id>
352
+ <wp:section_name>Section #5</wp:section_name>
353
+ <wp:section_course_id>1513</wp:section_course_id>
354
+ <wp:section_order>5</wp:section_order>
355
+ <wp:section_description><![CDATA[]]></wp:section_description>
356
+ <wp:section_item>
357
+ <wp:section_id>212</wp:section_id>
358
+ <wp:item_id>1534</wp:item_id>
359
+ <wp:item_order>1</wp:item_order>
360
+ <wp:item_type>lp_lesson</wp:item_type>
361
+ </wp:section_item>
362
+ <wp:section_item>
363
+ <wp:section_id>212</wp:section_id>
364
+ <wp:item_id>1535</wp:item_id>
365
+ <wp:item_order>2</wp:item_order>
366
+ <wp:item_type>lp_lesson</wp:item_type>
367
+ </wp:section_item>
368
+ <wp:section_item>
369
+ <wp:section_id>212</wp:section_id>
370
+ <wp:item_id>1536</wp:item_id>
371
+ <wp:item_order>3</wp:item_order>
372
+ <wp:item_type>lp_lesson</wp:item_type>
373
+ </wp:section_item>
374
+ <wp:section_item>
375
+ <wp:section_id>212</wp:section_id>
376
+ <wp:item_id>1537</wp:item_id>
377
+ <wp:item_order>4</wp:item_order>
378
+ <wp:item_type>lp_lesson</wp:item_type>
379
+ </wp:section_item>
380
+ <wp:section_item>
381
+ <wp:section_id>212</wp:section_id>
382
+ <wp:item_id>1538</wp:item_id>
383
+ <wp:item_order>5</wp:item_order>
384
+ <wp:item_type>lp_lesson</wp:item_type>
385
+ </wp:section_item>
386
+ </wp:section>
387
+
388
+ <wp:section>
389
+ <wp:section_id>213</wp:section_id>
390
+ <wp:section_name>Section #6</wp:section_name>
391
+ <wp:section_course_id>1513</wp:section_course_id>
392
+ <wp:section_order>6</wp:section_order>
393
+ <wp:section_description><![CDATA[]]></wp:section_description>
394
+ <wp:section_item>
395
+ <wp:section_id>213</wp:section_id>
396
+ <wp:item_id>1539</wp:item_id>
397
+ <wp:item_order>1</wp:item_order>
398
+ <wp:item_type>lp_lesson</wp:item_type>
399
+ </wp:section_item>
400
+ <wp:section_item>
401
+ <wp:section_id>213</wp:section_id>
402
+ <wp:item_id>1540</wp:item_id>
403
+ <wp:item_order>2</wp:item_order>
404
+ <wp:item_type>lp_lesson</wp:item_type>
405
+ </wp:section_item>
406
+ <wp:section_item>
407
+ <wp:section_id>213</wp:section_id>
408
+ <wp:item_id>1541</wp:item_id>
409
+ <wp:item_order>3</wp:item_order>
410
+ <wp:item_type>lp_lesson</wp:item_type>
411
+ </wp:section_item>
412
+ </wp:section>
413
+
414
+ </item><item>
415
+ <title>333333333333</title>
416
+ <link>http://localhost/foobla/learnpress/1.0/quizzes/333333333333-2/</link>
417
+ <pubDate>Tue, 08 Dec 2015 04:19:22 +0000</pubDate>
418
+ <dc:creator><![CDATA[admin]]></dc:creator>
419
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/quizzes/333333333333-2/</guid>
420
+ <description></description>
421
+ <content:encoded><![CDATA[]]></content:encoded>
422
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
423
+ <wp:post_id>1514</wp:post_id>
424
+ <wp:post_date>2015-12-08 04:19:22</wp:post_date>
425
+ <wp:post_date_gmt>2015-12-08 04:19:22</wp:post_date_gmt>
426
+ <wp:comment_status>open</wp:comment_status>
427
+ <wp:ping_status>open</wp:ping_status>
428
+ <wp:post_name>333333333333-2</wp:post_name>
429
+ <wp:status>publish</wp:status>
430
+ <wp:post_parent>0</wp:post_parent>
431
+ <wp:menu_order>0</wp:menu_order>
432
+ <wp:post_type>lp_quiz</wp:post_type>
433
+ <wp:post_password></wp:post_password>
434
+ <wp:post_author_id>1</wp:post_author_id>
435
+ <wp:is_sticky>0</wp:is_sticky>
436
+ <wp:postmeta>
437
+ <wp:meta_key>_edit_lock</wp:meta_key>
438
+ <wp:meta_value><![CDATA[1451469598:1]]></wp:meta_value>
439
+ </wp:postmeta> <wp:postmeta>
440
+ <wp:meta_key>_edit_last</wp:meta_key>
441
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
442
+ </wp:postmeta> <wp:postmeta>
443
+ <wp:meta_key>_lp_duration</wp:meta_key>
444
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
445
+ </wp:postmeta> <wp:postmeta>
446
+ <wp:meta_key>_lp_show_result</wp:meta_key>
447
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
448
+ </wp:postmeta> <wp:postmeta>
449
+ <wp:meta_key>_lp_show_question_answer</wp:meta_key>
450
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
451
+ </wp:postmeta> <wp:postmeta>
452
+ <wp:meta_key>_lp_type</wp:meta_key>
453
+ <wp:meta_value><![CDATA[true_or_false]]></wp:meta_value>
454
+ </wp:postmeta>
455
+ </item><item>
456
+ <title>where are you now?</title>
457
+ <link>http://localhost/foobla/learnpress/1.0/lessons/where-are-you-now/</link>
458
+ <pubDate>Tue, 08 Dec 2015 08:20:59 +0000</pubDate>
459
+ <dc:creator><![CDATA[admin]]></dc:creator>
460
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/where-are-you-now/</guid>
461
+ <description></description>
462
+ <content:encoded><![CDATA[Nulla porta dolor. Ut varius tincidunt libero. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Fusce egestas elit eget lorem. Vivamus aliquet elit ac nisl.
463
+
464
+ Cras ultricies mi eu turpis hendrerit fringilla. Quisque id mi. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas malesuada. Praesent nec nisl a purus blandit viverra.
465
+
466
+ In auctor lobortis lacus. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Nam adipiscing. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Nam commodo suscipit quam.
467
+
468
+ Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam accumsan lorem in dui. Cras varius. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Suspendisse non nisl sit amet velit hendrerit rutrum.
469
+
470
+ Morbi ac felis. Etiam rhoncus. Praesent ac massa at ligula laoreet iaculis. Nunc nulla. In turpis.]]></content:encoded>
471
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
472
+ <wp:post_id>1515</wp:post_id>
473
+ <wp:post_date>2015-12-08 08:20:59</wp:post_date>
474
+ <wp:post_date_gmt>2015-12-08 08:20:59</wp:post_date_gmt>
475
+ <wp:comment_status>closed</wp:comment_status>
476
+ <wp:ping_status>closed</wp:ping_status>
477
+ <wp:post_name>where-are-you-now</wp:post_name>
478
+ <wp:status>publish</wp:status>
479
+ <wp:post_parent>0</wp:post_parent>
480
+ <wp:menu_order>0</wp:menu_order>
481
+ <wp:post_type>lp_lesson</wp:post_type>
482
+ <wp:post_password></wp:post_password>
483
+ <wp:post_author_id>1</wp:post_author_id>
484
+ <wp:is_sticky>0</wp:is_sticky>
485
+ <wp:postmeta>
486
+ <wp:meta_key>_lp_duration</wp:meta_key>
487
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
488
+ </wp:postmeta> <wp:postmeta>
489
+ <wp:meta_key>_lp_max_students</wp:meta_key>
490
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
491
+ </wp:postmeta> <wp:postmeta>
492
+ <wp:meta_key>_lp_students</wp:meta_key>
493
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
494
+ </wp:postmeta> <wp:postmeta>
495
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
496
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
497
+ </wp:postmeta> <wp:postmeta>
498
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
499
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
500
+ </wp:postmeta> <wp:postmeta>
501
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
502
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
503
+ </wp:postmeta> <wp:postmeta>
504
+ <wp:meta_key>_lp_payment</wp:meta_key>
505
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
506
+ </wp:postmeta> <wp:postmeta>
507
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
508
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
509
+ </wp:postmeta> <wp:postmeta>
510
+ <wp:meta_key>_edit_lock</wp:meta_key>
511
+ <wp:meta_value><![CDATA[1451449804:1]]></wp:meta_value>
512
+ </wp:postmeta> <wp:postmeta>
513
+ <wp:meta_key>_edit_last</wp:meta_key>
514
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
515
+ </wp:postmeta>
516
+ </item><item>
517
+ <title>I am here, beside you</title>
518
+ <link>http://localhost/foobla/learnpress/1.0/quizzes/i-am-here-beside-you/</link>
519
+ <pubDate>Tue, 08 Dec 2015 08:26:07 +0000</pubDate>
520
+ <dc:creator><![CDATA[admin]]></dc:creator>
521
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/quizzes/i-am-here-beside-you/</guid>
522
+ <description></description>
523
+ <content:encoded><![CDATA[]]></content:encoded>
524
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
525
+ <wp:post_id>1516</wp:post_id>
526
+ <wp:post_date>2015-12-08 08:26:07</wp:post_date>
527
+ <wp:post_date_gmt>2015-12-08 08:26:07</wp:post_date_gmt>
528
+ <wp:comment_status>open</wp:comment_status>
529
+ <wp:ping_status>open</wp:ping_status>
530
+ <wp:post_name>i-am-here-beside-you</wp:post_name>
531
+ <wp:status>publish</wp:status>
532
+ <wp:post_parent>0</wp:post_parent>
533
+ <wp:menu_order>0</wp:menu_order>
534
+ <wp:post_type>lp_quiz</wp:post_type>
535
+ <wp:post_password></wp:post_password>
536
+ <wp:post_author_id>1</wp:post_author_id>
537
+ <wp:is_sticky>0</wp:is_sticky>
538
+ <wp:postmeta>
539
+ <wp:meta_key>_lp_duration</wp:meta_key>
540
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
541
+ </wp:postmeta> <wp:postmeta>
542
+ <wp:meta_key>_lp_max_students</wp:meta_key>
543
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
544
+ </wp:postmeta> <wp:postmeta>
545
+ <wp:meta_key>_lp_students</wp:meta_key>
546
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
547
+ </wp:postmeta> <wp:postmeta>
548
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
549
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
550
+ </wp:postmeta> <wp:postmeta>
551
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
552
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
553
+ </wp:postmeta> <wp:postmeta>
554
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
555
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
556
+ </wp:postmeta> <wp:postmeta>
557
+ <wp:meta_key>_lp_payment</wp:meta_key>
558
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
559
+ </wp:postmeta> <wp:postmeta>
560
+ <wp:meta_key>_edit_lock</wp:meta_key>
561
+ <wp:meta_value><![CDATA[1452319835:1]]></wp:meta_value>
562
+ </wp:postmeta> <wp:postmeta>
563
+ <wp:meta_key>_edit_last</wp:meta_key>
564
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
565
+ </wp:postmeta> <wp:postmeta>
566
+ <wp:meta_key>_lp_show_result</wp:meta_key>
567
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
568
+ </wp:postmeta> <wp:postmeta>
569
+ <wp:meta_key>_lp_show_question_answer</wp:meta_key>
570
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
571
+ </wp:postmeta>
572
+ <wp:question>
573
+ <wp:quiz_id>1516</wp:quiz_id>
574
+ <wp:question_id>1542</wp:question_id>
575
+ <wp:params><![CDATA[]]></wp:params>
576
+ <wp:question_order></wp:question_order>
577
+ </wp:question>
578
+
579
+
580
+ <wp:question>
581
+ <wp:quiz_id>1516</wp:quiz_id>
582
+ <wp:question_id>1543</wp:question_id>
583
+ <wp:params><![CDATA[]]></wp:params>
584
+ <wp:question_order></wp:question_order>
585
+ </wp:question>
586
+
587
+
588
+ </item><item>
589
+ <title>Question #1</title>
590
+ <link>http://localhost/foobla/learnpress/1.0/questions/question-1/</link>
591
+ <pubDate>Sat, 09 Jan 2016 06:12:35 +0000</pubDate>
592
+ <dc:creator><![CDATA[admin]]></dc:creator>
593
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/questions/question-1/</guid>
594
+ <description></description>
595
+ <content:encoded><![CDATA[]]></content:encoded>
596
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
597
+ <wp:post_id>1542</wp:post_id>
598
+ <wp:post_date>2016-01-09 06:12:35</wp:post_date>
599
+ <wp:post_date_gmt>2016-01-09 06:12:35</wp:post_date_gmt>
600
+ <wp:comment_status>closed</wp:comment_status>
601
+ <wp:ping_status>closed</wp:ping_status>
602
+ <wp:post_name>question-1</wp:post_name>
603
+ <wp:status>publish</wp:status>
604
+ <wp:post_parent>0</wp:post_parent>
605
+ <wp:menu_order>0</wp:menu_order>
606
+ <wp:post_type>lp_question</wp:post_type>
607
+ <wp:post_password></wp:post_password>
608
+ <wp:post_author_id>1</wp:post_author_id>
609
+ <wp:is_sticky>0</wp:is_sticky>
610
+ <wp:postmeta>
611
+ <wp:meta_key>_lp_type</wp:meta_key>
612
+ <wp:meta_value><![CDATA[multi_choice]]></wp:meta_value>
613
+ </wp:postmeta> <wp:postmeta>
614
+ <wp:meta_key>_edit_lock</wp:meta_key>
615
+ <wp:meta_value><![CDATA[1452321706:1]]></wp:meta_value>
616
+ </wp:postmeta> <wp:postmeta>
617
+ <wp:meta_key>_edit_last</wp:meta_key>
618
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
619
+ </wp:postmeta> <wp:postmeta>
620
+ <wp:meta_key>_lp_mark</wp:meta_key>
621
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
622
+ </wp:postmeta>
623
+ <wp:answer>
624
+ <wp:question_id>1543</wp:question_id>
625
+ <wp:answer_data><![CDATA[a:3:{s:4:"text";s:4:"True";s:5:"value";s:4:"true";s:7:"is_true";s:3:"yes";}]]></wp:answer_data>
626
+ <wp:answer_order>1</wp:answer_order>
627
+ </wp:answer>
628
+
629
+
630
+ <wp:answer>
631
+ <wp:question_id>1543</wp:question_id>
632
+ <wp:answer_data><![CDATA[a:3:{s:4:"text";s:11:"Falseasdasd";s:5:"value";s:5:"false";s:7:"is_true";s:3:"yes";}]]></wp:answer_data>
633
+ <wp:answer_order>2</wp:answer_order>
634
+ </wp:answer>
635
+
636
+
637
+ <wp:answer>
638
+ <wp:question_id>1543</wp:question_id>
639
+ <wp:answer_data><![CDATA[a:3:{s:4:"text";s:13:"asdasdasdadss";s:5:"value";s:13:"5690ac2667caa";s:7:"is_true";s:2:"no";}]]></wp:answer_data>
640
+ <wp:answer_order>3</wp:answer_order>
641
+ </wp:answer>
642
+
643
+
644
+ </item><item>
645
+ <title>Question #2</title>
646
+ <link>http://localhost/foobla/learnpress/1.0/questions/question-2/</link>
647
+ <pubDate>Sat, 09 Jan 2016 06:12:49 +0000</pubDate>
648
+ <dc:creator><![CDATA[admin]]></dc:creator>
649
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/questions/question-2/</guid>
650
+ <description></description>
651
+ <content:encoded><![CDATA[]]></content:encoded>
652
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
653
+ <wp:post_id>1543</wp:post_id>
654
+ <wp:post_date>2016-01-09 06:12:49</wp:post_date>
655
+ <wp:post_date_gmt>2016-01-09 06:12:49</wp:post_date_gmt>
656
+ <wp:comment_status>closed</wp:comment_status>
657
+ <wp:ping_status>closed</wp:ping_status>
658
+ <wp:post_name>question-2</wp:post_name>
659
+ <wp:status>publish</wp:status>
660
+ <wp:post_parent>0</wp:post_parent>
661
+ <wp:menu_order>0</wp:menu_order>
662
+ <wp:post_type>lp_question</wp:post_type>
663
+ <wp:post_password></wp:post_password>
664
+ <wp:post_author_id>1</wp:post_author_id>
665
+ <wp:is_sticky>0</wp:is_sticky>
666
+ <wp:postmeta>
667
+ <wp:meta_key>_lp_type</wp:meta_key>
668
+ <wp:meta_value><![CDATA[multi_choice]]></wp:meta_value>
669
+ </wp:postmeta> <wp:postmeta>
670
+ <wp:meta_key>_edit_lock</wp:meta_key>
671
+ <wp:meta_value><![CDATA[1452326236:1]]></wp:meta_value>
672
+ </wp:postmeta> <wp:postmeta>
673
+ <wp:meta_key>_edit_last</wp:meta_key>
674
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
675
+ </wp:postmeta> <wp:postmeta>
676
+ <wp:meta_key>_lp_mark</wp:meta_key>
677
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
678
+ </wp:postmeta>
679
+ <wp:answer>
680
+ <wp:question_id>1543</wp:question_id>
681
+ <wp:answer_data><![CDATA[a:3:{s:4:"text";s:12:"Option First";s:5:"value";s:12:"option_first";s:7:"is_true";s:3:"yes";}]]></wp:answer_data>
682
+ <wp:answer_order>1</wp:answer_order>
683
+ </wp:answer>
684
+
685
+
686
+ <wp:answer>
687
+ <wp:question_id>1543</wp:question_id>
688
+ <wp:answer_data><![CDATA[a:3:{s:4:"text";s:14:"Option Seconds";s:5:"value";s:14:"option_seconds";s:7:"is_true";s:3:"yes";}]]></wp:answer_data>
689
+ <wp:answer_order>2</wp:answer_order>
690
+ </wp:answer>
691
+
692
+
693
+ <wp:answer>
694
+ <wp:question_id>1543</wp:question_id>
695
+ <wp:answer_data><![CDATA[a:3:{s:4:"text";s:12:"Option Third";s:5:"value";s:12:"option_third";s:7:"is_true";s:2:"no";}]]></wp:answer_data>
696
+ <wp:answer_order>3</wp:answer_order>
697
+ </wp:answer>
698
+
699
+
700
+ </item><item>
701
+ <title>asdasdasd</title>
702
+ <link>http://localhost/foobla/learnpress/1.0/lessons/asdasdasd/</link>
703
+ <pubDate>Tue, 08 Dec 2015 03:58:51 +0000</pubDate>
704
+ <dc:creator><![CDATA[admin]]></dc:creator>
705
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/asdasdasd/</guid>
706
+ <description></description>
707
+ <content:encoded><![CDATA[]]></content:encoded>
708
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
709
+ <wp:post_id>1517</wp:post_id>
710
+ <wp:post_date>2015-12-08 03:58:51</wp:post_date>
711
+ <wp:post_date_gmt>2015-12-08 03:58:51</wp:post_date_gmt>
712
+ <wp:comment_status>open</wp:comment_status>
713
+ <wp:ping_status>open</wp:ping_status>
714
+ <wp:post_name>asdasdasd</wp:post_name>
715
+ <wp:status>publish</wp:status>
716
+ <wp:post_parent>0</wp:post_parent>
717
+ <wp:menu_order>0</wp:menu_order>
718
+ <wp:post_type>lp_lesson</wp:post_type>
719
+ <wp:post_password></wp:post_password>
720
+ <wp:post_author_id>1</wp:post_author_id>
721
+ <wp:is_sticky>0</wp:is_sticky>
722
+ <wp:postmeta>
723
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
724
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
725
+ </wp:postmeta>
726
+ </item><item>
727
+ <title>dsfsdfsdf</title>
728
+ <link>http://localhost/foobla/learnpress/1.0/lessons/dsfsdfsdf/</link>
729
+ <pubDate>Tue, 08 Dec 2015 03:59:33 +0000</pubDate>
730
+ <dc:creator><![CDATA[admin]]></dc:creator>
731
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/dsfsdfsdf/</guid>
732
+ <description></description>
733
+ <content:encoded><![CDATA[]]></content:encoded>
734
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
735
+ <wp:post_id>1518</wp:post_id>
736
+ <wp:post_date>2015-12-08 03:59:33</wp:post_date>
737
+ <wp:post_date_gmt>2015-12-08 03:59:33</wp:post_date_gmt>
738
+ <wp:comment_status>open</wp:comment_status>
739
+ <wp:ping_status>open</wp:ping_status>
740
+ <wp:post_name>dsfsdfsdf</wp:post_name>
741
+ <wp:status>publish</wp:status>
742
+ <wp:post_parent>0</wp:post_parent>
743
+ <wp:menu_order>0</wp:menu_order>
744
+ <wp:post_type>lp_lesson</wp:post_type>
745
+ <wp:post_password></wp:post_password>
746
+ <wp:post_author_id>1</wp:post_author_id>
747
+ <wp:is_sticky>0</wp:is_sticky>
748
+ <wp:postmeta>
749
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
750
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
751
+ </wp:postmeta>
752
+ </item><item>
753
+ <title>Lesson 1</title>
754
+ <link>http://localhost/foobla/learnpress/1.0/lessons/lesson-1-2/</link>
755
+ <pubDate>Fri, 04 Dec 2015 08:41:24 +0000</pubDate>
756
+ <dc:creator><![CDATA[admin]]></dc:creator>
757
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/lesson-1-2/</guid>
758
+ <description></description>
759
+ <content:encoded><![CDATA[]]></content:encoded>
760
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
761
+ <wp:post_id>1519</wp:post_id>
762
+ <wp:post_date>2015-12-04 08:41:24</wp:post_date>
763
+ <wp:post_date_gmt>2015-12-04 08:41:24</wp:post_date_gmt>
764
+ <wp:comment_status>open</wp:comment_status>
765
+ <wp:ping_status>open</wp:ping_status>
766
+ <wp:post_name>lesson-1-2</wp:post_name>
767
+ <wp:status>publish</wp:status>
768
+ <wp:post_parent>0</wp:post_parent>
769
+ <wp:menu_order>0</wp:menu_order>
770
+ <wp:post_type>lp_lesson</wp:post_type>
771
+ <wp:post_password></wp:post_password>
772
+ <wp:post_author_id>1</wp:post_author_id>
773
+ <wp:is_sticky>0</wp:is_sticky>
774
+ <wp:postmeta>
775
+ <wp:meta_key>_lp_duration</wp:meta_key>
776
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
777
+ </wp:postmeta> <wp:postmeta>
778
+ <wp:meta_key>_lp_max_students</wp:meta_key>
779
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
780
+ </wp:postmeta> <wp:postmeta>
781
+ <wp:meta_key>_lp_students</wp:meta_key>
782
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
783
+ </wp:postmeta> <wp:postmeta>
784
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
785
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
786
+ </wp:postmeta> <wp:postmeta>
787
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
788
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
789
+ </wp:postmeta> <wp:postmeta>
790
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
791
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
792
+ </wp:postmeta> <wp:postmeta>
793
+ <wp:meta_key>_lp_payment</wp:meta_key>
794
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
795
+ </wp:postmeta> <wp:postmeta>
796
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
797
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
798
+ </wp:postmeta>
799
+ </item><item>
800
+ <title>Lesson 2</title>
801
+ <link>http://localhost/foobla/learnpress/1.0/lessons/lesson-2-2/</link>
802
+ <pubDate>Fri, 04 Dec 2015 08:41:24 +0000</pubDate>
803
+ <dc:creator><![CDATA[admin]]></dc:creator>
804
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/lesson-2-2/</guid>
805
+ <description></description>
806
+ <content:encoded><![CDATA[]]></content:encoded>
807
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
808
+ <wp:post_id>1520</wp:post_id>
809
+ <wp:post_date>2015-12-04 08:41:24</wp:post_date>
810
+ <wp:post_date_gmt>2015-12-04 08:41:24</wp:post_date_gmt>
811
+ <wp:comment_status>open</wp:comment_status>
812
+ <wp:ping_status>open</wp:ping_status>
813
+ <wp:post_name>lesson-2-2</wp:post_name>
814
+ <wp:status>publish</wp:status>
815
+ <wp:post_parent>0</wp:post_parent>
816
+ <wp:menu_order>0</wp:menu_order>
817
+ <wp:post_type>lp_lesson</wp:post_type>
818
+ <wp:post_password></wp:post_password>
819
+ <wp:post_author_id>1</wp:post_author_id>
820
+ <wp:is_sticky>0</wp:is_sticky>
821
+ <wp:postmeta>
822
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
823
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
824
+ </wp:postmeta>
825
+ </item><item>
826
+ <title>Lesson 3</title>
827
+ <link>http://localhost/foobla/learnpress/1.0/lessons/lesson-3/</link>
828
+ <pubDate>Tue, 08 Dec 2015 03:58:28 +0000</pubDate>
829
+ <dc:creator><![CDATA[admin]]></dc:creator>
830
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/lesson-3/</guid>
831
+ <description></description>
832
+ <content:encoded><![CDATA[]]></content:encoded>
833
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
834
+ <wp:post_id>1521</wp:post_id>
835
+ <wp:post_date>2015-12-08 03:58:28</wp:post_date>
836
+ <wp:post_date_gmt>2015-12-08 03:58:28</wp:post_date_gmt>
837
+ <wp:comment_status>open</wp:comment_status>
838
+ <wp:ping_status>open</wp:ping_status>
839
+ <wp:post_name>lesson-3</wp:post_name>
840
+ <wp:status>publish</wp:status>
841
+ <wp:post_parent>0</wp:post_parent>
842
+ <wp:menu_order>0</wp:menu_order>
843
+ <wp:post_type>lp_lesson</wp:post_type>
844
+ <wp:post_password></wp:post_password>
845
+ <wp:post_author_id>1</wp:post_author_id>
846
+ <wp:is_sticky>0</wp:is_sticky>
847
+ <wp:postmeta>
848
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
849
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
850
+ </wp:postmeta>
851
+ </item><item>
852
+ <title>qqqqqqqqqqqqqqqqq</title>
853
+ <link>http://localhost/foobla/learnpress/1.0/lessons/qqqqqqqqqqqqqqqqq/</link>
854
+ <pubDate>Tue, 08 Dec 2015 15:15:04 +0000</pubDate>
855
+ <dc:creator><![CDATA[admin]]></dc:creator>
856
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/qqqqqqqqqqqqqqqqq/</guid>
857
+ <description></description>
858
+ <content:encoded><![CDATA[]]></content:encoded>
859
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
860
+ <wp:post_id>1522</wp:post_id>
861
+ <wp:post_date>2015-12-08 15:15:04</wp:post_date>
862
+ <wp:post_date_gmt>2015-12-08 15:15:04</wp:post_date_gmt>
863
+ <wp:comment_status>open</wp:comment_status>
864
+ <wp:ping_status>open</wp:ping_status>
865
+ <wp:post_name>qqqqqqqqqqqqqqqqq</wp:post_name>
866
+ <wp:status>publish</wp:status>
867
+ <wp:post_parent>0</wp:post_parent>
868
+ <wp:menu_order>0</wp:menu_order>
869
+ <wp:post_type>lp_lesson</wp:post_type>
870
+ <wp:post_password></wp:post_password>
871
+ <wp:post_author_id>1</wp:post_author_id>
872
+ <wp:is_sticky>0</wp:is_sticky>
873
+ <wp:postmeta>
874
+ <wp:meta_key>_edit_lock</wp:meta_key>
875
+ <wp:meta_value><![CDATA[1449589506:1]]></wp:meta_value>
876
+ </wp:postmeta>
877
+ </item><item>
878
+ <title>trau va bo</title>
879
+ <link>http://localhost/foobla/learnpress/1.0/lessons/trau-va-bo/</link>
880
+ <pubDate>Tue, 08 Dec 2015 15:16:40 +0000</pubDate>
881
+ <dc:creator><![CDATA[admin]]></dc:creator>
882
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/trau-va-bo/</guid>
883
+ <description></description>
884
+ <content:encoded><![CDATA[]]></content:encoded>
885
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
886
+ <wp:post_id>1523</wp:post_id>
887
+ <wp:post_date>2015-12-08 15:16:40</wp:post_date>
888
+ <wp:post_date_gmt>2015-12-08 15:16:40</wp:post_date_gmt>
889
+ <wp:comment_status>open</wp:comment_status>
890
+ <wp:ping_status>open</wp:ping_status>
891
+ <wp:post_name>trau-va-bo</wp:post_name>
892
+ <wp:status>publish</wp:status>
893
+ <wp:post_parent>0</wp:post_parent>
894
+ <wp:menu_order>0</wp:menu_order>
895
+ <wp:post_type>lp_lesson</wp:post_type>
896
+ <wp:post_password></wp:post_password>
897
+ <wp:post_author_id>1</wp:post_author_id>
898
+ <wp:is_sticky>0</wp:is_sticky>
899
+ <wp:postmeta>
900
+ <wp:meta_key>_lp_duration</wp:meta_key>
901
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
902
+ </wp:postmeta> <wp:postmeta>
903
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
904
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
905
+ </wp:postmeta>
906
+ </item><item>
907
+ <title>adasdasdasda asd as</title>
908
+ <link>http://localhost/foobla/learnpress/1.0/lessons/adasdasdasda-asd-as/</link>
909
+ <pubDate>Thu, 17 Dec 2015 02:29:12 +0000</pubDate>
910
+ <dc:creator><![CDATA[admin]]></dc:creator>
911
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/adasdasdasda-asd-as/</guid>
912
+ <description></description>
913
+ <content:encoded><![CDATA[]]></content:encoded>
914
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
915
+ <wp:post_id>1524</wp:post_id>
916
+ <wp:post_date>2015-12-17 02:29:12</wp:post_date>
917
+ <wp:post_date_gmt>2015-12-17 02:29:12</wp:post_date_gmt>
918
+ <wp:comment_status>open</wp:comment_status>
919
+ <wp:ping_status>open</wp:ping_status>
920
+ <wp:post_name>adasdasdasda-asd-as</wp:post_name>
921
+ <wp:status>publish</wp:status>
922
+ <wp:post_parent>0</wp:post_parent>
923
+ <wp:menu_order>0</wp:menu_order>
924
+ <wp:post_type>lp_lesson</wp:post_type>
925
+ <wp:post_password></wp:post_password>
926
+ <wp:post_author_id>1</wp:post_author_id>
927
+ <wp:is_sticky>0</wp:is_sticky>
928
+ <wp:postmeta>
929
+ <wp:meta_key>_lp_duration</wp:meta_key>
930
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
931
+ </wp:postmeta> <wp:postmeta>
932
+ <wp:meta_key>_lp_max_students</wp:meta_key>
933
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
934
+ </wp:postmeta> <wp:postmeta>
935
+ <wp:meta_key>_lp_students</wp:meta_key>
936
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
937
+ </wp:postmeta> <wp:postmeta>
938
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
939
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
940
+ </wp:postmeta> <wp:postmeta>
941
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
942
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
943
+ </wp:postmeta> <wp:postmeta>
944
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
945
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
946
+ </wp:postmeta> <wp:postmeta>
947
+ <wp:meta_key>_lp_payment</wp:meta_key>
948
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
949
+ </wp:postmeta>
950
+ </item><item>
951
+ <title>asd asda sdasdas da</title>
952
+ <link>http://localhost/foobla/learnpress/1.0/lessons/asd-asda-sdasdas-da/</link>
953
+ <pubDate>Thu, 17 Dec 2015 02:29:12 +0000</pubDate>
954
+ <dc:creator><![CDATA[admin]]></dc:creator>
955
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/asd-asda-sdasdas-da/</guid>
956
+ <description></description>
957
+ <content:encoded><![CDATA[]]></content:encoded>
958
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
959
+ <wp:post_id>1525</wp:post_id>
960
+ <wp:post_date>2015-12-17 02:29:12</wp:post_date>
961
+ <wp:post_date_gmt>2015-12-17 02:29:12</wp:post_date_gmt>
962
+ <wp:comment_status>open</wp:comment_status>
963
+ <wp:ping_status>open</wp:ping_status>
964
+ <wp:post_name>asd-asda-sdasdas-da</wp:post_name>
965
+ <wp:status>publish</wp:status>
966
+ <wp:post_parent>0</wp:post_parent>
967
+ <wp:menu_order>0</wp:menu_order>
968
+ <wp:post_type>lp_lesson</wp:post_type>
969
+ <wp:post_password></wp:post_password>
970
+ <wp:post_author_id>1</wp:post_author_id>
971
+ <wp:is_sticky>0</wp:is_sticky>
972
+
973
+ </item><item>
974
+ <title>asdasdasdasdasda</title>
975
+ <link>http://localhost/foobla/learnpress/1.0/lessons/asdasdasdasdasda/</link>
976
+ <pubDate>Thu, 17 Dec 2015 02:29:12 +0000</pubDate>
977
+ <dc:creator><![CDATA[admin]]></dc:creator>
978
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/asdasdasdasdasda/</guid>
979
+ <description></description>
980
+ <content:encoded><![CDATA[]]></content:encoded>
981
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
982
+ <wp:post_id>1526</wp:post_id>
983
+ <wp:post_date>2015-12-17 02:29:12</wp:post_date>
984
+ <wp:post_date_gmt>2015-12-17 02:29:12</wp:post_date_gmt>
985
+ <wp:comment_status>open</wp:comment_status>
986
+ <wp:ping_status>open</wp:ping_status>
987
+ <wp:post_name>asdasdasdasdasda</wp:post_name>
988
+ <wp:status>publish</wp:status>
989
+ <wp:post_parent>0</wp:post_parent>
990
+ <wp:menu_order>0</wp:menu_order>
991
+ <wp:post_type>lp_lesson</wp:post_type>
992
+ <wp:post_password></wp:post_password>
993
+ <wp:post_author_id>1</wp:post_author_id>
994
+ <wp:is_sticky>0</wp:is_sticky>
995
+
996
+ </item><item>
997
+ <title>assasdasdasdasdasd</title>
998
+ <link>http://localhost/foobla/learnpress/1.0/lessons/assasdasdasdasdasd/</link>
999
+ <pubDate>Thu, 17 Dec 2015 02:29:12 +0000</pubDate>
1000
+ <dc:creator><![CDATA[admin]]></dc:creator>
1001
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/assasdasdasdasdasd/</guid>
1002
+ <description></description>
1003
+ <content:encoded><![CDATA[]]></content:encoded>
1004
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1005
+ <wp:post_id>1527</wp:post_id>
1006
+ <wp:post_date>2015-12-17 02:29:12</wp:post_date>
1007
+ <wp:post_date_gmt>2015-12-17 02:29:12</wp:post_date_gmt>
1008
+ <wp:comment_status>open</wp:comment_status>
1009
+ <wp:ping_status>open</wp:ping_status>
1010
+ <wp:post_name>assasdasdasdasdasd</wp:post_name>
1011
+ <wp:status>publish</wp:status>
1012
+ <wp:post_parent>0</wp:post_parent>
1013
+ <wp:menu_order>0</wp:menu_order>
1014
+ <wp:post_type>lp_lesson</wp:post_type>
1015
+ <wp:post_password></wp:post_password>
1016
+ <wp:post_author_id>1</wp:post_author_id>
1017
+ <wp:is_sticky>0</wp:is_sticky>
1018
+
1019
+ </item><item>
1020
+ <title>How to create a course</title>
1021
+ <link>http://localhost/foobla/learnpress/1.0/lessons/how-to-create-a-course/</link>
1022
+ <pubDate>Thu, 17 Dec 2015 03:39:13 +0000</pubDate>
1023
+ <dc:creator><![CDATA[admin]]></dc:creator>
1024
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/how-to-create-a-course/</guid>
1025
+ <description></description>
1026
+ <content:encoded><![CDATA[]]></content:encoded>
1027
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1028
+ <wp:post_id>1528</wp:post_id>
1029
+ <wp:post_date>2015-12-17 03:39:13</wp:post_date>
1030
+ <wp:post_date_gmt>2015-12-17 03:39:13</wp:post_date_gmt>
1031
+ <wp:comment_status>open</wp:comment_status>
1032
+ <wp:ping_status>open</wp:ping_status>
1033
+ <wp:post_name>how-to-create-a-course</wp:post_name>
1034
+ <wp:status>publish</wp:status>
1035
+ <wp:post_parent>0</wp:post_parent>
1036
+ <wp:menu_order>0</wp:menu_order>
1037
+ <wp:post_type>lp_lesson</wp:post_type>
1038
+ <wp:post_password></wp:post_password>
1039
+ <wp:post_author_id>1</wp:post_author_id>
1040
+ <wp:is_sticky>0</wp:is_sticky>
1041
+ <wp:postmeta>
1042
+ <wp:meta_key>_lp_duration</wp:meta_key>
1043
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1044
+ </wp:postmeta> <wp:postmeta>
1045
+ <wp:meta_key>_lp_max_students</wp:meta_key>
1046
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
1047
+ </wp:postmeta> <wp:postmeta>
1048
+ <wp:meta_key>_lp_students</wp:meta_key>
1049
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1050
+ </wp:postmeta> <wp:postmeta>
1051
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
1052
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1053
+ </wp:postmeta> <wp:postmeta>
1054
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
1055
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
1056
+ </wp:postmeta> <wp:postmeta>
1057
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
1058
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
1059
+ </wp:postmeta> <wp:postmeta>
1060
+ <wp:meta_key>_lp_payment</wp:meta_key>
1061
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
1062
+ </wp:postmeta>
1063
+ </item><item>
1064
+ <title>What is your name</title>
1065
+ <link>http://localhost/foobla/learnpress/1.0/lessons/what-is-your-name/</link>
1066
+ <pubDate>Thu, 17 Dec 2015 03:39:13 +0000</pubDate>
1067
+ <dc:creator><![CDATA[admin]]></dc:creator>
1068
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/what-is-your-name/</guid>
1069
+ <description></description>
1070
+ <content:encoded><![CDATA[]]></content:encoded>
1071
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1072
+ <wp:post_id>1529</wp:post_id>
1073
+ <wp:post_date>2015-12-17 03:39:13</wp:post_date>
1074
+ <wp:post_date_gmt>2015-12-17 03:39:13</wp:post_date_gmt>
1075
+ <wp:comment_status>open</wp:comment_status>
1076
+ <wp:ping_status>open</wp:ping_status>
1077
+ <wp:post_name>what-is-your-name</wp:post_name>
1078
+ <wp:status>publish</wp:status>
1079
+ <wp:post_parent>0</wp:post_parent>
1080
+ <wp:menu_order>0</wp:menu_order>
1081
+ <wp:post_type>lp_lesson</wp:post_type>
1082
+ <wp:post_password></wp:post_password>
1083
+ <wp:post_author_id>1</wp:post_author_id>
1084
+ <wp:is_sticky>0</wp:is_sticky>
1085
+
1086
+ </item><item>
1087
+ <title>My name is Tu Nguyen</title>
1088
+ <link>http://localhost/foobla/learnpress/1.0/lessons/my-name-is-tu-nguyen/</link>
1089
+ <pubDate>Thu, 17 Dec 2015 03:39:13 +0000</pubDate>
1090
+ <dc:creator><![CDATA[admin]]></dc:creator>
1091
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/my-name-is-tu-nguyen/</guid>
1092
+ <description></description>
1093
+ <content:encoded><![CDATA[]]></content:encoded>
1094
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1095
+ <wp:post_id>1530</wp:post_id>
1096
+ <wp:post_date>2015-12-17 03:39:13</wp:post_date>
1097
+ <wp:post_date_gmt>2015-12-17 03:39:13</wp:post_date_gmt>
1098
+ <wp:comment_status>open</wp:comment_status>
1099
+ <wp:ping_status>open</wp:ping_status>
1100
+ <wp:post_name>my-name-is-tu-nguyen</wp:post_name>
1101
+ <wp:status>publish</wp:status>
1102
+ <wp:post_parent>0</wp:post_parent>
1103
+ <wp:menu_order>0</wp:menu_order>
1104
+ <wp:post_type>lp_lesson</wp:post_type>
1105
+ <wp:post_password></wp:post_password>
1106
+ <wp:post_author_id>1</wp:post_author_id>
1107
+ <wp:is_sticky>0</wp:is_sticky>
1108
+
1109
+ </item><item>
1110
+ <title>sdfsdfsdf sdf sdf sdf s</title>
1111
+ <link>http://localhost/foobla/learnpress/1.0/quizzes/sdfsdfsdf-sdf-sdf-sdf-s/</link>
1112
+ <pubDate>Thu, 17 Dec 2015 03:39:07 +0000</pubDate>
1113
+ <dc:creator><![CDATA[admin]]></dc:creator>
1114
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/quizzes/sdfsdfsdf-sdf-sdf-sdf-s/</guid>
1115
+ <description></description>
1116
+ <content:encoded><![CDATA[]]></content:encoded>
1117
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1118
+ <wp:post_id>1531</wp:post_id>
1119
+ <wp:post_date>2015-12-17 03:39:07</wp:post_date>
1120
+ <wp:post_date_gmt>2015-12-17 03:39:07</wp:post_date_gmt>
1121
+ <wp:comment_status>open</wp:comment_status>
1122
+ <wp:ping_status>open</wp:ping_status>
1123
+ <wp:post_name>sdfsdfsdf-sdf-sdf-sdf-s</wp:post_name>
1124
+ <wp:status>publish</wp:status>
1125
+ <wp:post_parent>0</wp:post_parent>
1126
+ <wp:menu_order>0</wp:menu_order>
1127
+ <wp:post_type>lp_quiz</wp:post_type>
1128
+ <wp:post_password></wp:post_password>
1129
+ <wp:post_author_id>1</wp:post_author_id>
1130
+ <wp:is_sticky>0</wp:is_sticky>
1131
+ <wp:postmeta>
1132
+ <wp:meta_key>_lp_duration</wp:meta_key>
1133
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1134
+ </wp:postmeta> <wp:postmeta>
1135
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1136
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1137
+ </wp:postmeta>
1138
+ </item><item>
1139
+ <title>sdfsd fsd fsdf</title>
1140
+ <link>http://localhost/foobla/learnpress/1.0/quizzes/sdfsd-fsd-fsdf/</link>
1141
+ <pubDate>Thu, 17 Dec 2015 03:44:14 +0000</pubDate>
1142
+ <dc:creator><![CDATA[admin]]></dc:creator>
1143
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/quizzes/sdfsd-fsd-fsdf/</guid>
1144
+ <description></description>
1145
+ <content:encoded><![CDATA[]]></content:encoded>
1146
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1147
+ <wp:post_id>1532</wp:post_id>
1148
+ <wp:post_date>2015-12-17 03:44:14</wp:post_date>
1149
+ <wp:post_date_gmt>2015-12-17 03:44:14</wp:post_date_gmt>
1150
+ <wp:comment_status>open</wp:comment_status>
1151
+ <wp:ping_status>open</wp:ping_status>
1152
+ <wp:post_name>sdfsd-fsd-fsdf</wp:post_name>
1153
+ <wp:status>publish</wp:status>
1154
+ <wp:post_parent>0</wp:post_parent>
1155
+ <wp:menu_order>0</wp:menu_order>
1156
+ <wp:post_type>lp_quiz</wp:post_type>
1157
+ <wp:post_password></wp:post_password>
1158
+ <wp:post_author_id>1</wp:post_author_id>
1159
+ <wp:is_sticky>0</wp:is_sticky>
1160
+ <wp:postmeta>
1161
+ <wp:meta_key>_lp_duration</wp:meta_key>
1162
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1163
+ </wp:postmeta> <wp:postmeta>
1164
+ <wp:meta_key>_lp_max_students</wp:meta_key>
1165
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
1166
+ </wp:postmeta> <wp:postmeta>
1167
+ <wp:meta_key>_lp_students</wp:meta_key>
1168
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1169
+ </wp:postmeta> <wp:postmeta>
1170
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
1171
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1172
+ </wp:postmeta> <wp:postmeta>
1173
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
1174
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
1175
+ </wp:postmeta> <wp:postmeta>
1176
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
1177
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
1178
+ </wp:postmeta> <wp:postmeta>
1179
+ <wp:meta_key>_lp_payment</wp:meta_key>
1180
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
1181
+ </wp:postmeta>
1182
+ </item><item>
1183
+ <title>sdf sdfsd fsdf sdfsd f</title>
1184
+ <link>http://localhost/foobla/learnpress/1.0/quizzes/sdf-sdfsd-fsdf-sdfsd-f/</link>
1185
+ <pubDate>Thu, 17 Dec 2015 03:44:14 +0000</pubDate>
1186
+ <dc:creator><![CDATA[admin]]></dc:creator>
1187
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/quizzes/sdf-sdfsd-fsdf-sdfsd-f/</guid>
1188
+ <description></description>
1189
+ <content:encoded><![CDATA[]]></content:encoded>
1190
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1191
+ <wp:post_id>1533</wp:post_id>
1192
+ <wp:post_date>2015-12-17 03:44:14</wp:post_date>
1193
+ <wp:post_date_gmt>2015-12-17 03:44:14</wp:post_date_gmt>
1194
+ <wp:comment_status>open</wp:comment_status>
1195
+ <wp:ping_status>open</wp:ping_status>
1196
+ <wp:post_name>sdf-sdfsd-fsdf-sdfsd-f</wp:post_name>
1197
+ <wp:status>publish</wp:status>
1198
+ <wp:post_parent>0</wp:post_parent>
1199
+ <wp:menu_order>0</wp:menu_order>
1200
+ <wp:post_type>lp_quiz</wp:post_type>
1201
+ <wp:post_password></wp:post_password>
1202
+ <wp:post_author_id>1</wp:post_author_id>
1203
+ <wp:is_sticky>0</wp:is_sticky>
1204
+
1205
+ </item><item>
1206
+ <title>happy new year!</title>
1207
+ <link>http://localhost/foobla/learnpress/1.0/lessons/happy-new-year/</link>
1208
+ <pubDate>Tue, 29 Dec 2015 09:25:33 +0000</pubDate>
1209
+ <dc:creator><![CDATA[admin]]></dc:creator>
1210
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/happy-new-year/</guid>
1211
+ <description></description>
1212
+ <content:encoded><![CDATA[]]></content:encoded>
1213
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1214
+ <wp:post_id>1534</wp:post_id>
1215
+ <wp:post_date>2015-12-29 09:25:33</wp:post_date>
1216
+ <wp:post_date_gmt>2015-12-29 09:25:33</wp:post_date_gmt>
1217
+ <wp:comment_status>closed</wp:comment_status>
1218
+ <wp:ping_status>closed</wp:ping_status>
1219
+ <wp:post_name>happy-new-year</wp:post_name>
1220
+ <wp:status>publish</wp:status>
1221
+ <wp:post_parent>0</wp:post_parent>
1222
+ <wp:menu_order>0</wp:menu_order>
1223
+ <wp:post_type>lp_lesson</wp:post_type>
1224
+ <wp:post_password></wp:post_password>
1225
+ <wp:post_author_id>1</wp:post_author_id>
1226
+ <wp:is_sticky>0</wp:is_sticky>
1227
+ <wp:postmeta>
1228
+ <wp:meta_key>_lp_duration</wp:meta_key>
1229
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1230
+ </wp:postmeta> <wp:postmeta>
1231
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1232
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1233
+ </wp:postmeta>
1234
+ </item><item>
1235
+ <title>happy new year!</title>
1236
+ <link>http://localhost/foobla/learnpress/1.0/lessons/happy-new-year-2/</link>
1237
+ <pubDate>Tue, 29 Dec 2015 09:25:34 +0000</pubDate>
1238
+ <dc:creator><![CDATA[admin]]></dc:creator>
1239
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/happy-new-year-2/</guid>
1240
+ <description></description>
1241
+ <content:encoded><![CDATA[]]></content:encoded>
1242
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1243
+ <wp:post_id>1535</wp:post_id>
1244
+ <wp:post_date>2015-12-29 09:25:34</wp:post_date>
1245
+ <wp:post_date_gmt>2015-12-29 09:25:34</wp:post_date_gmt>
1246
+ <wp:comment_status>closed</wp:comment_status>
1247
+ <wp:ping_status>closed</wp:ping_status>
1248
+ <wp:post_name>happy-new-year-2</wp:post_name>
1249
+ <wp:status>publish</wp:status>
1250
+ <wp:post_parent>0</wp:post_parent>
1251
+ <wp:menu_order>0</wp:menu_order>
1252
+ <wp:post_type>lp_lesson</wp:post_type>
1253
+ <wp:post_password></wp:post_password>
1254
+ <wp:post_author_id>1</wp:post_author_id>
1255
+ <wp:is_sticky>0</wp:is_sticky>
1256
+ <wp:postmeta>
1257
+ <wp:meta_key>_lp_duration</wp:meta_key>
1258
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1259
+ </wp:postmeta> <wp:postmeta>
1260
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1261
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1262
+ </wp:postmeta>
1263
+ </item><item>
1264
+ <title>Lesson 1</title>
1265
+ <link>http://localhost/foobla/learnpress/1.0/lessons/lesson-1/</link>
1266
+ <pubDate>Fri, 04 Dec 2015 08:17:04 +0000</pubDate>
1267
+ <dc:creator><![CDATA[admin]]></dc:creator>
1268
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/lesson-1/</guid>
1269
+ <description></description>
1270
+ <content:encoded><![CDATA[]]></content:encoded>
1271
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1272
+ <wp:post_id>1536</wp:post_id>
1273
+ <wp:post_date>2015-12-04 08:17:04</wp:post_date>
1274
+ <wp:post_date_gmt>2015-12-04 08:17:04</wp:post_date_gmt>
1275
+ <wp:comment_status>open</wp:comment_status>
1276
+ <wp:ping_status>open</wp:ping_status>
1277
+ <wp:post_name>lesson-1</wp:post_name>
1278
+ <wp:status>publish</wp:status>
1279
+ <wp:post_parent>0</wp:post_parent>
1280
+ <wp:menu_order>0</wp:menu_order>
1281
+ <wp:post_type>lp_lesson</wp:post_type>
1282
+ <wp:post_password></wp:post_password>
1283
+ <wp:post_author_id>1</wp:post_author_id>
1284
+ <wp:is_sticky>0</wp:is_sticky>
1285
+ <wp:postmeta>
1286
+ <wp:meta_key>_lp_duration</wp:meta_key>
1287
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1288
+ </wp:postmeta> <wp:postmeta>
1289
+ <wp:meta_key>_lp_max_students</wp:meta_key>
1290
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
1291
+ </wp:postmeta> <wp:postmeta>
1292
+ <wp:meta_key>_lp_students</wp:meta_key>
1293
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1294
+ </wp:postmeta> <wp:postmeta>
1295
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
1296
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1297
+ </wp:postmeta> <wp:postmeta>
1298
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
1299
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
1300
+ </wp:postmeta> <wp:postmeta>
1301
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
1302
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
1303
+ </wp:postmeta> <wp:postmeta>
1304
+ <wp:meta_key>_lp_payment</wp:meta_key>
1305
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
1306
+ </wp:postmeta> <wp:postmeta>
1307
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1308
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1309
+ </wp:postmeta> <wp:postmeta>
1310
+ <wp:meta_key>_edit_lock</wp:meta_key>
1311
+ <wp:meta_value><![CDATA[1451567890:1]]></wp:meta_value>
1312
+ </wp:postmeta>
1313
+ </item><item>
1314
+ <title>Lesson 2</title>
1315
+ <link>http://localhost/foobla/learnpress/1.0/lessons/lesson-2/</link>
1316
+ <pubDate>Fri, 04 Dec 2015 08:17:04 +0000</pubDate>
1317
+ <dc:creator><![CDATA[admin]]></dc:creator>
1318
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/lesson-2/</guid>
1319
+ <description></description>
1320
+ <content:encoded><![CDATA[]]></content:encoded>
1321
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1322
+ <wp:post_id>1537</wp:post_id>
1323
+ <wp:post_date>2015-12-04 08:17:04</wp:post_date>
1324
+ <wp:post_date_gmt>2015-12-04 08:17:04</wp:post_date_gmt>
1325
+ <wp:comment_status>open</wp:comment_status>
1326
+ <wp:ping_status>open</wp:ping_status>
1327
+ <wp:post_name>lesson-2</wp:post_name>
1328
+ <wp:status>publish</wp:status>
1329
+ <wp:post_parent>0</wp:post_parent>
1330
+ <wp:menu_order>0</wp:menu_order>
1331
+ <wp:post_type>lp_lesson</wp:post_type>
1332
+ <wp:post_password></wp:post_password>
1333
+ <wp:post_author_id>1</wp:post_author_id>
1334
+ <wp:is_sticky>0</wp:is_sticky>
1335
+ <wp:postmeta>
1336
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1337
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1338
+ </wp:postmeta>
1339
+ </item><item>
1340
+ <title>oi troi oi la troi</title>
1341
+ <link>http://localhost/foobla/learnpress/1.0/lessons/oi-troi-oi-la-troi/</link>
1342
+ <pubDate>Tue, 29 Dec 2015 09:29:54 +0000</pubDate>
1343
+ <dc:creator><![CDATA[admin]]></dc:creator>
1344
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/oi-troi-oi-la-troi/</guid>
1345
+ <description></description>
1346
+ <content:encoded><![CDATA[]]></content:encoded>
1347
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1348
+ <wp:post_id>1538</wp:post_id>
1349
+ <wp:post_date>2015-12-29 09:29:54</wp:post_date>
1350
+ <wp:post_date_gmt>2015-12-29 09:29:54</wp:post_date_gmt>
1351
+ <wp:comment_status>closed</wp:comment_status>
1352
+ <wp:ping_status>closed</wp:ping_status>
1353
+ <wp:post_name>oi-troi-oi-la-troi</wp:post_name>
1354
+ <wp:status>publish</wp:status>
1355
+ <wp:post_parent>0</wp:post_parent>
1356
+ <wp:menu_order>0</wp:menu_order>
1357
+ <wp:post_type>lp_lesson</wp:post_type>
1358
+ <wp:post_password></wp:post_password>
1359
+ <wp:post_author_id>1</wp:post_author_id>
1360
+ <wp:is_sticky>0</wp:is_sticky>
1361
+ <wp:postmeta>
1362
+ <wp:meta_key>_lp_duration</wp:meta_key>
1363
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1364
+ </wp:postmeta> <wp:postmeta>
1365
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1366
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1367
+ </wp:postmeta>
1368
+ </item><item>
1369
+ <title>333333333333</title>
1370
+ <link>http://localhost/foobla/learnpress/1.0/lessons/333333333333-2/</link>
1371
+ <pubDate>Tue, 08 Dec 2015 04:18:47 +0000</pubDate>
1372
+ <dc:creator><![CDATA[admin]]></dc:creator>
1373
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/333333333333-2/</guid>
1374
+ <description></description>
1375
+ <content:encoded><![CDATA[]]></content:encoded>
1376
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1377
+ <wp:post_id>1539</wp:post_id>
1378
+ <wp:post_date>2015-12-08 04:18:47</wp:post_date>
1379
+ <wp:post_date_gmt>2015-12-08 04:18:47</wp:post_date_gmt>
1380
+ <wp:comment_status>open</wp:comment_status>
1381
+ <wp:ping_status>open</wp:ping_status>
1382
+ <wp:post_name>333333333333-2</wp:post_name>
1383
+ <wp:status>publish</wp:status>
1384
+ <wp:post_parent>0</wp:post_parent>
1385
+ <wp:menu_order>0</wp:menu_order>
1386
+ <wp:post_type>lp_lesson</wp:post_type>
1387
+ <wp:post_password></wp:post_password>
1388
+ <wp:post_author_id>1</wp:post_author_id>
1389
+ <wp:is_sticky>0</wp:is_sticky>
1390
+ <wp:postmeta>
1391
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1392
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1393
+ </wp:postmeta>
1394
+ </item><item>
1395
+ <title>44444444</title>
1396
+ <link>http://localhost/foobla/learnpress/1.0/lessons/44444444-2/</link>
1397
+ <pubDate>Tue, 29 Dec 2015 09:02:22 +0000</pubDate>
1398
+ <dc:creator><![CDATA[admin]]></dc:creator>
1399
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/44444444-2/</guid>
1400
+ <description></description>
1401
+ <content:encoded><![CDATA[]]></content:encoded>
1402
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1403
+ <wp:post_id>1540</wp:post_id>
1404
+ <wp:post_date>2015-12-29 09:02:22</wp:post_date>
1405
+ <wp:post_date_gmt>2015-12-29 09:02:22</wp:post_date_gmt>
1406
+ <wp:comment_status>closed</wp:comment_status>
1407
+ <wp:ping_status>closed</wp:ping_status>
1408
+ <wp:post_name>44444444-2</wp:post_name>
1409
+ <wp:status>publish</wp:status>
1410
+ <wp:post_parent>0</wp:post_parent>
1411
+ <wp:menu_order>0</wp:menu_order>
1412
+ <wp:post_type>lp_lesson</wp:post_type>
1413
+ <wp:post_password></wp:post_password>
1414
+ <wp:post_author_id>1</wp:post_author_id>
1415
+ <wp:is_sticky>0</wp:is_sticky>
1416
+ <wp:postmeta>
1417
+ <wp:meta_key>_lp_duration</wp:meta_key>
1418
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1419
+ </wp:postmeta> <wp:postmeta>
1420
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1421
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1422
+ </wp:postmeta>
1423
+ </item><item>
1424
+ <title>cookie</title>
1425
+ <link>http://localhost/foobla/learnpress/1.0/lessons/cookie/</link>
1426
+ <pubDate>Tue, 29 Dec 2015 09:33:07 +0000</pubDate>
1427
+ <dc:creator><![CDATA[admin]]></dc:creator>
1428
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/cookie/</guid>
1429
+ <description></description>
1430
+ <content:encoded><![CDATA[]]></content:encoded>
1431
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1432
+ <wp:post_id>1541</wp:post_id>
1433
+ <wp:post_date>2015-12-29 09:33:07</wp:post_date>
1434
+ <wp:post_date_gmt>2015-12-29 09:33:07</wp:post_date_gmt>
1435
+ <wp:comment_status>closed</wp:comment_status>
1436
+ <wp:ping_status>closed</wp:ping_status>
1437
+ <wp:post_name>cookie</wp:post_name>
1438
+ <wp:status>publish</wp:status>
1439
+ <wp:post_parent>0</wp:post_parent>
1440
+ <wp:menu_order>0</wp:menu_order>
1441
+ <wp:post_type>lp_lesson</wp:post_type>
1442
+ <wp:post_password></wp:post_password>
1443
+ <wp:post_author_id>1</wp:post_author_id>
1444
+ <wp:is_sticky>0</wp:is_sticky>
1445
+ <wp:postmeta>
1446
+ <wp:meta_key>_lp_duration</wp:meta_key>
1447
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1448
+ </wp:postmeta> <wp:postmeta>
1449
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1450
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1451
+ </wp:postmeta>
1452
+ </item> </channel>
1453
+ </rss>
dummy-data/learnpress-how-to-use-learnpress.xml ADDED
@@ -0,0 +1,1373 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <?xml version="1.0" encoding="UTF-8" ?>
3
+ <rss version="2.0"
4
+ xmlns:excerpt="http://wordpress.org/export/LPR_EXPORT_VER/excerpt/"
5
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
6
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
7
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
8
+ xmlns:wp="http://wordpress.org/export/LPR_EXPORT_VER/"
9
+ >
10
+ <channel>
11
+ <title>DEV LearnPress 1.0</title>
12
+ <link>http://localhost/foobla/learnpress/1.0</link>
13
+ <description>Just another WordPress site</description>
14
+ <pubDate>Fri, 08 Jan 2016 07:01:22 +0000</pubDate>
15
+ <language>en-US</language>
16
+ <wp:wxr_version>1.0</wp:wxr_version>
17
+ <wp:base_site_url>http://localhost/foobla/learnpress/1.0</wp:base_site_url>
18
+ <wp:base_blog_url>http://localhost/foobla/learnpress/1.0</wp:base_blog_url>
19
+ <wp:plugin_name>learnpress</wp:plugin_name>
20
+ <wp:plugin_version>1.0</wp:plugin_version>
21
+ <wp:author><wp:author_id>1</wp:author_id><wp:author_login>admin</wp:author_login><wp:author_email>tunnhn@gmail.com</wp:author_email><wp:author_display_name><![CDATA[admin]]></wp:author_display_name><wp:author_first_name><![CDATA[]]></wp:author_first_name><wp:author_last_name><![CDATA[]]></wp:author_last_name></wp:author>
22
+ <wp:author><wp:author_id>4</wp:author_id><wp:author_login>instructor</wp:author_login><wp:author_email>tunn@foobla.com</wp:author_email><wp:author_display_name><![CDATA[In Structor]]></wp:author_display_name><wp:author_first_name><![CDATA[In]]></wp:author_first_name><wp:author_last_name><![CDATA[Structor]]></wp:author_last_name></wp:author>
23
+ <item>
24
+ <title>This is a new course</title>
25
+ <link>http://localhost/foobla/learnpress/1.0/dao-tao-cac-khoa-hoc-onine/this-is-a-new-course/</link>
26
+ <pubDate>Wed, 11 Nov 2015 10:45:53 +0000</pubDate>
27
+ <dc:creator><![CDATA[admin]]></dc:creator>
28
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/?post_type=lp_course&#038;p=873</guid>
29
+ <description></description>
30
+ <content:encoded><![CDATA[]]></content:encoded>
31
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
32
+ <wp:post_id>873</wp:post_id>
33
+ <wp:post_date>2015-11-11 10:45:53</wp:post_date>
34
+ <wp:post_date_gmt>2015-11-11 10:45:53</wp:post_date_gmt>
35
+ <wp:comment_status>open</wp:comment_status>
36
+ <wp:ping_status>open</wp:ping_status>
37
+ <wp:post_name>this-is-a-new-course</wp:post_name>
38
+ <wp:status>publish</wp:status>
39
+ <wp:post_parent>0</wp:post_parent>
40
+ <wp:menu_order>0</wp:menu_order>
41
+ <wp:post_type>lp_course</wp:post_type>
42
+ <wp:post_password></wp:post_password>
43
+ <wp:post_author_id>1</wp:post_author_id>
44
+ <wp:is_sticky>0</wp:is_sticky>
45
+ <wp:postmeta>
46
+ <wp:meta_key>_edit_lock</wp:meta_key>
47
+ <wp:meta_value><![CDATA[1451441611:1]]></wp:meta_value>
48
+ </wp:postmeta> <wp:postmeta>
49
+ <wp:meta_key>_edit_last</wp:meta_key>
50
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
51
+ </wp:postmeta> <wp:postmeta>
52
+ <wp:meta_key>_lp_duration</wp:meta_key>
53
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
54
+ </wp:postmeta> <wp:postmeta>
55
+ <wp:meta_key>_lp_max_students</wp:meta_key>
56
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
57
+ </wp:postmeta> <wp:postmeta>
58
+ <wp:meta_key>_lp_students</wp:meta_key>
59
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
60
+ </wp:postmeta> <wp:postmeta>
61
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
62
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
63
+ </wp:postmeta> <wp:postmeta>
64
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
65
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
66
+ </wp:postmeta> <wp:postmeta>
67
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
68
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
69
+ </wp:postmeta> <wp:postmeta>
70
+ <wp:meta_key>_lp_payment</wp:meta_key>
71
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
72
+ </wp:postmeta> <wp:postmeta>
73
+ <wp:meta_key>_lpr_course_lesson_quiz</wp:meta_key>
74
+ <wp:meta_value><![CDATA[]]></wp:meta_value>
75
+ </wp:postmeta> <wp:postmeta>
76
+ <wp:meta_key>_lp_course_status</wp:meta_key>
77
+ <wp:meta_value><![CDATA[publish]]></wp:meta_value>
78
+ </wp:postmeta> <wp:postmeta>
79
+ <wp:meta_key>_lp_curriculum</wp:meta_key>
80
+ <wp:meta_value><![CDATA[a:1:{i:0;a:3:{s:4:"name";s:10:"Section #1";s:11:"description";s:0:"";s:5:"items";a:2:{i:614;a:5:{s:4:"name";s:18:"word wide web 2222";s:8:"old_name";s:13:"word wide web";s:7:"item_id";s:4:"1232";s:15:"section_item_id";s:3:"614";s:9:"post_type";s:9:"lp_lesson";}s:6:"item-1";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}}]]></wp:meta_value>
81
+ </wp:postmeta>
82
+ <wp:section>
83
+ <wp:section_id>144</wp:section_id>
84
+ <wp:section_name>Section #1</wp:section_name>
85
+ <wp:section_course_id>873</wp:section_course_id>
86
+ <wp:section_order>1</wp:section_order>
87
+ <wp:section_description><![CDATA[]]></wp:section_description>
88
+ <!--SELECT si.*, p.post_type FROM wp_learnpress_section_items si INNER JOIN wp_posts p ON p.ID = si.item_id WHERE section_id = 144--> <wp:section_item>
89
+ <wp:section_id>144</wp:section_id>
90
+ <wp:item_id>1232</wp:item_id>
91
+ <wp:item_order>1</wp:item_order>
92
+ <wp:item_type>lp_lesson</wp:item_type>
93
+ </wp:section_item>
94
+ </wp:section>
95
+
96
+ </item><item>
97
+ <title>word wide web 2222</title>
98
+ <link>http://localhost/foobla/learnpress/1.0/lessons/wwwwwwwwwwwwwwwwwwww/</link>
99
+ <pubDate>Wed, 30 Dec 2015 02:06:58 +0000</pubDate>
100
+ <dc:creator><![CDATA[admin]]></dc:creator>
101
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/?post_type=lp_lesson&#038;p=1232</guid>
102
+ <description></description>
103
+ <content:encoded><![CDATA[]]></content:encoded>
104
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
105
+ <wp:post_id>1232</wp:post_id>
106
+ <wp:post_date>2015-12-30 02:06:58</wp:post_date>
107
+ <wp:post_date_gmt>2015-12-30 02:06:58</wp:post_date_gmt>
108
+ <wp:comment_status>closed</wp:comment_status>
109
+ <wp:ping_status>closed</wp:ping_status>
110
+ <wp:post_name>wwwwwwwwwwwwwwwwwwww</wp:post_name>
111
+ <wp:status>publish</wp:status>
112
+ <wp:post_parent>0</wp:post_parent>
113
+ <wp:menu_order>0</wp:menu_order>
114
+ <wp:post_type>lp_lesson</wp:post_type>
115
+ <wp:post_password></wp:post_password>
116
+ <wp:post_author_id>1</wp:post_author_id>
117
+ <wp:is_sticky>0</wp:is_sticky>
118
+ <wp:postmeta>
119
+ <wp:meta_key>_edit_lock</wp:meta_key>
120
+ <wp:meta_value><![CDATA[1451443416:1]]></wp:meta_value>
121
+ </wp:postmeta>
122
+ </item> <item>
123
+ <title>What should be here?</title>
124
+ <link>http://localhost/foobla/learnpress/1.0/dao-tao-cac-khoa-hoc-onine/what-should-be-here/</link>
125
+ <pubDate>Fri, 04 Dec 2015 07:08:08 +0000</pubDate>
126
+ <dc:creator><![CDATA[instructor]]></dc:creator>
127
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/?post_type=lp_course&#038;p=908</guid>
128
+ <description></description>
129
+ <content:encoded><![CDATA[Phasellus accumsan cursus velit. Phasellus nec sem in justo pellentesque facilisis. Fusce vel dui. Integer tincidunt. Quisque id odio.
130
+
131
+ Sed hendrerit. Morbi mattis ullamcorper velit. Phasellus dolor. Sed libero. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.
132
+
133
+ Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. Phasellus tempus. Donec posuere vulputate arcu. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Sed a libero.
134
+
135
+ Nam eget dui. Quisque ut nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Nunc nec neque. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam.
136
+
137
+ Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Vestibulum suscipit nulla quis orci. Fusce ac felis sit amet ligula pharetra condimentum. Vestibulum fringilla pede sit amet augue. Etiam rhoncus.]]></content:encoded>
138
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
139
+ <wp:post_id>908</wp:post_id>
140
+ <wp:post_date>2015-12-04 07:08:08</wp:post_date>
141
+ <wp:post_date_gmt>2015-12-04 07:08:08</wp:post_date_gmt>
142
+ <wp:comment_status>open</wp:comment_status>
143
+ <wp:ping_status>open</wp:ping_status>
144
+ <wp:post_name>what-should-be-here</wp:post_name>
145
+ <wp:status>publish</wp:status>
146
+ <wp:post_parent>0</wp:post_parent>
147
+ <wp:menu_order>0</wp:menu_order>
148
+ <wp:post_type>lp_course</wp:post_type>
149
+ <wp:post_password></wp:post_password>
150
+ <wp:post_author_id>4</wp:post_author_id>
151
+ <wp:is_sticky>0</wp:is_sticky>
152
+ <category domain="course_category" nicename="it" id="18" parent="0" description=" "><![CDATA[IT]]></category>
153
+ <category domain="course_category" nicename="software" id="19" parent="18" description=" "><![CDATA[Software]]></category>
154
+ <wp:postmeta>
155
+ <wp:meta_key>_edit_lock</wp:meta_key>
156
+ <wp:meta_value><![CDATA[1452156731:1]]></wp:meta_value>
157
+ </wp:postmeta> <wp:postmeta>
158
+ <wp:meta_key>_edit_last</wp:meta_key>
159
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
160
+ </wp:postmeta> <wp:postmeta>
161
+ <wp:meta_key>_admin_hidden_sections</wp:meta_key>
162
+ <wp:meta_value><![CDATA[a:5:{i:0;s:3:"132";i:1;s:3:"133";i:2;s:3:"134";i:3;s:3:"135";i:4;s:0:"";}]]></wp:meta_value>
163
+ </wp:postmeta> <wp:postmeta>
164
+ <wp:meta_key>_lpr_course_lesson_quiz</wp:meta_key>
165
+ <wp:meta_value><![CDATA[]]></wp:meta_value>
166
+ </wp:postmeta> <wp:postmeta>
167
+ <wp:meta_key>_lp_curriculum</wp:meta_key>
168
+ <wp:meta_value><![CDATA[a:6:{i:0;a:3:{s:4:"name";s:10:"Section #1";s:11:"description";s:33:"asd asd asdasd asdasd asdasd asda";s:5:"items";a:15:{i:615;a:5:{s:4:"name";s:12:"333333333333";s:8:"old_name";s:12:"333333333333";s:7:"item_id";s:4:"1146";s:15:"section_item_id";s:3:"615";s:9:"post_type";s:7:"lp_quiz";}i:616;a:5:{s:4:"name";s:18:"where are you now?";s:8:"old_name";s:18:"where are you now?";s:7:"item_id";s:4:"1148";s:15:"section_item_id";s:3:"616";s:9:"post_type";s:9:"lp_lesson";}i:617;a:5:{s:4:"name";s:21:"I am here, beside you";s:8:"old_name";s:21:"I am here, beside you";s:7:"item_id";s:4:"1149";s:15:"section_item_id";s:3:"617";s:9:"post_type";s:7:"lp_quiz";}i:618;a:5:{s:4:"name";s:9:"asdasdasd";s:8:"old_name";s:9:"asdasdasd";s:7:"item_id";s:4:"1143";s:15:"section_item_id";s:3:"618";s:9:"post_type";s:9:"lp_lesson";}i:619;a:5:{s:4:"name";s:9:"dsfsdfsdf";s:8:"old_name";s:9:"dsfsdfsdf";s:7:"item_id";s:4:"1144";s:15:"section_item_id";s:3:"619";s:9:"post_type";s:9:"lp_lesson";}i:620;a:5:{s:4:"name";s:8:"Lesson 1";s:8:"old_name";s:8:"Lesson 1";s:7:"item_id";s:4:"1139";s:15:"section_item_id";s:3:"620";s:9:"post_type";s:9:"lp_lesson";}i:621;a:5:{s:4:"name";s:8:"Lesson 2";s:8:"old_name";s:8:"Lesson 2";s:7:"item_id";s:4:"1140";s:15:"section_item_id";s:3:"621";s:9:"post_type";s:9:"lp_lesson";}i:622;a:5:{s:4:"name";s:8:"Lesson 3";s:8:"old_name";s:8:"Lesson 3";s:7:"item_id";s:4:"1142";s:15:"section_item_id";s:3:"622";s:9:"post_type";s:9:"lp_lesson";}i:623;a:5:{s:4:"name";s:17:"qqqqqqqqqqqqqqqqq";s:8:"old_name";s:17:"qqqqqqqqqqqqqqqqq";s:7:"item_id";s:4:"1153";s:15:"section_item_id";s:3:"623";s:9:"post_type";s:9:"lp_lesson";}i:624;a:5:{s:4:"name";s:10:"trau va bo";s:8:"old_name";s:10:"trau va bo";s:7:"item_id";s:4:"1154";s:15:"section_item_id";s:3:"624";s:9:"post_type";s:9:"lp_lesson";}i:625;a:5:{s:4:"name";s:19:"adasdasdasda asd as";s:8:"old_name";s:19:"adasdasdasda asd as";s:7:"item_id";s:4:"1164";s:15:"section_item_id";s:3:"625";s:9:"post_type";s:9:"lp_lesson";}i:626;a:5:{s:4:"name";s:19:"asd asda sdasdas da";s:8:"old_name";s:19:"asd asda sdasdas da";s:7:"item_id";s:4:"1165";s:15:"section_item_id";s:3:"626";s:9:"post_type";s:9:"lp_lesson";}i:627;a:5:{s:4:"name";s:16:"asdasdasdasdasda";s:8:"old_name";s:16:"asdasdasdasdasda";s:7:"item_id";s:4:"1166";s:15:"section_item_id";s:3:"627";s:9:"post_type";s:9:"lp_lesson";}i:628;a:5:{s:4:"name";s:18:"assasdasdasdasdasd";s:8:"old_name";s:18:"assasdasdasdasdasd";s:7:"item_id";s:4:"1167";s:15:"section_item_id";s:3:"628";s:9:"post_type";s:9:"lp_lesson";}s:7:"item-14";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}i:1;a:3:{s:4:"name";s:10:"Section #2";s:11:"description";s:49:"asdas das d asdas das asdasd asdas dasdas dasdasd";s:5:"items";a:5:{i:629;a:5:{s:4:"name";s:22:"How to create a course";s:8:"old_name";s:22:"How to create a course";s:7:"item_id";s:4:"1169";s:15:"section_item_id";s:3:"629";s:9:"post_type";s:9:"lp_lesson";}i:630;a:5:{s:4:"name";s:17:"What is your name";s:8:"old_name";s:17:"What is your name";s:7:"item_id";s:4:"1170";s:15:"section_item_id";s:3:"630";s:9:"post_type";s:9:"lp_lesson";}i:631;a:5:{s:4:"name";s:20:"My name is Tu Nguyen";s:8:"old_name";s:20:"My name is Tu Nguyen";s:7:"item_id";s:4:"1171";s:15:"section_item_id";s:3:"631";s:9:"post_type";s:9:"lp_lesson";}i:632;a:5:{s:4:"name";s:23:"sdfsdfsdf sdf sdf sdf s";s:8:"old_name";s:23:"sdfsdfsdf sdf sdf sdf s";s:7:"item_id";s:4:"1168";s:15:"section_item_id";s:3:"632";s:9:"post_type";s:7:"lp_quiz";}s:6:"item-4";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}i:2;a:3:{s:4:"name";s:10:"Section #3";s:11:"description";s:0:"";s:5:"items";a:2:{i:633;a:5:{s:4:"name";s:14:"sdfsd fsd fsdf";s:8:"old_name";s:14:"sdfsd fsd fsdf";s:7:"item_id";s:4:"1172";s:15:"section_item_id";s:3:"633";s:9:"post_type";s:7:"lp_quiz";}s:6:"item-1";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}i:3;a:3:{s:4:"name";s:10:"Section #4";s:11:"description";s:0:"";s:5:"items";a:2:{i:634;a:5:{s:4:"name";s:22:"sdf sdfsd fsdf sdfsd f";s:8:"old_name";s:22:"sdf sdfsd fsdf sdfsd f";s:7:"item_id";s:4:"1173";s:15:"section_item_id";s:3:"634";s:9:"post_type";s:7:"lp_quiz";}s:6:"item-1";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}i:4;a:3:{s:4:"name";s:10:"Section #5";s:11:"description";s:0:"";s:5:"items";a:6:{i:635;a:5:{s:4:"name";s:15:"happy new year!";s:8:"old_name";s:15:"happy new year!";s:7:"item_id";s:4:"1228";s:15:"section_item_id";s:3:"635";s:9:"post_type";s:9:"lp_lesson";}i:636;a:5:{s:4:"name";s:15:"happy new year!";s:8:"old_name";s:15:"happy new year!";s:7:"item_id";s:4:"1229";s:15:"section_item_id";s:3:"636";s:9:"post_type";s:9:"lp_lesson";}i:637;a:5:{s:4:"name";s:8:"Lesson 1";s:8:"old_name";s:8:"Lesson 1";s:7:"item_id";s:4:"1136";s:15:"section_item_id";s:3:"637";s:9:"post_type";s:9:"lp_lesson";}i:638;a:5:{s:4:"name";s:8:"Lesson 2";s:8:"old_name";s:8:"Lesson 2";s:7:"item_id";s:4:"1137";s:15:"section_item_id";s:3:"638";s:9:"post_type";s:9:"lp_lesson";}i:639;a:5:{s:4:"name";s:18:"oi troi oi la troi";s:8:"old_name";s:18:"oi troi oi la troi";s:7:"item_id";s:4:"1230";s:15:"section_item_id";s:3:"639";s:9:"post_type";s:9:"lp_lesson";}s:6:"item-5";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}i:5;a:3:{s:4:"name";s:10:"Section #6";s:11:"description";s:0:"";s:5:"items";a:4:{i:640;a:5:{s:4:"name";s:12:"333333333333";s:8:"old_name";s:12:"333333333333";s:7:"item_id";s:4:"1145";s:15:"section_item_id";s:3:"640";s:9:"post_type";s:9:"lp_lesson";}i:641;a:5:{s:4:"name";s:8:"44444444";s:8:"old_name";s:8:"44444444";s:7:"item_id";s:4:"1227";s:15:"section_item_id";s:3:"641";s:9:"post_type";s:9:"lp_lesson";}i:642;a:5:{s:4:"name";s:6:"cookie";s:8:"old_name";s:6:"cookie";s:7:"item_id";s:4:"1231";s:15:"section_item_id";s:3:"642";s:9:"post_type";s:9:"lp_lesson";}s:6:"item-3";a:5:{s:4:"name";s:0:"";s:8:"old_name";s:0:"";s:7:"item_id";s:0:"";s:15:"section_item_id";s:0:"";s:9:"post_type";s:9:"lp_lesson";}}}}]]></wp:meta_value>
169
+ </wp:postmeta> <wp:postmeta>
170
+ <wp:meta_key>_lp_duration</wp:meta_key>
171
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
172
+ </wp:postmeta> <wp:postmeta>
173
+ <wp:meta_key>_lp_max_students</wp:meta_key>
174
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
175
+ </wp:postmeta> <wp:postmeta>
176
+ <wp:meta_key>_lp_students</wp:meta_key>
177
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
178
+ </wp:postmeta> <wp:postmeta>
179
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
180
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
181
+ </wp:postmeta> <wp:postmeta>
182
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
183
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
184
+ </wp:postmeta> <wp:postmeta>
185
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
186
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
187
+ </wp:postmeta> <wp:postmeta>
188
+ <wp:meta_key>_lp_payment</wp:meta_key>
189
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
190
+ </wp:postmeta> <wp:postmeta>
191
+ <wp:meta_key>_lp_course_status</wp:meta_key>
192
+ <wp:meta_value><![CDATA[publish]]></wp:meta_value>
193
+ </wp:postmeta> <wp:postmeta>
194
+ <wp:meta_key>_lp_course_result</wp:meta_key>
195
+ <wp:meta_value><![CDATA[evaluate_lesson]]></wp:meta_value>
196
+ </wp:postmeta> <wp:postmeta>
197
+ <wp:meta_key>_lp_required_enroll</wp:meta_key>
198
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
199
+ </wp:postmeta>
200
+ <wp:section>
201
+ <wp:section_id>145</wp:section_id>
202
+ <wp:section_name>Section #1</wp:section_name>
203
+ <wp:section_course_id>908</wp:section_course_id>
204
+ <wp:section_order>1</wp:section_order>
205
+ <wp:section_description><![CDATA[asd asd asdasd asdasd asdasd asda]]></wp:section_description>
206
+ <!--SELECT si.*, p.post_type FROM wp_learnpress_section_items si INNER JOIN wp_posts p ON p.ID = si.item_id WHERE section_id = 145--> <wp:section_item>
207
+ <wp:section_id>145</wp:section_id>
208
+ <wp:item_id>1146</wp:item_id>
209
+ <wp:item_order>1</wp:item_order>
210
+ <wp:item_type>lp_quiz</wp:item_type>
211
+ </wp:section_item>
212
+ <wp:section_item>
213
+ <wp:section_id>145</wp:section_id>
214
+ <wp:item_id>1148</wp:item_id>
215
+ <wp:item_order>2</wp:item_order>
216
+ <wp:item_type>lp_lesson</wp:item_type>
217
+ </wp:section_item>
218
+ <wp:section_item>
219
+ <wp:section_id>145</wp:section_id>
220
+ <wp:item_id>1149</wp:item_id>
221
+ <wp:item_order>3</wp:item_order>
222
+ <wp:item_type>lp_quiz</wp:item_type>
223
+ </wp:section_item>
224
+ <wp:section_item>
225
+ <wp:section_id>145</wp:section_id>
226
+ <wp:item_id>1143</wp:item_id>
227
+ <wp:item_order>4</wp:item_order>
228
+ <wp:item_type>lp_lesson</wp:item_type>
229
+ </wp:section_item>
230
+ <wp:section_item>
231
+ <wp:section_id>145</wp:section_id>
232
+ <wp:item_id>1144</wp:item_id>
233
+ <wp:item_order>5</wp:item_order>
234
+ <wp:item_type>lp_lesson</wp:item_type>
235
+ </wp:section_item>
236
+ <wp:section_item>
237
+ <wp:section_id>145</wp:section_id>
238
+ <wp:item_id>1139</wp:item_id>
239
+ <wp:item_order>6</wp:item_order>
240
+ <wp:item_type>lp_lesson</wp:item_type>
241
+ </wp:section_item>
242
+ <wp:section_item>
243
+ <wp:section_id>145</wp:section_id>
244
+ <wp:item_id>1140</wp:item_id>
245
+ <wp:item_order>7</wp:item_order>
246
+ <wp:item_type>lp_lesson</wp:item_type>
247
+ </wp:section_item>
248
+ <wp:section_item>
249
+ <wp:section_id>145</wp:section_id>
250
+ <wp:item_id>1142</wp:item_id>
251
+ <wp:item_order>8</wp:item_order>
252
+ <wp:item_type>lp_lesson</wp:item_type>
253
+ </wp:section_item>
254
+ <wp:section_item>
255
+ <wp:section_id>145</wp:section_id>
256
+ <wp:item_id>1153</wp:item_id>
257
+ <wp:item_order>9</wp:item_order>
258
+ <wp:item_type>lp_lesson</wp:item_type>
259
+ </wp:section_item>
260
+ <wp:section_item>
261
+ <wp:section_id>145</wp:section_id>
262
+ <wp:item_id>1154</wp:item_id>
263
+ <wp:item_order>10</wp:item_order>
264
+ <wp:item_type>lp_lesson</wp:item_type>
265
+ </wp:section_item>
266
+ <wp:section_item>
267
+ <wp:section_id>145</wp:section_id>
268
+ <wp:item_id>1164</wp:item_id>
269
+ <wp:item_order>11</wp:item_order>
270
+ <wp:item_type>lp_lesson</wp:item_type>
271
+ </wp:section_item>
272
+ <wp:section_item>
273
+ <wp:section_id>145</wp:section_id>
274
+ <wp:item_id>1165</wp:item_id>
275
+ <wp:item_order>12</wp:item_order>
276
+ <wp:item_type>lp_lesson</wp:item_type>
277
+ </wp:section_item>
278
+ <wp:section_item>
279
+ <wp:section_id>145</wp:section_id>
280
+ <wp:item_id>1166</wp:item_id>
281
+ <wp:item_order>13</wp:item_order>
282
+ <wp:item_type>lp_lesson</wp:item_type>
283
+ </wp:section_item>
284
+ <wp:section_item>
285
+ <wp:section_id>145</wp:section_id>
286
+ <wp:item_id>1167</wp:item_id>
287
+ <wp:item_order>14</wp:item_order>
288
+ <wp:item_type>lp_lesson</wp:item_type>
289
+ </wp:section_item>
290
+ </wp:section>
291
+
292
+ <wp:section>
293
+ <wp:section_id>146</wp:section_id>
294
+ <wp:section_name>Section #2</wp:section_name>
295
+ <wp:section_course_id>908</wp:section_course_id>
296
+ <wp:section_order>2</wp:section_order>
297
+ <wp:section_description><![CDATA[asdas das d asdas das asdasd asdas dasdas dasdasd]]></wp:section_description>
298
+ <!--SELECT si.*, p.post_type FROM wp_learnpress_section_items si INNER JOIN wp_posts p ON p.ID = si.item_id WHERE section_id = 146--> <wp:section_item>
299
+ <wp:section_id>146</wp:section_id>
300
+ <wp:item_id>1169</wp:item_id>
301
+ <wp:item_order>1</wp:item_order>
302
+ <wp:item_type>lp_lesson</wp:item_type>
303
+ </wp:section_item>
304
+ <wp:section_item>
305
+ <wp:section_id>146</wp:section_id>
306
+ <wp:item_id>1170</wp:item_id>
307
+ <wp:item_order>2</wp:item_order>
308
+ <wp:item_type>lp_lesson</wp:item_type>
309
+ </wp:section_item>
310
+ <wp:section_item>
311
+ <wp:section_id>146</wp:section_id>
312
+ <wp:item_id>1171</wp:item_id>
313
+ <wp:item_order>3</wp:item_order>
314
+ <wp:item_type>lp_lesson</wp:item_type>
315
+ </wp:section_item>
316
+ <wp:section_item>
317
+ <wp:section_id>146</wp:section_id>
318
+ <wp:item_id>1168</wp:item_id>
319
+ <wp:item_order>4</wp:item_order>
320
+ <wp:item_type>lp_quiz</wp:item_type>
321
+ </wp:section_item>
322
+ </wp:section>
323
+
324
+ <wp:section>
325
+ <wp:section_id>147</wp:section_id>
326
+ <wp:section_name>Section #3</wp:section_name>
327
+ <wp:section_course_id>908</wp:section_course_id>
328
+ <wp:section_order>3</wp:section_order>
329
+ <wp:section_description><![CDATA[]]></wp:section_description>
330
+ <!--SELECT si.*, p.post_type FROM wp_learnpress_section_items si INNER JOIN wp_posts p ON p.ID = si.item_id WHERE section_id = 147--> <wp:section_item>
331
+ <wp:section_id>147</wp:section_id>
332
+ <wp:item_id>1172</wp:item_id>
333
+ <wp:item_order>1</wp:item_order>
334
+ <wp:item_type>lp_quiz</wp:item_type>
335
+ </wp:section_item>
336
+ </wp:section>
337
+
338
+ <wp:section>
339
+ <wp:section_id>148</wp:section_id>
340
+ <wp:section_name>Section #4</wp:section_name>
341
+ <wp:section_course_id>908</wp:section_course_id>
342
+ <wp:section_order>4</wp:section_order>
343
+ <wp:section_description><![CDATA[]]></wp:section_description>
344
+ <!--SELECT si.*, p.post_type FROM wp_learnpress_section_items si INNER JOIN wp_posts p ON p.ID = si.item_id WHERE section_id = 148--> <wp:section_item>
345
+ <wp:section_id>148</wp:section_id>
346
+ <wp:item_id>1173</wp:item_id>
347
+ <wp:item_order>1</wp:item_order>
348
+ <wp:item_type>lp_quiz</wp:item_type>
349
+ </wp:section_item>
350
+ </wp:section>
351
+
352
+ <wp:section>
353
+ <wp:section_id>149</wp:section_id>
354
+ <wp:section_name>Section #5</wp:section_name>
355
+ <wp:section_course_id>908</wp:section_course_id>
356
+ <wp:section_order>5</wp:section_order>
357
+ <wp:section_description><![CDATA[]]></wp:section_description>
358
+ <!--SELECT si.*, p.post_type FROM wp_learnpress_section_items si INNER JOIN wp_posts p ON p.ID = si.item_id WHERE section_id = 149--> <wp:section_item>
359
+ <wp:section_id>149</wp:section_id>
360
+ <wp:item_id>1228</wp:item_id>
361
+ <wp:item_order>1</wp:item_order>
362
+ <wp:item_type>lp_lesson</wp:item_type>
363
+ </wp:section_item>
364
+ <wp:section_item>
365
+ <wp:section_id>149</wp:section_id>
366
+ <wp:item_id>1229</wp:item_id>
367
+ <wp:item_order>2</wp:item_order>
368
+ <wp:item_type>lp_lesson</wp:item_type>
369
+ </wp:section_item>
370
+ <wp:section_item>
371
+ <wp:section_id>149</wp:section_id>
372
+ <wp:item_id>1136</wp:item_id>
373
+ <wp:item_order>3</wp:item_order>
374
+ <wp:item_type>lp_lesson</wp:item_type>
375
+ </wp:section_item>
376
+ <wp:section_item>
377
+ <wp:section_id>149</wp:section_id>
378
+ <wp:item_id>1137</wp:item_id>
379
+ <wp:item_order>4</wp:item_order>
380
+ <wp:item_type>lp_lesson</wp:item_type>
381
+ </wp:section_item>
382
+ <wp:section_item>
383
+ <wp:section_id>149</wp:section_id>
384
+ <wp:item_id>1230</wp:item_id>
385
+ <wp:item_order>5</wp:item_order>
386
+ <wp:item_type>lp_lesson</wp:item_type>
387
+ </wp:section_item>
388
+ </wp:section>
389
+
390
+ <wp:section>
391
+ <wp:section_id>150</wp:section_id>
392
+ <wp:section_name>Section #6</wp:section_name>
393
+ <wp:section_course_id>908</wp:section_course_id>
394
+ <wp:section_order>6</wp:section_order>
395
+ <wp:section_description><![CDATA[]]></wp:section_description>
396
+ <!--SELECT si.*, p.post_type FROM wp_learnpress_section_items si INNER JOIN wp_posts p ON p.ID = si.item_id WHERE section_id = 150--> <wp:section_item>
397
+ <wp:section_id>150</wp:section_id>
398
+ <wp:item_id>1145</wp:item_id>
399
+ <wp:item_order>1</wp:item_order>
400
+ <wp:item_type>lp_lesson</wp:item_type>
401
+ </wp:section_item>
402
+ <wp:section_item>
403
+ <wp:section_id>150</wp:section_id>
404
+ <wp:item_id>1227</wp:item_id>
405
+ <wp:item_order>2</wp:item_order>
406
+ <wp:item_type>lp_lesson</wp:item_type>
407
+ </wp:section_item>
408
+ <wp:section_item>
409
+ <wp:section_id>150</wp:section_id>
410
+ <wp:item_id>1231</wp:item_id>
411
+ <wp:item_order>3</wp:item_order>
412
+ <wp:item_type>lp_lesson</wp:item_type>
413
+ </wp:section_item>
414
+ </wp:section>
415
+
416
+ <wp:comment>
417
+ <wp:comment_id>89</wp:comment_id>
418
+ <wp:comment_author><![CDATA[admin]]></wp:comment_author>
419
+ <wp:comment_author_email>tunnhn@gmail.com</wp:comment_author_email>
420
+ <wp:comment_author_url></wp:comment_author_url>
421
+ <wp:comment_author_IP>::1</wp:comment_author_IP>
422
+ <wp:comment_date>2016-01-07 03:50:26</wp:comment_date>
423
+ <wp:comment_date_gmt>2016-01-07 03:50:26</wp:comment_date_gmt>
424
+ <wp:comment_content><![CDATA[How create a course with LearnPress]]></wp:comment_content>
425
+ <wp:comment_approved>1</wp:comment_approved>
426
+ <wp:comment_type></wp:comment_type>
427
+ <wp:comment_parent>0</wp:comment_parent>
428
+ <wp:comment_user_id>1</wp:comment_user_id>
429
+ </wp:comment>
430
+ <wp:comment>
431
+ <wp:comment_id>90</wp:comment_id>
432
+ <wp:comment_author><![CDATA[admin]]></wp:comment_author>
433
+ <wp:comment_author_email>tunnhn@gmail.com</wp:comment_author_email>
434
+ <wp:comment_author_url></wp:comment_author_url>
435
+ <wp:comment_author_IP>::1</wp:comment_author_IP>
436
+ <wp:comment_date>2016-01-07 03:50:56</wp:comment_date>
437
+ <wp:comment_date_gmt>2016-01-07 03:50:56</wp:comment_date_gmt>
438
+ <wp:comment_content><![CDATA[Nam quam nunc blandit]]></wp:comment_content>
439
+ <wp:comment_approved>1</wp:comment_approved>
440
+ <wp:comment_type></wp:comment_type>
441
+ <wp:comment_parent>89</wp:comment_parent>
442
+ <wp:comment_user_id>1</wp:comment_user_id>
443
+ </wp:comment>
444
+ </item><item>
445
+ <title>333333333333</title>
446
+ <link>http://localhost/foobla/learnpress/1.0/quizzes/333333333333-2/</link>
447
+ <pubDate>Tue, 08 Dec 2015 04:19:22 +0000</pubDate>
448
+ <dc:creator><![CDATA[admin]]></dc:creator>
449
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/quizzes/333333333333-2/</guid>
450
+ <description></description>
451
+ <content:encoded><![CDATA[]]></content:encoded>
452
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
453
+ <wp:post_id>1146</wp:post_id>
454
+ <wp:post_date>2015-12-08 04:19:22</wp:post_date>
455
+ <wp:post_date_gmt>2015-12-08 04:19:22</wp:post_date_gmt>
456
+ <wp:comment_status>open</wp:comment_status>
457
+ <wp:ping_status>open</wp:ping_status>
458
+ <wp:post_name>333333333333-2</wp:post_name>
459
+ <wp:status>publish</wp:status>
460
+ <wp:post_parent>0</wp:post_parent>
461
+ <wp:menu_order>0</wp:menu_order>
462
+ <wp:post_type>lp_quiz</wp:post_type>
463
+ <wp:post_password></wp:post_password>
464
+ <wp:post_author_id>1</wp:post_author_id>
465
+ <wp:is_sticky>0</wp:is_sticky>
466
+ <wp:postmeta>
467
+ <wp:meta_key>_edit_lock</wp:meta_key>
468
+ <wp:meta_value><![CDATA[1451469598:1]]></wp:meta_value>
469
+ </wp:postmeta> <wp:postmeta>
470
+ <wp:meta_key>_edit_last</wp:meta_key>
471
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
472
+ </wp:postmeta> <wp:postmeta>
473
+ <wp:meta_key>_lp_duration</wp:meta_key>
474
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
475
+ </wp:postmeta> <wp:postmeta>
476
+ <wp:meta_key>_lp_show_result</wp:meta_key>
477
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
478
+ </wp:postmeta> <wp:postmeta>
479
+ <wp:meta_key>_lp_show_question_answer</wp:meta_key>
480
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
481
+ </wp:postmeta> <wp:postmeta>
482
+ <wp:meta_key>_lp_type</wp:meta_key>
483
+ <wp:meta_value><![CDATA[true_or_false]]></wp:meta_value>
484
+ </wp:postmeta>
485
+ </item><item>
486
+ <title>where are you now?</title>
487
+ <link>http://localhost/foobla/learnpress/1.0/lessons/where-are-you-now/</link>
488
+ <pubDate>Tue, 08 Dec 2015 08:20:59 +0000</pubDate>
489
+ <dc:creator><![CDATA[admin]]></dc:creator>
490
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/where-are-you-now/</guid>
491
+ <description></description>
492
+ <content:encoded><![CDATA[Nulla porta dolor. Ut varius tincidunt libero. Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Fusce egestas elit eget lorem. Vivamus aliquet elit ac nisl.
493
+
494
+ Cras ultricies mi eu turpis hendrerit fringilla. Quisque id mi. Fusce ac felis sit amet ligula pharetra condimentum. Maecenas malesuada. Praesent nec nisl a purus blandit viverra.
495
+
496
+ In auctor lobortis lacus. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Nam adipiscing. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Nam commodo suscipit quam.
497
+
498
+ Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam accumsan lorem in dui. Cras varius. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Suspendisse non nisl sit amet velit hendrerit rutrum.
499
+
500
+ Morbi ac felis. Etiam rhoncus. Praesent ac massa at ligula laoreet iaculis. Nunc nulla. In turpis.]]></content:encoded>
501
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
502
+ <wp:post_id>1148</wp:post_id>
503
+ <wp:post_date>2015-12-08 08:20:59</wp:post_date>
504
+ <wp:post_date_gmt>2015-12-08 08:20:59</wp:post_date_gmt>
505
+ <wp:comment_status>closed</wp:comment_status>
506
+ <wp:ping_status>closed</wp:ping_status>
507
+ <wp:post_name>where-are-you-now</wp:post_name>
508
+ <wp:status>publish</wp:status>
509
+ <wp:post_parent>0</wp:post_parent>
510
+ <wp:menu_order>0</wp:menu_order>
511
+ <wp:post_type>lp_lesson</wp:post_type>
512
+ <wp:post_password></wp:post_password>
513
+ <wp:post_author_id>1</wp:post_author_id>
514
+ <wp:is_sticky>0</wp:is_sticky>
515
+ <wp:postmeta>
516
+ <wp:meta_key>_lpr_course</wp:meta_key>
517
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
518
+ </wp:postmeta> <wp:postmeta>
519
+ <wp:meta_key>_lp_duration</wp:meta_key>
520
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
521
+ </wp:postmeta> <wp:postmeta>
522
+ <wp:meta_key>_lp_max_students</wp:meta_key>
523
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
524
+ </wp:postmeta> <wp:postmeta>
525
+ <wp:meta_key>_lp_students</wp:meta_key>
526
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
527
+ </wp:postmeta> <wp:postmeta>
528
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
529
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
530
+ </wp:postmeta> <wp:postmeta>
531
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
532
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
533
+ </wp:postmeta> <wp:postmeta>
534
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
535
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
536
+ </wp:postmeta> <wp:postmeta>
537
+ <wp:meta_key>_lp_payment</wp:meta_key>
538
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
539
+ </wp:postmeta> <wp:postmeta>
540
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
541
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
542
+ </wp:postmeta> <wp:postmeta>
543
+ <wp:meta_key>_edit_lock</wp:meta_key>
544
+ <wp:meta_value><![CDATA[1451449804:1]]></wp:meta_value>
545
+ </wp:postmeta> <wp:postmeta>
546
+ <wp:meta_key>_edit_last</wp:meta_key>
547
+ <wp:meta_value><![CDATA[1]]></wp:meta_value>
548
+ </wp:postmeta>
549
+ </item><item>
550
+ <title>I am here, beside you</title>
551
+ <link>http://localhost/foobla/learnpress/1.0/quizzes/i-am-here-beside-you/</link>
552
+ <pubDate>Tue, 08 Dec 2015 08:26:07 +0000</pubDate>
553
+ <dc:creator><![CDATA[admin]]></dc:creator>
554
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/quizzes/i-am-here-beside-you/</guid>
555
+ <description></description>
556
+ <content:encoded><![CDATA[]]></content:encoded>
557
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
558
+ <wp:post_id>1149</wp:post_id>
559
+ <wp:post_date>2015-12-08 08:26:07</wp:post_date>
560
+ <wp:post_date_gmt>2015-12-08 08:26:07</wp:post_date_gmt>
561
+ <wp:comment_status>open</wp:comment_status>
562
+ <wp:ping_status>open</wp:ping_status>
563
+ <wp:post_name>i-am-here-beside-you</wp:post_name>
564
+ <wp:status>publish</wp:status>
565
+ <wp:post_parent>0</wp:post_parent>
566
+ <wp:menu_order>0</wp:menu_order>
567
+ <wp:post_type>lp_quiz</wp:post_type>
568
+ <wp:post_password></wp:post_password>
569
+ <wp:post_author_id>1</wp:post_author_id>
570
+ <wp:is_sticky>0</wp:is_sticky>
571
+ <wp:postmeta>
572
+ <wp:meta_key>_lp_duration</wp:meta_key>
573
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
574
+ </wp:postmeta> <wp:postmeta>
575
+ <wp:meta_key>_lp_max_students</wp:meta_key>
576
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
577
+ </wp:postmeta> <wp:postmeta>
578
+ <wp:meta_key>_lp_students</wp:meta_key>
579
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
580
+ </wp:postmeta> <wp:postmeta>
581
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
582
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
583
+ </wp:postmeta> <wp:postmeta>
584
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
585
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
586
+ </wp:postmeta> <wp:postmeta>
587
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
588
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
589
+ </wp:postmeta> <wp:postmeta>
590
+ <wp:meta_key>_lp_payment</wp:meta_key>
591
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
592
+ </wp:postmeta> <wp:postmeta>
593
+ <wp:meta_key>_edit_lock</wp:meta_key>
594
+ <wp:meta_value><![CDATA[1450973326:1]]></wp:meta_value>
595
+ </wp:postmeta>
596
+ </item><item>
597
+ <title>asdasdasd</title>
598
+ <link>http://localhost/foobla/learnpress/1.0/lessons/asdasdasd/</link>
599
+ <pubDate>Tue, 08 Dec 2015 03:58:51 +0000</pubDate>
600
+ <dc:creator><![CDATA[admin]]></dc:creator>
601
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/asdasdasd/</guid>
602
+ <description></description>
603
+ <content:encoded><![CDATA[]]></content:encoded>
604
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
605
+ <wp:post_id>1143</wp:post_id>
606
+ <wp:post_date>2015-12-08 03:58:51</wp:post_date>
607
+ <wp:post_date_gmt>2015-12-08 03:58:51</wp:post_date_gmt>
608
+ <wp:comment_status>open</wp:comment_status>
609
+ <wp:ping_status>open</wp:ping_status>
610
+ <wp:post_name>asdasdasd</wp:post_name>
611
+ <wp:status>publish</wp:status>
612
+ <wp:post_parent>0</wp:post_parent>
613
+ <wp:menu_order>0</wp:menu_order>
614
+ <wp:post_type>lp_lesson</wp:post_type>
615
+ <wp:post_password></wp:post_password>
616
+ <wp:post_author_id>1</wp:post_author_id>
617
+ <wp:is_sticky>0</wp:is_sticky>
618
+ <wp:postmeta>
619
+ <wp:meta_key>_lpr_course</wp:meta_key>
620
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
621
+ </wp:postmeta> <wp:postmeta>
622
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
623
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
624
+ </wp:postmeta>
625
+ </item><item>
626
+ <title>dsfsdfsdf</title>
627
+ <link>http://localhost/foobla/learnpress/1.0/lessons/dsfsdfsdf/</link>
628
+ <pubDate>Tue, 08 Dec 2015 03:59:33 +0000</pubDate>
629
+ <dc:creator><![CDATA[admin]]></dc:creator>
630
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/dsfsdfsdf/</guid>
631
+ <description></description>
632
+ <content:encoded><![CDATA[]]></content:encoded>
633
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
634
+ <wp:post_id>1144</wp:post_id>
635
+ <wp:post_date>2015-12-08 03:59:33</wp:post_date>
636
+ <wp:post_date_gmt>2015-12-08 03:59:33</wp:post_date_gmt>
637
+ <wp:comment_status>open</wp:comment_status>
638
+ <wp:ping_status>open</wp:ping_status>
639
+ <wp:post_name>dsfsdfsdf</wp:post_name>
640
+ <wp:status>publish</wp:status>
641
+ <wp:post_parent>0</wp:post_parent>
642
+ <wp:menu_order>0</wp:menu_order>
643
+ <wp:post_type>lp_lesson</wp:post_type>
644
+ <wp:post_password></wp:post_password>
645
+ <wp:post_author_id>1</wp:post_author_id>
646
+ <wp:is_sticky>0</wp:is_sticky>
647
+ <wp:postmeta>
648
+ <wp:meta_key>_lpr_course</wp:meta_key>
649
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
650
+ </wp:postmeta> <wp:postmeta>
651
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
652
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
653
+ </wp:postmeta>
654
+ </item><item>
655
+ <title>Lesson 1</title>
656
+ <link>http://localhost/foobla/learnpress/1.0/lessons/lesson-1-2/</link>
657
+ <pubDate>Fri, 04 Dec 2015 08:41:24 +0000</pubDate>
658
+ <dc:creator><![CDATA[admin]]></dc:creator>
659
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/lesson-1-2/</guid>
660
+ <description></description>
661
+ <content:encoded><![CDATA[]]></content:encoded>
662
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
663
+ <wp:post_id>1139</wp:post_id>
664
+ <wp:post_date>2015-12-04 08:41:24</wp:post_date>
665
+ <wp:post_date_gmt>2015-12-04 08:41:24</wp:post_date_gmt>
666
+ <wp:comment_status>open</wp:comment_status>
667
+ <wp:ping_status>open</wp:ping_status>
668
+ <wp:post_name>lesson-1-2</wp:post_name>
669
+ <wp:status>publish</wp:status>
670
+ <wp:post_parent>0</wp:post_parent>
671
+ <wp:menu_order>0</wp:menu_order>
672
+ <wp:post_type>lp_lesson</wp:post_type>
673
+ <wp:post_password></wp:post_password>
674
+ <wp:post_author_id>1</wp:post_author_id>
675
+ <wp:is_sticky>0</wp:is_sticky>
676
+ <wp:postmeta>
677
+ <wp:meta_key>_lpr_course</wp:meta_key>
678
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
679
+ </wp:postmeta> <wp:postmeta>
680
+ <wp:meta_key>_lp_duration</wp:meta_key>
681
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
682
+ </wp:postmeta> <wp:postmeta>
683
+ <wp:meta_key>_lp_max_students</wp:meta_key>
684
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
685
+ </wp:postmeta> <wp:postmeta>
686
+ <wp:meta_key>_lp_students</wp:meta_key>
687
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
688
+ </wp:postmeta> <wp:postmeta>
689
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
690
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
691
+ </wp:postmeta> <wp:postmeta>
692
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
693
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
694
+ </wp:postmeta> <wp:postmeta>
695
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
696
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
697
+ </wp:postmeta> <wp:postmeta>
698
+ <wp:meta_key>_lp_payment</wp:meta_key>
699
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
700
+ </wp:postmeta> <wp:postmeta>
701
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
702
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
703
+ </wp:postmeta>
704
+ </item><item>
705
+ <title>Lesson 2</title>
706
+ <link>http://localhost/foobla/learnpress/1.0/lessons/lesson-2-2/</link>
707
+ <pubDate>Fri, 04 Dec 2015 08:41:24 +0000</pubDate>
708
+ <dc:creator><![CDATA[admin]]></dc:creator>
709
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/lesson-2-2/</guid>
710
+ <description></description>
711
+ <content:encoded><![CDATA[]]></content:encoded>
712
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
713
+ <wp:post_id>1140</wp:post_id>
714
+ <wp:post_date>2015-12-04 08:41:24</wp:post_date>
715
+ <wp:post_date_gmt>2015-12-04 08:41:24</wp:post_date_gmt>
716
+ <wp:comment_status>open</wp:comment_status>
717
+ <wp:ping_status>open</wp:ping_status>
718
+ <wp:post_name>lesson-2-2</wp:post_name>
719
+ <wp:status>publish</wp:status>
720
+ <wp:post_parent>0</wp:post_parent>
721
+ <wp:menu_order>0</wp:menu_order>
722
+ <wp:post_type>lp_lesson</wp:post_type>
723
+ <wp:post_password></wp:post_password>
724
+ <wp:post_author_id>1</wp:post_author_id>
725
+ <wp:is_sticky>0</wp:is_sticky>
726
+ <wp:postmeta>
727
+ <wp:meta_key>_lpr_course</wp:meta_key>
728
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
729
+ </wp:postmeta> <wp:postmeta>
730
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
731
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
732
+ </wp:postmeta>
733
+ </item><item>
734
+ <title>Lesson 3</title>
735
+ <link>http://localhost/foobla/learnpress/1.0/lessons/lesson-3/</link>
736
+ <pubDate>Tue, 08 Dec 2015 03:58:28 +0000</pubDate>
737
+ <dc:creator><![CDATA[admin]]></dc:creator>
738
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/lesson-3/</guid>
739
+ <description></description>
740
+ <content:encoded><![CDATA[]]></content:encoded>
741
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
742
+ <wp:post_id>1142</wp:post_id>
743
+ <wp:post_date>2015-12-08 03:58:28</wp:post_date>
744
+ <wp:post_date_gmt>2015-12-08 03:58:28</wp:post_date_gmt>
745
+ <wp:comment_status>open</wp:comment_status>
746
+ <wp:ping_status>open</wp:ping_status>
747
+ <wp:post_name>lesson-3</wp:post_name>
748
+ <wp:status>publish</wp:status>
749
+ <wp:post_parent>0</wp:post_parent>
750
+ <wp:menu_order>0</wp:menu_order>
751
+ <wp:post_type>lp_lesson</wp:post_type>
752
+ <wp:post_password></wp:post_password>
753
+ <wp:post_author_id>1</wp:post_author_id>
754
+ <wp:is_sticky>0</wp:is_sticky>
755
+ <wp:postmeta>
756
+ <wp:meta_key>_lpr_course</wp:meta_key>
757
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
758
+ </wp:postmeta> <wp:postmeta>
759
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
760
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
761
+ </wp:postmeta>
762
+ </item><item>
763
+ <title>qqqqqqqqqqqqqqqqq</title>
764
+ <link>http://localhost/foobla/learnpress/1.0/lessons/qqqqqqqqqqqqqqqqq/</link>
765
+ <pubDate>Tue, 08 Dec 2015 15:15:04 +0000</pubDate>
766
+ <dc:creator><![CDATA[admin]]></dc:creator>
767
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/qqqqqqqqqqqqqqqqq/</guid>
768
+ <description></description>
769
+ <content:encoded><![CDATA[]]></content:encoded>
770
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
771
+ <wp:post_id>1153</wp:post_id>
772
+ <wp:post_date>2015-12-08 15:15:04</wp:post_date>
773
+ <wp:post_date_gmt>2015-12-08 15:15:04</wp:post_date_gmt>
774
+ <wp:comment_status>open</wp:comment_status>
775
+ <wp:ping_status>open</wp:ping_status>
776
+ <wp:post_name>qqqqqqqqqqqqqqqqq</wp:post_name>
777
+ <wp:status>publish</wp:status>
778
+ <wp:post_parent>0</wp:post_parent>
779
+ <wp:menu_order>0</wp:menu_order>
780
+ <wp:post_type>lp_lesson</wp:post_type>
781
+ <wp:post_password></wp:post_password>
782
+ <wp:post_author_id>1</wp:post_author_id>
783
+ <wp:is_sticky>0</wp:is_sticky>
784
+ <wp:postmeta>
785
+ <wp:meta_key>_edit_lock</wp:meta_key>
786
+ <wp:meta_value><![CDATA[1449589506:1]]></wp:meta_value>
787
+ </wp:postmeta>
788
+ </item><item>
789
+ <title>trau va bo</title>
790
+ <link>http://localhost/foobla/learnpress/1.0/lessons/trau-va-bo/</link>
791
+ <pubDate>Tue, 08 Dec 2015 15:16:40 +0000</pubDate>
792
+ <dc:creator><![CDATA[admin]]></dc:creator>
793
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/trau-va-bo/</guid>
794
+ <description></description>
795
+ <content:encoded><![CDATA[]]></content:encoded>
796
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
797
+ <wp:post_id>1154</wp:post_id>
798
+ <wp:post_date>2015-12-08 15:16:40</wp:post_date>
799
+ <wp:post_date_gmt>2015-12-08 15:16:40</wp:post_date_gmt>
800
+ <wp:comment_status>open</wp:comment_status>
801
+ <wp:ping_status>open</wp:ping_status>
802
+ <wp:post_name>trau-va-bo</wp:post_name>
803
+ <wp:status>publish</wp:status>
804
+ <wp:post_parent>0</wp:post_parent>
805
+ <wp:menu_order>0</wp:menu_order>
806
+ <wp:post_type>lp_lesson</wp:post_type>
807
+ <wp:post_password></wp:post_password>
808
+ <wp:post_author_id>1</wp:post_author_id>
809
+ <wp:is_sticky>0</wp:is_sticky>
810
+ <wp:postmeta>
811
+ <wp:meta_key>_lp_duration</wp:meta_key>
812
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
813
+ </wp:postmeta> <wp:postmeta>
814
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
815
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
816
+ </wp:postmeta>
817
+ </item><item>
818
+ <title>adasdasdasda asd as</title>
819
+ <link>http://localhost/foobla/learnpress/1.0/lessons/adasdasdasda-asd-as/</link>
820
+ <pubDate>Thu, 17 Dec 2015 02:29:12 +0000</pubDate>
821
+ <dc:creator><![CDATA[admin]]></dc:creator>
822
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/adasdasdasda-asd-as/</guid>
823
+ <description></description>
824
+ <content:encoded><![CDATA[]]></content:encoded>
825
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
826
+ <wp:post_id>1164</wp:post_id>
827
+ <wp:post_date>2015-12-17 02:29:12</wp:post_date>
828
+ <wp:post_date_gmt>2015-12-17 02:29:12</wp:post_date_gmt>
829
+ <wp:comment_status>open</wp:comment_status>
830
+ <wp:ping_status>open</wp:ping_status>
831
+ <wp:post_name>adasdasdasda-asd-as</wp:post_name>
832
+ <wp:status>publish</wp:status>
833
+ <wp:post_parent>0</wp:post_parent>
834
+ <wp:menu_order>0</wp:menu_order>
835
+ <wp:post_type>lp_lesson</wp:post_type>
836
+ <wp:post_password></wp:post_password>
837
+ <wp:post_author_id>1</wp:post_author_id>
838
+ <wp:is_sticky>0</wp:is_sticky>
839
+ <wp:postmeta>
840
+ <wp:meta_key>_lp_duration</wp:meta_key>
841
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
842
+ </wp:postmeta> <wp:postmeta>
843
+ <wp:meta_key>_lp_max_students</wp:meta_key>
844
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
845
+ </wp:postmeta> <wp:postmeta>
846
+ <wp:meta_key>_lp_students</wp:meta_key>
847
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
848
+ </wp:postmeta> <wp:postmeta>
849
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
850
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
851
+ </wp:postmeta> <wp:postmeta>
852
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
853
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
854
+ </wp:postmeta> <wp:postmeta>
855
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
856
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
857
+ </wp:postmeta> <wp:postmeta>
858
+ <wp:meta_key>_lp_payment</wp:meta_key>
859
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
860
+ </wp:postmeta>
861
+ </item><item>
862
+ <title>asd asda sdasdas da</title>
863
+ <link>http://localhost/foobla/learnpress/1.0/lessons/asd-asda-sdasdas-da/</link>
864
+ <pubDate>Thu, 17 Dec 2015 02:29:12 +0000</pubDate>
865
+ <dc:creator><![CDATA[admin]]></dc:creator>
866
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/asd-asda-sdasdas-da/</guid>
867
+ <description></description>
868
+ <content:encoded><![CDATA[]]></content:encoded>
869
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
870
+ <wp:post_id>1165</wp:post_id>
871
+ <wp:post_date>2015-12-17 02:29:12</wp:post_date>
872
+ <wp:post_date_gmt>2015-12-17 02:29:12</wp:post_date_gmt>
873
+ <wp:comment_status>open</wp:comment_status>
874
+ <wp:ping_status>open</wp:ping_status>
875
+ <wp:post_name>asd-asda-sdasdas-da</wp:post_name>
876
+ <wp:status>publish</wp:status>
877
+ <wp:post_parent>0</wp:post_parent>
878
+ <wp:menu_order>0</wp:menu_order>
879
+ <wp:post_type>lp_lesson</wp:post_type>
880
+ <wp:post_password></wp:post_password>
881
+ <wp:post_author_id>1</wp:post_author_id>
882
+ <wp:is_sticky>0</wp:is_sticky>
883
+
884
+ </item><item>
885
+ <title>asdasdasdasdasda</title>
886
+ <link>http://localhost/foobla/learnpress/1.0/lessons/asdasdasdasdasda/</link>
887
+ <pubDate>Thu, 17 Dec 2015 02:29:12 +0000</pubDate>
888
+ <dc:creator><![CDATA[admin]]></dc:creator>
889
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/asdasdasdasdasda/</guid>
890
+ <description></description>
891
+ <content:encoded><![CDATA[]]></content:encoded>
892
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
893
+ <wp:post_id>1166</wp:post_id>
894
+ <wp:post_date>2015-12-17 02:29:12</wp:post_date>
895
+ <wp:post_date_gmt>2015-12-17 02:29:12</wp:post_date_gmt>
896
+ <wp:comment_status>open</wp:comment_status>
897
+ <wp:ping_status>open</wp:ping_status>
898
+ <wp:post_name>asdasdasdasdasda</wp:post_name>
899
+ <wp:status>publish</wp:status>
900
+ <wp:post_parent>0</wp:post_parent>
901
+ <wp:menu_order>0</wp:menu_order>
902
+ <wp:post_type>lp_lesson</wp:post_type>
903
+ <wp:post_password></wp:post_password>
904
+ <wp:post_author_id>1</wp:post_author_id>
905
+ <wp:is_sticky>0</wp:is_sticky>
906
+
907
+ </item><item>
908
+ <title>assasdasdasdasdasd</title>
909
+ <link>http://localhost/foobla/learnpress/1.0/lessons/assasdasdasdasdasd/</link>
910
+ <pubDate>Thu, 17 Dec 2015 02:29:12 +0000</pubDate>
911
+ <dc:creator><![CDATA[admin]]></dc:creator>
912
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/assasdasdasdasdasd/</guid>
913
+ <description></description>
914
+ <content:encoded><![CDATA[]]></content:encoded>
915
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
916
+ <wp:post_id>1167</wp:post_id>
917
+ <wp:post_date>2015-12-17 02:29:12</wp:post_date>
918
+ <wp:post_date_gmt>2015-12-17 02:29:12</wp:post_date_gmt>
919
+ <wp:comment_status>open</wp:comment_status>
920
+ <wp:ping_status>open</wp:ping_status>
921
+ <wp:post_name>assasdasdasdasdasd</wp:post_name>
922
+ <wp:status>publish</wp:status>
923
+ <wp:post_parent>0</wp:post_parent>
924
+ <wp:menu_order>0</wp:menu_order>
925
+ <wp:post_type>lp_lesson</wp:post_type>
926
+ <wp:post_password></wp:post_password>
927
+ <wp:post_author_id>1</wp:post_author_id>
928
+ <wp:is_sticky>0</wp:is_sticky>
929
+
930
+ </item><item>
931
+ <title>How to create a course</title>
932
+ <link>http://localhost/foobla/learnpress/1.0/lessons/how-to-create-a-course/</link>
933
+ <pubDate>Thu, 17 Dec 2015 03:39:13 +0000</pubDate>
934
+ <dc:creator><![CDATA[admin]]></dc:creator>
935
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/how-to-create-a-course/</guid>
936
+ <description></description>
937
+ <content:encoded><![CDATA[]]></content:encoded>
938
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
939
+ <wp:post_id>1169</wp:post_id>
940
+ <wp:post_date>2015-12-17 03:39:13</wp:post_date>
941
+ <wp:post_date_gmt>2015-12-17 03:39:13</wp:post_date_gmt>
942
+ <wp:comment_status>open</wp:comment_status>
943
+ <wp:ping_status>open</wp:ping_status>
944
+ <wp:post_name>how-to-create-a-course</wp:post_name>
945
+ <wp:status>publish</wp:status>
946
+ <wp:post_parent>0</wp:post_parent>
947
+ <wp:menu_order>0</wp:menu_order>
948
+ <wp:post_type>lp_lesson</wp:post_type>
949
+ <wp:post_password></wp:post_password>
950
+ <wp:post_author_id>1</wp:post_author_id>
951
+ <wp:is_sticky>0</wp:is_sticky>
952
+ <wp:postmeta>
953
+ <wp:meta_key>_lp_duration</wp:meta_key>
954
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
955
+ </wp:postmeta> <wp:postmeta>
956
+ <wp:meta_key>_lp_max_students</wp:meta_key>
957
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
958
+ </wp:postmeta> <wp:postmeta>
959
+ <wp:meta_key>_lp_students</wp:meta_key>
960
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
961
+ </wp:postmeta> <wp:postmeta>
962
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
963
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
964
+ </wp:postmeta> <wp:postmeta>
965
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
966
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
967
+ </wp:postmeta> <wp:postmeta>
968
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
969
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
970
+ </wp:postmeta> <wp:postmeta>
971
+ <wp:meta_key>_lp_payment</wp:meta_key>
972
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
973
+ </wp:postmeta>
974
+ </item><item>
975
+ <title>What is your name</title>
976
+ <link>http://localhost/foobla/learnpress/1.0/lessons/what-is-your-name/</link>
977
+ <pubDate>Thu, 17 Dec 2015 03:39:13 +0000</pubDate>
978
+ <dc:creator><![CDATA[admin]]></dc:creator>
979
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/what-is-your-name/</guid>
980
+ <description></description>
981
+ <content:encoded><![CDATA[]]></content:encoded>
982
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
983
+ <wp:post_id>1170</wp:post_id>
984
+ <wp:post_date>2015-12-17 03:39:13</wp:post_date>
985
+ <wp:post_date_gmt>2015-12-17 03:39:13</wp:post_date_gmt>
986
+ <wp:comment_status>open</wp:comment_status>
987
+ <wp:ping_status>open</wp:ping_status>
988
+ <wp:post_name>what-is-your-name</wp:post_name>
989
+ <wp:status>publish</wp:status>
990
+ <wp:post_parent>0</wp:post_parent>
991
+ <wp:menu_order>0</wp:menu_order>
992
+ <wp:post_type>lp_lesson</wp:post_type>
993
+ <wp:post_password></wp:post_password>
994
+ <wp:post_author_id>1</wp:post_author_id>
995
+ <wp:is_sticky>0</wp:is_sticky>
996
+
997
+ </item><item>
998
+ <title>My name is Tu Nguyen</title>
999
+ <link>http://localhost/foobla/learnpress/1.0/lessons/my-name-is-tu-nguyen/</link>
1000
+ <pubDate>Thu, 17 Dec 2015 03:39:13 +0000</pubDate>
1001
+ <dc:creator><![CDATA[admin]]></dc:creator>
1002
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/my-name-is-tu-nguyen/</guid>
1003
+ <description></description>
1004
+ <content:encoded><![CDATA[]]></content:encoded>
1005
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1006
+ <wp:post_id>1171</wp:post_id>
1007
+ <wp:post_date>2015-12-17 03:39:13</wp:post_date>
1008
+ <wp:post_date_gmt>2015-12-17 03:39:13</wp:post_date_gmt>
1009
+ <wp:comment_status>open</wp:comment_status>
1010
+ <wp:ping_status>open</wp:ping_status>
1011
+ <wp:post_name>my-name-is-tu-nguyen</wp:post_name>
1012
+ <wp:status>publish</wp:status>
1013
+ <wp:post_parent>0</wp:post_parent>
1014
+ <wp:menu_order>0</wp:menu_order>
1015
+ <wp:post_type>lp_lesson</wp:post_type>
1016
+ <wp:post_password></wp:post_password>
1017
+ <wp:post_author_id>1</wp:post_author_id>
1018
+ <wp:is_sticky>0</wp:is_sticky>
1019
+
1020
+ </item><item>
1021
+ <title>sdfsdfsdf sdf sdf sdf s</title>
1022
+ <link>http://localhost/foobla/learnpress/1.0/quizzes/sdfsdfsdf-sdf-sdf-sdf-s/</link>
1023
+ <pubDate>Thu, 17 Dec 2015 03:39:07 +0000</pubDate>
1024
+ <dc:creator><![CDATA[admin]]></dc:creator>
1025
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/quizzes/sdfsdfsdf-sdf-sdf-sdf-s/</guid>
1026
+ <description></description>
1027
+ <content:encoded><![CDATA[]]></content:encoded>
1028
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1029
+ <wp:post_id>1168</wp:post_id>
1030
+ <wp:post_date>2015-12-17 03:39:07</wp:post_date>
1031
+ <wp:post_date_gmt>2015-12-17 03:39:07</wp:post_date_gmt>
1032
+ <wp:comment_status>open</wp:comment_status>
1033
+ <wp:ping_status>open</wp:ping_status>
1034
+ <wp:post_name>sdfsdfsdf-sdf-sdf-sdf-s</wp:post_name>
1035
+ <wp:status>publish</wp:status>
1036
+ <wp:post_parent>0</wp:post_parent>
1037
+ <wp:menu_order>0</wp:menu_order>
1038
+ <wp:post_type>lp_quiz</wp:post_type>
1039
+ <wp:post_password></wp:post_password>
1040
+ <wp:post_author_id>1</wp:post_author_id>
1041
+ <wp:is_sticky>0</wp:is_sticky>
1042
+ <wp:postmeta>
1043
+ <wp:meta_key>_lp_duration</wp:meta_key>
1044
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1045
+ </wp:postmeta> <wp:postmeta>
1046
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1047
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1048
+ </wp:postmeta>
1049
+ </item><item>
1050
+ <title>sdfsd fsd fsdf</title>
1051
+ <link>http://localhost/foobla/learnpress/1.0/quizzes/sdfsd-fsd-fsdf/</link>
1052
+ <pubDate>Thu, 17 Dec 2015 03:44:14 +0000</pubDate>
1053
+ <dc:creator><![CDATA[admin]]></dc:creator>
1054
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/quizzes/sdfsd-fsd-fsdf/</guid>
1055
+ <description></description>
1056
+ <content:encoded><![CDATA[]]></content:encoded>
1057
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1058
+ <wp:post_id>1172</wp:post_id>
1059
+ <wp:post_date>2015-12-17 03:44:14</wp:post_date>
1060
+ <wp:post_date_gmt>2015-12-17 03:44:14</wp:post_date_gmt>
1061
+ <wp:comment_status>open</wp:comment_status>
1062
+ <wp:ping_status>open</wp:ping_status>
1063
+ <wp:post_name>sdfsd-fsd-fsdf</wp:post_name>
1064
+ <wp:status>publish</wp:status>
1065
+ <wp:post_parent>0</wp:post_parent>
1066
+ <wp:menu_order>0</wp:menu_order>
1067
+ <wp:post_type>lp_quiz</wp:post_type>
1068
+ <wp:post_password></wp:post_password>
1069
+ <wp:post_author_id>1</wp:post_author_id>
1070
+ <wp:is_sticky>0</wp:is_sticky>
1071
+ <wp:postmeta>
1072
+ <wp:meta_key>_lp_duration</wp:meta_key>
1073
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1074
+ </wp:postmeta> <wp:postmeta>
1075
+ <wp:meta_key>_lp_max_students</wp:meta_key>
1076
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
1077
+ </wp:postmeta> <wp:postmeta>
1078
+ <wp:meta_key>_lp_students</wp:meta_key>
1079
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1080
+ </wp:postmeta> <wp:postmeta>
1081
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
1082
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1083
+ </wp:postmeta> <wp:postmeta>
1084
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
1085
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
1086
+ </wp:postmeta> <wp:postmeta>
1087
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
1088
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
1089
+ </wp:postmeta> <wp:postmeta>
1090
+ <wp:meta_key>_lp_payment</wp:meta_key>
1091
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
1092
+ </wp:postmeta>
1093
+ </item><item>
1094
+ <title>sdf sdfsd fsdf sdfsd f</title>
1095
+ <link>http://localhost/foobla/learnpress/1.0/quizzes/sdf-sdfsd-fsdf-sdfsd-f/</link>
1096
+ <pubDate>Thu, 17 Dec 2015 03:44:14 +0000</pubDate>
1097
+ <dc:creator><![CDATA[admin]]></dc:creator>
1098
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/quizzes/sdf-sdfsd-fsdf-sdfsd-f/</guid>
1099
+ <description></description>
1100
+ <content:encoded><![CDATA[]]></content:encoded>
1101
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1102
+ <wp:post_id>1173</wp:post_id>
1103
+ <wp:post_date>2015-12-17 03:44:14</wp:post_date>
1104
+ <wp:post_date_gmt>2015-12-17 03:44:14</wp:post_date_gmt>
1105
+ <wp:comment_status>open</wp:comment_status>
1106
+ <wp:ping_status>open</wp:ping_status>
1107
+ <wp:post_name>sdf-sdfsd-fsdf-sdfsd-f</wp:post_name>
1108
+ <wp:status>publish</wp:status>
1109
+ <wp:post_parent>0</wp:post_parent>
1110
+ <wp:menu_order>0</wp:menu_order>
1111
+ <wp:post_type>lp_quiz</wp:post_type>
1112
+ <wp:post_password></wp:post_password>
1113
+ <wp:post_author_id>1</wp:post_author_id>
1114
+ <wp:is_sticky>0</wp:is_sticky>
1115
+
1116
+ </item><item>
1117
+ <title>happy new year!</title>
1118
+ <link>http://localhost/foobla/learnpress/1.0/lessons/happy-new-year/</link>
1119
+ <pubDate>Tue, 29 Dec 2015 09:25:33 +0000</pubDate>
1120
+ <dc:creator><![CDATA[admin]]></dc:creator>
1121
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/happy-new-year/</guid>
1122
+ <description></description>
1123
+ <content:encoded><![CDATA[]]></content:encoded>
1124
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1125
+ <wp:post_id>1228</wp:post_id>
1126
+ <wp:post_date>2015-12-29 09:25:33</wp:post_date>
1127
+ <wp:post_date_gmt>2015-12-29 09:25:33</wp:post_date_gmt>
1128
+ <wp:comment_status>closed</wp:comment_status>
1129
+ <wp:ping_status>closed</wp:ping_status>
1130
+ <wp:post_name>happy-new-year</wp:post_name>
1131
+ <wp:status>publish</wp:status>
1132
+ <wp:post_parent>0</wp:post_parent>
1133
+ <wp:menu_order>0</wp:menu_order>
1134
+ <wp:post_type>lp_lesson</wp:post_type>
1135
+ <wp:post_password></wp:post_password>
1136
+ <wp:post_author_id>1</wp:post_author_id>
1137
+ <wp:is_sticky>0</wp:is_sticky>
1138
+ <wp:postmeta>
1139
+ <wp:meta_key>_lp_duration</wp:meta_key>
1140
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1141
+ </wp:postmeta> <wp:postmeta>
1142
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1143
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1144
+ </wp:postmeta>
1145
+ </item><item>
1146
+ <title>happy new year!</title>
1147
+ <link>http://localhost/foobla/learnpress/1.0/lessons/happy-new-year-2/</link>
1148
+ <pubDate>Tue, 29 Dec 2015 09:25:34 +0000</pubDate>
1149
+ <dc:creator><![CDATA[admin]]></dc:creator>
1150
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/happy-new-year-2/</guid>
1151
+ <description></description>
1152
+ <content:encoded><![CDATA[]]></content:encoded>
1153
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1154
+ <wp:post_id>1229</wp:post_id>
1155
+ <wp:post_date>2015-12-29 09:25:34</wp:post_date>
1156
+ <wp:post_date_gmt>2015-12-29 09:25:34</wp:post_date_gmt>
1157
+ <wp:comment_status>closed</wp:comment_status>
1158
+ <wp:ping_status>closed</wp:ping_status>
1159
+ <wp:post_name>happy-new-year-2</wp:post_name>
1160
+ <wp:status>publish</wp:status>
1161
+ <wp:post_parent>0</wp:post_parent>
1162
+ <wp:menu_order>0</wp:menu_order>
1163
+ <wp:post_type>lp_lesson</wp:post_type>
1164
+ <wp:post_password></wp:post_password>
1165
+ <wp:post_author_id>1</wp:post_author_id>
1166
+ <wp:is_sticky>0</wp:is_sticky>
1167
+ <wp:postmeta>
1168
+ <wp:meta_key>_lp_duration</wp:meta_key>
1169
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1170
+ </wp:postmeta> <wp:postmeta>
1171
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1172
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1173
+ </wp:postmeta>
1174
+ </item><item>
1175
+ <title>Lesson 1</title>
1176
+ <link>http://localhost/foobla/learnpress/1.0/lessons/lesson-1/</link>
1177
+ <pubDate>Fri, 04 Dec 2015 08:17:04 +0000</pubDate>
1178
+ <dc:creator><![CDATA[admin]]></dc:creator>
1179
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/lesson-1/</guid>
1180
+ <description></description>
1181
+ <content:encoded><![CDATA[]]></content:encoded>
1182
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1183
+ <wp:post_id>1136</wp:post_id>
1184
+ <wp:post_date>2015-12-04 08:17:04</wp:post_date>
1185
+ <wp:post_date_gmt>2015-12-04 08:17:04</wp:post_date_gmt>
1186
+ <wp:comment_status>open</wp:comment_status>
1187
+ <wp:ping_status>open</wp:ping_status>
1188
+ <wp:post_name>lesson-1</wp:post_name>
1189
+ <wp:status>publish</wp:status>
1190
+ <wp:post_parent>0</wp:post_parent>
1191
+ <wp:menu_order>0</wp:menu_order>
1192
+ <wp:post_type>lp_lesson</wp:post_type>
1193
+ <wp:post_password></wp:post_password>
1194
+ <wp:post_author_id>1</wp:post_author_id>
1195
+ <wp:is_sticky>0</wp:is_sticky>
1196
+ <wp:postmeta>
1197
+ <wp:meta_key>_lpr_course</wp:meta_key>
1198
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1199
+ </wp:postmeta> <wp:postmeta>
1200
+ <wp:meta_key>_lp_duration</wp:meta_key>
1201
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1202
+ </wp:postmeta> <wp:postmeta>
1203
+ <wp:meta_key>_lp_max_students</wp:meta_key>
1204
+ <wp:meta_value><![CDATA[1000]]></wp:meta_value>
1205
+ </wp:postmeta> <wp:postmeta>
1206
+ <wp:meta_key>_lp_students</wp:meta_key>
1207
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1208
+ </wp:postmeta> <wp:postmeta>
1209
+ <wp:meta_key>_lp_retake_count</wp:meta_key>
1210
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1211
+ </wp:postmeta> <wp:postmeta>
1212
+ <wp:meta_key>_lp_passing_condition</wp:meta_key>
1213
+ <wp:meta_value><![CDATA[50]]></wp:meta_value>
1214
+ </wp:postmeta> <wp:postmeta>
1215
+ <wp:meta_key>_lp_enroll_requirement</wp:meta_key>
1216
+ <wp:meta_value><![CDATA[yes]]></wp:meta_value>
1217
+ </wp:postmeta> <wp:postmeta>
1218
+ <wp:meta_key>_lp_payment</wp:meta_key>
1219
+ <wp:meta_value><![CDATA[free]]></wp:meta_value>
1220
+ </wp:postmeta> <wp:postmeta>
1221
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1222
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1223
+ </wp:postmeta> <wp:postmeta>
1224
+ <wp:meta_key>_edit_lock</wp:meta_key>
1225
+ <wp:meta_value><![CDATA[1451567890:1]]></wp:meta_value>
1226
+ </wp:postmeta>
1227
+ </item><item>
1228
+ <title>Lesson 2</title>
1229
+ <link>http://localhost/foobla/learnpress/1.0/lessons/lesson-2/</link>
1230
+ <pubDate>Fri, 04 Dec 2015 08:17:04 +0000</pubDate>
1231
+ <dc:creator><![CDATA[admin]]></dc:creator>
1232
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/lesson-2/</guid>
1233
+ <description></description>
1234
+ <content:encoded><![CDATA[]]></content:encoded>
1235
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1236
+ <wp:post_id>1137</wp:post_id>
1237
+ <wp:post_date>2015-12-04 08:17:04</wp:post_date>
1238
+ <wp:post_date_gmt>2015-12-04 08:17:04</wp:post_date_gmt>
1239
+ <wp:comment_status>open</wp:comment_status>
1240
+ <wp:ping_status>open</wp:ping_status>
1241
+ <wp:post_name>lesson-2</wp:post_name>
1242
+ <wp:status>publish</wp:status>
1243
+ <wp:post_parent>0</wp:post_parent>
1244
+ <wp:menu_order>0</wp:menu_order>
1245
+ <wp:post_type>lp_lesson</wp:post_type>
1246
+ <wp:post_password></wp:post_password>
1247
+ <wp:post_author_id>1</wp:post_author_id>
1248
+ <wp:is_sticky>0</wp:is_sticky>
1249
+ <wp:postmeta>
1250
+ <wp:meta_key>_lpr_course</wp:meta_key>
1251
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1252
+ </wp:postmeta> <wp:postmeta>
1253
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1254
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1255
+ </wp:postmeta>
1256
+ </item><item>
1257
+ <title>oi troi oi la troi</title>
1258
+ <link>http://localhost/foobla/learnpress/1.0/lessons/oi-troi-oi-la-troi/</link>
1259
+ <pubDate>Tue, 29 Dec 2015 09:29:54 +0000</pubDate>
1260
+ <dc:creator><![CDATA[admin]]></dc:creator>
1261
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/oi-troi-oi-la-troi/</guid>
1262
+ <description></description>
1263
+ <content:encoded><![CDATA[]]></content:encoded>
1264
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1265
+ <wp:post_id>1230</wp:post_id>
1266
+ <wp:post_date>2015-12-29 09:29:54</wp:post_date>
1267
+ <wp:post_date_gmt>2015-12-29 09:29:54</wp:post_date_gmt>
1268
+ <wp:comment_status>closed</wp:comment_status>
1269
+ <wp:ping_status>closed</wp:ping_status>
1270
+ <wp:post_name>oi-troi-oi-la-troi</wp:post_name>
1271
+ <wp:status>publish</wp:status>
1272
+ <wp:post_parent>0</wp:post_parent>
1273
+ <wp:menu_order>0</wp:menu_order>
1274
+ <wp:post_type>lp_lesson</wp:post_type>
1275
+ <wp:post_password></wp:post_password>
1276
+ <wp:post_author_id>1</wp:post_author_id>
1277
+ <wp:is_sticky>0</wp:is_sticky>
1278
+ <wp:postmeta>
1279
+ <wp:meta_key>_lp_duration</wp:meta_key>
1280
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1281
+ </wp:postmeta> <wp:postmeta>
1282
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1283
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1284
+ </wp:postmeta>
1285
+ </item><item>
1286
+ <title>333333333333</title>
1287
+ <link>http://localhost/foobla/learnpress/1.0/lessons/333333333333-2/</link>
1288
+ <pubDate>Tue, 08 Dec 2015 04:18:47 +0000</pubDate>
1289
+ <dc:creator><![CDATA[admin]]></dc:creator>
1290
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/333333333333-2/</guid>
1291
+ <description></description>
1292
+ <content:encoded><![CDATA[]]></content:encoded>
1293
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1294
+ <wp:post_id>1145</wp:post_id>
1295
+ <wp:post_date>2015-12-08 04:18:47</wp:post_date>
1296
+ <wp:post_date_gmt>2015-12-08 04:18:47</wp:post_date_gmt>
1297
+ <wp:comment_status>open</wp:comment_status>
1298
+ <wp:ping_status>open</wp:ping_status>
1299
+ <wp:post_name>333333333333-2</wp:post_name>
1300
+ <wp:status>publish</wp:status>
1301
+ <wp:post_parent>0</wp:post_parent>
1302
+ <wp:menu_order>0</wp:menu_order>
1303
+ <wp:post_type>lp_lesson</wp:post_type>
1304
+ <wp:post_password></wp:post_password>
1305
+ <wp:post_author_id>1</wp:post_author_id>
1306
+ <wp:is_sticky>0</wp:is_sticky>
1307
+ <wp:postmeta>
1308
+ <wp:meta_key>_lpr_course</wp:meta_key>
1309
+ <wp:meta_value><![CDATA[0]]></wp:meta_value>
1310
+ </wp:postmeta> <wp:postmeta>
1311
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1312
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1313
+ </wp:postmeta>
1314
+ </item><item>
1315
+ <title>44444444</title>
1316
+ <link>http://localhost/foobla/learnpress/1.0/lessons/44444444-2/</link>
1317
+ <pubDate>Tue, 29 Dec 2015 09:02:22 +0000</pubDate>
1318
+ <dc:creator><![CDATA[admin]]></dc:creator>
1319
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/44444444-2/</guid>
1320
+ <description></description>
1321
+ <content:encoded><![CDATA[]]></content:encoded>
1322
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1323
+ <wp:post_id>1227</wp:post_id>
1324
+ <wp:post_date>2015-12-29 09:02:22</wp:post_date>
1325
+ <wp:post_date_gmt>2015-12-29 09:02:22</wp:post_date_gmt>
1326
+ <wp:comment_status>closed</wp:comment_status>
1327
+ <wp:ping_status>closed</wp:ping_status>
1328
+ <wp:post_name>44444444-2</wp:post_name>
1329
+ <wp:status>publish</wp:status>
1330
+ <wp:post_parent>0</wp:post_parent>
1331
+ <wp:menu_order>0</wp:menu_order>
1332
+ <wp:post_type>lp_lesson</wp:post_type>
1333
+ <wp:post_password></wp:post_password>
1334
+ <wp:post_author_id>1</wp:post_author_id>
1335
+ <wp:is_sticky>0</wp:is_sticky>
1336
+ <wp:postmeta>
1337
+ <wp:meta_key>_lp_duration</wp:meta_key>
1338
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1339
+ </wp:postmeta> <wp:postmeta>
1340
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1341
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1342
+ </wp:postmeta>
1343
+ </item><item>
1344
+ <title>cookie</title>
1345
+ <link>http://localhost/foobla/learnpress/1.0/lessons/cookie/</link>
1346
+ <pubDate>Tue, 29 Dec 2015 09:33:07 +0000</pubDate>
1347
+ <dc:creator><![CDATA[admin]]></dc:creator>
1348
+ <guid isPermaLink="false">http://localhost/foobla/learnpress/1.0/lessons/cookie/</guid>
1349
+ <description></description>
1350
+ <content:encoded><![CDATA[]]></content:encoded>
1351
+ <excerpt:encoded><![CDATA[]]></excerpt:encoded>
1352
+ <wp:post_id>1231</wp:post_id>
1353
+ <wp:post_date>2015-12-29 09:33:07</wp:post_date>
1354
+ <wp:post_date_gmt>2015-12-29 09:33:07</wp:post_date_gmt>
1355
+ <wp:comment_status>closed</wp:comment_status>
1356
+ <wp:ping_status>closed</wp:ping_status>
1357
+ <wp:post_name>cookie</wp:post_name>
1358
+ <wp:status>publish</wp:status>
1359
+ <wp:post_parent>0</wp:post_parent>
1360
+ <wp:menu_order>0</wp:menu_order>
1361
+ <wp:post_type>lp_lesson</wp:post_type>
1362
+ <wp:post_password></wp:post_password>
1363
+ <wp:post_author_id>1</wp:post_author_id>
1364
+ <wp:is_sticky>0</wp:is_sticky>
1365
+ <wp:postmeta>
1366
+ <wp:meta_key>_lp_duration</wp:meta_key>
1367
+ <wp:meta_value><![CDATA[10]]></wp:meta_value>
1368
+ </wp:postmeta> <wp:postmeta>
1369
+ <wp:meta_key>_lp_is_previewable</wp:meta_key>
1370
+ <wp:meta_value><![CDATA[no]]></wp:meta_value>
1371
+ </wp:postmeta>
1372
+ </item> </channel>
1373
+ </rss>
inc/abstracts/abstract-lp-assets.php ADDED
@@ -0,0 +1,262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Abstract_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
+ abstract class LP_Abstract_Assets {
16
+
17
+ /**
18
+ * Styles
19
+ *
20
+ * @var array
21
+ */
22
+ protected static $styles = array();
23
+
24
+ /**
25
+ * Scripts
26
+ *
27
+ * @var array
28
+ */
29
+ protected static $scripts = array();
30
+
31
+ /**
32
+ * Localize scripts
33
+ *
34
+ * @var array
35
+ */
36
+ protected static $wp_localize_scripts = array();
37
+
38
+ /**
39
+ * Params
40
+ *
41
+ * @var array
42
+ */
43
+ protected static $wp_params = array();
44
+
45
+ protected static $wp_script_codes = array();
46
+
47
+ /**
48
+ * Localized flag
49
+ *
50
+ * @var bool
51
+ */
52
+ protected static $localized = false;
53
+
54
+ /**
55
+ * @var int
56
+ */
57
+ protected static $id = 0;
58
+
59
+ protected static $caller = '';
60
+
61
+ /**
62
+ * Constructor
63
+ */
64
+ function __construct() {
65
+
66
+ }
67
+
68
+ /**
69
+ * Init Asset
70
+ */
71
+ static function init() {
72
+ if ( !self::$caller ) {
73
+ return;
74
+ }
75
+ self::$id = is_admin() ? 0 : 1;
76
+
77
+ $class = self::$caller;
78
+ if ( self::$id ) {
79
+ add_action( 'wp_enqueue_scripts', array( $class, 'load_scripts' ) );
80
+ add_action( 'wp_enqueue_scripts', array( $class, 'wp_assets' ) );
81
+ add_action( 'wp_print_scripts', array( $class, 'localize_printed_scripts' ), 5 );
82
+ add_action( 'wp_print_footer_scripts', array( $class, 'localize_printed_scripts' ), 5 );
83
+ } else {
84
+ add_action( 'admin_enqueue_scripts', array( $class, 'load_scripts' ) );
85
+ add_action( 'admin_enqueue_scripts', array( $class, 'wp_assets' ) );
86
+ add_action( 'admin_print_scripts', array( $class, 'localize_printed_scripts' ), 5 );
87
+ add_action( 'admin_print_footer_scripts', array( $class, 'localize_printed_scripts' ), 5 );
88
+ }
89
+
90
+ add_filter( 'script_loader_src', array( $class, 'script_params' ), 999, 2 );
91
+ }
92
+
93
+ /**
94
+ * register script
95
+ *
96
+ * @param string $handle
97
+ * @param string $src
98
+ * @param array $deps
99
+ * @param string $version
100
+ * @param boolean $in_footer
101
+ */
102
+ static function add_script( $handle, $src, $deps = array( 'jquery' ), $version = LEARNPRESS_VERSION, $in_footer = true ) {
103
+ self::$scripts[] = $handle;
104
+ wp_register_script( $handle, $src, $deps, $version, $in_footer );
105
+ }
106
+
107
+ /**
108
+ * register style
109
+ *
110
+ * @param string $handle
111
+ * @param string $src
112
+ * @param array $deps
113
+ * @param string $version
114
+ * @param string $media
115
+ */
116
+ static function add_style( $handle, $src, $deps = array(), $version = LEARNPRESS_VERSION, $media = 'all' ) {
117
+ self::$styles[] = $handle;
118
+ wp_register_style( $handle, $src, $deps, $version, $media );
119
+ }
120
+
121
+ /**
122
+ * enqueue script
123
+ *
124
+ * @param string $handle
125
+ * @param string $src
126
+ * @param array $deps
127
+ * @param string $version
128
+ * @param boolean $in_footer
129
+ */
130
+ static function enqueue_script( $handle, $src = '', $deps = array( 'jquery' ), $version = LEARNPRESS_VERSION, $in_footer = true ) {
131
+ if ( !in_array( $handle, self::$scripts ) && $src ) {
132
+ self::add_script( $handle, $src, $deps, $version, $in_footer );
133
+ }
134
+ wp_enqueue_script( $handle );
135
+ }
136
+
137
+ /**
138
+ * enqueue style
139
+ *
140
+ * @param string $handle
141
+ * @param string $src
142
+ * @param array $deps
143
+ * @param string $version
144
+ * @param string $media
145
+ */
146
+ static function enqueue_style( $handle, $src = '', $deps = array(), $version = LEARNPRESS_VERSION, $media = 'all' ) {
147
+ if ( !in_array( $handle, self::$styles ) && $src ) {
148
+ self::add_style( $handle, $src, $deps, $version, $media );
149
+ }
150
+ wp_enqueue_style( $handle );
151
+ }
152
+
153
+ /**
154
+ * add translate text
155
+ *
156
+ * @param string
157
+ * @param array $localize
158
+ * @param string
159
+ */
160
+ static function add_localize( $key, $localize = null, $handle = 'learn-press-js' ) {
161
+ if ( is_array( $key ) ) {
162
+ foreach ( $key as $k => $v ) {
163
+ self::add_localize( $k, $v, $handle );
164
+ }
165
+ } elseif ( is_string( $key ) && strlen( $key ) ) {
166
+ if ( !$handle ) $handle = 'learn-press-js';
167
+ if ( empty( self::$wp_localize_scripts[$handle] ) ) self::$wp_localize_scripts[$handle] = array();
168
+ self::$wp_localize_scripts[$handle][$key] = $localize;
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Add js param
174
+ *
175
+ * @param string
176
+ * @param array
177
+ * @param string
178
+ */
179
+ static function add_param( $key, $param = null, $handle = 'learn-press-js' ) {
180
+ if ( is_array( $key ) ) {
181
+ foreach ( $key as $k => $v ) {
182
+ self::add_param( $k, $v, $handle );
183
+ }
184
+ } elseif ( is_string( $key ) && strlen( $key ) ) {
185
+ if ( !$handle ) $handle = 'learn-press-js';
186
+ if ( empty( self::$wp_params[$handle] ) ) self::$wp_params[$handle] = array();
187
+ self::$wp_params[$handle][$key] = $param;
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Localize script
193
+ *
194
+ * @param mixed $handle
195
+ */
196
+ private static function localize_script( $handle ) {
197
+ $data = !empty( self::$wp_localize_scripts[$handle] ) ? self::$wp_localize_scripts[$handle] : false;
198
+ if ( wp_script_is( $handle ) && $data ) {
199
+ $name = str_replace( '-', '_', $handle ) . '_localize';
200
+ unset( self::$wp_localize_scripts[$handle] );
201
+ wp_localize_script( $handle, $name, apply_filters( $name, $data ) );
202
+ }
203
+ }
204
+
205
+ /**
206
+ * Print script params
207
+ *
208
+ * @param mixed $handle
209
+ */
210
+ private static function script_paramsx( $handle ) {
211
+ $data = !empty( self::$wp_params[$handle] ) ? self::$wp_params[$handle] : false;
212
+ if ( wp_script_is( $handle ) && $data ) {
213
+ $name = str_replace( '-', '_', $handle ) . '_params';
214
+ unset( self::$wp_params[$handle] );
215
+ //$data = learn_press_sanitize_json( $data );
216
+ //wp_localize_script( $handle, $name, apply_filters( $name, $data ) );
217
+ }
218
+ }
219
+
220
+ static function add_script_tag( $code, $handle = '' ) {
221
+ if ( empty( self::$wp_script_codes[$handle] ) ) {
222
+ self::$wp_script_codes[$handle] = '';
223
+ }
224
+ self::$wp_script_codes[$handle] .= preg_replace( '!</?script(.*)>!', '', $code );
225
+ }
226
+
227
+ static function wp_assets() {
228
+ do_action( 'learn_press_print_assets', is_admin() );
229
+ }
230
+
231
+ static function script_params( $src, $handle ) {
232
+ $data = !empty( self::$wp_params[$handle] ) ? self::$wp_params[$handle] : false;
233
+ if ( wp_script_is( $handle ) && $data ) {
234
+ $name = str_replace( '-', '_', $handle ) . '_params';
235
+ echo "<script type='text/javascript'>\n"; // CDATA and type='text/javascript' is not needed for HTML 5
236
+ echo "/* <![CDATA[ */\n";
237
+ echo "var {$name}=" . wp_json_encode( $data ) . "\n";
238
+ echo "/* ]]> */\n";
239
+ echo "</script>\n";
240
+ unset( self::$wp_params[$handle] );
241
+ }
242
+ return $src;
243
+ }
244
+
245
+ /**
246
+ * Load Script
247
+ */
248
+ static function load_scripts() {
249
+ }
250
+
251
+ static function localize_printed_scripts() {
252
+ if ( self::$scripts ) foreach ( self::$scripts as $handle ) {
253
+ self::localize_script( $handle );
254
+ //self::script_params( $handle );
255
+ if ( !empty( self::$wp_script_codes[$handle] ) ) {
256
+ learn_press_get_template( 'global/scripts.php', array( 'code' => self::$wp_script_codes[$handle] ) );
257
+ unset( self::$wp_script_codes[$handle] );
258
+ }
259
+ }
260
+
261
+ }
262
+ }
inc/admin/class-lp-admin-ajax.php ADDED
@@ -0,0 +1,947 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ /////////////
40
+ 'quick_add_lesson' => false,
41
+ 'quick_add_quiz' => false,
42
+ 'be_teacher' => false,
43
+ 'custom_stats' => false,
44
+ 'ignore_setting_up' => false,
45
+ 'get_page_permalink' => false,
46
+ 'dummy_image' => false,
47
+ 'update_add_on_status' => false,
48
+ 'plugin_install' => false,
49
+ 'bundle_activate_add_ons' => false,
50
+ 'install_sample_data' => false
51
+ );
52
+ foreach ( $ajaxEvents as $ajaxEvent => $nopriv ) {
53
+ add_action( 'wp_ajax_learnpress_' . $ajaxEvent, array( __CLASS__, $ajaxEvent ) );
54
+ // enable for non-logged in users
55
+ if ( $nopriv ) {
56
+ add_action( 'wp_ajax_nopriv_learnpress_' . $ajaxEvent, array( __CLASS__, $ajaxEvent ) );
57
+ }
58
+ }
59
+ add_filter( 'learn_press_modal_search_items_exclude', array( __CLASS__, '_modal_search_items_exclude' ), 10, 4 );
60
+ add_filter( 'learn_press_modal_search_items_not_found', array( __CLASS__, '_modal_search_items_not_found' ), 10, 2 );
61
+ do_action( 'learn_press_admin_ajax_load', __CLASS__ );
62
+ }
63
+
64
+ static function load_chart(){
65
+ if( !class_exists( '' ) ){
66
+ require_once LP_PLUGIN_PATH . '/inc/admin/sub-menus/statistics.php';
67
+ }
68
+ LP_Admin_Submenu_Statistic::instance()->load_chart();
69
+ }
70
+
71
+ static function remove_course_items() {
72
+ die( 'Please implement this function' );
73
+ }
74
+
75
+ static function search_users() {
76
+ if ( !current_user_can( 'edit_lp_orders' ) ) {
77
+ die( - 1 );
78
+ }
79
+
80
+ $term = stripslashes( $_GET['term'] );
81
+
82
+ if ( empty( $term ) ) {
83
+ die();
84
+ }
85
+
86
+ $found_customers = array();
87
+
88
+ add_action( 'pre_user_query', array( __CLASS__, 'json_search_customer_name' ) );
89
+
90
+ $customers_query = new WP_User_Query( apply_filters( 'learn_press_search_customers_query', array(
91
+ 'fields' => 'all',
92
+ 'orderby' => 'display_name',
93
+ 'search' => '*' . $term . '*',
94
+ 'search_columns' => array( 'ID', 'user_login', 'user_email', 'user_nicename' )
95
+ ) ) );
96
+
97
+ remove_action( 'pre_user_query', array( __CLASS__, 'json_search_customer_name' ) );
98
+
99
+ $customers = $customers_query->get_results();
100
+
101
+ if ( !empty( $customers ) ) {
102
+ foreach ( $customers as $customer ) {
103
+ $found_customers[] = array(
104
+ 'label' => $customer->display_name . ' (#' . $customer->ID . ' &ndash; ' . sanitize_email( $customer->user_email ) . ')',
105
+ 'value' => $customer->ID
106
+ );
107
+ }
108
+ }
109
+
110
+ echo json_encode( $found_customers );
111
+ die();
112
+ }
113
+
114
+ public static function json_search_customer_name( $query ) {
115
+ global $wpdb;
116
+
117
+ $term = wc_clean( stripslashes( $_GET['term'] ) );
118
+ if ( method_exists( $wpdb, 'esc_like' ) ) {
119
+ $term = $wpdb->esc_like( $term );
120
+ } else {
121
+ $term = like_escape( $term );
122
+ }
123
+
124
+ $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' ) ";
125
+ $query->query_where .= $wpdb->prepare( " OR user_name.meta_value LIKE %s ", '%' . $term . '%' );
126
+ }
127
+
128
+ static function dismiss_notice() {
129
+ $context = learn_press_get_request( 'context' );
130
+ $transient = learn_press_get_request( 'transient' );
131
+
132
+ if ( $context ) {
133
+ if ( $transient >= 0 ) {
134
+ set_transient( 'learn_press_dismiss_notice_' . $context, 'off', $transient ? $transient : DAY_IN_SECONDS * 7 );
135
+ } else {
136
+ update_option( 'learn_press_dismiss_notice_' . $context, 'off' );
137
+ }
138
+ }
139
+ die();
140
+ }
141
+
142
+ static function _modal_search_items_not_found( $message, $type ) {
143
+ switch ( $type ) {
144
+ case 'lp_lesson':
145
+ $message = __( 'No lessons found', 'learnpress' );
146
+ break;
147
+ case 'lp_quiz':
148
+ $message = __( 'No quizzes found', 'learnpress' );
149
+ break;
150
+ case 'lp_question':
151
+ $message = __( 'No questions found', 'learnpress' );
152
+ break;
153
+ }
154
+ return $message;
155
+ }
156
+
157
+ static function _modal_search_items_exclude( $exclude, $type, $context = '', $context_id = null ) {
158
+ global $wpdb;
159
+ $exclude2 = array();
160
+ $user = learn_press_get_current_user();
161
+ switch ( $type ) {
162
+ case 'lp_lesson':
163
+ case 'lp_quiz':
164
+ $query = $wpdb->prepare( "
165
+ SELECT item_id
166
+ FROM {$wpdb->prefix}learnpress_section_items
167
+ WHERE %d
168
+ ", 1 );
169
+ $exclude2 = $wpdb->get_col( $query );
170
+ if ( ( $context == 'course' ) && ( get_post_type( $context_id ) == 'lp_course' ) ) {
171
+ $course_author = get_post_field( 'post_author', $context_id );
172
+
173
+ }
174
+ break;
175
+ case 'lp_question':
176
+
177
+ }
178
+ if ( $exclude2 && $exclude ) {
179
+ $exclude = array_merge( $exclude, $exclude2 );
180
+ } else if ( $exclude2 ) {
181
+ $exclude = $exclude2;
182
+ }
183
+ return $exclude;
184
+ }
185
+
186
+ static function add_item_to_section() {
187
+ global $wpdb;
188
+ $section = learn_press_get_request( 'section' );
189
+ if ( !$section ) {
190
+ wp_die( __( 'Error', 'learnpress' ) );
191
+ }
192
+ $items = (array) learn_press_get_request( 'item' );
193
+ if ( !$items ) {
194
+ $max_order = $wpdb->get_var( $wpdb->prepare( "SELECT max() FROM {$wpdb}learnpress_section_items WHERE section_id = %d", $section ) );
195
+ foreach ( $items as $item ) {
196
+
197
+ }
198
+ }
199
+ }
200
+
201
+ static function modal_search_items() {
202
+ global $wpdb;
203
+
204
+ $user = learn_press_get_current_user();
205
+ $term = (string) ( stripslashes( learn_press_get_request( 'term' ) ) );
206
+ $type = (string) ( stripslashes( learn_press_get_request( 'type' ) ) );
207
+ $context = (string) ( stripslashes( learn_press_get_request( 'context' ) ) );
208
+ $context_id = (string) ( stripslashes( learn_press_get_request( 'context_id' ) ) );
209
+ $exclude = array();
210
+
211
+ if ( !empty( $_GET['exclude'] ) ) {
212
+ $exclude = array_map( 'intval', $_GET['exclude'] );
213
+ }
214
+ $exclude = array_unique( (array) apply_filters( 'learn_press_modal_search_items_exclude', $exclude, $type, $context, $context_id ) );
215
+ $exclude = array_map( 'intval', $exclude );
216
+ $args = array(
217
+ 'post_type' => array( $type ),
218
+ 'posts_per_page' => - 1,
219
+ 'post_status' => 'publish',
220
+ 'order' => 'ASC',
221
+ 'orderby' => 'parent title',
222
+ 'exclude' => $exclude
223
+ );
224
+ if ( !$user->is_admin() ) {
225
+ $args['author'] = $user->id;
226
+ }
227
+
228
+ if ( $context && $context_id ) {
229
+ switch ( $context ) {
230
+ /**
231
+ * If is search lesson/quiz for course only search the items of course's author
232
+ */
233
+ case 'course-items':
234
+ if ( get_post_type( $context_id ) == 'lp_course' ) {
235
+ $args['author'] = get_post_field( 'post_author', $context_id );
236
+ }
237
+ break;
238
+ /**
239
+ * If is search question for quiz only search the items of course's author
240
+ */
241
+ case 'quiz-items':
242
+ if ( get_post_type( $context_id ) == 'lp_quiz' ) {
243
+ $args['author'] = get_post_field( 'post_author', $context_id );
244
+ }
245
+ break;
246
+ }
247
+ }
248
+ if ( $term ) {
249
+ $args['s'] = $term;
250
+ }
251
+ $posts = get_posts( $args );
252
+ $found_items = array();
253
+
254
+ if ( !empty( $posts ) ) {
255
+ foreach ( $posts as $post ) {
256
+ $found_items[$post->ID] = $post;
257
+ $found_items[$post->ID]->post_title = !empty( $post->post_title ) ? $post->post_title : sprintf( '(%s)', __( 'Untitled', 'learnpress' ) );
258
+ }
259
+ }
260
+
261
+ ob_start();
262
+ if ( $found_items ) {
263
+ foreach ( $found_items as $id => $item ) {
264
+ printf( '
265
+ <li class="" data-id="%1$d" data-type="%3$s" data-text="%2$s">
266
+ <label>
267
+ <input type="checkbox" value="%1$d">
268
+ <span class="lp-item-text">%2$s</span>
269
+ </label>
270
+ </li>
271
+ ', $id, $item->post_title, $item->post_type );
272
+ }
273
+ } else {
274
+ echo '<li>' . apply_filters( 'learn_press_modal_search_items_not_found', __( 'No item found', 'learnpress' ), $type ) . '</li>';
275
+ }
276
+
277
+ $response = array(
278
+ 'html' => ob_get_clean(),
279
+ 'data' => $found_items,
280
+ 'args' => $args
281
+ );
282
+ learn_press_send_json( $response );
283
+ }
284
+
285
+ static function remove_quiz_question() {
286
+ global $wpdb;
287
+ $quiz_id = learn_press_get_request( 'quiz_id' );
288
+ $question_id = learn_press_get_request( 'question_id' );
289
+ if ( !wp_verify_nonce( learn_press_get_request( 'remove-nonce' ), 'remove_quiz_question' ) ) {
290
+ wp_die( __( 'Error', 'learnpress' ) );
291
+ }
292
+ $query = $wpdb->prepare( "
293
+ DELETE FROM {$wpdb->prefix}learnpress_quiz_questions
294
+ WHERE quiz_id = %d
295
+ AND question_id = %d
296
+ ", $quiz_id, $question_id );
297
+ $wpdb->query( $query );
298
+ die();
299
+ }
300
+
301
+ static function search_questions() {
302
+ global $wpdb;
303
+
304
+ $quiz_id = learn_press_get_request( 'quiz_id' );
305
+ $user = learn_press_get_current_user();
306
+ if ( !$user->is_admin() && get_post_field( 'post_author', $quiz_id ) != get_current_user_id() ) {
307
+ wp_die( __( 'You have not permission to access this section', 'learnpress' ) );
308
+ }
309
+ $term = (string) ( stripslashes( learn_press_get_request( 'term' ) ) );
310
+ $exclude = array();
311
+
312
+ if ( !empty( $_GET['exclude'] ) ) {
313
+ $exclude = array_map( 'intval', $_GET['exclude'] );
314
+ }
315
+
316
+ $added = $wpdb->get_col(
317
+ $wpdb->prepare( "
318
+ SELECT question_id
319
+ FROM {$wpdb->prefix}learnpress_quiz_questions
320
+ WHERE %d
321
+ ", 1 )
322
+ );
323
+ if ( $added ) {
324
+ $exclude = array_merge( $exclude, $added );
325
+ $exclude = array_unique( $exclude );
326
+ }
327
+
328
+ $args = array(
329
+ 'post_type' => array( 'lp_question' ),
330
+ 'posts_per_page' => - 1,
331
+ 'post_status' => 'publish',
332
+ 'order' => 'ASC',
333
+ 'orderby' => 'parent title',
334
+ 'exclude' => $exclude
335
+ );
336
+ if ( !$user->is_admin() ) {
337
+ $args['author'] = $user->id;
338
+ }
339
+ if ( $term ) {
340
+ $args['s'] = $term;
341
+ }
342
+ $posts = get_posts( $args );
343
+ $found_questions = array();
344
+
345
+ if ( !empty( $posts ) ) {
346
+ foreach ( $posts as $post ) {
347
+ $found_questions[$post->ID] = !empty( $post->post_title ) ? $post->post_title : sprintf( '(%s)', __( 'Untitled', 'learnpress' ) );
348
+ }
349
+ }
350
+
351
+ ob_start();
352
+ if ( $found_questions ) {
353
+ foreach ( $found_questions as $id => $question ) {
354
+ printf( '
355
+ <li class="" data-id="%1$d" data-type="" data-text="%2$s">
356
+ <label>
357
+ <input type="checkbox" value="%1$d">
358
+ <span class="lp-item-text">%2$s</span>
359
+ </label>
360
+ </li>
361
+ ', $id, $question );
362
+ }
363
+ } else {
364
+ echo '<li>' . __( 'No question found', 'learnpress' ) . '</li>';
365
+ }
366
+
367
+ $response = array(
368
+ 'html' => ob_get_clean(),
369
+ 'data' => $found_questions,
370
+ 'args' => $args
371
+ );
372
+ learn_press_send_json( $response );
373
+ }
374
+
375
+ static function plugin_action() {
376
+ $url = learn_press_get_request( 'url' );
377
+ ob_start();
378
+ wp_remote_get( $url );
379
+ ob_get_clean();
380
+ echo wp_remote_get( admin_url( 'admin.php?page=learn_press_add_ons&tab=installed' ) );
381
+ die();
382
+ }
383
+
384
+ /**
385
+ * Remove an item from order
386
+ */
387
+ static function remove_order_item() {
388
+ // ensure that user has permission
389
+ if ( !current_user_can( 'edit_lp_orders' ) ) {
390
+ die( __( 'Permission denied', 'learnpress' ) );
391
+ }
392
+
393
+ // verify nonce
394
+ $nonce = learn_press_get_request( 'remove_nonce' );
395
+ if ( !wp_verify_nonce( $nonce, 'remove_order_item' ) ) {
396
+ die( __( 'Check nonce failed', 'learnpress' ) );
397
+ }
398
+
399
+ // validate order
400
+ $order_id = learn_press_get_request( 'order_id' );
401
+ if ( !is_numeric( $order_id ) || get_post_type( $order_id ) != 'lp_order' ) {
402
+ die( __( 'Order invalid', 'learnpress' ) );
403
+ }
404
+
405
+ // validate item
406
+ $item_id = learn_press_get_request( 'item_id' );
407
+ $post = get_post( learn_press_get_order_item_meta( $item_id, '_course_id' ) );
408
+ if ( !$post || ( 'lp_course' !== $post->post_type ) ) {
409
+ die( __( 'Course invalid', 'learnpress' ) );
410
+ }
411
+
412
+ learn_press_remove_order_item( $item_id );
413
+
414
+ $order_data = learn_press_update_order_items( $order_id );
415
+ $currency_symbol = learn_press_get_currency_symbol( $order_data['currency'] );
416
+ $order_data['subtotal_html'] = learn_press_format_price( $order_data['subtotal'], $currency_symbol );
417
+ $order_data['total_html'] = learn_press_format_price( $order_data['total'], $currency_symbol );
418
+
419
+
420
+ learn_press_send_json(
421
+ array(
422
+ 'result' => 'success',
423
+ 'order_data' => $order_data
424
+ )
425
+ );
426
+ }
427
+
428
+ /**
429
+ * Add new course to order
430
+ */
431
+ static function add_item_to_order() {
432
+
433
+ // ensure that user has permission
434
+ if ( !current_user_can( 'edit_lp_orders' ) ) {
435
+ die( __( 'Permission denied', 'learnpress' ) );
436
+ }
437
+
438
+ // verify nonce
439
+ $nonce = learn_press_get_request( 'nonce' );
440
+ if ( !wp_verify_nonce( $nonce, 'add_item_to_order' ) ) {
441
+ die( __( 'Check nonce failed', 'learnpress' ) );
442
+ }
443
+
444
+ // validate order
445
+ $order_id = learn_press_get_request( 'order_id' );
446
+ if ( !is_numeric( $order_id ) || get_post_type( $order_id ) != 'lp_order' ) {
447
+ die( __( 'Order invalid', 'learnpress' ) );
448
+ }
449
+
450
+ // validate item
451
+ $item_id = learn_press_get_request( 'item_id' );
452
+ $post = get_post( $item_id );
453
+ if ( !$post || ( 'lp_course' !== $post->post_type ) ) {
454
+ die( __( 'Course invalid', 'learnpress' ) );
455
+ }
456
+
457
+
458
+ $course = learn_press_get_course( $post->ID );
459
+ $order = learn_press_get_order( $order_id );
460
+
461
+ $item = array(
462
+ 'course_id' => $course->id,
463
+ 'name' => $course->get_title(),
464
+ 'quantity' => 1,
465
+ 'subtotal' => $course->get_price(),
466
+ 'total' => $course->get_price()
467
+ );
468
+
469
+ // Add item
470
+ $item_id = learn_press_add_order_item( $order_id, array(
471
+ 'order_item_name' => $item['name']
472
+ ) );
473
+
474
+ $item['id'] = $item_id;
475
+
476
+ // Add item meta
477
+ if ( $item_id ) {
478
+ $item = apply_filters( 'learn_press_ajax_order_item', $item );
479
+
480
+ learn_press_add_order_item_meta( $item_id, '_course_id', $item['course_id'] );
481
+ learn_press_add_order_item_meta( $item_id, '_quantity', $item['quantity'] );
482
+ learn_press_add_order_item_meta( $item_id, '_subtotal', $item['subtotal'] );
483
+ learn_press_add_order_item_meta( $item_id, '_total', $item['total'] );
484
+
485
+ do_action( 'learn_press_ajax_add_order_item_meta', $item );
486
+ }
487
+
488
+ $order_data = learn_press_update_order_items( $order_id );
489
+ $currency_symbol = learn_press_get_currency_symbol( $order_data['currency'] );
490
+ $order_data['subtotal_html'] = learn_press_format_price( $order_data['subtotal'], $currency_symbol );
491
+ $order_data['total_html'] = learn_press_format_price( $order_data['total'], $currency_symbol );
492
+
493
+ ob_start();
494
+ include learn_press_get_admin_view( 'meta-boxes/order/order-item.php' );
495
+ $item_html = ob_get_clean();
496
+
497
+ learn_press_send_json(
498
+ array(
499
+ 'result' => 'success',
500
+ 'item_html' => $item_html,
501
+ 'order_data' => $order_data
502
+ )
503
+ );
504
+ }
505
+
506
+ static function search_courses() {
507
+ $nonce = learn_press_get_request( 'nonce' );
508
+ if ( !wp_verify_nonce( $nonce, 'search_item_term' ) ) {
509
+ LP_Debug::exception( __( 'Verify nonce failed', 'learnpress' ) );
510
+ }
511
+
512
+ $term = learn_press_get_request( 'term' );
513
+ $exclude = learn_press_get_request( 'exclude' );
514
+
515
+ $posts = learn_press_get_all_courses(
516
+ array(
517
+ 'term' => $term,
518
+ 'exclude' => $exclude
519
+ )
520
+ );
521
+ $found_courses = array();
522
+ if ( !empty( $posts ) ) {
523
+ foreach ( $posts as $post ) {
524
+ $found_courses[$post] = array(
525
+ 'title' => get_the_title( $post ),
526
+ 'permalink' => get_the_permalink( $post )
527
+ );
528
+ }
529
+ }
530
+
531
+ $found_courses = apply_filters( 'learn_press_json_search_found_courses', $found_courses );
532
+
533
+ learn_press_send_json( $found_courses );
534
+ }
535
+
536
+ static function remove_course_section() {
537
+ $id = learn_press_get_request( 'id' );
538
+ if ( $id ) {
539
+ global $wpdb;
540
+ $query = $wpdb->prepare( "
541
+ DELETE FROM {$wpdb->prefix}learnpress_section_items
542
+ WHERE section_id = %d
543
+ ", $id );
544
+ $wpdb->query( $query );
545
+ learn_press_reset_auto_increment( 'learnpress_section_items' );
546
+ $query = $wpdb->prepare( "
547
+ DELETE FROM {$wpdb->prefix}learnpress_sections
548
+ WHERE section_id = %d
549
+ ", $id );
550
+ $wpdb->query( $query );
551
+ learn_press_reset_auto_increment( 'learnpress_sections' );
552
+ }
553
+ die();
554
+ }
555
+
556
+ static function toggle_lesson_preview() {
557
+ $id = learn_press_get_request( 'lesson_id' );
558
+ if ( get_post_type( $id ) == 'lp_lesson' && wp_verify_nonce( learn_press_get_request( 'nonce' ), 'learn-press-toggle-lesson-preview' ) ) {
559
+ update_post_meta( $id, '_lp_preview', learn_press_get_request( 'previewable' ) );
560
+ }
561
+ die();
562
+ }
563
+
564
+ static function add_new_item() {
565
+ $post_type = learn_press_get_request( 'type' );
566
+ $post_title = learn_press_get_request( 'name' );
567
+ $response = array();
568
+ if ( $post_type && $post_title ) {
569
+ $args = compact( 'post_title', 'post_type' );
570
+ $args['post_status'] = 'publish';
571
+ $item_id = wp_insert_post( $args );
572
+ if ( $item_id ) {
573
+ LP_Lesson_Post_Type::create_default_meta( $item_id );
574
+ $item = get_post( $item_id );
575
+ $response['post'] = $item;
576
+ $response['post']->edit_link = get_edit_post_link( $item_id );
577
+ }
578
+ }
579
+ learn_press_send_json( $response );
580
+ }
581
+
582
+ static function quick_add_item() {
583
+ $post_type = learn_press_get_request( 'type' );
584
+ $post_title = learn_press_get_request( 'name' );
585
+ $response = array();
586
+ if ( $post_type && $post_title ) {
587
+ $args = compact( 'post_title', 'post_type' );
588
+ $args['post_status'] = 'publish';
589
+ $item_id = wp_insert_post( $args );
590
+ if ( $item_id ) {
591
+ $item = get_post( $item_id );
592
+ $response['post'] = $item;
593
+ $response['html'] = sprintf( '<li class="" data-id="%1$d" data-type="%2$s" data-text="%3$s">
594
+ <label>
595
+ <input type="checkbox" value="%1$d">
596
+ <span class="lp-item-text">%3$s</span>
597
+ </label>
598
+ </li>', $item->ID, $item->post_type, $item->post_title );
599
+ }
600
+ }
601
+ learn_press_send_json( $response );
602
+ }
603
+
604
+ static function update_editor_hidden() {
605
+ if ( $id = learn_press_get_request( 'course_id' ) ) {
606
+ if ( learn_press_get_request( 'is_hidden' ) ) {
607
+ update_post_meta( $id, '_lp_editor_hidden', 'yes' );
608
+ } else {
609
+ delete_post_meta( $id, '_lp_editor_hidden' );
610
+ }
611
+ }
612
+ learn_press_send_json( $_POST );
613
+ }
614
+
615
+ static function update_quiz_question_state() {
616
+ $hidden = learn_press_get_request( 'hidden' );
617
+ $post = learn_press_get_request( 'quiz_id' );
618
+ update_post_meta( $post, '_admin_hidden_questions', $hidden );
619
+ die();
620
+ }
621
+
622
+ static function update_curriculum_section_state() {
623
+ $hidden = learn_press_get_request( 'hidden' );
624
+ $post = learn_press_get_request( 'course_id' );
625
+ update_post_meta( $post, '_admin_hidden_sections', $hidden );
626
+ die();
627
+ }
628
+
629
+ /**
630
+ * Create a new page with the title passed via $_REQUEST
631
+ */
632
+ public static function create_page() {
633
+ $page_name = !empty( $_REQUEST['page_name'] ) ? $_REQUEST['page_name'] : '';
634
+ $response = array();
635
+ if ( $page_name ) {
636
+ $args = array(
637
+ 'post_type' => 'page',
638
+ 'post_title' => $page_name,
639
+ 'post_status' => 'publish'
640
+ );
641
+ $page_id = wp_insert_post( $args );
642
+
643
+ if ( $page_id ) {
644
+ $response['page'] = get_page( $page_id );
645
+ $html = learn_press_pages_dropdown( '', '', array( 'echo' => false ) );
646
+ preg_match_all( '!value=\"([0-9]+)\"!', $html, $matches );
647
+ $response['positions'] = $matches[1];
648
+ $response['html'] = '<a href="' . get_edit_post_link( $page_id ) . '" target="_blank">' . __( 'Edit Page', 'learnpress' ) . '</a>&nbsp;';
649
+ $response['html'] .= '<a href="' . get_permalink( $page_id ) . '" target="_blank">' . __( 'View Page', 'learnpress' ) . '</a>';
650
+ } else {
651
+ $response['error'] = __( 'Error! Can not create page. Please try again!', 'learnpress' );
652
+ }
653
+ } else {
654
+ $response['error'] = __( 'Page name is empty!', 'learnpress' );
655
+ }
656
+ learn_press_send_json( $response );
657
+ die();
658
+ }
659
+
660
+ public static function add_quiz_question() {
661
+ global $post;
662
+ $id = learn_press_get_request( 'id' );
663
+ $quiz_id = learn_press_get_request( 'quiz_id' );
664
+ $type = learn_press_get_request( 'type' );
665
+ $name = learn_press_get_request( 'name' );
666
+ $response = array(
667
+ 'id' => $id
668
+ );
669
+ $post = get_post($quiz_id);
670
+ setup_postdata($post);
671
+ if ( !$id ) {
672
+ $id = wp_insert_post(
673
+ array(
674
+ 'post_title' => $name,
675
+ 'post_type' => LP()->question_post_type,
676
+ 'post_status' => 'publish'
677
+ )
678
+ );
679
+ if ( $id ) {
680
+ add_post_meta( $id, '_lp_type', $type );
681
+ }
682
+ $response['id'] = $id;
683
+ }
684
+ if ( $id && $quiz_id ) {
685
+ global $wpdb;
686
+ $max_order = $wpdb->get_var( $wpdb->prepare( "SELECT max(question_order) FROM {$wpdb->prefix}learnpress_quiz_questions WHERE quiz_id = %d", $quiz_id ) );
687
+ $wpdb->insert(
688
+ $wpdb->prefix . 'learnpress_quiz_questions',
689
+ array(
690
+ 'quiz_id' => $quiz_id,
691
+ 'question_id' => $id,
692
+ 'question_order' => $max_order + 1
693
+ ),
694
+ array( '%d', '%d', '%d' )
695
+ );
696
+ ob_start();
697
+ $question = LP_Question_Factory::get_question( $id );
698
+ learn_press_admin_view( 'meta-boxes/quiz/question.php', array( 'question' => $question ) );
699
+ $response['html'] = ob_get_clean();
700
+ }
701
+ learn_press_send_json( $response );
702
+ die();
703
+ }
704
+
705
+ public static function convert_question_type() {
706
+ if ( ( $from = learn_press_get_request( 'from' ) ) && ( $to = learn_press_get_request( 'to' ) ) && $question_id = learn_press_get_request( 'question_id' ) ) {
707
+ $data = array();
708
+ parse_str( $_POST['data'], $data );
709
+
710
+ do_action( 'learn_press_convert_question_type', $question_id, $from, $to, $data );
711
+ $question = LP_Question_Factory::get_question( $question_id, array( 'type' => $to ) );
712
+ learn_press_send_json(
713
+ array(
714
+ 'html' => $question->admin_interface( array( 'echo' => false ) ),
715
+ 'icon' => $question->get_icon()
716
+ )
717
+ );
718
+ } else {
719
+ throw new Exception( __( 'Convert question type must be specify the id, source and destination type', 'learnpress' ) );
720
+ }
721
+ die();
722
+ }
723
+
724
+ /*******************************************************************************************************/
725
+
726
+ /**
727
+ * Install sample data or dismiss the notice depending on user's option
728
+ */
729
+ static function install_sample_data() {
730
+ $yes = !empty( $_REQUEST['yes'] ) ? $_REQUEST['yes'] : '';
731
+ $response = array( 'result' => 'fail' );
732
+ $retry_button = sprintf( '<a href="" class="button yes" data-action="yes">%s</a>', __( 'Try again!', 'learnpress' ) );
733
+ $dismiss_button = sprintf( '<a href="" class="button disabled no" data-action="no">%s</a>', __( 'Cancel', 'learnpress' ) );
734
+ $buttons = sprintf( '<p>%s %s</p>', $retry_button, $dismiss_button );
735
+ if ( 'no' == $yes ) {
736
+ set_transient( 'learn_press_install_sample_data', 'off', 12 * HOUR_IN_SECONDS );
737
+ } else {
738
+ $result = array( 'status' => 'activate' );//learn_press_install_and_active_add_on( 'learnpress-import-export' );
739
+ if ( 'activate' == $result['status'] ) {
740
+ // copy dummy-data.xml to import folder of the add-on
741
+ lpie_mkdir( lpie_import_path() );
742
+ if ( file_exists( lpie_import_path() ) ) {
743
+ $import_source = LP_PLUGIN_PATH . '/dummy-data/dummy-data.xml';
744
+ $file = 'dummy-data-' . time() . '.xml';
745
+ $copy = lpie_import_path() . '/' . $file;
746
+ copy( $import_source, $copy );
747
+ if ( file_exists( $copy ) ) {
748
+ $url = admin_url( 'admin-ajax.php?page=learn_press_import_export&tab=import-course' );
749
+ $postdata = array(
750
+ 'step' => 2,
751
+ 'action' => 'learn_press_import',
752
+ 'import-file' => 'import/' . $file,
753
+ 'nonce' => wp_create_nonce( 'lpie-import-file' ),
754
+ 'x' => 1
755
+ );
756
+ $response['url'] = $url = $url . '&' . http_build_query( $postdata ) . "\n";
757
+ $response['result'] = 'success';
758
+ $response['message'] = sprintf( '<p>%s <a href="edit.php?post_type=lp_course">%s</a> </p>', __( 'Import sample data successfully.', 'learnpress' ), __( 'View courses', 'learnpress' ) );
759
+ }
760
+ }
761
+ if ( $response['result'] == 'fail' ) {
762
+ $response['message'] = sprintf( '<p>%s</p>%s', __( 'Import sample data failed. Please try again!.', 'learnpress' ), $buttons );
763
+ }
764
+ } else {
765
+ $response['result'] = 'fail';
766
+ $response['message'] = sprintf( '<p>%s</p>', __( 'Unknown error when installing/activating Import/Export addon. Please try again!', 'learnpress' ) ) . $buttons;
767
+ }
768
+ }
769
+ learn_press_send_json( $response );
770
+ die();
771
+ }
772
+
773
+ /**
774
+ * Activate a bundle of add-ons, if an add-on is not installed then install it first
775
+ */
776
+ static function bundle_activate_add_ons() {
777
+ global $learn_press_add_ons;
778
+ include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); //for plugins_api..
779
+ $response = array( 'addons' => array() );
780
+
781
+ if ( !current_user_can( 'activate_plugins' ) ) {
782
+ $response['error'] = __( 'You do not have sufficient permissions to deactivate plugins for this site.', 'learnpress' );
783
+ } else {
784
+
785
+ $add_ons = $learn_press_add_ons['bundle_activate'];
786
+
787
+ if ( $add_ons ) {
788
+ foreach ( $add_ons as $slug ) {
789
+ $response['addons'][$slug] = learn_press_install_and_active_add_on( $slug );
790
+ }
791
+ }
792
+ }
793
+ learn_press_send_json( $response );
794
+ }
795
+
796
+ /**
797
+ * Activate a bundle of add-ons, if an add-on is not installed then install it first
798
+ */
799
+ static function bundle_activate_add_on() {
800
+ $response = array();
801
+ include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); //for plugins_api..
802
+ if ( !current_user_can( 'activate_plugins' ) ) {
803
+ $response['error'] = __( 'You do not have sufficient permissions to deactivate plugins for this site.', 'learnpress' );
804
+ } else {
805
+ $slug = !empty( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : null;
806
+ $response[$slug] = learn_press_install_and_active_add_on( $slug );
807
+ }
808
+ learn_press_send_json( $response );
809
+ }
810
+
811
+ static function plugin_install() {
812
+ $plugin_name = !empty( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
813
+ $response = learn_press_install_add_on( $plugin_name );
814
+ learn_press_send_json( $response );
815
+ die();
816
+ }
817
+
818
+ static function update_add_on_status() {
819
+ $plugin = !empty( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
820
+ $t = !empty( $_REQUEST['t'] ) ? $_REQUEST['t'] : '';
821
+ $response = array();
822
+ if ( !current_user_can( 'activate_plugins' ) ) {
823
+ $response['error'] = __( 'You do not have sufficient permissions to deactivate plugins for this site.', 'learnpress' );
824
+ }
825
+ if ( $plugin && $t ) {
826
+ if ( $t == 'activate' ) {
827
+ activate_plugin( $plugin, false, is_network_admin() );
828
+ } else {
829
+ deactivate_plugins( $plugin, false, is_network_admin() );
830
+ }
831
+ $is_activate = is_plugin_active( $plugin );
832
+ $response['status'] = $is_activate ? 'activate' : 'deactivate';
833
+
834
+ }
835
+ wp_send_json( $response );
836
+ die();
837
+ }
838
+
839
+ /**
840
+ * Output the image to browser with text and params passed via $_GET
841
+ */
842
+ public static function dummy_image() {
843
+ $text = !empty( $_REQUEST['text'] ) ? $_REQUEST['text'] : '';
844
+ learn_press_text_image( $text, $_GET );
845
+ die();
846
+ }
847
+
848
+ /**
849
+ * Get edit|view link of a page
850
+ */
851
+ public static function get_page_permalink() {
852
+ $page_id = !empty( $_REQUEST['page_id'] ) ? $_REQUEST['page_id'] : '';
853
+ ?>
854
+ <a href="<?php echo get_edit_post_link( $page_id ); ?>" target="_blank"><?php _e( 'Edit Page', 'learnpress' ); ?></a>
855
+ <a href="<?php echo get_permalink( $page_id ); ?>" target="_blank"><?php _e( 'View Page', 'learnpress' ); ?></a>
856
+ <?php
857
+ die();
858
+ }
859
+
860
+
861
+ /**
862
+ *
863
+ */
864
+ public function custom_stats() {
865
+ $from = !empty( $_REQUEST['from'] ) ? $_REQUEST['from'] : 0;
866
+ $to = !empty( $_REQUEST['to'] ) ? $_REQUEST['to'] : 0;
867
+ $date_diff = strtotime( $to ) - strtotime( $from );
868
+ if ( $date_diff <= 0 || $from == 0 || $to == 0 ) {
869
+ die();
870
+ }
871
+ learn_press_process_chart( learn_press_get_chart_students( $to, 'days', floor( $date_diff / ( 60 * 60 * 24 ) ) + 1 ) );
872
+ die();
873
+ }
874
+
875
+ /**
876
+ * Quick add lesson with only title
877
+ */
878
+ public static function quick_add_lesson() {
879
+
880
+ $lesson_title = $_POST['lesson_title'];
881
+
882
+ $new_lesson = array(
883
+ 'post_title' => wp_strip_all_tags( $lesson_title ),
884
+ 'post_type' => LP()->lesson_post_type,
885
+ 'post_status' => 'publish'
886
+ );
887
+
888
+ wp_insert_post( $new_lesson );
889
+
890
+ $args = array(
891
+ 'numberposts' => 1,
892
+ 'post_type' => LP()->lesson_post_type,
893
+ 'post_status' => 'publish'
894
+ );
895
+ $lesson = wp_get_recent_posts( $args );
896
+ $lesson_id = $lesson[0]['ID'];
897
+ $data = array(
898
+ 'id' => $lesson_id,
899
+ 'title' => $lesson_title
900
+ );
901
+ wp_send_json( $data );
902
+ die;
903
+ }
904
+
905
+ /**
906
+ * Add a new quiz with the title only
907
+ */
908
+ public static function quick_add_quiz() {
909
+ $quiz_title = $_POST['quiz_title'];
910
+
911
+ $new_quiz = array(
912
+ 'post_title' => wp_strip_all_tags( $quiz_title ),
913
+ 'post_type' => LP()->quiz_post_type,
914
+ 'post_status' => 'publish'
915
+ );
916
+
917
+ wp_insert_post( $new_quiz );
918
+
919
+ $args = array(
920
+ 'numberposts' => 1,
921
+ 'post_type' => LP()->quiz_post_type,
922
+ 'post_status' => 'publish'
923
+ );
924
+ $quiz = wp_get_recent_posts( $args );
925
+ $quiz_id = $quiz[0]['ID'];
926
+ $data = array(
927
+ 'id' => $quiz_id,
928
+ 'title' => $quiz_title
929
+ );
930
+ wp_send_json( $data );
931
+ die;
932
+ }
933
+
934
+ public static function be_teacher() {
935
+ $user_id = get_current_user_id();
936
+ $be_teacher = new WP_User( $user_id );
937
+ $be_teacher->set_role( LP()->teacher_role );
938
+ die;
939
+ }
940
+
941
+ public static function ignore_setting_up() {
942
+ update_option( '_lpr_ignore_setting_up', 1, true );
943
+ die;
944
+ }
945
+ }
946
+ }
947
+ LP_Admin_Ajax::init();
inc/admin/class-lp-admin-assets.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class LP_Assets
4
+ *
5
+ * @author ThimPress
6
+ * @package LearnPress/Classes
7
+ * @version 1.0
8
+ * @extends LP_Abstract_Assets
9
+ */
10
+
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit; // Exit if accessed directly
13
+ }
14
+
15
+ learn_press_include( 'abstracts/abstract-lp-assets.php' );
16
+ class LP_Admin_Assets extends LP_Abstract_Assets {
17
+
18
+ static function init(){
19
+ parent::$caller = __CLASS__;
20
+ add_action( 'learn_press_print_assets', array( __CLASS__, '_print_assets' ) );
21
+ parent::init();
22
+ }
23
+ /**
24
+ * Load assets for admin
25
+ */
26
+ static function load_scripts(){
27
+ $screen = get_current_screen();
28
+ $screen_id = $screen->id;
29
+ $page_id = !empty( $_REQUEST['page'] ) ? $_REQUEST['page'] : '';
30
+ if( in_array( $screen_id, learn_press_get_screens() ) || in_array( $page_id, learn_press_get_admin_pages() ) ) {
31
+ self::add_style( 'learn-press-global', learn_press_plugin_url( 'assets/css/global-style.css' ) );
32
+ self::add_style( 'learn-press-admin', learn_press_plugin_url( 'assets/css/admin/admin.css' ), array( 'learn-press-global' ) );
33
+ self::add_style( 'learn-press-icons', learn_press_plugin_url( 'assets/css/icons.css' ) );
34
+
35
+ //self::add_script( 'learn-press-ui', learn_press_plugin_url( 'assets/js/ui.js' ) );
36
+ self::add_script( 'learn-press-admin', learn_press_plugin_url( 'assets/js/admin/admin.js' ) );
37
+ self::add_script( 'modal-search-items', learn_press_plugin_url( 'assets/js/admin/modal-search-items.js' ), array( 'jquery' ) );
38
+ }
39
+ if( in_array( $screen_id, array( 'lp_order', 'order', 'edit-lp_order' ) ) ){
40
+ self::add_style( 'learn-press-order', learn_press_plugin_url( 'assets/css/admin/meta-box-order.css' ) );
41
+ self::add_script( 'learn-press-order', learn_press_plugin_url( 'assets/js/admin/meta-box-order.js' ), array( 'backbone', 'wp-util' ) );
42
+ }
43
+ }
44
+
45
+ static function _print_assets(){
46
+ self::enqueue_style( 'learn-press-icons' );
47
+ self::enqueue_style( 'learn-press-admin' );
48
+
49
+ self::enqueue_style( 'learn-press-order' );
50
+ self::enqueue_script( 'learn-press-order' );
51
+
52
+ self::enqueue_script( 'learn-press-admin' );
53
+ }
54
+ }
55
+ LP_Admin_Assets::init();
inc/admin/class-lp-admin-menu.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * LP_Admin_Menu Construct
21
+ */
22
+ function __construct() {
23
+ // admin menu
24
+ add_action( 'admin_menu', array( $this, 'admin_menu' ) );
25
+ add_action( 'admin_menu', array( $this, 'notify_new_course' ) );
26
+ add_action( 'init', array( $this, 'menu_content' ) );
27
+ add_action( 'init', 'learn_press_admin_update_settings', 1000 );
28
+
29
+ // auto include file for admin page
30
+ // example: slug = learn_press_settings -> file = inc/admin/sub-menus/settings.php
31
+ $page = !empty ( $_REQUEST['page'] ) ? $_REQUEST['page'] : null;
32
+ if ( $page ) {
33
+
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_post_type . '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
+ 'settings' => array(
69
+ 'options-general.php',
70
+ __( 'LearnPress Settings', 'learnpress' ),
71
+ __( 'LearnPress', 'learnpress' ),
72
+ 'manage_options',
73
+ 'learn_press_settings',
74
+ 'learn_press_settings_page'
75
+ ),
76
+ 'addons' => array(
77
+ 'learn_press',
78
+ __( 'Add-ons', 'learnpress' ),
79
+ __( 'Add-ons', 'learnpress' ),
80
+ 'manage_options',
81
+ 'learn_press_add_ons',
82
+ 'learn_press_add_ons_page'
83
+ )
84
+ );
85
+
86
+ // Third-party can be add more items
87
+ $menu_items = apply_filters( 'learn_press_menu_items', $menu_items );
88
+
89
+ if ( $menu_items ) foreach ( $menu_items as $item ) {
90
+ call_user_func_array( 'add_submenu_page', $item );
91
+ }
92
+ }
93
+
94
+ /*
95
+ * Notify an administrator with pending courses
96
+ */
97
+ function notify_new_course() {
98
+ global $menu;
99
+ $current_user = wp_get_current_user();
100
+ if ( !in_array( 'administrator', $current_user->roles ) ) {
101
+ return;
102
+ }
103
+ $count_courses = wp_count_posts( LP()->course_post_type );
104
+ $awaiting_mod = $count_courses->pending;
105
+ $menu['3.14'][0] .= " <span class='awaiting-mod count-$awaiting_mod'><span class='pending-count'>" . number_format_i18n( $awaiting_mod ) . "</span></span>";
106
+ }
107
+
108
+ function menu_page(){
109
+ if( $this->_submenu ){
110
+ $this->_submenu->display();
111
+ }
112
+ }
113
+
114
+ function menu_content(){
115
+ if( !function_exists( 'learn_press_admin_update_settings' ) ){
116
+ remove_action( 'init', 'learn_press_admin_update_settings', 1000 );
117
+ }
118
+ }
119
+ }
120
+
121
+ return new LP_Admin_Menu();
inc/admin/class-lp-admin-notice.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Manage the admin notices and display them in admin
4
+ *
5
+ * @package LearnPress
6
+ * @author ThimPress
7
+ * @version 1.0
8
+ */
9
+ if ( !defined( 'ABSPATH' ) ) {
10
+ exit; // Exit if accessed directly
11
+ }
12
+
13
+ /**
14
+ * Class LP_Admin_Notice
15
+ */
16
+ class LP_Admin_Notice {
17
+ /**
18
+ * Store all notices which added anywhere before show
19
+ * @var array
20
+ */
21
+ protected static $_notices = array();
22
+
23
+ /**
24
+ * LP_Admin_Notice construct
25
+ */
26
+ function __construct() {
27
+ add_action( 'admin_notices', array( __CLASS__, 'show_notices' ), 100000 );
28
+ }
29
+
30
+ /**
31
+ * Add new notice to queue
32
+ *
33
+ * @param string $message The message want to display
34
+ * @param string $type The class name of WP message type updated|update-nag|error
35
+ * @param string $id Custom id for html element's ID
36
+ * @param bool
37
+ */
38
+ static function add( $message, $type = 'updated', $id = '', $redirect = false ) {
39
+ if ( $redirect ) {
40
+ $notices = get_transient( 'learn_press_redirect_notices' );
41
+ if ( empty( $notices ) ) {
42
+ $notices = array();
43
+ }
44
+ $notices[] = array(
45
+ 'type' => $type,
46
+ 'message' => $message,
47
+ 'id' => $id
48
+ );
49
+ set_transient( 'learn_press_redirect_notices', $notices );
50
+ } else {
51
+ self::$_notices[] = array(
52
+ 'type' => $type,
53
+ 'message' => $message,
54
+ 'id' => $id
55
+ );
56
+ }
57
+ }
58
+
59
+ static function add_redirect( $message, $type = 'updated', $id = '' ) {
60
+ self::add( $message, $type, $id, true );
61
+ }
62
+
63
+ /**
64
+ * Show all notices has registered
65
+ */
66
+ static function show_notices() {
67
+ if ( self::$_notices ) {
68
+ foreach ( self::$_notices as $notice ) {
69
+ if ( empty( $notice ) ) {
70
+ continue;
71
+ }
72
+ learn_press_admin_view( 'admin-notice.php', $notice );
73
+ }
74
+ }
75
+ if ( $notices = get_transient( 'learn_press_redirect_notices' ) ) {
76
+ foreach ( $notices as $notice ) {
77
+ if ( empty( $notice ) ) {
78
+ continue;
79
+ }
80
+ learn_press_admin_view( 'admin-notice.php', $notice );
81
+ }
82
+ delete_transient( 'learn_press_redirect_notices' );
83
+ }
84
+ }
85
+ }
86
+
87
+ new LP_Admin_Notice();
inc/admin/class-lp-admin-settings.php ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ wp_die( __FILE__ );
3
+ if ( !defined( 'ABSPATH' ) ) {
4
+ exit; // Exit if accessed directly
5
+ }
6
+
7
+ /**
8
+ * Class LP_Admin_Settings
9
+ */
10
+ class LP_Admin_Settings {
11
+ /**
12
+ * The option key stored in database
13
+ *
14
+ * @var string
15
+ * @access protected
16
+ */
17
+ protected $_key = '';
18
+
19
+ /**
20
+ * Store value of the options stored in database
21
+ *
22
+ * @var array|bool
23
+ */
24
+ public $_options = false;
25
+
26
+ /**
27
+ * Constructor
28
+ *
29
+ * @param $key
30
+ */
31
+ function __construct( $key ) {
32
+ if ( !$key ) {
33
+ wp_die( __FILE__ . '::' . __FUNCTION__ );
34
+ }
35
+ $this->_key = $key;
36
+ $this->_options = (array) get_option( $this->_key );
37
+ }
38
+
39
+ /**
40
+ * Set new value for a key of $_options
41
+ *
42
+ * @param $name
43
+ * @param $value
44
+ */
45
+ function set( $name, $value ) {
46
+ $this->_set_option( $this->_options, $name, $value, true );
47
+ }
48
+
49
+ /**
50
+ * Set value for an object|array by key
51
+ *
52
+ * @param $obj
53
+ * @param $var
54
+ * @param $value
55
+ * @param bool $recurse
56
+ */
57
+ private function _set_option( &$obj, $var, $value, $recurse = false ) {
58
+ $var = (array) explode( '.', $var );
59
+ $current_var = array_shift( $var );
60
+ if ( is_object( $obj ) ) {
61
+ $obj_vars = get_object_vars( $obj );
62
+ if ( array_key_exists( $current_var, $obj_vars ) ) { // isset( $obj->{$current_var} ) ){
63
+ if ( count( $var ) ) {
64
+ if ( is_object( $obj->$current_var ) ) {
65
+ $obj->$current_var = new stdClass();
66
+ } else {
67
+ $obj->$current_var = array();
68
+ }
69
+ $this->_set_option( $obj->$current_var, join( '.', $var ), $value, $recurse );
70
+ } else {
71
+ $obj->$current_var = $value;
72
+ }
73
+ } else {
74
+ if ( $recurse ) {
75
+ if ( count( $var ) ) {
76
+ $next_var = reset( $var );
77
+ if ( is_object( $obj->$current_var ) ) {
78
+ $obj->$current_var = new stdClass();
79
+ } else {
80
+ $obj->$current_var = array();
81
+ }
82
+ $this->_set_option( $obj->$current_var, join( '.', $var ), $value, $recurse );
83
+ } else {
84
+ $obj->$current_var = $value;
85
+ }
86
+ } else {
87
+ $obj->$current_var = $value;
88
+ }
89
+ }
90
+ } else if ( is_array( $obj ) ) {
91
+ if ( array_key_exists( $current_var, $obj ) ) {
92
+ if ( count( $var ) ) {
93
+ $obj[$current_var] = array();
94
+ $this->_set_option( $obj[$current_var], join( '.', $var ), $value, $recurse );
95
+ } else {
96
+ $obj[$current_var] = $value;
97
+ }
98
+ } else {
99
+ if ( $recurse ) {
100
+ if ( count( $var ) ) {
101
+ $next_var = reset( $var );
102
+ $obj[$current_var] = array();
103
+ $this->_set_option( $obj[$current_var], join( '.', $var ), $value, $recurse );
104
+ } else {
105
+ $obj[$current_var] = $value;
106
+ }
107
+ } else {
108
+ $obj[$current_var] = $value;
109
+ }
110
+ }
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Get value from a key of $_options
116
+ *
117
+ * @param $var
118
+ * @param null $default
119
+ *
120
+ * @return null
121
+ */
122
+ function get( $var, $default = null ) {
123
+ return $this->_get_option( $this->_options, $var, $default );
124
+ }
125
+
126
+ /**
127
+ * Get value from a key of an object|array
128
+ *
129
+ * @param $obj
130
+ * @param $var
131
+ * @param null $default
132
+ *
133
+ * @return null
134
+ */
135
+ function _get_option( $obj, $var, $default = null ) {
136
+ $var = (array) explode( '.', $var );
137
+ $current_var = array_shift( $var );
138
+ if ( is_object( $obj ) ) {
139
+ if ( isset( $obj->{$current_var} ) ) {
140
+ if ( count( $var ) ) {
141
+ return $this->_get_option( $obj->{$current_var}, join( '.', $var ), $default );
142
+ } else {
143
+ return $obj->{$current_var};
144
+ }
145
+ } else {
146
+ return $default;
147
+ }
148
+ } else {
149
+ if ( isset( $obj[$current_var] ) ) {
150
+ if ( count( $var ) ) {
151
+ return $this->_get_option( $obj[$current_var], join( '.', $var ), $default );
152
+ } else {
153
+ return $obj[$current_var];
154
+ }
155
+ } else {
156
+ return $default;
157
+ }
158
+ }
159
+ return $default;
160
+ }
161
+
162
+ /**
163
+ * Combine an array|object to current options
164
+ *
165
+ * @param $new
166
+ */
167
+ function bind( $new ) {
168
+ if ( is_object( $new ) ) $new = (array) $new;
169
+ if ( is_array( $new ) ) {
170
+ foreach ( $new as $k => $v ) {
171
+ $this->set( $k, $v );
172
+ }
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Store options into database
178
+ */
179
+ function update() {
180
+ update_option( $this->_key, $this->_options );
181
+ }
182
+
183
+ /**
184
+ * Unique an instance of the class by the key of the options want to initial
185
+ *
186
+ * @param $key
187
+ *
188
+ * @return mixed
189
+ */
190
+ static function instance( $key ) {
191
+ static $instances = array();
192
+ $key = '_lpr_settings_' . $key;
193
+ if ( empty( $instances[$key] ) ) {
194
+ $instances[$key] = new LP_Admin_Settings( $key );
195
+ }
196
+ return $instances[$key];
197
+ }
198
+ }
199
+
200
+ if ( !function_exists( 'learn_press_admin_settings' ) ) {
201
+ function learn_press_admin_settings( $key ) {
202
+ return LP_Admin_Settings::instance( $key );
203
+ }
204
+ }
inc/admin/class-lp-admin.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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( 'init', array( $this, 'include_update' ) );
23
+ add_action( 'template_redirect', array( $this, '_redirect' ) );
24
+ }
25
+
26
+ /**
27
+ * Output common js settings in admin
28
+ *
29
+ * @since 0.9.4
30
+ */
31
+ function plugin_js_settings() {
32
+ static $did = false;
33
+ if ( $did || !is_admin() ) return;
34
+ $js = array(
35
+ 'ajax' => admin_url( 'admin-ajax.php' ),
36
+ 'plugin_url' => learn_press_plugin_url(),
37
+ 'siteurl' => home_url()
38
+ );
39
+ echo '<script type="text/javascript">var LearnPress_Settings = ' . json_encode( $js ) . '</script>';
40
+ if( LP_Settings::instance()->get('debug') == 'yes' ){
41
+ echo '<script type="text/javascript">var LEARN_PRESS_DEBUG = true;</script>';
42
+ }
43
+ $did = true;
44
+ }
45
+
46
+ /**
47
+ * Redirect to admin settings page
48
+ */
49
+ function _redirect() {
50
+ $page = isset( $_GET['page'] ) ? $_GET['page'] : '';
51
+ if ( 'learn_press_settings' == $page ) {
52
+ $current_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : '';
53
+ $tabs = learn_press_settings_tabs_array();
54
+
55
+ if ( !$current_tab || ( $tabs && empty( $tabs[$current_tab] ) ) ) {
56
+ if ( $tabs ) {
57
+ $tab_keys = array_keys( $tabs );
58
+ $current_tab = reset( $tab_keys );
59
+ wp_redirect( admin_url( 'options-general.php?page=learn_press_settings&tab=' . $current_tab ) );
60
+ exit();
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Include all classes and functions used for admin
68
+ */
69
+ public function includes() {
70
+ // Common function used in admin
71
+ include_once( 'lp-admin-functions.php' );
72
+ //Ajax Class
73
+ include_once( 'class-lp-admin-ajax.php' );
74
+ // Admin menu
75
+ include_once( 'class-lp-admin-menu.php' );
76
+
77
+
78
+ }
79
+ }
80
+ new LP_Admin();
81
+ }
inc/admin/class-lp-email.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Email
5
+ */
6
+ class LP_Email_bakup {
7
+
8
+ /**
9
+ * @var array
10
+ */
11
+ protected $to = array();
12
+
13
+ /**
14
+ * @var string
15
+ */
16
+ protected $subject = '';
17
+
18
+ /**
19
+ * @var string
20
+ */
21
+ protected $message = '';
22
+
23
+ /**
24
+ * Constructor.
25
+ */
26
+ public function __construct() {
27
+ }
28
+
29
+ /**
30
+ * Filter headers.
31
+ * Replaces new lines.
32
+ *
33
+ * @param string $value
34
+ *
35
+ * @return string
36
+ */
37
+ public function filter( $value ) {
38
+ return str_ireplace( array( "\r", "\n", '%0A', '%0D', '<CR>', '<LF>' ), '', $value );
39
+ }
40
+
41
+ /**
42
+ * Set email template.
43
+ *
44
+ * @param $action
45
+ */
46
+ public function set_action( $action ) {
47
+ $emails_settings = get_option( '_lpr_settings_emails' );
48
+
49
+ $this->subject = isset( $emails_settings[$action]['subject'] ) ? $emails_settings[$action]['subject'] : '';
50
+ $this->message = isset( $emails_settings[$action]['message'] ) ? $emails_settings[$action]['message'] : '';
51
+ }
52
+
53
+ /**
54
+ * Parse subject placeholders.
55
+ *
56
+ * @param array $vars
57
+ */
58
+ public function parse_email( $vars ) {
59
+ if ( empty( $vars ) ) {
60
+ return;
61
+ }
62
+
63
+ foreach ( $vars as $key => $value ) {
64
+ $this->subject = str_replace( '{' . $key . '}', $value, $this->subject );
65
+ $this->message = str_replace( '{' . $key . '}', $value, $this->message );
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Add email recipient.
71
+ *
72
+ * @param string $email
73
+ */
74
+ public function add_recipient( $email ) {
75
+ $this->to[] = $email;
76
+ }
77
+
78
+ /**
79
+ * Send email.
80
+ *
81
+ * @return boolean
82
+ */
83
+ public function send() {
84
+ $email_settings = get_option( '_lpr_settings_emails' );
85
+ $headers[] = 'Content-Type: text/html; charset=UTF-8';
86
+ $headers['from'] = '';
87
+
88
+ if ( is_array( $email_settings['general'] ) && !empty( $email_settings['general']['from_email'] ) ) {
89
+ $headers['from'] .= 'From:';
90
+
91
+ if ( !empty( $email_settings['general']['from_name'] ) ) {
92
+ $headers['from'] .= ' ' . $this->filter( $email_settings['general']['from_name'] );
93
+ }
94
+
95
+ $headers['from'] .= ' <' . sanitize_email( $email_settings['general']['from_email'] ) . ">\r\n";
96
+ }
97
+
98
+ return wp_mail( $this->to, $this->filter( $this->subject ), stripslashes( $this->message ), $headers );
99
+ }
100
+ }
inc/admin/class-lp-plugin-install-list-table.php ADDED
@@ -0,0 +1,489 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Installer List Table class.
4
+ *
5
+ * @package WordPress
6
+ * @subpackage List_Table
7
+ * @since 3.1.0
8
+ * @access private
9
+ */
10
+ die();
11
+ class LP_Plugin_Install_List_Table extends WP_List_Table {
12
+
13
+ public $order = 'ASC';
14
+ public $orderby = null;
15
+ public $groups = array();
16
+
17
+ private $error;
18
+ private $test_mode = false;
19
+ private $repo_url = 'http://thimpress.com/lprepo/';
20
+ private $upgrader = false;
21
+ public $items; // extended from it parent
22
+ public function ajax_user_can() {
23
+ return current_user_can('install_plugins');
24
+ }
25
+
26
+ /**
27
+ * Return a list of slugs of installed plugins, if known.
28
+ *
29
+ * Uses the transient data from the updates API to determine the slugs of
30
+ * known installed plugins. This might be better elsewhere, perhaps even
31
+ * within get_plugins().
32
+ *
33
+ * @since 4.0.0
34
+ * @access protected
35
+ */
36
+ protected function get_installed_plugin_slugs() {
37
+ $slugs = array();
38
+
39
+ $plugin_info = get_site_transient( 'update_plugins' );
40
+ if ( isset( $plugin_info->no_update ) ) {
41
+ foreach ( $plugin_info->no_update as $plugin ) {
42
+ $slugs[] = $plugin->slug;
43
+ }
44
+ }
45
+
46
+ if ( isset( $plugin_info->response ) ) {
47
+ foreach ( $plugin_info->response as $plugin ) {
48
+ $slugs[] = $plugin->slug;
49
+ }
50
+ }
51
+
52
+ return $slugs;
53
+ }
54
+
55
+ private function _get_items_from_wp( $args = array() ){
56
+ $tab = ! empty( $_REQUEST['tab'] ) ? $_REQUEST['tab'] : '';
57
+ if( ! $tab ) return;
58
+ global $learn_press_add_ons;
59
+ $plugins = learn_press_get_add_ons_from_wp( $args );
60
+ if( ( $tab == 'bundle_activate' ) && sizeof( $plugins ) ) {
61
+
62
+ $_plugins = array_values( $plugins );
63
+ $plugins = array();
64
+ $bundle_activate = $learn_press_add_ons['bundle_activate'];
65
+ for( $n = sizeof( $_plugins ), $i = $n - 1; $i >= 0; $i-- ){
66
+ foreach( $bundle_activate as $slug ){
67
+ if( ( false !== strpos( $slug, $_plugins[$i]->slug ) ) || ( false !== strpos( $_plugins[$i]->slug, $slug ) ) ){
68
+ $plugins[] = $_plugins[ $i ];
69
+ }
70
+ }
71
+ }
72
+ }
73
+ $this->items = $plugins;
74
+ }
75
+
76
+ private function _get_items_from_thimpress( $add_ons ){
77
+ $cache = WP_CONTENT_DIR . '/upgrade/' . md5( serialize( $add_ons ) ) . '.cache';
78
+ $timeover = HOUR_IN_SECONDS * 24;
79
+ if( file_exists( $cache ) && ( time() - filemtime( $cache ) ) < $timeover ){
80
+ $items = maybe_unserialize( file_get_contents( $cache ) );
81
+ }else {
82
+ $repo_url = 'http://thimpress.com/lprepo/';
83
+
84
+ foreach ($add_ons as $slug) {
85
+ if( false !== strpos( $slug, '.php' ) ){
86
+ $filename = basename( $slug );
87
+ $slug = dirname( $slug );
88
+ }else{
89
+ $filename = "{$slug}.php";
90
+ }
91
+ $item = array(
92
+ 'name' => '',
93
+ 'slug' => '',
94
+ 'version' => '0.0',
95
+ 'author' => '<a href="http://profiles.wordpress.org/thimpress">thimpress</a>',
96
+ 'author_profile' => 'http://profiles.wordpress.org/thimpress',
97
+ 'contributors' => array(),
98
+ 'requires' => '4.0',
99
+ 'tested' => '4.2.2',
100
+ 'rating' => 0,
101
+ 'num_ratings' => 0,
102
+ 'ratings' => array(
103
+ '5' => 0,
104
+ '4' => 0,
105
+ '3' => 0,
106
+ '2' => 0,
107
+ '1' => 0
108
+ ),
109
+
110
+ 'active_installs' => 0,
111
+ 'last_updated' => gmdate('Y-m-d h:iA', strtotime('last Friday', time())) . ' GMT',
112
+ 'homepage' => 'http://thimpress.com/learnpress',
113
+ 'short_description' => '',
114
+ 'icons' => array(
115
+ '2x' => LP_PLUGIN_URL . '/assets/images/icon-128x128.png',
116
+ '1x' => LP_PLUGIN_URL . '/assets/images/icon-128x128.png'
117
+ )
118
+ );
119
+ $readme = $this->upgrader->get_plugin_info($repo_url . "/{$slug}.zip", $filename );
120
+ $item['name'] = $readme['name'];
121
+ $item['slug'] = $slug;
122
+ if (preg_match('!<h4>(.*)<\/h4>!', $readme['sections']['changelog'], $matches)) {
123
+ $item['version'] = $matches[1];
124
+ }
125
+ $item['requires'] = $readme['requires_at_least'];
126
+ $item['tested'] = $readme['tested_up_to'];
127
+
128
+ $items["{$slug}/{$filename}"] = (object)$item;
129
+ }
130
+ file_put_contents( $cache, serialize($items));
131
+ }
132
+ $this->items = $items;
133
+ }
134
+
135
+ /**
136
+ * Get list of add ons
137
+ *
138
+ * @param array
139
+ */
140
+ public function prepare_items( $args = array() ) {
141
+ global $learn_press_add_ons;
142
+ $this->upgrader = new LP_Upgrader();
143
+
144
+ $page = ! empty( $_REQUEST['page'] ) ? $_REQUEST['page'] : '';
145
+ $tab = ! empty( $_REQUEST['tab'] ) ? $_REQUEST['tab'] : '';
146
+ if( 'learn_press_add_ons' != $page ) return;
147
+
148
+ if( 'more' == $tab ){
149
+ $add_ons = $learn_press_add_ons['more'];
150
+ }elseif( 'bundle_activate' == $tab ){
151
+ $add_ons = $learn_press_add_ons['bundle_activate'];
152
+ }
153
+ if( ! $this->test_mode ){
154
+ $this->_get_items_from_wp( $args );
155
+ }else{
156
+ $this->_get_items_from_thimpress( $add_ons );
157
+ }
158
+ }
159
+
160
+
161
+ public function no_items() {
162
+ $message = __( 'No plugins found.', 'learnpress' );
163
+
164
+ echo '<div class="no-plugin-results">' . $message . '</div>';
165
+ }
166
+
167
+ protected function get_views() {
168
+ global $tabs, $tab;
169
+
170
+ $display_tabs = array();
171
+ foreach ( (array) $tabs as $action => $text ) {
172
+ $class = ( $action == $tab ) ? ' current' : '';
173
+ $href = self_admin_url('plugin-install.php?tab=' . $action);
174
+ $display_tabs['plugin-install-'.$action] = "<a href='$href' class='$class'>$text</a>";
175
+ }
176
+ // No longer a real tab.
177
+ unset( $display_tabs['plugin-install-upload'] );
178
+
179
+ return $display_tabs;
180
+ }
181
+
182
+ /**
183
+ * Override parent views so we can use the filter bar display.
184
+ */
185
+ public function views() {
186
+ $views = $this->get_views();
187
+
188
+ /** This filter is documented in wp-admin/inclues/class-wp-list-table.php */
189
+ $views = apply_filters( "views_{$this->screen->id}", $views );
190
+
191
+ ?>
192
+ <div class="wp-filter">
193
+ <ul class="filter-links">
194
+ <?php
195
+ if ( ! empty( $views ) ) {
196
+ foreach ( $views as $class => $view ) {
197
+ $views[ $class ] = "\t<li class='$class'>$view";
198
+ }
199
+ echo implode( " </li>\n", $views ) . "</li>\n";
200
+ }
201
+ ?>
202
+ </ul>
203
+
204
+ <?php install_search_form( isset( $views['plugin-install-search'] ) ); ?>
205
+ </div>
206
+ <?php
207
+ }
208
+
209
+ /**
210
+ * Override the parent display() so we can provide a different container.
211
+ */
212
+ public function display() {
213
+ $data_attr = '';
214
+ ?>
215
+ <div class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>">
216
+
217
+ <div id="the-list"<?php echo $data_attr; ?>>
218
+ <?php $this->display_rows_or_placeholder(); ?>
219
+ </div>
220
+ </div>
221
+ <?php
222
+ $this->display_tablenav( 'bottom' );
223
+ }
224
+
225
+ /**
226
+ * @param string $which
227
+ */
228
+ protected function display_tablenav( $which ) {
229
+ if ( 'top' == $which ) {
230
+ wp_referer_field();
231
+ ?>
232
+ <div class="tablenav top">
233
+ <div class="alignleft actions">
234
+ <?php
235
+ /**
236
+ * Fires before the Plugin Install table header pagination is displayed.
237
+ *
238
+ * @since 2.7.0
239
+ */
240
+ do_action( 'install_plugins_table_header' ); ?>
241
+ </div>
242
+ <?php $this->pagination( $which ); ?>
243
+ <br class="clear" />
244
+ </div>
245
+ <?php } else { ?>
246
+ <div class="tablenav bottom">
247
+ <?php $this->pagination( $which ); ?>
248
+ <br class="clear" />
249
+ </div>
250
+ <?php
251
+ }
252
+ }
253
+
254
+ protected function get_table_classes() {
255
+ return array( 'widefat', $this->_args['plural'] );
256
+ }
257
+
258
+ public function get_columns() {
259
+ return array();
260
+ }
261
+
262
+ /**
263
+ * @param object $plugin_a
264
+ * @param object $plugin_b
265
+ * @return int
266
+ */
267
+ private function order_callback( $plugin_a, $plugin_b ) {
268
+ $orderby = $this->orderby;
269
+ if ( ! isset( $plugin_a->$orderby, $plugin_b->$orderby ) ) {
270
+ return 0;
271
+ }
272
+
273
+ $a = $plugin_a->$orderby;
274
+ $b = $plugin_b->$orderby;
275
+
276
+ if ( $a == $b ) {
277
+ return 0;
278
+ }
279
+
280
+ if ( 'DESC' == $this->order ) {
281
+ return ( $a < $b ) ? 1 : -1;
282
+ } else {
283
+ return ( $a < $b ) ? -1 : 1;
284
+ }
285
+ }
286
+
287
+ public function display_rows() {
288
+ $plugins_allowedtags = array(
289
+ 'a' => array( 'href' => array(),'title' => array(), 'target' => array() ),
290
+ 'abbr' => array( 'title' => array() ),'acronym' => array( 'title' => array() ),
291
+ 'code' => array(), 'pre' => array(), 'em' => array(),'strong' => array(),
292
+ 'ul' => array(), 'ol' => array(), 'li' => array(), 'p' => array(), 'br' => array()
293
+ );
294
+
295
+ $plugins_group_titles = array(
296
+ 'Performance' => _x( 'Performance', 'Plugin installer group title' ),
297
+ 'Social' => _x( 'Social', 'Plugin installer group title' ),
298
+ 'Tools' => _x( 'Tools', 'Plugin installer group title' ),
299
+ );
300
+
301
+ $tab = ! empty( $_REQUEST['tab'] ) ? $_REQUEST['tab'] : '';
302
+ $group = null;
303
+
304
+ foreach ( (array) $this->items as $kk => $plugin ) {
305
+ if ( is_object( $plugin ) ) {
306
+ $plugin = (array) $plugin;
307
+ }
308
+
309
+ // Display the group heading if there is one
310
+ if ( isset( $plugin['group'] ) && $plugin['group'] != $group ) {
311
+ if ( isset( $this->groups[ $plugin['group'] ] ) ) {
312
+ $group_name = $this->groups[ $plugin['group'] ];
313
+ if ( isset( $plugins_group_titles[ $group_name ] ) ) {
314
+ $group_name = $plugins_group_titles[ $group_name ];
315
+ }
316
+ } else {
317
+ $group_name = $plugin['group'];
318
+ }
319
+
320
+ // Starting a new group, close off the divs of the last one
321
+ if ( ! empty( $group ) ) {
322
+ echo '</div></div>';
323
+ }
324
+
325
+ echo '<div class="plugin-group"><h3>' . esc_html( $group_name ) . '</h3>';
326
+ // needs an extra wrapping div for nth-child selectors to work
327
+ echo '<div class="plugin-items">';
328
+
329
+ $group = $plugin['group'];
330
+ }
331
+ $title = wp_kses( $plugin['name'], $plugins_allowedtags );
332
+
333
+ // Remove any HTML from the description.
334
+ $description = strip_tags( $plugin['short_description'] );
335
+ $version = wp_kses( $plugin['version'], $plugins_allowedtags );
336
+
337
+ $name = strip_tags( $title . ' ' . $version );
338
+
339
+ $author = wp_kses( $plugin['author'], $plugins_allowedtags );
340
+ if ( ! empty( $author ) ) {
341
+ $author = ' <cite>' . sprintf( __( 'By %s', 'learnpress' ), $author ) . '</cite>';
342
+ }
343
+
344
+ $action_links = array();
345
+ $plugin_file = learn_press_plugin_basename_from_slug( $plugin['slug'] );
346
+
347
+ if ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) {
348
+
349
+ if( $this->test_mode ){
350
+ $status = array(
351
+ 'status' => file_exists( WP_PLUGIN_DIR . '/' . $plugin['slug'] ) ? 'newer_installed' : 'install' ,
352
+ 'url' => admin_url( 'admin-ajax.php?action=learnpress_plugin_install&plugin=' . $plugin['slug'] )
353
+ );
354
+ }else{
355
+ $status = install_plugin_install_status( $plugin );
356
+ }
357
+
358
+ switch ( $status['status'] ) {
359
+ case 'install':
360
+ if ( $status['url'] ) {
361
+ /* translators: 1: Plugin name and version. */
362
+ $action_links[] = '<a class="install-now button thimpress" data-action="install-now" data-slug="' . esc_attr( $plugin['slug'] ) . '" href="' . esc_url( $status['url'] ) . '&learnpress=active" aria-label="' . esc_attr( sprintf( __( 'Install %s now', 'learnpress' ), $name ) ) . '" data-name="' . esc_attr( $name ) . '">' . __( 'Install and Active', 'learnpress' ) . '</a>';
363
+ }
364
+
365
+ break;
366
+ case 'update_available':
367
+ if ( $status['url'] ) {
368
+ /* translators: 1: Plugin name and version */
369
+ $action_links[] = '<a class="update-now button thimpress" data-action="update-now" data-plugin="' . esc_attr( $status['file'] ) . '" data-slug="' . esc_attr( $plugin['slug'] ) . '" href="' . esc_url( $status['url'] ) . '&learnpress=active" aria-label="' . esc_attr( sprintf( __( 'Update %s now', 'learnpress' ), $name ) ) . '" data-name="' . esc_attr( $name ) . '">' . __( 'Update Now', 'learnpress' ) . '</a>';
370
+ }
371
+
372
+ break;
373
+ case 'latest_installed':
374
+ case 'newer_installed':
375
+ if( is_plugin_active( $plugin_file ) ){
376
+ $action_links[] = '<span class="button button-disabled" title="">' . _x('Enabled', 'plugin') . '</span>';
377
+ }else {
378
+ $action_links[] = '<a class="active-now button thimpress" data-action="active-now" href="'.wp_nonce_url( 'plugins.php?action=activate&learnpress=active&plugin='.$plugin_file, 'activate-plugin_' . $plugin_file ) . '" >' . _x('Enable', 'plugin') . '</a>';
379
+ }
380
+ break;
381
+ }
382
+ }
383
+
384
+ /*$details_link = self_admin_url( 'plugin-install.php?tab=plugin-information&amp;plugin=' . $plugin['slug'] .
385
+ '&amp;TB_iframe=true&amp;width=600&amp;height=550' );
386
+
387
+
388
+ $action_links[] = '<a href="' . esc_url( $details_link ) . '" class="thickbox" aria-label="' . esc_attr( sprintf( __( 'More information about %s' ), $name ) ) . '" data-title="' . esc_attr( $name ) . '">' . __( 'More Details' ) . '</a>';
389
+ */
390
+ if ( !empty( $plugin['icons']['svg'] ) ) {
391
+ $plugin_icon_url = $plugin['icons']['svg'];
392
+ } elseif ( !empty( $plugin['icons']['2x'] ) ) {
393
+ $plugin_icon_url = $plugin['icons']['2x'];
394
+ } elseif ( !empty( $plugin['icons']['1x'] ) ) {
395
+ $plugin_icon_url = $plugin['icons']['1x'];
396
+ } else {
397
+ $plugin_icon_url = $plugin['icons']['default'];
398
+ }
399
+
400
+ /**
401
+ * Filter the install action links for a plugin.
402
+ *
403
+ * @since 2.7.0
404
+ *
405
+ * @param array $action_links An array of plugin action hyperlinks. Defaults are links to Details and Install Now.
406
+ * @param array $plugin The plugin currently being listed.
407
+ */
408
+ $action_links = apply_filters( 'plugin_install_action_links', $action_links, $plugin );
409
+
410
+ $date_format = 'M j, Y @ H:i';
411
+ $last_updated_timestamp = strtotime( $plugin['last_updated'] );
412
+ $details_link = "";
413
+ $message = null;
414
+
415
+ if( 'bundle_activate' == $tab ){
416
+
417
+ if( learn_press_is_plugin_install( $plugin_file ) ) {
418
+
419
+ if (is_plugin_active( $plugin_file )) {
420
+ $message = sprintf('<span class="addon-status enabled">%s</span>', __( 'Enabled', 'learnpress' ));
421
+ } else {
422
+ $message = sprintf('<span class="addon-status disabled">%s</span>', __( 'Disabled', 'learnpress' ));
423
+ }
424
+ }else{
425
+ $message = sprintf('<span class="addon-status not_install">%s</span>', __( 'Not Install', 'learnpress' ));
426
+ }
427
+ }
428
+ ?>
429
+ <div class="plugin-card plugin-card-<?php echo sanitize_html_class( $plugin['slug'] ); ?>">
430
+ <div class="plugin-card-top">
431
+ <a href="<?php echo esc_url( $details_link ); ?>" class="thickbox plugin-icon"><img src="<?php echo esc_attr( $plugin_icon_url ) ?>" /></a>
432
+ <div class="name column-name">
433
+ <h3><a href="<?php echo esc_url( $details_link ); ?>" class="thickbox"><?php echo $title; ?></a></h3>
434
+ </div>
435
+ <div class="action-links">
436
+ <?php
437
+ if ( $action_links ) {
438
+ echo '<ul class="plugin-action-buttons"><li>' . implode( '</li><li>', $action_links ) . '</li></ul>';
439
+ }
440
+ //echo $message;
441
+ ?>
442
+ </div>
443
+ <div class="desc column-description">
444
+ <p><?php echo $description; ?></p>
445
+ <p class="authors"><?php echo $author; ?></p>
446
+ </div>
447
+ </div>
448
+ <div class="plugin-card-bottom">
449
+ <div class="vers column-rating">
450
+ <?php wp_star_rating( array( 'rating' => $plugin['rating'], 'type' => 'percent', 'number' => $plugin['num_ratings'] ) ); ?>
451
+ <span class="num-ratings">(<?php echo number_format_i18n( $plugin['num_ratings'] ); ?>)</span>
452
+ </div>
453
+ <div class="column-updated">
454
+ <strong><?php _e( 'Last Updated:', 'learnpress' ); ?></strong> <span title="<?php echo esc_attr( date_i18n( $date_format, $last_updated_timestamp ) ); ?>">
455
+ <?php printf( __( '%s ago', 'learnpress' ), human_time_diff( $last_updated_timestamp ) ); ?>
456
+ </span>
457
+ </div>
458
+ <div class="column-downloaded">
459
+ <?php
460
+ if ( $plugin['active_installs'] >= 1000000 ) {
461
+ $active_installs_text = _x( '1+ Million', 'Active plugin installs' );
462
+ } else {
463
+ $active_installs_text = number_format_i18n( $plugin['active_installs'] ) . '+';
464
+ }
465
+ printf( __( '%s Active Installs', 'learnpress' ), $active_installs_text );
466
+ ?>
467
+ </div>
468
+ <div class="column-compatibility">
469
+ <?php
470
+ if ( ! empty( $plugin['tested'] ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $plugin['tested'] ) ), $plugin['tested'], '>' ) ) {
471
+ echo '<span class="compatibility-untested">' . __( 'Untested with your version of WordPress', 'learnpress' ) . '</span>';
472
+ } elseif ( ! empty( $plugin['requires'] ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $plugin['requires'] ) ), $plugin['requires'], '<' ) ) {
473
+ echo '<span class="compatibility-incompatible">' . __( '<strong>Incompatible</strong> with your version of WordPress', 'learnpress' ) . '</span>';
474
+ } else {
475
+ echo '<span class="compatibility-compatible">' . __( '<strong>Compatible</strong> with your version of WordPress', 'learnpress' ) . '</span>';
476
+ }
477
+ ?>
478
+ </div>
479
+ </div>
480
+ </div>
481
+ <?php
482
+ }
483
+
484
+ // Close off the group divs of the last one
485
+ if ( ! empty( $group ) ) {
486
+ echo '</div></div>';
487
+ }
488
+ }
489
+ }
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/class-lp-upgrader.php ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class LP_Upgrader{
3
+ private $strings;
4
+ function __construct( $directories = array() ){
5
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
6
+ require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
7
+ if( ! class_exists( 'WP_Upgrader_Skin' ) ){
8
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader-skins.php' );
9
+
10
+ }
11
+
12
+ $this->strings['bad_request'] = __( 'Invalid Data provided.', 'learnpress' );
13
+ $this->strings['fs_unavailable'] = __( 'Could not access filesystem.', 'learnpress' );
14
+ $this->strings['fs_error'] = __( 'Filesystem error.', 'learnpress' );
15
+ $this->strings['fs_no_root_dir'] = __( 'Unable to locate WordPress Root directory.', 'learnpress' );
16
+ $this->strings['fs_no_content_dir'] = __( 'Unable to locate WordPress Content directory (wp-content).', 'learnpress' );
17
+ $this->strings['fs_no_plugins_dir'] = __( 'Unable to locate WordPress Plugin directory.', 'learnpress' );
18
+ $this->strings['fs_no_themes_dir'] = __( 'Unable to locate WordPress Theme directory.', 'learnpress' );
19
+ /* translators: %s: directory name */
20
+ $this->strings['fs_no_folder'] = __( 'Unable to locate needed folder (%s).', 'learnpress' );
21
+
22
+ $this->strings['download_failed'] = __( 'Download failed.', 'learnpress' );
23
+ $this->strings['installing_package'] = __( 'Installing the latest version&#8230;', 'learnpress' );
24
+ $this->strings['no_files'] = __( 'The package contains no files.', 'learnpress' );
25
+ $this->strings['folder_exists'] = __( 'Destination folder already exists.', 'learnpress' );
26
+ $this->strings['mkdir_failed'] = __( 'Could not create directory.', 'learnpress' );
27
+ $this->strings['incompatible_archive'] = __( 'The package could not be installed.', 'learnpress' );
28
+
29
+ $this->strings['maintenance_start'] = __( 'Enabling Maintenance mode&#8230;', 'learnpress' );
30
+ $this->strings['maintenance_end'] = __( 'Disabling Maintenance mode&#8230;', 'learnpress' );
31
+
32
+ $directories = wp_parse_args( $directories, array( WP_CONTENT_DIR ) );
33
+
34
+ $this->fs_connect( $directories );
35
+ }
36
+ public function download_package( $package ) {
37
+
38
+ if ( ! preg_match('!^(http|https|ftp)://!i', $package) && file_exists($package) ) //Local file or remote?
39
+ return $package; //must be a local file..
40
+
41
+ if ( empty($package) )
42
+ return new WP_Error('no_package', $this->strings['no_package']);
43
+
44
+ $download_file = download_url($package);
45
+
46
+ if ( is_wp_error($download_file) )
47
+ return new WP_Error('download_failed', $this->strings['download_failed'], $download_file->get_error_message());
48
+
49
+ return $download_file;
50
+ }
51
+
52
+ public function unpack_package( $package, $delete_package = true, $name = '' ) {
53
+ global $wp_filesystem;
54
+
55
+ $upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/learnpress/';
56
+
57
+ //Clean up contents of upgrade directory beforehand.
58
+ $upgrade_files = $wp_filesystem->dirlist($upgrade_folder);
59
+ if ( !empty($upgrade_files) ) {
60
+ foreach ( $upgrade_files as $file )
61
+ $wp_filesystem->delete($upgrade_folder . $file['name'], true);
62
+ }
63
+
64
+ // We need a working directory - Strip off any .tmp or .zip suffixes
65
+ $working_dir = $upgrade_folder . ( $name ? $name : basename( basename( $package, '.tmp' ), '.zip' ) );
66
+
67
+ // Clean up working directory
68
+ if ( $wp_filesystem->is_dir($working_dir) )
69
+ $wp_filesystem->delete($working_dir, true);
70
+
71
+ // Unzip package to working directory
72
+ $result = unzip_file( $package, $working_dir );
73
+
74
+ // Once extracted, delete the package if required.
75
+ if ( $delete_package )
76
+ unlink($package);
77
+
78
+ if ( is_wp_error($result) ) {
79
+ $wp_filesystem->delete($working_dir, true);
80
+ if ( 'incompatible_archive' == $result->get_error_code() ) {
81
+ return new WP_Error( 'incompatible_archive', '', $result->get_error_data() );
82
+ }
83
+ return $result;
84
+ }
85
+
86
+ return $working_dir;
87
+ }
88
+
89
+ function get_plugin_info( $path, $filename = '' ){
90
+ global $wp_filesystem;
91
+
92
+ $plugin_file = $filename ? basename( $path ) : $filename;
93
+ $basename = basename( basename( $plugin_file, '.tmp' ), '.zip' );
94
+
95
+ $download_path = WP_CONTENT_DIR . '/upgrade';
96
+ $download_file = $download_path . '/' . $plugin_file;
97
+ $working_dir = $download_path . '/' . $basename;
98
+ $readme = $working_dir . '/readme.txt';
99
+ if( ! file_exists( $download_file ) && ! file_exists( $readme ) ){
100
+ //$res = $this->fs_connect( array( $download_path ) );
101
+
102
+ $download_file = download_url( $path );
103
+ if( ! is_wp_error( $download_file ) ){
104
+
105
+ // Unzip package to working directory
106
+ $result = unzip_file( $download_file, $working_dir );
107
+ if( $result ) $readme = $working_dir . '/readme.txt';
108
+ unlink( $download_file );
109
+ }
110
+ }
111
+ $info = false;
112
+ if( file_exists( $readme ) ){
113
+ require_once( dirname( __FILE__ ) . '/includes/class-readme-parse.php' );
114
+ $parse = new WordPress_Readme_Parser( $readme );
115
+ $info = @$parse->parse_readme_contents( file_get_contents( $readme ) );
116
+
117
+ if( file_exists( $file = $working_dir . '/' . $basename . '.php' ) ) {
118
+ $headers = get_plugin_data( $file );
119
+ $info['name'] = $headers['Name'];
120
+ }
121
+ }
122
+ @$wp_filesystem->delete( $working_dir, true );
123
+ return $info;
124
+ }
125
+
126
+ public function fs_connect( $directories = array(), $allow_relaxed_file_ownership = false ) {
127
+ $skin = new WP_Upgrader_Skin();
128
+
129
+ global $wp_filesystem;
130
+
131
+ if ( false === ( $credentials = $skin->request_filesystem_credentials( false, $directories[0], $allow_relaxed_file_ownership ) ) ) {
132
+ return false;
133
+ }
134
+
135
+ if ( ! WP_Filesystem( $credentials, $directories[0], $allow_relaxed_file_ownership ) ) {
136
+ $error = true;
137
+ if ( is_object($wp_filesystem) && $wp_filesystem->errors->get_error_code() )
138
+ $error = $wp_filesystem->errors;
139
+ // Failed to connect, Error and request again
140
+ //$this->skin->request_filesystem_credentials( $error, $directories[0], $allow_relaxed_file_ownership );
141
+ return false;
142
+ }
143
+
144
+ if ( ! is_object($wp_filesystem) )
145
+ return new WP_Error('fs_unavailable', $this->strings['fs_unavailable'] );
146
+
147
+ if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
148
+ return new WP_Error('fs_error', $this->strings['fs_error'], $wp_filesystem->errors);
149
+
150
+ foreach ( (array)$directories as $dir ) {
151
+ switch ( $dir ) {
152
+ case ABSPATH:
153
+ if ( ! $wp_filesystem->abspath() )
154
+ return new WP_Error('fs_no_root_dir', $this->strings['fs_no_root_dir']);
155
+ break;
156
+ case WP_CONTENT_DIR:
157
+ if ( ! $wp_filesystem->wp_content_dir() )
158
+ return new WP_Error('fs_no_content_dir', $this->strings['fs_no_content_dir']);
159
+ break;
160
+ case WP_PLUGIN_DIR:
161
+ if ( ! $wp_filesystem->wp_plugins_dir() )
162
+ return new WP_Error('fs_no_plugins_dir', $this->strings['fs_no_plugins_dir']);
163
+ break;
164
+ case get_theme_root():
165
+ if ( ! $wp_filesystem->wp_themes_dir() )
166
+ return new WP_Error('fs_no_themes_dir', $this->strings['fs_no_themes_dir']);
167
+ break;
168
+ default:
169
+ if ( ! $wp_filesystem->find_folder($dir) )
170
+ return new WP_Error( 'fs_no_folder', sprintf( $this->strings['fs_no_folder'], esc_html( basename( $dir ) ) ) );
171
+ break;
172
+ }
173
+ }
174
+ return true;
175
+ } //end fs_connect();
176
+ }
inc/admin/includes/class-markdown-parse.php ADDED
@@ -0,0 +1,2932 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ #
3
+ # Markdown Extra - A text-to-HTML conversion tool for web writers
4
+ #
5
+ # PHP Markdown & Extra
6
+ # Copyright (c) 2004-2009 Michel Fortin
7
+ # <http://michelf.com/projects/php-markdown/>
8
+ #
9
+ # Original Markdown
10
+ # Copyright (c) 2004-2006 John Gruber
11
+ # <http://daringfireball.net/projects/markdown/>
12
+ #
13
+
14
+
15
+ define( 'MARKDOWN_VERSION', "1.0.1n" ); # Sat 10 Oct 2009
16
+ define( 'MARKDOWNEXTRA_VERSION', "1.2.4" ); # Sat 10 Oct 2009
17
+
18
+
19
+ #
20
+ # Global default settings:
21
+ #
22
+
23
+ # Change to ">" for HTML output
24
+ @define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX', " />");
25
+
26
+ # Define the width of a tab for code blocks.
27
+ @define( 'MARKDOWN_TAB_WIDTH', 4 );
28
+
29
+ # Optional title attribute for footnote links and backlinks.
30
+ @define( 'MARKDOWN_FN_LINK_TITLE', "" );
31
+ @define( 'MARKDOWN_FN_BACKLINK_TITLE', "" );
32
+
33
+ # Optional class attribute for footnote links and backlinks.
34
+ @define( 'MARKDOWN_FN_LINK_CLASS', "" );
35
+ @define( 'MARKDOWN_FN_BACKLINK_CLASS', "" );
36
+
37
+
38
+ #
39
+ # WordPress settings:
40
+ #
41
+
42
+ # Change to false to remove Markdown from posts and/or comments.
43
+ @define( 'MARKDOWN_WP_POSTS', true );
44
+ @define( 'MARKDOWN_WP_COMMENTS', true );
45
+
46
+
47
+
48
+ ### Standard Function Interface ###
49
+
50
+ @define( 'MARKDOWN_PARSER_CLASS', 'MarkdownExtra_Parser' );
51
+
52
+ function Markdown($text) {
53
+ #
54
+ # Initialize the parser and return the result of its transform method.
55
+ #
56
+ # Setup static parser variable.
57
+ static $parser;
58
+ if (!isset($parser)) {
59
+ $parser_class = MARKDOWN_PARSER_CLASS;
60
+ $parser = new $parser_class;
61
+ }
62
+
63
+ # Transform text using parser.
64
+ return $parser->transform($text);
65
+ }
66
+
67
+
68
+ ### WordPress Plugin Interface ###
69
+
70
+ /*
71
+ Plugin Name: Markdown Extra
72
+ Plugin URI: http://michelf.com/projects/php-markdown/
73
+ Description: <a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.com/projects/php-markdown/">More...</a>
74
+ Version: 1.2.4
75
+ Author: Michel Fortin
76
+ Author URI: http://michelf.com/
77
+ */
78
+
79
+ if (isset($wp_version)) {
80
+ # More details about how it works here:
81
+ # <http://michelf.com/weblog/2005/wordpress-text-flow-vs-markdown/>
82
+
83
+ # Post content and excerpts
84
+ # - Remove WordPress paragraph generator.
85
+ # - Run Markdown on excerpt, then remove all tags.
86
+ # - Add paragraph tag around the excerpt, but remove it for the excerpt rss.
87
+ if (MARKDOWN_WP_POSTS) {
88
+ remove_filter('the_content', 'wpautop');
89
+ remove_filter('the_content_rss', 'wpautop');
90
+ remove_filter('the_excerpt', 'wpautop');
91
+ add_filter('the_content', 'mdwp_MarkdownPost', 6);
92
+ add_filter('the_content_rss', 'mdwp_MarkdownPost', 6);
93
+ add_filter('get_the_excerpt', 'mdwp_MarkdownPost', 6);
94
+ add_filter('get_the_excerpt', 'trim', 7);
95
+ add_filter('the_excerpt', 'mdwp_add_p');
96
+ add_filter('the_excerpt_rss', 'mdwp_strip_p');
97
+
98
+ remove_filter('content_save_pre', 'balanceTags', 50);
99
+ remove_filter('excerpt_save_pre', 'balanceTags', 50);
100
+ add_filter('the_content', 'balanceTags', 50);
101
+ add_filter('get_the_excerpt', 'balanceTags', 9);
102
+ }
103
+
104
+ # Add a footnote id prefix to posts when inside a loop.
105
+ function mdwp_MarkdownPost($text) {
106
+ static $parser;
107
+ if (!$parser) {
108
+ $parser_class = MARKDOWN_PARSER_CLASS;
109
+ $parser = new $parser_class;
110
+ }
111
+ if (is_single() || is_page() || is_feed()) {
112
+ $parser->fn_id_prefix = "";
113
+ } else {
114
+ $parser->fn_id_prefix = get_the_ID() . ".";
115
+ }
116
+ return $parser->transform($text);
117
+ }
118
+
119
+ # Comments
120
+ # - Remove WordPress paragraph generator.
121
+ # - Remove WordPress auto-link generator.
122
+ # - Scramble important tags before passing them to the kses filter.
123
+ # - Run Markdown on excerpt then remove paragraph tags.
124
+ if (MARKDOWN_WP_COMMENTS) {
125
+ remove_filter('comment_text', 'wpautop', 30);
126
+ remove_filter('comment_text', 'make_clickable');
127
+ add_filter('pre_comment_content', 'Markdown', 6);
128
+ add_filter('pre_comment_content', 'mdwp_hide_tags', 8);
129
+ add_filter('pre_comment_content', 'mdwp_show_tags', 12);
130
+ add_filter('get_comment_text', 'Markdown', 6);
131
+ add_filter('get_comment_excerpt', 'Markdown', 6);
132
+ add_filter('get_comment_excerpt', 'mdwp_strip_p', 7);
133
+
134
+ global $mdwp_hidden_tags, $mdwp_placeholders;
135
+ $mdwp_hidden_tags = explode(' ',
136
+ '<p> </p> <pre> </pre> <ol> </ol> <ul> </ul> <li> </li>');
137
+ $mdwp_placeholders = explode(' ', str_rot13(
138
+ 'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '.
139
+ 'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli'));
140
+ }
141
+
142
+ function mdwp_add_p($text) {
143
+ if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) {
144
+ $text = '<p>'.$text.'</p>';
145
+ $text = preg_replace('{\n{2,}}', "</p>\n\n<p>", $text);
146
+ }
147
+ return $text;
148
+ }
149
+
150
+ function mdwp_strip_p($t) { return preg_replace('{</?p>}i', '', $t); }
151
+
152
+ function mdwp_hide_tags($text) {
153
+ global $mdwp_hidden_tags, $mdwp_placeholders;
154
+ return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text);
155
+ }
156
+ function mdwp_show_tags($text) {
157
+ global $mdwp_hidden_tags, $mdwp_placeholders;
158
+ return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text);
159
+ }
160
+ }
161
+
162
+
163
+ ### bBlog Plugin Info ###
164
+
165
+ function identify_modifier_markdown() {
166
+ return array(
167
+ 'name' => 'markdown',
168
+ 'type' => 'modifier',
169
+ 'nicename' => 'PHP Markdown Extra',
170
+ 'description' => 'A text-to-HTML conversion tool for web writers',
171
+ 'authors' => 'Michel Fortin and John Gruber',
172
+ 'licence' => 'GPL',
173
+ 'version' => MARKDOWNEXTRA_VERSION,
174
+ 'help' => '<a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.com/projects/php-markdown/">More...</a>',
175
+ );
176
+ }
177
+
178
+
179
+ ### Smarty Modifier Interface ###
180
+
181
+ function smarty_modifier_markdown($text) {
182
+ return Markdown($text);
183
+ }
184
+
185
+
186
+ ### Textile Compatibility Mode ###
187
+
188
+ # Rename this file to "classTextile.php" and it can replace Textile everywhere.
189
+
190
+ if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) {
191
+ # Try to include PHP SmartyPants. Should be in the same directory.
192
+ @include_once 'smartypants.php';
193
+ # Fake Textile class. It calls Markdown instead.
194
+ class Textile {
195
+ function TextileThis($text, $lite='', $encode='') {
196
+ if ($lite == '' && $encode == '') $text = Markdown($text);
197
+ if (function_exists('SmartyPants')) $text = SmartyPants($text);
198
+ return $text;
199
+ }
200
+ # Fake restricted version: restrictions are not supported for now.
201
+ function TextileRestricted($text, $lite='', $noimage='') {
202
+ return $this->TextileThis($text, $lite);
203
+ }
204
+ # Workaround to ensure compatibility with TextPattern 4.0.3.
205
+ function blockLite($text) { return $text; }
206
+ }
207
+ }
208
+
209
+
210
+
211
+ #
212
+ # Markdown Parser Class
213
+ #
214
+
215
+ class Markdown_Parser {
216
+
217
+ # Regex to match balanced [brackets].
218
+ # Needed to insert a maximum bracked depth while converting to PHP.
219
+ var $nested_brackets_depth = 6;
220
+ var $nested_brackets_re;
221
+
222
+ var $nested_url_parenthesis_depth = 4;
223
+ var $nested_url_parenthesis_re;
224
+
225
+ # Table of hash values for escaped characters:
226
+ var $escape_chars = '\`*_{}[]()>#+-.!';
227
+ var $escape_chars_re;
228
+
229
+ # Change to ">" for HTML output.
230
+ var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX;
231
+ var $tab_width = MARKDOWN_TAB_WIDTH;
232
+
233
+ # Change to `true` to disallow markup or entities.
234
+ var $no_markup = false;
235
+ var $no_entities = false;
236
+
237
+ # Predefined urls and titles for reference links and images.
238
+ var $predef_urls = array();
239
+ var $predef_titles = array();
240
+
241
+
242
+ function Markdown_Parser() {
243
+ #
244
+ # Constructor function. Initialize appropriate member variables.
245
+ #
246
+ $this->_initDetab();
247
+ $this->prepareItalicsAndBold();
248
+
249
+ $this->nested_brackets_re =
250
+ str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth).
251
+ str_repeat('\])*', $this->nested_brackets_depth);
252
+
253
+ $this->nested_url_parenthesis_re =
254
+ str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth).
255
+ str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth);
256
+
257
+ $this->escape_chars_re = '['.preg_quote($this->escape_chars).']';
258
+
259
+ # Sort document, block, and span gamut in ascendent priority order.
260
+ asort($this->document_gamut);
261
+ asort($this->block_gamut);
262
+ asort($this->span_gamut);
263
+ }
264
+
265
+
266
+ # Internal hashes used during transformation.
267
+ var $urls = array();
268
+ var $titles = array();
269
+ var $html_hashes = array();
270
+
271
+ # Status flag to avoid invalid nesting.
272
+ var $in_anchor = false;
273
+
274
+
275
+ function setup() {
276
+ #
277
+ # Called before the transformation process starts to setup parser
278
+ # states.
279
+ #
280
+ # Clear global hashes.
281
+ $this->urls = $this->predef_urls;
282
+ $this->titles = $this->predef_titles;
283
+ $this->html_hashes = array();
284
+
285
+ $in_anchor = false;
286
+ }
287
+
288
+ function teardown() {
289
+ #
290
+ # Called after the transformation process to clear any variable
291
+ # which may be taking up memory unnecessarly.
292
+ #
293
+ $this->urls = array();
294
+ $this->titles = array();
295
+ $this->html_hashes = array();
296
+ }
297
+
298
+
299
+ function transform($text) {
300
+ #
301
+ # Main function. Performs some preprocessing on the input text
302
+ # and pass it through the document gamut.
303
+ #
304
+ $this->setup();
305
+
306
+ # Remove UTF-8 BOM and marker character in input, if present.
307
+ $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text);
308
+
309
+ # Standardize line endings:
310
+ # DOS to Unix and Mac to Unix
311
+ $text = preg_replace('{\r\n?}', "\n", $text);
312
+
313
+ # Make sure $text ends with a couple of newlines:
314
+ $text .= "\n\n";
315
+
316
+ # Convert all tabs to spaces.
317
+ $text = $this->detab($text);
318
+
319
+ # Turn block-level HTML blocks into hash entries
320
+ $text = $this->hashHTMLBlocks($text);
321
+
322
+ # Strip any lines consisting only of spaces and tabs.
323
+ # This makes subsequent regexen easier to write, because we can
324
+ # match consecutive blank lines with /\n+/ instead of something
325
+ # contorted like /[ ]*\n+/ .
326
+ $text = preg_replace('/^[ ]+$/m', '', $text);
327
+
328
+ # Run document gamut methods.
329
+ foreach ($this->document_gamut as $method => $priority) {
330
+ $text = $this->$method($text);
331
+ }
332
+
333
+ $this->teardown();
334
+
335
+ return $text . "\n";
336
+ }
337
+
338
+ var $document_gamut = array(
339
+ # Strip link definitions, store in hashes.
340
+ "stripLinkDefinitions" => 20,
341
+
342
+ "runBasicBlockGamut" => 30,
343
+ );
344
+
345
+
346
+ function stripLinkDefinitions($text) {
347
+ #
348
+ # Strips link definitions from text, stores the URLs and titles in
349
+ # hash references.
350
+ #
351
+ $less_than_tab = $this->tab_width - 1;
352
+
353
+ # Link defs are in the form: ^[id]: url "optional title"
354
+ $text = preg_replace_callback('{
355
+ ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1
356
+ [ ]*
357
+ \n? # maybe *one* newline
358
+ [ ]*
359
+ (?:
360
+ <(.+?)> # url = $2
361
+ |
362
+ (\S+?) # url = $3
363
+ )
364
+ [ ]*
365
+ \n? # maybe one newline
366
+ [ ]*
367
+ (?:
368
+ (?<=\s) # lookbehind for whitespace
369
+ ["(]
370
+ (.*?) # title = $4
371
+ [")]
372
+ [ ]*
373
+ )? # title is optional
374
+ (?:\n+|\Z)
375
+ }xm',
376
+ array(&$this, '_stripLinkDefinitions_callback'),
377
+ $text);
378
+ return $text;
379
+ }
380
+ function _stripLinkDefinitions_callback($matches) {
381
+ $link_id = strtolower($matches[1]);
382
+ $url = $matches[2] == '' ? $matches[3] : $matches[2];
383
+ $this->urls[$link_id] = $url;
384
+ $this->titles[$link_id] =& $matches[4];
385
+ return ''; # String that will replace the block
386
+ }
387
+
388
+
389
+ function hashHTMLBlocks($text) {
390
+ if ($this->no_markup) return $text;
391
+
392
+ $less_than_tab = $this->tab_width - 1;
393
+
394
+ # Hashify HTML blocks:
395
+ # We only want to do this for block-level HTML tags, such as headers,
396
+ # lists, and tables. That's because we still want to wrap <p>s around
397
+ # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
398
+ # phrase emphasis, and spans. The list of tags we're looking for is
399
+ # hard-coded:
400
+ #
401
+ # * List "a" is made of tags which can be both inline or block-level.
402
+ # These will be treated block-level when the start tag is alone on
403
+ # its line, otherwise they're not matched here and will be taken as
404
+ # inline later.
405
+ # * List "b" is made of tags which are always block-level;
406
+ #
407
+ $block_tags_a_re = 'ins|del';
408
+ $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'.
409
+ 'script|noscript|form|fieldset|iframe|math';
410
+
411
+ # Regular expression for the content of a block tag.
412
+ $nested_tags_level = 4;
413
+ $attr = '
414
+ (?> # optional tag attributes
415
+ \s # starts with whitespace
416
+ (?>
417
+ [^>"/]+ # text outside quotes
418
+ |
419
+ /+(?!>) # slash not followed by ">"
420
+ |
421
+ "[^"]*" # text inside double quotes (tolerate ">")
422
+ |
423
+ \'[^\']*\' # text inside single quotes (tolerate ">")
424
+ )*
425
+ )?
426
+ ';
427
+ $content =
428
+ str_repeat('
429
+ (?>
430
+ [^<]+ # content without tag
431
+ |
432
+ <\2 # nested opening tag
433
+ '.$attr.' # attributes
434
+ (?>
435
+ />
436
+ |
437
+ >', $nested_tags_level). # end of opening tag
438
+ '.*?'. # last level nested tag content
439
+ str_repeat('
440
+ </\2\s*> # closing nested tag
441
+ )
442
+ |
443
+ <(?!/\2\s*> # other tags with a different name
444
+ )
445
+ )*',
446
+ $nested_tags_level);
447
+ $content2 = str_replace('\2', '\3', $content);
448
+
449
+ # First, look for nested blocks, e.g.:
450
+ # <div>
451
+ # <div>
452
+ # tags for inner block must be indented.
453
+ # </div>
454
+ # </div>
455
+ #
456
+ # The outermost tags must start at the left margin for this to match, and
457
+ # the inner nested divs must be indented.
458
+ # We need to do this before the next, more liberal match, because the next
459
+ # match will start at the first `<div>` and stop at the first `</div>`.
460
+ $text = preg_replace_callback('{(?>
461
+ (?>
462
+ (?<=\n\n) # Starting after a blank line
463
+ | # or
464
+ \A\n? # the beginning of the doc
465
+ )
466
+ ( # save in $1
467
+
468
+ # Match from `\n<tag>` to `</tag>\n`, handling nested tags
469
+ # in between.
470
+
471
+ [ ]{0,'.$less_than_tab.'}
472
+ <('.$block_tags_b_re.')# start tag = $2
473
+ '.$attr.'> # attributes followed by > and \n
474
+ '.$content.' # content, support nesting
475
+ </\2> # the matching end tag
476
+ [ ]* # trailing spaces/tabs
477
+ (?=\n+|\Z) # followed by a newline or end of document
478
+
479
+ | # Special version for tags of group a.
480
+
481
+ [ ]{0,'.$less_than_tab.'}
482
+ <('.$block_tags_a_re.')# start tag = $3
483
+ '.$attr.'>[ ]*\n # attributes followed by >
484
+ '.$content2.' # content, support nesting
485
+ </\3> # the matching end tag
486
+ [ ]* # trailing spaces/tabs
487
+ (?=\n+|\Z) # followed by a newline or end of document
488
+
489
+ | # Special case just for <hr />. It was easier to make a special
490
+ # case than to make the other regex more complicated.
491
+
492
+ [ ]{0,'.$less_than_tab.'}
493
+ <(hr) # start tag = $2
494
+ '.$attr.' # attributes
495
+ /?> # the matching end tag
496
+ [ ]*
497
+ (?=\n{2,}|\Z) # followed by a blank line or end of document
498
+
499
+ | # Special case for standalone HTML comments:
500
+
501
+ [ ]{0,'.$less_than_tab.'}
502
+ (?s:
503
+ <!-- .*? -->
504
+ )
505
+ [ ]*
506
+ (?=\n{2,}|\Z) # followed by a blank line or end of document
507
+
508
+ | # PHP and ASP-style processor instructions (<? and <%)
509
+
510
+ [ ]{0,'.$less_than_tab.'}
511
+ (?s:
512
+ <([?%]) # $2
513
+ .*?
514
+ \2>
515
+ )
516
+ [ ]*
517
+ (?=\n{2,}|\Z) # followed by a blank line or end of document
518
+
519
+ )
520
+ )}Sxmi',
521
+ array(&$this, '_hashHTMLBlocks_callback'),
522
+ $text);
523
+
524
+ return $text;
525
+ }
526
+ function _hashHTMLBlocks_callback($matches) {
527
+ $text = $matches[1];
528
+ $key = $this->hashBlock($text);
529
+ return "\n\n$key\n\n";
530
+ }
531
+
532
+
533
+ function hashPart($text, $boundary = 'X') {
534
+ #
535
+ # Called whenever a tag must be hashed when a function insert an atomic
536
+ # element in the text stream. Passing $text to through this function gives
537
+ # a unique text-token which will be reverted back when calling unhash.
538
+ #
539
+ # The $boundary argument specify what character should be used to surround
540
+ # the token. By convension, "B" is used for block elements that needs not
541
+ # to be wrapped into paragraph tags at the end, ":" is used for elements
542
+ # that are word separators and "X" is used in the general case.
543
+ #
544
+ # Swap back any tag hash found in $text so we do not have to `unhash`
545
+ # multiple times at the end.
546
+ $text = $this->unhash($text);
547
+
548
+ # Then hash the block.
549
+ static $i = 0;
550
+ $key = "$boundary\x1A" . ++$i . $boundary;
551
+ $this->html_hashes[$key] = $text;
552
+ return $key; # String that will replace the tag.
553
+ }
554
+
555
+
556
+ function hashBlock($text) {
557
+ #
558
+ # Shortcut function for hashPart with block-level boundaries.
559
+ #
560
+ return $this->hashPart($text, 'B');
561
+ }
562
+
563
+
564
+ var $block_gamut = array(
565
+ #
566
+ # These are all the transformations that form block-level
567
+ # tags like paragraphs, headers, and list items.
568
+ #
569
+ "doHeaders" => 10,
570
+ "doHorizontalRules" => 20,
571
+
572
+ "doLists" => 40,
573
+ "doCodeBlocks" => 50,
574
+ "doBlockQuotes" => 60,
575
+ );
576
+
577
+ function runBlockGamut($text) {
578
+ #
579
+ # Run block gamut tranformations.
580
+ #
581
+ # We need to escape raw HTML in Markdown source before doing anything
582
+ # else. This need to be done for each block, and not only at the
583
+ # begining in the Markdown function since hashed blocks can be part of
584
+ # list items and could have been indented. Indented blocks would have
585
+ # been seen as a code block in a previous pass of hashHTMLBlocks.
586
+ $text = $this->hashHTMLBlocks($text);
587
+
588
+ return $this->runBasicBlockGamut($text);
589
+ }
590
+
591
+ function runBasicBlockGamut($text) {
592
+ #
593
+ # Run block gamut tranformations, without hashing HTML blocks. This is
594
+ # useful when HTML blocks are known to be already hashed, like in the first
595
+ # whole-document pass.
596
+ #
597
+ foreach ($this->block_gamut as $method => $priority) {
598
+ $text = $this->$method($text);
599
+ }
600
+
601
+ # Finally form paragraph and restore hashed blocks.
602
+ $text = $this->formParagraphs($text);
603
+
604
+ return $text;
605
+ }
606
+
607
+
608
+ function doHorizontalRules($text) {
609
+ # Do Horizontal Rules:
610
+ return preg_replace(
611
+ '{
612
+ ^[ ]{0,3} # Leading space
613
+ ([-*_]) # $1: First marker
614
+ (?> # Repeated marker group
615
+ [ ]{0,2} # Zero, one, or two spaces.
616
+ \1 # Marker character
617
+ ){2,} # Group repeated at least twice
618
+ [ ]* # Tailing spaces
619
+ $ # End of line.
620
+ }mx',
621
+ "\n".$this->hashBlock("<hr$this->empty_element_suffix")."\n",
622
+ $text);
623
+ }
624
+
625
+
626
+ var $span_gamut = array(
627
+ #
628
+ # These are all the transformations that occur *within* block-level
629
+ # tags like paragraphs, headers, and list items.
630
+ #
631
+ # Process character escapes, code spans, and inline HTML
632
+ # in one shot.
633
+ "parseSpan" => -30,
634
+
635
+ # Process anchor and image tags. Images must come first,
636
+ # because ![foo][f] looks like an anchor.
637
+ "doImages" => 10,
638
+ "doAnchors" => 20,
639
+
640
+ # Make links out of things like `<http://example.com/>`
641
+ # Must come after doAnchors, because you can use < and >
642
+ # delimiters in inline links like [this](<url>).
643
+ "doAutoLinks" => 30,
644
+ "encodeAmpsAndAngles" => 40,
645
+
646
+ "doItalicsAndBold" => 50,
647
+ "doHardBreaks" => 60,
648
+ );
649
+
650
+ function runSpanGamut($text) {
651
+ #
652
+ # Run span gamut tranformations.
653
+ #
654
+ foreach ($this->span_gamut as $method => $priority) {
655
+ $text = $this->$method($text);
656
+ }
657
+
658
+ return $text;
659
+ }
660
+
661
+
662
+ function doHardBreaks($text) {
663
+ # Do hard breaks:
664
+ return preg_replace_callback('/ {2,}\n/',
665
+ array(&$this, '_doHardBreaks_callback'), $text);
666
+ }
667
+ function _doHardBreaks_callback($matches) {
668
+ return $this->hashPart("<br$this->empty_element_suffix\n");
669
+ }
670
+
671
+
672
+ function doAnchors($text) {
673
+ #
674
+ # Turn Markdown link shortcuts into XHTML <a> tags.
675
+ #
676
+ if ($this->in_anchor) return $text;
677
+ $this->in_anchor = true;
678
+
679
+ #
680
+ # First, handle reference-style links: [link text] [id]
681
+ #
682
+ $text = preg_replace_callback('{
683
+ ( # wrap whole match in $1
684
+ \[
685
+ ('.$this->nested_brackets_re.') # link text = $2
686
+ \]
687
+
688
+ [ ]? # one optional space
689
+ (?:\n[ ]*)? # one optional newline followed by spaces
690
+
691
+ \[
692
+ (.*?) # id = $3
693
+ \]
694
+ )
695
+ }xs',
696
+ array(&$this, '_doAnchors_reference_callback'), $text);
697
+
698
+ #
699
+ # Next, inline-style links: [link text](url "optional title")
700
+ #
701
+ $text = preg_replace_callback('{
702
+ ( # wrap whole match in $1
703
+ \[
704
+ ('.$this->nested_brackets_re.') # link text = $2
705
+ \]
706
+ \( # literal paren
707
+ [ \n]*
708
+ (?:
709
+ <(.+?)> # href = $3
710
+ |
711
+ ('.$this->nested_url_parenthesis_re.') # href = $4
712
+ )
713
+ [ \n]*
714
+ ( # $5
715
+ ([\'"]) # quote char = $6
716
+ (.*?) # Title = $7
717
+ \6 # matching quote
718
+ [ \n]* # ignore any spaces/tabs between closing quote and )
719
+ )? # title is optional
720
+ \)
721
+ )
722
+ }xs',
723
+ array(&$this, '_doAnchors_inline_callback'), $text);
724
+
725
+ #
726
+ # Last, handle reference-style shortcuts: [link text]
727
+ # These must come last in case you've also got [link text][1]
728
+ # or [link text](/foo)
729
+ #
730
+ $text = preg_replace_callback('{
731
+ ( # wrap whole match in $1
732
+ \[
733
+ ([^\[\]]+) # link text = $2; can\'t contain [ or ]
734
+ \]
735
+ )
736
+ }xs',
737
+ array(&$this, '_doAnchors_reference_callback'), $text);
738
+
739
+ $this->in_anchor = false;
740
+ return $text;
741
+ }
742
+ function _doAnchors_reference_callback($matches) {
743
+ $whole_match = $matches[1];
744
+ $link_text = $matches[2];
745
+ $link_id =& $matches[3];
746
+
747
+ if ($link_id == "") {
748
+ # for shortcut links like [this][] or [this].
749
+ $link_id = $link_text;
750
+ }
751
+
752
+ # lower-case and turn embedded newlines into spaces
753
+ $link_id = strtolower($link_id);
754
+ $link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
755
+
756
+ if (isset($this->urls[$link_id])) {
757
+ $url = $this->urls[$link_id];
758
+ $url = $this->encodeAttribute($url);
759
+
760
+ $result = "<a href=\"$url\"";
761
+ if ( isset( $this->titles[$link_id] ) ) {
762
+ $title = $this->titles[$link_id];
763
+ $title = $this->encodeAttribute($title);
764
+ $result .= " title=\"$title\"";
765
+ }
766
+
767
+ $link_text = $this->runSpanGamut($link_text);
768
+ $result .= ">$link_text</a>";
769
+ $result = $this->hashPart($result);
770
+ }
771
+ else {
772
+ $result = $whole_match;
773
+ }
774
+ return $result;
775
+ }
776
+ function _doAnchors_inline_callback($matches) {
777
+ $whole_match = $matches[1];
778
+ $link_text = $this->runSpanGamut($matches[2]);
779
+ $url = $matches[3] == '' ? $matches[4] : $matches[3];
780
+ $title =& $matches[7];
781
+
782
+ $url = $this->encodeAttribute($url);
783
+
784
+ $result = "<a href=\"$url\"";
785
+ if (isset($title)) {
786
+ $title = $this->encodeAttribute($title);
787
+ $result .= " title=\"$title\"";
788
+ }
789
+
790
+ $link_text = $this->runSpanGamut($link_text);
791
+ $result .= ">$link_text</a>";
792
+
793
+ return $this->hashPart($result);
794
+ }
795
+
796
+
797
+ function doImages($text) {
798
+ #
799
+ # Turn Markdown image shortcuts into <img> tags.
800
+ #
801
+ #
802
+ # First, handle reference-style labeled images: ![alt text][id]
803
+ #
804
+ $text = preg_replace_callback('{
805
+ ( # wrap whole match in $1
806
+ !\[
807
+ ('.$this->nested_brackets_re.') # alt text = $2
808
+ \]
809
+
810
+ [ ]? # one optional space
811
+ (?:\n[ ]*)? # one optional newline followed by spaces
812
+
813
+ \[
814
+ (.*?) # id = $3
815
+ \]
816
+
817
+ )
818
+ }xs',
819
+ array(&$this, '_doImages_reference_callback'), $text);
820
+
821
+ #
822
+ # Next, handle inline images: ![alt text](url "optional title")
823
+ # Don't forget: encode * and _
824
+ #
825
+ $text = preg_replace_callback('{
826
+ ( # wrap whole match in $1
827
+ !\[
828
+ ('.$this->nested_brackets_re.') # alt text = $2
829
+ \]
830
+ \s? # One optional whitespace character
831
+ \( # literal paren
832
+ [ \n]*
833
+ (?:
834
+ <(\S*)> # src url = $3
835
+ |
836
+ ('.$this->nested_url_parenthesis_re.') # src url = $4
837
+ )
838
+ [ \n]*
839
+ ( # $5
840
+ ([\'"]) # quote char = $6
841
+ (.*?) # title = $7
842
+ \6 # matching quote
843
+ [ \n]*
844
+ )? # title is optional
845
+ \)
846
+ )
847
+ }xs',
848
+ array(&$this, '_doImages_inline_callback'), $text);
849
+
850
+ return $text;
851
+ }
852
+ function _doImages_reference_callback($matches) {
853
+ $whole_match = $matches[1];
854
+ $alt_text = $matches[2];
855
+ $link_id = strtolower($matches[3]);
856
+
857
+ if ($link_id == "") {
858
+ $link_id = strtolower($alt_text); # for shortcut links like ![this][].
859
+ }
860
+
861
+ $alt_text = $this->encodeAttribute($alt_text);
862
+ if (isset($this->urls[$link_id])) {
863
+ $url = $this->encodeAttribute($this->urls[$link_id]);
864
+ $result = "<img src=\"$url\" alt=\"$alt_text\"";
865
+ if (isset($this->titles[$link_id])) {
866
+ $title = $this->titles[$link_id];
867
+ $title = $this->encodeAttribute($title);
868
+ $result .= " title=\"$title\"";
869
+ }
870
+ $result .= $this->empty_element_suffix;
871
+ $result = $this->hashPart($result);
872
+ }
873
+ else {
874
+ # If there's no such link ID, leave intact:
875
+ $result = $whole_match;
876
+ }
877
+
878
+ return $result;
879
+ }
880
+ function _doImages_inline_callback($matches) {
881
+ $whole_match = $matches[1];
882
+ $alt_text = $matches[2];
883
+ $url = $matches[3] == '' ? $matches[4] : $matches[3];
884
+ $title =& $matches[7];
885
+
886
+ $alt_text = $this->encodeAttribute($alt_text);
887
+ $url = $this->encodeAttribute($url);
888
+ $result = "<img src=\"$url\" alt=\"$alt_text\"";
889
+ if (isset($title)) {
890
+ $title = $this->encodeAttribute($title);
891
+ $result .= " title=\"$title\""; # $title already quoted
892
+ }
893
+ $result .= $this->empty_element_suffix;
894
+
895
+ return $this->hashPart($result);
896
+ }
897
+
898
+
899
+ function doHeaders($text) {
900
+ # Setext-style headers:
901
+ # Header 1
902
+ # ========
903
+ #
904
+ # Header 2
905
+ # --------
906
+ #
907
+ $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
908
+ array(&$this, '_doHeaders_callback_setext'), $text);
909
+
910
+ # atx-style headers:
911
+ # # Header 1
912
+ # ## Header 2
913
+ # ## Header 2 with closing hashes ##
914
+ # ...
915
+ # ###### Header 6
916
+ #
917
+ $text = preg_replace_callback('{
918
+ ^(\#{1,6}) # $1 = string of #\'s
919
+ [ ]*
920
+ (.+?) # $2 = Header text
921
+ [ ]*
922
+ \#* # optional closing #\'s (not counted)
923
+ \n+
924
+ }xm',
925
+ array(&$this, '_doHeaders_callback_atx'), $text);
926
+
927
+ return $text;
928
+ }
929
+ function _doHeaders_callback_setext($matches) {
930
+ # Terrible hack to check we haven't found an empty list item.
931
+ if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1]))
932
+ return $matches[0];
933
+
934
+ $level = $matches[2]{0} == '=' ? 1 : 2;
935
+ $block = "<h$level>".$this->runSpanGamut($matches[1])."</h$level>";
936
+ return "\n" . $this->hashBlock($block) . "\n\n";
937
+ }
938
+ function _doHeaders_callback_atx($matches) {
939
+ $level = strlen($matches[1]);
940
+ $block = "<h$level>".$this->runSpanGamut($matches[2])."</h$level>";
941
+ return "\n" . $this->hashBlock($block) . "\n\n";
942
+ }
943
+
944
+
945
+ function doLists($text) {
946
+ #
947
+ # Form HTML ordered (numbered) and unordered (bulleted) lists.
948
+ #
949
+ $less_than_tab = $this->tab_width - 1;
950
+
951
+ # Re-usable patterns to match list item bullets and number markers:
952
+ $marker_ul_re = '[*+-]';
953
+ $marker_ol_re = '\d+[.]';
954
+ $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
955
+
956
+ $markers_relist = array(
957
+ $marker_ul_re => $marker_ol_re,
958
+ $marker_ol_re => $marker_ul_re,
959
+ );
960
+
961
+ foreach ($markers_relist as $marker_re => $other_marker_re) {
962
+ # Re-usable pattern to match any entirel ul or ol list:
963
+ $whole_list_re = '
964
+ ( # $1 = whole list
965
+ ( # $2
966
+ ([ ]{0,'.$less_than_tab.'}) # $3 = number of spaces
967
+ ('.$marker_re.') # $4 = first list item marker
968
+ [ ]+
969
+ )
970
+ (?s:.+?)
971
+ ( # $5
972
+ \z
973
+ |
974
+ \n{2,}
975
+ (?=\S)
976
+ (?! # Negative lookahead for another list item marker
977
+ [ ]*
978
+ '.$marker_re.'[ ]+
979
+ )
980
+ |
981
+ (?= # Lookahead for another kind of list
982
+ \n
983
+ \3 # Must have the same indentation
984
+ '.$other_marker_re.'[ ]+
985
+ )
986
+ )
987
+ )
988
+ '; // mx
989
+
990
+ # We use a different prefix before nested lists than top-level lists.
991
+ # See extended comment in _ProcessListItems().
992
+
993
+ if ($this->list_level) {
994
+ $text = preg_replace_callback('{
995
+ ^
996
+ '.$whole_list_re.'
997
+ }mx',
998
+ array(&$this, '_doLists_callback'), $text);
999
+ }
1000
+ else {
1001
+ $text = preg_replace_callback('{
1002
+ (?:(?<=\n)\n|\A\n?) # Must eat the newline
1003
+ '.$whole_list_re.'
1004
+ }mx',
1005
+ array(&$this, '_doLists_callback'), $text);
1006
+ }
1007
+ }
1008
+
1009
+ return $text;
1010
+ }
1011
+ function _doLists_callback($matches) {
1012
+ # Re-usable patterns to match list item bullets and number markers:
1013
+ $marker_ul_re = '[*+-]';
1014
+ $marker_ol_re = '\d+[.]';
1015
+ $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
1016
+
1017
+ $list = $matches[1];
1018
+ $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol";
1019
+
1020
+ $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
1021
+
1022
+ $list .= "\n";
1023
+ $result = $this->processListItems($list, $marker_any_re);
1024
+
1025
+ $result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>");
1026
+ return "\n". $result ."\n\n";
1027
+ }
1028
+
1029
+ var $list_level = 0;
1030
+
1031
+ function processListItems($list_str, $marker_any_re) {
1032
+ #
1033
+ # Process the contents of a single ordered or unordered list, splitting it
1034
+ # into individual list items.
1035
+ #
1036
+ # The $this->list_level global keeps track of when we're inside a list.
1037
+ # Each time we enter a list, we increment it; when we leave a list,
1038
+ # we decrement. If it's zero, we're not in a list anymore.
1039
+ #
1040
+ # We do this because when we're not inside a list, we want to treat
1041
+ # something like this:
1042
+ #
1043
+ # I recommend upgrading to version
1044
+ # 8. Oops, now this line is treated
1045
+ # as a sub-list.
1046
+ #
1047
+ # As a single paragraph, despite the fact that the second line starts
1048
+ # with a digit-period-space sequence.
1049
+ #
1050
+ # Whereas when we're inside a list (or sub-list), that line will be
1051
+ # treated as the start of a sub-list. What a kludge, huh? This is
1052
+ # an aspect of Markdown's syntax that's hard to parse perfectly
1053
+ # without resorting to mind-reading. Perhaps the solution is to
1054
+ # change the syntax rules such that sub-lists must start with a
1055
+ # starting cardinal number; e.g. "1." or "a.".
1056
+
1057
+ $this->list_level++;
1058
+
1059
+ # trim trailing blank lines:
1060
+ $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
1061
+
1062
+ $list_str = preg_replace_callback('{
1063
+ (\n)? # leading line = $1
1064
+ (^[ ]*) # leading whitespace = $2
1065
+ ('.$marker_any_re.' # list marker and space = $3
1066
+ (?:[ ]+|(?=\n)) # space only required if item is not empty
1067
+ )
1068
+ ((?s:.*?)) # list item text = $4
1069
+ (?:(\n+(?=\n))|\n) # tailing blank line = $5
1070
+ (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))
1071
+ }xm',
1072
+ array(&$this, '_processListItems_callback'), $list_str);
1073
+
1074
+ $this->list_level--;
1075
+ return $list_str;
1076
+ }
1077
+ function _processListItems_callback($matches) {
1078
+ $item = $matches[4];
1079
+ $leading_line =& $matches[1];
1080
+ $leading_space =& $matches[2];
1081
+ $marker_space = $matches[3];
1082
+ $tailing_blank_line =& $matches[5];
1083
+
1084
+ if ($leading_line || $tailing_blank_line ||
1085
+ preg_match('/\n{2,}/', $item))
1086
+ {
1087
+ # Replace marker with the appropriate whitespace indentation
1088
+ $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
1089
+ $item = $this->runBlockGamut($this->outdent($item)."\n");
1090
+ }
1091
+ else {
1092
+ # Recursion for sub-lists:
1093
+ $item = $this->doLists($this->outdent($item));
1094
+ $item = preg_replace('/\n+$/', '', $item);
1095
+ $item = $this->runSpanGamut($item);
1096
+ }
1097
+
1098
+ return "<li>" . $item . "</li>\n";
1099
+ }
1100
+
1101
+
1102
+ function doCodeBlocks($text) {
1103
+ #
1104
+ # Process Markdown `<pre><code>` blocks.
1105
+ #
1106
+ $text = preg_replace_callback('{
1107
+ (?:\n\n|\A\n?)
1108
+ ( # $1 = the code block -- one or more lines, starting with a space/tab
1109
+ (?>
1110
+ [ ]{'.$this->tab_width.'} # Lines must start with a tab or a tab-width of spaces
1111
+ .*\n+
1112
+ )+
1113
+ )
1114
+ ((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
1115
+ }xm',
1116
+ array(&$this, '_doCodeBlocks_callback'), $text);
1117
+
1118
+ return $text;
1119
+ }
1120
+ function _doCodeBlocks_callback($matches) {
1121
+ $codeblock = $matches[1];
1122
+
1123
+ $codeblock = $this->outdent($codeblock);
1124
+ $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
1125
+
1126
+ # trim leading newlines and trailing newlines
1127
+ $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
1128
+
1129
+ $codeblock = "<pre><code>$codeblock\n</code></pre>";
1130
+ return "\n\n".$this->hashBlock($codeblock)."\n\n";
1131
+ }
1132
+
1133
+
1134
+ function makeCodeSpan($code) {
1135
+ #
1136
+ # Create a code span markup for $code. Called from handleSpanToken.
1137
+ #
1138
+ $code = htmlspecialchars(trim($code), ENT_NOQUOTES);
1139
+ return $this->hashPart("<code>$code</code>");
1140
+ }
1141
+
1142
+
1143
+ var $em_relist = array(
1144
+ '' => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?=\S|$)(?![.,:;]\s)',
1145
+ '*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
1146
+ '_' => '(?<=\S|^)(?<!_)_(?!_)',
1147
+ );
1148
+ var $strong_relist = array(
1149
+ '' => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?=\S|$)(?![.,:;]\s)',
1150
+ '**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
1151
+ '__' => '(?<=\S|^)(?<!_)__(?!_)',
1152
+ );
1153
+ var $em_strong_relist = array(
1154
+ '' => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?=\S|$)(?![.,:;]\s)',
1155
+ '***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
1156
+ '___' => '(?<=\S|^)(?<!_)___(?!_)',
1157
+ );
1158
+ var $em_strong_prepared_relist;
1159
+
1160
+ function prepareItalicsAndBold() {
1161
+ #
1162
+ # Prepare regular expressions for searching emphasis tokens in any
1163
+ # context.
1164
+ #
1165
+ foreach ($this->em_relist as $em => $em_re) {
1166
+ foreach ($this->strong_relist as $strong => $strong_re) {
1167
+ # Construct list of allowed token expressions.
1168
+ $token_relist = array();
1169
+ if (isset($this->em_strong_relist["$em$strong"])) {
1170
+ $token_relist[] = $this->em_strong_relist["$em$strong"];
1171
+ }
1172
+ $token_relist[] = $em_re;
1173
+ $token_relist[] = $strong_re;
1174
+
1175
+ # Construct master expression from list.
1176
+ $token_re = '{('. implode('|', $token_relist) .')}';
1177
+ $this->em_strong_prepared_relist["$em$strong"] = $token_re;
1178
+ }
1179
+ }
1180
+ }
1181
+
1182
+ function doItalicsAndBold($text) {
1183
+ $token_stack = array('');
1184
+ $text_stack = array('');
1185
+ $em = '';
1186
+ $strong = '';
1187
+ $tree_char_em = false;
1188
+
1189
+ while (1) {
1190
+ #
1191
+ # Get prepared regular expression for seraching emphasis tokens
1192
+ # in current context.
1193
+ #
1194
+ $token_re = $this->em_strong_prepared_relist["$em$strong"];
1195
+
1196
+ #
1197
+ # Each loop iteration search for the next emphasis token.
1198
+ # Each token is then passed to handleSpanToken.
1199
+ #
1200
+ $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
1201
+ $text_stack[0] .= $parts[0];
1202
+ $token =& $parts[1];
1203
+ $text =& $parts[2];
1204
+
1205
+ if (empty($token)) {
1206
+ # Reached end of text span: empty stack without emitting.
1207
+ # any more emphasis.
1208
+ while ($token_stack[0]) {
1209
+ $text_stack[1] .= array_shift($token_stack);
1210
+ $text_stack[0] .= array_shift($text_stack);
1211
+ }
1212
+ break;
1213
+ }
1214
+
1215
+ $token_len = strlen($token);
1216
+ if ($tree_char_em) {
1217
+ # Reached closing marker while inside a three-char emphasis.
1218
+ if ($token_len == 3) {
1219
+ # Three-char closing marker, close em and strong.
1220
+ array_shift($token_stack);
1221
+ $span = array_shift($text_stack);
1222
+ $span = $this->runSpanGamut($span);
1223
+ $span = "<strong><em>$span</em></strong>";
1224
+ $text_stack[0] .= $this->hashPart($span);
1225
+ $em = '';
1226
+ $strong = '';
1227
+ } else {
1228
+ # Other closing marker: close one em or strong and
1229
+ # change current token state to match the other
1230
+ $token_stack[0] = str_repeat($token{0}, 3-$token_len);
1231
+ $tag = $token_len == 2 ? "strong" : "em";
1232
+ $span = $text_stack[0];
1233
+ $span = $this->runSpanGamut($span);
1234
+ $span = "<$tag>$span</$tag>";
1235
+ $text_stack[0] = $this->hashPart($span);
1236
+ $$tag = ''; # $$tag stands for $em or $strong
1237
+ }
1238
+ $tree_char_em = false;
1239
+ } else if ($token_len == 3) {
1240
+ if ($em) {
1241
+ # Reached closing marker for both em and strong.
1242
+ # Closing strong marker:
1243
+ for ($i = 0; $i < 2; ++$i) {
1244
+ $shifted_token = array_shift($token_stack);
1245
+ $tag = strlen($shifted_token) == 2 ? "strong" : "em";
1246
+ $span = array_shift($text_stack);
1247
+ $span = $this->runSpanGamut($span);
1248
+ $span = "<$tag>$span</$tag>";
1249
+ $text_stack[0] .= $this->hashPart($span);
1250
+ $$tag = ''; # $$tag stands for $em or $strong
1251
+ }
1252
+ } else {
1253
+ # Reached opening three-char emphasis marker. Push on token
1254
+ # stack; will be handled by the special condition above.
1255
+ $em = $token{0};
1256
+ $strong = "$em$em";
1257
+ array_unshift($token_stack, $token);
1258
+ array_unshift($text_stack, '');
1259
+ $tree_char_em = true;
1260
+ }
1261
+ } else if ($token_len == 2) {
1262
+ if ($strong) {
1263
+ # Unwind any dangling emphasis marker:
1264
+ if (strlen($token_stack[0]) == 1) {
1265
+ $text_stack[1] .= array_shift($token_stack);
1266
+ $text_stack[0] .= array_shift($text_stack);
1267
+ }
1268
+ # Closing strong marker:
1269
+ array_shift($token_stack);
1270
+ $span = array_shift($text_stack);
1271
+ $span = $this->runSpanGamut($span);
1272
+ $span = "<strong>$span</strong>";
1273
+ $text_stack[0] .= $this->hashPart($span);
1274
+ $strong = '';
1275
+ } else {
1276
+ array_unshift($token_stack, $token);
1277
+ array_unshift($text_stack, '');
1278
+ $strong = $token;
1279
+ }
1280
+ } else {
1281
+ # Here $token_len == 1
1282
+ if ($em) {
1283
+ if (strlen($token_stack[0]) == 1) {
1284
+ # Closing emphasis marker:
1285
+ array_shift($token_stack);
1286
+ $span = array_shift($text_stack);
1287
+ $span = $this->runSpanGamut($span);
1288
+ $span = "<em>$span</em>";
1289
+ $text_stack[0] .= $this->hashPart($span);
1290
+ $em = '';
1291
+ } else {
1292
+ $text_stack[0] .= $token;
1293
+ }
1294
+ } else {
1295
+ array_unshift($token_stack, $token);
1296
+ array_unshift($text_stack, '');
1297
+ $em = $token;
1298
+ }
1299
+ }
1300
+ }
1301
+ return $text_stack[0];
1302
+ }
1303
+
1304
+
1305
+ function doBlockQuotes($text) {
1306
+ $text = preg_replace_callback('/
1307
+ ( # Wrap whole match in $1
1308
+ (?>
1309
+ ^[ ]*>[ ]? # ">" at the start of a line
1310
+ .+\n # rest of the first line
1311
+ (.+\n)* # subsequent consecutive lines
1312
+ \n* # blanks
1313
+ )+
1314
+ )
1315
+ /xm',
1316
+ array(&$this, '_doBlockQuotes_callback'), $text);
1317
+
1318
+ return $text;
1319
+ }
1320
+ function _doBlockQuotes_callback($matches) {
1321
+ $bq = $matches[1];
1322
+ # trim one level of quoting - trim whitespace-only lines
1323
+ $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
1324
+ $bq = $this->runBlockGamut($bq); # recurse
1325
+
1326
+ $bq = preg_replace('/^/m', " ", $bq);
1327
+ # These leading spaces cause problem with <pre> content,
1328
+ # so we need to fix that:
1329
+ $bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx',
1330
+ array(&$this, '_doBlockQuotes_callback2'), $bq);
1331
+
1332
+ return "\n". $this->hashBlock("<blockquote>\n$bq\n</blockquote>")."\n\n";
1333
+ }
1334
+ function _doBlockQuotes_callback2($matches) {
1335
+ $pre = $matches[1];
1336
+ $pre = preg_replace('/^ /m', '', $pre);
1337
+ return $pre;
1338
+ }
1339
+
1340
+
1341
+ function formParagraphs($text) {
1342
+ #
1343
+ # Params:
1344
+ # $text - string to process with html <p> tags
1345
+ #
1346
+ # Strip leading and trailing lines:
1347
+ $text = preg_replace('/\A\n+|\n+\z/', '', $text);
1348
+
1349
+ $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
1350
+
1351
+ #
1352
+ # Wrap <p> tags and unhashify HTML blocks
1353
+ #
1354
+ foreach ($grafs as $key => $value) {
1355
+ if (!preg_match('/^B\x1A[0-9]+B$/', $value)) {
1356
+ # Is a paragraph.
1357
+ $value = $this->runSpanGamut($value);
1358
+ $value = preg_replace('/^([ ]*)/', "<p>", $value);
1359
+ $value .= "</p>";
1360
+ $grafs[$key] = $this->unhash($value);
1361
+ }
1362
+ else {
1363
+ # Is a block.
1364
+ # Modify elements of @grafs in-place...
1365
+ $graf = $value;
1366
+ $block = $this->html_hashes[$graf];
1367
+ $graf = $block;
1368
+ // if (preg_match('{
1369
+ // \A
1370
+ // ( # $1 = <div> tag
1371
+ // <div \s+
1372
+ // [^>]*
1373
+ // \b
1374
+ // markdown\s*=\s* ([\'"]) # $2 = attr quote char
1375
+ // 1
1376
+ // \2
1377
+ // [^>]*
1378
+ // >
1379
+ // )
1380
+ // ( # $3 = contents
1381
+ // .*
1382
+ // )
1383
+ // (</div>) # $4 = closing tag
1384
+ // \z
1385
+ // }xs', $block, $matches))
1386
+ // {
1387
+ // list(, $div_open, , $div_content, $div_close) = $matches;
1388
+ //
1389
+ // # We can't call Markdown(), because that resets the hash;
1390
+ // # that initialization code should be pulled into its own sub, though.
1391
+ // $div_content = $this->hashHTMLBlocks($div_content);
1392
+ //
1393
+ // # Run document gamut methods on the content.
1394
+ // foreach ($this->document_gamut as $method => $priority) {
1395
+ // $div_content = $this->$method($div_content);
1396
+ // }
1397
+ //
1398
+ // $div_open = preg_replace(
1399
+ // '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open);
1400
+ //
1401
+ // $graf = $div_open . "\n" . $div_content . "\n" . $div_close;
1402
+ // }
1403
+ $grafs[$key] = $graf;
1404
+ }
1405
+ }
1406
+
1407
+ return implode("\n\n", $grafs);
1408
+ }
1409
+
1410
+
1411
+ function encodeAttribute($text) {
1412
+ #
1413
+ # Encode text for a double-quoted HTML attribute. This function
1414
+ # is *not* suitable for attributes enclosed in single quotes.
1415
+ #
1416
+ $text = $this->encodeAmpsAndAngles($text);
1417
+ $text = str_replace('"', '&quot;', $text);
1418
+ return $text;
1419
+ }
1420
+
1421
+
1422
+ function encodeAmpsAndAngles($text) {
1423
+ #
1424
+ # Smart processing for ampersands and angle brackets that need to
1425
+ # be encoded. Valid character entities are left alone unless the
1426
+ # no-entities mode is set.
1427
+ #
1428
+ if ($this->no_entities) {
1429
+ $text = str_replace('&', '&amp;', $text);
1430
+ } else {
1431
+ # Ampersand-encoding based entirely on Nat Irons's Amputator
1432
+ # MT plugin: <http://bumppo.net/projects/amputator/>
1433
+ $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/',
1434
+ '&amp;', $text);;
1435
+ }
1436
+ # Encode remaining <'s
1437
+ $text = str_replace('<', '&lt;', $text);
1438
+
1439
+ return $text;
1440
+ }
1441
+
1442
+
1443
+ function doAutoLinks($text) {
1444
+ $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i',
1445
+ array(&$this, '_doAutoLinks_url_callback'), $text);
1446
+
1447
+ # Email addresses: <address@domain.foo>
1448
+ $text = preg_replace_callback('{
1449
+ <
1450
+ (?:mailto:)?
1451
+ (
1452
+ (?:
1453
+ [-!#$%&\'*+/=?^_`.{|}~\w\x80-\xFF]+
1454
+ |
1455
+ ".*?"
1456
+ )
1457
+ \@
1458
+ (?:
1459
+ [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+
1460
+ |
1461
+ \[[\d.a-fA-F:]+\] # IPv4 & IPv6
1462
+ )
1463
+ )
1464
+ >
1465
+ }xi',
1466
+ array(&$this, '_doAutoLinks_email_callback'), $text);
1467
+
1468
+ return $text;
1469
+ }
1470
+ function _doAutoLinks_url_callback($matches) {
1471
+ $url = $this->encodeAttribute($matches[1]);
1472
+ $link = "<a href=\"$url\">$url</a>";
1473
+ return $this->hashPart($link);
1474
+ }
1475
+ function _doAutoLinks_email_callback($matches) {
1476
+ $address = $matches[1];
1477
+ $link = $this->encodeEmailAddress($address);
1478
+ return $this->hashPart($link);
1479
+ }
1480
+
1481
+
1482
+ function encodeEmailAddress($addr) {
1483
+ #
1484
+ # Input: an email address, e.g. "foo@example.com"
1485
+ #
1486
+ # Output: the email address as a mailto link, with each character
1487
+ # of the address encoded as either a decimal or hex entity, in
1488
+ # the hopes of foiling most address harvesting spam bots. E.g.:
1489
+ #
1490
+ # <p><a href="&#109;&#x61;&#105;&#x6c;&#116;&#x6f;&#58;&#x66;o&#111;
1491
+ # &#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;&#101;&#46;&#x63;&#111;
1492
+ # &#x6d;">&#x66;o&#111;&#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;
1493
+ # &#101;&#46;&#x63;&#111;&#x6d;</a></p>
1494
+ #
1495
+ # Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
1496
+ # With some optimizations by Milian Wolff.
1497
+ #
1498
+ $addr = "mailto:" . $addr;
1499
+ $chars = preg_split('/(?<!^)(?!$)/', $addr);
1500
+ $seed = (int)abs(crc32($addr) / strlen($addr)); # Deterministic seed.
1501
+
1502
+ foreach ($chars as $key => $char) {
1503
+ $ord = ord($char);
1504
+ # Ignore non-ascii chars.
1505
+ if ($ord < 128) {
1506
+ $r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
1507
+ # roughly 10% raw, 45% hex, 45% dec
1508
+ # '@' *must* be encoded. I insist.
1509
+ if ($r > 90 && $char != '@') /* do nothing */;
1510
+ else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';';
1511
+ else $chars[$key] = '&#'.$ord.';';
1512
+ }
1513
+ }
1514
+
1515
+ $addr = implode('', $chars);
1516
+ $text = implode('', array_slice($chars, 7)); # text without `mailto:`
1517
+ $addr = "<a href=\"$addr\">$text</a>";
1518
+
1519
+ return $addr;
1520
+ }
1521
+
1522
+
1523
+ function parseSpan($str) {
1524
+ #
1525
+ # Take the string $str and parse it into tokens, hashing embeded HTML,
1526
+ # escaped characters and handling code spans.
1527
+ #
1528
+ $output = '';
1529
+
1530
+ $span_re = '{
1531
+ (
1532
+ \\\\'.$this->escape_chars_re.'
1533
+ |
1534
+ (?<![`\\\\])
1535
+ `+ # code span marker
1536
+ '.( $this->no_markup ? '' : '
1537
+ |
1538
+ <!-- .*? --> # comment
1539
+ |
1540
+ <\?.*?\?> | <%.*?%> # processing instruction
1541
+ |
1542
+ <[/!$]?[-a-zA-Z0-9:_]+ # regular tags
1543
+ (?>
1544
+ \s
1545
+ (?>[^"\'>]+|"[^"]*"|\'[^\']*\')*
1546
+ )?
1547
+ >
1548
+ ').'
1549
+ )
1550
+ }xs';
1551
+
1552
+ while (1) {
1553
+ #
1554
+ # Each loop iteration seach for either the next tag, the next
1555
+ # openning code span marker, or the next escaped character.
1556
+ # Each token is then passed to handleSpanToken.
1557
+ #
1558
+ $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
1559
+
1560
+ # Create token from text preceding tag.
1561
+ if ($parts[0] != "") {
1562
+ $output .= $parts[0];
1563
+ }
1564
+
1565
+ # Check if we reach the end.
1566
+ if (isset($parts[1])) {
1567
+ $output .= $this->handleSpanToken($parts[1], $parts[2]);
1568
+ $str = $parts[2];
1569
+ }
1570
+ else {
1571
+ break;
1572
+ }
1573
+ }
1574
+
1575
+ return $output;
1576
+ }
1577
+
1578
+
1579
+ function handleSpanToken($token, &$str) {
1580
+ #
1581
+ # Handle $token provided by parseSpan by determining its nature and
1582
+ # returning the corresponding value that should replace it.
1583
+ #
1584
+ switch ($token{0}) {
1585
+ case "\\":
1586
+ return $this->hashPart("&#". ord($token{1}). ";");
1587
+ case "`":
1588
+ # Search for end marker in remaining text.
1589
+ if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
1590
+ $str, $matches))
1591
+ {
1592
+ $str = $matches[2];
1593
+ $codespan = $this->makeCodeSpan($matches[1]);
1594
+ return $this->hashPart($codespan);
1595
+ }
1596
+ return $token; // return as text since no ending marker found.
1597
+ default:
1598
+ return $this->hashPart($token);
1599
+ }
1600
+ }
1601
+
1602
+
1603
+ function outdent($text) {
1604
+ #
1605
+ # Remove one level of line-leading tabs or spaces
1606
+ #
1607
+ return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
1608
+ }
1609
+
1610
+
1611
+ # String length function for detab. `_initDetab` will create a function to
1612
+ # hanlde UTF-8 if the default function does not exist.
1613
+ var $utf8_strlen = 'mb_strlen';
1614
+
1615
+ function detab($text) {
1616
+ #
1617
+ # Replace tabs with the appropriate amount of space.
1618
+ #
1619
+ # For each line we separate the line in blocks delemited by
1620
+ # tab characters. Then we reconstruct every line by adding the
1621
+ # appropriate number of space between each blocks.
1622
+
1623
+ $text = preg_replace_callback('/^.*\t.*$/m',
1624
+ array(&$this, '_detab_callback'), $text);
1625
+
1626
+ return $text;
1627
+ }
1628
+ function _detab_callback($matches) {
1629
+ $line = $matches[0];
1630
+ $strlen = $this->utf8_strlen; # strlen function for UTF-8.
1631
+
1632
+ # Split in blocks.
1633
+ $blocks = explode("\t", $line);
1634
+ # Add each blocks to the line.
1635
+ $line = $blocks[0];
1636
+ unset($blocks[0]); # Do not add first block twice.
1637
+ foreach ($blocks as $block) {
1638
+ # Calculate amount of space, insert spaces, insert block.
1639
+ $amount = $this->tab_width -
1640
+ $strlen($line, 'UTF-8') % $this->tab_width;
1641
+ $line .= str_repeat(" ", $amount) . $block;
1642
+ }
1643
+ return $line;
1644
+ }
1645
+ function _initDetab() {
1646
+ #
1647
+ # Check for the availability of the function in the `utf8_strlen` property
1648
+ # (initially `mb_strlen`). If the function is not available, create a
1649
+ # function that will loosely count the number of UTF-8 characters with a
1650
+ # regular expression.
1651
+ #
1652
+ if (function_exists($this->utf8_strlen)) return;
1653
+ $this->utf8_strlen = create_function('$text', 'return preg_match_all(
1654
+ "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/",
1655
+ $text, $m);');
1656
+ }
1657
+
1658
+
1659
+ function unhash($text) {
1660
+ #
1661
+ # Swap back in all the tags hashed by _HashHTMLBlocks.
1662
+ #
1663
+ return preg_replace_callback('/(.)\x1A[0-9]+\1/',
1664
+ array(&$this, '_unhash_callback'), $text);
1665
+ }
1666
+ function _unhash_callback($matches) {
1667
+ return $this->html_hashes[$matches[0]];
1668
+ }
1669
+
1670
+ }
1671
+
1672
+
1673
+ #
1674
+ # Markdown Extra Parser Class
1675
+ #
1676
+
1677
+ class MarkdownExtra_Parser extends Markdown_Parser {
1678
+
1679
+ # Prefix for footnote ids.
1680
+ var $fn_id_prefix = "";
1681
+
1682
+ # Optional title attribute for footnote links and backlinks.
1683
+ var $fn_link_title = MARKDOWN_FN_LINK_TITLE;
1684
+ var $fn_backlink_title = MARKDOWN_FN_BACKLINK_TITLE;
1685
+
1686
+ # Optional class attribute for footnote links and backlinks.
1687
+ var $fn_link_class = MARKDOWN_FN_LINK_CLASS;
1688
+ var $fn_backlink_class = MARKDOWN_FN_BACKLINK_CLASS;
1689
+
1690
+ # Predefined abbreviations.
1691
+ var $predef_abbr = array();
1692
+
1693
+
1694
+ function MarkdownExtra_Parser() {
1695
+ #
1696
+ # Constructor function. Initialize the parser object.
1697
+ #
1698
+ # Add extra escapable characters before parent constructor
1699
+ # initialize the table.
1700
+ $this->escape_chars .= ':|';
1701
+
1702
+ # Insert extra document, block, and span transformations.
1703
+ # Parent constructor will do the sorting.
1704
+ $this->document_gamut += array(
1705
+ "doFencedCodeBlocks" => 5,
1706
+ "stripFootnotes" => 15,
1707
+ "stripAbbreviations" => 25,
1708
+ "appendFootnotes" => 50,
1709
+ );
1710
+ $this->block_gamut += array(
1711
+ "doFencedCodeBlocks" => 5,
1712
+ "doTables" => 15,
1713
+ "doDefLists" => 45,
1714
+ );
1715
+ $this->span_gamut += array(
1716
+ "doFootnotes" => 5,
1717
+ "doAbbreviations" => 70,
1718
+ );
1719
+
1720
+ parent::Markdown_Parser();
1721
+ }
1722
+
1723
+
1724
+ # Extra variables used during extra transformations.
1725
+ var $footnotes = array();
1726
+ var $footnotes_ordered = array();
1727
+ var $abbr_desciptions = array();
1728
+ var $abbr_word_re = '';
1729
+
1730
+ # Give the current footnote number.
1731
+ var $footnote_counter = 1;
1732
+
1733
+
1734
+ function setup() {
1735
+ #
1736
+ # Setting up Extra-specific variables.
1737
+ #
1738
+ parent::setup();
1739
+
1740
+ $this->footnotes = array();
1741
+ $this->footnotes_ordered = array();
1742
+ $this->abbr_desciptions = array();
1743
+ $this->abbr_word_re = '';
1744
+ $this->footnote_counter = 1;
1745
+
1746
+ foreach ($this->predef_abbr as $abbr_word => $abbr_desc) {
1747
+ if ($this->abbr_word_re)
1748
+ $this->abbr_word_re .= '|';
1749
+ $this->abbr_word_re .= preg_quote($abbr_word);
1750
+ $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
1751
+ }
1752
+ }
1753
+
1754
+ function teardown() {
1755
+ #
1756
+ # Clearing Extra-specific variables.
1757
+ #
1758
+ $this->footnotes = array();
1759
+ $this->footnotes_ordered = array();
1760
+ $this->abbr_desciptions = array();
1761
+ $this->abbr_word_re = '';
1762
+
1763
+ parent::teardown();
1764
+ }
1765
+
1766
+
1767
+ ### HTML Block Parser ###
1768
+
1769
+ # Tags that are always treated as block tags:
1770
+ var $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend';
1771
+
1772
+ # Tags treated as block tags only if the opening tag is alone on it's line:
1773
+ var $context_block_tags_re = 'script|noscript|math|ins|del';
1774
+
1775
+ # Tags where markdown="1" default to span mode:
1776
+ var $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address';
1777
+
1778
+ # Tags which must not have their contents modified, no matter where
1779
+ # they appear:
1780
+ var $clean_tags_re = 'script|math';
1781
+
1782
+ # Tags that do not need to be closed.
1783
+ var $auto_close_tags_re = 'hr|img';
1784
+
1785
+
1786
+ function hashHTMLBlocks($text) {
1787
+ #
1788
+ # Hashify HTML Blocks and "clean tags".
1789
+ #
1790
+ # We only want to do this for block-level HTML tags, such as headers,
1791
+ # lists, and tables. That's because we still want to wrap <p>s around
1792
+ # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
1793
+ # phrase emphasis, and spans. The list of tags we're looking for is
1794
+ # hard-coded.
1795
+ #
1796
+ # This works by calling _HashHTMLBlocks_InMarkdown, which then calls
1797
+ # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1"
1798
+ # attribute is found whitin a tag, _HashHTMLBlocks_InHTML calls back
1799
+ # _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag.
1800
+ # These two functions are calling each other. It's recursive!
1801
+ #
1802
+ #
1803
+ # Call the HTML-in-Markdown hasher.
1804
+ #
1805
+ list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text);
1806
+
1807
+ return $text;
1808
+ }
1809
+ function _hashHTMLBlocks_inMarkdown($text, $indent = 0,
1810
+ $enclosing_tag_re = '', $span = false)
1811
+ {
1812
+ #
1813
+ # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags.
1814
+ #
1815
+ # * $indent is the number of space to be ignored when checking for code
1816
+ # blocks. This is important because if we don't take the indent into
1817
+ # account, something like this (which looks right) won't work as expected:
1818
+ #
1819
+ # <div>
1820
+ # <div markdown="1">
1821
+ # Hello World. <-- Is this a Markdown code block or text?
1822
+ # </div> <-- Is this a Markdown code block or a real tag?
1823
+ # <div>
1824
+ #
1825
+ # If you don't like this, just don't indent the tag on which
1826
+ # you apply the markdown="1" attribute.
1827
+ #
1828
+ # * If $enclosing_tag_re is not empty, stops at the first unmatched closing
1829
+ # tag with that name. Nested tags supported.
1830
+ #
1831
+ # * If $span is true, text inside must treated as span. So any double
1832
+ # newline will be replaced by a single newline so that it does not create
1833
+ # paragraphs.
1834
+ #
1835
+ # Returns an array of that form: ( processed text , remaining text )
1836
+ #
1837
+ if ($text === '') return array('', '');
1838
+
1839
+ # Regex to check for the presense of newlines around a block tag.
1840
+ $newline_before_re = '/(?:^\n?|\n\n)*$/';
1841
+ $newline_after_re =
1842
+ '{
1843
+ ^ # Start of text following the tag.
1844
+ (?>[ ]*<!--.*?-->)? # Optional comment.
1845
+ [ ]*\n # Must be followed by newline.
1846
+ }xs';
1847
+
1848
+ # Regex to match any tag.
1849
+ $block_tag_re =
1850
+ '{
1851
+ ( # $2: Capture hole tag.
1852
+ </? # Any opening or closing tag.
1853
+ (?> # Tag name.
1854
+ '.$this->block_tags_re.' |
1855
+ '.$this->context_block_tags_re.' |
1856
+ '.$this->clean_tags_re.' |
1857
+ (?!\s)'.$enclosing_tag_re.'
1858
+ )
1859
+ (?:
1860
+ (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name.
1861
+ (?>
1862
+ ".*?" | # Double quotes (can contain `>`)
1863
+ \'.*?\' | # Single quotes (can contain `>`)
1864
+ .+? # Anything but quotes and `>`.
1865
+ )*?
1866
+ )?
1867
+ > # End of tag.
1868
+ |
1869
+ <!-- .*? --> # HTML Comment
1870
+ |
1871
+ <\?.*?\?> | <%.*?%> # Processing instruction
1872
+ |
1873
+ <!\[CDATA\[.*?\]\]> # CData Block
1874
+ |
1875
+ # Code span marker
1876
+ `+
1877
+ '. ( !$span ? ' # If not in span.
1878
+ |
1879
+ # Indented code block
1880
+ (?: ^[ ]*\n | ^ | \n[ ]*\n )
1881
+ [ ]{'.($indent+4).'}[^\n]* \n
1882
+ (?>
1883
+ (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n
1884
+ )*
1885
+ |
1886
+ # Fenced code block marker
1887
+ (?> ^ | \n )
1888
+ [ ]{'.($indent).'}~~~+[ ]*\n
1889
+ ' : '' ). ' # End (if not is span).
1890
+ )
1891
+ }xs';
1892
+
1893
+
1894
+ $depth = 0; # Current depth inside the tag tree.
1895
+ $parsed = ""; # Parsed text that will be returned.
1896
+
1897
+ #
1898
+ # Loop through every tag until we find the closing tag of the parent
1899
+ # or loop until reaching the end of text if no parent tag specified.
1900
+ #
1901
+ do {
1902
+ #
1903
+ # Split the text using the first $tag_match pattern found.
1904
+ # Text before pattern will be first in the array, text after
1905
+ # pattern will be at the end, and between will be any catches made
1906
+ # by the pattern.
1907
+ #
1908
+ $parts = preg_split($block_tag_re, $text, 2,
1909
+ PREG_SPLIT_DELIM_CAPTURE);
1910
+
1911
+ # If in Markdown span mode, add a empty-string span-level hash
1912
+ # after each newline to prevent triggering any block element.
1913
+ if ($span) {
1914
+ $void = $this->hashPart("", ':');
1915
+ $newline = "$void\n";
1916
+ $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void;
1917
+ }
1918
+
1919
+ $parsed .= $parts[0]; # Text before current tag.
1920
+
1921
+ # If end of $text has been reached. Stop loop.
1922
+ if (count($parts) < 3) {
1923
+ $text = "";
1924
+ break;
1925
+ }
1926
+
1927
+ $tag = $parts[1]; # Tag to handle.
1928
+ $text = $parts[2]; # Remaining text after current tag.
1929
+ $tag_re = preg_quote($tag); # For use in a regular expression.
1930
+
1931
+ #
1932
+ # Check for: Code span marker
1933
+ #
1934
+ if ($tag{0} == "`") {
1935
+ # Find corresponding end marker.
1936
+ $tag_re = preg_quote($tag);
1937
+ if (preg_match('{^(?>.+?|\n(?!\n))*?(?<!`)'.$tag_re.'(?!`)}',
1938
+ $text, $matches))
1939
+ {
1940
+ # End marker found: pass text unchanged until marker.
1941
+ $parsed .= $tag . $matches[0];
1942
+ $text = substr($text, strlen($matches[0]));
1943
+ }
1944
+ else {
1945
+ # Unmatched marker: just skip it.
1946
+ $parsed .= $tag;
1947
+ }
1948
+ }
1949
+ #
1950
+ # Check for: Indented code block.
1951
+ #
1952
+ else if ($tag{0} == "\n" || $tag{0} == " ") {
1953
+ # Indented code block: pass it unchanged, will be handled
1954
+ # later.
1955
+ $parsed .= $tag;
1956
+ }
1957
+ #
1958
+ # Check for: Fenced code block marker.
1959
+ #
1960
+ else if ($tag{0} == "~") {
1961
+ # Fenced code block marker: find matching end marker.
1962
+ $tag_re = preg_quote(trim($tag));
1963
+ if (preg_match('{^(?>.*\n)+?'.$tag_re.' *\n}', $text,
1964
+ $matches))
1965
+ {
1966
+ # End marker found: pass text unchanged until marker.
1967
+ $parsed .= $tag . $matches[0];
1968
+ $text = substr($text, strlen($matches[0]));
1969
+ }
1970
+ else {
1971
+ # No end marker: just skip it.
1972
+ $parsed .= $tag;
1973
+ }
1974
+ }
1975
+ #
1976
+ # Check for: Opening Block level tag or
1977
+ # Opening Context Block tag (like ins and del)
1978
+ # used as a block tag (tag is alone on it's line).
1979
+ #
1980
+ else if (preg_match('{^<(?:'.$this->block_tags_re.')\b}', $tag) ||
1981
+ ( preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) &&
1982
+ preg_match($newline_before_re, $parsed) &&
1983
+ preg_match($newline_after_re, $text) )
1984
+ )
1985
+ {
1986
+ # Need to parse tag and following text using the HTML parser.
1987
+ list($block_text, $text) =
1988
+ $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true);
1989
+
1990
+ # Make sure it stays outside of any paragraph by adding newlines.
1991
+ $parsed .= "\n\n$block_text\n\n";
1992
+ }
1993
+ #
1994
+ # Check for: Clean tag (like script, math)
1995
+ # HTML Comments, processing instructions.
1996
+ #
1997
+ else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) ||
1998
+ $tag{1} == '!' || $tag{1} == '?')
1999
+ {
2000
+ # Need to parse tag and following text using the HTML parser.
2001
+ # (don't check for markdown attribute)
2002
+ list($block_text, $text) =
2003
+ $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false);
2004
+
2005
+ $parsed .= $block_text;
2006
+ }
2007
+ #
2008
+ # Check for: Tag with same name as enclosing tag.
2009
+ #
2010
+ else if ($enclosing_tag_re !== '' &&
2011
+ # Same name as enclosing tag.
2012
+ preg_match('{^</?(?:'.$enclosing_tag_re.')\b}', $tag))
2013
+ {
2014
+ #
2015
+ # Increase/decrease nested tag count.
2016
+ #
2017
+ if ($tag{1} == '/') $depth--;
2018
+ else if ($tag{strlen($tag)-2} != '/') $depth++;
2019
+
2020
+ if ($depth < 0) {
2021
+ #
2022
+ # Going out of parent element. Clean up and break so we
2023
+ # return to the calling function.
2024
+ #
2025
+ $text = $tag . $text;
2026
+ break;
2027
+ }
2028
+
2029
+ $parsed .= $tag;
2030
+ }
2031
+ else {
2032
+ $parsed .= $tag;
2033
+ }
2034
+ } while ($depth >= 0);
2035
+
2036
+ return array($parsed, $text);
2037
+ }
2038
+ function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) {
2039
+ #
2040
+ # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags.
2041
+ #
2042
+ # * Calls $hash_method to convert any blocks.
2043
+ # * Stops when the first opening tag closes.
2044
+ # * $md_attr indicate if the use of the `markdown="1"` attribute is allowed.
2045
+ # (it is not inside clean tags)
2046
+ #
2047
+ # Returns an array of that form: ( processed text , remaining text )
2048
+ #
2049
+ if ($text === '') return array('', '');
2050
+
2051
+ # Regex to match `markdown` attribute inside of a tag.
2052
+ $markdown_attr_re = '
2053
+ {
2054
+ \s* # Eat whitespace before the `markdown` attribute
2055
+ markdown
2056
+ \s*=\s*
2057
+ (?>
2058
+ (["\']) # $1: quote delimiter
2059
+ (.*?) # $2: attribute value
2060
+ \1 # matching delimiter
2061
+ |
2062
+ ([^\s>]*) # $3: unquoted attribute value
2063
+ )
2064
+ () # $4: make $3 always defined (avoid warnings)
2065
+ }xs';
2066
+
2067
+ # Regex to match any tag.
2068
+ $tag_re = '{
2069
+ ( # $2: Capture hole tag.
2070
+ </? # Any opening or closing tag.
2071
+ [\w:$]+ # Tag name.
2072
+ (?:
2073
+ (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name.
2074
+ (?>
2075
+ ".*?" | # Double quotes (can contain `>`)
2076
+ \'.*?\' | # Single quotes (can contain `>`)
2077
+ .+? # Anything but quotes and `>`.
2078
+ )*?
2079
+ )?
2080
+ > # End of tag.
2081
+ |
2082
+ <!-- .*? --> # HTML Comment
2083
+ |
2084
+ <\?.*?\?> | <%.*?%> # Processing instruction
2085
+ |
2086
+ <!\[CDATA\[.*?\]\]> # CData Block
2087
+ )
2088
+ }xs';
2089
+
2090
+ $original_text = $text; # Save original text in case of faliure.
2091
+
2092
+ $depth = 0; # Current depth inside the tag tree.
2093
+ $block_text = ""; # Temporary text holder for current text.
2094
+ $parsed = ""; # Parsed text that will be returned.
2095
+
2096
+ #
2097
+ # Get the name of the starting tag.
2098
+ # (This pattern makes $base_tag_name_re safe without quoting.)
2099
+ #
2100
+ if (preg_match('/^<([\w:$]*)\b/', $text, $matches))
2101
+ $base_tag_name_re = $matches[1];
2102
+
2103
+ #
2104
+ # Loop through every tag until we find the corresponding closing tag.
2105
+ #
2106
+ do {
2107
+ #
2108
+ # Split the text using the first $tag_match pattern found.
2109
+ # Text before pattern will be first in the array, text after
2110
+ # pattern will be at the end, and between will be any catches made
2111
+ # by the pattern.
2112
+ #
2113
+ $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
2114
+
2115
+ if (count($parts) < 3) {
2116
+ #
2117
+ # End of $text reached with unbalenced tag(s).
2118
+ # In that case, we return original text unchanged and pass the
2119
+ # first character as filtered to prevent an infinite loop in the
2120
+ # parent function.
2121
+ #
2122
+ return array($original_text{0}, substr($original_text, 1));
2123
+ }
2124
+
2125
+ $block_text .= $parts[0]; # Text before current tag.
2126
+ $tag = $parts[1]; # Tag to handle.
2127
+ $text = $parts[2]; # Remaining text after current tag.
2128
+
2129
+ #
2130
+ # Check for: Auto-close tag (like <hr/>)
2131
+ # Comments and Processing Instructions.
2132
+ #
2133
+ if (preg_match('{^</?(?:'.$this->auto_close_tags_re.')\b}', $tag) ||
2134
+ $tag{1} == '!' || $tag{1} == '?')
2135
+ {
2136
+ # Just add the tag to the block as if it was text.
2137
+ $block_text .= $tag;
2138
+ }
2139
+ else {
2140
+ #
2141
+ # Increase/decrease nested tag count. Only do so if
2142
+ # the tag's name match base tag's.
2143
+ #
2144
+ if (preg_match('{^</?'.$base_tag_name_re.'\b}', $tag)) {
2145
+ if ($tag{1} == '/') $depth--;
2146
+ else if ($tag{strlen($tag)-2} != '/') $depth++;
2147
+ }
2148
+
2149
+ #
2150
+ # Check for `markdown="1"` attribute and handle it.
2151
+ #
2152
+ if ($md_attr &&
2153
+ preg_match($markdown_attr_re, $tag, $attr_m) &&
2154
+ preg_match('/^1|block|span$/', $attr_m[2] . $attr_m[3]))
2155
+ {
2156
+ # Remove `markdown` attribute from opening tag.
2157
+ $tag = preg_replace($markdown_attr_re, '', $tag);
2158
+
2159
+ # Check if text inside this tag must be parsed in span mode.
2160
+ $this->mode = $attr_m[2] . $attr_m[3];
2161
+ $span_mode = $this->mode == 'span' || $this->mode != 'block' &&
2162
+ preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag);
2163
+
2164
+ # Calculate indent before tag.
2165
+ if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) {
2166
+ $strlen = $this->utf8_strlen;
2167
+ $indent = $strlen($matches[1], 'UTF-8');
2168
+ } else {
2169
+ $indent = 0;
2170
+ }
2171
+
2172
+ # End preceding block with this tag.
2173
+ $block_text .= $tag;
2174
+ $parsed .= $this->$hash_method($block_text);
2175
+
2176
+ # Get enclosing tag name for the ParseMarkdown function.
2177
+ # (This pattern makes $tag_name_re safe without quoting.)
2178
+ preg_match('/^<([\w:$]*)\b/', $tag, $matches);
2179
+ $tag_name_re = $matches[1];
2180
+
2181
+ # Parse the content using the HTML-in-Markdown parser.
2182
+ list ($block_text, $text)
2183
+ = $this->_hashHTMLBlocks_inMarkdown($text, $indent,
2184
+ $tag_name_re, $span_mode);
2185
+
2186
+ # Outdent markdown text.
2187
+ if ($indent > 0) {
2188
+ $block_text = preg_replace("/^[ ]{1,$indent}/m", "",
2189
+ $block_text);
2190
+ }
2191
+
2192
+ # Append tag content to parsed text.
2193
+ if (!$span_mode) $parsed .= "\n\n$block_text\n\n";
2194
+ else $parsed .= "$block_text";
2195
+
2196
+ # Start over a new block.
2197
+ $block_text = "";
2198
+ }
2199
+ else $block_text .= $tag;
2200
+ }
2201
+
2202
+ } while ($depth > 0);
2203
+
2204
+ #
2205
+ # Hash last block text that wasn't processed inside the loop.
2206
+ #
2207
+ $parsed .= $this->$hash_method($block_text);
2208
+
2209
+ return array($parsed, $text);
2210
+ }
2211
+
2212
+
2213
+ function hashClean($text) {
2214
+ #
2215
+ # Called whenever a tag must be hashed when a function insert a "clean" tag
2216
+ # in $text, it pass through this function and is automaticaly escaped,
2217
+ # blocking invalid nested overlap.
2218
+ #
2219
+ return $this->hashPart($text, 'C');
2220
+ }
2221
+
2222
+
2223
+ function doHeaders($text) {
2224
+ #
2225
+ # Redefined to add id attribute support.
2226
+ #
2227
+ # Setext-style headers:
2228
+ # Header 1 {#header1}
2229
+ # ========
2230
+ #
2231
+ # Header 2 {#header2}
2232
+ # --------
2233
+ #
2234
+ $text = preg_replace_callback(
2235
+ '{
2236
+ (^.+?) # $1: Header text
2237
+ (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # $2: Id attribute
2238
+ [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer
2239
+ }mx',
2240
+ array(&$this, '_doHeaders_callback_setext'), $text);
2241
+
2242
+ # atx-style headers:
2243
+ # # Header 1 {#header1}
2244
+ # ## Header 2 {#header2}
2245
+ # ## Header 2 with closing hashes ## {#header3}
2246
+ # ...
2247
+ # ###### Header 6 {#header2}
2248
+ #
2249
+ $text = preg_replace_callback('{
2250
+ ^(\#{1,6}) # $1 = string of #\'s
2251
+ [ ]*
2252
+ (.+?) # $2 = Header text
2253
+ [ ]*
2254
+ \#* # optional closing #\'s (not counted)
2255
+ (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # id attribute
2256
+ [ ]*
2257
+ \n+
2258
+ }xm',
2259
+ array(&$this, '_doHeaders_callback_atx'), $text);
2260
+
2261
+ return $text;
2262
+ }
2263
+ function _doHeaders_attr($attr) {
2264
+ if (empty($attr)) return "";
2265
+ return " id=\"$attr\"";
2266
+ }
2267
+ function _doHeaders_callback_setext($matches) {
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
+ }
2281
+
2282
+
2283
+ function doTables($text) {
2284
+ #
2285
+ # Form HTML tables.
2286
+ #
2287
+ $less_than_tab = $this->tab_width - 1;
2288
+ #
2289
+ # Find tables with leading pipe.
2290
+ #
2291
+ # | Header 1 | Header 2
2292
+ # | -------- | --------
2293
+ # | Cell 1 | Cell 2
2294
+ # | Cell 3 | Cell 4
2295
+ #
2296
+ $text = preg_replace_callback('
2297
+ {
2298
+ ^ # Start of a line
2299
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
2300
+ [|] # Optional leading pipe (present)
2301
+ (.+) \n # $1: Header row (at least one pipe)
2302
+
2303
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
2304
+ [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline
2305
+
2306
+ ( # $3: Cells
2307
+ (?>
2308
+ [ ]* # Allowed whitespace.
2309
+ [|] .* \n # Row content.
2310
+ )*
2311
+ )
2312
+ (?=\n|\Z) # Stop at final double newline.
2313
+ }xm',
2314
+ array(&$this, '_doTable_leadingPipe_callback'), $text);
2315
+
2316
+ #
2317
+ # Find tables without leading pipe.
2318
+ #
2319
+ # Header 1 | Header 2
2320
+ # -------- | --------
2321
+ # Cell 1 | Cell 2
2322
+ # Cell 3 | Cell 4
2323
+ #
2324
+ $text = preg_replace_callback('
2325
+ {
2326
+ ^ # Start of a line
2327
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
2328
+ (\S.*[|].*) \n # $1: Header row (at least one pipe)
2329
+
2330
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
2331
+ ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline
2332
+
2333
+ ( # $3: Cells
2334
+ (?>
2335
+ .* [|] .* \n # Row content
2336
+ )*
2337
+ )
2338
+ (?=\n|\Z) # Stop at final double newline.
2339
+ }xm',
2340
+ array(&$this, '_DoTable_callback'), $text);
2341
+
2342
+ return $text;
2343
+ }
2344
+ function _doTable_leadingPipe_callback($matches) {
2345
+ $head = $matches[1];
2346
+ $underline = $matches[2];
2347
+ $content = $matches[3];
2348
+
2349
+ # Remove leading pipe for each row.
2350
+ $content = preg_replace('/^ *[|]/m', '', $content);
2351
+
2352
+ return $this->_doTable_callback(array($matches[0], $head, $underline, $content));
2353
+ }
2354
+ function _doTable_callback($matches) {
2355
+ $head = $matches[1];
2356
+ $underline = $matches[2];
2357
+ $content = $matches[3];
2358
+
2359
+ # Remove any tailing pipes for each line.
2360
+ $head = preg_replace('/[|] *$/m', '', $head);
2361
+ $underline = preg_replace('/[|] *$/m', '', $underline);
2362
+ $content = preg_replace('/[|] *$/m', '', $content);
2363
+
2364
+ # Reading alignement from header underline.
2365
+ $separators = preg_split('/ *[|] */', $underline);
2366
+ foreach ($separators as $n => $s) {
2367
+ if (preg_match('/^ *-+: *$/', $s)) $attr[$n] = ' align="right"';
2368
+ else if (preg_match('/^ *:-+: *$/', $s))$attr[$n] = ' align="center"';
2369
+ else if (preg_match('/^ *:-+ *$/', $s)) $attr[$n] = ' align="left"';
2370
+ else $attr[$n] = '';
2371
+ }
2372
+
2373
+ # Parsing span elements, including code spans, character escapes,
2374
+ # and inline HTML tags, so that pipes inside those gets ignored.
2375
+ $head = $this->parseSpan($head);
2376
+ $headers = preg_split('/ *[|] */', $head);
2377
+ $col_count = count($headers);
2378
+
2379
+ # Write column headers.
2380
+ $text = "<table>\n";
2381
+ $text .= "<thead>\n";
2382
+ $text .= "<tr>\n";
2383
+ foreach ($headers as $n => $header)
2384
+ $text .= " <th$attr[$n]>".$this->runSpanGamut(trim($header))."</th>\n";
2385
+ $text .= "</tr>\n";
2386
+ $text .= "</thead>\n";
2387
+
2388
+ # Split content by row.
2389
+ $rows = explode("\n", trim($content, "\n"));
2390
+
2391
+ $text .= "<tbody>\n";
2392
+ foreach ($rows as $row) {
2393
+ # Parsing span elements, including code spans, character escapes,
2394
+ # and inline HTML tags, so that pipes inside those gets ignored.
2395
+ $row = $this->parseSpan($row);
2396
+
2397
+ # Split row by cell.
2398
+ $row_cells = preg_split('/ *[|] */', $row, $col_count);
2399
+ $row_cells = array_pad($row_cells, $col_count, '');
2400
+
2401
+ $text .= "<tr>\n";
2402
+ foreach ($row_cells as $n => $cell)
2403
+ $text .= " <td$attr[$n]>".$this->runSpanGamut(trim($cell))."</td>\n";
2404
+ $text .= "</tr>\n";
2405
+ }
2406
+ $text .= "</tbody>\n";
2407
+ $text .= "</table>";
2408
+
2409
+ return $this->hashBlock($text) . "\n";
2410
+ }
2411
+
2412
+
2413
+ function doDefLists($text) {
2414
+ #
2415
+ # Form HTML definition lists.
2416
+ #
2417
+ $less_than_tab = $this->tab_width - 1;
2418
+
2419
+ # Re-usable pattern to match any entire dl list:
2420
+ $whole_list_re = '(?>
2421
+ ( # $1 = whole list
2422
+ ( # $2
2423
+ [ ]{0,'.$less_than_tab.'}
2424
+ ((?>.*\S.*\n)+) # $3 = defined term
2425
+ \n?
2426
+ [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
2427
+ )
2428
+ (?s:.+?)
2429
+ ( # $4
2430
+ \z
2431
+ |
2432
+ \n{2,}
2433
+ (?=\S)
2434
+ (?! # Negative lookahead for another term
2435
+ [ ]{0,'.$less_than_tab.'}
2436
+ (?: \S.*\n )+? # defined term
2437
+ \n?
2438
+ [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
2439
+ )
2440
+ (?! # Negative lookahead for another definition
2441
+ [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
2442
+ )
2443
+ )
2444
+ )
2445
+ )'; // mx
2446
+
2447
+ $text = preg_replace_callback('{
2448
+ (?>\A\n?|(?<=\n\n))
2449
+ '.$whole_list_re.'
2450
+ }mx',
2451
+ array(&$this, '_doDefLists_callback'), $text);
2452
+
2453
+ return $text;
2454
+ }
2455
+ function _doDefLists_callback($matches) {
2456
+ # Re-usable patterns to match list item bullets and number markers:
2457
+ $list = $matches[1];
2458
+
2459
+ # Turn double returns into triple returns, so that we can make a
2460
+ # paragraph for the last item in a list, if necessary:
2461
+ $result = trim($this->processDefListItems($list));
2462
+ $result = "<dl>\n" . $result . "\n</dl>";
2463
+ return $this->hashBlock($result) . "\n\n";
2464
+ }
2465
+
2466
+
2467
+ function processDefListItems($list_str) {
2468
+ #
2469
+ # Process the contents of a single definition list, splitting it
2470
+ # into individual term and definition list items.
2471
+ #
2472
+ $less_than_tab = $this->tab_width - 1;
2473
+
2474
+ # trim trailing blank lines:
2475
+ $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
2476
+
2477
+ # Process definition terms.
2478
+ $list_str = preg_replace_callback('{
2479
+ (?>\A\n?|\n\n+) # leading line
2480
+ ( # definition terms = $1
2481
+ [ ]{0,'.$less_than_tab.'} # leading whitespace
2482
+ (?![:][ ]|[ ]) # negative lookahead for a definition
2483
+ # mark (colon) or more whitespace.
2484
+ (?> \S.* \n)+? # actual term (not whitespace).
2485
+ )
2486
+ (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed
2487
+ # with a definition mark.
2488
+ }xm',
2489
+ array(&$this, '_processDefListItems_callback_dt'), $list_str);
2490
+
2491
+ # Process actual definitions.
2492
+ $list_str = preg_replace_callback('{
2493
+ \n(\n+)? # leading line = $1
2494
+ ( # marker space = $2
2495
+ [ ]{0,'.$less_than_tab.'} # whitespace before colon
2496
+ [:][ ]+ # definition mark (colon)
2497
+ )
2498
+ ((?s:.+?)) # definition text = $3
2499
+ (?= \n+ # stop at next definition mark,
2500
+ (?: # next term or end of text
2501
+ [ ]{0,'.$less_than_tab.'} [:][ ] |
2502
+ <dt> | \z
2503
+ )
2504
+ )
2505
+ }xm',
2506
+ array(&$this, '_processDefListItems_callback_dd'), $list_str);
2507
+
2508
+ return $list_str;
2509
+ }
2510
+ function _processDefListItems_callback_dt($matches) {
2511
+ $terms = explode("\n", trim($matches[1]));
2512
+ $text = '';
2513
+ foreach ($terms as $term) {
2514
+ $term = $this->runSpanGamut(trim($term));
2515
+ $text .= "\n<dt>" . $term . "</dt>";
2516
+ }
2517
+ return $text . "\n";
2518
+ }
2519
+ function _processDefListItems_callback_dd($matches) {
2520
+ $leading_line = $matches[1];
2521
+ $marker_space = $matches[2];
2522
+ $def = $matches[3];
2523
+
2524
+ if ($leading_line || preg_match('/\n{2,}/', $def)) {
2525
+ # Replace marker with the appropriate whitespace indentation
2526
+ $def = str_repeat(' ', strlen($marker_space)) . $def;
2527
+ $def = $this->runBlockGamut($this->outdent($def . "\n\n"));
2528
+ $def = "\n". $def ."\n";
2529
+ }
2530
+ else {
2531
+ $def = rtrim($def);
2532
+ $def = $this->runSpanGamut($this->outdent($def));
2533
+ }
2534
+
2535
+ return "\n<dd>" . $def . "</dd>\n";
2536
+ }
2537
+
2538
+
2539
+ function doFencedCodeBlocks($text) {
2540
+ #
2541
+ # Adding the fenced code block syntax to regular Markdown:
2542
+ #
2543
+ # ~~~
2544
+ # Code block
2545
+ # ~~~
2546
+ #
2547
+ $less_than_tab = $this->tab_width;
2548
+
2549
+ $text = preg_replace_callback('{
2550
+ (?:\n|\A)
2551
+ # 1: Opening marker
2552
+ (
2553
+ ~{3,} # Marker: three tilde or more.
2554
+ )
2555
+ [ ]* \n # Whitespace and newline following marker.
2556
+
2557
+ # 2: Content
2558
+ (
2559
+ (?>
2560
+ (?!\1 [ ]* \n) # Not a closing marker.
2561
+ .*\n+
2562
+ )+
2563
+ )
2564
+
2565
+ # Closing marker.
2566
+ \1 [ ]* \n
2567
+ }xm',
2568
+ array(&$this, '_doFencedCodeBlocks_callback'), $text);
2569
+
2570
+ return $text;
2571
+ }
2572
+ function _doFencedCodeBlocks_callback($matches) {
2573
+ $codeblock = $matches[2];
2574
+ $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
2575
+ $codeblock = preg_replace_callback('/^\n+/',
2576
+ array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock);
2577
+ $codeblock = "<pre><code>$codeblock</code></pre>";
2578
+ return "\n\n".$this->hashBlock($codeblock)."\n\n";
2579
+ }
2580
+ function _doFencedCodeBlocks_newlines($matches) {
2581
+ return str_repeat("<br$this->empty_element_suffix",
2582
+ strlen($matches[0]));
2583
+ }
2584
+
2585
+
2586
+ #
2587
+ # Redefining emphasis markers so that emphasis by underscore does not
2588
+ # work in the middle of a word.
2589
+ #
2590
+ var $em_relist = array(
2591
+ '' => '(?:(?<!\*)\*(?!\*)|(?<![a-zA-Z0-9_])_(?!_))(?=\S|$)(?![.,:;]\s)',
2592
+ '*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
2593
+ '_' => '(?<=\S|^)(?<!_)_(?![a-zA-Z0-9_])',
2594
+ );
2595
+ var $strong_relist = array(
2596
+ '' => '(?:(?<!\*)\*\*(?!\*)|(?<![a-zA-Z0-9_])__(?!_))(?=\S|$)(?![.,:;]\s)',
2597
+ '**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
2598
+ '__' => '(?<=\S|^)(?<!_)__(?![a-zA-Z0-9_])',
2599
+ );
2600
+ var $em_strong_relist = array(
2601
+ '' => '(?:(?<!\*)\*\*\*(?!\*)|(?<![a-zA-Z0-9_])___(?!_))(?=\S|$)(?![.,:;]\s)',
2602
+ '***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
2603
+ '___' => '(?<=\S|^)(?<!_)___(?![a-zA-Z0-9_])',
2604
+ );
2605
+
2606
+
2607
+ function formParagraphs($text) {
2608
+ #
2609
+ # Params:
2610
+ # $text - string to process with html <p> tags
2611
+ #
2612
+ # Strip leading and trailing lines:
2613
+ $text = preg_replace('/\A\n+|\n+\z/', '', $text);
2614
+
2615
+ $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
2616
+
2617
+ #
2618
+ # Wrap <p> tags and unhashify HTML blocks
2619
+ #
2620
+ foreach ($grafs as $key => $value) {
2621
+ $value = trim($this->runSpanGamut($value));
2622
+
2623
+ # Check if this should be enclosed in a paragraph.
2624
+ # Clean tag hashes & block tag hashes are left alone.
2625
+ $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value);
2626
+
2627
+ if ($is_p) {
2628
+ $value = "<p>$value</p>";
2629
+ }
2630
+ $grafs[$key] = $value;
2631
+ }
2632
+
2633
+ # Join grafs in one text, then unhash HTML tags.
2634
+ $text = implode("\n\n", $grafs);
2635
+
2636
+ # Finish by removing any tag hashes still present in $text.
2637
+ $text = $this->unhash($text);
2638
+
2639
+ return $text;
2640
+ }
2641
+
2642
+
2643
+ ### Footnotes
2644
+
2645
+ function stripFootnotes($text) {
2646
+ #
2647
+ # Strips link definitions from text, stores the URLs and titles in
2648
+ # hash references.
2649
+ #
2650
+ $less_than_tab = $this->tab_width - 1;
2651
+
2652
+ # Link defs are in the form: [^id]: url "optional title"
2653
+ $text = preg_replace_callback('{
2654
+ ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?: # note_id = $1
2655
+ [ ]*
2656
+ \n? # maybe *one* newline
2657
+ ( # text = $2 (no blank lines allowed)
2658
+ (?:
2659
+ .+ # actual text
2660
+ |
2661
+ \n # newlines but
2662
+ (?!\[\^.+?\]:\s)# negative lookahead for footnote marker.
2663
+ (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed
2664
+ # by non-indented content
2665
+ )*
2666
+ )
2667
+ }xm',
2668
+ array(&$this, '_stripFootnotes_callback'),
2669
+ $text);
2670
+ return $text;
2671
+ }
2672
+ function _stripFootnotes_callback($matches) {
2673
+ $note_id = $this->fn_id_prefix . $matches[1];
2674
+ $this->footnotes[$note_id] = $this->outdent($matches[2]);
2675
+ return ''; # String that will replace the block
2676
+ }
2677
+
2678
+
2679
+ function doFootnotes($text) {
2680
+ #
2681
+ # Replace footnote references in $text [^id] with a special text-token
2682
+ # which will be replaced by the actual footnote marker in appendFootnotes.
2683
+ #
2684
+ if (!$this->in_anchor) {
2685
+ $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text);
2686
+ }
2687
+ return $text;
2688
+ }
2689
+
2690
+
2691
+ function appendFootnotes($text) {
2692
+ #
2693
+ # Append footnote list to text.
2694
+ #
2695
+ $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
2696
+ array(&$this, '_appendFootnotes_callback'), $text);
2697
+
2698
+ if (!empty($this->footnotes_ordered)) {
2699
+ $text .= "\n\n";
2700
+ $text .= "<div class=\"footnotes\">\n";
2701
+ $text .= "<hr". $this->empty_element_suffix ."\n";
2702
+ $text .= "<ol>\n\n";
2703
+
2704
+ $attr = " rev=\"footnote\"";
2705
+ if ($this->fn_backlink_class != "") {
2706
+ $class = $this->fn_backlink_class;
2707
+ $class = $this->encodeAttribute($class);
2708
+ $attr .= " class=\"$class\"";
2709
+ }
2710
+ if ($this->fn_backlink_title != "") {
2711
+ $title = $this->fn_backlink_title;
2712
+ $title = $this->encodeAttribute($title);
2713
+ $attr .= " title=\"$title\"";
2714
+ }
2715
+ $num = 0;
2716
+
2717
+ while (!empty($this->footnotes_ordered)) {
2718
+ $footnote = reset($this->footnotes_ordered);
2719
+ $note_id = key($this->footnotes_ordered);
2720
+ unset($this->footnotes_ordered[$note_id]);
2721
+
2722
+ $footnote .= "\n"; # Need to append newline before parsing.
2723
+ $footnote = $this->runBlockGamut("$footnote\n");
2724
+ $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
2725
+ array(&$this, '_appendFootnotes_callback'), $footnote);
2726
+
2727
+ $attr = str_replace("%%", ++$num, $attr);
2728
+ $note_id = $this->encodeAttribute($note_id);
2729
+
2730
+ # Add backlink to last paragraph; create new paragraph if needed.
2731
+ $backlink = "<a href=\"#fnref:$note_id\"$attr>&#8617;</a>";
2732
+ if (preg_match('{</p>$}', $footnote)) {
2733
+ $footnote = substr($footnote, 0, -4) . "&#160;$backlink</p>";
2734
+ } else {
2735
+ $footnote .= "\n\n<p>$backlink</p>";
2736
+ }
2737
+
2738
+ $text .= "<li id=\"fn:$note_id\">\n";
2739
+ $text .= $footnote . "\n";
2740
+ $text .= "</li>\n\n";
2741
+ }
2742
+
2743
+ $text .= "</ol>\n";
2744
+ $text .= "</div>";
2745
+ }
2746
+ return $text;
2747
+ }
2748
+ function _appendFootnotes_callback($matches) {
2749
+ $node_id = $this->fn_id_prefix . $matches[1];
2750
+
2751
+ # Create footnote marker only if it has a corresponding footnote *and*
2752
+ # the footnote hasn't been used by another marker.
2753
+ if (isset($this->footnotes[$node_id])) {
2754
+ # Transfert footnote content to the ordered list.
2755
+ $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id];
2756
+ unset($this->footnotes[$node_id]);
2757
+
2758
+ $num = $this->footnote_counter++;
2759
+ $attr = " rel=\"footnote\"";
2760
+ if ($this->fn_link_class != "") {
2761
+ $class = $this->fn_link_class;
2762
+ $class = $this->encodeAttribute($class);
2763
+ $attr .= " class=\"$class\"";
2764
+ }
2765
+ if ($this->fn_link_title != "") {
2766
+ $title = $this->fn_link_title;
2767
+ $title = $this->encodeAttribute($title);
2768
+ $attr .= " title=\"$title\"";
2769
+ }
2770
+
2771
+ $attr = str_replace("%%", $num, $attr);
2772
+ $node_id = $this->encodeAttribute($node_id);
2773
+
2774
+ return
2775
+ "<sup id=\"fnref:$node_id\">".
2776
+ "<a href=\"#fn:$node_id\"$attr>$num</a>".
2777
+ "</sup>";
2778
+ }
2779
+
2780
+ return "[^".$matches[1]."]";
2781
+ }
2782
+
2783
+
2784
+ ### Abbreviations ###
2785
+
2786
+ function stripAbbreviations($text) {
2787
+ #
2788
+ # Strips abbreviations from text, stores titles in hash references.
2789
+ #
2790
+ $less_than_tab = $this->tab_width - 1;
2791
+
2792
+ # Link defs are in the form: [id]*: url "optional title"
2793
+ $text = preg_replace_callback('{
2794
+ ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?: # abbr_id = $1
2795
+ (.*) # text = $2 (no blank lines allowed)
2796
+ }xm',
2797
+ array(&$this, '_stripAbbreviations_callback'),
2798
+ $text);
2799
+ return $text;
2800
+ }
2801
+ function _stripAbbreviations_callback($matches) {
2802
+ $abbr_word = $matches[1];
2803
+ $abbr_desc = $matches[2];
2804
+ if ($this->abbr_word_re)
2805
+ $this->abbr_word_re .= '|';
2806
+ $this->abbr_word_re .= preg_quote($abbr_word);
2807
+ $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
2808
+ return ''; # String that will replace the block
2809
+ }
2810
+
2811
+
2812
+ function doAbbreviations($text) {
2813
+ #
2814
+ # Find defined abbreviations in text and wrap them in <abbr> elements.
2815
+ #
2816
+ if ($this->abbr_word_re) {
2817
+ // cannot use the /x modifier because abbr_word_re may
2818
+ // contain significant spaces:
2819
+ $text = preg_replace_callback('{'.
2820
+ '(?<![\w\x1A])'.
2821
+ '(?:'.$this->abbr_word_re.')'.
2822
+ '(?![\w\x1A])'.
2823
+ '}',
2824
+ array(&$this, '_doAbbreviations_callback'), $text);
2825
+ }
2826
+ return $text;
2827
+ }
2828
+ function _doAbbreviations_callback($matches) {
2829
+ $abbr = $matches[0];
2830
+ if (isset($this->abbr_desciptions[$abbr])) {
2831
+ $desc = $this->abbr_desciptions[$abbr];
2832
+ if (empty($desc)) {
2833
+ return $this->hashPart("<abbr>$abbr</abbr>");
2834
+ } else {
2835
+ $desc = $this->encodeAttribute($desc);
2836
+ return $this->hashPart("<abbr title=\"$desc\">$abbr</abbr>");
2837
+ }
2838
+ } else {
2839
+ return $matches[0];
2840
+ }
2841
+ }
2842
+
2843
+ }
2844
+
2845
+
2846
+ /*
2847
+
2848
+ PHP Markdown Extra
2849
+ ==================
2850
+
2851
+ Description
2852
+ -----------
2853
+
2854
+ This is a PHP port of the original Markdown formatter written in Perl
2855
+ by John Gruber. This special "Extra" version of PHP Markdown features
2856
+ further enhancements to the syntax for making additional constructs
2857
+ such as tables and definition list.
2858
+
2859
+ Markdown is a text-to-HTML filter; it translates an easy-to-read /
2860
+ easy-to-write structured text format into HTML. Markdown's text format
2861
+ is most similar to that of plain text email, and supports features such
2862
+ as headers, *emphasis*, code blocks, blockquotes, and links.
2863
+
2864
+ Markdown's syntax is designed not as a generic markup language, but
2865
+ specifically to serve as a front-end to (X)HTML. You can use span-level
2866
+ HTML tags anywhere in a Markdown document, and you can use block level
2867
+ HTML tags (like <div> and <table> as well).
2868
+
2869
+ For more information about Markdown's syntax, see:
2870
+
2871
+ <http://daringfireball.net/projects/markdown/>
2872
+
2873
+
2874
+ Bugs
2875
+ ----
2876
+
2877
+ To file bug reports please send email to:
2878
+
2879
+ <michel.fortin@michelf.com>
2880
+
2881
+ Please include with your report: (1) the example input; (2) the output you
2882
+ expected; (3) the output Markdown actually produced.
2883
+
2884
+
2885
+ Version History
2886
+ ---------------
2887
+
2888
+ See the readme file for detailed release notes for this version.
2889
+
2890
+
2891
+ Copyright and License
2892
+ ---------------------
2893
+
2894
+ PHP Markdown & Extra
2895
+ Copyright (c) 2004-2009 Michel Fortin
2896
+ <http://michelf.com/>
2897
+ All rights reserved.
2898
+
2899
+ Based on Markdown
2900
+ Copyright (c) 2003-2006 John Gruber
2901
+ <http://daringfireball.net/>
2902
+ All rights reserved.
2903
+
2904
+ Redistribution and use in source and binary forms, with or without
2905
+ modification, are permitted provided that the following conditions are
2906
+ met:
2907
+
2908
+ * Redistributions of source code must retain the above copyright notice,
2909
+ this list of conditions and the following disclaimer.
2910
+
2911
+ * Redistributions in binary form must reproduce the above copyright
2912
+ notice, this list of conditions and the following disclaimer in the
2913
+ documentation and/or other materials provided with the distribution.
2914
+
2915
+ * Neither the name "Markdown" nor the names of its contributors may
2916
+ be used to endorse or promote products derived from this software
2917
+ without specific prior written permission.
2918
+
2919
+ This software is provided by the copyright holders and contributors "as
2920
+ is" and any express or implied warranties, including, but not limited
2921
+ to, the implied warranties of merchantability and fitness for a
2922
+ particular purpose are disclaimed. In no event shall the copyright owner
2923
+ or contributors be liable for any direct, indirect, incidental, special,
2924
+ exemplary, or consequential damages (including, but not limited to,
2925
+ procurement of substitute goods or services; loss of use, data, or
2926
+ profits; or business interruption) however caused and on any theory of
2927
+ liability, whether in contract, strict liability, or tort (including
2928
+ negligence or otherwise) arising in any way out of the use of this
2929
+ software, even if advised of the possibility of such damage.
2930
+
2931
+ */
2932
+ ?>
inc/admin/includes/class-readme-parse.php ADDED
@@ -0,0 +1,329 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // This is the path to markdown.php
3
+ if ( !defined('WORDPRESS_README_MARKDOWN') ) {
4
+ if ( defined('AUTOMATTIC_README_MARKDOWN') )
5
+ define( 'WORDPRESS_README_MARKDOWN', AUTOMATTIC_README_MARKDOWN );
6
+ else
7
+ define('WORDPRESS_README_MARKDOWN', dirname(__FILE__) . '/class-markdown-parse.php');
8
+ }
9
+
10
+ Class WordPress_Readme_Parser {
11
+
12
+ function __construct() {
13
+ // This space intentially blank
14
+ }
15
+
16
+ function parse_readme( $file ) {
17
+ $file_contents = @implode('', @file($file));
18
+ return $this->parse_readme_contents( $file_contents );
19
+ }
20
+
21
+ function parse_readme_contents( $file_contents ) {
22
+ $file_contents = str_replace(array("\r\n", "\r"), "\n", $file_contents);
23
+ $file_contents = trim($file_contents);
24
+ if ( 0 === strpos( $file_contents, "\xEF\xBB\xBF" ) )
25
+ $file_contents = substr( $file_contents, 3 );
26
+
27
+ // Markdown transformations
28
+ $file_contents = preg_replace( "|^###([^#]+)#*?\s*?\n|im", '=$1='."\n", $file_contents );
29
+ $file_contents = preg_replace( "|^##([^#]+)#*?\s*?\n|im", '==$1=='."\n", $file_contents );
30
+ $file_contents = preg_replace( "|^#([^#]+)#*?\s*?\n|im", '===$1==='."\n", $file_contents );
31
+
32
+ // === Plugin Name ===
33
+ // Must be the very first thing.
34
+ if ( !preg_match('|^===(.*)===|', $file_contents, $_name) )
35
+ return array('error'); // require a name
36
+ $name = trim($_name[1], '=');
37
+ $name = $this->sanitize_text( $name );
38
+
39
+ $file_contents = $this->chop_string( $file_contents, $_name[0] );
40
+
41
+
42
+ // Requires at least: 1.5
43
+ if ( preg_match('|Requires at least:(.*)|i', $file_contents, $_requires_at_least) )
44
+ $requires_at_least = $this->sanitize_text($_requires_at_least[1]);
45
+ else
46
+ $requires_at_least = NULL;
47
+
48
+
49
+ // Tested up to: 2.1
50
+ if ( preg_match('|Tested up to:(.*)|i', $file_contents, $_tested_up_to) )
51
+ $tested_up_to = $this->sanitize_text( $_tested_up_to[1] );
52
+ else
53
+ $tested_up_to = NULL;
54
+
55
+
56
+ // Stable tag: 10.4-ride-the-fire-eagle-danger-day
57
+ if ( preg_match('|Stable tag:(.*)|i', $file_contents, $_stable_tag) )
58
+ $stable_tag = $this->sanitize_text( $_stable_tag[1] );
59
+ else
60
+ $stable_tag = NULL; // we assume trunk, but don't set it here to tell the difference between specified trunk and default trunk
61
+
62
+
63
+ // Tags: some tag, another tag, we like tags
64
+ if ( preg_match('|Tags:(.*)|i', $file_contents, $_tags) ) {
65
+ $tags = preg_split('|,[\s]*?|', trim($_tags[1]));
66
+ foreach ( array_keys($tags) as $t )
67
+ $tags[$t] = $this->sanitize_text( $tags[$t] );
68
+ } else {
69
+ $tags = array();
70
+ }
71
+
72
+
73
+ // Contributors: markjaquith, mdawaffe, zefrank
74
+ $contributors = array();
75
+ if ( preg_match('|Contributors:(.*)|i', $file_contents, $_contributors) ) {
76
+ $temp_contributors = preg_split('|,[\s]*|', trim($_contributors[1]));
77
+ foreach ( array_keys($temp_contributors) as $c ) {
78
+ $tmp_sanitized = $this->user_sanitize( $temp_contributors[$c] );
79
+ if ( strlen(trim($tmp_sanitized)) > 0 )
80
+ $contributors[$c] = $tmp_sanitized;
81
+ unset($tmp_sanitized);
82
+ }
83
+ }
84
+
85
+
86
+ // Donate Link: URL
87
+ if ( preg_match('|Donate link:(.*)|i', $file_contents, $_donate_link) )
88
+ $donate_link = esc_url( $_donate_link[1] );
89
+ else
90
+ $donate_link = NULL;
91
+
92
+
93
+ // togs, conts, etc are optional and order shouldn't matter. So we chop them only after we've grabbed their values.
94
+ foreach ( array('tags', 'contributors', 'requires_at_least', 'tested_up_to', 'stable_tag', 'donate_link') as $chop ) {
95
+ if ( $$chop ) {
96
+ $_chop = '_' . $chop;
97
+ $file_contents = $this->chop_string( $file_contents, ${$_chop}[0] );
98
+ }
99
+ }
100
+
101
+ $file_contents = trim($file_contents);
102
+
103
+
104
+ // short-description fu
105
+ if ( !preg_match('/(^(.*?))^[\s]*=+?[\s]*.+?[\s]*=+?/ms', $file_contents, $_short_description) )
106
+ $_short_description = array( 1 => &$file_contents, 2 => &$file_contents );
107
+ $short_desc_filtered = $this->sanitize_text( $_short_description[2] );
108
+ $short_desc_length = strlen($short_desc_filtered);
109
+ $short_description = substr($short_desc_filtered, 0, 150);
110
+ if ( $short_desc_length > strlen($short_description) )
111
+ $truncated = true;
112
+ else
113
+ $truncated = false;
114
+ if ( $_short_description[1] )
115
+ $file_contents = $this->chop_string( $file_contents, $_short_description[1] ); // yes, the [1] is intentional
116
+
117
+ // == Section ==
118
+ // Break into sections
119
+ // $_sections[0] will be the title of the first section, $_sections[1] will be the content of the first section
120
+ // the array alternates from there: title2, content2, title3, content3... and so forth
121
+ $_sections = preg_split('/^[\s]*==[\s]*(.+?)[\s]*==/m', $file_contents, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
122
+
123
+ $sections = array();
124
+ for ( $i=1; $i <= count($_sections); $i +=2 ) {
125
+ $_sections[$i] = preg_replace('/^[\s]*=[\s]+(.+?)[\s]+=/m', '<h4>$1</h4>', $_sections[$i]);
126
+ $_sections[$i] = $this->filter_text( $_sections[$i], true );
127
+ $title = $this->sanitize_text( $_sections[$i-1] );
128
+ $sections[str_replace(' ', '_', strtolower($title))] = array('title' => $title, 'content' => $_sections[$i]);
129
+ }
130
+
131
+
132
+ // Special sections
133
+ // This is where we nab our special sections, so we can enforce their order and treat them differently, if needed
134
+ // upgrade_notice is not a section, but parse it like it is for now
135
+ $final_sections = array();
136
+ foreach ( array('description', 'installation', 'frequently_asked_questions', 'screenshots', 'changelog', 'change_log', 'upgrade_notice') as $special_section ) {
137
+ if ( isset($sections[$special_section]) ) {
138
+ $final_sections[$special_section] = $sections[$special_section]['content'];
139
+ unset($sections[$special_section]);
140
+ }
141
+ }
142
+ if ( isset($final_sections['change_log']) && empty($final_sections['changelog']) )
143
+ $final_sections['changelog'] = $final_sections['change_log'];
144
+
145
+
146
+ $final_screenshots = array();
147
+ if ( isset($final_sections['screenshots']) ) {
148
+ preg_match_all('|<li>(.*?)</li>|s', $final_sections['screenshots'], $screenshots, PREG_SET_ORDER);
149
+ if ( $screenshots ) {
150
+ foreach ( (array) $screenshots as $ss )
151
+ $final_screenshots[] = $ss[1];
152
+ }
153
+ }
154
+
155
+ // Parse the upgrade_notice section specially:
156
+ // 1.0 => blah, 1.1 => fnord
157
+ if ( isset($final_sections['upgrade_notice']) ) {
158
+ $upgrade_notice = array();
159
+ $split = preg_split( '#<h4>(.*?)</h4>#', $final_sections['upgrade_notice'], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
160
+ for ( $i = 0; $i < count( $split ); $i += 2 )
161
+ $upgrade_notice[$this->sanitize_text( $split[$i] )] = substr( $this->sanitize_text( $split[$i + 1] ), 0, 300 );
162
+ unset( $final_sections['upgrade_notice'] );
163
+ }
164
+
165
+ // No description?
166
+ // No problem... we'll just fall back to the old style of description
167
+ // We'll even let you use markup this time!
168
+ $excerpt = false;
169
+ if ( !isset($final_sections['description']) ) {
170
+ $final_sections = array_merge(array('description' => $this->filter_text( $_short_description[2], true )), $final_sections);
171
+ $excerpt = true;
172
+ }
173
+
174
+
175
+ // dump the non-special sections into $remaining_content
176
+ // their order will be determined by their original order in the readme.txt
177
+ $remaining_content = '';
178
+ foreach ( $sections as $s_name => $s_data ) {
179
+ $remaining_content .= "\n<h3>{$s_data['title']}</h3>\n{$s_data['content']}";
180
+ }
181
+ $remaining_content = trim($remaining_content);
182
+
183
+
184
+ // All done!
185
+ // $r['tags'] and $r['contributors'] are simple arrays
186
+ // $r['sections'] is an array with named elements
187
+ $r = array(
188
+ 'name' => $name,
189
+ 'tags' => $tags,
190
+ 'requires_at_least' => $requires_at_least,
191
+ 'tested_up_to' => $tested_up_to,
192
+ 'stable_tag' => $stable_tag,
193
+ 'contributors' => $contributors,
194
+ 'donate_link' => $donate_link,
195
+ 'short_description' => $short_description,
196
+ 'screenshots' => $final_screenshots,
197
+ 'is_excerpt' => $excerpt,
198
+ 'is_truncated' => $truncated,
199
+ 'sections' => $final_sections,
200
+ 'remaining_content' => $remaining_content,
201
+ 'upgrade_notice' => $upgrade_notice
202
+ );
203
+
204
+ return $r;
205
+ }
206
+
207
+ function chop_string( $string, $chop ) { // chop a "prefix" from a string: Agressive! uses strstr not 0 === strpos
208
+ if ( $_string = strstr($string, $chop) ) {
209
+ $_string = substr($_string, strlen($chop));
210
+ return trim($_string);
211
+ } else {
212
+ return trim($string);
213
+ }
214
+ }
215
+
216
+ function user_sanitize( $text, $strict = false ) { // whitelisted chars
217
+ if ( function_exists('user_sanitize') ) // bbPress native
218
+ return user_sanitize( $text, $strict );
219
+
220
+ if ( $strict ) {
221
+ $text = preg_replace('/[^a-z0-9-]/i', '', $text);
222
+ $text = preg_replace('|-+|', '-', $text);
223
+ } else {
224
+ $text = preg_replace('/[^a-z0-9_-]/i', '', $text);
225
+ }
226
+ return $text;
227
+ }
228
+
229
+ function sanitize_text( $text ) { // not fancy
230
+ $text = strip_tags($text);
231
+ $text = esc_html($text);
232
+ $text = trim($text);
233
+ return $text;
234
+ }
235
+
236
+ function filter_text( $text, $markdown = false ) { // fancy, Markdown
237
+ $text = trim($text);
238
+
239
+ $text = call_user_func( array( __CLASS__, 'code_trick' ), $text, $markdown ); // A better parser than Markdown's for: backticks -> CODE
240
+
241
+ if ( $markdown ) { // Parse markdown.
242
+ if ( !function_exists('Markdown') )
243
+ require( WORDPRESS_README_MARKDOWN );
244
+ $text = Markdown($text);
245
+ }
246
+
247
+ $allowed = array(
248
+ 'a' => array(
249
+ 'href' => array(),
250
+ 'title' => array(),
251
+ 'rel' => array()),
252
+ 'blockquote' => array('cite' => array()),
253
+ 'br' => array(),
254
+ 'p' => array(),
255
+ 'code' => array(),
256
+ 'pre' => array(),
257
+ 'em' => array(),
258
+ 'strong' => array(),
259
+ 'ul' => array(),
260
+ 'ol' => array(),
261
+ 'li' => array(),
262
+ 'h3' => array(),
263
+ 'h4' => array()
264
+ );
265
+
266
+ $text = balanceTags($text);
267
+
268
+ $text = wp_kses( $text, $allowed );
269
+ $text = trim($text);
270
+ return $text;
271
+ }
272
+
273
+ function code_trick( $text, $markdown ) { // Don't use bbPress native function - it's incompatible with Markdown
274
+ // If doing markdown, first take any user formatted code blocks and turn them into backticks so that
275
+ // markdown will preserve things like underscores in code blocks
276
+ if ( $markdown )
277
+ $text = preg_replace_callback("!(<pre><code>|<code>)(.*?)(</code></pre>|</code>)!s", array( __CLASS__,'decodeit'), $text);
278
+
279
+ $text = str_replace(array("\r\n", "\r"), "\n", $text);
280
+ if ( !$markdown ) {
281
+ // This gets the "inline" code blocks, but can't be used with Markdown.
282
+ $text = preg_replace_callback("|(`)(.*?)`|", array( __CLASS__, 'encodeit'), $text);
283
+ // This gets the "block level" code blocks and converts them to PRE CODE
284
+ $text = preg_replace_callback("!(^|\n)`(.*?)`!s", array( __CLASS__, 'encodeit'), $text);
285
+ } else {
286
+ // Markdown can do inline code, we convert bbPress style block level code to Markdown style
287
+ $text = preg_replace_callback("!(^|\n)([ \t]*?)`(.*?)`!s", array( __CLASS__, 'indent'), $text);
288
+ }
289
+ return $text;
290
+ }
291
+
292
+ function indent( $matches ) {
293
+ $text = $matches[3];
294
+ $text = preg_replace('|^|m', $matches[2] . ' ', $text);
295
+ return $matches[1] . $text;
296
+ }
297
+
298
+ function encodeit( $matches ) {
299
+ if ( function_exists('encodeit') ) // bbPress native
300
+ return encodeit( $matches );
301
+
302
+ $text = trim($matches[2]);
303
+ $text = htmlspecialchars($text, ENT_QUOTES);
304
+ $text = str_replace(array("\r\n", "\r"), "\n", $text);
305
+ $text = preg_replace("|\n\n\n+|", "\n\n", $text);
306
+ $text = str_replace('&amp;lt;', '&lt;', $text);
307
+ $text = str_replace('&amp;gt;', '&gt;', $text);
308
+ $text = "<code>$text</code>";
309
+ if ( "`" != $matches[1] )
310
+ $text = "<pre>$text</pre>";
311
+ return $text;
312
+ }
313
+
314
+ function decodeit( $matches ) {
315
+ if ( function_exists('decodeit') ) // bbPress native
316
+ return decodeit( $matches );
317
+
318
+ $text = $matches[2];
319
+ $trans_table = array_flip(get_html_translation_table(HTML_ENTITIES));
320
+ $text = strtr($text, $trans_table);
321
+ $text = str_replace('<br />', '', $text);
322
+ $text = str_replace('&#38;', '&', $text);
323
+ $text = str_replace('&#39;', "'", $text);
324
+ if ( '<pre><code>' == $matches[1] )
325
+ $text = "\n$text\n";
326
+ return "`$text`";
327
+ }
328
+
329
+ } // end class
inc/admin/lp-admin-functions.php ADDED
@@ -0,0 +1,1283 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ *
40
+ * @return bool
41
+ */
42
+ function learn_press_admin_view( $name, $args = array(), $include_once = false ) {
43
+ $view = learn_press_get_admin_view( $name, !empty( $args['plugin_file'] ) ? $args['plugin_file'] : null );
44
+ if ( file_exists( $view ) ) {
45
+ // extract parameters as local variables if passed
46
+ is_array( $args ) && extract( $args );
47
+ do_action( 'learn_press_before_display_admin_view', $name, $args );
48
+ if ( $include_once ) {
49
+ include_once $view;
50
+ } else {
51
+ include $view;
52
+ }
53
+ do_action( 'learn_press_after_display_admin_view', $name, $args );
54
+ return true;
55
+ }
56
+ return false;
57
+ }
58
+
59
+ /**
60
+ * List all pages as a dropdown with "Add New Page" option
61
+ *
62
+ * @param $name
63
+ * @param bool|false $selected
64
+ * @param array $args
65
+ *
66
+ * @return mixed|string
67
+ */
68
+ function learn_press_pages_dropdown( $name, $selected = false, $args = array() ) {
69
+ $id = null;
70
+ $class = null;
71
+ $css = null;
72
+ $before = array(
73
+ 'add_new_page' => __( '[ Add a new page ]', 'learnpress' )
74
+ );
75
+ $after = null;
76
+ $echo = true;
77
+ $allow_create = true;
78
+ is_array( $args ) && extract( $args );
79
+
80
+ if ( empty( $id ) ) {
81
+ $id = $name;
82
+ }
83
+ $args = array(
84
+ 'name' => $name,
85
+ 'id' => $id,
86
+ 'sort_column' => 'menu_order',
87
+ 'sort_order' => 'ASC',
88
+ 'show_option_none' => __( 'Select Page', 'learnpress' ),
89
+ 'class' => $class,
90
+ 'echo' => false,
91
+ 'selected' => $selected,
92
+ 'allow_create' => true
93
+ );
94
+ $output = wp_dropdown_pages( $args );
95
+ $replace = "";
96
+
97
+ $class .= 'learn-press-dropdown-pages';
98
+
99
+ if ( $class ) {
100
+ $replace .= ' class="' . $class . '"';
101
+ }
102
+ if ( $css ) {
103
+ $replace .= ' style="' . $css . '"';
104
+ }
105
+
106
+ $replace .= ' data-selected="' . $selected . '"';
107
+ $replace .= " data-placeholder='" . __( 'Select a page&hellip;', 'learnpress' ) . "' id=";
108
+ $output = str_replace( ' id=', $replace, $output );
109
+ if ( $before ) {
110
+ $before_output = array();
111
+ foreach ( $before as $v => $l ) {
112
+ $before_output[] = sprintf( '<option value="%s">%s</option>', $v, $l );
113
+ }
114
+ $before_output = join( "\n", $before_output );
115
+ $output = preg_replace( '!(<option class=".*" value="[0-9]+".*>.*</option>)!', $before_output . "\n$1", $output, 1 );
116
+ }
117
+ if ( $allow_create ) {
118
+ ob_start(); ?>
119
+ <p class="learn-press-quick-add-page-inline <?php echo $id; ?> hide-if-js">
120
+ <input type="text" />
121
+ <button class="button" type="button"><?php _e( 'Ok', 'learnpress' ); ?></button>
122
+ <a href=""><?php _e( 'Cancel', 'learnpress' ); ?></a>
123
+ </p>
124
+ <p class="learn-press-quick-add-page-actions <?php echo $id; ?><?php echo $selected ? '' : ' hide-if-js'; ?>">
125
+ <a class="edit-page" href="<?php echo get_edit_post_link( $selected ); ?>" target="_blank"><?php _e( 'Edit Page', 'learnpress' ); ?></a>
126
+ <a class="view-page" href="<?php echo get_permalink( $selected ); ?>" target="_blank"><?php _e( 'View Page', 'learnpress' ); ?></a>
127
+ </p>
128
+ <?php $output .= ob_get_clean();
129
+ }
130
+ if ( $echo ) {
131
+ echo $output;
132
+ }
133
+
134
+ return $output;
135
+ }
136
+
137
+
138
+ /**************************************************/
139
+ /**************************************************/
140
+ /**************************************************/
141
+
142
+ /**
143
+ * Translate javascript text
144
+ */
145
+ function learn_press_admin_localize_script() {
146
+ if ( defined( 'DOING_AJAX' ) || !is_admin() ) return;
147
+ $translate = array(
148
+ 'quizzes_is_not_available' => __( 'Quiz is not available', 'learnpress' ),
149
+ 'lessons_is_not_available' => __( 'Lesson is not available', 'learnpress' )
150
+ );
151
+ LP_Admin_Assets::add_localize( $translate );
152
+ }
153
+
154
+ add_action( 'init', 'learn_press_admin_localize_script' );
155
+
156
+ /**
157
+ * Default admin settings pages
158
+ *
159
+ * @return mixed
160
+ */
161
+ function learn_press_settings_tabs_array() {
162
+ $tabs = array(
163
+ 'general' => __( 'General', 'learnpress' ),
164
+ 'courses' => __( 'Courses', 'learnpress' ),
165
+ 'pages' => __( 'Pages', 'learnpress' ),
166
+ 'payments' => __( 'Payments', 'learnpress' ),
167
+ 'checkout' => __( 'Checkout', 'learnpress' ),
168
+ //'profile' => __( 'Profile', 'learnpress' ),
169
+ 'emails' => __( 'Emails', 'learnpress' )
170
+ );
171
+ return apply_filters( 'learn_press_settings_tabs_array', $tabs );
172
+ }
173
+
174
+ /**
175
+ * Count number of orders between to dates
176
+ *
177
+ * @param string
178
+ * @param int
179
+ *
180
+ * @return int
181
+ */
182
+ function learn_press_get_order_by_time( $by, $time ) {
183
+ global $wpdb;
184
+ $user_id = get_current_user_id();
185
+
186
+ $y = date( 'Y', $time );
187
+ $m = date( 'm', $time );
188
+ $d = date( 'd', $time );
189
+ switch ( $by ) {
190
+ case 'days':
191
+ $orders = $wpdb->get_var(
192
+ $wpdb->prepare(
193
+ "SELECT COUNT(*)
194
+ FROM $wpdb->posts AS p
195
+ INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
196
+ WHERE p.post_author = %d
197
+ AND p.post_type = %s
198
+ AND p.post_status = %s
199
+ AND m.meta_key = %s
200
+ AND m.meta_value = %s
201
+ AND YEAR(p.post_date) = %s AND MONTH(p.post_date) = %s AND DAY(p.post_date) = %s",
202
+ $user_id, LP()->order_post_type, 'publish', '_learn_press_transaction_status', 'completed', $y, $m, $d
203
+ )
204
+ );
205
+ break;
206
+ case 'months':
207
+ $orders = $wpdb->get_var(
208
+ $wpdb->prepare(
209
+ "SELECT COUNT(*)
210
+ FROM $wpdb->posts AS p
211
+ INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
212
+ WHERE p.post_author = %d
213
+ AND p.post_type = %s
214
+ AND p.post_status = %s
215
+ AND m.meta_key = %s
216
+ AND m.meta_value = %s
217
+ AND YEAR(p.post_date) = %s AND MONTH(p.post_date) = %s",
218
+ $user_id, LP()->order_post_type, 'publish', '_learn_press_transaction_status', 'completed', $y, $m
219
+ )
220
+ );
221
+ break;
222
+ }
223
+ return $orders;
224
+ }
225
+
226
+ /**
227
+ * Count number of orders by status
228
+ *
229
+ * @param string Status of the orders
230
+ *
231
+ * @return int
232
+ */
233
+ function learn_press_get_courses_by_status( $status ) {
234
+ global $wpdb;
235
+ $user_id = get_current_user_id();
236
+ $courses = $wpdb->get_var(
237
+ $wpdb->prepare(
238
+ "SELECT COUNT(*)
239
+ FROM $wpdb->posts
240
+ WHERE post_author = %d
241
+ AND post_type = %s
242
+ AND post_status = %s",
243
+ $user_id, LP()->course_post_type, $status
244
+ )
245
+ );
246
+ return $courses;
247
+ }
248
+
249
+ /**
250
+ * Count number of orders by price
251
+ *
252
+ * @param string
253
+ *
254
+ * @return int
255
+ */
256
+ function learn_press_get_courses_by_price( $fee ) {
257
+ global $wpdb;
258
+ $user_id = get_current_user_id();
259
+ $courses = $wpdb->get_var(
260
+ $wpdb->prepare(
261
+ "SELECT COUNT(*)
262
+ FROM $wpdb->posts AS p
263
+ INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
264
+ WHERE p.post_author = %d
265
+ AND p.post_type = %s
266
+ AND p.post_status IN (%s, %s)
267
+ AND m.meta_key = %s
268
+ AND m.meta_value = %s",
269
+ $user_id, LP()->course_post_type, 'publish', 'pending', '_lpr_course_payment', $fee
270
+ )
271
+ );
272
+ return $courses;
273
+ }
274
+
275
+ /**
276
+ * Get data about students to render in chart
277
+ *
278
+ * @param null $from
279
+ * @param null $by
280
+ * @param $time_ago
281
+ *
282
+ * @return array
283
+ */
284
+ function learn_press_get_chart_students( $from = null, $by = null, $time_ago ) {
285
+ $labels = array();
286
+ $datasets = array();
287
+ if ( is_null( $from ) ) {
288
+ $from = current_time( 'mysql' );
289
+ }
290
+ // $by: days, months or years
291
+ if ( is_null( $by ) ) {
292
+ $by = 'days';
293
+ }
294
+ switch ( $by ) {
295
+ case 'days':
296
+ $date_format = 'M d';
297
+ break;
298
+ case 'months':
299
+ $date_format = 'M Y';
300
+ break;
301
+ case 'years':
302
+ $date_format = 'Y';
303
+ break;
304
+ }
305
+
306
+ for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
307
+ $labels[] = date( $date_format, strtotime( "$i $by", strtotime( $from ) ) );
308
+ $datasets[0]['data'][] = learn_press_get_order_by_time( $by, strtotime( "$i $by", strtotime( $from ) ) );
309
+ }
310
+ $colors = learn_press_get_admin_colors();
311
+ $datasets[0]['fillColor'] = 'rgba(255,255,255,0.1)';
312
+ $datasets[0]['strokeColor'] = $colors[0];
313
+ $datasets[0]['pointColor'] = $colors[0];
314
+ $datasets[0]['pointStrokeColor'] = $colors[2];
315
+ $datasets[0]['pointHighlightFill'] = $colors[2];
316
+ $datasets[0]['pointHighlightStroke'] = $colors[0];
317
+ return array(
318
+ 'labels' => $labels,
319
+ 'datasets' => $datasets
320
+ );
321
+ }
322
+
323
+ /**
324
+ * Get data about students to render in chart
325
+ *
326
+ * @param null $from
327
+ * @param null $by
328
+ * @param $time_ago
329
+ *
330
+ * @return array
331
+ */
332
+ function learn_press_get_chart_users( $from = null, $by = null, $time_ago ) {
333
+ global $wpdb;
334
+
335
+ $labels = array();
336
+ $datasets = array();
337
+ if ( is_null( $from ) ) {
338
+ $from = current_time( 'mysql' );
339
+ }
340
+ if ( is_null( $by ) ) {
341
+ $by = 'days';
342
+ }
343
+ $results = array(
344
+ 'all' => array(),
345
+ 'instructors' => array()
346
+ );
347
+ $from_time = is_numeric( $from ) ? $from : strtotime( $from );
348
+
349
+ switch ( $by ) {
350
+ case 'days':
351
+ $date_format = 'M d Y';
352
+ $_from = - $time_ago + 1;
353
+ $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
354
+ $_to = date( 'Y-m-d', $from_time );
355
+ $_sql_format = '%Y-%m-%d';
356
+ $_key_format = 'Y-m-d';
357
+ break;
358
+ case 'months':
359
+ $date_format = 'M Y';
360
+ $_from = - $time_ago + 1;
361
+ $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
362
+ $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
363
+ $_to = date( 'Y-m-' . $days, $from_time );
364
+ $_sql_format = '%Y-%m';
365
+ $_key_format = 'Y-m';
366
+ break;
367
+ case 'years':
368
+ $date_format = 'Y';
369
+ $_from = - $time_ago + 1;
370
+ $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
371
+ $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
372
+ $_to = date( 'Y-12-' . $days, $from_time );
373
+ $_sql_format = '%Y';
374
+ $_key_format = 'Y';
375
+
376
+ break;
377
+ }
378
+ $query = $wpdb->prepare( "
379
+ SELECT count(u.ID) as c, DATE_FORMAT( u.user_registered, %s) as d
380
+ FROM {$wpdb->users} u
381
+ WHERE 1
382
+ GROUP BY d
383
+ HAVING d BETWEEN %s AND %s
384
+ ORDER BY d ASC
385
+ ", $_sql_format, $_from, $_to );
386
+ if ( $_results = $wpdb->get_results( $query ) ) {
387
+ foreach ( $_results as $k => $v ) {
388
+ $results['all'][$v->d] = $v;
389
+ }
390
+ }
391
+ $query = $wpdb->prepare( "
392
+ SELECT count(u.ID) as c, DATE_FORMAT( u.user_registered, %s) as d
393
+ FROM {$wpdb->users} u
394
+ 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 )
395
+ WHERE 1
396
+ GROUP BY d
397
+ HAVING d BETWEEN %s AND %s
398
+ ORDER BY d ASC
399
+ ", $_sql_format, 'wp_capabilities', '%' . $wpdb->esc_like( 's:13:"administrator"' ) . '%', '%' . $wpdb->esc_like( 's:10:"lp_teacher"' ) . '%', $_from, $_to );
400
+
401
+ if ( $_results = $wpdb->get_results( $query ) ) {
402
+ foreach ( $_results as $k => $v ) {
403
+ $results['instructors'][$v->d] = $v;
404
+ }
405
+ }
406
+ for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
407
+ $date = strtotime( "$i $by", $from_time );
408
+ $labels[] = date( $date_format, $date );
409
+ $key = date( $_key_format, $date );
410
+
411
+ $all = !empty( $results['all'][$key] ) ? $results['all'][$key]->c : 0;
412
+ $instructors = !empty( $results['instructors'][$key] ) ? $results['instructors'][$key]->c : 0;
413
+
414
+ $datasets[0]['data'][] = $all;
415
+ $datasets[1]['data'][] = $instructors;
416
+ $datasets[2]['data'][] = $all - $instructors;
417
+ }
418
+
419
+ $dataset_params = array(
420
+ array(
421
+ 'color1' => 'rgba(47, 167, 255, %s)',
422
+ 'color2' => '#FFF',
423
+ 'label' => __( 'All', 'learnpress' )
424
+ ),
425
+ array(
426
+ 'color1' => 'rgba(212, 208, 203, %s)',
427
+ 'color2' => '#FFF',
428
+ 'label' => __( 'Instructors', 'learnpress' )
429
+ ),
430
+ array(
431
+ 'color1' => 'rgba(234, 199, 155, %s)',
432
+ 'color2' => '#FFF',
433
+ 'label' => __( 'Students', 'learnpress' )
434
+ )
435
+ );
436
+
437
+ foreach ( $dataset_params as $k => $v ) {
438
+ $datasets[$k]['fillColor'] = sprintf( $v['color1'], '0.2' );
439
+ $datasets[$k]['strokeColor'] = sprintf( $v['color1'], '1' );
440
+ $datasets[$k]['pointColor'] = sprintf( $v['color1'], '1' );
441
+ $datasets[$k]['pointStrokeColor'] = $v['color2'];
442
+ $datasets[$k]['pointHighlightFill'] = $v['color2'];
443
+ $datasets[$k]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
444
+ $datasets[$k]['label'] = $v['label'];
445
+ }
446
+
447
+ return array(
448
+ 'labels' => $labels,
449
+ 'datasets' => $datasets,
450
+ 'sql' => $query
451
+ );
452
+ }
453
+
454
+
455
+ /**
456
+ * Get data about students to render in chart
457
+ *
458
+ * @param null $from
459
+ * @param null $by
460
+ * @param $time_ago
461
+ *
462
+ * @return array
463
+ */
464
+ function learn_press_get_chart_courses( $from = null, $by = null, $time_ago ) {
465
+ global $wpdb;
466
+
467
+ $labels = array();
468
+ $datasets = array();
469
+ if ( is_null( $from ) ) {
470
+ $from = current_time( 'mysql' );
471
+ }
472
+ if ( is_null( $by ) ) {
473
+ $by = 'days';
474
+ }
475
+ $results = array(
476
+ 'all' => array(),
477
+ 'public' => array(),
478
+ 'pending' => array(),
479
+ 'free' => array(),
480
+ 'paid' => 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
+
514
+ $query = $wpdb->prepare( "
515
+ SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
516
+ FROM {$wpdb->posts} c
517
+ WHERE 1
518
+ AND c.post_status IN('publish', 'pending') AND c.post_type = %s
519
+ GROUP BY d
520
+ HAVING d BETWEEN %s AND %s
521
+ ORDER BY d ASC
522
+ ", $_sql_format, 'lp_course', $_from, $_to );
523
+ if ( $_results = $wpdb->get_results( $query ) ) {
524
+ foreach ( $_results as $k => $v ) {
525
+ $results['all'][$v->d] = $v;
526
+ }
527
+ }
528
+ $query = $wpdb->prepare( "
529
+ SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
530
+ FROM {$wpdb->posts} c
531
+ WHERE 1
532
+ AND c.post_status = %s AND c.post_type = %s
533
+ GROUP BY d
534
+ HAVING d BETWEEN %s AND %s
535
+ ORDER BY d ASC
536
+ ", $_sql_format, 'publish', 'lp_course', $_from, $_to );
537
+ if ( $_results = $wpdb->get_results( $query ) ) {
538
+ foreach ( $_results as $k => $v ) {
539
+ $results['publish'][$v->d] = $v;
540
+ }
541
+ }
542
+
543
+ $query = $wpdb->prepare( "
544
+ SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
545
+ FROM {$wpdb->posts} c
546
+ INNER JOIN {$wpdb->postmeta} cm ON cm.post_id = c.ID AND cm.meta_key = %s AND cm.meta_value = %s
547
+ WHERE 1
548
+ AND c.post_status = %s AND c.post_type = %s
549
+ GROUP BY d
550
+ HAVING d BETWEEN %s AND %s
551
+ ORDER BY d ASC
552
+ ", $_sql_format, '_lp_payment', 'yes', 'publish', 'lp_course', $_from, $_to );
553
+ if ( $_results = $wpdb->get_results( $query ) ) {
554
+ foreach ( $_results as $k => $v ) {
555
+ $results['paid'][$v->d] = $v;
556
+ }
557
+ }
558
+
559
+ for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
560
+ $date = strtotime( "$i $by", $from_time );
561
+ $labels[] = date( $date_format, $date );
562
+ $key = date( $_key_format, $date );
563
+
564
+ $all = !empty( $results['all'][$key] ) ? $results['all'][$key]->c : 0;
565
+ $publish = !empty( $results['publish'][$key] ) ? $results['publish'][$key]->c : 0;
566
+ $paid = !empty( $results['paid'][$key] ) ? $results['paid'][$key]->c : 0;
567
+
568
+ $datasets[0]['data'][] = $all;
569
+ $datasets[1]['data'][] = $publish;
570
+ $datasets[2]['data'][] = $all - $publish;
571
+ $datasets[3]['data'][] = $paid;
572
+ $datasets[4]['data'][] = $all - $paid;
573
+ }
574
+
575
+ $dataset_params = array(
576
+ array(
577
+ 'color1' => 'rgba(47, 167, 255, %s)',
578
+ 'color2' => '#FFF',
579
+ 'label' => __( 'All', 'learnpress' )
580
+ ),
581
+ array(
582
+ 'color1' => 'rgba(212, 208, 203, %s)',
583
+ 'color2' => '#FFF',
584
+ 'label' => __( 'Publish', 'learnpress' )
585
+ ),
586
+ array(
587
+ 'color1' => 'rgba(234, 199, 155, %s)',
588
+ 'color2' => '#FFF',
589
+ 'label' => __( 'Pending', 'learnpress' )
590
+ ),
591
+ array(
592
+ 'color1' => 'rgba(234, 199, 155, %s)',
593
+ 'color2' => '#FFF',
594
+ 'label' => __( 'Paid', 'learnpress' )
595
+ ),
596
+ array(
597
+ 'color1' => 'rgba(234, 199, 155, %s)',
598
+ 'color2' => '#FFF',
599
+ 'label' => __( 'Free', 'learnpress' )
600
+ )
601
+ );
602
+
603
+ foreach ( $dataset_params as $k => $v ) {
604
+ $datasets[$k]['fillColor'] = sprintf( $v['color1'], '0.2' );
605
+ $datasets[$k]['strokeColor'] = sprintf( $v['color1'], '1' );
606
+ $datasets[$k]['pointColor'] = sprintf( $v['color1'], '1' );
607
+ $datasets[$k]['pointStrokeColor'] = $v['color2'];
608
+ $datasets[$k]['pointHighlightFill'] = $v['color2'];
609
+ $datasets[$k]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
610
+ $datasets[$k]['label'] = $v['label'];
611
+ }
612
+
613
+ return array(
614
+ 'labels' => $labels,
615
+ 'datasets' => $datasets,
616
+ 'sql' => $query
617
+ );
618
+ }
619
+
620
+
621
+ /**
622
+ * Get data about students to render in chart
623
+ *
624
+ * @param null $from
625
+ * @param null $by
626
+ * @param $time_ago
627
+ *
628
+ * @return array
629
+ */
630
+ function learn_press_get_chart_orders( $from = null, $by = null, $time_ago ) {
631
+ global $wpdb;
632
+
633
+ $labels = array();
634
+ $datasets = array();
635
+ if ( is_null( $from ) ) {
636
+ $from = current_time( 'mysql' );
637
+ }
638
+ if ( is_null( $by ) ) {
639
+ $by = 'days';
640
+ }
641
+ $results = array(
642
+ 'all' => array(),
643
+ 'completed' => array(),
644
+ 'pending' => array()
645
+ );
646
+ $from_time = is_numeric( $from ) ? $from : strtotime( $from );
647
+
648
+ switch ( $by ) {
649
+ case 'days':
650
+ $date_format = 'M d Y';
651
+ $_from = - $time_ago + 1;
652
+ $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
653
+ $_to = date( 'Y-m-d', $from_time );
654
+ $_sql_format = '%Y-%m-%d';
655
+ $_key_format = 'Y-m-d';
656
+ break;
657
+ case 'months':
658
+ $date_format = 'M Y';
659
+ $_from = - $time_ago + 1;
660
+ $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
661
+ $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
662
+ $_to = date( 'Y-m-' . $days, $from_time );
663
+ $_sql_format = '%Y-%m';
664
+ $_key_format = 'Y-m';
665
+ break;
666
+ case 'years':
667
+ $date_format = 'Y';
668
+ $_from = - $time_ago + 1;
669
+ $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
670
+ $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
671
+ $_to = date( 'Y-12-' . $days, $from_time );
672
+ $_sql_format = '%Y';
673
+ $_key_format = 'Y';
674
+
675
+ break;
676
+ }
677
+
678
+ $query = $wpdb->prepare( "
679
+ SELECT count(o.ID) as c, DATE_FORMAT( o.post_date, %s) as d
680
+ FROM {$wpdb->posts} o
681
+ WHERE 1
682
+ AND o.post_status IN('lp-completed') AND o.post_type = %s
683
+ GROUP BY d
684
+ HAVING d BETWEEN %s AND %s
685
+ ORDER BY d ASC
686
+ ", $_sql_format, 'lp_order', $_from, $_to );
687
+ if ( $_results = $wpdb->get_results( $query ) ) {
688
+ foreach ( $_results as $k => $v ) {
689
+ $results['all'][$v->d] = $v;
690
+ }
691
+ }
692
+ $query = $wpdb->prepare( "
693
+ SELECT count(o.ID) as c, DATE_FORMAT( o.post_date, %s) as d
694
+ FROM {$wpdb->posts} o
695
+ WHERE 1
696
+ AND o.post_status IN('lp-pending', 'lp-processing') AND o.post_type = %s
697
+ GROUP BY d
698
+ HAVING d BETWEEN %s AND %s
699
+ ORDER BY d ASC
700
+ ", $_sql_format, 'lp_order', $_from, $_to );
701
+ if ( $_results = $wpdb->get_results( $query ) ) {
702
+ foreach ( $_results as $k => $v ) {
703
+ $results['completed'][$v->d] = $v;
704
+ }
705
+ }
706
+
707
+
708
+ for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
709
+ $date = strtotime( "$i $by", $from_time );
710
+ $labels[] = date( $date_format, $date );
711
+ $key = date( $_key_format, $date );
712
+
713
+ $all = !empty( $results['all'][$key] ) ? $results['all'][$key]->c : 0;
714
+ $completed = !empty( $results['completed'][$key] ) ? $results['completed'][$key]->c : 0;
715
+
716
+ $datasets[0]['data'][] = $all;
717
+ $datasets[1]['data'][] = $completed;
718
+ $datasets[2]['data'][] = $all - $completed;
719
+ }
720
+
721
+ $dataset_params = array(
722
+ array(
723
+ 'color1' => 'rgba(47, 167, 255, %s)',
724
+ 'color2' => '#FFF',
725
+ 'label' => __( 'All', 'learnpress' )
726
+ ),
727
+ array(
728
+ 'color1' => 'rgba(212, 208, 203, %s)',
729
+ 'color2' => '#FFF',
730
+ 'label' => __( 'Completed', 'learnpress' )
731
+ ),
732
+ array(
733
+ 'color1' => 'rgba(234, 199, 155, %s)',
734
+ 'color2' => '#FFF',
735
+ 'label' => __( 'Pending', 'learnpress' )
736
+ )
737
+ );
738
+
739
+ foreach ( $dataset_params as $k => $v ) {
740
+ $datasets[$k]['fillColor'] = sprintf( $v['color1'], '0.2' );
741
+ $datasets[$k]['strokeColor'] = sprintf( $v['color1'], '1' );
742
+ $datasets[$k]['pointColor'] = sprintf( $v['color1'], '1' );
743
+ $datasets[$k]['pointStrokeColor'] = $v['color2'];
744
+ $datasets[$k]['pointHighlightFill'] = $v['color2'];
745
+ $datasets[$k]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
746
+ $datasets[$k]['label'] = $v['label'];
747
+ }
748
+
749
+ return array(
750
+ 'labels' => $labels,
751
+ 'datasets' => $datasets,
752
+ 'sql' => $query
753
+ );
754
+ }
755
+
756
+ /**
757
+ * Get data about courses to render in the chart
758
+ * @return array
759
+ */
760
+ function learn_press_get_chart_courses2() {
761
+ $labels = array( __( 'Pending Courses / Publish Courses', 'learnpress' ), __( 'Free Courses / Priced Courses', 'learnpress' ) );
762
+ $datasets = array();
763
+ $datasets[0]['data'] = array( learn_press_get_courses_by_status( 'pending' ), learn_press_get_courses_by_price( 'free' ) );
764
+ $datasets[1]['data'] = array( learn_press_get_courses_by_status( 'publish' ), learn_press_get_courses_by_price( 'not_free' ) );
765
+
766
+ $colors = learn_press_get_admin_colors();
767
+ $datasets[0]['fillColor'] = $colors[1];
768
+ $datasets[0]['strokeColor'] = $colors[1];
769
+ $datasets[1]['fillColor'] = $colors[3];
770
+ $datasets[1]['strokeColor'] = $colors[3];
771
+ return array(
772
+ 'labels' => $labels,
773
+ 'datasets' => $datasets
774
+ );
775
+ }
776
+
777
+ /**
778
+ * Get colors setting up by admin user
779
+ * @return array
780
+ */
781
+ function learn_press_get_admin_colors() {
782
+ $admin_color = get_user_meta( get_current_user_id(), 'admin_color', true );
783
+ global $_wp_admin_css_colors;
784
+ $colors = array();
785
+ if ( !empty( $_wp_admin_css_colors[$admin_color]->colors ) ) {
786
+ $colors = $_wp_admin_css_colors[$admin_color]->colors;
787
+ }
788
+ if ( empty ( $colors[0] ) ) {
789
+ $colors[0] = '#000000';
790
+ }
791
+ if ( empty ( $colors[2] ) ) {
792
+ $colors[2] = '#00FF00';
793
+ }
794
+ return $colors;
795
+ }
796
+
797
+ /**
798
+ * Convert an array to json format and print out to browser
799
+ *
800
+ * @param array $chart
801
+ */
802
+ function learn_press_process_chart( $chart = array() ) {
803
+ $data = json_encode(
804
+ array(
805
+ 'labels' => $chart['labels'],
806
+ 'datasets' => $chart['datasets']
807
+ )
808
+ );
809
+ echo $data;
810
+ }
811
+
812
+ /**
813
+ * Print out the configuration for admin chart
814
+ */
815
+ function learn_press_config_chart() {
816
+ $colors = learn_press_get_admin_colors();
817
+ $config = array(
818
+ 'scaleShowGridLines' => true,
819
+ 'scaleGridLineColor' => "#777",
820
+ 'scaleGridLineWidth' => 0.3,
821
+ 'scaleFontColor' => "#444",
822
+ 'scaleLineColor' => $colors[0],
823
+ 'bezierCurve' => true,
824
+ 'bezierCurveTension' => 0.2,
825
+ 'pointDotRadius' => 5,
826
+ 'pointDotStrokeWidth' => 5,
827
+ 'pointHitDetectionRadius' => 20,
828
+ 'datasetStroke' => true,
829
+ 'responsive' => true,
830
+ 'tooltipFillColor' => $colors[2],
831
+ 'tooltipFontColor' => "#eee",
832
+ 'tooltipCornerRadius' => 0,
833
+ 'tooltipYPadding' => 10,
834
+ 'tooltipXPadding' => 10,
835
+ 'barDatasetSpacing' => 10,
836
+ 'barValueSpacing' => 200
837
+
838
+ );
839
+ echo json_encode( $config );
840
+ }
841
+
842
+ function set_post_order_in_admin( $wp_query ) {
843
+ global $pagenow;
844
+ if ( isset( $_GET['post_type'] ) ) {
845
+ $post_type = $_GET['post_type'];
846
+ } else $post_type = '';
847
+ if ( is_admin() && 'edit.php' == $pagenow && $post_type == LP()->course_post_type && !isset( $_GET['orderby'] ) ) {
848
+ $wp_query->set( 'orderby', 'date' );
849
+ $wp_query->set( 'order', 'DSC' );
850
+ }
851
+ }
852
+
853
+ add_filter( 'pre_get_posts', 'set_post_order_in_admin' );
854
+ /**
855
+ * Add actions to the list of the course. e.g: Duplicate link
856
+ *
857
+ * @param $actions
858
+ *
859
+ * @return mixed
860
+ */
861
+ function learn_press_add_row_action_link( $actions ) {
862
+ global $post;
863
+ if ( LP()->course_post_type == $post->post_type ) {
864
+ $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 ) );
865
+ $duplicate_link = array(
866
+ array(
867
+ 'link' => $duplicate_link,
868
+ 'title' => __( 'Duplicate this course', 'learnpress' ),
869
+ 'class' => ''
870
+ )
871
+ );
872
+ $links = apply_filters( 'learn_press_row_action_links', $duplicate_link );
873
+ if ( count( $links ) > 1 ) {
874
+ $drop_down = array( '<ul class="lpr-row-action-dropdown">' );
875
+ foreach ( $links as $link ) {
876
+ $drop_down[] = '<li>' . sprintf( '<a href="%s" class="%s">%s</a>', $link['link'], $link['class'], $link['title'] ) . '</li>';
877
+ };
878
+ $drop_down[] = '</ul>';
879
+ $link = sprintf( '<div class="lpr-row-actions"><a href="%s">%s</a>%s</div>', 'javascript: void(0);', __( 'Course', 'learnpress' ), join( "\n", $drop_down ) );
880
+ } else {
881
+ $link = array_shift( $links );
882
+ $link = sprintf( '<a href="%s" class="%s">%s</a>', $link['link'], $link['class'], $link['title'] );
883
+ }
884
+ $actions['lpr-course-row-action'] = $link;
885
+ }
886
+ return $actions;
887
+ }
888
+
889
+ add_filter( 'page_row_actions', 'learn_press_add_row_action_link' );
890
+
891
+ function learn_press_copy_post_meta( $from_id, $to_id){
892
+ global $wpdb;
893
+ $course_meta = $wpdb->get_results(
894
+ $wpdb->prepare("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id = %d", $from_id )
895
+ );
896
+ if ( count( $course_meta ) != 0 ) {
897
+ $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
898
+ $sql_query_sel = array();
899
+
900
+ foreach ( $course_meta as $meta ) {
901
+ $meta_key = $meta->meta_key;
902
+ $meta_value = addslashes( $meta->meta_value );
903
+
904
+ $sql_query_sel[] = "SELECT {$to_id}, '$meta_key', '$meta_value'";
905
+ }
906
+
907
+ $sql_query .= implode( " UNION ALL ", $sql_query_sel );
908
+ $wpdb->query( $sql_query );
909
+ }
910
+ }
911
+ /**
912
+ * Duplicate a course when user hit "Duplicate" button
913
+ *
914
+ * @author TuNN
915
+ */
916
+ function learn_press_process_duplicate_action() {
917
+
918
+ $wp_list_table = _get_list_table( 'WP_Posts_List_Table' );
919
+ $action = $wp_list_table->current_action();
920
+
921
+ if ( isset( $_REQUEST['action'] ) && ( $action = $_REQUEST['action'] ) == 'lp-duplicate-course' ) {
922
+ $post_id = isset( $_REQUEST['post'] ) ? $_REQUEST['post'] : 0;
923
+ $nonce = !empty( $_REQUEST['nonce'] ) ? $_REQUEST['nonce'] : '';
924
+ if ( !wp_verify_nonce( $nonce, 'lp-duplicate-' . $post_id ) ) {
925
+ wp_die( __( 'Error', 'learnpress' ) );
926
+ }
927
+ if ( $post_id && is_array( $post_id ) ) {
928
+ $post_id = array_shift( $post_id );
929
+ }
930
+ // check for post is exists
931
+ if ( !( $post_id && $post = get_post( $post_id ) ) ) {
932
+ wp_die( __( 'Op! The course does not exists', 'learnpress' ) );
933
+ }
934
+ // ensure that user can create course
935
+ if ( !current_user_can( 'edit_posts' ) ) {
936
+ wp_die( __( 'Sorry! You have not permission to duplicate this course', 'learnpress' ) );
937
+ }
938
+
939
+ // assign course to current user
940
+ $current_user = wp_get_current_user();
941
+ $new_course_author = $current_user->ID;
942
+
943
+ // setup course data
944
+ $new_course_title = $post->post_title . ' - Copy';
945
+ $args = array(
946
+ 'comment_status' => $post->comment_status,
947
+ 'ping_status' => $post->ping_status,
948
+ 'post_author' => $new_course_author,
949
+ 'post_content' => $post->post_content,
950
+ 'post_excerpt' => $post->post_excerpt,
951
+ 'post_name' => $post->post_name,
952
+ 'post_parent' => $post->post_parent,
953
+ 'post_password' => $post->post_password,
954
+ 'post_status' => 'draft',
955
+ 'post_title' => $new_course_title,
956
+ 'post_type' => $post->post_type,
957
+ 'to_ping' => $post->to_ping,
958
+ 'menu_order' => $post->menu_order
959
+ );
960
+
961
+ // insert new course and get it ID
962
+ $new_post_id = wp_insert_post( $args );
963
+
964
+ if ( !$new_post_id ) {
965
+ LP_Admin_Notice::add_redirect( __( '<p>Sorry! Duplicate the course failed!</p>', 'learnpress' ) );
966
+ wp_redirect( admin_url( 'edit.php?post_type=lp_course' ) );
967
+ exit();
968
+ }
969
+ // assign related tags/categories to new course
970
+ $taxonomies = get_object_taxonomies( $post->post_type );
971
+ foreach ( $taxonomies as $taxonomy ) {
972
+ $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
973
+ wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false );
974
+ }
975
+
976
+ // duplicate course data
977
+ global $wpdb;
978
+ //learn_press_copy_post_meta( $post_id, $new_post_id );
979
+
980
+ $query = $wpdb->prepare( "
981
+ SELECT *
982
+ FROM {$wpdb->prefix}learnpress_sections s
983
+ INNER JOIN {$wpdb->posts} c ON c.ID = s.section_course_id
984
+ WHERE c.ID = %d
985
+ ", $post->ID );
986
+ if ( $sections = $wpdb->get_results( $query ) ) {
987
+ foreach ( $sections as $section ) {
988
+ $new_section_id = $wpdb->insert(
989
+ $wpdb->prefix . 'learnpress_sections',
990
+ array(
991
+ 'section_name' => $section->section_name,
992
+ 'section_course_id' => $new_post_id,
993
+ 'section_order' => $section->section_order,
994
+ 'section_description' => $section->section_description
995
+ ),
996
+ array( '%s', '%d', '%d', '%s' )
997
+ );
998
+ if ( $new_section_id ) {
999
+ $query = $wpdb->prepare( "
1000
+ SELECT i.*
1001
+ FROM {$wpdb->posts} i
1002
+ INNER JOIN {$wpdb->prefix}learnpress_sections s ON i.item_id = i.ID
1003
+ WHERE s.section_id = %d
1004
+ ", $section->section_id );
1005
+ if ( $items = $wpdb->get_results( $query ) ) {
1006
+ foreach ( $items as $item ) {
1007
+ $item_args = (array) $item;
1008
+ unset(
1009
+ $item_args['ID'],
1010
+ $item_args['post_author'],
1011
+ $item_args['post_date'],
1012
+ $item_args['post_date_gmt'],
1013
+ $item_args['post_modified'],
1014
+ $item_args['post_modified_gmt'],
1015
+ $item_args['comment_count']
1016
+ );
1017
+ $new_item_id = $wpdb->insert(
1018
+ $wpdb->posts,
1019
+ $item_args
1020
+ );
1021
+ }
1022
+ }
1023
+ }
1024
+ }
1025
+ }
1026
+ LP_Admin_Notice::add_redirect( __( '<p>Course duplicated.</p>', 'learnpress' ) );
1027
+ wp_redirect( admin_url( "post.php?post={$new_post_id}&action=edit" ) );
1028
+ die();
1029
+ }
1030
+ }
1031
+
1032
+ add_action( 'load-edit.php', 'learn_press_process_duplicate_action' );
1033
+
1034
+ function learn_press_admin_notice_bundle_activation() {
1035
+ if ( !empty( $_REQUEST['tab'] ) && ( 'bundle_activate' != $_REQUEST['tab'] ) && learn_press_get_notice_dismiss( 'bundle-addon-install', '' ) != 'off' ) {
1036
+ ?>
1037
+ <div class="updated">
1038
+ <p>
1039
+ <?php printf( __( 'Want full free features? Click <a href="%s">here</a> to install LearnPress Add-ons Bundle for free!', 'learnpress' ), admin_url( 'admin.php?page=learn_press_add_ons&tab=bundle_activate' ) ); ?>
1040
+ <?php printf( '<a href="" class="learn-press-admin-notice-dismiss" data-context="bundle-addon-install" data-transient="-1"></a>' ); ?>
1041
+ </p>
1042
+ </div>
1043
+ <?php
1044
+ }
1045
+ }
1046
+
1047
+ add_action( 'admin_notices', 'learn_press_admin_notice_bundle_activation' );
1048
+
1049
+ /**
1050
+ * Install a plugin
1051
+ *
1052
+ * @param string $plugin_name
1053
+ *
1054
+ * @return array
1055
+ */
1056
+ function learn_press_install_add_on( $plugin_name ) {
1057
+ require_once( LP_PLUGIN_PATH . '/inc/admin/class-lp-upgrader.php' );
1058
+ $upgrader = new LP_Upgrader();
1059
+ global $wp_filesystem;
1060
+ $response = array();
1061
+
1062
+ $package = 'http://thimpress.com/lprepo/' . $plugin_name . '.zip';
1063
+
1064
+ $package = $upgrader->download_package( $package );
1065
+ if ( is_wp_error( $package ) ) {
1066
+ $response['error'] = $package;
1067
+ } else {
1068
+ $working_dir = $upgrader->unpack_package( $package, true, $plugin_name );
1069
+ if ( is_wp_error( $working_dir ) ) {
1070
+ $response['error'] = $working_dir;
1071
+ } else {
1072
+
1073
+ $wp_upgrader = new WP_Upgrader();
1074
+ $options = array(
1075
+ 'source' => $working_dir,
1076
+ 'destination' => WP_PLUGIN_DIR,
1077
+ 'clear_destination' => false, // Do not overwrite files.
1078
+ 'clear_working' => true,
1079
+ 'hook_extra' => array(
1080
+ 'type' => 'plugin',
1081
+ 'action' => 'install'
1082
+ )
1083
+ );
1084
+ //$response = array();
1085
+ $result = $wp_upgrader->install_package( $options );
1086
+
1087
+ if ( is_wp_error( $result ) ) {
1088
+ $response['error'] = $result;
1089
+ } else {
1090
+ $response = $result;
1091
+ $response['text'] = __( 'Installed', 'learnpress' );
1092
+ }
1093
+ }
1094
+ }
1095
+ return $response;
1096
+ }
1097
+
1098
+ function learn_press_accept_become_a_teacher() {
1099
+ $action = !empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
1100
+ $user_id = !empty( $_REQUEST['user_id'] ) ? $_REQUEST['user_id'] : '';
1101
+ if ( !$action || !$user_id || ( $action != 'accept-to-be-teacher' ) ) return;
1102
+
1103
+ $be_teacher = new WP_User( $user_id );
1104
+ $be_teacher->set_role( LP()->teacher_role );
1105
+
1106
+ do_action( 'learn_press_user_become_a_teacher', $user_id );
1107
+ }
1108
+
1109
+ add_action( 'admin_notices', 'learn_press_accept_become_a_teacher' );
1110
+
1111
+ function learn_press_user_become_a_teacher_notice( $user_id ) {
1112
+ $user = new WP_User( $user_id );
1113
+ ?>
1114
+ <div class="updated">
1115
+ <p><?php printf( __( 'The user %s has become a teacher', 'learnpress' ), $user->user_login ); ?></p>
1116
+ </div>
1117
+ <?php
1118
+ }
1119
+
1120
+ add_action( 'learn_press_user_become_a_teacher', 'learn_press_user_become_a_teacher_notice' );
1121
+
1122
+ /**
1123
+ * Check to see if a plugin is already installed or not
1124
+ *
1125
+ * @param $plugin
1126
+ *
1127
+ * @return bool
1128
+ */
1129
+ function learn_press_is_plugin_install( $plugin ) {
1130
+ $installed_plugins = get_plugins();
1131
+ return isset( $installed_plugins[$plugin] );
1132
+ }
1133
+
1134
+ /**
1135
+ * Get plugin file that contains the information from slug
1136
+ *
1137
+ * @param $slug
1138
+ *
1139
+ * @return mixed
1140
+ */
1141
+ function learn_press_plugin_basename_from_slug( $slug ) {
1142
+ $keys = array_keys( get_plugins() );
1143
+ foreach ( $keys as $key ) {
1144
+ if ( preg_match( '|^' . $slug . '/|', $key ) ) {
1145
+ return $key;
1146
+ }
1147
+ }
1148
+ return $slug;
1149
+ }
1150
+
1151
+ function learn_press_one_click_install_sample_data_notice() {
1152
+ $courses = get_posts(
1153
+ array(
1154
+ 'post_type' => LP()->course_post_type,
1155
+ 'post_status' => 'any'
1156
+ )
1157
+ );
1158
+ if ( ( 0 == sizeof( $courses ) ) && ( 'off' != get_transient( 'learn_press_install_sample_data' ) ) ) {
1159
+ printf(
1160
+ '<div class="updated" id="learn-press-install-sample-data-notice">
1161
+ <div class="install-sample-data-notice">
1162
+ <p>%s</p>
1163
+ <p>%s <strong>%s</strong> %s
1164
+ <p><a href="" class="button yes" data-action="yes">%s</a> <a href="" class="button disabled no" data-action="no">%s</a></p>
1165
+ </div>
1166
+ <div class="install-sample-data-loading">
1167
+ <p>Importing...</p>
1168
+ </div>
1169
+ </div>',
1170
+ __( 'You haven\'t got any courses yet! Would you like to import sample data?', 'learnpress' ),
1171
+ __( 'If yes, it requires to install addon named', 'learnpress' ),
1172
+ __( 'LearnPress Import/Export', 'learnpress' ),
1173
+ __( 'but don\'t worry because it is completely automated.', 'learnpress' ),
1174
+ __( 'Import now', 'learnpress' ),
1175
+ __( 'No, thanks!', 'learnpress' )
1176
+ );
1177
+ }
1178
+ }
1179
+
1180
+ //add_action( 'admin_notices', 'learn_press_one_click_install_sample_data_notice' );
1181
+
1182
+ function learn_press_request_query( $vars = array() ) {
1183
+ global $typenow, $wp_query, $wp_post_statuses;
1184
+ if ( LP()->order_post_type === $typenow ) {
1185
+ // Status
1186
+ if ( !isset( $vars['post_status'] ) ) {
1187
+ $post_statuses = learn_press_get_order_statuses();
1188
+
1189
+ foreach ( $post_statuses as $status => $value ) {
1190
+ if ( isset( $wp_post_statuses[$status] ) && false === $wp_post_statuses[$status]->show_in_admin_all_list ) {
1191
+ unset( $post_statuses[$status] );
1192
+ }
1193
+ }
1194
+
1195
+ $vars['post_status'] = array_keys( $post_statuses );
1196
+
1197
+ }
1198
+ }
1199
+ return $vars;
1200
+ }
1201
+
1202
+ add_filter( 'request', 'learn_press_request_query' );
1203
+
1204
+ function _learn_press_reset_course_data() {
1205
+ if ( empty( $_REQUEST['reset-course-data'] ) ) {
1206
+ return false;
1207
+ }
1208
+ learn_press_reset_course_data( intval( $_REQUEST['reset-course-data'] ) );
1209
+ wp_redirect( remove_query_arg( 'reset-course-data' ) );
1210
+ }
1211
+
1212
+ add_action( 'init', '_learn_press_reset_course_data' );
1213
+
1214
+ /***********************/
1215
+ function learn_press_admin_section_loop_item_class( $item, $section ) {
1216
+ $classes = array(
1217
+ 'lp-section-item'
1218
+ );
1219
+ $classes[] = 'lp-item-' . $item->post_type;
1220
+ if ( !absint( $item->ID ) ) {
1221
+ $classes[] = 'lp-item-empty lp-item-new';
1222
+ }
1223
+ $classes = apply_filters( 'learn_press_section_loop_item_class', $classes, $item, $section );
1224
+ if ( $classes ) echo 'class="' . join( ' ', $classes ) . '"';
1225
+ return $classes;
1226
+ }
1227
+
1228
+ function learn_press_disable_checked_ontop( $args ) {
1229
+
1230
+ if ( 'course_category' == $args['taxonomy'] ) {
1231
+ $args['checked_ontop'] = false;
1232
+ }
1233
+
1234
+ return $args;
1235
+ }
1236
+
1237
+ add_filter( 'wp_terms_checklist_args', 'learn_press_disable_checked_ontop' );
1238
+
1239
+ function learn_press_output_admin_template() {
1240
+ learn_press_admin_view( 'admin-template.php' );
1241
+ }
1242
+
1243
+ add_action( 'admin_print_scripts', 'learn_press_output_admin_template' );
1244
+
1245
+ function learn_press_output_screen_id() {
1246
+ $screen = get_current_screen();
1247
+ if ( $screen ) {
1248
+ echo "<div style=\"position:fixed;top: 0; left:0; z-index: 99999999; background-color:#FFF;padding:4px;\">" . $screen->id . "</div>";
1249
+ }
1250
+ }
1251
+
1252
+ //add_action( 'admin_head', 'learn_press_output_screen_id' );
1253
+
1254
+ function learn_press_get_screens() {
1255
+ $screen_id = sanitize_title( __( 'LearnPress', 'learnpress' ) );
1256
+ $screens = array(
1257
+ 'toplevel_page_' . $screen_id,
1258
+ $screen_id . '_page_learn_press_statistics',
1259
+ $screen_id . '_page_learn_press_add_ons'
1260
+ );
1261
+ foreach ( array( 'lp_course', 'lp_lesson', 'lp_quiz', 'lp_lesson', 'lp_order' ) as $post_type ) {
1262
+ $screens[] = 'edit-' . $post_type;
1263
+ $screens[] = $post_type;
1264
+ }
1265
+
1266
+ return apply_filters( 'learn_press_screen_ids', $screens );
1267
+ }
1268
+
1269
+ function learn_press_get_admin_pages() {
1270
+ return apply_filters(
1271
+ 'learn_press_admin_pages',
1272
+ array(
1273
+ 'learn_press_settings'
1274
+ )
1275
+ );
1276
+ }
1277
+
1278
+ function learn_press_get_notice_dismiss( $context, $type = 'transient' ) {
1279
+ if ( $type == 'transient' ) {
1280
+ return get_transient( 'learn_press_dismiss_notice_' . $context );
1281
+ }
1282
+ return get_option( 'learn_press_dismiss_notice_' . $context );
1283
+ }
inc/admin/meta-boxes/class-course-tabs-field.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Prevent loading this file directly
3
+ defined( 'ABSPATH' ) || exit;
4
+
5
+ if ( !class_exists( 'RWMB_Course_Tabs_Field' ) ) {
6
+ /**
7
+ * Thim Theme
8
+ *
9
+ * Manage Course, Lesson, Quiz
10
+ *
11
+ * @class RWMB_Course_lesson_Quiz_Field
12
+ */
13
+ class RWMB_Course_Tabs_Field extends RWMB_Field {
14
+ static function html(){
15
+ ob_start();
16
+ learn_press_admin_view( 'meta-boxes/course/tabs.php' );
17
+ return ob_get_clean();
18
+ }
19
+ }
20
+ }
inc/admin/meta-boxes/class-curriculum-field.php ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ static function admin_enqueue_scripts() {
20
+ LP_Admin_Assets::enqueue_style( 'meta-box-course', LP()->plugin_url( 'assets/css/admin/meta-box-course.css' ) );
21
+ LP_Admin_Assets::enqueue_style( 'select2', RWMB_CSS_URL . 'select2/select2.css' );
22
+ // LP_Admin_Assets::enqueue_style( 'toastr', LP_CSS_URL . 'toastr.css' );
23
+ //LP_Admin_Assets::enqueue_style( 'thim-course', LearnPress()->plugin_url( 'inc/admin/meta-boxes/css/course.css' ) );
24
+
25
+ LP_Admin_Assets::enqueue_script( 'select2', RWMB_JS_URL . 'select2/select2.min.js' );
26
+ //LP_Admin_Assets::enqueue_script( 'toastr', LP_JS_URL . 'toastr.js' );
27
+ //LP_Admin_Assets::enqueue_script( 'tojson', LP_JS_URL . 'toJSON.js' );
28
+ LP_Admin_Assets::enqueue_script( 'modal-search-items' );
29
+ LP_Admin_Assets::enqueue_script( 'meta-box-course', learn_press_plugin_url( 'assets/js/admin/meta-box-course.js' ), array( 'jquery' ) );
30
+
31
+
32
+ LP_Admin_Assets::add_localize(
33
+ array(
34
+ 'confirm_remove_section_lesson' => __( 'Do you want to remove this lesson permanently?', 'learnpress' ),
35
+ 'confirm_remove_section_quiz' => __( 'Do you want to remove this quiz permanently?', 'learnpress' ),
36
+ 'confirm_remove_section' => __( 'Do you want to remove this section permanently?', 'learnpress' ),
37
+ 'add_new_quiz' => __( 'New quiz added', 'learnpress' ),
38
+ 'add_new_lesson' => __( 'New lesson added', 'learnpress' ),
39
+ 'add_new_section' => __( 'New section added', 'learnpress' ),
40
+ 'remove_section_lesson' => __( 'The lesson removed', 'learnpress' ),
41
+ 'remove_section_quiz' => __( 'The quiz removed', 'learnpress' ),
42
+ 'remove_section' => __( 'The section removed', 'learnpress' ),
43
+ 'section_ordered' => __( 'The ordering completed', 'learnpress' ),
44
+ 'add_lesson_to_section' => __( 'Lesson added to section complete!', 'learnpress' ),
45
+ 'add_quiz_to_section' => __( 'Quiz added to section complete!', 'learnpress' ),
46
+ 'update_lesson_quiz' => __( '%s updated', 'learnpress' ),
47
+ 'quick_edit_name' => __( 'Click to quick edit name', 'learnpress' ),
48
+ 'save_course' => __( 'Save Course', 'learnpress' ),
49
+ 'submit_course_review' => __( 'Submit for Review', 'learnpress' )
50
+ ), null, 'meta-box-course'
51
+ );
52
+ }
53
+
54
+
55
+ /**
56
+ * Get field HTML
57
+ *
58
+ * @param mixed $meta
59
+ * @param array $field
60
+ *
61
+ * @return string
62
+ */
63
+ static function html( $meta, $field ) {
64
+ global $post;
65
+ $course = LP_Course::get_course( $post );
66
+ $view = learn_press_get_admin_view( 'meta-boxes/course/curriculum.php' );
67
+ ob_start();
68
+ include $view;
69
+ return ob_get_clean();
70
+ }
71
+
72
+ /**
73
+ * Normalize parameters for field
74
+ *
75
+ * @param array $field
76
+ *
77
+ * @return array
78
+ */
79
+ static function normalize_field( $field ) {
80
+ $field = wp_parse_args( $field, array(
81
+ 'size' => 30,
82
+ 'datalist' => false,
83
+ 'placeholder' => '',
84
+ ) );
85
+
86
+ return $field;
87
+ }
88
+
89
+ /**
90
+ * Create datalist, if any
91
+ *
92
+ * @param array $field
93
+ *
94
+ * @return array
95
+ */
96
+ static function datalist_html( $field ) {
97
+ if ( !$field['datalist'] ) {
98
+ return '';
99
+ }
100
+
101
+ $datalist = $field['datalist'];
102
+ $html = sprintf(
103
+ '<datalist id="%s">',
104
+ $datalist['id']
105
+ );
106
+
107
+ foreach ( $datalist['options'] as $option ) {
108
+ $html .= sprintf( '<option value="%s"></option>', $option );
109
+ }
110
+
111
+ $html .= '</datalist>';
112
+
113
+ return $html;
114
+ }
115
+
116
+ /**
117
+ * Save meta value
118
+ * If field is cloneable, value is saved as a single entry in DB
119
+ * Otherwise value is saved as multiple entries (for backward compatibility)
120
+ *
121
+ * TODO: A good way to ALWAYS save values in single entry in DB, while maintaining backward compatibility
122
+ *
123
+ * @param $new
124
+ * @param $old
125
+ * @param $post_id
126
+ * @param $field
127
+ */
128
+ static function save( $new, $old, $post_id, $field ) {
129
+
130
+ if ( empty( $new ) ) {
131
+ delete_post_meta( $post_id, $field['id'] );
132
+ } else {
133
+ $new = array_values( $new );
134
+ for ( $n = count( $new ), $i = $n - 1; $i >= 0; $i -- ) {
135
+ if ( !$new[$i]['name'] ) unset( $new[$i] );
136
+ }
137
+ $new = array_values( $new );
138
+ update_post_meta( $post_id, $field['id'], $new );
139
+ }
140
+ }
141
+
142
+ static function add_actions() {
143
+ // Do same actions as file field
144
+ parent::add_actions();
145
+
146
+ add_action( 'wp_ajax_lpr_quick_add', array( __CLASS__, 'quick_add' ) );
147
+ add_action( 'wp_ajax_lpr_update_course_curriculum', array( __CLASS__, 'update_course_curriculum' ) );
148
+ add_action( 'wp_ajax_lpr_quick_edit_lesson_quiz_name', array( __CLASS__, 'quick_edit_lesson_quiz_name' ) );
149
+ add_action( 'wp_ajax_lpr_update_section_state', array( __CLASS__, 'update_section_state' ) );
150
+ add_action( 'wp_ajax_lpr_remove_lesson_quiz', array( __CLASS__, 'remove_lesson_quiz' ) );
151
+
152
+ add_action( 'save_post', array( __CLASS__, 'update_course_curriculum' ) );
153
+ add_filter( 'learn_press_loop_section_buttons', array( __CLASS__, 'add_section_buttons' ) );
154
+ //add_filter( 'learn_press_after_section_content', array( __CLASS__, 'section_options' ) );
155
+ }
156
+
157
+ static function add_section_buttons( $buttons ) {
158
+ $buttons = array_merge(
159
+ $buttons,
160
+ array(
161
+ array(
162
+ 'id' => 'add-lesson',
163
+ 'text' => __( 'Add Lesson', 'learnpress' ),
164
+ 'attr' => 'data-action="add-lesson" data-type="lp_lesson"'
165
+ ),
166
+ array(
167
+ 'id' => 'add-quiz',
168
+ 'text' => __( 'Add Quiz', 'learnpress' ),
169
+ 'attr' => 'data-action="add-quiz" data-type="lp_quiz"'
170
+ )/*,
171
+ array(
172
+ 'id' => 'toggle-section-options',
173
+ 'text' => __( 'Options', 'learnpress' ),
174
+ 'attr' => 'data-action=""'
175
+ )*/
176
+ )
177
+ );
178
+ return $buttons;
179
+ }
180
+
181
+ static function section_options() {
182
+ ?>
183
+ <table class="form-table">
184
+ <tr>
185
+ <th>
186
+ <?php _e( 'Using final quiz', 'learnpress' ); ?>
187
+ </th>
188
+ <td>
189
+ <input type="checkbox" />
190
+
191
+ <p class="description"><?php _e( 'User must be completed the final quiz to finish a section', 'learnpress' ); ?></p>
192
+
193
+ </td>
194
+ </tr>
195
+ </table>
196
+ <?php
197
+ }
198
+
199
+ static function remove_lesson_quiz() {
200
+ $lesson_quiz_id = $_POST['lesson_quiz_id'];
201
+ delete_post_meta( $lesson_quiz_id, '_lpr_course' );
202
+ update_post_meta( $lesson_quiz_id, '_lpr_course', 0 );
203
+
204
+ }
205
+
206
+ static function update_section_state() {
207
+ $post_id = $_POST['post_id'];
208
+ $section = $_POST['section'];
209
+ update_post_meta( $post_id, '_lpr_course_section_state', $section );
210
+ die();
211
+ }
212
+
213
+ static function quick_add() {
214
+ //ob_end_flush();
215
+ echo '__LP_JSON__';
216
+ $name = isset( $_POST['name'] ) ? $_POST['name'] : null;
217
+ $type = isset( $_POST['type'] ) ? $_POST['type'] : null;
218
+ $course_id = isset( $_POST['course_id'] ) ? $_POST['course_id'] : null;
219
+ $post = false;
220
+ if ( $name && $type ) {
221
+ $post_id = wp_insert_post(
222
+ array(
223
+ 'post_title' => $name,
224
+ 'post_type' => $type == 'lesson' ? LP_LESSON_CPT : LP_QUIZ_CPT,
225
+ 'post_status' => 'publish'
226
+ )
227
+ );
228
+ if ( $post_id ) {
229
+ $post = get_post( $post_id );
230
+ if ( $course_id ) {
231
+ update_post_meta( $post_id, '_lpr_course', $course_id );
232
+ }
233
+ }
234
+ }
235
+ wp_send_json( $post );
236
+ die();
237
+ }
238
+
239
+ static function quick_edit_lesson_quiz_name() {
240
+ $id = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : 0;
241
+ echo '__LP_JSON__';
242
+ if ( $id ) {
243
+ $name = $_POST['name'];
244
+ $slug = sanitize_title( $name );
245
+ $post_id = wp_update_post(
246
+ array(
247
+ 'ID' => $id,
248
+ 'post_title' => $name,
249
+ 'post_name' => $slug
250
+ )
251
+ );
252
+ if ( $post_id ) {
253
+ wp_send_json( get_post( $post_id ) );
254
+ }
255
+ }
256
+
257
+ }
258
+
259
+ static function update_course_curriculum() {
260
+
261
+ $is_ajax = false;
262
+ if ( !empty( $_REQUEST['action'] ) && 'lpr_update_course_curriculum' == $_REQUEST['action'] ) {
263
+ $course_id = isset( $_POST['course_id'] ) ? intval( $_POST['course_id'] ) : 0;
264
+ $is_ajax = true;
265
+ } else {
266
+ if ( LP()->course_post_type != get_post_type() ) return;
267
+ global $post;
268
+ $course_id = $post->ID;
269
+ }
270
+ $meta_key = isset( $_POST['meta_key'] ) ? $_POST['meta_key'] : '_lpr_course_lesson_quiz';
271
+ $metadata = isset( $_POST['_lpr_course_lesson_quiz'] ) ? $_POST['_lpr_course_lesson_quiz'] : false;
272
+ if ( !$course_id ) {
273
+ echo '__LP_JSON__';
274
+ wp_send_json(
275
+ array(
276
+ 'message' => __( 'The course is empty', 'learnpress' )
277
+ )
278
+ );
279
+ }
280
+
281
+ $metadata = apply_filters( 'learn_press_course_curriculum', $metadata, $course_id );
282
+ update_post_meta( $course_id, $meta_key, $metadata );
283
+ do_action( 'learn_press_update_course_curriculum', $course_id, $metadata );
284
+
285
+ //
286
+ global $wpdb;
287
+ if ( $metadata ) foreach ( $metadata as $section ) {
288
+ if ( !empty( $section['lesson_quiz'] ) && $lesson_quiz = $section['lesson_quiz'] ) {
289
+ $query = $wpdb->prepare( "
290
+ DELETE FROM {$wpdb->postmeta}
291
+ WHERE meta_key = %s
292
+ AND ( meta_value = %d OR meta_value = %d OR meta_value = %s )
293
+ AND post_id IN(" . join( ',', $lesson_quiz ) . ")
294
+ ", '_lpr_course', $course_id, 0, '' );
295
+
296
+ $wpdb->query( $query );
297
+
298
+ $query = "INSERT INTO {$wpdb->postmeta}(`post_id`, `meta_key`, `meta_value`) VALUES";
299
+ $query_values = array();
300
+ foreach ( $lesson_quiz as $id ) {
301
+ $query_values[] = $wpdb->prepare( "(%d, %s, %d)", $id, '_lpr_course', $course_id );
302
+ }
303
+ $query .= join( ",", $query_values );
304
+ $wpdb->query( $query );
305
+ }
306
+ }
307
+ if ( !$is_ajax ) return;
308
+ wp_send_json(
309
+ array(
310
+ 'message' => __( 'Success', 'learnpress' )
311
+ )
312
+ );
313
+ }
314
+
315
+ static function meta( $post_id, $saved, $field ) {
316
+ $meta = get_post_meta( $post_id, $field['id'], true );
317
+
318
+ // Use $field['std'] only when the meta box hasn't been saved (i.e. the first time we run)
319
+ $meta = ( !$saved && '' === $meta || array() === $meta ) ? $field['std'] : $meta;
320
+
321
+ // Escape attributes for non-wysiwyg fields
322
+ if ( 'wysiwyg' !== $field['type'] ) {
323
+ //$meta = is_array( $meta ) ? array_map( 'esc_attr', $meta ) : esc_attr( $meta );
324
+ }
325
+
326
+ return $meta;
327
+ }
328
+
329
+ static function cleanHeader() {
330
+
331
+ }
332
+ }
333
+ }
inc/admin/meta-boxes/class-question-field.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Prevent loading this file directly
4
+ defined( 'ABSPATH' ) || exit;
5
+ /**
6
+ * @author ThimPress
7
+ * @package LearnPress/Classes
8
+ * @version 1.0
9
+ */
10
+ if ( !class_exists( 'RWMB_Question_Field' ) ) {
11
+ class RWMB_Question_Field extends RWMB_Field {
12
+ static function add_actions() {
13
+ // Do same actions as file field
14
+ parent::add_actions();
15
+ add_action( 'wp_ajax_lpr_load_question_settings', array( __CLASS__, 'load_question_settings' ) );
16
+ }
17
+
18
+ static function load_question_settings() {
19
+ $type = isset( $_REQUEST['type'] ) ? $_REQUEST['type'] : null;
20
+ $question_id = isset( $_REQUEST['question_id'] ) ? $_REQUEST['question_id'] : null;
21
+
22
+ $options = array(
23
+ 'ID' => $question_id
24
+ );
25
+
26
+ $question = LP_Question::instance( $type, $options );
27
+ $options = $question->get( 'options' );
28
+ if ( isset( $options['type'] ) && $options['type'] == $type ) {
29
+
30
+ } else {
31
+ unset( $options['answer'] );
32
+ $question->set( 'options', $options );
33
+ }
34
+
35
+ $post_options = !empty( $_REQUEST['options'] ) ? $_REQUEST['options'] : null;
36
+ if ( $type == 'single_choice' ) {
37
+ $selected = - 1;
38
+ if ( $post_options && $post_options['answer'] ) foreach ( $post_options['answer'] as $k => $option ) {
39
+ if ( !empty( $option['is_true'] ) ) $selected = $k;
40
+ $post_options['answer'][$k]['is_true'] = 0;
41
+ }
42
+ if ( $selected > - 1 ) {
43
+ $post_options['answer'][$selected]['is_true'] = 1;
44
+ }
45
+ }
46
+ if ( $post_options ) $question->set( 'options', $post_options );
47
+
48
+ $question->admin_interface();
49
+ die();
50
+ }
51
+
52
+ static function save( $new, $old, $post_id, $field ) {
53
+ }
54
+
55
+ static function html( $meta, $field ) {
56
+ global $post;
57
+ $post_id = $post->ID;
58
+ /*$question = get_post_meta( $post_id, '_lpr_question', true );
59
+ $question = wp_parse_args(
60
+ $question,
61
+ array(
62
+ 'type' => null
63
+ )
64
+ );*/
65
+ ob_start();
66
+
67
+ if ( $q = LP_Question_Factory::get_question( $post_id ) ) {
68
+ $q->admin_interface();
69
+ }
70
+ return ob_get_clean();
71
+ }
72
+ }
73
+ }
inc/admin/meta-boxes/class-quiz-questions-field.php ADDED
@@ -0,0 +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
+ function __construct() {
20
+
21
+ }
22
+
23
+ static function admin_enqueue_scripts() {
24
+ /*$q = new LP_Question();
25
+ $q->admin_script();*/
26
+ LP_Admin_Assets::enqueue_style( 'select2', RWMB_CSS_URL . 'select2/select2.css' );
27
+ LP_Admin_Assets::enqueue_script( 'select2', RWMB_JS_URL . 'select2/select2.min.js' );
28
+ LP_Admin_Assets::enqueue_script( 'lpr-quiz-question', learn_press_plugin_url( 'assets/js/admin/meta-box-quiz.js' ) );
29
+ wp_enqueue_script( 'modal-search-items' );
30
+
31
+ }
32
+
33
+ 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
+ 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
+ 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_post_type );
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
+ static function save_quiz_questions( $post_id ) {
87
+ learn_press_debug($_POST);
88
+ die();
89
+ static $has_updated;
90
+ $questions = isset( $_POST[LP()->question_post_type] ) ? $_POST[LP()->question_post_type] : 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
+ 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
+ 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/pointers/pointers.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ /**
5
+ * Load pointer
6
+ */
7
+ function learn_press_pointer_load() {
8
+
9
+ // Don't run on WP < 3.3
10
+ if ( get_bloginfo( 'version' ) < '3.3' )
11
+ return;
12
+
13
+ $screen = get_current_screen();
14
+ $screen_id = $screen->id;
15
+
16
+ // Get pointers for this screen
17
+ $pointers = apply_filters( 'learn_press_admin_pointers-' . $screen_id, array() );
18
+
19
+ if ( !$pointers || !is_array( $pointers ) )
20
+ return;
21
+
22
+ // Get dismissed pointers
23
+ $dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
24
+ $valid_pointers = array();
25
+
26
+ // Check pointers and remove dismissed ones.
27
+ foreach ( $pointers as $pointer_id => $pointer ) {
28
+
29
+ // Sanity check
30
+ if ( in_array( $pointer_id, $dismissed ) || empty( $pointer ) || empty( $pointer_id ) || empty( $pointer['target'] ) || empty( $pointer['options'] ) )
31
+ continue;
32
+
33
+ $pointer['pointer_id'] = $pointer_id;
34
+
35
+ // Add the pointer to $valid_pointers array
36
+ $valid_pointers['pointers'][] = $pointer;
37
+ }
38
+
39
+ // No valid pointers? Stop here.
40
+ if ( empty( $valid_pointers ) )
41
+ return;
42
+
43
+ // Add pointers style to queue.
44
+ wp_enqueue_style( 'wp-pointer' );
45
+
46
+ // Add pointers script to queue. Add custom script.
47
+ //wp_enqueue_script( 'learn_press-pointer', LP_JS_URL . 'pointer.js', array( 'wp-pointer' ) );
48
+
49
+ // Add pointer options to script.
50
+ wp_localize_script( 'learn-press-admin', 'lpPointer', $valid_pointers );
51
+ }
52
+ add_action( 'admin_enqueue_scripts', 'learn_press_pointer_load', 1000 );
53
+
54
+ /**
55
+ * Register pointer
56
+ *
57
+ * @param $pointer
58
+ *
59
+ * @return mixed
60
+ */
61
+ function learn_press_register_pointer_in_edit_course( $pointer ) {
62
+ $pointer['lp_course_guide'] = array(
63
+ 'target' => '#course_curriculum',
64
+ 'options' => array(
65
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p>',
66
+ __( 'Course Curriculum', 'learnpress' ),
67
+ __( 'Build a course by selecting created lessons and quizzes or adding new ones. Sorting, editing, shortcuts (l and q), it never gets easier with LearnPress.', 'learnpress' )
68
+ ),
69
+ 'position' => array( 'edge' => 'top', 'align' => 'middle' )
70
+ )
71
+ );
72
+ return $pointer;
73
+ }
74
+ add_filter( 'learn_press_admin_pointers-lpr_course', 'learn_press_register_pointer_in_edit_course' );
inc/admin/settings/class-lp-settings-base.php ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Settings_Base
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_Settings_Base {
16
+
17
+ /**
18
+ * Tab's ID
19
+ *
20
+ * @var string
21
+ */
22
+ public $id = '';
23
+
24
+ /**
25
+ * Tab's text
26
+ *
27
+ * @var string
28
+ */
29
+ public $text = '';
30
+
31
+ /**
32
+ * Tab's sections
33
+ *
34
+ * @var array|bool
35
+ */
36
+ public $section = false;
37
+
38
+ /**
39
+ * @var array|bool
40
+ */
41
+ public $tab = false;
42
+
43
+ /**
44
+ * Current tab
45
+ *
46
+ * @var string
47
+ */
48
+ static $current_tab = '';
49
+
50
+ /**
51
+ * Constructor
52
+ */
53
+ function __construct() {
54
+ if( strtolower( current_filter() ) == 'activate_learnpress/learnpress.php' ){
55
+ return;
56
+ }
57
+ $current_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : '';
58
+ $tabs = learn_press_settings_tabs_array();
59
+ if ( !$current_tab && $tabs ) {
60
+ $tab_keys = array_keys( $tabs );
61
+ $current_tab = reset( $tab_keys );
62
+ $this->tab = array(
63
+ 'id' => $current_tab,
64
+ 'text' => $tabs[$current_tab]
65
+ );
66
+ } else {
67
+ $this->tab = array( 'id' => null, 'text' => null );
68
+ }
69
+
70
+ $current_section = !empty( $_REQUEST['section'] ) ? $_REQUEST['section'] : '';
71
+ $sections = $this->get_sections();
72
+
73
+ /**
74
+ * Find current section by detect request
75
+ */
76
+ if ( $sections ) {
77
+ $array_keys = array_keys( $sections );
78
+ if ( !$current_section ) $current_section = reset( $array_keys );
79
+ if ( !empty( $sections[$current_section] ) ) {
80
+ $this->section = $sections[$current_section];
81
+ } else {
82
+ $this->section = array( 'id' => null, 'title' => '' );
83
+ }
84
+
85
+ } else {
86
+ $this->section = array( 'id' => null, 'title' => '' );
87
+ }
88
+
89
+ if ( $sections = $this->get_sections() ) foreach ( $sections as $id => $text ) {
90
+ $callback = apply_filters( 'learn_press_section_callback_' . $this->id . '_' . $id, array( $this, 'output_section_' . $id ) );
91
+ if ( is_callable( $callback ) ) {
92
+ add_action( 'learn_press_section_' . $this->id . '_' . $id, $callback );
93
+ }
94
+ }
95
+
96
+ // hooks
97
+ add_action( 'learn_press_sections_' . $this->id, array( $this, 'output_sections' ) );
98
+ add_action( 'learn_press_settings_' . $this->id, array( $this, 'output' ) );
99
+ add_action( 'learn_press_settings_save_' . $this->id, array( $this, 'save' ) );
100
+ }
101
+
102
+ /**
103
+ * Output tab's sections if defined
104
+ */
105
+ function output_sections() {
106
+ $current_section = $this->section['id'];
107
+ $sections = $this->get_sections();
108
+
109
+ if ( $sections && sizeof( $sections ) > 1 ) {
110
+ $array_keys = array_keys( $sections );
111
+ echo '<ul class="subsubsub clearfix">';
112
+ foreach ( $sections as $name => $section ) {
113
+ ?>
114
+ <li>
115
+ <a href="<?php echo '?page=learn_press_settings&tab=' . $this->id . '&section=' . sanitize_title( $name ); ?>" class="<?php echo $current_section == $name ? 'current' : ''; ?>">
116
+ <?php echo $section['title']; ?>
117
+ </a>
118
+ <?php echo( end( $array_keys ) == $name ? '' : '|' ); ?>
119
+ </li>
120
+ <?php
121
+ }
122
+ echo '</ul>';
123
+ echo '<div class="clear"></div>';
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Output settings tab content
129
+ */
130
+ function output() {
131
+ do_action( 'learn_press_section_' . $this->id . '_' . $this->section['id'] );
132
+ }
133
+
134
+ /**
135
+ * Save settings for current tab
136
+ */
137
+ function save() {
138
+ foreach ( $_POST as $k => $v ) {
139
+ if ( ( strpos( $k, 'learn_press_' ) === false ) || ( !apply_filters( 'learn_press_abort_update_option', true, $k ) ) ) continue;
140
+ update_option( $k, apply_filters( 'learn_press_update_option_value', $v, $k ) );
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Get tab's sections if defined
146
+ *
147
+ * @return bool
148
+ */
149
+ function get_sections() {
150
+ return false;
151
+ }
152
+
153
+ /**
154
+ * Get name for field
155
+ *
156
+ * @param $name
157
+ *
158
+ * @return mixed
159
+ */
160
+ function get_field_name( $name ) {
161
+ $field_name = apply_filters( 'learn_press_settings_field_name_' . $name, "learn_press_{$name}" );
162
+ return $field_name;
163
+ }
164
+
165
+ /**
166
+ * Get ID for field
167
+ *
168
+ * @param $name
169
+ *
170
+ * @return mixed
171
+ */
172
+ function get_field_id( $name ) {
173
+ return preg_replace( array( '!\[|(\]\[)!', '!\]!' ), array( '_', '' ), $this->get_field_name( $name ) );
174
+ }
175
+
176
+ function get_settings(){
177
+ return array();
178
+ }
179
+
180
+ /**
181
+ * admin settings page
182
+ */
183
+ function output_settings() {
184
+
185
+ $settings = new LP_Settings_Base();
186
+ if( $fields = $this->get_settings() ) foreach ( $fields as $field ) {
187
+ $settings->output_field( $field );
188
+ }
189
+ }
190
+
191
+ function output_field( $options ){
192
+ if ( ! isset( $options['type'] ) ) {
193
+ return;
194
+ }
195
+ if ( !isset( $options['id'] ) ) {
196
+ $options['id'] = '';
197
+ }
198
+ if ( !isset( $options['title'] ) ) {
199
+ $options['title'] = isset( $options['name'] ) ? $options['name'] : '';
200
+ }
201
+ if ( !isset( $options['class'] ) ) {
202
+ $options['class'] = '';
203
+ }
204
+ if ( !isset( $options['css'] ) ) {
205
+ $options['css'] = '';
206
+ }
207
+ if ( !isset( $options['default'] ) ) {
208
+ $options['default'] = '';
209
+ }
210
+ if ( !isset( $options['desc'] ) ) {
211
+ $options['desc'] = '';
212
+ }
213
+ if ( !isset( $options['desc_tip'] ) ) {
214
+ $options['desc_tip'] = false;
215
+ }
216
+ if ( !isset( $options['placeholder'] ) ) {
217
+ $options['placeholder'] = '';
218
+ }
219
+
220
+ $custom_attributes = array();
221
+
222
+ if ( !empty( $options['custom_attributes'] ) && is_array( $options['custom_attributes'] ) ) {
223
+ foreach ( $options['custom_attributes'] as $attribute => $attribute_value ) {
224
+ $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
225
+ }
226
+ }
227
+
228
+ if( !empty( $options['desc'] ) ){
229
+ $description = sprintf( '<p class="description">%s</p>', $options['desc'] );
230
+ }else{
231
+ $description = '';
232
+ }
233
+ $file = $options['type'];
234
+ if( in_array( $file, array( 'text', 'email', 'color', 'password', 'number' ) ) ){
235
+ $file = 'text';
236
+ }
237
+ require learn_press_get_admin_view( 'settings/fields/' . $file . '.php' );
238
+ }
239
+
240
+ function get_option( $option_name, $default = null ){
241
+ if ( strstr( $option_name, '[' ) ) {
242
+ parse_str( $option_name, $option_array );
243
+
244
+ // Option name is first key
245
+ $option_name = current( array_keys( $option_array ) );
246
+
247
+ // Get value
248
+ $option_values = get_option( $option_name, '' );
249
+
250
+ $key = key( $option_array[ $option_name ] );
251
+
252
+ if ( isset( $option_values[ $key ] ) ) {
253
+ $option_value = $option_values[ $key ];
254
+ } else {
255
+ $option_value = null;
256
+ }
257
+
258
+ // Single value
259
+ } else {
260
+ $option_value = LP()->settings->get( preg_replace( '!^learn_press_!', '', $option_name ), null );
261
+ }
262
+
263
+ if ( is_array( $option_value ) ) {
264
+ $option_value = array_map( 'stripslashes', $option_value );
265
+ } elseif ( ! is_null( $option_value ) ) {
266
+ $option_value = stripslashes( $option_value );
267
+ }
268
+
269
+ return $option_value === null ? $default : $option_value;
270
+ }
271
+ }
272
+ return new LP_Settings_Base();
inc/admin/settings/class-lp-settings-checkout.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ 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
+ 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
+ function output_section_general() {
43
+ $view = learn_press_get_admin_view( 'settings/checkout.php' );
44
+ include_once $view;
45
+ }
46
+
47
+ function get_settings() {
48
+ return apply_filters(
49
+ 'learn_press_checkout_settings',
50
+ array(
51
+ array(
52
+ 'title' => __( 'Enable cart', 'learnpress' ),
53
+ 'desc' => __( 'Check this option to enable user can purchase multiple course at one time', 'learnpress' ),
54
+ 'id' => $this->get_field_name( 'enable_cart' ),
55
+ 'default' => 'yes',
56
+ 'type' => 'checkbox'
57
+ ),
58
+ array(
59
+ 'title' => __( 'Add to cart redirect', 'learnpress' ),
60
+ 'desc' => __( 'Redirect to checkout immediately after add course to cart', 'learnpress' ),
61
+ 'id' => $this->get_field_name( 'redirect_after_add' ),
62
+ 'default' => 'yes',
63
+ 'type' => 'checkbox'
64
+ ),
65
+ array(
66
+ 'title' => __( 'AJAX add to cart', 'learnpress' ),
67
+ 'desc' => __( 'Using AJAX to add course to the cart', 'learnpress' ),
68
+ 'id' => $this->get_field_name( 'ajax_add_to_cart' ),
69
+ 'default' => 'no',
70
+ 'type' => 'checkbox'
71
+ ),
72
+ array(
73
+ 'title' => __( 'No checkout free course', 'learnpress' ),
74
+ 'desc' => __( 'Check this option to enable user can enroll course immediate without add to cart', 'learnpress' ),
75
+ 'id' => $this->get_field_name( 'no_checkout_free_course' ),
76
+ 'default' => 'yes',
77
+ 'type' => 'checkbox'
78
+ ),
79
+ array(
80
+ 'title' => __( 'Cart page', 'learnpress' ),
81
+ 'id' => $this->get_field_name( 'cart_page_id' ),
82
+ 'default' => '',
83
+ 'type' => 'pages-dropdown'
84
+ ),
85
+ array(
86
+ 'title' => __( 'Checkout page', 'learnpress' ),
87
+ 'id' => $this->get_field_name( 'checkout_page_id' ),
88
+ 'default' => '',
89
+ 'type' => 'pages-dropdown'
90
+ ),
91
+ array(
92
+ 'title' => __( 'Checkout Endpoints', 'learnpress' ),
93
+ 'type' => 'title'
94
+ ),
95
+ array(
96
+ 'title' => __( 'Order received', 'learnpress' ),
97
+ 'id' => $this->get_field_name( 'checkout_endpoints[lp_order_received]' ),
98
+ 'default' => 'lp-order-received',
99
+ 'type' => 'text'
100
+ ),
101
+ )
102
+ );
103
+ }
104
+ }
105
+
106
+ //
107
+ return new LP_Settings_Checkout();
inc/admin/settings/class-lp-settings-courses.php ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Settings_Courses
5
+ */
6
+ class LP_Settings_Courses extends LP_Settings_Base {
7
+ function __construct() {
8
+ $this->id = 'courses';
9
+ $this->text = __( 'Courses', 'learnpress' );
10
+
11
+ parent::__construct();
12
+ }
13
+
14
+ 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
+ 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
+
45
+ $courses_page_id = learn_press_get_page_id( 'courses' );
46
+ $courses_permalink = ( $courses_page_id > 0 && get_post( $courses_page_id ) ) ? get_page_uri( $courses_page_id ) : _x( 'courses', 'default-slug', 'learnpress' );
47
+
48
+ if ( $courses_page_id && trim( $course_base, '/' ) === $courses_permalink ) {
49
+ update_option( 'learn_press_use_verbose_page_rules', 'yes' );
50
+ } else {
51
+ delete_option( 'learn_press_use_verbose_page_rules' );
52
+ }
53
+ }
54
+
55
+ function output() {
56
+ $view = learn_press_get_admin_view( 'settings/courses.php' );
57
+ require_once $view;
58
+ }
59
+
60
+ function get_settings() {
61
+ return apply_filters(
62
+ 'learn_press_courses_settings',
63
+ array(
64
+ array(
65
+ 'title' => __( 'Courses Page', 'learnpress' ),
66
+ 'id' => $this->get_field_name( 'courses_page_id' ),
67
+ 'default' => '',
68
+ 'type' => 'pages-dropdown'
69
+ ),
70
+ array(
71
+ 'title' => __( 'Course category base', 'learnpress' ),
72
+ 'id' => $this->get_field_name( 'course_category_base' ),
73
+ 'default' => 'course-category',
74
+ 'type' => 'text'
75
+ ),
76
+ array(
77
+ 'title' => __( 'Course tag base', 'learnpress' ),
78
+ 'id' => $this->get_field_name( 'course_tag_base' ),
79
+ 'default' => 'course-tag',
80
+ 'type' => 'text'
81
+ ),
82
+ array(
83
+ 'title' => __( 'Review course before publish', 'learnpress' ),
84
+ 'desc' => __( 'The course need to review by admin before it can be published', 'learnpress' ),
85
+ 'id' => $this->get_field_name( 'required_review' ),
86
+ 'default' => 'yes',
87
+ 'type' => 'checkbox'
88
+ ),
89
+ array(
90
+ 'title' => __( 'Enable edit published course', 'learnpress' ),
91
+ 'desc' => __( 'Allows instructor edit the course that published without review.<br /> If this option is disabled, the course status will be changed to Pending Review when the instructor update course', 'learnpress' ),
92
+ 'id' => $this->get_field_name( 'enable_edit_published' ),
93
+ 'default' => 'yes',
94
+ 'type' => 'checkbox'
95
+ ),
96
+ array(
97
+ 'title' => __( 'Archive', 'learnpress' ),
98
+ 'type' => 'title'
99
+ ),
100
+ array(
101
+ 'title' => __( 'Courses limit', 'learnpress' ),
102
+ 'desc' => __( 'Number of courses display per page', 'learnpress' ),
103
+ 'id' => $this->get_field_name( 'archive_course_limit' ),
104
+ 'default' => '10',
105
+ 'type' => 'number'
106
+ ),
107
+ array(
108
+ 'title' => __( 'Course thumbnail', 'learnpress' ),
109
+ 'type' => 'title'
110
+ ),
111
+ array(
112
+ 'title' => __( 'Single course', 'learnpress' ),
113
+ 'id' => $this->get_field_name( 'single_course_image_size' ),
114
+ 'default' => array( 800, 450, 'yes' ),
115
+ 'type' => 'image-size'
116
+ ),
117
+ array(
118
+ 'title' => __( 'Course thumbnail', 'learnpress' ),
119
+ 'id' => $this->get_field_name( 'course_thumbnail_image_size' ),
120
+ 'default' => array( 400, 250, 'yes' ),
121
+ 'type' => 'image-size'
122
+ ),
123
+ array(
124
+ 'title' => __( 'Single course permalink', 'learnpress' ),
125
+ 'type' => 'title'
126
+ ),
127
+ array(
128
+ 'title' => __( 'Single course permalink', 'learnpress' ),
129
+ 'type' => 'course-permalink',
130
+ 'default' => ''
131
+ )/*,
132
+ array(
133
+ 'title' => __( 'Auto navigation item', 'learnpress' ),
134
+ 'type' => 'auto_nav_course_item',
135
+ 'default' => 'yes',
136
+ 'type' => 'checkbox',
137
+ 'desc' => __( 'Navigate to next item after user complete', 'learnpress' )
138
+ )*/
139
+ )
140
+ );
141
+ }
142
+ }
143
+
144
+ return new LP_Settings_Courses();
inc/admin/settings/class-lp-settings-emails.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Settings_Emails
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_Settings_Emails extends LP_Settings_Base {
16
+ /**
17
+ * Constructor
18
+ */
19
+ function __construct() {
20
+ $this->id = 'emails';
21
+ $this->text = __( 'Emails', 'learnpress' );
22
+ parent::__construct();
23
+ }
24
+
25
+ /**
26
+ * Sections
27
+ *
28
+ * @return mixed
29
+ */
30
+ function get_sections() {
31
+
32
+ $emails = LP_Emails::instance()->emails;
33
+
34
+ $sections = array(
35
+ 'general' => array( 'id' => 'general', 'title' => __( 'General options', 'learnpress' ) )
36
+ );
37
+
38
+ if ( $emails ) foreach ( $emails as $email ) {
39
+ $sections[$email->id] = array(
40
+ 'id' => $email->id,
41
+ 'title' => $email->title
42
+ );
43
+ }
44
+
45
+
46
+ /*$sections = array(
47
+ 'general' => __( 'General options', 'learnpress' ),
48
+ 'new_course' => __( 'New course', 'learnpress' ),
49
+ 'published_course' => __( 'Published course', 'learnpress' ),
50
+ 'new_order' => __( 'New order', 'learnpress' ),
51
+ 'enrolled_course' => __( 'Enrolled course', 'learnpress' ),
52
+ 'passed_course' => __( 'Passed course', 'learnpress' ),
53
+ );*/
54
+ return $sections = apply_filters( 'learn_press_settings_sections_' . $this->id, $sections );
55
+ }
56
+
57
+ /**
58
+ * @param $default_message
59
+ */
60
+ function message_editor( $default_message ) {
61
+ $settings = LP()->settings;
62
+ $content = stripslashes( $settings->get( $this->section['id'] . '.message', $default_message ) );
63
+ $editor_id = 'email_message';
64
+ wp_editor(
65
+ stripslashes( $content ),
66
+ $editor_id,
67
+ array(
68
+ 'textarea_rows' => 10,
69
+ 'wpautop' => false,
70
+ 'textarea_name' => "lpr_settings[$this->id][message]",
71
+ )
72
+ );
73
+
74
+ }
75
+
76
+ function get_email_class( $id ) {
77
+ $emails = LP_Emails::instance()->emails;
78
+ if ( $emails ) foreach ( $emails as $email ) {
79
+ if ( $email->id == $id ) {
80
+ return $email;
81
+ }
82
+ }
83
+ return false;
84
+ }
85
+
86
+ /**
87
+ *
88
+ */
89
+ function output_section_general() {
90
+ $view = learn_press_get_admin_view( 'settings/emails/general.php' );
91
+ include_once $view;
92
+ }
93
+
94
+ function output_section_new_course() {
95
+ if ( $email = $this->get_email_class( 'new_course' ) ) {
96
+ $email->admin_options( $this );
97
+ }
98
+ }
99
+
100
+ function output_section_rejected_course() {
101
+ if ( $email = $this->get_email_class( 'rejected_course' ) ) {
102
+ $email->admin_options( $this );
103
+ }
104
+ }
105
+
106
+ function output_section_new_order() {
107
+ if ( $email = $this->get_email_class( 'new_order' ) ) {
108
+ $email->admin_options( $this );
109
+ }
110
+ }
111
+
112
+ function output_section_published_course() {
113
+ if ( $email = $this->get_email_class( 'published_course' ) ) {
114
+ $email->admin_options( $this );
115
+ }
116
+ }
117
+
118
+ function output_section_enrolled_course() {
119
+ if ( $email = $this->get_email_class( 'enrolled_course' ) ) {
120
+ $email->admin_options( $this );
121
+ }
122
+ }
123
+
124
+ function output_section_finished_course() {
125
+ if ( $email = $this->get_email_class( 'finished_course' ) ) {
126
+ $email->admin_options( $this );
127
+ }
128
+ }
129
+
130
+ function output_section_become_a_teacher() {
131
+ $view = learn_press_get_admin_view( 'settings/emails/general.php' );
132
+ include_once $view;
133
+ $this->_become_a_teacher_request();
134
+ }
135
+
136
+ private function _become_a_teacher_request() {
137
+ $view = learn_press_get_admin_view( 'settings/emails/become-a-teacher-request.php' );
138
+ include_once $view;
139
+ }
140
+
141
+ function get_settings() {
142
+ return apply_filters(
143
+ 'learn_press_email_settings',
144
+ array(
145
+ array(
146
+ 'title' => __( 'Profile page', 'learnpress' ),
147
+ 'id' => $this->get_field_name( 'profile_page_id' ),
148
+ 'id' => $this->get_field_name( 'profile_page_id' ),
149
+ 'default' => '',
150
+ 'type' => 'pages-dropdown'
151
+ )
152
+ )
153
+ );
154
+ }
155
+ }
156
+
157
+ //
158
+ return new LP_Settings_Emails();
inc/admin/settings/class-lp-settings-general.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ 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
+ function output() {
23
+ $view = learn_press_get_admin_view( 'settings/general.php' );
24
+ include_once $view;
25
+ }
26
+
27
+ function get_settings() {
28
+ return apply_filters(
29
+ 'learn_press_general_settings',
30
+ array(
31
+ array(
32
+ 'title' => __( 'Instructors registration', 'learnpress' ),
33
+ 'desc' => __( 'Create option for instructors registration.', 'learnpress' ),
34
+ 'id' => $this->get_field_name( 'instructor_registration' ),
35
+ 'default' => 'no',
36
+ 'type' => 'checkbox'
37
+ ),
38
+ array(
39
+ 'title' => __( 'Auto update post name', 'learnpress' ),
40
+ 'desc' => __( 'The post\'s name will update along with the title when changes title of lesson or quiz in course curriculum or question in quiz<br />The permalink also is changed, therefore uncheck this if you don\'t want to change the permalink', 'learnpress' ),
41
+ 'id' => $this->get_field_name( 'auto_update_post_name' ),
42
+ 'default' => 'no',
43
+ 'type' => 'checkbox'
44
+ ),
45
+ array(
46
+ 'title' => __( 'Currency', 'learnpress' ),
47
+ 'id' => $this->get_field_name( 'currency' ),
48
+ 'default' => 'USD',
49
+ 'type' => 'select',
50
+ 'options' => $this->_get_currency_options()
51
+ ),
52
+ array(
53
+ 'title' => __( 'Currency position', 'learnpress' ),
54
+ 'id' => $this->get_field_name( 'currency_pos' ),
55
+ 'default' => 'left',
56
+ 'type' => 'select',
57
+ 'options' => $this->_get_currency_positions()
58
+ ),
59
+ array(
60
+ 'title' => __( 'Thousands Separator', 'learnpress' ),
61
+ 'id' => $this->get_field_name( 'thousands_separator' ),
62
+ 'default' => ',',
63
+ 'type' => 'text',
64
+ 'options' => $this->_get_currency_positions()
65
+ ),
66
+ array(
67
+ 'title' => __( 'Decimals Separator', 'learnpress' ),
68
+ 'id' => $this->get_field_name( 'decimals_separator' ),
69
+ 'default' => '.',
70
+ 'type' => 'text',
71
+ 'options' => $this->_get_currency_positions()
72
+ ),
73
+ array(
74
+ 'title' => __( 'Number of Decimals', 'learnpress' ),
75
+ 'id' => $this->get_field_name( 'number_of_decimals' ),
76
+ 'default' => '2',
77
+ 'type' => 'text',
78
+ 'options' => $this->_get_currency_positions()
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
+ /*function save() {
125
+ $settings = LP_Admin_Settings::instance( 'general' );// $_POST['lpr_settings']['general'];
126
+ $settings->bind( $_POST['learn_press'] );
127
+ $settings->update();
128
+ }*/
129
+ }
130
+
131
+ return new LP_Settings_General();
inc/admin/settings/class-lp-settings-pages.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Settings_Pages
5
+ */
6
+ class LP_Settings_Pages extends LP_Settings_Base {
7
+ function __construct() {
8
+ $this->id = 'pages';
9
+ $this->text = __( 'Pages', 'learnpress' );
10
+
11
+ parent::__construct();
12
+ }
13
+
14
+ 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
+ function get_settings() {
33
+ return apply_filters(
34
+ 'learn_press_page_settings',
35
+ array(
36
+ array( 'section' => 'profile' ),
37
+ array(
38
+ 'title' => __( 'Profile', 'learnpress' ),
39
+ 'id' => $this->get_field_name( 'profile_page_id' ),
40
+ 'default' => '',
41
+ 'type' => 'pages-dropdown'
42
+ ),
43
+ array(
44
+ 'title' => __( 'Add link to admin bar', 'learnpress' ),
45
+ 'id' => $this->get_field_name( 'admin_bar_link' ),
46
+ 'default' => 'yes',
47
+ 'type' => 'checkbox'
48
+ ),
49
+ array(
50
+ 'title' => __( 'Text link', 'learnpress' ),
51
+ 'id' => $this->get_field_name( 'admin_bar_link_text' ),
52
+ 'default' => '',
53
+ 'type' => 'text',
54
+ 'placeholder' => __( 'Default: View Course Profile', 'learnpress' ),
55
+ 'class' => 'regular-text'
56
+ ),
57
+ array(
58
+ 'title' => __( 'Target link', 'learnpress' ),
59
+ 'id' => $this->get_field_name( 'admin_bar_link_target' ),
60
+ 'default' => 'yes',
61
+ 'type' => 'select',
62
+ 'options' => array(
63
+ '_self' => __( 'Self', 'learnpress' ),
64
+ '_blank' => __( 'New window', 'learnpress' )
65
+ )
66
+ ),
67
+ /*array(
68
+ 'title' => __( 'Access level', 'learnpress' ),
69
+ 'id' => $this->get_field_name( 'profile_access_level' ),
70
+ 'default' => 'private',
71
+ 'type' => 'select',
72
+ 'options' => array(
73
+ 'private' => __( 'Private (Only account own)', 'learnpress' ),
74
+ 'public' => __( 'Public', 'learnpress' )
75
+ )
76
+ ),*/
77
+ array(
78
+ 'title' => __( 'Endpoints', 'learnpress' ),
79
+ 'type' => 'title'
80
+ ),
81
+ array(
82
+ 'title' => __( 'Tab Courses', 'learnpress' ),
83
+ 'id' => $this->get_field_name( 'profile_endpoints[profile-courses]' ),
84
+ 'default' => 'courses',
85
+ 'type' => 'text',
86
+ 'placeholder' => '',
87
+ 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[profile/admin/courses]</code>', __( 'Example link is', 'learnpress' ) )
88
+ ),
89
+ array(
90
+ 'title' => __( 'Tab Quizzes', 'learnpress' ),
91
+ 'id' => $this->get_field_name( 'profile_endpoints[profile-quizzes]' ),
92
+ 'default' => 'quizzes',
93
+ 'type' => 'text',
94
+ 'placeholder' => '',
95
+ 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[profile/admin/quizzes]</code>', __( 'Example link is', 'learnpress' ) )
96
+ ),
97
+ array(
98
+ 'title' => __( 'Tab Orders', 'learnpress' ),
99
+ 'id' => $this->get_field_name( 'profile_endpoints[profile-orders]' ),
100
+ 'default' => 'orders',
101
+ 'type' => 'text',
102
+ 'placeholder' => '',
103
+ 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[profile/admin/orders]</code>', __( 'Example link is', 'learnpress' ) )
104
+ ),
105
+ array(
106
+ 'title' => __( 'View order', 'learnpress' ),
107
+ 'id' => $this->get_field_name( 'profile_endpoints[profile-order-details]' ),
108
+ 'default' => 'order-details',
109
+ 'type' => 'text',
110
+ 'placeholder' => '',
111
+ 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[profile/admin/order-details/123]</code>', __( 'Example link is', 'learnpress' ) )
112
+ ),
113
+ array( 'section' => 'quiz' ),
114
+ array(
115
+ 'title' => __( 'Endpoints', 'learnpress' ),
116
+ 'type' => 'title'
117
+ ),
118
+ array(
119
+ 'title' => __( 'Results', 'learnpress' ),
120
+ 'id' => $this->get_field_name( 'quiz_endpoints[results]' ),
121
+ 'default' => 'results',
122
+ 'type' => 'text',
123
+ 'placeholder' => '',
124
+ 'desc' => __( 'This is a slug and should be unique.', 'learnpress' ) . sprintf( ' %s <code>[quizzes/sample-quiz/results]</code>', __( 'Example link is', 'learnpress' ) )
125
+ ),
126
+ array( 'section' => 'become_a_teacher' ),
127
+ array(
128
+ 'title' => __( 'Become a teacher', 'learnpress' ),
129
+ 'id' => $this->get_field_name( 'become_a_teacher_page_id' ),
130
+ 'default' => '',
131
+ 'type' => 'pages-dropdown'
132
+ )
133
+ )
134
+ );
135
+ }
136
+
137
+ function _get_settings( $section ) {
138
+ $settings = $this->get_settings();
139
+ $get = false;
140
+ $return = array();
141
+ foreach ( $settings as $k => $v ) {
142
+ if ( !empty( $v['section'] ) ) {
143
+ if ( $get ) {
144
+ break;
145
+ }
146
+ if ( $v['section'] == $section ) {
147
+ $get = true;
148
+ continue;
149
+ }
150
+ }
151
+ if ( $get ) {
152
+ $return[] = $v;
153
+ }
154
+ }
155
+ return $return;
156
+ }
157
+
158
+ function output_section_profile() {
159
+ $view = learn_press_get_admin_view( 'settings/pages/profile.php' );
160
+ require_once $view;
161
+ }
162
+
163
+ function output_section_quiz() {
164
+ $view = learn_press_get_admin_view( 'settings/pages/quiz.php' );
165
+ require_once $view;
166
+ }
167
+
168
+ function output_section_become_a_teacher() {
169
+ $view = learn_press_get_admin_view( 'settings/pages/become-a-teacher.php' );
170
+ require_once $view;
171
+ }
172
+ }
173
+
174
+ new LP_Settings_Pages();
inc/admin/settings/class-lp-settings-payments.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Settings_Payment
5
+ *
6
+ * @author ThimPress
7
+ * @package LearnPress/Admin/Classes
8
+ * @version 1.0
9
+ */
10
+
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit; // Exit if accessed directly
13
+ }
14
+
15
+ class LP_Settings_Payments extends LP_Settings_Base {
16
+ /**
17
+ * Constructor
18
+ */
19
+ function __construct() {
20
+ $this->id = 'payments';
21
+ $this->text = __( 'Payments', 'learnpress' );
22
+
23
+ parent::__construct();
24
+ }
25
+
26
+ /**
27
+ * @return mixed
28
+ */
29
+ function get_sections() {
30
+ $gateways = LP_Gateways::instance()->get_gateways();
31
+ $sections = array();
32
+ if ( $gateways ) foreach ( $gateways as $id => $gateway ) {
33
+ $sections[$id] = array(
34
+ 'id' => $id,
35
+ 'title' => !empty( $gateway->method_title ) ? $gateway->method_title : ucfirst( $gateway->id ),
36
+ 'description' => !empty( $gateway->method_description ) ? $gateway->method_description : ''
37
+ );
38
+ }
39
+ return $sections;
40
+ }
41
+
42
+ function output() {
43
+ $section = $this->section;
44
+ ?>
45
+ <h3 class="learn-press-settings-title"><?php echo $this->section['title']; ?></h3>
46
+ <?php if ( !empty( $this->section['description'] ) ) : ?>
47
+ <p class="description">
48
+ <?php echo $this->section['description']; ?>
49
+ </p>
50
+ <?php endif; ?>
51
+ <table class="form-table">
52
+ <tbody>
53
+ <?php
54
+ if ( 'paypal' == $section['id'] ) {
55
+ $this->output_section_paypal();
56
+ } else {
57
+ do_action( 'learn_press_section_' . $this->id . '_' . $section['id'] );
58
+ }
59
+ ?>
60
+ </tbody>
61
+ </table>
62
+ <script type="text/javascript">
63
+ jQuery(function ($) {
64
+ var $sandbox_mode = $('#learn_press_paypal_sandbox_mode'),
65
+ $paypal_type = $('#learn_press_paypal_type');
66
+ $paypal_type.change(function () {
67
+ $('.learn_press_paypal_type_security').toggleClass('hide-if-js', 'security' != this.value);
68
+ });
69
+ $sandbox_mode.change(function () {
70
+ this.checked ? $('.sandbox input').removeAttr('readonly') : $('.sandbox input').attr('readonly', true);
71
+ });
72
+ })
73
+ </script>
74
+ <?php
75
+ }
76
+
77
+ /**
78
+ * Print admin options for paypal section
79
+ */
80
+ function output_section_paypal() {
81
+ $view = learn_press_get_admin_view( 'settings/payments.php' );
82
+ include_once $view;
83
+ }
84
+
85
+ function saves() {
86
+
87
+ $settings = LP_Admin_Settings::instance( 'payment' );
88
+ $section = $this->section['id'];
89
+ if ( 'paypal' == $section ) {
90
+ $post_data = $_POST['lpr_settings'][$this->id];
91
+
92
+ $settings->set( 'paypal', $post_data );
93
+ } else {
94
+ do_action( 'learn_press_save_' . $this->id . '_' . $section );
95
+ }
96
+ $settings->update();
97
+
98
+ }
99
+ }
100
+
101
+ new LP_Settings_Payments();
inc/admin/settings/class-lp-settings-profile.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_Settings_Profile
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_Profile extends LP_Settings_Base {
16
+
17
+ /**
18
+ * Constructor
19
+ */
20
+ function __construct() {
21
+ $this->id = 'profile';
22
+ $this->text = __( 'Profile', 'learnpress' );
23
+
24
+ parent::__construct();
25
+ }
26
+
27
+ function output(){
28
+ $view = learn_press_get_admin_view( 'settings/profile.php' );
29
+ include_once $view;
30
+ }
31
+
32
+ function get_settings() {
33
+ return apply_filters(
34
+ 'learn_press_checkout_settings',
35
+ array(
36
+ array(
37
+ 'title' => __( 'Profile page', 'learnpress' ),
38
+ 'id' => $this->get_field_name( 'profile_page_id' ),
39
+ 'id' => $this->get_field_name( 'profile_page_id' ),
40
+ 'default' => '',
41
+ 'type' => 'pages-dropdown'
42
+ )
43
+ )
44
+ );
45
+ }
46
+ }
47
+ //
48
+ //return new LP_Settings_Profile();
inc/admin/sub-menus/add-ons.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Admin view for add-ons page display in admin under menu LearnPress -> Add ons
4
+ *
5
+ * @author ThimPress
6
+ * @package Admin/Views
7
+ * @version 1.0
8
+ */
9
+
10
+ if ( !defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly
12
+ }
13
+
14
+ /**
15
+ * Add-on page
16
+ */
17
+ function learn_press_add_ons_page() {
18
+ $current = isset( $_GET['tab'] ) ? $_GET['tab'] : '';
19
+
20
+ ?>
21
+ <div id="learn-press-add-ons-wrap" class="wrap">
22
+ <h2><?php echo __( 'LearnPress Add-ons', 'learnpress' ); ?></h2>
23
+ <!-- <p class="top-description"><?php _e( 'Add-ons are features that you can add or remove depending on your needs', 'learnpress' ); ?></p>-->
24
+ <ul class="subsubsub">
25
+ <?php
26
+ do_action( 'learn_press_add_ons_before_head_tab' );
27
+ if ( $tabs = learn_press_get_add_on_tabs() ) {
28
+ if ( empty( $tabs[$current] ) ) {
29
+ $tab_ids = array_keys( $tabs );
30
+ $current = reset( $tab_ids );
31
+ }
32
+ $links = array();
33
+ foreach ( $tabs as $id => $args ) {
34
+ $class = array();
35
+ if ( !empty( $args['class'] ) ) {
36
+ if ( is_array( $args['class'] ) ) {
37
+ $class = array_merge( $class, $args['class'] );
38
+ } else {
39
+ $class[] = $args['class'];
40
+ }
41
+ }
42
+
43
+ $class = join( ' ', $class );
44
+ if ( !empty( $args['url'] ) ) {
45
+ $url = $args['url'];
46
+ } else {
47
+ $url = admin_url( 'admin.php?page=learn_press_add_ons&tab=' . $id );
48
+ }
49
+ $text = $args['text'];
50
+
51
+ $links[] = sprintf( '<li class="%s"><a href="%s" class="%s">%s</a></li>', $class, $url, ( $current == $id ? 'current' : '' ), $text );
52
+ }
53
+ echo join( '|', $links );
54
+ }
55
+ do_action( 'learn_press_add_ons_after_head_tab' );
56
+ ?>
57
+ </ul>
58
+ <div class="clear"></div>
59
+ <?php do_action( 'learn_press_add_ons_content_tab_' . $current, $current ); ?>
60
+ </div>
61
+ <?php
62
+ }
inc/admin/sub-menus/settings.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Admin view for settings page display in admin under menu Settings -> LearnPress
4
+ *
5
+ * @author ThimPress
6
+ * @package Admin/Views
7
+ * @version 1.0
8
+ */
9
+
10
+ if ( !defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly
12
+ }
13
+ /**
14
+ * Setting page
15
+ */
16
+ function learn_press_settings_page() {
17
+ LP_Assets::enqueue_style( 'learn-press-admin' );
18
+ LP_Assets::enqueue_script( 'learn-press-admin-settings', LP()->plugin_url( 'assets/js/admin/settings.js' ) );
19
+
20
+
21
+ $current_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : '';
22
+
23
+ $tabs = learn_press_settings_tabs_array();
24
+
25
+ if ( !$current_tab && $tabs ) {
26
+ $keys = array_keys( $tabs );
27
+ $current_tab = reset( $keys );
28
+ }
29
+
30
+ // ensure all settings relevant to rewrite rules effect immediately
31
+ flush_rewrite_rules();
32
+
33
+ if ( !empty( $_GET['settings-updated'] ) ) : ?>
34
+ <div id="message" class="updated notice is-dismissible">
35
+ <p><?php _e( 'LearnPress settings updated.', 'learnpress' ); ?></p>
36
+ </div>
37
+ <?php endif; ?>
38
+
39
+ <div class="wrap">
40
+ <form method="<?php echo esc_attr( apply_filters( 'learn_press_settings_form_method_tab_' . $current_tab, 'post' ) ); ?>" id="mainform" action="" enctype="multipart/form-data">
41
+ <div id="icon-themes" class="icon32"><br></div>
42
+ <h2 class="nav-tab-wrapper">
43
+ <?php if ( $tabs ) foreach ( $tabs as $tab => $name ) { ?>
44
+ <?php $class = ( $tab == $current_tab ) ? ' nav-tab-active' : ''; ?>
45
+ <a class="nav-tab <?php echo $class; ?>" href="?page=learn_press_settings&tab=<?php echo $tab; ?>"><?php echo $name; ?></a>
46
+ <?php } ?>
47
+ <?php do_action( 'learn_press_settings_tabs' ); ?>
48
+ </h2>
49
+ <?php
50
+ do_action( 'learn_press_sections_' . $current_tab );
51
+ do_action( 'learn_press_settings_' . $current_tab );
52
+ ?>
53
+ <p>
54
+ <button class="button button-primary"><?php _e( 'Save settings', 'learnpress' ); ?></button>
55
+ </p>
56
+ <?php wp_nonce_field( 'learn_press_settings', 'learn_press_settings_nonce' ); ?>
57
+ </form>
58
+ </div>
59
+ <?php
60
+ }
61
+
62
+ function learn_press_admin_update_settings() {
63
+
64
+ $tabs = learn_press_settings_tabs_array();
65
+ $current_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : '';
66
+
67
+ if ( !$current_tab && $tabs ) {
68
+ $keys = array_keys( $tabs );
69
+ $current_tab = reset( $keys );
70
+ }
71
+
72
+ $class_name = apply_filters( 'learn_press_settings_class_' . $current_tab, 'LP_Settings_' . $tabs[$current_tab] );
73
+ if ( !class_exists( $class_name ) ) {
74
+ $class_file = apply_filters( 'learn_press_settings_file_' . $current_tab, LP()->plugin_path( 'inc/admin/settings/class-lp-settings-' . $current_tab . '.php' ) );
75
+ if ( !file_exists( $class_file ) ) {
76
+ return false;
77
+ }
78
+
79
+ include_once $class_file;
80
+ if ( !class_exists( $class_name ) ) {
81
+
82
+ }
83
+ }
84
+
85
+ if ( !empty( $_POST ) ) {
86
+ // Check if our nonce is set.
87
+ if ( !isset( $_POST['learn_press_settings_nonce'] ) ) {
88
+ return;
89
+ }
90
+
91
+ // Verify that the nonce is valid.
92
+ if ( !wp_verify_nonce( $_POST['learn_press_settings_nonce'], 'learn_press_settings' ) ) {
93
+ return;
94
+ }
95
+
96
+ do_action( 'learn_press_settings_save_' . $current_tab );
97
+
98
+ $section = !empty( $_REQUEST['section'] ) ? '&section=' . $_REQUEST['section'] : '';
99
+ LP_Admin_Notice::add( '<p><strong>' . __( 'Settings saved', 'learnpress' ) . '</strong></p>' );
100
+
101
+ wp_redirect( admin_url( 'options-general.php?page=learn_press_settings&tab=' . $current_tab . $section . '&settings-updated=true' ) );
102
+ exit();
103
+ }
104
+ }
inc/admin/sub-menus/statistics.php ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Admin statistic
4
+ */
5
+
6
+ if ( !defined( 'ABSPATH' ) ) {
7
+ exit; // Exit if accessed directly
8
+ }
9
+
10
+ /**
11
+ * Class LP_Admin_Submenu_Statistic
12
+ */
13
+ class LP_Admin_Submenu_Statistic {
14
+ /**
15
+ * @var string
16
+ */
17
+ public $tab = '';
18
+
19
+ /**
20
+ * @var string
21
+ */
22
+ public $section = '';
23
+
24
+ /**
25
+ * @var null
26
+ */
27
+ protected static $_instance = null;
28
+
29
+ /**
30
+ * LP_Admin_Submenu_Statistic constructor.
31
+ */
32
+ function __construct() {
33
+ add_action( 'learn_press_get_stats_users', array( $this, 'get_stats_users' ) );
34
+ add_action( 'learn_press_get_stats_courses', array( $this, 'get_stats_courses' ) );
35
+ add_action( 'learn_press_get_stats_orders', array( $this, 'get_stats_orders' ) );
36
+ add_action( 'wp_ajax_learn_press_load_chart', array( $this, 'load_chart' ) );
37
+ add_action( 'admin_enqueue_scripts', array( $this, 'load_chart_scripts' ) );
38
+ }
39
+
40
+ /**
41
+ * Statistic page
42
+ */
43
+ function display() {
44
+ $this->tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'users';
45
+ $this->section = isset( $_GET['section'] ) ? $_GET['section'] : '';
46
+ $tabs = apply_filters( 'learn_press_statistics_tabs', array(
47
+ 'users' => __( 'Users', 'learnpress' ),
48
+ 'courses' => __( 'Courses', 'learnpress' ),
49
+ 'orders' => __( 'Orders', 'learnpress' ),
50
+ ) );
51
+ echo '<div class="wrap">';
52
+ echo '<h2 class="nav-tab-wrapper">';
53
+ foreach ( $tabs as $tab => $name ) {
54
+ $class = ( $tab == $this->tab ) ? ' nav-tab-active' : '';
55
+ echo "<a class='nav-tab$class' href='?page=learn_press_statistics&tab=$tab'>$name</a>";
56
+ }
57
+ echo '</h2>';
58
+ do_action( 'learn_press_get_stats_' . $this->tab . '' );
59
+ echo '</div>';
60
+ }
61
+
62
+ /**
63
+ *
64
+ */
65
+ function get_stats_users() {
66
+ require_once learn_press_get_admin_view( 'statistics/users.php' );
67
+ }
68
+
69
+ /**
70
+ *
71
+ */
72
+ function get_stats_courses() {
73
+ require_once learn_press_get_admin_view( 'statistics/courses.php' );
74
+ }
75
+
76
+ /**
77
+ *
78
+ */
79
+ function get_stats_orders() {
80
+ require_once learn_press_get_admin_view( 'statistics/orders.php' );
81
+ }
82
+
83
+ function load_chart() {
84
+ $type = learn_press_get_request( 'type' );
85
+ $response = null;
86
+ switch ( $type ) {
87
+ case 'user-last-7-days':
88
+ $response = learn_press_get_chart_users( null, 'days', 7 );
89
+ break;
90
+ case 'user-last-30-days':
91
+ $response = learn_press_get_chart_users( null, 'days', 30 );
92
+ break;
93
+ case 'user-last-12-months':
94
+ $response = learn_press_get_chart_users( null, 'months', 12 );
95
+ break;
96
+ case 'user-custom-time':
97
+ $range = learn_press_get_request( 'range' );
98
+ $from_time = strtotime( $range[0] );
99
+ $to_time = strtotime( $range[1] );
100
+ list( $from_d, $from_m, $from_y ) = explode( ' ', date( 'd m Y', $from_time ) );
101
+ list( $to_d, $to_m, $to_y ) = explode( ' ', date( 'd m Y', $to_time ) );
102
+ if ( $from_y != $to_y ) {
103
+ $response = learn_press_get_chart_users( $to_time, 'years', $to_y - $from_y + 1 );
104
+ } else {
105
+ if ( $from_m != $to_m ) {
106
+ $response = learn_press_get_chart_users( $to_time, 'months', $to_m - $from_m + 1 );
107
+ } else {
108
+ $response = learn_press_get_chart_users( $to_time, 'days', $to_d - $from_d + 1 );
109
+ }
110
+ }
111
+ break;
112
+ case 'user-all':
113
+ global $wpdb;
114
+ $results = $wpdb->get_row( "
115
+ SELECT min(u.user_registered) as `from`, max(u.user_registered) as `to`
116
+ FROM {$wpdb->users} u
117
+ " );
118
+
119
+ if ( $results ) {
120
+ $_POST['range'] = array( date( 'Y/m/d', strtotime( $results->from ) ), date( 'Y/m/d', strtotime( $results->to ) ) );
121
+ $_POST['type'] = 'user-custom-time';
122
+ $this->load_chart();
123
+ return;
124
+ }
125
+ break;
126
+
127
+ //////////////////
128
+ case 'course-last-7-days':
129
+ $response = learn_press_get_chart_courses( null, 'days', 7 );
130
+ break;
131
+ case 'course-last-30-days':
132
+ $response = learn_press_get_chart_courses( null, 'days', 30 );
133
+ break;
134
+ case 'course-last-12-months':
135
+ $response = learn_press_get_chart_courses( null, 'months', 12 );
136
+ break;
137
+ case 'course-custom-time':
138
+ $range = learn_press_get_request( 'range' );
139
+ $from_time = strtotime( $range[0] );
140
+ $to_time = strtotime( $range[1] );
141
+ list( $from_d, $from_m, $from_y ) = explode( ' ', date( 'd m Y', $from_time ) );
142
+ list( $to_d, $to_m, $to_y ) = explode( ' ', date( 'd m Y', $to_time ) );
143
+ if ( $from_y != $to_y ) {
144
+ $months = abs( ( date( 'Y', $to_time ) - date( 'Y', $from_time ) ) * 12 + ( date( 'm', $to_time ) - date( 'm', $from_time ) ) ) + 1;
145
+ if ( $months > 12 ) {
146
+ $response = learn_press_get_chart_courses( $to_time, 'years', $to_y - $from_y + 1 );
147
+ } else {
148
+ $response = learn_press_get_chart_courses( $to_time, 'months', $months );
149
+ }
150
+ } else {
151
+ if ( $from_m != $to_m ) {
152
+ $response = learn_press_get_chart_courses( $to_time, 'months', $to_m - $from_m + 1 );
153
+ } else {
154
+ $response = learn_press_get_chart_courses( $to_time, 'days', $to_d - $from_d + 1 );
155
+ }
156
+ }
157
+ break;
158
+ case 'course-all':
159
+ global $wpdb;
160
+ $results = $wpdb->get_row(
161
+ $wpdb->prepare( "
162
+ SELECT min(c.post_date) as `from`, max(c.post_date) as `to`
163
+ FROM {$wpdb->posts} c
164
+ WHERE c.post_date <> %s
165
+ AND c.post_type = %s
166
+ ", '0000-00-00 00:00:00', 'lp_course' )
167
+ );
168
+
169
+ if ( $results ) {
170
+ $_POST['range'] = array( date( 'Y/m/d', strtotime( $results->from ) ), date( 'Y/m/d', strtotime( $results->to ) ) );
171
+ $_POST['type'] = 'course-custom-time';
172
+ $this->load_chart();
173
+ return;
174
+ }
175
+
176
+ //////////////////
177
+ case 'order-last-7-days':
178
+ $response = learn_press_get_chart_orders( null, 'days', 7 );
179
+ break;
180
+ case 'order-last-30-days':
181
+ $response = learn_press_get_chart_orders( null, 'days', 30 );
182
+ break;
183
+ case 'order-last-12-months':
184
+ $response = learn_press_get_chart_orders( null, 'months', 12 );
185
+ break;
186
+ case 'order-custom-time':
187
+ $range = learn_press_get_request( 'range' );
188
+ $from_time = strtotime( $range[0] );
189
+ $to_time = strtotime( $range[1] );
190
+ list( $from_d, $from_m, $from_y ) = explode( ' ', date( 'd m Y', $from_time ) );
191
+ list( $to_d, $to_m, $to_y ) = explode( ' ', date( 'd m Y', $to_time ) );
192
+ if ( $from_y != $to_y ) {
193
+ $months = abs( ( date( 'Y', $to_time ) - date( 'Y', $from_time ) ) * 12 + ( date( 'm', $to_time ) - date( 'm', $from_time ) ) ) + 1;
194
+ if ( $months > 12 ) {
195
+ $response = learn_press_get_chart_orders( $to_time, 'years', $to_y - $from_y + 1 );
196
+ } else {
197
+ $response = learn_press_get_chart_orders( $to_time, 'months', $months );
198
+ }
199
+ } else {
200
+ if ( $from_m != $to_m ) {
201
+ $response = learn_press_get_chart_orders( $to_time, 'months', $to_m - $from_m + 1 );
202
+ } else {
203
+ $response = learn_press_get_chart_orders( $to_time, 'days', $to_d - $from_d + 1 );
204
+ }
205
+ }
206
+ break;
207
+ case 'order-all':
208
+ global $wpdb;
209
+ $results = $wpdb->get_row(
210
+ $wpdb->prepare( "
211
+ SELECT min(c.post_date) as `from`, max(c.post_date) as `to`
212
+ FROM {$wpdb->posts} c
213
+ WHERE c.post_date <> %s
214
+ AND c.post_type = %s
215
+ ", '0000-00-00 00:00:00', 'lp_order' )
216
+ );
217
+
218
+ if ( $results ) {
219
+ $_POST['range'] = array( date( 'Y/m/d', strtotime( $results->from ) ), date( 'Y/m/d', strtotime( $results->to ) ) );
220
+ $_POST['type'] = 'order-custom-time';
221
+ $this->load_chart();
222
+ return;
223
+ }
224
+ }
225
+
226
+ learn_press_send_json( $response );
227
+ }
228
+
229
+ /**
230
+ *
231
+ */
232
+ function load_chart_scripts() {
233
+ //wp_enqueue_style( 'lpr-jquery-ui-css', LP_CSS_URL . 'jquery-ui.css' );
234
+ //wp_enqueue_script( 'lpr-jquery-ui-js', LP_JS_URL . 'jquery-ui.js', array( 'jquery' ), '', false );
235
+ wp_enqueue_script( 'learn-press-chart', LP_JS_URL . 'chart.min.js', array( 'jquery', 'jquery-ui-datepicker' ) );
236
+ wp_enqueue_script( 'learn-press-statistic', LP_JS_URL . 'admin/statistic.js' );
237
+ }
238
+
239
+ /**
240
+ * @return LP_Admin_Submenu_Statistic|null
241
+ */
242
+ static function instance() {
243
+ if ( !self::$_instance ) {
244
+ self::$_instance = new self();
245
+ }
246
+ return self::$_instance;
247
+ }
248
+ }
249
+
250
+ return LP_Admin_Submenu_Statistic::instance();
251
+
252
+
253
+
inc/admin/views/admin-notice.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Template for display a notice in admin
4
+ */
5
+
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ exit;
8
+ }
9
+
10
+ ?>
11
+ <div<?php if( ! empty( $id ) ) echo ' id="' . $id . '"';?> class="<?php echo $type;?>">
12
+ <?php echo $message;?>
13
+ </div>
inc/admin/views/admin-template.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/html" id="tmpl-learn-press-search-items">
2
+ <div class="modal-inner">
3
+ <header>
4
+ <input type="text" name="lp-search-term" placeholder="<# if(data.placeholder){#>{{data.placeholder}}<#}else{#><?php _e( 'Type here to search the item', 'learnpress' );?><#}#>">
5
+ </header>
6
+ <article>
7
+ <ul class="lp-list-items">
8
+ </ul>
9
+ </article>
10
+ <footer>
11
+ <button class="lp-add-item button" disabled="disabled" data-text="<# if(data.addText){ #>{{data.addText}}<# }else{ #><?php _e( 'Add', 'learnpress' );?><# } #>">
12
+ <# if(data.addText){ #>{{data.addText}}<# }else{ #><?php _e( 'Add', 'learnpress' );?><# } #>
13
+ </button>
14
+ <button class="close-modal button" onclick="LearnPress.MessageBox.hide();"><# if(data.closeText){ #>{{data.closeText}}<# }else{ #><?php _e( 'Close', 'learnpress' );?><# } #></button>
15
+ </footer>
16
+ </div>
17
+ </script>
inc/admin/views/meta-boxes/course/curriculum.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ $exclude_quiz = array();
4
+ $exclude_lesson = array();
5
+ $current_user = get_current_user_id();
6
+ global $wpdb;
7
+ $q = $wpdb->prepare(
8
+ "SELECT pm.meta_value
9
+ FROM $wpdb->posts AS p
10
+ INNER JOIN $wpdb->postmeta AS pm ON p.ID = pm.post_id
11
+ WHERE p.post_type = %s
12
+ AND p.post_author = %d
13
+ AND pm.meta_key = %s",
14
+ LP()->course_post_type,
15
+ $current_user,
16
+ '_lpr_course_lesson_quiz'
17
+ );
18
+ $used_item = $wpdb->get_col(
19
+ $q
20
+ );
21
+
22
+ for ( $i = 0; $i < count( $used_item ); $i ++ ) {
23
+ $lesson_quiz_array = unserialize( $used_item[$i] );
24
+ for ( $j = 0; $j < count( $lesson_quiz_array ); $j ++ ) {
25
+ if ( isset( $lesson_quiz_array[$j]['lesson_quiz'] ) ) {
26
+ foreach ( $lesson_quiz_array[$j]['lesson_quiz'] as $key => $value ) {
27
+ array_push( $exclude_lesson, $value );
28
+ array_push( $exclude_quiz, $value );
29
+ }
30
+ }
31
+ }
32
+ }*/
33
+ global $post;
34
+ $course_sections = $course->get_curriculum();
35
+
36
+ $hidden_sections = (array) get_post_meta( $post->ID, '_admin_hidden_sections', true );
37
+ ?>
38
+ <div id="lp-course-curriculum" class="lp-course-curriculum">
39
+ <h3 class="curriculum-heading">
40
+ <?php _e( 'Curriculum', 'learnpress' ); ?>
41
+ <span class="description"><?php _e( 'Outline your course and add content with sections, lessons and quizzes.', 'learnpress' ); ?></span>
42
+
43
+ <p align="right" class="items-toggle">
44
+ <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>
45
+ <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>
46
+ </p>
47
+ </h3>
48
+ <!---->
49
+ <ul class="curriculum-sections">
50
+ <?php
51
+ if ( $course_sections ):
52
+ foreach ( $course_sections as $k => $section ):
53
+
54
+ $content_items = '';
55
+
56
+ if ( $section->items ):
57
+ foreach ( $section->items as $item ):
58
+ //if ( LP()->quiz_post_type == $item->post_type ) $exclude_quiz[] = $item->ID;
59
+ //if ( LP()->lesson_post_type == $item->post_type ) $exclude_lesson[] = $item->ID;
60
+ $loop_item_view = learn_press_get_admin_view( 'meta-boxes/course/loop-item.php' );
61
+ ob_start();
62
+ include $loop_item_view;
63
+ $content_items .= "\n" . ob_get_clean();
64
+ endforeach;
65
+ endif;
66
+
67
+ include learn_press_get_admin_view( 'meta-boxes/course/loop-section.php' );
68
+ endforeach;
69
+ unset( $content_items );
70
+ endif;
71
+ if ( !empty( $section ) ) foreach ( get_object_vars( $section ) as $k => $v ) {
72
+ $section->{$k} = null;
73
+ }
74
+ include learn_press_get_admin_view( 'meta-boxes/course/loop-section.php' );
75
+ ?>
76
+ </ul>
77
+ </div>
inc/admin/views/meta-boxes/course/js-template.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php global $post;?>
2
+ <script type="text/html" id="tmpl-quick-add-lesson">
3
+ <div id="lpr-quick-add-lesson-form" class="lpr-quick-add-form">
4
+ <input type="text" name="" />
5
+ <button type="button" class="button" data-action="cancel"><?php _e( 'Cancel [ESC]', 'learnpress' ); ?></button>
6
+ <button type="button" class="button" data-action="add"><?php _e( 'Add [Enter]', 'learnpress' ); ?></button>
7
+ <span class="lpr-ajaxload">...</span>
8
+ </div>
9
+ </script>
10
+ <script type="text/html" id="tmpl-quick-add-quiz">
11
+ <div id="lpr-quick-add-quiz-form" class="lpr-quick-add-form">
12
+ <input type="text" name="" />
13
+ <button type="button" class="button" data-action="cancel"><?php _e( 'Cancel [ESC]', 'learnpress' ); ?></button>
14
+ <button type="button" class="button" data-action="add"><?php _e( 'Add [Enter]', 'learnpress' ); ?></button>
15
+ <span class="lpr-ajaxload">...</span>
16
+ </div>
17
+ </script>
18
+ <script type="text/html" id="tmpl-curriculum-section">
19
+ <?php
20
+ learn_press_admin_view(
21
+ 'meta-boxes/course/loop-section.php',
22
+ array(
23
+ 'class' => 'lp-section-empty',
24
+ 'toggle_class' => 'dashicons-minus',
25
+ 'section_name' => '',
26
+ 'content_items' => ''
27
+ )
28
+ );
29
+ ?>
30
+ </script>
31
+ <script type="text/html" id="tmpl-section-item">
32
+ <?php
33
+ $item = learn_press_post_object( array( 'post_type' => LP()->lesson_post_type ) );
34
+ $item->post_title = '{{data.text}}';
35
+ $item->item_id = '{{data.id}}';
36
+ $item->post_type = '{{data.type}}';
37
+ learn_press_admin_view(
38
+ 'meta-boxes/course/loop-item.php',
39
+ array(
40
+ 'item' => $item
41
+ )
42
+ )
43
+ ?>
44
+ </script>
45
+
46
+ <?php $curriculum_items = LP_Course::get_course( $post )->get_curriculum_items( array( 'group' => true, 'field' => 'ID' ) );?>
47
+ <script type="text/html" id="tmpl-lp-modal-search-lesson">
48
+ <div id="lp-modal-search-lesson" class="lp-modal-search">
49
+ <?php
50
+ $exclude_lessons = $curriculum_items['lessons'];
51
+ $lessons = learn_press_get_current_user()->get_lessons(array('orderby' => 'name', 'order' => 'ASC', 'posts_per_page' => -1));
52
+ ?>
53
+ <div class="lp-search-items">
54
+ <input type="text" name="lp-item-name" placeholder="<?php _e( 'Type here to search the lesson', 'learnpress' );?>" />
55
+ <!--<button type="button" class="button lp-add-new-item"><?php _e( 'Add New', 'learnpress' );?></button>-->
56
+ </div>
57
+ <ul>
58
+ <?php
59
+ if ( $lessons ) {
60
+ foreach( $lessons as $lesson ){
61
+ $hidden = in_array( $lesson->ID, $exclude_lessons ) ? 'selected hide-if-js' : '';
62
+ ?>
63
+ <li class="<?php echo $hidden;?>" data-id="<?php echo $lesson->ID;?>" data-type="<?php echo $lesson->post_type;?>" data-text="<?php echo esc_attr( $lesson->post_title );?>">
64
+ <label>
65
+ <input type="checkbox" value="<?php echo $lesson->ID;?>">
66
+ <span class="lp-item-text"><?php echo $lesson->post_title;?></span>
67
+ </label>
68
+ </li>
69
+ <?php
70
+ }
71
+ }
72
+ ?>
73
+ <li class="lp-search-no-results hide-if-js" data-id="0"><?php _e( 'No results', 'learnpress' );?></li>
74
+ </ul>
75
+ <button class="lp-add-item button" disabled="disabled" data-text="<?php _e( 'Add to section', 'learnpress' );?>"><?php _e( 'Add to section', 'learnpress' );?></button>
76
+ <button class="lp-close-lightbox button" onclick="LearnPress.MessageBox.hide();"><?php _e( 'Close', 'learnpress' );?></button>
77
+ </div>
78
+ </script>
79
+ <script type="text/html" id="tmpl-lp-modal-search-quiz">
80
+ <div id="lp-modal-search-quiz" class="lp-modal-search">
81
+ <?php
82
+ $exclude_quizzes = $curriculum_items['quizzes'];
83
+ $args = array('orderby' => 'name', 'order' => 'ASC', 'posts_per_page' => -1);
84
+ $quizzes = learn_press_get_current_user()->get_quizzes( $args );
85
+ ?>
86
+ <div class="lp-search-items">
87
+ <input type="text" name="lp-item-name" placeholder="<?php _e( 'Type here to search the quiz', 'learnpress' );?>" />
88
+ <!--<button type="button" class="button lp-add-new-item"><?php _e( 'Add New', 'learnpress' );?></button>-->
89
+ </div>
90
+ <ul>
91
+ <?php
92
+ if ( $quizzes ) {
93
+ foreach( $quizzes as $quiz ){
94
+ $hidden = in_array( $quiz->ID, $exclude_quizzes ) ? 'selected hide-if-js' : '';
95
+ ?>
96
+ <li class="<?php echo $hidden;?>" data-id="<?php echo $quiz->ID;?>" data-type="<?php echo $quiz->post_type;?>" data-text="<?php echo esc_attr( $quiz->post_title );?>">
97
+ <label>
98
+ <input type="checkbox" value="<?php echo $quiz->ID;?>">
99
+ <span class="lp-item-text"><?php echo $quiz->post_title;?></span>
100
+ </label>
101
+ </li>
102
+ <?php
103
+ }
104
+ }
105
+ ?>
106
+ <li class="lp-search-no-results hide-if-js" data-id="0"><?php _e( 'No results', 'learnpress' );?></li>
107
+ </ul>
108
+ <button class="lp-add-item button" disabled="disabled" data-text="<?php _e( 'Add to section', 'learnpress' );?>"><?php _e( 'Add to section', 'learnpress' );?></button>
109
+ <button class="lp-close-lightbox button" onclick="LearnPress.MessageBox.hide();"><?php _e( 'Close', 'learnpress' );?></button>
110
+ </div>
111
+ </script>
112
+ <script type="text/javascript">
113
+ var LP_Curriculum_Settings = {
114
+ selectedItems: [<?php echo join(',', array_merge( $exclude_quizzes, $exclude_lessons ) ) ;?>]
115
+ }
116
+ </script>
inc/admin/views/meta-boxes/course/loop-item.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Template for displaying item in a section
4
+ *
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 = apply_filters(
15
+ 'learn_press_support_item_types', array(
16
+ 'lp_quiz' => __( 'Quiz', 'learn_press' ),
17
+ 'lp_lesson' => __( 'Lesson', 'learn_press' )
18
+ )
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
+ <?php foreach ( $support_types as $_type => $text ) { ?>
28
+ <span class="learn-press-icon<?php echo $_type == $item->post_type ? ' item-selected' : ''; ?> item-<?php echo $_type; ?>" title="<?php echo sprintf( __( 'Switch to %s', 'learnpress' ), $text ); ?>" data-type="<?php echo $_type;?>"></span>
29
+ <?php } ?>
30
+ </td>
31
+ <td class="section-item-input">
32
+ <input type="text" 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( 'Enter name of the new item here and press Enter', 'learnpress' ); ?>" />
33
+ <input type="hidden" name="<?php echo $group_name; ?>[old_name]" value="<?php echo esc_attr( $item->post_title ); ?>" />
34
+ <input type="hidden" name="<?php echo $group_name; ?>[item_id]" value="<?php echo $item_id; ?>" />
35
+ <input type="hidden" name="<?php echo $group_name; ?>[section_item_id]" value="<?php echo $section_item_id; ?>" />
36
+ <input type="hidden" class="lp-item-type" name="<?php echo $group_name; ?>[post_type]" value="<?php echo $item->post_type; ?>" />
37
+ </td>
38
+ <td class="section-item-actions">
39
+ <p class="lp-item-actions lp-button-actions">
40
+ <?php do_action( 'learn_press_admin_begin_section_item_actions', $item, $section ); ?>
41
+ <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>
42
+ <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>
43
+ <span class="item-checkbox">
44
+ <input type="checkbox" value="<?php echo $section_item_id; ?>" />
45
+ </span>
46
+ <?php do_action( 'learn_press_admin_end_section_item_actions', $item, $section ); ?>
47
+ </p>
48
+ </td>
49
+ <?php do_action( 'learn_press_admin_end_section_item', $item, $section ); ?>
50
+ </tr>
inc/admin/views/meta-boxes/course/loop-section.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Template for displaying the loop of section
4
+ *
5
+ * @param $class
6
+ * @param $toggle_class
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
+ $class = array(
21
+ 'curriculum-section'
22
+ );
23
+ if ( !$section->section_id ) {
24
+ $class[] = 'lp-empty-section';
25
+ }
26
+ if ( $is_hidden ) {
27
+ $class[] = 'is_hidden';
28
+ }
29
+ ?>
30
+ <li class="<?php echo join( ' ', $class ); ?>" data-id="<?php echo $section ? $section->section_id : ''; ?>">
31
+ <h3 class="curriculum-section-head">
32
+ <input name="_lp_curriculum[__SECTION__][name]" type="text" data-field="section-name" placeholder="<?php _e( 'Enter the section name and hit enter', 'learnpress' ); ?>" class="lp-section-name no-submit" value="<?php echo esc_attr( $section->section_name ); ?>" />
33
+ <p class="lp-section-actions lp-button-actions">
34
+ <a href="" data-action="expand" class="dashicons dashicons-arrow-down<?php echo $is_hidden ? '' : ' hide-if-js'; ?>" title="<?php _e( 'Expand', 'learnpress' ); ?>"></a>
35
+ <a href="" data-action="collapse" class="dashicons dashicons-arrow-up<?php echo !$is_hidden ? '' : ' hide-if-js'; ?>" title="<?php _e( 'Collapse', 'learnpress' ); ?>"></a>
36
+ <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>
37
+ <a href="" class="move"></a>
38
+ </p>
39
+ </h3>
40
+ <div class="curriculum-section-content<?php echo $is_hidden ? ' hide-if-js' : ''; ?>">
41
+ <div class="item-bulk-actions">
42
+ <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' ); ?>" />
43
+ <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>
44
+ <!--
45
+ <button class="button" type="button" data-action="delete-forever" disabled="disabled" data-title="<?php _e( 'Delete Forever', 'learnpress' ); ?>"><?php _e( 'Delete Forever', 'learnpress' ); ?></button>
46
+
47
+ <button class="button hide-if-js" type="button" data-action="cancel"><?php _e( 'Cancel', 'learnpress' ); ?></button>-->
48
+ <!--<div class="button lp-check-all-items">
49
+ <input type="checkbox" class="" />
50
+ <span>&dtrif;</span>
51
+ </div>-->
52
+ <span class="button lp-check-items">
53
+ <input class="lp-check-all-items" data-action="check-all" type="checkbox" />
54
+ </span>
55
+ </div>
56
+ <table class="curriculum-section-items">
57
+ <?php echo isset( $content_items ) ? $content_items : ''; ?>
58
+ <?php
59
+ $item = learn_press_post_object( array( 'post_type' => LP()->lesson_post_type ) );
60
+ ?>
61
+ <?php learn_press_admin_view( 'meta-boxes/course/loop-item.php', array( 'item' => $item) ); ?>
62
+
63
+ </table>
64
+ <?php do_action( 'learn_press_after_section_items', $section ); ?>
65
+ <?php if ( $buttons = apply_filters( 'learn_press_loop_section_buttons', array() ) ): ?>
66
+ <br />
67
+ <div class="lp-add-buttons">
68
+ <input type="text" class="regular-text no-submit" name="lp-new-item-name" placeholder="<?php _e( 'The name of new question or quiz', 'learnpress' ); ?>" />
69
+ <div class="button lp-button-dropdown lp-button-add-item disabled">
70
+ <span class="lp-dropdown-label lp-add-new-item"><?php _e( 'Add New', 'learnpress' ); ?></span>
71
+ <span class="lp-dropdown-arrow">+</span>
72
+ <ul class="lp-dropdown-items">
73
+ <?php foreach ( learn_press_section_item_types() as $slug => $name ) { ?>
74
+ <li>
75
+ <a href="" data-type="<?php echo $slug; ?>"><?php echo $name; ?></a>
76
+ </li>
77
+ <?php } ?>
78
+ </ul>
79
+ </div>
80
+ -OR-
81
+ <?php foreach ( learn_press_section_item_types() as $slug => $name ) { ?>
82
+ <?php if ( apply_filters( 'learn_press_button_type_select_items', true, $slug ) ) { ?>
83
+ <button class="button" type="button" data-action="add-<?php echo $slug;?>" data-type="<?php echo $slug;?>">
84
+ <?php echo sprintf( __( 'Select %s', 'learnpress' ), $name ); ?>
85
+ </button>
86
+ <?php } ?>
87
+ <?php } ?>
88
+ <!--<button class="button " id="add-quiz" type="button" data-action="add-quiz" data-type="lp_quiz">
89
+ <?php _e( 'Select Quizzes', 'learnpress' ); ?>
90
+ </button>-->
91
+ </div>
92
+ <?php endif; ?>
93
+ <?php do_action( 'learn_press_after_section_content', $section ); ?>
94
+ </div>
95
+ </li>
inc/admin/views/meta-boxes/course/review-log.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ global $post;
3
+ if( get_post_type() != 'lp_course' ){
4
+ return;
5
+ }
6
+ if ( !learn_press_course_is_required_review( $post->ID, get_current_user_id() ) ) {
7
+ //return;
8
+ }
9
+ $user = learn_press_get_current_user();
10
+ $course_user = learn_press_get_user( get_post_field( 'post_author', $post->ID ) );
11
+ $required_review = LP()->settings->get( 'required_review' ) == 'yes';
12
+ $enable_edit_published = LP()->settings->get( 'enable_edit_published' ) == 'yes';
13
+ ?>
14
+ <input type="hidden" id="learn-press-course-status" value="<?php echo get_post_status();?>">
15
+ <?php
16
+ if ( $user->is_instructor() && ( ( get_post() != 'publish' ) ) ) {
17
+ ?>
18
+ <div id="learn-press-review-message">
19
+ <h4><?php _e( 'Review message to Reviewer', 'learnpress' ); ?></h4>
20
+ <p>
21
+ <label>
22
+ <input type="checkbox" id="learn-press-notice-check" name="learn_press_submit_course_notice_reviewer" value="yes" />
23
+ <?php _e( 'Message to Reviewer', 'learnpress' ); ?>
24
+ </label>
25
+ </p>
26
+ <div class="hide-if-js">
27
+ <textarea class="widefat" rows="5" disabled="disabled" name="review_message" resize="none" placeholder="<?php _e( 'Enter some information here for reviewer', 'learnpress' ); ?>"></textarea>
28
+
29
+ </div>
30
+ <?php if( $required_review && !$enable_edit_published ){?>
31
+ <p class="description submitdelete">
32
+ <?php _e( 'Warning! Your course will become to Pending Review for admin reviews before it can be published when you update' ); ?>
33
+ </p>
34
+ <?php } ?>
35
+ </div>
36
+ <?php ob_start(); ?>
37
+ <script type="text/javascript">
38
+ jQuery('#post').submit(function (e) {
39
+ var $review = $('textarea[name="review_message"]');
40
+ if (!($review.val() + '').length && $('#learn-press-notice-check').is(':checked')) {
41
+ alert('<?php _e( 'Please write your message to Reviewer', 'learnpress' );?>');
42
+ $review.focus();
43
+ return false;
44
+ }
45
+ });
46
+ jQuery('#learn-press-notice-check').change(function(){
47
+ var checked = this.checked,
48
+ $review = jQuery('textarea[name="review_message"]').prop('disabled', !checked),
49
+ $parent = $review.parent();
50
+ $parent[checked ? 'slideDown' : 'slideUp'](function(){
51
+ checked && $review.focus();
52
+ });
53
+ });
54
+ </script>
55
+ <?php learn_press_enqueue_script( strip_tags( ob_get_clean() ) ); ?>
56
+ <?php
57
+ } else if ( $user->is_admin() && !$course_user->is_admin() ) {
58
+ ?>
59
+ <div id="learn-press-review-message">
60
+ <h4><?php _e( 'Review message to Instructor', 'learnpress' ); ?></h4>
61
+ <p>
62
+ <label>
63
+ <input type="checkbox" id="learn-press-notice-check" name="learn_press_submit_course_notice_instructor" value="yes"/>
64
+ <?php _e( 'Message to Instructor', 'learnpress' ); ?>
65
+ </label>
66
+ </p>
67
+ <div class="hide-if-js">
68
+ <textarea class="widefat" rows="5" disabled="disabled" name="review_message" resize="none" placeholder="<?php _e( 'Enter some information here for instructor. E.g: for reason why the course is rejected etc...', 'learnpress' ); ?>"></textarea>
69
+ </div>
70
+ </div>
71
+ <?php ob_start(); ?>
72
+ <script type="text/javascript">
73
+ jQuery(function($){
74
+ console.log($('input[name="publish"]')[0])
75
+ })
76
+ jQuery('#post').submit(function (e) {
77
+ var $review = $('textarea[name="review_message"]', this),
78
+ status = $('select#post_status', this).val(),
79
+ current_status = $('#learn-press-course-status').val(),
80
+ clicked = $(':focus', this).attr('name');
81
+
82
+ if ( ( ( clicked == 'save' || clicked == 'publish' ) && ( status != current_status ) || ( clicked == 'publish' ) && ( status == 'pending' ) )&& !($review.val() + '').length) {
83
+ alert('<?php _e( 'Please write your message to Instructor', 'learnpress' );?>');
84
+ var $check = $('input[name="learn_press_submit_course_notice_instructor"]').prop('checked', true);
85
+ $check.trigger('change');
86
+ return false;
87
+ }else{
88
+ }
89
+ console.log($('input[name="publish"]')[0])
90
+
91
+ });
92
+ jQuery('#learn-press-notice-check').change(function(){
93
+ var that = this,
94
+ $review = jQuery('textarea[name="review_message"]').prop('disabled', !this.checked),
95
+ $parent = $review.parent();
96
+ $parent[this.checked ? 'slideDown' : 'slideUp'](function(){
97
+ that.checked && $review.focus();
98
+ });
99
+ });
100
+ </script>
101
+ <?php learn_press_enqueue_script( strip_tags( ob_get_clean() ) ); ?>
102
+ <?php
103
+ }
inc/admin/views/meta-boxes/course/review-logs.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ global $post;
3
+ $index = $total_reviews;
4
+ ?>
5
+ <h4>
6
+ <?php if ( $total_reviews ) { ?>
7
+ <?php printf( _nx( '%d review', '%d reviews', $total_reviews, 'learnpress' ), $total_reviews ); ?>
8
+ <?php } else { ?>
9
+ <?php _e( 'This course has not got any review yet', 'learnpress' ); ?>
10
+ <?php } ?>
11
+ </h4>
12
+ <ul class="learn-press-review-logs clearfix">
13
+ <?php foreach ( $reviews as $review ) { ?>
14
+ <?php $user = get_userdata( $review->user_id ); ?>
15
+ <li>
16
+ <div class="review-index">#<?php echo $index --; ?></div>
17
+ <div class="review-user">
18
+ <span class="user-avatar"><?php echo get_avatar( $review->user_id ); ?></span>
19
+ </div>
20
+ <div class="review-content">
21
+ <strong class="user-nicename"><?php echo $user->user_nicename; ?></strong>
22
+
23
+ <div class="review-message"><?php echo $review->message; ?></div>
24
+ <span class="lp-label <?php echo $review->status == 'publish' ? 'lp-label-preview' : ( $review->user_type == 'reviewer' ? 'lp-label-final' : 'lp-label-format' ); ?>">
25
+ <?php echo $review->status == 'publish' ? __( 'Publish', 'learnpress' ) : ( $review->user_type == 'reviewer' ? __( 'Soft rejected', 'learnpress' ) : __( 'Submit for review', 'learnpress' ) ); ?>
26
+ </span>
27
+ <?php if ( current_user_can( 'delete_others_lp_courses' ) ) { ?>
28
+ &nbsp;&nbsp;
29
+ <a href="<?php echo wp_nonce_url( admin_url( 'post.php?post=' . $post->ID . '&action=edit&delete_log=' . $review->review_log_id ), 'delete_log_' . $post->ID . '_' . $review->review_log_id ); ?>"><?php _e( 'Delete', 'learnpress' ); ?></a>
30
+ <?php } ?>
31
+ </div>
32
+ </li>
33
+ <?php } ?>
34
+ </ul>
35
+ <?php if ( $total_reviews > 10 ) { ?>
36
+ <p>
37
+ <?php if ( $total_reviews == $count_reviews ) { ?>
38
+ <a href="<?php echo remove_query_arg( 'view_all_review' ); ?>"><?php _e( 'View less', 'learnpress' ); ?></a>
39
+ <?php } else { ?>
40
+ <a href="<?php echo add_query_arg( 'view_all_review', '1' ); ?>"><?php _e( 'View all', 'learnpress' ); ?></a>
41
+ <?php } ?>
42
+ </p>
43
+ <?php } ?>
inc/admin/views/meta-boxes/course/tabs.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ global $wp_meta_boxes;
3
+ $screen = get_current_screen();
4
+ $page = $screen->id;
5
+ $context = 'normal';
6
+ $hidden = get_hidden_meta_boxes( $screen );
7
+
8
+ if ( isset( $wp_meta_boxes[ $page ][ $context ] ) ) {
9
+ echo '<h3 id="course-tabs-h3">';
10
+ foreach ( array( 'high', 'sorted', 'core', 'default', 'low' ) as $priority ) {
11
+ if ( isset( $wp_meta_boxes[$page][$context][$priority] ) ) {
12
+ foreach ( (array) $wp_meta_boxes[$page][$context][$priority] as $box ) {
13
+ if ( false == $box || !$box['title'] )
14
+ continue;
15
+ $i ++;
16
+ $hidden_class = in_array( $box['id'], $hidden ) ? ' hide-if-js' : '';
17
+ if( $box['id'] == 'course_tabs') continue;
18
+ echo '<a href="#' . $box['id'] . '">' . $box['title'] . '</a>';
19
+ }
20
+ }
21
+ }
22
+ echo '</h3>';
23
+ }
inc/admin/views/meta-boxes/order/actions.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ 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
+
7
+ $datef = __( 'M j, Y @ H:i' );
8
+ if ( 0 != $post->ID ) {
9
+ if ( 'future' == $post->post_status ) { // scheduled for publishing at a future date
10
+ $stamp = __( 'Scheduled for: <b>%1$s</b>' );
11
+ } elseif ( 'publish' == $post->post_status || 'private' == $post->post_status ) { // already published
12
+ $stamp = __( 'Order date: <b>%1$s</b>' );
13
+ } elseif ( '0000-00-00 00:00:00' == $post->post_date_gmt ) { // draft, 1 or more saves, no date specified
14
+ $stamp = __( 'Publish <b>immediately</b>' );
15
+ } elseif ( time() < strtotime( $post->post_date_gmt . ' +0000' ) ) { // draft, 1 or more saves, future date specified
16
+ $stamp = __( 'Schedule for: <b>%1$s</b>' );
17
+ } else { // draft, 1 or more saves, date specified
18
+ $stamp = __( 'Publish on: <b>%1$s</b>' );
19
+ }
20
+ $date = date_i18n( $datef, strtotime( $post->post_date ) );
21
+ } else { // draft (no saves, and thus no date specified)
22
+ $stamp = __( 'Publish <b>immediately</b>' );
23
+ $date = date_i18n( $datef, strtotime( current_time( 'mysql' ) ) );
24
+ }
25
+
26
+ ?>
27
+ <div class="submitbox" id="submitpost">
28
+ <div id="minor-publishing">
29
+ <div id="misc-publishing-actions">
30
+ <?php if ( $can_publish ) : // Contributors don't get to choose the date of publish ?>
31
+
32
+ <div class="misc-pub-section">
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 ) {
40
+ echo '<option value="' . esc_attr( $status ) . '" ' . selected( $status, 'lp-' . $order->get_status(), false ) . '>' . esc_html( $status_name ) . '</option>';
41
+ }
42
+ ?>
43
+ </select>
44
+ </div>
45
+
46
+ <div class="misc-pub-section">
47
+ <label>
48
+ <?php _e( 'Customer', 'learnpress' ); ?>
49
+ </label>
50
+ <!--
51
+ <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">
52
+ -->
53
+ <?php
54
+ wp_dropdown_users(
55
+ array(
56
+ 'show_option_none' => __( '[Guest]', 'learnpress' ),
57
+ 'show_option_none' => __( '[Guest]', 'learnpress' ),
58
+ 'name' => 'order-customer',
59
+ 'id' => null,
60
+ 'selected' => $order->get_user( 'ID' )
61
+ )
62
+ );
63
+ ?>
64
+ </div>
65
+
66
+ <div class="misc-pub-section curtime misc-pub-curtime">
67
+ <span id="timestamp"><?php printf( $stamp, $date ); ?></span>
68
+ <a href="#edit_timestamp" class="edit-timestamp hide-if-no-js"><span aria-hidden="true"><?php _e( 'Edit' ); ?></span>
69
+ <span class="screen-reader-text"><?php _e( 'Edit date and time' ); ?></span></a>
70
+ <fieldset id="timestampdiv" class="hide-if-js">
71
+ <legend class="screen-reader-text"><?php _e( 'Date and time' ); ?></legend>
72
+ <?php touch_time( ( $action === 'edit' ), 1 ); ?>
73
+ </fieldset>
74
+ </div><?php // /misc-pub-section ?>
75
+ <?php endif; ?>
76
+ </div>
77
+ <div id="major-publishing-actions">
78
+ <div id="delete-action">
79
+ <?php
80
+ if ( current_user_can( "delete_post", $post->ID ) ) {
81
+ if ( !EMPTY_TRASH_DAYS )
82
+ $delete_text = __( 'Delete Permanently' );
83
+ else
84
+ $delete_text = __( 'Move to Trash' );
85
+ ?>
86
+ <a class="submitdelete deletion" href="<?php echo get_delete_post_link( $post->ID ); ?>"><?php echo $delete_text; ?></a><?php
87
+ } ?>
88
+ </div>
89
+
90
+ <div id="publishing-action">
91
+ <span class="spinner"></span>
92
+ <input name="original_publish" type="hidden" id="original_publish" value="Update">
93
+ <input name="save" type="submit" class="button button-primary button-large" id="publish" value="Update">
94
+ </div>
95
+ <div class="clear"></div>
96
+ </div>
97
+ </div>
98
+ </div>
inc/admin/views/meta-boxes/order/details.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( isset( $order_items ) ) {
3
+ $currency_symbol = learn_press_get_currency_symbol( $order_items->currency );
4
+ } else {
5
+ $currency_symbol = learn_press_get_currency_symbol();
6
+ }
7
+ global $post;
8
+ ?>
9
+ <div id="learn-press-order" class="order-details">
10
+ <div class="order-data">
11
+ <h3 class="order-data-number"><?php echo sprintf( __( 'Order %s', 'learnpress' ), $order->get_order_number() ); ?></h3>
12
+
13
+ <div
14
+ class="order-data-date"><?php echo sprintf( __( 'Date %s', 'learnpress' ), $order->order_date ); ?></div>
15
+ <div class="order-data-status <?php echo sanitize_title( $order->post_status ); ?>"><?php echo sprintf( __( 'Status %s', 'learnpress' ), $order->get_order_status() ); ?></div>
16
+ <div
17
+ class="order-data-payment-method"><?php echo learn_press_payment_method_from_slug( $post->ID ); ?></div>
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 $display_name = $order->get_user( 'display_name' );
26
+ echo empty( $display_name ) ? __( 'Guest', 'learnpress' ) : $display_name; ?>
27
+ </div>
28
+ <div class="user-email">
29
+ <?php $user_email = $order->get_user( 'user_email' );
30
+ echo empty( $user_email ) ? '' : $user_email; ?>
31
+ </div>
32
+ <div class="user-ip-address">
33
+ <?php echo $order->user_ip_address; ?>
34
+ </div>
35
+ <?php if ( $title = $order->get_payment_method_title() ) { ?>
36
+ <div class="payment-method-title">
37
+ <?php echo $order->order_total == 0 ? $title : sprintf( __( 'Pay via <strong>%s</strong>', 'learnpress' ), $title ); ?>
38
+ </div>
39
+ <?php } ?>
40
+ </div>
41
+ </div>
42
+ <br />
43
+
44
+ <h3><?php _e( 'Order Items', 'learnpress' ); ?></h3>
45
+ <div class="order-items">
46
+ <table>
47
+ <thead>
48
+ <tr>
49
+ <th><?php _e( 'Item', 'learnpress' ); ?></th>
50
+ <th><?php _e( 'Cost', 'learnpress' ); ?></th>
51
+ <th><?php _e( 'Quantity', 'learnpress' ); ?></th>
52
+ <th class="align-right"><?php _e( 'Amount', 'learnpress' ); ?></th>
53
+ </tr>
54
+ </thead>
55
+ <tbody>
56
+ <?php if ( $items = $order->get_items() ): ?>
57
+ <?php foreach ( $items as $item ) : ?>
58
+ <?php include learn_press_get_admin_view( 'meta-boxes/order/order-item.php' ); ?>
59
+ <?php endforeach; ?>
60
+ <?php endif; ?>
61
+ <tr class="no-order-items<?php echo $items ? ' hide-if-js' : ''; ?>">
62
+ <td colspan="4"><?php _e( 'No order items', 'learnpress' ); ?></td>
63
+ </tr>
64
+ </tbody>
65
+ <tfoot>
66
+ <tr>
67
+ <td width="300" colspan="3" class="align-right"><?php _e( 'Sub Total', 'learnpress' ); ?></td>
68
+ <td width="100" class="align-right">
69
+ <span class="order-subtotal">
70
+ <?php echo learn_press_format_price( $order->order_subtotal, $currency_symbol ); ?>
71
+ </span>
72
+ </td>
73
+ </tr>
74
+ <tr>
75
+ <td class="align-right" colspan="3"><?php _e( 'Total', 'learnpress' ); ?></td>
76
+ <td class="align-right total">
77
+ <span class="order-total">
78
+ <?php echo learn_press_format_price( $order->order_total, $currency_symbol ); ?>
79
+ </span>
80
+ </td>
81
+ </tr>
82
+ <tr>
83
+ <td class="align-right" colspan="4">
84
+ <button class="button" type="button" id="learn-press-add-order-item"><?php _e( 'Add Item', 'learnpress' ); ?></button>
85
+ <!--<button class="button" type="button" id="learn-press-calculate-order-total"><?php _e( 'Calculate Total', 'learnpress' ); ?></button>-->
86
+ </td>
87
+ </tr>
88
+ </tfoot>
89
+ </table>
90
+ </div>
91
+ <?php if ( $note = get_the_excerpt( $order->id ) ) { ?>
92
+ <br />
93
+ <h3><?php _e( 'Customer Note', 'learnpress' ); ?></h3>
94
+ <p class="order-note description"><?php echo $note;?></p>
95
+ <?php } ?>
96
+ </div>
97
+ <script type="text/html" id="tmpl-learn-press-modal-add-order-courses">
98
+ <div id="learn-press-modal-add-order-courses" class="lp-modal-search" data-nonce="<?php echo wp_create_nonce( 'add_item_to_order' ); ?>">
99
+ <div class="lp-search-items">
100
+ <input type="text" id="learn-press-search-item-term" data-nonce="<?php echo wp_create_nonce( 'search_item_term' ); ?>" name="lp-item-name" placeholder="<?php _e( 'Type here to search the course', 'learnpress' ); ?>" />
101
+ </div>
102
+ <ul id="learn-press-courses-result">
103
+ <li class="lp-search-no-results hide-if-js" data-id="0"><?php _e( 'No results', 'learnpress' ); ?></li>
104
+ </ul>
105
+ <button class="lp-close-lightbox button" onclick="LearnPress.MessageBox.hide();"><?php _e( 'Close', 'learnpress' ); ?></button>
106
+ </div>
107
+ </script>
inc/admin/views/meta-boxes/order/order-item.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ *
4
+ */
5
+ ?>
6
+ <tr data-item_id="<?php echo $item['id']; ?>" data-remove_nonce="<?php echo wp_create_nonce( 'remove_order_item' ); ?>">
7
+ <td>
8
+ <a href="" class="remove-order-item">&times;</a>
9
+ <a href="<?php echo get_the_permalink( $item['course_id'] ); ?>"><?php echo $item['name']; ?></a>
10
+ </td>
11
+ <td class="align-right">
12
+ <?php echo learn_press_format_price( $item['total'], $currency_symbol ); ?>
13
+ </td>
14
+ <td class="align-right"><?php echo $item['quantity']; ?></td>
15
+ <td class="align-right"><?php echo learn_press_format_price( $item['total'], $currency_symbol ); ?></td>
16
+ </tr>
inc/admin/views/meta-boxes/question/footer.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ </div>
2
+ </div>
3
+ <script type="text/javascript">
4
+ jQuery(function ($) {
5
+ LearnPress.sortableQuestionAnswers($('#learn-press-question-<?php echo $this->id;?>'));
6
+ })
7
+ </script>
inc/admin/views/meta-boxes/question/header.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ wp_die( 'Something went wrong');
3
+ $post_id = $this->get( 'ID' );
4
+ settype( $args, 'array' );
5
+ $is_collapse = array_key_exists( 'toggle', $args ) && !$args['toggle'];
6
+
7
+ $questions = learn_press_question_types();
8
+ ?>
9
+ <div class="learn-press-question learn-press-question-<?php echo preg_replace( '!_!', '-', $this->get_type() ); ?>" data-id="<?php echo $this->id; ?>">
10
+ <div class="question-head">
11
+ <p>
12
+ <a href="<?php echo get_edit_post_link( $this->id ); ?>"><?php _e( 'Edit', 'learnpress' ); ?></a>
13
+ <a href="" data-action="remove"><?php _e( 'Remove', 'learnpress' ); ?></a>
14
+ <a href="" data-action="expand" class="<?php echo !$is_collapse ? "hide-if-js" : ""; ?>"><?php _e( 'Expand', 'learnpress' ); ?></a>
15
+ <a href="" data-action="collapse" class="<?php echo $is_collapse ? "hide-if-js" : ""; ?>"><?php _e( 'Collapse', 'learnpress' ); ?></a>
16
+ <a href="" class="move">asdasdadsaasdsad</a>
17
+ </p>
18
+ <select name="learn_press_question[<?php echo $post_id; ?>][type]" data-type="<?php echo $this->get_type(); ?>">
19
+ <?php if ( $questions ) foreach ( $questions as $slug => $name ): ?>
20
+ <option value="<?php echo $slug; ?>" <?php selected( $this->get_type() == $slug ? 1 : 0, 1 ); ?>>
21
+ <?php echo $name; ?>
22
+ </option>
23
+ <?php endforeach; ?>
24
+ </select>
25
+ <input class="question-title" type="text" name="learn_press_question[<?php echo $this->id; ?>][text]" value="<?php echo esc_attr( $this->get( 'post.post_title' ) ); ?>" />
26
+ </div>
27
+ <div class="question-content<?php echo $is_collapse ? " hide-if-js" : ""; ?>">
inc/admin/views/meta-boxes/question/multi-choice-options.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="learn-press-question" id="learn-press-question-<?php echo $this->id;?>" data-type="multi-choice" data-id="<?php echo $this->id;?>">
2
+ <table class="lp-sortable lp-list-options" id="learn-press-list-options-<?php echo $this->id;?>">
3
+ <thead>
4
+
5
+ <th><?php _e( 'Answer Text', 'learnpress' ); ?></th>
6
+ <th><?php _e( 'Is Correct?', 'learnpress' ); ?></th>
7
+ <th width="20"></th>
8
+ <th width="20"></th>
9
+ </thead>
10
+ <tbody>
11
+
12
+ <?php $answers = $this->answers; if ( $answers ): ?>
13
+ <?php foreach ( $answers as $answer ): ?>
14
+ <?php
15
+ $value = $this->_get_option_value( $answer['value'] );
16
+ ?>
17
+
18
+ <?php do_action( 'learn_press_before_question_answer_option', $this ); ?>
19
+
20
+ <tr class="lp-list-option lp-list-option-<?php echo $value;?>" data-id="<?php echo $value;?>">
21
+
22
+ <td>
23
+ <input class="lp-answer-text no-submit key-nav" type="text" name="learn_press_question[<?php echo $this->id; ?>][answer][text][]" value="<?php echo esc_attr( $answer['text'] ); ?>" />
24
+ </td>
25
+ <th class="lp-answer-check">
26
+ <input type="hidden" name="learn_press_question[<?php echo $this->id; ?>][answer][value][]" value="<?php echo $value; ?>" />
27
+ <input type="checkbox" name="learn_press_question[<?php echo $this->id; ?>][checked][]" <?php checked( $answer['is_true'] == 'yes', true ); ?> value="<?php echo $value; ?>" />
28
+ </th>
29
+ <td class="lp-list-option-actions lp-remove-list-option">
30
+ <i class="dashicons dashicons-trash"></i>
31
+ </td>
32
+ <td class="lp-list-option-actions lp-move-list-option open-hand">
33
+ <i class="dashicons dashicons-sort"></i>
34
+ </td>
35
+ </tr>
36
+
37
+ <?php do_action( 'learn_press_after_question_answer_option', $this ); ?>
38
+
39
+ <?php endforeach; ?>
40
+ <?php endif; ?>
41
+ </tbody>
42
+ </table>
43
+ <p class="question-bottom-actions">
44
+ <?php
45
+ $buttons = apply_filters(
46
+ 'learn_press_question_bottom_buttons',
47
+ array(
48
+ 'add_option' => sprintf(
49
+ __( '<button class="button add-question-option-button add-question-option-button-%1$d" data-id="%1$d" type="button">%2$s</button>', 'learnpress' ),
50
+ $this->id,
51
+ __( 'Add Option', 'learnpress' )
52
+ ),
53
+ 'change_type' => learn_press_dropdown_question_types(array('echo' => false, 'id' => 'learn-press-dropdown-question-types-' . $this->id, 'selected' => $this->type ))
54
+ ),
55
+ $this
56
+ );
57
+ echo join( "\n", $buttons );
58
+ ?>
59
+ </p>
60
+ </div>
61
+ <script type="text/javascript">
62
+ jQuery(function ($) {
63
+ LearnPress.sortableQuestionAnswers($('#learn-press-question-<?php echo $this->id;?>'));
64
+ })
65
+ </script>
inc/admin/views/meta-boxes/question/none.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="learn-press-question" id="learn-press-question-<?php echo $this->id;?>" data-type="none" data-id="<?php echo $this->id;?>">
2
+ <?php _e( 'Please select a type for this question'); ?>
3
+
4
+ <p class="question-bottom-actions">
5
+ <?php
6
+ $buttons = apply_filters(
7
+ 'learn_press_question_bottom_buttons',
8
+ array(
9
+ 'change_type' => learn_press_dropdown_question_types(array('echo' => false, 'id' => 'learn-press-dropdown-question-types-' . $this->id, 'selected' => 'none' ))
10
+ ),
11
+ $this
12
+ );
13
+ echo join( "\n", $buttons );
14
+ ?>
15
+ </p>
16
+ </div>
inc/admin/views/meta-boxes/question/single-choice-options.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="learn-press-question" id="learn-press-question-<?php echo $this->id;?>" data-type="<?php echo str_replace( '_', '-', $this->type );?>" data-id="<?php echo $this->id;?>">
2
+ <table class="lp-sortable lp-list-options" id="learn-press-list-options-<?php echo $this->id;?>">
3
+ <thead>
4
+ <th><?php _e( 'Answer Text', 'learnpress' ); ?></th>
5
+ <th><?php _e( 'Is Correct?', 'learnpress' ); ?></th>
6
+ <th width="20"></th>
7
+ <?php if ( $this->type == 'single_choice' ): ?>
8
+ <th width="20"></th>
9
+ <?php endif;?>
10
+ </thead>
11
+ <tbody>
12
+
13
+ <?php $answers = $this->answers; if ( $answers ): ?>
14
+ <?php foreach ( $answers as $answer ): ?>
15
+ <?php
16
+ $value = $this->_get_option_value( $answer['value'] );
17
+ $id = $value;
18
+ ?>
19
+
20
+ <?php do_action( 'learn_press_before_question_answer_option', $this ); ?>
21
+
22
+ <tr class="lp-list-option lp-list-option-<?php echo $id;?>" data-id="<?php echo $id;?>">
23
+ <td>
24
+ <input class="lp-answer-text no-submit key-nav" type="text" name="learn_press_question[<?php echo $this->id; ?>][answer][text][]" value="<?php echo esc_attr( $answer['text'] ); ?>" />
25
+ </td>
26
+ <th class="lp-answer-check">
27
+ <input type="hidden" name="learn_press_question[<?php echo $this->id; ?>][answer][value][]" value="<?php echo $value; ?>" />
28
+ <input type="radio" name="learn_press_question[<?php echo $this->id; ?>][checked]" <?php checked( $answer['is_true'] == 'yes', true ); ?> value="<?php echo $value; ?>" />
29
+ </th>
30
+ <?php if ( $this->type == 'single_choice' ): ?>
31
+ <td class="lp-list-option-actions lp-remove-list-option">
32
+ <i class="dashicons dashicons-trash"></i>
33
+ </td>
34
+ <?php endif;?>
35
+ <td class="lp-list-option-actions lp-move-list-option open-hand">
36
+ <i class="dashicons dashicons-sort"></i>
37
+ </td>
38
+ </tr>
39
+
40
+ <?php do_action( 'learn_press_after_question_answer_option', $this ); ?>
41
+
42
+ <?php endforeach; ?>
43
+ <?php endif; ?>
44
+ </tbody>
45
+ </table>
46
+ <p class="question-bottom-actions">
47
+ <?php
48
+ $buttons = array(
49
+ 'change_type' => learn_press_dropdown_question_types(array('echo' => false, 'id' => 'learn-press-dropdown-question-types-' . $this->id, 'selected' => $this->type ))
50
+ );
51
+ if( $this->type != 'true_or_false' ){
52
+ array_splice($buttons, 0, 0, sprintf(
53
+ __( '<button class="button add-question-option-button add-question-option-button-%1$d" data-id="%1$d" type="button">%2$s</button>', 'learnpress' ),
54
+ $this->id,
55
+ __( 'Add Option', 'learnpress' )
56
+ )
57
+ );
58
+ }
59
+ $buttons = apply_filters(
60
+ 'learn_press_question_bottom_buttons',
61
+ $buttons,
62
+ $this
63
+ );
64
+ echo join( "\n", $buttons );
65
+ ?>
66
+ </p>
67
+ </div>
68
+ <script type="text/javascript">
69
+ jQuery(function ($) {
70
+ LearnPress.sortableQuestionAnswers($('#learn-press-question-<?php echo $this->id;?>'));
71
+ })
72
+ </script>
inc/admin/views/meta-boxes/quiz/js-template.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/html" id="tmpl-lp-modal-quiz-questions">
2
+ <div id="lp-modal-quiz-questions" class="lp-modal-search">
3
+ <div class="lp-search-items">
4
+ <input type="text" name="lp-item-name" placeholder="<?php _e( 'Type here to search the questions', 'learnpress' );?>" />
5
+ <!--<div class="button lp-button-dropdown lp-button-add-question">
6
+ <span class="lp-dropdown-label lp-add-new-item"><?php _e( 'Add New', 'learnpress' );?></span>
7
+ <span class="lp-dropdown-arrow">+</span>
8
+ <ul class="lp-dropdown-items">
9
+ <?php foreach( learn_press_question_types() as $slug => $name ){?>
10
+ <li>
11
+ <a href="" data-type="<?php echo $slug;?>"><?php echo $name;?></a>
12
+ </li>
13
+ <?php } ?>
14
+ </ul>
15
+ </div>-->
16
+ </div>
17
+ <ul class="lp-list-items">
18
+ <?php
19
+ $questions = learn_press_get_user_questions( null, array( 'posts_per_page' => 9999 ) );
20
+ if ( $questions ) {
21
+ foreach( $questions as $question ){
22
+ $hidden = '';//in_array( $questions->ID, $exclude_lessons ) ? 'selected hide-if-js' : '';
23
+
24
+ if( $question->post_title ){
25
+ $title = $question->post_title;
26
+ }else{
27
+ $title = __( '(Untitled)', 'learnpress' );
28
+ }
29
+ ?>
30
+ <li class="<?php echo $hidden;?>" data-id="<?php echo $question->ID;?>" data-type="<?php echo $question->post_type;?>" data-text="<?php echo esc_attr( $title );?>">
31
+ <label>
32
+ <input type="checkbox" value="<?php echo $question->ID;?>">
33
+ <span class="lp-item-text"><?php echo $title;?></span>
34
+ </label>
35
+ </li>
36
+ <?php
37
+ }
38
+ }
39
+ ?>
40
+ <li class="lp-search-no-results hide-if-js" data-id="0"><?php _e( 'No results', 'learnpress' );?></li>
41
+ </ul>
42
+ <button class="lp-add-item button" disabled="disabled" data-text="<?php _e( 'Add to quiz', 'learnpress' );?>"><?php _e( 'Add to quiz', 'learnpress' );?></button>
43
+ <button class="lp-close-lightbox button" onclick="LearnPress.MessageBox.hide();"><?php _e( 'Close', 'learnpress' );?></button>
44
+ </div>
45
+ </script>
inc/admin/views/meta-boxes/quiz/question.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ global $post;
3
+ if ( !isset( $hidden ) ) {
4
+ $hidden = array();
5
+ }
6
+ $is_hidden = $question->id && is_array( $hidden ) && in_array( $question->id, $hidden );
7
+ if ( empty ( $question->id ) ) {
8
+ ?>
9
+ <div class="quiz-question<?php echo $is_hidden ? ' is-hidden' : ''; ?>">
10
+ <div class="quiz-question-head">
11
+ <span class="quiz-question-icon">
12
+
13
+ </span>
14
+ <span><?php _e( 'Load question failed!', 'learnpress' ); ?></span>
15
+ </div>
16
+ </div>
17
+ <?php
18
+ return;
19
+ }
20
+ ?>
21
+ <div class="quiz-question<?php echo $is_hidden ? ' is-hidden' : ''; ?>">
22
+ <div class="quiz-question-head">
23
+ <span class="quiz-question-icon">
24
+ <?php echo $question->get_icon(); ?>
25
+ </span>
26
+ <input type="text" class="question-name" name="learn-press-question-name[<?php echo $question->id; ?>]" value="<?php echo esc_attr( $question->post->post_title ); ?>" />
27
+ <p class="quiz-question-actions lp-button-actions">
28
+ <a href="" data-action="expand" class="dashicons dashicons-plus <?php echo $is_hidden ? '' : 'hide-if-js'; ?>" title="<?php _e( 'Expand', 'learnpress' ); ?>"></a>
29
+ <a href="" data-action="collapse" class="dashicons dashicons-minus <?php echo !$is_hidden ? '' : 'hide-if-js'; ?>" title="<?php _e( 'Collapse', 'learnpress' ); ?>"></a>
30
+ <a href="<?php echo get_edit_post_link( $question->id ); ?>" class="dashicons dashicons-edit" data-action="" title="<?php _e( 'Edit', 'learnpress' ); ?>"></a>
31
+ <a href="<?php echo wp_nonce_url( admin_url( 'admin-ajax.php?action=learnpress_remove_quiz_question&quiz_id=' . $post->ID . '&question_id=' . $question->id ), 'remove_quiz_question', 'remove-nonce' ); ?>"
32
+ class="dashicons dashicons-trash"
33
+ data-action="remove"
34
+ data-confirm-remove="<?php _e( 'Are you sure you want to remove this question?', 'learnpress' ); ?>"
35
+ title="<?php _e( 'Remove', 'learnpress' ); ?>"></a>
36
+ <a href="" class="move"></a>
37
+ </p>
38
+ </div>
39
+ <div class="quiz-question-content<?php echo $is_hidden ? ' hide-if-js' : ''; ?>">
40
+ <?php $question && $question->admin_interface(); ?>
41
+ </div>
42
+ </div>
inc/admin/views/meta-boxes/quiz/questions.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ global $post;
3
+ $quiz = LP_Quiz::get_quiz( $post->ID );
4
+ $current_user = get_current_user_id();
5
+ $question_types = learn_press_question_types();
6
+ $exclude_ids = array();
7
+ $questions = $quiz->get_questions();
8
+ $hidden = (array) get_post_meta( $quiz->id, '_admin_hidden_questions', true );
9
+ $question_ids = $questions ? array_keys( $questions ) : array();
10
+
11
+ $hidden_all = sizeof( $hidden ) && ( sizeof( array_diff( $hidden, $question_ids ) ) == 0 );
12
+ ?>
13
+ <div id="learn-press-quiz-questions-wrap">
14
+ <h3 class="quiz-questions-heading">
15
+ <?php _e( 'Questions', 'learnpress' ); ?>
16
+ <p align="right" class="questions-toggle">
17
+ <a href="" data-action="expand" class="dashicons dashicons-plus <?php echo $hidden_all ? '' : ' hide-if-js';?>" title="<?php _e( 'Expand All', 'learnpress' ); ?>"></a>
18
+ <a href="" data-action="collapse" class="dashicons dashicons-minus <?php echo !$hidden_all ? '' : ' hide-if-js';?>" title="<?php _e( 'Collapse All', 'learnpress' ); ?>"></a>
19
+ </p>
20
+ </h3>
21
+
22
+ <div id="learn-press-list-questions">
23
+ <?php if ( $questions ): $index = 0; ?>
24
+ <?php foreach ( $questions as $question ): ?>
25
+ <?php
26
+ $question = LP_Question_Factory::get_question($question );
27
+ $question_view = learn_press_get_admin_view( 'meta-boxes/quiz/question.php' );
28
+ include $question_view;
29
+ ?>
30
+ <?php endforeach; ?>
31
+ <?php $exclude_ids = array_keys( $questions ); endif; ?>
32
+ </div>
33
+ <div class="question-actions">
34
+ <input type="text" class="regular-text no-submit" name="lp-new-question-name" placeholder="<?php _e( 'The name of new question and hit enter', 'learnpress' );?>" />
35
+ <div class="button lp-button-dropdown lp-button-add-question disabled">
36
+ <span class="lp-dropdown-label lp-add-new-item"><?php _e( 'Add New', 'learnpress' );?></span>
37
+ <span class="lp-dropdown-arrow">+</span>
38
+ <ul class="lp-dropdown-items">
39
+ <?php foreach( learn_press_question_types() as $slug => $name ){?>
40
+ <li>
41
+ <a href="" data-type="<?php echo $slug;?>"><?php echo $name;?></a>
42
+ </li>
43
+ <?php } ?>
44
+ </ul>
45
+ </div>
46
+ -OR-
47
+ <button id="learn-press-button-add-question" class="button" type="button"><?php _e( 'Add Existing Question', 'learnpress' ); ?></button>
48
+ </div>
49
+ </div>
50
+ <?php wp_reset_postdata();?>
inc/admin/views/settings/checkout.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Display settings for checkout
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
+ <table class="form-table">
17
+ <tbody>
18
+ <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $this ); ?>
19
+ <?php foreach( $this->get_settings() as $field ){?>
20
+ <?php $this->output_field( $field );?>
21
+ <?php }?>
22
+ <?php if( 1 == 0 ){?>
23
+ <tr>
24
+ <th scope="row"><label for="learn-press-checkout-enable-cart"><?php _e( 'Enable cart', 'learnpress' ); ?></label></th>
25
+ <td>
26
+ <input type="hidden" name="<?php echo $this->get_field_name( 'enable_cart' ); ?>" value="no" />
27
+ <input id="learn-press-checkout-enable-cart" type="checkbox" name="<?php echo $this->get_field_name( 'enable_cart' ); ?>" value="yes" <?php checked( $settings->get( 'enable_cart' ) == 'yes', true ); ?> />
28
+ <p class="description"><?php _e( 'Check this option to enable user can purchase multiple course at one time', 'learnpress' );?></p>
29
+ </td>
30
+ </tr>
31
+ <tr>
32
+ <th scope="row"><label for="learn-press-checkout-add-to-cart-redirect"><?php _e( 'Add to cart redirect', 'learnpress' ); ?></label></th>
33
+ <td>
34
+ <input type="hidden" name="<?php echo $this->get_field_name( 'redirect_after_add' ); ?>" value="no" />
35
+ <input id="learn-press-checkout-add-to-cart-redirect" type="checkbox" name="<?php echo $this->get_field_name( 'redirect_after_add' ); ?>" value="yes" <?php checked( $settings->get( 'redirect_after_add' ) == 'yes', true ); ?> />
36
+ <p class="description"><?php _e( 'Redirect to checkout immediately after add course to cart', 'learnpress' );?></p>
37
+ </td>
38
+ </tr>
39
+ <tr>
40
+ <th scope="row"><label for="learn-press-checkout-add-to-cart-ajax"><?php _e( 'AJAX add to cart', 'learnpress' ); ?></label></th>
41
+ <td>
42
+ <input type="hidden" name="<?php echo $this->get_field_name( 'ajax_add_to_cart' ); ?>" value="no" />
43
+ <input id="learn-press-checkout-add-to-cart-ajax" type="checkbox" name="<?php echo $this->get_field_name( 'ajax_add_to_cart' ); ?>" value="yes" <?php checked( $settings->get( 'ajax_add_to_cart' ) == 'yes', true ); ?> />
44
+ <p class="description"><?php _e( 'Using AJAX to add course to the cart', 'learnpress' );?></p>
45
+ </td>
46
+ </tr>
47
+ <tr>
48
+ <th scope="row"><label><?php _e( 'Cart page', 'learnpress' ); ?></label></th>
49
+ <td>
50
+ <?php
51
+ $cart_page_id = $settings->get( 'cart_page_id', 0 );
52
+ learn_press_pages_dropdown( $this->get_field_name( "cart_page_id" ), $cart_page_id );
53
+ ?>
54
+ </td>
55
+ </tr>
56
+ <tr>
57
+ <th scope="row"><label><?php _e( 'Checkout page', 'learnpress' ); ?></label></th>
58
+ <td>
59
+ <?php
60
+ $checkout_page_id = $settings->get( 'checkout_page_id', 0 );
61
+ learn_press_pages_dropdown( $this->get_field_name( "checkout_page_id" ), $checkout_page_id );
62
+ ?>
63
+ </td>
64
+ </tr>
65
+ <?php }?>
66
+ </tbody>
67
+
68
+ </table>
69
+ <?php if( 1 == 0 ){?>
70
+ <h3><?php _e( 'Checkout Endpoints', 'learnpress' );?></h3>
71
+ <table class="form-table">
72
+ <tbody>
73
+ <tr>
74
+ <th scope="row"><label><?php _e( 'Order received', 'learnpress' ); ?></label></th>
75
+ <td>
76
+ <input type="text" class="regular-text" name="<?php echo $this->get_field_name( 'checkout_endpoints[lp_order_received]' );?>" value="<?php echo $settings->get( 'checkout_endpoints.lp_order_received', 'lp-order-received' );?>" />
77
+ </td>
78
+ </tr>
79
+ <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $this ); ?>
80
+ </tbody>
81
+ </table>
82
+ <?php } ?>
inc/admin/views/settings/courses.php ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Display settings for course
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
+ $settings = LP_Settings::instance();
14
+ ?>
15
+ <h3 class=""><?php echo $this->section['title']; ?></h3>
16
+ <table class="form-table">
17
+ <tbody>
18
+ <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
19
+ <?php foreach( $this->get_settings() as $field ){?>
20
+ <?php $this->output_field( $field );?>
21
+ <?php }?>
22
+ <?php if( 1 == 0 ){?>
23
+ <tr>
24
+ <th scope="row"><label><?php _e( 'Courses Page', 'learnpress' ); ?></label></th>
25
+ <td>
26
+ <?php
27
+ learn_press_pages_dropdown( $this->get_field_name( "courses_page_id" ), $courses_page_id );
28
+ ?>
29
+ </td>
30
+ </tr>
31
+ <tr>
32
+ <th scope="row"><label><?php _e( 'Course category base', 'learnpress' ); ?></label></th>
33
+ <td>
34
+ <input type="text" class="regular-text" name="<?php echo $this->get_field_name( "course_category_base" ); ?>" value="<?php echo $settings->get( 'course_category_base' ); ?>" placeholder="<?php echo 'course-category'; ?>" />
35
+ </td>
36
+ </tr>
37
+ <tr>
38
+ <th scope="row"><label><?php _e( 'Course tag base', 'learnpress' ); ?></label></th>
39
+ <td>
40
+ <input type="text" class="regular-text" name="<?php echo $this->get_field_name( "course_tag_base" ); ?>" value="<?php echo $settings->get( 'course_tag_base' ); ?>" placeholder="<?php echo 'course-tag'; ?>" />
41
+ </td>
42
+ </tr>
43
+ <tr>
44
+ <th scope="row"><label><?php _e( 'Review course before publish', 'learnpress' ); ?></label></th>
45
+ <td>
46
+ <input type="hidden" name="<?php echo $this->get_field_name( "required_review" ); ?>" value="no" />
47
+ <input type="checkbox" name="<?php echo $this->get_field_name( "required_review" ); ?>" value="yes" <?php checked( $settings->get( 'required_review' ) == 'yes' );?> />
48
+ <p class="description">
49
+ <?php _e( 'The course need to review by admin before it can be published', 'learnpress' );?>
50
+ </p>
51
+ </td>
52
+ </tr>
53
+ <tr>
54
+ <th scope="row"><label><?php _e( 'Enable edit published course', 'learnpress' ); ?></label></th>
55
+ <td>
56
+ <input type="hidden" name="<?php echo $this->get_field_name( "enable_edit_published" ); ?>" value="no" />
57
+ <input type="checkbox" name="<?php echo $this->get_field_name( "enable_edit_published" ); ?>" value="yes" <?php checked( $settings->get( 'enable_edit_published' ) == 'yes' );?> />
58
+ <p class="description">
59
+ <?php _e( 'Allows instructor edit the course that published without review.<br /> If this option is disabled, the course status will be changed to Pending Review when the instructor update course', 'learnpress' );?>
60
+ </p>
61
+ </td>
62
+ </tr>
63
+ <!-- thumbnail -->
64
+ <tr>
65
+ <th colspan="2">
66
+ <h3><?php _e( 'Course images', 'learnpress' );?></h3>
67
+ </th>
68
+ </tr>
69
+ <tr>
70
+ <th scope="row"><label><?php _e( 'Single course', 'learnpress' ); ?></label></th>
71
+ <td>
72
+ <input type="text" size="4" name="<?php echo $this->get_field_name( "single_course_image_size[width]" ); ?>" value="<?php echo $settings->get( 'single_course_image_size.width' ); ?>" placeholder="" />
73
+ &times;
74
+ <input type="text" size="4" name="<?php echo $this->get_field_name( "single_course_image_size[height]" ); ?>" value="<?php echo $settings->get( 'single_course_image_size.height' ); ?>" placeholder="" />
75
+ <?php _e( 'px', 'learnpress' );?>
76
+ &nbsp;&nbsp;&nbsp;
77
+ <input type="hidden" name="<?php echo $this->get_field_name( "single_course_image_size[crop]" ); ?>" value="no" />
78
+ <label>
79
+ <input type="checkbox" name="<?php echo $this->get_field_name( "single_course_image_size[crop]" ); ?>" value="yes" <?php checked( $settings->get( 'single_course_image_size.crop' ) == 'yes' ); ?>" />
80
+ <?php _e( 'Crop?', 'learn_pres' );?>
81
+ </label>
82
+ </td>
83
+ </tr>
84
+ <tr>
85
+ <th scope="row"><label><?php _e( 'Course thumbnail', 'learnpress' ); ?></label></th>
86
+ <td>
87
+ <input type="text" size="4" name="<?php echo $this->get_field_name( "course_thumbnail_image_size[width]" ); ?>" value="<?php echo $settings->get( 'course_thumbnail_image_size.width' ); ?>" placeholder="" />
88
+ &times;
89
+ <input type="text" size="4" name="<?php echo $this->get_field_name( "course_thumbnail_image_size[height]" ); ?>" value="<?php echo $settings->get( 'course_thumbnail_image_size.height' ); ?>" placeholder="" />
90
+ <?php _e( 'px', 'learnpress' );?>
91
+ &nbsp;&nbsp;&nbsp;
92
+ <input type="hidden" name="<?php echo $this->get_field_name( "course_thumbnail_image_size[crop]" ); ?>" value="no" />
93
+ <label>
94
+ <input type="checkbox" name="<?php echo $this->get_field_name( "course_thumbnail_image_size[crop]" ); ?>" value="yes" <?php checked( $settings->get( 'course_thumbnail_image_size.crop' ) == 'yes' ); ?>" />
95
+ <?php _e( 'Crop?', 'learn_pres' );?>
96
+ </label>
97
+ </td>
98
+ </tr>
99
+ <!-- permalink -->
100
+ <tr>
101
+ <th colspan="2">
102
+ <h3><?php _e( 'Single course permalink', 'learnpress' );?></h3>
103
+ </th>
104
+ </tr>
105
+ <?php foreach( $structures as $k => $structure ): ?>
106
+ <tr<?php if( $k == 2 || $k == 3 ){ echo ' class="learn-press-courses-page-id'; echo !$courses_page_id ? ' hide-if-js"' : '""'; };?> >
107
+ <th>
108
+ <?php
109
+ $is_checked = checked( ( $course_permalink == '' && $structure['value'] == '' ) || ( $structure['value'] == trailingslashit( $course_permalink ) ), true, false );
110
+ if( $is_custom && $is_checked ) {
111
+ $is_custom = false;
112
+ }
113
+ ?>
114
+ <label>
115
+ <input name="<?php echo $this->get_field_name( "course_base" ); ?>" type="radio" value="<?php echo esc_attr( $structure['value'] ); ?>" class="learn-press-course-base" <?php echo $is_checked; ?> />
116
+ <?php echo $structure['text']; ?>
117
+ </label>
118
+ </th>
119
+ <td>
120
+ <code><?php echo $structure['code'];?></code>
121
+ </td>
122
+ </tr>
123
+ <?php endforeach; ?>
124
+ <tr>
125
+ <th>
126
+ <label>
127
+ <input name="<?php echo $this->get_field_name( "course_base" ); ?>" id="learn_press_custom_permalink" type="radio" value="custom" <?php checked( $is_custom, true ); ?> />
128
+ <?php _e( 'Custom Base', 'learnpress' ); ?>
129
+ </label>
130
+ </th>
131
+ <td>
132
+ <input name="course_permalink_structure" id="course_permalink_structure" type="text" value="<?php echo esc_attr( $course_permalink ); ?>" class="regular-text code" />
133
+ <p class="description"><?php _e( 'Enter a custom base to use. A base <strong>must</strong> be set or WordPress will use default instead.', 'learnpress' ); ?></p>
134
+ </td>
135
+ </tr>
136
+ <?php }?>
137
+ <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
138
+ </tbody>
139
+ </table>
140
+ <script type="text/javascript">
141
+ jQuery( function($) {
142
+ $('input.learn-press-course-base').change(function() {
143
+ $('#course_permalink_structure').val( $( this ).val() );
144
+ });
145
+
146
+ $('#course_permalink_structure').focus( function(){
147
+ $('#learn_press_custom_permalink').click();
148
+ } );
149
+
150
+ $('#learn_press_courses_page_id').change(function(){
151
+ $('tr.learn-press-courses-page-id').toggleClass( 'hide-if-js', !parseInt( this.value ) )
152
+ });
153
+ } );
154
+ </script>
inc/admin/views/settings/emails/become-a-teacher-request.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ $default_subject = 'Request to become a teacher';
16
+ $default_message = '<strong>Dear Administrator</strong>,
17
+
18
+ <p>An user want to be a teacher and has requested. Below is the information about requester</p>
19
+ ';
20
+ ?>
21
+ <table class="form-table">
22
+ <tbody>
23
+ <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
24
+ <tr>
25
+ <th scope="row"><label for="lpr_email_enable"><?php _e( 'Enable', 'learnpress' ); ?></label></th>
26
+ <td>
27
+ <input id="lpr_email_enable" type="checkbox" name="lpr_settings[<?php echo $this->id; ?>][enable]" value="1" <?php checked( $settings->get( 'become_a_teacher_request.enable' ), 1 ); ?> />
28
+
29
+ <p class="description"><?php _e( 'Send notification when a user want to be a teacher', 'learnpress' ); ?></p>
30
+ </td>
31
+ </tr>
32
+ <tr>
33
+ <th scope="row"><label for="lpr_email_subject"><?php _e( 'Subject', 'learnpress' ); ?></label></th>
34
+ <td>
35
+ <input id="lpr_email_subject" class="regular-text" type="text" name="lpr_settings[<?php echo $this->id; ?>][subject]" value="<?php echo $settings->get( 'become_a_teacher_request.subject', $default_subject ); ?>" />
36
+
37
+ <p class="description"><?php _e( 'Email subject', 'learnpress' ); ?></p>
38
+ </td>
39
+ </tr>
40
+ <tr>
41
+ <th scope="row"><label><?php _e( 'Message', 'learnpress' ); ?></label></th>
42
+ <td>
43
+ <?php $this->message_editor( $default_message ); ?>
44
+ </td>
45
+ </tr>
46
+ <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
47
+ </tbody>
48
+ </table>
inc/admin/views/settings/emails/email-template.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <tr>
2
+ <th scope="row">
3
+ <label for="learn-press-emails-new-course-email-content"><?php _e( 'Email content', 'learnpress' ); ?></label>
4
+ </th>
5
+ <td>
6
+ <?php if ( current_user_can( 'edit_themes' ) && ( !empty( $this->template_html ) || !empty( $this->template_plain ) ) ) { ?>
7
+ <div id="templates">
8
+ <?php
9
+ $templates = array(
10
+ 'html' => __( 'HTML template', 'learnpress' ),
11
+ 'plain' => __( 'Plain text template', 'learnpress' )
12
+ );
13
+
14
+ foreach ( $templates as $template_type => $title ) :
15
+ $template = $this->get_template( 'template_' . $template_type );
16
+
17
+ if ( empty( $template ) ) {
18
+ continue;
19
+ }
20
+
21
+ $local_file = $this->get_theme_template_file( $template );
22
+ $template_file = $this->template_base . $template;
23
+ $template_dir = learn_press_template_path();
24
+ ?>
25
+ <div class="template <?php echo $template_type == 'html' ? $template_type . ' multipart' : 'plain_text'; ?>" style="display: none;">
26
+
27
+ <?php if ( file_exists( $local_file ) ) { ?>
28
+ <?php if( $template_type == 'plain' ){ ?>
29
+ <div class="editor">
30
+ <textarea name="<?php echo $settings_class->get_field_name( 'emails_' . $this->id . '[email_content_plain]' );?>" class="code" cols="25" rows="20" style="width: 97%;"><?php echo file_get_contents( $local_file ); ?></textarea>
31
+ </div>
32
+ <?php } else { ?>
33
+ <?php
34
+ wp_editor(
35
+ stripslashes( file_get_contents( $local_file ) ),
36
+ 'learn_press_email_content_' . $template_type,
37
+ array(
38
+ 'textarea_rows' => 20,
39
+ 'wpautop' => false,
40
+ 'textarea_name' => $settings_class->get_field_name( 'emails_' . $this->id . '[email_content_html]' )
41
+ )
42
+ );
43
+ ?>
44
+ <?php } ?>
45
+ <h4><?php echo wp_kses_post( $title ); ?></h4>
46
+
47
+ <p class="description">
48
+ <?php printf( __( 'This template has been overridden by your theme and can be found in: <code>%s</code>.', 'learnpress' ), 'yourtheme/' . $template_dir . '/' . $template ); ?>
49
+ </p>
50
+ <p>
51
+ <?php if ( is_writable( $local_file ) ) : ?>
52
+ <a href="<?php echo esc_url( wp_nonce_url( remove_query_arg( array( 'move_template', 'saved' ), add_query_arg( 'delete_template', $template_type ) ), 'learn_press_email_template_nonce', '_learn_press_email_nonce' ) ); ?>" class="delete_template button">
53
+ <?php _e( 'Delete template file', 'learnpress' ); ?>
54
+ </a>
55
+ <?php endif; ?>
56
+ </p>
57
+ <?php } elseif ( file_exists( $template_file ) ) { ?>
58
+ <div class="editor">
59
+ <textarea class="code" readonly="readonly" disabled="disabled" cols="25" rows="20" style="width: 97%;"><?php echo file_get_contents( $template_file ); ?></textarea>
60
+ </div>
61
+ <h4><?php echo wp_kses_post( $title ); ?></h4>
62
+ <p class="description">
63
+ <?php printf( __( 'To override and edit this email template copy <code>%s</code> to your theme folder: <code>%s</code>.', 'learnpress' ), plugin_basename( $template_file ), 'yourtheme/' . $template_dir . '/' . $template ); ?>
64
+ </p>
65
+ <p>
66
+ <?php if ( ( is_dir( get_stylesheet_directory() . '/' . $template_dir . '/emails/' ) && is_writable( get_stylesheet_directory() . '/' . $template_dir . '/emails/' ) ) || is_writable( get_stylesheet_directory() ) ) { ?>
67
+ <a href="<?php echo esc_url( wp_nonce_url( remove_query_arg( array( 'delete_template', 'saved' ), add_query_arg( 'move_template', $template_type ) ), 'learn_press_email_template_nonce', '_learn_press_email_nonce' ) ); ?>" class="button">
68
+ <?php _e( 'Copy file to theme', 'learnpress' ); ?>
69
+ </a>
70
+ <?php } ?>
71
+ </p>
72
+ <?php } else { ?>
73
+
74
+ <p><?php _e( 'File was not found.', 'learnpress' ); ?></p>
75
+
76
+ <?php } ?>
77
+ </div>
78
+ <?php
79
+ endforeach;
80
+ ?>
81
+ </div>
82
+ <?php } ?>
83
+ </td>
84
+ </tr>
85
+ <?php ob_start();?>
86
+ <script>
87
+ jQuery(function($){
88
+ $('#learn_press_email_formats').change(function(){
89
+ var format = $(this).val();
90
+ $('.'+format).show().siblings().hide();
91
+ }).change();
92
+ });
93
+ </script>
94
+ <?php learn_press_enqueue_script( preg_replace( '!</?script>!', '', ob_get_clean() ) );?>
inc/admin/views/settings/emails/enrolled-course.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
16
+ <table class="form-table">
17
+ <tbody>
18
+ <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
19
+ <tr>
20
+ <th scope="row">
21
+ <label for="learn-press-emails-enrolled-course-enable"><?php _e( 'Enable', 'learnpress' ); ?></label></th>
22
+ <td>
23
+ <input type="hidden" name="<?php echo $settings_class->get_field_name( 'emails_enrolled_course[enable]' ); ?>" value="no" />
24
+ <input id="learn-press-emails-enrolled-course-enable" type="checkbox" name="<?php echo $settings_class->get_field_name( 'emails_enrolled_course[enable]' ); ?>" value="yes" <?php checked( $settings->get( 'emails_enrolled_course.enable', 'yes' ) == 'yes' ); ?>" />
25
+ </td>
26
+ </tr>
27
+ <tr>
28
+ <th scope="row">
29
+ <label for="learn-press-emails-enrolled-course-subject"><?php _e( 'Subject', 'learnpress' ); ?></label></th>
30
+ <td>
31
+ <input id="learn-press-emails-enrolled-course-subject" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_enrolled_course[subject]' ); ?>" value="<?php echo $settings->get( 'emails_enrolled_course.subject', $this->default_subject ); ?>" />
32
+
33
+ <p class="description">
34
+ <?php printf( __( 'Email subject , default: <code>%s</code>', 'learnpress' ), $this->default_subject ); ?>
35
+ </p>
36
+ </td>
37
+ </tr>
38
+ <tr>
39
+ <th scope="row">
40
+ <label for="learn-press-emails-enrolled-course-heading"><?php _e( 'Heading', 'learnpress' ); ?></label></th>
41
+ <td>
42
+ <input id="learn-press-emails-enrolled-course-heading" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_enrolled_course[heading]' ); ?>" value="<?php echo $settings->get( 'emails_enrolled_course.heading', $this->default_heading ); ?>" />
43
+
44
+ <p class="description">
45
+ <?php printf( __( 'Email heading, default: <code>%s</code>', 'learnpress' ), $this->default_heading ); ?>
46
+ </p>
47
+ </td>
48
+ </tr>
49
+ <tr>
50
+ <th scope="row">
51
+ <label for="learn-press-emails-enrolled-course-email-format"><?php _e( 'Email format', 'learnpress' ); ?></label>
52
+ </th>
53
+ <td>
54
+ <?php learn_press_email_formats_dropdown( array( 'name' => $settings_class->get_field_name( 'emails_enrolled_course[email_format]' ), 'id' => 'learn_press_email_formats', 'selected' => $settings->get( 'emails_enrolled_course.email_format' ) ) ); ?>
55
+ </td>
56
+ </tr>
57
+ <?php
58
+ $view = learn_press_get_admin_view( 'settings/emails/email-template.php' );
59
+ include_once $view;
60
+ ?>
61
+ <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
62
+ </tbody>
63
+ </table>
inc/admin/views/settings/emails/finished-course.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
16
+ <table class="form-table">
17
+ <tbody>
18
+ <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
19
+ <tr>
20
+ <th scope="row">
21
+ <label for="learn-press-emails-finished-course-enable"><?php _e( 'Enable', 'learnpress' ); ?></label></th>
22
+ <td>
23
+ <input type="hidden" name="<?php echo $settings_class->get_field_name( 'emails_finished_course[enable]' ); ?>" value="no" />
24
+ <input id="learn-press-emails-finished-course-enable" type="checkbox" name="<?php echo $settings_class->get_field_name( 'emails_finished_course[enable]' ); ?>" value="yes" <?php checked( $settings->get( 'emails_finished_course.enable', 'yes' ) == 'yes' ); ?>" />
25
+ </td>
26
+ </tr>
27
+ <tr>
28
+ <th scope="row">
29
+ <label for="learn-press-emails-finished-course-subject"><?php _e( 'Subject', 'learnpress' ); ?></label></th>
30
+ <td>
31
+ <input id="learn-press-emails-finished-course-subject" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_finished_course[subject]' ); ?>" value="<?php echo $settings->get( 'emails_finished_course.subject', $this->default_subject ); ?>" />
32
+
33
+ <p class="description">
34
+ <?php printf( __( 'Email subject, default: <code>%s</code>', 'learnpress' ), $this->default_subject ); ?>
35
+ </p>
36
+ </td>
37
+ </tr>
38
+ <tr>
39
+ <th scope="row">
40
+ <label for="learn-press-emails-finished-course-heading"><?php _e( 'Heading', 'learnpress' ); ?></label></th>
41
+ <td>
42
+ <input id="learn-press-emails-finished-course-heading" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_finished_course[heading]' ); ?>" value="<?php echo $settings->get( 'emails_finished_course.heading', $this->default_heading ); ?>" />
43
+
44
+ <p class="description">
45
+ <?php printf( __( 'Email heading, default: <code>%s</code>', 'learnpress' ), $this->default_heading ); ?>
46
+ </p>
47
+ </td>
48
+ </tr>
49
+ <tr>
50
+ <th scope="row">
51
+ <label for="learn-press-emails-finished-course-email-format"><?php _e( 'Email format', 'learnpress' ); ?></label>
52
+ </th>
53
+ <td>
54
+ <?php learn_press_email_formats_dropdown( array( 'name' => $settings_class->get_field_name( 'emails_finished_course[email_format]' ), 'id' => 'learn_press_email_formats', 'selected' => $settings->get( 'emails_finished_course.email_format' ) ) ); ?>
55
+ </td>
56
+ </tr>
57
+ <?php
58
+ $view = learn_press_get_admin_view( 'settings/emails/email-template.php' );
59
+ include_once $view;
60
+ ?>
61
+ <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
62
+ </tbody>
63
+ </table>
inc/admin/views/settings/emails/general.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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( 'Email Options', 'learnpress' ); ?></h3>
16
+ <p class="description">
17
+ <?php _e( 'The following options affect the sender (email address and name) used in LearnPress emails.', '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"><label for="learn-press-emails-general-from-name"><?php _e( 'From Name', 'learnpress' ); ?></label></th>
24
+ <td>
25
+ <input class="regular-text" id="learn-press-emails-general-from-name" type="text" name="<?php echo $this->get_field_name('emails_general[from_name]');?>" value="<?php echo $settings->get( 'emails_general.from_name', get_option( 'blogname' ) ); ?>" />
26
+ </td>
27
+ </tr>
28
+ <tr>
29
+ <th scope="row"><label for="learn-press-emails-general-from-email"><?php _e( 'From Email', 'learnpress' ); ?></label></th>
30
+ <td>
31
+ <input id="learn-press-emails-general-from-email" class="regular-text" type="email" name="<?php echo $this->get_field_name( 'emails_general[from_email]');?>" value="<?php echo $settings->get( 'emails_general.from_email', get_option( 'admin_email' ) ); ?>" />
32
+ </td>
33
+ </tr>
34
+ <tr>
35
+ <th scope="row" colspan="2">
36
+ <h3><?php _e( 'Email Template', 'learnpress' );?></h3>
37
+ </th>
38
+ </tr>
39
+ <tr>
40
+ <th scope="row"><label for="learn-press-emails-general-header-image"><?php _e( 'Header image', 'learnpress' ); ?></label></th>
41
+ <td>
42
+ <input id="learn-press-emails-general-header-image" class="regular-text" type="text" name="<?php echo $this->get_field_name( 'emails_general[header_image]');?>" value="<?php echo $settings->get( 'emails_general.header_image' ); ?>" />
43
+ <p class="description"><?php _e( 'The image display in the top of email', 'learnpress' );?></p>
44
+ </td>
45
+ </tr>
46
+ <tr>
47
+ <th scope="row"><label for="learn-press-emails-general-footer-text"><?php _e( 'Footer text', 'learnpress' ); ?></label></th>
48
+ <td>
49
+ <textarea id="learn-press-emails-general-footer-text" name="<?php echo $this->get_field_name( 'emails_general[footer_text]');?>" style="height: 100px; width: 100%;"><?php echo $settings->get( 'emails_general.footer_text' ); ?></textarea>
50
+ <p class="description"><?php _e( 'The text display in the bottom of email', 'learnpress' );?></p>
51
+ </td>
52
+ </tr>
53
+ <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
54
+ </tbody>
55
+ </table>
inc/admin/views/settings/emails/new-course.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_class = $obj;
14
+ $settings = LP()->settings;
15
+ ?>
16
+ <h3><?php _e( 'New course for review', 'learnpress' ); ?></h3>
17
+ <p class="description">
18
+ <?php _e( 'Settings for email when a new course submit for review', 'learnpress' ); ?>
19
+ </p>
20
+ <table class="form-table">
21
+ <tbody>
22
+ <?php do_action( 'learn_press_before_' . $settings_class->id . '_' . $settings_class->section['id'] . '_settings_fields', $settings ); ?>
23
+ <tr>
24
+ <th scope="row">
25
+ <label for="learn-press-emails-new-course-enable"><?php _e( 'Enable', 'learnpress' ); ?></label></th>
26
+ <td>
27
+ <input type="hidden" name="<?php echo $settings_class->get_field_name( 'emails_new_course[enable]' ); ?>" value="no" />
28
+ <input id="learn-press-emails-new-course-enable" type="checkbox" name="<?php echo $settings_class->get_field_name( 'emails_new_course[enable]' ); ?>" value="yes" <?php checked( $settings->get( 'emails_new_course.enable', 'yes' ) == 'yes' ); ?>" />
29
+ </td>
30
+ </tr>
31
+ <tr>
32
+ <th scope="row">
33
+ <label for="learn-press-emails-new-course-recipients"><?php _e( 'Recipient(s)', 'learnpress' ); ?></label>
34
+ </th>
35
+ <td>
36
+ <?php $default = get_option( 'admin_email' ); ?>
37
+ <input id="learn-press-emails-new-course-recipients" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_new_course[recipient]' ); ?>" value="<?php echo $settings->get( 'emails_new_course.recipient', $default ); ?>" />
38
+
39
+ <p class="description">
40
+ <?php printf( __( 'Email recipient(s), default: <code>%s</code>', 'learnpress' ), $default ); ?>
41
+ </p>
42
+ </td>
43
+ </tr>
44
+ <tr>
45
+ <th scope="row">
46
+ <label for="learn-press-emails-new-course-subject"><?php _e( 'Subject', 'learnpress' ); ?></label></th>
47
+ <td>
48
+ <input id="learn-press-emails-new-course-subject" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_new_course[subject]' ); ?>" value="<?php echo $settings->get( 'emails_new_course.subject', $this->default_subject ); ?>" />
49
+
50
+ <p class="description">
51
+ <?php printf( __( 'Email subject (separated by comma), default: <code>%s</code>', 'learnpress' ), $this->default_subject ); ?>
52
+ </p>
53
+ </td>
54
+ </tr>
55
+ <tr>
56
+ <th scope="row">
57
+ <label for="learn-press-emails-new-course-heading"><?php _e( 'Heading', 'learnpress' ); ?></label></th>
58
+ <td>
59
+ <?php $default = __( 'New course', 'learnpress' ); ?>
60
+ <input id="learn-press-emails-new-course-heading" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_new_course[heading]' ); ?>" value="<?php echo $settings->get( 'emails_new_course.heading', $this->default_heading ); ?>" />
61
+
62
+ <p class="description">
63
+ <?php printf( __( 'Email subject, default: <code>%s</code>', 'learnpress' ), $this->default_heading ); ?>
64
+ </p>
65
+ </td>
66
+ </tr>
67
+ <tr>
68
+ <th scope="row">
69
+ <label for="learn-press-emails-new-course-email-format"><?php _e( 'Email format', 'learnpress' ); ?></label>
70
+ </th>
71
+ <td>
72
+ <?php learn_press_email_formats_dropdown( array( 'name' => $settings_class->get_field_name( 'emails_new_course[email_format]' ), 'id' => 'learn_press_email_formats', 'selected' => $settings->get( 'emails_new_course.email_format' ) ) ); ?>
73
+ </td>
74
+ </tr>
75
+ <?php
76
+ $view = learn_press_get_admin_view( 'settings/emails/email-template.php' );
77
+ include_once $view;
78
+ ?>
79
+ <?php do_action( 'learn_press_after_' . $settings_class->id . '_' . $settings_class->section['id'] . '_settings_fields', $settings ); ?>
80
+ </tbody>
81
+ </table>
inc/admin/views/settings/emails/new-order.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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( 'New order', 'learnpress' ); ?></h3>
16
+ <p class="description">
17
+ <?php _e( 'Settings for email when a new order placed', '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_new_order[enable]' ); ?>" value="no" />
27
+ <input id="learn-press-emails-new-order-enable" type="checkbox" name="<?php echo $settings_class->get_field_name( 'emails_new_order[enable]' ); ?>" value="yes" <?php checked( $settings->get( 'emails_new_order.enable', 'yes' ) == 'yes' ); ?>" />
28
+ </td>
29
+ </tr>
30
+ <tr>
31
+ <th scope="row">
32
+ <label for="learn-press-emails-new-order-recipients"><?php _e( 'Recipient(s)', 'learnpress' ); ?></label>
33
+ </th>
34
+ <td>
35
+ <?php $default = get_option( 'admin_email' ); ?>
36
+ <input id="learn-press-emails-new-order-recipients" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_new_order[recipients]' ); ?>" value="<?php echo $settings->get( 'emails_new_order.recipients', $default ); ?>" />
37
+
38
+ <p class="description">
39
+ <?php printf( __( 'Email recipient(s), default: <code>%s</code>', 'learnpress' ), $default ); ?>
40
+ </p>
41
+ </td>
42
+ </tr>
43
+ <tr>
44
+ <th scope="row">
45
+ <label for="learn-press-emails-new-order-subject"><?php _e( 'Subject', 'learnpress' ); ?></label></th>
46
+ <td>
47
+ <?php $default = __( '[{site_title}] New course for review ({course_name}) - {course_date}', 'learnpress' ); ?>
48
+ <input id="learn-press-emails-new-order-subject" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_new_order[subject]' ); ?>" value="<?php echo $settings->get( 'emails_new_order.subject', $default ); ?>" />
49
+
50
+ <p class="description">
51
+ <?php printf( __( 'Email subject (separated by comma), default: <code>%s</code>', 'learnpress' ), $default ); ?>
52
+ </p>
53
+ </td>
54
+ </tr>
55
+ <tr>
56
+ <th scope="row">
57
+ <label for="learn-press-emails-new-order-heading"><?php _e( 'Heading', 'learnpress' ); ?></label></th>
58
+ <td>
59
+ <?php $default = __( 'New course', 'learnpress' ); ?>
60
+ <input id="learn-press-emails-new-order-heading" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_new_order[heading]' ); ?>" value="<?php echo $settings->get( 'emails_new_order.heading', $default ); ?>" />
61
+
62
+ <p class="description">
63
+ <?php printf( __( 'Email subject, default: <code>%s</code>', 'learnpress' ), $default ); ?>
64
+ </p>
65
+ </td>
66
+ </tr>
67
+ <tr>
68
+ <th scope="row">
69
+ <label for="learn-press-emails-new-order-email-format"><?php _e( 'Email format', 'learnpress' ); ?></label>
70
+ </th>
71
+ <td>
72
+ <?php learn_press_email_formats_dropdown( array( 'name' => $settings_class->get_field_name( 'emails_new_order[email_format]' ), 'id' => 'learn_press_email_formats', 'selected' => $settings->get( 'emails_new_order.email_format', $default ) ) ); ?>
73
+ </td>
74
+ </tr>
75
+ <?php
76
+ $view = learn_press_get_admin_view( 'settings/emails/email-template.php' );
77
+ include_once $view;
78
+ ?>
79
+ <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
80
+ </tbody>
81
+ </table>
inc/admin/views/settings/emails/published-course.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 echo $this->title;?></h3>
16
+ <table class="form-table">
17
+ <tbody>
18
+ <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
19
+ <tr>
20
+ <th scope="row">
21
+ <label for="learn-press-emails-published-course-enable"><?php _e( 'Enable', 'learnpress' ); ?></label></th>
22
+ <td>
23
+ <input type="hidden" name="<?php echo $settings_class->get_field_name( 'emails_published_course[enable]' ); ?>" value="no" />
24
+ <input id="learn-press-emails-published-course-enable" type="checkbox" name="<?php echo $settings_class->get_field_name( 'emails_published_course[enable]' ); ?>" value="yes" <?php checked( $settings->get( 'emails_published_course.enable', 'yes' ) == 'yes' ); ?>" />
25
+ </td>
26
+ </tr>
27
+ <tr>
28
+ <th scope="row">
29
+ <label for="learn-press-emails-published-course-subject"><?php _e( 'Subject', 'learnpress' ); ?></label></th>
30
+ <td>
31
+ <input id="learn-press-emails-published-course-subject" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_published_course[subject]' ); ?>" value="<?php echo $settings->get( 'emails_published_course.subject', $this->default_subject ); ?>" />
32
+
33
+ <p class="description">
34
+ <?php printf( __( 'Email subject, default: <code>%s</code>', 'learnpress' ), $this->default_subject ); ?>
35
+ </p>
36
+ </td>
37
+ </tr>
38
+ <tr>
39
+ <th scope="row">
40
+ <label for="learn-press-emails-published-course-heading"><?php _e( 'Heading', 'learnpress' ); ?></label></th>
41
+ <td>
42
+ <input id="learn-press-emails-published-course-heading" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_published_course[heading]' ); ?>" value="<?php echo $settings->get( 'emails_published_course.heading', $this->default_heading ); ?>" />
43
+
44
+ <p class="description">
45
+ <?php printf( __( 'Email heading, default: <code>%s</code>', 'learnpress' ), $this->default_heading ); ?>
46
+ </p>
47
+ </td>
48
+ </tr>
49
+ <tr>
50
+ <th scope="row">
51
+ <label for="learn-press-emails-published-course-email-format"><?php _e( 'Email format', 'learnpress' ); ?></label>
52
+ </th>
53
+ <td>
54
+ <?php learn_press_email_formats_dropdown( array( 'name' => $settings_class->get_field_name( 'emails_published_course[email_format]' ), 'id' => 'learn_press_email_formats', 'selected' => $settings->get( 'emails_published_course.email_format' ) ) ); ?>
55
+ </td>
56
+ </tr>
57
+ <?php
58
+ $view = learn_press_get_admin_view( 'settings/emails/email-template.php' );
59
+ include_once $view;
60
+ ?>
61
+ <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
62
+ </tbody>
63
+ </table>
inc/admin/views/settings/emails/rejected-course.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_class = $obj;
14
+ $settings = LP()->settings;
15
+ ?>
16
+ <h3><?php echo $this->title; ?></h3>
17
+ <p class="description">
18
+ <?php _e( 'Settings for email when a course is rejected', 'learnpress' ); ?>
19
+ </p>
20
+ <table class="form-table">
21
+ <tbody>
22
+ <?php do_action( 'learn_press_before_' . $settings_class->id . '_' . $settings_class->section['id'] . '_settings_fields', $settings ); ?>
23
+ <tr>
24
+ <th scope="row">
25
+ <label for="learn-press-emails-rejected-course-enable"><?php _e( 'Enable', 'learnpress' ); ?></label></th>
26
+ <td>
27
+ <input type="hidden" name="<?php echo $settings_class->get_field_name( 'emails_rejected_course[enable]' ); ?>" value="no" />
28
+ <input id="learn-press-emails-rejected-course-enable" type="checkbox" name="<?php echo $settings_class->get_field_name( 'emails_rejected_course[enable]' ); ?>" value="yes" <?php checked( $settings->get( 'emails_rejected_course.enable', 'yes' ) == 'yes' ); ?>" />
29
+ </td>
30
+ </tr>
31
+ <tr>
32
+ <th scope="row">
33
+ <label for="learn-press-emails-rejected-course-subject"><?php _e( 'Subject', 'learnpress' ); ?></label></th>
34
+ <td>
35
+ <input id="learn-press-emails-rejected-course-subject" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_rejected_course[subject]' ); ?>" value="<?php echo esc_attr( $settings->get( 'emails_rejected_course.subject', $this->default_subject ) ); ?>" />
36
+
37
+ <p class="description">
38
+ <?php printf( __( 'Email subject, default: <code>%s</code>', 'learnpress' ), $this->default_subject ); ?>
39
+ </p>
40
+ </td>
41
+ </tr>
42
+ <tr>
43
+ <th scope="row">
44
+ <label for="learn-press-emails-rejected-course-heading"><?php _e( 'Heading', 'learnpress' ); ?></label></th>
45
+ <td>
46
+ <input id="learn-press-emails-rejected-course-heading" class="regular-text" type="text" name="<?php echo $settings_class->get_field_name( 'emails_rejected_course[heading]' ); ?>" value="<?php echo esc_attr( $settings->get( 'emails_rejected_course.heading', $this->default_heading ) ); ?>" />
47
+
48
+ <p class="description">
49
+ <?php printf( __( 'Email heading, default: <code>%s</code>', 'learnpress' ), $this->default_heading ); ?>
50
+ </p>
51
+ </td>
52
+ </tr>
53
+ <tr>
54
+ <th scope="row">
55
+ <label for="learn-press-emails-rejected-course-email-format"><?php _e( 'Email format', 'learnpress' ); ?></label>
56
+ </th>
57
+ <td>
58
+ <?php learn_press_email_formats_dropdown( array( 'name' => $settings_class->get_field_name( 'emails_rejected_course[email_format]' ), 'id' => 'learn_press_email_formats', 'selected' => $settings->get( 'emails_rejected_course.email_format' ) ) ); ?>
59
+ </td>
60
+ </tr>
61
+ <?php
62
+ $view = learn_press_get_admin_view( 'settings/emails/email-template.php' );
63
+ include_once $view;
64
+ ?>
65
+ <?php do_action( 'learn_press_after_' . $settings_class->id . '_' . $settings_class->section['id'] . '_settings_fields', $settings ); ?>
66
+ </tbody>
67
+ </table>
inc/admin/views/settings/fields/checkbox.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $option_value = $this->get_option( $options['id'], $options['default'] );
3
+ $visbility_class = array();
4
+
5
+ if ( !isset( $options['hide_if_checked'] ) ) {
6
+ $options['hide_if_checked'] = false;
7
+ }
8
+ if ( !isset( $options['show_if_checked'] ) ) {
9
+ $options['show_if_checked'] = false;
10
+ }
11
+ if ( 'yes' == $options['hide_if_checked'] || 'yes' == $options['show_if_checked'] ) {
12
+ $visbility_class[] = 'hidden_option';
13
+ }
14
+ if ( 'option' == $options['hide_if_checked'] ) {
15
+ $visbility_class[] = 'hide_options_if_checked';
16
+ }
17
+ if ( 'option' == $options['show_if_checked'] ) {
18
+ $visbility_class[] = 'show_options_if_checked';
19
+ }
20
+
21
+ ?>
22
+ <tr valign="top" class="<?php echo esc_attr( implode( ' ', $visbility_class ) ); ?>">
23
+ <th scope="row" class="titledesc"><?php echo esc_html( $options['title'] ) ?></th>
24
+ <td class="forminp forminp-checkbox">
25
+ <fieldset>
26
+ <?php if ( !empty( $options['title'] ) ) { ?>
27
+ <legend class="screen-reader-text">
28
+ <span><?php echo esc_html( $options['title'] ) ?></span>
29
+ </legend>
30
+ <?php } ?>
31
+ <input name="<?php echo esc_attr( $options['id'] ); ?>" type="hidden" value="no" />
32
+ <label for="<?php echo $options['id'] ?>">
33
+ <input
34
+ name="<?php echo esc_attr( $options['id'] ); ?>"
35
+ id="<?php echo esc_attr( $options['id'] ); ?>"
36
+ type="checkbox"
37
+ class="<?php echo esc_attr( isset( $options['class'] ) ? $options['class'] : '' ); ?>"
38
+ value="yes"
39
+ <?php checked( $option_value, 'yes' ); ?>
40
+ <?php echo implode( ' ', $custom_attributes ); ?>
41
+ /> <?php echo $description ?>
42
+ </label>
43
+ </fieldset>
44
+ </td>
45
+ </tr>
inc/admin/views/settings/fields/course-permalink.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $settings = LP()->settings;
4
+ global $wp_post_types;
5
+ if ( !empty( $wp_post_types[LP()->course_post_type] ) ) {
6
+ $course_type = $wp_post_types[LP()->course_post_type];
7
+ $default_courses_slug = $course_type->rewrite['slug'];
8
+ } else {
9
+ $default_courses_slug = '';
10
+ }
11
+
12
+ $course_permalink = $settings->get( 'course_base' );
13
+ $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' => '',
26
+ 'text' => __( 'Default', 'learnpress' ),
27
+ 'code' => esc_html( home_url() ) . '/?lp_course=sample-course'
28
+ ),
29
+ 1 => array(
30
+ 'value' => '/' . trailingslashit( $course_base ),
31
+ 'text' => __( 'Course', 'learnpress' ),
32
+ 'code' => esc_html( sprintf( '%s/%s/sample-course/', home_url(), $course_base ) )
33
+ ),
34
+ 2 => array(
35
+ 'value' => '/' . trailingslashit( $base_slug ),
36
+ 'text' => __( 'Courses base', 'learnpress' ),
37
+ 'code' => esc_html( sprintf( '%s/%s/sample-course/', home_url(), $base_slug ) )
38
+ ),
39
+ 3 => array(
40
+ 'value' => '/' . trailingslashit( $base_slug ) . trailingslashit( '%course_category%' ),
41
+ 'text' => __( 'Courses base with category', 'learnpress' ),
42
+ 'code' => esc_html( sprintf( '%s/%s/course-category/sample-course/', home_url(), $base_slug ) )
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
+ }
60
+ ?>
61
+ <label>
62
+ <input name="<?php echo $this->get_field_name( "course_base" ); ?>" type="radio" value="<?php echo esc_attr( $structure['value'] ); ?>" class="learn-press-course-base" <?php echo $is_checked; ?> />
63
+ <?php echo $structure['text']; ?>
64
+ </label>
65
+ </th>
66
+ <td>
67
+ <code><?php echo $structure['code']; ?></code>
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 instead.', 'learnpress' ); ?></p>
82
+ </td>
83
+ </tr>
inc/admin/views/settings/fields/html.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ ?>
3
+ <tr valign="top">
4
+ <th scope="row" class="titledesc">
5
+ <label for="<?php echo esc_attr( $options['id'] ); ?>"><?php echo esc_html( $options['title'] ); ?></label>
6
+ </th>
7
+ <td class="forminp forminp-<?php echo sanitize_title( $options['type'] ) ?>">
8
+ <?php
9
+ if( !empty( $options['html'] ) ){
10
+ echo $options['html'];
11
+ }
12
+ ?>
13
+ <?php echo $description; ?>
14
+ </td>
15
+ </tr>
inc/admin/views/settings/fields/image-size.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <input type="text" size="4" name="<?php echo $options['id'];?>[width]" value="<?php echo $this->get_option( $options['id'] . '.width', $options['default'][0] ); ?>" placeholder="" />
10
+ &times;
11
+ <input type="text" size="4" name="<?php echo $options['id'];?>[height]" value="<?php echo $this->get_option( $options['id'] . '.height', $options['default'][1] ); ?>" placeholder="" />
12
+ <?php _e( 'px', 'learnpress' );?>
13
+ &nbsp;&nbsp;&nbsp;
14
+ <input type="hidden" name="<?php echo $options['id'];?>[crop]" value="no" />
15
+ <label>
16
+ <input type="checkbox" name="<?php echo $options['id'];?>[crop]" value="yes" <?php checked( $this->get_option( $options['id'] . '.crop', $options['default'][2] ) == 'yes' ); ?> />
17
+ <?php _e( 'Crop?', 'learn_pres' );?>
18
+ </label>
19
+ </td>
20
+ </tr>
inc/admin/views/settings/fields/pages-dropdown.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <tr>
2
+ <th scope="row" class="titledesc"><?php echo esc_html( $options['title'] ) ?></th>
3
+ <td>
4
+ <?php
5
+ learn_press_pages_dropdown( $options['id'], $this->get_option( $options['id'], $options['default'] ) );
6
+ ?>
7
+ </td>
8
+ </tr>
inc/admin/views/settings/fields/select.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $option_value = self::get_option( $options['id'], $options['default'] );
3
+ ?>
4
+ <tr valign="top">
5
+ <th scope="row" class="titledesc">
6
+ <label for="<?php echo esc_attr( $options['id'] ); ?>"><?php echo esc_html( $options['title'] ); ?></label>
7
+ </th>
8
+ <td class="forminp forminp-<?php echo sanitize_title( $options['type'] ) ?>">
9
+ <select
10
+ name="<?php echo esc_attr( $options['id'] ); ?><?php if ( $options['type'] == 'multiselect' ) echo '[]'; ?>"
11
+ id="<?php echo esc_attr( $options['id'] ); ?>"
12
+ style="<?php echo esc_attr( $options['css'] ); ?>"
13
+ class="<?php echo esc_attr( $options['class'] ); ?>"
14
+ <?php echo implode( ' ', $custom_attributes ); ?>
15
+ <?php echo ( 'multiselect' == $options['type'] ) ? 'multiple="multiple"' : ''; ?>
16
+ >
17
+ <?php
18
+ foreach ( $options['options'] as $key => $val ) {
19
+ ?>
20
+ <option value="<?php echo esc_attr( $key ); ?>" <?php
21
+
22
+ if ( is_array( $option_value ) ) {
23
+ selected( in_array( $key, $option_value ), true );
24
+ } else {
25
+ selected( $option_value, $key );
26
+ }
27
+
28
+ ?>><?php echo $val ?></option>
29
+ <?php
30
+ }
31
+ ?>
32
+ </select> <?php echo $description; ?>
33
+ </td>
34
+ </tr>
inc/admin/views/settings/fields/text.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $type = $options['type'];
3
+ $option_value = self::get_option( $options['id'], $options['default'] );
4
+
5
+ if ( $options['type'] == 'color' ) {
6
+ $type = 'text';
7
+ $options['class'] .= 'colorpick';
8
+ $description .= '<div id="colorPickerDiv_' . esc_attr( $options['id'] ) . '" class="colorpickdiv" style="z-index: 100;background:#eee;border:1px solid #ccc;position:absolute;display:none;"></div>';
9
+ }
10
+
11
+ ?>
12
+ <tr valign="top">
13
+ <th scope="row" class="titledesc">
14
+ <label for="<?php echo esc_attr( $options['id'] ); ?>"><?php echo esc_html( $options['title'] ); ?></label>
15
+ </th>
16
+ <td class="forminp forminp-<?php echo sanitize_title( $options['type'] ) ?>">
17
+ <?php
18
+ if ( 'color' == $options['type'] ) {
19
+ echo '<span class="colorpickpreview" style="background: ' . esc_attr( $option_value ) . ';"></span>';
20
+ }
21
+ ?>
22
+ <input
23
+ name="<?php echo esc_attr( $options['id'] ); ?>"
24
+ id="<?php echo esc_attr( $options['id'] ); ?>"
25
+ type="<?php echo esc_attr( $type ); ?>"
26
+ style="<?php echo esc_attr( $options['css'] ); ?>"
27
+ value="<?php echo esc_attr( $option_value ); ?>"
28
+ class="<?php echo esc_attr( $options['class'] ); ?>"
29
+ placeholder="<?php echo esc_attr( $options['placeholder'] ); ?>"
30
+ <?php echo implode( ' ', $custom_attributes ); ?>
31
+ /> <?php echo $description; ?>
32
+ </td>
33
+ </tr>
inc/admin/views/settings/fields/textarea.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $option_value = self::get_option( $options['id'], $options['default'] );
3
+ ?>
4
+ <tr valign="top">
5
+ <th scope="row" class="titledesc">
6
+ <label for="<?php echo esc_attr( $options['id'] ); ?>"><?php echo esc_html( $options['title'] ); ?></label>
7
+ <?php //echo $tooltip_html; ?>
8
+ </th>
9
+ <td class="forminp forminp-<?php echo sanitize_title( $options['type'] ) ?>">
10
+ <?php if( !empty( $options['editor'] ) && $options['editor'] !== false ){?>
11
+ <?php
12
+ $editor_args = array( 'textarea_name' => $options['id'] );
13
+ if( is_array( $options['editor'] ) ){
14
+ $editor_args = array_merge( $editor_args, $options['editor'] );
15
+ }
16
+ wp_editor( $option_value, $options['id'], $editor_args );
17
+ ?>
18
+ <?php }else{ ?>
19
+ <textarea
20
+ name="<?php echo esc_attr( $options['id'] ); ?>"
21
+ id="<?php echo esc_attr( $options['id'] ); ?>"
22
+ style="<?php echo esc_attr( $options['css'] ); ?>"
23
+ class="<?php echo esc_attr( $options['class'] ); ?>"
24
+ placeholder="<?php echo esc_attr( $options['placeholder'] ); ?>"
25
+ <?php echo implode( ' ', $custom_attributes ); ?>
26
+ ><?php echo esc_textarea( $option_value ); ?></textarea>
27
+ <?php }?>
28
+ <?php echo $description; ?>
29
+ </td>
30
+ </tr>
inc/admin/views/settings/fields/title.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <tr class="header-form">
2
+ <th colspan="2" style="padding: 0;"><h3 style="padding: 0; margin: 0;"><?php echo esc_html( $options['title'] ) ?></h3></th>
3
+ </tr>
inc/admin/views/settings/general.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <table class="form-table">
17
+ <tbody>
18
+ <?php do_action( 'learn_press_before_general_settings_fields', $settings ); ?>
19
+ <?php foreach( $this->get_settings() as $field ){?>
20
+ <?php $this->output_field( $field );?>
21
+ <?php }?>
22
+
23
+ <?php if(1 == 0){?>
24
+ <tr>
25
+ <th scope="row">
26
+ <label><?php _e( 'Instructors registration', 'learnpress' ); ?></label>
27
+ </th>
28
+ <td>
29
+ <input type="hidden" name="<?php echo $this->get_field_name( 'instructor_registration' ); ?>" value="no">
30
+ <input type="checkbox" name="<?php echo $this->get_field_name( 'instructor_registration' ); ?>" value="yes" <?php checked( $settings->get( 'instructor_registration' ) == 'yes', true ); ?> />
31
+
32
+ <p class="description"><?php _e( 'Create option for instructors registration', 'learnpress' ); ?></p>
33
+ </td>
34
+ </tr>
35
+ <tr>
36
+ <th><label><?php _e( 'Auto update post name', 'learnpress' ); ?></label></th>
37
+ <td>
38
+ <input type="hidden" name="<?php echo $this->get_field_name( 'auto_update_post_name' ); ?>" value="no">
39
+ <input type="checkbox" name="<?php echo $this->get_field_name( 'auto_update_post_name' ); ?>" value="yes" <?php checked( $settings->get( 'auto_update_post_name' ) == 'yes', true ); ?> />
40
+ <p class="description">
41
+ <?php _e( 'The post\'s name will update along with the title when changes title of lesson or quiz in course curriculum or question in quiz<br />The permalink also is changed, therefore uncheck this if you don\'t want to change the permalink', 'learnpress' );?>
42
+ </p>
43
+ </td>
44
+ </tr>
45
+ <tr>
46
+ <th><label><?php _e( 'Currency', 'learnpress' ); ?></label></th>
47
+ <td>
48
+ <select name="<?php echo $this->get_field_name( 'currency' ); ?>">
49
+ <?php if ( $payment_currencies = learn_press_get_payment_currencies() ) foreach ( $payment_currencies as $code => $symbol ) { ?>
50
+ <?php $selected = selected( $settings->get( 'currency' ) == $code ? 1 : 0, 1, false ); ?>
51
+ <option <?php echo $selected; ?> value="<?php echo $code; ?>"><?php echo $symbol; ?></option>
52
+ <?php } ?>
53
+ </select>
54
+ </td>
55
+ </tr>
56
+ <tr>
57
+ <th><label><?php _e( 'Currency Position', 'learnpress' ); ?></label>
58
+ </th>
59
+ <td>
60
+ <select name="<?php echo $this->get_field_name( 'currency_pos' ); ?>">
61
+ <?php foreach ( learn_press_currency_positions() as $pos => $text ) { ?>
62
+ <option value="<?php echo $pos; ?>" <?php selected( $settings->get( 'currency_pos' ) == $pos ? 1 : 0, 1 ); ?>>
63
+ <?php
64
+ switch ( $pos ) {
65
+ case 'left':
66
+ printf( '%s ( %s%s )', $text, learn_press_get_currency_symbol(), '69.99' );
67
+ break;
68
+ case 'right':
69
+ printf( '%s ( %s%s )', $text, '69.99', learn_press_get_currency_symbol() );
70
+ break;
71
+ case 'left_with_space':
72
+ printf( '%s ( %s %s )', $text, learn_press_get_currency_symbol(), '69.99' );
73
+ break;
74
+ case 'right_with_space':
75
+ printf( '%s ( %s %s )', $text, '69.99', learn_press_get_currency_symbol() );
76
+ break;
77
+ }
78
+ ?>
79
+ </option>
80
+ <?php } ?>
81
+ </select>
82
+ </td>
83
+ </tr>
84
+ <tr>
85
+ <th><label><?php _e( 'Thousands Separator', 'learnpress' ); ?></label></th>
86
+ <td>
87
+ <input class="regular_text" type="text" name="<?php echo $this->get_field_name( 'thousands_separator' ); ?>" value="<?php echo $settings->get( 'thousands_separator', ',' ); ?>" />
88
+ </td>
89
+ </tr>
90
+ <tr>
91
+ <th><label><?php _e( 'Decimals Separator', 'learnpress' ); ?></label></th>
92
+ <td>
93
+ <input class="regular_text" type="text" name="<?php echo $this->get_field_name( 'decimals_separator' ); ?>" value="<?php echo $settings->get( 'decimals_separator', '.' ); ?>" />
94
+ </td>
95
+ </tr>
96
+ <tr>
97
+ <th><label><?php _e( 'Number of Decimals', 'learnpress' ); ?></label></th>
98
+ <td>
99
+ <input class="regular_text" type="text" name="<?php echo $this->get_field_name( 'number_of_decimals' ); ?>" value="<?php echo $settings->get( 'number_of_decimals', 2 ); ?>" />
100
+ </td>
101
+ </tr>
102
+ <?php do_action( 'learn_press_after_general_settings_fields', $settings ); ?>
103
+ <?php }?>
104
+ </tbody>
105
+ </table>
inc/admin/views/settings/pages/become-a-teacher.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Display settings for pages
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
+ <table class="form-table">
17
+ <tbody>
18
+ <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
19
+ <?php foreach( $this->_get_settings( 'become_a_teacher' ) as $field ){?>
20
+ <?php $this->output_field( $field );?>
21
+ <?php }?>
22
+ <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
23
+ </tbody>
24
+ </table>
inc/admin/views/settings/pages/profile.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Display settings for pages
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
+ <table class="form-table">
17
+ <tbody>
18
+ <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
19
+ <?php foreach( $this->_get_settings( 'profile' ) as $field ){?>
20
+ <?php $this->output_field( $field );?>
21
+ <?php }?>
22
+ <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
23
+ </tbody>
24
+ </table>
inc/admin/views/settings/pages/quiz.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Display settings for pages
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
+ <table class="form-table">
17
+ <tbody>
18
+ <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
19
+ <?php foreach( $this->_get_settings( 'quiz' ) as $field ){?>
20
+ <?php $this->output_field( $field );?>
21
+ <?php }?>
22
+ <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
23
+ </tbody>
24
+ </table>
inc/admin/views/settings/payments.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Display settings for payments
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
+ $settings = LP()->settings;
14
+ ?>
15
+ <?php do_action( 'learn_press_before_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
16
+ <tr>
17
+ <th scope="row"><label for="learn_press_paypal_enable"><?php _e( 'Enable', 'learnpress' ); ?></label></th>
18
+ <td>
19
+ <input type="hidden" name="<?php echo $this->get_field_name( 'paypal_enable' ); ?>" value="no">
20
+ <input type="checkbox" id="learn_press_paypal_enable" name="<?php echo $this->get_field_name( 'paypal_enable' ); ?>" value="yes" <?php checked( $settings->get( 'paypal_enable', 'yes' ) == 'yes', true ); ?> />
21
+ </td>
22
+ </tr>
23
+ <!--<tr class="" data-learn_press_paypal_enable="yes">
24
+ <th scope="row"><label for="learn_press_paypal_type"><?php _e( 'Type', 'learnpress' ); ?></label></th>
25
+ <td>
26
+ <select id="learn_press_paypal_type" name="<?php echo $this->get_field_name( 'paypal_type' ); ?>">
27
+ <option value="basic"<?php selected( $settings->get( 'paypal_type' ) == 'basic' ? 1 : 0, 1 ); ?>><?php _e( 'Basic', 'learnpress' ); ?></option>
28
+ <option value="security" <?php selected( $settings->get( 'paypal_type' ) == 'security' ? 1 : 0, 1 ); ?>><?php _e( 'Security', 'learnpress' ); ?></option>
29
+ </select>
30
+ </td>
31
+ </tr>-->
32
+ <tr data-learn_press_paypal_enable="yes">
33
+ <th scope="row"><label for="learn_press_paypal_email"><?php _e( 'Email Address', 'learnpress' ); ?></label>
34
+ </th>
35
+ <td>
36
+ <input type="email" class="regular-text" name="<?php echo $this->get_field_name( 'paypal_email' ); ?>" value="<?php echo $settings->get( 'paypal_email', '' ); ?>" />
37
+ </td>
38
+ </tr>
39
+ <!--
40
+ <tr data-learn_press_paypal_enable="yes" class="learn_press_paypal_type_security<?php echo $settings->get( 'paypal_type' ) != 'security' ? ' hide-if-js' : ''; ?>">
41
+ <th scope="row">
42
+ <label for="learn_press_paypal_api_name"><?php _e( 'API Username', 'learnpress' ); ?></label></th>
43
+ <td>
44
+ <input type="text" class="regular-text" name="<?php echo $this->get_field_name( 'paypal_api_username' ); ?>" value="<?php echo $settings->get( 'paypal_api_username', '' ); ?>" />
45
+ </td>
46
+ </tr>
47
+ <tr data-learn_press_paypal_enable="yes" class="learn_press_paypal_type_security<?php echo $settings->get( 'paypal_type' ) != 'security' ? ' hide-if-js' : ''; ?>">
48
+ <th scope="row">
49
+ <label for="learn_press_paypal_api_pass"><?php _e( 'API Password', 'learnpress' ); ?></label></th>
50
+ <td>
51
+ <input type="password" class="regular-text" name="<?php echo $this->get_field_name( 'paypal_api_password' ); ?>" value="<?php echo $settings->get( 'paypal_api_password', '' ); ?>" />
52
+ </td>
53
+ </tr>
54
+ <tr data-learn_press_paypal_enable="yes" class="learn_press_paypal_type_security<?php echo $settings->get( 'paypal_type' ) != 'security' ? ' hide-if-js' : ''; ?>">
55
+ <th scope="row">
56
+ <label for="learn_press_paypal_api_sign"><?php _e( 'API Signature', 'learnpress' ); ?></label></th>
57
+ <td>
58
+ <input type="text" class="regular-text" name="<?php echo $this->get_field_name( 'paypal_api_signature' ); ?>" value="<?php echo $settings->get( 'paypal_api_signature', '' ); ?>" />
59
+ </td>
60
+ </tr>
61
+ <!-- sandbox mode -->
62
+ <?php
63
+ $show_or_hide = $settings->get( 'paypal_type' ) == 'security' ? '' : ' hide-if-js';
64
+ $readonly = $settings->get( 'paypal_sandbox' ) ? '' : ' readonly="readonly"';
65
+ ?>
66
+ <tr>
67
+ <th scope="row">
68
+ <label for="learn_press_paypal_sandbox_mode"><?php _e( 'Sandbox Mode', 'learnpress' ); ?></label></th>
69
+ <td>
70
+ <input type="hidden" name="<?php echo $this->get_field_name( 'paypal_sandbox' ); ?>" value="no">
71
+ <input type="checkbox" id="learn_press_paypal_sandbox_mode" name="<?php echo $this->get_field_name( 'paypal_sandbox' ); ?>" value="yes" <?php checked( $settings->get( 'paypal_sandbox', 'no' ) == 'yes', true ); ?> />
72
+ </td>
73
+ </tr>
74
+ <tr class="sandbox">
75
+ <th scope="row">
76
+ <label for="learn_press_paypal_sandbox_email"><?php _e( 'Sandbox Email Address', 'learnpress' ); ?></label>
77
+ </th>
78
+ <td>
79
+ <input type="email" class="regular-text"<?php echo $readonly; ?> name="<?php echo $this->get_field_name( 'paypal_sandbox_email' ); ?>" value="<?php echo $settings->get( 'paypal_sandbox_email', '' ); ?>" />
80
+ </td>
81
+ </tr>
82
+ <!--
83
+ <tr class="learn_press_paypal_type_security sandbox<?php echo $show_or_hide; ?>">
84
+ <th scope="row">
85
+ <label for="learn_press_paypal_sandbox_name"><?php _e( 'Sandbox API Username', 'learnpress' ); ?></label>
86
+ </th>
87
+ <td>
88
+ <input type="text" class="regular-text"<?php echo $readonly; ?> name="<?php echo $this->get_field_name( 'paypal_sandbox_api_username' ); ?>" value="<?php echo $settings->get( 'paypal_sandbox_api_username', '' ); ?>" />
89
+ </td>
90
+ </tr>
91
+ <tr class="learn_press_paypal_type_security sandbox<?php echo $show_or_hide; ?>">
92
+ <th scope="row">
93
+ <label for="learn_press_paypal_sandbox_pass"><?php _e( 'Sandbox API Password', 'learnpress' ); ?></label>
94
+ </th>
95
+ <td>
96
+ <input type="password" class="regular-text"<?php echo $readonly; ?> name="<?php echo $this->get_field_name( 'paypal_sandbox_api_password' ); ?>" value="<?php echo $settings->get( 'paypal_sandbox_api_password', '' ); ?>" />
97
+ </td>
98
+ </tr>
99
+ <tr class="learn_press_paypal_type_security sandbox<?php echo $show_or_hide; ?>">
100
+ <th scope="row">
101
+ <label for="learn_press_paypal_sandbox_sign"><?php _e( 'Sandbox API Signature', 'learnpress' ); ?></label>
102
+ </th>
103
+ <td>
104
+ <input type="text" class="regular-text"<?php echo $readonly; ?> name="<?php echo $this->get_field_name( 'paypal_sandbox_api_signature' ); ?>" value="<?php echo $settings->get( 'paypal_sandbox_api_signature', '' ); ?>" />
105
+ </td>
106
+ </tr>-->
107
+ <?php do_action( 'learn_press_after_' . $this->id . '_' . $this->section['id'] . '_settings_fields', $settings ); ?>
inc/admin/views/settings/profile.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Display settings for profile
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
+ <table class="form-table">
17
+ <tbody>
18
+ <?php do_action( 'learn_press_before_' . $this->id . '_settings_fields', $this ); ?>
19
+ <?php foreach( $this->get_settings() as $field ){?>
20
+ <?php $this->output_field( $field );?>
21
+ <?php }?>
22
+ <?php if( 1 == 0 ){?>
23
+ <tr>
24
+ <th scope="row"><label><?php _e( 'Profile page', 'learnpress' ); ?></label></th>
25
+ <td>
26
+ <?php
27
+ $profile_page_id = $settings->get( 'profile_page_id', 0 );
28
+ learn_press_pages_dropdown( $this->get_field_name( "profile_page_id" ), $profile_page_id );
29
+ ?>
30
+ </td>
31
+ </tr>
32
+ <?php }?>
33
+ <?php do_action( 'learn_press_after_' . $this->id . '_settings_fields', $this ); ?>
34
+ </tbody>
35
+ </table>
inc/admin/views/settings/setting-field.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Switch based on type
3
+ switch ( $options['type'] ) {
4
+ case 'text':
5
+ case 'email':
6
+ case 'number':
7
+ case 'color' :
8
+ case 'password' :
9
+ break;
10
+
11
+ // Textarea
12
+ case 'textarea':
13
+ $option_value = self::get_option( $options['id'], $options['default'] );
14
+ ?>
15
+ <tr valign="top">
16
+ <th scope="row" class="titledesc">
17
+ <label for="<?php echo esc_attr( $options['id'] ); ?>"><?php echo esc_html( $options['title'] ); ?></label>
18
+ <?php echo $tooltip_html; ?>
19
+ </th>
20
+ <td class="forminp forminp-<?php echo sanitize_title( $options['type'] ) ?>">
21
+ <?php echo $description; ?>
22
+
23
+ <textarea
24
+ name="<?php echo esc_attr( $options['id'] ); ?>"
25
+ id="<?php echo esc_attr( $options['id'] ); ?>"
26
+ style="<?php echo esc_attr( $options['css'] ); ?>"
27
+ class="<?php echo esc_attr( $options['class'] ); ?>"
28
+ placeholder="<?php echo esc_attr( $options['placeholder'] ); ?>"
29
+ <?php echo implode( ' ', $custom_attributes ); ?>
30
+ ><?php echo esc_textarea( $option_value ); ?></textarea>
31
+ </td>
32
+ </tr><?php
33
+ break;
34
+
35
+ // Select boxes
36
+ case 'select' :
37
+ case 'multiselect' :
38
+
39
+
40
+ break;
41
+
42
+ // Radio inputs
43
+ case 'radio' :
44
+
45
+ $option_value = self::get_option( $options['id'], $options['default'] );
46
+
47
+ ?>
48
+ <tr valign="top">
49
+ <th scope="row" class="titledesc">
50
+ <label for="<?php echo esc_attr( $options['id'] ); ?>"><?php echo esc_html( $options['title'] ); ?></label>
51
+ <?php echo $tooltip_html; ?>
52
+ </th>
53
+ <td class="forminp forminp-<?php echo sanitize_title( $options['type'] ) ?>">
54
+ <fieldset>
55
+ <?php echo $description; ?>
56
+ <ul>
57
+ <?php
58
+ foreach ( $options['options'] as $key => $val ) {
59
+ ?>
60
+ <li>
61
+ <label><input
62
+ name="<?php echo esc_attr( $options['id'] ); ?>"
63
+ value="<?php echo $key; ?>"
64
+ type="radio"
65
+ style="<?php echo esc_attr( $options['css'] ); ?>"
66
+ class="<?php echo esc_attr( $options['class'] ); ?>"
67
+ <?php echo implode( ' ', $custom_attributes ); ?>
68
+ <?php checked( $key, $option_value ); ?>
69
+ /> <?php echo $val ?></label>
70
+ </li>
71
+ <?php
72
+ }
73
+ ?>
74
+ </ul>
75
+ </fieldset>
76
+ </td>
77
+ </tr><?php
78
+ break;
79
+
80
+ // Checkbox input
81
+ case 'checkbox' :
82
+
83
+
84
+ break;
85
+ // Image width settings
86
+ case
87
+ 'image_width' :
88
+
89
+ $image_size = str_replace( '_image_size', '', $options['id'] );
90
+ $size = learn_press_get_image_size( $image_size );
91
+ $width = isset( $size['width'] ) ? $size['width'] : $options['default']['width'];
92
+ $height = isset( $size['height'] ) ? $size['height'] : $options['default']['height'];
93
+ $crop = isset( $size['crop'] ) ? $size['crop'] : $options['default']['crop'];
94
+ $disabled_attr = '';
95
+ $disabled_message = '';
96
+
97
+ if ( has_filter( 'learn_press_get_image_size_' . $image_size ) ) {
98
+ $disabled_attr = 'disabled="disabled"';
99
+ $disabled_message = "<p><small>" . __( 'The settings of this image size have been disabled because its values are being overwritten by a filter.', 'learnpress' ) . "</small></p>";
100
+ }
101
+
102
+ ?>
103
+ <tr valign="top">
104
+ <th scope="row" class="titledesc"><?php echo esc_html( $options['title'] ) ?><?php echo $tooltip_html;
105
+ echo $disabled_message; ?></th>
106
+ <td class="forminp image_width_settings">
107
+
108
+ <input name="<?php echo esc_attr( $options['id'] ); ?>[width]" <?php echo $disabled_attr; ?> id="<?php echo esc_attr( $options['id'] ); ?>-width" type="text" size="3" value="<?php echo $width; ?>" /> &times;
109
+ <input name="<?php echo esc_attr( $options['id'] ); ?>[height]" <?php echo $disabled_attr; ?> id="<?php echo esc_attr( $options['id'] ); ?>-height" type="text" size="3" value="<?php echo $height; ?>" />px
110
+
111
+ <label><input name="<?php echo esc_attr( $options['id'] ); ?>[crop]" <?php echo $disabled_attr; ?> id="<?php echo esc_attr( $options['id'] ); ?>-crop" type="checkbox" value="1" <?php checked( 1, $crop ); ?> /> <?php _e( 'Hard Crop?', 'learnpress' ); ?>
112
+ </label>
113
+
114
+ </td>
115
+ </tr><?php
116
+ break;
117
+
118
+ default:
119
+ do_action( 'learn_press_admin_field_' . $options['type'], $options );
120
+ break;
121
+ }
inc/admin/views/statistics/courses.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !defined( 'ABSPATH' ) ) {
4
+ exit; // Exit if accessed directly
5
+ }
6
+
7
+ $sections = array(
8
+ 'students' => __( 'Students', 'learnpress' ),
9
+ 'instructors' => __( 'Instructors', 'learnpress' ),
10
+ );
11
+ $section = $this->section ? $this->section : 'students';
12
+ $sections_count = sizeof( $sections );
13
+ $count = 0;
14
+ ?>
15
+ <div id="learn-press-statistic" class="learn-press-statistic-courses">
16
+ <ul class="subsubsub chart-buttons">
17
+ <li>
18
+ <button class="button" data-type="course-last-7-days" disabled="disabled"><?php _e( 'Last 7 Days', 'learnpress' ); ?></button>
19
+ </li>
20
+ <li>
21
+ <button class="button" data-type="course-last-30-days"><?php _e( 'Last 30 Days', 'learnpress' ); ?></button>
22
+ </li>
23
+ <li>
24
+ <button class="button" data-type="course-last-12-months"><?php _e( 'Last 12 Months', 'learnpress' ); ?></button>
25
+ </li>
26
+ <li>
27
+ <button class="button" data-type="course-all"><?php _e( 'All', 'learnpress' ); ?></button>
28
+ </li>
29
+ <li>
30
+ <form id="course-custom-time">
31
+ <span><?php _e( 'From', 'learnpress' ) ?></span>
32
+ <input type="text" placeholder="Y/m/d" name="from" class="date-picker" readonly="readonly">
33
+ <span><?php _e( 'To', 'learnpress' ) ?></span>
34
+ <input type="text" placeholder="Y/m/d" name="to" class="date-picker" readonly="readonly">
35
+ <input type="hidden" name="action" value="learnpress_custom_stats">
36
+ <button class="button button-primary" data-type="course-custom-time" type="submit" disabled="disabled"><?php _e( 'Go', 'learnpress' ); ?></button>
37
+ </form>
38
+ </li>
39
+ </ul>
40
+ <div class="clear"></div>
41
+ <ul class="chart-description">
42
+ <li class="all"><span><?php _e( 'All', 'learnpress' ); ?></span></li>
43
+ <li class="free"><span><?php _e( 'Public', 'learnpress' ); ?></span></li>
44
+ <li class="paid"><span><?php _e( 'Pending', 'learnpress' ); ?></span></li>
45
+ <li class="all"><span><?php _e( 'Paid', 'learnpress' ); ?></span></li>
46
+ <li class="free"><span><?php _e( 'Free', 'learnpress' ); ?></span></li>
47
+ </ul>
48
+ <div id="learn-press-chart" class="learn-press-chart">
49
+ </div>
50
+
51
+ <script type="text/javascript">
52
+ var LP_Chart_Config = <?php learn_press_config_chart();?>;
53
+ jQuery(document).ready(function ($) {
54
+ $('#learn-press-chart').LP_Chart_Line(<?php echo json_encode( learn_press_get_chart_courses( null, 'days', 7 ) );?>, LP_Chart_Config);
55
+ });
56
+ </script>
57
+ </div>
58
+
inc/admin/views/statistics/orders.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !defined( 'ABSPATH' ) ) {
4
+ exit; // Exit if accessed directly
5
+ }
6
+
7
+ $sections = array(
8
+ 'students' => __( 'Students', 'learnpress' ),
9
+ 'instructors' => __( 'Instructors', 'learnpress' ),
10
+ );
11
+ $section = $this->section ? $this->section : 'students';
12
+ $sections_count = sizeof( $sections );
13
+ $count = 0;
14
+ ?>
15
+ <div id="learn-press-statistic" class="learn-press-statistic-users">
16
+ <ul class="subsubsub chart-buttons">
17
+ <li>
18
+ <button class="button" data-type="order-last-7-days" disabled="disabled"><?php _e( 'Last 7 Days', 'learnpress' ); ?></button>
19
+ </li>
20
+ <li>
21
+ <button class="button" data-type="order-last-30-days"><?php _e( 'Last 30 Days', 'learnpress' ); ?></button>
22
+ </li>
23
+ <li>
24
+ <button class="button" data-type="order-last-12-months"><?php _e( 'Last 12 Months', 'learnpress' ); ?></button>
25
+ </li>
26
+ <li>
27
+ <button class="button" data-type="order-all"><?php _e( 'All', 'learnpress' ); ?></button>
28
+ </li>
29
+ <li>
30
+ <form id="order-custom-time">
31
+ <span><?php _e( 'From', 'learnpress' ) ?></span>
32
+ <input type="text" placeholder="Y/m/d" name="from" class="date-picker" readonly="readonly">
33
+ <span><?php _e( 'To', 'learnpress' ) ?></span>
34
+ <input type="text" placeholder="Y/m/d" name="to" class="date-picker" readonly="readonly">
35
+ <input type="hidden" name="action" value="learnpress_custom_stats">
36
+ <button class="button button-primary" data-type="order-custom-time" type="submit" disabled="disabled"><?php _e( 'Go', 'learnpress' ); ?></button>
37
+ </form>
38
+ </li>
39
+ </ul>
40
+ <div class="clear"></div>
41
+ <ul class="chart-description">
42
+ <li class="all"><span><?php _e( 'All', 'learnpress' ); ?></span></li>
43
+ <li class="instructors"><span><?php _e( 'Completed', 'learnpress' ); ?></span></li>
44
+ <li class="students"><span><?php _e( 'Pending', 'learnpress' ); ?></span></li>
45
+ </ul>
46
+ <div id="learn-press-chart" class="learn-press-chart">
47
+ </div>
48
+
49
+ <script type="text/javascript">
50
+ var LP_Chart_Config = <?php learn_press_config_chart();?>;
51
+ jQuery(document).ready(function ($) {
52
+ $('#learn-press-chart').LP_Chart_Line(<?php echo json_encode( learn_press_get_chart_orders( null, 'days', 7 ) );?>, LP_Chart_Config);
53
+ });
54
+ </script>
55
+ </div>
56
+
inc/admin/views/statistics/users.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !defined( 'ABSPATH' ) ) {
4
+ exit; // Exit if accessed directly
5
+ }
6
+
7
+ $sections = array(
8
+ 'students' => __( 'Students', 'learnpress' ),
9
+ 'instructors' => __( 'Instructors', 'learnpress' ),
10
+ );
11
+ $section = $this->section ? $this->section : 'students';
12
+ $sections_count = sizeof( $sections );
13
+ $count = 0;
14
+ ?>
15
+ <div id="learn-press-statistic" class="learn-press-statistic-users">
16
+ <ul class="subsubsub chart-buttons">
17
+ <li>
18
+ <button class="button" data-type="user-last-7-days" disabled="disabled"><?php _e( 'Last 7 Days', 'learnpress' ); ?></button>
19
+ </li>
20
+ <li>
21
+ <button class="button" data-type="user-last-30-days"><?php _e( 'Last 30 Days', 'learnpress' ); ?></button>
22
+ </li>
23
+ <li>
24
+ <button class="button" data-type="user-last-12-months"><?php _e( 'Last 12 Months', 'learnpress' ); ?></button>
25
+ </li>
26
+ <li>
27
+ <button class="button" data-type="user-all"><?php _e( 'All', 'learnpress' ); ?></button>
28
+ </li>
29
+ <li>
30
+ <form id="user-custom-time">
31
+ <span><?php _e( 'From', 'learnpress' ) ?></span>
32
+ <input type="text" placeholder="Y/m/d