ReIMG Image Resizer

All new MODs released in our MOD Database will be announced in here. All support for released MODs needs to take place in the Customisations Database.
Forum rules
READ: phpBB.com Board-Wide Rules and Regulations

NOTICE: This forum is only for the announcement of new releases and/or updates of MODs. Any MOD support should be obtained through the Customisations Database in the support area designated for each MOD.

A direct link to support for each MOD is in the first post of the respective topic.
snor1991
Registered User
Posts: 5
Joined: Tue Apr 20, 2010 6:48 am

Re: ReIMG Image Resizer

Post by snor1991 »

_Salvatore_ wrote:
I can't see the + and - zoom buttons on the top left of the image.
I do see a green and red square. But not the images. I did something wrong. But what? :?
had the same problem because I missed some changes in the includes/acp_styles.php file.
Check all the changes again and REFRESH the imageset of the style you modified.
That doesn't work.
User avatar
DavidIQ
Customisations Team Leader
Customisations Team Leader
Posts: 18282
Joined: Thu Jan 06, 2005 1:30 pm
Location: Fishkill, NY
Name: David Colón
Contact:

Re: ReIMG Image Resizer

Post by DavidIQ »

snor1991 wrote:That doesn't work.
What doesn't work? Post a link to an example post where it's not working.
Apply to become a Jr. Extension Validator
My extensions | In need of phpBB services? | Was I helpful today?
No unsolicited PMs unless you're planning on asking for paid help.
snor1991
Registered User
Posts: 5
Joined: Tue Apr 20, 2010 6:48 am

Re: ReIMG Image Resizer

Post by snor1991 »

DavidIQ wrote:
snor1991 wrote:That doesn't work.
What doesn't work? Post a link to an example post where it's not working.
http://www.novacrew.nl/forum/viewtopic. ... 480#p34480

It is like this on the whole forum.
User avatar
DavidIQ
Customisations Team Leader
Customisations Team Leader
Posts: 18282
Joined: Thu Jan 06, 2005 1:30 pm
Location: Fishkill, NY
Name: David Colón
Contact:

Re: ReIMG Image Resizer

Post by DavidIQ »

snor1991 wrote:
DavidIQ wrote:
snor1991 wrote:That doesn't work.
What doesn't work? Post a link to an example post where it's not working.
http://www.novacrew.nl/forum/viewtopic. ... 480#p34480

It is like this on the whole forum.
http://www.novacrew.nl/forum/styles/bla ... ageset.cfg
Look at the bottom of that and you'll quickly see why it's not working ;)
Apply to become a Jr. Extension Validator
My extensions | In need of phpBB services? | Was I helpful today?
No unsolicited PMs unless you're planning on asking for paid help.
User avatar
muggins
Registered User
Posts: 1183
Joined: Fri Feb 22, 2008 5:12 pm
Location: Texas
Name: Donovan
Contact:

Re: ReIMG Image Resizer

Post by muggins »

I hate to be cruel, but is that a candidate for your site? :lol:

I never understood why this mod is so difficult for some...
Muggins
Sarrene
Registered User
Posts: 79
Joined: Wed Jan 23, 2008 10:20 am
Name: Sarrene Grant
Contact:

Re: ReIMG Image Resizer

Post by Sarrene »

I feel like a complete idiot. I cannot get this working for some reason.

All images are default size. There are no resize buttons. Click on image, it takes you to another page to display full size. Basically acts as vanilla phpbb3 images/attachments.

Install seemed to work. There were no errors and the message that it was installed successfully and I should delete the install file.

I have edited all files, I have gone back to double checked. After reading the entire thread I triple check the files to make sure i have all edits.
Edited root files and both templates.

Settings showing up in the adm > post settings. I have those set and adjusted.

I have edited both prosilver and my custom theme... No go on either of them.

I have purged the cache several times, refreshed all templates and theme files.. even purged the cache manually. Still no go. What obvious thing am I looking over?

Site:
http://darkrelic.com/player-network/forums

Thank you ahead of time for all your help.
User avatar
DavidIQ
Customisations Team Leader
Customisations Team Leader
Posts: 18282
Joined: Thu Jan 06, 2005 1:30 pm
Location: Fishkill, NY
Name: David Colón
Contact:

Re: ReIMG Image Resizer

Post by DavidIQ »

Sarrene wrote:Site:
http://darkrelic.com/player-network/forums

Thank you ahead of time for all your help.
Can you be a little more specific? I'm not about to go fishing through all your topics until I find one that has an image in one of the posts ;)
Apply to become a Jr. Extension Validator
My extensions | In need of phpBB services? | Was I helpful today?
No unsolicited PMs unless you're planning on asking for paid help.
Sarrene
Registered User
Posts: 79
Joined: Wed Jan 23, 2008 10:20 am
Name: Sarrene Grant
Contact:

Re: ReIMG Image Resizer

Post by Sarrene »

Pretty much as I said.. There is no difference from before I installed the mod to now. We really do not have many public posts right now. We have not yet gone public. So here is one I just made

Example thread...
http://darkrelic.com/player-network/for ... ?f=2&t=244

Peace,
Sarrene'
User avatar
DavidIQ
Customisations Team Leader
Customisations Team Leader
Posts: 18282
Joined: Thu Jan 06, 2005 1:30 pm
Location: Fishkill, NY
Name: David Colón
Contact:

Re: ReIMG Image Resizer

Post by DavidIQ »

That's an attachment. If you want to use this MOD with attachments you have to disable the thumbnail creation feature. And btw disabling the thumbnails feature is not retroactive. It only applies to new attachments.
Apply to become a Jr. Extension Validator
My extensions | In need of phpBB services? | Was I helpful today?
No unsolicited PMs unless you're planning on asking for paid help.
Sarrene
Registered User
Posts: 79
Joined: Wed Jan 23, 2008 10:20 am
Name: Sarrene Grant
Contact:

Re: ReIMG Image Resizer

Post by Sarrene »

I understand that is an attachment and that it will not be retroactive. I have disabled thumbnails already, and just double checked before making this new post.

Here is a new post from today I just made. As you can see, neither are working.
http://darkrelic.com/player-network/for ... ,710/#p710

Thank you for your help I really appreciate it.

Peace,
Sarrene'
User avatar
DavidIQ
Customisations Team Leader
Customisations Team Leader
Posts: 18282
Joined: Thu Jan 06, 2005 1:30 pm
Location: Fishkill, NY
Name: David Colón
Contact:

Re: ReIMG Image Resizer

Post by DavidIQ »

The attachment seems to be working fine from what I can see. The img tag seems to not be though. However you have placed some restrictions on accessing files directly so I can't really tell you what's missing. I would look at http://darkrelic.com/player-network/for ... bcode.html since it looks like attachments are at least working. Also, as per the user a few posts above, I would re-check the imageset.cfg file to make sure the reimg edits are done correctly and then refresh the imageset for your darkrelic style.
Apply to become a Jr. Extension Validator
My extensions | In need of phpBB services? | Was I helpful today?
No unsolicited PMs unless you're planning on asking for paid help.
Sarrene
Registered User
Posts: 79
Joined: Wed Jan 23, 2008 10:20 am
Name: Sarrene Grant
Contact:

Re: ReIMG Image Resizer

Post by Sarrene »

I have done that a few times..And refreshed more times then I can think. From template, to imageset. Here are two fo the files. If you need more, let me know.

Thank you again so much for helping me.

imageset.cfg

Code: Select all

#
# phpBB Imageset Configuration File
#
# @package phpBB3
# @copyright (c) 2005 phpBB Group 
# @license http://opensource.org/licenses/gpl-license.php GNU Public License 
#
#
# At the left is the name, please do not change this
# At the right the value is entered
# For on/off options the valid values are on, off, 1, 0, true and false
#
# Values get trimmed, if you want to add a space in front or at the end of
# the value, then enclose the value with single or double quotes. 
# Single and double quotes do not need to be escaped.
#
#

# General Information about this style
name = darkrelic
copyright = AVI Graphics LLC, Triad Game Studios LLC
version = 1.1.44

# Images 
img_upload_bar = upload_bar.gif*16*280
img_poll_left = poll_left.gif*12*4
img_poll_center = poll_center.gif*12*1
img_poll_right = poll_right.gif*12*4

img_forum_link = forum_link.png*27*27
img_forum_read = forum_read.png*27*27
img_forum_read_locked = forum_read_locked.png*27*27
img_forum_read_subforum = forum_read_subforum.png*27*27
img_forum_unread = forum_unread.png*27*27
img_forum_unread_locked = forum_unread_locked.png*27*27
img_forum_unread_subforum = forum_unread_subforum.png*27*27

img_topic_moved = topic_moved.png*27*27

img_topic_read = topic_read.png*27*27
img_topic_read_mine = topic_read_mine.png*27*27
img_topic_read_hot = topic_read_hot.png*27*27
img_topic_read_hot_mine = topic_read_hot_mine.png*27*27
img_topic_read_locked = topic_read_locked.png*27*27
img_topic_read_locked_mine = topic_read_locked_mine.png*27*27

img_topic_unread = topic_unread.png*27*27
img_topic_unread_mine = topic_unread_mine.png*27*27
img_topic_unread_hot = topic_unread_hot.png*27*27
img_topic_unread_hot_mine = topic_unread_hot_mine.png*27*27
img_topic_unread_locked = topic_unread_locked.png*27*27
img_topic_unread_locked_mine = topic_unread_locked_mine.png*27*27

img_sticky_read = sticky_read.png*27*27
img_sticky_read_mine = sticky_read_mine.png*27*27
img_sticky_read_locked = sticky_read_locked.png*27*27
img_sticky_read_locked_mine = sticky_read_locked_mine.png*27*27
img_sticky_unread = sticky_unread.png*27*27
img_sticky_unread_mine = sticky_unread_mine.png*27*27
img_sticky_unread_locked = sticky_unread_locked.png*27*27
img_sticky_unread_locked_mine = sticky_unread_locked_mine.png*27*27

img_announce_read = announce_read.png*27*27
img_announce_read_mine = announce_read_mine.png*27*27
img_announce_read_locked = announce_read_locked.png*27*27
img_announce_read_locked_mine = announce_read_locked_mine.png*27*27
img_announce_unread = announce_unread.png*27*27
img_announce_unread_mine = announce_unread_mine.png*27*27
img_announce_unread_locked = announce_unread_locked.png*27*27
img_announce_unread_locked_mine = announce_unread_locked_mine.png*27*27

img_global_read = announce_read.png*27*27
img_global_read_mine = announce_read_mine.png*27*27
img_global_read_locked = announce_read_locked.png*27*27
img_global_read_locked_mine = announce_read_locked_mine.png*27*27
img_global_unread = announce_unread.png*27*27
img_global_unread_mine = announce_unread_mine.png*27*27
img_global_unread_locked = announce_unread_locked.png*27*27
img_global_unread_locked_mine = announce_unread_locked_mine.png*27*27

img_subforum_read = 
img_subforum_unread = 

img_pm_read = topic_read.png*27*27
img_pm_unread = topic_unread.png*27*27

img_icon_back_top =

img_icon_post_target = icon_post_target.gif*9*11
img_icon_post_target_unread = icon_post_target_unread.gif*9*11

img_icon_topic_attach = icon_topic_attach.gif*18*14
img_icon_topic_latest = icon_topic_latest.gif*9*11
img_icon_topic_newest = icon_topic_newest.gif*9*11
img_icon_topic_reported = icon_topic_reported.gif*18*19
img_icon_topic_unapproved = icon_topic_unapproved.gif*18*19

img_icon_reimg_loading = icon_reimg_loading.gif*16*16
img_icon_reimg_zoom_in = icon_reimg_zoom_in.gif*15*18
img_icon_reimg_zoom_out = icon_reimg_zoom_out.gif*15*18
viewtopic_print.html

Code: Select all

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}">
<head>
<meta http-equiv="Content-Type" content="text/html; charset={S_CONTENT_ENCODING}">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Language" content="{S_USER_LANG}">
<title>{SITENAME} :: {PAGE_TITLE}</title>
<!-- INCLUDE reimg_content.html -->
<style type="text/css">
<!--

body {
	font-family: Verdana,serif;
	font-size: 10pt;
}

img {
	border: 0;
}

td {
	font-family: Verdana,serif;
	font-size: 10pt;
	line-height: 150%;
}

.code, .codecontent, 
.quote, .quotecontent {
	margin: 0 5px 0 5px;
	padding: 5px;
	font-size: smaller;
	border: black solid 1px;
}

.quotetitle {
	color: black;
	display : block;
	font-weight: bold;
}

.forum {
	font-family: Arial,Helvetica,sans-serif;
	font-weight: bold;
	font-size: 18pt;
}

.topic {
	font-family: Arial,Helvetica,sans-serif;
	font-size: 14pt;
	font-weight: bold;
}

.gensmall {
	font-size: 8pt;
}

hr {
	color: #888;
	height: 3px;
	border-style: solid;
}

hr.sep {
	color: #aaa;
	height: 1px;
	border-style: dashed;
}
//-->
</style>

</head>
<body>

<table width="85%" cellspacing="3" cellpadding="0" border="0" align="center">
<tr>
	<td colspan="2" align="center"><span class="Forum">{SITENAME}</span><br /><span class="gensmall"><a href="{U_FORUM}">{U_FORUM}</a></span></td>
</tr>
<tr>
	<td colspan="2"><br /></td>
</tr>
<tr>
	<td><span class="topic">{TOPIC_TITLE}</span><br /><span class="gensmall"><a href="{U_TOPIC}">{U_TOPIC}</a></span></td>
	<td align="{S_CONTENT_FLOW_END}" valign="bottom"><span class="gensmall">{PAGE_NUMBER}</span></td>
</tr>
</table>

<!-- BEGIN postrow -->

	<hr width="85%" />

	<table width="85%" cellspacing="3" cellpadding="0" border="0" align="center">
	<tr>
		<td width="10%" nowrap="nowrap">{L_AUTHOR}:&nbsp;</td>
		<td><b>{postrow.POST_AUTHOR}</b> [ {postrow.POST_DATE} ]</td>	</tr>
	<tr>
		<td width="10%" nowrap="nowrap">{L_POST_SUBJECT}:&nbsp;</td>
		<td><b>{postrow.POST_SUBJECT}</b></td>
	</tr>
	<tr>
		<td colspan="2"><hr class="sep" />{postrow.MESSAGE}

		<!-- IF postrow.S_HAS_ATTACHMENTS -->
			<br clear="all" /><br />

			<table class="tablebg" width="100%" cellspacing="1">
			<tr>
				<td><b class="genmed">{L_ATTACHMENTS}: </b></td>
			</tr>
			<!-- BEGIN attachment -->
				<tr>
					<td>{postrow.attachment.DISPLAY_ATTACHMENT}</td>
				</tr>
			<!-- END attachment -->
			</table>
		<!-- ENDIF -->

		</td>
	</tr>
	</table>
<!-- END postrow -->

<hr width="85%" />
<!--
	We request you retain the full copyright notice below including the link to www.phpbb.com.
	This not only gives respect to the large amount of time given freely by the developers
	but also helps build interest, traffic and use of phpBB3. If you (honestly) cannot retain
	the full copyright we ask you at least leave in place the "Powered by phpBB" line. If you
	refuse to include even this then support on our forums may be affected.

	The phpBB Group : 2006
// -->

<table width="85%" cellspacing="3" cellpadding="0" border="0" align="center">
<tr>
	<td><span class="gensmall">{PAGE_NUMBER}</span></td>
	<td align="{S_CONTENT_FLOW_END}"><span class="gensmall">{S_TIMEZONE}</span></td>
</tr>
<tr>
	<td colspan="2" align="center"><span class="gensmall">Powered by phpBB &copy; 2000, 2002, 2005, 2007 phpBB Group<br />http://www.phpbb.com/</span></td>
</tr>
</table>

</body>
</html>
bbcode.html:

Code: Select all

<!-- BEGIN ulist_open --><ul style="list-style-type: {LIST_TYPE}"><!-- END ulist_open -->
<!-- BEGIN ulist_open_default --><ul><!-- END ulist_open_default -->
<!-- BEGIN ulist_close --></ul><!-- END ulist_close -->

<!-- BEGIN olist_open --><ol style="list-style-type: {LIST_TYPE}"><!-- END olist_open -->
<!-- BEGIN olist_close --></ol><!-- END olist_close -->

<!-- BEGIN listitem --><li><!-- END listitem -->
<!-- BEGIN listitem_close --></li><!-- END listitem_close -->

<!-- BEGIN quote_username_open -->
<div class="quotetitle">{USERNAME} {L_WROTE}:</div><div class="quotecontent">
<!-- END quote_username_open -->

<!-- BEGIN quote_open -->
<div class="quotetitle"><b>{L_QUOTE}:</b></div><div class="quotecontent">
<!-- END quote_open -->

<!-- BEGIN quote_close -->
</div>
<!-- END quote_close -->

<!-- BEGIN code_open -->
<div class="codetitle"><b>{L_CODE}:</b></div><div class="codecontent">
<!-- END code_open -->

<!-- BEGIN code_close -->
</div>
<!-- END code_close -->

<!-- BEGIN inline_attachment_open -->
<div class="attachtitle">{L_ATTACHMENT}:</div><div class="attachcontent">
<!-- END inline_attachment_open -->

<!-- BEGIN inline_attachment_close -->
</div>
<!-- END inline_attachment_close -->


<!-- BEGIN b_open --><strong><!-- END b_open -->
<!-- BEGIN b_close --></strong><!-- END b_close -->

<!-- BEGIN u_open --><span style="text-decoration: underline"><!-- END u_open -->
<!-- BEGIN u_close --></span><!-- END u_close -->

<!-- BEGIN i_open --><em><!-- END i_open -->
<!-- BEGIN i_close --></em><!-- END i_close -->

<!-- BEGIN color --><span style="color: {COLOR}">{TEXT}</span><!-- END color -->

<!-- BEGIN size --><span style="font-size: {SIZE}%; line-height: normal">{TEXT}</span><!-- END size -->

<!-- BEGIN img --><img src="{URL}" alt="{L_IMAGE}" {REIMG_PROPERTIES} /><!-- END img -->

<!-- BEGIN url --><a href="{URL}" class="postlink">{DESCRIPTION}</a><!-- END url -->

<!-- BEGIN email --><a href="mailto:{EMAIL}">{DESCRIPTION}</a><!-- END email -->

<!-- BEGIN flash -->
	<object classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=5,0,0,0" width="{WIDTH}" height="{HEIGHT}">
		<param name="movie" value="{URL}" />
		<param name="play" value="false" />
		<param name="loop" value="false" />
		<param name="quality" value="high" />
		<param name="allowScriptAccess" value="never" />
		<param name="allowNetworking" value="internal" />
		<embed src="{URL}" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" width="{WIDTH}" height="{HEIGHT}" play="false" loop="false" quality="high" allowscriptaccess="never" allownetworking="internal"></embed>
	</object>
<!-- END flash -->
User avatar
DavidIQ
Customisations Team Leader
Customisations Team Leader
Posts: 18282
Joined: Thu Jan 06, 2005 1:30 pm
Location: Fishkill, NY
Name: David Colón
Contact:

Re: ReIMG Image Resizer

Post by DavidIQ »

Those look fine. What about includes/bbcode.php and includes/acp/acp_styles.php?
Apply to become a Jr. Extension Validator
My extensions | In need of phpBB services? | Was I helpful today?
No unsolicited PMs unless you're planning on asking for paid help.
Sarrene
Registered User
Posts: 79
Joined: Wed Jan 23, 2008 10:20 am
Name: Sarrene Grant
Contact:

Re: ReIMG Image Resizer

Post by Sarrene »

Okay, here we go.. You might have a better chance at finding out what I messed up on .. two sets of eyes are better then one, eh? As always, Thank you for helping. I dont know why this is so difficult fro some, let alone me lol.

includes/bbcode.php:

Code: Select all

<?php
/**
*
* @package phpBB3
* @version $Id$
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
	exit;
}

/**
* BBCode class
* @package phpBB3
*/
class bbcode
{
	var $bbcode_uid = '';
	var $bbcode_bitfield = '';
	var $bbcode_cache = array();
	var $bbcode_template = array();

	var $bbcodes = array();

	var $template_bitfield;
	var $template_filename = '';

	/**
	* Constructor
	* Init bbcode cache entries if bitfield is specified
	*/
	function bbcode($bitfield = '')
	{
		if ($bitfield)
		{
			$this->bbcode_bitfield = $bitfield;
			$this->bbcode_cache_init();
		}
	}

	/**
	* Second pass bbcodes
	*/
	function bbcode_second_pass(&$message, $bbcode_uid = '', $bbcode_bitfield = false)
	{
	$matchs = array (
			'#\[img(.*?)\](.*?)\[\/img(.*?)\]#is' => '<img src="\\2" alt="" />',
			'#\[color=(.*?)\]#is'				  => '<span style="color:\\1;">',
			'#\[highlight=(.*?)\]#is'				  => '<span style="background-color:\\1;">',
			'#\[font=(.*?)\]#is'				  => '<span style="font-family:\\1;">',
			'#\[\/(font|color|size|highlight)(.*?)\]#is'    => '</span>',
			'#\[size=1(.*?)\]#is'    => '[size=85]',
			'#\[size=2(.*?)\]#is'    => '[size=100]',
			'#\[size=3(.*?)\]#is'    => '[size=150]',
			'#\[size=4(.*?)\]#is'    => '[size=175]',
			'#\[size=5(.*?)\]#is'    => '[size=200]',
			'#\[size=6(.*?)\]#is'    => '[size=210]',
			'#\[size=7(.*?)\]#is'    => '[size=220]',
			'#\[size=([0-9]{2,3}+)(.*?)\]#is'    => '<span style="font-size: \\1%; line-height: 116%;">',
			'#\[table\]#is'    => '<table style="width: 100%; padding: 0px;border:1px dotted gray;">',
			'#\[td\]#is'    => '<td style="font-size: 20px; display:table-cell;padding:1px;vertical-align:inherit;border:1px dotted #CCCCCC;">',
			'#\[tr\]#is'    => '<tr>',
			'#\[\/tr\]#is'    => '</tr>',
			'#\[\/td\]#is'    => '</td>',
			'#\[\/table\]#is'    => '</table>',
			'#\[(indent|blockquote)\]#is'    => '<blockquote class="editor">',
			'#\[\/(indent|blockquote)\]#is'    => '</blockquote>',			
			'#\[size=(.*?)\]#is'    => '',
			);
		$message = preg_replace(array_keys($matchs), array_values($matchs), $message);
		if ($bbcode_uid)
		{
			$this->bbcode_uid = $bbcode_uid;
		}

		if ($bbcode_bitfield !== false)
		{
			$this->bbcode_bitfield = $bbcode_bitfield;

			// Init those added with a new bbcode_bitfield (already stored codes will not get parsed again)
			$this->bbcode_cache_init();
		}

		if (!$this->bbcode_bitfield)
		{
			// Remove the uid from tags that have not been transformed into HTML
			if ($this->bbcode_uid)
			{
				$message = str_replace(':' . $this->bbcode_uid, '', $message);
			}

			return;
		}

		$str = array('search' => array(), 'replace' => array());
		$preg = array('search' => array(), 'replace' => array());

		$bitfield = new bitfield($this->bbcode_bitfield);
		$bbcodes_set = $bitfield->get_all_set();

		$undid_bbcode_specialchars = false;
		foreach ($bbcodes_set as $bbcode_id)
		{
			if (!empty($this->bbcode_cache[$bbcode_id]))
			{
				foreach ($this->bbcode_cache[$bbcode_id] as $type => $array)
				{
					foreach ($array as $search => $replace)
					{
						${$type}['search'][] = str_replace('$uid', $this->bbcode_uid, $search);
						${$type}['replace'][] = $replace;
					}

					if (sizeof($str['search']))
					{
						$message = str_replace($str['search'], $str['replace'], $message);
						$str = array('search' => array(), 'replace' => array());
					}

					if (sizeof($preg['search']))
					{
						// we need to turn the entities back into their original form to allow the
						// search patterns to work properly
						if (!$undid_bbcode_specialchars)
						{
							$message = str_replace(array('&#58;', '&#46;'), array(':', '.'), $message);
							$undid_bbcode_specialchars = true;
						}

						$message = preg_replace($preg['search'], $preg['replace'], $message);
						$preg = array('search' => array(), 'replace' => array());
					}
				}
			}
		}

		// Remove the uid from tags that have not been transformed into HTML
		$message = str_replace(':' . $this->bbcode_uid, '', $message);
	}

	/**
	* Init bbcode cache
	*
	* requires: $this->bbcode_bitfield
	* sets: $this->bbcode_cache with bbcode templates needed for bbcode_bitfield
	*/
	function bbcode_cache_init()
	{
		global $phpbb_root_path, $template, $user;

		if (empty($this->template_filename))
		{
			$this->template_bitfield = new bitfield($user->theme['bbcode_bitfield']);
			$this->template_filename = $phpbb_root_path . 'styles/' . $user->theme['template_path'] . '/template/bbcode.html';

			if (!@file_exists($this->template_filename))
			{
				if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'])
				{
					$this->template_filename = $phpbb_root_path . 'styles/' . $user->theme['template_inherit_path'] . '/template/bbcode.html';
					if (!@file_exists($this->template_filename))
					{
						trigger_error('The file ' . $this->template_filename . ' is missing.', E_USER_ERROR);
					}
				}
				else
				{
					trigger_error('The file ' . $this->template_filename . ' is missing.', E_USER_ERROR);
				}
			}
		}

		$bbcode_ids = $rowset = $sql = array();

		$bitfield = new bitfield($this->bbcode_bitfield);
		$bbcodes_set = $bitfield->get_all_set();

		foreach ($bbcodes_set as $bbcode_id)
		{
			if (isset($this->bbcode_cache[$bbcode_id]))
			{
				// do not try to re-cache it if it's already in
				continue;
			}
			$bbcode_ids[] = $bbcode_id;

			if ($bbcode_id > NUM_CORE_BBCODES)
			{
				$sql[] = $bbcode_id;
			}
		}

		if (sizeof($sql))
		{
			global $db;

			$sql = 'SELECT *
				FROM ' . BBCODES_TABLE . '
				WHERE ' . $db->sql_in_set('bbcode_id', $sql);
			$result = $db->sql_query($sql, 3600);

			while ($row = $db->sql_fetchrow($result))
			{
				// To circumvent replacing newlines with <br /> for the generated html,
				// we use carriage returns here. They are later changed back to newlines
				$row['bbcode_tpl'] = str_replace("\n", "\r", $row['bbcode_tpl']);
				$row['second_pass_replace'] = str_replace("\n", "\r", $row['second_pass_replace']);

				$rowset[$row['bbcode_id']] = $row;
			}
			$db->sql_freeresult($result);
		}

		foreach ($bbcode_ids as $bbcode_id)
		{
			switch ($bbcode_id)
			{
				case 0:
					$this->bbcode_cache[$bbcode_id] = array(
						'str' => array(
							'[/quote:$uid]'	=> $this->bbcode_tpl('quote_close', $bbcode_id)
						),
						'preg' => array(
							'#\[quote(?:="(.*?)")?:$uid\]((?!\[quote(?:=".*?")?:$uid\]).)?#ise'	=> "\$this->bbcode_second_pass_quote('\$1', '\$2')"
						)
					);
				break;

				case 1:
					$this->bbcode_cache[$bbcode_id] = array(
						'str' => array(
							'[b:$uid]'	=> $this->bbcode_tpl('b_open', $bbcode_id),
							'[/b:$uid]'	=> $this->bbcode_tpl('b_close', $bbcode_id),
						)
					);
				break;

				case 2:
					$this->bbcode_cache[$bbcode_id] = array(
						'str' => array(
							'[i:$uid]'	=> $this->bbcode_tpl('i_open', $bbcode_id),
							'[/i:$uid]'	=> $this->bbcode_tpl('i_close', $bbcode_id),
						)
					);
				break;

				case 3:
					$this->bbcode_cache[$bbcode_id] = array(
						'preg' => array(
							'#\[url:$uid\]((.*?))\[/url:$uid\]#s'			=> $this->bbcode_tpl('url', $bbcode_id),
							'#\[url=([^\[]+?):$uid\](.*?)\[/url:$uid\]#s'	=> $this->bbcode_tpl('url', $bbcode_id),
						)
					);
				break;

				case 4:
					if ($user->optionget('viewimg'))
					{
						$this->bbcode_cache[$bbcode_id] = array(
							'preg' => array(
								'#\[img:$uid\](.*?)\[/img:$uid\]#s'		=> str_replace('$2', reimg_properties(), $this->bbcode_tpl('img', $bbcode_id)),
							)
						);
					}
					else
					{
						$this->bbcode_cache[$bbcode_id] = array(
							'preg' => array(
								'#\[img:$uid\](.*?)\[/img:$uid\]#s'		=> str_replace('$2', '[ img ]', $this->bbcode_tpl('url', $bbcode_id, true)),
							)
						);
					}
				break;

				case 5:
					$this->bbcode_cache[$bbcode_id] = array(
						'preg' => array(
							'#\[size=([\-\+]?\d+):$uid\](.*?)\[/size:$uid\]#s'	=> $this->bbcode_tpl('size', $bbcode_id),
						)
					);
				break;

				case 6:
					$this->bbcode_cache[$bbcode_id] = array(
						'preg' => array(
							'!\[color=(#[0-9a-f]{3}|#[0-9a-f]{6}|[a-z\-]+):$uid\](.*?)\[/color:$uid\]!is'	=> $this->bbcode_tpl('color', $bbcode_id),
						)
					);
				break;

				case 7:
					$this->bbcode_cache[$bbcode_id] = array(
						'str' => array(
							'[u:$uid]'	=> $this->bbcode_tpl('u_open', $bbcode_id),
							'[/u:$uid]'	=> $this->bbcode_tpl('u_close', $bbcode_id),
						)
					);
				break;

				case 8:
					$this->bbcode_cache[$bbcode_id] = array(
						'preg' => array(
							'#\[code(?:=([a-z]+))?:$uid\](.*?)\[/code:$uid\]#ise'	=> "\$this->bbcode_second_pass_code('\$1', '\$2')",
						)
					);
				break;

				case 9:
					$this->bbcode_cache[$bbcode_id] = array(
						'preg' => array(
							'#(\[\/?(list|\*):[mou]?:?$uid\])[\n]{1}#'	=> "\$1",
							'#(\[list=([^\[]+):$uid\])[\n]{1}#'			=> "\$1",
							'#\[list=([^\[]+):$uid\]#e'					=> "\$this->bbcode_list('\$1')",
						),
						'str' => array(
							'[list:$uid]'		=> $this->bbcode_tpl('ulist_open_default', $bbcode_id),
							'[/list:u:$uid]'	=> $this->bbcode_tpl('ulist_close', $bbcode_id),
							'[/list:o:$uid]'	=> $this->bbcode_tpl('olist_close', $bbcode_id),
							'[*:$uid]'			=> $this->bbcode_tpl('listitem', $bbcode_id),
							'[/*:$uid]'			=> $this->bbcode_tpl('listitem_close', $bbcode_id),
							'[/*:m:$uid]'		=> $this->bbcode_tpl('listitem_close', $bbcode_id)
						),
					);
				break;

				case 10:
					$this->bbcode_cache[$bbcode_id] = array(
						'preg' => array(
							'#\[email:$uid\]((.*?))\[/email:$uid\]#is'			=> $this->bbcode_tpl('email', $bbcode_id),
							'#\[email=([^\[]+):$uid\](.*?)\[/email:$uid\]#is'	=> $this->bbcode_tpl('email', $bbcode_id)
						)
					);
				break;

				case 11:
					if ($user->optionget('viewflash'))
					{
						$this->bbcode_cache[$bbcode_id] = array(
							'preg' => array(
								'#\[flash=([0-9]+),([0-9]+):$uid\](.*?)\[/flash:$uid\]#'	=> $this->bbcode_tpl('flash', $bbcode_id),
							)
						);
					}
					else
					{
						$this->bbcode_cache[$bbcode_id] = array(
							'preg' => array(
								'#\[flash=([0-9]+),([0-9]+):$uid\](.*?)\[/flash:$uid\]#'	=> str_replace('$1', '$3', str_replace('$2', '[ flash ]', $this->bbcode_tpl('url', $bbcode_id, true)))
							)
						);
					}
				break;

				case 12:
					$this->bbcode_cache[$bbcode_id] = array(
						'str'	=> array(
							'[/attachment:$uid]'	=> $this->bbcode_tpl('inline_attachment_close', $bbcode_id)
						),
						'preg'	=> array(
							'#\[attachment=([0-9]+):$uid\]#'	=> $this->bbcode_tpl('inline_attachment_open', $bbcode_id)
						)
					);
				break;

				default:
					if (isset($rowset[$bbcode_id]))
					{
						if ($this->template_bitfield->get($bbcode_id))
						{
							// The bbcode requires a custom template to be loaded
							if (!$bbcode_tpl = $this->bbcode_tpl($rowset[$bbcode_id]['bbcode_tag'], $bbcode_id))
							{
								// For some reason, the required template seems not to be available, use the default template
								$bbcode_tpl = (!empty($rowset[$bbcode_id]['second_pass_replace'])) ? $rowset[$bbcode_id]['second_pass_replace'] : $rowset[$bbcode_id]['bbcode_tpl'];
							}
							else
							{
								// In order to use templates with custom bbcodes we need
								// to replace all {VARS} to corresponding backreferences
								// Note that backreferences are numbered from bbcode_match
								if (preg_match_all('/\{(URL|LOCAL_URL|EMAIL|TEXT|SIMPLETEXT|INTTEXT|IDENTIFIER|COLOR|NUMBER)[0-9]*\}/', $rowset[$bbcode_id]['bbcode_match'], $m))
								{
									foreach ($m[0] as $i => $tok)
									{
										$bbcode_tpl = str_replace($tok, '$' . ($i + 1), $bbcode_tpl);
									}
								}
							}
						}
						else
						{
							// Default template
							$bbcode_tpl = (!empty($rowset[$bbcode_id]['second_pass_replace'])) ? $rowset[$bbcode_id]['second_pass_replace'] : $rowset[$bbcode_id]['bbcode_tpl'];
						}

						// Replace {L_*} lang strings
						$bbcode_tpl = preg_replace('/{L_([A-Z_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $bbcode_tpl);

						if (!empty($rowset[$bbcode_id]['second_pass_replace']))
						{
							// The custom BBCode requires second-pass pattern replacements
							$this->bbcode_cache[$bbcode_id] = array(
								'preg' => array($rowset[$bbcode_id]['second_pass_match'] => $bbcode_tpl)
							);
						}
						else
						{
							$this->bbcode_cache[$bbcode_id] = array(
								'str' => array($rowset[$bbcode_id]['second_pass_match'] => $bbcode_tpl)
							);
						}
					}
					else
					{
						$this->bbcode_cache[$bbcode_id] = false;
					}
				break;
			}
		}
	}

	/**
	* Return bbcode template
	*/
	function bbcode_tpl($tpl_name, $bbcode_id = -1, $skip_bitfield_check = false)
	{
		static $bbcode_hardtpl = array();
		if (empty($bbcode_hardtpl))
		{
			global $user;

			$bbcode_hardtpl = array(
				'b_open'	=> '<span style="font-weight: bold">',
				'b_close'	=> '</span>',
				'i_open'	=> '<span style="font-style: italic">',
				'i_close'	=> '</span>',
				'u_open'	=> '<span style="text-decoration: underline">',
				'u_close'	=> '</span>',
				'img'		=> '<img src="$1" alt="' . $user->lang['IMAGE'] . '" ' . reimg_properties() . '/>',
				'size'		=> '<span style="font-size: $1%; line-height: normal">$2</span>',
				'color'		=> '<span style="color: $1">$2</span>',
				'email'		=> '<a href="mailto:$1">$2</a>'
			);
		}

		if ($bbcode_id != -1 && !$skip_bitfield_check && !$this->template_bitfield->get($bbcode_id))
		{
			return (isset($bbcode_hardtpl[$tpl_name])) ? $bbcode_hardtpl[$tpl_name] : false;
		}

		if (empty($this->bbcode_template))
		{
			if (($tpl = file_get_contents($this->template_filename)) === false)
			{
				trigger_error('Could not load bbcode template', E_USER_ERROR);
			}

			// replace \ with \\ and then ' with \'.
			$tpl = str_replace('\\', '\\\\', $tpl);
			$tpl = str_replace("'", "\'", $tpl);

			// strip newlines and indent
			$tpl = preg_replace("/\n[\n\r\s\t]*/", '', $tpl);

			// Turn template blocks into PHP assignment statements for the values of $bbcode_tpl..
			$this->bbcode_template = array();

			$matches = preg_match_all('#<!-- BEGIN (.*?) -->(.*?)<!-- END (?:.*?) -->#', $tpl, $match);

			for ($i = 0; $i < $matches; $i++)
			{
				if (empty($match[1][$i]))
				{
					continue;
				}

				$this->bbcode_template[$match[1][$i]] = $this->bbcode_tpl_replace($match[1][$i], $match[2][$i]);
			}
		}

		return (isset($this->bbcode_template[$tpl_name])) ? $this->bbcode_template[$tpl_name] : ((isset($bbcode_hardtpl[$tpl_name])) ? $bbcode_hardtpl[$tpl_name] : false);
	}

	/**
	* Return bbcode template replacement
	*/
	function bbcode_tpl_replace($tpl_name, $tpl)
	{
		global $user;

		static $replacements = array(
			'quote_username_open'	=> array('{USERNAME}'	=> '$1'),
			'color'					=> array('{COLOR}'		=> '$1', '{TEXT}'			=> '$2'),
			'size'					=> array('{SIZE}'		=> '$1', '{TEXT}'			=> '$2'),
			'img'					=> array('{URL}'		=> '$1', '{REIMG_PROPERTIES}'	=> '$2'),
			'flash'					=> array('{WIDTH}'		=> '$1', '{HEIGHT}'			=> '$2', '{URL}'	=> '$3'),
			'url'					=> array('{URL}'		=> '$1', '{DESCRIPTION}'	=> '$2'),
			'email'					=> array('{EMAIL}'		=> '$1', '{DESCRIPTION}'	=> '$2')
		);

		$tpl = preg_replace('/{L_([A-Z_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $tpl);

		if (!empty($replacements[$tpl_name]))
		{
			$tpl = strtr($tpl, $replacements[$tpl_name]);
		}

		return trim($tpl);
	}

	/**
	* Second parse list bbcode
	*/
	function bbcode_list($type)
	{
		if ($type == '')
		{
			$tpl = 'ulist_open_default';
			$type = 'default';
		}
		else if ($type == 'i')
		{
			$tpl = 'olist_open';
			$type = 'lower-roman';
		}
		else if ($type == 'I')
		{
			$tpl = 'olist_open';
			$type = 'upper-roman';
		}
		else if (preg_match('#^(disc|circle|square)$#i', $type))
		{
			$tpl = 'ulist_open';
			$type = strtolower($type);
		}
		else if (preg_match('#^[a-z]$#', $type))
		{
			$tpl = 'olist_open';
			$type = 'lower-alpha';
		}
		else if (preg_match('#[A-Z]#', $type))
		{
			$tpl = 'olist_open';
			$type = 'upper-alpha';
		}
		else if (is_numeric($type))
		{
			$tpl = 'olist_open';
			$type = 'decimal';
		}
		else
		{
			$tpl = 'olist_open';
			$type = 'decimal';
		}

		return str_replace('{LIST_TYPE}', $type, $this->bbcode_tpl($tpl));
	}

	/**
	* Second parse quote tag
	*/
	function bbcode_second_pass_quote($username, $quote)
	{
		// when using the /e modifier, preg_replace slashes double-quotes but does not
		// seem to slash anything else
		$quote = str_replace('\"', '"', $quote);
		$username = str_replace('\"', '"', $username);

		// remove newline at the beginning
		if ($quote == "\n")
		{
			$quote = '';
		}

		$quote = (($username) ? str_replace('$1', $username, $this->bbcode_tpl('quote_username_open')) : $this->bbcode_tpl('quote_open')) . $quote;

		return $quote;
	}

	/**
	* Second parse code tag
	*/
	function bbcode_second_pass_code($type, $code)
	{
		// when using the /e modifier, preg_replace slashes double-quotes but does not
		// seem to slash anything else
		$code = str_replace('\"', '"', $code);

		switch ($type)
		{
			case 'php':
				// Not the english way, but valid because of hardcoded syntax highlighting
				if (strpos($code, '<span class="syntaxdefault"><br /></span>') === 0)
				{
					$code = substr($code, 41);
				}

			// no break;

			default:
				$code = str_replace("\t", '&nbsp; &nbsp;', $code);
				$code = str_replace('  ', '&nbsp; ', $code);
				$code = str_replace('  ', ' &nbsp;', $code);

				// remove newline at the beginning
				if (!empty($code) && $code[0] == "\n")
				{
					$code = substr($code, 1);
				}
			break;
		}

		$code = $this->bbcode_tpl('code_open') . $code . $this->bbcode_tpl('code_close');

		return $code;
	}
}

?>
includes/acp/acp_styles.php:

Code: Select all

<?php
/**
*
* @package acp
* @version $Id$
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
	exit;
}

/**
* @package acp
*/
class acp_styles
{
	var $u_action;

	var $style_cfg;
	var $template_cfg;
	var $theme_cfg;
	var $imageset_cfg;
	var $imageset_keys;

	function main($id, $mode)
	{
		global $db, $user, $auth, $template, $cache;
		global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;

		// Hardcoded template bitfield to add for new templates
		$bitfield = new bitfield();
		$bitfield->set(0);
		$bitfield->set(1);
		$bitfield->set(2);
		$bitfield->set(3);
		$bitfield->set(4);
		$bitfield->set(8);
		$bitfield->set(9);
		$bitfield->set(11);
		$bitfield->set(12);
		define('TEMPLATE_BITFIELD', $bitfield->get_base64());
		unset($bitfield);

		$user->add_lang('acp/styles');
		$user->add_lang('mods/reimg');
		$this->tpl_name = 'acp_styles';
		$this->page_title = 'ACP_CAT_STYLES';

		$action = request_var('action', '');
		$action = (isset($_POST['add'])) ? 'add' : $action;
		$style_id = request_var('id', 0);

		// Fill the configuration variables
		$this->style_cfg = $this->template_cfg = $this->theme_cfg = $this->imageset_cfg = '
#
# phpBB {MODE} configuration file
#
# @package phpBB3
# @copyright (c) 2005 phpBB Group
# @license http://opensource.org/licenses/gpl-license.php GNU Public License
#
#
# At the left is the name, please do not change this
# At the right the value is entered
# For on/off options the valid values are on, off, 1, 0, true and false
#
# Values get trimmed, if you want to add a space in front or at the end of
# the value, then enclose the value with single or double quotes.
# Single and double quotes do not need to be escaped.
#
#

# General Information about this {MODE}
name = {NAME}
copyright = {COPYRIGHT}
version = {VERSION}
';

		$this->theme_cfg .= '
# Some configuration options

#
# You have to turn this option on if you want to use the
# path template variables ({T_IMAGESET_PATH} for example) within
# your css file.
# This is mostly the case if you want to use language specific
# images within your css file.
#
parse_css_file = {PARSE_CSS_FILE}
';

		$this->template_cfg .= '
# Some configuration options

#
# You can use this function to inherit templates from another template.
# The template of the given name has to be installed.
# Templates cannot inherit from inheriting templates.
#';

		$this->imageset_keys = array(
			'logos' => array(
				'site_logo',
			),
			'buttons'	=> array(
				'icon_back_top', 				
				'icon_reimg_loading', 'icon_reimg_zoom_in', 'icon_reimg_zoom_out','icon_contact_aim', 'icon_contact_email', 'icon_contact_icq', 'icon_contact_jabber', 'icon_contact_msnm', 'icon_contact_pm', 'icon_contact_yahoo', 'icon_contact_www', 'icon_post_delete', 'icon_post_edit', 'icon_post_info', 'icon_post_quote', 'icon_post_report', 'icon_user_online', 'icon_user_offline', 'icon_user_profile', 'icon_user_search', 'icon_user_warn', 'button_pm_forward', 'button_pm_new', 'button_pm_reply', 'button_topic_locked', 'button_topic_new', 'button_topic_reply',
			),
			'icons'		=> array(
				'icon_post_target', 'icon_post_target_unread', 'icon_topic_attach', 'icon_topic_latest', 'icon_topic_newest', 'icon_topic_reported', 'icon_topic_unapproved', 'icon_friend', 'icon_foe',
			),
			'forums'	=> array(
				'forum_link', 'forum_read', 'forum_read_locked', 'forum_read_subforum', 'forum_unread', 'forum_unread_locked', 'forum_unread_subforum', 'subforum_read', 'subforum_unread'
			),
			'folders'	=> array(
				'topic_moved', 'topic_read', 'topic_read_mine', 'topic_read_hot', 'topic_read_hot_mine', 'topic_read_locked', 'topic_read_locked_mine', 'topic_unread', 'topic_unread_mine', 'topic_unread_hot', 'topic_unread_hot_mine', 'topic_unread_locked', 'topic_unread_locked_mine', 'sticky_read', 'sticky_read_mine', 'sticky_read_locked', 'sticky_read_locked_mine', 'sticky_unread', 'sticky_unread_mine', 'sticky_unread_locked', 'sticky_unread_locked_mine', 'announce_read', 'announce_read_mine', 'announce_read_locked', 'announce_read_locked_mine', 'announce_unread', 'announce_unread_mine', 'announce_unread_locked', 'announce_unread_locked_mine', 'global_read', 'global_read_mine', 'global_read_locked', 'global_read_locked_mine', 'global_unread', 'global_unread_mine', 'global_unread_locked', 'global_unread_locked_mine', 'pm_read', 'pm_unread',
			),
			'polls'		=> array(
				'poll_left', 'poll_center', 'poll_right',
			),
			'ui'		=> array(
				'upload_bar',
			),
			'user'		=> array(
				'user_icon1', 'user_icon2', 'user_icon3', 'user_icon4', 'user_icon5', 'user_icon6', 'user_icon7', 'user_icon8', 'user_icon9', 'user_icon10',
			),
		);

		// Execute overall actions
		switch ($action)
		{
			case 'delete':
				if ($style_id)
				{
					$this->remove($mode, $style_id);
					return;
				}
			break;

			case 'export':
				if ($style_id)
				{
					$this->export($mode, $style_id);
					return;
				}
			break;

			case 'install':
				$this->install($mode);
				return;
			break;

			case 'add':
				$this->add($mode);
				return;
			break;

			case 'details':
				if ($style_id)
				{
					$this->details($mode, $style_id);
					return;
				}
			break;

			case 'edit':
				if ($style_id)
				{
					switch ($mode)
					{
						case 'imageset':
							return $this->edit_imageset($style_id);
						case 'template':
							return $this->edit_template($style_id);
						case 'theme':
							return $this->edit_theme($style_id);
					}
				}
			break;

			case 'cache':
				if ($style_id)
				{
					switch ($mode)
					{
						case 'template':
							return $this->template_cache($style_id);
					}
				}
			break;
		}

		switch ($mode)
		{
			case 'style':

				switch ($action)
				{
					case 'activate':
					case 'deactivate':

						if ($style_id == $config['default_style'])
						{
							trigger_error($user->lang['DEACTIVATE_DEFAULT'] . adm_back_link($this->u_action), E_USER_WARNING);
						}

						if (($action == 'deactivate' && confirm_box(true)) || $action == 'activate')
						{
							$sql = 'UPDATE ' . STYLES_TABLE . '
								SET style_active = ' . (($action == 'activate') ? 1 : 0) . '
								WHERE style_id = ' . $style_id;
							$db->sql_query($sql);

							// Set style to default for any member using deactivated style
							if ($action == 'deactivate')
							{
								$sql = 'UPDATE ' . USERS_TABLE . '
									SET user_style = ' . $config['default_style'] . "
									WHERE user_style = $style_id";
								$db->sql_query($sql);

								$sql = 'UPDATE ' . FORUMS_TABLE . '
									SET forum_style = 0
									WHERE forum_style = ' . $style_id;
								$db->sql_query($sql);
							}
						}
						else if ($action == 'deactivate')
						{
							$s_hidden_fields = array(
								'i'			=> $id,
								'mode'		=> $mode,
								'action'	=> $action,
								'style_id'	=> $style_id,
							);
							confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($s_hidden_fields));
						}
					break;
				}

				$this->frontend('style', array('details'), array('export', 'delete'));
			break;

			case 'template':

				switch ($action)
				{
					// Refresh template data stored in db and clear cache
					case 'refresh':

						$sql = 'SELECT *
							FROM ' . STYLES_TEMPLATE_TABLE . "
							WHERE template_id = $style_id";
						$result = $db->sql_query($sql);
						$template_row = $db->sql_fetchrow($result);
						$db->sql_freeresult($result);

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

						if (confirm_box(true))
						{
							$template_refreshed = '';

							// Only refresh database if the template is stored in the database
							if ($template_row['template_storedb'] && file_exists("{$phpbb_root_path}styles/{$template_row['template_path']}/template/"))
							{
								$filelist = array('' => array());

								$sql = 'SELECT template_filename, template_mtime
									FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
									WHERE template_id = $style_id";
								$result = $db->sql_query($sql);

								while ($row = $db->sql_fetchrow($result))
								{
//									if (@filemtime("{$phpbb_root_path}styles/{$template_row['template_path']}/template/" . $row['template_filename']) > $row['template_mtime'])
//									{
										// get folder info from the filename
										if (($slash_pos = strrpos($row['template_filename'], '/')) === false)
										{
											$filelist[''][] = $row['template_filename'];
										}
										else
										{
											$filelist[substr($row['template_filename'], 0, $slash_pos + 1)][] = substr($row['template_filename'], $slash_pos + 1, strlen($row['template_filename']) - $slash_pos - 1);
										}
//									}
								}
								$db->sql_freeresult($result);

								$this->store_templates('update', $style_id, $template_row['template_path'], $filelist);
								unset($filelist);

								$template_refreshed = $user->lang['TEMPLATE_REFRESHED'] . '<br />';
								add_log('admin', 'LOG_TEMPLATE_REFRESHED', $template_row['template_name']);
							}

							$this->clear_template_cache($template_row);

							trigger_error($template_refreshed . $user->lang['TEMPLATE_CACHE_CLEARED'] . adm_back_link($this->u_action));
						}
						else
						{
							confirm_box(false, ($template_row['template_storedb']) ? $user->lang['CONFIRM_TEMPLATE_REFRESH'] : $user->lang['CONFIRM_TEMPLATE_CLEAR_CACHE'], build_hidden_fields(array(
								'i'			=> $id,
								'mode'		=> $mode,
								'action'	=> $action,
								'id'		=> $style_id
							)));
						}

					break;
				}

				$this->frontend('template', array('edit', 'cache', 'details'), array('refresh', 'export', 'delete'));
			break;

			case 'theme':

				switch ($action)
				{
					// Refresh theme data stored in the database
					case 'refresh':

						$sql = 'SELECT *
							FROM ' . STYLES_THEME_TABLE . "
							WHERE theme_id = $style_id";
						$result = $db->sql_query($sql);
						$theme_row = $db->sql_fetchrow($result);
						$db->sql_freeresult($result);

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

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

						if (confirm_box(true))
						{
							if ($theme_row['theme_storedb'] && file_exists("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"))
							{
								// Save CSS contents
								$sql_ary = array(
									'theme_mtime'	=> (int) filemtime("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"),
									'theme_data'	=> $this->db_theme_data($theme_row)
								);

								$sql = 'UPDATE ' . STYLES_THEME_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
									WHERE theme_id = $style_id";
								$db->sql_query($sql);

								$cache->destroy('sql', STYLES_THEME_TABLE);

								add_log('admin', 'LOG_THEME_REFRESHED', $theme_row['theme_name']);
								trigger_error($user->lang['THEME_REFRESHED'] . adm_back_link($this->u_action));
							}
						}
						else
						{
							confirm_box(false, $user->lang['CONFIRM_THEME_REFRESH'], build_hidden_fields(array(
								'i'			=> $id,
								'mode'		=> $mode,
								'action'	=> $action,
								'id'		=> $style_id
							)));
						}
					break;
				}

				$this->frontend('theme', array('edit', 'details'), array('refresh', 'export', 'delete'));
			break;

			case 'imageset':

				switch ($action)
				{
					case 'refresh':

						$sql = 'SELECT *
							FROM ' . STYLES_IMAGESET_TABLE . "
							WHERE imageset_id = $style_id";
						$result = $db->sql_query($sql);
						$imageset_row = $db->sql_fetchrow($result);
						$db->sql_freeresult($result);

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

						if (confirm_box(true))
						{
							$sql_ary = array();

							$imageset_definitions = array();
							foreach ($this->imageset_keys as $topic => $key_array)
							{
								$imageset_definitions = array_merge($imageset_definitions, $key_array);
							}

							$cfg_data_imageset = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/imageset.cfg");

							$db->sql_transaction('begin');

							$sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . '
								WHERE imageset_id = ' . $style_id;
							$result = $db->sql_query($sql);

							foreach ($cfg_data_imageset as $image_name => $value)
							{
								if (strpos($value, '*') !== false)
								{
									if (substr($value, -1, 1) === '*')
									{
										list($image_filename, $image_height) = explode('*', $value);
										$image_width = 0;
									}
									else
									{
										list($image_filename, $image_height, $image_width) = explode('*', $value);
									}
								}
								else
								{
									$image_filename = $value;
									$image_height = $image_width = 0;
								}

								if (strpos($image_name, 'img_') === 0 && $image_filename)
								{
									$image_name = substr($image_name, 4);
									if (in_array($image_name, $imageset_definitions))
									{
										$sql_ary[] = array(
											'image_name'		=> (string) $image_name,
											'image_filename'	=> (string) $image_filename,
											'image_height'		=> (int) $image_height,
											'image_width'		=> (int) $image_width,
											'imageset_id'		=> (int) $style_id,
											'image_lang'		=> '',
										);
									}
								}
							}

							$sql = 'SELECT lang_dir
								FROM ' . LANG_TABLE;
							$result = $db->sql_query($sql);

							while ($row = $db->sql_fetchrow($result))
							{
								if (@file_exists("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg"))
								{
									$cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$row['lang_dir']}/imageset.cfg");
									foreach ($cfg_data_imageset_data as $image_name => $value)
									{
										if (strpos($value, '*') !== false)
										{
											if (substr($value, -1, 1) === '*')
											{
												list($image_filename, $image_height) = explode('*', $value);
												$image_width = 0;
											}
											else
											{
												list($image_filename, $image_height, $image_width) = explode('*', $value);
											}
										}
										else
										{
											$image_filename = $value;
											$image_height = $image_width = 0;
										}

										if (strpos($image_name, 'img_') === 0 && $image_filename)
										{
											$image_name = substr($image_name, 4);
											if (in_array($image_name, $imageset_definitions))
											{
												$sql_ary[] = array(
													'image_name'		=> (string) $image_name,
													'image_filename'	=> (string) $image_filename,
													'image_height'		=> (int) $image_height,
													'image_width'		=> (int) $image_width,
													'imageset_id'		=> (int) $style_id,
													'image_lang'		=> (string) $row['lang_dir'],
												);
											}
										}
									}
								}
							}
							$db->sql_freeresult($result);

							$db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary);

							$db->sql_transaction('commit');

							$cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);

							add_log('admin', 'LOG_IMAGESET_REFRESHED', $imageset_row['imageset_name']);
							trigger_error($user->lang['IMAGESET_REFRESHED'] . adm_back_link($this->u_action));
						}
						else
						{
							confirm_box(false, $user->lang['CONFIRM_IMAGESET_REFRESH'], build_hidden_fields(array(
								'i'			=> $id,
								'mode'		=> $mode,
								'action'	=> $action,
								'id'		=> $style_id
							)));
						}
					break;
				}

				$this->frontend('imageset', array('edit', 'details'), array('refresh', 'export', 'delete'));
			break;
		}
	}

	/**
	* Build Frontend with supplied options
	*/
	function frontend($mode, $options, $actions)
	{
		global $user, $template, $db, $config, $phpbb_root_path, $phpEx;

		$sql_from = '';
		$style_count = array();

		switch ($mode)
		{
			case 'style':
				$sql_from = STYLES_TABLE;

				$sql = 'SELECT user_style, COUNT(user_style) AS style_count
					FROM ' . USERS_TABLE . '
					GROUP BY user_style';
				$result = $db->sql_query($sql);

				while ($row = $db->sql_fetchrow($result))
				{
					$style_count[$row['user_style']] = $row['style_count'];
				}
				$db->sql_freeresult($result);

			break;

			case 'template':
				$sql_from = STYLES_TEMPLATE_TABLE;
			break;

			case 'theme':
				$sql_from = STYLES_THEME_TABLE;
			break;

			case 'imageset':
				$sql_from = STYLES_IMAGESET_TABLE;
			break;
		}

		$l_prefix = strtoupper($mode);

		$this->page_title = 'ACP_' . $l_prefix . 'S';

		$template->assign_vars(array(
			'S_FRONTEND'		=> true,
			'S_STYLE'			=> ($mode == 'style') ? true : false,

			'L_TITLE'			=> $user->lang[$this->page_title],
			'L_EXPLAIN'			=> $user->lang[$this->page_title . '_EXPLAIN'],
			'L_NAME'			=> $user->lang[$l_prefix . '_NAME'],
			'L_INSTALLED'		=> $user->lang['INSTALLED_' . $l_prefix],
			'L_UNINSTALLED'		=> $user->lang['UNINSTALLED_' . $l_prefix],
			'L_NO_UNINSTALLED'	=> $user->lang['NO_UNINSTALLED_' . $l_prefix],
			'L_CREATE'			=> $user->lang['CREATE_' . $l_prefix],

			'U_ACTION'			=> $this->u_action,
			)
		);

		$sql = "SELECT *
			FROM $sql_from";
		$result = $db->sql_query($sql);

		$installed = array();

		$basis_options = '<option class="sep" value="">' . $user->lang['OPTIONAL_BASIS'] . '</option>';
		while ($row = $db->sql_fetchrow($result))
		{
			$installed[] = $row[$mode . '_name'];
			$basis_options .= '<option value="' . $row[$mode . '_id'] . '">' . $row[$mode . '_name'] . '</option>';

			$stylevis = ($mode == 'style' && !$row['style_active']) ? 'activate' : 'deactivate';

			$s_options = array();
			foreach ($options as $option)
			{
				$s_options[] = '<a href="' . $this->u_action . "&action=$option&id=" . $row[$mode . '_id'] . '">' . $user->lang[strtoupper($option)] . '</a>';
			}

			$s_actions = array();
			foreach ($actions as $option)
			{
				$s_actions[] = '<a href="' . $this->u_action . "&action=$option&id=" . $row[$mode . '_id'] . '">' . $user->lang[strtoupper($option)] . '</a>';
			}

			$template->assign_block_vars('installed', array(
				'S_DEFAULT_STYLE'		=> ($mode == 'style' && $row['style_id'] == $config['default_style']) ? true : false,
				'U_EDIT'				=> $this->u_action . '&action=' . (($mode == 'style') ? 'details' : 'edit') . '&id=' . $row[$mode . '_id'],
				'U_STYLE_ACT_DEACT'		=> $this->u_action . '&action=' . $stylevis . '&id=' . $row[$mode . '_id'],
				'L_STYLE_ACT_DEACT'		=> $user->lang['STYLE_' . strtoupper($stylevis)],
				'S_OPTIONS'				=> implode(' | ', $s_options),
				'S_ACTIONS'				=> implode(' | ', $s_actions),
				'U_PREVIEW'				=> ($mode == 'style') ? append_sid("{$phpbb_root_path}index.$phpEx", "$mode=" . $row[$mode . '_id']) : '',

				'NAME'					=> $row[$mode . '_name'],
				'STYLE_COUNT'			=> ($mode == 'style' && isset($style_count[$row['style_id']])) ? $style_count[$row['style_id']] : 0,
				)
			);
		}
		$db->sql_freeresult($result);

		// Grab uninstalled items
		$new_ary = $cfg = array();

		$dp = @opendir("{$phpbb_root_path}styles");

		if ($dp)
		{
			while (($file = readdir($dp)) !== false)
			{
				if (!is_dir($phpbb_root_path . 'styles/' . $file))
				{
					continue;
				}

				$subpath = ($mode != 'style') ? "$mode/" : '';
				if ($file[0] != '.' && file_exists("{$phpbb_root_path}styles/$file/$subpath$mode.cfg"))
				{
					if ($cfg = file("{$phpbb_root_path}styles/$file/$subpath$mode.cfg"))
					{
						$items = parse_cfg_file('', $cfg);
						$name = (isset($items['name'])) ? trim($items['name']) : false;

						if ($name && !in_array($name, $installed))
						{
							$new_ary[] = array(
								'path'		=> $file,
								'name'		=> $name,
								'copyright'	=> $items['copyright'],
							);
						}
					}
				}
			}
			closedir($dp);
		}

		unset($installed);

		if (sizeof($new_ary))
		{
			foreach ($new_ary as $cfg)
			{
				$template->assign_block_vars('uninstalled', array(
					'NAME'			=> $cfg['name'],
					'COPYRIGHT'		=> $cfg['copyright'],
					'U_INSTALL'		=> $this->u_action . '&action=install&path=' . urlencode($cfg['path']))
				);
			}
		}
		unset($new_ary);

		$template->assign_vars(array(
			'S_BASIS_OPTIONS'		=> $basis_options)
		);

	}

	/**
	* Provides a template editor which allows saving changes to template files on the filesystem or in the database.
	*
	* @param int $template_id specifies which template set is being edited
	*/
	function edit_template($template_id)
	{
		global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode;

		if (defined('PHPBB_DISABLE_ACP_EDITOR'))
		{
			trigger_error($user->lang['EDITOR_DISABLED'] . adm_back_link($this->u_action));
		}

		$this->page_title = 'EDIT_TEMPLATE';

		$filelist = $filelist_cats = array();

		$template_data	= utf8_normalize_nfc(request_var('template_data', '', true));
		$template_data	= htmlspecialchars_decode($template_data);
		$template_file	= utf8_normalize_nfc(request_var('template_file', '', true));
		$text_rows		= max(5, min(999, request_var('text_rows', 20)));
		$save_changes	= (isset($_POST['save'])) ? true : false;

		// make sure template_file path doesn't go upwards
		$template_file = str_replace('..', '.', $template_file);

		// Retrieve some information about the template
		$sql = 'SELECT template_storedb, template_path, template_name
			FROM ' . STYLES_TEMPLATE_TABLE . "
			WHERE template_id = $template_id";
		$result = $db->sql_query($sql);
		$template_info = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

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

		if ($save_changes && !check_form_key('acp_styles'))
		{
			trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
		}
		else if (!$save_changes)
		{
			add_form_key('acp_styles');
		}

		// save changes to the template if the user submitted any
		if ($save_changes && $template_file)
		{
			// Get the filesystem location of the current file
			$file = "{$phpbb_root_path}styles/{$template_info['template_path']}/template/$template_file";
			$additional = '';

			// If the template is stored on the filesystem try to write the file else store it in the database
			if (!$safe_mode && !$template_info['template_storedb'] && file_exists($file) && @is_writable($file))
			{
				if (!($fp = @fopen($file, 'wb')))
				{
					// File exists and is writeable, but still not able to be written to
					trigger_error(sprintf($user->lang['TEMPLATE_FILE_NOT_WRITABLE'], htmlspecialchars($template_file)) . adm_back_link($this->u_action), E_USER_WARNING);
				}
				fwrite($fp, $template_data);
				fclose($fp);
			}
			else
			{
				$db->sql_transaction('begin');

				// If it's not stored in the db yet, then update the template setting and store all template files in the db
				if (!$template_info['template_storedb'])
				{
					if ($super = $this->get_super('template', $template_id))
					{
						$this->store_in_db('template', $super['template_id']);
					}
					else
					{
						$this->store_in_db('template', $template_id);
					}

					add_log('admin', 'LOG_TEMPLATE_EDIT_DETAILS', $template_info['template_name']);
					$additional .= '<br />' . $user->lang['EDIT_TEMPLATE_STORED_DB'];
				}

				// Update the template_data table entry for this template file
				$sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . "
					SET template_data = '" . $db->sql_escape($template_data) . "', template_mtime = " . time() . "
					WHERE template_id = $template_id
						AND template_filename = '" . $db->sql_escape($template_file) . "'";
				$db->sql_query($sql);

				$db->sql_transaction('commit');
			}

			// destroy the cached version of the template (filename without extension)
			$this->clear_template_cache($template_info, array(substr($template_file, 0, -5)));

			$cache->destroy('sql', STYLES_TABLE);

			add_log('admin', 'LOG_TEMPLATE_EDIT', $template_info['template_name'], $template_file);
			trigger_error($user->lang['TEMPLATE_FILE_UPDATED'] . $additional . adm_back_link($this->u_action . "&action=edit&id=$template_id&text_rows=$text_rows&template_file=$template_file"));
		}

		// Generate a category array containing template filenames
		if (!$template_info['template_storedb'])
		{
			$template_path = "{$phpbb_root_path}styles/{$template_info['template_path']}/template";

			$filelist = filelist($template_path, '', 'html');
			$filelist[''] = array_diff($filelist[''], array('bbcode.html'));

			if ($template_file)
			{
				if (!file_exists($template_path . "/$template_file") || !($template_data = file_get_contents($template_path . "/$template_file")))
				{
					trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
				}
			}
		}
		else
		{
			$sql = 'SELECT *
				FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
				WHERE template_id = $template_id";
			$result = $db->sql_query($sql);

			$filelist = array('' => array());
			while ($row = $db->sql_fetchrow($result))
			{
				$file_info = pathinfo($row['template_filename']);

				if (($file_info['basename'] != 'bbcode') && ($file_info['extension'] == 'html'))
				{
					if (($file_info['dirname'] == '.') || empty($file_info['dirname']))
					{
						$filelist[''][] = $row['template_filename'];
					}
					else
					{
						$filelist[$file_info['dirname'] . '/'][] = $file_info['basename'];
					}
				}

				if ($row['template_filename'] == $template_file)
				{
					$template_data = $row['template_data'];
				}
			}
			$db->sql_freeresult($result);
			unset($file_info);
		}

		if (empty($filelist['']))
		{
			trigger_error($user->lang['NO_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING);
		}

		// Now create the categories
		$filelist_cats[''] = array();
		foreach ($filelist as $pathfile => $file_ary)
		{
			// Use the directory name as category name
			if (!empty($pathfile))
			{
				$filelist_cats[$pathfile] = array();
				foreach ($file_ary as $file)
				{
					$filelist_cats[$pathfile][$pathfile . $file] = $file;
				}
			}
			// or if it's in the main category use the word before the first underscore to group files
			else
			{
				$cats = array();
				foreach ($file_ary as $file)
				{
					$cats[] = substr($file, 0, strpos($file, '_'));
					$filelist_cats[substr($file, 0, strpos($file, '_'))][$file] = $file;
				}

				$cats = array_values(array_unique($cats));

				// we don't need any single element categories so put them into the misc '' category
				for ($i = 0, $n = sizeof($cats); $i < $n; $i++)
				{
					if (sizeof($filelist_cats[$cats[$i]]) == 1 && $cats[$i] !== '')
					{
						$filelist_cats[''][key($filelist_cats[$cats[$i]])] = current($filelist_cats[$cats[$i]]);
						unset($filelist_cats[$cats[$i]]);
					}
				}
				unset($cats);
			}
		}
		unset($filelist);

		// Generate list of categorised template files
		$tpl_options = '';
		ksort($filelist_cats);
		foreach ($filelist_cats as $category => $tpl_ary)
		{
			ksort($tpl_ary);

			if (!empty($category))
			{
				$tpl_options .= '<option class="sep" value="">' . $category . '</option>';
			}

			foreach ($tpl_ary as $filename => $file)
			{
				$selected = ($template_file == $filename) ? ' selected="selected"' : '';
				$tpl_options .= '<option value="' . $filename . '"' . $selected . '>' . $file . '</option>';
			}
		}

		$template->assign_vars(array(
			'S_EDIT_TEMPLATE'	=> true,
			'S_HIDDEN_FIELDS'	=> build_hidden_fields(array('template_file' => $template_file)),
			'S_TEMPLATES'		=> $tpl_options,

			'U_ACTION'			=> $this->u_action . "&action=edit&id=$template_id&text_rows=$text_rows",
			'U_BACK'			=> $this->u_action,

			'L_EDIT'			=> $user->lang['EDIT_TEMPLATE'],
			'L_EDIT_EXPLAIN'	=> $user->lang['EDIT_TEMPLATE_EXPLAIN'],
			'L_EDITOR'			=> $user->lang['TEMPLATE_EDITOR'],
			'L_EDITOR_HEIGHT'	=> $user->lang['TEMPLATE_EDITOR_HEIGHT'],
			'L_FILE'			=> $user->lang['TEMPLATE_FILE'],
			'L_SELECT'			=> $user->lang['SELECT_TEMPLATE'],
			'L_SELECTED'		=> $user->lang['SELECTED_TEMPLATE'],
			'L_SELECTED_FILE'	=> $user->lang['SELECTED_TEMPLATE_FILE'],

			'SELECTED_TEMPLATE'	=> $template_info['template_name'],
			'TEMPLATE_FILE'		=> $template_file,
			'TEMPLATE_DATA'		=> utf8_htmlspecialchars($template_data),
			'TEXT_ROWS'			=> $text_rows)
		);
	}

	/**
	* Allows the admin to view cached versions of template files and clear single template cache files
	*
	* @param int $template_id specifies which template's cache is shown
	*/
	function template_cache($template_id)
	{
		global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;

		$source		= str_replace('/', '.', request_var('source', ''));
		$file_ary	= array_diff(request_var('delete', array('')), array(''));
		$submit		= isset($_POST['submit']) ? true : false;

		$sql = 'SELECT *
			FROM ' . STYLES_TEMPLATE_TABLE . "
			WHERE template_id = $template_id";
		$result = $db->sql_query($sql);
		$template_row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

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

		// User wants to delete one or more files ...
		if ($submit && $file_ary)
		{
			$this->clear_template_cache($template_row, $file_ary);
			trigger_error($user->lang['TEMPLATE_CACHE_CLEARED'] . adm_back_link($this->u_action . "&action=cache&id=$template_id"));
		}

		$cache_prefix = 'tpl_' . str_replace('_', '-', $template_row['template_path']);

		// Someone wants to see the cached source ... so we'll highlight it,
		// add line numbers and indent it appropriately. This could be nasty
		// on larger source files ...
		if ($source && file_exists("{$phpbb_root_path}cache/{$cache_prefix}_$source.html.$phpEx"))
		{
			adm_page_header($user->lang['TEMPLATE_CACHE']);

			$template->set_filenames(array(
				'body'	=> 'viewsource.html')
			);

			$template->assign_vars(array(
				'FILENAME'	=> str_replace('.', '/', $source) . '.html')
			);

			$code = str_replace(array("\r\n", "\r"), array("\n", "\n"), file_get_contents("{$phpbb_root_path}cache/{$cache_prefix}_$source.html.$phpEx"));

			$conf = array('highlight.bg', 'highlight.comment', 'highlight.default', 'highlight.html', 'highlight.keyword', 'highlight.string');
			foreach ($conf as $ini_var)
			{
				@ini_set($ini_var, str_replace('highlight.', 'syntax', $ini_var));
			}

			$marker = 'MARKER' . time();
			$code = highlight_string(str_replace("\n", $marker, $code), true);
			$code = str_replace($marker, "\n", $code);
			$str_from = array('<span style="color: ', '<font color="syntax', '</font>', '<code>', '</code>','[', ']', '.', ':');
			$str_to = array('<span class="', '<span class="syntax', '</span>', '', '', '&#91;', '&#93;', '&#46;', '&#58;');

			$code = str_replace($str_from, $str_to, $code);
			$code = preg_replace('#^(<span class="[a-z_]+">)\n?(.*?)\n?(</span>)$#ism', '$1$2$3', $code);
			$code = substr($code, strlen('<span class="syntaxhtml">'));
			$code = substr($code, 0, -1 * strlen('</ span>'));
			$code = explode("\n", $code);

			foreach ($code as $key => $line)
			{
				$template->assign_block_vars('source', array(
					'LINENUM'	=> $key + 1,
					'LINE'		=> preg_replace('#([^ ;])&nbsp;([^ &])#', '$1 $2', $line))
				);
				unset($code[$key]);
			}

			adm_page_footer();
		}

		$filemtime = array();
		if ($template_row['template_storedb'])
		{
			$ids = array();
			if (isset($template_row['template_inherits_id']) && $template_row['template_inherits_id'])
			{
				$ids[] = $template_row['template_inherits_id'];
			}
			$ids[] = $template_row['template_id'];

			$filemtime 			= array();
			$file_template_db	= array();

			foreach ($ids as $id)
			{
				$sql = 'SELECT template_filename, template_mtime
					FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
					WHERE template_id = $id";
				$result = $db->sql_query($sql);

				while ($row = $db->sql_fetchrow($result))
				{
					$filemtime[$row['template_filename']] = $row['template_mtime'];
					$file_template_db[$row['template_filename']] = $id;
				}
				$db->sql_freeresult($result);
			}
		}

		// Get a list of cached template files and then retrieve additional information about them
		$file_ary = $this->template_cache_filelist($template_row['template_path']);

		foreach ($file_ary as $file)
		{
			$file		= str_replace('/', '.', $file);

			// perform some dirty guessing to get the path right.
			// We assume that three dots in a row were '../'
			$tpl_file	= str_replace('.', '/', $file);
			$tpl_file	= str_replace('///', '../', $tpl_file);

			$filename = "{$cache_prefix}_$file.html.$phpEx";

			if (!file_exists("{$phpbb_root_path}cache/$filename"))
			{
				continue;
			}

			$file_tpl = "{$phpbb_root_path}styles/{$template_row['template_path']}/template/$tpl_file.html";
			$inherited = false;

			if (isset($template_row['template_inherits_id']) && $template_row['template_inherits_id'])
			{
				if (!$template_row['template_storedb'])
				{
					if (!file_exists($file_tpl))
					{
						$file_tpl = "{$phpbb_root_path}styles/{$template_row['template_inherit_path']}/template/$tpl_file.html";
						$inherited = true;
					}
				}
				else
				{
					if ($file_template_db[$file . '.html'] == $template_row['template_inherits_id'])
					{
						$file_tpl = "{$phpbb_root_path}styles/{$template_row['template_inherit_path']}/template/$tpl_file.html";
						$inherited = true;
					}
				}
			}

			// Correct the filename if it is stored in database and the file is in a subfolder.
			if ($template_row['template_storedb'])
			{
				$file = str_replace('.', '/', $file);
			}

			$template->assign_block_vars('file', array(
				'U_VIEWSOURCE'	=> $this->u_action . "&action=cache&id=$template_id&source=$file",

				'CACHED'		=> $user->format_date(filemtime("{$phpbb_root_path}cache/$filename")),
				'FILENAME'		=> $file,
				'FILENAME_PATH'	=> $file_tpl,
				'FILESIZE'		=> get_formatted_filesize(filesize("{$phpbb_root_path}cache/$filename")),
				'MODIFIED'		=> $user->format_date((!$template_row['template_storedb']) ? filemtime($file_tpl) : $filemtime[$file . '.html']))
			);
		}
		unset($filemtime);

		$template->assign_vars(array(
			'S_CACHE'			=> true,
			'S_TEMPLATE'		=> true,

			'U_ACTION'			=> $this->u_action . "&action=cache&id=$template_id",
			'U_BACK'			=> $this->u_action)
		);
	}

	/**
	* Provides a css editor and a basic easier to use stylesheet editing tool for less experienced (or lazy) users
	*
	* @param int $theme_id specifies which theme is being edited
	*/
	function edit_theme($theme_id)
	{
		global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template, $safe_mode;

		$this->page_title = 'EDIT_THEME';

		$filelist = $filelist_cats = array();

		$theme_data		= utf8_normalize_nfc(request_var('template_data', '', true));
		$theme_data		= htmlspecialchars_decode($theme_data);
		$theme_file		= utf8_normalize_nfc(request_var('template_file', '', true));
		$text_rows		= max(5, min(999, request_var('text_rows', 20)));
		$save_changes	= (isset($_POST['save'])) ? true : false;

		// make sure theme_file path doesn't go upwards
		$theme_file = str_replace('..', '.', $theme_file);

		// Retrieve some information about the theme
		$sql = 'SELECT theme_storedb, theme_path, theme_name, theme_data
			FROM ' . STYLES_THEME_TABLE . "
			WHERE theme_id = $theme_id";
		$result = $db->sql_query($sql);

		if (!($theme_info = $db->sql_fetchrow($result)))
		{
			trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
		}
		$db->sql_freeresult($result);

		// save changes to the theme if the user submitted any
		if ($save_changes)
		{
			// Get the filesystem location of the current file
			$file = "{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme/$theme_file";
			$additional = '';
			$message = $user->lang['THEME_UPDATED'];

			// If the theme is stored on the filesystem try to write the file else store it in the database
			if (!$safe_mode && !$theme_info['theme_storedb'] && file_exists($file) && @is_writable($file))
			{
				if (!($fp = @fopen($file, 'wb')))
				{
					trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
				}
				fwrite($fp, $theme_data);
				fclose($fp);
			}
			else
			{
				// Write stylesheet to db
				$sql_ary = array(
					'theme_mtime'		=> time(),
					'theme_storedb'		=> 1,
					'theme_data'		=> $this->db_theme_data($theme_info, $theme_data),
				);
				$sql = 'UPDATE ' . STYLES_THEME_TABLE . '
					SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
					WHERE theme_id = ' . $theme_id;
				$db->sql_query($sql);

				$cache->destroy('sql', STYLES_THEME_TABLE);

				// notify the user if the theme was not stored in the db before his modification
				if (!$theme_info['theme_storedb'])
				{
					add_log('admin', 'LOG_THEME_EDIT_DETAILS', $theme_info['theme_name']);
					$message .= '<br />' . $user->lang['EDIT_THEME_STORED_DB'];
				}
			}
			$cache->destroy('sql', STYLES_THEME_TABLE);
			add_log('admin', (!$theme_info['theme_storedb']) ? 'LOG_THEME_EDIT_FILE' : 'LOG_THEME_EDIT', $theme_info['theme_name'], (!$theme_info['theme_storedb']) ? $theme_file : '');

			trigger_error($message . adm_back_link($this->u_action . "&action=edit&id=$theme_id&template_file=$theme_file&text_rows=$text_rows"));
		}

		// Generate a category array containing theme filenames
		if (!$theme_info['theme_storedb'])
		{
			$theme_path = "{$phpbb_root_path}styles/{$theme_info['theme_path']}/theme";

			$filelist = filelist($theme_path, '', 'css');

			if ($theme_file)
			{
				if (!file_exists($theme_path . "/$theme_file") || !($theme_data = file_get_contents($theme_path . "/$theme_file")))
				{
					trigger_error($user->lang['NO_THEME'] . adm_back_link($this->u_action), E_USER_WARNING);
				}
			}
		}
		else
		{
			$theme_data = &$theme_info['theme_data'];
		}

		// Now create the categories
		$filelist_cats[''] = array();
		foreach ($filelist as $pathfile => $file_ary)
		{
			// Use the directory name as category name
			if (!empty($pathfile))
			{
				$filelist_cats[$pathfile] = array();
				foreach ($file_ary as $file)
				{
					$filelist_cats[$pathfile][$pathfile . $file] = $file;
				}
			}
			// or if it's in the main category use the word before the first underscore to group files
			else
			{
				$cats = array();
				foreach ($file_ary as $file)
				{
					$cats[] = substr($file, 0, strpos($file, '_'));
					$filelist_cats[substr($file, 0, strpos($file, '_'))][$file] = $file;
				}

				$cats = array_values(array_unique($cats));

				// we don't need any single element categories so put them into the misc '' category
				for ($i = 0, $n = sizeof($cats); $i < $n; $i++)
				{
					if (sizeof($filelist_cats[$cats[$i]]) == 1 && $cats[$i] !== '')
					{
						$filelist_cats[''][key($filelist_cats[$cats[$i]])] = current($filelist_cats[$cats[$i]]);
						unset($filelist_cats[$cats[$i]]);
					}
				}
				unset($cats);
			}
		}
		unset($filelist);

		// Generate list of categorised theme files
		$tpl_options = '';
		ksort($filelist_cats);
		foreach ($filelist_cats as $category => $tpl_ary)
		{
			ksort($tpl_ary);

			if (!empty($category))
			{
				$tpl_options .= '<option class="sep" value="">' . $category . '</option>';
			}

			foreach ($tpl_ary as $filename => $file)
			{
				$selected = ($theme_file == $filename) ? ' selected="selected"' : '';
				$tpl_options .= '<option value="' . $filename . '"' . $selected . '>' . $file . '</option>';
			}
		}

		$template->assign_vars(array(
			'S_EDIT_THEME'		=> true,
			'S_HIDDEN_FIELDS'	=> build_hidden_fields(array('template_file' => $theme_file)),
			'S_THEME_IN_DB'		=> $theme_info['theme_storedb'],
			'S_TEMPLATES'		=> $tpl_options,

			'U_ACTION'			=> $this->u_action . "&action=edit&id=$theme_id&text_rows=$text_rows",
			'U_BACK'			=> $this->u_action,

			'L_EDIT'			=> $user->lang['EDIT_THEME'],
			'L_EDIT_EXPLAIN'	=> $user->lang['EDIT_THEME_EXPLAIN'],
			'L_EDITOR'			=> $user->lang['THEME_EDITOR'],
			'L_EDITOR_HEIGHT'	=> $user->lang['THEME_EDITOR_HEIGHT'],
			'L_FILE'			=> $user->lang['THEME_FILE'],
			'L_SELECT'			=> $user->lang['SELECT_THEME'],
			'L_SELECTED'		=> $user->lang['SELECTED_THEME'],
			'L_SELECTED_FILE'	=> $user->lang['SELECTED_THEME_FILE'],

			'SELECTED_TEMPLATE'	=> $theme_info['theme_name'],
			'TEMPLATE_FILE'		=> $theme_file,
			'TEMPLATE_DATA'		=> utf8_htmlspecialchars($theme_data),
			'TEXT_ROWS'			=> $text_rows)
		);
	}

	/**
	* Edit imagesets
	*
	* @param int $imageset_id specifies which imageset is being edited
	*/
	function edit_imageset($imageset_id)
	{
		global $db, $user, $phpbb_root_path, $cache, $template;

		$this->page_title = 'EDIT_IMAGESET';

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

		$update		= (isset($_POST['update'])) ? true : false;

		$imgname	= request_var('imgname', 'site_logo');
		$imgname	= preg_replace('#[^a-z0-9\-+_]#i', '', $imgname);
		$sql_extra = $imgnamelang = '';

		$sql = 'SELECT imageset_path, imageset_name
			FROM ' . STYLES_IMAGESET_TABLE . "
			WHERE imageset_id = $imageset_id";
		$result = $db->sql_query($sql);
		$imageset_row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

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

		$imageset_path		= $imageset_row['imageset_path'];
		$imageset_name		= $imageset_row['imageset_name'];

		if (strpos($imgname, '-') !== false)
		{
			list($imgname, $imgnamelang) = explode('-', $imgname);
			$sql_extra = " AND image_lang IN ('" . $db->sql_escape($imgnamelang) . "', '')";
		}

		$sql = 'SELECT image_filename, image_width, image_height, image_lang, image_id
			FROM ' . STYLES_IMAGESET_DATA_TABLE . "
			WHERE imageset_id = $imageset_id
				AND image_name = '" . $db->sql_escape($imgname) . "'$sql_extra";
		$result = $db->sql_query($sql);
		$imageset_data_row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

		$image_filename	= $imageset_data_row['image_filename'];
		$image_width	= $imageset_data_row['image_width'];
		$image_height	= $imageset_data_row['image_height'];
		$image_lang		= $imageset_data_row['image_lang'];
		$image_id		= $imageset_data_row['image_id'];
		$imgsize		= ($imageset_data_row['image_width'] && $imageset_data_row['image_height']) ? 1 : 0;

		// Check to see whether the selected image exists in the table
		$valid_name = ($update) ? false : true;

		foreach ($this->imageset_keys as $category => $img_ary)
		{
			if (in_array($imgname, $img_ary))
			{
				$valid_name = true;
				break;
			}
		}

		if ($update && isset($_POST['imgpath']) && $valid_name)
		{
			// If imgwidth and imgheight are non-zero grab the actual size
			// from the image itself ... we ignore width settings for the poll center image
			$imgwidth	= request_var('imgwidth', 0);
			$imgheight	= request_var('imgheight', 0);
			$imgsize	= request_var('imgsize', 0);
			$imgpath	= request_var('imgpath', '');
			$imgpath	= str_replace('..', '.', $imgpath);

			// If no dimensions selected, we reset width and height to 0 ;)
			if (!$imgsize)
			{
				$imgwidth = $imgheight = 0;
			}

			$imglang = '';

			if ($imgpath && !file_exists("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath"))
			{
				trigger_error($user->lang['NO_IMAGE_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
			}

			// Determine width/height. If dimensions included and no width/height given, we detect them automatically...
			if ($imgsize && $imgpath)
			{
				if (!$imgwidth || !$imgheight)
				{
					list($imgwidth_file, $imgheight_file) = getimagesize("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath");
					$imgwidth = ($imgwidth) ? $imgwidth : $imgwidth_file;
					$imgheight = ($imgheight) ? $imgheight : $imgheight_file;
				}
				$imgwidth	= ($imgname != 'poll_center') ? (int) $imgwidth : 0;
				$imgheight	= (int) $imgheight;
			}

			if (strpos($imgpath, '/') !== false)
			{
				list($imglang, $imgfilename) = explode('/', $imgpath);
			}
			else
			{
				$imgfilename = $imgpath;
			}

			$sql_ary = array(
				'image_filename'	=> (string) $imgfilename,
				'image_width'		=> (int) $imgwidth,
				'image_height'		=> (int) $imgheight,
				'image_lang'		=> (string) $imglang,
			);

			// already exists
			if ($imageset_data_row)
			{
				$sql = 'UPDATE ' . STYLES_IMAGESET_DATA_TABLE . '
					SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
					WHERE image_id = $image_id";
				$db->sql_query($sql);
			}
			// does not exist
			else if (!$imageset_data_row)
			{
				$sql_ary['image_name']	= $imgname;
				$sql_ary['imageset_id']	= (int) $imageset_id;
				$db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
			}

			$cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);

			add_log('admin', 'LOG_IMAGESET_EDIT', $imageset_name);

			$template->assign_var('SUCCESS', true);

			$image_filename = $imgfilename;
			$image_width	= $imgwidth;
			$image_height	= $imgheight;
			$image_lang		= $imglang;
		}

		$imglang = '';
		$imagesetlist = array('nolang' => array(), 'lang' => array());
		$langs = array();

		$dir = "{$phpbb_root_path}styles/$imageset_path/imageset";
		$dp = @opendir($dir);

		if ($dp)
		{
			while (($file = readdir($dp)) !== false)
			{
				if ($file[0] != '.' && strtoupper($file) != 'CVS' && !is_file($dir . '/' . $file) && !is_link($dir . '/' . $file))
				{
					$langs[] = $file;
				}
				else if (preg_match('#\.(?:gif|jpg|png)$#', $file))
				{
					$imagesetlist['nolang'][] = $file;
				}
			}

			if ($sql_extra)
			{
				$dp2 = @opendir("$dir/$imgnamelang");

				if ($dp2)
				{
					while (($file2 = readdir($dp2)) !== false)
					{
						if (preg_match('#\.(?:gif|jpg|png)$#', $file2))
						{
							$imagesetlist['lang'][] = "$imgnamelang/$file2";
						}
					}
					closedir($dp2);
				}
			}
			closedir($dp);
		}

		// Generate list of image options
		$img_options = '';
		foreach ($this->imageset_keys as $category => $img_ary)
		{
			$template->assign_block_vars('category', array(
				'NAME'			=> $user->lang['IMG_CAT_' . strtoupper($category)]
			));

			foreach ($img_ary as $img)
			{
				if ($category == 'buttons')
				{
					foreach ($langs as $language)
					{
						$template->assign_block_vars('category.images', array(
							'SELECTED'			=> ($img == $imgname && $language == $imgnamelang),
							'VALUE'				=> $img . '-' . $language,
							'TEXT'				=> $user->lang['IMG_' . strtoupper($img)] . ' [ ' . $language . ' ]'
						));
					}
				}
				else
				{
					$template->assign_block_vars('category.images', array(
						'SELECTED'			=> ($img == $imgname),
						'VALUE'				=> $img,
						'TEXT'				=> (($category == 'custom') ? $img : $user->lang['IMG_' . strtoupper($img)])
					));
				}
			}
		}

		// Make sure the list of possible images is sorted alphabetically
		sort($imagesetlist['lang']);
		sort($imagesetlist['nolang']);

		$image_found = false;
		$img_val = '';
		foreach ($imagesetlist as $type => $img_ary)
		{
			if ($type !== 'lang' || $sql_extra)
			{
				$template->assign_block_vars('imagesetlist', array(
					'TYPE'	=> ($type == 'lang')
				));
			}

			foreach ($img_ary as $img)
			{
				$imgtext = preg_replace('/^([^\/]+\/)/', '', $img);
				$selected = (!empty($imgname) && strpos($image_filename, $imgtext) !== false);
				if ($selected)
				{
					$image_found = true;
					$img_val = htmlspecialchars($img);
				}
				$template->assign_block_vars('imagesetlist.images', array(
					'SELECTED'			=> $selected,
					'TEXT'				=> $imgtext,
					'VALUE'				=> htmlspecialchars($img)
				));
			}
		}

		$imgsize_bool = (!empty($imgname) && $image_width && $image_height) ? true : false;
		$image_request = '../styles/' . $imageset_path . '/imageset/' . ($image_lang ? $imgnamelang . '/' : '') . $image_filename;

		$template->assign_vars(array(
			'S_EDIT_IMAGESET'	=> true,
			'L_TITLE'			=> $user->lang[$this->page_title],
			'L_EXPLAIN'			=> $user->lang[$this->page_title . '_EXPLAIN'],
			'IMAGE_OPTIONS'		=> $img_options,
			'IMAGE_SIZE'		=> $image_width,
			'IMAGE_HEIGHT'		=> $image_height,
			'IMAGE_REQUEST'		=> (empty($image_filename)) ? 'images/no_image.png' : $image_request,
			'U_ACTION'			=> $this->u_action . "&action=edit&id=$imageset_id",
			'U_BACK'			=> $this->u_action,
			'NAME'				=> $imageset_name,
			'A_NAME'			=> addslashes($imageset_name),
			'PATH'				=> $imageset_path,
			'A_PATH'			=> addslashes($imageset_path),
			'ERROR'				=> !$valid_name,
			'IMG_SRC'			=> ($image_found) ? '../styles/' . $imageset_path . '/imageset/' . $img_val : 'images/no_image.png',
			'IMAGE_SELECT'		=> $image_found
		));
	}

	/**
	* Remove style/template/theme/imageset
	*/
	function remove($mode, $style_id)
	{
		global $db, $template, $user, $phpbb_root_path, $cache, $config;

		$new_id = request_var('new_id', 0);
		$update = (isset($_POST['update'])) ? true : false;
		$sql_where = '';

		switch ($mode)
		{
			case 'style':
				$sql_from = STYLES_TABLE;
				$sql_select = 'style_name';
				$sql_where = 'AND style_active = 1';
			break;

			case 'template':
				$sql_from = STYLES_TEMPLATE_TABLE;
				$sql_select = 'template_name, template_path, template_storedb';
			break;

			case 'theme':
				$sql_from = STYLES_THEME_TABLE;
				$sql_select = 'theme_name, theme_path, theme_storedb';
			break;

			case 'imageset':
				$sql_from = STYLES_IMAGESET_TABLE;
				$sql_select = 'imageset_name, imageset_path';
			break;
		}

		if ($mode === 'template' && ($conflicts = $this->check_inheritance($mode, $style_id)))
		{
			$l_type = strtoupper($mode);
			$msg = $user->lang[$l_type . '_DELETE_DEPENDENT'];
			foreach ($conflicts as $id => $values)
			{
				$msg .= '<br />' . $values['template_name'];
			}

			trigger_error($msg . adm_back_link($this->u_action), E_USER_WARNING);
		}

		$l_prefix = strtoupper($mode);

		$sql = "SELECT $sql_select
			FROM $sql_from
			WHERE {$mode}_id = $style_id";
		$result = $db->sql_query($sql);
		$style_row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

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

		$sql = "SELECT {$mode}_id, {$mode}_name
			FROM $sql_from
			WHERE {$mode}_id <> $style_id
			$sql_where
			ORDER BY {$mode}_name ASC";
		$result = $db->sql_query($sql);

		$s_options = '';

		if ($row = $db->sql_fetchrow($result))
		{
			do
			{
				$s_options .= '<option value="' . $row[$mode . '_id'] . '">' . $row[$mode . '_name'] . '</option>';
			}
			while ($row = $db->sql_fetchrow($result));
		}
		else
		{
			trigger_error($user->lang['ONLY_' . $l_prefix] . adm_back_link($this->u_action), E_USER_WARNING);
		}
		$db->sql_freeresult($result);

		if ($update)
		{
			$sql = "DELETE FROM $sql_from
				WHERE {$mode}_id = $style_id";
			$db->sql_query($sql);

			if ($mode == 'style')
			{
				$sql = 'UPDATE ' . USERS_TABLE . "
					SET user_style = $new_id
					WHERE user_style = $style_id";
				$db->sql_query($sql);

				$sql = 'UPDATE ' . FORUMS_TABLE . "
					SET forum_style = $new_id
					WHERE forum_style = $style_id";
				$db->sql_query($sql);

				if ($style_id == $config['default_style'])
				{
					set_config('default_style', $new_id);
				}
			}
			else
			{
				if ($mode == 'imageset')
				{
					$sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . "
						WHERE imageset_id = $style_id";
					$db->sql_query($sql);
				}
				$sql = 'UPDATE ' . STYLES_TABLE . "
					SET {$mode}_id = $new_id
					WHERE {$mode}_id = $style_id";
				$db->sql_query($sql);
			}

			$cache->destroy('sql', STYLES_TABLE);

			add_log('admin', 'LOG_' . $l_prefix . '_DELETE', $style_row[$mode . '_name']);
			$message = ($mode != 'style') ? $l_prefix . '_DELETED_FS' : $l_prefix . '_DELETED';
			trigger_error($user->lang[$message] . adm_back_link($this->u_action));
		}

		$this->page_title = 'DELETE_' . $l_prefix;

		$template->assign_vars(array(
			'S_DELETE'			=> true,
			'S_REPLACE_OPTIONS'	=> $s_options,

			'L_TITLE'			=> $user->lang[$this->page_title],
			'L_EXPLAIN'			=> $user->lang[$this->page_title . '_EXPLAIN'],
			'L_NAME'			=> $user->lang[$l_prefix . '_NAME'],
			'L_REPLACE'			=> $user->lang['REPLACE_' . $l_prefix],
			'L_REPLACE_EXPLAIN'	=> $user->lang['REPLACE_' . $l_prefix . '_EXPLAIN'],

			'U_ACTION'		=> $this->u_action . "&action=delete&id=$style_id",
			'U_BACK'		=> $this->u_action,

			'NAME'			=> $style_row[$mode . '_name'],
			)
		);
	}

	/**
	* Export style or style elements
	*/
	function export($mode, $style_id)
	{
		global $db, $template, $user, $phpbb_root_path, $cache, $phpEx, $config;

		$update = (isset($_POST['update'])) ? true : false;

		$inc_template = request_var('inc_template', 0);
		$inc_theme = request_var('inc_theme', 0);
		$inc_imageset = request_var('inc_imageset', 0);
		$store = request_var('store', 0);
		$format = request_var('format', '');

		$error = array();
		$methods = array('tar');

		$available_methods = array('tar.gz' => 'zlib', 'tar.bz2' => 'bz2', 'zip' => 'zlib');
		foreach ($available_methods as $type => $module)
		{
			if (!@extension_loaded($module))
			{
				continue;
			}

			$methods[] = $type;
		}

		if (!in_array($format, $methods))
		{
			$format = 'tar';
		}

		switch ($mode)
		{
			case 'style':
				if ($update && ($inc_template + $inc_theme + $inc_imageset) < 1)
				{
					$error[] = $user->lang['STYLE_ERR_MORE_ELEMENTS'];
				}

				$name = 'style_name';

				$sql_select = 's.style_id, s.style_name, s.style_copyright';
				$sql_select .= ($inc_template) ? ', t.*' : ', t.template_name';
				$sql_select .= ($inc_theme) ? ', c.*' : ', c.theme_name';
				$sql_select .= ($inc_imageset) ? ', i.*' : ', i.imageset_name';
				$sql_from = STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . ' i';
				$sql_where = "s.style_id = $style_id AND t.template_id = s.template_id AND c.theme_id = s.theme_id AND i.imageset_id = s.imageset_id";

				$l_prefix = 'STYLE';
			break;

			case 'template':
				$name = 'template_name';

				$sql_select = '*';
				$sql_from = STYLES_TEMPLATE_TABLE;
				$sql_where = "template_id = $style_id";

				$l_prefix = 'TEMPLATE';
			break;

			case 'theme':
				$name = 'theme_name';

				$sql_select = '*';
				$sql_from = STYLES_THEME_TABLE;
				$sql_where = "theme_id = $style_id";

				$l_prefix = 'THEME';
			break;

			case 'imageset':
				$name = 'imageset_name';

				$sql_select = '*';
				$sql_from = STYLES_IMAGESET_TABLE;
				$sql_where = "imageset_id = $style_id";

				$l_prefix = 'IMAGESET';
			break;
		}

		if ($update && !sizeof($error))
		{
			$sql = "SELECT $sql_select
				FROM $sql_from
				WHERE $sql_where";
			$result = $db->sql_query($sql);
			$style_row = $db->sql_fetchrow($result);
			$db->sql_freeresult($result);

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

			$var_ary = array('style_id', 'style_name', 'style_copyright', 'template_id', 'template_name', 'template_path', 'template_copyright', 'template_storedb', 'template_inherits_id', 'bbcode_bitfield', 'theme_id', 'theme_name', 'theme_path', 'theme_copyright', 'theme_storedb', 'theme_mtime', 'theme_data', 'imageset_id', 'imageset_name', 'imageset_path', 'imageset_copyright');

			foreach ($var_ary as $var)
			{
				if (!isset($style_row[$var]))
				{
					$style_row[$var] = '';
				}
			}

			$files = $data = array();

			if ($mode == 'style')
			{
				$style_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['style_name'], $style_row['style_copyright'], $config['version']), $this->style_cfg);

				$style_cfg .= (!$inc_template) ? "\nrequired_template = {$style_row['template_name']}" : '';
				$style_cfg .= (!$inc_theme) ? "\nrequired_theme = {$style_row['theme_name']}" : '';
				$style_cfg .= (!$inc_imageset) ? "\nrequired_imageset = {$style_row['imageset_name']}" : '';

				$data[] = array(
					'src'		=> $style_cfg,
					'prefix'	=> 'style.cfg'
				);

				unset($style_cfg);
			}

			// Export template core code
			if ($mode == 'template' || $inc_template)
			{
				$template_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['template_name'], $style_row['template_copyright'], $config['version']), $this->template_cfg);

				$use_template_name = '';

				// Add the inherit from variable, depending on it's use...
				if ($style_row['template_inherits_id'])
				{
					// Get the template name
					$sql = 'SELECT template_name
						FROM ' . STYLES_TEMPLATE_TABLE . '
						WHERE template_id = ' . (int) $style_row['template_inherits_id'];
					$result = $db->sql_query($sql);
					$use_template_name = (string) $db->sql_fetchfield('template_name');
					$db->sql_freeresult($result);
				}

				$template_cfg .= ($use_template_name) ? "\ninherit_from = $use_template_name" : "\n#inherit_from = ";
				$template_cfg .= "\n\nbbcode_bitfield = {$style_row['bbcode_bitfield']}";

				$data[] = array(
					'src'		=> $template_cfg,
					'prefix'	=> 'template/template.cfg'
				);

				// This is potentially nasty memory-wise ...
				if (!$style_row['template_storedb'])
				{
					$files[] = array(
						'src'		=> "styles/{$style_row['template_path']}/template/",
						'prefix-'	=> "styles/{$style_row['template_path']}/",
						'prefix+'	=> false,
						'exclude'	=> 'template.cfg'
					);
				}
				else
				{
					$sql = 'SELECT template_filename, template_data
						FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
						WHERE template_id = {$style_row['template_id']}";
					$result = $db->sql_query($sql);

					while ($row = $db->sql_fetchrow($result))
					{
						$data[] = array(
							'src' => $row['template_data'],
							'prefix' => 'template/' . $row['template_filename']
						);
					}
					$db->sql_freeresult($result);
				}
				unset($template_cfg);
			}

			// Export theme core code
			if ($mode == 'theme' || $inc_theme)
			{
				$theme_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['theme_name'], $style_row['theme_copyright'], $config['version']), $this->theme_cfg);

				// Read old cfg file
				$items = $cache->obtain_cfg_items($style_row);
				$items = $items['theme'];

				if (!isset($items['parse_css_file']))
				{
					$items['parse_css_file'] = 'off';
				}

				$theme_cfg = str_replace(array('{PARSE_CSS_FILE}'), array($items['parse_css_file']), $theme_cfg);

				$files[] = array(
					'src'		=> "styles/{$style_row['theme_path']}/theme/",
					'prefix-'	=> "styles/{$style_row['theme_path']}/",
					'prefix+'	=> false,
					'exclude'	=> ($style_row['theme_storedb']) ? 'stylesheet.css,theme.cfg' : 'theme.cfg'
				);

				$data[] = array(
					'src'		=> $theme_cfg,
					'prefix'	=> 'theme/theme.cfg'
				);

				if ($style_row['theme_storedb'])
				{
					$data[] = array(
						'src'		=> $style_row['theme_data'],
						'prefix'	=> 'theme/stylesheet.css'
					);
				}

				unset($items, $theme_cfg);
			}

			// Export imageset core code
			if ($mode == 'imageset' || $inc_imageset)
			{
				$imageset_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['imageset_name'], $style_row['imageset_copyright'], $config['version']), $this->imageset_cfg);

				$imageset_main = array();

				$sql = 'SELECT image_filename, image_name, image_height, image_width
					FROM ' . STYLES_IMAGESET_DATA_TABLE . "
					WHERE imageset_id = $style_id
						AND image_lang = ''";
				$result = $db->sql_query($sql);
				while ($row = $db->sql_fetchrow($result))
				{
					$imageset_main[$row['image_name']] = $row['image_filename'] . ($row['image_height'] ? '*' . $row['image_height']: '') . ($row['image_width'] ? '*' . $row['image_width']: '');
				}
				$db->sql_freeresult($result);

				foreach ($this->imageset_keys as $topic => $key_array)
				{
					foreach ($key_array as $key)
					{
						if (isset($imageset_main[$key]))
						{
							$imageset_cfg .= "\nimg_" . $key . ' = ' . str_replace("styles/{$style_row['imageset_path']}/imageset/", '{PATH}', $imageset_main[$key]);
						}
					}
				}

				$files[] = array(
					'src'		=> "styles/{$style_row['imageset_path']}/imageset/",
					'prefix-'	=> "styles/{$style_row['imageset_path']}/",
					'prefix+'	=> false,
					'exclude'	=> 'imageset.cfg'
				);

				$data[] = array(
					'src'		=> trim($imageset_cfg),
					'prefix'	=> 'imageset/imageset.cfg'
				);

				end($data);

				$imageset_root = "{$phpbb_root_path}styles/{$style_row['imageset_path']}/imageset/";

				if ($dh = @opendir($imageset_root))
				{
					while (($fname = readdir($dh)) !== false)
					{
						if ($fname[0] != '.' && $fname != 'CVS' && is_dir("$imageset_root$fname"))
						{
							$files[key($files)]['exclude'] .= ',' . $fname . '/imageset.cfg';
						}
					}
					closedir($dh);
				}

				$imageset_lang = array();

				$sql = 'SELECT image_filename, image_name, image_height, image_width, image_lang
					FROM ' . STYLES_IMAGESET_DATA_TABLE . "
					WHERE imageset_id = $style_id
						AND image_lang <> ''";
				$result = $db->sql_query($sql);
				while ($row = $db->sql_fetchrow($result))
				{
					$imageset_lang[$row['image_lang']][$row['image_name']] = $row['image_filename'] . ($row['image_height'] ? '*' . $row['image_height']: '') . ($row['image_width'] ? '*' . $row['image_width']: '');
				}
				$db->sql_freeresult($result);

				foreach ($imageset_lang as $lang => $imageset_localized)
				{
					$imageset_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['imageset_name'], $style_row['imageset_copyright'], $config['version']), $this->imageset_cfg);

					foreach ($this->imageset_keys as $topic => $key_array)
					{
						foreach ($key_array as $key)
						{
							if (isset($imageset_localized[$key]))
							{
								$imageset_cfg .= "\nimg_" . $key . ' = ' . str_replace("styles/{$style_row['imageset_path']}/imageset/", '{PATH}', $imageset_localized[$key]);
							}
						}
					}

					$data[] = array(
						'src'		=> trim($imageset_cfg),
						'prefix'	=> 'imageset/' . $lang . '/imageset.cfg'
					);
				}

				unset($imageset_cfg);
			}

			switch ($format)
			{
				case 'tar':
					$ext = '.tar';
					$mimetype = 'x-tar';
					$compress = 'compress_tar';
				break;

				case 'zip':
					$ext = '.zip';
					$mimetype = 'zip';
				break;

				case 'tar.gz':
					$ext = '.tar.gz';
					$mimetype = 'x-gzip';
				break;

				case 'tar.bz2':
					$ext = '.tar.bz2';
					$mimetype = 'x-bzip2';
				break;

				default:
					$error[] = $user->lang[$l_prefix . '_ERR_ARCHIVE'];
			}

			if (!sizeof($error))
			{
				include($phpbb_root_path . 'includes/functions_compress.' . $phpEx);

				if ($mode == 'style')
				{
					$path = preg_replace('#[^\w-]+#', '_', $style_row['style_name']);
				}
				else
				{
					$path = $style_row[$mode . '_path'];
				}

				if ($format == 'zip')
				{
					$compress = new compress_zip('w', $phpbb_root_path . "store/$path$ext");
				}
				else
				{
					$compress = new compress_tar('w', $phpbb_root_path . "store/$path$ext", $ext);
				}

				if (sizeof($files))
				{
					foreach ($files as $file_ary)
					{
						$compress->add_file($file_ary['src'], $file_ary['prefix-'], $file_ary['prefix+'], $file_ary['exclude']);
					}
				}

				if (sizeof($data))
				{
					foreach ($data as $data_ary)
					{
						$compress->add_data($data_ary['src'], $data_ary['prefix']);
					}
				}

				$compress->close();

				add_log('admin', 'LOG_' . $l_prefix . '_EXPORT', $style_row[$mode . '_name']);

				if (!$store)
				{
					$compress->download($path);
					@unlink("{$phpbb_root_path}store/$path$ext");
					exit;
				}

				trigger_error(sprintf($user->lang[$l_prefix . '_EXPORTED'], "store/$path$ext") . adm_back_link($this->u_action));
			}
		}

		$sql = "SELECT {$mode}_id, {$mode}_name
			FROM " . (($mode == 'style') ? STYLES_TABLE : $sql_from) . "
			WHERE {$mode}_id = $style_id";
		$result = $db->sql_query($sql);
		$style_row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

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

		$this->page_title = $l_prefix . '_EXPORT';

		$format_buttons = '';
		foreach ($methods as $method)
		{
			$format_buttons .= '<label><input type="radio"' . ((!$format_buttons) ? ' id="format"' : '') . ' class="radio" value="' . $method . '" name="format"' . (($method == $format) ? ' checked="checked"' : '') . ' /> ' . $method . '</label>';
		}

		$template->assign_vars(array(
			'S_EXPORT'		=> true,
			'S_ERROR_MSG'	=> (sizeof($error)) ? true : false,
			'S_STYLE'		=> ($mode == 'style') ? true : false,

			'L_TITLE'		=> $user->lang[$this->page_title],
			'L_EXPLAIN'		=> $user->lang[$this->page_title . '_EXPLAIN'],
			'L_NAME'		=> $user->lang[$l_prefix . '_NAME'],

			'U_ACTION'		=> $this->u_action . '&action=export&id=' . $style_id,
			'U_BACK'		=> $this->u_action,

			'ERROR_MSG'			=> (sizeof($error)) ? implode('<br />', $error) : '',
			'NAME'				=> $style_row[$mode . '_name'],
			'FORMAT_BUTTONS'	=> $format_buttons)
		);
	}

	/**
	* Display details
	*/
	function details($mode, $style_id)
	{
		global $template, $db, $config, $user, $safe_mode, $cache, $phpbb_root_path;

		$update = (isset($_POST['update'])) ? true : false;
		$l_type = strtoupper($mode);

		$error = array();
		$element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);

		switch ($mode)
		{
			case 'style':
				$sql_from = STYLES_TABLE;
			break;

			case 'template':
				$sql_from = STYLES_TEMPLATE_TABLE;
			break;

			case 'theme':
				$sql_from = STYLES_THEME_TABLE;
			break;

			case 'imageset':
				$sql_from = STYLES_IMAGESET_TABLE;
			break;
		}

		$sql = "SELECT *
			FROM $sql_from
			WHERE {$mode}_id = $style_id";
		$result = $db->sql_query($sql);
		$style_row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

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

		$style_row['style_default'] = ($mode == 'style' && $config['default_style'] == $style_id) ? 1 : 0;

		if ($update)
		{
			$name = utf8_normalize_nfc(request_var('name', '', true));
			$copyright = utf8_normalize_nfc(request_var('copyright', '', true));

			$template_id = request_var('template_id', 0);
			$theme_id = request_var('theme_id', 0);
			$imageset_id = request_var('imageset_id', 0);

			$style_active = request_var('style_active', 0);
			$style_default = request_var('style_default', 0);
			$store_db = request_var('store_db', 0);

			// If the admin selected the style to be the default style, but forgot to activate it... we will do it for him
			if ($style_default)
			{
				$style_active = 1;
			}

			$sql = "SELECT {$mode}_id, {$mode}_name
				FROM $sql_from
				WHERE {$mode}_id <> $style_id
				AND LOWER({$mode}_name) = '" . $db->sql_escape(strtolower($name)) . "'";
			$result = $db->sql_query($sql);
			$conflict = $db->sql_fetchrow($result);
			$db->sql_freeresult($result);

			if ($mode == 'style' && (!$template_id || !$theme_id || !$imageset_id))
			{
				$error[] = $user->lang['STYLE_ERR_NO_IDS'];
			}

			if ($mode == 'style' && $style_row['style_active'] && !$style_active && $config['default_style'] == $style_id)
			{
				$error[] = $user->lang['DEACTIVATE_DEFAULT'];
			}

			if (!$name || $conflict)
			{
				$error[] = $user->lang[$l_type . '_ERR_STYLE_NAME'];
			}

			if ($mode === 'theme' || $mode === 'template')
			{
				// a rather elaborate check we have to do here once to avoid trouble later
				$check = "{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . (($mode === 'theme') ? '/theme/stylesheet.css' : '/template');
				if (($style_row["{$mode}_storedb"] != $store_db) && !$store_db && ($safe_mode || !@is_writable($check)))
				{
					$error[] = $user->lang['EDIT_' . strtoupper($mode) . '_STORED_DB'];
					$store_db = 1;
				}

				// themes which have to be parsed have to go into db
				if ($mode == 'theme')
				{
					$cfg = parse_cfg_file("{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . "/theme/theme.cfg");

					if (isset($cfg['parse_css_file']) && $cfg['parse_css_file'] && !$store_db)
					{
						$error[] = $user->lang['EDIT_THEME_STORE_PARSED'];
						$store_db = 1;
					}
				}
			}

			if (!sizeof($error))
			{
				// Check length settings
				if (utf8_strlen($name) > 30)
				{
					$error[] = $user->lang[$l_type . '_ERR_NAME_LONG'];
				}

				if (utf8_strlen($copyright) > 60)
				{
					$error[] = $user->lang[$l_type . '_ERR_COPY_LONG'];
				}
			}
		}

		if ($update && sizeof($error))
		{
			$style_row = array_merge($style_row, array(
				'template_id'			=> $template_id,
				'theme_id'				=> $theme_id,
				'imageset_id'			=> $imageset_id,
				'style_active'			=> $style_active,
				$mode . '_storedb'		=> $store_db,
				$mode . '_name'			=> $name,
				$mode . '_copyright'	=> $copyright)
			);
		}

		// User has submitted form and no errors have occurred
		if ($update && !sizeof($error))
		{
			$sql_ary = array(
				$mode . '_name'			=> $name,
				$mode . '_copyright'	=> $copyright
			);

			switch ($mode)
			{
				case 'style':

					$sql_ary += array(
						'template_id'		=> (int) $template_id,
						'theme_id'			=> (int) $theme_id,
						'imageset_id'		=> (int) $imageset_id,
						'style_active'		=> (int) $style_active,
					);
				break;

				case 'imageset':
				break;

				case 'theme':

					if ($style_row['theme_storedb'] != $store_db)
					{
						$theme_data = '';

						if (!$style_row['theme_storedb'])
						{
							$theme_data = $this->db_theme_data($style_row);
						}
						else if (!$store_db && !$safe_mode && @is_writable("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css"))
						{
							$store_db = 1;
							$theme_data = $style_row['theme_data'];

							if ($fp = @fopen("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css", 'wb'))
							{
								$store_db = (@fwrite($fp, str_replace("styles/{$style_row['theme_path']}/theme/", './', $theme_data))) ? 0 : 1;
							}
							fclose($fp);
						}

						$sql_ary += array(
							'theme_mtime'	=> ($store_db) ? filemtime("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css") : 0,
							'theme_storedb'	=> $store_db,
							'theme_data'	=> ($store_db) ? $theme_data : '',
						);
					}
				break;

				case 'template':

					if ($style_row['template_storedb'] != $store_db)
					{
						if ($super = $this->get_super($mode, $style_row['template_id']))
						{
							$error[] = (sprintf($user->lang["{$l_type}_INHERITS"], $super['template_name']));
							$sql_ary = array();
						}
						else
						{
							if (!$store_db && !$safe_mode && @is_writable("{$phpbb_root_path}styles/{$style_row['template_path']}/template"))
							{
								$err = $this->store_in_fs('template', $style_row['template_id']);
								if ($err)
								{
									$error += $err;
								}
							}
							else if ($store_db)
							{
								$this->store_in_db('template', $style_row['template_id']);
							}
							else
							{
								// We no longer store within the db, but are also not able to update the file structure
								// Since the admin want to switch this, we adhere to his decision. But we also need to remove the cache
								$sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
									WHERE template_id = $style_id";
								$db->sql_query($sql);
							}

							$sql_ary += array(
								'template_storedb'	=> $store_db,
							);
						}
					}
				break;
			}

			if (sizeof($sql_ary))
			{
				$sql = "UPDATE $sql_from
					SET " . $db->sql_build_array('UPDATE', $sql_ary) . "
					WHERE {$mode}_id = $style_id";
				$db->sql_query($sql);

				// Making this the default style?
				if ($mode == 'style' && $style_default)
				{
					set_config('default_style', $style_id);
				}
			}

			$cache->destroy('sql', STYLES_TABLE);

			add_log('admin', 'LOG_' . $l_type . '_EDIT_DETAILS', $name);
			if (sizeof($error))
			{
				trigger_error(implode('<br />', $error) . adm_back_link($this->u_action), E_USER_WARNING);
			}
			else
			{
				trigger_error($user->lang[$l_type . '_DETAILS_UPDATED'] . adm_back_link($this->u_action));
			}
		}

		if ($mode == 'style')
		{
			foreach ($element_ary as $element => $table)
			{
				$sql = "SELECT {$element}_id, {$element}_name
					FROM $table
					ORDER BY {$element}_id ASC";
				$result = $db->sql_query($sql);

				${$element . '_options'} = '';
				while ($row = $db->sql_fetchrow($result))
				{
					$selected = ($row[$element . '_id'] == $style_row[$element . '_id']) ? ' selected="selected"' : '';
					${$element . '_options'} .= '<option value="' . $row[$element . '_id'] . '"' . $selected . '>' . $row[$element . '_name'] . '</option>';
				}
				$db->sql_freeresult($result);
			}
		}

		if ($mode == 'template')
		{
			$super = array();
			if (isset($style_row[$mode . '_inherits_id']) && $style_row['template_inherits_id'])
			{
				$super = $this->get_super($mode, $style_row['template_id']);
			}
		}

		$this->page_title = 'EDIT_DETAILS_' . $l_type;

		$template->assign_vars(array(
			'S_DETAILS'				=> true,
			'S_ERROR_MSG'			=> (sizeof($error)) ? true : false,
			'S_STYLE'				=> ($mode == 'style') ? true : false,
			'S_TEMPLATE'			=> ($mode == 'template') ? true : false,
			'S_THEME'				=> ($mode == 'theme') ? true : false,
			'S_IMAGESET'			=> ($mode == 'imageset') ? true : false,
			'S_STORE_DB'			=> (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0,
			'S_STORE_DB_DISABLED'	=> (isset($style_row[$mode . '_inherits_id'])) ? $style_row[$mode . '_inherits_id'] : 0,
			'S_STYLE_ACTIVE'		=> (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
			'S_STYLE_DEFAULT'		=> (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
			'S_SUPERTEMPLATE'		=> (isset($style_row[$mode . '_inherits_id']) && $style_row[$mode . '_inherits_id']) ? $super['template_name'] : 0,

			'S_TEMPLATE_OPTIONS'	=> ($mode == 'style') ? $template_options : '',
			'S_THEME_OPTIONS'		=> ($mode == 'style') ? $theme_options : '',
			'S_IMAGESET_OPTIONS'	=> ($mode == 'style') ? $imageset_options : '',

			'U_ACTION'		=> $this->u_action . '&action=details&id=' . $style_id,
			'U_BACK'		=> $this->u_action,

			'L_TITLE'				=> $user->lang[$this->page_title],
			'L_EXPLAIN'				=> $user->lang[$this->page_title . '_EXPLAIN'],
			'L_NAME'				=> $user->lang[$l_type . '_NAME'],
			'L_LOCATION'			=> ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
			'L_LOCATION_EXPLAIN'	=> ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',

			'ERROR_MSG'		=> (sizeof($error)) ? implode('<br />', $error) : '',
			'NAME'			=> $style_row[$mode . '_name'],
			'COPYRIGHT'		=> $style_row[$mode . '_copyright'],
			)
		);
	}

	/**
	* Load css file contents
	*/
	function load_css_file($path, $filename)
	{
		global $phpbb_root_path;

		$file = "{$phpbb_root_path}styles/$path/theme/$filename";

		if (file_exists($file) && ($content = file_get_contents($file)))
		{
			$content = trim($content);
		}
		else
		{
			$content = '';
		}
		if (defined('DEBUG'))
		{
			$content = "/* BEGIN @include $filename */ \n $content \n /* END @include $filename */ \n";
		}

		return $content;
	}

	/**
	* Returns a string containing the value that should be used for the theme_data column in the theme database table.
	* Includes contents of files loaded via @import
	*
	* @param array $theme_row is an associative array containing the theme's current database entry
	* @param mixed $stylesheet can either be the new content for the stylesheet or false to load from the standard file
	* @param string $root_path should only be used in case you want to use a different root path than "{$phpbb_root_path}styles/{$theme_row['theme_path']}"
	*
	* @return string Stylesheet data for theme_data column in the theme table
	*/
	function db_theme_data($theme_row, $stylesheet = false, $root_path = '')
	{
		global $phpbb_root_path;

		if (!$root_path)
		{
			$root_path = $phpbb_root_path . 'styles/' . $theme_row['theme_path'];
		}

		if (!$stylesheet)
		{
			$stylesheet = '';
			if (file_exists($root_path . '/theme/stylesheet.css'))
			{
				$stylesheet = file_get_contents($root_path . '/theme/stylesheet.css');
			}
		}

		// Match CSS imports
		$matches = array();
		preg_match_all('/@import url\(["\'](.*)["\']\);/i', $stylesheet, $matches);

		if (sizeof($matches))
		{
			foreach ($matches[0] as $idx => $match)
			{
				$stylesheet = str_replace($match, acp_styles::load_css_file($theme_row['theme_path'], $matches[1][$idx]), $stylesheet);
			}
		}

		// adjust paths
		return str_replace('./', 'styles/' . $theme_row['theme_path'] . '/theme/', $stylesheet);
	}

	/**
	* Store template files into db
	*/
	function store_templates($mode, $style_id, $template_path, $filelist)
	{
		global $phpbb_root_path, $phpEx, $db;

		$template_path = $template_path . '/template/';
		$includes = array();
		foreach ($filelist as $pathfile => $file_ary)
		{
			foreach ($file_ary as $file)
			{
				if (!($fp = @fopen("{$phpbb_root_path}styles/$template_path$pathfile$file", 'r')))
				{
					trigger_error("Could not open {$phpbb_root_path}styles/$template_path$pathfile$file", E_USER_ERROR);
				}

				$filesize = filesize("{$phpbb_root_path}styles/$template_path$pathfile$file");

				if ($filesize)
				{
					$template_data = fread($fp, $filesize);
				}

				fclose($fp);

				if (!$filesize)
				{
					// File is empty
					continue;
				}

				if (preg_match_all('#<!-- INCLUDE (.*?\.html) -->#is', $template_data, $matches))
				{
					foreach ($matches[1] as $match)
					{
						$includes[trim($match)][] = $file;
					}
				}
			}
		}

		foreach ($filelist as $pathfile => $file_ary)
		{
			foreach ($file_ary as $file)
			{
				// Skip index.
				if (strpos($file, 'index.') === 0)
				{
					continue;
				}

				// We could do this using extended inserts ... but that could be one
				// heck of a lot of data ...
				$sql_ary = array(
					'template_id'			=> (int) $style_id,
					'template_filename'		=> "$pathfile$file",
					'template_included'		=> (isset($includes[$file])) ? implode(':', $includes[$file]) . ':' : '',
					'template_mtime'		=> (int) filemtime("{$phpbb_root_path}styles/$template_path$pathfile$file"),
					'template_data'			=> (string) file_get_contents("{$phpbb_root_path}styles/$template_path$pathfile$file"),
				);

				if ($mode == 'insert')
				{
					$sql = 'INSERT INTO ' . STYLES_TEMPLATE_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
				}
				else
				{
					$sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
						WHERE template_id = $style_id
							AND template_filename = '" . $db->sql_escape("$pathfile$file") . "'";
				}
				$db->sql_query($sql);
			}
		}
	}

	/**
	* Returns an array containing all template filenames for one template that are currently cached.
	*
	* @param string $template_path contains the name of the template's folder in /styles/
	*
	* @return array of filenames that exist in /styles/$template_path/template/ (without extension!)
	*/
	function template_cache_filelist($template_path)
	{
		global $phpbb_root_path, $phpEx, $user;

		$cache_prefix = 'tpl_' . str_replace('_', '-', $template_path);

		if (!($dp = @opendir("{$phpbb_root_path}cache")))
		{
			trigger_error($user->lang['TEMPLATE_ERR_CACHE_READ'] . adm_back_link($this->u_action), E_USER_WARNING);
		}

		$file_ary = array();
		while ($file = readdir($dp))
		{
			if ($file[0] == '.')
			{
				continue;
			}

			if (is_file($phpbb_root_path . 'cache/' . $file) && (strpos($file, $cache_prefix) === 0))
			{
				$file_ary[] = str_replace('.', '/', preg_replace('#^' . preg_quote($cache_prefix, '#') . '_(.*?)\.html\.' . $phpEx . '$#i', '\1', $file));
			}
		}
		closedir($dp);

		return $file_ary;
	}

	/**
	* Destroys cached versions of template files
	*
	* @param array $template_row contains the template's row in the STYLES_TEMPLATE_TABLE database table
	* @param mixed $file_ary is optional and may contain an array of template file names which should be refreshed in the cache.
	*	The file names should be the original template file names and not the cache file names.
	*/
	function clear_template_cache($template_row, $file_ary = false)
	{
		global $phpbb_root_path, $phpEx, $user;

		$cache_prefix = 'tpl_' . str_replace('_', '-', $template_row['template_path']);

		if (!$file_ary || !is_array($file_ary))
		{
			$file_ary = $this->template_cache_filelist($template_row['template_path']);
			$log_file_list = $user->lang['ALL_FILES'];
		}
		else
		{
			$log_file_list = implode(', ', $file_ary);
		}

		foreach ($file_ary as $file)
		{
			$file = str_replace('/', '.', $file);

			$file = "{$phpbb_root_path}cache/{$cache_prefix}_$file.html.$phpEx";
			if (file_exists($file) && is_file($file))
			{
				@unlink($file);
			}
		}
		unset($file_ary);

		add_log('admin', 'LOG_TEMPLATE_CACHE_CLEARED', $template_row['template_name'], $log_file_list);
	}

	/**
	* Install Style/Template/Theme/Imageset
	*/
	function install($mode)
	{
		global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;

		$l_type = strtoupper($mode);

		$error = $installcfg = $style_row = array();
		$root_path = $cfg_file = '';
		$element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);

		$install_path = request_var('path', '');
		$update = (isset($_POST['update'])) ? true : false;

		// Installing, obtain cfg file contents
		if ($install_path)
		{
			$root_path = $phpbb_root_path . 'styles/' . $install_path . '/';
			$cfg_file = ($mode == 'style') ? "$root_path$mode.cfg" : "$root_path$mode/$mode.cfg";

			if (!file_exists($cfg_file))
			{
				$error[] = $user->lang[$l_type . '_ERR_NOT_' . $l_type];
			}
			else
			{
				$installcfg = parse_cfg_file($cfg_file);
			}
		}

		// Installing
		if (sizeof($installcfg))
		{
			$name		= $installcfg['name'];
			$copyright	= $installcfg['copyright'];
			$version	= $installcfg['version'];

			$style_row = array(
				$mode . '_id'			=> 0,
				$mode . '_name'			=> '',
				$mode . '_copyright'	=> ''
			);

			switch ($mode)
			{
				case 'style':

					$style_row = array(
						'style_id'			=> 0,
						'style_name'		=> $installcfg['name'],
						'style_copyright'	=> $installcfg['copyright']
					);

					$reqd_template = (isset($installcfg['required_template'])) ? $installcfg['required_template'] : false;
					$reqd_theme = (isset($installcfg['required_theme'])) ? $installcfg['required_theme'] : false;
					$reqd_imageset = (isset($installcfg['required_imageset'])) ? $installcfg['required_imageset'] : false;

					// Check to see if each element is already installed, if it is grab the id
					foreach ($element_ary as $element => $table)
					{
						$style_row = array_merge($style_row, array(
							$element . '_id'			=> 0,
							$element . '_name'			=> '',
							$element . '_copyright'		=> '')
						);

			 			$this->test_installed($element, $error, (${'reqd_' . $element}) ? $phpbb_root_path . 'styles/' . $reqd_template . '/' : $root_path, ${'reqd_' . $element}, $style_row[$element . '_id'], $style_row[$element . '_name'], $style_row[$element . '_copyright']);

						if (!$style_row[$element . '_name'])
						{
							$style_row[$element . '_name'] = $reqd_template;
						}

						// Merge other information to installcfg... if present
						$cfg_file = $phpbb_root_path . 'styles/' . $install_path . '/' . $element . '/' . $element . '.cfg';

						if (file_exists($cfg_file))
						{
							$cfg_contents = parse_cfg_file($cfg_file);

							// Merge only specific things. We may need them later.
							foreach (array('inherit_from', 'parse_css_file') as $key)
							{
								if (!empty($cfg_contents[$key]) && !isset($installcfg[$key]))
								{
									$installcfg[$key] = $cfg_contents[$key];
								}
							}
						}
					}

				break;

				case 'template':
					$this->test_installed('template', $error, $root_path, false, $style_row['template_id'], $style_row['template_name'], $style_row['template_copyright']);
				break;

				case 'theme':
					$this->test_installed('theme', $error, $root_path, false, $style_row['theme_id'], $style_row['theme_name'], $style_row['theme_copyright']);
				break;

				case 'imageset':
					$this->test_installed('imageset', $error, $root_path, false, $style_row['imageset_id'], $style_row['imageset_name'], $style_row['imageset_copyright']);
				break;
			}
		}
		else
		{
			trigger_error($user->lang['NO_' . $l_type] . adm_back_link($this->u_action), E_USER_WARNING);
		}

		$style_row['store_db'] = request_var('store_db', 0);
		$style_row['style_active'] = request_var('style_active', 1);
		$style_row['style_default'] = request_var('style_default', 0);

		// User has submitted form and no errors have occurred
		if ($update && !sizeof($error))
		{
			if ($mode == 'style')
			{
				foreach ($element_ary as $element => $table)
				{
					${$element . '_root_path'} = (${'reqd_' . $element}) ? $phpbb_root_path . 'styles/' . ${'reqd_' . $element} . '/' : false;
					${$element . '_path'} = (${'reqd_' . $element}) ? ${'reqd_' . $element} : false;
				}
				$this->install_style($error, 'install', $root_path, $style_row['style_id'], $style_row['style_name'], $install_path, $style_row['style_copyright'], $style_row['style_active'], $style_row['style_default'], $style_row, $template_root_path, $template_path, $theme_root_path, $theme_path, $imageset_root_path, $imageset_path);
			}
			else
			{
				$style_row['store_db'] = $this->install_element($mode, $error, 'install', $root_path, $style_row[$mode . '_id'], $style_row[$mode . '_name'], $install_path, $style_row[$mode . '_copyright'], $style_row['store_db']);
			}

			if (!sizeof($error))
			{
				$cache->destroy('sql', STYLES_TABLE);

				$message = ($style_row['store_db']) ? '_ADDED_DB' : '_ADDED';
				trigger_error($user->lang[$l_type . $message] . adm_back_link($this->u_action));
			}
		}

		$this->page_title = 'INSTALL_' . $l_type;

		$template->assign_vars(array(
			'S_DETAILS'			=> true,
			'S_INSTALL'			=> true,
			'S_ERROR_MSG'		=> (sizeof($error)) ? true : false,
			'S_LOCATION'		=> (isset($installcfg['inherit_from']) && $installcfg['inherit_from']) ? false : true,
			'S_STYLE'			=> ($mode == 'style') ? true : false,
			'S_TEMPLATE'		=> ($mode == 'template') ? true : false,
			'S_SUPERTEMPLATE'	=> (isset($installcfg['inherit_from'])) ? $installcfg['inherit_from'] : '',
			'S_THEME'			=> ($mode == 'theme') ? true : false,

			'S_STORE_DB'			=> (isset($style_row[$mode . '_storedb'])) ? $style_row[$mode . '_storedb'] : 0,
			'S_STYLE_ACTIVE'		=> (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
			'S_STYLE_DEFAULT'		=> (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,

			'U_ACTION'			=> $this->u_action . "&action=install&path=" . urlencode($install_path),
			'U_BACK'			=> $this->u_action,

			'L_TITLE'				=> $user->lang[$this->page_title],
			'L_EXPLAIN'				=> $user->lang[$this->page_title . '_EXPLAIN'],
			'L_NAME'				=> $user->lang[$l_type . '_NAME'],
			'L_LOCATION'			=> ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
			'L_LOCATION_EXPLAIN'	=> ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',

			'ERROR_MSG'			=> (sizeof($error)) ? implode('<br />', $error) : '',
			'NAME'				=> $style_row[$mode . '_name'],
			'COPYRIGHT'			=> $style_row[$mode . '_copyright'],
			'TEMPLATE_NAME'		=> ($mode == 'style') ? $style_row['template_name'] : '',
			'THEME_NAME'		=> ($mode == 'style') ? $style_row['theme_name'] : '',
			'IMAGESET_NAME'		=> ($mode == 'style') ? $style_row['imageset_name'] : '')
		);
	}

	/**
	* Add new style
	*/
	function add($mode)
	{
		global $phpbb_root_path, $phpEx, $config, $db, $cache, $user, $template;

		$l_type = strtoupper($mode);
		$element_ary = array('template' => STYLES_TEMPLATE_TABLE, 'theme' => STYLES_THEME_TABLE, 'imageset' => STYLES_IMAGESET_TABLE);
		$error = array();

		$style_row = array(
			$mode . '_name'			=> utf8_normalize_nfc(request_var('name', '', true)),
			$mode . '_copyright'	=> utf8_normalize_nfc(request_var('copyright', '', true)),
			'template_id'			=> 0,
			'theme_id'				=> 0,
			'imageset_id'			=> 0,
			'store_db'				=> request_var('store_db', 0),
			'style_active'			=> request_var('style_active', 1),
			'style_default'			=> request_var('style_default', 0),
		);

		$basis = request_var('basis', 0);
		$update = (isset($_POST['update'])) ? true : false;

		if ($basis)
		{
			switch ($mode)
			{
				case 'style':
					$sql_select = 'template_id, theme_id, imageset_id';
					$sql_from = STYLES_TABLE;
				break;

				case 'template':
					$sql_select = 'template_id';
					$sql_from = STYLES_TEMPLATE_TABLE;
				break;

				case 'theme':
					$sql_select = 'theme_id';
					$sql_from = STYLES_THEME_TABLE;
				break;

				case 'imageset':
					$sql_select = 'imageset_id';
					$sql_from = STYLES_IMAGESET_TABLE;
				break;
			}

			$sql = "SELECT $sql_select
				FROM $sql_from
				WHERE {$mode}_id = $basis";
			$result = $db->sql_query($sql);
			$row = $db->sql_fetchrow($result);
			$db->sql_freeresult($result);

			if (!$row)
			{
				$error[] = $user->lang['NO_' . $l_type];
			}

			if (!sizeof($error))
			{
				$style_row['template_id']	= (isset($row['template_id'])) ? $row['template_id'] : $style_row['template_id'];
				$style_row['theme_id']		= (isset($row['theme_id'])) ? $row['theme_id'] : $style_row['theme_id'];
				$style_row['imageset_id']	= (isset($row['imageset_id'])) ? $row['imageset_id'] : $style_row['imageset_id'];
			}
		}

		if ($update)
		{
			$style_row['template_id'] = request_var('template_id', $style_row['template_id']);
			$style_row['theme_id'] = request_var('theme_id', $style_row['theme_id']);
			$style_row['imageset_id'] = request_var('imageset_id', $style_row['imageset_id']);

			if ($mode == 'style' && (!$style_row['template_id'] || !$style_row['theme_id'] || !$style_row['imageset_id']))
			{
				$error[] = $user->lang['STYLE_ERR_NO_IDS'];
			}
		}

		// User has submitted form and no errors have occurred
		if ($update && !sizeof($error))
		{
			if ($mode == 'style')
			{
				$style_row['style_id'] = 0;

				$this->install_style($error, 'add', '', $style_row['style_id'], $style_row['style_name'], '', $style_row['style_copyright'], $style_row['style_active'], $style_row['style_default'], $style_row);
			}

			if (!sizeof($error))
			{
				$cache->destroy('sql', STYLES_TABLE);

				$message = ($style_row['store_db']) ? '_ADDED_DB' : '_ADDED';
				trigger_error($user->lang[$l_type . $message] . adm_back_link($this->u_action));
			}
		}

		if ($mode == 'style')
		{
			foreach ($element_ary as $element => $table)
			{
				$sql = "SELECT {$element}_id, {$element}_name
					FROM $table
					ORDER BY {$element}_id ASC";
				$result = $db->sql_query($sql);

				${$element . '_options'} = '';
				while ($row = $db->sql_fetchrow($result))
				{
					$selected = ($row[$element . '_id'] == $style_row[$element . '_id']) ? ' selected="selected"' : '';
					${$element . '_options'} .= '<option value="' . $row[$element . '_id'] . '"' . $selected . '>' . $row[$element . '_name'] . '</option>';
				}
				$db->sql_freeresult($result);
			}
		}

		$this->page_title = 'ADD_' . $l_type;

		$template->assign_vars(array(
			'S_DETAILS'			=> true,
			'S_ADD'				=> true,
			'S_ERROR_MSG'		=> (sizeof($error)) ? true : false,
			'S_STYLE'			=> ($mode == 'style') ? true : false,
			'S_TEMPLATE'		=> ($mode == 'template') ? true : false,
			'S_THEME'			=> ($mode == 'theme') ? true : false,
			'S_BASIS'			=> ($basis) ? true : false,

			'S_STORE_DB'			=> (isset($style_row['storedb'])) ? $style_row['storedb'] : 0,
			'S_STYLE_ACTIVE'		=> (isset($style_row['style_active'])) ? $style_row['style_active'] : 0,
			'S_STYLE_DEFAULT'		=> (isset($style_row['style_default'])) ? $style_row['style_default'] : 0,
			'S_TEMPLATE_OPTIONS'	=> ($mode == 'style') ? $template_options : '',
			'S_THEME_OPTIONS'		=> ($mode == 'style') ? $theme_options : '',
			'S_IMAGESET_OPTIONS'	=> ($mode == 'style') ? $imageset_options : '',

			'U_ACTION'			=> $this->u_action . '&action=add&basis=' . $basis,
			'U_BACK'			=> $this->u_action,

			'L_TITLE'				=> $user->lang[$this->page_title],
			'L_EXPLAIN'				=> $user->lang[$this->page_title . '_EXPLAIN'],
			'L_NAME'				=> $user->lang[$l_type . '_NAME'],
			'L_LOCATION'			=> ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION'] : '',
			'L_LOCATION_EXPLAIN'	=> ($mode == 'template' || $mode == 'theme') ? $user->lang[$l_type . '_LOCATION_EXPLAIN'] : '',

			'ERROR_MSG'			=> (sizeof($error)) ? implode('<br />', $error) : '',
			'NAME'				=> $style_row[$mode . '_name'],
			'COPYRIGHT'			=> $style_row[$mode . '_copyright'])
		);

	}

	/**

					$reqd_template = (isset($installcfg['required_template'])) ? $installcfg['required_template'] : false;
					$reqd_theme = (isset($installcfg['required_theme'])) ? $installcfg['required_theme'] : false;
					$reqd_imageset = (isset($installcfg['required_imageset'])) ? $installcfg['required_imageset'] : false;

					// Check to see if each element is already installed, if it is grab the id
					foreach ($element_ary as $element => $table)
					{
						$style_row = array_merge($style_row, array(
							$element . '_id'			=> 0,
							$element . '_name'			=> '',
							$element . '_copyright'		=> '')
						);

			 			$this->test_installed($element, $error, $root_path, ${'reqd_' . $element}, $style_row[$element . '_id'], $style_row[$element . '_name'], $style_row[$element . '_copyright']);
	* Is this element installed? If not, grab its cfg details
	*/
	function test_installed($element, &$error, $root_path, $reqd_name, &$id, &$name, &$copyright)
	{
		global $db, $user;

		switch ($element)
		{
			case 'template':
				$sql_from = STYLES_TEMPLATE_TABLE;
			break;

			case 'theme':
				$sql_from = STYLES_THEME_TABLE;
			break;

			case 'imageset':
				$sql_from = STYLES_IMAGESET_TABLE;
			break;
		}

		$l_element = strtoupper($element);

		$chk_name = ($reqd_name !== false) ? $reqd_name : $name;

		$sql = "SELECT {$element}_id, {$element}_name
			FROM $sql_from
			WHERE {$element}_name = '" . $db->sql_escape($chk_name) . "'";
		$result = $db->sql_query($sql);

		if ($row = $db->sql_fetchrow($result))
		{
			$name = $row[$element . '_name'];
			$id = $row[$element . '_id'];
		}
		else
		{
			if (!($cfg = @file("$root_path$element/$element.cfg")))
			{
				$error[] = sprintf($user->lang['REQUIRES_' . $l_element], $reqd_name);
				return false;
			}

			$cfg = parse_cfg_file("$root_path$element/$element.cfg", $cfg);

			$name = $cfg['name'];
			$copyright = $cfg['copyright'];
			$id = 0;

			unset($cfg);
		}
		$db->sql_freeresult($result);
	}

	/**
	* Install/Add style
	*/
	function install_style(&$error, $action, $root_path, &$id, $name, $path, $copyright, $active, $default, &$style_row, $template_root_path = false, $template_path = false, $theme_root_path = false, $theme_path = false, $imageset_root_path = false, $imageset_path = false)
	{
		global $config, $db, $user;

		$element_ary = array('template', 'theme', 'imageset');

		if (!$name)
		{
			$error[] = $user->lang['STYLE_ERR_STYLE_NAME'];
		}

		// Check length settings
		if (utf8_strlen($name) > 30)
		{
			$error[] = $user->lang['STYLE_ERR_NAME_LONG'];
		}

		if (utf8_strlen($copyright) > 60)
		{
			$error[] = $user->lang['STYLE_ERR_COPY_LONG'];
		}

		// Check if the name already exist
		$sql = 'SELECT style_id
			FROM ' . STYLES_TABLE . "
			WHERE style_name = '" . $db->sql_escape($name) . "'";
		$result = $db->sql_query($sql);
		$row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

		if ($row)
		{
			$error[] = $user->lang['STYLE_ERR_NAME_EXIST'];
		}

		if (sizeof($error))
		{
			return false;
		}

		foreach ($element_ary as $element)
		{
			// Zero id value ... need to install element ... run usual checks
			// and do the install if necessary
			if (!$style_row[$element . '_id'])
			{
				$this->install_element($element, $error, $action, (${$element . '_root_path'}) ? ${$element . '_root_path'} : $root_path, $style_row[$element . '_id'], $style_row[$element . '_name'], (${$element . '_path'}) ? ${$element . '_path'} : $path, $style_row[$element . '_copyright']);
			}
		}

		if (!$style_row['template_id'] || !$style_row['theme_id'] || !$style_row['imageset_id'])
		{
			$error[] = $user->lang['STYLE_ERR_NO_IDS'];
		}

		if (sizeof($error))
		{
			return false;
		}

		$db->sql_transaction('begin');

		$sql_ary = array(
			'style_name'		=> $name,
			'style_copyright'	=> $copyright,
			'style_active'		=> (int) $active,
			'template_id'		=> (int) $style_row['template_id'],
			'theme_id'			=> (int) $style_row['theme_id'],
			'imageset_id'		=> (int) $style_row['imageset_id'],
		);

		$sql = 'INSERT INTO ' . STYLES_TABLE . '
			' . $db->sql_build_array('INSERT', $sql_ary);
		$db->sql_query($sql);

		$id = $db->sql_nextid();

		if ($default)
		{
			$sql = 'UPDATE ' . USERS_TABLE . "
				SET user_style = $id
				WHERE user_style = " . $config['default_style'];
			$db->sql_query($sql);

			set_config('default_style', $id);
		}

		$db->sql_transaction('commit');

		add_log('admin', 'LOG_STYLE_ADD', $name);
	}

	/**
	* Install/add an element, doing various checks as we go
	*/
	function install_element($mode, &$error, $action, $root_path, &$id, $name, $path, $copyright, $store_db = 0)
	{
		global $phpbb_root_path, $db, $user;

		// we parse the cfg here (again)
		$cfg_data = parse_cfg_file("$root_path$mode/$mode.cfg");

		switch ($mode)
		{
			case 'template':
				$sql_from = STYLES_TEMPLATE_TABLE;
			break;

			case 'theme':
				$sql_from = STYLES_THEME_TABLE;
			break;

			case 'imageset':
				$sql_from = STYLES_IMAGESET_TABLE;
			break;
		}

		$l_type = strtoupper($mode);

		if (!$name)
		{
			$error[] = $user->lang[$l_type . '_ERR_STYLE_NAME'];
		}

		// Check length settings
		if (utf8_strlen($name) > 30)
		{
			$error[] = $user->lang[$l_type . '_ERR_NAME_LONG'];
		}

		if (utf8_strlen($copyright) > 60)
		{
			$error[] = $user->lang[$l_type . '_ERR_COPY_LONG'];
		}

		// Check if the name already exist
		$sql = "SELECT {$mode}_id
			FROM $sql_from
			WHERE {$mode}_name = '" . $db->sql_escape($name) . "'";
		$result = $db->sql_query($sql);
		$row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

		if ($row)
		{
			// If it exist, we just use the style on installation
			if ($action == 'install')
			{
				$id = $row[$mode . '_id'];
				return false;
			}

			$error[] = $user->lang[$l_type . '_ERR_NAME_EXIST'];
		}

		if (isset($cfg_data['inherit_from']) && $cfg_data['inherit_from'])
		{
			if ($mode === 'template')
			{
				$select_bf = ', bbcode_bitfield';
			}
			else
			{
				$select_bf = '';
			}

			$sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path, {$mode}_storedb $select_bf
				FROM $sql_from
				WHERE {$mode}_name = '" . $db->sql_escape($cfg_data['inherit_from']) . "'
					AND {$mode}_inherits_id = 0";
			$result = $db->sql_query($sql);
			$row = $db->sql_fetchrow($result);
			$db->sql_freeresult($result);
			if (!$row)
			{
				$error[] = sprintf($user->lang[$l_type . '_ERR_REQUIRED_OR_INCOMPLETE'], $cfg_data['inherit_from']);
			}
			else
			{
				$inherit_id = $row["{$mode}_id"];
				$inherit_path = $row["{$mode}_path"];
				$inherit_bf = ($mode === 'template') ? $row["bbcode_bitfield"] : false;
				$cfg_data['store_db'] = $row["{$mode}_storedb"];
				$store_db = $row["{$mode}_storedb"];
			}
		}
		else
		{
			$inherit_id = 0;
			$inherit_path = '';
			$inherit_bf = false;
		}

		if (sizeof($error))
		{
			return false;
		}

		$sql_ary = array(
			$mode . '_name'			=> $name,
			$mode . '_copyright'	=> $copyright,
			$mode . '_path'			=> $path,
		);

		switch ($mode)
		{
			case 'template':
				// We check if the template author defined a different bitfield
				if (!empty($cfg_data['template_bitfield']))
				{
					$sql_ary['bbcode_bitfield'] = $cfg_data['template_bitfield'];
				}
				else if ($inherit_bf)
				{
					$sql_ary['bbcode_bitfield'] = $inherit_bf;
				}
				else
				{
					$sql_ary['bbcode_bitfield'] = TEMPLATE_BITFIELD;
				}

				// We set a pre-defined bitfield here which we may use further in 3.2
				$sql_ary += array(
					'template_storedb'		=> $store_db,
				);
				if (isset($cfg_data['inherit_from']) && $cfg_data['inherit_from'])
				{
					$sql_ary += array(
						'template_inherits_id'	=> $inherit_id,
						'template_inherit_path' => $inherit_path,
					);
				}
			break;

			case 'theme':
				// We are only interested in the theme configuration for now

				if (isset($cfg_data['parse_css_file']) && $cfg_data['parse_css_file'])
				{
					$store_db = 1;
				}

				$sql_ary += array(
					'theme_storedb'	=> $store_db,
					'theme_data'	=> ($store_db) ? $this->db_theme_data($sql_ary, false, $root_path) : '',
					'theme_mtime'	=> (int) filemtime("{$phpbb_root_path}styles/$path/theme/stylesheet.css")
				);
			break;

			// all the heavy lifting is done later
			case 'imageset':
			break;
		}

		$db->sql_transaction('begin');

		$sql = "INSERT INTO $sql_from
			" . $db->sql_build_array('INSERT', $sql_ary);
		$db->sql_query($sql);

		$id = $db->sql_nextid();

		if ($mode == 'template' && $store_db)
		{
			$filelist = filelist("{$root_path}template", '', 'html');
			$this->store_templates('insert', $id, $path, $filelist);
		}
		else if ($mode == 'imageset')
		{
			$cfg_data = parse_cfg_file("$root_path$mode/imageset.cfg");

			$imageset_definitions = array();
			foreach ($this->imageset_keys as $topic => $key_array)
			{
				$imageset_definitions = array_merge($imageset_definitions, $key_array);
			}

			foreach ($cfg_data as $key => $value)
			{
				if (strpos($value, '*') !== false)
				{
					if (substr($value, -1, 1) === '*')
					{
						list($image_filename, $image_height) = explode('*', $value);
						$image_width = 0;
					}
					else
					{
						list($image_filename, $image_height, $image_width) = explode('*', $value);
					}
				}
				else
				{
					$image_filename = $value;
					$image_height = $image_width = 0;
				}

				if (strpos($key, 'img_') === 0 && $image_filename)
				{
					$key = substr($key, 4);
					if (in_array($key, $imageset_definitions))
					{
						$sql_ary = array(
							'image_name'		=> $key,
							'image_filename'	=> str_replace('{PATH}', "styles/$path/imageset/", trim($image_filename)),
							'image_height'		=> (int) $image_height,
							'image_width'		=> (int) $image_width,
							'imageset_id'		=> (int) $id,
							'image_lang'		=> '',
						);
						$db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
					}
				}
			}
			unset($cfg_data);

			$sql = 'SELECT lang_dir
				FROM ' . LANG_TABLE;
			$result = $db->sql_query($sql);

			while ($row = $db->sql_fetchrow($result))
			{
				if (@file_exists("$root_path$mode/{$row['lang_dir']}/imageset.cfg"))
				{
					$cfg_data_imageset_data = parse_cfg_file("$root_path$mode/{$row['lang_dir']}/imageset.cfg");
					foreach ($cfg_data_imageset_data as $image_name => $value)
					{
						if (strpos($value, '*') !== false)
						{
							if (substr($value, -1, 1) === '*')
							{
								list($image_filename, $image_height) = explode('*', $value);
								$image_width = 0;
							}
							else
							{
								list($image_filename, $image_height, $image_width) = explode('*', $value);
							}
						}
						else
						{
							$image_filename = $value;
							$image_height = $image_width = 0;
						}

						if (strpos($image_name, 'img_') === 0 && $image_filename)
						{
							$image_name = substr($image_name, 4);
							if (in_array($image_name, $imageset_definitions))
							{
								$sql_ary = array(
									'image_name'		=> $image_name,
									'image_filename'	=> $image_filename,
									'image_height'		=> (int) $image_height,
									'image_width'		=> (int) $image_width,
									'imageset_id'		=> (int) $id,
									'image_lang'		=> $row['lang_dir'],
								);
								$db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
							}
						}
					}
					unset($cfg_data_imageset_data);
				}
			}
			$db->sql_freeresult($result);
		}

		$db->sql_transaction('commit');

		$log = ($store_db) ? 'LOG_' . $l_type . '_ADD_DB' : 'LOG_' . $l_type . '_ADD_FS';
		add_log('admin', $log, $name);

		// Return store_db in case it had to be altered
		return $store_db;
	}

	/**
	* Checks downwards dependencies
	*
	* @access public
	* @param string $mode The element type to check - only template is supported
	* @param int $id The template id
	* @returns false if no component inherits, array with name, path and id for each subtemplate otherwise
	*/
	function check_inheritance($mode, $id)
	{
		global $db;

		$l_type = strtoupper($mode);

		switch ($mode)
		{
			case 'template':
				$sql_from = STYLES_TEMPLATE_TABLE;
			break;

			case 'theme':
				$sql_from = STYLES_THEME_TABLE;
			break;

			case 'imageset':
				$sql_from = STYLES_IMAGESET_TABLE;
			break;
		}

		$sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path
			FROM $sql_from
			WHERE {$mode}_inherits_id = " . (int) $id;
		$result = $db->sql_query($sql);

		$names = array();
		while ($row = $db->sql_fetchrow($result))
		{

			$names[$row["{$mode}_id"]] = array(
				"{$mode}_id" => $row["{$mode}_id"],
				"{$mode}_name" => $row["{$mode}_name"],
				"{$mode}_path" => $row["{$mode}_path"],
			);
		}
		$db->sql_freeresult($result);

		if (sizeof($names))
		{
			return $names;
		}
		else
		{
			return false;
		}
	}

	/**
	* Checks upwards dependencies
	*
	* @access public
	* @param string $mode The element type to check - only template is supported
	* @param int $id The template id
	* @returns false if the component does not inherit, array with name, path and id otherwise
	*/
	function get_super($mode, $id)
	{
		global $db;

		$l_type = strtoupper($mode);

		switch ($mode)
		{
			case 'template':
				$sql_from = STYLES_TEMPLATE_TABLE;
			break;

			case 'theme':
				$sql_from = STYLES_THEME_TABLE;
			break;

			case 'imageset':
				$sql_from = STYLES_IMAGESET_TABLE;
			break;
		}

		$sql = "SELECT {$mode}_inherits_id
			FROM $sql_from
			WHERE {$mode}_id = " . (int) $id;
		$result = $db->sql_query_limit($sql, 1);

		if ($row = $db->sql_fetchrow($result))
		{
			$db->sql_freeresult($result);
		}
		else
		{
			return false;
		}

		$super_id = $row["{$mode}_inherits_id"];

		$sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path
			FROM $sql_from
			WHERE {$mode}_id = " . (int) $super_id;

		$result = $db->sql_query_limit($sql, 1);
		if ($row = $db->sql_fetchrow($result))
		{
			$db->sql_freeresult($result);
			return $row;
		}

		return false;
	}

	/**
	* Moves a template set and its subtemplates to the database
	*
	* @access public
	* @param string $mode The component to move - only template is supported
	* @param int $id The template id
	*/
	function store_in_db($mode, $id)
	{
		global $db, $user;

		$error = array();
		$l_type = strtoupper($mode);
		if ($super = $this->get_super($mode, $id))
		{
			$error[] = (sprintf($user->lang["{$l_type}_INHERITS"], $super['template_name']));
			return $error;
		}

		$sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path
			FROM " . STYLES_TEMPLATE_TABLE . '
			WHERE template_id = ' . (int) $id;

		$result = $db->sql_query_limit($sql, 1);
		if ($row = $db->sql_fetchrow($result))
		{
			$db->sql_freeresult($result);
			$subs = $this->check_inheritance($mode, $id);

			$this->_store_in_db($mode, $id, $row["{$mode}_path"]);
			if ($subs && sizeof($subs))
			{
				foreach ($subs as $sub_id => $sub)
				{
					if ($err = $this->_store_in_db($mode, $sub["{$mode}_id"], $sub["{$mode}_path"]))
					{
						$error[] = $err;
					}
				}
			}
		}
		if (sizeof($error))
		{
			return $error;
		}

		return false;
	}

	/**
	* Moves a template set to the database
	*
	* @access private
	* @param string $mode The component to move - only template is supported
	* @param int $id The template id
	* @param string $path TThe path to the template files
	*/
	function _store_in_db($mode, $id, $path)
	{
		global $phpbb_root_path, $db;

		$filelist = filelist("{$phpbb_root_path}styles/{$path}/template", '', 'html');
		$this->store_templates('insert', $id, $path, $filelist);

		// Okay, we do the query here -shouldn't be triggered often.
		$sql = 'UPDATE ' . STYLES_TEMPLATE_TABLE . '
						SET template_storedb = 1
						WHERE template_id = ' . $id;
		$db->sql_query($sql);
	}

	/**
	* Moves a template set and its subtemplates to the filesystem
	*
	* @access public
	* @param string $mode The component to move - only template is supported
	* @param int $id The template id
	*/
	function store_in_fs($mode, $id)
	{
		global $db, $user;

		$error = array();
		$l_type = strtoupper($mode);
		if ($super = $this->get_super($mode, $id))
		{
			$error[] = (sprintf($user->lang["{$l_type}_INHERITS"], $super['template_name']));
			return($error);
		}

		$sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path
			FROM " . STYLES_TEMPLATE_TABLE . '
			WHERE template_id = ' . (int) $id;

		$result = $db->sql_query_limit($sql, 1);
		if ($row = $db->sql_fetchrow($result))
		{
			$db->sql_freeresult($result);
			if (!sizeof($error))
			{
				$subs = $this->check_inheritance($mode, $id);

				$this->_store_in_fs($mode, $id, $row["{$mode}_path"]);

				if ($subs && sizeof($subs))
				{
					foreach ($subs as $sub_id => $sub)
					{
						$this->_store_in_fs($mode, $sub["{$mode}_id"], $sub["{$mode}_path"]);
					}
				}
			}
			if (sizeof($error))
			{
				$this->store_in_db($id, $mode);
				return $error;
			}
		}
		return false;
	}

	/**
	* Moves a template set to the filesystem
	*
	* @access private
	* @param string $mode The component to move - only template is supported
	* @param int $id The template id
	* @param string $path The path to the template
	*/
	function _store_in_fs($mode, $id, $path)
	{
		global $phpbb_root_path, $db, $user, $safe_mode;

		$store_db = 0;
		$error = array();
		if (!$safe_mode && @is_writable("{$phpbb_root_path}styles/{$path}/template"))
		{
			$sql = 'SELECT *
					FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
					WHERE template_id = $id";
			$result = $db->sql_query($sql);

			while ($row = $db->sql_fetchrow($result))
			{
				if (!($fp = @fopen("{$phpbb_root_path}styles/{$path}/template/" . $row['template_filename'], 'wb')))
				{
					$store_db = 1;
					$error[] = $user->lang['EDIT_TEMPLATE_STORED_DB'];
					break;
				}

				fwrite($fp, $row['template_data']);
				fclose($fp);
			}
			$db->sql_freeresult($result);

			if (!$store_db)
			{
				$sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
						WHERE template_id = $id";
				$db->sql_query($sql);
			}
		}
		if (sizeof($error))
		{
			return $error;
		}
		$sql = 'UPDATE ' . STYLES_TEMPLATE_TABLE . '
				SET template_storedb = 0
				WHERE template_id = ' . $id;
		$db->sql_query($sql);

		return false;
	}

}

?>
Sarrene
Registered User
Posts: 79
Joined: Wed Jan 23, 2008 10:20 am
Name: Sarrene Grant
Contact:

Re: ReIMG Image Resizer

Post by Sarrene »

Okay, that was odd.. Empty post, even with me editing it. And yes, I did have the code tags closed.

Okay, let me try this again, one at a time...

"Okay, here we go.. You might have a better chance at finding out what I messed up on .. two sets of eyes are better then one, eh? As always, Thank you for helping. I dont know why this is so difficult fro some, let alone me lol."

includes/bbcode.php:

Code: Select all

<?php
/**
*
* @package phpBB3
* @version $Id$
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
	exit;
}

/**
* BBCode class
* @package phpBB3
*/
class bbcode
{
	var $bbcode_uid = '';
	var $bbcode_bitfield = '';
	var $bbcode_cache = array();
	var $bbcode_template = array();

	var $bbcodes = array();

	var $template_bitfield;
	var $template_filename = '';

	/**
	* Constructor
	* Init bbcode cache entries if bitfield is specified
	*/
	function bbcode($bitfield = '')
	{
		if ($bitfield)
		{
			$this->bbcode_bitfield = $bitfield;
			$this->bbcode_cache_init();
		}
	}

	/**
	* Second pass bbcodes
	*/
	function bbcode_second_pass(&$message, $bbcode_uid = '', $bbcode_bitfield = false)
	{
	$matchs = array (
			'#\[img(.*?)\](.*?)\[\/img(.*?)\]#is' => '<img src="\\2" alt="" />',
			'#\[color=(.*?)\]#is'				  => '<span style="color:\\1;">',
			'#\[highlight=(.*?)\]#is'				  => '<span style="background-color:\\1;">',
			'#\[font=(.*?)\]#is'				  => '<span style="font-family:\\1;">',
			'#\[\/(font|color|size|highlight)(.*?)\]#is'    => '</span>',
			'#\[size=1(.*?)\]#is'    => '[size=85]',
			'#\[size=2(.*?)\]#is'    => '[size=100]',
			'#\[size=3(.*?)\]#is'    => '[size=150]',
			'#\[size=4(.*?)\]#is'    => '[size=175]',
			'#\[size=5(.*?)\]#is'    => '[size=200]',
			'#\[size=6(.*?)\]#is'    => '[size=210]',
			'#\[size=7(.*?)\]#is'    => '[size=220]',
			'#\[size=([0-9]{2,3}+)(.*?)\]#is'    => '<span style="font-size: \\1%; line-height: 116%;">',
			'#\[table\]#is'    => '<table style="width: 100%; padding: 0px;border:1px dotted gray;">',
			'#\[td\]#is'    => '<td style="font-size: 20px; display:table-cell;padding:1px;vertical-align:inherit;border:1px dotted #CCCCCC;">',
			'#\[tr\]#is'    => '<tr>',
			'#\[\/tr\]#is'    => '</tr>',
			'#\[\/td\]#is'    => '</td>',
			'#\[\/table\]#is'    => '</table>',
			'#\[(indent|blockquote)\]#is'    => '<blockquote class="editor">',
			'#\[\/(indent|blockquote)\]#is'    => '</blockquote>',			
			'#\[size=(.*?)\]#is'    => '',
			);
		$message = preg_replace(array_keys($matchs), array_values($matchs), $message);
		if ($bbcode_uid)
		{
			$this->bbcode_uid = $bbcode_uid;
		}

		if ($bbcode_bitfield !== false)
		{
			$this->bbcode_bitfield = $bbcode_bitfield;

			// Init those added with a new bbcode_bitfield (already stored codes will not get parsed again)
			$this->bbcode_cache_init();
		}

		if (!$this->bbcode_bitfield)
		{
			// Remove the uid from tags that have not been transformed into HTML
			if ($this->bbcode_uid)
			{
				$message = str_replace(':' . $this->bbcode_uid, '', $message);
			}

			return;
		}

		$str = array('search' => array(), 'replace' => array());
		$preg = array('search' => array(), 'replace' => array());

		$bitfield = new bitfield($this->bbcode_bitfield);
		$bbcodes_set = $bitfield->get_all_set();

		$undid_bbcode_specialchars = false;
		foreach ($bbcodes_set as $bbcode_id)
		{
			if (!empty($this->bbcode_cache[$bbcode_id]))
			{
				foreach ($this->bbcode_cache[$bbcode_id] as $type => $array)
				{
					foreach ($array as $search => $replace)
					{
						${$type}['search'][] = str_replace('$uid', $this->bbcode_uid, $search);
						${$type}['replace'][] = $replace;
					}

					if (sizeof($str['search']))
					{
						$message = str_replace($str['search'], $str['replace'], $message);
						$str = array('search' => array(), 'replace' => array());
					}

					if (sizeof($preg['search']))
					{
						// we need to turn the entities back into their original form to allow the
						// search patterns to work properly
						if (!$undid_bbcode_specialchars)
						{
							$message = str_replace(array('&#58;', '&#46;'), array(':', '.'), $message);
							$undid_bbcode_specialchars = true;
						}

						$message = preg_replace($preg['search'], $preg['replace'], $message);
						$preg = array('search' => array(), 'replace' => array());
					}
				}
			}
		}

		// Remove the uid from tags that have not been transformed into HTML
		$message = str_replace(':' . $this->bbcode_uid, '', $message);
	}

	/**
	* Init bbcode cache
	*
	* requires: $this->bbcode_bitfield
	* sets: $this->bbcode_cache with bbcode templates needed for bbcode_bitfield
	*/
	function bbcode_cache_init()
	{
		global $phpbb_root_path, $template, $user;

		if (empty($this->template_filename))
		{
			$this->template_bitfield = new bitfield($user->theme['bbcode_bitfield']);
			$this->template_filename = $phpbb_root_path . 'styles/' . $user->theme['template_path'] . '/template/bbcode.html';

			if (!@file_exists($this->template_filename))
			{
				if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'])
				{
					$this->template_filename = $phpbb_root_path . 'styles/' . $user->theme['template_inherit_path'] . '/template/bbcode.html';
					if (!@file_exists($this->template_filename))
					{
						trigger_error('The file ' . $this->template_filename . ' is missing.', E_USER_ERROR);
					}
				}
				else
				{
					trigger_error('The file ' . $this->template_filename . ' is missing.', E_USER_ERROR);
				}
			}
		}

		$bbcode_ids = $rowset = $sql = array();

		$bitfield = new bitfield($this->bbcode_bitfield);
		$bbcodes_set = $bitfield->get_all_set();

		foreach ($bbcodes_set as $bbcode_id)
		{
			if (isset($this->bbcode_cache[$bbcode_id]))
			{
				// do not try to re-cache it if it's already in
				continue;
			}
			$bbcode_ids[] = $bbcode_id;

			if ($bbcode_id > NUM_CORE_BBCODES)
			{
				$sql[] = $bbcode_id;
			}
		}

		if (sizeof($sql))
		{
			global $db;

			$sql = 'SELECT *
				FROM ' . BBCODES_TABLE . '
				WHERE ' . $db->sql_in_set('bbcode_id', $sql);
			$result = $db->sql_query($sql, 3600);

			while ($row = $db->sql_fetchrow($result))
			{
				// To circumvent replacing newlines with <br /> for the generated html,
				// we use carriage returns here. They are later changed back to newlines
				$row['bbcode_tpl'] = str_replace("\n", "\r", $row['bbcode_tpl']);
				$row['second_pass_replace'] = str_replace("\n", "\r", $row['second_pass_replace']);

				$rowset[$row['bbcode_id']] = $row;
			}
			$db->sql_freeresult($result);
		}

		foreach ($bbcode_ids as $bbcode_id)
		{
			switch ($bbcode_id)
			{
				case 0:
					$this->bbcode_cache[$bbcode_id] = array(
						'str' => array(
							'[/quote:$uid]'	=> $this->bbcode_tpl('quote_close', $bbcode_id)
						),
						'preg' => array(
							'#\[quote(?:="(.*?)")?:$uid\]((?!\[quote(?:=".*?")?:$uid\]).)?#ise'	=> "\$this->bbcode_second_pass_quote('\$1', '\$2')"
						)
					);
				break;

				case 1:
					$this->bbcode_cache[$bbcode_id] = array(
						'str' => array(
							'[b:$uid]'	=> $this->bbcode_tpl('b_open', $bbcode_id),
							'[/b:$uid]'	=> $this->bbcode_tpl('b_close', $bbcode_id),
						)
					);
				break;

				case 2:
					$this->bbcode_cache[$bbcode_id] = array(
						'str' => array(
							'[i:$uid]'	=> $this->bbcode_tpl('i_open', $bbcode_id),
							'[/i:$uid]'	=> $this->bbcode_tpl('i_close', $bbcode_id),
						)
					);
				break;

				case 3:
					$this->bbcode_cache[$bbcode_id] = array(
						'preg' => array(
							'#\[url:$uid\]((.*?))\[/url:$uid\]#s'			=> $this->bbcode_tpl('url', $bbcode_id),
							'#\[url=([^\[]+?):$uid\](.*?)\[/url:$uid\]#s'	=> $this->bbcode_tpl('url', $bbcode_id),
						)
					);
				break;

				case 4:
					if ($user->optionget('viewimg'))
					{
						$this->bbcode_cache[$bbcode_id] = array(
							'preg' => array(
								'#\[img:$uid\](.*?)\[/img:$uid\]#s'		=> str_replace('$2', reimg_properties(), $this->bbcode_tpl('img', $bbcode_id)),
							)
						);
					}
					else
					{
						$this->bbcode_cache[$bbcode_id] = array(
							'preg' => array(
								'#\[img:$uid\](.*?)\[/img:$uid\]#s'		=> str_replace('$2', '[ img ]', $this->bbcode_tpl('url', $bbcode_id, true)),
							)
						);
					}
				break;

				case 5:
					$this->bbcode_cache[$bbcode_id] = array(
						'preg' => array(
							'#\[size=([\-\+]?\d+):$uid\](.*?)\[/size:$uid\]#s'	=> $this->bbcode_tpl('size', $bbcode_id),
						)
					);
				break;

				case 6:
					$this->bbcode_cache[$bbcode_id] = array(
						'preg' => array(
							'!\[color=(#[0-9a-f]{3}|#[0-9a-f]{6}|[a-z\-]+):$uid\](.*?)\[/color:$uid\]!is'	=> $this->bbcode_tpl('color', $bbcode_id),
						)
					);
				break;

				case 7:
					$this->bbcode_cache[$bbcode_id] = array(
						'str' => array(
							'[u:$uid]'	=> $this->bbcode_tpl('u_open', $bbcode_id),
							'[/u:$uid]'	=> $this->bbcode_tpl('u_close', $bbcode_id),
						)
					);
				break;

				case 8:
					$this->bbcode_cache[$bbcode_id] = array(
						'preg' => array(
							'#\[code(?:=([a-z]+))?:$uid\](.*?)\[/code:$uid\]#ise'	=> "\$this->bbcode_second_pass_code('\$1', '\$2')",
						)
					);
				break;

				case 9:
					$this->bbcode_cache[$bbcode_id] = array(
						'preg' => array(
							'#(\[\/?(list|\*):[mou]?:?$uid\])[\n]{1}#'	=> "\$1",
							'#(\[list=([^\[]+):$uid\])[\n]{1}#'			=> "\$1",
							'#\[list=([^\[]+):$uid\]#e'					=> "\$this->bbcode_list('\$1')",
						),
						'str' => array(
							'[list:$uid]'		=> $this->bbcode_tpl('ulist_open_default', $bbcode_id),
							'[/list:u:$uid]'	=> $this->bbcode_tpl('ulist_close', $bbcode_id),
							'[/list:o:$uid]'	=> $this->bbcode_tpl('olist_close', $bbcode_id),
							'[*:$uid]'			=> $this->bbcode_tpl('listitem', $bbcode_id),
							'[/*:$uid]'			=> $this->bbcode_tpl('listitem_close', $bbcode_id),
							'[/*:m:$uid]'		=> $this->bbcode_tpl('listitem_close', $bbcode_id)
						),
					);
				break;

				case 10:
					$this->bbcode_cache[$bbcode_id] = array(
						'preg' => array(
							'#\[email:$uid\]((.*?))\[/email:$uid\]#is'			=> $this->bbcode_tpl('email', $bbcode_id),
							'#\[email=([^\[]+):$uid\](.*?)\[/email:$uid\]#is'	=> $this->bbcode_tpl('email', $bbcode_id)
						)
					);
				break;

				case 11:
					if ($user->optionget('viewflash'))
					{
						$this->bbcode_cache[$bbcode_id] = array(
							'preg' => array(
								'#\[flash=([0-9]+),([0-9]+):$uid\](.*?)\[/flash:$uid\]#'	=> $this->bbcode_tpl('flash', $bbcode_id),
							)
						);
					}
					else
					{
						$this->bbcode_cache[$bbcode_id] = array(
							'preg' => array(
								'#\[flash=([0-9]+),([0-9]+):$uid\](.*?)\[/flash:$uid\]#'	=> str_replace('$1', '$3', str_replace('$2', '[ flash ]', $this->bbcode_tpl('url', $bbcode_id, true)))
							)
						);
					}
				break;

				case 12:
					$this->bbcode_cache[$bbcode_id] = array(
						'str'	=> array(
							'[/attachment:$uid]'	=> $this->bbcode_tpl('inline_attachment_close', $bbcode_id)
						),
						'preg'	=> array(
							'#\[attachment=([0-9]+):$uid\]#'	=> $this->bbcode_tpl('inline_attachment_open', $bbcode_id)
						)
					);
				break;

				default:
					if (isset($rowset[$bbcode_id]))
					{
						if ($this->template_bitfield->get($bbcode_id))
						{
							// The bbcode requires a custom template to be loaded
							if (!$bbcode_tpl = $this->bbcode_tpl($rowset[$bbcode_id]['bbcode_tag'], $bbcode_id))
							{
								// For some reason, the required template seems not to be available, use the default template
								$bbcode_tpl = (!empty($rowset[$bbcode_id]['second_pass_replace'])) ? $rowset[$bbcode_id]['second_pass_replace'] : $rowset[$bbcode_id]['bbcode_tpl'];
							}
							else
							{
								// In order to use templates with custom bbcodes we need
								// to replace all {VARS} to corresponding backreferences
								// Note that backreferences are numbered from bbcode_match
								if (preg_match_all('/\{(URL|LOCAL_URL|EMAIL|TEXT|SIMPLETEXT|INTTEXT|IDENTIFIER|COLOR|NUMBER)[0-9]*\}/', $rowset[$bbcode_id]['bbcode_match'], $m))
								{
									foreach ($m[0] as $i => $tok)
									{
										$bbcode_tpl = str_replace($tok, '$' . ($i + 1), $bbcode_tpl);
									}
								}
							}
						}
						else
						{
							// Default template
							$bbcode_tpl = (!empty($rowset[$bbcode_id]['second_pass_replace'])) ? $rowset[$bbcode_id]['second_pass_replace'] : $rowset[$bbcode_id]['bbcode_tpl'];
						}

						// Replace {L_*} lang strings
						$bbcode_tpl = preg_replace('/{L_([A-Z_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $bbcode_tpl);

						if (!empty($rowset[$bbcode_id]['second_pass_replace']))
						{
							// The custom BBCode requires second-pass pattern replacements
							$this->bbcode_cache[$bbcode_id] = array(
								'preg' => array($rowset[$bbcode_id]['second_pass_match'] => $bbcode_tpl)
							);
						}
						else
						{
							$this->bbcode_cache[$bbcode_id] = array(
								'str' => array($rowset[$bbcode_id]['second_pass_match'] => $bbcode_tpl)
							);
						}
					}
					else
					{
						$this->bbcode_cache[$bbcode_id] = false;
					}
				break;
			}
		}
	}

	/**
	* Return bbcode template
	*/
	function bbcode_tpl($tpl_name, $bbcode_id = -1, $skip_bitfield_check = false)
	{
		static $bbcode_hardtpl = array();
		if (empty($bbcode_hardtpl))
		{
			global $user;

			$bbcode_hardtpl = array(
				'b_open'	=> '<span style="font-weight: bold">',
				'b_close'	=> '</span>',
				'i_open'	=> '<span style="font-style: italic">',
				'i_close'	=> '</span>',
				'u_open'	=> '<span style="text-decoration: underline">',
				'u_close'	=> '</span>',
				'img'		=> '<img src="$1" alt="' . $user->lang['IMAGE'] . '" ' . reimg_properties() . '/>',
				'size'		=> '<span style="font-size: $1%; line-height: normal">$2</span>',
				'color'		=> '<span style="color: $1">$2</span>',
				'email'		=> '<a href="mailto:$1">$2</a>'
			);
		}

		if ($bbcode_id != -1 && !$skip_bitfield_check && !$this->template_bitfield->get($bbcode_id))
		{
			return (isset($bbcode_hardtpl[$tpl_name])) ? $bbcode_hardtpl[$tpl_name] : false;
		}

		if (empty($this->bbcode_template))
		{
			if (($tpl = file_get_contents($this->template_filename)) === false)
			{
				trigger_error('Could not load bbcode template', E_USER_ERROR);
			}

			// replace \ with \\ and then ' with \'.
			$tpl = str_replace('\\', '\\\\', $tpl);
			$tpl = str_replace("'", "\'", $tpl);

			// strip newlines and indent
			$tpl = preg_replace("/\n[\n\r\s\t]*/", '', $tpl);

			// Turn template blocks into PHP assignment statements for the values of $bbcode_tpl..
			$this->bbcode_template = array();

			$matches = preg_match_all('#<!-- BEGIN (.*?) -->(.*?)<!-- END (?:.*?) -->#', $tpl, $match);

			for ($i = 0; $i < $matches; $i++)
			{
				if (empty($match[1][$i]))
				{
					continue;
				}

				$this->bbcode_template[$match[1][$i]] = $this->bbcode_tpl_replace($match[1][$i], $match[2][$i]);
			}
		}

		return (isset($this->bbcode_template[$tpl_name])) ? $this->bbcode_template[$tpl_name] : ((isset($bbcode_hardtpl[$tpl_name])) ? $bbcode_hardtpl[$tpl_name] : false);
	}

	/**
	* Return bbcode template replacement
	*/
	function bbcode_tpl_replace($tpl_name, $tpl)
	{
		global $user;

		static $replacements = array(
			'quote_username_open'	=> array('{USERNAME}'	=> '$1'),
			'color'					=> array('{COLOR}'		=> '$1', '{TEXT}'			=> '$2'),
			'size'					=> array('{SIZE}'		=> '$1', '{TEXT}'			=> '$2'),
			'img'					=> array('{URL}'		=> '$1', '{REIMG_PROPERTIES}'	=> '$2'),
			'flash'					=> array('{WIDTH}'		=> '$1', '{HEIGHT}'			=> '$2', '{URL}'	=> '$3'),
			'url'					=> array('{URL}'		=> '$1', '{DESCRIPTION}'	=> '$2'),
			'email'					=> array('{EMAIL}'		=> '$1', '{DESCRIPTION}'	=> '$2')
		);

		$tpl = preg_replace('/{L_([A-Z_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $tpl);

		if (!empty($replacements[$tpl_name]))
		{
			$tpl = strtr($tpl, $replacements[$tpl_name]);
		}

		return trim($tpl);
	}

	/**
	* Second parse list bbcode
	*/
	function bbcode_list($type)
	{
		if ($type == '')
		{
			$tpl = 'ulist_open_default';
			$type = 'default';
		}
		else if ($type == 'i')
		{
			$tpl = 'olist_open';
			$type = 'lower-roman';
		}
		else if ($type == 'I')
		{
			$tpl = 'olist_open';
			$type = 'upper-roman';
		}
		else if (preg_match('#^(disc|circle|square)$#i', $type))
		{
			$tpl = 'ulist_open';
			$type = strtolower($type);
		}
		else if (preg_match('#^[a-z]$#', $type))
		{
			$tpl = 'olist_open';
			$type = 'lower-alpha';
		}
		else if (preg_match('#[A-Z]#', $type))
		{
			$tpl = 'olist_open';
			$type = 'upper-alpha';
		}
		else if (is_numeric($type))
		{
			$tpl = 'olist_open';
			$type = 'decimal';
		}
		else
		{
			$tpl = 'olist_open';
			$type = 'decimal';
		}

		return str_replace('{LIST_TYPE}', $type, $this->bbcode_tpl($tpl));
	}

	/**
	* Second parse quote tag
	*/
	function bbcode_second_pass_quote($username, $quote)
	{
		// when using the /e modifier, preg_replace slashes double-quotes but does not
		// seem to slash anything else
		$quote = str_replace('\"', '"', $quote);
		$username = str_replace('\"', '"', $username);

		// remove newline at the beginning
		if ($quote == "\n")
		{
			$quote = '';
		}

		$quote = (($username) ? str_replace('$1', $username, $this->bbcode_tpl('quote_username_open')) : $this->bbcode_tpl('quote_open')) . $quote;

		return $quote;
	}

	/**
	* Second parse code tag
	*/
	function bbcode_second_pass_code($type, $code)
	{
		// when using the /e modifier, preg_replace slashes double-quotes but does not
		// seem to slash anything else
		$code = str_replace('\"', '"', $code);

		switch ($type)
		{
			case 'php':
				// Not the english way, but valid because of hardcoded syntax highlighting
				if (strpos($code, '<span class="syntaxdefault"><br /></span>') === 0)
				{
					$code = substr($code, 41);
				}

			// no break;

			default:
				$code = str_replace("\t", '&nbsp; &nbsp;', $code);
				$code = str_replace('  ', '&nbsp; ', $code);
				$code = str_replace('  ', ' &nbsp;', $code);

				// remove newline at the beginning
				if (!empty($code) && $code[0] == "\n")
				{
					$code = substr($code, 1);
				}
			break;
		}

		$code = $this->bbcode_tpl('code_open') . $code . $this->bbcode_tpl('code_close');

		return $code;
	}
}

?>
Locked

Return to “[3.0.x] MOD Database Releases”