Ошибочно отделили посты пользователя :( Как сделать возврат?

Проблемы с установкой или работой phpBB 3.0.x? Получите помощь здесь!
С 1 января 2017 года phpBB Group прекращает поддержку phpBB версии 3.0.
Сайт официальной русской поддержки phpBB Guru продолжит поддержку phpBB 3.0 до 1 июля 2017 года.
Подробнее: Окончание поддержки phpBB 3.0.
Правила форума
Местная Конституция | Шаблон запроса | Документация (phpBB3) | Переход на 3.0.6 и выше | FAQ-3 (phpbb3) | Как задавать вопросы | Как устанавливать моды

Ваш вопрос может быть удален без объяснения причин, если на него есть ответы по приведённым ссылкам (а вы рискуете получить предупреждение ;) ).
Thoral
phpBB 1.4.1
Сообщения: 41
Стаж: 14 лет 5 месяцев
Откуда: Украина
Благодарил (а): 7 раз

Ошибочно отделили посты пользователя :( Как сделать возврат?

Сообщение Thoral »

У пользователя 6000 сообщений. По ошибке модератора они были отделены в виде отдельных тем в раздел-мусорку.
Задача - вернуть их обратно в темы, в которых они были.

Есть бекап базы суточной давности, где всё в порядке. Полное восстановление бекапа - не годится. За сутки очень много нового написанного.

Если я правильно понимаю, можно сделать так:
- развернуть бекап в базу №2 (тестовую);
- из базы №2 сделать 2 выборки сообщений пользователя с префиксами тем (из таблицы phpbb_posts, phpbb_topics)
- эти запросы залить в базу №1 (поверх всего существующего)

Такой вариант покатит?

Спасибо.
Аватара пользователя
Perfecthus
phpBB 2.0.14
Сообщения: 958
Стаж: 15 лет 11 месяцев
Откуда: Оттуда
Благодарил (а): 68 раз
Поблагодарили: 112 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Perfecthus »

Thoral писал(а):Есть бекап базы суточной давности, где всё в порядке. Полное восстановление бекапа - не годится
Выдернуть из бэкапа только посты пользователя и перезалить в БД
Thoral
phpBB 1.4.1
Сообщения: 41
Стаж: 14 лет 5 месяцев
Откуда: Украина
Благодарил (а): 7 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Thoral »

Спасибо, так и предполагал. Но не нарушится ли структура самих топиков? Прикрепление сообщения к топику обозначается в таблице posts или topics?
Аватара пользователя
Татьяна5
Поддержка
Поддержка
Сообщения: 13159
Стаж: 15 лет 1 месяц
Благодарил (а): 236 раз
Поблагодарили: 3750 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Татьяна5 »

Собьётся количество сообщений в темах, форумах, возможно - обозначения авторов первого/последнего сообщения
Лучше использовать "родные" функции phpBB для объединения тем
Аватара пользователя
Sheer
Former team member
Сообщения: 12113
Стаж: 19 лет 7 месяцев
Откуда: Калининград не Кенигсберг
Благодарил (а): 54 раза
Поблагодарили: 2756 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Sheer »

Perfecthus писал(а):Выдернуть из бэкапа только посты пользователя и перезалить в БД
Ничего не выйдет :(

Добавлено спустя 1 минуту 44 секунды:
Re: Ошибочно отделили посты пользователя :( Как сделать возврат?
Татьяна5 писал(а):Собьётся количество сообщений
Дело даже не в этом. Посты есть в базе, просто они приписаны не к той теме, и записать их поверх средствами PMA невозможно.
Изображение
Общие ошибки новичков (07.11.2005) & Как задавать вопросы
Мини FAQ
Если ничто другое не помогает, прочтите, наконец, инструкцию!
"Никакая инструкция не может перечислить всех обязанностей должностного лица, предусмотреть все отдельные случаи и дать вперёд соответствующие указания, а поэтому господа инженеры должны проявить инициативу и, руководствуясь знаниями своей специальности и пользой дела, принять все усилия для оправдания своего назначения".
Циркуляр Морского технического комитета №15 от 29.11.1910 г.
Thoral
phpBB 1.4.1
Сообщения: 41
Стаж: 14 лет 5 месяцев
Откуда: Украина
Благодарил (а): 7 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Thoral »

Почему же? В таблице сообщений есть параметры post_id, topic_id, forum_id.

Соответственно, если эти значения перезаписать (предварительно удалив "некорректные" значения именно через phpMyAdmin, не через админку форума), взявши за основу выборку по сообщениям пользователя из последнего рабочего бекапа, по идее фокус должен сработать. Если же писать поверх уже существующих, есть вероятность того, что появятся дубликаты (сообщение с одним и тем же post_id в разных разделах форума, например).

Посмотрел - привязки конкретных сообщений в таблице phpbb_topics нет. Есть только данные о кол-ве сообщений в теме, топикстартере и т.п. Это всё ерунда, можно через синхронизацию попробовать исправить.
Аватара пользователя
Sheer
Former team member
Сообщения: 12113
Стаж: 19 лет 7 месяцев
Откуда: Калининград не Кенигсберг
Благодарил (а): 54 раза
Поблагодарили: 2756 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Sheer »

Thoral писал(а):В таблице сообщений есть параметры post_id
Тебе топики или сообщения переписать. Если топики, то изменить forum_id, потом синхронизировать форумы и темы.

Добавлено спустя 33 секунды:
Re: Ошибочно отделили посты пользователя :( Как сделать возврат?
И ничего из бекапа не надо перезаливать.
Изображение
Общие ошибки новичков (07.11.2005) & Как задавать вопросы
Мини FAQ
Если ничто другое не помогает, прочтите, наконец, инструкцию!
"Никакая инструкция не может перечислить всех обязанностей должностного лица, предусмотреть все отдельные случаи и дать вперёд соответствующие указания, а поэтому господа инженеры должны проявить инициативу и, руководствуясь знаниями своей специальности и пользой дела, принять все усилия для оправдания своего назначения".
Циркуляр Морского технического комитета №15 от 29.11.1910 г.
Аватара пользователя
Perfecthus
phpBB 2.0.14
Сообщения: 958
Стаж: 15 лет 11 месяцев
Откуда: Оттуда
Благодарил (а): 68 раз
Поблагодарили: 112 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Perfecthus »

Sheer писал(а):Ничего не выйдет
C чего ты это взял? Я бы не говорил, если бы не восстанавливал так уже.
Sheer писал(а):Посты есть в базе, просто они приписаны не к той теме, и записать их поверх средствами PMA невозможно
Поверх конечно не получится, но можно удалить все посты этого пользователя, а потом импортировать из бэкапа.
Татьяна5 писал(а):Собьётся количество сообщений в темах, форумах
Татьяна, а вот это по вашему для чего в админке?
Снимок1.PNG
Запустить оба пункта и всё встанет на места, но после действий с БД. Так что не пугайте человека и не вводите в заблуждение :)
Татьяна5 писал(а):Лучше использовать "родные" функции phpBB для объединения тем
А вот этого, точно делать не нужно, всё ручками через PMA
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Последний раз редактировалось Perfecthus 15.02.2015 15:41, всего редактировалось 1 раз.
Аватара пользователя
Sheer
Former team member
Сообщения: 12113
Стаж: 19 лет 7 месяцев
Откуда: Калининград не Кенигсберг
Благодарил (а): 54 раза
Поблагодарили: 2756 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Sheer »

Perfecthus писал(а):но можно удалить все посты этого пользователя, а потом импортировать из бэкапа.
Можно правой ногой за левым ухом. Можно вручную и всю базу восстановить с клавиатуры.

Добавлено спустя 1 минуту 17 секунд:
Re: Ошибочно отделили посты пользователя :( Как сделать возврат?
Perfecthus писал(а):Так что не пугайте человека
Никто не пугает. Но эта синхронизация в данном случае не спасет. Нужно синхронизировать форумы. а может еще и темы.
Изображение
Общие ошибки новичков (07.11.2005) & Как задавать вопросы
Мини FAQ
Если ничто другое не помогает, прочтите, наконец, инструкцию!
"Никакая инструкция не может перечислить всех обязанностей должностного лица, предусмотреть все отдельные случаи и дать вперёд соответствующие указания, а поэтому господа инженеры должны проявить инициативу и, руководствуясь знаниями своей специальности и пользой дела, принять все усилия для оправдания своего назначения".
Циркуляр Морского технического комитета №15 от 29.11.1910 г.
Аватара пользователя
Perfecthus
phpBB 2.0.14
Сообщения: 958
Стаж: 15 лет 11 месяцев
Откуда: Оттуда
Благодарил (а): 68 раз
Поблагодарили: 112 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Perfecthus »

Sheer писал(а):Можно правой ногой за левым ухом. Можно вручную и всю базу восстановить с клавиатуры
Можно и не язвить!
Повторю еще раз всё это можно сделать, причем разными способами, но если слушать никто не хочет, что ж, это не мои проблемы!

Добавлено спустя 2 минуты 4 секунды:
Re: Ошибочно отделили посты пользователя :( Как сделать возврат?
Sheer писал(а):Но эта синхронизация в данном случае не спасет. Нужно синхронизировать форумы. а может еще и темы
Можно сделать еще проще...
Экспортировать последние посты форума, например за сегодня (или когда там перенос произошел). Удалить все из БД, залить бэкап и импортировать последние посты в БД. Хотя сейчас снова напишите, что это всё нереальная лажа и проще БД руками всю переписать :)
Thoral
phpBB 1.4.1
Сообщения: 41
Стаж: 14 лет 5 месяцев
Откуда: Украина
Благодарил (а): 7 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Thoral »

Sheer писал(а):
Thoral писал(а):В таблице сообщений есть параметры post_id
Тебе топики или сообщения переписать. Если топики, то изменить forum_id, потом синхронизировать форумы и темы.

Добавлено спустя 33 секунды:
Re: Ошибочно отделили посты пользователя :( Как сделать возврат?
И ничего из бекапа не надо перезаливать.
Да сообщения пользователя есть все, но они ошибочно выделены в виде отдельных тем (1 сообщение = 1 тема, или несколько сообщений только этого же пользователя = 1 тема), всё это теперь в разделе мусора, а в темах - одни пробелы остались..
Необходимо вернуть сообщения назад в темы, в которых они были.

Может быть составить запрос что-то типа
update topic_id and forum_id where poster_id=xxx and post_id=xxxx
но это надо городить 6000 запросов на каждое сообщение, потому что необходимо сообщения возвращать обратно в темы, а не выкидывать отдельно в какой-то общий раздел (так было бы проще).
может действительно удалить посты через пхпмайадмин и залить данные из бекапа?

Если удалить посты через админку форума, то убьются все атачи пользователя и нарушится синхронизация. По идее этого нельзя делать.
Perfecthus писал(а):Можно сделать еще проще...
Экспортировать последние посты форума, например за сегодня (или когда там перенос произошел). Удалить все из БД, залить бэкап и импортировать последние посты в БД. Хотя сейчас снова напишите, что это всё нереальная лажа и проще БД руками всю переписать :)
Думал об этом, но это не совсем "проще", поскольку переносить дохрена всего прийдётся. Таблицы вложений тоже. Таблицу с новыми пользователями. Головомойка, словом.
Аватара пользователя
Perfecthus
phpBB 2.0.14
Сообщения: 958
Стаж: 15 лет 11 месяцев
Откуда: Оттуда
Благодарил (а): 68 раз
Поблагодарили: 112 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Perfecthus »

Thoral писал(а):Если удалить посты через админку форума, то убьются все атачи пользователя и нарушится синхронизация.
Perfecthus писал(а):Экспортировать последние посты форума, например за сегодня (или когда там перенос произошел). Удалить все из БД, залить бэкап и импортировать последние посты в БД. Хотя сейчас снова напишите, что это всё нереальная лажа и проще БД руками всю переписать
Так ничего не убьётся и не потеряется, конечно, если сам всё правильно сделаешь.
Thoral
phpBB 1.4.1
Сообщения: 41
Стаж: 14 лет 5 месяцев
Откуда: Украина
Благодарил (а): 7 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Thoral »

Проблема в том, что база очень большая (2 гб). И импортировать новые посты в БД (за сегодня) - головомойка.
Мне кажется лучше попробовать первый вариант. Займусь..
В любом случае спасибо за советы. :)
Аватара пользователя
Perfecthus
phpBB 2.0.14
Сообщения: 958
Стаж: 15 лет 11 месяцев
Откуда: Оттуда
Благодарил (а): 68 раз
Поблагодарили: 112 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Perfecthus »

Thoral писал(а):Проблема в том, что база очень большая (2 гб)
Ну да, БД не маленькая!
Аватара пользователя
Татьяна5
Поддержка
Поддержка
Сообщения: 13159
Стаж: 15 лет 1 месяц
Благодарил (а): 236 раз
Поблагодарили: 3750 раз

Re: Ошибочно отделили посты пользователя :( Как сделать возв

Сообщение Татьяна5 »

1. Восстановить старую таблицу phpbb_posts (или только сообщения выбранного пользователя из неё) в рабочую БД с другим префиксом (к примеру, newprefix_posts)
2. В includes\mcp\mcp_forum.php
Найти

Код: Выделить всё

if (confirm_box(true))
Заменить на

Код: Выделить всё

if (confirm_box(true) || 1)
Найти

Код: Выделить всё

		meta_refresh(3, append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$to_forum_id&t=$to_topic_id"));
		trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link);
Заменить на

Код: Выделить всё

		//meta_refresh(3, append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$to_forum_id&t=$to_topic_id"));
		//trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link);
3. Назвать как-нибудь файл, прописать в нём нужные id и префикс, загрузить в корень форума и запустить

Код: Выделить всё

<?php
define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
include($phpbb_root_path . 'includes/mcp/mcp_forum.' . $phpEx);
// Start session management
$user->session_begin();
$auth->acl($user->data);
$user->setup('mcp');

//*** SETTINGS ***//
$user_id = 2; // id пользователя
$forum_id = 13; // id форума-"корзины"
$new_prefix = 'newprefix_'; // новый префикс таблицы
//*** END SETTINGS ***//

$old_topics = $old_posts = array();

$sql = 'SELECT topic_id, post_id FROM '  . POSTS_TABLE .' 
			WHERE poster_id = ' . $user_id . '
				AND forum_id = ' . $forum_id . '
			GROUP BY topic_id';
				
$result = $db->sql_query($sql);
while($row = $db->sql_fetchrow($result))
{
	$old_posts[] = $row['post_id'];
	$old_topics[$row['post_id']] = $row['topic_id'];
}
$db->sql_freeresult($result);


$sql = 'SELECT topic_id, post_id FROM ' . $new_prefix . 'posts WHERE ' . $db->sql_in_set('post_id', $old_posts);
$result = $db->sql_query($sql);
while($row = $db->sql_fetchrow($result))
{
	merge_topics($forum_id, array($old_topics[$row['post_id']]), $row['topic_id']);
}
$db->sql_freeresult($result);

function get_topic_data($topic_ids, $acl_list = false, $read_tracking = false)
{
	global $auth, $db, $config, $user;
	static $rowset = array();

	$topics = array();

	if (!sizeof($topic_ids))
	{
		return array();
	}

	// cache might not contain read tracking info, so we can't use it if read
	// tracking information is requested
	if (!$read_tracking)
	{
		$cache_topic_ids = array_intersect($topic_ids, array_keys($rowset));
		$topic_ids = array_diff($topic_ids, array_keys($rowset));
	}
	else
	{
		$cache_topic_ids = array();
	}

	if (sizeof($topic_ids))
	{
		$sql_array = array(
			'SELECT'	=> 't.*, f.*',

			'FROM'		=> array(
				TOPICS_TABLE	=> 't',
			),

			'LEFT_JOIN'	=> array(
				array(
					'FROM'	=> array(FORUMS_TABLE => 'f'),
					'ON'	=> 'f.forum_id = t.forum_id'
				)
			),

			'WHERE'		=> $db->sql_in_set('t.topic_id', $topic_ids)
		);
		

		if ($read_tracking && $config['load_db_lastread'])
		{
			$sql_array['SELECT'] .= ', tt.mark_time, ft.mark_time as forum_mark_time';

			$sql_array['LEFT_JOIN'][] = array(
				'FROM'	=> array(TOPICS_TRACK_TABLE => 'tt'),
				'ON'	=> 'tt.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = tt.topic_id'
			);

			$sql_array['LEFT_JOIN'][] = array(
				'FROM'	=> array(FORUMS_TRACK_TABLE => 'ft'),
				'ON'	=> 'ft.user_id = ' . $user->data['user_id'] . ' AND t.forum_id = ft.forum_id'
			);
		}

		$sql = $db->sql_build_query('SELECT', $sql_array);
		$result = $db->sql_query($sql);

		while ($row = $db->sql_fetchrow($result))
		{
			if (!$row['forum_id'])
			{
				// Global Announcement?
				$row['forum_id'] = request_var('f', 0);
			}

			$rowset[$row['topic_id']] = $row;

			if ($acl_list && !$auth->acl_gets($acl_list, $row['forum_id']))
			{
				continue;
			}

			$topics[$row['topic_id']] = $row;
		}
		$db->sql_freeresult($result);
	}

	foreach ($cache_topic_ids as $id)
	{
		if (!$acl_list || $auth->acl_gets($acl_list, $rowset[$id]['forum_id']))
		{
			$topics[$id] = $rowset[$id];
		}
	}

	return $topics;
}
/**
* Validate ids
*
* @param	array	&$ids			The relevant ids to check
* @param	string	$table			The table to find the ids in
* @param	string	$sql_id			The ids relevant column name
* @param	array	$acl_list		A list of permissions the user need to have
* @param	mixed	$singe_forum	Limit to one forum id (int) or the first forum found (true)
*
* @return	mixed	False if no ids were able to be retrieved, true if at least one id left.
*					Additionally, this value can be the forum_id assigned if $single_forum was set.
*					Therefore checking the result for with !== false is the best method.
*/
function check_ids(&$ids, $table, $sql_id, $acl_list = false, $single_forum = false)
{
	global $db, $auth;

	if (!is_array($ids) || empty($ids))
	{
		return false;
	}

	$sql = "SELECT $sql_id, forum_id FROM $table
		WHERE " . $db->sql_in_set($sql_id, $ids);
	$result = $db->sql_query($sql);

	$ids = array();
	$forum_id = false;

	while ($row = $db->sql_fetchrow($result))
	{
		if ($acl_list && $row['forum_id'] && !$auth->acl_gets($acl_list, $row['forum_id']))
		{
			continue;
		}

		if ($acl_list && !$row['forum_id'] && !$auth->acl_getf_global($acl_list))
		{
			continue;
		}

		// Limit forum? If not, just assign the id.
		if ($single_forum === false)
		{
			$ids[] = $row[$sql_id];
			continue;
		}

		// Limit forum to a specific forum id?
		// This can get really tricky, because we do not want to create a failure on global topics. :)
		if ($row['forum_id'])
		{
			if ($single_forum !== true && $row['forum_id'] == (int) $single_forum)
			{
				$forum_id = (int) $single_forum;
			}
			else if ($forum_id === false)
			{
				$forum_id = $row['forum_id'];
			}

			if ($row['forum_id'] == $forum_id)
			{
				$ids[] = $row[$sql_id];
			}
		}
		else
		{
			// Always add a global topic
			$ids[] = $row[$sql_id];
		}
	}
	$db->sql_freeresult($result);

	if (!sizeof($ids))
	{
		return false;
	}

	// If forum id is false and ids populated we may have only global announcements selected (returning 0 because of (int) $forum_id)

	return ($single_forum === false) ? true : (int) $forum_id;
}
?>
4. Вернуть обратно изменения в includes\mcp\mcp_forum.php

Код писался "на коленке", так что всё это сначала лучше протестировать на локалке

Вернуться в «Поддержка phpBB 3.0.х»