From 47e2e3df98ad726898554d278df086a4e22e46ae Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Mon, 23 Feb 2015 22:43:23 -0700 Subject: [PATCH] Ajax quiz functionality and quiz timer. 1.2.2 release --- README.html | 211 ++ README.md | 15 + _private/assets/css/quiz-timer.css | 62 + _private/scss/frontend/_main.scss | 15 + _private/scss/frontend/quiz-timer.scss | 93 + _private/scss/lifterlms.scss | 2 + assets/css/lifterlms.css | 2481 +++++++---------- assets/js/llms-ajax.js | 140 +- assets/js/llms-quiz.js | 228 +- assets/js/min/llms-ajax-min.js | 1 + assets/js/min/llms-quiz-min.js | 1 + config.codekit | 103 +- includes/admin/class.llms.admin.analytics.php | 4 +- .../class.llms.meta.box.quiz.general.php | 31 +- includes/class.llms.ajax.php | 188 +- includes/class.llms.date.php | 40 + includes/class.llms.frontend.forms.php | 302 +- includes/class.llms.lesson.php | 11 +- includes/class.llms.quiz.php | 351 ++- includes/functions/llms.functions.access.php | 15 +- includes/functions/llms.functions.person.php | 4 +- includes/llms.functions.core.php | 17 + includes/llms.template.functions.php | 116 +- includes/llms.template.hooks.php | 18 +- lifterlms.php | 4 +- templates/content-single-question-after.php | 3 +- templates/content-single-question.php | 47 + templates/course/complete-lesson-link.php | 34 +- templates/course/lesson-navigation.php | 2 +- templates/course/parent_course.php | 10 +- templates/quiz/next-question.php | 16 +- templates/quiz/previous-question.php | 11 +- templates/quiz/question-count.php | 13 +- templates/quiz/quiz-question.php | 6 + templates/quiz/quiz-wrapper-end.php | 5 + templates/quiz/quiz-wrapper-start.php | 5 + templates/quiz/results.php | 171 +- templates/quiz/return-to-lesson.php | 10 +- templates/quiz/single-choice.php | 2 +- templates/quiz/single-choice_ajax.php | 65 + templates/quiz/start-button.php | 8 +- templates/quiz/time-limit.php | 21 + templates/quiz/timer.php | 19 + 43 files changed, 2793 insertions(+), 2108 deletions(-) create mode 100644 README.html create mode 100644 _private/assets/css/quiz-timer.css create mode 100644 _private/scss/frontend/quiz-timer.scss create mode 100644 assets/js/min/llms-ajax-min.js create mode 100644 assets/js/min/llms-quiz-min.js create mode 100644 templates/content-single-question.php create mode 100644 templates/quiz/quiz-question.php create mode 100644 templates/quiz/quiz-wrapper-end.php create mode 100644 templates/quiz/quiz-wrapper-start.php create mode 100644 templates/quiz/single-choice_ajax.php create mode 100644 templates/quiz/time-limit.php create mode 100644 templates/quiz/timer.php diff --git a/README.html b/README.html new file mode 100644 index 0000000000..169cde0029 --- /dev/null +++ b/README.html @@ -0,0 +1,211 @@ +

lifterLMS

+ +

LIFTER LMS

+ +

Shortcodes

+ + + + +

Debug: lms_log($message)

+ +

*Logs message to wp-contents/debug.log

+ +

Examples

+ +

log_me(array(‘This is a message’ => ‘for debugging purposes’)); +log_me(‘This is a message for debugging purposes’);

+ +

CHANGELOG

+ +

v1.2.2 - 2015-02-23

+ + + + +

v1.2.1 - 2015-02-19

+ + + + +

v1.2.0 - 2015-02-17

+ + + + +

v1.1.2 - 2014-12-18

+ + + + +

v1.1.1 - 2014-12-16

+ + + + +

v1.1.0 - 2014-12-08

+ + + + +

User Admin Table

+ + + + +

User Roles

+ + + + +

BUDDYPRESS

+ + + + +

MISC

+ + + + +

v1.0.5 - 2014-11-12

+ + + + +

v1.0.4 - 2014-11-04

+ + + + +

v1.0.3 - 2014-11-04

+ + + + +

v1.0.2 - 2014-10-31

+ + + + +

v1.0.2 - 2014-10-30

+ + + + +

v1.0.1 - 2014-10-30

+ + + diff --git a/README.md b/README.md index d3af015a65..e0ab32b5a1 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,21 @@ LIFTER LMS CHANGELOG ========= +v1.2.2 - 2015-02-23 +------------------- ++ Corrected drip content bug ++ Added Ajax functionality to quiz ++ rounded quiz grades ++ Added quiz time limit setting to Quiz ++ Added quiz timer to quiz, front end ++ Quiz allowed attempts field now allows unlimited attempts ++ Set Ajax lesson delete method to not return empty lesson value ++ Set next and previous questions to display below quiz question ++ Decoupled Single option select question type from quiz to allow for more question types ++ Added Quiz time limit to display on Quiz page ++ Added functionality to automatically complete quiz when quiz timer reaches 0 ++ Moved Quiz functionality methods from front end forms class to Quiz class + v1.2.1 - 2015-02-19 ------------------- + Updated settings page theming diff --git a/_private/assets/css/quiz-timer.css b/_private/assets/css/quiz-timer.css new file mode 100644 index 0000000000..cad1e0128a --- /dev/null +++ b/_private/assets/css/quiz-timer.css @@ -0,0 +1,62 @@ +.countdown-label { + font: thin 15px Arial, sans-serif; + color: #65584c; + text-align: center; + text-transform: uppercase; + display: inline-block; + letter-spacing: 2px; + margin-top: 9px; } + +#countdown { + box-shadow: 0 1px 2px 0 rgba(1, 1, 1, 0.4); + width: 240px; + height: 96px; + text-align: center; + background: #f1f1f1; + border-radius: 5px; + margin: auto; } + +#countdown #tiles { + color: #fff; + position: relative; + z-index: 1; + text-shadow: 1px 1px 0px #ccc; + display: inline-block; + font-family: Arial, sans-serif; + text-align: center; + padding: 20px; + border-radius: 5px 5px 0 0; + font-size: 48px; + font-weight: thin; + display: block; } + +.color-full { + background: #53bb74; } + +.color-half { + background: #ebc85d; } + +.color-empty { + background: #e5554e; } + +#countdown #tiles > span { + width: 70px; + max-width: 70px; + padding: 18px 0; + position: relative; } + +#countdown .labels { + width: 100%; + height: 25px; + text-align: center; + position: absolute; + bottom: 8px; } + +#countdown .labels li { + width: 102px; + font: bold 15px 'Droid Sans', Arial, sans-serif; + color: #f47321; + text-shadow: 1px 1px 0px #000; + text-align: center; + text-transform: uppercase; + display: inline-block; } diff --git a/_private/scss/frontend/_main.scss b/_private/scss/frontend/_main.scss index 936dd9f7d9..c845185e71 100644 --- a/_private/scss/frontend/_main.scss +++ b/_private/scss/frontend/_main.scss @@ -1047,3 +1047,18 @@ svg .llms-animated-circle { } } +.llms-question-wrapper { + margin: 40px 0 20px 0; +} +.llms-error{ + width: 100%; + background: #e5554e; + padding: 10px 20px; + color: #fff; + border-radius: 5px; + margin-bottom: 10px; +} +.llms-question-count { + margin-bottom: 20px; +} + diff --git a/_private/scss/frontend/quiz-timer.scss b/_private/scss/frontend/quiz-timer.scss new file mode 100644 index 0000000000..ed7add3217 --- /dev/null +++ b/_private/scss/frontend/quiz-timer.scss @@ -0,0 +1,93 @@ +#llms-quiz-timer { + float: right; + width: 100%; + clear: both; +} +.countdown-label { + margin-top: 6px; + text-align: center; + + display: inline-block; + + + p { + color: #65584c; + letter-spacing: 2px; + text-transform: uppercase; + font-size: 12px; + font-weight: thin; + font-family: Arial; + } +} +#countdown{ +box-shadow: 0 1px 2px 0 rgba(1, 1, 1, 0.4); +width: 240px; + height: 96px; + text-align: center; +background: #f1f1f1; + + border-radius: 5px; + + float: right; + +} + + + +#countdown #tiles{ + color: #fff; + position: relative; + z-index: 1; +text-shadow: 1px 1px 0px #ccc; + display: inline-block; + font-family: Arial, sans-serif; + text-align: center; + + padding: 0; + border-radius: 5px 5px 0 0; + font-size: 48px; + font-weight: thin; + display: block; + line-height: 1.4; + +} + +.color-full { + background: #53bb74; +} +.color-half { + background: #ebc85d; +} +.color-empty { + background: #e5554e; +} + +#countdown #tiles > span{ + width: 70px; + max-width: 70px; + + padding: 18px 0; + position: relative; +} + + + + + +#countdown .labels{ + width: 100%; + height: 25px; + text-align: center; + position: absolute; + bottom: 8px; +} + +#countdown .labels li{ + width: 102px; + font: bold 15px 'Droid Sans', Arial, sans-serif; + color: #f47321; + text-shadow: 1px 1px 0px #000; + text-align: center; + text-transform: uppercase; + display: inline-block; +} \ No newline at end of file diff --git a/_private/scss/lifterlms.scss b/_private/scss/lifterlms.scss index ce7100fd34..81c439c80e 100644 --- a/_private/scss/lifterlms.scss +++ b/_private/scss/lifterlms.scss @@ -8,4 +8,6 @@ @import "frontend/main"; +@import "frontend/quiz-timer"; + @import "_includes/vendor/_font-awesome"; diff --git a/assets/css/lifterlms.css b/assets/css/lifterlms.css index 9478bb2664..1d5f4548ea 100644 --- a/assets/css/lifterlms.css +++ b/assets/css/lifterlms.css @@ -1,8 +1,7 @@ .llms-lesson-preview .llms-lesson-link:after { content: ""; display: table; - clear: both; -} + clear: both; } .llms-course-list .llms-membership-link, .llms-course-list .llms-course-link, .llms-lesson-preview .llms-lesson-link { background: #f1f1f1; @@ -13,18 +12,15 @@ padding: 15px; text-decoration: none; position: relative; - -webkit-transition: background .4s ease; - transition: background .4s ease; -} -.llms-course-list .llms-membership-link:hover, .llms-course-list .llms-course-link:hover, .llms-lesson-preview .llms-lesson-link:hover { - background: #eaeaea; -} + transition: background .4s ease; } + .llms-course-list .llms-membership-link:hover, .llms-course-list .llms-course-link:hover, .llms-lesson-preview .llms-lesson-link:hover { + background: #eaeaea; } *, *:after, *::before { + -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; - box-sizing: border-box; -} + box-sizing: border-box; } .llms-button { background: #e5554e; @@ -33,82 +29,64 @@ display: inline-block; padding: 10px 20px; text-decoration: none; - -webkit-transition: background .4s ease; - transition: background .4s ease; - text-decoration: none; -} -.llms-button:visited { - color: #fefefe; - text-decoration: none; -} -.llms-button:hover { - background: #e24038; - text-decoration: none; - color: #fefefe; -} + transition: background .4s ease; + text-decoration: none; } + .llms-button:visited { + color: #fefefe; + text-decoration: none; } + .llms-button:hover { + background: #e24038; + text-decoration: none; + color: #fefefe; } .course-link .llms-button { color: #fefefe; - text-decoration: none; -} -.course-link .llms-button:hover { - color: #fefefe; - text-decoration: none; -} + text-decoration: none; } + .course-link .llms-button:hover { + color: #fefefe; + text-decoration: none; } .llms-purchase-link-wrapper .llms-purchase-button.llms-button { color: #fefefe; - text-decoration: none; -} -.llms-purchase-link-wrapper .llms-purchase-button.llms-button:visited { - color: #fefefe; - text-decoration: none; -} -.llms-purchase-link-wrapper .llms-purchase-button.llms-button:hover { - color: #fefefe; - text-decoration: none; -} + text-decoration: none; } + .llms-purchase-link-wrapper .llms-purchase-button.llms-button:visited { + color: #fefefe; + text-decoration: none; } + .llms-purchase-link-wrapper .llms-purchase-button.llms-button:hover { + color: #fefefe; + text-decoration: none; } .course-link .llms-button { color: #fefefe; - text-decoration: none; -} -.course-link .llms-button:visited { - color: #fefefe; - text-decoration: none; -} -.course-link .llms-button:hover { - color: #fefefe; - text-decoration: none; -} + text-decoration: none; } + .course-link .llms-button:visited { + color: #fefefe; + text-decoration: none; } + .course-link .llms-button:hover { + color: #fefefe; + text-decoration: none; } .hentry .course-link .llms-button { color: #fefefe; - text-decoration: none; -} -.hentry .course-link .llms-button:visited { - color: #fefefe; - text-decoration: none; -} -.hentry .course-link .llms-button:hover { - color: #fefefe; - text-decoration: none; -} + text-decoration: none; } + .hentry .course-link .llms-button:visited { + color: #fefefe; + text-decoration: none; } + .hentry .course-link .llms-button:hover { + color: #fefefe; + text-decoration: none; } .llms-course-list .llms-membership-link { - display: block; -} + display: block; } .llms-course-list .llms-membership-footer { border-top: 3px solid #fefefe; margin: 15px -15px 0; padding: 15px 15px 0; - text-align: center; -} + text-align: center; } .llms-membership-image { display: block; - margin: 0 auto; -} + margin: 0 auto; } .llms-membership-list .memberships { border-top: 1px solid #f6f6f6; @@ -118,8 +96,7 @@ list-style: none; clear: both; margin: 0; - padding: 0; -} + padding: 0; } .llms-membership-list .memberships li { width: 300px; @@ -127,16 +104,13 @@ list-style: none; vertical-align: top; display: inline-block; - text-align: left; -} + text-align: left; } .llms-membership-list .memberships li.first { - margin-left: 0; -} + margin-left: 0; } .llms-membership-list .memberships li.last { - margin-right: 15px; -} + margin-right: 15px; } .llms-membership-list .memberships li .llms-title { display: block; @@ -144,8 +118,7 @@ margin-bottom: .5em; font-size: 18px; text-decoration: none; - line-height: 30px; -} + line-height: 30px; } .llms-membership-list .memberships li .llms-price { display: block; @@ -153,41 +126,33 @@ margin-bottom: .5em; font-size: 24px; text-decoration: none; - line-height: 30px; -} + line-height: 30px; } .llms-course-list { padding: 30px; display: inline-block; - width: 100%; -} -.llms-course-list .llms-course-link { - display: block; -} -.llms-course-list .llms-course-footer { - border-top: 3px solid #fefefe; - margin: 15px -15px 0; - padding: 15px 15px 0; - text-align: center; -} -.llms-course-list .llms-progress { - margin-top: 0; -} + width: 100%; } + .llms-course-list .llms-course-link { + display: block; } + .llms-course-list .llms-course-footer { + border-top: 3px solid #fefefe; + margin: 15px -15px 0; + padding: 15px 15px 0; + text-align: center; } + .llms-course-list .llms-progress { + margin-top: 0; } .llms-course-image { display: block; margin: 0 auto; - max-width: 100%; -} + max-width: 100%; } .llms-featured-image { display: block; - margin: 0 auto 10px auto; -} + margin: 0 auto 10px auto; } .llms-image-thumb { - width: 150px; -} + width: 150px; } .llms-course-list .courses { width: 100%; @@ -196,8 +161,7 @@ list-style: none; clear: both; margin: 0; - padding: 0; -} + padding: 0; } .llms-course-list .courses li { width: 300px; @@ -205,12 +169,10 @@ list-style: none; vertical-align: top; display: inline-block; - text-align: left; -} + text-align: left; } .llms-course-list .courses li.last { - margin-right: 15px; -} + margin-right: 15px; } .llms-course-list .courses li .llms-title { display: block; @@ -218,8 +180,7 @@ margin-bottom: .5em; font-size: 18px; text-decoration: none; - line-height: 30px; -} + line-height: 30px; } .llms-course-list .courses li .llms-price { display: block; @@ -227,21 +188,17 @@ margin-bottom: .5em; font-size: 24px; text-decoration: none; - line-height: 30px; -} + line-height: 30px; } .llms-video-wrapper { text-align: center; - margin-bottom: 10px; -} + margin-bottom: 10px; } .llms-syllabus-wrapper { padding: 15px; - text-align: center; -} -.llms-syllabus-wrapper h3 { - margin-bottom: 0; -} + text-align: center; } + .llms-syllabus-wrapper h3 { + margin-bottom: 0; } .llms-lesson-preview { display: inline-block; @@ -250,203 +207,166 @@ vertical-align: top; width: 500px; max-width: 100%; - max-width: calc(100% - 30px); -} -.llms-lesson-preview.is-complete .llms-lesson-link { - padding-left: 75px; -} -.llms-lesson-preview .llms-lesson-link:visited { - color: inherit; -} -.llms-lesson-preview .llms-lesson-complete { - color: #e5554e; - font-size: 3em; - line-height: 1; - margin-right: .25em; - position: absolute; - top: 15px; - left: 15px; -} -.llms-lesson-preview .llms-lesson-title { - padding-right: 60px; - margin: 0 0 .25em 0; -} -.llms-lesson-preview .llms-lesson-counter { - position: absolute; - top: 15px; - right: 15px; -} -.llms-lesson-preview .llms-lesson-excerpt { - clear: both; -} + max-width: calc(100% - 30px); } + .llms-lesson-preview.is-complete .llms-lesson-link { + padding-left: 75px; } + .llms-lesson-preview .llms-lesson-link:visited { + color: inherit; } + .llms-lesson-preview .llms-lesson-complete { + color: #e5554e; + font-size: 3em; + line-height: 1; + margin-right: .25em; + position: absolute; + top: 15px; + left: 15px; } + .llms-lesson-preview .llms-lesson-title { + padding-right: 60px; + margin: 0 0 .25em 0; } + .llms-lesson-preview .llms-lesson-counter { + position: absolute; + top: 15px; + right: 15px; } + .llms-lesson-preview .llms-lesson-excerpt { + clear: both; } .llms-course-navigation .llms-lesson-preview.previous { float: left; width: 50%; margin: 0; - max-width: 300px; -} -.llms-course-navigation .llms-lesson-preview.previous h5 { - margin: 0; -} -.llms-course-navigation .llms-lesson-preview.previous p { - font-size: .8em; -} + max-width: 300px; } + .llms-course-navigation .llms-lesson-preview.previous h5 { + margin: 0; } + .llms-course-navigation .llms-lesson-preview.previous p { + font-size: .8em; } .llms-course-navigation .llms-lesson-preview.next { float: right; width: 50%; margin: 0; - max-width: 300px; -} -.llms-course-navigation .llms-lesson-preview.next h5 { - margin: 0; -} -.llms-course-navigation .llms-lesson-preview.next p { - font-size: .8em; -} + max-width: 300px; } + .llms-course-navigation .llms-lesson-preview.next h5 { + margin: 0; } + .llms-course-navigation .llms-lesson-preview.next p { + font-size: .8em; } .llms-course-navigation { text-align: center; - padding: 30px 0; -} -.llms-course-navigation .prev-lesson, -.llms-course-navigation .next-lesson, -.llms-course-navigation .parent-course { - display: inline-block; - width: 28%; - margin: 0; -} -@media screen and (max-width: 768px) { + padding: 30px 0; } + .llms-course-navigation .prev-lesson, + .llms-course-navigation .next-lesson, .llms-course-navigation .parent-course { - display: none; - } -} + display: inline-block; + width: 28%; + margin: 0; } + @media screen and (max-width: 768px) { + .llms-course-navigation .parent-course { + display: none; } } .clear { clear: both; - width: 100%; -} + width: 100%; } .llms-featured-image { - text-align: center; -} + text-align: center; } .llms-purchase-link-wrapper { text-align: center; width: 100%; - margin-bottom: 10px; -} + margin-bottom: 10px; } .llms-length-wrapper { - margin-top: 20px; -} + margin-top: 20px; } .llms-length-wrapper p { - margin: 0; -} + margin: 0; } /* My Quizes */ .llms-quiz-results { font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif; - position: relative; -} + position: relative; } .llms-quiz-results > h3 { background-color: #f5f5f5; - padding: 4px; -} + padding: 4px; } /* My Courses */ .llms-my-courses { - font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif; -} + font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif; } .llms-my-courses a { -webkit-filter: brightness(100%); -webkit-transition: all .5s ease; - transition: all .5s ease; -} + -moz-transition: all .5s ease; + -o-transition: all .5s ease; + -ms-transition: all .5s ease; + transition: all .5s ease; } .llms-my-courses ul.listing-courses { width: 100%; margin: 0; - padding: 0; -} + padding: 0; } .llms-my-courses > h3 { background-color: #f5f5f5; - padding: 4px; -} + padding: 4px; } .llms-my-courses ul.listing-courses li.course-item { margin: 10px 0; padding: 10px 0; list-style-type: none; width: 100%; - border-bottom: 2px solid #f5f5f5; -} + border-bottom: 2px solid #f5f5f5; } .llms-my-courses ul.listing-courses li.course-item:first-child { - border-bottom: 2px solid #f5f5f5; -} + border-bottom: 2px solid #f5f5f5; } .llms-my-courses ul.listing-courses li.course-item .course .course-image { float: left; margin-right: 20px; border: 1px solid #f5f5f5; padding: 4px; - overflow: hidden; -} -@media screen and (max-width: 641px) { - .llms-my-courses ul.listing-courses li.course-item .course .course-image { - width: 100%; - } -} + overflow: hidden; } + @media screen and (max-width: 641px) { + .llms-my-courses ul.listing-courses li.course-item .course .course-image { + width: 100%; } } .llms-my-courses ul.listing-courses li.course-item .course .course-image img { -webkit-filter: brightness(100%); -webkit-transition: all 1s ease; - transition: all 1s ease; -} + -moz-transition: all 1s ease; + -o-transition: all 1s ease; + -ms-transition: all 1s ease; + transition: all 1s ease; } .llms-my-courses ul.listing-courses li.course-item .course .course-image img:hover { - -webkit-filter: brightness(80%); -} + -webkit-filter: brightness(80%); } .llms-my-courses ul.listing-courses li.course-item .course h3 { margin: 10px 0; display: block; - clear: none; -} + clear: none; } .llms-my-courses ul.listing-courses li.course-item .course p { - margin: 0; -} + margin: 0; } .llms-my-courses ul.listing-courses li.course-item .course .info { float: left; - width: 100%; -} + width: 100%; } .llms-sts-enrollment { - display: inline-block; -} + display: inline-block; } .llms-sts-enrollment .llms-sts-current { - font-weight: 400; -} + font-weight: 400; } .llms-start-date { float: right; - text-align: right; -} -@media screen and (max-width: 641px) { - .llms-start-date { - float: none; - text-align: left; - } -} + text-align: right; } + @media screen and (max-width: 641px) { + .llms-start-date { + float: none; + text-align: left; } } .llms-my-courses ul.listing-courses li.course-item .course .course-message { border-radius: 3px; @@ -454,29 +374,24 @@ margin: 10px 0; padding: 15px 20px; background: #fffef4; - border: 1px solid #ccc; -} + border: 1px solid #ccc; } .course-message p { - margin: 0; -} + margin: 0; } .course-link { - text-align: center; -} + text-align: center; } .account-links { text-align: left; - margin-bottom: 40px; -} + margin-bottom: 40px; } /* progress bar */ .llms-progress { position: relative; height: 1em; width: 100%; - margin: 15px 0; -} + margin: 15px 0; } .llms-progress .progress-bar { background-color: #f1f2f1; @@ -484,177 +399,144 @@ height: .4em; left: 0; right: 3em; - top: .3em; -} + top: .3em; } .llms-progress .progress-bar-complete { background-color: #e5554e; position: absolute; - height: 100%; -} + height: 100%; } .progress__indicator { float: right; width: 3em; text-align: right; height: 1em; - line-height: 1em; -} + line-height: 1em; } /* my certificates grid */ .llms-my-certificates { - font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif; -} -.llms-my-certificates h3 { - background-color: #f5f5f5; - padding: 4px; -} -.llms-my-certificates ul.listing-certificates { - width: 100%; - margin: 0; -} -.llms-my-certificates ul.listing-certificates li.certificate-item { - border-radius: 3px; - z-index: 10; - margin: 10px 0; - padding: 15px 20px; - background: #fffef4; - border: 1px solid #ccc; - list-style-type: none; - width: 100%; - overflow: auto; -} -.llms-my-certificates ul.listing-certificates li.certificate-item div { - display: block; - width: 30%; - float: left; - text-align: right; -} -.llms-my-certificates ul.listing-certificates li.certificate-item div p, .llms-my-certificates ul.listing-certificates li.certificate-item div h4 { - margin: 0; -} -.llms-my-certificates ul.listing-certificates li.certificate-item div:first-child { - width: 40%; - text-align: left; -} + font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif; } + .llms-my-certificates h3 { + background-color: #f5f5f5; + padding: 4px; } + .llms-my-certificates ul.listing-certificates { + width: 100%; + margin: 0; } + .llms-my-certificates ul.listing-certificates li.certificate-item { + border-radius: 3px; + z-index: 10; + margin: 10px 0; + padding: 15px 20px; + background: #fffef4; + border: 1px solid #ccc; + list-style-type: none; + width: 100%; + overflow: auto; } + .llms-my-certificates ul.listing-certificates li.certificate-item div { + display: block; + width: 30%; + float: left; + text-align: right; } + .llms-my-certificates ul.listing-certificates li.certificate-item div p, .llms-my-certificates ul.listing-certificates li.certificate-item div h4 { + margin: 0; } + .llms-my-certificates ul.listing-certificates li.certificate-item div:first-child { + width: 40%; + text-align: left; } .llms-my-achievements { - font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif; -} -.llms-my-achievements h3 { - background-color: #f5f5f5; - padding: 4px; -} -.llms-my-achievements ul.listing-achievements { - width: 100%; - margin: 0; -} -.llms-my-achievements ul.listing-achievements li.achievement-item { - border-radius: 3px; - z-index: 10; - margin: 10px 0; - padding: 15px 20px; - background: #fffef4; - border: 1px solid #ccc; - list-style-type: none; - width: 30%; - overflow: auto; - min-width: 200px; -} -.llms-my-achievements ul.listing-achievements li.achievement-item div { - display: block; - width: 100%; - float: left; - text-align: center; -} -.llms-my-achievements ul.listing-achievements li.achievement-item div p, .llms-my-achievements ul.listing-achievements li.achievement-item div h4 { - margin: 0; -} + font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif; } + .llms-my-achievements h3 { + background-color: #f5f5f5; + padding: 4px; } + .llms-my-achievements ul.listing-achievements { + width: 100%; + margin: 0; } + .llms-my-achievements ul.listing-achievements li.achievement-item { + border-radius: 3px; + z-index: 10; + margin: 10px 0; + padding: 15px 20px; + background: #fffef4; + border: 1px solid #ccc; + list-style-type: none; + width: 30%; + overflow: auto; + min-width: 200px; } + .llms-my-achievements ul.listing-achievements li.achievement-item div { + display: block; + width: 100%; + float: left; + text-align: center; } + .llms-my-achievements ul.listing-achievements li.achievement-item div p, .llms-my-achievements ul.listing-achievements li.achievement-item div h4 { + margin: 0; } /* Genisis Overrides */ h1, h2, h3, h4, h5, h6 { - font-weight: 300; -} + font-weight: 300; } #main-content .llms-payment-options p { margin: 0; - font-size: 16px; -} + font-size: 16px; } /* checkout form */ .llms-checkout-wrapper { border: 1px solid #f5f5f5; width: 100%; max-width: 800px; - margin: 0 auto; -} -.llms-checkout-wrapper .llms-checkout { - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-top: 6px solid #e5554e; -} -.llms-checkout-wrapper .llms-checkout > h4 { - background-color: #f5f5f5; - padding: 6px 10px; - margin: 0; -} -.llms-checkout-wrapper .llms-checkout .llms-title-wrapper { - display: block; - width: 100%; - border-bottom: 2px solid #f5f5f5; -} -.llms-checkout-wrapper .llms-checkout .llms-title-wrapper p { - padding: 0 10px; - margin: 10px 0; -} -.llms-checkout-wrapper .llms-checkout .llms-title-wrapper h4 { - padding: 0 10px; - margin: 10px 0; -} -.llms-checkout-wrapper .llms-checkout .llms-price-wrapper { - margin: 20px; - text-size: 16px; -} + margin: 0 auto; } + .llms-checkout-wrapper .llms-checkout { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-top: 6px solid #e5554e; } + .llms-checkout-wrapper .llms-checkout > h4 { + background-color: #f5f5f5; + padding: 6px 10px; + margin: 0; } + .llms-checkout-wrapper .llms-checkout .llms-title-wrapper { + display: block; + width: 100%; + border-bottom: 2px solid #f5f5f5; } + .llms-checkout-wrapper .llms-checkout .llms-title-wrapper p { + padding: 0 10px; + margin: 10px 0; } + .llms-checkout-wrapper .llms-checkout .llms-title-wrapper h4 { + padding: 0 10px; + margin: 10px 0; } + .llms-checkout-wrapper .llms-checkout .llms-price-wrapper { + margin: 20px; + text-size: 16px; } .llms-option { display: block; position: relative; margin: 20px 0; padding-left: 40px; - font-size: 16px; -} -.llms-option label { - cursor: pointer; - position: static; -} + font-size: 16px; } + .llms-option label { + cursor: pointer; + position: static; } .llms-option:first-child { - margin-top: 0; -} + margin-top: 0; } .llms-option:last-child { - margin-bottom: 0; -} + margin-bottom: 0; } #main-content .llms-option:last-child { - margin-bottom: 0; -} + margin-bottom: 0; } .llms-option input[type="radio"] { display: block; position: absolute; top: 3px; left: 0; - z-index: 0; -} + z-index: 0; } .llms-option input[type="radio"] { - display: inline-block; -} + display: inline-block; } .llms-option input[type="radio"] + label span.llms-radio { - display: none; -} + display: none; } .llms-option input[type="radio"] + label span.llms-radio { appearance: none; @@ -670,25 +552,18 @@ h1, h2, h3, h4, h5, h6 { vertical-align: middle; box-shadow: rgba(255, 255, 255, 0.15) 0 1px 1px, inset rgba(0, 0, 0, 0.5) 0 0 0 1px; background: #efefef; - background-image: -webkit-radial-gradient(center, ellipse, #e5554e 0%, #e5554e 40%, #efefef 45%); background-image: radial-gradient(ellipse at center, #e5554e 0%, #e5554e 40%, #efefef 45%); background-repeat: no-repeat; - -webkit-transition: background-position 0.15s cubic-bezier(0.8, 0, 1, 1); - transition: background-position 0.15s cubic-bezier(0.8, 0, 1, 1); -} + transition: background-position 0.15s cubic-bezier(0.8, 0, 1, 1); } .llms-option input[type="radio"]:checked + label span.llms-radio { - -webkit-transition: background-position 0.2s 0.15s cubic-bezier(0, 0, 0.2, 1); - transition: background-position 0.2s 0.15s cubic-bezier(0, 0, 0.2, 1); -} + transition: background-position 0.2s 0.15s cubic-bezier(0, 0, 0.2, 1); } .llms-option input[type="radio"] + label span.llms-radio { - background-position: -24px 0; -} + background-position: -24px 0; } .llms-option input[type="radio"]:checked + label span.llms-radio { - background-position: 0 0; -} + background-position: 0 0; } .llms-option input[type="submit"] { border: none; @@ -698,12 +573,10 @@ h1, h2, h3, h4, h5, h6 { padding: 10px 0; border-radius: 3px; cursor: pointer; - width: 100%; -} + width: 100%; } .llms-styled-text { - padding: 14px 0; -} + padding: 14px 0; } .llms-notice-box { border-radius: 3px; @@ -714,64 +587,47 @@ h1, h2, h3, h4, h5, h6 { border: 1px solid #ccc; list-style-type: none; width: 100%; - overflow: auto; -} -.llms-notice-box input[type="text"] { - height: 35px; -} -.llms-notice-box .col-1-1 { - width: 100%; -} -.llms-notice-box .col-1-1 input[type=text] { - width: 100%; -} -.llms-notice-box .col-1-2 { - width: 50%; - float: left; -} -@media screen and (max-width: 768px) { + overflow: auto; } + .llms-notice-box input[type="text"] { + height: 35px; } + .llms-notice-box .col-1-1 { + width: 100%; } + .llms-notice-box .col-1-1 input[type=text] { + width: 100%; } .llms-notice-box .col-1-2 { - width: 100%; - } -} -.llms-notice-box .col-1-3 { - width: 33%; - float: left; - margin-right: 10px; -} -.llms-notice-box .col-1-4 { - width: 25%; - float: left; - margin-right: 10px; -} -@media screen and (max-width: 768px) { + width: 50%; + float: left; } + @media screen and (max-width: 768px) { + .llms-notice-box .col-1-2 { + width: 100%; } } + .llms-notice-box .col-1-3 { + width: 33%; + float: left; + margin-right: 10px; } .llms-notice-box .col-1-4 { - width: 100%; - } -} -.llms-notice-box .col-1-6 { - width: 16.6%; - float: left; - margin-right: 10px; -} -.llms-notice-box .col-1-8 { - width: 11%; - float: right; -} -.llms-notice-box .llms-pad-right { - padding-right: 10px; -} -@media screen and (max-width: 768px) { + width: 25%; + float: left; + margin-right: 10px; } + @media screen and (max-width: 768px) { + .llms-notice-box .col-1-4 { + width: 100%; } } + .llms-notice-box .col-1-6 { + width: 16.6%; + float: left; + margin-right: 10px; } + .llms-notice-box .col-1-8 { + width: 11%; + float: right; } .llms-notice-box .llms-pad-right { - padding-right: 0; - } -} + padding-right: 10px; } + @media screen and (max-width: 768px) { + .llms-notice-box .llms-pad-right { + padding-right: 0; } } #cc_cvv { margin-right: 0; width: 23%; - float: right; -} + float: right; } .llms-clear-box { border-radius: 3px; @@ -780,21 +636,17 @@ h1, h2, h3, h4, h5, h6 { padding: 15px 20px; list-style-type: none; width: 100%; - overflow: auto; -} + overflow: auto; } .llms-price-label { - font-weight: normal; -} + font-weight: normal; } .llms-final-price { font-weight: bold; - float: right; -} + float: right; } .llms-center-content { - text-align: center; -} + text-align: center; } .llms-input-text { background-color: #fff; @@ -803,73 +655,59 @@ h1, h2, h3, h4, h5, h6 { font-size: 18px; font-weight: 300; padding: 16px; - width: 100%; -} + width: 100%; } .llms-price { margin-bottom: 0; - font-weight: bold; -} + font-weight: bold; } .llms-price-loop { font-weight: .8em; margin-bottom: 0; - font-weight: bold; -} + font-weight: bold; } .courses .entry { - padding: 0; -} + padding: 0; } .list-view .site-content .llms-course-list .hentry, .list-view .site-content .llms-membership-list .hentry { border-top: 0; - padding-top: 0; -} + padding-top: 0; } .llms-content { - width: 100%; -} + width: 100%; } .llms-lesson-button-wrapper { width: 100%; display: block; clear: both; - text-align: center; -} + text-align: center; } .llms-template-wrapper { width: 100%; display: block; - clear: both; -} + clear: both; } .llms-button-wrapper { width: 100%; display: block; clear: both; - text-align: center; -} + text-align: center; } .courses a.llms-course-link:hover { - text-decoration: none; -} + text-decoration: none; } .llms-styled-select { border: 1px solid #ccc; - -moz-box-sizing: border-box; - box-sizing: border-box; + box-sizing: border-box; border-radius: 3px; overflow: hidden; - position: relative; -} + position: relative; } .llms-styled-select, .llms-styled-select select { - width: 100%; -} + width: 100%; } select:focus { - outline: none; -} + outline: none; } .llms-styled-select select { height: 34px; @@ -878,41 +716,33 @@ select:focus { border: none; -webkit-appearance: none; font-size: 16px; - color: #444444; -} + color: #444444; } @-moz-document url-prefix() { .--ms-styled-select select { - width: 110%; - } -} + width: 110%; } } .llms-styled-select .fa-sort-desc { position: absolute; top: 0; right: 12px; font-size: 24px; - color: #ccc; -} + color: #ccc; } select::-ms-expand { - display: none; -} + display: none; } _:-o-prefocus .llms-styled-select, .selector .llms-styled-select { - background: none; -} + background: none; } .llms-form-item-wrapper { - margin-bottom: 1em; -} + margin-bottom: 1em; } /* Circle Graph */ .llms-progress-circle { position: relative; width: 200px; height: 200px; - float: left; -} + float: left; } .llms-progress-circle-count { position: absolute; @@ -923,89 +753,155 @@ _:-o-prefocus .llms-styled-select, .selector .llms-styled-select { text-align: center; line-height: 50px; color: #666; - font-size: 44px; -} + font-size: 44px; } .llms-progress-circle svg { position: absolute; width: 200px; - height: 200px; -} + height: 200px; } .llms-progress-circle circle { - fill: transparent; -} + fill: transparent; } svg .llms-background-circle { fill: transparent; stroke-width: 10px; stroke: #f1f2f1; - stroke-dasharray: 430; -} + stroke-dasharray: 430; } svg .llms-animated-circle { fill: transparent; stroke-width: 10px; stroke: #e5554e; stroke-dasharray: 430; - stroke-dashoffset: 410; -} + stroke-dashoffset: 410; } .llms-quiz-result-details { - float: left; -} -.llms-quiz-result-details ul { - list-style-type: none; - float: left; -} -.llms-quiz-result-details ul li { - font-size: 20px; -} + float: left; } + .llms-quiz-result-details ul { + list-style-type: none; + float: left; } + .llms-quiz-result-details ul li { + font-size: 20px; } .llms-attempts { - font-weight: bold; -} + font-weight: bold; } .llms-pass-perc { - font-weight: bold; -} + font-weight: bold; } .llms-content-block { - margin: 6px 0; -} + margin: 6px 0; } .llms-widget-syllabus .llms-lesson-complete { size: 1.2em; margin-right: 6px; font-size: 1.2em; - color: #ccc; -} -.llms-widget-syllabus .llms-lesson-complete.done { - color: #e5554e; -} + color: #ccc; } + .llms-widget-syllabus .llms-lesson-complete.done { + color: #e5554e; } .llms-widget-syllabus .section-title { - font-weight: bold; -} + font-weight: bold; } .llms-widget-syllabus .lesson-title a { - text-decoration: none; -} -.llms-widget-syllabus .lesson-title a:hover { - text-decoration: none !important; -} + text-decoration: none; } + .llms-widget-syllabus .lesson-title a:hover { + text-decoration: none !important; } .llms-widget-syllabus .lesson-title.done a { color: #999; - text-decoration: line-through; -} + text-decoration: line-through; } .llms-widget-syllabus ul { - list-style-type: none; -} -.llms-widget-syllabus ul li { - list-style-type: none; -} -.llms-widget-syllabus ul li ul li { - margin: 0 0 2px 0; + list-style-type: none; } + .llms-widget-syllabus ul li { + list-style-type: none; } + .llms-widget-syllabus ul li ul li { + margin: 0 0 2px 0; + padding: 0; } + +.llms-question-wrapper { + margin: 40px 0 20px 0; } + +.llms-error { + width: 100%; + background: #e5554e; + padding: 10px 20px; + color: #fff; + border-radius: 5px; + margin-bottom: 10px; } + +.llms-question-count { + margin-bottom: 20px; } + +#llms-quiz-timer { + float: right; + width: 100%; + clear: both; } + +.countdown-label { + margin-top: 6px; + text-align: center; + display: inline-block; } + .countdown-label p { + color: #65584c; + letter-spacing: 2px; + text-transform: uppercase; + font-size: 12px; + font-weight: thin; + font-family: Arial; } + +#countdown { + box-shadow: 0 1px 2px 0 rgba(1, 1, 1, 0.4); + width: 240px; + height: 96px; + text-align: center; + background: #f1f1f1; + border-radius: 5px; + float: right; } + +#countdown #tiles { + color: #fff; + position: relative; + z-index: 1; + text-shadow: 1px 1px 0px #ccc; + display: inline-block; + font-family: Arial, sans-serif; + text-align: center; padding: 0; -} + border-radius: 5px 5px 0 0; + font-size: 48px; + font-weight: thin; + display: block; + line-height: 1.4; } + +.color-full { + background: #53bb74; } + +.color-half { + background: #ebc85d; } + +.color-empty { + background: #e5554e; } + +#countdown #tiles > span { + width: 70px; + max-width: 70px; + padding: 18px 0; + position: relative; } + +#countdown .labels { + width: 100%; + height: 25px; + text-align: center; + position: absolute; + bottom: 8px; } + +#countdown .labels li { + width: 102px; + font: bold 15px 'Droid Sans', Arial, sans-serif; + color: #f47321; + text-shadow: 1px 1px 0px #000; + text-align: center; + text-transform: uppercase; + display: inline-block; } /*! * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome @@ -1018,157 +914,126 @@ svg .llms-animated-circle { src: url("../fonts/fontawesome/fontawesome-webfont.eot?v=4.2.0"); src: url("../fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=4.2.0") format("embedded-opentype"), url("../fonts/fontawesome/fontawesome-webfont.woff?v=4.2.0") format("woff"), url("../fonts/fontawesome/fontawesome-webfont.ttf?v=4.2.0") format("truetype"), url("../fonts/fontawesome/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular") format("svg"); font-weight: normal; - font-style: normal; -} + font-style: normal; } .fa { display: inline-block; font: normal normal normal 14px/1 FontAwesome; font-size: inherit; text-rendering: auto; -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} + -moz-osx-font-smoothing: grayscale; } /* makes the font 33% larger relative to the icon container */ .fa-lg { font-size: 1.33333333em; line-height: 0.75em; - vertical-align: -15%; -} + vertical-align: -15%; } .fa-2x { - font-size: 2em; -} + font-size: 2em; } .fa-3x { - font-size: 3em; -} + font-size: 3em; } .fa-4x { - font-size: 4em; -} + font-size: 4em; } .fa-5x { - font-size: 5em; -} + font-size: 5em; } .fa-fw { width: 1.28571429em; - text-align: center; -} + text-align: center; } .fa-ul { padding-left: 0; margin-left: 2.14285714em; - list-style-type: none; -} + list-style-type: none; } .fa-ul > li { - position: relative; -} + position: relative; } .fa-li { position: absolute; left: -2.14285714em; width: 2.14285714em; top: 0.14285714em; - text-align: center; -} + text-align: center; } .fa-li.fa-lg { - left: -1.85714286em; -} + left: -1.85714286em; } .fa-border { padding: .2em .25em .15em; border: solid 0.08em #eeeeee; - border-radius: .1em; -} + border-radius: .1em; } .pull-right { - float: right; -} + float: right; } .pull-left { - float: left; -} + float: left; } .fa.pull-left { - margin-right: .3em; -} + margin-right: .3em; } .fa.pull-right { - margin-left: .3em; -} + margin-left: .3em; } .fa-spin { -webkit-animation: fa-spin 2s infinite linear; - animation: fa-spin 2s infinite linear; -} + animation: fa-spin 2s infinite linear; } @-webkit-keyframes fa-spin { 0% { -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } + transform: rotate(0deg); } 100% { -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} + transform: rotate(359deg); } } @keyframes fa-spin { 0% { -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } + transform: rotate(0deg); } 100% { -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} + transform: rotate(359deg); } } .fa-rotate-90 { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); -webkit-transform: rotate(90deg); -ms-transform: rotate(90deg); - transform: rotate(90deg); -} + transform: rotate(90deg); } .fa-rotate-180 { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); -webkit-transform: rotate(180deg); -ms-transform: rotate(180deg); - transform: rotate(180deg); -} + transform: rotate(180deg); } .fa-rotate-270 { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); -webkit-transform: rotate(270deg); -ms-transform: rotate(270deg); - transform: rotate(270deg); -} + transform: rotate(270deg); } .fa-flip-horizontal { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); -webkit-transform: scale(-1, 1); -ms-transform: scale(-1, 1); - transform: scale(-1, 1); -} + transform: scale(-1, 1); } .fa-flip-vertical { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); -webkit-transform: scale(1, -1); -ms-transform: scale(1, -1); - transform: scale(1, -1); -} + transform: scale(1, -1); } :root .fa-rotate-90, :root .fa-rotate-180, :root .fa-rotate-270, :root .fa-flip-horizontal, :root .fa-flip-vertical { - -webkit-filter: none; - filter: none; -} + filter: none; } .fa-stack { position: relative; @@ -1176,2013 +1041,1529 @@ svg .llms-animated-circle { width: 2em; height: 2em; line-height: 2em; - vertical-align: middle; -} + vertical-align: middle; } .fa-stack-1x, .fa-stack-2x { position: absolute; left: 0; width: 100%; - text-align: center; -} + text-align: center; } .fa-stack-1x { - line-height: inherit; -} + line-height: inherit; } .fa-stack-2x { - font-size: 2em; -} + font-size: 2em; } .fa-inverse { - color: #ffffff; -} + color: #ffffff; } /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen readers do not read off random characters that represent icons */ .fa-glass:before { - content: "\f000"; -} + content: "\f000"; } .fa-music:before { - content: "\f001"; -} + content: "\f001"; } .fa-search:before { - content: "\f002"; -} + content: "\f002"; } .fa-envelope-o:before { - content: "\f003"; -} + content: "\f003"; } .fa-heart:before { - content: "\f004"; -} + content: "\f004"; } .fa-star:before { - content: "\f005"; -} + content: "\f005"; } .fa-star-o:before { - content: "\f006"; -} + content: "\f006"; } .fa-user:before { - content: "\f007"; -} + content: "\f007"; } .fa-film:before { - content: "\f008"; -} + content: "\f008"; } .fa-th-large:before { - content: "\f009"; -} + content: "\f009"; } .fa-th:before { - content: "\f00a"; -} + content: "\f00a"; } .fa-th-list:before { - content: "\f00b"; -} + content: "\f00b"; } .fa-check:before { - content: "\f00c"; -} + content: "\f00c"; } .fa-remove:before, .fa-close:before, .fa-times:before { - content: "\f00d"; -} + content: "\f00d"; } .fa-search-plus:before { - content: "\f00e"; -} + content: "\f00e"; } .fa-search-minus:before { - content: "\f010"; -} + content: "\f010"; } .fa-power-off:before { - content: "\f011"; -} + content: "\f011"; } .fa-signal:before { - content: "\f012"; -} + content: "\f012"; } .fa-gear:before, .fa-cog:before { - content: "\f013"; -} + content: "\f013"; } .fa-trash-o:before { - content: "\f014"; -} + content: "\f014"; } .fa-home:before { - content: "\f015"; -} + content: "\f015"; } .fa-file-o:before { - content: "\f016"; -} + content: "\f016"; } .fa-clock-o:before { - content: "\f017"; -} + content: "\f017"; } .fa-road:before { - content: "\f018"; -} + content: "\f018"; } .fa-download:before { - content: "\f019"; -} + content: "\f019"; } .fa-arrow-circle-o-down:before { - content: "\f01a"; -} + content: "\f01a"; } .fa-arrow-circle-o-up:before { - content: "\f01b"; -} + content: "\f01b"; } .fa-inbox:before { - content: "\f01c"; -} + content: "\f01c"; } .fa-play-circle-o:before { - content: "\f01d"; -} + content: "\f01d"; } .fa-rotate-right:before, .fa-repeat:before { - content: "\f01e"; -} + content: "\f01e"; } .fa-refresh:before { - content: "\f021"; -} + content: "\f021"; } .fa-list-alt:before { - content: "\f022"; -} + content: "\f022"; } .fa-lock:before { - content: "\f023"; -} + content: "\f023"; } .fa-flag:before { - content: "\f024"; -} + content: "\f024"; } .fa-headphones:before { - content: "\f025"; -} + content: "\f025"; } .fa-volume-off:before { - content: "\f026"; -} + content: "\f026"; } .fa-volume-down:before { - content: "\f027"; -} + content: "\f027"; } .fa-volume-up:before { - content: "\f028"; -} + content: "\f028"; } .fa-qrcode:before { - content: "\f029"; -} + content: "\f029"; } .fa-barcode:before { - content: "\f02a"; -} + content: "\f02a"; } .fa-tag:before { - content: "\f02b"; -} + content: "\f02b"; } .fa-tags:before { - content: "\f02c"; -} + content: "\f02c"; } .fa-book:before { - content: "\f02d"; -} + content: "\f02d"; } .fa-bookmark:before { - content: "\f02e"; -} + content: "\f02e"; } .fa-print:before { - content: "\f02f"; -} + content: "\f02f"; } .fa-camera:before { - content: "\f030"; -} + content: "\f030"; } .fa-font:before { - content: "\f031"; -} + content: "\f031"; } .fa-bold:before { - content: "\f032"; -} + content: "\f032"; } .fa-italic:before { - content: "\f033"; -} + content: "\f033"; } .fa-text-height:before { - content: "\f034"; -} + content: "\f034"; } .fa-text-width:before { - content: "\f035"; -} + content: "\f035"; } .fa-align-left:before { - content: "\f036"; -} + content: "\f036"; } .fa-align-center:before { - content: "\f037"; -} + content: "\f037"; } .fa-align-right:before { - content: "\f038"; -} + content: "\f038"; } .fa-align-justify:before { - content: "\f039"; -} + content: "\f039"; } .fa-list:before { - content: "\f03a"; -} + content: "\f03a"; } .fa-dedent:before, .fa-outdent:before { - content: "\f03b"; -} + content: "\f03b"; } .fa-indent:before { - content: "\f03c"; -} + content: "\f03c"; } .fa-video-camera:before { - content: "\f03d"; -} + content: "\f03d"; } .fa-photo:before, .fa-image:before, .fa-picture-o:before { - content: "\f03e"; -} + content: "\f03e"; } .fa-pencil:before { - content: "\f040"; -} + content: "\f040"; } .fa-map-marker:before { - content: "\f041"; -} + content: "\f041"; } .fa-adjust:before { - content: "\f042"; -} + content: "\f042"; } .fa-tint:before { - content: "\f043"; -} + content: "\f043"; } .fa-edit:before, .fa-pencil-square-o:before { - content: "\f044"; -} + content: "\f044"; } .fa-share-square-o:before { - content: "\f045"; -} + content: "\f045"; } .fa-check-square-o:before { - content: "\f046"; -} + content: "\f046"; } .fa-arrows:before { - content: "\f047"; -} + content: "\f047"; } .fa-step-backward:before { - content: "\f048"; -} + content: "\f048"; } .fa-fast-backward:before { - content: "\f049"; -} + content: "\f049"; } .fa-backward:before { - content: "\f04a"; -} + content: "\f04a"; } .fa-play:before { - content: "\f04b"; -} + content: "\f04b"; } .fa-pause:before { - content: "\f04c"; -} + content: "\f04c"; } .fa-stop:before { - content: "\f04d"; -} + content: "\f04d"; } .fa-forward:before { - content: "\f04e"; -} + content: "\f04e"; } .fa-fast-forward:before { - content: "\f050"; -} + content: "\f050"; } .fa-step-forward:before { - content: "\f051"; -} + content: "\f051"; } .fa-eject:before { - content: "\f052"; -} + content: "\f052"; } .fa-chevron-left:before { - content: "\f053"; -} + content: "\f053"; } .fa-chevron-right:before { - content: "\f054"; -} + content: "\f054"; } .fa-plus-circle:before { - content: "\f055"; -} + content: "\f055"; } .fa-minus-circle:before { - content: "\f056"; -} + content: "\f056"; } .fa-times-circle:before { - content: "\f057"; -} + content: "\f057"; } .fa-check-circle:before { - content: "\f058"; -} + content: "\f058"; } .fa-question-circle:before { - content: "\f059"; -} + content: "\f059"; } .fa-info-circle:before { - content: "\f05a"; -} + content: "\f05a"; } .fa-crosshairs:before { - content: "\f05b"; -} + content: "\f05b"; } .fa-times-circle-o:before { - content: "\f05c"; -} + content: "\f05c"; } .fa-check-circle-o:before { - content: "\f05d"; -} + content: "\f05d"; } .fa-ban:before { - content: "\f05e"; -} + content: "\f05e"; } .fa-arrow-left:before { - content: "\f060"; -} + content: "\f060"; } .fa-arrow-right:before { - content: "\f061"; -} + content: "\f061"; } .fa-arrow-up:before { - content: "\f062"; -} + content: "\f062"; } .fa-arrow-down:before { - content: "\f063"; -} + content: "\f063"; } .fa-mail-forward:before, .fa-share:before { - content: "\f064"; -} + content: "\f064"; } .fa-expand:before { - content: "\f065"; -} + content: "\f065"; } .fa-compress:before { - content: "\f066"; -} + content: "\f066"; } .fa-plus:before { - content: "\f067"; -} + content: "\f067"; } .fa-minus:before { - content: "\f068"; -} + content: "\f068"; } .fa-asterisk:before { - content: "\f069"; -} + content: "\f069"; } .fa-exclamation-circle:before { - content: "\f06a"; -} + content: "\f06a"; } .fa-gift:before { - content: "\f06b"; -} + content: "\f06b"; } .fa-leaf:before { - content: "\f06c"; -} + content: "\f06c"; } .fa-fire:before { - content: "\f06d"; -} + content: "\f06d"; } .fa-eye:before { - content: "\f06e"; -} + content: "\f06e"; } .fa-eye-slash:before { - content: "\f070"; -} + content: "\f070"; } .fa-warning:before, .fa-exclamation-triangle:before { - content: "\f071"; -} + content: "\f071"; } .fa-plane:before { - content: "\f072"; -} + content: "\f072"; } .fa-calendar:before { - content: "\f073"; -} + content: "\f073"; } .fa-random:before { - content: "\f074"; -} + content: "\f074"; } .fa-comment:before { - content: "\f075"; -} + content: "\f075"; } .fa-magnet:before { - content: "\f076"; -} + content: "\f076"; } .fa-chevron-up:before { - content: "\f077"; -} + content: "\f077"; } .fa-chevron-down:before { - content: "\f078"; -} + content: "\f078"; } .fa-retweet:before { - content: "\f079"; -} + content: "\f079"; } .fa-shopping-cart:before { - content: "\f07a"; -} + content: "\f07a"; } .fa-folder:before { - content: "\f07b"; -} + content: "\f07b"; } .fa-folder-open:before { - content: "\f07c"; -} + content: "\f07c"; } .fa-arrows-v:before { - content: "\f07d"; -} + content: "\f07d"; } .fa-arrows-h:before { - content: "\f07e"; -} + content: "\f07e"; } .fa-bar-chart-o:before, .fa-bar-chart:before { - content: "\f080"; -} + content: "\f080"; } .fa-twitter-square:before { - content: "\f081"; -} + content: "\f081"; } .fa-facebook-square:before { - content: "\f082"; -} + content: "\f082"; } .fa-camera-retro:before { - content: "\f083"; -} + content: "\f083"; } .fa-key:before { - content: "\f084"; -} + content: "\f084"; } .fa-gears:before, .fa-cogs:before { - content: "\f085"; -} + content: "\f085"; } .fa-comments:before { - content: "\f086"; -} + content: "\f086"; } .fa-thumbs-o-up:before { - content: "\f087"; -} + content: "\f087"; } .fa-thumbs-o-down:before { - content: "\f088"; -} + content: "\f088"; } .fa-star-half:before { - content: "\f089"; -} + content: "\f089"; } .fa-heart-o:before { - content: "\f08a"; -} + content: "\f08a"; } .fa-sign-out:before { - content: "\f08b"; -} + content: "\f08b"; } .fa-linkedin-square:before { - content: "\f08c"; -} + content: "\f08c"; } .fa-thumb-tack:before { - content: "\f08d"; -} + content: "\f08d"; } .fa-external-link:before { - content: "\f08e"; -} + content: "\f08e"; } .fa-sign-in:before { - content: "\f090"; -} + content: "\f090"; } .fa-trophy:before { - content: "\f091"; -} + content: "\f091"; } .fa-github-square:before { - content: "\f092"; -} + content: "\f092"; } .fa-upload:before { - content: "\f093"; -} + content: "\f093"; } .fa-lemon-o:before { - content: "\f094"; -} + content: "\f094"; } .fa-phone:before { - content: "\f095"; -} + content: "\f095"; } .fa-square-o:before { - content: "\f096"; -} + content: "\f096"; } .fa-bookmark-o:before { - content: "\f097"; -} + content: "\f097"; } .fa-phone-square:before { - content: "\f098"; -} + content: "\f098"; } .fa-twitter:before { - content: "\f099"; -} + content: "\f099"; } .fa-facebook:before { - content: "\f09a"; -} + content: "\f09a"; } .fa-github:before { - content: "\f09b"; -} + content: "\f09b"; } .fa-unlock:before { - content: "\f09c"; -} + content: "\f09c"; } .fa-credit-card:before { - content: "\f09d"; -} + content: "\f09d"; } .fa-rss:before { - content: "\f09e"; -} + content: "\f09e"; } .fa-hdd-o:before { - content: "\f0a0"; -} + content: "\f0a0"; } .fa-bullhorn:before { - content: "\f0a1"; -} + content: "\f0a1"; } .fa-bell:before { - content: "\f0f3"; -} + content: "\f0f3"; } .fa-certificate:before { - content: "\f0a3"; -} + content: "\f0a3"; } .fa-hand-o-right:before { - content: "\f0a4"; -} + content: "\f0a4"; } .fa-hand-o-left:before { - content: "\f0a5"; -} + content: "\f0a5"; } .fa-hand-o-up:before { - content: "\f0a6"; -} + content: "\f0a6"; } .fa-hand-o-down:before { - content: "\f0a7"; -} + content: "\f0a7"; } .fa-arrow-circle-left:before { - content: "\f0a8"; -} + content: "\f0a8"; } .fa-arrow-circle-right:before { - content: "\f0a9"; -} + content: "\f0a9"; } .fa-arrow-circle-up:before { - content: "\f0aa"; -} + content: "\f0aa"; } .fa-arrow-circle-down:before { - content: "\f0ab"; -} + content: "\f0ab"; } .fa-globe:before { - content: "\f0ac"; -} + content: "\f0ac"; } .fa-wrench:before { - content: "\f0ad"; -} + content: "\f0ad"; } .fa-tasks:before { - content: "\f0ae"; -} + content: "\f0ae"; } .fa-filter:before { - content: "\f0b0"; -} + content: "\f0b0"; } .fa-briefcase:before { - content: "\f0b1"; -} + content: "\f0b1"; } .fa-arrows-alt:before { - content: "\f0b2"; -} + content: "\f0b2"; } .fa-group:before, .fa-users:before { - content: "\f0c0"; -} + content: "\f0c0"; } .fa-chain:before, .fa-link:before { - content: "\f0c1"; -} + content: "\f0c1"; } .fa-cloud:before { - content: "\f0c2"; -} + content: "\f0c2"; } .fa-flask:before { - content: "\f0c3"; -} + content: "\f0c3"; } .fa-cut:before, .fa-scissors:before { - content: "\f0c4"; -} + content: "\f0c4"; } .fa-copy:before, .fa-files-o:before { - content: "\f0c5"; -} + content: "\f0c5"; } .fa-paperclip:before { - content: "\f0c6"; -} + content: "\f0c6"; } .fa-save:before, .fa-floppy-o:before { - content: "\f0c7"; -} + content: "\f0c7"; } .fa-square:before { - content: "\f0c8"; -} + content: "\f0c8"; } .fa-navicon:before, .fa-reorder:before, .fa-bars:before { - content: "\f0c9"; -} + content: "\f0c9"; } .fa-list-ul:before { - content: "\f0ca"; -} + content: "\f0ca"; } .fa-list-ol:before { - content: "\f0cb"; -} + content: "\f0cb"; } .fa-strikethrough:before { - content: "\f0cc"; -} + content: "\f0cc"; } .fa-underline:before { - content: "\f0cd"; -} + content: "\f0cd"; } .fa-table:before { - content: "\f0ce"; -} + content: "\f0ce"; } .fa-magic:before { - content: "\f0d0"; -} + content: "\f0d0"; } .fa-truck:before { - content: "\f0d1"; -} + content: "\f0d1"; } .fa-pinterest:before { - content: "\f0d2"; -} + content: "\f0d2"; } .fa-pinterest-square:before { - content: "\f0d3"; -} + content: "\f0d3"; } .fa-google-plus-square:before { - content: "\f0d4"; -} + content: "\f0d4"; } .fa-google-plus:before { - content: "\f0d5"; -} + content: "\f0d5"; } .fa-money:before { - content: "\f0d6"; -} + content: "\f0d6"; } .fa-caret-down:before { - content: "\f0d7"; -} + content: "\f0d7"; } .fa-caret-up:before { - content: "\f0d8"; -} + content: "\f0d8"; } .fa-caret-left:before { - content: "\f0d9"; -} + content: "\f0d9"; } .fa-caret-right:before { - content: "\f0da"; -} + content: "\f0da"; } .fa-columns:before { - content: "\f0db"; -} + content: "\f0db"; } .fa-unsorted:before, .fa-sort:before { - content: "\f0dc"; -} + content: "\f0dc"; } .fa-sort-down:before, .fa-sort-desc:before { - content: "\f0dd"; -} + content: "\f0dd"; } .fa-sort-up:before, .fa-sort-asc:before { - content: "\f0de"; -} + content: "\f0de"; } .fa-envelope:before { - content: "\f0e0"; -} + content: "\f0e0"; } .fa-linkedin:before { - content: "\f0e1"; -} + content: "\f0e1"; } .fa-rotate-left:before, .fa-undo:before { - content: "\f0e2"; -} + content: "\f0e2"; } .fa-legal:before, .fa-gavel:before { - content: "\f0e3"; -} + content: "\f0e3"; } .fa-dashboard:before, .fa-tachometer:before { - content: "\f0e4"; -} + content: "\f0e4"; } .fa-comment-o:before { - content: "\f0e5"; -} + content: "\f0e5"; } .fa-comments-o:before { - content: "\f0e6"; -} + content: "\f0e6"; } .fa-flash:before, .fa-bolt:before { - content: "\f0e7"; -} + content: "\f0e7"; } .fa-sitemap:before { - content: "\f0e8"; -} + content: "\f0e8"; } .fa-umbrella:before { - content: "\f0e9"; -} + content: "\f0e9"; } .fa-paste:before, .fa-clipboard:before { - content: "\f0ea"; -} + content: "\f0ea"; } .fa-lightbulb-o:before { - content: "\f0eb"; -} + content: "\f0eb"; } .fa-exchange:before { - content: "\f0ec"; -} + content: "\f0ec"; } .fa-cloud-download:before { - content: "\f0ed"; -} + content: "\f0ed"; } .fa-cloud-upload:before { - content: "\f0ee"; -} + content: "\f0ee"; } .fa-user-md:before { - content: "\f0f0"; -} + content: "\f0f0"; } .fa-stethoscope:before { - content: "\f0f1"; -} + content: "\f0f1"; } .fa-suitcase:before { - content: "\f0f2"; -} + content: "\f0f2"; } .fa-bell-o:before { - content: "\f0a2"; -} + content: "\f0a2"; } .fa-coffee:before { - content: "\f0f4"; -} + content: "\f0f4"; } .fa-cutlery:before { - content: "\f0f5"; -} + content: "\f0f5"; } .fa-file-text-o:before { - content: "\f0f6"; -} + content: "\f0f6"; } .fa-building-o:before { - content: "\f0f7"; -} + content: "\f0f7"; } .fa-hospital-o:before { - content: "\f0f8"; -} + content: "\f0f8"; } .fa-ambulance:before { - content: "\f0f9"; -} + content: "\f0f9"; } .fa-medkit:before { - content: "\f0fa"; -} + content: "\f0fa"; } .fa-fighter-jet:before { - content: "\f0fb"; -} + content: "\f0fb"; } .fa-beer:before { - content: "\f0fc"; -} + content: "\f0fc"; } .fa-h-square:before { - content: "\f0fd"; -} + content: "\f0fd"; } .fa-plus-square:before { - content: "\f0fe"; -} + content: "\f0fe"; } .fa-angle-double-left:before { - content: "\f100"; -} + content: "\f100"; } .fa-angle-double-right:before { - content: "\f101"; -} + content: "\f101"; } .fa-angle-double-up:before { - content: "\f102"; -} + content: "\f102"; } .fa-angle-double-down:before { - content: "\f103"; -} + content: "\f103"; } .fa-angle-left:before { - content: "\f104"; -} + content: "\f104"; } .fa-angle-right:before { - content: "\f105"; -} + content: "\f105"; } .fa-angle-up:before { - content: "\f106"; -} + content: "\f106"; } .fa-angle-down:before { - content: "\f107"; -} + content: "\f107"; } .fa-desktop:before { - content: "\f108"; -} + content: "\f108"; } .fa-laptop:before { - content: "\f109"; -} + content: "\f109"; } .fa-tablet:before { - content: "\f10a"; -} + content: "\f10a"; } .fa-mobile-phone:before, .fa-mobile:before { - content: "\f10b"; -} + content: "\f10b"; } .fa-circle-o:before { - content: "\f10c"; -} + content: "\f10c"; } .fa-quote-left:before { - content: "\f10d"; -} + content: "\f10d"; } .fa-quote-right:before { - content: "\f10e"; -} + content: "\f10e"; } .fa-spinner:before { - content: "\f110"; -} + content: "\f110"; } .fa-circle:before { - content: "\f111"; -} + content: "\f111"; } .fa-mail-reply:before, .fa-reply:before { - content: "\f112"; -} + content: "\f112"; } .fa-github-alt:before { - content: "\f113"; -} + content: "\f113"; } .fa-folder-o:before { - content: "\f114"; -} + content: "\f114"; } .fa-folder-open-o:before { - content: "\f115"; -} + content: "\f115"; } .fa-smile-o:before { - content: "\f118"; -} + content: "\f118"; } .fa-frown-o:before { - content: "\f119"; -} + content: "\f119"; } .fa-meh-o:before { - content: "\f11a"; -} + content: "\f11a"; } .fa-gamepad:before { - content: "\f11b"; -} + content: "\f11b"; } .fa-keyboard-o:before { - content: "\f11c"; -} + content: "\f11c"; } .fa-flag-o:before { - content: "\f11d"; -} + content: "\f11d"; } .fa-flag-checkered:before { - content: "\f11e"; -} + content: "\f11e"; } .fa-terminal:before { - content: "\f120"; -} + content: "\f120"; } .fa-code:before { - content: "\f121"; -} + content: "\f121"; } .fa-mail-reply-all:before, .fa-reply-all:before { - content: "\f122"; -} + content: "\f122"; } .fa-star-half-empty:before, .fa-star-half-full:before, .fa-star-half-o:before { - content: "\f123"; -} + content: "\f123"; } .fa-location-arrow:before { - content: "\f124"; -} + content: "\f124"; } .fa-crop:before { - content: "\f125"; -} + content: "\f125"; } .fa-code-fork:before { - content: "\f126"; -} + content: "\f126"; } .fa-unlink:before, .fa-chain-broken:before { - content: "\f127"; -} + content: "\f127"; } .fa-question:before { - content: "\f128"; -} + content: "\f128"; } .fa-info:before { - content: "\f129"; -} + content: "\f129"; } .fa-exclamation:before { - content: "\f12a"; -} + content: "\f12a"; } .fa-superscript:before { - content: "\f12b"; -} + content: "\f12b"; } .fa-subscript:before { - content: "\f12c"; -} + content: "\f12c"; } .fa-eraser:before { - content: "\f12d"; -} + content: "\f12d"; } .fa-puzzle-piece:before { - content: "\f12e"; -} + content: "\f12e"; } .fa-microphone:before { - content: "\f130"; -} + content: "\f130"; } .fa-microphone-slash:before { - content: "\f131"; -} + content: "\f131"; } .fa-shield:before { - content: "\f132"; -} + content: "\f132"; } .fa-calendar-o:before { - content: "\f133"; -} + content: "\f133"; } .fa-fire-extinguisher:before { - content: "\f134"; -} + content: "\f134"; } .fa-rocket:before { - content: "\f135"; -} + content: "\f135"; } .fa-maxcdn:before { - content: "\f136"; -} + content: "\f136"; } .fa-chevron-circle-left:before { - content: "\f137"; -} + content: "\f137"; } .fa-chevron-circle-right:before { - content: "\f138"; -} + content: "\f138"; } .fa-chevron-circle-up:before { - content: "\f139"; -} + content: "\f139"; } .fa-chevron-circle-down:before { - content: "\f13a"; -} + content: "\f13a"; } .fa-html5:before { - content: "\f13b"; -} + content: "\f13b"; } .fa-css3:before { - content: "\f13c"; -} + content: "\f13c"; } .fa-anchor:before { - content: "\f13d"; -} + content: "\f13d"; } .fa-unlock-alt:before { - content: "\f13e"; -} + content: "\f13e"; } .fa-bullseye:before { - content: "\f140"; -} + content: "\f140"; } .fa-ellipsis-h:before { - content: "\f141"; -} + content: "\f141"; } .fa-ellipsis-v:before { - content: "\f142"; -} + content: "\f142"; } .fa-rss-square:before { - content: "\f143"; -} + content: "\f143"; } .fa-play-circle:before { - content: "\f144"; -} + content: "\f144"; } .fa-ticket:before { - content: "\f145"; -} + content: "\f145"; } .fa-minus-square:before { - content: "\f146"; -} + content: "\f146"; } .fa-minus-square-o:before { - content: "\f147"; -} + content: "\f147"; } .fa-level-up:before { - content: "\f148"; -} + content: "\f148"; } .fa-level-down:before { - content: "\f149"; -} + content: "\f149"; } .fa-check-square:before { - content: "\f14a"; -} + content: "\f14a"; } .fa-pencil-square:before { - content: "\f14b"; -} + content: "\f14b"; } .fa-external-link-square:before { - content: "\f14c"; -} + content: "\f14c"; } .fa-share-square:before { - content: "\f14d"; -} + content: "\f14d"; } .fa-compass:before { - content: "\f14e"; -} + content: "\f14e"; } .fa-toggle-down:before, .fa-caret-square-o-down:before { - content: "\f150"; -} + content: "\f150"; } .fa-toggle-up:before, .fa-caret-square-o-up:before { - content: "\f151"; -} + content: "\f151"; } .fa-toggle-right:before, .fa-caret-square-o-right:before { - content: "\f152"; -} + content: "\f152"; } .fa-euro:before, .fa-eur:before { - content: "\f153"; -} + content: "\f153"; } .fa-gbp:before { - content: "\f154"; -} + content: "\f154"; } .fa-dollar:before, .fa-usd:before { - content: "\f155"; -} + content: "\f155"; } .fa-rupee:before, .fa-inr:before { - content: "\f156"; -} + content: "\f156"; } .fa-cny:before, .fa-rmb:before, .fa-yen:before, .fa-jpy:before { - content: "\f157"; -} + content: "\f157"; } .fa-ruble:before, .fa-rouble:before, .fa-rub:before { - content: "\f158"; -} + content: "\f158"; } .fa-won:before, .fa-krw:before { - content: "\f159"; -} + content: "\f159"; } .fa-bitcoin:before, .fa-btc:before { - content: "\f15a"; -} + content: "\f15a"; } .fa-file:before { - content: "\f15b"; -} + content: "\f15b"; } .fa-file-text:before { - content: "\f15c"; -} + content: "\f15c"; } .fa-sort-alpha-asc:before { - content: "\f15d"; -} + content: "\f15d"; } .fa-sort-alpha-desc:before { - content: "\f15e"; -} + content: "\f15e"; } .fa-sort-amount-asc:before { - content: "\f160"; -} + content: "\f160"; } .fa-sort-amount-desc:before { - content: "\f161"; -} + content: "\f161"; } .fa-sort-numeric-asc:before { - content: "\f162"; -} + content: "\f162"; } .fa-sort-numeric-desc:before { - content: "\f163"; -} + content: "\f163"; } .fa-thumbs-up:before { - content: "\f164"; -} + content: "\f164"; } .fa-thumbs-down:before { - content: "\f165"; -} + content: "\f165"; } .fa-youtube-square:before { - content: "\f166"; -} + content: "\f166"; } .fa-youtube:before { - content: "\f167"; -} + content: "\f167"; } .fa-xing:before { - content: "\f168"; -} + content: "\f168"; } .fa-xing-square:before { - content: "\f169"; -} + content: "\f169"; } .fa-youtube-play:before { - content: "\f16a"; -} + content: "\f16a"; } .fa-dropbox:before { - content: "\f16b"; -} + content: "\f16b"; } .fa-stack-overflow:before { - content: "\f16c"; -} + content: "\f16c"; } .fa-instagram:before { - content: "\f16d"; -} + content: "\f16d"; } .fa-flickr:before { - content: "\f16e"; -} + content: "\f16e"; } .fa-adn:before { - content: "\f170"; -} + content: "\f170"; } .fa-bitbucket:before { - content: "\f171"; -} + content: "\f171"; } .fa-bitbucket-square:before { - content: "\f172"; -} + content: "\f172"; } .fa-tumblr:before { - content: "\f173"; -} + content: "\f173"; } .fa-tumblr-square:before { - content: "\f174"; -} + content: "\f174"; } .fa-long-arrow-down:before { - content: "\f175"; -} + content: "\f175"; } .fa-long-arrow-up:before { - content: "\f176"; -} + content: "\f176"; } .fa-long-arrow-left:before { - content: "\f177"; -} + content: "\f177"; } .fa-long-arrow-right:before { - content: "\f178"; -} + content: "\f178"; } .fa-apple:before { - content: "\f179"; -} + content: "\f179"; } .fa-windows:before { - content: "\f17a"; -} + content: "\f17a"; } .fa-android:before { - content: "\f17b"; -} + content: "\f17b"; } .fa-linux:before { - content: "\f17c"; -} + content: "\f17c"; } .fa-dribbble:before { - content: "\f17d"; -} + content: "\f17d"; } .fa-skype:before { - content: "\f17e"; -} + content: "\f17e"; } .fa-foursquare:before { - content: "\f180"; -} + content: "\f180"; } .fa-trello:before { - content: "\f181"; -} + content: "\f181"; } .fa-female:before { - content: "\f182"; -} + content: "\f182"; } .fa-male:before { - content: "\f183"; -} + content: "\f183"; } .fa-gittip:before { - content: "\f184"; -} + content: "\f184"; } .fa-sun-o:before { - content: "\f185"; -} + content: "\f185"; } .fa-moon-o:before { - content: "\f186"; -} + content: "\f186"; } .fa-archive:before { - content: "\f187"; -} + content: "\f187"; } .fa-bug:before { - content: "\f188"; -} + content: "\f188"; } .fa-vk:before { - content: "\f189"; -} + content: "\f189"; } .fa-weibo:before { - content: "\f18a"; -} + content: "\f18a"; } .fa-renren:before { - content: "\f18b"; -} + content: "\f18b"; } .fa-pagelines:before { - content: "\f18c"; -} + content: "\f18c"; } .fa-stack-exchange:before { - content: "\f18d"; -} + content: "\f18d"; } .fa-arrow-circle-o-right:before { - content: "\f18e"; -} + content: "\f18e"; } .fa-arrow-circle-o-left:before { - content: "\f190"; -} + content: "\f190"; } .fa-toggle-left:before, .fa-caret-square-o-left:before { - content: "\f191"; -} + content: "\f191"; } .fa-dot-circle-o:before { - content: "\f192"; -} + content: "\f192"; } .fa-wheelchair:before { - content: "\f193"; -} + content: "\f193"; } .fa-vimeo-square:before { - content: "\f194"; -} + content: "\f194"; } .fa-turkish-lira:before, .fa-try:before { - content: "\f195"; -} + content: "\f195"; } .fa-plus-square-o:before { - content: "\f196"; -} + content: "\f196"; } .fa-space-shuttle:before { - content: "\f197"; -} + content: "\f197"; } .fa-slack:before { - content: "\f198"; -} + content: "\f198"; } .fa-envelope-square:before { - content: "\f199"; -} + content: "\f199"; } .fa-wordpress:before { - content: "\f19a"; -} + content: "\f19a"; } .fa-openid:before { - content: "\f19b"; -} + content: "\f19b"; } .fa-institution:before, .fa-bank:before, .fa-university:before { - content: "\f19c"; -} + content: "\f19c"; } .fa-mortar-board:before, .fa-graduation-cap:before { - content: "\f19d"; -} + content: "\f19d"; } .fa-yahoo:before { - content: "\f19e"; -} + content: "\f19e"; } .fa-google:before { - content: "\f1a0"; -} + content: "\f1a0"; } .fa-reddit:before { - content: "\f1a1"; -} + content: "\f1a1"; } .fa-reddit-square:before { - content: "\f1a2"; -} + content: "\f1a2"; } .fa-stumbleupon-circle:before { - content: "\f1a3"; -} + content: "\f1a3"; } .fa-stumbleupon:before { - content: "\f1a4"; -} + content: "\f1a4"; } .fa-delicious:before { - content: "\f1a5"; -} + content: "\f1a5"; } .fa-digg:before { - content: "\f1a6"; -} + content: "\f1a6"; } .fa-pied-piper:before { - content: "\f1a7"; -} + content: "\f1a7"; } .fa-pied-piper-alt:before { - content: "\f1a8"; -} + content: "\f1a8"; } .fa-drupal:before { - content: "\f1a9"; -} + content: "\f1a9"; } .fa-joomla:before { - content: "\f1aa"; -} + content: "\f1aa"; } .fa-language:before { - content: "\f1ab"; -} + content: "\f1ab"; } .fa-fax:before { - content: "\f1ac"; -} + content: "\f1ac"; } .fa-building:before { - content: "\f1ad"; -} + content: "\f1ad"; } .fa-child:before { - content: "\f1ae"; -} + content: "\f1ae"; } .fa-paw:before { - content: "\f1b0"; -} + content: "\f1b0"; } .fa-spoon:before { - content: "\f1b1"; -} + content: "\f1b1"; } .fa-cube:before { - content: "\f1b2"; -} + content: "\f1b2"; } .fa-cubes:before { - content: "\f1b3"; -} + content: "\f1b3"; } .fa-behance:before { - content: "\f1b4"; -} + content: "\f1b4"; } .fa-behance-square:before { - content: "\f1b5"; -} + content: "\f1b5"; } .fa-steam:before { - content: "\f1b6"; -} + content: "\f1b6"; } .fa-steam-square:before { - content: "\f1b7"; -} + content: "\f1b7"; } .fa-recycle:before { - content: "\f1b8"; -} + content: "\f1b8"; } .fa-automobile:before, .fa-car:before { - content: "\f1b9"; -} + content: "\f1b9"; } .fa-cab:before, .fa-taxi:before { - content: "\f1ba"; -} + content: "\f1ba"; } .fa-tree:before { - content: "\f1bb"; -} + content: "\f1bb"; } .fa-spotify:before { - content: "\f1bc"; -} + content: "\f1bc"; } .fa-deviantart:before { - content: "\f1bd"; -} + content: "\f1bd"; } .fa-soundcloud:before { - content: "\f1be"; -} + content: "\f1be"; } .fa-database:before { - content: "\f1c0"; -} + content: "\f1c0"; } .fa-file-pdf-o:before { - content: "\f1c1"; -} + content: "\f1c1"; } .fa-file-word-o:before { - content: "\f1c2"; -} + content: "\f1c2"; } .fa-file-excel-o:before { - content: "\f1c3"; -} + content: "\f1c3"; } .fa-file-powerpoint-o:before { - content: "\f1c4"; -} + content: "\f1c4"; } .fa-file-photo-o:before, .fa-file-picture-o:before, .fa-file-image-o:before { - content: "\f1c5"; -} + content: "\f1c5"; } .fa-file-zip-o:before, .fa-file-archive-o:before { - content: "\f1c6"; -} + content: "\f1c6"; } .fa-file-sound-o:before, .fa-file-audio-o:before { - content: "\f1c7"; -} + content: "\f1c7"; } .fa-file-movie-o:before, .fa-file-video-o:before { - content: "\f1c8"; -} + content: "\f1c8"; } .fa-file-code-o:before { - content: "\f1c9"; -} + content: "\f1c9"; } .fa-vine:before { - content: "\f1ca"; -} + content: "\f1ca"; } .fa-codepen:before { - content: "\f1cb"; -} + content: "\f1cb"; } .fa-jsfiddle:before { - content: "\f1cc"; -} + content: "\f1cc"; } .fa-life-bouy:before, .fa-life-buoy:before, .fa-life-saver:before, .fa-support:before, .fa-life-ring:before { - content: "\f1cd"; -} + content: "\f1cd"; } .fa-circle-o-notch:before { - content: "\f1ce"; -} + content: "\f1ce"; } .fa-ra:before, .fa-rebel:before { - content: "\f1d0"; -} + content: "\f1d0"; } .fa-ge:before, .fa-empire:before { - content: "\f1d1"; -} + content: "\f1d1"; } .fa-git-square:before { - content: "\f1d2"; -} + content: "\f1d2"; } .fa-git:before { - content: "\f1d3"; -} + content: "\f1d3"; } .fa-hacker-news:before { - content: "\f1d4"; -} + content: "\f1d4"; } .fa-tencent-weibo:before { - content: "\f1d5"; -} + content: "\f1d5"; } .fa-qq:before { - content: "\f1d6"; -} + content: "\f1d6"; } .fa-wechat:before, .fa-weixin:before { - content: "\f1d7"; -} + content: "\f1d7"; } .fa-send:before, .fa-paper-plane:before { - content: "\f1d8"; -} + content: "\f1d8"; } .fa-send-o:before, .fa-paper-plane-o:before { - content: "\f1d9"; -} + content: "\f1d9"; } .fa-history:before { - content: "\f1da"; -} + content: "\f1da"; } .fa-circle-thin:before { - content: "\f1db"; -} + content: "\f1db"; } .fa-header:before { - content: "\f1dc"; -} + content: "\f1dc"; } .fa-paragraph:before { - content: "\f1dd"; -} + content: "\f1dd"; } .fa-sliders:before { - content: "\f1de"; -} + content: "\f1de"; } .fa-share-alt:before { - content: "\f1e0"; -} + content: "\f1e0"; } .fa-share-alt-square:before { - content: "\f1e1"; -} + content: "\f1e1"; } .fa-bomb:before { - content: "\f1e2"; -} + content: "\f1e2"; } .fa-soccer-ball-o:before, .fa-futbol-o:before { - content: "\f1e3"; -} + content: "\f1e3"; } .fa-tty:before { - content: "\f1e4"; -} + content: "\f1e4"; } .fa-binoculars:before { - content: "\f1e5"; -} + content: "\f1e5"; } .fa-plug:before { - content: "\f1e6"; -} + content: "\f1e6"; } .fa-slideshare:before { - content: "\f1e7"; -} + content: "\f1e7"; } .fa-twitch:before { - content: "\f1e8"; -} + content: "\f1e8"; } .fa-yelp:before { - content: "\f1e9"; -} + content: "\f1e9"; } .fa-newspaper-o:before { - content: "\f1ea"; -} + content: "\f1ea"; } .fa-wifi:before { - content: "\f1eb"; -} + content: "\f1eb"; } .fa-calculator:before { - content: "\f1ec"; -} + content: "\f1ec"; } .fa-paypal:before { - content: "\f1ed"; -} + content: "\f1ed"; } .fa-google-wallet:before { - content: "\f1ee"; -} + content: "\f1ee"; } .fa-cc-visa:before { - content: "\f1f0"; -} + content: "\f1f0"; } .fa-cc-mastercard:before { - content: "\f1f1"; -} + content: "\f1f1"; } .fa-cc-discover:before { - content: "\f1f2"; -} + content: "\f1f2"; } .fa-cc-amex:before { - content: "\f1f3"; -} + content: "\f1f3"; } .fa-cc-paypal:before { - content: "\f1f4"; -} + content: "\f1f4"; } .fa-cc-stripe:before { - content: "\f1f5"; -} + content: "\f1f5"; } .fa-bell-slash:before { - content: "\f1f6"; -} + content: "\f1f6"; } .fa-bell-slash-o:before { - content: "\f1f7"; -} + content: "\f1f7"; } .fa-trash:before { - content: "\f1f8"; -} + content: "\f1f8"; } .fa-copyright:before { - content: "\f1f9"; -} + content: "\f1f9"; } .fa-at:before { - content: "\f1fa"; -} + content: "\f1fa"; } .fa-eyedropper:before { - content: "\f1fb"; -} + content: "\f1fb"; } .fa-paint-brush:before { - content: "\f1fc"; -} + content: "\f1fc"; } .fa-birthday-cake:before { - content: "\f1fd"; -} + content: "\f1fd"; } .fa-area-chart:before { - content: "\f1fe"; -} + content: "\f1fe"; } .fa-pie-chart:before { - content: "\f200"; -} + content: "\f200"; } .fa-line-chart:before { - content: "\f201"; -} + content: "\f201"; } .fa-lastfm:before { - content: "\f202"; -} + content: "\f202"; } .fa-lastfm-square:before { - content: "\f203"; -} + content: "\f203"; } .fa-toggle-off:before { - content: "\f204"; -} + content: "\f204"; } .fa-toggle-on:before { - content: "\f205"; -} + content: "\f205"; } .fa-bicycle:before { - content: "\f206"; -} + content: "\f206"; } .fa-bus:before { - content: "\f207"; -} + content: "\f207"; } .fa-ioxhost:before { - content: "\f208"; -} + content: "\f208"; } .fa-angellist:before { - content: "\f209"; -} + content: "\f209"; } .fa-cc:before { - content: "\f20a"; -} + content: "\f20a"; } .fa-shekel:before, .fa-sheqel:before, .fa-ils:before { - content: "\f20b"; -} + content: "\f20b"; } .fa-meanpath:before { - content: "\f20c"; -} + content: "\f20c"; } diff --git a/assets/js/llms-ajax.js b/assets/js/llms-ajax.js index e53e50e091..4db1821c13 100644 --- a/assets/js/llms-ajax.js +++ b/assets/js/llms-ajax.js @@ -1,9 +1,13 @@ + + function Ajax (type, data, cache) { + this.type = type; this.data = data; this.cache = cache; this.dataType = 'json'; this.url = window.ajaxurl || window.llms.ajaxurl; + } Ajax.prototype.get_sections = function () { @@ -106,13 +110,143 @@ Ajax.prototype.get_questions = function () { }); }; -Ajax.prototype.get_quiz_questions = function (quiz_id, user_id) { +Ajax.prototype.start_quiz = function (quiz_id, user_id) { + jQuery.ajax({ + type : this.type, + url : this.url, + data : this.data, + cache : this.cache, + dataType : this.dataType, + beforeSend: function() { + + jQuery( '#llms_start_quiz' ).hide(); + jQuery('html, body').stop().animate({scrollTop: 0}, 500); + jQuery('#llms-quiz-wrapper').empty(); + + jQuery('#llms-quiz-question-wrapper').append( '
Loading Question...
' ); + + }, + success: function( html ) { + + //start the quiz timer + start_quiz_timer(); + + //show the quiz timer + jQuery('#llms-quiz-timer').show(); + + //remove the loading message + jQuery('#llms-quiz-question-wrapper #loader').remove(); + + //append the returned html + jQuery('#llms-quiz-question-wrapper').append( html ); + + jQuery('#llms_answer_question').click(function() { + + //call answer question + answer_question(); + + return false; + + }); + } + }); +}; + +Ajax.prototype.answer_question = function ( quiz_id, question_type, question_id, answer ) { jQuery.ajax({ type : this.type, url : this.url, data : this.data, cache : this.cache, dataType : this.dataType, - success : function(response) { get_quiz_full_page(response); }, + beforeSend: function() { + jQuery('#llms-quiz-question-wrapper').empty(); + jQuery('#llms-quiz-question-wrapper').append( '
Loading Next Question...
' ); + }, + success: function( response ) { + + if ( response.redirect ) { + window.location.replace( response.redirect ); + + } else if ( response.message) { + window.location.replace( response.redirect ); + + } else { + + jQuery('#llms-quiz-question-wrapper #loader').remove(); + + jQuery('#llms-quiz-question-wrapper').append( response.html ); + + jQuery('#llms_answer_question').click(function() { + console.log( 'answer question clicked'); + answer_question(); + return false; + }); + + jQuery('#llms_prev_question').click(function() { + console.log( 'answer question clicked'); + previous_question(); + return false; + }); + + } + } //end success }); -}; \ No newline at end of file +}; + +Ajax.prototype.previous_question = function (quiz_id, question_id) { + jQuery.ajax({ + type : this.type, + url : this.url, + data : this.data, + cache : this.cache, + dataType : this.dataType, + beforeSend: function() { + + jQuery('#llms-quiz-question-wrapper').empty(); + jQuery('#llms-quiz-question-wrapper').append( '
Loading Question...
' ); + + }, + success: function( html ) { + + jQuery('#llms-quiz-question-wrapper #loader').remove(); + + jQuery('#llms-quiz-question-wrapper').append( html ); + + jQuery('#llms_answer_question').click(function() { + answer_question(); + return false; + }); + + jQuery('#llms_prev_question').click(function() { + console.log( 'previus question clicked'); + previous_question(); + return false; + }); + } + + }); +}; + +Ajax.prototype.complete_quiz = function ( quiz_id, question_id, question_type, answer ) { + jQuery.ajax({ + type : this.type, + url : this.url, + data : this.data, + cache : this.cache, + dataType : this.dataType, + beforeSend: function() { + + jQuery('#llms-quiz-question-wrapper').empty(); + jQuery('#llms-quiz-question-wrapper').append( '
Loading Quiz Results...
' ); + + }, + success: function( response ) { + + //redirect back to quiz page + window.location.replace( response.redirect ); + + } //end success + }); +}; + diff --git a/assets/js/llms-quiz.js b/assets/js/llms-quiz.js index 984f1ab6fd..4d80384ee1 100644 --- a/assets/js/llms-quiz.js +++ b/assets/js/llms-quiz.js @@ -1,39 +1,219 @@ jQuery(document).ready(function($) { - $('#llms_start_quiz_depreciated').click(function() { - get_quiz_questions(); - //alert('sript is loaded'); + // calls start quix on "Start Quiz" button click + $('#llms_start_quiz').click(function() { + start_quiz(); return false; }); - -}); - -/** - * Returns array of all questions - */ -get_quiz_questions = function() { - var post_id = jQuery('#llms-quiz').val(); - var user_id = jQuery('#llms-user').val(); - console.log(post_id + ' ' + user_id); - var ajax = new Ajax('post', { 'action':'get_quiz_questions', 'quiz_id' : post_id, 'user_id' : user_id }, true); - ajax.get_quiz_questions(post_id, user_id); -} - -get_quiz_full_page = function(questions, user_id) { - console.log('get quiz full page called'); - console.log(questions); -} + //hides the quiz timer when page loads + $('#llms-quiz-timer').hide(); -jQuery(document).ready(function($) { + /** + * Used for populating the quiz grade svg graph + * @type {[type]} + */ var $llms_circ = $('.llms-animated-circle'); var $llms_prog_count = $('.llms-progress-circle-count'); var $llms_circ_val = $('.progress-range'); - var llms_grade_perc = $('#llms-grade-value').val(); var llms_circ_offset = 430 * llms_grade_perc / 100; + $llms_circ.css({ - "stroke-dashoffset" : 430 - llms_circ_offset + "stroke-dashoffset" : 430 - llms_circ_offset }) + $llms_prog_count.html(Math.round(llms_grade_perc) + "%"); + }); + +/** + * Quiz Functions + * All methods used for interacting with quiz + */ +(function($) { + + /** + * Start Quiz + * Finds values of quiz-id and user-id + * Calls ajax.start_quiz + * @return {[void]} + */ + start_quiz = function () { + + var post_id = jQuery('#llms-quiz').val(); + var user_id = jQuery('#llms-user').val(); + + var ajax = new Ajax('post', { 'action':'start_quiz', 'quiz_id' : post_id, 'user_id' : user_id }, true); + + ajax.start_quiz( post_id, user_id ); + } + + /** + * Answer Question + * Finds values of quiz-id, question-type, question-id and answer + * Calls ajax.answer_question + * + * @return {[void]} + */ + answer_question = function() { + + if ( jQuery( 'input[name=llms_option_selected]:checked' ).length <= 0 ){ + + jQuery('#llms-quiz-question-wrapper .llms-error').remove(); + jQuery('#llms-quiz-question-wrapper').prepend( '
You must enter an answer to continue.
' ); + + } else { + + var quiz_id = jQuery('#llms-quiz').val(); + var question_type = jQuery('#question-type').val(); + var question_id = jQuery('#question-id').val(); + var answer = jQuery('input[name=llms_option_selected]:checked').val(); + + var ajax = new Ajax('post', { 'action':'answer_question', 'quiz_id' : quiz_id, 'question_type' : question_type, 'question_id' : question_id, 'answer' : answer }, true); + + ajax.answer_question( question_type, question_id, answer ); + + } + + } + + /** + * Previous Question + * Finds quiz-id and question-id + * Calls ajax.previous_question to find the previous question + * @return {[void]} + */ + previous_question = function() { + + var quiz_id = jQuery('#llms-quiz').val(); + var question_id = jQuery('#question-id').val(); + + var ajax = new Ajax('post', { 'action':'previous_question', 'quiz_id' : quiz_id, 'question_id' : question_id }, true); + + ajax.previous_question( quiz_id, question_id ); + } + + /** + * Start Quiz Timer + * Gets minutes from hidden field + * Not used as actual quiz timer. Quiz is timed on the server from the quiz class + * Calculates minutes to milliseconds and then converts to hours / minutes + * + * When time limit reaches 0 calls complete_quiz() to complete quiz. + * + * @return Calls get_count_down at a set interval of 1 second + */ + start_quiz_timer = function() { + + var minutes = $( '#set-time' ).val(); + + if ( minutes ) { + + var target_date = new Date().getTime() + ((minutes * 60 ) * 1000); // set the countdown date + var time_limit = ((minutes * 60 ) * 1000); + + //set actual timer + setTimeout( + function() + { + complete_quiz(); + }, time_limit ); + + var days, hours, minutes, seconds; // variables for time units + + var countdown = document.getElementById("tiles"); // get tag element + + getCountdown(minutes, target_date, time_limit, days, hours, minutes, seconds, countdown); + + //call get_count_down every 1 second + setInterval(function () { getCountdown(minutes, target_date, time_limit, days, hours, minutes, seconds, countdown); }, 1000); + + } + + } + + /** + * Get Count Down + * Called every second to update the on screen countdown timer + * Changes color to yellow at 1/2 of total time + * Changes color to red at 1/4 of total time + * @param {[int]} minutes [description] + * @param {[date]} target_date [description] + * @param {[int]} time_limit [description] + * @param {[int]} days [description] + * @param {[int]} hours [description] + * @param {[int]} minutes [description] + * @param {[int]} seconds [description] + * @param {[int]} countdown [description] + * @return Displays updates hours, minutes on quiz timer + */ + function getCountdown(minutes, target_date, time_limit, days, hours, minutes, seconds, countdown){ + + // find the amount of "seconds" between now and target + var current_date = new Date().getTime(); + var seconds_left = (target_date - current_date) / 1000; + + if ( seconds_left >= 0 ) { + + if ( (seconds_left * 1000 ) < ( time_limit / 2 ) ) { + + $( '#tiles' ).removeClass('color-full'); + $( '#tiles' ).addClass('color-half'); + + } + + if ( (seconds_left * 1000 ) < ( time_limit / 4 ) ) { + + $( '#tiles' ).removeClass('color-half'); + $( '#tiles' ).addClass('color-empty'); + + } + + days = pad( parseInt(seconds_left / 86400) ); + seconds_left = seconds_left % 86400; + + hours = pad( parseInt(seconds_left / 3600) ); + seconds_left = seconds_left % 3600; + + minutes = pad( parseInt(seconds_left / 60) ); + seconds = pad( parseInt( seconds_left % 60 ) ); + + // format countdown string + set tag value + countdown.innerHTML = "" + hours + ":" + minutes + ":" + seconds + ""; + + } + } + + /** + * Pad Number + * pads number with 0 if single digit. + * + * @param {[int]} n [number] + * @return {[string]} [padded number] + */ + function pad(n) { + return (n < 10 ? '0' : '') + n; + } + + /** + * Complete Quiz + * Called by start_quiz_timer when countdown reaches 0 + * + * @return Calls ajax.complete_quiz to end quiz + */ + function complete_quiz() { + console.log( 'complete quiz called'); + var quiz_id = jQuery('#llms-quiz').val(); + var question_type = jQuery('#question-type').val(); + var question_id = jQuery('#question-id').val(); + var answer = jQuery('input[name=llms_option_selected]:checked').val(); + var ajax = new Ajax('post', { 'action':'complete_quiz', 'quiz_id' : quiz_id, 'question_id' : question_id, 'question_type' : question_type, 'answer' : answer }, true); + ajax.complete_quiz( quiz_id, question_id, question_type, answer ); + } + +})(jQuery); + + + + diff --git a/assets/js/min/llms-ajax-min.js b/assets/js/min/llms-ajax-min.js new file mode 100644 index 0000000000..4a19a2532d --- /dev/null +++ b/assets/js/min/llms-ajax-min.js @@ -0,0 +1 @@ +function Ajax(e,t,a){this.type=e,this.data=t,this.cache=a,this.dataType="json",this.url=window.ajaxurl||window.llms.ajaxurl}Ajax.prototype.get_sections=function(){jQuery.ajax({type:this.type,url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,success:function(e){section_template(e)}})},Ajax.prototype.get_lesson=function(e,t,a){jQuery.ajax({type:this.type,url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,success:function(s){add_edit_link(s,e,t,a)}})},Ajax.prototype.get_lessons=function(e,t){jQuery.ajax({type:this.type,url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,success:function(a){lesson_template(a,e,t)}})},Ajax.prototype.update_syllabus=function(){jQuery.ajax({url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,success:function(e){console.log(JSON.stringify(e,null,4))},error:function(e){console.log(e)}})},Ajax.prototype.get_all_posts=function(){jQuery.ajax({type:this.type,url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,success:function(e){return_data(e)}})},Ajax.prototype.get_all_engagements=function(){jQuery.ajax({type:this.type,url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,success:function(e){return_engagement_data(e)}})},Ajax.prototype.get_associated_lessons=function(e,t){jQuery.ajax({type:this.type,url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,success:function(a){add_associated_lessons(a,e,t)}})},Ajax.prototype.get_question=function(e,t){jQuery.ajax({type:this.type,url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,success:function(a){add_edit_link(a,e,t)}})},Ajax.prototype.get_questions=function(){jQuery.ajax({type:this.type,url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,success:function(e){single_question_template(e)}})},Ajax.prototype.start_quiz=function(e,t){jQuery.ajax({type:this.type,url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,beforeSend:function(){jQuery("#llms_start_quiz").hide(),jQuery("html, body").stop().animate({scrollTop:0},500),jQuery("#llms-quiz-wrapper").empty(),jQuery("#llms-quiz-question-wrapper").append('
Loading Question...
')},success:function(e){start_quiz_timer(),jQuery("#llms-quiz-timer").show(),jQuery("#llms-quiz-question-wrapper #loader").remove(),jQuery("#llms-quiz-question-wrapper").append(e),jQuery("#llms_answer_question").click(function(){return answer_question(),!1})}})},Ajax.prototype.answer_question=function(e,t,a,s){jQuery.ajax({type:this.type,url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,beforeSend:function(){jQuery("#llms-quiz-question-wrapper").empty(),jQuery("#llms-quiz-question-wrapper").append('
Loading Next Question...
')},success:function(e){e.redirect?window.location.replace(e.redirect):e.message?window.location.replace(e.redirect):(jQuery("#llms-quiz-question-wrapper #loader").remove(),jQuery("#llms-quiz-question-wrapper").append(e.html),jQuery("#llms_answer_question").click(function(){return console.log("answer question clicked"),answer_question(),!1}),jQuery("#llms_prev_question").click(function(){return console.log("answer question clicked"),previous_question(),!1}))}})},Ajax.prototype.previous_question=function(e,t){jQuery.ajax({type:this.type,url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,beforeSend:function(){jQuery("#llms-quiz-question-wrapper").empty(),jQuery("#llms-quiz-question-wrapper").append('
Loading Question...
')},success:function(e){jQuery("#llms-quiz-question-wrapper #loader").remove(),jQuery("#llms-quiz-question-wrapper").append(e),jQuery("#llms_answer_question").click(function(){return answer_question(),!1}),jQuery("#llms_prev_question").click(function(){return console.log("previus question clicked"),previous_question(),!1})}})},Ajax.prototype.complete_quiz=function(e,t,a,s){jQuery.ajax({type:this.type,url:this.url,data:this.data,cache:this.cache,dataType:this.dataType,beforeSend:function(){jQuery("#llms-quiz-question-wrapper").empty(),jQuery("#llms-quiz-question-wrapper").append('
Loading Quiz Results...
')},success:function(e){window.location.replace(e.redirect)}})}; \ No newline at end of file diff --git a/assets/js/min/llms-quiz-min.js b/assets/js/min/llms-quiz-min.js new file mode 100644 index 0000000000..4a8884f666 --- /dev/null +++ b/assets/js/min/llms-quiz-min.js @@ -0,0 +1 @@ +jQuery(document).ready(function($){$("#llms_start_quiz").click(function(){return start_quiz(),!1}),$("#llms-quiz-timer").hide();var e=$(".llms-animated-circle"),t=$(".llms-progress-circle-count"),s=$(".progress-range"),i=$("#llms-grade-value").val(),n=430*i/100;e.css({"stroke-dashoffset":430-n}),t.html(Math.round(i)+"%")}),function($){function e(e,s,i,n,u,e,l,r){var a=(new Date).getTime(),o=(s-a)/1e3;o>=0&&(i/2>1e3*o&&($("#tiles").removeClass("color-full"),$("#tiles").addClass("color-half")),i/4>1e3*o&&($("#tiles").removeClass("color-half"),$("#tiles").addClass("color-empty")),n=t(parseInt(o/86400)),o%=86400,u=t(parseInt(o/3600)),o%=3600,e=t(parseInt(o/60)),l=t(parseInt(o%60)),r.innerHTML=""+u+":"+e+":"+l+"")}function t(e){return(10>e?"0":"")+e}function s(){console.log("complete quiz called");var e=jQuery("#llms-quiz").val(),t=jQuery("#question-type").val(),s=jQuery("#question-id").val(),i=jQuery("input[name=llms_option_selected]:checked").val(),n=new Ajax("post",{action:"complete_quiz",quiz_id:e,question_id:s,question_type:t,answer:i},!0);n.complete_quiz(e,s,t,i)}start_quiz=function(){var e=jQuery("#llms-quiz").val(),t=jQuery("#llms-user").val(),s=new Ajax("post",{action:"start_quiz",quiz_id:e,user_id:t},!0);s.start_quiz(e,t)},answer_question=function(){if(jQuery("input[name=llms_option_selected]:checked").length<=0)jQuery("#llms-quiz-question-wrapper .llms-error").remove(),jQuery("#llms-quiz-question-wrapper").prepend('
You must enter an answer to continue.
');else{var e=jQuery("#llms-quiz").val(),t=jQuery("#question-type").val(),s=jQuery("#question-id").val(),i=jQuery("input[name=llms_option_selected]:checked").val(),n=new Ajax("post",{action:"answer_question",quiz_id:e,question_type:t,question_id:s,answer:i},!0);n.answer_question(t,s,i)}},previous_question=function(){var e=jQuery("#llms-quiz").val(),t=jQuery("#question-id").val(),s=new Ajax("post",{action:"previous_question",quiz_id:e,question_id:t},!0);s.previous_question(e,t)},start_quiz_timer=function(){var t=$("#set-time").val();if(t){var i=(new Date).getTime()+60*t*1e3,n=60*t*1e3;setTimeout(function(){s()},n);var u,l,t,r,a=document.getElementById("tiles");e(t,i,n,u,l,t,r,a),setInterval(function(){e(t,i,n,u,l,t,r,a)},1e3)}}}(jQuery); \ No newline at end of file diff --git a/config.codekit b/config.codekit index a57fb35545..ce725680a8 100644 --- a/config.codekit +++ b/config.codekit @@ -2,6 +2,15 @@ "CodeKitInfo": "This is a CodeKit 2.x project configuration file. It is designed to sync project settings across multiple machines. MODIFYING THE CONTENTS OF THIS FILE IS A POOR LIFE DECISION. If you do so, you will likely cause CodeKit to crash. This file is not useful unless accompanied by the project that created it in CodeKit 2. This file is not backwards-compatible with CodeKit 1.x. For more information, see: http:\/\/incident57.com\/codekit", "creatorBuild": "18493", "files": { + "\/_private\/assets\/css\/quiz-timer.css": { + "fileType": 16, + "ignore": 1, + "ignoreWasSetByUser": 0, + "inputAbbreviatedPath": "\/_private\/assets\/css\/quiz-timer.css", + "outputAbbreviatedPath": "No Output Path", + "outputPathIsOutsideProject": 0, + "outputPathIsSetByUser": 0 + }, "\/_private\/scss\/_includes\/_extends.scss": { "createSourceMap": 0, "debugStyle": 0, @@ -306,6 +315,22 @@ "shouldRunBless": 0, "useLibsass": 0 }, + "\/_private\/scss\/frontend\/quiz-timer.scss": { + "createSourceMap": 0, + "debugStyle": 0, + "decimalPrecision": 10, + "fileType": 4, + "ignore": 1, + "ignoreWasSetByUser": 0, + "inputAbbreviatedPath": "\/_private\/scss\/frontend\/quiz-timer.scss", + "outputAbbreviatedPath": "\/_private\/assets\/css\/quiz-timer.css", + "outputPathIsOutsideProject": 0, + "outputPathIsSetByUser": 0, + "outputStyle": 0, + "shouldRunAutoprefixer": 0, + "shouldRunBless": 0, + "useLibsass": 0 + }, "\/_private\/scss\/lifterlms.scss": { "createSourceMap": 0, "debugStyle": 0, @@ -537,7 +562,7 @@ "fileType": 32768, "ignore": 0, "ignoreWasSetByUser": 0, - "initialSize": 0, + "initialSize": 96217, "inputAbbreviatedPath": "\/assets\/images\/optional_certificate.png", "outputAbbreviatedPath": "\/assets\/images\/optional_certificate.png", "outputPathIsOutsideProject": 0, @@ -874,6 +899,17 @@ "outputStyle": 1, "syntaxCheckerStyle": 1 }, + "\/assets\/js\/min\/llms-ajax-min.js": { + "fileType": 64, + "ignore": 1, + "ignoreWasSetByUser": 0, + "inputAbbreviatedPath": "\/assets\/js\/min\/llms-ajax-min.js", + "outputAbbreviatedPath": "\/assets\/js\/min\/min\/llms-ajax-min-min.js", + "outputPathIsOutsideProject": 0, + "outputPathIsSetByUser": 0, + "outputStyle": 1, + "syntaxCheckerStyle": 1 + }, "\/assets\/js\/min\/llms-metabox-syllabus-min.js": { "fileType": 64, "ignore": 1, @@ -885,6 +921,17 @@ "outputStyle": 1, "syntaxCheckerStyle": 1 }, + "\/assets\/js\/min\/llms-quiz-min.js": { + "fileType": 64, + "ignore": 1, + "ignoreWasSetByUser": 0, + "inputAbbreviatedPath": "\/assets\/js\/min\/llms-quiz-min.js", + "outputAbbreviatedPath": "\/assets\/js\/min\/min\/llms-quiz-min-min.js", + "outputPathIsOutsideProject": 0, + "outputPathIsSetByUser": 0, + "outputStyle": 1, + "syntaxCheckerStyle": 1 + }, "\/includes\/achievements\/class.llms.achievement.user.php": { "fileType": 8192, "ignore": 0, @@ -2189,6 +2236,15 @@ "outputPathIsOutsideProject": 0, "outputPathIsSetByUser": 0 }, + "\/templates\/content-single-question.php": { + "fileType": 8192, + "ignore": 0, + "ignoreWasSetByUser": 0, + "inputAbbreviatedPath": "\/templates\/content-single-question.php", + "outputAbbreviatedPath": "No Output Path", + "outputPathIsOutsideProject": 0, + "outputPathIsSetByUser": 0 + }, "\/templates\/content-single-quiz-after.php": { "fileType": 8192, "ignore": 0, @@ -2711,6 +2767,33 @@ "outputPathIsOutsideProject": 0, "outputPathIsSetByUser": 0 }, + "\/templates\/quiz\/quiz-question.php": { + "fileType": 8192, + "ignore": 0, + "ignoreWasSetByUser": 0, + "inputAbbreviatedPath": "\/templates\/quiz\/quiz-question.php", + "outputAbbreviatedPath": "No Output Path", + "outputPathIsOutsideProject": 0, + "outputPathIsSetByUser": 0 + }, + "\/templates\/quiz\/quiz-wrapper-end.php": { + "fileType": 8192, + "ignore": 0, + "ignoreWasSetByUser": 0, + "inputAbbreviatedPath": "\/templates\/quiz\/quiz-wrapper-end.php", + "outputAbbreviatedPath": "No Output Path", + "outputPathIsOutsideProject": 0, + "outputPathIsSetByUser": 0 + }, + "\/templates\/quiz\/quiz-wrapper-start.php": { + "fileType": 8192, + "ignore": 0, + "ignoreWasSetByUser": 0, + "inputAbbreviatedPath": "\/templates\/quiz\/quiz-wrapper-start.php", + "outputAbbreviatedPath": "No Output Path", + "outputPathIsOutsideProject": 0, + "outputPathIsSetByUser": 0 + }, "\/templates\/quiz\/results.php": { "fileType": 8192, "ignore": 0, @@ -2738,6 +2821,15 @@ "outputPathIsOutsideProject": 0, "outputPathIsSetByUser": 0 }, + "\/templates\/quiz\/single-choice_ajax.php": { + "fileType": 8192, + "ignore": 0, + "ignoreWasSetByUser": 0, + "inputAbbreviatedPath": "\/templates\/quiz\/single-choice_ajax.php", + "outputAbbreviatedPath": "No Output Path", + "outputPathIsOutsideProject": 0, + "outputPathIsSetByUser": 0 + }, "\/templates\/quiz\/start-button.php": { "fileType": 8192, "ignore": 0, @@ -2747,6 +2839,15 @@ "outputPathIsOutsideProject": 0, "outputPathIsSetByUser": 0 }, + "\/templates\/quiz\/timer.php": { + "fileType": 8192, + "ignore": 0, + "ignoreWasSetByUser": 0, + "inputAbbreviatedPath": "\/templates\/quiz\/timer.php", + "outputAbbreviatedPath": "No Output Path", + "outputPathIsOutsideProject": 0, + "outputPathIsSetByUser": 0 + }, "\/templates\/quiz\/wrapper-end.php": { "fileType": 8192, "ignore": 0, diff --git a/includes/admin/class.llms.admin.analytics.php b/includes/admin/class.llms.admin.analytics.php index 73b4d4d840..65e17a6976 100644 --- a/includes/admin/class.llms.admin.analytics.php +++ b/includes/admin/class.llms.admin.analytics.php @@ -195,7 +195,7 @@ public static function save_search_fields( $analytics ) { $search->start_date = LLMS_Date::db_date( llms_clean( $_POST[ 'llms-start-date' ] ) ); $search->end_date = LLMS_Date::db_date( llms_clean( $_POST[ 'llms-end-date' ] ) ); - + $end_date_plus_one = LLMS_Date::db_date( llms_clean( $_POST[ 'llms-end-date' ] ) . '+ 1 day'); } //set up search arguments @@ -207,7 +207,7 @@ public static function save_search_fields( $analytics ) { ), '1' => array( 'key' => '_llms_order_date', - 'value' => $search->end_date, + 'value' => $end_date_plus_one, 'compare' => '<=' ), ); diff --git a/includes/admin/post-types/meta-boxes/class.llms.meta.box.quiz.general.php b/includes/admin/post-types/meta-boxes/class.llms.meta.box.quiz.general.php index 52cd5bb5d8..2d27b15a80 100644 --- a/includes/admin/post-types/meta-boxes/class.llms.meta.box.quiz.general.php +++ b/includes/admin/post-types/meta-boxes/class.llms.meta.box.quiz.general.php @@ -25,6 +25,7 @@ public static function output( $post ) { $allowed_attempts = get_post_meta( $post->ID, '_llms_allowed_attempts', true ); $passing_percent = get_post_meta( $post->ID, '_llms_passing_percent', true ); + $time_limit = get_post_meta( $post->ID, '_llms_time_limit', true ); ?> @@ -41,7 +42,7 @@ public static function output( $post ) { '; - $html .= '
' . __( 'Number of allowed attempts. Must be at least 1.', 'lifterlms' ) . ''; + $html .= '
' . __( 'Number of allowed attempts. Leave blank for unlimited attempts.', 'lifterlms' ) . ''; echo $html; ?> @@ -64,6 +65,27 @@ public static function output( $post ) { ?> + + + + + + + +
+ ' . __( 'Time Limit', 'lifterlms' ) . ' '; + echo $label; + ?> + + '; + $html .= '
' . __( 'Enter a time limit for quiz completion in minutes. Leave empty if no time limit.', 'lifterlms' ) . ''; + echo $html; + ?> +
@@ -85,12 +107,17 @@ public static function save( $post_id, $post ) { if ( isset( $_POST['_llms_allowed_attempts'] ) ) { $allowed_attempts = ( llms_clean( $_POST['_llms_allowed_attempts'] ) ); - update_post_meta( $post_id, '_llms_allowed_attempts', ( $allowed_attempts === '' ) ? '1' : $allowed_attempts ); + update_post_meta( $post_id, '_llms_allowed_attempts', ( $allowed_attempts === '' ) ? '' : $allowed_attempts ); } if ( isset( $_POST['_llms_passing_percent'] ) ) { $passing_percent = ( llms_clean( $_POST['_llms_passing_percent'] ) ); update_post_meta( $post_id, '_llms_passing_percent', ( $passing_percent === '' ) ? '0' : $passing_percent ); } + if ( isset( $_POST['_llms_time_limit'] ) ) { + $time_limit = ( llms_clean( $_POST['_llms_time_limit'] ) ); + update_post_meta( $post_id, '_llms_time_limit', $time_limit ); + } + } } \ No newline at end of file diff --git a/includes/class.llms.ajax.php b/includes/class.llms.ajax.php index dca2863811..674d7c9b71 100644 --- a/includes/class.llms.ajax.php +++ b/includes/class.llms.ajax.php @@ -29,6 +29,10 @@ public function __construct() { 'get_question' => false, 'get_questions' => false, 'get_quiz_questions' => false, + 'start_quiz' => false, + 'answer_question' => false, + 'previous_question' => false, + 'complete_quiz' => false, ); foreach ( $ajax_events as $ajax_event => $nopriv ) { @@ -344,6 +348,7 @@ function array_has_dupes($new_array) { function delete_lesson_meta($post_id) { + $lesson_ids = array(); $rd_args = array( @@ -354,13 +359,12 @@ function delete_lesson_meta($post_id) { $rd_query = new WP_Query( $rd_args ); - $lesson_ids = array(); - - //foreach( $rd_query as $key => $value ) while ( $rd_query->have_posts() ) : $rd_query->the_post(); - //delete_post_meta($rd_query->post->ID, '_parent_course', $post_id) + array_push($lesson_ids, $rd_query->post->ID ); + endwhile; + wp_reset_postdata(); } @@ -471,52 +475,168 @@ function delete_lesson_meta($post_id) { } } - echo json_encode($lesson_ids); - die(); + //echo json_encode($lesson_ids); + die(); } /** - * Return array of questions (id => name) - * - * @param string - * @return array + * Starts Quiz + * Calls Quiz::start_quiz to set session object and get first question id + * + * @return [json] [1st question id, html of 1st question post] */ - public function get_quiz_questions(){ - $quiz_id = $_REQUEST['quiz_id']; - $user_id = $_REQUEST['user_id']; + public function start_quiz() { + + $quiz_id = llms_clean( $_REQUEST['quiz_id'] ); + $user_id = llms_clean( $_REQUEST['user_id'] ); - $quiz = new LLMS_Quiz($quiz_id ); + //call start quiz method + $question_id = LLMS_Quiz::start_quiz( $quiz_id, $user_id ); + + //get requst variables + $args = array( + 'quiz_id' => $quiz_id, + 'question_id' => $question_id + ); - //first off. we need to check if the user can actually view this quiz - // - //then we need to get the postmeta and then get each question. - $all_questions = array(); - $questions = $quiz->get_questions(); + $first_question = llms_get_template_ajax( 'content-single-question.php', $args ); - if($questions) { - foreach ($questions as $key => $value) { - array_push($all_questions, get_post($value['id'])); - - } + echo json_encode( $first_question ); + die(); + } + + /** + * Calls Quiz::answer_question to update session object and get next quiz question + * + * @return [json] [html, message, redirect] + */ + public function answer_question() { + + $quiz_id = llms_clean( $_REQUEST['quiz_id'] ); + $question_id = llms_clean( $_REQUEST['question_id'] ); + $question_type = llms_clean( $_REQUEST['question_type'] ); + $answer = llms_clean( $_REQUEST['answer'] ); + $complete = false; + + //call answer question and get response + $next_step = LLMS_Quiz::answer_question( $quiz_id, $question_id, $question_type, $answer, $complete ); + + //if next question exists then get next question html + $next_question = ''; + if ( array_key_exists('next_question_id', $next_step ) ) { + + $args = array( + 'quiz_id' => $quiz_id, + 'question_id' => $next_step['next_question_id'], + ); + + $next_question = llms_get_template_ajax( 'content-single-question.php', $args ); + + } + + //if message exists then set message + $message = ''; + if (array_key_exists('message', $next_step ) ) { + $message = $next_step['message']; } - //get each question and build array + + //if redirect exists set redirect + $redirect = ''; + if (array_key_exists('redirect', $next_step ) ) { + $redirect = $next_step['redirect']; + } + + //setup json response + $response = array( + 'html' => $next_question, + 'message' => $message, + 'redirect' => $redirect + ); + + echo json_encode( $response ); + die(); + } + + /** + * Calls Quiz::previous_question to get previous question html + * @return [json] [prevous question id] + */ + public function previous_question() { + + $quiz_id = llms_clean( $_REQUEST['quiz_id'] ); + $question_id = llms_clean( $_REQUEST['question_id'] ); + + //call start quiz method + $prev_question_id = LLMS_Quiz::previous_question( $question_id ); + + //get requst variables $args = array( - 'posts_per_page' => -1, - 'post_type' => 'llms_question', - 'nopaging' => true, - 'post_status' => 'publish', + 'quiz_id' => $quiz_id, + 'question_id' => $prev_question_id ); - $questions = get_posts( $args ); - foreach($questions as $key => $value) { - $value->edit_url = get_edit_post_link($value->ID, false); + $previous_question = llms_get_template_ajax( 'content-single-question.php', $args ); + + echo json_encode( $previous_question ); + die(); + } + + + /** + * Calls Quiz::answer_question, passes $complete as true to complete quiz prematurely + * Only called if quiz timer hits 0 + * + * @return [type] [description] + */ + public function complete_quiz() { + + $quiz_id = llms_clean( $_REQUEST['quiz_id'] ); + $question_id = llms_clean( $_REQUEST['question_id'] ); + $question_type = llms_clean( $_REQUEST['question_type'] ); + $answer = isset( $_REQUEST['answer'] ) ? llms_clean( $_REQUEST['answer'] ) : ''; + $complete = true; + + //call answer question and get response + $next_step = LLMS_Quiz::answer_question( $quiz_id, $question_id, $question_type, $answer, $complete ); + + //if next question exists then get next question html + $next_question = ''; + if ( array_key_exists('next_question_id', $next_step ) ) { + + $args = array( + 'quiz_id' => $quiz_id, + 'question_id' => $next_step['next_question_id'], + ); + + $next_question = llms_get_template_ajax( 'content-single-question.php', $args ); + } - echo json_encode($all_questions); - die(); + //if message exists then set message + $message = ''; + if (array_key_exists('message', $next_step ) ) { + $message = $next_step['message']; + } + + //if redirect exists set redirect + $redirect = ''; + if (array_key_exists('redirect', $next_step ) ) { + $redirect = $next_step['redirect']; + } + + //setup json response + $response = array( + 'html' => $next_question, + 'message' => $message, + 'redirect' => $redirect + ); + + echo json_encode( $response ); + die(); } + } new LLMS_AJAX(); diff --git a/includes/class.llms.date.php b/includes/class.llms.date.php index f963b8e983..406c3e12f6 100644 --- a/includes/class.llms.date.php +++ b/includes/class.llms.date.php @@ -164,6 +164,46 @@ public static function get_localized_date_string() { return strftime( _x( '%b %d, %Y @ %I:%M %p', 'Localized Order DateTime', 'lifterlms' ) ); } + public static function convert_to_hours_minutes_string( $time ) { + settype($time, 'integer'); + if ($time < 1) { + return; + } + $hours = floor($time / 60); + $minutes = ($time % 60); + + $hour_desc = ''; + $minute_desc = ''; + + $hours_string = ''; + $minutes_string = ''; + + //determine hours vs hour in string + if ( !empty( $hours ) ) { + if ( $hours > 1 ) { + $hour_desc = 'hours'; + } else { + $hour_desc = 'hour'; + } + + $hours_string = sprintf( __( '%d %s ', 'lifterlms' ), $hours, $hour_desc ); + } + + //determine minutes vs minute in string + if ( !empty( $minutes ) ) { + if ( $minutes > 1 ) { + $minute_desc = 'minutes'; + } else { + $minute_desc = 'minute'; + } + + $minutes_string = sprintf( __( '%d %s', 'lifterlms' ), $minutes, $minute_desc ); + + } + + return $hours_string . $minutes_string; + } + } diff --git a/includes/class.llms.frontend.forms.php b/includes/class.llms.frontend.forms.php index bd6f02b98d..5f56aed457 100644 --- a/includes/class.llms.frontend.forms.php +++ b/includes/class.llms.frontend.forms.php @@ -29,9 +29,6 @@ public function __construct() { add_action( 'init', array( $this, 'reset_password' ) ); add_action( 'init', array( $this, 'mark_complete' ) ); add_action( 'init', array( $this, 'take_quiz' ) ); - add_action( 'init', array( $this, 'llms_start_quiz' ) ); - add_action( 'init', array( $this, 'llms_answer_question' ) ); - add_action( 'init', array( $this, 'prev_question' ) ); add_action( 'lifterlms_order_process_begin', array( $this, 'order_processing' ), 10, 1 ); add_action( 'lifterlms_order_process_success', array( $this, 'order_success' ), 10, 1 ); add_action( 'lifterlms_order_process_complete', array( $this, 'order_complete' ), 10, 1 ); @@ -39,303 +36,6 @@ public function __construct() { } - /** - * Previous question button click - * Finds the previous question and redirects the user to the post - * - * @return void - */ - public function prev_question() { - $request_method = strtoupper( getenv( 'REQUEST_METHOD' ) ); - - if( 'POST' !== $request_method ) { - return; - } - - if( !isset( $_POST[ 'llms_prev_question' ] ) || empty( $_POST[ '_wpnonce' ] ) ) { - return; - } - if( isset( $_POST[ 'llms_prev_question' ] ) ) { - $quiz = LLMS()->session->get( 'llms_quiz' ); - - foreach( (array)$quiz->questions as $key => $value ) { - if( $value[ 'id' ] == $_POST[ 'question_id' ] ) { - $previous_question_key = ( $key - 1 ); - if( $previous_question_key >= 0 ) { - $prev_question_link = get_permalink( $quiz->questions[ $previous_question_key ][ 'id' ] ); - $redirect = get_permalink( $prev_question_link ); - wp_redirect( apply_filters( 'lifterlms_prev_question_redirect', $prev_question_link ) ); - } - } - } - } - } - - /** - * answer question form post (next lesson / complete quiz button click) - * inserts answer in database and adds it to current quiz session - * - * @return void - */ - public function llms_answer_question() { - $request_method = strtoupper( getenv( 'REQUEST_METHOD' ) ); - - if( 'POST' !== $request_method ) { - return; - } - - if( !isset( $_POST[ 'llms_answer_question' ] ) || empty( $_POST[ '_wpnonce' ] ) ) { - return; - } - - if( isset( $_POST[ 'llms_answer_question' ] ) ) { - - //get quiz object from session - $quiz = LLMS()->session->get( 'llms_quiz' ); - - //if quiz session does not exist return an error message to the user. - if( empty( $quiz ) ) { - return llms_add_notice( __( 'There was an error finding the associated quiz. Please return to the lesson and begin quiz again.', 'lifterlms' ), 'error' ); - } - - if( $_POST[ 'llms_option_selected' ] === '' ) { - return llms_add_notice( __( 'You must answer the question to continue.', 'lifterlms' ), 'error' ); - } - - //get question meta data - $correct_option = ''; - $question_options = get_post_meta( $_POST[ 'question_id' ], '_llms_question_options', true ); - - foreach( $question_options as $key => $value ) { - if( $value[ 'correct_option' ] ) { - $correct_option = $key; - } - } - - //update quiz object - foreach( (array)$quiz->questions as $key => $value ) { - - if( $value[ 'id' ] == $_POST[ 'question_id' ] ) { - - $current_question = $value[ 'id' ]; - - $quiz->questions[ $key ][ 'answer' ] = $_POST[ 'llms_option_selected' ]; - - if( $_POST[ 'llms_option_selected' ] == $correct_option ) { - $quiz->questions[ $key ][ 'correct' ] = true; - } - else { - $quiz->questions[ $key ][ 'correct' ] = false; - } - - } - } - - LLMS()->session->set( 'llms_quiz', $quiz ); - - //update quiz user meta data - $quiz_data = get_user_meta( $quiz->user_id, 'llms_quiz_data', true ); - - foreach( $quiz_data as $key => $value ) { - - if( $value[ 'wpnonce' ] == $quiz->wpnonce ) { - - foreach( $quiz_data[ $key ][ 'questions' ] as $id => $data ) { - if( $data[ 'id' ] == $_POST[ 'question_id' ] ) { - - $quiz_data[ $key ][ 'questions' ][ $id ][ 'answer' ] = $quiz->questions[ $id ][ 'answer' ]; - $quiz_data[ $key ][ 'questions' ][ $id ][ 'correct' ] = $quiz->questions[ $id ][ 'correct' ]; - - } - } - } - - } - } - update_user_meta( $quiz->user_id, 'llms_quiz_data', $quiz_data ); - - - //if another question exists in lessons array then take user to next question - foreach( (array)$quiz->questions as $k => $q ) { - if( $q[ 'id' ] == $current_question ) { - $next_question = $k + 1; - } - if( !empty( $next_question ) && $k == $next_question ) { - $next_question_id = $q[ 'id' ]; - } - } - if( empty( $next_question_id ) ) { - - $quiz->end_date = current_time( 'mysql' ); - //$quiz->attempts = ( $quiz->attempts - 1 ); - - //save quiz object to usermeta - $quiz_array = (array)$quiz; - - if( $quiz_data ) { - - foreach( $quiz_data as $id => $q ) { - - if( $q[ 'wpnonce' ] == $quiz->wpnonce ) { - - $points = 0; - $grade = 0; - - //set the end time - $quiz_data[ $id ][ 'end_date' ] = $quiz->end_date; - - $quiz_obj = new LLMS_Quiz( $quiz->id ); - - //get grade - //get total points earned - foreach( $q[ 'questions' ] as $key => $value ) { - if( $value[ 'correct' ] ) { - $points += $value[ 'points' ]; - } - } - - //calculate grade - if( $points == 0 ) { - $quiz_data[ $id ][ 'grade' ] = 0; - } - else { - $quiz_data[ $id ][ 'grade' ] = $quiz_obj->get_grade( $points ); - update_user_meta( $quiz->user_id, 'llms_quiz_data', $quiz_data ); - - $quiz_data[ $id ][ 'passed' ] = $quiz_obj->is_passing_score( $quiz->user_id ); - update_user_meta( $quiz->user_id, 'llms_quiz_data', $quiz_data ); - - LLMS()->session->set( 'llms_quiz', $quiz ); - } - - if( $quiz_data[ $id ][ 'passed' ] ) { - $lesson = new LLMS_Lesson( $quiz->assoc_lesson ); - $lesson->mark_complete( $quiz->user_id ); - } - - } - - - } - } - else { - return llms_add_notice( __( 'There was an error with your quiz.', 'lifterlms' ), 'error' ); - } - - - //if there are no other questions in the questions array then redirect back to quiz page - $redirect = get_permalink( $quiz->id ); - wp_redirect( apply_filters( 'lifterlms_quiz_completed_redirect', $redirect ) ); - - } - else { - $redirect = get_permalink( $next_question_id ); - wp_redirect( $redirect ); - } - - } - - - /** - * Start Quiz submit handler - * Performs security and verification checks - * If quiz is enabled for user redirects user to 1st question. - * - * @return void - */ - public function llms_start_quiz() { - $request_method = strtoupper( getenv( 'REQUEST_METHOD' ) ); - if( 'POST' !== $request_method ) { - return; - } - - if( !isset( $_POST[ 'llms_start_quiz' ] ) || empty( $_POST[ '_wpnonce' ] ) ) { - return; - } - - if( isset( $_POST[ 'llms_start_quiz' ] ) ) { - - $quiz = LLMS()->session->get( 'llms_quiz' ); - - if( $quiz->id == $_POST[ 'llms-quiz_id' ] && $quiz->user_id == $_POST[ 'llms-user_id' ] ) { - - if( property_exists( $quiz, 'end_date' ) && $quiz->end_date === '' ) { - $redirect = get_permalink( $quiz->questions[ 0 ][ 'id' ] ); - wp_redirect( apply_filters( 'lifterlms_lesson_begin_quiz', $redirect ) ); - return; - } - - $quiz->start_date = current_time( 'mysql' ); - $quiz->end_date = ''; - $quiz->grade = 0; - $quiz->passed = false; - - //get existing quiz object from database - $quiz_data = get_user_meta( $quiz->user_id, 'llms_quiz_data', true ); - - //count previous attempts and set quiz attempt to +1 of quiz attempt count - $attempts = 0; - - if( $quiz_data ) { - - foreach( $quiz_data as $key => $value ) { - if( $value[ 'id' ] == $quiz->id ) { - $attempts++; - } - } - } - - $quiz->attempt = ( $attempts + 1 ); - $quiz->wpnonce = wp_create_nonce( 'my-action_' . $quiz->id . $quiz->attempt ); - //add questions to quiz object - //question_id (int), answer (string), correct (bool) - $quiz_obj = new LLMS_Quiz( $quiz->id ); - - //$all_questions = array(); - $questions = $quiz_obj->get_questions(); - - if( $questions ) { - foreach( $questions as $key => $value ) { - $questions[ $key ][ 'answer' ] = ''; - $questions[ $key ][ 'correct' ] = false; - } - - $quiz->questions = $questions; - } - else { - return llms_add_notice( __( 'There are no questions associated with this quiz.', 'lifterlms' ), 'error' ); - } - - //save quiz object to usermeta - $quiz_array = (array)$quiz; - - if( $quiz_data ) { - array_push( $quiz_data, $quiz_array ); - } - else { - $quiz_data = array(); - $quiz_data[ ] = $quiz_array; - } - - update_user_meta( $quiz->user_id, 'llms_quiz_data', $quiz_data ); - - //save quiz object to session - LLMS()->session->set( 'llms_quiz', $quiz ); - - //redirect user to first question in questions - $redirect = get_permalink( $quiz->questions[ 0 ][ 'id' ] ); - wp_redirect( apply_filters( 'lifterlms_lesson_begin_quiz', $redirect ) ); - } - else { - return llms_add_notice( __( 'There was an error starting the quiz. Please return to the lesson and begin again.', 'lifterlms' ), 'error' ); - } - - } - else { - return llms_add_notice( __( 'There was an error starting the quiz. Please return to the lesson and begin again.', 'lifterlms' ), 'error' ); - } - } - /** * Take quiz submit handler from lesson * Redirect user to quiz if quiz is available for lesson. @@ -523,7 +223,7 @@ public function process_free_order() { /** Redirect to success page */ do_action( 'lifterlms_order_process_success', $order ); - //return true; + } /** diff --git a/includes/class.llms.lesson.php b/includes/class.llms.lesson.php index 1bd09bffc1..fc1212ac40 100644 --- a/includes/class.llms.lesson.php +++ b/includes/class.llms.lesson.php @@ -131,7 +131,7 @@ public function get_audio() { * @return string */ public function get_parent_course() { - + //$this->parent_course = get_post_meta( $this->ID, '_parent_course', true ); return $this->parent_course; } @@ -143,7 +143,8 @@ public function get_parent_course() { * @return int [ID of parent section] */ public function get_parent_section() { - global $course; + + $course = new LLMS_Course( $this->parent_course ); $sections = array(); @@ -188,8 +189,8 @@ public function get_prerequisite() { * @return int [ID of next lesson] */ public function get_next_lesson() { - global $course; + $course = new LLMS_Course( $this->parent_course ); $lessons = array(); $current_lesson = $this->id; $parent_section = $this->get_parent_section(); @@ -231,13 +232,13 @@ public function get_next_lesson() { * @return int [ID of previous lesson] */ public function get_previous_lesson() { - global $course; $lessons = array(); $current_lesson = $this->id; $parent_section = $this->get_parent_section(); + $course = new LLMS_Course( $this->parent_course ); - if (is_object($course) ){ + if (is_object( $course ) ){ $syllabus = $course->get_syllabus(); foreach( $syllabus as $key => $value ) { diff --git a/includes/class.llms.quiz.php b/includes/class.llms.quiz.php index 971df6392e..7d670f05d3 100644 --- a/includes/class.llms.quiz.php +++ b/includes/class.llms.quiz.php @@ -100,6 +100,10 @@ public function get_passing_percent() { } + public function get_time_limit() { + return $this->llms_time_limit; + } + /** * returns the total points possible * @return int [sum of all question points] @@ -158,7 +162,7 @@ public function get_user_grade( $user_id ) { } } - return $grade; + return round($grade); } /** @@ -185,7 +189,7 @@ public function get_best_grade( $user_id ) { } $highest_grade = ( empty( $grades ) ? 0 : max( $grades ) ); - return $highest_grade; + return round($highest_grade); } /** @@ -196,22 +200,27 @@ public function get_best_grade( $user_id ) { public function get_best_quiz_attempt( $user_id ) { $quiz = get_user_meta( $user_id, 'llms_quiz_data', true ); $grades = array(); + $unique_id = ''; - foreach ( $quiz as $key => $value ) { - if ( $value['id'] == $this->id ) { - if ( $value['grade'] ) { - array_push( $grades, $value['grade'] ); + if ( $quiz ) { + + foreach ( $quiz as $key => $value ) { + if ( $value['id'] == $this->id ) { + if ( $value['grade'] ) { + array_push( $grades, $value['grade'] ); + } } } - } - $highest_grade = ( empty( $grades ) ? 0 : max( $grades ) ); + $highest_grade = ( empty( $grades ) ? 0 : max( $grades ) ); - foreach ( $quiz as $key => $value ) { - if ( $value['id'] == $this->id && $highest_grade == $value['grade'] ) { - $unique_id = $value['wpnonce']; + foreach ( $quiz as $key => $value ) { + if ( $value['id'] == $this->id && $highest_grade == $value['grade'] ) { + $unique_id = $value['wpnonce']; + } } - } + } + return $unique_id; } @@ -232,7 +241,7 @@ public function get_total_time( $user_id, $unique_id = '' ) { if ( $value['end_date'] ) { $start_date = strtotime( $value['start_date'] ); $end_date = strtotime( $this->get_end_date( $user_id, $unique_id ) ); - $total_time = round( abs( $end_date - $start_date ) / 60, 2 ) . " minutes"; + $total_time = round( round( abs( $end_date - $start_date ) / 60, 2 ) ) . " minutes"; } break; } @@ -240,7 +249,7 @@ public function get_total_time( $user_id, $unique_id = '' ) { if ( $value['end_date'] ) { $start_date = strtotime( $value['start_date'] ); $end_date = strtotime( $this->get_end_date( $user_id ) ); - $total_time = round( abs( $end_date - $start_date ) / 60, 2 ) . " minutes"; + $total_time = round( round( abs( $end_date - $start_date ) / 60, 2 ) ) . " minutes"; } } } @@ -283,19 +292,27 @@ public function get_end_date( $user_id, $unique_id = '' ) { * @return datetime [time user started quiz] */ public function get_start_date( $user_id, $unique_id = '' ) { - $end_date = ''; + $start_date = ''; + $quiz = get_user_meta( $user_id, 'llms_quiz_data', true ); - foreach ( $quiz as $key => $value ) { - if ( $value['wpnonce'] == $unique_id ) { - $start_date = $value['start_date']; - break; - } - elseif ( $value['id'] == $this->id ) { - $start_date = $value['start_date']; + if ( $quiz ) { + + foreach ( $quiz as $key => $value ) { + if ( $value['wpnonce'] == $unique_id ) { + $start_date = $value['start_date']; + break; + } + elseif ( $value['id'] == $this->id ) { + $start_date = $value['start_date']; + } } + + } + return $start_date; + } /** @@ -304,11 +321,12 @@ public function get_start_date( $user_id, $unique_id = '' ) { * @return int [ID of associated lesson with quiz attempt] */ public function get_assoc_lesson( $user_id ) { - $end_date = ''; + + $lesson = false; $quiz = get_user_meta( $user_id, 'llms_quiz_data', true ); if ( ! $quiz ) { - return; + return false; } foreach ( $quiz as $key => $value ) { if ( $value['id'] == $this->id ) { @@ -348,11 +366,20 @@ public function get_remaining_attempts_by_user( $user_id ) { $attempts_allowed = $this->get_total_allowed_attempts(); $attempts = $this->get_total_attempts_by_user( $user_id ); - if ( empty($attempts) ) { - $attempts = 0; - } + if ( !empty( $attempts_allowed ) ) { + + if ( empty($attempts) ) { - $total_attempts_remaining = ($attempts_allowed - $attempts); + $attempts = 0; + } + + $total_attempts_remaining = ($attempts_allowed - $attempts); + + } else { + + $total_attempts_remaining = 'unlimited'; + + } return $total_attempts_remaining; } @@ -422,4 +449,272 @@ public function get_question_key ($question_id) { return $question_key; } + /** + * Start Quiz submit handler + * Performs security and verification checks + * If quiz is enabled for user redirects user to 1st question. + * + * @return void + */ + public static function start_quiz( $quiz_id, $user_id ) { + + $quiz = LLMS()->session->get( 'llms_quiz' ); + + if( $quiz->id == $quiz_id && $quiz->user_id == $user_id ) { + + $quiz->start_date = current_time( 'mysql' ); + $quiz->end_date = ''; + $quiz->grade = 0; + $quiz->passed = false; + + //get existing quiz object from database + $quiz_data = get_user_meta( $quiz->user_id, 'llms_quiz_data', true ); + + //count previous attempts and set quiz attempt to +1 of quiz attempt count + $attempts = 0; + + if( $quiz_data ) { + + foreach( $quiz_data as $key => $value ) { + if( $value[ 'id' ] == $quiz->id ) { + $attempts++; + } + } + } + + $quiz->attempt = ( $attempts + 1 ); + $quiz->wpnonce = wp_create_nonce( 'my-action_' . $quiz->id . $quiz->attempt ); + //add questions to quiz object + //question_id (int), answer (string), correct (bool) + $quiz_obj = new LLMS_Quiz( $quiz->id ); + + //$all_questions = array(); + $questions = $quiz_obj->get_questions(); + + if( $questions ) { + foreach( $questions as $key => $value ) { + $questions[ $key ][ 'answer' ] = ''; + $questions[ $key ][ 'correct' ] = false; + } + + $quiz->questions = $questions; + } + else { + return llms_add_notice( __( 'There are no questions associated with this quiz.', 'lifterlms' ), 'error' ); + } + + //save quiz object to usermeta + $quiz_array = (array)$quiz; + + if( $quiz_data ) { + array_push( $quiz_data, $quiz_array ); + } + else { + $quiz_data = array(); + $quiz_data[] = $quiz_array; + } + + update_user_meta( $quiz->user_id, 'llms_quiz_data', $quiz_data ); + + //save quiz object to session + LLMS()->session->set( 'llms_quiz', $quiz ); + + //return first question in quiz + return $quiz->questions[ 0 ][ 'id' ]; + + } + else { + + $response['message'] = __( 'There was an error starting the quiz. Please return to the lesson and begin again.', 'lifterlms' ); + return $response; + + } + + } + + /** + * answer question form post (next lesson / complete quiz button click) + * inserts answer in database and adds it to current quiz session + * + * @return void + */ + public static function answer_question( $quiz_id, $question_id, $question_type, $answer, $complete ) { + + //get quiz object from session + $quiz = LLMS()->session->get( 'llms_quiz' ); + + //if quiz session does not exist return an error message to the user. + if( empty( $quiz ) ) { + + $response['message'] = __( 'There was an error finding the associated quiz. Please return to the lesson and begin quiz again.', 'lifterlms' ); + return $response; + + } + + //get question meta data + $correct_option = ''; + $question_options = get_post_meta( $question_id, '_llms_question_options', true ); + + foreach( $question_options as $key => $value ) { + if( $value[ 'correct_option' ] ) { + $correct_option = $key; + } + } + + //update quiz object + foreach( (array)$quiz->questions as $key => $value ) { + + if( $value[ 'id' ] == $question_id ) { + + $current_question = $value[ 'id' ]; + + $quiz->questions[ $key ][ 'answer' ] = $answer; + + if( $answer == $correct_option ) { + $quiz->questions[ $key ][ 'correct' ] = true; + } + else { + $quiz->questions[ $key ][ 'correct' ] = false; + } + + } + } + + LLMS()->session->set( 'llms_quiz', $quiz ); + + //update quiz user meta data + $quiz_data = get_user_meta( $quiz->user_id, 'llms_quiz_data', true ); + + foreach( $quiz_data as $key => $value ) { + + if( $value[ 'wpnonce' ] == $quiz->wpnonce ) { + + foreach( $quiz_data[ $key ][ 'questions' ] as $id => $data ) { + if( $data[ 'id' ] == $question_id ) { + + $quiz_data[ $key ][ 'questions' ][ $id ][ 'answer' ] = $quiz->questions[ $id ][ 'answer' ]; + $quiz_data[ $key ][ 'questions' ][ $id ][ 'correct' ] = $quiz->questions[ $id ][ 'correct' ]; + + } + } + } + + } + + update_user_meta( $quiz->user_id, 'llms_quiz_data', $quiz_data ); + + + //if another question exists in lessons array then take user to next question + foreach( (array)$quiz->questions as $k => $q ) { + if( $q[ 'id' ] == $current_question ) { + $next_question = $k + 1; + } + if( !empty( $next_question ) && $k == $next_question ) { + $next_question_id = $q[ 'id' ]; + } + } + + //setup response array + $response = array(); + + //if there is not a next querstion end the quiz + if( empty( $next_question_id ) || $complete ) { + + $quiz->end_date = current_time( 'mysql' ); + //$quiz->attempts = ( $quiz->attempts - 1 ); + + //save quiz object to usermeta + $quiz_array = (array)$quiz; + + if( $quiz_data ) { + + foreach( $quiz_data as $id => $q ) { + + if( $q[ 'wpnonce' ] == $quiz->wpnonce ) { + + $points = 0; + $grade = 0; + + //set the end time + $quiz_data[ $id ][ 'end_date' ] = $quiz->end_date; + + $quiz_obj = new LLMS_Quiz( $quiz->id ); + + //get grade + //get total points earned + foreach( $q[ 'questions' ] as $key => $value ) { + if( $value[ 'correct' ] ) { + $points += $value[ 'points' ]; + } + } + + //calculate grade + if( $points == 0 ) { + $quiz_data[ $id ][ 'grade' ] = 0; + } + else { + $quiz_data[ $id ][ 'grade' ] = $quiz_obj->get_grade( $points ); + + update_user_meta( $quiz->user_id, 'llms_quiz_data', $quiz_data ); + + $quiz_data[ $id ][ 'passed' ] = $quiz_obj->is_passing_score( $quiz->user_id ); + update_user_meta( $quiz->user_id, 'llms_quiz_data', $quiz_data ); + + LLMS()->session->set( 'llms_quiz', $quiz ); + } + + if( $quiz_data[ $id ][ 'passed' ] ) { + $lesson = new LLMS_Lesson( $quiz->assoc_lesson ); + $lesson->mark_complete( $quiz->user_id ); + } + + } + + + } + } + else { + + $response['message'] = __( 'There was an error with your quiz.', 'lifterlms' ); + return $response; + + } + + $response['redirect'] = get_permalink( $quiz->id ); + return $response; + + } + else { + + $response['next_question_id'] = $next_question_id; + return $response; + + } + + } + + /** + * Previous question button click + * Finds the previous question and redirects the user to the post + * + * @return void + */ + public static function previous_question( $question_id ) { + + $quiz = LLMS()->session->get( 'llms_quiz' ); + + foreach( (array)$quiz->questions as $key => $value ) { + if( $value[ 'id' ] == $question_id ) { + $previous_question_key = ( $key - 1 ); + if( $previous_question_key >= 0 ) { + $prev_question_link = get_permalink( $quiz->questions[ $previous_question_key ][ 'id' ] ); + $redirect = get_permalink( $prev_question_link ); + + return $quiz->questions[ $previous_question_key ][ 'id' ]; + + } + } + } + } + } \ No newline at end of file diff --git a/includes/functions/llms.functions.access.php b/includes/functions/llms.functions.access.php index bf49758f30..1992f85194 100644 --- a/includes/functions/llms.functions.access.php +++ b/includes/functions/llms.functions.access.php @@ -401,8 +401,10 @@ function llms_get_prerequisite($user_id, $post_id) { * @return datetime $start_date [Start Date in M, d, Y format] */ function llms_get_course_start_date($post_id) { - $post = get_post($post_id); - $start_date = get_metadata('post', $post->ID, '_course_dates_from', true); + + $post = get_post( $post_id ); + + $start_date = get_post_meta( $post->ID, '_course_dates_from', true ); if ($start_date != '') { $start_date = date('M d, Y', $start_date); @@ -499,7 +501,8 @@ function course_end_date_in_past($post_id) { * @return datetime $lesson_start_date [Start Date in M, d, Y format] */ function llms_get_lesson_start_date($user_id, $post_id) { - $start_date = llms_get_course_start_date(post_id); + + $start_date = llms_get_course_start_date( $post_id ); //TODO if the course start date is not set, default the start date to the date the user enrolled //TODO NOTE: should this be the default, not relevant for me since I never set a start date ... if ( $start_date == '' ) { @@ -529,7 +532,7 @@ function llms_get_lesson_start_date($user_id, $post_id) { * @return bool $result [Does the lesson have a future start date?] */ function lesson_start_date_in_future($user_id, $post_id) { - return course_end_date_in_past(post_id) || (date_create('today') < date_create(llms_get_lesson_start_date($user_id, $post_id))); + return course_end_date_in_past( $post_id ) || (date_create('today') < date_create(llms_get_lesson_start_date($user_id, $post_id))); } /** @@ -540,7 +543,9 @@ function lesson_start_date_in_future($user_id, $post_id) { * @return bool $course_in_future [Does the course have a future start date?] */ function course_start_date_in_future($post_id) { - $start_date = llms_get_course_start_date(post_id); + $start_date = llms_get_course_start_date( $post_id ); + + $course_in_future = false; if ( $start_date != '' ) { if (strtotime('today') < date_create($start_date)) { diff --git a/includes/functions/llms.functions.person.php b/includes/functions/llms.functions.person.php index cbeaf068a9..fc6d459c1f 100644 --- a/includes/functions/llms.functions.person.php +++ b/includes/functions/llms.functions.person.php @@ -127,7 +127,9 @@ function llms_create_new_person( } } - if ( ( 'yes' === get_option( 'lifterlms_registration_require_agree_to_terms' ) ) && ( !empty( get_option( 'lifterlms_terms_page_id' ) ) ) ) { + //get terms page + $terms = get_option( 'lifterlms_terms_page_id' ); + if ( ( 'yes' === get_option( 'lifterlms_registration_require_agree_to_terms' ) ) && $terms ) { if( empty( $agree_to_terms ) ) { return new WP_Error( 'registration-error', __( 'You must agree to the Terms and Conditions.', 'lifterlms' ) ); diff --git a/includes/llms.functions.core.php b/includes/llms.functions.core.php index 1767e4fa74..9901db6022 100644 --- a/includes/llms.functions.core.php +++ b/includes/llms.functions.core.php @@ -534,6 +534,23 @@ function llms_get_template( $template_name, $args = array(), $template_path = '' do_action( 'lifterlms_after_template_part', $template_name, $template_path, $located, $args ); } +function llms_get_template_ajax( $template_name, $args = array(), $template_path = '', $default_path = '' ) { + if ( $args && is_array( $args ) ) { + extract( $args ); + } + + $located = llms_locate_template( $template_name, $template_path, $default_path ); + + //do_action( 'lifterlms_before_template_part', $template_name, $template_path, $located, $args ); + + include( $located ); + $myvar = ob_get_contents(); + ob_end_clean(); + return $myvar; + + // do_action( 'lifterlms_after_template_part', $template_name, $template_path, $located, $args ); +} + /** * Locate Template * diff --git a/includes/llms.template.functions.php b/includes/llms.template.functions.php index d20075c914..13bc11ec28 100644 --- a/includes/llms.template.functions.php +++ b/includes/llms.template.functions.php @@ -89,20 +89,6 @@ function llms_get_post_content( $content ) { return do_shortcode($output_before . $content . $output_after); - case 'llms_question': - $template_before = llms_get_template_part_contents( 'content', 'single-question-before' ); - $template_after = llms_get_template_part_contents( 'content', 'single-question-after' ); - - ob_start(); - load_template($template_before); - $output_before = ob_get_clean(); - - ob_start(); - load_template($template_after); - $output_after = ob_get_clean(); - - return do_shortcode($output_before . $content . $output_after); - default: return $content; } @@ -404,6 +390,66 @@ function lifterlms_template_quiz_attempts() { } } +/** + * Quiz timer + * @return void + */ +if ( ! function_exists( 'lifterlms_template_quiz_time_limit' ) ) { + + function lifterlms_template_quiz_time_limit() { + + llms_get_template( 'quiz/time-limit.php' ); + } +} + +/** + * Quiz timer + * @return void + */ +if ( ! function_exists( 'lifterlms_template_quiz_timer' ) ) { + + function lifterlms_template_quiz_timer() { + + llms_get_template( 'quiz/timer.php' ); + } +} + +/** + * Quiz: wrapper start ( quiz container ) + * @return void + */ +if ( ! function_exists( 'lifterlms_template_quiz_wrapper_start' ) ) { + + function lifterlms_template_quiz_wrapper_start() { + + llms_get_template( 'quiz/quiz-wrapper-start.php' ); + } +} + +/** + * Quiz: wrapper end ( quiz container ) + * @return void + */ +if ( ! function_exists( 'lifterlms_template_quiz_wrapper_end' ) ) { + + function lifterlms_template_quiz_wrapper_end() { + + llms_get_template( 'quiz/quiz-wrapper-end.php' ); + } +} + +/** + * Question: Wrapper for ajax loaded quiz question + * @return void + */ +if ( ! function_exists( 'lifterlms_template_quiz_question' ) ) { + + function lifterlms_template_quiz_question() { + + llms_get_template( 'quiz/quiz-question.php' ); + } +} + /** * Lesson Return link Template Include * @return void @@ -446,9 +492,9 @@ function lifterlms_template_start_button() { */ if ( ! function_exists( 'lifterlms_template_single_next_question' ) ) { - function lifterlms_template_single_next_question() { + function lifterlms_template_single_next_question( $args ) { - llms_get_template( 'quiz/next-question.php' ); + llms_get_template( 'quiz/next-question.php', $args ); } } @@ -458,9 +504,9 @@ function lifterlms_template_single_next_question() { */ if ( ! function_exists( 'lifterlms_template_single_prev_question' ) ) { - function lifterlms_template_single_prev_question() { + function lifterlms_template_single_prev_question( $args ) { - llms_get_template( 'quiz/previous-question.php' ); + llms_get_template( 'quiz/previous-question.php', $args ); } } @@ -470,9 +516,17 @@ function lifterlms_template_single_prev_question() { */ if ( ! function_exists( 'lifterlms_template_single_question_count' ) ) { - function lifterlms_template_single_question_count() { + function lifterlms_template_single_question_count( $args ) { + + llms_get_template( 'quiz/question-count.php', $args ); + } +} + +if ( ! function_exists( 'lifterlms_get_content' ) ) { + + function lifterlms_get_content( $args ) { - llms_get_template( 'quiz/question-count.php' ); + llms_get_template( 'content-single-question.php', $args ); } } @@ -488,15 +542,27 @@ function lifterlms_template_single_single_choice() { } } +/** + * Single Choice Question Template Include AJAX + * @return void + */ +if ( ! function_exists( 'lifterlms_template_single_single_choice_ajax' ) ) { + + function lifterlms_template_single_single_choice_ajax( $args ) { + + llms_get_template( 'quiz/single-choice_ajax.php', $args ); + } +} + /** * Question Wrapper Start Template Include * @return void */ if ( ! function_exists( 'lifterlmslifterlms_template_question_wrapper_start' ) ) { - function lifterlmslifterlms_template_question_wrapper_start() { + function lifterlmslifterlms_template_question_wrapper_start( $args ) { - llms_get_template( 'quiz/wrapper-start.php' ); + llms_get_template( 'quiz/wrapper-start.php', $args ); } } @@ -506,9 +572,9 @@ function lifterlmslifterlms_template_question_wrapper_start() { */ if ( ! function_exists( 'lifterlmslifterlms_template_question_wrapper_end' ) ) { - function lifterlmslifterlms_template_question_wrapper_end() { + function lifterlmslifterlms_template_question_wrapper_end( $args ) { - llms_get_template( 'quiz/wrapper-end.php' ); + llms_get_template( 'quiz/wrapper-end.php', $args ); } } @@ -656,7 +722,7 @@ function llms_setup_lesson_data( $post ) { $courseid = get_post_meta( $post->ID, '_parent_course'); if ( isset($courseid) ) { - $parent_course = get_post( $courseid[0] ); + $parent_course = get_post( $courseid ); } $GLOBALS['lesson'] = get_lesson( $post ); diff --git a/includes/llms.template.hooks.php b/includes/llms.template.hooks.php index 013558d72b..8bf3492117 100644 --- a/includes/llms.template.hooks.php +++ b/includes/llms.template.hooks.php @@ -62,20 +62,27 @@ * QUIZ */ //before Quiz Summary +add_action( 'lifterlms_single_quiz_before_summary', 'lifterlms_template_quiz_timer', 5 ); +add_action( 'lifterlms_single_quiz_before_summary', 'lifterlms_template_quiz_wrapper_start', 5 ); add_action( 'lifterlms_single_quiz_before_summary', 'lifterlms_template_quiz_return_link', 10 ); -add_action( 'lifterlms_single_quiz_before_summary', 'lifterlms_template_quiz_results', 10 ); -add_action( 'lifterlms_single_quiz_before_summary', 'lifterlms_template_passing_percent', 10 ); -add_action( 'lifterlms_single_quiz_before_summary', 'lifterlms_template_quiz_attempts', 10 ); +add_action( 'lifterlms_single_quiz_before_summary', 'lifterlms_template_quiz_results', 15 ); +add_action( 'lifterlms_single_quiz_before_summary', 'lifterlms_template_passing_percent', 20 ); +add_action( 'lifterlms_single_quiz_before_summary', 'lifterlms_template_quiz_attempts', 25 ); +add_action( 'lifterlms_single_quiz_before_summary', 'lifterlms_template_quiz_time_limit', 30 ); //After Quiz Summary +add_action( 'lifterlms_single_quiz_after_summary', 'lifterlms_template_quiz_wrapper_end', 5 ); add_action( 'lifterlms_single_quiz_after_summary', 'lifterlms_template_start_button', 10 ); +add_action( 'lifterlms_single_quiz_after_summary', 'lifterlms_template_quiz_question', 15 ); + + //Before Question Summary add_action( 'lifterlms_single_question_before_summary', 'lifterlmslifterlms_template_question_wrapper_start', 10 ); add_action( 'lifterlms_single_question_before_summary', 'lifterlms_template_single_question_count', 10 ); //After Question Summary -add_action( 'lifterlms_single_question_after_summary', 'lifterlms_template_single_single_choice', 10 ); +add_action( 'lifterlms_single_question_after_summary', 'lifterlms_template_single_single_choice_ajax', 10 ); add_action( 'lifterlms_single_question_after_summary', 'lifterlms_template_single_prev_question', 10 ); add_action( 'lifterlms_single_question_after_summary', 'lifterlms_template_single_next_question', 10 ); add_action( 'lifterlms_single_question_after_summary', 'lifterlmslifterlms_template_question_wrapper_end', 10 ); @@ -83,3 +90,6 @@ + + + diff --git a/lifterlms.php b/lifterlms.php index 7c8a4ba6a3..0f28b8c9ff 100644 --- a/lifterlms.php +++ b/lifterlms.php @@ -3,7 +3,7 @@ * Plugin Name: LifterLMS * Plugin URI: http://lifterlms.com/ * Description: lifterLMS is the easiest way for anyone to create a Learning Management System on the Wordpress platform. -* Version: 1.2.1 +* Version: 1.2.2 * Author: codeBOX * Author URI: http://gocodebox.com * @@ -29,7 +29,7 @@ */ final class LifterLMS { - public $version = '1.2.1'; + public $version = '1.2.2'; protected static $_instance = null; diff --git a/templates/content-single-question-after.php b/templates/content-single-question-after.php index 69930b5240..d2367435bf 100644 --- a/templates/content-single-question-after.php +++ b/templates/content-single-question-after.php @@ -8,7 +8,6 @@ */ if ( ! defined( 'ABSPATH' ) ) exit; - -do_action( 'lifterlms_single_question_after_summary' ); +do_action( 'lifterlms_single_question_after_summary', $args ); ?> diff --git a/templates/content-single-question.php b/templates/content-single-question.php new file mode 100644 index 0000000000..559cac7e2a --- /dev/null +++ b/templates/content-single-question.php @@ -0,0 +1,47 @@ + array( 'llms_question' ), + 'orderby' => 'ASC', + 'post__in' => array( $args['question_id'] ) +); + +$loop = new WP_Query( $query_args ); + +if( ! $loop->have_posts() ) { + get_template_part( 'content', 'none' ); + } + else { + while ($loop->have_posts()): $loop->the_post(); + ob_start(); + do_action( 'lifterlms_single_question_before_summary', $args ); + $html .= ob_get_contents(); + ob_clean(); + + ob_start(); + the_content(); + $html .= ob_get_contents(); + ob_clean(); + + ob_start(); + do_action( 'lifterlms_single_question_after_summary', $args ); + $html .= ob_get_contents(); + ob_clean(); + + endwhile; + } + echo $html; +wp_reset_postdata(); + +?> diff --git a/templates/course/complete-lesson-link.php b/templates/course/complete-lesson-link.php index b0e59d5132..8e2b258b17 100644 --- a/templates/course/complete-lesson-link.php +++ b/templates/course/complete-lesson-link.php @@ -29,24 +29,10 @@ echo __( 'Lesson Complete', 'lifterlms' ); } - } - elseif ($associated_quiz) { - ?> -
+ } - - - - - - -
- -
@@ -61,5 +47,21 @@
+ + +
+ + + + + + + +
+ + diff --git a/templates/course/lesson-navigation.php b/templates/course/lesson-navigation.php index e76cffe45d..b8da4ccb6a 100644 --- a/templates/course/lesson-navigation.php +++ b/templates/course/lesson-navigation.php @@ -5,7 +5,7 @@ */ if ( ! defined( 'ABSPATH' ) ) exit; -global $post, $course, $lesson, $lifterlms; +global $post, $lesson; ?>