<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="./contrib/xsl/modx.prosilver.en.xsl"?>
<!-- 
	NOTICE: Please open this file in your web browser. If presented with a security warning, you may safely tell it to allow the blocked content.
-->
<!--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.1.xsd">
	<header>
		<license>http://opensource.org/licenses/gpl-license.php GNU General Public License v2</license>
		<title lang="en">Prime Nest BBCodes</title>
		<description lang="en">This MOD will allow Custom BBCodes to be nested. The maximum number of times that a custom BBCode is allowed to be nested can be set when creating or editing custom BBCodes (in the Administration Control Panel).</description>
		<author-notes lang="en">Creating, maintaining, and updating MODs requires a lot of time and effort, so if you like this MOD and have the desire to express your thanks through donations, that would be greatly appreciated. My Paypal ID is primehalo@gmail.com, or contact me for my mailing address. The suggested donation amount for this MOD is $5.00 (but any amount will help).</author-notes>
		<author-group>
			<author>
				<realname>Ken F. Innes IV</realname>
				<email>primehalo@gmail.com</email>
				<username>primehalo</username>
				<homepage><![CDATA[http://www.absoluteanime.com/admin/mods.htm#nest_bbcodes]]></homepage>
			</author>
		</author-group>
		<mod-version>0.0.1c</mod-version>
		<installation>
			<level>easy</level>
			<time>180</time>
			<target-version>3.0.3</target-version>
		</installation>
		<history>
			<entry>
				<date>2007-09-06</date>
				<rev-version>0.0.0</rev-version>
				<changelog lang="en">
					<change>Initial test release</change>
				</changelog>
			</entry>

			<entry>
				<date>2007-09-07</date>
				<rev-version>0.0.1</rev-version>
				<changelog lang="en">
					<change>Fixed: No styling (nesting or otherwise) would work on nested tags that were posted when their maximum depth was set to zero, even if the max depth was later changed to a positive integer.</change>
				</changelog>
			</entry>

			<entry>
				<date>2007-10-22</date>
				<rev-version>0.0.1a</rev-version>
				<changelog lang="en">
					<change>Confirmed compatibility with phpBB3.0.RC7.</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-07-02</date>
				<rev-version>0.0.1b</rev-version>
				<changelog lang="en">
					<change>Repackaged for MODX 1.2.0.</change>
				</changelog>
			</entry>
			<entry>
				<date>2008-11-14</date>
				<rev-version>0.0.1c</rev-version>
				<changelog lang="en">
					<change>Updated instructions for phpBB3.0.3.</change>
				</changelog>
			</entry>
		</history>
	</header>
	<action-group>
		<copy>
			<file from="root/language/en/mods/prime_nest_bbcodes.php" to="language/en/mods/prime_nest_bbcodes.php" />
		</copy>

		<sql><![CDATA[ALTER TABLE phpbb_bbcodes ADD (`max_depth` tinyint(1) UNSIGNED DEFAULT "0" NOT NULL)]]></sql>

		<open src="adm/style/acp_bbcodes.html">
			<edit>
				<find><![CDATA[		<dd><input type="checkbox" class="radio" name="display_on_posting" id="display_on_posting" value="1"<!-- IF DISPLAY_ON_POSTING --> checked="checked"<!-- ENDIF --> /></dd>
	</dl>]]></find>
				<action type="after-add"><![CDATA[<!-- mod: Prime Nest BBCodes - - - - - - - - - - - - - - - - - - - - -->
	<dl>
		<dt><label for="max_depth">{L_PRIME_NEST_BBCODES_MAX_DEPTH}</label></dt>
		<dd><input type="text" id="max_depth" name="max_depth" value="{MAX_DEPTH}" size="2" /></dd>
	</dl>
<!-- end: Prime Nest BBCodes - - - - - - - - - - - - - - - - - - - - -->]]></action>
			</edit>
		</open>

		<open src="includes/acp/acp_bbcodes.php">
			<edit>
				<find><![CDATA[		$user->add_lang('acp/posting');]]></find>
				<action type="after-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
		$user->add_lang('mods/prime_nest_bbcodes');
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>

			<edit>
				<find><![CDATA[				$display_on_posting = 0;]]></find>
				<action type="after-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
				$max_depth = 0;
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>

			<edit>
				<find><![CDATA[			case 'edit':
				$sql = 'SELECT bbcode_match, bbcode_tpl, display_on_posting, bbcode_helpline
					FROM ' . BBCODES_TABLE . '
					WHERE bbcode_id = ' . $bbcode_id;]]></find>
				<action type="after-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
				$sql = str_replace('SELECT ', 'SELECT max_depth, ', $sql);
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>

			<edit>
				<find><![CDATA[				$bbcode_helpline = $row['bbcode_helpline'];]]></find>
				<action type="after-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
				$max_depth = $row['max_depth'];
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>

			<edit>
				<find><![CDATA[				$display_on_posting = request_var('display_on_posting', 0);]]></find>
				<action type="after-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
				$max_depth = request_var('max_depth', 0);
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>

			<edit>
				<find><![CDATA[					'U_ACTION'			=> $this->u_action . '&amp;action=' . (($action == 'add') ? 'create' : 'modify') . (($bbcode_id) ? "&amp;bbcode=$bbcode_id" : ''),]]></find>
				<action type="after-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
					'MAX_DEPTH'			=> $max_depth,
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>

			<edit>
				<find><![CDATA['display_on_posting'		=> $display_on_posting,]]></find>
				<action type="before-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
// Here we change the second pass regular expression so it will only match a 
// tag that does not contain another of the same tag inside it.
				if (!empty($max_depth))
				{
					if (preg_match('/^!(.*)!([imsxeADSUXu]+)$/', $data['second_pass_match']))
					{
						// We cannot use a '!' delemeter because we need to use (?!) inside the 
						// regular expression. Thus, we will use '@' for our delemeter.
						$data['second_pass_match'] = str_replace('@', '\\@', $data['second_pass_match']);
						$data['second_pass_match'] = preg_replace('/^!(.*)!([imsxeADSUXu]+)$/', '@$1@$2', $data['second_pass_match']);
						$data['second_pass_match'] = str_replace('\\!', '!', $data['second_pass_match']);
					}
					$data['second_pass_match'] = preg_replace('%(\\\\\[' . $test . '[^]]*])%se', "str_replace('=(.*?)', '=([^\]]*)', '$1') . '(?!.*' . preg_replace('/=.*?\\\]/', '=[^\]]*\\]', '$1') . '.*)'", $data['second_pass_match']);
					$data['second_pass_match'] = str_replace(':$uid', '(?::$uid)?', $data['second_pass_match']);
				}
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>

			<edit>
				<find><![CDATA[					'bbcode_tag'				=> $data['bbcode_tag'],]]></find>
				<action type="before-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
					'max_depth'					=> $max_depth,
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>
		</open>


		<open src="includes/bbcode.php">
			<edit>
				<find><![CDATA[					foreach ($array as $search => $replace)]]></find>
				<action type="before-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
// Here our custom $max_depth variable gets created.
					if (!is_array($array))
					{
						${$type} = $array;
						continue;
					}
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>

			<edit>
				<find><![CDATA[					if (sizeof($str['search']))]]></find>
				<action type="before-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
// Here each nested tag will get its replacement, up to $max_depth tags.
					if ($bbcode_id > NUM_CORE_BBCODES && $max_depth > 0 && sizeof($preg['search']) && strpos(implode('', $preg['search']), '@') === 0)
					{
						for ($depth_count = 0, $replace_count = null; $depth_count <= $max_depth && $replace_count !== 0; $depth_count++)
						{
							$message = preg_replace($preg['search'], $preg['replace'], $message, -1, $replace_count);
						}
						$preg = array('search' => array(), 'replace' => array());
					}
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>

			<edit>
				<find><![CDATA[								'preg' => array($rowset[$bbcode_id]['second_pass_match'] => $bbcode_tpl)]]></find>
				<action type="before-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
// Store the max depth allowed, for use later in the bbcode_second_pass() function.
								'max_depth'  => !empty($rowset[$bbcode_id]['max_depth']) ? $rowset[$bbcode_id]['max_depth'] : 0,
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>
		</open>


		<open src="includes/message_parser.php">
			<edit>
				<find><![CDATA[						$bitfield->set($bbcode_data['bbcode_id']);
					}]]></find>
				<action type="after-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
// Here we put the uid in the nested tags that didn't get it above.
					if ($bbcode_data['bbcode_id'] > NUM_CORE_BBCODES && !empty($bbcode_data['max_depth']))
					{
						for ($depth = 0; preg_match($regexp, $this->message); $depth++)
						{
							$this->message = preg_replace($regexp, $replacement, $this->message);
						}
						if ($depth > $bbcode_data['max_depth'])
						{
							$this->warn_msg[] = sprintf($user->lang['QUOTE_DEPTH_EXCEEDED'], $bbcode_data['max_depth']);
						}
					}
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>

			<edit>
				<find><![CDATA[			$this->bbcodes[$row['bbcode_tag']] = array(]]></find>
				<action type="after-add"><![CDATA[//-- mod: Prime Nest BBCodes ------------------------------------------------//
// Here we store the max_depth amount, for use later in the parse_bbcode() function.
				'max_depth'	=> (int) $row['max_depth'],
//-- end: Prime Nest BBCodes ------------------------------------------------//]]></action>
			</edit>
		</open>

		<diy-instructions lang="en">As an alternative to manually executing the SQL statements, you can use the included 
"db_install.php" (located in the contrib directory). Simply copy the file to the root
directory of your phpbb3 install, and point your web browser to the address. Make 
sure you are logged in as an administrator before you do this, and make sure to
delete the file once you're done.</diy-instructions>
	</action-group>
</mod>