Права отвечать и создавать новые темы через 3 часа после регистрации.

Автор vitkor, 24 сентября 2010, 12:17:06

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

vitkor

Доброго дня.
Возникла задача: Пользователь должен получать права на ответ в темах и создание новых тем, через определенный таймаут после регистрации.
Готового мода найти не смог, http://www.simplemachines.ru/index.php?topic=1013.msg79562#msg79562 [задавал вопрос] в теме поиска модификаций. По всей видимости, ничего готового в природе нет. Решил поковыряться самостоятельно.

Вот что пока смог сделать (все эксперименты на тестовом форуме):
Создал группу основанную на кол-ве сообщений - "Вновь прибывший", с количеством сообщений 0.
Убрал права на запись для этой группы, везде кроме одного раздела. Т.е пользователь который вновь зарегистрировался попадает в группу "Вновь прибывший" и писать может только в одном разделе. Это половинчатое решение.
В базе members есть параметр dateRegistered - дата регистрации в формате UTC.
Нам как бэ никто не мешает сравнить дату регистрации и текущую дату, если разница больше требуемой перекидываем пользователя в группу "Новичок", которая имеет права на запись во всех разделах форума.
Апдейт базы такого вида:
UPDATE `smf_members`
SET ID_POST_GROUP = CASE
//в минутах
WHEN (UNIX_TIMESTAMP() - dateRegistered)/60 >= 10080
AND ID_POST_GROUP = 4 THEN 9
ELSE ID_POST_GROUP
END;

отрабатывает нормально. Немного поправил файл Subs.php - функцию updateStats case 'postgroups'. Вроде все почти правильно. За исключением одного, updateStats работает только в случае если пользователь пишет пост. В случае если пользователь просто залогинился и писать не может - группа у него не измениться. Вот собсно на этом месте я и встал в ступор. По идее, нужно обновлять группу в момент логина - файл LoginOut.php - но если я вношу туда изменения вида UPDATE `smf_members` - получаю Hacking attempt... Может есть какие-то другие способы решения данной задачи? Куда и где копать?
Поскольку я не являюсь докой в php и mysql.
Буду благодарен за любую помощь.



vitkor

Вот такие изменения вносил в Subs.php, мои изменения выделены "added by vik" "end added by vik"
    case 'postgroups':
        // Parameter two is the updated columns: we should check to see if we base groups off any of these.
        if ($parameter2 !== null && !in_array('posts', $parameter2))
            return;

        if (($postgroups = cache_get_data('updateStats:postgroups', 360)) == null)
        {
            // Fetch the postgroups!
            $request = db_query("
                SELECT ID_GROUP, minPosts
                FROM {$db_prefix}membergroups
                WHERE minPosts != -1 AND minPosts != 0" , __FILE__, __LINE__);
        // added by vik
        $request1 = db_query("
                SELECT dateRegistered, ID_POST_GROUP
                FROM {$db_prefix}members
                WHERE ID_POST_GROUP = 4" , __FILE__, __LINE__);
        // end added by vik
        // added by vik
        $postgroups1 = array();
            while ($row1 = mysql_fetch_assoc($request1))
                $postgroups1[$row1['dateRegistered']] = $row1['ID_POST_GROUP'];
            mysql_free_result($request1);

            // Sort them this way because if it's done with MySQL it causes a filesort :(.
            arsort($postgroups1);
            cache_put_data('updateStats:postgroups', $postgroups1, 360);
        // end added by vik
            $postgroups = array();
            while ($row = mysql_fetch_assoc($request))
                $postgroups[$row['ID_GROUP']] = $row['minPosts'];
            mysql_free_result($request);

            // Sort them this way because if it's done with MySQL it causes a filesort :(.
            arsort($postgroups);

            cache_put_data('updateStats:postgroups', $postgroups, 360);
        }

        // Oh great, they've screwed their post groups.
        if (empty($postgroups))
            return;
        // Set all membergroups from most posts to least posts.
        $conditions = '';
        foreach ($postgroups as $id => $minPosts)
        {
            $conditions .= '
                    WHEN posts >= ' . $minPosts . (!empty($lastMin) ? ' AND posts <= ' . $lastMin : '') . ' THEN ' . $id ;
            $lastMin = $minPosts;
        }
        //added by vik
        $conditions1 = '';
        foreach ($postgroups1 as $id => $dateRegistered)
        {
            $conditions1 .= '
                    WHEN ROUND((UNIX_TIMESTAMP() - dateRegistered)/60) >= 100 AND ID_POST_GROUP = 4 THEN 9';
        }
       
        // end added by vik
        // A big fat CASE WHEN... END is faster than a zillion UPDATE's ;).
        db_query("
            UPDATE {$db_prefix}members
           
            SET ID_POST_GROUP = CASE$conditions
                    ELSE ID_POST_GROUP
                END" . ($parameter1 != null ? "
            WHERE $parameter1" : ''), __FILE__, __LINE__);
        //added by vik
        db_query("
            UPDATE {$db_prefix}members
           
            SET ID_POST_GROUP = CASE$conditions1
                    ELSE ID_POST_GROUP
                END" . ($parameter1 != null ? "
            WHERE $parameter1" : ''), __FILE__, __LINE__);
        // end added by vik
        break;

vitkor

В общем, проблему запрета вновь прибывшим пользователям оставлять сообщения сразу, решил. Тупо брутально но решил. Менять группу будем по крону, средствами операционной системы и mysql.
Пишем вот такой скрипт (smf_group_change):
#!/usr/local/bin/bash
DB=smf
USER=root
PASSWORD=******
HOST=localhost

<путь к бинарникам mysql>mysql -D $DB -h$HOST -u$USER -p$PASSWORD < \
<путь где расположен файл с запросами к базе>zapros_group_change

Скрипт берет список запросов  из файла  zapros_group_change и отправляет их в базу данных.
Запрос простой, не знаю как быстро он будет отрабатываться на большом количестве пользователей, но на малом >500, работает нормально.
Вот сам запрос, который содержится в файле zapros_group_change:
UPDATE `smf_members`
SET ID_POST_GROUP = CASE
WHEN ROUND((UNIX_TIMESTAMP() - dateRegistered)/60) >= 180
AND ID_POST_GROUP = 4 THEN 9
ELSE ID_POST_GROUP
END;

Данный запрос меняет параметр ID_POST_GROUP у пользователя с 4 (не может писать - статус "Вновь прибывший" с количеством сообщений 0) на 9 ("Новичок" с количеством сообщений 5), если с момента регистрации пользователя прошло более 3-х часов. Пользователи у которых  ID_POST_GROUP=4 писать на форуме не могут.
В строку "AND ID_POST_GROUP = 4 THEN 9" вместо 4 и 9 нужно подставить свои группы. Посмотреть можно в Администрирование > Группы пользователей.  Наведите на интересующую вас группу и после знака "=" будет цифра - это и есть id группы. Также, можно посмотреть непосредственно в базе данных, таблица smf_membergroups.
Далее, ставим на периодическое выполнение в cron с помощью команды crontab -e вставляем в таблицу задач следующую строку:
0 0/3 * * * <путь где расположен скрипт/>./smf_group_change
Таким образом, мы задали проверять и обновлять группу пользователям каждые 3 часа.


P.S Пока так. Как разберусь более детально с движком форума, попробую все сделать правильно, и оформить в виде мода. Но обещать не буду.
Так как судя по тому, что никто на просьбу не откликнулся - такая фича никому не нужна.

P.P.S Также, буду очень благодарен, если более опытные форумчане выскажут свое мнение по поводу данного решения. И по прежнему прошу помощи в оформлении правильного решения.
Спасибо.