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();
 }
    '[clusterIdentifier:][exclude:]',
    "",
    array(
        'clusterIdentifier' => 'Comma separated list of cluster identifiers (or value all if all of them)',
        'exclude' => 'Boolean flag deciding whether the script should be run for all clusters except given (default: false)'
    )
);
$script->initialize();

try {
    $options = processOptions($options);
    $clusters = $options['clusters'];
    foreach($clusters as $cluster)
    {
        $cli->output("Starting new season for cluster {$cluster}");
        QuizPlayerScoring::startNewSeason($cluster);
    }
} catch (Exception $e)
{
    $cli->error($e->getMessage());
    $script->shutdown(1);
}


$script->shutdown();

function processOptions($options)
{

    if ($options['clusterIdentifier'] == null)
    {
<?php

/* @type $cli eZCli */
/* @type $script eZScript */

$cli = eZCLI::instance();
$rankingUpdateResult = QuizPlayerScoring::updateRanking();

if( !is_null( $rankingUpdateResult ) )
{
    if( $rankingUpdateResult['updateCount'] > 0 && $rankingUpdateResult['updateResult'] == true )
    {
        $message = date( DATE_ATOM ) . ' -- Ranking update finished for application with id #' . $rankingUpdateResult['applicationId'] . ' (' . $rankingUpdateResult['clusterIdentifier'] . '), ' . $rankingUpdateResult['updateCount'] . ' rank(s) updated';
        if( $rankingUpdateResult['benchmark'] != null )
            $message .= '. ' . $rankingUpdateResult['benchmark'];
        $cli->output( $message );
        eZLog::write( $message, 'quiz.log' );
    }
}
    'debug-output' => true,
) );

$options = $script->getOptions( "[clusterIdentifier:][countryCode:]", "", array(
    'clusterIdentifier' => 'Cluster identifier',
    'countryCode'       => 'Country code'
) );

$script->startup();
$script->initialize();

if( $options['clusterIdentifier'] && $options['countryCode'] )
{
    $updated = 0;
    $lowestRankingsPerQuizApp = array();
    $playerScoringRows = QuizPlayerScoring::fetchBy( array( 'cluster_identifier' => array( array( $options['clusterIdentifier'] ) ) ) );
    if( $playerScoringRows )
    {
        ClusterTool::setCurrentCluster( $options['clusterIdentifier'] );
        $us = FacetFilteringTool::getTaxoTranslationWithIDs( 'user_specialty' );
        foreach( $playerScoringRows as $playerScoring )
        {
            $user = MMUsers::fetchByIdAndCountry( $playerScoring->attribute( 'uuid' ), $options['countryCode'] );
            if( $user )
            {
                if( isset( $us[$user->attribute( 'user_speciality' )] ) && $us[$user->attribute( 'user_speciality' )]['id'] != $playerScoring->attribute( 'user_specialty' ) )
                {
                    if( !isset( $lowestRankingsPerQuizApp[$playerScoring->attribute( 'application_id' )] ) || ( isset( $lowestRankingsPerQuizApp[$playerScoring->attribute( 'application_id' )] ) && $lowestRankingsPerQuizApp[$playerScoring->attribute( 'application_id' )] < (int)$playerScoring->attribute( 'global_ranking' ) ) )
                        $lowestRankingsPerQuizApp[$playerScoring->attribute( 'application_id' )] = (int)$playerScoring->attribute( 'global_ranking' );
                    $oldUS = $playerScoring->attribute( 'user_specialty' );
                    $playerScoring->setAttribute( 'user_specialty', $us[$user->attribute( 'user_speciality' )]['id'] );
    /**
     * @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;
    }
                if (is_null($lastGlobalRanking))
                {
                    $lastGlobalRanking = $r[0];
                    continue;
                }
                if (count(array_unique($r)) > 1 || $r[0] <= $lastGlobalRanking)
                {
                    $shouldRecalculate = true;
                    break;
                }
                $lastGlobalRanking = $r[0];
            }
            if ($shouldRecalculate)
            {
                $lowestGlobalranking = QuizPlayerScoring::fetchBy(
                    array('application_id' => $applicationId),
                    array('global_ranking' => 'desc'),
                    array('length' => 1)
                );
                QuizPendingRankingUpdate::add(
                    (int)$lowestGlobalranking[0]->attribute('global_ranking'),
                    $applicationId
                );
                $message = "Scheduled a complete ranking update for application with id #$applicationId ($clusterIdentifier)";
                $cli->output($message);
                eZLog::write($message, 'quiz.log');
            }
        }
    }
}
            $countUS[$us]
        );
        $score++;
        $db->query( $query );
    }

    QuizPlayerScoring::scheduleRankingUpdate( $gr, $options['quizApplicationId'] );

    $cli->output( "Done, added " . $options['nbPlayer'] . " test players in quiz player scoring table" );
}
elseif( $options['empty'] && $options['clusterIdentifier'] && $options['quizApplicationId'] )
{
    ClusterTool::setCurrentCluster( $options['clusterIdentifier'] );
    $db->query( sprintf( "DELETE FROM %s WHERE uuid LIKE 'qzbench%%'", QuizPlayerScoring::SQL_TABLENAME ) );

    $lowestGlobalScore = QuizPlayerScoring::fetchBy( array( 'application_id' => $options['quizApplicationId'] ), array( 'global_ranking' => 'desc' ), array( 'length' => 1 ) );
    if( $lowestGlobalScore )
        $gr = $lowestGlobalScore[0]->attribute( 'score' ) == 0 ? $lowestGlobalScore[0]->attribute( 'global_ranking' ) : ( $lowestGlobalScore[0]->attribute( 'global_ranking' ) + 1 );
    else
        $gr = 1;
    QuizPlayerScoring::scheduleRankingUpdate( $gr, $options['quizApplicationId'] );

    $cli->output( "Quiz player scoring table has been emptied of its test players" );
}
else
{
    $cli->output( "Please specify either the --clusterIdentifier/--quizApplicationId/--nbPlayer parameters or the --clusterIdentifier/--quizApplicationId/--empty parameters" );
}

$script->shutdown();
<?php

$http        = eZHTTPTool::instance();
$description = '';
$userId      = MMUsers::getCurrentUserId();

if ($userId !== '-1')
{
    $applicationIdentifier = $http->postVariable('identifier');
    $cardType = $http->postVariable('type');
    $applicationLocalized = CacheApplicationTool::buildLocalizedApplicationByIdentifier($applicationIdentifier);
    if ($applicationLocalized) {
        $playerScoring = QuizPlayerScoring::fetchCurrentUserRow($applicationLocalized->applicationObject()->id);
        $description = ezpI18n::tr('merck/quiz', "WE HAVE THE PLEASURE TO INFORM YOU THAT YOU ARE NOW %SPE_RANK IN YOUR SPECIALITY AND %GLOBAL_RANK IN GLOBAL RANKING WITH A SCORE OF %NB_POINTS POINTS", null, array(
            '%SPE_RANK' => $playerScoring->attribute('specialty_ranking'),
            '%GLOBAL_RANK' => $playerScoring->attribute('global_ranking'),
            '%NB_POINTS' => $playerScoring->attribute('score')
        ));

        $description = strip_tags($description);
        $data = array(
            'title' => ezpI18n::tr("merck/quiz", "QUIZ ANNOUNCEMENT"),
            'description' => $description,
            'specialty_rank' => $playerScoring->attribute('specialty_ranking'),
            'global_rank' => $playerScoring->attribute('global_ranking'),
            'application_identifier' => $applicationIdentifier,
            'type' => $cardType,
        );
        $userId = $playerScoring->attribute('uuid');
        $clusterIdentifier = $playerScoring->attribute('cluster_identifier');
    /**
     * @param array $uncrytedTicket
     * @return MMUsers
     */
    public static function createOrUpdateMMUser( $uncrytedTicket )
    {
        $userId = $uncrytedTicket['uuid'];
        $customerType = $uncrytedTicket['customerType'];
        if ( isset($uncrytedTicket['userSpeciality']) )
        {
            $userSpeciality = $uncrytedTicket['userSpeciality'];
        }
        else
        {
            $userSpeciality = $uncrytedTicket['mainSpeciality'];
        }
        $state = $uncrytedTicket['state'];
        $country = eZIni::instance('site.ini')->variable('RegionalSettings','CountryOfRegistration');
        $language = $uncrytedTicket['language'];
        /**
         * @todo: check $language entry format and parse it if needed to get an iso code on 2 chars
         */
        $iniMapping = eZINI::instance('mercktaxonomymapping.ini');
        $taxonomyType = $iniMapping->variable( 'Taxonomy', 'SpecialtiesTaxonomyType');

        $specialtiesMappingINI = $iniMapping->variable( 'Taxonomy', 'Specialties' );
        $customerTypesMappingINI = $iniMapping->variable( 'Taxonomy', 'CustomerTypes' );

        if($taxonomyType != "transitive")
        {
            if ( isset( $customerTypesMappingINI[$customerType] ) )
            {
                $customerType = $customerTypesMappingINI[$customerType];
            }
            else
            {
                $customerType = $customerTypesMappingINI['Default'];
                self::updateDBWithEmptyValue( 'empty-CT', $userId, $country );
            }

            if ( isset( $specialtiesMappingINI[$userSpeciality] ) )
            {
                $userSpeciality = $specialtiesMappingINI[$userSpeciality];
            }
            else
            {
                $userSpeciality = $specialtiesMappingINI['Default'];
                self::updateDBWithEmptyValue( 'empty-SPE', $userId, $country );
            }
        }
        else
        {
            $customerTypesMapping = SolrSafeOperatorHelper::getCustomerTypes();
            if ( !isset( $customerTypesMapping["$customerType"] ) )
            {
                // fill with default value
                $customerType = $customerTypesMappingINI['Default'];
                self::updateDBWithEmptyValue( 'empty-CT', $userId, $country );
            }

            $specialtiesMapping = SolrSafeOperatorHelper::getUserSpecialities();
            if ( !isset( $specialtiesMapping[(string)$userSpeciality] ) )
            {
                // fill with default value
                $userSpeciality = $specialtiesMappingINI['Default'];
                self::updateDBWithEmptyValue( 'empty-SPE', $userId, $country );
            }
        }

        /** @var MMUsers $user */
        $user = MMUsers::fetchByIdAndCountry( $userId, $country );
        $isModifiedUser = false;

        if ( $user )
        {
            if ( $customerType != $user->attribute('customer_type') )
            {
                $user->setAttribute('customer_type', $customerType);
                $isModifiedUser = true;
            }
            if ( $userSpeciality !== $user->attribute('user_speciality') )
            {
                $mainSpeciality = UserSpecialityContentSpeciality::getContentSpeciality ( $userSpeciality );
                $defaultAdditionalSpecialities = MMUserLogin::getAddSpecialties($mainSpeciality);

                $user->setAttribute('user_speciality', $userSpeciality);

                // mapping main_spe additional spe
                $preferences = $user->getPreferences();
                $userAditionalSpecialities = $preferences['specialities'];
                array_shift($userAditionalSpecialities);
                $tmp = array_diff( $userAditionalSpecialities, $defaultAdditionalSpecialities );
                if( empty( $tmp ) )    // we don't modify the user spes if he has changed his selection
                {
                    $preferences["specialities"] = MMUserLogin::getAddSpecialties($mainSpeciality);
                    $user->setPreferences($preferences);
                }
                $user->setPreferences($preferences);

                // The user specialty has been modified, we need to update it for Quiz-type applications of the current cluster
                if( CacheApplicationTool::buildLocalizedApplicationByIdentifier('train-the-brain') instanceof ApplicationLocalized)
                {
                    $playerScoring = QuizPlayerScoring::fetchOneBy( array( 'application_id' => (int)$app->applicationObject->id, 'uuid' => $user->attribute( 'uuid' ) ) );
                    // Checking if the current user has scored at least once for the application
                    if( $playerScoring )
                    {
                        foreach( FacetFilteringTool::getTaxoTranslationWithIDs( 'user_specialty' ) as $k => $t )
                        {
                            if( ($k . "") === ($userSpeciality . "") )
                            {
                                // Updating the user specialty id in the player scoring table
                                $playerScoring->setAttribute( 'user_specialty', $t['id'] );
                                $playerScoring->store();
                            }
                        }
                        // Scheduling a ranking update
                        QuizPendingRankingUpdate::add( $playerScoring->attribute( 'global_ranking' ), $app->applicationObject->id );
                    }
                }

                $isModifiedUser = true;
            }

            if ( $country != $user->attribute('country') )
            {
                $user->setAttribute('country', $country);
                $isModifiedUser = true;
            }

            if( $language != $user->attribute( 'language' ) )
            {
                $user->setAttribute('language', $language );
                $isModifiedUser = true;
            }

            if ( $state != $user->attribute('state') )
            {
                $user->setAttribute('state', $state);
                $isModifiedUser = true;
            }

            if ( $isModifiedUser )
            {
                $user->setAttribute('date_update', time());
                $user->store();
            }

            // set gpnotebook hand shake data in preferences
            if($user->getGPNotebookHS())
            {
                SolrSafeOperatorHelper::getAndStoreGPNotebookHS();
            }
        }
        else
        {
            $mainSpeciality = UserSpecialityContentSpeciality::getContentSpeciality ( $userSpeciality );
            $insertedArray = array (
                'uuid' => $userId,
                'customer_type' => $customerType,
                'user_speciality' => $userSpeciality,
                'country' => $country,
                'language' => $language,
                'date_update' => time(),
                'state' => $state,
            );

            $user = new MMUsers ($insertedArray);
            $user->store();

            // mapping main_spe additional spe
            $preferences = $user->getPreferences();
            $preferences["specialities"] = MMUserLogin::getAddSpecialties($mainSpeciality);
            $user->setPreferences($preferences);

            $isModifiedUser = true;
        }

        if ( $isModifiedUser )
        {
            // Tag Lyris user to be reimported :
            $user->tagLyrisToProcess();
        }

        return $user;
    }