public static function startNewSeason($clusterIdentifier)
 {
     $season = QuizHallOfFame::getCurrentSeason($clusterIdentifier);
     $db = MMDB::instance();
     $players = $db->arrayQuery( sprintf("
         SELECT uuid
         FROM quiz_player_scoring
         WHERE user_cluster = '%s'",
         $db->escapeString( $clusterIdentifier )
     ));
     $db->begin();
     foreach($players as $player)
     {
         $uuid = $player['uuid'];
         QuizReply::moveToArchive($uuid, $season);
     }
     QuizPlayerScoring::moveToArchive($clusterIdentifier, $season);
     $db->commit();
 }
Пример #2
0
    /**
     * @param int $quizId
     * @param int $applicationId
     * @return array
     */
    static function getQuizData( $quizId, $applicationId, $isLocalQuiz = true )
    {
        $quizData = self::fetchOneBy( array( 'quiz_id' => $quizId, 'application_id' => $applicationId ) );
        if( !$quizData )
        {
            // We don't have the quiz meta for the requested quiz, we try to create it (happens only once)
            $object =& eZContentObject::fetch( $quizId );
            if( !$object )
                return null;
            /* @type $dm eZContentObjectAttribute[] */
            $dm = $object->DataMap();
            $mc = $dm['media_content']->content();
            if( isset( $mc['relation_list'][0]['node_id'] ) )
            {
                $quiz =& eZContentObjectTreeNode::fetch( $mc['relation_list'][0]['node_id'] );
                /* @type $quizDM eZContentObjectAttribute[] */
                $quizDM = $quiz->DataMap();
                self::add( $quizId, ClusterTool::clusterIdentifier(), $applicationId, (int)$quizDM['points']->content(), (int)$quizDM['correct_reply']->content() );
                $quizData = self::fetchOneBy( array( 'quiz_id' => $quizId, 'application_id' => $applicationId ) );
            } else {
                return null;
            }
        }
        $currentMMUser = MMUsers::getCurrentUserObject();
        $currentUserResponse = false;
        $nbCorrect     = (int)$quizData->attribute( 'nb_correct' );
        $nbWrong       = (int)$quizData->attribute( 'nb_wrong' );
        if ( $currentMMUser )
        {
            $responseFetchParams = array(
                'quiz_id' => $quizId,
                'uuid' => $currentMMUser->attribute( 'uuid' ),
                'application_id' => $applicationId
            );
            if (!$isLocalQuiz)
            {
                $responseFetchParams['cluster_identifier'] = null;
            }
            $currentUserResponse = QuizReply::fetchOneBy( $responseFetchParams );
        }

        if( $currentUserResponse )
        {
            $currentUserResponded = true;
            $answerWasCorrect = (bool)$currentUserResponse->attribute( 'is_correct' );
        }
        else
        {
            $currentUserResponded = false;
            $answerWasCorrect = false;
        }
        $speRepliesResult = array( 'total' => 0, 'correct' => 0, 'wrong' => 0 );
        $userSpecialtyTranslations = FacetFilteringTool::getTaxoTranslationWithIDs( 'user_specialty' );
        if ( $currentMMUser )
        {
            $userSpecialtyId = $userSpecialtyTranslations[$currentMMUser->attribute( 'user_speciality' )]['id'];
            $speReplies = QuizReply::fetchBySpecialtyInScoring( $currentMMUser->attribute( 'uuid' ), $quizId, $applicationId, $userSpecialtyId );
            if( $speReplies )
            {
                $speRepliesResult['total'] = count( $speReplies );
                foreach( $speReplies as $reply )
                {
                    if( $reply['is_correct'] == 1 )
                        $speRepliesResult['correct']++;
                    else
                        $speRepliesResult['wrong']++;
                }
            }
        }
        $response = array(
            'points'                 => (int)$quizData->attribute( 'points' ),
            'correct_answer'         => (int)$quizData->attribute( 'correct_answer' ),
            'global_answers'         => array( 'total' => ( $nbCorrect + $nbWrong ), 'correct' => $nbCorrect, 'wrong' => $nbWrong ),
            'specialty_answers'      => $speRepliesResult,
            'current_user_responded' => $currentUserResponded,
            'answer_was_correct'     => $answerWasCorrect
        );
        if( $currentUserResponded )
        {
            /* @type $quizArticleDM eZContentObjectAttribute[] */
            $quizArticleDM   = eZContentObject::fetch( $quizId )->DataMap();
            $mediaContent    = $quizArticleDM["media_content"]->content();
            $quizDM          = eZContentObjectTreeNode::fetch( $mediaContent['relation_list'][0]['node_id'] )->DataMap();
            $outputHandler   = new eZXHTMLXMLOutput( $quizDM['commented_answer']->DataText, false );
            $commentedAnswer = $outputHandler->outputText();
            $response['commented_answer'] = $commentedAnswer;
        }
        return $response;
    }
    /**
     * @return array
     */
    protected function submitQuizReply()
    {
        if (!$this->user())
        {
            return null;
        }
        $season = QuizHallOfFame::getCurrentSeason(ClusterTool::clusterIdentifier());
        $isLocalQuiz = $this->isLocalQuiz();

        $quizId = $_POST['qid'];
        $quizObject = eZContentObject::fetch($quizId);
        $dataMap = $quizObject->dataMap();

        $publicationDateTimestamp = $dataMap['online_date']->content()->timeStamp();
        $publicationDate = DateTime::createFromFormat('U', $publicationDateTimestamp);

        $questionSeason = QuizHallOfFame::calculateSeason($publicationDate);

        if ($questionSeason > $season && !$this->isLocalQuiz())
        {
            QuizPlayerScoring::startNewSeason(ClusterTool::clusterIdentifier());
        }

        $fetchParams = array(
            'quiz_id' => $quizId,
            'uuid' => $this->user()->attribute( 'uuid' ),
            'application_id' => $this->applicationObject->attribute( 'id' )
        );
        if (!$isLocalQuiz)
        {
            $fetchParams['cluster_identifier'] = null;
        }
        if( QuizReply::fetchOneBy( $fetchParams ) != null )
        {
            return null;
        }
        $quizMetaFetchParams = array(
            'quiz_id' => $quizId
        );
        if (!$isLocalQuiz)
        {
            $quizMetaFetchParams['cluster_identifier'] = null;
        }
        $quizMeta = QuizMeta::fetchOneBy( $quizMetaFetchParams );
        if (!$quizMeta)
        {
            return null;
        }
        $db = eZDB::instance();
        $db->begin();
        $lowestScores = null;
        $isCorrect    = $_POST['r'] == $quizMeta->attribute( 'correct_answer' ) ? true : false;

        $reply        = new QuizReply();
        $reply->setAttribute( 'uuid', $this->user()->attribute( 'uuid' ) );
        if ($isLocalQuiz)
        {
            $reply->setAttribute( 'cluster_identifier', ClusterTool::clusterIdentifier() );
        }
        $reply->setAttribute( 'application_id', $this->applicationObject->attribute( 'id' ) );
        $reply->setAttribute( 'quiz_id', $quizId );
        $reply->setAttribute( 'is_correct', $isCorrect );

        $playerScoringFetchParams = array(
            'uuid' => $this->user()->attribute( 'uuid' ),
        );

        if (!$isLocalQuiz)
        {
            $playerScoringFetchParams['cluster_identifier'] = null;
        }
        $playerScoring = QuizPlayerScoring::fetchOneBy( $playerScoringFetchParams );
        if( is_null( $playerScoring ) )
        {
            $lowestScores = QuizPlayerScoring::createNewPlayer( null, $this->applicationObject->attribute( 'id' ), $isLocalQuiz );
            // TODO use returned playerScoring object from createNewPlayer instead of fetching one again
            $playerScoring = QuizPlayerScoring::fetchOneBy( $playerScoringFetchParams );
        }
        if( $isCorrect )
        {
            QuizPlayerScoring::scheduleRankingUpdate( $playerScoring->attribute( 'global_ranking' ), $this->applicationObject->attribute( 'id' ), $isLocalQuiz );
            $playerScoring->setAttribute( 'score', ( (int)$playerScoring->attribute( 'score' ) + (int)$quizMeta->attribute( 'points' ) ) );
            $playerScoring->setAttribute( 'nb_correct', ( (int)$playerScoring->attribute( 'nb_correct' ) + 1 ) );
            $quizMeta->setAttribute( 'nb_correct', ( (int)$quizMeta->attribute( 'nb_correct' ) + 1 ) );
        }
        else
        {
            $playerScoring->setAttribute( 'nb_wrong', ( (int)$playerScoring->attribute( 'nb_wrong' ) + 1 ) );
            $quizMeta->setAttribute( 'nb_wrong', ( (int)$quizMeta->attribute( 'nb_wrong' ) + 1 ) );
        }

        $quizMeta->store();
        $reply->store();
        $playerScoring->store();
        $db->commit();

        /* @type $quizArticleDM eZContentObjectAttribute[] */
        $quizArticleDM   = eZContentObject::fetch( $quizId )->DataMap();
        $mediaContent    = $quizArticleDM["media_content"]->content();
        $quizDM          = eZContentObjectTreeNode::fetch( $mediaContent['relation_list'][0]['node_id'] )->DataMap();
        $outputHandler   = new eZXHTMLXMLOutput( $quizDM['commented_answer']->DataText, false );
        $commentedAnswer = $outputHandler->outputText();

        $response = array( 'answer' => $quizMeta->attribute( 'correct_answer' ), 'comment' => $commentedAnswer, 'points' => (int)$quizMeta->attribute( 'points' ) );
        if( !is_null( $lowestScores ) )
            $response['ranking'] = $lowestScores;

        return $response;
    }