Pull to refresh

Обсуждение страниц MediaWiki на форуме vBulletin

Признаюсь сразу: я не понял концепцию обсуждений в Wiki. Странно выглядит страница, на которой каждый пользователь от чьего угодно имени может писать/редактировать сообщения. Собщение, как правило выражающее мысль автора, должно принадлежать самому автору, а не всему сообществу.
Гораздо лучше для обсуждения подходят форумы, и лучшим из них я считаю vBulletin. Удобный, функциональный, красивый, надёжный… Хорошо бы устроить обсуждение там!
Я с удивлением обнаружил, что для этого не существует никаких расширений. Бриджи для базы пользователей и общего интерфейса есть, а этого нема. Придётся писать самому. Благо, MediaWiki и vBulletin обладают отличным расширяемым API.

Оба продукта должны использовать одну и ту же базу данных.

Шаг первый


CREATE TABLE `wiki_page2thread` (
  `page_title` varchar(255) character SET utf8 collate utf8_bin NOT NULL,
  `threadid` int(10) UNSIGNED NOT NULL,
  PRIMARY KEY  (`page_title`),
  KEY `10` (`threadid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


Шаг второй


Затем напишем расширение MediaWiki, заменяющее ссылку на обсуждение вверху страницы на форум:
<?php
$wgHooks['SkinTemplateTabs'][] = 'vbTalk'; // Регистрируем расширение
 
function vbTalk($skin, &$content_actions)
{
	$pageTitle = $GLOBALS['wgTitle']->mDbkeyform; // Получаем ключ страницы в БД
 
	if ($vbTalkInfo = mysql_fetch_assoc(mysql_query('select * from `wiki_page2thread` where page_title = "' . addslashes($pageTitle) . '"')))
	{
		// В форуме уже существует тема обсуждения этой страницы
		$content_actions['talk'] = array('class' => '',
		                                 'href' => 'http://forum_vb/showthread.php?t=' . $vbTalkInfo['threadid'],
		                                 'text' => 'Обсуждение');
	} else {
		// На форуме эту страницу не обсуждали, дадим ссылку на создание новой темы (замените URL и параметр f на ID форума, в котором будут вестись обсуждения)
		$content_actions['talk'] = array('class' => 'new',
						 'href' => 'http://forum_vb/newthread.php?do=newthread&f=12&wikiPageTitle=' . urlencode($pageTitle),
						 'text' => 'Обсуждение');
	}
 
	// Хаки должны всегда возвращать true
	return true;
}
?>


Шаг третий


Сохраним созданный выше файл в extensions/vbTalk.php и пропишем в конец LocalSettings.php:


require_once("extensions/vbTalk.php");


Шаг четвёртый


Теперь переходим к созданию модулей для vBulletin:

Местоположение модуля: newthread_form_complete


// Меняет и блокирует поле ввода заголовка темы,
// добавляет скрытое поле на странице создания новой темы
// если указано для какой Wiki-страницы создавать обсуждение.
if (!empty($_GET['wikiPageTitle']))
{
	// Что за страница
	$wikiPage = $db->query_first('select page_title from wiki_page where page_title = "' . addslashes($_GET['wikiPageTitle']) . '"');
	// А не обсуждается ли уже?
	$exists = $db->query_first('select * from wiki_page2thread where page_title = "' . addslashes($_GET['wikiPageTitle']) . '"');
 
	if ($wikiPage && !$exists)
	{
		// Делаем что нужно
		$subject = str_replace("_", " ", $wikiPage['page_title']) . '" readonly="readonly';
		$threadmanagement .= '<input type="hidden" name="wikiPageTitle" value="' . htmlspecialchars($_GET['wikiPageTitle']) . '" />';
	} else {
		// Кракер
		standard_error("Вы пытаетесь создать тему обсуждения к несуществующей Wiki-странице или тема обсуждения уже создана. Если вы считаете, что это не так, обратитесь к администратору.");
	}
}


Местоположение модуля: newthread_post_complete


// После создания новой темы привязывает её
// как обсуждение к Wiki-странице
if (!empty($_POST['wikiPageTitle']))
{
	// Ну опять эти проверки
	$wikiPage = $db->query_first('select page_title from wiki_page where page_title = "' . addslashes($_POST['wikiPageTitle']) . '"');
	$exists = $db->query_first('select * from wiki_page2thread where page_title = "' . addslashes($_POST['wikiPageID']) . '"');
 
	if ($wikiPage && !$exists)
	{
		// Привязываем
		$db->query('insert into wiki_page2thread values ("' . addslashes($_POST['wikiPageTitle']) . '", ' . $threadinfo['threadid'] . ')');
		// И сбрасываем кэш страницы
		$db->query('update wiki_page set page_touched = "' . gmdate('YmdHis') . '" where page_title = "' . addslashes($_POST['wikiPageTitle']) . '"');
	} else {
		// Настойчивый кракер
		standard_error("Вы пытаетесь создать тему обсуждения к несуществующей Wiki-странице или тема обсуждения уже создана. Если вы считаете, что это не так, обратитесь к администратору.");
	}
}


Местоположение модуля: threaddata_delete

// Отвязывает тему от Wiki-страницы
// при удалении темы
global $db;
$exists = $db->query_first('select * from wiki_page2thread where threadid = ' . $threadid);
if ($exists)
{
	// Отвязываем
	$db->query('delete from wiki_page2thread where threadid = ' . $threadid);
	// Сбрасываем кэш
	$db->query('update wiki_page set page_touched = "' . gmdate('YmdHis') . '" where page_title = "' . addslashes($exists['page_title']) . '"');
}


На этом наша работа закончена. Буду рад услышать пожелания и советы по улучшению/оптимизации кода, для решения данной задачи.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.