phpBB 2.0.16 to 2.0.17 Code Changes

These are the code changes introduced between phpBB 2.0.16 and phpBB 2.0.17. If you have installed many hacks on a forum, but wish to update it, these may help you. It is often easier to apply code changes such as these instead of replacing and rehacking your current files.

These code changes use the following instruction labels:
filename - The name of a file to be edited. Equivalent to an OPEN action in a hack or modification.
FIND - This indicates lines of code you should locate. Changes will be made in reference to this code.
REPLACE WITH - This code should completely replace the code in the preceding FIND instruction.
AFTER, ADD - The code in this instruction should be added on a new line after the last line of code in the preceding FIND instruction.

Once you have completed the code changes, create an install/ directory in your forum's root directory, and upload the update_to_latest.php file that comes in any phpBB 2.0.17 download to the install/ directory. Run update_to_latest.php by opening it via your web browser, just as you would a normal forum page. Afterward, delete the file and the install/ directory so that your forum is accessible again.

Now, onward to the file changes!

privmsg.php
FIND
Code:
      if ( $delete_all )
      {
         switch($folder)
         {
            case 'inbox':
               $delete_type = "privmsgs_to_userid = " . $userdata['user_id'] . " AND (
               privmsgs_type = " . PRIVMSGS_READ_MAIL . " OR privmsgs_type = " . PRIVMSGS_NEW_MAIL . " OR privmsgs_type = " . PRIVMSGS_UNREAD_MAIL . " )";
               break;

            case 'outbox':
               $delete_type = "privmsgs_from_userid = " . $userdata['user_id'] . " AND ( privmsgs_type = " . PRIVMSGS_NEW_MAIL . " OR privmsgs_type = " . PRIVMSGS_UNREAD_MAIL . " )";
               break;

            case 'sentbox':
               $delete_type = "privmsgs_from_userid = " . $userdata['user_id'] . " AND privmsgs_type = " . PRIVMSGS_SENT_MAIL;
               break;

            case 'savebox':
               $delete_type = "( ( privmsgs_from_userid = " . $userdata['user_id'] . "
                  AND privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . " )
               OR ( privmsgs_to_userid = " . $userdata['user_id'] . "
                  AND privmsgs_type = " . PRIVMSGS_SAVED_IN_MAIL . " ) )";
               break;
         }

         $sql = "SELECT privmsgs_id
            FROM " . PRIVMSGS_TABLE . "
            WHERE $delete_type";
         if ( !($result = $db->sql_query($sql)) )
         {
            message_die(GENERAL_ERROR, 'Could not obtain id list to delete all messages', '', __LINE__, __FILE__, $sql);
         }

         while ( $row = $db->sql_fetchrow($result) )
         {
            $mark_list[] = $row['privmsgs_id'];
         }

         unset($delete_type);
      }

      if ( count($mark_list) )
REPLACE WITH
Code:
      $delete_sql_id = '';

      if (!$delete_all)
      {
         for ($i = 0; $i < count($mark_list); $i++)
         {
            $delete_sql_id .= (($delete_sql_id != '') ? ', ' : '') . intval($mark_list[$i]);
         }
         $delete_sql_id = "AND privmsgs_id IN ($delete_sql_id)";
      }

      switch($folder)
      {
         case 'inbox':
            $delete_type = "privmsgs_to_userid = " . $userdata['user_id'] . " AND (
            privmsgs_type = " . PRIVMSGS_READ_MAIL . " OR privmsgs_type = " . PRIVMSGS_NEW_MAIL . " OR privmsgs_type = " . PRIVMSGS_UNREAD_MAIL . " )";
            break;

         case 'outbox':
            $delete_type = "privmsgs_from_userid = " . $userdata['user_id'] . " AND ( privmsgs_type = " . PRIVMSGS_NEW_MAIL . " OR privmsgs_type = " . PRIVMSGS_UNREAD_MAIL . " )";
            break;

         case 'sentbox':
            $delete_type = "privmsgs_from_userid = " . $userdata['user_id'] . " AND privmsgs_type = " . PRIVMSGS_SENT_MAIL;
            break;

         case 'savebox':
            $delete_type = "( ( privmsgs_from_userid = " . $userdata['user_id'] . "
               AND privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . " )
            OR ( privmsgs_to_userid = " . $userdata['user_id'] . "
               AND privmsgs_type = " . PRIVMSGS_SAVED_IN_MAIL . " ) )";
            break;
      }

      $sql = "SELECT privmsgs_id
         FROM " . PRIVMSGS_TABLE . "
         WHERE $delete_type $delete_sql_id";

      if ( !($result = $db->sql_query($sql)) )
      {
         message_die(GENERAL_ERROR, 'Could not obtain id list to delete messages', '', __LINE__, __FILE__, $sql);
      }

      $mark_list = array();
      while ( $row = $db->sql_fetchrow($result) )
      {
         $mark_list[] = $row['privmsgs_id'];
      }

      unset($delete_type);

      if ( count($mark_list) )
FIND
Code:
            $mode = 'reply';
         }
      }
AFTER, ADD
Code:
      else
      {
         $privmsg_subject = $privmsg_message = '';
      }
FIND
Code:
         $l_box_size_status = '';
         break;
   }
AFTER, ADD
Code:
}
else
{
   $inbox_limit_img_length = $inbox_limit_pct = $l_box_size_status = '';
viewtopic.php
FIND
Code:
   $search_img = '<a href="' . $temp_url . '"><img src="' . $images['icon_search'] . '" alt="' . $lang['Search_user_posts'] . '" title="' . $lang['Search_user_posts'] . '" border="0" /></a>';
   $search = '<a href="' . $temp_url . '">' . $lang['Search_user_posts'] . '</a>';
REPLACE WITH
Code:
   $search_img = '<a href="' . $temp_url . '"><img src="' . $images['icon_search'] . '" alt="' . $lang['Search_user_posts'] . '" title="' . sprintf($lang['Search_user_posts'], $postrow[$i]['username']) . '" border="0" /></a>';
   $search = '<a href="' . $temp_url . '">' . sprintf($lang['Search_user_posts'], $postrow[$i]['username']) . '</a>';
admin/admin_ug_auth.php
FIND
Code:
         FROM " . AUTH_ACCESS_TABLE . " aa, " . USER_GROUP_TABLE . " ug, " . USERS_TABLE . " u 
         WHERE ug.group_id = aa.group_id
            AND u.user_id = ug.user_id
AFTER, ADD
Code:
            AND ug.user_pending = 0
FIND
Code:
   //
   // Front end
   //
   $sql = "SELECT *
      FROM " . FORUMS_TABLE . " f
      ORDER BY forum_order";
REPLACE WITH
Code:
   //
   // Front end
   //
   $sql = "SELECT f.*
      FROM " . FORUMS_TABLE . " f, " . CATEGORIES_TABLE . " c
      WHERE f.cat_id = c.cat_id
      ORDER BY c.cat_order, f.forum_order ASC";
FIND
Code:
   $sql = "SELECT u.user_id, u.username, u.user_level, g.group_id, g.group_name, g.group_single_user FROM " . USERS_TABLE . " u, " . GROUPS_TABLE . " g, " . USER_GROUP_TABLE . " ug WHERE ";
REPLACE WITH
Code:
>   $sql = "SELECT u.user_id, u.username, u.user_level, g.group_id, g.group_name, g.group_single_user, ug.user_pending FROM " . USERS_TABLE . " u, " . GROUPS_TABLE . " g, " . USER_GROUP_TABLE . " ug WHERE ";
FIND
Code:
      $t_usergroup_list = '';
      for($i = 0; $i < count($ug_info); $i++)
      {
         $ug = ( $mode == 'user' ) ? 'group&amp;' . POST_GROUPS_URL : 'user&amp;' . POST_USERS_URL;

         $t_usergroup_list .= ( ( $t_usergroup_list != '' ) ? ', ' : '' ) . '<a href="' . append_sid("admin_ug_auth.$phpEx?mode=$ug=" . $id[$i]) . '">' . $name[$i] . '</a>';
      }
   }
   else
REPLACE WITH
Code:
      $t_usergroup_list = $t_pending_list = '';
      for($i = 0; $i < count($ug_info); $i++)
      {
         $ug = ( $mode == 'user' ) ? 'group&amp;' . POST_GROUPS_URL : 'user&amp;' . POST_USERS_URL;

         if (!$ug_info[$i]['user_pending'])
         {
            $t_usergroup_list .= ( ( $t_usergroup_list != '' ) ? ', ' : '' ) . '<a href="' . append_sid("admin_ug_auth.$phpEx?mode=$ug=" . $id[$i]) . '">' . $name[$i] . '</a>';
         }
         else
         {
            $t_pending_list .= ( ( $t_pending_list != '' ) ? ', ' : '' ) . '<a href="' . append_sid("admin_ug_auth.$phpEx?mode=$ug=" . $id[$i]) . '">' . $name[$i] . '</a>';
         }
      }
   }
   else
FIND
Code:
         'GROUP_MEMBERSHIP' => $lang['Usergroup_members'] . ' : ' . $t_usergroup_list)
REPLACE WITH
Code:
         'GROUP_MEMBERSHIP' => $lang['Usergroup_members'] . ' : ' . $t_usergroup_list . '<br />' . $lang['Pending_members'] . ' : ' . $t_pending_list)
admin/admin_users.php
FIND
Code:
            SET poster_id = " . DELETED . ", post_username = '$username'
REPLACE WITH
Code:
            SET poster_id = " . DELETED . ", post_username = '" . str_replace("\\'", "''", addslashes($this_userdata['username'])) . "'
includes/bbcode.php
FIND
Code:
   $replacements[] = $bbcode_tpl['img'];

   // matches a [url]xxxx://www.phpbb.com[/url] code..
   $patterns[] = "#\[url\]([\w]+?://[^ \"\n\r\t<]*?)\[/url\]#is";
   $replacements[] = $bbcode_tpl['url1'];

   // [url]www.phpbb.com[/url] code.. (no xxxx:// prefix).
   $patterns[] = "#\[url\]((www|ftp)\.[^ \"\n\r\t<]*?)\[/url\]#is";
   $replacements[] = $bbcode_tpl['url2'];

   // [url=xxxx://www.phpbb.com]phpBB[/url] code..
   $patterns[] = "#\[url=([\w]+?://[^ \"\n\r\t<]*?)\]([^?\n\r\t].*?)\[/url\]#is";
   $replacements[] = $bbcode_tpl['url3'];

   // [url=www.phpbb.com]phpBB[/url] code.. (no xxxx:// prefix).
   $patterns[] = "#\[url=((www|ftp)\.[^ \"\n\r\t<]*?)\]([^?\n\r\t].*?)\[/url\]#is";
REPLACE WITH
Code:
   $replacements[] = $bbcode_tpl['img'];

   // matches a [url]xxxx://www.phpbb.com[/url] code..
   $patterns[] = "#\[url\]([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*?)\[/url\]#is";
   $replacements[] = $bbcode_tpl['url1'];

   // [url]www.phpbb.com[/url] code.. (no xxxx:// prefix).
   $patterns[] = "#\[url\]((www|ftp)\.[\w\#$%&~/.\-;:=,?@\[\]+]*?)\[/url\]#is";
   $replacements[] = $bbcode_tpl['url2'];

   // [url=xxxx://www.phpbb.com]phpBB[/url] code..
   $patterns[] = "#\[url=([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*?)\]([^?\n\r\t].*?)\[/url\]#is";
   $replacements[] = $bbcode_tpl['url3'];

   // [url=www.phpbb.com]phpBB[/url] code.. (no xxxx:// prefix).
   $patterns[] = "#\[url=((www|ftp)\.[\w\#$%&~/.\-;:=,?@\[\]+]*?)\]([^?\n\r\t].*?)\[/url\]#is";
FIND
Code:
   $ret = preg_replace("#(^|[\n ])([\w]+?://[^ \"\n\r\t<]*)#is", "\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $ret);

   // matches a "www|ftp.xxxx.yyyy[/zzzz]" kinda lazy URL thing
   // Must contain at least 2 dots. xxxx contains either alphanum, or "-"
   // zzzz is optional.. will contain everything up to the first space, newline,
   // comma, double quote or <.
   $ret = preg_replace("#(^|[\n ])((www|ftp)\.[^ \"\t\n\r<]*)#is", "\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>", $ret);
REPLACE WITH
Code:
   $ret = preg_replace("#(^|[\n ])([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)#is", "\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $ret);

   // matches a "www|ftp.xxxx.yyyy[/zzzz]" kinda lazy URL thing
   // Must contain at least 2 dots. xxxx contains either alphanum, or "-"
   // zzzz is optional.. will contain everything up to the first space, newline,
   // comma, double quote or <.
   $ret = preg_replace("#(^|[\n ])((www|ftp)\.[\w\#$%&~/.\-;:=,?@\[\]+]*)#is",
includes/functions.php
FIND
Code:
   if (intval($user) == 0 || $force_str)
REPLACE WITH
Code:
   if (!is_numeric($user) || $force_str)
FIND
Code:
   define(HAS_DIED, 1);
REPLACE WITH
Code:
   define('HAS_DIED', 1);
includes/functions_validate.php
FIND
Code:
   $username = preg_replace('#\s+#', ' ', $username);
   // Limit username length
   $username = substr(str_replace("\'", "'", $username), 0, 25);
   $username = str_replace("'", "''", $username);

   $sql = "SELECT username
REPLACE WITH
Code:
   // Remove doubled up spaces
   $username = preg_replace('#\s+#', ' ', trim($username));
   $username = phpbb_clean_username($username);
   
   $sql = "SELECT username
includes/usercp_activate.php
FIND
Code:
   else if ((trim($row['user_actkey']) == trim($HTTP_GET_VARS['act_key'])) && (trim($row['user_actkey']) != ''))
   {
AFTER, ADD
Code:
      if (intval($board_config['require_activation']) == USER_ACTIVATION_ADMIN && $userdata['user_level'] != ADMIN)
      {
         message_die(GENERAL_MESSAGE, $lang['Not_Authorised']);
      }
includes/usercp_avatar.ph
FIND
Code:
function user_avatar_url($mode, &$error, &$error_msg, $avatar_filename)
{
AFTER, ADD
Code:
   global $lang;
includes/usercp_viewprofile.php
FIND
Code:
$search_img = '<a href="' . $temp_url . '"><img src="' . $images['icon_search'] . '" alt="' . $lang['Search_user_posts'] . '" title="' . $lang['Search_user_posts'] . '" border="0" /></a>';
$search = '<a href="' . $temp_url . '">' . $lang['Search_user_posts'] . '</a>';
REPLACE WITH
Code:
$search_img = '<a href="' . $temp_url . '"><img src="' . $images['icon_search'] . '" alt="' . $lang['Search_user_posts'] . '" title="' . sprintf($lang['Search_user_posts'], $profiledata['username']) . '" border="0" /></a>';
$search = '<a href="' . $temp_url . '">' . sprintf($lang['Search_user_posts'], $profiledata['username']) . '</a>';
templates/subSilver/faq_body.tpl
FIND
Code:
      <td class="{faq_block.faq_row.ROW_CLASS}" align="left" valign="top"><span class="postbody"><a name="{faq_block.faq_row.U_FAQ_ID}"></a><b>{faq_block.faq_row.FAQ_QUESTION}</b></span><br /><span class="postbody">{faq_block.faq_row.FAQ_ANSWER}<br /><a class="postlink" href="#Top">{L_BACK_TO_TOP}</a></span></td>
REPLACE WITH
Code:
      <td class="{faq_block.faq_row.ROW_CLASS}" align="left" valign="top"><span class="postbody"><a name="{faq_block.faq_row.U_FAQ_ID}"></a><b>{faq_block.faq_row.FAQ_QUESTION}</b></span><br /><span class="postbody">{faq_block.faq_row.FAQ_ANSWER}<br /><a class="postlink" href="#top">{L_BACK_TO_TOP}</a></span></td>