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();
 }
    /**
     * @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;
    }