view Install.xml @ 3:e3c4cd9d4938 1.2-updates

Re #1: Separate branch to hold updates of v1.2 caused by submission to MOD DB
author IBBoard <dev@ibboard.co.uk>
date Sun, 07 Jun 2009 18:14:27 +0000
parents d5536d233ec1
children 6077ff381bf8 31d2daed0532
line wrap: on
line source

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="modx.prosilver.en.xsl"?>
<!--For security purposes, please check: http://www.phpbb.com/mods/ for the
      latest version of this MOD. Although MODs are checked before being
      allowed in the MODs Database there is no guarantee that there are no
      security problems within the MOD. No support will be given for MODs not
      found within the MODs Database which can be found at
      http://www.phpbb.com/mods/-->
<mod xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.phpbb.com/mods/xml/modx-1.2.2.xsd">

	<header>
		<license>http://opensource.org/licenses/gpl-license.php GNU General Public License v2</license>
		<title lang="en-gb">Multi-race rank themes</title>
		<description lang="en-gb">This MOD will allow you to add, modify and remove rank themes.

Rank themes are selectable collections of ranks that users can choose to use, allowing RPG forums to have different 'races' or allowing 'normal' forums to provide an set of alternative icon images for their users.</description>
		<author-notes lang="en-gb"><![CDATA[The following description is taken from digiTsai's phpBB2 'Rank themes' mod (with some minor modifications in the last paragraph), as I couldn't word it any better myself:

Different ranking themes for your forum. Users are allowed to choose a ranking theme to their liking. For example, you can add two ranking themes named "Good" and "Evil" for your forum. The ranking then might look like this:

Posts	| Good   | Evil
Needed	| Ranks  | Ranks
=========================
0       | Knight | Zombie
10      | Priest | Minion
20      | Zealot | Demon
50      | Angel	 | Devil

So if one were to choose the "good" ranking, then he/she will go through the ranks Knight, Priest, Zealot, and finally Angel, but another user might decide to choose the "Evil" theme, he/she will go through the ranks Zombie, Minion, Demon, then Devil.

On install, there are two ranking themes already added, "special" and "default". Ranks classified as special cannot be chosen by the public and will continue to override any rank theme selection, as is the phpBB3 default behaviour. The default ranking theme is the one a newly registered user has.
]]></author-notes>
		<author-group>
			<author>
				<realname>IBBoard</realname>
				<email>phpbb@ibboard.co.uk</email>
				<username>IBBoard</username>
				<homepage>http://www.ibboard.co.uk</homepage>
			</author>
		</author-group>
		<link-group>
			<link type="template" href="subsilver2.xml" lang="en-gb">subsilver2</link>
		</link-group>
		<mod-version>1.2.3</mod-version>
		<installation>
			<level>intermediate</level>
			<time>2700</time>
			<target-version>3.0.4</target-version>
		</installation>
		<history>
			<entry>
				<date>2009-05-10</date>
				<rev-version>1.2.3</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Update to latest MODX format</change>
					<change>Fix: Remove apology from author notes as the formatting of the new MODX styling is no longer broken for author notes</change>
					<change>Fix: Fix closing tag in adm/style/acp_ranks.html template</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-04-29</date>
				<rev-version>1.2.2</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Fix typo in tag name of instructions (no code functionality changes)</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-04-28</date>
				<rev-version>1.2.1</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Fix some code formatting to pass validation (no code functionality changes)</change>
					<change>Fix: Separate out subsilver instructions to templates/subsilver2.xml to pass validation (no code functionality changes)</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-04-12</date>
				<rev-version>1.2.0</rev-version>
				<changelog lang="en-gb">
					<change>Update: No issues found in 1.1b7 - change to 1.2.0 and submit to MOD Database</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-03-29</date>
				<rev-version>1.1.7</rev-version>
				<changelog lang="en-gb">
					<change>Fix: move one bracket to new line for code formatting to pass validation (fix copied from v1.0.3)</change>
					<change>Fix: undefined variable $special_rank in includes/acp/acp_ranks.php by moving code (fix copied from v1.0.3)</change>
					<change>Fix: Make rank theme ordering alphabetical but with 'default' at the start (thanks to ccole513 for finding the issue and supplying an initial fix)</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-03-29</date>
				<rev-version>1.1.6</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Move UCP Profile rank list generation out of "if allowed birthdays" block (phpBB3 changed around that area for Gold, but instructions were pre-Gold). Only affects sites who disabled birthdays.</change>
					<change>Add: subsilver theme instructions and files (requested and partially helped by gergokee)</change>
					<change>Update: Minor tweaks to prosilver theme</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-03-28</date>
				<rev-version>1.1.5</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Replace DEFAULT_RANK_THEME_ID with SPECIAL_RANK_THEME_ID in validation of rank theme in ucp_profile.php</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-03-23</date>
				<rev-version>1.1.4</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Add ordering of ranks in a theme to memberslist.php (thanks to ccole513 for finding it)</change>
					<change>Update: Make one instruction that involved adding to an associative array in acp_ranks.php clearer so that the comma doesn't get missed (thanks to ccole513 for finding it)</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-03-23</date>
				<rev-version>1.1.3</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Add styling for rank theme list on registration page</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-03-23</date>
				<rev-version>1.1.2</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Merge changes made to v1.0.x to pass MOD database submission.</change>
					<change>Add: Rank theme selction on registration</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-01-20</date>
				<rev-version>1.1.1</rev-version>
				<changelog lang="en-gb">
					<change>Add: Add rank theme pages to members list with prosilver styling.</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-01-20</date>
				<rev-version>1.0.2</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Corrected ACP page so that the post count box shows by default, because 'default' theme is selected. Thanks to Scorpio for finding the strange behaviour.</change>
					<change>Update: Update the change log with missed prefixes and a credit for catching a mistake.</change>
				</changelog>
			</entry>
			<entry>
				<date>2007-12-29</date>
				<rev-version>1.0.1</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Fixed XSL (changed back to Prosilver and replaced with valid XSL file). Thanks to Mitch1063 for finding the mistake.</change>
					<change>Update: Used new feature of MODX format and moved to RC numbering.</change>
				</changelog>
			</entry>
			<entry>
				<date>2007-12-13</date>
				<rev-version>0.1.6</rev-version>
				<changelog lang="en-gb">
					<change>Update: Merged the template and language changes back into this file to pass mod validation check.</change>
				</changelog>
			</entry>
			<entry>
				<date>2007-12-13</date>
				<rev-version>0.1.5</rev-version>
				<changelog lang="en-gb">
					<change>Update: Checked for compatibility with phpBB3 Gold</change>
					<change>Update: Moved template changes out to template/prosilver.xml</change>
					<change>Update: Moved language changes out to languages/en.xml</change>
					<change>Fix: Make some find instructions slightly less ambiguous</change>
					<change>Fix: Alter some find instructions that have changed slightly from initial write to Gold</change>
					<change>Fix: Include fix from http://www.phpbb.com/community/viewtopic.php?f=70&amp;t=554987&amp;st=0&amp;sk=t&amp;sd=a&amp;start=15#p3117909</change>
					<change>Fix: Alter the UCP instructions so that they don't get caught in the "if birthday enabled" checks</change>
					<change>Update: Replace some "after-add" instructions with inline edits (shorter and stops the duplicate calling of the method)</change>
					<change>Update: Make use of inline changes</change>
				</changelog>
			</entry>
			<entry>
				<date>2007-07-18</date>
				<rev-version>0.1.4</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Added missing instruction to add the $rank_theme parameter to the get_user_rank function (parameter documentation was included before, but the parameter wasn't!)</change>
				</changelog>
			</entry>
			<entry>
				<date>2007-07-13</date>
				<rev-version>0.1.3</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Added missing "NO_RANKS_FOR_THEME" translation</change>
				</changelog>
			</entry>
			<entry>
				<date>2007-07-06</date>
				<rev-version>0.1.2</rev-version>
				<changelog lang="en-gb">
					<change>Fix: corrected SQL so that all tables used the "phpbb_" prefix</change>
					<change>Fix: corrected SQL so that the new table had the correct charset</change>
					<change>Fix: corrected XML document so that "find and replace" show as "find and replace" rather than a find with two code blocks</change>
					<change>Change: changed a replace that replaced a line with a comment to a replace that replaced the line with a comment and the original line commented out (for clarity and so it doesn't look like code is missing)</change>
				</changelog>
			</entry>
			<entry>
				<date>2007-06-26</date>
				<rev-version>0.1.1</rev-version>
				<changelog lang="en-gb">
					<change>Fix: Added "ALTER TABLE" command for phpbb_users table</change>
				</changelog>
			</entry>
			<entry>
				<date>2007-06-26</date>
				<rev-version>0.1.0</rev-version>
				<changelog lang="en-gb">
					<change>Initial Version</change>
				</changelog>
			</entry>
		</history>
	</header>
	<action-group>
	    <sql><![CDATA[ALTER TABLE phpbb_users ADD user_rank_theme INT DEFAULT 1 NOT NULL ;
ALTER TABLE phpbb_ranks ADD rank_theme INT DEFAULT 1 NOT NULL ;

UPDATE phpbb_ranks SET rank_theme = -1 WHERE rank_special = 1;

CREATE TABLE phpbb_rank_themes (
  rtheme_id smallint(5) NOT NULL auto_increment,
  rtheme_title varchar(50) default NULL,
  rtheme_public tinyint(1) default '0',
  PRIMARY KEY  (rtheme_id)
) CHARSET=utf8 COLLATE=utf8_bin;

INSERT INTO phpbb_rank_themes VALUES (-1, 'Special', 0);
INSERT INTO phpbb_rank_themes VALUES (1, 'Default', 1);]]></sql>
		<copy>
			<file from="templates/prosilver/template/memberlist_ranks.html" to="styles/prosilver/template/memberlist_ranks.html" />
			<file from="templates/prosilver/themes/images/icon_ranks.gif" to="styles/prosilver/themes/images/icon_ranks.gif" />
		</copy>
		<open src="adm/style/acp_ranks.html">
			<edit>
				<find><![CDATA[	<dl>
		<dt><label for="special_rank">{L_RANK_SPECIAL}:</label></dt>
		<dd><label><input onchange="dE('posts', -1)" type="radio" class="radio" name="special_rank" value="1" id="special_rank"<!-- IF S_SPECIAL_RANK --> checked="checked"<!-- ENDIF --> />{L_YES}</label>
			<label><input onchange="dE('posts', 1)" type="radio" class="radio" name="special_rank" value="0"<!-- IF not S_SPECIAL_RANK --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
	</dl>
]]></find>
				<action type="replace-with"><![CDATA[	 <dl>
		<dt><label for="rank_theme">{L_RANK_THEME}:</label></dt>
		<dd><select name="rank_theme" id="rank_theme" onchange="if (this.selectedIndex > 0) { dE('posts', 1) } else { dE('posts', -1) }">{S_RANK_THEME_LIST}</select></dd>
	</dl>
]]>
				</action>
			</edit>
			<edit>
				<find><![CDATA[<!-- ELSE -->

	<h1>{L_ACP_MANAGE_RANKS}</h1>]]></find>
				<action type="before-add"><![CDATA[<!-- ELSEIF S_EDIT_THEME -->


	<a href="{U_BACK}" style="float: right">&laquo; {L_BACK}</a>
	<h1>{L_ACP_MANAGE_RANK_THEMES}</h1>

	<p>{L_ACP_RANK_THEMES_EXPLAIN}</p>

	<form id="acp_ranks" method="post" action="{U_ACTION}">

	<fieldset>
		<legend>{L_ACP_RANK_THEMES}</legend>
	<dl>
		<dt><label for="title">{L_RANK_THEME_TITLE}:</label></dt>
		<dd><input name="title" type="text" id="title" value="{RANK_THEME_TITLE}" maxlength="255" /></dd>
	</dl>
	<dl>
		<dt><label for="theme_public">{L_RANK_THEME_PUBLIC}:</label></dt>
		<dd><label><input type="radio" class="radio" name="theme_public" value="1" id="theme_public"<!-- IF S_RANK_THEME_PUBLIC --> checked="checked"<!-- ENDIF --> />{L_YES}</label>
			<label><input type="radio" class="radio" name="theme_public" value="0"<!-- IF not S_RANK_THEME_PUBLIC --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
	</dl>

	<p class="submit-buttons">
		<input type="hidden" name="action" value="save_theme" />

		<input class="button1" type="submit" id="submit" name="submit" value="{L_SUBMIT}" />&nbsp;
		<input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" />
	</p>
	</fieldset>

	</form>]]>
				</action>
			</edit>
			<edit>
				<find><![CDATA[
	<!-- BEGIN ranks -->]]></find>
				<action type="before-add"><![CDATA[
	<!-- BEGIN themes -->
		<tr><th colspan="4">{themes.RANK_THEME_TITLE}<!-- IF not themes.S_THEME_PUBLIC --> ({L_PRIVATE})<!-- ENDIF --><!-- IF themes.U_EDIT_THEME --> <span style="margin-left: 5em"><a href="{themes.U_EDIT_THEME}">{ICON_EDIT}</a> <a href="{themes.U_DELETE_THEME}">{ICON_DELETE}</a></span><!-- ENDIF --></th></tr>]]>
				</action>
			</edit>
			<edit>
				<find><![CDATA[<!-- END ranks -->]]></find>
				<action type="replace-with"><![CDATA[
		<!-- BEGINELSE -->
		<tr>
			<td colspan="4">{L_NO_RANKS_FOR_THEME}</td>
		</tr>
		<!-- END ranks -->
	<!-- END themes -->]]></action>
			</edit>
			<edit>
				<find><![CDATA[
		<input class="button2" name="add" type="submit" value="{L_ADD_RANK}" />]]></find>
				<action type="before-add"><![CDATA[
		<input class="button2" name="add_theme" type="submit" value="{L_ADD_RANK_THEME}" />]]></action>
			</edit>
		</open>
		<open src="adm/style/admin.css">
			<edit>
				<find><![CDATA[
	color: #FFFFFF;
	background: #70AED3 url("../images/gradient2b.gif") bottom left repeat-x;
	border-top: 1px solid #6DACD2;
	border-bottom: 1px solid #327AA5;]]></find>
				<action type="replace-with"><![CDATA[
	background-color: #DCEBFE;
	border: 1px solid #6DACD2;
	border-width: 1px 0;]]></action>
			</edit>
			<edit>
				<find><![CDATA[td {
	text-align: left;]]></find>
				<action type="before-add"><![CDATA[
thead th {
	color: #FFFFFF;
	background: #70AED3 url("../images/gradient2b.gif") bottom left repeat-x;
	border-bottom-color: #327AA5
}
				]]></action>
			</edit>
		</open>
		<open src="includes/acp/acp_ranks.php">
			<edit>
				<find><![CDATA[var $u_action;]]></find>
				<action type="after-add"><![CDATA[var $rank_themes = array();]]></action>
			</edit>
			<edit>
				<find><![CDATA[
		$action = (isset($_POST['add'])) ? 'add' : $action;]]></find>
				<action type="after-add"><![CDATA[
		$action = (isset($_POST['add_theme'])) ? 'add_theme' : $action;
				]]></action>
			</edit>
			<edit>
				<find><![CDATA[				$special_rank = request_var('special_rank', 0);]]></find>
				<action type="replace-with"><![CDATA[				//Multi-rank theme mod: special rank now calculated another way
				//$special_rank = request_var('special_rank', 0);
				$rank_theme = request_var('rank_theme', DEFAULT_RANK_THEME_ID);

				if ($rank_theme < DEFAULT_RANK_THEME_ID)
				{
					$special_rank = 1;
					$rank_theme = SPECIAL_RANK_THEME_ID;
				}
				else
				{
					$special_rank = 0;
				}]]></action>
			</edit>
			<edit>
				<find><![CDATA[					'rank_image'		=> htmlspecialchars_decode($rank_image)]]></find>
				<action type="before-add"><![CDATA[					'rank_theme'		=> $rank_theme,]]></action>
			</edit>
			<edit>
				<find><![CDATA[					$cache->destroy('_ranks');

					add_log('admin', 'LOG_RANK_REMOVED', $rank_title);]]></find>
				<action type="after-add"><![CDATA[

					trigger_error($user->lang['RANK_REMOVED'] . adm_back_link($this->u_action));]]></action>
			</edit>
			<edit>
				<find><![CDATA[					if ($action == 'edit' && $rank_id == $row['rank_id'])
					{
						$ranks = $row;
					}
				}
				$db->sql_freeresult($result);]]></find>
				<action type="after-add"><![CDATA[

				$this->load_rank_themes();

				$rank_theme_list = '';
				$rank_theme = (isset($ranks['rank_theme']) ? $ranks['rank_theme'] : DEFAULT_RANK_THEME_ID);

				foreach ($this->rank_themes as $id => $theme_data)
				{
					$rank_theme_list.= '<option value="' . $id . '"' . ($rank_theme == $id ? ' selected="selected"' : '') . '>' . $theme_data['rtheme_title'] . '</option>';
				}]]></action>
			</edit>
			<edit>
				<find><![CDATA[					'S_SPECIAL_RANK'	=> (!isset($ranks['rank_special']) || $ranks['rank_special']) ? true : false,]]></find>
				<action type="replace-with"><![CDATA[					'S_SPECIAL_RANK'	=> (isset($ranks['rank_special']) && $ranks['rank_special']) ? true : false,
					'S_RANK_THEME_LIST'	=> $rank_theme_list,]]></action>
			</edit>
			<edit>
				<find><![CDATA[			}

		$template->assign_vars(array(]]></find>
				<action type="before-add"><![CDATA[

			//Multi-rank theme mod: Add separate theme saving, deleting, adding and editing rather than overriding a single mode
			case 'save_theme':

				$theme_title = utf8_normalize_nfc(request_var('title', '', true));
				$theme_public = request_var('theme_public', 1);

				if (!$theme_title)
				{
					trigger_error($user->lang['NO_RANK_THEME_TITLE'] . adm_back_link($this->u_action), E_USER_WARNING);
				}

				if ($rank_id <= DEFAULT_RANK_THEME_ID && $rank_id != 0)
				{
					trigger_error($user->lang['MUST_SELECT_RANK_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
				}

				$sql_ary = array(
					'rtheme_title'		=> $theme_title,
					'rtheme_public'		=> $theme_public
				);

				if ($rank_id)
				{
					$sql = 'UPDATE ' . RANK_THEMES_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " WHERE rtheme_id = $rank_id";
					$message = $user->lang['RANK_THEME_UPDATED'];

					add_log('admin', 'LOG_RANK_THEME_UPDATED', $theme_title);
				}
				else
				{
					$sql = 'INSERT INTO ' . RANK_THEMES_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
					$message = $user->lang['RANK_THEME_ADDED'];

					add_log('admin', 'LOG_RANK_THEME_ADDED', $theme_title);
				}

				$db->sql_query($sql);

				$cache->destroy('_ranks');

				trigger_error($message . adm_back_link($this->u_action));

			break;

			case 'delete_theme':
				//Don't allow deletion of special or default rank sets
				if ($rank_id <= DEFAULT_RANK_THEME_ID)
				{
					trigger_error($user->lang['MUST_SELECT_RANK_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
				}

				if (confirm_box(true))
				{
					$sql = 'SELECT rtheme_title
						FROM ' . RANK_THEMES_TABLE . '
						WHERE rtheme_id = ' . $rank_id;
					$result = $db->sql_query($sql);
					$theme_title = (string) $db->sql_fetchfield('rtheme_title');
					$db->sql_freeresult($result);

					$sql = 'DELETE FROM ' . RANKS_TABLE . "
						WHERE rank_theme = $rank_id";
					$db->sql_query($sql);

					$sql = 'DELETE FROM ' . RANK_THEMES_TABLE . "
						WHERE rtheme_id = $rank_id";
					$db->sql_query($sql);

					$sql = 'UPDATE ' . USERS_TABLE . "
						SET user_rank_theme = ".DEFAULT_RANK_THEME_ID."
						WHERE user_rank_theme = $rank_id";
					$db->sql_query($sql);

					$cache->destroy('_ranks');

					add_log('admin', 'LOG_RANK_THEME_REMOVED', $theme_title);

					trigger_error($user->lang['RANK_THEME_REMOVED'] . adm_back_link($this->u_action));
				}
				else
				{
					confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
						'i'			=> $id,
						'mode'		=> $mode,
						'rank_id'	=> $rank_id,
						'action'	=> 'delete_theme',
					)));
				}

			break;

			case 'edit_theme':
			case 'add_theme':

				$theme = array();

				$sql = 'SELECT *
					FROM ' . RANK_THEMES_TABLE . '
					WHERE rtheme_id = ' . $rank_id;
				$result = $db->sql_query($sql);

				while ($row = $db->sql_fetchrow($result))
				{
					$theme = $row;
				}
				$db->sql_freeresult($result);

				$template->assign_vars(array(
					'S_EDIT_THEME'		=> true,
					'U_BACK'			=> $this->u_action,
					'U_ACTION'			=> $this->u_action . '&amp;id=' . $rank_id,
					'RANK_THEME_TITLE'	=> (isset($theme['rtheme_title'])) ? $theme['rtheme_title'] : '',
					'S_RANK_THEME_PUBLIC'	=> (isset($theme['rtheme_public']) && $theme['rtheme_public']) ? true : false)
				);


				return;

			break;]]></action>
			</edit>
			<edit>
				<find><![CDATA[		$sql = 'SELECT *
			FROM ' . RANKS_TABLE . '
			ORDER BY rank_special DESC, rank_min ASC, rank_title ASC';]]></find>
				<action type="before-add"><![CDATA[

		$this->load_rank_themes();

		$ranks = array();

		foreach ($this->rank_themes as $theme)
		{
			$ranks[$theme['rtheme_id']] = array();
		}]]></action>
			</edit>
			<edit>
				<find><![CDATA[			$template->assign_block_vars('ranks', array(]]></find>
				<action type="replace-with"><![CDATA[
			$ranks[$row['rank_theme']][] = $row;
		}

		foreach ($this->rank_themes as $theme)
		{
			$template->assign_block_vars('themes', array(
				'RANK_THEME_TITLE'	=> $theme['rtheme_title'],
				'S_THEME_PUBLIC'	=> $theme['rtheme_public'],
				'U_EDIT_THEME'		=> ($theme['rtheme_id'] > 1 ? $this->u_action . '&amp;action=edit_theme&amp;id=' . $theme['rtheme_id'] : ''),
				'U_DELETE_THEME'	=> ($theme['rtheme_id'] > 1 ? $this->u_action . '&amp;action=delete_theme&amp;id=' . $theme['rtheme_id'] : '')));

			if (sizeof($ranks[$theme['rtheme_id']]) > 0)
			{
				foreach ($ranks[$theme['rtheme_id']] as $row)
				{
					$template->assign_block_vars('themes.ranks', array(]]></action>
			</edit>
			<edit>
				<find><![CDATA[}
		$db->sql_freeresult($result);

	}]]></find>
				<action type="replace-with"><![CDATA[
				}
			}
		}
		$db->sql_freeresult($result);
	}

	function load_rank_themes()
	{
		if (sizeof($this->rank_themes) > 0)
		{
			return;
		}

		global $db, $user;

		$sql = 'SELECT * FROM ' . RANK_THEMES_TABLE. " WHERE rtheme_id > ".DEFAULT_RANK_THEME_ID." ORDER BY rtheme_title";
		$result = $db->sql_query($sql);

		$this->rank_themes = array(SPECIAL_RANK_THEME_ID => array('rtheme_id' => SPECIAL_RANK_THEME_ID, 'rtheme_title' => $user->lang['SPECIAL_RANK_THEME'], 'rtheme_public' => false),
									DEFAULT_RANK_THEME_ID => array('rtheme_id' => DEFAULT_RANK_THEME_ID, 'rtheme_title' => $user->lang['DEFAULT_RANK_THEME'], 'rtheme_public' => true));

		while ($row = $db->sql_fetchrow($result))
		{
			$this->rank_themes[$row['rtheme_id']] = $row;
		}
		$db->sql_freeresult($result);
	}]]></action>
			</edit>
		</open>
		<open src="includes/cache.php">
			<edit>
				<find><![CDATA[$sql = 'SELECT *
				FROM ' . RANKS_TABLE . '
				ORDER BY rank_min DESC';]]></find>
				<action type="replace-with"><![CDATA[			//Make sure we only pull data for public rank themes and the special theme
			$sql = $db->sql_build_query('SELECT', array(
				'SELECT'	=> 'r.*',

				'FROM'		=> array(
					RANK_THEMES_TABLE	=> 't'
				),

				'LEFT_JOIN'	=> array(
					array(
						'FROM'	=> array(RANKS_TABLE			=> 'r'),
						'ON'	=> 'r.rank_theme = t.rtheme_id'
					)
				),

				'WHERE'		=> 't.rtheme_public OR t.rtheme_id = ' . SPECIAL_RANK_THEME_ID,
				'ORDER_BY'	=> 'r.rank_min DESC'
			));]]></action>
			</edit>
			<edit>
				<find><![CDATA[$ranks['normal'][] = array(]]></find>
				<action type="replace-with"><![CDATA[$ranks[$row['rank_theme']][] = array(]]></action>
			</edit>
		</open>
		<open src="includes/constants.php">
			<edit>
				<find><![CDATA[// Additional constants]]></find>
				<action type="after-add"><![CDATA[
define('SPECIAL_RANK_THEME_ID', -1);
define('DEFAULT_RANK_THEME_ID', 1);]]></action>
			</edit>
			<edit>
				<find><![CDATA[define('RANKS_TABLE',				$table_prefix . 'ranks');]]></find>
				<action type="after-add"><![CDATA[define('RANK_THEMES_TABLE',			$table_prefix . 'rank_themes');]]></action>
			</edit>
		</open>
		<open src="includes/functions.php">
			<edit>
				<find><![CDATA[		'U_FAQ'					=> append_sid("{$phpbb_root_path}faq.$phpEx"),]]></find>
				<action type="after-add"><![CDATA[		'U_RANKS'				=> append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=ranks'),]]></action>
			</edit>
		</open>
		<open src="includes/functions_display.php">
			<edit>
				<find><![CDATA[* @param string &$rank_img_src the rank image source is stored here after execution]]></find>
				<action type="after-add"><![CDATA[* @param int $rank_theme the rank theme set to load from (defaulting to DEFAULT_RANK_THEME_ID)]]></action>
			</edit>
			<edit>
				<find><![CDATA[function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank_img_src)]]></find>
				<inline-edit>
            				<inline-find>, &amp;$rank_img_src</inline-find>
					<inline-action type="after-add">, $rank_theme = DEFAULT_RANK_THEME_ID</inline-action>
				</inline-edit>
			</edit>
			<edit>
				<find><![CDATA[		if (!empty($ranks['normal']))]]></find>
				<action type="replace-with"><![CDATA[		//Multi-rank theme: find our theme, defaulting to DEFAULT_RANK_THEME_ID if the user chose an invalid value
		if (!empty($ranks[$rank_theme]))
		{
			$theme = $ranks[$rank_theme];
		}
		else
		{
			//Assume DEFAULT_RANK_THEME_ID always exists
			$theme = $ranks[DEFAULT_RANK_THEME_ID];
		}

		if (!empty($theme))]]></action>
			</edit>
			<edit>
				<find><![CDATA[		foreach ($ranks['normal'] as $rank)]]></find>
				<action type="replace-with"><![CDATA[		foreach ($theme as $rank)]]></action>
			</edit>
		</open>
		<open src="includes/ucp/ucp_profile.php">
			<edit>
				<find><![CDATA[					'interests'		=> utf8_normalize_nfc(request_var('interests', $user->data['user_interests'], true)),]]></find>
				<action type="after-add"><![CDATA[					'rank_theme'		=> request_var('rank_theme', $user->data['user_rank_theme']),]]></action>
			</edit>
			<edit>
				<find><![CDATA[
						'interests'		=> array('string', true, 2, 500),]]></find>
				<action type="after-add"><![CDATA[
						'rank_theme'	=> array('num', true, SPECIAL_RANK_THEME_ID),]]></action>
			</edit>
			<edit>
				<find><![CDATA[
							'user_interests'=> $data['interests'],]]></find>
				<action type="after-add"><![CDATA[
							'user_rank_theme' => $data['rank_theme'],]]></action>
			</edit>
			<edit>
				<find><![CDATA[					$template->assign_vars(array(
						'S_BIRTHDAY_DAY_OPTIONS'	=> $s_birthday_day_options,
						'S_BIRTHDAY_MONTH_OPTIONS'	=> $s_birthday_month_options,
						'S_BIRTHDAY_YEAR_OPTIONS'	=> $s_birthday_year_options,
						'S_BIRTHDAYS_ENABLED'		=> true,
					));
				}]]></find>
				<action type="after-add"><![CDATA[				//Multi-rank theme: Construct the rank theme options, if applicable
				$s_rank_theme_options = '';

				if ($user->data['user_rank'] == 0)
				{
					$sql = $db->sql_build_query('SELECT', array(
						'SELECT'	=> 'rtheme_id, rtheme_title',

						'FROM'		=> array(
							RANK_THEMES_TABLE		=> 'r'
						),

						'WHERE'		=> 'rtheme_public = 1 AND rtheme_id > ' . DEFAULT_RANK_THEME_ID,

						'ORDER_BY'	=> 'rtheme_title ASC',
					));

					$result = $db->sql_query($sql);
					$valid_selection = false;

					while ($row = $db->sql_fetchrow($result))
					{
						if ($row['rtheme_id'] == $data['rank_theme'])
						{
							$selected = ' selected="selected"';
							$valid_selection = true;
						}
						else
						{
							$selected = '';
						}

						$s_rank_theme_options .= '<option value="' . $row['rtheme_id'] . '"' . $selected . '>' . $row['rtheme_title'] . '</option>';
					}

					$db->sql_freeresult($result);

					$selected = (!$valid_selection) ? ' selected="selected"' : ''; //If they've managed to get a bad selection, make sure "default" is selected
					$s_rank_theme_options = '<option value="' . DEFAULT_RANK_THEME_ID . '"' . $selected . '>' . $user->lang['DEFAULT_RANK_THEME'] . '</option>' . $s_rank_theme_options; //And append to the start
				}]]></action>
			</edit>
			<edit>
				<find><![CDATA[					'INTERESTS'	=> $data['interests'],]]></find>
				<action type="after-add"><![CDATA[					'RANK_THEME'	=> $data['rank_theme'],
					'S_RANK_THEME_OPTIONS'	=> $s_rank_theme_options,]]></action>
			</edit>
		</open>
		<open src="includes/ucp/ucp_register.php">
			<edit>
				<find><![CDATA[					'tz'				=> request_var('tz', (float) $config['board_timezone']),]]></find>
				<action type="after-add"><![CDATA[					'rank_theme'		=> request_var('rank_theme', DEFAULT_RANK_THEME_ID),]]></action>
			</edit>
			<edit>
				<find><![CDATA[			'tz'				=> request_var('tz', (float) $timezone),]]></find>
				<action type="after-add"><![CDATA[			'rank_theme'		=> request_var('rank_theme', DEFAULT_RANK_THEME_ID),]]></action>
			</edit>
			<edit>
				<find><![CDATA[				'tz'				=> array('num', false, -14, 14),]]></find>
				<action type="after-add"><![CDATA[				'rank_theme'	=> array('num', true, SPECIAL_RANK_THEME_ID),]]></action>
			</edit>
			<edit>
				<find><![CDATA[					'user_timezone'			=> (float) $data['tz'],]]></find>
				<action type="after-add"><![CDATA[					'user_rank_theme'		=> (int) $data['rank_theme'],]]></action>
			</edit>
			<edit>
				<find><![CDATA[		$template->assign_vars(array(
			'ERROR'				=> (sizeof($error)) ? implode('<br />', $error) : '',]]></find>
				<action type="before-add"><![CDATA[		//IBBoard: Construct the rank theme options, if applicable
		$s_rank_theme_options = '';

		$sql = $db->sql_build_query('SELECT', array(
			'SELECT'	=> 'rtheme_id, rtheme_title',

			'FROM'		=> array(
				RANK_THEMES_TABLE		=> 'r'
			),

			'WHERE'		=> 'rtheme_public = 1 AND rtheme_id > '.DEFAULT_RANK_THEME_ID,

			'ORDER_BY'	=> 'rtheme_title ASC',
		));

		$result = $db->sql_query($sql);
		$valid_selection = false;

		while ($row = $db->sql_fetchrow($result))
		{
			if ($row['rtheme_id'] == $data['rank_theme'])
			{
				$selected = ' selected="selected"';
				$valid_selection = true;
			}
			else
			{
				$selected = '';
			}

						$s_rank_theme_options .= '<option value="' . $row['rtheme_id'] . '"' . $selected . '>' . $row['rtheme_title'] . '</option>';
					}

					$db->sql_freeresult($result);

					$selected = (!$valid_selection) ? ' selected="selected"' : ''; //If they've managed to get a bad selection, make sure "default" is selected
					$s_rank_theme_options = '<option value="' . DEFAULT_RANK_THEME_ID . '"' . $selected . '>' . $user->lang['DEFAULT_RANK_THEME'] . '</option>' . $s_rank_theme_options; //And append to the start]]></action>
			</edit>
			<edit>
				<find><![CDATA[			'S_TZ_OPTIONS'		=> tz_select($data['tz']),]]></find>
				<action type="after-add"><![CDATA[			'S_RANK_THEME_OPTIONS'		=> $s_rank_theme_options,]]></action>
			</edit>
		</open>
		<open src="language/en/acp/common.php">
			<edit>
				<find><![CDATA[));

?>]]></find>
				<action type="before-add"><![CDATA[	//Multi-rank theme: Add rank theme logging messages
	'LOG_RANK_THEME_ADDED'		=> '<strong>Added new rank theme</strong><br />» %s',
	'LOG_RANK_THEME_REMOVED'		=> '<strong>Removed rank theme</strong><br />» %s',
	'LOG_RANK_THEME_UPDATED'		=> '<strong>Updated rank theme</strong><br />» %s',
	//Multi-rank theme: Add other common new langs
	'PRIVATE'					=> 'Private',
	'ACP_MANAGE_RANK_THEMES'			=> 'Manage rank themes',
	'ACP_RANK_THEMES'					=> 'Rank themes',
]]></action>
			</edit>
		</open>
		<open src="language/en/acp/posting.php">
			<edit>
				<find><![CDATA[	'RANK_UPDATED'			=> 'The rank was successfully updated.',]]></find>
				<action type="after-add"><![CDATA[	//Multi-rank theme: Rank theme specific language strings
	'ADD_RANK_THEME'		=> 'Add new rank theme',
	'ACP_RANK_THEMES_EXPLAIN'	=> 'Using this form you can add, edit, view and delete rank themes. Rank themes can be made private so that they are not selectable by users.',
	'RANK_THEME_TITLE'		=> 'Rank theme title',
	'RANK_THEME_PUBLIC'		=> 'Set as public rank theme',
	'RANK_THEME'			=> 'Rank theme',
	'MUST_SELECT_RANK_THEME'	=> 'You must select a valid rank theme. Default and special themes cannot be deleted.',
	'RANK_THEME_ADDED'		=> 'The rank theme was successfully added.',
	'RANK_THEME_REMOVED'	=> 'The rank theme (and all ranks within it) was successfully removed.',
	'RANK_THEME_UPDATED'	=> 'The rank theme was successfully updated.',
	'NO_RANKS_FOR_THEME'	=> 'No ranks for theme',]]></action>
			</edit>
		</open>
		<open src="language/en/common.php">
			<edit>
				<find><![CDATA[	'YOU_NO_NEW_PM'		=> 'No new private messages are waiting for you.',]]></find>
				<action type="after-add"><![CDATA[
	//Multi-rank theme: Add in new rank naming
	'DEFAULT_RANK_THEME'	=> 'Default theme',
	'SPECIAL_RANK_THEME'	=> 'Special theme',
	//Multi-rank theme: Add header link text
	'RANKS_EXPLAIN'         => 'Available rank themes',
	'RANKS'                 => 'Rank Themes',]]></action>
			</edit>
		</open>
		<open src="language/en/memberlist.php">
			<edit>
				<find><![CDATA[));

?>]]></find>
				<action type="before-add"><![CDATA[// Multi-rank theme: Rank theme list information
	'RANKTHEMES'		=> 'Rank Themes',
	'RANKTHEME_TEXT'	=> 'Rank themes allow you to customise the name and image of the rank that is displayed beside your post. For a full list of the ranks within a scheme click on the scheme name. For more detail on ranks please see the <a href="faq.php#f15">FAQ</a>.',
	'RANK_NAME'		=> 'Rank',
	'RANK_IMG'		=> 'Rank image',
	'RANK_POSTS'		=> 'Required post count',
	'NO_RANKSET_ERROR'	=> 'The rank theme you selected was invalid. Please check the link and try again.'
]]></action>
			</edit>
		</open>
		<open src="language/en/ucp.php">
			<edit>
				<find><![CDATA[	'UCP_PROFILE_SIGNATURE'		=> 'Edit signature',]]></find>
				<action type="after-add"><![CDATA[	'UCP_RANK_THEME'			=> 'Rank theme',	//Multi-rank theme: Add rank theme label]]></action>
			</edit>
		</open>
		<open src="memberlist.php">
			<edit>
				<find><![CDATA[$topic_id	= request_var('t', 0);]]></find>
				<action type="after-add"><![CDATA[$rank_theme	= request_var('r', 0);]]></action>
			</edit>
			<edit>
				<find><![CDATA[if (!in_array($mode, array('', 'group', 'viewprofile', 'email', 'contact', 'searchuser', 'leaders')))]]></find>
				<inline-edit>
					<inline-find>, 'leaders'</inline-find>
					<inline-action type="after-add"><![CDATA[, 'ranks']]></inline-action>
				</inline-edit>
			</edit>
			<edit>
				<find><![CDATA[	case 'email':]]></find>
				<action type="after-add"><![CDATA[	case 'ranks':]]></action>
			</edit>
			<edit>
				<find><![CDATA[			get_user_rank($row['user_rank'], $row['user_posts'], $rank_title, $rank_img, $rank_img_src);]]></find>
				<inline-edit>
					<inline-find>$rank_img_src</inline-find>
					<inline-action type="after-add"><![CDATA[, $row['user_rank_theme']]]></inline-action>
				</inline-edit>
			</edit>
			<edit>
				<find><![CDATA[	case 'group':
	default:
		// The basic memberlist]]></find>
				<action type="before-add"><![CDATA[	case 'ranks':
		// Display all available rank sets or the list of ranks for a set
		$page_title = $user->lang['RANKTHEMES'];
		$template_html = 'memberlist_ranks.html';

		if ($rank_theme == 0)
		{
			// Get list of rank themes
			$sql = 'SELECT rtheme_id, rtheme_title
				FROM ' . RANK_THEMES_TABLE . '
				WHERE rtheme_public = 1
					AND rtheme_id > ' . DEFAULT_RANK_THEME_ID . '
				ORDER BY rtheme_title ASC';
			$result = $db->sql_query($sql);

			$template->assign_block_vars('rankset', array(
				'RANKSET_URL' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=ranks&amp;r=' . DEFAULT_RANK_THEME_ID),
				'RANKSET_NAME' => $user->lang['DEFAULT_RANK_THEME']
			));

			while ($row = $db->sql_fetchrow($result))
			{
				$template->assign_block_vars('rankset', array(
					'RANKSET_URL' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=ranks&amp;r=' . $row['rtheme_id']),
					'RANKSET_NAME' => $row['rtheme_title']
				));
			}

			$db->sql_freeresult($result);
		}
		else
		{
			$sql = 'SELECT rtheme_title
				FROM ' . RANK_THEMES_TABLE . '
				WHERE rtheme_public = 1
					AND rtheme_id = ' . $rank_theme;
			$result = $db->sql_query($sql);
			$row = $db->sql_fetchrow($result);
			$db->sql_freeresult($result);

			if ($row != false)
			{
				$set_title = $row['rtheme_title'];
				$template->assign_vars(array(
					'RANKSET_NAME' => $set_title,
					'U_RANKSET_LIST_LINK' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=ranks')
				));
				$sql = 'SELECT rank_title, rank_min, rank_image
					FROM ' . RANKS_TABLE . '
					WHERE rank_theme = ' . $rank_theme . '
					ORDER BY rank_min ASC';
				$result = $db->sql_query($sql);

				while ($rank = $db->sql_fetchrow($result))
				{
					$rank_img = (!empty($rank['rank_image'])) ? '<img src="' . $config['ranks_path'] . '/' . $rank['rank_image'] . '" alt="' . $rank['rank_title'] . '" title="' . $rank['rank_title'] . '" />' : '';
					$template->assign_block_vars('rank', array(
						'RANK_NAME' => $rank['rank_title'],
						'RANK_IMG' => $rank_img,
						'RANK_POSTS' => $rank['rank_min']
					));
				}

				$db->sql_freeresult($result);
			}
			else
			{
				trigger_error($user->lang['NO_RANKSET_ERROR']);
			}
		}

	break;]]></action>
			</edit>
			<edit>
				<find><![CDATA[	get_user_rank($data['user_rank'], $data['user_posts'], $rank_title, $rank_img, $rank_img_src);]]></find>
				<inline-edit>
					<inline-find>$rank_img_src</inline-find>
					<inline-action type="after-add"><![CDATA[, $data['user_rank_theme']]]></inline-action>
				</inline-edit>
			</edit>
		</open>
		<open src="styles/prosilver/template/overall_header.html">
			<edit>
				<find><![CDATA[					<!-- IF S_DISPLAY_MEMBERLIST --><li class="icon-members"><a href="{U_MEMBERLIST}" title="{L_MEMBERLIST_EXPLAIN}">{L_MEMBERLIST}</a></li><!-- ENDIF -->]]></find>
				<action type="after-add"><![CDATA[					<li class="icon-ranks"><a href="{U_RANKS}" title="{L_RANKS_EXPLAIN}">{L_RANKS}</a></li>]]></action>
			</edit>
		</open>
		<open src="styles/prosilver/template/ucp_profile_profile_info.html">
			<edit>
				<find><![CDATA[	<!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF -->]]></find>
				<action type="after-add"><![CDATA[
	<!-- IF S_RANK_THEME_OPTIONS -->
	<dl>
		<dt><label for="rank_theme">{L_UCP_RANK_THEME}:</label></dt>
		<dd><select name="rank_theme" id="rank_theme">{S_RANK_THEME_OPTIONS}</select></dd>
	</dl>
	<!-- ELSE -->
	<input type="hidden" name="rank_theme" value="{RANK_THEME}" />
	<!-- ENDIF -->]]></action>
			</edit>
		</open>
		<open src="styles/prosilver/template/ucp_register.html">
			<edit>
				<find><![CDATA[		<dt><label for="tz">{L_TIMEZONE}:</label></dt>
		<dd><select name="tz" id="tz" class="autowidth">{S_TZ_OPTIONS}</select></dd>
	</dl>]]></find>
				<action type="after-add"><![CDATA[
	<!-- IF S_RANK_THEME_OPTIONS -->
	<dl>
		<dt><label for="rank_theme">{L_UCP_RANK_THEME}:</label></dt>
		<dd><select name="rank_theme" id="rank_theme">{S_RANK_THEME_OPTIONS}</select></dd>
	</dl>
	<!-- ENDIF -->]]></action>
			</edit>
		</open>
		<open src="styles/prosilver/theme/bidi.css">
			<edit>
				<find><![CDATA[.rtl .icon-bookmark, .rtl .icon-bump, .rtl .icon-subscribe, .rtl .icon-unsubscribe, .rtl .icon-pages, .rtl .icon-search {]]></find>
				<inline-edit>
					<inline-find>{</inline-find>
					<inline-action type="before-add"><![CDATA[, .rtl .icon-ranks]]></inline-action>
				</inline-edit>
			</edit>
		</open>
		<open src="styles/prosilver/theme/buttons.css">
			<edit>
				<find><![CDATA[.icon-bookmark, .icon-bump, .icon-subscribe, .icon-unsubscribe, .icon-pages, .icon-search {]]></find>
				<inline-edit>
					<inline-find>{</inline-find>
					<inline-action type="before-add"><![CDATA[, .icon-ranks]]></inline-action>
				</inline-edit>
			</edit>
		</open>
		<open src="styles/prosilver/theme/colours.css">
			<edit>
				<find><![CDATA[.icon-search					{ background-image: url("{T_THEME_PATH}/images/icon_search.gif"); }]]></find>
				<action type="after-add"><![CDATA[.icon-ranks					{ background-image: url("{T_THEME_PATH}/images/icon_ranks.gif"); }]]></action>
			</edit>
		</open>
		<open src="viewtopic.php">
			<edit>
				<find><![CDATA[			get_user_rank($row['user_rank'], $row['user_posts'], $user_cache[$poster_id]['rank_title'], $user_cache[$poster_id]['rank_image'], $user_cache[$poster_id]['rank_image_src']);]]></find>
				<inline-edit>
					<inline-find>$user_cache[$poster_id]['rank_image_src']</inline-find>
					<inline-action type="after-add"><![CDATA[, $row['user_rank_theme']]]></inline-action>
				</inline-edit>
			</edit>
		</open>
		<diy-instructions lang="en">Clear the rank and template files from your cache folder to ensure that all of the new ranks show up correctly and that users can select them.</diy-instructions>
	</action-group>
</mod>