PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.10
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.10
4.4.10 4.4.9.1 4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 All 142 releases
← All changes | assets/src/apps/js/frontend/quiz/components/questions/question.js +292 -245 4.3.8 → 4.4.10 View file →
@@ -1,245 +1,292 @@
1 -import { Component, Fragment } from '@wordpress/element';
2 -import { withSelect, withDispatch } from '@wordpress/data';
3 -import { compose } from '@wordpress/compose';
4 -import { __, sprintf } from '@wordpress/i18n';
5 -import Buttons from './buttons';
6 -import { MaybeShowButton } from '../buttons';
7 -import { default as ButtonCheck } from '../buttons/button-check';
8 -import { default as ButtonHint } from '../buttons/button-hint';
9 -
10 -const $ = window.jQuery;
11 -const { uniqueId, isArray, isNumber, bind } = lodash;
12 -
13 -class Question extends Component {
14 - constructor() {
15 - super( ...arguments );
16 -
17 - this.state = {
18 - time: null,
19 - showHint: false,
20 - };
21 -
22 - this.$wrap = null;
23 - }
24 -
25 - componentDidMount( a ) {
26 - const {
27 - question,
28 - isCurrent,
29 - markQuestionRendered,
30 - } = this.props;
31 -
32 - if ( isCurrent ) {
33 - markQuestionRendered( question.id );
34 - }
35 -
36 - if ( ! this.state.time ) {
37 - this.setState( {
38 - time: new Date(),
39 - } );
40 - }
41 -
42 - LP.Hook.doAction( 'lp-question-compatible-builder' );
43 -
44 - if ( typeof MathJax !== 'undefined' && typeof MathJax.Hub !== 'undefined' ) {
45 - MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] );
46 - }
47 -
48 - return a;
49 - }
50 -
51 - setRef = ( el ) => {
52 - this.$wrap = $( el );
53 - };
54 -
55 - parseOptions = ( options ) => {
56 - if ( options ) {
57 - options = ! isArray( options ) ? JSON.parse( CryptoJS.AES.decrypt( options.data, options.key, { format: CryptoJSAesJson } ).toString( CryptoJS.enc.Utf8 ) ) : options;
58 - options = ! isArray( options ) ? JSON.parse( options ) : options;
59 - }
60 -
61 - return options || [];
62 - };
63 -
64 - getWrapperClass = () => {
65 - const { question, answered } = this.props;
66 -
67 - const classes = [ 'question', 'question-' + question.type ];
68 - const options = this.parseOptions( question.options );
69 -
70 - if ( options.length && options[ 0 ].isTrue !== undefined ) {
71 - classes.push( 'question-answered' );
72 - }
73 -
74 - return classes;
75 - };
76 -
77 - getEditLink = () => {
78 - const {
79 - question,
80 - editPermalink,
81 - } = this.props;
82 -
83 - return editPermalink ? editPermalink.replace( /post=(.*[0-9])/, `post=${ question.id }` ) : '';
84 - };
85 -
86 - editPermalink = ( editPermalink ) => {
87 - return sprintf( '<a href="%s">%s</a>', editPermalink, __( 'Edit', 'learnpress' ) );
88 - };
89 -
90 - render() {
91 - const {
92 - question,
93 - isShow,
94 - isShowIndex,
95 - isShowHint,
96 - status,
97 - } = this.props;
98 -
99 - const QuestionTypes = LP.questionTypes.default;
100 - const editPermalink = this.getEditLink();
101 -
102 - if ( editPermalink ) {
103 - jQuery( '#wp-admin-bar-edit-lp_question' ).find( '.ab-item' ).attr( 'href', editPermalink );
104 - }
105 -
106 - const titleParts = {
107 - index: () => {
108 - return ( isShowIndex ? <span className="question-index">{ isShowIndex }.</span> : '' );
109 - },
110 -
111 - title: () => {
112 - return ( <span dangerouslySetInnerHTML={ { __html: question.title } } /> );
113 - },
114 -
115 - hint: () => {
116 - return <ButtonHint question={ question }></ButtonHint>;
117 - },
118 -
119 - 'edit-permalink': () => {
120 - return (
121 - editPermalink && (
122 - <span
123 - dangerouslySetInnerHTML={ { __html: this.editPermalink( editPermalink ) } }
124 - className="edit-link">
125 - </span>
126 - )
127 - );
128 - },
129 - };
130 -
131 - const blocks = {
132 - title: () => {
133 - return (
134 - <h4 className="question-title">
135 - { LP.config.questionTitleParts().map( ( name ) => {
136 - return (
137 - <Fragment key={ `title-part-${ name }` }>
138 - { titleParts[ name ] && titleParts[ name ]() }
139 - </Fragment>
140 - );
141 - } ) }
142 - </h4>
143 - );
144 - },
145 -
146 - content: () => {
147 - return (
148 - <div className="question-content" dangerouslySetInnerHTML={ { __html: question.content } } />
149 - );
150 - },
151 -
152 - 'answer-options': () => {
153 - return (
154 - this.$wrap && <QuestionTypes { ...{ ...this.props, $wrap: this.$wrap } } />
155 - );
156 - },
157 -
158 - explanation: () => {
159 - return (
160 - question.explanation && (
161 - <>
162 - <div className="question-explanation-content">
163 - <strong className="explanation-title">{ __( 'Explanation', 'learnpress' ) }:</strong>
164 - <div dangerouslySetInnerHTML={ { __html: question.explanation } }>
165 - </div>
166 - </div>
167 - </>
168 - )
169 - );
170 - },
171 -
172 - hint: () => {
173 - return (
174 - question.hint && ! question.explanation && question.showHint && (
175 - <>
176 - <div className="question-hint-content">
177 - <strong className="hint-title">{ __( 'Hint', 'learnpress' ) }:</strong>
178 - <div dangerouslySetInnerHTML={ { __html: question.hint } } />
179 - </div>
180 - </>
181 - )
182 - );
183 - },
184 -
185 - buttons: () => {
186 - return (
187 - ( 'started' === status ) && <Buttons question={ question } />
188 - );
189 - },
190 - };
191 -
192 - const configBlocks = LP.config.questionBlocks();
193 -
194 - return (
195 - <>
196 - <div className={ this.getWrapperClass().join( ' ' ) }
197 - style={ { display: isShow ? '' : 'none' } }
198 - data-id={ question.id }
199 - ref={ this.setRef }>
200 -
201 - { configBlocks.map( ( name ) => {
202 - return (
203 - <Fragment key={ `block-${ name }` }>
204 - { blocks[ name ] ? blocks[ name ]() : '' }
205 - </Fragment>
206 - );
207 - } ) }
208 - </div>
209 - </>
210 - );
211 - }
212 -}
213 -
214 -export default compose( [
215 - withSelect( ( select, { question: { id } } ) => {
216 - const {
217 - getData,
218 - getQuestionAnswered,
219 - getQuestionMark,
220 - } = select( 'learnpress/quiz' );
221 -
222 - return {
223 - status: getData( 'status' ),
224 - questions: getData( 'question' ),
225 - answered: getQuestionAnswered( id ),
226 - questionsRendered: getData( 'questionsRendered' ),
227 - editPermalink: getData( 'editPermalink' ),
228 - numPages: getData( 'numPages' ),
229 - mark: getQuestionMark( id ) || '',
230 - };
231 - } ),
232 - withDispatch( ( dispatch ) => {
233 - const {
234 - updateUserQuestionAnswers,
235 - updateUserQuestionFibAnswers,
236 - markQuestionRendered,
237 - } = dispatch( 'learnpress/quiz' );
238 -
239 - return {
240 - markQuestionRendered,
241 - updateUserQuestionAnswers,
242 - updateUserQuestionFibAnswers,
243 - };
244 - } ),
245 -] )( Question );
1 +import { Component, Fragment } from '@wordpress/element';
2 +import { withSelect, withDispatch } from '@wordpress/data';
3 +import { compose } from '@wordpress/compose';
4 +import { __, sprintf } from '@wordpress/i18n';
5 +import Buttons from './buttons';
6 +import { MaybeShowButton } from '../buttons';
7 +import { default as ButtonCheck } from '../buttons/button-check';
8 +import { default as ButtonHint } from '../buttons/button-hint';
9 +
10 +const $ = window.jQuery;
11 +const { uniqueId, isArray, isNumber, bind } = lodash;
12 +
13 +class Question extends Component {
14 + constructor() {
15 + super( ...arguments );
16 +
17 + this.state = {
18 + time: null,
19 + showHint: false,
20 + };
21 +
22 + this.$wrap = null;
23 + }
24 +
25 + componentDidMount( a ) {
26 + const { question, isCurrent, markQuestionRendered } = this.props;
27 +
28 + if ( isCurrent ) {
29 + markQuestionRendered( question.id );
30 + }
31 +
32 + if ( ! this.state.time ) {
33 + this.setState( {
34 + time: new Date(),
35 + } );
36 + }
37 +
38 + LP.Hook.doAction( 'lp-question-compatible-builder' );
39 +
40 + if (
41 + typeof MathJax !== 'undefined' &&
42 + typeof MathJax.Hub !== 'undefined'
43 + ) {
44 + MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] );
45 + }
46 +
47 + return a;
48 + }
49 +
50 + setRef = ( el ) => {
51 + this.$wrap = $( el );
52 + };
53 +
54 + parseOptions = ( options ) => {
55 + if ( options ) {
56 + options = ! isArray( options )
57 + ? JSON.parse(
58 + CryptoJS.AES.decrypt( options.data, options.key, {
59 + format: CryptoJSAesJson,
60 + } ).toString( CryptoJS.enc.Utf8 )
61 + )
62 + : options;
63 + options = ! isArray( options ) ? JSON.parse( options ) : options;
64 + }
65 +
66 + return options || [];
67 + };
68 +
69 + getWrapperClass = () => {
70 + const { question, answered } = this.props;
71 +
72 + const classes = [ 'question', 'question-' + question.type ];
73 + const options = this.parseOptions( question.options );
74 +
75 + if ( options.length && options[ 0 ].isTrue !== undefined ) {
76 + classes.push( 'question-answered' );
77 + }
78 +
79 + return classes;
80 + };
81 +
82 + getEditLink = () => {
83 + const { question, editPermalink } = this.props;
84 +
85 + return editPermalink
86 + ? editPermalink.replace( /post=(.*[0-9])/, `post=${ question.id }` )
87 + : '';
88 + };
89 +
90 + editPermalink = ( editPermalink ) => {
91 + return sprintf(
92 + '<a href="%s">%s</a>',
93 + editPermalink,
94 + __( 'Edit', 'learnpress' )
95 + );
96 + };
97 +
98 + render() {
99 + const { question, isShow, isShowIndex, isShowHint, status, results } =
100 + this.props;
101 +
102 + if (
103 + results &&
104 + results.questions &&
105 + results.questions[ question.id ]
106 + ) {
107 + if (
108 + typeof results.questions[ question.id ].correct !== 'undefined'
109 + ) {
110 + question.correct = results.questions[ question.id ].correct;
111 + }
112 + }
113 +
114 + const QuestionTypes = LP.questionTypes.default;
115 + const editPermalink = this.getEditLink();
116 +
117 + if ( editPermalink ) {
118 + jQuery( '#wp-admin-bar-edit-lp_question' )
119 + .find( '.ab-item' )
120 + .attr( 'href', editPermalink );
121 + }
122 +
123 + const titleParts = {
124 + index: () => {
125 + return isShowIndex ? (
126 + <span className="question-index">{ isShowIndex }.</span>
127 + ) : (
128 + ''
129 + );
130 + },
131 +
132 + title: () => {
133 + return (
134 + <span
135 + dangerouslySetInnerHTML={ { __html: question.title } }
136 + />
137 + );
138 + },
139 +
140 + hint: () => {
141 + return <ButtonHint question={ question }></ButtonHint>;
142 + },
143 +
144 + 'edit-permalink': () => {
145 + return (
146 + editPermalink && (
147 + <span
148 + dangerouslySetInnerHTML={ {
149 + __html: this.editPermalink( editPermalink ),
150 + } }
151 + className="edit-link"
152 + ></span>
153 + )
154 + );
155 + },
156 + };
157 +
158 + const blocks = {
159 + title: () => {
160 + return (
161 + <h4 className="question-title">
162 + { LP.config.questionTitleParts().map( ( name ) => {
163 + return (
164 + <Fragment key={ `title-part-${ name }` }>
165 + { titleParts[ name ] &&
166 + titleParts[ name ]() }
167 + </Fragment>
168 + );
169 + } ) }
170 + </h4>
171 + );
172 + },
173 +
174 + content: () => {
175 + return (
176 + <div
177 + className="question-content"
178 + dangerouslySetInnerHTML={ { __html: question.content } }
179 + />
180 + );
181 + },
182 +
183 + 'answer-options': () => {
184 + return (
185 + this.$wrap && (
186 + <QuestionTypes
187 + { ...{ ...this.props, $wrap: this.$wrap } }
188 + />
189 + )
190 + );
191 + },
192 +
193 + explanation: () => {
194 + return (
195 + question.explanation && (
196 + <>
197 + <div className="question-explanation-content">
198 + <strong className="explanation-title">
199 + { __( 'Explanation', 'learnpress' ) }:
200 + </strong>
201 + <div
202 + dangerouslySetInnerHTML={ {
203 + __html: question.explanation,
204 + } }
205 + ></div>
206 + </div>
207 + </>
208 + )
209 + );
210 + },
211 +
212 + hint: () => {
213 + return (
214 + question.hint &&
215 + ! question.explanation &&
216 + question.showHint && (
217 + <>
218 + <div className="question-hint-content">
219 + <strong className="hint-title">
220 + { __( 'Hint', 'learnpress' ) }:
221 + </strong>
222 + <div
223 + dangerouslySetInnerHTML={ {
224 + __html: question.hint,
225 + } }
226 + />
227 + </div>
228 + </>
229 + )
230 + );
231 + },
232 +
233 + buttons: () => {
234 + return (
235 + 'started' === status && <Buttons question={ question } />
236 + );
237 + },
238 + };
239 +
240 + const configBlocks = LP.config.questionBlocks();
241 +
242 + return (
243 + <>
244 + <div
245 + className={ this.getWrapperClass().join( ' ' ) }
246 + style={ { display: isShow ? '' : 'none' } }
247 + data-id={ question.id }
248 + ref={ this.setRef }
249 + >
250 + { configBlocks.map( ( name ) => {
251 + return (
252 + <Fragment key={ `block-${ name }` }>
253 + { blocks[ name ] ? blocks[ name ]() : '' }
254 + </Fragment>
255 + );
256 + } ) }
257 + </div>
258 + </>
259 + );
260 + }
261 +}
262 +
263 +export default compose( [
264 + withSelect( ( select, { question: { id } } ) => {
265 + const { getData, getQuestionAnswered, getQuestionMark } =
266 + select( 'learnpress/quiz' );
267 +
268 + return {
269 + status: getData( 'status' ),
270 + questions: getData( 'question' ),
271 + answered: getQuestionAnswered( id ),
272 + questionsRendered: getData( 'questionsRendered' ),
273 + editPermalink: getData( 'editPermalink' ),
274 + numPages: getData( 'numPages' ),
275 + mark: getQuestionMark( id ) || '',
276 + results: getData( 'results' ),
277 + };
278 + } ),
279 + withDispatch( ( dispatch ) => {
280 + const {
281 + updateUserQuestionAnswers,
282 + updateUserQuestionFibAnswers,
283 + markQuestionRendered,
284 + } = dispatch( 'learnpress/quiz' );
285 +
286 + return {
287 + markQuestionRendered,
288 + updateUserQuestionAnswers,
289 + updateUserQuestionFibAnswers,
290 + };
291 + } ),
292 +] )( Question );