/** * @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; }
/** * @param string $newGameName * @param int $applicationId * @return array */ static function createNewPlayer( $newGameName, $applicationId, $isLocalQuiz = true ) { $currentMMUser = MMUsers::getCurrentUserObject(); if( $currentMMUser ) { $clusterIdentifier = ($isLocalQuiz) ? ClusterTool::clusterIdentifier() : ''; $newPlayer = new QuizPlayerScoring(); // Setting up the global ranking of the new player $lowestGlobalScore = self::fetchBy( array( 'application_id' => $applicationId, 'cluster_identifier' => $clusterIdentifier ), array( 'global_ranking' => 'desc' ), array( 'length' => 1 ) ); if( $lowestGlobalScore ) $lgs = $lowestGlobalScore[0]->attribute( 'score' ) == 0 ? $lowestGlobalScore[0]->attribute( 'global_ranking' ) : ( $lowestGlobalScore[0]->attribute( 'global_ranking' ) + 1 ); else $lgs = 1; // Setting up the specialty ranking of the new player $userSpecialtyTranslations = FacetFilteringTool::getTaxoTranslationWithIDs( 'user_specialty' ); $userSpecialtyTaxonomyId = $userSpecialtyTranslations[$currentMMUser->attribute( 'user_speciality' )]['id']; $lowestSpecialtyScore = self::fetchBy( array( 'application_id' => $applicationId, 'user_specialty' => $userSpecialtyTaxonomyId ), array( 'specialty_ranking' => 'desc' ), array( 'length' => 1 ) ); if( $lowestSpecialtyScore ) $lss = $lowestSpecialtyScore[0]->attribute( 'score' ) == 0 ? $lowestSpecialtyScore[0]->attribute( 'specialty_ranking' ) : ( $lowestSpecialtyScore[0]->attribute( 'specialty_ranking' ) + 1 ); else $lss = 1; $newPlayer->setAttribute( 'game_name', $newGameName ); $newPlayer->setAttribute( 'uuid', $currentMMUser->attribute( 'uuid' ) ); $newPlayer->setAttribute( 'cluster_identifier', $clusterIdentifier); $newPlayer->setAttribute( 'application_id', $applicationId ); $newPlayer->setAttribute( 'score', 0 ); $newPlayer->setAttribute( 'user_specialty', Taxonomy::fetchObject( Taxonomy::definition(), null, array( 'code' => $currentMMUser->attribute( 'user_speciality' ) ), true)->attribute( 'id' ) ); $newPlayer->setAttribute( 'nb_correct', 0 ); $newPlayer->setAttribute( 'nb_wrong', 0 ); $newPlayer->setAttribute( 'global_ranking', $lgs ); $newPlayer->setAttribute( 'specialty_ranking', $lss ); $newPlayer->setAttribute( 'user_cluster', ClusterTool::clusterIdentifier() ); $newPlayer->store(); return array( 'lgs' => $lgs, 'lss' => $lss ); } return null; }
public function getHallOfFame($season) { $tpl = $this->tpl(); $db = eZDB::instance(); $ust = array(); $playerData = null; $totalPlayers = 0; $lowestGlobalRanking = 0; $uuidsInGlobalLeaderboard = array(); $_globalLeaderboard = array( 1 => array(), 2 => array(), 3 => array(), ); $userSpecialtyTranslations = FacetFilteringTool::getTaxoTranslationWithIDs( 'user_specialty' ); foreach( $userSpecialtyTranslations as $translation ) $ust[$translation['id']] = $translation['label']; $userSpecialtyTaxonomyId = $userSpecialtyTranslations[$this->user()->attribute( 'user_speciality' )]['id']; $clusterIdentifier = ($this->isLocalQuiz()) ? ClusterTool::clusterIdentifier() : ''; $results = array(); for ($i = 1; $i <= 3; $i++) { $chunks = $db->arrayQuery( sprintf(" SELECT COUNT(id) as total, uuid, user_specialty, game_name, global_ranking, specialty_ranking, score, nb_correct, nb_wrong FROM %s WHERE cluster_identifier = '%s' AND application_id = %d AND global_ranking = %d AND season = %d GROUP BY uuid ORDER BY global_ranking ASC, uuid = '%s' DESC LIMIT 5", QuizHallOfFame::SQL_TABLENAME, $db->escapeString( $clusterIdentifier ), $this->applicationObject->attribute( 'id' ), $i, $season, $this->user()->attribute('uuid') )); $results = array_merge($results, $chunks); } if( $results ) { foreach( $results as $row ) { if( $row['nb_correct'] == 0 && $row['nb_wrong'] == 0 ) continue; if( $row['global_ranking'] <= 10 && !in_array( $row['uuid'], $uuidsInGlobalLeaderboard ) && count( $uuidsInGlobalLeaderboard ) < 10 ) { $_globalLeaderboard[$row['global_ranking']][] = array( 'game_name' => is_null( $row['game_name'] ) || $row['game_name'] == '' ? ezpI18n::tr( 'merck/quiz', 'ANONYMOUS' ) : $row['game_name'], 'specialty_label' => $ust[$row['user_specialty']], 'ranking' => $row['global_ranking'], 'uuid' => $row['uuid'], 'score' => $row['score'] ); $uuidsInGlobalLeaderboard[] = $row['uuid']; } if( $row['uuid'] == $this->user()->attribute( 'uuid' ) && is_null( $playerData ) ) { $playerData = $row; } } if( !in_array( $this->user()->attribute( 'uuid' ), $uuidsInGlobalLeaderboard ) ) { if( is_null( $playerData ) ) { $playerData = QuizHallOfFame::fetchUserInSeason( $this->applicationObject->attribute( 'id' ), $season, false, $this->isLocalQuiz() ); } if( $playerData && ( $playerData['nb_correct'] == 0 && $playerData['nb_wrong'] == 0 ) ) { $playerData = null; } } $playersCount = $db->arrayQuery( sprintf(" SELECT COUNT(*) as total, user_specialty, MAX(global_ranking) as lowest_global_ranking, MAX(specialty_ranking) as lowest_specialty_ranking FROM %s WHERE cluster_identifier = '%s' AND application_id = %d AND ( nb_correct > 0 OR nb_wrong > 0 ) AND season = %d GROUP BY (user_specialty)", QuizHallOfFame::SQL_TABLENAME, $db->escapeString( $clusterIdentifier ), $this->applicationObject->attribute( 'id' ), $season ) ); foreach( $playersCount as $row ) { $totalPlayers += $row['total']; if( $row['user_specialty'] == $userSpecialtyTaxonomyId ) { $totalSpecialtyPlayers = $row['total']; $lowestSpecialtyRanking = $row['lowest_specialty_ranking']; } if( $row['lowest_global_ranking'] > $lowestGlobalRanking ) $lowestGlobalRanking = $row['lowest_global_ranking']; } } $tpl->setVariable( 'global_leaderboard', $_globalLeaderboard ); $tpl->setVariable( 'current_player_uuid', $this->user()->attribute('uuid') ); $response = array( 'player_position' => ($playerData) ? $playerData['global_ranking'] : 0, 'hall_of_fame' => $tpl->fetch( 'design:esibuild/app_content/train-the-brain/hall_of_fame.tpl' ), 'total_players' => $totalPlayers, ); return $response; }
'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'] ); $playerScoring->store(); $updated++; $cli->output( "Updated user speciality (" . $oldUS . " -> " . $us[$user->attribute( 'user_speciality' )]['id'] . ") in scoring data for user " . $playerScoring->attribute( 'uuid' ) ); }
/** * @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; }