TemKa_SD Posted August 11, 2018 Share Posted August 11, 2018 Здравствуйте. Я не знаком с программированием, только на уровне чтения ну и основ. Мне нужно реализовать следующее: В таблице 1 содержатся данные игрового аккаунта, в котором есть полу active и оно принимает значения 0 или 1. Эта активность берется с двух других таблиц, где сравниваются ИГРОКИ и ИГРЫ, там где ИГРЫ есть дата игры, по ней и будет проходить сравнение, если игрок играл за последний месяц, то должно передаваться значение 1. Я уже написал основу, разобрался немного, мне осталось составить SQL запрос для сравнения игрока и игр. Т.е запрос примерно такой: Если "игрок" (stats_gameplayers.gameid, stats_gameplayers.name, stats_gameplayers.spoofedrealm) есть в "играх" за последний месяц (stats_games.id) то условие выполняется, true. /** * memberActive Task */ class _memberActive extends \IPS\Task { /** * Execute * * If ran successfully, should return anything worth logging. Only log something * worth mentioning (don't log "task ran successfully"). Return NULL (actual NULL, not '' or 0) to not log (which will be most cases). * If an error occurs which means the task could not finish running, throw an \IPS\Task\Exception - do not log an error as a normal log. * Tasks should execute within the time of a normal HTTP request. * * @return mixed Message to log or NULL * @throws \IPS\Task\Exception */ public function execute() { $db = \IPS\sharedstats\DB::get(); $accounts = []; foreach($db::i('stats')->select('id, status, name, active, server, created', 'stats_forum_connections') as $acc) { $accounts[$acc['id']] = [ 'status' => $acc['status'], 'name' => $acc['name'], 'server' => $acc['server'], 'active' => $acc['active'] ]; } $this->updateAccounts($accounts); } /** * Cleanup * * If your task takes longer than 15 minutes to run, this method * will be called before execute(). Use it to clean up anything which * may not have been done * * @return void */ public function cleanup() { } /** * @param $accounts */ protected function updateAccounts($accounts) { foreach($accounts as $id => $acc) { $data = $this->fetchAccount($acc); $account = \IPS\sharedstats\Records\ForumConnection::load($id); if(!$data) { $account->active = '0'; } else { $account->active = '1'; } $account->save(); } } protected function fetchAccount($acc) { $result = true; if (FALSE === $result) { return false; } else { return json_decode($result, true); } } } Это готовый таск, он рабочий, данные изменяются где надо. Нужно вместо $result = true; вставить SQL запрос правильный. Link to comment Share on other sites More sharing options...
newbie Posted August 13, 2018 Share Posted August 13, 2018 Если "игрок" (stats_gameplayers.gameid, stats_gameplayers.name, stats_gameplayers.spoofedrealm)Где здесь игрок?Наверное, должно быть поле для хранения ID игрока, которое равно id из таблицы stats_forum_connections Link to comment Share on other sites More sharing options...
TemKa_SD Posted August 13, 2018 Author Share Posted August 13, 2018 (edited) Да, только не ID а логин + сервер (stats_gameplayers.name, stats_gameplayers.spoofedrealm) а в таблице с играми, чтобы дату вывести сравниваются поля stats_gameplayers.gameid и stats_games.id. Вы структуру запроса примерно напишите плиз, я дальше сам поля подставлю. Edited August 13, 2018 by TemKa_SD Link to comment Share on other sites More sharing options...
newbie Posted August 13, 2018 Share Posted August 13, 2018 только не ID а логин + сервер (stats_gameplayers.name, stats_gameplayers.spoofedrealm)А где связь между игроком и данными игрового аккаунта в таблицах stats_gameplayers и stats_forum_connections? Вот Вам пример с юзерами и темами $data = \IPS\Db::i()->select( 'core_members.member_id', 'core_members', array( 'start_date>?', \IPS\DateTime::create()->sub(new \DateInterval('P1D'))->getTimestamp()), null, null, 'member_id' )->join( 'core_pfields_content', 'core_pfields_content.member_id=core_members.member_id' )->join( 'forums_topics', 'forums_topics.starter_id=core_pfields_content.member_id' ); Получить список ID'шников юзеров, которые создали тему(ы) за последние 24 часа. По сути можно устанавливать active=0 для всех записей, а после устанавливать active=1 для записей, полученных в результате запроса. Опять же пример.Сперва устанавливаем всем юзерам стиль с ID 1 \IPS\Db::i()->update('core_members', array('skin' => 1)); После устанавливаем стиль с ID 10 юзерам, которые создали тему(ы) за последние 24 часа. $data2 = \IPS\Db::i()->select( 'core_pfields_content.member_id', 'core_pfields_content', array( 'forums_topics.start_date>?', \IPS\DateTime::create()->sub(new \DateInterval('P1D'))->getTimestamp()), null, null, 'core_pfields_content.member_id' )->join( 'forums_topics', 'forums_topics.starter_id=core_pfields_content.member_id' ); \IPS\Db::i()->update('core_members', array('skin' => 10), \IPS\Db::i()->in('member_id', iterator_to_array($data2))); 1 Link to comment Share on other sites More sharing options...
TemKa_SD Posted August 13, 2018 Author Share Posted August 13, 2018 Так, не могу разобраться. Составил SQL запрос нужный, попробуем так. SELECT gp.gameid, gp.name, gp.spoofedrealm FROM stats_gameplayers gp INNER JOIN stats_games g ON gp.gameid = g.id AND g.datetime='2018-06-30 13:27:56' Осталось изменить следующее: Вместо даты нужно указать за последние 30 дней. Добавить сравнение игрока и сервера из таблицы stats_forum_connections (поля в первом сообщении, member_id - id пользователя IPS). Только, может через модуль наверно переменные лучше поставить, ну это потом уже, сначала с этим помогите плиз )) Link to comment Share on other sites More sharing options...
newbie Posted August 13, 2018 Share Posted August 13, 2018 Покажите все 3 таблицы (как на 2 скрине). Link to comment Share on other sites More sharing options...
TemKa_SD Posted August 13, 2018 Author Share Posted August 13, 2018 А, стоп. В этой функции же мне просто нужно получить результат true или false (были ли игры за последние 30 дней). А сравнение с пользователем в функции выше должно быть, где записывает active. Правильно? Link to comment Share on other sites More sharing options...
TemKa_SD Posted August 13, 2018 Author Share Posted August 13, 2018 Обвел поля, которые нужны для выборки и сравнения. Link to comment Share on other sites More sharing options...
newbie Posted August 13, 2018 Share Posted August 13, 2018 Зачем Вам столько полей получать, если по факту Вы их нигде не используете К тому же делаете одинаковую работу, но разными способами foreach($db::i('stats')->select('id, status, name, active, server, created', 'stats_forum_connections') as $acc) { $accounts[$acc['id']] = [ 'status' => $acc['status'], 'name' => $acc['name'], 'server' => $acc['server'], 'active' => $acc['active'] ]; }Здесь Вы получаете аккаунты с 4-мя полями А дальше снова загружаете аккаунты foreach($accounts as $id => $acc) { $account = \IPS\sharedstats\Records\ForumConnection::load($id); Сделайте так1. Сбросим все значения active на 0\IPS\Db::i()->update('stats_forum_connections', array('active' => 0)); 2. Получим имена игроков, которые играли за последние 30 дней$names = iterator_to_array(\IPS\Db::i()->select( 'stats_gameplayers.name', 'stats_gameplayers', array( 'UNIX_TIMESTAMP(stats_games.datetime)>?', \IPS\DateTime::create()->sub(new \DateInterval('P30D'))->getTimestamp()), null, null, 'stats_gameplayers.name' )->join( 'stats_games', 'stats_games.id=stats_gameplayers.gameid' )); 3. Установим active=1if (count($names)) { \IPS\Db::i()->update('stats_forum_connections', array('active' => 1), \IPS\Db::i()->in('name', $names)); } 1 Link to comment Share on other sites More sharing options...
TemKa_SD Posted August 13, 2018 Author Share Posted August 13, 2018 Огромное спасибо, всё работает как надо. Link to comment Share on other sites More sharing options...
TemKa_SD Posted August 13, 2018 Author Share Posted August 13, 2018 Пожалуйста, добавьте еще сервер к нику, а то я что-то не разберусь со структурой.$names = iterator_to_array($db::i('stats')->select( 'stats_gameplayers.name, stats_gameplayers.spoofedrealm', Link to comment Share on other sites More sharing options...
newbie Posted August 13, 2018 Share Posted August 13, 2018 Что этот "сервер" делает в запросе? Link to comment Share on other sites More sharing options...
TemKa_SD Posted August 13, 2018 Author Share Posted August 13, 2018 Тоже самое что и ник, идет сравнение по нему ник + сервер. Просто может играть такой же ник но с другого сервера. Link to comment Share on other sites More sharing options...
newbie Posted August 13, 2018 Share Posted August 13, 2018 Как Вы тогда определяете, к какому аккаунту принадлежит игрок? Link to comment Share on other sites More sharing options...
TemKa_SD Posted August 13, 2018 Author Share Posted August 13, 2018 (edited) Это уже реализовано в компоненте, мне таск просто нужен, который обновляет active с 0 на 1. И наоборот, если игрок играл а потом перестал. Edited August 13, 2018 by TemKa_SD Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now