На каждом углу валяются даже русифицированные версии vBulletin и IPBoard - качай не хочу. Ценники на лиценизию ~200 и ~150 доллариев соответственно. Сопсно вопрос: насколькно нелегально пользоваться ими бесплатно? Кто-нить юзает в таком режиме? Или знакомые мож?)) Сразу предупреждаю - неправомерными действиями не собираюсь заниматься. Интерес чисто академический.
Вообщето, они по лицензии GNU распространяются (i think so). За баблосы получаешь доп. фишки, тех. поддержку и все такое.
походу, именно эти - платные. То что дается в freedownload - палево пиратское. Для законного юзания нужна лицензия, иначе через суд могут потребовать убрать свой код. Вот глянул, phpBB - по GNU лицензии идет (респект и уважуха ). Его можно качать где хочешь, изменять, выкладывать свою версию и все такое.
engager за те бабки, что просят за лиц. форум, он еще отсасывать должен я б так не говорил. другое дело - что в этих двух куча доп. прибомбасов - галереи, видео, календари и блоги. Кому нужно все в одном флаконе - пусть покупает. Кому нужен только форум - вот этот пхпбб вполне хватит.
дело не только в прибамбасах. они гораздо дружелюбнее выглядят. а пхпББ застрял в каменном веке в смоем развитии.
engager Сравни линух и виндовс - первый халявный, второй платный и красивый. Такая же аналогия и тут - сколько платишь - столько и получаешь. По-моему, неправильно ровнять бесплатный код и то что only for money.
Извини за прямоту, но моё ИМХО что vBulletin и IPBoard используют только ламеры (за деньги, потому что поддержка хорошая) или идиоты (которые думают что ломаный платный форум на халяву это круто) ни то ни другое не делается от желания иметь удобный для пользователей форум, а только от собственной глупости... Умные люди качают бесплатные/открытые форумы, и модифицируют (если надо) под нужды своей публики (для этого конечно нужны мозги, время и желание угодить простым юзерам) Ржал как конь... Мало того это субъективно, но если смотреть дефолтный скин то у рнрВВ (причём даже 2-го который и в правду устарел) удобен и приятен намного большему количеству людей...
Vladson Владсон, ты извини, но ты бредишь. Всех под одну гребенку ... Лично мне в первую очередь нравится профессионализм и изящество, с которым IP.Board написан. Код - конфетка.
Где я сказал всех, я сказал ИМХО (т.е всех кого видел я) В коде может быть, но пользователю не насрать ли на код ? (не могу писать/читать/искать, всё неудобно, юзабилити на нуле)
Vladson Я думаю, что я не смогу тебя переубедить. А я не приму твою точку зрения. Так что проще будет не обсуждать это.
admyx ты забываешь, что с одной стороны free, а с другой 150 уе. Вот в эти бабки и входят всякие плюшки
Пиздеть не мешки ворочать, ты бы привел ссылки на форумы с функционалом,удобством и поддержкой аналогично IPB хотя-бы, тогда и можно о чем-то говорить.
В гугле забанили ? Первое что попалось... http://en.wikipedia.org/wiki/Comparison_of_Internet_forum_software_(PHP) (выбирай на вкус, есть те где код конфетка, легко допилить до того что надо, есть где говнокод но простой что даже идиот допилит)
Koc Я пуп земли ? Или может ты ? Универсального решения для всех нет !!! Кому-то нравится в говнокоде копаться, кому-то нравится хорошо структурированный код, на некоторых я лично использую SMF на некоторых FluxBB, и даже рнрВВ2 (зависит от требований публики, и квалификаци админов)
100500 точек входа. Аштеемло вперемешку с запросами к БД. PHP: <?php /** * Copyright (C) 2008-2010 FluxBB * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB * License: [url=http://www.gnu.org/licenses/gpl.html]http://www.gnu.org/licenses/gpl.html[/url] GPL version 2 or higher */ // Tell header.php to use the admin template define('PUN_ADMIN_CONSOLE', 1); define('PUN_ROOT', './'); require PUN_ROOT.'include/common.php'; require PUN_ROOT.'include/common_admin.php'; if ($pun_user['g_id'] != PUN_ADMIN) message($lang_common['No permission']); // Load the admin_permissions.php language file require PUN_ROOT.'lang/'.$admin_language.'/admin_permissions.php'; if (isset($_POST['form_sent'])) { confirm_referrer('admin_permissions.php'); $form = array_map('intval', $_POST['form']); foreach ($form as $key => $input) { // Only update values that have changed if (array_key_exists('p_'.$key, $pun_config) && $pun_config['p_'.$key] != $input) $db->query('UPDATE '.$db->prefix.'config SET conf_value='.$input.' WHERE conf_name=\'p_'.$db->escape($key).'\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error()); } // Regenerate the config cache if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) require PUN_ROOT.'include/cache.php'; generate_config_cache(); redirect('admin_permissions.php', $lang_admin_permissions['Perms updated redirect']); } $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_admin_common['Admin'], $lang_admin_common['Permissions']); define('PUN_ACTIVE_PAGE', 'admin'); require PUN_ROOT.'header.php'; generate_admin_menu('permissions'); ?> <div class="blockform"> <h2><span><?php echo $lang_admin_permissions['Permissions head'] ?></span></h2> <div class="box"> <form method="post" action="admin_permissions.php"> <p class="submittop"><input type="submit" name="save" value="<?php echo $lang_admin_common['Save changes'] ?>" /></p> <div class="inform"> <input type="hidden" name="form_sent" value="1" /> <fieldset> <legend><?php echo $lang_admin_permissions['Posting subhead'] ?></legend> <div class="infldset"> <table class="aligntop" cellspacing="0"> <tr> <th scope="row"><?php echo $lang_admin_permissions['BBCode label'] ?></th> <td> <input type="radio" name="form[message_bbcode]" value="1"<?php if ($pun_config['p_message_bbcode'] == '1') echo ' checked="checked"' ?> /> <strong><?php echo $lang_admin_common['Yes'] ?></strong> <input type="radio" name="form[message_bbcode]" value="0"<?php if ($pun_config['p_message_bbcode'] == '0') echo ' checked="checked"' ?> /> <strong><?php echo $lang_admin_common['No'] ?></strong> <span><?php echo $lang_admin_permissions['BBCode help'] ?></span> </td> </tr> <tr> <th scope="row"><?php echo $lang_admin_permissions['Image tag label'] ?></th> <td> <input type="radio" name="form[message_img_tag]" value="1"<?php if ($pun_config['p_message_img_tag'] == '1') echo ' checked="checked"' ?> /> <strong><?php echo $lang_admin_common['Yes'] ?></strong> <input type="radio" name="form[message_img_tag]" value="0"<?php if ($pun_config['p_message_img_tag'] == '0') echo ' checked="checked"' ?> /> <strong><?php echo $lang_admin_common['No'] ?></strong> <span><?php echo $lang_admin_permissions['Image tag help'] ?></span> </td> </tr> <tr> <th scope="row"><?php echo $lang_admin_permissions['All caps message label'] ?></th> <td> <input type="radio" name="form[message_all_caps]" value="1"<?php if ($pun_config['p_message_all_caps'] == '1') echo ' checked="checked"' ?> /> <strong><?php echo $lang_admin_common['Yes'] ?></strong> <input type="radio" name="form[message_all_caps]" value="0"<?php if ($pun_config['p_message_all_caps'] == '0') echo ' checked="checked"' ?> /> <strong><?php echo $lang_admin_common['No'] ?></strong> <span><?php echo $lang_admin_permissions['All caps message help'] ?></span> </td> </tr> это по твоему не говнокод? SMF PHP: <?php /********************************************************************************** * ManageRegistration.php * *********************************************************************************** * SMF: Simple Machines Forum * * Open-Source Project Inspired by Zef Hemel ([email=zef@zefhemel.com]zef@zefhemel.com[/email]) * * =============================================================================== * * Software Version: SMF 2.0 RC3 * * Software by: Simple Machines ([url=http://www.simplemachines.org]http://www.simplemachines.org[/url]) * * Copyright 2006-2010 by: Simple Machines LLC ([url=http://www.simplemachines.org]http://www.simplemachines.org[/url]) * * 2001-2006 by: Lewis Media ([url=http://www.lewismedia.com]http://www.lewismedia.com[/url]) * * Support, News, Updates at: [url=http://www.simplemachines.org]http://www.simplemachines.org[/url] * *********************************************************************************** * This program is free software; you may redistribute it and/or modify it under * * the terms of the provided license as published by Simple Machines LLC. * * * * This program is distributed in the hope that it is and will be useful, but * * WITHOUT ANY WARRANTIES; without even any implied warranty of MERCHANTABILITY * * or FITNESS FOR A PARTICULAR PURPOSE. * * * * See the "license.txt" file for details of the Simple Machines license. * * The latest version can always be found at [url=http://www.simplemachines.org]http://www.simplemachines.org[/url]. * **********************************************************************************/ if (!defined('SMF')) die('Hacking attempt...'); // Main handling function for the admin approval center function RegCenter() { global $modSettings, $context, $txt, $scripturl; // Old templates might still request this. if (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'browse') redirectexit('action=admin;area=viewmembers;sa=browse' . (isset($_REQUEST['type']) ? ';type=' . $_REQUEST['type'] : '')); $subActions = array( 'register' => array('AdminRegister', 'moderate_forum'), 'agreement' => array('EditAgreement', 'admin_forum'), 'reservednames' => array('SetReserve', 'admin_forum'), 'settings' => array('ModifyRegistrationSettings', 'admin_forum'), ); // Work out which to call... $context['sub_action'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : (allowedTo('moderate_forum') ? 'register' : 'settings'); // Must have sufficient permissions. isAllowedTo($subActions[$context['sub_action']][1]); // Loading, always loading. loadLanguage('Login'); loadTemplate('Register'); // Next create the tabs for the template. $context[$context['admin_menu_name']]['tab_data'] = array( 'title' => $txt['registration_center'], 'help' => 'registrations', 'description' => $txt['admin_settings_desc'], 'tabs' => array( 'register' => array( 'description' => $txt['admin_register_desc'], ), 'agreement' => array( 'description' => $txt['registration_agreement_desc'], ), 'reservednames' => array( 'description' => $txt['admin_reserved_desc'], ), 'settings' => array( 'description' => $txt['admin_settings_desc'], ) ) ); // Finally, get around to calling the function... $subActions[$context['sub_action']][0](); } // This function allows the admin to register a new member by hand. function AdminRegister() { global $txt, $context, $sourcedir, $scripturl, $smcFunc; if (!empty($_POST['regSubmit'])) { checkSession(); foreach ($_POST as $key => $value) if (!is_array($_POST[$key])) $_POST[$key] = htmltrim__recursive(str_replace(array("\n", "\r"), '', $_POST[$key])); $regOptions = array( 'interface' => 'admin', 'username' => $_POST['user'], 'email' => $_POST['email'], 'password' => $_POST['password'], 'password_check' => $_POST['password'], 'check_reserved_name' => true, 'check_password_strength' => false, 'check_email_ban' => false, 'send_welcome_email' => isset($_POST['emailPassword']) || empty($_POST['password']), 'require' => isset($_POST['emailActivate']) ? 'activation' : 'nothing', 'memberGroup' => empty($_POST['group']) || !allowedTo('manage_membergroups') ? 0 : (int) $_POST['group'], ); require_once($sourcedir . '/Subs-Members.php'); $memberID = registerMember($regOptions); if (!empty($memberID)) { $context['new_member'] = array( 'id' => $memberID, 'name' => $_POST['user'], 'href' => $scripturl . '?action=profile;u=' . $memberID, 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $memberID . '">' . $_POST['user'] . '</a>', ); $context['registration_done'] = sprintf($txt['admin_register_done'], $context['new_member']['link']); } } // Basic stuff. $context['sub_template'] = 'admin_register'; $context['page_title'] = $txt['registration_center']; // Load the assignable member groups. if (allowedTo('manage_membergroups')) { $request = $smcFunc['db_query']('', ' SELECT group_name, id_group FROM {db_prefix}membergroups WHERE id_group != {int:moderator_group} AND min_posts = {int:min_posts}' . (allowedTo('admin_forum') ? '' : ' AND id_group != {int:admin_group}') . ' AND hidden != {int:hidden_group} ORDER BY min_posts, CASE WHEN id_group < {int:newbie_group} THEN id_group ELSE 4 END, group_name', array( 'moderator_group' => 3, 'min_posts' => -1, 'admin_group' => 1, 'hidden_group' => 2, 'newbie_group' => 4, ) ); $context['member_groups'] = array(0 => $txt['admin_register_group_none']); while ($row = $smcFunc['db_fetch_assoc']($request)) $context['member_groups'][$row['id_group']] = $row['group_name']; $smcFunc['db_free_result']($request); } else $context['member_groups'] = array(); } // Set reserved names/words.... function SetReserve() { global $txt, $context, $modSettings; // Submitting new reserved words. if (!empty($_POST['save_reserved_names'])) { checkSession(); // Set all the options.... updateSettings(array( 'reserveWord' => (isset($_POST['matchword']) ? '1' : '0'), 'reserveCase' => (isset($_POST['matchcase']) ? '1' : '0'), 'reserveUser' => (isset($_POST['matchuser']) ? '1' : '0'), 'reserveName' => (isset($_POST['matchname']) ? '1' : '0'), 'reserveNames' => str_replace("\r", '', $_POST['reserved']) )); } // Get the reserved word options and words. $modSettings['reserveNames'] = str_replace('\n', "\n", $modSettings['reserveNames']); $context['reserved_words'] = explode("\n", $modSettings['reserveNames']); $context['reserved_word_options'] = array(); $context['reserved_word_options']['match_word'] = $modSettings['reserveWord'] == '1'; $context['reserved_word_options']['match_case'] = $modSettings['reserveCase'] == '1'; $context['reserved_word_options']['match_user'] = $modSettings['reserveUser'] == '1'; $context['reserved_word_options']['match_name'] = $modSettings['reserveName'] == '1'; // Ready the template...... $context['sub_template'] = 'edit_reserved_words'; $context['page_title'] = $txt['admin_reserved_set']; } // This function handles registration settings, and provides a few pretty stats too while it's at it. function ModifyRegistrationSettings($return_config = false) { global $txt, $context, $scripturl, $modSettings, $sourcedir; // This is really quite wanting. require_once($sourcedir . '/ManageServer.php'); $config_vars = array( array('select', 'registration_method', array($txt['setting_registration_standard'], $txt['setting_registration_activate'], $txt['setting_registration_approval'], $txt['setting_registration_disabled'])), array('check', 'enableOpenID'), array('check', 'notify_new_registration'), array('check', 'send_welcomeEmail'), '', array('int', 'coppaAge', 'subtext' => $txt['setting_coppaAge_desc'], 'onchange' => 'checkCoppa();'), array('select', 'coppaType', array($txt['setting_coppaType_reject'], $txt['setting_coppaType_approval']), 'onchange' => 'checkCoppa();'), array('large_text', 'coppaPost', 'subtext' => $txt['setting_coppaPost_desc']), array('text', 'coppaFax'), array('text', 'coppaPhone'), ); if ($return_config) return $config_vars; // Setup the template $context['sub_template'] = 'show_settings'; $context['page_title'] = $txt['registration_center']; if (isset($_GET['save'])) { checkSession(); // Are there some contacts missing? if (!empty($_POST['coppaAge']) && !empty($_POST['coppaType']) && empty($_POST['coppaPost']) && empty($_POST['coppaFax'])) fatal_lang_error('admin_setting_coppa_require_contact'); // Post needs to take into account line breaks. $_POST['coppaPost'] = str_replace("\n", '<br />', empty($_POST['coppaPost']) ? '' : $_POST['coppaPost']); saveDBSettings($config_vars); redirectexit('action=admin;area=regcenter;sa=settings'); } $context['post_url'] = $scripturl . '?action=admin;area=regcenter;save;sa=settings'; $context['settings_title'] = $txt['settings']; // Define some javascript for COPPA. $context['settings_post_javascript'] = ' function checkCoppa() { var coppaDisabled = document.getElementById(\'coppaAge\').value == 0; document.getElementById(\'coppaType\').disabled = coppaDisabled; var disableContacts = coppaDisabled || document.getElementById(\'coppaType\').options[document.getElementById(\'coppaType\').selectedIndex].value != 1; document.getElementById(\'coppaPost\').disabled = disableContacts; document.getElementById(\'coppaFax\').disabled = disableContacts; document.getElementById(\'coppaPhone\').disabled = disableContacts; } checkCoppa();'; // Turn the postal address into something suitable for a textbox. $modSettings['coppaPost'] = !empty($modSettings['coppaPost']) ? preg_replace('~<br ?/?' . '>~', "\n", $modSettings['coppaPost']) : ''; prepareDBSettingContext($config_vars); } ?> мм, крастота. У них даже банального автолоада нет не думаю. Скорее ты - пиздабол