Skip to content
Snippets Groups Projects
Select Git revision
  • 2054b4c0815aa508623165d7fc0b810bafc16cc0
  • main default protected
  • studip-rector
  • ci-opt
  • course-members-export-as-word
  • data-vue-app
  • pipeline-improvements
  • webpack-optimizations
  • rector
  • icon-renewal
  • http-client-and-factories
  • jsonapi-atomic-operations
  • vueify-messages
  • tic-2341
  • 135-translatable-study-areas
  • extensible-sorm-action-parameters
  • sorm-configuration-trait
  • jsonapi-mvv-routes
  • docblocks-for-magic-methods
19 results

StudipSemTree.class.php

Blame
  • Forked from Stud.IP / Stud.IP
    Source project has a limited visibility.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Score.class.php 8.45 KiB
    <?
    /**
     * Score.class.php - Score class
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License as
     * published by the Free Software Foundation; either version 2 of
     * the License, or (at your option) any later version.
     *
     * @author      Ralf Stockmann <rstockm@gwdg.de>
     * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
     * @category    Stud.IP
     */
    
    class Score
    {
        // How long is the duration of a score-block?
        const MEASURING_STEP = 1800; // half an hour
    
        public static function getScoreContent($persons)
        {
            $user_ids = array_keys($persons);
    
            // News
            $query = "SELECT nr.range_id as user_id, COUNT(*) AS newscount
                      FROM news_range AS nr
                      INNER JOIN news AS n ON (nr.news_id = n.news_id)
                      WHERE nr.range_id IN (?) AND UNIX_TIMESTAMP() <= n.date + n.expire
                      GROUP BY nr.range_id
                      ORDER BY NULL";
            $statement = DBManager::get()->prepare($query);
            $statement->execute([$user_ids]);
            while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
                $persons[$row['user_id']]['newscount'] = $row['newscount'];
            }
    
            // Events
            $query = "SELECT range_id as user_id, COUNT(*) AS eventcount
                      FROM calendar_event
                      INNER JOIN event_data ON (calendar_event.event_id = event_data.event_id AND class = 'PUBLIC')
                      WHERE range_id IN (?) AND UNIX_TIMESTAMP() <= end
                      GROUP BY range_id
                      ORDER BY NULL";
            $statement = DBManager::get()->prepare($query);
            $statement->execute([$user_ids]);
            while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
                $persons[$row['user_id']]['eventcount'] = $row['eventcount'];
            }
    
            // Votes
            if (Config::get()->VOTE_ENABLE){
                $query = "SELECT questionnaire_assignments.range_id as user_id, COUNT(*) AS votecount
                          FROM questionnaire_assignments
                          WHERE questionnaire_assignments.range_id IN (?)
                              AND questionnaire_assignments.range_type = 'user'
                          GROUP BY questionnaire_assignments.range_id
                          ORDER BY NULL";
                $statement = DBManager::get()->prepare($query);
                $statement->execute([$user_ids]);
                while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
                    $persons[$row['user_id']]['votecount'] = $row['votecount'];
                }
            }
    
            return $persons;
        }
    
        /**
        * Retrieves the titel for a given studip score
        *
        * @param        integer a score value
        * @param        integer gender (0: unknown, 1: male; 2: female)
        * @return       string  the titel
        *
        */
        public static function getTitel($score, $gender = 0)
        {
            if ($score) {
                $logscore = floor(log10($score) / log10(2));
            } else {
                $logscore = 0;
            }
    
            if ($logscore > 20) {
                $logscore = 20;
            }
    
            $titel = [];
            $titel[0]  = [_('Unbeschriebenes Blatt'), _('Unbeschriebenes Blatt')];
            $titel[1]  = [_('Unbeschriebenes Blatt'), _('Unbeschriebenes Blatt')];
            $titel[2]  = [_('Unbeschriebenes Blatt'), _('Unbeschriebenes Blatt')];
            $titel[3]  = [_('Neuling'), _('Neuling')];
            $titel[4]  = [_('Greenhorn'), _('Greenhorn')];
            $titel[5]  = [_('Anfänger'), _('Anfängerin')];
            $titel[6]  = [_('Einsteiger'), _('Einsteigerin')];
            $titel[7]  = [_('Beginner'), _('Beginnerin')];
            $titel[8]  = [_('Novize'), _('Novizin')];
            $titel[9]  = [_('Fortgeschrittener'), _('Fortgeschrittene')];
            $titel[10] = [_('Kenner'), _('Kennerin')];
            $titel[11] = [_('Könner'), _('Könnerin')];
            $titel[12] = [_('Profi'), _('Profi')];
            $titel[13] = [_('Experte'), _('Expertin')];
            $titel[14] = [_('Meister'), _('Meisterin')];
            $titel[15] = [_('Großmeister'), _('Großmeisterin')];
            $titel[16] = [_('Idol'), _('Idol')];
            $titel[17] = [_('Guru'), _('Hohepriesterin')];
            $titel[18] = [_('Lichtgestalt'), _('Lichtgestalt')];
            $titel[19] = [_('Halbgott'), _('Halbgöttin')];
            $titel[20] = [_('Gott'), _('Göttin')];
    
            return $titel[$logscore][$gender == 2 ? 1 : 0];
        }
    
        /**
        * Retrieves the score for the current user
        *
        * @return       integer the score
        *
        */
        public static function GetMyScore($user_or_id = null)
        {
            $user = $user_or_id ? User::toObject($user_or_id) : User::findCurrent();
            $cache = StudipCacheFactory::getCache();
            if ($cache->read("user_score_of_".$user->id)) {
                return $cache->read("user_score_of_".$user->id);
            }
            //Behold! The all new mighty score algorithm!
            //Step 1: Select all activities as mkdate-timestamps.
            //Step 2: Group these activities to timeslots of halfhours
            //        with COUNT(*) as a weigh of the timeslot.
            //Step 3: Calculate the measurement of the timeslot from the weigh of it.
            //        This makes the first activity count fully, the second
            //        almost half and so on. We use log_n to make huge amounts of
            //        activities to not count so much.
            //Step 4: Calculate a single score for each timeslot depending on the
            //        measurement and the mkdate-timestamp. Use arctan as the function
            //        here so that older activities tend to zero.
            //Step 5: Sum all scores from all timeslots together.
            $sql = "
                SELECT round(SUM((-atan(measurement / " . round(31556926 / self::MEASURING_STEP) . ") / PI() + 0.5) * 200)) as score
                FROM (
                    SELECT ((unix_timestamp() / " . self::MEASURING_STEP . ") - timeslot) / (LN(weigh) + 1) AS measurement
                    FROM (
                        SELECT (round(mkdate / " . self::MEASURING_STEP . ")) as timeslot, COUNT(*) AS weigh
                        FROM (
                            " . self::createTimestampQuery() . "
                        ) as mkdates
                        GROUP BY timeslot
                    ) as measurements
                ) as dates
            ";
            $stmt = DBManager::get()->prepare($sql);
            $stmt->execute([':user' => $user->id]);
            $score = $stmt->fetchColumn();
            if ($user->score && $user->score != $score) {
                $user->score = $score;
                $user->store();
            }
            $cache->write("user_score_of_{$user->id}", $score, 60 * 5);
    
            return $score;
        }
    
        protected static function createTimestampQuery()
        {
            $statements = [];
            foreach (self::getActivityTables() as $table) {
                $statements[] = "SELECT "
                    . ($table['date_column'] ?: 'mkdate')
                    . " AS mkdate FROM "
                    . $table['table']
                    . " WHERE "
                    . ($table['user_id_column'] ?: 'user_id')
                    . " = :user "
                    . ($table['where'] ? (' AND ' . $table['where']) : '');
            }
            return join(' UNION ', $statements);
        }
    
        protected static function getActivityTables()
        {
            $tables = [];
            $tables[] = ['table' => 'user_info'];
            $tables[] = ['table' => 'comments'];
            $tables[] = ['table' => 'file_refs'];
            $tables[] = ['table' => 'forum_entries'];
            $tables[] = ['table' => 'news'];
            $tables[] = ['table' => 'seminar_user'];
            $tables[] = [
                'table' => 'blubber_threads'
            ];
            $tables[] = [
                'table' => 'blubber_comments'
            ];
            $tables[] = [
                'table'          => 'kategorien',
                'user_id_column' => 'range_id',
            ];
            $tables[] = [
                'table'          => 'message',
                'user_id_column' => 'autor_id'
            ];
            $tables[] = ['table' => 'questionnaires'];
            $tables[] = [
                'table'       => 'questionnaire_answers',
                'date_column' => 'chdate',
            ];
            $tables[] = ['table' => 'questionnaire_anonymous_answers'];
            $tables[] = [
                'table'       => 'wiki',
                'date_column' => 'chdate'
            ];
    
            foreach (PluginManager::getInstance()->getPlugins('ScorePlugin') as $plugin) {
                foreach ((array) $plugin->getPluginActivityTables() as $table) {
                    if ($table['table']) {
                        $tables[] = $table;
                    }
                }
            }
    
            return $tables;
        }
    }