====== The Context ====== * Joomla 1.5.18 * SMF 2.0 * JFusion 1.5.5-000 ====== The Problem ====== Simple Machines Forum (SMF) changed many of its field names in going from version 1 to version 2. This killed the JFusion SMF plugin. ^ smf_settings ^^ | || | //SMF 1.x// | //SMF 2.x// | |additionalGroups|additional_groups| |AIM|aim| |avatar|avatar| |birthdate|birthdate| |buddy_list|buddy_list| |dateRegistered|date_registered| |emailAddress|email_address| |gender|gender| |hideEmail|hide_email| |ICQ|icq| |ID_GROUP|id_group| |ID_MEMBER|id_member| |ID_MSG_LAST_VISIT|id_msg_last_visit| |ID_POST_GROUP|id_post_group| |ID_THEME|id_theme| |instantMessages|instant_messages| |is_activated|is_activated| |karmaBad|karma_bad| |karmaGood|karma_good| |lastLogin|last_login| |lngfile|lngfile| |location|location| |memberIP|member_ip| |memberIP2|member_ip2| |memberName|member_name| |messageLabels|message_labels| |MSN|msn| |notifyAnnouncements|notify_announcements| |notifyOnce|notify_regularity| |notifySendBody|notify_send_body| |notifyTypes|notify_types| |passwd|passwd| |passwordSalt|password_salt| |personalText|personal_text| |pm_email_notify|pm_email_notify| |pm_ignore_list|pm_ignore_list| |posts|posts| |realName|real_name| |secretAnswer|secret_answer| |secretQuestion|secret_question| |showOnline|show_online| |signature|signature| |smileySet|smiley_set| |timeFormat|time_format| |timeOffset|time_offset| |totalTimeLoggedIn|total_time_logged_in| |unreadMessages|unread_messages| |usertitle|usertitle| |validation_code|validation_code| |websiteTitle|website_title| |websiteUrl|website_url| |YIM|yim| | |mod_prefs| | |warning| | |ignore_boards| | |passwd_flood| | |new_pm| | |pm_prefs| | |openid_uri| | |pm_receive_from| ====== Solution: fix users.php ====== If there is a proper plugin for my combination of software, I couldn't find it. I decided to bite the bullet and update the field names myself. It //seems// to be working. * @copyright 2008 JFusion. All rights reserved. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * @link http://www.jfusion.org */ // no direct access defined('_JEXEC') or die('Restricted access'); /** * Load the JFusion framework */ require_once JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_jfusion' . DS . 'models' . DS . 'model.jfusion.php'; require_once JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_jfusion' . DS . 'models' . DS . 'model.abstractuser.php'; require_once JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_jfusion' . DS . 'models' . DS . 'model.jplugin.php'; /** * JFusion User Class for SMF 1.1.x * For detailed descriptions on these functions please check the model.abstractuser.php * * @category JFusion * @package JFusionPlugins * @subpackage SMF1 * @author JFusion Team * @copyright 2008 JFusion. All rights reserved. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * @link http://www.jfusion.org */ class JFusionUser_smf extends JFusionUser { /** * get user * * @param object $userinfo holds the new user data * * @access public * @return object */ function &getUser($userinfo) { //get the identifier list($identifier_type, $identifier) = $this->getUserIdentifier($userinfo, 'a.member_name', 'a.email_address'); // initialise some objects $params = JFusionFactory::getParams($this->getJname()); $db = JFusionFactory::getDatabase($this->getJname()); $query = 'SELECT a.ID_MEMBER as userid, a.member_name as username, a.real_name as name, a.email_address as email, a.passwd as password, a.password_salt as password_salt, a.validation_code as activation, a.is_activated, null as reason, a.last_login as lastvisit, a.ID_GROUP as group_id ' . 'FROM #__members as a ' . 'WHERE ' . $identifier_type . '=' . $db->Quote($identifier); $db->setQuery($query); $result = $db->loadObject(); if ($result) { if ($result->group_id == 0) { $result->group_name = "Default Usergroup"; } else { $query = 'SELECT group_name FROM #__membergroups WHERE ID_GROUP = ' . (int)$result->group_id; $db->setQuery($query); $result->group_name = $db->loadResult(); } //Check to see if they are banned $query = 'SELECT ID_BAN_GROUP, expire_time FROM #__ban_groups WHERE name= ' . $db->quote($result->username); $db->setQuery($query); $expire_time = $db->loadObject(); if ($expire_time) { if ($expire_time->expire_time == '' || $expire_time->expire_time > time()) { $result->block = 1; } else { $result->block = 0; } } else { $result->block = 0; } if ($result->is_activated == 1) { $result->activation = ''; } } return $result; } /** * returns the name of this JFusion plugin * * @return string name of current JFusion plugin */ function getJname() { return 'smf'; } /** * delete user * * @param object $userinfo holds the new user data * * @access public * @return array */ function deleteUser($userinfo) { //setup status array to hold debug info and errors $status = array(); $status['debug'] = array(); $status['error'] = array(); $db = JFusionFactory::getDatabase($this->getJname()); $query = 'DELETE FROM #__members WHERE member_name = ' . $db->quote($userinfo->username); $db->setQuery($query); if (!$db->query()) { $status['error'][] = JText::_('USER_DELETION_ERROR') . ' ' . $db->stderr(); } else { //update the stats $query = 'UPDATE #__settings SET value = value - 1 WHERE variable = \'totalMembers\' '; $db->setQuery($query); if (!$db->query()) { //return the error $status['error'][] = JText::_('USER_DELETION_ERROR') . ' ' . $db->stderr(); return; } $query = 'SELECT MAX(ID_MEMBER) as ID_MEMBER FROM #__members WHERE is_activated = 1'; $db->setQuery($query); $resultID = $db->loadObject(); if (!$resultID) { //return the error $status['error'][] = JText::_('USER_DELETION_ERROR') . $db->stderr(); return; } $query = 'SELECT real_name as name FROM #__members WHERE ID_MEMBER = ' . $db->quote($resultID->ID_MEMBER) . ' LIMIT 1'; $db->setQuery($query); $resultName = $db->loadObject(); if (!$resultName) { //return the error $status['error'][] = JText::_('USER_DELETION_ERROR') . $db->stderr(); return; } $query = 'REPLACE INTO #__settings (variable, value) VALUES (\'latestMember\', ' . $resultID->ID_MEMBER . '), (\'latestRealName\', ' . $db->quote($resultName->name) . ')'; $db->setQuery($query); if (!$db->query()) { //return the error $status['error'][] = JText::_('USER_DELETION_ERROR') . $db->stderr(); return; } $status['error'] = false; $status['debug'][] = JText::_('USER_DELETION') . ' ' . $userinfo->username; } return $status; } /** * destroy session * * @param object $userinfo holds the new user data * @param array $options Status array * * @access public * @return array */ function destroySession($userinfo, $options) { // $status = JFusionJplugin::destroySession($userinfo, $options,$this->getJname()); $params = JFusionFactory::getParams($this->getJname()); setcookie($params->get('cookie_name'), '', 0, $params->get('cookie_path'), $params->get('cookie_domain'), $params->get('secure'), $params->get('httponly')); $status = array(); return $status; } /** * create session * * @param object $userinfo holds the new user data * @param array $options options * * @access public * @return array */ function createSession($userinfo, $options) { //do not create sessions for blocked users if (!empty($userinfo->block) || !empty($userinfo->activation)) { $status = array(); $status['error'] = array(); $status['debug'] = array(); $status['error'][] = JText::_('FUSION_BLOCKED_USER'); return $status; } $status = JFusionJplugin::createSession($userinfo, $options, $this->getJname()); return $status; } /** * filterUsername * * @param string $username holds the new user data * * @access public * @return string */ function filterUsername($username) { //no username filtering implemented yet return $username; } /** * updatePassword * * @param object $userinfo holds the new user data * @param object &$existinguser holds the exsisting user data * @param array &$status Status array * * @access public * @return void */ function updatePassword($userinfo, &$existinguser, &$status) { $existinguser->password = sha1(strtolower($userinfo->username) . $userinfo->password_clear); $existinguser->password_salt = substr(md5(rand()), 0, 4); $db = JFusionFactory::getDatabase($this->getJname()); $query = 'UPDATE #__members SET passwd = ' . $db->quote($existinguser->password) . ', password_salt = ' . $db->quote($existinguser->password_salt) . ' WHERE ID_MEMBER = ' . (int)$existinguser->userid; $db = JFusionFactory::getDatabase($this->getJname()); $db->setQuery($query); if (!$db->query()) { $status['error'][] = JText::_('PASSWORD_UPDATE_ERROR') . $db->stderr(); } else { $status['debug'][] = JText::_('PASSWORD_UPDATE') . ' ' . substr($existinguser->password, 0, 6) . '********'; } } /** * updateUsername * * @param object $userinfo holds the new user data * @param object &$existinguser holds the exsisting user data * @param array &$status Status array * * @access public * @return void */ function updateUsername($userinfo, &$existinguser, &$status) { } /** * updateEmail * * @param object $userinfo holds the new user data * @param object &$existinguser holds the exsisting user data * @param array &$status Status array * * @access public * @return void */ function updateEmail($userinfo, &$existinguser, &$status) { //we need to update the email $db = JFusionFactory::getDatabase($this->getJname()); $query = 'UPDATE #__members SET email_address =' . $db->quote($userinfo->email) . ' WHERE ID_MEMBER =' . (int)$existinguser->userid; $db->setQuery($query); if (!$db->query()) { $status['error'][] = JText::_('EMAIL_UPDATE_ERROR') . $db->stderr(); } else { $status['debug'][] = JText::_('EMAIL_UPDATE') . ': ' . $existinguser->email . ' -> ' . $userinfo->email; } } /** * updateUsergroup * * @param object $userinfo holds the new user data * @param object &$existinguser holds the exsisting user data * @param array &$status Status array * * @access public * @return void */ function updateUsergroup($userinfo, &$existinguser, &$status) { $params = JFusionFactory::getParams($this->getJname()); //get the usergroup and determine if working in advanced or simple mode if (substr($params->get('usergroup'), 0, 2) == 'a:') { //check to see if we have a group_id in the $userinfo, if not return if (!isset($userinfo->group_id)) { $status['error'][] = JText::_('GROUP_UPDATE_ERROR') . ": " . JText::_('ADVANCED_GROUPMODE_MASTER_NOT_HAVE_GROUPID'); return null; } $usergroups = unserialize($params->get('usergroup')); if (isset($usergroups[$userinfo->group_id])) { $db = JFusionFactory::getDatabase($this->getJname()); $query = 'UPDATE #__members SET ID_GROUP =' . $db->quote($usergroups[$userinfo->group_id]) . ' WHERE ID_MEMBER =' . (int)$existinguser->userid; $db->setQuery($query); if (!$db->query()) { $status['error'][] = JText::_('GROUP_UPDATE_ERROR') . $db->stderr(); } else { $status['debug'][] = JText::_('GROUP_UPDATE') . ': ' . $existinguser->group_id . ' -> ' . $usergroups[$userinfo->group_id]; } } } else { $status['error'][] = JText::_('GROUP_UPDATE_ERROR'); } } /** * blockUser * * @param object $userinfo holds the new user data * @param object &$existinguser holds the exsisting user data * @param array &$status Status array * * @access public * @return void */ function blockUser($userinfo, &$existinguser, &$status) { $db = JFusionFactory::getDatabase($this->getJname()); $ban = new stdClass; $ban->ID_BAN_GROUP = null; $ban->name = $existinguser->username; $ban->ban_time = time(); $ban->expire_time = null; $ban->cannot_access = 1; $ban->cannot_register = 0; $ban->cannot_post = 0; $ban->cannot_login = 0; $ban->reason = 'You have been banned from this software. Please contact your site admin for more details'; //now append the new user data if (!$db->insertObject('#__ban_groups', $ban, 'ID_BAN_GROUP')) { $status['error'][] = JText::_('BLOCK_UPDATE_ERROR') . $db->stderr(); } $ban_item = new stdClass; $ban_item->ID_BAN_GROUP = $ban->ID_BAN_GROUP; $ban_item->ID_MEMBER = $existinguser->userid; if (!$db->insertObject('#__ban_items', $ban_item, 'ID_BAN')) { $status['error'][] = JText::_('BLOCK_UPDATE_ERROR') . $db->stderr(); } else { $status['debug'][] = JText::_('BLOCK_UPDATE') . ': ' . $existinguser->block . ' -> ' . $userinfo->block; } } /** * unblock user * * @param object $userinfo holds the new user data * @param object &$existinguser holds the exsisting user data * @param array &$status Status array * * @access public * @return void */ function unblockUser($userinfo, &$existinguser, &$status) { $db = JFusionFactory::getDatabase($this->getJname()); $query = 'DELETE FROM #__ban_groups WHERE name = ' . $db->quote($existinguser->username); $db->setQuery($query); if (!$db->query()) { $status['error'][] = JText::_('BLOCK_UPDATE_ERROR') . $db->stderr(); } $query = 'DELETE FROM #__ban_items WHERE ID_MEMBER = ' . (int)$existinguser->userid; $db->setQuery($query); if (!$db->query()) { $status['error'][] = JText::_('BLOCK_UPDATE_ERROR') . $db->stderr(); } else { $status['debug'][] = JText::_('BLOCK_UPDATE') . ': ' . $existinguser->block . ' -> ' . $userinfo->block; } } /** * activate user * * @param object $userinfo holds the new user data * @param object &$existinguser holds the exsisting user data * @param array &$status Status array * * @access public * @return void */ function activateUser($userinfo, &$existinguser, &$status) { $db = JFusionFactory::getDatabase($this->getJname()); $query = 'UPDATE #__members SET is_activated = 1, validation_code = \'\' WHERE ID_MEMBER = ' . (int)$existinguser->userid; $db->setQuery($query); if (!$db->query()) { $status['error'][] = JText::_('ACTIVATION_UPDATE_ERROR') . $db->stderr(); } else { $status['debug'][] = JText::_('ACTIVATION_UPDATE') . ': ' . $existinguser->activation . ' -> ' . $userinfo->activation; } } /** * deactivate user * * @param object $userinfo holds the new user data * @param object &$existinguser holds the exsisting user data * @param array &$status Status array * * @access public * @return void */ function inactivateUser($userinfo, &$existinguser, &$status) { $db = JFusionFactory::getDatabase($this->getJname()); $query = 'UPDATE #__members SET is_activated = 0, validation_code = ' . $db->Quote($userinfo->activation) . ' WHERE ID_MEMBER = ' . (int)$existinguser->userid; $db->setQuery($query); if (!$db->query()) { $status['error'][] = JText::_('ACTIVATION_UPDATE_ERROR') . $db->stderr(); } else { $status['debug'][] = JText::_('ACTIVATION_UPDATE') . ': ' . $existinguser->activation . ' -> ' . $userinfo->activation; } } /** * Creates a new user * * @param object $userinfo holds the new user data * @param array &$status Status array * * @access public * @return mixed null on fail or array with status */ function createUser($userinfo, &$status) { //we need to create a new SMF user $db = JFusionFactory::getDatabase($this->getJname()); $params = JFusionFactory::getParams($this->getJname()); $source_path = $params->get('source_path'); //get the default user group and determine if we are using simple or advanced $usergroups = (substr($params->get('usergroup'), 0, 2) == 'a:') ? unserialize($params->get('usergroup')) : $params->get('usergroup', 18); //check to make sure that if using the advanced group mode, $userinfo->group_id exists if (is_array($usergroups) && !isset($userinfo->group_id)) { $status['error'][] = JText::_('GROUP_UPDATE_ERROR') . ": " . JText::_('ADVANCED_GROUPMODE_MASTER_NOT_HAVE_GROUPID'); return null; } //prepare the user variables $user = new stdClass; $user->ID_MEMBER = null; $user->member_name = $userinfo->username; $user->real_name = $userinfo->name; $user->email_address = $userinfo->email; if (isset($userinfo->password_clear)) { $user->passwd = sha1(strtolower($userinfo->username) . $userinfo->password_clear); $user->password_salt = substr(md5(rand()), 0, 4); } else { $user->passwd = $userinfo->password; if (!isset($userinfo->password_salt)) { $user->password_salt = substr(md5(rand()), 0, 4); } else { $user->password_salt = $userinfo->password_salt; } } $user->posts = 0; $user->date_registered = time(); if ($userinfo->activation) { $user->is_activated = 0; $user->validation_code = $userinfo->activation; } else { $user->is_activated = 1; $user->validation_code = ''; } $user->personal_text = ''; $user->pm_email_notify = 1; $user->hide_email = 1; $user->ID_THEME = 0; $user->ID_GROUP = (is_array($usergroups)) ? $usergroups[$userinfo->group_id] : $usergroups; $user->ID_POST_GROUP = $params->get('userpostgroup', 4); //now append the new user data if (!$db->insertObject('#__members', $user, 'ID_MEMBER')) { //return the error $status['error'] = JText::_('USER_CREATION_ERROR') . ': ' . $db->stderr(); return $status; } else { //update the stats $query = 'UPDATE #__settings SET value = value + 1 WHERE variable = \'totalMembers\' '; $db->setQuery($query); if (!$db->query()) { //return the error $status['error'][] = JText::_('USER_CREATION_ERROR') . $db->stderr(); return; } $date = strftime('%Y-%m-%d'); $query = 'UPDATE #__log_activity SET registers = registers + 1 WHERE date = \'' . $date . '\''; $db->setQuery($query); if (!$db->query()) { //return the error $status['error'][] = JText::_('USER_CREATION_ERROR') . $db->stderr(); return; } $query = 'REPLACE INTO #__settings (variable, value) VALUES (\'latestMember\', ' . $user->ID_MEMBER . '), (\'latestRealName\', ' . $db->quote($userinfo->name) . ')'; $db->setQuery($query); if (!$db->query()) { //return the error $status['error'][] = JText::_('USER_CREATION_ERROR') . $db->stderr(); return; } //return the good news $status['debug'][] = JText::_('USER_CREATION'); $status['userinfo'] = $this->getUser($userinfo); return $status; } } /** * Keep alive function called by system plugin to keep session alive * * @access public * @return boolean False on Falior */ function keepAlive() { //retrieve the smf cookie name $params = & JFusionFactory::getParams($this->getJname()); $cookie_name = $params->get('cookie_name'); $cookie_value = isset($_COOKIE[$cookie_name]) ? $_COOKE[$cookie_name] : ''; $JUser = & JFactory::getUser(); if (!$JUser->get('guest', true)) { //JError::raiseNotice(0, 'joomla logged in'); //user logged into Joomla so let's check for an active SMF session if (empty($cookie_value)) { //JError::raiseNotice(0, 'smf logged out:' . $cookie_name . ','.$cookie_value); //no SMF session present. //Since we can not recreate it due to license issues, logout from joomla instead $mainframe = & JFactory::getApplication('site'); $mainframe->logout(); $session = & JFactory::getSession(); $session->close(); return 1; } else { //JError::raiseNotice(0, 'smf logged in:' . $cookie_name . ','.$cookie_value); } } else { //JError::raiseNotice(0, 'joomla logged out'); if (!empty($cookie_value)) { //JError::raiseNotice(0, 'smf logged in:' . $cookie_name . ','.$cookie_value); //the user is not logged into Joomla and we have an active SMF session //destroy the SMF session $params = JFusionFactory::getParams($this->getJname()); setcookie($params->get('cookie_name'), '', 0, $params->get('cookie_path'), $params->get('cookie_domain'), $params->get('secure'), $params->get('httponly')); return 1; } else { //JError::raiseNotice(0, 'smf logged out:' . $cookie_name . ','.$cookie_value); } } } } ===== Results ===== * Usersync works * Login checker passes all tests * Logout checker passes all tests Those are the only features I'm using at present. There are other fields in public.php that almost certainly need fixing. ====== Solution: Fix forum.php ====== * @copyright 2008 JFusion. All rights reserved. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * @link http://www.jfusion.org */ // no direct access defined('_JEXEC') or die('Restricted access'); /** * JFusion Forum Class for SMF 1.1.x * For detailed descriptions on these functions please check the model.abstractforum.php * * @category JFusion * @package JFusionPlugins * @subpackage SMF1 * @author JFusion Team * @copyright 2008 JFusion. All rights reserved. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * @link http://www.jfusion.org */ class JFusionForum_smf extends JFusionForum { /** * returns the name of this JFusion plugin * * @return string name of current JFusion plugin */ function getJname() { return 'smf'; } /** * Get profile url * * @param int $threadid thread id * * @return string url */ function getThreadURL($threadid) { return 'index.php?topic=' . $threadid; } /** * Get profile url * * @param int $threadid thread id * @param int $postid post id * * @return string url */ function getPostURL($threadid, $postid) { return 'index.php?topic=' . $threadid . '.msg' . $postid . '#msg' . $postid; } /** * Get profile url * * @param int $uid user id * * @return string url */ function getProfileURL($uid) { return 'index.php?action=profile&u=' . $uid; } /** * Get pm message url * * @return string url */ function getPrivateMessageURL() { return 'index.php?action=pm'; } /** * Get new message url * * @return string url */ function getViewNewMessagesURL() { return 'index.php?action=unread'; } /** * Get activity queary * * @param string $usedforums sting coma seperated with board id's * @param string $result_order how to order * @param string $result_limit limit * * @return object */ function getActivityQuery($usedforums, $result_order, $result_limit) { $where = (!empty($usedforums)) ? ' WHERE a.ID_BOARD IN (' . $usedforums . ')' : ''; $end = $result_order . " LIMIT 0," . $result_limit; $query = array( //LAT with first post info LAT . '0' => "SELECT a.ID_TOPIC AS threadid, a.ID_LAST_MSG AS postid, b.poster_name AS username, b.ID_MEMBER AS userid, b.subject AS subject, b.poster_time AS dateline FROM `#__topics` as a INNER JOIN `#__messages` as b ON a.ID_FIRST_MSG = b.ID_MSG INNER JOIN `#__messages` AS c ON a.ID_LAST_MSG = c.ID_MSG $where ORDER BY c.poster_time $end", //LAT with latest post info LAT . '1' => "SELECT a.ID_TOPIC AS threadid, a.ID_LAST_MSG AS postid, c.poster_name AS username, c.ID_MEMBER AS userid, b.subject AS subject, c.poster_time AS dateline FROM `#__topics` as a INNER JOIN `#__messages` as b ON a.ID_FIRST_MSG = b.ID_MSG INNER JOIN `#__messages` AS c ON a.ID_LAST_MSG = c.ID_MSG $where ORDER BY c.poster_time $end", LCT => "SELECT a.ID_TOPIC AS threadid, b.ID_MSG AS postid, b.poster_name AS username, b.ID_MEMBER AS userid, b.subject AS subject, b.body, b.poster_time AS dateline FROM `#__topics` as a INNER JOIN `#__messages` as b ON a.ID_FIRST_MSG = b.ID_MSG $where ORDER BY b.poster_time $end", LCP => "SELECT ID_TOPIC AS threadid, ID_MSG AS postid, poster_name AS username, ID_MEMBER AS userid, subject AS subject, body, poster_time AS dateline FROM `#__messages` " . str_replace('a.ID_BOARD', 'id_board', $where) . " ORDER BY poster_time $end"); return $query; } /** * Filter forums from a set of results sent in / useful if the plugin needs to restrict the forums visible to a user * * @param array $results set of results from query * @param int $limit limit results parameter as set in the module's params; used for plugins that cannot limit using a query limiter */ function filterActivityResults(&$results, $limit=0) { $db =& JFusionFactory::getDatabase($this->getJname()); $query = "SELECT value FROM #__settings WHERE variable='censor_vulgar'"; $db->setQuery($query); $vulgar = $db->loadResult(); $db =& JFusionFactory::getDatabase($this->getJname()); $query = "SELECT value FROM #__settings WHERE variable='censor_proper'"; $db->setQuery($query); $proper = $db->loadResult(); $vulgar = explode ( ',' , $vulgar ); $proper = explode ( ',' , $proper ); foreach($results as $rkey => $result) { foreach( $vulgar as $key => $value ) { $results[$rkey]->subject = preg_replace ( '#\b'.$value.'\b#is' , $proper[$key] , $result->subject ); $results[$rkey]->body = preg_replace ( '#\b'.$value.'\b#is' , $proper[$key] , $result->body ); } } } /** * Get gorum list * * @return object */ function getForumList() { // initialise some objects $db = JFusionFactory::getDatabase($this->getJname()); $query = 'SELECT id_board as id, name FROM #__boards'; $db->setQuery($query); //getting the results return $db->loadObjectList(); } /** * Get avatar * * @param int $userid user id * * @return array number of unread and total messages */ function getPrivateMessageCounts($userid) { if ($userid) { // initialise some objects $db = JFusionFactory::getDatabase($this->getJname()); // read unread count $db->setQuery('SELECT unread_messages FROM #__members WHERE ID_MEMBER = ' . $userid); $unreadCount = $db->loadResult(); // read total pm count $db->setQuery('SELECT instant_messages FROM #__members WHERE ID_MEMBER = ' . $userid); $totalCount = $db->loadResult(); return array('unread' => $unreadCount, 'total' => $totalCount); } return array('unread' => 0, 'total' => 0); } /** * Get avatar * * @param int $puser_id user id * * @return string url of avatar */ function getAvatar($puser_id) { if ($puser_id) { // Get SMF Params and get an instance of the database $params = JFusionFactory::getParams($this->getJname()); $db = JFusionFactory::getDatabase($this->getJname()); // Load member params from database "mainly to get the avatar" $db->setQuery('SELECT * FROM #__members WHERE ID_MEMBER=' . $puser_id); $db->query(); $result = $db->loadObject(); if (!empty($result)) { $url = ''; // SMF has a wierd way of holding attachments. Get instance of the attachments table $db->setQuery('SELECT * FROM #__attachments WHERE id_member=' . $puser_id); $db->query(); $attachment = $db->loadObject(); // See if the user has a specific attachment ment for an avatar if (!empty($attachment) && $attachment->ID_THUMB == 0 && $attachment->ID_MSG == 0 && empty($result->avatar)) { $url = $params->get('source_url') . 'index.php?action=dlattach;attach=' . $attachment->ID_ATTACH . ';type=avatar'; // If user didnt, check to see if the avatar specified in the first query is a url. If so use it. } else if (preg_match("/http(s?):\/\//", $result->avatar)) { $url = $result->avatar; } else if ($result->avatar) { // If the avatar specified in the first query is not a url but is a file name. Make it one $db->setQuery('SELECT * FROM #__settings WHERE variable = "avatar_url"'); $avatarurl = $db->loadObject(); // Check for trailing slash. If there is one DONT ADD ONE! if (substr($avatarurl->value, -1) == DS) { $url = $avatarurl->value . $result->avatar; // I like redundancy. Recheck to see if there isnt a trailing slash. If there isnt one, add one. } else if (substr($avatarurl->value, -1) !== DS) { $url = $avatarurl->value . "/" . $result->avatar; } } return $url; } } } /** * Creates new thread and posts first post * * @param object &$dbparams with discussion bot parameters * @param object &$contentitem object containing content information * @param int $forumid Id of forum to create thread * @param array &$status contains errors and status of actions * * @return void */ function createThread(&$dbparams, &$contentitem, $forumid, &$status) { //setup some variables $userid = $this->getThreadAuthor($dbparams, $contentitem); $firstPost = $dbparams->get("first_post"); $jdb = & JFusionFactory::getDatabase($this->getJname()); $subject = trim(strip_tags($contentitem->title)); //set what should be posted as the first post if ($firstPost == "articleLink") { //create link $forumText = $dbparams->get("first_post_link_text"); if ($dbparams->get("first_post_link_type") == 'image') { $forumText = ""; } $text = $this->prepareText(JFusionFunction::createJoomlaArticleURL($contentitem, $forumText)); } elseif ($firstPost == "articleIntro") { //prepare the text for posting $text = $this->prepareText($contentitem->introtext . "

"); //create link $forumText = $dbparams->get("first_post_link_text"); if ($dbparams->get("first_post_link_type") == 'image') { $forumText = ""; } $text.= $this->prepareText(JFusionFunction::createJoomlaArticleURL($contentitem, $forumText)); } else { //prepare the text for posting $text = $this->prepareText($contentitem->introtext . $contentitem->fulltext); } //the user information $query = "SELECT member_name, email_address FROM #__members WHERE ID_MEMBER = '$userid'"; $jdb->setQuery($query); $smfUser = $jdb->loadObject(); $timestamp = $dbparams->get('use_content_created_date', false) ? JFactory::getDate($contentitem->created)->toUnix() : JFactory::getDate()->toUnix(); $topic_row = new stdClass(); $topic_row->isSticky = 0; $topic_row->id_board = $forumid; $topic_row->ID_FIRST_MSG = $topic_row->ID_LAST_MSG = 0; $topic_row->ID_MEMBER_STARTED = $topic_row->ID_MEMBER_UPDATED = $userid; $topic_row->ID_POLL = 0; $topic_row->numReplies = 0; $topic_row->numViews = 0; $topic_row->locked = 0; if (!$jdb->insertObject('#__topics', $topic_row, 'ID_TOPIC')) { $status['error'] = $jdb->stderr(); return; } $topicid = $jdb->insertid(); $post_row = new stdClass(); $post_row->ID_BOARD = $forumid; $post_row->ID_TOPIC = $topicid; $post_row->poster_time = $timestamp; $post_row->ID_MEMBER = $userid; $post_row->subject = $subject; $post_row->poster_name = $smfUser->member_name; $post_row->posterEmail = $smfUser->email_address; $post_row->posterIP = $_SERVER["REMOTE_ADDR"]; $post_row->smileysEnabled = 1; $post_row->modifiedTime = 0; $post_row->modifiedName = ''; $post_row->body = $text; $post_row->icon = 'xx'; if (!$jdb->insertObject('#__messages', $post_row, 'ID_MSG')) { $status['error'] = $jdb->stderr(); return; } $postid = $jdb->insertid(); $post_row = new stdClass(); $post_row->ID_MSG = $postid; $post_row->ID_MSG_MODIFIED = $postid; if (!$jdb->updateObject('#__messages', $post_row, 'ID_MSG')) { $status['error'] = $jdb->stderr(); } $topic_row = new stdClass(); $topic_row->ID_FIRST_MSG = $postid; $topic_row->ID_LAST_MSG = $postid; $topic_row->ID_TOPIC = $topicid; if (!$jdb->updateObject('#__topics', $topic_row, 'ID_TOPIC')) { $status['error'] = $jdb->stderr(); } $forum_stats = new stdClass(); $forum_stats->id_board = $forumid; $query = "SELECT m.poster_time FROM #__messages AS m INNER JOIN #__boards AS b ON b.ID_LAST_MSG = m.ID_MSG WHERE b.ID_BOARD = $forumid"; $jdb->setQuery($query); $lastPostTime = (int)$jdb->loadResult(); if ($dbparams->get('use_content_created_date', false)) { //only update the last post for the board if it really is newer $updateLastPost = ($timestamp > $lastPostTime) ? true : false; } else { $updateLastPost = true; } if ($updateLastPost) { $forum_stats->ID_LAST_MSG = $postid; $forum_stats->ID_MSG_UPDATED = $postid; } $query = "SELECT numTopics, numPosts FROM #__boards WHERE ID_BOARD = $forumid"; $jdb->setQuery($query); $num = $jdb->loadObject(); $forum_stats->numPosts = $num->numPosts + 1; $forum_stats->numTopics = $num->numTopics + 1; if (!$jdb->updateObject('#__boards', $forum_stats, 'ID_BOARD')) { $status['error'] = $jdb->stderr(); } $query = "INSERT INTO #__log_topics SET ID_MEMBER = $userid, ID_TOPIC = $topicid, ID_MSG = $postid"; $jdb->setQuery($query); if (!$jdb->query()) { $status['error'] = $jdb->stderr(); } if (!empty($topicid) && !empty($postid)) { //save the threadid to the lookup table JFusionFunction::updateForumLookup($contentitem->id, $forumid, $topicid, $postid, $this->getJname()); } } /** * Updates information in a specific thread/post * * @param object &$dbparams with discussion bot parameters * @param object &$existingthread with existing thread info * @param object &$contentitem object containing content information * @param array &$status contains errors and status of actions * * @return void */ function updateThread(&$dbparams, &$existingthread, &$contentitem, &$status) { $threadid = & $existingthread->threadid; $forumid = & $existingthread->forumid; $postid = & $existingthread->postid; //setup some variables $firstPost = $dbparams->get("first_post"); $jdb = & JFusionFactory::getDatabase($this->getJname()); $subject = trim(strip_tags($contentitem->title)); //set what should be posted as the first post if ($firstPost == "articleLink") { //create link $forumText = $dbparams->get("first_post_link_text"); if ($dbparams->get("first_post_link_type") == 'image') { $forumText = ""; } $text = $this->prepareText(JFusionFunction::createJoomlaArticleURL($contentitem, $forumText)); } elseif ($firstPost == "articleIntro") { //prepare the text for posting $text = $this->prepareText($contentitem->introtext . "

"); //create link $forumText = $dbparams->get("first_post_link_text"); if ($dbparams->get("first_post_link_type") == 'image') { $forumText = ""; } $text.= $this->prepareText(JFusionFunction::createJoomlaArticleURL($contentitem, $forumText)); } else { //prepare the text for posting $text = $this->prepareText($contentitem->introtext . $contentitem->fulltext); } $timestamp = JFactory::getDate()->toUnix(); $userid = $dbparams->get('default_user'); $query = "SELECT member_name FROM #__members WHERE ID_MEMBER = '$userid'"; $jdb->setQuery($query); $smfUser = $jdb->loadObject(); $post_row = new stdClass(); $post_row->subject = $subject; $post_row->body = $text; $post_row->modifiedTime = $timestamp; $post_row->modifiedName = $smfUser->member_name; $post_row->ID_MSG_MODIFIED = $postid; $post_row->ID_MSG = $postid; if (!$jdb->updateObject('#__messages', $post_row, 'ID_MSG')) { $status['error'] = $jdb->stderr(); } else { //update the lookup table JFusionFunction::updateForumLookup($contentitem->id, $forumid, $threadid, $postid, $this->getJname()); } } /** * Returns HTML of a quick reply * * @param object &$dbparams with discussion bot parameters * @param boolean $showGuestInputs toggles whether to show guest inputs or not * * @return string of html */ function createQuickReply(&$dbparams, $showGuestInputs) { $html = ''; if ($showGuestInputs) { $username = JRequest::getVar('guest_username', '', 'post'); $email = JRequest::getVar('guest_email', '', 'post'); $html.= ""; $html.= ""; $html.= $this->createCaptcha($dbparams); $html.= "
" . JText::_('USERNAME') . ":
" . JText::_('EMAIL') . "

"; } $quickReply = JRequest::getVar('quickReply', '', 'post'); $html.= "
"; $html.= "
"; return $html; } /** * Creates a post from the quick reply * * @param object &$dbparams with discussion bot parameters * @param object &$ids stdClass with thread id ($ids->threadid) and first post id ($ids->postid) * @param object &$contentitem object of content item * @param object &$userinfo object info of the forum user * * @return array with status */ function createPost(&$dbparams, &$ids, &$contentitem, &$userinfo) { $status = array(); $status["error"] = false; if ($userinfo->guest) { $userinfo->username = JRequest::getVar('guest_username', '', 'POST'); $userinfo->email = JRequest::getVar('guest_email', '', 'POST'); $userinfo->userid = 0; $pattern = "^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"; if (empty($userinfo->username) || empty($userinfo->email) || !eregi($pattern, $userinfo->email)) { $status['error'][] = JTEXT::_('GUEST_FIELDS_MISSING'); return $status; } else { $db = & JFusionFactory::getDatabase($this->getJname()); $query = "SELECT COUNT(*) FROM #__members " . " WHERE member_name = " . $db->Quote($userinfo->username) . " OR member_name = " . $db->Quote($userinfo->email) . " OR realName = " . $db->Quote($userinfo->username) . " OR realName = " . $db->Quote($userinfo->email) . " OR LOWER(email_address) = " . strtolower($db->Quote($userinfo->username)) . " OR LOWER(email_address) = " . strtolower($db->Quote($userinfo->email)); $db->setQuery($query); $result = $db->loadResult(); if (!empty($result)) { $status["error"][] = JText::_('USERNAME_IN_USE'); return $status; } } } //setup some variables $userid = $userinfo->userid; $jdb = & JFusionFactory::getDatabase($this->getJname()); $text = JRequest::getVar('quickReply', false, 'POST'); if (!empty($text)) { $text = $this->prepareText($text); //get some topic information $where = "WHERE t.ID_TOPIC = {$ids->threadid} AND m.ID_MSG = t.ID_FIRST_MSG"; $query = "SELECT t.ID_FIRST_MSG , t.numReplies, m.subject FROM `#__messages` as m INNER JOIN `#__topics` as t ON t.ID_TOPIC = m.ID_TOPIC $where"; $jdb->setQuery($query); $topic = $jdb->loadObject(); //the user information if ($userinfo->guest) { $smfUser = new stdClass(); $smfUser->member_name = $userinfo->username; $smfUser->email_address = $userinfo->email; } else { $query = "SELECT member_name,email_address FROM #__members WHERE ID_MEMBER = '$userid'"; $jdb->setQuery($query); $smfUser = $jdb->loadObject(); } $timestamp = JFactory::getDate()->toUnix(); $post_row = new stdClass(); $post_row->ID_BOARD = $ids->forumid; $post_row->ID_TOPIC = $ids->threadid; $post_row->poster_time = $timestamp; $post_row->ID_MEMBER = $userid; $post_row->subject = 'Re: ' . $topic->subject; $post_row->poster_name = $smfUser->memberName; $post_row->posterEmail = $smfUser->emailAddress; $post_row->posterIP = $_SERVER["REMOTE_ADDR"]; $post_row->smileysEnabled = 1; $post_row->modifiedTime = 0; $post_row->modifiedName = ''; $post_row->body = $text; $post_row->icon = 'xx'; if (!$jdb->insertObject('#__messages', $post_row, 'ID_MSG')) { $status['error'] = $jdb->stderr(); return $status; } $postid = $jdb->insertid(); $post_row = new stdClass(); $post_row->ID_MSG = $postid; $post_row->ID_MSG_MODIFIED = $postid; if (!$jdb->updateObject('#__messages', $post_row, 'ID_MSG')) { $status['error'] = $jdb->stderr(); } //store the postid $status['postid'] = $postid; $topic_row = new stdClass(); $topic_row->ID_LAST_MSG = $postid; $topic_row->ID_MEMBER_UPDATED = (int)$userid; $topic_row->numReplies = $topic->numReplies + 1; $topic_row->ID_TOPIC = $ids->threadid; if (!$jdb->updateObject('#__topics', $topic_row, 'ID_TOPIC')) { $status['error'] = $jdb->stderr(); } $forum_stats = new stdClass(); $forum_stats->ID_LAST_MSG = $postid; $forum_stats->ID_MSG_UPDATED = $postid; $query = "SELECT numPosts FROM #__boards WHERE ID_BOARD = {$ids->forumid}"; $jdb->setQuery($query); $num = $jdb->loadObject(); $forum_stats->numPosts = $num->numPosts + 1; $forum_stats->ID_BOARD = $ids->forumid; if (!$jdb->updateObject('#__boards', $forum_stats, 'ID_BOARD')) { $status['error'] = $jdb->stderr(); } } return $status; } /** * Retrieves the posts to be displayed in the content item if enabled * * @param object &$dbparams with discussion bot parameters * @param object &$existingthread info about thread * * @return array or object Returns retrieved posts */ function getPosts(&$dbparams, &$existingthread) { $threadid = & $existingthread->threadid; $postid = & $existingthread->postid; //set the query $sort = $dbparams->get("sort_posts"); $where = "WHERE ID_TOPIC = {$threadid} AND ID_MSG != {$postid}"; $query = "SELECT ID_TOPIC , ID_MSG, poster_name, ID_MEMBER, CASE WHEN ID_MEMBER = 0 THEN 1 ELSE 0 END AS guest, subject, poster_time, body FROM `#__messages` $where ORDER BY poster_time $sort"; $jdb = & JFusionFactory::getDatabase($this->getJname()); if ($dbparams->get('enable_pagination', true)) { $application = JFactory::getApplication(); $limitstart = JRequest::getInt('limitstart', 0); $limit = $application->getUserStateFromRequest('global.list.limit', 'limit', 14, 'int'); $jdb->setQuery($query, $limitstart, $limit); } else { $limit_posts = $dbparams->get('limit_posts'); $query.= empty($limit_posts) || trim($limit_posts) == 0 ? "" : " LIMIT 0,$limit_posts"; $jdb->setQuery($query); } $posts = $jdb->loadObjectList(); return $posts; } /** * get number of replyes * * @param object &$existingthread info about exsisting thread * * @return object */ function getReplyCount(&$existingthread) { $db = & JFusionFactory::getDatabase($this->getJname()); $query = "SELECT numReplies FROM #__topics WHERE ID_TOPIC = {$existingthread->threadid}"; $db->setQuery($query); $result = $db->loadResult(); return $result; } /** * Returns an object of columns used in createPostTable() * Saves from having to repeat the same code over and over for each plugin * For example: * $columns->userid = "userid"; * $columns->username = "username"; * $columns->username_clean = "username_clean"; //if applicable for filtered usernames * $columns->dateline = "dateline"; * $columns->posttext = "pagetext"; * $columns->posttitle = "title"; * $columns->postid = "postid"; * $columns->threadid = "threadid"; * * @return object with column names */ function getDiscussionColumns() { $columns = new stdClass(); $columns->userid = "ID_MEMBER"; $columns->username = "poster_name"; $columns->dateline = "poster_time"; $columns->posttext = "body"; $columns->posttitle = "subject"; $columns->postid = "ID_MSG"; $columns->threadid = "ID_TOPIC"; $columns->guest = "guest"; return $columns; } /** * Prepares text before saving to db or presentint to joomla article * * @param string $text Text to be modified * @param boolean $prepareForJoomla boolean to indicate if the text is to be saved to software's db or presented in joomla article * * @return string Modified text */ function prepareText($text, $prepareForJoomla = false) { static $bbcode; if ($prepareForJoomla === false) { //first thing is to remove all joomla plugins preg_match_all('/\{(.*)\}/U', $text, $matches); //find each thread by the id foreach ($matches[1] AS $plugin) { //replace plugin with nothing $text = str_replace('{' . $plugin . '}', "", $text); } if (!is_array($bbcode)) { $bbcode = array(); //pattens to run in begening $bbcode[0][] = "#]*href=['|\"](ftp://)(.*?)['|\"][^>]*>(.*?)#si"; $bbcode[1][] = "[ftp=$1$2]$3[/ftp]"; //pattens to run in end $bbcode[2][] = '#]*>(.*?)<\/table>#si'; $bbcode[3][] = '[table]$1[/table]'; $bbcode[2][] = '#]*>(.*?)<\/tr>#si'; $bbcode[3][] = '[tr]$1[/tr]'; $bbcode[2][] = '#]*>(.*?)<\/td>#si'; $bbcode[3][] = '[td]$1[/td]'; $bbcode[2][] = '#]*>(.*?)<\/strong>#si'; $bbcode[3][] = '[b]$1[/b]'; $bbcode[2][] = '#<(strike|s)>(.*?)<\/\\1>#sim'; $bbcode[3][] = '[s]$2[/s]'; } $options = array(); $options['bbcode_patterns'] = $bbcode; $text = JFusionFunction::parseCode($text, 'bbcode', $options); } else { //convert smilies so they show up in Joomla as images static $smiley_search, $smiley_replace; if (!is_array($smiley_search)) { $smiley_search = $smiley_replace = array(); $db = & JFusionFactory::getDatabase($this->getJname()); $query = "SELECT value, variable FROM #__settings WHERE variable = 'smileys_url' OR variable = 'smiley_sets_default'"; $db->setQuery($query); $settings = $db->loadObjectList('variable'); $query = "SELECT code, filename FROM #__smileys ORDER BY smileyOrder"; $db->setQuery($query); $smilies = $db->loadObjectList(); if (!empty($smilies)) { foreach ($smilies as $s) { $alt = JFusionFunction::strtoascii($s->code); //$smiley_search[] = "/(?code}",'/') . ")(?![\\w])/"; $smiley_search[] = '/(?<=[>:\?\.\s[\]()*\\\;]|^)(' . preg_quote($s->code, '/') . '|' . preg_quote(htmlspecialchars($s->code, ENT_QUOTES), '/') . ')(?=[^[:alpha:]0-9]|$)/'; $smiley_replace[] = "value}/{$settings['smiley_sets_default']->value}/{$s->filename}' alt='{$alt}' />"; } } } if (!empty($smiley_search)) { $text = preg_replace($smiley_search, $smiley_replace, $text); } //parse bbcode to html $options = array(); $options['parse_smileys'] = false; $text = JFusionFunction::parseCode($text, 'html', $options); } return $text; } /** * get info about a thread * * @param int $threadid thread id * * @return object */ function getThread($threadid) { $db = & JFusionFactory::getDatabase($this->getJname()); $query = "SELECT ID_TOPIC AS threadid, ID_BOARD AS forumid, ID_FIRST_MSG AS postid FROM #__topics WHERE ID_TOPIC = $threadid"; $db->setQuery($query); $results = $db->loadObject(); return $results; } }
===== Result ===== * JFusion "New Forum Posts" plugin working.