/**
 * Handle the question deletion from the question pool page.
 * @param PageBuilder $page The page rendering object.
 */
function WPCW_quizzes_handleQuestionDeletion($page)
{
    global $wpcwdb, $wpdb;
    $wpdb->show_errors();
    // Check that the question exists and deletion has been requested
    if (isset($_GET['action']) && $_GET['action'] == 'delete' && isset($_GET['question_id'])) {
        $questionID = $_GET['question_id'];
        $questionDetails = WPCW_questions_getQuestionDetails($questionID);
        // Only do deletion if question details are valid.
        if ($questionDetails) {
            // Get tags for questions
            $question_tags = WPCW_questions_getQuestionDetails($questionID, $getTagsToo = true);
            // Remove tags for each question
            foreach ($question_tags->tags as $question_tag) {
                WPCW_questions_tags_removeTag($questionID, $question_tag->question_tag_id);
            }
            // Delete question from question map
            $wpdb->query($wpdb->prepare("\n\t\t\t\tDELETE FROM {$wpcwdb->quiz_qs_mapping}\n\t\t\t\tWHERE question_id = %d\n\t\t\t", $questionDetails->question_id));
            // Finally delete question itself
            $wpdb->query($wpdb->prepare("\n\t\t\t\tDELETE FROM {$wpcwdb->quiz_qs} \n\t\t\t\tWHERE question_id = %d\n\t\t\t", $questionDetails->question_id));
            $page->showMessage(sprintf(__('The question \'%s\' was successfully deleted.', 'wp_courseware'), $questionDetails->question_question));
        }
        // end of if $questionDetails
    }
    // end of check for deletion action
}
Example #2
0
 /**
  * Handle exporting the XML for all of the questions.
  * 
  * @param String The XML for the quiz in this unit.
  */
 function export_content_handleQuestionsAndTags()
 {
     $xml = false;
     if (empty($this->questionList)) {
         return $xml;
     }
     // Copied so we can update the master list only without adding to the work that this loop does.
     $questionIDListForExpanding = $this->questionList;
     // ### Expand Random Questions - If we have any random questions - we need all questions that they use.
     foreach ($questionIDListForExpanding as $questionID => $singleQuestionDetails) {
         // We've got a random selection, so we need to get all questions that fall into this
         // particular selection, and remove this random selection before it's exported.
         if ('random_selection' == $singleQuestionDetails->question_type) {
             // Expand the tags into an array.
             $decodedTags = WPCW_quiz_RandomSelection::decodeTagSelection($singleQuestionDetails->question_question);
             if (!empty($decodedTags)) {
                 // Got any questions for these tags?
                 $questionsForTag = WPCW_quiz_RandomSelection::questionSelection_getAllQuestionsFromTags($decodedTags);
                 // Yep, so add them to the list, ignoring duplicates.
                 if (!empty($questionsForTag)) {
                     $this->questionList = $this->questionList + $questionsForTag;
                 }
                 // If we have a whole pool flag, then we need to get all questions that exist. But this code
                 // doesn't check for the whole pool flag, as this export is an expensive process anyway, so
                 // for simplicity, we're not checking for the single exception.
             }
             // Now remove this question, as it's a random question that can't be exported.
             unset($this->questionList[$questionID]);
         }
         // end if random selection check
     }
     global $fieldsToProcess_quizzes, $fieldsToProcess_quiz_questions;
     $questionParentPath = '/questions';
     $newQuestionIndex = 1;
     foreach ($this->questionList as $questionID => $singleQuestionDetails) {
         // Check question is valid - just in case.
         $questionDetails = WPCW_questions_getQuestionDetails($questionID, true);
         if (!$questionDetails) {
             continue;
         }
         // Create a new hash for this question ID for the XML file so that we can map
         // questions to quizzes. Intentionally using odd numbers only, to help with spotting
         // any potential errors with import.
         $this->questionList[$questionID]->question_hash = $questionDetails->question_hash = 'wpcwqid_' . $newQuestionIndex;
         $newQuestionIndex += 2;
         // Increment by 2, to allow us to spot issues.
         // ### Question - Start
         $xml .= $this->export_objectToXML('question', false, $questionDetails, $fieldsToProcess_quiz_questions, $questionParentPath, false);
         // Debug - check we have all the right fields for this question
         //$this->debug_courseCheckFieldsWeHave($questionDetails, $fieldsToProcess_quiz_questions);
         // ### Questions - question_data_answers
         // Handle the serialized 'question_data_answers' field e.g.
         /*
         				 [question_data_answers] => Array
                          	(
         						[1] => Array
                                 (
         							[answer] => RHJpenpsZQ==
         						)
         
                                     [2] => Array
                                         (
                                             [answer] => RHJpcA==
                                         )
         
                                     [3] => Array
                                         (
                                             [answer] => Q2xvdWRidXJzdA==
                                         )
         
                                     [4] => Array
                                         (
                                             [answer] => Q2F0cyAmIERvZ3M=
                                         )
         
                                 )
         */
         $questionDetails->question_data_answers = maybe_unserialize($questionDetails->question_data_answers);
         // Use this to numerically order the answers
         $questionidx = 1;
         if (!empty($questionDetails->question_data_answers) && is_array($questionDetails->question_data_answers)) {
             $dataToBeExported = array();
             foreach ($questionDetails->question_data_answers as $idx => $details) {
                 $dataToBeExported['possible_answer_' . $questionidx] = $details['answer'];
                 // Do we have an image for this answer? If so, then add it with it's own tag for simplcity.
                 if (isset($details['image'])) {
                     $dataToBeExported['possible_answer_' . $questionidx . '_image'] = $details['image'];
                 }
                 $questionidx++;
             }
             $xml .= $this->export_arrayToXML('question_data_answers', false, $dataToBeExported, false, $questionParentPath . '/question', '/question_data_answers');
         }
         // ###ÊQuestion - Tags - Start
         if (!empty($questionDetails->tags)) {
             $tagParentPath = $questionParentPath . '/question';
             $xml .= $this->export_startBlock($tagParentPath, 'tags');
             // Render tags as question->tags->tag
             foreach ($questionDetails->tags as $singleTag) {
                 $xml .= $this->export_textData('tag', $singleTag->question_tag_name, $tagParentPath . '/tags/');
             }
             // ###ÊQuestion - Tags - End
             $xml .= $this->export_endBlock($questionParentPath . '/question', 'tags');
         }
         // ### Question - End
         $xml .= $this->export_endBlock($questionParentPath, 'question');
         flush();
     }
     return $xml;
 }
Example #3
0
/**
 * Function called when a new question tag is added.
 */
function WPCW_AJAX_handleQuestionNewTag()
{
    $ajaxResults = array('success' => true, 'errormsg' => __('Unfortunately there was a problem adding the tag.', 'wp_courseware'), 'html' => false);
    // Assume that we may have multiple tags, separated by commas.
    $potentialTagList = explode(',', WPCW_arrays_getValue($_POST, 'tagtext'));
    $cleanTagList = array();
    // Check if question is expected to have been saved.
    $hasQuestionBeenSaved = 'yes' == WPCW_arrays_getValue($_POST, 'isquestionsaved');
    // Got potential tags
    if (!empty($potentialTagList)) {
        // Clean up each tag, and add to a list.
        foreach ($potentialTagList as $potentialTag) {
            $cleanTagList[] = sanitize_text_field(stripslashes($potentialTag));
        }
        // Check that cleaned tags are ok too
        if (!empty($cleanTagList)) {
            // Do this if the question exists and we're adding tags.
            if ($hasQuestionBeenSaved) {
                // Get the ID of the question we're adding this tag to.
                $questionID = intval(WPCW_arrays_getValue($_POST, 'questionid'));
                // Validate that the question exists before we tag it.
                $questionDetails = WPCW_questions_getQuestionDetails($questionID);
                if (!$questionDetails) {
                    $ajaxResults['errormsg'] = __('Unfortunately that question could not be found, so the tag could not be added.', 'wp_courseware');
                    $ajaxResults['success'] = false;
                } else {
                    // Add the tag to the database, get a list of the tag details now that they have been added.
                    $tagDetailList = WPCW_questions_tags_addTags($questionID, $cleanTagList);
                    foreach ($tagDetailList as $tagAddedID => $tagAddedText) {
                        // Create the HTML to show the new tag.
                        $ajaxResults['html'] .= sprintf('<span><a data-questionid="%d" data-tagid="%d" class="ntdelbutton">X</a>&nbsp;%s</span>', $questionID, $tagAddedID, $tagAddedText);
                    }
                }
                // else question found
            } else {
                $tagDetailList = WPCW_questions_tags_addTags_withoutQuestion($cleanTagList);
                // For a new question, the ID is a string, not a value.
                $questionIDStr = WPCW_arrays_getValue($_POST, 'questionid');
                // Create a hidden form entry plus the little tag, so that we can add the tag to the question when we save.
                foreach ($tagDetailList as $tagAddedID => $tagAddedText) {
                    // Create the HTML to show the new tag. We'll add the full string to the hidden field so that we can
                    // add the tags later.
                    $ajaxResults['html'] .= sprintf('
								<span>
									<a data-questionid="%d" data-tagid="%d" class="ntdelbutton">X</a>&nbsp;%s
									<input type="hidden" name="tags_to_add%s[]" value="%s" />
								</span>
								', 0, $tagAddedID, $tagAddedText, $questionIDStr, addslashes($tagAddedText));
                }
                // end foreach
            }
        }
    }
    header('Content-Type: application/json');
    echo json_encode($ajaxResults);
    die;
}
/**
 * Function that allows a question to be edited.
 */
function WPCW_showPage_ModifyQuestion_load()
{
    $page = new PageBuilder(true);
    $page->showPageHeader(__('Edit Single Question', 'wp_courseware'), '70%', WPCW_icon_getPageIconURL());
    $questionID = false;
    // Check POST and GET
    if (isset($_GET['question_id'])) {
        $questionID = $_GET['question_id'] + 0;
    } else {
        if (isset($_POST['question_id'])) {
            $questionID = $_POST['question_id'] + 0;
        }
    }
    // Trying to edit a question
    $questionDetails = WPCW_questions_getQuestionDetails($questionID, true);
    // Abort if question not found.
    if (!$questionDetails) {
        $page->showMessage(__('Sorry, but that question could not be found.', 'wp_courseware'), true);
        $page->showPageFooter();
        return;
    }
    // See if the question has been submitted for saving.
    if ('true' == WPCW_arrays_getValue($_POST, 'question_save_mode')) {
        WPCW_handler_questions_processSave(false, true);
        $page->showMessage(__('Question successfully updated.', 'wp_courseware'));
        // Assume save has happened, so reload the settings.
        $questionDetails = WPCW_questions_getQuestionDetails($questionID, true);
    }
    // Manually set the order to zero, as not needed for ordering in this context.
    $questionDetails->question_order = 0;
    switch ($questionDetails->question_type) {
        case 'multi':
            $quizObj = new WPCW_quiz_MultipleChoice($questionDetails);
            break;
        case 'truefalse':
            $quizObj = new WPCW_quiz_TrueFalse($questionDetails);
            break;
        case 'open':
            $quizObj = new WPCW_quiz_OpenEntry($questionDetails);
            break;
        case 'upload':
            $quizObj = new WPCW_quiz_FileUpload($questionDetails);
            break;
        default:
            die(__('Unknown quiz type: ', 'wp_courseware') . $questionDetails->question_type);
            break;
    }
    $quizObj->showErrors = true;
    $quizObj->needCorrectAnswers = true;
    $quizObj->hideDragActions = true;
    // #wpcw_quiz_details_questions = needed for media uploader
    // .wpcw_question_holder_static = needed for wrapping the question using existing HTML.
    printf('<div id="wpcw_quiz_details_questions"><ul class="wpcw_question_holder_static">');
    // Create form wrapper, so that we can save this question.
    printf('<form method="POST" action="%s?page=WPCW_showPage_ModifyQuestion&question_id=%d" />', admin_url('admin.php'), $questionDetails->question_id);
    // Question hidden fields
    printf('<input name="question_id" type="hidden" value="%d" />', $questionDetails->question_id);
    printf('<input name="question_save_mode" type="hidden" value="true" />');
    // Show the quiz so that it can be edited. We're re-using the code we have for editing questions,
    // to save creating any special form edit code.
    echo $quizObj->editForm_toString();
    // Save and return buttons.
    printf('<div class="wpcw_button_group"><br/>');
    printf('<a href="%s?page=WPCW_showPage_QuestionPool" class="button-secondary">%s</a>&nbsp;&nbsp;', admin_url('admin.php'), __('&laquo; Return to Question Pool', 'wp_courseware'));
    printf('<input type="submit" class="button-primary" value="%s" />', __('Save Question Details', 'wp_courseware'));
    printf('</div>');
    printf('</form>');
    printf('</ul></div>');
    $page->showPageFooter();
}
Example #5
0
function wpcw_tag_cleanup()
{
    global $wpdb, $wpcwdb;
    $wpcwdb = new WPCW_Database();
    $tags = array();
    $SQL = "SELECT *\n\t\t\tFROM {$wpcwdb->question_tag_mapping}";
    $tags = $wpdb->get_results($SQL);
    foreach ($tags as $tag) {
        $questionDetails = WPCW_questions_getQuestionDetails($tag->question_id);
        if (!$questionDetails) {
            WPCW_questions_tags_removeTag($tag->question_id, $tag->tag_id);
        }
        WPCW_questions_tags_updatePopularity($tag->tag_id);
    }
}