<?php
/*
// phpBB3 Post Class
//
// !--------------------------------------------------------
// @class phpbbPoster
// @desc This class can be used to post messages
// on a phpBB3 forum from another application,
// like a blog, mailinglist software, ...
// @author SaWey (info (@) sawey.be)
// @version Version: 1.0 / Revision: 2
// !--------------------------------------------------------
//
// ### HOW TO USE THIS CLASS ###
//
-- First of all, you have to define the $phpbb_root_path variable, relative to the directory of your script
//
// $path_to_phpbb = "../phpBB3/";
//
-- include this class in you script:
//
// include($path_to_phpbb . 'phpbbPoster.php');
## phpBB3 gives you the possibility to use an extension other than 'php', so does this class, just rename phpbbPoster.php to phpbbPoster.extension_you_want
//
-- instantiate the class
//
// $phpbb_poster = new phpbbPoster($phpbb_root_path);
//
-- call the start function
// $phpbb_poster->start();
//
-- Define the following arrays
//
## $topic['type'] = 0; //what type of topic will this be
// //TOPIC TYPES:
// // POST NORMAL = 0
// // POST STICKY = 1
// // POST ANNOUNCE = 2
// // POST GLOBAL = 3
## $topic['id'] = 1; //topic id
## $topic['time_limit'] = 10; //if sticky or announce, you can set a time limit before changing state to regular topic
//
//
//
## $post_options = array(
// 'user_id' => 2, //you can use either user_id or user_name, if both are set, user_id will be used
// 'user_name'=> 'UserName', //you can use either user_id or user_name, if both are set, user_id will be used
// 'subject' => $subject, //the subject of the post
// 'text' => $text, //the text of the post
// 'icon_id' => 0, //icon used for this topic
// 'forum_id' => 1, //the forum_id to post in (0 for global post);
// 'mode' => 'post', //post or reply
// 'topic' => $topic, //has to be an array with at least $topic['type']
// 'bbcode' => true, //set this if you want to enable bbcode
// 'smilies' => true, //set this if you want to enable smilies
// 'urls' => true, //set this if you want to enable urls
// 'signature' => true, //set this if you want to enable signature
// );
//
-- call the post function
//
// $phpbb_poster->post($post_options);
//
-- call the stop function
//
// $phpbb_poster->stop_posting();
//
-- check if there were errors
//
// if(isset($phpbb_poster->error[0]))
// {
// print'<pre>';
// print_r($phpbb_poster->error );
// print'</pre>';
// }
//
// Support for this class can be found on my website: http://www.sawey.be
//
// current flaws: no notifications after post
//
//
//########################################################################################//
//########################################################################################//
*/
$poll = $uid = $bitfield = $options = $config = $db = $phpbb_root_path = $phpEx = '';
class phpbbPoster
{
var $text; //the text to post
var $subject; //subject of the post
var $forum; //forum to create topic in
var $topic; //topic to post in
//var $priv_message = false; //currently not in use
var $user_data; //holds the user data from the db
var $error = array(); //holds the error messages
var $db; //the db connection of phpbb3
var $started = false; //only one time needed to start
function phpbbPoster($root)
{
global $phpbb_root_path, $phpEx;
$phpbb_root_path = $root;
$phpEx = substr(strrchr(__FILE__, '.'), 1);
}
function start($user_id = 0, $user_name = '')
{
if(!$started)
{
global $phpbb_root_path, $phpEx, $config, $db;
//we have to tell phpbb3 that we are working together
define('IN_PHPBB', true);
//include files
require_once($phpbb_root_path . 'config.' . $phpEx);
require_once($phpbb_root_path . 'includes/constants.' . $phpEx);
require_once($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
require_once($phpbb_root_path . 'includes/functions.' . $phpEx);
require_once($phpbb_root_path . 'includes/functions_content.' . $phpEx);
require_once($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx);
require_once($phpbb_root_path . 'includes/acm/acm_' . $acm_type . '.' . $phpEx);
require_once($phpbb_root_path . 'includes/cache.' . $phpEx);
//instantiate db and connect
$this->db = new $sql_db();
$db = $this->db;
$this->db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false);
if($user_id != 0 && user_name != '')
{
//load user details
$this->load_user($user_id, $user_name);
}
$cache = new cache;
$config = $cache->obtain_config();
$started = true;
}
}
function load_user($user_id = 0, $user_name = "")
{
if($user_id != 0)
{
//get user_data by user_id
$sql = 'SELECT *
FROM ' . USERS_TABLE . '
WHERE user_id = ' . $user_id;
$result = $this->db->sql_query($sql);
$this->user_data = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
}
else if($user_name != "")
{
//get user_data by user_name
$sql = 'SELECT *
FROM ' . USERS_TABLE . '
WHERE username_clean = \'' . strtolower($user_name) . "'";
$result = $this->db->sql_query($sql);
$this->user_data = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
}
else
{
//no correct user input, add error
array_push($this->error, "Could not figure out which user to use, please provide user details.");
}
}
function set_subject($subject)
{
global $phpbb_root_path, $phpEx, $poll, $uid, $bitfield, $options;
$temp = utf8_normalize_nfc($subject);
//$this->subject = generate_text_for_storage($temp, &$uid, &$bitfield, &$flags, $allow_bbcode = false, $allow_urls = false, $allow_smilies = false)
generate_text_for_storage(&$temp, &$uid, &$bitfield, &$options, false, false, false);
$this->subject = $temp;
}
function set_text($text, $bbcode, $smilies, $urls)
{
global $phpbb_root_path, $phpEx, $poll, $uid, $bitfield, $options;
$temp = utf8_normalize_nfc($text);
generate_text_for_storage(&$temp, &$uid, &$bitfield, &$options, $bbcode, $urls, $smilies);
$this->text = $temp;
}
function set_forum($forum_id)
{
//check if forum exists if not global
if($forum_id != 0)
{
$sql = 'SELECT forum_id
FROM ' . FORUMS_TABLE . '
WHERE forum_id = ' . $forum_id;
$result = $this->db->sql_query($sql);
$id = $this->db->sql_fetchrow($result);
if(isset($id['forum_id']))
{
//put in var
$this->forum = $forum_id;
return true;
}
else
{
//add error
array_push($this->error, "Forum does not exist.");
return false;
}
}
else
{
//use global post, put in var
$this->forum = $forum_id;
return true;
}
}
function set_topic($topic_id)
{
//put in var
$this->topic = $topic_id;
return true;
}
function stop_posting(){
$this->db->sql_close();
}
function post($post_options)
{
global $phpbb_root_path, $phpEx, $poll, $uid, $bitfield, $options, $config;
//extract option
isset($post_options['user_id']) ? $this->load_user($post_options['user_id']) : $this->load_user(0, $post_options['user_name']);
isset($post_options['icon_id']) ? ($icon_id = $post_options['icon_id']) : ($icon_id = 0);
isset($post_options['bbcode']) ? ($bbcode = 1) : ($bbcode = 0);
isset($post_options['smilies']) ? ($smilies = 1) : ($smilies = 0);
isset($post_options['urls']) ? ($urls = 1) : ($urls = 0);
isset($post_options['signature'])? ($signature = 1) : ($signature = 0);
isset($post_options['subject']) ? $this->set_subject($post_options['subject']) : '';
isset($post_options['text']) ? $this->set_text($post_options['text'], $bbcode, $smilies, $urls) : '';
isset($post_options['forum_id']) ? $this->set_forum($post_options['forum_id']) : '';
isset($post_options['topic']['id']) ? $this->set_topic($post_options['topic']['id']) : '';
$topic = $post_options['topic'];
$mode = $post_options['mode'];
$data['topic_id'] = $topic['id'];
if(is_array($this->user_data) && is_array($topic))
{
$update_message = true;
if ($mode == 'post')
{
$post_mode = 'post';
}
else if ($mode != 'edit')
{
$post_mode = 'reply';
}
// First of all make sure the subject and topic title are having the correct length.
// To achieve this without cutting off between special chars we convert to an array and then count the elements.
$this->subject = truncate_string($this->subject);
// Collect some basic information about which tables and which rows to update/insert
$sql_data = $topic_row = array();
$poster_id = $this->user_data['user_id'];
$current_time = time();
//start transaction
$this->db->sql_transaction('begin');
$sql_data[POSTS_TABLE]['sql'] = array(
'forum_id' => $this->forum, //0 to have gobal post
'poster_id' => (int) $poster_id,
'icon_id' => $icon_id, //have to require this
'poster_ip' => $_SERVER['REMOTE_ADDR'],
'post_time' => $current_time,
'post_approved' => 1,
'enable_bbcode' => $bbcode, //have to require this
'enable_smilies' => $smilies, //have to require this
'enable_magic_url' => $urls, //have to require this
'enable_sig' => $signature, //have to require this
'post_username' => $this->user_data['username'],
'post_subject' => $this->subject,
'post_text' => $this->text,
'post_checksum' => md5($this->text),
'post_attachment' => 0, //no attachments possible yet
'bbcode_bitfield' => $bitfield,
'bbcode_uid' => $uid,
'post_postcount' => 1, //will always increment the posters post-count.
'post_edit_locked' => 0
);
$post_approved = $sql_data[POSTS_TABLE]['sql']['post_approved'];
$topic_row = array();
//topic options
switch ($post_mode)
{
case 'post':
$sql_data[TOPICS_TABLE]['sql'] = array(
'topic_poster' => (int) $poster_id,
'topic_time' => $current_time,
'forum_id' => $this->forum, //0 to have gobal post
'icon_id' => $icon_id, //have to require this
'topic_approved' => 1,
'topic_title' => $this->subject,
'topic_first_poster_name' => $this->user_data['username'],
'topic_first_poster_colour' => $this->user_data['user_colour'],
'topic_type' => $topic['type'], //have to require this, see below what is what
'topic_time_limit' => ($topic['type'] == POST_STICKY || $topic['type'] == POST_ANNOUNCE) ? ($topic['time_limit'] * 86400) : 0, //have to require this
/*
TOPIC TYPES:
POST_NORMAL = 0
POST_STICKY = 1
POST_ANNOUNCE = 2
POST_GLOBAL = 3
*/
'topic_attachment' => 0, //no attachments possible yet
);
/* NO POLL YET
if (isset($poll['poll_options']) && !empty($poll['poll_options']))
{
$sql_data[TOPICS_TABLE]['sql'] = array_merge($sql_data[TOPICS_TABLE]['sql'], array(
'poll_title' => $poll['poll_title'],
'poll_start' => ($poll['poll_start']) ? $poll['poll_start'] : $current_time,
'poll_max_options' => $poll['poll_max_options'],
'poll_length' => ($poll['poll_length'] * 86400),
'poll_vote_change' => $poll['poll_vote_change'])
);
}
*/
$sql_data[USERS_TABLE]['stat'][] = 'user_lastpost_time = ' . $current_time . ', user_posts = user_posts + 1';
if ($topic['type'] != POST_GLOBAL)
{
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1';
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real + 1, forum_topics = forum_topics + 1';
}
break;
case 'reply':
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_replies_real = topic_replies_real + 1, topic_bumped = 0, topic_bumper = 0, topic_replies = topic_replies + 1';
$sql_data[USERS_TABLE]['stat'][] = 'user_lastpost_time = ' . $current_time . ', user_posts = user_posts + 1';
if ($topic['type'] != POST_GLOBAL)
{
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1';
}
break;
}
// Submit new topic
if ($post_mode == 'post')
{
$sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' .
$this->db->sql_build_array('INSERT', $sql_data[TOPICS_TABLE]['sql']);
$this->db->sql_query($sql);
$data['topic_id'] = $this->db->sql_nextid();
$sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
'topic_id' => $data['topic_id'])
);
unset($sql_data[TOPICS_TABLE]['sql']);
}
// Submit new post
if ($post_mode == 'post' || $post_mode == 'reply')
{
if ($post_mode == 'reply')
{
$sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
'topic_id' => $data['topic_id'])
);
}
$sql = 'INSERT INTO ' . POSTS_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_data[POSTS_TABLE]['sql']);
$this->db->sql_query($sql);
$data['post_id'] = $this->db->sql_nextid();
if ($post_mode == 'post')
{
$sql_data[TOPICS_TABLE]['sql'] = array(
'topic_first_post_id' => $data['post_id'],
'topic_last_post_id' => $data['post_id'],
'topic_last_post_time' => $current_time,
'topic_last_poster_id' => (int) $this->user_data['user_id'],
'topic_last_poster_name' => $this->user_data['username'],
'topic_last_poster_colour' => $this->user_data['user_colour'],
);
}
unset($sql_data[POSTS_TABLE]['sql']);
}
// Update the topics table
if (isset($sql_data[TOPICS_TABLE]['sql']))
{
$sql = 'UPDATE ' . TOPICS_TABLE . '
SET ' . $this->db->sql_build_array('UPDATE', $sql_data[TOPICS_TABLE]['sql']) . '
WHERE topic_id = ' . $data['topic_id'];
$this->db->sql_query($sql);
}
// Update the posts table
if (isset($sql_data[POSTS_TABLE]['sql']))
{
$sql = 'UPDATE ' . POSTS_TABLE . '
SET ' . $this->db->sql_build_array('UPDATE', $sql_data[POSTS_TABLE]['sql']) . '
WHERE post_id = ' . $data['post_id'];
$this->db->sql_query($sql);
}
if ($topic['type'] != POST_GLOBAL)
{
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . $data['post_id'];
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $this->db->sql_escape($this->subject) . "'";
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_time = " . (int)$current_time;
$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $this->user_data['user_id'];
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $this->db->sql_escape($this->user_data['username']) . "'";
$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $this->db->sql_escape($this->user_data['user_colour']) . "'";
}
if ($post_mode == 'reply')
{
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_id = ' . (int) $data['post_id'];
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_poster_id = ' . (int) $this->user_data['user_id'];
$sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_name = '" . $this->db->sql_escape($this->user_data['username']) . "'";
$sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_colour = '" . $this->db->sql_escape($this->user_data['user_colour']) . "'";
$sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $this->db->sql_escape($this->subject) . "'";
$sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_time = ' . (int) $current_time;
}
if ($post_mode == 'post')
{
set_config('num_topics', $config['num_topics'] + 1, true);
set_config('num_posts', $config['num_posts'] + 1, true);
}
if ($post_mode == 'reply')
{
set_config('num_posts', $config['num_posts'] + 1, true);
}
// Update forum stats
$where_sql = array(POSTS_TABLE => 'post_id = ' . $data['post_id'], TOPICS_TABLE => 'topic_id = ' . $data['topic_id'], FORUMS_TABLE => 'forum_id = ' . $this->forum, USERS_TABLE => 'user_id = ' . $this->user_data['user_id']);
foreach ($sql_data as $table => $update_ary)
{
if (isset($update_ary['stat']) && implode('', $update_ary['stat']))
{
$sql = "UPDATE $table SET " . implode(', ', $update_ary['stat']) . ' WHERE ' . $where_sql[$table];
$this->db->sql_query($sql);
}
}
// Committing the transaction before updating search index
$this->db->sql_transaction('commit');
// Index message contents
if ($update_message && $data['enable_indexing'])
{
// Select the search method and do some additional checks to ensure it can actually be utilised
$search_type = basename($config['search_type']);
if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
{
trigger_error('NO_SUCH_SEARCH_MODULE');
}
if (!class_exists($search_type))
{
include("{$phpbb_root_path}includes/search/$search_type.$phpEx");
}
$error = false;
$search = new $search_type($error);
if ($error)
{
trigger_error($error);
}
$search->index($mode, $data['post_id'], $data['message'], $this->subject, $poster_id, ($topic['type'] == POST_GLOBAL) ? 0 : $this->forum);
}
}
else
{
//no user defined, add error
array_push($this->error, "No user defined, can not post");
}
}
}
?>