<commit_before><?php
/**
 * @copyright Copyright (C) 2015-2016 <NAME>
 * @license https://github.com/fetus-hina/stat.ink/blob/master/LICENSE MIT
 * @author <NAME> <<EMAIL>>
 */

namespace app\actions\show;

use yii\db\Query;
use app\components\helpers\Battle as BattleHelper;
use app\models\BattleFilterForm;
use app\models\SplatoonVersion;
use app\models\Weapon;

trait UserStatFilterTrait
{
    public function filter(Query $query, BattleFilterForm $filter)
    {
        return $this
            ->filterByLobby($query, $filter->lobby)
            ->filterByRule($query, $filter->rule)
            ->filterByMap($query, $filter->map)
            ->filterByWeapon($query, $filter->weapon)
            ->filterByResult($query, $filter->result)
            ->filterByTerm($query, $filter->term, [
                'from' => $filter->term_from,
                'to' => $filter->term_to,
                'form' => $filter,
            ]);
    }

    public function filterByLobby($query, $value)
    {
        $value = trim((string)$value);
        if ($value === '') {
            return $this;
        }
        $query->andWhere(['{{lobby}}.[[key]]' => $value]);
        return $this;
    }

    public function filterByRule($query, $value)
    {
        $value = trim((string)$value);
        if ($value === '') {
            return $this;
        }
        if (substr($value, 0, 1) === '@') {
            $query->andWhere(['{{game_mode}}.[[key]]' => substr($value, 1)]);
        } else {
            $query->andWhere(['{{rule}}.[[key]]' => $value]);
        }
        return $this;
    }

    public function filterByMap($query, $value)
    {
        $value = trim((string)$value);
        if ($value === '') {
            return $this;
        }
        $query->andWhere(['{{map}}.[[key]]' => $value]);
        return $this;
    }

    public function filterByWeapon($query, $value)
    {
        $value = trim((string)$value);
        if ($value === '') {
            return $this;
        }
        switch (substr($value, 0, 1)) {
            default:
                $query->andWhere(['{{weapon}}.[[key]]' => $value]);
                break;

            case '@':
                $query->andWhere(['{{weapon_type}}.[[key]]' => substr($value, 1)]);
                break;

            case '+':
                $query->andWhere(['{{subweapon}}.[[key]]' => substr($value, 1)]);
                break;

            case '*':
                $query->andWhere(['{{special}}.[[key]]' => substr($value, 1)]);
                break;

            case '~':
                if (!$main = Weapon::findOne(['key' => substr($value, 1)])) {
                    $query->andWhere('1 = 0');
                } else {
                    $query->andWhere(['{{weapon}}.[[main_group_id]]' => $main->id]);
                }
                break;
        }
        return $this;
    }

    public function filterByResult($query, $result)
    {
        if ($result === 'win' || $result === true) {
            $query->andWhere(['{{battle}}.[[is_win]]' => true]);
        } elseif ($result === 'lose' || $result === false) {
            $query->andWhere(['{{battle}}.[[is_win]]' => false]);
        }
        return $this;
    }

    public function filterByTerm($query, $value, array $options = [])
    {
        $now = $_SERVER['REQUEST_TIME'] ?? time();
        $currentPeriod = BattleHelper::calcPeriod($now);

        switch ($value) {
            case 'this-period':
                $query->andWhere(['{{battle}}.[[period]]' => $currentPeriod]);
                break;
                
            case 'last-period':
                $query->andWhere(['{{battle}}.[[period]]' => $currentPeriod - 1]);
                break;
                
            case '24h':
                $query->andWhere(['>=', '{{battle}}.[[at]]', gmdate('Y-m-d\TH:i:sP', $now - 86400)]);
                break;

            case 'today':
                $t = mktime(0, 0, 0, date('n', $now), date('j', $now), date('Y', $now));
                $query->andWhere(['>=', '{{battle}}.[[at]]', gmdate('Y-m-d\TH:i:sP', $t)]);
                break;

            case 'yesterday':
                // 昨日の 00:00:00
                $t1 = mktime(0, 0, 0, date('n', $now), date('j', $now) - 1, date('Y', $now));
                // 今日の 00:00:00
                $t2 = mktime(0, 0, 0, date('n', $now), date('j', $now), date('Y', $now));
                $query->andWhere(['>=', '{{battle}}.[[at]]', gmdate('Y-m-d\TH:i:sP', $t1)]);
                $query->andWhere(['<', '{{battle}}.[[at]]', gmdate('Y-m-d\TH:i:sP', $t2)]);
                break;

            case 'term':
                if (isset($options['from']) && $options['from'] != '') {
                    if ($t = @strtotime($options['from'])) {
                        $query->andWhere(['>=', '{{battle}}.[[at]]', gmdate('Y-m-d\TH:i:sP', $t)]);
                    }
                }
                if (isset($options['to']) && $options['to'] != '') {
                    if ($t = @strtotime($options['to'])) {
                        $query->andWhere(['<=', '{{battle}}.[[at]]', gmdate('Y-m-d\TH:i:sP', $t)]);
                    }
                }
                break;

            default:
                if (preg_match('/^last-(\d+)-battles$/', $value, $match)) {
                    $range = BattleHelper::getNBattlesRange($options['form'], (int)$match[1]);
                    if (!$range || $range['min_id'] < 1 || $range['max_id'] < 1) {
                        $query->andWhere('0 = 1');
                        break;
                    }
                    $query->andWhere(['between', '{{battle}}.[[id]]', $range['min_id'], $range['max_id']]);
                } elseif (preg_match('/^v\d+/', $value)) {
                    $version = SplatoonVersion::findOne(['tag' => substr($value, 1)]);
                    if (!$version) {
                        $query->andWhere('0 = 1');
                        break;
                    }
                    $query->andWhere(['{{battle}}.[[version_id]]' => $version->id]);
                }
                break;
        }
        return $this;
    }
}<commit_msg>:sperkles: 統計もバトルIDの幅指定による絞り込みに対応（UIなし）<commit_after><?php
/**
 * @copyright Copyright (C) 2015-2016 <NAME>
 * @license https://github.com/fetus-hina/stat.ink/blob/master/LICENSE MIT
 * @author <NAME> <<EMAIL>>
 */

namespace app\actions\show;

use yii\db\Query;
use app\components\helpers\Battle as BattleHelper;
use app\models\BattleFilterForm;
use app\models\SplatoonVersion;
use app\models\Weapon;

trait UserStatFilterTrait
{
    public function filter(Query $query, BattleFilterForm $filter)
    {
        return $this
            ->filterByLobby($query, $filter->lobby)
            ->filterByRule($query, $filter->rule)
            ->filterByMap($query, $filter->map)
            ->filterByWeapon($query, $filter->weapon)
            ->filterByResult($query, $filter->result)
            ->filterByTerm($query, $filter->term, [
                'from' => $filter->term_from,
                'to' => $filter->term_to,
                'form' => $filter,
            ])
            ->filterByIdRange($query, $filter->id_from, $filter->id_to);
    }

    public function filterByLobby($query, $value)
    {
        $value = trim((string)$value);
        if ($value === '') {
            return $this;
        }
        $query->andWhere(['{{lobby}}.[[key]]' => $value]);
        return $this;
    }

    public function filterByRule($query, $value)
    {
        $value = trim((string)$value);
        if ($value === '') {
            return $this;
        }
        if (substr($value, 0, 1) === '@') {
            $query->andWhere(['{{game_mode}}.[[key]]' => substr($value, 1)]);
        } else {
            $query->andWhere(['{{rule}}.[[key]]' => $value]);
        }
        return $this;
    }

    public function filterByMap($query, $value)
    {
        $value = trim((string)$value);
        if ($value === '') {
            return $this;
        }
        $query->andWhere(['{{map}}.[[key]]' => $value]);
        return $this;
    }

    public function filterByWeapon($query, $value)
    {
        $value = trim((string)$value);
        if ($value === '') {
            return $this;
        }
        switch (substr($value, 0, 1)) {
            default:
                $query->andWhere(['{{weapon}}.[[key]]' => $value]);
                break;

            case '@':
                $query->andWhere(['{{weapon_type}}.[[key]]' => substr($value, 1)]);
                break;

            case '+':
                $query->andWhere(['{{subweapon}}.[[key]]' => substr($value, 1)]);
                break;

            case '*':
                $query->andWhere(['{{special}}.[[key]]' => substr($value, 1)]);
                break;

            case '~':
                if (!$main = Weapon::findOne(['key' => substr($value, 1)])) {
                    $query->andWhere('1 = 0');
                } else {
                    $query->andWhere(['{{weapon}}.[[main_group_id]]' => $main->id]);
                }
                break;
        }
        return $this;
    }

    public function filterByResult($query, $result)
    {
        if ($result === 'win' || $result === true) {
            $query->andWhere(['{{battle}}.[[is_win]]' => true]);
        } elseif ($result === 'lose' || $result === false) {
            $query->andWhere(['{{battle}}.[[is_win]]' => false]);
        }
        return $this;
    }

    public function filterByTerm($query, $value, array $options = [])
    {
        $now = $_SERVER['REQUEST_TIME'] ?? time();
        $currentPeriod = BattleHelper::calcPeriod($now);

        switch ($value) {
            case 'this-period':
                $query->andWhere(['{{battle}}.[[period]]' => $currentPeriod]);
                break;
                
            case 'last-period':
                $query->andWhere(['{{battle}}.[[period]]' => $currentPeriod - 1]);
                break;
                
            case '24h':
                $query->andWhere(['>=', '{{battle}}.[[at]]', gmdate('Y-m-d\TH:i:sP', $now - 86400)]);
                break;

            case 'today':
                $t = mktime(0, 0, 0, date('n', $now), date('j', $now), date('Y', $now));
                $query->andWhere(['>=', '{{battle}}.[[at]]', gmdate('Y-m-d\TH:i:sP', $t)]);
                break;

            case 'yesterday':
                // 昨日の 00:00:00
                $t1 = mktime(0, 0, 0, date('n', $now), date('j', $now) - 1, date('Y', $now));
                // 今日の 00:00:00
                $t2 = mktime(0, 0, 0, date('n', $now), date('j', $now), date('Y', $now));
                $query->andWhere(['>=', '{{battle}}.[[at]]', gmdate('Y-m-d\TH:i:sP', $t1)]);
                $query->andWhere(['<', '{{battle}}.[[at]]', gmdate('Y-m-d\TH:i:sP', $t2)]);
                break;

            case 'term':
                if (isset($options['from']) && $options['from'] != '') {
                    if ($t = @strtotime($options['from'])) {
                        $query->andWhere(['>=', '{{battle}}.[[at]]', gmdate('Y-m-d\TH:i:sP', $t)]);
                    }
                }
                if (isset($options['to']) && $options['to'] != '') {
                    if ($t = @strtotime($options['to'])) {
                        $query->andWhere(['<=', '{{battle}}.[[at]]', gmdate('Y-m-d\TH:i:sP', $t)]);
                    }
                }
                break;

            default:
                if (preg_match('/^last-(\d+)-battles$/', $value, $match)) {
                    $range = BattleHelper::getNBattlesRange($options['form'], (int)$match[1]);
                    if (!$range || $range['min_id'] < 1 || $range['max_id'] < 1) {
                        $query->andWhere('0 = 1');
                        break;
                    }
                    $query->andWhere(['between', '{{battle}}.[[id]]', $range['min_id'], $range['max_id']]);
                } elseif (preg_match('/^v\d+/', $value)) {
                    $version = SplatoonVersion::findOne(['tag' => substr($value, 1)]);
                    if (!$version) {
                        $query->andWhere('0 = 1');
                        break;
                    }
                    $query->andWhere(['{{battle}}.[[version_id]]' => $version->id]);
                }
                break;
        }
        return $this;
    }

    public function filterByIdRange($query, $idFrom, $idTo)
    {
        if ($idFrom != '' && $idFrom > 0) {
            $query->andWhere(['>=', '{{battle}}.[[id]]', (int)$idFrom]);
        }
        if($idTo != '' && $idTo > 0) {
            $query->andWhere(['<=', '{{battle}}.[[id]]', (int)$idTo]);
        }
        return $this;
    }
}
{'fraction_non_alphanumeric': 0.21453287197231835, 'fraction_numerical': 0.009751494180559924, 'mean_word_length': 1.611829944547135, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 145, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3087262', 'n_tokens_mistral': 4128, 'n_tokens_neox': 3892, 'n_words': 658}