Song Опубликовано 6 Апреля 2005 Жалоба Поделиться Опубликовано 6 Апреля 2005 Внимание! Все add-on'ы приводимые в этом топике преднозначены для форумов версий 1.2, 1.3 Примочка №1 Если на форум стоит премодерация новых топиков, то эту премодерацию можно легко обойти, переместив топик из другого форума.Некоторые могут сказать, что дескать это ж модератор, ему можно.Но вот вам пример. В один форум идёт вечный спам. Модератору этого форума надоедает чистить, и он просит ставить премодерацию.Какой-нибудь нахальный гость плодит эту тему, пока до его одноизвилинного мозга наконец не доходит, что безрезультатно, тема не появится.Тогда он идёт в раздел по похожей тематике и оставляет тему там. Радивый модератор того раздела славно и совершенно правильно делает свою работу: он переместит эту тему по назначению.. Итак как пофиксить.Файл sources/lib/modfunctions.php Находим кусок кода: //---------------------------------- // Update the topic //---------------------------------- $DB->query("UPDATE ibf_topics SET forum_id=$moveto WHERE forum_id=$source AND tid".$tid); и заменяем на // Song * permit activation topic if the destination forum is moderated within topics, 06.04.2005 $preview = ""; $DB->query("SELECT preview_posts FROM ibf_forums WHERE id='".$moveto."'"); $moderate = $DB->fetch_row(); if ( $moderate['preview_posts'] and ( $moderate['preview_posts'] == 1 or $moderate['preview_posts'] == 2 ) ) { $preview = ", approved=0"; } // Song * permit activation topic if the destination forum is moderated within topics, 06.04.2005 //---------------------------------- // Update the topic //---------------------------------- $DB->query("UPDATE ibf_topics SET forum_id=".$moveto.$preview." WHERE forum_id=$source AND tid".$tid); Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
Christoph Schneider Опубликовано 9 Апреля 2005 Жалоба Поделиться Опубликовано 9 Апреля 2005 Полезная фича, имхоРеспект Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
Song Опубликовано 14 Апреля 2005 Автор Жалоба Поделиться Опубликовано 14 Апреля 2005 Примочка №2 Функция слежения за PM письмами, доступная в профиле выполняется очень долго, потому как написана очень нерационально и без нужных индексов.Лично у меня вызов этой функции делается около 7-10 секунд. Это конечно же не дело.Давайте убыстрим? Первое нам нужно добавить индекс:ALTER TABLE ibf_messages ADD INDEX (from_id) Это сократит выполнение функции вдвое.Давайте сократим ещё вдвое Дело в том, что функция, написанная создателями форума очень нерациональна. Схематично она выглядит так:Запрос 1Обработка результатов запроса 1 Запрос 2Обработка результатов запроса 2 Это было бы допустимо, если бы запросы были разные. Но на самом деле (вы не поверите ) они разделяются всего лишь на одну цифру.Выход так и напрашивается - объединить оба запроса в 1 и написать вывод в один цикл. Файл Messenger.phpНаходим и вырезаем полностью функциюfunction show_tracking() Вместо неё пишем мою: // Song * new tracking function function show_tracking() { global $ibforums, $DB, $std, $print; //--------------------------------------------- // Get all tracked and read messages //--------------------------------------------- $this->output .= $this->html->trackread_table_header(); $DB->query("SELECT m.*, mp.name as to_name, mp.id as memid FROM ibf_messages m, ibf_members mp WHERE m.tracking=1 AND m.from_id='".$this->member['id']."' AND m.member_id=mp.id ORDER BY m.read_state DESC, msg_date DESC"); if ( $DB->get_num_rows() ) { $current = ""; $change = FALSE; while( $row = $DB->fetch_row() ) { if ( $row['read_state'] != $current and !$row['read_state'] ) { if ( $current == "" ) $this->output .= $this->html->No_msg_inbox(); $this->output .= $this->html->trackread_end(); $this->output .= $this->html->trackUNread_table_header(); $change = TRUE; } if ( $row['read_state'] ) { $row['icon'] = "<{M_READ}>"; $row['date'] = $std->get_date( $row['read_date'] , 'LONG' ); $this->output .= $this->html->trackread_row( $row ); } else { $row['icon'] = "<{M_UNREAD}>"; $row['date'] = $std->get_date( $row['msg_date'] , 'LONG' ); $this->output .= $this->html->trackUNread_row( $row ); } $current = $row['read_state']; } if ( !$change ) { $this->output .= $this->html->trackread_end(); $this->output .= $this->html->trackUNread_table_header(); $this->output .= $this->html->No_msg_inbox(); } $this->output .= $this->html->trackUNread_end(); } else { $this->output .= $this->html->No_msg_inbox(); $this->output .= $this->html->trackread_end(); $this->output .= $this->html->trackUNread_table_header(); $this->output .= $this->html->No_msg_inbox(); $this->output .= $this->html->trackUNread_end(); } $this->page_title = $ibforums->lang['t_welcome']; $this->nav = array( "<a href='".$this->base_url."act=UserCP&CODE=00'>".$ibforums->lang['t_title']."</a>" ); } // Song * new tracking function Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
Song Опубликовано 18 Апреля 2005 Автор Жалоба Поделиться Опубликовано 18 Апреля 2005 Примочка №3Мы знаем, что в настройках групп можно включить право ответа в закрытые темы.Как правило, такое право дают для группы модераторов.При этом любой модератор может отвечать в закрытую тему любого раздела, хотя сам не модерирует там.Предлагаю пофиксить.Файлы post_reply_post.php, post_q_reply_post.php, post_edit_post.php Находим: // Is the topic locked? if ($this->topic['state'] != 'open') { if ($ibforums->member['g_post_closed'] != 1) { $std->Error( array( LEVEL => 1, MSG => 'locked_topic') ); } } меняем на: // Is the topic locked? if ( $this->topic['state'] != 'open' ) { if ( !$ibforums->member['id'] or !( $ibforums->member['g_post_closed'] and ( $ibforums->member['g_is_supmod'] or $class->moderator['mid'] ) ) ) { $std->Error( array( LEVEL => 1, MSG => 'locked_topic') ); } } Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
Song Опубликовано 24 Мая 2005 Автор Жалоба Поделиться Опубликовано 24 Мая 2005 Примочка №4Добавляем автоинкремент пользователей. Как ни странно, авторы IPB не включали автоинкремент в таблицу пользователей. Тем не менее зря.Это досадное упущение вызывает ошибки при активной регистрации пользователей. Если коротко, то регистрация выполняется так:1) Получаем максимальный id пользователя2) Прибавляем единицу3) Добавляем нового мебера4) Добавляем дополнительные поля мембера Всё бы хорошо, если между п. 1 и п.2 не вклинивалась регистрация 2-го мембера, который тоже захотел зарегистрироваться в данный момент. В этом случае система даёт сбой, id "сдваивается", а т.к. на это поле назначен PRIMARY ключ, то выдаётся MySQL ошибка. Как от этого избавиться.Прежде всего, почему разработчики не сделали автоинкремента? Не не знали же они про него Отчасти есть тому объяснение.В таблице мемберов есть участник с именем Guest. И id унего 0.Если бы был автоинкремент, тогда бы id 0-го быть не могло. Врочем, для меня всегда оставалось загадкой для чего нужен юзер Guest с id=0.При авторизации он участия не принимает. При удалении этого пользователя ничего не меняется. Итак, Шаг 1. AdminCP -> SQL Managment -> MySQL ToolBox -> область "Manual Query".Введите и исполните запросDELETE FROM ibf_members WHERE id=0 Ша 2. Файл Register.phpНайдите //+-------------------------------------------- //| Find the highest member id, and increment it //| auto_increment not used for guest id 0 val. //+-------------------------------------------- $DB->query("SELECT MAX(id) as new_id FROM ibf_members"); $r = $DB->fetch_row(); $member_id = $r['new_id'] + 1;Удалите этот кусок. Найдите на 2 строчки ниже 'id' => $member_id, Удалите этот кусок. Найдите $DB->query("INSERT INTO ibf_members (" .$db_string['FIELD_NAMES']. ") VALUES (". $db_string['FIELD_VALUES'] .")"); Добавьте ниже: // id of new user $member_id = $DB->get_insert_id(); $member['id'] = $member_id; Шаг 3. Файд ad_members.php Найдите //+-------------------------------------------- //| Find the highest member id, and increment it //| auto_increment not used for guest id 0 val. //+-------------------------------------------- $DB->query("SELECT MAX(id) as new_id FROM ibf_members"); $r = $DB->fetch_row(); $member_id = $r['new_id'] + 1;Удалите этот кусок. Чуть ниже найдите 'id' => $member_id,Удалите этот кусок. Найдите $DB->query("INSERT INTO ibf_members (" .$db_string['FIELD_NAMES']. ") VALUES (". $db_string['FIELD_VALUES'] .")"); //$member_id = $DB->get_insert_id(); Расскоментируйте вторую строчку (уберите две косые черты).Если у вас нет такой строчки то добавьте (без косых черт само собой). Шаг 4. AdminCP -> SQL Managment -> MySQL ToolBox -> область "Manual Query". Введите и исполните запрос ALTER TABLE ibf_members MODIFY id mediumint(8) UNSIGNED NOT NULL default 0 auto_increment Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
Song Опубликовано 24 Мая 2005 Автор Жалоба Поделиться Опубликовано 24 Мая 2005 Примочка №5. Часто бывает ситуация, когда юзер, зарегистрировавшись на форуме, задаёт ответ, подписывается на тему и, получив ответ, уходит с форума. Со временем его электронный адрес пропадает, а темы или форумы, подписанные на него продолжают пытаться отправляться. Файл /sources/Admin/ad_member.php 1. Найти if ($custom_out != "") { $ADMIN->html .= $SKIN->end_table(); $SKIN->td_header[] = array( " " , "40%" ); $SKIN->td_header[] = array( " " , "60%" ); //+-------------------------------+ $ADMIN->html .= $SKIN->start_table( "Custom Profile Fields" ); $ADMIN->html .= $custom_out; } Вставить перед этим: $SKIN->td_header[] = array( " " , "40%" ); $SKIN->td_header[] = array( " " , "60%" ); $ADMIN->html .= $SKIN->start_table( "Контроль подписок" ); $ADMIN->html .= $SKIN->add_td_row( array( "Удалить все подписки пользователя на темы и форумы?" , $SKIN->form_checkbox("subscribe_delete", 0) ) ); 2. Найти: //---------------------------------- // Custom profile field stuff //---------------------------------- Вставить перед этим: if ( $IN['subscribe_delete'] ) { $DB->query("DELETE FROM ibf_tracker WHERE member_id={$IN['mid']}"); $DB->query("DELETE FROM ibf_forum_tracker WHERE member_id={$IN['mid']}"); } Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
Song Опубликовано 2 Сентября 2005 Автор Жалоба Поделиться Опубликовано 2 Сентября 2005 Примочка №6 Указываем в title'е юзера о том, что он забанен. Файл Topics.php: $query = "SELECT p.*, m.id, m.name, m.mgroup, m.email, m.joined, m.avatar, m.avatar_size, m.posts, m.aim_name, m.icq_number, m.signature, m.website, m.yahoo, m.integ_msg, m.title, m.hide_email, m.msnname, m.warn_level, ....Заменить выделенный кусочек на IF(m.temp_ban=1,'".$ibforums->lang['banned_title']."',m.title) as title А в файлы lang_topic.php всех языков внести нужную надпись Файл Profile.php Ищем SELECT m.*, g.g_title as group_title FROM ibf_members m, ibf_groups g... После выделенного куска дописываем: IF(m.temp_ban=1,'".$ibforums->lang['banned_title']."',m.title) as title, В файлы lang_profile.php всех языков добавляем желаемую надпись. Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
Song Опубликовано 9 Ноября 2005 Автор Жалоба Поделиться Опубликовано 9 Ноября 2005 (изменено) Примочка №7. Помощь в отладке ошибок Идея: GIVВнимание! Версия PHP от 4.3.0 ! Очень часто когда мы разрабатываем модификации, у нас вылезают ошибки форума. Поясню: не ошибки интерпретатора php, а именно ошибки форума, который он выдаёт в функции func:: Error. Следующая модификация очень поможет вам с отладкой своих модификаций.Суть её заключается в том, что под стандартной ошибкой показывается "история" наследования классов форума с указанием номеров строк (!) и названием функций и классов.С такой информацией вы сможете быстро отладить свой код, понять где как и почему код у вас не работает так как надо.К примеру, такой мод понадобился мне при разработке мода мультиаттача 1. В функцию класса func:: $std->Error(), файл functions.phpперед $print = new display();добавляем:// Song * admin debug info if ( $ibforums->member['g_access_cp'] ) { $html = str_replace("<!--IBF.ADMIN_ERROR_CODES-->", $this->admin_debug_info(debug_backtrace()), $html); } // Song * admin debug info 2. В этот же класс функцией ниже добавляем новую функцию:// Song * admin debug info function admin_debug_info($debug_trace = array()) { global $skin_universal; $class = " class='row%d'"; foreach($debug_trace as $error) { $debug_array[] = "<tr>"; $idx = 1; foreach($error as $line) { if ( !is_array($line) ) { $curr = "<td"; if ( $idx - 1 ) { $curr .= " align='center'"; } $curr .= sprintf($class,( $idx % 2 ) ? 1 : 2).">".$line."</td>"; $debug_array[] = $curr; $idx++; } } $debug_array[count($debug_array) - 1] = "</tr>"; } $debug_txt = implode("", $debug_array); $debug_txt = $skin_universal->describe_error($debug_txt); return $debug_txt; } 3. В файле skin_global.php находим скиновую функцию function Error($message,....и в нужном месте включаем наш трейс, например перед окончанием таблицы: перед <div class='tableborder'> <div class='pformstrip' align="center">< <a href='javascript:history.go(-1)'>{$ibforums->lang['error_back']}</a> </div> </div> добавим <!--IBF.ADMIN_ERROR_CODES--> 4. В скин функцией ниже добавляем ещё одну функцию:function describe_error($data) { global $ibforums; return <<<EOF <br><b>{$ibforums->lang['desc_error_header']}</b> <div class='tableborder'> <div class='maintitle'>{$ibforums->lang['debug_caption']}</div> <table width='100%' border='0'> <tr> <th class='pformstrip'>{$ibforums->lang['debug_php_file']}</th> <th class='pformstrip'>{$ibforums->lang['debug_line_number']}</th> <th class='pformstrip'>{$ibforums->lang['debug_func_name']}</th> <th class='pformstrip'>{$ibforums->lang['debug_class_name']}</th> </tr> {$data} </table> </div> <br> EOF; } 5. В языковых файлах вам нужно описать используемые язоковые макросы на свой вкус. 6. That is all! Изменено 9 Ноября 2005 пользователем Song Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
maroleg Опубликовано 29 Августа 2007 Жалоба Поделиться Опубликовано 29 Августа 2007 Несколько замечаний по примочкамПримочка №4Последний mysql запросALTER TABLE ibf_members MODIFY id mediumint(8) UNSIGNED NOT NULL default 0 auto_incrementв таком виде не выполнится. Выдаст ошибку о неверном дефолтном значении для поля idПравильно будет так:ALTER TABLE ibf_members MODIFY id mediumint(8) UNSIGNED NOT NULL auto_increment Примочка №5Здесь небольшая ошибкаВставить перед этим: $SKIN->td_header[] = array( " " , "40%" ); $SKIN->td_header[] = array( " " , "60%" ); $ADMIN->html .= $SKIN->start_table( "Контроль подписок" ); $ADMIN->html .= $SKIN->add_td_row( array( "Удалить все подписки пользователя на темы и форумы?" , $SKIN->form_checkbox("subscribe_delete", 0) ) );Нужно так:$ADMIN->html .= $SKIN->end_table(); $SKIN->td_header[] = array( " " , "40%" ); $SKIN->td_header[] = array( " " , "60%" ); $ADMIN->html .= $SKIN->start_table( "Контроль подписок" ); $ADMIN->html .= $SKIN->add_td_row( array( "Удалить все подписки пользователя на темы и форумы?" , $SKIN->form_checkbox("subscribe_delete", 0) ) );Т.е. прежде чем открыть новую таблицу, нужно закрыть предыдущую. Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
Song Опубликовано 30 Августа 2007 Автор Жалоба Поделиться Опубликовано 30 Августа 2007 в таком виде не выполнится. Выдаст ошибку о неверном дефолтном значении для поля idПравильно будет так:В то время когда я писал эту примочку, стабильной была MySQL 3-я версия. В ней выполнится.Соответственно и пробовал всё на ней. Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
Рекомендуемые сообщения
Присоединиться к обсуждению
Вы можете ответить сейчас, а зарегистрироваться позже. Если у вас уже есть аккаунт, войдите, чтобы ответить от своего имени.