[BETA] Assign multiple posts to another user

Zelf bezig aan een modificatie? Wij kijken graag mee..
Forumregels

LEES: Algemene Voorwaarden. Denk eventueel aan tags (DEV, BETA, RC)!
phpBB3.0.x
Plaats reactie
Salomon
Berichten: 3878
Lid geworden op: 14 feb 2006, 16:15

[BETA] Assign multiple posts to another user

Bericht door Salomon » 27 dec 2007, 12:47

Beta stadium!

Code:

Code: Selecteer alles

<?php
/** 
*
* @package phpBB3
* @version $Id: $
* @copyright (c) 2007 phpBB Group 
* @license http://opensource.org/licenses/gpl-license.php GNU Public License 
*
*/

/**
*/

/**
* @ignore
*/
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);
$mode = request_var('mode', '');

// Start session management
$user->session_begin();
$auth->acl($user->data);
$user->setup();

// Does the user have admin permissions?
if(!$auth->acl_get('a_')) 
{
	// It seems he hasn't...
	trigger_error('You are not an admin', E_USER_ERROR);
}

switch($mode) 
{
	case 'submit':
		// Get some needed things
		$new_poster_id			= intval(request_var('new_poster_id', 0));
		$old_user_id			= intval(request_var('old_user_id', 1));
		$old_post_username		= $db->sql_escape(request_var('old_post_username', ''));
		
		// Get information about the new user
		$sql = "SELECT user_colour, username FROM " . USERS_TABLE . " WHERE user_id = " . $new_poster_id;
		$result = $db->sql_query($sql);
		$new_user_data = $db->sql_fetchrow($result);
		if(empty($result)) 
		{
			// We have a little problem right here
			trigger_error($user->lang['USER_NOT_EXISTS'], E_USER_ERROR);
		}
		$new_poster_colour = $new_user_data['user_colour'];
		$new_poster_username = $new_user_data['username'];
		$err_msg = '';
		if(empty($old_post_username) || empty($new_poster_id) || empty($old_user_id)) {
			// O no! We don't have all the things we need! That's not wat we want!
			$err_msg = "Not al needed things given!<br />\n";
			show_form($err_msg);
			break;
		}
		$result = array();
		// Now we are gonna 'undo' all the query the delete_user function does.
		$sql1 = 'UPDATE ' . POSTS_TABLE .  "
			SET poster_id = '$new_poster_id', post_username = '$new_poster_username' 
			WHERE post_username = '$old_post_username' 
				AND poster_id = $old_user_id;";
		$result[] = $db->sql_query($sql1);
		$sql2 = 	'UPDATE ' . TOPICS_TABLE . "
			SET topic_poster = $new_poster_id, topic_first_poster_name = '$new_poster_username', topic_first_poster_colour = '$new_poster_colour' 
			WHERE topic_first_poster_name = '$old_post_username' 
				AND topic_poster = $old_user_id;";
		$result[] = $db->sql_query($sql2);
		$sql3 = 	'UPDATE ' . TOPICS_TABLE . " 
			SET topic_last_poster_id = $new_poster_id, topic_last_poster_name = '$new_poster_username', topic_last_poster_colour = '$new_poster_colour' 
				WHERE topic_last_poster_name = '$old_post_username' 
					AND topic_last_poster_id = $old_user_id;";
		$result[] = $db->sql_query($sql3);
		$sql4 = 	'UPDATE ' . FORUMS_TABLE . " 
			SET forum_last_poster_id = $new_poster_id, forum_last_poster_name = '$new_poster_username', forum_last_poster_colour = '$new_poster_colour' 
				WHERE forum_last_poster_name = '$old_post_username'
					AND forum_last_poster_id = $old_user_id;";
		$result[] = $db->sql_query($sql4);
		$sql5 = 'UPDATE ' . POSTS_TABLE . '
			SET post_edit_user = ' . $new_poster_id . "
				WHERE post_edit_user = $old_user_id";
		$result[] = $db->sql_query($sql5);
		if(in_array(false, $result)) 
		{
			// Everything has gone fine. Jippie!
			echo "Succes!";
			resync('stats');
			resync('db_track');
			resync('user');
		}
		else 
		{
			// We have an error right here.
			$failed_sql = array_ksearch(false, $result);
			echo "Sorry... Something has gone wrong in query<br />\n";
			foreach($failed_sql as $failed_sql_query) {
				$failed_sql_query--;
				$sql_var = 'sql' . $failed_sql_query;
				echo $$sql_var . "<br />\n";
			}
			
		}
	break;
	
	default:
	case 'view':
		show_form();
	break;		
}
/**
 * Show form and display a given error message
 *
 * @param string $error_message
 */
function show_form($error_message= '') 
{
	global $sid;
	$action = $_SERVER['SCRIPT_FILENAME'];
	?><html>
	<head>
		<title>Assign multiple posts to an other user</title>
	</head>	
	<body>
		<?php echo $error_msg; ?>
		<form action="<?php echo $action ?>" method="post">
			<table>
				<tr>
					<td width="20%">
						New poster id:
					</td>
					<td>
						<input type="text" name="new_poster_id" />
					</td>
				</tr>
				<tr>
					<td>
						Old user id:
					</td>
					<td>
						<input type="text" name="old_user_id" value="1" /> (If you don't know, leave it to 1)
					</td>
				</tr>
				<tr>
					<td>
						Old post username:
					</td>
					<td>
						<input type="text" name="old_post_username" />
					</td>
				</tr>
				<tr>
					<td>
						<input type="submit" value="Submit" />
					</td>
				</tr>
			</table>
		<input type="hidden" name="mode" value="submit" />
		<input type="hidden" name="sid" value="<?php echo $sid; ?>" />
		</form>
	</body>
</html><?
	
}

/**
 * Resync things like stats etc
 */

function resync($action) 
{
	global $db, $user, $auth;
	global $phpbb_root_path, $phpEx;
	switch ($action)
	{
		case 'stats':
			if (!$auth->acl_get('a_board'))
			{
				trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
			}
			$sql = 'SELECT COUNT(post_id) AS stat
				FROM ' . POSTS_TABLE . '
					WHERE post_approved = 1';
				$result = $db->sql_query($sql);
				set_config('num_posts', (int) $db->sql_fetchfield('stat'), true);
				$db->sql_freeresult($result);
				$sql = 'SELECT COUNT(topic_id) AS stat
					FROM ' . TOPICS_TABLE . '
					WHERE topic_approved = 1';
				$result = $db->sql_query($sql);
				set_config('num_topics', (int) $db->sql_fetchfield('stat'), true);
				$db->sql_freeresult($result);
				$sql = 'SELECT COUNT(user_id) AS stat
					FROM ' . USERS_TABLE . '
					WHERE user_type IN (' . USER_NORMAL . ',' . USER_FOUNDER . ')';
				$result = $db->sql_query($sql);
				set_config('num_users', (int) $db->sql_fetchfield('stat'), true);
				$db->sql_freeresult($result);
				$sql = 'SELECT COUNT(attach_id) as stat
					FROM ' . ATTACHMENTS_TABLE . '
					WHERE is_orphan = 0';
				$result = $db->sql_query($sql);
				set_config('num_files', (int) $db->sql_fetchfield('stat'), true);
				$db->sql_freeresult($result);
				$sql = 'SELECT SUM(filesize) as stat
					FROM ' . ATTACHMENTS_TABLE . '
					WHERE is_orphan = 0';
				$result = $db->sql_query($sql);
				set_config('upload_dir_size', (int) $db->sql_fetchfield('stat'), true);
				$db->sql_freeresult($result);
				
				if (!function_exists('update_last_username'))
				{
					include($phpbb_root_path . "includes/functions_user.$phpEx");
				}
				update_last_username();
				add_log('admin', 'LOG_RESYNC_STATS');
			break;
			case 'user':
				if (!$auth->acl_get('a_board'))
				{
					trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
				}
				$sql = 'SELECT COUNT(p.post_id) AS num_posts, u.user_id
					FROM ' . USERS_TABLE . ' u
					LEFT JOIN  ' . POSTS_TABLE . ' p ON (u.user_id = p.poster_id AND p.post_postcount = 1)
					GROUP BY u.user_id';
				$result = $db->sql_query($sql);
				while ($row = $db->sql_fetchrow($result))
				{
					$db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['user_id']}");
				}
				$db->sql_freeresult($result);
				add_log('admin', 'LOG_RESYNC_POSTCOUNTS');
			break;
		
			case 'db_track':
				switch ($db->sql_layer)
				{
				case 'sqlite':
					case 'firebird':
						$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
					break;
					default:
						$db->sql_query('TRUNCATE TABLE ' . TOPICS_POSTED_TABLE);
					break;
				}
				// This can get really nasty... therefore we only do the last six months
				$get_from_time = time() - (6 * 4 * 7 * 24 * 60 * 60);
				// Select forum ids, do not include categories
				$sql = 'SELECT forum_id
					FROM ' . FORUMS_TABLE . '
					WHERE forum_type <> ' . FORUM_CAT;
				$result = $db->sql_query($sql);
		
				$forum_ids = array();
				while ($row = $db->sql_fetchrow($result))
				{
					$forum_ids[] = $row['forum_id'];
				}
				$db->sql_freeresult($result);
				// Any global announcements? ;)
				$forum_ids[] = 0;
				// Now go through the forums and get us some topics...
				foreach ($forum_ids as $forum_id)
				{
					$sql = 'SELECT p.poster_id, p.topic_id
						FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t
						WHERE t.forum_id = ' . $forum_id . '
							AND t.topic_moved_id = 0
							AND t.topic_last_post_time > ' . $get_from_time . '
							AND t.topic_id = p.topic_id
							AND p.poster_id <> ' . ANONYMOUS . '
						GROUP BY p.poster_id, p.topic_id';
					$result = $db->sql_query($sql);
					$posted = array();
					while ($row = $db->sql_fetchrow($result))
					{
						$posted[$row['poster_id']][] = $row['topic_id'];
					}
					$db->sql_freeresult($result);
					$sql_ary = array();
					foreach ($posted as $user_id => $topic_row)
					{
						foreach ($topic_row as $topic_id)
						{
							$sql_ary[] = array(
								'user_id'		=> (int) $user_id,
								'topic_id'		=> (int) $topic_id,
								'topic_posted'	=> 1,
							);
						}
					}
					unset($posted);
					if (sizeof($sql_ary))
					{
						$db->sql_multi_insert(TOPICS_POSTED_TABLE, $sql_ary);
					}
				}
	
				add_log('admin', 'LOG_RESYNC_POST_MARKING');
			break;
	}
}

/**
 * Search for more values in an array
 * Thanks to kermes [at] thesevens [dot] net on http://nl3.php.net/array_search
 */
function array_ksearch($needle, $haystack)
{
	$result = array();
	for($i = 0; $i < count($haystack); next($haystack), $i++) 
    {
		if(strtolower(current($haystack)) == strtolower($needle)) {
			array_push($result, key($haystack));
		}
    }

	return $result;
}
?>
Plak dit in een bestand genaamd poststouser.php en open dat in je webbrowser.
Veel plezier ermee :)

Oud bericht:
Spoiler: bekijk
Ik ben bezig met een mod die een beheerder in staat stelt om posts van een verwijderde gebruiker OF een andere gebruiker toe te wijzen aan een nieuwe gebruiker. Dit heb ik nu: t41866 (omdat code=php niet werkt, omdat acyd burn het niet kon fixen :()
En in gewone code:

Code: Selecteer alles

<?php
/**
*
* @package phpBB3
* @version $Id: poststouser.php,v 1.0 2007/12/27 12:07:08 SalomonV Exp $
* @copyright (c) 2007 SalomonV
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

/**
*/

/**
* @ignore
*/
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);
$mode = request_var('mode', '');

// Start session management
$user->session_begin();
$auth->acl($user->data);

if(!$auth->acl_get('a_')) {
	trigger_error(E_USER_ERROR, $user->lang['NO_ADMIN']);
}

switch ( $mode ) {
	case 'submit':
		$new_poster_id			= request_var('new_poster_id', 0);
		$old_userid				= request_var('old_userid', 1);
		$old_post_username		= request_var('old_post_username', '');
		
		$sql = "SELECT user_colour, username FROM " . USERS_TABLE . " WHERE user_id = " . $new_poster_id;
		$result = $db->sql_query($sql);
		$new_user_data = $db->sql_fetchrow($result);
		$new_poster_colour = $new_user_data['user_colour'];
		$new_poster_username = $new_user_data['username'];
		
		if(empty($old_post_username) || empty($new_poster_id) || empty($old_userid)) {
			$err_msg = 'Not al needed things given!';
			$mode = 'view';
			break;
		}
		$sql = "UPDATE " . POSTS_TABLE .  " SET poster_id = $new_poster_id, post_username = '$new_poster_username' WHERE post_username = '$old_post_username' AND poster_id = $old_userid;
				UPDATE " . TOPICS_TABLE . " SET topic_poster = $new_poster_id, topic_first_poster_name = '$new_poster_username', topic_first_poster_colour = '$new_poster_colour' WHERE topic_first_poster_name = '$old_post_username' AND topic_poster = $old_userid;
				UPDATE " . TOPICS_TABLE . " SET topic_last_poster_id = $new_poster_id, topic_last_poster_name = '$new_poster_username', topic_last_poster_colour = '$new_poster_colour' WHERE topic_last_poster_name = '$old_post_username' AND topic_last_poster_id = $old_userid;
				UPDATE " . FORUMS_TABLE . " SET forum_last_poster_id = $new_poster_id, forum_last_poster_name = '$new_poster_username', forum_last_poster_colour = '$new_poster_colour' WHERE forum_last_poster_name = '$old_post_username' AND forum_last_poster_id = $old_userid;";
		$result = $db->sql_query( $sql );
		if ( $result ) {
			echo "Succes!";
			resync('stats');
			resync('db_track');
			resync('user');
		}
		else {
			echo "Sorry...";
		}
	break;
	
	default:
	case 'view':
		// Input fields
	break;		
}

function resync($action) {
	global $db, $user, $auth;
	global $phpbb_root_path, $phpEx;
	switch ($action)
	{
		case 'stats':
			if (!$auth->acl_get('a_board'))
			{
				trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
			}
			$sql = 'SELECT COUNT(post_id) AS stat
				FROM ' . POSTS_TABLE . '
					WHERE post_approved = 1';
				$result = $db->sql_query($sql);
				set_config('num_posts', (int) $db->sql_fetchfield('stat'), true);
				$db->sql_freeresult($result);
				$sql = 'SELECT COUNT(topic_id) AS stat
					FROM ' . TOPICS_TABLE . '
					WHERE topic_approved = 1';
				$result = $db->sql_query($sql);
				set_config('num_topics', (int) $db->sql_fetchfield('stat'), true);
				$db->sql_freeresult($result);
				$sql = 'SELECT COUNT(user_id) AS stat
					FROM ' . USERS_TABLE . '
					WHERE user_type IN (' . USER_NORMAL . ',' . USER_FOUNDER . ')';
				$result = $db->sql_query($sql);
				set_config('num_users', (int) $db->sql_fetchfield('stat'), true);
				$db->sql_freeresult($result);
				$sql = 'SELECT COUNT(attach_id) as stat
					FROM ' . ATTACHMENTS_TABLE . '
					WHERE is_orphan = 0';
				$result = $db->sql_query($sql);
				set_config('num_files', (int) $db->sql_fetchfield('stat'), true);
				$db->sql_freeresult($result);
				$sql = 'SELECT SUM(filesize) as stat
					FROM ' . ATTACHMENTS_TABLE . '
					WHERE is_orphan = 0';
				$result = $db->sql_query($sql);
				set_config('upload_dir_size', (int) $db->sql_fetchfield('stat'), true);
				$db->sql_freeresult($result);
				
				if (!function_exists('update_last_username'))
				{
					include($phpbb_root_path . "includes/functions_user.$phpEx");
				}
				update_last_username();
				add_log('admin', 'LOG_RESYNC_STATS');
			break;
			case 'user':
				if (!$auth->acl_get('a_board'))
				{
					trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
				}
				$sql = 'SELECT COUNT(p.post_id) AS num_posts, u.user_id
					FROM ' . USERS_TABLE . ' u
					LEFT JOIN  ' . POSTS_TABLE . ' p ON (u.user_id = p.poster_id AND p.post_postcount = 1)
					GROUP BY u.user_id';
				$result = $db->sql_query($sql);
				while ($row = $db->sql_fetchrow($result))
				{
					$db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['user_id']}");
				}
				$db->sql_freeresult($result);
				add_log('admin', 'LOG_RESYNC_POSTCOUNTS');
			break;
		
			case 'db_track':
				switch ($db->sql_layer)
				{
				case 'sqlite':
					case 'firebird':
						$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
					break;
					default:
						$db->sql_query('TRUNCATE TABLE ' . TOPICS_POSTED_TABLE);
					break;
				}
				// This can get really nasty... therefore we only do the last six months
				$get_from_time = time() - (6 * 4 * 7 * 24 * 60 * 60);
				// Select forum ids, do not include categories
				$sql = 'SELECT forum_id
					FROM ' . FORUMS_TABLE . '
					WHERE forum_type <> ' . FORUM_CAT;
				$result = $db->sql_query($sql);
		
				$forum_ids = array();
				while ($row = $db->sql_fetchrow($result))
				{
					$forum_ids[] = $row['forum_id'];
				}
				$db->sql_freeresult($result);
				// Any global announcements? ;)
				$forum_ids[] = 0;
				// Now go through the forums and get us some topics...
				foreach ($forum_ids as $forum_id)
				{
					$sql = 'SELECT p.poster_id, p.topic_id
						FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t
						WHERE t.forum_id = ' . $forum_id . '
							AND t.topic_moved_id = 0
							AND t.topic_last_post_time > ' . $get_from_time . '
							AND t.topic_id = p.topic_id
							AND p.poster_id <> ' . ANONYMOUS . '
						GROUP BY p.poster_id, p.topic_id';
					$result = $db->sql_query($sql);
					$posted = array();
					while ($row = $db->sql_fetchrow($result))
					{
						$posted[$row['poster_id']][] = $row['topic_id'];
					}
					$db->sql_freeresult($result);
					$sql_ary = array();
					foreach ($posted as $user_id => $topic_row)
					{
						foreach ($topic_row as $topic_id)
						{
							$sql_ary[] = array(
								'user_id'		=> (int) $user_id,
								'topic_id'		=> (int) $topic_id,
								'topic_posted'	=> 1,
							);
						}
					}
					unset($posted);
					if (sizeof($sql_ary))
					{
						$db->sql_multi_insert(TOPICS_POSTED_TABLE, $sql_ary);
					}
				}
	
				add_log('admin', 'LOG_RESYNC_POST_MARKING');
			break;
	}
}
?>
Wat ik nog moet doen is de HTML goed doen, met template bestanden. Maar ik vraag me tegelijkertijd af, moet ik het als simpel bestand doen of echt inbouwen in het beheerderspaneel?

Iemand die me kan helpen met HTML of over deze vraag tips kan geven is welkom :)
Laatst gewijzigd door Salomon op 27 dec 2007, 20:53, 5 keer totaal gewijzigd.

lifeguard
Berichten: 2861
Lid geworden op: 05 jul 2005, 08:20
Locatie: Dakloos
Contacteer:

Re: [DEV] Assign multiple posts to another user

Bericht door lifeguard » 27 dec 2007, 13:03

Is di een MOD die je wel af gaat maken? :mrgreen:
Ben wel geinteresserd als die klaar is.
Doenwenu.nl Een site over van alles ... zeg maar

Salomon
Berichten: 3878
Lid geworden op: 14 feb 2006, 16:15

Re: [DEV] Assign multiple posts to another user

Bericht door Salomon » 27 dec 2007, 14:10

Jep, deze ga ik wel afmaken.

Ik heb het net getest met dit script, het werkt :)

Gebruikersavatar
Paul
Beheerder
Beheerder
Berichten: 20298
Lid geworden op: 23 okt 2003, 11:38
Locatie: Utrecht
Contacteer:

Re: [BETA] Assign multiple posts to another user

Bericht door Paul » 27 dec 2007, 17:18

Er zit XSS in je MOD. Verder vergeet je $user->setup aan te roepen, en zijn deze querys niet echt goed geschreven.
Ook betwijfel ik of je hiermee niet de database beschadigt mbt forum <--> topics data relaties.

Salomon
Berichten: 3878
Lid geworden op: 14 feb 2006, 16:15

Re: [BETA] Assign multiple posts to another user

Bericht door Salomon » 27 dec 2007, 17:26

Wat is de XSS dan? En waar moet de $user->setup, moet dat voor/na $auth->acl($user->data);?

En over die data-topic relaties, ik zal eens kijken hoe het deleten exact gaat, dan kan je daarna ook kijken of ik de query's goed heb omgedraaid.

EDIT: Query toegevoegd, nu draai ik alle querys terug die user_delete doet, $user->setup() toegevoegd en xss weggehaald vermoed ik.

Gebruikersavatar
Paul
Beheerder
Beheerder
Berichten: 20298
Lid geworden op: 23 okt 2003, 11:38
Locatie: Utrecht
Contacteer:

Re: [BETA] Assign multiple posts to another user

Bericht door Paul » 27 dec 2007, 18:11

Er zit nog steeds xss in met <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"> ;).

Salomon
Berichten: 3878
Lid geworden op: 14 feb 2006, 16:15

Re: [BETA] Assign multiple posts to another user

Bericht door Salomon » 27 dec 2007, 18:53

Hoe kan je dat misbruiken dan... Dat snap ik even niet :)

En beter, hoe moet ik het wel doen dan in phpBB3?

Gebruikersavatar
Derky
Berichten: 4466
Lid geworden op: 07 apr 2005, 16:24
Locatie: Nederland
Contacteer:

Re: [BETA] Assign multiple posts to another user

Bericht door Derky » 27 dec 2007, 20:33

Eh gewoon zo :P

Code: Selecteer alles

http://www.site/nl/forum/poststouser.php/%22%3E%3Cscript%3Ealert('salomon_nub')%3C/script%3E%3Cboe

Salomon
Berichten: 3878
Lid geworden op: 14 feb 2006, 16:15

Re: [BETA] Assign multiple posts to another user

Bericht door Salomon » 27 dec 2007, 20:53

Opgelost + weer wat dingetjes toegevoegd :)

Gebruikersavatar
Roofiej0
Berichten: 364
Lid geworden op: 09 sep 2007, 15:01
Locatie: Soest

Re: [BETA] Assign multiple posts to another user

Bericht door Roofiej0 » 27 dec 2007, 21:00

Klinkt super! Als hij helemaal af is test ik hem graag ;)
Ex-Service Teamlid

Plaats reactie