diff options
-rw-r--r-- | src/PhpBB3.php | 139 |
1 files changed, 113 insertions, 26 deletions
diff --git a/src/PhpBB3.php b/src/PhpBB3.php index d8b77b9..6f829a9 100644 --- a/src/PhpBB3.php +++ b/src/PhpBB3.php @@ -7,6 +7,7 @@ define('IN_PHPBB', true); require_once(__DIR__ . '/PhpBB3Conf.php'); $phpEx = substr(strrchr(__FILE__, '.'), 1); require_once($phpbb_root_path . 'common.' . $phpEx); +require_once($phpbb_root_path . 'includes/functions.' . $phpEx); require_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx); require_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); @@ -82,30 +83,16 @@ class PhpBB3 { } } - public function topicExists($topicId) { + public function topicStatus($topicId) { throw_if_null($topicId); global $db; - $sql = 'SELECT 1 FROM ' . TOPICS_TABLE . ' ' . - 'WHERE topic_id = ' . $topicId . ' LIMIT 1'; + $sql = 'SELECT topic_status FROM ' . TOPICS_TABLE . ' ' . + 'WHERE topic_id = ' . $topicId; - $result = $db->sql_query($sql); - - $rows = $db->sql_fetchrowset($result); - $db->sql_freeresult($result); - - switch (count($rows)) { - case 0: - return false; - - case 1: - return true; - - default: - # Should be impossible due to LIMIT 1. - throw new Exception("Too many rows returned: $sql"); - } + $row = $this->get_exactly_one_row($sql); + return $row ? $row['topic_status'] : false; } public function getPostTime($postId) { @@ -137,7 +124,36 @@ class PhpBB3 { public function postMessage($postType, $forumId, $topicId, $msg) { throw_if_null($msg); - if ($postType != 'post' && $postType != 'reply') { + if ($postType == 'post') { + # do nothing + } + else if ($postType == 'reply') { + # Check that we're not replying to a locked topic. + $status = $this->topicStatus($topicId); + if ($status === false) { + throw new Exception('topic does not exist: ' . $topicId); + } + + switch ($this->topicStatus($topicId)) { + case ITEM_UNLOCKED: + # normal, ok + break; + case ITEM_LOCKED: + throw new Exception('post to locked topic: ' . $topicId); + break; + case ITEM_MOVED: + # Should not happen, since the only topics with this status + # are new shadow topics created after moves. + throw new Exception('post to moved topic: ' . $topicId); + break; + default: + # Should not happen. + throw new Exception('bad topic status: ' . $topicId); + break; + } + } + else { + # Should not happen. throw new Exception('bad post type: ' . $postType); } @@ -145,10 +161,6 @@ class PhpBB3 { throw new Exception('forum does not exist: ' . $forumId); } - if ($postType == 'reply' && !$this->topicExists($topicId)) { - throw new Exception('topic does not exist: ' . $topicId); - } - $userId = $this->getUserId($msg->getFrom()); if ($userId === false) { throw new Exception('unrecognized email address: ' . $msg->getFrom()); @@ -160,7 +172,16 @@ class PhpBB3 { } $subject = $msg->getSubject(); - $message = 'foo'; # FIXME: fill in with acutal message contents + list($message, $attachments) = $msg->getFlattenedParts(); + + # handle attachments + $attachment_data = array(); + + foreach ($attachments as $a) { + $attachment_data[] = addAttachment( + $userId, $a['filename'], $a['comment'], $a['mimetype'], $a['data'] + ); + } # bring in the PhpBB globals global $phpEx, $phpbb_root_path, $user, $auth, @@ -183,6 +204,7 @@ class PhpBB3 { $message, $uid, $bitfield, $options, true, true, true ); + # build the data array for submit_post $postId = null; $data = array( @@ -208,9 +230,13 @@ class PhpBB3 { 'notify' => false, 'post_time' => 0, 'forum_name' => '', - 'enable_indexing' => true, + 'enable_indexing' => true ); + if (!empty($attachment_data)) { + $data['attachment_data'] = $attachment_data; + } + $poll = ''; submit_post($postType, $subject, $userName, POST_NORMAL, $poll, $data); @@ -218,6 +244,67 @@ class PhpBB3 { return $postId; } + public function addAttachment($userId, $filename, $comment, + $mimetype, $data) { + throw_if_null($userId); + throw_if_null($filename); + throw_if_null($mimetype); + throw_if_null($data); + +# TODO: check that attachment is a permissible type, size + + # lifted from include/functions_upload.php: filespec::clean_filename() + $realFilename = $userId . '_' . md5(unique_id()); + + # put the attachment data into the db + $sql = 'INSERT INTO ' . ATTACHMENTS_TABLE . ' (' . + 'poster_id, is_orphan, physical_filename, attach_comment, ' . + 'extension, mimetype, filesize, filetime' . + ') VALUES (' . + $userId . ', ' . + '1, ' . + $realFilename . ', ' . + $comment . ', ' . + $mimetype . ', ' . + strlen($data) . ', ' . + time() . + ')'; + + $db->sql_query($sql); + + if ($db->sql_affectedrows() != 1) { + throw new Exception("Adding attachment failed: $sql"); + } + + # write the attachment to disk + $realPath = $phpbb_root_path . $config['upload_path'] . '/' . $realFilename; + $count = file_put_contents($realPath, $data); + if ($count === false) { + throw new Exception('Failed to write attachment file: ' . $realPath); + } + +# FIXME: how to get right uid, gid for file? This surely won't work. +/* + $result = chown($realPath, 'apache'); + if ($result === false) { + throw new Exception('Failed to chown attachment file: ' . $realPath); + } + + chgrp($realPath, 'apache'); + if ($result === false) { + throw new Exception('Failed to chgrp attachment file: ' . $realPath); + } +*/ + + # return the attachment info needed by submit_post + return array( + 'attach_id' => $db->sql_nextid(), + 'is_orphan' => 1, + 'real_filename' => $realFilename, + 'attach_comment' => $comment, + ); + } + protected function get_exactly_one_row($sql) { global $db; |